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

📄 mbx.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
{  if (stream) dummy_lsub (NIL,ref,pat);}/* MBX mail create mailbox * Accepts: MAIL stream *	    mailbox name to create * Returns: T on success, NIL on failure */long mbx_create (MAILSTREAM *stream,char *mailbox){  char *s,*t,mbx[MAILTMPLEN],tmp[HDRSIZE];  long ret = NIL;  int i,fd;  if (!(s = mbx_file (mbx,mailbox))) {    sprintf (mbx,"Can't create %.80s: invalid name",mailbox);    MM_LOG (mbx,ERROR);  }				/* create underlying file */  else if (dummy_create_path (stream,s,get_dir_protection (mailbox))) {				/* done if made directory */    if ((s = strrchr (s,'/')) && !s[1]) return 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 {      memset (tmp,'\0',HDRSIZE);/* initialize header */      sprintf (s = tmp,"*mbx*\015\012%08lx00000000\015\012",	       (unsigned long) time (0));      for (i = 0; i < NUSERFLAGS; ++i) {	t = (stream && stream->user_flags[i]) ? stream->user_flags[i] :	  ((t = default_user_flag (i)) ? t : "");	sprintf (s += strlen (s),"%s\015\012",t);      }      if (write (fd,tmp,HDRSIZE) != HDRSIZE) {	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;}/* MBX mail delete mailbox * Accepts: MAIL stream *	    mailbox name to delete * Returns: T on success, NIL on failure */long mbx_delete (MAILSTREAM *stream,char *mailbox){  return mbx_rename (stream,mailbox,NIL);}/* MBX mail rename mailbox * Accepts: MAIL stream *	    old mailbox name *	    new mailbox name (or NIL for delete) * Returns: T on success, NIL on failure */long mbx_rename (MAILSTREAM *stream,char *old,char *newname){  long ret = LONGT;  char c,*s,tmp[MAILTMPLEN],file[MAILTMPLEN],lock[MAILTMPLEN];  int fd,ld;  struct stat sbuf;  if (!mbx_file (file,old) ||      (newname && (!((s = mailboxfile (tmp,newname)) && *s) ||		   ((s = strrchr (tmp,'/')) && !s[1])))) {    sprintf (tmp,newname ?	     "Can't rename mailbox %.80s to %.80s: invalid name" :	     "Can't delete mailbox %.80s: invalid name",	     old,newname);    MM_LOG (tmp,ERROR);    return NIL;  }  else if ((fd = open (file,O_RDWR|O_BINARY,NIL)) < 0) {    sprintf (tmp,"Can't open mailbox %.80s: %s",old,strerror (errno));    MM_LOG (tmp,ERROR);    return NIL;  }				/* get parse/append permission */  if ((ld = lockfd (fd,lock,LOCK_EX)) < 0) {    MM_LOG ("Unable to lock rename mailbox",ERROR);    return NIL;  }				/* lock out other users */  if (flock (fd,LOCK_EX|LOCK_NB)) {    close (fd);			/* couldn't lock, give up on it then */    sprintf (tmp,"Mailbox %.80s is in use by another process",old);    MM_LOG (tmp,ERROR);    unlockfd (ld,lock);		/* release exclusive parse/append permission */    return NIL;  }  if (newname) {		/* want rename? */				/* found superior to destination name? */    if (s = strrchr (tmp,'/')) {      c = *++s;			/* remember first character of inferior */      *s = '\0';		/* tie off to get just superior */				/* superior name doesn't exist, create it */      if ((stat (tmp,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) &&	  !dummy_create_path (stream,tmp,get_dir_protection (newname)))	ret = NIL;      else *s = c;		/* restore full name */    }				/* rename the file */    if (ret && rename (file,tmp)) {      sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %s",old,newname,	       strerror (errno));      MM_LOG (tmp,ERROR);      ret = NIL;		/* set failure */    }  }  else if (unlink (file)) {    sprintf (tmp,"Can't delete mailbox %.80s: %s",old,strerror (errno));    MM_LOG (tmp,ERROR);    ret = NIL;			/* set failure */  }  flock (fd,LOCK_UN);		/* release lock on the file */  unlockfd (ld,lock);		/* release exclusive parse/append permission */  close (fd);			/* close the file */				/* recreate file if renamed INBOX */  if (ret && !compare_cstring (old,"INBOX")) mbx_create (NIL,"INBOX");  return ret;			/* return success */}/* MBX Mail status * Accepts: mail stream *	    mailbox name *	    status flags * Returns: T on success, NIL on failure */long mbx_status (MAILSTREAM *stream,char *mbx,long flags){  MAILSTATUS status;  unsigned long i;  MAILSTREAM *tstream = NIL;  MAILSTREAM *systream = NIL;				/* make temporary stream (unless this mbx) */  if (!stream && !(stream = tstream =		   mail_open (NIL,mbx,OP_READONLY|OP_SILENT)))    return NIL;  status.flags = flags;		/* return status values */  status.messages = stream->nmsgs;  status.recent = stream->recent;  if (flags & SA_UNSEEN)	/* must search to get unseen messages */    for (i = 1,status.unseen = 0; i <= stream->nmsgs; i++)      if (!mail_elt (stream,i)->seen) status.unseen++;  status.uidnext = stream->uid_last + 1;  status.uidvalidity = stream->uid_validity;				/* calculate post-snarf results */  if (!status.recent && stream->inbox &&      (systream = mail_open (NIL,sysinbox (),OP_READONLY|OP_SILENT))) {    status.messages += systream->nmsgs;    status.recent += systream->recent;    if (flags & SA_UNSEEN)	/* must search to get unseen messages */      for (i = 1; i <= systream->nmsgs; i++)	if (!mail_elt (systream,i)->seen) status.unseen++;				/* kludge but probably good enough */    status.uidnext += systream->nmsgs;  }  MM_STATUS(stream,mbx,&status);/* pass status to main program */  if (tstream) mail_close (tstream);  if (systream) mail_close (systream);  return T;			/* success */}/* MBX mail open * Accepts: stream to open * Returns: stream on success, NIL on failure */MAILSTREAM *mbx_open (MAILSTREAM *stream){  int fd,ld;  short silent;  char tmp[MAILTMPLEN];  blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);				/* return prototype for OP_PROTOTYPE call */  if (!stream) return user_flags (&mbxproto);  if (stream->local) fatal ("mbx recycle stream");				/* canonicalize the mailbox name */  if (!mbx_file (tmp,stream->mailbox)) {    sprintf (tmp,"Can't open - invalid name: %.80s",stream->mailbox);    MM_LOG (tmp,ERROR);  }  if (stream->rdonly ||      (fd = open (tmp,O_RDWR|O_BINARY,NIL)) < 0) {    if ((fd = open (tmp,O_RDONLY|O_BINARY,NIL)) < 0) {      sprintf (tmp,"Can't open mailbox: %s",strerror (errno));      MM_LOG (tmp,ERROR);      return NIL;    }    else if (!stream->rdonly) {	/* got it, but readonly */      MM_LOG ("Can't get write access to mailbox, access is readonly",WARN);      stream->rdonly = T;    }  }  stream->local = memset (fs_get (sizeof (MBXLOCAL)),NIL,sizeof (MBXLOCAL));  LOCAL->fd = fd;		/* bind the file */  LOCAL->ld = -1;		/* no flaglock */  LOCAL->buf = (char *) fs_get (CHUNKSIZE);  LOCAL->buflen = CHUNKSIZE - 1;				/* note if an INBOX or not */  stream->inbox = !compare_cstring (stream->mailbox,"INBOX");  fs_give ((void **) &stream->mailbox);  stream->mailbox = cpystr (tmp);				/* get parse/append permission */  if ((ld = lockfd (LOCAL->fd,tmp,LOCK_EX)) < 0) {    MM_LOG ("Unable to lock open mailbox",ERROR);    return NIL;  }  (*bn) (BLOCK_FILELOCK,NIL);  flock (LOCAL->fd,LOCK_SH);	/* lock the file */  (*bn) (BLOCK_NONE,NIL);  unlockfd (ld,tmp);		/* release shared parse permission */  LOCAL->filesize = HDRSIZE;	/* initialize parsed file size */				/* time not set up yet */  LOCAL->lastsnarf = LOCAL->filetime = 0;  LOCAL->expok = LOCAL->flagcheck = NIL;  stream->sequence++;		/* bump sequence number */				/* parse mailbox */  stream->nmsgs = stream->recent = 0;  silent = stream->silent;	/* defer events */  stream->silent = T;  if (mbx_ping (stream) && !stream->nmsgs)    MM_LOG ("Mailbox is empty",(long) NIL);  stream->silent = silent;	/* now notify upper level */  mail_exists (stream,stream->nmsgs);  mail_recent (stream,stream->recent);  if (!LOCAL) return NIL;	/* failure if stream died */  stream->perm_seen = stream->perm_deleted = stream->perm_flagged =    stream->perm_answered = stream->perm_draft = stream->rdonly ? NIL : T;  stream->perm_user_flags = stream->rdonly ? NIL : 0xffffffff;  stream->kwd_create = (stream->user_flags[NUSERFLAGS-1] || stream->rdonly) ?    NIL : T;			/* can we create new user flags? */  return stream;		/* return stream to caller */}/* MBX mail close * Accepts: MAIL stream *	    close options */void mbx_close (MAILSTREAM *stream,long options){  if (stream && LOCAL) {	/* only if a file is open */    int silent = stream->silent;    stream->silent = T;		/* note this stream is dying */				/* do an expunge if requested */    if (options & CL_EXPUNGE) mbx_expunge (stream,NIL,NIL);    else {			/* otherwise do a checkpoint to purge */      LOCAL->expok = T;		/*  possible expunged messages */      mbx_ping (stream);    }    stream->silent = silent;	/* restore previous status */    mbx_abort (stream);  }}/* MBX mail abort stream * Accepts: MAIL stream */void mbx_abort (MAILSTREAM *stream){  if (stream && LOCAL) {	/* only if a file is open */    flock (LOCAL->fd,LOCK_UN);	/* unlock local file */    close (LOCAL->fd);		/* close the local file */				/* free local text buffer */    if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);				/* nuke the local data */    fs_give ((void **) &stream->local);    stream->dtb = NIL;		/* log out the DTB */  }}/* MBX mail fetch flags * Accepts: MAIL stream *	    sequence *	    option flags * Sniffs at file to see if some other process changed the flags */void mbx_flags (MAILSTREAM *stream,char *sequence,long flags){  MESSAGECACHE *elt;  unsigned long i;  if (mbx_ping (stream) && 	/* ping mailbox, get new status for messages */      ((flags & FT_UID) ? mail_uid_sequence (stream,sequence) :       mail_sequence (stream,sequence)))    for (i = 1; i <= stream->nmsgs; i++)       if ((elt = mail_elt (stream,i))->sequence && !elt->valid)	mbx_elt (stream,i,NIL);}/* MBX mail fetch message header * Accepts: MAIL stream *	    message # to fetch *	    pointer to returned header text length *	    option flags * Returns: message header in RFC822 format */char *mbx_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,		  long flags){  unsigned long i;  char *s;  *length = 0;			/* default to empty */  if (flags & FT_UID) return "";/* UID call "impossible" */				/* get header position, possibly header */  i = mbx_hdrpos (stream,msgno,length,&s);  if (!s) {			/* mbx_hdrpos() returned header? */    lseek (LOCAL->fd,i,L_SET);	/* no, get to header position */				/* is buffer big enough? */    if (*length > LOCAL->buflen) {      fs_give ((void **) &LOCAL->buf);      LOCAL->buf = (char *) fs_get ((LOCAL->buflen = *length) + 1);    }				/* slurp the data */    read (LOCAL->fd,s = LOCAL->buf,*length);  }  s[*length] = '\0';		/* tie off string */  return s;}/* MBX mail fetch message text (body only) * Accepts: MAIL stream *	    message # to fetch *	    pointer to returned header text length *	    option flags * Returns: T on success, NIL on failure */long mbx_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){  FDDATA d;  unsigned long i,j;  MESSAGECACHE *elt;				/* UID call "impossible" */  if (flags & FT_UID) return NIL;				/* get message status */  elt = mbx_elt (stream,msgno,NIL);				/* if message not seen */  if (!(flags & FT_PEEK) && !elt->seen && mbx_flaglock (stream)) {    elt->seen = T;		/* mark message as seen */				/* recalculate status */    mbx_update_status (stream,msgno,NIL);    MM_FLAGS (stream,msgno);				/* update flags */    mbx_flag (stream,NIL,NIL,NIL);  }  if (!LOCAL) return NIL;	/* mbx_flaglock() could have aborted */				/* find header position */  i = mbx_hdrpos (stream,msgno,&j,NIL);  d.fd = LOCAL->fd;		/* set up file descriptor */

⌨️ 快捷键说明

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