📄 pop3.c
字号:
fs_give ((void **) &t); } else ret = net_sout (LOCAL->netstream,"\015\012",2); } else { /* abort requested */ ret = net_sout (LOCAL->netstream,"*\015\012",3); LOCAL->saslcancel = T; /* mark protocol-requested SASL cancel */ } pop3_reply (stream); /* get response */ return ret;}/* POP3 mail close * Accepts: MAIL stream * option flags */void pop3_close (MAILSTREAM *stream,long options){ int silent = stream->silent; if (LOCAL) { /* only if a file is open */ if (LOCAL->netstream) { /* close POP3 connection */ stream->silent = T; if (options & CL_EXPUNGE) pop3_expunge (stream,NIL,NIL); stream->silent = silent; pop3_send (stream,"QUIT",NIL); mm_notify (stream,LOCAL->reply,BYE); } /* close POP3 connection */ if (LOCAL->netstream) net_close (LOCAL->netstream); /* clean up */ if (LOCAL->cap.implementation) fs_give ((void **) &LOCAL->cap.implementation); if (LOCAL->txt) fclose (LOCAL->txt); LOCAL->txt = NIL; if (LOCAL->response) fs_give ((void **) &LOCAL->response); /* nuke the local data */ fs_give ((void **) &stream->local); stream->dtb = NIL; /* log out the DTB */ }}/* POP3 mail fetch fast information * Accepts: MAIL stream * sequence * option flags * This is ugly and slow */void pop3_fetchfast (MAILSTREAM *stream,char *sequence,long flags){ unsigned long i; MESSAGECACHE *elt; /* get sequence */ if (stream && LOCAL && ((flags & FT_UID) ? mail_uid_sequence (stream,sequence) : mail_sequence (stream,sequence))) for (i = 1; i <= stream->nmsgs; i++) if ((elt = mail_elt (stream,i))->sequence && !(elt->day && elt->rfc822_size)) { ENVELOPE **env = NIL; ENVELOPE *e = NIL; if (!stream->scache) env = &elt->private.msg.env; else if (stream->msgno == i) env = &stream->env; else env = &e; if (!*env || !elt->rfc822_size) { STRING bs; unsigned long hs; char *ht = (*stream->dtb->header) (stream,i,&hs,NIL); /* need to make an envelope? */ if (!*env) rfc822_parse_msg (env,NIL,ht,hs,NIL,BADHOST, stream->dtb->flags); /* need message size too, ugh */ if (!elt->rfc822_size) { (*stream->dtb->text) (stream,i,&bs,FT_PEEK); elt->rfc822_size = hs + SIZE (&bs) - GETPOS (&bs); } } /* if need date, have date in envelope? */ if (!elt->day && *env && (*env)->date) mail_parse_date (elt,(*env)->date); /* sigh, fill in bogus default */ if (!elt->day) elt->day = elt->month = 1; mail_free_envelope (&e); }}/* POP3 fetch header as text * Accepts: mail stream * message number * pointer to return size * flags * Returns: header text */char *pop3_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *size, long flags){ unsigned long i; char tmp[MAILTMPLEN]; MESSAGECACHE *elt; FILE *f = NIL; *size = 0; /* initially no header size */ if ((flags & FT_UID) && !(msgno = mail_msgno (stream,msgno))) return ""; /* have header text already? */ if (!(elt = mail_elt (stream,msgno))->private.msg.header.text.data) { /* if have CAPA and TOP, assume good TOP */ if (!LOCAL->loser && LOCAL->cap.top) { sprintf (tmp,"TOP %lu 0",mail_uid (stream,msgno)); if (pop3_send (stream,tmp,NIL)) f = netmsg_slurp (LOCAL->netstream,&i, &elt->private.msg.header.text.size); } /* otherwise load the cache with the message */ else if (elt->private.msg.header.text.size = pop3_cache (stream,elt)) f = LOCAL->txt; if (f) { /* got it, make sure at start of file */ fseek (f,(unsigned long) 0,SEEK_SET); /* read header from the cache */ fread (elt->private.msg.header.text.data = (unsigned char *) fs_get ((size_t) elt->private.msg.header.text.size + 1), (size_t) 1,(size_t) elt->private.msg.header.text.size,f); /* tie off header text */ elt->private.msg.header.text.data[elt->private.msg.header.text.size] = '\0'; /* close if not the cache */ if (f != LOCAL->txt) fclose (f); } } /* return size of text */ if (size) *size = elt->private.msg.header.text.size; return elt->private.msg.header.text.data ? (char *) elt->private.msg.header.text.data : "";}/* POP3 fetch body * Accepts: mail stream * message number * pointer to stringstruct to initialize * flags * Returns: T if successful, else NIL */long pop3_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){ MESSAGECACHE *elt; INIT (bs,mail_string,(void *) "",0); if ((flags & FT_UID) && !(msgno = mail_msgno (stream,msgno))) return NIL; elt = mail_elt (stream,msgno); pop3_cache (stream,elt); /* make sure cache loaded */ if (!LOCAL->txt) return NIL; /* error if don't have a file */ if (!(flags & FT_PEEK)) { /* mark seen if needed */ elt->seen = T; mm_flags (stream,elt->msgno); } INIT (bs,file_string,(void *) LOCAL->txt,elt->rfc822_size); SETPOS (bs,LOCAL->hdrsize); /* skip past header */ return T;}/* POP3 cache message * Accepts: mail stream * message number * Returns: header size */unsigned long pop3_cache (MAILSTREAM *stream,MESSAGECACHE *elt){ /* already cached? */ if (LOCAL->cached != mail_uid (stream,elt->msgno)) { /* no, close current file */ if (LOCAL->txt) fclose (LOCAL->txt); LOCAL->txt = NIL; LOCAL->cached = LOCAL->hdrsize = 0; if (pop3_send_num (stream,"RETR",elt->msgno) && (LOCAL->txt = netmsg_slurp (LOCAL->netstream,&elt->rfc822_size, &LOCAL->hdrsize))) /* set as current message number */ LOCAL->cached = mail_uid (stream,elt->msgno); else elt->deleted = T; } return LOCAL->hdrsize;}/* POP3 mail ping mailbox * Accepts: MAIL stream * Returns: T if stream alive, else NIL */long pop3_ping (MAILSTREAM *stream){ return pop3_send (stream,"NOOP",NIL);}/* POP3 mail check mailbox * Accepts: MAIL stream */void pop3_check (MAILSTREAM *stream){ if (pop3_ping (stream)) mm_log ("Check completed",NIL);}/* POP3 mail expunge mailbox * Accepts: MAIL stream * sequence to expunge if non-NIL * expunge options * Returns: T if success, NIL if failure */long pop3_expunge (MAILSTREAM *stream,char *sequence,long options){ char tmp[MAILTMPLEN]; MESSAGECACHE *elt; unsigned long i = 1,n = 0; long ret; if (ret = sequence ? ((options & EX_UID) ? mail_uid_sequence (stream,sequence) : mail_sequence (stream,sequence)) : LONGT) { /* build selected sequence if needed */ while (i <= stream->nmsgs) { elt = mail_elt (stream,i); if (elt->deleted && (sequence ? elt->sequence : T) && pop3_send_num (stream,"DELE",i)) { /* expunging currently cached message? */ if (LOCAL->cached == mail_uid (stream,i)) { /* yes, close current file */ if (LOCAL->txt) fclose (LOCAL->txt); LOCAL->txt = NIL; LOCAL->cached = LOCAL->hdrsize = 0; } mail_expunged (stream,i); n++; } else i++; /* try next message */ } if (!stream->silent) { /* only if not silent */ if (n) { /* did we expunge anything? */ sprintf (tmp,"Expunged %lu messages",n); mm_log (tmp,(long) NIL); } else mm_log ("No messages deleted, so no update needed",(long) NIL); } } return ret;}/* POP3 mail copy message(s) * Accepts: MAIL stream * sequence * destination mailbox * option flags * Returns: T if copy successful, else NIL */long pop3_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){ mailproxycopy_t pc = (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL); if (pc) return (*pc) (stream,sequence,mailbox,options); mm_log ("Copy not valid for POP3",ERROR); return NIL;}/* POP3 mail append message from stringstruct * Accepts: MAIL stream * destination mailbox * append callback * data for callback * Returns: T if append successful, else NIL */long pop3_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){ mm_log ("Append not valid for POP3",ERROR); return NIL;}/* Internal routines *//* Post Office Protocol 3 send command with number argument * Accepts: MAIL stream * command * number * Returns: T if successful, NIL if failure */long pop3_send_num (MAILSTREAM *stream,char *command,unsigned long n){ char tmp[MAILTMPLEN]; sprintf (tmp,"%lu",mail_uid (stream,n)); return pop3_send (stream,command,tmp);}/* Post Office Protocol 3 send command * Accepts: MAIL stream * command * command argument * Returns: T if successful, NIL if failure */long pop3_send (MAILSTREAM *stream,char *command,char *args){ long ret; char *s = (char *) fs_get (strlen (command) + (args ? strlen (args) + 1: 0) + 3); mail_lock (stream); /* lock up the stream */ if (!LOCAL->netstream) ret = pop3_fake (stream,"POP3 connection lost"); else { /* build the complete command */ if (args) sprintf (s,"%s %s",command,args); else strcpy (s,command); if (stream->debug) mail_dlog (s,LOCAL->sensitive); strcat (s,"\015\012"); /* send the command */ ret = net_soutr (LOCAL->netstream,s) ? pop3_reply (stream) : pop3_fake (stream,"POP3 connection broken in command"); } fs_give ((void **) &s); mail_unlock (stream); /* unlock stream */ return ret;}/* Post Office Protocol 3 get reply * Accepts: MAIL stream * Returns: T if success reply, NIL if error reply */long pop3_reply (MAILSTREAM *stream){ char *s; /* flush old reply */ if (LOCAL->response) fs_give ((void **) &LOCAL->response); /* get reply */ if (!(LOCAL->response = net_getline (LOCAL->netstream))) return pop3_fake (stream,"POP3 connection broken in response"); if (stream->debug) mm_dlog (LOCAL->response); LOCAL->reply = (s = strchr (LOCAL->response,' ')) ? s + 1 : LOCAL->response; /* return success or failure */ return (*LOCAL->response =='+') ? T : NIL;}/* Post Office Protocol 3 set fake error * Accepts: MAIL stream * error text * Returns: NIL, always */long pop3_fake (MAILSTREAM *stream,char *text){ mm_notify (stream,text,BYE); /* send bye alert */ if (LOCAL->netstream) net_close (LOCAL->netstream); LOCAL->netstream = NIL; /* farewell, dear TCP stream */ /* flush any old reply */ if (LOCAL->response) fs_give ((void **) &LOCAL->response); LOCAL->reply = text; /* set up pseudo-reply string */ return NIL; /* return error code */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -