📄 client
字号:
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,flags) && t->data) ? mail_fetch_text_return (&md,t,len) : ""; if (len) *len = t->size; if (!t->size) { /* empty body part -- mark seen anyway */ markseen (stream,mail_elt (stream,msgno),flags); return ""; } /* copy body from stringstruct offset */ if (stream->private.search.text) return stream->private.search.text + p->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 + p->offset; } SETPOS (&bs,p->offset); return mail_fetch_string_return (&md,&bs,t->size,len);}/* Mail fetch partial message text * Accepts: mail stream * message # to fetch * MIME section specifier (#.#.#...#) * offset of first designed byte or 0 to start at beginning * maximum number of bytes or 0 for all bytes * flags * Returns: T if successful, else NIL */long mail_partial_text (MAILSTREAM *stream,unsigned long msgno,char *section, unsigned long first,unsigned long last,long flags){ GETS_DATA md; PARTTEXT *p = NIL; MESSAGECACHE *elt; STRING bs; BODY *b; char tmp[MAILTMPLEN]; unsigned long i; if (!mailgets) fatal ("mail_partial_text() called without a mailgets!"); if (section && (strlen (section) > (MAILTMPLEN - 20))) return NIL; if (flags & FT_UID) { /* UID form of call */ if (msgno = mail_msgno (stream,msgno)) flags &= ~FT_UID; else return NIL; /* must get UID/msgno map first */ } elt = mail_elt (stream,msgno);/* get cache data */ flags &= ~FT_INTERNAL; /* bogus if this is set */ if (section && *section) { /* nested body text wanted? */ if (!((b = mail_body (stream,msgno,section)) && (b->type == TYPEMESSAGE) && !strcmp (b->subtype,"RFC822"))) return NIL; /* 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); } else { /* else top-level message text wanted */ p = &elt->private.msg.text; strcpy (tmp,"TEXT"); } /* initialize message data identifier */ INIT_GETS (md,stream,msgno,tmp,first,last); if (p->text.data) { /* is data already cached? */ INIT (&bs,mail_string,p->text.data,i = p->text.size); markseen (stream,elt,flags);/* mark message seen */ } else { /* else get data from driver */ if (!stream->dtb) return NIL; if (stream->dtb->msgdata) /* driver will handle this */ return (*stream->dtb->msgdata) (stream,msgno,tmp,first,last,NIL,flags); if (!(*stream->dtb->text) (stream,msgno,&bs,flags)) return NIL; if (section && *section) { /* nexted if more complex */ SETPOS (&bs,p->offset); /* offset stringstruct to data */ i = p->text.size; /* maximum size of data */ } else i = SIZE (&bs); /* just want this much */ } if (i <= first) i = first = 0;/* first byte is beyond end of text */ /* truncate as needed */ else { /* offset and truncate */ SETPOS (&bs,first + GETPOS (&bs)); i -= first; /* reduced size */ if (last && (i > last)) i = last; } /* do the mailgets thing */ (*mailgets) (mail_read,&bs,i,&md); return T; /* success */}/* Mail fetch partial message body part * Accepts: mail stream * message # to fetch * MIME section specifier (#.#.#...#) * offset of first designed byte or 0 to start at beginning * maximum number of bytes or 0 for all bytes * flags * Returns: T if successful, else NIL */long mail_partial_body (MAILSTREAM *stream,unsigned long msgno,char *section, unsigned long first,unsigned long last,long flags){ GETS_DATA md; PARTTEXT *p; STRING bs; BODY *b; SIZEDTEXT *t; unsigned long i; if (!(section && *section)) /* top-level text wanted? */ return mail_partial_text (stream,msgno,NIL,first,last,flags); if (!mailgets) fatal ("mail_partial_body() called without a mailgets!"); if (flags & FT_UID) { /* UID form of call */ if (msgno = mail_msgno (stream,msgno)) flags &= ~FT_UID; else return NIL; /* must get UID/msgno map first */ } /* must have body */ if (!(b = mail_body (stream,msgno,section))) return NIL; flags &= ~FT_INTERNAL; /* bogus if this is set */ /* initialize message data identifier */ INIT_GETS (md,stream,msgno,section,first,last); /* have cached text? */ if ((t = &(p = &b->contents)->text)->data) { /* mark message seen */ markseen (stream,mail_elt (stream,msgno),flags); INIT (&bs,mail_string,t->data,i = t->size); } else { /* else get data from driver */ if (!stream->dtb) return NIL; if (stream->dtb->msgdata) /* driver will handle this */ return (*stream->dtb->msgdata) (stream,msgno,section,first,last,NIL, flags); if (!(*stream->dtb->text) (stream,msgno,&bs,flags)) return NIL; if (section && *section) { /* nexted if more complex */ SETPOS (&bs,p->offset); /* offset stringstruct to data */ i = t->size; /* maximum size of data */ } else i = SIZE (&bs); /* just want this much */ } if (i <= first) i = first = 0;/* first byte is beyond end of text */ else { /* offset and truncate */ SETPOS (&bs,first + GETPOS (&bs)); i -= first; /* reduced size */ if (last && (i > last)) i = last; } /* do the mailgets thing */ (*mailgets) (mail_read,&bs,i,&md); return T; /* success */}/* Mail return message text * Accepts: identifier data * sized text * pointer to returned length * Returns: text */char *mail_fetch_text_return (GETS_DATA *md,SIZEDTEXT *t,unsigned long *len){ STRING bs; if (len) *len = t->size; /* return size */ if (t->size && mailgets) { /* have to do the mailgets thing? */ /* silly but do it anyway for consistency */ INIT (&bs,mail_string,t->data,t->size); return (*mailgets) (mail_read,&bs,t->size,md); } return t->size ? (char *) t->data : "";}/* Mail return message string * Accepts: identifier data * stringstruct * text length * pointer to returned length * Returns: text */char *mail_fetch_string_return (GETS_DATA *md,STRING *bs,unsigned long i, unsigned long *len){ if (len) *len = i; /* return size */ /* have to do the mailgets thing? */ if (mailgets) return (*mailgets) (mail_read,bs,i,md); /* special hack to avoid extra copy */ if (bs->dtb->next == mail_string_next) return bs->curpos; /* make string copy in memory */ return textcpyoffstring (&md->stream->text,bs,GETPOS (bs),i);}/* Read data from stringstruct * Accepts: stringstruct * size of data to read * buffer to read into * Returns: T, always, stringstruct updated */long mail_read (void *stream,unsigned long size,char *buffer){ STRING *s = (STRING *) stream; while (size--) *buffer++ = SNX (s); return T;}/* Mail fetch UID * Accepts: mail stream * message number * Returns: UID or zero if dead stream */unsigned long mail_uid (MAILSTREAM *stream,unsigned long msgno){ unsigned long uid = mail_elt (stream,msgno)->private.uid; return uid ? uid : (stream->dtb && stream->dtb->uid) ? (*stream->dtb->uid) (stream,msgno) : 0;}/* Mail fetch msgno from UID (for internal use only) * Accepts: mail stream * UID * Returns: msgno or zero if failed */unsigned long mail_msgno (MAILSTREAM *stream,unsigned long uid){ unsigned long msgno; /* scan cache for UID */ for (msgno = 1; msgno <= stream->nmsgs; msgno++) if (mail_elt (stream,msgno)->private.uid == uid) return msgno; if (stream->dtb) { /* else get it from driver if possible */ /* direct way */ if (stream->dtb->msgno) return (*stream->dtb->msgno) (stream,uid); if (stream->dtb->uid) /* indirect way */ for (msgno = 1; msgno <= stream->nmsgs; msgno++) if ((*stream->dtb->uid) (stream,msgno) == uid) return msgno; } return 0; /* didn't find the UID anywhere */}/* Mail fetch From string for menu * Accepts: destination string * mail stream * message # to fetch * desired string length * Returns: string of requested length */void mail_fetchfrom (char *s,MAILSTREAM *stream,unsigned long msgno, long length){ char *t; char tmp[MAILTMPLEN]; ENVELOPE *env = mail_fetchenvelope (stream,msgno); ADDRESS *adr = env ? env->from : NIL; memset (s,' ',(size_t)length);/* fill it with spaces */ s[length] = '\0'; /* tie off with null */ /* get first from address from envelope */ while (adr && !adr->host) adr = adr->next; if (adr) { /* if a personal name exists use it */ if (!(t = adr->personal)) sprintf (t = tmp,"%.256s@%.256s",adr->mailbox,adr->host); memcpy (s,t,(size_t) min (length,(long) strlen (t))); }}/* Mail fetch Subject string for menu * Accepts: destination string * mail stream * message # to fetch * desired string length * Returns: string of no more than requested length */void mail_fetchsubject (char *s,MAILSTREAM *stream,unsigned long msgno, long length){ ENVELOPE *env = mail_fetchenvelope (stream,msgno); memset (s,'\0',(size_t) length+1); /* copy subject from envelope */ if (env && env->subject) strncpy (s,env->subject,(size_t) length); else *s = ' '; /* if no subject then just a space */}/* Mail modify flags * Accepts: mail stream * sequence * flag(s) * option flags */void mail_flag (MAILSTREAM *stream,char *sequence,char *flag,long flags){ MESSAGECACHE *elt; unsigned long i,uf; long f; short nf; if (!stream->dtb) return; /* no-op if no stream */ if ((stream->dtb->flagmsg || !stream->dtb->flag) && ((f = mail_parse_flags (stream,flag,&uf)) || uf) && ((flags & ST_UID) ? mail_uid_sequence (stream,sequence) : mail_sequence (stream,sequence))) for (i = 1,nf = (flags & ST_SET) ? T : NIL; i <= stream->nmsgs; i++) if ((elt = mail_elt (stream,i))->sequence) { struct { /* old flags */ unsigned int valid : 1; unsigned int seen : 1; unsigned int deleted : 1; unsigned int flagged : 1; unsigned int answered : 1; unsigned int draft : 1; unsigned long user_flags; } old; old.valid = elt->valid; old.seen = elt->seen; old.deleted = elt->deleted; old.flagged = elt->flagged; old.answered = elt->answered; old.draft = elt->draft; old.user_flags = elt->user_flags; elt->valid = NIL; /* prepare for flag alteration */ if (stream->dtb->flagmsg) (*stream->dtb->flagmsg) (stream,elt); if (f&fSEEN) elt->seen = nf; if (f&fDELETED) elt->deleted = nf; if (f&fFLAGGED) elt->flagged = nf; if (f&fANSWERED) elt->answered = nf; if (f&fDRAFT) elt->draft = nf; /* user flags */ if (flags & ST_SET) elt->user_flags |= uf; else elt->user_flags &= ~uf; elt->valid = T; /* flags now altered */ if ((old.valid != elt->valid) || (old.seen != elt->seen) || (old.deleted != elt->deleted) || (old.flagged != elt->flagged) || (old.answered != elt->answered) || (old.draft != elt->draft) || (old.user_flags != elt->user_flags)) mm_flags(stream,elt->msgno); if (stream->dtb->flagmsg) (*stream->dtb->flagmsg) (stream,elt); } /* call driver once */ if (stream->dtb->flag) (*stream->dtb->flag) (stream,sequence,flag,flags);}/* Mail search for messages * Accepts: mail stream * character set * search program * option flags */void mail_search_full (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm, long flags){ unsigned long i; if (!(flags & SE_RETAIN)) /* clear search vector unless retaining */ for (i = 1; i <= stream->nmsgs; ++i) mail_elt (stream,i)->searched = NIL; if (pgm && stream->dtb) { /* must have a search program and driver */ /* do the driver's action if requested */ if (!(flags & SO_NOSERVER) && stream->dtb->search) (*stream->dtb->search) (stream,charset,pgm,flags); else mail_search_default (stream,charset,pgm,flags); } /* flush search program if requested */ if (flags & SE_FREE) mail_free_searchpgm (&pgm);}/* Mail search for messages default handler * Accepts: mail stream * character set * search program * option flags */void mail_search_default (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm, long flags){ unsigned long i; if (charset && *charset && /* convert if charset not US-ASCII or UTF-8 */ !(((charset[0] == 'U') || (charset[0] == 'u')) && ((((charset[1] == 'S') || (charset[1] == 's')) && (charset[2] == '-') && ((charset[3] == 'A') || (charset[3] == 'a')) && ((charset[4] == 'S') || (charset[4] == 's')) && ((charset[5] == 'C') || (charset[5] == 'c')) && ((charset[6] == 'I') || (charset[6] == 'i')) && ((charset[7] == 'I') || (charset[7] == 'i')) && !charset[8]) || (((charset[1] == 'T') || (charset[1] == 't')) && ((charset[2] == 'F') || (charset[2] == 'f')) && (charset[3] == '-') && (charset[4] == '8') && !charset[5])))) { if (utf8_text (NIL,charset,NIL,T)) utf8_searchpgm (pgm,charset); else return; /* charset unknown */ } for (i = 1; i <= stream->nmsgs; +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -