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

📄 mmdf.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
    lines->text.size = strlen ((char *) (lines->text.data =					 (unsigned char *) "X-Status"));    lines = lines->next = mail_newstringlist ();    lines->text.size = strlen ((char *) (lines->text.data =					 (unsigned char *) "X-Keywords"));    lines = lines->next = mail_newstringlist ();    lines->text.size = strlen ((char *) (lines->text.data =					 (unsigned char *) "X-UID"));    lines = lines->next = mail_newstringlist ();    lines->text.size = strlen ((char *) (lines->text.data =					 (unsigned char *) "X-IMAP"));    lines = lines->next = mail_newstringlist ();    lines->text.size = strlen ((char *) (lines->text.data =					 (unsigned char *) "X-IMAPbase"));  }				/* go to header position */  lseek (LOCAL->fd,elt->private.special.offset +	 elt->private.msg.header.offset,L_SET);  if (flags & FT_INTERNAL) {	/* initial data OK? */    if (elt->private.msg.header.text.size > LOCAL->buflen) {      fs_give ((void **) &LOCAL->buf);      LOCAL->buf = (char *) fs_get ((LOCAL->buflen =				     elt->private.msg.header.text.size) + 1);    }				/* read message */    read (LOCAL->fd,LOCAL->buf,elt->private.msg.header.text.size);				/* got text, tie off string */    LOCAL->buf[*length = elt->private.msg.header.text.size] = '\0';				/* squeeze out CRs (in case from PC) */    for (s = t = LOCAL->buf,tl = LOCAL->buf + *length; t < tl; t++)      if (*t != '\r') *s++ = *t;    *s = '\0';    *length = s - LOCAL->buf;	/* adjust length */  }  else {			/* need to make a CRLF version */    read (LOCAL->fd,s = (char *) fs_get (elt->private.msg.header.text.size+1),	  elt->private.msg.header.text.size);				/* tie off string, and convert to CRLF */    s[elt->private.msg.header.text.size] = '\0';    *length = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen,s,			  elt->private.msg.header.text.size);    fs_give ((void **) &s);	/* free readin buffer */				/* squeeze out spurious CRs */    for (s = t = LOCAL->buf,tl = LOCAL->buf + *length; t < tl; t++)      if ((*t != '\r') || (t[1] == '\n')) *s++ = *t;    *s = '\0';    *length = s - LOCAL->buf;	/* adjust length */  }  *length = mail_filter (LOCAL->buf,*length,mmdf_hlines,FT_NOT);  return (char *) LOCAL->buf;	/* return processed copy */}/* MMDF mail fetch message text * Accepts: MAIL stream *	    message # to fetch *	    pointer to returned stringstruct *	    option flags * Returns: T on success, NIL if failure */long mmdf_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){  char *s;  unsigned long i;  MESSAGECACHE *elt;				/* UID call "impossible" */  if (flags & FT_UID) return NIL;  elt = mail_elt (stream,msgno);/* get cache element */				/* if message not seen */  if (!(flags & FT_PEEK) && !elt->seen) {				/* mark message seen and dirty */    elt->seen = elt->private.dirty = LOCAL->dirty = T;    MM_FLAGS (stream,msgno);  }  s = mmdf_text_work (stream,elt,&i,flags);  INIT (bs,mail_string,s,i);	/* set up stringstruct */  return T;			/* success */}/* MMDF mail fetch message text worker routine * Accepts: MAIL stream *	    message cache element *	    pointer to returned header text length *	    option flags */char *mmdf_text_work (MAILSTREAM *stream,MESSAGECACHE *elt,		      unsigned long *length,long flags){  FDDATA d;  STRING bs;  unsigned char c,*s,*t,*tl,tmp[CHUNKSIZE];				/* go to text position */  lseek (LOCAL->fd,elt->private.special.offset +	 elt->private.msg.text.offset,L_SET);  if (flags & FT_INTERNAL) {	/* initial data OK? */    if (elt->private.msg.text.text.size > LOCAL->buflen) {      fs_give ((void **) &LOCAL->buf);      LOCAL->buf = (char *) fs_get ((LOCAL->buflen =				     elt->private.msg.text.text.size) + 1);    }				/* read message */    read (LOCAL->fd,LOCAL->buf,elt->private.msg.text.text.size);				/* got text, tie off string */    LOCAL->buf[*length = elt->private.msg.text.text.size] = '\0';				/* squeeze out CRs (in case from PC) */    for (s = t = LOCAL->buf,tl = LOCAL->buf + *length; t < tl; t++)      if (*t != '\r') *s++ = *t;    *s = '\0';    *length = s - LOCAL->buf;	/* adjust length */    return (char *) LOCAL->buf;  }				/* have it cached already? */  if (elt->private.uid != LOCAL->uid) {				/* not cached, cache it now */    LOCAL->uid = elt->private.uid;				/* is buffer big enough? */    if (elt->rfc822_size > LOCAL->text.size) {      /* excessively conservative, but the right thing is too hard to do */      fs_give ((void **) &LOCAL->text.data);      LOCAL->text.data = (unsigned char *)	fs_get ((LOCAL->text.size = elt->rfc822_size) + 1);    }    d.fd = LOCAL->fd;		/* yes, set up file descriptor */    d.pos = elt->private.special.offset + elt->private.msg.text.offset;    d.chunk = tmp;		/* initial buffer chunk */    d.chunksize = CHUNKSIZE;	/* file chunk size */    INIT (&bs,fd_string,&d,elt->private.msg.text.text.size);    for (s = (char *) LOCAL->text.data; SIZE (&bs);) switch (c = SNX (&bs)) {    case '\r':			/* carriage return seen */      break;    case '\n':      *s++ = '\r';		/* insert a CR */    default:      *s++ = c;			/* copy characters */    }    *s = '\0';			/* tie off buffer */				/* calculate length of cached data */    LOCAL->textlen = s - LOCAL->text.data;  }  *length = LOCAL->textlen;	/* return from cache */  return (char *) LOCAL->text.data;}/* MMDF per-message modify flag * Accepts: MAIL stream *	    message cache element */void mmdf_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt){				/* only after finishing */  if (elt->valid) elt->private.dirty = LOCAL->dirty = T;}/* MMDF mail ping mailbox * Accepts: MAIL stream * Returns: T if stream alive, else NIL */long mmdf_ping (MAILSTREAM *stream){  DOTLOCK lock;  struct stat sbuf;  long reparse;				/* big no-op if not readwrite */  if (LOCAL && (LOCAL->ld >= 0) && !stream->lock) {    if (stream->rdonly) {	/* does he want to give up readwrite? */				/* checkpoint if we changed something */      if (LOCAL->dirty) mmdf_check (stream);      flock (LOCAL->ld,LOCK_UN);/* release readwrite lock */      close (LOCAL->ld);	/* close the readwrite lock file */      LOCAL->ld = -1;		/* no more readwrite lock fd */      unlink (LOCAL->lname);	/* delete the readwrite lock file */    }    else {			/* see if need to reparse */      if (!(reparse = (long) mail_parameters (NIL,GET_NETFSSTATBUG,NIL))) {				/* get current mailbox size */	if (LOCAL->fd >= 0) fstat (LOCAL->fd,&sbuf);	else if (stat (stream->mailbox,&sbuf)) {	  sprintf (LOCAL->buf,"Mailbox stat failed, aborted: %s",		   strerror (errno));	  MM_LOG (LOCAL->buf,ERROR);	  mmdf_abort (stream);	  return NIL;	}	reparse = (sbuf.st_size != LOCAL->filesize);      }				/* parse if mailbox changed */      if ((LOCAL->ddirty || reparse) && mmdf_parse (stream,&lock,LOCK_EX)) {				/* force checkpoint if double-dirty */	if (LOCAL->ddirty) mmdf_rewrite (stream,NIL,&lock,NIL);				/* unlock mailbox */	else mmdf_unlock (LOCAL->fd,stream,&lock);	mail_unlock (stream);	/* and stream */				/* done with critical */	MM_NOCRITICAL (stream);      }    }  }  return LOCAL ? LONGT : NIL;	/* return if still alive */}/* MMDF mail check mailbox * Accepts: MAIL stream */void mmdf_check (MAILSTREAM *stream){  DOTLOCK lock;				/* parse and lock mailbox */  if (LOCAL && (LOCAL->ld >= 0) && !stream->lock &&      mmdf_parse (stream,&lock,LOCK_EX)) {				/* any unsaved changes? */    if (LOCAL->dirty && mmdf_rewrite (stream,NIL,&lock,NIL)) {      if (!stream->silent) MM_LOG ("Checkpoint completed",NIL);    }				/* no checkpoint needed, just unlock */    else mmdf_unlock (LOCAL->fd,stream,&lock);    mail_unlock (stream);	/* unlock the stream */    MM_NOCRITICAL (stream);	/* done with critical */  }}/* MMDF mail expunge mailbox * Accepts: MAIL stream *	    sequence to expunge if non-NIL *	    expunge options * Returns: T, always */long mmdf_expunge (MAILSTREAM *stream,char *sequence,long options){  long ret;  unsigned long i;  DOTLOCK lock;  char *msg = NIL;  if (ret = (sequence ? ((options & EX_UID) ?			 mail_uid_sequence (stream,sequence) :			 mail_sequence (stream,sequence)) : LONGT) &&      LOCAL && (LOCAL->ld >= 0) && !stream->lock &&      mmdf_parse (stream,&lock,LOCK_EX)) {				/* check expunged messages if not dirty */    for (i = 1; !LOCAL->dirty && (i <= stream->nmsgs); i++) {      MESSAGECACHE *elt = mail_elt (stream,i);      if (mail_elt (stream,i)->deleted) LOCAL->dirty = T;    }    if (!LOCAL->dirty) {	/* not dirty and no expunged messages */      mmdf_unlock (LOCAL->fd,stream,&lock);      msg = "No messages deleted, so no update needed";    }    else if (mmdf_rewrite (stream,&i,&lock,sequence ? LONGT : NIL)) {      if (i) sprintf (msg = LOCAL->buf,"Expunged %lu messages",i);      else msg = "Mailbox checkpointed, but no messages expunged";    }				/* rewrite failed */    else mmdf_unlock (LOCAL->fd,stream,&lock);    mail_unlock (stream);	/* unlock the stream */    MM_NOCRITICAL (stream);	/* done with critical */    if (msg && !stream->silent) MM_LOG (msg,NIL);  }  else if (!stream->silent)    MM_LOG ("Expunge ignored on readonly mailbox",WARN);  return ret;}/* MMDF mail copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    copy options * Returns: T if copy successful, else NIL */long mmdf_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){  struct stat sbuf;  int fd;  char *s,file[MAILTMPLEN];  DOTLOCK lock;  time_t tp[2];  unsigned long i,j;  MESSAGECACHE *elt;  long ret = T;  mailproxycopy_t pc =    (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);  copyuid_t cu = (copyuid_t) (mail_parameters (NIL,GET_USERHASNOLIFE,NIL) ?			      NIL : mail_parameters (NIL,GET_COPYUID,NIL));  SEARCHSET *source = cu ? mail_newsearchset () : NIL;  SEARCHSET *dest = cu ? mail_newsearchset () : NIL;  MAILSTREAM *tstream = NIL;  if (!((options & CP_UID) ? mail_uid_sequence (stream,sequence) :	mail_sequence (stream,sequence))) return NIL;				/* make sure destination is valid */  if (!(mmdf_valid (mailbox) || !errno))    switch (errno) {    case ENOENT:		/* no such file? */      if (compare_cstring (mailbox,"INBOX")) {	MM_NOTIFY (stream,"[TRYCREATE] Must create mailbox before copy",NIL);	return NIL;      }      if (pc) return (*pc) (stream,sequence,mailbox,options);      mmdf_create (NIL,"INBOX");/* create empty INBOX */    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 MMDF-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 MMDF-format mailbox: %.80s",mailbox);      MM_LOG (LOCAL->buf,ERROR);      return NIL;    }				/* try to open rewrite for UIDPLUS */  if ((tstream = mail_open_work (&mmdfdriver,NIL,mailbox,				 OP_SILENT|OP_NOKOD)) && tstream->rdonly)    tstream = mail_close (tstream);  if (cu && !tstream) {		/* wanted a COPYUID? */    sprintf (LOCAL->buf,"Unable to write-open mailbox for COPYUID: %.80s",	     mailbox);    MM_LOG (LOCAL->buf,WARN);    cu = NIL;			/* don't try to do COPYUID */  }  LOCAL->buf[0] = '\0';  MM_CRITICAL (stream);		/* go critical */  if ((fd = mmdf_lock (dummy_file (file,mailbox),O_WRONLY|O_APPEND,		       (long) mail_parameters (NIL,GET_MBXPROTECTION,NIL),		       &lock,LOCK_EX)) < 0) {    MM_NOCRITICAL (stream);	/* done with critical */    sprintf (LOCAL->buf,"Can't open destination mailbox: %s",strerror (errno));    MM_LOG (LOCAL->buf,ERROR);	/* log the error */    return NIL;			/* failed */  }  fstat (fd,&sbuf);		/* get current file size */				/* write all requested messages to mailbox */  for (i = 1; ret && (i <= stream->nmsgs); i++)    if ((elt = mail_elt (stream,i))->sequence) {      lseek (LOCAL->fd,elt->private.special.offset,L_SET);      read (LOCAL->fd,LOCAL->buf,elt->private.special.text.size);      if (write (fd,LOCAL->buf,elt->private.special.text.size) < 0) ret = NIL;      else {			/* internal header succeeded */	s = mmdf_header (stream,i,&j,FT_INTERNAL);				/* header size, sans trailing newline */	if (j && (s[j - 2] == '\n')) j--;	if (write (fd,s,j) < 0) ret = NIL;	else {			/* message header succeeded */	  j = tstream ?		/* write UIDPLUS data if have readwrite */	    mmdf_xstatus (stream,LOCAL->buf,elt,++(tstream->uid_last),LONGT) :	    mmdf_xstatus (stream,LOCAL->buf,elt,NIL,NIL);	  if (write (fd,LOCAL->buf,j) < 0) ret = NIL;	  else {		/* message status succeeded */	    s = mmdf_text_work (stream,elt,&j,FT_INTERNAL);	    if ((write (fd,s,j) < 0) || (write (fd,mmdfhdr,MMDFHDRLEN) < 0))	      ret = NIL;	    else if (cu) {	/* need to pass back new UID? */	      mail_append_set (source,mail_uid (stream,i));	      mail_append_set (dest,tstream->uid_last);	    }	  }	}      }

⌨️ 快捷键说明

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