diff options
author | Werner Koch <wk@gnupg.org> | 2009-10-28 13:02:15 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2009-10-28 13:02:15 +0100 |
commit | a1b614285518c1e4928919b905e992f35f4a3224 (patch) | |
tree | b8b0fdbc2459188fcdef689b32b17cf40871f644 /g13 | |
parent | 2009-10-20 Marcus Brinkmann <marcus@g10code.com> (diff) | |
download | gnupg2-a1b614285518c1e4928919b905e992f35f4a3224.tar.xz gnupg2-a1b614285518c1e4928919b905e992f35f4a3224.zip |
[scd] Memory leak fix.
[g13] Send MOUNTPOINT status line
Diffstat (limited to 'g13')
-rw-r--r-- | g13/be-encfs.c | 2 | ||||
-rw-r--r-- | g13/g13.c | 3 | ||||
-rw-r--r-- | g13/g13.h | 2 | ||||
-rw-r--r-- | g13/mount.c | 37 | ||||
-rw-r--r-- | g13/mountinfo.c | 22 | ||||
-rw-r--r-- | g13/mountinfo.h | 3 | ||||
-rw-r--r-- | g13/server.c | 167 |
7 files changed, 138 insertions, 98 deletions
diff --git a/g13/be-encfs.c b/g13/be-encfs.c index 250084a48..524f09e6b 100644 --- a/g13/be-encfs.c +++ b/g13/be-encfs.c @@ -418,7 +418,7 @@ be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples, { err = gpg_error_from_syserror (); log_error (_("can't create directory `%s': %s\n"), - "/tmp/g13-XXXXXX", gpg_strerror (err)); + "/tmp/.#g13_XXXXXX", gpg_strerror (err)); goto leave; } @@ -420,6 +420,8 @@ main ( int argc, char **argv) /* Setup a default control structure for command line mode. */ memset (&ctrl, 0, sizeof ctrl); g13_init_default_ctrl (&ctrl); + ctrl.no_server = 1; + ctrl.status_fd = -1; /* No status output. */ /* Set the default option file */ if (default_config ) @@ -678,6 +680,7 @@ main ( int argc, char **argv) case aServer: { start_idle_task (); + ctrl.no_server = 0; err = g13_server (&ctrl); if (err) log_error ("server exited with error: %s <%s>\n", @@ -106,6 +106,8 @@ struct server_control_s void g13_exit (int rc); void g13_init_default_ctrl (struct server_control_s *ctrl); +/*-- server.c (commonly used, thus declared here) --*/ +gpg_error_t g13_status (ctrl_t ctrl, int no, ...) GNUPG_GCC_A_SENTINEL(0); #endif /*G13_H*/ diff --git a/g13/mount.c b/g13/mount.c index dc23b6b2b..2ab5cc636 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -250,15 +250,35 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) const unsigned char *value; int conttype; unsigned int rid; + char *mountpoint_buffer = NULL; /* A quick check to see whether the container exists. */ if (access (filename, R_OK)) return gpg_error_from_syserror (); + if (!mountpoint) + { + mountpoint_buffer = xtrystrdup ("/tmp/g13-XXXXXX"); + if (!mountpoint_buffer) + return gpg_error_from_syserror (); + if (!mkdtemp (mountpoint_buffer)) + { + err = gpg_error_from_syserror (); + log_error (_("can't create directory `%s': %s\n"), + "/tmp/g13-XXXXXX", gpg_strerror (err)); + xfree (mountpoint_buffer); + return err; + } + mountpoint = mountpoint_buffer; + } + /* Try to take a lock. */ lock = create_dotlock (filename); if (!lock) - return gpg_error_from_syserror (); + { + xfree (mountpoint_buffer); + return gpg_error_from_syserror (); + } if (make_dotlock (lock, 0)) { @@ -318,9 +338,21 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples, &rid); if (!err) { - err = mountinfo_add_mount (filename, mountpoint, conttype, rid); + err = mountinfo_add_mount (filename, mountpoint, conttype, rid, + !!mountpoint_buffer); /* Fixme: What shall we do if this fails? Add a provisional mountinfo entry first and remove it on error? */ + if (!err) + { + char *tmp = percent_plus_escape (mountpoint); + if (!tmp) + err = gpg_error_from_syserror (); + else + { + g13_status (ctrl, STATUS_MOUNTPOINT, tmp, NULL); + xfree (tmp); + } + } } leave: @@ -328,6 +360,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) xfree (keyblob); xfree (enckeyblob); destroy_dotlock (lock); + xfree (mountpoint_buffer); return err; } diff --git a/g13/mountinfo.c b/g13/mountinfo.c index 100c1e475..07c6240d4 100644 --- a/g13/mountinfo.c +++ b/g13/mountinfo.c @@ -43,6 +43,10 @@ struct mounttable_s char *mountpoint; /* Name of the mounttype. */ int conttype; /* Type of the container. */ unsigned int rid; /* Identifier of the runner task. */ + struct { + unsigned int remove:1; /* True if the mountpoint shall be removed + on umount. */ + } flags; }; @@ -55,7 +59,7 @@ size_t mounttable_size; /* Add CONTAINER,MOUNTPOINT,CONTTYPE,RID to the mounttable. */ gpg_error_t mountinfo_add_mount (const char *container, const char *mountpoint, - int conttype, unsigned int rid) + int conttype, unsigned int rid, int remove_flag) { size_t idx; mtab_t m; @@ -96,6 +100,7 @@ mountinfo_add_mount (const char *container, const char *mountpoint, } m->conttype = conttype; m->rid = rid; + m->flags.remove = !!remove_flag; m->in_use = 1; return 0; @@ -125,6 +130,16 @@ mountinfo_del_mount (const char *container, const char *mountpoint, for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) if (m->in_use && m->rid == rid) { + if (m->flags.remove && m->mountpoint) + { + /* FIXME: This does not always work because the umount may + not have completed yet. We should add the mountpoints + to an idle queue and retry a remove. */ + if (rmdir (m->mountpoint)) + log_error ("error removing mount point `%s': %s\n", + m->mountpoint, + gpg_strerror (gpg_error_from_syserror ())); + } m->in_use = 0; xfree (m->container); m->container = NULL; @@ -177,7 +192,8 @@ mountinfo_dump_all (void) for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) if (m->in_use) - log_info ("mtab[%d] %s on %s type %d rid %u\n", - idx, m->container, m->mountpoint, m->conttype, m->rid); + log_info ("mtab[%d] %s on %s type %d rid %u%s\n", + idx, m->container, m->mountpoint, m->conttype, m->rid, + m->flags.remove?" [remove]":""); } diff --git a/g13/mountinfo.h b/g13/mountinfo.h index 187dff0db..b8ac5bd7b 100644 --- a/g13/mountinfo.h +++ b/g13/mountinfo.h @@ -25,7 +25,8 @@ typedef struct mounttable_s *mtab_t; gpg_error_t mountinfo_add_mount (const char *container, const char *mountpoint, - int conttype, unsigned int rid); + int conttype, unsigned int rid, + int remove_flag); gpg_error_t mountinfo_del_mount (const char *container, const char *mountpoint, unsigned int rid); diff --git a/g13/server.c b/g13/server.c index e9b9a0a33..a6906aaa3 100644 --- a/g13/server.c +++ b/g13/server.c @@ -33,6 +33,10 @@ #include "mount.h" #include "create.h" + +/* The filepointer for status message used in non-server mode */ +static FILE *statusfp; + /* Local data for this server module. A pointer to this is stored in the CTRL object of each connection. */ struct server_local_s @@ -310,7 +314,8 @@ cmd_mount (assuan_context_t ctx, char *line) /* UMOUNT [options] [<mountpoint>] Unmount the currently open file or the one opened at MOUNTPOINT. - MOUNTPOINT must be percent-plus escaped. + MOUNTPOINT must be percent-plus escaped. On success the mountpoint + is returned via a "MOUNTPOINT" status line. */ static gpg_error_t cmd_umount (assuan_context_t ctx, char *line) @@ -662,99 +667,81 @@ g13_server (ctrl_t ctrl) } +/* Send a status line with status ID NO. The arguments are a list of + strings terminated by a NULL argument. */ +gpg_error_t +g13_status (ctrl_t ctrl, int no, ...) +{ + gpg_error_t err = 0; + va_list arg_ptr; + const char *text; + + va_start (arg_ptr, no); -/* gpg_error_t */ -/* gpgsm_status2 (ctrl_t ctrl, int no, ...) */ -/* { */ -/* gpg_error_t err = 0; */ -/* va_list arg_ptr; */ -/* const char *text; */ - -/* va_start (arg_ptr, no); */ - -/* if (ctrl->no_server && ctrl->status_fd == -1) */ -/* ; /\* No status wanted. *\/ */ -/* else if (ctrl->no_server) */ -/* { */ -/* if (!statusfp) */ -/* { */ -/* if (ctrl->status_fd == 1) */ -/* statusfp = stdout; */ -/* else if (ctrl->status_fd == 2) */ -/* statusfp = stderr; */ -/* else */ -/* statusfp = fdopen (ctrl->status_fd, "w"); */ - -/* if (!statusfp) */ -/* { */ -/* log_fatal ("can't open fd %d for status output: %s\n", */ -/* ctrl->status_fd, strerror(errno)); */ -/* } */ -/* } */ + if (ctrl->no_server && ctrl->status_fd == -1) + ; /* No status wanted. */ + else if (ctrl->no_server) + { + if (!statusfp) + { + if (ctrl->status_fd == 1) + statusfp = stdout; + else if (ctrl->status_fd == 2) + statusfp = stderr; + else + statusfp = fdopen (ctrl->status_fd, "w"); + + if (!statusfp) + { + log_fatal ("can't open fd %d for status output: %s\n", + ctrl->status_fd, strerror(errno)); + } + } -/* fputs ("[GNUPG:] ", statusfp); */ -/* fputs (get_status_string (no), statusfp); */ + fputs ("[GNUPG:] ", statusfp); + fputs (get_status_string (no), statusfp); -/* while ( (text = va_arg (arg_ptr, const char*) )) */ -/* { */ -/* putc ( ' ', statusfp ); */ -/* for (; *text; text++) */ -/* { */ -/* if (*text == '\n') */ -/* fputs ( "\\n", statusfp ); */ -/* else if (*text == '\r') */ -/* fputs ( "\\r", statusfp ); */ -/* else */ -/* putc ( *(const byte *)text, statusfp ); */ -/* } */ -/* } */ -/* putc ('\n', statusfp); */ -/* fflush (statusfp); */ -/* } */ -/* else */ -/* { */ -/* assuan_context_t ctx = ctrl->server_local->assuan_ctx; */ -/* char buf[950], *p; */ -/* size_t n; */ - -/* p = buf; */ -/* n = 0; */ -/* while ( (text = va_arg (arg_ptr, const char *)) ) */ -/* { */ -/* if (n) */ -/* { */ -/* *p++ = ' '; */ -/* n++; */ -/* } */ -/* for ( ; *text && n < DIM (buf)-2; n++) */ -/* *p++ = *text++; */ -/* } */ -/* *p = 0; */ -/* err = assuan_write_status (ctx, get_status_string (no), buf); */ -/* } */ - -/* va_end (arg_ptr); */ -/* return err; */ -/* } */ - -/* gpg_error_t */ -/* gpgsm_status (ctrl_t ctrl, int no, const char *text) */ -/* { */ -/* return gpgsm_status2 (ctrl, no, text, NULL); */ -/* } */ + while ( (text = va_arg (arg_ptr, const char*) )) + { + putc ( ' ', statusfp ); + for (; *text; text++) + { + if (*text == '\n') + fputs ( "\\n", statusfp ); + else if (*text == '\r') + fputs ( "\\r", statusfp ); + else + putc ( *(const byte *)text, statusfp ); + } + } + putc ('\n', statusfp); + fflush (statusfp); + } + else + { + assuan_context_t ctx = ctrl->server_local->assuan_ctx; + char buf[950], *p; + size_t n; -/* gpg_error_t */ -/* gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, */ -/* gpg_err_code_t ec) */ -/* { */ -/* char buf[30]; */ + p = buf; + n = 0; + while ( (text = va_arg (arg_ptr, const char *)) ) + { + if (n) + { + *p++ = ' '; + n++; + } + for ( ; *text && n < DIM (buf)-2; n++) + *p++ = *text++; + } + *p = 0; + err = assuan_write_status (ctx, get_status_string (no), buf); + } -/* sprintf (buf, "%u", (unsigned int)ec); */ -/* if (text) */ -/* return gpgsm_status2 (ctrl, no, text, buf, NULL); */ -/* else */ -/* return gpgsm_status2 (ctrl, no, buf, NULL); */ -/* } */ + va_end (arg_ptr); + return err; +} /* Helper to notify the client about Pinentry events. Returns an gpg @@ -768,5 +755,3 @@ g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line) } - - |