⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mail.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
    else {			/* can save memory doing it this way */      hdr = (*stream->dtb->header) (stream,msgno,&hdrsize,flags | FT_INTERNAL);      if (hdrsize) {		/* in case null header */	c = hdr[hdrsize];	/* preserve what's there */	hdr[hdrsize] = '\0';	/* tie off header */	rfc822_parse_msg (env,NIL,hdr,hdrsize,NIL,BADHOST,stream->dtb->flags);	hdr[hdrsize] = c;	/* restore in case cached data */      }      else *env = mail_newenvelope ();    }  }				/* if need date, have date in envelope? */  if (!elt->day && *env && (*env)->date) mail_parse_date (elt,(*env)->date);				/* sigh, fill in bogus default */  if (!elt->day) elt->day = elt->month = 1;  if (body) *body = *b;		/* return the body */  return *env;			/* return the envelope */}/* Mail mark single message (internal use only) * Accepts: mail stream *	    elt to mark *	    fetch flags */static void markseen (MAILSTREAM *stream,MESSAGECACHE *elt,long flags){  unsigned long i;  char sequence[20];  MESSAGECACHE *e;				/* non-peeking and needs to set \Seen? */  if (!(flags & FT_PEEK) && !elt->seen) {    if (stream->dtb->flagmsg){	/* driver wants per-message call? */      elt->valid = NIL;		/* do pre-alteration driver call */      (*stream->dtb->flagmsg) (stream,elt);				/* set seen, do post-alteration driver call */      elt->seen = elt->valid = T;      (*stream->dtb->flagmsg) (stream,elt);    }    if (stream->dtb->flag) {	/* driver wants one-time call?  */				/* better safe than sorry, save seq bits */      for (i = 1; i <= stream->nmsgs; i++) {	e = mail_elt (stream,i);	e->private.sequence = e->sequence;      }				/* call driver to set the message */      sprintf (sequence,"%lu",elt->msgno);      (*stream->dtb->flag) (stream,sequence,"\\Seen",ST_SET);				/* restore sequence bits */      for (i = 1; i <= stream->nmsgs; i++) {	e = mail_elt (stream,i);	e->sequence = e->private.sequence;      }    }				/* notify mail program of flag change */    MM_FLAGS (stream,elt->msgno);  }}/* Mail fetch message * Accepts: mail stream *	    message # to fetch *	    pointer to returned length *	    flags * Returns: message text */char *mail_fetch_message (MAILSTREAM *stream,unsigned long msgno,			  unsigned long *len,long flags){  GETS_DATA md;  SIZEDTEXT *t;  STRING bs;  MESSAGECACHE *elt;  char *s,*u;  unsigned long i,j;  if (len) *len = 0;		/* default return size */  if (flags & FT_UID) {		/* UID form of call */    if (msgno = mail_msgno (stream,msgno)) flags &= ~FT_UID;    else return "";		/* must get UID/msgno map first */  }				/* initialize message data identifier */  INIT_GETS (md,stream,msgno,"",0,0);				/* is data already cached? */  if ((t = &(elt = mail_elt (stream,msgno))->private.msg.full.text)->data) {    markseen (stream,elt,flags);/* mark message seen */    return mail_fetch_text_return (&md,t,len);  }  if (!stream->dtb) return "";	/* not in cache, must have live driver */  if (stream->dtb->msgdata) return    ((*stream->dtb->msgdata) (stream,msgno,"",0,0,NIL,flags) && t->data) ?      mail_fetch_text_return (&md,t,len) : "";				/* ugh, have to do this the crufty way */  u = mail_fetch_header (stream,msgno,NIL,NIL,&i,flags);				/* copy in case text method stomps on it */  s = (char *) memcpy (fs_get ((size_t) i),u,(size_t) i);  if ((*stream->dtb->text) (stream,msgno,&bs,flags)) {    t = &stream->text;		/* build combined copy */    if (t->data) fs_give ((void **) &t->data);    t->data = (unsigned char *) fs_get ((t->size = i + SIZE (&bs)) + 1);    if (!elt->rfc822_size) elt->rfc822_size = t->size;    else if (elt->rfc822_size != t->size) {      char tmp[MAILTMPLEN];      sprintf (tmp,"Calculated RFC822.SIZE (%lu) != reported size (%lu)",	       t->size,elt->rfc822_size);      mm_log (tmp,WARN);	/* bug trap */    }    memcpy (t->data,s,(size_t) i);    for (u = (char *) t->data + i, j = SIZE (&bs); j;) {      memcpy (u,bs.curpos,bs.cursize);      u += bs.cursize;		/* update text */      j -= bs.cursize;      bs.curpos += (bs.cursize -1);      bs.cursize = 0;      (*bs.dtb->next) (&bs);	/* advance to next buffer's worth */    }     *u = '\0';			/* tie off data */    u = mail_fetch_text_return (&md,t,len);  }  else u = "";  fs_give ((void **) &s);	/* finished with copy of header */  return u;}/* Mail fetch message header * Accepts: mail stream *	    message # to fetch *	    MIME section specifier (#.#.#...#) *	    list of lines to fetch *	    pointer to returned length *	    flags * Returns: message header in RFC822 format * * Note: never calls a mailgets routine */char *mail_fetch_header (MAILSTREAM *stream,unsigned long msgno,char *section,			 STRINGLIST *lines,unsigned long *len,long flags){  STRING bs;  BODY *b = NIL;  SIZEDTEXT *t = NIL,rt;  MESSAGE *m = NIL;  MESSAGECACHE *elt;  char tmp[MAILTMPLEN];  if (len) *len = 0;		/* default return size */  if (section && (strlen (section) > (MAILTMPLEN - 20))) return "";  if (flags & FT_UID) {		/* UID form of call */    if (msgno = mail_msgno (stream,msgno)) flags &= ~FT_UID;    else return "";		/* must get UID/msgno map first */  }  elt = mail_elt (stream,msgno);/* get cache data */  if (section && *section) {	/* nested body header wanted? */    if (!((b = mail_body (stream,msgno,section)) &&	  (b->type == TYPEMESSAGE) && !strcmp (b->subtype,"RFC822")))      return "";		/* lose if no body or not MESSAGE/RFC822 */    m = b->nested.msg;		/* point to nested message */  }				/* else top-level message header wanted */  else m = &elt->private.msg;  if (m->header.text.data && mail_match_lines (lines,m->lines,flags)) {    if (lines) textcpy (t = &stream->text,&m->header.text);    else t = &m->header.text;	/* in cache, and cache is valid */    markseen (stream,elt,flags);/* mark message seen */  }  else if (stream->dtb) {	/* not in cache, has live driver? */    if (stream->dtb->msgdata) {	/* has driver section fetch? */				/* build driver section specifier */      if (section && *section) sprintf (tmp,"%s.HEADER",section);      else strcpy (tmp,"HEADER");      if ((*stream->dtb->msgdata) (stream,msgno,tmp,0,0,lines,flags)) {	t = &m->header.text;	/* fetch data */				/* don't need to postprocess lines */	if (m->lines) lines = NIL;	else if (lines) textcpy (t = &stream->text,&m->header.text);      }    }    else if (b) {		/* nested body wanted? */      if (stream->private.search.text) {	rt.data = (unsigned char *) stream->private.search.text +	  b->nested.msg->header.offset;	rt.size = b->nested.msg->header.text.size;	t = &rt;      }      else if ((*stream->dtb->text) (stream,msgno,&bs,flags & ~FT_INTERNAL)) {	if ((bs.dtb->next == mail_string_next) && !lines) {	  rt.data = (unsigned char *) bs.curpos + b->nested.msg->header.offset;	  rt.size = b->nested.msg->header.text.size;	  if (stream->private.search.string)	    stream->private.search.text = bs.curpos;	  t = &rt;		/* special hack to avoid extra copy */	}	else textcpyoffstring (t = &stream->text,&bs,			       b->nested.msg->header.offset,			       b->nested.msg->header.text.size);      }    }    else {			/* top-level header fetch */				/* mark message seen */      markseen (stream,elt,flags);      if (rt.data = (unsigned char *)	  (*stream->dtb->header) (stream,msgno,&rt.size,flags)) {				/* make a safe copy if need to filter */	if (lines) textcpy (t = &stream->text,&rt);	else t = &rt;		/* top level header */      }    }  }  if (!t || !t->data) return "";/* error if no string */				/* filter headers if requested */  if (lines) t->size = mail_filter ((char *) t->data,t->size,lines,flags);  if (len) *len = t->size;	/* return size if requested */  return (char *) t->data;	/* and text */}/* Mail fetch message text * Accepts: mail stream *	    message # to fetch *	    MIME section specifier (#.#.#...#) *	    pointer to returned length *	    flags * Returns: message text */char *mail_fetch_text (MAILSTREAM *stream,unsigned long msgno,char *section,		       unsigned long *len,long flags){  GETS_DATA md;  PARTTEXT *p;  STRING bs;  MESSAGECACHE *elt;  BODY *b = NIL;  char tmp[MAILTMPLEN];  unsigned long i;  if (len) *len = 0;		/* default return size */  memset (&stream->private.string,NIL,sizeof (STRING));  if (section && (strlen (section) > (MAILTMPLEN - 20))) return "";  if (flags & FT_UID) {		/* UID form of call */    if (msgno = mail_msgno (stream,msgno)) flags &= ~FT_UID;    else return "";		/* must get UID/msgno map first */  }  elt = mail_elt (stream,msgno);/* get cache data */  if (section && *section) {	/* nested body text wanted? */    if (!((b = mail_body (stream,msgno,section)) &&	  (b->type == TYPEMESSAGE) && !strcmp (b->subtype,"RFC822")))      return "";		/* lose if no body or not MESSAGE/RFC822 */    p = &b->nested.msg->text;	/* point at nested message */				/* build IMAP-format section specifier */    sprintf (tmp,"%s.TEXT",section);    flags &= ~FT_INTERNAL;	/* can't win with this set */  }  else {			/* top-level message text wanted */    p = &elt->private.msg.text;    strcpy (tmp,"TEXT");  }				/* initialize message data identifier */  INIT_GETS (md,stream,msgno,section,0,0);  if (p->text.data) {		/* is data already cached? */    markseen (stream,elt,flags);/* mark message seen */    return mail_fetch_text_return (&md,&p->text,len);  }  if (!stream->dtb) return "";	/* not in cache, must have live driver */  if (stream->dtb->msgdata) return    ((*stream->dtb->msgdata) (stream,msgno,tmp,0,0,NIL,flags) && p->text.data)?      mail_fetch_text_return (&md,&p->text,len) : "";  if (!(*stream->dtb->text) (stream,msgno,&bs,flags)) return "";  if (section && *section) {	/* nested is more complex */    SETPOS (&bs,p->offset);    i = p->text.size;		/* just want this much */  }  else i = SIZE (&bs);		/* want entire text */  return mail_fetch_string_return (&md,&bs,i,len,flags);}/* Mail fetch message body part MIME headers * Accepts: mail stream *	    message # to fetch *	    MIME section specifier (#.#.#...#) *	    pointer to returned length *	    flags * Returns: message text */char *mail_fetch_mime (MAILSTREAM *stream,unsigned long msgno,char *section,		       unsigned long *len,long flags){  PARTTEXT *p;  STRING bs;  BODY *b;  char tmp[MAILTMPLEN];  if (len) *len = 0;		/* default return size */  if (section && (strlen (section) > (MAILTMPLEN - 20))) return "";  if (flags & FT_UID) {		/* UID form of call */    if (msgno = mail_msgno (stream,msgno)) flags &= ~FT_UID;    else return "";		/* must get UID/msgno map first */  }  flags &= ~FT_INTERNAL;	/* can't win with this set */  if (!(section && *section && (b = mail_body (stream,msgno,section))))    return "";			/* not valid section */				/* in cache? */  if ((p = &b->mime)->text.data) {				/* mark message seen */    markseen (stream,mail_elt (stream,msgno),flags);    if (len) *len = p->text.size;    return (char *) p->text.data;  }  if (!stream->dtb) return "";	/* not in cache, must have live driver */  if (stream->dtb->msgdata) {	/* has driver fetch? */				/* build driver section specifier */    sprintf (tmp,"%s.MIME",section);    if ((*stream->dtb->msgdata) (stream,msgno,tmp,0,0,NIL,flags) &&	p->text.data) {      if (len) *len = p->text.size;      return (char *) p->text.data;    }    else return "";  }  if (len) *len = b->mime.text.size;  if (!b->mime.text.size) {	/* empty MIME header -- mark seen anyway */    markseen (stream,mail_elt (stream,msgno),flags);    return "";  }				/* have to get it from offset */  if (stream->private.search.text)    return stream->private.search.text + b->mime.offset;  if (!(*stream->dtb->text) (stream,msgno,&bs,flags)) {    if (len) *len = 0;    return "";  }  if (bs.dtb->next == mail_string_next) {    if (stream->private.search.string) stream->private.search.text = bs.curpos;    return bs.curpos + b->mime.offset;  }  return textcpyoffstring (&stream->text,&bs,b->mime.offset,b->mime.text.size);}/* Mail fetch message body part * Accepts: mail stream *	    message # to fetch *	    MIME section specifier (#.#.#...#) *	    pointer to returned length *	    flags * Returns: message body */char *mail_fetch_body (MAILSTREAM *stream,unsigned long msgno,char *section,		       unsigned long *len,long flags){  GETS_DATA md;  PARTTEXT *p;  STRING bs;  BODY *b;  SIZEDTEXT *t;  char *s,tmp[MAILTMPLEN];  memset (&stream->private.string,NIL,sizeof (STRING));  if (!(section && *section))	/* top-level text wanted? */    return mail_fetch_message (stream,msgno,len,flags);  else if (strlen (section) > (MAILTMPLEN - 20)) return "";  flags &= ~FT_INTERNAL;	/* can't win with this set */				/* initialize message data identifier */  INIT_GETS (md,stream,msgno,section,0,0);				/* kludge for old section 0 header */  if (!strcmp (s = strcpy (tmp,section),"0") ||      ((s = strstr (tmp,".0")) && !s[2])) {    SIZEDTEXT ht;    *s = '\0';			/* tie off section */				/* this silly way so it does mailgets */    ht.data = (unsigned char *) mail_fetch_header (stream,msgno,						   tmp[0] ? tmp : NIL,NIL,						   &ht.size,flags);				/* may have UIDs here */    md.flags = (flags & FT_UID) ? MG_UID : NIL;    return mail_fetch_text_return (&md,&ht,len);  }  if (len) *len = 0;		/* default return size */  if (flags & FT_UID) {		/* UID form of call */    if (msgno = mail_msgno (stream,msgno)) flags &= ~FT_UID;    else return "";		/* must get UID/msgno map first */  }				/* must have body */  if (!(b = mail_body (stream,msgno,section))) return "";				/* have cached text? */  if ((t = &(p = &b->contents)->text)->data) {				/* mark message seen */    markseen (stream,mail_elt (stream,msgno),flags);    return mail_fetch_text_return (&md,t,len);  }  if (!stream->dtb) return "";	/* not in cache, must have live driver */  if (stream->dtb->msgdata) return    ((*stream->dtb->msgdata)(stream,msgno,section,0,0,NIL,flag

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -