📄 imapd.c
字号:
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 */ lastuid = 0; /* no last uid */ if (lastid) fs_give ((void **) &lastid); if (lastst.data) fs_give ((void **) &lastst.data); /* force update */ nmsgs = recent = 0xffffffff; if (factory && !strcmp (factory->name,"phile") && (stream = mail_open (stream,s,f | OP_SILENT)) && ((response == win) || (response == altwin))) { BODY *b; /* see if proxy open */ if ((mail_elt (stream,1)->rfc822_size < 400) && mail_fetchstructure (stream,1,&b) && (b->type == TYPETEXT) && (s = mail_fetch_text (stream,1,NIL,&i,NIL)) && (i < MAILTMPLEN) && (s[0] == '{')) { /* copy and tie off */ strncpy (tmp,s,i)[i] = '\0'; /* nuke any trailing newline */ if (s = strpbrk (tmp,"\r\n")) *s = '\0'; /* try to open proxy */ if ((tstream = mail_open (NIL,tmp,f | OP_SILENT)) && ((response == win) || (response == altwin)) && tstream->nmsgs) { /* 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); } /* open stream normally then */ else stream = mail_open (stream,s,f); if (stream && ((response == win) || (response == altwin))) { state = OPEN; /* note state open */ /* note readonly/readwrite */ response = stream->rdonly ? "%.80s OK [READ-ONLY] %.80s completed\015\012" : "%.80s OK [READ-WRITE] %.80s completed\015\012"; if (anonymous) syslog (LOG_INFO,"Anonymous select of %.80s host=%.80s", stream->mailbox,tcp_clienthost ()); lastcheck = 0; /* no last check */ } else { /* failed */ state = SELECT; /* no mailbox open now */ 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)) { response = trycreate ? losetry : lose; if (!lsterr) lsterr = cpystr ("Unexpected APPEND failure"); } /* 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)) 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)) mail_scan (NIL,s,t,u); if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* list subscribed mailboxes */ else if (!(anonymous || (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)) mail_lsub (NIL,s,t); if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* find mailboxes */ else if (!strcmp (cmd,"FIND")) { response = "%.80s OK FIND %.80s completed\015\012"; /* get subcommand and true argument */ if (!(arg && (s = strtok (arg," \015\012")) && (cmd = 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 FIND %.80s ? or %% wildcard not supported\015\012"; else if (nameok (NIL,s)) { finding = T; /* note that we are FINDing */ /* dispatch based on type */ if (!strcmp (cmd,"MAILBOXES") && !anonymous) mail_lsub (NIL,NIL,s); else if (!strcmp (cmd,"ALL.MAILBOXES")) { /* convert * to % for compatible behavior */ for (t = s; *t; t++) if (*t == '*') *t = '%'; mail_list (NIL,NIL,s); } else response="%.80s BAD Command unrecognized: FIND %.80s\015\012"; } 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 */ /* get mailbox status */ if ((state == LOGOUT) || !mail_status (NIL,s,f)) response = lose; } if (stream) /* allow untagged EXPUNGE */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream); } /* subscribe to mailbox */ else if (!(anonymous || strcmp (cmd,"SUBSCRIBE"))) { /* get <mailbox> or MAILBOX <mailbox> */ if (!(s = snarf (&arg))) response = misarg; else if (arg) { sprintf (tmp,"%.30s",s); if (strcmp (ucase (tmp),"MAILBOX")) response = badarg; else if (!(s = snarf (&arg))) response = misarg; else if (arg) response = badarg; else mail_subscribe (NIL,s); } 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) { sprintf (tmp,"%.30s",s); if (strcmp (ucase (tmp),"MAILBOX")) response = badarg; else if (!(s = snarf (&arg))) response = misarg; else if (arg) response = badarg; 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 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 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 */ PSOUT (argrdy); PFLUSH; /* dump output buffer */ /* maybe do a checkpoint if not anonymous */ if (!anonymous && stream && (time (0) > lastcheck + CHECKTIMER)) { mail_check (stream); /* cancel likely altwin from mail_check() */ if (response == altwin) response = win; /* remember last checkpoint */ lastcheck = time (0); } /* inactivity countdown */ i = ((TIMEOUT) / (IDLETIMER)) + 1; do { /* main idle loop */ mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *)stream); ping_mailbox (uid); if (lstwrn) { /* have a warning? */ PSOUT ("* NO "); PSOUT (lstwrn); CRLF; fs_give ((void **) &lstwrn); } 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); 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"; } else clkint (); /* otherwise do autologout action */ } } } else response = "%.80s BAD Command unrecognized: %.80s\015\012"; break; default: response = "%.80s BAD Server in unknown state for %.80s command\015\012"; break; } if (lstwrn) { /* output most recent warning */ PSOUT ("* NO "); PSOUT (lstwrn); CRLF; } /* get text for alternative win message now */ if (response == altwin) cmd = lsterr; /* build response */ sprintf (tmp,response,tag,cmd,lasterror ()); ping_mailbox (uid); /* update mailbox status before response */ 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)) { PSOUT ("* BYE Autologout\015\012"); syslog (LOG_INFO,"Autologout host=%.80s",tcp_clienthost ()); PFLUSH; /* make sure output blatted */ state = LOGOUT; /* sayonara */ } } } while (state != LOGOUT); /* until logged out */ syslog (LOG_INFO,"Logout user=%.80s host=%.80s",user ? user : "???", tcp_clienthost ()); return 0; /* all done */}/* 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; state = LOGOUT; /* go away */ syslog (LOG_INFO,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -