📄 whatnowsbr.c
字号:
/* whatnowsbr.c - the WhatNow shell */#ifndef lintstatic char ident[] = "@(#)$Id: whatnowsbr.c,v 1.2 90/11/25 19:06:16 sharpe Exp $";#endif lint#include "../h/mh.h"#include <stdio.h>#include <signal.h>#include <sys/types.h>#include <sys/stat.h>static int editfile(), copyf(), sendfile(), sendit(), whomfile();/* */static struct swit whatnowswitches[] = {#define DFOLDSW 0 "draftfolder +folder", 0,#define DMSGSW 1 "draftmessage msg", 0,#define NDFLDSW 2 "nodraftfolder", 0,#define EDITRSW 3 "editor editor", 0,#define NEDITSW 4 "noedit", 0,#define PRMPTSW 5 "prompt string", 4,#define HELPSW 6 "help", 4, NULL, NULL};/* */static struct swit aleqs[] = {#define DISPSW 0 "display [<switches>]", 0,#define EDITSW 1 "edit [<editor> <switches>]", 0,#define LISTSW 2 "list [<switches>]", 0,#define PUSHSW 3 "push [<switches>]", 0,#define QUITSW 4 "quit [-delete]", 0,#define REFILEOPT 5 "refile [<switches>] +folder", 0,#define SENDSW 6 "send [<switches>]", 0,#define WHOMSW 7 "whom [<switches>]", 0, NULL, NULL};/* */static char *myprompt = "\nWhat now? ";/* *//* ARGSUSED */int WhatNow (argc, argv)int argc;char **argv;{ int isdf = 0, nedit = 0, use = 0; char *cp, *dfolder = NULL, *dmsg = NULL, *ed = NULL, *drft = NULL, *msgnam = NULL, buf[100], prompt[BUFSIZ], **ap, **argp, *arguments[MAXARGS]; struct stat st; invo_name = r1bindex (argv[0], '/'); if ((cp = m_find (invo_name)) != NULL) { ap = brkstring (cp = getcpy (cp), " ", "\n"); ap = copyip (ap, arguments); } else ap = arguments; (void) copyip (argv + 1, ap); argp = arguments;/* */ while (cp = *argp++) { if (*cp == '-') switch (smatch (++cp, whatnowswitches)) { case AMBIGSW: ambigsw (cp, whatnowswitches); done (1); case UNKWNSW: adios (NULLCP, "-%s unknown", cp); case HELPSW: (void) sprintf (buf, "%s [switches] [file]", invo_name); help (buf, whatnowswitches); done (1); case DFOLDSW: if (dfolder) adios (NULLCP, "only one draft folder at a time!"); if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp, *cp != '@' ? TFOLDER : TSUBCWF); continue; case DMSGSW: if (dmsg) adios (NULLCP, "only one draft message at a time!"); if (!(dmsg = *argp++) || *dmsg == '-') adios (NULLCP, "missing argument to %s", argp[-2]); continue; case NDFLDSW: dfolder = NULL; isdf = NOTOK; continue; case EDITRSW: if (!(ed = *argp++) || *ed == '-') adios (NULLCP, "missing argument to %s", argp[-2]); nedit = 0; continue; case NEDITSW: nedit++; continue; case PRMPTSW: if (!(myprompt = *argp++) || *myprompt == '-') adios (NULLCP, "missing argument to %s", argp[-2]); continue; } if (drft) adios (NULLCP, "only one draft at a time!"); else drft = cp; }/* */ if (drft == NULL && (drft = getenv ("mhdraft")) == NULL || *drft == NULL) drft = getcpy (m_draft (dfolder, dmsg, 1, &isdf)); msgnam = (cp = getenv ("mhaltmsg")) && *cp ? getcpy (cp) : NULLCP; if (ed == NULL && ((ed = getenv ("mheditor")) == NULL || *ed == NULL)) ed = NULL, nedit++; if ((cp = getenv ("mhuse")) && *cp) use = atoi (cp); if (!nedit && editfile (&ed, NULLVP, drft, use, NULLMP, msgnam, NULLCP) < 0) done (1);/* */ (void) sprintf (prompt, myprompt, invo_name); for (;;) { if (!(argp = getans (prompt, aleqs))) { (void) unlink (LINK); done (1); } switch (smatch (*argp, aleqs)) { case DISPSW: if (msgnam) (void) showfile (++argp, msgnam); else advise (NULLCP, "no alternate message to display"); break; case EDITSW: if (*++argp) ed = *argp++; if (editfile (&ed, argp, drft, NOUSE, NULLMP, msgnam, NULLCP) == NOTOK) done (1); break; case LISTSW: (void) showfile (++argp, drft); break; case WHOMSW: (void) whomfile (++argp, drft); break; case QUITSW: if (*++argp && (*argp[0] == 'd' || ((*argp)[0] == '-' && (*argp)[1] == 'd'))) { if (unlink (drft) == NOTOK) adios (drft, "unable to unlink"); } else if (stat (drft, &st) != NOTOK) advise (NULLCP, "draft left on %s", drft); done (1); case PUSHSW: sendfile (++argp, drft, 1); done (1); case SENDSW: sendfile (++argp, drft, 0); break; case REFILEOPT: if (refile (++argp, drft) == 0) done (0); break; default: advise (NULLCP, "say what?"); break; } }}/* EDIT */static int reedit = 0;static char *edsave = NULL;/* ARGSUSED */static int editfile (ed, arg, file, use, mp, altmsg, cwd)register struct msgs *mp;register char **ed, **arg, *file, *altmsg, *cwd;register int use;{ int pid, status; register int vecp; register char *cp; char altpath[BUFSIZ], linkpath[BUFSIZ], *vec[MAXARGS]; struct stat st;#ifdef BSD42#ifdef notdef int oumask; /* PJS: for setting permissions on symlinks. */#endif int slinked;#endif BSD42 if (!reedit) { /* set initial editor */ if (*ed == NULL && (*ed = m_find ("editor")) == NULL) *ed = sysed; } else if (!*ed) { /* no explicit editor */ *ed = edsave; if ((cp = r1bindex (*ed, '/')) == NULL) cp = *ed; cp = concat (cp, "-next", NULLCP); if ((cp = m_find (cp)) != NULL) *ed = cp; } if (altmsg) { if (mp == NULL || *altmsg == '/' || cwd == NULL) (void) strcpy (altpath, altmsg); else (void) sprintf (altpath, "%s/%s", mp -> foldpath, altmsg); if (cwd == NULL) (void) strcpy (linkpath, LINK); else (void) sprintf (linkpath, "%s/%s", cwd, LINK); } if (altmsg) { (void) unlink (linkpath);#ifdef BSD42 if (link (altpath, linkpath) == NOTOK) {#ifdef notdef /* I don't think permission on symlinks matters /JLR */ oumask = umask(0044); /* PJS: else symlinks are world 'r' */#endif (void) symlink (altpath, linkpath);#ifdef notdef umask(oumask); /* PJS: else symlinks are world 'r' */#endif slinked = 1; } else slinked = 0;#else not BSD42 (void) link (altpath, linkpath);#endif not BSD42 } m_update (); (void) fflush (stdout); switch (pid = vfork ()) { case NOTOK: advise ("fork", "unable to"); status = NOTOK; break; case OK: if (cwd) (void) chdir (cwd); if (altmsg) { if (mp) (void) putenv ("mhfolder", mp -> foldpath); (void) putenv ("editalt", altpath); } vecp = 0; vec[vecp++] = r1bindex (*ed, '/'); if (arg) while (*arg) vec[vecp++] = *arg++; vec[vecp++] = file; vec[vecp] = NULL; execvp (*ed, vec); fprintf (stderr, "unable to exec "); perror (*ed); _exit (-1); default: if (status = pidwait (pid, NOTOK)) { if (((status & 0xff00) != 0xff00) && (!reedit || (status & 0x00ff))) if (!use && (status & 0xff00) && (rename (file, m_backup (file)) != NOTOK)) { advise (NULLCP, "problems with edit--%s deleted", file); } else advise (NULLCP, "problems with edit--%s preserved", file); status = -2; break; } reedit++;#ifdef BSD42 if (altmsg && mp && (!mp -> msgflags & READONLY) && (slinked ? lstat (linkpath, &st) != NOTOK && (st.st_mode & S_IFMT) == S_IFREG && copyf (linkpath, altpath) == NOTOK : stat (linkpath, &st) != NOTOK && st.st_nlink == 1 && (unlink (altpath) == NOTOK || link (linkpath, altpath) == NOTOK))) advise (linkpath, "unable to update %s from", altmsg);#else not BSD42 if (altmsg && mp && (!mp -> msgflags & READONLY) && stat (linkpath, &st) != NOTOK && st.st_nlink == 1 && (unlink (altpath) == NOTOK || link (linkpath, altpath) == NOTOK)) advise (linkpath, "unable to update %s from", altmsg);#endif not BSD42 } edsave = getcpy (*ed); *ed = NULL; if (altmsg) (void) unlink (linkpath); return status;}/* */#ifdef BSD42static int copyf (ifile, ofile)register char *ifile, *ofile;{ register int i; int in, out; char buffer[BUFSIZ]; if ((in = open (ifile, 0)) == NOTOK) return NOTOK; if ((out = open (ofile, 1)) == NOTOK || ftruncate (out, 0) == NOTOK) { if (out != NOTOK) { admonish (ofile, "unable to truncate"); (void) close (out); } (void) close (in); return NOTOK; } while ((i = read (in, buffer, sizeof buffer)) > OK) if (write (out, buffer, i) != i) { advise (ofile, "may have damaged"); i = NOTOK; break; } (void) close (in); (void) close (out); return i;}#endif BSD42/* SEND */static sendfile (arg, file, pushsw)register char **arg, *file;int pushsw;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -