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

📄 mail.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ======================================================================== * Copyright 1988-2008 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:	Mailbox Access routines * * Author:	Mark Crispin *		UW Technology *		University of Washington *		Seattle, WA  98195 *		Internet: MRC@Washington.EDU * * Date:	22 November 1989 * Last Edited:	15 April 2008 */#include <ctype.h>#include <stdio.h>#include <time.h>#include "c-client.h"char *UW_copyright = "Copyright 1988-2007 University of Washington\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n";/* c-client global data */				/* version of this library */static char *mailcclientversion = CCLIENTVERSION;				/* list of mail drivers */static DRIVER *maildrivers = NIL;				/* list of authenticators */static AUTHENTICATOR *mailauthenticators = NIL;				/* SSL driver pointer */static NETDRIVER *mailssldriver = NIL;				/* pointer to alternate gets function */static mailgets_t mailgets = NIL;				/* pointer to read progress function */static readprogress_t mailreadprogress = NIL;				/* mail cache manipulation function */static mailcache_t mailcache = mm_cache;				/* RFC-822 output generator */static rfc822out_t mail822out = NIL;				/* RFC-822 output generator (new style) */static rfc822outfull_t mail822outfull = NIL;				/* SMTP verbose callback */static smtpverbose_t mailsmtpverbose = mm_dlog;				/* proxy copy routine */static mailproxycopy_t mailproxycopy = NIL;				/* RFC-822 external line parse */static parseline_t mailparseline = NIL;				/* RFC-822 external phrase parser */static parsephrase_t mailparsephrase = NIL;static kinit_t mailkinit = NIL;	/* application kinit callback */				/* note network sent command */static sendcommand_t mailsendcommand = NIL;				/* newsrc file name decision function */static newsrcquery_t mailnewsrcquery = NIL;				/* ACL results callback */static getacl_t mailaclresults = NIL;				/* list rights results callback */static listrights_t maillistrightsresults = NIL;				/* my rights results callback */static myrights_t mailmyrightsresults = NIL;				/* quota results callback */static quota_t mailquotaresults = NIL;				/* quota root results callback */static quotaroot_t mailquotarootresults = NIL;				/* sorted results callback */static sortresults_t mailsortresults = NIL;				/* threaded results callback */static threadresults_t mailthreadresults = NIL;				/* COPY UID results */static copyuid_t mailcopyuid = NIL;				/* APPEND UID results */static appenduid_t mailappenduid = NIL;				/* free elt extra stuff callback */static freeeltsparep_t mailfreeeltsparep = NIL;				/* free envelope extra stuff callback */static freeenvelopesparep_t mailfreeenvelopesparep = NIL;				/* free body extra stuff callback */static freebodysparep_t mailfreebodysparep = NIL;				/* free stream extra stuff callback */static freestreamsparep_t mailfreestreamsparep = NIL;				/* SSL start routine */static sslstart_t mailsslstart = NIL;				/* SSL certificate query */static sslcertificatequery_t mailsslcertificatequery = NIL;				/* SSL client certificate */static sslclientcert_t mailsslclientcert = NIL;				/* SSL client private key */static sslclientkey_t mailsslclientkey = NIL;				/* SSL failure notify */static sslfailure_t mailsslfailure = NIL;				/* snarf interval */static long mailsnarfinterval = 60;				/* snarf preservation */static long mailsnarfpreserve = NIL;				/* newsrc name uses canonical host */static long mailnewsrccanon = LONGT;				/* supported threaders */static THREADER mailthreadordsub = {  "ORDEREDSUBJECT",mail_thread_orderedsubject,NIL};static THREADER mailthreadlist = {  "REFERENCES",mail_thread_references,&mailthreadordsub};				/* server name */static char *servicename = "unknown";				/* server externally-set authentication ID */static char *externalauthid = NIL;static int expungeatping = T;	/* mail_ping() may call mm_expunged() */static int trysslfirst = NIL;	/* always try SSL first */static int notimezones = NIL;	/* write timezones in "From " header */static int trustdns = T;	/* do DNS canonicalization */static int saslusesptrname = T;	/* SASL uses name from DNS PTR lookup */				/* trustdns also must be set */static int debugsensitive = NIL;/* debug telemetry includes sensitive data *//* Default mail cache handler * Accepts: pointer to cache handle *	    message number *	    caching function * Returns: cache data */void *mm_cache (MAILSTREAM *stream,unsigned long msgno,long op){  size_t n;  void *ret = NIL;  unsigned long i;  switch ((int) op) {		/* what function? */  case CH_INIT:			/* initialize cache */    if (stream->cache) {	/* flush old cache contents */      while (stream->cachesize) {	mm_cache (stream,stream->cachesize,CH_FREE);	mm_cache (stream,stream->cachesize--,CH_FREESORTCACHE);      }      fs_give ((void **) &stream->cache);      fs_give ((void **) &stream->sc);      stream->nmsgs = 0;	/* can't have any messages now */    }    break;  case CH_SIZE:			/* (re-)size the cache */    if (!stream->cache)	{	/* have a cache already? */				/* no, create new cache */      n = (stream->cachesize = msgno + CACHEINCREMENT) * sizeof (void *);      stream->cache = (MESSAGECACHE **) memset (fs_get (n),0,n);      stream->sc = (SORTCACHE **) memset (fs_get (n),0,n);    }				/* is existing cache size large neough */    else if (msgno > stream->cachesize) {      i = stream->cachesize;	/* remember old size */      n = (stream->cachesize = msgno + CACHEINCREMENT) * sizeof (void *);      fs_resize ((void **) &stream->cache,n);      fs_resize ((void **) &stream->sc,n);      while (i < stream->cachesize) {	stream->cache[i] = NIL;	stream->sc[i++] = NIL;      }    }    break;  case CH_MAKEELT:		/* return elt, make if necessary */    if (!stream->cache[msgno - 1])      stream->cache[msgno - 1] = mail_new_cache_elt (msgno);				/* falls through */  case CH_ELT:			/* return elt */    ret = (void *) stream->cache[msgno - 1];    break;  case CH_SORTCACHE:		/* return sortcache entry, make if needed */    if (!stream->sc[msgno - 1]) stream->sc[msgno - 1] =      (SORTCACHE *) memset (fs_get (sizeof (SORTCACHE)),0,sizeof (SORTCACHE));    ret = (void *) stream->sc[msgno - 1];    break;  case CH_FREE:			/* free elt */    mail_free_elt (&stream->cache[msgno - 1]);    break;  case CH_FREESORTCACHE:    if (stream->sc[msgno - 1]) {      if (stream->sc[msgno - 1]->from)	fs_give ((void **) &stream->sc[msgno - 1]->from);      if (stream->sc[msgno - 1]->to)	fs_give ((void **) &stream->sc[msgno - 1]->to);      if (stream->sc[msgno - 1]->cc)	fs_give ((void **) &stream->sc[msgno - 1]->cc);      if (stream->sc[msgno - 1]->subject)	fs_give ((void **) &stream->sc[msgno - 1]->subject);      if (stream->sc[msgno - 1]->unique &&	  (stream->sc[msgno - 1]->unique != stream->sc[msgno - 1]->message_id))	fs_give ((void **) &stream->sc[msgno - 1]->unique);      if (stream->sc[msgno - 1]->message_id)	fs_give ((void **) &stream->sc[msgno - 1]->message_id);      if (stream->sc[msgno - 1]->references)	mail_free_stringlist (&stream->sc[msgno - 1]->references);      fs_give ((void **) &stream->sc[msgno - 1]);    }    break;  case CH_EXPUNGE:		/* expunge cache slot */    for (i = msgno - 1; msgno < stream->nmsgs; i++,msgno++) {      if (stream->cache[i] = stream->cache[msgno])	stream->cache[i]->msgno = msgno;      stream->sc[i] = stream->sc[msgno];    }    stream->cache[i] = NIL;	/* top of cache goes away */    stream->sc[i] = NIL;    break;  default:    fatal ("Bad mm_cache op");    break;  }  return ret;}/* Dummy string driver for complete in-memory strings */static void mail_string_init (STRING *s,void *data,unsigned long size);static char mail_string_next (STRING *s);static void mail_string_setpos (STRING *s,unsigned long i);STRINGDRIVER mail_string = {  mail_string_init,		/* initialize string structure */  mail_string_next,		/* get next byte in string structure */  mail_string_setpos		/* set position in string structure */};/* Initialize mail string structure for in-memory string * Accepts: string structure *	    pointer to string *	    size of string */static void mail_string_init (STRING *s,void *data,unsigned long size){				/* set initial string pointers */  s->chunk = s->curpos = (char *) (s->data = data);				/* and sizes */  s->size = s->chunksize = s->cursize = size;  s->data1 = s->offset = 0;	/* never any offset */}/* Get next character from string * Accepts: string structure * Returns: character, string structure chunk refreshed */static char mail_string_next (STRING *s){  return *s->curpos++;		/* return the last byte */}/* Set string pointer position * Accepts: string structure *	    new position */static void mail_string_setpos (STRING *s,unsigned long i){  s->curpos = s->chunk + i;	/* set new position */  s->cursize = s->chunksize - i;/* and new size */}/* Mail routines * *  mail_xxx routines are the interface between this module and the outside * world.  Only these routines should be referenced by external callers. * *  Note that there is an important difference between a "sequence" and a * "message #" (msgno).  A sequence is a string representing a sequence in * {"n", "n:m", or combination separated by commas} format, whereas a msgno * is a single integer. * *//* Mail version check * Accepts: version */void mail_versioncheck (char *version){				/* attempt to protect again wrong .h */  if (strcmp (version,mailcclientversion)) {    char tmp[MAILTMPLEN];    sprintf (tmp,"c-client library version skew, app=%.100s library=%.100s",	     version,mailcclientversion);    fatal (tmp);  }}/* Mail link driver * Accepts: driver to add to list */void mail_link (DRIVER *driver){  DRIVER **d = &maildrivers;  while (*d) d = &(*d)->next;	/* find end of list of drivers */  *d = driver;			/* put driver at the end */  driver->next = NIL;		/* this driver is the end of the list */}/* Mail manipulate driver parameters * Accepts: mail stream *	    function code *	    function-dependent value * Returns: function-dependent return value */void *mail_parameters (MAILSTREAM *stream,long function,void *value){  void *r,*ret = NIL;  DRIVER *d;  AUTHENTICATOR *a;  switch ((int) function) {  case SET_INBOXPATH:    fatal ("SET_INBOXPATH not permitted");  case GET_INBOXPATH:    if ((stream || (stream = mail_open (NIL,"INBOX",OP_PROTOTYPE))) &&	stream->dtb) ret = (*stream->dtb->parameters) (function,value);    break;  case SET_THREADERS:    fatal ("SET_THREADERS not permitted");  case GET_THREADERS:		/* use stream dtb instead of global */    ret = (stream && stream->dtb) ?				/* KLUDGE ALERT: note stream passed as value */      (*stream->dtb->parameters) (function,stream) : (void *) &mailthreadlist;    break;  case SET_NAMESPACE:    fatal ("SET_NAMESPACE not permitted");    break;  case SET_NEWSRC:		/* too late on open stream */    if (stream && stream->dtb && (stream != ((*stream->dtb->open) (NIL))))      fatal ("SET_NEWSRC not permitted");    else ret = env_parameters (function,value);    break;  case GET_NAMESPACE:  case GET_NEWSRC:		/* use stream dtb instead of environment */    ret = (stream && stream->dtb) ?				/* KLUDGE ALERT: note stream passed as value */      (*stream->dtb->parameters) (function,stream) :	env_parameters (function,value);    break;  case ENABLE_DEBUG:    fatal ("ENABLE_DEBUG not permitted");  case DISABLE_DEBUG:    fatal ("DISABLE_DEBUG not permitted");  case SET_DIRFMTTEST:    fatal ("SET_DIRFMTTEST not permitted");  case GET_DIRFMTTEST:    if (!(stream && stream->dtb &&	  (ret = (*stream->dtb->parameters) (function,NIL))))      fatal ("GET_DIRFMTTEST not permitted");    break;  case SET_DRIVERS:    fatal ("SET_DRIVERS not permitted");  case GET_DRIVERS:		/* always return global */    ret = (void *) maildrivers;    break;  case SET_DRIVER:    fatal ("SET_DRIVER not permitted");  case GET_DRIVER:    for (d = maildrivers; d && compare_cstring (d->name,(char *) value);	 d = d->next);    ret = (void *) d;    break;  case ENABLE_DRIVER:    for (d = maildrivers; d && compare_cstring (d->name,(char *) value);	 d = d->next);    if (ret = (void *) d) d->flags &= ~DR_DISABLE;    break;  case DISABLE_DRIVER:    for (d = maildrivers; d && compare_cstring (d->name,(char *) value);	 d = d->next);    if (ret = (void *) d) d->flags |= DR_DISABLE;    break;  case ENABLE_AUTHENTICATOR:    for (a = mailauthenticators;/* scan authenticators */	 a && compare_cstring (a->name,(char *) value); a = a->next);

⌨️ 快捷键说明

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