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

📄 imapd.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
	PSOUT (")\015\012");      }    }    else {			/* driver changed */      new_flags (stream);	/* send mailbox flags */      if (curdriver) {		/* note readonly/write if possible change */	PSOUT ("* OK [READ-");	PSOUT (stream->rdonly ? "ONLY" : "WRITE");	PSOUT ("] Mailbox status\015\012");      }      curdriver = stream->dtb;      if (nmsgs) {		/* get flags for all messages */	sprintf (tmp,"1:%lu",nmsgs);	mail_fetch_flags (stream,tmp,NIL);				/* don't do this if newsrc already did */	if (!(curdriver->flags & DR_NEWS)) {				/* find first unseen message */	  for (i = 1; i <= nmsgs && mail_elt (stream,i)->seen; i++);	  if (i <= nmsgs) {	    PSOUT ("* OK [UNSEEN ");	    pnum (i);	    PSOUT ("] first unseen message in ");	    PSOUT (stream->mailbox);	    CRLF;	  }	}      }    }  }  if (shutdowntime && (time (0) > shutdowntime + SHUTDOWNTIMER)) {    PSOUT ("* BYE Server shutting down\015\012");    state = LOGOUT;  }				/* don't do these stat()s every cycle */  else if (time (0) > alerttime + ALERTTIMER) {     struct stat sbuf;				/* have a shutdown file? */    if (!stat (SHUTDOWNFILE,&sbuf)) {      PSOUT ("* OK [ALERT] Server shutting down shortly\015\012");      shutdowntime = time (0);    }    alerttime = time (0);	/* output any new alerts */    sysalerttime = palert (ALERTFILE,sysalerttime);    if (state != LOGIN)		/* do user alert if logged in */      useralerttime = palert (mailboxfile (tmp,USERALERTFILE),useralerttime);  }}/* Print an alert file * Accepts: path of alert file *	    time of last printed alert file * Returns: updated time of last printed alert file */time_t palert (char *file,time_t oldtime){  FILE *alf;  struct stat sbuf;  int c,lc = '\012';				/* have a new alert file? */  if (stat (file,&sbuf) || (sbuf.st_mtime <= oldtime) ||      !(alf = fopen (file,"r"))) return oldtime;				/* yes, display it */  while ((c = getc (alf)) != EOF) {    if (lc == '\012') PSOUT ("* OK [ALERT] ");    switch (c) {		/* output character */    case '\012':		/* newline means do CRLF */      CRLF;    case '\015':		/* flush CRs */    case '\0':			/* flush nulls */      break;    default:      PBOUT (c);		/* output all other characters */      break;    }    lc = c;			/* note previous character */  }  fclose (alf);  if (lc != '\012') CRLF;	/* final terminating CRLF */  return sbuf.st_mtime;		/* return updated last alert time */}/* Initialize file string structure for file stringstruct * Accepts: string structure *	    pointer to message data structure *	    size of string */void msg_string_init (STRING *s,void *data,unsigned long size){  MSGDATA *md = (MSGDATA *) data;  s->data = data;		/* note stream/msgno and header length */#if 0  s->size = size;		/* message size */  s->curpos = s->chunk =	/* load header */    mail_fetchheader_full (md->stream,md->msgno,NIL,&s->data1,			   FT_PREFETCHTEXT | FT_PEEK);#else	/* This kludge is necessary because of broken mail stores */  mail_fetchtext_full (md->stream,md->msgno,&s->size,FT_PEEK);  s->curpos = s->chunk =	/* load header */    mail_fetchheader_full (md->stream,md->msgno,NIL,&s->data1,FT_PEEK);  s->size += s->data1;		/* header + body size */#endif  s->cursize = s->chunksize = s->data1;  s->offset = 0;		/* offset is start of message */}/* Get next character from file stringstruct * Accepts: string structure * Returns: character, string structure chunk refreshed */char msg_string_next (STRING *s){  char c = *s->curpos++;	/* get next byte */  SETPOS (s,GETPOS (s));	/* move to next chunk */  return c;			/* return the byte */}/* Set string pointer position for file stringstruct * Accepts: string structure *	    new position */void msg_string_setpos (STRING *s,unsigned long i){  MSGDATA *md = (MSGDATA *) s->data;  if (i < s->data1) {		/* want header? */    s->chunk = mail_fetchheader_full (md->stream,md->msgno,NIL,NIL,FT_PEEK);    s->chunksize = s->data1;	/* header length */    s->offset = 0;		/* offset is start of message */  }  else if (i < s->size) {	/* want body */    s->chunk = mail_fetchtext_full (md->stream,md->msgno,NIL,FT_PEEK);    s->chunksize = s->size - s->data1;    s->offset = s->data1;	/* offset is end of header */  }  else {			/* off end of message */    s->chunk = NIL;		/* make sure that we crack on this then */    s->chunksize = 1;		/* make sure SNX cracks the right way... */    s->offset = i;  }				/* initial position and size */  s->curpos = s->chunk + (i -= s->offset);  s->cursize = s->chunksize - i;}/* Send flags for stream * Accepts: MAIL stream *	    scratch buffer */void new_flags (MAILSTREAM *stream){  int i,c;  PSOUT ("* FLAGS (");  for (i = 0; i < NUSERFLAGS; i++) if (stream->user_flags[i]) {    PSOUT (stream->user_flags[i]);    PBOUT (' ');    nflags = i + 1;  }  PSOUT ("\\Answered \\Flagged \\Deleted \\Draft \\Seen)\015\012* OK [PERMANENTFLAGS (");  for (i = c = 0; i < NUSERFLAGS; i++)    if ((stream->perm_user_flags & (1 << i)) && stream->user_flags[i])      put_flag (&c,stream->user_flags[i]);  if (stream->kwd_create) put_flag (&c,"\\*");  if (stream->perm_answered) put_flag (&c,"\\Answered");  if (stream->perm_flagged) put_flag (&c,"\\Flagged");  if (stream->perm_deleted) put_flag (&c,"\\Deleted");  if (stream->perm_draft) put_flag (&c,"\\Draft");  if (stream->perm_seen) put_flag (&c,"\\Seen");  PSOUT (")] Permanent flags\015\012");}/* Set timeout * Accepts: desired interval */void settimeout (unsigned int i){				/* limit if not logged in */  if (i) alarm ((state == LOGIN) ? LOGINTIMEOUT : i);  else alarm (0);}/* Clock interrupt * Returns only if critical code in progress */void clkint (void){  settimeout (0);		/* disable all interrupts */  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);  logout = "Autologout";  goodbye = "Autologout (idle for too long)";  if (critical) {		/* must defer if in critical code(?) */    close (0);			/* kill stdin */    state = LOGOUT;		/* die as soon as we can */  }  else longjmp (jmpenv,1);	/* die now */}/* Kiss Of Death interrupt * Returns only if critical code in progress */void kodint (void){  settimeout (0);		/* disable all interrupts */  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);  logout = goodbye = "Killed (lost mailbox lock)";  if (critical) {		/* must defer if in critical code */    close (0);			/* kill stdin */    state = LOGOUT;		/* die as soon as we can */  }  else longjmp (jmpenv,1);	/* die now */}/* Hangup interrupt * Returns only if critical code in progress */void hupint (void){  settimeout (0);		/* disable all interrupts */  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);  logout = "Hangup";  goodbye = NIL;		/* other end is already gone */  if (critical) {		/* must defer if in critical code */    close (0);			/* kill stdin */    close (1);			/* and stdout */    state = LOGOUT;		/* die as soon as we can */  }  else longjmp (jmpenv,1);	/* die now */}/* Termination interrupt * Returns only if critical code in progress */void trmint (void){  settimeout (0);		/* disable all interrupts */  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);  logout = goodbye = "Killed (terminated)";  /* Make no attempt at graceful closure since a shutdown may be in   * progress, and we won't have any time to do mail_close() actions   */  stream = NIL;  if (critical) {		/* must defer if in critical code */    close (0);			/* kill stdin */    close (1);			/* and stdout */    state = LOGOUT;		/* die as soon as we can */  }  else longjmp (jmpenv,1);	/* die now */}/* The routines on this and the next page eschew the use of non-syscall libc * routines (especially stdio) for a reason.  Also, these hideous #if * condtionals need to be replaced. */#ifndef unix#define unix 0#endif/* Status request interrupt * Always returns */void staint (void){#if unix  int fd;  char *s,buf[8*MAILTMPLEN];  unsigned long pid = getpid ();				/* build file name */  s = nout (sout (buf,"/tmp/imapd-status."),pid,10);  if (user) s = sout (sout (s,"."),user);  *s = '\0';			/* tie off file name */  if ((fd = open (buf,O_WRONLY | O_CREAT | O_TRUNC,0666)) >= 0) {    fchmod (fd,0666);    s = nout (sout (buf,"PID="),pid,10);    if (user) s = sout (sout (s,", user="),user);    switch (state) {    case LOGIN:      s = sout (s,", not logged in");      break;    case SELECT:      s = sout (s,", logged in");      break;    case OPEN:      s = sout (s,", mailbox open");      break;    case LOGOUT:      s = sout (s,", logging out");      break;    }    if (stream && stream->mailbox)      s = sout (sout (s,"\nmailbox="),stream->mailbox);    *s++ = '\n';    if (status) {      s = sout (s,status);      if (cmd) s = sout (sout (s,", last command="),cmd);    }    else s = sout (sout (s,cmd)," in progress");    *s++ = '\n';    write (fd,buf,s-buf);    close (fd);  }#endif}/* Write string * Accepts: destination string pointer *	    string * Returns: updated string pointer */char *sout (char *s,char *t){  while (*t) *s++ = *t++;  return s;}/* Write number * Accepts: destination string pointer *	    number *	    base * Returns: updated string pointer */char *nout (char *s,unsigned long n,unsigned long base){  char stack[256];  char *t = stack;				/* push PID digits on stack */  do *t++ = (char) (n % base) + '0';  while (n /= base);				/* pop digits from stack */  while (t > stack) *s++ = *--t;  return s;}/* Slurp a command line * Accepts: buffer pointer *	    buffer size *	    input timeout */void slurp (char *s,int n,unsigned long timeout){  memset (s,'\0',n);		/* zap buffer */  if (state != LOGOUT) {	/* get a command under timeout */    settimeout (timeout);    clearerr (stdin);		/* clear stdin errors */    status = "reading line";    if (!PSIN (s,n-1)) ioerror (stdin,status);    settimeout (0);		/* make sure timeout disabled */    status = NIL;  }}/* Read a literal * Accepts: destination buffer (must be size+1 for trailing NUL) *	    size of buffer (must be less than 4294967295) */void inliteral (char *s,unsigned long n){  unsigned long i;  if (litplus.ok) {		/* no more LITERAL+ to worry about */    litplus.ok = NIL;    litplus.size = 0;  }  else {			/* otherwise tell client ready for argument */    PSOUT ("+ Ready for argument\015\012");    PFLUSH ();			/* dump output buffer */  }  clearerr (stdin);		/* clear stdin errors */  memset (s,'\0',n+1);		/* zap buffer */  status

⌨️ 快捷键说明

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