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

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

Webmaster