📄 pop3.c
字号:
/* ======================================================================== * Copyright 1988-2007 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * * ======================================================================== *//* * Program: Post Office Protocol 3 (POP3) client routines * * Author: Mark Crispin * Networks and Distributed Computing * Computing & Communications * University of Washington * Administration Building, AG-44 * Seattle, WA 98195 * Internet: MRC@CAC.Washington.EDU * * Date: 6 June 1994 * Last Edited: 4 April 2007 */#include <ctype.h>#include <stdio.h>#include <time.h>#include "c-client.h"#include "flstring.h"#include "netmsg.h"/* Parameters */#define POP3TCPPORT (long) 110 /* assigned TCP contact port */#define POP3SSLPORT (long) 995 /* assigned SSL TCP contact port */#define IDLETIMEOUT (long) 10 /* defined in RFC 1939 *//* POP3 I/O stream local data */ typedef struct pop3_local { NETSTREAM *netstream; /* TCP I/O stream */ char *response; /* last server reply */ char *reply; /* text of last server reply */ unsigned long cached; /* current cached message uid */ unsigned long hdrsize; /* current cached header size */ FILE *txt; /* current cached file descriptor */ struct { unsigned int capa : 1; /* server has CAPA, definitely new */ unsigned int expire : 1; /* server has EXPIRE */ unsigned int logindelay : 1;/* server has LOGIN-DELAY */ unsigned int stls : 1; /* server has STLS */ unsigned int pipelining : 1;/* server has PIPELINING */ unsigned int respcodes : 1; /* server has RESP-CODES */ unsigned int top : 1; /* server has TOP */ unsigned int uidl : 1; /* server has UIDL */ unsigned int user : 1; /* server has USER */ char *implementation; /* server implementation string */ long delaysecs; /* minimum time between login (neg variable) */ long expiredays; /* server-guaranteed minimum retention days */ /* supported authenticators */ unsigned int sasl : MAXAUTHENTICATORS; } cap; unsigned int sensitive : 1; /* sensitive data in progress */ unsigned int loser : 1; /* server is a loser */ unsigned int saslcancel : 1; /* SASL cancelled by protocol */} POP3LOCAL;/* Convenient access to local data */#define LOCAL ((POP3LOCAL *) stream->local)/* Function prototypes */DRIVER *pop3_valid (char *name);void *pop3_parameters (long function,void *value);void pop3_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);void pop3_list (MAILSTREAM *stream,char *ref,char *pat);void pop3_lsub (MAILSTREAM *stream,char *ref,char *pat);long pop3_subscribe (MAILSTREAM *stream,char *mailbox);long pop3_unsubscribe (MAILSTREAM *stream,char *mailbox);long pop3_create (MAILSTREAM *stream,char *mailbox);long pop3_delete (MAILSTREAM *stream,char *mailbox);long pop3_rename (MAILSTREAM *stream,char *old,char *newname);long pop3_status (MAILSTREAM *stream,char *mbx,long flags);MAILSTREAM *pop3_open (MAILSTREAM *stream);long pop3_capa (MAILSTREAM *stream,long flags);long pop3_auth (MAILSTREAM *stream,NETMBX *mb,char *pwd,char *usr);void *pop3_challenge (void *stream,unsigned long *len);long pop3_response (void *stream,char *s,unsigned long size);void pop3_close (MAILSTREAM *stream,long options);void pop3_fetchfast (MAILSTREAM *stream,char *sequence,long flags);char *pop3_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *size, long flags);long pop3_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);unsigned long pop3_cache (MAILSTREAM *stream,MESSAGECACHE *elt);long pop3_ping (MAILSTREAM *stream);void pop3_check (MAILSTREAM *stream);long pop3_expunge (MAILSTREAM *stream,char *sequence,long options);long pop3_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);long pop3_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);long pop3_send_num (MAILSTREAM *stream,char *command,unsigned long n);long pop3_send (MAILSTREAM *stream,char *command,char *args);long pop3_reply (MAILSTREAM *stream);long pop3_fake (MAILSTREAM *stream,char *text);/* POP3 mail routines *//* Driver dispatch used by MAIL */DRIVER pop3driver = { "pop3", /* driver name */ /* driver flags */#ifdef INADEQUATE_MEMORY DR_LOWMEM |#endif DR_MAIL|DR_NOFAST|DR_CRLF|DR_NOSTICKY|DR_NOINTDATE|DR_NONEWMAIL, (DRIVER *) NIL, /* next driver */ pop3_valid, /* mailbox is valid for us */ pop3_parameters, /* manipulate parameters */ pop3_scan, /* scan mailboxes */ pop3_list, /* find mailboxes */ pop3_lsub, /* find subscribed mailboxes */ pop3_subscribe, /* subscribe to mailbox */ pop3_unsubscribe, /* unsubscribe from mailbox */ pop3_create, /* create mailbox */ pop3_delete, /* delete mailbox */ pop3_rename, /* rename mailbox */ pop3_status, /* status of mailbox */ pop3_open, /* open mailbox */ pop3_close, /* close mailbox */ pop3_fetchfast, /* fetch message "fast" attributes */ NIL, /* fetch message flags */ NIL, /* fetch overview */ NIL, /* fetch message structure */ pop3_header, /* fetch message header */ pop3_text, /* fetch message text */ NIL, /* fetch message */ NIL, /* unique identifier */ NIL, /* message number from UID */ NIL, /* modify flags */ NIL, /* per-message modify flags */ NIL, /* search for message based on criteria */ NIL, /* sort messages */ NIL, /* thread messages */ pop3_ping, /* ping mailbox to see if still alive */ pop3_check, /* check for new messages */ pop3_expunge, /* expunge deleted messages */ pop3_copy, /* copy messages to another mailbox */ pop3_append, /* append string message to mailbox */ NIL /* garbage collect stream */}; /* prototype stream */MAILSTREAM pop3proto = {&pop3driver}; /* driver parameters */static unsigned long pop3_maxlogintrials = MAXLOGINTRIALS;static long pop3_port = 0;static long pop3_sslport = 0;/* POP3 mail validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *pop3_valid (char *name){ NETMBX mb; return (mail_valid_net_parse (name,&mb) && !strcmp (mb.service,pop3driver.name) && !mb.authuser[0] && !compare_cstring (mb.mailbox,"INBOX")) ? &pop3driver : NIL;}/* News manipulate driver parameters * Accepts: function code * function-dependent value * Returns: function-dependent return value */void *pop3_parameters (long function,void *value){ switch ((int) function) { case SET_MAXLOGINTRIALS: pop3_maxlogintrials = (unsigned long) value; break; case GET_MAXLOGINTRIALS: value = (void *) pop3_maxlogintrials; break; case SET_POP3PORT: pop3_port = (long) value; break; case GET_POP3PORT: value = (void *) pop3_port; break; case SET_SSLPOPPORT: pop3_sslport = (long) value; break; case GET_SSLPOPPORT: value = (void *) pop3_sslport; break; case GET_IDLETIMEOUT: value = (void *) IDLETIMEOUT; break; default: value = NIL; /* error case */ break; } return value;}/* POP3 mail scan mailboxes for string * Accepts: mail stream * reference * pattern to search * string to scan */void pop3_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){ char tmp[MAILTMPLEN]; if ((ref && *ref) ? /* have a reference */ (pop3_valid (ref) && pmatch ("INBOX",pat)) : (mail_valid_net (pat,&pop3driver,NIL,tmp) && pmatch ("INBOX",tmp))) mm_log ("Scan not valid for POP3 mailboxes",ERROR);}/* POP3 mail find list of all mailboxes * Accepts: mail stream * reference * pattern to search */void pop3_list (MAILSTREAM *stream,char *ref,char *pat){ char tmp[MAILTMPLEN]; if (ref && *ref) { /* have a reference */ if (pop3_valid (ref) && pmatch ("INBOX",pat)) { strcpy (strchr (strcpy (tmp,ref),'}')+1,"INBOX"); mm_list (stream,NIL,tmp,LATT_NOINFERIORS); } } else if (mail_valid_net (pat,&pop3driver,NIL,tmp) && pmatch ("INBOX",tmp)) { strcpy (strchr (strcpy (tmp,pat),'}')+1,"INBOX"); mm_list (stream,NIL,tmp,LATT_NOINFERIORS); }}/* POP3 mail find list of subscribed mailboxes * Accepts: mail stream * reference * pattern to search */void pop3_lsub (MAILSTREAM *stream,char *ref,char *pat){ void *sdb = NIL; char *s,mbx[MAILTMPLEN]; if (*pat == '{') { /* if remote pattern, must be POP3 */ if (!pop3_valid (pat)) return; ref = NIL; /* good POP3 pattern, punt reference */ } /* if remote reference, must be valid POP3 */ if (ref && (*ref == '{') && !pop3_valid (ref)) return; /* kludgy application of reference */ if (ref && *ref) sprintf (mbx,"%s%s",ref,pat); else strcpy (mbx,pat); if (s = sm_read (&sdb)) do if (pop3_valid (s) && pmatch (s,mbx)) mm_lsub (stream,NIL,s,NIL); while (s = sm_read (&sdb)); /* until no more subscriptions */}/* POP3 mail subscribe to mailbox * Accepts: mail stream * mailbox to add to subscription list * Returns: T on success, NIL on failure */long pop3_subscribe (MAILSTREAM *stream,char *mailbox){ return sm_subscribe (mailbox);}/* POP3 mail unsubscribe to mailbox * Accepts: mail stream * mailbox to delete from subscription list * Returns: T on success, NIL on failure */long pop3_unsubscribe (MAILSTREAM *stream,char *mailbox){ return sm_unsubscribe (mailbox);}/* POP3 mail create mailbox * Accepts: mail stream * mailbox name to create * Returns: T on success, NIL on failure */long pop3_create (MAILSTREAM *stream,char *mailbox){ return NIL; /* never valid for POP3 */}/* POP3 mail delete mailbox * mailbox name to delete * Returns: T on success, NIL on failure */long pop3_delete (MAILSTREAM *stream,char *mailbox){ return NIL; /* never valid for POP3 */}/* POP3 mail rename mailbox * Accepts: mail stream * old mailbox name * new mailbox name * Returns: T on success, NIL on failure */long pop3_rename (MAILSTREAM *stream,char *old,char *newname){ return NIL; /* never valid for POP3 */}/* POP3 status * Accepts: mail stream * mailbox name * status flags * Returns: T on success, NIL on failure */long pop3_status (MAILSTREAM *stream,char *mbx,long flags){ MAILSTATUS status; unsigned long i; long ret = NIL; MAILSTREAM *tstream = (stream && LOCAL->netstream && mail_usable_network_stream (stream,mbx)) ? stream : mail_open (NIL,mbx,OP_SILENT); if (tstream) { /* have a usable stream? */ status.flags = flags; /* return status values */ status.messages = tstream->nmsgs; status.recent = tstream->recent; if (flags & SA_UNSEEN) /* must search to get unseen messages */ for (i = 1,status.unseen = 0; i <= tstream->nmsgs; i++) if (!mail_elt (tstream,i)->seen) status.unseen++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -