mail: fix the "shell" ("!") command.
* mail/mail.h (mail_execute): Change signature. All callers updated. * mail/shell.c (expand_bang): Change signature. Take the string to be expanded as the 2nd and the last command as 3rd arguments. Always allocate the return string, even if there's nothing to expand. (mail_execute): fix memory management. * mail/escape.c: Update. * mail/escape.c: Update calls to mail_execute.
Showing
3 changed files
with
51 additions
and
33 deletions
... | @@ -173,7 +173,7 @@ escape_check_args (int argc, char **argv) | ... | @@ -173,7 +173,7 @@ escape_check_args (int argc, char **argv) |
173 | int | 173 | int |
174 | escape_shell (int argc, char **argv, compose_env_t *env) | 174 | escape_shell (int argc, char **argv, compose_env_t *env) |
175 | { | 175 | { |
176 | return mail_execute (1, argc - 1, argv + 1); | 176 | return mail_execute (1, argv[1], argc - 1, argv + 1); |
177 | } | 177 | } |
178 | 178 | ||
179 | /* ~:[mail-command] */ | 179 | /* ~:[mail-command] */ |
... | @@ -325,7 +325,7 @@ run_editor (char *ed, char *arg) | ... | @@ -325,7 +325,7 @@ run_editor (char *ed, char *arg) |
325 | argv[0] = ed; | 325 | argv[0] = ed; |
326 | argv[1] = arg; | 326 | argv[1] = arg; |
327 | argv[2] = NULL; | 327 | argv[2] = NULL; |
328 | return mail_execute (1, 2, argv); | 328 | return mail_execute (1, arg, 2, argv); |
329 | } | 329 | } |
330 | 330 | ||
331 | static int | 331 | static int | ... | ... |
... | @@ -217,7 +217,7 @@ extern int mail_save (int argc, char **argv); | ... | @@ -217,7 +217,7 @@ extern int mail_save (int argc, char **argv); |
217 | extern int mail_sendheader (int argc, char **argv); | 217 | extern int mail_sendheader (int argc, char **argv); |
218 | extern int mail_set (int argc, char **argv); | 218 | extern int mail_set (int argc, char **argv); |
219 | extern int mail_shell (int argc, char **argv); | 219 | extern int mail_shell (int argc, char **argv); |
220 | extern int mail_execute (int shell, int argc, char **argv); | 220 | extern int mail_execute (int shell, char *progname, int argc, char **argv); |
221 | extern int mail_size (int argc, char **argv); | 221 | extern int mail_size (int argc, char **argv); |
222 | extern int mail_source (int argc, char **argv); | 222 | extern int mail_source (int argc, char **argv); |
223 | extern int mail_summary (int argc, char **argv); | 223 | extern int mail_summary (int argc, char **argv); | ... | ... |
... | @@ -18,20 +18,21 @@ | ... | @@ -18,20 +18,21 @@ |
18 | #include "mail.h" | 18 | #include "mail.h" |
19 | 19 | ||
20 | static void | 20 | static void |
21 | expand_bang (char **pbuf) | 21 | expand_bang (char **pbuf, const char *arg, const char *last) |
22 | { | 22 | { |
23 | char *last = NULL; | 23 | char *tmp, *q; |
24 | char *tmp, *p, *q; | 24 | const char *p; |
25 | size_t count = 0; | 25 | size_t count = 0; |
26 | 26 | ||
27 | mailvar_get (&last, "gnu-last-command", mailvar_type_string, 0); | 27 | for (p = arg; *p; p++) |
28 | |||
29 | for (p = *pbuf; *p; p++) | ||
30 | if (*p == '!') | 28 | if (*p == '!') |
31 | count++; | 29 | count++; |
32 | 30 | ||
33 | if (count == 0) | 31 | if (count == 0) |
34 | return; | 32 | { |
33 | *pbuf = xstrdup (arg); | ||
34 | return; | ||
35 | } | ||
35 | 36 | ||
36 | if (!last) | 37 | if (!last) |
37 | { | 38 | { |
... | @@ -39,8 +40,8 @@ expand_bang (char **pbuf) | ... | @@ -39,8 +40,8 @@ expand_bang (char **pbuf) |
39 | return; | 40 | return; |
40 | } | 41 | } |
41 | 42 | ||
42 | tmp = xmalloc (strlen (*pbuf) + count * (strlen (last) - 1) + 1); | 43 | tmp = xmalloc (strlen (arg) + count * (strlen (last) - 1) + 1); |
43 | for (p = *pbuf, q = tmp; *p; ) | 44 | for (p = arg, q = tmp; *p; ) |
44 | { | 45 | { |
45 | if (*p == '!') | 46 | if (*p == '!') |
46 | { | 47 | { |
... | @@ -49,7 +50,7 @@ expand_bang (char **pbuf) | ... | @@ -49,7 +50,7 @@ expand_bang (char **pbuf) |
49 | p++; | 50 | p++; |
50 | } | 51 | } |
51 | else | 52 | else |
52 | *p++ = *q++; | 53 | *q++ = *p++; |
53 | } | 54 | } |
54 | *q = 0; | 55 | *q = 0; |
55 | 56 | ||
... | @@ -58,12 +59,13 @@ expand_bang (char **pbuf) | ... | @@ -58,12 +59,13 @@ expand_bang (char **pbuf) |
58 | } | 59 | } |
59 | 60 | ||
60 | int | 61 | int |
61 | mail_execute (int shell, int argc, char **argv) | 62 | mail_execute (int shell, char *progname, int argc, char **argv) |
62 | { | 63 | { |
63 | int xargc, i, status, rc; | 64 | int xargc, i, status, rc; |
64 | char **xargv; | 65 | char **xargv; |
65 | char *buf; | 66 | char *buf; |
66 | 67 | int expanded; /* Indicates whether argv has been bang-expanded */ | |
68 | |||
67 | if (argc == 0) | 69 | if (argc == 0) |
68 | { | 70 | { |
69 | /* No arguments mean execute a copy of the user shell */ | 71 | /* No arguments mean execute a copy of the user shell */ |
... | @@ -75,18 +77,27 @@ mail_execute (int shell, int argc, char **argv) | ... | @@ -75,18 +77,27 @@ mail_execute (int shell, int argc, char **argv) |
75 | xargc = 3; | 77 | xargc = 3; |
76 | xargv = xcalloc (xargc + 1, sizeof (xargv[0])); | 78 | xargv = xcalloc (xargc + 1, sizeof (xargv[0])); |
77 | 79 | ||
78 | for (i = 0; i < argc; i++) | ||
79 | xargv[i] = argv[i]; | ||
80 | |||
81 | /* Expand arguments if required */ | 80 | /* Expand arguments if required */ |
82 | if (mailvar_get (NULL, "bang", mailvar_type_boolean, 0) == 0) | 81 | if (mailvar_get (NULL, "bang", mailvar_type_boolean, 0) == 0) |
83 | { | 82 | { |
84 | int i; | 83 | int i; |
85 | 84 | char *last = NULL; | |
86 | for (i = 0; i < xargc; i++) | 85 | |
87 | expand_bang (xargv + i); | 86 | mailvar_get (&last, "gnu-last-command", mailvar_type_string, 0); |
87 | expand_bang (xargv, progname, last); | ||
88 | for (i = 1; i < argc; i++) | ||
89 | expand_bang (xargv + i, argv[i], last); | ||
90 | expanded = 1; | ||
88 | } | 91 | } |
89 | 92 | else | |
93 | { | ||
94 | if (argc) | ||
95 | xargv[0] = progname; | ||
96 | for (i = 1; i < argc; i++) | ||
97 | xargv[i] = argv[i]; | ||
98 | expanded = 0; | ||
99 | } | ||
100 | |||
90 | /* Reconstruct the command line and save it to gnu-last-command variable. | 101 | /* Reconstruct the command line and save it to gnu-last-command variable. |
91 | Important: use argc (not xargc)! | 102 | Important: use argc (not xargc)! |
92 | */ | 103 | */ |
... | @@ -96,14 +107,25 @@ mail_execute (int shell, int argc, char **argv) | ... | @@ -96,14 +107,25 @@ mail_execute (int shell, int argc, char **argv) |
96 | 107 | ||
97 | if (shell) | 108 | if (shell) |
98 | { | 109 | { |
110 | if (expanded) | ||
111 | { | ||
112 | for (i = 0; i < argc; i++) | ||
113 | free (xargv[i]); | ||
114 | expanded = 0; | ||
115 | } | ||
116 | |||
99 | xargv[0] = getenv ("SHELL"); | 117 | xargv[0] = getenv ("SHELL"); |
100 | if (argc == 0) | 118 | if (argc == 0) |
101 | xargv[1] = NULL; | 119 | { |
120 | xargv[1] = NULL; | ||
121 | xargc = 1; | ||
122 | } | ||
102 | else | 123 | else |
103 | { | 124 | { |
104 | xargv[1] = "-c"; | 125 | xargv[1] = "-c"; |
105 | xargv[2] = buf; | 126 | xargv[2] = buf; |
106 | xargv[3] = NULL; | 127 | xargv[3] = NULL; |
128 | xargc = 3; | ||
107 | } | 129 | } |
108 | } | 130 | } |
109 | 131 | ||
... | @@ -117,6 +139,9 @@ mail_execute (int shell, int argc, char **argv) | ... | @@ -117,6 +139,9 @@ mail_execute (int shell, int argc, char **argv) |
117 | mu_diag_output (MU_DIAG_NOTICE, .... | 139 | mu_diag_output (MU_DIAG_NOTICE, .... |
118 | */ | 140 | */ |
119 | free (buf); | 141 | free (buf); |
142 | if (expanded) | ||
143 | for (i = 0; i < argc; i++) | ||
144 | free (xargv[i]); | ||
120 | free (xargv); | 145 | free (xargv); |
121 | return rc; | 146 | return rc; |
122 | } | 147 | } |
... | @@ -130,18 +155,11 @@ int | ... | @@ -130,18 +155,11 @@ int |
130 | mail_shell (int argc, char **argv) | 155 | mail_shell (int argc, char **argv) |
131 | { | 156 | { |
132 | if (argv[0][0] == '!' && strlen (argv[0]) > 1) | 157 | if (argv[0][0] == '!' && strlen (argv[0]) > 1) |
133 | { | 158 | return mail_execute (1, argv[0] + 1, argc, argv); |
134 | argv[0][0] = ' '; | ||
135 | return mail_execute (1, argc, argv); | ||
136 | } | ||
137 | else if (argc > 1) | 159 | else if (argc > 1) |
138 | { | 160 | return mail_execute (0, argv[1], argc-1, argv+1); |
139 | return mail_execute (0, argc-1, argv+1); | ||
140 | } | ||
141 | else | 161 | else |
142 | { | 162 | return mail_execute (1, NULL, 0, NULL); |
143 | return mail_execute (1, 0, NULL); | ||
144 | } | ||
145 | return 1; | 163 | return 1; |
146 | } | 164 | } |
147 | 165 | ... | ... |
-
Please register or sign in to post a comment