msh.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,615 行 · 第 1/4 页
C
2,615 行
/* msh.c - The MH shell (sigh) */#ifndef lintstatic char ident[] = "@(#)$Id: msh.c,v 1.2 90/11/25 19:05:05 sharpe Exp $";#endif lint/* TODO: Keep more status information in maildrop map */#include "../h/mh.h"#include "../h/dropsbr.h"#include "../h/formatsbr.h"#include "../h/scansbr.h"#include "../zotnet/tws.h"#include <stdio.h>#include "../zotnet/mts.h"#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#ifndef SYS5#include <sgtty.h>#else SYS5#include <termio.h>#ifndef NOIOCTLH#include <sys/ioctl.h>#endif NOIOCTLH#endif SYS5#include <pwd.h>#include <setjmp.h>#include <signal.h>#include "../h/mshsbr.h"#include "../h/vmhsbr.h"#define QUOTE '\\' /* sigh *//* */static struct swit switches[] = {#define IDSW 0 "idstart number", -7, /* interface from bbc */#define FDSW 1 "idstop number", -6, /* .. */#define QDSW 2 "idquit number", -6, /* .. */#define NMSW 3 "idname BBoard", -6, /* .. */#define PRMPTSW 4 "prompt string", 0,#define SCANSW 5 "scan", 0,#define NSCANSW 6 "noscan", 0,#define READSW 7 "vmhread fd", -7,#define WRITESW 8 "vmhwrite fd", -8, #define PREADSW 9 "popread fd", -7,#define PWRITSW 10 "popwrite fd", -8,#define TCURSW 11 "topcur", 0,#define NTCURSW 12 "notopcur", 0,#define HELPSW 13 "help", 4, NULL, NULL};/* */ /* FOLDER */char *fmsh = NULL; /* folder instead of file */int modified; /* command modified folder */struct msgs *mp; /* used a lot */static int nMsgs = 0;struct Msg *Msgs = NULL; /* Msgs[0] not used */static FILE *fp; /* input file */static FILE *yp = NULL; /* temporary file */static int mode; /* mode of file */static int numfds = 0; /* number of files cached */static int maxfds = 0; /* number of files cached to be cached */static time_t mtime = (time_t) 0;/* mtime of file */ /* VMH */#define ALARM ((unsigned int) 10)#define ttyN(c) ttyNaux ((c), NULLCP)static int vmh = 0;static int vmhpid = OK;static int vmhfd0;static int vmhfd1;static int vmhfd2;static int vmhtty = NOTOK;#define SCAN 1#define STATUS 2#define DISPLAY 3#define NWIN DISPLAYstatic int topcur = 0;static int numwins = 0;static int windows[NWIN + 1];static jmp_buf peerenv;void padios (), padvise ();static int alrmser ();#ifdef BPOP /* POP */static int pmsh = 0; /* BPOP enabled */extern char response[];#endif BPOP /* PARENT */static int pfd = NOTOK; /* fd parent is reading from */static int ppid = 0; /* pid of parent */ /* COMMAND */int interactive; /* running from a /dev/tty */int redirected; /* re-directing output */FILE *sp = NULL; /* original stdout */char *cmd_name; /* command being run */char myfilter[BUFSIZ]; /* path to mhl.forward */static char *myprompt = "(%s) ";/* prompting string */ /* BBOARDS */static int gap; /* gap in BBoard-ID:s */static char *myname = NULL; /* BBoard name */char *BBoard_ID = "BBoard-ID";/* BBoard-ID constant */ /* SIGNALS */TYPESIG (*istat) (); /* original SIGINT */static TYPESIG (*pstat) (); /* current SIGPIPE */TYPESIG (*qstat) (); /* original SIGQUIT */#ifdef SIGTSTPstatic TYPESIG (*tstat) (); /* original SIGTSTP */#endif SIGTSTPint interrupted; /* SIGINT detected */int broken_pipe; /* SIGPIPE detected */int told_to_quit; /* SIGQUIT detected */#ifdef BSD42int should_intr; /* signal handler should interrupt call */jmp_buf sigenv; /* the environment pointer */#endif BSD42static int intrser (), pipeser (), quitser ();#ifdef SYS5struct passwd *getpwnam ();#endif SYS5static int read_map(), read_file(), check_folder(), getargs(), parse();static int getcmds(), init_io(), initaux_io(), finaux_io(), peerwait();static int pINI(), pQRY(), pQRY1(), pQRY2(), pCMD(), pFIN();static int ttyR(), ttyNaux(), winN(), winR(), winX();static msh(), m_gMsgs(), scanrange(), scanstring(), quit();static fin_io(), m_init();#ifdef BPOPstatic int read_pop();#endif/* *//* ARGSUSED */main (argc, argv)int argc;char **argv;{ int id = 0, scansw = 0, vmh1 = 0, vmh2 = 0;#ifdef BPOP int pmsh1 = 0, pmsh2 = 0;#endif BPOP char *cp, *file = NULL, *folder = NULL, **ap, **argp, buf[80], *arguments[MAXARGS]; invo_name = r1bindex (argv[0], '/'); mts_init (invo_name); 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, switches)) { case AMBIGSW: ambigsw (cp, switches); done (1); case UNKWNSW: adios (NULLCP, "-%s unknown", cp); case HELPSW: (void) sprintf (buf, "%s [switches] file", invo_name); help (buf, switches); done (1); case IDSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); if ((id = atoi (cp)) < 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp); continue; case FDSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); if ((pfd = atoi (cp)) <= 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp); continue; case QDSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); if ((ppid = atoi (cp)) <= 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp); continue; case NMSW: if (!(myname = *argp++) || *myname == '-') adios (NULLCP, "missing argument to %s", argp[-2]); continue; case SCANSW: scansw++; continue; case NSCANSW: scansw = 0; continue; case PRMPTSW: if (!(myprompt = *argp++) || *myprompt == '-') adios (NULLCP, "missing argument to %s", argp[-2]); continue; case READSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); if ((vmh1 = atoi (cp)) < 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp); continue; case WRITESW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); if ((vmh2 = atoi (cp)) < 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp); continue; case PREADSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]);#ifdef BPOP if ((pmsh1 = atoi (cp)) < 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp);#endif BPOP continue; case PWRITSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]);#ifdef BPOP if ((pmsh2 = atoi (cp)) < 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp);#endif BPOP continue; case TCURSW: topcur++; continue; case NTCURSW: topcur = 0; continue; } if (*cp == '+' || *cp == '@') { if (folder) adios (NULLCP, "only one folder at a time!"); else folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); } else if (file) adios (NULLCP, "only one file at a time!"); else file = cp; }/* */ if (!file && !folder) file = "./msgbox"; if (file && folder) adios (NULLCP, "use a file or a folder, not both"); (void) strcpy (myfilter, libpath (mhlforward));#ifdef FIOCLEX if (pfd > 1) (void) ioctl (pfd, FIOCLEX, NULLCP);#endif FIOCLEX#ifdef BSD42 should_intr = 0;#endif BSD42 setsigx (istat, SIGINT, intrser); setsigx (qstat, SIGQUIT, quitser); (void) sc_width (); /* MAGIC... */ if (vmh = vmh1 && vmh2) { (void) rcinit (vmh1, vmh2); (void) pINI (); (void) signal (SIGINT, SIG_IGN); (void) signal (SIGQUIT, SIG_IGN);#ifdef SIGTSTP tstat = signal (SIGTSTP, SIG_IGN);#endif SIGTSTP }#ifdef BPOP if (pmsh = pmsh1 && pmsh2) { cp = getenv ("MHPOPDEBUG");#ifdef NNTP if (pop_set (pmsh1, pmsh2, cp && *cp, myname) == NOTOK)#else NNTP if (pop_set (pmsh1, pmsh2, cp && *cp) == NOTOK)#endif NNTP padios (NULLCP, "%s", response); if (folder) file = folder, folder = NULL; }#endif BPOP if (folder) fsetup (folder); else setup (file); readids (id); display_info (id > 0 ? scansw : 0); msh (id > 0 ? scansw : 0); m_reset (); done (0);}/* */static struct swit mshcmds[] = {#define ADVCMD 0 "advance", -7,#define ALICMD 1 "ali", 0,#define EXPLCMD 2 "burst", 0,#define COMPCMD 3 "comp", 0,#define DISTCMD 4 "dist", 0,#define EXITCMD 5 "exit", 0,#define FOLDCMD 6 "folder", 0,#define FORWCMD 7 "forw", 0,#define HELPCMD 8 "help", 0,#define INCMD 9 "inc", 0,#define MARKCMD 10 "mark", 0,#define MAILCMD 11 "mhmail", 0,#define MSGKCMD 12 "msgchk", 0,#define NEXTCMD 13 "next", 0,#define PACKCMD 14 "packf", 0,#define PICKCMD 15 "pick", 0,#define PREVCMD 16 "prev", 0,#define QUITCMD 17 "quit", 0,#define FILECMD 18 "refile", 0,#define REPLCMD 19 "repl", 0,#define RMMCMD 20 "rmm", 0,#define SCANCMD 21 "scan", 0,#define SENDCMD 22 "send", 0,#define SHOWCMD 23 "show", 0,#define SORTCMD 24 "sortm", 0,#define WHATCMD 25 "whatnow", 0,#define WHOMCMD 26 "whom", 0, NULL, NULL};/* */static msh (scansw)int scansw;{ int i; register char *cp, **ap; char prompt[BUFSIZ], *vec[MAXARGS]; struct Cmd typein; register struct Cmd *cmdp; static int once_only = ADVCMD; (void) sprintf (prompt, myprompt, invo_name); cmdp = &typein; for (;;) { if (yp) { (void) fclose (yp); yp = NULL; } if (vmh) { if ((i = getcmds (mshcmds, cmdp, scansw)) == EOF) { (void) rcdone (); return; } } else { (void) check_folder (scansw); if ((i = getargs (prompt, mshcmds, cmdp)) == EOF) { (void) putchar ('\n'); return; } } cmd_name = mshcmds[i].sw; switch (i) { case QUITCMD: quit (); return; case ADVCMD: if (once_only == ADVCMD) once_only = i = SHOWCMD; else i = mp -> curmsg != mp -> hghmsg ? NEXTCMD : EXITCMD; cmd_name = mshcmds[i].sw; /* and fall... */ case EXITCMD: case EXPLCMD: case FOLDCMD: case FORWCMD: /* sigh */ case MARKCMD: case NEXTCMD: case PACKCMD: case PICKCMD: case PREVCMD: case RMMCMD: case SHOWCMD: case SCANCMD: case SORTCMD: if ((cp = m_find (cmd_name)) != NULL) { ap = brkstring (cp = getcpy (cp), " ", "\n"); ap = copyip (ap, vec); } else ap = vec; break; default: cp = NULL; ap = vec; break; } (void) copyip (cmdp -> args + 1, ap); m_init (); if (!vmh && init_io (cmdp, vmh) == NOTOK) { if (cp != NULL) free (cp); continue; } modified = 0; redirected = vmh || cmdp -> direction != STDIO; switch (i) { case ALICMD: case COMPCMD: case INCMD: case MAILCMD: case MSGKCMD: case SENDCMD: case WHATCMD: case WHOMCMD: if (!vmh || ttyN (cmdp) != NOTOK) forkcmd (vec, cmd_name); break; case DISTCMD: if (!vmh || ttyN (cmdp) != NOTOK) distcmd (vec); break; case EXPLCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) explcmd (vec); break; case FILECMD: if (!vmh || (filehak (vec) == OK ? ttyN (cmdp) : winN (cmdp, DISPLAY, 1)) != NOTOK) filecmd (vec); break; case FOLDCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) foldcmd (vec); break; case FORWCMD: if (!vmh || ttyN (cmdp) != NOTOK) forwcmd (vec); break; case HELPCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) helpcmd (vec); break; case EXITCMD: case MARKCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) markcmd (vec); break; case NEXTCMD: case PREVCMD: case SHOWCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) showcmd (vec); break; case PACKCMD: if (!vmh || (packhak (vec) == OK ? ttyN (cmdp) : winN (cmdp, DISPLAY, 1)) != NOTOK) packcmd (vec); break; case PICKCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) pickcmd (vec); break; case REPLCMD: if (!vmh || ttyN (cmdp) != NOTOK) replcmd (vec); break; case RMMCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) rmmcmd (vec); break; case SCANCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) scancmd (vec); break; case SORTCMD: if (!vmh || winN (cmdp, DISPLAY, 1) != NOTOK) sortcmd (vec); break; default: padios (NULLCP, "no dispatch for %s", cmd_name); } if (vmh) { if (vmhtty != NOTOK) (void) ttyR (cmdp); if (vmhpid > OK) (void) winR (cmdp); } else fin_io (cmdp, vmh); if (cp != NULL) free (cp); if (i == EXITCMD) { quit (); return; } }}/* */fsetup (folder)char *folder;{ register int msgnum; char *maildir; struct stat st; maildir = m_maildir (folder); if (chdir (maildir) == NOTOK) padios (maildir, "unable to change directory to"); if (!(mp = m_gmsg (folder))) padios (NULLCP, "unable to read folder %s", folder);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?