📄 newsrc.c
字号:
/* ======================================================================== * Copyright 1988-2006 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * * ======================================================================== *//* * Program: Newsrc manipulation routines * * Author: Mark Crispin * Networks and Distributed Computing * Computing & Communications * University of Washington * Administration Building, AG-44 * Seattle, WA 98195 * Internet: MRC@CAC.Washington.EDU * * Date: 12 September 1994 * Last Edited: 30 August 2006 */#include <ctype.h>#include <stdio.h>#include "c-client.h"#include "newsrc.h"#ifndef OLDFILESUFFIX#define OLDFILESUFFIX ".old"#endif/* Error message * Accepts: message format * additional message string * message level * Returns: NIL, always */long newsrc_error (char *fmt,char *text,long errflg){ char tmp[MAILTMPLEN]; sprintf (tmp,fmt,text); MM_LOG (tmp,errflg); return NIL;}/* Write error message * Accepts: newsrc name * file designator * file designator * Returns: NIL, always */long newsrc_write_error (char *name,FILE *f1,FILE *f2){ if (f1) fclose (f1); /* close file designators */ if (f2) fclose (f2); return newsrc_error ("Error writing to %.80s",name,ERROR);}/* Create newsrc file in local form * Accepts: MAIL stream * notification flag * Returns: file designator of newsrc */FILE *newsrc_create (MAILSTREAM *stream,int notify){ char *newsrc = (char *) mail_parameters (stream,GET_NEWSRC,stream); FILE *f = fopen (newsrc,"wb"); if (!f) newsrc_error ("Unable to create news state %.80s",newsrc,ERROR); else if (notify) newsrc_error ("Creating news state %.80s",newsrc,WARN); return f;}/* Write new state in newsrc * Accepts: file designator of newsrc * group * new subscription status character * newline convention * Returns: T if successful, NIL otherwise */long newsrc_newstate (FILE *f,char *group,char state,char *nl){ long ret = (f && (fputs (group,f) != EOF) && ((putc (state,f)) != EOF) && ((putc (' ',f)) != EOF) && (fputs (nl,f) != EOF)) ? LONGT : NIL; if (fclose (f) == EOF) ret = NIL; return ret;}/* Write messages in newsrc * Accepts: file designator of newsrc * MAIL stream * message number/newsgroup message map * newline convention * Returns: T if successful, NIL otherwise */long newsrc_newmessages (FILE *f,MAILSTREAM *stream,char *nl){ unsigned long i,j,k; char tmp[MAILTMPLEN]; MESSAGECACHE *elt; int c = ' '; if (stream->nmsgs) { /* have any messages? */ for (i = 1,j = k = (mail_elt (stream,i)->private.uid > 1) ? 1 : 0; i <= stream->nmsgs; ++i) { /* deleted message? */ if ((elt = mail_elt (stream,i))->deleted) { k = elt->private.uid; /* this is the top of the current range */ if (!j) j = k; /* if no range in progress, start one */ } else if (j) { /* unread message, ending a range */ /* calculate end of range */ if (k = elt->private.uid - 1) { /* dump range */ sprintf (tmp,(j == k) ? "%c%ld" : "%c%ld-%ld",c,j,k); if (fputs (tmp,f) == EOF) return NIL; c = ','; /* need a comma after the first time */ } j = 0; /* no more range in progress */ } } if (j) { /* dump trailing range */ sprintf (tmp,(j == k) ? "%c%ld" : "%c%ld-%ld",c,j,k); if (fputs (tmp,f) == EOF) return NIL; } } /* write trailing newline, return */ return (fputs (nl,f) == EOF) ? NIL : LONGT;}/* List subscribed newsgroups * Accepts: MAIL stream * prefix to append name * pattern to search */void newsrc_lsub (MAILSTREAM *stream,char *pattern){ char *s,*t,*lcl,name[MAILTMPLEN]; int c = ' '; int showuppers = pattern[strlen (pattern) - 1] == '%'; FILE *f = fopen ((char *) mail_parameters (stream,GET_NEWSRC,stream),"rb"); if (f) { /* got file? */ /* remote name? */ if (*(lcl = strcpy (name,pattern)) == '{') lcl = strchr (lcl,'}') + 1; if (*lcl == '#') lcl += 6; /* namespace format name? */ while (c != EOF) { /* yes, read newsrc */ for (s = lcl; (s < (name + MAILTMPLEN - 1)) && ((c = getc (f)) != EOF) && (c != ':') && (c != '!') && (c != '\015') && (c != '\012'); *s++ = c); if (c == ':') { /* found a subscribed newsgroup? */ *s = '\0'; /* yes, tie off name */ /* report if match */ if (pmatch_full (name,pattern,'.')) mm_lsub (stream,'.',name,NIL); else while (showuppers && (t = strrchr (lcl,'.'))) { *t = '\0'; /* tie off the name */ if (pmatch_full (name,pattern,'.')) mm_lsub (stream,'.',name,LATT_NOSELECT); } } while ((c != '\015') && (c != '\012') && (c != EOF)) c = getc (f); } fclose (f); }}/* Update subscription status of newsrc * Accepts: MAIL stream * group * new subscription status character * Returns: T if successful, NIL otherwise */long newsrc_update (MAILSTREAM *stream,char *group,char state){ char tmp[MAILTMPLEN]; char *newsrc = (char *) mail_parameters (stream,GET_NEWSRC,stream); long ret = NIL; FILE *f = fopen (newsrc,"r+b"); if (f) { /* update existing file */ int c = 0; char *s,nl[3]; long pos = 0; nl[0] = nl[1] = nl[2]='\0'; /* no newline known yet */ do { /* read newsrc */ for (s = tmp; (s < (tmp + MAILTMPLEN - 1)) && ((c = getc (f)) != EOF) && (c != ':') && (c != '!') && (c != '\015') && (c != '\012'); *s++ = c) pos = ftell (f); *s = '\0'; /* tie off name */ /* found the newsgroup? */ if (((c == ':') || (c == '!')) && !strcmp (tmp,group)) { if (c == state) { /* already at that state? */ if (c == ':') newsrc_error("Already subscribed to %.80s",group,WARN); ret = LONGT; /* noop the update */ } /* write the character */ else if (!fseek (f,pos,0)) ret = ((putc (state,f)) == EOF) ? NIL:LONGT; if (fclose (f) == EOF) ret = NIL; f = NIL; /* done with file */ break; } /* gobble remainder of this line */ while ((c != '\015') && (c != '\012') && (c != EOF)) c = getc (f); /* 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; else ungetc (c,f); /* nope, push it back */ } } while (c != EOF); if (f) { /* still haven't written it yet? */ if (nl[0]) { /* know its newline convention? */ fseek (f,0L,2); /* yes, seek to end of file */ ret = newsrc_newstate (f,group,state,nl); } else { /* can't find a newline convention */ fclose (f); /* punt the file */ /* can't win if read something */ if (pos) newsrc_error ("Unknown newline convention in %.80s", newsrc,ERROR); /* file must have been empty, rewrite it */ else ret = newsrc_newstate(newsrc_create(stream,NIL),group,state,"\n"); } } } /* create new file */ else ret = newsrc_newstate (newsrc_create (stream,T),group,state,"\n"); return ret; /* return with update status */}/* Update newsgroup status in stream * Accepts: newsgroup name * MAIL stream * Returns: number of recent messages */long newsrc_read (char *group,MAILSTREAM *stream){ int c = 0; char *s,tmp[MAILTMPLEN]; unsigned long i,j; MESSAGECACHE *elt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -