X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/92c3b05ef3e582d64b3cecfc261fdd66ef13a4ef..085bca07c0b505f095a50666a3752e5fcb69bc70:/uip/sendsbr.c diff --git a/uip/sendsbr.c b/uip/sendsbr.c index 0af6f63a..628b99d2 100644 --- a/uip/sendsbr.c +++ b/uip/sendsbr.c @@ -5,16 +5,36 @@ * complete copyright information. */ -#include -#include -#include -#include +#include "h/mh.h" +#include "sbr/fmt_new.h" +#include "sendsbr.h" +#include "distsbr.h" +#include "annosbr.h" +#include "sbr/m_name.h" +#include "sbr/m_getfld.h" +#include "sbr/concat.h" +#include "sbr/cpydgst.h" +#include "sbr/trimcpy.h" +#include "sbr/uprf.h" +#include "sbr/getcpy.h" +#include "sbr/m_convert.h" +#include "sbr/m_backup.h" +#include "sbr/folder_read.h" +#include "sbr/folder_free.h" +#include "sbr/context_find.h" +#include "sbr/brkstring.h" +#include "sbr/pidstatus.h" +#include "sbr/arglist.h" +#include "sbr/error.h" +#include "h/fmt_scan.h" +#include "h/fmt_compile.h" +#include "h/signals.h" #include #include -#include -#include -#include -#include +#include "h/mime.h" +#include "h/tws.h" +#include "h/utils.h" +#include "h/mts.h" #ifdef HAVE_SYS_TIME_H # include @@ -22,8 +42,9 @@ #include #ifdef OAUTH_SUPPORT -#include +#include "h/oauth.h" #endif +#include "h/done.h" #include "sbr/m_maildir.h" #include "sbr/m_mktemp.h" #include "sbr/message_id.h" @@ -33,12 +54,11 @@ static int setup_oauth_params(char *[], int *, const char *, const char **); #endif /* OAUTH_SUPPORT */ int debugsw = 0; /* global */ -int forwsw = 1; +bool forwsw = true; int inplace = 1; -int pushsw = 0; -int splitsw = -1; -int unique = 0; -int verbsw = 0; +bool pushsw; +bool unique; +bool verbsw; char *altmsg = NULL; /* .. */ char *annotext = NULL; @@ -53,7 +73,6 @@ static void alert (char *, int); static int tmp_fd (void); static void anno (int, struct stat *); static void annoaux (int); -static int splitmsg (char **, int, char *, char *, struct stat *, int); static int sendaux (char **, int, char *, char *, struct stat *); static void handle_sendfrom(char **, int *, char *, const char *); static int get_from_header_info(const char *, const char **, const char **, const char **); @@ -72,7 +91,6 @@ sendsbr (char **vec, int vecp, char *program, char *draft, struct stat *st, int status, i; pid_t child; char buffer[BUFSIZ], file[BUFSIZ]; - struct stat sts; char **buildvec, *buildprogram; char *volatile drft = draft; /* nvecs is volatile to prevent warning from gcc about possible clobbering @@ -100,16 +118,16 @@ sendsbr (char **vec, int vecp, char *program, char *draft, struct stat *st, execvp(buildprogram, buildvec); fprintf(stderr, "unable to exec "); perror(buildmimeproc); - _exit(-1); + _exit(1); break; default: - if (pidXwait(child, buildmimeproc)) + if (pidXwait(child, buildmimeproc)) return NOTOK; break; } - done=armed_done; + set_done(armed_done); switch (setjmp (env)) { case OK: /* @@ -119,10 +137,10 @@ sendsbr (char **vec, int vecp, char *program, char *draft, struct stat *st, if (pushsw && unique) { char *cp = m_mktemp2(drft, invo_name, NULL, NULL); if (cp == NULL) { - adios(NULL, "unable to create temporary file in %s", - get_temp_dir()); + die("unable to create temporary file"); } - if (rename (drft, strncpy(file, cp, sizeof(file))) == NOTOK) + if (rename (drft, strncpy(file, cp, sizeof(file) - 1)) == + NOTOK) adios (file, "unable to rename %s to", drft); drft = file; } @@ -135,10 +153,10 @@ sendsbr (char **vec, int vecp, char *program, char *draft, struct stat *st, #ifdef OAUTH_SUPPORT const char *errmsg; if (setup_oauth_params(vec, nvecsp, auth_svc, &errmsg) != OK) { - adios(NULL, "%s", errmsg); + die("%s", errmsg); } #else - adios(NULL, "send built without OAUTH_SUPPORT, " + die("send built without OAUTH_SUPPORT, " "so auth_svc %s is not supported", auth_svc); #endif /* OAUTH_SUPPORT */ } @@ -151,22 +169,12 @@ sendsbr (char **vec, int vecp, char *program, char *draft, struct stat *st, handle_sendfrom(vec, nvecsp, draft, auth_svc); } - /* - * Check if we need to split the message into - * multiple messages of type "message/partial". - */ - if (splitsw >= 0 && !distfile && stat ((char *) drft, &sts) != NOTOK - && sts.st_size >= CPERMSG) { - status = splitmsg (vec, nvecs, program, drft, - st, splitsw) ? NOTOK : OK; - } else { - status = sendaux (vec, nvecs, program, drft, st) ? NOTOK : OK; - } + status = sendaux (vec, nvecs, program, drft, st) ? NOTOK : OK; /* rename the original draft */ if (rename_drft && status == OK && rename (drft, strncpy (buffer, m_backup (drft), - sizeof(buffer))) == NOTOK) + sizeof(buffer) - 1)) == NOTOK) advise (buffer, "unable to rename %s to", drft); break; @@ -175,245 +183,13 @@ sendsbr (char **vec, int vecp, char *program, char *draft, struct stat *st, break; } - done=exit; + set_done(exit); if (distfile) (void) m_unlink (distfile); return status; } -/* - * Split large message into several messages of - * type "message/partial" and send them. - */ - -static int -splitmsg (char **vec, int vecp, char *program, char *drft, - struct stat *st, int delay) -{ - int compnum, nparts, partno, state, status; - long pos, start; - time_t clock; - char *cp, *dp, buffer[NMH_BUFSIZ], msgid[BUFSIZ]; - char subject[BUFSIZ]; - char name[NAMESZ], partnum[BUFSIZ]; - FILE *in; - m_getfld_state_t gstate; - - if ((in = fopen (drft, "r")) == NULL) - adios (drft, "unable to open for reading"); - - cp = dp = NULL; - start = 0L; - - /* - * Scan through the message and examine the various header fields, - * as well as locate the beginning of the message body. - */ - gstate = m_getfld_state_init(in); - m_getfld_track_filepos2(&gstate); - for (compnum = 1;;) { - int bufsz = sizeof buffer; - switch (state = m_getfld2(&gstate, name, buffer, &bufsz)) { - case FLD: - case FLDPLUS: - compnum++; - - /* - * This header field is discarded. - */ - if (!strcasecmp (name, "Message-ID")) { - while (state == FLDPLUS) { - bufsz = sizeof buffer; - state = m_getfld2(&gstate, name, buffer, &bufsz); - } - } else if (uprf (name, XXX_FIELD_PRF) - || !strcasecmp (name, VRSN_FIELD) - || !strcasecmp (name, "Subject") - || !strcasecmp (name, "Encrypted")) { - /* - * These header fields are copied to the enclosed - * header of the first message in the collection - * of message/partials. For the "Subject" header - * field, we also record it, so that a modified - * version of it, can be copied to the header - * of each message/partial in the collection. - */ - if (!strcasecmp (name, "Subject")) { - size_t sublen; - - strncpy (subject, buffer, BUFSIZ); - sublen = strlen (subject); - if (sublen > 0 && subject[sublen - 1] == '\n') - subject[sublen - 1] = '\0'; - } - - dp = add (concat (name, ":", buffer, NULL), dp); - while (state == FLDPLUS) { - bufsz = sizeof buffer; - state = m_getfld2(&gstate, name, buffer, &bufsz); - dp = add (buffer, dp); - } - } else { - /* - * These header fields are copied to the header of - * each message/partial in the collection. - */ - cp = add (concat (name, ":", buffer, NULL), cp); - while (state == FLDPLUS) { - bufsz = sizeof buffer; - state = m_getfld2(&gstate, name, buffer, &bufsz); - cp = add (buffer, cp); - } - } - - start = ftell (in) + 1; - continue; - - case BODY: - case FILEEOF: - break; - - case LENERR: - case FMTERR: - adios (NULL, "message format error in component #%d", compnum); - - default: - adios (NULL, "getfld () returned %d", state); - } - - break; - } - m_getfld_state_destroy (&gstate); - if (cp == NULL) - adios (NULL, "headers missing from draft"); - - nparts = 1; - pos = start; - while (fgets (buffer, sizeof buffer, in)) { - long len; - - if ((pos += (len = strlen (buffer))) > CPERMSG) { - nparts++; - pos = len; - } - } - - /* Only one part, nothing to split */ - if (nparts == 1) { - free (cp); - free(dp); - - fclose (in); - return sendaux (vec, vecp, program, drft, st); - } - - if (!pushsw) { - printf ("Sending as %d Partial Messages\n", nparts); - fflush (stdout); - } - status = OK; - - vec[vecp++] = "-partno"; - vec[vecp++] = partnum; - if (delay == 0) - vec[vecp++] = "-queued"; - - time (&clock); - snprintf (msgid, sizeof(msgid), "%s", message_id (clock, 0)); - - fseek (in, start, SEEK_SET); - for (partno = 1; partno <= nparts; partno++) { - char tmpdrf[BUFSIZ]; - FILE *out; - - char *cp = m_mktemp2(drft, invo_name, NULL, &out); - if (cp == NULL) { - adios(NULL, "unable to create temporary file in %s", - get_temp_dir()); - } - strncpy(tmpdrf, cp, sizeof(tmpdrf)); - - /* - * Output the header fields - */ - fputs (cp, out); - fprintf (out, "Subject: %s (part %d of %d)\n", subject, partno, nparts); - fprintf (out, "%s: %s\n", VRSN_FIELD, VRSN_VALUE); - fprintf (out, "%s: message/partial; id=\"%s\";\n", TYPE_FIELD, msgid); - fprintf (out, "\tnumber=%d; total=%d\n", partno, nparts); - fprintf (out, "%s: part %d of %d\n\n", DESCR_FIELD, partno, nparts); - - /* - * If this is the first in the collection, output the - * header fields we are encapsulating at the beginning - * of the body of the first message. - */ - if (partno == 1) { - if (dp) - fputs (dp, out); - fprintf (out, "Message-ID: %s\n", msgid); - fprintf (out, "\n"); - } - - pos = 0; - for (;;) { - long len; - - if (!fgets (buffer, sizeof buffer, in)) { - if (partno == nparts) - break; - adios (NULL, "premature eof"); - } - - if ((pos += (len = strlen (buffer))) > CPERMSG) { - fseek (in, -len, SEEK_CUR); - break; - } - - fputs (buffer, out); - } - - if (fflush (out)) - adios (tmpdrf, "error writing to"); - - fclose (out); - - if (!pushsw && verbsw) { - putchar('\n'); - fflush (stdout); - } - - /* Pause here, if a delay is specified */ - if (delay > 0 && 1 < partno && partno <= nparts) { - if (!pushsw) { - printf ("pausing %d seconds before sending part %d...\n", - delay, partno); - fflush (stdout); - } - sleep ((unsigned int) delay); - } - - snprintf (partnum, sizeof(partnum), "%d", partno); - status = sendaux (vec, vecp, program, tmpdrf, st); - (void) m_unlink (tmpdrf); - if (status != OK) - break; - - /* - * This is so sendaux will only annotate - * the altmsg the first time it is called. - */ - annotext = NULL; - } - - free (cp); - free(dp); - - fclose (in); /* close the draft */ - return status; -} - /* * Annotate original message, and @@ -467,7 +243,7 @@ sendaux (char **vec, int vecp, char *program, char *drft, struct stat *st) execvp (program, vec); fprintf (stderr, "unable to exec "); perror (postproc); - _exit (-1); + _exit(1); default: /* @@ -549,7 +325,8 @@ alert (char *file, int out) if (write (out, buf, strlen (buf)) < 0) { advise (file, "write"); } - if (rename (file, strncpy (buf, m_backup (file), sizeof(buf))) == NOTOK) + if (rename (file, strncpy (buf, m_backup (file), + sizeof(buf) - 1)) == NOTOK) admonish (buf, "unable to rename %s to", file); } } @@ -562,7 +339,7 @@ alert (char *file, int out) arglist = argsplit(mailproc, &program, &argp); - arglist[argp++] = getusername(); + arglist[argp++] = getusername(1); arglist[argp++] = "-subject"; arglist[argp++] = buf; arglist[argp] = NULL; @@ -570,9 +347,9 @@ alert (char *file, int out) execvp (program, arglist); fprintf (stderr, "unable to exec "); perror (mailproc); - _exit (-1); + _exit(1); - default: /* no waiting... */ + default: /* no waiting... */ break; } } @@ -615,7 +392,7 @@ anno (int fd, struct stat *st) child_id = debugsw ? NOTOK : fork (); switch (child_id) { - case NOTOK: /* oops */ + case NOTOK: /* oops */ if (!debugsw) inform("unable to fork, so doing annotations by hand..."); if (cwd == NULL) @@ -645,7 +422,7 @@ anno (int fd, struct stat *st) } break; - default: /* no waiting... */ + default: /* no waiting... */ close (fd); break; } @@ -739,9 +516,9 @@ oops: } -static -void -handle_sendfrom(char **vec, int *vecp, char *draft, const char *auth_svc) { +static void +handle_sendfrom(char **vec, int *vecp, char *draft, const char *auth_svc) +{ const char *addr, *host; const char *message; @@ -764,12 +541,12 @@ handle_sendfrom(char **vec, int *vecp, char *draft, const char *auth_svc) { if (strcmp(*vp, "xoauth2") == 0) { #ifdef OAUTH_SUPPORT if (setup_oauth_params(vec, vecp, auth_svc, &message) != OK) { - adios(NULL, "%s", message); + die("%s", message); } break; #else NMH_UNUSED(auth_svc); - adios(NULL, "send built without OAUTH_SUPPORT, " + die("send built without OAUTH_SUPPORT, " "so -saslmech xoauth2 is not supported"); #endif /* OAUTH_SUPPORT */ } @@ -784,7 +561,8 @@ handle_sendfrom(char **vec, int *vecp, char *draft, const char *auth_svc) { */ static int setup_oauth_params(char *vec[], int *vecp, const char *auth_svc, - const char **message) { + const char **message) +{ const char *saslmech = NULL, *user = NULL; mh_oauth_service_info svc; char errbuf[256]; @@ -816,14 +594,14 @@ setup_oauth_params(char *vec[], int *vecp, const char *auth_svc, if (saslmech && ! strcasecmp(saslmech, "xoauth2")) { if (! mh_oauth_get_service_info(auth_svc, &svc, errbuf, - sizeof(errbuf))) - adios(NULL, "Unable to retrieve oauth profile entries: %s", + sizeof(errbuf))) + die("Unable to retrieve oauth profile entries: %s", errbuf); vec[(*vecp)++] = mh_xstrdup("-authservice"); vec[(*vecp)++] = mh_xstrdup(auth_svc); vec[(*vecp)++] = mh_xstrdup("-oauthcredfile"); - vec[(*vecp)++] = mh_xstrdup(mh_oauth_cred_fn(auth_svc)); + vec[(*vecp)++] = mh_oauth_cred_fn(auth_svc); vec[(*vecp)++] = mh_xstrdup("-oauthclientid"); vec[(*vecp)++] = getcpy(svc.client_id); vec[(*vecp)++] = mh_xstrdup("-oauthclientsecret"); @@ -847,9 +625,9 @@ setup_oauth_params(char *vec[], int *vecp, const char *auth_svc, /* * Extract user and domain from From: header line in draft. */ -static -int -get_from_header_info(const char *filename, const char **addr, const char **host, const char **message) { +static int +get_from_header_info(const char *filename, const char **addr, const char **host, const char **message) +{ struct stat st; FILE *in; @@ -901,13 +679,13 @@ get_from_header_info(const char *filename, const char **addr, const char **host, * Get formatted information from header of a message. * Adapted from process_single_file() in uip/fmttest.c. */ -static -const char * -get_message_header_info(FILE *in, char *format) { +static const char * +get_message_header_info(FILE *in, char *format) +{ int dat[5]; struct format *fmt; struct stat st; - int parsing_header; + bool parsing_header; m_getfld_state_t gstate; charstring_t buffer = charstring_create(0); char *retval; @@ -923,7 +701,7 @@ get_message_header_info(FILE *in, char *format) { * Read in the message and process the header. */ rewind (in); - parsing_header = 1; + parsing_header = true; gstate = m_getfld_state_init(in); do { char name[NAMESZ], rbuf[NMH_BUFSIZ]; @@ -950,7 +728,7 @@ get_message_header_info(FILE *in, char *format) { break; } default: - parsing_header = 0; + parsing_header = false; } } while (parsing_header); m_getfld_state_destroy(&gstate); @@ -979,9 +757,9 @@ get_message_header_info(FILE *in, char *format) { * If no -server passed in from profile or commandline, could use smtp..com for gmail, * but that might not generalize for other svcs. */ -static -void -merge_profile_entry(const char *addr, const char *host, char *vec[], int *vecp) { +static void +merge_profile_entry(const char *addr, const char *host, char *vec[], int *vecp) +{ char *addr_entry = concat("sendfrom-", addr, NULL); char *profile_entry = context_find(addr_entry);