📄 mail.c
字号:
value = (void *) expungeatping; break; case SET_SORTRESULTS: mailsortresults = (sortresults_t) value; case GET_SORTRESULTS: ret = (void *) mailsortresults; break; case SET_THREADRESULTS: mailthreadresults = (threadresults_t) value; case GET_THREADRESULTS: ret = (void *) mailthreadresults; break; case SET_ALTDRIVER: mailaltdriver = (NETDRIVER *) value; case GET_ALTDRIVER: ret = (void *) mailaltdriver; break; case SET_ALTDRIVERNAME: mailaltdrivername = (char *) value; case GET_ALTDRIVERNAME: ret = (void *) mailaltdrivername; break; case SET_ALTOPTIONNAME: mailaltoptionname = (char *) value; case GET_ALTOPTIONNAME: ret = (void *) mailaltoptionname; break; case SET_TRYALTFIRST: tryaltfirst = (int) value; case GET_TRYALTFIRST: ret = (void *) tryaltfirst; break; case SET_NOTIMEZONES: notimezones = (int) value; case GET_NOTIMEZONES: ret = (void *) notimezones; break; case SET_ACL: mailaclresults = (getacl_t) value; case GET_ACL: ret = (void *) mailaclresults; break; case SET_LISTRIGHTS: maillistrightsresults = (listrights_t) value; case GET_LISTRIGHTS: ret = (void *) maillistrightsresults; break; case SET_MYRIGHTS: mailmyrightsresults = (myrights_t) value; case GET_MYRIGHTS: ret = (void *) mailmyrightsresults; break; case SET_QUOTA: mailquotaresults = (quota_t) value; case GET_QUOTA: ret = (void *) mailquotaresults; break; case SET_QUOTAROOT: mailquotarootresults = (quotaroot_t) value; case GET_QUOTAROOT: ret = (void *) mailquotarootresults; break; default: if (r = smtp_parameters (function,value)) ret = r; else if (r = env_parameters (function,value)) ret = r; else if (r = tcp_parameters (function,value)) ret = r; /* if have stream, do for its driver only */ else if (stream && stream->dtb) ret = (*stream->dtb->parameters) (function,value); /* else do all drivers */ else for (d = maildrivers; d; d = d->next) if (r = (d->parameters) (function,value)) ret = r; break; } return ret;}/* Mail validate mailbox name * Accepts: MAIL stream * mailbox name * purpose string for error message * Return: driver factory on success, NIL on failure */DRIVER *mail_valid (MAILSTREAM *stream,char *mailbox,char *purpose){ char tmp[MAILTMPLEN]; DRIVER *factory = NIL; /* validate name, find driver factory */ if (strlen (mailbox) < (NETMAXHOST+(NETMAXUSER*2)+NETMAXMBX+NETMAXSRV+50)) for (factory = maildrivers; factory && ((factory->flags & DR_DISABLE) || ((factory->flags & DR_LOCAL) && (*mailbox == '{')) || !(*factory->valid) (mailbox)); factory = factory->next); /* validate factory against non-dummy stream */ if (factory && stream && (stream->dtb != factory) && strcmp (stream->dtb->name,"dummy")) /* factory invalid; if dummy, use stream */ factory = strcmp (factory->name,"dummy") ? NIL : stream->dtb; if (!factory && purpose) { /* if want an error message */ sprintf (tmp,"Can't %s %.80s: %s",purpose,mailbox,(*mailbox == '{') ? "invalid remote specification" : "no such mailbox"); mm_log (tmp,ERROR); } return factory; /* return driver factory */}/* Mail validate network mailbox name * Accepts: mailbox name * mailbox driver to validate against * pointer to where to return host name if non-NIL * pointer to where to return mailbox name if non-NIL * Returns: driver on success, NIL on failure */DRIVER *mail_valid_net (char *name,DRIVER *drv,char *host,char *mailbox){ NETMBX mb; if (!mail_valid_net_parse (name,&mb) || strcmp (mb.service,drv->name)) return NIL; if (host) strcpy (host,mb.host); if (mailbox) strcpy (mailbox,mb.mailbox); return drv;}/* Mail validate network mailbox name * Accepts: mailbox name * NETMBX structure to return values * Returns: T on success, NIL on failure */long mail_valid_net_parse (char *name,NETMBX *mb){ int i,j; char c,*s,*t,*v,tmp[MAILTMPLEN],arg[MAILTMPLEN]; /* initialize structure */ memset (mb,'\0',sizeof (NETMBX)); /* have host specification? */ if (!((*name++ == '{') && (v = strpbrk (name,"/:}")) && (i = v - name) && (i < NETMAXHOST) && (t = strchr (v,'}')) && ((j = t - v)<MAILTMPLEN) && (strlen (t+1) < (size_t) NETMAXMBX))) return NIL; strncpy (mb->host,name,i); /* set host name */ strncpy (mb->orighost,name,i); mb->host[i] = mb->orighost[i] = '\0'; strcpy (mb->mailbox,t+1); /* set mailbox name */ if (t - v) { /* any switches or port specification? */ strncpy (t = tmp,v,j); /* copy it */ tmp[j] = '\0'; /* tie it off */ c = *t++; /* get first delimiter */ do switch (c) { /* act based upon the character */ case ':': /* port specification */ if (mb->port || !(mb->port = strtoul (t,&t,10))) return NIL; c = t ? *t++ : '\0'; /* get delimiter, advance pointer */ break; case '/': /* switch */ /* find delimiter */ if (t = strpbrk (s = t,"/:=")) { c = *t; /* remember delimiter for later */ *t++ = '\0'; /* tie off switch name */ } else c = '\0'; /* no delimiter */ lcase (s); /* coerce switch name to lower case */ if (c == '=') { /* parse switches which take arguments */ if (*t == '"') { /* quoted string? */ for (v = arg,i = 0,++t; (c = *t++) != '"';) { /* quote next character */ if (c == '\\') c = *t++; arg[i++] = c; } c = *t++; /* remember delimiter for later */ arg[i] = '\0'; /* tie off argument */ } else { /* non-quoted argument */ if (t = strpbrk (v = t,"/:")) { c = *t; /* remember delimiter for later */ *t++ = '\0'; /* tie off switch name */ } else c = '\0'; /* no delimiter */ i = strlen (v); /* length of argument */ } if (!strcmp (s,"service") && (i < NETMAXSRV)) { if (*mb->service) return NIL; else strcpy (mb->service,lcase (v)); } else if (!strcmp (s,"user") && (i < NETMAXUSER)) { if (*mb->user) return NIL; else strcpy (mb->user,v); } else if (!strcmp (s,"authuser") && (i < NETMAXUSER)) { if (*mb->authuser) return NIL; else strcpy (mb->authuser,v); } else return NIL; /* invalid argument switch */ } else { /* non-argument switch */ if (!strcmp (s,"anonymous")) mb->anoflag = T; else if (!strcmp (s,"debug")) mb->dbgflag = T; else if (!strcmp (s,"secure")) mb->secflag = T; else if (!strcmp (s,"alt")) mb->altflag = mailaltdriver ? T : NIL; else if (mailaltdriver && mailaltdrivername && !strcmp (s,mailaltdrivername)) mb->altflag = T; else if (mailaltdriver && mailaltoptionname && !strcmp (s,mailaltoptionname)) mb->altflag = mb->altopt = T; /* hack for compatibility with the past */ else if (mailaltdriver && mailaltoptionname && (mailaltoptionname[0] == 'n') && (mailaltoptionname[1] == 'o') && !strcmp (s,mailaltoptionname+2)) mb->altflag = T; /* service switches below here */ else if (*mb->service) return NIL; else if (!strncmp (s,"imap",4) && (!s[4] || !strcmp (s+4,"2") || !strcmp (s+4,"2bis") || !strcmp (s+4,"4") || !strcmp (s+4,"4rev1"))) strcpy (mb->service,"imap"); else if (!strncmp (s,"pop",3) && (!s[3] || !strcmp (s+3,"3"))) strcpy (mb->service,"pop3"); else if (!strcmp (s,"nntp") || !strcmp (s,"smtp")) strcpy (mb->service,s); else return NIL; /* invalid non-argument switch */ } break; default: /* anything else is bogus */ return NIL; } while (c); /* see if anything more to parse */ } /* default mailbox name */ if (!*mb->mailbox) strcpy (mb->mailbox,"INBOX"); /* default service name */ if (!*mb->service) strcpy (mb->service,"imap"); return T;}/* Mail scan mailboxes for string * Accepts: mail stream * reference * pattern to search * contents to search */void mail_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents){ int remote = ((*pat == '{') || (ref && *ref == '{')); DRIVER *d; if (*pat == '{') ref = NIL; /* ignore reference if pattern is remote */ if (stream) { /* if have a stream, do it for that stream */ if ((d = stream->dtb) && d->scan && !(((d->flags & DR_LOCAL) && remote))) (*d->scan) (stream,ref,pat,contents); } /* otherwise do for all DTB's */ else for (d = maildrivers; d; d = d->next) if (d->scan && !((d->flags & DR_DISABLE) || ((d->flags & DR_LOCAL) && remote))) (d->scan) (NIL,ref,pat,contents);}/* Mail list mailboxes * Accepts: mail stream * reference * pattern to search */void mail_list (MAILSTREAM *stream,char *ref,char *pat){ int remote = ((*pat == '{') || (ref && *ref == '{')); DRIVER *d = maildrivers; if (ref && (strlen (ref) > NETMAXMBX)) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LIST reference specification: %.80s",ref); mm_log (tmp,ERROR); } if (strlen (pat) > NETMAXMBX) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LIST pattern specification: %.80s",pat); mm_log (tmp,ERROR); } if (*pat == '{') ref = NIL; /* ignore reference if pattern is remote */ if (stream && stream->dtb) { /* if have a stream, do it for that stream */ if (!(((d = stream->dtb)->flags & DR_LOCAL) && remote)) (*d->list) (stream,ref,pat); } /* otherwise do for all DTB's */ else do if (!((d->flags & DR_DISABLE) || ((d->flags & DR_LOCAL) && remote))) (d->list) (NIL,ref,pat); while (d = d->next); /* until at the end */}/* Mail list subscribed mailboxes * Accepts: mail stream * pattern to search */void mail_lsub (MAILSTREAM *stream,char *ref,char *pat){ int remote = ((*pat == '{') || (ref && *ref == '{')); DRIVER *d = maildrivers; if (ref && (strlen (ref) > NETMAXMBX)) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LSUB reference specification: %.80s",ref); mm_log (tmp,ERROR); } if (strlen (pat) > NETMAXMBX) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LSUB pattern specification: %.80s",pat); mm_log (tmp,ERROR); } if (*pat == '{') ref = NIL; /* ignore reference if pattern is remote */ if (stream && stream->dtb) { /* if have a stream, do it for that stream */ if (!(((d = stream->dtb)->flags & DR_LOCAL) && remote)) (*d->lsub) (stream,ref,pat); } /* otherwise do for all DTB's */ else do if (!((d->flags & DR_DISABLE) || ((d->flags & DR_LOCAL) && remote))) (d->lsub) (NIL,ref,pat); while (d = d->next); /* until at the end */}/* Mail subscribe to mailbox * Accepts: mail stream * mailbox to add to subscription list * Returns: T on success, NIL on failure */long mail_subscribe (MAILSTREAM *stream,char *mailbox){ DRIVER *factory = mail_valid (stream,mailbox,"subscribe to mailbox"); return factory ? (factory->subscribe ? (*factory->subscribe) (stream,mailbox) : sm_subscribe (mailbox)) : NIL;}/* Mail unsubscribe to mailbox * Accepts: mail stream * mailbox to delete from subscription list * Returns: T on success, NIL on failure */long mail_unsubscribe (MAILSTREAM *stream,char *mailbox){ DRIVER *factory = mail_valid (stream,mailbox,NIL); return (factory && factory->unsubscribe) ? (*factory->unsubscribe) (stream,mailbox) : sm_unsubscribe (mailbox);}/* Mail create mailbox * Accepts: mail stream * mailbox name to create * Returns: T on success, NIL on failure */long mail_create (MAILSTREAM *stream,char *mailbox){ MAILSTREAM *ts; char *s,tmp[MAILTMPLEN]; DRIVER *d; if (strlen (mailbox) >= (NETMAXHOST+(NETMAXUSER*2)+NETMAXMBX+NETMAXSRV+50)) { sprintf (tmp,"Can't create %.80s: %s",mailbox,(*mailbox == '{') ? "invalid remote specification" : "no such mailbox"); mm_log (tmp,ERROR); return NIL; } /* create of INBOX invalid */ if (!strcmp (lcase (strcpy (tmp,mailbox)),"inbox")) { mm_log ("Can't create INBOX",ERROR); return NIL; } for (s = mailbox; *s; s++) { /* make sure valid name */ if (*s & 0x80) { /* reserved for future use with UTF-8 */ mm_log ("Can't create mailbox name with 8-bit character",ERROR); return NIL; } /* validate modified UTF-7 */ else if (*s == '&') while (*++s != '-') switch (*s) { case '\0': sprintf (tmp,"Can't create unterminated modified UTF-7 name: %.80s", mailbox); mm_log (tmp,ERROR); return NIL; default: /* must be alphanumeric */ if (!isalnum (*s)) { sprintf (tmp,"Can't create invalid modified UTF-7 name: %.80s", mailbox); mm_log (tmp,ERROR); return NIL; } case '+': /* valid modified BASE64 */ case ',': break; /* all OK so far */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -