📄 mshcmds.c
字号:
} headersw = 0; } if (clearsw) clear_screen ();}/* */static struct swit showswit[] = {#define SHDRAFT 0 "draft", 5,#define SHFORM 1 "form formfile", 4,#define SHPROG 2 "moreproc program", 4,#define SHNPROG 3 "nomoreproc", 3,#define SHLEN 4 "length lines", 4,#define SHWID 5 "width columns", 4,#define SHSHOW 6 "showproc program", 4,#define SHNSHOW 7 "noshowproc", 3,#define SHHEAD 8 "header", 4,#define SHNHEAD 9 "noheader", 3,#define SHHELP 10 "help", 4, NULL, NULL};/* */showcmd (args)char **args;{ int headersw = 1, nshow = 0, msgp = 0, vecp = 1, mhl = 0, seen = 0, mode = 0, i, msgnum; char *cp, *proc = showproc, buf[BUFSIZ], *msgs[MAXARGS], *vec[MAXARGS]; if (uleq (cmd_name, "next")) mode = 1; else if (uleq (cmd_name, "prev")) mode = -1; while (cp = *args++) { if (*cp == '-') switch (i = smatch (++cp, showswit)) { case AMBIGSW: ambigsw (cp, showswit); return; case UNKWNSW: case SHNPROG: vec[vecp++] = --cp; continue; case SHHELP: (void) sprintf (buf, "%s %s[switches] [switches for showproc]", cmd_name, mode ? NULL : "[msgs] "); help (buf, showswit); return; case SHFORM: case SHPROG: case SHLEN: case SHWID: vec[vecp++] = --cp; if (!(cp = *args++) || *cp == '-') { advise (NULLCP, "missing argument to %s", args[-2]); return; } vec[vecp++] = cp; continue; case SHHEAD: headersw++; continue; case SHNHEAD: headersw = 0; continue; case SHSHOW: if (!(proc = *args++) || *proc == '-') { advise (NULLCP, "missing argument to %s", args[-2]); return; } nshow = 0; continue; case SHNSHOW: nshow++; continue; case SHDRAFT: advise (NULLCP, "sorry, -%s not allowed!", showswit[i].sw); return; } if (*cp == '+' || *cp == '@') { advise (NULLCP, "sorry, no folders allowed!"); return; } else if (mode) { fprintf (stderr, "usage: %s [switches] [switches for showproc]\n", cmd_name); return; } else msgs[msgp++] = cp; } vec[vecp] = NULL; if (!msgp) msgs[msgp++] = mode > 0 ? "next" : mode < 0 ? "prev" : "cur"; for (msgnum = 0; msgnum < msgp; msgnum++) if (!m_convert (mp, msgs[msgnum])) return; m_setseq (mp); if (nshow) proc = "cat"; else if (strcmp (showproc, "mhl") == 0) { proc = mhlproc; mhl++; } seen = m_seqflag (mp, "unseen"); vec[0] = r1bindex (proc, '/'); if (mhl) { msgp = vecp; for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) if (mp -> msgstats[msgnum] & SELECTED) { vec[vecp++] = getcpy (m_name (msgnum)); if (seen) (void) m_seqdel (mp, "unseen", msgnum); } vec[vecp] = NULL; if (mp -> numsel == 1 && headersw) show (mp -> lowsel); (void) mhlsbr (vecp, vec, mhl_action); m_eomsbr ((int (*)()) 0); while (msgp < vecp) free (vec[msgp++]); } else { interrupted = 0; for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel && !interrupted; msgnum++) if (mp -> msgstats[msgnum] & SELECTED) { switch (ask (msgnum)) { case NOTOK: /* QUIT */ break; case OK: /* INTR */ continue; default: if (mp -> numsel == 1 && headersw) show (msgnum); if (nshow) copy_message (msgnum, stdout); else (void) process (msgnum, proc, vecp, vec); if (seen) (void) m_seqdel (mp, "unseen", msgnum); continue; } break; } } m_setcur (mp, mp -> hghsel);}/* */static show (msgnum)int msgnum;{ if (Msgs[msgnum].m_bboard_id == 0) (void) readid (msgnum); printf ("(Message %d", msgnum); if (Msgs[msgnum].m_bboard_id > 0) printf (", %s: %d", BBoard_ID, Msgs[msgnum].m_bboard_id); printf (")\n");}/* ARGSUSED */static int eom_action (c)int c;{ return (ftell (mhlfp) >= Msgs[mhlnum].m_stop);}static FP mhl_action (name)char *name;{ int msgnum; if ((msgnum = m_atoi (name)) < mp -> lowmsg || msgnum > mp -> hghmsg || !(mp -> msgstats[msgnum] & EXISTS)) return NULL; mhlnum = msgnum; mhlfp = msh_ready (msgnum, 1); if (!fmsh) m_eomsbr (eom_action); return mhlfp;}/* */static ask (msgnum)int msgnum;{ char buf[BUFSIZ]; if (mp -> numsel == 1 || !interactive || redirected) return DONE; if (SOprintf ("Press <return> to list \"%d\"...", msgnum)) { if (mp -> lowsel != msgnum) printf ("\n\n\n"); printf ("Press <return> to list \"%d\"...", msgnum); } (void) fflush (stdout); buf[0] = NULL;#ifndef BSD42 (void) read (fileno (stdout), buf, sizeof buf);#else BSD42 switch (setjmp (sigenv)) { case OK: should_intr = 1; (void) read (fileno (stdout), buf, sizeof buf);/* fall... */ default: should_intr = 0; break; }#endif BSD42 if (index (buf, '\n') == NULL) (void) putchar ('\n'); if (told_to_quit) { told_to_quit = interrupted = 0; return NOTOK; } if (interrupted) { interrupted = 0; return OK; } return DONE;}/* */static struct swit sortswit[] = {#define SODATE 0 "datefield field", 0,#define SOSUBJ 1 "textfield field", 0,#define SONSUBJ 2 "notextfield", 0,#define SOLIMT 3 "limit days", 0,#define SONLIMT 4 "nolimit", 0,#define SOVERB 5 "verbose", 0,#define SONVERB 6 "noverbose", 0,#define SOHELP 7 "help", 4, NULL, NULL};/* */sortcmd (args)char **args;{ int msgp = 0, msgnum; char *cp, *datesw = NULL, *subjsw = NULL, buf[BUFSIZ], *msgs[MAXARGS]; struct tws tb, *tw; if (fmsh) { forkcmd (args, cmd_name); return; } while (cp = *args++) { if (*cp == '-') switch (smatch (++cp, sortswit)) { case AMBIGSW: ambigsw (cp, sortswit); return; case UNKWNSW: fprintf (stderr, "-%s unknown\n", cp); return; case SOHELP: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); help (buf, sortswit); return; case SODATE: if (datesw) { advise (NULLCP, "only one date field at a time!"); return; } if (!(datesw = *args++) || *datesw == '-') { advise (NULLCP, "missing argument to %s", args[-2]); return; } continue; case SOSUBJ: if (subjsw) { advise (NULLCP, "only one text field at a time!"); return; } if (!(subjsw = *args++) || *subjsw == '-') { advise (NULLCP, "missing argument to %s", args[-2]); return; } continue; case SONSUBJ: subjsw = (char *)0; continue; case SOLIMT: /* too hard */ if (!(cp = *args++) || *cp == '-') { advise (NULLCP, "missing argument to %s", args[-2]); return; } case SONLIMT: case SOVERB: /* not implemented */ case SONVERB: continue; } if (*cp == '+' || *cp == '@') { advise (NULLCP, "sorry, no folders allowed!"); return; } else msgs[msgp++] = cp; } if (!msgp) msgs[msgp++] = "all"; if (!datesw) datesw = "Date"; for (msgnum = 0; msgnum < msgp; msgnum++) if (!m_convert (mp, msgs[msgnum])) return; m_setseq (mp); twscopy (&tb, dtwstime ()); for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) { if (Msgs[msgnum].m_scanl) { free (Msgs[msgnum].m_scanl); Msgs[msgnum].m_scanl = NULL; } if (mp -> msgstats[msgnum] & SELECTED) { if (getws (datesw, subjsw, msgnum, &Msgs[msgnum])) twscopy (&Msgs[msgnum].m_tb, msgnum != mp -> lowsel ? &Msgs[msgnum - 1].m_tb : &tb); } else /* m_scaln is already NULL */ twscopy (&Msgs[msgnum].m_tb, &tb); Msgs[msgnum].m_stats = mp -> msgstats[msgnum]; if (mp -> curmsg == msgnum) Msgs[msgnum].m_stats |= CUR; } qsort ((char *) &Msgs[mp -> lowsel], mp -> hghsel - mp -> lowsel + 1, sizeof (struct Msg), subjsw ? subsort : msgsort); for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) { if (subjsw && Msgs[msgnum].m_scanl) { free (Msgs[msgnum].m_scanl); /* from subjsort */ Msgs[msgnum].m_scanl = NULL; } mp -> msgstats[msgnum] = Msgs[msgnum].m_stats & ~CUR; if (Msgs[msgnum].m_stats & CUR) m_setcur (mp, msgnum); } mp -> msgflags |= MODIFIED; modified++;}/* *//* * getws - parse message, and get date and subject if needed. We'll use * the msgp->m_tb tws struct for the date, and overload the msgp->m_scanl * field with our subject string. */static int getws (datesw, subjsw, msgnum, msgp)char *datesw, *subjsw;int msgnum;struct Msg *msgp;{ int state, gotdate = 0; char *bp, buf[BUFSIZ], name[NAMESZ]; struct tws *tw = (struct tws *)0; register FILE *zp; zp = msh_ready (msgnum, 0); for (state = FLD;;) { switch (state = m_getfld (state, name, buf, sizeof buf, zp)) { case FLD: case FLDEOF: case FLDPLUS: if (uleq (name, datesw)) { bp = getcpy (buf); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, zp); bp = add (buf, bp); } if ((tw = dparsetime (bp)) == NULL) admonish (NULLCP, "unable to parse %s field in message %d", datesw, msgnum); else twscopy (&(msgp->m_tb), tw); free (bp); if (!subjsw) /* not using this, or already done */ break; /* all done! */ gotdate++; } else if (subjsw && uleq(name, subjsw)) { bp = getcpy (buf); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, zp); bp = add (buf, bp); } msgp->m_scanl = sosmash(subjsw, bp); if (gotdate) break; /* date done so we're done */ else subjsw = (char *)0;/* subject done, need date */ } else { while (state == FLDPLUS) /* flush this one */ state = m_getfld (state, name, buf, sizeof buf, zp); } continue; case BODY: case BODYEOF: case FILEEOF: break; case LENERR: case FMTERR: admonish (NULLCP, "format error in message %d", msgnum); if (msgp->m_scanl) { /* this might need free'd */ free (msgp->m_scanl); /* probably can't use subj anyway */ msgp->m_scanl = NULL; } return NOTOK; default: adios (NULLCP, "internal error -- you lose"); } break; } if (tw) return OK; /* not an error if subj not found */ admonish (NULLCP, "no %s field in message %d", datesw, msgnum); return NOTOK; /* NOTOK means use some other date */}/* sort routines */static int msgsort (a, b)struct Msg *a, *b;{ return twsort (&a -> m_tb, &b -> m_tb);}static int subsort (a, b)struct Msg *a, *b;{ register int i; if (a->m_scanl && b->m_scanl) if (i = strcmp (a->m_scanl, b->m_scanl)) return (i); return twsort (&a -> m_tb, &b -> m_tb);}/* * try to make the subject "canonical": delete leading "re:", everything * but letters & smash letters to lower case. */static char *sosmash (subj, s)char *subj;register char *s;{ register char *cp, *dp, c; if (s) { cp = s; dp = s; /* dst pointer */ if (uleq (subj, "subject")) while (c = *cp++) { if (! isspace(c)) { if ((c == 'R' || c == 'r') && (cp[0] == 'e' || cp[0] == 'E') && cp[1] == ':') cp += 2; else { if (isalnum(c)) *dp++ = isupper(c) ? tolower(c) : c; break; } } } while (c = *cp++) { if (isalnum(c)) *dp++ = isupper(c) ? tolower(c) : c; } *dp = '\0'; } return s;}/* */static int process (msgnum, proc, vecp, vec)int msgnum, vecp;char *proc, **vec;{ int child_id, status; char tmpfil[80]; FILE *out; if (fmsh) { (void) strcpy (tmpfil, m_name (msgnum)); (void) m_delete (pfolder); m_replace (pfolder, fmsh); m_sync (mp); m_update (); goto ready; } (void) strcpy (tmpfil, m_scratch ("", invo_name)); if ((out = fopen (tmpfil, "w")) == NULL) { int olderr; extern int errno; char newfil[80]; olderr = errno; (void) strcpy (newfil, m_tmpfil (invo_name)); if ((out = fopen (newfil, "w")) == NULL) { errno = olderr; advise (tmpfil, "unable to create temporary file"); return NOTOK; } else (void) strcpy (tmpfil, newfil); } copy_message (msgnum, out); (void) fclose (out);ready: ; (void) fflush (stdout); switch (child_id = fork ()) { case NOTOK: advise ("fork", "unable to"); status = NOTOK; break; case OK: closefds (3); (void) signal (SIGINT, istat); (void) signal (SIGQUIT, qstat); vec[vecp++] = tmpfil; vec[vecp] = NULL; execvp (proc, vec); fprintf (stderr, "unable to exec "); perror (proc); _exit (1); default: status = pidXwait (child_id, NULLCP); break; } if (!fmsh) (void) unlink (tmpfil); return status;}/* */static copy_message (msgnum, out)int msgnum;FILE * out;{ long pos; static char buffer[BUFSIZ]; register FILE * zp; zp = msh_ready (msgnum, 1); if (fmsh) { while (fgets (buffer, sizeof buffer, zp) != NULL) { fputs (buffer, out); if (interrupted && out == stdout) break; } } else { pos = ftell (zp); while (fgets (buffer, sizeof buffer, zp) != NULL && pos < Msgs[msgnum].m_stop) { fputs (buffer, out); pos += (long) strlen (buffer); if (interrupted && out == stdout) break; } }}static copy_digest (msgnum, out)int msgnum;FILE * out;{ char c; long pos; static char buffer[BUFSIZ]; register FILE *zp; c = '\n'; zp = msh_ready (msgnum, 1); if (!fmsh) pos = ftell (zp); while (fgets (buffer, sizeof buffer, zp) != NULL && !fmsh && pos < Msgs[msgnum].m_stop) { if (c == '\n' && *buffer == '-') (void) fputc (' ', out); fputs (buffer, out); c = buffer[strlen (buffer) - 1]; if (!fmsh) pos += (long) strlen (buffer); if (interrupted && out == stdout) break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -