#include "HTUtils.h"
#include "tcp.h"
#include "HTAccess.h"
#include "HTList.h"
#include "HTAlert.h"
#include "HTFile.h"
#include "LYCurses.h"
#include "GridText.h"
#include "LYUtils.h"
#include "LYPrint.h"
#include "LYGlobalDefs.h"
#include "LYSignal.h"
#include "LYStrings.h"
#include "LYClean.h"
#include "LYGetFile.h"
#include "LYHistory.h"
#include "LYSystem.h"
#include "LYList.h"
#ifdef VMS
#include "HTVMSUtils.h"
#endif /* VMS */
#ifdef DOSPATH
#include "HTDOS.h"
#endif
#ifdef EXP_CHARTRANS
#include "LYCharSets.h" /* to get current charset for mail header */
extern BOOLEAN LYHaveCJKCharacterSet;
#endif
#include "LYLeaks.h"
#define FREE(x) if (x) {free(x); x = NULL;}
/*
* printfile prints out the current file minus the links and targets
* to a veriaty of places
*/
/* it parses an incoming link that looks like
*
* LYNXPRINT://LOCAL_FILE/lines=##
* LYNXPRINT://MAIL_FILE/lines=##
* LYNXPRINT://TO_SCREEN/lines=##
* LYNXPRINT://PRINTER/lines=##/number=#
*/
#define TO_FILE 1
#define TO_SCREEN 2
#define MAIL 3
#define PRINTER 4
#ifdef VMS
PRIVATE int remove_quotes PARAMS((char *string));
#endif /* VMS */
PUBLIC int printfile ARGS1(
document *, newdoc)
{
static char tempfile[256];
static BOOLEAN first = TRUE;
char buffer[LINESIZE];
char filename[LINESIZE];
char user_response[256];
int lines_in_file = 0;
int printer_number = 0;
int pages = 0;
int type = 0, c, len;
FILE *outfile_fp;
char *cp = NULL;
lynx_printer_item_type *cur_printer;
char *sug_filename = NULL;
char *link_info = NULL;
DocAddress WWWDoc;
int pagelen = 0;
int ch, recall;
int FnameTotal;
int FnameNum;
BOOLEAN FirstRecall = TRUE;
char *content_base = NULL, *content_location = NULL;
HTFormat format;
HTAtom *encoding;
BOOL use_mime, use_cte, use_type;
char *disp_charset;
#ifdef VMS
extern BOOLEAN HadVMSInterrupt;
#endif /* VMS */
/*
* Extract useful info from URL.
*/
StrAllocCopy(link_info, newdoc->address+12);
/*
* Reload the file we want to print into memory.
*/
LYpop(newdoc);
WWWDoc.address = newdoc->address;
WWWDoc.post_data = newdoc->post_data;
WWWDoc.post_content_type = newdoc->post_content_type;
WWWDoc.bookmark = newdoc->bookmark;
WWWDoc.isHEAD = newdoc->isHEAD;
WWWDoc.safe = newdoc->safe;
if (!HTLoadAbsolute(&WWWDoc))
return(NOT_FOUND);
/*
* If document is source, load the content_base
* and content_location strings. - FM
*/
if (HTisDocumentSource()) {
if (HText_getContentBase()) {
StrAllocCopy(content_base, HText_getContentBase());
collapse_spaces(content_base);
if (!(content_base && *content_base)) {
FREE(content_base);
}
}
if (HText_getContentLocation()) {
StrAllocCopy(content_location, HText_getContentLocation());
collapse_spaces(content_location);
if (!(content_location && *content_location)) {
FREE(content_location);
}
}
if (!content_base) {
if ((content_location) && is_url(content_location)) {
StrAllocCopy(content_base, content_location);
} else {
StrAllocCopy(content_base, newdoc->address);
}
}
if (!content_location) {
StrAllocCopy(content_location, newdoc->address);
}
}
/*
* Load the suggested filename string. - FM
*/
if (HText_getSugFname() != NULL)
StrAllocCopy(sug_filename, HText_getSugFname()); /* must be freed */
else
StrAllocCopy(sug_filename, newdoc->address); /* must be freed */
/*
* Strip any gzip or compress suffix, if present. - FM
*/
cp = NULL;
if (strlen(sug_filename) > 3) {
cp = (char *)&sug_filename[(strlen(sug_filename) - 3)];
if ((*cp == '.' || *cp == '-' || *cp == '_') &&
!strcasecomp((cp + 1), "gz")) {
*cp = '\0';
} else {
cp = NULL;
}
}
if ((cp == NULL) && strlen(sug_filename) > 2) {
cp = (char *)&sug_filename[(strlen(sug_filename) - 2)];
if ((*cp == '.' || *cp == '-' || *cp == '_') &&
!strcasecomp((cp + 1), "Z")) {
*cp = '\0';
}
}
cp = NULL;
/*
* Get the number of lines in the file.
*/
if ((cp = (char *)strstr(link_info, "lines=")) != NULL) {
/*
* Terminate prev string here.
*/
*cp = '\0';
/*
* Number of characters in "lines=".
*/
cp += 6;
lines_in_file = atoi(cp);
pages = lines_in_file/66;
}
/*
* Determine the type.
*/
if (strstr(link_info, "LOCAL_FILE")) {
type = TO_FILE;
} else if (strstr(link_info, "TO_SCREEN")) {
type = TO_SCREEN;
} else if (strstr(link_info, "MAIL_FILE")) {
type = MAIL;
} else if (strstr(link_info, "PRINTER")) {
type = PRINTER;
if ((cp = (char *)strstr(link_info, "number=")) != NULL) {
/* number of characters in "number=" */
cp += 7;
printer_number = atoi(cp);
}
if ((cp = (char *)strstr(link_info, "pagelen=")) != NULL) {
/* number of characters in "pagelen=" */
cp += 8;
pagelen = atoi(cp);
} else {
/* default to 66 lines */
pagelen = 66;
}
}
/*
* Set up the sug_filenames recall buffer.
*/
FnameTotal = (sug_filenames ? HTList_count(sug_filenames) : 0);
recall = ((FnameTotal >= 1) ? RECALL : NORECALL);
FnameNum = FnameTotal;
/*
* Act on the request. - FM
*/
switch (type) {
case TO_FILE:
_statusline(FILENAME_PROMPT);
retry: strcpy(filename, sug_filename); /* add suggestion info */
/* make the sug_filename conform to system specs */
change_sug_filename(filename);
if (!(HTisDocumentSource()) &&
(cp = strrchr(filename, '.')) != NULL) {
format = HTFileFormat(filename, &encoding);
if (!strcasecomp(format->name, "text/html")) {
*cp = '\0';
strcat(filename, ".txt");
}
}
if (lynx_save_space && *lynx_save_space) {
strcpy(buffer, lynx_save_space);
strcat(buffer, filename);
strcpy(filename, buffer);
}
check_recall:
if ((ch = LYgetstr(filename, VISIBLE,
sizeof(filename), recall)) < 0 ||
*filename == '\0' || ch == UPARROW || ch == DNARROW) {
if (recall && ch == UPARROW) {
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) {
strcpy(filename, cp);
if (FnameTotal == 1) {
_statusline(EDIT_THE_PREV_FILENAME);
} else {
_statusline(EDIT_A_PREV_FILENAME);
}
goto check_recall;
}
} else if (recall && ch == DNARROW) {
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) {
strcpy(filename, cp);
if (FnameTotal == 1) {
_statusline(EDIT_THE_PREV_FILENAME);
} else {
_statusline(EDIT_A_PREV_FILENAME);
}
goto check_recall;
}
}
/*
* Save cancelled.
*/
_statusline(SAVE_REQUEST_CANCELLED);
sleep(InfoSecs);
break;
}
if (no_dotfiles || !show_dotfiles) {
if (*filename == '.' ||
#ifdef VMS
((cp = strrchr(filename, ':')) && *(cp+1) == '.') ||
((cp = strrchr(filename, ']')) && *(cp+1) == '.') ||
#endif /* VMS */
((cp = strrchr(filename, '/')) && *(cp+1) == '.')) {
HTAlert(FILENAME_CANNOT_BE_DOT);
_statusline(NEW_FILENAME_PROMPT);
FirstRecall = TRUE;
FnameNum = FnameTotal;
goto retry;
}
}
/*
* Cancel if the user entered "/dev/null" on Unix,
* or an "nl:" path (case-insensitive) on VMS. - FM
*/
#ifdef VMS
if (!strncasecomp(filename, "nl:", 3) ||
!strncasecomp(filename, "/nl/", 4))
#else
if (!strcmp(filename, "/dev/null"))
#endif /* VMS */
{
_statusline(SAVE_REQUEST_CANCELLED);
sleep(InfoSecs);
break;
}
if ((cp = strchr(filename, '~'))) {
*(cp++) = '\0';
strcpy(buffer, filename);
if ((len=strlen(buffer)) > 0 && buffer[len-1] == '/')
buffer[len-1] = '\0';
#ifdef DOSPATH
strcat(buffer, HTDOS_wwwName((char *)Home_Dir()));
#else
#ifdef VMS
strcat(buffer, HTVMS_wwwName((char *)Home_Dir()));
#else
strcat(buffer, Home_Dir());
#endif /* VMS */
#endif /* DOSPATH */
strcat(buffer, cp);
strcpy(filename, buffer);
}
#ifdef VMS
if (strchr(filename, '/') != NULL) {
strcpy(buffer, HTVMS_name("", filename));
strcpy(filename, buffer);
}
if (filename[0] != '/' && strchr(filename, ':') == NULL) {
strcpy(buffer, "sys$disk:");
if (strchr(filename, ']') == NULL)
strcat(buffer, "[]");
strcat(buffer, filename);
} else {
strcpy(buffer, filename);
}
#else
if (*filename != '/')
cp = getenv("PWD");
else
cp = NULL;
if (cp)
#ifdef DOSPATH
sprintf(buffer,"%s/%s", cp, HTDOS_name(filename));
#else
sprintf(buffer, "%s/%s", cp, filename);
#endif
else
#ifdef DOSPATH
strcpy(buffer, HTDOS_name(filename));
#else
strcpy(buffer, filename);
#endif
#endif /* VMS */
/*
* See if it already exists.
*/
if ((outfile_fp = fopen(buffer, "r")) != NULL) {
fclose(outfile_fp);
#ifdef VMS
_statusline(FILE_EXISTS_HPROMPT);
#else
_statusline(FILE_EXISTS_OPROMPT);
#endif /* VMS */
c = 0;
while (TOUPPER(c)!='Y' && TOUPPER(c)!='N' &&
c != 7 && c != 3)
c = LYgetch();
#ifdef VMS
if (HadVMSInterrupt) {
HadVMSInterrupt = FALSE;
_statusline(SAVE_REQUEST_CANCELLED);
sleep(InfoSecs);
break;
}
#endif /* VMS */
if (c == 7 || c == 3) { /* Control-G or Control-C */
_statusline(SAVE_REQUEST_CANCELLED);
sleep(InfoSecs);
break;
}
if (TOUPPER(c) == 'N') {
_statusline(NEW_FILENAME_PROMPT);
FirstRecall = TRUE;
FnameNum = FnameTotal;
goto retry;
}
}
if ((outfile_fp = fopen(buffer,"w")) == NULL) {
HTAlert(CANNOT_WRITE_TO_FILE);
_statusline(NEW_FILENAME_PROMPT);
FirstRecall = TRUE;
FnameNum = FnameTotal;
goto retry;
}
chmod(buffer, 0600);
if (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
*/
fprintf(outfile_fp,
"\n
\n", fp0); if (child_lynx == FALSE && no_disk_save == FALSE && no_print == FALSE) fprintf(fp0, " Save to a local file\n", lines_in_file); else fprintf(fp0," Save to disk disabled.\n"); if (child_lynx == FALSE && no_mail == FALSE) fprintf(fp0, " Mail the file\n", lines_in_file); fprintf(fp0, " Print to the screen\n", lines_in_file); 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, " ", count, cur_printer->pagelen, lines_in_file); fprintf(fp0, (cur_printer->name ? cur_printer->name : "No Name Given")); fprintf(fp0, "\n"); } fprintf(fp0, "\n\n"); fclose(fp0); LYforce_no_cache = TRUE; return(0); }