int LYUpload( char *line ) { int eax; char *method, *directory; int method_number; int count; char *the_upload = 0; char tmpbuf[256]; char *filename = 0; lynx_list_item_type *upload_command = 0; char *the_command = 0; directory = strstr( line, "TO=" ); if ( directory != 0 ) { directory[ -1 ] = 0; directory += 3; method = strstr( line, "UPLOAD=" ); if ( method != 0 ) { method += 7; method_number = atoi( method ); count = 0; upload_command = uploaders; for ( ; count < method_number; upload_command = &upload_command ) { count++; //upload_command = &upload_command; } if ( upload_command->command == 0 ) { HTAlert( gettext( "ERROR! - upload command is misconfigured" ) ); } if ( HTCountCommandArgs( upload_command->command ) != 0 ) { mustshow = 1; statusline( gettext( "Enter a filename: " ) ); do { tmpbuf[0] = 0; if ( LYgetstr( tmpbuf, 0, 256, 0 ) >= 0 && ( tmpbuf[0] & 255 ) != 0 ) { if ( strstr( tmpbuf, "../" ) != 0 ) { HTAlert( gettext( "Illegal redirection \"../\" found! Request ignored." ) ); } if ( strchr( tmpbuf, 47 ) != 0 ) { HTAlert( gettext( "Illegal character \"/\" found! Request ignored." ) ); } if ( tmpbuf[0] == '~' ) { HTAlert( gettext( "Illegal redirection using \"~\" found! Request ignored." ) ); } HTSprintf0( &filename, "%s/%s", directory, tmpbuf[0] ); if ( filename[0] == '|' ) { HTAlert( gettext( "Cannot write to file." ) ); mustshow = 1; statusline( gettext( "Enter a new filename: " ) ); } switch ( LYValidateOutput( filename ) ) { case 89: if ( ( WWW_TraceFlag & 255 ) != 0 ) { fprintf( TraceFP( ), "LYUpload: filename is %s", filename ); } break; default: HTInfoMsg( gettext( "Cancelling!" ) ); if ( ( 0 ^ 0 ) != 0 ) { __stack_chk_fail( ); break; } break; } } } while ( ( LYCanWriteFile( filename ) & 255 ) == 0 ); HTAddParam( &the_upload, upload_command->command, 1, filename ); HTEndParam( &the_upload, upload_command->command, 1 ); } else { HTSACopy( &the_upload, upload_command->command ); HTAddParam( &the_command, "cd %s ; ", 1, directory ); HTEndParam( &the_command, "cd %s ; ", 1 ); HTSACat( &the_command, the_upload ); if ( ( WWW_TraceFlag & 255 ) != 0 ) { fprintf( TraceFP( ), "command: %s\n", the_command ); } stop_curses( ); LYSystem( the_command ); start_curses( ); if ( the_command != 0 ) { free( the_command ); the_command = 0; } if ( the_upload != 0 ) { free( the_upload ); the_upload = 0; } if ( filename != 0 ) chmod( filename, 384 ); if ( filename != 0 ) { free( filename ); filename = 0; } } } } HTAlert( gettext( "Unable to upload file." ) ); }
void LYDownload(char *line) { char *Line = NULL, *method, *file, *sug_file = NULL; int method_number; int count; char *the_command = 0; bstring *buffer = NULL; bstring *command = NULL; char *cp; lynx_list_item_type *download_command = 0; int ch; RecallType recall; int FnameTotal; int FnameNum; BOOLEAN FirstRecall = TRUE; BOOLEAN SecondS = FALSE; #ifdef VMS LYDidRename = FALSE; #endif /* VMS */ /* * Make sure we have a valid download file comparison string loaded via the * download options menu. - FM */ if (LYValidDownloadFile[0] == '\0') { goto failed; } /* * Make a copy of the LYNXDOWNLOAD internal URL for parsing. - FM */ StrAllocCopy(Line, line); /* * Parse out the File, sug_file, and the Method. */ if ((file = strstr(Line, "/File=")) == NULL) goto failed; *file = '\0'; /* * Go past "File=". */ file += 6; if ((sug_file = strstr(file + 1, "/SugFile=")) != NULL) { *sug_file = '\0'; /* * Go past "SugFile=". */ sug_file += 9; HTUnEscape(sug_file); } /* * Make sure that the file string is the one from the last displayed * download options menu. - FM */ if (strcmp(file, LYValidDownloadFile)) { goto failed; } #if defined(DIRED_SUPPORT) /* FIXME: use HTLocalName */ if (!StrNCmp(file, "file://localhost", 16)) { #ifdef __DJGPP__ if (!StrNCmp(file + 16, "/dev/", 5)) file += 16; else { file += 17; file = HTDOS_name(file); } #else file += 16; #endif /* __DJGPP__ */ } else if (isFILE_URL(file)) file += LEN_FILE_URL; HTUnEscape(file); #else #if defined(_WINDOWS) /* 1997/10/15 (Wed) 16:27:38 */ if (!StrNCmp(file, "file://localhost/", 17)) file += 17; else if (!StrNCmp(file, "file:/", 6)) file += 6; HTUnEscape(file); #endif /* _WINDOWS */ #endif /* DIRED_SUPPORT */ if ((method = strstr(Line, "Method=")) == NULL) goto failed; /* * Go past "Method=". */ method += 7; method_number = atoi(method); /* * Set up the sug_filenames recall buffer. */ FnameTotal = (sug_filenames ? HTList_count(sug_filenames) : 0); recall = ((FnameTotal >= 1) ? RECALL_URL : NORECALL); FnameNum = FnameTotal; if (method_number < 0) { /* * Write to local file. */ _statusline(FILENAME_PROMPT); retry: if (sug_file) { BStrCopy0(buffer, sug_file); } else { BStrCopy0(buffer, ""); } check_recall: if ((ch = LYgetBString(&buffer, FALSE, 0, recall)) < 0 || isBEmpty(buffer) || ch == UPARROW_KEY || ch == DNARROW_KEY) { if (recall && ch == UPARROW_KEY) { if (FirstRecall) { FirstRecall = FALSE; /* * Use the last Fname in the list. - FM */ FnameNum = 0; } else { /* * Go back to the previous Fname in the list. - FM */ FnameNum++; } if (FnameNum >= FnameTotal) { /* * Reset the FirstRecall flag, and use sug_file or a blank. * - FM */ FirstRecall = TRUE; FnameNum = FnameTotal; _statusline(FILENAME_PROMPT); goto retry; } else if ((cp = (char *) HTList_objectAt(sug_filenames, FnameNum)) != NULL) { BStrCopy0(buffer, cp); if (FnameTotal == 1) { _statusline(EDIT_THE_PREV_FILENAME); } else { _statusline(EDIT_A_PREV_FILENAME); } goto check_recall; } } else if (recall && ch == DNARROW_KEY) { if (FirstRecall) { FirstRecall = FALSE; /* * Use the first Fname in the list. - FM */ FnameNum = FnameTotal - 1; } else { /* * Advance to the next Fname in the list. - FM */ FnameNum--; } if (FnameNum < 0) { /* * Set the FirstRecall flag, and use sug_file or a blank. * - FM */ FirstRecall = TRUE; FnameNum = FnameTotal; _statusline(FILENAME_PROMPT); goto retry; } else if ((cp = (char *) HTList_objectAt(sug_filenames, FnameNum)) != NULL) { BStrCopy0(buffer, cp); if (FnameTotal == 1) { _statusline(EDIT_THE_PREV_FILENAME); } else { _statusline(EDIT_A_PREV_FILENAME); } goto check_recall; } } /* * Save cancelled. */ goto cancelled; } BStrCopy(command, buffer); if (!LYValidateFilename(&buffer, &command)) goto cancelled; #ifdef HAVE_POPEN else if (LYIsPipeCommand(buffer->str)) { /* I don't know how to download to a pipe */ HTAlert(CANNOT_WRITE_TO_FILE); _statusline(NEW_FILENAME_PROMPT); FirstRecall = TRUE; FnameNum = FnameTotal; goto retry; } #endif /* * See if it already exists. */ switch (LYValidateOutput(buffer->str)) { case 'Y': break; case 'N': _statusline(NEW_FILENAME_PROMPT); FirstRecall = TRUE; FnameNum = FnameTotal; goto retry; default: goto cleanup; } /* * See if we can write to it. */ CTRACE((tfp, "LYDownload: filename is %s\n", buffer->str)); SecondS = TRUE; HTInfoMsg(SAVING); #ifdef VMS /* * Try rename() first. - FM */ CTRACE((tfp, "command: rename(%s, %s)\n", file, buffer->str)); if (rename(file, buffer->str)) { /* * Failed. Use spawned COPY_COMMAND. - FM */ CTRACE((tfp, " FAILED!\n")); LYCopyFile(file, buffer->str); } else { /* * We don't have the temporary file (it was renamed to a permanent * file), so set a flag to pop out of the download menu. - FM */ LYDidRename = TRUE; } chmod(buffer->str, HIDE_CHMOD); #else /* Unix: */ LYCopyFile(file, buffer->str); LYRelaxFilePermissions(buffer->str); #endif /* VMS */ } else { /* * Use configured download commands. */ BStrCopy0(buffer, ""); for (count = 0, download_command = downloaders; count < method_number; count++, download_command = download_command->next) ; /* null body */ /* * Commands have the form "command %s [etc]" where %s is the filename. */ if (download_command->command != NULL) { /* * Check for two '%s' and ask for the local filename if there is. */ if (HTCountCommandArgs(download_command->command) >= 2) { _statusline(FILENAME_PROMPT); again: if (sug_file) { BStrCopy0(buffer, sug_file); } else { BStrCopy0(buffer, ""); } check_again: if ((ch = LYgetBString(&buffer, FALSE, 0, recall)) < 0 || isBEmpty(buffer) || ch == UPARROW_KEY || ch == DNARROW_KEY) { if (recall && ch == UPARROW_KEY) { if (FirstRecall) { FirstRecall = FALSE; /* * Use the last Fname in the list. - FM */ FnameNum = 0; } else { /* * Go back to the previous Fname in the list. - FM */ FnameNum++; } if (FnameNum >= FnameTotal) { /* * Reset the FirstRecall flag, and use sug_file or * a blank. - FM */ FirstRecall = TRUE; FnameNum = FnameTotal; _statusline(FILENAME_PROMPT); goto again; } else if ((cp = (char *) HTList_objectAt(sug_filenames, FnameNum)) != NULL) { BStrCopy0(buffer, cp); if (FnameTotal == 1) { _statusline(EDIT_THE_PREV_FILENAME); } else { _statusline(EDIT_A_PREV_FILENAME); } goto check_again; } } else if (recall && ch == DNARROW_KEY) { if (FirstRecall) { FirstRecall = FALSE; /* * Use the first Fname in the list. - FM */ FnameNum = FnameTotal - 1; } else { /* * Advance to the next Fname in the list. - FM */ FnameNum--; } if (FnameNum < 0) { /* * Set the FirstRecall flag, and use sug_file or a * blank. - FM */ FirstRecall = TRUE; FnameNum = FnameTotal; _statusline(FILENAME_PROMPT); goto again; } else if ((cp = (char *) HTList_objectAt(sug_filenames, FnameNum)) != NULL) { BStrCopy0(buffer, cp); if (FnameTotal == 1) { _statusline(EDIT_THE_PREV_FILENAME); } else { _statusline(EDIT_A_PREV_FILENAME); } goto check_again; } } /* * Download cancelled. */ goto cancelled; } if (no_dotfiles || !show_dotfiles) { if (*LYPathLeaf(buffer->str) == '.') { HTAlert(FILENAME_CANNOT_BE_DOT); _statusline(NEW_FILENAME_PROMPT); goto again; } } /* * Cancel if the user entered "/dev/null" on Unix, or an "nl:" * path on VMS. - FM */ if (LYIsNullDevice(buffer->str)) { goto cancelled; } SecondS = TRUE; } /* * The following is considered a bug by the community. If the * command only takes one argument on the command line, then the * suggested file name is not used. It actually is not a bug at * all and does as it should, putting both names on the command * line. */ count = 1; HTAddParam(&the_command, download_command->command, count, file); if (HTCountCommandArgs(download_command->command) > 1) HTAddParam(&the_command, download_command->command, ++count, buffer->str); HTEndParam(&the_command, download_command->command, count); } else { HTAlert(MISCONF_DOWNLOAD_COMMAND); goto failed; } CTRACE((tfp, "command: %s\n", the_command)); stop_curses(); LYSystem(the_command); FREE(the_command); start_curses(); /* don't remove(file); */ } if (SecondS == TRUE) { #ifdef VMS if (0 == strncasecomp(buffer->str, "sys$disk:", 9)) { if (0 == StrNCmp((buffer->str + 9), "[]", 2)) { HTAddSugFilename(buffer->str + 11); } else { HTAddSugFilename(buffer->str + 9); } } else { HTAddSugFilename(buffer->str); } #else HTAddSugFilename(buffer->str); #endif /* VMS */ } goto cleanup; failed: HTAlert(CANNOT_DOWNLOAD_FILE); goto cleanup; cancelled: HTInfoMsg(CANCELLING); cleanup: FREE(Line); BStrFree(buffer); return; }
static void send_file_to_file(DocInfo *newdoc, char *content_base, char *sug_filename) { BOOLEAN FirstRecall = TRUE; BOOLEAN use_cte; const char *disp_charset; FILE *outfile_fp; bstring *buffer = NULL; bstring *filename = NULL; int FnameNum = -1; int FnameTotal; int c = 0; _statusline(FILENAME_PROMPT); retry: SetupFilename(&filename, sug_filename); if (lynx_save_space) { BStrCopy0(buffer, lynx_save_space); BStrCat(buffer, filename); BStrCopy(filename, buffer); } else { BStrCopy0(buffer, ""); } check_recall: switch (RecallFilename(&filename, &FirstRecall, &FnameNum, &FnameTotal, PRINT_FLAG)) { case FN_INIT: goto retry; case FN_READ: goto check_recall; case FN_QUIT: goto done; default: break; } if (!LYValidateFilename(&buffer, &filename)) { CancelPrint(SAVE_REQUEST_CANCELLED); } /* * See if it already exists. */ switch (c = LYValidateOutput(buffer->str)) { case 'Y': break; case 'N': _statusline(NEW_FILENAME_PROMPT); FirstRecall = TRUE; FnameNum = FnameTotal; goto retry; default: goto done; } /* * See if we can write to it. */ CTRACE((tfp, "LYPrint: filename is %s, action is `%c'\n", buffer->str, c)); #ifdef HAVE_POPEN if (buffer->str[0] == '|') { if (no_shell) { HTUserMsg(SPAWNING_DISABLED); FirstRecall = TRUE; FnameNum = FnameTotal; goto retry; } else if ((outfile_fp = popen(buffer->str + 1, "w")) == NULL) { CTRACE((tfp, "LYPrint: errno is %d\n", errno)); HTAlert(CANNOT_WRITE_TO_FILE); _statusline(NEW_FILENAME_PROMPT); FirstRecall = TRUE; FnameNum = FnameTotal; goto retry; } } else #endif if ((outfile_fp = (TOUPPER(c) == 'A' ? LYAppendToTxtFile(buffer->str) : LYNewTxtFile(buffer->str))) == NULL) { CTRACE((tfp, "LYPrint: errno is %d\n", errno)); HTAlert(CANNOT_WRITE_TO_FILE); _statusline(NEW_FILENAME_PROMPT); FirstRecall = TRUE; FnameNum = FnameTotal; goto retry; } if (LYPrependBaseToSource && HTisDocumentSource()) { /* * Added the document's base as a BASE tag to the top of the file. May * create technically invalid HTML, but will help get any partial or * relative URLs resolved properly if no BASE tag is present to replace * it. - FM * * Add timestamp (last reload). */ fprintf(outfile_fp, "<!-- X-URL: %s -->\n", newdoc->address); if (HText_getDate() != NULL) { fprintf(outfile_fp, "<!-- Date: %s -->\n", HText_getDate()); if (HText_getLastModified() != NULL && strcmp(HText_getLastModified(), HText_getDate()) && strcmp(HText_getLastModified(), "Thu, 01 Jan 1970 00:00:01 GMT")) { fprintf(outfile_fp, "<!-- Last-Modified: %s -->\n", HText_getLastModified()); } } fprintf(outfile_fp, "<BASE HREF=\"%s\">\n", content_base); } if (LYPrependCharsetToSource && HTisDocumentSource()) { /* * Added the document's charset as a META CHARSET tag to the top of the * file. May create technically invalid HTML, but will help to resolve * properly the document converted via chartrans: printed document * correspond to a display charset and we *should* override both * assume_local_charset and original document's META CHARSET (if any). * * Currently, if several META CHARSETs are found Lynx uses the first * only, and it is opposite to BASE where the original BASE in the * <HEAD> overrides ones from the top. * * As in print-to-email we write charset only if the document has 8-bit * characters, and we have no CJK or an unofficial "x-" charset. */ use_cte = HTLoadedDocumentEightbit(); disp_charset = LYCharSet_UC[current_char_set].MIMEname; if (!use_cte || LYHaveCJKCharacterSet || strncasecomp(disp_charset, "x-", 2) == 0) { } else { fprintf(outfile_fp, "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=%s\">\n\n", disp_charset); } } print_wwwfile_to_fd(outfile_fp, FALSE, FALSE); /* FILE */ if (keypad_mode) printlist(outfile_fp, FALSE); #ifdef HAVE_POPEN if (LYIsPipeCommand(buffer->str)) pclose(outfile_fp); else #endif LYCloseOutput(outfile_fp); #ifdef VMS if (0 == strncasecomp(buffer->str, "sys$disk:", 9)) { if (0 == StrNCmp((buffer->str + 9), "[]", 2)) { HTAddSugFilename(buffer->str + 11); } else { HTAddSugFilename(buffer->str + 9); } } else { HTAddSugFilename(buffer->str); } #else HTAddSugFilename(buffer->str); #endif /* VMS */ done: BStrFree(buffer); BStrFree(filename); return; }