diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-04 17:56:00 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-04 17:56:00 +0000 |
commit | 021de3f0297af87bfc098bd364dffb332d6ace20 (patch) | |
tree | 46176c3f21464b69aba0682db196124271622b72 | |
parent | 5a2ad699fca8ce2a1e008dfaacd30f7b3f611721 (diff) | |
download | busybox-w32-021de3f0297af87bfc098bd364dffb332d6ace20.tar.gz busybox-w32-021de3f0297af87bfc098bd364dffb332d6ace20.tar.bz2 busybox-w32-021de3f0297af87bfc098bd364dffb332d6ace20.zip |
sendmail: document and fix usage of fd #4, fix check for helper failure.
function old new delta
packed_usage 25663 25694 +31
signal_handler 191 215 +24
kill_helper 22 31 +9
launch_helper 194 184 -10
get_cred_or_die 142 129 -13
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/2 up/down: 64/-23) Total: 41 bytes
-rw-r--r-- | include/usage.h | 1 | ||||
-rw-r--r-- | mailutils/mail.c | 51 |
2 files changed, 28 insertions, 24 deletions
diff --git a/include/usage.h b/include/usage.h index 3363e103f..de6f03767 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -3651,6 +3651,7 @@ | |||
3651 | "\n -H 'prog args' Run connection helper. E.g. openssl for encryption:" \ | 3651 | "\n -H 'prog args' Run connection helper. E.g. openssl for encryption:" \ |
3652 | "\n -H 'exec openssl s_client -quiet -tls1 -starttls smtp" \ | 3652 | "\n -H 'exec openssl s_client -quiet -tls1 -starttls smtp" \ |
3653 | "\n -connect smtp.gmail.com:25' <email.txt" \ | 3653 | "\n -connect smtp.gmail.com:25' <email.txt" \ |
3654 | "\n [4<username_and_passwd.txt]" \ | ||
3654 | "\n -S server[:port] Server" \ | 3655 | "\n -S server[:port] Server" \ |
3655 | ) \ | 3656 | ) \ |
3656 | USE_FEATURE_SENDMAIL_MAILXX( \ | 3657 | USE_FEATURE_SENDMAIL_MAILXX( \ |
diff --git a/mailutils/mail.c b/mailutils/mail.c index f30984897..71f46c86f 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c | |||
@@ -11,9 +11,10 @@ | |||
11 | 11 | ||
12 | static void kill_helper(void) | 12 | static void kill_helper(void) |
13 | { | 13 | { |
14 | // TODO!!!: is there more elegant way to terminate child on program failure? | 14 | if (G.helper_pid > 0) { |
15 | if (G.helper_pid > 0) | ||
16 | kill(G.helper_pid, SIGTERM); | 15 | kill(G.helper_pid, SIGTERM); |
16 | G.helper_pid = 0; | ||
17 | } | ||
17 | } | 18 | } |
18 | 19 | ||
19 | // generic signal handler | 20 | // generic signal handler |
@@ -26,44 +27,50 @@ static void signal_handler(int signo) | |||
26 | } | 27 | } |
27 | 28 | ||
28 | // SIGCHLD. reap zombies | 29 | // SIGCHLD. reap zombies |
29 | if (safe_waitpid(G.helper_pid, &err, WNOHANG) > 0) | 30 | if (safe_waitpid(G.helper_pid, &err, WNOHANG) > 0) { |
31 | if (WIFSIGNALED(err)) | ||
32 | bb_error_msg_and_die("helper killed by signal %u", WTERMSIG(err)); | ||
30 | if (WIFEXITED(err)) { | 33 | if (WIFEXITED(err)) { |
31 | G.helper_pid = 0; | 34 | G.helper_pid = 0; |
32 | if (WEXITSTATUS(err)) | 35 | if (WEXITSTATUS(err)) |
33 | bb_error_msg_and_die("child exited (%d)", WEXITSTATUS(err)); | 36 | bb_error_msg_and_die("helper exited (%u)", WEXITSTATUS(err)); |
34 | } | 37 | } |
38 | } | ||
35 | #undef err | 39 | #undef err |
36 | } | 40 | } |
37 | 41 | ||
38 | void FAST_FUNC launch_helper(const char **argv) | 42 | void FAST_FUNC launch_helper(const char **argv) |
39 | { | 43 | { |
40 | // setup vanilla unidirectional pipes interchange | 44 | // setup vanilla unidirectional pipes interchange |
41 | int idx; | 45 | int i; |
42 | int pipes[4]; | 46 | int pipes[4]; |
43 | 47 | ||
44 | xpipe(pipes); | 48 | xpipe(pipes); |
45 | xpipe(pipes+2); | 49 | xpipe(pipes + 2); |
50 | |||
46 | G.helper_pid = vfork(); | 51 | G.helper_pid = vfork(); |
47 | if (G.helper_pid < 0) | 52 | if (G.helper_pid < 0) |
48 | bb_perror_msg_and_die("vfork"); | 53 | bb_perror_msg_and_die("vfork"); |
49 | idx = (!G.helper_pid) * 2; | 54 | |
50 | xdup2(pipes[idx], STDIN_FILENO); | 55 | i = (!G.helper_pid) * 2; // for parent:0, for child:2 |
51 | xdup2(pipes[3-idx], STDOUT_FILENO); | 56 | close(pipes[i + 1]); // 1 or 3 - closing one write end |
52 | if (ENABLE_FEATURE_CLEAN_UP) | 57 | close(pipes[2 - i]); // 2 or 0 - closing one read end |
53 | for (int i = 4; --i >= 0; ) | 58 | xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end |
54 | if (pipes[i] > STDOUT_FILENO) | 59 | xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - other write end |
55 | close(pipes[i]); | 60 | |
56 | if (!G.helper_pid) { | 61 | if (!G.helper_pid) { |
57 | // child: try to execute connection helper | 62 | // child: try to execute connection helper |
58 | BB_EXECVP(*argv, (char **)argv); | 63 | BB_EXECVP(*argv, (char **)argv); |
59 | _exit(127); | 64 | _exit(127); |
60 | } | 65 | } |
61 | // parent: check whether child is alive | 66 | |
67 | // parent | ||
62 | bb_signals(0 | 68 | bb_signals(0 |
63 | + (1 << SIGCHLD) | 69 | + (1 << SIGCHLD) |
64 | + (1 << SIGALRM) | 70 | + (1 << SIGALRM) |
65 | , signal_handler); | 71 | , signal_handler); |
66 | signal_handler(SIGCHLD); | 72 | // check whether child is alive |
73 | //redundant:signal_handler(SIGCHLD); | ||
67 | // child seems OK -> parent goes on | 74 | // child seems OK -> parent goes on |
68 | atexit(kill_helper); | 75 | atexit(kill_helper); |
69 | } | 76 | } |
@@ -226,17 +233,13 @@ void FAST_FUNC decode_base64(FILE *src_stream, FILE *dst_stream) | |||
226 | */ | 233 | */ |
227 | void FAST_FUNC get_cred_or_die(int fd) | 234 | void FAST_FUNC get_cred_or_die(int fd) |
228 | { | 235 | { |
229 | // either from TTY | ||
230 | if (isatty(fd)) { | 236 | if (isatty(fd)) { |
231 | G.user = xstrdup(bb_ask_stdin("User: ")); | 237 | G.user = xstrdup(bb_ask(fd, /* timeout: */ 0, "User: ")); |
232 | G.pass = xstrdup(bb_ask_stdin("Password: ")); | 238 | G.pass = xstrdup(bb_ask(fd, /* timeout: */ 0, "Password: ")); |
233 | // or from STDIN | ||
234 | } else { | 239 | } else { |
235 | FILE *fp = fdopen(fd, "r"); | 240 | G.user = xmalloc_reads(fd, /* pfx: */ NULL, /* maxsize: */ NULL); |
236 | G.user = xmalloc_fgetline(fp); | 241 | G.pass = xmalloc_reads(fd, /* pfx: */ NULL, /* maxsize: */ NULL); |
237 | G.pass = xmalloc_fgetline(fp); | ||
238 | fclose(fp); | ||
239 | } | 242 | } |
240 | if (!G.user || !*G.user || !G.pass || !*G.pass) | 243 | if (!G.user || !*G.user || !G.pass) |
241 | bb_error_msg_and_die("no username or password"); | 244 | bb_error_msg_and_die("no username or password"); |
242 | } | 245 | } |