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

📄 mix.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:	MIX mail routines * * Author(s):	Mark Crispin *		UW Technology *		University of Washington *		Seattle, WA  98195 *		Internet: MRC@Washington.EDU * * Date:	1 March 2006 * Last Edited:	7 May 2008 */#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 "misc.h"#include "dummy.h"#include "fdstring.h"/* MIX definitions */#define MEGABYTE (1024*1024)#define MIXDATAROLL MEGABYTE	/* size at which we roll to a new file *//* MIX files */#define MIXNAME ".mix"		/* prefix for all MIX file names */#define MIXMETA "meta"		/* suffix for metadata */#define MIXINDEX "index"	/* suffix for index */#define MIXSTATUS "status"	/* suffix for status */#define MIXSORTCACHE "sortcache"/* suffix for sortcache */#define METAMAX (MEGABYTE-1)	/* maximum metadata file size (sanity check) *//* MIX file formats */				/* sequence format (all but msg files) */#define SEQFMT "S%08lx\015\012"				/* metadata file format */#define MTAFMT "V%08lx\015\012L%08lx\015\012N%08lx\015\012"				/* index file record format */#define IXRFMT ":%08lx:%04d%02d%02d%02d%02d%02d%c%02d%02d:%08lx:%08lx:%08lx:%08lx:%08lx:\015\012"				/* status file record format */#define STRFMT ":%08lx:%08lx:%04x:%08lx:\015\012"				/* message file header format */#define MSRFMT "%s%08lx:%04d%02d%02d%02d%02d%02d%c%02d%02d:%08lx:\015\012"#define MSGTOK ":msg:"#define MSGTSZ (sizeof(MSGTOK)-1)				/* sortcache file record format */#define SCRFMT ":%08lx:%08lx:%08lx:%08lx:%08lx:%c%08lx:%08lx:%08lx:\015\012"/* MIX I/O stream local data */	typedef struct mix_local {  unsigned long curmsg;		/* current message file number */  unsigned long newmsg;		/* current new message file number */  time_t lastsnarf;		/* last snarf time */  int msgfd;			/* file description of current msg file */  int mfd;			/* file descriptor of open metadata */  unsigned long metaseq;	/* metadata sequence */  char *index;			/* mailbox index name */  unsigned long indexseq;	/* index sequence */  char *status;			/* mailbox status name */  unsigned long statusseq;	/* status sequence */  char *sortcache;		/* mailbox sortcache name */  unsigned long sortcacheseq;	/* sortcache sequence */  unsigned char *buf;		/* temporary buffer */  unsigned long buflen;		/* current size of temporary buffer */  unsigned int expok : 1;	/* non-zero if expunge reports OK */  unsigned int internal : 1;	/* internally opened, do not validate */} MIXLOCAL;#define MIXBURP struct mix_burpMIXBURP {  unsigned long fileno;		/* message file number */  char *name;			/* message file name */  SEARCHSET *tail;		/* tail of ranges */  SEARCHSET set;		/* set of retained ranges */  MIXBURP *next;		/* next file to burp */};/* Convenient access to local data */#define LOCAL ((MIXLOCAL *) stream->local)/* Function prototypes */DRIVER *mix_valid (char *name);long mix_isvalid (char *name,char *meta);void *mix_parameters (long function,void *value);long mix_dirfmttest (char *name);void mix_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);long mix_scan_contents (char *name,char *contents,unsigned long csiz,			unsigned long fsiz);void mix_list (MAILSTREAM *stream,char *ref,char *pat);void mix_lsub (MAILSTREAM *stream,char *ref,char *pat);long mix_subscribe (MAILSTREAM *stream,char *mailbox);long mix_unsubscribe (MAILSTREAM *stream,char *mailbox);long mix_create (MAILSTREAM *stream,char *mailbox);long mix_delete (MAILSTREAM *stream,char *mailbox);long mix_rename (MAILSTREAM *stream,char *old,char *newname);int mix_rselect (struct direct *name);MAILSTREAM *mix_open (MAILSTREAM *stream);void mix_close (MAILSTREAM *stream,long options);void mix_abort (MAILSTREAM *stream);char *mix_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,		  long flags);long mix_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);void mix_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags);unsigned long *mix_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg,			 SORTPGM *pgm,long flags);THREADNODE *mix_thread (MAILSTREAM *stream,char *type,char *charset,			SEARCHPGM *spg,long flags);long mix_ping (MAILSTREAM *stream);void mix_check (MAILSTREAM *stream);long mix_expunge (MAILSTREAM *stream,char *sequence,long options);int mix_select (struct direct *name);int mix_msgfsort (const void *d1,const void *d2);long mix_addset (SEARCHSET **set,unsigned long start,unsigned long size);long mix_burp (MAILSTREAM *stream,MIXBURP *burp,unsigned long *reclaimed);long mix_burp_check (SEARCHSET *set,size_t size,char *file);long mix_copy (MAILSTREAM *stream,char *sequence,char *mailbox,	       long options);long mix_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);long mix_append_msg (MAILSTREAM *stream,FILE *f,char *flags,MESSAGECACHE *delt,		     STRING *msg,SEARCHSET *set,unsigned long seq);FILE *mix_parse (MAILSTREAM *stream,FILE **idxf,long iflags,long sflags);char *mix_meta_slurp (MAILSTREAM *stream,unsigned long *seq);long mix_meta_update (MAILSTREAM *stream);long mix_index_update (MAILSTREAM *stream,FILE *idxf,long flag);long mix_status_update (MAILSTREAM *stream,FILE *statf,long flag);FILE *mix_data_open (MAILSTREAM *stream,int *fd,long *size,		     unsigned long newsize);FILE *mix_sortcache_open (MAILSTREAM *stream);long mix_sortcache_update (MAILSTREAM *stream,FILE **sortcache);char *mix_read_record (FILE *f,char *buf,unsigned long buflen,char *type);unsigned long mix_read_sequence (FILE *f);char *mix_dir (char *dst,char *name);char *mix_file (char *dst,char *dir,char *name);char *mix_file_data (char *dst,char *dir,unsigned long data);unsigned long mix_modseq (unsigned long oldseq);/* MIX mail routines *//* Driver dispatch used by MAIL */DRIVER mixdriver = {  "mix",			/* driver name */				/* driver flags */  DR_MAIL|DR_LOCAL|DR_NOFAST|DR_CRLF|DR_LOCKING|DR_DIRFMT|DR_MODSEQ,  (DRIVER *) NIL,		/* next driver */  mix_valid,			/* mailbox is valid for us */  mix_parameters,		/* manipulate parameters */  mix_scan,			/* scan mailboxes */  mix_list,			/* find mailboxes */  mix_lsub,			/* find subscribed mailboxes */  mix_subscribe,		/* subscribe to mailbox */  mix_unsubscribe,		/* unsubscribe from mailbox */  mix_create,			/* create mailbox */  mix_delete,			/* delete mailbox */  mix_rename,			/* rename mailbox */  mail_status_default,		/* status of mailbox */  mix_open,			/* open mailbox */  mix_close,			/* close mailbox */  NIL,				/* fetch message "fast" attributes */  NIL,				/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message envelopes */  mix_header,			/* fetch message header only */  mix_text,			/* fetch message body only */  NIL,				/* fetch partial message test */  NIL,				/* unique identifier */  NIL,				/* message number */  mix_flag,			/* modify flags */  NIL,				/* per-message modify flags */  NIL,				/* search for message based on criteria */  mix_sort,			/* sort messages */  mix_thread,			/* thread messages */  mix_ping,			/* ping mailbox to see if still alive */  mix_check,			/* check for new messages */  mix_expunge,			/* expunge deleted messages */  mix_copy,			/* copy messages to another mailbox */  mix_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM mixproto = {&mixdriver};/* MIX mail validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *mix_valid (char *name){  char tmp[MAILTMPLEN];  return mix_isvalid (name,tmp) ? &mixdriver : NIL;}/* MIX mail test for valid mailbox * Accepts: mailbox name *	    buffer to return meta name * Returns: T if valid, NIL otherwise, metadata name written in both cases */long mix_isvalid (char *name,char *meta){  char dir[MAILTMPLEN];  struct stat sbuf;				/* validate name as directory */  if (!(errno = ((strlen (name) > NETMAXMBX) ? ENAMETOOLONG : NIL)) &&      *mix_dir (dir,name) && mix_file (meta,dir,MIXMETA) &&      !stat (dir,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFDIR)) {				/* name is directory; is it mix? */    if (!stat (meta,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFREG))      return LONGT;    else errno = NIL;		/* directory but not mix */  }  return NIL;}/* MIX manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *mix_parameters (long function,void *value){  void *ret = NIL;  switch ((int) function) {  case GET_INBOXPATH:    if (value) ret = mailboxfile ((char *) value,"~/INBOX");    break;  case GET_DIRFMTTEST:    ret = (void *) mix_dirfmttest;    break;  case GET_SCANCONTENTS:    ret = (void *) mix_scan_contents;    break;  case SET_ONETIMEEXPUNGEATPING:    if (value) ((MIXLOCAL *) ((MAILSTREAM *) value)->local)->expok = T;  case GET_ONETIMEEXPUNGEATPING:    if (value) ret = (void *)      (((MIXLOCAL *) ((MAILSTREAM *) value)->local)->expok ? VOIDT : NIL);    break;  }  return ret;}/* MIX test for directory format internal node * Accepts: candidate node name * Returns: T if internal name, NIL otherwise */long mix_dirfmttest (char *name){				/* belongs to MIX if starts with .mix */  return strncmp (name,MIXNAME,sizeof (MIXNAME) - 1) ? NIL : LONGT;}/* MIX mail scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void mix_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  if (stream) dummy_scan (NIL,ref,pat,contents);}/* MIX scan mailbox for contents * Accepts: mailbox name *	    desired contents *	    contents size *	    file size (ignored) * Returns: NIL if contents not found, T if found */long mix_scan_contents (char *name,char *contents,unsigned long csiz,			unsigned long fsiz){  long i,nfiles;  void *a;  char *s;  long ret = NIL;  size_t namelen = strlen (name);  struct stat sbuf;  struct direct **names = NIL;  if ((nfiles = scandir (name,&names,mix_select,mix_msgfsort)) > 0)    for (i = 0; i < nfiles; ++i) {      if (!ret) {	sprintf (s = (char *) fs_get (namelen + strlen (names[i]->d_name) + 2),		 "%s/%s",name,names[i]->d_name);	if (!stat (s,&sbuf) && (csiz <= sbuf.st_size))	  ret = dummy_scan_contents (s,contents,csiz,sbuf.st_size);	fs_give ((void **) &s);      }      fs_give ((void **) &names[i]);    }				/* free directory list */  if (a = (void *) names) fs_give ((void **) &a);  return ret;}/* MIX list mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mix_list (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_list (NIL,ref,pat);}/* MIX list subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mix_lsub (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_lsub (NIL,ref,pat);}/* MIX mail subscribe to mailbox * Accepts: mail stream *	    mailbox to add to subscription list * Returns: T on success, NIL on failure */long mix_subscribe (MAILSTREAM *stream,char *mailbox){  return sm_subscribe (mailbox);}/* MIX mail unsubscribe to mailbox * Accepts: mail stream *	    mailbox to delete from subscription list * Returns: T on success, NIL on failure */

⌨️ 快捷键说明

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