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

📄 unixnt.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:	UNIX mail routines * * Author:	Mark Crispin *		UW Technology *		University of Washington *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	20 December 1989 * Last Edited:	27 March 2008 *//*				DEDICATION * *  This file is dedicated to my dog, Unix, also known as Yun-chan and * Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast.  Unix * passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after * a two-month bout with cirrhosis of the liver. * *  He was a dear friend, and I miss him terribly. * *  Lift a leg, Yunie.  Luv ya forever!!!! */#include <stdio.h>#include <ctype.h>#include <errno.h>extern int errno;		/* just in case */#include "mail.h"#include "osdep.h"#include <time.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/utime.h>#include "unixnt.h"#include "pseudo.h"#include "fdstring.h"#include "misc.h"#include "dummy.h"/* UNIX I/O stream local data */typedef struct unix_local {  unsigned int dirty : 1;	/* disk copy needs updating */  unsigned int ddirty : 1;	/* double-dirty, ping becomes checkpoint */  unsigned int pseudo : 1;	/* uses a pseudo message */  unsigned int appending : 1;	/* don't mark new messages as old */  int fd;			/* mailbox file descriptor */  int ld;			/* lock file descriptor */  char *lname;			/* lock file name */  off_t filesize;		/* file size parsed */  time_t filetime;		/* last file time */  unsigned char *buf;		/* temporary buffer */  unsigned long buflen;		/* current size of temporary buffer */  unsigned long uid;		/* current text uid */  SIZEDTEXT text;		/* current text */  unsigned long textlen;	/* current text length */  char *line;			/* returned line */  char *linebuf;		/* line readin buffer */  unsigned long linebuflen;	/* current line readin buffer length */} UNIXLOCAL;/* Convenient access to local data */#define LOCAL ((UNIXLOCAL *) stream->local)/* UNIX protected file structure */typedef struct unix_file {  MAILSTREAM *stream;		/* current stream */  off_t curpos;			/* current file position */  off_t protect;		/* protected position */  off_t filepos;		/* current last written file position */  char *buf;			/* overflow buffer */  size_t buflen;		/* current overflow buffer length */  char *bufpos;			/* current buffer position */} UNIXFILE;/* Function prototypes */DRIVER *unix_valid (char *name);void *unix_parameters (long function,void *value);void unix_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);void unix_list (MAILSTREAM *stream,char *ref,char *pat);void unix_lsub (MAILSTREAM *stream,char *ref,char *pat);long unix_create (MAILSTREAM *stream,char *mailbox);long unix_delete (MAILSTREAM *stream,char *mailbox);long unix_rename (MAILSTREAM *stream,char *old,char *newname);MAILSTREAM *unix_open (MAILSTREAM *stream);void unix_close (MAILSTREAM *stream,long options);char *unix_header (MAILSTREAM *stream,unsigned long msgno,		   unsigned long *length,long flags);long unix_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);char *unix_text_work (MAILSTREAM *stream,MESSAGECACHE *elt,		      unsigned long *length,long flags);void unix_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt);long unix_ping (MAILSTREAM *stream);void unix_check (MAILSTREAM *stream);long unix_expunge (MAILSTREAM *stream,char *sequence,long options);long unix_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);long unix_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);int unix_collect_msg (MAILSTREAM *stream,FILE *sf,char *flags,char *date,		     STRING *msg);int unix_append_msgs (MAILSTREAM *stream,FILE *sf,FILE *df,SEARCHSET *set);void unix_abort (MAILSTREAM *stream);char *unix_file (char *dst,char *name);int unix_lock (char *file,int flags,int mode,char *lock,int op);void unix_unlock (int fd,MAILSTREAM *stream,char *lock);int unix_parse (MAILSTREAM *stream,char *lock,int op);char *unix_mbxline (MAILSTREAM *stream,STRING *bs,unsigned long *size);unsigned long unix_pseudo (MAILSTREAM *stream,char *hdr);unsigned long unix_xstatus (MAILSTREAM *stream,char *status,MESSAGECACHE *elt,			    unsigned long uid,long flag);long unix_rewrite (MAILSTREAM *stream,unsigned long *nexp,char *lock,		   long flags);long unix_extend (MAILSTREAM *stream,unsigned long size);void unix_write (UNIXFILE *f,char *s,unsigned long i);void unix_phys_write (UNIXFILE *f,char *buf,size_t size);/* UNIX mail routines *//* Driver dispatch used by MAIL */DRIVER unixdriver = {  "unix",			/* driver name */				/* driver flags */  DR_LOCAL|DR_MAIL|DR_NONEWMAILRONLY|DR_XPOINT,  (DRIVER *) NIL,		/* next driver */  unix_valid,			/* mailbox is valid for us */  unix_parameters,		/* manipulate parameters */  unix_scan,			/* scan mailboxes */  unix_list,			/* list mailboxes */  unix_lsub,			/* list subscribed mailboxes */  NIL,				/* subscribe to mailbox */  NIL,				/* unsubscribe from mailbox */  unix_create,			/* create mailbox */  unix_delete,			/* delete mailbox */  unix_rename,			/* rename mailbox */  mail_status_default,		/* status of mailbox */  unix_open,			/* open mailbox */  unix_close,			/* close mailbox */  NIL,				/* fetch message "fast" attributes */  NIL,				/* fetch message flags */  NIL,				/* fetch overview */  NIL,				/* fetch message envelopes */  unix_header,			/* fetch message header */  unix_text,			/* fetch message text */  NIL,				/* fetch partial message text */  NIL,				/* unique identifier */  NIL,				/* message number */  NIL,				/* modify flags */  unix_flagmsg,			/* per-message modify flags */  NIL,				/* search for message based on criteria */  NIL,				/* sort messages */  NIL,				/* thread messages */  unix_ping,			/* ping mailbox to see if still alive */  unix_check,			/* check for new messages */  unix_expunge,			/* expunge deleted messages */  unix_copy,			/* copy messages to another mailbox */  unix_append,			/* append string message to mailbox */  NIL				/* garbage collect stream */};				/* prototype stream */MAILSTREAM unixproto = {&unixdriver};				/* driver parameters */static long unix_fromwidget = T;/* UNIX mail validate mailbox * Accepts: mailbox name * Returns: our driver if name is valid, NIL otherwise */DRIVER *unix_valid (char *name){  int fd;  DRIVER *ret = NIL;  int c,r;  char tmp[MAILTMPLEN],file[MAILTMPLEN],*s,*t;  struct stat sbuf;  struct utimbuf times;  errno = EINVAL;		/* assume invalid argument */				/* must be non-empty file */  if ((t = dummy_file (file,name)) && !stat (t,&sbuf) &&      ((sbuf.st_mode & S_IFMT) == S_IFREG)) {    if (!sbuf.st_size)errno = 0;/* empty file */    else if ((fd = open (file,O_BINARY|O_RDONLY,NIL)) >= 0) {      memset (tmp,'\0',MAILTMPLEN);      if (read (fd,tmp,MAILTMPLEN-1) <= 0) errno = -1;      else {			/* ignore leading whitespace */	for (s = tmp,c = '\n';	     (*s == '\r') || (*s == '\n') || (*s == ' ') || (*s == '\t');	     c = *s++);	if (c == '\n') {	/* at start of a line? */	  VALID (s,t,r,c);	/* yes, validate format */	  if (r) ret = &unixdriver;	  else errno = -1;	/* invalid format */	}      }      close (fd);		/* close the file */				/* \Marked status? */      if ((sbuf.st_ctime > sbuf.st_atime) || (sbuf.st_mtime > sbuf.st_atime)) {				/* yes, preserve atime and mtime */	times.actime = sbuf.st_atime;	times.modtime = sbuf.st_mtime;	utime (file,&times);	/* set the times */      }    }  }  return ret;			/* return what we should */}/* UNIX manipulate driver parameters * Accepts: function code *	    function-dependent value * Returns: function-dependent return value */void *unix_parameters (long function,void *value){  void *ret = NIL;  switch ((int) function) {  case SET_FROMWIDGET:    unix_fromwidget = (long) value;  case GET_FROMWIDGET:    ret = (void *) unix_fromwidget;    break;  }  return ret;}/* UNIX mail scan mailboxes * Accepts: mail stream *	    reference *	    pattern to search *	    string to scan */void unix_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){  if (stream) dummy_scan (NIL,ref,pat,contents);}/* UNIX mail list mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void unix_list (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_list (NIL,ref,pat);}/* UNIX mail list subscribed mailboxes * Accepts: mail stream *	    reference *	    pattern to search */void unix_lsub (MAILSTREAM *stream,char *ref,char *pat){  if (stream) dummy_lsub (NIL,ref,pat);}/* UNIX mail create mailbox * Accepts: MAIL stream *	    mailbox name to create * Returns: T on success, NIL on failure */long unix_create (MAILSTREAM *stream,char *mailbox){  char *s,mbx[MAILTMPLEN],tmp[MAILTMPLEN];  long ret = NIL;  int 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,NIL)) {    if ((s = strrchr (s,'\\')) && !s[1]) ret = T;    if ((fd = open (mbx,O_WRONLY|O_BINARY,NIL)) < 0) {      sprintf (tmp,"Can't reopen mailbox node %.80s: %s",mbx,strerror (errno));      mm_log (tmp,ERROR);      unlink (mbx);		/* delete the file */    }    else {			/* initialize header */      memset (tmp,'\0',MAILTMPLEN);      sprintf (tmp,"From %s %s",pseudo_from,ctime (&ti));      if (s = strpbrk (tmp,"\r\n")) *s = '\0';      strcat (tmp,"\r\nDate: ");      rfc822_fixed_date (s = tmp + strlen (tmp));      sprintf (s += strlen (s),	/* write the pseudo-header */	       "\r\nFrom: %s <%s@%s>\r\nSubject: %s\r\nX-IMAP: %010lu 0000000000\r\nStatus: RO\r\n\r\n%s\r\n\r\n",	       pseudo_name,pseudo_from,mylocalhost (),pseudo_subject,	       (unsigned long) ti,pseudo_msg);      if (write (fd,tmp,strlen (tmp)) > 0) {	close (fd);		/* close file */	ret = T;      }      else {	sprintf (tmp,"Can't initialize mailbox node %.80s: %s",mbx,		 strerror (errno));	mm_log (tmp,ERROR);	close (fd);		/* close file before unlinking */	unlink (mbx);		/* delete the file */      }    }  }  return ret;}/* UNIX mail delete mailbox * Accepts: MAIL stream *	    mailbox name to delete * Returns: T on success, NIL on failure */long unix_delete (MAILSTREAM *stream,char *mailbox){  return unix_rename (stream,mailbox,NIL);}/* UNIX mail rename mailbox * Accepts: MAIL stream *	    old mailbox name *	    new mailbox name (or NIL for delete) * Returns: T on success, NIL on failure */long unix_rename (MAILSTREAM *stream,char *old,char *newname){  long ret = NIL;  char c,*s = NIL;  char tmp[MAILTMPLEN],file[MAILTMPLEN],lock[MAILTMPLEN],lockx[MAILTMPLEN];  int fd,ld;  struct stat sbuf;  mm_critical (stream);		/* get the c-client lock */  if (!dummy_file (file,old) ||      (newname && (!(s = dummy_file (tmp,newname)) ||		   ((s = strrchr (s,'\\')) && !s[1]))))    sprintf (tmp,newname ?	     "Can't rename mailbox %.80s to %.80s: invalid name" :	     "Can't delete mailbox %.80s: invalid name",	     old,newname);  else if ((ld = lockname (lock,file,NIL)) < 0)    sprintf (tmp,"Can't get lock for mailbox %.80s",old);  else {			/* lock out other c-clients */    if (flock (ld,LOCK_EX|LOCK_NB)) {      close (ld);		/* couldn't lock, give up on it then */

⌨️ 快捷键说明

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