Begin real implementation of mailx mail command
make sure none of the necessary environment variables will be unset in mailx
Showing
12 changed files
with
183 additions
and
53 deletions
... | @@ -29,11 +29,8 @@ mail_edit (int argc, char **argv) | ... | @@ -29,11 +29,8 @@ mail_edit (int argc, char **argv) |
29 | else | 29 | else |
30 | { | 30 | { |
31 | char *file = tempnam(getenv("TMPDIR"), "mu"); | 31 | char *file = tempnam(getenv("TMPDIR"), "mu"); |
32 | char *editor = getenv ("EDITOR"); | ||
33 | if (!editor) | ||
34 | editor = strdup ("ed"); | ||
35 | util_do_command ("copy %s", file); | 32 | util_do_command ("copy %s", file); |
36 | util_do_command ("shell %s %s", editor, file); | 33 | util_do_command ("shell %s %s", getenv("EDITOR"), file); |
37 | remove (file); | 34 | remove (file); |
38 | free (file); | 35 | free (file); |
39 | return 0; | 36 | return 0; | ... | ... |
... | @@ -64,11 +64,6 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -64,11 +64,6 @@ parse_opt (int key, char *arg, struct argp_state *state) |
64 | { | 64 | { |
65 | int len; | 65 | int len; |
66 | char *home = getenv("HOME"); | 66 | char *home = getenv("HOME"); |
67 | if (home == NULL) | ||
68 | { | ||
69 | fprintf (stderr, "No Home!\n"); | ||
70 | home = (char *)""; | ||
71 | } | ||
72 | len = strlen (home) + strlen ("/mbox") + 1; | 67 | len = strlen (home) + strlen ("/mbox") + 1; |
73 | args->file = malloc(len * sizeof (char)); | 68 | args->file = malloc(len * sizeof (char)); |
74 | strcpy (args->file, home); | 69 | strcpy (args->file, home); |
... | @@ -129,6 +124,20 @@ main (int argc, char **argv) | ... | @@ -129,6 +124,20 @@ main (int argc, char **argv) |
129 | 124 | ||
130 | signal (SIGPIPE, SIG_IGN); | 125 | signal (SIGPIPE, SIG_IGN); |
131 | 126 | ||
127 | /* set up the default environment */ | ||
128 | if (!getenv ("HOME")) | ||
129 | exit (1); /* FIXME: how to start with no $HOME ? */ | ||
130 | setenv ("DEAD", "~/dead.letter", 0); /* FIXME: expand ~ */ | ||
131 | setenv ("EDITOR", "ed", 0); | ||
132 | setenv ("LISTER", "ls", 0); | ||
133 | setenv ("MAILRC", "~/.mailrc", 0); /* FIXME: expand ~ */ | ||
134 | setenv ("MBOX", "~/mbox", 0); /* FIXME: expand ~ */ | ||
135 | setenv ("PAGER", "more", 0); | ||
136 | setenv ("SHELL", "sh", 0); | ||
137 | setenv ("VISUAL", "vi", 0); | ||
138 | setenv ("COLUMNS", "80", 0); | ||
139 | setenv ("LINES", "24", 0); | ||
140 | |||
132 | /* set defaults for execution */ | 141 | /* set defaults for execution */ |
133 | util_do_command ("set noallnet"); | 142 | util_do_command ("set noallnet"); |
134 | util_do_command ("set noappend"); | 143 | util_do_command ("set noappend"); | ... | ... |
... | @@ -43,6 +43,7 @@ | ... | @@ -43,6 +43,7 @@ |
43 | #include <mailutils/body.h> | 43 | #include <mailutils/body.h> |
44 | 44 | ||
45 | #include <argcv.h> | 45 | #include <argcv.h> |
46 | #include <getline.h> | ||
46 | 47 | ||
47 | #ifdef __cplusplus | 48 | #ifdef __cplusplus |
48 | extern "C" { | 49 | extern "C" { |
... | @@ -106,10 +107,8 @@ int mail_mbox __P((int argc, char **argv)); | ... | @@ -106,10 +107,8 @@ int mail_mbox __P((int argc, char **argv)); |
106 | int mail_next __P((int argc, char **argv)); | 107 | int mail_next __P((int argc, char **argv)); |
107 | int mail_pipe __P((int argc, char **argv)); | 108 | int mail_pipe __P((int argc, char **argv)); |
108 | int mail_previous __P((int argc, char **argv)); | 109 | int mail_previous __P((int argc, char **argv)); |
109 | int mail_printall __P((int argc, char **argv)); /* command Print */ | ||
110 | int mail_print __P((int argc, char **argv)); | 110 | int mail_print __P((int argc, char **argv)); |
111 | int mail_quit __P((int argc, char **argv)); | 111 | int mail_quit __P((int argc, char **argv)); |
112 | int mail_relist __P((int argc, char **argv)); /* command Reply */ | ||
113 | int mail_reply __P((int argc, char **argv)); | 112 | int mail_reply __P((int argc, char **argv)); |
114 | int mail_retain __P((int argc, char **argv)); | 113 | int mail_retain __P((int argc, char **argv)); |
115 | int mail_save __P((int argc, char **argv)); | 114 | int mail_save __P((int argc, char **argv)); |
... | @@ -126,7 +125,6 @@ int mail_visual __P((int argc, char **argv)); | ... | @@ -126,7 +125,6 @@ int mail_visual __P((int argc, char **argv)); |
126 | int mail_write __P((int argc, char **argv)); | 125 | int mail_write __P((int argc, char **argv)); |
127 | int mail_z __P((int argc, char **argv)); | 126 | int mail_z __P((int argc, char **argv)); |
128 | 127 | ||
129 | int mail_bang __P((int argc, char **argv)); /* command ! */ | ||
130 | int mail_eq __P((int argc, char **argv)); /* command = */ | 128 | int mail_eq __P((int argc, char **argv)); /* command = */ |
131 | 129 | ||
132 | int util_expand_msglist __P((const int argc, char **argv, int **list)); | 130 | int util_expand_msglist __P((const int argc, char **argv, int **list)); | ... | ... |
... | @@ -31,10 +31,13 @@ mail_next (int argc, char **argv) | ... | @@ -31,10 +31,13 @@ mail_next (int argc, char **argv) |
31 | realcursor++; | 31 | realcursor++; |
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | else if (argc == 2) | 34 | else |
35 | { | 35 | { |
36 | cursor = strtol (argv[1], NULL, 10); | 36 | int *list = NULL; |
37 | util_expand_msglist (argc, argv, &list); | ||
38 | cursor = list[0]; | ||
37 | realcursor = cursor; | 39 | realcursor = cursor; |
40 | free (list); | ||
38 | return 0; | 41 | return 0; |
39 | } | 42 | } |
40 | return 1; | 43 | return 1; | ... | ... |
... | @@ -60,7 +60,7 @@ mail_pipe (int argc, char **argv) | ... | @@ -60,7 +60,7 @@ mail_pipe (int argc, char **argv) |
60 | off =+ n; | 60 | off =+ n; |
61 | } | 61 | } |
62 | if ((util_find_env("page"))->set) | 62 | if ((util_find_env("page"))->set) |
63 | fprintf (pipe, "\f"); | 63 | fprintf (pipe, "\f"); /* FIXME: is this formfeed ? */ |
64 | } | 64 | } |
65 | } | 65 | } |
66 | } | 66 | } | ... | ... |
... | @@ -31,10 +31,13 @@ mail_previous (int argc, char **argv) | ... | @@ -31,10 +31,13 @@ mail_previous (int argc, char **argv) |
31 | realcursor--; | 31 | realcursor--; |
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | else if ( argc == 2) | 34 | else |
35 | { | 35 | { |
36 | cursor = strtol (argv[1], NULL, 10); | 36 | int *list = NULL; |
37 | util_expand_msglist (argc, argv, &list); | ||
38 | cursor = list[0]; | ||
37 | realcursor = cursor; | 39 | realcursor = cursor; |
40 | free (list); | ||
38 | return 0; | 41 | return 0; |
39 | } | 42 | } |
40 | return 1; | 43 | return 1; | ... | ... |
... | @@ -50,13 +50,7 @@ mail_print (int argc, char **argv) | ... | @@ -50,13 +50,7 @@ mail_print (int argc, char **argv) |
50 | message_lines (mesg, &lines); | 50 | message_lines (mesg, &lines); |
51 | 51 | ||
52 | if ((util_find_env("crt"))->set && lines > util_getlines ()) | 52 | if ((util_find_env("crt"))->set && lines > util_getlines ()) |
53 | { | 53 | out = popen (getenv("PAGER"), "w"); |
54 | char *pager = getenv ("PAGER"); | ||
55 | if (pager) | ||
56 | out = popen (pager, "w"); | ||
57 | else | ||
58 | out = popen ("more", "w"); | ||
59 | } | ||
60 | 54 | ||
61 | if (islower (argv[0][0])) | 55 | if (islower (argv[0][0])) |
62 | { | 56 | { |
... | @@ -64,13 +58,13 @@ mail_print (int argc, char **argv) | ... | @@ -64,13 +58,13 @@ mail_print (int argc, char **argv) |
64 | if (header_get_value (hdr, MU_HEADER_FROM, buffer, sizeof (buffer), | 58 | if (header_get_value (hdr, MU_HEADER_FROM, buffer, sizeof (buffer), |
65 | NULL) == 0) | 59 | NULL) == 0) |
66 | { | 60 | { |
67 | printf ("From: %s\n", buffer); | 61 | fprintf (out, "From: %s\n", buffer); |
68 | /* free (buf); */ | 62 | /* free (buf); */ |
69 | } | 63 | } |
70 | if (header_get_value (hdr, MU_HEADER_SUBJECT, buffer, | 64 | if (header_get_value (hdr, MU_HEADER_SUBJECT, buffer, |
71 | sizeof (buffer), NULL) == 0) | 65 | sizeof (buffer), NULL) == 0) |
72 | { | 66 | { |
73 | printf ("Subject: %s\n", buffer); | 67 | fprintf (out, "Subject: %s\n", buffer); |
74 | /* free (buf); */ | 68 | /* free (buf); */ |
75 | } | 69 | } |
76 | 70 | ... | ... |
... | @@ -25,6 +25,10 @@ int | ... | @@ -25,6 +25,10 @@ int |
25 | mail_send (int argc, char **argv) | 25 | mail_send (int argc, char **argv) |
26 | { | 26 | { |
27 | char *to = NULL, *cc = NULL, *bcc = NULL, *subj = NULL; | 27 | char *to = NULL, *cc = NULL, *bcc = NULL, *subj = NULL; |
28 | char *filename = tempnam (getenv ("TMPDIR"), "mu"); | ||
29 | FILE *file = fopen (filename, "w"); | ||
30 | char *buf = NULL; | ||
31 | size_t n; | ||
28 | 32 | ||
29 | if (argc < 2) | 33 | if (argc < 2) |
30 | to = readline ("To: "); | 34 | to = readline ("To: "); |
... | @@ -42,7 +46,143 @@ mail_send (int argc, char **argv) | ... | @@ -42,7 +46,143 @@ mail_send (int argc, char **argv) |
42 | subj = readline ("Subject: "); | 46 | subj = readline ("Subject: "); |
43 | else | 47 | else |
44 | subj = (util_find_env ("subject"))->value; | 48 | subj = (util_find_env ("subject"))->value; |
45 | 49 | ||
46 | printf ("Function not implemented in %s line %d\n", __FILE__, __LINE__); | 50 | while (getline (&buf, &n, stdin) != -1) |
51 | { | ||
52 | if (buf[0] == (util_find_env("escape"))->value[0]) | ||
53 | { | ||
54 | FILE *ostdout = stdout; | ||
55 | stdout = file; | ||
56 | buf[strlen(buf)-1] = '\0'; | ||
57 | switch (buf[1]) | ||
58 | { | ||
59 | case '!': | ||
60 | util_do_command ("!%s", &buf[3]); | ||
61 | break; | ||
62 | case '.': | ||
63 | /* eof */ | ||
64 | break; | ||
65 | case ':': | ||
66 | case '-': | ||
67 | util_do_command ("%s", &buf[3]); | ||
68 | break; | ||
69 | case '?': | ||
70 | /* escape help */ | ||
71 | break; | ||
72 | case 'A': | ||
73 | printf ("%s", (util_find_env("Sign"))->value); | ||
74 | break; | ||
75 | case 'a': | ||
76 | printf ("%s", (util_find_env("sign"))->value); | ||
77 | break; | ||
78 | case 'b': | ||
79 | bcc = realloc (bcc, (strlen(bcc) + strlen(buf) - 1) * | ||
80 | sizeof(char)); | ||
81 | strcat (bcc, ", "); | ||
82 | strcat (bcc, &buf[3]); | ||
83 | break; | ||
84 | case 'c': | ||
85 | cc = realloc (cc, (strlen(cc) + strlen(buf) - 1) * | ||
86 | sizeof (char)); | ||
87 | strcat (cc, ", "); | ||
88 | strcat (cc, &buf[3]); | ||
89 | break; | ||
90 | case 'd': | ||
91 | { | ||
92 | FILE *dead = fopen (getenv("DEAD"), "r"); | ||
93 | char c; | ||
94 | while ((c = fgetc(dead))) | ||
95 | fputc (c, file); | ||
96 | fclose (dead); | ||
97 | } | ||
98 | break; | ||
99 | case 'e': | ||
100 | fclose (file); | ||
101 | stdout = ostdout; | ||
102 | util_do_command ("!%s %s", getenv("EDITOR"), filename); | ||
103 | file = fopen (filename, "a"); | ||
104 | stdout = file; | ||
105 | break; | ||
106 | case 'f': | ||
107 | util_do_command ("print %s", &buf[3]); | ||
108 | break; | ||
109 | case 'F': | ||
110 | util_do_command ("Print %s", &buf[3]); | ||
111 | break; | ||
112 | case 'h': | ||
113 | /* reget Bcc, Cc, To, and Subject */ | ||
114 | break; | ||
115 | case 'i': | ||
116 | fprintf (file, "%s", (util_find_env(&buf[3]))->value); | ||
117 | break; | ||
118 | case 'm': | ||
119 | /* quote messages */ | ||
120 | break; | ||
121 | case 'M': | ||
122 | /* same as m with no headers ignored */ | ||
123 | break; | ||
124 | case 'p': | ||
125 | fclose (file); | ||
126 | stdout = ostdout; | ||
127 | if (/* numlines (filename) > */ util_getlines()) | ||
128 | util_do_command ("!%s %s", getenv("PAGER"), filename); | ||
129 | else | ||
130 | /* dump filename */; | ||
131 | file = fopen (filename, "a"); | ||
132 | stdout = file; | ||
133 | break; | ||
134 | case 'q': | ||
135 | fclose (file); | ||
136 | rename (filename, getenv("DEAD")); | ||
137 | util_do_command ("quit"); | ||
138 | break; | ||
139 | case 'r': | ||
140 | case '<': | ||
141 | /* read in a file */ | ||
142 | break; | ||
143 | case 's': | ||
144 | free (subj); | ||
145 | subj = strdup (&buf[3]); | ||
146 | break; | ||
147 | case 't': | ||
148 | to = realloc (to, (strlen(to) + strlen(buf) - 1) * | ||
149 | sizeof (char)); | ||
150 | strcat (to, ", "); | ||
151 | strcat (to, &buf[3]); | ||
152 | break; | ||
153 | case 'v': | ||
154 | fclose (file); | ||
155 | stdout = ostdout; | ||
156 | util_do_command ("!%s %s", getenv("VISUAL"), filename); | ||
157 | file = fopen (filename, "a"); | ||
158 | stdout = file; | ||
159 | break; | ||
160 | case 'w': | ||
161 | { | ||
162 | FILE *f2 = fopen (&buf[3], "a"); | ||
163 | /* read this file and output to f2 */ | ||
164 | fclose (f2); | ||
165 | } | ||
166 | break; | ||
167 | case 'x': | ||
168 | util_do_command ("quit"); | ||
169 | break; | ||
170 | case '|': | ||
171 | /* pipe to &buf[3] */ | ||
172 | break; | ||
173 | default: | ||
174 | fprintf (stderr, "Unknown escape %c\n", buf[0]); | ||
175 | break; | ||
176 | } | ||
177 | stdout = ostdout; | ||
178 | } | ||
179 | else | ||
180 | fprintf (file, "%s", buf); | ||
181 | fflush (file); | ||
182 | /* free (buf); */ | ||
183 | } | ||
184 | |||
185 | /* read in filename, send it */ | ||
186 | |||
47 | return 1; | 187 | return 1; |
48 | } | 188 | } | ... | ... |
... | @@ -44,26 +44,22 @@ mail_shell (int argc, char **argv) | ... | @@ -44,26 +44,22 @@ mail_shell (int argc, char **argv) |
44 | int pid = fork (); | 44 | int pid = fork (); |
45 | if (pid == 0) | 45 | if (pid == 0) |
46 | { | 46 | { |
47 | const char *shell = getenv ("SHELL"); | ||
48 | const char **argvec; | 47 | const char **argvec; |
49 | char *buf = NULL; | 48 | char *buf = NULL; |
50 | 49 | ||
51 | if (shell == NULL) | ||
52 | shell = "/bin/sh"; | ||
53 | |||
54 | /* 1(shell) + 1 (-c) + 1(arg) + 1 (null) = 4 */ | 50 | /* 1(shell) + 1 (-c) + 1(arg) + 1 (null) = 4 */ |
55 | argvec = malloc (4 * (sizeof (char *))); | 51 | argvec = malloc (4 * (sizeof (char *))); |
56 | 52 | ||
57 | argcv_string (argc-1, &argv[1], &buf); | 53 | argcv_string (argc-1, &argv[1], &buf); |
58 | 54 | ||
59 | argvec[0] = shell; | 55 | argvec[0] = getenv("SHELL"); |
60 | argvec[1] = "-c"; | 56 | argvec[1] = "-c"; |
61 | argvec[2] = buf; | 57 | argvec[2] = buf; |
62 | argvec[3] = NULL; | 58 | argvec[3] = NULL; |
63 | 59 | ||
64 | /* why does this complain if argvec[2] is in the path but not | 60 | /* why does this complain if argvec[2] is in the path but not |
65 | fully qualified ? */ | 61 | fully qualified ? */ |
66 | execvp (shell, argvec); | 62 | execvp (argvec[0], argvec); |
67 | free (buf); /* Being cute, nuke it when finish testing. */ | 63 | free (buf); /* Being cute, nuke it when finish testing. */ |
68 | free (argvec); | 64 | free (argvec); |
69 | return 1; | 65 | return 1; |
... | @@ -78,10 +74,7 @@ mail_shell (int argc, char **argv) | ... | @@ -78,10 +74,7 @@ mail_shell (int argc, char **argv) |
78 | } | 74 | } |
79 | else | 75 | else |
80 | { | 76 | { |
81 | char *shell = getenv ("SHELL"); | 77 | return util_do_command ("shell %s", getenv("SHELL")); |
82 | if (!shell) | ||
83 | shell = strdup ("/bin/sh"); | ||
84 | return util_do_command ("shell %s", shell); | ||
85 | } | 78 | } |
86 | return 1; | 79 | return 1; |
87 | } | 80 | } | ... | ... |
... | @@ -90,5 +90,9 @@ const struct mail_command_entry mail_command_table[] = { | ... | @@ -90,5 +90,9 @@ const struct mail_command_entry mail_command_table[] = { |
90 | { "+", "+", mail_next, "+ [message]" }, | 90 | { "+", "+", mail_next, "+ [message]" }, |
91 | { "|", "|", mail_pipe, "| [[msglist] command]" }, | 91 | { "|", "|", mail_pipe, "| [[msglist] command]" }, |
92 | { "-", "-", mail_previous, "- [message]" }, | 92 | { "-", "-", mail_previous, "- [message]" }, |
93 | { 0, 0, 0, 0,} | 93 | { 0, 0, 0, 0} |
94 | }; | ||
95 | |||
96 | const struct mail_command_entry mail_escape_table[] = { | ||
97 | {0, 0, 0, 0} | ||
94 | }; | 98 | }; | ... | ... |
... | @@ -382,11 +382,7 @@ util_stripwhite (char *string) | ... | @@ -382,11 +382,7 @@ util_stripwhite (char *string) |
382 | int | 382 | int |
383 | util_getcols (void) | 383 | util_getcols (void) |
384 | { | 384 | { |
385 | int columns = 80; | 385 | return strtol (getenv("COLUMNS"), NULL, 10); |
386 | char *col = getenv ("COLUMNS"); | ||
387 | if (col) | ||
388 | columns = strtol (col, NULL, 10); | ||
389 | return columns; | ||
390 | } | 386 | } |
391 | 387 | ||
392 | /* | 388 | /* |
... | @@ -395,11 +391,7 @@ util_getcols (void) | ... | @@ -395,11 +391,7 @@ util_getcols (void) |
395 | int | 391 | int |
396 | util_getlines (void) | 392 | util_getlines (void) |
397 | { | 393 | { |
398 | int lines = 24; | 394 | return strtol (getenv("LINES"), NULL, 10); |
399 | char *lin = getenv ("LINES"); | ||
400 | if (lin) | ||
401 | lines = strtol (lin, NULL, 10); | ||
402 | return lines; | ||
403 | } | 395 | } |
404 | 396 | ||
405 | /* | 397 | /* | ... | ... |
... | @@ -29,11 +29,8 @@ mail_visual (int argc, char **argv) | ... | @@ -29,11 +29,8 @@ mail_visual (int argc, char **argv) |
29 | else | 29 | else |
30 | { | 30 | { |
31 | char *file = tempnam(getenv("TMPDIR"), "mu"); | 31 | char *file = tempnam(getenv("TMPDIR"), "mu"); |
32 | char *editor = getenv ("VISUAL"); | ||
33 | if (!editor) | ||
34 | editor = strdup ("vi"); | ||
35 | util_do_command ("copy %s", file); | 32 | util_do_command ("copy %s", file); |
36 | util_do_command ("shell %s %s", editor, file); | 33 | util_do_command ("shell %s %s", getenv("VISUAL"), file); |
37 | remove (file); | 34 | remove (file); |
38 | free (file); | 35 | free (file); |
39 | return 0; | 36 | return 0; | ... | ... |
-
Please register or sign in to post a comment