Does some basic tasks.
authorWerner Koch <wk@gnupg.org>
Mon, 20 Nov 2000 20:17:36 +0000 (20:17 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 20 Nov 2000 20:17:36 +0000 (20:17 +0000)
trunk/acconfig.h
trunk/configure.in
trunk/gpgme/context.h
trunk/gpgme/gpgme.c
trunk/gpgme/gpgme.h
trunk/gpgme/rungpg.c
trunk/gpgme/wait.c
trunk/tests/t-decrypt.c
trunk/tests/t-sign.c
trunk/tests/t-verify.c

index 2db9b12fbce0c87c01ad2475c8c3c459a2a9bc1d..724fd6ffc52b528b1cb8592ef1685e6a254998e8 100644 (file)
 #define GPGME_CONFIG_H
 
 /* need this, because some autoconf tests rely on this (e.g. stpcpy)
- * and it should be used for new programs
- */
+ * and it should be used for new programs  */
 #define _GNU_SOURCE  1
+/* To allow the use of gpgme in multithreaded programs we have to use 
+ * special features from the library.  
+ * IMPORTANT: gpgme is not yet fully reentrant and you should use it
+ * only from one thread. */
+#define _REENTRANT 1 
 
 @TOP@
 
index f8301ca726d7a20bd72f6f9c131574c552cb80f1..3e23edfdc630a0f04556891cc9368f1d6abff970 100644 (file)
@@ -13,10 +13,10 @@ AM_MAINTAINER_MODE
 #    AGE, set REVISION to 0.
 # 3. Interfaces removed (BAD, breaks upward compatibility): Increment
 #    CURRENT, set AGE and REVISION to 0.
-AM_INIT_AUTOMAKE(gpgme,0.0.1)
+AM_INIT_AUTOMAKE(gpgme,0.1.0)
 LIBGPGME_LT_CURRENT=0
 LIBGPGME_LT_AGE=0
-LIBGPGME_LT_REVISION=0
+LIBGPGME_LT_REVISION=2
 ##############################################
 
 AC_SUBST(LIBGPGME_LT_CURRENT)
index 71c4239573650e259524509d9f17de7d23d18e67..e888aa8d488b18484fe3a8d8b6f861aca56f7596 100644 (file)
@@ -55,6 +55,9 @@ struct gpgme_context_s {
     int verbosity;  /* level of verbosity to use */
     int use_armor;  
     int use_textmode;
+
+    /*   GpgmePassphraseCb passphrase_cb;*/
+    /* void *            passphrase_cb_value;*/
     
     ResultType result_type;
     union {
index 05f940f72a9983d98c63de351d98d239612fdbc4..165f03cb58edba14d6c3ff9e065e844d730e2c3e 100644 (file)
@@ -96,7 +96,7 @@ _gpgme_release_result ( GpgmeCtx c )
 
 
 char *
-gpgme_op_get_notation ( GpgmeCtx c )
+gpgme_get_notation ( GpgmeCtx c )
 {
     if ( !c->notation )
         return NULL;
@@ -105,7 +105,7 @@ gpgme_op_get_notation ( GpgmeCtx c )
 
 
 void
-gpgme_op_set_armor ( GpgmeCtx c, int yes )
+gpgme_set_armor ( GpgmeCtx c, int yes )
 {
     if ( !c )
         return; /* oops */
@@ -113,19 +113,23 @@ gpgme_op_set_armor ( GpgmeCtx c, int yes )
 }
 
 void
-gpgme_op_set_textmode ( GpgmeCtx c, int yes )
+gpgme_set_textmode ( GpgmeCtx c, int yes )
 {
     if ( !c )
         return; /* oops */
     c->use_textmode = yes;
 }
 
-
-
-
-
-
-
+#if 0
+void
+gpgme_set_passphrase_cb ( GpgmeCtx c, GpgmePassphraseCb fnc, void *fncval )
+{
+    if ( c ) {
+        c->passphrase_cb = fnc;
+        c->passphrase_cb_value = fncval;
+    }
+}
+#endif
 
 
 
index 6c9c76619146d9cb3945187f296de9e3c45a8267..692362b160f38b8f98f808c93ca082e68df4dfe8 100644 (file)
@@ -34,7 +34,7 @@ extern "C" {
  * let autoconf (using the AM_PATH_GPGME macro) check that this
  * header matches the installed library.
  * Warning: Do not edit the next line.  configure will do that for you! */
-#define GPGME_VERSION "0.0.1"
+#define GPGME_VERSION "0.1.0"
 
 
 
@@ -91,6 +91,7 @@ typedef enum {
     GPGME_SIG_STAT_ERROR = 5
 } GpgmeSigStat;
 
+/*typedef GpgmeData (*GpgmePassphraseCb)( void *opaque, const char *desc );*/
 
 
 /* Context management */
@@ -98,9 +99,11 @@ GpgmeError gpgme_new (GpgmeCtx *r_ctx);
 void       gpgme_release ( GpgmeCtx c );
 GpgmeCtx   gpgme_wait ( GpgmeCtx c, int hang );
 
-char *gpgme_op_get_notation ( GpgmeCtx c );
-void gpgme_op_set_armor ( GpgmeCtx c, int yes );
-void gpgme_op_set_textmode ( GpgmeCtx c, int yes );
+char *gpgme_get_notation ( GpgmeCtx c );
+void gpgme_set_armor ( GpgmeCtx c, int yes );
+void gpgme_set_textmode ( GpgmeCtx c, int yes );
+/*void gpgme_set_passphrase_cb ( GpgmeCtx c,
+  GpgmePassphraseCb fnc, void *fncval );*/
 
 
 /* Functions to handle recipients */
index 991624f94f1a996a5b3442dfcbb29b4bfac4f9bd..f75b8b14cce1842652d383962aa031c427a9e7cd 100644 (file)
@@ -201,6 +201,20 @@ kill_gpg ( GpgObject gpg )
 }
 
 
+    
+static int
+set_nonblocking ( int fd )
+{
+    int flags;
+
+    flags = fcntl (fd, F_GETFL, 0);
+    if (flags == -1)
+        return -1;
+    flags |= O_NONBLOCK;
+    return fcntl (fd, F_SETFL, flags);
+}
+
+
 GpgmeError
 _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg )
 {
@@ -313,7 +327,6 @@ build_argv ( GpgObject gpg )
     char **argv;
     int need_special = 0;
     int use_agent = !!getenv ("GPG_AGENT_INFO");
-
        
     if ( gpg->argv ) {
         free_argv ( gpg->argv );
@@ -583,6 +596,13 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
     for (i=0; gpg->fd_data_map[i].data; i++ ) {
         close (gpg->fd_data_map[i].peer_fd);
         gpg->fd_data_map[i].peer_fd = -1;
+        
+        /* Due to problems with select and write we set outbound pipes
+         * to non-blocking */
+        if (!gpg->fd_data_map[i].inbound) {
+            set_nonblocking (gpg->fd_data_map[i].fd);
+        }
+
         if ( _gpgme_register_pipe_handler (
                  opaque, 
                  gpg->fd_data_map[i].inbound?
@@ -650,15 +670,29 @@ write_mem_data ( GpgmeData dh, int fd )
 
     nbytes = dh->len - dh->readpos;
     if ( !nbytes ) {
+        fprintf (stderr, "write_mem_data(%d): closing\n", fd );
         close (fd);
         return 1;
     }
     
+    /* FIXME: Arggg, the pipe blocks on large write request, although
+     * select told us that it is okay to write - need to figure out
+     * why this happens?  Stevens says nothing about this problem (or
+     * is it my Linux kernel 2.4.0test1)
+     * To avoid that we have set the pipe to nonblocking.
+     */
+
+
     do {
+        fprintf (stderr, "write_mem_data(%d): about to write %d bytes len=%d rpos=%d\n",
+                 fd, (int)nbytes, (int)dh->len, dh->readpos );
         nwritten = write ( fd, dh->data+dh->readpos, nbytes );
+        fprintf (stderr, "write_mem_data(%d): wrote %d bytes\n", fd, nwritten );
     } while ( nwritten == -1 && errno == EINTR );
+    if (nwritten == -1 && errno == EAGAIN )
+        return 0;
     if ( nwritten < 1 ) {
-        fprintf (stderr, "write_mem_data: write failed on fd %d (n=%d): %s\n",
+        fprintf (stderr, "write_mem_data(%d): write failed (n=%d): %s\n",
                  fd, nwritten, strerror (errno) );
         close (fd);
         return 1;
index a3c50930373b409a39999747196225dc685cecee..f54209d6510b70eb099397a8d5e31fdce6114f22 100644 (file)
 #include "ops.h"
 #include "wait.h"
 
+#define DEBUG_SELECT_ENABLED 1
+
+#if DEBUG_SELECT_ENABLED
+# define DEBUG_SELECT(a) fprintf a
+#else
+# define DEBUG_SELECT(a) do { } while(0)
+#endif
+
 /* Fixme: implement the following stuff to make the code MT safe.
  * To avoid the need to link against a specific threads lib, such
  * an implementation should require the caller to register a function
@@ -243,23 +251,28 @@ the_big_select ( void )
     FD_ZERO ( &readfds );
     FD_ZERO ( &writefds );
     max_fd = 0;
+
+    
+    DEBUG_SELECT ((stderr, "gpgme:select on [ "));
     lock_queue ();
     for ( q = wait_queue; q; q = q->next ) {
         if ( q->used && q->active ) {
             if (q->inbound) {
                 assert ( !FD_ISSET ( q->fd, &readfds ) );
                 FD_SET ( q->fd, &readfds );
+                DEBUG_SELECT ((stderr, "r%d ", q->fd ));
             }
             else {
                 assert ( !FD_ISSET ( q->fd, &writefds ) );
                 FD_SET ( q->fd, &writefds );
+                DEBUG_SELECT ((stderr, "w%d ", q->fd ));
             }
             if ( q->fd > max_fd )
                 max_fd = q->fd;
           }
     }
     unlock_queue ();
-
+    DEBUG_SELECT ((stderr, "]\n" ));
 
     n = select ( max_fd+1, &readfds, &writefds, NULL, &timeout );
     if ( n <= 0 ) {
@@ -270,15 +283,40 @@ the_big_select ( void )
         return 0;
     }
 
+#if DEBUG_SELECT_ENABLED
+    { 
+        int i;
+
+        fprintf (stderr, "gpgme:select OK [ " );
+        for (i=0; i <= max_fd; i++ ) {
+            if (FD_ISSET (i, &readfds) )
+                fprintf (stderr, "r%d ", i );
+            if (FD_ISSET (i, &writefds) )
+                fprintf (stderr, "w%d ", i );
+        }
+        fprintf (stderr, "]\n" );
+    }
+#endif
+
     /* something has to be done.  Go over the queue and call
      * the handlers */
  restart:
     while ( n ) {
         lock_queue ();
         for ( q = wait_queue; q; q = q->next ) {
-            if ( q->used && q->active 
-                 && FD_ISSET (q->fd, q->inbound? &readfds : &writefds ) ) {
-                FD_CLR (q->fd, q->inbound? &readfds : &writefds );
+            if ( q->used && q->active && q->inbound 
+                 && FD_ISSET (q->fd, &readfds ) ) {
+                FD_CLR (q->fd, &readfds );
+                assert (n);
+                n--;
+                unlock_queue ();
+                if ( q->handler (q->handler_value, q->pid, q->fd ) )
+                    q->active = 0;
+                goto restart;
+            }
+            if ( q->used && q->active && !q->inbound
+                 && FD_ISSET (q->fd, &writefds ) ) {
+                FD_CLR (q->fd, &writefds );
                 assert (n);
                 n--;
                 unlock_queue ();
index bf96112d9c5f6f962aca279f08a29ee3715e1db3..f98748da73daf396743032c2a4b7b383beb1d105 100644 (file)
@@ -50,6 +50,17 @@ print_data ( GpgmeData dh )
         fail_if_err (err);
 }
 
+#if 0
+static GpgmeData
+passphrase_cb ( void *opaque, const char *description )
+{
+    GpgmeData dh;
+
+    assert (NULL);
+    gpgme_data_new_from_mem ( &dh, "abc", 3, 0 );
+    return dh;
+}
+#endif
 
 static char *
 mk_fname ( const char *fname )
@@ -79,6 +90,11 @@ main (int argc, char **argv )
   do {
     err = gpgme_new (&ctx);
     fail_if_err (err);
+#if 0
+    if ( !getenv("GPG_AGENT_INFO") {
+        gpgme_set_passphrase_cb ( ctx, passphrase_cb, NULL );
+    } 
+#endif
 
     err = gpgme_data_new_from_file ( &in, cipher_1_asc, 1 );
     fail_if_err (err);
index 4d3ed3407b69ad17642ca6816b1531e822e47d0b..c09b2c96936a9833642cb92eb350e76a24681919 100644 (file)
@@ -66,8 +66,8 @@ main (int argc, char **argv )
     err = gpgme_data_new ( &out );
     fail_if_err (err);
 
-    gpgme_op_set_textmode (ctx, 1);
-    gpgme_op_set_armor (ctx, 1);
+    gpgme_set_textmode (ctx, 1);
+    gpgme_set_armor (ctx, 1);
     err = gpgme_op_sign (ctx, in, out );
     fail_if_err (err);
 
index bc997236a8f057b60ff33043a474472718c818fc..ac9e3376454afc4ddeda26427d3224eef93aed0a 100644 (file)
@@ -116,7 +116,7 @@ main (int argc, char **argv )
     err = gpgme_op_verify (ctx, sig, text, &status );
     print_sig_stat ( status );
     fail_if_err (err);
-    if ( (nota=gpgme_op_get_notation (ctx)) )
+    if ( (nota=gpgme_get_notation (ctx)) )
         printf ("---Begin Notation---\n%s---End Notation---\n", nota );
 
     puts ("checking a manipulated message:\n");
@@ -128,7 +128,7 @@ main (int argc, char **argv )
     err = gpgme_op_verify (ctx, sig, text, &status );
     print_sig_stat ( status );
     fail_if_err (err);
-    if ( (nota=gpgme_op_get_notation (ctx)) )
+    if ( (nota=gpgme_get_notation (ctx)) )
         printf ("---Begin Notation---\n%s---End Notation---\n", nota );
 
     gpgme_data_release (sig);