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

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

Webmaster