📄 imapd.c
字号:
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); cancelled = NIL; /* single argument */ if (!(s = snarf (&arg))) response = misarg; 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"); state = SELECT; /* make select */ alerttime = 0; /* force alert */ PSOUT ("* "); pcapability (1); /* print logged-in capabilities */ CRLF; 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))) { state = SELECT; /* make select */ alerttime = 0; /* force alert */ PSOUT ("* "); pcapability (1); /* print logged-in capabilities */ CRLF; syslog (LOG_INFO,"Authenticated user=%.80s host=%.80s", user,tcp_clienthost ()); } else { lsterr = cpystr (s); response = cancelled ? "%.80s BAD %.80s %.80s cancelled\015\012" : "%.80s NO %.80s %.80s failed\015\012"; syslog (LOG_INFO,"AUTHENTICATE %.80s failure 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 (((user[0] == 'a') || (user[0] == 'A')) && ((user[1] == 'n') || (user[1] == 'N')) && ((user[2] == 'o') || (user[2] == 'O')) && ((user[3] == 'n') || (user[3] == 'N')) && ((user[4] == 'y') || (user[4] == 'Y')) && ((user[5] == 'm') || (user[5] == 'M')) && ((user[6] == 'o') || (user[6] == 'O')) && ((user[7] == 'u') || (user[7] == 'U')) && ((user[8] == 's') || (user[8] == 'S')) && !user[9] && !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 */ PSOUT ("* "); pcapability (1); /* print logged-in capabilities */ CRLF; 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 */ PSOUT ("* "); pcapability (1); /* print logged-in capabilities */ CRLF; syslog (LOG_INFO,"Login user=%.80s host=%.80s",user, tcp_clienthost ()); } else response = "%.80s NO %.80s failed\015\012"; } }#ifdef IMAPSPECIALCAP else if (!strcmp (cmd,IMAPSPECIALCAP)) { if (arg) response = badarg; else if (lsterr = SPECIALCAP (argv[0])) response = lose; }#endif else response = "%.80s BAD Command unrecognized/login please: %.80s\015\012"; 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"))) { 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; } else response = misarg; } /* fetch partial mailbox attributes */ else if (!strcmp (cmd,"PARTIAL")) { SIZEDTEXT st; if (!(arg && (m = strtoul (arg,&s,10)) && (t = strtok (s," ")) && (s = strtok (NIL,"\015\012")) && (j = strtoul (s,&s,10)) && (k = strtoul (s,&s,10)))) response = misarg; else if (s && *s) response = badarg; else if (m > nmsgs) response = badseq; else { /* looks good */ int sf = mail_elt (stream,m)->seen; if (!strcmp (ucase (t),"RFC822")) st.data = (unsigned char *) mail_fetch_message (stream,m,&st.size,NIL); else if (!strcmp (t,"RFC822.PEEK")) st.data = (unsigned char *) mail_fetch_message (stream,m,&st.size,FT_PEEK); else if (!strcmp (t,"RFC822.HEADER")) st.data = (unsigned char *) mail_fetch_header (stream,m,NIL,NIL,&st.size,FT_PEEK); else if (!strcmp (t,"RFC822.TEXT")) st.data = (unsigned char *) mail_fetch_text (stream,m,NIL,&st.size,NIL); else if (!strcmp (t,"RFC822.TEXT.PEEK")) st.data = (unsigned char *) mail_fetch_text (stream,m,NIL,&st.size,FT_PEEK); else if (!strncmp (t,"BODY[",5) && (v = strchr(t+5,']')) && !v[1]){ strncpy (tmp,t+5,i = v - (t+5)); tmp[i] = '\0'; /* tie off body part */ st.data = (unsigned char *) mail_fetch_body (stream,m,tmp,&st.size,NIL); } else if (!strncmp (t,"BODY.PEEK[",10) && (v = strchr (t+10,']')) && !v[1]) { strncpy (tmp,t+10,i = v - (t+10)); tmp[i] = '\0'; /* tie off body part */ st.data = (unsigned char *) mail_fetch_body (stream,m,tmp,&st.size,FT_PEEK); } else response = badatt, st.data = NIL; if (st.data) { /* got a string? */ PSOUT ("* "); pnum (m); PSOUT (" FETCH ("); PSOUT (t); PBOUT (' '); /* start position larger than text size */ if (st.size <= --j) PSOUT ("NIL"); else { /* output as sized text */ st.data += j; if ((st.size -= j) > k) st.size = k; psizedtext (&st); } changed_flags (m,sf); PSOUT (")\015\012"); } } } /* 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"))) { /* no arguments */ if (arg) response = badarg; else { mail_expunge (stream); /* remember last checkpoint */ lastcheck = time (0); } } /* close mailbox */ else if (!strcmp (cmd,"CLOSE")) { /* no arguments */ if (arg) response = badarg; else { lastuid = 0; /* no last uid */ if (lastid) fs_give ((void **) &lastid); if (lastst.data) fs_give ((void **) &lastst.data); stream = mail_close_full (stream,anonymous ? NIL : CL_EXPUNGE); 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 = "%.80s NO Mailbox is empty\015\012"; /* try copy */ else if (!(stream->dtb->copy) (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 */ s = strtok (ucase (s)," "); 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; else if (!((t = snarf (&arg)) && (cs = cpystr (t)) && arg && *arg)) response = misarg;/* missing search attributes */ else if (!parse_criteria (spg = mail_newsearchpgm (),&arg,nmsgs, nmsgs ? mail_uid (stream,nmsgs) : 0,0)) response = badatt;/* bad search attribute */ 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; 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, nmsgs ? mail_uid (stream,nmsgs) : 0,0)) response = badatt;/* bad thread attribute */ else if (arg && *arg) response = badarg; else { if (thr = mail_thread (stream,ucase (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")) { char *charset = NIL; SEARCHPGM *pgm; /* one or more arguments required */ if (!arg) response = misarg; /* character set specified? */ else if ((arg[0] == 'C' || arg[0] == 'c') && (arg[1] == 'H' || arg[1] == 'h') && (arg[2] == 'A' || arg[2] == 'a') && (arg[3] == 'R' || arg[3] == 'r') && (arg[4] == 'S' || arg[4] == 's') && (arg[5] == 'E' || arg[5] == 'e') && (arg[6] == 'T' || arg[6] == 't') && (arg[7] == ' ' || arg[7] == ' ')) { arg += 8; /* yes, skip over CHARSET token */ if (s = snarf (&arg)) charset = cpystr (s); else { /* missing character set */ response = misarg; break; } } /* must have arguments here */ if (!(arg && *arg)) response = misarg; else if (parse_criteria (pgm = mail_newsearchpgm (),&arg,nmsgs, nmsgs ? mail_uid (stream,nmsgs) : 0,0) && !*arg) { mail_search_full (stream,charset,pgm,SE_FREE); if (response == win || response == altwin) { /* output search results */ PSOUT ("* SEARCH"); for (i = 1; i <= nmsgs; ++i) if (mail_elt (stream,i)->searched) { PBOUT (' '); pnum (uid ? mail_uid (stream,i) : i); } CRLF; } } else { response = "%.80s BAD Bogus criteria list in %.80s\015\012"; mail_free_searchpgm (&pgm); } if (charset) fs_give ((void **) &charset); } else /* fall into select case */ case SELECT: /* valid whenever logged in */ /* select new mailbox */ if (!(strcmp (cmd,"SELECT") && strcmp (cmd,"EXAMINE") &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -