struct imap_msg {
char *command; /* Command to send */
- int queue; /* If true, queue for later delivery */
+ bool queue; /* If true, queue for later delivery */
struct imap_msg *next; /* Next pointer */
};
struct imap_cmd {
char tag[16]; /* Command tag */
struct timeval start; /* Time command was sent */
+ char prefix[64]; /* Command prefix */
struct imap_cmd *next; /* Next pointer */
};
static int capability_set(const char *);
static void clear_capability(void);
static int have_capability(void);
-static int send_imap_command(netsec_context *, int noflush, char **errstr,
+static int send_imap_command(netsec_context *, bool noflush, char **errstr,
const char *fmt, ...) CHECK_PRINTF(4, 5);
static int get_imap_response(netsec_context *, const char *token,
char **tokenresp, char **status, int failerr,
char **errstr);
-static void ts_report(const char *str, struct timeval *tv);
+static void ts_report(struct timeval *tv, const char *fmt, ...)
+ CHECK_PRINTF(2, 3);
-static void add_msg(int queue, const char *fmt, ...) CHECK_PRINTF(2, 3);
+static void add_msg(bool queue, const char *fmt, ...) CHECK_PRINTF(2, 3);
static bool timestamp = false;
size_t len;
struct timeval tv_start, tv_connect, tv_auth;
- if (nmh_init(argv[0], 1)) { return 1; }
+ if (nmh_init(argv[0], true, true)) { return 1; }
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
ambigsw (cp, switches);
done (1);
case UNKWNSW:
- adios (NULL, "-%s unknown", cp);
+ die("-%s unknown", cp);
case HELPSW:
snprintf (buf, sizeof(buf), "%s [switches] +folder command "
case HOSTSW:
if (!(host = *argp++) || *host == '-')
- adios(NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
case PORTSW:
if (!(port = *argp++) || *port == '-')
- adios(NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
case USERSW:
if (!(user = *argp++) || *user == '-')
- adios(NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
case SNOOPSW:
continue;
case SASLMECHSW:
if (!(saslmech = *argp++) || *saslmech == '-')
- adios(NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
case AUTHSERVICESW:
if (!(oauth_svc = *argp++) || *oauth_svc == '-')
- adios(NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
case TLSSW:
tls = true;
}
} else if (*cp == '+') {
if (*(cp + 1) == '\0')
- adios(NULL, "Invalid null folder name");
+ die("Invalid null folder name");
add_msg(0, "SELECT \"%s\"", cp + 1);
} else {
add_msg(0, "%s", cp);
}
if (! host)
- adios(NULL, "A hostname must be given with -host");
+ die("A hostname must be given with -host");
nsc = netsec_init();
if (oauth_svc) {
if (netsec_set_oauth_service(nsc, oauth_svc) != OK) {
- adios(NULL, "OAuth2 not supported");
+ die("OAuth2 not supported");
}
}
gettimeofday(&tv_start, NULL);
if ((fd = client(host, port, buf, sizeof(buf), snoop)) == NOTOK)
- adios(NULL, "Connect failed: %s", buf);
+ die("Connect failed: %s", buf);
if (timestamp) {
- ts_report("Connect time", &tv_start);
+ ts_report(&tv_start, "Connect time");
gettimeofday(&tv_connect, NULL);
}
if (initialtls || tls) {
if (netsec_set_tls(nsc, 1, 0, &errstr) != OK)
- adios(NULL, errstr);
+ die("%s", errstr);
if (initialtls && netsec_negotiate_tls(nsc, &errstr) != OK)
- adios(NULL, errstr);
+ die("%s", errstr);
}
if (sasl) {
if (netsec_set_sasl_params(nsc, "imap", saslmech, imap_sasl_callback,
nsc, &errstr) != OK)
- adios(NULL, errstr);
+ die("%s", errstr);
}
if ((cp = netsec_readline(nsc, &len, &errstr)) == NULL) {
- adios(NULL, errstr);
+ die("%s", errstr);
}
if (has_prefix(cp, "* BYE")) {
} else {
char *capstring;
- if (send_imap_command(nsc, 0, &errstr, "CAPABILITY") != OK) {
+ if (send_imap_command(nsc, false, &errstr, "CAPABILITY") != OK) {
fprintf(stderr, "Unable to send CAPABILITY command: %s\n", errstr);
goto finish;
}
"has no support for STARTTLS\n");
goto finish;
}
- if (send_imap_command(nsc, 0, &errstr, "STARTTLS") != OK) {
+ if (send_imap_command(nsc, false, &errstr, "STARTTLS") != OK) {
fprintf(stderr, "Unable to issue STARTTLS: %s\n", errstr);
goto finish;
}
goto finish;
}
if (netsec_negotiate_tls(nsc, &errstr) != OK) {
- adios(NULL, errstr);
+ die("%s", errstr);
}
}
if (!have_capability()) {
char *capstring;
- if (send_imap_command(nsc, 0, &errstr, "CAPABILITY") != OK) {
+ if (send_imap_command(nsc, false, &errstr, "CAPABILITY") != OK) {
fprintf(stderr, "Unable to send CAPABILITY command: %s\n", errstr);
goto finish;
}
}
if (timestamp) {
- ts_report("Authentication time", &tv_connect);
+ ts_report(&tv_connect, "Authentication time");
gettimeofday(&tv_auth, NULL);
}
free(imsg);
}
- ts_report("Total command execution time", &tv_auth);
+ if (timestamp)
+ ts_report(&tv_auth, "Total command execution time");
send_imap_command(nsc, 0, NULL, "LOGOUT");
get_imap_response(nsc, NULL, NULL, NULL, 0, NULL);
finish:
netsec_shutdown(nsc);
- ts_report("Total elapsed time", &tv_start);
+ if (timestamp)
+ ts_report(&tv_start, "Total elapsed time");
exit(0);
}
*/
case NETSEC_SASL_FINISH:
+ line = NULL;
if (get_imap_response(nsc, NULL, NULL, &line, 1, errstr) != OK)
return NOTOK;
/*
* parse it.
*/
- if (has_prefix(line, "OK [CAPABILITY ")) {
+ if (line && has_prefix(line, "OK [CAPABILITY ")) {
char *p = line + 15, *q;
q = strchr(p, ']');
*/
static int
-send_imap_command(netsec_context *nsc, int noflush, char **errstr,
+send_imap_command(netsec_context *nsc, bool noflush, char **errstr,
const char *fmt, ...)
{
static unsigned int seq = 0; /* Tag sequence number */
snprintf(cmd->tag, sizeof(cmd->tag), "A%u ", seq++);
- if (timestamp)
+ if (timestamp) {
+ char *p;
+ va_start(ap, fmt);
+ vsnprintf(cmd->prefix, sizeof(cmd->prefix), fmt, ap);
+ va_end(ap);
+
+ p = strchr(cmd->prefix, ' ');
+
+ if (p)
+ *p = '\0';
+
gettimeofday(&cmd->start, NULL);
+ }
if (netsec_write(nsc, cmd->tag, strlen(cmd->tag), errstr) != OK) {
free(cmd);
{
char *line;
struct imap_cmd *cmd;
- int numerrs = 0;
+ bool numerrs = false;
if (tokenresponse)
*tokenresponse = NULL;
if (has_prefix(line, cmdqueue->tag)) {
cmd = cmdqueue;
if (timestamp)
- ts_report("Command execution time", &cmd->start);
+ ts_report(&cmd->start, "Command (%s) execution time",
+ cmd->prefix);
cmdqueue = cmd->next;
free(cmd);
} else {
cmd->next = cmd->next->next;
if (failerr && strncmp(line + strlen(cmd2->tag),
"OK ", 3) != 0) {
- numerrs++;
+ numerrs = true;
netsec_err(errstr, "%s", line + strlen(cmd2->tag));
}
free(cmd2);
}
}
- return numerrs == 0 ? OK : NOTOK;
+ return numerrs ? NOTOK : OK;
}
/*
*/
static void
-add_msg(int queue, const char *fmt, ...)
+add_msg(bool queue, const char *fmt, ...)
{
struct imap_msg *imsg;
va_list ap;
*/
static void
-ts_report(const char *str, struct timeval *tv)
+ts_report(struct timeval *tv, const char *fmt, ...)
{
struct timeval now;
double delta;
+ va_list ap;
gettimeofday(&now, NULL);
delta = ((double) now.tv_sec) - ((double) tv->tv_sec) +
(now.tv_usec / 1E6 - tv->tv_usec / 1E6);
- printf("%s: %f sec\n", str, delta);
+ va_start(ap, fmt);
+ vfprintf(stdout, fmt, ap);
+ va_end(ap);
+
+ printf(": %f sec\n", delta);
}