#line 10 "commands.c-nw" #include "config.h" #include #include #include #include #include #include "w3a.h" #include #include "str.h" #include "url.h" #include "w3alib.h" #include "rcfile.e" #include "globals.e" #include "dynload.e" #include "requests.e" #include "input.e" #include "viewers.e" #include "cache.e" #include "tabs.e" static process(W3ADocumentInfo *doc, int method, const char *data, size_t nbytes, Bool no_events) { /* W3ADocumentInfo info; */ URI uri; int fd = -1, doc_nr, i, a = -1, tab; ViewerInfo *info = NULL; Bool use_cache; char *url; const char *where; size_t howmuch; if (! check_url(doc, &uri)) {errno = EURL; return FALSE;} url = newstring(doc->url); if (method == GET_METHOD && (i = find_among_tabs(url)) >= 0) { switch_to_tabbed_doc(i); goto success; } if (method != GET_METHOD) { a = find_agent(strip2str(uri.scheme)); if (a == -1) {errno = ETYPE; goto fail;} if (method == DELETE_METHOD) if (agent_delete(a, url)) goto success; else goto fail; if (method == PUT_METHOD || method == POST_METHOD) { int n; char s[256]; /* * For POST, the connection is made immediately, * without waiting for other connections to close. * The request queue in `input.c' will notice * that fd >= 0 and will use the already opened * connection. */ fd = agent_open(a, url, method, O_NONBLOCK, doc->referer); if (fd == -1) goto fail; n = sprintf(s, "Content-Length: %d\r\n", nbytes); n = agent_write(a, fd, s, n); n = sprintf(s, "Content-Type: \ application/x-www-form-urlencoded\r\n\r\n"); n = agent_write(a, fd, s, n); if (n == -1 && errno != EAGAIN) goto fail; while (nbytes > 0) { n = agent_write(a, fd, data, nbytes); if (n == -1 && errno != EAGAIN) goto fail; data += n; nbytes -= n; } } } /* Initialize info */ info = get_request_rec(); info->method = method; info->doc = new_doc(); copy_doc(info->doc, *doc); info->agent = a; info->fd = fd; info->seqnr = seqnr++; /* Unique request ID */ info->high_prio = FALSE; info->w = XtVaCreateManagedWidget ("viewer", xmFrameWidgetClass, area, XmNmarginWidth, 0, XmNmarginHeight, 0, XmNbottomAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, NULL); if (XtIsRealized(info->w)) XDefineCursor(XtDisplay(info->w), XtWindow(info->w), waitcursor); info->need_event = (method == GET_METHOD) && ! no_events; info->toplevel = TRUE; /* Set tabs */ tab = get_oldest_tab(); /* See tabs.c */ create_tab(tab, info); XFlush(XtDisplay(toplevel)); /* Map window */ #if 0 if (! use_cache) { #endif /* Start request in the background */ assert(fd == -1 || method != GET_METHOD); start_request(uri, info, TRUE); /* Prioritized request */ #if 0 } else { /* Copy from the cache to a viewer */ info->viewer = find_viewer(doc->mime_type); if (! viewer_open(info->viewer, *doc, info->w, (long) info)) goto fail; if (viewer_write(info->viewer, (long) info, where, howmuch) != howmuch || viewer_write(info->viewer, (long) info, NULL, 0) != 0) goto fail; set_tab_titles(); } #endif (void) XmProcessTraversal(info->w, XmTRAVERSE_CURRENT); success: dispose(url); return TRUE; fail: if (info) (void) free_request_rec(info); dispose(url); return FALSE; } #line 151 "commands.c-nw" EXPORT void goto_url(const String url, Bool no_events) { W3ADocumentInfo *doc; char pwd[1060]; if (url == NULL || url[0] == '\0') return; doc = new_doc(); doc->url = newstring(url); strcpy(pwd, "file://localhost"); (void) getcwd(pwd + strlen(pwd), 1024); strcat(pwd, "/dummy"); doc->referer = newstring(pwd); if (! process(doc, GET_METHOD, NULL, 0, no_events)) show_error("goto_url", *doc); dispose_doc(doc); } EXPORT void clone_argo(void) { ViewerInfo *cur; String *argv, *argv2; int argc, i; long c, tblsiz; cur = get_cur_doc(); XtVaGetValues(toplevel, XmNargc, &argc, XmNargv, &argv, NULL); newarray(argv2, argc + 2); for (i = 0; i < argc; i++) argv2[i] = argv[i]; if (argc == 1 || argv[argc-1][0] == '-') { /* Last arg is option */ argv2[argc] = cur->doc->url; /* Add Home Page */ argv2[argc+1] = NULL; } else { /* Last arg was Home Page */ argv2[argc-1] = cur->doc->url; /* Replace it */ argv2[argc] = NULL; } switch (fork()) { case -1: XtAppWarning(XtWidgetToApplicationContext(toplevel), "Failed to start new process; system full?"); break; case 0: tblsiz = sysconf(_SC_OPEN_MAX); /* Close all files */ for (c = 3; c < tblsiz; c++) (void) close(c); exit(execv(argv2[0], argv2)); /* NOTREACHED */ } dispose(argv2); } EXPORT Bool W3Aprocess(W3ADocumentInfo *doc, int method, const char *data, size_t nbytes) { return process(doc, method, data, nbytes, FALSE); } EXPORT int W3AresolveURN(const char *URN, char ***URLs) { errno = ENYI; return -1; } EXPORT void W3Aevent(long id, long eventtype, void *param) { int i; ViewerInfo *v; assert(param !=NULL && ((W3ADocumentInfo *) param)->url != NULL); #if 0 enter("W3Aevent(id=%ld, eventtype=%ld,...)\n", id, eventtype); #ifdef DEBUG if (eventtype == NEW_DOCUMENT) debug("URL=%s\n", ((W3ADocumentInfo *) param)->url); #endif #endif /* Send the event to all open viewers */ v = get_first_request_rec(); /* The struct is also the ID */ while (v) { if (v->viewer >= 0) viewer_event(v->viewer, (long) v, id, eventtype, param); v = get_next_request_rec(v); } /* Send the event to all viewer classes (id = -1) */ for (i = 0; i < nrviewers; i++) viewer_event(i, -1, id, eventtype, param); /* Send the event to all user functions */ for (i = 0; i < nrfunctions; i++) if (id != userfns[i].id) function_event(i, id, eventtype, param); #if 0 leave("W3Aevent\n"); #endif } EXPORT W3AWindow W3Atoplevel(void) { return toplevel; }