mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
Compare commits
37
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4099b5c828 | ||
|
|
813eb5a497 | ||
|
|
151d7a8cb1 | ||
|
|
b503d9e219 | ||
|
|
1f20ac6a3d | ||
|
|
5805e0ec88 | ||
|
|
9c7f4633c5 | ||
|
|
1aefa1fab9 | ||
|
|
b9cac4b178 | ||
|
|
c086ed0cc5 | ||
|
|
514ef2fdfc | ||
|
|
77528485e8 | ||
|
|
03c50e6573 | ||
|
|
bdfae0fed8 | ||
|
|
eddae793c8 | ||
|
|
10dd09ca4c | ||
|
|
281fb7d8a2 | ||
|
|
43bbea2cc8 | ||
|
|
dde557209a | ||
|
|
9c5f81332b | ||
|
|
7cc6a5d464 | ||
|
|
3a1396af29 | ||
|
|
31c2290fc1 | ||
|
|
2f580cc4c2 | ||
|
|
feecef8df3 | ||
|
|
8ca6be06ee | ||
|
|
19a1025e1c | ||
|
|
8bca5d0c0d | ||
|
|
c33f8dd282 | ||
|
|
2cc2d2f64f | ||
|
|
c555236ec7 | ||
|
|
a9a5c96f55 | ||
|
|
fbe0d8aa64 | ||
|
|
f77a60a27a | ||
|
|
ce139f7da0 | ||
|
|
f68ca7c41d | ||
|
|
187da1388d |
No files matched your search
@@ -12,6 +12,9 @@ Items affecting the ports and packages system can be found in
|
||||
/usr/ports/UPDATING. Please read that file before updating system packages
|
||||
and/or ports.
|
||||
|
||||
20260908:
|
||||
14.5-RELEASE.
|
||||
|
||||
20260727:
|
||||
The wait_for_pids() function in rc.subr, used by rc scripts
|
||||
when stopping or restarting a service, has been modified to
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
------------
|
||||
|
||||
Less
|
||||
Copyright (C) 1984-2025 Mark Nudelman
|
||||
Copyright (C) 1984-2026 Mark Nudelman
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
||||
@@ -9,6 +9,215 @@
|
||||
Report bugs, suggestions or comments at
|
||||
https://github.com/gwsw/less/issues.
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 702 and 704
|
||||
|
||||
* Fix possibly passing unsafe options to man when opening an
|
||||
OSC 8 link (github #779).
|
||||
|
||||
* Fix possibly sending unsafe OSC sequence to terminal when file
|
||||
contains an unterminated OSC sequence (github #781).
|
||||
|
||||
* In Examine and Shell commands, expand % and # to shell-escaped
|
||||
filenames (github #784).
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 692 and 702
|
||||
|
||||
* Add --hilite-target option and -DJ to color target line (github #745).
|
||||
|
||||
* Add --past-eof option.
|
||||
|
||||
* Add --end-prompt option.
|
||||
|
||||
* Add --emouse and --rmouse options, and horizontal mouse scrolling
|
||||
and dragging (github #744).
|
||||
|
||||
* Add -DT option to format tilde lines (github #725).
|
||||
|
||||
* Change OSC 8 link handling: replace LESS_OSC8_xxx with LESS_OSC8_OPEN_xxx.
|
||||
Remove %O from prompt expansion as no longer needed.
|
||||
Any use of environment variables LESS_OSC8_xxx need to be manually
|
||||
changed to use LESS_OSC8_OPEN_xxx.
|
||||
|
||||
* Add ?o to prompt strings, to detect whether an OSC 8 link is selected.
|
||||
|
||||
* When scrolling past end-of-file or before beginning-of-file,
|
||||
stop when exactly one line is left on screen.
|
||||
|
||||
* Make -w/-W highlight lines when moving backward as well as forward
|
||||
(github #729).
|
||||
|
||||
* Display pattern in "Pattern not found" message (github #731).
|
||||
|
||||
* Allow m and M commands to take a numeric argument to specify the
|
||||
line to be marked (github #736).
|
||||
|
||||
* Allow ' command to take a numeric argument to specify the screen
|
||||
position on which to place the marked line.
|
||||
|
||||
* Allow lesskey to map keypad ENTER with \kpe (github #761).
|
||||
|
||||
* Add "noaction" as a possible action in #line-edit section
|
||||
in a lesskey file (github #761).
|
||||
|
||||
* Support POSIX character classes with the built-in V8 regex library
|
||||
(github #732).
|
||||
|
||||
* Change | command to pipe just one line if the marked line is at the
|
||||
top of the screen (github #733).
|
||||
|
||||
* If OSC8 handler command begins with "-", suppress command echo,
|
||||
and if it begins with ctrl-P, suppress "done" message (github #747).
|
||||
|
||||
* Don't ask for confirmation when input is a binary file and stdout is
|
||||
redirected. Fixes infinite loop in that situation (github #719).
|
||||
|
||||
* Make early error messages go to stderr if stdout is redirected
|
||||
(github #719).
|
||||
|
||||
* Don't retry read after read error; fixes hang when attempting to read
|
||||
a directory or other unreadable file (github #741).
|
||||
|
||||
* Fix incorrect restoration of saved mark if not at top of screen.
|
||||
|
||||
* With --save-marks, don't save a mark that was cleared with ESC-m.
|
||||
|
||||
* Fix buffer overflow when using malformed lesskey file (github #721).
|
||||
|
||||
* Fix unexpected scrolling past end of file (github #720).
|
||||
|
||||
* Fix bug when env var in LESSKEY_CONTENT partially matches env var
|
||||
defined in lesskey file (github #727).
|
||||
|
||||
* Fix bug when env var in lesskey file matches tail of env var used
|
||||
by less (github #728).
|
||||
|
||||
* Fix command parsing bug when one command is a substring of another.
|
||||
Also fixes --no-paste option (github #724).
|
||||
|
||||
* Fix incorrect display using --color to set character attributes
|
||||
without color, such as -DS-u (github #730).
|
||||
|
||||
* Fix crash when tags file contains invalid line number 0 (github #743).
|
||||
|
||||
* Fix build when tparm() doesn't use varargs (github #748).
|
||||
|
||||
* Fix prompt overflow when filtering with long prompt (github #749).
|
||||
|
||||
* Fix incorrect highlighting when change -i while filtering (github #750).
|
||||
|
||||
* Fix erroneous error mesage using --show-preproc-error with
|
||||
some shells (github #753).
|
||||
|
||||
* Fix erroneous highlighting when using a search pattern containing more
|
||||
than 5 pairs of parentheses with PCRE2 (github #754).
|
||||
|
||||
* When ^X interrupts F mode, discard pending keys as is done when
|
||||
^C interrupts it (github #757).
|
||||
|
||||
* Fix bug in Windows where pressing any key during "waiting for data" would
|
||||
prevent a subsequent ^X from working.
|
||||
|
||||
* Fix erroneous display in some situations when using LESS_LINES (github #759).
|
||||
|
||||
* Fix erroneous display after certain messages are displayed in a
|
||||
very narrow terminal (github #760).
|
||||
|
||||
* Don't init terminal if stdout is not a tty (github #768).
|
||||
|
||||
* Fix bug clicking OSC 8 link that crosses a screen line boundary
|
||||
(github #775).
|
||||
|
||||
* Fix beeps when resizing window on Windows (github #771).
|
||||
|
||||
* Fix beeps when paging continuously on Windows (github #772).
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 691 and 692
|
||||
|
||||
* Revert HOME key to scroll to beginning of file and END key
|
||||
to scroll to end of file (github #658).
|
||||
|
||||
* Configure tty to leave CR and NL unmodified (github #703).
|
||||
|
||||
* Add commands to lesskey parser (forw-bell-hilite, goto-pos and osc8-jump).
|
||||
|
||||
* Add key sequences to lesskey parser (\kE, \kF, \kH, \kI, \kM, and \kS).
|
||||
|
||||
* Fix bug using negative value with -z option (github #709).
|
||||
|
||||
* Fix bug handling empty terminfo capabilties (github #710).
|
||||
|
||||
* Fix memory leak in setupterm (github #707).
|
||||
|
||||
* Make lesstest ignore system locale (nl_langinfo) (github #708).
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 685 and 691
|
||||
|
||||
* Add --autosave option (github #678).
|
||||
|
||||
* Add ESC-f command (github #680).
|
||||
|
||||
* Add column number to long prompt and = message.
|
||||
|
||||
* Add prompt prototype sequences %C, %W, %Q and ?Q (github #685).
|
||||
|
||||
* Map keypad keys, and use terminfo rather than termcap since keypad
|
||||
definitions don't exist in termcap (github #650).
|
||||
|
||||
* Change HOME key to scroll fully left and END key to scroll fully right.
|
||||
Add shift-HOME and ctrl-HOME to scroll left and jump to top, and
|
||||
add shift-END and ctrl-END to scroll right and jump to end (github #658).
|
||||
|
||||
* Add LESSNOCONFIG environment variable.
|
||||
|
||||
* Add --without-termlib to configure (github #701).
|
||||
|
||||
* When setting line number colors (-DN), don't force bold attribute.
|
||||
To set bold, you must append "d" or "*" to the color string (github #684).
|
||||
|
||||
* While waiting for file data, only ^C or ^X will interrupt, not any command.
|
||||
This reverts to behavior that existed before less-670 (github #700).
|
||||
|
||||
* When --save-marks is not used, retain any marks saved in the history file
|
||||
(github #662).
|
||||
|
||||
* Defer sending the terminal init string until the first char is read
|
||||
from the input file (github #682).
|
||||
|
||||
* Make SIGHUP do an orderly exit like SIGTERM.
|
||||
|
||||
* Implement modeline handling in Windows build.
|
||||
|
||||
* Fix bugs and improve behavior of screen resize on Windows.
|
||||
|
||||
* Fix bug when entering search modifier key at start of non-empty
|
||||
search string (github #668).
|
||||
|
||||
* Fix bug repainting screen with --form-feed (github #672).
|
||||
|
||||
* Fix bugs passing invalid negative values to some command line
|
||||
options (github #675).
|
||||
|
||||
* Fix incorrect display of Lit indicator (github #670).
|
||||
|
||||
* Fix incorrect display when returning to a mark after resizeing window
|
||||
(github #681).
|
||||
|
||||
* Fix bug using --pattern with --incsearch (github #696).
|
||||
|
||||
* Disallow mouse click to open OSC8 link in SECURE mode (github #676).
|
||||
|
||||
* Add SECURE_COMPILE environment variable for Windows builds.
|
||||
|
||||
* Update Unicode tables.
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 679 and 685
|
||||
|
||||
+21
-41
@@ -84,7 +84,7 @@ INSTALLATION (Unix & Linux systems only):
|
||||
Makefile now. Take particular notice of the list of "terminal"
|
||||
libraries in the LIBS definition in the Makefile; these may need
|
||||
to be edited. The terminal libraries will be some subset of
|
||||
-lncurses -lcurses -ltermcap -ltermlib
|
||||
-ltinfo -ltinfow -lxcurses -lncursesw -lncurses -lcurses -ltermcap -ltermlib
|
||||
|
||||
If you wish, you may edit defines.h to remove some optional features.
|
||||
If you choose not to include some features in your version, you may
|
||||
@@ -108,12 +108,27 @@ INSTALLATION (Unix & Linux systems only):
|
||||
bindir and/or mandir to the appropriate directories.
|
||||
|
||||
|
||||
Note to hackers: comments noting possible improvements are enclosed
|
||||
in double curly brackets {{ like this }}.
|
||||
|
||||
(Note that the above note was originally written at a time when
|
||||
"hackers" most commonly meant "enthusiastic and dedicated computer
|
||||
programmers", not "persons who attempt to circumvent computer security".)
|
||||
=======================================================================
|
||||
INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
|
||||
with Microsoft Visual C++, mingw, or Borland C)
|
||||
|
||||
1. Move the distributed source to its own directory.
|
||||
|
||||
2. If you wish, you may edit defines.wn to remove some optional features.
|
||||
If you choose not to include some features in your version, you may
|
||||
wish to edit the manual page less.man and the help page help.c
|
||||
to remove the descriptions of the features which you are removing.
|
||||
|
||||
3. If you are using Microsoft Visual C++, run "nmake -f Makefile.wnm".
|
||||
If you are using mingw, run "make -f Makefile.wng".
|
||||
If you are using Borland C, run "make -f Makefile.wnb".
|
||||
|
||||
If the environment variable SECURE_COMPILE is to 1 during the make,
|
||||
a "secure" version of less is built, with some features disabled.
|
||||
|
||||
4. If the make succeeds, it will generate the programs "less.exe" and
|
||||
"lesskey.exe" in your current directory. Test the generated programs.
|
||||
|
||||
|
||||
|
||||
@@ -156,34 +171,6 @@ INSTALLATION (MS-DOS systems only,
|
||||
|
||||
|
||||
|
||||
=======================================================================
|
||||
INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
|
||||
with Borland C or Microsoft Visual C++)
|
||||
|
||||
1. Move the distributed source to its own directory.
|
||||
|
||||
2. If you are using Borland C, rename Makefile.wnb to Makefile.
|
||||
If you are using Microsoft Visual C++, rename Makefile.wnm to Makefile.
|
||||
|
||||
3. Check the Makefile to make sure the definitions look ok.
|
||||
|
||||
4. If you wish, you may edit defines.wn to remove some optional features.
|
||||
If you choose not to include some features in your version, you may
|
||||
wish to edit the manual page less.man and the help page help.c
|
||||
to remove the descriptions of the features which you are removing.
|
||||
|
||||
5. Type "make" and watch the fun.
|
||||
|
||||
6. If the make succeeds, it will generate the programs "less.exe" and
|
||||
"lesskey.exe" in your current directory. Test the generated programs.
|
||||
|
||||
7. When satisfied that it works, if you wish to install it
|
||||
in a public place, type "make install".
|
||||
See step 6 of the Unix installation instructions for details
|
||||
on how to change the default installation directories.
|
||||
|
||||
|
||||
|
||||
=======================================================================
|
||||
INSTALLATION (OS/2 systems only,
|
||||
with EMX C)
|
||||
@@ -245,10 +232,3 @@ INSTALLATION (OS-9 systems only,
|
||||
See step 6 of the Unix installation instructions for details
|
||||
on how to change the default installation directories.
|
||||
|
||||
=======================================================================
|
||||
ACKNOWLEDGMENTS:
|
||||
Some versions of the less distribution are packaged using
|
||||
Info-ZIP's compression utility.
|
||||
Info-ZIP's software is free and can be obtained as source
|
||||
code or executables from various anonymous-ftp sites,
|
||||
including ftp.uu.net:/pub/archiving/zip.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+13
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
typedef POSITION BLOCKNUM;
|
||||
|
||||
public int ignore_eoi;
|
||||
public lbool ignore_eoi = FALSE;
|
||||
public lbool read_error = FALSE;
|
||||
|
||||
/*
|
||||
* Pool of buffers holding the most recently used blocks of the input file.
|
||||
@@ -292,13 +293,14 @@ static int ch_get(void)
|
||||
if (n < 0)
|
||||
{
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
if (errno != EPIPE)
|
||||
if (errno == EPIPE)
|
||||
n = 0;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
error("read error", NULL_PARG);
|
||||
clear_eol();
|
||||
read_error = TRUE;
|
||||
return (EOI);
|
||||
}
|
||||
n = 0;
|
||||
}
|
||||
|
||||
#if LOGFILE
|
||||
@@ -883,13 +885,13 @@ public void ch_init(int f, int flags, ssize_t nread)
|
||||
*/
|
||||
ch_fsize = (flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file);
|
||||
|
||||
/*
|
||||
* This is a kludge to workaround a Linux kernel bug: files in some
|
||||
* pseudo filesystems like /proc and tracefs have a size of 0 according
|
||||
* to fstat() but have readable data.
|
||||
*/
|
||||
if (ch_fsize == 0 && nread > 0)
|
||||
{
|
||||
/*
|
||||
* This is a kludge to workaround a Linux kernel bug: files in some
|
||||
* pseudo filesystems like /proc and tracefs have a size of 0 according
|
||||
* to fstat() but have readable data.
|
||||
*/
|
||||
ch_flags |= CH_NOTRUSTSIZE;
|
||||
}
|
||||
|
||||
|
||||
+33
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -202,20 +202,20 @@ static void ichardef_utf(constant char *s)
|
||||
switch (*s++)
|
||||
{
|
||||
case 'b':
|
||||
xbuf_add_data(&user_ubin_array, (unsigned char *) &range, sizeof(range));
|
||||
xbuf_add_data(&user_ubin_array, &range, sizeof(range));
|
||||
break;
|
||||
case 'c':
|
||||
xbuf_add_data(&user_compose_array, (unsigned char *) &range, sizeof(range));
|
||||
xbuf_add_data(&user_compose_array, &range, sizeof(range));
|
||||
break;
|
||||
case 'd':
|
||||
xbuf_add_data(&user_omit_array, (unsigned char *) &range, sizeof(range));
|
||||
xbuf_add_data(&user_omit_array, &range, sizeof(range));
|
||||
break;
|
||||
case 'w':
|
||||
xbuf_add_data(&user_wide_array, (unsigned char *) &range, sizeof(range));
|
||||
xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range));
|
||||
xbuf_add_data(&user_wide_array, &range, sizeof(range));
|
||||
xbuf_add_data(&user_prt_array, &range, sizeof(range));
|
||||
break;
|
||||
case 'p': case '.':
|
||||
xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range));
|
||||
xbuf_add_data(&user_prt_array, &range, sizeof(range));
|
||||
break;
|
||||
case '\0':
|
||||
s--;
|
||||
@@ -429,13 +429,21 @@ static void set_charset(void)
|
||||
/*
|
||||
* Try using the codeset name as the charset name.
|
||||
*/
|
||||
s = nl_langinfo(CODESET);
|
||||
if (icharset(s, 1))
|
||||
return;
|
||||
#if LESSTEST
|
||||
/*
|
||||
* Don't check nl_langinfo in lesstest mode; charset should come
|
||||
* only from environment variables, not from the system locale.
|
||||
*/
|
||||
if (0) /* {{ unfortunately it's too early to use is_lesstest }} */
|
||||
#endif
|
||||
{
|
||||
s = nl_langinfo(CODESET);
|
||||
if (icharset(s, 1))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_STRSTR
|
||||
/*
|
||||
* Check whether LC_ALL, LC_CTYPE or LANG look like UTF-8 is used.
|
||||
*/
|
||||
@@ -448,7 +456,6 @@ static void set_charset(void)
|
||||
if (icharset("utf-8", 1))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_LOCALE
|
||||
/*
|
||||
@@ -578,20 +585,21 @@ public constant char * prutfchar(LWCHAR ch)
|
||||
/*
|
||||
* Get the length of a UTF-8 character in bytes.
|
||||
*/
|
||||
public int utf_len(char ch)
|
||||
public int utf_len(char ach)
|
||||
{
|
||||
if ((ch & 0x80) == 0)
|
||||
unsigned char ch = (unsigned char) ach;
|
||||
if (IS_ASCII_OCTET(ch))
|
||||
return 1;
|
||||
if ((ch & 0xE0) == 0xC0)
|
||||
if (IS_UTF8_LEAD2(ch))
|
||||
return 2;
|
||||
if ((ch & 0xF0) == 0xE0)
|
||||
if (IS_UTF8_LEAD3(ch))
|
||||
return 3;
|
||||
if ((ch & 0xF8) == 0xF0)
|
||||
if (IS_UTF8_LEAD4(ch))
|
||||
return 4;
|
||||
#if 0
|
||||
if ((ch & 0xFC) == 0xF8)
|
||||
if (IS_UTF8_LEAD5(ch))
|
||||
return 5;
|
||||
if ((ch & 0xFE) == 0xFC)
|
||||
if (IS_UTF8_LEAD6(ch))
|
||||
return 6;
|
||||
#endif
|
||||
/* Invalid UTF-8 encoding. */
|
||||
@@ -601,16 +609,17 @@ public int utf_len(char ch)
|
||||
/*
|
||||
* Does the parameter point to the lead byte of a well-formed UTF-8 character?
|
||||
*/
|
||||
public lbool is_utf8_well_formed(constant char *ss, int slen)
|
||||
public lbool is_utf8_well_formed(constant char *ssa, int slen)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
unsigned char s0 = (unsigned char) ss[0];
|
||||
constant unsigned char *ss = (constant unsigned char *) ssa;
|
||||
unsigned char s0 = ss[0];
|
||||
|
||||
if (IS_UTF8_INVALID(s0))
|
||||
if (IS_UTF8_LEAD5(s0) || IS_UTF8_LEAD6(s0) || IS_UTF8_INVALID(s0))
|
||||
return (FALSE);
|
||||
|
||||
len = utf_len(ss[0]);
|
||||
len = utf_len(s0);
|
||||
if (len > slen)
|
||||
return (FALSE);
|
||||
if (len == 1)
|
||||
@@ -897,6 +906,7 @@ public lbool is_composing_char(LWCHAR ch)
|
||||
public lbool is_ubin_char(LWCHAR ch)
|
||||
{
|
||||
if (is_in_table(ch, &user_prt_table)) return FALSE;
|
||||
if (ch > MAX_UNICODE) return TRUE;
|
||||
return is_in_table(ch, &user_ubin_table) ||
|
||||
(is_in_table(ch, &ubin_table) ||
|
||||
(bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table) &&
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -16,3 +16,5 @@
|
||||
#define IS_UTF8_LEAD6(c) (((c) & 0xFE) == 0xFC)
|
||||
#define IS_UTF8_INVALID(c) (((c) & 0xFE) == 0xFE)
|
||||
#define IS_UTF8_LEAD(c) (((c) & 0xC0) == 0xC0 && !IS_UTF8_INVALID(c))
|
||||
|
||||
#define MAX_UNICODE 0x10FFFF
|
||||
+28
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -86,6 +86,9 @@
|
||||
#define A_OSC8_JUMP 74
|
||||
#define A_START_PASTE 75 /* must not overlap EC_* */
|
||||
#define A_END_PASTE 76 /* must not overlap EC_* */
|
||||
#define A_F_FOREVER_BELL 77
|
||||
#define A_L_MOUSE 78
|
||||
#define A_R_MOUSE 79
|
||||
|
||||
/* These values must not conflict with any A_* or EC_* value. */
|
||||
#define A_INVALID 100
|
||||
@@ -155,4 +158,28 @@
|
||||
#define SK_BACKTAB 15
|
||||
#define SK_CTL_BACKSPACE 16
|
||||
#define SK_BACKSPACE 17
|
||||
#define SK_PAD_U 18
|
||||
#define SK_PAD_D 19
|
||||
#define SK_PAD_R 20
|
||||
#define SK_PAD_L 21
|
||||
#define SK_PAD_UR 22
|
||||
#define SK_PAD_UL 23
|
||||
#define SK_PAD_DR 24
|
||||
#define SK_PAD_DL 25
|
||||
#define SK_PAD_CENTER 26
|
||||
#define SK_PAD_STAR 27
|
||||
#define SK_PAD_SLASH 28
|
||||
#define SK_PAD_DASH 29
|
||||
#define SK_PAD_PLUS 30
|
||||
#define SK_PAD_DOT 31
|
||||
#define SK_PAD_COMMA 32
|
||||
#define SK_PAD_ZERO 33
|
||||
#define SK_SHIFT_HOME 34
|
||||
#define SK_SHIFT_END 35
|
||||
#define SK_CTL_HOME 36
|
||||
#define SK_CTL_END 37
|
||||
#define SK_SHIFT_LEFT_ARROW 38
|
||||
#define SK_SHIFT_RIGHT_ARROW 39
|
||||
#define SK_PAD_ENTER 41
|
||||
|
||||
#define SK_CONTROL_K 40
|
||||
+84
-60
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -23,7 +23,7 @@
|
||||
extern int sc_width;
|
||||
extern int utf_mode;
|
||||
extern int no_hist_dups;
|
||||
extern int marks_modified;
|
||||
extern lbool marks_modified;
|
||||
extern int no_paste;
|
||||
public lbool pasting = FALSE;
|
||||
|
||||
@@ -35,6 +35,9 @@ static int cmd_offset; /* Index into cmdbuf of first displayed char */
|
||||
static lbool literal; /* Next input char should not be interpreted */
|
||||
static size_t updown_match; /* Prefix length in up/down movement */
|
||||
static lbool have_updown_match = FALSE;
|
||||
#if LESS_INSERT_MODE
|
||||
static lbool insert_mode = TRUE;
|
||||
#endif
|
||||
|
||||
static int cmd_complete(int action);
|
||||
/*
|
||||
@@ -110,8 +113,8 @@ static struct mlist *curr_mlist = NULL;
|
||||
static int curr_cmdflags;
|
||||
|
||||
static char cmd_mbc_buf[MAX_UTF_CHAR_LEN];
|
||||
static int cmd_mbc_buf_len;
|
||||
static int cmd_mbc_buf_index;
|
||||
static size_t cmd_mbc_buf_len;
|
||||
static size_t cmd_mbc_buf_index;
|
||||
|
||||
|
||||
/*
|
||||
@@ -189,7 +192,7 @@ public int len_cmdbuf(void)
|
||||
*/
|
||||
public lbool cmdbuf_empty(void)
|
||||
{
|
||||
return cp == cmdbuf && cmd_mbc_buf_len == 0;
|
||||
return cmdbuf[0] == '\0' && cmd_mbc_buf_len == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -454,39 +457,6 @@ static int cmd_left(void)
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a char into the command buffer, at the current position.
|
||||
*/
|
||||
static int cmd_ichar(constant char *cs, size_t clen)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1)
|
||||
{
|
||||
/* No room in the command buffer for another char. */
|
||||
bell();
|
||||
return (CC_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make room for the new character (shift the tail of the buffer right).
|
||||
*/
|
||||
for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--)
|
||||
s[clen] = s[0];
|
||||
/*
|
||||
* Insert the character into the buffer.
|
||||
*/
|
||||
for (s = cp; s < cp + clen; s++)
|
||||
*s = *cs++;
|
||||
/*
|
||||
* Reprint the tail of the line from the inserted char.
|
||||
*/
|
||||
have_updown_match = FALSE;
|
||||
cmd_repaint(cp);
|
||||
cmd_right();
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Backspace in the command buffer.
|
||||
* Delete the char to the left of the cursor.
|
||||
@@ -502,7 +472,7 @@ static int cmd_erase(void)
|
||||
* Backspace past beginning of the buffer:
|
||||
* this usually means abort the command.
|
||||
*/
|
||||
return (CC_QUIT);
|
||||
return CC_QUIT;
|
||||
}
|
||||
/*
|
||||
* Move cursor left (to the char being erased).
|
||||
@@ -532,7 +502,7 @@ static int cmd_erase(void)
|
||||
* to abort the current command, if CF_QUIT_ON_ERASE is set.
|
||||
*/
|
||||
if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0')
|
||||
return (CC_QUIT);
|
||||
return CC_QUIT;
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
@@ -554,6 +524,43 @@ static int cmd_delete(void)
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a char into the command buffer, at the current position.
|
||||
*/
|
||||
static int cmd_ichar(constant char *cs, size_t clen)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1)
|
||||
{
|
||||
/* No room in the command buffer for another char. */
|
||||
lbell();
|
||||
return (CC_ERROR);
|
||||
}
|
||||
|
||||
#if LESS_INSERT_MODE
|
||||
if (!insert_mode)
|
||||
cmd_delete();
|
||||
#endif
|
||||
/*
|
||||
* Make room for the new character (shift the tail of the buffer right).
|
||||
*/
|
||||
for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--)
|
||||
s[clen] = s[0];
|
||||
/*
|
||||
* Insert the character into the buffer.
|
||||
*/
|
||||
for (s = cp; s < cp + clen; s++)
|
||||
*s = *cs++;
|
||||
/*
|
||||
* Reprint the tail of the line from the inserted char.
|
||||
*/
|
||||
have_updown_match = FALSE;
|
||||
cmd_repaint(cp);
|
||||
cmd_right();
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete the "word" to the left of the cursor.
|
||||
*/
|
||||
@@ -612,7 +619,7 @@ static int cmd_kill(void)
|
||||
if (cmdbuf[0] == '\0')
|
||||
{
|
||||
/* Buffer is already empty; abort the current command. */
|
||||
return (CC_QUIT);
|
||||
return CC_QUIT;
|
||||
}
|
||||
cmd_offset = 0;
|
||||
cmd_home();
|
||||
@@ -625,7 +632,7 @@ static int cmd_kill(void)
|
||||
* to abort the current command, if CF_QUIT_ON_ERASE is set.
|
||||
*/
|
||||
if (curr_cmdflags & CF_QUIT_ON_ERASE)
|
||||
return (CC_QUIT);
|
||||
return CC_QUIT;
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
@@ -660,7 +667,7 @@ static int cmd_updown(int action)
|
||||
/*
|
||||
* The current command has no history list.
|
||||
*/
|
||||
bell();
|
||||
lbell();
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
@@ -705,7 +712,7 @@ static int cmd_updown(int action)
|
||||
/*
|
||||
* We didn't find a history entry that matches.
|
||||
*/
|
||||
bell();
|
||||
lbell();
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
@@ -796,6 +803,15 @@ public void cmd_addhist(struct mlist *mlist, constant char *cmd, lbool modified)
|
||||
* Thus, an UPARROW will always retrieve the previous command.
|
||||
*/
|
||||
mlist->curr_mp = ml->next;
|
||||
if (modified)
|
||||
{
|
||||
if (mlist == &mlist_search && autosave_action('/'))
|
||||
save_cmdhist();
|
||||
#if SHELL_ESCAPE || PIPEC
|
||||
else if (mlist == &mlist_shell && autosave_action('!'))
|
||||
save_cmdhist();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -904,6 +920,9 @@ static int cmd_edit(char c, lbool stay_in_completion)
|
||||
return (CC_OK);
|
||||
case EC_INSERT:
|
||||
not_in_completion();
|
||||
#if LESS_INSERT_MODE
|
||||
insert_mode = !insert_mode;
|
||||
#endif
|
||||
return (CC_OK);
|
||||
case EC_BACKSPACE:
|
||||
not_in_completion();
|
||||
@@ -914,7 +933,7 @@ static int cmd_edit(char c, lbool stay_in_completion)
|
||||
case EC_ABORT:
|
||||
not_in_completion();
|
||||
(void) cmd_kill();
|
||||
return (CC_QUIT);
|
||||
return CC_QUIT;
|
||||
case EC_W_BACKSPACE:
|
||||
not_in_completion();
|
||||
return (cmd_werase());
|
||||
@@ -950,17 +969,23 @@ static int cmd_istr(constant char *str)
|
||||
{
|
||||
constant char *endline = str + strlen(str);
|
||||
constant char *s;
|
||||
int action;
|
||||
|
||||
int action = CC_OK;
|
||||
#if LESS_INSERT_MODE
|
||||
lbool save_insert_mode = insert_mode;
|
||||
insert_mode = TRUE;
|
||||
#endif
|
||||
for (s = str; *s != '\0'; )
|
||||
{
|
||||
constant char *os = s;
|
||||
step_charc(&s, +1, endline);
|
||||
action = cmd_ichar(os, ptr_diff(s, os));
|
||||
if (action != CC_OK)
|
||||
return (action);
|
||||
break;
|
||||
}
|
||||
return (CC_OK);
|
||||
#if LESS_INSERT_MODE
|
||||
insert_mode = save_insert_mode;
|
||||
#endif
|
||||
return (action);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1171,7 +1196,7 @@ static int cmd_complete(int action)
|
||||
#endif /* TAB_COMPLETE_FILENAME */
|
||||
if (tk_text == NULL)
|
||||
{
|
||||
bell();
|
||||
lbell();
|
||||
return (CC_OK);
|
||||
}
|
||||
if (action == EC_EXPAND)
|
||||
@@ -1239,7 +1264,7 @@ static int cmd_complete(int action)
|
||||
|
||||
fail:
|
||||
in_completion = FALSE;
|
||||
bell();
|
||||
lbell();
|
||||
return (CC_OK);
|
||||
}
|
||||
|
||||
@@ -1281,7 +1306,7 @@ static int cmd_uchar(char c, size_t *plen)
|
||||
} else
|
||||
{
|
||||
/* UTF8_INVALID or stray UTF8_TRAIL */
|
||||
bell();
|
||||
lbell();
|
||||
return (CC_ERROR);
|
||||
}
|
||||
} else if (IS_UTF8_TRAIL(c))
|
||||
@@ -1293,19 +1318,19 @@ static int cmd_uchar(char c, size_t *plen)
|
||||
{
|
||||
/* complete, but not well formed (non-shortest form), sequence */
|
||||
cmd_mbc_buf_len = 0;
|
||||
bell();
|
||||
lbell();
|
||||
return (CC_ERROR);
|
||||
}
|
||||
} else
|
||||
{
|
||||
/* Flush incomplete (truncated) sequence. */
|
||||
cmd_mbc_buf_len = 0;
|
||||
bell();
|
||||
lbell();
|
||||
/* Handle new char. */
|
||||
goto retry;
|
||||
}
|
||||
|
||||
*plen = (size_t) cmd_mbc_buf_len; /*{{type-issue}}*/
|
||||
*plen = cmd_mbc_buf_len;
|
||||
cmd_mbc_buf_len = 0;
|
||||
}
|
||||
return (CC_PASS);
|
||||
@@ -1388,7 +1413,6 @@ public LINENUM cmd_int(mutable long *frac)
|
||||
{
|
||||
constant char *p;
|
||||
LINENUM n = 0;
|
||||
lbool err;
|
||||
|
||||
for (p = cmdbuf; *p >= '0' && *p <= '9'; p++)
|
||||
{
|
||||
@@ -1401,8 +1425,8 @@ public LINENUM cmd_int(mutable long *frac)
|
||||
*frac = 0;
|
||||
if (*p++ == '.')
|
||||
{
|
||||
*frac = getfraction(&p, NULL, &err);
|
||||
/* {{ do something if err is set? }} */
|
||||
/* {{ Just ignore error in fractional part. }} */
|
||||
(void) getfraction(&p, frac);
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
@@ -1447,7 +1471,7 @@ static int mlist_size(struct mlist *ml)
|
||||
static char * histfile_find(lbool must_exist)
|
||||
{
|
||||
constant char *home = lgetenv("HOME");
|
||||
char *name = NULL;
|
||||
char *name;
|
||||
|
||||
/* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */
|
||||
#if OS2
|
||||
@@ -1738,7 +1762,7 @@ public void save_cmdhist(void)
|
||||
int skip_shell;
|
||||
struct save_ctx ctx;
|
||||
constant char *s;
|
||||
FILE *fout = NULL;
|
||||
FILE *fout;
|
||||
int histsize = 0;
|
||||
|
||||
if (!secure_allow(SF_HISTORY) || !histfile_modified())
|
||||
|
||||
+177
-94
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -23,16 +23,17 @@
|
||||
extern int erase_char, erase2_char, kill_char;
|
||||
extern int sigs;
|
||||
extern int quit_if_one_screen;
|
||||
extern int one_screen;
|
||||
extern lbool one_screen;
|
||||
extern int sc_width;
|
||||
extern int sc_height;
|
||||
extern char *kent;
|
||||
extern lbool kent_mapped;
|
||||
extern int swindow;
|
||||
extern int jump_sline;
|
||||
extern lbool quitting;
|
||||
extern int wscroll;
|
||||
extern int top_scroll;
|
||||
extern int ignore_eoi;
|
||||
extern lbool ignore_eoi;
|
||||
extern int hshift;
|
||||
extern int bs_mode;
|
||||
extern int proc_backspace;
|
||||
@@ -48,14 +49,16 @@ extern void *ml_search;
|
||||
extern void *ml_examine;
|
||||
extern int wheel_lines;
|
||||
extern int def_search_type;
|
||||
extern int hilite_target;
|
||||
extern lbool search_wrapped;
|
||||
extern lbool no_poll;
|
||||
extern int no_paste;
|
||||
extern lbool pasting;
|
||||
extern int no_edit_warn;
|
||||
extern lbool read_error;
|
||||
extern POSITION soft_eof;
|
||||
extern POSITION search_incr_start;
|
||||
extern char *first_cmd_at_prompt;
|
||||
extern lbool prompting;
|
||||
#if SHELL_ESCAPE || PIPEC
|
||||
extern void *ml_shell;
|
||||
#endif
|
||||
@@ -66,9 +69,9 @@ extern constant char *editproto;
|
||||
extern char *osc8_uri;
|
||||
#endif
|
||||
extern int shift_count;
|
||||
extern int forw_prompt;
|
||||
extern lbool forw_prompt;
|
||||
extern int incr_search;
|
||||
extern int full_screen;
|
||||
extern lbool full_screen;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
extern int utf_mode;
|
||||
extern unsigned less_acp;
|
||||
@@ -86,6 +89,7 @@ static struct loption *curropt;
|
||||
static lbool opt_lower;
|
||||
static int optflag;
|
||||
static lbool optgetname;
|
||||
static POSITION toppos;
|
||||
static POSITION bottompos;
|
||||
static int save_hshift;
|
||||
static int save_bs_mode;
|
||||
@@ -154,7 +158,7 @@ static void start_mca(int action, constant char *prompt, void *mlist, int cmdfla
|
||||
set_mlist(mlist, cmdflags);
|
||||
}
|
||||
|
||||
public int in_mca(void)
|
||||
public lbool in_mca(void)
|
||||
{
|
||||
return (mca != 0 && mca != A_PREFIX);
|
||||
}
|
||||
@@ -209,7 +213,7 @@ static void mca_search1(void)
|
||||
cmd_putstr("/");
|
||||
else
|
||||
cmd_putstr("?");
|
||||
forw_prompt = 0;
|
||||
forw_prompt = FALSE;
|
||||
}
|
||||
|
||||
static void mca_search(void)
|
||||
@@ -249,7 +253,7 @@ static void mca_opt_toggle(void)
|
||||
cmd_putstr("!");
|
||||
break;
|
||||
}
|
||||
forw_prompt = 0;
|
||||
forw_prompt = FALSE;
|
||||
set_mlist(NULL, CF_OPTION);
|
||||
}
|
||||
|
||||
@@ -476,7 +480,7 @@ static int mca_opt_nonfirst_char(char c)
|
||||
}
|
||||
} else if (!ambig)
|
||||
{
|
||||
bell();
|
||||
lbell();
|
||||
}
|
||||
return (MCA_MORE);
|
||||
}
|
||||
@@ -575,7 +579,10 @@ static int mca_search_char(char c)
|
||||
*/
|
||||
if (!cmdbuf_empty() || literal_char)
|
||||
{
|
||||
lbool was_literal_char = literal_char;
|
||||
literal_char = FALSE;
|
||||
if (was_literal_char)
|
||||
mca_search1();
|
||||
return (NO_MCA);
|
||||
}
|
||||
|
||||
@@ -639,6 +646,17 @@ static int mca_search_char(char c)
|
||||
return (NO_MCA);
|
||||
}
|
||||
|
||||
/*
|
||||
* Jump back to the starting position of an incremental search.
|
||||
*/
|
||||
static void jump_search_incr_pos(void)
|
||||
{
|
||||
if (search_incr_pos.pos == NULL_POSITION)
|
||||
return;
|
||||
hshift = search_incr_hshift;
|
||||
jump_loc(search_incr_pos.pos, search_incr_pos.ln);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a character of a multi-character command.
|
||||
*/
|
||||
@@ -772,30 +790,21 @@ static int mca_char(char c)
|
||||
if (*pattern == '\0')
|
||||
{
|
||||
/* User has backspaced to an empty pattern. */
|
||||
undo_search(1);
|
||||
hshift = search_incr_hshift;
|
||||
jump_loc(search_incr_pos.pos, search_incr_pos.ln);
|
||||
undo_search(TRUE);
|
||||
jump_search_incr_pos();
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* Suppress tty polling while searching.
|
||||
* This avoids a problem where tty input
|
||||
* can cause the search to be interrupted.
|
||||
*/
|
||||
no_poll = TRUE;
|
||||
if (search(st | SRCH_INCR, pattern, 1) != 0)
|
||||
{
|
||||
/* No match, invalid pattern, etc. */
|
||||
undo_search(1);
|
||||
hshift = search_incr_hshift;
|
||||
jump_loc(search_incr_pos.pos, search_incr_pos.ln);
|
||||
undo_search(TRUE);
|
||||
jump_search_incr_pos();
|
||||
}
|
||||
no_poll = FALSE;
|
||||
}
|
||||
/* Redraw the search prompt and search string. */
|
||||
if (is_screen_trashed() || !full_screen)
|
||||
{
|
||||
clear();
|
||||
lclear();
|
||||
repaint();
|
||||
}
|
||||
mca_search1();
|
||||
@@ -846,12 +855,6 @@ public int is_screen_trashed(void)
|
||||
*/
|
||||
static void make_display(void)
|
||||
{
|
||||
/*
|
||||
* If not full_screen, we can't rely on scrolling to fill the screen.
|
||||
* We need to clear and repaint screen before any change.
|
||||
*/
|
||||
if (!full_screen && !(quit_if_one_screen && one_screen))
|
||||
clear();
|
||||
/*
|
||||
* If nothing is displayed yet, display starting from initial_scrpos.
|
||||
*/
|
||||
@@ -864,9 +867,9 @@ static void make_display(void)
|
||||
} else if (is_screen_trashed() || !full_screen)
|
||||
{
|
||||
int save_top_scroll = top_scroll;
|
||||
int save_ignore_eoi = ignore_eoi;
|
||||
lbool save_ignore_eoi = ignore_eoi;
|
||||
top_scroll = 1;
|
||||
ignore_eoi = 0;
|
||||
ignore_eoi = FALSE;
|
||||
if (is_screen_trashed() == 2)
|
||||
{
|
||||
/* Special case used by ignore_eoi: re-open the input file
|
||||
@@ -880,12 +883,47 @@ static void make_display(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Display any message that needs to be displayed before the prompt.
|
||||
*/
|
||||
static void prompt_message(void)
|
||||
{
|
||||
if (read_error)
|
||||
{
|
||||
error("read error", NULL_PARG);
|
||||
read_error = FALSE;
|
||||
}
|
||||
if (search_wrapped)
|
||||
{
|
||||
if (search_type & SRCH_BACK)
|
||||
error("Search hit top; continuing at bottom", NULL_PARG);
|
||||
else
|
||||
error("Search hit bottom; continuing at top", NULL_PARG);
|
||||
search_wrapped = FALSE;
|
||||
}
|
||||
#if OSC8_LINK
|
||||
if (osc8_uri != NULL)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = osc8_uri;
|
||||
error("Link: %s", &parg);
|
||||
free(osc8_uri);
|
||||
osc8_uri = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the appropriate prompt.
|
||||
*/
|
||||
static void prompt(void)
|
||||
{
|
||||
constant char *p;
|
||||
int attr;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
WCHAR w[MAX_PATH*2];
|
||||
char a[MAX_PATH*2];
|
||||
#endif
|
||||
|
||||
if (ungot != NULL && !ungot->ug_end_command)
|
||||
{
|
||||
@@ -900,6 +938,10 @@ static void prompt(void)
|
||||
* Make sure the screen is displayed.
|
||||
*/
|
||||
make_display();
|
||||
|
||||
if (hilite_target)
|
||||
draw_target_attn(TRUE); /* Redraw target line for --hilite-target. */
|
||||
toppos = position(TOP);
|
||||
bottompos = position(BOTTOM_PLUS_ONE);
|
||||
|
||||
/*
|
||||
@@ -917,7 +959,7 @@ static void prompt(void)
|
||||
entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) &&
|
||||
next_ifile(curr_ifile) == NULL_IFILE)
|
||||
quit(QUIT_OK);
|
||||
quit_if_one_screen = FALSE; /* only get one chance at this */
|
||||
quit_if_one_screen = 0; /* only get one chance at this */
|
||||
if (first_cmd_at_prompt != NULL)
|
||||
{
|
||||
ungetsc(first_cmd_at_prompt);
|
||||
@@ -928,6 +970,7 @@ static void prompt(void)
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
/*
|
||||
* In Win32, display the file name in the window title.
|
||||
* {{ Seems like this should be done in edit_ifile, not on every prompt. }}
|
||||
*/
|
||||
if (!(ch_getflags() & CH_HELPFILE))
|
||||
{
|
||||
@@ -954,50 +997,43 @@ static void prompt(void)
|
||||
if (!forw_prompt)
|
||||
clear_bot();
|
||||
clear_cmd();
|
||||
forw_prompt = 0;
|
||||
forw_prompt = FALSE;
|
||||
prompt_message();
|
||||
/* We called make_display above, but if prompt_message displayed
|
||||
* a message longer than the screen width, we may have trashed
|
||||
* the screen and need to call make_display again. */
|
||||
if (is_screen_trashed())
|
||||
make_display();
|
||||
p = pr_string();
|
||||
#if HILITE_SEARCH
|
||||
if (is_filtering())
|
||||
putstr("& ");
|
||||
#endif
|
||||
if (search_wrapped)
|
||||
{
|
||||
if (search_type & SRCH_BACK)
|
||||
error("Search hit top; continuing at bottom", NULL_PARG);
|
||||
else
|
||||
error("Search hit bottom; continuing at top", NULL_PARG);
|
||||
search_wrapped = FALSE;
|
||||
}
|
||||
#if OSC8_LINK
|
||||
if (osc8_uri != NULL)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = osc8_uri;
|
||||
error("Link: %s", &parg);
|
||||
free(osc8_uri);
|
||||
osc8_uri = NULL;
|
||||
}
|
||||
#endif
|
||||
if (p == NULL || *p == '\0')
|
||||
{
|
||||
at_enter(AT_NORMAL|AT_COLOR_PROMPT);
|
||||
putchr(':');
|
||||
at_exit();
|
||||
p = ":";
|
||||
attr = AT_NORMAL|AT_COLOR_PROMPT;
|
||||
} else
|
||||
{
|
||||
attr = AT_STANDOUT|AT_COLOR_PROMPT;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
WCHAR w[MAX_PATH*2];
|
||||
char a[MAX_PATH*2];
|
||||
MultiByteToWideChar(less_acp, 0, p, -1, w, countof(w));
|
||||
WideCharToMultiByte(utf_mode ? CP_UTF8 : GetConsoleOutputCP(),
|
||||
0, w, -1, a, sizeof(a), NULL, NULL);
|
||||
p = a;
|
||||
#endif
|
||||
load_line(p);
|
||||
put_line(FALSE);
|
||||
}
|
||||
#if HILITE_SEARCH
|
||||
if (is_filtering())
|
||||
{
|
||||
constant char *amp = "& ";
|
||||
load_line(p, attr, strlen(amp)+1);
|
||||
putstr(amp);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
load_line(p, attr, 1);
|
||||
}
|
||||
put_line(FALSE);
|
||||
clear_eol();
|
||||
resume_screen();
|
||||
prompting = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1135,8 +1171,9 @@ static char getcc_repl(char constant *orig, char constant *repl, char (*gr_getc)
|
||||
*/
|
||||
public char getcc(void)
|
||||
{
|
||||
/* Replace kent (keypad Enter) with a newline. */
|
||||
return getcc_repl(kent, "\n", getccu, ungetcc);
|
||||
/* Replace kent (keypad Enter) with a newline.
|
||||
* However don't do this if kent is mapped to a command via lesskey. */
|
||||
return getcc_repl(kent_mapped ? NULL : kent, "\n", getccu, ungetcc);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1287,7 +1324,14 @@ static void multi_search(constant char *pattern, int n, int silent)
|
||||
* Print an error message if we haven't already.
|
||||
*/
|
||||
if (n > 0 && !silent)
|
||||
error("Pattern not found", NULL_PARG);
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = prev_pattern_text();
|
||||
if (parg.p_string == NULL) /* {{ can this happen? }} */
|
||||
error("Pattern not found", NULL_PARG);
|
||||
else
|
||||
error("Pattern not found: %s", &parg);
|
||||
}
|
||||
|
||||
if (changed_file)
|
||||
{
|
||||
@@ -1304,29 +1348,31 @@ static void multi_search(constant char *pattern, int n, int silent)
|
||||
/*
|
||||
* Forward forever, or until a highlighted line appears.
|
||||
*/
|
||||
static int forw_loop(int until_hilite)
|
||||
static int forw_loop(int action)
|
||||
{
|
||||
POSITION curr_len;
|
||||
POSITION prev_hilite;
|
||||
|
||||
if (ch_getflags() & CH_HELPFILE)
|
||||
return (A_NOACTION);
|
||||
|
||||
cmd_exec();
|
||||
jump_forw_buffered();
|
||||
curr_len = ch_length();
|
||||
highest_hilite = until_hilite ? curr_len : NULL_POSITION;
|
||||
ignore_eoi = 1;
|
||||
highest_hilite = prev_hilite = 0;
|
||||
ignore_eoi = TRUE;
|
||||
while (!sigs)
|
||||
{
|
||||
if (until_hilite && highest_hilite > curr_len)
|
||||
if (action != A_F_FOREVER && highest_hilite > prev_hilite)
|
||||
{
|
||||
bell();
|
||||
break;
|
||||
lbell();
|
||||
if (action == A_F_UNTIL_HILITE)
|
||||
break;
|
||||
prev_hilite = highest_hilite;
|
||||
}
|
||||
make_display();
|
||||
forward(1, FALSE, FALSE, FALSE);
|
||||
}
|
||||
ignore_eoi = 0;
|
||||
highest_hilite = NULL_POSITION;
|
||||
ignore_eoi = FALSE;
|
||||
ch_set_eof();
|
||||
|
||||
/*
|
||||
@@ -1334,7 +1380,7 @@ static int forw_loop(int until_hilite)
|
||||
* a non-abort signal (e.g. window-change).
|
||||
*/
|
||||
if (sigs && !ABORT_SIGS())
|
||||
return (until_hilite ? A_F_UNTIL_HILITE : A_F_FOREVER);
|
||||
return (action);
|
||||
|
||||
return (A_NOACTION);
|
||||
}
|
||||
@@ -1342,7 +1388,7 @@ static int forw_loop(int until_hilite)
|
||||
/*
|
||||
* Ignore subsequent (pasted) input chars.
|
||||
*/
|
||||
public void start_ignoring_input()
|
||||
public void start_ignoring_input(void)
|
||||
{
|
||||
ignoring_input = TRUE;
|
||||
#if HAVE_TIME
|
||||
@@ -1353,7 +1399,7 @@ public void start_ignoring_input()
|
||||
/*
|
||||
* Stop ignoring input chars.
|
||||
*/
|
||||
public void stop_ignoring_input()
|
||||
public void stop_ignoring_input(void)
|
||||
{
|
||||
ignoring_input = FALSE;
|
||||
pasting = FALSE;
|
||||
@@ -1401,7 +1447,6 @@ public void commands(void)
|
||||
#endif
|
||||
|
||||
search_type = SRCH_FORW;
|
||||
wscroll = (sc_height + 1) / 2;
|
||||
newaction = A_NOACTION;
|
||||
|
||||
for (;;)
|
||||
@@ -1438,6 +1483,8 @@ public void commands(void)
|
||||
c = getcc();
|
||||
|
||||
again:
|
||||
if (c == READ_AGAIN)
|
||||
continue;
|
||||
if (sigs)
|
||||
continue;
|
||||
|
||||
@@ -1507,7 +1554,9 @@ public void commands(void)
|
||||
* want erase_char/kill_char to be treated
|
||||
* as line editing characters.
|
||||
*/
|
||||
constant char tbuf[2] = { c, '\0' };
|
||||
char tbuf[2];
|
||||
tbuf[0] = c;
|
||||
tbuf[1] = '\0';
|
||||
action = fcmd_decode(tbuf, &extra);
|
||||
}
|
||||
/*
|
||||
@@ -1575,12 +1624,13 @@ public void commands(void)
|
||||
if (number <= 0)
|
||||
number = get_swindow();
|
||||
cmd_exec();
|
||||
if (show_attn && toppos != NULL_POSITION && toppos > ch_zero())
|
||||
set_attnpos(toppos-1);
|
||||
backward((int) number, FALSE, TRUE, FALSE);
|
||||
break;
|
||||
|
||||
case A_F_LINE:
|
||||
case A_F_NEWLINE:
|
||||
|
||||
/*
|
||||
* Forward N (default 1) line.
|
||||
*/
|
||||
@@ -1600,6 +1650,8 @@ public void commands(void)
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
cmd_exec();
|
||||
if (show_attn == OPT_ONPLUS && number > 1 && toppos != NULL_POSITION && toppos > ch_zero())
|
||||
set_attnpos(toppos-1);
|
||||
backward((int) number, FALSE, FALSE, action == A_B_NEWLINE && !chopline);
|
||||
break;
|
||||
|
||||
@@ -1619,6 +1671,29 @@ public void commands(void)
|
||||
backward(wheel_lines, FALSE, FALSE, FALSE);
|
||||
break;
|
||||
|
||||
case A_L_MOUSE:
|
||||
/*
|
||||
* Left wheel_lines columns.
|
||||
*/
|
||||
cmd_exec();
|
||||
pos_rehead(FALSE);
|
||||
if (wheel_lines > hshift)
|
||||
hshift = 0;
|
||||
else
|
||||
hshift -= wheel_lines;
|
||||
screen_trashed();
|
||||
break;
|
||||
|
||||
case A_R_MOUSE:
|
||||
/*
|
||||
* Right wheel_lines columns.
|
||||
*/
|
||||
cmd_exec();
|
||||
pos_rehead(FALSE);
|
||||
hshift += wheel_lines;
|
||||
screen_trashed();
|
||||
break;
|
||||
|
||||
case A_FF_LINE:
|
||||
/*
|
||||
* Force forward N (default 1) line.
|
||||
@@ -1638,6 +1713,8 @@ public void commands(void)
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
cmd_exec();
|
||||
if (show_attn == OPT_ONPLUS && number > 1 && toppos != NULL_POSITION && toppos > ch_zero())
|
||||
set_attnpos(toppos-1);
|
||||
backward((int) number, TRUE, FALSE, FALSE);
|
||||
break;
|
||||
|
||||
@@ -1660,10 +1737,14 @@ public void commands(void)
|
||||
if (number <= 0)
|
||||
number = get_swindow();
|
||||
cmd_exec();
|
||||
if (show_attn == OPT_ONPLUS && toppos != NULL_POSITION && toppos > ch_zero())
|
||||
set_attnpos(toppos-1);
|
||||
backward((int) number, TRUE, FALSE, FALSE);
|
||||
break;
|
||||
|
||||
case A_F_FOREVER:
|
||||
case A_F_FOREVER_BELL:
|
||||
case A_F_UNTIL_HILITE:
|
||||
/*
|
||||
* Forward forever, ignoring EOF.
|
||||
*/
|
||||
@@ -1671,11 +1752,7 @@ public void commands(void)
|
||||
error("Warning: command may not work correctly when file is viewed via LESSOPEN", NULL_PARG);
|
||||
if (show_attn)
|
||||
set_attnpos(bottompos);
|
||||
newaction = forw_loop(0);
|
||||
break;
|
||||
|
||||
case A_F_UNTIL_HILITE:
|
||||
newaction = forw_loop(1);
|
||||
newaction = forw_loop(action);
|
||||
break;
|
||||
|
||||
case A_F_SCROLL:
|
||||
@@ -1699,6 +1776,8 @@ public void commands(void)
|
||||
if (number > 0)
|
||||
wscroll = (int) number;
|
||||
cmd_exec();
|
||||
if (show_attn == OPT_ONPLUS && toppos != NULL_POSITION && toppos > ch_zero())
|
||||
set_attnpos(toppos-1);
|
||||
backward(wscroll, FALSE, FALSE, FALSE);
|
||||
break;
|
||||
|
||||
@@ -1958,6 +2037,7 @@ public void commands(void)
|
||||
/*
|
||||
* Clear search string highlighting.
|
||||
*/
|
||||
cmd_exec();
|
||||
undo_search(action == A_CLR_SEARCH);
|
||||
break;
|
||||
|
||||
@@ -2143,7 +2223,7 @@ public void commands(void)
|
||||
cmd_exec();
|
||||
if (new_ifile == NULL_IFILE)
|
||||
{
|
||||
bell();
|
||||
lbell();
|
||||
break;
|
||||
}
|
||||
if (edit_ifile(new_ifile) != 0)
|
||||
@@ -2224,9 +2304,11 @@ public void commands(void)
|
||||
}
|
||||
start_mca(A_SETMARK, "set mark: ", NULL, 0);
|
||||
c = getcc();
|
||||
make_display();
|
||||
cmd_exec();
|
||||
if (is_erase_char(c) || is_newline_char(c))
|
||||
break;
|
||||
setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP);
|
||||
setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP, number);
|
||||
repaint();
|
||||
break;
|
||||
|
||||
@@ -2236,6 +2318,7 @@ public void commands(void)
|
||||
*/
|
||||
start_mca(A_CLRMARK, "clear mark: ", NULL, 0);
|
||||
c = getcc();
|
||||
cmd_exec();
|
||||
if (is_erase_char(c) || is_newline_char(c))
|
||||
break;
|
||||
clrmark(c);
|
||||
@@ -2251,7 +2334,7 @@ public void commands(void)
|
||||
if (is_erase_char(c) || is_newline_char(c))
|
||||
break;
|
||||
cmd_exec();
|
||||
gomark(c);
|
||||
gomark(c, number);
|
||||
break;
|
||||
|
||||
case A_PIPE:
|
||||
@@ -2294,7 +2377,7 @@ public void commands(void)
|
||||
number = (shift_count > 0) ? shift_count : sc_width / 2;
|
||||
if (number > hshift)
|
||||
number = hshift;
|
||||
pos_rehead();
|
||||
pos_rehead(FALSE);
|
||||
hshift -= (int) number;
|
||||
screen_trashed();
|
||||
cmd_exec();
|
||||
@@ -2308,7 +2391,7 @@ public void commands(void)
|
||||
shift_count = (int) number;
|
||||
else
|
||||
number = (shift_count > 0) ? shift_count : sc_width / 2;
|
||||
pos_rehead();
|
||||
pos_rehead(FALSE);
|
||||
hshift += (int) number;
|
||||
screen_trashed();
|
||||
cmd_exec();
|
||||
@@ -2318,7 +2401,7 @@ public void commands(void)
|
||||
/*
|
||||
* Shift view left to margin.
|
||||
*/
|
||||
pos_rehead();
|
||||
pos_rehead(FALSE);
|
||||
hshift = 0;
|
||||
screen_trashed();
|
||||
cmd_exec();
|
||||
@@ -2328,7 +2411,7 @@ public void commands(void)
|
||||
/*
|
||||
* Shift view right to view rightmost char on screen.
|
||||
*/
|
||||
pos_rehead();
|
||||
pos_rehead(FALSE);
|
||||
hshift = rrshift();
|
||||
screen_trashed();
|
||||
cmd_exec();
|
||||
@@ -2353,7 +2436,7 @@ public void commands(void)
|
||||
break;
|
||||
|
||||
default:
|
||||
bell();
|
||||
lbell();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Aug 11 0:27:25 GMT 2025 */
|
||||
/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Nov 28 1:30:11 GMT 2025 */
|
||||
{ 0x0300, 0x036f }, /* Mn */
|
||||
{ 0x0483, 0x0487 }, /* Mn */
|
||||
{ 0x0488, 0x0489 }, /* Me */
|
||||
@@ -144,7 +144,8 @@
|
||||
{ 0x1a7f, 0x1a7f }, /* Mn */
|
||||
{ 0x1ab0, 0x1abd }, /* Mn */
|
||||
{ 0x1abe, 0x1abe }, /* Me */
|
||||
{ 0x1abf, 0x1ace }, /* Mn */
|
||||
{ 0x1abf, 0x1add }, /* Mn */
|
||||
{ 0x1ae0, 0x1aeb }, /* Mn */
|
||||
{ 0x1b00, 0x1b03 }, /* Mn */
|
||||
{ 0x1b34, 0x1b34 }, /* Mn */
|
||||
{ 0x1b36, 0x1b3a }, /* Mn */
|
||||
@@ -230,7 +231,7 @@
|
||||
{ 0x10d24, 0x10d27 }, /* Mn */
|
||||
{ 0x10d69, 0x10d6d }, /* Mn */
|
||||
{ 0x10eab, 0x10eac }, /* Mn */
|
||||
{ 0x10efc, 0x10eff }, /* Mn */
|
||||
{ 0x10efa, 0x10eff }, /* Mn */
|
||||
{ 0x10f46, 0x10f50 }, /* Mn */
|
||||
{ 0x10f82, 0x10f85 }, /* Mn */
|
||||
{ 0x11001, 0x11001 }, /* Mn */
|
||||
@@ -305,6 +306,9 @@
|
||||
{ 0x11a59, 0x11a5b }, /* Mn */
|
||||
{ 0x11a8a, 0x11a96 }, /* Mn */
|
||||
{ 0x11a98, 0x11a99 }, /* Mn */
|
||||
{ 0x11b60, 0x11b60 }, /* Mn */
|
||||
{ 0x11b62, 0x11b64 }, /* Mn */
|
||||
{ 0x11b66, 0x11b66 }, /* Mn */
|
||||
{ 0x11c30, 0x11c36 }, /* Mn */
|
||||
{ 0x11c38, 0x11c3d }, /* Mn */
|
||||
{ 0x11c3f, 0x11c3f }, /* Mn */
|
||||
@@ -360,5 +364,9 @@
|
||||
{ 0x1e2ec, 0x1e2ef }, /* Mn */
|
||||
{ 0x1e4ec, 0x1e4ef }, /* Mn */
|
||||
{ 0x1e5ee, 0x1e5ef }, /* Mn */
|
||||
{ 0x1e6e3, 0x1e6e3 }, /* Mn */
|
||||
{ 0x1e6e6, 0x1e6e6 }, /* Mn */
|
||||
{ 0x1e6ee, 0x1e6ef }, /* Mn */
|
||||
{ 0x1e6f5, 0x1e6f5 }, /* Mn */
|
||||
{ 0x1e8d0, 0x1e8d6 }, /* Mn */
|
||||
{ 0x1e944, 0x1e94a }, /* Mn */
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+344
-97
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -34,10 +34,11 @@
|
||||
#include "lesskey.h"
|
||||
|
||||
extern int erase_char, erase2_char, kill_char;
|
||||
extern int mousecap;
|
||||
extern int emouse;
|
||||
extern int mouse_reverse;
|
||||
extern int hshift;
|
||||
extern int sc_height;
|
||||
|
||||
static constant lbool allow_drag = TRUE;
|
||||
extern char *no_config;
|
||||
|
||||
#if USERFILE
|
||||
/* "content" is lesskey source, never binary. */
|
||||
@@ -92,6 +93,7 @@ static unsigned char cmdtable[] =
|
||||
ESC,'j',0, A_F_NEWLINE,
|
||||
ESC,'k',0, A_B_NEWLINE,
|
||||
'F',0, A_F_FOREVER,
|
||||
ESC,'f',0, A_F_FOREVER_BELL,
|
||||
ESC,'F',0, A_F_UNTIL_HILITE,
|
||||
'R',0, A_FREPAINT,
|
||||
'r',0, A_REPAINT,
|
||||
@@ -101,6 +103,11 @@ static unsigned char cmdtable[] =
|
||||
ESC,'U',0, A_CLR_SEARCH,
|
||||
'g',0, A_GOLINE,
|
||||
SK(SK_HOME),0, A_GOLINE,
|
||||
SK(SK_SHIFT_HOME),0, A_GOLINE|A_EXTRA, ESC,'{',0,
|
||||
SK(SK_CTL_HOME),0, A_GOLINE|A_EXTRA, ESC,'{',0,
|
||||
SK(SK_END),0, A_GOEND,
|
||||
SK(SK_SHIFT_END),0, A_GOEND|A_EXTRA, ESC,'}',0,
|
||||
SK(SK_CTL_END),0, A_GOEND|A_EXTRA, ESC,'}',0,
|
||||
'<',0, A_GOLINE,
|
||||
ESC,'<',0, A_GOLINE,
|
||||
'p',0, A_PERCENT,
|
||||
@@ -113,6 +120,8 @@ static unsigned char cmdtable[] =
|
||||
SK(SK_LEFT_ARROW),0, A_LSHIFT,
|
||||
SK(SK_CTL_RIGHT_ARROW),0, A_RRSHIFT,
|
||||
SK(SK_CTL_LEFT_ARROW),0, A_LLSHIFT,
|
||||
SK(SK_SHIFT_RIGHT_ARROW),0, A_RRSHIFT,
|
||||
SK(SK_SHIFT_LEFT_ARROW),0, A_LLSHIFT,
|
||||
'{',0, A_F_BRACKET|A_EXTRA, '{','}',0,
|
||||
'}',0, A_B_BRACKET|A_EXTRA, '{','}',0,
|
||||
'(',0, A_F_BRACKET|A_EXTRA, '(',')',0,
|
||||
@@ -125,7 +134,6 @@ static unsigned char cmdtable[] =
|
||||
ESC,'G',0, A_GOEND_BUF,
|
||||
ESC,'>',0, A_GOEND,
|
||||
'>',0, A_GOEND,
|
||||
SK(SK_END),0, A_GOEND,
|
||||
'P',0, A_GOPOS,
|
||||
|
||||
'0',0, A_DIGIT,
|
||||
@@ -183,6 +191,24 @@ static unsigned char cmdtable[] =
|
||||
'!',0, A_SHELL,
|
||||
'#',0, A_PSHELL,
|
||||
'+',0, A_FIRSTCMD,
|
||||
|
||||
SK(SK_PAD_U),0, A_B_LINE,
|
||||
SK(SK_PAD_D),0, A_F_LINE,
|
||||
SK(SK_PAD_R),0, A_RSHIFT,
|
||||
SK(SK_PAD_L),0, A_LSHIFT,
|
||||
SK(SK_PAD_UR),0, A_B_SCREEN,
|
||||
SK(SK_PAD_UL),0, A_GOLINE,
|
||||
SK(SK_PAD_DR),0, A_F_SCREEN,
|
||||
SK(SK_PAD_DL),0, A_GOEND,
|
||||
SK(SK_PAD_STAR),0, A_NOACTION|A_EXTRA, '*',0,
|
||||
SK(SK_PAD_SLASH),0, A_NOACTION|A_EXTRA, '/',0,
|
||||
SK(SK_PAD_DASH),0, A_NOACTION|A_EXTRA, '-',0,
|
||||
SK(SK_PAD_PLUS),0, A_NOACTION|A_EXTRA, '+',0,
|
||||
SK(SK_PAD_DOT),0, A_NOACTION|A_EXTRA, '.',0,
|
||||
SK(SK_PAD_COMMA),0, A_NOACTION,
|
||||
SK(SK_PAD_ZERO),0, A_NOACTION|A_EXTRA, '0',0,
|
||||
SK(SK_PAD_CENTER),0, A_NOACTION,
|
||||
|
||||
ESC,'[','2','0','0','~',0, A_START_PASTE,
|
||||
ESC,'[','2','0','1','~',0, A_END_PASTE,
|
||||
|
||||
@@ -227,30 +253,52 @@ static unsigned char edittable[] =
|
||||
ESC,SK(SK_BACKSPACE),0, EC_W_BACKSPACE, /* ESC BACKSPACE */
|
||||
ESC,'0',0, EC_HOME, /* ESC 0 */
|
||||
SK(SK_HOME),0, EC_HOME, /* HOME */
|
||||
SK(SK_SHIFT_HOME),0, EC_HOME, /* SHIFT-HOME */
|
||||
SK(SK_CTL_HOME),0, EC_HOME, /* CTRL-HOME */
|
||||
ESC,'$',0, EC_END, /* ESC $ */
|
||||
SK(SK_END),0, EC_END, /* END */
|
||||
SK(SK_SHIFT_END),0, EC_END, /* SHIFT-END */
|
||||
SK(SK_CTL_END),0, EC_END, /* CTRL-END */
|
||||
ESC,'k',0, EC_UP, /* ESC k */
|
||||
SK(SK_UP_ARROW),0, EC_UP, /* UPARROW */
|
||||
ESC,'j',0, EC_DOWN, /* ESC j */
|
||||
SK(SK_DOWN_ARROW),0, EC_DOWN, /* DOWNARROW */
|
||||
CONTROL('G'),0, EC_ABORT, /* CTRL-G */
|
||||
SK(SK_PAD_U),0, EC_UP,
|
||||
SK(SK_PAD_D),0, EC_DOWN,
|
||||
SK(SK_PAD_R),0, EC_RIGHT,
|
||||
SK(SK_PAD_L),0, EC_LEFT,
|
||||
SK(SK_PAD_UR),0, A_NOACTION,
|
||||
SK(SK_PAD_UL),0, EC_HOME,
|
||||
SK(SK_PAD_DR),0, A_NOACTION,
|
||||
SK(SK_PAD_DL),0, EC_END,
|
||||
SK(SK_PAD_STAR),0, A_NOACTION|A_EXTRA, '*',0,
|
||||
SK(SK_PAD_SLASH),0, A_NOACTION|A_EXTRA, '/',0,
|
||||
SK(SK_PAD_DASH),0, A_NOACTION|A_EXTRA, '-',0,
|
||||
SK(SK_PAD_PLUS),0, A_NOACTION|A_EXTRA, '+',0,
|
||||
SK(SK_PAD_DOT),0, A_NOACTION|A_EXTRA, '.',0,
|
||||
SK(SK_PAD_COMMA),0, A_NOACTION|A_EXTRA, ',',0,
|
||||
SK(SK_PAD_ZERO),0, A_NOACTION|A_EXTRA, '0',0,
|
||||
SK(SK_PAD_CENTER),0, A_NOACTION,
|
||||
ESC,'[','M',0, EC_X11MOUSE, /* X11 mouse report */
|
||||
ESC,'[','<',0, EC_X116MOUSE, /* X11 1006 mouse report */
|
||||
ESC,'[','2','0','0','~',0, A_START_PASTE, /* open paste bracket */
|
||||
ESC,'[','2','0','1','~',0, A_END_PASTE, /* close paste bracket */
|
||||
};
|
||||
|
||||
static unsigned char dflt_vartable[] =
|
||||
/*
|
||||
* Default environment variables.
|
||||
* Note: "\201" is (A_EXTRA|EV_OK).
|
||||
*/
|
||||
static char dflt_vartable[] =
|
||||
{
|
||||
'L','E','S','S','_','O','S','C','8','_','m','a','n', 0, EV_OK|A_EXTRA,
|
||||
/* echo '%o' | sed -e "s,^man\:\\([^(]*\\)( *\\([^)]*\\)\.*,-man '\\2' '\\1'," -e"t X" -e"s,\.*,-echo Invalid man link," -e"\: X" */
|
||||
'e','c','h','o',' ','\'','%','o','\'',' ','|',' ','s','e','d',' ','-','e',' ','"','s',',','^','m','a','n','\\',':','\\','\\','(','[','^','(',']','*','\\','\\',')','(',' ','*','\\','\\','(','[','^',')',']','*','\\','\\',')','\\','.','*',',','-','m','a','n',' ','\'','\\','\\','2','\'',' ','\'','\\','\\','1','\'',',','"',' ','-','e','"','t',' ','X','"',' ','-','e','"','s',',','\\','.','*',',','-','e','c','h','o',' ','I','n','v','a','l','i','d',' ','m','a','n',' ','l','i','n','k',',','"',' ','-','e','"','\\',':',' ','X','"',
|
||||
0,
|
||||
|
||||
'L','E','S','S','_','O','S','C','8','_','f','i','l','e', 0, EV_OK|A_EXTRA,
|
||||
/* eval `echo '%o' | sed -e "s,^file://\\([^/]*\\)\\(.*\\),_H=\\1;_P=\\2;_E=0," -e"t X" -e"s,.*,_E=1," -e": X"`; if [ "$_E" = 1 ]; then echo -echo Invalid file link; elif [ -z "$_H" -o "$_H" = localhost -o "$_H" = $HOSTNAME ]; then echo ":e $_P"; else echo -echo Cannot open remote file on "$_H"; fi */
|
||||
'e','v','a','l',' ','`','e','c','h','o',' ','\'','%','o','\'',' ','|',' ','s','e','d',' ','-','e',' ','"','s',',','^','f','i','l','e','\\',':','/','/','\\','\\','(','[','^','/',']','*','\\','\\',')','\\','\\','(','\\','.','*','\\','\\',')',',','_','H','=','\\','\\','1',';','_','P','=','\\','\\','2',';','_','E','=','0',',','"',' ','-','e','"','t',' ','X','"',' ','-','e','"','s',',','\\','.','*',',','_','E','=','1',',','"',' ','-','e','"','\\',':',' ','X','"','`',';',' ','i','f',' ','[',' ','"','$','_','E','"',' ','=',' ','1',' ',']',';',' ','t','h','e','n',' ','e','c','h','o',' ','-','e','c','h','o',' ','I','n','v','a','l','i','d',' ','f','i','l','e',' ','l','i','n','k',';',' ','e','l','i','f',' ','[',' ','-','z',' ','"','$','_','H','"',' ','-','o',' ','"','$','_','H','"',' ','=',' ','l','o','c','a','l','h','o','s','t',' ','-','o',' ','"','$','_','H','"',' ','=',' ','$','H','O','S','T','N','A','M','E',' ',']',';',' ','t','h','e','n',' ','e','c','h','o',' ','"','\\',':','e',' ','$','_','P','"',';',' ','e','l','s','e',' ','e','c','h','o',' ','-','e','c','h','o',' ','C','a','n','n','o','t',' ','o','p','e','n',' ','r','e','m','o','t','e',' ','f','i','l','e',' ','o','n',' ','"','$','_','H','"',';',' ','f','i',
|
||||
0,
|
||||
"LESS_OSC8_OPEN_ANY\0\201"
|
||||
#ifdef LIBEXECDIR
|
||||
"-" LIBEXECDIR "/less-osc8-open"
|
||||
#else
|
||||
"-less-osc8-open"
|
||||
#endif
|
||||
"\0"
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -271,6 +319,9 @@ static struct tablelist *list_ecmd_tables = NULL;
|
||||
static struct tablelist *list_var_tables = NULL;
|
||||
static struct tablelist *list_sysvar_tables = NULL;
|
||||
|
||||
#if USERFILE
|
||||
static struct tablelist * find_stop_table(struct tablelist *t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Expand special key abbreviations in a command table.
|
||||
@@ -289,7 +340,7 @@ static void expand_special_keys(unsigned char *table, size_t len)
|
||||
* Rewrite each command in the table with any
|
||||
* special key abbreviations expanded.
|
||||
*/
|
||||
for (to = fm; *fm != '\0'; )
|
||||
for (to = fm; fm < table + len && *fm != '\0'; )
|
||||
{
|
||||
if (*fm != SK_SPECIAL_KEY)
|
||||
{
|
||||
@@ -306,7 +357,7 @@ static void expand_special_keys(unsigned char *table, size_t len)
|
||||
* output by the special key on this terminal.
|
||||
*/
|
||||
repl = special_key_str(fm[1]);
|
||||
klen = fm[2] & 0377;
|
||||
klen = fm[2];
|
||||
fm += klen;
|
||||
if (repl == NULL || strlen(repl) > klen)
|
||||
repl = "\377";
|
||||
@@ -321,10 +372,10 @@ static void expand_special_keys(unsigned char *table, size_t len)
|
||||
while (to <= fm)
|
||||
*to++ = A_SKIP;
|
||||
fm++;
|
||||
a = *fm++ & 0377;
|
||||
a = *fm++;
|
||||
if (a & A_EXTRA)
|
||||
{
|
||||
while (*fm++ != '\0')
|
||||
while (fm < table + len && *fm++ != '\0')
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -358,12 +409,15 @@ public void expand_cmd_tables(void)
|
||||
*/
|
||||
public void init_cmds(void)
|
||||
{
|
||||
struct tablelist *t;
|
||||
unsigned char *udflt_vartable = (unsigned char *) dflt_vartable;
|
||||
|
||||
/*
|
||||
* Add the default command tables.
|
||||
*/
|
||||
add_fcmd_table(cmdtable, sizeof(cmdtable));
|
||||
add_ecmd_table(edittable, sizeof(edittable));
|
||||
add_sysvar_table(dflt_vartable, sizeof(dflt_vartable));
|
||||
add_sysvar_table(udflt_vartable, sizeof(dflt_vartable));
|
||||
#if USERFILE
|
||||
#ifdef BINDIR /* For backwards compatibility */
|
||||
/* Try to add tables in the OLD system lesskey file. */
|
||||
@@ -403,6 +457,16 @@ public void init_cmds(void)
|
||||
|
||||
add_content_table(lesskey_content, "LESSKEY_CONTENT_SYSTEM", TRUE);
|
||||
add_content_table(lesskey_content, "LESSKEY_CONTENT", FALSE);
|
||||
|
||||
/*
|
||||
* If any command table contains a #stop directive, discard all other tables.
|
||||
*/
|
||||
t = find_stop_table(list_fcmd_tables);
|
||||
if (t != NULL)
|
||||
{
|
||||
t->t_next = NULL;
|
||||
list_fcmd_tables = t;
|
||||
}
|
||||
#endif /* USERFILE */
|
||||
}
|
||||
|
||||
@@ -509,7 +573,9 @@ public void add_sysvar_table(unsigned char *buf, size_t len)
|
||||
*/
|
||||
static int mouse_wheel_down(void)
|
||||
{
|
||||
return ((mousecap == OPT_ONPLUS) ? A_B_MOUSE : A_F_MOUSE);
|
||||
if (!(emouse & EMOUSE_VSCROLL))
|
||||
return A_NOACTION;
|
||||
return mouse_reverse ? A_B_MOUSE : A_F_MOUSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -517,7 +583,29 @@ static int mouse_wheel_down(void)
|
||||
*/
|
||||
static int mouse_wheel_up(void)
|
||||
{
|
||||
return ((mousecap == OPT_ONPLUS) ? A_F_MOUSE : A_B_MOUSE);
|
||||
if (!(emouse & EMOUSE_VSCROLL))
|
||||
return A_NOACTION;
|
||||
return mouse_reverse ? A_F_MOUSE : A_B_MOUSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return action for a mouse wheel left event.
|
||||
*/
|
||||
static int mouse_wheel_left(void)
|
||||
{
|
||||
if (!(emouse & EMOUSE_HSCROLL))
|
||||
return A_NOACTION;
|
||||
return mouse_reverse ? A_R_MOUSE : A_L_MOUSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return action for a mouse wheel right event.
|
||||
*/
|
||||
static int mouse_wheel_right(void)
|
||||
{
|
||||
if (!(emouse & EMOUSE_HSCROLL))
|
||||
return A_NOACTION;
|
||||
return mouse_reverse ? A_L_MOUSE : A_R_MOUSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -525,38 +613,58 @@ static int mouse_wheel_up(void)
|
||||
*/
|
||||
static int mouse_button_left(int x, int y, lbool down, lbool drag)
|
||||
{
|
||||
static int last_drag_x = -1;
|
||||
static int last_drag_y = -1;
|
||||
static int last_click_y = -1;
|
||||
|
||||
if (down && !drag)
|
||||
{
|
||||
last_drag_x = x;
|
||||
last_drag_y = last_click_y = y;
|
||||
}
|
||||
if (allow_drag && drag && last_drag_y >= 0)
|
||||
if (drag)
|
||||
{
|
||||
/* Drag text up/down */
|
||||
if (y > last_drag_y)
|
||||
{
|
||||
if ((emouse & EMOUSE_HDRAG) && last_drag_x >= 0 && x != last_drag_x) {
|
||||
/* Drag text left/right */
|
||||
pos_rehead(FALSE);
|
||||
if (hshift < x - last_drag_x)
|
||||
hshift = 0;
|
||||
else
|
||||
hshift -= x - last_drag_x;
|
||||
screen_trashed();
|
||||
cmd_exec();
|
||||
backward(y - last_drag_y, FALSE, FALSE, FALSE);
|
||||
last_drag_y = y;
|
||||
} else if (y < last_drag_y)
|
||||
{
|
||||
cmd_exec();
|
||||
forward(last_drag_y - y, FALSE, FALSE, FALSE);
|
||||
last_drag_y = y;
|
||||
last_drag_x = x;
|
||||
}
|
||||
} else if (!down)
|
||||
if ((emouse & EMOUSE_VDRAG) && last_drag_y >= 0) {
|
||||
/* Drag text up/down */
|
||||
if (y > last_drag_y)
|
||||
{
|
||||
cmd_exec();
|
||||
backward(y - last_drag_y, FALSE, FALSE, FALSE);
|
||||
last_drag_y = y;
|
||||
} else if (y < last_drag_y)
|
||||
{
|
||||
cmd_exec();
|
||||
forward(last_drag_y - y, FALSE, FALSE, FALSE);
|
||||
last_drag_y = y;
|
||||
}
|
||||
}
|
||||
} else if ((emouse & EMOUSE_LCLICK) && !down)
|
||||
{
|
||||
#if OSC8_LINK
|
||||
if (osc8_click(y, x))
|
||||
return (A_NOACTION);
|
||||
if (secure_allow(SF_OSC8_OPEN))
|
||||
{
|
||||
cmd_exec();
|
||||
if (osc8_click(y, x))
|
||||
return (A_NOACTION);
|
||||
}
|
||||
#else
|
||||
(void) x;
|
||||
#endif /* OSC8_LINK */
|
||||
if (y < sc_height-1 && y == last_click_y)
|
||||
{
|
||||
setmark('#', y);
|
||||
cmd_exec();
|
||||
setmark('#', y, 0);
|
||||
screen_trashed();
|
||||
}
|
||||
}
|
||||
@@ -573,9 +681,11 @@ static int mouse_button_right(int x, int y, lbool down, lbool drag)
|
||||
* {{ unlike mouse_button_left, we could return an action,
|
||||
* but keep it near mouse_button_left for readability. }}
|
||||
*/
|
||||
if (!(emouse & EMOUSE_RCLICK))
|
||||
return (A_NOACTION);
|
||||
if (!down && y < sc_height-1)
|
||||
{
|
||||
gomark('#');
|
||||
gomark('#', 0);
|
||||
screen_trashed();
|
||||
}
|
||||
return (A_NOACTION);
|
||||
@@ -637,6 +747,10 @@ static int x11mouse_action(lbool skip)
|
||||
return mouse_wheel_down();
|
||||
case X11MOUSE_WHEEL_UP:
|
||||
return mouse_wheel_up();
|
||||
case X11MOUSE_WHEEL_LEFT:
|
||||
return mouse_wheel_left();
|
||||
case X11MOUSE_WHEEL_RIGHT:
|
||||
return mouse_wheel_right();
|
||||
case X11MOUSE_BUTTON1:
|
||||
case X11MOUSE_BUTTON2:
|
||||
case X11MOUSE_BUTTON3:
|
||||
@@ -671,6 +785,10 @@ static int x116mouse_action(lbool skip)
|
||||
return mouse_wheel_down();
|
||||
case X11MOUSE_WHEEL_UP:
|
||||
return mouse_wheel_up();
|
||||
case X11MOUSE_WHEEL_LEFT:
|
||||
return mouse_wheel_left();
|
||||
case X11MOUSE_WHEEL_RIGHT:
|
||||
return mouse_wheel_right();
|
||||
case X11MOUSE_BUTTON1:
|
||||
case X11MOUSE_BUTTON2:
|
||||
case X11MOUSE_BUTTON3: {
|
||||
@@ -727,82 +845,95 @@ static constant unsigned char * cmd_next_entry(constant unsigned char *entry, mu
|
||||
}
|
||||
|
||||
/*
|
||||
* Search a single command table for the command string in cmd.
|
||||
* Does a command table contain a #stop directive?
|
||||
*/
|
||||
static int cmd_search(constant char *cmd, constant unsigned char *table, constant unsigned char *endtable, constant unsigned char **extra, size_t *mlen)
|
||||
static lbool table_has_stop(struct tablelist *t)
|
||||
{
|
||||
int action = A_INVALID;
|
||||
size_t match_len = 0;
|
||||
if (extra != NULL)
|
||||
*extra = NULL;
|
||||
while (table < endtable)
|
||||
constant unsigned char *entry = t->t_start;
|
||||
|
||||
while (entry < t->t_end)
|
||||
{
|
||||
int taction;
|
||||
const unsigned char *textra;
|
||||
size_t cmdlen;
|
||||
size_t match = cmd_match((constant char *) table, cmd);
|
||||
table = cmd_next_entry(table, &taction, &textra, &cmdlen);
|
||||
if (taction == A_END_LIST)
|
||||
return (-action);
|
||||
if (match >= match_len)
|
||||
{
|
||||
if (match == cmdlen) /* (last chars of) cmd matches this table entry */
|
||||
{
|
||||
action = taction;
|
||||
if (extra != NULL)
|
||||
*extra = textra;
|
||||
} else if (match > 0 && action == A_INVALID) /* cmd is a prefix of this table entry */
|
||||
{
|
||||
action = A_PREFIX;
|
||||
}
|
||||
match_len = match;
|
||||
}
|
||||
int action;
|
||||
entry = cmd_next_entry(entry, &action, NULL, NULL);
|
||||
if (action == A_END_LIST)
|
||||
return TRUE;
|
||||
}
|
||||
if (mlen != NULL)
|
||||
*mlen = match_len;
|
||||
return (action);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a command character and return the associated action.
|
||||
* The "extra" string, if any, is returned in sp.
|
||||
* Find the first command table with a #stop directive, if any.
|
||||
*/
|
||||
static int cmd_decode(struct tablelist *tlist, constant char *cmd, constant char **sp)
|
||||
static struct tablelist * find_stop_table(struct tablelist *t)
|
||||
{
|
||||
for (; t != NULL; t = t->t_next)
|
||||
{
|
||||
if (table_has_stop(t))
|
||||
return t;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search a single command table for the command string in cmd.
|
||||
*/
|
||||
static int cmd_decode(struct tablelist *tlist, constant char *cmd, lbool anchored, constant char **extra)
|
||||
{
|
||||
struct tablelist *t;
|
||||
int action = A_INVALID;
|
||||
size_t match_len = 0;
|
||||
constant unsigned char *table = NULL;
|
||||
constant unsigned char *endtable;
|
||||
|
||||
/*
|
||||
* Search for the cmd thru all the command tables.
|
||||
* If we find it more than once, take the last one.
|
||||
*/
|
||||
*sp = NULL;
|
||||
for (t = tlist; t != NULL; t = t->t_next)
|
||||
if (extra != NULL)
|
||||
*extra = NULL;
|
||||
while (tlist != NULL)
|
||||
{
|
||||
constant unsigned char *tsp;
|
||||
size_t mlen = match_len;
|
||||
int taction = cmd_search(cmd, t->t_start, t->t_end, &tsp, &mlen);
|
||||
if (mlen >= match_len)
|
||||
int taction;
|
||||
constant unsigned char *textra;
|
||||
size_t tcmdlen;
|
||||
size_t tmatch;
|
||||
if (table == NULL)
|
||||
{
|
||||
match_len = mlen;
|
||||
if (taction != A_INVALID)
|
||||
/* Beginning of table: set start/end pointers. */
|
||||
table = tlist->t_start;
|
||||
endtable = tlist->t_end;
|
||||
}
|
||||
if (anchored)
|
||||
tmatch = (strcmp((constant char *) table, cmd) == 0) ? strlen(cmd) : 0;
|
||||
else
|
||||
tmatch = cmd_match((constant char *) table, cmd);
|
||||
table = cmd_next_entry(table, &taction, &textra, &tcmdlen);
|
||||
if (table >= endtable)
|
||||
{
|
||||
/* End of table; move to next table. */
|
||||
tlist = tlist->t_next;
|
||||
table = NULL;
|
||||
}
|
||||
if (taction == A_END_LIST)
|
||||
break;
|
||||
if (tmatch >= match_len)
|
||||
{
|
||||
if (tmatch == tcmdlen)
|
||||
{
|
||||
*sp = (constant char *) tsp;
|
||||
if (taction < 0)
|
||||
{
|
||||
action = -taction;
|
||||
break;
|
||||
}
|
||||
/* (Last chars of) cmd matches this table entry. */
|
||||
action = taction;
|
||||
if (extra != NULL)
|
||||
*extra = (constant char *) textra;
|
||||
} else if (tmatch > 0 && (tmatch > match_len || action == A_INVALID))
|
||||
{
|
||||
/* cmd is a prefix of this table entry */
|
||||
action = A_PREFIX;
|
||||
if (extra != NULL)
|
||||
*extra = NULL;
|
||||
}
|
||||
match_len = tmatch;
|
||||
}
|
||||
}
|
||||
if (action == A_X11MOUSE_IN)
|
||||
action = x11mouse_action(FALSE);
|
||||
else if (action == A_X116MOUSE_IN)
|
||||
action = x116mouse_action(FALSE);
|
||||
return (action);
|
||||
return action;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -810,7 +941,7 @@ static int cmd_decode(struct tablelist *tlist, constant char *cmd, constant char
|
||||
*/
|
||||
public int fcmd_decode(constant char *cmd, constant char **sp)
|
||||
{
|
||||
return (cmd_decode(list_fcmd_tables, cmd, sp));
|
||||
return (cmd_decode(list_fcmd_tables, cmd, FALSE, sp));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -818,9 +949,119 @@ public int fcmd_decode(constant char *cmd, constant char **sp)
|
||||
*/
|
||||
public int ecmd_decode(constant char *cmd, constant char **sp)
|
||||
{
|
||||
return (cmd_decode(list_ecmd_tables, cmd, sp));
|
||||
return (cmd_decode(list_ecmd_tables, cmd, FALSE, sp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a comma-separated list.
|
||||
* Call func repeatedly, passing each item in the list.
|
||||
* Stop and return FALSE if func ever returns FALSE,
|
||||
* otherwise parse the entire list and return TRUE.
|
||||
*/
|
||||
public lbool parse_csl(lbool (*func)(constant char *word, size_t wlen, void *arg), constant char *str, void *arg)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
constant char *estr;
|
||||
while (*str == ' ' || *str == ',') ++str; /* skip leading spaces/commas */
|
||||
if (*str == '\0') break;
|
||||
estr = strchr(str, ',');
|
||||
if (estr == NULL) estr = str + strlen(str);
|
||||
while (estr > str && estr[-1] == ' ') --estr; /* trim trailing spaces */
|
||||
if (!(*func)(str, ptr_diff(estr, str), arg))
|
||||
return FALSE;
|
||||
str = estr;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display error message for parse_csl_bitmap.
|
||||
*/
|
||||
static int csl_bitmap_error(constant char *pfx, constant char *type, size_t len, constant char *name)
|
||||
{
|
||||
PARG parg;
|
||||
size_t msglen = len + strlen(pfx) + strlen(type) + 32;
|
||||
char *msg = ecalloc(msglen, sizeof(char));
|
||||
SNPRINTF4(msg, msglen, "%s: %s name \"%.*s\"", pfx, type, (int) len, name);
|
||||
parg.p_string = msg;
|
||||
error("%s", &parg);
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the bit value of a csl_bitmap name.
|
||||
*/
|
||||
public int csl_bitmap_bit(constant char *name, size_t len, struct csl_bitmap_def *defs, int num_defs, constant char *pfx)
|
||||
{
|
||||
int i;
|
||||
int match = -1;
|
||||
|
||||
for (i = 0; i < num_defs; i++)
|
||||
{
|
||||
if (strncmp(defs[i].bit_name, name, len) == 0)
|
||||
{
|
||||
if (match >= 0) /* name is ambiguous */
|
||||
return csl_bitmap_error(pfx, "ambiguous", len, name);
|
||||
match = i;
|
||||
}
|
||||
}
|
||||
if (match < 0)
|
||||
return csl_bitmap_error(pfx, "invalid", len, name);
|
||||
return defs[match].bit_value;
|
||||
}
|
||||
|
||||
/* State for parse_csl_bitmap. */
|
||||
struct csl_bitmap_info
|
||||
{
|
||||
int bitmap; /* bitmap being constructed */
|
||||
struct csl_bitmap_def *def; /* array of name/value pairs */
|
||||
int num_defs; /* length of def array */
|
||||
constant char *pfx; /* prefix for error messages */
|
||||
};
|
||||
|
||||
/*
|
||||
* Set a bit in a csl_bitmap_info based on a csl_bitmap name.
|
||||
*/
|
||||
static lbool csl_bitmap_set(constant char *word, size_t wlen, void *arg)
|
||||
{
|
||||
struct csl_bitmap_info *info = (struct csl_bitmap_info *) arg;
|
||||
info->bitmap |= csl_bitmap_bit(word, wlen, info->def, info->num_defs, info->pfx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a comma-separated list of csl_bitmap names and return
|
||||
* the combined bitmap value.
|
||||
*/
|
||||
public int parse_csl_bitmap(constant char *str, struct csl_bitmap_def *defs, int num_defs, constant char *pfx)
|
||||
{
|
||||
struct csl_bitmap_info info;
|
||||
info.bitmap = 0;
|
||||
info.def = defs;
|
||||
info.num_defs = num_defs;
|
||||
info.pfx = pfx;
|
||||
if (!parse_csl(csl_bitmap_set, str, &info))
|
||||
return -1;
|
||||
return info.bitmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should we ignore the setting of an environment variable?
|
||||
*/
|
||||
static lbool word_no_match(constant char *word, size_t wlen, void *arg)
|
||||
{
|
||||
constant char *var = (constant char *) arg;
|
||||
return !(wlen == strlen(var) && strncmp(var, word, wlen) == 0);
|
||||
}
|
||||
static lbool ignore_env(constant char *var)
|
||||
{
|
||||
if (isnullenv(no_config))
|
||||
return FALSE; /* no_config is not set; don't ignore anything */
|
||||
/* no_config is set; ignore any var that does not appear in no_config */
|
||||
return parse_csl(word_no_match, no_config, (void*) var);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the value of an environment variable.
|
||||
@@ -831,13 +1072,15 @@ public constant char * lgetenv(constant char *var)
|
||||
int a;
|
||||
constant char *s;
|
||||
|
||||
a = cmd_decode(list_var_tables, var, &s);
|
||||
if (ignore_env(var))
|
||||
return (NULL);
|
||||
a = cmd_decode(list_var_tables, var, TRUE, &s);
|
||||
if (a == EV_OK)
|
||||
return (s);
|
||||
s = getenv(var);
|
||||
if (s != NULL && *s != '\0')
|
||||
return (s);
|
||||
a = cmd_decode(list_sysvar_tables, var, &s);
|
||||
a = cmd_decode(list_sysvar_tables, var, TRUE, &s);
|
||||
if (a == EV_OK)
|
||||
return (s);
|
||||
return (NULL);
|
||||
@@ -986,7 +1229,7 @@ public int lesskey(constant char *filename, lbool sysvar)
|
||||
ssize_t n;
|
||||
int f;
|
||||
|
||||
if (!secure_allow(SF_LESSKEY))
|
||||
if (!secure_allow(SF_LESSKEY) || !isnullenv(no_config))
|
||||
return (1);
|
||||
/*
|
||||
* Try to open the lesskey file.
|
||||
@@ -1048,7 +1291,7 @@ static int lesskey_text(constant char *filename, lbool sysvar, lbool content)
|
||||
int r;
|
||||
static struct lesskey_tables tables;
|
||||
|
||||
if (!secure_allow(SF_LESSKEY))
|
||||
if (!secure_allow(SF_LESSKEY) || !isnullenv(no_config))
|
||||
return (1);
|
||||
r = content ? parse_lesskey_content(filename, &tables) : parse_lesskey(filename, &tables);
|
||||
if (r != 0)
|
||||
@@ -1089,6 +1332,10 @@ static int add_hometable(int (*call_lesskey)(constant char *, lbool), constant c
|
||||
constant char *efilename;
|
||||
int r;
|
||||
|
||||
#if LESSTEST
|
||||
if (is_lesstest()) /* Don't use lesskey files in lesstest */
|
||||
return -1;
|
||||
#endif
|
||||
if (envname != NULL && (efilename = lgetenv(envname)) != NULL)
|
||||
filename = save(efilename);
|
||||
else if (sysvar) /* def_filename is full path */
|
||||
|
||||
+37
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -25,13 +25,13 @@ public int fd0 = 0;
|
||||
extern lbool new_file;
|
||||
extern char *every_first_cmd;
|
||||
extern int force_open;
|
||||
extern int is_tty;
|
||||
extern lbool is_tty;
|
||||
extern int sigs;
|
||||
extern int hshift;
|
||||
extern int want_filesize;
|
||||
extern int consecutive_nulls;
|
||||
extern int modelines;
|
||||
extern int show_preproc_error;
|
||||
extern lbool read_error;
|
||||
extern IFILE curr_ifile;
|
||||
extern IFILE old_ifile;
|
||||
extern struct scrpos initial_scrpos;
|
||||
@@ -77,20 +77,20 @@ public void init_textlist(struct textlist *tlist, mutable char *str)
|
||||
#if SPACES_IN_FILENAMES
|
||||
if (meta_quoted)
|
||||
{
|
||||
meta_quoted = 0;
|
||||
meta_quoted = FALSE;
|
||||
} else if (esclen > 0 && s + esclen < tlist->endstring &&
|
||||
strncmp(s, esc, esclen) == 0)
|
||||
{
|
||||
meta_quoted = 1;
|
||||
meta_quoted = TRUE;
|
||||
s += esclen - 1;
|
||||
} else if (delim_quoted)
|
||||
{
|
||||
if (*s == closequote)
|
||||
delim_quoted = 0;
|
||||
delim_quoted = FALSE;
|
||||
} else /* (!delim_quoted) */
|
||||
{
|
||||
if (*s == openquote)
|
||||
delim_quoted = 1;
|
||||
delim_quoted = TRUE;
|
||||
else if (*s == ' ')
|
||||
*s = '\0';
|
||||
}
|
||||
@@ -101,7 +101,7 @@ public void init_textlist(struct textlist *tlist, mutable char *str)
|
||||
}
|
||||
}
|
||||
|
||||
public constant char * forw_textlist(struct textlist *tlist, constant char *prev)
|
||||
public constant char * forw_textlist(constant struct textlist *tlist, constant char *prev)
|
||||
{
|
||||
constant char *s;
|
||||
|
||||
@@ -120,7 +120,7 @@ public constant char * forw_textlist(struct textlist *tlist, constant char *prev
|
||||
return (s);
|
||||
}
|
||||
|
||||
public constant char * back_textlist(struct textlist *tlist, constant char *prev)
|
||||
public constant char * back_textlist(constant struct textlist *tlist, constant char *prev)
|
||||
{
|
||||
constant char *s;
|
||||
|
||||
@@ -210,7 +210,6 @@ static void modeline_options(constant char *str, char end_char)
|
||||
*/
|
||||
static void check_modeline(constant char *line)
|
||||
{
|
||||
#if HAVE_STRSTR
|
||||
static constant char *pgms[] = { "less:", "vim:", "vi:", "ex:", NULL };
|
||||
constant char **pgm;
|
||||
for (pgm = pgms; *pgm != NULL; ++pgm)
|
||||
@@ -235,7 +234,6 @@ static void check_modeline(constant char *line)
|
||||
pline = str;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_STRSTR */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -266,6 +264,7 @@ static void close_pipe(FILE *pipefd)
|
||||
int status;
|
||||
char *p;
|
||||
PARG parg;
|
||||
int sig = 0;
|
||||
|
||||
if (pipefd == NULL)
|
||||
return;
|
||||
@@ -292,18 +291,33 @@ static void close_pipe(FILE *pipefd)
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
int s = WEXITSTATUS(status);
|
||||
if (s != 0)
|
||||
if (s == 0)
|
||||
return;
|
||||
if (s <= 128)
|
||||
{
|
||||
parg.p_int = s;
|
||||
error("Input preprocessor failed (status %d)", &parg);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
/*
|
||||
* popen invoked the shell, which likely last ran a
|
||||
* program that terminated due to a signal.
|
||||
* Assume the longstanding tradition (allowed but not
|
||||
* required by POSIX) of adding 128 to the signal.
|
||||
* Many shells use last command optimization, i.e.,
|
||||
* they exec the last command instead of forking and
|
||||
* waiting for it, and in that case the more-reliable
|
||||
* WIFSIGNALED code below will be used.
|
||||
*/
|
||||
sig = s - 128;
|
||||
}
|
||||
#endif
|
||||
#if defined WIFSIGNALED && defined WTERMSIG
|
||||
if (WIFSIGNALED(status))
|
||||
sig = WTERMSIG(status);
|
||||
#endif
|
||||
if (sig != 0)
|
||||
{
|
||||
int sig = WTERMSIG(status);
|
||||
if (
|
||||
#ifdef SIGPIPE
|
||||
sig != SIGPIPE ||
|
||||
@@ -315,7 +329,6 @@ static void close_pipe(FILE *pipefd)
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (status != 0)
|
||||
{
|
||||
parg.p_int = status;
|
||||
@@ -363,11 +376,14 @@ static void close_file(void)
|
||||
* Save the current position so that we can return to
|
||||
* the same position if we edit this file again.
|
||||
*/
|
||||
get_scrpos(&scrpos, TOP);
|
||||
if (scrpos.pos != NULL_POSITION)
|
||||
if (is_tty)
|
||||
{
|
||||
store_pos(curr_ifile, &scrpos);
|
||||
lastmark();
|
||||
get_scrpos(&scrpos, TOP);
|
||||
if (scrpos.pos != NULL_POSITION)
|
||||
{
|
||||
store_pos(curr_ifile, &scrpos);
|
||||
lastmark();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Close the file descriptor, unless it is a pipe.
|
||||
@@ -547,7 +563,7 @@ public int edit_ifile(IFILE ifile)
|
||||
} else
|
||||
{
|
||||
chflags |= CH_CANSEEK;
|
||||
if (bin_file(f, &nread) && !force_open && !opened(ifile))
|
||||
if (bin_file(f, &nread) && is_tty && !force_open && !opened(ifile))
|
||||
{
|
||||
/*
|
||||
* Looks like a binary file.
|
||||
@@ -613,7 +629,6 @@ public int edit_ifile(IFILE ifile)
|
||||
set_open(curr_ifile); /* File has been opened */
|
||||
get_pos(curr_ifile, &initial_scrpos);
|
||||
ch_init(f, chflags, nread);
|
||||
consecutive_nulls = 0;
|
||||
check_modelines();
|
||||
|
||||
if (!(chflags & CH_HELPFILE))
|
||||
@@ -662,6 +677,7 @@ public int edit_ifile(IFILE ifile)
|
||||
#endif
|
||||
undo_osc8();
|
||||
hshift = 0;
|
||||
read_error = FALSE;
|
||||
if (strcmp(filename, FAKE_HELPFILE) && strcmp(filename, FAKE_EMPTYFILE))
|
||||
{
|
||||
char *qfilename = shell_quote(filename);
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+22
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -319,15 +319,13 @@ static void xcpy_char(xcpy *xp, char ch)
|
||||
|
||||
static void xcpy_filename(xcpy *xp, constant char *str)
|
||||
{
|
||||
/* If filename contains spaces, quote it
|
||||
* to prevent edit_list from splitting it. */
|
||||
lbool quote = (strchr(str, ' ') != NULL);
|
||||
if (quote)
|
||||
xcpy_char(xp, openquote);
|
||||
for (; *str != '\0'; str++)
|
||||
xcpy_char(xp, *str);
|
||||
if (quote)
|
||||
xcpy_char(xp, closequote);
|
||||
char *qstr = shell_quote(str);
|
||||
char *s;
|
||||
if (qstr == NULL)
|
||||
return;
|
||||
for (s = qstr; *s != '\0'; s++)
|
||||
xcpy_char(xp, *s);
|
||||
free(qstr);
|
||||
}
|
||||
|
||||
static size_t fexpand_copy(constant char *fr, char *to)
|
||||
@@ -469,22 +467,23 @@ public char * fcomplete(constant char *s)
|
||||
* be used later to compare to st_size from stat(2) to see if the file
|
||||
* is lying about its size.
|
||||
*/
|
||||
public int bin_file(int f, ssize_t *n)
|
||||
public lbool bin_file(int f, ssize_t *n)
|
||||
{
|
||||
int bin_count = 0;
|
||||
char data[256];
|
||||
constant char* p;
|
||||
constant char* edata;
|
||||
constant int umax = 4;
|
||||
|
||||
if (!seekable(f))
|
||||
return (0);
|
||||
return FALSE;
|
||||
if (less_lseek(f, (less_off_t)0, SEEK_SET) == BAD_LSEEK)
|
||||
return (0);
|
||||
return FALSE;
|
||||
*n = read(f, data, sizeof(data));
|
||||
if (*n <= 0)
|
||||
return (0);
|
||||
if (*n <= umax)
|
||||
return FALSE;
|
||||
edata = &data[*n];
|
||||
for (p = data; p < edata; )
|
||||
for (p = data; p+umax < edata; )
|
||||
{
|
||||
if (utf_mode && !is_utf8_well_formed(p, (int) ptr_diff(edata,p)))
|
||||
{
|
||||
@@ -569,9 +568,10 @@ static FILE * shellcmd(constant char *cmd)
|
||||
fd = popen(cmd, "r");
|
||||
} else
|
||||
{
|
||||
size_t len = strlen(shell) + strlen(esccmd) + 5;
|
||||
constant char *copt = shell_coption();
|
||||
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
|
||||
scmd = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF3(scmd, len, "%s %s %s", shell, shell_coption(), esccmd);
|
||||
SNPRINTF3(scmd, len, "%s %s %s", shell, copt, esccmd);
|
||||
free(esccmd);
|
||||
fd = popen(scmd, "r");
|
||||
free(scmd);
|
||||
@@ -731,7 +731,11 @@ public char * lglob(constant char *afilename)
|
||||
}
|
||||
lessecho = lgetenv("LESSECHO");
|
||||
if (isnullenv(lessecho))
|
||||
#ifdef LIBEXECDIR
|
||||
lessecho = LIBEXECDIR "/lessecho";
|
||||
#else
|
||||
lessecho = "lessecho";
|
||||
#endif
|
||||
/*
|
||||
* Invoke lessecho, and read its output (a globbed list of filenames).
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Jul 27 19:38:50 GMT 2025 */
|
||||
/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Nov 28 1:30:12 GMT 2025 */
|
||||
{ 0x0600, 0x0605 }, /* Cf */
|
||||
{ 0x061c, 0x061c }, /* Cf */
|
||||
{ 0x06dd, 0x06dd }, /* Cf */
|
||||
|
||||
+60
-30
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -19,8 +19,8 @@
|
||||
extern int less_is_more;
|
||||
|
||||
public lbool squished;
|
||||
public int no_back_scroll = 0;
|
||||
public int forw_prompt;
|
||||
public lbool no_back_scroll = FALSE;
|
||||
public lbool forw_prompt;
|
||||
public lbool first_time = TRUE; /* We're printing the first screen of output */
|
||||
public int shell_lines = 1;
|
||||
/* soft_eof is set as end-of-file when a read attempt returns EOF. This can
|
||||
@@ -36,11 +36,12 @@ extern int auto_wrap;
|
||||
extern lbool plusoption;
|
||||
extern int forw_scroll;
|
||||
extern int back_scroll;
|
||||
extern int ignore_eoi;
|
||||
extern lbool ignore_eoi;
|
||||
extern int header_lines;
|
||||
extern int header_cols;
|
||||
extern int full_screen;
|
||||
extern lbool full_screen;
|
||||
extern int stop_on_form_feed;
|
||||
extern int past_eof;
|
||||
extern POSITION header_start_pos;
|
||||
extern lbool getting_one_screen;
|
||||
#if HILITE_SEARCH
|
||||
@@ -66,7 +67,7 @@ public void eof_bell(void)
|
||||
}
|
||||
#endif
|
||||
if (quiet == NOT_QUIET)
|
||||
bell();
|
||||
lbell();
|
||||
else
|
||||
vbell();
|
||||
}
|
||||
@@ -140,7 +141,7 @@ static POSITION forw_line_pfx(POSITION pos, int pfx, int skipeol)
|
||||
sc_width = pfx + line_pfx_width();
|
||||
auto_wrap = 0;
|
||||
hshift = 0;
|
||||
pos = forw_line_seg(pos, skipeol, FALSE, FALSE, NULL, NULL);
|
||||
pos = forw_line_seg(pos, skipeol, FALSE, FALSE, FALSE, TRUE, NULL, NULL);
|
||||
sc_width = save_sc_width;
|
||||
auto_wrap = save_auto_wrap;
|
||||
hshift = save_hshift;
|
||||
@@ -218,15 +219,18 @@ public int overlay_header(void)
|
||||
* The first real line after the blanks will start at ch_zero().
|
||||
* "to_newline" means count file lines rather than screen lines.
|
||||
*/
|
||||
public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, int nblank)
|
||||
public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed, int nblank)
|
||||
{
|
||||
int nlines = 0;
|
||||
lbool do_repaint;
|
||||
lbool newline;
|
||||
lbool first_line = TRUE;
|
||||
lbool need_home = FALSE;
|
||||
|
||||
if (pos != NULL_POSITION)
|
||||
pos = after_header_pos(pos);
|
||||
if (past_eof)
|
||||
force = TRUE;
|
||||
squish_check();
|
||||
|
||||
/*
|
||||
@@ -242,7 +246,7 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
(forw_scroll >= 0 && n > forw_scroll && n != sc_height-1);
|
||||
if (!do_repaint)
|
||||
{
|
||||
if (top_scroll && n >= sc_height - 1 && pos != ch_length())
|
||||
if (top_scroll && n >= sc_height - 1 && pos != NULL_POSITION && pos != ch_length())
|
||||
{
|
||||
/*
|
||||
* Start a new screen.
|
||||
@@ -252,10 +256,7 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
*/
|
||||
pos_clear();
|
||||
force = TRUE;
|
||||
if (less_is_more == 0) {
|
||||
clear();
|
||||
home();
|
||||
}
|
||||
need_home = (less_is_more == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
if (pos != position(BOTTOM_PLUS_ONE) || empty_screen())
|
||||
@@ -269,8 +270,7 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
force = TRUE;
|
||||
if (top_scroll)
|
||||
{
|
||||
clear();
|
||||
home();
|
||||
need_home = TRUE;
|
||||
} else if (!first_time && !is_filtering() && full_screen)
|
||||
{
|
||||
putstr("...skipping...\n");
|
||||
@@ -308,18 +308,25 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
/*
|
||||
* End of file: stop here unless the top line
|
||||
* is still empty, or "force" is true.
|
||||
* Even if force is true, stop when the last
|
||||
* line in the file reaches the top of screen.
|
||||
*/
|
||||
soft_eof = opos;
|
||||
linepos = opos;
|
||||
if (ABORT_SIGS() ||
|
||||
(!force && position(TOP) != NULL_POSITION) ||
|
||||
(!empty_lines(0, 0) && !empty_lines(1, 1) && empty_lines(2, sc_height-1)))
|
||||
linepos = (opos == ch_zero()) ? NULL_POSITION : opos;
|
||||
if (ABORT_SIGS() || !force)
|
||||
{
|
||||
pos = opos;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Even if force is true, stop when the last
|
||||
* line in the file reaches the top of screen.
|
||||
* Check for 3 non-empty lines at top of screen.
|
||||
* The first will be shifted away by the add_forw_pos()
|
||||
* after this loop; the other two are the start and end of
|
||||
* the single line that we want to retain at top of screen.
|
||||
*/
|
||||
if (!first_line && sc_height >= 3 && empty_lines(3, sc_height-1) &&
|
||||
!empty_lines(0, 0) && !empty_lines(1, 1) && !empty_lines(2, 2))
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
@@ -331,6 +338,12 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
nlines++;
|
||||
if (do_repaint)
|
||||
continue;
|
||||
if (need_home)
|
||||
{
|
||||
lclear();
|
||||
home();
|
||||
need_home = FALSE;
|
||||
}
|
||||
/*
|
||||
* If this is the first screen displayed and
|
||||
* we hit an early EOF (i.e. before the requested
|
||||
@@ -353,13 +366,13 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
continue;
|
||||
}
|
||||
put_line(TRUE);
|
||||
if (stop_on_form_feed && !do_repaint && line_is_ff() && position(TOP) != NULL_POSITION)
|
||||
if (do_stop_on_form_feed && !do_repaint && line_is_ff() && position(TOP) != NULL_POSITION)
|
||||
break;
|
||||
forw_prompt = 1;
|
||||
forw_prompt = TRUE;
|
||||
}
|
||||
if (!first_line)
|
||||
add_forw_pos(pos, FALSE);
|
||||
if (nlines == 0 && !ignore_eoi && !ABORT_SIGS())
|
||||
if (nlines == 0 && !ignore_eoi)
|
||||
eof_bell();
|
||||
else if (do_repaint)
|
||||
repaint();
|
||||
@@ -375,13 +388,15 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
/*
|
||||
* Display n lines, scrolling backward.
|
||||
*/
|
||||
public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline)
|
||||
public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed)
|
||||
{
|
||||
int nlines = 0;
|
||||
lbool do_repaint;
|
||||
lbool newline;
|
||||
|
||||
squish_check();
|
||||
if (past_eof)
|
||||
force = TRUE;
|
||||
do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1) || header_lines > 0);
|
||||
|
||||
while (--n >= 0)
|
||||
@@ -397,7 +412,18 @@ public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
/*
|
||||
* Beginning of file: stop here unless "force" is true.
|
||||
*/
|
||||
if (!force)
|
||||
if (ABORT_SIGS() || !force)
|
||||
break;
|
||||
/*
|
||||
* Even if force is true, stop when the first
|
||||
* line in the file reaches the bottom of the screen.
|
||||
* Check for 2 non-empty lines at bottom of screen.
|
||||
* These are the start and end of the single line that
|
||||
* we want to retain at bottom of screen.
|
||||
*/
|
||||
if (sc_height >= 3 && empty_lines(0, sc_height-3) &&
|
||||
!empty_lines(sc_height-1, sc_height-1) &&
|
||||
!empty_lines(sc_height-2, sc_height-2))
|
||||
break;
|
||||
}
|
||||
if (pos != after_header_pos(pos))
|
||||
@@ -418,7 +444,7 @@ public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
|
||||
home();
|
||||
add_line();
|
||||
put_line(FALSE);
|
||||
if (stop_on_form_feed && line_is_ff())
|
||||
if (do_stop_on_form_feed && line_is_ff())
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -453,6 +479,8 @@ public void forward(int n, lbool force, lbool only_last, lbool to_newline)
|
||||
return;
|
||||
}
|
||||
|
||||
if (past_eof)
|
||||
force = TRUE;
|
||||
pos = position(BOTTOM_PLUS_ONE);
|
||||
if (pos == NULL_POSITION && (!force || empty_lines(2, sc_height-1)))
|
||||
{
|
||||
@@ -469,7 +497,7 @@ public void forward(int n, lbool force, lbool only_last, lbool to_newline)
|
||||
{
|
||||
do
|
||||
{
|
||||
back(1, position(TOP), TRUE, FALSE, FALSE);
|
||||
back(1, position(TOP), TRUE, FALSE, FALSE, stop_on_form_feed);
|
||||
pos = position(BOTTOM_PLUS_ONE);
|
||||
} while (pos == NULL_POSITION && !ABORT_SIGS());
|
||||
}
|
||||
@@ -479,7 +507,7 @@ public void forward(int n, lbool force, lbool only_last, lbool to_newline)
|
||||
return;
|
||||
}
|
||||
}
|
||||
forw(n, pos, force, only_last, to_newline, 0);
|
||||
forw(n, pos, force, only_last, to_newline, stop_on_form_feed, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -490,13 +518,15 @@ public void backward(int n, lbool force, lbool only_last, lbool to_newline)
|
||||
{
|
||||
POSITION pos;
|
||||
|
||||
if (past_eof)
|
||||
force = TRUE;
|
||||
pos = position(TOP);
|
||||
if (pos == NULL_POSITION && (!force || position(BOTTOM) == 0))
|
||||
{
|
||||
eof_bell();
|
||||
return;
|
||||
}
|
||||
back(n, pos, force, only_last, to_newline);
|
||||
back(n, pos, force, only_last, to_newline, stop_on_form_feed);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+65
-47
@@ -8,6 +8,7 @@ public size_t sprefix(constant char *ps, constant char *s, int uppercase);
|
||||
public void quit(int status);
|
||||
public int secure_allow(int features);
|
||||
public void raw_mode(int on);
|
||||
public void scrsize(void);
|
||||
public void screen_size_changed(void);
|
||||
public constant char * special_key_str(int key);
|
||||
public void init_win_colors(void);
|
||||
@@ -16,9 +17,9 @@ public void init_mouse(void);
|
||||
public void deinit_mouse(void);
|
||||
public void suspend_screen(void);
|
||||
public void resume_screen(void);
|
||||
public void init(void);
|
||||
public void deinit(void);
|
||||
public int interactive(void);
|
||||
public void term_init(void);
|
||||
public void term_deinit(void);
|
||||
public lbool interactive(void);
|
||||
public void home(void);
|
||||
public void dump_screen(void);
|
||||
public void add_line(void);
|
||||
@@ -29,8 +30,8 @@ public void line_left(void);
|
||||
public void check_winch(void);
|
||||
public void goto_line(int sindex);
|
||||
public void vbell(void);
|
||||
public void bell(void);
|
||||
public void clear(void);
|
||||
public void lbell(void);
|
||||
public void lclear(void);
|
||||
public void clear_eol(void);
|
||||
public void clear_bot(void);
|
||||
public void init_bracketed_paste(void);
|
||||
@@ -42,10 +43,12 @@ public void at_switch(int attr);
|
||||
public lbool is_at_equiv(int attr1, int attr2);
|
||||
public int apply_at_specials(int attr);
|
||||
public void putbs(void);
|
||||
public void win32_enqueue(int ch);
|
||||
public void WIN32ungetch(int ch);
|
||||
public lbool win32_kbhit2(lbool no_queued);
|
||||
public void win32_clear_queue(void);
|
||||
public lbool win32_kbhit2(char *pch);
|
||||
public lbool win32_kbhit(void);
|
||||
public char WIN32getch(void);
|
||||
public int WIN32getch(void);
|
||||
public void win32_getch_clear(void);
|
||||
public void WIN32setcolors(int fg, int bg);
|
||||
public void WIN32textout(constant char *text, size_t len);
|
||||
@@ -75,8 +78,8 @@ public lbool binary_char(LWCHAR c);
|
||||
public lbool control_char(LWCHAR c);
|
||||
public constant char * prchar(LWCHAR c);
|
||||
public constant char * prutfchar(LWCHAR ch);
|
||||
public int utf_len(char ch);
|
||||
public lbool is_utf8_well_formed(constant char *ss, int slen);
|
||||
public int utf_len(char ach);
|
||||
public lbool is_utf8_well_formed(constant char *ssa, int slen);
|
||||
public void utf_skip_to_lead(constant char **pp, constant char *limit);
|
||||
public LWCHAR get_wchar(constant char *sp);
|
||||
public void put_wchar(mutable char **pp, LWCHAR ch);
|
||||
@@ -106,7 +109,7 @@ public constant char * cmd_lastpattern(void);
|
||||
public void init_cmdhist(void);
|
||||
public void save_cmdhist(void);
|
||||
public void cmd_exec(void);
|
||||
public int in_mca(void);
|
||||
public lbool in_mca(void);
|
||||
public int norm_search_type(int st);
|
||||
public void screen_trashed_num(int trashed);
|
||||
public void screen_trashed(void);
|
||||
@@ -119,8 +122,8 @@ public void ungetcc_back(char c);
|
||||
public void ungetcc_end_command(void);
|
||||
public void ungetsc(constant char *s);
|
||||
public char peekcc(void);
|
||||
public void start_ignoring_input();
|
||||
public void stop_ignoring_input();
|
||||
public void start_ignoring_input(void);
|
||||
public void stop_ignoring_input(void);
|
||||
public lbool is_ignoring_input(int action);
|
||||
public void commands(void);
|
||||
public size_t cvt_length(size_t len, int ops);
|
||||
@@ -134,6 +137,9 @@ public void add_uvar_table(unsigned char *buf, size_t len);
|
||||
public void add_sysvar_table(unsigned char *buf, size_t len);
|
||||
public int fcmd_decode(constant char *cmd, constant char **sp);
|
||||
public int ecmd_decode(constant char *cmd, constant char **sp);
|
||||
public lbool parse_csl(lbool (*func)(constant char *word, size_t wlen, void *arg), constant char *str, void *arg);
|
||||
public int csl_bitmap_bit(constant char *name, size_t len, struct csl_bitmap_def *defs, int num_defs, constant char *pfx);
|
||||
public int parse_csl_bitmap(constant char *str, struct csl_bitmap_def *defs, int num_defs, constant char *pfx);
|
||||
public constant char * lgetenv(constant char *var);
|
||||
public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, size_t env_buf_len);
|
||||
public lbool isnullenv(constant char *s);
|
||||
@@ -142,8 +148,8 @@ public int lesskey_src(constant char *filename, lbool sysvar);
|
||||
public int lesskey_content(constant char *content, lbool sysvar);
|
||||
public int editchar(char c, int flags);
|
||||
public void init_textlist(struct textlist *tlist, mutable char *str);
|
||||
public constant char * forw_textlist(struct textlist *tlist, constant char *prev);
|
||||
public constant char * back_textlist(struct textlist *tlist, constant char *prev);
|
||||
public constant char * forw_textlist(constant struct textlist *tlist, constant char *prev);
|
||||
public constant char * back_textlist(constant struct textlist *tlist, constant char *prev);
|
||||
public void close_altpipe(IFILE ifile);
|
||||
public void check_altpipe_error(void);
|
||||
public int edit(constant char *filename);
|
||||
@@ -170,7 +176,7 @@ public char * dirfile(constant char *dirname, constant char *filename, int must_
|
||||
public char * homefile(constant char *filename);
|
||||
public char * fexpand(constant char *s);
|
||||
public char * fcomplete(constant char *s);
|
||||
public int bin_file(int f, ssize_t *n);
|
||||
public lbool bin_file(int f, ssize_t *n);
|
||||
public char * readfd(FILE *fd);
|
||||
public char * lglob(constant char *afilename);
|
||||
public lbool is_fake_pathname(constant char *path);
|
||||
@@ -188,8 +194,8 @@ public lbool eof_displayed(lbool offset);
|
||||
public lbool entire_file_displayed(void);
|
||||
public void squish_check(void);
|
||||
public int overlay_header(void);
|
||||
public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, int nblank);
|
||||
public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline);
|
||||
public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed, int nblank);
|
||||
public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed);
|
||||
public void forward(int n, lbool force, lbool only_last, lbool to_newline);
|
||||
public void backward(int n, lbool force, lbool only_last, lbool to_newline);
|
||||
public int get_back_scroll(void);
|
||||
@@ -203,10 +209,10 @@ public IFILE get_ifile(constant char *filename, IFILE prev);
|
||||
public constant char * get_filename(IFILE ifile);
|
||||
public constant char * get_real_filename(IFILE ifile);
|
||||
public int get_index(IFILE ifile);
|
||||
public void store_pos(IFILE ifile, struct scrpos *scrpos);
|
||||
public void store_pos(IFILE ifile, constant struct scrpos *scrpos);
|
||||
public void get_pos(IFILE ifile, struct scrpos *scrpos);
|
||||
public void set_open(IFILE ifile);
|
||||
public int opened(IFILE ifile);
|
||||
public lbool opened(IFILE ifile);
|
||||
public void hold_ifile(IFILE ifile, int incr);
|
||||
public int held_ifile(IFILE ifile);
|
||||
public void * get_filestate(IFILE ifile);
|
||||
@@ -216,7 +222,7 @@ public void *get_altpipe(IFILE ifile);
|
||||
public void set_altfilename(IFILE ifile, char *altfilename);
|
||||
public char * get_altfilename(IFILE ifile);
|
||||
public void if_dump(void);
|
||||
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop, POSITION *p_linepos, lbool *p_newline);
|
||||
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop, lbool full_pad, lbool rforw, POSITION *p_linepos, lbool *p_newline);
|
||||
public POSITION forw_line(POSITION curr_pos, POSITION *p_linepos, lbool *p_newline);
|
||||
public POSITION back_line(POSITION curr_pos, lbool *p_newline);
|
||||
public void set_attnpos(POSITION pos);
|
||||
@@ -235,7 +241,7 @@ public lbool is_line_contig_pos(POSITION pos);
|
||||
public void set_line_contig_pos(POSITION pos);
|
||||
public void prewind(lbool contig);
|
||||
public void plinestart(POSITION pos);
|
||||
public int line_pfx_width(void);
|
||||
public unsigned line_pfx_width(void);
|
||||
public void pshift_all(void);
|
||||
public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a);
|
||||
public void savec(void);
|
||||
@@ -251,7 +257,7 @@ public int pappend_b(char c, POSITION pos, lbool before_pendc);
|
||||
public int pappend(char c, POSITION pos);
|
||||
public lbool line_is_ff(void);
|
||||
public int pflushmbc(void);
|
||||
public void pdone(lbool endline, lbool chopped, lbool forw);
|
||||
public void pdone(lbool endline, lbool chopped, lbool forw, lbool full_pad);
|
||||
public int col_from_pos(POSITION linepos, POSITION spos, POSITION saved_pos, int saved_col);
|
||||
public POSITION pos_from_col(POSITION linepos, int col, POSITION saved_pos, int saved_col);
|
||||
public void set_attr_line(int a);
|
||||
@@ -263,7 +269,8 @@ public POSITION forw_raw_line_len(POSITION curr_pos, size_t read_len, constant c
|
||||
public POSITION forw_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp);
|
||||
public POSITION back_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp);
|
||||
public int skip_columns(int cols, constant char **linep, size_t *line_lenp);
|
||||
public void load_line(constant char *str);
|
||||
public void load_line(constant char *str, int attr, int reserve);
|
||||
public int longest_line_width(void);
|
||||
public int rrshift(void);
|
||||
public int set_color_map(int attr, constant char *colorstr);
|
||||
public constant char * get_color_map(int attr);
|
||||
@@ -278,11 +285,11 @@ public void lsystem(constant char *cmd, constant char *donemsg);
|
||||
public int pipe_mark(char c, constant char *cmd);
|
||||
public int pipe_data(constant char *cmd, POSITION spos, POSITION epos);
|
||||
public void init_mark(void);
|
||||
public int badmark(char c);
|
||||
public void setmark(char c, int where);
|
||||
public lbool badmark(char c);
|
||||
public void setmark(char c, int where, LINENUM linenum);
|
||||
public void clrmark(char c);
|
||||
public void lastmark(void);
|
||||
public void gomark(char c);
|
||||
public void gomark(char c, int sline);
|
||||
public POSITION markpos(char c);
|
||||
public char posmark(POSITION pos);
|
||||
public void unmark(IFILE ifile);
|
||||
@@ -303,6 +310,8 @@ public void opt_t(int type, constant char *s);
|
||||
public void opt__T(int type, constant char *s);
|
||||
public void opt_p(int type, constant char *s);
|
||||
public void opt__P(int type, constant char *s);
|
||||
public void opt_end_prompt(int type, constant char *s);
|
||||
public void opt_autosave(int type, constant char *s);
|
||||
public void opt_b(int type, constant char *s);
|
||||
public void opt_i(int type, constant char *s);
|
||||
public void opt__V(int type, constant char *s);
|
||||
@@ -314,15 +323,16 @@ public void opt_rscroll(int type, constant char *s);
|
||||
public void opt_query(int type, constant char *s);
|
||||
public void opt_match_shift(int type, constant char *s);
|
||||
public void calc_match_shift(void);
|
||||
public void opt_mousecap(int type, constant char *s);
|
||||
public void opt_emouse(int type, constant char *s);
|
||||
public void opt_mouse(int type, constant char *s);
|
||||
public void opt_wheel_lines(int type, constant char *s);
|
||||
public void opt_linenum_width(int type, constant char *s);
|
||||
public void opt_status_col_width(int type, constant char *s);
|
||||
public void opt_filesize(int type, constant char *s);
|
||||
public void opt_first_cmd_at_prompt(int type, constant char *s);
|
||||
public void opt_intr(int type, constant char *s);
|
||||
public int next_cnum(constant char **sp, constant char *printopt, constant char *errmsg, lbool *errp);
|
||||
public void opt_header(int type, constant char *s);
|
||||
public void opt_hilite_target(int type, constant char *s);
|
||||
public void opt_search_type(int type, constant char *s);
|
||||
public void opt_nosearch_headers(int type, constant char *s);
|
||||
public void opt_nosearch_header_lines(int type, constant char *s);
|
||||
@@ -331,17 +341,18 @@ public void opt_no_paste(int type, constant char *s);
|
||||
public void opt_ttyin_name(int type, constant char *s);
|
||||
public int chop_line(void);
|
||||
public int get_swindow(void);
|
||||
public lbool autosave_action(char act);
|
||||
public constant char * propt(char c);
|
||||
public void scan_option(constant char *s, lbool is_env);
|
||||
public void toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle);
|
||||
public int opt_has_param(struct loption *o);
|
||||
public constant char * opt_prompt(struct loption *o);
|
||||
public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle);
|
||||
public lbool opt_has_param(constant struct loption *o);
|
||||
public constant char * opt_prompt(constant struct loption *o);
|
||||
public constant char * opt_toggle_disallowed(int c);
|
||||
public lbool isoptpending(void);
|
||||
public void nopendopt(void);
|
||||
public int getnumc(constant char **sp, constant char *printopt, lbool *errp);
|
||||
public int getnum(char **sp, constant char *printopt, lbool *errp);
|
||||
public long getfraction(constant char **sp, constant char *printopt, lbool *errp);
|
||||
public lbool getnumc(constant char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num);
|
||||
public lbool getnum(char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num);
|
||||
public lbool getfraction(constant char **sp, mutable long *p_frac);
|
||||
public void init_unsupport(void);
|
||||
public int get_quit_at_eof(void);
|
||||
public void init_option(void);
|
||||
@@ -350,10 +361,11 @@ public struct loption * findopt_name(constant char **p_optname, constant char **
|
||||
public char * findopts_name(constant char *pfx);
|
||||
public void init_poll(void);
|
||||
public lbool ttyin_ready(void);
|
||||
public int supports_ctrl_x(void);
|
||||
public lbool supports_ctrl_x(void);
|
||||
public ssize_t iread(int fd, unsigned char *buf, size_t len);
|
||||
public int iopen(constant char *filename, int flags);
|
||||
public void intio(void);
|
||||
public void polling_ok(void);
|
||||
public time_type get_time(void);
|
||||
public char * errno_message(constant char *filename);
|
||||
public constant char * signal_message(int sig);
|
||||
@@ -362,18 +374,19 @@ public int percentage(POSITION num, POSITION den);
|
||||
public POSITION percent_pos(POSITION pos, int percent, long fraction);
|
||||
public int os9_signal(int type, RETSIGTYPE (*handler)());
|
||||
public void sleep_ms(int ms);
|
||||
public void put_line_hilite(lbool forw_scroll, lbool target);
|
||||
public void put_line(lbool forw_scroll);
|
||||
public void flush(void);
|
||||
public void set_output(int fd);
|
||||
public void set_output(int fd, lbool no_term_init);
|
||||
public int putchr(int ch);
|
||||
public void clear_bot_if_needed(void);
|
||||
public void putstr(constant char *s);
|
||||
public int less_printf(constant char *fmt, PARG *parg);
|
||||
public int less_printf(constant char *fmt, constant PARG *parg);
|
||||
public void get_return(void);
|
||||
public void error(constant char *fmt, PARG *parg);
|
||||
public void ierror(constant char *fmt, PARG *parg);
|
||||
public void ixerror(constant char *fmt, PARG *parg);
|
||||
public int query(constant char *fmt, PARG *parg);
|
||||
public void error(constant char *fmt, constant PARG *parg);
|
||||
public void ierror(constant char *fmt, constant PARG *parg);
|
||||
public void ixerror(constant char *fmt, constant PARG *parg);
|
||||
public int query(constant char *fmt, constant PARG *parg);
|
||||
public int compile_pattern(constant char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern);
|
||||
public void uncompile_pattern(PATTERN_TYPE *pattern);
|
||||
public int valid_pattern(char *pattern);
|
||||
@@ -386,22 +399,27 @@ public void add_back_pos(POSITION pos);
|
||||
public void pos_clear(void);
|
||||
public void pos_init(void);
|
||||
public int onscreen(POSITION pos);
|
||||
public int empty_screen(void);
|
||||
public int empty_lines(int s, int e);
|
||||
public lbool empty_screen(void);
|
||||
public lbool empty_lines(int s, int e);
|
||||
public void get_scrpos_pos(struct scrpos *scrpos, int where, POSITION pos);
|
||||
public void get_scrpos(struct scrpos *scrpos, int where);
|
||||
public int sindex_from_sline(int sline);
|
||||
public void pos_rehead(void);
|
||||
public POSITION beginning_of_line(POSITION tpos);
|
||||
public void pos_rehead(lbool adj_hshift);
|
||||
public void init_prompt(void);
|
||||
public constant char * pr_expand(constant char *proto);
|
||||
public constant char * eq_message(void);
|
||||
public constant char * pr_string(void);
|
||||
public constant char * end_pr_string(void);
|
||||
public constant char * wait_message(void);
|
||||
public void init_search(void);
|
||||
public int get_cvt_ops(int search_type);
|
||||
public constant char* prev_pattern_text(void);
|
||||
public void repaint_hilite(lbool on);
|
||||
public void draw_target_attn(lbool hilite);
|
||||
public void clear_attn(void);
|
||||
public void undo_search(lbool clear);
|
||||
public void undo_osc8(void);
|
||||
public lbool undo_osc8(void);
|
||||
public void clr_hlist(struct hilite_tree *anchor);
|
||||
public void clr_hilite(void);
|
||||
public void clr_filter(void);
|
||||
@@ -420,7 +438,7 @@ public int search(int search_type, constant char *pattern, int n);
|
||||
public void prep_hilite(POSITION spos, POSITION epos, int maxlines);
|
||||
public void set_filter_pattern(constant char *pattern, int search_type);
|
||||
public lbool is_filtering(void);
|
||||
public RETSIGTYPE winch(int type);
|
||||
public RETSIGTYPE lwinch(int type);
|
||||
public void init_signals(int on);
|
||||
public void psignals(void);
|
||||
public void cleantags(void);
|
||||
@@ -445,7 +463,7 @@ public void xbuf_deinit(struct xbuffer *xbuf);
|
||||
public void xbuf_reset(struct xbuffer *xbuf);
|
||||
public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b);
|
||||
public void xbuf_add_char(struct xbuffer *xbuf, char c);
|
||||
public void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len);
|
||||
public void xbuf_add_data(struct xbuffer *xbuf, constant void *vdata, size_t len);
|
||||
public int xbuf_pop(struct xbuffer *buf);
|
||||
public void xbuf_set(struct xbuffer *dst, constant struct xbuffer *src);
|
||||
public constant char * xbuf_char_data(constant struct xbuffer *xbuf);
|
||||
|
||||
+23
-12
@@ -1,4 +1,4 @@
|
||||
/* This file was generated by mkhelp.pl from less.hlp at 18:02 on 2025/10/4 */
|
||||
/* This file was generated by mkhelp.pl from less.hlp at 23:54 on 2026/5/30 */
|
||||
#include "less.h"
|
||||
constant char helpdata[] = {
|
||||
'\n',
|
||||
@@ -32,6 +32,7 @@ constant char helpdata[] = {
|
||||
' ',' ','E','S','C','-','{',' ',' ','^','L','e','f','t','A','r','r','o','w',' ',' ',' ',' ','L','e','f','t',' ',' ','t','o',' ','f','i','r','s','t',' ','c','o','l','u','m','n','.','\n',
|
||||
' ',' ','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','f','o','r','e','v','e','r',';',' ','l','i','k','e',' ','"','t','a','i','l',' ','-','f','"','.','\n',
|
||||
' ',' ','E','S','C','-','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','i','k','e',' ','F',' ','b','u','t',' ','s','t','o','p',' ','w','h','e','n',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','i','s',' ','f','o','u','n','d','.','\n',
|
||||
' ',' ','E','S','C','-','f',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','i','k','e',' ','F',' ','b','u','t',' ','r','i','n','g',' ','t','h','e',' ','b','e','l','l',' ','w','h','e','n',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','i','s',' ','f','o','u','n','d','.','\n',
|
||||
' ',' ','r',' ',' ','^','R',' ',' ','^','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n','.','\n',
|
||||
' ',' ','R',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n',',',' ','d','i','s','c','a','r','d','i','n','g',' ','b','u','f','f','e','r','e','d',' ','i','n','p','u','t','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
|
||||
@@ -54,7 +55,7 @@ constant char helpdata[] = {
|
||||
' ',' ','E','S','C','-','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n',
|
||||
' ',' ','&','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','D','i','s','p','l','a','y',' ','o','n','l','y',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
|
||||
'\t','\t','S','e','a','r','c','h',' ','i','s',' ','c','a','s','e','-','s','e','n','s','i','t','i','v','e',' ','u','n','l','e','s','s',' ','c','h','a','n','g','e','d',' ','w','i','t','h',' ','-','i',' ','o','r',' ','-','I','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','i','s',' ','c','a','s','e','-','s','e','n','s','i','t','i','v','e',' ','u','n','l','e','s','s',' ','c','h','a','n','g','e','d',' ','w','i','t','h',' ','-','i',' ','o','r',' ','-','I','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','A',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','m','a','y',' ','b','e','g','i','n',' ','w','i','t','h',' ','o','n','e',' ','o','r',' ','m','o','r','e',' ','o','f',':','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','^','N',' ','o','r',' ','!',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','N','O','N','-','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','^','E',' ','o','r',' ','*',' ',' ','S','e','a','r','c','h',' ','m','u','l','t','i','p','l','e',' ','f','i','l','e','s',' ','(','p','a','s','s',' ','t','h','r','u',' ','E','N','D',' ','O','F',' ','F','I','L','E',')','.','\n',
|
||||
@@ -68,8 +69,8 @@ constant char helpdata[] = {
|
||||
'\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','J','\b','J','U','\b','U','M','\b','M','P','\b','P','I','\b','I','N','\b','N','G','\b','G','\n',
|
||||
'\n',
|
||||
' ',' ','g',' ',' ','<',' ',' ','E','S','C','-','<',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','f','i','r','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
|
||||
' ',' ','G',' ',' ','>',' ',' ','E','S','C','-','>',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','l','a','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
|
||||
' ',' ','g',' ',' ','<',' ',' ','E','S','C','-','<',' ',' ','H','O','M','E',' ','*',' ',' ','G','o',' ','t','o',' ','f','i','r','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
|
||||
' ',' ','G',' ',' ','>',' ',' ','E','S','C','-','>',' ',' ','E','N','D',' ',' ','*',' ',' ','G','o',' ','t','o',' ','l','a','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
|
||||
' ',' ','p',' ',' ','%',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','b','e','g','i','n','n','i','n','g',' ','o','f',' ','f','i','l','e',' ','(','o','r',' ','_','\b','N',' ','p','e','r','c','e','n','t',' ','i','n','t','o',' ','f','i','l','e',')','.','\n',
|
||||
' ',' ','t',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','n','e','x','t',' ','t','a','g','.','\n',
|
||||
' ',' ','T',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','p','r','e','v','i','o','u','s',' ','t','a','g','.','\n',
|
||||
@@ -83,11 +84,11 @@ constant char helpdata[] = {
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','b','a','c','k','w','a','r','d',' ','t','o',' ','t','h','e',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','b','o','t','t','o','m',' ','l','i','n','e','.','\n',
|
||||
'\n',
|
||||
' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','t','o','p',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
|
||||
' ',' ','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','b','o','t','t','o','m',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
|
||||
' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n','.','\n',
|
||||
' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n',
|
||||
' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n',
|
||||
' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','M','a','r','k',' ','t','h','e',' ','t','o','p',' ','l','i','n','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
|
||||
' ',' ','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','M','a','r','k',' ','t','h','e',' ','b','o','t','t','o','m',' ','l','i','n','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
|
||||
' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n',' ','(','p','u','t',' ','o','n',' ','p','o','s','i','t','i','o','n',' ','_','\b','N',')','.','\n',
|
||||
' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n',
|
||||
' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n',
|
||||
' ',' ','E','S','C','-','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','a',' ','m','a','r','k','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','A',' ','m','a','r','k',' ','i','s',' ','a','n','y',' ','u','p','p','e','r','-','c','a','s','e',' ','o','r',' ','l','o','w','e','r','-','c','a','s','e',' ','l','e','t','t','e','r','.','\n',
|
||||
@@ -204,9 +205,9 @@ constant char helpdata[] = {
|
||||
' ',' ','-','V',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','v','e','r','s','i','o','n','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n',
|
||||
' ',' ','-','w',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','u','n','r','e','a','d','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','f','o','r','w','a','r','d','-','s','c','r','e','e','n','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','f','u','l','l',' ','s','c','r','e','e','n',' ','m','o','v','e','m','e','n','t','.','\n',
|
||||
' ',' ','-','W',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','H','I','L','I','T','E','-','U','N','R','E','A','D','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','a','n','y',' ','f','o','r','w','a','r','d',' ','m','o','v','e','m','e','n','t','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','a','n','y',' ','m','o','v','e','m','e','n','t','.','\n',
|
||||
' ',' ','-','x',' ','[','_','\b','N','[',',','.','.','.',']',']',' ',' ','-','-','t','a','b','s','=','[','_','\b','N','[',',','.','.','.',']',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','a','b',' ','s','t','o','p','s','.','\n',
|
||||
' ',' ','-','X',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','n','o','-','i','n','i','t','\n',
|
||||
@@ -222,6 +223,12 @@ constant char helpdata[] = {
|
||||
' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','h','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','.','\n',
|
||||
'\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','a','u','t','o','s','a','v','e','=','[','_','\b','m','_','\b','/','_','\b','!','_','\b','*',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','A','c','t','i','o','n','s',' ','w','h','i','c','h',' ','c','a','u','s','e',' ','t','h','e',' ','h','i','s','t','o','r','y',' ','f','i','l','e',' ','t','o',' ','b','e',' ','s','a','v','e','d','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','e','m','o','u','s','e','=','[','_','\b','v','_','\b','s','_','\b','c','_','\b','r','_','\b','o','_','\b','l','_','\b','l',',','_','\b','v','_','\b','d','_','\b','r','_','\b','a','_','\b','g',',','_','\b','h','_','\b','s','_','\b','c','_','\b','r','_','\b','o','_','\b','l','_','\b','l',',','_','\b','h','_','\b','d','_','\b','r','_','\b','a','_','\b','g',',','_','\b','l','_','\b','c','_','\b','l','_','\b','i','_','\b','c','_','\b','k',',','_','\b','r','_','\b','c','_','\b','l','_','\b','i','_','\b','c','_','\b','k',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','f','e','a','t','u','r','e','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','e','n','d','-','p','r','o','m','p','t','=','[','_','\b','s','_','\b','t','_','\b','r','_','\b','i','_','\b','n','_','\b','g',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','t','r','i','n','g',' ','t','o',' ','b','e',' ','p','r','i','n','t','e','d',' ','a','f','t','e','r',' ','e','r','a','s','i','n','g',' ','t','h','e',' ','p','r','o','m','p','t','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','e','x','i','t','-','f','o','l','l','o','w','-','o','n','-','c','l','o','s','e','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','i','t',' ','F',' ','c','o','m','m','a','n','d',' ','o','n',' ','a',' ','p','i','p','e',' ','w','h','e','n',' ','w','r','i','t','e','r',' ','c','l','o','s','e','s',' ','p','i','p','e','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','i','l','e','-','s','i','z','e','\n',
|
||||
@@ -232,6 +239,8 @@ constant char helpdata[] = {
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','t','o','p',' ','s','c','r','o','l','l','i','n','g',' ','w','h','e','n',' ','a',' ','f','o','r','m',' ','f','e','e','d',' ','c','h','a','r','a','c','t','e','r',' ','i','s',' ','r','e','a','c','h','e','d','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','h','e','a','d','e','r','=','[','_','\b','L','[',',','_','\b','C','[',',','_','\b','N',']',']',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','_','\b','L',' ','l','i','n','e','s',' ','(','s','t','a','r','t','i','n','g',' ','a','t',' ','l','i','n','e',' ','_','\b','N',')',' ','a','n','d',' ','_','\b','C',' ','c','o','l','u','m','n','s',' ','a','s',' ','h','e','a','d','e','r','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','h','i','l','i','t','e','-','t','a','r','g','e','t','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','t','h','e',' ','t','a','r','g','e','t',' ','l','i','n','e','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','c','s','e','a','r','c','h','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','i','l','e',' ','a','s',' ','e','a','c','h',' ','p','a','t','t','e','r','n',' ','c','h','a','r','a','c','t','e','r',' ','i','s',' ','t','y','p','e','d',' ','i','n','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','t','r','=','[','_','\b','C',']','\n',
|
||||
@@ -247,7 +256,7 @@ constant char helpdata[] = {
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','d','e','l','i','n','e','s','=','[','_','\b','N',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','a','d',' ','_','\b','N',' ','l','i','n','e','s',' ','f','r','o','m',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','a','n','d',' ','l','o','o','k',' ','f','o','r',' ','v','i','m',' ','m','o','d','e','l','i','n','e','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','u','s','e','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','i','n','p','u','t','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','c','l','i','c','k','i','n','g',' ','a','n','d',' ','v','e','r','t','i','c','a','l',' ','s','c','r','o','l','l','i','n','g','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','e','d','i','t','-','w','a','r','n','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','w','a','r','n',' ','w','h','e','n',' ','u','s','i','n','g',' ','v',' ','c','o','m','m','a','n','d',' ','o','n',' ','a',' ','f','i','l','e',' ','o','p','e','n','e','d',' ','v','i','a',' ','L','E','S','S','O','P','E','N','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','k','e','y','p','a','d','\n',
|
||||
@@ -276,6 +285,8 @@ constant char helpdata[] = {
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','d','e','f','a','u','l','t',' ','o','p','t','i','o','n','s',' ','f','o','r',' ','e','v','e','r','y',' ','s','e','a','r','c','h','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','h','o','w','-','p','r','e','p','r','o','c','-','e','r','r','o','r','s','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','a',' ','m','e','s','s','a','g','e',' ','i','f',' ','p','r','e','p','r','o','c','e','s','s','o','r',' ','e','x','i','t','s',' ','w','i','t','h',' ','a','n',' ','e','r','r','o','r',' ','s','t','a','t','u','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','a','s','t','-','e','o','f','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','c','r','o','l','l','i','n','g',' ','c','o','m','m','a','n','d','s',' ','c','o','n','t','i','n','u','e',' ','p','a','s','t',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','r','o','c','-','b','a','c','k','s','p','a','c','e','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','o','c','e','s','s',' ','b','a','c','k','s','p','a','c','e','s',' ','f','o','r',' ','b','o','l','d','/','u','n','d','e','r','l','i','n','e','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','P','R','O','C','-','B','A','C','K','S','P','A','C','E','\n',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -31,7 +31,7 @@ struct ifile {
|
||||
void *h_filestate; /* File state (used in ch.c) */
|
||||
int h_index; /* Index within command line list */
|
||||
int h_hold; /* Hold count */
|
||||
char h_opened; /* Has this ifile been opened? */
|
||||
lbool h_opened; /* Has this ifile been opened? */
|
||||
struct scrpos h_scrpos; /* Saved position within the file */
|
||||
void *h_altpipe; /* Alt pipe */
|
||||
char *h_altfilename; /* Alt filename */
|
||||
@@ -108,7 +108,7 @@ static struct ifile * new_ifile(constant char *filename, struct ifile *prev)
|
||||
p->h_filename = save(filename);
|
||||
p->h_rfilename = lrealpath(filename);
|
||||
p->h_scrpos.pos = NULL_POSITION;
|
||||
p->h_opened = 0;
|
||||
p->h_opened = FALSE;
|
||||
p->h_hold = 0;
|
||||
p->h_filestate = NULL;
|
||||
p->h_altfilename = NULL;
|
||||
@@ -269,7 +269,7 @@ public int get_index(IFILE ifile)
|
||||
/*
|
||||
* Save the file position to be associated with a given file.
|
||||
*/
|
||||
public void store_pos(IFILE ifile, struct scrpos *scrpos)
|
||||
public void store_pos(IFILE ifile, constant struct scrpos *scrpos)
|
||||
{
|
||||
int_ifile(ifile)->h_scrpos = *scrpos;
|
||||
}
|
||||
@@ -288,13 +288,13 @@ public void get_pos(IFILE ifile, struct scrpos *scrpos)
|
||||
*/
|
||||
public void set_open(IFILE ifile)
|
||||
{
|
||||
int_ifile(ifile)->h_opened = 1;
|
||||
int_ifile(ifile)->h_opened = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return whether the ifile has been opened previously.
|
||||
*/
|
||||
public int opened(IFILE ifile)
|
||||
public lbool opened(IFILE ifile)
|
||||
{
|
||||
return (int_ifile(ifile)->h_opened);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -22,7 +22,6 @@
|
||||
extern int squeeze;
|
||||
extern int hshift;
|
||||
extern int quit_if_one_screen;
|
||||
extern int ignore_eoi;
|
||||
extern int status_col;
|
||||
extern int wordwrap;
|
||||
extern POSITION start_attnpos;
|
||||
@@ -81,7 +80,7 @@ static void init_status_col(POSITION base_pos, POSITION disp_pos, POSITION edisp
|
||||
* a line. The new position is the position of the first character
|
||||
* of the NEXT line. The line obtained is the line starting at curr_pos.
|
||||
*/
|
||||
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop, POSITION *p_linepos, lbool *p_newline)
|
||||
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop, lbool full_pad, lbool rforw, POSITION *p_linepos, lbool *p_newline)
|
||||
{
|
||||
POSITION base_pos;
|
||||
POSITION new_pos;
|
||||
@@ -246,7 +245,7 @@ get_forw_line:
|
||||
} while (c != '\n' && c != EOI);
|
||||
new_pos = ch_tell();
|
||||
endline = TRUE;
|
||||
quit_if_one_screen = FALSE;
|
||||
quit_if_one_screen = 0;
|
||||
chopped = TRUE;
|
||||
} else
|
||||
{
|
||||
@@ -307,7 +306,7 @@ get_forw_line:
|
||||
pappend_b(' ', ch_tell()-1, TRUE);
|
||||
}
|
||||
#endif
|
||||
pdone(endline, rscroll && chopped, TRUE);
|
||||
pdone(endline, rscroll && chopped, rforw, full_pad);
|
||||
|
||||
#if HILITE_SEARCH
|
||||
if (is_filtered(base_pos))
|
||||
@@ -346,7 +345,7 @@ get_forw_line:
|
||||
|
||||
public POSITION forw_line(POSITION curr_pos, POSITION *p_linepos, lbool *p_newline)
|
||||
{
|
||||
return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE, p_linepos, p_newline);
|
||||
return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE, FALSE, TRUE, p_linepos, p_newline);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -502,7 +501,7 @@ get_back_line:
|
||||
{
|
||||
endline = TRUE;
|
||||
chopped = TRUE;
|
||||
quit_if_one_screen = FALSE;
|
||||
quit_if_one_screen = 0;
|
||||
edisp_pos = new_pos;
|
||||
break;
|
||||
}
|
||||
@@ -569,7 +568,7 @@ get_back_line:
|
||||
}
|
||||
}
|
||||
|
||||
pdone(endline, chopped, FALSE);
|
||||
pdone(endline, chopped, FALSE, FALSE);
|
||||
|
||||
#if HILITE_SEARCH
|
||||
if (is_filtered(base_pos))
|
||||
|
||||
+29
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -20,6 +20,9 @@ extern lbool squished;
|
||||
extern int sc_width, sc_height;
|
||||
extern int show_attn;
|
||||
extern int top_scroll;
|
||||
extern int quit_if_one_screen;
|
||||
extern lbool one_screen;
|
||||
extern lbool full_screen;
|
||||
extern POSITION header_start_pos;
|
||||
|
||||
/*
|
||||
@@ -188,15 +191,15 @@ static void after_header_message(void)
|
||||
{
|
||||
#if HAVE_TIME
|
||||
#define MSG_FREQ 1 /* seconds */
|
||||
static time_type last_msg = (time_type) 0;
|
||||
time_type now = get_time();
|
||||
if (now < last_msg + MSG_FREQ)
|
||||
return;
|
||||
last_msg = now;
|
||||
static time_type last_msg = (time_type) 0;
|
||||
time_type now = get_time();
|
||||
if (now < last_msg + MSG_FREQ)
|
||||
return;
|
||||
last_msg = now;
|
||||
#endif
|
||||
bell();
|
||||
/* {{ This message displays before the file text is updated, which is not a good UX. }} */
|
||||
/** error("Cannot display text before header; use --header=- to disable header", NULL_PARG); */
|
||||
lbell();
|
||||
/* {{ This message displays before the file text is updated, which is not a good UX. }} */
|
||||
/** error("Cannot display text before header; use --header=- to disable header", NULL_PARG); */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -210,8 +213,8 @@ public POSITION after_header_pos(POSITION pos)
|
||||
{
|
||||
if (header_start_pos != NULL_POSITION && pos < header_start_pos)
|
||||
{
|
||||
after_header_message();
|
||||
pos = header_start_pos;
|
||||
after_header_message();
|
||||
pos = header_start_pos;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
@@ -235,6 +238,14 @@ public void jump_loc(POSITION pos, int sline)
|
||||
pos = next_unfiltered(pos);
|
||||
sindex = sindex_from_sline(sline);
|
||||
|
||||
if (!full_screen && !(quit_if_one_screen && one_screen))
|
||||
{
|
||||
/* If not full screen, can't rely on scrolling logic below, since
|
||||
* "scrolling" may just print lines in the unused part of the screen. */
|
||||
pos_clear();
|
||||
lclear();
|
||||
}
|
||||
|
||||
if ((nline = onscreen(pos)) >= 0)
|
||||
{
|
||||
/*
|
||||
@@ -243,9 +254,9 @@ public void jump_loc(POSITION pos, int sline)
|
||||
*/
|
||||
nline -= sindex;
|
||||
if (nline > 0)
|
||||
forw(nline, position(BOTTOM_PLUS_ONE), TRUE, FALSE, FALSE, 0);
|
||||
forw(nline, position(BOTTOM_PLUS_ONE), TRUE, FALSE, FALSE, FALSE, 0);
|
||||
else
|
||||
back(-nline, position(TOP), TRUE, FALSE, FALSE);
|
||||
back(-nline, position(TOP), TRUE, FALSE, FALSE, FALSE);
|
||||
#if HILITE_SEARCH
|
||||
if (show_attn)
|
||||
repaint_hilite(TRUE);
|
||||
@@ -286,7 +297,7 @@ public void jump_loc(POSITION pos, int sline)
|
||||
* close enough to the current screen
|
||||
* that we can just scroll there after all.
|
||||
*/
|
||||
forw(sc_height-sindex+nline-1, bpos, TRUE, FALSE, FALSE, 0);
|
||||
forw(sc_height-sindex+nline-1, bpos, TRUE, FALSE, FALSE, FALSE, 0);
|
||||
#if HILITE_SEARCH
|
||||
if (show_attn)
|
||||
repaint_hilite(TRUE);
|
||||
@@ -308,7 +319,7 @@ public void jump_loc(POSITION pos, int sline)
|
||||
lastmark();
|
||||
squished = FALSE;
|
||||
screen_trashed_num(0);
|
||||
forw(sc_height-1, pos, TRUE, FALSE, FALSE, sindex-nline);
|
||||
forw(sc_height-1, pos, TRUE, FALSE, FALSE, FALSE, sindex-nline);
|
||||
} else
|
||||
{
|
||||
/*
|
||||
@@ -337,7 +348,7 @@ public void jump_loc(POSITION pos, int sline)
|
||||
* close enough to the current screen
|
||||
* that we can just scroll there after all.
|
||||
*/
|
||||
back(nline, tpos, TRUE, FALSE, FALSE);
|
||||
back(nline, tpos, TRUE, FALSE, FALSE, FALSE);
|
||||
#if HILITE_SEARCH
|
||||
if (show_attn)
|
||||
repaint_hilite(TRUE);
|
||||
@@ -347,11 +358,11 @@ public void jump_loc(POSITION pos, int sline)
|
||||
}
|
||||
lastmark();
|
||||
if (!top_scroll)
|
||||
clear();
|
||||
lclear();
|
||||
else
|
||||
home();
|
||||
screen_trashed_num(0);
|
||||
add_back_pos(pos);
|
||||
back(sc_height-1, pos, TRUE, FALSE, FALSE);
|
||||
back(sc_height-1, pos, TRUE, FALSE, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -53,5 +53,8 @@ typedef __int64 ssize_t;
|
||||
typedef __int32 ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __BORLANDC__
|
||||
typedef long ssize_t;
|
||||
#endif
|
||||
|
||||
#endif // LESS_LANG_H_
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Less OSC 8 handler.
|
||||
|
||||
echo() { printf %s\\n "$*"; }
|
||||
|
||||
# Open a link of the form "file://HOST/PATH" or "file:///PATH"
|
||||
open_file() {
|
||||
case $1 in
|
||||
file:///* | file://localhost/*)
|
||||
less -- "/${1#file://*/}"
|
||||
;;
|
||||
|
||||
file://*/*)
|
||||
linkhost=${1#file://}; linkhost=${linkhost%%/*}
|
||||
localhost=${HOSTNAME:-$(bash -c 'printf %s "$HOSTNAME"' || uname -n)} 2>/dev/null
|
||||
|
||||
case $localhost in
|
||||
*/* | '')
|
||||
echo "unable to detect local hostname: $localhost"
|
||||
exit 1
|
||||
;;
|
||||
"$linkhost")
|
||||
less -- "/${1#file://*/}"
|
||||
;;
|
||||
*)
|
||||
echo "cannot open remote file: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "invalid file link: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Open a link of the form "man:NAME" or "man:NAME(SECTION)".
|
||||
open_man() {
|
||||
case $1 in
|
||||
man:?*\(*\) )
|
||||
sect=${1#*\(}; sect=${sect%?}
|
||||
name=${1#man:}; name=${name%%\(*}
|
||||
man -- ${sect:+"$sect"} "$name"
|
||||
;;
|
||||
|
||||
man:?*)
|
||||
man -- "${1#man:}"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "invalid man link: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case $1 in
|
||||
file:*) open_file "$1" ;;
|
||||
man:*) open_man "$1" ;;
|
||||
*) echo "unsupported link type: $1"; exit 1 ;;
|
||||
esac
|
||||
+47
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -52,9 +52,6 @@
|
||||
#if HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#if HAVE_WCTYPE_H
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
#if HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
@@ -266,6 +263,11 @@ typedef off_t LINENUM;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use iread() to read tty? */
|
||||
#if !MSDOS_COMPILER || MSDOS_COMPILER == DJGPPC
|
||||
#define LESS_IREAD_TTY 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flags for creat()
|
||||
*/
|
||||
@@ -336,6 +338,12 @@ struct wchar_range_table
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
struct csl_bitmap_def
|
||||
{
|
||||
constant char *bit_name;
|
||||
int bit_value;
|
||||
};
|
||||
|
||||
#if HAVE_POLL
|
||||
typedef short POLL_EVENTS;
|
||||
#endif
|
||||
@@ -438,8 +446,7 @@ typedef enum osc8_state {
|
||||
#define AT_PLACEHOLDER (1 << 7) /* Placeholder for half of double-wide char */
|
||||
|
||||
#define AT_COLOR_SHIFT 8
|
||||
#define AT_NUM_COLORS 16
|
||||
#define AT_COLOR ((AT_NUM_COLORS-1) << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR ((~(unsigned)0) << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_ATTN (1 << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_BIN (2 << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_CTRL (3 << AT_COLOR_SHIFT)
|
||||
@@ -450,8 +457,12 @@ typedef enum osc8_state {
|
||||
#define AT_COLOR_RSCROLL (8 << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_HEADER (9 << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_SEARCH (10 << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_SUBSEARCH(i) ((10+(i)) << AT_COLOR_SHIFT)
|
||||
#define NUM_SEARCH_COLORS (AT_NUM_COLORS-10-1)
|
||||
#define AT_COLOR_TILDE (11 << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_TARGET (12 << AT_COLOR_SHIFT)
|
||||
#define AT_COLOR_SS_OFFSET 13 /* largest AT_COLOR_* value + 1 */
|
||||
#define NUM_SEARCH_COLORS 5
|
||||
#define AT_NUM_COLORS (AT_COLOR_SS_OFFSET + NUM_SEARCH_COLORS)
|
||||
#define AT_COLOR_SUBSEARCH(i) ((AT_COLOR_SS_OFFSET+(i)-1) << AT_COLOR_SHIFT)
|
||||
|
||||
typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE;
|
||||
|
||||
@@ -627,14 +638,25 @@ typedef enum {
|
||||
#endif
|
||||
|
||||
/* X11 mouse reporting definitions */
|
||||
#define X11MOUSE_BUTTON1 0 /* Left button press */
|
||||
#define X11MOUSE_BUTTON2 1 /* Middle button press */
|
||||
#define X11MOUSE_BUTTON3 2 /* Right button press */
|
||||
#define X11MOUSE_BUTTON_REL 3 /* Button release */
|
||||
#define X11MOUSE_DRAG 0x20 /* Drag with button down */
|
||||
#define X11MOUSE_WHEEL_UP 0x40 /* Wheel scroll up */
|
||||
#define X11MOUSE_WHEEL_DOWN 0x41 /* Wheel scroll down */
|
||||
#define X11MOUSE_OFFSET 0x20 /* Added to button & pos bytes to create a char */
|
||||
#define X11MOUSE_BUTTON1 0 /* Left button press */
|
||||
#define X11MOUSE_BUTTON2 1 /* Middle button press */
|
||||
#define X11MOUSE_BUTTON3 2 /* Right button press */
|
||||
#define X11MOUSE_BUTTON_REL 3 /* Button release */
|
||||
#define X11MOUSE_DRAG 0x20 /* Drag with button down */
|
||||
#define X11MOUSE_WHEEL_UP 0x40 /* Wheel scroll up */
|
||||
#define X11MOUSE_WHEEL_DOWN 0x41 /* Wheel scroll down */
|
||||
#define X11MOUSE_WHEEL_LEFT 0x42 /* Wheel scroll left */
|
||||
#define X11MOUSE_WHEEL_RIGHT 0x43 /* Wheel scroll right */
|
||||
#define X11MOUSE_OFFSET 0x20 /* Added to button & pos bytes to create a char */
|
||||
|
||||
/* Mouse features */
|
||||
#define EMOUSE_HSCROLL (1<<0) /* Horizontal scroll */
|
||||
#define EMOUSE_VSCROLL (1<<1) /* Vertical scroll */
|
||||
#define EMOUSE_HDRAG (1<<2) /* Horizontal drag */
|
||||
#define EMOUSE_VDRAG (1<<3) /* Vertical drag */
|
||||
#define EMOUSE_LCLICK (1<<4) /* Left click */
|
||||
#define EMOUSE_RCLICK (1<<5) /* Right click */
|
||||
#define EMOUSE_COUNT 6
|
||||
|
||||
/* Security features. */
|
||||
#define SF_EDIT (1<<1) /* Edit file (v) */
|
||||
@@ -675,3 +697,12 @@ unsigned long lstrtoulc(constant char*, constant char**, int);
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
int pclose(FILE*);
|
||||
#endif
|
||||
#if !HAVE_STRCHR
|
||||
char * strchr(char *s, char c);
|
||||
#endif
|
||||
#if !HAVE_MEMCPY
|
||||
void * memcpy(void *dst, constant void *src, size_t len);
|
||||
#endif
|
||||
#if !HAVE_STRSTR
|
||||
char * strstr(constant char *haystack, constant char *needle);
|
||||
#endif
|
||||
+22
-11
@@ -29,6 +29,7 @@
|
||||
ESC-{ ^LeftArrow Left to first column.
|
||||
F Forward forever; like "tail -f".
|
||||
ESC-F Like F but stop when search pattern is found.
|
||||
ESC-f Like F but ring the bell when search pattern is found.
|
||||
r ^R ^L Repaint screen.
|
||||
R Repaint screen, discarding buffered input.
|
||||
---------------------------------------------------
|
||||
@@ -51,7 +52,7 @@
|
||||
ESC-U Clear search highlighting.
|
||||
&_p_a_t_t_e_r_n * Display only matching lines.
|
||||
---------------------------------------------------
|
||||
Search is case-sensitive unless changed with -i or -I.
|
||||
Search is case-sensitive unless changed with -i or -I.
|
||||
A search pattern may begin with one or more of:
|
||||
^N or ! Search for NON-matching lines.
|
||||
^E or * Search multiple files (pass thru END OF FILE).
|
||||
@@ -65,8 +66,8 @@
|
||||
|
||||
JJUUMMPPIINNGG
|
||||
|
||||
g < ESC-< * Go to first line in file (or line _N).
|
||||
G > ESC-> * Go to last line in file (or line _N).
|
||||
g < ESC-< HOME * Go to first line in file (or line _N).
|
||||
G > ESC-> END * Go to last line in file (or line _N).
|
||||
p % * Go to beginning of file (or _N percent into file).
|
||||
t * Go to the (_N-th) next tag.
|
||||
T * Go to the (_N-th) previous tag.
|
||||
@@ -80,11 +81,11 @@
|
||||
Each "find open bracket" command goes backward to the open bracket
|
||||
matching the (_N-th) close bracket in the bottom line.
|
||||
|
||||
m_<_l_e_t_t_e_r_> Mark the current top line with <letter>.
|
||||
M_<_l_e_t_t_e_r_> Mark the current bottom line with <letter>.
|
||||
'_<_l_e_t_t_e_r_> Go to a previously marked position.
|
||||
'' Go to the previous position.
|
||||
^X^X Same as '.
|
||||
m_<_l_e_t_t_e_r_> * Mark the top line (or line _N) with <letter>.
|
||||
M_<_l_e_t_t_e_r_> * Mark the bottom line (or line _N) with <letter>.
|
||||
'_<_l_e_t_t_e_r_> * Go to a previously marked position (put on position _N).
|
||||
'' * Go to the previous position.
|
||||
^X^X * Same as '.
|
||||
ESC-m_<_l_e_t_t_e_r_> Clear a mark.
|
||||
---------------------------------------------------
|
||||
A mark is any upper-case or lower-case letter.
|
||||
@@ -201,9 +202,9 @@
|
||||
-V ........ --version
|
||||
Display the version number of "less".
|
||||
-w ........ --hilite-unread
|
||||
Highlight first new line after forward-screen.
|
||||
Highlight first new line after full screen movement.
|
||||
-W ........ --HILITE-UNREAD
|
||||
Highlight first new line after any forward movement.
|
||||
Highlight first new line after any movement.
|
||||
-x [_N[,...]] --tabs=[_N[,...]]
|
||||
Set tab stops.
|
||||
-X ........ --no-init
|
||||
@@ -219,6 +220,12 @@
|
||||
-# [_N] .... --shift=[_N]
|
||||
Set horizontal scroll amount (0 = one half screen width).
|
||||
|
||||
--autosave=[_m_/_!_*]
|
||||
Actions which cause the history file to be saved.
|
||||
--emouse=[_v_s_c_r_o_l_l,_v_d_r_a_g,_h_s_c_r_o_l_l,_h_d_r_a_g,_l_c_l_i_c_k,_r_c_l_i_c_k]
|
||||
Enable mouse features.
|
||||
--end-prompt=[_s_t_r_i_n_g]
|
||||
String to be printed after erasing the prompt.
|
||||
--exit-follow-on-close
|
||||
Exit F command on a pipe when writer closes pipe.
|
||||
--file-size
|
||||
@@ -229,6 +236,8 @@
|
||||
Stop scrolling when a form feed character is reached.
|
||||
--header=[_L[,_C[,_N]]]
|
||||
Use _L lines (starting at line _N) and _C columns as headers.
|
||||
--hilite-target
|
||||
Highlight the target line.
|
||||
--incsearch
|
||||
Search file as each pattern character is typed in.
|
||||
--intr=[_C]
|
||||
@@ -244,7 +253,7 @@
|
||||
--modelines=[_N]
|
||||
Read _N lines from the input file and look for vim modelines.
|
||||
--mouse
|
||||
Enable mouse input.
|
||||
Enable mouse clicking and vertical scrolling.
|
||||
--no-edit-warn
|
||||
Don't warn when using v command on a file opened via LESSOPEN.
|
||||
--no-keypad
|
||||
@@ -273,6 +282,8 @@
|
||||
Set default options for every search.
|
||||
--show-preproc-errors
|
||||
Display a message if preprocessor exits with an error status.
|
||||
--past-eof
|
||||
Scrolling commands continue past end of file.
|
||||
--proc-backspace
|
||||
Process backspaces for bold/underline.
|
||||
--PROC-BACKSPACE
|
||||
|
||||
+1212
-572
File diff suppressed because it is too large.
Load diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
@@ -1,9 +1,33 @@
|
||||
.TH LESSECHO 1 "Version 685: 04 Oct 2025"
|
||||
.TH LESSECHO 1 "30 May 2026" "less 704"
|
||||
.\" Define a string to interpolate the hyphenless break point escape
|
||||
.\" sequence (for URLs and similar) if the formatter claims groff
|
||||
.\" compatibility, else interpolate nothing.
|
||||
.ie \n(.g .ds : \:
|
||||
.el .ds : \" empty
|
||||
.SH NAME
|
||||
lessecho \- expand metacharacters
|
||||
.SH SYNOPSIS
|
||||
.HP
|
||||
.B lessecho
|
||||
.I "[-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-a] file ..."
|
||||
.RB [ \-a ]
|
||||
.RB [ \-o\c
|
||||
.IR x ]
|
||||
.RB [ \-c\c
|
||||
.IR x ]
|
||||
.RB [ \-p\c
|
||||
.IR n ]
|
||||
.RB [ \-d\c
|
||||
.IR n ]
|
||||
.RB [ \-m\c
|
||||
.IR x ]
|
||||
.RB [ \-n\c
|
||||
.IR n ]
|
||||
.RB [ \-e\c
|
||||
.IR x ]
|
||||
.I file
|
||||
\&.\|.\|.
|
||||
.PP
|
||||
.B "lessecho \-\-version"
|
||||
.SH "DESCRIPTION"
|
||||
.B lessecho
|
||||
is a program that simply echos its arguments on standard output.
|
||||
@@ -18,12 +42,12 @@ A summary of options is included below.
|
||||
.TP
|
||||
.B \-e\fIx\fP
|
||||
Specifies "\fIx\fP", rather than backslash, to be the escape char for metachars.
|
||||
If \fIx\fP is "-", no escape char is used and arguments containing metachars
|
||||
If \fIx\fP is "\-", no escape char is used and arguments containing metachars
|
||||
are surrounded by quotes instead.
|
||||
.TP
|
||||
.B \-o\fIx\fP
|
||||
Specifies "\fIx\fP", rather than double-quote, to be the open quote character,
|
||||
which is used if the \-e- option is specified.
|
||||
which is used if the \-e\- option is specified.
|
||||
.TP
|
||||
.B \-c\fIx\fP
|
||||
Specifies "\fIx\fP" to be the close quote character.
|
||||
@@ -53,4 +77,7 @@ The default is that only arguments containing metacharacters are quoted.
|
||||
This manual page was written by Thomas Schoepf <[email protected]>,
|
||||
for the Debian GNU/Linux system (but may be used by others).
|
||||
.PP
|
||||
Report bugs at https://github.com/gwsw/less/issues.
|
||||
Report bugs at
|
||||
.nh
|
||||
https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues.
|
||||
.hy
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+246
-144
@@ -1,12 +1,31 @@
|
||||
'\" t
|
||||
.TH LESSKEY 1 "Version 685: 04 Oct 2025"
|
||||
.TH LESSKEY 1 "30 May 2026" "less 704"
|
||||
.\" Define a string for the caret ("hat") as portably as possible.
|
||||
.ie \n(.g .ds ^ \(ha
|
||||
.el .ds ^ ^
|
||||
.\" Define a string for the neutral apostrophe as portably as possible.
|
||||
.ie \n(.g .ds ' \(aq
|
||||
.el .ds ' '
|
||||
.\" Define a string to interpolate the hyphenless break point escape
|
||||
.\" sequence (for URLs and similar) if the formatter claims groff
|
||||
.\" compatibility, else interpolate nothing.
|
||||
.ie \n(.g .ds : \:
|
||||
.el .ds : \" empty
|
||||
.SH NAME
|
||||
lesskey \- customize key bindings for less
|
||||
.SH "SYNOPSIS (deprecated)"
|
||||
.B "lesskey [\-o output] [\-\-] [input]"
|
||||
.br
|
||||
.B "lesskey [\-\-output=output] [\-\-] [input]"
|
||||
.B lesskey
|
||||
.RB [ \-o
|
||||
.IR output ]
|
||||
.B \-\-
|
||||
.I input
|
||||
.br
|
||||
.B lesskey
|
||||
.RB [ \-\-output=\c
|
||||
.IR output ]
|
||||
.B \-\-
|
||||
.I input
|
||||
.PP
|
||||
.B "lesskey \-V"
|
||||
.br
|
||||
.B "lesskey \-\-version"
|
||||
@@ -43,7 +62,7 @@ Each section starts with a line that identifies the type of section.
|
||||
Possible sections are:
|
||||
.IP #command
|
||||
Customizes command key bindings.
|
||||
.IP #line-edit
|
||||
.IP #line\-edit
|
||||
Customizes line-editing key bindings.
|
||||
.IP #env
|
||||
Defines environment variables.
|
||||
@@ -54,15 +73,15 @@ except as noted below.
|
||||
.
|
||||
.SH "COMMAND SECTION"
|
||||
The command section begins with the line
|
||||
.sp
|
||||
.PP
|
||||
#command
|
||||
.sp
|
||||
.PP
|
||||
If the command section is the first section in the file,
|
||||
this line may be omitted.
|
||||
The command section consists of lines of the form:
|
||||
.sp
|
||||
.PP
|
||||
\fIstring\fP <whitespace> \fIaction\fP <whitespace> [extra-string] <newline>
|
||||
.sp
|
||||
.PP
|
||||
Whitespace is any sequence of one or more spaces and/or tabs.
|
||||
The \fIstring\fP is the command key(s) which invoke the action.
|
||||
The \fIstring\fP may be a single command key, or a sequence of up to 15 keys.
|
||||
@@ -84,28 +103,52 @@ l l l.
|
||||
\et TAB (0x09)
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
\ek followed by a single character represents the char(s) produced when one of these keys is pressed:
|
||||
.PP
|
||||
\ek followed by one or two characters represents the char(s) produced
|
||||
when one of these keys is pressed:
|
||||
.RS 5m
|
||||
.TS
|
||||
l l.
|
||||
\ekb BACKSPACE (the BACKSPACE key)
|
||||
\ekb BACKSPACE (the BACKSPACE key; may be different than \eb)
|
||||
\ekB ctrl-BACKSPACE
|
||||
\ekd DOWN ARROW
|
||||
\ekD PAGE DOWN
|
||||
\eke END
|
||||
\ekE ctrl-END
|
||||
\ekF shift-END
|
||||
\ekh HOME
|
||||
\ekH ctrl-HOME
|
||||
\ekI shift-HOME
|
||||
\eki INSERT
|
||||
\ekl LEFT ARROW
|
||||
\ekL ctrl-LEFT ARROW
|
||||
\ekM shift-LEFT ARROW
|
||||
\ekr RIGHT ARROW
|
||||
\ekR ctrl-RIGHT ARROW
|
||||
\ekS shift-RIGHT ARROW
|
||||
\ekt BACKTAB
|
||||
\eku UP ARROW
|
||||
\ekU PAGE UP
|
||||
\ekx DELETE
|
||||
\ekX ctrl-DELETE
|
||||
\ek1 F1
|
||||
\ekp1 lower left key on the numeric keypad
|
||||
\ekp2 lower center key on the numeric keypad
|
||||
\ekp3 lower right key on the numeric keypad
|
||||
\ekp4 center left key on the numeric keypad
|
||||
\ekp5 center key on the numeric keypad
|
||||
\ekp6 center right key on the numeric keypad
|
||||
\ekp7 upper left key on the numeric keypad
|
||||
\ekp8 upper center key on the numeric keypad
|
||||
\ekp9 upper right key on the numeric keypad
|
||||
\ekp0 0 on the numeric keypad
|
||||
\ekp* * on the numeric keypad
|
||||
\ekp/ / on the numeric keypad
|
||||
\ekp\- \- on the numeric keypad
|
||||
\ekp+ + on the numeric keypad
|
||||
\ekp. . on the numeric keypad
|
||||
\ekp, , on the numeric keypad
|
||||
\ekpe ENTER on the numeric keypad
|
||||
.TE
|
||||
.RE
|
||||
.PP
|
||||
@@ -126,11 +169,13 @@ For example, see the "{" and ":t" commands in the example below.
|
||||
It can also be used to execute more than one command when a key is pressed.
|
||||
For example, if this line were in a lesskey file, pressing the "B" key
|
||||
would first set the "b" mark and then search for the string "next":
|
||||
.sp
|
||||
.PP
|
||||
.EX
|
||||
.nf
|
||||
B set-mark b/next\en
|
||||
B set\-mark b/next\en
|
||||
.fi
|
||||
.sp
|
||||
.EE
|
||||
.PP
|
||||
The extra string has a special meaning for the "quit" action:
|
||||
when
|
||||
.B less
|
||||
@@ -144,116 +189,130 @@ default command keys used by
|
||||
Documentation on each command can be found in the
|
||||
.B less
|
||||
man page, under the key sequence which invokes the command.
|
||||
.sp
|
||||
.PP
|
||||
.RS 5m
|
||||
.TS
|
||||
l l.
|
||||
#command
|
||||
\er forw-line
|
||||
\en forw-line
|
||||
e forw-line
|
||||
j forw-line
|
||||
\ekd forw-line
|
||||
^E forw-line
|
||||
^N forw-line
|
||||
k back-line
|
||||
y back-line
|
||||
^Y back-line
|
||||
^K back-line
|
||||
^P back-line
|
||||
J forw-line-force
|
||||
K back-line-force
|
||||
Y back-line-force
|
||||
\eej forw-newline
|
||||
\eek back-newline
|
||||
d forw-scroll
|
||||
^D forw-scroll
|
||||
u back-scroll
|
||||
^U back-scroll
|
||||
\e40 forw-screen
|
||||
f forw-screen
|
||||
^F forw-screen
|
||||
^V forw-screen
|
||||
\ekD forw-screen
|
||||
b back-screen
|
||||
^B back-screen
|
||||
\eev back-screen
|
||||
\ekU back-screen
|
||||
z forw-window
|
||||
w back-window
|
||||
\ee\e40 forw-screen-force
|
||||
\eeb back-screen-force
|
||||
F forw-forever
|
||||
\eeF forw-until-hilite
|
||||
R repaint-flush
|
||||
\er forw\-line
|
||||
\en forw\-line
|
||||
e forw\-line
|
||||
j forw\-line
|
||||
\ekd forw\-line
|
||||
\*^E forw\-line
|
||||
\*^N forw\-line
|
||||
k back\-line
|
||||
y back\-line
|
||||
\*^Y back\-line
|
||||
\*^K back\-line
|
||||
\*^P back\-line
|
||||
\eku back\-line
|
||||
J forw\-line\-force
|
||||
K back\-line\-force
|
||||
Y back\-line\-force
|
||||
d forw\-scroll
|
||||
\*^D forw\-scroll
|
||||
u back\-scroll
|
||||
\*^U back\-scroll
|
||||
\e40 forw\-screen
|
||||
f forw\-screen
|
||||
\*^F forw\-screen
|
||||
\*^V forw\-screen
|
||||
\ekD forw\-screen
|
||||
b back\-screen
|
||||
\*^B back\-screen
|
||||
\eev back\-screen
|
||||
\ekU back\-screen
|
||||
z forw\-window
|
||||
w back\-window
|
||||
\ee\e40 forw\-screen\-force
|
||||
\eeb back\-screen\-force
|
||||
\eej forw\-newline
|
||||
\eek back\-newline
|
||||
F forw\-forever
|
||||
\eeF forw\-until\-hilite
|
||||
\eef forw\-bell\-hilite
|
||||
R repaint\-flush
|
||||
r repaint
|
||||
^R repaint
|
||||
^L repaint
|
||||
\eeu undo-hilite
|
||||
\eeU clear-search
|
||||
g goto-line
|
||||
\ekh goto-line
|
||||
< goto-line
|
||||
\ee< goto-line
|
||||
\*^R repaint
|
||||
\*^L repaint
|
||||
\eeu undo\-hilite
|
||||
\eeU clear\-search
|
||||
g goto\-line
|
||||
\ekh goto\-line
|
||||
\ekH goto\-line \ee{
|
||||
\ekI goto\-line \ee{
|
||||
\eke goto\-end
|
||||
\ekE goto\-end \ee}
|
||||
\ekF goto\-end \ee}
|
||||
< goto\-line
|
||||
\ee< goto\-line
|
||||
p percent
|
||||
% percent
|
||||
\ee( left-scroll
|
||||
\ee) right-scroll
|
||||
\ekl left-scroll
|
||||
\ekr right-scroll
|
||||
\ee{ no-scroll
|
||||
\ee} end-scroll
|
||||
{ forw-bracket {}
|
||||
} back-bracket {}
|
||||
( forw-bracket ()
|
||||
) back-bracket ()
|
||||
[ forw-bracket []
|
||||
] back-bracket []
|
||||
\ee^F forw-bracket
|
||||
\ee^B back-bracket
|
||||
G goto-end
|
||||
\ee> goto-end
|
||||
> goto-end
|
||||
\eke goto-end
|
||||
\eeG goto-end-buffered
|
||||
\ee( left\-scroll
|
||||
\ee) right\-scroll
|
||||
\ee{ no\-scroll
|
||||
\ee} end\-scroll
|
||||
\ekl left\-scroll
|
||||
\ekr right\-scroll
|
||||
\ekL no\-scroll
|
||||
\ekM no\-scroll
|
||||
\ekR end\-scroll
|
||||
\ekS end\-scroll
|
||||
{ forw\-bracket {}
|
||||
} back\-bracket {}
|
||||
( forw\-bracket ()
|
||||
) back\-bracket ()
|
||||
[ forw\-bracket []
|
||||
] back\-bracket []
|
||||
\ee\*^F forw\-bracket
|
||||
\ee\*^B back\-bracket
|
||||
G goto\-end
|
||||
\ee> goto\-end
|
||||
> goto\-end
|
||||
P goto\-pos
|
||||
\eeG goto\-end\-buffered
|
||||
\&= status
|
||||
^G status
|
||||
\*^G status
|
||||
:f status
|
||||
/ forw-search
|
||||
? back-search
|
||||
\ee/ forw-search *
|
||||
\ee? back-search *
|
||||
n repeat-search
|
||||
\een repeat-search-all
|
||||
N reverse-search
|
||||
\eeN reverse-search-all
|
||||
^O^N osc8-forw-search
|
||||
^On osc8-forw-search
|
||||
^O^P osc8-back-search
|
||||
^Op osc8-back-search
|
||||
^O^O osc8-open
|
||||
/ forw\-search
|
||||
? back\-search
|
||||
\ee/ forw\-search *
|
||||
\ee? back\-search *
|
||||
n repeat\-search
|
||||
\een repeat\-search\-all
|
||||
N reverse\-search
|
||||
\eeN reverse\-search\-all
|
||||
& filter
|
||||
m set-mark
|
||||
M set-mark-bottom
|
||||
\eem clear-mark
|
||||
\&' goto-mark
|
||||
^X^X goto-mark
|
||||
m set\-mark
|
||||
M set\-mark\-bottom
|
||||
\eem clear\-mark
|
||||
\&\*' goto\-mark
|
||||
\*^X\*^X goto\-mark
|
||||
E examine
|
||||
:e examine
|
||||
^X^V examine
|
||||
:n next-file
|
||||
:p prev-file
|
||||
t next-tag
|
||||
T prev-tag
|
||||
:x index-file
|
||||
:d remove-file
|
||||
- toggle-option
|
||||
:t toggle-option t
|
||||
s toggle-option o
|
||||
\*^X\*^V examine
|
||||
:n next\-file
|
||||
:p prev\-file
|
||||
\*^O\*^N osc8\-forw\-search
|
||||
\*^On osc8\-forw\-search
|
||||
\*^O\*^P osc8\-back\-search
|
||||
\*^Op osc8\-back\-search
|
||||
\*^O\*^O osc8\-open
|
||||
\*^Oo osc8\-open
|
||||
\*^O\*^L osc8\-jump
|
||||
\*^Ol osc8\-jump
|
||||
t next\-tag
|
||||
T prev\-tag
|
||||
:x index\-file
|
||||
:d remove\-file
|
||||
\- toggle\-option
|
||||
:t toggle\-option t
|
||||
s toggle\-option o
|
||||
## Use a long option name by starting the
|
||||
## extra string with ONE dash; eg:
|
||||
## s toggle-option -log-file\en
|
||||
\&_ display-option
|
||||
## s toggle\-option \-log\-file\en
|
||||
\&_ display\-option
|
||||
| pipe
|
||||
v visual
|
||||
! shell
|
||||
@@ -261,8 +320,24 @@ v visual
|
||||
+ firstcmd
|
||||
\ee[M mouse
|
||||
\ee[< mouse6
|
||||
\ekp1 goto\-end
|
||||
\ekp2 forw\-line
|
||||
\ekp3 forw\-screen
|
||||
\ekp4 left\-scroll
|
||||
\ekp6 right\-scroll
|
||||
\ekp7 goto\-line
|
||||
\ekp8 back\-line
|
||||
\ekp9 back\-screen
|
||||
\ekp0 noaction 0
|
||||
\ekp* noaction *
|
||||
\ekp/ noaction /
|
||||
\ekp\- noaction \-
|
||||
\ekp+ noaction +
|
||||
\ekp. noaction .
|
||||
\ekp, noaction ,
|
||||
H help
|
||||
h help
|
||||
\ek1 help
|
||||
V version
|
||||
0 digit
|
||||
1 digit
|
||||
@@ -281,7 +356,6 @@ Q quit
|
||||
ZZ quit
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
.SH PRECEDENCE
|
||||
Commands specified by
|
||||
.B lesskey
|
||||
@@ -296,9 +370,9 @@ will give an error beep for an "invalid" command,
|
||||
but not for a "noaction" command.
|
||||
In addition, ALL default commands may be disabled by
|
||||
adding this control line to the input file:
|
||||
.sp
|
||||
.PP
|
||||
#stop
|
||||
.sp
|
||||
.PP
|
||||
This will cause all default commands to be ignored.
|
||||
The #stop line should be the last line in that section of the file.
|
||||
.PP
|
||||
@@ -310,9 +384,11 @@ For example, failure to provide a "quit" command can lead to frustration.
|
||||
.
|
||||
.SH "LINE EDITING SECTION"
|
||||
The line-editing section begins with the line:
|
||||
.sp
|
||||
#line-edit
|
||||
.sp
|
||||
.PP
|
||||
.EX
|
||||
#line\-edit
|
||||
.EE
|
||||
.PP
|
||||
This section specifies new key bindings for the line editing commands,
|
||||
in a manner similar to the way key bindings for
|
||||
ordinary commands are specified in the #command section.
|
||||
@@ -323,14 +399,15 @@ one per line as in the example below.
|
||||
The following input file describes the set of
|
||||
default line-editing keys used by
|
||||
.BR less :
|
||||
.sp
|
||||
.PP
|
||||
.RS 5m
|
||||
.TS
|
||||
l l.
|
||||
#line-edit
|
||||
\et forw-complete
|
||||
\e17 back-complete
|
||||
\ee\et back-complete
|
||||
#line\-edit
|
||||
\et forw\-complete
|
||||
\e17 back\-complete
|
||||
\eekt back\-complete
|
||||
\ee\et back\-complete
|
||||
^L expand
|
||||
^V literal
|
||||
^A literal
|
||||
@@ -338,16 +415,21 @@ l l.
|
||||
\ekr right
|
||||
\eeh left
|
||||
\ekl left
|
||||
\eeb word-left
|
||||
\ee\ekl word-left
|
||||
\eew word-right
|
||||
\ee\ekr word-right
|
||||
\eeb word\-left
|
||||
\ee\ekl word\-left
|
||||
\ee\ekL word\-left
|
||||
\eew word\-right
|
||||
\ee\ekr word\-right
|
||||
\ee\ekR word\-right
|
||||
\eei insert
|
||||
\eki insert
|
||||
\eex delete
|
||||
\ekx delete
|
||||
\eeX word-delete
|
||||
\eekx word-delete
|
||||
\ee\eb word-backspace
|
||||
\eeX word\-delete
|
||||
\eekx word\-delete
|
||||
\ekX word\-delete
|
||||
\ee\eb word\-backspace
|
||||
\ekB word\-backspace
|
||||
\ee0 home
|
||||
\ekh home
|
||||
\ee$ end
|
||||
@@ -355,18 +437,31 @@ l l.
|
||||
\eek up
|
||||
\eku up
|
||||
\eej down
|
||||
\ekd down
|
||||
^G abort
|
||||
\ekp1 end
|
||||
\ekp2 down
|
||||
\ekp4 left
|
||||
\ekp6 right
|
||||
\ekp7 home
|
||||
\ekp8 up
|
||||
\ekp0 noaction 0
|
||||
\ekp* noaction *
|
||||
\ekp/ noaction /
|
||||
\ekp\- noaction \-
|
||||
\ekp+ noaction +
|
||||
\ekp. noaction .
|
||||
\ekp, noaction ,
|
||||
\ee[M mouse
|
||||
\ee[< mouse6
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
.
|
||||
.SH "LESS ENVIRONMENT VARIABLES"
|
||||
The environment variable section begins with the line
|
||||
.sp
|
||||
.PP
|
||||
#env
|
||||
.sp
|
||||
.PP
|
||||
Following this line is a list of environment variable assignments.
|
||||
Each line consists of an environment variable name, an equals sign (=)
|
||||
and the value to be assigned to the environment variable.
|
||||
@@ -376,7 +471,7 @@ Variables assigned in this way are visible only to
|
||||
If a variable is specified in the system environment and also in a
|
||||
lesskey file, the value in the lesskey file takes precedence.
|
||||
.
|
||||
.sp
|
||||
.PP
|
||||
If the variable name is followed by += rather than =,
|
||||
the string is appended to the variable's existing value.
|
||||
This currently works only if any += lines immediately follow
|
||||
@@ -390,7 +485,7 @@ it should be appended to the end of the preceding line.
|
||||
(It cannot be added to the beginning of the += string because space after
|
||||
the equals sign is ignored, as noted above.)
|
||||
.
|
||||
.sp
|
||||
.PP
|
||||
In the string after the = sign, a substring of the form ${NAME}
|
||||
is replaced with the value of the environment variable "NAME".
|
||||
The value of the variable may come from either the system environment,
|
||||
@@ -417,18 +512,20 @@ the remainder of the line is parsed if and only if the running version of
|
||||
matches the operator.
|
||||
This can be helpful if a lesskey file is used by different versions of
|
||||
.BR less .
|
||||
.sp
|
||||
For example, suppose that a new command named 'sideways-search' is added in
|
||||
.PP
|
||||
For example, suppose that a new command named 'sideways\-search' is added in
|
||||
.B less
|
||||
version 777.
|
||||
Then the following line would assign the command to the Q key, but only in versions of
|
||||
.B less
|
||||
which support it. The line would be ignored by versions earlier than 777.
|
||||
.sp
|
||||
.PP
|
||||
.EX
|
||||
.nf
|
||||
#version >= 777 Q sideways-search
|
||||
#version >= 777 Q sideways\-search
|
||||
.fi
|
||||
.sp
|
||||
.EE
|
||||
.PP
|
||||
These six operators are supported:
|
||||
.RS 5m
|
||||
.TS
|
||||
@@ -441,7 +538,7 @@ l l.
|
||||
!= Not equal to
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
.PP
|
||||
The #version feature is not supported in
|
||||
.B less
|
||||
and
|
||||
@@ -453,14 +550,16 @@ In those older versions, all #version lines are ignored.
|
||||
The following input file sets the \-i and \-S options when
|
||||
.B less
|
||||
is run and, on version 595 and higher, adds a \-\-color option.
|
||||
.sp
|
||||
.PP
|
||||
.EX
|
||||
.nf
|
||||
#env
|
||||
## (Note that there must be a space at the end of the next line,
|
||||
## to separate the --color option from the -S option.)
|
||||
## to separate the \-\-color option from the \-S option.)
|
||||
LESS = \-i\ \-S\
|
||||
#version\ >=\ 595\ \ LESS\ +=\ \-\-color=Hkc
|
||||
.fi
|
||||
.EE
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR less (1)
|
||||
@@ -471,7 +570,7 @@ which start with a NUL character (0).
|
||||
This NUL character should be represented as \e340 in a lesskey file.
|
||||
.
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 1984-2025 Mark Nudelman
|
||||
Copyright (C) 1984-2026 Mark Nudelman
|
||||
.PP
|
||||
less is part of the GNU project and is free software.
|
||||
You can redistribute it and/or modify it
|
||||
@@ -496,4 +595,7 @@ See the GNU General Public License for more details.
|
||||
.
|
||||
Mark Nudelman
|
||||
.br
|
||||
Report bugs at https://github.com/gwsw/less/issues.
|
||||
Report bugs at
|
||||
.nh
|
||||
https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues.
|
||||
.hy
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -53,6 +53,7 @@ static constant struct lesskey_cmdname cmdnames[] =
|
||||
{ "first-cmd", A_FIRSTCMD },
|
||||
{ "firstcmd", A_FIRSTCMD },
|
||||
{ "flush-repaint", A_FREPAINT },
|
||||
{ "forw-bell-hilite", A_F_FOREVER_BELL },
|
||||
{ "forw-bracket", A_F_BRACKET },
|
||||
{ "forw-forever", A_F_FOREVER },
|
||||
{ "forw-line", A_F_LINE },
|
||||
@@ -68,6 +69,7 @@ static constant struct lesskey_cmdname cmdnames[] =
|
||||
{ "goto-end-buffered", A_GOEND_BUF },
|
||||
{ "goto-line", A_GOLINE },
|
||||
{ "goto-mark", A_GOMARK },
|
||||
{ "goto-pos", A_GOPOS },
|
||||
{ "help", A_HELP },
|
||||
{ "index-file", A_INDEX_FILE },
|
||||
{ "invalid", A_UINVALID },
|
||||
@@ -80,6 +82,7 @@ static constant struct lesskey_cmdname cmdnames[] =
|
||||
{ "noaction", A_NOACTION },
|
||||
{ "osc8-forw-search", A_OSC8_F_SEARCH },
|
||||
{ "osc8-back-search", A_OSC8_B_SEARCH },
|
||||
{ "osc8-jump", A_OSC8_JUMP },
|
||||
{ "osc8-open", A_OSC8_OPEN },
|
||||
{ "percent", A_PERCENT },
|
||||
{ "pipe", A_PIPE },
|
||||
@@ -125,6 +128,7 @@ static constant struct lesskey_cmdname editnames[] =
|
||||
{ "literal", EC_LITERAL },
|
||||
{ "mouse", EC_X11MOUSE },
|
||||
{ "mouse6", EC_X116MOUSE },
|
||||
{ "noaction", A_NOACTION },
|
||||
{ "right", EC_RIGHT },
|
||||
{ "up", EC_UP },
|
||||
{ "word-backspace", EC_W_BACKSPACE },
|
||||
@@ -247,6 +251,7 @@ static constant char * tstr(char **pp, int xlate)
|
||||
case 'k':
|
||||
if (xlate)
|
||||
{
|
||||
ch = 0;
|
||||
switch (*++p)
|
||||
{
|
||||
case 'b': ch = SK_BACKSPACE; break;
|
||||
@@ -254,19 +259,49 @@ static constant char * tstr(char **pp, int xlate)
|
||||
case 'd': ch = SK_DOWN_ARROW; break;
|
||||
case 'D': ch = SK_PAGE_DOWN; break;
|
||||
case 'e': ch = SK_END; break;
|
||||
case 'E': ch = SK_CTL_END; break;
|
||||
case 'F': ch = SK_SHIFT_END; break;
|
||||
case 'h': ch = SK_HOME; break;
|
||||
case 'H': ch = SK_CTL_HOME; break;
|
||||
case 'I': ch = SK_SHIFT_HOME; break;
|
||||
case 'i': ch = SK_INSERT; break;
|
||||
case 'l': ch = SK_LEFT_ARROW; break;
|
||||
case 'L': ch = SK_CTL_LEFT_ARROW; break;
|
||||
case 'M': ch = SK_SHIFT_LEFT_ARROW; break;
|
||||
case 'r': ch = SK_RIGHT_ARROW; break;
|
||||
case 'R': ch = SK_CTL_RIGHT_ARROW; break;
|
||||
case 'S': ch = SK_SHIFT_RIGHT_ARROW; break;
|
||||
case 't': ch = SK_BACKTAB; break;
|
||||
case 'u': ch = SK_UP_ARROW; break;
|
||||
case 'U': ch = SK_PAGE_UP; break;
|
||||
case 'x': ch = SK_DELETE; break;
|
||||
case 'X': ch = SK_CTL_DELETE; break;
|
||||
case '1': ch = SK_F1; break;
|
||||
default:
|
||||
case 'p':
|
||||
switch (*++p)
|
||||
{
|
||||
case '1': ch = SK_PAD_DL; break;
|
||||
case '2': ch = SK_PAD_D; break;
|
||||
case '3': ch = SK_PAD_DR; break;
|
||||
case '4': ch = SK_PAD_L; break;
|
||||
case '5': ch = SK_PAD_CENTER; break;
|
||||
case '6': ch = SK_PAD_R; break;
|
||||
case '7': ch = SK_PAD_UL; break;
|
||||
case '8': ch = SK_PAD_U; break;
|
||||
case '9': ch = SK_PAD_UR; break;
|
||||
case '0': ch = SK_PAD_ZERO; break;
|
||||
case '*': ch = SK_PAD_STAR; break;
|
||||
case '/': ch = SK_PAD_SLASH; break;
|
||||
case '-': ch = SK_PAD_DASH; break;
|
||||
case '+': ch = SK_PAD_PLUS; break;
|
||||
case '.': ch = SK_PAD_DOT; break;
|
||||
case ',': ch = SK_PAD_COMMA; break;
|
||||
case 'e': ch = SK_PAD_ENTER; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ch == 0)
|
||||
{
|
||||
parse_error("invalid escape sequence \"\\k%s\"", char_string(buf, *p, 0));
|
||||
*pp = increment_pointer(p);
|
||||
return ("");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+70
-53
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -97,7 +97,7 @@ extern int twiddle;
|
||||
extern int status_col;
|
||||
extern int status_col_width;
|
||||
extern int linenum_width;
|
||||
extern int auto_wrap, ignaw;
|
||||
extern int auto_wrap, defer_wrap;
|
||||
extern int bo_s_width, bo_e_width;
|
||||
extern int ul_s_width, ul_e_width;
|
||||
extern int bl_s_width, bl_e_width;
|
||||
@@ -129,12 +129,14 @@ static struct color_map color_map[] = {
|
||||
{ AT_COLOR_BIN, "kR" },
|
||||
{ AT_COLOR_CTRL, "kR" },
|
||||
{ AT_COLOR_ERROR, "kY" },
|
||||
{ AT_COLOR_LINENUM, "c" },
|
||||
{ AT_COLOR_LINENUM, "c*" },
|
||||
{ AT_COLOR_MARK, "Wb" },
|
||||
{ AT_COLOR_PROMPT, "kC" },
|
||||
{ AT_COLOR_RSCROLL, "kc" },
|
||||
{ AT_COLOR_HEADER, "" },
|
||||
{ AT_COLOR_SEARCH, "kG" },
|
||||
{ AT_COLOR_TILDE, "-d" },
|
||||
{ AT_COLOR_TARGET, "-u" },
|
||||
{ AT_COLOR_SUBSEARCH(1), "ky" },
|
||||
{ AT_COLOR_SUBSEARCH(2), "wb" },
|
||||
{ AT_COLOR_SUBSEARCH(3), "YM" },
|
||||
@@ -185,7 +187,7 @@ public void init_line(void)
|
||||
s = skipspc(s);
|
||||
if (*s == ',')
|
||||
++s;
|
||||
xbuf_add_data(&xbuf, (constant void *) &num, sizeof(num));
|
||||
xbuf_add_data(&xbuf, &num, sizeof(num));
|
||||
++osc_ansi_allow_count;
|
||||
}
|
||||
osc_ansi_allow = (long *) xbuf.data;
|
||||
@@ -436,7 +438,7 @@ public void plinestart(POSITION pos)
|
||||
for (i = 0; i + len < (size_t) linenum_width; i++)
|
||||
add_pfx(' ', AT_NORMAL);
|
||||
for (i = 0; i < len; i++)
|
||||
add_pfx(buf[i], AT_BOLD|AT_COLOR_LINENUM);
|
||||
add_pfx(buf[i], use_color ? AT_COLOR_LINENUM : AT_BOLD);
|
||||
add_pfx(' ', AT_NORMAL);
|
||||
}
|
||||
end_column = (int) linebuf.pfx_end; /*{{type-issue}}*/
|
||||
@@ -446,7 +448,7 @@ public void plinestart(POSITION pos)
|
||||
* Return the width of the line prefix (status column and line number).
|
||||
* {{ Actual line number can be wider than linenum_width. }}
|
||||
*/
|
||||
public int line_pfx_width(void)
|
||||
public unsigned line_pfx_width(void)
|
||||
{
|
||||
int width = 0;
|
||||
if (status_col)
|
||||
@@ -1077,7 +1079,7 @@ static int flush_mbc_buf(POSITION pos)
|
||||
*/
|
||||
public int pappend_b(char c, POSITION pos, lbool before_pendc)
|
||||
{
|
||||
LWCHAR ch = c & 0377;
|
||||
LWCHAR ch = (unsigned char) c;
|
||||
int r;
|
||||
|
||||
if (pendc && !before_pendc)
|
||||
@@ -1192,6 +1194,22 @@ static int store_control_char(LWCHAR ch, constant char *rep, POSITION pos)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove invalid ANSI sequence.
|
||||
*/
|
||||
static void remove_ansi(void)
|
||||
{
|
||||
constant char *start = (cshift < hshift) ? xbuf_char_data(&shifted_ansi): linebuf.buf;
|
||||
size_t *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
|
||||
constant char *p = start + *end;
|
||||
LWCHAR bch;
|
||||
do {
|
||||
bch = step_charc(&p, -1, start);
|
||||
} while (p > start && (!IS_CSI_START(bch) || line_ansi->escs_in_seq-- > 0));
|
||||
*end = ptr_diff(p, start);
|
||||
xbuf_reset(&last_ansi);
|
||||
}
|
||||
|
||||
static int store_ansi(LWCHAR ch, constant char *rep, POSITION pos)
|
||||
{
|
||||
switch (ansi_step2(line_ansi, ch, pos != NULL_POSITION))
|
||||
@@ -1215,18 +1233,7 @@ static int store_ansi(LWCHAR ch, constant char *rep, POSITION pos)
|
||||
curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS;
|
||||
break;
|
||||
case ANSI_ERR:
|
||||
{
|
||||
/* Remove whole unrecognized sequence. */
|
||||
constant char *start = (cshift < hshift) ? xbuf_char_data(&shifted_ansi): linebuf.buf;
|
||||
size_t *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
|
||||
constant char *p = start + *end;
|
||||
LWCHAR bch;
|
||||
do {
|
||||
bch = step_charc(&p, -1, start);
|
||||
} while (p > start && (!IS_CSI_START(bch) || line_ansi->escs_in_seq-- > 0));
|
||||
*end = ptr_diff(p, start);
|
||||
}
|
||||
xbuf_reset(&last_ansi);
|
||||
remove_ansi();
|
||||
ansi_done(line_ansi);
|
||||
line_ansi = NULL;
|
||||
break;
|
||||
@@ -1388,13 +1395,12 @@ static void add_attr_normal(void)
|
||||
{
|
||||
switch (line_ansi->ostate)
|
||||
{
|
||||
case OSC_TYPENUM:
|
||||
case OSC8_PARAMS:
|
||||
case OSC8_URI:
|
||||
case OSC_STRING:
|
||||
addstr_linebuf("\033\\", AT_ANSI, 0);
|
||||
case OSC_START:
|
||||
case OSC_END:
|
||||
break;
|
||||
default:
|
||||
/* We're in an unterminated OSC sequence; remove it. */
|
||||
remove_ansi();
|
||||
break;
|
||||
}
|
||||
ansi_done(line_ansi);
|
||||
@@ -1410,7 +1416,7 @@ static void add_attr_normal(void)
|
||||
/*
|
||||
* Terminate the line in the line buffer.
|
||||
*/
|
||||
public void pdone(lbool endline, lbool chopped, lbool forw)
|
||||
public void pdone(lbool endline, lbool chopped, lbool forw, lbool full_pad)
|
||||
{
|
||||
(void) pflushmbc();
|
||||
linebuf.prev_end = (!endline && !chopped) ? linebuf.end : 0;
|
||||
@@ -1462,8 +1468,8 @@ public void pdone(lbool endline, lbool chopped, lbool forw)
|
||||
/*
|
||||
* If we're coloring a status line, fill out the line with spaces.
|
||||
*/
|
||||
if (status_line && line_mark_attr != 0) {
|
||||
while (end_column +1 < sc_width + cshift)
|
||||
if (status_line && (line_mark_attr != 0 || full_pad)) {
|
||||
while (end_column < sc_width + cshift)
|
||||
add_linebuf(' ', line_mark_attr, 1);
|
||||
}
|
||||
|
||||
@@ -1480,14 +1486,14 @@ public void pdone(lbool endline, lbool chopped, lbool forw)
|
||||
* the next line is blank. In that case the single newline output for
|
||||
* that blank line would be ignored!)
|
||||
*/
|
||||
if (end_column < sc_width + cshift || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON)
|
||||
if (end_column < sc_width + cshift || !auto_wrap || (endline && defer_wrap) || ctldisp == OPT_ON)
|
||||
{
|
||||
add_linebuf('\n', AT_NORMAL, 0);
|
||||
}
|
||||
else if (ignaw && end_column >= sc_width + cshift && forw)
|
||||
else if (defer_wrap && end_column >= sc_width + cshift && forw)
|
||||
{
|
||||
/*
|
||||
* Terminals with "ignaw" don't wrap until they *really* need
|
||||
* Terminals with "defer_wrap" don't wrap until they *really* need
|
||||
* to, i.e. when the character *after* the last one to fit on a
|
||||
* line is output. But they are too hard to deal with when they
|
||||
* get in the state where a full screen width of characters
|
||||
@@ -1509,7 +1515,7 @@ public void pdone(lbool endline, lbool chopped, lbool forw)
|
||||
* colored with the last char's background color before the color
|
||||
* reset sequence is sent. Clear the line to reset the background color.
|
||||
*/
|
||||
if (auto_wrap && !ignaw && end_column >= sc_width + cshift)
|
||||
if (auto_wrap && !defer_wrap && end_column >= sc_width + cshift)
|
||||
clear_after_line = TRUE;
|
||||
set_linebuf(linebuf.end, '\0', AT_NORMAL);
|
||||
}
|
||||
@@ -1664,7 +1670,7 @@ public int gline(size_t i, int *ap)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
*ap = AT_BOLD;
|
||||
*ap = use_color ? AT_COLOR_TILDE : AT_BOLD;
|
||||
return '~';
|
||||
}
|
||||
--i;
|
||||
@@ -1681,7 +1687,7 @@ public int gline(size_t i, int *ap)
|
||||
}
|
||||
i += linebuf.print - linebuf.pfx_end;
|
||||
*ap = linebuf.attr[i];
|
||||
return (linebuf.buf[i] & 0xFF);
|
||||
return (unsigned char) linebuf.buf[i];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1878,10 +1884,10 @@ static int pappstr(constant char *str)
|
||||
|
||||
/*
|
||||
* Load a string into the line buffer.
|
||||
* If the string is too long to fit on the screen,
|
||||
* If the string is too long to fit on the screen (minus reserve chars),
|
||||
* truncate the beginning of the string to fit.
|
||||
*/
|
||||
public void load_line(constant char *str)
|
||||
public void load_line(constant char *str, int attr, int reserve)
|
||||
{
|
||||
int save_hshift = hshift;
|
||||
hshift = 0;
|
||||
@@ -1889,6 +1895,7 @@ public void load_line(constant char *str)
|
||||
/* We're overwriting the line buffer, so what's in it will no longer be contiguous. */
|
||||
set_line_contig_pos(NULL_POSITION);
|
||||
|
||||
sc_width -= reserve;
|
||||
for (;;)
|
||||
{
|
||||
prewind(FALSE);
|
||||
@@ -1903,39 +1910,49 @@ public void load_line(constant char *str)
|
||||
}
|
||||
set_linebuf(linebuf.end, '\0', AT_NORMAL);
|
||||
linebuf.prev_end = 0;
|
||||
sc_width += reserve;
|
||||
|
||||
/* Color the prompt unless it has ansi sequences in it. */
|
||||
if (!ansi_in_line)
|
||||
{
|
||||
size_t i;
|
||||
for (i = linebuf.print; i < linebuf.end; i++)
|
||||
set_linebuf(i, linebuf.buf[i], AT_STANDOUT|AT_COLOR_PROMPT);
|
||||
set_linebuf(i, linebuf.buf[i], attr);
|
||||
}
|
||||
hshift = save_hshift;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the length of the longest displayed line on the screen.
|
||||
*/
|
||||
public int longest_line_width(void)
|
||||
{
|
||||
POSITION pos;
|
||||
int save_width;
|
||||
int sindex;
|
||||
int longest = 0;
|
||||
|
||||
save_width = sc_width;
|
||||
sc_width = INT_MAX; /* so forw_line() won't chop */
|
||||
for (sindex = TOP; sindex < sc_height-1; sindex++)
|
||||
if ((pos = position(sindex)) != NULL_POSITION)
|
||||
break;
|
||||
for (; sindex < sc_height-1 && pos != NULL_POSITION; sindex++)
|
||||
{
|
||||
pos = forw_line(pos, NULL, NULL);
|
||||
if (end_column > longest)
|
||||
longest = end_column;
|
||||
}
|
||||
sc_width = save_width;
|
||||
return longest;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the shift necessary to show the end of the longest displayed line.
|
||||
*/
|
||||
public int rrshift(void)
|
||||
{
|
||||
POSITION pos;
|
||||
int save_width;
|
||||
int sline;
|
||||
int longest = 0;
|
||||
|
||||
save_width = sc_width;
|
||||
sc_width = INT_MAX; /* so forw_line() won't chop */
|
||||
for (sline = TOP; sline < sc_height; sline++)
|
||||
if ((pos = position(sline)) != NULL_POSITION)
|
||||
break;
|
||||
for (; sline < sc_height && pos != NULL_POSITION; sline++)
|
||||
{
|
||||
pos = forw_line(pos, NULL, NULL);
|
||||
if (end_column > longest)
|
||||
longest = end_column;
|
||||
}
|
||||
sc_width = save_width;
|
||||
int longest = longest_line_width();
|
||||
if (longest < sc_width)
|
||||
return 0;
|
||||
return longest - sc_width;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+12
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int sigs;
|
||||
extern IFILE curr_ifile;
|
||||
|
||||
|
||||
@@ -92,7 +93,7 @@ public void lsystem(constant char *cmd, constant char *donemsg)
|
||||
/*
|
||||
* De-initialize the terminal and take out of raw mode.
|
||||
*/
|
||||
deinit();
|
||||
term_deinit();
|
||||
flush(); /* Make sure the deinit chars get out */
|
||||
raw_mode(0);
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
@@ -135,9 +136,10 @@ public void lsystem(constant char *cmd, constant char *donemsg)
|
||||
char *esccmd = shell_quote(cmd);
|
||||
if (esccmd != NULL)
|
||||
{
|
||||
size_t len = strlen(shell) + strlen(esccmd) + 5;
|
||||
constant char *copt = shell_coption();
|
||||
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
|
||||
p = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF3(p, len, "%s %s %s", shell, shell_coption(), esccmd);
|
||||
SNPRINTF3(p, len, "%s %s %s", shell, copt, esccmd);
|
||||
free(esccmd);
|
||||
}
|
||||
}
|
||||
@@ -191,7 +193,7 @@ public void lsystem(constant char *cmd, constant char *donemsg)
|
||||
putchr('\n');
|
||||
flush();
|
||||
}
|
||||
init();
|
||||
term_init();
|
||||
screen_trashed();
|
||||
|
||||
#if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C
|
||||
@@ -220,15 +222,13 @@ public void lsystem(constant char *cmd, constant char *donemsg)
|
||||
*/
|
||||
reedit_ifile(save_ifile);
|
||||
|
||||
#if defined(SIGWINCH) || defined(SIGWIND)
|
||||
/*
|
||||
* Since we were ignoring window change signals while we executed
|
||||
* the system command, we must assume the window changed.
|
||||
* Warning: this leaves a signal pending (in "sigs"),
|
||||
* so psignals() should be called soon after lsystem().
|
||||
*/
|
||||
winch(0);
|
||||
#endif
|
||||
sigs |= S_WINCH;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -266,7 +266,7 @@ public int pipe_mark(char c, constant char *cmd)
|
||||
|
||||
if (c == '.')
|
||||
return (pipe_data(cmd, tpos, bpos));
|
||||
else if (mpos <= tpos)
|
||||
else if (mpos < tpos)
|
||||
return (pipe_data(cmd, mpos, bpos));
|
||||
else if (bpos == NULL_POSITION)
|
||||
return (pipe_data(cmd, tpos, bpos));
|
||||
@@ -305,7 +305,7 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
|
||||
putstr(cmd);
|
||||
putstr("\n");
|
||||
|
||||
deinit();
|
||||
term_deinit();
|
||||
flush();
|
||||
raw_mode(0);
|
||||
init_signals(0);
|
||||
@@ -351,11 +351,11 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
|
||||
#endif
|
||||
init_signals(1);
|
||||
raw_mode(1);
|
||||
init();
|
||||
term_init();
|
||||
screen_trashed();
|
||||
#if defined(SIGWINCH) || defined(SIGWIND)
|
||||
/* {{ Probably don't need this here. }} */
|
||||
winch(0);
|
||||
lwinch(0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
+36
-76
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -29,7 +29,7 @@ public unsigned less_acp = CP_ACP;
|
||||
|
||||
public char * every_first_cmd = NULL;
|
||||
public lbool new_file;
|
||||
public int is_tty;
|
||||
public lbool is_tty;
|
||||
public IFILE curr_ifile = NULL_IFILE;
|
||||
public IFILE old_ifile = NULL_IFILE;
|
||||
public struct scrpos initial_scrpos;
|
||||
@@ -38,8 +38,9 @@ public POSITION end_attnpos = NULL_POSITION;
|
||||
public int wscroll;
|
||||
public constant char *progname;
|
||||
public lbool quitting = FALSE;
|
||||
public int dohelp;
|
||||
public lbool dohelp = FALSE;
|
||||
public char * init_header = NULL;
|
||||
public char * no_config = NULL;
|
||||
static int secure_allow_features;
|
||||
|
||||
#if LOGFILE
|
||||
@@ -67,7 +68,7 @@ public time_type less_start_time;
|
||||
static wchar_t consoleTitle[256];
|
||||
#endif
|
||||
|
||||
public int one_screen;
|
||||
public lbool one_screen;
|
||||
extern int less_is_more;
|
||||
extern lbool missing_cap;
|
||||
extern int know_dumb;
|
||||
@@ -75,8 +76,9 @@ extern int quit_if_one_screen;
|
||||
extern int no_init;
|
||||
extern int errmsgs;
|
||||
extern int redraw_on_quit;
|
||||
extern int term_init_done;
|
||||
extern int term_addrs;
|
||||
extern lbool first_time;
|
||||
extern lbool term_init_ever;
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C && (defined(__MINGW32__) || defined(_MSC_VER))
|
||||
/* malloc'ed 0-terminated utf8 of 0-terminated wide ws, or null on errors */
|
||||
@@ -156,26 +158,16 @@ cleanup:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SECURE
|
||||
static int security_feature_error(constant char *type, size_t len, constant char *name)
|
||||
{
|
||||
PARG parg;
|
||||
size_t msglen = len + strlen(type) + 64;
|
||||
char *msg = ecalloc(msglen, sizeof(char));
|
||||
SNPRINTF3(msg, msglen, "LESSSECURE_ALLOW: %s feature name \"%.*s\"", type, (int) len, name);
|
||||
parg.p_string = msg;
|
||||
error("%s", &parg);
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the SF_xxx value of a secure feature given the name of the feature.
|
||||
* Set the secure_allow_features bitmask, which controls
|
||||
* whether certain secure features are allowed.
|
||||
*/
|
||||
static int security_feature(constant char *name, size_t len)
|
||||
static void init_secure(void)
|
||||
{
|
||||
struct secure_feature { constant char *name; int sf_value; };
|
||||
static struct secure_feature features[] = {
|
||||
#if SECURE
|
||||
secure_allow_features = 0;
|
||||
#else
|
||||
static struct csl_bitmap_def security_features[] = {
|
||||
{ "edit", SF_EDIT },
|
||||
{ "examine", SF_EXAMINE },
|
||||
{ "glob", SF_GLOB },
|
||||
@@ -189,33 +181,6 @@ static int security_feature(constant char *name, size_t len)
|
||||
{ "stop", SF_STOP },
|
||||
{ "tags", SF_TAGS },
|
||||
};
|
||||
int i;
|
||||
int match = -1;
|
||||
|
||||
for (i = 0; i < countof(features); i++)
|
||||
{
|
||||
if (strncmp(features[i].name, name, len) == 0)
|
||||
{
|
||||
if (match >= 0) /* name is ambiguous */
|
||||
return security_feature_error("ambiguous", len, name);
|
||||
match = i;
|
||||
}
|
||||
}
|
||||
if (match < 0)
|
||||
return security_feature_error("invalid", len, name);
|
||||
return features[match].sf_value;
|
||||
}
|
||||
#endif /* !SECURE */
|
||||
|
||||
/*
|
||||
* Set the secure_allow_features bitmask, which controls
|
||||
* whether certain secure features are allowed.
|
||||
*/
|
||||
static void init_secure(void)
|
||||
{
|
||||
#if SECURE
|
||||
secure_allow_features = 0;
|
||||
#else
|
||||
constant char *str = lgetenv("LESSSECURE");
|
||||
if (isnullenv(str))
|
||||
secure_allow_features = ~0; /* allow everything */
|
||||
@@ -224,19 +189,8 @@ static void init_secure(void)
|
||||
|
||||
str = lgetenv("LESSSECURE_ALLOW");
|
||||
if (!isnullenv(str))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
constant char *estr;
|
||||
while (*str == ' ' || *str == ',') ++str; /* skip leading spaces/commas */
|
||||
if (*str == '\0') break;
|
||||
estr = strchr(str, ',');
|
||||
if (estr == NULL) estr = str + strlen(str);
|
||||
while (estr > str && estr[-1] == ' ') --estr; /* trim trailing spaces */
|
||||
secure_allow_features |= security_feature(str, ptr_diff(estr, str));
|
||||
str = estr;
|
||||
}
|
||||
}
|
||||
secure_allow_features = parse_csl_bitmap(str,
|
||||
security_features, countof(security_features), "LESSSECURE_ALLOW");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -251,8 +205,11 @@ int main(int argc, constant char *argv[])
|
||||
struct xbuffer xfiles;
|
||||
constant int *files;
|
||||
size_t num_files;
|
||||
size_t f;
|
||||
lbool end_opts = FALSE;
|
||||
lbool posixly_correct = FALSE;
|
||||
lbool posixly_correct;
|
||||
|
||||
no_config = getenv("LESSNOCONFIG");
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C && (defined(__MINGW32__) || defined(_MSC_VER))
|
||||
if (GetACP() != CP_UTF8) /* not using a UTF-8 manifest */
|
||||
@@ -295,7 +252,7 @@ int main(int argc, constant char *argv[])
|
||||
* Process command line arguments and LESS environment arguments.
|
||||
* Command line arguments override environment arguments.
|
||||
*/
|
||||
is_tty = isatty(1);
|
||||
is_tty = (isatty(1) != 0);
|
||||
init_mark();
|
||||
init_cmds();
|
||||
init_poll();
|
||||
@@ -325,7 +282,7 @@ int main(int argc, constant char *argv[])
|
||||
#define isoptstring(s) less_is_more ? (((s)[0] == '-') && (s)[1] != '\0') : \
|
||||
(((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
|
||||
xbuf_init(&xfiles);
|
||||
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
|
||||
posixly_correct = (lgetenv("POSIXLY_CORRECT") != NULL);
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (strcmp(argv[i], "--") == 0)
|
||||
@@ -336,7 +293,7 @@ int main(int argc, constant char *argv[])
|
||||
{
|
||||
if (posixly_correct)
|
||||
end_opts = TRUE;
|
||||
xbuf_add_data(&xfiles, (constant unsigned char *) &i, sizeof(i));
|
||||
xbuf_add_data(&xfiles, &i, sizeof(i));
|
||||
}
|
||||
}
|
||||
#undef isoptstring
|
||||
@@ -354,7 +311,8 @@ int main(int argc, constant char *argv[])
|
||||
if (less_is_more)
|
||||
no_init = TRUE;
|
||||
|
||||
get_term();
|
||||
if (is_tty)
|
||||
get_term();
|
||||
expand_cmd_tables();
|
||||
|
||||
#if EDITOR
|
||||
@@ -379,7 +337,7 @@ int main(int argc, constant char *argv[])
|
||||
ifile = get_ifile(FAKE_HELPFILE, ifile);
|
||||
files = (constant int *) xfiles.data;
|
||||
num_files = xfiles.end / sizeof(int);
|
||||
for (i = 0; i < num_files; i++)
|
||||
for (f = 0; f < num_files; f++)
|
||||
{
|
||||
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC)
|
||||
/*
|
||||
@@ -393,7 +351,7 @@ int main(int argc, constant char *argv[])
|
||||
char *gfilename;
|
||||
char *qfilename;
|
||||
|
||||
gfilename = lglob(argv[files[i]]);
|
||||
gfilename = lglob(argv[files[f]]);
|
||||
init_textlist(&tlist, gfilename);
|
||||
filename = NULL;
|
||||
while ((filename = forw_textlist(&tlist, filename)) != NULL)
|
||||
@@ -405,7 +363,7 @@ int main(int argc, constant char *argv[])
|
||||
}
|
||||
free(gfilename);
|
||||
#else
|
||||
(void) get_ifile(argv[files[i]], ifile);
|
||||
(void) get_ifile(argv[files[f]], ifile);
|
||||
ifile = prev_ifile(NULL_IFILE);
|
||||
#endif
|
||||
}
|
||||
@@ -420,10 +378,10 @@ int main(int argc, constant char *argv[])
|
||||
* Output is not a tty.
|
||||
* Just copy the input file(s) to output.
|
||||
*/
|
||||
set_output(1); /* write to stdout */
|
||||
SET_BINARY(1);
|
||||
if (edit_first() == 0)
|
||||
{
|
||||
set_output(1, TRUE); /* write to stdout */
|
||||
do {
|
||||
cat_file();
|
||||
} while (edit_next(1) == 0);
|
||||
@@ -476,7 +434,7 @@ int main(int argc, constant char *argv[])
|
||||
/*
|
||||
* See if file fits on one screen to decide whether
|
||||
* to send terminal init. But don't need this
|
||||
* if -X (no_init) overrides this (see init()).
|
||||
* if -X (no_init) overrides this (see term_init()).
|
||||
*/
|
||||
if (quit_if_one_screen)
|
||||
{
|
||||
@@ -504,8 +462,10 @@ int main(int argc, constant char *argv[])
|
||||
get_return();
|
||||
putchr('\n');
|
||||
}
|
||||
set_output(1);
|
||||
init();
|
||||
set_output(1, FALSE);
|
||||
#if MSDOS_COMPILER
|
||||
term_init();
|
||||
#endif
|
||||
commands();
|
||||
quit(QUIT_OK);
|
||||
/*NOTREACHED*/
|
||||
@@ -617,9 +577,9 @@ public void quit(int status)
|
||||
check_altpipe_error();
|
||||
if (interactive())
|
||||
clear_bot();
|
||||
deinit();
|
||||
term_deinit();
|
||||
flush();
|
||||
if (redraw_on_quit && term_init_done)
|
||||
if (redraw_on_quit && term_addrs)
|
||||
{
|
||||
/*
|
||||
* The last file text displayed might have been on an
|
||||
|
||||
+144
-62
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -27,7 +27,6 @@ struct mark
|
||||
* because we don't want to create an ifile until the
|
||||
* user explicitly requests the file (by name or mark).
|
||||
*/
|
||||
char m_letter; /* Associated character */
|
||||
IFILE m_ifile; /* Input file being marked */
|
||||
char *m_filename; /* Name of the input file */
|
||||
struct scrpos m_scrpos; /* Position of the mark */
|
||||
@@ -39,12 +38,14 @@ struct mark
|
||||
* The final one is lmark, for the "last mark"; addressed by the apostrophe.
|
||||
*/
|
||||
#define NMARKS ((2*26)+2) /* a-z, A-Z, mousemark, lastmark */
|
||||
#define NUMARKS ((2*26)+1) /* user marks (not lastmark) */
|
||||
#define MOUSEMARK (NMARKS-2)
|
||||
#define NUMARKS (NMARKS-1) /* user marks (not lastmark) */
|
||||
#define LASTMARK (NMARKS-1)
|
||||
#define MOUSEMARK (LASTMARK-1)
|
||||
static struct mark marks[NMARKS];
|
||||
public int marks_modified = 0;
|
||||
|
||||
public lbool marks_modified = FALSE;
|
||||
#if CMD_HISTORY
|
||||
static struct mark file_marks[NMARKS];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize a mark struct.
|
||||
@@ -69,17 +70,23 @@ public void init_mark(void)
|
||||
|
||||
for (i = 0; i < NMARKS; i++)
|
||||
{
|
||||
char letter;
|
||||
switch (i) {
|
||||
case MOUSEMARK: letter = '#'; break;
|
||||
case LASTMARK: letter = '\''; break;
|
||||
default: letter = (char) ((i < 26) ? 'a'+i : 'A'+i-26); break;
|
||||
}
|
||||
marks[i].m_letter = letter;
|
||||
cmark(&marks[i], NULL_IFILE, NULL_POSITION, -1);
|
||||
#if CMD_HISTORY
|
||||
cmark(&file_marks[i], NULL_IFILE, NULL_POSITION, -1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void mark_clear(struct mark *m)
|
||||
{
|
||||
m->m_scrpos.pos = NULL_POSITION;
|
||||
}
|
||||
|
||||
static lbool mark_is_set(struct mark *m)
|
||||
{
|
||||
return m->m_scrpos.pos != NULL_POSITION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set m_ifile and clear m_filename.
|
||||
*/
|
||||
@@ -101,23 +108,48 @@ static void mark_get_ifile(struct mark *m)
|
||||
mark_set_ifile(m, get_ifile(m->m_filename, prev_ifile(NULL_IFILE)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the letter associated with a mark index.
|
||||
*/
|
||||
static char mark_letter(int index)
|
||||
{
|
||||
switch (index) {
|
||||
case LASTMARK: return '\'';
|
||||
case MOUSEMARK: return '#';
|
||||
default: return (char) ((index < 26) ? 'a'+index : 'A'+index-26);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the mark table index identified by a character.
|
||||
*/
|
||||
static int mark_index(char c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c-'a';
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return c-'A'+26;
|
||||
if (c == '\'')
|
||||
return LASTMARK;
|
||||
if (c == '#')
|
||||
return MOUSEMARK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the user mark struct identified by a character.
|
||||
*/
|
||||
static struct mark * getumark(char c)
|
||||
{
|
||||
PARG parg;
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return (&marks[c-'a']);
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (&marks[c-'A'+26]);
|
||||
if (c == '\'')
|
||||
return (&marks[LASTMARK]);
|
||||
if (c == '#')
|
||||
return (&marks[MOUSEMARK]);
|
||||
parg.p_char = (char) c;
|
||||
error("Invalid mark letter %c", &parg);
|
||||
return (NULL);
|
||||
int index = mark_index(c);
|
||||
if (index < 0 || index >= NUMARKS)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_char = (char) c;
|
||||
error("Invalid mark letter %c", &parg);
|
||||
return NULL;
|
||||
}
|
||||
return &marks[index];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -129,6 +161,7 @@ static struct mark * getmark(char c)
|
||||
{
|
||||
struct mark *m;
|
||||
static struct mark sm;
|
||||
POSITION pos;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
@@ -149,7 +182,13 @@ static struct mark * getmark(char c)
|
||||
return (NULL);
|
||||
}
|
||||
m = &sm;
|
||||
cmark(m, curr_ifile, ch_tell(), sc_height);
|
||||
pos = ch_tell();
|
||||
if (pos == NULL_POSITION)
|
||||
return (NULL);
|
||||
pos = back_line(pos, NULL);
|
||||
if (pos == NULL_POSITION)
|
||||
return (NULL);
|
||||
cmark(m, curr_ifile, pos, sc_height-1);
|
||||
break;
|
||||
case '.':
|
||||
/*
|
||||
@@ -172,7 +211,7 @@ static struct mark * getmark(char c)
|
||||
m = getumark(c);
|
||||
if (m == NULL)
|
||||
break;
|
||||
if (m->m_scrpos.pos == NULL_POSITION)
|
||||
if (!mark_is_set(m))
|
||||
{
|
||||
error("Mark not set", NULL_PARG);
|
||||
return (NULL);
|
||||
@@ -185,7 +224,7 @@ static struct mark * getmark(char c)
|
||||
/*
|
||||
* Is a mark letter invalid?
|
||||
*/
|
||||
public int badmark(char c)
|
||||
public lbool badmark(char c)
|
||||
{
|
||||
return (getmark(c) == NULL);
|
||||
}
|
||||
@@ -193,22 +232,40 @@ public int badmark(char c)
|
||||
/*
|
||||
* Set a user-defined mark.
|
||||
*/
|
||||
public void setmark(char c, int where)
|
||||
public void setmark(char c, int where, LINENUM linenum)
|
||||
{
|
||||
struct mark *m;
|
||||
struct scrpos scrpos;
|
||||
POSITION pos;
|
||||
|
||||
m = getumark(c);
|
||||
if (m == NULL)
|
||||
return;
|
||||
get_scrpos(&scrpos, where);
|
||||
if (scrpos.pos == NULL_POSITION)
|
||||
|
||||
if (linenum == 0)
|
||||
{
|
||||
bell();
|
||||
return;
|
||||
get_scrpos(&scrpos, where);
|
||||
if (scrpos.pos == NULL_POSITION)
|
||||
{
|
||||
lbell();
|
||||
return;
|
||||
}
|
||||
} else
|
||||
{
|
||||
pos = find_pos(linenum);
|
||||
if (pos == NULL_POSITION)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_linenum = linenum;
|
||||
error("Cannot find line number %n", &parg);
|
||||
return;
|
||||
}
|
||||
get_scrpos_pos(&scrpos, where, pos);
|
||||
}
|
||||
cmark(m, curr_ifile, scrpos.pos, scrpos.ln);
|
||||
marks_modified = 1;
|
||||
marks_modified = TRUE;
|
||||
if (perma_marks && autosave_action('m'))
|
||||
save_cmdhist();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -223,11 +280,18 @@ public void clrmark(char c)
|
||||
return;
|
||||
if (m->m_scrpos.pos == NULL_POSITION)
|
||||
{
|
||||
bell();
|
||||
lbell();
|
||||
return;
|
||||
}
|
||||
m->m_scrpos.pos = NULL_POSITION;
|
||||
marks_modified = 1;
|
||||
mark_clear(m);
|
||||
#if CMD_HISTORY
|
||||
/* Also clear in file_marks, so save_marks doesn't save it to history file. */
|
||||
m = &file_marks[mark_index(c)];
|
||||
mark_clear(m);
|
||||
#endif
|
||||
marks_modified = TRUE;
|
||||
if (perma_marks && autosave_action('m'))
|
||||
save_cmdhist();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -243,13 +307,13 @@ public void lastmark(void)
|
||||
if (scrpos.pos == NULL_POSITION)
|
||||
return;
|
||||
cmark(&marks[LASTMARK], curr_ifile, scrpos.pos, scrpos.ln);
|
||||
marks_modified = 1;
|
||||
marks_modified = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Go to a mark.
|
||||
*/
|
||||
public void gomark(char c)
|
||||
public void gomark(char c, int sline)
|
||||
{
|
||||
struct mark *m;
|
||||
struct scrpos scrpos;
|
||||
@@ -257,6 +321,8 @@ public void gomark(char c)
|
||||
m = getmark(c);
|
||||
if (m == NULL)
|
||||
return;
|
||||
if (sline != 0)
|
||||
m->m_scrpos.ln = sline;
|
||||
|
||||
/*
|
||||
* If we're trying to go to the lastmark and
|
||||
@@ -264,7 +330,7 @@ public void gomark(char c)
|
||||
* set it to the beginning of the current file.
|
||||
* {{ Couldn't we instead set marks[LASTMARK] in edit()? }}
|
||||
*/
|
||||
if (m == &marks[LASTMARK] && m->m_scrpos.pos == NULL_POSITION)
|
||||
if (m == &marks[LASTMARK] && !mark_is_set(m))
|
||||
cmark(m, curr_ifile, ch_zero(), jump_sline);
|
||||
|
||||
mark_get_ifile(m);
|
||||
@@ -316,14 +382,11 @@ public char posmark(POSITION pos)
|
||||
/* Only user marks */
|
||||
for (i = 0; i < NUMARKS; i++)
|
||||
{
|
||||
if (marks[i].m_ifile == curr_ifile && marks[i].m_scrpos.pos == pos)
|
||||
{
|
||||
if (i < 26) return (char) ('a' + i);
|
||||
if (i < 26*2) return (char) ('A' + (i - 26));
|
||||
return '#';
|
||||
}
|
||||
struct mark *m = &marks[i];
|
||||
if (m->m_ifile == curr_ifile && m->m_scrpos.pos == pos)
|
||||
return mark_letter(i);
|
||||
}
|
||||
return 0;
|
||||
return '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -335,7 +398,7 @@ public void unmark(IFILE ifile)
|
||||
|
||||
for (i = 0; i < NMARKS; i++)
|
||||
if (marks[i].m_ifile == ifile)
|
||||
marks[i].m_scrpos.pos = NULL_POSITION;
|
||||
mark_clear(&marks[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -363,6 +426,15 @@ public void mark_check_ifile(IFILE ifile)
|
||||
|
||||
#if CMD_HISTORY
|
||||
|
||||
/*
|
||||
* Initialize a mark struct, including the filename.
|
||||
*/
|
||||
static void cmarkf(struct mark *m, IFILE ifile, POSITION pos, int ln, constant char *filename)
|
||||
{
|
||||
cmark(m, ifile, pos, ln);
|
||||
m->m_filename = (filename == NULL) ? NULL : save(filename);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save marks to history file.
|
||||
*/
|
||||
@@ -370,16 +442,29 @@ public void save_marks(FILE *fout, constant char *hdr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!perma_marks)
|
||||
return;
|
||||
if (perma_marks)
|
||||
{
|
||||
/* Copy active marks to file_marks. */
|
||||
for (i = 0; i < NMARKS; i++)
|
||||
{
|
||||
struct mark *m = &marks[i];
|
||||
if (mark_is_set(m))
|
||||
cmarkf(&file_marks[i], m->m_ifile, m->m_scrpos.pos, m->m_scrpos.ln, m->m_filename);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save file_marks to the history file.
|
||||
* These may have been read from the history file at startup
|
||||
* (in restore_mark), or copied from the active marks above.
|
||||
*/
|
||||
fprintf(fout, "%s\n", hdr);
|
||||
for (i = 0; i < NMARKS; i++)
|
||||
{
|
||||
constant char *filename;
|
||||
struct mark *m = &marks[i];
|
||||
struct mark *m = &file_marks[i];
|
||||
char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2];
|
||||
if (m->m_scrpos.pos == NULL_POSITION)
|
||||
if (!mark_is_set(m))
|
||||
continue;
|
||||
postoa(m->m_scrpos.pos, pos_str, 10);
|
||||
filename = m->m_filename;
|
||||
@@ -387,7 +472,7 @@ public void save_marks(FILE *fout, constant char *hdr)
|
||||
filename = get_real_filename(m->m_ifile);
|
||||
if (strcmp(filename, "-") != 0)
|
||||
fprintf(fout, "m %c %d %s %s\n",
|
||||
m->m_letter, m->m_scrpos.ln, pos_str, filename);
|
||||
mark_letter(i), m->m_scrpos.ln, pos_str, filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,7 +481,7 @@ public void save_marks(FILE *fout, constant char *hdr)
|
||||
*/
|
||||
public void restore_mark(constant char *line)
|
||||
{
|
||||
struct mark *m;
|
||||
int index;
|
||||
int ln;
|
||||
POSITION pos;
|
||||
|
||||
@@ -404,24 +489,21 @@ public void restore_mark(constant char *line)
|
||||
if (*line++ != 'm')
|
||||
return;
|
||||
skip_whitespace;
|
||||
m = getumark(*line++);
|
||||
if (m == NULL)
|
||||
index = mark_index(*line++);
|
||||
if (index < 0)
|
||||
return;
|
||||
skip_whitespace;
|
||||
ln = lstrtoic(line, &line, 10);
|
||||
if (ln < 0)
|
||||
return;
|
||||
if (ln < 1)
|
||||
ln = 1;
|
||||
if (ln > sc_height)
|
||||
ln = sc_height;
|
||||
skip_whitespace;
|
||||
pos = lstrtoposc(line, &line, 10);
|
||||
if (pos < 0)
|
||||
return;
|
||||
skip_whitespace;
|
||||
cmark(m, NULL_IFILE, pos, ln);
|
||||
m->m_filename = save(line);
|
||||
/* Save in both active marks table and file_marks table. */
|
||||
cmarkf(&marks[index], NULL_IFILE, pos, ln, line);
|
||||
cmarkf(&file_marks[index], NULL_IFILE, pos, ln, line);
|
||||
}
|
||||
|
||||
#endif /* CMD_HISTORY */
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Generated by "./mkutable -f2 Xx -- unicode/UnicodeData.txt" on Aug 19 1:16:32 GMT 2025 */
|
||||
/* Generated by "./mkutable -f2 Xx -- unicode/UnicodeData.txt" on Nov 28 1:30:12 GMT 2025 */
|
||||
{ 0x00ad, 0x00ad }, /* Xx */
|
||||
{ 0x200d, 0x200d }, /* Xx */
|
||||
{ 0xfe00, 0xfe0f }, /* Xx */
|
||||
|
||||
+251
-83
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -34,16 +34,18 @@ extern lbool plusoption;
|
||||
extern int swindow;
|
||||
extern int sc_width;
|
||||
extern int sc_height;
|
||||
extern int dohelp;
|
||||
extern lbool dohelp;
|
||||
extern char openquote;
|
||||
extern char closequote;
|
||||
extern char *prproto[];
|
||||
extern char *eprproto[];
|
||||
extern char *eqproto;
|
||||
extern char *hproto;
|
||||
extern char *wproto;
|
||||
extern char *every_first_cmd;
|
||||
extern IFILE curr_ifile;
|
||||
extern char version[];
|
||||
extern int jump_sline_arg;
|
||||
extern int jump_sline;
|
||||
extern long jump_sline_fraction;
|
||||
extern int shift_count;
|
||||
@@ -52,7 +54,9 @@ extern int match_shift;
|
||||
extern long match_shift_fraction;
|
||||
extern LWCHAR rscroll_char;
|
||||
extern int rscroll_attr;
|
||||
extern int mousecap;
|
||||
extern int emouse;
|
||||
extern int mouse_reverse;
|
||||
extern int xmouse;
|
||||
extern int wheel_lines;
|
||||
extern int less_is_more;
|
||||
extern int linenum_width;
|
||||
@@ -67,12 +71,14 @@ extern int tabstops[];
|
||||
extern int ntabstops;
|
||||
extern int tabdefault;
|
||||
extern int no_paste;
|
||||
extern int hilite_target;
|
||||
extern char intr_char;
|
||||
extern int nosearch_header_lines;
|
||||
extern int nosearch_header_cols;
|
||||
extern POSITION header_start_pos;
|
||||
extern char *init_header;
|
||||
extern char *first_cmd_at_prompt;
|
||||
extern char *autosave;
|
||||
#if LOGFILE
|
||||
extern char *namelogfile;
|
||||
extern lbool force_logfile;
|
||||
@@ -85,7 +91,7 @@ extern char ztags[];
|
||||
#endif
|
||||
#if LESSTEST
|
||||
extern constant char *ttyin_name;
|
||||
extern int is_tty;
|
||||
extern lbool is_tty;
|
||||
#endif /*LESSTEST*/
|
||||
#if MSDOS_COMPILER
|
||||
extern int nm_fg_color, nm_bg_color, nm_attr;
|
||||
@@ -166,36 +172,27 @@ public void opt__O(int type, constant char *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int toggle_fraction(int *num, long *frac, constant char *s, constant char *printopt, void (*calc)(void))
|
||||
static void toggle_fraction(int *num, long *frac, constant char *s, constant char *printopt, lbool neg_ok, void (*calc)(void))
|
||||
{
|
||||
lbool err;
|
||||
if (s == NULL)
|
||||
{
|
||||
(*calc)();
|
||||
} else if (*s == '.')
|
||||
{
|
||||
long tfrac;
|
||||
s++;
|
||||
tfrac = getfraction(&s, printopt, &err);
|
||||
if (err)
|
||||
if (!getfraction(&s, frac))
|
||||
{
|
||||
error("Invalid fraction", NULL_PARG);
|
||||
return -1;
|
||||
PARG parg;
|
||||
parg.p_string = printopt;
|
||||
error("Invalid fraction in %s", &parg);
|
||||
return;
|
||||
}
|
||||
*frac = tfrac;
|
||||
(*calc)();
|
||||
} else
|
||||
{
|
||||
int tnum = getnumc(&s, printopt, &err);
|
||||
if (err)
|
||||
{
|
||||
error("Invalid number", NULL_PARG);
|
||||
return -1;
|
||||
}
|
||||
if (!getnumc(&s, printopt, neg_ok, num))
|
||||
return;
|
||||
*frac = -1;
|
||||
*num = tnum;
|
||||
}
|
||||
return 0;
|
||||
(*calc)();
|
||||
}
|
||||
|
||||
static void query_fraction(int value, long fraction, constant char *int_msg, constant char *frac_msg)
|
||||
@@ -229,11 +226,11 @@ public void opt_j(int type, constant char *s)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
toggle_fraction(&jump_sline, &jump_sline_fraction,
|
||||
s, "j", calc_jump_sline);
|
||||
toggle_fraction(&jump_sline_arg, &jump_sline_fraction,
|
||||
s, "-j", TRUE, calc_jump_sline);
|
||||
break;
|
||||
case QUERY:
|
||||
query_fraction(jump_sline, jump_sline_fraction,
|
||||
query_fraction(jump_sline_arg, jump_sline_fraction,
|
||||
"Position target at screen line %d", "Position target at screen position %s");
|
||||
break;
|
||||
}
|
||||
@@ -241,10 +238,19 @@ public void opt_j(int type, constant char *s)
|
||||
|
||||
public void calc_jump_sline(void)
|
||||
{
|
||||
jump_sline = jump_sline_arg;
|
||||
/* If jump_sline_fraction is set, calculate jump_sline from it. */
|
||||
if (jump_sline_fraction >= 0)
|
||||
jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM);
|
||||
/* Negative jump_sline means relative to bottom of screen. */
|
||||
if (jump_sline < 0)
|
||||
jump_sline += sc_height;
|
||||
/* If jump_sline is obscured by header, move it after the header. */
|
||||
if (jump_sline <= header_lines)
|
||||
jump_sline = header_lines + 1;
|
||||
/* If jump_sline is past bottom of screen, move it to the bottom. */
|
||||
if (jump_sline >= sc_height)
|
||||
jump_sline = sc_height - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -257,7 +263,7 @@ public void opt_shift(int type, constant char *s)
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
toggle_fraction(&shift_count, &shift_count_fraction,
|
||||
s, "#", calc_shift_count);
|
||||
s, "-#", FALSE, calc_shift_count);
|
||||
break;
|
||||
case QUERY:
|
||||
query_fraction(shift_count, shift_count_fraction,
|
||||
@@ -331,7 +337,7 @@ public void opt__S(int type, constant char *s)
|
||||
switch (type)
|
||||
{
|
||||
case TOGGLE:
|
||||
pos_rehead();
|
||||
pos_rehead(TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -467,7 +473,73 @@ public void opt__P(int type, constant char *s)
|
||||
break;
|
||||
case QUERY:
|
||||
parg.p_string = prproto[pr_type];
|
||||
error("%s", &parg);
|
||||
switch (pr_type)
|
||||
{
|
||||
case PR_MEDIUM: error("Prompt (medium): %s", &parg); break;
|
||||
case PR_LONG: error("Prompt (long): %s", &parg); break;
|
||||
default: error("Prompt (short): %s", &parg); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for --end-prompt option.
|
||||
*/
|
||||
public void opt_end_prompt(int type, constant char *s)
|
||||
{
|
||||
char **pend;
|
||||
PARG parg;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
switch (*s)
|
||||
{
|
||||
case 's': pend = &eprproto[PR_SHORT]; s++; break;
|
||||
case 'm': pend = &eprproto[PR_MEDIUM]; s++; break;
|
||||
case 'M': pend = &eprproto[PR_LONG]; s++; break;
|
||||
default: pend = &eprproto[PR_SHORT]; break;
|
||||
}
|
||||
if (*pend != NULL)
|
||||
free(*pend);
|
||||
*pend = (strcmp(s, "-") == 0) ? NULL : save(s);
|
||||
break;
|
||||
case QUERY:
|
||||
parg.p_string = eprproto[pr_type];
|
||||
if (parg.p_string == NULL)
|
||||
parg.p_string = "(nothing)";
|
||||
switch (pr_type)
|
||||
{
|
||||
case PR_MEDIUM: error("Print after medium prompt: %s", &parg); break;
|
||||
case PR_LONG: error("Print after long prompt: %s", &parg); break;
|
||||
default: error("Print after short prompt: %s", &parg); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for --autosave option.
|
||||
*/
|
||||
public void opt_autosave(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
if (s == NULL)
|
||||
s = "-";
|
||||
if (autosave != NULL)
|
||||
free(autosave);
|
||||
autosave = save(s);
|
||||
break;
|
||||
case QUERY:
|
||||
parg.p_string = (autosave != NULL) ? autosave : "-";
|
||||
error("Autosave actions: %s", &parg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -522,7 +594,7 @@ public void opt__V(int type, constant char *s)
|
||||
dispversion();
|
||||
break;
|
||||
case INIT:
|
||||
set_output(1); /* Force output to stdout per GNU standard for --version output. */
|
||||
set_output(1, TRUE); /* Force output to stdout per GNU standard for --version output. */
|
||||
putstr("less ");
|
||||
putstr(version);
|
||||
putstr(" (");
|
||||
@@ -530,7 +602,7 @@ public void opt__V(int type, constant char *s)
|
||||
putstr(" regular expressions)\n");
|
||||
{
|
||||
char constant *copyright =
|
||||
"Copyright (C) 1984-2025 Mark Nudelman\n\n";
|
||||
"Copyright (C) 1984-2026 Mark Nudelman\n\n";
|
||||
putstr(copyright);
|
||||
}
|
||||
if (version[strlen(version)-1] == 'x')
|
||||
@@ -587,11 +659,13 @@ static int color_from_namechar(char namechar)
|
||||
case 'C': return AT_COLOR_CTRL;
|
||||
case 'E': return AT_COLOR_ERROR;
|
||||
case 'H': return AT_COLOR_HEADER;
|
||||
case 'J': return AT_COLOR_TARGET;
|
||||
case 'M': return AT_COLOR_MARK;
|
||||
case 'N': return AT_COLOR_LINENUM;
|
||||
case 'P': return AT_COLOR_PROMPT;
|
||||
case 'R': return AT_COLOR_RSCROLL;
|
||||
case 'S': return AT_COLOR_SEARCH;
|
||||
case 'T': return AT_COLOR_TILDE;
|
||||
case 'W': case 'A': return AT_COLOR_ATTN;
|
||||
case 'n': return AT_NORMAL;
|
||||
case 's': return AT_STANDOUT;
|
||||
@@ -622,6 +696,11 @@ public void opt_D(int type, constant char *s)
|
||||
if (*s == 'a')
|
||||
{
|
||||
sgr_mode = !sgr_mode;
|
||||
if (type == TOGGLE)
|
||||
{
|
||||
p.p_string = (sgr_mode) ? "on" : "off";
|
||||
error("SGR mode is %s", &p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -674,12 +753,6 @@ public void opt_D(int type, constant char *s)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#if MSDOS_COMPILER
|
||||
case QUERY:
|
||||
p.p_string = (sgr_mode) ? "on" : "off";
|
||||
error("SGR mode is %s", &p);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,7 +915,7 @@ public void opt_query(int type, constant char *s)
|
||||
error("Use \"h\" for help", NULL_PARG);
|
||||
break;
|
||||
case INIT:
|
||||
dohelp = 1;
|
||||
dohelp = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,7 +927,7 @@ public void opt_match_shift(int type, constant char *s)
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
toggle_fraction(&match_shift, &match_shift_fraction,
|
||||
s, "--match-shift", calc_match_shift);
|
||||
s, "--match-shift", FALSE, calc_match_shift);
|
||||
break;
|
||||
case QUERY:
|
||||
query_fraction(match_shift, match_shift_fraction,
|
||||
@@ -870,21 +943,100 @@ public void calc_match_shift(void)
|
||||
match_shift = (int) muldiv(sc_width, match_shift_fraction, NUM_FRAC_DENOM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for the --emouse option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_emouse(int type, constant char *s)
|
||||
{
|
||||
/* Order of entries matters for QUERY.
|
||||
* Combinations must come after their components. */
|
||||
static struct csl_bitmap_def emouse_defs[] = {
|
||||
{ "hscroll", EMOUSE_HSCROLL },
|
||||
{ "vscroll", EMOUSE_VSCROLL },
|
||||
{ "hdrag", EMOUSE_HDRAG },
|
||||
{ "vdrag", EMOUSE_VDRAG },
|
||||
{ "lclick", EMOUSE_LCLICK },
|
||||
{ "rclick", EMOUSE_RCLICK },
|
||||
{ "scroll", EMOUSE_HSCROLL|EMOUSE_VSCROLL },
|
||||
{ "drag", EMOUSE_HDRAG|EMOUSE_VDRAG },
|
||||
{ "hmove", EMOUSE_HSCROLL|EMOUSE_HDRAG },
|
||||
{ "vmove", EMOUSE_VSCROLL|EMOUSE_VDRAG },
|
||||
{ "move", EMOUSE_VSCROLL|EMOUSE_VDRAG|EMOUSE_HSCROLL|EMOUSE_HDRAG },
|
||||
{ "click", EMOUSE_LCLICK|EMOUSE_RCLICK },
|
||||
{ "all", EMOUSE_VSCROLL|EMOUSE_VDRAG|EMOUSE_HSCROLL|EMOUSE_HDRAG|EMOUSE_LCLICK|EMOUSE_RCLICK },
|
||||
};
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE: {
|
||||
lbool was_mouse_enabled = (emouse != 0);
|
||||
if (s == NULL || strcmp(s, "-") == 0)
|
||||
emouse = 0;
|
||||
else
|
||||
emouse = parse_csl_bitmap(s,
|
||||
emouse_defs, countof(emouse_defs), "--emouse");
|
||||
if (type == TOGGLE && was_mouse_enabled != (emouse != 0))
|
||||
{
|
||||
if (emouse == 0)
|
||||
deinit_mouse();
|
||||
else
|
||||
init_mouse();
|
||||
}
|
||||
break; }
|
||||
case QUERY: {
|
||||
char buf[128];
|
||||
char *bp = buf;
|
||||
char *ebuf = buf + sizeof(buf);
|
||||
int qmouse = emouse;
|
||||
PARG parg;
|
||||
int i;
|
||||
|
||||
for (i = countof(emouse_defs)-1; i >= 0; i--)
|
||||
{
|
||||
int bit = emouse_defs[i].bit_value;
|
||||
if ((qmouse & bit) == bit)
|
||||
{
|
||||
if (bp > buf && bp+1 < ebuf)
|
||||
*bp++ = ',';
|
||||
strncpy(bp, emouse_defs[i].bit_name, ptr_diff(ebuf, bp));
|
||||
bp += strlen(bp);
|
||||
qmouse &= ~bit;
|
||||
}
|
||||
}
|
||||
*bp = '\0';
|
||||
parg.p_string = buf;
|
||||
if (buf[0] == '\0')
|
||||
error("Ignore mouse input", NULL_PARG);
|
||||
else
|
||||
error("Mouse features enabled: %s", &parg);
|
||||
break; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for the --mouse option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_mousecap(int type, constant char *s)
|
||||
public void opt_mouse(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TOGGLE:
|
||||
if (mousecap == OPT_OFF)
|
||||
deinit_mouse();
|
||||
else
|
||||
init_mouse();
|
||||
break;
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
switch (xmouse)
|
||||
{
|
||||
case OPT_OFF:
|
||||
opt_emouse(type, "-");
|
||||
break;
|
||||
case OPT_ON:
|
||||
case OPT_ONPLUS:
|
||||
opt_emouse(type, "vmove,click");
|
||||
mouse_reverse = (xmouse == OPT_ONPLUS);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case QUERY:
|
||||
break;
|
||||
}
|
||||
@@ -1019,28 +1171,24 @@ public void opt_intr(int type, constant char *s)
|
||||
* Return -1 if the list entry is missing or empty.
|
||||
* Updates *sp to point to the first char of the next number in the list.
|
||||
*/
|
||||
public int next_cnum(constant char **sp, constant char *printopt, constant char *errmsg, lbool *errp)
|
||||
static lbool next_cnum(constant char **sp, constant char *printopt, mutable int *p_num)
|
||||
{
|
||||
int n;
|
||||
*errp = FALSE;
|
||||
if (**sp == '\0') /* at end of line */
|
||||
return -1;
|
||||
{
|
||||
*p_num = -1;
|
||||
return TRUE;
|
||||
}
|
||||
if (**sp == ',') /* that's the next comma; we have an empty string */
|
||||
{
|
||||
++(*sp);
|
||||
return -1;
|
||||
}
|
||||
n = getnumc(sp, printopt, errp);
|
||||
if (*errp)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = errmsg;
|
||||
error("invalid %s", &parg);
|
||||
return -1;
|
||||
*p_num = -1;
|
||||
return TRUE;
|
||||
}
|
||||
if (!getnumc(sp, printopt, FALSE, p_num))
|
||||
return FALSE;
|
||||
if (**sp == ',')
|
||||
++(*sp);
|
||||
return n;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1050,26 +1198,21 @@ public int next_cnum(constant char **sp, constant char *printopt, constant char
|
||||
static lbool parse_header(constant char *s, int *lines, int *cols, POSITION *start_pos)
|
||||
{
|
||||
int n;
|
||||
lbool err;
|
||||
|
||||
if (*s == '-')
|
||||
s = "0,0";
|
||||
|
||||
n = next_cnum(&s, "header", "number of lines", &err);
|
||||
if (err) return FALSE;
|
||||
if (!next_cnum(&s, "--header", &n))
|
||||
return FALSE;
|
||||
if (n >= 0) *lines = n;
|
||||
|
||||
n = next_cnum(&s, "header", "number of columns", &err);
|
||||
if (err) return FALSE;
|
||||
if (!next_cnum(&s, "--header", &n))
|
||||
return FALSE;
|
||||
if (n >= 0) *cols = n;
|
||||
|
||||
n = next_cnum(&s, "header", "line number", &err);
|
||||
if (err) return FALSE;
|
||||
if (n > 0)
|
||||
if (!next_cnum(&s, "--header", &n))
|
||||
return FALSE;
|
||||
if (n > 0)
|
||||
{
|
||||
LINENUM lnum = (LINENUM) n;
|
||||
if (lnum < 1) lnum = 1;
|
||||
*start_pos = find_pos(lnum);
|
||||
if (n < 1) n = 1;
|
||||
*start_pos = find_pos((LINENUM)n);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1099,13 +1242,31 @@ public void opt_header(int type, constant char *s)
|
||||
set_header(start_pos);
|
||||
calc_jump_sline();
|
||||
break; }
|
||||
case QUERY: {
|
||||
char buf[3*INT_STRLEN_BOUND(long)+3];
|
||||
PARG parg;
|
||||
SNPRINTF3(buf, sizeof(buf), "%ld,%ld,%ld", (long) header_lines, (long) header_cols, (long) find_linenum(header_start_pos));
|
||||
parg.p_string = buf;
|
||||
error("Header (lines,columns,line-number) is %s", &parg);
|
||||
break; }
|
||||
case QUERY: {
|
||||
char buf[3*INT_STRLEN_BOUND(long)+3];
|
||||
PARG parg;
|
||||
SNPRINTF3(buf, sizeof(buf), "%ld,%ld,%ld", (long) header_lines, (long) header_cols, (long) find_linenum(header_start_pos));
|
||||
parg.p_string = buf;
|
||||
error("Header (lines,columns,line-number) is %s", &parg);
|
||||
break; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for the --hilite-target option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_hilite_target(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
break;
|
||||
case TOGGLE:
|
||||
draw_target_attn(hilite_target != OPT_OFF);
|
||||
break;
|
||||
case QUERY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1225,11 +1386,11 @@ public void opt_no_paste(int type, constant char *s)
|
||||
init_bracketed_paste();
|
||||
else
|
||||
deinit_bracketed_paste();
|
||||
break;
|
||||
break;
|
||||
case INIT:
|
||||
case QUERY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LESSTEST
|
||||
@@ -1243,7 +1404,7 @@ public void opt_ttyin_name(int type, constant char *s)
|
||||
{
|
||||
case INIT:
|
||||
ttyin_name = s;
|
||||
is_tty = 1;
|
||||
is_tty = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1264,3 +1425,10 @@ public int get_swindow(void)
|
||||
return (sc_height - header_lines + swindow);
|
||||
}
|
||||
|
||||
/*
|
||||
* Should an action initiate an autosave?
|
||||
*/
|
||||
public lbool autosave_action(char act)
|
||||
{
|
||||
return strchr(autosave, act) != NULL || strchr(autosave, '*') != NULL;
|
||||
}
|
||||
+70
-68
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -70,7 +70,6 @@ public void scan_option(constant char *s, lbool is_env)
|
||||
char *str;
|
||||
lbool set_default;
|
||||
lbool lc;
|
||||
lbool ambig;
|
||||
PARG parg;
|
||||
|
||||
if (s == NULL)
|
||||
@@ -94,7 +93,7 @@ public void scan_option(constant char *s, lbool is_env)
|
||||
break;
|
||||
case O_NUMBER:
|
||||
printopt = opt_desc(pendopt);
|
||||
*(pendopt->ovar) = getnumc(&s, printopt, NULL);
|
||||
getnumc(&s, printopt, (pendopt->otype & O_NEGOK) != 0, pendopt->ovar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -179,14 +178,20 @@ public void scan_option(constant char *s, lbool is_env)
|
||||
* Not a special case.
|
||||
* Look up the option letter in the option table.
|
||||
*/
|
||||
ambig = FALSE;
|
||||
if (optname == NULL)
|
||||
{
|
||||
printopt = propt(optc);
|
||||
lc = ASCII_IS_LOWER(optc);
|
||||
o = findopt(optc);
|
||||
if (o == NULL)
|
||||
{
|
||||
parg.p_string = printopt;
|
||||
error("There is no %s option (\"less --help\" for help)", &parg);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
{
|
||||
lbool ambig = FALSE;
|
||||
printopt = optname;
|
||||
lc = ASCII_IS_LOWER(optname[0]);
|
||||
o = findopt_name(&optname, NULL, &ambig);
|
||||
@@ -208,7 +213,7 @@ public void scan_option(constant char *s, lbool is_env)
|
||||
(o->otype & OTYPE) != O_NUMBER)
|
||||
{
|
||||
parg.p_string = printopt;
|
||||
error("The %s option should not be followed by =",
|
||||
error("The --%s option should not be followed by =",
|
||||
&parg);
|
||||
return;
|
||||
}
|
||||
@@ -221,17 +226,15 @@ public void scan_option(constant char *s, lbool is_env)
|
||||
*/
|
||||
o = NULL;
|
||||
}
|
||||
}
|
||||
if (o == NULL)
|
||||
{
|
||||
parg.p_string = printopt;
|
||||
if (ambig)
|
||||
error("%s is an ambiguous abbreviation (\"less --help\" for help)",
|
||||
&parg);
|
||||
else
|
||||
error("There is no %s option (\"less --help\" for help)",
|
||||
&parg);
|
||||
return;
|
||||
if (o == NULL)
|
||||
{
|
||||
parg.p_string = printopt;
|
||||
if (ambig)
|
||||
error("--%s is an ambiguous abbreviation (\"less --help\" for help)", &parg);
|
||||
else
|
||||
error("There is no --%s option (\"less --help\" for help)", &parg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
str = NULL;
|
||||
@@ -292,7 +295,7 @@ public void scan_option(constant char *s, lbool is_env)
|
||||
}
|
||||
if (o->otype & O_UNSUPPORTED)
|
||||
break;
|
||||
*(o->ovar) = getnumc(&s, printopt, NULL);
|
||||
getnumc(&s, printopt, (o->otype & O_NEGOK) != 0, o->ovar);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
@@ -314,11 +317,9 @@ public void scan_option(constant char *s, lbool is_env)
|
||||
* OPT_UNSET set to the default value
|
||||
* OPT_SET set to the inverse of the default value
|
||||
*/
|
||||
public void toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle)
|
||||
public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle)
|
||||
{
|
||||
int num;
|
||||
int no_prompt;
|
||||
lbool err;
|
||||
PARG parg;
|
||||
|
||||
no_prompt = (how_toggle & OPT_NO_PROMPT);
|
||||
@@ -327,21 +328,21 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
|
||||
if (o == NULL)
|
||||
{
|
||||
error("No such option", NULL_PARG);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (how_toggle == OPT_TOGGLE && (o->otype & O_NO_TOGGLE))
|
||||
{
|
||||
parg.p_string = opt_desc(o);
|
||||
error("Cannot change the %s option", &parg);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (how_toggle == OPT_NO_TOGGLE && (o->otype & O_NO_QUERY))
|
||||
{
|
||||
parg.p_string = opt_desc(o);
|
||||
error("Cannot query the %s option", &parg);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -426,7 +427,7 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
|
||||
case OPT_UNSET:
|
||||
error("Cannot use \"-+\" or \"-!\" for a string option",
|
||||
NULL_PARG);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case O_NUMBER:
|
||||
@@ -436,9 +437,8 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
|
||||
switch (how_toggle)
|
||||
{
|
||||
case OPT_TOGGLE:
|
||||
num = getnumc(&s, NULL, &err);
|
||||
if (!err)
|
||||
*(o->ovar) = num;
|
||||
if (!getnumc(&s, opt_desc(o), (o->otype & O_NEGOK) != 0, o->ovar))
|
||||
return FALSE;
|
||||
break;
|
||||
case OPT_UNSET:
|
||||
*(o->ovar) = o->odefault;
|
||||
@@ -446,7 +446,7 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
|
||||
case OPT_SET:
|
||||
error("Can't use \"-!\" for a numeric option",
|
||||
NULL_PARG);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -488,15 +488,15 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
|
||||
error(o->odesc[1], &parg);
|
||||
break;
|
||||
case O_STRING:
|
||||
/*
|
||||
* Message was already printed by the handling function.
|
||||
*/
|
||||
if (how_toggle != OPT_NO_TOGGLE && o->ofunc != NULL)
|
||||
(*o->ofunc)(QUERY, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (how_toggle != OPT_NO_TOGGLE && (o->otype & O_REPAINT))
|
||||
screen_trashed();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -513,20 +513,20 @@ static int flip_triple(int val, lbool lc)
|
||||
/*
|
||||
* Determine if an option takes a parameter.
|
||||
*/
|
||||
public int opt_has_param(struct loption *o)
|
||||
public lbool opt_has_param(constant struct loption *o)
|
||||
{
|
||||
if (o == NULL)
|
||||
return (0);
|
||||
return FALSE;
|
||||
if (o->otype & (O_BOOL|O_TRIPLE|O_NOVAR|O_NO_TOGGLE))
|
||||
return (0);
|
||||
return (1);
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the prompt to be used for a given option letter.
|
||||
* Only string and number valued options have prompts.
|
||||
*/
|
||||
public constant char * opt_prompt(struct loption *o)
|
||||
public constant char * opt_prompt(constant struct loption *o)
|
||||
{
|
||||
if (o == NULL || (o->otype & (O_STRING|O_NUMBER)) == 0)
|
||||
return ("?");
|
||||
@@ -653,26 +653,29 @@ static constant char * optstring(constant char *s, char **p_str, constant char *
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
static int num_error(constant char *printopt, lbool *errp, lbool overflow)
|
||||
{
|
||||
PARG parg;
|
||||
typedef enum {
|
||||
NUM_ERR_NONE, NUM_ERR_OVERFLOW, NUM_ERR_NEG, NUM_ERR_MISSING
|
||||
} num_error_type;
|
||||
|
||||
if (errp != NULL)
|
||||
{
|
||||
*errp = TRUE;
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
* Display error message for invalid number.
|
||||
*/
|
||||
static lbool num_error(constant char *printopt, num_error_type error_type)
|
||||
{
|
||||
if (printopt != NULL)
|
||||
{
|
||||
constant char *msg;
|
||||
PARG parg;
|
||||
switch (error_type)
|
||||
{
|
||||
case NUM_ERR_OVERFLOW: msg = "Number too large in %s"; break;
|
||||
case NUM_ERR_NEG: msg = "Negative number not allowed in %s"; break;
|
||||
default: msg = "Number is required after %s"; break;
|
||||
}
|
||||
parg.p_string = printopt;
|
||||
error((overflow
|
||||
? "Number too large in '%s'"
|
||||
: "Number is required after %s"),
|
||||
&parg);
|
||||
error(msg, &parg);
|
||||
}
|
||||
return (-1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -680,38 +683,38 @@ static int num_error(constant char *printopt, lbool *errp, lbool overflow)
|
||||
* Like atoi(), but takes a pointer to a char *, and updates
|
||||
* the char * to point after the translated number.
|
||||
*/
|
||||
public int getnumc(constant char **sp, constant char *printopt, lbool *errp)
|
||||
public lbool getnumc(constant char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num)
|
||||
{
|
||||
constant char *s = *sp;
|
||||
int n;
|
||||
lbool neg;
|
||||
lbool neg = FALSE;
|
||||
|
||||
s = skipspc(s);
|
||||
neg = FALSE;
|
||||
if (*s == '-')
|
||||
{
|
||||
if (!neg_ok)
|
||||
return num_error(printopt, NUM_ERR_NEG);
|
||||
neg = TRUE;
|
||||
s++;
|
||||
}
|
||||
if (*s < '0' || *s > '9')
|
||||
return (num_error(printopt, errp, FALSE));
|
||||
|
||||
return num_error(printopt, NUM_ERR_MISSING);
|
||||
n = lstrtoic(s, sp, 10);
|
||||
if (n < 0)
|
||||
return (num_error(printopt, errp, TRUE));
|
||||
if (errp != NULL)
|
||||
*errp = FALSE;
|
||||
return num_error(printopt, NUM_ERR_OVERFLOW);
|
||||
if (neg)
|
||||
n = -n;
|
||||
return (n);
|
||||
*p_num = n;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public int getnum(char **sp, constant char *printopt, lbool *errp)
|
||||
public lbool getnum(char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num)
|
||||
{
|
||||
constant char *cs = *sp;
|
||||
int r = getnumc(&cs, printopt, errp);
|
||||
if (!getnumc(&cs, printopt, neg_ok, p_num))
|
||||
return FALSE;
|
||||
*sp = (char *) cs;
|
||||
return r;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -720,7 +723,7 @@ public int getnum(char **sp, constant char *printopt, lbool *errp)
|
||||
* The value of the fraction is returned as parts per NUM_FRAC_DENOM.
|
||||
* That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM.
|
||||
*/
|
||||
public long getfraction(constant char **sp, constant char *printopt, lbool *errp)
|
||||
public lbool getfraction(constant char **sp, mutable long *p_frac)
|
||||
{
|
||||
constant char *s;
|
||||
long frac = 0;
|
||||
@@ -728,7 +731,7 @@ public long getfraction(constant char **sp, constant char *printopt, lbool *errp
|
||||
|
||||
s = skipspc(*sp);
|
||||
if (*s < '0' || *s > '9')
|
||||
return (num_error(printopt, errp, FALSE));
|
||||
return FALSE;
|
||||
|
||||
for ( ; *s >= '0' && *s <= '9'; s++)
|
||||
{
|
||||
@@ -740,9 +743,8 @@ public long getfraction(constant char **sp, constant char *printopt, lbool *errp
|
||||
while (fraclen++ < NUM_LOG_FRAC_DENOM)
|
||||
frac *= 10;
|
||||
*sp = s;
|
||||
if (errp != NULL)
|
||||
*errp = FALSE;
|
||||
return (frac);
|
||||
*p_frac = frac;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -24,6 +24,7 @@
|
||||
#define O_NO_QUERY 0400 /* Option cannot be queried with "_" cmd */
|
||||
#define O_INIT_HANDLER 01000 /* Call option handler function at startup */
|
||||
#define O_UNSUPPORTED 02000 /* Option is unsupported via LESS_UNSUPPORT */
|
||||
#define O_NEGOK 04000 /* O_NUMBER parameter may be negative */
|
||||
|
||||
#define OTYPE (O_BOOL|O_TRIPLE|O_NUMBER|O_STRING|O_NOVAR)
|
||||
|
||||
|
||||
+60
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -40,6 +40,7 @@ public int ctldisp; /* Send control chars to screen untranslated */
|
||||
public int force_open; /* Open the file even if not regular file */
|
||||
public int swindow; /* Size of scrolling window */
|
||||
public int jump_sline; /* Screen line of "jump target" */
|
||||
public int jump_sline_arg;
|
||||
public long jump_sline_fraction = -1;
|
||||
public int shift_count; /* Number of positions to shift horizontally */
|
||||
public long shift_count_fraction = -1;
|
||||
@@ -49,6 +50,7 @@ public int no_init; /* Disable sending ti/te termcap strings */
|
||||
public int no_keypad; /* Disable sending ks/ke termcap strings */
|
||||
public int twiddle; /* Show tildes after EOF */
|
||||
public int show_attn; /* Hilite first unread line */
|
||||
public int hilite_target; /* Hilite target line */
|
||||
public int status_col; /* Display a status column */
|
||||
public int use_lessopen; /* Use the LESSOPEN filter */
|
||||
public int quit_on_intr; /* Quit on interrupt */
|
||||
@@ -58,7 +60,9 @@ public int opt_use_backslash; /* Use backslash escaping in option parsing */
|
||||
public LWCHAR rscroll_char; /* Char which marks chopped lines with -S */
|
||||
public int rscroll_attr; /* Attribute of rscroll_char */
|
||||
public int no_hist_dups; /* Remove dups from history list */
|
||||
public int mousecap; /* Allow mouse for scrolling */
|
||||
public int emouse; /* Enabled mouse features */
|
||||
public int mouse_reverse; /* Reverse mouse wheel scrolling direction */
|
||||
public int xmouse; /* Old --mouse option, replaced by --emouse */
|
||||
public int wheel_lines; /* Number of lines to scroll on mouse wheel scroll */
|
||||
public int perma_marks; /* Save marks in history file */
|
||||
public int linenum_width; /* Width of line numbers */
|
||||
@@ -84,9 +88,12 @@ public int match_shift; /* Extra horizontal shift on search match */
|
||||
public int no_paste; /* Don't accept pasted input */
|
||||
public int no_edit_warn; /* Don't warn when editing a LESSOPENed file */
|
||||
public int stop_on_form_feed; /* Stop scrolling on a line starting with form feed */
|
||||
public int past_eof; /* Continue scrolling past EOF */
|
||||
public long match_shift_fraction = NUM_FRAC_DENOM/2; /* 1/2 of screen width */
|
||||
public char intr_char = CONTROL('X'); /* Char to interrupt reads */
|
||||
public char *first_cmd_at_prompt = NULL; /* Command to exec before first prompt */
|
||||
public char *autosave; /* Actions which do autosave of history file */
|
||||
public char *end_prompt; /* Printed after clearing the prompt */
|
||||
#if HILITE_SEARCH
|
||||
public int hilite_search; /* Highlight matched search patterns? */
|
||||
#endif
|
||||
@@ -155,7 +162,9 @@ static struct optname follow_optname = { "follow-name", NULL };
|
||||
static struct optname use_backslash_optname = { "use-backslash", NULL };
|
||||
static struct optname rscroll_optname = { "rscroll", NULL };
|
||||
static struct optname nohistdups_optname = { "no-histdups", NULL };
|
||||
static struct optname mousecap_optname = { "mouse", NULL };
|
||||
static struct optname mouse_optname = { "mouse", NULL };
|
||||
static struct optname emouse_optname = { "emouse", NULL };
|
||||
static struct optname mouse_reverse_optname = { "rmouse", NULL };
|
||||
static struct optname wheel_lines_optname = { "wheel-lines", NULL };
|
||||
static struct optname perma_marks_optname = { "save-marks", NULL };
|
||||
static struct optname linenum_width_optname = { "line-num-width", NULL };
|
||||
@@ -167,6 +176,7 @@ static struct optname status_line_optname = { "status-line", NULL };
|
||||
static struct optname header_optname = { "header", NULL };
|
||||
static struct optname no_paste_optname = { "no-paste", NULL };
|
||||
static struct optname form_feed_optname = { "form-feed", NULL };
|
||||
static struct optname past_eof_optname = { "past-eof", NULL };
|
||||
static struct optname no_edit_warn_optname2 = { "no-warn-edit", NULL };
|
||||
static struct optname no_edit_warn_optname = { "no-edit-warn", &no_edit_warn_optname2 };
|
||||
static struct optname nonum_headers_optname = { "no-number-headers", NULL };
|
||||
@@ -186,6 +196,9 @@ static struct optname proc_tab_optname = { "proc-tab", NULL };
|
||||
static struct optname proc_return_optname = { "proc-return", NULL };
|
||||
static struct optname match_shift_optname = { "match-shift", NULL };
|
||||
static struct optname first_cmd_at_prompt_optname = { "cmd", NULL };
|
||||
static struct optname autosave_optname = { "autosave", NULL };
|
||||
static struct optname hilite_target_optname = { "hilite-target", NULL };
|
||||
static struct optname end_prompt_optname = { "end-prompt", NULL };
|
||||
#if LESSTEST
|
||||
static struct optname ttyin_name_optname = { "tty", NULL };
|
||||
#endif /*LESSTEST*/
|
||||
@@ -436,6 +449,14 @@ static struct loption option[] =
|
||||
O_NOVAR, 0, NULL, opt__V,
|
||||
{ NULL, NULL, NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &hilite_target_optname,
|
||||
O_BOOL, OPT_OFF, &hilite_target, opt_hilite_target,
|
||||
{
|
||||
"Don't highlight target line",
|
||||
"Highlight target line",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{ 'w', &w_optname,
|
||||
O_TRIPLE|O_REPAINT, OPT_OFF, &show_attn, NULL,
|
||||
{
|
||||
@@ -469,7 +490,7 @@ static struct loption option[] =
|
||||
}
|
||||
},
|
||||
{ 'z', &z_optname,
|
||||
O_NUMBER, -1, &swindow, NULL,
|
||||
O_NUMBER|O_NEGOK, -1, &swindow, NULL,
|
||||
{
|
||||
"Scroll window size: ",
|
||||
"Scroll window size is %d lines",
|
||||
@@ -527,8 +548,8 @@ static struct loption option[] =
|
||||
{ OLETTER_NONE, &use_backslash_optname,
|
||||
O_BOOL, OPT_OFF, &opt_use_backslash, NULL,
|
||||
{
|
||||
"Use backslash escaping in command line parameters",
|
||||
"Don't use backslash escaping in command line parameters",
|
||||
"Use backslash escaping in command line parameters",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
@@ -544,12 +565,24 @@ static struct loption option[] =
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &mousecap_optname,
|
||||
O_TRIPLE, OPT_OFF, &mousecap, opt_mousecap,
|
||||
{ OLETTER_NONE, &mouse_optname,
|
||||
O_TRIPLE, OPT_OFF, &xmouse, opt_mouse,
|
||||
{
|
||||
"Ignore mouse input",
|
||||
"Use the mouse for scrolling",
|
||||
"Use the mouse for scrolling (reverse)"
|
||||
"Use the mouse for scrolling vertically",
|
||||
"Use the mouse for scrolling vertically (reverse)"
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &emouse_optname,
|
||||
O_STRING, 0, NULL, opt_emouse,
|
||||
{ "Mouse features: ", "s", NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &mouse_reverse_optname,
|
||||
O_BOOL, OPT_OFF, &mouse_reverse, NULL,
|
||||
{
|
||||
"Normal mouse scroll direction",
|
||||
"Reverse mouse scroll direction",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &wheel_lines_optname,
|
||||
@@ -611,8 +644,8 @@ static struct loption option[] =
|
||||
{ OLETTER_NONE, &status_line_optname,
|
||||
O_BOOL|O_REPAINT, OPT_OFF, &status_line, NULL,
|
||||
{
|
||||
"Don't color each line with its status column color",
|
||||
"Color each line with its status column color",
|
||||
"Line highlight applies to text only",
|
||||
"Line highlight applies to entire width of screen",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
@@ -636,6 +669,14 @@ static struct loption option[] =
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &past_eof_optname,
|
||||
O_BOOL, OPT_OFF, &past_eof, NULL,
|
||||
{
|
||||
"Stop scrolling at end of file",
|
||||
"Don't stop scrolling at end of file",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &no_edit_warn_optname,
|
||||
O_BOOL, OPT_OFF, &no_edit_warn, NULL,
|
||||
{
|
||||
@@ -762,6 +803,14 @@ static struct loption option[] =
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &autosave_optname,
|
||||
O_STRING|O_INIT_HANDLER, 0, NULL, opt_autosave,
|
||||
{ "Autosave actions: ", "s", NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &end_prompt_optname,
|
||||
O_STRING, 0, NULL, opt_end_prompt,
|
||||
{ "Print after prompt: ", "s", NULL }
|
||||
},
|
||||
#if LESSTEST
|
||||
{ OLETTER_NONE, &ttyin_name_optname,
|
||||
O_STRING|O_NO_TOGGLE, 0, NULL, opt_ttyin_name,
|
||||
|
||||
+59
-45
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -80,9 +80,7 @@ static lbool any_data = FALSE;
|
||||
static lbool reading;
|
||||
static lbool opening;
|
||||
public lbool waiting_for_data;
|
||||
public int consecutive_nulls = 0;
|
||||
public lbool getting_one_screen = FALSE;
|
||||
public lbool no_poll = FALSE;
|
||||
|
||||
/* Milliseconds to wait for data before displaying "waiting for data" message. */
|
||||
static int waiting_for_data_delay = 4000;
|
||||
@@ -93,18 +91,18 @@ static JUMP_BUF read_label;
|
||||
static JUMP_BUF open_label;
|
||||
|
||||
extern int sigs;
|
||||
extern int ignore_eoi;
|
||||
extern lbool ignore_eoi;
|
||||
extern int exit_F_on_close;
|
||||
extern int follow_mode;
|
||||
extern int scanning_eof;
|
||||
extern char intr_char;
|
||||
extern int is_tty;
|
||||
extern lbool is_tty;
|
||||
extern int quit_if_one_screen;
|
||||
extern int one_screen;
|
||||
extern lbool one_screen;
|
||||
#if HAVE_TIME
|
||||
extern time_type less_start_time;
|
||||
#endif
|
||||
#if !MSDOS_COMPILER
|
||||
#if LESS_IREAD_TTY
|
||||
extern int tty;
|
||||
#endif
|
||||
|
||||
@@ -164,8 +162,6 @@ static int check_poll(int fd, int tty)
|
||||
/* Break out of "waiting for data". */
|
||||
return (READ_INTR);
|
||||
ungetcc_back((char) ch);
|
||||
if (!no_poll)
|
||||
return (READ_INTR);
|
||||
}
|
||||
}
|
||||
if (ignore_eoi && exit_F_on_close && (poller[0].revents & (POLLHUP|POLLIN)) == POLLHUP)
|
||||
@@ -198,6 +194,7 @@ public lbool ttyin_ready(void)
|
||||
if (!use_poll)
|
||||
return FALSE;
|
||||
{
|
||||
/* {{ assert LESS_IREAD_TTY }} */
|
||||
struct pollfd poller[1] = { { tty, POLLIN, 0 } };
|
||||
poll(poller, 1, 0);
|
||||
return ((poller[0].revents & POLLIN) != 0);
|
||||
@@ -209,7 +206,7 @@ public lbool ttyin_ready(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
public int supports_ctrl_x(void)
|
||||
public lbool supports_ctrl_x(void)
|
||||
{
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
return (TRUE);
|
||||
@@ -269,7 +266,7 @@ start:
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if !MSDOS_COMPILER
|
||||
#if !MSDOS_COMPILER /* {{ LESS_IREAD_TTY? }} */
|
||||
if (fd != tty && !ABORT_SIGS())
|
||||
/* Non-interrupt signal like SIGWINCH. */
|
||||
return (READ_AGAIN);
|
||||
@@ -307,51 +304,36 @@ start:
|
||||
if (ret != 0)
|
||||
{
|
||||
if (ret == READ_INTR)
|
||||
{
|
||||
sigs |= S_SWINTERRUPT;
|
||||
getcc_clear();
|
||||
}
|
||||
reading = FALSE;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
if (!(quit_if_one_screen && one_screen) && win32_kbhit2(TRUE))
|
||||
if (!(quit_if_one_screen && one_screen))
|
||||
{
|
||||
int c;
|
||||
lbool intr;
|
||||
|
||||
c = WIN32getch();
|
||||
intr = (c == CONTROL('C') || c == intr_char);
|
||||
if (!intr)
|
||||
WIN32ungetch((char) c);
|
||||
if (intr || !no_poll)
|
||||
char c;
|
||||
if (win32_kbhit2(&c))
|
||||
{
|
||||
sigs |= S_SWINTERRUPT;
|
||||
reading = FALSE;
|
||||
return (READ_INTR);
|
||||
if (c == CONTROL('C') || c == intr_char)
|
||||
{
|
||||
sigs |= S_SWINTERRUPT;
|
||||
reading = FALSE;
|
||||
win32_clear_queue();
|
||||
return (READ_INTR);
|
||||
}
|
||||
win32_enqueue((int) c);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
n = read(fd, buf, len);
|
||||
reading = FALSE;
|
||||
#if 0
|
||||
/*
|
||||
* This is a kludge to workaround a problem on some systems
|
||||
* where terminating a remote tty connection causes read() to
|
||||
* start returning 0 forever, instead of -1.
|
||||
*/
|
||||
{
|
||||
if (!ignore_eoi)
|
||||
{
|
||||
if (n == 0)
|
||||
consecutive_nulls++;
|
||||
else
|
||||
consecutive_nulls = 0;
|
||||
if (consecutive_nulls > 20)
|
||||
quit(QUIT_ERROR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
#if HAVE_ERRNO
|
||||
@@ -369,10 +351,13 @@ start:
|
||||
#endif
|
||||
return (READ_ERR);
|
||||
}
|
||||
#if USE_POLL
|
||||
if (fd != tty && n > 0)
|
||||
any_data = TRUE;
|
||||
#if LESS_IREAD_TTY
|
||||
if (fd != tty)
|
||||
#endif
|
||||
{
|
||||
if (n > 0)
|
||||
polling_ok();
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
|
||||
@@ -418,6 +403,16 @@ public void intio(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We can start polling the input file.
|
||||
*/
|
||||
public void polling_ok(void)
|
||||
{
|
||||
#if USE_POLL
|
||||
any_data = TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the current time.
|
||||
*/
|
||||
@@ -548,7 +543,7 @@ char * strchr(char *s, char c)
|
||||
#endif
|
||||
|
||||
#if !HAVE_MEMCPY
|
||||
void * memcpy(void *dst, void *src, size_t len)
|
||||
void * memcpy(void *dst, constant void *src, size_t len)
|
||||
{
|
||||
char *dstp = (char *) dst;
|
||||
char *srcp = (char *) src;
|
||||
@@ -560,6 +555,25 @@ void * memcpy(void *dst, void *src, size_t len)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAVE_STRSTR
|
||||
char * strstr(constant char *haystack, constant char *needle)
|
||||
{
|
||||
if (*needle == '\0')
|
||||
return (char *) haystack;
|
||||
for (; *haystack; haystack++) {
|
||||
constant char *h = haystack;
|
||||
constant char *n = needle;
|
||||
while (*h != '\0' && *n != '\0' && *h == *n) {
|
||||
h++;
|
||||
n++;
|
||||
}
|
||||
if (*n == '\0')
|
||||
return (char *) haystack;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _OSK_MWC32
|
||||
|
||||
/*
|
||||
|
||||
+65
-39
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -21,17 +21,22 @@
|
||||
#endif
|
||||
|
||||
public int errmsgs; /* Count of messages displayed by error() */
|
||||
public int need_clr;
|
||||
public int final_attr;
|
||||
public int at_prompt;
|
||||
public lbool prompting = FALSE;
|
||||
static lbool need_clr = FALSE;
|
||||
|
||||
extern int sigs;
|
||||
extern int sc_width;
|
||||
extern int so_s_width, so_e_width;
|
||||
extern int is_tty;
|
||||
extern lbool is_tty;
|
||||
extern int oldbot;
|
||||
extern int utf_mode;
|
||||
extern int status_col;
|
||||
extern int status_line;
|
||||
extern int hilite_target;
|
||||
extern int use_color;
|
||||
extern char intr_char;
|
||||
extern lbool term_init_ever;
|
||||
extern int pr_type;
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
|
||||
extern int ctldisp;
|
||||
@@ -49,11 +54,13 @@ extern int vt_enabled;
|
||||
/*
|
||||
* Display the line which is in the line buffer.
|
||||
*/
|
||||
public void put_line(lbool forw_scroll)
|
||||
public void put_line_hilite(lbool forw_scroll, lbool target)
|
||||
{
|
||||
int c;
|
||||
size_t i;
|
||||
int a;
|
||||
lbool empty_line = TRUE;
|
||||
constant int target_attr = use_color ? AT_COLOR_TARGET : AT_UNDERLINE;
|
||||
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
@@ -64,12 +71,27 @@ public void put_line(lbool forw_scroll)
|
||||
return;
|
||||
}
|
||||
|
||||
final_attr = AT_NORMAL;
|
||||
|
||||
for (i = 0; (c = gline(i, &a)) != '\0'; i++)
|
||||
{
|
||||
if (target && a == AT_NORMAL)
|
||||
{
|
||||
/* We're highlighting this line as the target line. Highlight
|
||||
* this char if it's not already highlighted, and either we're
|
||||
* highlighting the whole line or we're highlighting only the
|
||||
* status column and this is the status column. */
|
||||
if ((status_col && i == 0) ||
|
||||
(i >= line_pfx_width() && (status_line || !status_col)))
|
||||
a = target_attr;
|
||||
}
|
||||
if (target && (c == '\n' || c == '\r') && empty_line)
|
||||
{
|
||||
/* Line is empty; add a space to carry the target hilite. */
|
||||
at_switch(target_attr);
|
||||
putchr(' ');
|
||||
}
|
||||
if (!(a & AT_ANSI))
|
||||
empty_line = FALSE;
|
||||
at_switch(a);
|
||||
final_attr = a;
|
||||
if (c == '\b')
|
||||
putbs();
|
||||
else
|
||||
@@ -81,10 +103,15 @@ public void put_line(lbool forw_scroll)
|
||||
clear_eol();
|
||||
}
|
||||
|
||||
public void put_line(lbool forw_scroll)
|
||||
{
|
||||
put_line_hilite(forw_scroll, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* win_flush has at least one non-critical issue when an escape sequence
|
||||
* begins at the last char of the buffer, and possibly more issues.
|
||||
* as a temporary measure to reduce likelyhood of encountering end-of-buffer
|
||||
* as a temporary measure to reduce likelihood of encountering end-of-buffer
|
||||
* issues till the SGR parser is replaced, OUTBUF_SIZE is 8K on Windows.
|
||||
*/
|
||||
static char obuf[OUTBUF_SIZE];
|
||||
@@ -435,17 +462,19 @@ public void flush(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (write(outfd, obuf, n) != n)
|
||||
if (write(outfd, obuf, n) != (ssize_t) n)
|
||||
screen_trashed();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the output file descriptor (1=stdout or 2=stderr).
|
||||
*/
|
||||
public void set_output(int fd)
|
||||
public void set_output(int fd, lbool no_term_init)
|
||||
{
|
||||
flush();
|
||||
outfd = fd;
|
||||
if (no_term_init)
|
||||
term_init_ever = TRUE; /* don't init terminal in putchr */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -455,25 +484,23 @@ public void set_output(int fd)
|
||||
public int putchr(int ch)
|
||||
{
|
||||
char c = (char) ch;
|
||||
#if 0 /* fake UTF-8 output for testing */
|
||||
extern int utf_mode;
|
||||
if (utf_mode)
|
||||
|
||||
/*
|
||||
* Init the terminal if this is the first byte written to stdout
|
||||
* (rather than stderr), and the terminal has never been initted.
|
||||
* If it has previously been initted, it will be reinitted explicitly
|
||||
* as part of a term_deinit/term_init pair, so we shouldn't do it here.
|
||||
*/
|
||||
if (!term_init_ever && outfd == 1)
|
||||
term_init();
|
||||
if (prompting)
|
||||
{
|
||||
static char ubuf[MAX_UTF_CHAR_LEN];
|
||||
static int ubuf_len = 0;
|
||||
static int ubuf_index = 0;
|
||||
if (ubuf_len == 0)
|
||||
{
|
||||
ubuf_len = utf_len(c);
|
||||
ubuf_index = 0;
|
||||
}
|
||||
ubuf[ubuf_index++] = c;
|
||||
if (ubuf_index < ubuf_len)
|
||||
return c;
|
||||
c = get_wchar(ubuf) & 0xFF;
|
||||
ubuf_len = 0;
|
||||
constant char *epr = end_pr_string();
|
||||
prompting = FALSE;
|
||||
if (epr != NULL)
|
||||
putstr(epr);
|
||||
}
|
||||
#endif
|
||||
|
||||
clear_bot_if_needed();
|
||||
#if MSDOS_COMPILER
|
||||
if (c == '\n' && is_tty)
|
||||
@@ -494,7 +521,6 @@ public int putchr(int ch)
|
||||
if (ob >= &obuf[sizeof(obuf)-1])
|
||||
flush();
|
||||
*ob++ = c;
|
||||
at_prompt = 0;
|
||||
return (c);
|
||||
}
|
||||
|
||||
@@ -502,7 +528,7 @@ public void clear_bot_if_needed(void)
|
||||
{
|
||||
if (!need_clr)
|
||||
return;
|
||||
need_clr = 0;
|
||||
need_clr = FALSE;
|
||||
clear_bot();
|
||||
}
|
||||
|
||||
@@ -590,7 +616,7 @@ IPRINT_FUNC(iprint_linenum, LINENUM, linenumtoa)
|
||||
* {{ This paranoia about the portability of printf dates from experiences
|
||||
* with systems in the 1980s and is of course no longer necessary. }}
|
||||
*/
|
||||
public int less_printf(constant char *fmt, PARG *parg)
|
||||
public int less_printf(constant char *fmt, constant PARG *parg)
|
||||
{
|
||||
constant char *s;
|
||||
constant char *es;
|
||||
@@ -664,7 +690,7 @@ public void get_return(void)
|
||||
|
||||
#if ONLY_RETURN
|
||||
while ((c = getchr()) != '\n' && c != '\r')
|
||||
bell();
|
||||
lbell();
|
||||
#else
|
||||
c = getchr();
|
||||
if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
|
||||
@@ -676,7 +702,7 @@ public void get_return(void)
|
||||
* Output a message in the lower left corner of the screen
|
||||
* and wait for carriage return.
|
||||
*/
|
||||
public void error(constant char *fmt, PARG *parg)
|
||||
public void error(constant char *fmt, constant PARG *parg)
|
||||
{
|
||||
int col = 0;
|
||||
static char return_to_continue[] = " (press RETURN)";
|
||||
@@ -722,7 +748,7 @@ public void error(constant char *fmt, PARG *parg)
|
||||
* Usually used to warn that we are beginning a potentially
|
||||
* time-consuming operation.
|
||||
*/
|
||||
static void ierror_suffix(constant char *fmt, PARG *parg, constant char *suffix1, constant char *suffix2, constant char *suffix3)
|
||||
static void ierror_suffix(constant char *fmt, constant PARG *parg, constant char *suffix1, constant char *suffix2, constant char *suffix3)
|
||||
{
|
||||
at_exit();
|
||||
clear_bot();
|
||||
@@ -733,15 +759,15 @@ static void ierror_suffix(constant char *fmt, PARG *parg, constant char *suffix1
|
||||
putstr(suffix3);
|
||||
at_exit();
|
||||
flush();
|
||||
need_clr = 1;
|
||||
need_clr = TRUE;
|
||||
}
|
||||
|
||||
public void ierror(constant char *fmt, PARG *parg)
|
||||
public void ierror(constant char *fmt, constant PARG *parg)
|
||||
{
|
||||
ierror_suffix(fmt, parg, "... (interrupt to abort)", "", "");
|
||||
}
|
||||
|
||||
public void ixerror(constant char *fmt, PARG *parg)
|
||||
public void ixerror(constant char *fmt, constant PARG *parg)
|
||||
{
|
||||
if (!supports_ctrl_x())
|
||||
ierror(fmt, parg);
|
||||
@@ -757,7 +783,7 @@ public void ixerror(constant char *fmt, PARG *parg)
|
||||
* Output a message in the lower left corner of the screen
|
||||
* and return a single-character response.
|
||||
*/
|
||||
public int query(constant char *fmt, PARG *parg)
|
||||
public int query(constant char *fmt, constant PARG *parg)
|
||||
{
|
||||
int c;
|
||||
int col = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -147,7 +147,11 @@ public int compile_pattern(constant char *pattern, int search_type, int show_err
|
||||
{
|
||||
int result;
|
||||
|
||||
if (caseless != OPT_ONPLUS || (re_handles_caseless && !(search_type & SRCH_NO_REGEX)))
|
||||
#if RE_HANDLES_CASELESS
|
||||
if (caseless != OPT_ONPLUS || (!(search_type & SRCH_NO_REGEX)))
|
||||
#else
|
||||
if (caseless != OPT_ONPLUS)
|
||||
#endif
|
||||
{
|
||||
result = compile_pattern2(pattern, search_type, comp_pattern, show_error);
|
||||
} else
|
||||
@@ -391,7 +395,7 @@ static lbool match_pattern1(PATTERN_TYPE pattern, constant char *tpattern, const
|
||||
#if HAVE_PCRE2
|
||||
{
|
||||
int flags = (notbol) ? PCRE2_NOTBOL : 0;
|
||||
pcre2_match_data *md = pcre2_match_data_create(nsp-1, NULL);
|
||||
pcre2_match_data *md = pcre2_match_data_create_from_pattern(pattern, NULL);
|
||||
int mcount = pcre2_match(pattern, (PCRE2_SPTR)line, line_len,
|
||||
line_off, flags, md, NULL);
|
||||
matched = (mcount > 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -25,7 +25,7 @@ extern int less_is_more;
|
||||
#endif
|
||||
#define PATTERN_TYPE regex_t *
|
||||
#define SET_NULL_PATTERN(name) name = NULL
|
||||
#define re_handles_caseless TRUE
|
||||
#define RE_HANDLES_CASELESS 1
|
||||
#endif
|
||||
|
||||
/* ---- PCRE ---- */
|
||||
@@ -33,7 +33,7 @@ extern int less_is_more;
|
||||
#include <pcre.h>
|
||||
#define PATTERN_TYPE pcre *
|
||||
#define SET_NULL_PATTERN(name) name = NULL
|
||||
#define re_handles_caseless TRUE
|
||||
#define RE_HANDLES_CASELESS 1
|
||||
#endif
|
||||
|
||||
/* ---- PCRE2 ---- */
|
||||
@@ -42,7 +42,7 @@ extern int less_is_more;
|
||||
#include <pcre2.h>
|
||||
#define PATTERN_TYPE pcre2_code *
|
||||
#define SET_NULL_PATTERN(name) name = NULL
|
||||
#define re_handles_caseless TRUE
|
||||
#define RE_HANDLES_CASELESS 1
|
||||
#endif
|
||||
|
||||
/* ---- RE_COMP ---- */
|
||||
@@ -76,6 +76,6 @@ extern int reg_show_error;
|
||||
#define SET_NULL_PATTERN(name)
|
||||
#endif
|
||||
|
||||
#ifndef re_handles_caseless
|
||||
#define re_handles_caseless FALSE
|
||||
#ifndef RE_HANDLES_CASELESS
|
||||
#define RE_HANDLES_CASELESS 0
|
||||
#endif
|
||||
+26
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -13,21 +13,28 @@
|
||||
* Special (non-ASCII) keys on the PC send a two-byte sequence,
|
||||
* where the first byte is 0 and the second is as defined below.
|
||||
*/
|
||||
#define PCK_SHIFT_TAB '\017'
|
||||
#define PCK_ALT_E '\022'
|
||||
#define PCK_CAPS_LOCK '\072'
|
||||
#define PCK_F1 '\073'
|
||||
#define PCK_NUM_LOCK '\105'
|
||||
#define PCK_HOME '\107'
|
||||
#define PCK_UP '\110'
|
||||
#define PCK_PAGEUP '\111'
|
||||
#define PCK_LEFT '\113'
|
||||
#define PCK_RIGHT '\115'
|
||||
#define PCK_END '\117'
|
||||
#define PCK_DOWN '\120'
|
||||
#define PCK_PAGEDOWN '\121'
|
||||
#define PCK_INSERT '\122'
|
||||
#define PCK_DELETE '\123'
|
||||
#define PCK_CTL_LEFT '\163'
|
||||
#define PCK_CTL_RIGHT '\164'
|
||||
#define PCK_CTL_DELETE '\223'
|
||||
#define PCK_SHIFT_TAB '\x0f'
|
||||
#define PCK_ALT_E '\x12'
|
||||
#define PCK_CAPS_LOCK '\x3a'
|
||||
#define PCK_F1 '\x3b'
|
||||
#define PCK_NUM_LOCK '\x45'
|
||||
#define PCK_HOME '\x47'
|
||||
#define PCK_UP '\x48'
|
||||
#define PCK_PAGEUP '\x49'
|
||||
#define PCK_LEFT '\x4b'
|
||||
#define PCK_RIGHT '\x4d'
|
||||
#define PCK_END '\x4f'
|
||||
#define PCK_DOWN '\x50'
|
||||
#define PCK_PAGEDOWN '\x51'
|
||||
#define PCK_INSERT '\x52'
|
||||
#define PCK_DELETE '\x53'
|
||||
/* The following are nonstandard and internal to less. */
|
||||
#define PCK_SHIFT_END '\x61'
|
||||
#define PCK_CTL_DELETE '\x62'
|
||||
#define PCK_CTL_LEFT '\x63'
|
||||
#define PCK_CTL_RIGHT '\x74'
|
||||
#define PCK_CTL_HOME '\x7a'
|
||||
#define PCK_CTL_END '\x7c'
|
||||
#define PCK_SHIFT_HOME '\x7d'
|
||||
#define PCK_SHIFT_LEFT '\x73'
|
||||
#define PCK_SHIFT_RIGHT '\x7f'
|
||||
+57
-35
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -147,19 +147,19 @@ public int onscreen(POSITION pos)
|
||||
/*
|
||||
* See if the entire screen is empty.
|
||||
*/
|
||||
public int empty_screen(void)
|
||||
public lbool empty_screen(void)
|
||||
{
|
||||
return (empty_lines(0, sc_height-1));
|
||||
}
|
||||
|
||||
public int empty_lines(int s, int e)
|
||||
public lbool empty_lines(int s, int e)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = s; i <= e; i++)
|
||||
if (table[i] != NULL_POSITION && table[i] != 0)
|
||||
return (0);
|
||||
return (1);
|
||||
if (table[i] != NULL_POSITION)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -170,7 +170,7 @@ public int empty_lines(int s, int e)
|
||||
* such that the top few lines are empty, we may have to set
|
||||
* the screen line to a number > 0.
|
||||
*/
|
||||
public void get_scrpos(struct scrpos *scrpos, int where)
|
||||
public void get_scrpos_pos(struct scrpos *scrpos, int where, POSITION pos)
|
||||
{
|
||||
int i;
|
||||
int dir;
|
||||
@@ -194,24 +194,52 @@ public void get_scrpos(struct scrpos *scrpos, int where)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first line on the screen which has something on it,
|
||||
* and return the screen line number and the file position.
|
||||
*/
|
||||
for (;; i += dir)
|
||||
if (pos != NULL_POSITION)
|
||||
{
|
||||
if (table[i] != NULL_POSITION)
|
||||
scrpos->ln = i+1;
|
||||
scrpos->pos = pos;
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* Find the first line on the screen which has something on it,
|
||||
* and return the screen line number and the file position.
|
||||
*/
|
||||
for (;; i += dir)
|
||||
{
|
||||
scrpos->ln = i+1;
|
||||
scrpos->pos = table[i];
|
||||
return;
|
||||
if (table[i] != NULL_POSITION)
|
||||
{
|
||||
scrpos->ln = i+1;
|
||||
scrpos->pos = table[i];
|
||||
return;
|
||||
}
|
||||
if (i == last) break;
|
||||
}
|
||||
if (i == last) break;
|
||||
/* The screen is empty. */
|
||||
scrpos->pos = NULL_POSITION;
|
||||
}
|
||||
}
|
||||
|
||||
public void get_scrpos(struct scrpos *scrpos, int where)
|
||||
{
|
||||
get_scrpos_pos(scrpos, where, NULL_POSITION);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert sline to sindex and clip to screen size.
|
||||
*/
|
||||
static int sindex_from_sline_clipped(int sline)
|
||||
{
|
||||
/*
|
||||
* The screen is empty.
|
||||
* Can't be less than 1 or greater than sc_height-1.
|
||||
*/
|
||||
scrpos->pos = NULL_POSITION;
|
||||
if (sline <= 0)
|
||||
sline = 1;
|
||||
if (sline >= sc_height)
|
||||
sline = sc_height-1;
|
||||
/*
|
||||
* Return zero-based line number, not one-based.
|
||||
*/
|
||||
return (sline-1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -231,17 +259,7 @@ public int sindex_from_sline(int sline)
|
||||
*/
|
||||
if (sline < 0)
|
||||
sline += sc_height;
|
||||
/*
|
||||
* Can't be less than 1 or greater than sc_height.
|
||||
*/
|
||||
if (sline <= 0)
|
||||
sline = 1;
|
||||
if (sline > sc_height)
|
||||
sline = sc_height;
|
||||
/*
|
||||
* Return zero-based line number, not one-based.
|
||||
*/
|
||||
return (sline-1);
|
||||
return sindex_from_sline_clipped(sline);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -273,12 +291,14 @@ static int pos_shift(POSITION linepos, size_t choff)
|
||||
* Return the position of the first char of the line containing tpos.
|
||||
* Thus if tpos is the first char of its line, just return tpos.
|
||||
*/
|
||||
static POSITION beginning_of_line(POSITION tpos)
|
||||
public POSITION beginning_of_line(POSITION tpos)
|
||||
{
|
||||
ch_seek(tpos);
|
||||
while (ch_tell() != ch_zero())
|
||||
{
|
||||
int ch = ch_back_get();
|
||||
if (ch == EOI)
|
||||
break; /* {{ probably unnecessary due to ch_zero() check }} */
|
||||
if (ch == '\n')
|
||||
{
|
||||
(void) ch_forw_get();
|
||||
@@ -291,10 +311,11 @@ static POSITION beginning_of_line(POSITION tpos)
|
||||
/*
|
||||
* When viewing long lines, it may be that the first char in the top screen
|
||||
* line is not the first char in its (file) line (the table is "beheaded").
|
||||
* This function sets that entry to the position of the first char in the line,
|
||||
* and sets hshift so that the first char in the first line is unchanged.
|
||||
* This function sets that entry to the position of the first char in the
|
||||
* line, and optionally sets hshift so that the first char in the first line
|
||||
* is unchanged.
|
||||
*/
|
||||
public void pos_rehead(void)
|
||||
public void pos_rehead(lbool adj_hshift)
|
||||
{
|
||||
POSITION linepos;
|
||||
POSITION tpos = table[TOP];
|
||||
@@ -304,6 +325,7 @@ public void pos_rehead(void)
|
||||
if (linepos == tpos)
|
||||
return;
|
||||
table[TOP] = linepos;
|
||||
hshift = pos_shift(linepos, (size_t) (tpos - linepos));
|
||||
if (adj_hshift)
|
||||
hshift = pos_shift(linepos, (size_t) (tpos - linepos));
|
||||
screen_trashed();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+56
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -24,6 +24,7 @@ extern int pr_type;
|
||||
extern lbool new_file;
|
||||
extern int linenums;
|
||||
extern int hshift;
|
||||
extern int sc_width;
|
||||
extern int sc_height;
|
||||
extern int jump_sline;
|
||||
extern int less_is_more;
|
||||
@@ -31,7 +32,7 @@ extern int header_lines;
|
||||
extern int utf_mode;
|
||||
extern IFILE curr_ifile;
|
||||
#if OSC8_LINK
|
||||
extern char *osc8_path;
|
||||
extern POSITION osc8_linepos;
|
||||
#endif
|
||||
#if EDITOR
|
||||
extern constant char *editor;
|
||||
@@ -47,9 +48,9 @@ static constant char s_proto[] =
|
||||
static constant char m_proto[] =
|
||||
"?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t";
|
||||
static constant char M_proto[] =
|
||||
"?f%f .?n?m(%T %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t";
|
||||
"?f%f .?n?m(%T %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..?c (column %c).%t";
|
||||
static constant char e_proto[] =
|
||||
"?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t";
|
||||
"?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..?c (column %c).%t";
|
||||
static constant char h_proto[] =
|
||||
"HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done";
|
||||
static constant char w_proto[] =
|
||||
@@ -58,12 +59,14 @@ static constant char more_proto[] =
|
||||
"--More--(?eEND ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t)";
|
||||
|
||||
public char *prproto[3];
|
||||
public char *eprproto[3];
|
||||
public char constant *eqproto = e_proto;
|
||||
public char constant *hproto = h_proto;
|
||||
public char constant *wproto = w_proto;
|
||||
|
||||
static char message[PROMPT_SIZE];
|
||||
static char *mp;
|
||||
static int longest_line;
|
||||
|
||||
/*
|
||||
* Initialize the prompt prototype strings.
|
||||
@@ -73,11 +76,24 @@ public void init_prompt(void)
|
||||
prproto[0] = save(s_proto);
|
||||
prproto[1] = save(less_is_more ? more_proto : m_proto);
|
||||
prproto[2] = save(M_proto);
|
||||
eprproto[0] = eprproto[1] = eprproto[2] = NULL;
|
||||
eqproto = save(e_proto);
|
||||
hproto = save(h_proto);
|
||||
wproto = save(w_proto);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get width of longest line currently on screen.
|
||||
* Calling longest_line_width() is expensive, so we cache its value here
|
||||
* in case it is called more than once per prompt expansion.
|
||||
*/
|
||||
static int pr_longest_line(void)
|
||||
{
|
||||
if (longest_line < 0)
|
||||
longest_line = longest_line_width();
|
||||
return longest_line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a string to the end of the message.
|
||||
* nprt means the character *may* be nonprintable
|
||||
@@ -226,6 +242,12 @@ static lbool cond(char c, int where)
|
||||
return (ntags() ? TRUE : new_file ? TRUE : FALSE);
|
||||
#else
|
||||
return (new_file ? TRUE : FALSE);
|
||||
#endif
|
||||
case 'O': /* OSC 8 link selected? */
|
||||
#if OSC8_LINK
|
||||
return (osc8_linepos != NULL_POSITION);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
case 'p': /* Percent into file (bytes) known? */
|
||||
return (curr_byte(where) != NULL_POSITION && ch_length() > 0);
|
||||
@@ -233,6 +255,8 @@ static lbool cond(char c, int where)
|
||||
return (currline(where) != 0 &&
|
||||
(len = ch_length()) > 0 &&
|
||||
find_linenum(len) != 0);
|
||||
case 'Q': /* Any on-screen line truncated? */
|
||||
return (hshift + sc_width < pr_longest_line());
|
||||
case 's': /* Size of file known? */
|
||||
case 'B':
|
||||
return (ch_length() != NULL_POSITION);
|
||||
@@ -275,7 +299,10 @@ static void protochar(char c, int where)
|
||||
ap_quest();
|
||||
break;
|
||||
case 'c':
|
||||
ap_int(hshift);
|
||||
ap_int(hshift+1);
|
||||
break;
|
||||
case 'C':
|
||||
ap_int(hshift + sc_width);
|
||||
break;
|
||||
case 'd': /* Current page number */
|
||||
linenum = currline(where);
|
||||
@@ -349,14 +376,6 @@ static void protochar(char c, int where)
|
||||
#endif
|
||||
ap_int(nifile());
|
||||
break; }
|
||||
case 'o': /* path (URI without protocol) of selected OSC8 link */
|
||||
#if OSC8_LINK
|
||||
if (osc8_path != NULL)
|
||||
ap_str(osc8_path);
|
||||
else
|
||||
#endif
|
||||
ap_quest();
|
||||
break;
|
||||
case 'p': /* Percent into file (bytes) */
|
||||
pos = curr_byte(where);
|
||||
len = ch_length();
|
||||
@@ -374,6 +393,9 @@ static void protochar(char c, int where)
|
||||
else
|
||||
ap_int(percentage(linenum, last_linenum));
|
||||
break;
|
||||
case 'Q': /* Percent shifted horizontally */
|
||||
ap_int(percentage(hshift + sc_width, pr_longest_line()));
|
||||
break;
|
||||
case 's': /* Size of file */
|
||||
case 'B':
|
||||
len = ch_length();
|
||||
@@ -395,6 +417,9 @@ static void protochar(char c, int where)
|
||||
#endif
|
||||
ap_str("file");
|
||||
break;
|
||||
case 'W': /* Width of longest line on screen */
|
||||
ap_int(pr_longest_line());
|
||||
break;
|
||||
case 'x': /* Name of next file */
|
||||
h = next_ifile(curr_ifile);
|
||||
if (h != NULL_IFILE)
|
||||
@@ -496,11 +521,12 @@ public constant char * pr_expand(constant char *proto)
|
||||
char c;
|
||||
int where;
|
||||
|
||||
mp = message;
|
||||
|
||||
if (*proto == '\0')
|
||||
return ("");
|
||||
|
||||
mp = message;
|
||||
longest_line = -1;
|
||||
|
||||
for (p = proto; *p != '\0'; p++)
|
||||
{
|
||||
switch (*p)
|
||||
@@ -572,6 +598,21 @@ public constant char * pr_string(void)
|
||||
return (prompt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the end prompt string.
|
||||
*/
|
||||
public constant char * end_pr_string(void)
|
||||
{
|
||||
int type;
|
||||
|
||||
if (ch_getflags() & CH_HELPFILE)
|
||||
return NULL;
|
||||
type = (!less_is_more) ? pr_type : pr_type ? 0 : 1;
|
||||
if (eprproto[type] == NULL)
|
||||
return NULL;
|
||||
return pr_expand(eprproto[type]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a message suitable for printing while waiting in the F command.
|
||||
*/
|
||||
|
||||
+147
-59
@@ -25,6 +25,8 @@
|
||||
* *** NOTE: this code has been altered slightly for use in Tcl. ***
|
||||
* Slightly modified by David MacKenzie to undo most of the changes for TCL.
|
||||
* Added regexec2 with notbol parameter. -- 4/19/99 Mark Nudelman
|
||||
* Change functions style from K&R to C89 -- 2023-09 Avi Halachmi
|
||||
* Add support for character classes [:NAME:] -- 2026-02 Avi Halachmi
|
||||
*/
|
||||
|
||||
#include "less.h"
|
||||
@@ -47,16 +49,13 @@
|
||||
* regstart char that must begin a match; '\0' if none obvious
|
||||
* reganch is the match anchored (at beginning-of-line only)?
|
||||
* regmust string (pointer into program) that match must include, or NULL
|
||||
* regmlen length of regmust string
|
||||
*
|
||||
* Regstart and reganch permit very fast decisions on suitable starting points
|
||||
* for a match, cutting down the work a lot. Regmust permits fast rejection
|
||||
* of lines that cannot possibly match. The regmust tests are costly enough
|
||||
* that regcomp() supplies a regmust only if the r.e. contains something
|
||||
* potentially expensive (at present, the only such thing detected is * or +
|
||||
* at the start of the r.e., which can involve a lot of backup). Regmlen is
|
||||
* supplied because the test in regexec() needs it and regcomp() is
|
||||
* computing it anyway.
|
||||
* at the start of the r.e., which can involve a lot of backup).
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -251,7 +250,6 @@ regcomp(constant char *exp)
|
||||
r->regstart = '\0'; /* Worst-case defaults. */
|
||||
r->reganch = 0;
|
||||
r->regmust = NULL;
|
||||
r->regmlen = 0;
|
||||
scan = r->program+1; /* First BRANCH. */
|
||||
if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
|
||||
scan = OPERAND(scan);
|
||||
@@ -276,10 +274,10 @@ regcomp(constant char *exp)
|
||||
for (; scan != NULL; scan = regnext(scan))
|
||||
if (OP(scan) == EXACTLY && ((int) strlen(OPERAND(scan))) >= len) {
|
||||
longest = OPERAND(scan);
|
||||
/* redundant strlen, not critical in regcomp */
|
||||
len = (int) strlen(OPERAND(scan));
|
||||
}
|
||||
r->regmust = longest;
|
||||
r->regmlen = len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,6 +456,126 @@ regpiece(int *flagp)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handling of character classes [:NAME:]
|
||||
*
|
||||
* - We only cover C/POSIX locale (ASCII).
|
||||
* - We identify the 12 POSIX classes.
|
||||
* - We error on unknown [:THING:].
|
||||
* - [=EQUIV=] or [.COLLATE.] are NOT detected, and considered non-special.
|
||||
* - [:NAME:] errors on either side of '-' range (but not if the '-' is
|
||||
* literal - at the beginning or end of the [...]).
|
||||
* - The logic is confined to regbracket(), and only used during regcomp.
|
||||
*
|
||||
* POSIX regex, classes, collation, etc:
|
||||
* https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html
|
||||
* https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap07.html
|
||||
*/
|
||||
|
||||
typedef struct cclass {
|
||||
constant size_t len; /* of id */
|
||||
constant char *id;
|
||||
constant char *chars;
|
||||
} cclass;
|
||||
|
||||
static constant cclass cclasses[] = {
|
||||
/* first two chars of id are ignored, and expected to be "[:" */
|
||||
{9, "[:alnum:]", "0-9A-Za-z"},
|
||||
{9, "[:alpha:]", "A-Za-z"},
|
||||
{9, "[:blank:]", "\t "},
|
||||
{9, "[:cntrl:]", "\x01-\x1f\x7f"},
|
||||
{9, "[:digit:]", "0-9"},
|
||||
{9, "[:graph:]", "\x21-\x7e"},
|
||||
{9, "[:lower:]", "a-z"},
|
||||
{9, "[:print:]", "\x20-\x7e"},
|
||||
{9, "[:punct:]", "!-/:-@[-`{|}~"},
|
||||
{9, "[:space:]", "\t\n\v\f\r "},
|
||||
{9, "[:upper:]", "A-Z"},
|
||||
{10, "[:xdigit:]", "0-9A-Fa-f"},
|
||||
};
|
||||
|
||||
/* returns index>=0 in cclasses if s starts with known [:NAME:],
|
||||
* else -2 on error (s starts with unknown [:THING:]),
|
||||
* else -1 (not-special).
|
||||
*
|
||||
* we could create a wrapper macro which tests '[' and ':' before
|
||||
* calling cclass_idx(s) - to avoid a function call on early abort,
|
||||
* and/or replace the string search in cclass_idx with binary search
|
||||
* or something else, but this is not hot code, so keep it simple.
|
||||
*/
|
||||
static int
|
||||
cclass_idx(constant char *s)
|
||||
{
|
||||
int i;
|
||||
constant char *p;
|
||||
|
||||
if (*s++ != '[' || *s++ != ':')
|
||||
return -1;
|
||||
|
||||
/* s is past the "[:" prefix */
|
||||
for (i = 0; i < countof(cclasses); ++i)
|
||||
if (strncmp(s, cclasses[i].id + 2, cclasses[i].len - 2) == 0)
|
||||
return i; /* found */
|
||||
|
||||
p = strchr(s, ']');
|
||||
if (p && p != s && p[-1] == ':')
|
||||
return -2; /* unrecognized [:THING:] */
|
||||
|
||||
return -1; /* not special as far as we can tell */
|
||||
}
|
||||
|
||||
/* Calls regc(c) for each char which a bracket expression matches,
|
||||
* without touching the global regparse.
|
||||
*
|
||||
* The caller should ensure that ANYOF or ANYBUT node was already added
|
||||
* (depending on whether it starts with "[" or "[^"), and "in" should
|
||||
* point to the first data char after this prefix.
|
||||
*
|
||||
* calls FAIL(...) and returns NULL on failure,
|
||||
* or returns a pointer to the first unprocessed char (']' or '\0').
|
||||
* the caller may then update the global regparse, and add final regc(0).
|
||||
*/
|
||||
static constant char *
|
||||
regbracket(constant char *in)
|
||||
{
|
||||
register int clss;
|
||||
register int classend;
|
||||
int idx;
|
||||
|
||||
if (*in == ']' || *in == '-')
|
||||
regc(*in++);
|
||||
while (*in != '\0' && *in != ']') {
|
||||
if (*in == '-') {
|
||||
in++;
|
||||
if (cclass_idx(in) != -1)
|
||||
FAIL("invalid [] range end"); /* X-[:NAME:] */
|
||||
if (*in == ']' || *in == '\0')
|
||||
regc('-');
|
||||
else {
|
||||
clss = UCHARAT(in-2)+1;
|
||||
classend = UCHARAT(in);
|
||||
if (clss > classend+1)
|
||||
FAIL("invalid [] range");
|
||||
for (; clss <= classend; clss++)
|
||||
regc(clss);
|
||||
in++;
|
||||
}
|
||||
} else if ((idx = cclass_idx(in)) == -1) {
|
||||
regc(*in++);
|
||||
} else if (idx == -2) {
|
||||
FAIL("unknown [:CLASS:] name");
|
||||
} else { /* idx is a valid index, add class chars */
|
||||
if (regbracket(cclasses[idx].chars) == NULL)
|
||||
return(NULL); /* should be unreachable */
|
||||
in += cclasses[idx].len;
|
||||
|
||||
if (*in == '-' && in[1] != '\0' && in[1] != ']')
|
||||
FAIL("invalid [] range start"); /* [:NAME:]-X */
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
/*
|
||||
- regatom - the lowest level
|
||||
*
|
||||
@@ -485,40 +603,22 @@ regatom(int *flagp)
|
||||
ret = regnode(ANY);
|
||||
*flagp |= HASWIDTH|SIMPLE;
|
||||
break;
|
||||
case '[': {
|
||||
register int clss;
|
||||
register int classend;
|
||||
|
||||
if (*regparse == '^') { /* Complement of range. */
|
||||
ret = regnode(ANYBUT);
|
||||
regparse++;
|
||||
} else
|
||||
ret = regnode(ANYOF);
|
||||
if (*regparse == ']' || *regparse == '-')
|
||||
regc(*regparse++);
|
||||
while (*regparse != '\0' && *regparse != ']') {
|
||||
if (*regparse == '-') {
|
||||
regparse++;
|
||||
if (*regparse == ']' || *regparse == '\0')
|
||||
regc('-');
|
||||
else {
|
||||
clss = UCHARAT(regparse-2)+1;
|
||||
classend = UCHARAT(regparse);
|
||||
if (clss > classend+1)
|
||||
FAIL("invalid [] range");
|
||||
for (; clss <= classend; clss++)
|
||||
regc(clss);
|
||||
regparse++;
|
||||
}
|
||||
} else
|
||||
regc(*regparse++);
|
||||
}
|
||||
regc('\0');
|
||||
if (*regparse != ']')
|
||||
FAIL("unmatched []");
|
||||
case '[':
|
||||
if (*regparse == '^') { /* Complement of range. */
|
||||
ret = regnode(ANYBUT);
|
||||
regparse++;
|
||||
*flagp |= HASWIDTH|SIMPLE;
|
||||
}
|
||||
} else
|
||||
ret = regnode(ANYOF);
|
||||
|
||||
regparse = regbracket(regparse);
|
||||
if (regparse == NULL)
|
||||
return(NULL);
|
||||
|
||||
regc('\0');
|
||||
if (*regparse != ']')
|
||||
FAIL("unmatched []");
|
||||
regparse++;
|
||||
*flagp |= HASWIDTH|SIMPLE;
|
||||
break;
|
||||
case '(':
|
||||
ret = reg(1, &flags);
|
||||
@@ -701,8 +801,7 @@ STATIC int regrepeat(char *);
|
||||
|
||||
#ifdef DEBUG
|
||||
int regnarrate = 0;
|
||||
void regdump();
|
||||
STATIC char *regprop();
|
||||
STATIC constant char *regprop(constant char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -726,16 +825,8 @@ regexec2(register regexp *prog, register constant char *string, int notbol)
|
||||
}
|
||||
|
||||
/* If there is a "must appear" string, look for it. */
|
||||
if (prog->regmust != NULL) {
|
||||
s = string;
|
||||
while ((s = strchr(s, prog->regmust[0])) != NULL) {
|
||||
if (strncmp(s, prog->regmust, prog->regmlen) == 0)
|
||||
break; /* Found it. */
|
||||
s++;
|
||||
}
|
||||
if (s == NULL) /* Not present. */
|
||||
return(0);
|
||||
}
|
||||
if (prog->regmust != NULL && strstr(string, prog->regmust) == NULL)
|
||||
return(0); /* Not present. */
|
||||
|
||||
/* Mark beginning of line for ^ . */
|
||||
if (notbol)
|
||||
@@ -1068,14 +1159,11 @@ regnext(register char *p)
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
STATIC char *regprop();
|
||||
|
||||
/*
|
||||
- regdump - dump a regexp onto stdout in vaguely comprehensible form
|
||||
*/
|
||||
void
|
||||
regdump(r)
|
||||
regexp *r;
|
||||
regdump(regexp *r)
|
||||
{
|
||||
register char *s;
|
||||
register char op = EXACTLY; /* Arbitrary non-END op. */
|
||||
@@ -1085,12 +1173,13 @@ regexp *r;
|
||||
s = r->program + 1;
|
||||
while (op != END) { /* While that wasn't END last time... */
|
||||
op = OP(s);
|
||||
printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
|
||||
/* prints ADDRESS:... where the ":..." is from regprop(s) */
|
||||
printf("%2ld%s", (long)(s - r->program), regprop(s));
|
||||
next = regnext(s);
|
||||
if (next == NULL) /* Next ptr. */
|
||||
printf("(0)");
|
||||
else
|
||||
printf("(%d)", (s-r->program)+(next-s));
|
||||
printf("(%ld)", (long)((s - r->program)+(next-s)));
|
||||
s += 3;
|
||||
if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
|
||||
/* Literal string, where present. */
|
||||
@@ -1117,8 +1206,7 @@ regexp *r;
|
||||
- regprop - printable representation of opcode
|
||||
*/
|
||||
static constant char *
|
||||
regprop(op)
|
||||
constant char *op;
|
||||
regprop(constant char *op)
|
||||
{
|
||||
register char *p;
|
||||
static char buf[50];
|
||||
|
||||
@@ -15,7 +15,6 @@ typedef struct regexp {
|
||||
char regstart; /* Internal use only. */
|
||||
char reganch; /* Internal use only. */
|
||||
char *regmust; /* Internal use only. */
|
||||
int regmlen; /* Internal use only. */
|
||||
char program[1]; /* Unwarranted chumminess with compiler. */
|
||||
} regexp;
|
||||
|
||||
@@ -31,4 +30,8 @@ extern int regexec2 _ANSI_ARGS_((regexp *prog, constant char *string, int notbol
|
||||
extern void regsub _ANSI_ARGS_((regexp *prog, constant char *source, char *dest));
|
||||
extern void regerror _ANSI_ARGS_((constant char *msg));
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void regdump _ANSI_ARGS_((regexp *r));
|
||||
#endif
|
||||
|
||||
#endif /* REGEXP */
|
||||
+446
-172
File diff suppressed because it is too large.
Load diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
||||
+97
-64
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -29,6 +29,8 @@ extern int proc_backspace;
|
||||
extern int proc_return;
|
||||
extern int ctldisp;
|
||||
extern int status_col;
|
||||
extern int status_line;
|
||||
extern int hilite_target;
|
||||
extern void *ml_search;
|
||||
extern POSITION start_attnpos;
|
||||
extern POSITION end_attnpos;
|
||||
@@ -63,7 +65,6 @@ public POSITION osc8_uri_start = NULL_POSITION;
|
||||
public POSITION osc8_uri_end = NULL_POSITION;
|
||||
public POSITION osc8_text_start = NULL_POSITION;
|
||||
public POSITION osc8_text_end = NULL_POSITION;
|
||||
char *osc8_path = NULL;
|
||||
char *osc8_uri = NULL;
|
||||
constant char *osc8_search_param = NULL;
|
||||
#endif
|
||||
@@ -230,8 +231,13 @@ public int get_cvt_ops(int search_type)
|
||||
{
|
||||
int ops = 0;
|
||||
|
||||
if (is_caseless && (!re_handles_caseless || (search_type & SRCH_NO_REGEX)))
|
||||
#if RE_HANDLES_CASELESS
|
||||
if (is_caseless && (search_type & SRCH_NO_REGEX))
|
||||
ops |= CVT_TO_LC;
|
||||
#else
|
||||
if (is_caseless)
|
||||
ops |= CVT_TO_LC;
|
||||
#endif
|
||||
if (proc_backspace == OPT_ON || (bs_mode == BS_SPECIAL && proc_backspace == OPT_OFF))
|
||||
ops |= CVT_BS;
|
||||
if (proc_return == OPT_ON || (bs_mode != BS_CONTROL && proc_backspace == OPT_OFF))
|
||||
@@ -253,6 +259,14 @@ static lbool prev_pattern(struct pattern_info *info)
|
||||
return (info->text != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return text of previous search pattern.
|
||||
*/
|
||||
public constant char* prev_pattern_text(void)
|
||||
{
|
||||
return search_info.text;
|
||||
}
|
||||
|
||||
#if HILITE_SEARCH
|
||||
/*
|
||||
* Repaint the hilites currently displayed on the screen.
|
||||
@@ -299,6 +313,27 @@ public void repaint_hilite(lbool on)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Redraw the jump target line with the attn hilite on or off.
|
||||
*/
|
||||
public void draw_target_attn(lbool hilite)
|
||||
{
|
||||
int sindex;
|
||||
POSITION pos;
|
||||
|
||||
if (!can_goto_line) /* {{ Are there any such terminals any more? }} */
|
||||
return;
|
||||
if (squished)
|
||||
return;
|
||||
sindex = sindex_from_sline(jump_sline);
|
||||
pos = position(sindex);
|
||||
forw_line_seg(pos, chop_line() || hshift > 0, TRUE, FALSE, hilite && status_line, FALSE, NULL, NULL);
|
||||
goto_line(sindex);
|
||||
clear_eol();
|
||||
put_line_hilite(TRUE, hilite);
|
||||
lower_left();
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the attn hilite.
|
||||
*/
|
||||
@@ -312,6 +347,9 @@ public void clear_attn(void)
|
||||
POSITION epos;
|
||||
int moved = 0;
|
||||
|
||||
if (hilite_target)
|
||||
draw_target_attn(FALSE);
|
||||
|
||||
if (start_attnpos == NULL_POSITION)
|
||||
return;
|
||||
old_start_attnpos = start_attnpos;
|
||||
@@ -354,32 +392,37 @@ public void clear_attn(void)
|
||||
*/
|
||||
public void undo_search(lbool clear)
|
||||
{
|
||||
clear_pattern(&search_info);
|
||||
undo_osc8();
|
||||
#if HILITE_SEARCH
|
||||
lbool osc8_active = undo_osc8();
|
||||
lbool has_pattern = prev_pattern(&search_info);
|
||||
if (clear)
|
||||
{
|
||||
clear_pattern(&search_info);
|
||||
clr_hilite();
|
||||
} else
|
||||
{
|
||||
if (hilite_anchor.first == NULL)
|
||||
{
|
||||
if (has_pattern)
|
||||
hide_hilite = !hide_hilite;
|
||||
else if (!osc8_active)
|
||||
error("No previous regular expression", NULL_PARG);
|
||||
return;
|
||||
}
|
||||
hide_hilite = !hide_hilite;
|
||||
}
|
||||
repaint_hilite(TRUE);
|
||||
#else
|
||||
undo_osc8();
|
||||
clear_pattern(&search_info);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
public void undo_osc8(void)
|
||||
public lbool undo_osc8(void)
|
||||
{
|
||||
lbool was_active = FALSE;
|
||||
#if OSC8_LINK
|
||||
was_active = (osc8_linepos != NULL_POSITION);
|
||||
osc8_linepos = NULL_POSITION;
|
||||
#endif
|
||||
return was_active;
|
||||
}
|
||||
|
||||
#if HILITE_SEARCH
|
||||
@@ -957,7 +1000,7 @@ static void add_hilite(struct hilite_tree *anchor, struct hilite *hl)
|
||||
*/
|
||||
static void create_hilites(POSITION linepos, constant char *line, constant char *sp, constant char *ep, int attr, int *chpos)
|
||||
{
|
||||
size_t start_index = ptr_diff(sp, line); /*{{type-issue}}*/
|
||||
size_t start_index = ptr_diff(sp, line);
|
||||
size_t end_index = ptr_diff(ep, line);
|
||||
struct hilite hl;
|
||||
size_t i;
|
||||
@@ -1813,6 +1856,7 @@ public lbool osc8_click(int sindex, int col)
|
||||
clickpos = pos_from_col(linepos, col, NULL_POSITION, -1);
|
||||
if (clickpos == NULL_POSITION)
|
||||
return FALSE;
|
||||
linepos = beginning_of_line(linepos);
|
||||
if (forw_raw_line(linepos, &line, &line_len) == NULL_POSITION)
|
||||
return FALSE;
|
||||
r = osc8_search_line(SRCH_FORW|SRCH_OSC8, linepos, line, line_len, NULL, clickpos, &matches);
|
||||
@@ -1843,18 +1887,6 @@ static size_t scheme_length(constant char *uri, size_t uri_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does a URI contain any dangerous characters?
|
||||
*/
|
||||
static lbool bad_uri(constant char *uri, size_t uri_len)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < uri_len; i++)
|
||||
if (strchr("'\"", uri[i]) != NULL)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-read the line containing the selected OSC8 link.
|
||||
*/
|
||||
@@ -1885,10 +1917,11 @@ public void osc8_open(void)
|
||||
char env_name[64];
|
||||
size_t scheme_len;
|
||||
constant char *handler;
|
||||
char *open_cmd;
|
||||
char *cmd;
|
||||
char *uri_q;
|
||||
size_t uri_len;
|
||||
FILE *hf;
|
||||
static constant char *env_name_pfx = "LESS_OSC8_";
|
||||
char *p;
|
||||
static constant char *env_name_pfx = "LESS_OSC8_OPEN_";
|
||||
|
||||
if (osc8_linepos == NULL_POSITION)
|
||||
{
|
||||
@@ -1901,9 +1934,8 @@ public void osc8_open(void)
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Read a "handler" shell cmd from environment variable "LESS_OSC8_scheme".
|
||||
* pr_expand the handler cmd (to expand %o -> osc8_path) and execute it.
|
||||
* Handler's stdout is an "opener" shell cmd; execute opener to open the link.
|
||||
* Read a "handler" shell cmd from environment variable "LESS_OSC8_OPEN_scheme".
|
||||
* Append the URI to the handler as an argument, and execute it.
|
||||
*/
|
||||
uri_len = ptr_diff(op.uri_end, op.uri_start);
|
||||
scheme_len = scheme_length(op.uri_start, uri_len);
|
||||
@@ -1918,16 +1950,19 @@ public void osc8_open(void)
|
||||
free(param);
|
||||
return;
|
||||
}
|
||||
#if HAVE_POPEN
|
||||
if (bad_uri(op.uri_start, uri_len))
|
||||
if (scheme_len == 0)
|
||||
{
|
||||
error("Cannot open link containing quote characters", NULL_PARG);
|
||||
return;
|
||||
SNPRINTF1(env_name, sizeof(env_name), "%sNONE", env_name_pfx);
|
||||
} else
|
||||
{
|
||||
SNPRINTF3(env_name, sizeof(env_name), "%s%.*s", env_name_pfx, (int) scheme_len, op.uri_start);
|
||||
for (p = &env_name[strlen(env_name_pfx)]; *p != '\0'; p++)
|
||||
if (ASCII_IS_UPPER(*p))
|
||||
*p = ASCII_TO_LOWER(*p);
|
||||
}
|
||||
SNPRINTF3(env_name, sizeof(env_name), "%s%.*s", env_name_pfx, (int) scheme_len, op.uri_start);
|
||||
handler = lgetenv(env_name);
|
||||
if (isnullenv(handler) || strcmp(handler, "-") == 0)
|
||||
handler = lgetenv("LESS_OSC8_ANY");
|
||||
handler = lgetenv("LESS_OSC8_OPEN_ANY");
|
||||
if (isnullenv(handler))
|
||||
{
|
||||
PARG parg;
|
||||
@@ -1935,31 +1970,25 @@ public void osc8_open(void)
|
||||
error("No handler for \"%s\" link type", &parg);
|
||||
return;
|
||||
}
|
||||
/* {{ ugly global osc8_path }} */
|
||||
osc8_path = saven(op.uri_start, uri_len);
|
||||
hf = popen(pr_expand(handler), "r");
|
||||
free(osc8_path);
|
||||
osc8_path = NULL;
|
||||
if (hf == NULL)
|
||||
uri_q = shell_quoten(op.uri_start, uri_len);
|
||||
cmd = ecalloc(strlen(handler) + strlen(uri_q) + 2, sizeof(char));
|
||||
sprintf(cmd, "%s %s", handler, uri_q);
|
||||
free(uri_q);
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = env_name;
|
||||
error("Cannot execute protocol handler in %s", &parg);
|
||||
return;
|
||||
constant char *exec_cmd = cmd;
|
||||
constant char *done_msg = "link done";
|
||||
POSITION save_osc8_linepos = osc8_linepos;
|
||||
if (*exec_cmd == CONTROL('P'))
|
||||
{
|
||||
done_msg = NULL;
|
||||
exec_cmd++;
|
||||
}
|
||||
lsystem(exec_cmd, done_msg);
|
||||
/* lsystem reedits the input file which clears the selected
|
||||
* OSC8 link, so restore it. */
|
||||
osc8_linepos = save_osc8_linepos;
|
||||
}
|
||||
open_cmd = readfd(hf);
|
||||
pclose(hf);
|
||||
if (strncmp(open_cmd, ":e", 2) == 0)
|
||||
{
|
||||
edit(skipsp(&open_cmd[2]));
|
||||
} else
|
||||
{
|
||||
lsystem(open_cmd, "link done");
|
||||
}
|
||||
free(open_cmd);
|
||||
#else
|
||||
error("Cannot open link because your system does not support popen", NULL_PARG);
|
||||
#endif /* HAVE_POPEN */
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2021,15 +2050,19 @@ public void chg_caseless(void)
|
||||
* If regex handles caseless, we need to discard
|
||||
* the pattern which was compiled with the old caseless.
|
||||
*/
|
||||
if (!re_handles_caseless)
|
||||
/* We handle caseless, so the pattern doesn't change. */
|
||||
return;
|
||||
#if !RE_HANDLES_CASELESS
|
||||
/* Less handles caseless, so the pattern doesn't change. */
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Regenerate the pattern using the new state.
|
||||
*/
|
||||
clear_pattern(&search_info);
|
||||
(void) hist_pattern(search_info.search_type);
|
||||
if (prev_pattern(&search_info))
|
||||
{
|
||||
clear_pattern(&search_info);
|
||||
(void) hist_pattern(search_info.search_type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+19
-11
@@ -1,6 +1,6 @@
|
||||
#include <errno.h>
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -44,7 +44,7 @@ extern int less_is_more;
|
||||
static RETSIGTYPE u_interrupt(int type)
|
||||
{
|
||||
(void) type;
|
||||
bell();
|
||||
lbell();
|
||||
#if OS2
|
||||
LSIGNAL(SIGINT, SIG_ACK);
|
||||
#endif
|
||||
@@ -64,6 +64,7 @@ static RETSIGTYPE u_interrupt(int type)
|
||||
#if HILITE_SEARCH
|
||||
set_filter_pattern(NULL, 0);
|
||||
#endif
|
||||
polling_ok();
|
||||
intio();
|
||||
}
|
||||
#endif
|
||||
@@ -96,10 +97,10 @@ static RETSIGTYPE stop(int type)
|
||||
* "Window" change handler
|
||||
*/
|
||||
/* ARGSUSED*/
|
||||
public RETSIGTYPE winch(int type)
|
||||
public RETSIGTYPE lwinch(int type)
|
||||
{
|
||||
(void) type;
|
||||
LSIGNAL(SIG_LESSWINDOW, winch);
|
||||
LSIGNAL(SIG_LESSWINDOW, lwinch);
|
||||
#if LESSTEST
|
||||
/*
|
||||
* Ignore window changes during lesstest.
|
||||
@@ -185,10 +186,10 @@ public void init_signals(int on)
|
||||
(void) LSIGNAL(SIGTSTP, !secure_allow(SF_STOP) ? SIG_IGN : stop);
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
(void) LSIGNAL(SIGWINCH, winch);
|
||||
(void) LSIGNAL(SIGWINCH, lwinch);
|
||||
#endif
|
||||
#ifdef SIGWIND
|
||||
(void) LSIGNAL(SIGWIND, winch);
|
||||
(void) LSIGNAL(SIGWIND, lwinch);
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
(void) LSIGNAL(SIGQUIT, SIG_IGN);
|
||||
@@ -196,6 +197,9 @@ public void init_signals(int on)
|
||||
#ifdef SIGTERM
|
||||
(void) LSIGNAL(SIGTERM, terminate);
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
(void) LSIGNAL(SIGHUP, terminate);
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
(void) LSIGNAL(SIGUSR1, sigusr1);
|
||||
#endif
|
||||
@@ -224,6 +228,9 @@ public void init_signals(int on)
|
||||
#ifdef SIGTERM
|
||||
(void) LSIGNAL(SIGTERM, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
(void) LSIGNAL(SIGHUP, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
(void) LSIGNAL(SIGUSR1, SIG_DFL);
|
||||
#endif
|
||||
@@ -252,7 +259,7 @@ public void psignals(void)
|
||||
LSIGNAL(SIGTTOU, SIG_IGN);
|
||||
#endif
|
||||
clear_bot();
|
||||
deinit();
|
||||
term_deinit();
|
||||
flush();
|
||||
raw_mode(0);
|
||||
#ifdef SIGTTOU
|
||||
@@ -268,7 +275,7 @@ public void psignals(void)
|
||||
*/
|
||||
LSIGNAL(SIGTSTP, stop);
|
||||
raw_mode(1);
|
||||
init();
|
||||
term_init();
|
||||
screen_trashed();
|
||||
tsignals |= S_WINCH;
|
||||
}
|
||||
@@ -284,10 +291,7 @@ public void psignals(void)
|
||||
old_height = sc_height;
|
||||
get_term();
|
||||
if (sc_width != old_width || sc_height != old_height)
|
||||
{
|
||||
wscroll = (sc_height + 1) / 2;
|
||||
screen_size_changed();
|
||||
}
|
||||
screen_trashed();
|
||||
}
|
||||
#endif
|
||||
@@ -295,5 +299,9 @@ public void psignals(void)
|
||||
{
|
||||
if (quit_on_intr)
|
||||
quit(QUIT_INTERRUPT);
|
||||
getcc_clear();
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
win32_getch_clear();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -256,12 +256,12 @@ static enum tag_result findctag(constant char *tag)
|
||||
char *q;
|
||||
FILE *f;
|
||||
size_t taglen;
|
||||
int n;
|
||||
LINENUM taglinenum;
|
||||
char *tagfile;
|
||||
char *tagpattern;
|
||||
lbool tagendline;
|
||||
int search_char;
|
||||
lbool err;
|
||||
char tline[TAGLINE_SIZE];
|
||||
struct tag *tp;
|
||||
|
||||
@@ -321,8 +321,15 @@ static enum tag_result findctag(constant char *tag)
|
||||
* First see if it is a line number.
|
||||
*/
|
||||
tagendline = FALSE;
|
||||
taglinenum = getnum(&p, 0, &err);
|
||||
if (err)
|
||||
if (getnum(&p, NULL, FALSE, &n)) {
|
||||
/*
|
||||
* Line numbers start from 1.
|
||||
*/
|
||||
if (n == 0)
|
||||
continue;
|
||||
taglinenum = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* No, it must be a pattern.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -192,7 +192,7 @@ public int getchr(void)
|
||||
do
|
||||
{
|
||||
flush();
|
||||
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
|
||||
#if !LESS_IREAD_TTY
|
||||
/*
|
||||
* In raw read, we don't see ^C so look here for it.
|
||||
*/
|
||||
@@ -208,7 +208,7 @@ public int getchr(void)
|
||||
result = 1;
|
||||
if (c == '\003')
|
||||
return (READ_INTR);
|
||||
#else
|
||||
#else /* LESS_IREAD_TTY */
|
||||
{
|
||||
unsigned char uc;
|
||||
result = iread(tty, &uc, sizeof(char));
|
||||
@@ -274,5 +274,5 @@ public int getchr(void)
|
||||
c = '\340';
|
||||
} while (result != 1);
|
||||
|
||||
return (c & 0xFF);
|
||||
return (unsigned char) c;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Aug 19 1:16:32 GMT 2025 */
|
||||
/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Nov 28 1:30:13 GMT 2025 */
|
||||
{ 0x0000, 0x0007 }, /* Cc */
|
||||
{ 0x000b, 0x000b }, /* Cc */
|
||||
{ 0x000e, 0x001f }, /* Cc */
|
||||
|
||||
+52
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2025 Mark Nudelman
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
@@ -1061,6 +1061,56 @@ v684 9/18/25 Allow mixing of options and filenames on command line;
|
||||
add LESS_TERMCAP_SUSPEND & LESS_TERMCAP_RESUME.
|
||||
v685 10/4/25 Make --incsearch return to same column as well as same line;
|
||||
fix some problems reported by valgrind.
|
||||
v686 10/30/25 Map keypad keys; make HOME/END scroll horizontally;
|
||||
retain saved marks even if --save-marks is not specified;
|
||||
fix repaint bug with --form-feed; fix bugs passing negative
|
||||
values to cmd line options.
|
||||
v687 11/17/25 Disallow opening OSC8 link via mouse in secure mode;
|
||||
add --autosave; make SIGHUP act like SIGTERM; add ESC-f.
|
||||
v688 11/28/25 Add LESSNOCONFIG; defer "ti" until first char received;
|
||||
don't auto-bold line numbers.
|
||||
v689 12/27/25 Add prompt seqs %C, %W, %Q, ?Q; don't allow any command to
|
||||
interrupt waiting for data; fix screen resize on Windows;
|
||||
add --without-termlib.
|
||||
v690 12/31/25 Cleanup.
|
||||
v691 1/10/26 Fix mingw build.
|
||||
v692 1/29/26 Fix memory leak in setupterm; clear termio ICRNL|INLCR;
|
||||
fix bug with negative value in -z; fix bug with empty
|
||||
terminfo caps; make lesstest ignore nl_langinfo;
|
||||
revert HOME/END to g/G; add keys & cmds to lesskey parser.
|
||||
v693 2/14/26 Fix binary file with redirected stdout; fix error messages
|
||||
with redirected stdout; fix buffer overrun with malformed
|
||||
lesskey file; fix bad scrolling past EOF; fix command
|
||||
parser bugs; fix -D bug when no color specified; add -DT;
|
||||
make -w/-W hilite on backward movement; show pattern in
|
||||
"not found" message.
|
||||
v694 3/24/26 | cmd pipes 1 line if mark is top line; allow numeric arg
|
||||
on m/M cmds; support POSIX char classes with built-in regex;
|
||||
don't retry read after error; fix crash with bad tags file;
|
||||
add --past-eof; add --emouse; fix restore mark if not at top;
|
||||
don't save cleared marks.
|
||||
v695 4/3/26 Fix build if tparm doesn't use varargs; fix prompt overflow
|
||||
with & filtering; fix hilite when change -i with & filtering;
|
||||
add --end-prompt; install lessecho in libexecdir; change mark
|
||||
cmds to take file line number not screen line; add numeric
|
||||
arg to ' cmd; add %O and ?o to prompts; fix
|
||||
--show-preproc-error with some shells.
|
||||
v696 4/3/26 Doc.
|
||||
v697 4/19/26 Fix bug using PCRE2 with more than 5 parentheses; discard
|
||||
pending keys when interrupt with ^X; fix bad display with
|
||||
LESS_LINES.
|
||||
v698 4/23/26 Fix bad display after message in narrow terminal; replace
|
||||
LESS_OSC8_xxx with LESS_OSC8_OPEN_xxx; add \kpe to lesskey.
|
||||
v699 4/23/26 Add less-osc8-*.bash files to distribution.
|
||||
v700 4/30/26 Add \kpe to lesskey; improve less-osc8-* scripts.
|
||||
v701 5/13/26 Replace less-osc-*.bash with less-osc8-open.sh; don't init
|
||||
terminal if stdout is not tty; fix bug clicking OSC 8 link
|
||||
in a long line; fix misread chars on Windows; remove %O.
|
||||
v702 5/22/26 Doc.
|
||||
v703 5/30/26 Fix handling unsafe man options in OSC 8 link; fix unsafe
|
||||
handling of unterminated OSC seq; shell-escape expansion
|
||||
of % and #.
|
||||
v704 5/30/26 Fix uninstall target in Makefile.
|
||||
*/
|
||||
|
||||
char version[] = "685";
|
||||
char version[] = "704";
|
||||
+12
-11
@@ -1,4 +1,4 @@
|
||||
/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Aug 10 20:15:03 GMT 2025 */
|
||||
/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Nov 28 1:30:13 GMT 2025 */
|
||||
{ 0x1100, 0x115f }, /* W */
|
||||
{ 0x231a, 0x231b }, /* W */
|
||||
{ 0x2329, 0x232a }, /* W */
|
||||
@@ -61,10 +61,10 @@
|
||||
{ 0xff01, 0xff60 }, /* F */
|
||||
{ 0xffe0, 0xffe6 }, /* F */
|
||||
{ 0x16fe0, 0x16fe4 }, /* W */
|
||||
{ 0x16ff0, 0x16ff1 }, /* W */
|
||||
{ 0x17000, 0x187f7 }, /* W */
|
||||
{ 0x18800, 0x18cd5 }, /* W */
|
||||
{ 0x18cff, 0x18d08 }, /* W */
|
||||
{ 0x16ff0, 0x16ff6 }, /* W */
|
||||
{ 0x17000, 0x18cd5 }, /* W */
|
||||
{ 0x18cff, 0x18d1e }, /* W */
|
||||
{ 0x18d80, 0x18df2 }, /* W */
|
||||
{ 0x1aff0, 0x1aff3 }, /* W */
|
||||
{ 0x1aff5, 0x1affb }, /* W */
|
||||
{ 0x1affd, 0x1affe }, /* W */
|
||||
@@ -107,7 +107,7 @@
|
||||
{ 0x1f680, 0x1f6c5 }, /* W */
|
||||
{ 0x1f6cc, 0x1f6cc }, /* W */
|
||||
{ 0x1f6d0, 0x1f6d2 }, /* W */
|
||||
{ 0x1f6d5, 0x1f6d7 }, /* W */
|
||||
{ 0x1f6d5, 0x1f6d8 }, /* W */
|
||||
{ 0x1f6dc, 0x1f6df }, /* W */
|
||||
{ 0x1f6eb, 0x1f6ec }, /* W */
|
||||
{ 0x1f6f4, 0x1f6fc }, /* W */
|
||||
@@ -118,10 +118,11 @@
|
||||
{ 0x1f947, 0x1f9af }, /* W */
|
||||
{ 0x1f9b4, 0x1f9ff }, /* W */
|
||||
{ 0x1fa70, 0x1fa7c }, /* W */
|
||||
{ 0x1fa80, 0x1fa89 }, /* W */
|
||||
{ 0x1fa8f, 0x1fac6 }, /* W */
|
||||
{ 0x1face, 0x1fadc }, /* W */
|
||||
{ 0x1fadf, 0x1fae9 }, /* W */
|
||||
{ 0x1faf0, 0x1faf8 }, /* W */
|
||||
{ 0x1fa80, 0x1fa8a }, /* W */
|
||||
{ 0x1fa8e, 0x1fac6 }, /* W */
|
||||
{ 0x1fac8, 0x1fac8 }, /* W */
|
||||
{ 0x1facd, 0x1fadc }, /* W */
|
||||
{ 0x1fadf, 0x1faea }, /* W */
|
||||
{ 0x1faef, 0x1faf8 }, /* W */
|
||||
{ 0x20000, 0x2fffd }, /* W */
|
||||
{ 0x30000, 0x3fffd }, /* W */
|
||||
+11
-1
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
*
|
||||
* For more information, see the README file.
|
||||
*/
|
||||
|
||||
#include "less.h"
|
||||
#include "xbuf.h"
|
||||
|
||||
@@ -66,8 +75,9 @@ public void xbuf_add_char(struct xbuffer *xbuf, char c)
|
||||
/*
|
||||
* Add arbitrary data to an xbuf.
|
||||
*/
|
||||
public void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len)
|
||||
public void xbuf_add_data(struct xbuffer *xbuf, constant void *vdata, size_t len)
|
||||
{
|
||||
constant unsigned char *data = (constant unsigned char *) vdata;
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++)
|
||||
xbuf_add_byte(xbuf, data[i]);
|
||||
|
||||
+10
-1
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2026 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
*
|
||||
* For more information, see the README file.
|
||||
*/
|
||||
|
||||
#ifndef XBUF_H_
|
||||
#define XBUF_H_
|
||||
|
||||
@@ -17,7 +26,7 @@ void xbuf_deinit(struct xbuffer *xbuf);
|
||||
void xbuf_reset(struct xbuffer *xbuf);
|
||||
void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b);
|
||||
void xbuf_add_char(struct xbuffer *xbuf, char c);
|
||||
void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len);
|
||||
void xbuf_add_data(struct xbuffer *xbuf, constant void *data, size_t len);
|
||||
int xbuf_pop(struct xbuffer *xbuf);
|
||||
constant char *xbuf_char_data(constant struct xbuffer *xbuf);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Unbound is a validating, recursive, caching DNS resolver. It is designed to be
|
||||
fast and lean and incorporates modern features based on open standards. If you
|
||||
have any feedback, we would love to hear from you. Don’t hesitate to
|
||||
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
|
||||
or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
|
||||
or post a message on our [community forum](https://community.nlnetlabs.nl/).
|
||||
You can learn more about Unbound by reading our
|
||||
[documentation](https://unbound.docs.nlnetlabs.nl/).
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 31
|
||||
#serial 32
|
||||
|
||||
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
|
||||
AC_DEFUN([AX_PTHREAD], [
|
||||
@@ -249,7 +249,22 @@ AS_IF([test "x$ax_pthread_clang" = "xyes"],
|
||||
# correctly enabled
|
||||
|
||||
case $host_os in
|
||||
darwin* | hpux* | linux* | osf* | solaris*)
|
||||
solaris*)
|
||||
# Solaris 11.4 introduced XPG7 support and did away with the need for
|
||||
# _REENTRANT.
|
||||
|
||||
AC_EGREP_CPP([AX_PTHREAD_SOLARIS__REENTRANT],
|
||||
[
|
||||
# undef _XOPEN_SOURCE
|
||||
# include <sys/feature_tests.h>
|
||||
# if _XOPEN_VERSION < 700
|
||||
AX_PTHREAD_SOLARIS__REENTRANT
|
||||
# endif
|
||||
],
|
||||
[ax_pthread_check_macro="_REENTRANT"],
|
||||
[ax_pthread_check_macro="--"])
|
||||
;;
|
||||
darwin* | hpux* | linux* | osf*)
|
||||
ax_pthread_check_macro="_REENTRANT"
|
||||
;;
|
||||
|
||||
|
||||
@@ -401,6 +401,12 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
|
||||
LDNS_RCODE_YXDOMAIN)
|
||||
return 0;
|
||||
/* Do not persist data the validator has not yet seen, or has rejected.
|
||||
* Otherwise an expired blob could maybe reach clients via
|
||||
* serve-expired. */
|
||||
if(qstate->env->need_to_validate &&
|
||||
qstate->return_msg->rep->security == sec_status_bogus)
|
||||
return 0;
|
||||
/* We don't store the reply if its TTL is 0. This is probably coming
|
||||
* from upstream and it is not meant to be stored. */
|
||||
if(qstate->return_msg->rep->ttl == 0)
|
||||
@@ -863,6 +869,11 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
return;
|
||||
}
|
||||
/* No 0TTL answers escaping from external cache. */
|
||||
if(qstate->return_msg->rep->ttl == 0) {
|
||||
qstate->return_msg = NULL;
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
log_assert(qstate->return_msg->rep->ttl > 0);
|
||||
qstate->is_cachedb_answer = 1;
|
||||
/* we are done with the query */
|
||||
|
||||
@@ -20,398 +20,25 @@
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
/* Modified to use SecRandomCopyBytes. It is from macOS 10.7 (2011) and
|
||||
* iOS 2.0 (2008), and is the primary API for cryptographic random numbers. */
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/host_info.h>
|
||||
#if TARGET_OS_OSX
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#if TARGET_OS_OSX
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#endif
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c)))
|
||||
#define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
|
||||
#define SHA512_Final(xxx, yyy) (CC_SHA512_Final((xxx), (yyy)))
|
||||
#define SHA512_CTX CC_SHA512_CTX
|
||||
#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH
|
||||
|
||||
#define REPEAT 5
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define HX(a, b) \
|
||||
do { \
|
||||
if ((a)) \
|
||||
HD(errno); \
|
||||
else \
|
||||
HD(b); \
|
||||
} while (0)
|
||||
|
||||
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
|
||||
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
#include <Security/SecRandom.h>
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to get entropy with /dev/urandom
|
||||
*
|
||||
* This can fail if the process is inside a chroot or if file
|
||||
* descriptors are exhausted.
|
||||
*/
|
||||
ret = getentropy_urandom(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Entropy collection via /dev/urandom and sysctl have failed.
|
||||
*
|
||||
* No other API exists for collecting entropy, and we have
|
||||
* no failsafe way to get it on OSX that is not sensitive
|
||||
* to resource exhaustion.
|
||||
*
|
||||
* We have very few options:
|
||||
* - Even syslog_r is unsafe to call at this low level, so
|
||||
* there is no way to alert the user or program.
|
||||
* - Cannot call abort() because some systems have unsafe
|
||||
* corefiles.
|
||||
* - Could raise(SIGKILL) resulting in silent program termination.
|
||||
* - Return EIO, to hint that arc4random's stir function
|
||||
* should raise(SIGKILL)
|
||||
* - Do the best under the circumstances....
|
||||
*
|
||||
* This code path exists to bring light to the issue that OSX
|
||||
* does not provide a failsafe API for entropy collection.
|
||||
*
|
||||
* We hope this demonstrates that OSX should consider
|
||||
* providing a new failsafe API which works in a chroot or
|
||||
* when file descriptors are exhausted.
|
||||
*/
|
||||
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
|
||||
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
|
||||
raise(SIGKILL);
|
||||
#endif
|
||||
ret = getentropy_fallback(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
if (SecRandomCopyBytes(kSecRandomDefault, len, buf) == errSecSuccess) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
error:
|
||||
errno = EIO;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
struct stat st;
|
||||
size_t i;
|
||||
int fd, flags;
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
|
||||
flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
flags |= O_NOFOLLOW;
|
||||
#endif
|
||||
#ifdef O_CLOEXEC
|
||||
flags |= O_CLOEXEC;
|
||||
#endif
|
||||
fd = open("/dev/urandom", flags, 0);
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR)
|
||||
goto start;
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
/* Lightly verify that the device node looks sane */
|
||||
if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char *)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
|
||||
static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
|
||||
static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
|
||||
#endif
|
||||
static int kmib[] = { CTL_KERN, KERN_USRSTACK };
|
||||
static int hwmib[] = { CTL_HW, HW_USERMEM };
|
||||
|
||||
static int
|
||||
getentropy_fallback(void *buf, size_t len)
|
||||
{
|
||||
uint8_t results[SHA512_DIGEST_LENGTH];
|
||||
int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
|
||||
static int cnt;
|
||||
struct timespec ts;
|
||||
struct timeval tv;
|
||||
struct rusage ru;
|
||||
sigset_t sigset;
|
||||
struct stat st;
|
||||
SHA512_CTX ctx;
|
||||
static pid_t lastpid;
|
||||
pid_t pid;
|
||||
size_t i, ii, m;
|
||||
char *p;
|
||||
#if TARGET_OS_OSX
|
||||
struct tcpstat tcpstat;
|
||||
struct udpstat udpstat;
|
||||
struct ipstat ipstat;
|
||||
#endif
|
||||
u_int64_t mach_time;
|
||||
unsigned int idata;
|
||||
void *addr;
|
||||
|
||||
pid = getpid();
|
||||
if (lastpid == pid) {
|
||||
faster = 1;
|
||||
repeat = 2;
|
||||
} else {
|
||||
faster = 0;
|
||||
lastpid = pid;
|
||||
repeat = REPEAT;
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
int j;
|
||||
SHA512_Init(&ctx);
|
||||
for (j = 0; j < repeat; j++) {
|
||||
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
|
||||
if (e != -1) {
|
||||
cnt += (int)tv.tv_sec;
|
||||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
mach_time = mach_absolute_time();
|
||||
HD(mach_time);
|
||||
|
||||
ii = sizeof(addr);
|
||||
HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]),
|
||||
&addr, &ii, NULL, 0) == -1, addr);
|
||||
|
||||
ii = sizeof(idata);
|
||||
HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
|
||||
&idata, &ii, NULL, 0) == -1, idata);
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
ii = sizeof(tcpstat);
|
||||
HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
|
||||
&tcpstat, &ii, NULL, 0) == -1, tcpstat);
|
||||
|
||||
ii = sizeof(udpstat);
|
||||
HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]),
|
||||
&udpstat, &ii, NULL, 0) == -1, udpstat);
|
||||
|
||||
ii = sizeof(ipstat);
|
||||
HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
|
||||
&ipstat, &ii, NULL, 0) == -1, ipstat);
|
||||
#endif
|
||||
|
||||
HX((pid = getpid()) == -1, pid);
|
||||
HX((pid = getsid(pid)) == -1, pid);
|
||||
HX((pid = getppid()) == -1, pid);
|
||||
HX((pid = getpgid(0)) == -1, pid);
|
||||
HX((e = getpriority(0, 0)) == -1, e);
|
||||
|
||||
if (!faster) {
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
(void) nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
HX(sigpending(&sigset) == -1, sigset);
|
||||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
HD(p); /* an addr on stack */
|
||||
p = (char *)&errno;
|
||||
HD(p); /* the addr of errno */
|
||||
|
||||
if (i == 0) {
|
||||
struct sockaddr_storage ss;
|
||||
struct statvfs stvfs;
|
||||
struct termios tios;
|
||||
struct statfs stfs;
|
||||
socklen_t ssl;
|
||||
off_t off;
|
||||
|
||||
/*
|
||||
* Prime-sized mappings encourage fragmentation;
|
||||
* thus exposing some address entropy.
|
||||
*/
|
||||
struct mm {
|
||||
size_t npg;
|
||||
void *p;
|
||||
} mm[] = {
|
||||
{ 17, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 11, MAP_FAILED }, { 2, MAP_FAILED },
|
||||
{ 5, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 7, MAP_FAILED }, { 1, MAP_FAILED },
|
||||
{ 57, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 131, MAP_FAILED }, { 1, MAP_FAILED },
|
||||
};
|
||||
|
||||
for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
|
||||
HX(mm[m].p = mmap(NULL,
|
||||
mm[m].npg * pgs,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANON, -1,
|
||||
(off_t)0), mm[m].p);
|
||||
if (mm[m].p != MAP_FAILED) {
|
||||
size_t mo;
|
||||
|
||||
/* Touch some memory... */
|
||||
p = mm[m].p;
|
||||
mo = cnt %
|
||||
(mm[m].npg * pgs - 1);
|
||||
p[mo] = 1;
|
||||
cnt += (int)((long)(mm[m].p)
|
||||
/ pgs);
|
||||
}
|
||||
|
||||
/* Check cnts and times... */
|
||||
mach_time = mach_absolute_time();
|
||||
HD(mach_time);
|
||||
cnt += (int)mach_time;
|
||||
|
||||
HX((e = getrusage(RUSAGE_SELF,
|
||||
&ru)) == -1, ru);
|
||||
if (e != -1) {
|
||||
cnt += (int)ru.ru_utime.tv_sec;
|
||||
cnt += (int)ru.ru_utime.tv_usec;
|
||||
}
|
||||
}
|
||||
|
||||
for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
|
||||
if (mm[m].p != MAP_FAILED)
|
||||
munmap(mm[m].p, mm[m].npg * pgs);
|
||||
mm[m].p = MAP_FAILED;
|
||||
}
|
||||
|
||||
HX(stat(".", &st) == -1, st);
|
||||
HX(statvfs(".", &stvfs) == -1, stvfs);
|
||||
HX(statfs(".", &stfs) == -1, stfs);
|
||||
|
||||
HX(stat("/", &st) == -1, st);
|
||||
HX(statvfs("/", &stvfs) == -1, stvfs);
|
||||
HX(statfs("/", &stfs) == -1, stfs);
|
||||
|
||||
HX((e = fstat(0, &st)) == -1, st);
|
||||
if (e == -1) {
|
||||
if (S_ISREG(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode) ||
|
||||
S_ISSOCK(st.st_mode)) {
|
||||
HX(fstatvfs(0, &stvfs) == -1,
|
||||
stvfs);
|
||||
HX(fstatfs(0, &stfs) == -1,
|
||||
stfs);
|
||||
HX((off = lseek(0, (off_t)0,
|
||||
SEEK_CUR)) < 0, off);
|
||||
}
|
||||
if (S_ISCHR(st.st_mode)) {
|
||||
HX(tcgetattr(0, &tios) == -1,
|
||||
tios);
|
||||
} else if (S_ISSOCK(st.st_mode)) {
|
||||
memset(&ss, 0, sizeof ss);
|
||||
ssl = sizeof(ss);
|
||||
HX(getpeername(0,
|
||||
(void *)&ss, &ssl) == -1,
|
||||
ss);
|
||||
}
|
||||
}
|
||||
|
||||
HX((e = getrusage(RUSAGE_CHILDREN,
|
||||
&ru)) == -1, ru);
|
||||
if (e != -1) {
|
||||
cnt += (int)ru.ru_utime.tv_sec;
|
||||
cnt += (int)ru.ru_utime.tv_usec;
|
||||
}
|
||||
} else {
|
||||
/* Subsequent hashes absorb previous result */
|
||||
HD(results);
|
||||
}
|
||||
|
||||
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
|
||||
if (e != -1) {
|
||||
cnt += (int)tv.tv_sec;
|
||||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
HD(cnt);
|
||||
}
|
||||
|
||||
SHA512_Final(results, &ctx);
|
||||
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
|
||||
i += min(sizeof(results), len - i);
|
||||
}
|
||||
explicit_bzero(&ctx, sizeof ctx);
|
||||
explicit_bzero(results, sizeof results);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
return -1;
|
||||
}
|
||||
@@ -59,10 +59,7 @@ static int inet_pton6 (const char *src, uint8_t *dst);
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(af, src, dst)
|
||||
int af;
|
||||
const char *src;
|
||||
void *dst;
|
||||
inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
@@ -91,9 +88,7 @@ inet_pton(af, src, dst)
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
uint8_t *dst;
|
||||
inet_pton4(const char *src, uint8_t *dst)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
@@ -145,9 +140,7 @@ inet_pton4(src, dst)
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
uint8_t *dst;
|
||||
inet_pton6(const char *src, uint8_t *dst)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
|
||||
Vendored
+9
-17
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
#!/usr/bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
|
||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||
|
||||
timestamp='2026-05-17'
|
||||
timestamp='2024-07-27'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -60,7 +60,7 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -150,7 +150,7 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case $UNAME_SYSTEM in
|
||||
Ironclad|Linux|GNU|GNU/*)
|
||||
Linux|GNU|GNU/*)
|
||||
LIBC=unknown
|
||||
|
||||
set_cc_for_build
|
||||
@@ -167,8 +167,6 @@ Ironclad|Linux|GNU|GNU/*)
|
||||
LIBC=gnu
|
||||
#elif defined(__LLVM_LIBC__)
|
||||
LIBC=llvm
|
||||
#elif defined(__mlibc__)
|
||||
LIBC=mlibc
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
/* First heuristic to detect musl libc. */
|
||||
@@ -1188,9 +1186,6 @@ EOF
|
||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
sw_64:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
tile*:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
@@ -1602,11 +1597,8 @@ EOF
|
||||
*:Unleashed:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
|
||||
;;
|
||||
x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-pc-ironclad-$LIBC
|
||||
;;
|
||||
*:[Ii]ronclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-ironclad-$LIBC
|
||||
*:Ironclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-ironclad
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1816,8 +1808,8 @@ fi
|
||||
exit 1
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "timestamp='"
|
||||
# time-stamp-format: "%Y-%02m-%02d"
|
||||
# time-stamp-format: "%:y-%02m-%02d"
|
||||
# time-stamp-end: "'"
|
||||
# End:
|
||||
+220
-178
@@ -31,6 +31,9 @@
|
||||
/* Whether daemon is deprecated */
|
||||
#undef DEPRECATED_DAEMON
|
||||
|
||||
/* Whether X509_NAME_get_text_by_NID is deprecated */
|
||||
#undef DEPRECATED_X509_NAME_GET_TEXT_BY_NID
|
||||
|
||||
/* Deprecate RSA 1024 bit length, makes that an unsupported key */
|
||||
#undef DEPRECATE_RSA_1024
|
||||
|
||||
@@ -48,18 +51,21 @@
|
||||
internal symbols */
|
||||
#undef EXPORT_ALL_SYMBOLS
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
/* Define to 1 if you have the 'accept4' function. */
|
||||
#undef HAVE_ACCEPT4
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
/* Define to 1 if you have the 'arc4random' function. */
|
||||
#undef HAVE_ARC4RANDOM
|
||||
|
||||
/* Define to 1 if you have the `arc4random_uniform' function. */
|
||||
/* Define to 1 if you have the 'arc4random_uniform' function. */
|
||||
#undef HAVE_ARC4RANDOM_UNIFORM
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
/* Define to 1 if you have the 'ASN1_STRING_get0_data' function. */
|
||||
#undef HAVE_ASN1_STRING_GET0_DATA
|
||||
|
||||
/* Whether the C compiler accepts the "fallthrough" attribute */
|
||||
#undef HAVE_ATTR_FALLTHROUGH
|
||||
|
||||
@@ -81,7 +87,7 @@
|
||||
/* If we have be64toh */
|
||||
#undef HAVE_BE64TOH
|
||||
|
||||
/* Define to 1 if you have the `BIO_set_callback_ex' function. */
|
||||
/* Define to 1 if you have the 'BIO_set_callback_ex' function. */
|
||||
#undef HAVE_BIO_SET_CALLBACK_EX
|
||||
|
||||
/* Define to 1 if you have the <bsd/stdlib.h> header file. */
|
||||
@@ -90,245 +96,255 @@
|
||||
/* Define to 1 if you have the <bsd/string.h> header file. */
|
||||
#undef HAVE_BSD_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `chown' function. */
|
||||
/* Define to 1 if you have the 'chown' function. */
|
||||
#undef HAVE_CHOWN
|
||||
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
/* Define to 1 if you have the 'chroot' function. */
|
||||
#undef HAVE_CHROOT
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
/* Define to 1 if you have the 'CRYPTO_cleanup_all_ex_data' function. */
|
||||
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
|
||||
/* Define to 1 if you have the 'CRYPTO_THREADID_set_callback' function. */
|
||||
#undef HAVE_CRYPTO_THREADID_SET_CALLBACK
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
/* Define to 1 if you have the 'ctime_r' function. */
|
||||
#undef HAVE_CTIME_R
|
||||
|
||||
/* Define to 1 if you have the `daemon' function. */
|
||||
/* Define to 1 if you have the 'daemon' function. */
|
||||
#undef HAVE_DAEMON
|
||||
|
||||
/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'arc4random', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_ARC4RANDOM
|
||||
|
||||
/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0
|
||||
/* Define to 1 if you have the declaration of 'arc4random_uniform', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_ARC4RANDOM_UNIFORM
|
||||
|
||||
/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if
|
||||
/* Define to 1 if you have the declaration of 'evsignal_assign', and to 0 if
|
||||
you don't. */
|
||||
#undef HAVE_DECL_EVSIGNAL_ASSIGN
|
||||
|
||||
/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'inet_ntop', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_INET_NTOP
|
||||
|
||||
/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'inet_pton', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the declaration of `nghttp2_session_server_new',
|
||||
/* Define to 1 if you have the declaration of 'nghttp2_session_server_new',
|
||||
and to 0 if you don't. */
|
||||
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
|
||||
|
||||
/* Define to 1 if you have the declaration of `ngtcp2_conn_server_new', and to
|
||||
/* Define to 1 if you have the declaration of 'ngtcp2_conn_server_new', and to
|
||||
0 if you don't. */
|
||||
#undef HAVE_DECL_NGTCP2_CONN_SERVER_NEW
|
||||
|
||||
/* Define to 1 if you have the declaration of `ngtcp2_crypto_encrypt_cb', and
|
||||
/* Define to 1 if you have the declaration of 'ngtcp2_crypto_encrypt_cb', and
|
||||
to 0 if you don't. */
|
||||
#undef HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'ngtcp2_crypto_ossl_ctx_new',
|
||||
and to 0 if you don't. */
|
||||
#undef HAVE_DECL_NGTCP2_CRYPTO_OSSL_CTX_NEW
|
||||
|
||||
/* Define to 1 if you have the declaration of 'NID_ED25519', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED25519
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'NID_ED448', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED448
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'NID_secp384r1', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_SECP384R1
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0
|
||||
/* Define to 1 if you have the declaration of 'NID_X9_62_prime256v1', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_NID_X9_62_PRIME256V1
|
||||
|
||||
/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'reallocarray', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'redisConnect', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_REDISCONNECT
|
||||
|
||||
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
|
||||
/* Define to 1 if you have the declaration of 'sk_SSL_COMP_pop_free', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
|
||||
/* Define to 1 if you have the declaration of
|
||||
`SSL_COMP_get_compression_methods', and to 0 if you don't. */
|
||||
'SSL_COMP_get_compression_methods', and to 0 if you don't. */
|
||||
#undef HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
|
||||
/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to
|
||||
/* Define to 1 if you have the declaration of 'SSL_CTX_set_ecdh_auto', and to
|
||||
0 if you don't. */
|
||||
#undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
|
||||
|
||||
/* Define to 1 if you have the declaration of `SSL_CTX_set_tmp_ecdh', and to 0
|
||||
/* Define to 1 if you have the declaration of 'SSL_CTX_set_tmp_ecdh', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_SSL_CTX_SET_TMP_ECDH
|
||||
|
||||
/* Define to 1 if you have the declaration of `strlcat', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'strlcat', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_STRLCAT
|
||||
|
||||
/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you
|
||||
/* Define to 1 if you have the declaration of 'strlcpy', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the declaration of `XML_StopParser', and to 0 if
|
||||
/* Define to 1 if you have the declaration of 'XML_StopParser', and to 0 if
|
||||
you don't. */
|
||||
#undef HAVE_DECL_XML_STOPPARSER
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `DSA_SIG_set0' function. */
|
||||
/* Define to 1 if you have the 'DSA_SIG_set0' function. */
|
||||
#undef HAVE_DSA_SIG_SET0
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
#undef HAVE_ENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the `endprotoent' function. */
|
||||
/* Define to 1 if you have the 'endprotoent' function. */
|
||||
#undef HAVE_ENDPROTOENT
|
||||
|
||||
/* Define to 1 if you have the `endpwent' function. */
|
||||
/* Define to 1 if you have the 'endpwent' function. */
|
||||
#undef HAVE_ENDPWENT
|
||||
|
||||
/* Define to 1 if you have the `endservent' function. */
|
||||
/* Define to 1 if you have the 'endservent' function. */
|
||||
#undef HAVE_ENDSERVENT
|
||||
|
||||
/* Define to 1 if you have the `ENGINE_cleanup' function. */
|
||||
/* Define to 1 if you have the 'ENGINE_cleanup' function. */
|
||||
#undef HAVE_ENGINE_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the `ERR_free_strings' function. */
|
||||
/* Define to 1 if you have the 'ERR_free_strings' function. */
|
||||
#undef HAVE_ERR_FREE_STRINGS
|
||||
|
||||
/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
|
||||
/* Define to 1 if you have the 'ERR_load_crypto_strings' function. */
|
||||
#undef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
|
||||
/* Define to 1 if you have the `event_assign' function. */
|
||||
/* Define to 1 if you have the 'event_assign' function. */
|
||||
#undef HAVE_EVENT_ASSIGN
|
||||
|
||||
/* Define to 1 if you have the `event_base_free' function. */
|
||||
/* Define to 1 if you have the 'event_base_free' function. */
|
||||
#undef HAVE_EVENT_BASE_FREE
|
||||
|
||||
/* Define to 1 if you have the `event_base_get_method' function. */
|
||||
/* Define to 1 if you have the 'event_base_get_method' function. */
|
||||
#undef HAVE_EVENT_BASE_GET_METHOD
|
||||
|
||||
/* Define to 1 if you have the `event_base_new' function. */
|
||||
/* Define to 1 if you have the 'event_base_new' function. */
|
||||
#undef HAVE_EVENT_BASE_NEW
|
||||
|
||||
/* Define to 1 if you have the `event_base_once' function. */
|
||||
/* Define to 1 if you have the 'event_base_once' function. */
|
||||
#undef HAVE_EVENT_BASE_ONCE
|
||||
|
||||
/* Define to 1 if you have the <event.h> header file. */
|
||||
#undef HAVE_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
|
||||
/* Define to 1 if you have the 'EVP_aes_256_cbc' function. */
|
||||
#undef HAVE_EVP_AES_256_CBC
|
||||
|
||||
/* Define to 1 if you have the `EVP_cleanup' function. */
|
||||
/* Define to 1 if you have the 'EVP_cleanup' function. */
|
||||
#undef HAVE_EVP_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the `EVP_default_properties_is_fips_enabled'
|
||||
/* Define to 1 if you have the 'EVP_default_properties_is_fips_enabled'
|
||||
function. */
|
||||
#undef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED
|
||||
|
||||
/* Define to 1 if you have the `EVP_DigestVerify' function. */
|
||||
/* Define to 1 if you have the 'EVP_DigestVerify' function. */
|
||||
#undef HAVE_EVP_DIGESTVERIFY
|
||||
|
||||
/* Define to 1 if you have the `EVP_dss1' function. */
|
||||
/* Define to 1 if you have the 'EVP_dss1' function. */
|
||||
#undef HAVE_EVP_DSS1
|
||||
|
||||
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
|
||||
/* Define to 1 if you have the 'EVP_EncryptInit_ex' function. */
|
||||
#undef HAVE_EVP_ENCRYPTINIT_EX
|
||||
|
||||
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
|
||||
/* Define to 1 if you have the 'EVP_MAC_CTX_set_params' function. */
|
||||
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
|
||||
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
|
||||
/* Define to 1 if you have the 'EVP_MD_CTX_new' function. */
|
||||
#undef HAVE_EVP_MD_CTX_NEW
|
||||
|
||||
/* Define to 1 if you have the `EVP_sha1' function. */
|
||||
/* Define to 1 if you have the 'EVP_sha1' function. */
|
||||
#undef HAVE_EVP_SHA1
|
||||
|
||||
/* Define to 1 if you have the `EVP_sha256' function. */
|
||||
/* Define to 1 if you have the 'EVP_sha256' function. */
|
||||
#undef HAVE_EVP_SHA256
|
||||
|
||||
/* Define to 1 if you have the `EVP_sha512' function. */
|
||||
/* Define to 1 if you have the 'EVP_sha512' function. */
|
||||
#undef HAVE_EVP_SHA512
|
||||
|
||||
/* Define to 1 if you have the `ev_default_loop' function. */
|
||||
/* Define to 1 if you have the 'ev_default_loop' function. */
|
||||
#undef HAVE_EV_DEFAULT_LOOP
|
||||
|
||||
/* Define to 1 if you have the `ev_loop' function. */
|
||||
/* Define to 1 if you have the 'ev_loop' function. */
|
||||
#undef HAVE_EV_LOOP
|
||||
|
||||
/* Define to 1 if you have the <expat.h> header file. */
|
||||
#undef HAVE_EXPAT_H
|
||||
|
||||
/* Define to 1 if you have the `explicit_bzero' function. */
|
||||
/* Define to 1 if you have the 'explicit_bzero' function. */
|
||||
#undef HAVE_EXPLICIT_BZERO
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
/* Define to 1 if you have the 'fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
/* Define to 1 if you have the `FIPS_mode' function. */
|
||||
/* Define to 1 if you have the 'FIPS_mode' function. */
|
||||
#undef HAVE_FIPS_MODE
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
/* Define to 1 if you have the 'fnmatch' function. */
|
||||
#undef HAVE_FNMATCH
|
||||
|
||||
/* Define to 1 if you have the <fnmatch.h> header file. */
|
||||
#undef HAVE_FNMATCH_H
|
||||
|
||||
/* Define to 1 if you have the 'fork' function. */
|
||||
#undef HAVE_FORK
|
||||
|
||||
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
|
||||
/* Define to 1 if fseeko (and ftello) are declared in stdio.h. */
|
||||
#undef HAVE_FSEEKO
|
||||
|
||||
/* Define to 1 if you have the `fsync' function. */
|
||||
/* Define to 1 if you have the 'fsync' function. */
|
||||
#undef HAVE_FSYNC
|
||||
|
||||
/* Whether getaddrinfo is available */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `getauxval' function. */
|
||||
/* Define to 1 if you have the 'getauxval' function. */
|
||||
#undef HAVE_GETAUXVAL
|
||||
|
||||
/* Define to 1 if you have the `getentropy' function. */
|
||||
/* Define to 1 if you have the 'getentropy' function. */
|
||||
#undef HAVE_GETENTROPY
|
||||
|
||||
/* Define to 1 if you have the `getifaddrs' function. */
|
||||
/* Define to 1 if you have the 'getifaddrs' function. */
|
||||
#undef HAVE_GETIFADDRS
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define to 1 if you have the `getpwnam' function. */
|
||||
/* Define to 1 if you have the 'getpwnam' function. */
|
||||
#undef HAVE_GETPWNAM
|
||||
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
/* Define to 1 if you have the 'getrlimit' function. */
|
||||
#undef HAVE_GETRLIMIT
|
||||
|
||||
/* Define to 1 if you have the `gettid' function. */
|
||||
/* Define to 1 if you have the 'gettid' function. */
|
||||
#undef HAVE_GETTID
|
||||
|
||||
/* Define to 1 if you have the `glob' function. */
|
||||
/* Define to 1 if you have the 'glob' function. */
|
||||
#undef HAVE_GLOB
|
||||
|
||||
/* Define to 1 if you have the <glob.h> header file. */
|
||||
#undef HAVE_GLOB_H
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
/* Define to 1 if you have the 'gmtime_r' function. */
|
||||
#undef HAVE_GMTIME_R
|
||||
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
@@ -337,7 +353,7 @@
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* Define to 1 if you have the `HMAC_Init_ex' function. */
|
||||
/* Define to 1 if you have the 'HMAC_Init_ex' function. */
|
||||
#undef HAVE_HMAC_INIT_EX
|
||||
|
||||
/* If we have htobe64 */
|
||||
@@ -346,19 +362,19 @@
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#undef HAVE_IFADDRS_H
|
||||
|
||||
/* Define to 1 if you have the `if_nametoindex' function. */
|
||||
/* Define to 1 if you have the 'if_nametoindex' function. */
|
||||
#undef HAVE_IF_NAMETOINDEX
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
/* Define to 1 if you have the 'inet_aton' function. */
|
||||
#undef HAVE_INET_ATON
|
||||
|
||||
/* Define to 1 if you have the `inet_ntop' function. */
|
||||
/* Define to 1 if you have the 'inet_ntop' function. */
|
||||
#undef HAVE_INET_NTOP
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
/* Define to 1 if you have the 'inet_pton' function. */
|
||||
#undef HAVE_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the `initgroups' function. */
|
||||
/* Define to 1 if you have the 'initgroups' function. */
|
||||
#undef HAVE_INITGROUPS
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
@@ -370,10 +386,10 @@
|
||||
/* Define to 1 if you have the <iphlpapi.h> header file. */
|
||||
#undef HAVE_IPHLPAPI_H
|
||||
|
||||
/* Define to 1 if you have the `isblank' function. */
|
||||
/* Define to 1 if you have the 'isblank' function. */
|
||||
#undef HAVE_ISBLANK
|
||||
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
/* Define to 1 if you have the 'kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Use portable libbsd functions */
|
||||
@@ -391,7 +407,7 @@
|
||||
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
|
||||
#undef HAVE_LINUX_NET_TSTAMP_H
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
/* Define to 1 if you have the 'localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
/* Define to 1 if you have the <login_cap.h> header file. */
|
||||
@@ -400,7 +416,7 @@
|
||||
/* If have GNU libc compatible malloc */
|
||||
#undef HAVE_MALLOC
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
/* Define to 1 if you have the 'memmove' function. */
|
||||
#undef HAVE_MEMMOVE
|
||||
|
||||
/* Define to 1 if you have the <minix/config.h> header file. */
|
||||
@@ -442,52 +458,52 @@
|
||||
/* Define this to use ngtcp2. */
|
||||
#undef HAVE_NGTCP2
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_ccerr_default' function. */
|
||||
/* Define to 1 if you have the 'ngtcp2_ccerr_default' function. */
|
||||
#undef HAVE_NGTCP2_CCERR_DEFAULT
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_conn_encode_0rtt_transport_params'
|
||||
/* Define to 1 if you have the 'ngtcp2_conn_encode_0rtt_transport_params'
|
||||
function. */
|
||||
#undef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_conn_get_max_local_streams_uni'
|
||||
/* Define to 1 if you have the 'ngtcp2_conn_get_max_local_streams_uni'
|
||||
function. */
|
||||
#undef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_conn_get_num_scid' function. */
|
||||
/* Define to 1 if you have the 'ngtcp2_conn_get_num_scid' function. */
|
||||
#undef HAVE_NGTCP2_CONN_GET_NUM_SCID
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_conn_in_closing_period' function. */
|
||||
/* Define to 1 if you have the 'ngtcp2_conn_in_closing_period' function. */
|
||||
#undef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_conn_in_draining_period' function. */
|
||||
/* Define to 1 if you have the 'ngtcp2_conn_in_draining_period' function. */
|
||||
#undef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
|
||||
|
||||
/* Define if ngtcp2_conn_shutdown_stream has 4 arguments. */
|
||||
#undef HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_conn_tls_early_data_rejected' function.
|
||||
/* Define to 1 if you have the 'ngtcp2_conn_tls_early_data_rejected' function.
|
||||
*/
|
||||
#undef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_crypto_encrypt_cb' function. */
|
||||
/* Define to 1 if you have the 'ngtcp2_crypto_encrypt_cb' function. */
|
||||
#undef HAVE_NGTCP2_CRYPTO_ENCRYPT_CB
|
||||
|
||||
/* Define to 1 if you have the
|
||||
`ngtcp2_crypto_quictls_configure_client_context' function. */
|
||||
'ngtcp2_crypto_quictls_configure_client_context' function. */
|
||||
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
|
||||
|
||||
/* Define to 1 if you have the
|
||||
`ngtcp2_crypto_quictls_configure_server_context' function. */
|
||||
'ngtcp2_crypto_quictls_configure_server_context' function. */
|
||||
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
|
||||
|
||||
/* Define to 1 if you have the
|
||||
`ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
|
||||
'ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
|
||||
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_crypto_quictls_init' function. */
|
||||
/* Define to 1 if you have the 'ngtcp2_crypto_quictls_init' function. */
|
||||
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_INIT
|
||||
|
||||
/* Define to 1 if the system has the type `ngtcp2_encryption_level'. */
|
||||
/* Define to 1 if the system has the type 'ngtcp2_encryption_level'. */
|
||||
#undef HAVE_NGTCP2_ENCRYPTION_LEVEL
|
||||
|
||||
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_openssl.h> header file.
|
||||
@@ -507,13 +523,16 @@
|
||||
/* Use libnss for crypto */
|
||||
#undef HAVE_NSS
|
||||
|
||||
/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */
|
||||
/* Define to 1 if you have the 'OpenSSL_add_all_digests' function. */
|
||||
#undef HAVE_OPENSSL_ADD_ALL_DIGESTS
|
||||
|
||||
/* Define to 1 if you have the <openssl/bn.h> header file. */
|
||||
#undef HAVE_OPENSSL_BN_H
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_config' function. */
|
||||
/* Define to 1 if you have the 'OPENSSL_cleanup' function. */
|
||||
#undef HAVE_OPENSSL_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the 'OPENSSL_config' function. */
|
||||
#undef HAVE_OPENSSL_CONFIG
|
||||
|
||||
/* Define to 1 if you have the <openssl/conf.h> header file. */
|
||||
@@ -534,10 +553,10 @@
|
||||
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||
#undef HAVE_OPENSSL_ERR_H
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
|
||||
/* Define to 1 if you have the 'OPENSSL_init_crypto' function. */
|
||||
#undef HAVE_OPENSSL_INIT_CRYPTO
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
|
||||
/* Define to 1 if you have the 'OPENSSL_init_ssl' function. */
|
||||
#undef HAVE_OPENSSL_INIT_SSL
|
||||
|
||||
/* Define to 1 if you have the <openssl/param_build.h> header file. */
|
||||
@@ -552,10 +571,10 @@
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#undef HAVE_OPENSSL_SSL_H
|
||||
|
||||
/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */
|
||||
/* Define to 1 if you have the 'OSSL_PARAM_BLD_new' function. */
|
||||
#undef HAVE_OSSL_PARAM_BLD_NEW
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
/* Define to 1 if you have the 'poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
@@ -570,7 +589,7 @@
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
#undef HAVE_PTHREAD_PRIO_INHERIT
|
||||
|
||||
/* Define to 1 if the system has the type `pthread_rwlock_t'. */
|
||||
/* Define to 1 if the system has the type 'pthread_rwlock_t'. */
|
||||
#undef HAVE_PTHREAD_RWLOCK_T
|
||||
|
||||
/* Define if pthread_setname_np has the common 2 arguments. */
|
||||
@@ -585,7 +604,7 @@
|
||||
/* Define if pthread_setname_np exists as pthread_set_name_np instead. */
|
||||
#undef HAVE_PTHREAD_SET_NAME_NP
|
||||
|
||||
/* Define to 1 if the system has the type `pthread_spinlock_t'. */
|
||||
/* Define to 1 if the system has the type 'pthread_spinlock_t'. */
|
||||
#undef HAVE_PTHREAD_SPINLOCK_T
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
@@ -594,100 +613,107 @@
|
||||
/* Define if you have Python libraries and header files. */
|
||||
#undef HAVE_PYTHON
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
/* Define to 1 if you have the 'random' function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
/* Define to 1 if you have the `RAND_cleanup' function. */
|
||||
/* Define to 1 if you have the 'RAND_cleanup' function. */
|
||||
#undef HAVE_RAND_CLEANUP
|
||||
|
||||
/* If we have reallocarray(3) */
|
||||
#undef HAVE_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the `recvmsg' function. */
|
||||
/* Define to 1 if you have the 'recvmsg' function. */
|
||||
#undef HAVE_RECVMSG
|
||||
|
||||
/* Define to 1 if you have the `sendmsg' function. */
|
||||
/* Define to 1 if you have the 'sendmsg' function. */
|
||||
#undef HAVE_SENDMSG
|
||||
|
||||
/* Define to 1 if you have the `setregid' function. */
|
||||
/* Define to 1 if you have the 'setregid' function. */
|
||||
#undef HAVE_SETREGID
|
||||
|
||||
/* Define to 1 if you have the `setresgid' function. */
|
||||
/* Define to 1 if you have the 'setresgid' function. */
|
||||
#undef HAVE_SETRESGID
|
||||
|
||||
/* Define to 1 if you have the `setresuid' function. */
|
||||
/* Define to 1 if you have the 'setresuid' function. */
|
||||
#undef HAVE_SETRESUID
|
||||
|
||||
/* Define to 1 if you have the `setreuid' function. */
|
||||
/* Define to 1 if you have the 'setreuid' function. */
|
||||
#undef HAVE_SETREUID
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
/* Define to 1 if you have the 'setrlimit' function. */
|
||||
#undef HAVE_SETRLIMIT
|
||||
|
||||
/* Define to 1 if you have the `setsid' function. */
|
||||
/* Define to 1 if you have the 'setsid' function. */
|
||||
#undef HAVE_SETSID
|
||||
|
||||
/* Define to 1 if you have the `setusercontext' function. */
|
||||
/* Define to 1 if you have the 'setusercontext' function. */
|
||||
#undef HAVE_SETUSERCONTEXT
|
||||
|
||||
/* Define to 1 if you have the `SHA512_Update' function. */
|
||||
/* Define to 1 if you have the 'SHA512_Update' function. */
|
||||
#undef HAVE_SHA512_UPDATE
|
||||
|
||||
/* Define to 1 if you have the `shmget' function. */
|
||||
/* Define to 1 if you have the 'shmget' function. */
|
||||
#undef HAVE_SHMGET
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
/* Define to 1 if you have the 'sigprocmask' function. */
|
||||
#undef HAVE_SIGPROCMASK
|
||||
|
||||
/* Define to 1 if you have the `sleep' function. */
|
||||
/* Define to 1 if you have the 'sleep' function. */
|
||||
#undef HAVE_SLEEP
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
/* Define to 1 if you have the 'snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `socketpair' function. */
|
||||
/* Define to 1 if you have the 'socketpair' function. */
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
/* Using Solaris threads */
|
||||
#undef HAVE_SOLARIS_THREADS
|
||||
|
||||
/* Define to 1 if you have the `srandom' function. */
|
||||
/* Define to 1 if you have the 'srandom' function. */
|
||||
#undef HAVE_SRANDOM
|
||||
|
||||
/* Define if you have the SSL libraries installed. */
|
||||
#undef HAVE_SSL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_alpn_protos' function. */
|
||||
/* Define to 1 if you have the 'SSL_CTX_set_alpn_protos' function. */
|
||||
#undef HAVE_SSL_CTX_SET_ALPN_PROTOS
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
|
||||
/* Define to 1 if you have the 'SSL_CTX_set_alpn_select_cb' function. */
|
||||
#undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
|
||||
/* Define to 1 if you have the 'SSL_CTX_set_ciphersuites' function. */
|
||||
#undef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
|
||||
/* Define to 1 if you have the 'SSL_CTX_set_security_level' function. */
|
||||
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_evp_cb'
|
||||
/* Define to 1 if you have the 'SSL_CTX_set_tlsext_ticket_key_evp_cb'
|
||||
function. */
|
||||
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
|
||||
/* Define to 1 if you have the 'SSL_get0_alpn_selected' function. */
|
||||
#undef HAVE_SSL_GET0_ALPN_SELECTED
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_peername' function. */
|
||||
/* Define to 1 if you have the 'SSL_get0_peername' function. */
|
||||
#undef HAVE_SSL_GET0_PEERNAME
|
||||
|
||||
/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */
|
||||
/* Define to 1 if you have the 'SSL_get1_peer_certificate' function. */
|
||||
#undef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
|
||||
/* Define to 1 if you have the `SSL_is_quic' function. */
|
||||
/* Define to 1 if you have the 'SSL_is_quic' function. */
|
||||
#undef HAVE_SSL_IS_QUIC
|
||||
|
||||
/* Define to 1 if you have the `SSL_set1_host' function. */
|
||||
/* Define to 1 if you have the 'SSL_set1_dnsname' function. */
|
||||
#undef HAVE_SSL_SET1_DNSNAME
|
||||
|
||||
/* Define to 1 if you have the 'SSL_set1_host' function. */
|
||||
#undef HAVE_SSL_SET1_HOST
|
||||
|
||||
/* Define to 1 if you have the 'SSL_set_quic_tls_early_data_enabled' function.
|
||||
*/
|
||||
#undef HAVE_SSL_SET_QUIC_TLS_EARLY_DATA_ENABLED
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
@@ -706,7 +732,7 @@
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
/* Define to 1 if you have the 'strftime' function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
@@ -715,45 +741,45 @@
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
/* Define to 1 if you have the 'strlcat' function. */
|
||||
#undef HAVE_STRLCAT
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
/* Define to 1 if you have the 'strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strptime' function. */
|
||||
/* Define to 1 if you have the 'strptime' function. */
|
||||
#undef HAVE_STRPTIME
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
/* Define to 1 if you have the 'strsep' function. */
|
||||
#undef HAVE_STRSEP
|
||||
|
||||
/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
|
||||
/* Define to 1 if 'ipi_spec_dst' is a member of 'struct in_pktinfo'. */
|
||||
#undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
|
||||
|
||||
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_pkt_hd'. */
|
||||
/* Define to 1 if 'tokenlen' is a member of 'struct ngtcp2_pkt_hd'. */
|
||||
#undef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN
|
||||
|
||||
/* Define to 1 if `max_tx_udp_payload_size' is a member of `struct
|
||||
/* Define to 1 if 'max_tx_udp_payload_size' is a member of 'struct
|
||||
ngtcp2_settings'. */
|
||||
#undef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE
|
||||
|
||||
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_settings'. */
|
||||
/* Define to 1 if 'tokenlen' is a member of 'struct ngtcp2_settings'. */
|
||||
#undef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN
|
||||
|
||||
/* Define to 1 if `original_dcid_present' is a member of `struct
|
||||
/* Define to 1 if 'original_dcid_present' is a member of 'struct
|
||||
ngtcp2_transport_params'. */
|
||||
#undef HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT
|
||||
|
||||
/* Define to 1 if the system has the type `struct ngtcp2_version_cid'. */
|
||||
/* Define to 1 if the system has the type 'struct ngtcp2_version_cid'. */
|
||||
#undef HAVE_STRUCT_NGTCP2_VERSION_CID
|
||||
|
||||
/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
|
||||
/* Define to 1 if 'sun_len' is a member of 'struct sockaddr_un'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||
|
||||
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
|
||||
/* Define to 1 if 'st_mtimensec' is a member of 'struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||
|
||||
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||
/* Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
|
||||
/* Define if you have Swig libraries and header files. */
|
||||
@@ -813,16 +839,16 @@
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
/* Define to 1 if you have the `tzset' function. */
|
||||
/* Define to 1 if you have the 'tzset' function. */
|
||||
#undef HAVE_TZSET
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
/* Define to 1 if you have the 'usleep' function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
/* Define to 1 if you have the 'vfork' function. */
|
||||
#undef HAVE_VFORK
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
@@ -840,22 +866,28 @@
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
#undef HAVE_WINSOCK2_H
|
||||
|
||||
/* Define to 1 if `fork' works. */
|
||||
/* Define to 1 if 'fork' works. */
|
||||
#undef HAVE_WORKING_FORK
|
||||
|
||||
/* Define to 1 if `vfork' works. */
|
||||
/* Define to 1 if 'vfork' works. */
|
||||
#undef HAVE_WORKING_VFORK
|
||||
|
||||
/* Define to 1 if you have the `writev' function. */
|
||||
/* Define to 1 if you have the 'writev' function. */
|
||||
#undef HAVE_WRITEV
|
||||
|
||||
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||
#undef HAVE_WS2TCPIP_H
|
||||
|
||||
/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
|
||||
/* Define to 1 if you have the 'X509_get_key_usage' function. */
|
||||
#undef HAVE_X509_GET_KEY_USAGE
|
||||
|
||||
/* Define to 1 if you have the 'X509_NAME_get_text_by_NID' function. */
|
||||
#undef HAVE_X509_NAME_GET_TEXT_BY_NID
|
||||
|
||||
/* Define to 1 if you have the 'X509_VERIFY_PARAM_set1_host' function. */
|
||||
#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
|
||||
|
||||
/* Define to 1 if you have the `_beginthreadex' function. */
|
||||
/* Define to 1 if you have the '_beginthreadex' function. */
|
||||
#undef HAVE__BEGINTHREADEX
|
||||
|
||||
/* If HMAC_Init_ex() returns void */
|
||||
@@ -954,16 +986,16 @@
|
||||
/* Shared data */
|
||||
#undef SHARE_DIR
|
||||
|
||||
/* The size of `pthread_t', as computed by sizeof. */
|
||||
/* The size of 'pthread_t', as computed by sizeof. */
|
||||
#undef SIZEOF_PTHREAD_T
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
/* The size of 'size_t', as computed by sizeof. */
|
||||
#undef SIZEOF_SIZE_T
|
||||
|
||||
/* The size of `time_t', as computed by sizeof. */
|
||||
/* The size of 'time_t', as computed by sizeof. */
|
||||
#undef SIZEOF_TIME_T
|
||||
|
||||
/* The size of `unsigned long', as computed by sizeof. */
|
||||
/* The size of 'unsigned long', as computed by sizeof. */
|
||||
#undef SIZEOF_UNSIGNED_LONG
|
||||
|
||||
/* define if (v)snprintf does not return length needed, (but length used) */
|
||||
@@ -972,7 +1004,7 @@
|
||||
/* Define to 1 if libsodium supports sodium_set_misuse_handler */
|
||||
#undef SODIUM_MISUSE_HANDLER
|
||||
|
||||
/* Define to 1 if all of the C90 standard headers exist (not just the ones
|
||||
/* Define to 1 if all of the C89 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
backward compatibility; new code need not use it. */
|
||||
#undef STDC_HEADERS
|
||||
@@ -1069,7 +1101,7 @@
|
||||
/* Define this to enable SHA256 and SHA512 support. */
|
||||
#undef USE_SHA2
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
/* Enable extensions on AIX, Interix, z/OS. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
@@ -1130,11 +1162,15 @@
|
||||
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_DFP_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by C23 Annex F. */
|
||||
#ifndef __STDC_WANT_IEC_60559_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
|
||||
/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#endif
|
||||
@@ -1175,30 +1211,36 @@
|
||||
/* Define if you want PyUnbound. */
|
||||
#undef WITH_PYUNBOUND
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
/* Define to 1 if 'lex' declares 'yytext' as a 'char *' by default, not a
|
||||
'char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
|
||||
/* Define to 1 if necessary to make fseeko visible. */
|
||||
#undef _LARGEFILE_SOURCE
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* Define to 1 on platforms where this makes off_t a 64-bit type. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Enable for compile on Minix */
|
||||
#undef _NETBSD_SOURCE
|
||||
|
||||
/* Number of bits in time_t, on hosts where this is settable. */
|
||||
#undef _TIME_BITS
|
||||
|
||||
/* Define to 1 on platforms where this makes time_t a 64-bit type. */
|
||||
#undef __MINGW_USE_VC2005_COMPAT
|
||||
|
||||
/* defined to use gcc ansi snprintf and sscanf that understands %lld when
|
||||
compiled for windows. */
|
||||
#undef __USE_MINGW_ANSI_STDIO
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* Define to empty if 'const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* Define as 'int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* in_addr_t */
|
||||
@@ -1207,28 +1249,28 @@
|
||||
/* in_port_t */
|
||||
#undef in_port_t
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
/* Define to '__inline__' or '__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `short' if <sys/types.h> does not define. */
|
||||
/* Define to 'short' if <sys/types.h> does not define. */
|
||||
#undef int16_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* Define to 'int' if <sys/types.h> does not define. */
|
||||
#undef int32_t
|
||||
|
||||
/* Define to `long long' if <sys/types.h> does not define. */
|
||||
/* Define to 'long long' if <sys/types.h> does not define. */
|
||||
#undef int64_t
|
||||
|
||||
/* Define to `signed char' if <sys/types.h> does not define. */
|
||||
/* Define to 'signed char' if <sys/types.h> does not define. */
|
||||
#undef int8_t
|
||||
|
||||
/* Define if replacement function should be used. */
|
||||
#undef malloc
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
/* Define to 'long int' if <sys/types.h> does not define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define as a signed integer type capable of holding a process identifier. */
|
||||
@@ -1237,34 +1279,34 @@
|
||||
/* Define to 'int' if not defined */
|
||||
#undef rlim_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* Define as 'unsigned int' if <stddef.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to 'int' if not defined */
|
||||
#undef socklen_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* Define to 'int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define to 'unsigned char if not defined */
|
||||
#undef u_char
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* Define as 'int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
/* Define to `unsigned short' if <sys/types.h> does not define. */
|
||||
/* Define to 'unsigned short' if <sys/types.h> does not define. */
|
||||
#undef uint16_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* Define to 'unsigned int' if <sys/types.h> does not define. */
|
||||
#undef uint32_t
|
||||
|
||||
/* Define to `unsigned long long' if <sys/types.h> does not define. */
|
||||
/* Define to 'unsigned long long' if <sys/types.h> does not define. */
|
||||
#undef uint64_t
|
||||
|
||||
/* Define to `unsigned char' if <sys/types.h> does not define. */
|
||||
/* Define to 'unsigned char' if <sys/types.h> does not define. */
|
||||
#undef uint8_t
|
||||
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
/* Define as 'fork' if 'vfork' does not work. */
|
||||
#undef vfork
|
||||
|
||||
#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE)
|
||||
|
||||
Vendored
+10
-21
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
#!/usr/bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
|
||||
# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale
|
||||
|
||||
timestamp='2026-05-17'
|
||||
timestamp='2024-05-27'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -76,7 +76,7 @@ Report bugs and patches to <[email protected]>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -145,7 +145,6 @@ case $1 in
|
||||
| kfreebsd*-gnu* \
|
||||
| knetbsd*-gnu* \
|
||||
| kopensolaris*-gnu* \
|
||||
| ironclad-* \
|
||||
| linux-* \
|
||||
| managarm-* \
|
||||
| netbsd*-eabi* \
|
||||
@@ -243,6 +242,7 @@ case $1 in
|
||||
| rombug \
|
||||
| semi \
|
||||
| sequent* \
|
||||
| siemens \
|
||||
| sgi* \
|
||||
| siemens \
|
||||
| sim \
|
||||
@@ -261,7 +261,7 @@ case $1 in
|
||||
basic_machine=$field1-$field2
|
||||
basic_os=
|
||||
;;
|
||||
tock* | zephyr*)
|
||||
zephyr*)
|
||||
basic_machine=$field1-unknown
|
||||
basic_os=$field2
|
||||
;;
|
||||
@@ -1194,7 +1194,7 @@ case $cpu-$vendor in
|
||||
xscale-* | xscalee[bl]-*)
|
||||
cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
|
||||
;;
|
||||
arm64-* | aarch64le-* | arm64_32-*)
|
||||
arm64-* | aarch64le-*)
|
||||
cpu=aarch64
|
||||
;;
|
||||
|
||||
@@ -1321,7 +1321,6 @@ case $cpu-$vendor in
|
||||
| i960 \
|
||||
| ia16 \
|
||||
| ia64 \
|
||||
| intelgt \
|
||||
| ip2k \
|
||||
| iq2000 \
|
||||
| javascript \
|
||||
@@ -1432,7 +1431,6 @@ case $cpu-$vendor in
|
||||
| sparcv9v \
|
||||
| spu \
|
||||
| sv1 \
|
||||
| sw_64 \
|
||||
| sx* \
|
||||
| tahoe \
|
||||
| thumbv7* \
|
||||
@@ -1524,10 +1522,6 @@ EOF
|
||||
kernel=nto
|
||||
os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
|
||||
;;
|
||||
ironclad*)
|
||||
kernel=ironclad
|
||||
os=`echo "$basic_os" | sed -e 's|ironclad|gnu|'`
|
||||
;;
|
||||
linux*)
|
||||
kernel=linux
|
||||
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
|
||||
@@ -1982,7 +1976,6 @@ case $os in
|
||||
| atheos* \
|
||||
| auroraux* \
|
||||
| aux* \
|
||||
| banan_os* \
|
||||
| beos* \
|
||||
| bitrig* \
|
||||
| bme* \
|
||||
@@ -2029,6 +2022,7 @@ case $os in
|
||||
| ios* \
|
||||
| iris* \
|
||||
| irix* \
|
||||
| ironclad* \
|
||||
| isc* \
|
||||
| its* \
|
||||
| l4re* \
|
||||
@@ -2124,7 +2118,6 @@ case $os in
|
||||
| sysv* \
|
||||
| tenex* \
|
||||
| tirtos* \
|
||||
| tock* \
|
||||
| toppers* \
|
||||
| tops10* \
|
||||
| tops20* \
|
||||
@@ -2221,8 +2214,6 @@ case $kernel-$os-$obj in
|
||||
;;
|
||||
uclinux-uclibc*- | uclinux-gnu*- )
|
||||
;;
|
||||
ironclad-gnu*- | ironclad-mlibc*- )
|
||||
;;
|
||||
managarm-mlibc*- | managarm-kernel*- )
|
||||
;;
|
||||
windows*-msvc*-)
|
||||
@@ -2258,8 +2249,6 @@ case $kernel-$os-$obj in
|
||||
;;
|
||||
*-eabi*- | *-gnueabi*-)
|
||||
;;
|
||||
ios*-simulator- | tvos*-simulator- | watchos*-simulator- )
|
||||
;;
|
||||
none--*)
|
||||
# None (no kernel, i.e. freestanding / bare metal),
|
||||
# can be paired with an machine code file format
|
||||
@@ -2358,8 +2347,8 @@ echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
|
||||
exit
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "timestamp='"
|
||||
# time-stamp-format: "%Y-%02m-%02d"
|
||||
# time-stamp-format: "%:y-%02m-%02d"
|
||||
# time-stamp-end: "'"
|
||||
# End:
|
||||
Vendored
+2874
-1942
File diff suppressed because it is too large.
Load diff
@@ -11,15 +11,15 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[25])
|
||||
m4_define([VERSION_MICRO],[2])
|
||||
m4_define([VERSION_MINOR],[26])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[[email protected] or https://github.com/NLnetLabs/unbound/issues],[unbound])
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=38
|
||||
LIBUNBOUND_REVISION=39
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -125,6 +125,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.25.0 had 9:36:1
|
||||
# 1.25.1 had 9:37:1
|
||||
# 1.25.2 had 9:38:1
|
||||
# 1.26.0 had 9:39:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -483,7 +484,7 @@ PKG_PROG_PKG_CONFIG
|
||||
fi
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h fnmatch.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT])
|
||||
# net/if.h portability for Darwin see:
|
||||
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
|
||||
AC_CHECK_HEADERS([net/if.h],,, [
|
||||
@@ -1080,12 +1081,19 @@ else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex OPENSSL_cleanup])
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate])
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername SSL_set1_dnsname X509_get_key_usage ASN1_STRING_get0_data X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate])
|
||||
AC_CHECK_FUNCS([X509_NAME_get_text_by_NID])
|
||||
if test $ac_cv_func_X509_NAME_get_text_by_NID = yes; then
|
||||
ACX_FUNC_DEPRECATED([X509_NAME_get_text_by_NID], [
|
||||
(void)X509_NAME_get_text_by_NID(NULL, 0, NULL, 0);], [
|
||||
#include "openssl/x509.h"
|
||||
])
|
||||
fi
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto,SSL_CTX_set_tmp_ecdh], [], [], [
|
||||
@@ -1704,6 +1712,9 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
AC_CHECK_LIB([ngtcp2_crypto_ossl], [ngtcp2_crypto_encrypt_cb], [
|
||||
LIBS="$LIBS -lngtcp2_crypto_ossl"
|
||||
AC_DEFINE(USE_NGTCP2_CRYPTO_OSSL, 1, [Define this to use ngtcp2_crypto_ossl.])
|
||||
AC_CHECK_DECLS([ngtcp2_crypto_ossl_ctx_new], [], [AC_MSG_ERROR([No declaration of ngtcp2_crypto_ossl_ctx_new in the ngtcp2_crypto_ossl header file. Perhaps the ngtcp2_crypto_ossl devel header files need to be installed.])], [AC_INCLUDES_DEFAULT
|
||||
#include <ngtcp2/ngtcp2_crypto_ossl.h>
|
||||
])
|
||||
], [
|
||||
AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ], [
|
||||
AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ])
|
||||
@@ -1715,6 +1726,7 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])])
|
||||
AC_CHECK_FUNCS([SSL_set_quic_tls_early_data_enabled])
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT
|
||||
@@ -1928,7 +1940,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll gettid])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob fnmatch initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll gettid])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ static void
|
||||
dump_rrset_line(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
|
||||
time_t now, size_t i)
|
||||
{
|
||||
char s[65535];
|
||||
char s[65535*4+2048];
|
||||
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
|
||||
spool_txt_string(txt, "BADRR\n");
|
||||
return;
|
||||
@@ -455,7 +455,7 @@ load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
|
||||
/* read the line */
|
||||
if(!ssl_read_buf(ssl, buf))
|
||||
return 0;
|
||||
if(strncmp((char*)sldns_buffer_begin(buf), "BADRR\n", 6) == 0) {
|
||||
if(strcmp((char*)sldns_buffer_begin(buf), "BADRR") == 0) {
|
||||
*go_on = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -217,7 +217,8 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh,
|
||||
(cfg->tls_session_ticket_keys.first &&
|
||||
cfg->tls_session_ticket_keys.first->str[0] != 0),
|
||||
is_dot, is_doh, cfg->tls_protocols))) {
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
log_err("could not set up listen SSL_CTX");
|
||||
*ctx = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
@@ -259,7 +260,8 @@ void* daemon_setup_listen_quic_sslctx(struct daemon* daemon,
|
||||
pem += strlen(chroot);
|
||||
|
||||
if(!(ctx = quic_sslctx_create(key, pem, NULL))) {
|
||||
fatal_exit("could not set up quic SSL_CTX");
|
||||
log_err("could not set up quic SSL_CTX");
|
||||
return NULL;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
@@ -277,8 +279,10 @@ void* daemon_setup_connect_dot_sslctx(struct daemon* daemon,
|
||||
bundle += strlen(chroot);
|
||||
|
||||
if(!(ctx = connect_sslctx_create(NULL, NULL, bundle,
|
||||
cfg->tls_win_cert)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
cfg->tls_win_cert))) {
|
||||
log_err("could not set up connect SSL_CTX");
|
||||
return NULL;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
@@ -308,16 +312,22 @@ daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
|
||||
}
|
||||
daemon->listen_dot_sslctx = daemon_setup_listen_dot_sslctx(
|
||||
daemon, cfg);
|
||||
if(!daemon->listen_dot_sslctx)
|
||||
fatal_exit("Could not set up listen dot sslctx");
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
if(cfg_has_https(cfg)) {
|
||||
daemon->listen_doh_sslctx =
|
||||
daemon_setup_listen_doh_sslctx(daemon, cfg);
|
||||
if(!daemon->listen_doh_sslctx)
|
||||
fatal_exit("Could not set up listen doh sslctx");
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(cfg_has_quic(cfg)) {
|
||||
daemon->listen_quic_sslctx =
|
||||
daemon_setup_listen_quic_sslctx(daemon, cfg);
|
||||
if(!daemon->listen_quic_sslctx)
|
||||
fatal_exit("Could not set up listen quic sslctx");
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
|
||||
@@ -350,6 +360,8 @@ daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
|
||||
}
|
||||
daemon->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
|
||||
daemon, cfg);
|
||||
if(!daemon->connect_dot_sslctx)
|
||||
fatal_exit("could not setup connect dot sslctx");
|
||||
#else /* HAVE_SSL */
|
||||
(void)daemon;(void)cfg;
|
||||
#endif /* HAVE_SSL */
|
||||
@@ -921,13 +933,14 @@ thread_start(void* arg)
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
int port_num = 0;
|
||||
log_assert(worker->thr_id);
|
||||
set_log_thread_id(worker, worker->daemon->cfg);
|
||||
{
|
||||
char name[16]; /* seems to be the safest size between
|
||||
different OSes */
|
||||
snprintf(name, sizeof(name), "unbound/%u", worker->thread_num);
|
||||
ub_thread_setname(worker->thr_id, name);
|
||||
/* worker->thr_id can be written to after the thread was made
|
||||
* by the creating thread, so this uses pthread_self. */
|
||||
ub_thread_setname(ub_thread_self(), name);
|
||||
}
|
||||
ub_thread_blocksigs();
|
||||
#ifdef THREADS_DISABLED
|
||||
@@ -942,8 +955,9 @@ thread_start(void* arg)
|
||||
port_num = 0;
|
||||
#endif
|
||||
if(!worker_init(worker, worker->daemon->cfg,
|
||||
worker->daemon->ports[port_num], 0))
|
||||
worker->daemon->ports[port_num], 0)) {
|
||||
fatal_exit("Could not initialize thread");
|
||||
}
|
||||
|
||||
worker_work(worker);
|
||||
return NULL;
|
||||
@@ -1105,8 +1119,9 @@ daemon_fork(struct daemon* daemon)
|
||||
|
||||
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
/* in libev the first inited base gets signals */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1)) {
|
||||
fatal_exit("Could not initialize main thread");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now create the threads and init the workers.
|
||||
@@ -1119,8 +1134,9 @@ daemon_fork(struct daemon* daemon)
|
||||
*/
|
||||
#if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
|
||||
/* libevent has the last inited base get signals (or any base) */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1)) {
|
||||
fatal_exit("Could not initialize main thread");
|
||||
}
|
||||
#endif
|
||||
signal_handling_playback(daemon->workers[0]);
|
||||
|
||||
@@ -1164,7 +1180,6 @@ daemon_cleanup(struct daemon* daemon)
|
||||
/* before stopping main worker, handle signals ourselves, so we
|
||||
don't die on multiple reload signals for example. */
|
||||
signal_handling_record();
|
||||
log_thread_set(NULL);
|
||||
/* clean up caches because
|
||||
* a) RRset IDs will be recycled after a reload, causing collisions
|
||||
* b) validation config can change, thus rrset, msg, keycache clear
|
||||
@@ -1270,7 +1285,7 @@ daemon_delete(struct daemon* daemon)
|
||||
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
# ifndef S_SPLINT_S
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
|
||||
sk_SSL_COMP_pop_free(comp_meth, (void(*)(SSL_COMP*))CRYPTO_free);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
@@ -1293,6 +1308,9 @@ daemon_delete(struct daemon* daemon)
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
ub_openssl_lock_delete();
|
||||
# endif
|
||||
#ifdef HAVE_OPENSSL_CLEANUP
|
||||
OPENSSL_cleanup();
|
||||
#endif
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
_ARC4_LOCK_DESTROY();
|
||||
#endif
|
||||
|
||||
+249
-14
@@ -307,7 +307,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
char* s = strchr(ip, '@');
|
||||
const char* s = strchr(ip, '@');
|
||||
char newif[128];
|
||||
if(s) {
|
||||
/* override port with ifspec@port */
|
||||
@@ -1533,18 +1533,95 @@ do_datas_add(struct daemon_remote* rc, RES* ssl, struct worker* worker)
|
||||
(void)ssl_printf(ssl, "added %d datas\n", num);
|
||||
}
|
||||
|
||||
static int
|
||||
perform_data_remove_rr(RES* ssl, struct local_zones* local_zones,
|
||||
uint8_t* rr, size_t len, size_t dname_len, char *arg)
|
||||
{
|
||||
uint16_t rr_class, rr_type;
|
||||
int labs;
|
||||
struct local_zone* z;
|
||||
struct local_data* ld;
|
||||
uint8_t *rdata;
|
||||
size_t rdata_len, index;
|
||||
struct packed_rrset_data* d;
|
||||
struct local_rrset* p;
|
||||
|
||||
rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len);
|
||||
rdata_len = ((size_t)sldns_wirerr_get_rdatalen(rr, len, dname_len))+2;
|
||||
|
||||
labs = dname_count_labels(rr);
|
||||
|
||||
rr_class = sldns_wirerr_get_class(rr, len, dname_len);
|
||||
rr_type = sldns_wirerr_get_type(rr, len, dname_len);
|
||||
|
||||
z = local_zones_lookup(local_zones, rr, dname_len,
|
||||
labs, rr_class, rr_type, 1);
|
||||
if (!z) {
|
||||
ssl_printf(ssl, "error no zone for rr %s\n", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ld = local_zone_find_data(z, rr, dname_len, labs);
|
||||
if (!ld) {
|
||||
ssl_printf(ssl, "error no local data for rr %s\n", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = ld->rrsets;
|
||||
while (p && ntohs(p->rrset->rk.type) != rr_type) {
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
ssl_printf(ssl, "error no rrset for rr %s\n", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = (struct packed_rrset_data*)p->rrset->entry.data;
|
||||
if (!packed_rrset_find_rr(d, rdata, rdata_len, &index)) {
|
||||
ssl_printf(ssl, "error rr %s not found in rrset\n", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!local_rrset_remove_rr(d, index)) {
|
||||
ssl_printf(ssl, "error unable to delete rr %s\n", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Remove RR data */
|
||||
static int
|
||||
perform_data_remove(RES* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE], *nm;
|
||||
size_t len = sizeof(rr);
|
||||
int status, nmlabs;
|
||||
size_t nmlen, dname_len;
|
||||
|
||||
/* try to parse as a rr first */
|
||||
status = sldns_str2wire_rr_buf(arg, rr, &len, &dname_len, 3600,
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
/* try to parse as a domain name second */
|
||||
if (status != 0) {
|
||||
if (parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) {
|
||||
local_zones_del_data(zones, nm,
|
||||
nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
||||
free(nm);
|
||||
return 1;
|
||||
}
|
||||
ssl_printf(ssl, "error cannot parse rr %s at %d: %s\n", arg,
|
||||
LDNS_WIREPARSE_OFFSET(status),
|
||||
sldns_get_errorstr_parse(status));
|
||||
return 0;
|
||||
local_zones_del_data(zones, nm,
|
||||
nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
||||
free(nm);
|
||||
}
|
||||
|
||||
/* handle the rr case */
|
||||
if (!perform_data_remove_rr(ssl, zones, rr, len, dname_len, arg))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2315,6 +2392,9 @@ zone_del_rrset(struct lruhash_entry* e, void* arg)
|
||||
(struct packed_rrset_data*)e->data;
|
||||
if(d->ttl > inf->expired) {
|
||||
d->ttl = inf->expired;
|
||||
if(d->ttl_add > inf->expired)
|
||||
d->ttl_add = inf->expired; /* for 0TTL rrsets,
|
||||
means that d->ttl_add <= d->ttl */
|
||||
inf->num_rrsets++;
|
||||
}
|
||||
}
|
||||
@@ -3238,6 +3318,10 @@ do_auth_zone_reload(RES* ssl, struct worker* worker, char* arg)
|
||||
return;
|
||||
}
|
||||
if(!auth_zone_read_zonefile(z, worker->env.cfg)) {
|
||||
/* The old tree was already cleared. Do not answer from the
|
||||
* failed load. */
|
||||
z->zone_expired = 1;
|
||||
auth_zone_clear_data(z);
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(xfr) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
@@ -3249,6 +3333,7 @@ do_auth_zone_reload(RES* ssl, struct worker* worker, char* arg)
|
||||
z->zone_expired = 0;
|
||||
if(xfr) {
|
||||
xfr->zone_expired = 0;
|
||||
xfr->num_ixfrs = 0;
|
||||
if(!xfr_find_soa(z, xfr)) {
|
||||
if(z->data.count == 0) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
@@ -4941,6 +5026,74 @@ fr_check_changed_cfg_str2list(struct config_str2list* cmp1,
|
||||
}
|
||||
}
|
||||
|
||||
/** fast reload thread, check if config str3list has changed. */
|
||||
#define FR_CHECK_CHANGED_CFG_STR3LIST(desc, var, buff) do { \
|
||||
fr_check_changed_cfg_str3list(cfg->var, newcfg->var, desc, buff,\
|
||||
sizeof(buff)); \
|
||||
} while(0);
|
||||
static void
|
||||
fr_check_changed_cfg_str3list(struct config_str3list* cmp1,
|
||||
struct config_str3list* cmp2, const char* desc, char* str, size_t len)
|
||||
{
|
||||
struct config_str3list* p1 = cmp1, *p2 = cmp2;
|
||||
while(p1 && p2) {
|
||||
if((!p1->str && p2->str) ||
|
||||
(p1->str && !p2->str) ||
|
||||
(p1->str && p2->str && strcmp(p1->str, p2->str) != 0)) {
|
||||
/* The str3list is different. */
|
||||
fr_add_incompatible_option(desc, str, len);
|
||||
return;
|
||||
}
|
||||
if((!p1->str2 && p2->str2) ||
|
||||
(p1->str2 && !p2->str2) ||
|
||||
(p1->str2 && p2->str2 &&
|
||||
strcmp(p1->str2, p2->str2) != 0)) {
|
||||
/* The str3list is different. */
|
||||
fr_add_incompatible_option(desc, str, len);
|
||||
return;
|
||||
}
|
||||
if((!p1->str3 && p2->str3) ||
|
||||
(p1->str3 && !p2->str3) ||
|
||||
(p1->str3 && p2->str3 &&
|
||||
strcmp(p1->str3, p2->str3) != 0)) {
|
||||
/* The str3list is different. */
|
||||
fr_add_incompatible_option(desc, str, len);
|
||||
return;
|
||||
}
|
||||
p1 = p1->next;
|
||||
p2 = p2->next;
|
||||
}
|
||||
if((!p1 && p2) || (p1 && !p2)) {
|
||||
fr_add_incompatible_option(desc, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
/** fast reload thread, check tag datas. */
|
||||
static int
|
||||
fr_check_tag_datas(struct fast_reload_thread* fr, struct config_file* newcfg)
|
||||
{
|
||||
char changed_str[1024];
|
||||
struct config_file* cfg = fr->worker->env.cfg;
|
||||
changed_str[0]=0;
|
||||
|
||||
/* Check for tag_datas in acl_addr. */
|
||||
FR_CHECK_CHANGED_CFG_STR3LIST("interface-tag-data", interface_tag_datas, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STR3LIST("access-control-tag-data", acl_tag_datas, changed_str);
|
||||
|
||||
if(changed_str[0] != 0) {
|
||||
if(fr->fr_drop_mesh)
|
||||
return 1; /* already dropping queries */
|
||||
fr->fr_drop_mesh = 1;
|
||||
fr->worker->daemon->fast_reload_drop_mesh = fr->fr_drop_mesh;
|
||||
if(!fr_output_printf(fr, "recursion referenced data has changed, with: '%s"
|
||||
"', and the queries have to be dropped"
|
||||
", setting '+d'\n", changed_str))
|
||||
return 0;
|
||||
fr_send_notification(fr, fast_reload_notification_printout);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** fast reload thread, check compatible config items */
|
||||
static int
|
||||
fr_check_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg)
|
||||
@@ -5477,6 +5630,23 @@ xfr_masterlist_equal(struct auth_master* list1, struct auth_master* list2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** See if configuration has changed. */
|
||||
static int
|
||||
xfr_config_equal(struct auth_xfer* xfr1, struct auth_xfer* xfr2)
|
||||
{
|
||||
if(xfr1 == NULL && xfr2 == NULL)
|
||||
return 1;
|
||||
if(xfr1 == NULL && xfr2 != NULL)
|
||||
return 0;
|
||||
if(xfr1 != NULL && xfr2 == NULL)
|
||||
return 0;
|
||||
if(xfr1->max_transfer_size != xfr2->max_transfer_size)
|
||||
return 0;
|
||||
if(xfr1->max_transfer_time != xfr2->max_transfer_time)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** See if the list of masters has changed. */
|
||||
static int
|
||||
xfr_masters_equal(struct auth_xfer* xfr1, struct auth_xfer* xfr2)
|
||||
@@ -5565,8 +5735,31 @@ auth_zones_check_changes(struct fast_reload_thread* fr,
|
||||
&old_serial)!=0);
|
||||
have_new = (auth_zone_get_serial(new_z,
|
||||
&new_serial)!=0);
|
||||
/* A change in primaries, also means it is different
|
||||
* and the change makes it fire new transfers, from
|
||||
* the new primaries. */
|
||||
/* Treat as changed when the old zone has an
|
||||
* outstanding ZONEMD DS/DNSKEY mesh callback.
|
||||
* This will make the worker pickup change code
|
||||
* remove the mesh callback, before the old zone is
|
||||
* deleted. Also it makes a new zonemd lookup.
|
||||
* The new lookup is needed, because the new zone
|
||||
* entry needs to have a valid zonemd result,
|
||||
* and if that is bad, needs to be invalidated.
|
||||
* Also if there is a race event where the
|
||||
* outstanding callback makes the zone invalid,
|
||||
* before fast-reload completes, the change makes
|
||||
* the new zone entry have a new zonemd lookup,
|
||||
* to then invalidate that new zone.
|
||||
* There is also a brief operational window at
|
||||
* program start when a zonemd has to be looked
|
||||
* up on-line, where the zone is operational.
|
||||
* And this copies that for such a race event.
|
||||
*/
|
||||
if(have_old != have_new || old_serial != new_serial
|
||||
|| !xfr_masters_equal(old_xfr, new_xfr)) {
|
||||
|| !xfr_masters_equal(old_xfr, new_xfr)
|
||||
|| !xfr_config_equal(old_xfr, new_xfr)
|
||||
|| old_z->zonemd_callback_env != NULL) {
|
||||
/* The zone has been changed. */
|
||||
if(!fr_add_auth_zone_change(fr, old_z, new_z,
|
||||
0, 0, 1)) {
|
||||
@@ -5639,6 +5832,8 @@ ct_create_sslctxs(struct fast_reload_construct* ct,
|
||||
/* Leave listen ctxs and file str at NULL */
|
||||
ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
|
||||
daemon, newcfg);
|
||||
if(!ct->connect_dot_sslctx)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5648,20 +5843,28 @@ ct_create_sslctxs(struct fast_reload_construct* ct,
|
||||
pem += strlen(chroot);
|
||||
|
||||
ct->listen_dot_sslctx = daemon_setup_listen_dot_sslctx(daemon, newcfg);
|
||||
if(!ct->listen_dot_sslctx)
|
||||
return 0;
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
if(cfg_has_https(newcfg)) {
|
||||
ct->listen_doh_sslctx = daemon_setup_listen_doh_sslctx(
|
||||
daemon, newcfg);
|
||||
if(!ct->listen_doh_sslctx)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(cfg_has_quic(newcfg)) {
|
||||
ct->listen_quic_sslctx = daemon_setup_listen_quic_sslctx(
|
||||
daemon, newcfg);
|
||||
if(!ct->listen_quic_sslctx)
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(daemon,
|
||||
newcfg);
|
||||
if(!ct->connect_dot_sslctx)
|
||||
return 0;
|
||||
|
||||
/* Store mtime and names */
|
||||
ct->ssl_service_key = strdup(newcfg->ssl_service_key);
|
||||
@@ -6631,9 +6834,12 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(env->cfg->dnstap) {
|
||||
if(!fr->fr_nopause)
|
||||
dt_apply_cfg(daemon->dtenv, env->cfg);
|
||||
else dt_apply_logcfg(daemon->dtenv, env->cfg);
|
||||
if(!fr->fr_nopause) {
|
||||
if(!dt_apply_cfg(daemon->dtenv, env->cfg))
|
||||
log_warn("fast_reload: dnstap identity/version metadata not updated due to allocation failure");
|
||||
} else {
|
||||
dt_apply_logcfg(daemon->dtenv, env->cfg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fr_adjust_cache(env, ct->oldcfg);
|
||||
@@ -6773,6 +6979,10 @@ fr_load_config(struct fast_reload_thread* fr, struct timeval* time_read,
|
||||
config_delete(newcfg);
|
||||
return 0;
|
||||
}
|
||||
if(!fr_check_tag_datas(fr, newcfg)) {
|
||||
config_delete(newcfg);
|
||||
return 0;
|
||||
}
|
||||
if(!fr_check_compat_cfg(fr, newcfg)) {
|
||||
config_delete(newcfg);
|
||||
return 0;
|
||||
@@ -6864,7 +7074,7 @@ static void* fast_reload_thread_main(void* arg)
|
||||
#endif
|
||||
log_thread_set(&fast_reload_thread->threadnum);
|
||||
|
||||
ub_thread_setname(fast_reload_thread->tid, name);
|
||||
ub_thread_setname(ub_thread_self(), name);
|
||||
(void)name; /* When setname is not defined, ignore the name variable. */
|
||||
|
||||
verbose(VERB_ALGO, "start fast reload thread");
|
||||
@@ -7587,7 +7797,8 @@ auth_zone_zonemd_stop_lookup(struct auth_zone* z, struct mesh_area* mesh)
|
||||
qinfo.local_alias = NULL;
|
||||
|
||||
mesh_remove_callback(mesh, &qinfo, qflags,
|
||||
&auth_zonemd_dnskey_lookup_callback, z);
|
||||
&auth_zonemd_dnskey_lookup_callback, z,
|
||||
z->zonemd_callback_unique_info);
|
||||
}
|
||||
|
||||
/** Pick up the auth zone locks. */
|
||||
@@ -7696,6 +7907,9 @@ auth_xfr_pickup_config(struct auth_xfer* loadxfr, struct auth_xfer* xfr)
|
||||
log_assert(loadxfr->namelabs == xfr->namelabs);
|
||||
log_assert(loadxfr->dclass == xfr->dclass);
|
||||
|
||||
xfr->max_transfer_size = loadxfr->max_transfer_size;
|
||||
xfr->max_transfer_time = loadxfr->max_transfer_time;
|
||||
|
||||
/* The lists can be swapped in, the other xfr struct will be deleted
|
||||
* afterwards. */
|
||||
probe_masters = xfr->task_probe->masters;
|
||||
@@ -7720,6 +7934,16 @@ fr_worker_auth_add(struct worker* worker, struct fast_reload_auth_change* item,
|
||||
/* The xfr item needs to be created. The auth zones lock
|
||||
* is held to make this possible. */
|
||||
xfr = auth_xfer_create(worker->env.auth_zones, item->new_z);
|
||||
if(!xfr) {
|
||||
log_err("out of memory in fr_worker_auth_add");
|
||||
lock_rw_unlock(&item->new_z->lock);
|
||||
lock_rw_unlock(&worker->env.auth_zones->lock);
|
||||
lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
|
||||
if(loadxfr) {
|
||||
lock_basic_unlock(&loadxfr->lock);
|
||||
}
|
||||
return;
|
||||
}
|
||||
auth_xfr_pickup_config(loadxfr, xfr);
|
||||
/* Serial information is copied into the xfr struct. */
|
||||
if(!xfr_find_soa(item->new_z, xfr)) {
|
||||
@@ -7789,6 +8013,17 @@ fr_worker_auth_cha(struct worker* worker, struct fast_reload_auth_change* item)
|
||||
} else if(loadxfr && !xfr) {
|
||||
/* Create the xfr. */
|
||||
xfr = auth_xfer_create(worker->env.auth_zones, item->new_z);
|
||||
if(!xfr) {
|
||||
log_err("out of memory in fr_worker_auth_cha");
|
||||
lock_rw_unlock(&item->new_z->lock);
|
||||
lock_rw_unlock(&item->old_z->lock);
|
||||
lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
|
||||
lock_rw_unlock(&worker->env.auth_zones->lock);
|
||||
if(loadxfr) {
|
||||
lock_basic_unlock(&loadxfr->lock);
|
||||
}
|
||||
return;
|
||||
}
|
||||
auth_xfr_pickup_config(loadxfr, xfr);
|
||||
item->new_z->zone_is_slave = 1;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#include "util/locks.h"
|
||||
#include "libunbound/remote.h"
|
||||
struct config_file;
|
||||
struct listen_list;
|
||||
struct listen_port;
|
||||
@@ -365,13 +366,6 @@ void fast_reload_thread_start(RES* ssl, struct worker* worker,
|
||||
*/
|
||||
void fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread);
|
||||
|
||||
/** fast reload thread commands to remote service thread event callback */
|
||||
void fast_reload_service_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** fast reload callback for the remote control client connection */
|
||||
int fast_reload_client_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* rep);
|
||||
|
||||
/** fast reload printq delete list */
|
||||
void fast_reload_printq_list_delete(struct fast_reload_printq* list);
|
||||
|
||||
|
||||
@@ -422,12 +422,28 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
# endif
|
||||
#endif
|
||||
);
|
||||
log_err("server_stats_obtain: no response from worker %d "
|
||||
"(stats timeout); returning zero stats for this worker",
|
||||
who->thread_num);
|
||||
/* A later reply from the worker, would be sizeof stats reply,
|
||||
* and the worker_handle_control_cmd routine discards if
|
||||
* it is not a 4byte command, when that is received here. */
|
||||
memset(s, 0, sizeof(*s));
|
||||
return;
|
||||
}
|
||||
if(!tube_read_msg(worker->cmd, &reply, &len, 0)) {
|
||||
log_err("server_stats_obtain: failed to read stats from worker "
|
||||
"(tube read error); returning zero stats for this worker");
|
||||
memset(s, 0, sizeof(*s));
|
||||
return;
|
||||
}
|
||||
if(len != (uint32_t)sizeof(*s)) {
|
||||
log_err("server_stats_obtain: wrong stats length %d (expected %d); "
|
||||
"discarding", (int)len, (int)sizeof(*s));
|
||||
free(reply);
|
||||
memset(s, 0, sizeof(*s));
|
||||
return;
|
||||
}
|
||||
if(!tube_read_msg(worker->cmd, &reply, &len, 0))
|
||||
fatal_exit("failed to read stats over cmd channel");
|
||||
if(len != (uint32_t)sizeof(*s))
|
||||
fatal_exit("stats on cmd channel wrong length %d %d",
|
||||
(int)len, (int)sizeof(*s));
|
||||
memcpy(s, reply, (size_t)len);
|
||||
free(reply);
|
||||
}
|
||||
@@ -439,7 +455,7 @@ void server_stats_reply(struct worker* worker, int reset)
|
||||
verbose(VERB_ALGO, "write stats replymsg");
|
||||
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
|
||||
(uint8_t*)&s, sizeof(s), 0))
|
||||
fatal_exit("could not write stat values over cmd channel");
|
||||
log_err("could not write stat values over cmd channel");
|
||||
}
|
||||
|
||||
void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
|
||||
@@ -501,7 +501,9 @@ worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
|
||||
return;
|
||||
}
|
||||
if(len != sizeof(uint32_t)) {
|
||||
fatal_exit("bad control msg length %d", (int)len);
|
||||
verbose(VERB_ALGO, "bad control msg length %d", (int)len);
|
||||
free(msg);
|
||||
return;
|
||||
}
|
||||
cmd = sldns_read_uint32(msg);
|
||||
free(msg);
|
||||
@@ -714,7 +716,8 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, struct reply_info* rep,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct ub_packed_rrset_key** alias_rrset,
|
||||
struct reply_info** encode_repp, struct auth_zones* az)
|
||||
struct reply_info** encode_repp, struct auth_zones* az,
|
||||
int* rpz_passthru)
|
||||
{
|
||||
struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
|
||||
actinfo.action = respip_none;
|
||||
@@ -725,7 +728,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
return 1;
|
||||
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
|
||||
alias_rrset, 0, worker->scratchpad, az, NULL,
|
||||
alias_rrset, 0, worker->scratchpad, az, rpz_passthru,
|
||||
worker->env.views, worker->env.respip_set))
|
||||
return 0;
|
||||
|
||||
@@ -772,7 +775,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
int* is_secure_answer, struct ub_packed_rrset_key** alias_rrset,
|
||||
struct reply_info** partial_repp,
|
||||
struct reply_info* rep, uint16_t id, uint16_t flags,
|
||||
struct comm_reply* repinfo, struct edns_data* edns)
|
||||
struct comm_reply* repinfo, struct edns_data* edns, int* rpz_passthru)
|
||||
{
|
||||
time_t timenow = *worker->env.now;
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
@@ -882,7 +885,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
|
||||
!partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep,
|
||||
&repinfo->client_addr, repinfo->client_addrlen, alias_rrset,
|
||||
&encode_rep, worker->env.auth_zones)) {
|
||||
&encode_rep, worker->env.auth_zones, rpz_passthru)) {
|
||||
goto bail_out;
|
||||
} else if(partial_rep &&
|
||||
!respip_merge_cname(partial_rep, qinfo, rep, cinfo,
|
||||
@@ -1494,6 +1497,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct reply_info* partial_rep = NULL;
|
||||
struct query_info* lookup_qinfo = &qinfo;
|
||||
struct query_info qinfo_tmp; /* placeholder for lookup_qinfo */
|
||||
uint8_t* alias_orig_qname = NULL; /* original qname for logs, if
|
||||
a local_alias is used to change the qname. */
|
||||
struct respip_client_info* cinfo = NULL, cinfo_tmp;
|
||||
struct timeval wait_time;
|
||||
struct check_request_result check_result = {0,0};
|
||||
@@ -1511,7 +1516,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if (worker->stats.max_query_time_us < wait_queue_time)
|
||||
worker->stats.max_query_time_us = wait_queue_time;
|
||||
if(wait_queue_time >
|
||||
(long long)(worker->env.cfg->sock_queue_timeout * 1000000)) {
|
||||
(long long)worker->env.cfg->sock_queue_timeout * 1000000) {
|
||||
/* count and drop queries that were sitting in the socket queue too long */
|
||||
worker->stats.num_queries_timed_out++;
|
||||
return 0;
|
||||
@@ -1936,6 +1941,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
/* If we've found a local alias, replace the qname with the alias
|
||||
* target before resolving it. */
|
||||
if(qinfo.local_alias) {
|
||||
if(qinfo.local_alias->rrset &&
|
||||
qinfo.local_alias->rrset->rk.dname)
|
||||
/* Store the original qname, used for logs, since
|
||||
* local_alias can be removed by region_free_all. */
|
||||
alias_orig_qname = qinfo.local_alias->rrset->rk.dname;
|
||||
if(!local_alias_shallow_copy_qname(qinfo.local_alias, &qinfo.qname,
|
||||
&qinfo.qname_len)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
@@ -1983,7 +1993,7 @@ lookup_cache:
|
||||
&alias_rrset, &partial_rep, rep,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
&edns, &rpz_passthru)) {
|
||||
/* prefetch it if the prefetch TTL expired.
|
||||
* Note that if there is more than one pass
|
||||
* its qname must be that used for cache
|
||||
@@ -2101,11 +2111,10 @@ send_reply_rc:
|
||||
{
|
||||
struct timeval tv;
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
if(qinfo.local_alias && qinfo.local_alias->rrset &&
|
||||
qinfo.local_alias->rrset->rk.dname) {
|
||||
if(alias_orig_qname) {
|
||||
/* log original qname, before the local alias was
|
||||
* used to resolve that CNAME to something else */
|
||||
qinfo.qname = qinfo.local_alias->rrset->rk.dname;
|
||||
qinfo.qname = alias_orig_qname;
|
||||
log_reply_info(NO_VERBOSE, &qinfo,
|
||||
&repinfo->client_addr, repinfo->client_addrlen,
|
||||
tv, 1, c->buffer,
|
||||
@@ -2374,6 +2383,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker_stat_timer_cb, worker);
|
||||
if(!worker->stat_timer) {
|
||||
log_err("could not create statistics timer");
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we use the msg_buffer_size as a good estimate for what the
|
||||
@@ -2526,6 +2537,8 @@ worker_delete(struct worker* worker)
|
||||
/* don't touch worker->alloc, as it's maintained in daemon */
|
||||
regional_destroy(worker->env.scratch);
|
||||
regional_destroy(worker->scratchpad);
|
||||
/* The thread id can reference this worker's id value, so clear it. */
|
||||
log_thread_set(NULL);
|
||||
free(worker);
|
||||
}
|
||||
|
||||
@@ -2534,7 +2547,8 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, int check_ratelimit,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q, int* was_ratelimited)
|
||||
struct module_qstate* q, int* was_ratelimited,
|
||||
int* ratelimit_incremented)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -2546,7 +2560,7 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
want_dnssec, nocaps, check_ratelimit, tcp_upstream,
|
||||
ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
|
||||
worker_handle_service_reply, e, worker->back->udp_buff, q->env,
|
||||
was_ratelimited);
|
||||
was_ratelimited, ratelimit_incremented);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -2595,7 +2609,8 @@ struct outbound_entry* libworker_send_query(
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
|
||||
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited),
|
||||
int* ATTR_UNUSED(ratelimit_incremented))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
@@ -643,6 +643,12 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
qstate->return_msg->rep &&
|
||||
reply_find_answer_rrset(&qstate->qinfo, qstate->return_msg->rep);
|
||||
int synth_qname = 0;
|
||||
if(could_synth && !has_data && qstate->env->need_to_validate &&
|
||||
qstate->return_msg && qstate->return_msg->rep &&
|
||||
qstate->return_msg->rep->security == sec_status_bogus) {
|
||||
verbose(VERB_ALGO, "dns64: bogus AAAA reply not synthesized");
|
||||
could_synth = 0;
|
||||
}
|
||||
|
||||
if(could_synth &&
|
||||
(!has_data ||
|
||||
@@ -654,8 +660,11 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
|
||||
/* Store the response in cache. */
|
||||
if( (!iq || !iq->started_no_cache_store) &&
|
||||
!qstate->rpz_applied && !qstate->rpz_passthru &&
|
||||
!qstate->is_subnet_answer &&
|
||||
qstate->return_msg &&
|
||||
qstate->return_msg->rep &&
|
||||
!qstate->fwd_stub_no_cache &&
|
||||
!dns_cache_store(
|
||||
qstate->env, &qstate->qinfo, qstate->return_msg->rep,
|
||||
0, qstate->prefetch_leeway, 0, NULL,
|
||||
@@ -717,8 +726,15 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
}
|
||||
if(qstate->ext_state[id] == module_finished) {
|
||||
iq = (struct dns64_qstate*)qstate->minfo[id];
|
||||
if(iq && iq->state != DNS64_INTERNAL_QUERY)
|
||||
qstate->no_cache_store = iq->started_no_cache_store;
|
||||
if(iq && iq->state != DNS64_INTERNAL_QUERY) {
|
||||
if(qstate->fwd_stub_no_cache) {
|
||||
/* If the forward/stub has no cache, then
|
||||
* continue with the query with no cache. */
|
||||
qstate->no_cache_store = qstate->fwd_stub_no_cache;
|
||||
} else {
|
||||
qstate->no_cache_store = iq->started_no_cache_store;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -825,6 +841,7 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
size_t i, s;
|
||||
struct packed_rrset_data* fd, *dd;
|
||||
struct ub_packed_rrset_key* fk, *dk;
|
||||
int allocated_return_msg = 0;
|
||||
|
||||
verbose(VERB_ALGO, "converting A answers to AAAA answers");
|
||||
|
||||
@@ -840,6 +857,7 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
return;
|
||||
memset(super->return_msg, 0, sizeof(*super->return_msg));
|
||||
super->return_msg->qinfo = super->qinfo;
|
||||
allocated_return_msg = 1;
|
||||
}
|
||||
|
||||
rep = qstate->return_msg->rep;
|
||||
@@ -852,11 +870,14 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
rep->serve_expired_norec_ttl,
|
||||
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
|
||||
rep->rrset_count, rep->security, LDNS_EDE_NONE);
|
||||
if(!cp)
|
||||
if(!cp) {
|
||||
if(allocated_return_msg) super->return_msg = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate ub_key structures special or not */
|
||||
if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) {
|
||||
if(allocated_return_msg) super->return_msg = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -871,8 +892,10 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
if(i<rep->an_numrrsets && fk->rk.type == htons(LDNS_RR_TYPE_A)) {
|
||||
/* also sets dk->entry.hash */
|
||||
dns64_synth_aaaa_data(fk, fd, dk, &dd, super->region, dns64_env);
|
||||
if(!dd)
|
||||
if(!dd) {
|
||||
if(allocated_return_msg) super->return_msg = NULL;
|
||||
return;
|
||||
}
|
||||
/* Delete negative AAAA record from cache stored by
|
||||
* the iterator module */
|
||||
rrset_cache_remove(super->env->rrset_cache, dk->rk.dname,
|
||||
@@ -889,15 +912,19 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
dk->rk.dname = (uint8_t*)regional_alloc_init(super->region,
|
||||
fk->rk.dname, fk->rk.dname_len);
|
||||
|
||||
if(!dk->rk.dname)
|
||||
if(!dk->rk.dname) {
|
||||
if(allocated_return_msg) super->return_msg = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
s = packed_rrset_sizeof(fd);
|
||||
dd = (struct packed_rrset_data*)regional_alloc_init(
|
||||
super->region, fd, s);
|
||||
|
||||
if(!dd)
|
||||
if(!dd) {
|
||||
if(allocated_return_msg) super->return_msg = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
packed_rrset_ptr_fixup(dd);
|
||||
@@ -928,8 +955,10 @@ dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
|
||||
return;
|
||||
super->return_msg->qinfo = super->qinfo;
|
||||
if (!(super->return_msg->rep = reply_info_copy(qstate->return_msg->rep,
|
||||
NULL, super->region)))
|
||||
NULL, super->region))) {
|
||||
super->return_msg = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust the domain name of the answer RR set so that it matches the
|
||||
@@ -998,6 +1027,21 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
/* Use return code from A query in response to client. */
|
||||
if (super->return_rcode != LDNS_RCODE_NOERROR)
|
||||
super->return_rcode = qstate->return_rcode;
|
||||
/* RPZ applied to the subquery need to then change (not cache)
|
||||
* the super query. With the super query not cached, it is
|
||||
* going to run the state machine modules on incoming queries,
|
||||
* that fetch the subquery (cache) response, and modify it
|
||||
* according to the rpz policy. That makes the synthesized
|
||||
* super query also adjusted by rpz policies. But loses cache
|
||||
* hits. Even though the subquery likely is answered from cache,
|
||||
* internally in its state machine process. */
|
||||
if(qstate->rpz_applied)
|
||||
super->rpz_applied = 1;
|
||||
if(qstate->rpz_passthru)
|
||||
super->rpz_passthru = 1;
|
||||
|
||||
/* Since the super qstate has a new response, its errinf is removed. */
|
||||
super->errinf = NULL;
|
||||
|
||||
/* Generate a response suitable for the original query. */
|
||||
if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) {
|
||||
@@ -1006,9 +1050,16 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
log_assert(qstate->qinfo.qtype == LDNS_RR_TYPE_PTR);
|
||||
dns64_adjust_ptr(qstate, super);
|
||||
}
|
||||
/* If the sub-query has no cache store, then also the super query. */
|
||||
if(qstate->fwd_stub_no_cache)
|
||||
super->fwd_stub_no_cache = 1;
|
||||
|
||||
/* Store the generated response in cache. */
|
||||
if ( (!super_dq || !super_dq->started_no_cache_store) &&
|
||||
if ( super->return_msg && super->return_msg->rep &&
|
||||
(!super_dq || !super_dq->started_no_cache_store) &&
|
||||
!qstate->fwd_stub_no_cache &&
|
||||
!super->rpz_applied && !super->rpz_passthru &&
|
||||
!super->is_subnet_answer &&
|
||||
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||
0, super->prefetch_leeway, 0, NULL, super->query_flags,
|
||||
qstate->qstarttime, qstate->is_valrec))
|
||||
|
||||
@@ -842,7 +842,14 @@ dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
|
||||
if(memcmp(current_keypair->crypt_publickey,
|
||||
env->signed_certs[c].server_publickey,
|
||||
crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
dnsccert *current_cert = &env->certs[cert_id++];
|
||||
dnsccert* current_cert;
|
||||
if(cert_id >= env->signed_certs_count) {
|
||||
log_err("dnscrypt: secret key %s matches a cert that "
|
||||
"is already bound to another key (duplicate "
|
||||
"dnscrypt-secret-key?)", head->str);
|
||||
return -1;
|
||||
}
|
||||
current_cert = &env->certs[cert_id++];
|
||||
found_cert = 1;
|
||||
current_cert->keypair = current_keypair;
|
||||
memcpy(current_cert->magic_query,
|
||||
|
||||
@@ -176,26 +176,29 @@ dt_create(struct config_file* cfg)
|
||||
env->dtio = dt_io_thread_create();
|
||||
if(!env->dtio) {
|
||||
log_err("malloc failure");
|
||||
free(env);
|
||||
dt_delete(env);
|
||||
return NULL;
|
||||
}
|
||||
if(!dt_io_thread_apply_cfg(env->dtio, cfg)) {
|
||||
dt_io_thread_delete(env->dtio);
|
||||
free(env);
|
||||
dt_delete(env);
|
||||
return NULL;
|
||||
}
|
||||
if(!dt_apply_cfg(env, cfg)) {
|
||||
dt_delete(env);
|
||||
return NULL;
|
||||
}
|
||||
dt_apply_cfg(env, cfg);
|
||||
return env;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
dt_apply_identity(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
char buf[MAXHOSTNAMELEN+1];
|
||||
if (!cfg->dnstap_send_identity) {
|
||||
free(env->identity);
|
||||
env->identity = NULL;
|
||||
return;
|
||||
env->len_identity = 0;
|
||||
return 1;
|
||||
}
|
||||
free(env->identity);
|
||||
if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) {
|
||||
@@ -203,36 +206,49 @@ dt_apply_identity(struct dt_env *env, struct config_file *cfg)
|
||||
buf[MAXHOSTNAMELEN] = 0;
|
||||
env->identity = strdup(buf);
|
||||
} else {
|
||||
fatal_exit("dt_apply_identity: gethostname() failed");
|
||||
log_err("dt_apply_identity: gethostname() failed: %s",
|
||||
strerror(errno));
|
||||
env->identity = NULL;
|
||||
env->len_identity = 0;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
env->identity = strdup(cfg->dnstap_identity);
|
||||
}
|
||||
if (env->identity == NULL)
|
||||
fatal_exit("dt_apply_identity: strdup() failed");
|
||||
if (env->identity == NULL) {
|
||||
log_err("dt_apply_identity: strdup() failed");
|
||||
env->len_identity = 0;
|
||||
return 0;
|
||||
}
|
||||
env->len_identity = (unsigned int)strlen(env->identity);
|
||||
verbose(VERB_OPS, "dnstap identity field set to \"%s\"",
|
||||
env->identity);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
dt_apply_version(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
if (!cfg->dnstap_send_version) {
|
||||
free(env->version);
|
||||
env->version = NULL;
|
||||
return;
|
||||
env->len_version = 0;
|
||||
return 1;
|
||||
}
|
||||
free(env->version);
|
||||
if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0)
|
||||
env->version = strdup(PACKAGE_STRING);
|
||||
else
|
||||
env->version = strdup(cfg->dnstap_version);
|
||||
if (env->version == NULL)
|
||||
fatal_exit("dt_apply_version: strdup() failed");
|
||||
if (env->version == NULL) {
|
||||
log_err("dt_apply_version: strdup() failed");
|
||||
env->len_version = 0;
|
||||
return 0;
|
||||
}
|
||||
env->len_version = (unsigned int)strlen(env->version);
|
||||
verbose(VERB_OPS, "dnstap version field set to \"%s\"",
|
||||
env->version);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -276,15 +292,18 @@ dt_apply_logcfg(struct dt_env *env, struct config_file *cfg)
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
if (!cfg->dnstap)
|
||||
return;
|
||||
return 1;
|
||||
|
||||
dt_apply_identity(env, cfg);
|
||||
dt_apply_version(env, cfg);
|
||||
dt_apply_logcfg(env, cfg);
|
||||
if(!dt_apply_identity(env, cfg))
|
||||
return 0;
|
||||
if(!dt_apply_version(env, cfg))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -102,9 +102,9 @@ dt_create(struct config_file* cfg);
|
||||
* Apply config settings.
|
||||
* @param env: dnstap environment object.
|
||||
* @param cfg: new config settings.
|
||||
* @return false on failure.
|
||||
*/
|
||||
void
|
||||
dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
|
||||
int dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
|
||||
|
||||
/**
|
||||
* Apply config settings for log enable for message types.
|
||||
|
||||
@@ -2144,7 +2144,7 @@ static void* dnstap_io(void* arg)
|
||||
#endif
|
||||
log_thread_set(&dtio->threadnum);
|
||||
|
||||
ub_thread_setname(dtio->tid, name);
|
||||
ub_thread_setname(ub_thread_self(), name);
|
||||
|
||||
/* setup */
|
||||
verbose(VERB_ALGO, "start dnstap io thread");
|
||||
|
||||
@@ -1659,7 +1659,8 @@ struct outbound_entry* worker_send_query(
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
|
||||
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited),
|
||||
int* ATTR_UNUSED(ratelimit_incremented))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
@@ -1693,7 +1694,8 @@ struct outbound_entry* libworker_send_query(
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
|
||||
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited),
|
||||
int* ATTR_UNUSED(ratelimit_incremented))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
@@ -1,3 +1,507 @@
|
||||
24 July 2026: Wouter
|
||||
- Merge #1433 from jisakiel: Add new static zone type
|
||||
block_aaaa to suppress AAAA queries.
|
||||
- Unit test for block_a and block_aaaa.
|
||||
- Fix #1477: respip + dns64: dns64 uses A records modified by
|
||||
respip instead of original A records. Adds local-zone types
|
||||
block_a_wdata and block_aaaa_wdata, that are like block_a
|
||||
and block_aaaa, and uses local-data if present.
|
||||
- set code repository version to 1.26.0.
|
||||
- Update generated man pages.
|
||||
- Fix to allow test fake sha1 on systems with possible sha1
|
||||
support.
|
||||
- Fix to use sha256 for unbound-anchor unit test.
|
||||
- Fix unbound-anchor check for return value of
|
||||
X509_NAME_get_text_by_NID of the emailaddress.
|
||||
- Fix lock test protect for auth zone change.
|
||||
- Fix to lock shared_ports structure during initialisation.
|
||||
- Fix to lock anchor structure when file is set for it in
|
||||
parse of the header.
|
||||
- Merge #1480 from petrvaganoff: authzone: fix memory leak in
|
||||
xfer_set_masters() error path.
|
||||
- Fix unused variable warnings in shared_ports_fetch_random
|
||||
and shared_ports_return_port when compiled without threads.
|
||||
- Fix to guard access to shared ports interface array during
|
||||
set up, for analyzer.
|
||||
- Fix sign of comparison warning in shared ports setup.
|
||||
- Fix #1481: Fix to use tls-port after referral if
|
||||
tls-upstream is set.
|
||||
- Merge #1479 from psumbera: Fix pthread detection on
|
||||
Solaris 11.4.
|
||||
- Fix to call OPENSSL_cleanup on exit when that is defined.
|
||||
|
||||
23 July 2026: Wouter
|
||||
- Updated credits for Xuanchao Xie in 22 july changelog.
|
||||
- Merge #1478 from petrvaganoff: pythonmod: add check return
|
||||
value after ftell().
|
||||
- Fix that for NSEC3 proofs the NSEC3 zone, as the b32.name is
|
||||
checked to be the same as the signer name. Also RRSIGs are
|
||||
not considered valid when an NSEC3 is not b32.signerzone.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that the aggressive negative cache does not insert NSEC
|
||||
records with overreaching next owner name. Also the result
|
||||
is not above the trust anchor's bailiwick. Also RRSIGS are
|
||||
not considered valid when an NSEC next owner name is not
|
||||
under the signer zone name. Thanks to Qifan Zhang, Palo
|
||||
Alto Networks, for the report.
|
||||
- Fix mesh cycle detection for configuration with respip CNAME
|
||||
loop and tagged clients. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
|
||||
22 July 2026: Wouter
|
||||
- Release tag for 1.25.2, with the security commits:
|
||||
- Fix CVE-2026-14586, Assertion in libngtcp2 when under pressure
|
||||
in high concurrency DNS-over-QUIC environments. Thanks to Kunta
|
||||
Chu, Kaihua Wang, and Jianjun Chen from Tsinghua University,
|
||||
for the report.
|
||||
- Fix CVE-2026-32665, Remote DNS-over-QUIC denial of
|
||||
service due to `quic-size` budget bypass. Thanks to N0zoM1z0
|
||||
(https://github.com/N0zoM1z0) for the report. In addition, thanks to
|
||||
Kunta Chu, Kaihua Wang, and Jianjun Chen from Tsinghua University,
|
||||
for also reporting this issue. In addition, thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for also reporting this issue. In addition,
|
||||
thanks to Xuanchao Xie, Lutong Chen, and Kaiping Xue of the
|
||||
University of Science and Technology of China (USTC), for also
|
||||
reporting this issue.
|
||||
- Fix CVE-2026-40691, Packet of death for DNSCrypt over TCP. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks, for the report. In addition,
|
||||
thanks to Trung Nguyen (@everping) of CyStack, for also reporting
|
||||
this issue.
|
||||
- Fix CVE-2026-41637, Degradation of resolution service from
|
||||
improperly accounted client-terminated DNS-over-QUIC queries. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-42955, Extra fix for CVE-2026-40622 to also clamp
|
||||
the TTL of A/AAAA records disallowing a one-time 'ghost domain'
|
||||
delegation renewal via glue records. Thanks to Qifan Zhang, Palo
|
||||
Alto Networks, for the report.
|
||||
- Fix CVE-2026-44621, Libunbound applications configured with
|
||||
'unwanted-reply-threshold' could eventually be abruptly
|
||||
terminated. Thanks to Qifan Zhang, Palo Alto Networks, for the
|
||||
report.
|
||||
- Fix CVE-2026-44687, Off-by-one error in 'harden-below-nxdomain'
|
||||
logic can shadow a stub/forward zone by a legitimate parent's
|
||||
NXDOMAIN. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-44690, Cross-zone wildcard cache poisoning via
|
||||
RRSIG.labels manipulation. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix CVE-2026-46582, A wildcard replay, as another piece of data,
|
||||
triggers poisoning in the serve expired reply path. Thanks to
|
||||
Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-50045, 'max-global-quota' reset by DNSSEC validation
|
||||
restarts. Thanks to Kunjie Shang, University of Science and
|
||||
Technology of China, for the report.
|
||||
- Fix CVE-2026-50046, Possible heap use-after-free in an error path
|
||||
when a DoT forwarded query is jostled out. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-50243, 'response-ip'/'rpz' can rewrite BOGUS answers
|
||||
instead of returning SERVFAIL. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix CVE-2026-50248, BOGUS configured primary hostname accepted for
|
||||
XFR in auth/rpz zones. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix CVE-2026-50251, Attacker supplied `0.0.0.0`/`::` glue triggers
|
||||
defensive full-cache flush. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix CVE-2026-50252, Possible cache poisoning attack by mapping
|
||||
source port population per thread. Thanks to Inbal Schussheim and
|
||||
Amit Klein, Hebrew University, for the report.
|
||||
- Fix CVE-2026-52863, Memory corruption could lead to crash and
|
||||
denial of service. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix CVE-2026-54478, DNS Cookie bypass when combined with
|
||||
proxy-protocol use. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix CVE-2026-55708, Privacy/configuration issue when adding local
|
||||
data in views through 'unbound-control'. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-55717, 'serve-expired-client-timeout' and 'response-ip'
|
||||
CNAME redirect could lead to a crash. Thanks to Qifan Zhang, Palo
|
||||
Alto Networks, for the report. In addition, thanks to Xin Wang,
|
||||
Jiapeng Li, and Jiajia Liu, Northwestern Polytechnical University,
|
||||
for also reporting this issue.
|
||||
- Fix CVE-2026-55973, 'dns-error-reporting: yes' leads to stack buffer
|
||||
overflow. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-55990, Packet of death for a DNSCrypt misconfigured
|
||||
Unbound. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-55991, Remote DNS-over-QUIC (DoQ) flow-control
|
||||
assertion failure in libngtcp2. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report. In addition, thanks to Xuanchao Xie,
|
||||
Lutong Chen, and Kaiping Xue of the University of Science and
|
||||
Technology of China (USTC), for also reporting this issue.
|
||||
- Fix CVE-2026-56416, Possible heap buffer overflow when validator
|
||||
canonicalizes RDATA that contains domain name. Thanks to Qifan
|
||||
Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-56444, Degradation of resolution service when
|
||||
'discard-timeout' and 'serve-expired-client-timeout' are combined in
|
||||
unusual configuration. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report. In addition, thanks to Xin Wang, Jiapeng Li,
|
||||
and Jiajia Liu, Northwestern Polytechnical University, for also
|
||||
reporting this issue. In addition, thanks to Haruki Oyama (Waseda
|
||||
University), for also reporting this issue.
|
||||
- Set the repository to 1.25.3, it continues with the previous
|
||||
changes.
|
||||
- Unit test for CVE-2026-42955.
|
||||
- Unit test for CVE-2026-44687.
|
||||
- Unit test for CVE-2026-44690.
|
||||
- Unit test for CVE-2026-46582.
|
||||
- Unit test for CVE-2026-50045.
|
||||
- Unit test for CVE-2026-50243.
|
||||
- Unit test for CVE-2026-50248.
|
||||
- Unit test for CVE-2026-55717.
|
||||
- Unit test for CVE-2026-55973.
|
||||
- Unit test for CVE-2026-56416.
|
||||
- Fix error in log printout in fix for CVE-2026-50248, when the
|
||||
primary name is bogus.
|
||||
- iana portlist update.
|
||||
|
||||
21 July 2026: Wouter
|
||||
- Merge #1476 from petrvaganoff: ipsecmod: fix possible deref
|
||||
on null after reply_find_answer_rrset().
|
||||
|
||||
20 July 2026: Wouter
|
||||
- Merge #1475 from petrvaganoff: ipsecmod: fix deref on null
|
||||
in ipsecmod-whitelist after OOM.
|
||||
- Fix #1474: DoQ responses are never padded - pad-responses
|
||||
does not apply to comm_doq (RFC 9250 §5.4 MUST).
|
||||
|
||||
9 July 2026: Wouter
|
||||
- Merge #1383 from jdek: Fix randomness generation on
|
||||
macOS/iOS under chroot.
|
||||
- Fix unit test for malformed svcb for test on Windows.
|
||||
|
||||
2 July 2026: Wouter
|
||||
- Merge #1087: Overload `local_data_remove` to support removing
|
||||
specific records.
|
||||
|
||||
30 June 2026: Wouter
|
||||
- Fix #1469: dohclient: DoH POST missing content-length → :status
|
||||
400 from strict resolvers (Cloudflare, Mullvad).
|
||||
- iana portlist updated.
|
||||
|
||||
26 June 2026: Wouter
|
||||
- Merge #1467: daemon: fix DEREF_AFTER_NULL.EX.COND on
|
||||
worker_init. This fixes error handling if the worker
|
||||
stat_timer allocation has an out of memory error. That
|
||||
makes the server not crash later, attempting to use it.
|
||||
|
||||
24 June 2026: Wouter
|
||||
- Merge #1465 from dag-erling: Add libunbound/remote.h. Add
|
||||
a shared header containing prototypes for functions that
|
||||
both ends of a remote control connection need to implement.
|
||||
|
||||
19 June 2026: Wouter
|
||||
- Fix for #1457: fix thread setname for thread start of
|
||||
dnstap, and fast_reload.
|
||||
- Fix to update github ci actions/checkout to v7.
|
||||
- Fix warning about file_string_matches in unbound-checkconf.
|
||||
|
||||
17 June 2026: Wouter
|
||||
- Fix that after fast_reload the disown of the auth zone
|
||||
transfer task cleans the chunk list. Also fix the
|
||||
auth_transfer_limit test to use a forwarder for each type
|
||||
of failure, so the one is not blocked by the other waiting.
|
||||
- Fix to remove debug from auth_transfer_limit test.
|
||||
- Fix that unbound-checkconf checks if an auth-zone download
|
||||
can overwrite another file, by filename collision.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that malloc failure in auth-zone insert rr does
|
||||
not create an empty node and does not cause an infinite
|
||||
loop. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix that unbound-control auth_zone_reload stops the
|
||||
server answering from the zone after a failure to read.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that malloc failure in dns64_inform_super does
|
||||
not set up a half-built reply for cache store, that could
|
||||
lead to a crash. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix that malloc failure for new_local_rrset for RPZ qname
|
||||
trigger RR insert does not crash. It does not link a
|
||||
partial RRset, and logs an error on failure, and cleans
|
||||
up the dname allocation. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix that malloc failure in doq connection setup, does
|
||||
not crash in doq connection delete later. Thanks to Qifan
|
||||
Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that malloc failure for ngtcp2_conn_server_new
|
||||
cleans up reference that older ngtcp2 versions can leave.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that on malloc failure during accept of TCP, the
|
||||
socket is not left to cause a read event loop. It uses
|
||||
slow-accept to delay accepting new connections, if
|
||||
that fails it drops the new connections. When the tcp
|
||||
connection usage is full, it waits for 50msec, to allow
|
||||
existing queries to be resolved. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix that malloc failure for rpz_strip_nsdname is
|
||||
checked and handled, so that it does not crash later.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that malloc failure during edns subnet addrtree
|
||||
insert is checked, so it does not crash later. Thanks to
|
||||
Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix to check the return value of auth_xfer_create
|
||||
during fast_reload auth-zone add and change processing.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix to check for malloc failure in rpz response create,
|
||||
for nodata and nxdomain, so it does not crash later.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that fast_reload does not terminate the server
|
||||
on malloc failure for dnstap, or if gethostname fails.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix after malloc failure for stats, then it drains the pipe
|
||||
so the internal messaging stays correct. Also it does
|
||||
not exit the server if stats pipe communication fails.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that fast_reload does not terminate the server
|
||||
on config read failure after malloc failure. Thanks to
|
||||
Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that fast_reload does not terminate the server if
|
||||
random init for DNS cookies fails. The data is only random
|
||||
generated if cookies are enabled, and the random data
|
||||
is necessary. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
|
||||
17 June 2026: Yorgos
|
||||
- Fix memory leak on DNAME 0TTL records.
|
||||
|
||||
16 June 2026: Wouter
|
||||
- Fix to disallow $INCLUDE for secondary zones. Start up
|
||||
of server continues if a secondary zone fails to load.
|
||||
Failed loads clear the zone data, so there is no partial
|
||||
zone. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix that when SVCB records cannot be written out, and
|
||||
are written in unknown format, that the zone read allows
|
||||
such unknown format SVCB records. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix that a half-written trust anchor file does not crash
|
||||
the server at runtime. It unlinks a wrong file from the list.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that auth-zone, and RPZ zones, do not allow out-of-zone
|
||||
records. These are records that are not under the zone apex.
|
||||
The out-of-zone records are dropped from the zone contents.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that dns64 does not ignore the `forward-no-cache` and
|
||||
`stub-no-cache` options. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix that a signed wildcard NSEC, is checked before use,
|
||||
so it does not allow insecure DS proofs inappropriately.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that after malloc failure a half-built local_alias does
|
||||
not crash the server. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix that for a zonefile only zone, if that file does not
|
||||
exist on server start, the server continues to start with
|
||||
a warning log message. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix that after malloc failure in RPZ load a half built
|
||||
list does not crash later. The newly created RRset is
|
||||
linked after creation has succeeded. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix that dnscrypt configuration does not crash, due to
|
||||
inconsistency between secret and public keys. Also
|
||||
duplicate files are skipped. Thanks to Qifan Zhang, Palo
|
||||
Alto Networks, for the report.
|
||||
- Fix locking in libunbound ub_ctx_set_event call.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that libunbound pipe functions fail with error after
|
||||
an event base is set. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix for neater solution to clear log thread id after
|
||||
worker init failure. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix incorrect cleanup after an allocation failure for
|
||||
a delegation point. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix that after malloc failure in find_tag_datas, the
|
||||
local_alias is cleaned up. Thanks to Qifan Zhang, Palo
|
||||
Alto Networks, for the report.
|
||||
- Fix that after shared memory cannot be created, from
|
||||
`shm-enable`, the server does not crash. Thanks to Qifan
|
||||
Zhang, Palo Alto Networks, for the report.
|
||||
- Fix incorrect cleanup after an allocation failure for
|
||||
a delegation point in a region. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix after malloc failure the rrset_insert_rr in
|
||||
localzone processing, during RPZ qname trigger processing,
|
||||
the RRset retains its previous data correcly. Thanks to
|
||||
Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix for #1462: Fix that auth primary host name lookup
|
||||
allows CNAMEs.
|
||||
|
||||
15 June 2026: Wouter
|
||||
- Fix to add `max-transfer-size` and `max-transfer-time` that
|
||||
limit auth-zone and rpz transfer amount and time taken.
|
||||
Default is disabled. This hardens against unbounded
|
||||
transfers. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix perform a full transfer every number of incremental
|
||||
transfers, to stop increasing memory usage, for rpz
|
||||
zones. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix assertion failure for long HTTP header that fills
|
||||
buffer. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix buffer overflow when configured with lower than
|
||||
default size and http transfer. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix that misconfigured `iter-scrub-ns: 0` causes request
|
||||
failures. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix that fast_reload when a zonemd verification lookup
|
||||
it in progress with subnet loaded, deregisters the
|
||||
callback. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix for fast_reload that removes an auth zone while its
|
||||
lookups are in progress, for a primary name. Also after the
|
||||
change, it no longer picks up the old results. Thanks to
|
||||
Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix integer overflow in infra-cache-max-rtt calculation.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix erroneous DNS error report values after bogus AAAA
|
||||
query caused error information that was not cleared by
|
||||
a successful A subquery. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix integer overflow for very high values of
|
||||
`sock-queue-timeout`. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix that fast_reload does not terminate the server for
|
||||
errors in config, for key files. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix log of an aliased qname, to not use freed region
|
||||
memory. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix DNAME synthesis from cache that keeps use of 0TTL
|
||||
entries in a sliding window. It did not surpass RRSIG
|
||||
expiry. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix misconfigured ipsecmod hook causing path name
|
||||
similarity with other file. The ipsecmod is changed for
|
||||
exec of the hook. The ipsecmod hook, if a script, has to
|
||||
start now with a line like `#!/bin/sh`. Thanks to Qifan
|
||||
Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that dns64 bypasses rpz-passthru rule during
|
||||
synthesis. This restricted more than necessary. Thanks to
|
||||
Qifan Zhang, Palo Alto Networks, for the report.
|
||||
|
||||
12 June 2026: Wouter
|
||||
- Fix that for auth-zone and rpz zones the allow-notify
|
||||
addresses and netblocks are available from start, and
|
||||
fix the probe step skip.
|
||||
|
||||
11 June 2026: Wouter
|
||||
- Fix for #1306: configure detects specifically the call to
|
||||
SSL_set_quic_tls_early_data_enabled and
|
||||
SSL_set_quic_early_data_enabled, so the correct one is used.
|
||||
- Fix for #1306: configure checks if the ngtcp2_crypto_ossl
|
||||
header file is available, and prints an error otherwise.
|
||||
- Fix #1437: Fix compile with OpenSSL 4.0.1.
|
||||
- Fix compile for OpenSSL 1.0.2 and before in server cleanup.
|
||||
|
||||
10 June 2026: Wouter
|
||||
- Fix pythonmod script read for numeric overflow.
|
||||
- Fix warnings with gcc in compat/inet_pton.c.
|
||||
|
||||
9 June 2026: Wouter
|
||||
- Fix unit test for ecs to check for malloc success.
|
||||
|
||||
3 June 2026: Wouter
|
||||
- Fix that the processing of class responses does not have
|
||||
a heap use-after-free. That could happen if at least two
|
||||
distinct classes are configured for resolution. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks for the report.
|
||||
In addition, thanks to Xin Wang, Jiapeng Li, and Jiajia
|
||||
Liu, Northwestern Polytechnical University, for also
|
||||
reporting this.
|
||||
- Fix negative cache to work with NSEC3 records without salt.
|
||||
Thanks to Xin Wang, Jiapeng Li, and Jiajia Liu, Northwestern
|
||||
Polytechnical University, for the report.
|
||||
- Fix parse of svcbparam ech, it had incorrect length. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks for the report.
|
||||
- Fix that quotation and escaping works the same in auth-zone
|
||||
url content, as in the zonefile read. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks for the report.
|
||||
- Fix ipset module to use larger domain name buffers, and
|
||||
check buffer lengths. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks for the report.
|
||||
- Fix PROXYv2 header read and consume, it checks the header
|
||||
size. Thanks to Qifan Zhang, Palo Alto Networks for
|
||||
the report.
|
||||
- Fix negative cache NSEC3 nodata proof, to use the correct
|
||||
message size. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix fast_reload for when a ZONEMD lookup is in progress.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that validation canonicalization of domain names
|
||||
in rdata checks for buffer bounds. Thanks to Qifan Zhang,
|
||||
Palo Alto Networks, for the report.
|
||||
- Fix that dump_cache has a larger buffer for records,
|
||||
and it checks that an owner name does not collide with BADRR
|
||||
on the input, and changes verbosity on the log of failure in
|
||||
rrset to string. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix that dns64 cleans up the allocated message if the adjust
|
||||
routines fail, and checks if there is a reply before cache
|
||||
store, also unbound checks if A and AAAA are malformed
|
||||
for auth-zones. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
|
||||
3 June 2026: Yorgos
|
||||
- Fix const as reported by newest compiler warnings.
|
||||
|
||||
29 May 2026: Wouter
|
||||
- Fix header_seen detection for trust anchor files, so that it
|
||||
detects the id line.
|
||||
- iana portlist updated.
|
||||
- Update icannbundle.pem certificates in unbound-anchor. It
|
||||
has the public keys for 2009 to 2029 and for 2025 to 2045.
|
||||
- Fix unit test to check for new icannbundle.pem.
|
||||
|
||||
28 May 2026: Wouter
|
||||
- Fix #1457: race condition causes segfault when starting
|
||||
threads.
|
||||
|
||||
27 May 2026: Wouter
|
||||
- Fix for autotrust state-file line overflow, that can give
|
||||
hold-down bypass. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix to limit the DSNS per-label walk in the iterator. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that the ratelimit is decremented on successful
|
||||
referrals. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix that msgencode insert_query has the correct assertion,
|
||||
for a local_alias. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix to reset the tcp-timeout before applying a load based
|
||||
reduction. Thanks to Qifan Zhang, Palo Alto Networks, for the
|
||||
report.
|
||||
- Fix to decrement the per-netblock tcp connection limits, so
|
||||
it keeps usable. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix manual to document ratelimit, that it is for target
|
||||
nameservers for a domain, and keeps queries limited. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix, in depth, for respip rewrite of dns64 responses. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that dns64 with subnetcache does not write ECS scoped
|
||||
answers to global cache. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix ipset module for name too long checks, race conditions
|
||||
on local name buffer, and for socket close race condition.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix that validator caps number of ANY RRsets it can
|
||||
validate, and the wait timer is shortened. Thanks to Qifan
|
||||
Zhang, Palo Alto Networks, for the report.
|
||||
- Fix analyzer warning in mesh_new_client.
|
||||
|
||||
26 May 2026: Wouter
|
||||
- Fix for mesh new client and mesh new callback to rollback the
|
||||
added address, tcp mesh state and callback when there is a failure
|
||||
to initialize. This fixes the mesh accounting of reply addresses.
|
||||
Thanks to Xin Wang, Jiapeng Li, and Jiajia Liu, Northwestern
|
||||
Polytechnical University, for the report
|
||||
|
||||
20 May 2026: Wouter
|
||||
- Fix CVE-2026-33278, Possible remote code execution during DNSSEC
|
||||
validation. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
@@ -27,6 +531,79 @@
|
||||
Networks, for the report.
|
||||
- Fix CVE-2026-44608, Use after free and crash in RPZ code. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Tag for 1.25.1 release, it contains the security fixes on 1.25.0.
|
||||
the code repository continues with in addition the previous fixes,
|
||||
for 1.25.2.
|
||||
- Unit test for CVE-2026-33278.
|
||||
- Unit test for CVE-2026-42944.
|
||||
- Unit test for CVE-2026-42959.
|
||||
- Unit test for CVE-2026-40622.
|
||||
- Unit test for CVE-2026-42960.
|
||||
- Fix in depth for serve-expired responses from cachedb, that it
|
||||
does not store bogus. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix lame server detection, for selfpointed glue records.
|
||||
Thanks to Shuhan Zhang, Dan Li, and Baojun Liu from Tsinghua
|
||||
University for the report.
|
||||
- Fix cleaning up DoH session. The same query can be on multiple
|
||||
streams in a session. Thanks to Qifan Zhang, Palo Alto Networks,
|
||||
for the report.
|
||||
- Fix for signed same-owner CNAME and ordinary RRset responses.
|
||||
Thanks to Xin Wang and Jiajia Liu, Northwestern Polytechnical
|
||||
University, for the report.
|
||||
|
||||
18 May 2026: Wouter
|
||||
- Fix for mixed class referrals, the resolver uses the query
|
||||
class. Thanks to Xin Wang and Jiajia Liu, Northwestern
|
||||
Polytechnical University, for the report.
|
||||
|
||||
15 May 2026: Wouter
|
||||
- Fix man page entry for so-sndbuf, it is for responses sent out.
|
||||
- Fix val_find_DS for robustness, to check the result of
|
||||
packet_rrset_copy_region before using it. Thanks to Xin Wang
|
||||
and Jiajia Liu, Northwestern Polytechnical University, for
|
||||
the report.
|
||||
- Fix that for dns64 answers, the AAAA query is checked to be
|
||||
DNSSEC validated, when DNSSEC is enabled. This improves
|
||||
the RFC6147 conformance of Unbound. Thanks to Xin Wang
|
||||
and Jiajia Liu, Northwestern Polytechnical University, for
|
||||
the report. In addition, thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for reporting it.
|
||||
- Fix for allocation-failure hardening of rrset cache wildcard
|
||||
storage and canonical NSEC owner replacement. Thanks to Xin
|
||||
Wang and Jiajia Liu, Northwestern Polytechnical University,
|
||||
for the report.
|
||||
- Fix DNSSEC validation with libnettle for noncanonical RSA
|
||||
DNSKEYs with leading zeroes for n. Thanks to Xin Wang and
|
||||
Jiajia Liu, Northwestern Polytechnical University, for
|
||||
the report.
|
||||
- Fix DNSKEY size calculation for noncanonical RSA DNSKEYs
|
||||
with leading zeroes for n. Thanks to Xin Wang and Jiajia Liu,
|
||||
Northwestern Polytechnical University, for the report.
|
||||
|
||||
11 May 2026: Yorgos
|
||||
- Fix comment and verbose logging for EDNS fallback buffer size.
|
||||
|
||||
8 May 2026: Wouter
|
||||
- Fix to relax assertions after the TTL 0 handling change.
|
||||
This relaxes an assertion in cachedb (it fails instead),
|
||||
and for packet_rrset_copy_region.
|
||||
|
||||
7 May 2026: Wouter
|
||||
- Fix for Heap Out-of-Bounds Write via size_t-to-int Truncation
|
||||
in setup_if() - outside_network_create(). This fixes that
|
||||
large values for num_ports do not overflow and create
|
||||
invalid references after integer truncation. Thanks
|
||||
to Karnakar Reddy (@karnakarreddi) for the report.
|
||||
- Fix to clean up log ids after a failure to start a worker thread.
|
||||
|
||||
1 May 2026: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
29 April 2026: Wouter
|
||||
- tag for 1.25.0. The code repository continues with 1.25.1 in
|
||||
development.
|
||||
- Fix windows 64bit build for libssp dependency.
|
||||
|
||||
23 April 2026: Wouter
|
||||
- Merge #1441: Fix buffer overrun in
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
README for Unbound 1.25.2
|
||||
README for Unbound 1.26.0
|
||||
Copyright 2007 NLnet Labs
|
||||
http://unbound.net
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page, version 1.25.2.
|
||||
# See unbound.conf(5) man page, version 1.26.0.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
@@ -899,6 +899,10 @@ server:
|
||||
# that name
|
||||
# o block_a resolves all records normally but returns
|
||||
# NODATA for A queries and ignores local data for that name
|
||||
# o block_aaaa similarly to block_a, resolves all records normally but
|
||||
# returns NODATA for AAAA queries and ignores local data for that name
|
||||
# o block_a_wdata like block_a but uses local data if present.
|
||||
# o block_aaaa_wdata like block_aaaa but uses local data if present.
|
||||
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
#
|
||||
@@ -1287,6 +1291,9 @@ remote-control:
|
||||
# zonemd-check: no
|
||||
# zonemd-reject-absence: no
|
||||
# zonefile: "example.org.zone"
|
||||
# max-transfer-size: 0
|
||||
# max-transfer-time: 0
|
||||
|
||||
|
||||
# Views
|
||||
# Create named views. Name must be unique.
|
||||
@@ -1453,3 +1460,5 @@ remote-control:
|
||||
# rpz-signal-nxdomain-ra: no
|
||||
# for-downstream: no
|
||||
# tags: "example"
|
||||
# max-transfer-size: 0
|
||||
# max-transfer-time: 0
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page, version 1.25.2.
|
||||
# See unbound.conf(5) man page, version 1.26.0.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
@@ -899,6 +899,10 @@ server:
|
||||
# that name
|
||||
# o block_a resolves all records normally but returns
|
||||
# NODATA for A queries and ignores local data for that name
|
||||
# o block_aaaa similarly to block_a, resolves all records normally but
|
||||
# returns NODATA for AAAA queries and ignores local data for that name
|
||||
# o block_a_wdata like block_a but uses local data if present.
|
||||
# o block_aaaa_wdata like block_aaaa but uses local data if present.
|
||||
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
#
|
||||
@@ -1287,6 +1291,9 @@ remote-control:
|
||||
# zonemd-check: no
|
||||
# zonemd-reject-absence: no
|
||||
# zonefile: "example.org.zone"
|
||||
# max-transfer-size: 0
|
||||
# max-transfer-time: 0
|
||||
|
||||
|
||||
# Views
|
||||
# Create named views. Name must be unique.
|
||||
@@ -1453,3 +1460,5 @@ remote-control:
|
||||
# rpz-signal-nxdomain-ra: no
|
||||
# for-downstream: no
|
||||
# tags: "example"
|
||||
# max-transfer-size: 0
|
||||
# max-transfer-time: 0
|
||||
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "LIBUNBOUND" "3" "Jul 22, 2026" "1.25.2" "Unbound"
|
||||
.TH "LIBUNBOUND" "3" "Aug 4, 2026" "1.26.0" "Unbound"
|
||||
.SH NAME
|
||||
libunbound \- Unbound DNS validating resolver 1.25.2 functions.
|
||||
libunbound \- Unbound DNS validating resolver 1.26.0 functions.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fB#include <unbound.h>\fP
|
||||
|
||||
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "LIBUNBOUND" "3" "Jul 22, 2026" "1.25.2" "Unbound"
|
||||
.TH "LIBUNBOUND" "3" "Aug 4, 2026" "1.26.0" "Unbound"
|
||||
.SH NAME
|
||||
libunbound \- Unbound DNS validating resolver 1.25.2 functions.
|
||||
libunbound \- Unbound DNS validating resolver 1.26.0 functions.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fB#include <unbound.h>\fP
|
||||
|
||||
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "UNBOUND-ANCHOR" "8" "Jul 22, 2026" "1.25.2" "Unbound"
|
||||
.TH "UNBOUND-ANCHOR" "8" "Aug 4, 2026" "1.26.0" "Unbound"
|
||||
.SH NAME
|
||||
unbound-anchor \- Unbound 1.25.2 anchor utility.
|
||||
unbound-anchor \- Unbound 1.26.0 anchor utility.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fBunbound\-anchor\fP [\fBopts\fP]
|
||||
|
||||
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "UNBOUND-ANCHOR" "8" "Jul 22, 2026" "1.25.2" "Unbound"
|
||||
.TH "UNBOUND-ANCHOR" "8" "Aug 4, 2026" "1.26.0" "Unbound"
|
||||
.SH NAME
|
||||
unbound-anchor \- Unbound 1.25.2 anchor utility.
|
||||
unbound-anchor \- Unbound 1.26.0 anchor utility.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fBunbound\-anchor\fP [\fBopts\fP]
|
||||
|
||||
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "UNBOUND-CHECKCONF" "8" "Jul 22, 2026" "1.25.2" "Unbound"
|
||||
.TH "UNBOUND-CHECKCONF" "8" "Aug 4, 2026" "1.26.0" "Unbound"
|
||||
.SH NAME
|
||||
unbound-checkconf \- Check Unbound 1.25.2 configuration file for errors.
|
||||
unbound-checkconf \- Check Unbound 1.26.0 configuration file for errors.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fBunbound\-checkconf\fP [\fB\-hf\fP] [\fB\-o option\fP] [cfgfile]
|
||||
|
||||
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "UNBOUND-CHECKCONF" "8" "Jul 22, 2026" "1.25.2" "Unbound"
|
||||
.TH "UNBOUND-CHECKCONF" "8" "Aug 4, 2026" "1.26.0" "Unbound"
|
||||
.SH NAME
|
||||
unbound-checkconf \- Check Unbound 1.25.2 configuration file for errors.
|
||||
unbound-checkconf \- Check Unbound 1.26.0 configuration file for errors.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fBunbound\-checkconf\fP [\fB\-hf\fP] [\fB\-o option\fP] [cfgfile]
|
||||
|
||||
@@ -27,9 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "UNBOUND-CONTROL" "8" "Jul 22, 2026" "1.25.2" "Unbound"
|
||||
.TH "UNBOUND-CONTROL" "8" "Aug 4, 2026" "1.26.0" "Unbound"
|
||||
.SH NAME
|
||||
unbound-control \- Unbound 1.25.2 remote server control utility.
|
||||
unbound-control \- Unbound 1.26.0 remote server control utility.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fBunbound\-control\fP [\fB\-hq\fP] [\fB\-c cfgfile\fP] [\fB\-s server\fP] command
|
||||
@@ -354,6 +354,8 @@ If the name already has no items, nothing happens.
|
||||
Often results in NXDOMAIN for the name (in a static zone), but if the name
|
||||
has become an empty nonterminal (there is still data in domain names below
|
||||
the removed name), NOERROR nodata answers are the result for that name.
|
||||
With a specific RR instead of a domain name, that specific record is
|
||||
removed from the local data, and not all the RR data.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
|
||||
Loaded 100 of 225 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user