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

📄 mx.c

📁 这是用C编写IMAP源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				/* if deleted, need to trash it */      if ((elt = mail_elt (stream,i))->deleted) {	sprintf (LOCAL->buf,"%s/%lu",LOCAL->dir,elt->private.uid);	if (unlink (LOCAL->buf)) {/* try to delete the message */	  sprintf (LOCAL->buf,"Expunge of message %lu failed, aborted: %s",i,		   strerror (errno));	  MM_LOG (LOCAL->buf,(long) NIL);	  break;	}				/* note uncached */	LOCAL->cachedtexts -= ((elt->private.msg.header.text.data ?				elt->private.msg.header.text.size : 0) +			       (elt->private.msg.text.text.data ?				elt->private.msg.text.text.size : 0));	mail_gc_msg (&elt->private.msg,GC_ENV | GC_TEXTS);	if(elt->recent)--recent;/* if recent, note one less recent message */	mail_expunged(stream,i);/* notify upper levels */	n++;			/* count up one more expunged message */      }      else i++;			/* otherwise try next message */    }    if (n) {			/* output the news if any expunged */      sprintf (LOCAL->buf,"Expunged %lu messages",n);      MM_LOG (LOCAL->buf,(long) NIL);    }    else MM_LOG ("No messages deleted, so no update needed",(long) NIL);    MM_NOCRITICAL (stream);	/* release critical */    mx_unlockindex (stream);	/* finished with index */  }				/* notify upper level of new mailbox size */  mail_exists (stream,stream->nmsgs);  mail_recent (stream,recent);}/* MX mail copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    copy options * Returns: T if copy successful, else NIL */long mx_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){  STRING st;  MESSAGECACHE *elt;  struct stat sbuf;  int fd;  unsigned long i,j;  char *t,flags[MAILTMPLEN],date[MAILTMPLEN];				/* copy the messages */  if ((options & CP_UID) ? mail_uid_sequence (stream,sequence) :      mail_sequence (stream,sequence))    for (i = 1; i <= stream->nmsgs; i++)       if ((elt = mail_elt (stream,i))->sequence) {	if ((fd = open (mx_fast_work (stream,elt),O_RDONLY,NIL))<0) return NIL;	fstat (fd,&sbuf);	/* get size of message */				/* is buffer big enough? */	if (sbuf.st_size > LOCAL->buflen) {	  fs_give ((void **) &LOCAL->buf);	  LOCAL->buf = (char *) fs_get ((LOCAL->buflen = sbuf.st_size) + 1);	}				/* slurp message */	read (fd,LOCAL->buf,sbuf.st_size);				/* tie off file */	LOCAL->buf[sbuf.st_size] = '\0';	close (fd);		/* flush message file */	INIT (&st,mail_string,(void *) LOCAL->buf,sbuf.st_size);				/* init flag string */	flags[0] = flags[1] = '\0';	if (j = elt->user_flags) do	  if (t = stream->user_flags[find_rightmost_bit (&j)])	    strcat (strcat (flags," "),t);	while (j);	if (elt->seen) strcat (flags," \\Seen");	if (elt->deleted) strcat (flags," \\Deleted");	if (elt->flagged) strcat (flags," \\Flagged");	if (elt->answered) strcat (flags," \\Answered");	if (elt->draft) strcat (flags," \\Draft");	flags[0] = '(';		/* open list */	strcat (flags,")");	/* close list */	mail_date (date,elt);	/* generate internal date */	if (!mail_append_full (NIL,mailbox,flags,date,&st)) return NIL;	if (options & CP_MOVE) elt->deleted = T;      }  return T;			/* return success */}/* MX mail append message from stringstruct * Accepts: MAIL stream *	    destination mailbox *	    append callback *	    data for callback * Returns: T if append successful, else NIL */long mx_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){  MESSAGECACHE *elt,selt;  MAILSTREAM *astream;  int fd;  char *flags,*date,*s,tmp[MAILTMPLEN];  STRING *message;  long f,i,size;  unsigned long uf;  long ret = LONGT;				/* default stream to prototype */  if (!stream) stream = user_flags (&mxproto);				/* N.B.: can't use LOCAL->buf for tmp */				/* make sure valid mailbox */  if (!mx_isvalid (mailbox,tmp)) switch (errno) {  case ENOENT:			/* no such file? */    if (!compare_cstring (mailbox,"INBOX")) mx_create (NIL,"INBOX");    else {      MM_NOTIFY (stream,"[TRYCREATE] Must create mailbox before append",NIL);      return NIL;    }				/* falls through */  case 0:			/* merely empty file? */    break;  case EINVAL:    sprintf (tmp,"Invalid MX-format mailbox name: %.80s",mailbox);    MM_LOG (tmp,ERROR);    return NIL;  default:    sprintf (tmp,"Not a MX-format mailbox: %.80s",mailbox);    MM_LOG (tmp,ERROR);    return NIL;  }				/* get first message */  if (!MM_APPEND (af) (stream,data,&flags,&date,&message)) return NIL;  if (!(astream = mail_open (NIL,mailbox,OP_SILENT))) {    sprintf (tmp,"Can't open append mailbox: %s",strerror (errno));    MM_LOG (tmp,ERROR);    return NIL;  }  MM_CRITICAL (stream);	/* go critical */				/* lock the index */  if (mx_lockindex (astream)) do {    if (!SIZE (message)) {	/* guard against zero-length */      MM_LOG ("Append of zero-length message",ERROR);      ret = NIL;      break;    }				/* parse flags */    f = mail_parse_flags (astream,flags,&uf);    if (date) {			/* want to preserve date? */				/* yes, parse date into an elt */      if (!mail_parse_date (&selt,date)) {	sprintf (tmp,"Bad date in append: %.80s",date);	MM_LOG (tmp,ERROR);	ret = NIL;	break;      }    }    mx_file (tmp,mailbox);	/* make message name */    sprintf (tmp + strlen (tmp),"/%lu",++astream->uid_last);    if ((fd = open (tmp,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {      sprintf (tmp,"Can't create append message: %s",strerror (errno));      MM_LOG (tmp,ERROR);      ret = NIL;      break;    }				/* copy message */    s = (char *) fs_get (size = SIZE (message));    for (i = 0; i < size; s[i++] = SNX (message));				/* write the data */    if ((write (fd,s,size) < 0) || fsync (fd)) {      unlink (tmp);		/* delete mailbox */      sprintf (tmp,"Message append failed: %s",strerror (errno));      MM_LOG (tmp,ERROR);      ret = NIL;    }    fs_give ((void **) &s);	/* flush the buffer */    close (fd);			/* close the file */    if (ret) {			/* set the date for this message */      if (date) mx_setdate (tmp,&selt);				/* swell the cache */      mail_exists (astream,++astream->nmsgs);				/* copy flags */      (elt = mail_elt (astream,astream->nmsgs))->private.uid=astream->uid_last;      if (f&fSEEN) elt->seen = T;      if (f&fDELETED) elt->deleted = T;      if (f&fFLAGGED) elt->flagged = T;      if (f&fANSWERED) elt->answered = T;      if (f&fDRAFT) elt->draft = T;      elt->user_flags |= uf;				/* get next message */      if (!MM_APPEND (af) (stream,data,&flags,&date,&message)) ret = NIL;    }  } while (ret && message);  else {    MM_LOG ("Message append failed: unable to lock index",ERROR);    ret = NIL;  }  mx_unlockindex (astream);	/* unlock index */  MM_NOCRITICAL (stream);	/* release critical */  mail_close (astream);  return ret;}/* Internal routines *//* MX file name selection test * Accepts: candidate directory entry * Returns: T to use file name, NIL to skip it */int mx_select (struct direct *name){  char c;  char *s = name->d_name;  while (c = *s++) if (!isdigit (c)) return NIL;  return T;}/* MX file name comparision * Accepts: first candidate directory entry *	    second candidate directory entry * Returns: negative if d1 < d2, 0 if d1 == d2, postive if d1 > d2 */int mx_numsort (const void *d1,const void *d2){  return atoi ((*(struct direct **) d1)->d_name) -    atoi ((*(struct direct **) d2)->d_name);}/* MX mail build file name * Accepts: destination string *          source * Returns: destination */char *mx_file (char *dst,char *name){  char *s;  if (!(mailboxfile (dst,name) && *dst)) return mailboxfile (dst,"~/INBOX");				/* tie off unnecessary trailing / */  if ((s = strrchr (dst,'/')) && !s[1]) *s = '\0';  return dst;}/* MX read and lock index * Accepts: MAIL stream * Returns: T if success, NIL if failure */long mx_lockindex (MAILSTREAM *stream){  unsigned long uf,sf,uid;  int k = 0;  unsigned long msgno = 1;  struct stat sbuf;  char *s,*t,*idx,tmp[MAILTMPLEN];  MESSAGECACHE *elt;  blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);  if ((LOCAL->fd < 0) &&	/* get index file, no-op if already have it */      (LOCAL->fd = open (strcat (strcpy (tmp,LOCAL->dir),MXINDEXNAME),			 O_RDWR|O_CREAT,S_IREAD|S_IWRITE)) >= 0) {    (*bn) (BLOCK_FILELOCK,NIL);    flock (LOCAL->fd,LOCK_EX);	/* get exclusive lock */    (*bn) (BLOCK_NONE,NIL);    fstat (LOCAL->fd,&sbuf);	/* get size of index */				/* slurp index */    read (LOCAL->fd,s = idx = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);    idx[sbuf.st_size] = '\0';	/* tie off index */				/* parse index */    if (sbuf.st_size) while (s && *s) switch (*s) {    case 'V':			/* UID validity record */      stream->uid_validity = strtoul (s+1,&s,16);      break;    case 'L':			/* UID last record */      stream->uid_last = strtoul (s+1,&s,16);      break;    case 'K':			/* keyword */				/* find end of keyword */      if (s = strchr (t = ++s,'\n')) {	*s++ = '\0';		/* tie off keyword */				/* copy keyword */	if ((k < NUSERFLAGS) && !stream->user_flags[k] &&	    (strlen (t) <= MAXUSERFLAG)) stream->user_flags[k] = cpystr (t);	k++;			/* one more keyword */      }      break;    case 'M':			/* message status record */      uid = strtoul (s+1,&s,16);/* get UID for this message */      if (*s == ';') {		/* get user flags */	uf = strtoul (s+1,&s,16);	if (*s == '.') {	/* get system flags */	  sf = strtoul (s+1,&s,16);	  while ((msgno <= stream->nmsgs) && (mail_uid (stream,msgno) < uid))	    msgno++;		/* find message number for this UID */	  if ((msgno <= stream->nmsgs) && (mail_uid (stream,msgno) == uid)) {	    (elt = mail_elt (stream,msgno))->valid = T;	    elt->user_flags=uf; /* set user and system flags in elt */	    if (sf & fSEEN) elt->seen = T;	    if (sf & fDELETED) elt->deleted = T;	    if (sf & fFLAGGED) elt->flagged = T;	    if (sf & fANSWERED) elt->answered = T;	    if (sf & fDRAFT) elt->draft = T;	  }	  break;	}      }    default:			/* bad news */      sprintf (tmp,"Error in index: %.80s",s);      MM_LOG (tmp,ERROR);      *s = NIL;			/* ignore remainder of index */    }    else {			/* new index */      stream->uid_validity = time (0);      user_flags (stream);	/* init stream with default user flags */    }    fs_give ((void **) &idx);	/* flush index */  }  return (LOCAL->fd >= 0) ? T : NIL;}/* MX write and unlock index * Accepts: MAIL stream */void mx_unlockindex (MAILSTREAM *stream){  unsigned long i,j;  off_t size = 0;  char *s,tmp[MAILTMPLEN + 64];  MESSAGECACHE *elt;  if (LOCAL->fd >= 0) {    lseek (LOCAL->fd,0,L_SET);	/* rewind file */				/* write header */    sprintf (s = tmp,"V%08lxL%08lx",stream->uid_validity,stream->uid_last);    for (i = 0; (i < NUSERFLAGS) && stream->user_flags[i]; ++i)      sprintf (s += strlen (s),"K%s\n",stream->user_flags[i]);				/* write messages */    for (i = 1; i <= stream->nmsgs; i++) {				/* filled buffer? */      if (((s += strlen (s)) - tmp) > MAILTMPLEN) {	write (LOCAL->fd,tmp,j = s - tmp);	size += j;	*(s = tmp) = '\0';	/* dump out and restart buffer */      }      elt = mail_elt (stream,i);      sprintf(s,"M%08lx;%08lx.%04x",elt->private.uid,elt->user_flags,(unsigned)	      ((fSEEN * elt->seen) + (fDELETED * elt->deleted) +	       (fFLAGGED * elt->flagged) + (fANSWERED * elt->answered) +	       (fDRAFT * elt->draft)));    }				/* write tail end of buffer */    if ((s += strlen (s)) != tmp) {      write (LOCAL->fd,tmp,j = s - tmp);      size += j;    }    ftruncate (LOCAL->fd,size);    flock (LOCAL->fd,LOCK_UN);	/* unlock the index */    close (LOCAL->fd);		/* finished with file */    LOCAL->fd = -1;		/* no index now */  }}/* Set date for message * Accepts: file name *	    elt containing date */void mx_setdate (char *file,MESSAGECACHE *elt){  time_t tp[2];  tp[0] = time (0);		/* atime is now */  tp[1] = mail_longdate (elt);	/* modification time */  utime (file,tp);		/* set the times */}

⌨️ 快捷键说明

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