update to mailx msglist parser (parts of it now work!)
tweak some mailx commands
Showing
9 changed files
with
162 additions
and
117 deletions
... | @@ -24,6 +24,19 @@ | ... | @@ -24,6 +24,19 @@ |
24 | int | 24 | int |
25 | mail_bang (int argc, char **argv) | 25 | mail_bang (int argc, char **argv) |
26 | { | 26 | { |
27 | printf ("Function not implemented in %s line %d\n", __FILE__, __LINE__); | 27 | int pid = fork (); |
28 | if (pid == 0) | ||
29 | { | ||
30 | free (argv[0]); | ||
31 | argv[0] = strdup ("/bin/sh"); | ||
32 | execv ("/bin/sh", argv); | ||
33 | return 1; | ||
34 | } | ||
35 | else if (pid > 0) | ||
36 | { | ||
37 | while (waitpid(pid, NULL, 0) == -1) | ||
38 | /* do nothing */; | ||
39 | return 0; | ||
40 | } | ||
28 | return 1; | 41 | return 1; |
29 | } | 42 | } | ... | ... |
... | @@ -32,12 +32,8 @@ mail_from (int argc, char **argv) | ... | @@ -32,12 +32,8 @@ mail_from (int argc, char **argv) |
32 | header_t hdr; | 32 | header_t hdr; |
33 | char *from, *subj; | 33 | char *from, *subj; |
34 | int froml, subjl; | 34 | int froml, subjl; |
35 | int columns = 74; | ||
36 | char format[64]; | 35 | char format[64]; |
37 | char *col = getenv("COLUMNS"); | 36 | int cols = util_getcols () - 6; |
38 | |||
39 | if (col) | ||
40 | columns = strtol (col, NULL, 10) - 5; | ||
41 | 37 | ||
42 | if (mailbox_get_message (mbox, cursor, &msg) != 0) | 38 | if (mailbox_get_message (mbox, cursor, &msg) != 0) |
43 | { | 39 | { |
... | @@ -45,9 +41,9 @@ mail_from (int argc, char **argv) | ... | @@ -45,9 +41,9 @@ mail_from (int argc, char **argv) |
45 | return 1; | 41 | return 1; |
46 | } | 42 | } |
47 | 43 | ||
48 | froml = columns / 3; | 44 | froml = cols / 3; |
49 | subjl = columns * 2 / 3; | 45 | subjl = cols * 2 / 3; |
50 | if (froml + subjl > columns) | 46 | if (froml + subjl > cols) |
51 | subjl--; | 47 | subjl--; |
52 | 48 | ||
53 | from = malloc (froml * sizeof (char)); | 49 | from = malloc (froml * sizeof (char)); | ... | ... |
... | @@ -24,34 +24,30 @@ | ... | @@ -24,34 +24,30 @@ |
24 | int | 24 | int |
25 | mail_headers (int argc, char **argv) | 25 | mail_headers (int argc, char **argv) |
26 | { | 26 | { |
27 | if (argc > 1) | 27 | char buf[64]; |
28 | return util_msglist_command (mail_headers, argc, argv); | 28 | int low = 1, high = total, middle = cursor; |
29 | else | 29 | int lines = util_getlines () - 2; |
30 | |||
31 | if (argc > 2) | ||
32 | return 1; | ||
33 | |||
34 | if (argc == 2) | ||
35 | middle = strtol (argv[1], NULL, 10); | ||
36 | |||
37 | if (lines < total) | ||
30 | { | 38 | { |
31 | message_t msg; | 39 | low = middle - (lines / 2); |
32 | header_t hdr; | 40 | if (low < 1) |
33 | stream_t is; | 41 | low = 1; |
34 | char buffer[BUFSIZ]; | 42 | high = low + lines; |
35 | off_t off = 0; | 43 | if (high > total) |
36 | size_t n = 0; | ||
37 | |||
38 | if (mailbox_get_message (mbox, cursor, &msg) != 0) | ||
39 | { | ||
40 | printf ("Could not read message %d\n", cursor); | ||
41 | return 1; | ||
42 | } | ||
43 | |||
44 | message_get_header (msg, &hdr); | ||
45 | header_get_stream (hdr, &is); | ||
46 | |||
47 | while (stream_read (is, buffer, sizeof (buffer) - 1, off, &n) == 0 | ||
48 | && n != 0) | ||
49 | { | 44 | { |
50 | buffer[n] = '\0'; | 45 | high = total; |
51 | printf ("%s", buffer); | 46 | low = high - lines; |
52 | off += n; | ||
53 | } | 47 | } |
54 | return 0; | ||
55 | } | 48 | } |
56 | return 1; | 49 | |
50 | memset (buf, '\0', 64); | ||
51 | snprintf (buf, 64, "from %d-%d", low, high); | ||
52 | return util_do_command (buf); | ||
57 | } | 53 | } | ... | ... |
... | @@ -25,13 +25,10 @@ | ... | @@ -25,13 +25,10 @@ |
25 | int | 25 | int |
26 | mail_list (int argc, char **argv) | 26 | mail_list (int argc, char **argv) |
27 | { | 27 | { |
28 | int i = 0, pos = 0, columns = 80, len = 0; | 28 | char *cmd = NULL; |
29 | char *cmd; | 29 | int i = 0, pos = 0, len = 0; |
30 | char *col = getenv ("COLUMNS"); | 30 | int cols = util_getcols () - 5; |
31 | 31 | ||
32 | if (col) | ||
33 | columns = strtol (col, NULL, 10); | ||
34 | |||
35 | for (i=0; mail_command_table[i].shortname != 0; i++) | 32 | for (i=0; mail_command_table[i].shortname != 0; i++) |
36 | { | 33 | { |
37 | len = strlen (mail_command_table[i].longname); | 34 | len = strlen (mail_command_table[i].longname); |
... | @@ -45,7 +42,7 @@ mail_list (int argc, char **argv) | ... | @@ -45,7 +42,7 @@ mail_list (int argc, char **argv) |
45 | 42 | ||
46 | pos += len + 1; | 43 | pos += len + 1; |
47 | 44 | ||
48 | if (pos >= columns) | 45 | if (pos >= cols) |
49 | { | 46 | { |
50 | pos = 0; | 47 | pos = 0; |
51 | printf ("\n"); | 48 | printf ("\n"); | ... | ... |
... | @@ -119,7 +119,6 @@ int | ... | @@ -119,7 +119,6 @@ int |
119 | main (int argc, char **argv) | 119 | main (int argc, char **argv) |
120 | { | 120 | { |
121 | char *command = NULL, *cmd = NULL; | 121 | char *command = NULL, *cmd = NULL; |
122 | char *from[] = { "from", "*" }; | ||
123 | struct arguments args; | 122 | struct arguments args; |
124 | 123 | ||
125 | cursor = 1; | 124 | cursor = 1; |
... | @@ -162,11 +161,7 @@ main (int argc, char **argv) | ... | @@ -162,11 +161,7 @@ main (int argc, char **argv) |
162 | exit (0); | 161 | exit (0); |
163 | } | 162 | } |
164 | 163 | ||
165 | /* mail_from (2, from); */ | 164 | util_do_command ("from *"); |
166 | /* FIXME: this is bad form */ | ||
167 | for (cursor = 1; cursor <= total; cursor++) | ||
168 | mail_from (1, from); | ||
169 | cursor = realcursor; | ||
170 | 165 | ||
171 | /* Initialize readline */ | 166 | /* Initialize readline */ |
172 | rl_readline_name = "mail"; | 167 | rl_readline_name = "mail"; | ... | ... |
... | @@ -40,6 +40,8 @@ | ... | @@ -40,6 +40,8 @@ |
40 | #include <mailutils/header.h> | 40 | #include <mailutils/header.h> |
41 | #include <mailutils/body.h> | 41 | #include <mailutils/body.h> |
42 | 42 | ||
43 | #include <argcv.h> | ||
44 | |||
43 | #ifdef __cplusplus | 45 | #ifdef __cplusplus |
44 | extern "C" { | 46 | extern "C" { |
45 | #endif | 47 | #endif |
... | @@ -53,14 +55,14 @@ extern "C" { | ... | @@ -53,14 +55,14 @@ extern "C" { |
53 | #endif /*__P */ | 55 | #endif /*__P */ |
54 | 56 | ||
55 | /* Type definitions */ | 57 | /* Type definitions */ |
56 | #ifndef Function | 58 | #ifndef function_t |
57 | typedef int Function (); | 59 | typedef int function_t (); |
58 | #endif | 60 | #endif |
59 | 61 | ||
60 | struct mail_command_entry { | 62 | struct mail_command_entry { |
61 | char *shortname; | 63 | char *shortname; |
62 | char *longname; | 64 | char *longname; |
63 | Function *func; | 65 | function_t *func; |
64 | char *synopsis; | 66 | char *synopsis; |
65 | }; | 67 | }; |
66 | 68 | ||
... | @@ -121,12 +123,14 @@ int mail_eq __P((int argc, char **argv)); /* command = */ | ... | @@ -121,12 +123,14 @@ int mail_eq __P((int argc, char **argv)); /* command = */ |
121 | 123 | ||
122 | int util_expand_msglist __P((const int argc, char **argv, int **list)); | 124 | int util_expand_msglist __P((const int argc, char **argv, int **list)); |
123 | int util_do_command __P((const char *cmd)); | 125 | int util_do_command __P((const char *cmd)); |
124 | int util_msglist_command __P((int (*func)(int, char**), int argc, char **argv)); | 126 | int util_msglist_command __P((function_t *func, int argc, char **argv)); |
125 | Function* util_command_get __P((char *cmd)); | 127 | function_t* util_command_get __P((char *cmd)); |
126 | char **util_command_completion __P((char *cmd, int start, int end)); | 128 | char **util_command_completion __P((char *cmd, int start, int end)); |
127 | char *util_command_generator __P((char *text, int state)); | 129 | char *util_command_generator __P((char *text, int state)); |
128 | char *util_stripwhite __P((char *string)); | 130 | char *util_stripwhite __P((char *string)); |
129 | struct mail_command_entry util_find_entry __P((char *cmd)); | 131 | struct mail_command_entry util_find_entry __P((char *cmd)); |
132 | int util_getcols __P((void)); | ||
133 | int util_getlines __P((void)); | ||
130 | 134 | ||
131 | #ifdef __cplusplus | 135 | #ifdef __cplusplus |
132 | } | 136 | } | ... | ... |
... | @@ -26,13 +26,12 @@ mail_shell (int argc, char **argv) | ... | @@ -26,13 +26,12 @@ mail_shell (int argc, char **argv) |
26 | { | 26 | { |
27 | if (argc > 1) | 27 | if (argc > 1) |
28 | return 1; | 28 | return 1; |
29 | else if (fork ()) | 29 | else if (!fork ()) |
30 | { | 30 | { |
31 | char *path = getenv ("SHELL"); | 31 | char *path = getenv ("SHELL"); |
32 | if (path == NULL) | 32 | if (path == NULL) |
33 | path = strdup ("sh"); | 33 | path = strdup ("/bin/sh"); |
34 | execl (path, path); | 34 | execv (path, &path); |
35 | free (path); | ||
36 | return 1; | 35 | return 1; |
37 | } | 36 | } |
38 | else | 37 | else | ... | ... |
... | @@ -17,6 +17,32 @@ | ... | @@ -17,6 +17,32 @@ |
17 | 17 | ||
18 | #include "mail.h" | 18 | #include "mail.h" |
19 | 19 | ||
20 | typedef struct _node { | ||
21 | int data; | ||
22 | struct _node *next; | ||
23 | } node; | ||
24 | |||
25 | static node * | ||
26 | util_ll_add (node *c, int data) | ||
27 | { | ||
28 | c->next = malloc (sizeof (node)); | ||
29 | c->data = data; | ||
30 | c->next->next = NULL; | ||
31 | return c->next; | ||
32 | } | ||
33 | |||
34 | static void | ||
35 | util_ll_free (node *c) | ||
36 | { | ||
37 | node *t = c; | ||
38 | while (t != NULL) | ||
39 | { | ||
40 | c = t; | ||
41 | t = t->next; | ||
42 | free (c); | ||
43 | } | ||
44 | } | ||
45 | |||
20 | /* | 46 | /* |
21 | * expands a standard message list into an array of numbers | 47 | * expands a standard message list into an array of numbers |
22 | * argc is the number of elements being passed in | 48 | * argc is the number of elements being passed in |
... | @@ -30,98 +56,93 @@ util_expand_msglist (const int argc, char **argv, int **list) | ... | @@ -30,98 +56,93 @@ util_expand_msglist (const int argc, char **argv, int **list) |
30 | { | 56 | { |
31 | int i = 0, lc = 0; | 57 | int i = 0, lc = 0; |
32 | int undelete = 0; | 58 | int undelete = 0; |
33 | int hyphen = 0; | 59 | int *ret = NULL; |
60 | /* let's try a linked list */ | ||
61 | node *first = malloc (sizeof (node)); | ||
62 | node *current = first; | ||
63 | first->next = NULL; | ||
34 | 64 | ||
35 | if (util_command_get (argv[0]) == util_command_get ("undelete")) | 65 | if (util_command_get (argv[0]) == util_command_get ("undelete")) |
36 | undelete = 1; | 66 | undelete = 1; |
37 | 67 | ||
38 | *list = malloc (argc * sizeof (int)); | ||
39 | for (i = 1; i < argc; i++) | 68 | for (i = 1; i < argc; i++) |
40 | { | 69 | { |
41 | if (!strcmp (argv[i], "+")) | 70 | if (!strcmp (argv[i], "+")) |
42 | { | 71 | { |
43 | *list[lc++] = i; /* FIXME: next [un]deleted message */ | 72 | /* FIXME: next [un]deleted message */ |
73 | current = util_ll_add (current, realcursor + 1); | ||
44 | } | 74 | } |
45 | else if (!strcmp (argv[i], "-")) | 75 | else if (!strcmp (argv[i], "-")) |
46 | { | 76 | { |
47 | hyphen = 1; /* FIXME: previous [un]deleted message */ | 77 | /* FIXME: prev [un]deleted message */ |
78 | current = util_ll_add (current, realcursor - 1); | ||
48 | } | 79 | } |
49 | else if (!strcmp (argv[i], ".")) | 80 | else if (!strcmp (argv[i], ".")) |
50 | { | 81 | { |
51 | *list[lc++] = realcursor; | 82 | /* the current cursor location */ |
83 | current = util_ll_add (current, realcursor); | ||
52 | } | 84 | } |
53 | else if (!strcmp (argv[i], "^")) | 85 | else if (!strcmp (argv[i], "^")) |
54 | { | 86 | { |
55 | *list[lc++] = i; /* FIXME: first [un]deleted message */ | 87 | /* FIXME: first [un]deleted message */ |
88 | current =util_ll_add (current, 1); | ||
56 | } | 89 | } |
57 | else if (!strcmp (argv[i], "$")) | 90 | else if (!strcmp (argv[i], "$")) |
58 | { | 91 | { |
59 | *list[lc++] = i; /* FIXME: the last message */ | 92 | /* FIXME: should this be last [un]deleted? */ |
93 | current = util_ll_add (current, total); | ||
60 | } | 94 | } |
61 | else if (!strcmp (argv[i], "*")) | 95 | else if (!strcmp (argv[i], "*")) |
62 | { | 96 | { |
63 | free (*list); | 97 | util_ll_free (first); |
64 | *list = malloc (total * sizeof(int)); | 98 | current = first = malloc (sizeof (node)); |
65 | for (i = 0; i < total; i++) | 99 | for (i = 1; i <= total; i++) |
66 | *list[i] = i + 1; | 100 | current = util_ll_add (current, i); |
67 | return total; | 101 | i = argc + 1; |
68 | } | 102 | } |
69 | else if (argv[i][0] == '/') | 103 | else if (argv[i][0] == '/') |
70 | { | 104 | { |
71 | *list[lc++] = i; /* FIXME: all messages with pattern following / in | 105 | /* FIXME: all messages with pattern following / in |
72 | the subject line, case insensitive */ | 106 | the subject line, case insensitive */ |
73 | } | 107 | } |
74 | else if (argv[i][0] == ':') | 108 | else if (argv[i][0] == ':') |
75 | { | 109 | { |
76 | *list[lc++] = i; /* FIXME: all messages of type argv[i][1] */ | 110 | /* FIXME: all messages of type argv[i][1] */ |
77 | } | 111 | } |
78 | else if (isalpha(argv[i][0])) | 112 | else if (isalpha(argv[i][0])) |
79 | { | 113 | { |
80 | *list[lc++] = i; /* FIXME: all messages from argv[i] */ | 114 | /* FIXME: all messages from argv[i] */ |
115 | } | ||
116 | else if (strchr (argv[i], '-') != NULL) | ||
117 | { | ||
118 | int j, x, y; | ||
119 | char *arg = strdup (argv[i]); | ||
120 | for (j=0; j < strlen (arg); j++) | ||
121 | if (arg[j] == '-') | ||
122 | break; | ||
123 | arg[j] = '\0'; | ||
124 | x = strtol (arg, NULL, 10); | ||
125 | y = strtol (&(arg[j + 1]), NULL, 10); | ||
126 | for (; x <= y; x++) | ||
127 | current = util_ll_add (current, x); | ||
128 | free (arg); | ||
81 | } | 129 | } |
82 | else | 130 | else |
83 | { | 131 | { |
84 | int j; | 132 | current = util_ll_add (current, strtol (argv[i], NULL, 10)); |
85 | int len = strlen (argv[i]); | ||
86 | |||
87 | for (j = 0; j < len; j++) | ||
88 | if (argv[i][j] == '-') | ||
89 | { | ||
90 | hyphen = 1; | ||
91 | break; | ||
92 | } | ||
93 | if (hyphen) | ||
94 | { | ||
95 | if (j != len) /* One argument "x-y". */ | ||
96 | { | ||
97 | int x, y; | ||
98 | char *arg = strdup (argv[i]); | ||
99 | arg[j] = '\0'; | ||
100 | x = atoi (arg); | ||
101 | y = atoi (&(arg[j + 1])); | ||
102 | /* In this case, we also have to realloc() the list. */ | ||
103 | *list = realloc (*list, (argc + 2) * sizeof (int)); | ||
104 | for (; x <= y; x++, lc++) | ||
105 | *list[lc] = x; | ||
106 | free (arg); | ||
107 | } | ||
108 | else if (i == 3) /* 3 arguments "x" "-" "y". */ | ||
109 | { | ||
110 | int x, y; | ||
111 | x = *list[lc - 1]; | ||
112 | y = atoi (argv[i]); | ||
113 | for (; x <= y; x++, lc++) | ||
114 | *list[lc] = x; | ||
115 | } | ||
116 | else /* Badly form. */ | ||
117 | *list[lc++] = atoi (argv[i]); | ||
118 | hyphen = 0; | ||
119 | } | ||
120 | else | ||
121 | *list[lc++] = atoi(argv[i]); | ||
122 | } | 133 | } |
123 | } | 134 | } |
124 | return lc; | 135 | |
136 | for (current = first; current != NULL; current = current->next) | ||
137 | lc++; | ||
138 | |||
139 | ret = malloc (lc * sizeof (int)); | ||
140 | lc = 0; | ||
141 | for (current = first; current != NULL; current = current->next) | ||
142 | ret [lc++] = current->data; | ||
143 | util_ll_free (first); | ||
144 | *list = ret; | ||
145 | return lc-1; | ||
125 | } | 146 | } |
126 | 147 | ||
127 | /* | 148 | /* |
... | @@ -135,7 +156,7 @@ util_do_command (const char *cmd) | ... | @@ -135,7 +156,7 @@ util_do_command (const char *cmd) |
135 | int argc = 0; | 156 | int argc = 0; |
136 | char **argv = NULL; | 157 | char **argv = NULL; |
137 | int status = 0; | 158 | int status = 0; |
138 | Function *command; | 159 | function_t *command; |
139 | 160 | ||
140 | if (cmd[0] == '#') | 161 | if (cmd[0] == '#') |
141 | return 0; | 162 | return 0; |
... | @@ -169,7 +190,7 @@ util_do_command (const char *cmd) | ... | @@ -169,7 +190,7 @@ util_do_command (const char *cmd) |
169 | */ | 190 | */ |
170 | 191 | ||
171 | int | 192 | int |
172 | util_msglist_command (int (*func)(int, char**), int argc, char **argv) | 193 | util_msglist_command (function_t *func, int argc, char **argv) |
173 | { | 194 | { |
174 | int i; | 195 | int i; |
175 | int *list = NULL; | 196 | int *list = NULL; |
... | @@ -192,7 +213,7 @@ util_msglist_command (int (*func)(int, char**), int argc, char **argv) | ... | @@ -192,7 +213,7 @@ util_msglist_command (int (*func)(int, char**), int argc, char **argv) |
192 | /* | 213 | /* |
193 | * returns the function to run for command | 214 | * returns the function to run for command |
194 | */ | 215 | */ |
195 | Function * | 216 | function_t * |
196 | util_command_get (char *cmd) | 217 | util_command_get (char *cmd) |
197 | { | 218 | { |
198 | struct mail_command_entry entry = util_find_entry (cmd); | 219 | struct mail_command_entry entry = util_find_entry (cmd); |
... | @@ -279,4 +300,28 @@ util_stripwhite (char *string) | ... | @@ -279,4 +300,28 @@ util_stripwhite (char *string) |
279 | return s; | 300 | return s; |
280 | } | 301 | } |
281 | 302 | ||
303 | /* | ||
304 | * get the number of columns on the screen | ||
305 | */ | ||
306 | int | ||
307 | util_getcols (void) | ||
308 | { | ||
309 | int columns = 80; | ||
310 | char *col = getenv ("COLUMNS"); | ||
311 | if (col) | ||
312 | columns = strtol (col, NULL, 10); | ||
313 | return columns; | ||
314 | } | ||
282 | 315 | ||
316 | /* | ||
317 | * get the number of lines on the screen | ||
318 | */ | ||
319 | int | ||
320 | util_getlines (void) | ||
321 | { | ||
322 | int lines = 24; | ||
323 | char *lin = getenv ("LINES"); | ||
324 | if (lin) | ||
325 | lines = strtol (lin, NULL, 10); | ||
326 | return lines; | ||
327 | } | ... | ... |
-
Please register or sign in to post a comment