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.
10 # include <sys/prctl.h>
12 #elif defined(__FreeBSD__)
13 # include <sys/procctl.h>
19 // common signal handler
20 static void signal_handler(int signo
)
22 if (SIGALRM
== signo
) {
23 bb_simple_error_msg_and_die("timed out");
26 // SIGCHLD. reap the zombie if we expect one
27 if (G
.helper_pid
== 0)
30 if (safe_waitpid(G
.helper_pid
, &status
, WNOHANG
) > 0) {
32 if (WIFSIGNALED(status
))
33 bb_error_msg_and_die("helper killed by signal %u", WTERMSIG(status
));
34 if (WIFEXITED(status
) && WEXITSTATUS(status
) != 0)
35 bb_error_msg_and_die("helper exited (%u)", WEXITSTATUS(status
));
40 void FAST_FUNC
launch_helper(const char **argv
)
43 struct fd_pair child_out
;
44 struct fd_pair child_in
;
46 xpiped_pair(child_out
);
47 xpiped_pair(child_in
);
49 // NB: handler must be installed before vfork
61 xmove_fd(child_in
.rd
, STDIN_FILENO
);
62 xmove_fd(child_out
.wr
, STDOUT_FILENO
);
63 // if parent dies, get SIGTERM
65 prctl(PR_SET_PDEATHSIG
, SIGTERM
, 0, 0, 0);
66 #elif defined(PROCCTL)
69 procctl(P_PID
, 0, PROC_PDEATHSIG_CTL
, &signum
);
72 // try to execute connection helper
73 // NB: SIGCHLD & SIGALRM revert to SIG_DFL on exec
74 BB_EXECVP_or_die((char**)argv
);
79 xmove_fd(child_out
.rd
, STDIN_FILENO
);
80 xmove_fd(child_in
.wr
, STDOUT_FILENO
);
85 void FAST_FUNC
send_r_n(const char *s
)
88 bb_error_msg("send:'%s'", s
);
92 char* FAST_FUNC
send_mail_command(const char *fmt
, const char *param
)
99 msg
= xasprintf(fmt
, param
);
106 // NB: parse_url can modify url[] (despite const), but only if '@' is there
108 static char* FAST_FUNC parse_url(char *url, char **user, char **pass)
110 // parse [user[:pass]@]host
112 char *s = strchr(url, '@');
113 *user = *pass = NULL;
118 s = strchr(*user, ':');
128 static void encode_n_base64(const char *fname
, const char *text
, size_t len
)
131 SRC_BUF_SIZE
= 57, /* This *MUST* be a multiple of 3 */
132 DST_BUF_SIZE
= 4 * ((SRC_BUF_SIZE
+ 2) / 3),
135 char src
[SRC_BUF_SIZE
];
137 char dst_buf
[DST_BUF_SIZE
+ 1];
140 fp
= (NOT_LONE_DASH(fname
)) ? xfopen_for_read(fname
) : stdin
;
147 size
= fread((char *)src_buf
, 1, SRC_BUF_SIZE
, fp
);
148 if ((ssize_t
)size
< 0)
149 bb_simple_perror_msg_and_die(bb_msg_read_error
);
152 if (len
> SRC_BUF_SIZE
)
157 // encode the buffer we just read in
158 bb_uuencode(dst_buf
, src_buf
, size
, bb_uuenc_tbl_base64
);
165 fwrite(dst_buf
, 1, 4 * ((size
+ 2) / 3), stdout
);
167 if (fname
&& NOT_LONE_DASH(fname
))
172 void FAST_FUNC
printstr_base64(const char *text
)
174 encode_n_base64(NULL
, text
, strlen(text
));
177 void FAST_FUNC
printbuf_base64(const char *text
, unsigned len
)
179 encode_n_base64(NULL
, text
, len
);
182 void FAST_FUNC
printfile_base64(const char *fname
)
184 encode_n_base64(fname
, NULL
, 0);
188 * get username and password from a file descriptor
190 void FAST_FUNC
get_cred_or_die(int fd
)
193 G
.user
= bb_ask_noecho(fd
, /* timeout: */ 0, "User: ");
194 G
.pass
= bb_ask_noecho(fd
, /* timeout: */ 0, "Password: ");
196 G
.user
= xmalloc_reads(fd
, /* maxsize: */ NULL
);
197 G
.pass
= xmalloc_reads(fd
, /* maxsize: */ NULL
);
199 if (!G
.user
|| !*G
.user
|| !G
.pass
)
200 bb_simple_error_msg_and_die("no username or password");