#include "HTUtils.h"
#include "tcp.h"
#include "HTAccess.h"
#include "HTParse.h"
#include "HTList.h"
#include "HTFTP.h"
#include "HTFile.h"
#include "HTTP.h"
#include "LYCurses.h"
#include "LYStyle.h"
#include "LYGlobalDefs.h"
#include "HTAlert.h"
#include "LYUtils.h"
#include "GridText.h"
#include "LYStrings.h"
#include "LYOptions.h"
#include "LYSignal.h"
#include "LYGetFile.h"
#include "HTForms.h"
#include "LYSearch.h"
#include "LYClean.h"
#include "LYHistory.h"
#include "LYPrint.h"
#include "LYMail.h"
#include "LYEdit.h"
#include "LYShowInfo.h"
#include "LYBookmark.h"
#include "LYSystem.h"
#include "LYKeymap.h"
#include "LYJump.h"
#include "LYDownload.h"
#include "LYList.h"
#include "LYMap.h"
#include "LYTraversal.h"
#include "LYCharSets.h"
#include "LYCharUtils.h"
#include "LYCookie.h"
#include "LYMainLoop.h"
#ifdef DOSPATH
#include "HTDOS.h"
#endif
#ifdef USE_EXTERNALS
#include "LYExtern.h"
#endif
#ifdef VMS
#include "HTVMSUtils.h"
#endif /* VMS */
#ifdef DIRED_SUPPORT
#include "LYLocal.h"
#include "LYUpload.h"
#endif /* DIRED_SUPPORT */
#include "LYexit.h"
#include "LYLeaks.h"
PRIVATE int are_different PARAMS((document *doc1, document *doc2));
PRIVATE int are_phys_different PARAMS((document *doc1, document *doc2));
PUBLIC void HTGotoURLs_free NOPARAMS;
PUBLIC void HTAddGotoURL PARAMS((char *url));
#define FASTTAB
#ifdef FASTTAB
PRIVATE int sametext ARGS2(
char *, een,
char *, twee)
{
if (een && twee)
return (strcmp(een, twee) == 0);
return TRUE;
}
#endif /* FASTTAB */
#define FREE(x) if (x) {free(x); x = NULL;}
PUBLIC HTList * Goto_URLs = NULL; /* List of Goto URLs */
PUBLIC char * LYRequestTitle = NULL; /* newdoc.title in calls to getfile() */
PRIVATE document newdoc;
PRIVATE document curdoc;
PRIVATE char *traversal_host = NULL;
PRIVATE char *traversal_link_to_add = NULL;
PRIVATE char *CurrentUserAgent = NULL;
PRIVATE char *CurrentNegoLanguage = NULL;
PRIVATE char *CurrentNegoCharset = NULL;
/*
* Function for freeing allocated mainloop() variables. - FM
*/
PRIVATE void free_mainloop_variables NOARGS
{
FREE(newdoc.title);
FREE(newdoc.address);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
FREE(curdoc.title);
FREE(curdoc.address);
FREE(curdoc.post_data);
FREE(curdoc.post_content_type);
FREE(curdoc.bookmark);
#ifdef USE_HASH
FREE(curdoc.style);
FREE(newdoc.style);
#endif
FREE(traversal_host);
FREE(traversal_link_to_add);
FREE(CurrentUserAgent);
FREE(CurrentNegoLanguage);
FREE(CurrentNegoCharset);
#ifdef DIRED_SUPPORT
clear_tags();
#endif /* DIRED_SUPPORT */
return;
}
/*
* Here's where we do all the work.
* mainloop is basically just a big switch dependent on the users input.
* I have tried to offload most of the work done here to procedures to
* make it more modular, but this procedure still does a lot of variable
* manipulation. This needs some work to make it neater. - Lou Moutilli
* (memoir from the original Lynx - FM)
*/
int mainloop NOARGS
{
int c = 0, real_c = 0, old_c = 0, cmd, real_cmd = LYK_DO_NOTHING;
int getresult;
int arrowup = FALSE, show_help = FALSE;
int lines_in_file = -1;
int Newline = 0;
char prev_target[512];
char user_input_buffer[1024];
char *owner_address = NULL; /* Holds the responsible owner's address */
char *ownerS_address = NULL; /* Holds owner's address during source fetch */
BOOLEAN first_file = TRUE;
BOOLEAN popped_doc = FALSE;
BOOLEAN refresh_screen = FALSE;
BOOLEAN force_load = FALSE;
BOOLEAN try_internal = FALSE;
BOOLEAN crawl_ok = FALSE;
BOOLEAN rlink_exists;
BOOLEAN rlink_allowed;
BOOLEAN vi_keys_flag = vi_keys;
BOOLEAN emacs_keys_flag = emacs_keys;
BOOLEAN keypad_mode_flag = keypad_mode;
BOOLEAN user_mode_flag = user_mode;
BOOLEAN HTfileSortMethod_flag = HTfileSortMethod;
int CurrentCharSet_flag = current_char_set;
BOOLEAN show_dotfiles_flag = show_dotfiles;
BOOLEAN LYRawMode_flag = LYRawMode;
BOOLEAN LYSelectPopups_flag = LYSelectPopups;
BOOLEAN trace_mode_flag = FALSE;
BOOLEAN forced_HTML_mode = LYforce_HTML_mode;
char cfile[128];
FILE *cfp;
char *cp, *toolbar;
#ifdef VMS
extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig */
#endif /* VMS */
int ch, recall;
int URLTotal;
int URLNum;
BOOLEAN FirstURLRecall = TRUE;
char *temp = NULL;
BOOLEAN ForcePush = FALSE;
unsigned int len;
int i;
#ifdef DIRED_SUPPORT
char *tp = NULL;
struct stat dir_info;
extern char LYPermitFileURL[];
extern char LYDiredFileURL[];
extern char LYUploadFileURL[];
#endif /* DIRED_SUPPORT */
/*
* curdoc.address contains the name of the file that is currently open.
* newdoc.address contains the name of the file that will soon be
* opened if it exits.
* prev_target contains the last search string the user searched for.
* newdoc.title contains the link name that the user last chose to get
* into the current link (file).
*/
/* initalize some variables*/
newdoc.address = NULL;
newdoc.title = NULL;
newdoc.post_data = NULL;
newdoc.post_content_type = NULL;
newdoc.bookmark = NULL;
curdoc.address = NULL;
curdoc.title = NULL;
curdoc.post_data = NULL;
curdoc.post_content_type = NULL;
curdoc.bookmark = NULL;
#ifdef USE_HASH
curdoc.style = NULL;
newdoc.style = NULL;
#endif
nhist = 0;
user_input_buffer[(sizeof(user_input_buffer) - 1)] = '\0';
*prev_target = '\0';
*user_input_buffer = '\0';
StrAllocCopy(CurrentUserAgent, (LYUserAgent ?
LYUserAgent : ""));
StrAllocCopy(CurrentNegoLanguage, (language ?
language : ""));
StrAllocCopy(CurrentNegoCharset, (pref_charset ?
pref_charset : ""));
atexit(free_mainloop_variables);
initialize:
StrAllocCopy(newdoc.address, startfile);
StrAllocCopy(startrealm, startfile);
StrAllocCopy(newdoc.title, "Entry into main screen");
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
newdoc.line = 1;
newdoc.link = 0;
#ifdef USE_SLANG
if (TRACE && LYCursesON) {
addstr("\n");
refresh();
}
#endif /* USE_SLANG */
if (TRACE)
fprintf(stderr,"Entering mainloop, startfile=%s\n",startfile);
if (form_post_data) {
StrAllocCopy(newdoc.post_data, form_post_data);
StrAllocCopy(newdoc.post_content_type,
"application/x-www-form-urlencoded");
} else if (form_get_data) {
StrAllocCat(newdoc.address, form_get_data);
}
if (bookmark_start) {
if (LYValidate) {
_statusline(BOOKMARKS_DISABLED);
sleep(AlertSecs);
bookmark_start = FALSE;
goto initialize;
} else if (traversal) {
_statusline(BOOKMARKS_NOT_TRAVERSED);
sleep(AlertSecs);
traversal = FALSE;
crawl = FALSE;
bookmark_start = FALSE;
goto initialize;
} else {
/*
* See if a bookmark page exists. If it does,
* replace newdoc.address with it's name
*/
if ((cp = get_bookmark_filename(&newdoc.address)) != NULL &&
*cp != '\0' && strcmp(cp, " ")) {
StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
StrAllocCopy(newdoc.bookmark, BookmarkPage);
StrAllocCopy(startrealm, newdoc.address);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
if (TRACE)
fprintf(stderr, "Using bookmarks=%s\n", newdoc.address);
} else {
_statusline(BOOKMARKS_NOT_OPEN);
sleep(MessageSecs);
bookmark_start = FALSE;
goto initialize;
}
}
}
FREE(form_post_data);
FREE(form_get_data);
if (user_mode == NOVICE_MODE)
display_lines = LYlines-4;
else
display_lines = LYlines-2;
while (TRUE) {
#ifdef USE_HASH
if (curdoc.style != NULL) force_load = TRUE;
#endif
/*
* If newdoc.address is different then curdoc.address then
* we need to go out and find and load newdoc.address.
*/
if (LYforce_no_cache || force_load ||
are_different(&curdoc, &newdoc)) {
force_load = FALSE; /* done */
if (TRACE && LYCursesON) {
move(LYlines-1, LYcols-1); /* make sure cursor is down */
#ifdef USE_SLANG
addstr("\n");
#endif /* USE_SLANG */
refresh();
}
try_again:
/*
* Push the old file onto the history stack if we
* have a current doc and a new address. - FM
*/
if (curdoc.address && newdoc.address) {
/*
* Don't actually push if this is a LYNXDOWNLOAD
* URL, because that returns NORMAL even if it
* fails due to a spoof attempt or file access
* problem, and we set the newdoc structure
* elements to the curdoc structure elements
* under case NORMAL. - FM
*/
if (strncmp(newdoc.address, "LYNXDOWNLOAD:", 13)) {
LYpush(&curdoc, ForcePush);
}
} else if (!newdoc.address) {
/*
* If newdoc.address is empty then pop a file
* and load it. Force a no_cache override unless
* it's a bookmark file, or it has POST content
* and LYresubmit_posts is set without safe also
* set.
*/
LYpop(&newdoc);
popped_doc = TRUE;
#ifndef DONT_TRACK_INTERNAL_LINKS
#define NONINTERNAL_OR_DIFFERENT(c,n) TRUE
#define NONINTERNAL_OR_PHYS_DIFFERENT(p,n) (!curdoc.internal_link || \
are_phys_different(p,n))
#else /* TRACK_INTERNAL_LINKS */
#define NONINTERNAL_OR_DIFFERENT(c,n) are_different(c,n)
#define NONINTERNAL_OR_PHYS_DIFFERENT(p,n) are_different(p,n)
#endif /* TRACK_INTERNAL_LINKS */
#ifndef DONT_TRACK_INTERNAL_LINKS
/*
** If curdoc had been reached via an internal
** (fragment) link from what we now have just
** popped into newdoc, then override non-caching in
** all cases. - kw
*/
if (curdoc.internal_link &&
!are_phys_different(&curdoc, &newdoc)) {
LYoverride_no_cache = TRUE;
LYforce_no_cache = FALSE;
try_internal = TRUE;
} else
#endif /* TRACK_INTERNAL_LINKS */
if ((newdoc.bookmark != NULL) ||
(newdoc.post_data != NULL && !newdoc.safe &&
LYresubmit_posts &&
NONINTERNAL_OR_DIFFERENT(&curdoc, &newdoc))) {
LYoverride_no_cache = FALSE;
} else {
LYoverride_no_cache = TRUE;
}
}
if (HEAD_request) {
/*
* Make SURE this is an appropriate request. - FM
*/
if (newdoc.address) {
if (!strncmp(newdoc.address, "http", 4)) {
newdoc.isHEAD = TRUE;
} else if (!strncmp(newdoc.address, "LYNXIMGMAP:", 11)) {
if (!strncmp(newdoc.address + 11, "http", 4)) {
StrAllocCopy(temp, newdoc.address + 11);
FREE(newdoc.address);
newdoc.address = temp;
newdoc.isHEAD = TRUE;
temp = NULL;
}
}
}
try_internal = FALSE;
HEAD_request = FALSE;
}
/*
* If we're getting the TRACE log and it's not new,
* check whether its HText structure has been dumped,
* and if so, fflush() and fclose() it to ensure it is
* fully updated, and then fopen() it again. - FM
*/
if (LYUseTraceLog == TRUE &&
trace_mode_flag == FALSE &&
LYTraceLogFP != NULL &&
!strcmp((newdoc.title ? newdoc.title : ""),
LYNX_TRACELOG_TITLE)) {
DocAddress WWWDoc;
HTParentAnchor *tmpanchor;
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;
tmpanchor = HTAnchor_parent(HTAnchor_findAddress(&WWWDoc));
if ((HText *)HTAnchor_document(tmpanchor) == NULL) {
if (TRACE)
fprintf(stderr,
"\nTurning off TRACE for fetch of log.\n");
fflush(stderr);
fclose(LYTraceLogFP);
*stderr = LYOrigStderr;
if ((LYTraceLogFP = LYAppendToTxtFile(LYTraceLogPath)) == NULL) {
WWW_TraceFlag = FALSE;
_statusline(TRACELOG_OPEN_FAILED);
sleep(MessageSecs);
old_c = 0;
cmd = LYK_PREV_DOC;
goto new_cmd;
}
*stderr = *LYTraceLogFP;
if (TRACE) {
WWW_TraceFlag = FALSE;
trace_mode_flag = TRUE;
}
}
}
LYRequestTitle = newdoc.title;
if (newdoc.bookmark)
LYforce_HTML_mode = TRUE;
if (LYValidate &&
startfile_ok &&
newdoc.address && startfile && homepage &&
(!strcmp(newdoc.address, startfile) ||
!strcmp(newdoc.address, homepage))) {
LYPermitURL = TRUE;
}
#ifndef DONT_TRACK_INTERNAL_LINKS
if (try_internal) {
if (newdoc.address &&
0==strncmp(newdoc.address, "LYNXIMGMAP:", 11)) {
try_internal = FALSE;
} else if (curdoc.address &&
0==strncmp(curdoc.address, "LYNXIMGMAP:", 11)) {
try_internal = FALSE;
}
}
if (try_internal) {
char *hashp = strchr(newdoc.address,'#');
if (hashp) {
HTFindPoundSelector(hashp+1);
}
getresult = (HTMainText != NULL) ? NORMAL : NOT_FOUND;
try_internal = FALSE; /* done */
/* fix up newdoc.address which may have been fragment-only */
if (getresult == NORMAL && (!hashp || hashp == newdoc.address)) {
if (!hashp) {
StrAllocCopy(newdoc.address, HTLoadedDocumentURL());
} else {
StrAllocCopy(temp, HTLoadedDocumentURL());
StrAllocCat(temp, hashp); /* append fragment */
StrAllocCopy(newdoc.address, temp);
FREE(temp);
}
}
} else {
if (newdoc.internal_link && newdoc.address &&
*newdoc.address == '#' && nhist > 0) {
char *cp0;
if (0==strncmp(history[nhist-1].address, "LYNXIMGMAP:", 11))
cp0 = history[nhist-1].address + 11;
else
cp0 = history[nhist-1].address;
StrAllocCopy(temp, cp0);
cp0 = strchr(temp, '#');
if (cp0)
*cp0 = '\0';
StrAllocCat(temp, newdoc.address);
FREE(newdoc.address);
newdoc.address = temp;
temp = NULL;
}
getresult = getfile(&newdoc);
}
#else /* TRACK_INTERNAL_LINKS */
getresult = getfile(&newdoc);
#endif /* TRACK_INTERNAL_LINKS */
switch(getresult) {
case NOT_FOUND:
/*
* OK! can't find the file, so it must not be around now.
* Do any error logging, if appropriate.
*/
LYoverride_no_cache = FALSE; /* Was TRUE if popped. - FM */
popped_doc = FALSE; /* Was TRUE if popped. - FM */
if (trace_mode_flag == TRUE) {
WWW_TraceFlag = TRUE;
trace_mode_flag = FALSE;
fprintf(stderr, "Turning TRACE back on.\n\n");
}
if (error_logging &&
first_file && owner_address && !LYCancelledFetch) {
/*
* Email a bad link message to the owner of
* the document (but NOT to lynx-dev). - FM
*/
if (strncasecomp(owner_address, "mailto:", 7)) {
if (strncasecomp((owner_address + 7),
"lynx-dev@", 9)) {
mailmsg(curdoc.link,
(owner_address+7),
history[nhist-1].address,
history[nhist-1].title);
}
}
}
if (traversal && !first_file && !LYCancelledFetch) {
FILE *ofp;
if ((ofp = LYAppendToTxtFile(TRAVERSE_ERRORS)) == NULL) {
if ((ofp = LYNewTxtFile(TRAVERSE_ERRORS)) == NULL) {
perror(NOOPEN_TRAV_ERR_FILE);
#ifndef NOSIGHUP
(void) signal(SIGHUP, SIG_DFL);
#endif /* NOSIGHUP */
(void) signal(SIGTERM, SIG_DFL);
#ifndef VMS
(void) signal(SIGINT, SIG_DFL);
#endif /* !VMS */
#ifdef SIGTSTP
if (no_suspend)
(void) signal(SIGTSTP,SIG_DFL);
#endif /* SIGTSTP */
exit(-1);
}
}
fprintf(ofp, "%s %s\tin %s\n",
links[curdoc.link].lname,
links[curdoc.link].target,
history[nhist-1].address);
fclose(ofp);
}
/*
* Fall through to do the NULL stuff and reload the
* old file, unless the first file wasn't found or
* has gone missing.
*/
if (!nhist) {
/*
* If nhist = 0 then it must be the first file.
*/
if (!dump_output_immediately)
cleanup();
#ifdef UNIX
if (dump_output_immediately)
fprintf(stderr,"\nlynx: Can't access startfile %s\n",
startfile);
else
#endif /* UNIX */
printf("\nlynx: Can't access startfile %s\n",
startfile);
if (!dump_output_immediately) {
#ifndef NOSIGHUP
(void) signal(SIGHUP, SIG_DFL);
#endif /* NOSIGHUP */
(void) signal(SIGTERM, SIG_DFL);
#ifndef VMS
(void) signal(SIGINT, SIG_DFL);
#endif /* !VMS */
#ifdef SIGTSTP
if (no_suspend)
(void) signal(SIGTSTP,SIG_DFL);
#endif /* SIGTSTP */
exit(-1);
}
return(-1);
}
case NULLFILE:
/*
* Not supposed to return any file.
*/
LYoverride_no_cache = FALSE; /* Was TRUE if popped. - FM */
popped_doc = FALSE; /* Was TRUE if popped. - FM */
if (trace_mode_flag == TRUE) {
WWW_TraceFlag = TRUE;
trace_mode_flag = FALSE;
fprintf(stderr, "Turning TRACE back on.\n\n");
}
FREE(newdoc.address); /* to pop last doc */
FREE(newdoc.bookmark);
LYJumpFileURL = FALSE;
reloading = FALSE;
LYPermitURL = FALSE;
LYCancelledFetch = FALSE;
ForcePush = FALSE;
LYforce_HTML_mode = FALSE;
if (traversal) {
crawl_ok = FALSE;
if (traversal_link_to_add) {
/*
* It's a binary file, or the fetch attempt
* failed. Add it to TRAVERSE_REJECT_FILE
* so we don't try again in this run.
*/
if (!lookup_reject(traversal_link_to_add)) {
add_to_reject_list(traversal_link_to_add);
}
FREE(traversal_link_to_add);
}
}
/*
* Make sure the first file was found and
* has not gone missing.
*/
if (!nhist) {
/*
* If nhist = 0 then it must be the first file.
*/
if (first_file && homepage &&
#ifdef VMS
strcasecomp(homepage, startfile) != 0)
#else
strcmp(homepage, startfile) != 0)
#endif /* VMS */
{
/*
* Couldn't return to the first file but there is a
* homepage we can use instead. Useful for when the
* first URL causes a program to be invoked. - GL
*
* But first make sure homepage is different from
* startfile (above), then make it the same (below)
* so we don't enter an infinite getfile() loop on
* on failures to find the files. - FM
*/
StrAllocCopy(newdoc.address, homepage);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
StrAllocCopy(startfile, homepage);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
} else {
if (!dump_output_immediately)
cleanup();
#ifdef UNIX
if (dump_output_immediately) {
fprintf(stderr,
"\nlynx: Start file could not be found or is not text/html or text/plain\n");
fprintf(stderr," Exiting...\n");
} else
#endif /* UNIX */
{
printf(
"\nlynx: Start file could not be found or is not text/html or text/plain\n");
printf(" Exiting...\n");
}
if (!dump_output_immediately) {
#ifndef NOSIGHUP
(void) signal(SIGHUP, SIG_DFL);
#endif /* NOSIGHUP */
(void) signal(SIGTERM, SIG_DFL);
#ifndef VMS
(void) signal(SIGINT, SIG_DFL);
#endif /* !VMS */
#ifdef SIGTSTP
if (no_suspend)
(void) signal(SIGTSTP,SIG_DFL);
#endif /* SIGTSTP */
exit(-1);
}
return(-1);
}
}
goto try_again;
break;
case NORMAL:
/*
* Marvelously, we got the document!
*/
LYoverride_no_cache = FALSE; /* Was TRUE if popped. - FM */
if (trace_mode_flag == TRUE) {
WWW_TraceFlag = TRUE;
trace_mode_flag = FALSE;
fprintf(stderr, "Turning TRACE back on.\n\n");
}
*prev_target = '\0'; /* Reset for this document. - FM */
/*
* If it's the first file and we're interactive,
* check whether it's a bookmark file which was
* not accessed via the -book switch. - FM
*/
if (((first_file == TRUE) &&
(dump_output_immediately == FALSE) &&
!(newdoc.bookmark && *newdoc.bookmark)) &&
((LYisLocalFile(newdoc.address) == TRUE) &&
!(strcmp((HText_getTitle() ? HText_getTitle() : ""),
BOOKMARK_TITLE))) &&
(temp = HTParse(newdoc.address, "",
PARSE_PATH+PARSE_PUNCTUATION)) != NULL) {
#ifdef DOSPATH
cp = HTDOS_wwwName((char *)Home_Dir());
#else
#ifdef VMS
cp = HTVMS_wwwName((char *)Home_Dir());
#else
cp = (char *)Home_Dir();
#endif /* VMS */
#endif /* DOSPATH */
len = strlen(cp);
#ifdef VMS
if (!strncasecomp(temp, cp, len) &&
#else
if (!strncmp(temp, cp, len) &&
#endif /* VMS */
strlen(temp) > len) {
/*
* We're interactive and this might be a
* bookmark file entered as a startfile
* rather than invoked via -book. Check
* if it's in our bookmark file list, and
* if so, reload if with the relevant
* bookmark elements set. - FM
*/
if ((cp = (char *)calloc(1,
(strlen((char *)&temp[len]) + 2))) == NULL)
outofmem(__FILE__, "mainloop");
if (temp[len] == '/') {
if (strchr((char *)&temp[(len + 1)], '/')) {
sprintf(cp, ".%s", (char *)&temp[len]);
} else {
strcpy(cp, (char *)&temp[(len + 1)]);
}
} else {
strcpy(cp, (char *)&temp[len]);
}
for (i = 0; i <= MBM_V_MAXFILES; i++) {
if (MBM_A_subbookmark[i] &&
#ifdef VMS
!strcasecomp(cp, MBM_A_subbookmark[i]))
#else
!strcmp(cp, MBM_A_subbookmark[i]))
#endif /* VMS */
{
StrAllocCopy(BookmarkPage,
MBM_A_subbookmark[i]);
break;
}
}
FREE(cp);
if (i <= MBM_V_MAXFILES) {
FREE(temp);
if (LYValidate) {
_statusline(BOOKMARKS_DISABLED);
sleep(AlertSecs);
return(-1);
}
if ((temp = HTParse(newdoc.address, "",
PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION))) {
StrAllocCopy(newdoc.address, temp);
HTuncache_current_document();
FREE(curdoc.address);
#ifdef DOSPATH
StrAllocCat(newdoc.address,
HTDOS_wwwName((char *)Home_Dir()));
#else
#ifdef VMS
StrAllocCat(newdoc.address,
HTVMS_wwwName((char *)Home_Dir()));
#else
StrAllocCat(newdoc.address, Home_Dir());
#endif /* VMS */
#endif /* DOSPATH */
StrAllocCat(newdoc.address, "/");
StrAllocCat(newdoc.address,
(strncmp(BookmarkPage, "./", 2) ?
BookmarkPage :
(BookmarkPage + 2)));
StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
StrAllocCopy(newdoc.bookmark, BookmarkPage);
#ifdef USE_HASH
if (curdoc.style)
StrAllocCopy(newdoc.style, curdoc.style);
#endif
StrAllocCopy(startrealm, newdoc.address);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
FREE(temp);
if (!strcmp(homepage, startfile))
StrAllocCopy(homepage, newdoc.address);
StrAllocCopy(startfile, newdoc.address);
if (TRACE)
fprintf(stderr,
"Reloading as bookmarks=%s\n",
newdoc.address);
goto try_again;
}
}
}
cp = NULL;
}
FREE(temp);
if (traversal) {
/*
* During traversal build up lists of all links
* traversed. Traversal mode is a special
* feature for traversing http links in the web.
*/
if (traversal_link_to_add) {
/*
* Add the address we sought to TRAVERSE_FILE.
*/
if (!lookup(traversal_link_to_add))
add_to_table(traversal_link_to_add);
FREE(traversal_link_to_add);
}
if (curdoc.address && curdoc.title &&
strncmp(curdoc.address, "LYNXIMGMAP:", 11))
/*
* Add the address we got to TRAVERSE_FOUND_FILE.
*/
add_to_traverse_list(curdoc.address, curdoc.title);
}
/*
* If this was a LYNXDOWNLOAD, we still have curdoc,
* not a newdoc, so reset the address, title and
* positioning elements. - FM
*/
if (newdoc.address && curdoc.address &&
!strncmp(newdoc.address, "LYNXDOWNLOAD:", 13)) {
StrAllocCopy(newdoc.address, curdoc.address);
StrAllocCopy(newdoc.title, (curdoc.title ?
curdoc.title : ""));
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
newdoc.line = curdoc.line;
newdoc.link = curdoc.link;
newdoc.internal_link = FALSE; /* can't be true. - kw */
}
/*
* Set Newline to the saved line. It contains the
* line the user was on if s/he has been in the file
* before, or it is 1 if this is a new file.
*/
Newline = newdoc.line;
/*
* If we are going to a target line or
* the first page of a popped document,
* override any www_search line result.
*/
if (Newline > 1 || popped_doc == TRUE)
www_search_result = -1;
/*
* Make sure curdoc.line will not be equal
* to Newline, so we get a redraw.
*/
curdoc.line = -1;
break;
} /* end switch */
if (TRACE) {
if (!LYTraceLogFP || trace_mode_flag)
sleep(AlertSecs); /* allow me to look at the results */
}
/*
* Set the files the same.
*/
StrAllocCopy(curdoc.address, newdoc.address);
StrAllocCopy(curdoc.post_data, newdoc.post_data);
StrAllocCopy(curdoc.post_content_type, newdoc.post_content_type);
StrAllocCopy(curdoc.bookmark, newdoc.bookmark);
#ifdef USE_HASH
StrAllocCopy(curdoc.style, HText_getStyle());
if (curdoc.style != NULL)
style_readFromFile (curdoc.style);
#endif
curdoc.isHEAD = newdoc.isHEAD;
curdoc.internal_link = newdoc.internal_link;
/*
* Set the remaining document elements and add to
* the visitied links list. - FM
*/
if (ownerS_address != NULL) {
if (HTOutputFormat == WWW_SOURCE && !HText_getOwner())
HText_setMainTextOwner(ownerS_address);
FREE(ownerS_address);
}
if (HText_getTitle()) {
StrAllocCopy(curdoc.title, HText_getTitle());
} else if (!dump_output_immediately) {
StrAllocCopy(curdoc.title, newdoc.title);
}
owner_address = HText_getOwner();
curdoc.safe = HTLoadedDocumentIsSafe();
if (!dump_output_immediately) {
LYAddVisitedLink(&curdoc);
}
/*
* Reset WWW present mode so that if we were getting
* the source, we get rendered HTML from now on.
*/
HTOutputFormat = WWW_PRESENT;
/*
* Reset all of the other relevant flags. - FM
*/
LYUserSpecifiedURL = FALSE; /* only set for goto's and jumps's */
LYJumpFileURL = FALSE; /* only set for jump's */
LYNoRefererForThis = FALSE; /* always reset on return here */
reloading = FALSE; /* only set for RELOAD and RESUBMIT */
HEAD_request = FALSE; /* only set for HEAD requests */
LYPermitURL = FALSE; /* only set for LYValidate */
ForcePush = FALSE; /* only set for some PRINT requests. */
LYforce_HTML_mode = FALSE;
popped_doc = FALSE;
} /* end if (STREQ(newdoc.address, curdoc.address) */
if (dump_output_immediately) {
if (crawl) {
print_crawl_to_fd(stdout, curdoc.address, curdoc.title);
} else {
print_wwwfile_to_fd(stdout,0);
}
return(0);
}
/*
* If the recent_sizechange variable is set to TRUE
* then the window size changed recently.
*/
if (recent_sizechange) {
stop_curses();
start_curses();
clear();
refresh_screen = TRUE; /* to force a redraw */
recent_sizechange = FALSE;
if (user_mode == NOVICE_MODE) {
display_lines = LYlines-4;
} else {
display_lines = LYlines-2;
}
}
if (www_search_result != -1) {
/*
* This was a WWW search, set the line
* to the result of the search.
*/
Newline = www_search_result;
www_search_result = -1; /* reset */
more = HText_canScrollDown();
}
if (first_file == TRUE) {
/*
* We can never again have the first file.
*/
first_file = FALSE;
/*
* Set the startrealm, and deal as best we can
* with preserving forced HTML mode for a local
* startfile. - FM
*/
temp = HTParse(curdoc.address, "",
PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
if (!temp || *temp == '\0') {
StrAllocCopy(startrealm, "None");
} else {
StrAllocCopy(startrealm, temp);
FREE(temp);
if (!(temp = HTParse(curdoc.address, "",
PARSE_PATH+PARSE_PUNCTUATION))) {
if (startrealm[strlen(startrealm)-1] != '/') {
StrAllocCat(startrealm, "/");
}
} else {
if (forced_HTML_mode &&
!dump_output_immediately &&
!curdoc.bookmark &&
!strncasecomp(curdoc.address, "file:", 5) &&
strlen(temp) > 1) {
/*
* We forced HTML for a local startfile which
* is not a bookmark file and has a path of at
* least two letters. If it doesn't have a
* suffix mapped to text/html, we'll set the
* entire path (including the lead slash) as a
* "suffix" mapped to text/html to ensure it is
* always treated as an HTML source file. We
* are counting on a tail match to this full path
* for some other URL fetched during the session
* having too low a probability to worry about,
* but it could happen. - FM
*/
HTAtom *encoding;
if (HTFileFormat(temp, &encoding, NULL) != WWW_HTML) {
HTSetSuffix(temp, "text/html", "8bit", 1.0);
}
}
if ((cp = strrchr(temp, '/')) != NULL) {
*(cp+1) = '\0';
StrAllocCat(startrealm, temp);
}
}
}
FREE(temp);
if (TRACE) {
fprintf(stderr, "Starting realm is '%s'\n\n", startrealm);
}
if (traversal) {
/*
* Set up the crawl output stuff.
*/
if (curdoc.address && !lookup(curdoc.address)) {
if (strncmp(curdoc.address, "LYNXIMGMAP:", 11))
crawl_ok = TRUE;
add_to_table(curdoc.address);
}
/*
* Set up the traversal_host comparison string.
*/
if (strncmp((curdoc.address ? curdoc.address : "NULL"),
"http", 4)) {
StrAllocCopy(traversal_host, "None");
} else if (check_realm) {
StrAllocCopy(traversal_host, startrealm);
} else {
temp = HTParse(curdoc.address, "",
PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
if (!temp || *temp == '\0') {
StrAllocCopy(traversal_host, "None");
} else {
StrAllocCopy(traversal_host, temp);
if (traversal_host[strlen(traversal_host)-1] != '/') {
StrAllocCat(traversal_host, "/");
}
}
FREE(temp);
}
if (TRACE) {
fprintf(stderr,
"Traversal host is '%s'\n\n", traversal_host);
}
}
if (startfile) {
/*
* If homepage was not equated to startfile,
* make the homepage URL the first goto
* entry. - FM
*/
if (homepage && strcmp(startfile, homepage))
HTAddGotoURL(homepage);
/*
* If we are not starting up with startfile
* (e.g., had -book), or if we are using the
* startfile and it has no POST content, make
* the startfile URL a goto entry. - FM
*/
if (strcmp(startfile, newdoc.address) ||
newdoc.post_data == NULL)
HTAddGotoURL(startfile);
}
if (TRACE) {
refresh_screen = TRUE;
if (!LYTraceLogFP || trace_mode_flag)
sleep(AlertSecs);
}
}
/*
* If the curdoc.line is different than Newline then there must
* have been a change since last update. Run HText_pageDisplay()
* create a fresh screen of text out.
*/
if (curdoc.line != Newline) {
refresh_screen = FALSE;
HText_pageDisplay(Newline, prev_target);
#ifdef DIRED_SUPPORT
if (lynx_edit_mode && nlinks > 0 && !HTList_isEmpty(tagged))
showtags(tagged);
#endif /* DIRED_SUPPORT */
/*
* If more equals TRUE, then there is more
* info below this page .
*/
more = HText_canScrollDown();
curdoc.line = Newline = HText_getTopOfScreen()+1;
lines_in_file = HText_getNumOfLines();
if (curdoc.title == NULL) {
/*
* If we don't yet have a title, try to get it,
* or set to that for newdoc.title. - FM
*/
if (HText_getTitle()) {
StrAllocCopy(curdoc.title, HText_getTitle());
} else {
StrAllocCopy(curdoc.title, newdoc.title);
}
}
if (arrowup) {
/*
* arrowup is set if we just came up from
* a page below.
*/
curdoc.link = nlinks - 1;
arrowup = FALSE;
} else {
curdoc.link = newdoc.link;
if (curdoc.link >= nlinks) {
curdoc.link = nlinks - 1;
} else if (curdoc.link < 0 && nlinks > 0) {
/*
* We may have popped a doc (possibly in local_dired)
* which didn't have any links when it was pushed, but
* does have links now (e.g. a file was created) - KW
*/
curdoc.link = 0;
}
}
show_help = FALSE; /* reset */
newdoc.line = 1;
newdoc.link = 0;
curdoc.line = Newline; /* set */
}
/*
* Refresh the screen if neccessary.
*/
if (refresh_screen) {
clear();
HText_pageDisplay(Newline, prev_target);
#ifdef DIRED_SUPPORT
if (lynx_edit_mode && nlinks > 0 && !HTList_isEmpty(tagged))
showtags(tagged);
#endif /* DIRED_SUPPORT */
if (user_mode == NOVICE_MODE)
noviceline(more); /* print help message */
refresh_screen = FALSE;
}
/*
* Report unread or new mail, if appropriate.
*/
if (check_mail && !no_mail && LYCheckMail())
sleep(MessageSecs);
/*
* If help is not on the screen,
* then put a message on the screen
* to tell the user other misc info.
*/
if (!show_help) {
/*
* Make sure form novice lines are replaced.
*/
if (user_mode == NOVICE_MODE) {
noviceline(more);
}
/*
* If we are in forms mode then explicitly
* tell the user what each kind of link is.
*/
if (HTisDocumentSource()) {
/*
* Currently displaying HTML source.
*/
_statusline(SOURCE_HELP);
#ifdef INDICATE_FORMS_MODE_FOR_ALL_LINKS_ON_PAGE
} else if (lynx_mode == FORMS_LYNX_MODE && nlinks > 0) {
#else
#ifdef NORMAL_NON_FORM_LINK_STATUSLINES_FOR_ALL_USER_MODES
} else if (lynx_mode == FORMS_LYNX_MODE && nlinks > 0 &&
!(links[curdoc.link].type & WWW_LINK_TYPE)) {
#else
} else if (lynx_mode == FORMS_LYNX_MODE && nlinks > 0 &&
!(user_mode == ADVANCED_MODE &&
(links[curdoc.link].type & WWW_LINK_TYPE))) {
#endif /* NORMAL_NON_FORM_LINK_STATUSLINES_FOR_ALL_USER_MODES */
#endif /* INDICATE_FORMS_MODE_FOR_ALL_LINKS_ON_PAGE */
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE)
switch(links[curdoc.link].form->type) {
case F_PASSWORD_TYPE:
if (links[curdoc.link].form->disabled == YES)
statusline(FORM_LINK_PASSWORD_UNM_MSG);
else
statusline(FORM_LINK_PASSWORD_MESSAGE);
break;
case F_OPTION_LIST_TYPE:
if (links[curdoc.link].form->disabled == YES)
statusline(FORM_LINK_OPTION_LIST_UNM_MSG);
else
statusline(FORM_LINK_OPTION_LIST_MESSAGE);
break;
case F_CHECKBOX_TYPE:
if (links[curdoc.link].form->disabled == YES)
statusline(FORM_LINK_CHECKBOX_UNM_MSG);
else
statusline(FORM_LINK_CHECKBOX_MESSAGE);
break;
case F_RADIO_TYPE:
if (links[curdoc.link].form->disabled == YES)
statusline(FORM_LINK_RADIO_UNM_MSG);
else
statusline(FORM_LINK_RADIO_MESSAGE);
break;
case F_TEXT_SUBMIT_TYPE:
if (links[curdoc.link].form->disabled == YES) {
statusline(FORM_LINK_TEXT_SUBMIT_UNM_MSG);
} else if (links[curdoc.link].form->submit_method ==
URL_MAIL_METHOD) {
if (no_mail)
statusline(
FORM_LINK_TEXT_SUBMIT_MAILTO_DIS_MSG);
else
statusline(FORM_LINK_TEXT_SUBMIT_MAILTO_MSG);
} else if (links[curdoc.link].form->no_cache) {
statusline(FORM_LINK_TEXT_RESUBMIT_MESSAGE);
} else {
statusline(FORM_LINK_TEXT_SUBMIT_MESSAGE);
}
break;
case F_SUBMIT_TYPE:
case F_IMAGE_SUBMIT_TYPE:
if (links[curdoc.link].form->disabled == YES) {
statusline(FORM_LINK_SUBMIT_DIS_MSG);
} else if (links[curdoc.link].form->submit_method ==
URL_MAIL_METHOD) {
if (no_mail) {
statusline(FORM_LINK_SUBMIT_MAILTO_DIS_MSG);
} else {
statusline(FORM_LINK_SUBMIT_MAILTO_MSG);
}
} else if (links[curdoc.link].form->no_cache) {
statusline(FORM_LINK_RESUBMIT_MESSAGE);
} else {
statusline(FORM_LINK_SUBMIT_MESSAGE);
}
break;
case F_RESET_TYPE:
if (links[curdoc.link].form->disabled == YES)
statusline(FORM_LINK_RESET_DIS_MSG);
else
statusline(FORM_LINK_RESET_MESSAGE);
break;
case F_TEXT_TYPE:
case F_TEXTAREA_TYPE:
if (links[curdoc.link].form->disabled == YES)
statusline(FORM_LINK_TEXT_UNM_MSG);
else
statusline(FORM_LINK_TEXT_MESSAGE);
break;
}
else
statusline(NORMAL_LINK_MESSAGE);
/*
* Let them know if it's an index -- very rare.
*/
if (is_www_index) {
move(LYlines-1,LYcols-8);
start_reverse();
addstr("-index-");
stop_reverse();
}
} else if (user_mode == ADVANCED_MODE && nlinks > 0) {
/*
* Show the URL or, for some internal links, the fragment
*/
cp = NULL;
if (links[curdoc.link].type == WWW_INTERN_LINK_TYPE &&
strncmp(links[curdoc.link].lname, "LYNXIMGMAP:", 11)) {
cp = strchr(links[curdoc.link].lname, '#');
}
if (!cp)
cp = links[curdoc.link].lname;
if (more)
if (is_www_index)
_user_message("-more- -index- %s",
cp);
else
_user_message("-more- %s",cp);
else
if (is_www_index)
_user_message("-index- %s",cp);
else
statusline(cp);
} else if (is_www_index && more) {
char buf[128];
sprintf(buf, WWW_INDEX_MORE_MESSAGE, key_for_func(LYK_INDEX_SEARCH));
_statusline(buf);
} else if (is_www_index) {
char buf[128];
sprintf(buf, WWW_INDEX_MESSAGE, key_for_func(LYK_INDEX_SEARCH));
_statusline(buf);
} else if (more) {
if (user_mode == NOVICE_MODE)
_statusline(MORE);
else
_statusline(MOREHELP);
} else {
_statusline(HELP);
}
} else {
show_help = FALSE;
}
if (!(nlinks > 0 &&
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
(links[curdoc.link].form->type == F_TEXT_TYPE ||
links[curdoc.link].form->type == F_TEXTAREA_TYPE)))
/*
* Highlight current link.
*/
highlight(ON, curdoc.link, prev_target);
if (traversal) {
/*
* Don't go interactively into forms,
* or accept keystrokes from the user
*/
if (crawl && crawl_ok) {
crawl_ok = FALSE;
sprintf(cfile,"lnk%08d.dat",ccount);
ccount = ccount + 1;
if ((cfp = LYNewTxtFile(cfile)) != NULL) {
print_crawl_to_fd(cfp,curdoc.address,curdoc.title);
fclose(cfp);
} else {
if (!dump_output_immediately)
cleanup();
#ifdef UNIX
if (dump_output_immediately)
fprintf(stderr,
"Fatal error - could not open output file %s\n",cfile);
else
#endif
printf(
"Fatal error - could not open output file %s\n",cfile);
if (!dump_output_immediately) {
#ifndef NOSIGHUP
(void) signal(SIGHUP, SIG_DFL);
#endif /* NOSIGHUP */
(void) signal(SIGTERM, SIG_DFL);
#ifndef VMS
(void) signal(SIGINT, SIG_DFL);
#endif /* !VMS */
#ifdef SIGTSTP
if (no_suspend)
(void) signal(SIGTSTP,SIG_DFL);
#endif /* SIGTSTP */
exit(-1);
}
return(-1);
}
}
} else {
/*
* Normal, non-traversal handling.
*/
if (nlinks > 0 &&
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
(links[curdoc.link].form->type == F_TEXT_TYPE ||
links[curdoc.link].form->type == F_TEXT_SUBMIT_TYPE ||
links[curdoc.link].form->type == F_PASSWORD_TYPE ||
links[curdoc.link].form->type == F_TEXTAREA_TYPE)) {
/*
* Replace novice lines if in NOVICE_MODE.
*/
if (user_mode==NOVICE_MODE) {
move(LYlines-2,0); clrtoeol();
addstr(FORM_NOVICELINE_ONE);
move(LYlines-1,0); clrtoeol();
addstr(FORM_NOVICELINE_TWO);
}
c = change_form_link(&links[curdoc.link],
FORM_UP, &newdoc, &refresh_screen,
links[curdoc.link].form->name,
links[curdoc.link].form->value);
if (c == '\n' || c == '\r')
#ifdef FASTTAB
/*
* Make return act like down-arrow.
*/
c = DNARROW;
#else
/*
* Make return act like tab.
*/
c = '\t';
#endif /* FASTTAB */
} else {
/*
* Get a keystroke from the user.
* Save the last keystroke to avoid
* redundant error reporting.
*/
real_c = c = LYgetch(); /* get user input */
#ifndef VMS
if (c == 3) { /* ^C */
/*
* This shouldn't happen. We'll try to
* deal with whatever bug caused it. - FM
*/
signal(SIGINT, cleanup_sig);
old_c = 0;
cmd = LYK_QUIT;
goto new_cmd;
}
#endif /* !VMS */
if (old_c != real_c) {
old_c = 0;
}
}
}
#ifdef VMS
if (HadVMSInterrupt) {
HadVMSInterrupt = FALSE;
c = DO_NOTHING;
}
#else
if (recent_sizechange) {
if (c <= 0)
c = DO_NOTHING;
}
#endif /* VMS */
new_keyboard_input:
/*
* A goto point for new input without going
* back through the getch() loop.
*/
if (traversal) {
/*
* This is a special feature to traverse every http link
* derived from startfile and check for errors or create
* crawl ouput files. Only URL's that begin with
* "traversal_host" are searched - this keeps the search
* from crossing to other servers (a feature, not a bug!).
*/
rlink_exists = (nlinks > 0 && links[curdoc.link].lname != NULL);
if (rlink_exists) {
rlink_allowed =
(!lookup_reject(links[curdoc.link].lname) &&
traversal_host && links[curdoc.link].lname &&
!strncmp(traversal_host,
(strncmp(links[curdoc.link].lname,
"LYNXIMGMAP:", 11)
?
links[curdoc.link].lname : (links[curdoc.link].lname + 11)),
strlen(traversal_host)));
} else {
rlink_allowed = FALSE;
}
if (rlink_exists && rlink_allowed) {
if (lookup(links[curdoc.link].lname)) {
if (more_links ||
(curdoc.link > -1 && curdoc.link < nlinks -1))
c= DNARROW;
else {
if (STREQ(curdoc.title,"Entry into main screen") ||
(nhist <= 0 )) {
if (!dump_output_immediately) {
cleanup();
#ifndef NOSIGHUP
(void) signal(SIGHUP, SIG_DFL);
#endif /* NOSIGHUP */
(void) signal(SIGTERM, SIG_DFL);
#ifndef VMS
(void) signal(SIGINT, SIG_DFL);
#endif /* !VMS */
#ifdef SIGTSTP
if (no_suspend)
(void) signal(SIGTSTP,SIG_DFL);
#endif /* SIGTSTP */
exit(-1);
}
return(-1);
}
c = LTARROW;
}
} else {
StrAllocCopy(traversal_link_to_add,
links[curdoc.link].lname);
if (strncmp(traversal_link_to_add, "LYNXIMGMAP:", 11))
crawl_ok = TRUE;
c = RTARROW;
}
} else { /* no good right link, so only down and left arrow ok*/
if (rlink_exists)
add_to_reject_list(links[curdoc.link].lname);
if (more_links ||
(curdoc.link > -1 && curdoc.link < nlinks-1))
c = DNARROW;
else {
/*
* curdoc.title doesn't always work, so
* bail out if the history list is empty.
*/
if (STREQ(curdoc.title,"Entry into main screen") ||
(nhist <= 0 )) {
if (!dump_output_immediately) {
cleanup();
#ifndef NOSIGHUP
(void) signal(SIGHUP, SIG_DFL);
#endif /* NOSIGHUP */
(void) signal(SIGTERM, SIG_DFL);
#ifndef VMS
(void) signal(SIGINT, SIG_DFL);
#endif /* !VMS */
#ifdef SIGTSTP
if (no_suspend)
(void) signal(SIGTSTP,SIG_DFL);
#endif /* SIGTSTP */
exit(-1);
}
return(-1);
}
c = LTARROW;
}
} /* right link not NULL or link to another site*/
} /* traversal */
cmd = keymap[c+1]; /* add 1 to map EOF to 0 */
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
if (lynx_edit_mode && override[c+1] && !no_dired_support)
cmd = override[c+1];
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
real_cmd = cmd;
new_cmd: /*
* A goto point for new input without going
* back through the getch() loop.
*/
switch(cmd) {
case 0: /* unmapped character */
default:
if (more)
_statusline(MOREHELP);
else
_statusline(HELP);
show_help = TRUE;
if (TRACE) {
sprintf(cfile, "%d", c);
addstr(cfile); /* show the user input */
cfile[0] = '\0';
}
break;
case LYK_INTERRUPT:
/*
* No network transmission to interrupt - 'til we multithread.
*/
break;
case LYK_F_LINK_NUM:
c = '\0';
case LYK_1:
case LYK_2:
case LYK_3:
case LYK_4:
case LYK_5:
case LYK_6:
case LYK_7:
case LYK_8:
case LYK_9:
{
/*
* Get a number from the user and follow that link number.
*/
int lindx = ((nlinks > 0) ? curdoc.link : 0);
int number;
switch (follow_link_number(c, lindx, &newdoc, &number)) {
case DO_LINK_STUFF:
/*
* Follow a normal link.
*/
StrAllocCopy(newdoc.address, links[lindx].lname);
StrAllocCopy(newdoc.title, links[lindx].hightext);
/*
* Might be an anchor in the same doc from a POST
* form. If so, don't free the content. -- FM
*/
if (links[lindx].type == WWW_INTERN_LINK_TYPE) {
LYoverride_no_cache = TRUE;
newdoc.internal_link = TRUE;
if (0==strcmp(curdoc.address, LYlist_temp_url()) &&
0==strcmp((curdoc.title ? curdoc.title : ""),
LIST_PAGE_TITLE)) {
FREE(curdoc.address);
} else
try_internal = TRUE;
force_load = TRUE;
break;
}
if (are_different(&curdoc, &newdoc)) {
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
}
newdoc.internal_link = FALSE;
force_load = TRUE; /* force MainLoop to reload */
break;
case DO_GOTOLINK_STUFF:
/*
* Position on a normal link, don't follow it. - KW
*/
Newline = newdoc.line;
newdoc.line = 1;
if (Newline == curdoc.line) {
/*
* It's a link in the current page. - FM
*/
if (nlinks > 0 && curdoc.link > -1) {
if (curdoc.link == newdoc.link) {
/*
* It's the current link, and presumeably
* reflects a typo in the statusline entry,
* so issue a statusline message for the
* typo-prone users (like me 8-). - FM
*/
StrAllocCopy(temp, user_input_buffer);
sprintf(user_input_buffer,
LINK_ALREADY_CURRENT, number);
_statusline(user_input_buffer);
sleep(MessageSecs);
strcpy(user_input_buffer, temp);
FREE(temp);
} else {
/*
* It's a different link on this page,
* so turn the highlighting off, set the
* current link to the new link value from
* follow_link_number(), and re-initialize
* the new link value. - FM
*/
highlight(OFF, curdoc.link, prev_target);
curdoc.link = newdoc.link;
newdoc.link = 0;
}
}
}
break; /* nothing more to do */
case DO_GOTOPAGE_STUFF:
/*
* Position on a page in this document. - FM
*/
Newline = newdoc.line;
newdoc.line = 1;
if (Newline == curdoc.line) {
/*
* It's the current page, so issue a
* statusline message for the typo-prone
* users (like me 8-). - FM
*/
if (Newline <= 1) {
_statusline(ALREADY_AT_BEGIN);
} else if (!more) {
_statusline(ALREADY_AT_END);
} else {
StrAllocCopy(temp, user_input_buffer);
sprintf(user_input_buffer,
ALREADY_AT_PAGE, number);
_statusline(user_input_buffer);
sleep(MessageSecs);
strcpy(user_input_buffer, temp);
FREE(temp);
}
sleep(MessageSecs);
}
break;
case PRINT_ERROR:
old_c = real_c;
_statusline(BAD_LINK_NUM_ENTERED);
sleep(MessageSecs);
break;
}
break;
}
case LYK_SOURCE: /* toggle view source mode */
/*
* Check if this is a reply from a POST, and if so,
* seek confirmation if the safe element is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
if (HTisDocumentSource()) {
HTOutputFormat = WWW_PRESENT;
} else {
if (HText_getOwner())
StrAllocCopy(ownerS_address, HText_getOwner());
LYUCPushAssumed(HTMainAnchor);
HTOutputFormat = WWW_SOURCE;
}
HTuncache_current_document();
FREE(curdoc.address); /* so it doesn't get pushed */
break;
case LYK_RELOAD: /* control-R to reload and refresh */
/*
* Check if this is a reply from a POST, and if so,
* seek confirmation if the safe element is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
/*
* Check to see if should reload source, or load html
*/
if (HTisDocumentSource()) {
HTOutputFormat = WWW_SOURCE;
}
HEAD_request = HTLoadedDocumentIsHEAD();
HTuncache_current_document();
#ifdef NO_ASSUME_SAME_DOC
/*
* Don't assume the reloaded document will be the same. - FM
*/
newdoc.line = 1;
newdoc.link = 0;
#else
/*
* Do assume the reloaded document will be the same. - FM
* (I don't remember all the reasons why we couldn't assume
* this. As the problems show up, we'll try to fix them,
* or add warnings. - FM)
*/
if (lynx_mode == FORMS_LYNX_MODE) {
/*
* Note that if there are no form links on the current
* page, lynx_mode won't have this setting and we won't
* know that this warning should be issued. - FM
*/
_statusline(RELOADING_FORM);
sleep(AlertSecs);
}
newdoc.line = ((curdoc.line > 0) ?
curdoc.line : 1);
newdoc.link = ((curdoc.link > -1) ?
curdoc.link : 0);
#endif /* NO_ASSUME_SAME_DOC */
FREE(curdoc.address); /* so it doesn't get pushed */
#ifdef VMS
lynx_force_repaint();
#endif /* VMS */
/*
* Reload should force a cache refresh on a proxy.
* -- Ari L. <luotonen@dxcern.cern.ch>
*
* -- but only if this was really a reload requested by
* the user, not if we jumped here to handle reloading for
* INLINE_TOGGLE, IMAGE_TOGGLE, RAW_TOGGLE, etc. - KW
*/
if (real_cmd == LYK_RELOAD)
reloading = TRUE;
break;
case LYK_HISTORICAL:
/*
* Check if this is a reply from a POST, and if so,
* seek confirmation of reload if the safe element
* is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(WILL_NOT_RELOAD_DOC);
sleep(InfoSecs);
} else {
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
FREE(curdoc.address);
}
if (historical_comments)
historical_comments = FALSE;
else
historical_comments = TRUE;
if (minimal_comments) {
_statusline(historical_comments ?
HISTORICAL_ON_MINIMAL_OFF : HISTORICAL_OFF_MINIMAL_ON);
} else {
_statusline(historical_comments ?
HISTORICAL_ON_VALID_OFF : HISTORICAL_OFF_VALID_ON);
}
sleep(AlertSecs);
break;
case LYK_MINIMAL:
if (!historical_comments) {
/*
* Check if this is a reply from a POST, and if so,
* seek confirmation of reload if the safe element
* is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(WILL_NOT_RELOAD_DOC);
sleep(InfoSecs);
} else {
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
FREE(curdoc.address);
}
}
if (minimal_comments)
minimal_comments = FALSE;
else
minimal_comments = TRUE;
if (!historical_comments) {
_statusline(minimal_comments ?
MINIMAL_ON_IN_EFFECT : MINIMAL_OFF_VALID_ON);
} else {
_statusline(minimal_comments ?
MINIMAL_ON_BUT_HISTORICAL : MINIMAL_OFF_HISTORICAL_ON);
}
sleep(AlertSecs);
break;
case LYK_SOFT_DQUOTES:
/*
* Check if this is a reply from a POST, and if so,
* seek confirmation of reload if the safe element
* is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(WILL_NOT_RELOAD_DOC);
sleep(InfoSecs);
} else {
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
FREE(curdoc.address);
}
if (soft_dquotes)
soft_dquotes = FALSE;
else
soft_dquotes = TRUE;
_statusline(soft_dquotes ?
SOFT_DOUBLE_QUOTE_ON : SOFT_DOUBLE_QUOTE_OFF);
sleep(MessageSecs);
break;
case LYK_SWITCH_DTD:
/*
* Check if this is a reply from a POST, and if so,
* seek confirmation of reload if the safe element
* is not set. - FM, kw
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(WILL_NOT_RELOAD_DOC);
sleep(InfoSecs);
} else {
/*
* If currently viewing preparsed source, switching
* to the other DTD parsing may show source differences,
* so stay in source view - kw
*/
if (HTisDocumentSource() && LYPreparsedSource) {
HTOutputFormat = WWW_SOURCE;
}
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
FREE(curdoc.address);
}
#ifdef NO_ASSUME_SAME_DOC
newdoc.line=1;
newdoc.link=0;
#else
newdoc.line = ((curdoc.line > 0) ? curdoc.line : 1);
newdoc.link = ((curdoc.link > -1) ? curdoc.link : 0);
#endif /* NO_ASSUME_SAME_DOC */
if (New_DTD)
New_DTD = NO;
else
New_DTD = YES;
HTSwitchDTD(New_DTD);
_statusline(New_DTD ? USING_DTD_1 : USING_DTD_0);
sleep(MessageSecs);
break;
#ifdef NOT_DONE_YET
case LYK_PIPE:
/* ignore for now */
break;
#endif /* NOT_DONE_YET */
case LYK_QUIT: /* quit */
_statusline(REALLY_QUIT);
c = LYgetch();
#ifdef QUIT_DEFAULT_YES
if (TOUPPER(c) != 'N' &&
c != 7)
#else
if (TOUPPER(c) == 'Y')
#endif /* QUIT_DEFAULT_YES */
return(0);
else {
statusline(NO_CANCEL);
sleep(InfoSecs);
}
break;
case LYK_ABORT: /* don't ask the user about quitting */
return(0);
break;
case LYK_NEXT_PAGE: /* next page */
if (more) {
Newline += display_lines;
} else if (curdoc.link < nlinks-1) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = nlinks-1; /* put on last link */
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_END);
sleep(MessageSecs);
}
break;
case LYK_PREV_PAGE: /* page up */
if (Newline > 1) {
Newline -= display_lines;
} else if (curdoc.link > 0) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = 0; /* put on first link */
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_BEGIN);
sleep(MessageSecs);
}
break;
case LYK_UP_TWO:
if (Newline > 1) {
int scrollamount = (Newline > 2 ? 2 : 1);
Newline -= scrollamount;
if (nlinks > 0 && curdoc.link > -1) {
if (links[curdoc.link].ly + scrollamount <= display_lines) {
newdoc.link = curdoc.link +
HText_LinksInLines(HTMainText,
Newline, scrollamount);
} else {
arrowup = TRUE;
}
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_BEGIN);
sleep(MessageSecs);
}
break;
case LYK_DOWN_TWO:
if (more) {
Newline += 2;
if (nlinks > 0 && curdoc.link > -1 &&
links[curdoc.link].ly > 2) {
newdoc.link = curdoc.link;
for (i = 0; links[i].ly <= 2; i++)
--newdoc.link;
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_END);
sleep(MessageSecs);
}
break;
case LYK_UP_HALF:
if (Newline > 1) {
int scrollamount = display_lines/2;
if (Newline - scrollamount < 1)
scrollamount = Newline - 1;
Newline -= scrollamount;
if (nlinks > 0 && curdoc.link > -1) {
if (links[curdoc.link].ly + scrollamount <= display_lines) {
newdoc.link = curdoc.link +
HText_LinksInLines(HTMainText,
Newline,
scrollamount);
} else {
arrowup = TRUE;
}
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_BEGIN);
sleep(MessageSecs);
}
break;
case LYK_DOWN_HALF:
if (more) {
Newline += (display_lines/2);
if (nlinks > 0 && curdoc.link > -1 &&
links[curdoc.link].ly > display_lines/2) {
newdoc.link = curdoc.link;
for (i = 0; links[i].ly <= (display_lines/2); i++)
--newdoc.link;
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_END);
sleep(MessageSecs);
}
break;
case LYK_REFRESH:
refresh_screen = TRUE;
#if defined(VMS) || defined(USE_SLANG)
lynx_force_repaint();
#endif /* VMS || USE_SLANG */
break;
case LYK_HOME:
if (curdoc.line > 1)
Newline = 1;
else {
cmd = LYK_PREV_PAGE;
goto new_cmd;
}
break;
case LYK_END:
if (more) {
Newline = MAXINT; /* go to end of file */
arrowup = TRUE; /* position on last link */
} else {
cmd = LYK_NEXT_PAGE;
goto new_cmd;
}
break;
case LYK_PREV_LINK:
if (curdoc.link > 0) { /* previous link */
/*
* Unhighlight current link.
*/
highlight(OFF, curdoc.link, prev_target);
curdoc.link--;
} else if (!more &&
curdoc.link==0 && Newline==1) { /* at the top of list */
/*
* If there is only one page of data and the user
* goes off the top, then unhighlight the current
* link and just move the cursor to last link on
* the page.
*/
highlight(OFF, curdoc.link, prev_target);
curdoc.link = nlinks-1; /* the last link */
} else if (curdoc.line > 1) { /* previous page */
/*
* Go back to the previous page.
*/
int scrollamount = (Newline > display_lines ?
display_lines : Newline - 1);
Newline -= scrollamount;
if (scrollamount < display_lines &&
nlinks > 0 && curdoc.link == 0 &&
links[0].ly - 1 + scrollamount <= display_lines) {
newdoc.link = HText_LinksInLines(HTMainText,
1,
scrollamount) - 1;
} else {
arrowup = TRUE;
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_BEGIN);
sleep(MessageSecs);
}
break;
case LYK_NEXT_LINK:
if (curdoc.link < nlinks-1) { /* next link */
highlight(OFF, curdoc.link, prev_target);
#ifdef FASTTAB
/*
* Move to different textarea if TAB in textarea.
*/
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
links[curdoc.link].form->type == F_TEXTAREA_TYPE &&
c=='\t') {
int thisgroup = links[curdoc.link].form->number;
char *thisname = links[curdoc.link].form->name;
do curdoc.link++;
while ((curdoc.link < nlinks-1) &&
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
links[curdoc.link].form->type == F_TEXTAREA_TYPE &&
links[curdoc.link].form->number == thisgroup &&
sametext(links[curdoc.link].form->name, thisname));
} else {
curdoc.link++;
}
#else
curdoc.link++;
#endif /* FASTTAB */
/*
* At the bottom of list and there is only one page.
* Move to the top link on the page.
*/
} else if (!more && Newline == 1 && curdoc.link == nlinks-1) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = 0;
} else if (more) { /* next page */
Newline += (display_lines);
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_END);
sleep(MessageSecs);
}
break;
case LYK_UP_LINK:
if (curdoc.link > 0 &&
(links[0].ly != links[curdoc.link].ly ||
!HText_LinksInLines(HTMainText, 1, Newline - 1))) {
/* more links before this on screen, and first of them on
a different line or no previous links before this screen? */
int newlink = -1;
for (i = curdoc.link; i >= 0; i--) {
if (links[i].ly < links[curdoc.link].ly) {
newlink = i;
break;
}
}
if (newlink > -1) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = newlink;
#ifdef NOTDEFINED
} else if (!more && Newline == 1 && curdoc.link == 0) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = (nlinks-1);
} else if (more) { /* next page */
Newline += (display_lines);
#else
} else if (old_c != real_c) {
old_c = real_c;
_statusline(NO_LINKS_ABOVE);
sleep(MessageSecs);
#endif /* NOTDEFINED */
}
#ifdef NOTDEFINED
/*
* At the bottom of list and there is only one page.
* Move to the top link on the page.
*/
} else if (!more && Newline == 1 && curdoc.link == (nlinks-1)) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = 0;
#endif /* NOTDEFINED */
} else if (curdoc.line > 1 && Newline > 1) { /* previous page */
int scrollamount = (Newline > display_lines ?
display_lines : Newline - 1);
Newline -= scrollamount;
if (scrollamount < display_lines &&
nlinks > 0 && curdoc.link > -1 &&
links[0].ly -1 + scrollamount <= display_lines) {
newdoc.link = HText_LinksInLines(HTMainText,
1,
scrollamount) - 1;
} else {
arrowup = TRUE;
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_BEGIN);
sleep(MessageSecs);
}
break;
case LYK_DOWN_LINK:
if (curdoc.link < (nlinks-1)) { /* more links? */
int newlink = -1;
for (i = curdoc.link; i < nlinks; i++)
if (links[i].ly > links[curdoc.link].ly) {
newlink = i;
break;
}
if (newlink > -1) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = newlink;
#ifdef NOTDEFINED
} else if (!more &&
Newline == 1 && curdoc.link == (nlinks-1)) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = 0;
#endif /* NOTDEFINED */
} else if (more) { /* next page */
Newline += (display_lines);
} else if (old_c != real_c) {
old_c = real_c;
_statusline(NO_LINKS_BELOW);
sleep(MessageSecs);
break;
}
#ifdef NOTDEFINED
/*
* At the bottom of list and there is only one page.
* Move to the top link on the page.
*/
} else if (!more && Newline == 1 && curdoc.link == (nlinks-1)) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = 0;
#endif /* NOTDEFINED */
} else if (more) { /* next page */
Newline += (display_lines);
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_END);
sleep(MessageSecs);
}
break;
case LYK_RIGHT_LINK:
if (curdoc.link<nlinks-1 &&
links[curdoc.link].ly == links[curdoc.link+1].ly) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link++;
}
break;
case LYK_LEFT_LINK:
if (curdoc.link>0 &&
links[curdoc.link].ly == links[curdoc.link-1].ly) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link--;
}
break;
case LYK_COOKIE_JAR: /* show the cookie jar */
/*
* Don't do if already viewing the cookie jar.
*/
if (strcmp((curdoc.title ? curdoc.title : ""),
COOKIE_JAR_TITLE)) {
StrAllocCopy(newdoc.address, "LYNXCOOKIE:/");
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
LYforce_no_cache = TRUE;
if (LYValidate || check_realm) {
LYPermitURL = TRUE;
}
} else {
/*
* If already in the cookie jar, get out.
*/
cmd = LYK_PREV_DOC;
goto new_cmd;
}
break;
case LYK_HISTORY: /* show the history page */
if (curdoc.title && strcmp(curdoc.title, HISTORY_PAGE_TITLE)) {
/*
* Don't do this if already viewing history page.
*
* Push the current file so that the history list
* contains the current file for printing purposes.
* Pop the file afterwards to prevent multiple copies.
*/
if (TRACE && !LYUseTraceLog && LYCursesON) {
move(LYlines-1, LYcols-1); /* make sure cursor is down */
#ifdef USE_SLANG
addstr("\n");
#endif /* USE_SLANG */
refresh();
}
LYpush(&curdoc, ForcePush);
/*
* Print history options to file.
*/
if (showhistory(&newdoc.address) < 0) {
LYpop(&curdoc);
break;
}
StrAllocCopy(newdoc.title, HISTORY_PAGE_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
FREE(curdoc.address); /* so it doesn't get pushed */
refresh_screen = TRUE;
if (LYValidate || check_realm) {
LYPermitURL = TRUE;
}
break;
} /* end if strncmp */
/*
* Don't put break here so that if the backspace key
* is pressed in the history page, we fall though,
* i.e., it acts like a left arrow.
*/
case LYK_PREV_DOC: /* back up a level */
if (nhist > 0) { /* if there is anything to go back to */
/*
* Check if the previous document is a reply from a POST,
* and if so, seek confirmation of resubmission if the safe
* element is not set and the document is not still in the
* cache or LYresubmit_posts is set. If not confirmed and
* it is not the startfile, pop it so we go to the yet
* previous document, until we're OK or reach the startfile.
* If we reach the startfile and its not OK or we don't get
* confirmation, cancel. - FM
*/
DocAddress WWWDoc;
HTParentAnchor *tmpanchor;
while (nhist > 0) {
if (history[(nhist - 1)].post_data == NULL) {
break;
}
WWWDoc.address = history[(nhist - 1)].address;
WWWDoc.post_data = history[(nhist - 1)].post_data;
WWWDoc.post_content_type =
history[(nhist - 1)].post_content_type;
WWWDoc.bookmark = history[(nhist - 1)].bookmark;
WWWDoc.isHEAD = history[(nhist - 1)].isHEAD;
WWWDoc.safe = history[(nhist - 1)].safe;
tmpanchor = HTAnchor_parent(HTAnchor_findAddress(&WWWDoc));
if (HTAnchor_safe(tmpanchor)) {
break;
}
if (((HText *)HTAnchor_document(tmpanchor) == NULL ||
(LYresubmit_posts &&
NONINTERNAL_OR_PHYS_DIFFERENT(
(document *)&history[(nhist - 1)],
&curdoc))) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
if (nhist == 1) {
_statusline(CANCELLED);
sleep(InfoSecs);
old_c = 0;
cmd = LYK_DO_NOTHING;
goto new_cmd;
} else {
_user_message(WWW_SKIP_MESSAGE, WWWDoc.address);
sleep(MessageSecs);
LYpop(&curdoc);
continue;
}
} else {
break;
}
}
/*
* Set newdoc.address to empty to pop a file.
*/
FREE(newdoc.address);
#ifdef DIRED_SUPPORT
if (lynx_edit_mode)
HTuncache_current_document();
#endif /* DIRED_SUPPORT */
} else if (child_lynx == TRUE) {
return(0); /* exit on left arrow in main screen */
} else if (old_c != real_c) {
old_c = real_c;
_statusline(ALREADY_AT_FIRST);
sleep(MessageSecs);
}
break;
case LYK_NOCACHE: /* Force submission of form or link with no-cache */
if (nlinks > 0) {
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
links[curdoc.link].form->type != F_SUBMIT_TYPE &&
links[curdoc.link].form->type != F_IMAGE_SUBMIT_TYPE) {
if (old_c == real_c)
break;
old_c = real_c;
_statusline(NOT_ON_SUBMIT_OR_LINK);
sleep(MessageSecs);
break;
} else {
LYforce_no_cache = TRUE;
reloading = TRUE;
}
} /* fall through to LYK_ACTIVATE */
case LYK_ACTIVATE: /* follow a link */
{
/* Is there a mouse-clicked link waiting? */
int mouse_tmp = get_mouse_link();
/* If yes, use it as the link */
if (mouse_tmp != -1) curdoc.link = mouse_tmp;
}
if (nlinks > 0) {
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE) {
/*
* Don't try to submit forms with bad actions. - FM
*/
if (links[curdoc.link].form->type == F_SUBMIT_TYPE ||
links[curdoc.link].form->type == F_IMAGE_SUBMIT_TYPE ||
links[curdoc.link].form->type ==
F_TEXT_SUBMIT_TYPE) {
/*
* Do nothing if it's disabled. - FM
*/
if (links[curdoc.link].form->disabled == YES) {
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
break;
}
/*
* Make sure we have an action. - FM
*/
if (!links[curdoc.link].form->submit_action ||
*links[curdoc.link].form->submit_action
== '\0') {
_statusline(NO_FORM_ACTION);
sleep(MessageSecs);
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
break;
}
/*
* Check for no_mail if the form action
* is a mailto URL. - FM
*/
if (links[curdoc.link].form->submit_method
== URL_MAIL_METHOD && no_mail) {
HTAlert(FORM_MAILTO_DISALLOWED);
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
break;
}
/*
* Make sure this isn't a spoof in an account
* with restrictions on file URLs. - FM
*/
if (no_file_url &&
!strncasecomp(
links[curdoc.link].form->submit_action,
"file:", 5)) {
HTAlert(FILE_ACTIONS_DISALLOWED);
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
break;
}
/*
* Make sure this isn't a spoof attempt
* via an internal URL. - FM
*/
if (!strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXCOOKIE:", 11) ||
#ifdef DIRED_SUPPORT
#ifdef OK_PERMIT
(!(strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXDIRED:", 10)) &&
(no_dired_support ||
strncasecomp(
(links[curdoc.link].form->submit_action + 10),
"//PERMIT_LOCATION", 17) ||
strcmp(curdoc.address, LYPermitFileURL) ||
strcmp((curdoc.title ? curdoc.title : ""),
PERMIT_OPTIONS_TITLE))) ||
#else
!strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXDIRED:", 10) ||
#endif /* OK_PERMIT */
#endif /* DIRED_SUPPORT */
!strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXDOWNLOAD:", 13) ||
!strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXHIST:", 9) ||
!strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXKEYMAP:", 11) ||
!strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXIMGMAP:", 11) ||
!strncasecomp(
links[curdoc.link].form->submit_action,
"LYNXPRINT:", 10) ||
!strncasecomp(
links[curdoc.link].form->submit_action,
"lynxexec:", 9) ||
!strncasecomp(
links[curdoc.link].form->submit_action,
"lynxprog:", 9)) {
HTAlert(SPECIAL_ACTION_DISALLOWED);
if (TRACE) {
fprintf(stderr,
"LYMainLoop: Rejected '%s'\n",
links[curdoc.link].form->submit_action);
}
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
break;
}
#ifdef NOTDEFINED /* We're disabling form inputs instead of using this. - FM */
/*
* Check for enctype and let user know we
* don't yet support multipart/form-data - FM
*/
if (links[curdoc.link].form->submit_enctype) {
if (!strcmp(
links[curdoc.link].form->submit_enctype,
"multipart/form-data")) {
HTAlert(
"Enctype multipart/form-data not yet supported! Cannot submit.");
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
break;
}
}
#endif /* NOTDEFINED */
if (check_realm) {
LYPermitURL = TRUE;
}
if (no_filereferer == TRUE &&
!strncmp(curdoc.address, "file:", 5)) {
LYNoRefererForThis = TRUE;
}
StrAllocCopy(newdoc.title,
links[curdoc.link].hightext);
}
c = change_form_link(&links[curdoc.link],
FORM_UP, &newdoc, &refresh_screen,
links[curdoc.link].form->name,
links[curdoc.link].form->value);
if (HTOutputFormat == HTAtom_for("www/download") &&
newdoc.post_data != NULL &&
newdoc.safe == FALSE) {
if ((HText_POSTReplyLoaded(&newdoc) == TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(CANCELLED);
sleep(InfoSecs);
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
StrAllocCopy(newdoc.address, curdoc.address);
StrAllocCopy(newdoc.title, curdoc.title);
StrAllocCopy(newdoc.post_data, curdoc.post_data);
StrAllocCopy(newdoc.post_content_type,
curdoc.post_content_type);
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
newdoc.isHEAD = curdoc.isHEAD;
newdoc.safe = curdoc.safe;
newdoc.internal_link = curdoc.internal_link;
break;
}
}
if (c == 23) {
c = DO_NOTHING;
refresh_screen = TRUE;
}
goto new_keyboard_input;
} else {
/*
* Not a forms link.
*
* Make sure this isn't a spoof in an account
* with restrictions on file URLs. - FM
*/
if (no_file_url &&
!strncmp(links[curdoc.link].lname, "file:", 5)) {
if (strncmp(curdoc.address, "file:", 5)) {
HTAlert(FILE_SERVED_LINKS_DISALLOWED);
break;
} else if (curdoc.bookmark != NULL) {
HTAlert(FILE_BOOKMARKS_DISALLOWED);
break;
}
}
/*
* Make sure this isn't a spoof attempt
* via an internal URL in a non-internal
* document. - FM
*/
if ((!strncmp(links[curdoc.link].lname,
"LYNXCOOKIE:", 11) &&
strcmp((curdoc.title ? curdoc.title : ""),
COOKIE_JAR_TITLE)) ||
#ifdef DIRED_SUPPORT
(!strncmp(links[curdoc.link].lname,
"LYNXDIRED:", 10) &&
(strcmp(curdoc.address, LYDiredFileURL) ||
strcmp((curdoc.title ? curdoc.title : ""),
DIRED_MENU_TITLE)) &&
(strcmp(curdoc.address, LYPermitFileURL) ||
strcmp((curdoc.title ? curdoc.title : ""),
PERMIT_OPTIONS_TITLE)) &&
(strcmp(curdoc.address, LYUploadFileURL) ||
strcmp((curdoc.title ? curdoc.title : ""),
UPLOAD_OPTIONS_TITLE))) ||
#endif /* DIRED_SUPPORT */
(!strncmp(links[curdoc.link].lname,
"LYNXDOWNLOAD:", 13) &&
strcmp((curdoc.title ? curdoc.title : ""),
DOWNLOAD_OPTIONS_TITLE)) ||
(!strncmp(links[curdoc.link].lname,
"LYNXHIST:", 9) &&
strcmp((curdoc.title ? curdoc.title : ""),
HISTORY_PAGE_TITLE)) ||
(!strncmp(links[curdoc.link].lname,
"LYNXPRINT:", 10) &&
strcmp((curdoc.title ? curdoc.title : ""),
PRINT_OPTIONS_TITLE))) {
HTAlert(SPECIAL_VIA_EXTERNAL_DISALLOWED);
HTOutputFormat = WWW_PRESENT;
LYforce_no_cache = FALSE;
break;
}
/*
* Follow a normal link or anchor.
*/
StrAllocCopy(newdoc.address, links[curdoc.link].lname);
StrAllocCopy(newdoc.title, links[curdoc.link].hightext);
#ifndef DONT_TRACK_INTERNAL_LINKS
/*
* Might be an internal link anchor in the same doc.
* If so, take the try_internal shortcut if we didn't
* fall through from LYK_NOCACHE. - kw
*/
newdoc.internal_link =
(links[curdoc.link].type == WWW_INTERN_LINK_TYPE);
if (newdoc.internal_link) {
if (0==strcmp(curdoc.address, LYlist_temp_url()) &&
0==strcmp((curdoc.title ? curdoc.title : ""),
LIST_PAGE_TITLE)) {
FREE(curdoc.address);
} else if (cmd != LYK_NOCACHE) {
try_internal = TRUE;
}
LYoverride_no_cache = TRUE; /* ??? */
/* We still set force_load so that history pushing
** etc. will be done. - kw */
force_load = TRUE;
break;
} else {
}
#endif /* TRACK_INTERNAL_LINKS */
/*
* Might be an anchor in the same doc from a POST
* form. If so, dont't free the content. -- FM
*/
if (are_different(&curdoc, &newdoc)) {
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
}
if (!no_jump && lynxjumpfile && curdoc.address &&
!strcmp(lynxjumpfile, curdoc.address)) {
LYJumpFileURL = TRUE;
LYUserSpecifiedURL = TRUE;
} else if ((curdoc.title &&
!strcmp(curdoc.title, HISTORY_PAGE_TITLE)) ||
curdoc.bookmark != NULL ||
(lynxjumpfile &&
!strcmp(lynxjumpfile, curdoc.address))) {
LYUserSpecifiedURL = TRUE;
} else if (no_filereferer == TRUE &&
!strncmp(curdoc.address, "file:", 5)) {
LYNoRefererForThis = TRUE;
}
newdoc.link = 0;
force_load = TRUE; /* force MainLoop to reload */
#ifdef DIRED_SUPPORT
if (lynx_edit_mode) {
HTuncache_current_document();
/*
* Unescaping any slash chars in the URL,
* but avoid double unescaping and too-early
* unescaping of other chars. - KW
*/
HTUnEscapeSome(newdoc.address,"/");
strip_trailing_slash(newdoc.address);
}
#endif /* DIRED_SUPPORT */
if (!strncmp(curdoc.address, "LYNXCOOKIE:", 11)) {
HTuncache_current_document();
}
}
}
break;
case LYK_ECGOTO: /* edit current URL and go to to it */
if (no_goto && !LYValidate) {
if (old_c != real_c) {
old_c = real_c;
_statusline(GOTO_DISALLOWED);
sleep(MessageSecs);
}
break;
}
/*
* Save the current user_input_buffer string,
* and load the current document's address.
*/
StrAllocCopy(temp, user_input_buffer);
LYstrncpy(user_input_buffer,
curdoc.address,
(sizeof(user_input_buffer) - 1));
/*
* Warn the user if the current document has POST
* data associated with it. - FM
*/
if (curdoc.post_data)
HTAlert(CURRENT_DOC_HAS_POST_DATA);
/*
* Offer the current document's URL for editing. - FM
*/
_statusline(EDIT_CURDOC_URL);
if (((ch = LYgetstr(user_input_buffer, VISIBLE,
sizeof(user_input_buffer), RECALL)) >= 0) &&
user_input_buffer[0] != '\0' &&
strcmp(user_input_buffer, curdoc.address)) {
LYTrimHead(user_input_buffer);
if (!strncasecomp(user_input_buffer, "lynxexec:", 9) ||
!strncasecomp(user_input_buffer, "lynxprog:", 9)) {
/*
* The original implementations of these schemes expected
* white space without hex escaping, and did not check
* for hex escaping, so we'll continue to support that,
* until that code is redone in conformance with SGML
* principles. - FM
*/
HTUnEscapeSome(user_input_buffer, " \r\n\t");
convert_to_spaces(user_input_buffer, TRUE);
} else {
collapse_spaces(user_input_buffer);
}
if (user_input_buffer[0] != '\0') {
goto check_goto_URL;
}
}
/*
* User cancelled via ^G, a full deletion,
* or not modifying the URL. - FM
*/
_statusline(CANCELLED);
sleep(InfoSecs);
strcpy(user_input_buffer, temp);
FREE(temp);
break;
case LYK_GOTO: /* 'g' to goto a random URL */
if (no_goto && !LYValidate) {
if (old_c != real_c) {
old_c = real_c;
_statusline(GOTO_DISALLOWED);
sleep(MessageSecs);
}
break;
}
StrAllocCopy(temp, user_input_buffer);
if (!goto_buffer)
*user_input_buffer = '\0';
URLTotal = (Goto_URLs ? HTList_count(Goto_URLs) : 0);
if (goto_buffer && *user_input_buffer) {
recall = ((URLTotal > 1) ? RECALL : NORECALL);
URLNum = 0;
FirstURLRecall = FALSE;
} else {
recall = ((URLTotal >= 1) ? RECALL : NORECALL);
URLNum = URLTotal;
FirstURLRecall = TRUE;
}
/*
* Ask the user.
*/
_statusline(URL_TO_OPEN);
if ((ch = LYgetstr(user_input_buffer, VISIBLE,
sizeof(user_input_buffer), recall)) < 0 ) {
/*
* User cancelled the Goto via ^G.
* Restore user_input_buffer and break. - FM
*/
strcpy(user_input_buffer, temp);
FREE(temp);
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
check_recall:
/*
* Get rid of leading spaces (and any other spaces).
*/
LYTrimHead(user_input_buffer);
if (!strncasecomp(user_input_buffer, "lynxexec:", 9) ||
!strncasecomp(user_input_buffer, "lynxprog:", 9)) {
/*
* The original implementations of these schemes expected
* white space without hex escaping, and did not check
* for hex escaping, so we'll continue to support that,
* until that code is redone in conformance with SGML
* principles. - FM
*/
HTUnEscapeSome(user_input_buffer, " \r\n\t");
convert_to_spaces(user_input_buffer, TRUE);
} else {
collapse_spaces(user_input_buffer);
}
if (*user_input_buffer == '\0' &&
!(recall && (ch == UPARROW || ch == DNARROW))) {
strcpy(user_input_buffer, temp);
FREE(temp);
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
if (recall && ch == UPARROW) {
if (FirstURLRecall) {
/*
* Use last URL in the list. - FM
*/
FirstURLRecall = FALSE;
URLNum = 0;
} else {
/*
* Go back to the previous URL in the list. - FM
*/
URLNum++;
}
if (URLNum >= URLTotal)
/*
* Roll around to the last URL in the list. - FM
*/
URLNum = 0;
if ((cp = (char *)HTList_objectAt(Goto_URLs,
URLNum)) != NULL) {
strcpy(user_input_buffer, cp);
if (goto_buffer && *temp &&
!strcmp(temp, user_input_buffer)) {
_statusline(EDIT_CURRENT_GOTO);
} else if ((goto_buffer && URLTotal == 2) ||
(!goto_buffer && URLTotal == 1)) {
_statusline(EDIT_THE_PREV_GOTO);
} else {
_statusline(EDIT_A_PREV_GOTO);
}
if ((ch = LYgetstr(user_input_buffer, VISIBLE,
sizeof(user_input_buffer),
recall)) < 0) {
/*
* User cancelled the Goto via ^G.
* Restore user_input_buffer and break. - FM
*/
strcpy(user_input_buffer, temp);
FREE(temp);
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
goto check_recall;
}
} else if (recall && ch == DNARROW) {
if (FirstURLRecall) {
/*
* Use the first URL in the list. - FM
*/
FirstURLRecall = FALSE;
URLNum = URLTotal - 1;
} else {
/*
* Advance to the next URL in the list. - FM
*/
URLNum--;
}
if (URLNum < 0)
/*
* Roll around to the first URL in the list. - FM
*/
URLNum = URLTotal - 1;
if ((cp=(char *)HTList_objectAt(Goto_URLs,
URLNum)) != NULL) {
strcpy(user_input_buffer, cp);
if (goto_buffer && *temp &&
!strcmp(temp, user_input_buffer)) {
_statusline(EDIT_CURRENT_GOTO);
} else if ((goto_buffer && URLTotal == 2) ||
(!goto_buffer && URLTotal == 1)) {
_statusline(EDIT_THE_PREV_GOTO);
} else {
_statusline(EDIT_A_PREV_GOTO);
}
if ((ch = LYgetstr(user_input_buffer, VISIBLE,
sizeof(user_input_buffer),
recall)) < 0) {
/*
* User cancelled the Goto via ^G.
* Restore user_input_buffer and break. - FM
*/
strcpy(user_input_buffer, temp);
FREE(temp);
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
goto check_recall;
}
}
check_goto_URL:
/*
* If its not a URL then make it one.
*/
StrAllocCopy(temp, user_input_buffer);
LYFillLocalFileURL((char **)&temp, "file://localhost");
LYEnsureAbsoluteURL((char **)&temp, "");
sprintf(user_input_buffer, "%.*s",
(int)(sizeof(user_input_buffer) - 1), temp);
FREE(temp);
if ((no_file_url || no_goto_file) &&
!strncmp(user_input_buffer,"file:",5)) {
_statusline(GOTO_FILE_DISALLOWED);
sleep(MessageSecs);
#ifdef EXEC_LINKS
} else if ((no_shell || no_goto_lynxexec ||
local_exec_on_local_files) &&
#else
} else if ((no_shell || no_goto_lynxexec) &&
#endif /* EXEC_LINKS */
!strncmp(user_input_buffer, "lynxexec:",9)) {
_statusline(GOTO_EXEC_DISALLOWED);
sleep(MessageSecs);
#ifdef EXEC_LINKS
} else if ((no_shell || no_goto_lynxprog ||
local_exec_on_local_files) &&
#else
} else if ((no_shell || no_goto_lynxprog) &&
#endif /* EXEC_LINKS */
!strncmp(user_input_buffer, "lynxprog:",9)) {
_statusline(GOTO_PROG_DISALLOWED);
sleep(MessageSecs);
} else if ((no_shell || no_goto_lynxcgi) &&
!strncmp(user_input_buffer, "lynxcgi:", 8)) {
_statusline(GOTO_CGI_DISALLOWED);
sleep(MessageSecs);
} else if (LYValidate &&
strncmp(user_input_buffer, "http:", 5) &&
strncmp(user_input_buffer, "https:", 6)) {
_statusline(GOTO_NON_HTTP_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_cso &&
!strncmp(user_input_buffer, "cso:", 4)) {
_statusline(GOTO_CSO_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_finger &&
!strncmp(user_input_buffer, "finger:", 7)) {
_statusline(GOTO_FINGER_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_ftp &&
!strncmp(user_input_buffer, "ftp:", 4)) {
_statusline(GOTO_FTP_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_gopher &&
!strncmp(user_input_buffer, "gopher:", 7)) {
_statusline(GOTO_GOPHER_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_http &&
!strncmp(user_input_buffer, "http:", 5)) {
_statusline(GOTO_HTTP_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_https &&
!strncmp(user_input_buffer, "https:", 6)) {
_statusline(GOTO_HTTPS_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_mailto &&
!strncmp(user_input_buffer, "mailto:", 7)) {
_statusline(GOTO_MAILTO_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_news &&
!strncmp(user_input_buffer, "news:", 5)) {
_statusline(GOTO_NEWS_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_nntp &&
!strncmp(user_input_buffer, "nntp:", 5)) {
_statusline(GOTO_NNTP_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_rlogin &&
!strncmp(user_input_buffer, "rlogin:", 7)) {
_statusline(GOTO_RLOGIN_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_snews &&
!strncmp(user_input_buffer, "snews:", 6)) {
_statusline(GOTO_SNEWS_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_telnet &&
!strncmp(user_input_buffer, "telnet:", 7)) {
_statusline(GOTO_TELNET_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_tn3270 &&
!strncmp(user_input_buffer, "tn3270:", 7)) {
_statusline(GOTO_TN3270_DISALLOWED);
sleep(MessageSecs);
} else if (no_goto_wais &&
!strncmp(user_input_buffer, "wais:", 5)) {
_statusline(GOTO_WAIS_DISALLOWED);
sleep(MessageSecs);
} else if (!strncmp(user_input_buffer, "LYNXCOOKIE:", 11) ||
!strncmp(user_input_buffer, "LYNXDIRED:", 10) ||
!strncmp(user_input_buffer, "LYNXDOWNLOAD:", 13) ||
!strncmp(user_input_buffer, "LYNXPRINT:", 10)) {
_statusline(GOTO_SPECIAL_DISALLOWED);
sleep(MessageSecs);
} else {
StrAllocCopy(newdoc.address, user_input_buffer);
newdoc.isHEAD = FALSE;
/*
* Might be an anchor in the same doc from a POST
* form. If so, dont't free the content. -- FM
*/
if (are_different(&curdoc, &newdoc)) {
/*
* Make a name for this new URL.
*/
StrAllocCopy(newdoc.title, "A URL specified by the user");
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
force_load = TRUE;
#ifdef DIRED_SUPPORT
if (lynx_edit_mode)
HTuncache_current_document();
#endif /* DIRED_SUPPORT */
}
LYUserSpecifiedURL = TRUE;
HTAddGotoURL(newdoc.address);
}
break;
case LYK_HELP: /* show help file */
if (!STREQ(curdoc.address, helpfile)) {
/*
* Set the filename.
*/
StrAllocCopy(newdoc.address, helpfile);
/*
* Make a name for this help file.
*/
StrAllocCopy(newdoc.title, "Help Screen");
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
}
break;
case LYK_INDEX: /* index file */
/*
* Make sure we are not in the index already.
*/
if (!STREQ(curdoc.address, indexfile)) {
if (indexfile[0]=='\0') { /* no defined index */
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_INDEX_FILE);
sleep(MessageSecs);
}
} else {
StrAllocCopy(newdoc.address, indexfile);
StrAllocCopy(newdoc.title, "System Index"); /* name it */
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
} /* end else */
} /* end if */
break;
#ifdef NOT_USED
case LYK_FORM_UP: /* change form */
break; /* not implemented */
if (lynx_mode == FORMS_LYNX_MODE) {
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE) {
c = change_form_link(&links[curdoc.link],
FORM_UP, &newdoc, &refresh_screen,
links[curdoc.link].form->name,
links[curdoc.link].form->value);
/*
* Code to handle multiple submit buttons?
* Taken out due to bug it causes.
if (links[curdoc.link].form->type == F_SUBMIT_TYPE ||
links[curdoc.link].form->type == F_IMAGESUBMIT_TYPE) {
curdoc.address = NULL;
}
*/
goto new_keyboard_input;
} else {
_statusline("'X' can only toggle a form link");
}
} else {
_statusline("'X' only toggles in forms mode");
}
break;
case LYK_FORM_DOWN: /* change form */
break; /* not implemented */
if (lynx_mode==FORMS_LYNX_MODE) {
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE) {
c = change_form_link(&links[curdoc.link],
FORM_DOWN,&newdoc,&refresh_screen,
links[curdoc.link].form->name,
links[curdoc.link].form->value);
goto new_keyboard_input;
} else {
_statusline("'Z' can only toggle a form link");
}
} else {
_statusline("'Z' only toggles in forms mode");
}
break;
#endif /* NOT_USED */
case LYK_MAIN_MENU: /* return to main screen */
/*
* If its already the homepage then don't reload it.
*/
if (!STREQ(curdoc.address,homepage)) {
_statusline(CONFIRM_MAIN_SCREEN);
c = LYgetch();
if (TOUPPER(c)=='Y') {
StrAllocCopy(newdoc.address, homepage);
StrAllocCopy(newdoc.title, "Entry into main screen");
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
highlight(OFF, curdoc.link, prev_target);
#ifdef DIRED_SUPPORT
if (lynx_edit_mode)
HTuncache_current_document();
#endif /* DIRED_SUPPORT */
}
#ifdef VMS
if (HadVMSInterrupt)
HadVMSInterrupt = FALSE;
#endif /* VMS */
} else {
if (old_c != real_c) {
old_c = real_c;
_statusline(IN_MAIN_SCREEN);
sleep(MessageSecs);
}
}
break;
case LYK_OPTIONS: /* options screen */
#ifdef DIRED_SUPPORT
c = dir_list_style;
#endif /* DIRED_SUPPORT */
options(); /* do the options stuff */
if (keypad_mode_flag != keypad_mode ||
(user_mode_flag != user_mode &&
(user_mode_flag == NOVICE_MODE ||
user_mode == NOVICE_MODE)) ||
(((HTfileSortMethod_flag != HTfileSortMethod) ||
#ifdef DIRED_SUPPORT
(c != dir_list_style) ||
#endif /* DIRED_SUPPORT */
(show_dotfiles_flag != show_dotfiles)) &&
(!strncmp(curdoc.address, "file:", 5) ||
!strncmp(curdoc.address, "ftp:", 4))) ||
CurrentCharSet_flag != current_char_set ||
LYRawMode_flag != LYRawMode ||
LYSelectPopups_flag != LYSelectPopups ||
((strcmp(CurrentUserAgent, (LYUserAgent ?
LYUserAgent : "")) ||
strcmp(CurrentNegoLanguage, (language ?
language : "")) ||
strcmp(CurrentNegoCharset, (pref_charset ?
pref_charset : ""))) &&
(!strncmp(curdoc.address, "http", 4) ||
!strncmp(curdoc.address, "lynxcgi:", 8)))) {
/*
* Check if this is a reply from a POST, and if so,
* seek confirmation of reload if the safe element
* is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(WILL_NOT_RELOAD_DOC);
sleep(InfoSecs);
} else {
LYforce_no_cache = TRUE;
StrAllocCopy(newdoc.address, curdoc.address);
if (((strcmp(CurrentUserAgent, (LYUserAgent ?
LYUserAgent : "")) ||
strcmp(CurrentNegoLanguage,
(language ? language : "")) ||
strcmp(CurrentNegoCharset,
(pref_charset ? pref_charset : ""))) &&
(strncmp(curdoc.address, "http", 4) == 0 ||
strncmp(curdoc.address, "lynxcgi:", 8) == 0))) {
/*
* An option has changed which may influence
* content negotiation, and the resource is from
* a http or https or lynxcgi URL (the only protocols
* which currently do anything with this information).
* Set reloading = TRUE so that proxy caches will be
* flushed, which is necessary until the time when
* all proxies understand HTTP 1.1 Vary: and all
* Servers properly use it... Treat like
* case LYK_RELOAD (see comments there). - KW
*/
reloading = TRUE;
}
if (lynx_mode == FORMS_LYNX_MODE) {
_statusline(RELOADING_FORM);
sleep(AlertSecs);
}
if (HTisDocumentSource()) {
HTOutputFormat = WWW_SOURCE;
}
HEAD_request = HTLoadedDocumentIsHEAD();
HTuncache_current_document();
#ifdef NO_ASSUME_SAME_DOC
newdoc.line = 1;
newdoc.link = 0;
#else
newdoc.line = ((curdoc.line > 0) ?
curdoc.line : 1);
newdoc.link = ((curdoc.link > -1) ?
curdoc.link : 0);
#endif /* NO_ASSUME_SAME_DOC */
FREE(curdoc.address);
}
}
keypad_mode_flag = keypad_mode;
user_mode_flag = user_mode;
HTfileSortMethod_flag = HTfileSortMethod;
CurrentCharSet_flag = current_char_set;
show_dotfiles_flag = show_dotfiles;
LYRawMode_flag = LYRawMode;
LYSelectPopups_flag = LYSelectPopups;
StrAllocCopy(CurrentUserAgent, (LYUserAgent ?
LYUserAgent : ""));
StrAllocCopy(CurrentNegoLanguage, (language ?
language : ""));
StrAllocCopy(CurrentNegoCharset, (pref_charset ?
pref_charset : ""));
refresh_screen = TRUE; /* to repaint screen */
break;
case LYK_INDEX_SEARCH: /* search for a user string */
if (is_www_index) {
/*
* Perform a database search.
*
* do_www_search will try to go out and get the document.
* If it returns TRUE, a new document was returned and is
* named in the newdoc.address.
*/
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
if (do_www_search(&newdoc) == NORMAL) {
/*
* Yah, the search succeeded.
*/
if (TRACE && !LYUseTraceLog && LYCursesON) {
/*
* Make sure cursor is down.
*/
move(LYlines-1, LYcols-1);
#ifdef USE_SLANG
addstr("\n");
#endif /* USE_SLANG */
refresh();
}
LYpush(&curdoc, ForcePush);
/*
* Make the curdoc.address the newdoc.address so that
* getfile doesn't try to get the newdoc.address.
* Since we have already gotton it.
*/
StrAllocCopy(curdoc.address, newdoc.address);
StrAllocCopy(newdoc.post_data, curdoc.post_data);
newdoc.internal_link = FALSE;
curdoc.line = -1;
Newline = 0;
refresh_screen = TRUE; /* redisplay it */
} else if (use_this_url_instead != NULL) {
/*
* Got back a redirecting URL. Check it out.
*/
_user_message("Using %s", use_this_url_instead);
/*
* Make a name for this URL.
*/
StrAllocCopy(newdoc.title,
"A URL specified by redirection");
StrAllocCopy(newdoc.address, use_this_url_instead);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
FREE(use_this_url_instead);
force_load = TRUE;
break;
} else {
/*
* Yuk, the search failed. Restore the old file.
*/
StrAllocCopy(newdoc.address, curdoc.address);
StrAllocCopy(newdoc.post_data, curdoc.post_data);
StrAllocCopy(newdoc.post_content_type,
curdoc.post_content_type);
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
newdoc.isHEAD = curdoc.isHEAD;
newdoc.safe = curdoc.safe;
newdoc.internal_link = curdoc.internal_link;
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(NOT_ISINDEX);
sleep(MessageSecs);
}
break;
case LYK_WHEREIS: /* search within the document */
case LYK_NEXT: /* search for the next occurrence in the document */
/* user search */
{
BOOLEAN have_target_onscreen = (*prev_target != '\0' &&
HText_pageHasPrevTarget());
BOOL found;
int oldcur = curdoc.link; /* temporarily remember */
char *remember_old_target = NULL;
if (have_target_onscreen)
StrAllocCopy(remember_old_target, prev_target);
else
StrAllocCopy(remember_old_target, "");
if (cmd != LYK_NEXT) {
/*
* Reset prev_target to force prompting
* for a new search string and to turn
* off highlighting in no search string
* is entered by the user.
*/
*prev_target = '\0';
found = textsearch(&curdoc, prev_target, FALSE);
} else {
/*
* When the third argument is TRUE, the previous
* search string, if any, will be recalled from
* a buffer, loaded into prev_target, and used
* for the search without prompting for a new
* search string. This allows the LYK_NEXT
* command to repeat a search in a new document,
* after prev_target was reset on fetch of that
* document.
*/
found = textsearch(&curdoc, prev_target, TRUE);
}
/*
* Force a redraw to ensure highlighting of hits
* even when found on the same page, or clearing
* of highlighting is the default search string
* was erased without replacement. - FM
*/
/*
** Well let's try to avoid it at least in a few cases
** where it is not needed. - kw
*/
if (www_search_result >= 0 && www_search_result != curdoc.line) {
refresh_screen = TRUE; /* doesn't really matter */
} else if (!found) {
refresh_screen = have_target_onscreen;
} else if (!have_target_onscreen && found) {
refresh_screen = TRUE;
} else if (www_search_result == curdoc.line &&
curdoc.link == oldcur &&
curdoc.link >= 0 && nlinks > 0 &&
links[curdoc.link].ly >= (display_lines/3)) {
refresh_screen = TRUE;
} else if ((case_sensitive && 0!=strcmp(prev_target,
remember_old_target)) ||
(!case_sensitive && 0!=strcasecomp(prev_target,
remember_old_target))) {
refresh_screen = TRUE;
}
FREE(remember_old_target);
}
break;
case LYK_COMMENT: /* reply by mail */
if (!owner_address &&
strncasecomp(curdoc.address, "http", 4)) {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_OWNER);
sleep(MessageSecs);
}
} else if (no_mail) {
if (old_c != real_c) {
old_c = real_c;
_statusline(MAIL_DISALLOWED);
sleep(MessageSecs);
}
} else {
_statusline(CONFIRM_COMMENT);
c = LYgetch();
if (TOUPPER(c) == 'Y') {
if (!owner_address) {
/*
* No owner defined, so make a guess and
* and offer it to the user. - FM
*/
char *address = NULL;
temp = HTParse(curdoc.address, "", PARSE_PATH);
if (temp != NULL) {
HTUnEscape(temp);
if (*temp == '~' && strlen(temp) > 1) {
/*
* It's a ~user URL so guess user@host. - FM
*/
if ((cp = strchr((temp+1), '/')) != NULL)
*cp = '\0';
StrAllocCopy(address, "mailto:");
StrAllocCat(address, (temp+1));
StrAllocCat(address, "@");
}
FREE(temp);
}
if (address == NULL)
/*
* Wasn't a ~user URL so guess WebMaster@host. - FM
*/
StrAllocCopy(address, "mailto:WebMaster@");
temp = HTParse(curdoc.address, "", PARSE_HOST);
StrAllocCat(address, temp);
FREE(temp);
_user_message(NO_OWNER_USE, address);
c = LYgetch();
if (TOUPPER(c) == 'Y') {
StrAllocCopy(owner_address, address);
FREE(address);
} else {
FREE(address);
break;
}
}
if (is_url(owner_address) != MAILTO_URL_TYPE) {
/*
* The address is a URL. Just follow the link.
*/
StrAllocCopy(newdoc.address, owner_address);
newdoc.internal_link = FALSE;
} else {
/*
* The owner_address is a mailto: URL.
*/
cp = HText_getRevTitle();
if (strchr(owner_address,':')!=NULL)
/*
* Send a reply. The address is after the colon.
*/
reply_by_mail(strchr(owner_address,':')+1,
curdoc.address,
(cp ? cp : ""));
else
reply_by_mail(owner_address, curdoc.address,
(cp ? cp : ""));
refresh_screen = TRUE; /* to force a showpage */
}
}
}
break;
#ifdef DIRED_SUPPORT
case LYK_TAG_LINK: /* tag or untag the current link */
if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
if (!strcmp(links[curdoc.link].hightext, ".."))
break; /* Never tag the parent directory */
if (dir_list_style == MIXED_STYLE) {
if (!strcmp(links[curdoc.link].hightext, "../"))
break;
} else if (!strncmp(links[curdoc.link].hightext, "Up to ", 6))
break;
{
/*
* HTList-based management of tag list, see LYLocal.c - KW
*/
HTList * t1 = tagged;
char * tagname = NULL;
BOOLEAN found = FALSE;
while ((tagname = (char *)HTList_nextObject(t1)) != NULL) {
if (!strcmp(links[curdoc.link].lname, tagname)) {
found = TRUE;
HTList_removeObject(tagged, tagname);
FREE(tagname);
tagflag(OFF,curdoc.link);
break;
}
}
if (!found) {
if (tagged == NULL)
tagged = HTList_new();
tagname = NULL;
StrAllocCopy(tagname,links[curdoc.link].lname);
HTList_addObject(tagged,tagname);
tagflag(ON,curdoc.link);
}
}
if (curdoc.link < nlinks-1) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link++;
} else if (!more && Newline == 1 && curdoc.link == nlinks-1) {
highlight(OFF, curdoc.link, prev_target);
curdoc.link = 0;
} else if (more) { /* next page */
Newline += (display_lines);
}
}
break;
case LYK_MODIFY: /* rename a file or directory */
if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
int ret;
ret = local_modify(&curdoc, &newdoc.address);
if (ret == PERMIT_FORM_RESULT) { /* Permit form thrown up */
refresh_screen = TRUE;
} else if (ret) {
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
FREE(curdoc.address);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
newdoc.line = curdoc.line;
newdoc.link = curdoc.link;
clear();
}
}
break;
case LYK_CREATE: /* create a new file or directory */
if (lynx_edit_mode && !no_dired_support) {
if (local_create(&curdoc)) {
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
FREE(curdoc.address);
FREE(curdoc.address);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.line = curdoc.line;
newdoc.link = curdoc.link > -1 ? curdoc.link : 0;
clear();
}
}
break;
#endif /* DIRED_SUPPORT */
case LYK_EDIT: /* edit */
if (no_editor) {
if (old_c != real_c) {
old_c = real_c;
_statusline(EDIT_DISABLED);
sleep(MessageSecs);
}
break;
}
#ifdef DIRED_SUPPORT
/*
* Allow the user to edit the link rather
* than curdoc in edit mode.
*/
if (lynx_edit_mode &&
editor && *editor != '\0' && !no_dired_support) {
if (nlinks > 0) {
cp = links[curdoc.link].lname;
if (is_url(cp) == FILE_URL_TYPE) {
if (!strncmp(cp, "file://localhost", 16)) {
/*
* This is the only case that should occur. - kw
*/
StrAllocCopy(tp, cp + 16);
} else if (!strncmp(cp, "file:", 5)) {
StrAllocCopy(tp, cp + 5);
} else {
StrAllocCopy(tp, cp);
}
HTUnEscape(tp);
if (stat(tp, &dir_info) == -1) {
_statusline(NO_STATUS);
sleep(AlertSecs);
} else {
if (((dir_info.st_mode) & S_IFMT) == S_IFREG) {
StrAllocCopy(tp, cp);
HTUnEscapeSome(tp, "/");
if (edit_current_file(tp,
curdoc.link, Newline)) {
HTuncache_current_document();
StrAllocCopy(newdoc.address,
curdoc.address);
FREE(curdoc.address);
#ifdef NO_SEEK_OLD_POSITION
/*
* Go to top of file.
*/
newdoc.line = 1;
newdoc.link = 0;
#else
/*
* Seek old position,
* which probably changed.
*/
newdoc.line =
((curdoc.line > 0) ? curdoc.line : 1);
newdoc.link =
((curdoc.link > -1) ? curdoc.link : 0);
#endif /* NO_SEEK_OLD_POSITION */
clear(); /* clear the screen */
}
}
}
FREE(tp);
}
}
} else
#endif /* DIRED_SUPPORT */
if (editor && *editor != '\0') {
if (edit_current_file(newdoc.address, curdoc.link, Newline)) {
HTuncache_current_document();
LYforce_no_cache = TRUE; /*force reload of document */
FREE(curdoc.address); /* so it doesn't get pushed */
#ifdef NO_SEEK_OLD_POSITION
/*
* Go to top of file.
*/
newdoc.line = 1;
newdoc.link = 0;
#else
/*
* Seek old position, which probably changed.
*/
newdoc.line = curdoc.line;
newdoc.link = curdoc.link;
#endif /* NO_SEEK_OLD_POSITION */
clear(); /* clear the screen */
}
} else {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_EDITOR);
sleep(MessageSecs);
}
}
break;
case LYK_DEL_BOOKMARK: /* remove a bookmark file link */
#ifdef DIRED_SUPPORT
case LYK_REMOVE: /* remove files and directories */
c = 'N';
if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
local_remove(&curdoc);
c = 'Y';
} else
#endif /* DIRED_SUPPORT */
if (curdoc.bookmark != NULL) {
_statusline(CONFIRM_BOOKMARK_DELETE);
c = LYgetch();
if (TOUPPER(c) != 'Y')
break;
remove_bookmark_link(links[curdoc.link].anchor_number-1,
curdoc.bookmark);
} else { /* behave like REFRESH for backward compatability */
refresh_screen = TRUE;
break;
}
if (TOUPPER(c) == 'Y') {
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
FREE(curdoc.address);
newdoc.line = curdoc.line;
if (curdoc.link == nlinks-1) {
/*
* We deleted the last link on the page. - FM
*/
newdoc.link = curdoc.link-1;
} else {
newdoc.link = curdoc.link;
}
}
break;
#ifdef DIRED_SUPPORT
case LYK_INSTALL: /* install a file into system area */
if (lynx_edit_mode && nlinks > 0 && !no_dired_support)
local_install(NULL, links[curdoc.link].lname, &newdoc.address);
break;
#endif /* DIRED_SUPPORT */
case LYK_INFO: /* show document info */
/*
* Don't do if already viewing info page.
*/
if (strcmp((curdoc.title ? curdoc.title : ""),
SHOWINFO_TITLE)) {
if (!showinfo(&curdoc, lines_in_file,
&newdoc, owner_address))
break;
StrAllocCopy(newdoc.title, SHOWINFO_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
LYforce_no_cache = TRUE;
if (LYValidate || check_realm)
LYPermitURL = TRUE;
} else {
/*
* If already in info page, get out.
*/
cmd = LYK_PREV_DOC;
goto new_cmd;
}
break;
case LYK_PRINT: /* print the file */
if (LYValidate) {
if (old_c != real_c) {
old_c = real_c;
_statusline(PRINT_DISABLED);
sleep(MessageSecs);
}
break;
}
/*
* Don't do if already viewing print options page.
*/
if (strcmp((curdoc.title ? curdoc.title : ""),
PRINT_OPTIONS_TITLE)) {
if (print_options(&newdoc.address, lines_in_file) < 0)
break;
StrAllocCopy(newdoc.title, PRINT_OPTIONS_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
ForcePush = TRUE;
if (check_realm)
LYPermitURL = TRUE;
refresh_screen = TRUE; /* redisplay */
}
break;
case LYK_LIST: /* list links in the current document */
/*
* Don't do if already viewing list page.
*/
if (!strcmp((curdoc.title ? curdoc.title : ""),
LIST_PAGE_TITLE)) {
/*
* Already viewing list page, so get out.
*/
cmd = LYK_PREV_DOC;
goto new_cmd;
}
/*
* Print list page to file.
*/
if (showlist(&newdoc.address, TRUE) < 0)
break;
StrAllocCopy(newdoc.title, LIST_PAGE_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
refresh_screen = TRUE; /* redisplay */
if (LYValidate || check_realm) {
LYPermitURL = TRUE;
StrAllocCopy(lynxlistfile, newdoc.address);
}
break;
case LYK_VLINKS: /* list links visited during the current session */
if (!strcmp((curdoc.title ? curdoc.title : ""),
VISITED_LINKS_TITLE)) {
/*
* Already viewing visited links page, so get out.
*/
cmd = LYK_PREV_DOC;
goto new_cmd;
}
/*
* Print visited links page to file.
*/
if (LYShowVisitedLinks(&newdoc.address) < 0) {
_statusline(VISITED_LINKS_EMPTY);
sleep(MessageSecs);
break;
}
StrAllocCopy(newdoc.title, VISITED_LINKS_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
refresh_screen = TRUE;
if (LYValidate || check_realm) {
LYPermitURL = TRUE;
StrAllocCopy(lynxlinksfile, newdoc.address);
}
break;
case LYK_TOOLBAR: /* go to Toolbar or Banner in current document */
if (!HText_hasToolbar(HTMainText)) {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_TOOLBAR);
sleep(MessageSecs);
}
} else if (old_c != real_c) {
old_c = real_c;
if ((cp = strchr(curdoc.address, '#')) != NULL)
*cp = '\0';
toolbar = (char *)malloc(strlen(curdoc.address) +
strlen(LYToolbarName) + 2);
sprintf(toolbar, "%s#%s", curdoc.address, LYToolbarName);
if (cp)
*cp = '#';
StrAllocCopy(newdoc.address, toolbar);
FREE(toolbar);
try_internal = TRUE;
force_load = TRUE; /* force MainLoop to reload */
}
break;
#if defined(DIRED_SUPPORT) || defined(VMS)
case LYK_DIRED_MENU: /* provide full file management menu */
#ifdef VMS
/*
* Check if the CSwing Directory/File Manager is available.
* Will be disabled if LYCSwingPath is NULL, zero-length,
* or "none" (case insensitive), if no_file_url was set via
* the file_url restriction, if no_goto_file was set for
* the anonymous account, or if HTDirAccess was set to
* HT_DIR_FORBID or HT_DIR_SELECTIVE via the -nobrowse
* or -selective switches. - FM
*/
if (!(LYCSwingPath && *LYCSwingPath) ||
!strcasecomp(LYCSwingPath, "none") ||
no_file_url || no_goto_file ||
HTDirAccess == HT_DIR_FORBID ||
HTDirAccess == HT_DIR_SELECTIVE) {
if (old_c != real_c) {
old_c = real_c;
_statusline(DFM_NOT_AVAILABLE);
sleep(MessageSecs);
}
break;
}
/*
* If we are viewing a local directory listing or a
* local file which is not temporary, invoke CSwing
* with the URL's directory converted to VMS path specs
* and passed as the argument, so we start up CSwing
* positioned on that node of the directory tree.
* Otherwise, pass the current default directory as
* the argument. - FM
*/
if (LYisLocalFile(curdoc.address) &&
strncasecomp(curdoc.address,
lynx_temp_space, strlen(lynx_temp_space))) {
/*
* We are viewing a local directory or a local file
* which is not temporary. - FM
*/
struct stat stat_info;
cp = HTParse(curdoc.address, "", PARSE_PATH|PARSE_PUNCTUATION);
HTUnEscape(cp);
if (HTStat(cp, &stat_info) == -1) {
if (TRACE)
fprintf(stderr, "mainloop: Can't stat %s\n", cp);
FREE(cp);
temp = (char *)calloc(1, (strlen(LYCSwingPath) + 4));
if (temp == NULL)
outofmem(__FILE__, "mainloop");
sprintf(temp, "%s []", LYCSwingPath);
refresh_screen = TRUE; /* redisplay */
} else {
char *VMSdir = NULL;
if (((stat_info.st_mode) & S_IFMT) == S_IFDIR) {
/*
* We're viewing a local directory. Make
* that the CSwing argument. - FM
*/
if (cp[(strlen(cp) - 1)] != '/')
StrAllocCat(cp, "/");
StrAllocCopy(VMSdir, HTVMS_name("", cp));
FREE(cp);
} else {
/*
* We're viewing a local file. Make it's
* directory the CSwing argument. - FM
*/
StrAllocCopy(VMSdir, HTVMS_name("", cp));
FREE(cp);
if ((cp = strrchr(VMSdir, ']')) != NULL) {
*(cp + 1) = '\0';
cp == NULL;
} else if ((cp = strrchr(VMSdir, ':')) != NULL) {
*(cp + 1) = '\0';
cp == NULL;
}
}
temp = (char *)calloc(1,
(strlen(LYCSwingPath) +
strlen(VMSdir) +
2));
if (temp == NULL)
outofmem(__FILE__, "mainloop");
sprintf(temp, "%s %s", LYCSwingPath, VMSdir);
FREE(VMSdir);
/*
* Uncache the current document in case we
* change, move, or delete it during the
* CSwing session. - FM
*/
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
StrAllocCopy(newdoc.title,
curdoc.title ? curdoc.title : "");
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
FREE(curdoc.address);
newdoc.line = curdoc.line;
newdoc.link = curdoc.link;
}
} else {
/*
* We're not viewing a local directory or file.
* Pass CSwing the current default directory as
* an argument and don't uncache the current
* document. - FM
*/
temp = (char *)calloc(1, (strlen(LYCSwingPath) + 4));
if (temp == NULL)
outofmem(__FILE__, "mainloop");
sprintf(temp, "%s []", LYCSwingPath);
refresh_screen = TRUE; /* redisplay */
}
stop_curses();
system(temp);
start_curses();
FREE(temp);
break;
#else
/*
* Don't do if not allowed or already viewing the menu.
*/
if (lynx_edit_mode && !no_dired_support &&
strcmp(curdoc.address, LYDiredFileURL) &&
strcmp((curdoc.title ? curdoc.title : ""),
DIRED_MENU_TITLE)) {
dired_options(&curdoc,&newdoc.address);
refresh_screen = TRUE; /* redisplay */
}
break;
#endif /* VMS */
#endif /* DIRED_SUPPORT || VMS*/
#ifdef USE_EXTERNALS
case LYK_EXTERN: /* use external program on url */
run_external(links[curdoc.link].lname);
refresh_screen = TRUE;
break;
#endif /* USE_EXTERNALS */
case LYK_ADD_BOOKMARK: /* add link to bookmark file */
if (LYValidate) {
if (old_c != real_c) {
old_c = real_c;
_statusline(BOOKMARKS_DISABLED);
sleep(MessageSecs);
}
break;
}
if (strcmp((curdoc.title ? curdoc.title : ""),
HISTORY_PAGE_TITLE) &&
strcmp((curdoc.title ? curdoc.title : ""),
SHOWINFO_TITLE) &&
strcmp((curdoc.title ? curdoc.title : ""),
PRINT_OPTIONS_TITLE) &&
#ifdef DIRED_SUPPORT
strcmp(curdoc.address, LYDiredFileURL) &&
strcmp((curdoc.title ? curdoc.title : ""),
DIRED_MENU_TITLE) &&
strcmp(curdoc.address, LYPermitFileURL) &&
strcmp((curdoc.title ? curdoc.title : ""),
PERMIT_OPTIONS_TITLE) &&
strcmp(curdoc.address, LYUploadFileURL) &&
strcmp((curdoc.title ? curdoc.title : ""),
UPLOAD_OPTIONS_TITLE) &&
#endif /* DIRED_SUPPORT */
strcmp((curdoc.title ? curdoc.title : ""),
DOWNLOAD_OPTIONS_TITLE) &&
strcmp((curdoc.title ? curdoc.title : ""),
COOKIE_JAR_TITLE) &&
((nlinks <= 0) ||
(links[curdoc.link].lname != NULL &&
strncmp(links[curdoc.link].lname,
"LYNXHIST:", 9) &&
strncmp(links[curdoc.link].lname,
"LYNXPRINT:", 10) &&
strncmp(links[curdoc.link].lname,
"LYNXDIRED:", 10) &&
strncmp(links[curdoc.link].lname,
"LYNXDOWNLOAD:", 13) &&
strncmp(links[curdoc.link].lname,
"LYNXCOOKIE:", 11) &&
strncmp(links[curdoc.link].lname,
"LYNXLIST:", 9)))) {
if (nlinks > 0) {
if (curdoc.post_data == NULL &&
curdoc.bookmark == NULL &&
strcmp((curdoc.title ? curdoc.title : ""),
LIST_PAGE_TITLE) &&
strcmp((curdoc.title ? curdoc.title : ""),
VISITED_LINKS_TITLE)) {
/*
* The document doesn't have POST content,
* and is not a bookmark file, nor is the
* list or visited links page, so we can
* save either that or the link. - FM
*/
_statusline(BOOK_D_L_OR_CANCEL);
c = LYgetch();
if (TOUPPER(c) == 'D') {
save_bookmark_link(curdoc.address, curdoc.title);
refresh_screen = TRUE; /* MultiBookmark support */
goto check_add_bookmark_to_self;
}
} else {
if (LYMultiBookmarks == FALSE &&
curdoc.bookmark != NULL &&
strstr(curdoc.address,
(*bookmark_page == '.'
?
(bookmark_page+1) : bookmark_page)) != NULL) {
/*
* If multiple bookmarks are disabled, offer
* the L)ink or C)ancel, but with wording
* which indicates that the link already
* exists in this bookmark file. - FM
*/
_statusline(MULTIBOOKMARKS_SELF);
} else {
/*
* Only offer the link in a document with
* POST content, or if the current document
* is a bookmark file and multiple bookmarks
* are enabled. - FM
*/
_statusline(BOOK_L_OR_CANCEL);
}
c = LYgetch();
}
if (TOUPPER(c) == 'L') {
/*
* User does want to save the link. - FM
*/
if (links[curdoc.link].type != WWW_FORM_LINK_TYPE) {
save_bookmark_link(links[curdoc.link].lname,
links[curdoc.link].hightext);
refresh_screen = TRUE; /* MultiBookmark support */
} else {
_statusline(NOBOOK_FORM_FIELD);
sleep(MessageSecs);
break;
}
} else {
break;
}
} else if (curdoc.post_data != NULL) {
/*
* No links, and document has POST content. - FM
*/
_statusline(NOBOOK_POST_FORM);
sleep(MessageSecs);
break;
} else if (curdoc.bookmark != NULL) {
/*
* It's a bookmark file from which all
* of the links were deleted. - FM
*/
_statusline(BOOKMARKS_NOLINKS);
sleep(MessageSecs);
break;
} else {
_statusline(BOOK_D_OR_CANCEL);
c = LYgetch();
if (TOUPPER(c) == 'D') {
save_bookmark_link(curdoc.address, curdoc.title);
refresh_screen = TRUE; /* MultiBookmark support */
} else {
break;
}
}
check_add_bookmark_to_self:
if (curdoc.bookmark && BookmarkPage &&
!strcmp(curdoc.bookmark, BookmarkPage)) {
HTuncache_current_document();
StrAllocCopy(newdoc.address, curdoc.address);
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
FREE(curdoc.address);
newdoc.line = curdoc.line;
newdoc.link = curdoc.link;
newdoc.internal_link = FALSE;
}
FREE(temp);
} else {
if (old_c != real_c) {
old_c = real_c;
_statusline(NOBOOK_HSML);
sleep(MessageSecs);
}
}
break;
case LYK_VIEW_BOOKMARK: /* v to view home page */
if (LYValidate) {
if (old_c != real_c) {
old_c = real_c;
_statusline(BOOKMARKS_DISABLED);
sleep(MessageSecs);
}
break;
}
/*
* See if a bookmark exists.
* If it does replace newdoc.address with it's name.
*/
if ((cp = get_bookmark_filename(&newdoc.address)) != NULL) {
if (*cp == '\0' || !strcmp(cp, " ") ||
!strcmp(curdoc.address, newdoc.address)) {
if (LYMultiBookmarks == TRUE)
refresh_screen = TRUE;
break;
}
LYforce_no_cache = TRUE; /*force the document to be reloaded*/
StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
StrAllocCopy(newdoc.bookmark, BookmarkPage);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
} else {
if (old_c != real_c) {
old_c = real_c;
LYMBM_statusline(BOOKMARKS_NOT_OPEN);
sleep(AlertSecs);
if (LYMultiBookmarks == TRUE) {
refresh_screen = TRUE;
}
}
}
break;
case LYK_SHELL: /* shell escape */
if (!no_shell) {
stop_curses();
printf(SPAWNING_MSG);
fflush(stdout);
fflush(stderr);
if (LYTraceLogFP)
/*
* Set stderr back to its orginal value
* during the shell escape. - FM
*/
*stderr = LYOrigStderr;
#ifdef DOSPATH
system("cls");
system("echo Type EXIT to return to Lynx.");
#ifdef __DJGPP__
__djgpp_set_ctrl_c(0);
_go32_want_ctrl_break(1);
#endif /* __DJGPP__ */
if (getenv("SHELL") != NULL) {
system(getenv("SHELL"));
} else {
system(getenv("COMSPEC") == NULL ? "command.com" : getenv("COMSPEC"));
}
#ifdef __DJGPP__
__djgpp_set_ctrl_c(1);
_go32_want_ctrl_break(0);
#endif /* __DJGPP__ */
#else
#ifdef VMS
system("");
#else
system("exec $SHELL");
#endif /* VMS */
#endif /* DOSPATH */
if (LYTraceLogFP)
/*
* Set stderr back to the log file on
* return from the shell escape. - FM
*/
*stderr = *LYTraceLogFP;
start_curses();
refresh_screen = TRUE; /* for an HText_pageDisplay() */
} else {
if (old_c != real_c) {
old_c = real_c;
_statusline(SPAWNING_DISABLED);
sleep(MessageSecs);
}
}
break;
case LYK_DOWNLOAD:
/*
* Don't do if both download and disk_save are restricted.
*/
if (LYValidate ||
(no_download && !override_no_download && no_disk_save)) {
if (old_c != real_c) {
old_c = real_c;
_statusline(DOWNLOAD_DISABLED);
sleep(MessageSecs);
}
break;
}
/*
* Don't do if already viewing download options page.
*/
if (!strcmp((curdoc.title ? curdoc.title : ""),
DOWNLOAD_OPTIONS_TITLE))
break;
if (nlinks > 0) {
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE) {
if (links[curdoc.link].form->type == F_SUBMIT_TYPE ||
links[curdoc.link].form->type == F_IMAGE_SUBMIT_TYPE) {
if (links[curdoc.link].form->submit_method ==
URL_MAIL_METHOD) {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_DOWNLOAD_MAILTO_ACTION);
sleep(MessageSecs);
}
break;
}
HTOutputFormat = HTAtom_for("www/download");
LYforce_no_cache = TRUE;
cmd = LYK_ACTIVATE;
goto new_cmd;
}
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_DOWNLOAD_INPUT);
sleep(MessageSecs);
}
} else if (!strcmp((curdoc.title ? curdoc.title : ""),
COOKIE_JAR_TITLE)) {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_DOWNLOAD_COOKIES);
sleep(MessageSecs);
}
} else if (!strcmp((curdoc.title ? curdoc.title : ""),
PRINT_OPTIONS_TITLE)) {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_DOWNLOAD_PRINT_OP);
sleep(MessageSecs);
}
#ifdef DIRED_SUPPORT
} else if (!strcmp(curdoc.address, LYUploadFileURL) ||
!strcmp((curdoc.title ? curdoc.title : ""),
UPLOAD_OPTIONS_TITLE)) {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_DOWNLOAD_UPLOAD_OP);
sleep(MessageSecs);
}
} else if (!strcmp(curdoc.address, LYPermitFileURL) ||
!strcmp((curdoc.title ? curdoc.title : ""),
PERMIT_OPTIONS_TITLE)) {
if (old_c != real_c) {
old_c = real_c;
_statusline(NO_DOWNLOAD_PERMIT_OP);
sleep(MessageSecs);
}
} else if (lynx_edit_mode && !no_dired_support) {
/*
* Don't bother making a /tmp copy of the local file.
*/
StrAllocCopy(temp, newdoc.address);
StrAllocCopy(newdoc.address, links[curdoc.link].lname);
if (LYdownload_options(&newdoc.address,
links[curdoc.link].lname) < 0)
StrAllocCopy(newdoc.address, temp);
else
newdoc.internal_link = FALSE;
FREE(temp);
#endif /* DIRED_SUPPORT */
} else if (!strcmp((curdoc.title ? curdoc.title : ""),
HISTORY_PAGE_TITLE)) {
int number = atoi(links[curdoc.link].lname+9);
if ((history[number].post_data != NULL &&
history[number].safe != TRUE) &&
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
StrAllocCopy(newdoc.address, history[number].address);
StrAllocCopy(newdoc.title, links[curdoc.link].hightext);
StrAllocCopy(newdoc.bookmark, history[number].bookmark);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
if (history[number].post_data)
StrAllocCopy(newdoc.post_data,
history[number].post_data);
if (history[number].post_content_type)
StrAllocCopy(newdoc.post_content_type,
history[number].post_content_type);
newdoc.isHEAD = history[number].isHEAD;
newdoc.safe = history[number].safe;
newdoc.internal_link = FALSE;
newdoc.link = 0;
HTOutputFormat = HTAtom_for("www/download");
LYUserSpecifiedURL = TRUE;
/*
* Force the document to be reloaded.
*/
LYforce_no_cache = TRUE;
} else if (!strncmp(links[curdoc.link].lname, "data:", 5)) {
if (old_c != real_c) {
old_c = real_c;
HTAlert(UNSUPPORTED_DATA_URL);
}
} else if (!strncmp(links[curdoc.link].lname,
"LYNXCOOKIE:", 11) ||
!strncmp(links[curdoc.link].lname,
"LYNXDIRED:", 10) ||
!strncmp(links[curdoc.link].lname,
"LYNXDOWNLOAD:", 13) ||
!strncmp(links[curdoc.link].lname,
"LYNXPRINT:", 10) ||
!strncmp(links[curdoc.link].lname,
"lynxexec:", 9) ||
!strncmp(links[curdoc.link].lname,
"lynxprog:", 9)) {
_statusline(NO_DOWNLOAD_SPECIAL);
sleep(MessageSecs);
} else { /* Not a forms, options or history link */
/*
* Follow a normal link or anchor. Note that
* if it's an anchor within the same document,
* entire document will be downloaded.
*/
StrAllocCopy(newdoc.address, links[curdoc.link].lname);
StrAllocCopy(newdoc.title, links[curdoc.link].hightext);
newdoc.internal_link = FALSE;
/*
* Might be an anchor in the same doc from a POST
* form. If so, don't free the content. -- FM
*/
if (are_different(&curdoc, &newdoc)) {
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
}
newdoc.link = 0;
HTOutputFormat = HTAtom_for("www/download");
/*
* Force the document to be reloaded.
*/
LYforce_no_cache = TRUE;
}
} else if (old_c != real_c) {
old_c = real_c;
_statusline(NO_DOWNLOAD_CHOICE);
sleep(MessageSecs);
}
break;
#ifdef DIRED_SUPPORT
case LYK_UPLOAD:
/*
* Don't do if already viewing upload options page.
*/
if (!strcmp(curdoc.address, LYUploadFileURL) ||
!strcmp((curdoc.title ? curdoc.title : ""),
UPLOAD_OPTIONS_TITLE))
break;
if (lynx_edit_mode && !no_dired_support) {
LYUpload_options((char **)&newdoc.address,
(char *)curdoc.address);
StrAllocCopy(newdoc.title, UPLOAD_OPTIONS_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
/*
* Uncache the current listing so that it will
* be updated to included the uploaded file if
* placed in the current directory. - FM
*/
HTuncache_current_document();
}
break;
#endif /* DIRED_SUPPORT */
case LYK_TRACE_TOGGLE: /* Toggle TRACE mode. */
if (WWW_TraceFlag)
WWW_TraceFlag = FALSE;
else
WWW_TraceFlag = TRUE;
_statusline(WWW_TraceFlag ? TRACE_ON : TRACE_OFF);
sleep(MessageSecs);
if (TRACE && LYUseTraceLog && LYTraceLogFP == NULL) {
/*
* We haven't yet started a TRACE log for this
* session. If we can't open the file with write
* access, turn off TRACE and give up. Otherwise,
* on VMS we'll close it and delete it and any
* log file from a previous session, so they don't
* accumulate, and then open it again, including
* "shr=get" to overcome open file locking when
* attempting to read the log via the TRACE_LOG
* command. - FM
*/
if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
WWW_TraceFlag = FALSE;
_statusline(TRACELOG_OPEN_FAILED);
sleep(MessageSecs);
break;
}
#ifdef VMS
fclose(LYTraceLogFP);
while (remove(LYTraceLogPath) == 0)
;
if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
WWW_TraceFlag == FALSE;
_statusline(TRACELOG_OPEN_FAILED);
sleep(MessageSecs);
break;
}
#endif /* VMS */
*stderr = *LYTraceLogFP;
fprintf(stderr, "\t\t%s\n\n", LYNX_TRACELOG_TITLE);
}
break;
case LYK_TRACE_LOG: /* View TRACE log. */
/*
* Check whether we've started a TRACE log
* in this session. - FM
*/
if (LYTraceLogFP == NULL) {
_statusline(NO_TRACELOG_STARTED);
sleep(MessageSecs);
break;
}
/*
* Don't do if already viewing the TRACE log. - FM
*/
if (!strcmp((curdoc.title ? curdoc.title : ""),
LYNX_TRACELOG_TITLE))
break;
/*
* If TRACE mode is on, turn it off during this fetch of the
* TRACE log, so we don't enter stuff about this fetch, and
* set a flag for turning it back on when we return to this
* loop. Note that we'll miss any messages about memory
* exhaustion if it should occur. It seems unlikely that
* anything else bad might happen, but if it does, we'll
* miss messages about that too. We also fflush(), close,
* and open it again, to make sure all stderr messages thus
* far will be in the log. - FM
*/
if (TRACE)
fprintf(stderr, "\nTurning off TRACE for fetch of log.\n");
fflush(stderr);
fclose(LYTraceLogFP);
*stderr = LYOrigStderr;
if ((LYTraceLogFP = LYAppendToTxtFile(LYTraceLogPath)) == NULL) {
WWW_TraceFlag = FALSE;
_statusline(TRACELOG_OPEN_FAILED);
sleep(MessageSecs);
break;
}
*stderr = *LYTraceLogFP;
if (TRACE) {
WWW_TraceFlag = FALSE;
trace_mode_flag = TRUE;
}
StrAllocCopy(newdoc.address, "file://localhost");
#ifdef VMS
StrAllocCat(newdoc.address, HTVMS_wwwName(LYTraceLogPath));
#else
StrAllocCat(newdoc.address, LYTraceLogPath);
#endif /* VMS */
StrAllocCopy(newdoc.title, LYNX_TRACELOG_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
if (LYValidate || check_realm) {
LYPermitURL = TRUE;
}
LYforce_no_cache = TRUE;
break;
case LYK_IMAGE_TOGGLE:
if (clickable_images)
clickable_images = FALSE;
else
clickable_images = TRUE;
_statusline(clickable_images ?
CLICKABLE_IMAGES_ON : CLICKABLE_IMAGES_OFF);
sleep(MessageSecs);
cmd = LYK_RELOAD;
goto new_cmd;
break;
case LYK_INLINE_TOGGLE:
if (pseudo_inline_alts)
pseudo_inline_alts = FALSE;
else
pseudo_inline_alts = TRUE;
_statusline(pseudo_inline_alts ?
PSEUDO_INLINE_ALTS_ON : PSEUDO_INLINE_ALTS_OFF);
sleep(MessageSecs);
cmd = LYK_RELOAD;
goto new_cmd;
break;
case LYK_RAW_TOGGLE:
if (LYUseDefaultRawMode)
LYUseDefaultRawMode = FALSE;
else
LYUseDefaultRawMode = TRUE;
_statusline(LYRawMode ? RAWMODE_OFF : RAWMODE_ON);
HTMLSetCharacterHandling(current_char_set);
LYRawMode_flag = LYRawMode;
sleep(MessageSecs);
cmd = LYK_RELOAD;
goto new_cmd;
break;
case LYK_HEAD:
if (nlinks > 0 &&
(links[curdoc.link].type != WWW_FORM_LINK_TYPE ||
links[curdoc.link].form->type == F_SUBMIT_TYPE ||
links[curdoc.link].form->type == F_IMAGE_SUBMIT_TYPE)) {
/*
* We have links, and the current link is a
* normal link or a form's submit button. - FM
*/
_statusline(HEAD_D_L_OR_CANCEL);
c = LYgetch();
if (TOUPPER(c) == 'D') {
char *scheme = strncmp(curdoc.address, "LYNXIMGMAP:", 11) ?
curdoc.address : curdoc.address + 11;
if (strncmp(scheme, "http", 4)) {
_statusline(DOC_NOT_HTTP_URL);
sleep(MessageSecs);
} else {
/*
* Check if this is a reply from a POST,
* and if so, seek confirmation if the
* safe element is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_DOC_HEAD) == FALSE) {
_statusline(CANCELLED);
sleep(InfoSecs);
break;
}
HEAD_request = TRUE;
LYforce_no_cache = TRUE;
StrAllocCopy(newdoc.title, curdoc.title);
if (HTLoadedDocumentIsHEAD()) {
HTuncache_current_document();
FREE(curdoc.address);
} else {
StrAllocCat(newdoc.title, " - HEAD");
}
}
break;
} else if (TOUPPER(c) == 'L') {
if (links[curdoc.link].type != WWW_FORM_LINK_TYPE &&
strncmp(links[curdoc.link].lname, "http", 4) &&
strncmp(links[curdoc.link].lname,
"LYNXIMGMAP:http", 15) &&
(links[curdoc.link].type != WWW_INTERN_LINK_TYPE ||
!curdoc.address ||
strncmp(curdoc.address, "http", 4))) {
_statusline(LINK_NOT_HTTP_URL);
sleep(MessageSecs);
} else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
links[curdoc.link].form->disabled) {
_statusline(FORM_ACTION_DISABLED);
sleep(MessageSecs);
} else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
strncmp(links[curdoc.link].form->submit_action,
"http", 4)) {
_statusline(FORM_ACTION_NOT_HTTP_URL);
sleep(MessageSecs);
} else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
links[curdoc.link].form->submit_method ==
URL_POST_METHOD &&
HTConfirm(CONFIRM_POST_LINK_HEAD) == FALSE) {
_statusline(CANCELLED);
sleep(InfoSecs);
} else {
HEAD_request = TRUE;
LYforce_no_cache = TRUE;
StrAllocCopy(newdoc.title, links[curdoc.link].hightext);
StrAllocCat(newdoc.title, " - (HEAD)");
cmd = LYK_ACTIVATE;
goto new_cmd;
}
break;
}
break;
} else {
/*
* We can offer only this document for a HEAD request.
* Check if this is a reply from a POST, and if so,
* seek confirmation if the safe element is not set. - FM
*/
if ((curdoc.post_data != NULL &&
curdoc.safe != TRUE) &&
HTConfirm(CONFIRM_POST_DOC_HEAD) == FALSE) {
_statusline(CANCELLED);
sleep(InfoSecs);
break;
} else if (nlinks > 0) {
/*
* The current link is a non-submittable form
* link, so prompt the user to make it clear
* that the HEAD request would be for the
* current document, not the form link. - FM
*/
_statusline(HEAD_D_OR_CANCEL);
c = LYgetch();
} else {
/*
* No links, so we can just assume that
* the user wants a HEAD request for the
* current document. - FM
*/
c = 'D';
}
if (TOUPPER(c) == 'D') {
char *scheme = strncmp(curdoc.address, "LYNXIMGMAP:", 11) ?
curdoc.address : curdoc.address + 11;
/*
* The user didn't cancel, so check if
* a HEAD request is appropriate for the
* current document. - FM
*/
if (strncmp(scheme, "http", 4)) {
_statusline(DOC_NOT_HTTP_URL);
sleep(MessageSecs);
} else {
HEAD_request = TRUE;
LYforce_no_cache = TRUE;
StrAllocCopy(newdoc.title, curdoc.title);
if (HTLoadedDocumentIsHEAD()) {
HTuncache_current_document();
FREE(curdoc.address);
} else {
StrAllocCat(newdoc.title, " - HEAD");
}
}
}
}
break;
case LYK_TOGGLE_HELP:
if (user_mode == NOVICE_MODE) {
toggle_novice_line();
noviceline(more);
}
break;
case LYK_KEYMAP:
if (old_c != real_c) {
old_c = real_c;
StrAllocCopy(newdoc.address, "LYNXKEYMAP:");
StrAllocCopy(newdoc.title, CURRENT_KEYMAP_TITLE);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
/*
* If vi_keys changed, the keymap did too,
* so force no cache, and reset the flag. - FM
*/
if (vi_keys_flag != vi_keys ||
emacs_keys_flag != emacs_keys) {
LYforce_no_cache = TRUE;
vi_keys_flag = vi_keys;
emacs_keys_flag = emacs_keys;
}
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
/*
* Remember whether we are in dired menu
* so we can display the right keymap.
*/
if (!no_dired_support) {
prev_lynx_edit_mode = lynx_edit_mode;
}
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
LYforce_no_cache = TRUE;
}
break;
case LYK_JUMP:
{
char *ret;
if (no_jump || JThead == NULL) {
if (old_c != real_c) {
old_c = real_c;
if (no_jump)
_statusline(JUMP_DISALLOWED);
else
_statusline(NO_JUMPFILE);
sleep(MessageSecs);
}
} else {
LYJumpFileURL = TRUE;
if ((ret = LYJump(c)) != NULL) {
#ifdef PERMIT_GOTO_FROM_JUMP
if (!strncasecomp(ret, "Go ", 3)) {
LYJumpFileURL = FALSE;
StrAllocCopy(temp, user_input_buffer);
URLTotal = (Goto_URLs ?
HTList_count(Goto_URLs) : 0);
recall = ((URLTotal >= 1) ? RECALL : NORECALL);
URLNum = URLTotal;
FirstURLRecall = TRUE;
if (!strcasecomp(ret, "Go :")) {
if (recall) {
ch = UPARROW;
goto check_recall;
}
FREE(temp);
statusline(NO_RANDOM_URLS_YET);
sleep(MessageSecs);
break;
}
ret = HTParse((ret+3), startfile, PARSE_ALL);
strcpy(user_input_buffer, ret);
FREE(ret);
goto check_recall;
}
#endif /* PERMIT_GOTO_FROM_JUMP */
ret = HTParse(ret, startfile, PARSE_ALL);
LYTrimHead(ret);
if (!strncasecomp(ret, "lynxexec:", 9) ||
!strncasecomp(ret, "lynxprog:", 9)) {
/*
* The original implementions of these schemes
* expected white space without hex escaping,
* and did not check for hex escaping, so we'll
* continue to support that, until that code is
* redone in conformance with SGML principles.
* - FM
*/
HTUnEscapeSome(ret, " \r\n\t");
convert_to_spaces(ret, TRUE);
} else {
collapse_spaces(user_input_buffer);
}
StrAllocCopy(newdoc.address, ret);
StrAllocCopy(lynxjumpfile, ret);
FREE(newdoc.post_data);
FREE(newdoc.post_content_type);
FREE(newdoc.bookmark);
newdoc.isHEAD = FALSE;
newdoc.safe = FALSE;
newdoc.internal_link = FALSE;
FREE(ret);
LYUserSpecifiedURL = TRUE;
} else {
LYJumpFileURL = FALSE;
}
}
}
break;
#ifdef NOT_USED
case LYK_VERSION:
if (old_c != real_c) {
char version[128];
old_c = real_c;
sprintf(version, "*** %s Version %s ***",
LYNX_NAME, LYNX_VERSION);
statusline(version);
sleep(AlertMessage);
}
break;
#endif /* NOT_USED */
case LYK_DO_NOTHING: /* pretty self explanatory */
break;
} /* end of BIG switch */
}
}
PRIVATE int are_different ARGS2(
document *, doc1,
document *, doc2)
{
char *cp1, *cp2;
/*
* Do we have two addresses?
*/
if (!doc1->address || !doc2->address)
return (TRUE);
/*
* Do they differ in the type of request?
*/
if (doc1->isHEAD != doc2->isHEAD)
return (TRUE);
/*
* See if the addresses are different, making sure
* we're not tripped up by multiple anchors in the
* the same document from a POST form. -- FM
*/
if ((cp1 = strchr(doc1->address, '#')) != NULL)
*cp1 = '\0';
if ((cp2 = strchr(doc2->address, '#')) != NULL)
*cp2 = '\0';
/*
* Are the base addresses different?
*/
if (strcmp(doc1->address, doc2->address))
{
if (cp1)
*cp1 = '#';
if (cp2)
*cp2 = '#';
return(TRUE);
}
if (cp1)
*cp1 = '#';
if (cp2)
*cp2 = '#';
/*
* Do the docs have different contents?
*/
if (doc1->post_data)
{
if (doc2->post_data)
{
if (strcmp(doc1->post_data, doc2->post_data))
return(TRUE);
}
else
return(TRUE);
}
else
if (doc2->post_data)
return(TRUE);
/*
* We'll assume the two documents in fact are the same.
*/
return(FALSE);
}
/* This determines whether two docs are _physically_ different,
* meaning they are "from different files". - kw
*/
PRIVATE int are_phys_different ARGS2(
document *, doc1,
document *, doc2)
{
char *cp1, *cp2, *ap1 = doc1->address, *ap2 = doc2->address;
/*
* Do we have two addresses?
*/
if (!doc1->address || !doc2->address)
return (TRUE);
/*
* Do they differ in the type of request?
*/
if (doc1->isHEAD != doc2->isHEAD)
return (TRUE);
/*
* Skip over possible LYNXIMGMAP parts. - kw
*/
if (0==strncmp(doc1->address, "LYNXIMGMAP:", 11))
ap1 += 11;
if (0==strncmp(doc2->address, "LYNXIMGMAP:", 11))
ap2 += 11;
/*
* If there isn't any real URL in doc2->address, but maybe just
* a fragment, doc2 is assumed to be an internal reference in
* the same physical document, so return FALSE. - kw
*/
if (*ap2 == '\0' || *ap2 == '#')
return(FALSE);
/*
* See if the addresses are different, making sure
* we're not tripped up by multiple anchors in the
* the same document from a POST form. -- FM
*/
if ((cp1 = strchr(doc1->address, '#')) != NULL)
*cp1 = '\0';
if ((cp2 = strchr(doc2->address, '#')) != NULL)
*cp2 = '\0';
/*
* Are the base addresses different?
*/
if (strcmp(ap1, ap2))
{
if (cp1)
*cp1 = '#';
if (cp2)
*cp2 = '#';
return(TRUE);
}
if (cp1)
*cp1 = '#';
if (cp2)
*cp2 = '#';
/*
* Do the docs have different contents?
*/
if (doc1->post_data)
{
if (doc2->post_data)
{
if (strcmp(doc1->post_data, doc2->post_data))
return(TRUE);
}
else
return(TRUE);
}
else
if (doc2->post_data)
return(TRUE);
/*
* We'll assume the two documents in fact are the same.
*/
return(FALSE);
}
/*
* Utility for freeing the list of goto URLs. - FM
*/
PUBLIC void HTGotoURLs_free NOARGS
{
char *url;
HTList *cur = Goto_URLs;
if (!cur)
return;
while (NULL != (url = (char *)HTList_nextObject(cur))) {
FREE(url);
}
HTList_delete(Goto_URLs);
Goto_URLs = NULL;
return;
}
/*
* Utility for listing Goto URLs, making any
* repeated URLs the most current in the list. - FM
*/
PUBLIC void HTAddGotoURL ARGS1(
char *, url)
{
char *new;
char *old;
HTList *cur;
if (!(url && *url))
return;
if ((new = (char *)calloc(1, (strlen(url) + 1))) == NULL)
outofmem(__FILE__, "HTAddGotoURL");
strcpy(new, url);
if (!Goto_URLs) {
Goto_URLs = HTList_new();
atexit(HTGotoURLs_free);
HTList_addObject(Goto_URLs, new);
return;
}
cur = Goto_URLs;
while (NULL != (old = (char *)HTList_nextObject(cur))) {
if (!strcmp(old, new)) {
HTList_removeObject(Goto_URLs, old);
FREE(old);
break;
}
}
HTList_addObject(Goto_URLs, new);
return;
}