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

📄 imapd.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* no more last error or literal */    if (lstwrn) fs_give ((void **) &lstwrn);    if (lsterr) fs_give ((void **) &lsterr);    if (lstref) fs_give ((void **) &lstref);    while (litsp) fs_give ((void **) &litstk[--litsp]);				/* find end of line */    if (!strchr (cmdbuf,'\012')) {      if (t = strchr (cmdbuf,' ')) *t = '\0';      if ((t - cmdbuf) > 100) t = NIL;      flush ();			/* flush excess */      if (state == LOGIN)	/* error if NLI */	syslog (LOG_INFO,"Line too long before authentication host=%.80s",		tcp_clienthost ());      sprintf (tmp,response,t ? (char *) cmdbuf : "*");      PSOUT (tmp);    }    else if (!(tag = strtok (cmdbuf," \015\012"))) {      if (state == LOGIN)	/* error if NLI */	syslog (LOG_INFO,"Null command before authentication host=%.80s",		tcp_clienthost ());      PSOUT ("* BAD Null command\015\012");    }    else if (strlen (tag) > 50) PSOUT ("* BAD Excessively long tag\015\012");    else if (!(s = strtok (NIL," \015\012"))) {      if (state == LOGIN)	/* error if NLI */	syslog (LOG_INFO,"Missing command before authentication host=%.80s",		tcp_clienthost ());      PSOUT (tag);      PSOUT (" BAD Missing command\015\012");    }    else {			/* parse command */      response = win;		/* set default response */      finding = NIL;		/* no longer FINDing */      ucase (s);		/* canonicalize command case */				/* UID command? */      if (!strcmp (s,"UID") && strtok (NIL," \015\012")) {	uid = T;		/* a UID command */	s[3] = ' ';		/* restore the space delimiter */	ucase (s);		/* make sure command all uppercase */      }      else uid = NIL;		/* not a UID command */				/* flush previous saved command */      if (cmd) fs_give ((void **) &cmd);      cmd = cpystr (s);		/* save current command */				/* snarf argument, see if possible litplus */      if ((arg = strtok (NIL,"\015\012")) && ((i = strlen (arg)) > 3) &&	  (arg[i - 1] == '}') && (arg[i - 2] == '+') && isdigit (arg[i - 3])) {				/* back over possible count */	for (i -= 4; i && isdigit (arg[i]); i--);	if (arg[i] == '{') {	/* found a literal? */	  litplus.ok = T;	/* yes, note LITERAL+ in effect, set size */	  litplus.size = strtoul (arg + i + 1,NIL,10);	}      }				/* these commands always valid */      if (!strcmp (cmd,"NOOP")) {	if (arg) response = badarg;	else if (stream)	/* allow untagged EXPUNGE */	  mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);      }      else if (!strcmp (cmd,"LOGOUT")) {	if (arg) response = badarg;	else {			/* time to say farewell */	  server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN);	  if (lastsel) fs_give ((void **) &lastsel);	  if (state == OPEN) stream = mail_close (stream);	  state = LOGOUT;	  PSOUT ("* BYE ");	  PSOUT (mylocalhost ());	  PSOUT (" IMAP4rev1 server terminating connection\015\012");	}      }      else if (!strcmp (cmd,"CAPABILITY")) {	if (arg) response = badarg;	else {	  PSOUT ("* ");	  pcapability (0);	/* print capabilities */	  CRLF;	}	if (stream)		/* allow untagged EXPUNGE */	  mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);      }#ifdef NETSCAPE_BRAIN_DAMAGE      else if (!strcmp (cmd,"NETSCAPE")) {	PSOUT ("* OK [NETSCAPE]\015\012* VERSION 1.0 UNIX\015\012* ACCOUNT-URL \"");	PSOUT (NETSCAPE_BRAIN_DAMAGE);	PBOUT ('"');	CRLF;      }#endif      else switch (state) {	/* dispatch depending upon state */      case LOGIN:		/* waiting to get logged in */				/* new style authentication */	if (!strcmp (cmd,"AUTHENTICATE")) {	  if (user) fs_give ((void **) &user);	  if (pass) fs_give ((void **) &pass);	  initial = NIL;	/* no initial argument */	  cancelled = NIL;	/* not cancelled */				/* mandatory first argument */	  if (!(s = snarf (&arg))) response = misarg;	  else if (arg && !(initial = snarf_base64 (&arg)))	    response = misarg;	/* optional second argument */	  else if (arg) response = badarg;	  else if (!strcmp (ucase (s),"ANONYMOUS") && !stat (ANOFILE,&sbuf)) {	    if (!(s = imap_responder ("",0,NIL)))	      response ="%.80s BAD AUTHENTICATE ANONYMOUS cancelled\015\012";	    else if (anonymous_login (argc,argv)) {	      anonymous = T;	/* note we are anonymous */	      user = cpystr ("ANONYMOUS");	      pass = cpystr ("*");	      state = SELECT;	/* make select */	      alerttime = 0;	/* force alert */	      response = logwin;/* return logged-in capabilities */	      syslog (LOG_INFO,"Authenticated anonymous=%.80s host=%.80s",s,		      tcp_clienthost ());	      fs_give ((void **) &s);	    }	    else response ="%.80s NO AUTHENTICATE ANONYMOUS failed\015\012";	  }	  else if (user = cpystr (mail_auth (s,imap_responder,argc,argv))) {	    pass = cpystr ("*");	    state = SELECT;	/* make select */	    alerttime = 0;	/* force alert */	    response = logwin;	/* return logged-in capabilities */	    syslog (LOG_INFO,"Authenticated user=%.80s host=%.80s mech=%.80s",		    user,tcp_clienthost (),s);	  }	  else {	    AUTHENTICATOR *auth = mail_lookup_auth (1);	    char *msg = (char *) fs_get (strlen (cmd) + strlen (s) + 2);	    sprintf (msg,"%s %s",cmd,s);	    fs_give ((void **) &cmd);	    cmd = msg;	    for (i = !mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL);		 auth && compare_cstring (s,auth->name); auth = auth->next);	    /* Failed authentication when hidden looks like invalid command.	     * This is intentional but confused me when I was debugging.	     */	    if (auth && auth->server && !(auth->flags & AU_DISABLE) &&		!(auth->flags & AU_HIDE) && (i || (auth->flags & AU_SECURE))) {	      response = lose;	      if (cancelled) {		if (lsterr) fs_give ((void **) &lsterr);		lsterr = cpystr ("cancelled by user");	      }	      if (!lsterr)	/* catch-all */		lsterr = cpystr ("Invalid authentication credentials");	      syslog (LOG_INFO,"AUTHENTICATE %.80s failure host=%.80s",s,		      tcp_clienthost ());	    }	    else {	      response = badcmd;	      syslog (LOG_INFO,"AUTHENTICATE %.80s invalid host=%.80s",s,		      tcp_clienthost ());	    }	  }	}				/* plaintext login with password */	else if (!strcmp (cmd,"LOGIN")) {	  if (user) fs_give ((void **) &user);	  if (pass) fs_give ((void **) &pass);				/* two arguments */	  if (!((user = cpystr (snarf (&arg))) &&		(pass = cpystr (snarf (&arg))))) response = misarg;	  else if (arg) response = badarg;				/* see if we allow anonymous */	  else if (!compare_cstring (user,"ANONYMOUS") &&		   !stat (ANOFILE,&sbuf) && anonymous_login (argc,argv)) {	    anonymous = T;	/* note we are anonymous */	    ucase (user);	/* make all uppercase for consistency */	    state = SELECT;	/* make select */	    alerttime = 0;	/* force alert */	    response = logwin;	/* return logged-in capabilities */	    syslog (LOG_INFO,"Login anonymous=%.80s host=%.80s",pass,		    tcp_clienthost ());	  }	  else {		/* delimit user from possible admin */	    if (s = strchr (user,'*')) *s++ ='\0';				/* see if username and password are OK */	    if (server_login (user,pass,s,argc,argv)) {	      state = SELECT;	/* make select */	      alerttime = 0;	/* force alert */	      response = logwin;/* return logged-in capabilities */	      syslog (LOG_INFO,"Login user=%.80s host=%.80s",user,		      tcp_clienthost ());	    }	    else {	      response = lose;	      if (!lsterr) lsterr = cpystr ("Invalid login credentials");	    }	  }	}				/* start TLS security */	else if (!strcmp (cmd,"STARTTLS")) {	  if (arg) response = badarg;	  else if (lsterr = ssl_start_tls (pgmname)) response = lose;	}	else response = badcmd;	break;      case OPEN:		/* valid only when mailbox open */				/* fetch mailbox attributes */	if (!strcmp (cmd,"FETCH") || !strcmp (cmd,"UID FETCH")) {	  if (!(arg && (s = strtok (arg," ")) && (t = strtok(NIL,"\015\012"))))	    response = misarg;	  else if (uid ? mail_uid_sequence (stream,s) :		   mail_sequence (stream,s)) fetch (t,uid);	  else response = badseq;	}				/* store mailbox attributes */	else if (!strcmp (cmd,"STORE") || !strcmp (cmd,"UID STORE")) {				/* must have three arguments */	  if (!(arg && (s = strtok (arg," ")) && (v = strtok (NIL," ")) &&		(t = strtok (NIL,"\015\012")))) response = misarg;	  else if (!(uid ? mail_uid_sequence (stream,s) :		     mail_sequence (stream,s))) response = badseq;	  else {	    f = ST_SET | (uid ? ST_UID : NIL)|((v[5]&&v[6]) ? ST_SILENT : NIL);	    if (!strcmp (ucase (v),"FLAGS") || !strcmp (v,"FLAGS.SILENT")) {	      strcpy (tmp,"\\Answered \\Flagged \\Deleted \\Draft \\Seen");	      for (i = 0, u = tmp;		   (i < NUSERFLAGS) && (v = stream->user_flags[i]); i++)	        if (strlen (v) <		    ((size_t) (MAILTMPLEN - ((u += strlen (u)) + 2 - tmp)))) {		  *u++ = ' ';	/* write next flag */		  strcpy (u,v);		}	      mail_flag (stream,s,tmp,f & ~ST_SET);	    }	    else if (!strcmp (v,"-FLAGS") || !strcmp (v,"-FLAGS.SILENT"))	      f &= ~ST_SET;	/* clear flags */	    else if (strcmp (v,"+FLAGS") && strcmp (v,"+FLAGS.SILENT")) {	      response = badatt;	      break;	    }				/* find last keyword */	    for (i = 0; (i < NUSERFLAGS) && stream->user_flags[i]; i++);	    mail_flag (stream,s,t,f);				/* any new keywords appeared? */	    if (i < NUSERFLAGS && stream->user_flags[i]) new_flags (stream);				/* return flags if silence not wanted */	    if (uid ? mail_uid_sequence (stream,s) : mail_sequence (stream,s))	      for (i = 1; i <= nmsgs; i++) if (mail_elt(stream,i)->sequence)		mail_elt (stream,i)->spare2 = (f & ST_SILENT) ? NIL : T;	  }	}				/* check for new mail */	else if (!strcmp (cmd,"CHECK")) {				/* no arguments */	  if (arg) response = badarg;	  else if (!anonymous) {	    mail_check (stream);				/* remember last check time */	    lastcheck = time (0);	  }	}				/* expunge deleted messages */	else if (!(anonymous || (strcmp (cmd,"EXPUNGE") &&				 strcmp (cmd,"UID EXPUNGE")))) {	  if (uid && !arg) response = misarg;	  else if (!uid && arg) response = badarg;	  else {		/* expunge deleted or specified UIDs */	    mail_expunge_full (stream,arg,arg ? EX_UID : NIL);				/* remember last checkpoint */	    lastcheck = time (0);	  }	}				/* close mailbox */	else if (!strcmp (cmd,"CLOSE") || !strcmp (cmd,"UNSELECT")) {				/* no arguments */	  if (arg) response = badarg;	  else {				/* no last uid */	    uidvalidity = lastuid = 0;	    if (lastsel) fs_give ((void **) &lastsel);	    if (lastid) fs_give ((void **) &lastid);	    if (lastst.data) fs_give ((void **) &lastst.data);	    stream = mail_close_full (stream,((*cmd == 'C') && !anonymous) ?				      CL_EXPUNGE : NIL);	    state = SELECT;	/* no longer opened */	    lastcheck = 0;	/* no last checkpoint */	  }	}	else if (!anonymous &&	/* copy message(s) */		 (!strcmp (cmd,"COPY") || !strcmp (cmd,"UID COPY"))) {	  trycreate = NIL;	/* no trycreate status */	  if (!(arg && (s = strtok (arg," ")) && (arg = strtok(NIL,"\015\012"))		&& (t = snarf (&arg)))) response = misarg;	  else if (arg) response = badarg;	  else if (!nmsgs) {	    response = lose;	    if (!lsterr) lsterr = cpystr ("Mailbox is empty");	  }	  else if (!(uid ? mail_uid_sequence (stream,s) :		     mail_sequence (stream,s))) response = badseq;				/* try copy */	  else if (!mail_copy_full (stream,s,t,uid ? CP_UID : NIL)) {	    response = trycreate ? losetry : lose;	    if (!lsterr) lsterr = cpystr ("No such destination mailbox");	  }	}				/* sort mailbox */	else if (!strcmp (cmd,"SORT") || !strcmp (cmd,"UID SORT")) {				/* must have four arguments */	  if (!(arg && (*arg == '(') && (t = strchr (s = arg + 1,')')) &&		(t[1] == ' ') && (*(arg = t + 2)))) response = misarg;	  else {		/* read criteria */	    SEARCHPGM *spg = NIL;	    char *cs = NIL;	    SORTPGM *pgm = NIL,*pg = NIL;	    unsigned long *slst,*sl;	    *t = NIL;		/* tie off criteria list */	    if (!(s = strtok (ucase (s)," "))) response = badatt;	    else {	      do {		/* parse sort attributes */		if (pg) pg = pg->next = mail_newsortpgm ();		else pgm = pg = mail_newsortpgm ();		if (!strcmp (s,"REVERSE")) {		  pg->reverse = T;		  if (!(s = strtok (NIL," "))) {		    s = "";	/* end of attributes */		    break;		  }		}		if (!strcmp (s,"DATE")) pg->function = SORTDATE;		else if (!strcmp (s,"ARRIVAL")) pg->function = SORTARRIVAL;		else if (!strcmp (s,"FROM")) pg->function = SORTFROM;		else if (!strcmp (s,"SUBJECT")) pg->function = SORTSUBJECT;		else if (!strcmp (s,"TO")) pg->function = SORTTO;		else if (!strcmp (s,"CC")) pg->function = SORTCC;		else if (!strcmp (s,"SIZE")) pg->function = SORTSIZE;		else break;	      } while (s = strtok (NIL," "));				/* bad SORT attribute */	      if (s) response = badatt;				/* get charset and search criteria */	      else if (!((t = snarf (&arg)) && (cs = cpystr (t)) && arg &&			 *arg)) response = misarg;				/* parse search criteria  */	      else if (!parse_criteria (spg = mail_newsearchpgm (),&arg,nmsgs,					uidmax (stream),0)) response = badatt;	      else if (arg && *arg) response = badarg;	      else if (slst = mail_sort (stream,cs,spg,pgm,uid ? SE_UID:NIL)) {		PSOUT ("* SORT");		for (sl = slst; *sl; sl++) {		  PBOUT (' ');		  pnum (*sl);		}		CRLF;		fs_give ((void **) &slst);	      }	    }	    if (pgm) mail_free_sortpgm (&pgm);	    if (spg) mail_free_searchpgm (&spg);	    if (cs) fs_give ((void **) &cs);	  }	}				/* thread mailbox */	else if (!strcmp (cmd,"THREAD") || !strcmp (cmd,"UID THREAD")) {	  THREADNODE *thr;	  SEARCHPGM *spg = NIL;	  char *cs = NIL;				/* must have four arguments */	  if (!(arg && (s = strtok (arg," ")) && (cs = strtok (NIL," ")) &&		(cs = cpystr (cs)) && (arg = strtok (NIL,"\015\012"))))	    response = misarg;	  else if (!parse_criteria (spg = mail_newsearchpgm (),&arg,nmsgs,				    uidmax (stream),0)) response = badatt;	  else if (arg && *arg) response = badarg;	  else {	    if (thr = mail_thread (stream,s,cs,spg,uid ? SE_UID : NIL)) {	      PSOUT ("* THREAD ");	      pthread (thr);	      mail_free_threadnode (&thr);	    }	    else PSOUT ("* THREAD");	    CRLF;	  }	  if (spg) mail_free_searchpgm (&spg);	  if (cs) fs_give ((void **) &cs);	}				/* search mailbox */        else if (!strcmp (cmd,"SEARCH") || !strcmp (cmd,"UID SEARCH")) {	  int retval = NIL;

⌨️ 快捷键说明

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