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; ...@@ -118,7 +118,9 @@ typedef struct _mu_opool *mu_opool_t;
118 typedef struct _mu_progmailer *mu_progmailer_t; 118 typedef struct _mu_progmailer *mu_progmailer_t;
119 typedef struct _mu_secret *mu_secret_t; 119 typedef struct _mu_secret *mu_secret_t;
120 typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t; 120 typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t;
121 121
122 typedef void (*mu_onexit_t) (void*);
123
122 #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 124 #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001
123 #define MU_FOLDER_ATTRIBUTE_FILE 0x002 125 #define MU_FOLDER_ATTRIBUTE_FILE 0x002
124 #define MU_FOLDER_ATTRIBUTE_LINK 0x004 126 #define MU_FOLDER_ATTRIBUTE_LINK 0x004
......
...@@ -187,6 +187,11 @@ int mu_fd_wait (int fd, int *pflags, struct timeval *tvp); ...@@ -187,6 +187,11 @@ int mu_fd_wait (int fd, int *pflags, struct timeval *tvp);
187 int mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab, 187 int mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab,
188 int *perr); 188 int *perr);
189 189
190 /* Reset the onexit list. */
191 void mu_onexit_reset (void);
192 /* Register the onexit function and associated data */
193 int mu_onexit (mu_onexit_t func, void *data);
194
190 #ifdef __cplusplus 195 #ifdef __cplusplus
191 } 196 }
192 #endif 197 #endif
......
...@@ -620,8 +620,9 @@ find_entry (const char *file, struct mime_context *ctx) ...@@ -620,8 +620,9 @@ find_entry (const char *file, struct mime_context *ctx)
620 status = mu_file_stream_create (&stream, file, MU_STREAM_READ); 620 status = mu_file_stream_create (&stream, file, MU_STREAM_READ);
621 if (status) 621 if (status)
622 { 622 {
623 mu_error ("cannot create file stream %s: %s", 623 if (status != ENOENT)
624 file, mu_strerror (status)); 624 mu_error ("cannot open input stream %s: %s",
625 file, mu_strerror (status));
625 return -1; 626 return -1;
626 } 627 }
627 628
......
...@@ -49,6 +49,7 @@ libbase_la_SOURCES = \ ...@@ -49,6 +49,7 @@ libbase_la_SOURCES = \
49 nls.c\ 49 nls.c\
50 nullrec.c\ 50 nullrec.c\
51 observer.c\ 51 observer.c\
52 onexit.c\
52 opool.c\ 53 opool.c\
53 parsedate.c\ 54 parsedate.c\
54 permstr.c\ 55 permstr.c\
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <mailutils/types.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/error.h>
26 #include <mailutils/list.h>
27 #include <mailutils/iterator.h>
28 #include <mailutils/nls.h>
29 #include <mailutils/stream.h>
30 #include <mailutils/stdstream.h>
31
32 struct onexit_closure
33 {
34 mu_onexit_t function;
35 void *data;
36 };
37
38 static mu_list_t onexit_list;
39
40 void
41 _mu_onexit_run (void)
42 {
43 mu_iterator_t itr;
44 int rc, status = 0;
45
46 rc = mu_list_get_iterator (onexit_list, &itr);
47 if (rc)
48 {
49 mu_error (_("cannot create iterator, onexit aborted: %s"),
50 mu_strerror (rc));
51 mu_stream_destroy (&mu_strerr);
52 _exit (127);
53 }
54
55 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
56 mu_iterator_next (itr))
57 {
58 struct onexit_closure *cp;
59 int rc = mu_iterator_current (itr, (void**)&cp);
60 if (rc)
61 {
62 status = 127;
63 mu_error (_("cannot obtain current item while traversing the"
64 " onexit action list: %s"), mu_strerror (rc));
65 }
66 else
67 cp->function (cp->data);
68 mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
69 }
70 mu_iterator_destroy (&itr);
71 mu_list_destroy (&onexit_list);
72 if (status)
73 _exit (status);
74 }
75
76 int
77 mu_onexit (mu_onexit_t func, void *data)
78 {
79 struct onexit_closure *clos = malloc (sizeof (*clos));
80 if (!clos)
81 return ENOMEM;
82 clos->function = func;
83 clos->data = data;
84 if (!onexit_list)
85 {
86 int rc = mu_list_create (&onexit_list);
87 mu_list_set_destroy_item (onexit_list, mu_list_free_item);
88 if (rc)
89 return rc;
90 atexit (_mu_onexit_run);
91 }
92 return mu_list_append (onexit_list, clos);
93 }
94
95 void
96 mu_onexit_reset (void)
97 {
98 mu_list_clear (onexit_list);
99 }
...@@ -27,11 +27,20 @@ ...@@ -27,11 +27,20 @@
27 #include <mailutils/log.h> 27 #include <mailutils/log.h>
28 #include <mailutils/stream.h> 28 #include <mailutils/stream.h>
29 #include <mailutils/stdstream.h> 29 #include <mailutils/stdstream.h>
30 #include <mailutils/util.h>
30 31
31 mu_stream_t mu_strin; 32 mu_stream_t mu_strin;
32 mu_stream_t mu_strout; 33 mu_stream_t mu_strout;
33 mu_stream_t mu_strerr; 34 mu_stream_t mu_strerr;
34 35
36 static void
37 stdstream_flushall (void *data MU_ARG_UNUSED)
38 {
39 mu_stream_flush (mu_strin);
40 mu_stream_flush (mu_strout);
41 mu_stream_flush (mu_strerr);
42 }
43
35 void 44 void
36 mu_stdstream_setup () 45 mu_stdstream_setup ()
37 { 46 {
...@@ -44,20 +53,30 @@ mu_stdstream_setup () ...@@ -44,20 +53,30 @@ mu_stdstream_setup ()
44 mu_stream_destroy (&mu_strerr); 53 mu_stream_destroy (&mu_strerr);
45 54
46 /* Ensure that first 3 descriptors are open in proper mode */ 55 /* Ensure that first 3 descriptors are open in proper mode */
47 fd = open ("/dev/null", O_WRONLY); 56 fd = open ("/dev/null", O_RDWR);
48 switch (fd) 57 switch (fd)
49 { 58 {
50 case 2: 59 case 0:
51 /* keep it open */; 60 /* Keep it and try to open 1 */
52 break; 61 fd = open ("/dev/null", O_WRONLY);
62 if (fd != 1)
63 {
64 if (fd > 2)
65 close (fd);
66 break;
67 }
53 68
54 case 1: 69 case 1:
55 /* keep it open and try 0 */ 70 /* keep it open and try 2 */
56 fd = open ("/dev/null", O_RDONLY); 71 fd = open ("/dev/null", O_WRONLY);
57 if (fd != 0) 72 if (fd != 2)
58 close (fd); 73 close (fd);
59 break; 74 break;
60 75
76 case 2:
77 /* keep it open */;
78 break;
79
61 default: 80 default:
62 close (fd); 81 close (fd);
63 break; 82 break;
...@@ -82,7 +101,7 @@ mu_stdstream_setup () ...@@ -82,7 +101,7 @@ mu_stdstream_setup ()
82 if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0, 101 if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0,
83 mu_program_name, NULL)) 102 mu_program_name, NULL))
84 abort (); 103 abort ();
85 /* FIXME: atexit (flushall) */ 104 mu_onexit (stdstream_flushall, NULL);
86 } 105 }
87 106
88 int 107 int
......
...@@ -120,25 +120,15 @@ main (int argc, char **argv) ...@@ -120,25 +120,15 @@ main (int argc, char **argv)
120 120
121 if (!component) 121 if (!component)
122 { 122 {
123 mu_stream_t in;
124 size_t size = 0; 123 size_t size = 0;
125 char *p; 124 char *p;
126 int yes = 1;
127 125
128 rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
129 if (rc)
130 {
131 mu_error (_("cannot create input stream: %s"), mu_strerror (rc));
132 exit (1);
133 }
134 mu_stream_ioctl (in, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
135 if (isatty (0)) 126 if (isatty (0))
136 { 127 {
137 printf (_("Component name: ")); 128 mu_printf (_("Component name: "));
138 fflush (stdout); 129 mu_stream_flush (mu_strout);
139 } 130 }
140 rc = mu_stream_getline (in, &component, &size, NULL); 131 rc = mu_stream_getline (mu_strin, &component, &size, NULL);
141 mu_stream_destroy (&in);
142 if (rc) 132 if (rc)
143 { 133 {
144 mu_error (_("error reading input stream: %s"), mu_strerror (rc)); 134 mu_error (_("error reading input stream: %s"), mu_strerror (rc));
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
58 #include <mailutils/property.h> 58 #include <mailutils/property.h>
59 #include <mailutils/prog.h> 59 #include <mailutils/prog.h>
60 #include <mailutils/mh.h> 60 #include <mailutils/mh.h>
61 #include <mailutils/stdstream.h>
61 62
62 #include <mu_umaxtostr.h> 63 #include <mu_umaxtostr.h>
63 64
......
...@@ -53,6 +53,8 @@ void ...@@ -53,6 +53,8 @@ void
53 mh_init () 53 mh_init ()
54 { 54 {
55 mh_ensure_stdin (); 55 mh_ensure_stdin ();
56 mu_stdstream_setup ();
57
56 /* Register all mailbox and mailer formats */ 58 /* Register all mailbox and mailer formats */
57 mu_register_all_formats (); 59 mu_register_all_formats ();
58 #ifdef WITH_TLS 60 #ifdef WITH_TLS
...@@ -756,18 +758,8 @@ mh_real_install (char *name, int automode) ...@@ -756,18 +758,8 @@ mh_real_install (char *name, int automode)
756 char *home = mu_get_homedir (); 758 char *home = mu_get_homedir ();
757 char *mhdir; 759 char *mhdir;
758 char *ctx; 760 char *ctx;
759 mu_stream_t in;
760 int rc; 761 int rc;
761 FILE *fp; 762 mu_stream_t profile;
762 int yes;
763
764 rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
765 if (rc)
766 {
767 mu_error (_("cannot create input stream: %s"), mu_strerror (rc));
768 exit (1);
769 }
770 mu_stream_ioctl (in, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
771 763
772 mhdir = mh_safe_make_file_name (home, "Mail"); 764 mhdir = mh_safe_make_file_name (home, "Mail");
773 765
...@@ -790,10 +782,11 @@ mh_real_install (char *name, int automode) ...@@ -790,10 +782,11 @@ mh_real_install (char *name, int automode)
790 by question mark on output. */ 782 by question mark on output. */
791 local = mh_getyn_interactive (_("Do you want a path below your login directory")); 783 local = mh_getyn_interactive (_("Do you want a path below your login directory"));
792 if (local) 784 if (local)
793 printf (_("What is the path? ")); 785 mu_printf (_("What is the path? "));
794 else 786 else
795 printf (_("What is the full path? ")); 787 mu_printf (_("What is the full path? "));
796 if (mu_stream_getline (in, &buf, &size, NULL)) 788 mu_stream_flush (mu_strin);
789 if (mu_stream_getline (mu_strin, &buf, &size, NULL))
797 exit (1); 790 exit (1);
798 p = mu_str_stripws (buf); 791 p = mu_str_stripws (buf);
799 if (p > buf) 792 if (p > buf)
...@@ -813,21 +806,23 @@ mh_real_install (char *name, int automode) ...@@ -813,21 +806,23 @@ mh_real_install (char *name, int automode)
813 if (mh_check_folder (mhdir, !automode)) 806 if (mh_check_folder (mhdir, !automode))
814 exit (1); 807 exit (1);
815 808
816 fp = fopen (name, "w"); 809 rc = mu_file_stream_create (&profile, name,
817 if (!fp) 810 MU_STREAM_WRITE | MU_STREAM_CREAT);
811 if (rc)
818 { 812 {
819 mu_error (_("cannot open file %s: %s"), name, mu_strerror (errno)); 813 mu_error (_("cannot open file %s: %s"), name, mu_strerror (rc));
820 exit (1); 814 exit (1);
821 } 815 }
822 fprintf (fp, "Path: %s\n", mhdir); 816 mu_stream_printf (profile, "Path: %s\n", mhdir);
823 fclose (fp); 817 mu_stream_destroy (&profile);
824 818
825 ctx = mh_safe_make_file_name (mhdir, MH_CONTEXT_FILE); 819 ctx = mh_safe_make_file_name (mhdir, MH_CONTEXT_FILE);
826 fp = fopen (ctx, "w"); 820 rc = mu_file_stream_create (&profile, ctx,
827 if (fp) 821 MU_STREAM_WRITE | MU_STREAM_CREAT);
822 if (rc)
828 { 823 {
829 fprintf (fp, "Current-Folder: inbox\n"); 824 mu_stream_printf (profile, "Current-Folder: inbox\n");
830 fclose (fp); 825 mu_stream_destroy (&profile);
831 } 826 }
832 free (ctx); 827 free (ctx);
833 ctx = mh_safe_make_file_name (mhdir, "inbox"); 828 ctx = mh_safe_make_file_name (mhdir, "inbox");
...@@ -842,7 +837,7 @@ mh_install (char *name, int automode) ...@@ -842,7 +837,7 @@ mh_install (char *name, int automode)
842 { 837 {
843 struct stat st; 838 struct stat st;
844 839
845 if (stat(name, &st)) 840 if (stat (name, &st))
846 { 841 {
847 if (errno == ENOENT) 842 if (errno == ENOENT)
848 { 843 {
......
...@@ -331,29 +331,19 @@ static int ...@@ -331,29 +331,19 @@ static int
331 _whatnow (struct mh_whatnow_env *wh, struct action_tab *tab) 331 _whatnow (struct mh_whatnow_env *wh, struct action_tab *tab)
332 { 332 {
333 int rc, status = 0; 333 int rc, status = 0;
334 mu_stream_t in;
335 char *line = NULL; 334 char *line = NULL;
336 size_t size = 0; 335 size_t size = 0;
337 struct mu_wordsplit ws; 336 struct mu_wordsplit ws;
338 int wsflags = MU_WRDSF_DEFFLAGS|MU_WRDSF_COMMENT; 337 int wsflags = MU_WRDSF_DEFFLAGS|MU_WRDSF_COMMENT;
339 int yes = 1;
340 338
341 rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
342 if (rc)
343 {
344 mu_error (_("cannot create input stream: %s"), mu_strerror (rc));
345 exit (1);
346 }
347 mu_stream_ioctl (in, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
348
349 do 339 do
350 { 340 {
351 size_t n; 341 size_t n;
352 handler_fp fun; 342 handler_fp fun;
353 343
354 printf ("%s ", wh->prompt); 344 mu_printf ("%s ", wh->prompt);
355 fflush (stdout); 345 mu_stream_flush (mu_strout);
356 rc = mu_stream_getline (in, &line, &size, &n); 346 rc = mu_stream_getline (mu_strin, &line, &size, &n);
357 if (rc) 347 if (rc)
358 { 348 {
359 mu_error (_("cannot read input stream: %s"), mu_strerror (rc)); 349 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) ...@@ -445,7 +435,7 @@ quit (struct mh_whatnow_env *wh, int argc, char **argv, int *status)
445 unlink (wh->draftfile); 435 unlink (wh->draftfile);
446 else 436 else
447 { 437 {
448 printf (_("draft left on \"%s\".\n"), wh->draftfile); 438 mu_printf (_("draft left on \"%s\".\n"), wh->draftfile);
449 if (strcmp (wh->file, wh->draftfile)) 439 if (strcmp (wh->file, wh->draftfile))
450 rename (wh->file, wh->draftfile); 440 rename (wh->file, wh->draftfile);
451 } 441 }
......
...@@ -152,12 +152,9 @@ open_output () ...@@ -152,12 +152,9 @@ open_output ()
152 rc = mu_command_stream_create (&output, moreproc, MU_STREAM_WRITE); 152 rc = mu_command_stream_create (&output, moreproc, MU_STREAM_WRITE);
153 else 153 else
154 { 154 {
155 rc = mu_stdio_stream_create (&output, MU_STDOUT_FD, MU_STREAM_WRITE); 155 rc = 0;
156 if (rc == 0) 156 output = mu_strout;
157 { 157 mu_stream_ref (output);
158 int yes = 1;
159 mu_stream_ioctl (output, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
160 }
161 } 158 }
162 159
163 if (rc) 160 if (rc)
...@@ -178,12 +175,9 @@ list_message (char *name, mu_stream_t output) ...@@ -178,12 +175,9 @@ list_message (char *name, mu_stream_t output)
178 175
179 if (!name) 176 if (!name)
180 { 177 {
181 rc = mu_stdio_stream_create (&input, MU_STDIN_FD, MU_STREAM_SEEK); 178 rc = 0;
182 if (rc == 0) 179 input = mu_strin;
183 { 180 mu_stream_ref (input);
184 int yes = 1;
185 mu_stream_ioctl (input, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
186 }
187 } 181 }
188 else 182 else
189 rc = mu_file_stream_create (&input, name, MU_STREAM_READ); 183 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) ...@@ -1591,24 +1591,15 @@ show_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
1591 int 1591 int
1592 mhn_show () 1592 mhn_show ()
1593 { 1593 {
1594
1594 int rc; 1595 int rc;
1595 mu_stream_t ostr;
1596 int yes = 1;
1597
1598 rc = mu_stdio_stream_create (&ostr, MU_STDOUT_FD, 0);
1599 if (rc)
1600 {
1601 mu_error (_("cannot create output stream: %s"), mu_strerror (rc));
1602 exit (1);
1603 }
1604 mu_stream_ioctl (ostr, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
1605
1606 mhl_format = mhl_format_compile (formfile); 1596 mhl_format = mhl_format_compile (formfile);
1607 1597
1608 if (message) 1598 if (message)
1609 rc = show_message (message, 0, ostr); 1599 rc = show_message (message, 0, mu_strout);
1610 else 1600 else
1611 rc = mh_iterate (mbox, &msgset, show_iterator, ostr); 1601 rc = mh_iterate (mbox, &msgset, show_iterator, mu_strout);
1602 mu_stream_flush (mu_strout);
1612 return rc; 1603 return rc;
1613 } 1604 }
1614 1605
...@@ -1804,20 +1795,16 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, ...@@ -1804,20 +1795,16 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
1804 case store_to_stdout: 1795 case store_to_stdout:
1805 printf (_("storing msg %s part %s to stdout\n"), 1796 printf (_("storing msg %s part %s to stdout\n"),
1806 prefix, partstr); 1797 prefix, partstr);
1807 rc = mu_stdio_stream_create (&out, MU_STDOUT_FD, 0); 1798 rc = 0;
1808 if (rc) 1799 out = mu_strout;
1809 mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", NULL, rc); 1800 mu_stream_ref (out);
1810 else
1811 {
1812 int yes = 1;
1813 mu_stream_ioctl (out, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
1814 }
1815 break; 1801 break;
1816 } 1802 }
1817 1803
1818 if (out) 1804 if (out)
1819 { 1805 {
1820 show_internal (msg, part, encoding, out); 1806 show_internal (msg, part, encoding, out);
1807 mu_stream_flush (out);
1821 mu_stream_destroy (&out); 1808 mu_stream_destroy (&out);
1822 } 1809 }
1823 1810
......
...@@ -299,16 +299,22 @@ static int ...@@ -299,16 +299,22 @@ static int
299 b_ascii (union argument *args) 299 b_ascii (union argument *args)
300 { 300 {
301 int i; 301 int i;
302 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1) 302 int rc;
303
304 rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
305 if (rc)
303 { 306 {
304 mu_error ("fseek: %s", mu_strerror (errno)); 307 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
305 return 0; 308 return 0;
306 } 309 }
307 310
308 for (i = 0; i < args[1].number; i++) 311 for (i = 0; i < args[1].number; i++)
309 { 312 {
310 int c = getc (mimeview_fp); 313 char c;
311 if (c == EOF) 314 size_t n;
315
316 rc = mu_stream_read (mimeview_stream, &c, 1, &n);
317 if (rc || n == 0)
312 break; 318 break;
313 if (!mu_isascii (c)) 319 if (!mu_isascii (c))
314 return 0; 320 return 0;
...@@ -329,17 +335,22 @@ static int ...@@ -329,17 +335,22 @@ static int
329 b_printable (union argument *args) 335 b_printable (union argument *args)
330 { 336 {
331 int i; 337 int i;
338 int rc;
332 339
333 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1) 340 rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
341 if (rc)
334 { 342 {
335 mu_error ("fseek: %s", mu_strerror (errno)); 343 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
336 return 0; 344 return 0;
337 } 345 }
338 346
339 for (i = 0; i < args[1].number; i++) 347 for (i = 0; i < args[1].number; i++)
340 { 348 {
341 int c = getc (mimeview_fp); 349 char c;
342 if (c == EOF) 350 size_t n;
351
352 rc = mu_stream_read (mimeview_stream, &c, 1, &n);
353 if (rc || n == 0)
343 break; 354 break;
344 if (!ISPRINT ((unsigned)c)) 355 if (!ISPRINT ((unsigned)c))
345 return 0; 356 return 0;
...@@ -355,17 +366,22 @@ b_string (union argument *args) ...@@ -355,17 +366,22 @@ b_string (union argument *args)
355 { 366 {
356 struct mimetypes_string *str = args[1].string; 367 struct mimetypes_string *str = args[1].string;
357 int i; 368 int i;
369 int rc;
358 370
359 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1) 371 rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
372 if (rc)
360 { 373 {
361 mu_error ("fseek: %s", mu_strerror (errno)); 374 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
362 return 0; 375 return 0;
363 } 376 }
364 377
365 for (i = 0; i < str->len; i++) 378 for (i = 0; i < str->len; i++)
366 { 379 {
367 int c = getc (mimeview_fp); 380 char c;
368 if (c == EOF || (char)c != str->ptr[i]) 381 size_t n;
382
383 rc = mu_stream_read (mimeview_stream, &c, 1, &n);
384 if (rc || n == 0 || c != str->ptr[i])
369 return 0; 385 return 0;
370 } 386 }
371 return 1; 387 return 1;
...@@ -381,33 +397,60 @@ b_istring (union argument *args) ...@@ -381,33 +397,60 @@ b_istring (union argument *args)
381 int i; 397 int i;
382 struct mimetypes_string *str = args[1].string; 398 struct mimetypes_string *str = args[1].string;
383 399
384 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1) 400 int rc;
401
402 rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
403 if (rc)
385 { 404 {
386 mu_error ("fseek: %s", mu_strerror (errno)); 405 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
387 return 0; 406 return 0;
388 } 407 }
389 408
390 for (i = 0; i < str->len; i++) 409 for (i = 0; i < str->len; i++)
391 { 410 {
392 int c = getc (mimeview_fp); 411 char c;
393 if (c == EOF || mu_tolower (c) != mu_tolower (str->ptr[i])) 412 size_t n;
413
414 rc = mu_stream_read (mimeview_stream, &c, 1, &n);
415 if (rc || n == 0 || mu_tolower (c) != mu_tolower (str->ptr[i]))
394 return 0; 416 return 0;
395 } 417 }
396 return 1; 418 return 1;
397 } 419 }
398 420
421 int
422 compare_bytes (union argument *args, void *sample, void *buf, size_t size)
423 {
424 int rc;
425 size_t n;
426
427 rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
428 if (rc)
429 {
430 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
431 return 0;
432 }
433
434 rc = mu_stream_read (mimeview_stream, buf, sizeof (buf), &n);
435 if (rc)
436 {
437 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_read", NULL, rc);
438 return 0;
439 }
440 else if (n != size)
441 return 0;
442 return memcmp (sample, buf, size) == 0;
443 }
444
399 /* char(offset,value) 445 /* char(offset,value)
400 True if byte is identical 446 True if byte is identical
401 */ 447 */
402 static int 448 static int
403 b_char (union argument *args) 449 b_char (union argument *args)
404 { 450 {
405 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1) 451 char val = args[1].number;
406 { 452 char buf;
407 mu_error ("fseek: %s", mu_strerror (errno)); 453 return compare_bytes (args, &val, &buf, sizeof (buf));
408 return 0;
409 }
410 return getc (mimeview_fp) == args[1].number;
411 } 454 }
412 455
413 /* short(offset,value) 456 /* short(offset,value)
...@@ -417,24 +460,9 @@ b_char (union argument *args) ...@@ -417,24 +460,9 @@ b_char (union argument *args)
417 static int 460 static int
418 b_short (union argument *args) 461 b_short (union argument *args)
419 { 462 {
420 unsigned short val; 463 unsigned short val = args[1].number;
421 int rc; 464 unsigned short buf;
422 465 return compare_bytes (args, &val, &buf, sizeof (buf));
423 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
424 {
425 mu_error ("fseek: %s", mu_strerror (errno));
426 return 0;
427 }
428 rc = fread (&val, sizeof val, 1, mimeview_fp);
429
430 if (rc == -1)
431 {
432 mu_error ("fread: %s", mu_strerror (errno));
433 return 0;
434 }
435 else if (rc == 0)
436 return 0;
437 return val == args[1].number;
438 } 466 }
439 467
440 /* int(offset,value) 468 /* int(offset,value)
...@@ -444,23 +472,9 @@ b_short (union argument *args) ...@@ -444,23 +472,9 @@ b_short (union argument *args)
444 static int 472 static int
445 b_int (union argument *args) 473 b_int (union argument *args)
446 { 474 {
447 unsigned int val; 475 unsigned int val = args[1].number;
448 int rc; 476 unsigned int buf;
449 477 return compare_bytes (args, &val, &buf, sizeof (buf));
450 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1)
451 {
452 mu_error ("fseek: %s", mu_strerror (errno));
453 return 0;
454 }
455 rc = fread (&val, sizeof val, 1, mimeview_fp);
456 if (rc == -1)
457 {
458 mu_error ("fread: %s", mu_strerror (errno));
459 return 0;
460 }
461 else if (rc == 0)
462 return 0;
463 return val == args[1].number;
464 } 478 }
465 479
466 /* locale("string") 480 /* locale("string")
...@@ -479,20 +493,23 @@ b_locale (union argument *args) ...@@ -479,20 +493,23 @@ b_locale (union argument *args)
479 static int 493 static int
480 b_contains (union argument *args) 494 b_contains (union argument *args)
481 { 495 {
482 int i, count; 496 size_t i, count;
483 char *buf; 497 char *buf;
484 struct mimetypes_string *str = args[2].string; 498 struct mimetypes_string *str = args[2].string;
499 int rc;
485 500
486 if (fseek (mimeview_fp, args[0].number, SEEK_SET) == -1) 501 rc = mu_stream_seek (mimeview_stream, args[0].number, MU_SEEK_SET, NULL);
502 if (rc)
487 { 503 {
488 mu_error ("fseek: %s", mu_strerror (errno)); 504 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, rc);
489 return 0; 505 return 0;
490 } 506 }
507
491 buf = xmalloc (args[1].number); 508 buf = xmalloc (args[1].number);
492 count = fread (buf, 1, args[1].number, mimeview_fp); 509 rc = mu_stream_read (mimeview_stream, buf, args[1].number, &count);
493 if (count == -1) 510 if (count != args[1].number)
494 { 511 {
495 mu_error ("fread: %s", mu_strerror (errno)); 512 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_read", NULL, rc);
496 } 513 }
497 else if (count > str->len) 514 else if (count > str->len)
498 for (i = 0; i < count - str->len; i++) 515 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 ...@@ -66,7 +66,7 @@ static char *no_ask_types; /* List of MIME types for which no questions
66 should be asked */ 66 should be asked */
67 static int interactive = -1; 67 static int interactive = -1;
68 char *mimeview_file; /* Name of the file to view */ 68 char *mimeview_file; /* Name of the file to view */
69 FILE *mimeview_fp; /* Its descriptor */ 69 mu_stream_t mimeview_stream; /* The corresponding stream */
70 70
71 static void 71 static void
72 set_debug_flags (const char *arg) 72 set_debug_flags (const char *arg)
...@@ -184,7 +184,9 @@ static const char *capa[] = { ...@@ -184,7 +184,9 @@ static const char *capa[] = {
184 static int 184 static int
185 open_file (char *name) 185 open_file (char *name)
186 { 186 {
187 int rc;
187 struct stat st; 188 struct stat st;
189
188 if (stat (name, &st)) 190 if (stat (name, &st))
189 { 191 {
190 mu_error (_("cannot stat `%s': %s"), name, mu_strerror (errno)); 192 mu_error (_("cannot stat `%s': %s"), name, mu_strerror (errno));
...@@ -197,10 +199,10 @@ open_file (char *name) ...@@ -197,10 +199,10 @@ open_file (char *name)
197 } 199 }
198 200
199 mimeview_file = name; 201 mimeview_file = name;
200 mimeview_fp = fopen (name, "r"); 202 rc = mu_file_stream_create (&mimeview_stream, mimeview_file, MU_STREAM_READ);
201 if (mimeview_fp == NULL) 203 if (rc)
202 { 204 {
203 mu_error (_("Cannot open `%s': %s"), name, mu_strerror (errno)); 205 mu_error (_("Cannot open `%s': %s"), name, mu_strerror (rc));
204 return -1; 206 return -1;
205 } 207 }
206 return 0; 208 return 0;
...@@ -209,7 +211,7 @@ open_file (char *name) ...@@ -209,7 +211,7 @@ open_file (char *name)
209 void 211 void
210 close_file () 212 close_file ()
211 { 213 {
212 fclose (mimeview_fp); 214 mu_stream_close (mimeview_stream);
213 } 215 }
214 216
215 void 217 void
...@@ -244,7 +246,6 @@ display_file (const char *type) ...@@ -244,7 +246,6 @@ display_file (const char *type)
244 } 246 }
245 else 247 else
246 { 248 {
247 mu_stream_t stream;
248 mu_header_t hdr; 249 mu_header_t hdr;
249 char *text; 250 char *text;
250 251
...@@ -254,20 +255,9 @@ display_file (const char *type) ...@@ -254,20 +255,9 @@ display_file (const char *type)
254 mu_error (_("cannot create header: %s"), mu_strerror (status)); 255 mu_error (_("cannot create header: %s"), mu_strerror (status));
255 else 256 else
256 { 257 {
257 int yes = 1; 258 display_stream_mailcap (mimeview_file, mimeview_stream, hdr,
258
259 mu_stdio_stream_create (&stream, fileno (mimeview_fp),
260 MU_STREAM_READ|
261 MU_STREAM_SEEK);
262 mu_stream_ioctl (stream, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
263
264 display_stream_mailcap (mimeview_file, stream, hdr,
265 no_ask_types, interactive, dry_run, 259 no_ask_types, interactive, dry_run,
266 debug_level); 260 debug_level);
267
268 mu_stream_close (stream);
269 mu_stream_destroy (&stream);
270
271 mu_header_destroy (&hdr); 261 mu_header_destroy (&hdr);
272 } 262 }
273 } 263 }
......
...@@ -53,7 +53,7 @@ struct mimetypes_string *mimetypes_string_dup (struct mimetypes_string *s); ...@@ -53,7 +53,7 @@ struct mimetypes_string *mimetypes_string_dup (struct mimetypes_string *s);
53 const char *get_file_type (void); 53 const char *get_file_type (void);
54 54
55 extern char *mimeview_file; 55 extern char *mimeview_file;
56 extern FILE *mimeview_fp; 56 extern mu_stream_t mimeview_stream;
57 extern int debug_level; 57 extern int debug_level;
58 58
59 #define DEBUG(l,f) if (debug_level > (l)) printf f 59 #define DEBUG(l,f) if (debug_level > (l)) printf f
......
...@@ -277,26 +277,26 @@ check_user_perm (int action, struct action_data *ap) ...@@ -277,26 +277,26 @@ check_user_perm (int action, struct action_data *ap)
277 } 277 }
278 278
279 static void 279 static void
280 print_entry (FILE *fp, DBM_DATUM key, DBM_DATUM contents) 280 print_entry (mu_stream_t str, DBM_DATUM key, DBM_DATUM contents)
281 { 281 {
282 if (compatibility_option) 282 if (compatibility_option)
283 fprintf (fp, "%.*s: %.*s\n", 283 mu_stream_printf (str, "%.*s: %.*s\n",
284 (int) MU_DATUM_SIZE (key), 284 (int) MU_DATUM_SIZE (key),
285 (char*) MU_DATUM_PTR (key), 285 (char*) MU_DATUM_PTR (key),
286 (int) MU_DATUM_SIZE (contents), 286 (int) MU_DATUM_SIZE (contents),
287 (char*) MU_DATUM_PTR (contents)); 287 (char*) MU_DATUM_PTR (contents));
288 else 288 else
289 fprintf (fp, "%.*s %.*s\n", 289 mu_stream_printf (str, "%.*s %.*s\n",
290 (int) MU_DATUM_SIZE (key), 290 (int) MU_DATUM_SIZE (key),
291 (char*) MU_DATUM_PTR (key), 291 (char*) MU_DATUM_PTR (key),
292 (int) MU_DATUM_SIZE (contents), 292 (int) MU_DATUM_SIZE (contents),
293 (char*) MU_DATUM_PTR (contents)); 293 (char*) MU_DATUM_PTR (contents));
294 } 294 }
295 295
296 int 296 int
297 action_list (struct action_data *ap) 297 action_list (struct action_data *ap)
298 { 298 {
299 FILE *fp; 299 mu_stream_t str;
300 DBM_FILE db; 300 DBM_FILE db;
301 DBM_DATUM key; 301 DBM_DATUM key;
302 DBM_DATUM contents; 302 DBM_DATUM contents;
...@@ -311,15 +311,21 @@ action_list (struct action_data *ap) ...@@ -311,15 +311,21 @@ action_list (struct action_data *ap)
311 311
312 if (ap->output_name) 312 if (ap->output_name)
313 { 313 {
314 fp = fopen (ap->output_name, "w"); 314 int rc = mu_file_stream_create (&str, ap->output_name,
315 if (!fp) 315 MU_STREAM_WRITE|MU_STREAM_CREAT);
316 if (rc)
316 { 317 {
317 mu_error (_("cannot create file %s: %s"), ap->output_name, mu_strerror (errno)); 318 mu_error (_("cannot create file %s: %s"),
319 ap->output_name, mu_strerror (rc));
318 return 1; 320 return 1;
319 } 321 }
322 mu_stream_truncate (str, 0);
320 } 323 }
321 else 324 else
322 fp = stdout; 325 {
326 str = mu_strout;
327 mu_stream_ref (str);
328 }
323 329
324 if (ap->username) 330 if (ap->username)
325 { 331 {
...@@ -333,7 +339,7 @@ action_list (struct action_data *ap) ...@@ -333,7 +339,7 @@ action_list (struct action_data *ap)
333 } 339 }
334 else 340 else
335 { 341 {
336 print_entry (fp, key, contents); 342 print_entry (str, key, contents);
337 mu_dbm_datum_free (&contents); 343 mu_dbm_datum_free (&contents);
338 } 344 }
339 } 345 }
...@@ -344,13 +350,13 @@ action_list (struct action_data *ap) ...@@ -344,13 +350,13 @@ action_list (struct action_data *ap)
344 { 350 {
345 memset (&contents, 0, sizeof contents); 351 memset (&contents, 0, sizeof contents);
346 mu_dbm_fetch (db, key, &contents); 352 mu_dbm_fetch (db, key, &contents);
347 print_entry (fp, key, contents); 353 print_entry (str, key, contents);
348 mu_dbm_datum_free (&contents); 354 mu_dbm_datum_free (&contents);
349 } 355 }
350 } 356 }
351 357
352 mu_dbm_close (db); 358 mu_dbm_close (db);
353 fclose (fp); 359 mu_stream_destroy (&str);
354 return 0; 360 return 0;
355 } 361 }
356 362
...@@ -653,7 +659,7 @@ popauth_version (FILE *stream, struct argp_state *state) ...@@ -653,7 +659,7 @@ popauth_version (FILE *stream, struct argp_state *state)
653 # define FORMAT "Tokyo Cabinet" 659 # define FORMAT "Tokyo Cabinet"
654 #endif 660 #endif
655 mu_program_version_hook (stream, state); 661 mu_program_version_hook (stream, state);
656 printf (_("Database format: %s\n"), FORMAT); 662 fprintf (stream, _("Database format: %s\n"), FORMAT);
657 printf (_("Database location: %s\n"), APOP_PASSFILE); 663 fprintf (stream, _("Database location: %s\n"), APOP_PASSFILE);
658 exit (EX_OK); 664 exit (EX_OK);
659 } 665 }
......