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

📄 mbx.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ======================================================================== * 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:	MBX mail 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:	3 October 1995 * Last Edited:	11 October 2007 *//*				FILE TIME SEMANTICS * * The atime is the last read time of the file. * The mtime is the last flags update time of the file. * The ctime is the last write time of the file. */#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"/* Build parameters */#define HDRSIZE 2048/* Kludge to make Cygwin happy */#ifndef O_BINARY#define O_BINARY 0#endif/* MBX I/O stream local data */	typedef struct mbx_local {  unsigned int flagcheck: 1;	/* if ping should sweep for flags */  unsigned int expok: 1;	/* if expunging OK in ping */  unsigned int expunged : 1;	/* if one or more expunged messages */  int fd;			/* file descriptor for I/O */  int ld;			/* lock file descriptor */  int ffuserflag;		/* first free user flag */  off_t filesize;		/* file size parsed */  time_t filetime;		/* last file time */  time_t lastsnarf;		/* last snarf time */  unsigned long lastpid;	/* PID of last writer */  unsigned char *buf;		/* temporary buffer */  unsigned long buflen;		/* current size of temporary buffer */  char lock[MAILTMPLEN];	/* buffer to write lock name */} MBXLOCAL;/* Convenient access to local data */#define LOCAL ((MBXLOCAL *) stream->local)/* Function prototypes */DRIVER *mbx_valid (char *name);int mbx_isvalid (MAILSTREAM **stream,char *name,char *tmp,int *ld,char *lock,		 long flags);void *mbx_parameters (long function,void *value);void mbx_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);void mbx_list (MAILSTREAM *stream,char *ref,char *pat);void mbx_lsub (MAILSTREAM *stream,char *ref,char *pat);long mbx_create (MAILSTREAM *stream,char *mailbox);long mbx_delete (MAILSTREAM *stream,char *mailbox);long mbx_rename (MAILSTREAM *stream,char *old,char *newname);long mbx_status (MAILSTREAM *stream,char *mbx,long flags);MAILSTREAM *mbx_open (MAILSTREAM *stream);void mbx_close (MAILSTREAM *stream,long options);void mbx_abort (MAILSTREAM *stream);void mbx_flags (MAILSTREAM *stream,char *sequence,long flags);char *mbx_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,		  long flags);long mbx_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);void mbx_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags);void mbx_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt);long mbx_ping (MAILSTREAM *stream);void mbx_check (MAILSTREAM *stream);long mbx_expunge (MAILSTREAM *stream,char *sequence,long options);void mbx_snarf (MAILSTREAM *stream);long mbx_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);long mbx_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);char *mbx_file (char *dst,char *name);long mbx_parse (MAILSTREAM *stream);MESSAGECACHE *mbx_elt (MAILSTREAM *stream,unsigned long msgno,long expok);unsigned long mbx_read_flags (MAILSTREAM *stream,MESSAGECACHE *elt);void mbx_update_header (MAILSTREAM *stream);void mbx_update_status (MAILSTREAM *stream,unsigned long msgno,long flags);unsigned long mbx_hdrpos (MAILSTREAM *stream,unsigned long msgno,			  unsigned long *size,char **hdr);unsigned long mbx_rewrite (MAILSTREAM *stream,unsigned long *reclaimed,			   long flags);long mbx_flaglock (MAILSTREAM *stream);/* MBX mail routines *//* Driver dispatch used by MAIL */DRIVER mbxdriver = {  "mbx",			/* driver name */  DR_LOCAL|DR_MAIL|DR_CRLF|DR_LOCKING,				/* driver flags */  (DRIVER *) NIL,		/* next driver */  mbx_valid,			/* mailbox is valid for us */  mbx_parameters,		/* manipulate parameters */  mbx_scan,			/* scan mailboxes */  mbx_list,			/* list mailboxes */  mbx_lsub,			/* list subscribed mailboxes */  NIL,				/* subscribe to mailbox */  NIL,				/* unsubscribe from mailbox */  mbx_create,			/* create mailbox */  mbx_delete,			/* delete mailbox */  mbx_rename,			/* rename mailbox */  mbx_status,			/* status of mailbox */  mbx_open,			/* open mailbox */  mbx_close,			/* close mailbox */  mbx_flags,			/* fetch message "fast" attributes */  mbx_flags,			/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message envelopes */  mbx_header,			/* fetch message header */  mbx_text,			/* fetch message body */  NIL,				/* fetch partial message text */  NIL,				/* unique identifier */  NIL,				/* message number */  mbx_flag,			/* modify flags */  mbx_flagmsg,			/* per-message modify flags */  NIL,				/* search for message based on criteria */  NIL,				/* sort messages */  NIL,				/* thread messages */  mbx_ping,			/* ping mailbox to see if still alive */  mbx_check,			/* check for new messages */  mbx_expunge,			/* expunge deleted messages */  mbx_copy,			/* copy messages to another mailbox */  mbx_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM mbxproto = {&mbxdriver};/* MBX mail validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *mbx_valid (char *name){  char tmp[MAILTMPLEN];  int fd = mbx_isvalid (NIL,name,tmp,NIL,NIL,NIL);  if (fd < 0) return NIL;  close (fd);			/* don't need the fd now */  return &mbxdriver;}/* MBX mail test for valid mailbox * Accepts: returned stream with valid mailbox keywords *	    mailbox name *	    scratch buffer *	    returned lock fd *	    returned lock name *	    RW flags or NIL for readonly * Returns: file descriptor if valid, NIL otherwise */#define MBXISVALIDNOUID 0x1	/* RW, don't do UID action */#define MBXISVALIDUID 0x2	/* RW, do UID action */int mbx_isvalid (MAILSTREAM **stream,char *name,char *tmp,int *ld,char *lock,		 long flags){  int fd,upd;  int ret = -1;  unsigned long i;  long j,k;  off_t pos;  char c,*s,*t,hdr[HDRSIZE];  struct stat sbuf;  time_t tp[2];  int error = EINVAL;		/* assume invalid argument */  if (ld) *ld = -1;		/* initially no lock */  if ((s = mbx_file (tmp,name)) && !stat (s,&sbuf) &&      ((fd = open (tmp,(flags ? O_RDWR : O_RDONLY)|O_BINARY,NIL)) >= 0)) {    error = -1;			/* bogus format */		/* I love cretinous C compilers -- don't you? */    if (read (fd,hdr,HDRSIZE) == HDRSIZE)      if ((hdr[0] == '*') && (hdr[1] == 'm') && (hdr[2] == 'b') &&	  (hdr[3] == 'x') && (hdr[4] == '*') && (hdr[5] == '\015') &&	  (hdr[6] == '\012') && isxdigit (hdr[7]) && isxdigit (hdr[8]))	if (isxdigit (hdr[9]) && isxdigit (hdr[10]) && isxdigit (hdr[11]) &&	    isxdigit (hdr[12]) && isxdigit (hdr[13]) && isxdigit (hdr[14]) &&	    isxdigit (c = hdr[15]) && isxdigit (hdr[16]))	  if (isxdigit (hdr[17]) && isxdigit (hdr[18]) &&	      isxdigit (hdr[19]) && isxdigit (hdr[20]) &&	      isxdigit (hdr[21]) && isxdigit (hdr[22]) &&	      (hdr[23] == '\015') && (hdr[24] == '\012')) {	    ret = fd;		/* mbx format */	    if (stream) {	/* lock if making mini-stream */	      if (flock (fd,LOCK_SH) ||		  (flags && ((*ld = lockfd (fd,lock,LOCK_EX)) < 0))) ret = -1;				/* reread data now that locked */	      else if (lseek (fd,0,L_SET) ||		       (read (fd,hdr,HDRSIZE) != HDRSIZE)) ret = -1;	      else {		*stream = (MAILSTREAM *) memset (fs_get (sizeof (MAILSTREAM)),						 0,sizeof (MAILSTREAM));		hdr[15] = '\0';	/* tie off UIDVALIDITY */		(*stream)->uid_validity = strtoul (hdr+7,NIL,16);		hdr[15] = c;	/* now get UIDLAST */		(*stream)->uid_last = strtoul (hdr+15,NIL,16);				/* parse user flags */		for (i = 0, s = hdr + 25;		     (i < NUSERFLAGS) && (t = strchr (s,'\015')) && (t - s);		     i++, s = t + 2) {		  *t = '\0';	/* tie off flag */		  if (strlen (s) <= MAXUSERFLAG)		    (*stream)->user_flags[i] = cpystr (s);		}				/* make sure have true UIDLAST */		if (flags & MBXISVALIDUID) {		  for (upd = NIL,pos = 2048, k = 0; pos < sbuf.st_size;		       pos += (j + k)) {				/* read header for this message */		    lseek (fd,pos,L_SET);		    if ((j = read (fd,hdr,64)) >= 0) {		      hdr[j] = '\0';		      if ((s = strchr (hdr,'\015')) && (s[1] == '\012')) {			*s = '\0';			k = s + 2 - hdr;			if ((s = strchr (hdr,',')) &&			    (j = strtol (s+1,&s,10)) && (*s == ';') &&			    (s = strchr (s+1,'-'))) {				/* get UID if there is any */			  i = strtoul (++s,&t,16);			  if (!*t && (t == (s + 8)) &&			      (i <= (*stream)->uid_last)) {			    if (!i) {			      lseek (fd,pos + s - hdr,L_SET);			      sprintf (hdr,"%08lx",++(*stream)->uid_last);			      write (fd,hdr,8);			      upd = T;			    }			    continue;			  }			}		      }		      ret = -1;	/* error, give up */		      *stream = mail_close (*stream);		      pos = sbuf.st_size + 1;		      j = k = 0;		    }		  }		  if (upd) {	/* need to update hdr with new UIDLAST? */		    lseek (fd,15,L_SET);		    sprintf (hdr,"%08lx",(*stream)->uid_last);		    write (fd,hdr,8);		  }		}	      }	    }	  }    if (ret != fd) close (fd);	/* close the file */    else lseek (fd,0,L_SET);	/* else rewind to start */				/* \Marked status? */    if (sbuf.st_ctime > sbuf.st_atime) {      tp[0] = sbuf.st_atime;	/* preserve atime and mtime */      tp[1] = sbuf.st_mtime;      utime (tmp,tp);		/* set the times */    }  }				/* in case INBOX but not mbx format */  else if (((error = errno) == ENOENT) && !compare_cstring (name,"INBOX"))    error = -1;  if ((ret < 0) && ld && (*ld >= 0)) {    unlockfd (*ld,lock);    *ld = -1;  }  errno = error;		/* return as last error */  return ret;			/* return what we should */}/* MBX manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *mbx_parameters (long function,void *value){  void *ret = NIL;  switch ((int) function) {  case GET_INBOXPATH:    if (value) ret = mbx_file ((char *) value,"INBOX");    break;  case SET_ONETIMEEXPUNGEATPING:    if (value) ((MBXLOCAL *) ((MAILSTREAM *) value)->local)->expok = T;  case GET_ONETIMEEXPUNGEATPING:    if (value) ret = (void *)      (((MBXLOCAL *) ((MAILSTREAM *) value)->local)->expok ? VOIDT : NIL);    break;  }  return ret;}/* MBX mail scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void mbx_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  if (stream) dummy_scan (NIL,ref,pat,contents);}/* MBX mail list mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mbx_list (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_list (NIL,ref,pat);}/* MBX mail list subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mbx_lsub (MAILSTREAM *stream,char *ref,char *pat)

⌨️ 快捷键说明

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