📄 smail.c
字号:
/* *//* VARARGS */static int sm_ierror (fmt, a, b, c, d)char *fmt, *a, *b, *c, *d;{ (void) sprintf (sm_reply.text, fmt, a, b, c, d); sm_reply.length = strlen (sm_reply.text); sm_reply.code = NOTOK; return RP_BHST;}/* *//* VARARGS2 */static int smtalk (time, fmt, a, b, c, d)register int time;register char *fmt;{ register int result; char buffer[BUFSIZ]; (void) sprintf (buffer, fmt, a, b, c, d); if (sm_debug) { printf ("=> %s\n", buffer); (void) fflush (stdout); }#ifdef MPOP if (sm_ispool) { char file[BUFSIZ]; if (strcmp (buffer, ".") == 0) time = SM_DOT; fprintf (sm_wfp, "%s\r\n", buffer); switch (time) { case SM_DOT: (void) fflush (sm_wfp); if (ferror (sm_wfp)) return sm_werror (); (void) sprintf (file, "%s%c.bulk", sm_tmpfil, (char) (sm_ispool + 'a' - 1)); if (rename (sm_tmpfil, file) == NOTOK) { char *bp; (void) sprintf (bp = sm_reply.text, "error renaming %s to %s: ", sm_tmpfil, file); bp += strlen (bp); if (errno > 0 && errno < sys_nerr) (void) sprintf (bp, "%s", sys_errlist[errno]); else (void) sprintf (bp, "Error %d", errno); sm_reply.length = strlen (sm_reply.text); sm_reply.code = NOTOK; return RP_BHST; } (void) fclose (sm_wfp); if (sm_wfp = fopen (sm_tmpfil, "w")) (void) chmod (sm_tmpfil, 0600); sm_ispool++; /* and fall... */ case SM_MAIL: case SM_RCPT: result = 250; break; case SM_RSET: (void) fflush (sm_wfp); (void) ftruncate (fileno (sm_wfp), 0L); (void) fseek (sm_wfp, 0L, 0); result = 250; break; case SM_DATA: result = 354; break; case SM_QUIT: (void) unlink (sm_tmpfil); sm_ispool = 0; result = 221; break; default: result = 500; break; } if (sm_debug) { printf ("<= %d\n", result); (void) fflush (stdout); } sm_reply.text[sm_reply.length = 0] = NULL; return (sm_reply.code = result); }#endif /* MPOP */ sm_alarmed = 0; (void) alarm ((unsigned) time); if ((result = sm_wrecord (buffer, strlen (buffer))) != NOTOK) result = smhear (); (void) alarm (0); return result;}/* */static int sm_wrecord (buffer, len)register char *buffer;register int len;{ if (sm_wfp == NULL) return sm_werror (); (void) fwrite (buffer, sizeof *buffer, len, sm_wfp); (void) fputs ("\r\n", sm_wfp); (void) fflush (sm_wfp); return (ferror (sm_wfp) ? sm_werror () : OK);}/* */static int sm_wstream (buffer, len)register char *buffer;register int len;{ register char *bp; static char lc = 0; if (sm_wfp == NULL) return sm_werror (); if (buffer == NULL && len == 0) { if (lc != '\n') (void) fputs ("\r\n", sm_wfp); lc = 0; return (ferror (sm_wfp) ? sm_werror () : OK); } for (bp = buffer; len > 0; bp++, len--) { switch (*bp) { case '\n': sm_nl = TRUE; (void) fputc ('\r', sm_wfp); break; case '.': if (sm_nl) (void) fputc ('.', sm_wfp);/* FALL THROUGH */ default: sm_nl = FALSE; } (void) fputc (*bp, sm_wfp); if (ferror (sm_wfp)) return sm_werror (); } if (bp > buffer) lc = *--bp; return (ferror (sm_wfp) ? sm_werror () : OK);}/* */#ifdef _AIX/* * AIX by default will inline the strlen and strcpy commands by redefining * them as __strlen and __strcpy respectively. This causes compile problems * with the #ifdef MPOP in the middle. Should the #ifdef MPOP be removed, * remove these #undefs. */#undef strlen#undef strcpy#endif /* _AIX */static int sm_werror () { sm_reply.length =#ifdef SMTP strlen (strcpy (sm_reply.text, sm_wfp == NULL ? "no socket opened" : sm_alarmed ? "write to socket timed out"#ifdef MPOP : sm_ispool ? "error writing to spool file"#endif : "error writing to socket"));#else /* !SMTP */ strlen (strcpy (sm_reply.text, sm_wfp == NULL ? "no pipe opened" : sm_alarmed ? "write to pipe timed out" : "error writing to pipe"));#endif /* !SMTP */ return (sm_reply.code = NOTOK);}/* */static int smhear () { register int i, code, cont, rc, more; int bc; register char *bp, *rp; char **ehlo, buffer[BUFSIZ]; if (doingEHLO) { static int at_least_once = 0; if (at_least_once) { char *ep; for (ehlo = EHLOkeys; ep = *ehlo; ehlo++) free (ep); } else at_least_once = 1; *(ehlo = EHLOkeys) = NULL; }again: ; sm_reply.text[sm_reply.length = 0] = 0; rp = sm_reply.text, rc = sizeof sm_reply.text - 1; for (more = FALSE; sm_rrecord (bp = buffer, &bc) != NOTOK;) { if (sm_debug) { printf ("<= %s\n", buffer); (void) fflush (stdout); } if (doingEHLO && strncmp (buffer, "250", sizeof "250" - 1) == 0 && (buffer[3] == '-' || doingEHLO == 2) && buffer[4]) { if (doingEHLO == 2) { int len = strlen (buffer + 4); if (*ehlo = malloc ((unsigned) (strlen (buffer + 4) + 1))) { (void) strcpy (*ehlo++, buffer + 4); *ehlo = NULL; if (ehlo >= EHLOkeys + MAXEHLO) doingEHLO = 0; } else doingEHLO = 0; } else doingEHLO = 2; } for (; bc > 0 && (!isascii (*bp) || !isdigit (*bp)); bp++, bc--) continue; cont = FALSE; code = atoi (bp); bp += 3, bc -= 3; for (; bc > 0 && isspace (*bp); bp++, bc--) continue; if (bc > 0 && *bp == '-') { cont = TRUE; bp++, bc--; for (; bc > 0 && isspace (*bp); bp++, bc--) continue; } if (more) { if (code != sm_reply.code || cont) continue; more = FALSE; } else { sm_reply.code = code; more = cont; if (bc <= 0) { (void) strcpy (bp = buffer, sm_noreply); bc = strlen (sm_noreply); } } if ((i = min (bc, rc)) > 0) { (void) strncpy (rp, bp, i); rp += i, rc -= i; if (more && rc > strlen (sm_moreply) + 1) { (void) strcpy (sm_reply.text + rc, sm_moreply); rc += strlen (sm_moreply); } } if (more) continue; if (sm_reply.code < 100) { if (sm_verbose) { printf ("%s\n", sm_reply.text); (void) fflush (stdout); } goto again; } sm_reply.length = rp - sm_reply.text; return sm_reply.code; } return NOTOK;}/* */static int sm_rrecord (buffer, len)register char *buffer;register int *len;{ if (sm_rfp == NULL) return sm_rerror (); buffer[*len = 0] = 0; (void) fgets (buffer, BUFSIZ, sm_rfp); *len = strlen (buffer); if (ferror (sm_rfp) || feof (sm_rfp)) return sm_rerror (); if (buffer[*len - 1] != '\n') while (getc (sm_rfp) != '\n' && !ferror (sm_rfp) && !feof (sm_rfp)) continue; else if (buffer[*len - 2] == '\r') *len -= 1; buffer[*len - 1] = 0; return OK;}/* */static int sm_rerror () { sm_reply.length =#ifdef SMTP strlen (strcpy (sm_reply.text, sm_rfp == NULL ? "no socket opened" : sm_alarmed ? "read from socket timed out" : feof (sm_rfp) ? "premature end-of-file on socket" : "error reading from socket"));#else /* not SMTP */ strlen (strcpy (sm_reply.text, sm_rfp == NULL ? "no pipe opened" : sm_alarmed ? "read from pipe timed out" : feof (sm_rfp) ? "premature end-of-file on pipe" : "error reading from pipe"));#endif /* not SMTP */ return (sm_reply.code = NOTOK);}/* *//* ARGSUSED */static TYPESIG alrmser (i)int i;{#ifndef BSD42 signal (SIGALRM, alrmser);#endif /* BSD42 */ sm_alarmed++; if (sm_debug) { printf ("timed out...\n"); (void) fflush (stdout); }}/* */char *rp_string (code)register int code;{ register char *text; static char buffer[BUFSIZ]; switch (sm_reply.code != NOTOK ? code : NOTOK) { case RP_AOK: text = "AOK"; break; case RP_MOK: text = "MOK"; break; case RP_OK: text = "OK"; break; case RP_RPLY: text = "RPLY"; break; case RP_BHST: default: text = "BHST"; (void) sprintf (buffer, "[%s] %s", text, sm_reply.text); return buffer; case RP_PARM: text = "PARM"; break; case RP_NO: text = "NO"; break; case RP_USER: text = "USER"; break; case RP_NDEL: text = "NDEL"; break; } (void) sprintf (buffer, "[%s] %3d %s", text, sm_reply.code, sm_reply.text); return buffer;}/* */#ifdef MPOP#ifdef SMTPstatic char *broken[MAXARGS + 1];static char **brkstring (strg, brksep, brkterm)register char *strg;register char *brksep, *brkterm;{ register int bi; register char c, *sp; sp = strg; for (bi = 0; bi < MAXARGS; bi++) { while (brkany (c = *sp, brksep)) *sp++ = 0; if (!c || brkany (c, brkterm)) { *sp = 0; broken[bi] = 0; return broken; } broken[bi] = sp; while ((c = *++sp) && !brkany (c, brksep) && !brkany (c, brkterm)) continue; } broken[MAXARGS] = 0; return broken;}static brkany (chr, strg)register char chr, *strg;{ register char *sp; if (strg) for (sp = strg; *sp; sp++) if (chr == *sp) return 1; return 0;}static char **copyip (p, q)register char **p, **q;{ while (*p) *q++ = *p++; *q = 0; return q;}#endif#endif /* MPOP *//* */char *EHLOset (s)char *s;{ int len = strlen (s); register char *ep, **ehlo; for (ehlo = EHLOkeys; ep = *ehlo; ehlo++) if (strncmp (ep, s, len) == 0) { for (ep += len; *ep == ' '; ep++) continue; return ep; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -