1 /* whatnowsbr.c - the WhatNow shell */
3 static char ident[] = "@(#)$Id: whatnowsbr.c,v 1.24 1995/12/06 21:04:47 jromine Exp $";
13 #define MIMEminc(a) (a)
18 static int editfile(), copyf(), sendfile(), sendit(), whomfile();
24 static struct swit whatnowswitches[] = {
26 "draftfolder +folder", 0,
28 "draftmessage msg", 0,
48 static struct swit aleqs[] = {
50 "display [<switches>]", 0,
52 "edit [<editor> <switches>]", 0,
54 "list [<switches>]", 0,
56 "push [<switches>]", 0,
60 "refile [<switches>] +folder", 0,
62 "send [<switches>]", 0,
64 "whom [<switches>]", 0,
71 static char *myprompt = "\nWhat now? ";
77 int WhatNow (argc, argv)
97 invo_name = r1bindex (argv[0], '/');
98 if ((cp = m_find (invo_name)) != NULL) {
99 ap = brkstring (cp = getcpy (cp), " ", "\n");
100 ap = copyip (ap, arguments);
104 (void) copyip (argv + 1, ap);
109 while (cp = *argp++) {
111 switch (smatch (++cp, whatnowswitches)) {
113 ambigsw (cp, whatnowswitches);
116 adios (NULLCP, "-%s unknown", cp);
118 (void) sprintf (buf, "%s [switches] [file]", invo_name);
119 help (buf, whatnowswitches);
124 adios (NULLCP, "only one draft folder at a time!");
125 if (!(cp = *argp++) || *cp == '-')
126 adios (NULLCP, "missing argument to %s", argp[-2]);
127 dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
128 *cp != '@' ? TFOLDER : TSUBCWF);
132 adios (NULLCP, "only one draft message at a time!");
133 if (!(dmsg = *argp++) || *dmsg == '-')
134 adios (NULLCP, "missing argument to %s", argp[-2]);
142 if (!(ed = *argp++) || *ed == '-')
143 adios (NULLCP, "missing argument to %s", argp[-2]);
151 if (!(myprompt = *argp++) || *myprompt == '-')
152 adios (NULLCP, "missing argument to %s", argp[-2]);
156 adios (NULLCP, "only one draft at a time!");
163 if (drft == NULL && (drft = getenv ("mhdraft")) == NULL || *drft == 0)
164 drft = getcpy (m_draft (dfolder, dmsg, 1, &isdf));
165 msgnam = (cp = getenv ("mhaltmsg")) && *cp ? getcpy (cp) : NULLCP;
166 if (ed == NULL && ((ed = getenv ("mheditor")) == NULL || *ed == 0))
168 if ((cp = getenv ("mhuse")) && *cp)
171 && editfile (&ed, NULLVP, drft, use, NULLMP, msgnam, NULLCP) < 0)
176 (void) sprintf (prompt, myprompt, invo_name);
178 if (!(argp = getans (prompt, aleqs))) {
179 (void) unlink (LINK);
182 switch (smatch (*argp, aleqs)) {
185 (void) showfile (++argp, msgnam);
187 advise (NULLCP, "no alternate message to display");
193 if (editfile (&ed, argp, drft, NOUSE, NULLMP, msgnam, NULLCP)
199 (void) showfile (++argp, drft);
203 (void) whomfile (++argp, drft);
207 if (*++argp && (*argp[0] == 'd' ||
208 ((*argp)[0] == '-' && (*argp)[1] == 'd'))) {
209 if (unlink (drft) == NOTOK)
210 adios (drft, "unable to unlink");
213 if (stat (drft, &st) != NOTOK)
214 advise (NULLCP, "draft left on %s", drft);
218 if (sendfile (++argp, drft, 1))
223 (void) sendfile (++argp, drft, 0);
227 if (refile (++argp, drft) == 0)
232 advise (NULLCP, "say what?");
241 static int reedit = 0;
242 static char *edsave = NULL;
247 static int editfile (ed, arg, file, use, mp, altmsg, cwd)
248 register struct msgs *mp;
260 char altpath[BUFSIZ],
266 int oumask; /* PJS: for setting permissions on symlinks. */
271 if (!reedit) { /* set initial editor */
272 if (*ed == NULL && (*ed = m_find ("editor")) == NULL)
276 if (!*ed) { /* no explicit editor */
278 if ((cp = r1bindex (*ed, '/')) == NULL)
280 cp = concat (cp, "-next", NULLCP);
281 if ((cp = m_find (cp)) != NULL)
286 if (mp == NULL || *altmsg == '/' || cwd == NULL)
287 (void) strcpy (altpath, altmsg);
289 (void) sprintf (altpath, "%s/%s", mp -> foldpath, altmsg);
291 (void) strcpy (linkpath, LINK);
293 (void) sprintf (linkpath, "%s/%s", cwd, LINK);
297 (void) unlink (linkpath);
299 if (link (altpath, linkpath) == NOTOK) {
300 #ifdef notdef /* I don't think permission on symlinks matters /JLR */
301 oumask = umask(0044); /* PJS: else symlinks are world 'r' */
303 (void) symlink (altpath, linkpath);
305 umask(oumask); /* PJS: else symlinks are world 'r' */
311 #else /* not BSD42 */
312 (void) link (altpath, linkpath);
313 #endif /* not BSD42 */
317 (void) fflush (stdout);
319 switch (pid = vfork ()) {
321 advise ("fork", "unable to");
330 (void) m_putenv ("mhfolder", mp -> foldpath);
331 (void) m_putenv ("editalt", altpath);
335 vec[vecp++] = r1bindex (*ed, '/');
338 vec[vecp++] = *arg++;
343 fprintf (stderr, "unable to exec ");
348 if (status = pidwait (pid, NOTOK)) {
350 if ((cp = r1bindex (*ed, '/'))
351 && strcmp (cp, "vi") == 0
352 && (status & 0x00ff) == 0)
356 if (((status & 0xff00) != 0xff00)
357 && (!reedit || (status & 0x00ff)))
358 if (!use && (status & 0xff00) &&
359 (rename (file, cp = m_backup (file)) != NOTOK)) {
360 advise (NULLCP, "problems with edit--draft left in %s",
364 advise (NULLCP, "problems with edit--%s preserved",
366 status = -2; /* maybe "reedit ? -2 : -1"? */
377 && (!mp -> msgflags & READONLY)
379 ? lstat (linkpath, &st) != NOTOK
380 && (st.st_mode & S_IFMT) == S_IFREG
381 && copyf (linkpath, altpath) == NOTOK
382 : stat (linkpath, &st) != NOTOK
384 && (unlink (altpath) == NOTOK
385 || link (linkpath, altpath) == NOTOK)))
386 advise (linkpath, "unable to update %s from", altmsg);
387 #else /* not BSD42 */
390 && (!mp -> msgflags & READONLY)
391 && stat (linkpath, &st) != NOTOK
393 && (unlink (altpath) == NOTOK
394 || link (linkpath, altpath) == NOTOK))
395 advise (linkpath, "unable to update %s from", altmsg);
396 #endif /* not BSD42 */
399 edsave = getcpy (*ed);
402 (void) unlink (linkpath);
410 static int copyf (ifile, ofile)
411 register char *ifile,
419 if ((in = open (ifile, 0)) == NOTOK)
421 if ((out = open (ofile, 1)) == NOTOK || ftruncate (out, 0) == NOTOK) {
423 admonish (ofile, "unable to truncate");
430 while ((i = read (in, buffer, sizeof buffer)) > OK)
431 if (write (out, buffer, i) != i) {
432 advise (ofile, "may have damaged");
446 static sendfile (arg, file, pushsw)
451 register int child_id,
459 if ((cp = m_find ("automhnproc"))
460 && !getenv ("NOMHNPROC")
462 && (i = editfile (&cp, NULLVP, file, NOUSE, NULLMP, NULLCP,
467 if (strcmp (sp = r1bindex (sendproc, '/'), "send") == 0) {
469 sendit (invo_name = sp, arg, file, pushsw);
475 (void) fflush (stdout);
477 for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++)
481 advise (NULLCP, "unable to fork, so sending directly...");
484 vec[vecp++] = invo_name;
486 vec[vecp++] = "-push";
489 vec[vecp++] = *arg++;
493 execvp (sendproc, vec);
494 fprintf (stderr, "unable to exec ");
499 if (pidwait (child_id, OK) == 0)
508 #include "../h/mhn.h"
511 static int mhnfile (msgnam)
519 if ((fp = fopen (msgnam, "r")) == NULL)
522 switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
526 if (uleq (name, VRSN_FIELD) || uprf (name, XXX_FIELD_PRF)) {
530 while (state == FLDPLUS)
531 state = m_getfld (state, name, buf, sizeof buf, fp);
538 for (bp = buf; *bp; bp++)
539 if (*bp != ' ' && *bp != '\t' && *bp != '\n') {
544 state = m_getfld (state, name, buf, sizeof buf, fp);
545 } while (state == BODY);
557 static struct swit sendswitches[] = {
559 "alias aliasfile", 0,
580 "filter filterfile", 0,
595 "mime", MIMEminc(-4),
597 "nomime", MIMEminc(-6),
610 "split seconds", MIMEminc(-5),
650 "draftfolder +folder", -6,
652 "draftmessage msg", -6,
660 "record program", -6,
669 extern int debugsw; /* from sendsbr.c */
677 extern char *altmsg; /* .. */
678 extern char *annotext;
679 extern char *distfile;
683 static sendit (sp, arg, file, pushed)
691 #endif /* not lint */
705 (void) copyip (arg, vec);
706 if ((cp = m_find (sp)) != NULL) {
707 ap = brkstring (cp = getcpy (cp), " ", "\n");
708 ap = copyip (ap, arguments);
713 (void) copyip (vec, ap);
716 debugsw = 0, forwsw = 1, inplace = 0, unique = 0;
717 altmsg = annotext = distfile = NULL;
718 vec[vecp++] = "-library";
719 vec[vecp++] = getcpy (m_maildir (""));
723 while (cp = *argp++) {
725 switch (smatch (++cp, sendswitches)) {
727 ambigsw (cp, sendswitches);
730 advise (NULLCP, "-%s unknown\n", cp);
733 (void) sprintf (buf, "%s [switches]", sp);
734 help (buf, sendswitches);
745 if (!(cp = *argp++) || sscanf (cp, "%d", &splitsw) != 1) {
746 advise (NULLCP, "missing argument to %s", argp[-2]);
774 debugsw++; /* fall */
803 if (!(cp = *argp++) || *cp == '-') {
804 advise (NULLCP, "missing argument to %s", argp[-2]);
812 if (!(cp = *argp++) || *cp == '-') {
813 advise (NULLCP, "missing argument to %s", argp[-2]);
819 advise (NULLCP, "usage: %s [switches]", sp);
822 if (cp = m_find ("Aliasfile")) { /* allow Aliasfile: profile entry */
825 for (ap = brkstring(dp = getcpy(cp), " ", "\n"); ap && *ap; ap++) {
826 vec[vecp++] = "-alias";
834 if ((cp = getenv ("KDS")) == NULL || *cp == NULL)
835 if ((cp = m_find ("kdsproc")) && *cp)
836 (void) m_putenv ("KDS", cp);
837 if ((cp = getenv ("TMADB")) == NULL || *cp == NULL)
838 if ((cp = m_find ("tmadb")) && *cp)
839 (void) m_putenv ("TMADB", m_maildir (cp));
842 if ((cp = getenv ("SIGNATURE")) == NULL || *cp == 0)
843 if ((cp = m_find ("signature")) && *cp)
844 (void) m_putenv ("SIGNATURE", cp);
847 (void) sprintf (buf, "%s/.signature", mypath);
848 if ((fp = fopen (buf, "r")) != NULL
849 && fgets (buf, sizeof buf, fp) != NULL) {
851 if (cp = index (buf, '\n'))
853 (void) m_putenv ("SIGNATURE", buf);
858 if ((annotext = getenv ("mhannotate")) == NULL || *annotext == 0)
860 if ((altmsg = getenv ("mhaltmsg")) == NULL || *altmsg == 0)
862 if (annotext && ((cp = getenv ("mhinplace")) != NULL && *cp != 0))
865 if ((cp = getenv ("mhdist"))
868 && (distsw = atoi (cp))
869 #endif /* not lint */
871 vec[vecp++] = "-dist";
872 distfile = getcpy (m_scratch (altmsg, invo_name));
873 if (link (altmsg, distfile) == NOTOK)
874 adios (distfile, "unable to link %s to", altmsg);
879 if (altmsg == NULL || stat (altmsg, &st) == NOTOK)
880 st.st_mtime = 0, st.st_dev = 0, st.st_ino = 0;
884 vec[0] = r1bindex (postproc, '/');
887 if (sendsbr (vec, vecp, file, &st) == OK)
893 static int whomfile (arg, file)
902 (void) fflush (stdout);
904 switch (pid = vfork ()) {
906 advise ("fork", "unable to");
911 vec[vecp++] = r1bindex (whomproc, '/');
915 vec[vecp++] = *arg++;
918 execvp (whomproc, vec);
919 fprintf (stderr, "unable to exec ");
921 _exit (-1); /* NOTREACHED */
924 return (pidwait (pid, NOTOK) & 0377 ? 1 : 0);