Annotation of libwww/Library/src/HTNewsLs.c, revision 2.1
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.
! 6: **
! 7: ** Authors
! 8: ** FTLO Felix Lo
! 9: ** HFN Henrik Frystyk <frystyk@w3.org>
! 10: **
! 11: ** History:
! 12: ** Oct 95 HFN Written
! 13: */
! 14:
! 15: /* Library include files */
! 16: #include "tcp.h"
! 17: #include "HTUtils.h"
! 18: #include "HTString.h"
! 19: #include "HTStream.h"
! 20: #include "HTFormat.h"
! 21: #include "HTSocket.h"
! 22: #include "HTNDir.h"
! 23: #include "HTNews.h"
! 24: #include "HTNewsLs.h" /* Implemented here */
! 25:
! 26: #define DELIMITER '\t'
! 27:
! 28: struct _HTStream {
! 29: CONST HTStreamClass * isa;
! 30: HTRequest * request;
! 31: HTSocketEOL state;
! 32: HTNewsDir * dir;
! 33: BOOL group;
! 34: BOOL junk;
! 35: char buffer[MAX_NEWS_LINE+1];
! 36: int buflen;
! 37: };
! 38:
! 39: PRIVATE HTNewsDirKey dir_key = HT_NDK_THREAD;
! 40:
! 41: /* ------------------------------------------------------------------------- */
! 42:
! 43:
! 44: /* ParseList
! 45: ** ---------
! 46: ** Extract the group name from a LIST listing
! 47: ** Returns YES if OK, NO on error
! 48: */
! 49: PRIVATE BOOL ParseList (HTNewsDir *dir, char * line)
! 50: {
! 51: char *ptr = line;
! 52: while (*ptr && !WHITE(*ptr)) ptr++;
! 53: *ptr = '\0';
! 54: return HTNewsDir_addElement(dir, line, 0, NULL, NULL, 0);
! 55: }
! 56:
! 57:
! 58: /* ParseGroup
! 59: ** ----------
! 60: ** Extract the index number, subject etc, from a XOVER command. Expects
! 61: ** the following format of the line:
! 62: **
! 63: ** <index> <subject> <from> <data> <msgid> [*<thread>] ...
! 64: **
! 65: ** Returns YES if OK, NO on error
! 66: */
! 67: PRIVATE BOOL ParseGroup (HTNewsDir *dir, char * line)
! 68: {
! 69: int index;
! 70: int refcnt;
! 71: char *msgid;
! 72: char *from;
! 73: char *ptr;
! 74: char *subject = line; /* Index */
! 75: while (*subject && *subject != DELIMITER) subject++;
! 76: *subject++ = '\0';
! 77: index = atoi(line);
! 78: from = subject; /* Subject */
! 79: while (*from && *from != DELIMITER) from++;
! 80: *from++ = '\0';
! 81: ptr = from; /* Date */
! 82: while (*ptr && *ptr != DELIMITER) ptr++;
! 83: *ptr++ = '\0';
! 84: msgid = ptr; /* Msg-ID */
! 85: while (*msgid && *msgid != DELIMITER) msgid++;
! 86: *msgid++ = '\0';
! 87: ptr = msgid; /* Bytes or ref */
! 88: while (*ptr && *ptr != DELIMITER) ptr++;
! 89: *ptr++ = '\0';
! 90: while (!isdigit(*ptr)) {
! 91: while (*ptr && *ptr != DELIMITER) ptr++;
! 92: *ptr++ = '\0';
! 93: refcnt++;
! 94: }
! 95: return HTNewsDir_addElement(dir, msgid, index, subject, from, refcnt);
! 96: }
! 97:
! 98: /*
! 99: ** Searches for News line until buffer fills up or a CRLF or LF is found
! 100: */
! 101: PRIVATE int HTNewsList_put_block (HTStream * me, CONST char * b, int l)
! 102: {
! 103: while (l-- > 0) {
! 104: if (me->state == EOL_FCR) {
! 105: if (*b == LF && me->buflen) {
! 106: if (!me->junk) {
! 107: *(me->buffer+me->buflen) = '\0';
! 108: me->group ? ParseGroup(me->dir, me->buffer) :
! 109: ParseList(me->dir, me->buffer);
! 110: } else
! 111: me->junk = NO; /* back to normal */
! 112: }
! 113: me->buflen = 0;
! 114: me->state = EOL_BEGIN;
! 115: } else if (*b == CR) {
! 116: me->state = EOL_FCR;
! 117: } else if (*b == LF && me->buflen) {
! 118: if (!me->junk) {
! 119: *(me->buffer+me->buflen) = '\0';
! 120: me->group ? ParseGroup(me->dir, me->buffer) :
! 121: ParseList(me->dir, me->buffer);
! 122: } else
! 123: me->junk = NO; /* back to normal */
! 124: me->buflen = 0;
! 125: me->state = EOL_BEGIN;
! 126: } else {
! 127: *(me->buffer+me->buflen++) = *b;
! 128: if (me->buflen >= MAX_NEWS_LINE) {
! 129: if (PROT_TRACE)
! 130: fprintf(TDEST, "News Dir.... Line too long - chopped\n");
! 131: *(me->buffer+me->buflen) = '\0';
! 132: me->group ? ParseGroup(me->dir, me->buffer) :
! 133: ParseList(me->dir, me->buffer);
! 134: me->buflen = 0;
! 135: me->junk = YES;
! 136: }
! 137: }
! 138: b++;
! 139: }
! 140: return HT_OK;
! 141: }
! 142:
! 143: PRIVATE int HTNewsList_put_character (HTStream * me, char ch)
! 144: {
! 145: return HTNewsList_put_block(me, &ch, 1);
! 146: }
! 147:
! 148: PRIVATE int HTNewsList_put_string (HTStream * me, CONST char * s)
! 149: {
! 150: return HTNewsList_put_block(me, s, (int) strlen(s));
! 151: }
! 152:
! 153: PRIVATE int HTNewsList_flush (HTStream * me)
! 154: {
! 155: return HT_OK;
! 156: }
! 157:
! 158: PRIVATE int HTNewsList_free (HTStream * me)
! 159: {
! 160: HTNewsDir_free(me->dir);
! 161: free(me);
! 162: return HT_OK;
! 163: }
! 164:
! 165: PRIVATE int HTNewsList_abort (HTStream * me, HTError e)
! 166: {
! 167: if (PROT_TRACE) fprintf(TDEST, "News Dir.... ABORTING...\n");
! 168: HTNewsList_free(me);
! 169: return HT_ERROR;
! 170: }
! 171:
! 172: PRIVATE CONST HTStreamClass HTNewsListClass =
! 173: {
! 174: "NewsList",
! 175: HTNewsList_flush,
! 176: HTNewsList_free,
! 177: HTNewsList_abort,
! 178: HTNewsList_put_character,
! 179: HTNewsList_put_string,
! 180: HTNewsList_put_block
! 181: };
! 182:
! 183: PUBLIC HTStream *HTNewsList (HTRequest * request,
! 184: void * param,
! 185: HTFormat input_format,
! 186: HTFormat output_format,
! 187: HTStream * output_stream)
! 188: {
! 189: HTStream *me = (HTStream *) calloc(1, sizeof(HTStream));
! 190: if (!me) outofmem(__FILE__, "HTNewsList_new");
! 191: me->isa = &HTNewsListClass;
! 192: me->request = request;
! 193: me->state = EOL_BEGIN;
! 194: me->dir = HTNewsDir_new(request, "Newsgroups", HT_NDK_GROUP);
! 195: if (me->dir == NULL) FREE(me);
! 196: return me;
! 197: }
! 198:
! 199: PUBLIC HTStream *HTNewsGroup (HTRequest * request,
! 200: void * param,
! 201: HTFormat input_format,
! 202: HTFormat output_format,
! 203: HTStream * output_stream)
! 204: {
! 205: HTStream *me = (HTStream *) calloc(1, sizeof(HTStream));
! 206: if (!me) outofmem(__FILE__, "HTNewsList_new");
! 207: me->isa = &HTNewsListClass;
! 208: me->request = request;
! 209: me->state = EOL_BEGIN;
! 210: me->group = YES;
! 211: me->dir = HTNewsDir_new(request, "Newsgroup", dir_key);
! 212: if (me->dir == NULL) FREE(me);
! 213: return me;
! 214: }
Webmaster