X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fwhatnow.c;h=7217096afe7a095598d5a5b6cf6ac5f738083e36;hp=0ec8e41a5211785f6ebf173c68b60d045b9ace45;hb=32b2354dbaf4bf934936eb5b102a4a3d2fdd209a;hpb=c73c00bfccd22ec77e9593f47462aeca4a8cd9c0 diff --git a/uip/whatnow.c b/uip/whatnow.c index 0ec8e41..7217096 100644 --- a/uip/whatnow.c +++ b/uip/whatnow.c @@ -28,9 +28,8 @@ ** attach files This option attaches the named files to ** the draft. ** -** alist [-ln] This option lists the attachments on the -** draft. -l gets long listings, -n gets -** numbered listings. +** alist This option lists the attachments on the +** draft. ** ** detach files This option removes attachments from the ** detach -n numbers draft. This can be done by file name or @@ -46,13 +45,11 @@ static struct swit whatnowswitches[] = { #define EDITRSW 0 { "editor editor", 0 }, -#define NEDITSW 1 - { "noedit", 0 }, -#define PRMPTSW 2 +#define PRMPTSW 1 { "prompt string", 4 }, -#define VERSIONSW 3 - { "version", 0 }, -#define HELPSW 4 +#define VERSIONSW 2 + { "Version", 0 }, +#define HELPSW 3 { "help", 0 }, { NULL, 0 } }; @@ -66,29 +63,27 @@ static struct swit aleqs[] = { #define REFILEOPT 1 { "refile [] +folder", 0 }, #define DISPSW 2 - { "display []", 0 }, + { "display", 0 }, #define LISTSW 3 - { "list []", 0 }, + { "list", 0 }, #define SENDSW 4 { "send []", 0 }, -#define PUSHSW 5 - { "push []", 0 }, -#define QUITSW 6 - { "quit [-delete]", 0 }, -#define DELETESW 7 +#define QUITSW 5 + { "quit", 0 }, +#define DELETESW 6 { "delete", 0 }, -#define CDCMDSW 8 +#define CDCMDSW 7 { "cd [directory]", 0 }, -#define PWDCMDSW 9 +#define PWDCMDSW 8 { "pwd", 0 }, -#define LSCMDSW 10 +#define LSCMDSW 9 { "ls", 0 }, -#define ATTACHCMDSW 11 +#define ATTACHCMDSW 10 { "attach", 0 }, -#define DETACHCMDSW 12 - { "detach [-n]", 2 }, -#define ALISTCMDSW 13 - { "alist [-ln] ", 2 }, +#define DETACHCMDSW 11 + { "detach [-n]", 0 }, +#define ALISTCMDSW 12 + { "alist", 0 }, { NULL, 0 } }; @@ -98,9 +93,9 @@ static char *myprompt = "\nWhat now? "; ** static prototypes */ static int editfile(char **, char **, char *, int, struct msgs *, - char *, char *, int); -static int sendfile(char **, char *, int); -static void sendit(char *, char **, char *, int); + char *, char *); +static int sendfile(char **, char *); +static int refile(char **, char *); static int removefile(char *); static void writelscmd(char *, int, char **); static void writesomecmd(char *buf, int bufsz, char *cmd, char *trailcmd, char **argp); @@ -116,7 +111,7 @@ static int copyf(char *, char *); int main(int argc, char **argv) { - int nedit = 0, use = 0; + int use = 0; char *cp; char *ed = NULL, *drft = NULL, *msgnam = NULL; char buf[BUFSIZ], prompt[BUFSIZ]; @@ -126,8 +121,7 @@ main(int argc, char **argv) char file[MAXPATHLEN + 1]; /* file name buffer */ char shell[MAXPATHLEN + 1]; /* shell response buffer */ FILE *f; /* read pointer for bgnd proc */ - char *l; /* set on -l to alist command */ - int n; /* set on -n to alist command */ + int n; /* set on -n to detach command */ #ifdef LOCALE setlocale(LC_ALL, ""); @@ -145,7 +139,7 @@ main(int argc, char **argv) ** Get the initial current working directory. */ - if (getcwd(cwd, sizeof (cwd)) == NULL) { + if (!getcwd(cwd, sizeof (cwd))) { adios("getcwd", "could not get working directory"); } @@ -172,10 +166,6 @@ main(int argc, char **argv) if (!(ed = *argp++) || *ed == '-') adios(NULL, "missing argument to %s", argp[-2]); - nedit = 0; - continue; - case NEDITSW: - nedit++; continue; case PRMPTSW: @@ -192,7 +182,7 @@ main(int argc, char **argv) drft = cp; } - if ((drft == NULL && (drft = getenv("mhdraft")) == NULL) || *drft == 0) + if ((!drft && !(drft = getenv("mhdraft"))) || !*drft) drft = getcpy(m_draft(seq_cur)); msgnam = (cp = getenv("mhaltmsg")) && *cp ? getcpy(cp) : NULL; @@ -200,15 +190,20 @@ main(int argc, char **argv) if ((cp = getenv("mhuse")) && *cp) use = atoi(cp); - if (ed == NULL && ((ed = getenv("mheditor")) == NULL || *ed == 0)) { - ed = NULL; - nedit++; + if (!ed && !(ed = getenv("mheditor"))) { + ed = ""; /* Don't initially edit the draft */ } - /* start editing the draft, unless -noedit was given */ - if (!nedit && editfile(&ed, NULL, drft, use, NULL, msgnam, NULL, 1) - < 0) - done(1); + /* start editing the draft, unless editor is the empty string */ + if (*ed) { + if (editfile(&ed, NULL, drft, use, NULL, msgnam, NULL) <0) { + if (!use) { + unlink(drft); + } + advise(NULL, "Try again."); + done(1); + } + } snprintf(prompt, sizeof(prompt), myprompt, invo_name); for (;;) { @@ -218,38 +213,33 @@ main(int argc, char **argv) } switch (smatch(*argp, aleqs)) { case DISPSW: - /* - ** display the message being replied to, - ** or distributed - */ - if (msgnam) - showfile(++argp, msgnam); - else + /* display the msg being replied to or distributed */ + if (msgnam) { + snprintf(buf, sizeof buf, "%s '%s'", + listproc, msgnam); + system(buf); + } else { advise(NULL, "no alternate message to display"); + } break; case EDITSW: /* Call an editor on the draft file */ if (*++argp) ed = *argp++; - if (editfile(&ed, argp, drft, NOUSE, NULL, - msgnam, NULL, 1) == NOTOK) - done(1); + editfile(&ed, argp, drft, NOUSE, NULL, msgnam, NULL); break; case LISTSW: /* display the draft file */ - showfile(++argp, drft); + snprintf(buf, sizeof buf, "%s '%s'", listproc, drft); + system(buf); break; case QUITSW: - /* Quit, and possibly delete the draft */ - if (*++argp && (*argp[0] == 'd' || - ((*argp)[0] == '-' && (*argp)[1] == 'd'))) { - removefile(drft); - } else { - if (stat(drft, &st) != NOTOK) - advise(NULL, "draft left on %s", drft); + /* quit */ + if (stat(drft, &st) != NOTOK) { + advise(NULL, "draft left on %s", drft); } done(1); @@ -258,21 +248,16 @@ main(int argc, char **argv) removefile(drft); done(1); - case PUSHSW: - /* Send draft in background */ - if (sendfile(++argp, drft, 1)) - done(1); - break; - case SENDSW: /* Send draft */ - sendfile(++argp, drft, 0); + sendfile(++argp, drft); break; case REFILEOPT: /* Refile the draft */ - if (refile(++argp, drft) == 0) + if (refile(++argp, drft) == 0) { done(0); + } break; case CDCMDSW: @@ -290,11 +275,11 @@ main(int argc, char **argv) } else { writesomecmd(buf, BUFSIZ, "cd", "pwd", argp); } - if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) { + if ((f = popen_in_dir(cwd, buf, "r"))) { fgets(cwd, sizeof (cwd), f); - if (strchr(cwd, '\n') != NULL) - *strchr(cwd, '\n') = '\0'; + if (strchr(cwd, '\n')) + *strchr(cwd, '\n') = '\0'; pclose(f); } else { @@ -323,38 +308,14 @@ main(int argc, char **argv) case ALISTCMDSW: /* - ** List attachments on current draft. Options are: - ** - ** -l long listing (full path names) - ** -n numbers listing + ** List attachments on current draft. */ - - l = NULL; - n = 0; - - while (*++argp != NULL) { - if (strcmp(*argp, "-l") == 0) - l = "/"; - - else if (strcmp(*argp, "-n") == 0) - n = 1; - - else if (strcmp(*argp, "-ln") == 0 || - strcmp(*argp, "-nl") == 0) { - l = "/"; - n = 1; - } else { - n = -1; - break; - } + snprintf(buf, sizeof buf, "anno -list -comp '%s' " + "-number all -text IGNORE '%s'", + attach_hdr, drft); + if (system(buf) != 0) { + advise(NULL, "Could not list attachment headers."); } - - if (n == -1) - advise(NULL, "usage is alist [-ln]."); - - else - annolist(drft, attach_hdr, l, n); - break; case ATTACHCMDSW: @@ -384,21 +345,26 @@ main(int argc, char **argv) ** working directory to relative path names. ** Add the attachment annotation to the draft. */ - if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) { - while (fgets(shell, sizeof (shell), f) - != NULL) { + if ((f = popen_in_dir(cwd, buf, "r"))) { + char buf[BUFSIZ]; + + while (fgets(shell, sizeof(shell), f)) { *(strchr(shell, '\n')) = '\0'; if (*shell == '/') - annotate(drft, attach_hdr, - shell, 1, 0, - -2, 1); + sprintf(file, "%s", shell); else { sprintf(file, "%s/%s", cwd, shell); - annotate(drft, attach_hdr, - file, 1, 0, - -2, 1); + } + snprintf(buf, sizeof buf, + "anno -nodate -append " + "-comp '%s' -text '%s'" + " '%s'", + attach_hdr, file, + drft); + if (system(buf) != 0) { + advise(NULL, "Could not add attachment header."); } } @@ -417,7 +383,6 @@ main(int argc, char **argv) ** names and numbers aren't allowed, so this ** catches a -n anywhere in the argument list. */ - for (n = 0, arguments = argp + 1; *arguments != NULL; arguments++) { @@ -434,21 +399,23 @@ main(int argc, char **argv) ** just processed after processing each one so ** that the numbering stays correct. */ - if (n == 1) { - for (arguments = argp + 1; - *arguments != NULL; + for (arguments=argp+1; *arguments; arguments++) { if (strcmp(*arguments, "-n") == 0) continue; if (**arguments != '\0') { + char buf[BUFSIZ]; + n = atoi(*arguments); - annotate(drft, attach_hdr, - NULL, 1, 0, - n, 1); + snprintf(buf, sizeof buf, "anno -delete -comp '%s' -number '%d' '%s'", attach_hdr, n, drft); + if (system(buf) != 0) { + advise(NULL, "Could not delete attachment header."); + } - for (argp = arguments + 1; *argp != NULL; argp++) { + for (argp=arguments+1; *argp; + argp++) { if (atoi(*argp) > n) { if (atoi(*argp) == 1) *argp = ""; @@ -458,7 +425,9 @@ main(int argc, char **argv) } } } + break; } + /* else */ /* ** The arguments are interpreted as file names. @@ -473,12 +442,17 @@ main(int argc, char **argv) ** with a space in it. */ writelscmd(buf, sizeof(buf), argp); - if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) { - while (fgets(shell, sizeof (shell), f) - != NULL) { + if ((f = popen_in_dir(cwd, buf, "r"))) { + while (fgets(shell, sizeof (shell), f)) { *(strchr(shell, '\n')) = '\0'; - annotate(drft, attach_hdr, shell, - 1, 0, 0, 1); + snprintf(buf, sizeof buf, + "anno -delete -comp " + "'%s' -text '%s' '%s'", + attach_hdr, shell, + drft); + if (system(buf) != 0) { + advise(NULL, "Could not delete attachment header."); + } } pclose(f); } else { @@ -529,7 +503,7 @@ writesomecmd(char *buf, int bufsz, char *cmd, char *trailcmd, char **argp) cp = buf + ln; - while (*++argp != NULL) { + while (*++argp) { ln = strlen(*argp); /* +1 for leading space */ if (ln + trailln + 1 > bufsz - (cp-buf)) @@ -597,13 +571,12 @@ popen_in_dir(const char *dir, const char *cmd, const char *type) ** EDIT */ -static int reedit = 0; /* have we been here before? */ static char *edsave = NULL; /* the editor we used previously */ static int editfile(char **ed, char **arg, char *file, int use, struct msgs *mp, - char *altmsg, char *cwd, int save_editor) + char *altmsg, char *cwd) { int pid, status, vecp; char altpath[BUFSIZ], linkpath[BUFSIZ]; @@ -614,38 +587,35 @@ editfile(char **ed, char **arg, char *file, int use, struct msgs *mp, int slinked = 0; #endif /* HAVE_LSTAT */ - /* Was there a previous edit session? */ - if (reedit) { - if (!*ed) { /* no explicit editor */ - *ed = edsave; /* so use the previous one */ - if ((cp = mhbasename(*ed)) == NULL) + if (!*ed || !**ed) { + /* We have no explicit editor. */ + if (edsave) { + /* Use the previous editor ... */ + *ed = edsave; + if (!(cp = mhbasename(*ed))) cp = *ed; - /* unless we've specified it via "editor-next" */ + /* but prefer one specified via "editor-next" */ cp = concat(cp, "-next", NULL); - if ((cp = context_find(cp)) != NULL) + if ((cp = context_find(cp))) *ed = cp; - } - } else { - /* set initial editor */ - if (*ed == NULL && (*ed = context_find("editor")) == NULL) + } else { + /* set initial editor */ *ed = defaulteditor; + } } if (altmsg) { - if (mp == NULL || *altmsg == '/' || cwd == NULL) + if (!mp || *altmsg == '/' || !cwd) strncpy(altpath, altmsg, sizeof(altpath)); else snprintf(altpath, sizeof(altpath), "%s/%s", mp->foldpath, altmsg); - if (cwd == NULL) + if (!cwd) strncpy(linkpath, altmsglink, sizeof(linkpath)); else snprintf(linkpath, sizeof(linkpath), "%s/%s", cwd, altmsglink); - } - - if (altmsg) { unlink(linkpath); #ifdef HAVE_LSTAT if (link(altpath, linkpath) == NOTOK) { @@ -686,25 +656,30 @@ editfile(char **ed, char **arg, char *file, int use, struct msgs *mp, vec[vecp] = NULL; execvp(*ed, vec); - fprintf(stderr, "unable to exec "); + fprintf(stderr, "%s: unable to exec ", invo_name); perror(*ed); _exit(-1); default: if ((status = pidwait(pid, NOTOK))) { - if (((status & 0xff00) != 0xff00) - && (!reedit || (status & 0x00ff))) { - if (!use && (status & 0xff00) && (rename(file, cp = m_backup (file)) != NOTOK)) { - advise(NULL, "problems with edit--draft left in %s", cp); - } else { - advise(NULL, "problems with edit--%s preserved", file); - } + if ((status & 0xff00) == 0xff00) { + /* cmd not found or pidwait() failed */ + status = -1; + break; + } + if (status & 0x00ff) { + /* terminated by signal */ + advise(NULL, "%s terminated by signal %d", + *ed, status & 0x7f); + } else { + /* failure exit */ + advise(NULL, "%s exited with return code %d", + *ed, (status & 0xff00) >> 8); } - status = -2; /* maybe "reedit ? -2 : -1"? */ + status = -1; break; } - reedit++; #ifdef HAVE_LSTAT if (altmsg && mp && !is_readonly(mp) && (slinked ? lstat (linkpath, &st) != NOTOK && @@ -725,13 +700,13 @@ editfile(char **ed, char **arg, char *file, int use, struct msgs *mp, #endif /* HAVE_LSTAT */ } - /* normally, we remember which editor we used */ - if (save_editor) - edsave = getcpy(*ed); + /* remember which editor we used */ + edsave = getcpy(*ed); *ed = NULL; - if (altmsg) + if (altmsg) { unlink(linkpath); + } return status; } @@ -771,48 +746,31 @@ copyf(char *ifile, char *ofile) */ static int -sendfile(char **arg, char *file, int pushsw) +sendfile(char **arg, char *file) { pid_t child_id; - int i, vecp; - char *cp, *sp, *vec[MAXARGS]; - - /* - ** If the sendproc is the nmh command `send', then we call - ** those routines directly rather than exec'ing the command. - */ - if (strcmp(sp = mhbasename(sendproc), "send") == 0) { - cp = invo_name; - sendit(invo_name = sp, arg, file, pushsw); - invo_name = cp; - return 1; - } - - /* some different sendproc */ + int vecp; + char *vec[MAXARGS]; context_save(); /* save the context file */ fflush(stdout); - for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) - sleep(5); - switch (child_id) { + switch (child_id = fork()) { case NOTOK: advise(NULL, "unable to fork, so sending directly..."); /* fall */ case OK: vecp = 0; vec[vecp++] = invo_name; - if (pushsw) - vec[vecp++] = "-push"; if (arg) while (*arg) vec[vecp++] = *arg++; vec[vecp++] = file; vec[vecp] = NULL; - execvp(sendproc, vec); - fprintf(stderr, "unable to exec "); - perror(sendproc); + execvp("send", vec); + fprintf(stderr, "%s: unable to exec ", invo_name); + perror("send"); _exit(-1); default: @@ -823,231 +781,44 @@ sendfile(char **arg, char *file, int pushsw) } -static struct swit sendswitches[] = { -#define ALIASW 0 - { "alias aliasfile", 0 }, -#define DEBUGSW 1 - { "debug", -5 }, -#define FILTSW 2 - { "filter filterfile", 0 }, -#define NFILTSW 3 - { "nofilter", 0 }, -#define FRMTSW 4 - { "format", 0 }, -#define NFRMTSW 5 - { "noformat", 0 }, -#define FORWSW 6 - { "forward", 0 }, -#define NFORWSW 7 - { "noforward", 0 }, -#define SPSHSW 8 - { "push", 0 }, -#define NSPSHSW 9 - { "nopush", 0 }, -#define VERBSW 10 - { "verbose", 0 }, -#define NVERBSW 11 - { "noverbose", 0 }, -#define WATCSW 12 - { "watch", 0 }, -#define NWATCSW 13 - { "nowatch", 0 }, -#define WIDTHSW 14 - { "width columns", 0 }, -#define SVERSIONSW 15 - { "version", 0 }, -#define SHELPSW 16 - { "help", 0 }, - { NULL, 0 } -}; - - -extern int debugsw; /* from sendsbr.c */ -extern int forwsw; -extern int inplace; -extern int pushsw; -extern int verbsw; - -extern char *altmsg; /* .. */ -extern char *annotext; -extern char *distfile; - - -static void -sendit(char *sp, char **arg, char *file, int pushed) +/* +** refile msg into another folder +*/ +static int +refile(char **arg, char *file) { - int vecp, n = 1; - char *cp, buf[BUFSIZ], **argp; - char **arguments, *vec[MAXARGS]; - struct stat st; - -#ifndef lint - int distsw = 0; -#endif - - /* - ** Make sure these are defined. In particular, we need - ** vec[1] to be NULL, in case "arg" is NULL below. It - ** doesn't matter what is the value of vec[0], but we - ** set it to NULL, to help catch "off-by-one" errors. - */ - vec[0] = NULL; - vec[1] = NULL; - - /* - ** Temporarily copy arg to vec, since the brkstring() call in - ** getarguments() will wipe it out before it is merged in. - ** Also, we skip the first element of vec, since getarguments() - ** skips it. Then we count the number of arguments - ** copied. The value of "n" will be one greater than - ** this in order to simulate the standard argc/argv. - */ - if (arg) { - char **bp; - - copyip(arg, vec+1, MAXARGS-1); - bp = vec+1; - while (*bp++) - n++; - } - - /* - ** Merge any arguments from command line (now in vec) - ** and arguments from profile. - */ - arguments = getarguments(sp, n, vec, 1); - argp = arguments; - - debugsw = 0; - forwsw = 1; - inplace = 1; - - altmsg = NULL; - annotext = NULL; - distfile = NULL; - - vecp = 1; /* we'll get the zero'th element later */ - vec[vecp++] = "-library"; - vec[vecp++] = getcpy(toabsdir("+")); - - while ((cp = *argp++)) { - if (*cp == '-') { - switch (smatch(++cp, sendswitches)) { - case AMBIGSW: - ambigsw(cp, sendswitches); - return; - case UNKWNSW: - advise(NULL, "-%s unknown\n", cp); - return; - - case SHELPSW: - snprintf(buf, sizeof(buf), - "%s [switches]", sp); - print_help(buf, sendswitches, 1); - return; - case SVERSIONSW: - print_version(invo_name); - return; - - case SPSHSW: - pushed++; - continue; - case NSPSHSW: - pushed = 0; - continue; - - case FORWSW: - forwsw++; - continue; - case NFORWSW: - forwsw = 0; - continue; - - case VERBSW: - verbsw++; - vec[vecp++] = --cp; - continue; - case NVERBSW: - verbsw = 0; - vec[vecp++] = --cp; - continue; - - case DEBUGSW: - debugsw++; /* fall */ - case NFILTSW: - case FRMTSW: - case NFRMTSW: - case WATCSW: - case NWATCSW: - vec[vecp++] = --cp; - continue; - - case ALIASW: - case FILTSW: - case WIDTHSW: - vec[vecp++] = --cp; - if (!(cp = *argp++) || *cp == '-') { - advise(NULL, "missing argument to %s", - argp[-2]); - return; - } - vec[vecp++] = cp; - continue; - - } - } - advise(NULL, "usage: %s [switches]", sp); - return; + pid_t pid; + register int vecp; + char *vec[MAXARGS]; + + vecp = 0; + vec[vecp++] = "refile"; + vec[vecp++] = "-nolink"; /* override bad .mh_profile defaults */ + vec[vecp++] = "-file"; + vec[vecp++] = file; + + while (arg && *arg) { + vec[vecp++] = *arg++; } + vec[vecp] = NULL; - /* allow Aliasfile: profile entry */ - if ((cp = context_find("Aliasfile"))) { - char **ap, *dp; + context_save(); /* save the context file */ + fflush(stdout); - dp = getcpy(cp); - for (ap = brkstring(dp, " ", "\n"); ap && *ap; ap++) { - vec[vecp++] = "-alias"; - vec[vecp++] = getcpy(etcpath(*ap)); - } - } + switch (pid = fork()) { + case -1: + advise("fork", "unable to"); + return -1; - if (!(cp = getenv("SIGNATURE")) || !*cp) - if ((cp = context_find("signature")) && *cp) - m_putenv("SIGNATURE", cp); - - if ((annotext = getenv("mhannotate")) == NULL || *annotext == 0) - annotext = NULL; - if ((altmsg = getenv("mhaltmsg")) == NULL || *altmsg == 0) - altmsg = NULL; - if (annotext && ((cp = getenv("mhinplace")) != NULL && *cp != 0)) - inplace = atoi(cp); - - if ((cp = getenv("mhdist")) && *cp -#ifndef lint - && (distsw = atoi (cp)) -#endif /* not lint */ - && altmsg) { - vec[vecp++] = "-dist"; - distfile = getcpy(m_mktemp2(altmsg, invo_name, NULL, NULL)); - if (link(altmsg, distfile) == NOTOK) - adios(distfile, "unable to link %s to", altmsg); - } else { - distfile = NULL; - } + case 0: + execvp(*vec, vec); + fprintf(stderr, "%s: unable to exec ", invo_name); + perror(*vec); + _exit(-1); - if (altmsg == NULL || stat(altmsg, &st) == NOTOK) { - st.st_mtime = 0; - st.st_dev = 0; - st.st_ino = 0; + default: + return (pidwait(pid, -1)); } - if ((pushsw = pushed)) - push(); - - vec[0] = mhbasename(postproc); - closefds(3); - - if (sendsbr(vec, vecp, file, &st, 1) == OK) - done(0); }