13
#include <LYGlobalDefs.h>
17
#include <LYStrings.h>
18
#include <LYOptions.h>
20
#include <LYGetFile.h>
24
#include <LYHistory.h>
28
#include <LYShowInfo.h>
29
#include <LYBookmark.h>
32
#include <LYDownload.h>
35
#include <LYTraversal.h>
36
#include <LYCharSets.h>
37
#include <LYCharUtils.h>
39
#include <LYMainLoop.h>
40
#include <LYPrettySrc.h>
42
#ifdef KANJI_CODE_OVERRIDE
46
#ifdef KANJI_CODE_OVERRIDE
47
PUBLIC char *str_kcode(HTkcode code)
52
if (current_char_set == TRANSPARENT) {
54
} else if (!LYRawMode) {
80
if (no_table_center) {
93
PRIVATE char *str_sjis(char *to, char *from)
97
#ifdef KANJI_CODE_OVERRIDE
98
} else if (last_kcode == EUC) {
99
EUC_TO_SJIS(from, to);
100
} else if (last_kcode == SJIS) {
109
PRIVATE void set_ws_title(char * str)
111
SetConsoleTitle(str);
117
#ifdef SH_EX /* 1998/10/30 (Fri) 10:06:47 */
121
PRIVATE int str_n_cmp(const char *p, const char *q, int n)
132
return strncmp(p, q, n);
136
#define strncmp(p, q, r) str_n_cmp(p, q, r)
140
#if defined(USE_EXTERNALS) || defined(WIN_EX)
141
#include <LYExtern.h>
150
#include <LYUpload.h>
151
#endif /* DIRED_SUPPORT */
157
PUBLIC HTLinkType * HTInternalLink = 0;
158
PUBLIC HTAtom * WWW_SOURCE = 0;
160
#ifndef DONT_TRACK_INTERNAL_LINKS
161
#define NO_INTERNAL_OR_DIFFERENT(c,n) TRUE
162
#define NONINTERNAL_OR_PHYS_DIFFERENT(p,n) (!curdoc.internal_link || \
163
are_phys_different(p,n))
164
#else /* TRACK_INTERNAL_LINKS */
165
#define NO_INTERNAL_OR_DIFFERENT(c,n) are_different(c,n)
166
#define NONINTERNAL_OR_PHYS_DIFFERENT(p,n) are_different(p,n)
167
#endif /* TRACK_INTERNAL_LINKS */
170
PRIVATE void exit_immediately_with_error_message PARAMS((int state, BOOLEAN first_file));
171
PRIVATE void status_link PARAMS((char *curlink_name, BOOLEAN show_more, BOOLEAN show_indx));
172
PRIVATE void show_main_statusline PARAMS((CONST LinkInfo curlink, int for_what));
173
PRIVATE void form_noviceline PARAMS((int));
174
PRIVATE int are_different PARAMS((DocInfo *doc1, DocInfo *doc2));
176
#ifndef DONT_TRACK_INTERNAL_LINKS
177
PRIVATE int are_phys_different PARAMS((DocInfo *doc1, DocInfo *doc2));
182
PRIVATE int sametext ARGS2(
187
return (strcmp(een, twee) == 0);
191
PUBLIC HTList * Goto_URLs = NULL; /* List of Goto URLs */
193
PUBLIC char * LYRequestTitle = NULL; /* newdoc.title in calls to getfile() */
194
PUBLIC char * LYRequestReferer = NULL; /* Referer, may be set in getfile() */
196
PRIVATE char prev_target[512];
199
PUBLIC BOOLEAN display_partial = FALSE; /* could be enabled in HText_new() */
200
PUBLIC int NumOfLines_partial = 0; /* number of lines displayed in partial mode */
203
PRIVATE int Newline = 0;
204
PRIVATE DocInfo newdoc;
205
PRIVATE DocInfo curdoc;
206
PRIVATE char *traversal_host = NULL;
207
PRIVATE char *traversal_link_to_add = NULL;
208
PRIVATE char *owner_address = NULL; /* Holds the responsible owner's address */
209
PRIVATE char *ownerS_address = NULL; /* Holds owner's address during source fetch */
211
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
212
PRIVATE BOOL textinput_activated = FALSE;
214
#define textinput_activated TRUE /* a current text input is always active */
216
#ifdef INACTIVE_INPUT_STYLE_VH
217
PUBLIC BOOL textinput_redrawn = FALSE;
218
/*must be public since used in LYhighlight(..)*/
223
* Function for freeing allocated mainloop() variables. - FM
225
PRIVATE void free_mainloop_variables NOARGS
227
LYFreeDocInfo(&newdoc);
228
LYFreeDocInfo(&curdoc);
230
#ifdef USE_COLOR_STYLE
234
FREE(traversal_host);
235
FREE(traversal_link_to_add);
237
FREE(ownerS_address);
241
#endif /* DIRED_SUPPORT */
242
FREE(WWW_Download_File); /* LYGetFile.c/HTFWriter.c */
243
FREE(LYRequestReferer);
247
#endif /* LY_FIND_LEAKS */
249
#ifndef NO_LYNX_TRACE
250
PRIVATE void TracelogOpenFailed NOARGS
252
WWW_TraceFlag = FALSE;
254
HTUserMsg(TRACELOG_OPEN_FAILED);
256
fprintf(stderr, "%s\n", TRACELOG_OPEN_FAILED);
261
PRIVATE BOOLEAN LYReopenTracelog ARGS1(BOOLEAN *, trace_flag_ptr)
263
CTRACE((tfp, "\nTurning off TRACE for fetch of log.\n"));
265
if ((LYTraceLogFP = LYAppendToTxtFile(LYTraceLogPath)) == NULL) {
266
TracelogOpenFailed();
270
WWW_TraceFlag = FALSE;
271
*trace_flag_ptr = TRUE;
276
PRIVATE void turn_trace_back_on ARGS1(BOOLEAN *, trace_flag_ptr)
278
if (*trace_flag_ptr == TRUE) {
279
WWW_TraceFlag = TRUE;
280
*trace_flag_ptr = FALSE;
281
fprintf(tfp, "Turning TRACE back on.\n\n");
285
#define LYReopenTracelog(flag) TRUE
286
#define turn_trace_back_on(flag) /*nothing*/
287
#endif /* NO_LYNX_TRACE */
289
PUBLIC FILE *TraceFP NOARGS
291
#ifndef NO_LYNX_TRACE
292
if (LYTraceLogFP != 0) {
295
#endif /* NO_LYNX_TRACE */
299
PUBLIC BOOLEAN LYOpenTraceLog NOARGS
301
#ifndef NO_LYNX_TRACE
302
if (TRACE && LYUseTraceLog && LYTraceLogFP == NULL) {
304
* If we can't open it for writing, give up. Otherwise, on VMS close
305
* it, delete it and any versions from previous sessions so they don't
306
* accumulate, and open it again. - FM
308
if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
309
TracelogOpenFailed();
314
HTSYS_remove(LYTraceLogPath);
315
if ((LYTraceLogFP = LYNewTxtFile(LYTraceLogPath)) == NULL) {
316
TracelogOpenFailed();
322
fprintf(tfp, "\t\t%s (%s)\n\n", LYNX_TRACELOG_TITLE, LYNX_VERSION);
324
* If TRACE is on, indicate whether the
325
* anonymous restrictions are set. - FM, LP, kw
326
* This is only a summary for convenience - it doesn't
327
* take the case of individual -restrictions= options
331
if (LYRestricted && had_restrictions_default) {
332
CTRACE((tfp, "Validate and some anonymous restrictions are set.\n"));
333
} else if (had_restrictions_default) {
334
CTRACE((tfp, "Validate restrictions set, restriction \"default\" was given.\n"));
335
} else if (LYRestricted) {
336
CTRACE((tfp, "Validate restrictions set, additional anonymous restrictions ignored.\n"));
338
CTRACE((tfp, "Validate restrictions are set.\n"));
340
/* But none of the above can actually happen, since there should
341
* never be a Trace Log with -validate. If it appears in a log
342
* file something went wrong! */
343
} else if (LYRestricted) {
344
if (had_restrictions_all) {
345
CTRACE((tfp, "Anonymous restrictions set, restriction \"all\" was given.\n"));
347
CTRACE((tfp, "Anonymous restrictions are set.\n"));
349
} else if (had_restrictions_all && had_restrictions_default) {
350
CTRACE((tfp, "Restrictions \"all\" and \"default\" were given.\n"));
351
} else if (had_restrictions_default) {
352
CTRACE((tfp, "Restriction \"default\" was given.\n"));
353
} else if (had_restrictions_all) {
354
CTRACE((tfp, "\"all\" restrictions are set.\n"));
357
#endif /* NO_LYNX_TRACE */
361
PUBLIC void LYCloseTracelog NOARGS
363
#ifndef NO_LYNX_TRACE
364
if (LYTraceLogFP != 0) {
367
fclose(LYTraceLogFP);
370
#endif /* NO_LYNX_TRACE */
373
PUBLIC void handle_LYK_TRACE_TOGGLE NOARGS
375
#ifndef NO_LYNX_TRACE
376
WWW_TraceFlag = ! WWW_TraceFlag;
377
if (LYOpenTraceLog())
378
HTUserMsg(WWW_TraceFlag ? TRACE_ON : TRACE_OFF);
380
HTUserMsg(TRACE_DISABLED);
381
#endif /* NO_LYNX_TRACE */
384
PUBLIC void LYSetNewline ARGS1(
390
PUBLIC int LYGetNewline NOARGS
395
#ifdef USE_SOURCE_CACHE
396
PRIVATE BOOLEAN from_source_cache = FALSE;
399
* Like HTreparse_document(), but also set the flag.
401
PRIVATE BOOLEAN reparse_document NOARGS
404
from_source_cache = TRUE; /* set for LYMainLoop_pageDisplay() */
405
if ((ok = HTreparse_document()) != FALSE) {
406
from_source_cache = TRUE; /* set for mainloop refresh */
409
from_source_cache = FALSE;
412
#endif /* USE_SOURCE_CACHE */
415
* Prefer reparsing if we can, but reload if we must - to force regeneration
418
PRIVATE BOOLEAN reparse_or_reload ARGS1(
421
#ifdef USE_SOURCE_CACHE
422
if (reparse_document()) {
431
* Functions for setting the current address
433
PRIVATE void set_address ARGS2(
435
CONST char *, address)
437
StrAllocCopy(doc->address, address);
440
PRIVATE void copy_address ARGS2(
444
StrAllocCopy(dst->address, src->address);
447
PRIVATE void free_address ARGS1(
453
PRIVATE void move_address ARGS2(
457
copy_address(dst, src);
463
* This is for traversal call from within partial mode in LYUtils.c
464
* and HTFormat.c It simply calls HText_pageDisplay() but utilizes
465
* LYMainLoop.c PRIVATE variables to manage proper newline position
466
* in case of #fragment
468
PUBLIC BOOL LYMainLoop_pageDisplay ARGS1(
472
int prev_newline = Newline;
475
* Override Newline with a new value if user
476
* scrolled the document while loading (in LYUtils.c).
480
#ifdef USE_SOURCE_CACHE
482
* reparse_document() acts on 'curdoc' which always on top of the
483
* history stack: no need to resolve #fragment position since
484
* we already know it (curdoc.line).
485
* So bypass here. Sorry for possible confusion...
487
if (!from_source_cache)
490
* If the requested URL has the #fragment, and we are not popped
491
* from the history stack, and have not scrolled the document yet -
492
* we should calculate correct newline position for the fragment.
493
* (This is a bit suboptimal since HTFindPoundSelector() traverse
494
* anchors list each time, so we have a quadratic complexity
495
* and may load CPU in a worst case).
498
&& newdoc.line == 1 && line_num == 1 && prev_newline == 1
499
&& (pound = findPoundSelector(newdoc.address))
500
&& *pound && *(pound+1)) {
501
if (HTFindPoundSelector(pound+1)) {
502
/* HTFindPoundSelector will initialize www_search_result */
503
Newline = www_search_result;
505
Newline = prev_newline; /* restore ??? */
506
return NO; /* no repaint */
510
HText_pageDisplay(Newline, prev_target);
513
#endif /* DISP_PARTIAL */
516
PRIVATE void set_curdoc_link ARGS1(
519
if (curdoc.link != nextlink
521
&& nextlink < nlinks) {
522
if (curdoc.link >= 0 && curdoc.link < nlinks)
523
LYhighlight(OFF, curdoc.link, prev_target);
524
curdoc.link = nextlink;
528
PRIVATE int do_change_link NOARGS
531
/* Is there a mouse-clicked link waiting? */
532
int mouse_tmp = get_mouse_link();
533
/* If yes, use it as the link */
534
if (mouse_tmp != -1) {
535
if (mouse_tmp < 0 || mouse_tmp >= nlinks) {
538
gettext("Internal error: Invalid mouse link %d!"),
542
return(-1); /* indicates unexpected error */
544
set_curdoc_link(mouse_tmp);
546
#endif /* USE_MOUSE */
547
return(0); /* indicates OK */
551
#define DIRED_UNCACHE_1 if (LYAutoUncacheDirLists < 1) /*nothing*/ ;\
552
else HTuncache_current_document()
553
#define DIRED_UNCACHE_2 if (LYAutoUncacheDirLists < 2) /*nothing*/ ;\
554
else HTuncache_current_document()
555
#endif /* DIRED_SUPPORT */
557
PRIVATE void do_check_goto_URL ARGS3(
558
char *, user_input_buffer,
559
char **, old_user_input,
560
BOOLEAN *, force_load)
562
static BOOLEAN always = TRUE;
567
{ STR_FILE_URL, &no_file_url },
568
{ STR_FILE_URL, &no_goto_file },
569
{ STR_LYNXEXEC, &no_goto_lynxexec },
570
{ STR_LYNXPROG, &no_goto_lynxprog },
571
{ STR_LYNXCGI, &no_goto_lynxcgi },
572
{ STR_CSO_URL, &no_goto_cso },
573
{ STR_FINGER_URL, &no_goto_finger },
574
{ STR_FTP_URL, &no_goto_ftp },
575
{ STR_GOPHER_URL, &no_goto_gopher },
576
{ STR_HTTP_URL, &no_goto_http },
577
{ STR_HTTPS_URL, &no_goto_https },
578
{ STR_MAILTO_URL, &no_goto_mailto },
579
{ STR_RLOGIN_URL, &no_goto_rlogin },
580
{ STR_TELNET_URL, &no_goto_telnet },
581
{ STR_TN3270_URL, &no_goto_tn3270 },
582
{ STR_WAIS_URL, &no_goto_wais },
584
{ STR_BIBP_URL, &no_goto_bibp },
587
{ STR_NEWS_URL, &no_goto_news },
588
{ STR_NNTP_URL, &no_goto_nntp },
589
{ STR_SNEWS_URL, &no_goto_snews },
592
{ STR_LYNXEXEC, &local_exec_on_local_files },
593
{ STR_LYNXPROG, &local_exec_on_local_files },
594
#endif /* EXEC_LINKS */
595
{ STR_LYNXCFG, &no_goto_configinfo },
596
{ STR_LYNXCFLAGS, &no_goto_configinfo },
597
{ STR_LYNXCOOKIE, &always },
598
{ STR_LYNXDIRED, &always },
599
{ STR_LYNXDOWNLOAD, &always },
600
{ STR_LYNXOPTIONS, &always },
601
{ STR_LYNXPRINT, &always },
604
BOOLEAN found = FALSE;
606
/* allow going to anchors*/
607
if (*user_input_buffer == '#' ) {
608
if ( user_input_buffer[1] &&
609
HTFindPoundSelector(user_input_buffer+1) ) {
610
/* HTFindPoundSelector will initialize www_search_result,
611
so we do nothing else. */
612
HTAddGotoURL(user_input_buffer);
613
trimPoundSelector(curdoc.address);
614
StrAllocCat(curdoc.address, user_input_buffer);
618
* If it's not a URL then make it one.
620
StrAllocCopy(*old_user_input, user_input_buffer);
621
LYEnsureAbsoluteURL(old_user_input, "", TRUE);
622
sprintf(user_input_buffer, "%.*s",
623
(int)(MAX_LINE - 1), *old_user_input);
624
FREE(*old_user_input);
626
for (n = 0; n < TABLESIZE(table); n++) {
628
&& !strncmp(user_input_buffer, table[n].name, strlen(table[n].name))) {
630
HTUserMsg2(GOTO_XXXX_DISALLOWED, table[n].name);
636
} else if (LYValidate &&
637
!isHTTP_URL(user_input_buffer) &&
638
!isHTTPS_URL(user_input_buffer)) {
639
HTUserMsg(GOTO_NON_HTTP_DISALLOWED);
642
set_address(&newdoc, user_input_buffer);
643
newdoc.isHEAD = FALSE;
645
* Might be an anchor in the same doc from a POST
646
* form. If so, dont't free the content. -- FM
648
if (are_different(&curdoc, &newdoc)) {
650
* Make a name for this new URL.
652
StrAllocCopy(newdoc.title, gettext("A URL specified by the user"));
653
LYFreePostData(&newdoc);
654
FREE(newdoc.bookmark);
656
newdoc.internal_link = FALSE;
659
if (lynx_edit_mode) {
662
#endif /* DIRED_SUPPORT */
664
LYUserSpecifiedURL = TRUE;
665
HTAddGotoURL(newdoc.address);
670
/* returns FALSE if user cancelled input or URL was invalid, TRUE otherwise */
671
PRIVATE BOOL do_check_recall ARGS7(
673
char *, user_input_buffer,
674
char **, old_user_input,
678
BOOLEAN *, FirstURLRecall)
683
if (*old_user_input == 0)
684
StrAllocCopy(*old_user_input, "");
687
#ifdef WIN_EX /* 1998/10/11 (Sun) 10:41:05 */
688
int len = strlen(user_input_buffer);
691
if (len < MAX_LINE - 1
692
&& LYIsHtmlSep(user_input_buffer[len - 3])
693
&& LYIsDosDrive(user_input_buffer + len - 2))
694
LYAddPathSep0(user_input_buffer);
696
} else if (len == 2 && user_input_buffer[1] == ':') {
697
if (LYIsDosDrive(user_input_buffer)) {
698
LYAddPathSep0(user_input_buffer);
700
HTUserMsg2(WWW_ILLEGAL_URL_MESSAGE, user_input_buffer);
701
LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
702
FREE(*old_user_input);
709
* Get rid of leading spaces (and any other spaces).
711
LYTrimAllStartfile(user_input_buffer);
712
if (*user_input_buffer == '\0' &&
713
!(recall && (ch == UPARROW || ch == DNARROW))) {
714
LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
715
FREE(*old_user_input);
716
HTInfoMsg(CANCELLED);
720
if (recall && ch == UPARROW) {
721
if (*FirstURLRecall) {
723
* Use last URL in the list. - FM
725
*FirstURLRecall = FALSE;
729
* Go back to the previous URL in the list. - FM
733
if (*URLNum >= URLTotal)
735
* Roll around to the last URL in the list. - FM
738
if ((cp = (char *)HTList_objectAt(Goto_URLs,
740
LYstrncpy(user_input_buffer, cp, MAX_LINE - 1);
743
&& !strcmp(*old_user_input, user_input_buffer)) {
744
_statusline(EDIT_CURRENT_GOTO);
745
} else if ((goto_buffer && URLTotal == 2) ||
746
(!goto_buffer && URLTotal == 1)) {
747
_statusline(EDIT_THE_PREV_GOTO);
749
_statusline(EDIT_A_PREV_GOTO);
751
if ((ch = LYgetstr(user_input_buffer, VISIBLE,
755
* User cancelled the Goto via ^G.
756
* Restore user_input_buffer and break. - FM
758
LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
759
FREE(*old_user_input);
760
HTInfoMsg(CANCELLED);
766
} else if (recall && ch == DNARROW) {
767
if (*FirstURLRecall) {
769
* Use the first URL in the list. - FM
771
*FirstURLRecall = FALSE;
772
*URLNum = URLTotal - 1;
775
* Advance to the next URL in the list. - FM
781
* Roll around to the first URL in the list. - FM
783
*URLNum = URLTotal - 1;
784
if ((cp=(char *)HTList_objectAt(Goto_URLs, *URLNum)) != NULL) {
785
LYstrncpy(user_input_buffer, cp, MAX_LINE - 1);
786
if (goto_buffer && **old_user_input &&
787
!strcmp(*old_user_input, user_input_buffer)) {
788
_statusline(EDIT_CURRENT_GOTO);
789
} else if ((goto_buffer && URLTotal == 2) ||
790
(!goto_buffer && URLTotal == 1)) {
791
_statusline(EDIT_THE_PREV_GOTO);
793
_statusline(EDIT_A_PREV_GOTO);
795
if ((ch = LYgetstr(user_input_buffer, VISIBLE,
799
* User cancelled the Goto via ^G.
800
* Restore user_input_buffer and break. - FM
802
LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
803
FREE(*old_user_input);
804
HTInfoMsg(CANCELLED);
818
PRIVATE void do_cleanup_after_delete NOARGS
820
HTuncache_current_document();
821
move_address(&newdoc, &curdoc);
822
newdoc.line = curdoc.line;
823
if (curdoc.link == nlinks-1) {
825
* We deleted the last link on the page. - FM
827
newdoc.link = curdoc.link-1;
829
newdoc.link = curdoc.link;
833
PRIVATE int find_link_near_col ARGS2(
839
for (i = curdoc.link; delta > 0 ? (i < nlinks) : (i >= 0); i += delta) {
840
if ( (links[i].ly - links[curdoc.link].ly) * delta > 0 ) {
841
int cy = links[i].ly, best = -1, dist = 1000000;
843
while ((delta > 0 ? (i < nlinks) : (i >= 0)) && cy == links[i].ly) {
844
int cx = links[i].lx;
845
char *text = LYGetHiliteStr(i, 0);
848
cx += strlen(text) / 2;
865
* This is a special feature to traverse every http link derived from startfile
866
* and check for errors or create crawl output files. Only URL's that begin
867
* with "traversal_host" are searched - this keeps the search from crossing to
868
* other servers (a feature, not a bug!).
870
PRIVATE int DoTraversal ARGS2(
874
BOOLEAN rlink_rejected = FALSE;
875
BOOLEAN rlink_exists;
876
BOOLEAN rlink_allowed;
878
rlink_exists = (BOOL) (nlinks > 0 &&
879
links[curdoc.link].type != WWW_FORM_LINK_TYPE &&
880
links[curdoc.link].lname != NULL);
883
rlink_rejected = lookup_reject(links[curdoc.link].lname);
884
if (!rlink_rejected &&
886
links[curdoc.link].lname) {
887
if (!isLYNXIMGMAP(links[curdoc.link].lname)) {
888
rlink_allowed = (BOOL) !strncmp(traversal_host,
889
links[curdoc.link].lname,
890
strlen(traversal_host));
892
rlink_allowed = (BOOL) !strncmp(traversal_host,
893
links[curdoc.link].lname + LEN_LYNXIMGMAP,
894
strlen(traversal_host));
897
rlink_allowed = FALSE;
900
rlink_allowed = FALSE;
902
if (rlink_exists && rlink_allowed) {
903
if (lookup(links[curdoc.link].lname)) {
905
(curdoc.link > -1 && curdoc.link < nlinks -1))
908
if (STREQ(curdoc.title,"Entry into main screen") ||
910
if (!dump_output_immediately) {
912
exit_immediately(EXIT_FAILURE);
919
StrAllocCopy(traversal_link_to_add,
920
links[curdoc.link].lname);
921
if (!isLYNXIMGMAP(traversal_link_to_add))
925
} else { /* no good right link, so only down and left arrow ok*/
926
if (rlink_exists /* && !rlink_rejected */)
927
/* uncomment in previous line to avoid duplicates - kw */
928
add_to_reject_list(links[curdoc.link].lname);
930
(curdoc.link > -1 && curdoc.link < nlinks-1))
934
* curdoc.title doesn't always work, so
935
* bail out if the history list is empty.
937
if (STREQ(curdoc.title,"Entry into main screen") ||
939
if (!dump_output_immediately) {
941
exit_immediately(EXIT_FAILURE);
947
} /* right link not NULL or link to another site*/
951
#ifndef DONT_TRACK_INTERNAL_LINKS
952
PRIVATE BOOLEAN check_history NOARGS
956
if (!curdoc.post_data)
958
* Normal case - List Page is not associated
959
* with post data. - kw
965
&& HDOC(nhist - 1).post_data
966
&& BINEQ(curdoc.post_data, HDOC(nhist - 1).post_data)
967
&& (base = HText_getContentBase()) != 0) {
968
char *text = !isLYNXIMGMAP(HDOC(nhist - 1).address)
969
? HDOC(nhist - 1).address
970
: HDOC(nhist - 1).address + LEN_LYNXIMGMAP;
971
if (!strncmp(base, text, strlen(base))) {
973
* Normal case - as best as we can check, the document at the top
974
* of the history stack seems to be the document the List Page is
975
* about (or a LYNXIMGMAP derived from it), and LYresubmit_posts is
976
* not set, so don't prompt here. If we actually have to repeat a
977
* POST because, against expectations, the underlying document
978
* isn't cached any more, HTAccess will prompt for confirmation,
979
* unless we had LYK_NOCACHE -kw
988
PRIVATE int handle_LYK_ACTIVATE ARGS6(
991
BOOLEAN *, try_internal GCC_UNUSED,
992
BOOLEAN *, refresh_screen,
993
BOOLEAN *, force_load,
996
if (do_change_link() == -1) {
997
LYforce_no_cache = FALSE;
999
return 1; /* mouse stuff was confused, ignore - kw */
1002
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE) {
1003
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
1004
if (real_cmd == LYK_ACTIVATE && textfields_need_activation &&
1005
F_TEXTLIKE(links[curdoc.link].l_form->type)) {
1007
textinput_activated = TRUE;
1008
show_main_statusline(links[curdoc.link], FOR_INPUT);
1009
textfields_need_activation = textfields_activation_option;
1015
* Don't try to submit forms with bad actions. - FM
1017
if (links[curdoc.link].l_form->type == F_SUBMIT_TYPE ||
1018
links[curdoc.link].l_form->type == F_IMAGE_SUBMIT_TYPE ||
1019
links[curdoc.link].l_form->type ==
1020
F_TEXT_SUBMIT_TYPE) {
1022
* Do nothing if it's disabled. - FM
1024
if (links[curdoc.link].l_form->disabled == YES) {
1025
HTOutputFormat = WWW_PRESENT;
1026
LYforce_no_cache = FALSE;
1031
* Make sure we have an action. - FM
1033
if (!links[curdoc.link].l_form->submit_action ||
1034
*links[curdoc.link].l_form->submit_action
1036
HTUserMsg(NO_FORM_ACTION);
1037
HTOutputFormat = WWW_PRESENT;
1038
LYforce_no_cache = FALSE;
1043
* Check for no_mail if the form action
1044
* is a mailto URL. - FM
1046
if (links[curdoc.link].l_form->submit_method
1047
== URL_MAIL_METHOD && no_mail) {
1048
HTAlert(FORM_MAILTO_DISALLOWED);
1049
HTOutputFormat = WWW_PRESENT;
1050
LYforce_no_cache = FALSE;
1055
* Make sure this isn't a spoof in an account
1056
* with restrictions on file URLs. - FM
1059
isFILE_URL(links[curdoc.link].l_form->submit_action)) {
1060
HTAlert(FILE_ACTIONS_DISALLOWED);
1061
HTOutputFormat = WWW_PRESENT;
1062
LYforce_no_cache = FALSE;
1067
* Make sure this isn't a spoof attempt
1068
* via an internal URL. - FM
1070
if (isLYNXCOOKIE(links[curdoc.link].l_form->submit_action) ||
1071
#ifdef DIRED_SUPPORT
1073
(isLYNXDIRED(links[curdoc.link].l_form->submit_action) &&
1074
(no_dired_support ||
1076
(links[curdoc.link].l_form->submit_action + 10),
1077
"//PERMIT_LOCATION", 17) ||
1078
!LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS))) ||
1080
isLYNXDIRED(links[curdoc.link].l_form->submit_action) ||
1081
#endif /* OK_PERMIT */
1082
#endif /* DIRED_SUPPORT */
1083
isLYNXDOWNLOAD(links[curdoc.link].l_form->submit_action) ||
1084
isLYNXHIST(links[curdoc.link].l_form->submit_action) ||
1085
isLYNXKEYMAP(links[curdoc.link].l_form->submit_action) ||
1086
isLYNXIMGMAP(links[curdoc.link].l_form->submit_action) ||
1087
isLYNXPRINT(links[curdoc.link].l_form->submit_action) ||
1088
isLYNXEXEC(links[curdoc.link].l_form->submit_action) ||
1089
isLYNXPROG(links[curdoc.link].l_form->submit_action)) {
1091
HTAlert(SPECIAL_ACTION_DISALLOWED);
1092
CTRACE((tfp, "LYMainLoop: Rejected '%s'\n",
1093
links[curdoc.link].l_form->submit_action));
1094
HTOutputFormat = WWW_PRESENT;
1095
LYforce_no_cache = FALSE;
1099
#ifdef NOTDEFINED /* We're disabling form inputs instead of using this. - FM */
1101
* Check for enctype and let user know we
1102
* don't yet support multipart/form-data - FM
1104
if (links[curdoc.link].l_form->submit_enctype) {
1106
links[curdoc.link].l_form->submit_enctype,
1107
"multipart/form-data")) {
1109
gettext("Enctype multipart/form-data not yet supported! Cannot submit."));
1110
HTOutputFormat = WWW_PRESENT;
1111
LYforce_no_cache = FALSE;
1116
#endif /* NOTDEFINED */
1120
if (no_filereferer == TRUE && isFILE_URL(curdoc.address)) {
1121
LYNoRefererForThis = TRUE;
1123
if (links[curdoc.link].l_form->submit_method != URL_MAIL_METHOD) {
1124
StrAllocCopy(newdoc.title,
1125
LYGetHiliteStr(curdoc.link, 0));
1130
* Normally we don't get here for text input fields,
1131
* but it can happen as a result of mouse positioning.
1132
* In that case the statusline will not have updated
1133
* info, so update it now. - kw
1135
if (F_TEXTLIKE(links[curdoc.link].l_form->type)) {
1136
show_formlink_statusline(links[curdoc.link].l_form,
1137
(real_cmd == LYK_NOCACHE ||
1138
real_cmd == LYK_DOWNLOAD ||
1139
real_cmd == LYK_HEAD ||
1140
(real_cmd == LYK_SUBMIT &&
1141
!textinput_activated)) ?
1142
FOR_PANEL : FOR_INPUT);
1143
if (user_mode == NOVICE_MODE &&
1144
textinput_activated &&
1145
(real_cmd == LYK_ACTIVATE || real_cmd == LYK_SUBMIT)) {
1146
form_noviceline(links[curdoc.link].l_form->disabled);
1150
*c = change_form_link(curdoc.link,
1151
&newdoc, refresh_screen,
1153
(BOOLEAN)(real_cmd == LYK_SUBMIT ||
1154
real_cmd == LYK_NOCACHE ||
1155
real_cmd == LYK_DOWNLOAD ||
1156
real_cmd == LYK_HEAD));
1157
if (*c != LKC_DONE || *refresh_screen) {
1159
* Cannot have been a submit field for which
1160
* newdoc was filled in. - kw
1162
if ((links[curdoc.link].l_form->type == F_SUBMIT_TYPE ||
1163
links[curdoc.link].l_form->type == F_IMAGE_SUBMIT_TYPE ||
1164
links[curdoc.link].l_form->type == F_TEXT_SUBMIT_TYPE) &&
1165
links[curdoc.link].l_form->submit_method
1166
!= URL_MAIL_METHOD) {
1168
* Try to undo change of newdoc.title done above.
1170
if (HText_getTitle()) {
1171
StrAllocCopy(newdoc.title, HText_getTitle());
1172
} else if (curdoc.title) {
1173
StrAllocCopy(newdoc.title, curdoc.title);
1177
if (HTOutputFormat == HTAtom_for("www/download") &&
1178
newdoc.post_data != NULL &&
1179
newdoc.safe == FALSE) {
1181
if ((HText_POSTReplyLoaded(&newdoc) == TRUE) &&
1182
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
1183
HTInfoMsg(CANCELLED);
1184
HTOutputFormat = WWW_PRESENT;
1185
LYforce_no_cache = FALSE;
1186
copy_address(&newdoc, &curdoc);
1187
StrAllocCopy(newdoc.title, curdoc.title);
1188
BStrCopy(newdoc.post_data, curdoc.post_data);
1189
StrAllocCopy(newdoc.post_content_type,
1190
curdoc.post_content_type);
1191
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
1192
newdoc.isHEAD = curdoc.isHEAD;
1193
newdoc.safe = curdoc.safe;
1194
newdoc.internal_link = curdoc.internal_link;
1199
* Moved here from earlier to only apply when it
1200
* should. Anyway, why should realm checking be
1201
* overridden for form submissions, this seems to
1202
* be an unnecessary loophole?? But that's the way
1203
* it was, maybe there is some reason.
1204
* However, at least make sure this doesn't weaken
1205
* restrictions implied by -validate!
1208
if (check_realm && !LYValidate) {
1212
if (*c == LKC_DONE) {
1214
} else if (*c == 23) {
1216
*refresh_screen = TRUE;
1218
/* Avoid getting stuck with repeatedly calling
1219
** handle_LYK_ACTIVATE(), instead of calling
1220
** change_form_link() directly from mainloop(),
1221
** for text input fields. - kw
1223
switch (LKC_TO_C(*c)) {
1227
if ((real_cmd == LYK_ACTIVATE || real_cmd == LYK_SUBMIT) &&
1228
F_TEXTLIKE(links[curdoc.link].l_form->type) &&
1229
textinput_activated)
1239
* Make sure this isn't a spoof in an account
1240
* with restrictions on file URLs. - FM
1242
if (no_file_url && isFILE_URL(links[curdoc.link].lname)) {
1243
if (!isFILE_URL(curdoc.address) &&
1244
!((isLYNXKEYMAP(curdoc.address) ||
1245
isLYNXCOOKIE(curdoc.address)) &&
1246
!strncmp(links[curdoc.link].lname,
1248
strlen(helpfilepath)))) {
1249
HTAlert(FILE_SERVED_LINKS_DISALLOWED);
1252
} else if (curdoc.bookmark != NULL) {
1253
HTAlert(FILE_BOOKMARKS_DISALLOWED);
1259
* Make sure this isn't a spoof attempt
1260
* via an internal URL in a non-internal
1263
if ((isLYNXCOOKIE(links[curdoc.link].lname) &&
1264
(strcmp(NonNull(curdoc.title), COOKIE_JAR_TITLE) ||
1265
!isLYNXCOOKIE(curdoc.address))) ||
1266
#ifdef DIRED_SUPPORT
1267
(isLYNXDIRED(links[curdoc.link].lname) &&
1268
!LYIsUIPage(curdoc.address, UIP_DIRED_MENU) &&
1269
!LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS) &&
1271
!LYIsUIPage(curdoc.address, UIP_INSTALL) &&
1272
#endif /* OK_INSTALL */
1273
!LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS)) ||
1274
#endif /* DIRED_SUPPORT */
1275
(isLYNXDOWNLOAD(links[curdoc.link].lname) &&
1276
!LYIsUIPage(curdoc.address, UIP_DOWNLOAD_OPTIONS)) ||
1277
(isLYNXHIST(links[curdoc.link].lname) &&
1278
!LYIsUIPage(curdoc.address, UIP_HISTORY) &&
1279
!LYIsUIPage(curdoc.address, UIP_LIST_PAGE) &&
1280
!LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE)) ||
1281
(isLYNXPRINT(links[curdoc.link].lname) &&
1282
!LYIsUIPage(curdoc.address, UIP_PRINT_OPTIONS))) {
1283
HTAlert(SPECIAL_VIA_EXTERNAL_DISALLOWED);
1284
HTOutputFormat = WWW_PRESENT;
1285
LYforce_no_cache = FALSE;
1290
#ifdef USE_EXTERNALS
1291
if (run_external(links[curdoc.link].lname, TRUE))
1293
*refresh_screen = TRUE;
1296
#endif /* USE_EXTERNALS */
1299
* Follow a normal link or anchor.
1301
set_address(&newdoc, links[curdoc.link].lname);
1302
StrAllocCopy(newdoc.title, LYGetHiliteStr(curdoc.link, 0));
1303
#ifndef DONT_TRACK_INTERNAL_LINKS
1305
* For internal links, retain POST content if present.
1306
* If we are on the List Page, prevent pushing it on
1307
* the history stack. Otherwise set try_internal to
1308
* signal that the top of the loop should attempt to
1309
* reposition directly, without calling getfile. - kw
1312
* Might be an internal link anchor in the same doc.
1313
* If so, take the try_internal shortcut if we didn't
1314
* fall through from LYK_NOCACHE. - kw
1316
newdoc.internal_link =
1317
(links[curdoc.link].type == WWW_INTERN_LINK_TYPE);
1318
if (newdoc.internal_link) {
1320
* Special case of List Page document with an
1321
* internal link indication, which may really stand
1322
* for an internal link within the document the
1323
* List Page is about. - kw
1325
if (LYIsListpageTitle(NonNull(curdoc.title)) &&
1326
(LYIsUIPage(curdoc.address, UIP_LIST_PAGE) ||
1327
LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE))) {
1328
if (check_history()) {
1329
LYinternal_flag = TRUE;
1331
HTLastConfirmCancelled(); /* reset flag */
1332
if (!confirm_post_resub(newdoc.address,
1334
(LYresubmit_posts &&
1335
HText_POSTReplyLoaded(&newdoc)) ? 1 : 2,
1337
if (HTLastConfirmCancelled() ||
1338
(LYresubmit_posts &&
1339
cmd != LYK_NOCACHE &&
1340
!HText_POSTReplyLoaded(&newdoc))) {
1341
/* cancel the whole thing */
1342
LYforce_no_cache = FALSE;
1344
copy_address(&newdoc, &curdoc);
1345
StrAllocCopy(newdoc.title, curdoc.title);
1346
newdoc.internal_link = curdoc.internal_link;
1347
HTInfoMsg(CANCELLED);
1349
} else if (LYresubmit_posts &&
1350
cmd != LYK_NOCACHE) {
1351
/* If LYresubmit_posts is set, and the
1352
answer was No, and the key wasn't
1353
NOCACHE, and we have a cached copy,
1354
then use it. - kw */
1355
LYforce_no_cache = FALSE;
1357
/* if No, but not ^C or ^G, drop
1358
* the post data. Maybe the link
1359
* wasn't meant to be internal after
1360
* all, here we can recover from that
1361
* assumption. - kw */
1362
LYFreePostData(&newdoc);
1363
newdoc.internal_link = FALSE;
1364
HTAlert(DISCARDING_POST_DATA);
1369
* Don't push the List Page if we follow an
1370
* internal link given by it. - kw
1372
free_address(&curdoc);
1373
} else if (cmd != LYK_NOCACHE) {
1374
*try_internal = TRUE;
1376
if (!(LYresubmit_posts && newdoc.post_data))
1377
LYinternal_flag = TRUE;
1378
/* We still set force_load so that history pushing
1379
** etc. will be done. - kw */
1384
* Free POST content if not an internal link. - kw
1386
LYFreePostData(&newdoc);
1388
#endif /* TRACK_INTERNAL_LINKS */
1390
* Might be an anchor in the same doc from a POST
1391
* form. If so, don't free the content. -- FM
1393
if (are_different(&curdoc, &newdoc)) {
1394
LYFreePostData(&newdoc);
1395
FREE(newdoc.bookmark);
1396
if (isLYNXMESSAGES(newdoc.address))
1397
LYforce_no_cache = TRUE;
1399
if (!no_jump && lynxjumpfile && curdoc.address &&
1400
!strcmp(lynxjumpfile, curdoc.address)) {
1401
LYJumpFileURL = TRUE;
1402
LYUserSpecifiedURL = TRUE;
1403
} else if ((curdoc.title &&
1404
(LYIsUIPage(curdoc.address, UIP_HISTORY) ||
1405
!strcmp(curdoc.title, HISTORY_PAGE_TITLE))) ||
1406
curdoc.bookmark != NULL ||
1408
!strcmp(lynxjumpfile, curdoc.address))) {
1409
LYUserSpecifiedURL = TRUE;
1410
} else if (no_filereferer == TRUE && isFILE_URL(curdoc.address)) {
1411
LYNoRefererForThis = TRUE;
1414
*force_load = TRUE; /* force MainLoop to reload */
1415
#ifdef USE_PRETTYSRC
1416
psrc_view = FALSE; /* we get here if link is not internal */
1419
#if defined(DIRED_SUPPORT) && !defined(__DJGPP__)
1420
if (lynx_edit_mode) {
1423
* Unescaping any slash chars in the URL,
1424
* but avoid double unescaping and too-early
1425
* unescaping of other chars. - KW
1427
HTUnEscapeSome(newdoc.address,"/");
1428
/* avoid stripping final slash for root dir - kw */
1429
if (strcasecomp(newdoc.address, "file://localhost/"))
1430
strip_trailing_slash(newdoc.address);
1432
#endif /* DIRED_SUPPORT && !__DJGPP__ */
1433
if (isLYNXCOOKIE(curdoc.address)) {
1434
HTuncache_current_document();
1441
#ifdef EXP_ADDRLIST_PAGE
1442
PRIVATE BOOLEAN handle_LYK_ADDRLIST ARGS1(
1446
* Don't do if already viewing list addresses page.
1448
if (LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE)) {
1450
* Already viewing list page, so get out.
1452
*cmd = LYK_PREV_DOC;
1457
* Print address list page to file.
1459
if (showlist(&newdoc, FALSE) < 0)
1461
StrAllocCopy(newdoc.title, ADDRLIST_PAGE_TITLE);
1463
* showlist will set newdoc's other fields. It may leave
1464
* post_data intact so the list can be used to follow
1465
* internal links in the current document even if it is
1466
* a POST response. - kw
1469
if (LYValidate || check_realm) {
1471
StrAllocCopy(lynxlistfile, newdoc.address);
1475
#endif /* EXP_ADDRLIST_PAGE */
1477
PRIVATE void handle_LYK_ADD_BOOKMARK ARGS3(
1478
BOOLEAN *, refresh_screen,
1485
if (*old_c != real_c) {
1487
HTUserMsg(BOOKMARKS_DISABLED);
1492
if (!LYIsUIPage(curdoc.address, UIP_HISTORY) &&
1493
!LYIsUIPage(curdoc.address, UIP_SHOWINFO) &&
1494
!LYIsUIPage(curdoc.address, UIP_PRINT_OPTIONS) &&
1495
#ifdef DIRED_SUPPORT
1496
!LYIsUIPage(curdoc.address, UIP_DIRED_MENU) &&
1497
!LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS) &&
1498
!LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS) &&
1499
#endif /* DIRED_SUPPORT */
1500
!LYIsUIPage(curdoc.address, UIP_DOWNLOAD_OPTIONS) &&
1501
!isLYNXCOOKIE(curdoc.address) &&
1502
!LYIsUIPage(curdoc.address, UIP_OPTIONS_MENU) &&
1504
(links[curdoc.link].lname != NULL &&
1505
!isLYNXHIST(links[curdoc.link].lname) &&
1506
!isLYNXPRINT(links[curdoc.link].lname) &&
1507
!isLYNXDIRED(links[curdoc.link].lname) &&
1508
!isLYNXDOWNLOAD(links[curdoc.link].lname) &&
1509
!isLYNXCOOKIE(links[curdoc.link].lname) &&
1510
!isLYNXPRINT(links[curdoc.link].lname)))) {
1512
if (curdoc.post_data == NULL &&
1513
curdoc.bookmark == NULL &&
1514
!LYIsUIPage(curdoc.address, UIP_LIST_PAGE) &&
1515
!LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE) &&
1516
!LYIsUIPage(curdoc.address, UIP_VLINKS)) {
1518
* The document doesn't have POST content,
1519
* and is not a bookmark file, nor is the
1520
* list or visited links page, so we can
1521
* save either that or the link. - FM
1523
_statusline(BOOK_D_L_OR_CANCEL);
1524
if ((c = LYgetch_single()) == 'D') {
1525
save_bookmark_link(curdoc.address, curdoc.title);
1526
*refresh_screen = TRUE; /* MultiBookmark support */
1527
goto check_add_bookmark_to_self;
1530
if (LYMultiBookmarks == MBM_OFF &&
1531
curdoc.bookmark != NULL &&
1532
strstr(curdoc.address,
1533
(*bookmark_page == '.'
1535
: bookmark_page)) != NULL) {
1537
* If multiple bookmarks are disabled, offer
1538
* the L)ink or C)ancel, but with wording
1539
* which indicates that the link already
1540
* exists in this bookmark file. - FM
1542
_statusline(MULTIBOOKMARKS_SELF);
1543
} else if (curdoc.post_data != NULL &&
1544
links[curdoc.link].type == WWW_INTERN_LINK_TYPE) {
1546
* Internal link, and document has POST content.
1548
HTUserMsg(NOBOOK_POST_FORM);
1552
* Only offer the link in a document with
1553
* POST content, or if the current document
1554
* is a bookmark file and multiple bookmarks
1557
_statusline(BOOK_L_OR_CANCEL);
1559
c = LYgetch_single();
1562
if (curdoc.post_data != NULL &&
1563
links[curdoc.link].type == WWW_INTERN_LINK_TYPE) {
1565
* Internal link, and document has POST content.
1567
HTUserMsg(NOBOOK_POST_FORM);
1571
* User does want to save the link. - FM
1573
if (links[curdoc.link].type != WWW_FORM_LINK_TYPE) {
1574
save_bookmark_link(links[curdoc.link].lname,
1575
LYGetHiliteStr(curdoc.link, 0));
1576
*refresh_screen = TRUE; /* MultiBookmark support */
1578
HTUserMsg(NOBOOK_FORM_FIELD);
1584
} else if (curdoc.post_data != NULL) {
1586
* No links, and document has POST content. - FM
1588
HTUserMsg(NOBOOK_POST_FORM);
1590
} else if (curdoc.bookmark != NULL) {
1592
* It's a bookmark file from which all
1593
* of the links were deleted. - FM
1595
HTUserMsg(BOOKMARKS_NOLINKS);
1598
_statusline(BOOK_D_OR_CANCEL);
1599
if (LYgetch_single() == 'D') {
1600
save_bookmark_link(curdoc.address, curdoc.title);
1601
*refresh_screen = TRUE; /* MultiBookmark support */
1606
check_add_bookmark_to_self:
1607
if (curdoc.bookmark && BookmarkPage &&
1608
!strcmp(curdoc.bookmark, BookmarkPage)) {
1609
HTuncache_current_document();
1610
move_address(&newdoc, &curdoc);
1611
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
1612
newdoc.line = curdoc.line;
1613
newdoc.link = curdoc.link;
1614
newdoc.internal_link = FALSE;
1617
if (*old_c != real_c) {
1619
HTUserMsg(NOBOOK_HSML);
1624
PRIVATE void handle_LYK_CLEAR_AUTH ARGS2(
1628
if (*old_c != real_c) {
1630
if (HTConfirm(CLEAR_ALL_AUTH_INFO)) {
1631
FREE(authentication_info[0]);
1632
FREE(authentication_info[1]);
1633
FREE(proxyauth_info[0]);
1634
FREE(proxyauth_info[1]);
1635
HTClearHTTPAuthInfo();
1636
#ifndef DISABLE_NEWS
1637
HTClearNNTPAuthInfo();
1640
HTClearFTPPassword();
1642
HTUserMsg(AUTH_INFO_CLEARED);
1644
HTUserMsg(CANCELLED);
1649
PRIVATE int handle_LYK_COMMAND ARGS1(
1650
char *, user_input_buffer)
1656
*user_input_buffer = 0;
1658
if (LYgetstr(user_input_buffer, VISIBLE, MAX_LINE, RECALL_CMD) >= 0) {
1659
src = LYSkipBlanks(user_input_buffer);
1660
tmp = LYSkipNonBlanks(src);
1662
ch = ((mp = LYStringToKcmd(src)) != 0) ? mp->code : 0;
1663
CTRACE((tfp, "LYK_COMMAND(%s.%s) = %d\n", src, tmp, ch));
1665
return *src ? -1 : 0;
1667
/* FIXME: reuse the rest of the buffer for parameters */
1673
PRIVATE void handle_LYK_COMMENT ARGS4(
1674
BOOLEAN *, refresh_screen,
1675
char **, owner_address_p,
1681
if (!*owner_address_p &&
1682
strncasecomp(curdoc.address, "http", 4)) {
1683
if (*old_c != real_c) {
1685
HTUserMsg(NO_OWNER);
1687
} else if (no_mail) {
1688
if (*old_c != real_c) {
1690
HTUserMsg(MAIL_DISALLOWED);
1693
if (HTConfirmDefault(CONFIRM_COMMENT, NO)) {
1694
if (!*owner_address_p) {
1696
* No owner defined, so make a guess and
1697
* and offer it to the user. - FM
1699
char *address = NULL;
1700
char *temp = HTParse(curdoc.address, "", PARSE_PATH);
1705
if (*temp == '~' && strlen(temp) > 1) {
1707
* It's a ~user URL so guess user@host. - FM
1709
if ((cp = strchr((temp+1), '/')) != NULL)
1711
StrAllocCopy(address, STR_MAILTO_URL);
1712
StrAllocCat(address, (temp+1));
1713
StrAllocCat(address, "@");
1717
if (address == NULL)
1719
* Wasn't a ~user URL so guess WebMaster@host. - FM
1721
StrAllocCopy(address, "mailto:WebMaster@");
1722
temp = HTParse(curdoc.address, "", PARSE_HOST);
1723
StrAllocCat(address, temp);
1724
HTSprintf0(&temp, NO_OWNER_USE, address);
1725
c = HTConfirmDefault(temp, NO);
1728
StrAllocCopy(*owner_address_p, address);
1735
if (is_url(*owner_address_p) != MAILTO_URL_TYPE) {
1737
* The address is a URL. Just follow the link.
1739
set_address(&newdoc, *owner_address_p);
1740
newdoc.internal_link = FALSE;
1743
* The owner_address is a mailto: URL.
1745
CONST char *kp = HText_getRevTitle();
1746
CONST char *id = HText_getMessageID();
1747
char *tmptitle = NULL;
1748
if (!kp && HTMainAnchor) {
1749
kp = HTAnchor_subject(HTMainAnchor);
1751
if (strncasecomp(kp, "Re: ", 4)) {
1752
StrAllocCopy(tmptitle, "Re: ");
1753
StrAllocCat(tmptitle, kp);
1759
if (strchr(*owner_address_p, ':') != NULL)
1761
* Send a reply. The address is after the colon.
1763
reply_by_mail(strchr(*owner_address_p, ':') + 1,
1767
reply_by_mail(*owner_address_p, curdoc.address,
1771
*refresh_screen = TRUE; /* to force a showpage */
1777
PRIVATE BOOLEAN handle_LYK_COOKIE_JAR ARGS1(
1781
* Don't do if already viewing the cookie jar.
1783
if (!isLYNXCOOKIE(curdoc.address)) {
1784
set_address(&newdoc, "LYNXCOOKIE:/");
1785
LYFreePostData(&newdoc);
1786
FREE(newdoc.bookmark);
1787
newdoc.isHEAD = FALSE;
1788
newdoc.safe = FALSE;
1789
newdoc.internal_link = FALSE;
1790
LYforce_no_cache = TRUE;
1791
if (LYValidate || check_realm) {
1796
* If already in the cookie jar, get out.
1798
*cmd = LYK_PREV_DOC;
1804
#if defined(DIRED_SUPPORT)
1805
PRIVATE void handle_LYK_CREATE NOARGS
1807
if (lynx_edit_mode && !no_dired_support) {
1808
if (local_create(&curdoc) > 0) {
1810
move_address(&newdoc, &curdoc);
1811
LYFreePostData(&newdoc);
1812
FREE(newdoc.bookmark);
1813
newdoc.isHEAD = FALSE;
1814
newdoc.safe = FALSE;
1815
newdoc.line = curdoc.line;
1816
newdoc.link = curdoc.link > -1 ? curdoc.link : 0;
1821
#endif /* DIRED_SUPPORT */
1823
PRIVATE void handle_LYK_DEL_BOOKMARK ARGS3(
1824
BOOLEAN *, refresh_screen,
1828
if (curdoc.bookmark != NULL) {
1829
if (HTConfirmDefault(CONFIRM_BOOKMARK_DELETE,NO) != YES)
1831
remove_bookmark_link(links[curdoc.link].anchor_number-1,
1833
} else { /* behave like REFRESH for backward compatibility */
1834
*refresh_screen = TRUE;
1835
if (*old_c != real_c) {
1837
lynx_force_repaint();
1841
do_cleanup_after_delete();
1844
#if defined(DIRED_SUPPORT) || defined(VMS)
1845
PRIVATE void handle_LYK_DIRED_MENU ARGS3(
1846
BOOLEAN *, refresh_screen,
1847
int *, old_c GCC_UNUSED,
1848
int, real_c GCC_UNUSED)
1851
char *cp, *temp = 0;
1852
const char *test = HTGetProgramPath(ppCSWING);
1855
* Check if the CSwing Directory/File Manager is available.
1856
* Will be disabled if CSWING path is NULL, zero-length,
1857
* or "none" (case insensitive), if no_file_url was set via
1858
* the file_url restriction, if no_goto_file was set for
1859
* the anonymous account, or if HTDirAccess was set to
1860
* HT_DIR_FORBID or HT_DIR_SELECTIVE via the -nobrowse
1861
* or -selective switches. - FM
1863
if (isEmpty(test) ||
1864
!strcasecomp(test, "none") ||
1865
no_file_url || no_goto_file ||
1866
HTDirAccess == HT_DIR_FORBID ||
1867
HTDirAccess == HT_DIR_SELECTIVE) {
1868
if (*old_c != real_c) {
1870
HTUserMsg(DFM_NOT_AVAILABLE);
1876
* If we are viewing a local directory listing or a
1877
* local file which is not temporary, invoke CSwing
1878
* with the URL's directory converted to VMS path specs
1879
* and passed as the argument, so we start up CSwing
1880
* positioned on that node of the directory tree.
1881
* Otherwise, pass the current default directory as
1882
* the argument. - FM
1884
if (LYisLocalFile(curdoc.address) &&
1885
strncasecomp(curdoc.address,
1886
lynx_temp_space, strlen(lynx_temp_space))) {
1888
* We are viewing a local directory or a local file
1889
* which is not temporary. - FM
1891
struct stat stat_info;
1893
cp = HTParse(curdoc.address, "", PARSE_PATH|PARSE_PUNCTUATION);
1895
if (HTStat(cp, &stat_info) == -1) {
1896
CTRACE((tfp, "mainloop: Can't stat %s\n", cp));
1898
HTSprintf0(&temp, "%s []", HTGetProgramPath(ppCSWING));
1899
*refresh_screen = TRUE; /* redisplay */
1901
char *VMSdir = NULL;
1903
if (S_ISDIR(stat_info.st_mode)) {
1905
* We're viewing a local directory. Make
1906
* that the CSwing argument. - FM
1909
StrAllocCopy(VMSdir, HTVMS_name("", cp));
1913
* We're viewing a local file. Make its
1914
* directory the CSwing argument. - FM
1916
StrAllocCopy(VMSdir, HTVMS_name("", cp));
1918
if ((cp = strrchr(VMSdir, ']')) != NULL) {
1921
} else if ((cp = strrchr(VMSdir, ':')) != NULL) {
1926
HTSprintf0(&temp, "%s %s", HTGetProgramPath(ppCSWING), VMSdir);
1929
* Uncache the current document in case we
1930
* change, move, or delete it during the
1931
* CSwing session. - FM
1933
/* could use DIRED_UNCACHE_1 but it's currently only defined
1935
HTuncache_current_document();
1936
move_address(&newdoc, &curdoc);
1937
StrAllocCopy(newdoc.title, NonNull(curdoc.title));
1938
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
1939
newdoc.line = curdoc.line;
1940
newdoc.link = curdoc.link;
1944
* We're not viewing a local directory or file.
1945
* Pass CSwing the current default directory as
1946
* an argument and don't uncache the current
1949
HTSprintf0(&temp, "%s []", HTGetProgramPath(ppCSWING));
1950
*refresh_screen = TRUE; /* redisplay */
1958
* Don't do if not allowed or already viewing the menu.
1960
if (lynx_edit_mode && !no_dired_support &&
1961
!LYIsUIPage(curdoc.address, UIP_DIRED_MENU) &&
1962
strcmp(NonNull(curdoc.title), DIRED_MENU_TITLE)) {
1963
dired_options(&curdoc,&newdoc.address);
1964
*refresh_screen = TRUE; /* redisplay */
1968
#endif /* defined(DIRED_SUPPORT) || defined(VMS) */
1970
PRIVATE int handle_LYK_DOWNLOAD ARGS3(
1977
* Don't do if both download and disk_save are restricted.
1980
(no_download && !override_no_download && no_disk_save)) {
1981
if (*old_c != real_c) {
1983
HTUserMsg(DOWNLOAD_DISABLED);
1989
* Don't do if already viewing download options page.
1991
if (LYIsUIPage(curdoc.address, UIP_DOWNLOAD_OPTIONS))
1994
if (do_change_link() == -1)
1995
return 1; /* mouse stuff was confused, ignore - kw */
1997
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE) {
1998
if (links[curdoc.link].l_form->type == F_SUBMIT_TYPE ||
1999
links[curdoc.link].l_form->type == F_IMAGE_SUBMIT_TYPE ||
2000
links[curdoc.link].l_form->type == F_TEXT_SUBMIT_TYPE) {
2001
if (links[curdoc.link].l_form->submit_method ==
2003
if (*old_c != real_c) {
2005
HTUserMsg(NO_DOWNLOAD_MAILTO_ACTION);
2009
if (isLYNXOPTIONS(links[curdoc.link].l_form->submit_action)) {
2010
if (*old_c != real_c) {
2012
HTUserMsg(NO_DOWNLOAD_SPECIAL);
2016
HTOutputFormat = HTAtom_for("www/download");
2017
LYforce_no_cache = TRUE;
2018
*cmd = LYK_ACTIVATE;
2021
if (*old_c != real_c) {
2023
HTUserMsg(NO_DOWNLOAD_INPUT);
2026
} else if (isLYNXCOOKIE(curdoc.address)) {
2027
if (*old_c != real_c) {
2029
HTUserMsg(NO_DOWNLOAD_COOKIES);
2032
} else if (LYIsUIPage(curdoc.address, UIP_PRINT_OPTIONS)) {
2033
if (*old_c != real_c) {
2035
HTUserMsg(NO_DOWNLOAD_PRINT_OP);
2038
#ifdef DIRED_SUPPORT
2039
} else if (LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS)) {
2040
if (*old_c != real_c) {
2042
HTUserMsg(NO_DOWNLOAD_UPLOAD_OP);
2045
} else if (LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS)) {
2046
if (*old_c != real_c) {
2048
HTUserMsg(NO_DOWNLOAD_PERMIT_OP);
2051
} else if (lynx_edit_mode && !no_dired_support &&
2052
!strstr(links[curdoc.link].lname, "/SugFile=")) {
2054
* Don't bother making a /tmp copy of the local file.
2056
static DocInfo temp;
2057
copy_address(&temp, &newdoc);
2058
set_address(&newdoc, links[curdoc.link].lname);
2059
if (LYdownload_options(&newdoc.address,
2060
links[curdoc.link].lname) < 0)
2061
copy_address(&newdoc, &temp);
2063
newdoc.internal_link = FALSE;
2064
LYFreeDocInfo(&temp);
2065
#endif /* DIRED_SUPPORT */
2067
} else if (LYIsUIPage(curdoc.address, UIP_HISTORY) &&
2068
isLYNXHIST(links[curdoc.link].lname)) {
2069
int number = atoi(links[curdoc.link].lname + LEN_LYNXHIST);
2070
if (number >= nhist || number < 0) {
2071
HTUserMsg(NO_DOWNLOAD_SPECIAL);
2074
if ((HDOC(number).post_data != NULL &&
2075
HDOC(number).safe != TRUE) &&
2076
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
2077
HTInfoMsg(CANCELLED);
2081
* OK, we download from history page, restore URL from stack.
2083
copy_address(&newdoc, &HDOC(number));
2084
StrAllocCopy(newdoc.title, LYGetHiliteStr(curdoc.link, 0));
2085
StrAllocCopy(newdoc.bookmark, HDOC(number).bookmark);
2086
LYFreePostData(&newdoc);
2087
if (HDOC(number).post_data)
2088
BStrCopy(newdoc.post_data,
2089
HDOC(number).post_data);
2090
if (HDOC(number).post_content_type)
2091
StrAllocCopy(newdoc.post_content_type,
2092
HDOC(number).post_content_type);
2093
newdoc.isHEAD = HDOC(number).isHEAD;
2094
newdoc.safe = HDOC(number).safe;
2095
newdoc.internal_link = FALSE;
2097
HTOutputFormat = HTAtom_for("www/download");
2098
LYUserSpecifiedURL = TRUE;
2100
* Force the document to be reloaded.
2102
LYforce_no_cache = TRUE;
2104
} else if (!strncmp(links[curdoc.link].lname, "data:", 5)) {
2105
if (*old_c != real_c) {
2107
HTAlert(UNSUPPORTED_DATA_URL);
2110
} else if (isLYNXCOOKIE(links[curdoc.link].lname) ||
2111
isLYNXDIRED(links[curdoc.link].lname) ||
2112
isLYNXDOWNLOAD(links[curdoc.link].lname) ||
2113
isLYNXPRINT(links[curdoc.link].lname) ||
2114
isLYNXOPTIONS(links[curdoc.link].lname) ||
2115
isLYNXHIST(links[curdoc.link].lname) ||
2116
/* handled above if valid - kw */
2117
/* @@@ should next two be downloadable? - kw */
2118
isLYNXHIST(links[curdoc.link].lname) ||
2119
isLYNXCFLAGS(links[curdoc.link].lname) ||
2120
isLYNXEXEC(links[curdoc.link].lname) ||
2121
isLYNXPROG(links[curdoc.link].lname)) {
2122
HTUserMsg(NO_DOWNLOAD_SPECIAL);
2124
} else if (isMAILTO_URL(links[curdoc.link].lname)) {
2125
HTUserMsg(NO_DOWNLOAD_MAILTO_LINK);
2128
* From here on we could have a remote host, so check if
2131
* We copy all these checks from getfile() to LYK_DOWNLOAD
2132
* here because LYNXDOWNLOAD:// will NOT be pushing the
2133
* previous document into the history stack so preserve
2134
* getfile() from returning a wrong status (NULLFILE).
2136
} else if (local_host_only &&
2137
!(LYisLocalHost(links[curdoc.link].lname) ||
2138
LYisLocalAlias(links[curdoc.link].lname))) {
2139
HTUserMsg(ACCESS_ONLY_LOCALHOST);
2140
} else { /* Not a forms, options or history link */
2142
* Follow a normal link or anchor. Note that
2143
* if it's an anchor within the same document,
2144
* entire document will be downloaded.
2146
set_address(&newdoc, links[curdoc.link].lname);
2147
StrAllocCopy(newdoc.title, LYGetHiliteStr(curdoc.link, 0));
2148
#ifndef DONT_TRACK_INTERNAL_LINKS
2150
* Might be an internal link in the same doc from a
2151
* POST form. If so, don't free the content. - kw
2153
if (links[curdoc.link].type != WWW_INTERN_LINK_TYPE)
2156
* Might be an anchor in the same doc from a POST
2157
* form. If so, don't free the content. -- FM
2159
if (are_different(&curdoc, &newdoc))
2160
#endif /* TRACK_INTERNAL_LINKS */
2162
LYFreePostData(&newdoc);
2163
FREE(newdoc.bookmark);
2164
newdoc.isHEAD = FALSE;
2165
newdoc.safe = FALSE;
2167
newdoc.internal_link = FALSE;
2169
HTOutputFormat = HTAtom_for("www/download");
2171
* Force the document to be reloaded.
2173
LYforce_no_cache = TRUE;
2175
} else if (*old_c != real_c) {
2177
HTUserMsg(NO_DOWNLOAD_CHOICE);
2182
PRIVATE void handle_LYK_DOWN_HALF ARGS2(
2189
Newline += (display_lines/2);
2190
if (nlinks > 0 && curdoc.link > -1 &&
2191
links[curdoc.link].ly > display_lines/2) {
2192
newdoc.link = curdoc.link;
2193
for (i = 0; links[i].ly <= (display_lines/2); i++)
2196
} else if (*old_c != real_c) {
2198
HTInfoMsg(ALREADY_AT_END);
2202
PRIVATE void handle_LYK_DOWN_LINK ARGS3(
2207
if (curdoc.link < (nlinks-1)) { /* more links? */
2210
if (*follow_col == -1) {
2211
char *text = LYGetHiliteStr(curdoc.link, 0);
2212
*follow_col = links[curdoc.link].lx;
2215
*follow_col += strlen(text) / 2;
2218
newlink = find_link_near_col(*follow_col, 1);
2220
set_curdoc_link(newlink);
2221
} else if (more) { /* next page */
2222
Newline += (display_lines);
2223
} else if (*old_c != real_c) {
2225
HTUserMsg(NO_LINKS_BELOW);
2228
} else if (more) { /* next page */
2229
Newline += (display_lines);
2231
} else if (*old_c != real_c) {
2233
HTInfoMsg(ALREADY_AT_END);
2237
PRIVATE void handle_LYK_DOWN_TWO ARGS2(
2245
if (nlinks > 0 && curdoc.link > -1 &&
2246
links[curdoc.link].ly > 2) {
2247
newdoc.link = curdoc.link;
2248
for (i = 0; links[i].ly <= 2; i++)
2251
} else if (*old_c != real_c) {
2253
HTInfoMsg(ALREADY_AT_END);
2257
PRIVATE int handle_LYK_DWIMEDIT ARGS3(
2262
#ifdef TEXTAREA_AUTOEXTEDIT
2264
* If we're in a forms TEXTAREA, invoke the editor on *its*
2265
* contents, rather than attempting to edit the html source
2269
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2270
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE) {
2271
*cmd = LYK_EDIT_TEXTAREA;
2276
* If we're in a forms TEXT type, tell user the request
2277
* is bogus (though in reality, without this trap, if the
2278
* document with the TEXT field is local, the editor *would*
2279
* be invoked on the source .html file; eg, the o(ptions)
2282
* [This is done to avoid possible user confusion, due to
2283
* auto invocation of the editor on the TEXTAREA's contents
2284
* via the above if() statement.]
2287
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2288
links[curdoc.link].l_form->type == F_TEXT_TYPE) {
2289
HTUserMsg (CANNOT_EDIT_FIELD);
2294
if (*old_c != real_c) {
2296
HTUserMsg(ANYEDIT_DISABLED);
2300
#endif /* TEXTAREA_AUTOEXTEDIT */
2304
PRIVATE int handle_LYK_ECGOTO ARGS5(
2306
char *, user_input_buffer,
2307
char **, old_user_input,
2311
if (no_goto && !LYValidate) {
2313
* Go to not allowed. - FM
2315
if (*old_c != real_c) {
2317
HTUserMsg(GOTO_DISALLOWED);
2321
#ifdef DIRED_SUPPORT
2322
if (LYIsUIPage(curdoc.address, UIP_DIRED_MENU) ||
2323
LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS) ||
2324
LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS)) {
2326
* Disallow editing of File Management URLs. - FM
2328
if (*old_c != real_c) {
2330
HTUserMsg(EDIT_FM_MENU_URLS_DISALLOWED);
2334
#endif /* DIRED_SUPPORT */
2337
* Save the current user_input_buffer string,
2338
* and load the current document's address.
2340
StrAllocCopy(*old_user_input, user_input_buffer);
2341
LYstrncpy(user_input_buffer,
2346
* Warn the user if the current document has POST
2347
* data associated with it. - FM
2349
if (curdoc.post_data)
2350
HTAlert(CURRENT_DOC_HAS_POST_DATA);
2353
* Offer the current document's URL for editing. - FM
2355
_statusline(EDIT_CURDOC_URL);
2356
if (((*ch = LYgetstr(user_input_buffer, VISIBLE,
2357
MAX_LINE, RECALL_URL)) >= 0) &&
2358
user_input_buffer[0] != '\0' &&
2359
strcmp(user_input_buffer, curdoc.address)) {
2360
LYTrimAllStartfile(user_input_buffer);
2361
if (user_input_buffer[0] != '\0') {
2366
* User cancelled via ^G, a full deletion,
2367
* or not modifying the URL. - FM
2369
HTInfoMsg(CANCELLED);
2370
LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
2371
FREE(*old_user_input);
2375
PRIVATE void handle_LYK_EDIT ARGS2(
2379
#ifdef DIRED_SUPPORT
2382
struct stat dir_info;
2383
#endif /* DIRED_SUPPORT */
2386
if (*old_c != real_c) {
2388
HTUserMsg(EDIT_DISABLED);
2392
#ifdef DIRED_SUPPORT
2394
* Allow the user to edit the link rather
2395
* than curdoc in edit mode.
2397
if (lynx_edit_mode &&
2398
editor && *editor != '\0' && !no_dired_support) {
2400
cp = links[curdoc.link].lname;
2401
if (is_url(cp) == FILE_URL_TYPE) {
2402
cp = HTfullURL_toFile(cp);
2403
StrAllocCopy(tp, cp);
2406
if (stat(tp, &dir_info) == -1) {
2409
if (S_ISREG(dir_info.st_mode)) {
2410
StrAllocCopy(tp, links[curdoc.link].lname);
2411
HTUnEscapeSome(tp, "/");
2412
if (edit_current_file(tp, curdoc.link, Newline)) {
2414
move_address(&newdoc, &curdoc);
2415
#ifdef NO_SEEK_OLD_POSITION
2417
* Go to top of file.
2423
* Seek old position,
2424
* which probably changed.
2426
newdoc.line = curdoc.line;
2427
newdoc.link = curdoc.link;
2428
#endif /* NO_SEEK_OLD_POSITION */
2429
LYclear(); /* clear the screen */
2437
#endif /* DIRED_SUPPORT */
2438
if (editor && *editor != '\0') {
2439
if (edit_current_file(newdoc.address, curdoc.link, Newline)) {
2440
HTuncache_current_document();
2441
LYforce_no_cache = TRUE; /*force reload of document */
2442
free_address(&curdoc); /* so it doesn't get pushed */
2443
#ifdef NO_SEEK_OLD_POSITION
2445
* Go to top of file.
2451
* Seek old position, which probably changed.
2453
newdoc.line = curdoc.line;
2454
newdoc.link = curdoc.link;
2455
#endif /* NO_SEEK_OLD_POSITION */
2456
LYclear(); /* clear the screen */
2460
if (*old_c != real_c) {
2462
HTUserMsg(NO_EDITOR);
2467
PRIVATE void handle_LYK_DWIMHELP ARGS1(
2468
CONST char **, cshelpfile)
2471
* Currently a help file different from the main
2472
* 'helpfile' is shown only if current link is a
2473
* text input form field. - kw
2475
if (curdoc.link >= 0 && curdoc.link < nlinks &&
2476
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2477
!links[curdoc.link].l_form->disabled &&
2478
F_TEXTLIKE(links[curdoc.link].l_form->type)) {
2479
*cshelpfile = LYLineeditHelpURL();
2483
PRIVATE void handle_LYK_EDIT_TEXTAREA ARGS3(
2484
BOOLEAN *, refresh_screen,
2491
if (*old_c != real_c) {
2493
HTUserMsg(ANYEDIT_DISABLED);
2495
} else if (!editor || *editor == '\0') {
2496
if (*old_c != real_c) {
2498
HTUserMsg(NO_EDITOR);
2502
* See if the current link is in a form TEXTAREA.
2504
else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2505
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE) {
2510
n = HText_ExtEditForm (&links[curdoc.link]);
2513
* TODO: Move cursor "n" lines from the current line to
2514
* position it on the 1st trailing blank line in
2515
* the now edited TEXTAREA. If the target line/
2516
* anchor requires us to scroll up/down, position
2517
* the target in the approximate center of the
2521
/* curdoc.link += n;*/ /* works, except for page crossing, */
2522
/* damnit; why is nothing ever easy */
2526
*refresh_screen = TRUE;
2530
HTInfoMsg (NOT_IN_TEXTAREA_NOEDIT);
2534
PRIVATE int handle_LYK_ELGOTO ARGS5(
2536
char *, user_input_buffer,
2537
char **, old_user_input,
2541
if (no_goto && !LYValidate) {
2543
* Go to not allowed. - FM
2545
if (*old_c != real_c) {
2547
HTUserMsg(GOTO_DISALLOWED);
2551
if (!(nlinks > 0 && curdoc.link > -1) ||
2552
(links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2553
links[curdoc.link].l_form->type != F_SUBMIT_TYPE &&
2554
links[curdoc.link].l_form->type != F_IMAGE_SUBMIT_TYPE &&
2555
links[curdoc.link].l_form->type != F_TEXT_SUBMIT_TYPE)) {
2557
* No links on page, or not a normal link
2558
* or form submit button. - FM
2560
if (*old_c != real_c) {
2562
HTUserMsg(NOT_ON_SUBMIT_OR_LINK);
2566
if ((links[curdoc.link].type == WWW_FORM_LINK_TYPE) &&
2567
(!links[curdoc.link].l_form->submit_action ||
2568
*links[curdoc.link].l_form->submit_action == '\0')) {
2570
* Form submit button with no ACTION defined. - FM
2572
if (*old_c != real_c) {
2574
HTUserMsg(NO_FORM_ACTION);
2578
#ifdef DIRED_SUPPORT
2579
if (isLYNXDIRED(links[curdoc.link].lname) ||
2580
LYIsUIPage(curdoc.address, UIP_DIRED_MENU) ||
2581
LYIsUIPage(curdoc.address, UIP_PERMIT_OPTIONS) ||
2582
LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS)) {
2584
* Disallow editing of File Management URLs. - FM
2586
if (*old_c != real_c) {
2588
HTUserMsg(EDIT_FM_MENU_URLS_DISALLOWED);
2592
#endif /* DIRED_SUPPORT */
2595
* Save the current user_input_buffer string,
2596
* and load the current link's address. - FM
2598
StrAllocCopy(*old_user_input, user_input_buffer);
2599
LYstrncpy(user_input_buffer,
2600
((links[curdoc.link].type == WWW_FORM_LINK_TYPE)
2602
links[curdoc.link].l_form->submit_action : links[curdoc.link].lname),
2606
* Offer the current link's URL for editing. - FM
2608
_statusline(EDIT_CURLINK_URL);
2609
if (((*ch = LYgetstr(user_input_buffer, VISIBLE,
2610
MAX_LINE, RECALL_URL)) >= 0) &&
2611
user_input_buffer[0] != '\0' &&
2612
strcmp(user_input_buffer,
2613
((links[curdoc.link].type == WWW_FORM_LINK_TYPE)
2614
? links[curdoc.link].l_form->submit_action
2615
: links[curdoc.link].lname))) {
2616
LYTrimAllStartfile(user_input_buffer);
2617
if (user_input_buffer[0] != '\0') {
2622
* User cancelled via ^G, a full deletion,
2623
* or not modifying the URL. - FM
2625
HTInfoMsg(CANCELLED);
2626
LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
2627
FREE(*old_user_input);
2631
#ifdef USE_EXTERNALS
2632
PRIVATE void handle_LYK_EXTERN_LINK ARGS1(
2633
BOOLEAN *, refresh_screen)
2635
if ((nlinks > 0) && (links[curdoc.link].lname != NULL))
2637
run_external(links[curdoc.link].lname, FALSE);
2638
*refresh_screen = TRUE;
2642
PRIVATE void handle_LYK_EXTERN_PAGE ARGS1(
2643
BOOLEAN *, refresh_screen)
2645
if (curdoc.address != NULL)
2647
run_external(curdoc.address, FALSE);
2648
*refresh_screen = TRUE;
2653
PRIVATE BOOLEAN handle_LYK_FASTBACKW_LINK ARGS3(
2658
int samepage = 0, nextlink = curdoc.link;
2664
* If in textarea, move to first link or textarea group
2665
* before it if there is one on this screen. - kw
2667
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2668
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE) {
2669
int thisgroup = links[curdoc.link].l_form->number;
2670
char *thisname = links[curdoc.link].l_form->name;
2672
if (curdoc.link > 0 &&
2673
!(links[0].type == WWW_FORM_LINK_TYPE &&
2674
links[0].l_form->type == F_TEXTAREA_TYPE &&
2675
links[0].l_form->number == thisgroup &&
2676
sametext(links[0].l_form->name, thisname))) {
2679
(links[nextlink].type == WWW_FORM_LINK_TYPE &&
2680
links[nextlink].l_form->type == F_TEXTAREA_TYPE &&
2681
links[nextlink].l_form->number == thisgroup &&
2682
sametext(links[nextlink].l_form->name, thisname));
2685
} else if (!more && Newline == 1 &&
2686
(links[0].type == WWW_FORM_LINK_TYPE &&
2687
links[0].l_form->type == F_TEXTAREA_TYPE &&
2688
links[0].l_form->number == thisgroup &&
2689
sametext(links[0].l_form->name, thisname)) &&
2690
!(links[nlinks-1].type == WWW_FORM_LINK_TYPE &&
2691
links[nlinks-1].l_form->type == F_TEXTAREA_TYPE &&
2692
links[nlinks-1].l_form->number == thisgroup &&
2693
sametext(links[nlinks-1].l_form->name, thisname))) {
2694
nextlink = nlinks - 1;
2697
} else if (!more && Newline == 1 && curdoc.link > 0) {
2701
} else if (curdoc.link > 0) {
2704
} else if (!more && Newline == 1) {
2705
nextlink = nlinks - 1;
2711
* If the link as determined so far is part of a
2712
* group of textarea fields, try to use the first
2713
* of them that's on the screen instead. - kw
2716
links[nextlink].type == WWW_FORM_LINK_TYPE &&
2717
links[nextlink].l_form->type == F_TEXTAREA_TYPE) {
2718
int thisgroup = links[nextlink].l_form->number;
2719
char *thisname = links[nextlink].l_form->name;
2720
if (links[0].type == WWW_FORM_LINK_TYPE &&
2721
links[0].l_form->type == F_TEXTAREA_TYPE &&
2722
links[0].l_form->number == thisgroup &&
2723
sametext(links[0].l_form->name, thisname)) {
2728
links[nextlink-1].type == WWW_FORM_LINK_TYPE &&
2729
links[nextlink-1].l_form->type == F_TEXTAREA_TYPE &&
2730
links[nextlink-1].l_form->number == thisgroup &&
2731
sametext(links[nextlink-1].l_form->name, thisname)) {
2735
set_curdoc_link(nextlink);
2736
return FALSE; /* and we are done. */
2738
} else if (Newline > 1 && /* need a previous page */
2739
(res = HTGetLinkOrFieldStart(curdoc.link,
2740
&Newline, &newdoc.link,
2742
if (res == LINK_DO_ARROWUP) {
2744
* It says we should use the normal PREV_LINK
2745
* mechanism, so we'll do that. - kw
2749
*cmd = LYK_PREV_LINK;
2752
Newline++; /* our line counting starts with 1 not 0 */
2753
/* nothing more to do here */
2755
} else if (*old_c != real_c) {
2757
HTInfoMsg(NO_LINKS_ABOVE);
2762
PRIVATE void handle_LYK_FASTFORW_LINK ARGS2(
2766
int samepage = 0, nextlink = curdoc.link;
2771
* If in textarea, move to first link or field
2772
* after it if there is one on this screen. - kw
2774
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2775
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE) {
2776
int thisgroup = links[curdoc.link].l_form->number;
2777
char *thisname = links[curdoc.link].l_form->name;
2779
if (curdoc.link < nlinks-1 &&
2780
!(links[nlinks-1].type == WWW_FORM_LINK_TYPE &&
2781
links[nlinks-1].l_form->type == F_TEXTAREA_TYPE &&
2782
links[nlinks-1].l_form->number == thisgroup &&
2783
sametext(links[nlinks-1].l_form->name, thisname))) {
2786
(links[nextlink].type == WWW_FORM_LINK_TYPE &&
2787
links[nextlink].l_form->type == F_TEXTAREA_TYPE &&
2788
links[nextlink].l_form->number == thisgroup &&
2789
sametext(links[nextlink].l_form->name, thisname));
2791
} else if (!more && Newline == 1 && curdoc.link > 0) {
2795
} else if (curdoc.link < nlinks-1) {
2798
} else if (!more && Newline == 1 && curdoc.link > 0) {
2804
set_curdoc_link(nextlink);
2805
return; /* and we are done. */
2808
* At the bottom of list and there is only one page.
2809
* Move to the top link on the page.
2811
} else if (!more && Newline == 1 && curdoc.link == nlinks-1) {
2814
} else if (more && /* need a later page */
2815
HTGetLinkOrFieldStart(curdoc.link,
2816
&Newline, &newdoc.link,
2818
Newline++; /* our line counting starts with 1 not 0 */
2819
/* nothing more to do here */
2821
} else if (*old_c != real_c) {
2823
HTInfoMsg(NO_LINKS_BELOW);
2828
PRIVATE void handle_LYK_FIRST_LINK NOARGS
2830
int i = curdoc.link;
2834
|| links[i].ly != links[curdoc.link].ly) {
2835
set_curdoc_link(i + 1);
2841
PRIVATE BOOLEAN handle_LYK_GOTO ARGS9(
2843
char *, user_input_buffer,
2844
char **, old_user_input,
2848
BOOLEAN *, FirstURLRecall,
2853
if (no_goto && !LYValidate) {
2854
if (*old_c != real_c) {
2856
HTUserMsg(GOTO_DISALLOWED);
2861
StrAllocCopy(*old_user_input, user_input_buffer);
2863
*user_input_buffer = '\0';
2865
*URLTotal = (Goto_URLs ? HTList_count(Goto_URLs) : 0);
2866
if (goto_buffer && *user_input_buffer) {
2867
*recall = ((*URLTotal > 1) ? RECALL_URL : NORECALL);
2869
*FirstURLRecall = FALSE;
2871
*recall = ((*URLTotal >= 1) ? RECALL_URL : NORECALL);
2872
*URLNum = *URLTotal;
2873
*FirstURLRecall = TRUE;
2879
_statusline(URL_TO_OPEN);
2880
if ((*ch = LYgetstr(user_input_buffer, VISIBLE,
2881
MAX_LINE, *recall)) < 0 ) {
2883
* User cancelled the Goto via ^G.
2884
* Restore user_input_buffer and break. - FM
2886
LYstrncpy(user_input_buffer, *old_user_input, MAX_LINE - 1);
2887
FREE(*old_user_input);
2888
HTInfoMsg(CANCELLED);
2894
PRIVATE void handle_LYK_GROW_TEXTAREA ARGS1(
2895
BOOLEAN *, refresh_screen)
2898
* See if the current link is in a form TEXTAREA.
2900
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2901
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE) {
2903
HText_ExpandTextarea (&links[curdoc.link], TEXTAREA_EXPAND_SIZE);
2905
*refresh_screen = TRUE;
2909
HTInfoMsg (NOT_IN_TEXTAREA);
2913
PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
2919
(links[curdoc.link].type != WWW_FORM_LINK_TYPE ||
2920
links[curdoc.link].l_form->type == F_SUBMIT_TYPE ||
2921
links[curdoc.link].l_form->type == F_IMAGE_SUBMIT_TYPE ||
2922
links[curdoc.link].l_form->type == F_TEXT_SUBMIT_TYPE)) {
2924
* We have links, and the current link is a normal link or a form's
2925
* submit button. - FM
2927
_statusline(HEAD_D_L_OR_CANCEL);
2928
c = LYgetch_single();
2930
char *scheme = !isLYNXIMGMAP(curdoc.address)
2932
: curdoc.address + LEN_LYNXIMGMAP;
2933
if (LYCanDoHEAD(scheme) != TRUE) {
2934
HTUserMsg(DOC_NOT_HTTP_URL);
2937
* Check if this is a reply from a POST, and if so, seek
2938
* confirmation if the safe element is not set. - FM
2940
if ((curdoc.post_data != NULL &&
2941
curdoc.safe != TRUE) &&
2942
HTConfirm(CONFIRM_POST_DOC_HEAD) == FALSE) {
2943
HTInfoMsg(CANCELLED);
2945
HEAD_request = TRUE;
2946
LYforce_no_cache = TRUE;
2947
StrAllocCopy(newdoc.title, curdoc.title);
2948
if (HTLoadedDocumentIsHEAD()) {
2949
HText_setNoCache(HTMainText);
2950
free_address(&curdoc);
2952
StrAllocCat(newdoc.title, " - HEAD");
2956
} else if (c == 'L') {
2957
if (links[curdoc.link].type != WWW_FORM_LINK_TYPE &&
2958
strncmp(links[curdoc.link].lname, "http", 4) &&
2959
strncmp(links[curdoc.link].lname,
2960
"LYNXIMGMAP:http", 15) &&
2961
LYCanDoHEAD(links[curdoc.link].lname) != TRUE &&
2962
(links[curdoc.link].type != WWW_INTERN_LINK_TYPE ||
2964
strncmp(curdoc.address, "http", 4))) {
2965
HTUserMsg(LINK_NOT_HTTP_URL);
2966
} else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2967
links[curdoc.link].l_form->disabled) {
2968
HTUserMsg(FORM_ACTION_DISABLED);
2969
} else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2970
!isLYNXCGI(links[curdoc.link].l_form->submit_action) &&
2971
strncmp(links[curdoc.link].l_form->submit_action,
2973
HTUserMsg(FORM_ACTION_NOT_HTTP_URL);
2974
} else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
2975
links[curdoc.link].l_form->submit_method ==
2977
HTConfirm(CONFIRM_POST_LINK_HEAD) == FALSE) {
2978
HTInfoMsg(CANCELLED);
2980
HEAD_request = TRUE;
2981
LYforce_no_cache = TRUE;
2982
*cmd = LYK_ACTIVATE;
2988
* We can offer only this document for a HEAD request. Check if this
2989
* is a reply from a POST, and if so, seek confirmation if the safe
2990
* element is not set. - FM
2992
if ((curdoc.post_data != NULL &&
2993
curdoc.safe != TRUE) &&
2994
HTConfirm(CONFIRM_POST_DOC_HEAD) == FALSE) {
2995
HTInfoMsg(CANCELLED);
2999
* The current link is a non-submittable form link, so prompt
3000
* the user to make it clear that the HEAD request would be for
3001
* the current document, not the form link. - FM
3003
_statusline(HEAD_D_OR_CANCEL);
3004
c = LYgetch_single();
3007
* No links, so we can just assume that the user wants a HEAD
3008
* request for the current document. - FM
3013
char *scheme = !isLYNXIMGMAP(curdoc.address)
3015
: curdoc.address + LEN_LYNXIMGMAP;
3017
* The user didn't cancel, so check if a HEAD request is
3018
* appropriate for the current document. - FM
3020
if (LYCanDoHEAD(scheme) != TRUE) {
3021
HTUserMsg(DOC_NOT_HTTP_URL);
3023
HEAD_request = TRUE;
3024
LYforce_no_cache = TRUE;
3025
StrAllocCopy(newdoc.title, curdoc.title);
3026
if (HTLoadedDocumentIsHEAD()) {
3027
HText_setNoCache(HTMainText);
3028
free_address(&curdoc);
3030
StrAllocCat(newdoc.title, " - HEAD");
3039
PRIVATE void handle_LYK_HELP ARGS1(
3040
CONST char **, cshelpfile)
3042
if (*cshelpfile == NULL)
3043
*cshelpfile = helpfile;
3044
if (!STREQ(curdoc.address, *cshelpfile)) {
3048
set_address(&newdoc, *cshelpfile);
3050
* Make a name for this help file.
3052
StrAllocCopy(newdoc.title, gettext("Help Screen"));
3053
LYFreePostData(&newdoc);
3054
FREE(newdoc.bookmark);
3055
newdoc.isHEAD = FALSE;
3056
newdoc.safe = FALSE;
3057
newdoc.internal_link = FALSE;
3059
*cshelpfile = NULL; /* reset pointer - kw */
3062
PRIVATE void handle_LYK_HISTORICAL NOARGS
3064
#ifdef USE_SOURCE_CACHE
3065
if (!HTcan_reparse_document()) {
3068
* Check if this is a reply from a POST, and if so,
3069
* seek confirmation of reload if the safe element
3072
if ((curdoc.post_data != NULL &&
3073
curdoc.safe != TRUE) &&
3074
confirm_post_resub(curdoc.address, NULL, 0, 0) == FALSE) {
3075
HTInfoMsg(WILL_NOT_RELOAD_DOC);
3077
HText_setNoCache(HTMainText);
3078
move_address(&newdoc, &curdoc);
3079
newdoc.line = curdoc.line;
3080
newdoc.link = curdoc.link;
3082
#ifdef USE_SOURCE_CACHE
3083
} /* end if no bypass */
3085
historical_comments = !historical_comments;
3086
if (minimal_comments) {
3087
HTAlert(historical_comments ?
3088
HISTORICAL_ON_MINIMAL_OFF : HISTORICAL_OFF_MINIMAL_ON);
3090
HTAlert(historical_comments ?
3091
HISTORICAL_ON_VALID_OFF : HISTORICAL_OFF_VALID_ON);
3093
#ifdef USE_SOURCE_CACHE
3094
(void) reparse_document();
3099
PRIVATE BOOLEAN handle_LYK_HISTORY ARGS1(
3102
if (curdoc.title && !LYIsUIPage(curdoc.address, UIP_HISTORY)) {
3104
* Don't do this if already viewing history page.
3106
* Push the current file so that the history list
3107
* contains the current file for printing purposes.
3108
* Pop the file afterwards to prevent multiple copies.
3110
if (TRACE && !LYUseTraceLog && LYCursesON) {
3111
LYHideCursor(); /* make sure cursor is down */
3114
#endif /* USE_SLANG */
3117
LYpush(&curdoc, ForcePush);
3120
* Print history options to file.
3122
if (showhistory(&newdoc.address) < 0) {
3126
LYRegisterUIPage(newdoc.address, UIP_HISTORY);
3127
StrAllocCopy(newdoc.title, HISTORY_PAGE_TITLE);
3128
LYFreePostData(&newdoc);
3129
FREE(newdoc.bookmark);
3130
newdoc.isHEAD = FALSE;
3131
newdoc.safe = FALSE;
3132
newdoc.internal_link = FALSE;
3133
newdoc.link = 1; /*@@@ bypass "recent statusline messages" link */
3134
free_address(&curdoc); /* so it doesn't get pushed */
3136
if (LYValidate || check_realm) {
3140
} /* end if strncmp */
3144
PRIVATE BOOLEAN handle_LYK_IMAGE_TOGGLE ARGS1(
3147
clickable_images = !clickable_images;
3149
HTUserMsg(clickable_images ?
3150
CLICKABLE_IMAGES_ON : CLICKABLE_IMAGES_OFF);
3151
return reparse_or_reload(cmd);
3154
PRIVATE void handle_LYK_INDEX ARGS2(
3159
* Make sure we are not in the index already.
3161
if (!STREQ(curdoc.address, indexfile)) {
3163
if (indexfile[0]=='\0') { /* no defined index */
3164
if (*old_c != real_c) {
3166
HTUserMsg(NO_INDEX_FILE);
3170
#ifdef KANJI_CODE_OVERRIDE
3171
if (HTCJK == JAPANESE) {
3172
last_kcode = NOKANJI; /* AUTO */
3175
set_address(&newdoc, indexfile);
3176
StrAllocCopy(newdoc.title, gettext("System Index")); /* name it */
3177
LYFreePostData(&newdoc);
3178
FREE(newdoc.bookmark);
3179
newdoc.isHEAD = FALSE;
3180
newdoc.safe = FALSE;
3181
newdoc.internal_link = FALSE;
3186
PRIVATE void handle_LYK_INDEX_SEARCH ARGS4(
3187
BOOLEAN *, force_load,
3194
* Perform a database search.
3196
* do_www_search will try to go out and get the document.
3197
* If it returns TRUE, a new document was returned and is
3198
* named in the newdoc.address.
3200
newdoc.isHEAD = FALSE;
3201
newdoc.safe = FALSE;
3202
if (do_www_search(&newdoc) == NORMAL) {
3204
* Yah, the search succeeded.
3206
if (TRACE && !LYUseTraceLog && LYCursesON) {
3208
* Make sure cursor is down.
3213
#endif /* USE_SLANG */
3216
LYpush(&curdoc, ForcePush);
3218
* Make the curdoc.address the newdoc.address so that
3219
* getfile doesn't try to get the newdoc.address.
3220
* Since we have already gotten it.
3222
copy_address(&curdoc, &newdoc);
3223
BStrCopy(newdoc.post_data, curdoc.post_data);
3224
StrAllocCopy(newdoc.post_content_type, curdoc.post_content_type);
3225
newdoc.internal_link = FALSE;
3228
} else if (use_this_url_instead != NULL) {
3230
* Got back a redirecting URL. Check it out.
3232
HTUserMsg2 (WWW_USING_MESSAGE, use_this_url_instead);
3235
* Make a name for this URL.
3237
StrAllocCopy(newdoc.title,
3238
"A URL specified by redirection");
3239
set_address(&newdoc, use_this_url_instead);
3240
LYFreePostData(&newdoc);
3241
FREE(newdoc.bookmark);
3242
newdoc.isHEAD = FALSE;
3243
newdoc.safe = FALSE;
3244
newdoc.internal_link = FALSE;
3245
FREE(use_this_url_instead);
3249
* Yuk, the search failed. Restore the old file.
3251
copy_address(&newdoc, &curdoc);
3252
BStrCopy(newdoc.post_data, curdoc.post_data);
3253
StrAllocCopy(newdoc.post_content_type,
3254
curdoc.post_content_type);
3255
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
3256
newdoc.isHEAD = curdoc.isHEAD;
3257
newdoc.safe = curdoc.safe;
3258
newdoc.internal_link = curdoc.internal_link;
3260
} else if (*old_c != real_c) {
3262
HTUserMsg(NOT_ISINDEX);
3266
PRIVATE BOOLEAN handle_LYK_INFO ARGS1(
3270
* Don't do if already viewing info page.
3272
if (!LYIsUIPage(curdoc.address, UIP_SHOWINFO)) {
3273
if (do_change_link() != -1
3274
&& LYShowInfo(&curdoc, HText_getNumOfLines(),
3275
&newdoc, owner_address) >= 0) {
3276
LYRegisterUIPage(newdoc.address, UIP_SHOWINFO);
3277
StrAllocCopy(newdoc.title, SHOWINFO_TITLE);
3278
LYFreePostData(&newdoc);
3279
FREE(newdoc.bookmark);
3280
newdoc.isHEAD = FALSE;
3281
newdoc.safe = FALSE;
3282
newdoc.internal_link = FALSE;
3283
LYforce_no_cache = TRUE;
3284
if (LYValidate || check_realm)
3289
* If already in info page, get out.
3291
*cmd = LYK_PREV_DOC;
3297
PRIVATE BOOLEAN handle_LYK_INLINE_TOGGLE ARGS1(
3300
pseudo_inline_alts = !pseudo_inline_alts;
3302
HTUserMsg(pseudo_inline_alts ?
3303
PSEUDO_INLINE_ALTS_ON : PSEUDO_INLINE_ALTS_OFF);
3304
return reparse_or_reload(cmd);
3307
PRIVATE void handle_LYK_INSERT_FILE ARGS3(
3308
BOOLEAN *, refresh_screen,
3315
* See if the current link is in a form TEXTAREA.
3317
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
3318
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE) {
3321
* Reject attempts to use this for gaining access to
3322
* local files when such access is restricted:
3323
* if no_file_url was set via the file_url restriction,
3324
* if no_goto_file was set for the anonymous account,
3325
* or if HTDirAccess was set to HT_DIR_FORBID or
3326
* HT_DIR_SELECTIVE via the -nobrowse or -selective
3327
* switches, it is assumed that inserting files or
3328
* checking for existence of files needs to be denied. - kw
3330
if (no_file_url || no_goto_file ||
3331
HTDirAccess == HT_DIR_FORBID ||
3332
HTDirAccess == HT_DIR_SELECTIVE) {
3333
if (*old_c != real_c) {
3336
HTUserMsg2(GOTO_XXXX_DISALLOWED, STR_FILE_URL);
3338
HTUserMsg(NOAUTH_TO_ACCESS_FILES);
3339
HTInfoMsg(FILE_INSERT_CANCELLED);
3344
n = HText_InsertFile (&links[curdoc.link]);
3347
* TODO: Move cursor "n" lines from the current line to
3348
* position it on the 1st line following the text
3349
* that was inserted. If the target line/anchor
3350
* requires us to scroll up/down, position the
3351
* target in the approximate center of the screen.
3353
* [Current behavior leaves cursor on the same line relative
3354
* to the start of the TEXTAREA that it was on before the
3355
* insertion. This is the same behavior that occurs with
3356
* (my) editor, so this TODO will stay unimplemented.]
3359
*refresh_screen = TRUE;
3363
HTInfoMsg (NOT_IN_TEXTAREA);
3367
#if defined(DIRED_SUPPORT) && defined(OK_INSTALL)
3368
PRIVATE void handle_LYK_INSTALL NOARGS
3370
if (lynx_edit_mode && nlinks > 0 && !no_dired_support)
3371
local_install(NULL, links[curdoc.link].lname, &newdoc.address);
3375
PRIVATE BOOLEAN handle_LYK_JUMP ARGS10(
3377
char *, user_input_buffer,
3378
char **, old_user_input GCC_UNUSED,
3379
int *, recall GCC_UNUSED,
3380
BOOLEAN *, FirstURLRecall GCC_UNUSED,
3381
int *, URLNum GCC_UNUSED,
3382
int *, URLTotal GCC_UNUSED,
3383
int *, ch GCC_UNUSED,
3389
if (no_jump || JThead == NULL) {
3390
if (*old_c != real_c) {
3393
HTUserMsg(JUMP_DISALLOWED);
3395
HTUserMsg(NO_JUMPFILE);
3398
LYJumpFileURL = TRUE;
3399
if ((ret = LYJump(c)) != NULL) {
3400
#ifdef PERMIT_GOTO_FROM_JUMP
3401
if (!strncasecomp(ret, "Go ", 3)) {
3402
LYJumpFileURL = FALSE;
3403
StrAllocCopy(*old_user_input, user_input_buffer);
3404
*URLTotal = (Goto_URLs ? HTList_count(Goto_URLs) : 0);
3405
*recall = ((*URLTotal >= 1) ? RECALL_URL : NORECALL);
3406
*URLNum = *URLTotal;
3407
*FirstURLRecall = TRUE;
3408
if (!strcasecomp(ret, "Go :")) {
3413
FREE(*old_user_input);
3414
HTUserMsg(NO_RANDOM_URLS_YET);
3417
ret = HTParse((ret+3), startfile, PARSE_ALL);
3418
LYstrncpy(user_input_buffer, ret, MAX_LINE - 1);
3422
#endif /* PERMIT_GOTO_FROM_JUMP */
3423
ret = HTParse(ret, startfile, PARSE_ALL);
3424
if (!LYTrimStartfile(ret)) {
3425
LYRemoveBlanks(user_input_buffer);
3427
set_address(&newdoc, ret);
3428
StrAllocCopy(lynxjumpfile, ret);
3429
LYFreePostData(&newdoc);
3430
FREE(newdoc.bookmark);
3431
newdoc.isHEAD = FALSE;
3432
newdoc.safe = FALSE;
3433
newdoc.internal_link = FALSE;
3435
LYUserSpecifiedURL = TRUE;
3437
LYJumpFileURL = FALSE;
3443
PRIVATE void handle_LYK_KEYMAP ARGS4(
3444
BOOLEAN *, vi_keys_flag,
3445
BOOLEAN *, emacs_keys_flag,
3449
if (*old_c != real_c) {
3451
set_address(&newdoc, STR_LYNXKEYMAP);
3452
StrAllocCopy(newdoc.title, CURRENT_KEYMAP_TITLE);
3453
LYFreePostData(&newdoc);
3454
FREE(newdoc.bookmark);
3455
newdoc.isHEAD = FALSE;
3456
newdoc.safe = FALSE;
3457
newdoc.internal_link = FALSE;
3459
* If vi_keys changed, the keymap did too,
3460
* so force no cache, and reset the flag. - FM
3462
if (*vi_keys_flag != vi_keys ||
3463
*emacs_keys_flag != emacs_keys) {
3464
LYforce_no_cache = TRUE;
3465
*vi_keys_flag = vi_keys;
3466
*emacs_keys_flag = emacs_keys;
3468
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
3470
* Remember whether we are in dired menu
3471
* so we can display the right keymap.
3473
if (!no_dired_support) {
3474
prev_lynx_edit_mode = lynx_edit_mode;
3476
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
3477
LYforce_no_cache = TRUE;
3481
PRIVATE void handle_LYK_LAST_LINK NOARGS
3483
int i = curdoc.link;
3487
|| links[i].ly != links[curdoc.link].ly) {
3488
set_curdoc_link(i - 1);
3494
PRIVATE void handle_LYK_LEFT_LINK NOARGS
3496
if (curdoc.link>0 &&
3497
links[curdoc.link].ly == links[curdoc.link-1].ly) {
3498
set_curdoc_link(curdoc.link-1);
3502
PRIVATE BOOLEAN handle_LYK_LIST ARGS1(
3506
* Don't do if already viewing list page.
3508
if (!strcmp(NonNull(curdoc.title), LIST_PAGE_TITLE) &&
3509
LYIsUIPage(curdoc.address, UIP_LIST_PAGE)) {
3511
* Already viewing list page, so get out.
3513
*cmd = LYK_PREV_DOC;
3518
* Print list page to file.
3520
if (showlist(&newdoc, TRUE) < 0)
3522
StrAllocCopy(newdoc.title, LIST_PAGE_TITLE);
3524
* showlist will set newdoc's other fields. It may leave
3525
* post_data intact so the list can be used to follow
3526
* internal links in the current document even if it is
3527
* a POST response. - kw
3530
if (LYValidate || check_realm) {
3532
StrAllocCopy(lynxlistfile, newdoc.address);
3537
PRIVATE void handle_LYK_MAIN_MENU ARGS2(
3542
* If its already the homepage then don't reload it.
3544
if (!STREQ(curdoc.address,homepage)) {
3546
if (HTConfirmDefault(CONFIRM_MAIN_SCREEN, NO) == YES) {
3547
set_address(&newdoc, homepage);
3548
StrAllocCopy(newdoc.title, gettext("Entry into main screen"));
3549
LYFreePostData(&newdoc);
3550
FREE(newdoc.bookmark);
3551
newdoc.isHEAD = FALSE;
3552
newdoc.safe = FALSE;
3553
newdoc.internal_link = FALSE;
3554
LYhighlight(OFF, curdoc.link, prev_target);
3555
#ifdef DIRED_SUPPORT
3556
if (lynx_edit_mode) {
3559
#endif /* DIRED_SUPPORT */
3562
if (*old_c != real_c) {
3564
HTUserMsg(IN_MAIN_SCREEN);
3569
PRIVATE void handle_LYK_MINIMAL NOARGS
3571
if (!historical_comments) {
3572
#ifdef USE_SOURCE_CACHE
3573
if (!HTcan_reparse_document()) {
3576
* Check if this is a reply from a POST, and if so,
3577
* seek confirmation of reload if the safe element
3580
if ((curdoc.post_data != NULL &&
3581
curdoc.safe != TRUE) &&
3582
confirm_post_resub(curdoc.address, NULL, 0, 0) == FALSE) {
3583
HTInfoMsg(WILL_NOT_RELOAD_DOC);
3585
HText_setNoCache(HTMainText);
3586
move_address(&newdoc, &curdoc);
3587
newdoc.line = curdoc.line;
3588
newdoc.link = curdoc.link;
3590
#ifdef USE_SOURCE_CACHE
3591
} /* end if no bypass */
3594
minimal_comments = !minimal_comments;
3595
if (!historical_comments) {
3596
HTAlert(minimal_comments ?
3597
MINIMAL_ON_IN_EFFECT : MINIMAL_OFF_VALID_ON);
3599
HTAlert(minimal_comments ?
3600
MINIMAL_ON_BUT_HISTORICAL : MINIMAL_OFF_HISTORICAL_ON);
3602
#ifdef USE_SOURCE_CACHE
3603
(void)reparse_document();
3608
#if defined(DIRED_SUPPORT)
3609
PRIVATE void handle_LYK_MODIFY ARGS1(
3610
BOOLEAN *, refresh_screen)
3612
if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
3615
ret = local_modify(&curdoc, &newdoc.address);
3616
if (ret == PERMIT_FORM_RESULT) { /* Permit form thrown up */
3617
*refresh_screen = TRUE;
3620
move_address(&newdoc, &curdoc);
3621
LYFreePostData(&newdoc);
3622
FREE(newdoc.bookmark);
3623
newdoc.isHEAD = FALSE;
3624
newdoc.safe = FALSE;
3625
newdoc.internal_link = FALSE;
3626
newdoc.line = curdoc.line;
3627
newdoc.link = curdoc.link;
3632
#endif /* DIRED_SUPPORT */
3634
#ifdef EXP_NESTED_TABLES
3635
PRIVATE BOOLEAN handle_LYK_NESTED_TABLES ARGS1(
3638
nested_tables = !nested_tables;
3639
HTUserMsg(nested_tables ? NESTED_TABLES_ON : NESTED_TABLES_OFF);
3640
return reparse_or_reload(cmd);
3644
PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
3646
BOOLEAN *, refresh_screen)
3648
#ifndef NO_OPTION_MENU
3649
if (!LYUseFormsOptions) {
3650
BOOLEAN LYUseDefaultRawMode_flag = LYUseDefaultRawMode;
3651
BOOLEAN LYSelectPopups_flag = LYSelectPopups;
3652
BOOLEAN verbose_img_flag = verbose_img;
3653
BOOLEAN keypad_mode_flag = (BOOL) keypad_mode;
3654
BOOLEAN show_dotfiles_flag = show_dotfiles;
3655
BOOLEAN user_mode_flag = (BOOL) user_mode;
3656
int CurrentAssumeCharSet_flag = UCLYhndl_for_unspec;
3657
int CurrentCharSet_flag = current_char_set;
3658
int HTfileSortMethod_flag = HTfileSortMethod;
3659
char *CurrentUserAgent = NULL;
3660
char *CurrentNegoLanguage = NULL;
3661
char *CurrentNegoCharset = NULL;
3662
StrAllocCopy(CurrentUserAgent, (LYUserAgent ?
3664
StrAllocCopy(CurrentNegoLanguage, (language ?
3666
StrAllocCopy(CurrentNegoCharset, (pref_charset ?
3667
pref_charset : ""));
3669
LYoptions(); /** do the old-style options stuff **/
3671
if (keypad_mode_flag != keypad_mode ||
3672
(user_mode_flag != user_mode &&
3673
(user_mode_flag == NOVICE_MODE ||
3674
user_mode == NOVICE_MODE)) ||
3675
(((HTfileSortMethod_flag != HTfileSortMethod) ||
3676
(show_dotfiles_flag != show_dotfiles)) &&
3677
(isFILE_URL(curdoc.address) ||
3678
isFTP_URL(curdoc.address))) ||
3679
CurrentCharSet_flag != current_char_set ||
3680
CurrentAssumeCharSet_flag != UCLYhndl_for_unspec ||
3681
verbose_img_flag != verbose_img ||
3682
LYUseDefaultRawMode_flag != LYUseDefaultRawMode ||
3683
LYSelectPopups_flag != LYSelectPopups ||
3684
((strcmp(CurrentUserAgent, (LYUserAgent ?
3685
LYUserAgent : "")) ||
3686
strcmp(CurrentNegoLanguage, (language ?
3688
strcmp(CurrentNegoCharset, (pref_charset ?
3689
pref_charset : ""))) &&
3690
(!strncmp(curdoc.address, "http", 4) ||
3691
isLYNXCGI(curdoc.address)))) {
3693
BOOLEAN canreparse_post = FALSE;
3696
* Check if this is a reply from a POST, and if so,
3697
* seek confirmation of reload if the safe element
3700
if ((curdoc.post_data != NULL &&
3701
curdoc.safe != TRUE) &&
3702
#ifdef USE_SOURCE_CACHE
3703
(!(canreparse_post = HTcan_reparse_document())) &&
3705
confirm_post_resub(curdoc.address, curdoc.title,
3707
HTInfoMsg(WILL_NOT_RELOAD_DOC);
3709
copy_address(&newdoc, &curdoc);
3710
if (((strcmp(CurrentUserAgent, (LYUserAgent ?
3711
LYUserAgent : "")) ||
3712
strcmp(CurrentNegoLanguage, NonNull(language)) ||
3713
strcmp(CurrentNegoCharset, NonNull(pref_charset))) &&
3714
(strncmp(curdoc.address, "http", 4) == 0 ||
3715
!isLYNXCGI(curdoc.address) == 0))) {
3717
* An option has changed which may influence
3718
* content negotiation, and the resource is from
3719
* a http or https or lynxcgi URL (the only protocols
3720
* which currently do anything with this information).
3721
* Set reloading = TRUE so that proxy caches will be
3722
* flushed, which is necessary until the time when
3723
* all proxies understand HTTP 1.1 Vary: and all
3724
* Servers properly use it... Treat like
3725
* case LYK_RELOAD (see comments there). - KW
3729
if (HTisDocumentSource()) {
3730
srcmode_for_next_retrieval(1);
3732
#ifdef USE_SOURCE_CACHE
3733
if (reloading == FALSE) {
3734
/* one more attempt to be smart enough: */
3735
if (reparse_document()) {
3736
FREE(CurrentUserAgent);
3737
FREE(CurrentNegoLanguage);
3738
FREE(CurrentNegoCharset);
3743
if (canreparse_post &&
3744
confirm_post_resub(curdoc.address, curdoc.title,
3746
if (HTisDocumentSource()) {
3747
srcmode_for_next_retrieval(0);
3749
FREE(CurrentUserAgent);
3750
FREE(CurrentNegoLanguage);
3751
FREE(CurrentNegoCharset);
3755
HEAD_request = HTLoadedDocumentIsHEAD();
3756
HText_setNoCache(HTMainText);
3757
#ifdef NO_ASSUME_SAME_DOC
3761
newdoc.line = curdoc.line;
3762
newdoc.link = curdoc.link;
3763
#endif /* NO_ASSUME_SAME_DOC */
3764
LYforce_no_cache = TRUE;
3765
free_address(&curdoc); /* So it doesn't get pushed. */
3768
FREE(CurrentUserAgent);
3769
FREE(CurrentNegoLanguage);
3770
FREE(CurrentNegoCharset);
3771
*refresh_screen = TRUE; /* to repaint screen */
3773
} /* end if !LYUseFormsOptions */
3774
#endif /* !NO_OPTION_MENU */
3775
#ifndef NO_OPTION_FORMS
3777
* Generally stolen from LYK_COOKIE_JAR. Options menu handling is
3778
* done in postoptions(), called from getfile() currently.
3780
* postoptions() is also responsible for reloading the document
3781
* before the 'options menu' but only when (a few) important
3782
* options were changed.
3784
* It is critical that post_data is freed here since the
3785
* submission of changed options is done via the same protocol as
3789
* Don't do if already viewing options page.
3791
if (!LYIsUIPage(curdoc.address, UIP_OPTIONS_MENU)) {
3793
set_address(&newdoc, "LYNXOPTIONS:/");
3794
LYFreePostData(&newdoc);
3795
FREE(newdoc.bookmark);
3796
newdoc.isHEAD = FALSE;
3797
newdoc.safe = FALSE;
3798
newdoc.internal_link = FALSE;
3799
LYforce_no_cache = TRUE;
3800
/* change to 'if (check_realm && !LYValidate)' and
3801
make change near top of getfile to forbid
3802
using forms options menu with -validate: - kw */
3803
if (LYValidate || check_realm) {
3808
* If already in the options menu, get out.
3810
*cmd = LYK_PREV_DOC;
3813
#endif /* !NO_OPTION_FORMS */
3817
PRIVATE void handle_NEXT_DOC NOARGS
3819
if (LYhist_next(&curdoc, &newdoc)) {
3820
free_address(&curdoc); /* avoid push */
3823
HTUserMsg(gettext("No next document present"));
3826
PRIVATE void handle_LYK_NEXT_LINK ARGS3(
3831
if (curdoc.link < nlinks-1) { /* next link */
3832
LYhighlight(OFF, curdoc.link, prev_target);
3835
* Move to different textarea if TAB in textarea.
3837
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
3838
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE &&
3840
int thisgroup = links[curdoc.link].l_form->number;
3841
char *thisname = links[curdoc.link].l_form->name;
3844
while ((curdoc.link < nlinks-1) &&
3845
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
3846
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE &&
3847
links[curdoc.link].l_form->number == thisgroup &&
3848
sametext(links[curdoc.link].l_form->name, thisname));
3854
#endif /* FASTTAB */
3856
* At the bottom of list and there is only one page.
3857
* Move to the top link on the page.
3859
} else if (!more && Newline == 1 && curdoc.link == nlinks-1) {
3862
} else if (more) { /* next page */
3863
Newline += (display_lines);
3865
} else if (*old_c != real_c) {
3867
HTInfoMsg(ALREADY_AT_END);
3871
PRIVATE void handle_LYK_NEXT_PAGE ARGS2(
3876
Newline += display_lines;
3877
} else if (curdoc.link < nlinks-1) {
3878
set_curdoc_link(nlinks - 1);
3879
} else if (*old_c != real_c) {
3881
HTInfoMsg(ALREADY_AT_END);
3885
PRIVATE BOOLEAN handle_LYK_NOCACHE ARGS2(
3890
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
3891
links[curdoc.link].l_form->type != F_SUBMIT_TYPE &&
3892
links[curdoc.link].l_form->type != F_IMAGE_SUBMIT_TYPE &&
3893
links[curdoc.link].l_form->type != F_TEXT_SUBMIT_TYPE) {
3894
if (*old_c != real_c) {
3896
HTUserMsg(NOT_ON_SUBMIT_OR_LINK);
3900
LYforce_no_cache = TRUE;
3907
PRIVATE void handle_LYK_PREV_LINK ARGS3(
3912
if (curdoc.link > 0) { /* previous link */
3913
set_curdoc_link(curdoc.link - 1);
3916
curdoc.link==0 && Newline==1) { /* at the top of list */
3918
* If there is only one page of data and the user
3919
* goes off the top, just move the cursor to last link on
3922
set_curdoc_link(nlinks - 1);
3924
} else if (curdoc.line > 1) { /* previous page */
3926
* Go back to the previous page.
3928
int scrollamount = (Newline > display_lines ?
3929
display_lines : Newline - 1);
3930
Newline -= scrollamount;
3931
if (scrollamount < display_lines &&
3932
nlinks > 0 && curdoc.link == 0 &&
3933
links[0].ly - 1 + scrollamount <= display_lines) {
3934
newdoc.link = HText_LinksInLines(HTMainText,
3941
} else if (*old_c != real_c) {
3943
HTInfoMsg(ALREADY_AT_BEGIN);
3947
PRIVATE int handle_PREV_DOC ARGS3(
3952
if (nhist > 0) { /* if there is anything to go back to */
3954
* Check if the previous document is a reply from a POST,
3955
* and if so, seek confirmation of resubmission if the safe
3956
* element is not set and the document is not still in the
3957
* cache or LYresubmit_posts is set. If not confirmed and
3958
* it is not the startfile, pop it so we go to the yet
3959
* previous document, until we're OK or reach the startfile.
3960
* If we reach the startfile and its not OK or we don't get
3961
* confirmation, cancel. - FM
3964
HTParentAnchor *tmpanchor;
3966
BOOLEAN conf = FALSE, first = TRUE;
3968
HTLastConfirmCancelled(); /* reset flag */
3971
if (HDOC(nhist - 1).post_data == NULL) {
3974
WWWDoc.address = HDOC(nhist - 1).address;
3975
WWWDoc.post_data = HDOC(nhist - 1).post_data;
3976
WWWDoc.post_content_type =
3977
HDOC(nhist - 1).post_content_type;
3978
WWWDoc.bookmark = HDOC(nhist - 1).bookmark;
3979
WWWDoc.isHEAD = HDOC(nhist - 1).isHEAD;
3980
WWWDoc.safe = HDOC(nhist - 1).safe;
3981
tmpanchor = HTAnchor_findAddress(&WWWDoc);
3982
if (HTAnchor_safe(tmpanchor)) {
3985
if (((text = (HText *)HTAnchor_document(tmpanchor)) == NULL &&
3986
(isLYNXIMGMAP(WWWDoc.address) ||
3987
(conf = confirm_post_resub(WWWDoc.address,
3988
HDOC(nhist - 1).title,
3991
((LYresubmit_posts && !conf &&
3992
(NONINTERNAL_OR_PHYS_DIFFERENT(
3993
(DocInfo *)&history[(nhist - 1)],
3995
NONINTERNAL_OR_PHYS_DIFFERENT(
3996
(DocInfo *)&history[(nhist - 1)],
3998
!confirm_post_resub(WWWDoc.address,
3999
HDOC(nhist - 1).title,
4001
if (HTLastConfirmCancelled()) {
4002
if (!first && curdoc.internal_link)
4003
free_address(&curdoc);
4004
*cmd = LYK_DO_NOTHING;
4008
HTInfoMsg(CANCELLED);
4010
*cmd = LYK_DO_NOTHING;
4013
HTUserMsg2(WWW_SKIP_MESSAGE, WWWDoc.address);
4014
do { /* Should be LYhist_prev when _next supports */
4015
LYpop(&curdoc); /* skipping of forms */
4016
} while (nhist > 1 && !are_different(
4017
(DocInfo *)&history[(nhist - 1)],
4019
first = FALSE; /* have popped at least one */
4024
* Break from loop; if user just confirmed to
4025
* load again because document wasn't in cache,
4026
* set LYforce_no_cache to avoid unnecessary
4027
* repeat question down the road. - kw
4030
LYforce_no_cache = TRUE;
4036
curdoc.internal_link = FALSE;
4039
* Set newdoc.address to empty to pop a file.
4041
LYhist_prev_register(&curdoc); /* Why not call _prev instead of zeroing address? */
4042
free_address(&newdoc);
4043
#ifdef DIRED_SUPPORT
4044
if (lynx_edit_mode) {
4047
#endif /* DIRED_SUPPORT */
4048
} else if (child_lynx == TRUE) {
4049
return(1); /* exit on left arrow in main screen */
4051
} else if (*old_c != real_c) {
4053
HTUserMsg(ALREADY_AT_FIRST);
4058
PRIVATE void handle_LYK_PREV_PAGE ARGS2(
4063
Newline -= display_lines;
4064
} else if (curdoc.link > 0) {
4066
} else if (*old_c != real_c) {
4068
HTInfoMsg(ALREADY_AT_BEGIN);
4072
PRIVATE void handle_LYK_PRINT ARGS3(
4073
BOOLEAN *, ForcePush,
4078
if (*old_c != real_c) {
4080
HTUserMsg(PRINT_DISABLED);
4086
* Don't do if already viewing print options page.
4088
if (!LYIsUIPage(curdoc.address, UIP_PRINT_OPTIONS)
4089
&& print_options(&newdoc.address,
4090
curdoc.address, HText_getNumOfLines()) >= 0) {
4091
LYRegisterUIPage(newdoc.address, UIP_PRINT_OPTIONS);
4092
StrAllocCopy(newdoc.title, PRINT_OPTIONS_TITLE);
4093
LYFreePostData(&newdoc);
4094
FREE(newdoc.bookmark);
4095
newdoc.isHEAD = FALSE;
4096
newdoc.safe = FALSE;
4097
*ForcePush = TRUE; /* see LYpush() and print_options() */
4103
PRIVATE BOOLEAN handle_LYK_QUIT NOARGS
4107
if (LYQuitDefaultYes == TRUE) {
4108
c = HTConfirmDefault(REALLY_QUIT, YES);
4110
c = HTConfirmDefault(REALLY_QUIT, NO);
4112
if (LYQuitDefaultYes == TRUE) {
4116
HTInfoMsg(NO_CANCEL);
4118
} else if (c == YES) {
4121
HTInfoMsg(NO_CANCEL);
4126
PRIVATE BOOLEAN handle_LYK_RAW_TOGGLE ARGS1(
4129
if (HTLoadedDocumentCharset()) {
4130
HTUserMsg(gettext("charset for this document specified explicitly, sorry..."));
4133
LYUseDefaultRawMode = (BOOL) !LYUseDefaultRawMode;
4134
HTUserMsg(LYRawMode ? RAWMODE_OFF : RAWMODE_ON);
4135
HTMLSetCharacterHandling(current_char_set);
4136
return reparse_or_reload(cmd);
4140
PRIVATE void handle_LYK_RELOAD ARGS1(
4144
* Check if this is a reply from a POST, and if so,
4145
* seek confirmation if the safe element is not set. - FM
4147
if ((curdoc.post_data != NULL &&
4148
curdoc.safe != TRUE) &&
4149
HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
4150
HTInfoMsg(CANCELLED);
4155
* Check to see if should reload source, or load html
4158
if (HTisDocumentSource()) {
4159
if ((forced_UCLYhdnl = HTMainText_Get_UCLYhndl()) >= 0)
4160
force_old_UCLYhndl_on_reload = TRUE;
4161
srcmode_for_next_retrieval(1);
4164
HEAD_request = HTLoadedDocumentIsHEAD();
4165
HText_setNoCache(HTMainText);
4166
#ifdef NO_ASSUME_SAME_DOC
4168
* Don't assume the reloaded document will be the same. - FM
4174
* Do assume the reloaded document will be the same. - FM
4175
* (I don't remember all the reasons why we couldn't assume
4176
* this. As the problems show up, we'll try to fix them,
4177
* or add warnings. - FM)
4179
newdoc.line = curdoc.line;
4180
newdoc.link = curdoc.link;
4181
#endif /* NO_ASSUME_SAME_DOC */
4182
free_address(&curdoc); /* so it doesn't get pushed */
4184
lynx_force_repaint();
4187
* Reload should force a cache refresh on a proxy.
4188
* -- Ari L. <luotonen@dxcern.cern.ch>
4190
* -- but only if this was really a reload requested by
4191
* the user, not if we jumped here to handle reloading for
4192
* INLINE_TOGGLE, IMAGE_TOGGLE, RAW_TOGGLE, etc. - KW
4194
if (real_cmd == LYK_RELOAD)
4200
#ifdef DIRED_SUPPORT
4201
PRIVATE void handle_LYK_REMOVE ARGS1(
4202
BOOLEAN *, refresh_screen)
4204
if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
4205
int linkno = curdoc.link; /* may be changed in local_remove - kw */
4206
local_remove(&curdoc);
4207
if (LYAutoUncacheDirLists >= 1)
4208
do_cleanup_after_delete();
4209
else if (curdoc.link != linkno)
4210
*refresh_screen = TRUE;
4213
#endif /* DIRED_SUPPORT */
4215
PRIVATE void handle_LYK_RIGHT_LINK NOARGS
4217
if (curdoc.link<nlinks-1 &&
4218
links[curdoc.link].ly == links[curdoc.link+1].ly) {
4219
set_curdoc_link(curdoc.link + 1);
4223
PRIVATE void handle_LYK_SHELL ARGS3(
4224
BOOLEAN *, refresh_screen,
4230
printf("%s\r\n", SPAWNING_MSG);
4231
#if defined(__CYGWIN__)
4232
/* handling "exec $SHELL" does not work if $SHELL is null */
4233
if (LYGetEnv("SHELL") == NULL) {
4237
LYSystem(LYSysShell());
4239
*refresh_screen = TRUE; /* for an HText_pageDisplay() */
4241
if (*old_c != real_c) {
4243
HTUserMsg(SPAWNING_DISABLED);
4248
PRIVATE void handle_LYK_SOFT_DQUOTES NOARGS
4250
#ifdef USE_SOURCE_CACHE
4251
if (!HTcan_reparse_document()) {
4254
* Check if this is a reply from a POST, and if so,
4255
* seek confirmation of reload if the safe element
4258
if ((curdoc.post_data != NULL &&
4259
curdoc.safe != TRUE) &&
4260
confirm_post_resub(curdoc.address, NULL, 1, 1) == FALSE) {
4261
HTInfoMsg(WILL_NOT_RELOAD_DOC);
4263
HText_setNoCache(HTMainText);
4264
move_address(&newdoc, &curdoc);
4265
newdoc.line = curdoc.line;
4266
newdoc.link = curdoc.link;
4268
#ifdef USE_SOURCE_CACHE
4269
} /* end if no bypass */
4271
soft_dquotes = !soft_dquotes;
4272
HTUserMsg(soft_dquotes ?
4273
SOFT_DOUBLE_QUOTE_ON : SOFT_DOUBLE_QUOTE_OFF);
4274
#ifdef USE_SOURCE_CACHE
4275
(void)reparse_document();
4280
PRIVATE void handle_LYK_SOURCE ARGS1(
4281
char **, ownerS_address_p)
4284
* Check if this is a reply from a POST, and if so,
4285
* seek confirmation if the safe element is not set. - FM
4287
#ifdef USE_SOURCE_CACHE
4288
BOOLEAN canreparse_post = FALSE;
4290
if ((curdoc.post_data != NULL &&
4291
curdoc.safe != TRUE) &&
4292
#ifdef USE_SOURCE_CACHE
4293
(!(canreparse_post = HTcan_reparse_document())) &&
4295
(curdoc.isHEAD ? HTConfirm(CONFIRM_POST_RESUBMISSION) :
4296
confirm_post_resub(curdoc.address, curdoc.title, 1, 1)) == FALSE) {
4297
HTInfoMsg(CANCELLED);
4301
if (HTisDocumentSource()) {
4302
srcmode_for_next_retrieval(-1);
4304
if (HText_getOwner())
4305
StrAllocCopy(*ownerS_address_p, HText_getOwner());
4306
LYUCPushAssumed(HTMainAnchor);
4307
srcmode_for_next_retrieval(1);
4310
#ifdef USE_SOURCE_CACHE
4311
if (reparse_document()) {
4313
* These normally get cleaned up after getfile() returns;
4314
* since we're not calling getfile(), we have to clean them
4315
* up ourselves. -dsb
4317
HTOutputFormat = WWW_PRESENT;
4318
#ifdef USE_PRETTYSRC
4323
FREE(*ownerS_address_p); /* not used with source_cache */
4324
LYUCPopAssumed(); /* probably a right place here */
4325
HTMLSetCharacterHandling(current_char_set); /* restore now */
4328
} else if (canreparse_post) {
4329
srcmode_for_next_retrieval(0);
4330
LYUCPopAssumed(); /* probably a right place here */
4336
StrAllocCopy(newdoc.title, curdoc.title);
4337
free_address(&curdoc); /* so it doesn't get pushed */
4338
LYforce_no_cache = TRUE;
4341
PRIVATE void handle_LYK_SWITCH_DTD NOARGS
4343
#ifdef USE_SOURCE_CACHE
4344
BOOLEAN canreparse = FALSE;
4345
if (!(canreparse = HTcan_reparse_document())) {
4348
* Check if this is a reply from a POST, and if so,
4349
* seek confirmation of reload if the safe element
4350
* is not set. - FM, kw
4352
if ((curdoc.post_data != NULL &&
4353
curdoc.safe != TRUE) &&
4354
confirm_post_resub(curdoc.address, NULL, 1, 1) == FALSE) {
4355
HTInfoMsg(WILL_NOT_RELOAD_DOC);
4358
* If currently viewing preparsed source, switching
4359
* to the other DTD parsing may show source differences,
4360
* so stay in source view - kw
4363
/* NOTE: this conditional can be considered incorrect -
4364
current behaviour - when viewing source and
4365
LYPreparsedSource==TRUE, pressing ^V will toggle parser mode
4366
AND switch back from the source view to presentation view.-HV
4368
if (HTisDocumentSource() && LYPreparsedSource) {
4369
srcmode_for_next_retrieval(1);
4371
HText_setNoCache(HTMainText);
4372
move_address(&newdoc, &curdoc);
4373
#ifdef NO_ASSUME_SAME_DOC
4377
newdoc.line = curdoc.line;
4378
newdoc.link = curdoc.link;
4379
#endif /* NO_ASSUME_SAME_DOC */
4381
#ifdef USE_SOURCE_CACHE
4382
} /* end if no bypass */
4385
HTSwitchDTD(!Old_DTD);
4386
HTUserMsg(Old_DTD ? USING_DTD_0 : USING_DTD_1);
4387
#ifdef USE_SOURCE_CACHE
4389
if (HTisDocumentSource() && LYPreparsedSource) {
4390
srcmode_for_next_retrieval(1);
4392
if (!reparse_document()) {
4393
srcmode_for_next_retrieval(0);
4400
#ifdef DIRED_SUPPORT
4401
PRIVATE void handle_LYK_TAG_LINK NOARGS
4403
if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
4404
if (!strcmp(LYGetHiliteStr(curdoc.link, 0), ".."))
4405
return; /* Never tag the parent directory */
4406
if (dir_list_style == MIXED_STYLE) {
4407
if (!strcmp(LYGetHiliteStr(curdoc.link, 0), "../"))
4409
} else if (!strncmp(LYGetHiliteStr(curdoc.link, 0), "Up to ", 6))
4413
* HTList-based management of tag list, see LYLocal.c - KW
4415
HTList * t1 = tagged;
4416
char * tagname = NULL;
4417
BOOLEAN found = FALSE;
4419
while ((tagname = (char *)HTList_nextObject(t1)) != NULL) {
4420
if (!strcmp(links[curdoc.link].lname, tagname)) {
4422
HTList_removeObject(tagged, tagname);
4424
tagflag(OFF,curdoc.link);
4430
tagged = HTList_new();
4432
StrAllocCopy(tagname,links[curdoc.link].lname);
4433
HTList_addObject(tagged,tagname);
4434
tagflag(ON,curdoc.link);
4437
if (curdoc.link < nlinks-1) {
4438
set_curdoc_link(curdoc.link + 1);
4439
} else if (!more && Newline == 1 && curdoc.link == nlinks-1) {
4441
} else if (more) { /* next page */
4442
Newline += (display_lines);
4446
#endif /* DIRED_SUPPORT */
4448
PRIVATE void handle_LYK_TOGGLE_HELP NOARGS
4450
if (user_mode == NOVICE_MODE) {
4451
toggle_novice_line();
4456
PRIVATE void handle_LYK_TOOLBAR ARGS4(
4457
BOOLEAN *, try_internal,
4458
BOOLEAN *, force_load,
4463
char *toolbar = NULL;
4465
if (!HText_hasToolbar(HTMainText)) {
4466
if (*old_c != real_c) {
4468
HTUserMsg(NO_TOOLBAR);
4470
} else if (*old_c != real_c) {
4472
cp = trimPoundSelector(curdoc.address);
4473
HTSprintf0(&toolbar, "%s#%s", curdoc.address, LYToolbarName);
4474
restorePoundSelector(cp);
4475
set_address(&newdoc, toolbar);
4477
*try_internal = TRUE;
4478
*force_load = TRUE; /* force MainLoop to reload */
4482
PRIVATE void handle_LYK_TRACE_LOG ARGS1(
4483
BOOLEAN *, trace_flag_ptr)
4485
#ifndef NO_LYNX_TRACE
4487
* Check whether we've started a TRACE log
4488
* in this session. - FM
4490
if (LYTraceLogFP == NULL) {
4491
HTUserMsg(NO_TRACELOG_STARTED);
4496
* Don't do if already viewing the TRACE log. - FM
4498
if (LYIsUIPage(curdoc.address, UIP_TRACELOG))
4502
* If TRACE mode is on, turn it off during this fetch of the
4503
* TRACE log, so we don't enter stuff about this fetch, and
4504
* set a flag for turning it back on when we return to this
4505
* loop. Note that we'll miss any messages about memory
4506
* exhaustion if it should occur. It seems unlikely that
4507
* anything else bad might happen, but if it does, we'll
4508
* miss messages about that too. We also fflush(), close,
4509
* and open it again, to make sure all stderr messages thus
4510
* far will be in the log. - FM
4512
if (!LYReopenTracelog(trace_flag_ptr))
4515
LYLocalFileToURL (&(newdoc.address), LYTraceLogPath);
4516
LYRegisterUIPage(newdoc.address, UIP_TRACELOG);
4517
StrAllocCopy(newdoc.title, LYNX_TRACELOG_TITLE);
4518
LYFreePostData(&newdoc);
4519
FREE(newdoc.bookmark);
4520
newdoc.isHEAD = FALSE;
4521
newdoc.safe = FALSE;
4522
newdoc.internal_link = FALSE;
4523
if (LYValidate || check_realm) {
4526
LYforce_no_cache = TRUE;
4528
HTUserMsg(TRACE_DISABLED);
4529
#endif /* NO_LYNX_TRACE */
4532
#ifdef DIRED_SUPPORT
4533
PRIVATE void handle_LYK_UPLOAD NOARGS
4536
* Don't do if already viewing upload options page.
4538
if (LYIsUIPage(curdoc.address, UIP_UPLOAD_OPTIONS))
4541
if (lynx_edit_mode && !no_dired_support) {
4542
LYUpload_options(&(newdoc.address), curdoc.address);
4543
StrAllocCopy(newdoc.title, UPLOAD_OPTIONS_TITLE);
4544
LYFreePostData(&newdoc);
4545
FREE(newdoc.bookmark);
4546
newdoc.isHEAD = FALSE;
4547
newdoc.safe = FALSE;
4548
newdoc.internal_link = FALSE;
4550
* Uncache the current listing so that it will
4551
* be updated to included the uploaded file if
4552
* placed in the current directory. - FM
4557
#endif /* DIRED_SUPPORT */
4559
PRIVATE void handle_LYK_UP_HALF ARGS3(
4565
int scrollamount = display_lines/2;
4566
if (Newline - scrollamount < 1)
4567
scrollamount = Newline - 1;
4568
Newline -= scrollamount;
4569
if (nlinks > 0 && curdoc.link > -1) {
4570
if (links[curdoc.link].ly + scrollamount <= display_lines) {
4571
newdoc.link = curdoc.link +
4572
HText_LinksInLines(HTMainText,
4579
} else if (*old_c != real_c) {
4581
HTInfoMsg(ALREADY_AT_BEGIN);
4585
PRIVATE void handle_LYK_UP_LINK ARGS4(
4591
if (curdoc.link > 0 &&
4592
(links[0].ly != links[curdoc.link].ly ||
4593
!HText_LinksInLines(HTMainText, 1, Newline - 1))) {
4594
/* more links before this on screen, and first of them on
4595
a different line or no previous links before this screen? */
4598
if (*follow_col == -1) {
4599
char *text = LYGetHiliteStr(curdoc.link, 0);
4600
*follow_col = links[curdoc.link].lx;
4603
*follow_col += strlen(text) / 2;
4606
newlink = find_link_near_col(*follow_col, -1);
4608
set_curdoc_link(newlink);
4609
} else if (*old_c != real_c) {
4611
HTUserMsg(NO_LINKS_ABOVE);
4614
} else if (curdoc.line > 1 && Newline > 1) { /* previous page */
4615
int scrollamount = (Newline > display_lines ?
4616
display_lines : Newline - 1);
4617
Newline -= scrollamount;
4618
if (scrollamount < display_lines &&
4619
nlinks > 0 && curdoc.link > -1 &&
4620
links[0].ly -1 + scrollamount <= display_lines) {
4621
newdoc.link = HText_LinksInLines(HTMainText,
4628
} else if (*old_c != real_c) {
4630
HTInfoMsg(ALREADY_AT_BEGIN);
4634
PRIVATE void handle_LYK_UP_TWO ARGS3(
4640
int scrollamount = (Newline > 2 ? 2 : 1);
4641
Newline -= scrollamount;
4642
if (nlinks > 0 && curdoc.link > -1) {
4643
if (links[curdoc.link].ly + scrollamount <= display_lines) {
4644
newdoc.link = curdoc.link +
4645
HText_LinksInLines(HTMainText,
4646
Newline, scrollamount);
4651
} else if (*old_c != real_c) {
4653
HTInfoMsg(ALREADY_AT_BEGIN);
4657
PRIVATE void handle_LYK_VIEW_BOOKMARK ARGS3(
4658
BOOLEAN *, refresh_screen,
4665
if (*old_c != real_c) {
4667
HTUserMsg(BOOKMARKS_DISABLED);
4673
* See if a bookmark exists.
4674
* If it does replace newdoc.address with its name.
4676
if ((cp = get_bookmark_filename(&newdoc.address)) != NULL) {
4677
if (*cp == '\0' || !strcmp(cp, " ") ||
4678
!strcmp(curdoc.address, newdoc.address)) {
4679
if (LYMultiBookmarks != MBM_OFF)
4680
*refresh_screen = TRUE;
4683
#ifdef KANJI_CODE_OVERRIDE
4684
if (HTCJK == JAPANESE) {
4685
last_kcode = NOKANJI; /* AUTO */
4688
LYforce_no_cache = TRUE; /*force the document to be reloaded*/
4689
StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
4690
StrAllocCopy(newdoc.bookmark, BookmarkPage);
4691
LYFreePostData(&newdoc);
4692
newdoc.isHEAD = FALSE;
4693
newdoc.safe = FALSE;
4694
newdoc.internal_link = FALSE;
4696
if (*old_c != real_c) {
4698
LYMBM_statusline(BOOKMARKS_NOT_OPEN);
4700
if (LYMultiBookmarks != MBM_OFF) {
4701
*refresh_screen = TRUE;
4707
PRIVATE BOOLEAN handle_LYK_VLINKS ARGS2(
4709
BOOLEAN *, newdoc_link_is_absolute)
4713
if (LYIsUIPage(curdoc.address, UIP_VLINKS)) {
4715
* Already viewing visited links page, so get out.
4717
*cmd = LYK_PREV_DOC;
4722
* Print visited links page to file.
4724
c = LYShowVisitedLinks(&newdoc.address);
4726
HTUserMsg(VISITED_LINKS_EMPTY);
4729
StrAllocCopy(newdoc.title, VISITED_LINKS_TITLE);
4730
LYFreePostData(&newdoc);
4731
FREE(newdoc.bookmark);
4732
newdoc.isHEAD = FALSE;
4733
newdoc.safe = FALSE;
4734
newdoc.internal_link = FALSE;
4736
/* Select a correct link. */
4737
*newdoc_link_is_absolute = TRUE;
4738
newdoc.link = c - 1;
4740
if (LYValidate || check_realm) {
4742
StrAllocCopy(lynxlinksfile, newdoc.address);
4747
PUBLIC void handle_LYK_WHEREIS ARGS2(
4749
BOOLEAN *, refresh_screen)
4751
BOOLEAN have_target_onscreen = (BOOLEAN) (*prev_target != '\0' &&
4752
HText_pageHasPrevTarget());
4754
int oldcur = curdoc.link; /* temporarily remember */
4755
char *remember_old_target = NULL;
4756
if (have_target_onscreen)
4757
StrAllocCopy(remember_old_target, prev_target);
4759
StrAllocCopy(remember_old_target, "");
4761
if (cmd == LYK_WHEREIS) {
4763
* Reset prev_target to force prompting
4764
* for a new search string and to turn
4765
* off highlighting if no search string
4766
* is entered by the user.
4768
*prev_target = '\0';
4770
found = textsearch(&curdoc, prev_target, sizeof(prev_target)-1,
4771
(cmd == LYK_WHEREIS)
4773
: ((cmd == LYK_NEXT)
4778
* Force a redraw to ensure highlighting of hits
4779
* even when found on the same page, or clearing
4780
* of highlighting if the default search string
4781
* was erased without replacement. - FM
4784
** Well let's try to avoid it at least in a few cases
4785
** where it is not needed. - kw
4787
if (www_search_result >= 0 && www_search_result != curdoc.line) {
4788
*refresh_screen = TRUE; /* doesn't really matter */
4789
} else if (!found) {
4790
*refresh_screen = have_target_onscreen;
4791
} else if (!have_target_onscreen && found) {
4792
*refresh_screen = TRUE;
4793
} else if (www_search_result == curdoc.line &&
4794
curdoc.link == oldcur &&
4795
curdoc.link >= 0 && nlinks > 0 &&
4796
links[curdoc.link].ly >= (display_lines/3)) {
4797
*refresh_screen = TRUE;
4798
} else if ((case_sensitive && 0!=strcmp(prev_target,
4799
remember_old_target)) ||
4800
(!case_sensitive && 0!=strcasecomp8(prev_target,
4801
remember_old_target))) {
4802
*refresh_screen = TRUE;
4804
FREE(remember_old_target);
4808
* Get a number from the user and follow that link number.
4810
PRIVATE void handle_LYK_digit ARGS6(
4812
BOOLEAN *, force_load,
4813
char *, user_input_buffer,
4816
BOOLEAN *, try_internal GCC_UNUSED)
4818
int lindx = ((nlinks > 0) ? curdoc.link : 0);
4822
/* pass cur line num for use in follow_link_number()
4823
* Note: Current line may not equal links[cur].line
4825
number = curdoc.line;
4826
switch (follow_link_number(c, lindx, &newdoc, &number)) {
4829
* Follow a normal link.
4831
set_address(&newdoc, links[lindx].lname);
4832
StrAllocCopy(newdoc.title, LYGetHiliteStr(lindx, 0));
4833
#ifndef DONT_TRACK_INTERNAL_LINKS
4835
* For internal links, retain POST content if present.
4836
* If we are on the List Page, prevent pushing it on
4837
* the history stack. Otherwise set try_internal to
4838
* signal that the top of the loop should attempt to
4839
* reposition directly, without calling getfile. - kw
4841
if (links[lindx].type == WWW_INTERN_LINK_TYPE) {
4842
LYinternal_flag = TRUE;
4843
newdoc.internal_link = TRUE;
4844
if (LYIsListpageTitle(NonNull(curdoc.title)) &&
4845
(LYIsUIPage(curdoc.address, UIP_LIST_PAGE) ||
4846
LYIsUIPage(curdoc.address, UIP_ADDRLIST_PAGE))) {
4847
if (check_history()) {
4848
LYinternal_flag = TRUE;
4850
HTLastConfirmCancelled(); /* reset flag */
4851
if (!confirm_post_resub(newdoc.address,
4853
(LYresubmit_posts &&
4854
HText_POSTReplyLoaded(&newdoc)) ? 1 : 2,
4856
if (HTLastConfirmCancelled() ||
4857
(LYresubmit_posts &&
4858
!HText_POSTReplyLoaded(&newdoc))) {
4859
/* cancel the whole thing */
4860
LYforce_no_cache = FALSE;
4862
copy_address(&newdoc, &curdoc);
4863
StrAllocCopy(newdoc.title, curdoc.title);
4864
newdoc.internal_link = curdoc.internal_link;
4865
HTInfoMsg(CANCELLED);
4867
HText_pageDisplay(curdoc.line, prev_target);
4869
} else if (LYresubmit_posts) {
4870
/* If LYresubmit_posts is set, and the
4871
answer was No, and we have a cached
4872
copy, then use it. - kw */
4873
LYforce_no_cache = FALSE;
4875
/* if No, but not ^C or ^G, drop
4876
* the post data. Maybe the link
4877
* wasn't meant to be internal after
4878
* all, here we can recover from that
4879
* assumption. - kw */
4880
LYFreePostData(&newdoc);
4881
newdoc.internal_link = FALSE;
4882
HTAlert(DISCARDING_POST_DATA);
4887
* Don't push the List Page if we follow an
4888
* internal link given by it. - kw
4890
free_address(&curdoc);
4892
*try_internal = TRUE;
4893
if (!(LYresubmit_posts && newdoc.post_data))
4894
LYinternal_flag = TRUE;
4899
* Free POST content if not an internal link. - kw
4901
LYFreePostData(&newdoc);
4903
#endif /* DONT_TRACK_INTERNAL_LINKS */
4905
* Might be an anchor in the same doc from a POST
4906
* form. If so, don't free the content. -- FM
4908
if (are_different(&curdoc, &newdoc)) {
4909
LYFreePostData(&newdoc);
4910
FREE(newdoc.bookmark);
4911
newdoc.isHEAD = FALSE;
4912
newdoc.safe = FALSE;
4913
if (isLYNXMESSAGES(newdoc.address))
4914
LYforce_no_cache = TRUE;
4916
newdoc.internal_link = FALSE;
4917
*force_load = TRUE; /* force MainLoop to reload */
4920
case DO_GOTOLINK_STUFF:
4922
* Position on a normal link, don't follow it. - KW
4924
Newline = newdoc.line;
4926
if (Newline == curdoc.line) {
4928
* It's a link in the current page. - FM
4930
if (nlinks > 0 && curdoc.link > -1) {
4931
if (curdoc.link == newdoc.link) {
4933
* It's the current link, and presumably
4934
* reflects a typo in the statusline entry,
4935
* so issue a statusline message for the
4936
* typo-prone users (like me 8-). - FM
4938
StrAllocCopy(temp, user_input_buffer);
4939
sprintf(user_input_buffer,
4940
LINK_ALREADY_CURRENT, number);
4941
HTUserMsg(user_input_buffer);
4942
LYstrncpy(user_input_buffer, temp, MAX_LINE - 1);
4946
* It's a different link on this page,
4948
set_curdoc_link(newdoc.link);
4953
break; /* nothing more to do */
4955
case DO_GOTOPAGE_STUFF:
4957
* Position on a page in this document. - FM
4959
Newline = newdoc.line;
4961
if (Newline == curdoc.line) {
4963
* It's the current page, so issue a
4964
* statusline message for the typo-prone
4965
* users (like me 8-). - FM
4968
HTInfoMsg(ALREADY_AT_BEGIN);
4970
HTInfoMsg(ALREADY_AT_END);
4972
StrAllocCopy(temp, user_input_buffer);
4973
sprintf(user_input_buffer,
4974
ALREADY_AT_PAGE, number);
4975
HTUserMsg(user_input_buffer);
4976
LYstrncpy(user_input_buffer, temp, MAX_LINE - 1);
4984
HTUserMsg(BAD_LINK_NUM_ENTERED);
4990
#ifdef SUPPORT_CHDIR
4992
/* original implementation by VH */
4993
PUBLIC void handle_LYK_CHDIR NOARGS
4995
static char buf[LY_MAXPATH];
4999
HTUserMsg(CHDIR_DISABLED);
5003
_statusline(gettext("cd to:"));
5004
/* some people may prefer automatic clearing of the previous user input,
5005
here, to do this, just uncomment next line - VH */
5007
if (LYgetstr(buf, VISIBLE, sizeof(buf)-1, 0) < 0 || !*buf) {
5008
HTInfoMsg(CANCELLED);
5012
if (*buf == '~' && !buf[1]) {
5013
StrAllocCopy(p, Home_Dir());
5014
} else if (*buf == '~') {
5015
HTSprintf0(&p, "%s%s", Home_Dir(), buf+1);
5017
StrAllocCopy(p, buf);
5020
CTRACE((tfp, "changing directory to '%s'\n", p));
5024
HTInfoMsg(COULD_NOT_ACCESS_DIR);
5027
HTInfoMsg(gettext("No such directory"));
5030
HTInfoMsg(gettext("A component of path is not a directory"));
5033
HTInfoMsg(gettext("failed to change directory"));
5037
#ifdef DIRED_SUPPORT
5038
/*if in dired, load content of other directory*/
5039
if (!no_dired_support
5040
&& (lynx_edit_mode || (LYIsUIPage(curdoc.address, UIP_DIRED_MENU)))) {
5041
char buf2[LY_MAXPATH];
5045
LYLocalFileToURL(&addr, buf2);
5047
newdoc.address = addr;
5048
newdoc.isHEAD = FALSE;
5049
StrAllocCopy(newdoc.title, gettext("A URL specified by the user"));
5050
LYFreePostData(&newdoc);
5051
FREE(newdoc.bookmark);
5052
newdoc.safe = FALSE;
5053
newdoc.internal_link = FALSE;
5054
/**force_load = TRUE;*/
5055
if (lynx_edit_mode) {
5060
HTInfoMsg(OPERATION_DONE);
5066
#ifdef USE_CURSES_PADS
5068
* Having jumps larger than this is counter-productive. Indeed, it is natural
5069
* to expect that when the relevant text appears, one would "overshoot" and
5070
* would scroll 3-4 extra full screens. When going back, the "accumulation"
5071
* logic would again start moving in full screens, so one would overshoot
5074
* Going back, one can fix it in 28 keypresses. The relevant text will appear
5075
* on the screen soon enough for the key-repeat to become not that important,
5076
* and we are still moving in smaller steps than when we overshot. Since key
5077
* repeat is not important, even if we overshoot again, it is going to be by 30
5078
* steps, which is easy to fix by reversing the direction again.
5080
PRIVATE int repeat_to_delta ARGS1(int, n)
5082
int threshold = LYcols / 3;
5084
while (threshold > 0) {
5085
if (n >= threshold) {
5089
threshold = (threshold * 2) / 3;
5094
PRIVATE void handle_LYK_SHIFT_LEFT ARGS2(BOOLEAN *, flag, int, count)
5097
HTAlert(SHIFT_VS_LINEWRAP);
5100
if (LYshiftWin > 0) {
5101
LYshiftWin -= repeat_to_delta(count);
5108
PRIVATE void handle_LYK_SHIFT_RIGHT ARGS2(BOOLEAN *, flag, int, count)
5111
HTAlert(SHIFT_VS_LINEWRAP);
5114
LYshiftWin += repeat_to_delta(count);
5118
PRIVATE BOOLEAN handle_LYK_LINEWRAP_TOGGLE ARGS2(
5122
static char *choices[] = {
5123
"Try to fit screen width",
5124
"No line wrap in columns",
5125
"Wrap columns at screen width",
5126
"Wrap columns at 3/4 screen width",
5127
"Wrap columns at 2/3 screen width",
5128
"Wrap columns at 1/2 screen width",
5129
"Wrap columns at 1/3 screen width",
5130
"Wrap columns at 1/4 screen width",
5133
static int wrap[] = {
5136
12, /* In units of 1/12 */
5145
if (LYwin == stdscr)
5148
/* Somehow the mouse is over the number instead of being over the
5149
name, so we decrease x. */
5150
c = LYChoosePopup(!LYwideLines, LYlines /2 - 2, LYcols/2-6,
5151
choices, TABLESIZE(choices) - 1, FALSE, TRUE);
5153
* LYhandlePopupList() wasn't really meant to be used
5154
* outside of old-style Options menu processing. One result of
5155
* mis-using it here is that we have to deal with side-effects
5156
* regarding SIGINT signal handler and the term_options global
5162
LYtableCols = wrap[c];
5164
if (LYwideLines == 0)
5167
HTUserMsg(LYwideLines ? LINEWRAP_OFF : LINEWRAP_ON);
5168
return reparse_or_reload(cmd);
5173
* Here's where we do all the work.
5174
* mainloop is basically just a big switch dependent on the users input.
5175
* I have tried to offload most of the work done here to procedures to
5176
* make it more modular, but this procedure still does a lot of variable
5177
* manipulation. This needs some work to make it neater. - Lou Moutilli
5178
* (memoir from the original Lynx - FM)
5183
#if defined(WIN_EX) /* 1997/10/08 (Wed) 14:52:06 */
5185
#define STRING_MAX 4096
5186
char temp_buff[STRING_MAX];
5188
#define BUFF_MAX 1024
5189
char sjis_buff[BUFF_MAX];
5191
int c = 0, real_c = 0, old_c = 0, pending_form_c = -1;
5192
int cmd = LYK_DO_NOTHING, real_cmd = LYK_DO_NOTHING;
5194
int arrowup = FALSE, show_help = FALSE;
5195
char user_input_buffer[MAX_LINE];
5196
CONST char *cshelpfile = NULL;
5197
BOOLEAN first_file = TRUE;
5198
BOOLEAN popped_doc = FALSE;
5199
BOOLEAN refresh_screen = FALSE;
5200
BOOLEAN force_load = FALSE;
5201
BOOLEAN try_internal = FALSE;
5202
BOOLEAN crawl_ok = FALSE;
5203
BOOLEAN vi_keys_flag = vi_keys;
5204
BOOLEAN emacs_keys_flag = emacs_keys;
5205
BOOLEAN trace_mode_flag = FALSE;
5206
BOOLEAN forced_HTML_mode = LYforce_HTML_mode;
5213
BOOLEAN FirstURLRecall = TRUE;
5215
BOOLEAN ForcePush = FALSE;
5216
BOOLEAN override_LYresubmit_posts = FALSE;
5217
BOOLEAN newdoc_link_is_absolute = FALSE;
5218
BOOLEAN curlink_is_editable;
5219
BOOLEAN use_last_tfpos;
5222
int follow_col = -1, key_count = 0, last_key = 0;
5224
/* "internal" means "within the same document, with certainty".
5225
* It includes a space so it cannot conflict with any (valid) "TYPE"
5226
* attributes on A elements. [According to which DTD, anyway??] - kw
5228
HTInternalLink = HTAtom_for("internal link"); /* init, used as const */
5231
WWW_SOURCE = HTAtom_for("www/source"); /* init, used as const */
5235
* curdoc.address contains the name of the file that is currently open.
5236
* newdoc.address contains the name of the file that will soon be
5237
* opened if it exits.
5238
* prev_target contains the last search string the user searched for.
5239
* newdoc.title contains the link name that the user last chose to get
5240
* into the current link (file).
5242
/* initialize some variables*/
5243
newdoc.address = NULL;
5244
newdoc.title = NULL;
5245
newdoc.post_data = NULL;
5246
newdoc.post_content_type = NULL;
5247
newdoc.bookmark = NULL;
5248
newdoc.internal_link = FALSE;
5249
curdoc.address = NULL;
5250
curdoc.title = NULL;
5251
curdoc.post_data = NULL;
5252
curdoc.post_content_type = NULL;
5253
curdoc.bookmark = NULL;
5254
curdoc.internal_link = FALSE;
5255
#ifdef USE_COLOR_STYLE
5256
curdoc.style = NULL;
5257
newdoc.style = NULL;
5260
user_input_buffer[(sizeof(user_input_buffer) - 1)] = '\0';
5261
*prev_target = '\0';
5262
*user_input_buffer = '\0';
5263
#ifdef LY_FIND_LEAKS
5264
atexit(free_mainloop_variables);
5267
set_address(&newdoc, startfile);
5268
StrAllocCopy(startrealm, startfile);
5269
StrAllocCopy(newdoc.title, gettext("Entry into main screen"));
5270
newdoc.isHEAD = FALSE;
5271
newdoc.safe = FALSE;
5276
if (TRACE && LYCursesON) {
5280
#endif /* USE_SLANG */
5281
CTRACE((tfp, "Entering mainloop, startfile=%s\n", startfile));
5283
if (form_post_data) {
5284
BStrCopy0(newdoc.post_data, form_post_data);
5285
StrAllocCopy(newdoc.post_content_type,
5286
"application/x-www-form-urlencoded");
5287
} else if (form_get_data) {
5288
StrAllocCat(newdoc.address, form_get_data);
5291
if (bookmark_start) {
5293
HTAlert(BOOKMARKS_DISABLED);
5294
bookmark_start = FALSE;
5296
} else if (traversal) {
5297
HTAlert(BOOKMARKS_NOT_TRAVERSED);
5300
bookmark_start = FALSE;
5304
* See if a bookmark page exists. If it does,
5305
* replace newdoc.address with its name
5307
if ((cp = get_bookmark_filename(&newdoc.address)) != NULL &&
5308
*cp != '\0' && strcmp(cp, " ")) {
5309
StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
5310
StrAllocCopy(newdoc.bookmark, BookmarkPage);
5311
StrAllocCopy(startrealm, newdoc.address);
5312
LYFreePostData(&newdoc);
5313
newdoc.isHEAD = FALSE;
5314
newdoc.safe = FALSE;
5315
CTRACE((tfp, "Using bookmarks=%s\n", newdoc.address));
5317
HTUserMsg(BOOKMARKS_NOT_OPEN);
5318
bookmark_start = FALSE;
5324
FREE(form_post_data);
5325
FREE(form_get_data);
5327
if (user_mode == NOVICE_MODE)
5328
display_lines = LYlines-4;
5330
display_lines = LYlines-2;
5333
#ifdef USE_COLOR_STYLE
5334
if (curdoc.style != NULL) force_load = TRUE;
5337
* If newdoc.address is different then curdoc.address then
5338
* we need to go out and find and load newdoc.address.
5340
if (LYforce_no_cache || force_load ||
5341
are_different(&curdoc, &newdoc)) {
5343
force_load = FALSE; /* done */
5344
if (TRACE && LYCursesON) {
5345
LYHideCursor(); /* make sure cursor is down */
5348
#endif /* USE_SLANG */
5353
* Push the old file onto the history stack if we
5354
* have a current doc and a new address. - FM
5356
if (curdoc.address && newdoc.address) {
5358
* Don't actually push if this is a LYNXDOWNLOAD
5359
* URL, because that returns NORMAL even if it
5360
* fails due to a spoof attempt or file access
5361
* problem, and we set the newdoc structure
5362
* elements to the curdoc structure elements
5363
* under case NORMAL. - FM
5365
if (!isLYNXDOWNLOAD(newdoc.address))
5367
LYpush(&curdoc, ForcePush);
5369
} else if (!newdoc.address) {
5371
* If newdoc.address is empty then pop a file
5374
LYhist_prev(&newdoc);
5379
#ifndef DONT_TRACK_INTERNAL_LINKS
5381
** If curdoc had been reached via an internal
5382
** (fragment) link from what we now have just
5383
** popped into newdoc, then override non-caching in
5386
if (curdoc.internal_link &&
5387
!are_phys_different(&curdoc, &newdoc)) {
5388
LYinternal_flag = TRUE;
5389
LYoverride_no_cache = TRUE;
5390
LYforce_no_cache = FALSE;
5391
try_internal = TRUE;
5393
#endif /* TRACK_INTERNAL_LINKS */
5396
* Force a no_cache override unless
5397
* it's a bookmark file, or it has POST content
5398
* and LYresubmit_posts is set without safe also
5399
* set, and we are not going to another position
5400
* in the current document or restoring the previous
5401
* document due to a NOT_FOUND or NULLFILE return
5402
* value from getfile(). - FM
5404
if ((newdoc.bookmark != NULL) ||
5405
(newdoc.post_data != NULL &&
5408
!override_LYresubmit_posts &&
5409
NO_INTERNAL_OR_DIFFERENT(&curdoc, &newdoc))) {
5410
LYoverride_no_cache = FALSE;
5412
LYoverride_no_cache = TRUE;
5416
override_LYresubmit_posts = FALSE;
5420
* Make SURE this is an appropriate request. - FM
5422
if (newdoc.address) {
5423
if (LYCanDoHEAD(newdoc.address) == TRUE) {
5424
newdoc.isHEAD = TRUE;
5425
} else if (isLYNXIMGMAP(newdoc.address)) {
5426
if (LYCanDoHEAD(newdoc.address + LEN_LYNXIMGMAP) == TRUE) {
5427
StrAllocCopy(temp, newdoc.address + LEN_LYNXIMGMAP);
5428
free_address(&newdoc);
5429
newdoc.address = temp;
5430
newdoc.isHEAD = TRUE;
5435
try_internal = FALSE;
5436
HEAD_request = FALSE;
5440
* If we're getting the TRACE log and it's not new,
5441
* check whether its HText structure has been dumped,
5442
* and if so, fflush() and fclose() it to ensure it's
5443
* fully updated, and then fopen() it again. - FM
5445
if (LYUseTraceLog == TRUE &&
5446
trace_mode_flag == FALSE &&
5447
LYTraceLogFP != NULL &&
5448
LYIsUIPage(newdoc.address, UIP_TRACELOG)) {
5450
HTParentAnchor *tmpanchor;
5452
WWWDoc.address = newdoc.address;
5453
WWWDoc.post_data = newdoc.post_data;
5454
WWWDoc.post_content_type = newdoc.post_content_type;
5455
WWWDoc.bookmark = newdoc.bookmark;
5456
WWWDoc.isHEAD = newdoc.isHEAD;
5457
WWWDoc.safe = newdoc.safe;
5458
tmpanchor = HTAnchor_findAddress(&WWWDoc);
5459
if ((HText *)HTAnchor_document(tmpanchor) == NULL) {
5460
if (!LYReopenTracelog(&trace_mode_flag)) {
5468
LYRequestTitle = newdoc.title;
5469
if (newdoc.bookmark)
5470
LYforce_HTML_mode = TRUE;
5473
newdoc.address && startfile && homepage &&
5474
(!strcmp(newdoc.address, startfile) ||
5475
!strcmp(newdoc.address, homepage))) {
5479
/* reset these two variables here before getfile()
5480
* so they will be available in partial mode
5481
* (was previously implemented in case NORMAL).
5483
*prev_target = '\0'; /* Reset for new coming document */
5484
Newline = newdoc.line; /* set for LYGetNewline() */
5486
#ifdef USE_PRETTYSRC
5487
psrc_first_tag = TRUE;
5489
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
5490
textfields_need_activation = textfields_activation_option;
5492
FREE(LYRequestReferer);
5494
* Don't send Referer if we have to load a document again
5495
* that we got from the history stack. We don't know
5496
* any more how we originally got to that page. Using
5497
* a Referer based on the current HTMainText could only
5498
* be right by coincidence. - kw 1999-11-01
5501
LYNoRefererForThis = TRUE;
5503
#ifndef DONT_TRACK_INTERNAL_LINKS
5505
if (newdoc.address &&
5506
isLYNXIMGMAP(newdoc.address)) {
5507
try_internal = FALSE;
5508
} else if (curdoc.address &&
5509
isLYNXIMGMAP(curdoc.address)) {
5510
try_internal = FALSE;
5514
char *hashp = findPoundSelector(newdoc.address);
5516
HTFindPoundSelector(hashp+1);
5518
getresult = (HTMainText != NULL) ? NORMAL : NOT_FOUND;
5519
try_internal = FALSE; /* done */
5520
/* fix up newdoc.address which may have been fragment-only */
5521
if (getresult == NORMAL && (!hashp || hashp == newdoc.address)) {
5523
set_address(&newdoc, HTLoadedDocumentURL());
5525
StrAllocCopy(temp, HTLoadedDocumentURL());
5526
StrAllocCat(temp, hashp); /* append fragment */
5527
set_address(&newdoc, temp);
5532
if (newdoc.internal_link && newdoc.address &&
5533
*newdoc.address == '#' && nhist > 0) {
5535
if (isLYNXIMGMAP(HDOC(nhist-1).address))
5536
cp0 = HDOC(nhist-1).address + LEN_LYNXIMGMAP;
5538
cp0 = HDOC(nhist-1).address;
5539
StrAllocCopy(temp, cp0);
5540
(void) trimPoundSelector(temp);
5541
StrAllocCat(temp, newdoc.address);
5542
free_address(&newdoc);
5543
newdoc.address = temp;
5546
getresult = getfile(&newdoc);
5548
#else /* TRACK_INTERNAL_LINKS */
5549
getresult = getfile(&newdoc);
5550
#endif /* TRACK_INTERNAL_LINKS */
5552
#ifdef INACTIVE_INPUT_STYLE_VH
5553
textinput_redrawn = FALSE; /* for sure */
5560
* OK! can't find the file, so it must not be around now.
5561
* Do any error logging, if appropriate.
5563
LYoverride_no_cache = FALSE; /* Was TRUE if popped. - FM */
5564
LYinternal_flag = FALSE; /* Reset to default. - kw */
5565
turn_trace_back_on(&trace_mode_flag);
5566
if (!first_file && !LYCancelledFetch) {
5568
* Do error mail sending and/or traversal
5569
* stuff. Note that the links[] elements may
5570
* not be valid at this point, if we did call
5571
* HTuncache_current_document! This should
5572
* not have happened for traversal, but for
5573
* sending error mail check that HTMainText
5574
* exists for this reason. - kw
5576
if (error_logging && nhist > 0 && !popped_doc &&
5577
!LYUserSpecifiedURL &&
5579
nlinks > 0 && curdoc.link < nlinks &&
5580
!isLYNXHIST(NonNull(newdoc.address)) &&
5581
!isLYNXCOOKIE(NonNull(newdoc.address))) {
5582
char *mail_owner = NULL;
5583
if (owner_address && isMAILTO_URL(owner_address)) {
5584
mail_owner = owner_address + LEN_MAILTO_URL;
5587
* Email a bad link message to the owner of
5588
* the document, or to ALERTMAIL if defined,
5589
* but NOT to lynx-dev (it is rejected in
5590
* mailmsg). - FM, kw
5595
mailmsg(curdoc.link,
5597
HDOC(nhist-1).address,
5598
HDOC(nhist-1).title);
5603
if ((ofp = LYAppendToTxtFile(TRAVERSE_ERRORS)) == NULL) {
5604
if ((ofp = LYNewTxtFile(TRAVERSE_ERRORS)) == NULL) {
5605
perror(NOOPEN_TRAV_ERR_FILE);
5606
exit_immediately(EXIT_FAILURE);
5613
newdoc.address : links[curdoc.link].lname,
5614
links[curdoc.link].target,
5615
HDOC(nhist-1).address);
5620
newdoc.address : links[curdoc.link].lname,
5621
links[curdoc.link].target);
5628
* Fall through to do the NULL stuff and reload the
5629
* old file, unless the first file wasn't found or
5634
* If nhist = 0 then it must be the first file.
5636
exit_immediately_with_error_message(NOT_FOUND, first_file);
5637
return(EXIT_FAILURE);
5643
* Not supposed to return any file.
5645
LYoverride_no_cache = FALSE; /* Was TRUE if popped. - FM */
5646
popped_doc = FALSE; /* Was TRUE if popped. - FM */
5647
LYinternal_flag = FALSE; /* Reset to default. - kw */
5648
turn_trace_back_on(&trace_mode_flag);
5649
free_address(&newdoc); /* to pop last doc */
5650
FREE(newdoc.bookmark);
5651
LYJumpFileURL = FALSE;
5653
LYPermitURL = FALSE;
5654
LYCancelledFetch = FALSE;
5656
LYforce_HTML_mode = FALSE;
5657
force_old_UCLYhndl_on_reload = FALSE;
5660
if (traversal_link_to_add) {
5662
* It's a binary file, or the fetch attempt
5663
* failed. Add it to TRAVERSE_REJECT_FILE
5664
* so we don't try again in this run.
5666
if (!lookup_reject(traversal_link_to_add)) {
5667
add_to_reject_list(traversal_link_to_add);
5669
FREE(traversal_link_to_add);
5673
* Make sure the first file was found and
5674
* has not gone missing.
5678
* If nhist = 0 then it must be the first file.
5680
if (first_file && homepage &&
5681
!LYSameFilename(homepage, startfile)) {
5683
* Couldn't return to the first file but there is a
5684
* homepage we can use instead. Useful for when the
5685
* first URL causes a program to be invoked. - GL
5687
* But first make sure homepage is different from
5688
* startfile (above), then make it the same (below)
5689
* so we don't enter an infinite getfile() loop on
5690
* on failures to find the files. - FM
5692
set_address(&newdoc, homepage);
5693
LYFreePostData(&newdoc);
5694
FREE(newdoc.bookmark);
5695
StrAllocCopy(startfile, homepage);
5696
newdoc.isHEAD = FALSE;
5697
newdoc.safe = FALSE;
5698
newdoc.internal_link = FALSE;
5701
exit_immediately_with_error_message(NULLFILE, first_file);
5702
return(EXIT_FAILURE);
5707
* If we're going to pop from history because
5708
* getfile didn't succeed, reset LYforce_no_cache
5709
* first. This would have been done in HTAccess.c
5710
* if the request got that far, but the URL may
5711
* have been handled or rejected in getfile without
5712
* taking care of that. - kw
5714
LYforce_no_cache = FALSE;
5716
* Retrieval of a newdoc just failed, and just
5717
* going to try_again would pop the next doc
5718
* from history and try to get it without further
5719
* questions. This may not be the right thing to do if
5720
* we have POST data, so fake a PREV_DOC key if it seems
5721
* that some prompting should be done. This doesn't
5722
* affect the traversal logic, since with traversal
5723
* POST data can never occur. - kw
5725
if (HDOC(nhist - 1).post_data &&
5726
!HDOC(nhist - 1).safe) {
5727
if (HText_POSTReplyLoaded((DocInfo *)&history[(nhist - 1)])) {
5728
override_LYresubmit_posts = TRUE;
5731
/* Set newdoc fields, just in case the PREV_DOC
5732
* gets cancelled. - kw */
5733
if (!curdoc.address) {
5734
set_address(&newdoc, HTLoadedDocumentURL());
5735
StrAllocCopy(newdoc.title, HTLoadedDocumentTitle());
5737
&& HTMainAnchor->post_data) {
5738
BStrCopy(newdoc.post_data,
5739
HTMainAnchor->post_data);
5740
StrAllocCopy(newdoc.post_content_type,
5741
HTMainAnchor->post_content_type);
5743
BStrFree(newdoc.post_data);
5745
newdoc.isHEAD = HTLoadedDocumentIsHEAD();
5746
newdoc.safe = HTLoadedDocumentIsSafe();
5747
newdoc.internal_link = FALSE;
5749
copy_address(&newdoc, &curdoc);
5750
StrAllocCopy(newdoc.title, curdoc.title);
5751
BStrCopy(newdoc.post_data, curdoc.post_data);
5752
StrAllocCopy(newdoc.post_content_type,
5753
curdoc.post_content_type);
5754
newdoc.isHEAD = curdoc.isHEAD;
5755
newdoc.safe = curdoc.safe;
5756
newdoc.internal_link = curdoc.internal_link;
5757
newdoc.line = curdoc.line;
5758
newdoc.link = curdoc.link;
5763
override_LYresubmit_posts = TRUE;
5768
* Marvelously, we got the document!
5770
LYoverride_no_cache = FALSE; /* Was TRUE if popped. - FM */
5771
LYinternal_flag = FALSE; /* Reset to default. - kw */
5772
turn_trace_back_on(&trace_mode_flag);
5775
* If it's the first file and we're interactive,
5776
* check whether it's a bookmark file which was
5777
* not accessed via the -book switch. - FM
5779
if (((first_file == TRUE) &&
5780
(dump_output_immediately == FALSE) &&
5781
!(newdoc.bookmark && *newdoc.bookmark)) &&
5782
((LYisLocalFile(newdoc.address) == TRUE) &&
5783
!(strcmp(NonNull(HText_getTitle()),
5784
BOOKMARK_TITLE))) &&
5785
(temp = HTParse(newdoc.address, "",
5786
PARSE_PATH+PARSE_PUNCTUATION)) != NULL) {
5787
CONST char *name = wwwName(Home_Dir());
5790
if (!strncasecomp(temp, name, len) &&
5793
if (!strncmp(temp, name, len) &&
5798
* We're interactive and this might be a
5799
* bookmark file entered as a startfile
5800
* rather than invoked via -book. Check
5801
* if it's in our bookmark file list, and
5802
* if so, reload if with the relevant
5803
* bookmark elements set. - FM
5806
if (temp[len] == '/') {
5807
if (strchr(&temp[(len + 1)], '/')) {
5808
HTSprintf0(&cp, ".%s", &temp[len]);
5810
StrAllocCopy(cp, &temp[(len + 1)]);
5813
StrAllocCopy(cp, &temp[len]);
5815
for (i = 0; i <= MBM_V_MAXFILES; i++) {
5816
if (MBM_A_subbookmark[i] &&
5817
LYSameFilename(cp, MBM_A_subbookmark[i])) {
5818
StrAllocCopy(BookmarkPage,
5819
MBM_A_subbookmark[i]);
5824
if (i <= MBM_V_MAXFILES) {
5827
HTAlert(BOOKMARKS_DISABLED);
5828
return(EXIT_FAILURE);
5830
if ((temp = HTParse(newdoc.address, "",
5831
PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION))) {
5832
set_address(&newdoc, temp);
5833
HTuncache_current_document();
5834
free_address(&curdoc);
5835
StrAllocCat(newdoc.address,
5836
wwwName(Home_Dir()));
5837
StrAllocCat(newdoc.address, "/");
5838
StrAllocCat(newdoc.address,
5839
(strncmp(BookmarkPage, "./", 2) ?
5841
(BookmarkPage + 2)));
5842
StrAllocCopy(newdoc.title, BOOKMARK_TITLE);
5843
StrAllocCopy(newdoc.bookmark, BookmarkPage);
5844
#ifdef USE_COLOR_STYLE
5846
StrAllocCopy(newdoc.style, curdoc.style);
5848
StrAllocCopy(startrealm, newdoc.address);
5849
LYFreePostData(&newdoc);
5850
newdoc.isHEAD = FALSE;
5851
newdoc.safe = FALSE;
5853
if (!strcmp(homepage, startfile))
5854
StrAllocCopy(homepage, newdoc.address);
5855
StrAllocCopy(startfile, newdoc.address);
5856
CTRACE((tfp, "Reloading as bookmarks=%s\n",
5868
* During traversal build up lists of all links
5869
* traversed. Traversal mode is a special
5870
* feature for traversing http links in the web.
5872
if (traversal_link_to_add) {
5874
* Add the address we sought to TRAVERSE_FILE.
5876
if (!lookup(traversal_link_to_add))
5877
add_to_table(traversal_link_to_add);
5878
FREE(traversal_link_to_add);
5880
if (curdoc.address && curdoc.title &&
5881
!isLYNXIMGMAP(curdoc.address))
5883
* Add the address we got to TRAVERSE_FOUND_FILE.
5885
add_to_traverse_list(curdoc.address, curdoc.title);
5889
* If this was a LYNXDOWNLOAD, we still have curdoc,
5890
* not a newdoc, so reset the address, title and
5891
* positioning elements. - FM
5893
if (newdoc.address && curdoc.address &&
5894
isLYNXDOWNLOAD(newdoc.address)) {
5895
copy_address(&newdoc, &curdoc);
5896
StrAllocCopy(newdoc.title, (curdoc.title ?
5897
curdoc.title : ""));
5898
StrAllocCopy(newdoc.bookmark, curdoc.bookmark);
5899
newdoc.line = curdoc.line;
5900
newdoc.link = curdoc.link;
5901
newdoc.internal_link = FALSE; /* can't be true. - kw */
5905
* Set Newline to the saved line. It contains the
5906
* line the user was on if s/he has been in the file
5907
* before, or it is 1 if this is a new file.
5909
* We already set Newline before getfile() and probably
5910
* update it explicitly if popping from the history stack
5911
* via LYpop() or LYpop_num() within getfile() cycle.
5913
* In partial mode, Newline was probably updated in
5914
* LYMainLoop_pageDisplay() if user scrolled
5915
* the document while loading.
5916
* Incremental loading stage already closed in HT*Copy().
5919
/* Newline = newdoc.line; */
5920
display_partial = FALSE; /* for sure, LYNXfoo:/ may be a problem */
5922
/* Should not be needed either if we remove
5923
* "DISP_PARTIAL" from LYHistory.c, but lets leave it
5924
* as an important comment for now.
5926
Newline = newdoc.line;
5930
* If we are going to a target line or
5931
* the first page of a popped document,
5932
* override any www_search line result.
5934
if (Newline > 1 || popped_doc == TRUE)
5935
www_search_result = -1;
5938
* Make sure curdoc.line will not be equal
5939
* to Newline, so we get a redraw.
5946
if (!LYTraceLogFP || trace_mode_flag) {
5947
LYSleepAlert(); /* allow me to look at the results */
5952
* Set the files the same.
5954
copy_address(&curdoc, &newdoc);
5955
BStrCopy(curdoc.post_data, newdoc.post_data);
5956
StrAllocCopy(curdoc.post_content_type, newdoc.post_content_type);
5957
StrAllocCopy(curdoc.bookmark, newdoc.bookmark);
5958
#ifdef USE_COLOR_STYLE
5959
StrAllocCopy(curdoc.style, HText_getStyle());
5960
if (curdoc.style != NULL)
5961
style_readFromFile (curdoc.style);
5963
curdoc.isHEAD = newdoc.isHEAD;
5964
curdoc.internal_link = newdoc.internal_link;
5967
* Set the remaining document elements and add to
5968
* the visited links list. - FM
5970
if (ownerS_address != NULL) {
5971
#ifndef USE_PRETTYSRC
5972
if (HTOutputFormat == WWW_SOURCE && !HText_getOwner())
5974
if ( (LYpsrc ? psrc_view : HTOutputFormat == WWW_SOURCE)
5975
&& !HText_getOwner() )
5977
HText_setMainTextOwner(ownerS_address);
5978
FREE(ownerS_address);
5980
if (HText_getTitle()) {
5981
StrAllocCopy(curdoc.title, HText_getTitle());
5982
} else if (!dump_output_immediately) {
5983
StrAllocCopy(curdoc.title, newdoc.title);
5985
StrAllocCopy(owner_address, HText_getOwner());
5986
curdoc.safe = HTLoadedDocumentIsSafe();
5987
if (!dump_output_immediately) {
5988
LYAddVisitedLink(&curdoc);
5993
* Reset WWW present mode so that if we were getting
5994
* the source, we get rendered HTML from now on.
5996
HTOutputFormat = WWW_PRESENT;
5997
#ifdef USE_PRETTYSRC
6001
HTMLSetCharacterHandling(current_char_set); /* restore, for sure? */
6004
* Reset all of the other relevant flags. - FM
6006
LYUserSpecifiedURL = FALSE; /* only set for goto's and jumps's */
6007
LYJumpFileURL = FALSE; /* only set for jump's */
6008
LYNoRefererForThis = FALSE; /* always reset on return here */
6009
reloading = FALSE; /* set for RELOAD and NOCACHE keys */
6010
HEAD_request = FALSE; /* only set for HEAD requests */
6011
LYPermitURL = FALSE; /* only for LYValidate or check_realm */
6012
ForcePush = FALSE; /* only set for some PRINT requests. */
6013
LYforce_HTML_mode = FALSE;
6014
force_old_UCLYhndl_on_reload = FALSE;
6016
pending_form_c = -1;
6018
} /* end if (LYforce_no_cache || force_load || are_different(...)) */
6020
if (dump_output_immediately) {
6022
print_crawl_to_fd(stdout, curdoc.address, curdoc.title);
6024
print_wwwfile_to_fd(stdout, FALSE);
6026
return(EXIT_SUCCESS);
6030
* If the recent_sizechange variable is set to TRUE
6031
* then the window size changed recently.
6033
if (recent_sizechange) {
6035
* First we need to make sure the display library - curses, slang,
6036
* whatever - gets notified about the change, and gets a chance
6037
* to update external structures appropriately. Hopefully the
6038
* stop_curses()/start_curses() sequence achieves this, at least
6039
* if the display library has a way to get the new screen size
6041
* However, at least for ncurses, the update of the internal
6042
* structures will come still too late - the changed screen
6043
* size is detected in doupdate(), which would only be called
6044
* (indirectly through the HText_pageDisplay below) after the
6045
* WINDOW structures are already filled based on the old size.
6046
* So we notify the ncurses library directly here. - kw
6048
#if defined(NCURSES) && defined(HAVE_RESIZETERM) && defined(HAVE_WRESIZE)
6049
resizeterm(LYlines, LYcols);
6050
wresize(LYwin, LYlines, LYcols);
6052
#if 0 /* defined(PDCURSES) && defined(HAVE_XCURSES) */
6053
resize_term(LYlines, LYcols);
6055
LYwin = resize_window(LYwin, LYlines, LYcols);
6063
refresh_screen = TRUE; /* to force a redraw */
6064
if (HTMainText) /* to REALLY force it... - kw */
6065
HText_setStale(HTMainText);
6066
recent_sizechange = FALSE;
6067
if (user_mode == NOVICE_MODE) {
6068
display_lines = LYlines-4;
6070
display_lines = LYlines-2;
6074
if (www_search_result != -1) {
6076
* This was a WWW search, set the line
6077
* to the result of the search.
6079
Newline = www_search_result;
6080
www_search_result = -1; /* reset */
6083
if (first_file == TRUE) {
6085
* We can never again have the first file.
6090
* Set the startrealm, and deal as best we can
6091
* with preserving forced HTML mode for a local
6094
temp = HTParse(curdoc.address, "",
6095
PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
6096
if (!temp || *temp == '\0') {
6097
StrAllocCopy(startrealm, NO_NOTHING);
6099
StrAllocCopy(startrealm, temp);
6101
if (!(temp = HTParse(curdoc.address, "",
6102
PARSE_PATH+PARSE_PUNCTUATION))) {
6103
LYAddHtmlSep(&startrealm);
6105
if (forced_HTML_mode &&
6106
!dump_output_immediately &&
6108
isFILE_URL(curdoc.address) &&
6111
* We forced HTML for a local startfile which
6112
* is not a bookmark file and has a path of at
6113
* least two letters. If it doesn't have a
6114
* suffix mapped to text/html, we'll set the
6115
* entire path (including the lead slash) as a
6116
* "suffix" mapped to text/html to ensure it is
6117
* always treated as an HTML source file. We
6118
* are counting on a tail match to this full path
6119
* for some other URL fetched during the session
6120
* having too low a probability to worry about,
6121
* but it could happen. - FM
6125
if (HTFileFormat(temp, &encoding, NULL) != WWW_HTML) {
6126
HTSetSuffix(temp, "text/html", "8bit", 1.0);
6129
if ((cp = strrchr(temp, '/')) != NULL) {
6131
StrAllocCat(startrealm, temp);
6136
CTRACE((tfp, "Starting realm is '%s'\n\n", startrealm));
6139
* Set up the crawl output stuff.
6141
if (curdoc.address && !lookup(curdoc.address)) {
6142
if (!isLYNXIMGMAP(curdoc.address))
6144
add_to_table(curdoc.address);
6147
* Set up the traversal_host comparison string.
6149
if (strncmp((curdoc.address ? curdoc.address : "NULL"),
6151
StrAllocCopy(traversal_host, NO_NOTHING);
6152
} else if (check_realm) {
6153
StrAllocCopy(traversal_host, startrealm);
6155
temp = HTParse(curdoc.address, "",
6156
PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
6157
if (!temp || *temp == '\0') {
6158
StrAllocCopy(traversal_host, NO_NOTHING);
6160
StrAllocCopy(traversal_host, temp);
6161
LYAddHtmlSep(&traversal_host);
6165
CTRACE((tfp, "Traversal host is '%s'\n\n", traversal_host));
6169
* If homepage was not equated to startfile,
6170
* make the homepage URL the first goto
6173
if (homepage && strcmp(startfile, homepage))
6174
HTAddGotoURL(homepage);
6176
* If we are not starting up with startfile
6177
* (e.g., had -book), or if we are using the
6178
* startfile and it has no POST content, make
6179
* the startfile URL a goto entry. - FM
6181
if (strcmp(startfile, newdoc.address) ||
6182
newdoc.post_data == NULL)
6183
HTAddGotoURL(startfile);
6186
refresh_screen = TRUE;
6187
if (!LYTraceLogFP || trace_mode_flag) {
6193
#ifdef USE_SOURCE_CACHE
6195
* If the parse settings have changed since this HText was
6196
* generated, we need to reparse and redraw it. -dsb
6198
* Should be configured to avoid shock for experienced lynx users.
6199
* Currently enabled for cached sources only.
6201
if (HTdocument_settings_changed()) {
6202
if (HTcan_reparse_document()) {
6203
HTInfoMsg(gettext("Reparsing document under current settings..."));
6207
* Urk. I have no idea how to recover from a failure here.
6208
* At a guess, I'll try reloading. -dsb
6210
/* currently disabled ***
6211
HTUserMsg(gettext("Reparsing document under current settings..."));
6218
if (from_source_cache) {
6219
from_source_cache = FALSE; /* reset */
6220
curdoc.line = -1 ; /* so curdoc.line != Newline, see below */
6225
* If the curdoc.line is different than Newline then there must
6226
* have been a change since last update. Run HText_pageDisplay()
6227
* create a fresh screen of text out.
6229
* If we got new HTMainText go this way.
6230
* All display_partial calls ends here for final redraw.
6232
if (curdoc.line != Newline) {
6233
#ifdef INACTIVE_INPUT_STYLE_VH
6234
textinput_redrawn = FALSE;
6237
refresh_screen = FALSE;
6239
HText_pageDisplay(Newline, prev_target);
6241
#ifdef DIRED_SUPPORT
6242
if (lynx_edit_mode && nlinks > 0 && !HTList_isEmpty(tagged))
6244
#endif /* DIRED_SUPPORT */
6247
* If more equals TRUE, then there is more info below this page.
6249
more = HText_canScrollDown();
6250
curdoc.line = Newline = HText_getTopOfScreen()+1;
6252
if (curdoc.title == NULL) {
6254
* If we don't yet have a title, try to get it,
6255
* or set to that for newdoc.title. - FM
6257
if (HText_getTitle()) {
6258
StrAllocCopy(curdoc.title, HText_getTitle());
6260
StrAllocCopy(curdoc.title, newdoc.title);
6265
* If the request is to highlight a link which is counted
6266
* from the start of document, correct the link number:
6268
if (newdoc_link_is_absolute) {
6269
newdoc_link_is_absolute = FALSE;
6270
if (curdoc.line > 1)
6271
newdoc.link -= HText_LinksInLines(HTMainText, 1,
6277
* arrowup is set if we just came up from
6280
curdoc.link = nlinks - 1;
6283
curdoc.link = newdoc.link;
6284
if (curdoc.link >= nlinks) {
6285
curdoc.link = nlinks - 1;
6286
} else if (curdoc.link < 0 && nlinks > 0) {
6288
* We may have popped a doc (possibly in local_dired)
6289
* which didn't have any links when it was pushed, but
6290
* does have links now (e.g., a file was created).
6291
* Code below assumes that curdoc.link is valid and
6292
* that (curdoc.link==-1) only occurs if (nlinks==0)
6299
show_help = FALSE; /* reset */
6302
curdoc.line = Newline; /* set */
6306
* Refresh the screen if necessary.
6308
if (refresh_screen) {
6309
#if defined(FANCY_CURSES) || defined (USE_SLANG)
6310
if (enable_scrollback) {
6317
#endif /* FANCY_CURSES || USE_SLANG */
6318
HText_pageDisplay(Newline, prev_target);
6320
#ifdef DIRED_SUPPORT
6321
if (lynx_edit_mode && nlinks > 0 && !HTList_isEmpty(tagged))
6323
#endif /* DIRED_SUPPORT */
6326
* If more equals TRUE, then there is more info below this page.
6328
more = HText_canScrollDown();
6331
* Adjust curdoc.link as above; nlinks may have changed,
6332
* if the refresh_screen flag was set as a result of
6334
* Code below assumes that curdoc.link is valid and
6335
* that (curdoc.link==-1) only occurs if (nlinks==0)
6338
if (curdoc.link >= nlinks) {
6339
curdoc.link = nlinks - 1;
6340
} else if (curdoc.link < 0 && nlinks > 0) {
6344
if (user_mode == NOVICE_MODE)
6345
noviceline(more); /* print help message */
6346
refresh_screen = FALSE;
6350
curlink_is_editable =
6352
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
6353
F_TEXTLIKE(links[curdoc.link].l_form->type));
6355
use_last_tfpos = (curlink_is_editable &&
6356
(real_cmd == LYK_LPOS_PREV_LINK ||
6357
real_cmd == LYK_LPOS_NEXT_LINK));
6359
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
6360
if (!textfields_need_activation)
6361
textinput_activated = TRUE;
6364
#if defined(WIN_EX) /* 1997/10/08 (Wed) 14:52:06 */
6366
char *p = "LYNX (unknown link type)";
6368
/* Show the URL & kanji code . */
6369
if (strlen(links[curdoc.link].lname) == 0) {
6371
if (links[curdoc.link].type == WWW_FORM_LINK_TYPE) {
6373
switch(links[curdoc.link].l_form->type) {
6374
case F_TEXT_SUBMIT_TYPE:
6376
case F_IMAGE_SUBMIT_TYPE:
6379
case F_PASSWORD_TYPE:
6382
case F_OPTION_LIST_TYPE:
6385
case F_CHECKBOX_TYPE:
6397
case F_TEXTAREA_TYPE:
6398
p = "Text input lines";
6406
if (user_mode == ADVANCED_MODE) {
6409
p = links[curdoc.link].lname;
6412
if (strlen(p) < 500) {
6413
strcpy(temp_buff, p);
6414
if (strchr(temp_buff, '%')) {
6415
HTUnEscape(temp_buff);
6417
str_sjis(sjis_buff, temp_buff);
6418
set_ws_title(LYElideString(sjis_buff, 10));
6422
if (strlen(curdoc.address) < sizeof(temp_buff)-1) {
6423
if (user_mode == ADVANCED_MODE) {
6424
str_sjis(temp_buff, curdoc.title);
6426
strcpy(temp_buff, curdoc.address);
6428
set_ws_title(HTUnEscape(temp_buff));
6434
* Report unread or new mail, if appropriate.
6436
if (check_mail && !no_mail)
6440
* If help is not on the screen,
6441
* then put a message on the screen
6442
* to tell the user other misc info.
6445
show_main_statusline(links[curdoc.link],
6446
(curlink_is_editable && textinput_activated) ?
6447
FOR_INPUT : FOR_PANEL);
6454
* Highlight current link, unless it is an active
6457
if (!curlink_is_editable) {
6458
LYhighlight(ON, curdoc.link, prev_target);
6459
#ifndef INACTIVE_INPUT_STYLE_VH
6460
} else if (!textinput_activated) {
6461
LYhighlight(ON, curdoc.link, prev_target);
6468
* Don't go interactively into forms,
6469
* or accept keystrokes from the user
6471
if (crawl && crawl_ok) {
6474
sprintf(cfile,"lnk%05d.dat",ccount);
6476
sprintf(cfile,"lnk%08d.dat",ccount);
6477
#endif /* FNAMES_8_3 */
6478
ccount = ccount + 1;
6479
if ((cfp = LYNewTxtFile(cfile)) != NULL) {
6480
print_crawl_to_fd(cfp,curdoc.address,curdoc.title);
6483
if (!dump_output_immediately)
6486
if (dump_output_immediately)
6488
gettext("Fatal error - could not open output file %s\n"),cfile);
6492
gettext("Fatal error - could not open output file %s\n"),cfile);
6493
if (!dump_output_immediately) {
6494
exit_immediately(EXIT_FAILURE);
6496
return(EXIT_FAILURE);
6501
* Normal, non-traversal handling.
6504
if (curlink_is_editable &&
6505
(textinput_activated || pending_form_c != -1)) {
6506
if (pending_form_c != -1) {
6507
real_c = pending_form_c;
6508
pending_form_c = -1;
6511
* Replace novice lines if in NOVICE_MODE.
6513
if (user_mode==NOVICE_MODE) {
6514
form_noviceline(links[curdoc.link].l_form->disabled);
6516
real_c = change_form_link(curdoc.link,
6517
&newdoc, &refresh_screen,
6518
use_last_tfpos, FALSE);
6520
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
6521
if (textfields_need_activation)
6522
textinput_activated = FALSE;
6523
#ifdef INACTIVE_INPUT_STYLE_VH
6524
textinput_redrawn = FALSE;
6528
c = (real_c==LKC_DONE) ? DO_NOTHING : LKC_TO_C(real_c);
6529
if (c != DO_NOTHING &&
6530
peek_mouse_link() != -1 && peek_mouse_link() != -2)
6532
if (peek_mouse_link() >= 0 &&
6533
LKC_TO_LAC(keymap,real_c) != LYK_CHANGE_LINK) {
6535
if ((c == '\n' || c == '\r') &&
6536
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
6537
F_TEXTLIKE(links[curdoc.link].l_form->type) &&
6538
!textfields_need_activation) {
6541
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
6542
} else if ((links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
6543
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE)
6544
&& textfields_need_activation
6545
&& !links[curdoc.link].l_form->disabled
6546
&& peek_mouse_link() < 0 &&
6547
(((LKC_TO_LAC(keymap,real_c) == LYK_NEXT_LINK ||
6548
#ifdef TEXTAREA_AUTOGROW
6549
LKC_TO_LAC(keymap,real_c) == LYK_ACTIVATE ||
6551
LKC_TO_LAC(keymap,real_c) == LYK_LPOS_NEXT_LINK ||
6552
LKC_TO_LAC(keymap,real_c) == LYK_DOWN_LINK) &&
6553
((curdoc.link < nlinks-1 &&
6554
links[curdoc.link+1].type == WWW_FORM_LINK_TYPE &&
6555
links[curdoc.link+1].l_form->type == F_TEXTAREA_TYPE
6556
&& (links[curdoc.link].l_form->number ==
6557
links[curdoc.link+1].l_form->number) &&
6558
strcmp(links[curdoc.link].l_form->name,
6559
links[curdoc.link+1].l_form->name) == 0) ||
6560
(curdoc.link == nlinks-1 && more &&
6561
HText_TAHasMoreLines(curdoc.link, 1)))) ||
6562
((LKC_TO_LAC(keymap,real_c) == LYK_PREV_LINK ||
6563
LKC_TO_LAC(keymap,real_c) == LYK_LPOS_PREV_LINK ||
6564
LKC_TO_LAC(keymap,real_c) == LYK_UP_LINK) &&
6565
((curdoc.link > 0 &&
6566
links[curdoc.link-1].type == WWW_FORM_LINK_TYPE &&
6567
links[curdoc.link-1].l_form->type == F_TEXTAREA_TYPE
6568
&& (links[curdoc.link].l_form->number ==
6569
links[curdoc.link-1].l_form->number) &&
6570
strcmp(links[curdoc.link].l_form->name,
6571
links[curdoc.link-1].l_form->name) == 0) ||
6572
(curdoc.link == 0 && curdoc.line > 1 &&
6573
HText_TAHasMoreLines(curdoc.link, -1)))))) {
6574
textinput_activated = TRUE;
6575
#ifdef TEXTAREA_AUTOGROW
6576
if ((c == '\n' || c == '\r') &&
6577
LKC_TO_LAC(keymap,real_c) == LYK_ACTIVATE)
6578
c = LAC_TO_LKC0(LYK_NEXT_LINK);
6579
#endif /* TEXTAREA_AUTOGROW */
6580
#endif /* TEXTFIELDS_MAY_NEED_ACTIVATION */
6585
#ifdef TEXTAREA_AUTOGROW
6587
* If on the bottom line of a TEXTAREA, and the user hit
6588
* the ENTER key, we add a new line/anchor automatically,
6589
* positioning the cursor on it.
6591
* If at the bottom of the screen, we effectively perform
6592
* an LYK_DOWN_HALF-like operation, then move down to the
6593
* new line we just added. --KED 02/14/99
6595
* [There is some redundancy and non-standard indentation
6596
* in the monster-if() below. This is intentional ... to
6597
* try and improve the "readability" (such as it is).
6598
* Caveat emptor to anyone trying to change it.]
6600
if ((links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
6601
links[curdoc.link].l_form->type == F_TEXTAREA_TYPE) &&
6602
((curdoc.link == nlinks-1 &&
6603
!(more && HText_TAHasMoreLines(curdoc.link, 1)))
6605
((curdoc.link < nlinks-1) &&
6606
!(links[curdoc.link+1].type == WWW_FORM_LINK_TYPE &&
6607
links[curdoc.link+1].l_form->type == F_TEXTAREA_TYPE))
6609
((curdoc.link < nlinks-1) &&
6610
((links[curdoc.link+1].type == WWW_FORM_LINK_TYPE &&
6611
links[curdoc.link+1].l_form->type == F_TEXTAREA_TYPE)
6613
((links[curdoc.link].l_form->number !=
6614
links[curdoc.link+1].l_form->number) ||
6615
(strcmp (links[curdoc.link].l_form->name,
6616
links[curdoc.link+1].l_form->name) != 0)))))) {
6618
HText_ExpandTextarea (&links[curdoc.link], 1);
6620
if (links[curdoc.link].ly < display_lines) {
6621
refresh_screen = TRUE;
6625
Newline += (display_lines/2);
6626
if (nlinks > 0 && curdoc.link > -1 &&
6627
links[curdoc.link].ly > display_lines/2) {
6628
newdoc.link = curdoc.link;
6629
for (i = 0; links[i].ly <= (display_lines/2); i++)
6634
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
6635
if (textfields_need_activation) {
6636
textinput_activated = TRUE;
6637
textfields_need_activation = textfields_activation_option;
6638
#ifdef INACTIVE_INPUT_STYLE_VH
6639
textinput_redrawn = TRUE;
6645
#endif /* TEXTAREA_AUTOGROW */
6648
* Make return in input field (if it was returned
6649
* by change_form_link) act as LYK_NEXT_LINK,
6650
* independent of what key (if any) is mapped to
6651
* LYK_NEXT_LINK. - kw
6653
c = LAC_TO_LKC0(LYK_NEXT_LINK);
6657
if (old_c != c && old_c != real_c && c != real_c)
6661
#if defined(TEXTFIELDS_MAY_NEED_ACTIVATION) && defined(INACTIVE_INPUT_STYLE_VH)
6662
if (curlink_is_editable && !textinput_redrawn) {
6663
/*draw the text entry, but don't activate it*/
6664
textinput_redrawn = TRUE;
6665
change_form_link_ex(curdoc.link,
6666
&newdoc, &refresh_screen,
6667
use_last_tfpos, FALSE, TRUE);
6669
LYmove(links[curdoc.link].ly,
6670
((links[curdoc.link].lx > 0) ?
6671
(links[curdoc.link].lx - 1) : 0));
6676
#endif /* TEXTFIELDS_MAY_NEED_ACTIVATION && INACTIVE_INPUT_STYLE_VH */
6678
* Get a keystroke from the user.
6679
* Save the last keystroke to avoid
6680
* redundant error reporting.
6682
real_c = c = LYgetch(); /* get user input */
6689
if (c == 3) { /* ^C */
6691
* This shouldn't happen. We'll try to
6692
* deal with whatever bug caused it. - FM
6694
signal(SIGINT, cleanup_sig);
6700
if (LKC_HAS_ESC_MOD(c) && EditBinding(c) != LYE_FORM_PASS) {
6702
* If ESC + <key> was read (and not recognized as a
6703
* terminal escape sequence for another key), ignore
6704
* the ESC modifier and act on <key> only if the line
6705
* editor binding would have passed the same ESC-modified
6706
* lynxkeycode back to us if it had been pressed in a
6707
* text input field. Otherwise set interesting part
6708
* so that it will map to 0, to prevent that ESC + <key>
6709
* acts like <key>, which might be unexpected. - kw
6711
c = (c & ~LKC_MASK) | LAC_TO_LKC(0);
6713
if (old_c != real_c) {
6720
if (HadVMSInterrupt) {
6721
HadVMSInterrupt = FALSE;
6725
if (recent_sizechange) {
6733
* A goto point for new input without going
6734
* back through the getch() loop.
6737
if ((c = DoTraversal(c, &crawl_ok)) < 0)
6738
return (EXIT_FAILURE);
6742
if (c == DO_NOTHING)
6743
cmd = LYK_DO_NOTHING;
6746
cmd = LKC_TO_LAC(keymap,c); /* adds 1 to map EOF to 0 */
6748
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
6749
if (lynx_edit_mode && !no_dired_support && LKC_TO_LAC(key_override,c))
6750
cmd = LKC_TO_LAC(key_override,c);
6751
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
6756
* A goto point for new input without going
6757
* back through the getch() loop.
6760
force_old_UCLYhndl_on_reload = FALSE;
6763
if (cmd != LYK_UP_LINK && cmd != LYK_DOWN_LINK)
6768
HTUserMsg(COMMAND_UNKNOWN);
6770
case 0: /* unmapped character */
6772
if (curdoc.link >= 0 && curdoc.link < nlinks &&
6773
links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
6774
F_TEXTLIKE(links[curdoc.link].l_form->type)) {
6776
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
6777
if (textfields_need_activation) {
6778
show_main_statusline(links[curdoc.link], FOR_PANEL);
6779
#ifdef INACTIVE_INPUT_STYLE_VH
6780
textinput_redrawn = FALSE;
6784
show_main_statusline(links[curdoc.link], FOR_INPUT);
6786
HTInfoMsg(MOREHELP);
6793
sprintf(cfile, "%d", c);
6794
LYaddstr(cfile); /* show the user input */
6800
cmd = handle_LYK_COMMAND(user_input_buffer);
6805
* No network transmission to interrupt - 'til we multithread.
6809
case LYK_F_LINK_NUM:
6812
case LYK_1: /* FALLTHRU */
6813
case LYK_2: /* FALLTHRU */
6814
case LYK_3: /* FALLTHRU */
6815
case LYK_4: /* FALLTHRU */
6816
case LYK_5: /* FALLTHRU */
6817
case LYK_6: /* FALLTHRU */
6818
case LYK_7: /* FALLTHRU */
6819
case LYK_8: /* FALLTHRU */
6821
handle_LYK_digit(c, &force_load, user_input_buffer,
6822
&old_c, real_c, &try_internal);
6825
case LYK_SOURCE: /* toggle view source mode */
6826
handle_LYK_SOURCE(&ownerS_address);
6829
case LYK_CHG_CENTER: /* ^Q */
6831
if (no_table_center) {
6832
no_table_center = FALSE;
6833
HTInfoMsg(gettext("TABLE center enable."));
6835
no_table_center = TRUE;
6836
HTInfoMsg(gettext("TABLE center disable."));
6840
case LYK_RELOAD: /* control-R to reload and refresh */
6841
handle_LYK_RELOAD(real_cmd);
6844
case LYK_HISTORICAL: /* toggle 'historical' comments parsing */
6845
handle_LYK_HISTORICAL();
6848
case LYK_MINIMAL: /* toggle 'minimal' comments parsing */
6849
handle_LYK_MINIMAL();
6852
case LYK_SOFT_DQUOTES:
6853
handle_LYK_SOFT_DQUOTES();
6856
case LYK_SWITCH_DTD:
6857
handle_LYK_SWITCH_DTD();
6860
case LYK_QUIT: /* quit */
6861
if (handle_LYK_QUIT())
6862
return(EXIT_SUCCESS);
6865
case LYK_ABORT: /* don't ask the user about quitting */
6866
return(EXIT_SUCCESS);
6868
case LYK_NEXT_PAGE: /* next page */
6869
handle_LYK_NEXT_PAGE(&old_c, real_c);
6872
case LYK_PREV_PAGE: /* page up */
6873
handle_LYK_PREV_PAGE(&old_c, real_c);
6877
handle_LYK_UP_TWO(&arrowup, &old_c, real_c);
6881
handle_LYK_DOWN_TWO(&old_c, real_c);
6885
handle_LYK_UP_HALF(&arrowup, &old_c, real_c);
6889
handle_LYK_DOWN_HALF(&old_c, real_c);
6892
#ifdef CAN_CUT_AND_PASTE
6893
case LYK_TO_CLIPBOARD: /* ^S */
6898
/* The logic resembles one of ADD_BOOKMARK */
6899
if (nlinks > 0 && links[curdoc.link].lname
6900
&& links[curdoc.link].type != WWW_FORM_LINK_TYPE) {
6901
/* Makes sense to copy a link */
6902
_statusline("Copy D)ocument's or L)ink's URL to clipboard or C)ancel?");
6903
ch2 = LYgetch_single();
6906
else if (ch2 == 'C')
6909
s = links[curdoc.link].lname;
6913
HTInfoMsg(gettext("Current URL is empty."));
6915
HTInfoMsg(gettext("Copy to clipboard failed."));
6916
else if (s == curdoc.address)
6917
HTInfoMsg(gettext("Document URL put to clipboard."));
6919
HTInfoMsg(gettext("Link URL put to clipboard."));
6924
if (no_goto && !LYValidate) { /* Go to not allowed. - FM */
6925
HTUserMsg(GOTO_DISALLOWED);
6927
unsigned char *s = (unsigned char *) get_clip_grab(), *e, *t;
6933
len2 = strlen((const char *) s);
6935
while (s < e && strchr(" \t\n\r", *s))
6937
while (s < e && strchr(" \t\n\r", e[-1]))
6939
if (s[0] == '<' && e > s && e[-1] == '>') {
6941
if (!strncasecomp((const char *) s,"URL:", 4))
6945
HTInfoMsg(gettext("No URL in the clipboard."));
6950
len = MAX_LINE; /* Required for do_check_goto_URL() */
6951
buf = (char*)malloc(len);
6952
strncpy(buf, (const char *) s, e - s);
6954
t = (unsigned char *) buf;
6957
if (strchr(" \t\n\r", *s)) {
6958
int nl2 = 0; /* Keep whitespace without NL - file names! */
6959
unsigned char *s1 = s;
6961
while (strchr(" \t\n\r", *s)) {
6962
if (!nl2 && *s == '\n')
6968
if (*s1 != '\r' && *s1 != '\r')
6978
do_check_goto_URL(buf, &temp, &force_load);
6984
#ifdef KANJI_CODE_OVERRIDE
6985
case LYK_CHG_KCODE: /* ^L */
6986
if (LYRawMode && (HTCJK == JAPANESE)) {
6987
switch(last_kcode) {
6995
last_kcode = NOKANJI;
7002
lynx_start_title_color ();
7003
LYaddstr(str_kcode(last_kcode));
7004
lynx_stop_title_color ();
7010
refresh_screen = TRUE;
7011
lynx_force_repaint();
7015
if (curdoc.line > 1)
7018
cmd = LYK_PREV_PAGE;
7024
i = HText_getNumOfLines() - display_lines + 2;
7025
if (i >= 1 && Newline != i) {
7026
Newline = i; /* go to end of file */
7027
arrowup = TRUE; /* position on last link */
7029
cmd = LYK_NEXT_PAGE;
7034
case LYK_FIRST_LINK:
7035
handle_LYK_FIRST_LINK();
7039
handle_LYK_LAST_LINK();
7043
case LYK_LPOS_PREV_LINK:
7044
handle_LYK_PREV_LINK(&arrowup, &old_c, real_c);
7048
case LYK_LPOS_NEXT_LINK:
7049
handle_LYK_NEXT_LINK(c, &old_c, real_c);
7052
case LYK_FASTFORW_LINK:
7053
handle_LYK_FASTFORW_LINK(&old_c, real_c);
7056
case LYK_FASTBACKW_LINK:
7057
if (handle_LYK_FASTBACKW_LINK(&cmd, &old_c, real_c))
7062
handle_LYK_UP_LINK(&follow_col, &arrowup, &old_c, real_c);
7066
handle_LYK_DOWN_LINK(&follow_col, &old_c, real_c);
7069
case LYK_CHANGE_LINK:
7071
#if defined(TEXTFIELDS_MAY_NEED_ACTIVATION) && defined(INACTIVE_INPUT_STYLE_VH)
7072
if (textfields_need_activation)
7073
textinput_redrawn = FALSE;
7074
#endif /* TEXTFIELDS_MAY_NEED_ACTIVATION && INACTIVE_INPUT_STYLE_VH */
7077
case LYK_RIGHT_LINK:
7078
handle_LYK_RIGHT_LINK();
7082
handle_LYK_LEFT_LINK();
7085
case LYK_COOKIE_JAR: /* show the cookie jar */
7086
if (handle_LYK_COOKIE_JAR(&cmd))
7090
case LYK_HISTORY: /* show the history page */
7091
if (handle_LYK_HISTORY(ForcePush))
7095
case LYK_PREV_DOC: /* back up a level */
7096
switch (handle_PREV_DOC(&cmd, &old_c, real_c)) {
7098
return(EXIT_SUCCESS);
7104
case LYK_NEXT_DOC: /* undo back up a level */
7108
case LYK_NOCACHE: /* Force submission of form or link with no-cache */
7109
if (!handle_LYK_NOCACHE(&old_c, real_c))
7113
case LYK_ACTIVATE: /* follow a link */
7114
case LYK_SUBMIT: /* follow a link, submit TEXT_SUBMIT input */
7115
switch (handle_LYK_ACTIVATE(&c, cmd, &try_internal, &refresh_screen, &force_load, real_cmd)) {
7119
goto new_keyboard_input;
7125
case LYK_ELGOTO: /* edit URL of current link and go to it */
7126
if (handle_LYK_ELGOTO(&ch, user_input_buffer, &temp, &old_c, real_c))
7127
do_check_goto_URL(user_input_buffer, &temp, &force_load);
7130
case LYK_ECGOTO: /* edit current URL and go to to it */
7131
if (handle_LYK_ECGOTO(&ch, user_input_buffer, &temp, &old_c, real_c))
7132
do_check_goto_URL(user_input_buffer, &temp, &force_load);
7135
case LYK_GOTO: /* 'g' to goto a random URL */
7136
if (handle_LYK_GOTO(&ch, user_input_buffer, &temp, &recall,
7137
&URLTotal, &URLNum, &FirstURLRecall, &old_c,
7139
if (do_check_recall (ch, user_input_buffer, &temp, URLTotal,
7140
&URLNum, recall, &FirstURLRecall))
7141
do_check_goto_URL(user_input_buffer, &temp, &force_load);
7145
case LYK_DWIMHELP: /* show context-dependent help file */
7146
handle_LYK_DWIMHELP(&cshelpfile);
7149
case LYK_HELP: /* show help file */
7150
handle_LYK_HELP(&cshelpfile);
7153
case LYK_INDEX: /* index file */
7154
handle_LYK_INDEX(&old_c, real_c);
7157
case LYK_MAIN_MENU: /* return to main screen */
7158
handle_LYK_MAIN_MENU(&old_c, real_c);
7161
#ifdef EXP_NESTED_TABLES
7162
case LYK_NESTED_TABLES:
7163
if (handle_LYK_NESTED_TABLES(&cmd))
7167
case LYK_OPTIONS: /* options screen */
7168
if (handle_LYK_OPTIONS(&cmd, &refresh_screen))
7172
case LYK_INDEX_SEARCH: /* search for a user string */
7173
handle_LYK_INDEX_SEARCH(&force_load, ForcePush, &old_c, real_c);
7176
case LYK_WHEREIS: /* search within the document */
7177
case LYK_NEXT: /* find the next occurrence in the document */
7178
case LYK_PREV: /* find the previous occurrence in the document */
7179
handle_LYK_WHEREIS(cmd, &refresh_screen);
7182
case LYK_COMMENT: /* reply by mail */
7183
handle_LYK_COMMENT(&refresh_screen, &owner_address, &old_c, real_c);
7186
#ifdef DIRED_SUPPORT
7187
case LYK_TAG_LINK: /* tag or untag the current link */
7188
handle_LYK_TAG_LINK();
7191
case LYK_MODIFY: /* rename a file or directory */
7192
handle_LYK_MODIFY(&refresh_screen);
7195
case LYK_CREATE: /* create a new file or directory */
7196
handle_LYK_CREATE();
7198
#endif /* DIRED_SUPPORT */
7200
case LYK_DWIMEDIT: /* context-dependent edit */
7201
switch (handle_LYK_DWIMEDIT(&cmd, &old_c, real_c)) {
7209
case LYK_EDIT: /* edit */
7210
handle_LYK_EDIT(&old_c, real_c);
7213
case LYK_DEL_BOOKMARK: /* remove a bookmark file link */
7214
handle_LYK_DEL_BOOKMARK(&refresh_screen, &old_c, real_c);
7217
#ifdef DIRED_SUPPORT
7218
case LYK_REMOVE: /* remove files and directories */
7219
handle_LYK_REMOVE(&refresh_screen);
7221
#endif /* DIRED_SUPPORT */
7223
#if defined(DIRED_SUPPORT) && defined(OK_INSTALL)
7224
case LYK_INSTALL: /* install a file into system area */
7225
handle_LYK_INSTALL();
7227
#endif /* DIRED_SUPPORT && OK_INSTALL */
7229
case LYK_INFO: /* show document info */
7230
if (handle_LYK_INFO(&cmd))
7234
case LYK_EDIT_TEXTAREA: /* use external editor on a TEXTAREA - KED */
7235
handle_LYK_EDIT_TEXTAREA(&refresh_screen, &old_c, real_c);
7238
case LYK_GROW_TEXTAREA: /* add new lines to bottom of TEXTAREA - KED */
7239
handle_LYK_GROW_TEXTAREA(&refresh_screen);
7242
case LYK_INSERT_FILE: /* insert file in TEXTAREA, above cursor - KED */
7243
handle_LYK_INSERT_FILE(&refresh_screen, &old_c, real_c);
7246
case LYK_PRINT: /* print the file */
7247
handle_LYK_PRINT(&ForcePush, &old_c, real_c);
7250
case LYK_LIST: /* list links in the current document */
7251
if (handle_LYK_LIST(&cmd))
7255
#ifdef EXP_ADDRLIST_PAGE
7256
case LYK_ADDRLIST: /* always list URL's (only) */
7257
if (handle_LYK_ADDRLIST(&cmd))
7260
#endif /* EXP_ADDRLIST_PAGE */
7262
case LYK_VLINKS: /* list links visited during the current session */
7263
if (handle_LYK_VLINKS(&cmd, &newdoc_link_is_absolute))
7267
case LYK_TOOLBAR: /* go to Toolbar or Banner in current document */
7268
handle_LYK_TOOLBAR(&try_internal, &force_load, &old_c, real_c);
7271
#if defined(DIRED_SUPPORT) || defined(VMS)
7272
case LYK_DIRED_MENU: /* provide full file management menu */
7273
handle_LYK_DIRED_MENU(&refresh_screen, &old_c, real_c);
7275
#endif /* DIRED_SUPPORT || VMS*/
7277
#ifdef USE_EXTERNALS
7278
case LYK_EXTERN_LINK: /* use external program on url */
7279
handle_LYK_EXTERN_LINK(&refresh_screen);
7281
case LYK_EXTERN_PAGE: /* use external program on current page */
7282
handle_LYK_EXTERN_PAGE(&refresh_screen);
7284
#endif /* USE_EXTERNALS */
7286
case LYK_ADD_BOOKMARK: /* add link to bookmark file */
7287
handle_LYK_ADD_BOOKMARK(&refresh_screen, &old_c, real_c);
7290
case LYK_VIEW_BOOKMARK: /* v to view home page */
7291
handle_LYK_VIEW_BOOKMARK(&refresh_screen, &old_c, real_c);
7294
case LYK_SHELL: /* (!) shell escape */
7295
handle_LYK_SHELL(&refresh_screen, &old_c, real_c);
7299
switch (handle_LYK_DOWNLOAD(&cmd, &old_c, real_c)) {
7307
#ifdef DIRED_SUPPORT
7309
handle_LYK_UPLOAD();
7311
#endif /* DIRED_SUPPORT */
7313
case LYK_TRACE_TOGGLE: /* Toggle TRACE mode. */
7314
handle_LYK_TRACE_TOGGLE();
7317
case LYK_TRACE_LOG: /* View TRACE log. */
7318
handle_LYK_TRACE_LOG(&trace_mode_flag);
7321
case LYK_IMAGE_TOGGLE:
7322
if (handle_LYK_IMAGE_TOGGLE(&cmd))
7326
case LYK_INLINE_TOGGLE:
7327
if (handle_LYK_INLINE_TOGGLE(&cmd))
7331
case LYK_RAW_TOGGLE:
7332
if (handle_LYK_RAW_TOGGLE(&cmd))
7337
if (handle_LYK_HEAD(&cmd))
7341
case LYK_TOGGLE_HELP:
7342
handle_LYK_TOGGLE_HELP();
7346
handle_LYK_KEYMAP(&vi_keys_flag, &emacs_keys_flag, &old_c, real_c);
7350
if (handle_LYK_JUMP(c, user_input_buffer, &temp, &recall,
7351
&FirstURLRecall, &URLNum, &URLTotal, &ch,
7353
if (do_check_recall (ch, user_input_buffer, &temp, URLTotal,
7354
&URLNum, recall, &FirstURLRecall))
7355
do_check_goto_URL(user_input_buffer, &temp, &force_load);
7359
case LYK_CLEAR_AUTH:
7360
handle_LYK_CLEAR_AUTH(&old_c, real_c);
7363
case LYK_DO_NOTHING: /* pretty self explanatory */
7365
#ifdef SUPPORT_CHDIR
7370
#ifdef USE_CURSES_PADS
7371
case LYK_SHIFT_LEFT:
7372
handle_LYK_SHIFT_LEFT(&refresh_screen, key_count);
7374
case LYK_SHIFT_RIGHT:
7375
handle_LYK_SHIFT_RIGHT(&refresh_screen, key_count);
7377
case LYK_LINEWRAP_TOGGLE:
7378
if (handle_LYK_LINEWRAP_TOGGLE(&cmd, &refresh_screen))
7382
} /* end of BIG switch */
7386
PRIVATE int are_different ARGS2(
7393
* Do we have two addresses?
7395
if (!doc1->address || !doc2->address)
7399
* Do they differ in the type of request?
7401
if (doc1->isHEAD != doc2->isHEAD)
7405
* See if the addresses are different, making sure
7406
* we're not tripped up by multiple anchors in the
7407
* the same document from a POST form. -- FM
7409
cp1 = trimPoundSelector(doc1->address);
7410
cp2 = trimPoundSelector(doc2->address);
7412
* Are the base addresses different?
7414
if (strcmp(doc1->address, doc2->address)) {
7415
restorePoundSelector(cp1);
7416
restorePoundSelector(cp2);
7419
restorePoundSelector(cp1);
7420
restorePoundSelector(cp2);
7423
* Do the docs have different contents?
7425
if (doc1->post_data) {
7426
if (doc2->post_data) {
7427
if (!BINEQ(doc1->post_data, doc2->post_data))
7431
} else if (doc2->post_data)
7435
* We'll assume the two documents in fact are the same.
7440
/* This determines whether two docs are _physically_ different,
7441
* meaning they are "from different files". - kw
7443
#ifndef DONT_TRACK_INTERNAL_LINKS
7444
PRIVATE int are_phys_different ARGS2(
7448
char *cp1, *cp2, *ap1 = doc1->address, *ap2 = doc2->address;
7451
* Do we have two addresses?
7453
if (!doc1->address || !doc2->address)
7457
* Do they differ in the type of request?
7459
if (doc1->isHEAD != doc2->isHEAD)
7463
* Skip over possible LYNXIMGMAP parts. - kw
7465
if (isLYNXIMGMAP(doc1->address))
7466
ap1 += LEN_LYNXIMGMAP;
7467
if (isLYNXIMGMAP(doc2->address))
7468
ap2 += LEN_LYNXIMGMAP;
7470
* If there isn't any real URL in doc2->address, but maybe just
7471
* a fragment, doc2 is assumed to be an internal reference in
7472
* the same physical document, so return FALSE. - kw
7474
if (*ap2 == '\0' || *ap2 == '#')
7478
* See if the addresses are different, making sure
7479
* we're not tripped up by multiple anchors in the
7480
* the same document from a POST form. -- FM
7482
cp1 = trimPoundSelector(doc1->address);
7483
cp2 = trimPoundSelector(doc2->address);
7485
* Are the base addresses different?
7487
if (strcmp(ap1, ap2)) {
7488
restorePoundSelector(cp1);
7489
restorePoundSelector(cp2);
7492
restorePoundSelector(cp1);
7493
restorePoundSelector(cp2);
7496
* Do the docs have different contents?
7498
if (doc1->post_data) {
7499
if (doc2->post_data) {
7500
if (!BINEQ(doc1->post_data, doc2->post_data))
7504
} else if (doc2->post_data)
7508
* We'll assume the two documents in fact are the same.
7515
* Utility for freeing the list of goto URLs. - FM
7517
#ifdef LY_FIND_LEAKS
7518
PRIVATE void HTGotoURLs_free NOARGS
7521
HTList *cur = Goto_URLs;
7524
while (NULL != (url = (char *)HTList_nextObject(cur))) {
7527
HTList_delete(Goto_URLs);
7534
* Utility for listing Goto URLs, making any
7535
* repeated URLs the most current in the list. - FM
7537
PUBLIC void HTAddGotoURL ARGS1(
7547
CTRACE((tfp, "HTAddGotoURL %s\n", url));
7548
StrAllocCopy(new, url);
7551
Goto_URLs = HTList_new();
7552
#ifdef LY_FIND_LEAKS
7553
atexit(HTGotoURLs_free);
7555
HTList_addObject(Goto_URLs, new);
7560
while (NULL != (old = (char *)HTList_nextObject(cur))) {
7561
if (!strcmp(old, new)) {
7562
HTList_removeObject(Goto_URLs, old);
7567
HTList_addObject(Goto_URLs, new);
7573
* When help is not on the screen,
7574
* put a message on the screen
7575
* to tell the user other misc info.
7577
PRIVATE void show_main_statusline ARGS2(
7578
CONST LinkInfo, curlink,
7582
* Make sure form novice lines are replaced.
7584
if (user_mode == NOVICE_MODE && for_what != FOR_INPUT) {
7588
if (HTisDocumentSource()) {
7590
* Currently displaying HTML source.
7592
_statusline(SOURCE_HELP);
7595
* If we are in forms mode then explicitly
7596
* tell the user what each kind of link is.
7598
#ifdef INDICATE_FORMS_MODE_FOR_ALL_LINKS_ON_PAGE
7599
} else if (lynx_mode == FORMS_LYNX_MODE && nlinks > 0) {
7601
#ifdef NORMAL_NON_FORM_LINK_STATUSLINES_FOR_ALL_USER_MODES
7602
} else if (lynx_mode == FORMS_LYNX_MODE && nlinks > 0 &&
7603
!(curlink.type & WWW_LINK_TYPE)) {
7605
} else if (lynx_mode == FORMS_LYNX_MODE && nlinks > 0 &&
7606
!(user_mode == ADVANCED_MODE &&
7607
(curlink.type & WWW_LINK_TYPE))) {
7608
#endif /* NORMAL_NON_FORM_LINK_STATUSLINES_FOR_ALL_USER_MODES */
7609
#endif /* INDICATE_FORMS_MODE_FOR_ALL_LINKS_ON_PAGE */
7610
if (curlink.type == WWW_FORM_LINK_TYPE) {
7611
show_formlink_statusline(curlink.l_form, for_what);
7613
statusline(NORMAL_LINK_MESSAGE);
7617
* Let them know if it's an index -- very rare.
7620
char *indx = gettext("-index-");
7621
LYmove(LYlines-1, LYcols - strlen(indx) - 1);
7622
lynx_start_reverse();
7624
lynx_stop_reverse();
7627
} else if (user_mode == ADVANCED_MODE && nlinks > 0) {
7629
* Show the URL or, for some internal links, the fragment
7633
if (curlink.type == WWW_INTERN_LINK_TYPE &&
7634
!isLYNXIMGMAP(curlink.lname)) {
7635
cp = findPoundSelector(curlink.lname);
7639
status_link(cp, more, is_www_index);
7640
} else if (is_www_index && more) {
7643
sprintf(buf, WWW_INDEX_MORE_MESSAGE, key_for_func(LYK_INDEX_SEARCH));
7645
} else if (is_www_index) {
7648
sprintf(buf, WWW_INDEX_MESSAGE, key_for_func(LYK_INDEX_SEARCH));
7651
if (user_mode == NOVICE_MODE)
7654
_statusline(MOREHELP);
7659
/* turn off cursor since now it's probably on statusline -HV */
7660
/* But not if LYShowCursor is on. -show_cursor may be used as a
7661
* workaround to avoid putting the cursor in the last position, for
7662
* curses implementations or terminals that cannot deal with that
7663
* correctly. - kw */
7664
if (!LYShowCursor) {
7670
* Public function for redrawing the statusline appropriate for the
7671
* selected link. It should only be called at times when curdoc.link,
7672
* nlinks, and the links[] array are valid. - kw
7674
PUBLIC void repaint_main_statusline ARGS1(
7677
if (curdoc.link >= 0 && curdoc.link < nlinks)
7678
show_main_statusline(links[curdoc.link], for_what);
7681
PRIVATE void form_noviceline ARGS1(
7684
LYmove(LYlines-2,0); LYclrtoeol();
7686
LYaddstr(FORM_NOVICELINE_ONE);
7688
LYmove(LYlines-1,0); LYclrtoeol();
7691
if (EditBinding(FROMASCII('\025')) == LYE_ERASE) {
7692
LYaddstr(FORM_NOVICELINE_TWO);
7693
} else if (EditBinding(FROMASCII('\025')) == LYE_DELBL) {
7694
LYaddstr(FORM_NOVICELINE_TWO_DELBL);
7697
char *erasekey = fmt_keys(LYKeyForEditAction(LYE_ERASE), -1);
7699
HTSprintf0(&temp, FORM_NOVICELINE_TWO_VAR, erasekey);
7701
erasekey = fmt_keys(LYKeyForEditAction(LYE_DELBL), -1);
7704
FORM_NOVICELINE_TWO_DELBL_VAR, erasekey);
7714
PRIVATE void exit_immediately_with_error_message ARGS2(
7716
BOOLEAN, first_file)
7722
/* print statusline messages as a hint, if any */
7723
LYstatusline_messages_on_exit(&buf2);
7726
if (state == NOT_FOUND)
7728
HTSprintf0(&buf, "%s\n%s %s\n",
7730
gettext("lynx: Can't access startfile"),
7732
* hack: if we fail in HTAccess.c
7733
* avoid duplicating URL, oh.
7735
(buf2 && strstr(buf2, gettext("Can't Access"))) ?
7739
if (state == NULLFILE)
7741
HTSprintf0(&buf, "%s\n%s\n%s\n",
7743
gettext("lynx: Start file could not be found or is not text/html or text/plain"),
7744
gettext(" Exiting..."));
7749
if (!dump_output_immediately)
7753
if (dump_output_immediately) {
7758
SetOutputMode( O_TEXT );
7760
SetOutputMode( O_BINARY );
7765
if (!dump_output_immediately) {
7766
exit_immediately(EXIT_FAILURE);
7768
/* else: return(EXIT_FAILURE) in mainloop */
7772
PRIVATE void status_link ARGS3(
7773
char *, curlink_name,
7777
#define MAX_STATUS (LYcols - 2)
7778
#define MIN_STATUS 0
7779
char format[MAX_LINE];
7785
sprintf(format, "%.*s ",
7786
(int)(sizeof(format) - 2),
7788
prefix = strlen(format);
7791
sprintf(format + prefix, "%.*s ",
7792
(int)(sizeof(format) - prefix - 2),
7793
gettext("-index-"));
7795
prefix = strlen(format);
7796
length = strlen(curlink_name);
7798
if (prefix > MAX_STATUS || prefix >= MAX_LINE - 1) {
7799
_user_message("%s", format); /* no room for url */
7801
sprintf(format + prefix, "%%.%ds", MAX_STATUS - prefix);
7803
if ((length + prefix > MAX_STATUS) && long_url_ok) {
7809
StrAllocCopy(buf, curlink_name);
7811
* Scan to find the final leaf of the URL.
7812
* Ignore trailing '/'.
7814
for (cut_to_pos = length - 2;
7815
(cut_to_pos > 0) && (buf[cut_to_pos] != '/');
7819
* Jump back to the next leaf to remove.
7821
for (cut_from_pos = cut_to_pos - 4;
7822
(cut_from_pos > 0) && ((buf[cut_from_pos] != '/')
7823
|| (prefix + cut_from_pos + 4 + (length - cut_to_pos) >= MAX_STATUS));
7827
* Replace some leaves to '...', if possible, and put the
7828
* final leaf at the end. We assume that one can recognize
7829
* the link from at least MIN_STATUS characters.
7831
if (cut_from_pos > MIN_STATUS) {
7832
for (n = 1; n <= 3; n++)
7833
buf[cut_from_pos + n] = '.';
7834
for (n = 0; cut_to_pos + n <= length; n++)
7835
buf[cut_from_pos + 4 + n] = buf[cut_to_pos + n];
7837
_user_message(format, buf);
7838
CTRACE((tfp,"lastline = %s\n",buf)); /* don't forget to erase me */
7840
} else { /* show (possibly truncated) url */
7841
_user_message(format, curlink_name);
7847
LYDownLoadAddress NOARGS
7849
char *s = newdoc.address ? newdoc.address : "";