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

📄 unixnt.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
	do {			/* look for message body */	  s = t = unix_mbxline (stream,&bs,&i);	  if (i) switch (*s) {	/* check header lines */	  case 'X':		/* possible X-???: line */	    if (s[1] == '-') {	/* must be immediately followed by hyphen */				/* X-Status: becomes Status: in S case */	      if (s[2] == 'S' && s[3] == 't' && s[4] == 'a' && s[5] == 't' &&		  s[6] == 'u' && s[7] == 's' && s[8] == ':') s += 2;				/* possible X-Keywords */	      else if (s[2] == 'K' && s[3] == 'e' && s[4] == 'y' &&		       s[5] == 'w' && s[6] == 'o' && s[7] == 'r' &&		       s[8] == 'd' && s[9] == 's' && s[10] == ':') {		SIZEDTEXT uf;		retain = NIL;	/* don't retain continuation */		s += 11;	/* flush leading whitespace */		while (*s && (*s != '\n') && ((*s != '\r') || (s[1] != '\n'))){		  while (*s == ' ') s++;				/* find end of keyword */		  if (!(u = strpbrk (s," \n\r"))) u = s + strlen (s);				/* got a keyword? */		  if ((k = (u - s)) && (k <= MAXUSERFLAG)) {		    uf.data = (unsigned char *) s;		    uf.size = k;		    for (j = 0; (j < NUSERFLAGS) && stream->user_flags[j]; ++j)		      if (!compare_csizedtext (stream->user_flags[j],&uf)) {			elt->user_flags |= ((long) 1) << j;			break;		      }		  }		  s = u;	/* advance to next keyword */		}		break;	      }				/* possible X-IMAP */	      else if ((s[2] == 'I') && (s[3] == 'M') && (s[4] == 'A') &&		       (s[5] == 'P') && ((m = (s[6] == ':')) ||					 ((s[6] == 'b') && (s[7] == 'a') &&					  (s[8] == 's') && (s[9] == 'e') &&					  (s[10] == ':')))) {		retain = NIL;	/* don't retain continuation */		if ((nmsgs == 1) && !stream->uid_validity) {				/* advance to data */		  s += m ? 7 : 11;				/* flush whitespace */		  while (*s == ' ') s++;		  j = 0;	/* slurp UID validity */				/* found a digit? */		  while (isdigit (*s)) {		    j *= 10;	/* yes, add it in */		    j += *s++ - '0';		  }				/* flush whitespace */		  while (*s == ' ') s++;				/* must have valid UID validity and UID last */		  if (j && isdigit (*s)) {				/* pseudo-header seen if X-IMAP */		    if (m) pseudoseen = LOCAL->pseudo = T;				/* save UID validity */		    stream->uid_validity = j;		    j = 0;	/* slurp UID last */		    while (isdigit (*s)) {		      j *= 10;	/* yes, add it in */		      j += *s++ - '0';		    }				/* save UID last */		    stream->uid_last = j;				/* process keywords */		    for (j = 0; (*s != '\n') && ((*s != '\r')||(s[1] != '\n'));			 s = u,j++) {				/* flush leading whitespace */		      while (*s == ' ') s++;		      u = strpbrk (s," \n\r");				/* got a keyword? */		      if ((j < NUSERFLAGS) && (k = (u - s)) &&			  (k <= MAXUSERFLAG)) {			if (stream->user_flags[j])			  fs_give ((void **) &stream->user_flags[j]);			stream->user_flags[j] = (char *) fs_get (k + 1);			strncpy (stream->user_flags[j],s,k);			stream->user_flags[j][k] = '\0';		      }		    }		  }		}		break;	      }				/* possible X-UID */	      else if (s[2] == 'U' && s[3] == 'I' && s[4] == 'D' &&		       s[5] == ':') {		retain = NIL;	/* don't retain continuation */				/* only believe if have a UID validity */		if (stream->uid_validity && ((nmsgs > 1) || !pseudoseen)) {		  s += 6;	/* advance to UID value */				/* flush whitespace */		  while (*s == ' ') s++;		  j = 0;				/* found a digit? */		  while (isdigit (*s)) {		    j *= 10;	/* yes, add it in */		    j += *s++ - '0';		  }				/* flush remainder of line */		  while (*s != '\n') s++;				/* make sure not duplicated */		  if (elt->private.uid)		    sprintf (tmp,"Message %lu UID %lu already has UID %lu",			     pseudoseen ? elt->msgno - 1 : elt->msgno,			     j,elt->private.uid);				/* make sure UID doesn't go backwards */		  else if (j <= prevuid)		    sprintf (tmp,"Message %lu UID %lu less than %lu",			     pseudoseen ? elt->msgno - 1 : elt->msgno,			     j,prevuid + 1);#if 0	/* this is currently broken by UIDPLUS */				/* or skip by mailbox's recorded last */		  else if (j > stream->uid_last)		    sprintf (tmp,"Message %lu UID %lu greater than last %lu",			     pseudoseen ? elt->msgno - 1 : elt->msgno,			     j,stream->uid_last);#endif		  else {	/* normal UID case */		    prevuid = elt->private.uid = j;#if 1	/* temporary kludge for UIDPLUS */		    if (prevuid > stream->uid_last) {		      stream->uid_last = prevuid;		      LOCAL->ddirty = LOCAL->dirty = T;		    }		    #endif		    break;	/* exit this cruft */		  }		  mm_log (tmp,WARN);				/* invalidate UID validity */		  stream->uid_validity = 0;		  elt->private.uid = 0;		}		break;	      }	    }				/* otherwise fall into S case */	  case 'S':		/* possible Status: line */	    if (s[0] == 'S' && s[1] == 't' && s[2] == 'a' && s[3] == 't' &&		s[4] == 'u' && s[5] == 's' && s[6] == ':') {	      retain = NIL;	/* don't retain continuation */	      s += 6;		/* advance to status flags */	      do switch (*s++) {/* parse flags */	      case 'R':		/* message read */		elt->seen = T;		break;	      case 'O':		/* message old */		if (elt->recent) {		  elt->recent = NIL;		  recent--;	/* it really wasn't recent */		}		break;	      case 'D':		/* message deleted */		elt->deleted = T;		break;	      case 'F':		/* message flagged */		elt->flagged = T;		break;	      case 'A':		/* message answered */		elt->answered = T;		break;	      case 'T':		/* message is a draft */		elt->draft = T;		break;	      default:		/* some other crap */		break;	      } while (*s && (*s != '\n') && ((*s != '\r') || (s[1] != '\n')));	      break;		/* all done */	    }				/* otherwise fall into default case */	  default:		/* ordinary header line */	    if ((*s == 'S') || (*s == 's') ||		(((*s == 'X') || (*s == 'x')) && (s[1] == '-'))) {	      unsigned char *e,*v;				/* must match what mail_filter() does */	      for (u = s,v = tmp,e = u + min (i,MAILTMPLEN - 1);		   (u < e) && ((c = (*u ? *u : (*u = ' '))) != ':') &&		   ((c > ' ') || ((c != ' ') && (c != '\t') &&				  (c != '\r') && (c != '\n')));		   *v++ = *u++);	      *v = '\0';	/* tie off */				/* matches internal header? */	      if (!compare_cstring (tmp,"STATUS") ||		  !compare_cstring (tmp,"X-STATUS") ||		  !compare_cstring (tmp,"X-KEYWORDS") ||		  !compare_cstring (tmp,"X-UID") ||		  !compare_cstring (tmp,"X-IMAP") ||		  !compare_cstring (tmp,"X-IMAPBASE")) {		char err[MAILTMPLEN];		sprintf (err,"Discarding bogus %s header in message %lu",			 (char *) tmp,elt->msgno);		mm_log (err,WARN);		retain = NIL;	/* don't retain continuation */		break;		/* different case or something */	      }	    }				/* retain or non-continuation? */	    if (retain || ((*s != ' ') && (*s != '\t'))) {	      retain = T;	/* retaining continuation now */				/* line length in CRLF format newline */	      k = i + (((i < 2) || (s[i - 2] != '\r')) ? 1 : 0);				/* header size */	      elt->rfc822_size = elt->private.spare.data += k;	    }	    else {	      char err[MAILTMPLEN];	      sprintf (err,"Discarding bogus continuation in msg %lu: %.80s",		      elt->msgno,(char *) s);	      if (u = strpbrk (err,"\r\n")) *u = '\0';	      mm_log (err,WARN);	      break;		/* different case or something */	    }	    break;	  }	} while (i && (*t != '\n') && ((*t != '\r') || (t[1] != '\n')));				/* "internal" header sans trailing newline */	if (i) elt->private.spare.data -= 2;				/* assign a UID if none found */	if (((nmsgs > 1) || !pseudoseen) && !elt->private.uid) {	  prevuid = elt->private.uid = ++stream->uid_last;	  elt->private.dirty = T;	  LOCAL->ddirty = T;	/* force update */	}	else elt->private.dirty = elt->recent;				/* note size of header, location of text */	elt->private.msg.header.text.size = 	  (elt->private.msg.text.offset =	   (LOCAL->filesize + GETPOS (&bs)) - elt->private.special.offset) -	     elt->private.special.text.size;	k = m = 0;		/* no previous line size yet */				/* note current position */	j = LOCAL->filesize + GETPOS (&bs);	if (i) do {		/* look for next message */	  s = unix_mbxline (stream,&bs,&i);	  if (i) {		/* got new data? */	    VALID (s,t,ti,zn);	/* yes, parse line */	    if (!ti) {		/* not a header line, add it to message */	      if (s[i - 1] == '\n')		elt->rfc822_size += 		  k = i + (m = (((i < 2) || s[i - 2] != '\r') ? 1 : 0));	      else {		/* file does not end with newline! */		elt->rfc822_size += i;		k = m = 0;	      }				/* update current position */	      j = LOCAL->filesize + GETPOS (&bs);	    }	  }	} while (i && !ti);	/* until found a header */	elt->private.msg.text.text.size = j -	  (elt->private.special.offset + elt->private.msg.text.offset);	if (k == 2) {		/* last line was blank? */	  elt->private.msg.text.text.size -= (m ? 1 : 2);	  elt->rfc822_size -= 2;	}				/* until end of buffer */      } while (!stream->sniff && i);      if (pseudoseen) {		/* flush pseudo-message if present */				/* decrement recent count */	if (mail_elt (stream,1)->recent) recent--;				/* and the exists count */	mail_exists (stream,nmsgs--);	mail_expunged(stream,1);/* fake an expunge of that message */      }				/* need to start a new UID validity? */      if (!stream->uid_validity) {	stream->uid_validity = (unsigned long) time (0);	if (nmsgs) {		/* don't bother if empty file */				/* make dirty to restart UID epoch */	  LOCAL->ddirty = LOCAL->dirty = T;				/* need to rewrite msg 1 if not pseudo */	  if (!LOCAL->pseudo) mail_elt (stream,1)->private.dirty = T;	  mm_log ("Assigning new unique identifiers to all messages",NIL);	}      }      stream->nmsgs = oldnmsgs;	/* whack it back down */      stream->silent = silent;	/* restore old silent setting */				/* notify upper level of new mailbox sizes */      mail_exists (stream,nmsgs);      mail_recent (stream,recent);				/* mark dirty so O flags are set */      if (recent) LOCAL->dirty = T;    }  }				/* no change, don't babble if never got time */  else if (LOCAL->filetime && LOCAL->filetime != sbuf.st_mtime)    mm_log ("New mailbox modification time but apparently no changes",WARN);				/* update parsed file size and time */  LOCAL->filesize = sbuf.st_size;  LOCAL->filetime = sbuf.st_mtime;  return T;			/* return the winnage */}/* UNIX read line from mailbox * Accepts: mail stream *	    stringstruct *	    pointer to line size * Returns: pointer to input line */char *unix_mbxline (MAILSTREAM *stream,STRING *bs,unsigned long *size){  unsigned long i,j,k,m;  char *s,*t,*te;  char *ret = "";				/* flush old buffer */  if (LOCAL->line) fs_give ((void **) &LOCAL->line);				/* if buffer needs refreshing */  if (!bs->cursize) SETPOS (bs,GETPOS (bs));  if (SIZE (bs)) {		/* find newline */				/* end of fast scan */    te = (t = (s = bs->curpos) + bs->cursize) - 12;    while (s < te) if ((*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n') ||		       (*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n') ||		       (*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n') ||		       (*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n')) {      --s;			/* back up */      break;			/* exit loop */    }				/* final character-at-a-time scan */    while ((s < t) && (*s != '\n')) ++s;				/* difficult case if line spans buffer */    if ((i = s - bs->curpos) == bs->cursize) {				/* have space in line buffer? */      if (i > LOCAL->linebuflen) {	fs_give ((void **) &LOCAL->linebuf);	LOCAL->linebuf = (char *) fs_get (LOCAL->linebuflen = i);      }				/* remember what we have so far */      memcpy (LOCAL->linebuf,bs->curpos,i);				/* load next buffer */      SETPOS (bs,k = GETPOS (bs) + i);				/* end of fast scan */      te = (t = (s = bs->curpos) + bs->cursize) - 12;				/* fast scan in overlap buffer */      while (s < te) if ((*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n') ||			 (*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n') ||			 (*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n') ||			 (*s++ == '\n') || (*s++ == '\n') || (*s++ == '\n')) {	--s;			/* back up */	break;			/* exit loop */      }				/* final character-at-a-time scan */      while ((s < t) && (*s != '\n')) ++s;				/* huge line? */      if ((j = s - bs->curpos) == bs->cursize) {	SETPOS (bs,GETPOS (bs) + j);				/* look for end of line (s-l-o-w!!) */	for (m = SIZE (bs); m && (SNX (bs) != '\n'); --m,++j);	SETPOS (bs,k);		/* go back to where it started */      }				/* got size of data, make buffer for return */      ret = LOCAL->line = (char *) fs_get (i + j + 2);				/* copy first chunk */      memcpy (ret,LOCAL->linebuf,i);      while (j) {		/* copy remainder */	if (!bs->cursize) SETPOS (bs,GETPOS (bs));	memcpy (ret + i,bs->curpos,k = min (j,bs->cursize));	i += k;			/* account for this much read in */	j -= k;	bs->curpos += k;	/* increment new position */	bs->cursize -= k;	/* eat that many bytes */      }      if (!bs->cursize) SETPOS (bs,GETPOS (bs));				/* read newline at end */      if (SIZE (bs)) ret[i++] = SNX (bs);      ret[i] = '\0';		/* 

⌨️ 快捷键说明

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