📄 msh.c
字号:
/* msh.c - The MH shell (sigh) */#ifndef lintstatic char ident[] = "@(#)$Id: msh.c,v 2.13 1992/12/15 00:20:22 jromine 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"#ifdef LOCALE#include <locale.h>#endif#ifdef MIME#define MIMEminc(a) (a)#else#define MIMEminc(a) 0#endif#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, 0};/* */ /* 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 TYPESIG alrmser ();#ifdef BPOP /* POP */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 /* SIGTSTP */int 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 /* BSD42 */static TYPESIG intrser (), pipeser (), quitser ();#ifndef __STDC__#ifdef SYS5struct passwd *getpwnam ();#endif /* SYS5 */#endifstatic 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];#ifdef LOCALE setlocale(LC_ALL, "");#endif 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 MHNCMD 12 "mhn", MIMEminc(-3),#define MSGKCMD 13 "msgchk", 0,#define NEXTCMD 14 "next", 0,#define PACKCMD 15 "packf", 0,#define PICKCMD 16 "pick", 0,#define PREVCMD 17 "prev", 0,#define QUITCMD 18 "quit", 0,#define FILECMD 19 "refile", 0,#define REPLCMD 20 "repl", 0,#define RMMCMD 21 "rmm", 0,#define SCANCMD 22 "scan", 0,#define SENDCMD 23 "send", 0,#define SHOWCMD 24 "show", 0,#define SORTCMD 25 "sortm", 0,#define WHATCMD 26 "whatnow", 0,#define WHOMCMD 27 "whom", 0, NULL, 0};/* */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 MHNCMD:#ifdef MIME if (!vmh || ttyN (cmdp) != NOTOK) mhncmd (vec);#endif 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; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -