Annotation of libwww/Library/src/HTNewsLs.c, revision 2.11
2.1 frystyk 1: /* HTNewsLs.c
2: ** NEWS (NNTP) GROUP LISTINGS
3: **
4: ** (c) COPYRIGHT MIT 1995.
5: ** Please first read the full copyright statement in the file COPYRIGH.
2.11 ! frystyk 6: ** @(#) $Id: HTNewsLs.c,v 2.10 1996/04/12 17:48:20 frystyk Exp $
2.1 frystyk 7: **
8: ** Authors
9: ** FTLO Felix Lo
10: ** HFN Henrik Frystyk <frystyk@w3.org>
11: **
12: ** History:
13: ** Oct 95 HFN Written
14: */
15:
16: /* Library include files */
2.8 frystyk 17: #include "sysdep.h"
2.11 ! frystyk 18: #include "WWWUtil.h"
! 19: #include "WWWCore.h"
2.1 frystyk 20: #include "HTNDir.h"
21: #include "HTNews.h"
22: #include "HTNewsLs.h" /* Implemented here */
23:
24: #define DELIMITER '\t'
2.5 frystyk 25: #define ATSIGN '@'
2.1 frystyk 26:
27: struct _HTStream {
2.8 frystyk 28: const HTStreamClass * isa;
2.1 frystyk 29: HTRequest * request;
2.9 frystyk 30: HTEOLState state;
2.1 frystyk 31: HTNewsDir * dir;
32: BOOL group;
33: BOOL junk;
34: char buffer[MAX_NEWS_LINE+1];
35: int buflen;
36: };
37:
2.5 frystyk 38: PRIVATE HTNewsDirKey dir_key = HT_NDK_NONE;
2.1 frystyk 39:
40: /* ------------------------------------------------------------------------- */
41:
42:
43: /* ParseList
44: ** ---------
45: ** Extract the group name from a LIST listing
46: ** Returns YES if OK, NO on error
47: */
48: PRIVATE BOOL ParseList (HTNewsDir *dir, char * line)
49: {
50: char *ptr = line;
51: while (*ptr && !WHITE(*ptr)) ptr++;
52: *ptr = '\0';
2.5 frystyk 53: return HTNewsDir_addElement(dir, 0, line, NULL, (time_t) 0, line, 0);
2.1 frystyk 54: }
55:
56:
57: /* ParseGroup
58: ** ----------
59: ** Extract the index number, subject etc, from a XOVER command. Expects
60: ** the following format of the line:
61: **
62: ** <index> <subject> <from> <data> <msgid> [*<thread>] ...
63: **
64: ** Returns YES if OK, NO on error
65: */
66: PRIVATE BOOL ParseGroup (HTNewsDir *dir, char * line)
67: {
68: int index;
2.3 frystyk 69: int refcnt=0;
2.5 frystyk 70: time_t t=0;
71: char *subject = line;
72: char *from;
73: char *date;
2.1 frystyk 74: char *msgid;
2.5 frystyk 75: char *ptr=NULL;
2.1 frystyk 76: while (*subject && *subject != DELIMITER) subject++;
2.5 frystyk 77: *subject++ = '\0'; /* Index */
2.1 frystyk 78: index = atoi(line);
2.5 frystyk 79: from = subject;
2.1 frystyk 80: while (*from && *from != DELIMITER) from++;
2.5 frystyk 81: *from++ = '\0'; /* Subject */
82: date = from;
83: while (*date && *date != DELIMITER) {
84: if (*date=='<' || *date=='(') {
85: ptr = date+1;
86: *date = '\0';
87: }
88: if (*date=='>' || *date==')') *date = '\0';
89: date++;
90: }
91: *date++ = '\0';
92: if (strchr(from, ATSIGN) && ptr) from = ptr; /* From */
93: msgid = date;
2.1 frystyk 94: while (*msgid && *msgid != DELIMITER) msgid++;
2.5 frystyk 95: *msgid++ = '\0'; /* Date */
96: if (*msgid=='<') msgid++;
97: #if 0
98: t = HTParseTime(date);
99: #endif
100: ptr = msgid;
101: while (*ptr && *ptr != DELIMITER) {
102: if (*ptr=='>') *ptr = '\0';
103: ptr++;
104: }
105: *ptr++ = '\0'; /* MsgId */
2.1 frystyk 106: while (!isdigit(*ptr)) {
107: while (*ptr && *ptr != DELIMITER) ptr++;
108: *ptr++ = '\0';
109: refcnt++;
110: }
2.5 frystyk 111: return HTNewsDir_addElement(dir, index, subject, from, t, msgid, refcnt);
2.1 frystyk 112: }
113:
114: /*
115: ** Searches for News line until buffer fills up or a CRLF or LF is found
116: */
2.8 frystyk 117: PRIVATE int HTNewsList_put_block (HTStream * me, const char * b, int l)
2.1 frystyk 118: {
119: while (l-- > 0) {
120: if (me->state == EOL_FCR) {
121: if (*b == LF && me->buflen) {
122: if (!me->junk) {
123: *(me->buffer+me->buflen) = '\0';
124: me->group ? ParseGroup(me->dir, me->buffer) :
125: ParseList(me->dir, me->buffer);
126: } else
127: me->junk = NO; /* back to normal */
128: }
129: me->buflen = 0;
130: me->state = EOL_BEGIN;
131: } else if (*b == CR) {
132: me->state = EOL_FCR;
133: } else if (*b == LF && me->buflen) {
134: if (!me->junk) {
135: *(me->buffer+me->buflen) = '\0';
136: me->group ? ParseGroup(me->dir, me->buffer) :
137: ParseList(me->dir, me->buffer);
138: } else
139: me->junk = NO; /* back to normal */
140: me->buflen = 0;
141: me->state = EOL_BEGIN;
142: } else {
143: *(me->buffer+me->buflen++) = *b;
144: if (me->buflen >= MAX_NEWS_LINE) {
145: if (PROT_TRACE)
2.7 eric 146: HTTrace("News Dir.... Line too long - chopped\n");
2.1 frystyk 147: *(me->buffer+me->buflen) = '\0';
148: me->group ? ParseGroup(me->dir, me->buffer) :
149: ParseList(me->dir, me->buffer);
150: me->buflen = 0;
151: me->junk = YES;
152: }
153: }
154: b++;
155: }
156: return HT_OK;
157: }
158:
159: PRIVATE int HTNewsList_put_character (HTStream * me, char ch)
160: {
161: return HTNewsList_put_block(me, &ch, 1);
162: }
163:
2.8 frystyk 164: PRIVATE int HTNewsList_put_string (HTStream * me, const char * s)
2.1 frystyk 165: {
166: return HTNewsList_put_block(me, s, (int) strlen(s));
167: }
168:
169: PRIVATE int HTNewsList_flush (HTStream * me)
170: {
171: return HT_OK;
172: }
173:
174: PRIVATE int HTNewsList_free (HTStream * me)
175: {
176: HTNewsDir_free(me->dir);
2.6 frystyk 177: HT_FREE(me);
2.1 frystyk 178: return HT_OK;
179: }
180:
2.4 frystyk 181: PRIVATE int HTNewsList_abort (HTStream * me, HTList * e)
2.1 frystyk 182: {
2.7 eric 183: if (PROT_TRACE) HTTrace("News Dir.... ABORTING...\n");
2.1 frystyk 184: HTNewsList_free(me);
185: return HT_ERROR;
186: }
187:
2.8 frystyk 188: PRIVATE const HTStreamClass HTNewsListClass =
2.1 frystyk 189: {
190: "NewsList",
191: HTNewsList_flush,
192: HTNewsList_free,
193: HTNewsList_abort,
194: HTNewsList_put_character,
195: HTNewsList_put_string,
196: HTNewsList_put_block
197: };
198:
199: PUBLIC HTStream *HTNewsList (HTRequest * request,
200: void * param,
201: HTFormat input_format,
202: HTFormat output_format,
203: HTStream * output_stream)
204: {
2.6 frystyk 205: HTStream *me;
206: if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
207: HT_OUTOFMEM("HTNewsList_new");
2.1 frystyk 208: me->isa = &HTNewsListClass;
209: me->request = request;
210: me->state = EOL_BEGIN;
211: me->dir = HTNewsDir_new(request, "Newsgroups", HT_NDK_GROUP);
2.6 frystyk 212: if (me->dir == NULL) HT_FREE(me);
2.1 frystyk 213: return me;
214: }
215:
216: PUBLIC HTStream *HTNewsGroup (HTRequest * request,
217: void * param,
218: HTFormat input_format,
219: HTFormat output_format,
220: HTStream * output_stream)
221: {
2.5 frystyk 222: char * url = HTAnchor_physical(HTRequest_anchor(request));
223: char * title = NULL;
2.6 frystyk 224: HTStream *me;
225: if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
226: HT_OUTOFMEM("HTNewsList_new");
2.5 frystyk 227: StrAllocCopy(title, "Newsgroup: ");
228: if (!strncasecomp(url, "news:", 5))
229: StrAllocCat(title, url+5);
230: else
231: StrAllocCat(title, HTParse(url, "", PARSE_PATH));
2.1 frystyk 232: me->isa = &HTNewsListClass;
233: me->request = request;
234: me->state = EOL_BEGIN;
235: me->group = YES;
2.5 frystyk 236: me->dir = HTNewsDir_new(request, title, dir_key);
2.6 frystyk 237: if (me->dir == NULL) HT_FREE(me);
238: HT_FREE(title);
2.1 frystyk 239: return me;
240: }
Webmaster