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

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.2       frystyk   150:                    TTYPrint(TDEST, "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);
                    181:     free(me);
                    182:     return HT_OK;
                    183: }
                    184: 
2.4       frystyk   185: PRIVATE int HTNewsList_abort (HTStream * me, HTList * e)
2.1       frystyk   186: {
2.2       frystyk   187:     if (PROT_TRACE) TTYPrint(TDEST, "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: {
                    209:     HTStream *me = (HTStream *) calloc(1, sizeof(HTStream));
                    210:     if (!me) outofmem(__FILE__, "HTNewsList_new");
                    211:     me->isa = &HTNewsListClass;
                    212:     me->request = request;
                    213:     me->state = EOL_BEGIN;
                    214:     me->dir = HTNewsDir_new(request, "Newsgroups", HT_NDK_GROUP);
                    215:     if (me->dir == NULL) FREE(me);
                    216:     return me;
                    217: }
                    218: 
                    219: PUBLIC HTStream *HTNewsGroup (HTRequest *      request,
                    220:                              void *            param,  
                    221:                              HTFormat          input_format,
                    222:                              HTFormat          output_format,
                    223:                              HTStream *        output_stream)
                    224: {
2.5     ! frystyk   225:     char * url = HTAnchor_physical(HTRequest_anchor(request));
        !           226:     char * title = NULL;
2.1       frystyk   227:     HTStream *me = (HTStream *) calloc(1, sizeof(HTStream));
                    228:     if (!me) outofmem(__FILE__, "HTNewsList_new");
2.5     ! frystyk   229:     StrAllocCopy(title, "Newsgroup: ");
        !           230:     if (!strncasecomp(url, "news:", 5))
        !           231:        StrAllocCat(title, url+5);
        !           232:     else
        !           233:        StrAllocCat(title, HTParse(url, "", PARSE_PATH));
2.1       frystyk   234:     me->isa = &HTNewsListClass;
                    235:     me->request = request;
                    236:     me->state = EOL_BEGIN;
                    237:     me->group = YES;
2.5     ! frystyk   238:     me->dir = HTNewsDir_new(request, title, dir_key);
2.1       frystyk   239:     if (me->dir == NULL) FREE(me);
2.5     ! frystyk   240:     free(title);
2.1       frystyk   241:     return me;
                    242: }

Webmaster