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

📄 mx.c

📁 这是用C编写IMAP源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* MX mail rename mailbox * Accepts: MX mail stream *	    old mailbox name *	    new mailbox name * Returns: T on success, NIL on failure */long mx_rename (MAILSTREAM *stream,char *old,char *newname){  char c,*s,tmp[MAILTMPLEN],tmp1[MAILTMPLEN];  struct stat sbuf;  if (!mx_isvalid (old,tmp))    sprintf (tmp,"Can't rename mailbox %.80s: no such mailbox",old);				/* new mailbox name must not be valid */  else if (mx_isvalid (newname,tmp))    sprintf (tmp,"Can't rename to mailbox %.80s: destination already exists",	     newname);				/* success if can rename the directory */  else {			/* found superior to destination name? */    if (s = strrchr (mx_file (tmp1,newname),'/')) {      c = *++s;			/* remember first character of inferior */      *s = '\0';		/* tie off to get just superior */				/* name doesn't exist, create it */      if ((stat (tmp1,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) &&	  !dummy_create_path (stream,tmp1,get_dir_protection (newname)))	return NIL;      *s = c;			/* restore full name */    }    if (!rename (mx_file (tmp,old),tmp1)) {				/* recreate file if renamed INBOX */      if (!compare_cstring (old,"INBOX")) mx_create (NIL,"INBOX");      return T;    }    sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %s",	     old,newname,strerror (errno));  }  MM_LOG (tmp,ERROR);		/* something failed */  return NIL;}/* MX mail open * Accepts: stream to open * Returns: stream on success, NIL on failure */MAILSTREAM *mx_open (MAILSTREAM *stream){  char tmp[MAILTMPLEN];				/* return prototype for OP_PROTOTYPE call */  if (!stream) return user_flags (&mxproto);  if (stream->local) fatal ("mx recycle stream");  stream->local = fs_get (sizeof (MXLOCAL));				/* note if an INBOX or not */  stream->inbox = !compare_cstring (stream->mailbox,"INBOX");  mx_file (tmp,stream->mailbox);/* get directory name */  LOCAL->dir = cpystr (tmp);	/* copy directory name for later */				/* make temporary buffer */  LOCAL->buf = (char *) fs_get ((LOCAL->buflen = MAXMESSAGESIZE) + 1);  LOCAL->scantime = 0;		/* not scanned yet */  LOCAL->fd = -1;		/* no index yet */  LOCAL->cachedtexts = 0;	/* no cached texts */  stream->sequence++;		/* bump sequence number */				/* parse mailbox */  stream->nmsgs = stream->recent = 0;  if (mx_ping (stream) && !(stream->nmsgs || stream->silent))    MM_LOG ("Mailbox is empty",(long) NIL);  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 */}/* MX mail close * Accepts: MAIL stream *	    close options */void mx_close (MAILSTREAM *stream,long options){  if (LOCAL) {			/* only if a file is open */    int silent = stream->silent;    stream->silent = T;		/* note this stream is dying */    if (options & CL_EXPUNGE) mx_expunge (stream);    if (LOCAL->dir) fs_give ((void **) &LOCAL->dir);				/* free local scratch 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 */    stream->silent = silent;	/* reset silent state */  }}/* MX mail fetch fast information * Accepts: MAIL stream *	    sequence *	    option flags */void mx_fast (MAILSTREAM *stream,char *sequence,long flags){  unsigned long i;  MESSAGECACHE *elt;  if (stream && LOCAL &&      ((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) mx_fast_work (stream,elt);}/* MX mail fetch fast information * Accepts: MAIL stream *	    message cache element * Returns: name of message file */char *mx_fast_work (MAILSTREAM *stream,MESSAGECACHE *elt){  struct stat sbuf;  struct tm *tm;				/* build message file name */  sprintf (LOCAL->buf,"%s/%lu",LOCAL->dir,elt->private.uid);  if (!elt->rfc822_size) {	/* have size yet? */    stat (LOCAL->buf,&sbuf);	/* get size of message */				/* make plausible IMAPish date string */    tm = gmtime (&sbuf.st_mtime);    elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1;    elt->year = tm->tm_year + 1900 - BASEYEAR;    elt->hours = tm->tm_hour; elt->minutes = tm->tm_min;    elt->seconds = tm->tm_sec;    elt->zhours = 0; elt->zminutes = 0; elt->zoccident = 0;    elt->rfc822_size = sbuf.st_size;  }  return LOCAL->buf;		/* return file name */}/* MX 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 *mx_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,		 long flags){  unsigned long i;  int fd;  MESSAGECACHE *elt;  *length = 0;			/* default to empty */  if (flags & FT_UID) return "";/* UID call "impossible" */  elt = mail_elt (stream,msgno);/* get elt */  if (!elt->private.msg.header.text.data) {				/* purge cache if too big */    if (LOCAL->cachedtexts > max (stream->nmsgs * 4096,2097152)) {      mail_gc (stream,GC_TEXTS);/* just can't keep that much */      LOCAL->cachedtexts = 0;    }    if ((fd = open (mx_fast_work (stream,elt),O_RDONLY,NIL)) < 0) return "";				/* is buffer big enough? */    if (elt->rfc822_size > LOCAL->buflen) {      fs_give ((void **) &LOCAL->buf);      LOCAL->buf = (char *) fs_get ((LOCAL->buflen = elt->rfc822_size) + 1);    }				/* slurp message */    read (fd,LOCAL->buf,elt->rfc822_size);				/* tie off file */    LOCAL->buf[elt->rfc822_size] = '\0';    close (fd);			/* flush message file */				/* find end of header */    if (elt->rfc822_size < 4) i = 0;    else for (i = 4; (i < elt->rfc822_size) &&	      !((LOCAL->buf[i - 4] == '\015') &&		(LOCAL->buf[i - 3] == '\012') &&		(LOCAL->buf[i - 2] == '\015') &&		(LOCAL->buf[i - 1] == '\012')); i++);				/* copy header */    cpytxt (&elt->private.msg.header.text,LOCAL->buf,i);    cpytxt (&elt->private.msg.text.text,LOCAL->buf+i,elt->rfc822_size - i);				/* add to cached size */    LOCAL->cachedtexts += elt->rfc822_size;  }  *length = elt->private.msg.header.text.size;  return (char *) elt->private.msg.header.text.data;}/* MX mail fetch message text (body only) * Accepts: MAIL stream *	    message # to fetch *	    pointer to returned stringstruct *	    option flags * Returns: T on success, NIL on failure */long mx_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){  unsigned long i;  MESSAGECACHE *elt;				/* UID call "impossible" */  if (flags & FT_UID) return NIL;  elt = mail_elt (stream,msgno);				/* snarf message if don't have it yet */  if (!elt->private.msg.text.text.data) {    mx_header (stream,msgno,&i,flags);    if (!elt->private.msg.text.text.data) return NIL;  }				/* mark as seen */  if (!(flags & FT_PEEK) && mx_lockindex (stream)) {    elt->seen = T;    mx_unlockindex (stream);    MM_FLAGS (stream,msgno);  }  INIT (bs,mail_string,elt->private.msg.text.text.data,	elt->private.msg.text.text.size);  return T;}/* MX mail modify flags * Accepts: MAIL stream *	    sequence *	    flag(s) *	    option flags */void mx_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags){  mx_unlockindex (stream);	/* finished with index */}/* MX per-message modify flags * Accepts: MAIL stream *	    message cache element */void mx_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt){  mx_lockindex (stream);	/* lock index if not already locked */}/* MX mail ping mailbox * Accepts: MAIL stream * Returns: T if stream alive, else NIL */long mx_ping (MAILSTREAM *stream){  MAILSTREAM *sysibx = NIL;  MESSAGECACHE *elt,*selt;  struct stat sbuf;  char *s,tmp[MAILTMPLEN];  int fd;  unsigned long i,j,r,old;  long nmsgs = stream->nmsgs;  long recent = stream->recent;  int silent = stream->silent;  if (stat (LOCAL->dir,&sbuf)) return NIL;  stream->silent = T;		/* don't pass up mm_exists() events yet */  if (sbuf.st_ctime != LOCAL->scantime) {    struct direct **names = NIL;    long nfiles = scandir (LOCAL->dir,&names,mx_select,mx_numsort);    if (nfiles < 0) nfiles = 0;	/* in case error */    old = stream->uid_last;				/* note scanned now */    LOCAL->scantime = sbuf.st_ctime;				/* scan directory */    for (i = 0; i < nfiles; ++i) {				/* if newly seen, add to list */      if ((j = atoi (names[i]->d_name)) > old) {				/* swell the cache */	mail_exists (stream,++nmsgs);	stream->uid_last = (elt = mail_elt (stream,nmsgs))->private.uid = j;	elt->valid = T;		/* note valid flags */	if (old) {		/* other than the first pass? */	  elt->recent = T;	/* yup, mark as recent */	  recent++;		/* bump recent count */	}      }      fs_give ((void **) &names[i]);    }				/* free directory */    if (s = (void *) names) fs_give ((void **) &s);  }  stream->nmsgs = nmsgs;	/* don't upset mail_uid() */				/* if INBOX, snarf from system INBOX  */  if (mx_lockindex (stream) && stream->inbox) {    old = stream->uid_last;				/* paranoia check */    if (!strcmp (sysinbox (),stream->mailbox)) {      stream->silent = silent;      return NIL;    }    MM_CRITICAL (stream);	/* go critical */    stat (sysinbox (),&sbuf);	/* see if anything there */				/* can get sysinbox mailbox? */    if (sbuf.st_size && (sysibx = mail_open (sysibx,sysinbox (),OP_SILENT))	&& (!sysibx->rdonly) && (r = sysibx->nmsgs)) {      for (i = 1; i <= r; ++i) {/* for each message in sysinbox mailbox */				/* build file name we will use */	sprintf (LOCAL->buf,"%s/%lu",LOCAL->dir,++old);				/* snarf message from Berkeley mailbox */	selt = mail_elt (sysibx,i);	if (((fd = open (LOCAL->buf,O_WRONLY|O_CREAT|O_EXCL,			 S_IREAD|S_IWRITE)) >= 0) &&	    (s = mail_fetchheader_full (sysibx,i,NIL,&j,FT_PEEK)) &&	    (write (fd,s,j) == j) &&	    (s = mail_fetchtext_full (sysibx,i,&j,FT_PEEK)) &&	    (write (fd,s,j) == j) && !fsync (fd) && !close (fd)) {				/* swell the cache */	  mail_exists (stream,++nmsgs);	  stream->uid_last =	/* create new elt, note its file number */	    (elt = mail_elt (stream,nmsgs))->private.uid = old;	  recent++;		/* bump recent count */				/* set up initial flags and date */	  elt->valid = elt->recent = T;	  elt->seen = selt->seen;	  elt->deleted = selt->deleted;	  elt->flagged = selt->flagged;	  elt->answered = selt->answered;	  elt->draft = selt->draft;	  elt->day = selt->day;elt->month = selt->month;elt->year = selt->year;	  elt->hours = selt->hours;elt->minutes = selt->minutes;	  elt->seconds = selt->seconds;	  elt->zhours = selt->zhours; elt->zminutes = selt->zminutes;	  elt->zoccident = selt->zoccident;	  mx_setdate (LOCAL->buf,elt);	}	else {			/* failed to snarf */	  if (fd) {		/* did it ever get opened? */	    close (fd);		/* close descriptor */	    unlink (LOCAL->buf);/* flush this file */	  }	  stream->silent = silent;	  return NIL;		/* note that something is badly wrong */	}	sprintf (tmp,"%lu",i);	/* delete it from the sysinbox */	mail_flag (sysibx,tmp,"\\Deleted",ST_SET);      }      stat (LOCAL->dir,&sbuf);	/* update scan time */      LOCAL->scantime = sbuf.st_ctime;            mail_expunge (sysibx);	/* now expunge all those messages */    }    if (sysibx) mail_close (sysibx);    MM_NOCRITICAL (stream);	/* release critical */  }  mx_unlockindex (stream);	/* done with index */  stream->silent = silent;	/* can pass up events now */  mail_exists (stream,nmsgs);	/* notify upper level of mailbox size */  mail_recent (stream,recent);  return T;			/* return that we are alive */}/* MX mail check mailbox * Accepts: MAIL stream */void mx_check (MAILSTREAM *stream){  if (mx_ping (stream)) MM_LOG ("Check completed",(long) NIL);}/* MX mail expunge mailbox * Accepts: MAIL stream */void mx_expunge (MAILSTREAM *stream){  MESSAGECACHE *elt;  unsigned long i = 1;  unsigned long n = 0;  unsigned long recent = stream->recent;  if (mx_lockindex (stream)) {	/* lock the index */    MM_CRITICAL (stream);	/* go critical */    while (i <= stream->nmsgs) {/* for each message */

⌨️ 快捷键说明

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