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

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

Webmaster