HTNewsRq.c
Upload User: zlh9724
Upload Date: 2007-01-04
Package Size: 1991k
Code Size: 5k
Category:

Browser Client

Development Platform:

Unix_Linux

  1. /*      HTNewsRq.c
  2. ** NNTP MESSAGE GENERATION
  3. **
  4. ** This module implements the output stream for MIME used for sending
  5. ** requests with or without a entity body to HTTP, NEWS, etc.
  6. **
  7. ** History:
  8. ** Jan 95 HFN Written
  9. */
  10. /* Library Includes */
  11. #include "tcp.h"
  12. #include "HTUtils.h"
  13. #include "HTString.h"
  14. #include "HTParse.h"
  15. #include "HTTCP.h"
  16. #include "HTWriter.h"
  17. #include "HTReqMan.h"
  18. #include "HTChunk.h"
  19. #include "HTMIMERq.h"
  20. #include "HTNewsRq.h"        /* Implements */
  21. #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
  22. struct _HTStream {
  23.     CONST HTStreamClass * isa;
  24.     HTStream *    target;
  25.     HTRequest * request;
  26.     SOCKET sockfd;
  27.     HTChunk *   buffer;
  28.     int version;
  29.     BOOL transparent;
  30. };
  31. /* ------------------------------------------------------------------------- */
  32. /*      News Output Post Stream      */
  33. /* ------------------------------------------------------------------------- */
  34. /* NewsPost_start
  35. ** --------------
  36. ** NNTP needs two extra headers: "From" and "Newsgroups".
  37. ** Take the newsgroups from the Postweb model as destinations for this
  38. ** anchor.
  39. ** Return YES if OK else NO
  40. */
  41. PRIVATE BOOL NewsPost_start (HTStream * me, HTRequest * request)
  42. {
  43.     char linebuf[128]; /* @@@ */
  44.     HTChunk *header = me->buffer;
  45.     CONST char *mailaddress = HTGetMailAddress();
  46.     if (mailaddress) {
  47. sprintf(linebuf, "From: %s%c%c", mailaddress, CR, LF);
  48. HTChunk_puts(header, linebuf);
  49.     }
  50.     /*
  51.     ** Find all the newsgroups we are posting to by looking at all the
  52.     **  destinations from the source of this request.
  53.     **  First the main link and then the sub links
  54.     */
  55.     HTChunk_puts(header, "Newsgroups :");    
  56.     if (HTRequest_isDestination(request)) {
  57. HTRequest *src_req = HTRequest_source(request);
  58. HTParentAnchor *src_anchor = HTRequest_anchor(src_req);
  59. HTLink *link = HTAnchor_mainLink((HTAnchor *) src_anchor);
  60. HTAnchor *dest = HTLink_destination(link);
  61. HTMethod method = HTLink_method(link);
  62. if (link && method == METHOD_POST &&
  63.     HTLink_result(link) == HT_LINK_NONE) {
  64.     char *desturl = HTAnchor_physical((HTParentAnchor *) dest);
  65.     char *access = HTParse(desturl, "", PARSE_ACCESS);
  66.     if (!strcasecomp(access, "news") || !strcasecomp(access, "nntp")) {
  67. char *newsgroup = HTParse(desturl, "", PARSE_PATH);
  68. HTUnEscape(newsgroup);
  69. HTCleanTelnetString(newsgroup);
  70. HTChunk_puts(header, newsgroup);
  71. HT_FREE(newsgroup);
  72.     }
  73.     HT_FREE(access);
  74. }
  75. /* DO FOR ALL SUB ANCHOR DESTINATION S AS WELL */
  76.     }
  77.     if (PROT_TRACE) TTYPrint(TDEST, "News Tx..... %s", HTChunk_data(header));
  78.     return YES;
  79. }
  80. /* NewsPost_end
  81. ** ------------
  82. ** End the posting by CRLF.CRLF
  83. ** returns whatever PUT_BLOCK returns
  84. */
  85. PRIVATE int NewsPost_end (HTStream * me)
  86. {
  87.     char buf[6];
  88.     *buf = CR;
  89.     *(buf+1) = LF;
  90.     *(buf+2) = '.';
  91.     *(buf+3) = CR;
  92.     *(buf+4) = LF;
  93.     *(buf+5) = '';
  94.     return PUTBLOCK(buf, 5);
  95. }
  96. PRIVATE int NewsPost_put_block (HTStream * me, CONST char* b, int l)
  97. {
  98.     if (!me->target) {
  99. return HT_WOULD_BLOCK;
  100.     } else if (me->transparent)
  101. return b ? PUTBLOCK(b, l) : HT_OK;
  102.     else {
  103. int status;
  104. NewsPost_start(me, me->request);
  105. if ((status = PUTBLOCK(HTChunk_data(me->buffer),
  106.        HTChunk_size(me->buffer))) == HT_OK) {
  107.     me->transparent = YES;
  108.     return b ? PUTBLOCK(b, l) : HT_OK;
  109. }
  110. return status;
  111.     }
  112. }
  113. PRIVATE int NewsPost_put_character (HTStream * me, char c)
  114. {
  115.     return NewsPost_put_block(me, &c, 1);
  116. }
  117. PRIVATE int NewsPost_put_string (HTStream * me, CONST char * s)
  118. {
  119.     return NewsPost_put_block(me, s, strlen(s));
  120. }
  121. /*
  122. ** Flushes header but doesn't free stream object
  123. */
  124. PRIVATE int NewsPost_flush (HTStream * me)
  125. {
  126.     return NewsPost_put_block(me, NULL, 0);
  127. }
  128. /*
  129. ** Flushes data and frees stream object
  130. */
  131. PRIVATE int NewsPost_free (HTStream * me)
  132. {
  133.     int status;
  134.     if ((status = NewsPost_flush(me)) != HT_OK ||
  135. (status = NewsPost_end(me)) != HT_OK ||
  136. (status = (*me->target->isa->_free)(me->target)) != HT_OK)
  137. return status;
  138.     HTChunk_delete(me->buffer);
  139.     HT_FREE(me);
  140.     return status;
  141. }
  142. PRIVATE int NewsPost_abort (HTStream * me, HTList * e)
  143. {
  144.     if (me->target) (*me->target->isa->abort)(me->target, e);
  145.     HTChunk_delete(me->buffer);
  146.     HT_FREE(me);
  147.     if (PROT_TRACE) TTYPrint(TDEST, "NewsPost.... ABORTING...n");
  148.     return HT_ERROR;
  149. }
  150. /* NewsPost Stream
  151. ** -----------------
  152. */
  153. PRIVATE CONST HTStreamClass NewsPostClass =
  154. {
  155.     "NewsPost",
  156.     NewsPost_flush,
  157.     NewsPost_free,
  158.     NewsPost_abort,
  159.     NewsPost_put_character,
  160.     NewsPost_put_string,
  161.     NewsPost_put_block
  162. };
  163. PUBLIC HTStream * HTNewsPost_new (HTRequest * request, HTStream * target)
  164. {
  165.     HTStream * me;
  166.     if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
  167.         HT_OUTOFMEM("NewsPost_new");
  168.     me->isa = &NewsPostClass;
  169.     me->target = target;
  170.     me->request = request;
  171.     me->buffer = HTChunk_new(256);
  172.     me->transparent = NO;
  173.     return HTMIMERequest_new(request, me, YES);
  174. }