Commit 1152383e 1152383ee7848d07d6ce262ff05738fe9fa78be6 by Jakob Kaivo

Begin real implementation of mailx mail command

make sure none of the necessary environment variables will be unset in mailx
1 parent 2633d263
...@@ -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;
......