Annotation of libwww/Library/src/HTNewsRq.c, revision 2.1
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;
! 29: SOCKFD sockfd;
! 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);
! 53: HTChunkPuts(header, linebuf);
! 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: */
! 61: HTChunkPuts(header, "Newsgroups :");
! 62: if (HTRequest_isDestination(request)) {
! 63: HTRequest *src_req = HTRequest_source(request);
! 64: HTParentAnchor *src_anchor = HTRequest_anchor(src_req);
! 65: HTLink *link = HTAnchor_findMainLink(src_anchor);
! 66: HTAnchor *dest = HTAnchor_linkDest(link);
! 67: HTMethod method = HTAnchor_linkMethod(link);
! 68: if (link && method == METHOD_POST &&
! 69: HTAnchor_linkResult(link) == HT_LINK_NONE) {
! 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);
! 76: HTChunkPuts(header, newsgroup);
! 77: free(newsgroup);
! 78: }
! 79: free(access);
! 80: }
! 81:
! 82: /* DO FOR ALL SUB ANCHOR DESTINATION S AS WELL */
! 83:
! 84: }
! 85: if (PROT_TRACE) fprintf(TDEST, "News Tx..... %s", HTChunkData(header));
! 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);
! 115: if ((status = PUTBLOCK(HTChunkData(me->buffer),
! 116: HTChunkSize(me->buffer))) == HT_OK) {
! 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;
! 152: HTChunkFree(me->buffer);
! 153: free(me);
! 154: return status;
! 155: }
! 156:
! 157: PRIVATE int NewsPost_abort (HTStream * me, HTError e)
! 158: {
! 159: if (me->target) (*me->target->isa->abort)(me->target, e);
! 160: HTChunkFree(me->buffer);
! 161: free(me);
! 162: if (PROT_TRACE) fprintf(TDEST, "NewsPost.... ABORTING...\n");
! 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;
! 187: me->buffer = HTChunkCreate(256);
! 188: me->transparent = NO;
! 189: return HTMIMERequest_new(request, me); /* @@@ */
! 190: }
Webmaster