Annotation of libwww/Library/src/HTNewsLs.c, revision 2.2

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)
2.2     ! frystyk   130:                    TTYPrint(TDEST, "News Dir.... Line too long - chopped\n");
2.1       frystyk   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: {
2.2     ! frystyk   167:     if (PROT_TRACE) TTYPrint(TDEST, "News Dir.... ABORTING...\n");
2.1       frystyk   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