📄 mail.c
字号:
i = strlen (v); /* length of argument */ } if (!compare_cstring (s,"service") && (i < NETMAXSRV) && !*mb->service) lcase (strcpy (mb->service,v)); else if (!compare_cstring (s,"user") && (i < NETMAXUSER) && !*mb->user) strcpy (mb->user,v); else if (!compare_cstring (s,"authuser") && (i < NETMAXUSER) && !*mb->authuser) strcpy (mb->authuser,v); else return NIL; } else { /* non-argument switch */ if (!compare_cstring (s,"anonymous")) mb->anoflag = T; else if (!compare_cstring (s,"debug")) mb->dbgflag = T; else if (!compare_cstring (s,"readonly")) mb->readonlyflag = T; else if (!compare_cstring (s,"secure")) mb->secflag = T; else if (!compare_cstring (s,"norsh")) mb->norsh = T; else if (!compare_cstring (s,"loser")) mb->loser = T; else if (!compare_cstring (s,"tls") && !mb->notlsflag) mb->tlsflag = T; else if (!compare_cstring (s,"tls-sslv23") && !mb->notlsflag) mb->tlssslv23 = mb->tlsflag = T; else if (!compare_cstring (s,"notls") && !mb->tlsflag) mb->notlsflag = T; else if (!compare_cstring (s,"tryssl")) mb->trysslflag = mailssldriver? T : NIL; else if (mailssldriver && !compare_cstring (s,"ssl") && !mb->tlsflag) mb->sslflag = mb->notlsflag = T; else if (mailssldriver && !compare_cstring (s,"novalidate-cert")) mb->novalidate = T; /* hack for compatibility with the past */ else if (mailssldriver && !compare_cstring (s,"validate-cert")); /* service switches below here */ else if (*mb->service) return NIL; else if (!compare_cstring (s,"imap") || !compare_cstring (s,"nntp") || !compare_cstring (s,"pop3") || !compare_cstring (s,"smtp") || !compare_cstring (s,"submit")) lcase (strcpy (mb->service,s)); else if (!compare_cstring (s,"imap2") || !compare_cstring (s,"imap2bis") || !compare_cstring (s,"imap4") || !compare_cstring (s,"imap4rev1")) strcpy (mb->service,"imap"); else if (!compare_cstring (s,"pop")) strcpy (mb->service,"pop3"); 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,service); /* /norsh only valid if imap */ if (mb->norsh && strcmp (mb->service,"imap")) return NIL; 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 (ref && (strlen (ref) > NETMAXMBX)) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LIST reference specification: %.80s",ref); MM_LOG (tmp,ERROR); return; } if (strlen (pat) > NETMAXMBX) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LIST pattern specification: %.80s",pat); MM_LOG (tmp,ERROR); return; } 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); return; } if (strlen (pat) > NETMAXMBX) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LIST pattern specification: %.80s",pat); MM_LOG (tmp,ERROR); return; } 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); return; } if (strlen (pat) > NETMAXMBX) { char tmp[MAILTMPLEN]; sprintf (tmp,"Invalid LSUB pattern specification: %.80s",pat); MM_LOG (tmp,ERROR); return; } 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,*t,tmp[MAILTMPLEN]; size_t i; DRIVER *d; /* never allow names with newlines */ if (s = strpbrk (mailbox,"\015\012")) { MM_LOG ("Can't create mailbox with such a name",ERROR); return NIL; } 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 (!compare_cstring (mailbox,"INBOX")) { MM_LOG ("Can't create INBOX",ERROR); return NIL; } /* validate name */ if (s = mail_utf7_valid (mailbox)) { sprintf (tmp,"Can't create %s: %.80s",s,mailbox); MM_LOG (tmp,ERROR); return NIL; } /* see if special driver hack */ if ((mailbox[0] == '#') && ((mailbox[1] == 'd') || (mailbox[1] == 'D')) && ((mailbox[2] == 'r') || (mailbox[2] == 'R')) && ((mailbox[3] == 'i') || (mailbox[3] == 'I')) && ((mailbox[4] == 'v') || (mailbox[4] == 'V')) && ((mailbox[5] == 'e') || (mailbox[5] == 'E')) && ((mailbox[6] == 'r') || (mailbox[6] == 'R')) && (mailbox[7] == '.')) { /* copy driver until likely delimiter */ if ((s = strpbrk (t = mailbox+8,"/\\:")) && (i = s - t)) { strncpy (tmp,t,i); tmp[i] = '\0'; } else { sprintf (tmp,"Can't create mailbox %.80s: bad driver syntax",mailbox); MM_LOG (tmp,ERROR); return NIL; } for (d = maildrivers; d && strcmp (d->name,tmp); d = d->next); if (d) mailbox = ++s; /* skip past driver specification */ else { sprintf (tmp,"Can't create mailbox %.80s: unknown driver",mailbox); MM_LOG (tmp,ERROR); return NIL; } } /* use stream if one given or deterministic */ else if ((stream && stream->dtb) || (((*mailbox == '{') || (*mailbox == '#')) && (stream = mail_open (NIL,mailbox,OP_PROTOTYPE | OP_SILENT)))) d = stream->dtb; else if ((*mailbox != '{') && (ts = default_proto (NIL))) d = ts->dtb; else { /* failed utterly */ sprintf (tmp,"Can't create mailbox %.80s: indeterminate format",mailbox); MM_LOG (tmp,ERROR); return NIL; } return (*d->create) (stream,mailbox);}/* Mail delete mailbox * Accepts: mail stream * mailbox name to delete * Returns: T on success, NIL on failure */long mail_delete (MAILSTREAM *stream,char *mailbox){ DRIVER *dtb = mail_valid (stream,mailbox,"delete mailbox"); if (!dtb) return NIL; if (((mailbox[0] == 'I') || (mailbox[0] == 'i')) && ((mailbox[1] == 'N') || (mailbox[1] == 'n')) && ((mailbox[2] == 'B') || (mailbox[2] == 'b')) && ((mailbox[3] == 'O') || (mailbox[3] == 'o')) && ((mailbox[4] == 'X') || (mailbox[4] == 'x')) && !mailbox[5]) { MM_LOG ("Can't delete INBOX",ERROR); return NIL; } return SAFE_DELETE (dtb,stream,mailbox);}/* Mail rename mailbox * Accepts: mail stream * old mailbox name * new mailbox name * Returns: T on success, NIL on failure */long mail_rename (MAILSTREAM *stream,char *old,char *newname){ char *s,tmp[MAILTMPLEN]; DRIVER *dtb = mail_valid (stream,old,"rename mailbox"); if (!dtb) return NIL; /* validate name */ if (s = mail_utf7_valid (newname)) { sprintf (tmp,"Can't rename to %s: %.80s",s,newname); MM_LOG (tmp,ERROR); return NIL; } if ((*old != '{') && (*old != '#') && mail_valid (NIL,newname,NIL)) { sprintf (tmp,"Can't rename %.80s: mailbox %.80s already exists", old,newname); MM_LOG (tmp,ERROR); return NIL; } return SAFE_RENAME (dtb,stream,old,newname);}/* Validate mailbox as Modified UTF-7 * Accepts: candidate mailbox name * Returns: error string if error, NIL if valid */char *mail_utf7_valid (char *mailbox){ char *s; for (s = mailbox; *s; s++) { /* make sure valid name */ /* reserved for future use with UTF-8 */ if (*s & 0x80) return "mailbox name with 8-bit octet"; /* validate modified UTF-7 */ else if (*s == '&') while (*++s != '-') switch (*s) { case '\0': return "unterminated modified UTF-7 name"; case '+': /* valid modified BASE64 */ case ',': break; /* all OK so far */ default: /* must be alphanumeric */ if (!isalnum (*s)) return "invalid modified UTF-7 name"; break; } } return NIL; /* all OK */}/* Mail status of mailbox * Accepts: mail stream if open on this mailbox * mailbox name * status flags * Returns: T on success, NIL on failure */long mail_status (MAILSTREAM *stream,char *mbx,long flags){ DRIVER *dtb = mail_valid (stream,mbx,"get status of mailbox"); if (!dtb) return NIL; /* only if valid */ if (stream && ((dtb != stream->dtb) || ((dtb->flags & DR_LOCAL) && strcmp (mbx,stream->mailbox) && strcmp (mbx,stream->original_mailbox)))) stream = NIL; /* stream not suitable */ return SAFE_STATUS (dtb,stream,mbx,flags);}/* Mail status of mailbox default handler * Accepts: mail stream * mailbox name * status flags * Returns: T on success, NIL on failure */long mail_status_default (MAILSTREAM *stream,char *mbx,long flags){ MAILSTATUS status; unsigned long i; MAILSTREAM *tstream = NIL; /* make temporary stream (unless this mbx) */ if (!stream && !(stream = tstream = mail_open (NIL,mbx,OP_READONLY|OP_SILENT))) return NIL; status.flags = flags; /* return status values */ status.messages = stream->nmsgs; status.recent = stream->recent; if (flags & SA_UNSEEN) /* must search to get unseen messages */ for (i = 1,status.unseen = 0; i <= stream->nmsgs; i++) if (!mail_elt (stream,i)->seen) status.unseen++; status.uidnext = stream->uid_last + 1; status.uidvalidity = stream->uid_validity; MM_STATUS(stream,mbx,&status);/* pass status to main program */ if (tstream) mail_close (tstream); return T; /* success */}/* Mail open * Accepts: candidate stream for recycling * mailbox name * open options
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -