Commit 5416e044 5416e044b0995e3f49676152da15866fcf29d323 by Sergey Poznyakoff

Implement mu_onexit functions; use MU stdstream in mh and mimeview.

* include/mailutils/types.hin (mu_onexit_t): New typedef.
* include/mailutils/util.h (mu_onexit_reset, mu_onexit): New protos.
* libmailutils/base/onexit.c: New file.
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Add onexit.c

* libmailutils/stdstream/basestr.c (stdstream_flushall): New function.
(mu_stdstream_setup): Rewrite the fd checking algorithm.
Register stdstream_flushall as an onexit function.

* mh/anno.c: Use MU stdstream.
* mh/mh.h: Include mailutils/stdstream.h.
* mh/mh_init.c (mh_init): Call mu_stdstream_setup; use MU stdstream.
* mh/mh_whatnow.c (_whatnow): Use MU stdstream.
* mh/mhl.c (open_output,list_message): Likewise.
* mh/mhn.c (mhn_show,store_handler): Likewise.
* pop3d/popauth.c: Use MU stdstream.

* mimeview/mimetypes.y: Use MU stdstream.
* mimeview/mimeview.c: Likewise.
(mimeview_fp): Remove.
(mimeview_stream): New variable.
* mimeview/mimeview.h (mimeview_fp): Remove.
(mimeview_stream): New variable.

* lib/mailcap.c (find_entry): Don't report ENOENT.
1 parent 1ef74258
......@@ -118,7 +118,9 @@ typedef struct _mu_opool *mu_opool_t;
typedef struct _mu_progmailer *mu_progmailer_t;
typedef struct _mu_secret *mu_secret_t;
typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t;
typedef void (*mu_onexit_t) (void*);
#define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001
#define MU_FOLDER_ATTRIBUTE_FILE 0x002
#define MU_FOLDER_ATTRIBUTE_LINK 0x004
......
......@@ -187,6 +187,11 @@ int mu_fd_wait (int fd, int *pflags, struct timeval *tvp);
int mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab,
int *perr);
/* Reset the onexit list. */
void mu_onexit_reset (void);
/* Register the onexit function and associated data */
int mu_onexit (mu_onexit_t func, void *data);
#ifdef __cplusplus
}
#endif
......
......@@ -620,8 +620,9 @@ find_entry (const char *file, struct mime_context *ctx)
status = mu_file_stream_create (&stream, file, MU_STREAM_READ);
if (status)
{
mu_error ("cannot create file stream %s: %s",
file, mu_strerror (status));
if (status != ENOENT)
mu_error ("cannot open input stream %s: %s",
file, mu_strerror (status));
return -1;
}
......
......@@ -49,6 +49,7 @@ libbase_la_SOURCES = \
nls.c\
nullrec.c\
observer.c\
onexit.c\
opool.c\
parsedate.c\
permstr.c\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/list.h>
#include <mailutils/iterator.h>
#include <mailutils/nls.h>
#include <mailutils/stream.h>
#include <mailutils/stdstream.h>
struct onexit_closure
{
mu_onexit_t function;
void *data;
};
static mu_list_t onexit_list;
void
_mu_onexit_run (void)
{
mu_iterator_t itr;
int rc, status = 0;
rc = mu_list_get_iterator (onexit_list, &itr);
if (rc)
{
mu_error (_("cannot create iterator, onexit aborted: %s"),
mu_strerror (rc));
mu_stream_destroy (&mu_strerr);
_exit (127);
}
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
struct onexit_closure *cp;
int rc = mu_iterator_current (itr, (void**)&cp);
if (rc)
{
status = 127;
mu_error (_("cannot obtain current item while traversing the"
" onexit action list: %s"), mu_strerror (rc));
}
else
cp->function (cp->data);
mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
}
mu_iterator_destroy (&itr);
mu_list_destroy (&onexit_list);
if (status)
_exit (status);
}
int
mu_onexit (mu_onexit_t func, void *data)
{
struct onexit_closure *clos = malloc (sizeof (*clos));
if (!clos)
return ENOMEM;
clos->function = func;
clos->data = data;
if (!onexit_list)
{
int rc = mu_list_create (&onexit_list);
mu_list_set_destroy_item (onexit_list, mu_list_free_item);
if (rc)
return rc;
atexit (_mu_onexit_run);
}
return mu_list_append (onexit_list, clos);
}
void
mu_onexit_reset (void)
{
mu_list_clear (onexit_list);
}
......@@ -27,11 +27,20 @@
#include <mailutils/log.h>
#include <mailutils/stream.h>
#include <mailutils/stdstream.h>
#include <mailutils/util.h>
mu_stream_t mu_strin;
mu_stream_t mu_strout;
mu_stream_t mu_strerr;
static void
stdstream_flushall (void *data MU_ARG_UNUSED)
{
mu_stream_flush (mu_strin);
mu_stream_flush (mu_strout);
mu_stream_flush (mu_strerr);
}
void
mu_stdstream_setup ()
{
......@@ -44,20 +53,30 @@ mu_stdstream_setup ()
mu_stream_destroy (&mu_strerr);
/* Ensure that first 3 descriptors are open in proper mode */
fd = open ("/dev/null", O_WRONLY);
fd = open ("/dev/null", O_RDWR);
switch (fd)
{
case 2:
/* keep it open */;
break;
case 0:
/* Keep it and try to open 1 */
fd = open ("/dev/null", O_WRONLY);
if (fd != 1)
{
if (fd > 2)
close (fd);
break;
}
case 1:
/* keep it open and try 0 */
fd = open ("/dev/null", O_RDONLY);
if (fd != 0)
/* keep it open and try 2 */
fd = open ("/dev/null", O_WRONLY);
if (fd != 2)
close (fd);
break;
case 2:
/* keep it open */;
break;
default:
close (fd);
break;
......@@ -82,7 +101,7 @@ mu_stdstream_setup ()
if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0,
mu_program_name, NULL))
abort ();
/* FIXME: atexit (flushall) */
mu_onexit (stdstream_flushall, NULL);
}
int
......
......@@ -120,25 +120,15 @@ main (int argc, char **argv)
if (!component)
{
mu_stream_t in;
size_t size = 0;
char *p;
int yes = 1;
rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
if (rc)
{
mu_error (_("cannot create input stream: %s"), mu_strerror (rc));
exit (1);
}
mu_stream_ioctl (in, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
if (isatty (0))
{
printf (_("Component name: "));
fflush (stdout);
mu_printf (_("Component name: "));
mu_stream_flush (mu_strout);
}
rc = mu_stream_getline (in, &component, &size, NULL);
mu_stream_destroy (&in);
rc = mu_stream_getline (mu_strin, &component, &size, NULL);
if (rc)
{
mu_error (_("error reading input stream: %s"), mu_strerror (rc));
......
......@@ -58,6 +58,7 @@
#include <mailutils/property.h>
#include <mailutils/prog.h>
#include <mailutils/mh.h>
#include <mailutils/stdstream.h>
#include <mu_umaxtostr.h>
......
......@@ -53,6 +53,8 @@ void
mh_init ()
{
mh_ensure_stdin ();
mu_stdstream_setup ();
/* Register all mailbox and mailer formats */
mu_register_all_formats ();
#ifdef WITH_TLS
......@@ -756,18 +758,8 @@ mh_real_install (char *name, int automode)
char *home = mu_get_homedir ();
char *mhdir;
char *ctx;
mu_stream_t in;
int rc;
FILE *fp;
int yes;
rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
if (rc)
{
mu_error (_("cannot create input stream: %s"), mu_strerror (rc));
exit (1);
}
mu_stream_ioctl (in, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
mu_stream_t profile;
mhdir = mh_safe_make_file_name (home, "Mail");
......@@ -790,10 +782,11 @@ mh_real_install (char *name, int automode)
by question mark on output. */
local = mh_getyn_interactive (_("Do you want a path below your login directory"));
if (local)
printf (_("What is the path? "));
mu_printf (_("What is the path? "));
else
printf (_("What is the full path? "));
if (mu_stream_getline (in, &buf, &size, NULL))
mu_printf (_("What is the full path? "));
mu_stream_flush (mu_strin);
if (mu_stream_getline (mu_strin, &buf, &size, NULL))
exit (1);
p = mu_str_stripws (buf);
if (p > buf)
......@@ -813,21 +806,23 @@ mh_real_install (char *name, int automode)
if (mh_check_folder (mhdir, !automode))
exit (1);
fp = fopen (name, "w");
if (!fp)
rc = mu_file_stream_create (&profile, name,
MU_STREAM_WRITE | MU_STREAM_CREAT);
if (rc)
{
mu_error (_("cannot open file %s: %s"), name, mu_strerror (errno));
mu_error (_("cannot open file %s: %s"), name, mu_strerror (rc));
exit (1);
}
fprintf (fp, "Path: %s\n", mhdir);
fclose (fp);
mu_stream_printf (profile, "Path: %s\n", mhdir);
mu_stream_destroy (&profile);
ctx = mh_safe_make_file_name (mhdir, MH_CONTEXT_FILE);
fp = fopen (ctx, "w");
if (fp)
rc = mu_file_stream_create (&profile, ctx,
MU_STREAM_WRITE | MU_STREAM_CREAT);
if (rc)
{
fprintf (fp, "Current-Folder: inbox\n");
fclose (fp);
mu_stream_printf (profile, "Current-Folder: inbox\n");
mu_stream_destroy (&profile);
}
free (ctx);
ctx = mh_safe_make_file_name (mhdir, "inbox");
......@@ -842,7 +837,7 @@ mh_install (char *name, int automode)
{
struct stat st;
if (stat(name, &st))
if (stat (name, &st))
{
if (errno == ENOENT)
{
......
......@@ -331,29 +331,19 @@ static int
_whatnow (struct mh_whatnow_env *wh, struct action_tab *tab)
{
int rc, status = 0;
mu_stream_t in;
char *line = NULL;
size_t size = 0;
struct mu_wordsplit ws;
int wsflags = MU_WRDSF_DEFFLAGS|MU_WRDSF_COMMENT;
int yes = 1;
rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
if (rc)
{
mu_error (_("cannot create input stream: %s"), mu_strerror (rc));
exit (1);
}
mu_stream_ioctl (in, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
do
{
size_t n;
handler_fp fun;
printf ("%s ", wh->prompt);
fflush (stdout);
rc = mu_stream_getline (in, &line, &size, &n);
mu_printf ("%s ", wh->prompt);
mu_stream_flush (mu_strout);
rc = mu_stream_getline (mu_strin, &line, &size, &n);
if (rc)
{
mu_error (_("cannot read input stream: %s"), mu_strerror (rc));
......@@ -445,7 +435,7 @@ quit (struct mh_whatnow_env *wh, int argc, char **argv, int *status)
unlink (wh->draftfile);
else
{
printf (_("draft left on \"%s\".\n"), wh->draftfile);
mu_printf (_("draft left on \"%s\".\n"), wh->draftfile);
if (strcmp (wh->file, wh->draftfile))
rename (wh->file, wh->draftfile);
}
......
......@@ -152,12 +152,9 @@ open_output ()
rc = mu_command_stream_create (&output, moreproc, MU_STREAM_WRITE);
else
{
rc = mu_stdio_stream_create (&output, MU_STDOUT_FD, MU_STREAM_WRITE);
if (rc == 0)
{
int yes = 1;
mu_stream_ioctl (output, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
}
rc = 0;
output = mu_strout;
mu_stream_ref (output);
}
if (rc)
......@@ -178,12 +175,9 @@ list_message (char *name, mu_stream_t output)
if (!name)
{
rc = mu_stdio_stream_create (&input, MU_STDIN_FD, MU_STREAM_SEEK);
if (rc == 0)
{
int yes = 1;
mu_stream_ioctl (input, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
}
rc = 0;
input = mu_strin;
mu_stream_ref (input);
}
else
rc = mu_file_stream_create (&input, name, MU_STREAM_READ);
......
......@@ -1591,24 +1591,15 @@ show_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
int
mhn_show ()
{
int rc;
mu_stream_t ostr;
int yes = 1;
rc = mu_stdio_stream_create (&ostr, MU_STDOUT_FD, 0);
if (rc)
{
mu_error (_("cannot create output stream: %s"), mu_strerror (rc));
exit (1);
}
mu_stream_ioctl (ostr, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
mhl_format = mhl_format_compile (formfile);
if (message)
rc = show_message (message, 0, ostr);
rc = show_message (message, 0, mu_strout);
else
rc = mh_iterate (mbox, &msgset, show_iterator, ostr);
rc = mh_iterate (mbox, &msgset, show_iterator, mu_strout);
mu_stream_flush (mu_strout);
return rc;
}
......@@ -1804,20 +1795,16 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
case store_to_stdout:
printf (_("storing msg %s part %s to stdout\n"),
prefix, partstr);
rc = mu_stdio_stream_create (&out, MU_STDOUT_FD, 0);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", NULL, rc);
else
{
int yes = 1;
mu_stream_ioctl (out, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
}
rc = 0;
out = mu_strout;
mu_stream_ref (out);
break;
}
if (out)
{
show_internal (msg, part, encoding, out);
mu_stream_flush (out);
mu_stream_destroy (&out);
}
......
......@@ -299,16 +299,22 @@ static int
b_ascii (union argument *args)
{
int i;
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
int rc;
rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
if (rc)
{
mu_error ("fseek: %s", mu_strerror (errno));
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
return 0;
}
for (i = 0; i < args[1].number; i++)
{
int c = getc (mimeview_fp);
if (c == EOF)
char c;
size_t n;
rc = mu_stream_read (mimeview_stream, &c, 1, &n);
if (rc || n == 0)
break;
if (!mu_isascii (c))
return 0;
......@@ -329,17 +335,22 @@ static int
b_printable (union argument *args)
{
int i;
int rc;
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
if (rc)
{
mu_error ("fseek: %s", mu_strerror (errno));
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
return 0;
}
for (i = 0; i < args[1].number; i++)
{
int c = getc (mimeview_fp);
if (c == EOF)
char c;
size_t n;
rc = mu_stream_read (mimeview_stream, &c, 1, &n);
if (rc || n == 0)
break;
if (!ISPRINT ((unsigned)c))
return 0;
......@@ -355,17 +366,22 @@ b_string (union argument *args)
{
struct mimetypes_string *str = args[1].string;
int i;
int rc;
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
if (rc)
{
mu_error ("fseek: %s", mu_strerror (errno));
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
return 0;
}
for (i = 0; i < str->len; i++)
{
int c = getc (mimeview_fp);
if (c == EOF || (char)c != str->ptr[i])
char c;
size_t n;
rc = mu_stream_read (mimeview_stream, &c, 1, &n);
if (rc || n == 0 || c != str->ptr[i])
return 0;
}
return 1;
......@@ -381,33 +397,60 @@ b_istring (union argument *args)
int i;
struct mimetypes_string *str = args[1].string;
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
int rc;
rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
if (rc)
{
mu_error ("fseek: %s", mu_strerror (errno));
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
return 0;
}
for (i = 0; i < str->len; i++)
{
int c = getc (mimeview_fp);
if (c == EOF || mu_tolower (c) != mu_tolower (str->ptr[i]))
char c;
size_t n;
rc = mu_stream_read (mimeview_stream, &c, 1, &n);
if (rc || n == 0 || mu_tolower (c) != mu_tolower (str->ptr[i]))
return 0;
}
return 1;
}
int
compare_bytes (union argument *args, void *sample, void *buf, size_t size)
{
int rc;
size_t n;
rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
return 0;
}
rc = mu_stream_read (mimeview_stream, buf, sizeof (buf), &n);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_read", NULL, rc);
return 0;
}
else if (n != size)
return 0;
return memcmp (sample, buf, size) == 0;
}
/* char(offset,value)
True if byte is identical
*/
static int
b_char (union argument *args)
{
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
{
mu_error ("fseek: %s", mu_strerror (errno));
return 0;
}
return getc (mimeview_fp) == args[1].number;
char val = args[1].number;
char buf;
return compare_bytes (args, &val, &buf, sizeof (buf));
}
/* short(offset,value)
......@@ -417,24 +460,9 @@ b_char (union argument *args)
static int
b_short (union argument *args)
{
unsigned short val;
int rc;
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
{
mu_error ("fseek: %s", mu_strerror (errno));
return 0;
}
rc = fread (&val, sizeof val, 1, mimeview_fp);
if (rc == -1)
{
mu_error ("fread: %s", mu_strerror (errno));
return 0;
}
else if (rc == 0)
return 0;
return val == args[1].number;
unsigned short val = args[1].number;
unsigned short buf;
return compare_bytes (args, &val, &buf, sizeof (buf));
}
/* int(offset,value)
......@@ -444,23 +472,9 @@ b_short (union argument *args)
static int
b_int (union argument *args)
{
unsigned int val;
int rc;
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
{
mu_error ("fseek: %s", mu_strerror (errno));
return 0;
}
rc = fread (&val, sizeof val, 1, mimeview_fp);
if (rc == -1)
{
mu_error ("fread: %s", mu_strerror (errno));
return 0;
}
else if (rc == 0)
return 0;
return val == args[1].number;
unsigned int val = args[1].number;
unsigned int buf;
return compare_bytes (args, &val, &buf, sizeof (buf));
}
/* locale("string")
......@@ -479,20 +493,23 @@ b_locale (union argument *args)
static int
b_contains (union argument *args)
{
int i, count;
size_t i, count;
char *buf;
struct mimetypes_string *str = args[2].string;
int rc;
if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
if (rc)
{
mu_error ("fseek: %s", mu_strerror (errno));
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
return 0;
}
buf = xmalloc (args[1].number);
count = fread (buf, 1, args[1].number, mimeview_fp);
if (count == -1)
rc = mu_stream_read (mimeview_stream, buf, args[1].number, &count);
if (count != args[1].number)
{
mu_error ("fread: %s", mu_strerror (errno));
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_read", NULL, rc);
}
else if (count > str->len)
for (i = 0; i < count - str->len; i++)
......
......@@ -66,7 +66,7 @@ static char *no_ask_types; /* List of MIME types for which no questions
should be asked */
static int interactive = -1;
char *mimeview_file; /* Name of the file to view */
FILE *mimeview_fp; /* Its descriptor */
mu_stream_t mimeview_stream; /* The corresponding stream */
static void
set_debug_flags (const char *arg)
......@@ -184,7 +184,9 @@ static const char *capa[] = {
static int
open_file (char *name)
{
int rc;
struct stat st;
if (stat (name, &st))
{
mu_error (_("cannot stat `%s': %s"), name, mu_strerror (errno));
......@@ -197,10 +199,10 @@ open_file (char *name)
}
mimeview_file = name;
mimeview_fp = fopen (name, "r");
if (mimeview_fp == NULL)
rc = mu_file_stream_create (&mimeview_stream, mimeview_file, MU_STREAM_READ);
if (rc)
{
mu_error (_("Cannot open `%s': %s"), name, mu_strerror (errno));
mu_error (_("Cannot open `%s': %s"), name, mu_strerror (rc));
return -1;
}
return 0;
......@@ -209,7 +211,7 @@ open_file (char *name)
void
close_file ()
{
fclose (mimeview_fp);
mu_stream_close (mimeview_stream);
}
void
......@@ -244,7 +246,6 @@ display_file (const char *type)
}
else
{
mu_stream_t stream;
mu_header_t hdr;
char *text;
......@@ -254,20 +255,9 @@ display_file (const char *type)
mu_error (_("cannot create header: %s"), mu_strerror (status));
else
{
int yes = 1;
mu_stdio_stream_create (&stream, fileno (mimeview_fp),
MU_STREAM_READ|
MU_STREAM_SEEK);
mu_stream_ioctl (stream, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
display_stream_mailcap (mimeview_file, stream, hdr,
display_stream_mailcap (mimeview_file, mimeview_stream, hdr,
no_ask_types, interactive, dry_run,
debug_level);
mu_stream_close (stream);
mu_stream_destroy (&stream);
mu_header_destroy (&hdr);
}
}
......
......@@ -53,7 +53,7 @@ struct mimetypes_string *mimetypes_string_dup (struct mimetypes_string *s);
const char *get_file_type (void);
extern char *mimeview_file;
extern FILE *mimeview_fp;
extern mu_stream_t mimeview_stream;
extern int debug_level;
#define DEBUG(l,f) if (debug_level > (l)) printf f
......
......@@ -277,26 +277,26 @@ check_user_perm (int action, struct action_data *ap)
}
static void
print_entry (FILE *fp, DBM_DATUM key, DBM_DATUM contents)
print_entry (mu_stream_t str, DBM_DATUM key, DBM_DATUM contents)
{
if (compatibility_option)
fprintf (fp, "%.*s: %.*s\n",
(int) MU_DATUM_SIZE (key),
(char*) MU_DATUM_PTR (key),
(int) MU_DATUM_SIZE (contents),
(char*) MU_DATUM_PTR (contents));
mu_stream_printf (str, "%.*s: %.*s\n",
(int) MU_DATUM_SIZE (key),
(char*) MU_DATUM_PTR (key),
(int) MU_DATUM_SIZE (contents),
(char*) MU_DATUM_PTR (contents));
else
fprintf (fp, "%.*s %.*s\n",
(int) MU_DATUM_SIZE (key),
(char*) MU_DATUM_PTR (key),
(int) MU_DATUM_SIZE (contents),
(char*) MU_DATUM_PTR (contents));
mu_stream_printf (str, "%.*s %.*s\n",
(int) MU_DATUM_SIZE (key),
(char*) MU_DATUM_PTR (key),
(int) MU_DATUM_SIZE (contents),
(char*) MU_DATUM_PTR (contents));
}
int
action_list (struct action_data *ap)
{
FILE *fp;
mu_stream_t str;
DBM_FILE db;
DBM_DATUM key;
DBM_DATUM contents;
......@@ -311,15 +311,21 @@ action_list (struct action_data *ap)
if (ap->output_name)
{
fp = fopen (ap->output_name, "w");
if (!fp)
int rc = mu_file_stream_create (&str, ap->output_name,
MU_STREAM_WRITE|MU_STREAM_CREAT);
if (rc)
{
mu_error (_("cannot create file %s: %s"), ap->output_name, mu_strerror (errno));
mu_error (_("cannot create file %s: %s"),
ap->output_name, mu_strerror (rc));
return 1;
}
mu_stream_truncate (str, 0);
}
else
fp = stdout;
{
str = mu_strout;
mu_stream_ref (str);
}
if (ap->username)
{
......@@ -333,7 +339,7 @@ action_list (struct action_data *ap)
}
else
{
print_entry (fp, key, contents);
print_entry (str, key, contents);
mu_dbm_datum_free (&contents);
}
}
......@@ -344,13 +350,13 @@ action_list (struct action_data *ap)
{
memset (&contents, 0, sizeof contents);
mu_dbm_fetch (db, key, &contents);
print_entry (fp, key, contents);
print_entry (str, key, contents);
mu_dbm_datum_free (&contents);
}
}
mu_dbm_close (db);
fclose (fp);
mu_stream_destroy (&str);
return 0;
}
......@@ -653,7 +659,7 @@ popauth_version (FILE *stream, struct argp_state *state)
# define FORMAT "Tokyo Cabinet"
#endif
mu_program_version_hook (stream, state);
printf (_("Database format: %s\n"), FORMAT);
printf (_("Database location: %s\n"), APOP_PASSFILE);
fprintf (stream, _("Database format: %s\n"), FORMAT);
fprintf (stream, _("Database location: %s\n"), APOP_PASSFILE);
exit (EX_OK);
}
......