Commit 25db453e 25db453e96894f1f8c7320ec49a8213b9a2cdd1f by Alain Magloire

* doc/texinfo/programs.texi: Descibe the readmsg utility.

	* configure.in: Enable readmsg.
	* Makefile.in: Enable readmsg.
	* readmsg/readmsg.c: Implementation.
	* readmsg/msglist.c: Implement Elm weird expansion.
1 parent 89287b76
1 2001-12-31 Alain Magloire
2
3 * doc/texinfo/programs.texi: Descibe the readmsg utility.
4 * configure.in: Enable readmsg.
5 * Makefile.in: Enable readmsg.
6 * readmsg/readmsg.c: Implementation.
7 * readmsg/msglist.c: Implement Elm weird expansion.
8
1 2001-12-29 Sergey Poznyakoff 9 2001-12-29 Sergey Poznyakoff
2 10
3 * guimb/scm/numaddr.scm: (new) Implements "numaddr" extension 11 * guimb/scm/numaddr.scm: (new) Implements "numaddr" extension
......
...@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = gnu 1.4 ...@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = gnu 1.4
2 ACLOCAL_AMFLAGS = -I m4 2 ACLOCAL_AMFLAGS = -I m4
3 3
4 SUBDIRS = include doc m4 lib MySql argp mailbox frm from pop3d imap4d mail sieve \ 4 SUBDIRS = include doc m4 lib MySql argp mailbox frm from pop3d imap4d mail sieve \
5 scripts libmu_scm guimb messages comsat 5 scripts libmu_scm guimb messages comsat readmsg
6 6
7 EXTRA_DIST = mailutils.spec mailutils.spec.in README-alpha COPYING.FDL 7 EXTRA_DIST = mailutils.spec mailutils.spec.in README-alpha COPYING.FDL
8 8
......
...@@ -140,7 +140,7 @@ AC_FUNC_FNMATCH ...@@ -140,7 +140,7 @@ AC_FUNC_FNMATCH
140 if test "$ac_cv_func_fnmatch_works" = "no"; then 140 if test "$ac_cv_func_fnmatch_works" = "no"; then
141 : LIBOBJS="$LIBOBJS fnmatch.o" 141 : LIBOBJS="$LIBOBJS fnmatch.o"
142 fi 142 fi
143 AC_REPLACE_FUNCS(fgetpwent setenv snprintf strtok_r strncasecmp strcasecmp \ 143 AC_REPLACE_FUNCS(fgetpwent getpass setenv snprintf strtok_r strncasecmp strcasecmp \
144 strsignal vasprintf) 144 strsignal vasprintf)
145 AC_CHECK_FUNCS(mkstemp sigaction sysconf getdelim vsyslog) 145 AC_CHECK_FUNCS(mkstemp sigaction sysconf getdelim vsyslog)
146 146
...@@ -307,4 +307,5 @@ AC_OUTPUT(Makefile mailutils.spec include/Makefile include/mailutils/Makefile ...@@ -307,4 +307,5 @@ AC_OUTPUT(Makefile mailutils.spec include/Makefile include/mailutils/Makefile
307 mailbox/include/Makefile from/Makefile mail/Makefile pop3d/Makefile 307 mailbox/include/Makefile from/Makefile mail/Makefile pop3d/Makefile
308 frm/Makefile sieve/Makefile messages/Makefile scripts/Makefile 308 frm/Makefile sieve/Makefile messages/Makefile scripts/Makefile
309 libmu_scm/Makefile guimb/Makefile guimb/scm/Makefile 309 libmu_scm/Makefile guimb/Makefile guimb/scm/Makefile
310 readmsg/Makefile
310 MySql/Makefile mh/Makefile comsat/Makefile) 311 MySql/Makefile mh/Makefile comsat/Makefile)
......
...@@ -1444,7 +1444,71 @@ Output program version and exit. ...@@ -1444,7 +1444,71 @@ Output program version and exit.
1444 @section readmsg --- Extract messages from a folder. 1444 @section readmsg --- Extract messages from a folder.
1445 @pindex readmsg 1445 @pindex readmsg
1446 1446
1447 The program is currently in development 1447 The program, readmsg, extracts with the selection argument messages from
1448 a mailbox. Selection can be specify by:
1449
1450 @enumerate
1451
1452 @item
1453 A lone ``*'' means select all messages in the mailbox.
1454
1455 @item
1456 A list of message numbers may be specified. Values
1457 of ``0'' and ``$'' in the list both mean the last
1458 message in the mailbox. For example:
1459 @example
1460 readmsg 1 3 0
1461 @end example
1462 extracts three messages from the folder: the first, the third, and the last.
1463
1464 @item
1465 Finally, the selection may be some text to match. This will select a mail
1466 message which exactly matches the specified text. For example,
1467 @example
1468 readmsg staff meeting
1469 @end example
1470 extracts the message which contains the words ``staff meeting.'' Note that it
1471 will not match a message containing ``Staff Meeting'' - the matching is case
1472 sensitive. Normally only the first message which matches the pattern will be
1473 printed.
1474
1475 @end enumerate
1476
1477 @subheading Command line options
1478
1479 @table @samp
1480
1481 @item -a
1482 @itemx --show-all
1483 If a pattern is use for selection show all messages that match pattern
1484 by default only the first one is presented.
1485
1486 @item -d
1487 @itemx --debug
1488 Display mailbox debuging information.
1489
1490 @item -f @var{MAILBOX}
1491 @itemx --folder=@var{MAILBOX}
1492 Specified the default mailbox.
1493
1494 @item -h
1495 @itemx --header
1496 Show the entire header and ignore the weedlist.
1497
1498 @item -n
1499 @itemx --no-header
1500 Do not print the message header.
1501
1502 @item -p
1503 @itemx --form-feed
1504 Put form-feed (Control-L) between messages instead of newline.
1505
1506 @item -w @var{weedlist}
1507 @itemx --weedlist=@var{weedlist}
1508 A whitespace or coma separated list of header names to show per message.
1509 Default is --weedlist=''From Subject Date To CC Apparently-''
1510
1511 @end table
1448 1512
1449 @page 1513 @page
1450 @node sieve 1514 @node sieve
......
...@@ -37,74 +37,104 @@ addset (int **set, int *n, unsigned val) ...@@ -37,74 +37,104 @@ addset (int **set, int *n, unsigned val)
37 return 0; 37 return 0;
38 } 38 }
39 39
40 static int
41 isnumber (const char *s)
42 {
43 int is_number = 1;
44 if (*s == '\0')
45 is_number = 0;
46 for (; *s; s++)
47 {
48 if (!isdigit ((unsigned char)*s))
49 {
50 is_number = 0;
51 break;
52 }
53 }
54 return is_number;
55 }
56
57 /*
58 According to ELM readmsg(1):
59
60 1. A lone ``*'' means select all messages in the mailbox.
61
62 2. A list of message numbers may be specified. Values of ``0'' and ``$'' in the
63 list both mean the last message in the mailbox. For example:
64
65 readmsg 1 3 0
66
67 extracts three messages from the folder: the first, the third, and the last.
68
69 3. Finally, the selection may be some text to match. This will select a mail
70 message which exactly matches the specified text. For example,
71
72 readmsg staff meeting
73
74 extracts the message which contains the words ``staff meeting.'' Note that it
75 will not match a message containing ``Staff Meeting'' - the matching is case
76 sensitive. Normally only the first message which matches the pattern will be
77 printed. The -a option discussed in a moment changes this.
78 */
79
40 int 80 int
41 msgset (const int argc, char **argv, int **set, int *n) 81 msglist (mailbox_t mbox, int show_all, int argc, char **argv, int **set, int *n)
42 { 82 {
43 int i = 0, lc = 0; 83 int i = 0;
44 int undelete = 0; 84 size_t total = 0;
45 int *ret = NULL; 85
86 mailbox_messages_count (mbox, &total);
46 87
47 for (i = 0; i < argc; i++) 88 for (i = 0; i < argc; i++)
48 { 89 {
49 /* Last message */ 90 /* 1. A lone ``*'' means select all messages in the mailbox. */
50 if (!strcmp (argv[i], "$") || !strcmp (argv[i], "0")) 91 if (!strcmp (argv[i], "*"))
51 { 92 {
52 addset (set, n, total); 93 size_t j;
94 /* all messages */
95 for (j = 1; j <= total; j++)
96 addset (set, n, j);
97 j = argc + 1;
53 } 98 }
54 else if (!strcmp (argv[i], "*")) 99 /* 2. A list of message numbers may be specified. Values of ``0'' and ``$'' in the
100 list both mean the last message in the mailbox. */
101 else if (!strcmp (argv[i], "$") || !strcmp (argv[i], "0"))
55 { 102 {
56 /* all messages */ 103 size_t j;
57 for (i = 1; i <= total; i++) 104 mailbox_messages_count (mbox, &total);
58 addset (set, n, i); 105 for (j = 1; j < total; j++)
59 i = argc + 1; 106 addset (set, n, j);
60 } 107 }
61 else if (argv[i][0] == '/') 108 /* 3. Finally, the selection may be some text to match. This will select a mail
109 message which exactly matches the specified text. */
110 else if (!isnumber(argv[i]))
62 { 111 {
63 /* FIXME: all messages with pattern following / in 112 size_t j;
64 the subject line, case insensitive */ 113 int found = 0;
65 /* This currently appears to be quit b0rked */
66 message_t msg;
67 header_t hdr;
68 char subj[128];
69 int j = 1, k = 0, len2 = 0;
70 int len = strlen (&argv[i][1]);
71 for (j = 1; j <= total; j++) 114 for (j = 1; j <= total; j++)
72 { 115 {
116 char buf[128];
117 size_t len = 0;
118 off_t offset = 0;
119 message_t msg = NULL;
120 stream_t stream = NULL;
73 mailbox_get_message (mbox, j, &msg); 121 mailbox_get_message (mbox, j, &msg);
74 message_get_header (msg, &hdr); 122 message_get_stream (msg, &stream);
75 header_get_value (hdr, MU_HEADER_SUBJECT, subj, 128, NULL); 123 while (stream_readline (stream, buf, sizeof buf, offset, &len) == 0 && len > 0)
76 len2 = strlen (subj);
77 for (k = 0; i < strlen (subj); k++)
78 { 124 {
79 if (len2 - k >= len 125 if (strstr (buf, argv[i]) != NULL)
80 && !strncasecmp (&argv[i][1], &subj[k], len))
81 { 126 {
82 addset (set, n, j); 127 addset (set, n, j);
83 k = 128; 128 found = 1;
84 } 129 break;
85 }
86 } 130 }
131 offset += len;
87 } 132 }
88 else if (isalpha(argv[i][0])) 133 if (found && !show_all)
89 {
90 /* FIXME: all messages from sender argv[i] */
91 }
92 else if (strchr (argv[i], '-') != NULL)
93 {
94 /* message range */
95 int j, x, y;
96 char *arg = strdup (argv[i]);
97 for (j = 0; j < strlen (arg); j++)
98 if (arg[j] == '-')
99 break; 134 break;
100 arg[j] = '\0';
101 x = strtol (arg, NULL, 10);
102 y = strtol (&(arg[j + 1]), NULL, 10);
103 for (; x <= y; x++)
104 addset (set, n, x);
105 free (arg);
106 } 135 }
107 else 136 }
137 else if (isdigit (argv[i][0]))
108 { 138 {
109 /* single message */ 139 /* single message */
110 addset (set, n, strtol (argv[i], NULL, 10)); 140 addset (set, n, strtol (argv[i], NULL, 10));
......
...@@ -22,9 +22,11 @@ ...@@ -22,9 +22,11 @@
22 #include <stdio.h> 22 #include <stdio.h>
23 #include <stdlib.h> 23 #include <stdlib.h>
24 #include <string.h> 24 #include <string.h>
25 #include <ctype.h>
25 #include <unistd.h> 26 #include <unistd.h>
26 #include <limits.h> 27 #include <limits.h>
27 #include <errno.h> 28 #include <errno.h>
29 #include <getopt.h>
28 30
29 #include <mailutils/mailbox.h> 31 #include <mailutils/mailbox.h>
30 #include <mailutils/header.h> 32 #include <mailutils/header.h>
...@@ -32,7 +34,13 @@ ...@@ -32,7 +34,13 @@
32 #include <mailutils/filter.h> 34 #include <mailutils/filter.h>
33 #include <mailutils/registrar.h> 35 #include <mailutils/registrar.h>
34 36
35 extern mailbox_t mbox; 37 #ifndef __P
36 extern size_t total; 38 #ifdef __STDC__
39 #define __P(args) args
40 #else
41 #define __P(args) ()
42 #endif
43 #endif /*__P */
37 44
45 int msglist __P ((mailbox_t mbox, int show_all, int argc, char **argv, int **set, int *n));
38 #endif 46 #endif
......