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

📄 mmdf.c

📁 mgcp协议源代码。支持多种编码:g711
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Program:	MMDF 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:	20 December 1989 * Last Edited:	1 September 2000 * * 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 notice appears in all copies and that both the * above copyright notice and this permission notice appear in supporting * documentation, and that the name of the University of Washington 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 DISCLAIMS 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 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 <stdio.h>#include <ctype.h>#include <errno.h>extern int errno;		/* just in case */#include <signal.h>#include "mail.h"#include "osdep.h"#include <time.h>#include <sys/stat.h>#include "mmdf.h"#include "pseudo.h"#include "fdstring.h"#include "misc.h"#include "dummy.h"/* MMDF mail routines *//* Driver dispatch used by MAIL */DRIVER mmdfdriver = {  "mmdf",			/* driver name */  DR_LOCAL|DR_MAIL,		/* driver flags */  (DRIVER *) NIL,		/* next driver */  mmdf_valid,			/* mailbox is valid for us */  mmdf_parameters,		/* manipulate parameters */  mmdf_scan,			/* scan mailboxes */  mmdf_list,			/* list mailboxes */  mmdf_lsub,			/* list subscribed mailboxes */  NIL,				/* subscribe to mailbox */  NIL,				/* unsubscribe from mailbox */  mmdf_create,			/* create mailbox */  mmdf_delete,			/* delete mailbox */  mmdf_rename,			/* rename mailbox */  NIL,				/* status of mailbox */  mmdf_open,			/* open mailbox */  mmdf_close,			/* close mailbox */  NIL,				/* fetch message "fast" attributes */  NIL,				/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message envelopes */  mmdf_header,			/* fetch message header */  mmdf_text,			/* fetch message text */  NIL,				/* fetch partial message text */  NIL,				/* unique identifier */  NIL,				/* message number */  NIL,				/* modify flags */  mmdf_flagmsg,			/* per-message modify flags */  NIL,				/* search for message based on criteria */  NIL,				/* sort messages */  NIL,				/* thread messages */  mmdf_ping,			/* ping mailbox to see if still alive */  mmdf_check,			/* check for new messages */  mmdf_expunge,			/* expunge deleted messages */  mmdf_copy,			/* copy messages to another mailbox */  mmdf_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM mmdfproto = {&mmdfdriver};char *mmdfhdr = MMDFHDRTXT;	/* MMDF header *//* MMDF mail validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *mmdf_valid (char *name){  char tmp[MAILTMPLEN];  return mmdf_isvalid (name,tmp) ? &mmdfdriver : NIL;}/* MMDF mail test for valid mailbox name * Accepts: mailbox name *	    scratch buffer * Returns: T if valid, NIL otherwise */long mmdf_isvalid (char *name,char *tmp){  int fd;  int ret = NIL;  char *t,file[MAILTMPLEN];  struct stat sbuf;  time_t tp[2];  errno = EINVAL;		/* assume invalid argument */				/* must be non-empty file */  if ((t = dummy_file (file,name)) && !stat (t,&sbuf)) {    if (!sbuf.st_size)errno = 0;/* empty file */    else if ((fd = open (file,O_RDONLY,NIL)) >= 0) {				/* error -1 for invalid format */      if (!(ret = mmdf_isvalid_fd (fd,tmp))) errno = -1;      close (fd);		/* close the file */      tp[0] = sbuf.st_atime;	/* preserve atime and mtime */      tp[1] = sbuf.st_mtime;      utime (file,tp);		/* set the times */    }  }				/* in case INBOX but not MMDF format */  else if ((errno == ENOENT) && ((name[0] == 'I') || (name[0] == 'i')) &&	   ((name[1] == 'N') || (name[1] == 'n')) &&	   ((name[2] == 'B') || (name[2] == 'b')) &&	   ((name[3] == 'O') || (name[3] == 'o')) &&	   ((name[4] == 'X') || (name[4] == 'x')) && !name[5]) errno = -1;  return ret;			/* return what we should */}/* MMDF mail test for valid mailbox * Accepts: file descriptor *	    scratch buffer * Returns: T if valid, NIL otherwise */long mmdf_isvalid_fd (int fd,char *tmp){  int ret = NIL;  memset (tmp,'\0',MAILTMPLEN);  if (read (fd,tmp,MAILTMPLEN-1) >= 0) ret = ISMMDF (tmp) ? T : NIL;  return ret;			/* return what we should */}/* MMDF manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *mmdf_parameters (long function,void *value){  return NIL;}/* MMDF mail scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void mmdf_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  if (stream) dummy_scan (NIL,ref,pat,contents);}/* MMDF mail list mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mmdf_list (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_list (NIL,ref,pat);}/* MMDF mail list subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void mmdf_lsub (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_lsub (NIL,ref,pat);}/* MMDF mail create mailbox * Accepts: MAIL stream *	    mailbox name to create * Returns: T on success, NIL on failure */long mmdf_create (MAILSTREAM *stream,char *mailbox){  char *s,mbx[MAILTMPLEN],tmp[MAILTMPLEN];  long ret = NIL;  int i,fd;  time_t ti = time (0);  if (!(s = dummy_file (mbx,mailbox))) {    sprintf (tmp,"Can't create %.80s: invalid name",mailbox);    mm_log (tmp,ERROR);  }				/* create underlying file */  else if (dummy_create_path (stream,s)) {				/* done if made directory */    if ((s = strrchr (s,'/')) && !s[1]) return T;    if ((fd = open (mbx,O_WRONLY,		    (int) mail_parameters (NIL,GET_MBXPROTECTION,NIL))) < 0) {      sprintf (tmp,"Can't reopen mailbox node %.80s: %s",mbx,strerror (errno));      mm_log (tmp,ERROR);      unlink (mbx);		/* delete the file */    }				/* in case a whiner with no life */    else if (mail_parameters (NIL,GET_USERHASNOLIFE,NIL)) ret = T;    else {			/* initialize header */      memset (tmp,'\0',MAILTMPLEN);      sprintf (tmp,"%sFrom %s %sDate: ",mmdfhdr,pseudo_from,ctime (&ti));      rfc822_date (s = tmp + strlen (tmp));      sprintf (s += strlen (s),	/* write the pseudo-header */	       "\nFrom: %s <%s@%s>\nSubject: %s\nX-IMAP: %010lu 0000000000",	       pseudo_name,pseudo_from,mylocalhost (),pseudo_subject,	       (unsigned long) ti);      for (i = 0; i < NUSERFLAGS; ++i) if (default_user_flag (i))	sprintf (s += strlen (s)," %s",default_user_flag (i));      sprintf (s += strlen (s),"\nStatus: RO\n\n%s\n%s",pseudo_msg,mmdfhdr);      if ((write (fd,tmp,strlen (tmp)) < 0) || close (fd)) {	sprintf (tmp,"Can't initialize mailbox node %.80s: %s",mbx,		 strerror (errno));	mm_log (tmp,ERROR);	unlink (mbx);		/* delete the file */      }      else ret = T;		/* success */    }    close (fd);			/* close file, set proper protections */  }  return ret ? set_mbx_protections (mailbox,mbx) : NIL;}/* MMDF mail delete mailbox * Accepts: MAIL stream *	    mailbox name to delete * Returns: T on success, NIL on failure */long mmdf_delete (MAILSTREAM *stream,char *mailbox){  return mmdf_rename (stream,mailbox,NIL);}/* MMDF mail rename mailbox * Accepts: MAIL stream *	    old mailbox name *	    new mailbox name (or NIL for delete) * Returns: T on success, NIL on failure */long mmdf_rename (MAILSTREAM *stream,char *old,char *newname){  long ret = NIL;  char c,*s = NIL;  char tmp[MAILTMPLEN],file[MAILTMPLEN],lock[MAILTMPLEN];  DOTLOCK lockx;  int fd,ld;  long i;  struct stat sbuf;  mm_critical (stream);		/* get the c-client lock */  if (newname && !((s = dummy_file (tmp,newname)) && *s))    sprintf (tmp,"Can't rename mailbox %.80s to %.80s: invalid name",	     old,newname);				/* lock out other c-clients */  else if ((ld = lockname (lock,dummy_file (file,old),LOCK_EX|LOCK_NB,&i)) < 0)    sprintf (tmp,"Mailbox %.80s is in use by another process",old);  else {    if ((fd = mmdf_lock (file,O_RDWR,S_IREAD|S_IWRITE,&lockx,LOCK_EX)) < 0)      sprintf (tmp,"Can't lock mailbox %.80s: %s",old,strerror (errno));    else {      if (newname) {		/* want rename? */				/* found superior to destination name? */	if (s = strrchr (s,'/')) {	  c = *++s;		/* remember first character of inferior */	  *s = '\0';		/* tie off to get just superior */				/* name doesn't exist, create it */	  if ((stat (tmp,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) &&	      !dummy_create (stream,tmp)) {	    mmdf_unlock (fd,NIL,&lockx);	    mmdf_unlock (ld,NIL,NIL);	    unlink (lock);	    mm_nocritical (stream);	    return ret;		/* return success or failure */	  }	  *s = c;		/* restore full name */	}	if (rename (file,tmp))	  sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %s",old,newname,		   strerror (errno));	else ret = T;		/* set success */      }      else if (unlink (file))	sprintf (tmp,"Can't delete mailbox %.80s: %s",old,strerror (errno));      else ret = T;		/* set success */      mmdf_unlock (fd,NIL,&lockx);    }    mmdf_unlock (ld,NIL,NIL);	/* flush the lock */    unlink (lock);  }  mm_nocritical (stream);	/* no longer critical */  if (!ret) mm_log (tmp,ERROR);	/* log error */  return ret;			/* return success or failure */}/* MMDF mail open * Accepts: Stream to open * Returns: Stream on success, NIL on failure */MAILSTREAM *mmdf_open (MAILSTREAM *stream){  long i;  int fd;  char tmp[MAILTMPLEN];  DOTLOCK lock;  long retry;				/* return prototype for OP_PROTOTYPE call */  if (!stream) return user_flags (&mmdfproto);  retry = stream->silent ? 1 : KODRETRY;  if (stream->local) fatal ("mmdf recycle stream");  stream->local = memset (fs_get (sizeof (MMDFLOCAL)),0,sizeof (MMDFLOCAL));				/* note if an INBOX or not */  stream->inbox = !strcmp (ucase (strcpy (tmp,stream->mailbox)),"INBOX");				/* canonicalize the stream mailbox name */  dummy_file (tmp,stream->mailbox);				/* flush old name */  fs_give ((void **) &stream->mailbox);				/* save canonical name */  stream->mailbox = cpystr (tmp);  LOCAL->fd = LOCAL->ld = -1;	/* no file or state locking yet */  LOCAL->buf = (char *) fs_get ((LOCAL->buflen = CHUNK) + 1);  stream->sequence++;		/* bump sequence number */				/* make lock for read/write access */  if (!stream->rdonly) while (retry) {				/* try to lock file */    if ((fd = lockname (tmp,stream->mailbox,LOCK_EX|LOCK_NB,&i)) < 0) {      if (retry-- == KODRETRY) {/* no, first time through? */	if (i) {		/* learned the other guy's PID? */	  kill ((int) i,SIGUSR2);	  sprintf (tmp,"Trying to get mailbox lock from process %ld",i);	  mm_log (tmp,WARN);	}	else retry = 0;		/* give up */      }      if (!stream->silent) {	/* nothing if silent stream */	if (retry) sleep (1);	/* wait a second before trying again */	else mm_log ("Mailbox is open by another process, access is readonly",

⌨️ 快捷键说明

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