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

📄 imapd.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* subscribe to mailbox */	else if (!(anonymous || strcmp (cmd,"SUBSCRIBE"))) {				/* get <mailbox> or MAILBOX <mailbox> */	  if (!(s = snarf (&arg))) response = misarg;	  else if (arg) {	/* IMAP2bis form */	    if (compare_cstring (s,"MAILBOX")) response = badarg;	    else if (!(s = snarf (&arg))) response = misarg;	    else if (arg) response = badarg;	    else mail_subscribe (NIL,s);	  }	  else if (isnewsproxy (s)) newsrc_update (NIL,s+6,':');	  else mail_subscribe (NIL,s);	  if (stream)		/* allow untagged EXPUNGE */	    mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);	}				/* unsubscribe to mailbox */	else if (!(anonymous || strcmp (cmd,"UNSUBSCRIBE"))) {				/* get <mailbox> or MAILBOX <mailbox> */	  if (!(s = snarf (&arg))) response = misarg;	  else if (arg) {	/* IMAP2bis form */	    if (compare_cstring (s,"MAILBOX")) response = badarg;	    else if (!(s = snarf (&arg))) response = misarg;	    else if (arg) response = badarg;	    else if (isnewsproxy (s)) newsrc_update (NIL,s+6,'!');	    else mail_unsubscribe (NIL,s);	  }	  else mail_unsubscribe (NIL,s);	  if (stream)		/* allow untagged EXPUNGE */	    mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);	}	else if (!strcmp (cmd,"NAMESPACE")) {	  if (arg) response = badarg;	  else {	    NAMESPACE **ns = (NAMESPACE **) mail_parameters(NIL,GET_NAMESPACE,							     NIL);	    NAMESPACE *n;	    PARAMETER *p;	    PSOUT ("* NAMESPACE");	    if (ns) for (i = 0; i < 3; i++) {	      if (n = ns[i]) {		PSOUT (" (");		do {		  PBOUT ('(');		  pstring (n->name);		  switch (n->delimiter) {		  case '\\':	/* quoted delimiter */		  case '"':		    PSOUT (" \"\\\\\"");		    break;		  case '\0':	/* no delimiter */		    PSOUT (" NIL");		    break;		  default:	/* unquoted delimiter */		    PSOUT (" \"");		    PBOUT (n->delimiter);		    PBOUT ('"');		    break;		  }				/* NAMESPACE extensions are hairy */		  if (p = n->param) do {		    PBOUT (' ');		    pstring (p->attribute);		    PSOUT (" (");		    do pstring (p->value);		    while (p->next && !p->next->attribute && (p = p->next));		    PBOUT (')');		  } while (p = p->next);		  PBOUT (')');		} while (n = n->next);		PBOUT (')');	      }	      else PSOUT (" NIL");	    }	    else PSOUT (" NIL NIL NIL");	    CRLF;	  }	  if (stream)		/* allow untagged EXPUNGE */	    mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);	}				/* create mailbox */	else if (!(anonymous || strcmp (cmd,"CREATE"))) {	  if (!(s = snarf (&arg))) response = misarg;	  else if (arg) response = badarg;	  else mail_create (NIL,s);	  if (stream)		/* allow untagged EXPUNGE */	    mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);	}				/* delete mailbox */	else if (!(anonymous || strcmp (cmd,"DELETE"))) {	  if (!(s = snarf (&arg))) response = misarg;	  else if (arg) response = badarg;	  else {		/* make sure not selected */	    if (lastsel && (!strcmp (s,lastsel) ||			    (stream && !strcmp (s,stream->mailbox))))	      mm_log ("Can not DELETE the selected mailbox",ERROR);	    else mail_delete (NIL,s);	  }	  if (stream)		/* allow untagged EXPUNGE */	    mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);	}				/* rename mailbox */	else if (!(anonymous || strcmp (cmd,"RENAME"))) {	  if (!((s = snarf (&arg)) && (t = snarf (&arg)))) response = misarg;	  else if (arg) response = badarg;	  else {		/* make sure not selected */	    if (!compare_cstring (s,"INBOX")) s = "INBOX";	    else if (!compare_cstring (s,"#MHINBOX")) s = "#MHINBOX";	    if (lastsel && (!strcmp (s,lastsel) ||			    (stream && !strcmp (s,stream->mailbox))))	      mm_log ("Can not RENAME the selected mailbox",ERROR);	    else mail_rename (NIL,s,t);	  }	  if (stream)		/* allow untagged EXPUNGE */	    mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);	}				/* idle mode */	else if (!strcmp (cmd,"IDLE")) {				/* no arguments */	  if (arg) response = badarg;	  else {		/* tell client ready for argument */	    unsigned long donefake = 0;	    PSOUT ("+ Waiting for DONE\015\012");	    PFLUSH ();		/* dump output buffer */				/* inactivity countdown */	    i = ((TIMEOUT) / (IDLETIMER)) + 1;	    do {		/* main idle loop */	      if (!donefake) {	/* don't ping mailbox if faking */		mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,				 (void *) stream);		ping_mailbox (uid);				/* maybe do a checkpoint if not anonymous */		if (!anonymous && stream && (time (0) > lastcheck + CHECKTIMER)) {		  mail_check (stream);				/* cancel likely altwin from mail_check() */		  if (lsterr) fs_give ((void **) &lsterr);		  if (lstwrn) fs_give ((void **) &lstwrn);				/* remember last checkpoint */		  lastcheck = time (0);		}	      }	      if (lstwrn) {	/* have a warning? */		PSOUT ("* NO ");		PSOUT (lstwrn);		CRLF;		fs_give ((void **) &lstwrn);	      }	      if (!(i % 2)) {	/* prevent NAT timeouts */		sprintf (tmp,"* OK Timeout in %lu minutes\015\012",			 (i * IDLETIMER) / 60);		PSOUT (tmp);	      }				/* two minutes before the end... */	      if ((state == OPEN) && (i <= 2)) {		sprintf (tmp,"* %lu EXISTS\015\012* %lu RECENT\015\012",			 donefake = nmsgs + 1,recent + 1);		PSOUT (tmp);	/* prod client to wake up */	      }	      PFLUSH ();	/* dump output buffer */	    } while ((state != LOGOUT) && !INWAIT (IDLETIMER) && --i);				/* time to exit idle loop */	    if (state != LOGOUT) {	      if (i) {		/* still have time left? */				/* yes, read expected DONE */		slurp (tmp,MAILTMPLEN,INPUTTIMEOUT);		if (((tmp[0] != 'D') && (tmp[0] != 'd')) ||		    ((tmp[1] != 'O') && (tmp[1] != 'o')) ||		    ((tmp[2] != 'N') && (tmp[2] != 'n')) ||		    ((tmp[3] != 'E') && (tmp[3] != 'e')) ||		    (((tmp[4] != '\015') || (tmp[5] != '\012')) &&		     (tmp[4] != '\012')))		  response = "%.80s BAD Bogus IDLE continuation\015\012";		if (donefake) {	/* if faking at the end */				/* send EXPUNGE (should be just 1) */		  while (donefake > nmsgs) {		    sprintf (tmp,"* %lu EXPUNGE\015\012",donefake--);		    PSOUT (tmp);		  }		  sprintf (tmp,"* %lu EXISTS\015\012* %lu RECENT\015\012",			   nmsgs,recent);		  PSOUT (tmp);		}	      }	      else clkint ();	/* otherwise do autologout action */	    }	  }	}	else response = badcmd;	break;      default:        response = "%.80s BAD Unknown state for %.80s command\015\012";	break;      }      while (litplus.ok) {	/* any unread LITERAL+? */	litplus.ok = NIL;	/* yes, cancel it now */	clearerr (stdin);	/* clear stdin errors */	status = "discarding unread literal";				/* read literal and discard it */	while (i = (litplus.size > MAILTMPLEN) ? MAILTMPLEN : litplus.size) {	  if (state == LOGOUT) litplus.size = 0;	  else {	    settimeout (INPUTTIMEOUT);	    if (PSINR (tmp,i)) litplus.size -= i;	    else {	      ioerror (stdin,status);	      litplus.size = 0;	/* in case it continues */	    }	  }	}	settimeout (0);		/* stop timeout */				/* get new command tail */	slurp (tmp,MAILTMPLEN,INPUTTIMEOUT);				/* locate end of line */	if (t = strchr (tmp,'\012')) {				/* back over CR */	  if ((t > tmp) && (t[-1] == '\015')) --t;	  *t = NIL;		/* tie off CRLF */				/* possible LITERAL+? */	  if (((i = strlen (tmp)) > 3) && (tmp[i - 1] == '}') &&	      (tmp[i - 2] == '+') && isdigit (tmp[i - 3])) {				/* back over possible count */	    for (i -= 4; i && isdigit (tmp[i]); i--);	    if (tmp[i] == '{') {	/* found a literal? */	      litplus.ok = T;	/* yes, note LITERAL+ in effect, set size */	      litplus.size = strtoul (tmp + i + 1,NIL,10);	    }	  }	}	else flush ();		/* overlong line after LITERAL+, punt */      }      ping_mailbox (uid);	/* update mailbox status before response */      if (lstwrn && lsterr) {	/* output most recent warning */	PSOUT ("* NO ");	PSOUT (lstwrn);	CRLF;	fs_give ((void **) &lstwrn);      }      if (response == logwin) {	/* authentication win message */	sprintf (tmp,response,lstref ? "*" : tag);	PSOUT (tmp);		/* start response */	pcapability (1);	/* print logged-in capabilities */	PSOUT ("] User ");	PSOUT (user);	PSOUT (" authenticated\015\012");	if (lstref) {	  sprintf (tmp,response,tag);	  PSOUT (tmp);		/* start response */	  PSOUT ("[REFERRAL ");	  PSOUT (lstref);	  PSOUT ("] ");	  PSOUT (lasterror ());	  CRLF;	}      }      else if ((response == win) || (response == lose)) {	sprintf (tmp,response,tag);	PSOUT (tmp);	if (cauidvalidity) {	/* COPYUID/APPENDUID response? */	  sprintf (tmp,"[%.80sUID %lu ",(char *)		   ((s = strchr (cmd,' ')) ? s+1 : cmd),cauidvalidity);	  PSOUT (tmp);	  cauidvalidity = 0;	/* cancel response for future */	  if (csset) {	    pset (&csset);	    PBOUT (' ');	  }	  pset (&caset);	  PSOUT ("] ");	}	else if (lstref) {	/* have a referral? */	  PSOUT ("[REFERRAL ");	  PSOUT (lstref);	  PSOUT ("] ");	}	if (lsterr || lstwrn) PSOUT (lasterror ());	else {	  PSOUT (cmd);	  PSOUT ((response == win) ? " completed" : "failed");	}	CRLF;      }      else {			/* normal response */	if ((response == rowin) || (response == rwwin)) {	  if (lstwrn) {		/* output most recent warning */	    PSOUT ("* NO ");	    PSOUT (lstwrn);	    CRLF;	    fs_give ((void **) &lstwrn);	  }	}	sprintf (tmp,response,tag,cmd,lasterror ());	PSOUT (tmp);		/* output response */      }    }    PFLUSH ();			/* make sure output blatted */    if (autologouttime) {	/* have an autologout in effect? */				/* cancel if no longer waiting for login */      if (state != LOGIN) autologouttime = 0;				/* took too long to login */      else if (autologouttime < time (0)) {	logout = goodbye = "Autologout";	stream = NIL;	state = LOGOUT;		/* sayonara */      }    }  }  if (goodbye && !quell_events){/* have a goodbye message? */    PSOUT ("* BYE ");		/* utter it */    PSOUT (goodbye);    CRLF;    PFLUSH ();			/* make sure blatted */  }  syslog (LOG_INFO,"%s user=%.80s host=%.80s",logout,	  user ? (char *) user : "???",tcp_clienthost ());				/* do logout hook if needed */  if (lgoh = (logouthook_t) mail_parameters (NIL,GET_LOGOUTHOOK,NIL))    (*lgoh) (mail_parameters (NIL,GET_LOGOUTDATA,NIL));  _exit (ret);			/* all done */  return ret;			/* stupid compilers */}/* Ping mailbox during each cycle.  Also check alerts * Accepts: last command was UID flag */void ping_mailbox (unsigned long uid){  unsigned long i;  char tmp[MAILTMPLEN];  if (state == OPEN) {    if (!mail_ping (stream)) {	/* make sure stream still alive */      PSOUT ("* BYE ");      PSOUT (mylocalhost ());      PSOUT (" Fatal mailbox error: ");      PSOUT (lasterror ());      CRLF;      stream = NIL;		/* don't try to clean up stream */      state = LOGOUT;		/* go away */      syslog (LOG_INFO,	      "Fatal mailbox error user=%.80s host=%.80s mbx=%.80s: %.80s",	      user ? (char *) user : "???",tcp_clienthost (),	      (stream && stream->mailbox) ? stream->mailbox : "???",	      lasterror ());      return;    }				/* change in number of messages? */    if (existsquelled || (nmsgs != stream->nmsgs)) {      PSOUT ("* ");      pnum (nmsgs = stream->nmsgs);      PSOUT (" EXISTS\015\012");    }				/* change in recent messages? */    if (existsquelled || (recent != stream->recent)) {      PSOUT ("* ");      pnum (recent = stream->recent);      PSOUT (" RECENT\015\012");    }    existsquelled = NIL;	/* don't do this until asked again */    if (stream->uid_validity && (stream->uid_validity != uidvalidity)) {      PSOUT ("* OK [UIDVALIDITY ");      pnum (stream->uid_validity);      PSOUT ("] UID validity status\015\012* OK [UIDNEXT ");      pnum (stream->uid_last + 1);      PSOUT ("] Predicted next UID\015\012");      if (stream->uid_nosticky) {	PSOUT ("* NO [UIDNOTSTICKY] Non-permanent unique identifiers: ");	PSOUT (stream->mailbox);	CRLF;      }      uidvalidity = stream->uid_validity;    }				/* don't bother if driver changed */    if (curdriver == stream->dtb) {				/* first report any new flags */      if ((nflags < NUSERFLAGS) && stream->user_flags[nflags])	new_flags (stream);      for (i = 1; i <= nmsgs; i++) if (mail_elt (stream,i)->spare2) {	PSOUT ("* ");	pnum (i);	PSOUT (" FETCH (");	fetch_flags (i,NIL);	/* output changed flags */	if (uid) {		/* need to include UIDs in response? */	  PBOUT (' ');	  fetch_uid (i,NIL);	}

⌨️ 快捷键说明

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