📄 msh.c
字号:
(void) readid (msgnum); if ((i = Msgs[msgnum].m_bboard_id) > 0) break; } (void) sprintf (buffer, "%d %d\n", i, Msgs[mp -> hghmsg].m_bboard_id); (void) write (pfd, buffer, sizeof buffer); (void) close (pfd); pfd = NOTOK;}/* */static quit () { int i, md, msgnum; char *cp, tmpfil[BUFSIZ], map1[BUFSIZ], map2[BUFSIZ]; struct stat st; FILE *dp; if (!(mp -> msgflags & MODIFIED) || mp -> msgflags & READONLY || fmsh) { if (vmh) (void) rc2peer (RC_FIN, 0, NULLCP); return; } if (vmh) (void) ttyNaux (NULLCMD, "FAST"); cp = NULL; if ((dp = lkfopen (mp -> foldpath, "r")) == NULL) { advise (mp -> foldpath, "unable to lock"); if (vmh) { (void) ttyR (NULLCMD); (void) pFIN (); } return; } if (fstat (fileno (dp), &st) == NOTOK) { advise (mp -> foldpath, "unable to stat"); goto release; } if (mtime != st.st_mtime) { advise (NULLCP, "new messages have arrived, no update"); goto release; } mode = (int) (st.st_mode & 0777); if (mp -> nummsg == 0) { cp = concat ("Zero file \"", mp -> foldpath, "\"? ", NULLCP); if (getanswer (cp)) { if ((i = creat (mp -> foldpath, mode)) != NOTOK) (void) close (i); else advise (mp -> foldpath, "error zero'ing"); (void) unlink (map_name (mp -> foldpath));/* XXX */ } goto release; } cp = concat ("Update file \"", mp -> foldpath, "\"? ", NULLCP); if (!getanswer (cp)) goto release; (void) strcpy (tmpfil, m_backup (mp -> foldpath)); if ((md = mbx_open (tmpfil, st.st_uid, st.st_gid, mode)) == NOTOK) { advise (tmpfil, "unable to open"); goto release; } for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++) if (mp -> msgstats[msgnum] & EXISTS && pack (tmpfil, md, msgnum) == NOTOK) { (void) mbx_close (tmpfil, md); (void) unlink (tmpfil); (void) unlink (map_name (tmpfil)); goto release; } (void) mbx_close (tmpfil, md); if (rename (tmpfil, mp -> foldpath) == NOTOK) admonish (mp -> foldpath, "unable to rename %s to", tmpfil); else { (void) strcpy (map1, map_name (tmpfil)); (void) strcpy (map2, map_name (mp -> foldpath)); if (rename (map1, map2) == NOTOK) { admonish (map2, "unable to rename %s to", map1); (void) unlink (map1); (void) unlink (map2); } }release: ; if (cp) free (cp); (void) lkfclose (dp, mp -> foldpath); if (vmh) { (void) ttyR (NULLCMD); (void) pFIN (); }}/* */static int getargs (prompt, sw, cmdp)char *prompt;struct swit *sw;struct Cmd *cmdp;{ int i; char *cp; static char buffer[BUFSIZ]; told_to_quit = 0; for (;;) { interrupted = 0;#ifdef BSD42 switch (setjmp (sigenv)) { case OK: should_intr = 1; break; default: should_intr = 0; if (interrupted && !told_to_quit) { (void) putchar ('\n'); continue; } if (ppid > 0) (void) kill (ppid, SIGEMT); return EOF; }#endif /* BSD42 */ if (interactive) { printf ("%s", prompt); (void) fflush (stdout); } for (cp = buffer; (i = getchar ()) != '\n';) {#ifndef BSD42 if (interrupted && !told_to_quit) { buffer[0] = NULL; (void) putchar ('\n'); break; } if (told_to_quit || i == EOF) { if (ppid > 0) (void) kill (ppid, SIGEMT); return EOF; }#else /* BSD42 */ if (i == EOF) longjmp (sigenv, DONE);#endif /* BSD42 */ if (cp < &buffer[sizeof buffer - 2]) *cp++ = i; } *cp = 0; if (buffer[0] == 0) continue; if (buffer[0] == '?') { printf ("commands:\n"); printsw (ALL, sw, ""); printf ("type CTRL-D or use ``quit'' to leave %s\n", invo_name); continue; } if (parse (buffer, cmdp) == NOTOK) continue; switch (i = smatch (cmdp -> args[0], sw)) { case AMBIGSW: ambigsw (cmdp -> args[0], sw); continue; case UNKWNSW: printf ("say what: ``%s'' -- type ? (or help) for help\n", cmdp -> args[0]); continue; default: #ifdef BSD42 should_intr = 0;#endif /* BSD42 */ return i; } }}/* */static int getcmds (sw, cmdp, scansw)struct swit *sw;struct Cmd *cmdp;int scansw;{ int i; struct record rcs, *rc = &rcs; initrc (rc); for (;;) switch (peer2rc (rc)) { case RC_QRY: (void) pQRY (rc -> rc_data, scansw); break; case RC_CMD: if ((i = pCMD (rc -> rc_data, sw, cmdp)) != NOTOK) return i; break; case RC_FIN: if (ppid > 0) (void) kill (ppid, SIGEMT); return EOF; case RC_XXX: padios (NULLCP, "%s", rc -> rc_data); default: (void) fmt2peer (RC_ERR, "pLOOP protocol screw-up"); done (1); }}/* */static int parse (buffer, cmdp)char *buffer;struct Cmd *cmdp;{ int argp = 0; char c, *cp, *pp; cmdp -> line[0] = 0; pp = cmdp -> args[argp++] = cmdp -> line; cmdp -> redirect = NULL; cmdp -> direction = STDIO; cmdp -> stream = NULL; for (cp = buffer; c = *cp; cp++) if (!isspace (c)) break; if (c == 0) { if (vmh) (void) fmt2peer (RC_EOF, "null command"); return NOTOK; } while (c = *cp++) { if (isspace (c)) { while (isspace (c)) c = *cp++; if (c == 0) break; *pp++ = 0; cmdp -> args[argp++] = pp; *pp = 0; } switch (c) { case '"': for (;;) { switch (c = *cp++) { case 0: padvise (NULLCP, "unmatched \""); return NOTOK; case '"': break; case QUOTE: if ((c = *cp++) == 0) goto no_quoting; default: *pp++ = c; continue; } break; } continue; case QUOTE: if ((c = *cp++) == 0) { no_quoting: ; padvise (NULLCP, "the newline character can not be quoted"); return NOTOK; } default: ; *pp++ = c; continue; case '>': case '|': if (pp == cmdp -> line) { padvise (NULLCP, "invalid null command"); return NOTOK; } if (*cmdp -> args[argp - 1] == 0) argp--; cmdp -> direction = c == '>' ? CRTIO : PIPIO; if (cmdp -> direction == CRTIO && (c = *cp) == '>') { cmdp -> direction = APPIO; cp++; } cmdp -> redirect = pp + 1;/* sigh */ for (; c = *cp; cp++) if (!isspace (c)) break; if (c == 0) { padvise (NULLCP, cmdp -> direction != PIPIO ? "missing name for redirect" : "invalid null command"); return NOTOK; } (void) strcpy (cmdp -> redirect, cp); if (cmdp -> direction != PIPIO) { for (; *cp; cp++) if (isspace (*cp)) { padvise (NULLCP, "bad name for redirect"); return NOTOK; } if (expand (cmdp -> redirect) == NOTOK) return NOTOK; } break; } break; } *pp++ = 0; cmdp -> args[argp] = NULL; return OK;}/* */int expand (redirect)char *redirect;{ char *cp, *pp; char path[BUFSIZ]; struct passwd *pw; if (*redirect != '~') return OK; if (cp = index (pp = redirect + 1, '/')) *cp++ = 0; if (*pp == 0) pp = mypath; else if (pw = getpwnam (pp)) pp = pw -> pw_dir; else { padvise (NULLCP, "unknown user: %s", pp); return NOTOK; } (void) sprintf (path, "%s/%s", pp, cp ? cp : ""); (void) strcpy (redirect, path); return OK;}/* */static int init_io (cmdp, vio)register struct Cmd *cmdp;int vio;{ int io, result; io = vmh; vmh = vio; result = initaux_io (cmdp); vmh = io; return result;}static int initaux_io (cmdp)register struct Cmd *cmdp;{ char *mode; switch (cmdp -> direction) { case STDIO: return OK; case CRTIO: case APPIO: mode = cmdp -> direction == CRTIO ? "write" : "append"; if ((cmdp -> stream = fopen (cmdp -> redirect, mode)) == NULL) { padvise (cmdp -> redirect, "unable to %s ", mode); cmdp -> direction = STDIO; return NOTOK; } break; case PIPIO: if ((cmdp -> stream = popen (cmdp -> redirect, "w")) == NULL) { padvise (cmdp -> redirect, "unable to pipe"); cmdp -> direction = STDIO; return NOTOK; } (void) signal (SIGPIPE, pipeser); broken_pipe = 0; break; default: padios (NULLCP, "unknown redirection for command"); } (void) fflush (stdout); if (dup2 (fileno (cmdp -> stream), fileno (stdout)) == NOTOK) padios ("standard output", "unable to dup2"); clearerr (stdout); return OK;}/* */static fin_io (cmdp, vio)register struct Cmd *cmdp;int vio;{ int io; io = vmh; vmh = vio; finaux_io (cmdp); vmh = io;}static int finaux_io (cmdp)register struct Cmd *cmdp;{ switch (cmdp -> direction) { case STDIO: return; case CRTIO: case APPIO: (void) fflush (stdout); (void) close (fileno (stdout)); if (ferror (stdout)) padvise (NULLCP, "problems writing %s", cmdp -> redirect); (void) fclose (cmdp -> stream); break; case PIPIO: (void) fflush (stdout); (void) close (fileno (stdout)); (void) pclose (cmdp -> stream); (void) signal (SIGPIPE, SIG_DFL); break; default: padios (NULLCP, "unknown redirection for command"); } if (dup2 (fileno (sp), fileno (stdout)) == NOTOK) padios ("standard output", "unable to dup2"); clearerr (stdout); cmdp -> direction = STDIO;}/* */static m_init () { int msgnum; for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++) mp -> msgstats[msgnum] &= ~SELECTED; mp -> lowsel = mp -> hghsel = mp -> numsel = 0;}m_reset () { write_ids (); m_fmsg (mp); myname = NULL;#ifdef BPOP if (pmsh) { (void) pop_done (); pmsh = 0; }#endif /* BPOP */}/* */void m_setcur (mp, msgnum)register struct msgs *mp;register int msgnum;{ if (mp -> curmsg == msgnum) return; if (mp -> curmsg && Msgs[mp -> curmsg].m_scanl) { free (Msgs[mp -> curmsg].m_scanl); Msgs[mp -> curmsg].m_scanl = NULL; } if (Msgs[msgnum].m_scanl) { free (Msgs[msgnum].m_scanl); Msgs[msgnum].m_scanl = NULL; } mp -> curmsg = msgnum;}/* *//* ARGSUSED */static TYPESIG intrser (i)int i;{#ifndef BSD42 (void) signal (SIGINT, intrser);#endif /* not BSD42 */ discard (stdout); interrupted++;#ifdef BSD42 if (should_intr) longjmp (sigenv, NOTOK);#endif /* BSD42 */}/* ARGSUSED */static TYPESIG pipeser (i)int i;{#ifndef BSD42 (void) signal (SIGPIPE, pipeser);#endif /* not BSD42 */ if (broken_pipe++ == 0) fprintf (stderr, "broken pipe\n"); told_to_quit++; interrupted++;#ifdef BSD42 if (should_intr) longjmp (sigenv, NOTOK);#endif /* BSD42 */}/* ARGSUSED */static TYPESIG quitser (i)int i;{#ifndef BSD42 (void) signal (SIGQUIT, quitser);#endif /* BSD42 */ told_to_quit++; interrupted++;#ifdef BSD42 if (should_intr) longjmp (sigenv, NOTOK);#endif /* BSD42 */}/* */static int pINI () { int i, vrsn; char *bp; struct record rcs, *rc = &rcs; initrc (rc); switch (peer2rc (rc)) { case RC_INI: bp = rc -> rc_data; while (isspace (*bp)) bp++; if (sscanf (bp, "%d", &vrsn) != 1) { bad_init: ; (void) fmt2peer (RC_ERR, "bad init \"%s\"", rc -> rc_data); done (1); } if (vrsn != RC_VRSN) { (void) fmt2peer (RC_ERR, "version %d unsupported", vrsn); done (1); } while (*bp && !isspace (*bp)) bp++; while (isspace (*bp)) bp++; if (sscanf (bp, "%d", &numwins) != 1 || numwins <= 0) goto bad_init; if (numwins > NWIN) numwins = NWIN; for (i = 1; i <= numwins; i++) { while (*bp && !isspace (*bp)) bp++; while (isspace (*bp)) bp++; if (sscanf (bp, "%d", &windows[i]) != 1 || windows[i] <= 0) goto bad_init; } (void) rc2peer (RC_ACK, 0, NULLCP); return OK; case RC_XXX: padios (NULLCP, "%s", rc -> rc_data); default: (void) fmt2peer (RC_ERR, "pINI protocol screw-up"); done (1); /* NOTREACHED */ }}/* *//* ARGSUSED */static int pQRY (str, scansw)char *str;int scansw;{ if (pQRY1 (scansw) == NOTOK || pQRY2 () == NOTOK) return NOTOK; (void) rc2peer (RC_EOF, 0, NULLCP); return OK;} /* */static int pQRY1 (scansw)int scansw;{ int oldhgh; static int lastlow = 0, lastcur = 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -