📄 news.c
字号:
for (i = 1,status.unseen = 0; i <= stream->nmsgs; i++) if (!mail_elt (stream,i)->deleted) status.unseen++; status.uidnext = stream->uid_last + 1; status.uidvalidity = stream->uid_validity; /* pass status to main program */ mm_status (stream,mbx,&status); if (tstream) mail_close (tstream); return T; /* success */}/* News open * Accepts: stream to open * Returns: stream on success, NIL on failure */MAILSTREAM *news_open (MAILSTREAM *stream){ long i,nmsgs; char *s,tmp[MAILTMPLEN]; struct direct **names; /* return prototype for OP_PROTOTYPE call */ if (!stream) return &newsproto; if (stream->local) fatal ("news recycle stream"); /* build directory name */ sprintf (s = tmp,"%s/%s",(char *) mail_parameters (NIL,GET_NEWSSPOOL,NIL), stream->mailbox + 6); while (s = strchr (s,'.')) *s = '/'; /* scan directory */ if ((nmsgs = scandir (tmp,&names,news_select,news_numsort)) >= 0) { mail_exists (stream,nmsgs); /* notify upper level that messages exist */ stream->local = fs_get (sizeof (NEWSLOCAL)); LOCAL->dirty = NIL; /* no update to .newsrc needed yet */ LOCAL->dir = cpystr (tmp); /* copy directory name for later */ /* make temporary buffer */ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = MAXMESSAGESIZE) + 1); LOCAL->name = cpystr (stream->mailbox + 6); for (i = 0; i < nmsgs; ++i) { stream->uid_last = mail_elt (stream,i+1)->private.uid = atoi (names[i]->d_name); fs_give ((void **) &names[i]); } s = (void *) names; /* stupid language */ fs_give ((void **) &s); /* free directory */ LOCAL->cachedtexts = 0; /* no cached texts */ stream->sequence++; /* bump sequence number */ stream->rdonly = stream->perm_deleted = T; /* UIDs are always valid */ stream->uid_validity = 0xbeefface; /* read .newsrc entries */ mail_recent (stream,newsrc_read (LOCAL->name,stream)); /* notify if empty newsgroup */ if (!(stream->nmsgs || stream->silent)) { sprintf (tmp,"Newsgroup %s is empty",LOCAL->name); mm_log (tmp,WARN); } } else mm_log ("Unable to scan newsgroup spool directory",ERROR); return LOCAL ? stream : NIL; /* if stream is alive, return to caller */}/* News file name selection test * Accepts: candidate directory entry * Returns: T to use file name, NIL to skip it */int news_select (struct direct *name){ char c; char *s = name->d_name; while (c = *s++) if (!isdigit (c)) return NIL; return T;}/* News file name comparision * Accepts: first candidate directory entry * second candidate directory entry * Returns: negative if d1 < d2, 0 if d1 == d2, postive if d1 > d2 */int news_numsort (const void *d1,const void *d2){ return atoi ((*(struct direct **) d1)->d_name) - atoi ((*(struct direct **) d2)->d_name);}/* News close * Accepts: MAIL stream * option flags */void news_close (MAILSTREAM *stream,long options){ if (LOCAL) { /* only if a file is open */ news_check (stream); /* dump final checkpoint */ if (LOCAL->dir) fs_give ((void **) &LOCAL->dir); /* free local scratch buffer */ if (LOCAL->buf) fs_give ((void **) &LOCAL->buf); if (LOCAL->name) fs_give ((void **) &LOCAL->name); /* nuke the local data */ fs_give ((void **) &stream->local); stream->dtb = NIL; /* log out the DTB */ }}/* News fetch fast information * Accepts: MAIL stream * sequence * option flags */void news_fast (MAILSTREAM *stream,char *sequence,long flags){ unsigned long i,j; /* ugly and slow */ if (stream && LOCAL && ((flags & FT_UID) ? mail_uid_sequence (stream,sequence) : mail_sequence (stream,sequence))) for (i = 1; i <= stream->nmsgs; i++) if (mail_elt (stream,i)->sequence) news_header (stream,i,&j,NIL);}/* News fetch flags * Accepts: MAIL stream * sequence * option flags */void news_flags (MAILSTREAM *stream,char *sequence,long flags){ unsigned long i; if ((flags & FT_UID) ? /* validate all elts */ mail_uid_sequence (stream,sequence) : mail_sequence (stream,sequence)) for (i = 1; i <= stream->nmsgs; i++) mail_elt (stream,i)->valid = T;}/* News fetch message header * Accepts: MAIL stream * message # to fetch * pointer to returned header text length * option flags * Returns: message header in RFC822 format */char *news_header (MAILSTREAM *stream,unsigned long msgno, unsigned long *length,long flags){ unsigned long i,hdrsize; int fd; char *t; struct stat sbuf; struct tm *tm; MESSAGECACHE *elt; *length = 0; /* default to empty */ if (flags & FT_UID) return "";/* UID call "impossible" */ /* get elt */ (elt = mail_elt (stream,msgno))->valid = T; if (!elt->private.msg.header.text.data) { /* purge cache if too big */ if (LOCAL->cachedtexts > max (stream->nmsgs * 4096,2097152)) { mail_gc (stream,GC_TEXTS);/* just can't keep that much */ LOCAL->cachedtexts = 0; } /* build message file name */ sprintf (LOCAL->buf,"%s/%lu",LOCAL->dir,elt->private.uid); if ((fd = open (LOCAL->buf,O_RDONLY,NIL)) < 0) return ""; fstat (fd,&sbuf); /* get size of message */ /* make plausible IMAPish date string */ tm = gmtime (&sbuf.st_mtime); elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1; elt->year = tm->tm_year + 1900 - BASEYEAR; elt->hours = tm->tm_hour; elt->minutes = tm->tm_min; elt->seconds = tm->tm_sec; elt->zhours = 0; elt->zminutes = 0; /* is buffer big enough? */ if (sbuf.st_size > LOCAL->buflen) { fs_give ((void **) &LOCAL->buf); LOCAL->buf = (char *) fs_get ((LOCAL->buflen = sbuf.st_size) + 1); } /* slurp message */ read (fd,LOCAL->buf,sbuf.st_size); /* tie off file */ LOCAL->buf[sbuf.st_size] = '\0'; close (fd); /* flush message file */ /* find end of header */ for (i = 0,t = LOCAL->buf; *t && !(i && (*t == '\n')); i = (*t++ == '\n')); /* number of header bytes */ hdrsize = (*t ? ++t : t) - LOCAL->buf; elt->rfc822_size = /* size of entire message in CRLF form */ (elt->private.msg.header.text.size = strcrlfcpy ((char **) &elt->private.msg.header.text.data,&i,LOCAL->buf, hdrsize)) + (elt->private.msg.text.text.size = strcrlfcpy ((char **) &elt->private.msg.text.text.data,&i,t, sbuf.st_size - hdrsize)); /* add to cached size */ LOCAL->cachedtexts += elt->rfc822_size; } *length = elt->private.msg.header.text.size; return (char *) elt->private.msg.header.text.data;}/* News fetch message text (body only) * Accepts: MAIL stream * message # to fetch * pointer to returned stringstruct * option flags * Returns: T on success, NIL on failure */long news_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags){ unsigned long i; MESSAGECACHE *elt; /* UID call "impossible" */ if (flags & FT_UID) return NIL; elt = mail_elt (stream,msgno);/* get elt */ /* snarf message if don't have it yet */ if (!elt->private.msg.text.text.data) { news_header (stream,msgno,&i,flags); if (!elt->private.msg.text.text.data) return NIL; } if (!(flags & FT_PEEK)) { /* mark as seen */ mail_elt (stream,msgno)->seen = T; mm_flags (stream,msgno); } if (!elt->private.msg.text.text.data) return NIL; INIT (bs,mail_string,elt->private.msg.text.text.data, elt->private.msg.text.text.size); return T;}/* News per-message modify flag * Accepts: MAIL stream * message cache element */void news_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt){ if (!LOCAL->dirty) { /* only bother checking if not dirty yet */ if (elt->valid) { /* if done, see if deleted changed */ if (elt->sequence != elt->deleted) LOCAL->dirty = T; elt->sequence = T; /* leave the sequence set */ } /* note current setting of deleted flag */ else elt->sequence = elt->deleted; }}/* News ping mailbox * Accepts: MAIL stream * Returns: T if stream alive, else NIL */long news_ping (MAILSTREAM *stream){ return T; /* always alive */}/* News check mailbox * Accepts: MAIL stream */void news_check (MAILSTREAM *stream){ /* never do if no updates */ if (LOCAL->dirty) newsrc_write (LOCAL->name,stream); LOCAL->dirty = NIL;}/* News expunge mailbox * Accepts: MAIL stream */void news_expunge (MAILSTREAM *stream){ if (!stream->silent) mm_log ("Expunge ignored on news",NIL);}/* News copy message(s) * Accepts: MAIL stream * sequence * destination mailbox * option flags * Returns: T if copy successful, else NIL */long news_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options){ mailproxycopy_t pc = (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL); if (pc) return (*pc) (stream,sequence,mailbox,options); mm_log ("Copy not valid for News",ERROR); return NIL;}/* News append message from stringstruct * Accepts: MAIL stream * destination mailbox * append callback function * data for callback * Returns: T if append successful, else NIL */long news_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data){ mm_log ("Append not valid for news",ERROR); return NIL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -