HTNewsLs.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:6k
源码类别:

浏览器

开发平台:

Unix_Linux

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