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

📄 mbx.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
  d.pos = i + j;  d.chunk = LOCAL->buf;	/* initial buffer chunk */  d.chunksize = CHUNKSIZE;  INIT (bs,fd_string,&d,elt->rfc822_size - j);  return LONGT;			/* success */}/* MBX mail modify flags * Accepts: MAIL stream *	    sequence *	    flag(s) *	    option flags * Unlocks flag lock */void mbx_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags){  time_t tp[2];  struct stat sbuf;  unsigned long oldpid = LOCAL->lastpid;				/* make sure the update takes */  if (!stream->rdonly && LOCAL && (LOCAL->fd >= 0) && (LOCAL->ld >= 0)) {    fsync (LOCAL->fd);    fstat (LOCAL->fd,&sbuf);	/* get current write time */    tp[1] = LOCAL->filetime = sbuf.st_mtime;				/* we are the last flag updater */    LOCAL->lastpid = (unsigned long) getpid ();				/* update header if needed */    if (((LOCAL->ffuserflag < NUSERFLAGS) &&	 stream->user_flags[LOCAL->ffuserflag]) || (oldpid != LOCAL->lastpid))      mbx_update_header (stream);    tp[0] = time (0);		/* make sure read comes after all that */    utime (stream->mailbox,tp);  }  if (LOCAL->ld >= 0) {		/* unlock now */    unlockfd (LOCAL->ld,LOCAL->lock);    LOCAL->ld = -1;  }}/* MBX mail per-message modify flags * Accepts: MAIL stream *	    message cache element */void mbx_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt){  if (mbx_flaglock (stream)) mbx_update_status (stream,elt->msgno,NIL);}/* MBX mail ping mailbox * Accepts: MAIL stream * Returns: T if stream still alive, NIL if not */long mbx_ping (MAILSTREAM *stream){  unsigned long i,pos;  long ret = NIL;  int ld;  char lock[MAILTMPLEN];  MESSAGECACHE *elt;  struct stat sbuf;  if (stream && LOCAL) {	/* only if stream already open */    int snarf = stream->inbox && !stream->rdonly;    ret = LONGT;		/* assume OK */    fstat (LOCAL->fd,&sbuf);	/* get current file poop */				/* allow expunge if permitted at ping */    if (mail_parameters (NIL,GET_EXPUNGEATPING,NIL)) LOCAL->expok = T;				/* if external modification */    if (LOCAL->filetime && (LOCAL->filetime < sbuf.st_mtime))      LOCAL->flagcheck = T;	/* upgrade to flag checking */				/* new mail or flagcheck handling needed? */    if (((sbuf.st_size - LOCAL->filesize) || LOCAL->flagcheck ||	 !stream->nmsgs || snarf) &&	((ld = lockfd (LOCAL->fd,lock,LOCK_EX)) >= 0)) {				/* reparse header if not flagchecking */      if (!LOCAL->flagcheck) ret = mbx_parse (stream);				/* sweep mailbox for changed message status */      else if (ret = mbx_parse (stream)) {	unsigned long recent = 0;	LOCAL->filetime = sbuf.st_mtime;	for (i = 1; i <= stream->nmsgs; )	  if (elt = mbx_elt (stream,i,LOCAL->expok)) {	    if (elt->recent) ++recent;	    ++i;	  }	mail_recent (stream,recent);	LOCAL->flagcheck = NIL;	/* got all the updates */      }				/* always reparse header at least */      if (ret && snarf) {	/* snarf new messages if still OK */	mbx_snarf (stream);				/* parse snarfed messages */	ret = mbx_parse (stream);      }      unlockfd (ld,lock);	/* release shared parse/append permission */    }    if (ret) {			/* must still be alive */      if (!LOCAL->expunged)	/* look for holes if none known yet */	for (i = 1, pos = HDRSIZE;	     !LOCAL->expunged && (i <= stream->nmsgs);	     i++, pos += elt->private.special.text.size + elt->rfc822_size)	  if ((elt = mail_elt (stream,i))->private.special.offset != pos)	    LOCAL->expunged = T;/* found a hole */				/* burp any holes */      if (LOCAL->expunged && !stream->rdonly) {	if (mbx_rewrite (stream,&i,NIL)) fatal ("expunge on check");	if (i) {		/* any space reclaimed? */	  LOCAL->expunged = NIL;/* no more pending expunge */	  sprintf (LOCAL->buf,"Reclaimed %lu bytes of expunged space",i);	  MM_LOG (LOCAL->buf,(long) NIL);	}      }      LOCAL->expok = NIL;	/* no more expok */    }  }  return ret;			/* return result of the parse */}/* MBX mail check mailbox (reparses status too) * Accepts: MAIL stream */void mbx_check (MAILSTREAM *stream){  if (LOCAL) LOCAL->expok = T;	/* mark that a check is desired */  if (mbx_ping (stream)) MM_LOG ("Check completed",(long) NIL);}/* MBX mail expunge mailbox * Accepts: MAIL stream *	    sequence to expunge if non-NIL *	    expunge options * Returns: T if success, NIL if failure */long mbx_expunge (MAILSTREAM *stream,char *sequence,long options){  long ret;  unsigned long nexp,reclaimed;  if (ret = sequence ? ((options & EX_UID) ?			mail_uid_sequence (stream,sequence) :			mail_sequence (stream,sequence)) : LONGT) {    if (!mbx_ping (stream));	/* do nothing if stream dead */    else if (stream->rdonly)	/* won't do on readonly files! */      MM_LOG ("Expunge ignored on readonly mailbox",WARN);				/* if expunged any messages */    else if (nexp = mbx_rewrite (stream,&reclaimed,sequence ? -1 : 1)) {      sprintf (LOCAL->buf,"Expunged %lu messages",nexp);      MM_LOG (LOCAL->buf,(long) NIL);    }    else if (reclaimed) {	 /* or if any prior expunged space reclaimed */      sprintf (LOCAL->buf,"Reclaimed %lu bytes of expunged space",reclaimed);      MM_LOG (LOCAL->buf,(long) NIL);    }    else MM_LOG ("No messages deleted, so no update needed",(long) NIL);  }  return ret;}/* MBX mail snarf messages from system inbox * Accepts: MAIL stream, already locked */void mbx_snarf (MAILSTREAM *stream){  unsigned long i = 0;  unsigned long j,r,hdrlen,txtlen;  struct stat sbuf;  char *hdr,*txt,tmp[MAILTMPLEN];  MESSAGECACHE *elt;  MAILSTREAM *sysibx = NIL;				/* give up if can't get exclusive permission */  if ((time (0) >= (LOCAL->lastsnarf +		    (long) mail_parameters (NIL,GET_SNARFINTERVAL,NIL))) &&      strcmp (sysinbox (),stream->mailbox)) {    MM_CRITICAL (stream);	/* go critical */				/* sizes match and anything in sysinbox? */    if (!stat (sysinbox (),&sbuf) && sbuf.st_size &&	!fstat (LOCAL->fd,&sbuf) && (sbuf.st_size == LOCAL->filesize) && 	(sysibx = mail_open (sysibx,sysinbox (),OP_SILENT)) &&	(!sysibx->rdonly) && (r = sysibx->nmsgs)) {				/* yes, go to end of file in our mailbox */      lseek (LOCAL->fd,sbuf.st_size,L_SET);				/* for each message in sysibx mailbox */      while (r && (++i <= sysibx->nmsgs)) {				/* snarf message from system INBOX */	hdr = cpystr (mail_fetchheader_full (sysibx,i,NIL,&hdrlen,NIL));	txt = mail_fetchtext_full (sysibx,i,&txtlen,FT_PEEK);				/* if have a message */	if (j = hdrlen + txtlen) {				/* build header line */	  mail_date (LOCAL->buf,elt = mail_elt (sysibx,i));	  sprintf (LOCAL->buf + strlen (LOCAL->buf),		   ",%lu;00000000%04x-00000000\015\012",j,(unsigned)		   ((fSEEN * elt->seen) +		    (fDELETED * elt->deleted) + (fFLAGGED * elt->flagged) +		    (fANSWERED * elt->answered) + (fDRAFT * elt->draft)));				/* copy message */	  if ((write (LOCAL->fd,LOCAL->buf,strlen (LOCAL->buf)) < 0) ||	      (write (LOCAL->fd,hdr,hdrlen) < 0) ||	      (write (LOCAL->fd,txt,txtlen) < 0)) r = 0;	}	fs_give ((void **) &hdr);      }				/* make sure all the updates take */      if (fsync (LOCAL->fd)) r = 0;      if (r) {			/* delete all the messages we copied */	if (r == 1) strcpy (tmp,"1");	else sprintf (tmp,"1:%lu",r);	mail_setflag (sysibx,tmp,"\\Deleted");	mail_expunge (sysibx);	/* now expunge all those messages */      }      else {	sprintf (LOCAL->buf,"Can't copy new mail: %s",strerror (errno));	MM_LOG (LOCAL->buf,WARN);	ftruncate (LOCAL->fd,sbuf.st_size);      }      fstat (LOCAL->fd,&sbuf);	/* yes, get current file size */      LOCAL->filetime = sbuf.st_mtime;    }    if (sysibx) mail_close (sysibx);    MM_NOCRITICAL (stream);	/* release critical */    LOCAL->lastsnarf = time (0);/* note time of last snarf */  }}/* MBX mail copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    copy options * Returns: T if success, NIL if failed */long mbx_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){  struct stat sbuf;  time_t tp[2];  MESSAGECACHE *elt;  unsigned long i,j,k,m;  long ret = LONGT;  int fd,ld;  char *s,*t,file[MAILTMPLEN],lock[MAILTMPLEN];  mailproxycopy_t pc =    (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);  copyuid_t cu = (copyuid_t) mail_parameters (NIL,GET_COPYUID,NIL);  SEARCHSET *source = cu ? mail_newsearchset () : NIL;  SEARCHSET *dest = cu ? mail_newsearchset () : NIL;  MAILSTREAM *dstream = NIL;  if (!((options & CP_UID) ? mail_uid_sequence (stream,sequence) :	mail_sequence (stream,sequence))) return NIL;				/* make sure valid mailbox */  if ((fd = mbx_isvalid (&dstream,mailbox,file,&ld,lock,			 cu ? MBXISVALIDUID : MBXISVALIDNOUID)) < 0)    switch (errno) {    case ENOENT:		/* no such file? */      MM_NOTIFY (stream,"[TRYCREATE] Must create mailbox before copy",NIL);      return NIL;    case EACCES:		/* file protected */      sprintf (LOCAL->buf,"Can't access destination: %.80s",mailbox);      MM_LOG (LOCAL->buf,ERROR);      return NIL;    case EINVAL:      if (pc) return (*pc) (stream,sequence,mailbox,options);      sprintf (LOCAL->buf,"Invalid MBX-format mailbox name: %.80s",mailbox);      MM_LOG (LOCAL->buf,ERROR);      return NIL;    default:      if (pc) return (*pc) (stream,sequence,mailbox,options);      sprintf (LOCAL->buf,"Not a MBX-format mailbox: %.80s",mailbox);      MM_LOG (LOCAL->buf,ERROR);      return NIL;    }  MM_CRITICAL (stream);		/* go critical */  fstat (fd,&sbuf);		/* get current file size */  lseek (fd,sbuf.st_size,L_SET);/* move to end of file */				/* for each requested message */  for (i = 1; ret && (i <= stream->nmsgs); i++)     if ((elt = mail_elt (stream,i))->sequence) {      lseek (LOCAL->fd,elt->private.special.offset +	     elt->private.special.text.size,L_SET);      mail_date(LOCAL->buf,elt);/* build target header */				/* get target keyword mask */      for (j = elt->user_flags, k = 0; j; )	if (s = stream->user_flags[find_rightmost_bit (&j)])	  for (m = 0; (m < NUSERFLAGS) && (t = dstream->user_flags[m]); m++)	    if (!compare_cstring (s,t) && (k |= 1 << m)) break;      sprintf (LOCAL->buf+strlen(LOCAL->buf),",%lu;%08lx%04x-%08lx\015\012",	       elt->rfc822_size,k,(unsigned)	       ((fSEEN * elt->seen) + (fDELETED * elt->deleted) +		(fFLAGGED * elt->flagged) + (fANSWERED * elt->answered) +		(fDRAFT * elt->draft)),cu ? ++dstream->uid_last : 0);				/* write target header */      if (ret = (write (fd,LOCAL->buf,strlen (LOCAL->buf)) > 0)) {	for (k = elt->rfc822_size; ret && (j = min (k,LOCAL->buflen)); k -= j){	  read (LOCAL->fd,LOCAL->buf,j);	  ret = write (fd,LOCAL->buf,j) >= 0;	}	if (cu) {		/* need to pass back new UID? */	  mail_append_set (source,mail_uid (stream,i));	  mail_append_set (dest,dstream->uid_last);	}      }    }				/* make sure all the updates take */  if (!(ret && (ret = !fsync (fd)))) {    sprintf (LOCAL->buf,"Unable to write message: %s",strerror (errno));    MM_LOG (LOCAL->buf,ERROR);    ftruncate (fd,sbuf.st_size);  }  if (cu && ret) {		/* return sets if doing COPYUID */    (*cu) (stream,mailbox,dstream->uid_validity,source,dest);    lseek (fd,15,L_SET);	/* update UIDLAST */    sprintf (LOCAL->buf,"%08lx",dstream->uid_last);    write (fd,LOCAL->buf,8);  }  else {			/* flush any sets we may have built */    mail_free_searchset (&source);    mail_free_searchset (&dest);  }  if (ret) tp[0] = time (0) - 1;/* set atime to now-1 if successful copy */				/* else preserve \Marked status */  else tp[0] = (sbuf.st_ctime > sbuf.st_atime) ? sbuf.st_atime : time(0);  tp[1] = sbuf.st_mtime;	/* preserve mtime */  utime (file,tp);		/* set the times */  close (fd);			/* close the file */  MM_NOCRITICAL (stream);	/* release critical */  unlockfd (ld,lock);		/* release exclusive parse/append permission */				/* delete all requested messages */  if (ret && (options & CP_MOVE) && mbx_flaglock (stream)) {    for (i = 1; i <= stream->nmsgs; i++) if (mail_elt (stream,i)->sequence) {				/* mark message deleted */      mbx_elt (stream,i,NIL)->deleted = T;				/* recalculate status */      mbx_update_status (stream,i,NIL);    }				/* update flags */    mbx_flag (stream,NIL,NIL,NIL);  }  if (dstream != stream) mail_close (dstream);  return ret;}/* MBX mail append message from stringstruct * Accepts: MAIL stream *	    destination mailbox *	    append callback *	    data for callback * Returns: T if append successful, else NIL */long mbx_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){  struct stat sbuf;  int fd,ld;  char *flags,*date,tmp[MAILTMPLEN],file[MAILTMPLEN],lock[MAILTMPLEN];  time_t tp[2];  FILE *df;  MESSAGECACHE elt;  long f;  unsigned long i,uf;  STRING *message;  long ret = NIL;  MAILSTREAM *dstream = NIL;  appenduid_t au = (appenduid_t) mail_parameters (NIL,GET_APPENDUID,NIL);

⌨️ 快捷键说明

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