📄 mhn.c
字号:
if (f1) { via_mail (f1, f2, f3, f4, f5, f6, f7); /* NOTREACHED */ } else if (f2 || f3 || f4 || f5 || f6 || f7) adios (NULLCP, "missing -viamail \"mailpath\" switch"); if (cp = getenv ("MHN")) { if (fp = fopen (cp, "r")) { m_readefs ((struct node **) 0, fp, cp, 0); (void) fclose (fp); } else admonish ("", "unable to read $MHN profile (%s)", cp); } if (fp = fopen (cp = libpath ("mhn_defaults"), "r")) { m_readefs ((struct node **) 0, fp, cp, 0); (void) fclose (fp); } (void) sprintf (buf, "%s-cache", invo_name); if ((cache_public = m_find (buf)) && *cache_public != '/') cache_public = NULL; (void) sprintf (buf, "%s-private-cache", invo_name); if (!(cache_private = m_find (buf))) cache_private = ".cache"; cache_private = getcpy (m_maildir (cache_private)); cwdlen = strlen (cwd = getcpy (pwd ())); (void) sprintf (buf, "%s-storage", invo_name); dir = getcpy ((cp = m_find (buf)) && *cp ? cp : cwd); tmp = cp && *cp ? concat (cp, "/", invo_name, NULLCP) : add (m_maildir (invo_name), NULLCP); if (!m_find ("path")) free (path ("./", TFOLDER)); if (msgp == 1 && !folder && !npart && !cachesw && !showsw && !storesw && !ntype && !file && (cp = getenv ("mhdraft")) && strcmp (cp, msgs[0]) == 0) { build_comp (cp); /* NOTREACHED */ } if (file) { int stdinP; if (msgp) adios (NULLCP, "only one file at a time!"); if ((cts = (CT *) calloc ((unsigned) 2, sizeof *cts)) == NULL) adios (NULLCP, "out of memory"); ctp = cts; if (stdinP = (strcmp (file, "-") == 0)) { char buffer[BUFSIZ]; file = add (m_tmpfil (invo_name), NULLCP); if ((fp = fopen (file, "w+")) == NULL) adios (file, "unable to fopen for writing and reading"); (void) chmod (file, 0600); while (fgets (buffer, sizeof buffer, stdin)) (void) fputs (buffer, fp); (void) fflush (fp); if (ferror (stdin)) { (void) unlink (file); adios ("stdin", "error reading"); } if (ferror (fp)) { (void) unlink (file); adios (file, "error writing"); } (void) fseek (fp, 0L, 0); } else if ((fp = fopen (file, "r")) == NULL) adios (file, "unable to read"); if (ct = get_content (fp, file, 1)) { if (stdinP) ct -> c_unlink = 1; ct -> c_fp = NULL; if (ct -> c_end == 0L) { (void) fseek (fp, 0L, 2); ct -> c_end = ftell (fp); } if (ct -> c_ctinitfnx && (*ct -> c_ctinitfnx) (ct) == NOTOK) free_content (ct); else *ctp++ = ct; } else advise (NULLCP, "unable to decode %s", file); (void) fclose (fp); mp = NULL; goto go_to_it; } if (!msgp) msgs[msgp++] = "cur"; if (!folder) folder = m_getfolder (); maildir = m_maildir (folder); if (chdir (maildir) == NOTOK) adios (maildir, "unable to change directory to"); if (!(mp = m_gmsg (folder))) adios (NULLCP, "unable to read folder %s", folder); if (mp -> hghmsg == 0) adios (NULLCP, "no messages in %s", folder); for (msgnum = 0; msgnum < msgp; msgnum++) if (!m_convert (mp, msgs[msgnum])) done (1); m_setseq (mp); if ((cts = (CT *) calloc ((unsigned) (mp -> numsel + 1), sizeof *cts)) == NULL) adios (NULLCP, "out of memory"); ctp = cts; for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) if (mp -> msgstats[msgnum] & SELECTED) { char *msgnam; if ((fp = fopen (msgnam = m_name (msgnum), "r")) == NULL) adios (msgnam, "unable to read message"); if (ct = get_content (fp, msgnam, 1)) { ct -> c_fp = NULL; if (ct -> c_end == 0L) { (void) fseek (fp, 0L, 2); ct -> c_end = ftell (fp); } if (ct -> c_ctinitfnx && (*ct -> c_ctinitfnx) (ct) == NOTOK) free_content (ct); else *ctp++ = ct; } else advise (NULLCP, "unable to decode message %s", msgnam); (void) fclose (fp); }go_to_it: ; if (!*cts) done (1); if (!listsw && !showsw && !storesw && !cachesw) showsw++;/* listsw && showsw -> user wants per-message listing, so delay until showsw processing && storesw && sizesw -> evaluating size will cause more work, so delay until after storesw processing */ userrs = 1; (void) signal (SIGQUIT, quitser); (void) signal (SIGPIPE, pipeser); for (ctp = cts; ct = *ctp; ctp++) if (type_ok (ct, 1) && (ct -> c_ctlistfnx || ct -> c_ctstorefnx || ct -> c_ctshowfnx)) { struct stat st; if (!ct -> c_umask) ct -> c_umask = ~(stat (ct -> c_file, &st) != NOTOK ? (st.st_mode & 0777) : m_gmprot ()); } if (listsw && !showsw && (!storesw || !sizesw)) { if (headsw) printf (LSTFMT1, "msg", "part", "type/subtype", "size", "description"); for (ctp = cts; ct = *ctp; ctp++) if (type_ok (ct, 1) && ct -> c_ctlistfnx) { (void) umask (ct -> c_umask); (void) (*ct -> c_ctlistfnx) (ct, 1); if (ct -> c_fp) (void) fclose (ct -> c_fp), ct -> c_fp = NULL; if (ct -> c_ceclosefnx) (*ct -> c_ceclosefnx) (ct); } flush_errors (); } if (storesw) { for (ctp = cts; ct = *ctp; ctp++) if (type_ok (ct, 1) && ct -> c_ctstorefnx) { (void) umask (ct -> c_umask); (void) (*ct -> c_ctstorefnx) (ct, NULLCP); if (ct -> c_fp) (void) fclose (ct -> c_fp), ct -> c_fp = NULL; if (ct -> c_ceclosefnx) (*ct -> c_ceclosefnx) (ct); } flush_errors (); } if (cachesw) { for (ctp = cts; ct = *ctp; ctp++) if (type_ok (ct, 1)) { cache_content (ct); if (ct -> c_fp) (void) fclose (ct -> c_fp), ct -> c_fp = NULL; if (ct -> c_ceclosefnx) (*ct -> c_ceclosefnx) (ct); } flush_errors (); } if (listsw && !showsw && storesw && sizesw) { if (headsw) printf (LSTFMT1, "msg", "part", "type/subtype", "size", "description"); for (ctp = cts; ct = *ctp; ctp++) if (type_ok (ct, 1) && ct -> c_ctlistfnx) { (void) umask (ct -> c_umask); (void) (*ct -> c_ctlistfnx) (ct, 1); if (ct -> c_fp) (void) fclose (ct -> c_fp), ct -> c_fp = NULL; if (ct -> c_ceclosefnx) (*ct -> c_ceclosefnx) (ct); } flush_errors (); listsw = 0; } if (showsw) for (ctp = cts; ct = *ctp; ctp++) {#if defined(BSD42) && !defined(WAITINT) union wait status;#else int status;#endif TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) (); if (!type_ok (ct, 0)) continue; (void) umask (ct -> c_umask); if (listsw) { if (headsw) printf (LSTFMT1, "msg", "part", "type/subtype", "size", "description"); if (ct -> c_ctlistfnx) (void) (*ct -> c_ctlistfnx) (ct, 1); } if (!ct -> c_ctshowfnx) { if (ct -> c_fp) (void) fclose (ct -> c_fp), ct -> c_fp = NULL; if (ct -> c_ceclosefnx) (*ct -> c_ceclosefnx) (ct); continue; } if (strcmp (formsw, "mhl.null")) { int child_id, i, vecp; char *vec[8]; vecp = 0; vec[vecp++] = r1bindex (mhlproc, '/'); vec[vecp++] = "-form"; vec[vecp++] = formsw; vec[vecp++] = "-nobody"; vec[vecp++] = ct -> c_file; if (nomore) vec[vecp++] = "-nomoreproc"; else if (progsw) { vec[vecp++] = "-moreproc"; vec[vecp++] = progsw; } vec[vecp] = NULL; (void) fflush (stdout); for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++) sleep (5); switch (child_id) { case NOTOK: adios ("fork", "unable to"); /* NOTREACHED */ case OK: (void) execvp (mhlproc, vec); fprintf (stderr, "unable to exec "); perror (mhlproc); _exit (-1); /* NOTREACHED */ default: xpid = -child_id; break; } } else xpid = 0; (void) (*ct -> c_ctshowfnx) (ct, 1, 0); if (ct -> c_fp) (void) fclose (ct -> c_fp), ct -> c_fp = NULL; if (ct -> c_ceclosefnx) (*ct -> c_ceclosefnx) (ct); hstat = signal (SIGHUP, SIG_IGN); istat = signal (SIGINT, SIG_IGN); qstat = signal (SIGQUIT, SIG_IGN); tstat = signal (SIGTERM, SIG_IGN); while (wait (&status) != NOTOK) {#if defined(BSD42) && !defined(WAITINT) (void) pidcheck (status.w_status);#else (void) pidcheck (status);#endif continue; } (void) signal (SIGHUP, hstat); (void) signal (SIGINT, istat); (void) signal (SIGQUIT, qstat); (void) signal (SIGTERM, tstat); xpid = 0; flush_errors (); } for (ctp = cts; *ctp; ctp++) free_content (*ctp); free ((char *) cts); cts = NULL; if (mp) { m_replace (pfolder, folder); if (mp -> hghsel != mp -> curmsg) m_setcur (mp, mp -> hghsel); m_sync (mp); m_update (); } done (0); /* NOTREACHED */}/* */static TYPESIG pipeser (i)int i;{ if (i == SIGQUIT) { (void) unlink ("core"); (void) fflush (stdout); fprintf (stderr, "\n"); (void) fflush (stderr); } done (1); /* NOTREACHED */}/* */#include "../h/mhn.h"struct str2init { char *si_key; int si_value; int (*si_init) ();};static int InitApplication (), InitMessage (), InitMultiPart (), InitText (), InitGeneric (); static struct str2init str2cts[] = { "application", CT_APPLICATION, InitApplication, "audio", CT_AUDIO, InitGeneric, "image", CT_IMAGE, InitGeneric, "message", CT_MESSAGE, InitMessage, "multipart", CT_MULTIPART, InitMultiPart, "text", CT_TEXT, InitText, "video", CT_VIDEO, InitGeneric, NULL, CT_EXTENSION, NULL, /* these two must be last! */ NULL, CT_UNKNOWN, NULL,};static int InitBase64 (), InitQuoted (), Init7Bit ();static struct str2init str2ces[] = { "base64", CE_BASE64, InitBase64, "quoted-printable", CE_QUOTED, InitQuoted, "8bit", CE_8BIT, Init7Bit, "7bit", CE_7BIT, Init7Bit, "binary", CE_BINARY, NULL, NULL, CE_EXTENSION, NULL, /* these two must be last! */ NULL, CE_UNKNOWN, NULL,};/* */static CT get_content (in, file, toplevel)FILE *in;char *file;int toplevel;{ int compnum, state; char buf[BUFSIZ], name[NAMESZ]; register CT ct; if ((ct = (CT) calloc (1, sizeof *ct)) == NULL) adios (NULLCP, "out of memory"); ct -> c_begin = ftell (ct -> c_fp = in) + 1; ct -> c_file = add (file, NULLCP); for (compnum = 1, state = FLD;;) { switch (state = m_getfld (state, name, buf, sizeof buf, in)) { case FLD: case FLDPLUS: case FLDEOF: compnum++; if (uleq (name, VRSN_FIELD)) { int ucmp; char c, *cp, *dp; cp = add (buf, NULLCP); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, in); cp = add (buf, cp); } if (ct -> c_vrsn) { advise (NULLCP, "message %s has multiple %s: fields (%s)", ct -> c_file, VRSN_FIELD, dp = trimcpy (cp)); free (dp); free (cp); goto out; } ct -> c_vrsn = cp; while (isspace (*cp)) cp++; for (dp = index (cp, '\n'); dp; dp = index (dp, '\n')) *dp++ = ' '; for (dp = cp + strlen (cp) - 1; dp >= cp; dp--) if (!isspace (*dp)) break; *++dp = '\0'; if (debugsw) fprintf (stderr, "%s: %s\n", VRSN_FIELD, cp); if (*cp == '(' && get_comment (ct, &cp, 0) == NOTOK) goto out; for (dp = cp; istoken (*dp); dp++) continue; c = *dp, *dp = '\0'; ucmp = uleq (cp, VRSN_VALUE); *dp = c; if (!ucmp) admonish (NULLCP, "message %s has unknown value for %s: field (%s)", ct -> c_file, VRSN_FIELD, cp); goto got_header; } if (uleq (name, TYPE_FIELD)) { register char *cp; register struct str2init *s2i; register CI ci = &ct -> c_ctinfo; cp = add (buf, NULLCP); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, in); cp = add (buf, cp); } if (ct -> c_ctline) { char *dp = trimcpy (cp); advise (NULLCP, "message %s has multiple %s: fields (%s)", ct -> c_file, TYPE_FIELD, dp); free (dp); free (cp); goto out; } if (get_ctinfo (cp, ct, 0) == NOTOK) goto out; for (s2i = str2cts; s2i -> si_key; s2i++) if (uleq (ci -> ci_type, s2i -> si_key)) break; if (!s2i -> si_key && !uprf (ci -> ci_type, "X-")) s2i++; ct -> c_type = s2i -> si_value; ct -> c_ctinitfnx = s2i -> si_init; goto got_header; } if (uleq (name, ENCODING_FIELD)) { register char *cp, *dp; char c; register struct str2init *s2i; cp = add (buf, NULLCP); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, in); cp = add (buf, cp); } if (ct -> c_celine) { advise (NULLCP, "message %s has multiple %s: fields (%s)", ct -> c_file, ENCODING_FIELD, dp = trimcpy (cp)); free (dp); free (cp); goto out; } ct -> c_celine = cp; while (isspace (*cp)) cp++; for (dp = cp; istoken (*dp); dp++) continue; c = *dp, *dp = '\0'; for (s2i = str2ces; s2i -> si_key; s2i++) if (uleq (cp, s2i -> si_key)) break; if (!s2i -> si_key && !uprf (cp, "X-")) s2i++; *dp = c; ct -> c_encoding = s2i -> si_value; if (s2i -> si_init && (*s2i -> si_init) (ct) == NOTOK) goto out; goto got_header; } if (uleq (name, ID_FIELD)) { ct -> c_id = add (buf, ct -> c_id); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, in); ct -> c_id = add (buf, ct -> c_id); } goto got_header; } if (uleq (name, DESCR_FIELD)) { ct -> c_descr = add (buf, ct -> c_descr); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, in); ct -> c_descr = add (buf, ct -> c_descr); } goto got_header; } if (uleq (name, MD5_FIELD)) { char *cp, *dp, *ep; cp = add (buf, NULLCP); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, in); cp = add (buf, cp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -