PUBLIC HTStream * HTRules (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream) { HTAlertCallback *cbf = HTAlert_find(HT_A_CONFIRM); /* ** If the library has been compiled so that we automatically accept ** rule files then it's OK not to ask the user. */ #ifdef HT_AUTOMATIC_RULES if (!cbf || (cbf && (*cbf)(request,HT_A_CONFIRM, HT_MSG_RULES, NULL,NULL,NULL))) { #else if ((cbf && (*cbf)(request,HT_A_CONFIRM, HT_MSG_RULES, NULL,NULL,NULL))) { #endif HTStream * me; HTTRACE(APP_TRACE, "Rule file... Parser object created\n"); if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTRules"); me->isa = &HTRuleClass; me->request = request; me->buffer = HTChunk_new(512); me->EOLstate = EOL_BEGIN; if (!rules) rules = HTList_new(); return me; } else { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NO_AUTO_RULES, NULL, 0, "HTRules"); return HTErrorStream(); } } /* ** Parse a rule file - don't ask don't tell - be carefull with this one! */ PUBLIC HTStream * HTRules_parseAutomatically (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream) { if (request) { HTStream * me; HTTRACE(APP_TRACE, "Rule file... Automatic parser object created\n"); if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTRules"); me->isa = &HTRuleClass; me->request = request; me->buffer = HTChunk_new(512); me->EOLstate = EOL_BEGIN; if (!rules) rules = HTList_new(); return me; } else { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NO_AUTO_RULES, NULL, 0, "HTRules"); return HTErrorStream(); } }
/* Structured Text object ** ---------------------- ** ** The structured stream can generate either presentation, ** or plain text, or HTML. */ PRIVATE HTStructured * HTML_new (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream) { HTStructured * me = NULL; if (request) { if ((me = (HTStructured *) HT_CALLOC(1, sizeof(HTStructured))) == NULL) HT_OUTOFMEM("HTML_new"); me->isa = &HTMLPresentation; me->dtd = HTML_dtd(); me->request = request; me->node_anchor = HTRequest_anchor(request); me->title = HTChunk_new(128); me->comment_start = NULL; me->comment_end = NULL; me->target = output_stream; me->sp = me->stack + MAX_NESTING - 1; /* Create the text object */ me->text = HTextImp_new(me->request, me->node_anchor, me->target); } return me; }
/* ** Check whether the application provides us with a cookie or more. */ PRIVATE int HTCookie_beforeFilter (HTRequest * request, void * param, int mode) { if ((CookieMode & HT_COOKIE_SEND) && FindCookie) { HTAssocList * cookies = (*FindCookie)(request, FindCookieContext); if (cookies) { HTChunk * cookie_header = HTChunk_new(64); HTAssocList * cur = cookies; HTAssoc * pres; BOOL first=YES; while ((pres = (HTAssoc *) HTAssocList_nextObject(cur))) { if (!first) HTChunk_putc(cookie_header, ';'); HTChunk_puts(cookie_header, HTAssoc_name(pres)); HTChunk_putc(cookie_header, '='); HTChunk_puts(cookie_header, HTAssoc_value(pres)); first = NO; } HTRequest_addExtraHeader(request, "Cookie", HTChunk_data(cookie_header)); HTChunk_delete(cookie_header); /* Also delete the association list */ HTAssocList_delete(cookies); } } return HT_OK; }
int optionsURL_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { if (argc == 2) { char *url = argv[1]; if (url) { HTRequest *req = HTRequest_new(); BOOL work; HTChunk *chunk = HTChunk_new(0x2000); HTStream *stream = HTStreamToChunk(req, &chunk, 0); HTRequest_setOutputFormat(req, DEFAULT_FORMAT); HTRequest_setOutputStream(req, stream); HTRequest_setPreemptive(req, YES); work = HTOptionsAbsolute(url, req); Tcl_AppendResult(interp, work ? "YES" : "NO", HTChunkData(chunk), NULL); HT_FREE(url); HTRequest_kill(req); HT_FREE(stream); HTChunkFree(chunk); return TCL_OK; } Tcl_AppendResult(interp, bad_vars, NULL); return TCL_ERROR; } else { Tcl_AppendResult(interp, err_string, argv[0], " url", NULL); return TCL_ERROR; } }
int postURL_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { if (argc == 3) { char *url = argv[1]; char *dest = argv[2]; if (url && dest) { HTParentAnchor *source = (HTParentAnchor *) HTAnchor_findAddress(url); HTRequest *req = HTRequest_new(); HTChunk *chunk = HTChunk_new(0x2000); HTStream *stream = HTStreamToChunk(req, &chunk, 0); BOOL work; HTRequest_setOutputFormat(req, DEFAULT_FORMAT); HTRequest_setOutputStream(req, stream); HTRequest_setPreemptive(req, YES); work = HTPostAbsolute (source, dest, req); Tcl_AppendResult(interp, work ? "YES" : "NO", HTChunkData(chunk), NULL); HT_FREE(url); HTRequest_kill(req); HTAnchor_delete(source); HT_FREE(stream); HTChunkFree(chunk); return TCL_OK; } Tcl_AppendResult(interp, bad_vars, NULL); return TCL_ERROR; } else { Tcl_AppendResult(interp, err_string, argv[0], " url destination", NULL); return TCL_ERROR; } }
/* Determine a suitable suffix ** --------------------------- ** Use the set of bindings to find a suitable suffix (or index) ** for a certain combination of language, media type and encoding ** given in the anchor. ** ** Returns a pointer to a suitable suffix string that must be freed ** by the caller. If more than one suffix is found they are all ** concatenated using the first delimiter in HTDelimiters. ** If no suffix is found, NULL is returned. */ PUBLIC char * HTBind_getSuffix (HTParentAnchor * anchor) { int cnt; HTList * cur; HTChunk * suffix = HTChunk_new(48); char delimiter = *HTDelimiters; char * ct=NULL, * ce=NULL, * cl=NULL; HTFormat format = HTAnchor_format(anchor); HTList * encoding = HTAnchor_encoding(anchor); HTList * language = HTAnchor_language(anchor); if (!HTBindings) HTBind_init(); if (anchor) { for (cnt=0; cnt<HT_L_HASH_SIZE; cnt++) { if ((cur = HTBindings[cnt])) { HTBind *pres; while ((pres = (HTBind *) HTList_nextObject(cur))) { if (!ct && (pres->type && pres->type == format)){ ct = pres->suffix; } else if (!ce && pres->encoding && encoding) { HTList * cur_enc = encoding; HTEncoding pres_enc; while ((pres_enc = (HTEncoding) HTList_nextObject(cur_enc))) { if (pres_enc == pres->encoding) { ce = pres->suffix; break; } } } else if (!cl && pres->language && language) { HTList * cur_lang = language; HTLanguage pres_lang; while ((pres_lang = (HTLanguage) HTList_nextObject(cur_lang))) { if (pres_lang == pres->language) { cl = pres->suffix; break; } } } } } } /* Put the found suffixes together */ if (ct) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, ct); } if (ce) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, ce); } if (cl) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, cl); } } return HTChunk_toCString(suffix); }
/* Create a chunk from an allocated string ** --------------------------------------- */ PUBLIC HTChunk * HTChunk_fromCString (char * str, int grow) { HTChunk * ch; ch = HTChunk_new(grow); if (str) { ch->data = str; /* can't handle non-allocated str */ ch->size = strlen(str); ch->allocated = ch->size + 1; /* [SIC] bobr */ } return ch; }
/* C O N S T R U C T O R S */ PUBLIC CSParse_t * CSParse_new(void) { CSParse_t * me; if ((me = (CSParse_t *) HT_CALLOC(1, sizeof(CSParse_t))) == NULL) HT_OUTOFMEM("CSParse"); me->nowIn = NowIn_NEEDOPEN; me->token = HTChunk_new(0x10); if ((me->pParseContext = (ParseContext_t *) HT_CALLOC(1, sizeof(ParseContext_t))) == NULL) HT_OUTOFMEM("ParseContext_t"); return me; }
/* Create a chunk from an allocated buffer ** --------------------------------------- */ PUBLIC HTChunk * HTChunk_fromBuffer (char * buf, int buflen, int size, int grow) { HTChunk * ch; ch = HTChunk_new(grow); if (buf) { ch->data = buf; ch->size = ch->allocated = buflen; if (size < buflen) HTChunk_setSize(ch, size); /* This ensures the end is 0-filled */ } return ch; }
PUBLIC HTStream * HTNewsPost_new (HTRequest * request, HTStream * target) { HTStream * me; if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("NewsPost_new"); me->isa = &NewsPostClass; me->target = target; me->request = request; me->buffer = HTChunk_new(256); me->transparent = NO; return HTMIMERequest_new(request, me, YES); }
PRIVATE HTStream * HTTPReceive_new (HTRequest * request, https_info * http) { HTStream * me; if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTTPReceive_new"); me->isa = &HTTPReceiveClass; me->request = request; me->http = http; me->state = EOL_BEGIN; me->buffer = HTChunk_new(128); /* Sufficiant for most URLs */ HTTRACE(STREAM_TRACE, "HTTP Request Stream %p created\n" _ me); return me; }
/* MIME header parser stream. ** ------------------------- ** This stream parses a complete MIME header and if a content type header ** is found then the stream stack is called. Any left over data is pumped ** right through the stream */ PUBLIC HTStream* HTMIMEConvert (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream) { HTStream * me; if ((me = (HTStream *) HT_CALLOC(1, sizeof(* me))) == NULL) HT_OUTOFMEM("HTMIMEConvert"); me->isa = &HTMIME; me->request = request; me->response = HTRequest_response(request); me->net = HTRequest_net(request); me->target = output_stream; me->target_format = output_format; me->save_stream = LocalSaveStream ? LocalSaveStream : HTBlackHoleConverter; me->token = HTChunk_new(256); me->value = HTChunk_new(256); me->hash = 0; me->EOLstate = EOL_BEGIN; me->haveToken = NO; return me; }
PUBLIC char * Range_toStr(Range_t * pRange) { HTChunk * pChunk; char * ptr; pChunk = HTChunk_new(20); ptr = FVal_toStr(&pRange->min); HTChunk_puts(pChunk, ptr); HT_FREE(ptr); if (FVal_initialized(&pRange->max)) { ptr = FVal_toStr(&pRange->max); HTChunk_puts(pChunk, ":"); HTChunk_puts(pChunk, ptr); HT_FREE(ptr); } return HTChunk_toCString(pChunk); }
/* Create SGML Engine ** ------------------ ** ** On entry, ** dtd represents the DTD, along with ** actions is the sink for the data as a set of routines. ** */ PUBLIC HTStream *SGML_new(const SGML_dtd * dtd, HTStructured * target) { int i; HTStream* context; if ((context = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("SGML_begin"); context->isa = &SGMLParser; context->string = HTChunk_new(128); /* Grow by this much */ context->dtd = dtd; context->target = target; context->actions = (HTStructuredClass*)(((HTStream*)target)->isa); /* Ugh: no OO */ context->state = S_text; for(i=0; i<MAX_ATTRIBUTES; i++) context->value[i] = 0; return context; }
PUBLIC int HTLoadNews (SOCKET soc, HTRequest * request) { news_info *news; HTParentAnchor *anchor = HTRequest_anchor(request); HTNet * net = HTRequest_net(request); char * url = HTAnchor_physical(anchor); HTTRACE(PROT_TRACE, "NNTP........ Looking for `%s\'\n" _ url); if ((news = (news_info *) HT_CALLOC(1, sizeof(news_info))) == NULL) HT_OUTOFMEM("HTLoadNews"); news->cmd = HTChunk_new(128); news->state = NEWS_BEGIN; news->net = net; HTNet_setContext(net, news); HTNet_setEventCallback(net, NewsEvent); HTNet_setEventParam(net, news); /* callbacks get http* */ return NewsEvent(soc, news, HTEvent_BEGIN); /* get it started - ops is ignored */ }
PUBLIC HTStream * HTStreamToChunk (HTRequest * request, HTChunk ** chunk, int max_size) { if (request) { HTStream * me; *chunk = NULL; if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTStreamToChunk"); me->isa = &HTStreamToChunkClass; me->request = request; me->max_size = (!max_size) ? max_size : HT_MAXSIZE; me->chunk = *chunk = HTChunk_new(me->max_size > 0 ? HTMIN(me->max_size, HT_MAXGROWSIZE) : HT_MAXGROWSIZE); HTTRACE(STREAM_TRACE, "ChunkStream. Chunk %p created with max size %d\n" _ me->chunk _ me->max_size); return me; } return HTErrorStream(); }
int main (int argc, char ** argv) { HTSQL * sql = NULL; char * sqlserver = DEFAULT_SQL_SERVER; char * sqldb = DEFAULT_SQL_DB; char * sqluser = DEFAULT_SQL_USER; char * sqlpw = DEFAULT_SQL_PW; char * cvsuser = DEFAULT_CVS_USER; time_t cvsdate = -1; FILE * fin = stdin; char * input_buffer[BUFSIZE]; HTChunk * loginfo = HTChunk_new(BUFSIZE); int arg = 0; BOOL create_db = YES; /* Initiate libwww */ HTLibInit(APP_NAME, APP_VERSION); /* Scan command line for parameters */ for (arg=1; arg<argc; arg++) { if (*argv[arg] == '-') { if (!strcmp(argv[arg], "-h") || !strcmp(argv[arg], "-?")) { VersionInfo(); Cleanup(0, sql, loginfo); } else if (!strcmp(argv[arg], "-v")) { HTSetTraceMessageMask("q"); } else if (!strcmp(argv[arg], "-nocreate")) { create_db = NO; } else if (!strncmp(argv[arg], "-sqldb", 5)) { sqldb = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_SQL_DB; } else if (!strncmp(argv[arg], "-sqlpassword", 5)) { sqlpw = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_SQL_PW; } else if (!strncmp(argv[arg], "-sqlserver", 5)) { sqlserver = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_SQL_SERVER; } else if (!strncmp(argv[arg], "-sqluser", 5)) { sqluser = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_SQL_USER; } else if (!strncmp(argv[arg], "-cvsuser", 5)) { cvsuser = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_CVS_USER; } else if (!strncmp(argv[arg], "-cvsdate", 5)) { cvsdate = (arg+1 < argc && *argv[arg+1] != '-') ? HTParseTime(argv[++arg], NULL, NO) : -1; } else { fprintf(stderr, "Bad Argument (%s)\n", argv[arg]); } } else { fprintf(stderr, "Bad Argument (%s)\n", argv[arg]); } } /* Get an SQL object */ if ((sql = HTSQL_new(sqlserver, sqluser, sqlpw, 0)) == NULL) Cleanup(-1, sql, loginfo); /* Connect to the SQL server */ if (HTSQL_connect(sql) != YES) Cleanup(-1, sql, loginfo); /* Select our database */ if (HTSQL_selectDB(sql, sqldb) != YES) Cleanup(-1, sql, loginfo); /* Create our tables */ if (create_db) createTables(sql, 0); /* Read the arguments from stdin */ for (;;) { int status = fread(input_buffer, 1, BUFSIZE, fin); if (status < 0) Cleanup(-1, sql, loginfo); if (status == 0) break; HTChunk_putb(loginfo, (const char *) input_buffer, status); } /* Parse the input chunk */ { char * ptr = HTChunk_data(loginfo); char * noop1 = HTNextField(&ptr); char * noop2 = HTNextField(&ptr); char * root = HTNextField(&ptr); char * operation = NULL; char * files = NULL; char * comment = NULL; int comment_id = -1; int user_id = -1; char * p, * q; #ifdef HT_REENTRANT char *lasts; /* For strtok_r */ #endif /* Find shared log message and get id */ if ((q = HTStrCaseStr(ptr, "\nLog Message:")) != NULL) { comment = q+14; *q = '\0'; } if ((comment_id = add_comment(sql, comment)) < 0) Cleanup(-1, sql, loginfo); /* Add/find user and get id */ if ((user_id = add_user(sql, cvsuser)) < 0) Cleanup(-1, sql, loginfo); /* For each operation, find the files involved */ while ((q = HTStrCaseStr(ptr, " Files:")) != NULL) { /* Find the operation */ files = q+9; for (p=q; p>HTChunk_data(loginfo) && *p && *p!='\n'; p--); p++; operation = HTNextField(&p); /* Find the next line */ if ((q = strchr(files, '\n')) != NULL) { *q++ = '\0'; ptr = q; } /* Create the query */ if (operation && files && comment) { char * file; int location_id = -1; #ifdef HT_REENTRANT if ((file = strtok_r(files, DELIMITERS, &lasts)) != NULL) { #else if ((file = strtok(files, DELIMITERS)) != NULL) { #endif /* HT_REENTRANT */ do { char * path = NULL; StrAllocMCopy(&path, root, "/", file, NULL); /* Add/find location and get id */ if ((location_id = add_location(sql, path)) < 0) { Cleanup(-1, sql, loginfo); break; } #if 0 fprintf(stderr, "location: `%s\', user: `%s\', operation: `%s\', comment: `%s\'\n", path, cvsuser, operation, comment); #endif /* Add log entry */ { char buf[16384]; char * query = HTSQL_printf(buf, 16384, "insert into %s values (%u,%u,%T,%S,%u)", DEFAULT_SQL_LOG_TABLE, location_id, user_id, cvsdate, operation, comment_id); if (HTSQL_query(sql, query) != YES) { Cleanup(-1, sql, loginfo); break; } } HT_FREE(path); #ifdef HT_REENTRANT } while ((file = (char *) strtok_r(NULL, DELIMITERS, &lasts)) != NULL); #else } while ((file = strtok(NULL, DELIMITERS)) != NULL); #endif /* HT_REENTRANT */ } } } } return 0; }
int main (int argc, char ** argv) { int status = 0; int arg; int tokencount = 0; BOOL formdata = NO; HTChunk * keywords = NULL; /* From command line */ HTAssocList*formfields = NULL; HTMethod method = METHOD_GET; /* Default value */ ComLine * cl = ComLine_new(); BOOL cache = NO; /* Use persistent cache */ BOOL flush = NO; /* flush the persistent cache */ char * cache_root = NULL; /* Starts Mac GUSI socket library */ #ifdef GUSI GUSISetup(GUSIwithSIOUXSockets); GUSISetup(GUSIwithInternetSockets); #endif #ifdef __MWERKS__ /* STR */ InitGraf((Ptr) &qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(nil); InitCursor(); SIOUXSettings.asktosaveonclose = false; argc=ccommand(&argv); #endif /* Initiate W3C Reference Library with a client profile */ HTProfile_newNoCacheClient(APP_NAME, APP_VERSION); /* Need our own trace and print functions */ HTPrint_setCallback(printer); HTTrace_setCallback(tracer); /* ** Delete the default Username/password handler so that we can handle ** parameters handed to us from the command line. The default is set ** by the profile. */ HTAlert_deleteOpcode(HT_A_USER_PW); HTAlert_add(PromptUsernameAndPassword, HT_A_USER_PW); /* ** Add default content decoder. We insert a through line as it doesn't ** matter that we get an encoding that we don't know. */ HTFormat_addCoding("*", HTIdentityCoding, HTIdentityCoding, 0.3); /* Scan command Line for parameters */ for (arg=1; arg<argc; arg++) { if (*argv[arg] == '-') { /* - alone => filter */ if (argv[arg][1] == '\0') { cl->flags |= CL_FILTER; /* -? or -help: show the command line help page */ } else if (!strcmp(argv[arg],"-?") || !strcmp(argv[arg],"-help")) { cl->anchor = (HTParentAnchor *) HTAnchor_findAddress(W3C_HELP); tokencount = 1; /* non-interactive */ } else if (!strcmp(argv[arg], "-n")) { HTAlert_setInteractive(NO); /* Treat the keywords as form data with a <name> "=" <value> */ } else if (!strcmp(argv[arg], "-form")) { formdata = YES; /* from -- Initial represntation (only with filter) */ } else if (!strcmp(argv[arg], "-from")) { cl->format = (arg+1 < argc && *argv[arg+1] != '-') ? HTAtom_for(argv[++arg]) : WWW_HTML; /* to -- Final representation */ } else if (!strcmp(argv[arg], "-to")) { HTFormat format = (arg+1 < argc && *argv[arg+1] != '-') ? HTAtom_for(argv[++arg]) : DEFAULT_FORMAT; HTRequest_setOutputFormat(cl->request, format); /* destination for PUT, POST etc. */ } else if (!strcmp(argv[arg], "-dest")) { if (arg+1 < argc && *argv[arg+1] != '-') { char * dest = HTParse(argv[++arg], cl->cwd, PARSE_ALL); cl->dest = (HTParentAnchor *) HTAnchor_findAddress(dest); HT_FREE(dest); } /* source please */ } else if (!strcmp(argv[arg], "-source")) { HTRequest_setOutputFormat(cl->request, WWW_RAW); /* log file */ } else if (!strcmp(argv[arg], "-l")) { cl->logfile = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_LOG_FILE; /* Max forward hops in case of TRACE request */ } else if (!strcmp(argv[arg], "-hops") || !strcmp(argv[arg], "-maxforwards")) { int hops = (arg+1 < argc && *argv[arg+1] != '-') ? atoi(argv[++arg]) : DEFAULT_HOPS; if (hops >= 0) HTRequest_setMaxForwards(cl->request, hops); /* automated authentication of format user:password@realm */ } else if (!strncmp(argv[arg], "-auth", 5)) { char * credentials = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : NULL; if (credentials) ParseCredentials(cl, credentials); /* rule file */ } else if (!strcmp(argv[arg], "-r")) { cl->rules = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_RULE_FILE; /* output filename */ } else if (!strcmp(argv[arg], "-o")) { cl->outputfile = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : DEFAULT_OUTPUT_FILE; /* timeout -- Change the default request timeout */ } else if (!strcmp(argv[arg], "-timeout")) { int timeout = (arg+1 < argc && *argv[arg+1] != '-') ? atoi(argv[++arg]) : DEFAULT_TIMEOUT; if (timeout >= 1) cl->timer = timeout*MILLIES; /* preemptive or non-preemptive access */ } else if (!strcmp(argv[arg], "-single")) { HTRequest_setPreemptive(cl->request, YES); /* content Length Counter */ } else if (!strcmp(argv[arg], "-cl")) { cl->flags |= CL_COUNT; /* print version and exit */ } else if (!strcmp(argv[arg], "-version")) { VersionInfo(argv[0]); Cleanup(cl, 0); /* run in quiet mode */ } else if (!strcmp(argv[arg], "-q")) { cl->flags |= CL_QUIET; /* Start the persistent cache */ } else if (!strcmp(argv[arg], "-cache")) { cache = YES; /* Determine the cache root */ } else if (!strcmp(argv[arg], "-cacheroot")) { cache_root = (arg+1 < argc && *argv[arg+1] != '-') ? argv[++arg] : NULL; /* Persistent cache flush */ } else if (!strcmp(argv[arg], "-flush")) { flush = YES; /* Do a cache validation */ } else if (!strcmp(argv[arg], "-validate")) { cl->flags |= CL_VALIDATE; /* Do an end-to-end cache-validation */ } else if (!strcmp(argv[arg], "-endvalidate")) { cl->flags |= CL_END_VALIDATE; /* Force complete reload */ } else if (!strcmp(argv[arg], "-nocache")) { cl->flags |= CL_CACHE_FLUSH; #ifdef WWWTRACE /* trace flags */ } else if (!strncmp(argv[arg], "-v", 2)) { HTSetTraceMessageMask(argv[arg]+2); #endif /* GET method */ } else if (!strcasecomp(argv[arg], "-get")) { method = METHOD_GET; /* HEAD method */ } else if (!strcasecomp(argv[arg], "-head")) { method = METHOD_HEAD; /* DELETE method */ } else if (!strcasecomp(argv[arg], "-delete")) { method = METHOD_DELETE; /* POST Method */ } else if (!strcasecomp(argv[arg], "-post")) { method = METHOD_POST; /* PUT Method */ } else if (!strcasecomp(argv[arg], "-put")) { method = METHOD_PUT; /* OPTIONS Method */ } else if (!strcasecomp(argv[arg], "-options")) { method = METHOD_OPTIONS; /* TRACE Method */ } else if (!strcasecomp(argv[arg], "-trace")) { method = METHOD_TRACE; } else { if (SHOW_MSG) HTPrint("Bad Argument (%s)\n", argv[arg]); } } else { /* If no leading `-' then check for URL or keywords */ if (!tokencount) { char * ref = HTParse(argv[arg], cl->cwd, PARSE_ALL); cl->anchor = (HTParentAnchor *) HTAnchor_findAddress(ref); tokencount = 1; HT_FREE(ref); } else if (formdata) { /* Keywords are form data */ char * string = argv[arg]; if (tokencount++ <= 1) formfields = HTAssocList_new(); HTParseFormInput(formfields, string); } else { /* keywords are search tokens */ char * escaped = HTEscape(argv[arg], URL_XALPHAS); if (tokencount++ <= 1) keywords = HTChunk_new(128); else HTChunk_putc(keywords, ' '); HTChunk_puts(keywords, HTStrip(escaped)); HT_FREE(escaped); } } } if (!tokencount && !cl->flags & CL_FILTER) { VersionInfo(argv[0]); Cleanup(cl, 0); } /* Should we use persistent cache? */ if (cache) { HTCacheInit(cache_root, 20); /* Should we start by flushing? */ if (flush) HTCache_flushAll(); } /* ** Check whether we should do some kind of cache validation on ** the load */ if (cl->flags & CL_VALIDATE) HTRequest_setReloadMode(cl->request, HT_CACHE_VALIDATE); else if (cl->flags & CL_END_VALIDATE) HTRequest_setReloadMode(cl->request, HT_CACHE_END_VALIDATE); else if (cl->flags & CL_CACHE_FLUSH) HTRequest_setReloadMode(cl->request, HT_CACHE_FLUSH); /* Add progress notification */ if (cl->flags & CL_QUIET) HTAlert_deleteOpcode(HT_A_PROGRESS); /* Output file specified? */ if (cl->outputfile) { if ((cl->output = fopen(cl->outputfile, "wb")) == NULL) { if (SHOW_MSG) HTPrint("Can't open `%s'\\n",cl->outputfile); cl->output = OUTPUT; } } /* ** Set up the output. Even though we don't use this explicit, it is ** required in order to show the stream stack that we know that we are ** getting raw data output on the output stream of the request object. */ HTRequest_setOutputStream(cl->request, HTFWriter_new(cl->request, cl->output, YES)); /* Setting event timeout */ HTHost_setEventTimeout(cl->timer); /* ** Make sure that the first request is flushed immediately and not ** buffered in the output buffer */ HTRequest_setFlush(cl->request, YES); /* Log file specifed? */ if (cl->logfile) { cl->log = HTLog_open(cl->logfile, YES, YES); if (cl->log) HTNet_addAfter(HTLogFilter, NULL, cl->log, HT_ALL, HT_FILTER_LATE); } /* Just convert formats */ if (cl->flags & CL_FILTER) { #ifdef STDIN_FILENO HTRequest_setAnchor(cl->request, (HTAnchor *) cl->anchor); HTRequest_setPreemptive(cl->request, YES); HTLoadSocket(STDIN_FILENO, cl->request); #endif Cleanup(cl, 0); } /* Content Length Counter */ if (cl->flags & CL_COUNT) { HTRequest_setOutputStream(cl->request, HTContentCounter(HTBlackHole(), cl->request, 0x2000)); } /* Rule file specified? */ if (cl->rules) { char * rules = HTParse(cl->rules, cl->cwd, PARSE_ALL); if (!HTLoadRulesAutomatically(rules)) if (SHOW_MSG) HTPrint("Can't access rules\n"); HT_FREE(rules); } /* Add our own filter to update the history list */ HTNet_addAfter(terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); /* Start the request */ switch (method) { case METHOD_GET: if (formdata) status = HTGetFormAnchor(formfields, (HTAnchor *) cl->anchor, cl->request); else if (keywords) status = HTSearchAnchor(keywords, (HTAnchor *) cl->anchor, cl->request); else status = HTLoadAnchor((HTAnchor *) cl->anchor, cl->request); break; case METHOD_HEAD: if (formdata) { HTRequest_setMethod(cl->request, METHOD_HEAD); status = HTGetFormAnchor(formfields, (HTAnchor *) cl->anchor, cl->request); } else if (keywords) { HTRequest_setMethod(cl->request, METHOD_HEAD); status = HTSearchAnchor(keywords, (HTAnchor *) cl->anchor, cl->request); } else status = HTHeadAnchor((HTAnchor *) cl->anchor, cl->request); break; case METHOD_DELETE: status = HTDeleteAnchor((HTAnchor *) cl->anchor, cl->request); break; case METHOD_POST: if (formdata) { HTParentAnchor * posted = NULL; #if 1 posted = HTPostFormAnchor(formfields, (HTAnchor *) cl->anchor, cl->request); status = posted ? YES : NO; #else /* If we want output to a chunk instead */ post_result = HTPostFormAnchorToChunk(formfields, (HTAnchor *) cl->anchor, cl->request); status = post_result ? YES : NO; #endif } else { if (SHOW_MSG) HTPrint("Nothing to post to this address\n"); status = NO; } break; case METHOD_PUT: status = HTPutDocumentAnchor(cl->anchor, (HTAnchor *) cl->dest, cl->request); break; case METHOD_OPTIONS: status = HTOptionsAnchor((HTAnchor *) cl->anchor, cl->request); break; case METHOD_TRACE: status = HTTraceAnchor((HTAnchor *) cl->anchor, cl->request); break; default: if (SHOW_MSG) HTPrint("Don't know this method\n"); break; } if (keywords) HTChunk_delete(keywords); if (formfields) HTAssocList_delete(formfields); if (status != YES) { if (SHOW_MSG) HTPrint("Sorry, can't access resource\n"); Cleanup(cl, -1); } /* Go into the event loop... */ HTEventList_loop(cl->request); /* Only gets here if event loop fails */ Cleanup(cl, 0); return 0; }
PUBLIC char * HTDialog_errorMessage (HTRequest * request, HTAlertOpcode op, int msgnum, const char * dfault, void * input) { HTList * cur = (HTList *) input; HTError * pres; HTErrorShow showmask = HTError_show(); HTChunk * msg = NULL; int code; if (!request || !cur) return NULL; while ((pres = (HTError *) HTList_nextObject(cur))) { int index = HTError_index(pres); if (HTError_doShow(pres)) { if (!msg) { HTSeverity severity = HTError_severity(pres); msg = HTChunk_new(128); if (severity == ERR_WARN) HTChunk_puts(msg, "Warning: "); else if (severity == ERR_NON_FATAL) HTChunk_puts(msg, "Non Fatal Error: "); else if (severity == ERR_FATAL) HTChunk_puts(msg, "Fatal Error: "); else if (severity == ERR_INFO) HTChunk_puts(msg, "Information: "); else { HTChunk_puts(msg, "UNKNOWN ERROR TYPE"); return HTChunk_toCString(msg); } /* Error number */ if ((code = HTErrors[index].code) > 0) { char buf[10]; sprintf(buf, "%d ", code); HTChunk_puts(msg, buf); } } else HTChunk_puts(msg, "\nReason: "); if (index == HTERR_SYSTEM) { int length = 0; char * pars = (char *) HTError_parameter(pres, &length); HTChunk_puts(msg, HTError_location(pres)); HTChunk_puts(msg, " "); HTChunk_puts(msg, HTErrors[index].msg); if (length && pars) { HTChunk_puts(msg, " ("); HTChunk_puts(msg, pars); HTChunk_puts(msg, ")"); } } else { /* Error message */ HTChunk_puts(msg, HTErrors[index].msg); /* Error parameters */ if (showmask & HT_ERR_SHOW_PARS) { int length; int cnt; char *pars = (char *) HTError_parameter(pres, &length); if (length && pars) { HTChunk_puts(msg, " ("); for (cnt=0; cnt<length; cnt++) { char ch = *(pars+cnt); if (ch < 0x20 || ch >= 0x7F) HTChunk_putc(msg, '#'); else HTChunk_putc(msg, ch); } HTChunk_puts(msg, ") "); } } /* Error Location */ if (showmask & HT_ERR_SHOW_LOCATION) { HTChunk_puts(msg, "This occured in "); HTChunk_puts(msg, HTError_location(pres)); HTChunk_putc(msg, '\n'); } } /* ** Make sure that we don't get this error more than once even ** if we are keeping the error stack from one request to another */ HTError_setIgnore(pres); /* If we only are show the most recent entry then break here */ if (showmask & HT_ERR_SHOW_FIRST) break; } } return HTChunk_toCString(msg); }
PUBLIC BOOL HTBind_add (const char * suffix, const char * representation, const char * encoding, const char * transfer, const char * language, double value) { HTBind * suff; if (!suffix) return NO; if (!strcmp(suffix, "*")) suff = &no_suffix; else if (!strcmp(suffix, "*.*")) suff = &unknown_suffix; else { HTList * suflist; int hash; const unsigned char * p; /* Select list from hash table */ for (p=suffix, hash=0; *p; p++) { hash = (hash * 3 + TOLOWER(*p)) % HT_L_HASH_SIZE; } if (!HTBindings) HTBind_init(); if (!HTBindings[hash]) HTBindings[hash] = HTList_new(); suflist = HTBindings[hash]; /* Look for existing binding */ { HTList *cur = suflist; while ((suff = (HTBind *) HTList_nextObject(cur)) != NULL) { if (!strcmp(suff->suffix, suffix)) break; } } /* If not found -- create a new node */ if (!suff) { if ((suff = (HTBind *) HT_CALLOC(1, sizeof(HTBind))) == NULL) HT_OUTOFMEM("HTBind_add"); HTList_addObject(suflist, (void *) suff); StrAllocCopy(suff->suffix, suffix); } } /* Set the appropriate values */ { HTChunk * chunk = HTChunk_new(32); char *ptr; if (representation) { HTChunk_puts(chunk, representation); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->type = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } if (encoding) { HTChunk_puts(chunk, encoding); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->encoding = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } if (transfer) { HTChunk_puts(chunk, transfer); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->transfer = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } if (language) { HTChunk_puts(chunk, language); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->language = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } HTChunk_delete(chunk); suff->quality = value; } return YES; }