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

📄 unix.c

📁 这是用C编写IMAP源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (reparse && unix_parse (stream,&lock,LOCK_SH)) {				/* unlock mailbox */	unix_unlock (LOCAL->fd,stream,&lock);	mail_unlock (stream);	/* and stream */	MM_NOCRITICAL (stream);	/* done with critical */      }    }  }  return LOCAL ? LONGT : NIL;	/* return if still alive */}/* UNIX mail check mailbox * Accepts: MAIL stream */void unix_check (MAILSTREAM *stream){  DOTLOCK lock;				/* parse and lock mailbox */  if (LOCAL && (LOCAL->ld >= 0) && !stream->lock &&      unix_parse (stream,&lock,LOCK_EX)) {				/* any unsaved changes? */    if (LOCAL->dirty && unix_rewrite (stream,NIL,&lock)) {      if (!stream->silent) MM_LOG ("Checkpoint completed",NIL);    }				/* no checkpoint needed, just unlock */    else unix_unlock (LOCAL->fd,stream,&lock);    mail_unlock (stream);	/* unlock the stream */    MM_NOCRITICAL (stream);	/* done with critical */  }}/* UNIX mail expunge mailbox * Accepts: MAIL stream */void unix_expunge (MAILSTREAM *stream){  unsigned long i;  DOTLOCK lock;  char *msg = NIL;				/* parse and lock mailbox */  if (LOCAL && (LOCAL->ld >= 0) && !stream->lock &&      unix_parse (stream,&lock,LOCK_EX)) {				/* count expunged messages if not dirty */    if (!LOCAL->dirty) for (i = 1; i <= stream->nmsgs; i++)      if (mail_elt (stream,i)->deleted) LOCAL->dirty = T;    if (!LOCAL->dirty) {	/* not dirty and no expunged messages */      unix_unlock (LOCAL->fd,stream,&lock);      msg = "No messages deleted, so no update needed";    }    else if (unix_rewrite (stream,&i,&lock)) {      if (i) sprintf (msg = LOCAL->buf,"Expunged %lu messages",i);      else msg = "Mailbox checkpointed, but no messages expunged";    }				/* rewrite failed */    else unix_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);}/* UNIX mail copy message(s) * Accepts: MAIL stream *	    sequence *	    destination mailbox *	    copy options * Returns: T if copy successful, else NIL */long unix_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);  if (!((options & CP_UID) ? mail_uid_sequence (stream,sequence) :	mail_sequence (stream,sequence))) return NIL;				/* make sure valid mailbox */  if (!unix_valid (mailbox)) switch (errno) {  case ENOENT:			/* no such file? */    if (!compare_cstring (mailbox,"INBOX")) {      if (pc) return (*pc) (stream,sequence,mailbox,options);      unix_create (NIL,"INBOX");/* create empty INBOX */      break;    }    MM_NOTIFY (stream,"[TRYCREATE] Must create mailbox before copy",NIL);    return NIL;  case 0:			/* merely empty file? */    break;  case EINVAL:    if (pc) return (*pc) (stream,sequence,mailbox,options);    sprintf (LOCAL->buf,"Invalid UNIX-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 UNIX-format mailbox: %.80s",mailbox);    MM_LOG (LOCAL->buf,ERROR);    return NIL;  }  LOCAL->buf[0] = '\0';  MM_CRITICAL (stream);		/* go critical */  if ((fd = unix_lock (dummy_file (file,mailbox),O_WRONLY|O_APPEND|O_CREAT,		       S_IREAD|S_IWRITE,&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 = unix_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 = unix_xstatus (stream,LOCAL->buf,elt,NIL);	  if (write (fd,LOCAL->buf,j) < 0) ret = NIL;	  else {		/* message status succeeded */	    s = unix_text_work (stream,elt,&j,FT_INTERNAL);	    if ((write (fd,s,j) < 0) || (write (fd,"\n",1) < 0)) ret = NIL;	  }	}      }    }  if (!ret || fsync (fd)) {	/* force out the update */    sprintf (LOCAL->buf,"Message copy failed: %s",strerror (errno));    ftruncate (fd,sbuf.st_size);    ret = NIL;  }  tp[1] = time (0);		/* set mtime to now */  if (ret) tp[0] = tp[1] - 1;	/* set atime to now-1 if successful copy */  else tp[0] =			/* else preserve \Marked status */	 ((sbuf.st_ctime > sbuf.st_atime) || (sbuf.st_mtime > sbuf.st_atime)) ?	 sbuf.st_atime : tp[1];  utime (file,tp);		/* set the times */  unix_unlock (fd,NIL,&lock);	/* unlock and close mailbox */  MM_NOCRITICAL (stream);	/* release critical */				/* log the error */  if (!ret) MM_LOG (LOCAL->buf,ERROR);				/* delete if requested message */  else if (options & CP_MOVE) for (i = 1; i <= stream->nmsgs; i++)    if ((elt = mail_elt (stream,i))->sequence)      elt->deleted = elt->private.dirty = LOCAL->dirty = T;  return ret;}/* UNIX mail append message from stringstruct * Accepts: MAIL stream *	    destination mailbox *	    append callback *	    data for callback * Returns: T if append successful, else NIL */#define BUFLEN 8*MAILTMPLENlong unix_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){  struct stat sbuf;  int fd;  unsigned long i,j;  char *flags,*date,buf[BUFLEN],tmp[MAILTMPLEN],file[MAILTMPLEN];  time_t tp[2];  FILE *sf,*df;  MESSAGECACHE elt;  DOTLOCK lock;  STRING *message;  MAILSTREAM *tstream = NIL;  long ret = LONGT;  if (!stream) {		/* stream specified? */    stream = &unixproto;	/* no, default stream to prototype */    for (i = 0; i < NUSERFLAGS && stream->user_flags[i]; ++i)      fs_give ((void **) &stream->user_flags[i]);    stream->kwd_create = T;	/* allow new flags */  }				/* make sure valid mailbox */  if (!unix_valid (mailbox)) switch (errno) {  case ENOENT:			/* no such file? */    if (!compare_cstring (mailbox,"INBOX")) {      unix_create (NIL,"INBOX");/* create empty INBOX */      break;    }    MM_NOTIFY (stream,"[TRYCREATE] Must create mailbox before append",NIL);    return NIL;  case 0:			/* merely empty file? */    break;  case EINVAL:    sprintf (tmp,"Invalid UNIX-format mailbox name: %.80s",mailbox);    MM_LOG (tmp,ERROR);    return NIL;  default:    sprintf (tmp,"Not a UNIX-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 (!(sf = tmpfile ())) {	/* must have scratch file */    sprintf (tmp,".%lx.%lx",(unsigned long) time (0),(unsigned long)getpid ());    if (!stat (tmp,&sbuf) || !(sf = fopen (tmp,"wb+"))) {      sprintf (tmp,"Unable to create scratch file: %.80s",strerror (errno));      MM_LOG (tmp,ERROR);      return NIL;    }    unlink (tmp);  }  do {				/* parse date */    if (!date) rfc822_date (date = tmp);    if (!mail_parse_date (&elt,date)) {      sprintf (tmp,"Bad date in append: %.80s",date);      MM_LOG (tmp,ERROR);    }    else {			/* user wants to suppress time zones? */      if (mail_parameters (NIL,GET_NOTIMEZONES,NIL)) {	time_t when = mail_longdate (&elt);	date = ctime (&when);	/* use traditional date */      }				/* use POSIX-style date */      else date = mail_cdate (tmp,&elt);      if (!SIZE (message)) MM_LOG ("Append of zero-length message",ERROR);      else if (!unix_append_msg (stream,sf,flags,date,message)) {	sprintf (tmp,"Error writing scratch file: %.80s",strerror (errno));	MM_LOG (tmp,ERROR);      }				/* get next message */      else if (MM_APPEND (af) (stream,data,&flags,&date,&message)) continue;    }    fclose (sf);		/* punt scratch file */    return NIL;			/* give up */  } while (message);		/* until no more messages */  if (fflush (sf) || fstat (fileno (sf),&sbuf)) {    sprintf (tmp,"Error finishing scratch file: %.80s",strerror (errno));    MM_LOG (tmp,ERROR);    fclose (sf);		/* punt scratch file */    return NIL;			/* give up */  }  i = sbuf.st_size;		/* size of scratch file */  MM_CRITICAL (stream);		/* go critical */  if (((fd = unix_lock (dummy_file (file,mailbox),O_WRONLY|O_APPEND|O_CREAT,		       S_IREAD|S_IWRITE,&lock,LOCK_EX)) < 0) ||      !(df = fdopen (fd,"ab"))) {    MM_NOCRITICAL (stream);	/* done with critical */    sprintf (tmp,"Can't open append mailbox: %s",strerror (errno));    MM_LOG (tmp,ERROR);    return NIL;  }  fstat (fd,&sbuf);		/* get current file size */  rewind (sf);  for (; i && ((j = fread (buf,1,min ((long) BUFLEN,i),sf)) &&	       (fwrite (buf,1,j,df) == j)); i -= j);  fclose (sf);			/* done with scratch file */  tp[1] = time (0);		/* set mtime to now */				/* make sure append wins, fsync() necessary */  if (i || (fflush (df) == EOF) || fsync (fd)) {    sprintf (buf,"Message append failed: %s",strerror (errno));    MM_LOG (buf,ERROR);    ftruncate (fd,sbuf.st_size);    tp[0] =			/* preserve \Marked status */      ((sbuf.st_ctime > sbuf.st_atime) || (sbuf.st_mtime > sbuf.st_atime)) ?      sbuf.st_atime : tp[1];    ret = NIL;			/* return error */  }  else tp[0] = tp[1] - 1;	/* set atime to now-1 if successful copy */  utime (file,tp);		/* set the times */  unix_unlock (fd,NIL,&lock);	/* unlock and close mailbox */  fclose (df);			/* note that unix_unlock() released the fd */  MM_NOCRITICAL (stream);	/* release critical */  return ret;}/* Write single message to append scratch file * Accepts: MAIL stream *	    scratch file *	    flags *	    message stringstruct * Returns: NIL if write error, else T */int unix_append_msg (MAILSTREAM *stream,FILE *sf,char *flags,char *date,		     STRING *msg){  int ti,zn,c;  unsigned long i,uf;  char *x,tmp[MAILTMPLEN];  int hdrp = T;  long f = mail_parse_flags (stream,flags,&uf);				/* build initial header */  if ((fprintf (sf,"From %s@%s %sStatus: ",		myusername (),mylocalhost (),date) < 0) ||      (f&fSEEN && (putc ('R',sf) == EOF)) ||      (fputs ("\nX-Status: ",sf) == EOF) ||      (f&fDELETED && (putc ('D',sf) == EOF)) ||      (f&fFLAGGED && (putc ('F',sf) == EOF)) ||      (f&fANSWERED && (putc ('A',sf) == EOF)) ||      (f&fDRAFT && (putc ('T',sf) == EOF)) ||      (fputs ("\nX-Keywords:",sf) == EOF)) return NIL;  while (uf)			/* write user flags */    if (fprintf (sf," %s",stream->user_flags[find_rightmost_bit (&uf)]) < 0)      return NIL;				/* tie off flags */  if (putc ('\n',sf) == EOF) return NIL;  while (SIZE (msg)) {		/* copy text to scratch file */				/* disregard CRs */    while ((c = (SIZE (msg)) ? (0xff & SNX (msg)) : '\n') == '\r');				/* see if line needs special treatment */    if ((c == 'F') || (hdrp && ((c == 'S') || (c == 'X')))) {				/* copy line to buffer */      for (i = 1,tmp[0] = c; (c != '\n') && (i < MAILTMPLEN); )	if ((c = (SIZE (msg)) ? (0xff & SNX (msg)) : '\n') != '\r')	  tmp[i++] = c;				/* possible "From " line? */      if ((i > 4) && (tmp[0] == 'F') && (tmp[1] == 'r') && (tmp[2] == 'o') &&	  (tmp[3] == 'm') && (tmp[4] == ' ')) {				/* yes, see if need to write a widget */	if (!(ti = unix_fromwidget || (c != '\n'))) VALID (tmp,x,ti,zn);	if (ti && (putc ('>',sf) == EOF)) return NIL;      }				/* insert X- before metadata header */      else if ((((i > 6) && (tmp[0] == 'S') && (tmp[1] == 't') &&		 (tmp[2] == 'a') && (tmp[3] == 't') && (tmp[4] == 'u') &&		 (tmp[5] == 's') && (tmp[6] == ':')) ||		(((i > 5) && (tmp[0] == 'X') && (tmp[1] == '-')) &&		 (((tmp[2] == 'U') && (tmp[3] == 'I') && (tmp[4] == 'D') &&		   (tmp[5] == ':')) ||		  ((i > 6) && (tmp[2] == 'I') && (tmp[3] == 'M') &&		   (tmp[4] == 'A') && (tmp[5] == 'P') &&		   ((tmp[6] == ':') ||		    ((i > 10) && (tmp[6] == 'b') && (tmp[7] == 'a') &&		     (tmp[8] == 's') && (tmp[9] == 'e') &&		     (tmp[10] == ':')))) ||		  ((i > 8) && (tmp[2] == 'S') && (tmp[3] == 't') &&		   (tmp[4] == 'a') && (tmp[5] == 't') && (tmp[6] == 'u') &&		   (tmp[7] == 's') && (tmp[8] == ':')) ||		  ((i > 10) && (tmp[2] == 'K') && (tmp[3] == 'e') &&		   (tmp[4] == 'y') && (tmp[5] == 'w') && (tmp[6] == 'o') &&		   (tmp[7] == 'r') && (tmp[8] == 'd') && (tmp[9] == 's') &&		   (tmp[10] == ':'))))) && (fputs ("X-Original-",sf) == EOF))	return NIL;				/* write buffered text */      if (fwrite (tmp,1,i,sf) != i) return NIL;				/* set up to copy remainder of line */      if ((c != '\n') && SIZE (msg)) c = 0xff & SNX (msg);      else continue;		/* end of line or end of message */    }				/* check for end of header */    else if (hdrp && (c == '\n')) hdrp = NIL;				/* copy line, tossing out CR */    do if ((c != '\r') && (putc (c,sf) == EOF)) return NIL;    while ((c != '\n') && SIZE (msg) && ((c = 0xff & SNX (msg)) ? c : T));  }				/* write trailing newline and return */  return (putc ('\n',sf) == EOF) ? NIL : T;}

⌨️ 快捷键说明

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