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

📄 mx.c

📁 这是用C编写IMAP源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Program:	MX mail routines * * Author(s):	Mark Crispin *		Networks and Distributed Computing *		Computing & Communications *		University of Washington *		Administration Building, AG-44 *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	3 May 1996 * Last Edited:	4 November 2004 *  * The IMAP toolkit provided in this Distribution is * Copyright 1988-2004 University of Washington. * The full text of our legal notices is contained in the file called * CPYRIGHT, included with this Distribution. */#include <stdio.h>#include <ctype.h>#include <errno.h>extern int errno;		/* just in case */#include "mail.h"#include "osdep.h"#include <pwd.h>#include <sys/stat.h>#include <sys/time.h>#include "mx.h"#include "misc.h"#include "dummy.h"/* MX I/O stream local data */	typedef struct mx_local {  int fd;			/* file descriptor of open index */  char *dir;			/* spool directory name */  unsigned char *buf;		/* temporary buffer */  unsigned long buflen;		/* current size of temporary buffer */  unsigned long cachedtexts;	/* total size of all cached texts */  time_t scantime;		/* last time directory scanned */} MXLOCAL;/* Convenient access to local data */#define LOCAL ((MXLOCAL *) stream->local)/* Function prototypes */DRIVER *mx_valid (char *name);int mx_isvalid (char *name,char *tmp);void *mx_parameters (long function,void *value);void mx_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);void mx_list (MAILSTREAM *stream,char *ref,char *pat);void mx_lsub (MAILSTREAM *stream,char *ref,char *pat);void mx_list_work (MAILSTREAM *stream,char *dir,char *pat,long level);long mx_subscribe (MAILSTREAM *stream,char *mailbox);long mx_unsubscribe (MAILSTREAM *stream,char *mailbox);long mx_create (MAILSTREAM *stream,char *mailbox);long mx_delete (MAILSTREAM *stream,char *mailbox);long mx_rename (MAILSTREAM *stream,char *old,char *newname);MAILSTREAM *mx_open (MAILSTREAM *stream);void mx_close (MAILSTREAM *stream,long options);void mx_fast (MAILSTREAM *stream,char *sequence,long flags);char *mx_fast_work (MAILSTREAM *stream,MESSAGECACHE *elt);char *mx_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,		 long flags);long mx_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);void mx_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags);void mx_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt);long mx_ping (MAILSTREAM *stream);void mx_check (MAILSTREAM *stream);void mx_expunge (MAILSTREAM *stream);long mx_copy (MAILSTREAM *stream,char *sequence,char *mailbox,	      long options);long mx_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);int mx_numsort (const void *d1,const void *d2);char *mx_file (char *dst,char *name);long mx_lockindex (MAILSTREAM *stream);void mx_unlockindex (MAILSTREAM *stream);void mx_setdate (char *file,MESSAGECACHE *elt);/* MX mail routines *//* Driver dispatch used by MAIL */DRIVER mxdriver = {  "mx",				/* driver name */				/* driver flags */  DR_MAIL|DR_LOCAL|DR_NOFAST|DR_CRLF|DR_LOCKING,  (DRIVER *) NIL,		/* next driver */  mx_valid,			/* mailbox is valid for us */  mx_parameters,		/* manipulate parameters */  mx_scan,			/* scan mailboxes */  mx_list,			/* find mailboxes */  mx_lsub,			/* find subscribed mailboxes */  mx_subscribe,			/* subscribe to mailbox */  mx_unsubscribe,		/* unsubscribe from mailbox */  mx_create,			/* create mailbox */  mx_delete,			/* delete mailbox */  mx_rename,			/* rename mailbox */  mail_status_default,		/* status of mailbox */  mx_open,			/* open mailbox */  mx_close,			/* close mailbox */  mx_fast,			/* fetch message "fast" attributes */  NIL,				/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message envelopes */  mx_header,			/* fetch message header only */  mx_text,			/* fetch message body only */  NIL,				/* fetch partial message test */  NIL,				/* unique identifier */  NIL,				/* message number */  mx_flag,			/* modify flags */  mx_flagmsg,			/* per-message modify flags */  NIL,				/* search for message based on criteria */  NIL,				/* sort messages */  NIL,				/* thread messages */  mx_ping,			/* ping mailbox to see if still alive */  mx_check,			/* check for new messages */  mx_expunge,			/* expunge deleted messages */  mx_copy,			/* copy messages to another mailbox */  mx_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM mxproto = {&mxdriver};/* MX mail validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *mx_valid (char *name){  char tmp[MAILTMPLEN];  return mx_isvalid (name,tmp) ? &mxdriver : NIL;}/* MX mail test for valid mailbox * Accepts: mailbox name *	    temporary buffer to use * Returns: T if valid, NIL otherwise */int mx_isvalid (char *name,char *tmp){  struct stat sbuf;  errno = NIL;			/* zap error */				/* validate name as directory */  return (!stat (MXINDEX (tmp,name),&sbuf) &&	  ((sbuf.st_mode & S_IFMT) == S_IFREG));}/* MX manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *mx_parameters (long function,void *value){  return NIL;}/* MX scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void mx_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  if (stream) MM_LOG ("Scan not valid for mx mailboxes",ERROR);}/* MX list mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mx_list (MAILSTREAM *stream,char *ref,char *pat){  char *s,test[MAILTMPLEN],file[MAILTMPLEN];  long i = 0;				/* get canonical form of name */  if (stream && dummy_canonicalize (test,ref,pat)) {				/* found any wildcards? */    if (s = strpbrk (test,"%*")) {				/* yes, copy name up to that point */      strncpy (file,test,i = s - test);      file[i] = '\0';		/* tie off */    }    else strcpy (file,test);	/* use just that name then */				/* find directory name */    if (s = strrchr (file,'/')) {      *s = '\0';		/* found, tie off at that point */      s = file;    }				/* do the work */    mx_list_work (stream,s,test,0);  }}/* MX list subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mx_lsub (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_lsub (NIL,ref,pat);}/* MX list mailboxes worker routine * Accepts: mail stream *	    directory name to search *	    search pattern *	    search level */void mx_list_work (MAILSTREAM *stream,char *dir,char *pat,long level){  DIR *dp;  struct direct *d;  struct stat sbuf;  char *cp,*np,curdir[MAILTMPLEN],name[MAILTMPLEN];  if (dir && *dir) {		/* make mailbox and directory names */    sprintf (name,"%s/",dir);	/* print name starts at directory */    mx_file (curdir,dir);	/* path starts from mx_file() name */  }  else {			/* no directory, use mailbox home dir */    mx_file (curdir,mailboxdir (name,NIL,NIL));    name[0] = '\0';		/* dummy name */  }  if (dp = opendir (curdir)) {	/* open directory */    np = name + strlen (name);    cp = curdir + strlen (strcat (curdir,"/"));    while (d = readdir (dp)) {	/* scan, ignore . and numeric names */      if ((d->d_name[0] != '.') && !mx_select (d)) {	if (level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL)) {	  strcpy (cp,d->d_name);/* make directory name */	  strcpy (np,d->d_name);/* make mx name of directory name */	  if (dmatch (name,pat,'/') && !stat (curdir,&sbuf) &&	      ((sbuf.st_mode &= S_IFMT) == S_IFDIR))	    mx_list_work (stream,name,pat,level+1);	}      }      else if (!strcmp (d->d_name,MXINDEXNAME+1) && pmatch_full (dir,pat,'/'))	mm_list (stream,'/',dir,NIL);    }    closedir (dp);		/* all done, flush directory */  }}/* MX mail subscribe to mailbox * Accepts: mail stream *	    mailbox to add to subscription list * Returns: T on success, NIL on failure */long mx_subscribe (MAILSTREAM *stream,char *mailbox){  return sm_subscribe (mailbox);}/* MX mail unsubscribe to mailbox * Accepts: mail stream *	    mailbox to delete from subscription list * Returns: T on success, NIL on failure */long mx_unsubscribe (MAILSTREAM *stream,char *mailbox){  return sm_unsubscribe (mailbox);}/* MX mail create mailbox * Accepts: mail stream *	    mailbox name to create * Returns: T on success, NIL on failure */long mx_create (MAILSTREAM *stream,char *mailbox){  int fd;  char *s,tmp[MAILTMPLEN],mbx[MAILTMPLEN];				/* assume error */  sprintf (tmp,"Can't create mailbox %.80s: invalid MX-format name",mailbox);				/* make sure valid name */  for (s = mailbox; s && *s;) {    if (isdigit (*s)) s++;	/* digit, check this node further... */				/* all digit node, barf */    else if (*s == '/') s = NIL;				/* non-digit in node, skip to next node */    else if (s = strchr (s+1,'/')) s++;    else tmp[0] = NIL;		/* no more nodes, good name */  }  if (tmp[0]);			/* was there an error in the name? */				/* must not already exist */  else if (mx_isvalid (mailbox,tmp))    sprintf (tmp,"Can't create mailbox %.80s: mailbox already exists",mailbox);				/* create directory */  else if (!dummy_create_path (stream,strcat (mx_file (mbx,mailbox),"/"),			       get_dir_protection (mailbox)))    sprintf (tmp,"Can't create mailbox leaf %.80s: %s",	     mailbox,strerror (errno));  else {			/* create index file */    int mask = umask (0);    if (((fd = open (MXINDEX (tmp,mailbox),O_WRONLY|O_CREAT|O_EXCL,		     (int) mail_parameters (NIL,GET_MBXPROTECTION,mailbox)))<0)	|| close (fd))      sprintf (tmp,"Can't create mailbox index %.80s: %s",	       mailbox,strerror (errno));	    else {			/* success */      set_mbx_protections (mailbox,mbx);      set_mbx_protections (mailbox,tmp);      tmp[0] = NIL;    }    umask (mask);		/* restore mask */  }  if (!tmp[0]) return LONGT;	/* success */  MM_LOG (tmp,ERROR);		/* some error */  return NIL;}/* MX mail delete mailbox *	    mailbox name to delete * Returns: T on success, NIL on failure */long mx_delete (MAILSTREAM *stream,char *mailbox){  DIR *dirp;  struct direct *d;  char *s;  char tmp[MAILTMPLEN];  if (!mx_isvalid (mailbox,tmp))    sprintf (tmp,"Can't delete mailbox %.80s: no such mailbox",mailbox);				/* delete index */  else if (unlink (MXINDEX (tmp,mailbox)))    sprintf (tmp,"Can't delete mailbox %.80s index: %s",	     mailbox,strerror (errno));  else {			/* get directory name */    *(s = strrchr (tmp,'/')) = '\0';    if (dirp = opendir (tmp)) {	/* open directory */      *s++ = '/';		/* restore delimiter */				/* massacre messages */      while (d = readdir (dirp)) if (mx_select (d)) {	strcpy (s,d->d_name);	/* make path */	unlink (tmp);		/* sayonara */      }      closedir (dirp);		/* flush directory */    }				/* try to remove the directory */    if (rmdir (mx_file (tmp,mailbox))) {      sprintf (tmp,"Can't delete name %.80s: %s",mailbox,strerror (errno));      mm_log (tmp,WARN);    }    return T;			/* always success */  }  MM_LOG (tmp,ERROR);		/* something failed */  return NIL;}

⌨️ 快捷键说明

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