⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imap4r1.c

📁 SIP 1.5.0源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Program:	Interactive Message Access Protocol 4rev1 (IMAP4R1) 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:	15 June 1988 * Last Edited:	13 October 2000 * * Sponsorship:	The original version of this work was developed in the *		Symbolic Systems Resources Group of the Knowledge Systems *		Laboratory at Stanford University in 1987-88, and was funded *		by the Biomedical Research Technology Program of the National *		Institutes of Health under grant number RR-00785. * * Original version Copyright 1988 by The Leland Stanford Junior University * Copyright 2000 by the University of Washington * *  Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notices appear in all copies and that both the * above copyright notices and this permission notice appear in supporting * documentation, and that the name of the University of Washington or The * Leland Stanford Junior University not be used in advertising or publicity * pertaining to distribution of the software without specific, written prior * permission.  This software is made available "as is", and * THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY * DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF * WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */#include <ctype.h>#include <stdio.h>#include <time.h>#include "mail.h"#include "osdep.h"#include "imap4r1.h"#include "rfc822.h"#include "misc.h"/* Driver dispatch used by MAIL */DRIVER imapdriver = {  "imap",			/* driver name */				/* driver flags */  DR_MAIL|DR_NEWS|DR_NAMESPACE|DR_CRLF|DR_RECYCLE,  (DRIVER *) NIL,		/* next driver */  imap_valid,			/* mailbox is valid for us */  imap_parameters,		/* manipulate parameters */  imap_scan,			/* scan mailboxes */  imap_list,			/* find mailboxes */  imap_lsub,			/* find subscribed mailboxes */  imap_subscribe,		/* subscribe to mailbox */  imap_unsubscribe,		/* unsubscribe from mailbox */  imap_create,			/* create mailbox */  imap_delete,			/* delete mailbox */  imap_rename,			/* rename mailbox */  imap_status,			/* status of mailbox */  imap_open,			/* open mailbox */  imap_close,			/* close mailbox */  imap_fast,			/* fetch message "fast" attributes */  imap_flags,			/* fetch message flags */  imap_overview,		/* fetch overview */  imap_structure,		/* fetch message envelopes */  NIL,				/* fetch message header */  NIL,				/* fetch message body */  imap_msgdata,			/* fetch partial message */  imap_uid,			/* unique identifier */  imap_msgno,			/* message number */  imap_flag,			/* modify flags */  NIL,				/* per-message modify flags */  imap_search,			/* search for message based on criteria */  imap_sort,			/* sort messages */  imap_thread,			/* thread messages */  imap_ping,			/* ping mailbox to see if still alive */  imap_check,			/* check for new messages */  imap_expunge,			/* expunge deleted messages */  imap_copy,			/* copy messages to another mailbox */  imap_append,			/* append string message to mailbox */  imap_gc			/* garbage collect stream */};				/* prototype stream */MAILSTREAM imapproto = {&imapdriver};				/* driver parameters */static unsigned long imap_maxlogintrials = MAXLOGINTRIALS;static long imap_lookahead = IMAPLOOKAHEAD;static long imap_uidlookahead = IMAPUIDLOOKAHEAD;static long imap_defaultport = 0;static long imap_altport = 0;static char *imap_altname = NIL;static long imap_prefetch = IMAPLOOKAHEAD;static long imap_closeonerror = NIL;static imapenvelope_t imap_envelope = NIL;static imapreferral_t imap_referral = NIL;static char *imap_extrahdrs = NIL;				/* constants */static char *hdrheader = "BODY.PEEK[HEADER.FIELDS (Path Message-ID";static char *hdrtrailer ="Newsgroups Followup-To References)]";static char *allheader = "(UID ENVELOPE";static char *fasttrailer = "INTERNALDATE RFC822.SIZE FLAGS)";/* Append data */typedef struct append_data {  append_t af;  void *data;} APPENDDATA;/* IMAP validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *imap_valid (char *name){  return mail_valid_net (name,&imapdriver,NIL,NIL);}/* IMAP manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *imap_parameters (long function,void *value){  switch ((int) function) {  case SET_NAMESPACE:    fatal ("SET_NAMESPACE not permitted");  case GET_NAMESPACE:    if (((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->use.namespace &&	!((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->namespace)      imap_send (((MAILSTREAM *) value),"NAMESPACE",NIL);    value = (void *) &((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->namespace;    break;  case GET_THREADERS:    value = (void *) ((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->threader;    break;  case SET_MAXLOGINTRIALS:    imap_maxlogintrials = (long) value;    break;  case GET_MAXLOGINTRIALS:    value = (void *) imap_maxlogintrials;    break;  case SET_LOOKAHEAD:    imap_lookahead = (long) value;    break;  case GET_LOOKAHEAD:    value = (void *) imap_lookahead;    break;  case SET_UIDLOOKAHEAD:    imap_uidlookahead = (long) value;    break;  case GET_UIDLOOKAHEAD:    value = (void *) imap_uidlookahead;    break;  case SET_IMAPPORT:    imap_defaultport = (long) value;    break;  case GET_IMAPPORT:    value = (void *) imap_defaultport;    break;  case SET_ALTIMAPPORT:    imap_altport = (long) value;    break;  case GET_ALTIMAPPORT:    value = (void *) imap_altport;    break;  case SET_ALTIMAPNAME:    imap_altname = (char *) value;    break;  case GET_ALTIMAPNAME:    value = (void *) imap_altname;    break;  case SET_PREFETCH:    imap_prefetch = (long) value;    break;  case GET_PREFETCH:    value = (void *) imap_prefetch;    break;  case SET_CLOSEONERROR:    imap_closeonerror = (long) value;    break;  case GET_CLOSEONERROR:    value = (void *) imap_closeonerror;    break;  case SET_IMAPENVELOPE:    imap_envelope = (imapenvelope_t) value;    break;  case GET_IMAPENVELOPE:    value = (void *) imap_envelope;    break;  case SET_IMAPREFERRAL:    imap_referral = (imapreferral_t) value;    break;  case GET_IMAPREFERRAL:    value = (void *) imap_referral;    break;  case SET_IMAPEXTRAHEADERS:    imap_extrahdrs = (char *) value;    break;  case GET_IMAPEXTRAHEADERS:    value = (void *) imap_extrahdrs;    break;  default:    value = NIL;		/* error case */    break;  }  return value;}/* IMAP scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void imap_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  imap_list_work (stream,"SCAN",ref,pat,contents);}/* IMAP list mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void imap_list (MAILSTREAM *stream,char *ref,char *pat){  imap_list_work (stream,"LIST",ref,pat,NIL);}/* IMAP list subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void imap_lsub (MAILSTREAM *stream,char *ref,char *pat){  void *sdb = NIL;  char *s,mbx[MAILTMPLEN];				/* do it on the server */  imap_list_work (stream,"LSUB",ref,pat,NIL);  if (*pat == '{') {		/* if remote pattern, must be IMAP */    if (!imap_valid (pat)) return;    ref = NIL;			/* good IMAP pattern, punt reference */  }				/* if remote reference, must be valid IMAP */  if (ref && (*ref == '{') && !imap_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 (imap_valid (s) && pmatch (s,mbx))    mm_lsub (stream,NIL,s,NIL);  while (s = sm_read (&sdb));	/* until no more subscriptions */}/* IMAP find list of mailboxes * Accepts: mail stream *	    list command *	    reference *	    pattern to search *	    string to scan */void imap_list_work (MAILSTREAM *stream,char *cmd,char *ref,char *pat,		     char *contents){  MAILSTREAM *st = stream;  int pl;  char *s,prefix[MAILTMPLEN],mbx[MAILTMPLEN];  IMAPARG *args[4],aref,apat,acont;  if (ref && *ref) {		/* have a reference? */    if (!(imap_valid (ref) &&	/* make sure valid IMAP name and open stream */	  ((stream && LOCAL && LOCAL->netstream) ||	   (stream = mail_open (NIL,ref,OP_HALFOPEN|OP_SILENT))))) return;				/* calculate prefix length */    pl = strchr (ref,'}') + 1 - ref;    strncpy (prefix,ref,pl);	/* build prefix */    prefix[pl] = '\0';		/* tie off prefix */    ref += pl;			/* update reference */  }  else {    if (!(imap_valid (pat) &&	/* make sure valid IMAP name and open stream */	  ((stream && LOCAL && LOCAL->netstream) ||	   (stream = mail_open (NIL,pat,OP_HALFOPEN|OP_SILENT))))) return;				/* calculate prefix length */    pl = strchr (pat,'}') + 1 - pat;    strncpy (prefix,pat,pl);	/* build prefix */    prefix[pl] = '\0';		/* tie off prefix */    pat += pl;			/* update reference */  }  LOCAL->prefix = prefix;	/* note prefix */  if (contents) {		/* want to do a scan? */    if (LEVELSCAN (stream)) {	/* make sure permitted */      args[0] = &aref; args[1] = &apat; args[2] = &acont; args[3] = NIL;      aref.type = ASTRING; aref.text = (void *) (ref ? ref : "");      apat.type = LISTMAILBOX; apat.text = (void *) pat;      acont.type = ASTRING; acont.text = (void *) contents;      imap_send (stream,cmd,args);    }    else mm_log ("Scan not valid on this IMAP server",ERROR);  }  else if (LEVELIMAP4 (stream)){/* easy if IMAP4 */    args[0] = &aref; args[1] = &apat; args[2] = NIL;    aref.type = ASTRING; aref.text = (void *) (ref ? ref : "");    apat.type = LISTMAILBOX; apat.text = (void *) pat;				/* referrals armed? */    if (LOCAL->use.mbx_ref && mail_parameters (stream,GET_IMAPREFERRAL,NIL) &&      ((cmd[0] == 'L') || (cmd[0] == 'l')) && !cmd[4]) {				/* yes, convert LIST -> RLIST */      if (((cmd[1] == 'I') || (cmd[1] == 'i')) &&	  ((cmd[2] == 'S') || (cmd[1] == 's')) &&	  ((cmd[3] == 'T') || (cmd[3] == 't'))) cmd = "RLIST";				/* and convert LSUB -> RLSUB */      else if (((cmd[1] == 'S') || (cmd[1] == 's')) &&	       ((cmd[2] == 'U') || (cmd[1] == 'u')) &&	       ((cmd[3] == 'B') || (cmd[3] == 'b'))) cmd = "RLSUB";    }    imap_send (stream,cmd,args);  }  else if (LEVEL1176 (stream)) {/* convert to IMAP2 format wildcard */				/* kludgy application of reference */    if (ref && *ref) sprintf (mbx,"%s%s",ref,pat);    else strcpy (mbx,pat);    for (s = mbx; *s; s++) if (*s == '%') *s = '*';    args[0] = &apat; args[1] = NIL;    apat.type = LISTMAILBOX; apat.text = (void *) mbx;    if (!(strstr (cmd,"LIST") &&/* if list, try IMAP2bis, then RFC-1176 */	  strcmp (imap_send (stream,"FIND ALL.MAILBOXES",args)->key,"BAD")) &&	!strcmp (imap_send (stream,"FIND MAILBOXES",args)->key,"BAD"))      LOCAL->rfc1176 = NIL;	/* must be RFC-1064 */  }  LOCAL->prefix = NIL;		/* no more prefix */				/* close temporary stream if we made one */  if (stream != st) mail_close (stream);}/* IMAP subscribe to mailbox * Accepts: mail stream *	    mailbox to add to subscription list * Returns: T on success, NIL on failure */long imap_subscribe (MAILSTREAM *stream,char *mailbox){  MAILSTREAM *st = stream;  long ret = ((stream && LOCAL && LOCAL->netstream) ||	      (stream = mail_open (NIL,mailbox,OP_HALFOPEN|OP_SILENT))) ?		imap_manage (stream,mailbox,LEVELIMAP4 (stream) ?			     "Subscribe" : "Subscribe Mailbox",NIL) : NIL;				/* toss out temporary stream */  if (st != stream) mail_close (stream);  return ret;}/* IMAP unsubscribe to mailbox

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -