📄 imapd.c
字号:
char *charset = NIL; SEARCHPGM *pgm; response = misarg; /* assume failure */ if (!arg) break; /* one or more arguments required */ if (((arg[0] == 'R') || (arg[0] == 'r')) && ((arg[1] == 'E') || (arg[1] == 'e')) && ((arg[2] == 'T') || (arg[2] == 't')) && ((arg[3] == 'U') || (arg[3] == 'u')) && ((arg[4] == 'R') || (arg[4] == 'r')) && ((arg[5] == 'N') || (arg[5] == 'n')) && (arg[6] == ' ') && (arg[7] == '(')) { retval = 0x4000; /* return is specified */ for (arg += 8; *arg && (*arg != ')'); ) { if (((arg[0] == 'M') || (arg[0] == 'm')) && ((arg[1] == 'I') || (arg[1] == 'i')) && ((arg[2] == 'N') || (arg[2] == 'n')) && ((arg[3] == ' ') || (arg[3] == ')'))) { retval |= 0x1; arg += 3; } else if (((arg[0] == 'M') || (arg[0] == 'm')) && ((arg[1] == 'A') || (arg[1] == 'a')) && ((arg[2] == 'X') || (arg[2] == 'x')) && ((arg[3] == ' ') || (arg[3] == ')'))) { retval |= 0x2; arg += 3; } else if (((arg[0] == 'A') || (arg[0] == 'a')) && ((arg[1] == 'L') || (arg[1] == 'l')) && ((arg[2] == 'L') || (arg[2] == 'l')) && ((arg[3] == ' ') || (arg[3] == ')'))) { retval |= 0x4; arg += 3; } else if (((arg[0] == 'C') || (arg[0] == 'c')) && ((arg[1] == 'O') || (arg[1] == 'o')) && ((arg[2] == 'U') || (arg[2] == 'u')) && ((arg[3] == 'N') || (arg[3] == 'n')) && ((arg[4] == 'T') || (arg[4] == 't')) && ((arg[5] == ' ') || (arg[5] == ')'))) { retval |= 0x10; arg += 5; } else break; /* unknown return value */ /* more return values to come */ if ((*arg == ' ') && (arg[1] != ')')) ++arg; } /* RETURN list must be properly terminated */ if ((*arg++ != ')') || (*arg++ != ' ')) break; /* default return value is ALL */ if (!(retval &= 0x3fff)) retval = 0x4; } /* character set specified? */ 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 += 8; /* yes, skip over CHARSET token */ if (s = snarf (&arg)) charset = cpystr (s); else break; /* missing character set */ } /* must have arguments here */ if (!(arg && *arg)) break; if (parse_criteria (pgm = mail_newsearchpgm (),&arg,nmsgs, uidmax (stream),0) && !*arg) { response = win; /* looks good, try the search */ mail_search_full (stream,charset,pgm,SE_FREE); /* output search results if success */ if (response == win) { if (retval) { /* ESEARCH desired */ PSOUT ("* ESEARCH (TAG "); pstring (tag); PBOUT (')'); if (uid) PSOUT (" UID"); /* wants MIN */ if (retval & 0x1) { for (i = 1; (i <= nmsgs) && !mail_elt (stream,i)->searched; ++i); if (i <= nmsgs) { PSOUT (" MIN "); pnum (uid ? mail_uid (stream,i) : i); } } /* wants MAX */ if (retval & 0x2) { for (i = nmsgs; i && !mail_elt (stream,i)->searched; --i); if (i) { PSOUT (" MAX "); pnum (uid ? mail_uid (stream,i) : i); } } /* wants ALL */ if (retval & 0x4) { unsigned long j; /* find first match */ for (i = 1; (i <= nmsgs) && !mail_elt (stream,i)->searched; ++i); if (i <= nmsgs) { PSOUT (" ALL "); pnum (uid ? mail_uid (stream,i) : i); j = i; /* last message output */ } while (++i <= nmsgs) { if (mail_elt (stream,i)->searched) { while ((++i <= nmsgs) && mail_elt (stream,i)->searched); /* previous message is end of range */ if (j != --i) { PBOUT (':'); pnum (uid ? mail_uid (stream,i) : i); } } /* search for next match */ while ((++i <= nmsgs) && !mail_elt (stream,i)->searched); if (i <= nmsgs) { PBOUT (','); pnum (uid ? mail_uid (stream,i) : i); j = i; /* last message output */ } } } /* wants COUNT */ if (retval & 0x10) { unsigned long j; for (i = 1, j = 0; i <= nmsgs; ++i) if (mail_elt (stream,i)->searched) ++j; PSOUT (" COUNT "); pnum (j); } } else { /* standard search */ PSOUT ("* SEARCH"); for (i = 1; i <= nmsgs; ++i) if (mail_elt (stream,i)->searched) { PBOUT (' '); pnum (uid ? mail_uid (stream,i) : i); } } CRLF; } } else 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") && strcmp (cmd,"BBOARD"))) { /* single argument */ if (!(s = snarf (&arg))) response = misarg; else if (arg) response = badarg; else if (nameok (NIL,s = bboardname (cmd,s))) { DRIVER *factory = mail_valid (NIL,s,NIL); f = (anonymous ? OP_ANONYMOUS + OP_READONLY : NIL) | ((*cmd == 'S') ? NIL : OP_READONLY); curdriver = NIL; /* no drivers known */ /* no last uid */ uidvalidity = lastuid = 0; if (lastid) fs_give ((void **) &lastid); if (lastst.data) fs_give ((void **) &lastst.data); nflags = 0; /* force update */ nmsgs = recent = 0xffffffff; if (factory && !strcmp (factory->name,"phile") && (stream = mail_open (stream,s,f | OP_SILENT)) && (response == win)) { BODY *b; /* see if proxy open */ if ((mail_elt (stream,1)->rfc822_size < 400) && mail_fetchstructure (stream,1,&b) && (b->type == TYPETEXT) && (t = mail_fetch_text (stream,1,NIL,&i,NIL)) && (i < MAILTMPLEN) && (t[0] == '{')) { /* copy and tie off */ strncpy (tmp,t,i)[i] = '\0'; /* nuke any trailing newline */ if (t = strpbrk (tmp,"\r\n")) *t = '\0'; /* try to open proxy */ if ((tstream = mail_open (NIL,tmp,f | OP_SILENT)) && (response == win) && tstream->nmsgs) { s = tmp; /* got it, close the link */ mail_close (stream); stream = tstream; tstream = NIL; } } /* now give the exists event */ stream->silent = NIL; mm_exists (stream,stream->nmsgs); } else if (!factory && isnewsproxy (s)) { sprintf (tmp,"{%.300s/nntp}%.300s",nntpproxy,(char *) s+6); stream = mail_open (stream,tmp,f); } /* open stream normally then */ else stream = mail_open (stream,s,f); if (stream && (response == win)) { state = OPEN; /* note state open */ if (lastsel) fs_give ((void **) &lastsel); /* canonicalize INBOX */ if (!compare_cstring (s,"#MHINBOX")) lastsel = cpystr ("#MHINBOX"); else lastsel = cpystr (compare_cstring (s,"INBOX") ? (char *) s : "INBOX"); /* note readonly/readwrite */ response = stream->rdonly ? rowin : rwwin; if (anonymous) syslog (LOG_INFO,"Anonymous select of %.80s host=%.80s", stream->mailbox,tcp_clienthost ()); lastcheck = 0; /* no last check */ } else { /* failed, nuke old selection */ if (stream) stream = mail_close (stream); state = SELECT; /* no mailbox open now */ if (lastsel) fs_give ((void **) &lastsel); response = lose; /* open failed */ } } } /* APPEND message to mailbox */ else if (!(anonymous || strcmp (cmd,"APPEND"))) { /* parse mailbox name */ if ((s = snarf (&arg)) && arg) { STRING st; /* message stringstruct */ APPENDDATA ad; ad.arg = arg; /* command arguments */ /* no message yet */ ad.flags = ad.date = ad.msg = NIL; ad.message = &st; /* pointer to stringstruct to use */ trycreate = NIL; /* no trycreate status */ if (!mail_append_multiple (NIL,s,append_msg,(void *) &ad)) { if (response == win) response = trycreate ? losetry : lose; /* this can happen with #driver. hack */ if (!lsterr) lsterr = cpystr ("No such destination mailbox"); } /* clean up any message text left behind */ if (ad.flags) fs_give ((void **) &ad.flags); if (ad.date) fs_give ((void **) &ad.date); if (ad.msg) fs_give ((void **) &ad.msg); } else response = misarg; if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* list mailboxes */ else if (!strcmp (cmd,"LIST") || !strcmp (cmd,"RLIST")) { /* get reference and mailbox argument */ if (!((s = snarf (&arg)) && (t = snarf_list (&arg)))) response = misarg; else if (arg) response = badarg; /* make sure anonymous can't do bad things */ else if (nameok (s,t)) { if (newsproxypattern (s,t,tmp,LONGT)) { proxylist = T; mail_list (NIL,"",tmp); proxylist = NIL; } else mail_list (NIL,s,t); } if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* scan mailboxes */ else if (!strcmp (cmd,"SCAN")) { /* get arguments */ if (!((s = snarf (&arg)) && (t = snarf_list (&arg)) && (u = snarf (&arg)))) response = misarg; else if (arg) response = badarg; /* make sure anonymous can't do bad things */ else if (nameok (s,t)) { if (newsproxypattern (s,t,tmp,NIL)) mm_log ("SCAN not permitted for news",ERROR); else mail_scan (NIL,s,t,u); } if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* list subscribed mailboxes */ else if (!strcmp (cmd,"LSUB") || !strcmp (cmd,"RLSUB")) { /* get reference and mailbox argument */ if (!((s = snarf (&arg)) && (t = snarf_list (&arg)))) response = misarg; else if (arg) response = badarg; /* make sure anonymous can't do bad things */ else if (nameok (s,t)) { if (newsproxypattern (s,t,tmp,NIL)) newsrc_lsub (NIL,tmp); else mail_lsub (NIL,s,t); } if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* find mailboxes */ else if (!strcmp (cmd,"FIND")) { /* get subcommand and true argument */ if (!(arg && (s = strtok (arg," \015\012")) && (s == cmd + 5) && (cmd[4] = ' ') && ucase (s) && (arg = strtok (NIL,"\015\012")) && (s = snarf_list (&arg)))) response = misarg; /* missing required argument */ else if (arg) response = badarg; /* punt on single-char wildcards */ else if (strpbrk (s,"%?")) response = "%.80s NO IMAP2 ? and %% wildcards not supported: %.80s\015\012"; else if (nameok (NIL,s)) { finding = T; /* note that we are FINDing */ /* dispatch based on type */ if (!strcmp (cmd,"FIND MAILBOXES") && !anonymous) mail_lsub (NIL,NIL,s); else if (!strcmp (cmd,"FIND ALL.MAILBOXES")) { /* convert * to % for compatible behavior */ for (t = s; *t; t++) if (*t == '*') *t = '%'; mail_list (NIL,NIL,s); } else response = badcmd; } if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* status of mailbox */ else if (!strcmp (cmd,"STATUS")) { if (!((s = snarf (&arg)) && arg && (*arg++ == '(') && (t = strchr (arg,')')) && (t - arg) && !t[1])) response = misarg; else { f = NIL; /* initially no flags */ *t = '\0'; /* tie off flag string */ /* read flags */ t = strtok (ucase (arg)," "); do { /* parse each one; unknown generate warning */ if (!strcmp (t,"MESSAGES")) f |= SA_MESSAGES; else if (!strcmp (t,"RECENT")) f |= SA_RECENT; else if (!strcmp (t,"UNSEEN")) f |= SA_UNSEEN; else if (!strcmp (t,"UIDNEXT")) f |= SA_UIDNEXT; else if (!strcmp (t,"UIDVALIDITY")) f |= SA_UIDVALIDITY; else { PSOUT ("* NO Unknown status flag "); PSOUT (t); CRLF; } } while (t = strtok (NIL," ")); ping_mailbox (uid); /* in case the fool did STATUS on open mbx */ PFLUSH (); /* make sure stdout is dumped in case slave */ if (!compare_cstring (s,"INBOX")) s = "INBOX"; else if (!compare_cstring (s,"#MHINBOX")) s = "#MHINBOX"; if (state == LOGOUT) response = lose; /* get mailbox status */ else if (lastsel && (!strcmp (s,lastsel) || (stream && !strcmp (s,stream->mailbox)))) { unsigned long unseen; /* snarl at cretins which do this */ PSOUT ("* NO CLIENT BUG DETECTED: STATUS on selected mailbox: "); PSOUT (s); CRLF; tmp[0] = ' '; tmp[1] = '\0'; if (f & SA_MESSAGES) sprintf (tmp + strlen (tmp)," MESSAGES %lu",stream->nmsgs); if (f & SA_RECENT) sprintf (tmp + strlen (tmp)," RECENT %lu",stream->recent); if (f & SA_UNSEEN) { for (i = 1,unseen = 0; i <= stream->nmsgs; i++) if (!mail_elt (stream,i)->seen) unseen++; sprintf (tmp + strlen (tmp)," UNSEEN %lu",unseen); } if (f & SA_UIDNEXT) sprintf (tmp + strlen (tmp)," UIDNEXT %lu",stream->uid_last+1); if (f & SA_UIDVALIDITY) sprintf (tmp + strlen(tmp)," UIDVALIDITY %lu", stream->uid_validity); tmp[1] = '('; strcat (tmp,")\015\012"); PSOUT ("* STATUS "); pastring (s); PSOUT (tmp); } else if (isnewsproxy (s)) { sprintf (tmp,"{%.300s/nntp}%.300s",nntpproxy,(char *) s+6); if (!mail_status (NIL,tmp,f)) response = lose; } else if (!mail_status (NIL,s,f)) response = lose; } if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -