Annotation of libwww/Library/src/HTNewsRq.c, revision 2.10
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 */
2.10 ! frystyk 12: #include "sysdep.h"
2.1 frystyk 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 {
2.10 ! frystyk 26: const HTStreamClass * isa;
2.1 frystyk 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;
2.10 ! frystyk 50: const char *mailaddress = HTGetMailAddress();
2.1 frystyk 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.8 frystyk 77: HT_FREE(newsgroup);
2.1 frystyk 78: }
2.8 frystyk 79: HT_FREE(access);
2.1 frystyk 80: }
81:
82: /* DO FOR ALL SUB ANCHOR DESTINATION S AS WELL */
83:
84: }
2.9 eric 85: if (PROT_TRACE) HTTrace("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:
2.10 ! frystyk 106: PRIVATE int NewsPost_put_block (HTStream * me, const char* b, int l)
2.1 frystyk 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:
2.10 ! frystyk 129: PRIVATE int NewsPost_put_string (HTStream * me, const char * s)
2.1 frystyk 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.8 frystyk 153: HT_FREE(me);
2.1 frystyk 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.8 frystyk 161: HT_FREE(me);
2.9 eric 162: if (PROT_TRACE) HTTrace("NewsPost.... ABORTING...\n");
2.1 frystyk 163: return HT_ERROR;
164: }
165:
166: /* NewsPost Stream
167: ** -----------------
168: */
2.10 ! frystyk 169: PRIVATE const HTStreamClass NewsPostClass =
2.1 frystyk 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: {
2.8 frystyk 182: HTStream * me;
183: if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
184: HT_OUTOFMEM("NewsPost_new");
2.1 frystyk 185: me->isa = &NewsPostClass;
186: me->target = target;
187: me->request = request;
2.6 frystyk 188: me->buffer = HTChunk_new(256);
2.1 frystyk 189: me->transparent = NO;
2.7 frystyk 190: return HTMIMERequest_new(request, me, YES);
2.1 frystyk 191: }
Webmaster