]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/whatnowsbr.c
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);