int LYUpload_options( char **newfile, char *directory ) { static char tempfile[256]; static char curloc[256]; FILE *fp0 = InternalPageFP( tempfile, 1 ); lynx_list_item_type *cur_upload; int count; char *cp; if ( fp0 == 0 ) { return -1; } cp = HTnameOfFile_WWW( directory, 0, 1 ); strcpy( curloc, cp ); LYTrimPathSep( curloc ); if ( cp != 0 ) { free( cp ); cp = 0; } LYLocalFileToURL( newfile, tempfile ); LYRegisterUIPage( newfile, 10 ); BeginInternalPage( fp0, gettext( "Upload Options" ), "Lynx_users_guide.html.gz#DirEd" ); fwrite( "<pre>\n", 1, 6, fp0 ); fprintf( fp0, " <em>%s</em> %s\n", gettext( "Upload To:" ), curloc ); fprintf( fp0, "\n%s\n", gettext( "Upload options:" ) ); if ( uploaders != 0 ) { count = 0; cur_upload = uploaders; for ( ; cur_upload != 0; count++ ) { fprintf( fp0, " <a href=\"LYNXDIRED://UPLOAD=%d/TO=%s\">", count, curloc ); fputs( cur_upload->name == 0 ? gettext( "No Name Given" ) : cur_upload->name, fp0 ); fwrite( "</a>\n", 1, 5, fp0 ); cur_upload = &cur_upload; //count++; } } else fwrite( " <NONE>\n", 1, 16, fp0 ); fwrite( "</pre>\n", 1, 7, fp0 ); EndInternalPage( fp0 ); LYCloseTempFP( fp0 ); LYforce_no_cache = 1; return 0; }
/* * LYShowInfo prints a page of info about the current file and the link that * the cursor is on. */ int LYShowInfo(DocInfo *doc, DocInfo *newdoc, char *owner_address) { static char tempfile[LY_MAXPATH] = "\0"; int url_type; FILE *fp0; char *Title = NULL; const char *cp; char *temp = NULL; char *buffer = NULL; BOOLEAN LYInfoAdvanced = (BOOL) (user_mode == ADVANCED_MODE); #ifdef DIRED_SUPPORT struct stat dir_info; const char *name; #endif /* DIRED_SUPPORT */ if (LYReuseTempfiles) { fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); } else { (void) LYRemoveTemp(tempfile); fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); } if (fp0 == NULL) { HTAlert(CANNOT_OPEN_TEMP); return (-1); } /* * Point the address pointer at this Url */ LYLocalFileToURL(&newdoc->address, tempfile); if (nlinks > 0 && links[doc->link].lname != NULL && (url_type = is_url(links[doc->link].lname)) != 0 && (url_type == LYNXEXEC_URL_TYPE || url_type == LYNXPROG_URL_TYPE)) { char *last_slash = strrchr(links[doc->link].lname, '/'); int next_to_last = (int) strlen(links[doc->link].lname) - 1; if ((last_slash - links[doc->link].lname) == next_to_last) { links[doc->link].lname[next_to_last] = '\0'; } } label_columns = 9; WriteInternalTitle(fp0, SHOWINFO_TITLE); fprintf(fp0, "<h1>%s %s (%s) (<a href=\"%s\">%s</a>)", LYNX_NAME, LYNX_VERSION, LYVersionDate(), (LYVersionIsRelease()? LYNX_WWW_HOME : LYNX_WWW_DIST), LYVersionStatus()); fprintf(fp0, "</h1>\n"); /* don't forget to close <h1> */ #ifdef DIRED_SUPPORT if (lynx_edit_mode && nlinks > 0) { BEGIN_DL(gettext("Directory that you are currently viewing")); temp = HTfullURL_toFile(doc->address); ADD_SS(gettext("Name:"), temp); FREE(temp); dt_URL(fp0, doc->address); END_DL(); temp = HTfullURL_toFile(links[doc->link].lname); if (lstat(temp, &dir_info) == -1) { CTRACE((tfp, "lstat(%s) failed, errno=%d\n", temp, errno)); HTAlert(CURRENT_LINK_STATUS_FAILED); } else { char modes[80]; label_columns = 16; if (S_ISDIR(dir_info.st_mode)) { BEGIN_DL(gettext("Directory that you have currently selected")); } else if (S_ISREG(dir_info.st_mode)) { BEGIN_DL(gettext("File that you have currently selected")); #ifdef S_IFLNK } else if (S_ISLNK(dir_info.st_mode)) { BEGIN_DL(gettext("Symbolic link that you have currently selected")); #endif } else { BEGIN_DL(gettext("Item that you have currently selected")); } ADD_SS(gettext("Full name:"), temp); #ifdef S_IFLNK if (S_ISLNK(dir_info.st_mode)) { char buf[MAX_LINE]; int buf_size; size_t limit = sizeof(buf) - 1; if ((buf_size = (int) readlink(temp, buf, limit)) != -1) { if (buf_size > (int) limit) buf_size = (int) limit; buf[buf_size] = '\0'; } else { sprintf(buf, "%.*s", (int) limit, gettext("Unable to follow link")); } ADD_SS(gettext("Points to file:"), buf); } #endif name = HTAA_UidToName((int) dir_info.st_uid); if (*name) ADD_SS(gettext("Name of owner:"), name); name = HTAA_GidToName((int) dir_info.st_gid); if (*name) ADD_SS(gettext("Group name:"), name); if (S_ISREG(dir_info.st_mode)) { ADD_NN(gettext("File size:"), (long) dir_info.st_size, gettext("(bytes)")); } /* * Include date and time information. */ ADD_SS(gettext("Creation date:"), ctime(&dir_info.st_ctime)); ADD_SS(gettext("Last modified:"), ctime(&dir_info.st_mtime)); ADD_SS(gettext("Last accessed:"), ctime(&dir_info.st_atime)); END_DL(); label_columns = 9; BEGIN_DL(gettext("Access Permissions")); modes[0] = '\0'; modes[1] = '\0'; /* In case there are no permissions */ modes[2] = '\0'; if ((dir_info.st_mode & S_IRUSR)) strcat(modes, ", read"); if ((dir_info.st_mode & S_IWUSR)) strcat(modes, ", write"); if ((dir_info.st_mode & S_IXUSR)) { if (S_ISDIR(dir_info.st_mode)) strcat(modes, ", search"); else { strcat(modes, ", execute"); if ((dir_info.st_mode & S_ISUID)) strcat(modes, ", setuid"); } } ADD_SS(gettext("Owner:"), &modes[2]); modes[0] = '\0'; modes[1] = '\0'; /* In case there are no permissions */ modes[2] = '\0'; if ((dir_info.st_mode & S_IRGRP)) strcat(modes, ", read"); if ((dir_info.st_mode & S_IWGRP)) strcat(modes, ", write"); if ((dir_info.st_mode & S_IXGRP)) { if (S_ISDIR(dir_info.st_mode)) strcat(modes, ", search"); else { strcat(modes, ", execute"); if ((dir_info.st_mode & S_ISGID)) strcat(modes, ", setgid"); } } ADD_SS(gettext("Group:"), &modes[2]); modes[0] = '\0'; modes[1] = '\0'; /* In case there are no permissions */ modes[2] = '\0'; if ((dir_info.st_mode & S_IROTH)) strcat(modes, ", read"); if ((dir_info.st_mode & S_IWOTH)) strcat(modes, ", write"); if ((dir_info.st_mode & S_IXOTH)) { if (S_ISDIR(dir_info.st_mode)) strcat(modes, ", search"); else { strcat(modes, ", execute"); #ifdef S_ISVTX if ((dir_info.st_mode & S_ISVTX)) strcat(modes, ", sticky"); #endif } } ADD_SS(gettext("World:"), &modes[2]); END_DL(); } FREE(temp); } else { #endif /* DIRED_SUPPORT */ BEGIN_DL(gettext("File that you are currently viewing")); LYformTitle(&Title, doc->title); HTSprintf(&temp, "%s%s", LYEntifyTitle(&buffer, Title), ((doc->isHEAD && !strstr(Title, " (HEAD)") && !strstr(Title, " - HEAD")) ? " (HEAD)" : "")); ADD_SS(gettext("Linkname:"), temp); FREE(temp); dt_URL(fp0, doc->address); if (HTLoadedDocumentCharset()) { ADD_SS(gettext("Charset:"), HTLoadedDocumentCharset()); } else { LYUCcharset *p_in = HTAnchor_getUCInfoStage(HTMainAnchor, UCT_STAGE_PARSER); if (!p_in || isEmpty(p_in->MIMEname) || HTAnchor_getUCLYhndl(HTMainAnchor, UCT_STAGE_PARSER) < 0) { p_in = HTAnchor_getUCInfoStage(HTMainAnchor, UCT_STAGE_MIME); } if (p_in && non_empty(p_in->MIMEname) && HTAnchor_getUCLYhndl(HTMainAnchor, UCT_STAGE_MIME) >= 0) { HTSprintf(&temp, "%s %s", LYEntifyTitle(&buffer, p_in->MIMEname), gettext("(assumed)")); ADD_SS(gettext("Charset:"), p_in->MIMEname); FREE(temp); } } if ((cp = HText_getServer()) != NULL && *cp != '\0') ADD_SS(gettext("Server:"), cp); if ((cp = HText_getDate()) != NULL && *cp != '\0') ADD_SS(gettext("Date:"), cp); if ((cp = HText_getLastModified()) != NULL && *cp != '\0') ADD_SS(gettext("Last Mod:"), cp); if (LYInfoAdvanced) { if (HTMainAnchor && HTMainAnchor->expires) { ADD_SS(gettext("Expires:"), HTMainAnchor->expires); } if (HTMainAnchor && HTMainAnchor->cache_control) { ADD_SS(gettext("Cache-Control:"), HTMainAnchor->cache_control); } if (HTMainAnchor && HTMainAnchor->content_length > 0) { ADD_NN(gettext("Content-Length:"), HTMainAnchor->content_length, gettext("bytes")); } else { ADD_NN(gettext("Length:"), HText_getNumOfBytes(), gettext("bytes")); } if (HTMainAnchor && HTMainAnchor->content_language) { ADD_SS(gettext("Language:"), HTMainAnchor->content_language); } } if (doc->post_data) { fprintf(fp0, "<dt><em>%s</em> <xmp>%.*s</xmp>\n", LYEntifyTitle(&buffer, gettext("Post Data:")), BStrLen(doc->post_data), BStrData(doc->post_data)); ADD_SS(gettext("Post Content Type:"), doc->post_content_type); } ADD_SS(gettext("Owner(s):"), (owner_address ? owner_address : NO_NOTHING)); ADD_NN(gettext("size:"), HText_getNumOfLines(), gettext("lines")); StrAllocCopy(temp, ((lynx_mode == FORMS_LYNX_MODE) ? gettext("forms mode") : (HTisDocumentSource() ? gettext("source") : gettext("normal")))); if (doc->safe) StrAllocCat(temp, gettext(", safe")); if (doc->internal_link) StrAllocCat(temp, gettext(", via internal link")); if (LYInfoAdvanced) { if (HText_hasNoCacheSet(HTMainText)) StrAllocCat(temp, gettext(", no-cache")); if (HTAnchor_isISMAPScript((HTAnchor *) HTMainAnchor)) StrAllocCat(temp, gettext(", ISMAP script")); if (doc->bookmark) StrAllocCat(temp, gettext(", bookmark file")); } ADD_SS(gettext("mode:"), temp); FREE(temp); END_DL(); if (nlinks > 0) { BEGIN_DL(gettext("Link that you currently have selected")); ADD_SS(gettext("Linkname:"), LYGetHiliteStr(doc->link, 0)); if (lynx_mode == FORMS_LYNX_MODE && links[doc->link].type == WWW_FORM_LINK_TYPE) { if (links[doc->link].l_form->submit_method) { int method = links[doc->link].l_form->submit_method; char *enctype = links[doc->link].l_form->submit_enctype; ADD_SS(gettext("Method:"), ((method == URL_POST_METHOD) ? "POST" : ((method == URL_MAIL_METHOD) ? "(email)" : "GET"))); ADD_SS(gettext("Enctype:"), (non_empty(enctype) ? enctype : "application/x-www-form-urlencoded")); } if (links[doc->link].l_form->submit_action) { ADD_SS(gettext("Action:"), links[doc->link].l_form->submit_action); } if (!(links[doc->link].l_form->submit_method && links[doc->link].l_form->submit_action)) { fprintf(fp0, "<dt> %s\n", LYEntifyTitle(&buffer, gettext("(Form field)"))); } } else { dt_URL(fp0, NonNull(links[doc->link].lname)); } END_DL(); } else { fprintf(fp0, "<h2>%s</h2>", LYEntifyTitle(&buffer, gettext("No Links on the current page"))); } if ((cp = HText_getHttpHeaders()) != 0) { fprintf(fp0, "<h2>%s</h2>", LYEntifyTitle(&buffer, gettext("Server Headers:"))); fprintf(fp0, "<pre>%s</pre>", LYEntifyTitle(&buffer, cp)); } #ifdef DIRED_SUPPORT } #endif /* DIRED_SUPPORT */ EndInternalPage(fp0); LYrefresh(); LYCloseTemp(tempfile); FREE(Title); FREE(buffer); return (0); }
/* * LYdownload_options writes out the current download choices to a file so that * the user can select downloaders in the same way that they select all other * links. Download links look like: * LYNXDOWNLOAD://Method=<#>/File=<STRING>/SugFile=<STRING> */ int LYdownload_options(char **newfile, char *data_file) { static char tempfile[LY_MAXPATH] = "\0"; char *downloaded_url = NULL; char *sug_filename = NULL; FILE *fp0; lynx_list_item_type *cur_download; int count; /* * Get a suggested filename. */ StrAllocCopy(sug_filename, *newfile); change_sug_filename(sug_filename); if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return (-1); StrAllocCopy(downloaded_url, *newfile); LYLocalFileToURL(newfile, tempfile); LYStrNCpy(LYValidDownloadFile, data_file, (sizeof(LYValidDownloadFile) - 1)); LYforce_no_cache = TRUE; /* don't cache this doc */ BeginInternalPage(fp0, DOWNLOAD_OPTIONS_TITLE, DOWNLOAD_OPTIONS_HELP); fprintf(fp0, "<pre>\n"); fprintf(fp0, "<em>%s</em> %s\n", gettext("Downloaded link:"), downloaded_url); FREE(downloaded_url); fprintf(fp0, "<em>%s</em> %s\n", gettext("Suggested file name:"), sug_filename); fprintf(fp0, "\n%s\n", (user_mode == NOVICE_MODE) ? gettext("Standard download options:") : gettext("Download options:")); if (!no_disk_save) { #if defined(DIRED_SUPPORT) /* * Disable save to disk option for local files. */ if (!lynx_edit_mode) #endif /* DIRED_SUPPORT */ { fprintf(fp0, " <a href=\"%s//Method=-1/File=%s/SugFile=%s%s\">%s</a>\n", STR_LYNXDOWNLOAD, data_file, NonNull(lynx_save_space), sug_filename, gettext("Save to disk")); /* * If it is not a binary file, offer the opportunity to view the * downloaded temporary file (see HTSaveToFile). */ if (SuffixIs(data_file, HTML_SUFFIX) || SuffixIs(data_file, TEXT_SUFFIX)) { char *target = NULL; char *source = LYAddPathToSave(data_file); LYLocalFileToURL(&target, source); fprintf(fp0, " <a href=\"%s\">%s</a>\n", target, gettext("View temporary file")); FREE(source); FREE(target); } } } else { fprintf(fp0, " <em>%s</em>\n", gettext("Save to disk disabled.")); } if (user_mode == NOVICE_MODE) fprintf(fp0, "\n%s\n", gettext("Local additions:")); if (downloaders != NULL) { for (count = 0, cur_download = downloaders; cur_download != NULL; cur_download = cur_download->next, count++) { if (!no_download || cur_download->always_enabled) { fprintf(fp0, " <a href=\"%s//Method=%d/File=%s/SugFile=%s\">", STR_LYNXDOWNLOAD, count, data_file, sug_filename); fprintf(fp0, "%s", (cur_download->name ? cur_download->name : gettext("No Name Given"))); fprintf(fp0, "</a>\n"); } } } fprintf(fp0, "</pre>\n"); EndInternalPage(fp0); LYCloseTempFP(fp0); LYRegisterUIPage(*newfile, UIP_DOWNLOAD_OPTIONS); /* * Free off temp copy. */ FREE(sug_filename); return (0); }
/* * This procedure outputs the Visited Links list into a temporary file. - FM * Returns links's number to make active (1-based), or 0 if not required. */ int LYShowVisitedLinks(char **newfile) { static char tempfile[LY_MAXPATH] = "\0"; char *Title = NULL; char *Address = NULL; int x, tot; FILE *fp0; VisitedLink *vl; HTList *cur = Visited_Links; int offset; int ret = 0; const char *arrow, *post_arrow; if (!cur) return (-1); if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return (-1); LYLocalFileToURL(newfile, tempfile); LYRegisterUIPage(*newfile, UIP_VLINKS); LYforce_HTML_mode = TRUE; /* force this file to be HTML */ LYforce_no_cache = TRUE; /* force this file to be new */ BeginInternalPage(fp0, VISITED_LINKS_TITLE, VISITED_LINKS_HELP); #ifndef NO_OPTION_FORMS fprintf(fp0, "<form action=\"%s\" method=\"post\">\n", STR_LYNXOPTIONS); LYMenuVisitedLinks(fp0, FALSE); fprintf(fp0, "<input type=\"submit\" value=\"Accept Changes\">\n"); fprintf(fp0, "</form>\n"); fprintf(fp0, "<P>\n"); #endif fprintf(fp0, "<pre>\n"); fprintf(fp0, "<em>%s</em>\n", gettext("You visited (POSTs, bookmark, menu and list files excluded):")); if (Visited_Links_As & VISITED_LINKS_REVERSE) tot = x = HTList_count(Visited_Links); else tot = x = -1; if (Visited_Links_As & VISITED_LINKS_AS_TREE) { vl = First_tree; } else if (Visited_Links_As & VISITED_LINKS_AS_LATEST) { if (Visited_Links_As & VISITED_LINKS_REVERSE) vl = Latest_last.prev_latest; else vl = Latest_first.next_latest; if (vl == &Latest_last || vl == &Latest_first) vl = NULL; } else { if (Visited_Links_As & VISITED_LINKS_REVERSE) vl = Last_by_first; else vl = (VisitedLink *) HTList_nextObject(cur); } while (NULL != vl) { /* * The number of the document (most recent highest), its title in a * link, and its address. - FM */ post_arrow = arrow = ""; if (Visited_Links_As & VISITED_LINKS_REVERSE) x--; else x++; if (vl == PrevActiveVisitedLink) { if (Visited_Links_As & VISITED_LINKS_REVERSE) ret = tot - x + 2; else ret = x + 3; } if (vl == PrevActiveVisitedLink) { post_arrow = "<A NAME=current></A>"; /* Otherwise levels 0 and 1 look the same when with arrow: */ arrow = (vl->level && (Visited_Links_As & VISITED_LINKS_AS_TREE)) ? "==>" : "=>"; StrAllocCat(*newfile, "#current"); } if (Visited_Links_As & VISITED_LINKS_AS_TREE) { offset = 2 * vl->level; if (offset > 24) offset = (offset + 24) / 2; if (offset > LYcols * 3 / 4) offset = LYcols * 3 / 4; } else offset = (x > 99 ? 0 : x < 10 ? 2 : 1); if (non_empty(vl->title)) { StrAllocCopy(Title, vl->title); LYEntify(&Title, TRUE); LYTrimLeading(Title); LYTrimTrailing(Title); if (*Title == '\0') StrAllocCopy(Title, NO_TITLE); } else { StrAllocCopy(Title, NO_TITLE); } if (non_empty(vl->address)) { StrAllocCopy(Address, vl->address); LYEntify(&Address, FALSE); fprintf(fp0, "%-*s%s<em>%d</em>. <tab id=t%d><a href=\"%s\">%s</a>\n", offset, arrow, post_arrow, x, x, Address, Title); } else { fprintf(fp0, "%-*s%s<em>%d</em>. <tab id=t%d><em>%s</em>\n", offset, arrow, post_arrow, x, x, Title); } if (Address != NULL) { StrAllocCopy(Address, vl->address); LYEntify(&Address, TRUE); } fprintf(fp0, "<tab to=t%d>%s\n", x, ((Address != NULL) ? Address : gettext("(no address)"))); if (Visited_Links_As & VISITED_LINKS_AS_TREE) vl = vl->next_tree; else if (Visited_Links_As & VISITED_LINKS_AS_LATEST) { if (Visited_Links_As & VISITED_LINKS_REVERSE) vl = vl->prev_latest; else vl = vl->next_latest; if (vl == &Latest_last || vl == &Latest_first) vl = NULL; } else { if (Visited_Links_As & VISITED_LINKS_REVERSE) vl = vl->prev_first; else vl = (VisitedLink *) HTList_nextObject(cur); } } fprintf(fp0, "</pre>\n"); EndInternalPage(fp0); LYCloseTempFP(fp0); FREE(Title); FREE(Address); return (ret); }
/* * This procedure outputs the history buffer into a temporary file. */ int showhistory(char **newfile) { static char tempfile[LY_MAXPATH] = "\0"; char *Title = NULL; int x = 0; FILE *fp0; if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return (-1); LYLocalFileToURL(newfile, tempfile); LYforce_HTML_mode = TRUE; /* force this file to be HTML */ LYforce_no_cache = TRUE; /* force this file to be new */ BeginInternalPage(fp0, HISTORY_PAGE_TITLE, HISTORY_PAGE_HELP); fprintf(fp0, "<p align=right> <a href=\"%s\">[%s]</a>\n", STR_LYNXMESSAGES, STATUSLINES_TITLE); fprintf(fp0, "<pre>\n"); fprintf(fp0, "<em>%s</em>\n", gettext("You selected:")); for (x = nhist + nhist_extra - 1; x >= 0; x--) { /* * The number of the document in the hist stack, its title in a link, * and its address. - FM */ if (HDOC(x).title != NULL) { StrAllocCopy(Title, HDOC(x).title); LYEntify(&Title, TRUE); LYTrimLeading(Title); LYTrimTrailing(Title); if (*Title == '\0') StrAllocCopy(Title, NO_TITLE); } else { StrAllocCopy(Title, NO_TITLE); } fprintf(fp0, "%s<em>%d</em>. <tab id=t%d><a href=\"%s%d\">%s</a>\n", (x > 99 ? "" : x < 10 ? " " : " "), x, x, STR_LYNXHIST, x, Title); if (HDOC(x).address != NULL) { StrAllocCopy(Title, HDOC(x).address); LYEntify(&Title, TRUE); } else { StrAllocCopy(Title, gettext("(no address)")); } if (HDOC(x).internal_link) { if (history[x].intern_seq_start == history[nhist - 1].intern_seq_start) StrAllocCat(Title, gettext(" (internal)")); else StrAllocCat(Title, gettext(" (was internal)")); } fprintf(fp0, "<tab to=t%d>%s\n", x, Title); } fprintf(fp0, "</pre>\n"); EndInternalPage(fp0); LYCloseTempFP(fp0); FREE(Title); return (0); }
void HTFWriter_free( HTStream *me ) { int len; char *path = 0; char *addr = 0; int status; BOOLEAN use_zread = 0; BOOLEAN found = 0; if ( me->fp ) fflush( &me->fp ); if ( me->end_command ) { LYCloseTempFP( &me->fp ); if ( me->input_format == HTAtom_for( "www/compressed" ) ) { if ( me->anchor->FileCache ) { BOOLEAN skip_loadfile = me->viewer_command != 0; HTSACopy( &path, &me->anchor->FileCache ); len = strlen( path ); if ( len > 3 && ( strcasecomp( &path[ len + -2 ], "gz" ) == 0 || strcasecomp( &path[ len + -2 ], "zz" ) == 0 ) ) { if ( skip_loadfile == 0 ) use_zread = 1; else { path[ len + -3 ] = 0; remove( path ); } } else if ( len > 4 && strcasecomp( &path[ len + -3 ], "bz2" ) == 0 ) { path[ len + -4 ] = 0; remove( path ); } else if ( len > 2 && strcasecomp( &path[ len + -1 ], "Z" ) == 0 ) { path[ len + -2 ] = 0; remove( path ); } if ( use_zread == 0 ) { if ( dump_output_immediately == 0 ) { mustshow = 1; HTProgress( &me->end_command ); } if ( me->end_command && me->end_command[0] ) LYSystem( &me->end_command ); found = LYCanReadFile( &me->anchor->FileCache ); } if ( found ) { if ( dump_output_immediately == 0 ) { lynx_force_repaint( ); LYrefresh( ); } HTAlert( gettext( "Error uncompressing temporary file!" ) ); LYRemoveTemp( &me->anchor->FileCache ); if ( me->anchor->FileCache ) { free( &me->anchor->FileCache ); me->anchor->FileCache = 0; } } else { LYLocalFileToURL( &addr, path ); if ( use_zread == 0 ) { LYRenamedTemp( &me->anchor->FileCache, path ); HTSACopy( &me->anchor->FileCache, path ); HTSACopy( &me->anchor->content_encoding, "binary" ); } if ( path ) { free( path ); path = 0; } if ( skip_loadfile == 0 ) { if ( HTAnchor_getUCLYhndl( &me->anchor, 1 ) < 0 ) HTAnchor_copyUCInfoStage( &me->anchor, 1, 0, 2 ); HTAnchor_copyUCInfoStage( &me->anchor, 1, 0, -1 ); } if ( dump_output_immediately == 0 ) { LYstore_message2( gettext( "Using %s" ), addr ); } if ( skip_loadfile ) { if ( me->end_command ) { free( &me->end_command ); *(int*)&me->end_command = 0; } HTAddParam( &me->end_command, &me->viewer_command, 1, &me->anchor->FileCache ); HTEndParam( &me->end_command, &me->viewer_command, 1 ); if ( dump_output_immediately == 0 ) { HTProgress( &me->end_command ); stop_curses( ); } LYSystem( &me->end_command ); if ( me->remove_command && me->remove_command ) { free( &me->remove_command ); *(int*)&me->remove_command = 0; } if ( dump_output_immediately == 0 ) start_curses( ); } else { status = HTLoadFile( addr, &me->anchor, &me->output_format, &me->sink ); } if ( dump_output_immediately && me->output_format == HTAtom_for( "www/present" ) ) { if ( addr ) { free( addr ); addr = 0; } remove( &me->anchor->FileCache ); if ( me->anchor->FileCache ) { free( &me->anchor->FileCache ); me->anchor->FileCache = 0; } if ( me->remove_command ) { free( &me->remove_command ); *(int*)&me->remove_command = 0; } if ( me->end_command ) { free( &me->end_command ); *(int*)&me->end_command = 0; } if ( me->viewer_command ) { free( &me->viewer_command ); *(int*)&me->viewer_command = 0; } if ( me == 0 ) { return; } free( me ); me = 0; return; } } if ( addr ) { free( addr ); addr = 0; } } if ( me->remove_command && me->remove_command ) { free( &me->remove_command ); *(int*)&me->remove_command = 0; } } else { if ( strcmp( &me->end_command, "SaveToFile" ) ) { if ( dump_output_immediately == 0 ) { mustshow = 1; HTProgress( &me->end_command ); stop_curses( ); } LYSystem( &me->end_command ); if ( me->remove_command && me->remove_command ) { free( &me->remove_command ); *(int*)&me->remove_command = 0; } if ( dump_output_immediately == 0 ) start_curses( ); } else { if ( me->remove_command && me->remove_command ) { free( &me->remove_command ); *(int*)&me->remove_command = 0; } if ( dump_output_immediately == 0 ) start_curses( ); } } if ( me->end_command ) { free( &me->end_command ); *(int*)&me->end_command = 0; } } if ( me->viewer_command ) { free( &me->viewer_command ); *(int*)&me->viewer_command = 0; } if ( dump_output_immediately ) { if ( me->anchor->FileCache ) remove( &me->anchor->FileCache ); if ( me ) { free( me ); me = 0; } if ( persistent_cookies ) LYStoreCookies( LYCookieSaveFile ); exit_immediately( 0 ); } if ( me == 0 ) { return; } free( me ); me = 0; return; }
int LYShowInfo( DocInfo *doc, DocInfo *newdoc, char *owner_address ) { int eax; int edx; static char tempfile[256]; int url_type; FILE *fp0; char *Title = 0; char *cp; char *temp = 0; BOOLEAN LYInfoAdvanced = user_mode == 2; struct stat dir_info; static char *name; if ( LYReuseTempfiles ) { fp0 = LYOpenTempRewrite( tempfile, ".html", "w" ); } else { LYRemoveTemp( tempfile ); fp0 = LYOpenTemp( tempfile, ".html", "w" ); } if ( fp0 == 0 ) { HTAlert( gettext( "Can't open temporary file!" ) ); return -1; } else { LYLocalFileToURL( &newdoc->address, tempfile ); if ( nlinks > 0 && links[ doc->link ] ) { url_type = is_url( links[ doc->link ].lname ); switch ( url_type ) { case 26: case 27: { char *last_slash = strrchr( links[ doc->link ].lname, '/' ); int next_to_last = strlen( links[ doc->link ].lname ) + -1; if ( next_to_last == last_slash - links[ doc->link ].lname ) links[ doc->link ].lname[ ebp_1152 ] = 0; } break; } } label_columns = 9; WriteInternalTitle( fp0, gettext( "Information about the current document" ) ); fprintf( fp0, "<h1>%s %s (%s) (<a href=\"%s\">%s</a>)", "Lynx", "2.8.7dev.11", LYVersionDate( ), "http://lynx.isc.org/current/", LYVersionStatus( ) ); fwrite( "</h1>\n", 1, 6, fp0 ); if ( lynx_edit_mode && nlinks > 0 ) { fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "Directory that you are currently viewing" ) ); temp = HTnameOfFile_WWW( &doc->address, 0, 1 ); dt_String( fp0, gettext( "Name:" ), temp ); if ( temp ) { free( temp ); temp = 0; } dt_String( fp0, gettext( "URL:" ), &doc->address ); fwrite( "\n</dl>\n", 1, 7, fp0 ); temp = HTnameOfFile_WWW( links[ doc->link ].lname, 0, 1 ); if ( lstat64( temp, &dir_info.st_dev ) == -1 ) { if ( WWW_TraceFlag ) { fprintf( TraceFP( ), "lstat(%s) failed, errno=%d\n", temp, *(int*)(__errno_location( )) ); } HTAlert( gettext( "Failed to obtain status of current link!" ) ); } else { char modes[80]; label_columns = 16; if ( ( dir_info.st_mode & 61440 ) == 16384 ) { fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "Directory that you have currently selected" ) ); } else if ( ( dir_info.st_mode & 61440 ) == 32768 ) { fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "File that you have currently selected" ) ); } else if ( ( dir_info.st_mode & 61440 ) == 40960 ) { fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "Symbolic link that you have currently selected" ) ); } else { fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "Item that you have currently selected" ) ); } dt_String( fp0, gettext( "Full name:" ), temp ); if ( ( dir_info.st_mode & 61440 ) == 40960 ) { char buf[1024]; int buf_size = readlink( temp, buf, 1023 ); if ( buf_size != -1 ) buf[ buf_size ] = 0; else { sprintf( buf, "%.*s", 1023, gettext( "Unable to follow link" ) ); } dt_String( fp0, gettext( "Points to file:" ), buf ); } name = HTAA_UidToName( (int)dir_info.st_uid ); if ( name[0] ) { dt_String( fp0, gettext( "Name of owner:" ), name ); } name = HTAA_GidToName( (int)dir_info.st_gid ); if ( name[0] ) { dt_String( fp0, gettext( "Group name:" ), name ); } if ( ( dir_info.st_mode & 61440 ) == 32768 ) { dt_Number( fp0, gettext( "File size:" ), (int)( (long)(dir_info.st_size & 0xFFFFFFFF) ), gettext( "(bytes)" ) ); } dt_String( fp0, gettext( "Creation date:" ), ctime( &dir_info.st_ctim.tv_sec ) ); dt_String( fp0, gettext( "Last modified:" ), ctime( &dir_info.st_mtim.tv_sec ) ); dt_String( fp0, gettext( "Last accessed:" ), ctime( &dir_info.st_atim.tv_sec ) ); fwrite( "\n</dl>\n", 1, 7, fp0 ); label_columns = 9; fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "Access Permissions" ) ); modes[0] = 0; modes[1] = 0; modes[2] = 0; if ( dir_info.st_mode & 256 ) { memcpy( modes[0] + strlen( modes ) ); } if ( dir_info.st_mode & 128 ) { memcpy( modes[0] + strlen( modes ) ); } if ( dir_info.st_mode & 64 ) { if ( ( dir_info.st_mode & 61440 ) == 16384 ) { memcpy( modes[0] + strlen( modes ) ); } else { memcpy( modes[0] + strlen( modes ) ); if ( dir_info.st_mode & 2048 ) { memcpy( modes[0] + strlen( modes ) ); } } } dt_String( fp0, gettext( "Owner:" ), &modes[2] ); modes[0] = 0; modes[1] = 0; modes[2] = 0; if ( dir_info.st_mode & 32 ) { memcpy( modes[0] + strlen( modes ) ); } if ( dir_info.st_mode & 16 ) { memcpy( modes[0] + strlen( modes ) ); } if ( dir_info.st_mode & 8 ) { if ( ( dir_info.st_mode & 61440 ) == 16384 ) { memcpy( modes[0] + strlen( modes ) ); } else { memcpy( modes[0] + strlen( modes ) ); if ( dir_info.st_mode & 1024 ) { memcpy( modes[0] + strlen( modes ) ); } } } dt_String( fp0, gettext( "Group:" ), &modes[2] ); modes[0] = 0; modes[1] = 0; modes[2] = 0; if ( dir_info.st_mode & 4 ) { memcpy( modes[0] + strlen( modes ) ); } if ( dir_info.st_mode & 2 ) { memcpy( modes[0] + strlen( modes ) ); } if ( dir_info.st_mode & 1 ) { if ( ( dir_info.st_mode & 61440 ) == 16384 ) { memcpy( modes[0] + strlen( modes ) ); } else { memcpy( modes[0] + strlen( modes ) ); if ( dir_info.st_mode & 512 ) { memcpy( modes[0] + strlen( modes ) ); } } } dt_String( fp0, gettext( "World:" ), &modes[2] ); fwrite( "\n</dl>\n", 1, 7, fp0 ); } if ( temp ) { free( temp ); temp = 0; } } else { fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "File that you are currently viewing" ) ); LYformTitle( &Title, &doc->title[0] ); HTSprintf( &temp, "%s%s", Title, "" ); dt_String( fp0, gettext( "Linkname:" ), temp ); if ( temp ) { free( temp ); temp = 0; } dt_String( fp0, "URL:", &doc->address ); if ( HTLoadedDocumentCharset( ) ) { dt_String( fp0, gettext( "Charset:" ), HTLoadedDocumentCharset( ) ); } else { LYUCcharset *p_in = HTAnchor_getUCInfoStage( HTMainAnchor, 1 ); if ( p_in == 0 || p_in->MIMEname == 0 || p_in->MIMEname[0] == 0 || HTAnchor_getUCLYhndl( HTMainAnchor, 1 ) < 0 ) { p_in = HTAnchor_getUCInfoStage( HTMainAnchor, 0 ); } if ( p_in && p_in->MIMEname && p_in->MIMEname[0] && HTAnchor_getUCLYhndl( HTMainAnchor, 0 ) >= 0 ) { HTSprintf( &temp, "%s %s", p_in->MIMEname, gettext( "(assumed)" ) ); dt_String( fp0, gettext( "Charset:" ), &p_in->MIMEname ); if ( temp ) { free( temp ); temp = 0; } } } cp = HText_getServer( ); if ( cp && cp[0] ) { dt_String( fp0, gettext( "Server:" ), cp ); } cp = HText_getDate( ); if ( cp && cp[0] ) { dt_String( fp0, gettext( "Date:" ), cp ); } cp = HText_getLastModified( ); if ( cp && cp[0] ) { dt_String( fp0, gettext( "Last Mod:" ), cp ); } if ( LYInfoAdvanced ) { if ( HTMainAnchor && HTMainAnchor->expires ) { dt_String( fp0, gettext( "Expires:" ), &HTMainAnchor->expires ); } if ( HTMainAnchor && HTMainAnchor->cache_control ) { dt_String( fp0, gettext( "Cache-Control:" ), &HTMainAnchor->cache_control ); } if ( HTMainAnchor && HTMainAnchor->content_length > 0 ) { dt_Number( fp0, gettext( "Content-Length:" ), HTMainAnchor->content_length, gettext( "bytes" ) ); } else { dt_Number( fp0, gettext( "Length:" ), HText_getNumOfBytes( ), gettext( "bytes" ) ); } if ( HTMainAnchor && HTMainAnchor->content_language ) { dt_String( fp0, gettext( "Language:" ), &HTMainAnchor->content_language ); } } if ( doc->post_data ) { fprintf( fp0, "<dt><em>%s</em> <xmp>%.*s</xmp>\n", gettext( "Post Data:" ), 0, 0 ); dt_String( fp0, gettext( "Post Content Type:" ), &doc->post_content_type ); } dt_String( fp0, gettext( "Owner(s):" ), owner_address ? owner_address : gettext( "Owner(s):" ) ); dt_Number( fp0, gettext( "size:" ), HText_getNumOfLines( ), gettext( "lines" ) ); if ( lynx_mode != 2 ) { if ( HTisDocumentSource( ) ) { } else { } } else { } HTSACopy( &temp, gettext( "source" ) ); if ( doc->safe ) { HTSACat( &temp, gettext( ", safe" ) ); } if ( doc->internal_link ) { HTSACat( &temp, gettext( ", via internal link" ) ); } if ( LYInfoAdvanced ) { if ( HText_hasNoCacheSet( HTMainText ) & 255 ) { HTSACat( &temp, gettext( ", no-cache" ) ); } if ( HTAnchor_isISMAPScript( (int)( &HTMainAnchor->parent->parent ) ) & 255 ) { HTSACat( &temp, gettext( ", ISMAP script" ) ); } if ( doc->bookmark ) { HTSACat( &temp, gettext( ", bookmark file" ) ); } } dt_String( fp0, gettext( "mode:" ), temp ); if ( temp ) { free( temp ); temp = 0; } fwrite( "\n</dl>\n", 1, 7, fp0 ); if ( nlinks > 0 ) { fprintf( fp0, "<h2>%s</h2>\n<dl compact>", gettext( "Link that you currently have selected" ) ); dt_String( fp0, gettext( "Linkname:" ), LYGetHiliteStr( doc->link, 0 ) ); if ( lynx_mode == 2 && links[ doc->link ].type == 1 ) { if ( links[ doc->link ].l_form->submit_method ) { int method = links[ doc->link ].l_form->submit_method; char *enctype = &links[ doc->link ].l_form->submit_enctype; dt_String( fp0, gettext( "Method:" ), "POST" ); dt_String( fp0, gettext( "Enctype:" ), "application/x-www-form-urlencoded" ); } if ( links[ doc->link ].l_form->submit_action ) { dt_String( fp0, gettext( "Action:" ), &links[ doc->link ].l_form->submit_action ); } if ( links[ doc->link ].l_form->submit_method == 0 || links[ doc->link ].l_form->submit_action == 0 ) { fprintf( fp0, "<dt> %s\n", gettext( "(Form field)" ) ); } } else { dt_String( fp0, "URL:", "" ); } fwrite( "\n</dl>\n", 1, 7, fp0 ); } else { fprintf( fp0, "<h2>%s</h2>", gettext( "No Links on the current page" ) ); } } EndInternalPage( fp0 ); LYrefresh( ); LYCloseTemp( tempfile ); if ( Title ) { free( Title ); Title = 0; } return 0; } }
/* * print_options writes out the current printer choices to a file * so that the user can select printers in the same way that * they select all other links * printer links look like * * LYNXPRINT://LOCAL_FILE/lines=# print to a local file * LYNXPRINT://TO_SCREEN/lines=# print to the screen * LYNXPRINT://LPANSI/lines=# print to the local terminal * LYNXPRINT://MAIL_FILE/lines=# mail the file * LYNXPRINT://PRINTER/lines=#/number=# print to printer number # */ int print_options(char **newfile, const char *printed_url, int lines_in_file) { static char my_temp[LY_MAXPATH] = "\0"; char *buffer = 0; int count; int pages; FILE *fp0; lynx_list_item_type *cur_printer; if ((fp0 = InternalPageFP(my_temp, TRUE)) == 0) return (-1); LYLocalFileToURL(newfile, my_temp); BeginInternalPage(fp0, PRINT_OPTIONS_TITLE, PRINT_OPTIONS_HELP); fprintf(fp0, "<pre>\n"); /* pages = lines_in_file/66 + 1; */ pages = (lines_in_file + 65) / 66; HTSprintf0(&buffer, " <em>%s</em> %s\n <em>%s</em> %d\n <em>%s</em> %d %s %s\n", gettext("Document:"), printed_url, gettext("Number of lines:"), lines_in_file, gettext("Number of pages:"), pages, (pages > 1 ? gettext("pages") : gettext("page")), gettext("(approximately)")); fputs(buffer, fp0); FREE(buffer); if (no_print || no_disk_save || no_mail) fprintf(fp0, " <em>%s</em>\n", gettext("Some print functions have been disabled!")); fprintf(fp0, "\n%s\n", (user_mode == NOVICE_MODE) ? gettext("Standard print options:") : gettext("Print options:")); if (no_disk_save == FALSE && no_print == FALSE) { fprintf(fp0, " <a href=\"%s//LOCAL_FILE/lines=%d\">%s</a>\n", STR_LYNXPRINT, lines_in_file, gettext("Save to a local file")); } else { fprintf(fp0, " <em>%s</em>\n", gettext("Save to disk disabled")); } if (no_mail == FALSE && local_host_only == FALSE) fprintf(fp0, " <a href=\"%s//MAIL_FILE/lines=%d\">%s</a>\n", STR_LYNXPRINT, lines_in_file, gettext("Mail the file")); #if defined(UNIX) || defined(VMS) fprintf(fp0, " <a href=\"%s//TO_SCREEN/lines=%d\">%s</a>\n", STR_LYNXPRINT, lines_in_file, gettext("Print to the screen")); fprintf(fp0, " <a href=\"%s//LPANSI/lines=%d\">%s</a>\n", STR_LYNXPRINT, lines_in_file, gettext("Print out on a printer attached to your vt100 terminal")); #endif if (user_mode == NOVICE_MODE) fprintf(fp0, "\n%s\n", gettext("Local additions:")); for (count = 0, cur_printer = printers; cur_printer != NULL; cur_printer = cur_printer->next, count++) if (no_print == FALSE || cur_printer->always_enabled) { fprintf(fp0, " <a href=\"%s//PRINTER/number=%d/pagelen=%d/lines=%d\">", STR_LYNXPRINT, count, cur_printer->pagelen, lines_in_file); fprintf(fp0, "%s", (cur_printer->name ? cur_printer->name : "No Name Given")); fprintf(fp0, "</a>\n"); } fprintf(fp0, "</pre>\n"); EndInternalPage(fp0); LYCloseTempFP(fp0); LYforce_no_cache = TRUE; return (0); }
static int LYLoadCGI(const char *arg, HTParentAnchor *anAnchor, HTFormat format_out, HTStream *sink) { int status = 0; #ifdef LYNXCGI_LINKS #ifndef VMS char *cp; struct stat stat_buf; char *pgm = NULL; /* executable */ char *pgm_args = NULL; /* and its argument(s) */ int statrv; char *orig_pgm = NULL; /* Path up to ? as given, URL-escaped */ char *document_root = NULL; /* Corrected value of DOCUMENT_ROOT */ char *path_info = NULL; /* PATH_INFO extracted from pgm */ char *pgm_buff = NULL; /* PATH_INFO extraction buffer */ char *path_translated; /* From document_root/path_info */ if (isEmpty(arg) || strlen(arg) <= 8) { HTAlert(BAD_REQUEST); status = -2; return (status); } else { if (StrNCmp(arg, "lynxcgi://localhost", 19) == 0) { StrAllocCopy(pgm, arg + 19); } else { StrAllocCopy(pgm, arg + 8); } if ((cp = StrChr(pgm, '?')) != NULL) { /* Need to terminate executable */ *cp++ = '\0'; pgm_args = cp; } } StrAllocCopy(orig_pgm, pgm); if (trimPoundSelector(pgm) != NULL) { /* * Strip a #fragment from path. In this case any pgm_args found above * will also be bogus, since the '?' came after the '#' and is part of * the fragment. Note that we don't handle the case where a '#' * appears after a '?' properly according to URL rules. - kw */ pgm_args = NULL; } HTUnEscape(pgm); /* BEGIN WebSter Mods */ /* If pgm is not stat-able, see if PATH_INFO data is at the end of pgm */ if ((statrv = stat(pgm, &stat_buf)) < 0) { StrAllocCopy(pgm_buff, pgm); while (statrv < 0 || (statrv = stat(pgm_buff, &stat_buf)) < 0) { if ((cp = strrchr(pgm_buff, '/')) != NULL) { *cp = '\0'; statrv = 1; /* force new stat() - kw */ } else { PERROR("strrchr(pgm_buff, '/') returned NULL"); break; } } if (statrv < 0) { /* Did not find PATH_INFO data */ PERROR("stat() of pgm_buff failed"); } else { /* Found PATH_INFO data. Strip it off of pgm and into path_info. */ StrAllocCopy(path_info, pgm + strlen(pgm_buff)); /* The following is safe since pgm_buff was derived from pgm by stripping stuff off its end and by HTUnEscaping, so we know we have enough memory allocated for pgm. Note that pgm_args may still point into that memory, so we cannot reallocate pgm here. - kw */ strcpy(pgm, pgm_buff); CTRACE((tfp, "LYNXCGI: stat() of %s succeeded, path_info=\"%s\".\n", pgm_buff, path_info)); } FREE(pgm_buff); } /* END WebSter Mods */ if (statrv != 0) { /* * Neither the path as given nor any components examined by backing up * were stat()able. - kw */ HTAlert(gettext("Unable to access cgi script")); PERROR("stat() failed"); status = -4; } else #ifdef _WINDOWS /* 1998/01/14 (Wed) 09:16:04 */ #define isExecutable(mode) (mode & (S_IXUSR)) #else #define isExecutable(mode) (mode & (S_IXUSR|S_IXGRP|S_IXOTH)) #endif if (!(S_ISREG(stat_buf.st_mode) && isExecutable(stat_buf.st_mode))) { /* * Not a runnable file, See if we can load it using "file:" code. */ char *new_arg = NULL; /* * But try "file:" only if the file we are looking at is the path as * given (no path_info was extracted), otherwise it will be to * confusing to know just what file is loaded. - kw */ if (path_info) { CTRACE((tfp, "%s is not a file and %s not an executable, giving up.\n", orig_pgm, pgm)); FREE(path_info); FREE(pgm); FREE(orig_pgm); status = -4; return (status); } LYLocalFileToURL(&new_arg, orig_pgm); CTRACE((tfp, "%s is not an executable file, passing the buck.\n", arg)); status = HTLoadFile(new_arg, anAnchor, format_out, sink); FREE(new_arg); } else if (path_info && anAnchor != HTMainAnchor && !(reloading && anAnchor->document) && strcmp(arg, HTLoadedDocumentURL()) && HText_AreDifferent(anAnchor, arg) && HTUnEscape(orig_pgm) && !can_exec_cgi(orig_pgm, "")) { /* * If we have extra path info and are not just reloading the current, * check the full file path (after unescaping) now to catch forbidden * segments. - kw */ status = HT_NOT_LOADED; } else if (no_lynxcgi) { HTUserMsg(CGI_DISABLED); status = HT_NOT_LOADED; } else if (no_bookmark_exec && anAnchor != HTMainAnchor && !(reloading && anAnchor->document) && strcmp(arg, HTLoadedDocumentURL()) && HText_AreDifferent(anAnchor, arg) && HTLoadedDocumentBookmark()) { /* * If we are reloading a lynxcgi document that had already been loaded, * the various checks above should allow it even if no_bookmark_exec is * TRUE an we are not now coming from a bookmark page. - kw */ HTUserMsg(BOOKMARK_EXEC_DISABLED); status = HT_NOT_LOADED; } else if (anAnchor != HTMainAnchor && !(reloading && anAnchor->document) && strcmp(arg, HTLoadedDocumentURL()) && HText_AreDifferent(anAnchor, arg) && !can_exec_cgi(pgm, pgm_args)) { /* * If we are reloading a lynxcgi document that had already been loaded, * the various checks above should allow it even if exec_ok() would * reject it because we are not now coming from a document with a URL * allowed by TRUSTED_LYNXCGI rules. - kw */ status = HT_NOT_LOADED; } else { HTFormat format_in; HTStream *target = NULL; /* Unconverted data */ int fd1[2], fd2[2]; char buf[MAX_LINE]; int pid; #ifdef HAVE_TYPE_UNIONWAIT union wait wstatus; #else int wstatus; #endif fd1[0] = -1; fd1[1] = -1; fd2[0] = -1; fd2[1] = -1; if (anAnchor->isHEAD || keep_mime_headers) { /* Show output as plain text */ format_in = WWW_PLAINTEXT; } else { /* Decode full HTTP response */ format_in = HTAtom_for("www/mime"); } target = HTStreamStack(format_in, format_out, sink, anAnchor); if (!target || target == NULL) { char *tmp = 0; HTSprintf0(&tmp, CANNOT_CONVERT_I_TO_O, HTAtom_name(format_in), HTAtom_name(format_out)); HTAlert(tmp); FREE(tmp); status = HT_NOT_LOADED; } else if (anAnchor->post_data && pipe(fd1) < 0) { HTAlert(CONNECT_SET_FAILED); PERROR("pipe() failed"); status = -3; } else if (pipe(fd2) < 0) { HTAlert(CONNECT_SET_FAILED); PERROR("pipe() failed"); close(fd1[0]); close(fd1[1]); status = -3; } else { static BOOL first_time = TRUE; /* One time setup flag */ if (first_time) { /* Set up static environment variables */ first_time = FALSE; /* Only once */ add_environment_value("REMOTE_HOST=localhost"); add_environment_value("REMOTE_ADDR=127.0.0.1"); HTSprintf0(&user_agent, "HTTP_USER_AGENT=%s/%s libwww/%s", LYNX_NAME, LYNX_VERSION, HTLibraryVersion); add_environment_value(user_agent); HTSprintf0(&server_software, "SERVER_SOFTWARE=%s/%s", LYNX_NAME, LYNX_VERSION); add_environment_value(server_software); } fflush(stdout); fflush(stderr); CTRACE_FLUSH(tfp); if ((pid = fork()) > 0) { /* The good, */ ssize_t chars; off_t total_chars; close(fd2[1]); if (anAnchor->post_data) { ssize_t written; int remaining, total_written = 0; close(fd1[0]); /* We have form data to push across the pipe */ if (TRACE) { CTRACE((tfp, "LYNXCGI: Doing post, content-type '%s'\n", anAnchor->post_content_type)); CTRACE((tfp, "LYNXCGI: Writing:\n")); trace_bstring(anAnchor->post_data); CTRACE((tfp, "----------------------------------\n")); } remaining = BStrLen(anAnchor->post_data); while ((written = write(fd1[1], BStrData(anAnchor->post_data) + total_written, (size_t) remaining)) != 0) { if (written < 0) { #ifdef EINTR if (errno == EINTR) continue; #endif /* EINTR */ #ifdef ERESTARTSYS if (errno == ERESTARTSYS) continue; #endif /* ERESTARTSYS */ PERROR("write() of POST data failed"); break; } CTRACE((tfp, "LYNXCGI: Wrote %d bytes of POST data.\n", (int) written)); total_written += (int) written; remaining -= (int) written; if (remaining == 0) break; } if (remaining != 0) { CTRACE((tfp, "LYNXCGI: %d bytes remain unwritten!\n", remaining)); } close(fd1[1]); } HTReadProgress(total_chars = 0, (off_t) 0); while ((chars = read(fd2[0], buf, sizeof(buf))) != 0) { if (chars < 0) { #ifdef EINTR if (errno == EINTR) continue; #endif /* EINTR */ #ifdef ERESTARTSYS if (errno == ERESTARTSYS) continue; #endif /* ERESTARTSYS */ PERROR("read() of CGI output failed"); break; } total_chars += (int) chars; HTReadProgress(total_chars, (off_t) 0); CTRACE((tfp, "LYNXCGI: Rx: %.*s\n", (int) chars, buf)); (*target->isa->put_block) (target, buf, (int) chars); } if (chars < 0 && total_chars == 0) { status = HT_NOT_LOADED; (*target->isa->_abort) (target, NULL); target = NULL; } else if (chars != 0) { status = HT_PARTIAL_CONTENT; } else { status = HT_LOADED; } #ifndef HAVE_WAITPID while (wait(&wstatus) != pid) ; /* do nothing */ #else while (-1 == waitpid(pid, &wstatus, 0)) { /* wait for child */ #ifdef EINTR if (errno == EINTR) continue; #endif /* EINTR */ #ifdef ERESTARTSYS if (errno == ERESTARTSYS) continue; #endif /* ERESTARTSYS */ break; } #endif /* !HAVE_WAITPID */ close(fd2[0]); } else if (pid == 0) { /* The Bad, */ char **argv = NULL; int argv_cnt = 3; /* name, one arg and terminator */ char **cur_argv = NULL; int exec_errno; /* Set up output pipe */ close(fd2[0]); dup2(fd2[1], fileno(stdout)); /* Should check success code */ dup2(fd2[1], fileno(stderr)); close(fd2[1]); if (non_empty(language)) { HTSprintf0(&accept_language, "HTTP_ACCEPT_LANGUAGE=%s", language); add_environment_value(accept_language); } if (non_empty(pref_charset)) { cp = NULL; StrAllocCopy(cp, "HTTP_ACCEPT_CHARSET="); StrAllocCat(cp, pref_charset); add_environment_value(cp); } if (anAnchor->post_data && anAnchor->post_content_type) { cp = NULL; StrAllocCopy(cp, "CONTENT_TYPE="); StrAllocCat(cp, anAnchor->post_content_type); add_environment_value(cp); } if (anAnchor->post_data) { /* post script, read stdin */ close(fd1[1]); dup2(fd1[0], fileno(stdin)); close(fd1[0]); /* Build environment variables */ add_environment_value("REQUEST_METHOD=POST"); HTSprintf0(&post_len, "CONTENT_LENGTH=%d", BStrLen(anAnchor->post_data)); add_environment_value(post_len); } else { close(fileno(stdin)); if (anAnchor->isHEAD) { add_environment_value("REQUEST_METHOD=HEAD"); } } /* * Set up argument line, mainly for <index> scripts */ if (pgm_args != NULL) { for (cp = pgm_args; *cp != '\0'; cp++) { if (*cp == '+') { argv_cnt++; } } } argv = (char **) malloc((unsigned) argv_cnt * sizeof(char *)); if (argv == NULL) { outofmem(__FILE__, "LYCgi"); } assert(argv != NULL); cur_argv = argv + 1; /* For argv[0] */ if (pgm_args != NULL) { char *cr; /* Data for a get/search form */ if (is_www_index) { add_environment_value("REQUEST_METHOD=SEARCH"); } else if (!anAnchor->isHEAD && !anAnchor->post_data) { add_environment_value("REQUEST_METHOD=GET"); } cp = NULL; StrAllocCopy(cp, "QUERY_STRING="); StrAllocCat(cp, pgm_args); add_environment_value(cp); /* * Split up arguments into argv array */ cp = pgm_args; cr = cp; while (1) { if (*cp == '\0') { *(cur_argv++) = HTUnEscape(cr); break; } else if (*cp == '+') { *cp++ = '\0'; *(cur_argv++) = HTUnEscape(cr); cr = cp; } cp++; } } else if (!anAnchor->isHEAD && !anAnchor->post_data) { add_environment_value("REQUEST_METHOD=GET"); } *cur_argv = NULL; /* Terminate argv */ argv[0] = pgm; /* Begin WebSter Mods -jkt */ if (LYCgiDocumentRoot != NULL) { /* Add DOCUMENT_ROOT to env */ cp = NULL; StrAllocCopy(cp, "DOCUMENT_ROOT="); StrAllocCat(cp, LYCgiDocumentRoot); add_environment_value(cp); } if (path_info != NULL) { /* Add PATH_INFO to env */ cp = NULL; StrAllocCopy(cp, "PATH_INFO="); StrAllocCat(cp, path_info); add_environment_value(cp); } if (LYCgiDocumentRoot != NULL && path_info != NULL) { /* Construct and add PATH_TRANSLATED to env */ StrAllocCopy(document_root, LYCgiDocumentRoot); LYTrimHtmlSep(document_root); path_translated = document_root; StrAllocCat(path_translated, path_info); cp = NULL; StrAllocCopy(cp, "PATH_TRANSLATED="); StrAllocCat(cp, path_translated); add_environment_value(cp); FREE(path_translated); } /* End WebSter Mods -jkt */ execve(argv[0], argv, env); exec_errno = errno; PERROR("execve failed"); printf("Content-Type: text/plain\r\n\r\n"); if (!anAnchor->isHEAD) { printf("exec of %s failed", pgm); printf(": %s.\r\n", LYStrerror(exec_errno)); } fflush(stdout); fflush(stderr); _exit(1); } else { /* and the Ugly */ HTAlert(CONNECT_FAILED); PERROR("fork() failed"); close(fd1[0]); close(fd1[1]); close(fd2[0]); close(fd2[1]); status = -1; } } if (target != NULL) { (*target->isa->_free) (target); } } FREE(path_info); FREE(pgm); FREE(orig_pgm); #else /* VMS */ HTStream *target; char *buf = 0; target = HTStreamStack(WWW_HTML, format_out, sink, anAnchor); HTSprintf0(&buf, "<html>\n<head>\n<title>%s</title>\n</head>\n<body>\n", gettext("Good Advice")); PUTS(buf); HTSprintf0(&buf, "<h1>%s</h1>\n", gettext("Good Advice")); PUTS(buf); HTSprintf0(&buf, "%s <a\n", gettext("An excellent http server for VMS is available via")); PUTS(buf); HTSprintf0(&buf, "href=\"http://www.ecr6.ohio-state.edu/www/doc/serverinfo.html\"\n"); PUTS(buf); HTSprintf0(&buf, ">%s</a>.\n", gettext("this link")); PUTS(buf); HTSprintf0(&buf, "<p>%s\n", gettext("It provides state of the art CGI script support.\n")); PUTS(buf); HTSprintf0(&buf, "</body>\n</html>\n"); PUTS(buf); (*target->isa->_free) (target); FREE(buf); status = HT_LOADED; #endif /* VMS */ #else /* LYNXCGI_LINKS */ HTUserMsg(CGI_NOT_COMPILED); status = HT_NOT_LOADED; #endif /* LYNXCGI_LINKS */ (void) arg; (void) anAnchor; (void) format_out; (void) sink; return (status); }
int showlist(DocInfo *newdoc, BOOLEAN titles) { int cnt; int refs, hidden_links; static char tempfile[LY_MAXPATH]; static BOOLEAN last_titles = TRUE; FILE *fp0; char *Address = NULL, *Title = NULL, *cp = NULL; char *LinkTitle = NULL; /* Rel stored as property of link, not of dest */ BOOLEAN intern_w_post = FALSE; const char *desc = "unknown field or link"; void *helper; refs = HText_sourceAnchors(HTMainText); hidden_links = HText_HiddenLinkCount(HTMainText); if (refs <= 0 && hidden_links > 0 && LYHiddenLinks != HIDDENLINKS_SEPARATE) { HTUserMsg(NO_VISIBLE_REFS_FROM_DOC); return (-1); } if (refs <= 0 && hidden_links <= 0) { HTUserMsg(NO_REFS_FROM_DOC); return (-1); } if ((fp0 = InternalPageFP(tempfile, titles == last_titles)) == 0) return (-1); LYLocalFileToURL(&(newdoc->address), tempfile); LYRegisterUIPage(newdoc->address, titles ? UIP_LIST_PAGE : UIP_ADDRLIST_PAGE); last_titles = titles; LYforce_HTML_mode = TRUE; /* force this file to be HTML */ LYforce_no_cache = TRUE; /* force this file to be new */ #ifdef EXP_ADDRLIST_PAGE if (titles != TRUE) BeginInternalPage(fp0, ADDRLIST_PAGE_TITLE, LIST_PAGE_HELP); else #endif BeginInternalPage(fp0, LIST_PAGE_TITLE, LIST_PAGE_HELP); StrAllocCopy(Address, HTLoadedDocumentURL()); LYEntify(&Address, FALSE); fprintf(fp0, "%s%s<p>\n", gettext("References in "), (non_empty(Address) ? Address : gettext("this document:"))); FREE(Address); if (refs > 0) { fprintf(fp0, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); if (hidden_links > 0) fprintf(fp0, "<lh><em>%s</em>\n", gettext("Visible links:")); } if (hidden_links > 0) { if (LYHiddenLinks == HIDDENLINKS_IGNORE) hidden_links = 0; } helper = NULL; /* init */ for (cnt = 1; cnt <= refs; cnt++) { HTChildAnchor *child = HText_childNextNumber(cnt, &helper); HTAnchor *dest_intl = NULL; HTAnchor *dest; HTParentAnchor *parent; char *address; const char *title; if (child == 0) { /* * child should not be 0 unless form field numbering is on and cnt * is the number of a form input field. HText_FormDescNumber() * will set desc to a description of what type of input field this * is. We'll list it to ensure that the link numbers on the list * page match the numbering in the original document, but won't * create a forward link to the form. - FM && LE * * Changed to create a fake hidden link, to get the numbering right * in connection with always treating this file as * HIDDENLINKS_MERGE in GridText.c - kw */ if (fields_are_numbered()) { HText_FormDescNumber(cnt, &desc); fprintf(fp0, "<li><a id=%d href=\"#%d\">form field</a> = <em>%s</em>\n", cnt, cnt, desc); } continue; } #ifndef DONT_TRACK_INTERNAL_LINKS dest_intl = HTAnchor_followTypedLink(child, HTInternalLink); #endif dest = dest_intl ? dest_intl : HTAnchor_followLink(child); parent = HTAnchor_parent(dest); if (!intern_w_post && dest_intl && HTMainAnchor && HTMainAnchor->post_data && parent->post_data && BINEQ(HTMainAnchor->post_data, parent->post_data)) { /* * Set flag to note that we had at least one internal link, if the * document from which we are generating the list has associated * POST data; after an extra check that the link destination really * has the same POST data so that we can believe it is an internal * link. */ intern_w_post = TRUE; } address = HTAnchor_address(dest); title = titles ? HTAnchor_title(parent) : NULL; if (dest_intl) { HTSprintf0(&LinkTitle, "(internal)"); } else if (titles && child->type && dest == child->dest && !strncmp(HTAtom_name(child->type), "RelTitle: ", 10)) { HTSprintf0(&LinkTitle, "(%s)", HTAtom_name(child->type) + 10); } else { FREE(LinkTitle); } StrAllocCopy(Address, address); FREE(address); LYEntify(&Address, TRUE); if (non_empty(title)) { LYformTitle(&Title, title); LYEntify(&Title, TRUE); if (*Title) { cp = findPoundSelector(Address); } else { FREE(Title); } } fprintf(fp0, "<li><a href=\"%s\"%s>%s%s%s%s%s</a>\n", Address, dest_intl ? " TYPE=\"internal link\"" : "", NonNull(LinkTitle), ((HTAnchor *) parent != dest) && Title ? "in " : "", (char *) (Title ? Title : Address), (Title && cp) ? " - " : "", (Title && cp) ? (cp + 1) : ""); FREE(Address); FREE(Title); } FREE(LinkTitle); if (hidden_links > 0) { if (refs > 0) fprintf(fp0, "\n</%s>\n\n<p>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); fprintf(fp0, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol continue" : "ul")); fprintf(fp0, "<lh><em>%s</em>\n", gettext("Hidden links:")); } for (cnt = 0; cnt < hidden_links; cnt++) { StrAllocCopy(Address, HText_HiddenLinkAt(HTMainText, cnt)); LYEntify(&Address, FALSE); if (isEmpty(Address)) { FREE(Address); continue; } fprintf(fp0, "<li><a href=\"%s\">%s</a>\n", Address, Address); FREE(Address); } fprintf(fp0, "\n</%s>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); EndInternalPage(fp0); LYCloseTempFP(fp0); /* * Make necessary changes to newdoc before returning to caller. If the * intern_w_post flag is set, we keep the POST data in newdoc that have * been passed in. They should be the same as in the loaded document for * which we generated the list. In that case the file we have written will * be associated with the same POST data when it is loaded after we are * done here, so that following one of the links we have marked as * "internal link" can lead back to the underlying document with the right * address+post_data combination. - kw */ if (intern_w_post) { newdoc->internal_link = TRUE; } else { LYFreePostData(newdoc); newdoc->internal_link = FALSE; } newdoc->isHEAD = FALSE; newdoc->safe = FALSE; return (0); }