📄 mshcmds.c
字号:
/* mshcmds.c - command handlers in msh */#ifndef lintstatic char ident[] = "@(#)$Id: mshcmds.c,v 1.2 90/11/25 19:05:08 sharpe Exp $";#endif lint#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 <errno.h>#include <setjmp.h>#include <signal.h>#include "../h/mshsbr.h"#include <sys/types.h>#include <sys/stat.h>/* */extern int errno; /* BURST */static char delim3[] = "-------";/* from burst.c */ /* SHOW */static int mhlnum;static FILE *mhlfp;void clear_screen ();static int eom_action ();static FP mhl_action ();static burst(), forw(), rmm(), show(), ask(), copy_message(), copy_digest();static int process(); /* SORTM */static int msgsort (), subsort();static int getws ();static char *sosmash ();/* */forkcmd (args, pgm)char **args, *pgm;{ int child_id; char *vec[MAXARGS]; vec[0] = r1bindex (pgm, '/'); (void) copyip (args, vec + 1); if (fmsh) { (void) m_delete (pfolder); m_replace (pfolder, fmsh); m_sync (mp); m_update (); } (void) fflush (stdout); switch (child_id = fork ()) { case NOTOK: advise ("fork", "unable to"); return; case OK: closefds (3); (void) signal (SIGINT, istat); (void) signal (SIGQUIT, qstat); execvp (pgm, vec); fprintf (stderr, "unable to exec "); perror (cmd_name); _exit (1); default: (void) pidXwait (child_id, NULLCP); break; } if (fmsh) { /* assume the worst case */ mp -> msgflags |= MODIFIED; modified++; }}/* */static struct swit distswit[] = {#define DIANSW 0 "annotate", 0,#define DINANSW 1 "noannotate", 0,#define DIDFSW 2 "draftfolder +folder", 0,#define DIDMSW 3 "draftmessage msg", 0,#define DINDFSW 4 "nodraftfolder", 0,#define DIEDTSW 5 "editor editor", 0,#define DINEDSW 6 "noedit", 0,#define DIFRMSW 7 "form formfile", 0,#define DIINSW 8 "inplace", 0,#define DININSW 9 "noinplace", 0,#define DIWHTSW 10 "whatnowproc program", 0,#define DINWTSW 11 "nowhatnowproc", 0,#define DIHELP 12 "help", 4, NULL, NULL};/* */distcmd (args)char **args;{ int vecp = 1; char *cp, *msg = NULL, buf[BUFSIZ], *vec[MAXARGS]; if (fmsh) { forkcmd (args, cmd_name); return; } while (cp = *args++) { if (*cp == '-') switch (smatch (++cp, distswit)) { case AMBIGSW: ambigsw (cp, distswit); return; case UNKWNSW: fprintf (stderr, "-%s unknown\n", cp); return; case DIHELP: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); help (buf, distswit); return; case DIANSW: /* not implemented */ case DINANSW: case DIINSW: case DININSW: continue; case DINDFSW: case DINEDSW: case DINWTSW: vec[vecp++] = --cp; continue; case DIEDTSW: case DIFRMSW: case DIDFSW: case DIDMSW: case DIWHTSW: vec[vecp++] = --cp; if (!(cp = *args++) || *cp == '-') { advise (NULLCP, "missing argument to %s", args[-2]); return; } vec[vecp++] = cp; continue; } if (*cp == '+' || *cp == '@') { advise (NULLCP, "sorry, no folders allowed!"); return; } else if (msg) { advise (NULLCP, "only one message at a time!"); return; } else msg = cp; } vec[0] = cmd_name; vec[vecp++] = "-file"; vec[vecp] = NULL; if (!msg) msg = "cur"; if (!m_convert (mp, msg)) return; m_setseq (mp); if (mp -> numsel > 1) { advise (NULLCP, "only one message at a time!"); return; } (void) process (mp -> hghsel, cmd_name, vecp, vec); m_setcur (mp, mp -> hghsel);}/* */static struct swit explswit[] = {#define EXINSW 0 "inplace", 0,#define EXNINSW 1 "noinplace", 0,#define EXQISW 2 "quiet", 0,#define EXNQISW 3 "noquiet", 0,#define EXVBSW 4 "verbose", 0,#define EXNVBSW 5 "noverbose", 0,#define EXHELP 6 "help", 4, NULL, NULL};/* */explcmd (args)char **args;{ int inplace = 0, quietsw = 0, verbosw = 0, msgp = 0, hi, msgnum; char *cp, buf[BUFSIZ], *msgs[MAXARGS]; struct Msg *smsgs; if (fmsh) { forkcmd (args, cmd_name); return; } while (cp = *args++) { if (*cp == '-') switch (smatch (++cp, explswit)) { case AMBIGSW: ambigsw (cp, explswit); return; case UNKWNSW: fprintf (stderr, "-%s unknown\n", cp); return; case EXHELP: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); help (buf, explswit); return; case EXINSW: inplace++; continue; case EXNINSW: inplace = 0; continue; case EXQISW: quietsw++; continue; case EXNQISW: quietsw = 0; continue; case EXVBSW: verbosw++; continue; case EXNVBSW: verbosw = 0; continue; } if (*cp == '+' || *cp == '@') { advise (NULLCP, "sorry, no folders allowed!"); return; } else msgs[msgp++] = cp; } if (!msgp) msgs[msgp++] = "cur"; for (msgnum = 0; msgnum < msgp; msgnum++) if (!m_convert (mp, msgs[msgnum])) return; m_setseq (mp); smsgs = (struct Msg *) calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs); if (smsgs == NULL) adios (NULLCP, "unable to allocate folder storage"); hi = mp -> hghmsg + 1; interrupted = 0; for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel && !interrupted; msgnum++) if (mp -> msgstats[msgnum] & SELECTED) if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK) break; free ((char *) smsgs); if (inplace) m_setcur (mp, mp -> lowsel); else if (hi <= mp -> hghmsg) m_setcur (mp, hi); mp -> msgflags |= MODIFIED; modified++;}/* */static burst (smsgs, msgnum, inplace, quietsw, verbosw)struct Msg *smsgs;int msgnum, inplace, quietsw, verbosw;{ int i, j, ld3, wasdlm, msgp; long pos; char c, buffer[BUFSIZ]; register FILE *zp; ld3 = strlen (delim3); if (Msgs[msgnum].m_scanl) { free (Msgs[msgnum].m_scanl); Msgs[msgnum].m_scanl = NULL; } pos = ftell (zp = msh_ready (msgnum, 1)); for (msgp = 1; msgp <= MAXFOLDER;) { while (fgets (buffer, sizeof buffer, zp) != NULL && buffer[0] == '\n' && pos < Msgs[msgnum].m_stop) pos += (long) strlen (buffer); if (feof (zp) || pos >= Msgs[msgnum].m_stop) break; (void) fseek (zp, pos, 0); smsgs[msgp].m_start = pos; for (c = NULL; fgets (buffer, sizeof buffer, zp) != NULL && pos < Msgs[msgnum].m_stop; c = buffer[0]) if (strncmp (buffer, delim3, ld3) == 0 && peekc (zp) == '\n' && (msgp == 1 || c == '\n')) break; else pos += (long) strlen (buffer); wasdlm = strncmp (buffer, delim3, ld3) == 0; if (smsgs[msgp].m_start != pos) smsgs[msgp++].m_stop = c == '\n' && wasdlm ? pos - 1 : pos; if (feof (zp) || pos >= Msgs[msgnum].m_stop) { if (wasdlm) { smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1); msgp++; /* fake "End of XXX Digest" */ } break; } pos += (long) strlen (buffer); } switch (--msgp) { /* toss "End of XXX Digest" */ case 0: adios (NULLCP, "burst() botch -- you lose big"); case 1: if (!quietsw) printf ("message %d not in digest format\n", msgnum); return OK; default: if (verbosw) printf ("%d message%s exploded from digest %d\n", msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum); if (msgp == 2) msgp++; break; } msgp--; if ((i = msgp + mp -> hghmsg) > MAXFOLDER) { advise (NULLCP, "more than %d messages", MAXFOLDER); return NOTOK; } if ((mp = m_remsg (mp, 0, i)) == NULL) adios (NULLCP, "unable to allocate folder storage"); j = mp -> hghmsg; mp -> hghmsg += msgp - 1; mp -> nummsg += msgp - 1; if (mp -> hghsel > msgnum) mp -> hghsel += msgp - 1; if (inplace && msgp > 1) for (i = mp -> hghmsg; j > msgnum; i--, j--) { if (verbosw) printf ("message %d becomes message %d\n", j, i); Msgs[i].m_bboard_id = Msgs[j].m_bboard_id; Msgs[i].m_top = Msgs[j].m_top; Msgs[i].m_start = Msgs[j].m_start; Msgs[i].m_stop = Msgs[j].m_stop; Msgs[i].m_scanl = NULL; if (Msgs[j].m_scanl) { free (Msgs[j].m_scanl); Msgs[j].m_scanl = NULL; } mp -> msgstats[i] = mp -> msgstats[j]; } if (Msgs[msgnum].m_bboard_id == 0) (void) readid (msgnum); mp -> msgstats[msgnum] &= ~SELECTED; i = inplace ? msgnum + msgp - 1 : mp -> hghmsg; for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) { if (verbosw && i != msgnum) printf ("message %d of digest %d becomes message %d\n", j, msgnum, i); Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id; Msgs[i].m_top = Msgs[j].m_top; Msgs[i].m_start = smsgs[j].m_start; Msgs[i].m_stop = smsgs[j].m_stop; Msgs[i].m_scanl = NULL; mp -> msgstats[i] = mp -> msgstats[msgnum]; } return OK;}/* */static struct swit fileswit[] = {#define FIDRFT 0 "draft", 0,#define FILINK 1 "link", 0,#define FINLINK 2 "nolink", 0,#define FIPRES 3 "preserve", 0,#define FINPRES 4 "nopreserve", 0,#define FISRC 5 "src +folder", 0,#define FIFILE 6 "file file", 0,#define FIHELP 7 "help", 4, NULL, NULL};/* */filecmd (args)char **args;{ int linksw = 0, msgp = 0, vecp = 1, i, msgnum; char *cp, buf[BUFSIZ], *msgs[MAXARGS], *vec[MAXARGS]; if (fmsh) { forkcmd (args, cmd_name); return; } while (cp = *args++) { if (*cp == '-') switch (i = smatch (++cp, fileswit)) { case AMBIGSW: ambigsw (cp, fileswit); return; case UNKWNSW: fprintf (stderr, "-%s unknown\n", cp); return; case FIHELP: (void) sprintf (buf, "%s +folder... [msgs] [switches]", cmd_name); help (buf, fileswit); return; case FILINK: linksw++; continue; case FINLINK: linksw = 0; continue; case FIPRES: case FINPRES: continue; case FISRC: case FIDRFT: case FIFILE: advise (NULLCP, "sorry, -%s not allowed!", fileswit[i].sw); return; } if (*cp == '+' || *cp == '@') vec[vecp++] = cp; else msgs[msgp++] = cp; } vec[0] = cmd_name; vec[vecp++] = "-file"; vec[vecp] = NULL; if (!msgp) msgs[msgp++] = "cur"; for (msgnum = 0; msgnum < msgp; msgnum++) if (!m_convert (mp, msgs[msgnum])) return; m_setseq (mp); interrupted = 0; for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel && !interrupted; msgnum++) if (mp -> msgstats[msgnum] & SELECTED) if (process (msgnum, fileproc, vecp, vec)) { mp -> msgstats[msgnum] &= ~SELECTED; mp -> numsel--; } if (mp -> numsel != mp -> nummsg || linksw) m_setcur (mp, mp -> hghsel); if (!linksw) rmm ();}/* */int filehak (args)char **args;{ int result, vecp = 0; char *cp, *cwd, *vec[MAXARGS]; while (cp = *args++) { if (*cp == '-') switch (smatch (++cp, fileswit)) { case AMBIGSW: case UNKWNSW: case FIHELP: return NOTOK; case FILINK: case FINLINK: case FIPRES: case FINPRES: continue; case FISRC: case FIDRFT: case FIFILE: return NOTOK; } if (*cp == '+' || *cp == '@') vec[vecp++] = cp; } vec[vecp] = NULL; result = NOTOK; cwd = NULL; for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) { if (cwd == NULL) cwd = getcpy (pwd ()); (void) chdir (m_maildir ("")); cp = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); if (access (m_maildir (cp), 0) == NOTOK) result = OK; free (cp); } if (cwd) (void) chdir (cwd); return result;}/* */static struct swit foldswit[] = {#define FLALSW 0 "all", 0,#define FLFASW 1 "fast", 0,#define FLNFASW 2 "nofast", 0,#define FLHDSW 3 "header", 0,#define FLNHDSW 4 "noheader", 0,#define FLPKSW 5 "pack", 0,#define FLNPKSW 6 "nopack", 0,#define FLRCSW 7 "recurse", 0,#define FLNRCSW 8 "norecurse", 0,#define FLTLSW 9 "total", 0,#define FLNTLSW 10 "nototal", 0,#define FLPRSW 11 "print", 0,#define FLPUSW 12 "push", 0,#define FLPOSW 13 "pop", 0,#define FLLISW 14 "list", 0,#define FLHELP 15 "help", 4, NULL, NULL};/* */foldcmd (args)char **args;{ int fastsw = 0, headersw = 0, packsw = 0, hole, msgnum; char *cp, *folder = NULL, *msg = NULL, buf[BUFSIZ], **vec = args; if (args == NULL) goto fast; while (cp = *args++) { if (*cp == '-') switch (smatch (++cp, foldswit)) { case AMBIGSW: ambigsw (cp, foldswit); return; case UNKWNSW: fprintf (stderr, "-%s unknown\n", cp); return; case FLHELP: (void) sprintf (buf, "%s [+folder] [msg] [switches]", cmd_name); help (buf, foldswit); return; case FLALSW: /* not implemented */ case FLRCSW: case FLNRCSW: case FLTLSW: case FLNTLSW: case FLPRSW: case FLPUSW: case FLPOSW: case FLLISW: continue; case FLFASW: fastsw++; continue; case FLNFASW: fastsw = 0; continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -