/* HTNewsDir_new ** ---------- ** Creates a structured stream object and sets up the initial HTML stuff ** Returns the newsdir object if OK, else NULL */ PUBLIC HTNewsDir * HTNewsDir_new (HTRequest * request, const char * title, HTNewsDirKey key, BOOL cache) { HTNewsDir *dir; if (!request) return NULL; /* Create object */ if ((dir = (HTNewsDir *) HT_CALLOC(1, sizeof (HTNewsDir))) == NULL) HT_OUTOFMEM("HTNewsDir_new"); dir->target = HTMLGenerator(request, NULL, WWW_HTML, HTRequest_outputFormat(request), HTRequest_outputStream(request)); HTAnchor_setFormat(HTRequest_anchor(request), WWW_HTML); dir->request = request; dir->key = key; dir->lastLevel = -1; /* Added by MP. */ /* Get the newsgroup(s) name; added by MP. */ { char* url = HTAnchor_physical(HTRequest_anchor(request)); char* p = url+strlen(url); while (p > url && p[-1] != ':' && p[-1] != '/' && p[-1] != '\\') p--; StrAllocCopy (dir->name, p); } if (key != HT_NDK_NONE) { /* Thread is unsorted */ int total = HTNews_maxArticles(); dir->array = HTArray_new(total > 0 ? total : 128); } /* If we are asked to prepare a cache entry then create the cache array */ if (cache) { int total = HTNews_maxArticles(); dir->cache = HTArray_new(total > 0 ? total : 128); } /* Start the HTML stuff */ { HTStructured *target = dir->target; const char *msg = title ? title : "News Listing"; START(HTML_HTML); START(HTML_HEAD); START(HTML_TITLE); PUTS(msg); END(HTML_TITLE); END(HTML_HEAD); START(HTML_BODY); START(HTML_H1); PUTS(msg); END(HTML_H1); } return dir; }
/* ** LOCK requests */ PRIVATE BOOL lock_request (Cmdline * arg) { HTDAVHeaders * headers = HTDAVHeaders_new(); HTRequest * request = create_request (); HTAnchor * dst = HTAnchor_findAddress(arg->request_uri); HTParentAnchor * src = NULL; HTParentAnchor * base = NULL; BOOL status = NO; char * data = NULL; if (arg->I) { HTPrint ("Adding If header %s\n",arg->I); HTDAV_setIfHeader (headers,arg->I); } if (arg->arg1) { data = create_body (arg->arg1); HTPrint ("xml body %s\n",data); /* chose the func */ if (arg->func==1) { src = HTTmpAnchor(NULL); HTAnchor_setDocument(src, data); HTAnchor_setFormat(src, HTAtom_for ("text/xml")); HTAnchor_setLength(src, strlen(data)); } } if (arg->base_str && *(arg->base_str)) base = (HTParentAnchor *) HTAnchor_findAddress(arg->base_str); if (arg->D) HTDAV_setDepthHeader (headers,arg->D); if (arg->T) HTDAV_setTimeoutHeader (headers,arg->T); HTPrint ("function %d src? %s\n",arg->func,(src)?"yes":"no"); switch (arg->func) { case 1: status = HTLOCKDocumentAnchor (request,dst,src,headers); break; case 2: status = HTLOCKAnchor (request,dst,data,headers); break; case 3: status = HTLOCKAbsolute (request,arg->request_uri,data,headers); break; case 4: status = HTLOCKRelative (request,arg->request_uri,base,data,headers); break; } return status; }
/* ** MOVE requests */ PRIVATE BOOL move_request ( Cmdline * arg ) { HTDAVHeaders * headers = HTDAVHeaders_new(); HTRequest * request = create_request (); HTAnchor * src = HTAnchor_findAddress(arg->request_uri); HTParentAnchor * body = NULL; HTParentAnchor * base = NULL; BOOL status = NO; if (arg->arg1) { HTPrint ("Adding Destination header %s\n",arg->arg1); HTDAV_setDestinationHeader (headers,arg->arg1); } if (arg->I) { HTPrint ("Adding If header %s\n",arg->I); HTDAV_setIfHeader (headers,arg->I); } /* chose the func */ if (arg->func==2 && arg->arg2 ) { body = HTTmpAnchor(NULL); HTAnchor_setDocument(body, arg->arg2); HTAnchor_setFormat(body, HTAtom_for ("text/xml")); HTAnchor_setLength(body, strlen(arg->arg2)); } if (arg->base_str && *(arg->base_str)) base = (HTParentAnchor *) HTAnchor_findAddress(arg->base_str); if (arg->D) HTDAV_setDepthHeader (headers,arg->D); if (arg->O == 'T') HTDAV_setOverwriteHeader (headers,YES); else if (arg->O == 'F') HTDAV_setOverwriteHeader (headers,NO); switch (arg->func) { case 1: status = HTMOVEAnchor (request,src,arg->arg2,headers); break; case 2: status = HTMOVEDocumentAnchor (request,src,body,headers); break; case 3: status = HTMOVEAbsolute (request,arg->request_uri,arg->arg2, headers); break; case 4: status = HTMOVERelative (request,arg->request_uri,base,arg->arg2,headers); break; } return status; }
/* ** PROPPATCH requests */ PRIVATE BOOL proppatch_request (Cmdline * arg) { BOOL status = NO; HTDAVHeaders * headers = HTDAVHeaders_new(); HTRequest * request = create_request (); HTAnchor * dst = HTAnchor_findAddress(arg->request_uri); HTParentAnchor *base = NULL; HTParentAnchor *src = NULL; char * xmlbody = NULL; if (arg->arg1 && *(arg->arg1)) xmlbody = arg->arg1; else return NO; HTPrint ("xml body **%s**\n",xmlbody); if (arg->func==2) { src = HTTmpAnchor(NULL); HTAnchor_setDocument(src, xmlbody); HTAnchor_setFormat(src, HTAtom_for ("text/xml")); HTAnchor_setLength(src, strlen(xmlbody)); } if (arg->base_str && *(arg->base_str)) base = (HTParentAnchor *) HTAnchor_findAddress(arg->base_str); HTPrint ("setting headers\n"); if (arg->I && *(arg->I)) { HTPrint ("Adding If header %s\n",arg->I); HTDAV_setIfHeader (headers,arg->I); } HTPrint ("Chosing func\n"); switch (arg->func) { case 1: status = HTPROPPATCHAnchor (request,dst,xmlbody,headers); break; case 2: status = HTPROPPATCHDocumentAnchor (request,dst,src,headers); break; case 3: status = HTPROPPATCHAbsolute (request,arg->request_uri,xmlbody,headers); break; case 4: status = HTPROPPATCHRelative (request,arg->request_uri,base,xmlbody,headers); break; } return status; }
/* ** PROPFIND requests */ PRIVATE BOOL propfind_request (Cmdline * arg) { BOOL status = NO; HTDAVHeaders * headers = HTDAVHeaders_new(); HTRequest * request = create_request (); HTAnchor * dst = HTAnchor_findAddress(arg->request_uri); HTParentAnchor *base = NULL; HTParentAnchor *src = NULL; char * xmlbody = NULL; /* chose the func */ HTPrint ("should we set the xml body?\n"); if (arg->arg1 && *(arg->arg1)) { if (!strcasecomp (arg->arg1,"allprop") || !strcasecomp (arg->arg1,"propname")) xmlbody = create_propbody (arg->arg1); else xmlbody = arg->arg1; HTPrint ("xml body %s\n",xmlbody); } if (arg->func==2 && xmlbody && *xmlbody) { src = HTTmpAnchor(NULL); HTAnchor_setDocument(src, xmlbody); HTAnchor_setFormat(src, HTAtom_for ("text/xml")); HTAnchor_setLength(src, strlen(xmlbody)); } if (arg->base_str && *(arg->base_str)) base = (HTParentAnchor *) HTAnchor_findAddress(arg->base_str); HTPrint ("setting headers\n"); if (arg->D) HTDAV_setDepthHeader (headers,arg->D); switch (arg->func) { case 1: status = HTPROPFINDAnchor (request,dst,xmlbody,headers); break; case 2: status = HTPROPFINDDocumentAnchor (request,dst,src,headers); break; case 3: status = HTPROPFINDAbsolute (request,arg->request_uri,xmlbody,headers); break; case 4: status = HTPROPFINDRelative (request,arg->request_uri,base,xmlbody,headers); break; } return status; }
/* ** Use the set of bindings to find the combination of language, ** media type and encoding of a given object. This information can either be ** stored in the anchor obejct or in the response object depending on which ** function is called. ** ** We comprise here as bindings only can have one language and one encoding. ** If more than one suffix is found they are all searched. The last suffix ** has highest priority, the first one lowest. See also HTBind_getFormat() */ PUBLIC BOOL HTBind_getAnchorBindings (HTParentAnchor * anchor) { BOOL status = NO; double quality=1.0; /* @@@ Should we add this into the anchor? */ if (anchor) { char *addr = HTAnchor_address((HTAnchor *) anchor); char *path = HTParse(addr, "", PARSE_PATH+PARSE_PUNCTUATION); char *file; char *end; if ((end = strchr(path, ';')) || (end = strchr(path, '?')) || (end = strchr(path, '#'))) *end = '\0'; if ((file = strrchr(path, '/'))) { HTFormat format = NULL; HTEncoding encoding = NULL; HTEncoding transfer = NULL; HTLanguage language = NULL; HTTRACE(BIND_TRACE, "Anchor...... Get bindings for `%s\'\n" _ path); status = HTBind_getFormat(file, &format, &encoding, &transfer, &language, &quality); if (status) { HTAnchor_setFormat(anchor, format); HTAnchor_setContentTransferEncoding(anchor, transfer); HTAnchor_deleteEncodingAll(anchor); HTAnchor_addEncoding(anchor, encoding); HTAnchor_deleteLanguageAll(anchor); HTAnchor_addLanguage(anchor, language); } } HT_FREE(addr); HT_FREE(path); } return status; }
int main (int argc, char ** argv) { HTRequest * request = NULL; HTParentAnchor * src = NULL; HTAnchor * dst = NULL; char * dst_str = NULL; char * data = NULL; BOOL status = NO; /* Create a new premptive client */ HTProfile_newNoCacheClient("libwww-POST", "1.0"); /* Need our own trace and print functions */ HTPrint_setCallback(printer); HTTrace_setCallback(tracer); /* Add our own filter to update the history list */ HTNet_addAfter(terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); /* Handle command line args */ if (argc >= 3) { dst_str = argv[1]; data = argv[2]; } else { HTPrint("Type the URI of the destination you want to POST to and the contents that you want to post.\n"); HTPrint("\t%s <destination> <data>\n", argv[0]); HTPrint("For example, %s http://myserver/destination.html \"This is some testdata\"\n", argv[0]); return -1; } if (data && *data && dst_str && *dst_str) { /* Make source relative to where we are */ char * cwd = HTGetCurrentDirectoryURL(); HTPrint("Posting to %s\n", dst_str); /* Create a request */ request = HTRequest_new(); /* Get an anchor object for the destination URI */ dst = HTAnchor_findAddress(dst_str); /* ** Dream up a source anchor (an editor can for example use this). ** After creation we associate the data that we want to post and ** set some metadata about what the data is. More formats can be found ** ../src/HTFormat.html */ src = HTTmpAnchor(NULL); HTAnchor_setDocument(src, data); HTAnchor_setFormat(src, WWW_PLAINTEXT); /* ** If not posting to an HTTP/1.1 server then content length MUST be ** there. If HTTP/1.1 then it doesn't matter as we just use chunked ** encoding under the covers */ HTAnchor_setLength(src, strlen(data)); /* POST the source to the dest */ status = HTPostAnchor(src, dst, request); /* We don't need these anymore */ HT_FREE(cwd); /* Go into the event loop... */ if (status == YES) HTEventList_loop(request); } return 0; }
PRIVATE void HTML_start_element (HTStructured * me, int element_number, const BOOL * present, const char ** value) { HTChildAnchor * address = NULL; if (!me->started) { HTextImp_build(me->text, HTEXT_BEGIN); me->started = YES; } /* Look at what element was started */ switch (element_number) { case HTML_A: if (present[HTML_A_HREF] && value[HTML_A_HREF]) { address = HTAnchor_findChildAndLink( me->node_anchor, /* parent */ present[HTML_A_NAME] ? value[HTML_A_NAME] : NULL, /* Tag */ value[HTML_A_HREF], /* Addresss */ present[HTML_A_REL] && value[HTML_A_REL] ? (HTLinkType) HTAtom_caseFor(value[HTML_A_REL]) : NULL); if (present[HTML_A_TITLE] && value[HTML_A_TITLE]) { HTLink * link = HTAnchor_mainLink((HTAnchor *) address); HTParentAnchor * dest = HTAnchor_parent(HTLink_destination(link)); if (!HTAnchor_title(dest)) HTAnchor_setTitle(dest, value[HTML_A_TITLE]); } HTextImp_foundLink(me->text, element_number, HTML_A_HREF, address, present, value); HTTRACE(SGML_TRACE, "HTML Parser. Anchor `%s\'\n" _ value[HTML_A_HREF]); } break; case HTML_AREA: if (present[HTML_AREA_HREF] && value[HTML_AREA_HREF]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_AREA_HREF], NULL); HTextImp_foundLink(me->text, element_number, HTML_AREA_HREF, address, present, value); HTTRACE(SGML_TRACE, "HTML Parser. Image map area `%s\'\n" _ value[HTML_AREA_HREF]); } break; case HTML_BASE: if (present[HTML_BASE_HREF] && value[HTML_BASE_HREF]) { HTAnchor_setBase(me->node_anchor, (char *) value[HTML_BASE_HREF]); HTTRACE(SGML_TRACE, "HTML Parser. New base `%s\'\n" _ value[HTML_BASE_HREF]); } break; case HTML_BODY: if (present[HTML_BODY_BACKGROUND] && value[HTML_BODY_BACKGROUND]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_BODY_BACKGROUND], NULL); HTextImp_foundLink(me->text, element_number, HTML_BODY_BACKGROUND, address, present, value); HTTRACE(SGML_TRACE, "HTML Parser. Background `%s\'\n" _ value[HTML_BODY_BACKGROUND]); } break; case HTML_FORM: if (present[HTML_FORM_ACTION] && value[HTML_FORM_ACTION]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_FORM_ACTION], NULL); HTextImp_foundLink(me->text, element_number, HTML_FORM_ACTION, address, present, value); } break; case HTML_FRAME: if (present[HTML_FRAME_SRC] && value[HTML_FRAME_SRC]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_FRAME_SRC], NULL); HTextImp_foundLink(me->text, element_number, HTML_FRAME_SRC, address, present, value); HTTRACE(SGML_TRACE, "HTML Parser. Frame `%s\'\n" _ value[HTML_FRAME_SRC]); } break; case HTML_INPUT: if (present[HTML_INPUT_SRC] && value[HTML_INPUT_SRC]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_INPUT_SRC], NULL); HTextImp_foundLink(me->text, element_number, HTML_INPUT_SRC, address, present, value); } break; case HTML_IMG: if (present[HTML_IMG_SRC] && value[HTML_IMG_SRC]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_IMG_SRC], NULL); HTextImp_foundLink(me->text, element_number, HTML_IMG_SRC, address, present, value); } break; case HTML_ISINDEX: HTAnchor_setIndex(me->node_anchor); break; case HTML_LINK: if (present[HTML_LINK_HREF] && value[HTML_LINK_HREF]) { HTParentAnchor * dest = NULL; address = HTAnchor_findChildAndLink( me->node_anchor, /* parent */ present[HTML_A_NAME] ? value[HTML_A_NAME] : NULL, /* Tag */ present[HTML_A_HREF] ? value[HTML_A_HREF] : NULL, /* Addresss */ NULL); /* Rels */ dest = HTAnchor_parent(HTAnchor_followMainLink((HTAnchor *) address)); /* If forward reference */ if ((present[HTML_LINK_REL] && value[HTML_LINK_REL])) { char * strval = NULL; char * ptr = NULL; char * relation = NULL; StrAllocCopy(strval, value[HTML_LINK_REL]); ptr = strval; while ((relation = HTNextLWSToken(&ptr)) != NULL) { HTLink_add((HTAnchor *) me->node_anchor, (HTAnchor *) dest, (HTLinkType) HTAtom_caseFor(relation), METHOD_INVALID); } HT_FREE(strval); } /* If reverse reference */ if ((present[HTML_LINK_REV] && value[HTML_LINK_REV])) { char * strval = NULL; char * ptr = NULL; char * relation = NULL; StrAllocCopy(strval, value[HTML_LINK_REV]); ptr = strval; while ((relation = HTNextLWSToken(&ptr)) != NULL) { HTLink_add((HTAnchor *) dest, (HTAnchor *) me->node_anchor, (HTLinkType) HTAtom_caseFor(relation), METHOD_INVALID); } HT_FREE(strval); } /* If we got any type information as well */ if (present[HTML_LINK_TYPE] && value[HTML_LINK_TYPE]) { if (HTAnchor_format(dest) == WWW_UNKNOWN) HTAnchor_setFormat(dest, (HTFormat) HTAtom_caseFor(value[HTML_LINK_TYPE])); } /* Call out to the layout engine */ HTextImp_foundLink(me->text, element_number, HTML_LINK_HREF, address, present, value); } break; case HTML_META: if (present[HTML_META_NAME] && value[HTML_META_NAME]) { HTAnchor_addMeta (me->node_anchor, value[HTML_META_NAME], (present[HTML_META_CONTENT] && value[HTML_META_CONTENT]) ? value[HTML_META_CONTENT] : ""); } break; case HTML_OBJECT: if (present[HTML_OBJECT_CLASSID] && value[HTML_OBJECT_CLASSID]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_OBJECT_CLASSID], NULL); HTextImp_foundLink(me->text, element_number, HTML_OBJECT_CLASSID, address, present, value); } if (present[HTML_OBJECT_CODEBASE] && value[HTML_OBJECT_CODEBASE]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_OBJECT_CODEBASE], NULL); HTextImp_foundLink(me->text, element_number, HTML_OBJECT_CODEBASE, address, present, value); } if (present[HTML_OBJECT_DATA] && value[HTML_OBJECT_DATA]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_OBJECT_DATA], NULL); HTextImp_foundLink(me->text, element_number, HTML_OBJECT_DATA, address, present, value); } if (present[HTML_OBJECT_ARCHIVE] && value[HTML_OBJECT_ARCHIVE]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_OBJECT_ARCHIVE], NULL); HTextImp_foundLink(me->text, element_number, HTML_OBJECT_ARCHIVE, address, present, value); } if (present[HTML_OBJECT_USEMAP] && value[HTML_OBJECT_USEMAP]) { address = HTAnchor_findChildAndLink(me->node_anchor, NULL, value[HTML_OBJECT_USEMAP], NULL); HTextImp_foundLink(me->text, element_number, HTML_OBJECT_USEMAP, address, present, value); } break; case HTML_PRE: if (me->comment_end) HTextImp_addText(me->text, me->comment_end, strlen(me->comment_end)); break; case HTML_TITLE: HTChunk_truncate(me->title,0); break; } /* Update our parse stack */ if (SGML_findTagContents(me->dtd, element_number) != SGML_EMPTY) { if (me->sp == me->stack) { HTTRACE(SGML_TRACE, "HTML Parser. Maximum nesting of %d exceded!\n" _ MAX_NESTING); me->overflow++; return; } --(me->sp); me->sp[0] = element_number; } /* Call out to the layout engine */ HTextImp_beginElement(me->text, element_number, present, value); }
PRIVATE int NewsEvent (SOCKET soc, void * pVoid, HTEventType type) { news_info *news = (news_info *)pVoid; int status = HT_ERROR; HTNet * net = news->net; HTRequest * request = HTNet_request(net); HTParentAnchor * anchor = HTRequest_anchor(request); char * url = HTAnchor_physical(anchor); HTHost * host = HTNet_host(net); /* ** Initiate a new nntp structure and bind to request structure ** This is actually state NNTP_BEGIN, but it can't be in the state ** machine as we need the structure first. */ if (type == HTEvent_CLOSE) { /* Interrupted */ HTRequest_addError(request, ERR_FATAL, NO, HTERR_INTERRUPTED, NULL, 0, "HTLoadHTTP"); HTNewsCleanup(request, HT_INTERRUPTED); return HT_OK; } else news = (news_info *) HTNet_context(net); /* Get existing copy */ /* Now jump into the machine. We know the state from the previous run */ while (1) { switch (news->state) { case NEWS_BEGIN: news->state = (!strchr(url, '@') && strchr(url, '*')) ? NEWS_SEEK_CACHE : NEWS_NEED_CONNECTION; break; case NEWS_SEEK_CACHE: if (HTNewsCache_before(request, NULL, 0) == HT_LOADED) news->state = NEWS_SUCCESS; else news->state = NEWS_NEED_CONNECTION; break; case NEWS_NEED_CONNECTION: /* Let's set up a connection */ if (!strncasecomp(url, "news:", 5)) { HTUserProfile * up = HTRequest_userProfile(request); char * newshost = HTUserProfile_news(up); StrAllocCopy(news->name, url+5); if (newshost) { char *newshack = NULL; /* Then we can use HTParse :-) */ StrAllocCopy(newshack, "news://"); StrAllocCat(newshack, newshost); status = HTHost_connect(host, net, (char *) newshack); host = HTNet_host(net); HT_FREE(newshack); } else news->state = NEWS_ERROR; } else if (!strncasecomp(url, "nntp:", 5)) { news->name = HTParse(url, "", PARSE_PATH); status = HTHost_connect(host, net, url); host = HTNet_host(net); } else { HTTRACE(PROT_TRACE, "News........ Huh?"); news->state = NEWS_ERROR; } if (status == HT_OK) { BOOL greeting = NO; /* Set up the persistent connection */ if (!HTNet_persistent(net)) { HTNet_setPersistent(net, YES, HT_TP_SINGLE); greeting = YES; } /* ** Check the protocol class to see if we have connected to a ** the right class of server, in this case HTTP. */ { HTHost * host = HTNet_host(net); char * s_class = HTHost_class(host); if (s_class && strcasecomp(s_class, "nntp")) { HTRequest_addError(request, ERR_FATAL, NO, HTERR_CLASS, NULL, 0, "HTLoadNews"); news->state = NEWS_ERROR; break; } HTHost_setClass(host, "nntp"); } /* ** Create the stream pipe FROM the channel to the application. ** The target for the input stream pipe is set up using the ** stream stack. */ { HTStream * rstream = HTNewsStatus_new(request, news, host); HTNet_setReadStream(net, rstream); HTRequest_setOutputConnected(request, YES); } /* ** Create the stream pipe TO the channel from the application ** and hook it up to the request object */ { HTOutputStream * output = HTNet_getOutput(net, NULL, 0); HTRequest_setInputStream(request, (HTStream *) output); } news->state = greeting ? NEWS_NEED_GREETING : NEWS_NEED_SWITCH; } else if (status == HT_WOULD_BLOCK || status == HT_PENDING) return HT_OK; else news->state = NEWS_ERROR; break; case NEWS_NEED_GREETING: status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_LOADED) { if (news->repcode/100 == 2) news->state = NEWS_NEED_SWITCH; else news->state = NEWS_ERROR; } else news->state = NEWS_ERROR; break; case NEWS_NEED_SWITCH: { HTMethod method = HTRequest_method(request); /* ** Find out what to ask the news server. Syntax of address is ** xxx@yyy Article ** <xxx@yyy> Same article ** xxxxx News group (no "@") */ if (method == METHOD_GET) { if (strchr(url, '@')) { /* ARTICLE */ if (*(news->name) != '<') { /* Add '<' and '>' */ char *newart; if ((newart = (char *) HT_MALLOC(strlen(news->name)+3)) == NULL) HT_OUTOFMEM("HTLoadNews"); sprintf(newart, "<%s>", news->name); HT_FREE(news->name); news->name = newart; } news->state = NEWS_NEED_ARTICLE; } else if (strchr(url, '*')) news->state = NEWS_NEED_LIST; else news->state = NEWS_NEED_GROUP; } else if (method == METHOD_POST) news->state = NEWS_NEED_POST; else { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_IMPLEMENTED,NULL, 0,"HTLoadNews"); news->state = NEWS_ERROR; } HTUnEscape(news->name); HTCleanTelnetString(news->name); } break; case NEWS_NEED_ARTICLE: if (!news->sent) { status = SendCommand(request, news, "ARTICLE", news->name); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_ERROR) news->state = NEWS_ERROR; news->format = WWW_MIME; /* ** Set the default content type to plain text as news servers ** almost never send any useful information about the length ** of the body or the type - the success of MIME! */ HTAnchor_setFormat(anchor, WWW_PLAINTEXT); news->sent = YES; } else { status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_OK) news->state = NEWS_NEED_BODY; else if (status == HT_LOADED) { news->state = (news->repcode/100 == 2) ? NEWS_SUCCESS : NEWS_ERROR; } else news->state = NEWS_ERROR; news->sent = NO; } break; #if HT_LISTGROUP case NEWS_NEED_LGRP: if (!news->sent) { status = SendCommand(request, news, "LIST", "NEWSGROUPS"); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_ERROR) news->state = NEWS_ERROR; news->format = WWW_NNTP_LIST; news->sent = YES; } else { status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_OK) news->state = NEWS_NEED_BODY; else if (status == HT_LOADED) { news->state = (news->repcode/100 == 2) ? NEWS_SUCCESS : NEWS_NEED_LIST; } else news->state = NEWS_ERROR; news->sent = NO; } break; #endif /* HT_LISTGROUP */ case NEWS_NEED_LIST: if (!news->sent) { status = SendCommand(request, news, "LIST", NULL); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_ERROR) news->state = NEWS_ERROR; news->format = WWW_NNTP_LIST; news->sent = YES; } else { status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_OK) news->state = NEWS_NEED_BODY; else if (status == HT_LOADED) { news->state = (news->repcode/100 == 2) ? NEWS_SUCCESS : NEWS_ERROR; } else news->state = NEWS_ERROR; news->sent = NO; } break; case NEWS_NEED_GROUP: if (!news->sent) { status = SendCommand(request, news, "GROUP", news->name); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_ERROR) news->state = NEWS_ERROR; news->sent = YES; } else { status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_LOADED) { if (news->repcode/100 == 2) { if (sscanf(news->reply, "%d%d%d", &news->total, &news->first, &news->last) == 3) { if (MaxArt && news->total>MaxArt) news->last = news->first-MaxArt; news->current = news->first; /* If no content in this group */ if (news->first == news->last) { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NO_CONTENT, NULL, 0, "HTLoadNews"); news->state = NEWS_NO_DATA; break; } news->state = NEWS_NEED_XOVER; } else news->state = NEWS_ERROR; } else news->state = NEWS_ERROR; } else news->state = NEWS_ERROR; news->sent = NO; } break; case NEWS_NEED_XOVER: if (!news->sent) { char buf[20]; sprintf(buf, "%d-%d", news->first, news->last); status = SendCommand(request, news, "XOVER", buf); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_ERROR) news->state = NEWS_ERROR; news->format = WWW_NNTP_OVER; news->sent = YES; } else { status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_OK) news->state = NEWS_NEED_BODY; else if (status == HT_LOADED) { if (news->repcode/100 == 2) news->state = NEWS_SUCCESS; else { news->format = WWW_NNTP_HEAD; news->state = NEWS_NEED_HEAD; } } else news->state = NEWS_ERROR; news->sent = NO; } break; case NEWS_NEED_HEAD: if (!news->sent) { char buf[10]; sprintf(buf, "%d", news->current++); status = SendCommand(request, news, "HEAD", buf); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_ERROR) news->state = NEWS_ERROR; news->sent = YES; } else { status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_LOADED) { if (news->repcode/100 == 2) { if (news->current > news->last) news->state = NEWS_SUCCESS; } else news->state = NEWS_ERROR; } else news->state = NEWS_ERROR; news->sent = NO; } break; case NEWS_NEED_POST: { HTStream * oldinput = HTRequest_inputStream(request); HTStream * newinput = HTNewsPost_new(request, HTBuffer_new(oldinput, request,512)); HTRequest_setInputStream(request, newinput); /* Remember to convert to CRLF */ } news->state = NEWS_NEED_BODY; break; case NEWS_NEED_BODY: if (type == HTEvent_WRITE || type == HTEvent_BEGIN) { if (HTRequest_isDestination(request)) { HTRequest * source = HTRequest_source(request); HTNet * srcnet = HTRequest_net(source); if (srcnet) { HTHost_register(HTNet_host(srcnet), srcnet, HTEvent_READ); HTHost_unregister(HTNet_host(srcnet), srcnet, HTEvent_WRITE); } return HT_OK; } /* ** Should we use the input stream directly or call the post ** callback function to send data down to the network? */ { HTStream * input = HTRequest_inputStream(request); HTPostCallback * pcbf = HTRequest_postCallback(request); if (pcbf) { status = pcbf(request, input); if (status == HT_PAUSE || status == HT_LOADED) type = HTEvent_READ; } else { status = (*input->isa->flush)(input); type = HTEvent_READ; } if (status == HT_WOULD_BLOCK) return HT_OK; } status = request->PostCallback ? request->PostCallback(request, request->input_stream) : (*request->input_stream->isa->flush)(request->input_stream); if (status == HT_WOULD_BLOCK) return HT_OK; else type = HTEvent_READ; /* Trick to ensure that we do READ */ } else if (type == HTEvent_READ) { status = HTHost_read(HTNet_host(net), net); if (status == HT_WOULD_BLOCK) return HT_OK; else if (status == HT_LOADED) news->state = NEWS_SUCCESS; else news->state = NEWS_ERROR; } else { news->state = NEWS_ERROR; } break; case NEWS_SUCCESS: HTNewsCleanup(request, HT_LOADED); return HT_OK; break; case NEWS_NO_DATA: HTNewsCleanup(request, HT_NO_DATA); return HT_OK; break; case NEWS_ERROR: HTNewsCleanup(request, HT_NOT_FOUND); return HT_OK; break; } } /* End of while(1) */ }
/* HTDir_new ** --------- ** Creates a structured stream object and sets up the initial HTML stuff ** Returns the dir object if OK, else NULL */ PUBLIC HTDir * HTDir_new (HTRequest * request, HTDirShow show, HTDirKey key) { HTDir *dir; char *title = NULL; if (!request) return NULL; /* Create object */ if ((dir = (HTDir *) HT_CALLOC(1, sizeof (HTDir))) == NULL || (dir->fnbuf = (char *) HT_MALLOC(MaxFileW+HT_DLEN_SPACE)) == NULL) HT_OUTOFMEM("HTDir_new"); dir->target = HTMLGenerator(request, NULL, WWW_HTML, HTRequest_outputFormat(request), HTRequest_outputStream(request)); HTRequest_setOutputConnected(request, YES); HTAnchor_setFormat(HTRequest_anchor(request), WWW_HTML); dir->request = request; dir->show = show; dir->key = key; if (key==HT_DK_NONE) dir->curfw = MaxFileW; else { dir->curfw = MinFileW; dir->array = HTArray_new(256); } /* We're all OK */ HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0, "HTDir_new"); /* Find the length of the fields */ { int len = HT_DLEN_SPACE+1; if (show & HT_DS_SIZE) len += (HT_DLEN_SIZE+HT_DLEN_SPACE); if (show & HT_DS_DATE) len += (HT_DLEN_DATE+HT_DLEN_SPACE); if (show & HT_DS_DES) len += HT_DLEN_DES; if ((dir->lnbuf = (char *) HT_MALLOC(len)) == NULL) HT_OUTOFMEM("HTDir_new"); } /* Find the title and the base URL */ { char *addr = HTAnchor_address((HTAnchor *) HTRequest_anchor(request)); char *path = HTParse(addr, "", PARSE_PATH+PARSE_PUNCTUATION); char *ptr; if ((ptr = strchr(path, ';')) || (ptr = strchr(path, '?'))) *ptr = '\0'; StrAllocCopy(title, path); HTUnEscape(title); /* Title */ if((ptr=strrchr(path, '/')) && (ptr<path+strlen(path)-1 || ptr==path)){ StrAllocCopy(dir->base, ++ptr); StrAllocCat(dir->base, "/"); } HTTRACE(PROT_TRACE, "HTDir_new... base is `%s\'\n" _ dir->base ? dir->base : ""); HT_FREE(addr); HT_FREE(path); } /* Start the HTML stuff */ { HTStructured *target = dir->target; START(HTML_HTML); START(HTML_HEAD); START(HTML_TITLE); PUTS("Current index is "); PUTS(title); END(HTML_TITLE); END(HTML_HEAD); START(HTML_BODY); START(HTML_H1); PUTS("Index of "); PUTS(title); END(HTML_H1); } HT_FREE(title); return dir; }
BOOL CWinComDoc::SaveDocument() { CRequest * request = new CRequest(this); HTAnchor * source = NULL; HTAnchor * destination = NULL; // Create the source anchor char * src = HTParse(m_Location.m_source, m_cwd, PARSE_ALL); source = HTAnchor_findAddress(src); HT_FREE(src); /* If destination is not http://... then error */ if (!m_Location.m_destination.IsEmpty()) { char * access = HTParse(m_Location.m_destination, "", PARSE_ACCESS); if (strcasecomp(access, "http")) { CString strMessage; AfxFormatString1(strMessage, IDS_CANNOT_WRITE_TO_DESTINATION, m_Location.m_destination); AfxMessageBox(strMessage); HT_FREE(access); return FALSE; } else { char * dest = HTParse(m_Location.m_destination, m_cwd, PARSE_ALL); destination = HTAnchor_findAddress(dest); HT_FREE(dest); HT_FREE(access); } } // Do we have any metadata to set up? { HTParentAnchor * source_parent = HTAnchor_parent(source); if (!m_EntityInfo.m_mediaType.IsEmpty()) { HTAnchor_setFormat(source_parent, HTAtom_for(m_EntityInfo.m_mediaType)); } if (!m_EntityInfo.m_contentEncoding.IsEmpty()) { HTAnchor_deleteEncodingAll(source_parent); HTAnchor_addEncoding(source_parent, HTAtom_for(m_EntityInfo.m_contentEncoding)); } if (!m_EntityInfo.m_charset.IsEmpty()) { HTAnchor_setCharset(source_parent, HTAtom_for(m_EntityInfo.m_charset)); } if (!m_EntityInfo.m_language.IsEmpty()) { HTAnchor_deleteLanguageAll(source_parent); HTAnchor_addLanguage(source_parent, HTAtom_for(m_EntityInfo.m_language)); } } // Do we have any link relationships to set up? m_Links.AddLinkRelationships(source); /* Start the request */ if (m_detectVersionConflict) { char * etag = HTAnchor_etag(HTAnchor_parent(destination)); if (etag) { request->PutDocument(source, destination, HT_MATCH_THIS); } else { request->PutDocumentWithPrecheck(source, destination); } } else { request->PutDocument(source, destination, HT_NO_MATCH); } return TRUE; }