📄 msh.c
字号:
/* */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); if (mp -> hghmsg == 0) padios (NULLCP, "no messages in %s", folder); mode = m_gmprot (); mtime = stat (mp -> foldpath, &st) != NOTOK ? st.st_mtime : 0; m_gMsgs (mp -> hghmsg); for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++) { Msgs[msgnum].m_bboard_id = 0; Msgs[msgnum].m_top = NOTOK; Msgs[msgnum].m_start = Msgs[msgnum].m_stop = 0L; Msgs[msgnum].m_scanl = NULL; } m_init (); fmsh = getcpy (folder);#ifndef BSD42 maxfds = _NFILE / 2;#else /* BSD42 */ maxfds = getdtablesize () / 2;#endif /* BSD42 */ if ((maxfds -= 2) < 1) maxfds = 1;}/* */setup (file)char *file;{ int i, msgp;#ifdef BPOP char tmpfil[BUFSIZ];#endif /* BPOP */ struct stat st;#ifdef BPOP if (pmsh) { (void) strcpy (tmpfil, m_tmpfil (invo_name)); if ((fp = fopen (tmpfil, "w+")) == NULL) padios (tmpfil, "unable to create"); (void) unlink (tmpfil); } else#endif /* BPOP */ if ((fp = fopen (file, "r")) == NULL) padios (file, "unable to read");#ifdef FIOCLEX (void) ioctl (fileno (fp), FIOCLEX, NULLCP);#endif /* FIOCLEX */ if (fstat (fileno (fp), &st) != NOTOK) { mode = (int) (st.st_mode & 0777), mtime = st.st_mtime; msgp = read_map (file, (long) st.st_size); } else { mode = m_gmprot (), mtime = 0; msgp = 0; } if ((msgp = read_file (msgp ? Msgs[msgp].m_stop : 0L, msgp + 1)) < 1) padios (NULLCP, "no messages in %s", myname ? myname : file); mp = (struct msgs *) calloc ((unsigned) 1, MHSIZE (mp, 1, msgp + 1)); if (mp == NULL) padios (NULLCP, "unable to allocate folder storage"); mp -> hghmsg = msgp; mp -> nummsg = msgp; mp -> lowmsg = 1; mp -> curmsg = 0; mp -> foldpath = getcpy (myname ? myname : file); mp -> msgflags = 0;#ifdef BPOP if (pmsh) mp -> msgflags |= READONLY; else {#endif /* BPOP */ (void) stat (file, &st); if (st.st_uid != getuid () || access (file, 02) == NOTOK) mp -> msgflags |= READONLY;#ifdef BPOP }#endif /* BPOP */ mp -> lowoff = 1; mp -> hghoff = mp -> hghmsg + 1;#ifdef MTR mp -> msgstats = (short *) calloc ((unsigned) 1, MHSIZEX (mp, mp -> lowmsg, mp -> hghmsg)); if (mp -> msgstats == NULL) padios (NULLCP, "unable to allocate messages storage"); mp -> msgstats = (mp -> msgbase = mp -> msgstats) - mp -> lowoff; if (mp -> msgstats < (short *)0) padios (NULLCP, "setup() botch -- you lose big");#endif /* MTR */#ifdef BPOP if (pmsh) {#ifndef NNTP for (i = mp -> lowmsg; i <= mp -> hghmsg; i++) { Msgs[i].m_top = i; mp -> msgstats[i] = EXISTS | VIRTUAL; }#else /* NNTP */ for (i = mp -> lowmsg; i <= mp -> hghmsg; i++) { if (Msgs[i].m_top) /* set in read_pop() */ mp -> msgstats[i] = EXISTS | VIRTUAL; }#endif /* NNTP */ } else#endif /* BPOP */ for (i = mp -> lowmsg; i <= mp -> hghmsg; i++) mp -> msgstats[i] = EXISTS; m_init (); mp -> msgattrs[0] = getcpy ("unseen"); mp -> msgattrs[1] = NULL; m_unknown (fp); /* the MAGIC invocation */ if (fmsh) { free (fmsh); fmsh = NULL; }}/* */static int read_map (file, size)char *file;long size;{ register int i, msgp; register struct drop *dp, *mp; struct drop *rp;#ifdef BPOP if (pmsh) return read_pop ();#endif /* BPOP */ if ((i = map_read (file, size, &rp, 1)) == 0) return 0; m_gMsgs (i); msgp = 1; for (dp = rp + 1; i-- > 0; msgp++, dp++) { mp = &Msgs[msgp].m_drop; mp -> d_id = dp -> d_id; mp -> d_size = dp -> d_size; mp -> d_start = dp -> d_start; mp -> d_stop = dp -> d_stop; Msgs[msgp].m_scanl = NULL; } free ((char *) rp); return (msgp - 1);}/* */static int read_file (pos, msgp)register long pos;register int msgp;{ register int i; register struct drop *dp, *mp; struct drop *rp;#ifdef BPOP if (pmsh) return (msgp - 1);#endif /* BPOP */ if ((i = mbx_read (fp, pos, &rp, 1)) <= 0) return (msgp - 1); m_gMsgs ((msgp - 1) + i); for (dp = rp; i-- > 0; msgp++, dp++) { mp = &Msgs[msgp].m_drop; mp -> d_id = 0; mp -> d_size = dp -> d_size; mp -> d_start = dp -> d_start; mp -> d_stop = dp -> d_stop; Msgs[msgp].m_scanl = NULL; } free ((char *) rp); return (msgp - 1);}/* */#ifdef BPOP#ifdef NNTPstatic int pop_base = 0;static int pop_statmsg (s)register char *s;{ register int i, n; n = (i = atoi (s)) - pop_base; /* s="nnn header-line..." */ Msgs[n].m_top = Msgs[n].m_bboard_id = i;}#endif /* NNTP */static int read_pop () { int nmsgs, nbytes; if (pop_stat (&nmsgs, &nbytes) == NOTOK) padios (NULLCP, "%s", response); m_gMsgs (nmsgs);#ifdef NNTP /* this makes read_pop() do some real work... */ pop_base = nbytes - 1; /* nmsgs=last-first+1, nbytes=first */ pop_exists (pop_statmsg);#endif /* NNTP */ return nmsgs;}static int pop_action (s)register char *s;{ fprintf (yp, "%s\n", s);}#endif /* BPOP *//* */static m_gMsgs (n)int n;{ int nmsgs; if (Msgs == NULL) { nMsgs = n + MAXFOLDER / 2; Msgs = (struct Msg *) calloc ((unsigned) (nMsgs + 2), sizeof *Msgs); if (Msgs == NULL) padios (NULLCP, "unable to allocate Msgs structure"); return; } if (nMsgs >= n) return; nmsgs = nMsgs + n + MAXFOLDER / 2; Msgs = (struct Msg *) realloc ((char *) Msgs, (unsigned) (nmsgs + 2) * sizeof *Msgs); if (Msgs == NULL) padios (NULLCP, "unable to reallocate Msgs structure"); bzero ((char *) (Msgs + nMsgs + 2), (unsigned) ((nmsgs - nMsgs) * sizeof *Msgs)); nMsgs = nmsgs;}/* */FILE *msh_ready (msgnum, full)register int msgnum;int full;{ register int msgp; int fd; long pos1, pos2; char *cp, tmpfil[BUFSIZ]; if (yp) { (void) fclose (yp); yp = NULL; } if (fmsh) { if ((fd = Msgs[msgnum].m_top) == NOTOK) { if (numfds >= maxfds) for (msgp = mp -> lowmsg; msgp <= mp -> hghmsg; msgp++) if (Msgs[msgp].m_top != NOTOK) { (void) close (Msgs[msgp].m_top); Msgs[msgp].m_top = NOTOK; numfds--; break; } if ((fd = open (cp = m_name (msgnum), 0)) == NOTOK) padios (cp, "unable to open message"); Msgs[msgnum].m_top = fd; numfds++; } if ((fd = dup (fd)) == NOTOK) padios ("cached message", "unable to dup"); if ((yp = fdopen (fd, "r")) == NULL) padios (NULLCP, "unable to fdopen cached message"); (void) fseek (yp, 0L, 0); return yp; }#ifdef BPOP if (pmsh && (mp -> msgstats[msgnum] & VIRTUAL)) { if (Msgs[msgnum].m_top == 0) padios (NULLCP, "msh_ready (%d, %d) botch", msgnum, full); if (!full) { (void) strcpy (tmpfil, m_tmpfil (invo_name)); if ((yp = fopen (tmpfil, "w+")) == NULL) padios (tmpfil, "unable to create"); (void) unlink (tmpfil); if (pop_top (Msgs[msgnum].m_top, 4, pop_action) == NOTOK) padios (NULLCP, "%s", response); m_eomsbr ((int (*)()) 0); /* XXX */ msg_style = MS_DEFAULT; /* .. */ (void) fseek (yp, 0L, 0); return yp; } (void) fseek (fp, 0L, 2); (void) fwrite (mmdlm1, 1, strlen (mmdlm1), fp); if (fflush (fp)) padios ("temporary file", "write error on"); (void) fseek (fp, 0L, 2); pos1 = ftell (fp); yp = fp; if (pop_retr (Msgs[msgnum].m_top, pop_action) == NOTOK) padios (NULLCP, "%s", response); yp = NULL; (void) fseek (fp, 0L, 2); pos2 = ftell (fp); (void) fwrite (mmdlm2, 1, strlen (mmdlm2), fp); if (fflush (fp)) padios ("temporary file", "write error on"); Msgs[msgnum].m_start = pos1; Msgs[msgnum].m_stop = pos2; mp -> msgstats[msgnum] &= ~VIRTUAL; }#endif /* BPOP */ m_eomsbr ((int (*)()) 0); /* XXX */ (void) fseek (fp, Msgs[msgnum].m_start, 0); return fp;}/* */static int check_folder (scansw)int scansw;{ int flags, i, low, hgh, msgp; struct stat st;#ifdef BPOP if (pmsh) return 0;#endif /* BPOP */ if (fmsh) { if (stat (mp -> foldpath, &st) == NOTOK) padios (mp -> foldpath, "unable to stat"); if (mtime == st.st_mtime) return 0; mtime = st.st_mtime; low = mp -> hghmsg + 1; m_fmsg (mp); if (!(mp = m_gmsg (fmsh))) padios (NULLCP, "unable to re-read folder %s", fmsh); hgh = mp -> hghmsg; for (msgp = mp -> lowmsg; msgp <= mp -> hghmsg; msgp++) { if (Msgs[msgp].m_top != NOTOK) { (void) close (Msgs[msgp].m_top); Msgs[msgp].m_top = NOTOK; numfds--; } if (Msgs[msgp].m_scanl) { free (Msgs[msgp].m_scanl); Msgs[msgp].m_scanl = NULL; } } m_init (); if (modified || low > hgh) return 1; goto check_vmh; } if (fstat (fileno (fp), &st) == NOTOK) padios (mp -> foldpath, "unable to fstat"); if (mtime == st.st_mtime) return 0; mode = (int) (st.st_mode & 0777); mtime = st.st_mtime; if ((msgp = read_file (Msgs[mp -> hghmsg].m_stop, mp -> hghmsg + 1)) < 1) padios (NULLCP, "no messages in %s", mp -> foldpath); /* XXX */ if (msgp >= MAXFOLDER) padios (NULLCP, "more than %d messages in %s", MAXFOLDER, mp -> foldpath); if (msgp <= mp -> hghmsg) return 0; /* XXX */ if ((mp = m_remsg (mp, 0, msgp)) == NULL) padios (NULLCP, "unable to allocate folder storage"); low = mp -> hghmsg + 1, hgh = msgp; flags = scansw ? m_seqflag (mp, "unseen") : 0; for (i = mp -> hghmsg + 1; i <= msgp; i++) { mp -> msgstats[i] = EXISTS | flags; mp -> nummsg++; } mp -> hghmsg = msgp; m_init ();check_vmh: ; if (vmh) return 1; advise (NULLCP, "new messages have arrived!\007"); if (scansw) scanrange (low, hgh); return 1;}/* */static scanrange (low, hgh)int low, hgh;{ char buffer[BUFSIZ]; (void) sprintf (buffer, "%d-%d", low, hgh); scanstring (buffer);}static scanstring (arg)char *arg;{ char *cp, **ap, *vec[MAXARGS]; if ((cp = m_find (cmd_name = "scan")) != NULL) { ap = brkstring (cp = getcpy (cp), " ", "\n"); ap = copyip (ap, vec); } else ap = vec; *ap++ = arg; *ap = NULL; m_init (); scancmd (vec); if (cp != NULL) free (cp);}/* */readids (id)int id;{ register int cur, flags, i, msgnum; if (mp -> curmsg == 0) m_setcur (mp, mp -> lowmsg); if (id <= 0 || (flags = m_seqflag (mp, "unseen")) == 0) return; for (msgnum = mp -> hghmsg; msgnum >= mp -> lowmsg; msgnum--) mp -> msgstats[msgnum] |= flags; if (id != 1) { cur = mp -> curmsg; for (msgnum = mp -> hghmsg; msgnum >= mp -> lowmsg; msgnum--) if (mp -> msgstats[msgnum] & EXISTS) /* FIX */ if ((i = readid (msgnum)) > 0 && i < id) { cur = msgnum + 1; mp -> msgstats[msgnum] &= ~flags; break; } for (i = mp -> lowmsg; i < msgnum; i++) mp -> msgstats[i] &= ~flags; if (cur > mp -> hghmsg) cur = mp -> hghmsg; m_setcur (mp, cur); } if ((gap = 1 < id && id < (i = readid (mp -> lowmsg)) ? id : 0) && !vmh) advise (NULLCP, "gap in ID:s, last seen %d, lowest present %d\n", id - 1, i);}/* */int readid (msgnum)int msgnum;{ int i, state;#ifdef BPOP int arg1, arg2, arg3;#endif /* BPOP */ char *bp, buf[BUFSIZ], name[NAMESZ]; register FILE *zp; if (Msgs[msgnum].m_bboard_id) return Msgs[msgnum].m_bboard_id;#ifdef BPOP if (pmsh) { if (Msgs[msgnum].m_top == 0) padios (NULLCP, "readid (%d) botch", msgnum); if (pop_list (Msgs[msgnum].m_top, (int *) 0, &arg1, &arg2, &arg3) == OK && arg3 > 0) return (Msgs[msgnum].m_bboard_id = arg3); }#endif /* BPOP */ 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, BBoard_ID)) { bp = getcpy (buf); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, zp); bp = add (buf, bp); } i = atoi (bp); free (bp); if (i > 0) return (Msgs[msgnum].m_bboard_id = i); else continue; } while (state == FLDPLUS) state = m_getfld (state, name, buf, sizeof buf, zp); if (state != FLDEOF) continue; default: return 0; }}/* */display_info (scansw)int scansw;{ int flags, sd; interactive = isatty (fileno (stdout)); if (sp == NULL) { if ((sd = dup (fileno (stdout))) == NOTOK) padios ("standard output", "unable to dup");#ifndef BSD42 /* XXX */#ifdef FIOCLEX (void) ioctl (sd, FIOCLEX, NULL);#endif /* FIOCLEX */#endif /* not BSD42 */ if ((sp = fdopen (sd, "w")) == NULL) padios ("standard output", "unable to fdopen"); } (void) m_putenv ("mhfolder", mp -> foldpath); if (vmh) return; if (myname) { printf ("Reading "); if (SOprintf ("%s", myname)) printf ("%s", myname); printf (", currently at message %d of %d\n", mp -> curmsg, mp -> hghmsg); } else { printf ("Reading "); if (fmsh) printf ("+%s", fmsh); else printf ("%s", mp -> foldpath); printf (", currently at message %d of %d\n", mp -> curmsg, mp -> hghmsg); } if ((flags = m_seqflag (mp, "unseen")) && scansw && (mp -> msgstats[mp -> hghmsg] & flags)) scanstring ("unseen");}/* */static write_ids () { int i = 0, flags, msgnum; char buffer[80]; if (pfd <= 1) return; if (flags = m_seqflag (mp, "unseen")) for (msgnum = mp -> hghmsg; msgnum >= mp -> lowmsg; msgnum--) if (!(mp -> msgstats[msgnum] & flags)) { if (Msgs[msgnum].m_bboard_id == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -