📄 ipop3d.c
字号:
} else if (!strcmp (s,"RETR")) { if (t && *t) { /* must have an argument */ if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && msg[i] && !(flags[i] & DELE)) { MESSAGECACHE *elt; /* update highest message accessed */ if (i > last) last = i; sprintf (tmp,"+OK %lu octets\015\012", (elt = mail_elt (stream,msg[i]))->rfc822_size + SLEN); PSOUT (tmp); /* if not marked seen or noted to be marked */ if (!(elt->seen || (flags[i] & SEEN))) { ++nseen; /* note that we need to mark it seen */ flags[i] |= SEEN; } /* get header */ t = mail_fetch_header (stream,msg[i],NIL,NIL,&k,FT_PEEK); blat (t,-1,k,NIL);/* write up to trailing CRLF */ /* build status */ sprintf (tmp,STATUS,elt->seen ? "R" : " ", elt->recent ? " " : "O"); if (k < 4) CRLF; /* don't write Status: if no header */ /* normal header ending with CRLF CRLF? */ else if (t[k-3] == '\012') { PSOUT (tmp); /* write status */ CRLF; /* then write second CRLF */ } else { /* abnormal - no blank line at end of header */ CRLF; /* write CRLF first then */ PSOUT (tmp); } /* output text */ t = mail_fetch_text (stream,msg[i],NIL,&k, FT_RETURNSTRINGSTRUCT | FT_PEEK); if (k) { /* only if there is a text body */ blat (t,-1,k,&stream->private.string); CRLF; /* end of list */ } PBOUT ('.'); CRLF; } else PSOUT ("-ERR No such message\015\012"); } else PSOUT ("-ERR Missing message number argument\015\012"); } else if (!strcmp (s,"DELE")) { if (t && *t) { /* must have an argument */ if ((i = strtoul (t,NIL,10)) && (i <= nmsgs) && msg[i] && !(flags[i] & DELE)) { /* update highest message accessed */ if (i > last) last = i; flags[i] |= DELE; /* note that deletion is requested */ PSOUT ("+OK Message deleted\015\012"); ++ndele; /* one more message deleted */ } else PSOUT ("-ERR No such message\015\012"); } else PSOUT ("-ERR Missing message number argument\015\012"); } else if (!strcmp (s,"NOOP")) PSOUT ("+OK No-op to you too!\015\012"); else if (!strcmp (s,"LAST")) { sprintf (tmp,"+OK %lu\015\012",last); PSOUT (tmp); } else if (!strcmp (s,"RSET")) { rset (); /* reset the mailbox */ PSOUT ("+OK Reset state\015\012"); } else if (!strcmp (s,"TOP")) { if (t && *t && (i =strtoul (t,&s,10)) && (i <= nmsgs) && msg[i] && !(flags[i] & DELE)) { /* skip whitespace */ while (*s == ' ') s++; /* make sure line count argument good */ if ((*s >= '0') && (*s <= '9')) { MESSAGECACHE *elt = mail_elt (stream,msg[i]); j = strtoul (s,NIL,10); /* update highest message accessed */ if (i > last) last = i; PSOUT ("+OK Top of message follows\015\012"); /* get header */ t = mail_fetch_header (stream,msg[i],NIL,NIL,&k,FT_PEEK); blat (t,-1,k,NIL);/* write up to trailing CRLF */ /* build status */ sprintf (tmp,STATUS,elt->seen ? "R" : " ", elt->recent ? " " : "O"); if (k < 4) CRLF; /* don't write Status: if no header */ /* normal header ending with CRLF CRLF? */ else if (t[k-3] == '\012') { PSOUT (tmp); /* write status */ CRLF; /* then write second CRLF */ } else { /* abnormal - no blank line at end of header */ CRLF; /* write CRLF first then */ PSOUT (tmp); } if (j) { /* want any text lines? */ /* output text */ t = mail_fetch_text (stream,msg[i],NIL,&k, FT_PEEK | FT_RETURNSTRINGSTRUCT); /* tie off final line if full text output */ if (k && (j -= blat (t,j,k,&stream->private.string))) CRLF; } PBOUT ('.'); /* end of list */ CRLF; } else PSOUT ("-ERR Bad line count argument\015\012"); } else PSOUT ("-ERR Bad message number argument\015\012"); } else if (!strcmp (s,"XTND")) PSOUT ("-ERR Sorry I can't do that\015\012"); else PSOUT ("-ERR Unknown TRANSACTION state command\015\012"); break; default: PSOUT ("-ERR Server in unknown state\015\012"); break; } } PFLUSH (); /* make sure output finished */ if (autologouttime) { /* have an autologout in effect? */ /* cancel if no longer waiting for login */ if (state != AUTHORIZATION) autologouttime = 0; /* took too long to login */ else if (autologouttime < time (0)) { goodbye = "-ERR Autologout\015\012"; logout = "Autologout"; state = LOGOUT; /* sayonara */ } } } /* open and need to update? */ if (stream && (state == UPDATE)) { if (nseen) { /* only bother if messages need marking seen */ *(s = tmp) = '\0'; /* clear sequence */ for (i = 1; i <= nmsgs; ++i) if (flags[i] & SEEN) { for (j = i + 1, k = 0; (j <= nmsgs) && (flags[j] & SEEN); ++j) k = j; if (k) sprintf (s,",%lu:%lu",i,k); else sprintf (s,",%lu",i); s += strlen (s); /* point to end of string */ if ((s - tmp) > (MAILTMPLEN - 30)) { mail_setflag (stream,tmp + 1,"\\Seen"); *(s = tmp) = '\0'; /* restart sequence */ } i = j; /* continue after the range */ } if (tmp[0]) mail_setflag (stream,tmp + 1,"\\Seen"); } if (ndele) { /* any messages to delete? */ *(s = tmp) = '\0'; /* clear sequence */ for (i = 1; i <= nmsgs; ++i) if (flags[i] & DELE) { for (j = i + 1, k = 0; (j <= nmsgs) && (flags[j] & DELE); ++j) k = j; if (k) sprintf (s,",%lu:%lu",i,k); else sprintf (s,",%lu",i); s += strlen (s); /* point to end of string */ if ((s - tmp) > (MAILTMPLEN - 30)) { mail_setflag (stream,tmp + 1,"\\Deleted"); *(s = tmp) = '\0'; /* restart sequence */ } i = j; /* continue after the range */ } if (tmp[0]) mail_setflag (stream,tmp + 1,"\\Deleted"); mail_expunge (stream); } syslog (LOG_INFO,"Update user=%.80s host=%.80s nmsgs=%lu ndele=%lu nseen=%lu", user,tcp_clienthost (),stream->nmsgs,ndele,nseen); mail_close (stream); } sayonara (0); return 0; /* stupid compilers */}/* Say goodbye * Accepts: exit status * * Does not return */void sayonara (int status){ logouthook_t lgoh = (logouthook_t) mail_parameters (NIL,GET_LOGOUTHOOK,NIL); if (goodbye) { /* have a goodbye message? */ PSOUT (goodbye); PFLUSH (); /* make sure blatted */ } syslog (LOG_INFO,"%s user=%.80s host=%.80s",logout, user ? (char *) user : "???",tcp_clienthost ()); /* do logout hook if needed */ if (lgoh) (*lgoh) (mail_parameters (NIL,GET_LOGOUTDATA,NIL)); _exit (status); /* all done */}/* Clock interrupt */void clkint (){ alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); goodbye = "-ERR Autologout; idle for too long\015\012"; logout = "Autologout"; if (critical) state = LOGOUT; /* badly hosed if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { rset (); mail_close (stream); } state = LOGOUT; stream = NIL; sayonara (1); }}/* Kiss Of Death interrupt */void kodint (){ /* only if idle */ if (idletime && ((time (0) - idletime) > KODTIMEOUT)) { alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); goodbye = "-ERR Received Kiss of Death\015\012"; logout = "Killed (lost mailbox lock)"; if (critical) state =LOGOUT;/* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { rset (); mail_close (stream); } state = LOGOUT; stream = NIL; sayonara (1); /* die die die */ } }}/* Hangup interrupt */void hupint (){ alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); goodbye = NIL; /* nobody left to talk to */ logout = "Hangup"; if (critical) state = LOGOUT; /* must defer if in critical code */ else { /* try to gracefully close the stream */ if ((state == TRANSACTION) && !stream->lock) { rset (); mail_close (stream); } state = LOGOUT; stream = NIL; sayonara (1); /* die die die */ }}/* Termination interrupt */void trmint (){ alarm (0); /* disable all interrupts */ server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); goodbye = "-ERR Killed\015\012"; logout = "Killed"; if (critical) state = LOGOUT; /* must defer if in critical code */ /* Make no attempt at graceful closure since a shutdown may be in * progress, and we won't have any time to do mail_close() actions. */ else sayonara (1); /* die die die */}/* Parse PASS command * Accepts: pointer to command argument * Returns: new state */int pass_login (char *t,int argc,char *argv[]){ char tmp[MAILTMPLEN]; /* flush old passowrd */ if (pass) fs_give ((void **) &pass); if (!(t && *t)) { /* if no password given */ PSOUT ("-ERR Missing password argument\015\012"); return AUTHORIZATION; } pass = cpystr (t); /* copy password argument */ if (!host) { /* want remote mailbox? */ /* no, delimit user from possible admin */ if (t = strchr (user,'*')) *t++ ='\0'; /* attempt the login */ if (server_login (user,pass,t,argc,argv)) { int ret = mbxopen ("INBOX"); if (ret == TRANSACTION) /* mailbox opened OK? */ syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s nmsgs=%lu/%lu", t ? "Admin " : "",user,tcp_clienthost (),nmsgs,stream->nmsgs); else syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s no mailbox", t ? "Admin " : "",user,tcp_clienthost ()); return ret; } }#ifndef DISABLE_POP_PROXY /* remote; build remote INBOX */ else if (anonymous_login (argc,argv)) { syslog (LOG_INFO,"IMAP login to host=%.80s user=%.80s host=%.80s",host, user,tcp_clienthost ()); sprintf (tmp,"{%.128s/user=%.128s}INBOX",host,user); /* disable rimap just in case */ mail_parameters (NIL,SET_RSHTIMEOUT,0); return mbxopen (tmp); }#endif /* vague error message to confuse crackers */ PSOUT ("-ERR Bad login\015\012"); return AUTHORIZATION;}/* Authentication responder * Accepts: challenge * length of challenge * pointer to response length return location if non-NIL * Returns: response */#define RESPBUFLEN 8*MAILTMPLENchar *responder (void *challenge,unsigned long clen,unsigned long *rlen){ unsigned long i,j; unsigned char *t,resp[RESPBUFLEN]; char tmp[MAILTMPLEN]; if (initial) { /* initial response given? */ if (clen) return NIL; /* not permitted */ /* set up response */ t = (unsigned char *) initial; initial = NIL; /* no more initial response */ return (char *) rfc822_base64 (t,strlen ((char *) t),rlen ? rlen : &i); } PSOUT ("+ "); for (t = rfc822_binary (challenge,clen,&i),j = 0; j < i; j++) if (t[j] > ' ') PBOUT (t[j]); fs_give ((void **) &t); CRLF; PFLUSH (); /* dump output buffer */ resp[RESPBUFLEN-1] = '\0'; /* last buffer character is guaranteed NUL */ alarm (LOGINTIMEOUT); /* get a response under timeout */ clearerr (stdin); /* clear stdin errors */ /* read buffer */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -