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

📄 mh.c

📁 这是用C编写IMAP源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    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_INTERNAL)) &&	    (write (fd,s,j) == j) &&	    (s = mail_fetchtext_full (sysibx,i,&j,FT_INTERNAL|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;	  mh_setdate (LOCAL->buf,elt);	}	else {			/* failed to snarf */	  if (fd) {		/* did it ever get opened? */	    mm_log ("Message copy to MH mailbox failed",ERROR);	    close (fd);		/* close descriptor */	    unlink (LOCAL->buf);/* flush this file */	  }	  else {	    sprintf (tmp,"Can't add message: %s",strerror (errno));	    mm_log (tmp,ERROR);	  }	  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 */  }  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 */}/* MH mail check mailbox * Accepts: MAIL stream */void mh_check (MAILSTREAM *stream){  /* Perhaps in the future this will preserve flags */  if (mh_ping (stream)) mm_log ("Check completed",(long) NIL);}/* MH mail expunge mailbox * Accepts: MAIL stream */void mh_expunge (MAILSTREAM *stream){  MESSAGECACHE *elt;  unsigned long i = 1;  unsigned long n = 0;  unsigned long recent = stream->recent;  mm_critical (stream);		/* go critical */  while (i <= stream->nmsgs) {	/* for each message */				/* 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 */				/* notify upper level of new mailbox size */  mail_exists (stream,stream->nmsgs);  mail_recent (stream,recent);}/* MH mail copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    copy options * Returns: T if copy successful, else NIL */long mh_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){  STRING st;  MESSAGECACHE *elt;  struct stat sbuf;  int fd;  unsigned long i;  char 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) {	sprintf (LOCAL->buf,"%s/%lu",LOCAL->dir,elt->private.uid);	if ((fd = open (LOCAL->buf,O_RDONLY,NIL)) < 0) return NIL;	fstat (fd,&sbuf);	/* get size of message */	if (!elt->day) {	/* make plausible IMAPish date string */	  struct tm *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;	}				/* 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 (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 */}/* MH mail append message from stringstruct * Accepts: MAIL stream *	    destination mailbox *	    append callback *	    data for callback * Returns: T if append successful, else NIL */long mh_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){  struct direct **names;  int fd;  char c,*flags,*date,*s,tmp[MAILTMPLEN];  STRING *message;  MESSAGECACHE elt;  long i,size,last,nfiles;  long ret = LONGT;				/* default stream to prototype */  if (!stream) stream = &mhproto;				/* make sure valid mailbox */  if (!mh_isvalid (mailbox,tmp,NIL)) switch (errno) {  case ENOENT:			/* no such file? */    if (!compare_cstring (mailbox,"#mhinbox")) mh_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 MH-format mailbox name: %.80s",mailbox);    mm_log (tmp,ERROR);    return NIL;  default:    sprintf (tmp,"Not a MH-format mailbox: %.80s",mailbox);    mm_log (tmp,ERROR);    return NIL;  }				/* get first message */  if (!(*af) (stream,data,&flags,&date,&message)) return NIL;  if ((nfiles = scandir (tmp,&names,mh_select,mh_numsort)) > 0) {				/* largest number */    last = atoi (names[nfiles-1]->d_name);        for (i = 0; i < nfiles; ++i) /* free directory */      fs_give ((void **) &names[i]);  }  else last = 0;		/* no messages here yet */  if (s = (void *) names) fs_give ((void **) &s);  mm_critical (stream);		/* go critical */  do {    if (!SIZE (message)) {	/* guard against zero-length */      mm_log ("Append of zero-length message",ERROR);      ret = NIL;      break;    }    if (date) {			/* want to preserve date? */				/* yes, parse date into an elt */      if (!mail_parse_date (&elt,date)) {	sprintf (tmp,"Bad date in append: %.80s",date);	mm_log (tmp,ERROR);	ret = NIL;	break;      }    }    mh_file (tmp,mailbox);	/* build file name we will use */    sprintf (tmp + strlen (tmp),"/%ld",++last);    if ((fd = open (tmp,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {      sprintf (tmp,"Can't open append message: %s",strerror (errno));      mm_log (tmp,ERROR);      ret = NIL;      break;    }				/* copy the data w/o CR's */    for (size = 0,i = SIZE (message),s = (char *) fs_get (i + 1); i; --i)      if ((c = SNX (message)) != '\015') s[size++] = c;				/* write the data */    if ((write (fd,s,size) < 0) || fsync (fd)) {      unlink (tmp);		/* delete message */      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) mh_setdate (tmp,&elt);				/* get next message */      if (!(*af) (stream,data,&flags,&date,&message)) ret = NIL;    }  } while (ret && message);  mm_nocritical (stream);	/* release critical */  return ret;}/* Internal routines *//* MH file name selection test * Accepts: candidate directory entry * Returns: T to use file name, NIL to skip it */int mh_select (struct direct *name){  char c;  char *s = name->d_name;  while (c = *s++) if (!isdigit (c)) return NIL;  return T;}/* MH 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 mh_numsort (const void *d1,const void *d2){  return atoi ((*(struct direct **) d1)->d_name) -    atoi ((*(struct direct **) d2)->d_name);}/* MH mail build file name * Accepts: destination string *          source * Returns: destination */char *mh_file (char *dst,char *name){  char *s;				/* build composite name */  sprintf (dst,"%s/%.900s",mh_path,	   compare_cstring (name,"#MHINBOX") ? name + 4 : "inbox");				/* tie off unnecessary trailing / */  if ((s = strrchr (dst,'/')) && !s[1] && (s[-1] == '/')) *s = '\0';  return dst;}/* MH canonicalize name * Accepts: buffer to write name *	    reference *	    pattern * Returns: T if success, NIL if failure */long mh_canonicalize (char *pattern,char *ref,char *pat){  char tmp[MAILTMPLEN];  if (ref && *ref) {		/* have a reference */    strcpy (pattern,ref);	/* copy reference to pattern */				/* # overrides mailbox field in reference */    if (*pat == '#') strcpy (pattern,pat);				/* pattern starts, reference ends, with / */    else if ((*pat == '/') && (pattern[strlen (pattern) - 1] == '/'))      strcat (pattern,pat + 1);	/* append, omitting one of the period */    else strcat (pattern,pat);	/* anything else is just appended */  }  else strcpy (pattern,pat);	/* just have basic name */  return (mh_isvalid (pattern,tmp,T));}/* Set date for message * Accepts: file name *	    elt containing date */void mh_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 + -