1 /* vi: set sw=4 ts=4: */
5 * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
7 * Licensed under GPLv2, see file LICENSE in this source tree.
13 // generic signal handler
14 static void signal_handler(int signo)
17 if (SIGALRM == signo) {
18 bb_simple_error_msg_and_die("timed out");
21 // SIGCHLD. reap zombies
22 if (safe_waitpid(G.helper_pid, &err, WNOHANG) > 0) {
24 bb_error_msg_and_die("helper killed by signal %u", WTERMSIG(err));
28 bb_error_msg_and_die("helper exited (%u)", WEXITSTATUS(err));
34 void FAST_FUNC launch_helper(const char **argv)
36 // setup vanilla unidirectional pipes interchange
43 // NB: handler must be installed before vfork
49 G.helper_pid = xvfork();
51 i = (!G.helper_pid) * 2; // for parent:0, for child:2
52 close(pipes[i + 1]); // 1 or 3 - closing one write end
53 close(pipes[2 - i]); // 2 or 0 - closing one read end
54 xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end
55 xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - using other write end
57 // parent stdout [3] -> child stdin [2]
58 // child stdout [1] -> parent stdin [0]
62 // if parent dies, get SIGTERM
63 prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);
64 // try to execute connection helper
65 // NB: SIGCHLD & SIGALRM revert to SIG_DFL on exec
66 BB_EXECVP_or_die((char**)argv);
72 char* FAST_FUNC send_mail_command(const char *fmt, const char *param)
79 msg = xasprintf(fmt, param);
81 bb_error_msg("send:'%s'", msg);
82 printf("%s\r\n", msg);
88 // NB: parse_url can modify url[] (despite const), but only if '@' is there
90 static char* FAST_FUNC parse_url(char *url, char **user, char **pass)
92 // parse [user[:pass]@]host
94 char *s = strchr(url, '@');
100 s = strchr(*user, ':');
110 static void encode_n_base64(const char *fname, const char *text, size_t len)
113 SRC_BUF_SIZE = 57, /* This *MUST* be a multiple of 3 */
114 DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3),
117 char src[SRC_BUF_SIZE];
119 char dst_buf[DST_BUF_SIZE + 1];
122 fp = (NOT_LONE_DASH(fname)) ? xfopen_for_read(fname) : stdin;
129 size = fread((char *)src_buf, 1, SRC_BUF_SIZE, fp);
130 if ((ssize_t)size < 0)
131 bb_simple_perror_msg_and_die(bb_msg_read_error);
134 if (len > SRC_BUF_SIZE)
139 // encode the buffer we just read in
140 bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64);
147 fwrite(dst_buf, 1, 4 * ((size + 2) / 3), stdout);
149 if (fname && NOT_LONE_DASH(fname))
154 void FAST_FUNC printstr_base64(const char *text)
156 encode_n_base64(NULL, text, strlen(text));
159 void FAST_FUNC printbuf_base64(const char *text, unsigned len)
161 encode_n_base64(NULL, text, len);
164 void FAST_FUNC printfile_base64(const char *fname)
166 encode_n_base64(fname, NULL, 0);
170 * get username and password from a file descriptor
172 void FAST_FUNC get_cred_or_die(int fd)
175 G.user = bb_ask_noecho(fd, /* timeout: */ 0, "User: ");
176 G.pass = bb_ask_noecho(fd, /* timeout: */ 0, "Password: ");
178 G.user = xmalloc_reads(fd, /* maxsize: */ NULL);
179 G.pass = xmalloc_reads(fd, /* maxsize: */ NULL);
181 if (!G.user || !*G.user || !G.pass)
182 bb_simple_error_msg_and_die("no username or password");