📄 newsrc.c
字号:
unsigned long m = 1,recent = 0,unseen = 0; FILE *f = fopen ((char *) mail_parameters (stream,GET_NEWSRC,stream),"rb"); if (f) do { /* read newsrc */ for (s = tmp; (s < (tmp + MAILTMPLEN - 1)) && ((c = getc (f)) != EOF) && (c != ':') && (c != '!') && (c != '\015') && (c != '\012'); *s++ = c); *s = '\0'; /* tie off name */ if ((c==':') || (c=='!')) { /* found newsgroup? */ if (strcmp (tmp,group)) /* group name match? */ while ((c != '\015') && (c != '\012') && (c != EOF)) c = getc (f); else { /* yes, skip leading whitespace */ while ((c = getc (f)) == ' '); /* only if unprocessed messages */ if (stream->nmsgs) while (f && (m <= stream->nmsgs)) { /* collect a number */ if (isdigit (c)) { /* better have a number */ for (i = 0,j = 0; isdigit (c); c = getc (f)) i = i*10 + (c-'0'); if (c == '-') for (c = getc (f); isdigit (c); c = getc (f)) j = j*10 +(c-'0');/* collect second value if range */ if (!unseen && (mail_elt (stream,m)->private.uid < i)) unseen = m; /* skip messages before first value */ while ((m <= stream->nmsgs) && ((elt = mail_elt (stream,m))->private.uid < i) && m++) elt->valid = T; /* do all messages in range */ while ((m <= stream->nmsgs) && (elt = mail_elt (stream,m)) && (j ? ((elt->private.uid >= i) && (elt->private.uid <= j)) : (elt->private.uid == i)) && m++) elt->valid = elt->deleted = T; } switch (c) { /* what is the delimiter? */ case ',': /* more to come */ c = getc (f); /* get first character of number */ break; default: /* bogus character */ sprintf (tmp,"Bogus character 0x%x in news state",(unsigned int)c); MM_LOG (tmp,ERROR); case EOF: case '\015': case '\012': fclose (f); /* all done - close the file */ f = NIL; break; } } else { /* empty newsgroup */ while ((c != '\015') && (c != '\012') && (c != EOF)) c = getc (f); fclose (f); /* all done - close the file */ f = NIL; } } } } while (f && (c != EOF)); /* until file closed or EOF */ if (f) { /* still have file open? */ sprintf (tmp,"No state for newsgroup %.80s found, reading as new",group); MM_LOG (tmp,WARN); fclose (f); /* close the file */ } if (m <= stream->nmsgs) { /* any messages beyond newsrc range? */ if (!unseen) unseen = m; /* then this must be the first unseen one */ do { elt = mail_elt (stream,m++); elt->valid = elt->recent = T; ++recent; /* count another recent message */ } while (m <= stream->nmsgs); } if (unseen) { /* report first unseen message */ sprintf (tmp,"[UNSEEN] %lu is first unseen message in %.80s",unseen,group); MM_NOTIFY (stream,tmp,(long) NIL); } return recent;}/* Update newsgroup entry in newsrc * Accepts: newsgroup name * MAIL stream * Returns: T if successful, NIL otherwise */long newsrc_write (char *group,MAILSTREAM *stream){ long ret = NIL; int c = 0,d = EOF; char *newsrc = (char *) mail_parameters (stream,GET_NEWSRC,stream); char *s,tmp[MAILTMPLEN],backup[MAILTMPLEN],nl[3]; FILE *f,*bf; nl[0] = nl[1] = nl[2] = '\0'; /* no newline known yet */ if (f = fopen (newsrc,"rb")) {/* have existing newsrc file? */ if (!(bf = fopen ((strcat (strcpy (backup,newsrc),OLDFILESUFFIX)),"wb"))) { fclose (f); /* punt input file */ return newsrc_error("Can't create backup news state %.80s",backup,ERROR); } /* copy to backup file */ while ((c = getc (f)) != EOF) { /* need to know about newlines and found it? */ if (!nl[0] && ((c == '\015') || (c == '\012')) && ((nl[0]=c) == '\015')){ /* sniff and see if an LF */ if ((c = getc (f)) == '\012') nl[1] = c; ungetc (c,f); /* push it back */ } /* write to backup file */ if ((d = putc (c,bf)) == EOF) { fclose (f); /* punt input file */ return newsrc_error ("Error writing backup news state %.80s", newsrc,ERROR); } } fclose (f); /* close existing file */ if (fclose (bf) == EOF) /* and backup file */ return newsrc_error ("Error closing backup news state %.80s", newsrc,ERROR); if (d == EOF) { /* open for write if empty file */ if (f = newsrc_create (stream,NIL)) bf = NIL; else return NIL; } else if (!nl[0]) /* make sure newlines valid */ return newsrc_error ("Unknown newline convention in %.80s",newsrc,ERROR); /* now read backup file */ else if (!(bf = fopen (backup,"rb"))) return newsrc_error ("Error reading backup news state %.80s", backup,ERROR); /* open newsrc for writing */ else if (!(f = fopen (newsrc,"wb"))) { fclose (bf); /* punt backup */ return newsrc_error ("Can't rewrite news state %.80s",newsrc,ERROR); } } else { /* create new newsrc file */ if (f = newsrc_create (stream,T)) bf = NIL; else return NIL; /* can't create newsrc */ } while (bf) { /* read newsrc */ for (s = tmp; (s < (tmp + MAILTMPLEN - 1)) && ((c = getc (bf)) != EOF) && (c != ':') && (c != '!') && (c != '\015') && (c != '\012'); *s++ = c); *s = '\0'; /* tie off name */ /* saw correct end of group delimiter? */ if (tmp[0] && ((c == ':') || (c == '!'))) { /* yes, write newsgroup name and delimiter */ if ((tmp[0] && (fputs (tmp,f) == EOF)) || ((putc (c,f)) == EOF)) return newsrc_write_error (newsrc,bf,f); if (!strcmp (tmp,group)) {/* found correct group? */ /* yes, write new status */ if (!newsrc_newmessages (f,stream,nl[0] ? nl : "\n")) return newsrc_write_error (newsrc,bf,f); /* skip past old data */ while (((c = getc (bf)) != EOF) && (c != '\015') && (c != '\012')); /* skip past newline */ while ((c == '\015') || (c == '\012')) c = getc (bf); while (c != EOF) { /* copy remainder of file */ if (putc (c,f) == EOF) return newsrc_write_error (newsrc,bf,f); c = getc (bf); /* get next character */ } /* done with file */ if (fclose (f) == EOF) return newsrc_write_error (newsrc,bf,NIL); f = NIL; } /* copy remainder of line */ else while (((c = getc (bf)) != EOF) && (c != '\015') && (c != '\012')) if (putc (c,f) == EOF) return newsrc_write_error (newsrc,bf,f); if (c == '\015') { /* write CR if seen */ if (putc (c,f) == EOF) return newsrc_write_error (newsrc,bf,f); /* sniff to see if LF */ if (((c = getc (bf)) != EOF) && (c != '\012')) ungetc (c,bf); } /* write LF if seen */ if ((c == '\012') && (putc (c,f) == EOF)) return newsrc_write_error (newsrc,bf,f); } if (c == EOF) { /* hit end of file? */ fclose (bf); /* yup, close the file */ bf = NIL; } } if (f) { /* still have newsrc file open? */ ret = ((fputs (group,f) != EOF) && ((putc (':',f)) != EOF) && newsrc_newmessages (f,stream,nl[0] ? nl : "\n")) ? LONGT : NIL; if (fclose (f) == EOF) ret = newsrc_write_error (newsrc,NIL,NIL); } else ret = LONGT; return ret;}/* Get newsgroup state as text stream * Accepts: MAIL stream * newsgroup name * Returns: string containing newsgroup state, or NIL if not found */char *newsrc_state (MAILSTREAM *stream,char *group){ int c = 0; char *s,tmp[MAILTMPLEN]; long pos; size_t size; FILE *f = fopen ((char *) mail_parameters (stream,GET_NEWSRC,stream),"rb"); if (f) do { /* read newsrc */ for (s = tmp; (s < (tmp + MAILTMPLEN - 1)) && ((c = getc (f)) != EOF) && (c != ':') && (c != '!') && (c != '\015') && (c != '\012'); *s++ = c); *s = '\0'; /* tie off name */ if ((c==':') || (c=='!')) { /* found newsgroup? */ if (strcmp (tmp,group)) /* group name match? */ while ((c != '\015') && (c != '\012') && (c != EOF)) c = getc (f); else { /* yes, skip leading whitespace */ do pos = ftell (f); while ((c = getc (f)) == ' '); /* count characters in state */ for (size = 0; (c != '\015') && (c != '\012') && (c != EOF); size++) c = getc (f); /* now copy it */ s = (char *) fs_get (size + 1); fseek (f,pos,SEEK_SET); fread (s,(size_t) 1,size,f); s[size] = '\0'; /* tie off string */ fclose (f); /* all done - close the file */ return s; } } } while (f && (c != EOF)); /* until file closed or EOF */ sprintf (tmp,"No state for newsgroup %.80s found",group); MM_LOG (tmp,WARN); if (f) fclose (f); /* close the file */ return NIL; /* not found return */}/* Check UID in newsgroup state * Accepts: newsgroup state string * uid * returned recent count * returned unseen count */void newsrc_check_uid (unsigned char *state,unsigned long uid, unsigned long *recent,unsigned long *unseen){ unsigned long i,j; while (*state) { /* until run out of state string */ /* collect a number */ for (i = 0; isdigit (*state); i = i*10 + (*state++ - '0')); if (*state != '-') j = i; /* coerce single mesage into range */ else { /* have a range */ for (j = 0; isdigit (*++state); j = j*10 + (*state - '0')); if (!j) j = i; /* guard against -0 */ if (j < i) return; /* bogon if end less than start */ } if (*state == ',') state++; /* skip past comma */ else if (*state) return; /* otherwise it's a bogon */ if (uid <= j) { /* covered by upper bound? */ if (uid < i) ++*unseen; /* unseen if not covered by lower bound */ return; /* don't need to look further */ } } ++*unseen; /* not found in any range, message is unseen */ ++*recent; /* and recent */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -