ALT Linux Bugzilla
– Attachment 13358 Details for
Bug 46359
Обновление исходников до версии 4.9.0
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
[patch]
4.8.0 -> 4.9.0
screen-update.patch (text/plain), 231.83 KB, created by
Danil Nazarov
on 2023-06-01 15:53:19 MSK
(
hide
)
Description:
4.8.0 -> 4.9.0
Filename:
MIME Type:
Creator:
Danil Nazarov
Created:
2023-06-01 15:53:19 MSK
Size:
231.83 KB
patch
obsolete
>diff -ur screen.orig/ansi.c screen/ansi.c >--- screen.orig/ansi.c 2023-06-01 14:58:17.230665007 +0300 >+++ screen/ansi.c 2022-01-28 17:06:02.666611503 +0300 >@@ -727,8 +727,8 @@ > break; > } > # ifdef DW_CHARS >- if (curr->w_encoding == UTF8 && utf8_isdouble(c)) >- curr->w_mbcs = 0xff; >+ if (curr->w_encoding == UTF8 && utf8_isdouble(c)) >+ curr->w_mbcs = 0xff; > # endif > font = curr->w_rend.font; > # endif >@@ -3027,7 +3027,7 @@ > WMsg(p, err, str) > struct win *p; > int err; >-const char *str; >+char *str; > { > extern struct layer *flayer; > struct layer *oldflayer = flayer; >diff -ur screen.orig/attacher.c screen/attacher.c >--- screen.orig/attacher.c 2023-06-01 14:58:17.231665009 +0300 >+++ screen/attacher.c 2022-01-28 17:06:02.666611503 +0300 >@@ -33,14 +33,9 @@ > #include <sys/ioctl.h> > #include <fcntl.h> > #include <signal.h> >-#include <syslog.h> > #include "screen.h" > #include "extern.h" > >-#ifdef USE_PAM >-#include <security/pam_userpass.h> >-#endif >- > #include <pwd.h> > > static int WriteMessage __P((int, struct msg *)); >@@ -59,7 +54,7 @@ > #endif > static sigret_t AttachSigCont __P(SIGPROTOARG); > >-extern int real_uid, real_gid, eff_uid, eff_gid, init_eff_gid; >+extern int real_uid, real_gid, eff_uid, eff_gid; > extern int ServerSocket; > extern struct display *displays; > extern char *SockName, *SockMatch, SockPath[]; >@@ -704,7 +699,7 @@ > /* ADDED by Rainer Pruy 10/15/87 */ > /* POLISHED by mls. 03/10/91 */ > >-static const char LockEnd[] = "Welcome back to screen !!\n"; >+static char LockEnd[] = "Welcome back to screen !!\n"; > > static sigret_t > LockHup SIGDEFARG >@@ -741,7 +736,6 @@ > { > signal(SIGCHLD, SIG_DFL); > debug1("lockterminal: '%s' seems executable, execl it!\n", prg); >- fflush(NULL); > if ((pid = fork()) == 0) > { > /* Child */ >@@ -821,7 +815,6 @@ > > #ifdef USE_PAM > >-#if 0 > /* > * PAM support by Pablo Averbuj <pablo@averbuj.com> > */ >@@ -876,13 +869,8 @@ > &PAM_conv, > NULL > }; >-#endif > >-static pam_userpass_t userpass; >-static struct pam_conv conv = { >- &pam_userpass_conv, >- &userpass >-}; >+ > #endif > > /* -- original copyright by Luigi Cannelloni 1985 (luigi@faui70.UUCP) -- */ >@@ -891,10 +879,9 @@ > { > char fullname[100], *cp1, message[100 + 100]; > #ifdef USE_PAM >- int status; >- pam_handle_t *pamh = NULL; >-#else >- char *pass, mypass[16 + 1], salt[3]; >+ pam_handle_t *pamh = 0; >+ int pam_error; >+ char *tty_name; > #endif > char *pass = 0, mypass[16 + 1], salt[3]; > int using_pam = 1; >@@ -976,35 +963,23 @@ > if (using_pam) > { > #ifdef USE_PAM >- userpass.user = ppp->pw_name; >- userpass.pass = cp1; >- >- openlog("screen", LOG_PID, LOG_AUTH); >- status = pam_start("screen", ppp->pw_name, &conv, &pamh); >- >- if (status == PAM_SUCCESS) >- { >- /* Let the PAM modules make use of our SGID privileges. */ >- xsetegid(init_eff_gid); >- if ((status = pam_authenticate(pamh, 0)) != PAM_SUCCESS) >- { >- xsetegid(real_gid); >- pam_end(pamh, status); >- continue; >- } >- xsetegid(real_gid); >+ PAM_conversation.appdata_ptr = cp1; >+ pam_error = pam_start("screen", ppp->pw_name, &PAM_conversation, &pamh); >+ if (pam_error != PAM_SUCCESS) >+ AttacherFinit(SIGARG); /* goodbye */ > >- status = pam_end(pamh, PAM_SUCCESS); >- if (status == PAM_SUCCESS) >- { >- memset(cp1, 0, strlen(cp1)); >- userpass.pass = NULL; >- break; >- } >- } >- >-#else >- if (!strncmp(crypt(cp1, pass), pass, strlen(pass))) >+ if (strncmp(attach_tty, "/dev/", 5) == 0) >+ tty_name = attach_tty + 5; >+ else >+ tty_name = attach_tty; >+ pam_error = pam_set_item(pamh, PAM_TTY, tty_name); >+ if (pam_error != PAM_SUCCESS) >+ AttacherFinit(SIGARG); /* goodbye */ >+ >+ pam_error = pam_authenticate(pamh, 0); >+ pam_end(pamh, pam_error); >+ PAM_conversation.appdata_ptr = 0; >+ if (pam_error == PAM_SUCCESS) > break; > #endif > } >diff -ur screen.orig/autogen.sh screen/autogen.sh >--- screen.orig/autogen.sh 2023-06-01 14:58:17.231665009 +0300 >+++ screen/autogen.sh 2022-01-28 17:06:02.666611503 +0300 >@@ -1,2 +1,2 @@ > #!/bin/sh >-exec autoreconf >+autoreconf -i >diff -ur screen.orig/braille_tsi.c screen/braille_tsi.c >--- screen.orig/braille_tsi.c 2023-06-01 14:58:17.231665009 +0300 >+++ screen/braille_tsi.c 2022-01-28 17:06:02.670611602 +0300 >@@ -6,7 +6,7 @@ > * Bill Barry barryb@dots.physics.orst.edu > * > * Copyright (c) 1995 by Science Access Project, Oregon State University. >- * >+ * > * > * This program is free software; you can redistribute it and/or modify > * it under the terms of the GNU General Public License as published by >@@ -36,21 +36,20 @@ > extern struct display *display; > > struct key2rc { >- int key; >- int nr; >- char *arg1; >- char *arg2; >+ int key; >+ int nr; >+ char *arg1; >+ char *arg2; > }; > >+static int tsi_ctype = 1; /* cursor type, 0,1,2 */ > >-static int tsi_ctype = 1; /* cursor type, 0,1,2 */ >- >-static int tsi_line_type; /* indicates number of cells on powerbraille >- display 01=20 cells 02=40 cells 03=80 cells */ >+static int tsi_line_type; /* indicates number of cells on powerbraille >+ display 01=20 cells 02=40 cells 03=80 cells */ > > static int display_status_tsi __P((void)); >-static int write_line_tsi __P((char *, int, int)); >-static void buttonpress_tsi __P((struct key2rc *)); >+static int write_line_tsi __P((char*, int, int)); >+static void buttonpress_tsi __P((structkey2rc*)); > static void buttonpress_navigator_40 __P((void)); > static void buttonpress_powerbraille_40 __P((void)); > static void buttonpress_powerbraille_80 __P((void)); >@@ -58,262 +57,258 @@ > int > bd_init_powerbraille_40() > { >- bd.write_line_braille = write_line_tsi; >- bd.buttonpress = buttonpress_powerbraille_40; >- bd.bd_response_test = display_status_tsi; >- bd.bd_ncells = 40; >- tsi_line_type = 2; >- return 0; >+ bd.write_line_braille = write_line_tsi; >+ bd.buttonpress = buttonpress_powerbraille_40; >+ bd.bd_response_test = display_status_tsi; >+ bd.bd_ncells = 40; >+ tsi_line_type = 2; >+ return 0; > } > > int > bd_init_powerbraille_80() > { >- bd.write_line_braille = write_line_tsi; >- bd.buttonpress = buttonpress_powerbraille_80; >- bd.bd_response_test = display_status_tsi; >- bd.bd_ncells = 80; >- tsi_line_type = 3; >- return 0; >+ bd.write_line_braille = write_line_tsi; >+ bd.buttonpress = buttonpress_powerbraille_80; >+ bd.bd_response_test = display_status_tsi; >+ bd.bd_ncells = 80; >+ tsi_line_type = 3; >+ return 0; > } > > int > bd_init_navigator_40() > { >- bd.write_line_braille = write_line_tsi; >- bd.buttonpress = buttonpress_navigator_40; >- bd.bd_response_test = display_status_tsi; >- bd.bd_ncells = 40; >- tsi_line_type = 2; >- return 0; >+ bd.write_line_braille = write_line_tsi; >+ bd.buttonpress = buttonpress_navigator_40; >+ bd.bd_response_test = display_status_tsi; >+ bd.bd_ncells = 40; >+ tsi_line_type = 2; >+ return 0; > } > >-static int >+static int > display_status_tsi() > { >- char obuf[3],ibuf[20]; >- int r; >+ char obuf[3], ibuf[20]; >+ int r; > >- obuf[0] = 0xff; >- obuf[1] = 0xff; >- obuf[2] = 0x0a; >- r = read(bd.bd_fd, ibuf, 20); /* flush the input port */ >- r = write(bd.bd_fd, obuf, 3); >- if (r != 3) >- return -1; >+ obuf[0] = 0xff; >+ obuf[1] = 0xff; >+ obuf[2] = 0x0a; >+ r = read(bd.bd_fd, ibuf, 20); /* flush the input port */ >+ r = write(bd.bd_fd, obuf, 3); >+ if (r != 3) >+ return -1; > > /* we have written to the display asking for a response >- we wait 1 second for the response, read it and if no >+ we wait 1 second for the response, read it and if no > response we wait 2 seconds, if still no response, > return -1 to indicate no braille display available */ >- sleep(1); >- r = read(bd.bd_fd, ibuf, 2); >- if (r == -1) >- { >- sleep(2); >- r = read(bd.bd_fd, ibuf, 2); >- } >- debug2("first chars from braille display %d %d\n",ibuf[0],ibuf[1]); >- if (r != 2 || ibuf[0] != 0 || ibuf[1] != 5) >- return -1; >- >- r= read(bd.bd_fd,ibuf,2); >- if (r != 2) >- return -1; >- debug2("braille display size:%d dots:%d\n", ibuf[0], ibuf[1]); >- bd.bd_ncells = (unsigned char)ibuf[0]; >- if (bd.bd_ncells <= 1) >- return -1; >- r = read(bd.bd_fd,ibuf,1); >- if (r != 1) >- return -1; >- if (ibuf[0] == 'V') >- r = read(bd.bd_fd, ibuf, 3); >- else >- r = read(bd.bd_fd, ibuf + 1, 2) + 1; >- if (r != 3) >- return -1; >- ibuf[3] = 0; >- debug1("braille display version %s\n", ibuf); >- bd.bd_version = atof(ibuf); >- return 0; >+ >+ sleep(1); >+ r = read(bd.bd_fd, ibuf, 2); >+ if (r == -1) { >+ sleep(2); >+ r = read(bd.bd_fd, ibuf, 2); >+ } >+ >+ debug2("first chars from braille display %d %d\n", ibuf[0], ibuf[1]); >+ if (r != 2 || ibuf[0] != 0 || ibuf[1] != 5) >+ return -1; >+ >+ r = read(bd.bd_fd, ibuf, 2); >+ if (r != 2) >+ return -1; >+ >+ debug2("braille display size:%d dots:%d\n", ibuf[0], ibuf[1]); >+ bd.bd_ncells = (unsigned char)ibuf[0]; >+ if (bd.bd_ncells <= 1) >+ return -1; >+ >+ r = read(bd.bd_fd, ibuf, 1); >+ if (r != 1) >+ return -1; >+ >+ if (ibuf[0] == 'V') >+ r = read(bd.bd_fd, ibuf, 3); >+ else >+ r = read(bd.bd_fd, ibuf + 1, 2) + 1; >+ >+ if (r != 3) >+ return -1; >+ >+ ibuf[3] = 0; >+ debug1("braille display version %s\n", ibuf); >+ bd.bd_version = atof(ibuf); >+ return 0; > } >- > >-static int >-write_line_tsi (bstr,line_length, cursor_pos) >-char *bstr; >-int line_length, cursor_pos; >+static int >+write_line_tsi(char *bstr, int line_length, int cursor_pos) > { >- int obp, i; >- bd.bd_obuf[0] = 0xff; >- bd.bd_obuf[1] = 0xff; >- bd.bd_obuf[2] = tsi_line_type; >- bd.bd_obuf[3] = 0x07; >- bd.bd_obuf[4] = cursor_pos; >- bd.bd_obuf[5] = tsi_ctype; >- obp=6; >- >- for (i=0; i < line_length; i++) >- { >- bd.bd_obuf[2*i+obp] = 0; >- bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)(unsigned char)bstr[i]]; >- } >- for (i=line_length; i < bd.bd_ncells; i++) >- { >- bd.bd_obuf[2*i+obp] = 0; >- bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)' ']; >- } >+ int obp, i; >+ bd.bd_obuf[0] = 0xff; >+ bd.bd_obuf[1] = 0xff; >+ bd.bd_obuf[2] = tsi_line_type; >+ bd.bd_obuf[3] = 0x07; >+ bd.bd_obuf[4] = cursor_pos; >+ bd.bd_obuf[5] = tsi_ctype; >+ obp = 6; >+ >+ for (i = 0; i < line_length; i++) { >+ bd.bd_obuf[2*i + obp] = 0; >+ bd.bd_obuf[2*i + 1 + obp] = bd.bd_btable[(int)(unsigned char)bstr[i]]; >+ } >+ for (i = line_length; i < bd.bd_ncells; i++) { >+ bd.bd_obuf[2*i + obp] = 0; >+ bd.bd_obuf[2*i + 1 + obp] = bd.bd_btable[(int)' ']; >+ } > >- bd.bd_obuflen = 2*bd.bd_ncells + obp ; >- return 0; >+ bd.bd_obuflen = 2*bd.bd_ncells + obp; >+ return 0; > } > > static struct key2rc keys_navigator_40[] = { >- {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ >- {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ >- {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ >- {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ >- {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ >- {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ >- {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ >- {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ >- {0x6000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */ >- {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ >- {0x12000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */ >- {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ >- {0xa000, RC_BD_INFO, "1032", 0}, /* bc 6, 8 */ >- {0x14000000, RC_BD_INFO, "2301", 0}, /* sc 1, 3 */ >- {0x4008000, RC_BD_INFO, "3330", 0}, /* bc+sc 1, 8 */ >- {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ >- {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */ >- {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ >- {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ >- {0x10002000, RC_BD_SCROLL, 0, 0}, /* 3, 6 */ >- {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ >- {0x14000, RC_BD_SKIP, 0, 0}, /* 7, 9*/ >- {-1, RC_ILLEGAL, 0, 0} >+ {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ >+ {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ >+ {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ >+ {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ >+ {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ >+ {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ >+ {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ >+ {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ >+ {0x6000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */ >+ {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ >+ {0x12000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */ >+ {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ >+ {0xa000, RC_BD_INFO, "1032", 0}, /* bc 6, 8 */ >+ {0x14000000, RC_BD_INFO, "2301", 0}, /* sc 1, 3 */ >+ {0x4008000, RC_BD_INFO, "3330", 0}, /* bc+sc 1, 8 */ >+ {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ >+ {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */ >+ {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ >+ {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ >+ {0x10002000, RC_BD_SCROLL, 0, 0}, /* 3, 6 */ >+ {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ >+ {0x14000, RC_BD_SKIP, 0, 0}, /* 7, 9*/ >+ {-1, RC_ILLEGAL, 0, 0} > }; > > static struct key2rc keys_powerbraille_40[] = { >- {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ >- {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ >- {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ >- {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ >- {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ >- {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ >- {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ >- {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ >- {0x8002000, RC_BD_UPPER_LEFT, 0, 0}, /* 2, 6 */ >- {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ >- {0x20002000, RC_BD_LOWER_LEFT, 0, 0}, /* 3, 6 */ >- {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ >- {0x8008000, RC_BD_INFO, "1032", 0}, /* bc 2, 8 */ >- {0x6000, RC_BD_INFO, "2301", 0}, /* 6, 7 */ >- {0x8004000, RC_BD_INFO, "3330", 0}, /* bc+sc 2, 7 */ >- {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ >- {0x20008000, RC_BD_EIGHTDOT, 0, 0}, /* 4, 6 */ >- {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ >- {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ >- {0xa000, RC_BD_SCROLL, 0, 0}, /* 6, 8 */ >- {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ >- {0x20004000, RC_BD_SKIP, 0, 0}, /* 4, 7 */ >- {-1, RC_ILLEGAL, 0, 0} >+ {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ >+ {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ >+ {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ >+ {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ >+ {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ >+ {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ >+ {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ >+ {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ >+ {0x8002000, RC_BD_UPPER_LEFT, 0, 0}, /* 2, 6 */ >+ {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ >+ {0x20002000, RC_BD_LOWER_LEFT, 0, 0}, /* 3, 6 */ >+ {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ >+ {0x8008000, RC_BD_INFO, "1032", 0}, /* bc 2, 8 */ >+ {0x6000, RC_BD_INFO, "2301", 0}, /* 6, 7 */ >+ {0x8004000, RC_BD_INFO, "3330", 0}, /* bc+sc 2, 7 */ >+ {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ >+ {0x20008000, RC_BD_EIGHTDOT, 0, 0}, /* 4, 6 */ >+ {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ >+ {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ >+ {0xa000, RC_BD_SCROLL, 0, 0}, /* 6, 8 */ >+ {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ >+ {0x20004000, RC_BD_SKIP, 0, 0}, /* 4, 7 */ >+ {-1, RC_ILLEGAL, 0, 0} > }; > >- > static struct key2rc keys_powerbraille_80[] = { >- {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ >- {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ >- {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ >- {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ >- {0x40000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ >- {0x100000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ >- {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ >- {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ >- {0x44000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */ >- {0x104000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ >- {0x50000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */ >- {0x110000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ >- {0x8100000, RC_BD_INFO, "1032", 0}, /* 2, 8 */ >- {0x8040000, RC_BD_INFO, "2301", 0}, /* 2, 6 */ >- {0x140000, RC_BD_INFO, "3330", 0}, /* 6, 8 */ >- {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ >- {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */ >- {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ >- {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ >- {0x20004000, RC_BD_SCROLL, 0, 0}, /* 4, 7 */ >- {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ >- {0x40010000, RC_BD_SKIP, 0, 0}, /* 5, 9 */ >- {-1, RC_ILLEGAL, 0, 0} >+ {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ >+ {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ >+ {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ >+ {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ >+ {0x40000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ >+ {0x100000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ >+ {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ >+ {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ >+ {0x44000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */ >+ {0x104000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ >+ {0x50000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */ >+ {0x110000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ >+ {0x8100000, RC_BD_INFO, "1032", 0}, /* 2, 8 */ >+ {0x8040000, RC_BD_INFO, "2301", 0}, /* 2, 6 */ >+ {0x140000, RC_BD_INFO, "3330", 0}, /* 6, 8 */ >+ {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ >+ {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */ >+ {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ >+ {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ >+ {0x20004000, RC_BD_SCROLL, 0, 0}, /* 4, 7 */ >+ {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ >+ {0x40010000, RC_BD_SKIP, 0, 0}, /* 5, 9 */ >+ {-1, RC_ILLEGAL, 0, 0} > }; > > static void >-buttonpress_tsi(tab) >-struct key2rc *tab; >+buttonpress_tsi(struct key2rc *tab) > { >- int i, nb; >- int bkeys; >- unsigned char buf[10]; >- nb = read(bd.bd_fd, buf, 10); >- debug1("buttonpress_tsi: read %d bytes\n", nb); >- for (i=0, bkeys=0; i < nb; i++) >- { >- switch (buf[i] & 0xE0) >- { >- case 0x00: bkeys += ((int)(buf[i] & 0x1f) ); break; >- case 0x20: bkeys += ((int)(buf[i] & 0x1f) << 5 ); break; >- case 0x40: bkeys += ((int)(buf[i] & 0x1f) << 9 ); break; >- case 0x60: bkeys += ((int)(buf[i] & 0x1f) << 13 ); break; >- case 0xA0: bkeys += ((int)(buf[i] & 0x1f) << 18 ); break; >- case 0xC0: bkeys += ((int)(buf[i] & 0x1f) << 22 ); break; >- case 0xE0: bkeys += ((int)(buf[i] & 0x1f) << 26 ); break; >- default: break; >+ int i, nb; >+ int bkeys; >+ unsigned char buf[10]; >+ nb = read(bd.bd_fd, buf, 10); >+ debug1("buttonpress_tsi: read %d bytes\n", nb); >+ for (i = 0, bkeys = 0; i < nb; i++) { >+ switch (buf[i] & 0xE0) { >+ case 0x00: bkeys += ((int)(buf[i] & 0x1f)); break; >+ case 0x20: bkeys += ((int)(buf[i] & 0x1f) << 5); break; >+ case 0x40: bkeys += ((int)(buf[i] & 0x1f) << 9); break; >+ case 0x60: bkeys += ((int)(buf[i] & 0x1f) << 13); break; >+ case 0xA0: bkeys += ((int)(buf[i] & 0x1f) << 18); break; >+ case 0xC0: bkeys += ((int)(buf[i] & 0x1f) << 22); break; >+ case 0xE0: bkeys += ((int)(buf[i] & 0x1f) << 26); break; >+ default: break; >+ } > } >- } >- debug1("bkeys %x\n", bkeys); >- for (i = 0; tab[i].key != -1; i++) >- if (bkeys == tab[i].key) >- break; >- debug1("bkey index %d\n", i); >- if (tab[i].key != -1 && tab[i].nr != RC_ILLEGAL) >- { >- char *args[3]; >- int argl[2]; >- >- struct action act; >- args[0] = tab[i].arg1; >- args[1] = tab[i].arg2; >- args[2] = 0; >- argl[0] = args[0] ? strlen(args[0]) : 0; >- argl[1] = args[1] ? strlen(args[1]) : 0; >- act.nr = tab[i].nr; >- act.args = args; >- act.argl = argl; >- display = bd.bd_dpy; >- DoAction(&act, -2); >- } >-} >+ debug1("bkeys %x\n", bkeys); > >+ for (i = 0; tab[i].key != -1; i++) >+ if (bkeys == tab[i].key) >+ break; >+ >+ debug1("bkey index %d\n", i); >+ >+ if (tab[i].key != -1 && tab[i].nr != RC_ILLEGAL) { >+ char *args[3]; >+ int argl[2]; >+ >+ struct action act; >+ args[0] = tab[i].arg1; >+ args[1] = tab[i].arg2; >+ args[2] = 0; >+ argl[0] = args[0] ? strlen(args[0]) : 0; >+ argl[1] = args[1] ? strlen(args[1]) : 0; >+ act.nr = tab[i].nr; >+ act.args = args; >+ act.argl = argl; >+ display = bd.bd_dpy; >+ DoAction(&act, -2); >+ } >+} > > static void > buttonpress_navigator_40() > { >- buttonpress_tsi(keys_navigator_40); >+ buttonpress_tsi(keys_navigator_40); > } > > static void > buttonpress_powerbraille_40() > { >- buttonpress_tsi(keys_powerbraille_40); >+ buttonpress_tsi(keys_powerbraille_40); > } > > static void > buttonpress_powerbraille_80() > { >- buttonpress_tsi(keys_powerbraille_80); >+ buttonpress_tsi(keys_powerbraille_80); > } > > #endif /* HAVE_BRAILLE */ >- >- >diff -ur screen.orig/ChangeLog screen/ChangeLog >--- screen.orig/ChangeLog 2023-06-01 14:58:17.228665002 +0300 >+++ screen/ChangeLog 2022-01-28 17:06:02.662611403 +0300 >@@ -1,18 +1,28 @@ >-Version 4.8.0 (05/02/2020) >+Version 4.9.0 (30/01/2022): >+ * Hardstatus option for used encoding (escape string '%e') >+ * OpenBSD uses native openpty() from its utils.h >+ * Fixes: >+ - fix combining char handling that could lead to a segfault >+ - CVE-2021-26937: possible denial of service via a crafted UTF-8 character sequence (bug #60030) >+ - make screen exit code be 0 when checking --help >+ - session names limit is 80 symbols (bug #61534) >+ - option -X ignores specified user in multiuser env (bug #37437) >+ - a lot of reformations/fixes/cleanups (man page and source code) >+ >+Version 4.8.0 (05/02/2020): > * Improve startup time by only polling for files to close >- Fixes: >+ * Fixes: > - Fix for segfault if termcap doesn't have Km entry > - Make screen exit code be 0 when checking --version > - Fix potential memory corruption when using OSC 49 > >- >-Version 4.7.0 (02/10/2019) >+Version 4.7.0 (02/10/2019): > * Add support for SGR (1006) mouse mode > * Add support for OSC 11 > * Update Unicode ambiguous and wide tables to 12.1.0 > * Fixes: >- - cross-compilation support (bug #43223) >- - a lot of manpage fixes and cleanups >+ - cross-compilation support (bug #43223) >+ - a lot of manpage fixes and cleanups > > Version 4.6.2 (23/10/2017): > * Fixes: >@@ -62,12 +72,11 @@ > * Introduce Xx string escape showing the executed command of a window > * Implement dead/zombie window polling, allowing for auto reconnecting > * Allow setting hardstatus on first line >- >- New Commands: >- * 'sort' command sorting windows by title >- * 'bumpleft', 'bumpright' - manually move windows on window list >- * 'collapse' removing numbering 'gaps' between windows, by renumbering >- * 'windows' command now accepts arguments for use with querying >+ * New Commands: >+ - 'sort' command sorting windows by title >+ - 'bumpleft', 'bumpright' - manually move windows on window list >+ - 'collapse' removing numbering 'gaps' between windows, by renumbering >+ - 'windows' command now accepts arguments for use with querying > > Version 4.2.1 (28/04/2014): > * allow for terminal with long $TERM (up to 32 characters) >@@ -79,8 +88,7 @@ > New Commands: > * 'unbindall' to unbind all commands > * 'up', 'down', 'left', 'right' sub-commands for 'focus' >- * 'rendition' to specify rendition to use in caption/hardstatus for >- window-names that have bell/monitor/silence/so turned on. >+ * 'rendition' to specify rendition to use in caption/hardstatus for window-names that have bell/monitor/silence/so turned on. > * 'layout', with the following sub-commands > - 'title' > - 'number' >@@ -372,8 +380,8 @@ > ======================= > > .screenrc: >- screen now only opens the windows you explicitly ask for. if you >- specify none, you still get one window, of course. >+ screen now only opens the windows you explicitly ask for. >+ If you specify none, you still get one window, of course. > > screen 3.0. Patchlevel 5 > ======================== >@@ -391,7 +399,7 @@ > by a colon. Oldchar and newchar are either single ascii characters, > or the two character sequence ^x, where x is an ascii character, or > a 3 digit octal value prepended with '\'. the string "\040=.:^M=q" >- rebinds '.' to set marks, and the return rey will abort copy mode. >+ rebinds '.' to set marks, and the return key will abort copy mode. > > set scrollback 100 > resizes the scrollback history buffer to 100 lines. a default of 50 >@@ -426,7 +434,7 @@ > > ^A : set vbell_msg "Wuff Wuff" > >-Thousand enhancements: help resizible, copy'n'paste in main >+Thousand enhancements: help resizable, copy'n'paste in main > socket loop, and no more '\0' hackin'. :WS=\E8;%d;%dt: > > screen can now resize windows under sunview. >@@ -454,12 +462,12 @@ > bind 'O' set login off > is valid in your .screenrc as well as typed at the ':' prompt. > a bonus is ":set all" which is synonym to ":help". >- At the Colon prompt also KeyNames can be entered, alothough that makes >+ At the Colon prompt also KeyNames can be entered, although that makes > not always sense. > > ^A x uses a builtin lockprg, if > a) we don't find our lockprg, or >- b) user supplies us with the environmet variable LOCKPRG set to "builtin" >+ b) user supplies us with the environment variable LOCKPRG set to "builtin" > the builtin locks until your login password is typed. on systems using > "shadow password files" you are prompted for a password. > >@@ -480,7 +488,7 @@ > > rare markroutine bug fixed. > >-we dont open every file the attacher tells us. >+we don't open every file the attacher tells us. > > we have now our wonderful "Wuff, Wuff" visual_bell > >diff -ur screen.orig/configure.ac screen/configure.ac >--- screen.orig/configure.ac 2023-06-01 14:58:17.232665011 +0300 >+++ screen/configure.ac 2022-01-28 17:06:02.670611602 +0300 >@@ -172,6 +172,40 @@ > #include <signal.h> > #include <fcntl.h>], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV)) > >+AC_CHECKING(for sequent/ptx) >+AC_EGREP_CPP(YES_IS_DEFINED, >+[#ifdef _SEQUENT_ >+ YES_IS_DEFINED; >+#endif >+], LIBS="$LIBS -lsocket -linet";seqptx=1) >+ >+AC_CHECKING(SVR4) >+AC_EGREP_CPP(yes, >+[main () { >+#if defined(SVR4) || defined(__SVR4) >+ yes; >+#endif >+], AC_NOTE(- you have a SVR4 system) AC_DEFINE(SVR4) svr4=1) >+if test -n "$svr4" ; then >+oldlibs="$LIBS" >+LIBS="$LIBS -lelf" >+AC_CHECKING(SVR4) >+AC_TRY_LINK([#include <utmpx.h> >+],, >+[AC_CHECK_HEADER(dwarf.h, AC_DEFINE(BUGGYGETLOGIN), >+[AC_CHECK_HEADER(elf.h, AC_DEFINE(BUGGYGETLOGIN))])] >+,LIBS="$oldlibs") >+fi >+ >+AC_CHECK_HEADERS([stropts.h string.h strings.h]) >+ >+AC_CHECKING(for Solaris 2.x) >+AC_EGREP_CPP(YES_IS_DEFINED, >+[#if defined(SVR4) && defined(sun) >+ YES_IS_DEFINED; >+#endif >+], LIBS="$LIBS -lsocket -lnsl -lkstat") >+ > dnl > dnl **** typedefs **** > dnl >@@ -280,7 +314,7 @@ > #define S_IFIFO 0010000 > #endif > >-char *fin = "conftest$$"; >+char *fin = "/tmp/conftest$$"; > > main() > { >@@ -328,7 +362,7 @@ > ], AC_NOTE(- your fifos are usable) fifo=1, > AC_NOTE(- your fifos are not usable), > AC_NOTE(- skipping check because we are cross compiling; assuming fifos are usable) fifo=1) >-rm -f conftest* >+rm -f /tmp/conftest* > > if test -n "$fifo"; then > AC_CHECKING(for broken fifo implementation) >@@ -351,7 +385,7 @@ > #define S_IFIFO 0010000 > #endif > >-char *fin = "conftest$$"; >+char *fin = "/tmp/conftest$$"; > > main() > { >@@ -377,7 +411,7 @@ > ], AC_NOTE(- your implementation is ok), > AC_NOTE(- you have a broken implementation) AC_DEFINE(BROKEN_PIPE) fifobr=1, > AC_NOTE(- skipping check because we are cross compiling; assuming fifo implementation is ok)) >-rm -f conftest* >+rm -f /tmp/conftest* > fi > > dnl >@@ -401,7 +435,7 @@ > #include <sys/socket.h> > #include <sys/un.h> > >-char *son = "conftest$$"; >+char *son = "/tmp/conftest$$"; > > main() > { >@@ -440,7 +474,7 @@ > ], AC_NOTE(- your sockets are usable) sock=1, > AC_NOTE(- your sockets are not usable), > AC_NOTE(- skipping check because we are cross compiling; assuming sockets are usable) sock=1) >-rm -f conftest* >+rm -f /tmp/conftest* > > if test -n "$sock"; then > AC_CHECKING(socket implementation) >@@ -457,7 +491,7 @@ > #include <sys/socket.h> > #include <sys/un.h> > >-char *son = "conftest$$"; >+char *son = "/tmp/conftest$$"; > > main() > { >@@ -480,7 +514,7 @@ > AC_NOTE(- unix domain sockets are not kept in the filesystem) > AC_DEFINE(SOCK_NOT_IN_FS) socknofs=1, > AC_NOTE(- skipping check because we are cross compiling; assuming sockets are normal)) >-rm -f conftest* >+rm -f /tmp/conftest* > fi > > >@@ -502,7 +536,7 @@ > #include <sys/stat.h> > #include <fcntl.h> > >-char *nam = "conftest$$"; >+char *nam = "/tmp/conftest$$"; > > #ifdef NAMEDPIPE > >@@ -601,7 +635,7 @@ > tgetent((char *)0, (char *)0); > #endif > ],, >-LIBS="-ltinfo $olibs" >+LIBS="-ltermcap $olibs" > AC_CHECKING(libtermcap) > AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, > LIBS="-ltermlib $olibs" >@@ -622,9 +656,6 @@ > AC_MSG_ERROR(!!! no tgetent - no screen))))))))) > > AC_TRY_RUN([ >- >-extern char *tgoto(char *,int,int); >- > main() > { > exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1); >@@ -638,11 +669,20 @@ > dnl **** PTY specific things **** > dnl > if test "$cross_compiling" = no ; then >+AC_CHECKING(for /dev/ptc) >+if test -r /dev/ptc; then >+AC_DEFINE(HAVE_DEV_PTC) >+fi >+fi >+ >+if test "$cross_compiling" = no ; then > AC_CHECKING(for SVR4 ptys) > sysvr4ptys= >+if test -c /dev/ptmx ; then > AC_TRY_LINK([],[ptsname(0);grantpt(0);unlockpt(0);],[AC_DEFINE(HAVE_SVR4_PTYS) > sysvr4ptys=1]) > fi >+fi > > AC_CHECK_FUNCS(getpt) > >@@ -824,6 +864,11 @@ > dnl > dnl **** loadav **** > dnl >+if test "$cross_compiling" = no ; then >+AC_CHECKING(for libutil(s)) >+test -f /usr/lib/libutils.a && LIBS="$LIBS -lutils" >+test -f /usr/lib/libutil.a && LIBS="$LIBS -lutil" >+fi > > AC_CHECKING(getloadavg) > AC_TRY_LINK(,[getloadavg((double *)0, 0);], >@@ -1053,6 +1098,11 @@ > LIBS="$LIBS -lcrypt" > AC_CHECKING(crypt) > AC_TRY_LINK(,,,LIBS="$oldlibs") >+if test "$cross_compiling" = no ; then >+test -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec" >+test -f /lib/libshadow.a || test -f /usr/lib/libshadow.a && LIBS="$LIBS -lshadow" >+fi >+ > oldlibs="$LIBS" > LIBS="$LIBS -lsun" > AC_CHECKING(IRIX sun library) >@@ -1194,26 +1244,17 @@ > > AC_CHECK_FUNCS(rename fchmod fchown strerror lstat _exit utimes vsnprintf getcwd setlocale strftime) > >-AC_CHECK_LIB(dl, dlopen) >- > AC_ARG_ENABLE(pam, [ --enable-pam enable PAM support]) > if test "$enable_pam" = "yes"; then > AC_MSG_CHECKING(for PAM support) > oldlibs="$LIBS" >- cf_result=no >- >- AC_CHECK_LIB(pam, pam_start, LIBS="$LIBS -lpam";cf_result=yes, cf_result=no) >- >- if test "$cf_result" = yes; then >- AC_CHECK_LIB(pam_userpass, pam_userpass_conv, LIBS="$LIBS -lpam_userpass";cf_result=yes, cf_result=no) >- fi >- >- if test "$cf_result" = yes; then >- AC_DEFINE(USE_PAM) >- else >- LIBS="$oldlibs" >- fi >- AC_MSG_RESULT($cf_result); >+ LIBS="$LIBS -lpam" >+ AC_TRY_LINK([#include <security/pam_appl.h>], [ >+ pam_start(0, 0, 0, 0); >+ pam_authenticate(0, 0); >+ pam_end(0,0); >+ ], AC_MSG_RESULT(yes);AC_DEFINE(USE_PAM), >+ AC_MSG_RESULT(no);LIBS="$oldlibs") > fi > > AC_ARG_ENABLE(use-locale, >diff -ur screen.orig/display.c screen/display.c >--- screen.orig/display.c 2023-06-01 14:58:17.233665014 +0300 >+++ screen/display.c 2022-01-28 17:06:02.674611701 +0300 >@@ -28,7 +28,6 @@ > > #include <sys/types.h> > #include <signal.h> >-#include <setjmp.h> > #include <fcntl.h> > #ifndef sun > # include <sys/ioctl.h> >@@ -327,17 +326,6 @@ > return display; > } > >-static sigjmp_buf alarm_jump; >- >-static sigret_t >-FlushSigAlarm SIGDEFARG >-{ >-#ifdef DEBUG >- debug("FlushSigAlarm\n"); >-#endif >- siglongjmp (alarm_jump, 1); >-} >- > > void > FreeDisplay() >@@ -358,12 +346,7 @@ > Flush(3); > if (!display) > return; >- if (sigsetjmp(alarm_jump,1)==0) { >- signal(SIGALRM, FlushSigAlarm); >- alarm(10); >- SetTTY(D_userfd, &D_OldMode); >- alarm(0); >- } >+ SetTTY(D_userfd, &D_OldMode); > fcntl(D_userfd, F_SETFL, 0); > } > freetty(); >@@ -2332,7 +2315,7 @@ > { > char *buf; > #ifdef UTF8 >- int extrabytes = strlen(hstatusstring) - strlen_onscreen(hstatusstring, NULL); >+ int extrabytes = strlen(hstatusstring) - strlen_onscreen((unsigned char *)hstatusstring, NULL); > #else > int extrabytes = 0; > #endif >@@ -2435,7 +2418,7 @@ > if (y == cv->c_ye + 1 && from >= cv->c_xs && from <= cv->c_xe) > { > #ifdef UTF8 >- int extrabytes = strlen(captionstring) - strlen_onscreen(captionstring, NULL); >+ int extrabytes = strlen(captionstring) - strlen_onscreen((unsigned char *)captionstring, NULL); > #else > int extrabytes = 0; > #endif >@@ -3040,7 +3023,6 @@ > AddChar(' '); > } > >- > void > Flush(progress) > int progress; >@@ -3092,15 +3074,7 @@ > break; > } > } >- if (sigsetjmp (alarm_jump,1) == 0) { >- signal(SIGALRM, FlushSigAlarm); >- alarm(10); >- wr = write(D_userfd, p, l); >- alarm(0); >- } else { >- debug1("Warning: We spent too long in flush: %d\n", errno); >- return; >- } >+ wr = write(D_userfd, p, l); > if (wr <= 0) > { > if (errno == EINTR) >@@ -3208,8 +3182,7 @@ > { > debug("display activity stopped sleep\n"); > if (eat) >- if (read(D_userfd, &buf, 1) < 1) >- ; >+ read(D_userfd, &buf, 1); > } > debug2("DisplaySleep(%d) ending, eat was %d\n", n, eat); > } >@@ -3432,7 +3405,7 @@ > */ > int size; > char bufspace[MAX_MOUSE_SEQUENCE + IOSIZE]; >- unsigned char *buf = bufspace + MAX_MOUSE_SEQUENCE; >+ unsigned char *buf = (unsigned char*)bufspace + MAX_MOUSE_SEQUENCE; > > struct canvas *cv; > >@@ -3507,7 +3480,7 @@ > if (p->w_zdisplay == display) > { > flayer = &p->w_layer; >- bufp = buf; >+ bufp = (char *)buf; > while (size > 0) > LayProcess(&bufp, &size); > return; >@@ -3790,7 +3763,7 @@ > return; > } > #endif >- (*D_processinput)(buf, size); >+ (*D_processinput)((char *)buf, size); > } > > static void >@@ -4015,7 +3988,6 @@ > } > } > #endif >- fflush(NULL); > switch (pid = (int)fork()) > { > case -1: >@@ -4063,19 +4035,13 @@ > } > debug1("=== RunBlanker: pid %d\n", (int)getpid()); > #endif >- { >- int fd = open(m, O_RDWR); >- if (fd < 0) >- Panic(errno, "Cannot open %s", m); >- if (dup2(fd, 0) < 0) >- Panic(errno, "Cannot redirect %s to %s", "stdin", m); >- if (dup2(fd, 1) < 0) >- Panic(errno, "Cannot redirect %s to %s", "stdout", m); >- if (dup2(fd, 2) < 0) >- Panic(errno, "Cannot redirect %s to %s", "stderr", m); >- if (fd > 2) >- close(fd); >- } >+ close(0); >+ close(1); >+ close(2); >+ if (open(m, O_RDWR)) >+ Panic(errno, "Cannot open %s", m); >+ dup(0); >+ dup(0); > close(D_blankerev.fd); > if (slave != -1) > close(slave); >diff -ur screen.orig/display.h screen/display.h >--- screen.orig/display.h 2023-06-01 14:58:17.233665014 +0300 >+++ screen/display.h 2022-01-28 17:06:02.674611701 +0300 >@@ -61,7 +61,7 @@ > struct mouse_parse > { > char sgrmode; /* non-zero if parsing an SGR sequence */ >- char state; /* current state of parsing */ >+ int state; /* current state of parsing */ > int params[3]; /* parsed params: button, x, y */ > }; > >@@ -112,7 +112,7 @@ > int d_mousetrack; /* set when user wants to use mouse even when the window > does not */ > #ifdef RXVT_OSC >- int d_xtermosc[4]; /* osc used */ >+ int d_xtermosc[5]; /* osc used */ > #endif > struct mchar d_lpchar; /* missing char */ > struct timeval d_status_time; /* time of status display */ >diff -ur screen.orig/doc/FAQ screen/doc/FAQ >--- screen.orig/doc/FAQ 2023-06-01 14:58:17.233665014 +0300 >+++ screen/doc/FAQ 2022-01-28 17:06:02.674611701 +0300 >@@ -191,7 +191,7 @@ > Q: The "talk" command does not work when Screen is active. > > A: Talk and several other programs rely on entries in the Utmp- >- Database (/var/run/utmp). On some systems this Database is world >+ Database (/etc/utmp). On some systems this Database is world > writable, on others it is not. If it is not, screen must be > installed with the appropriate permissions (user or group s-bit) > just like any program that uses PTYs (rlogin, xterm, ...). When >diff -ur screen.orig/doc/screen.1 screen/doc/screen.1 >--- screen.orig/doc/screen.1 2023-06-01 14:58:17.236665021 +0300 >+++ screen/doc/screen.1 2022-01-28 17:06:02.678611800 +0300 >@@ -1,10 +1,7 @@ > .\" vi:set wm=5 >-.TH SCREEN 1 "Feb 2020" >-.if n .ds Q \&" >-.if n .ds U \&" >-.if t .ds Q `` >-.if t .ds U '' >-.UC 4 >+.TH SCREEN 1 "2022 Jan 30" "GNU Screen 4.9.0" >+. >+. > .SH NAME > screen \- screen manager with VT100/ANSI terminal emulation > >@@ -80,14 +77,14 @@ > .I Screen > will also print out control characters in caret notation. > .PP >-The standard way to create a new window is to type \*QC-a c\*U. >+The standard way to create a new window is to type \fBC-a c\fP. > This creates a new window running a shell and switches to that > window immediately, regardless of the state of the process running > in the current window. > Similarly, you can create a new window with a custom command in it by > first binding the command to a keystroke (in your .screenrc file or at the >-\*QC-a :\*U command line) and >-then using it just like the \*QC-a c\*U command. >+\fBC-a :\fP command line) and >+then using it just like the \fBC-a c\fP command. > In addition, new windows can be created by running a command like: > .IP > screen emacs prog.c >@@ -103,7 +100,7 @@ > the invoking shell to the application (emacs in this case), because it is > forked from the parent screen process, not from the invoking shell. > .PP >-If \*Q/var/run/utmp\*U is writable by >+If \*Q/etc/utmp\*U is writable by > .IR screen , > an appropriate record will be written to this file for each window, and > removed when the window is terminated. >@@ -121,11 +118,11 @@ > you'll need to make sure you have correctly selected your terminal type, > just as you would for any other termcap/terminfo program. > (You can do this by using >-.IR tset >+.IR test > for example.) > .PP > If you're impatient and want to get started without doing a lot more reading, >-you should remember this one command: \*QC-a ?\*U. >+you should remember this one command: \fBC-a ?\fP. > Typing these two characters will display a list of the available > .I screen > commands and their bindings. Each keystroke is discussed in >@@ -232,7 +229,7 @@ > The use of this option is discouraged. > .TP 5 > .BR \-l " and " \-ln >-turns login mode on or off (for /var/run/utmp updating). >+turns login mode on or off (for /etc/utmp updating). > This can also be defined through the \*Qdeflogin\*U .screenrc command. > .TP 5 > .BR \-ls " [" \fImatch ] >@@ -257,12 +254,6 @@ > Sessions marked as `dead' should be thoroughly checked and removed. > Ask your system administrator if you are not sure. Remove sessions with the > \fB-wipe\fP option. >-.IP "" 5 >-Note: >- If sockets are missing (and because of this, your sessions are not >-listed), you may send a SIGCHLD to its `SCREEN' >-process and the process will re-establish the socket (think of >-someone cleaning /tmp thoroughly). > .TP 5 > .B \-L > tells >@@ -378,7 +369,8 @@ > When creating a new session, this option can be used to specify a > meaningful name for the session. This name identifies the session for > \*Qscreen \-list\*U and \*Qscreen \-r\*U actions. It substitutes the >-default [\fItty.host\fP] suffix. >+default [\fItty.host\fP] suffix. This name should not be longer >+then 80 symbols. > .TP 5 > .BI "\-t " name > sets the title (a.\|k.\|a.) for the default shell or specified program. >@@ -788,7 +780,7 @@ > When > .I screen > is invoked, it executes initialization commands from the files >-\*Q/etc/screenrc\*U and >+\*Q/usr/local/etc/screenrc\*U and > \*Q.screenrc\*U in the user's home directory. These are the \*Qprogrammer's > defaults\*U that can be overridden in the following ways: for the > global screenrc file >@@ -930,14 +922,16 @@ > and each occurrence of `^G' is replaced by the definition for bell > in your termcap (usually an audible bell). > The default message is >-.sp >+.PP >+.nf > 'Activity in window %n' >-.sp >+.fi >+.PP > Note that monitoring is off for all windows by default, but can be altered > by use of the \*Qmonitor\*U command (C-a M). > .RE > .TP >-.BR "allpartial on" | off >+.BR "allpartial [ on | off ]" > .RS 0 > .PP > If set to on, only the current cursor line is refreshed on window change. >@@ -948,7 +942,7 @@ > default redraw behavior of newly created windows. > .RE > .TP >-.BR "altscreen on" | off >+.BR "altscreen [ on | off ]" > .RS 0 > .PP > If set to on, "alternate screen" support is enabled in virtual terminals, >@@ -1021,7 +1015,7 @@ > Make bright colored text also bold. > .RE > .TP >-.BR "autodetach on" | off >+.BR "autodetach [ on | off ]" > .RS 0 > .PP > Sets whether >@@ -1035,7 +1029,7 @@ > and all the processes it contains. Autodetach is on by default. > .RE > .TP >-.BR "autonuke on" | off >+.BR "autonuke [ on | off ]" > .RS 0 > .PP > Sets whether a clear screen sequence should nuke all the output >@@ -1069,7 +1063,7 @@ > with the numerical id \fIid\fP. > .RE > .TP >-.BR "bce " [ on | off ] >+.BR "bce [ on | off ]" > .RS 0 > .PP > Change background-color-erase setting. If \*Qbce\*U is set to on, all >@@ -1090,11 +1084,11 @@ > and each occurrence of `^G' is replaced by the definition for bell > in your termcap (usually an audible bell). > The default message is >-.sp >-.RS >+.PP >+.nf > 'Bell in window %n' >-.RE >-.sp >+.fi >+.PP > An empty message can be supplied to the \*Qbell_msg\*U command to suppress > output of a message line (bell_msg ""). > Without parameter, the current message is shown. >@@ -1248,7 +1242,7 @@ > escape (besides ^A). > .RE > .TP >-.BR break [ \fIduration\fR ] >+.BR "break " [ \fIduration\fR ] > .RS 0 > .PP > Send a break signal for \fIduration\fP*0.25 seconds to this window. >@@ -1318,10 +1312,10 @@ > Swaps window with next one on window list. > .RE > .TP >-.BR "c1 " [ on | off ] >+.BR "c1 [ on | off ]" > .RS 0 > .PP >-Change c1 code processing. \*QC1 on\*U tells screen to treat >+Change c1 code processing. \fBC1 on\fP tells screen to treat > the input characters between 128 and 159 as control functions. > Such an 8-bit code is normally the same as ESC followed by the > corresponding 7-bit code. The default setting is to process c1 >@@ -1426,7 +1420,7 @@ > you may regard \*QC-a esc\*U (copy mode) as its `Vi command mode'. > .RE > .TP >-.BR "command " [ \-c " \fIclass\fP" ] >+.BR "command [ \-c " \fIclass\fP" ]" > .RS 0 > .PP > This command has the same effect as typing the screen escape >@@ -1435,14 +1429,14 @@ > class. See also \*Qbind\*U and \*Qbindkey\*U. > .RE > .TP >-.BR "compacthist " [ on | off ] >+.BR "compacthist [ on | off ]" > .RS 0 > .PP > This tells screen whether to suppress trailing blank lines when > scrolling up text into the history buffer. > .RE > .TP >-.BR "console " [ on | off ] >+.BR "console [ on | off ]" > .RS 0 > .PP > Grabs or un-grabs the machines console output to a window. >@@ -1517,7 +1511,7 @@ > \fBB\fP, \fBE\fP@move the cursor WORD by WORD (as in vi). > _ > \fBf/F\fP, \fBt/T\fP@T{ >-move the cursor forward/backward to the next occurence of the >+move the cursor forward/backward to the next occurrence of the > target. (eg, '3fy' will move the cursor to the 3rd 'y' to the right.) > T} > _ >@@ -1539,7 +1533,7 @@ > _ > .TE > .\"\fBf\fP,\fBt\fP, \fBF\fP, \fBT\fP@T{ >-.\"move the cursor forward/backward to the next occurence of the target. >+.\"move the cursor forward/backward to the next occurrence of the target. > .\"T} > > .PP >@@ -1571,7 +1565,7 @@ > Example: \*QC-a C-[ H 10 j 5 Y\*U will copy lines > 11 to 15 into the paste buffer. > .PP >-The folllowing search keys are defined: >+The following search keys are defined: > .IP > \fB/\fP \fIVi\fP-like search forward. > .IP >@@ -1652,7 +1646,7 @@ > No longer exists, use \*Qreadreg\*U instead. > .RE > .TP >-.BR "crlf " [ on | off ] >+.BR "crlf [ on | off ]" > .RS 0 > .PP > This affects the copying of text regions with the `C-a [' command. If it is set >@@ -1661,7 +1655,7 @@ > When no parameter is given, the state is toggled. > .RE > .TP >-.BR "debug on" | off >+.BR "debug [ on | off ]" > .RS 0 > .PP > Turns runtime debugging on or off. If >@@ -1672,14 +1666,14 @@ > be turned off once and forever. > .RE > .TP >-.BR "defc1 on" | off >+.BR "defc1 [ on | off ]" > .RS 0 > .PP > Same as the \fBc1\fP command except that the default setting for new > windows is changed. Initial setting is `on'. > .RE > .TP >-.BR "defautonuke on" | off >+.BR "defautonuke [ on | off ]" > .RS 0 > .PP > Same as the \fBautonuke\fP command except that the default setting for new displays is changed. Initial setting is `off'. >@@ -1687,7 +1681,7 @@ > want to have a dependency on the terminal type. > .RE > .TP >-.BR "defbce on" | off >+.BR "defbce [ on | off ]" > .RS 0 > .PP > Same as the \fBbce\fP command except that the default setting for new >@@ -1721,7 +1715,7 @@ > argument. > .RE > .TP >-.BR "defdynamictitle on" | off >+.BR "defdynamictitle [ on | off ]" > .RS 0 > .PP > Set default behaviour for new windows regarding if screen should change window >@@ -1739,18 +1733,18 @@ > characters for users that will be added later. > .RE > .TP >-.BR "defflow " on | off | "auto " [ interrupt ] >+.BR "defflow [ on | off | auto [ interrupt ]] > .RS 0 > .PP > Same as the \fBflow\fP command except that the default setting for new windows > is changed. Initial setting is `auto'. >-Specifying \*Qdefflow auto interrupt\*U is the same as the command-line options >+Specifying \fBdefflow auto interrupt\fP is the same as the command-line options > .B \-fa > and > .BR \-i . > .RE > .TP >-.BR "defgr on" | off >+.BR "defgr [ on | off ]" > .RS 0 > .PP > Same as the \fBgr\fP command except that the default setting for new >@@ -1783,14 +1777,14 @@ > terminal. > .RE > .TP >-.BR "deflog on" | off >+.BR "deflog [ on | off ]" > .RS 0 > .PP > Same as the \fBlog\fP command except that the default setting for new windows > is changed. Initial setting is `off'. > .RE > .TP >-.BR "deflogin on" | off >+.BR "deflogin [ on | off ]" > .RS 0 > .PP > Same as the \fBlogin\fP command except that the default setting for new windows >@@ -1805,21 +1799,21 @@ > When no \*Qdefmode\*U command is given, mode 0622 is used. > .RE > .TP >-.BR "defmonitor on" | off >+.BR "defmonitor [ on | off]" > .RS 0 > .PP > Same as the \fBmonitor\fP command except that the default setting for new > windows is changed. Initial setting is `off'. > .RE > .TP >-.BR "defmousetrack on" | off >+.BR "defmousetrack [ on | off ]" > .RS 0 > .PP > Same as the \fBmousetrack\fP command except that the default setting for new > windows is changed. Initial setting is `off'. > .RE > .TP >-.BR "defnonblock on" | off | \fInumsecs\fP >+.BR "defnonblock [ on | off | \fInumsecs\fP] > .RS 0 > .PP > Same as the \fBnonblock\fP command except that the default setting for >@@ -1847,7 +1841,7 @@ > Synonym to the \fBshell\fP .screenrc command. See there. > .RE > .TP >-.BR "defsilence on" | off >+.BR "defsilence [ on | off ]" > .RS 0 > .PP > Same as the \fBsilence\fP command except that the default setting for new >@@ -1861,7 +1855,7 @@ > windows is changed. Initial setting is 0 milliseconds, meaning `off'. > .RE > .TP >-.BR "defutf8 on" | off >+.BR "defutf8 [ on | off ]" > .RS 0 > .PP > Same as the \fButf8\fP command except that the default setting for new >@@ -1869,7 +1863,7 @@ > \*Q\-U\*U, otherwise `off'. > .RE > .TP >-.BR "defwrap on" | off >+.BR "defwrap [ on | off ]" > .RS 0 > .PP > Same as the \fBwrap\fP command except that the default setting for new >@@ -1877,7 +1871,7 @@ > \*Qwrap\*U command (\*QC-a r\*U) or by means of "C-a : wrap on|off". > .RE > .TP >-.BR "defwritelock on" | off | auto >+.BR "defwritelock [ on | off | auto ]" > .RS 0 > .PP > Same as the \fBwritelock\fP command except that the default setting for new >@@ -2043,7 +2037,7 @@ > .IR tic . > .RE > .TP >-.BR "dynamictitle on" | off >+.BR "dynamictitle [ on | off ]" > .RS 0 > .PP > Change behaviour for windows regarding if screen should change window title >@@ -2056,7 +2050,7 @@ > The echo command may be used to annoy > .I screen > users with a 'message of the >-day'. Typically installed in a global /etc/screenrc. >+day'. Typically installed in a global /local/etc/screenrc. > The option \*Q\-n\*U may be used to suppress the line feed. > See also \*Qsleep\*U. > Echo is also useful for online checking of environment variables. >@@ -2201,8 +2195,7 @@ > automatically if the window is displayed more than once. > .RE > .TP >-.B flow >-.RB [ on | off | "auto\fR]\fP" >+.BR "flow [ on | off | auto]" > .RS 0 > .PP > Sets the flow-control mode for this window. >@@ -2213,7 +2206,7 @@ > Default is set by `defflow'. > .RE > .TP >-.BR "focus " [ next|prev|up|down|left|right|top|bottom ] >+.BR "focus [ next | prev | up | down | left | right | top | bottom ]" > .RS 0 > .PP > Move the input focus to the next region. This is done in a cyclic >@@ -2264,7 +2257,7 @@ > This forces any currently selected region to be automatically > resized at least a certain \fIwidth\fP and \fIheight\fP. All > other surrounding regions will be resized in order to accommodate. >-This constraint follows everytime the \*Qfocus\*U command is >+This constraint follows every time the \*Qfocus\*U command is > used. The \*Qresize\*U command can be used to increase either > dimension of a region, but never below what is set with > \*Qfocusminsize\*U. The underscore `_' is a synonym for >@@ -2273,7 +2266,7 @@ > Without any parameters, the minimum width and height is shown. > .RE > .TP >-.BR "gr " [ on | off ] >+.BR "gr [ on | off ]" > .RS 0 > .PP > Turn GR charset switching on/off. Whenever screen sees an input >@@ -2303,7 +2296,7 @@ > scrollback buffer. > .RE > .TP >-.BR "hardcopy_append on" | off >+.BR "hardcopy_append [ on | off ]" > .RS 0 > .PP > If set to "on", >@@ -2322,11 +2315,11 @@ > current working directory. > .RE > .TP >-.BR "hardstatus " [ on | off ] >+.BR "hardstatus [ on | off ]" > .TP >-.BR "hardstatus \fR[\fBalways\fR]\fBfirstline" | lastline | message | ignore [ \fIstring\fR ] >+.BR "hardstatus [ always ] firstline | lastline | message | ignore [ string ]" > .TP >-.BR "hardstatus string" [ \fIstring\fR ] >+.BR "hardstatus string [ string ]" > .RS 0 > .PP > This command configures the use and emulation of the terminal's >@@ -2386,8 +2379,7 @@ > .BR help [ \fIclass\fP ] > .RS 0 > .PP >-Not really a online help, but >-displays a help >+Not really a online help, but displays a help > .I screen > showing you all the key bindings. > The first pages list all the internal commands followed by their current >@@ -2432,7 +2424,7 @@ > If no arguments are given, the current settings are displayed. > .RE > .TP >-.BR "ignorecase " [ on | off ] >+.BR "ignorecase [ on | off ]" > .RS 0 > .PP > Tell screen to ignore the case of characters in searches. Default is >@@ -2492,8 +2484,7 @@ > (shell) running in the window receives a HANGUP condition, > the window structure is removed and > .I screen >-(your display) switches to another >-window. When the last window is destroyed, >+(your display) switches to another window. When the last window is destroyed, > .I screen > exits. > After a kill >@@ -2613,7 +2604,7 @@ > \fBlayout autosave\fP command. > .RE > .TP >-.BR "layout autosave " [\fBon|off\fP] >+.BR "layout autosave [ on | off]" > .RS 0 > .PP > Change or display the status of automatcally saving layouts. The >@@ -2652,7 +2643,7 @@ > Display the disclaimer page. This is done whenever > .I screen > is started without options, which should be often enough. See also >-the \*Qstartup_message\*U command. >+the \fBstartup_message\fP command. > .RE > .TP > .B lockscreen >@@ -2674,7 +2665,7 @@ > shell. This feature should rather be called `lockterminal'. > .RE > .TP >-.BR "log " [ on | off ] >+.BR "log [ on | off ]" > .RS 0 > .PP > Start/stop writing output of the current window to a file >@@ -2699,7 +2690,7 @@ > default value is 10 seconds. > .RE > .TP >-.BR "login " [ on | off ] >+.BR "login [ on | off ]" > .RS 0 > .PP > Adds or removes the entry in the utmp database file for the current window. >@@ -2798,7 +2789,7 @@ > Insert the command character (C-a) in the current window's input stream. > .RE > .TP >-.BR "monitor " [ on | off ] >+.BR "monitor [ on | off ]" > .RS 0 > .PP > Toggles activity monitoring of windows. >@@ -2809,7 +2800,7 @@ > Monitoring is initially off for all windows. > .RE > .TP >-.BR "mousetrack " [ on | off ] >+.BR "mousetrack [ on | off ]" > .RS 0 > .PP > This command determines whether >@@ -2819,7 +2810,7 @@ > been split in various ways can be selected by pointing to them > with a mouse and left-clicking them. Without specifying \fBon\fP > or \fBoff\fP, the current state is displayed. The default state >-is determined by the \*Qdefmousetrack\*U command. >+is determined by the \fBdefmousetrack\fP command. > .RE > .TP > .BI "msgminwait " sec >@@ -2839,7 +2830,7 @@ > is not disturbed by other activity. The default is 5 seconds. > .RE > .TP >-.BR "multiuser on" | off >+.BR "multiuser [ on | off ]" > .RS 0 > .PP > Switch between singleuser and multiuser mode. Standard >@@ -2851,7 +2842,7 @@ > session. > .RE > .TP >-.BR "nethack on" | off >+.BR "nethack [ on | off ]" > .RS 0 > .PP > Changes the kind of error messages used by >@@ -2861,8 +2852,7 @@ > much funnier to read. Anyway, standard messages often tend to be unclear as > well. > .br >-This option is only >-available if >+This option is only available if > .I screen > was compiled with the NETHACK flag defined. The > default setting is then determined by the presence of the environment >@@ -2877,8 +2867,7 @@ > This command can be used repeatedly to cycle through the list of windows. > .RE > .PP >-.B nonblock >-.RB [ on | off | \fInumsecs ] >+.BR "nonblock [ on | off | numsecs ]" > .RS 0 > .PP > Tell screen how to deal with user interfaces (displays) that cease to >@@ -2925,7 +2914,7 @@ > \fIother\fP has the same effect as \fInext\fP. > .RE > .TP >-.BR "partial on" | off >+.BR "partial [ on | off ]" > .RS 0 > .PP > Defines whether the display should be refreshed (as with \fIredisplay\fP) after >@@ -2940,9 +2929,8 @@ > .PP > Present a crypted password in your \*Q.screenrc\*U file and > .I screen >-will ask >-for it, whenever someone attempts to resume a detached. This is useful >-if you have privileged programs running under >+will ask for it, whenever someone attempts to resume a detached. >+This is useful if you have privileged programs running under > .I screen > and you want to protect your session from reattach attempts by another user > masquerading as your uid (i.e. any superuser.) >@@ -2960,22 +2948,22 @@ > of the current window. The register '.' is treated as the > paste buffer. If no parameter is given the user is prompted for a single > register to paste. >-The paste buffer can be filled with the \fIcopy\fP, \fIhistory\fP and >-\fIreadbuf\fP commands. >-Other registers can be filled with the \fIregister\fP, \fIreadreg\fP and >-\fIpaste\fP commands. >-If \fIpaste\fP is called with a second argument, the contents of the specified >-registers is pasted into the named destination register rather than >+The paste buffer can be filled with the \fBcopy\fP, \fBhistory\fP and >+\fBreadbuf\fP commands. >+Other registers can be filled with the \fBregister\fP, \fBreadreg\fP and >+\fBpaste\fP commands. >+If \fBpaste\fP is called with a second argument, the contents of the specified >+registers is pasted into the named destination register rather than > the window. If '.' is used as the second argument, the displays paste buffer is > the destination. >-Note, that \*Qpaste\*U uses a wide variety of resources: Whenever a second >+Note, that \fBpaste\fP uses a wide variety of resources: Whenever a second > argument is specified no current window is needed. When the source specification >-only contains registers (not the paste buffer) then there need not be a current >-display (terminal attached), as the registers are a global resource. The >+only contains registers (not the paste buffer) then there need not be a current >+display (terminal attached), as the registers are a global resource. The > paste buffer exists once for every user. > .RE > .TP >-.BR "pastefont " [ on | off ] >+.BR "pastefont [ on | off ]" > .RS 0 > .PP > Tell >@@ -3070,7 +3058,7 @@ > Reads the contents of the specified file into the paste buffer. > You can tell screen the encoding of the file via the \fB\-e\fP option. > If no file is specified, the screen-exchange filename is used. >-See also \*Qbufferfile\*U command. >+See also \fBbufferfile\fP command. > .RE > .TP > .IR "\fBreadreg\fP " [ encoding "] [" register " [" filename ]] >@@ -3117,17 +3105,21 @@ > .B "removebuf" > .RS 0 > .PP >-Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and >-\*Qreadbuf\*U. >+Unlinks the screen-exchange file used by the commands >+\fBwritebuf\fP and \fBreadbuf\fP. > .RE > .TP >-.B "rendition bell" | monitor | silence | so " \fIattr\fR " \fR[\fP \fIcolor\fP \fR]\fP >+.B "rendition [ bell | monitor | silence | so ] attr [ color ]" > .RS 0 > .PP > Change the way > .I screen >-renders the titles of windows that have monitor or bell flags set in caption or hardstatus or windowlist. See the \*QSTRING ESCAPES\*U chapter for the syntax of the modifiers. >-The default for monitor is currently \*Q=b \*U (bold, active colors), for bell \*Q=ub \*U (underline, bold and active colors), and \*Q=u \*U for silence. >+renders the titles of windows that have monitor or bell flags set in >+caption or hardstatus or windowlist. See the \*QSTRING ESCAPES\*U >+chapter for the syntax of the modifiers. >+The default for monitor is currently \*Q=b \*U (bold, active colors), >+for bell \*Q=ub \*U (underline, bold and active colors), and \*Q=u \*U >+for silence. > .RE > .TP > .B "reset" >@@ -3197,7 +3189,7 @@ > .I screen > will prompt for how you would like to resize the current region. > >-See \*Qfocusminsize\*U if you want to restrict the minimun size a region >+See \*Qfocusminsize\*U if you want to restrict the minimum size a region > can have. > .RE > .RE >@@ -3294,7 +3286,7 @@ > and value. The environment is inherited by all subsequently forked shells. > .RE > .TP >-.BR "setsid " [ on | off ] >+.BR "setsid [ on | off ]" > .RS 0 > .PP > Normally screen uses different sessions and process groups for >@@ -3326,7 +3318,7 @@ > entitled \*QTITLES (naming windows)\*U. > .RE > .TP >-.BR "silence " [ on | off "|\fIsec\fP]" >+.BR "silence [ on | off | sec ]" > .RS 0 > .PP > Toggles silence monitoring of windows. >@@ -3414,18 +3406,17 @@ > With this current implementation of screen, scrolling data > will appear much slower in a vertically split region than one > that is not. This should be taken into consideration if you need >-to use system commands such as \*Qcat\*U or \*Qtail -f\*U. >+to use system commands such as \fBcat\fP or \fBtail -f\fP. > .RE > .TP >-.B "startup_message on\fP|\fBoff" >+.B "startup_message [ on | off ]" > .RS 0 > .PP > Select whether you want to see the copyright notice during startup. > Default is `on', as you probably noticed. > .RE > .PP >-.BR "status " [ top | up | down | bottom ] >-.RB [ left | right ] >+.BR "status [ top | up | down | bottom ] [ left | right ]" > .RS 0 > .PP > The status window by default is in bottom-left corner. This command can move >@@ -3630,7 +3621,7 @@ > Unset an environment variable. > .RE > .TP >-.BR "utf8 " [ on | off [ on | off ]] >+.BR "utf8 [ on | off [ on | off ]]" > .RS 0 > .PP > Change the encoding used in the current window. If utf8 is enabled, the >@@ -3642,7 +3633,7 @@ > window. > .RE > .TP >-.BR "vbell " [ on | off ] >+.BR "vbell [ on | off ]" > .RS 0 > .PP > Sets the visual bell setting for this window. Omitting the parameter >@@ -3674,7 +3665,7 @@ > visual bell message. The default is 1 second. > .RE > .TP >-.BR "verbose " [ on | off ] >+.BR "verbose [ on | off ]" > .RS 0 > .PP > If verbose is switched on, the command name is echoed, whenever a window >@@ -3711,7 +3702,7 @@ > vice versa. > .RE > .TP >-.BR "windowlist " [ \-b "] [" \-m "] [" \-g ] >+.BR "windowlist [ \-b ] [ \-m ] [ \-g ]" > .TP > .IR "\fBwindowlist string\fR " [ string ] > .TP >@@ -3819,7 +3810,7 @@ > The default command without any parameter is limited to a size of 1024 bytes. > .RE > .TP >-.BR "wrap " [ on | off ] >+.BR "wrap [ on | off ]" > .RS 0 > .PP > Sets the line-wrap setting for the current window. >@@ -3842,7 +3833,7 @@ > command and defaults to \*Q/tmp/screen\-exchange\*U. > .RE > .TP >-.BR "writelock " [ on | "off\fR|\fBauto\fR]" >+.BR "writelock [ on | off | auto]" > .RS 0 > .PP > In addition to access control lists, not all users may be able to write to >@@ -3864,7 +3855,7 @@ > current window. > .RE > .TP >-.BR "zmodem " [ off\fR|\fPauto\fR|\fPcatch\fR|\fPpass ] >+.BR "zmodem [ off | auto | catch | pass ]" > .TP > .IR "\fBzmodem sendcmd\fR " [ string ] > .TP >@@ -4068,6 +4059,8 @@ > the escape character itself > .IP E > sets %? to true if the escape character has been pressed. >+.IP e >+encoding > .IP f > flags of the window, see \*Qwindows\*U for meanings of the various flags > .IP F >@@ -4163,7 +4156,7 @@ > .IP r > reverse > .IP s >-standout >+/standout > .IP B > blinking > .PD >@@ -4347,9 +4340,11 @@ > history recall commands. > .PP > Here's some .screenrc examples: >-.IP >-screen \-t top 2 nice top >-.PP >+.sp >+.nf >+ screen \-t top 2 nice top >+.fi >+.sp > Adding this line to your .screenrc would start a nice-d version of the > \*Qtop\*U command in window 2 named \*Qtop\*U rather than \*Qnice\*U. > .sp >@@ -4361,15 +4356,19 @@ > These commands would start a shell with the given shelltitle. > The title specified is an auto-title that would expect the prompt and > the typed command to look something like the following: >-.IP >-/usr/joe/src/dir> trn >-.PP >+.sp >+.nf >+ /usr/joe/src/dir> trn >+.fi >+.sp > (it looks after the '> ' for the command name). > The window status would show the name \*Qtrn\*U while the command was > running, and revert to \*Qcsh\*U upon completion. >-.IP >-bind R screen \-t '% |root:' su >-.PP >+.sp >+.nf >+ bind R screen \-t '% |root:' su >+.fi >+.sp > Having this command in your .screenrc would bind the key > sequence \*QC-a R\*U to the \*Qsu\*U command and give it an > auto-title name of \*Qroot:\*U. >@@ -4404,17 +4403,21 @@ > If these invisible characters aren't a multiple of 8 then backspacing over > a tab will result in an incorrect display. > One way to get around this is to use a prompt like this: >-.IP >-set prompt='^[[0000m^[k^[\e% ' >-.PP >+.sp >+.nf >+ set prompt='^[[0000m^[k^[\e% ' >+.fi >+.sp > The escape-sequence \*Q<esc>[0000m\*U not only normalizes the character > attributes, but all the zeros round the length of the invisible characters > up to 8. > Bash users will probably want to echo the escape sequence in the > PROMPT_COMMAND: >-.IP >-PROMPT_COMMAND='printf "\e033k\e033\e134"' >-.PP >+.sp >+.nf >+ PROMPT_COMMAND='printf "\e033k\e033\e134"' >+.fi >+.sp > (I used \*Q\e134\*U to output a `\e' because of a bug in bash v1.04). > > >@@ -5202,12 +5205,12 @@ > .I screen > distribution package for private and global initialization files. > .IP $SYSSCREENRC >-.IP /etc/screenrc >+.IP /usr/local/etc/screenrc > .I screen > initialization commands > .IP $SCREENRC > .IP $HOME/.screenrc >-Read in after /etc/screenrc >+Read in after /usr/local/etc/screenrc > .IP $SCREENDIR/S\-<login> > .IP /local/screens/S\-<login> > Socket directories (default) >@@ -5228,16 +5231,11 @@ > or > .IP /etc/termcap > Terminal capability databases >-.IP /var/run/utmp >+.IP /etc/utmp > Login records > .IP $LOCKPRG > Program that locks a terminal. > >- >-.SH "SEE ALSO" >-termcap(5), utmp(5), vi(1), captoinfo(1), tic(1) >- >- > .SH AUTHORS > Originally created by Oliver Laumann. For a long time maintained > and developed by Juergen Weigert, Michael Schroeder, Micah Cowan >@@ -5247,7 +5245,7 @@ > > .SH COPYLEFT > .nf >-Copyright (c) 2018-2020 >+Copyright (c) 2018-2022 > Alexander Naumov <alexander_naumov@opensuse.org> > Amadeusz Slawinski <amade@asmblr.net> > Copyright (c) 2015-2017 >@@ -5267,6 +5265,7 @@ > Michael Schroeder <mlschroe@immd4.informatik.uni\-erlangen.de> > Copyright (C) 1987 Oliver Laumann > .fi >+ > .PP > This program is free software; you can redistribute it and/or modify > it under the terms of the GNU General Public License as published by >@@ -5324,10 +5323,12 @@ > .I screen > available via anonymous ftp from ftp.gnu.org/gnu/screen/ or any other > .I GNU >-distribution site. The home site of >+distribution site. The home page of > .I screen >-is savannah.gnu.org/projects/screen/. If you want to help, send a note to >-screen-devel@gnu.org. >+is https://savannah.gnu.org/projects/screen/ and the git repo >+is https://git.savannah.gnu.org/cgit/screen.git. >+If you want to help, send a note to >+.BR screen-devel@gnu.org. > > .SH BUGS > .PD >@@ -5355,9 +5356,9 @@ > must be installed as set-uid with owner root on most systems in order > to be able to correctly change the owner of the tty device file for > each window. >-Special permission may also be required to write the file \*Q/var/run/utmp\*U. >+Special permission may also be required to write the file \*Q/etc/utmp\*U. > .IP \(bu >-Entries in \*Q/var/run/utmp\*U are not removed when >+Entries in \*Q/etc/utmp\*U are not removed when > .I screen > is killed with SIGKILL. > This will cause some programs (like "w" or "rwho") >@@ -5387,7 +5388,15 @@ > file from which the session is booted, or have to be changed manually. > .IP \(bu > A weird imagination is most useful to gain full advantage of all the features. >-.IP \(bu >+.PP > Send bug-reports, fixes, enhancements, t-shirts, money, beer & pizza to > .BR screen-devel@gnu.org . > >+.SH "SEE ALSO" >+.BR termcap(5), >+.BR utmp(5), >+.BR vi(1), >+.BR captoinfo(1), >+.BR tic(1), >+.BR tty(4), >+.BR pty(7) >diff -ur screen.orig/doc/screen.texinfo screen/doc/screen.texinfo >--- screen.orig/doc/screen.texinfo 2023-06-01 14:58:17.238665025 +0300 >+++ screen/doc/screen.texinfo 2022-01-28 17:06:02.682611899 +0300 >@@ -4,14 +4,14 @@ > @documentencoding ISO-8859-15 > @setfilename screen.info > @settitle Screen User's Manual >-@dircategory Terminals >+@dircategory General Commands > @finalout > @setchapternewpage odd > @c %**end of header >-@set version 4.8.0 >+@set version 4.9.0 > > @direntry >-* Screen: (screen). The virtual terminal manager. >+* Screen: (screen). Full-screen window manager. > @end direntry > > @c For examples, use a literal escape in info. >@@ -25,7 +25,7 @@ > @ifinfo > This file documents the @code{Screen} virtual terminal manager. > >-Copyright (c) 1993-2018 Free Software Foundation, Inc. >+Copyright (c) 1993-2022 Free Software Foundation, Inc. > > Permission is granted to make and distribute verbatim copies of > this manual provided the copyright notice and this permission notice >@@ -53,11 +53,11 @@ > @title Screen > @subtitle The virtual terminal manager > @subtitle for Version @value{version} >-@subtitle Feb 2020 >+@subtitle Jan 2022 > > @page > @vskip 0pt plus 1filll >-Copyright @copyright{} 1993-2018 Free Software Foundation, Inc. >+Copyright @copyright{} 1993-2022 Free Software Foundation, Inc. > > Permission is granted to make and distribute verbatim copies of > this manual provided the copyright notice and this permission notice >@@ -185,7 +185,7 @@ > the invoking shell to the application (emacs in this case), because it is > forked from the parent screen process, not from the invoking shell. > >-If @file{/var/run/utmp} is writable by @code{screen}, an appropriate record >+If @file{/etc/utmp} is writable by @code{screen}, an appropriate record > will be written to this file for each window, and removed when the > window is closed. This is useful for working with @code{talk}, > @code{script}, @code{shutdown}, @code{rsend}, @code{sccs} and other >@@ -314,7 +314,7 @@ > > @item -l > @itemx -ln >-Turn login mode on or off (for @file{/var/run/utmp} updating). This option >+Turn login mode on or off (for @file{/etc/utmp} updating). This option > is equivalent to the @code{deflogin} command (@pxref{Login}). > > @item -ls [@var{match}] >@@ -333,13 +333,6 @@ > Ask your system administrator if you are not sure. > Remove sessions with the @samp{-wipe} option. > >-@emph{Note}: >- If sockets are missing (and because of this, your sessions are not >- listed), you may send a @code{SIGCHLD} to its `SCREEN' >- process and the process will re-establish the socket (think of >- someone cleaning @file{/tmp} thoroughly). >- >- > @item -L > Tell @code{screen} to turn on automatic output logging for the > windows. >@@ -504,14 +497,14 @@ > @cindex screenrc > When @code{screen} is invoked, it executes initialization commands from > the files @file{.screenrc} in the user's home directory and >-@file{/etc/screenrc}. These defaults can be overridden in the >+@file{/usr/local/etc/screenrc}. These defaults can be overridden in the > following ways: > For the global screenrc file @code{screen} searches for the environment > variable @code{$SYSSCREENRC} (this override feature may be disabled at > compile-time). The user specific screenrc file is > searched for in @code{$SCREENRC}, then > @file{@code{$HOME}/.screenrc}. The command line option @samp{-c} >-specifies which file to use (@pxref{Invoking Screen}. Commands in these >+specifies which file to use (@pxref{Invoking Screen}). Commands in these > files are used to set options, bind commands to keys, and to > automatically establish one or more windows at the beginning of > your @code{screen} session. Commands are listed one per line, with >@@ -1096,7 +1089,7 @@ > @item logfile @var{filename} > Place where to collect logfiles. @xref{Log}. > @item login [@var{state}] >-Log the window in @file{/var/run/utmp}. @xref{Login}. >+Log the window in @file{/etc/utmp}. @xref{Login}. > @item logtstamp [@var{state}] > Configure logfile time-stamps. @xref{Log}. > @item mapdefault >@@ -2219,7 +2212,7 @@ > Without any arguments, @code{screen} will prompt for how you would > like to resize the current region. > >-See @code{focusminsize} if you want to restrict the minimun size a region can have. >+See @code{focusminsize} if you want to restrict the minimum size a region can have. > > @end deffn > >@@ -2412,7 +2405,7 @@ > * Naming Windows:: Control the name of the window > * Console:: See the host's console messages > * Kill:: Destroy an unwanted window >-* Login:: Control @file{/var/run/utmp} logging >+* Login:: Control @file{/etc/utmp} logging > * Mode:: Control the file mode of the pty > * Monitor:: Watch for activity or inactivity in a window > * Windows:: List the active windows >@@ -2621,7 +2614,7 @@ > @kindex L > @deffn Command login [state] > (@kbd{C-a L})@* >-Adds or removes the entry in @file{/var/run/utmp} for the current window. >+Adds or removes the entry in @file{/etc/utmp} for the current window. > This controls whether or not the window is @dfn{logged in}. In addition > to this toggle, it is convenient to have ``log in'' and ``log out'' > keys. For instance, @code{bind I login on} and @code{bind O >@@ -3696,7 +3689,7 @@ > > @noindent > @kbd{f}/@kbd{F}, @kbd{t}/@kbd{T} move the cursor forward/backward to the >-next occurence of the target. (eg, '3fy' will move the cursor to the 3rd >+next occurrence of the target. (eg, '3fy' will move the cursor to the 3rd > 'y' to the right.) > > @noindent >@@ -3877,7 +3870,7 @@ > (none)@* > Stuff the string @var{string} in the input buffer of the current window. > This is like the @code{paste} command, but with much less overhead. >-Without a paramter, @code{screen} will prompt for a string to stuff. >+Without a parameter, @code{screen} will prompt for a string to stuff. > You cannot paste large buffers with the @code{stuff} command. It is most > useful for key bindings. @xref{Bindkey}. > @end deffn >@@ -5328,7 +5321,8 @@ > load averages over 1, 5, and 15 minutes (if this is available on your > system). For window-specific information use @code{info} (@pxref{Info}). > If a @var{string} is specified, it changes the format of the time report >-like it is described in the string escapes chapter (@pxref{String Escapes}). Screen uses a default of @samp{%c:%s %M %d %H%? %l%?}. >+like it is described in the string escapes chapter (@pxref{String Escapes}). >+Screen uses a default of @samp{%c:%s %M %d %H%? %l%?}. > @end deffn > > @node Verbose, Version, Time, Miscellaneous >@@ -5578,6 +5572,8 @@ > weekday name > @item E > sets %? to true if the escape character has been pressed. >+@item e >+encoding > @item f > flags of the window. @xref{Windows}, for meanings of the various flags. > @item F >@@ -5809,13 +5805,13 @@ > global initialization files. > > @item @code{$SYSSCREENRC} >-@itemx /etc/screenrc >+@itemx /local/etc/screenrc > @code{screen} initialization commands > > @item @code{$SCREENRC} > @itemx @code{$HOME}/.iscreenrc > @itemx @code{$HOME}/.screenrc >-Read in after /etc/screenrc >+Read in after /local/etc/screenrc > > @item @code{$SCREENDIR}/S-@var{login} > >@@ -5842,7 +5838,7 @@ > @itemx /etc/termcap > Terminal capability databases > >-@item /var/run/utmp >+@item /etc/utmp > Login records > > @item @code{$LOCKPRG} >@@ -5954,10 +5950,10 @@ > in order to be able to > correctly change the owner of the tty device file for each window. > Special permission may also be required to write the file >-@file{/var/run/utmp}. >+@file{/etc/utmp}. > > @item >-Entries in @file{/var/run/utmp} are not removed when @code{screen} is killed >+Entries in @file{/etc/utmp} are not removed when @code{screen} is killed > with SIGKILL. This will cause some programs (like "w" or "rwho") to > advertise that a user is logged on who really isn't. > >@@ -5995,7 +5991,7 @@ > @section Reporting Bugs > @cindex bug report > >-If you find a bug in @code{Screen}, please send electronic mail to >+If you find a bug in @code{Screen}, please send mail to > @w{@samp{screen-devel@@gnu.org}}. Include the version number > of @code{Screen} which you are using. Also include in your message the > hardware and operating system, the compiler used to compile, a >diff -ur screen.orig/encoding.c screen/encoding.c >--- screen.orig/encoding.c 2023-06-01 14:58:17.239665027 +0300 >+++ screen/encoding.c 2022-01-28 17:06:02.682611899 +0300 >@@ -1264,7 +1264,7 @@ > }; > > if (c >= 0xdf00 && c <= 0xdfff) >- return 1; /* dw combining sequence */ >+ return 1; /* dw combining sequence */ > return ((bisearch(c, wide, sizeof(wide) / sizeof(struct interval) - 1)) || > (cjkwidth && > bisearch(c, ambiguous, >diff -ur screen.orig/etc/etcscreenrc screen/etc/etcscreenrc >--- screen.orig/etc/etcscreenrc 2023-06-01 14:58:17.239665027 +0300 >+++ screen/etc/etcscreenrc 2022-01-28 17:05:57.346479760 +0300 >@@ -1,6 +1,6 @@ > # > # This is an example for the global screenrc file. >-# You may want to install this file as /etc/screenrc. >+# You may want to install this file as /usr/local/etc/screenrc. > # Check config.h for the exact location. > # > # Flaws of termcap and standard settings are done here. >@@ -92,10 +92,3 @@ > bind O login off > bind } history > >-# Red Hat Hack^H^H^H^HPatch >-# This makes screen treat backspaces '^?' as >-# deletes. There should be a fix in the code >-# for the way termcap inheritance works, >-# but I dont know where to put it, and this works. >-bindkey -d -k kb stuff \010 >-# /Red Hat Patch >diff -ur screen.orig/etc/screenrc screen/etc/screenrc >--- screen.orig/etc/screenrc 2023-06-01 14:58:17.239665027 +0300 >+++ screen/etc/screenrc 2022-01-28 17:06:02.682611899 +0300 >@@ -130,15 +130,6 @@ > register ] "\033:se ai\015a" > bind ^] paste [.] > >-# Red Hat Hack^H^H^H^HPatch >-# This makes screen treat backspaces '^?' as >-# deletes. There should be a fix in the code >-# for the way termcap inheritance works, >-# but I dont know where to put it, and this works. >-bindkey -d -k kb stuff \010 >-# /Red Hat Patch >- >- > ################ > # > # default windows >diff -ur screen.orig/extern.h screen/extern.h >--- screen.orig/extern.h 2023-06-01 14:58:17.240665030 +0300 >+++ screen/extern.h 2022-01-28 17:06:02.682611899 +0300 >@@ -75,7 +75,7 @@ > extern int GetAnsiStatus __P((struct win *, char *)); > extern void WNewAutoFlow __P((struct win *, int)); > extern void WBell __P((struct win *, int)); >-extern void WMsg __P((struct win *, int, const char *)); >+extern void WMsg __P((struct win *, int, char *)); > extern void WChangeSize __P((struct win *, int, int)); > extern void WindowChanged __P((struct win *, int)); > extern int MFindUsedLine __P((struct win *, int, int)); >diff -ur screen.orig/FAQ screen/FAQ >--- screen.orig/FAQ 2023-06-01 14:58:17.233665014 +0300 >+++ screen/FAQ 2022-01-28 17:06:02.674611701 +0300 >@@ -191,7 +191,7 @@ > Q: The "talk" command does not work when Screen is active. > > A: Talk and several other programs rely on entries in the Utmp- >- Database (/var/run/utmp). On some systems this Database is world >+ Database (/etc/utmp). On some systems this Database is world > writable, on others it is not. If it is not, screen must be > installed with the appropriate permissions (user or group s-bit) > just like any program that uses PTYs (rlogin, xterm, ...). When >diff -ur screen.orig/fileio.c screen/fileio.c >--- screen.orig/fileio.c 2023-06-01 14:58:17.240665030 +0300 >+++ screen/fileio.c 2022-01-28 17:06:02.682611899 +0300 >@@ -42,109 +42,108 @@ > extern struct display *display, *displays; > extern struct win *fore; > extern struct layer *flayer; >-extern int ServerSocket; >-extern int real_uid, eff_uid; >-extern int real_gid, eff_gid; >-extern char *extra_incap, *extra_outcap; >-extern char *home, *RcFileName; >-extern char SockPath[], *SockName; >+extern int ServerSocket; >+extern int real_uid, eff_uid; >+extern int real_gid, eff_gid; >+extern char *extra_incap, *extra_outcap; >+extern char *home, *RcFileName; >+extern char SockPath[], *SockName; > #ifdef COPY_PASTE >-extern char *BufferFile; >+extern char *BufferFile; > #endif >-extern int hardcopy_append; >-extern char *hardcopydir; >- >-static char *CatExtra __P((char *, char *)); >-static char *findrcfile __P((char *)); >+extern int hardcopy_append; >+extern char *hardcopydir; > >+static char *CatExtra __P((char *, char *)); >+static char *findrcfile __P((char *)); > > char *rc_name = ""; > int rc_recursion = 0; > >-static char * CatExtra(register char *str1, register char *str2) { >- register char *cp; >- register int len1, len2, add_colon; >- >- len1 = strlen(str1); >- if (len1 == 0) >- return str2; >- add_colon = (str1[len1 - 1] != ':'); >- if (str2) { >- len2 = strlen(str2); >- if ((cp = realloc(str2, (unsigned) len1 + len2 + add_colon + 1)) == NULL) >- Panic(0, "%s", strnomem); >- bcopy(cp, cp + len1 + add_colon, len2 + 1); >- } >- else { >- if ((cp = malloc((unsigned) len1 + add_colon + 1)) == NULL) >- Panic(0, "%s", strnomem); >- cp[len1 + add_colon] = '\0'; >- } >- bcopy(str1, cp, len1); >- if (add_colon) >- cp[len1] = ':'; >- return cp; >-} >- >-static char *findrcfile(char *rcfile) { >- char buf[256]; >- char *p; >- >- /* Tilde prefix support courtesy <hesso@pool.math.tu-berlin.de>, >- * taken from a Debian patch. */ >- if (rcfile && *rcfile == '~') { >- static char rcfilename_tilde_exp[MAXPATHLEN+1]; >- char *slash_position = strchr(rcfile, '/'); >- >- if (slash_position == rcfile+1) { >- char *home = getenv("HOME"); >- if (!home) { >- Msg(0, "%s: source: tilde expansion failed", rc_name); >- return NULL; >- } >- snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile+2); >- } >- else if (slash_position) { >- struct passwd *p; >- *slash_position = 0; >- p = getpwnam(rcfile+1); >- if (!p){ >- Msg(0, "%s: source: tilde expansion failed for user %s", rc_name, rcfile+1); >- return NULL; >- } >- snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position+1); >- } >- else { >- Msg(0, "%s: source: illegal tilde expression.", rc_name); >- return NULL; >- } >- rcfile = rcfilename_tilde_exp; >- } >- >- if (rcfile) { >- char *rcend = rindex(rc_name, '/'); >- if (*rcfile != '/' && rcend && (rcend - rc_name) + strlen(rcfile) + 2 < sizeof(buf)) { >- strncpy(buf, rc_name, rcend - rc_name + 1); >- strcpy(buf + (rcend - rc_name) + 1, rcfile); >- if (access(buf, R_OK) == 0) >- return SaveStr(buf); >- } >- debug1("findrcfile: you specified '%s'\n", rcfile); >- return SaveStr(rcfile); >- } >- >- debug("findrcfile: you specified nothing...\n"); >- if ((p = getenv("SCREENRC")) != NULL && *p != '\0') { >- debug1(" $SCREENRC has: '%s'\n", p); >- return SaveStr(p); >- } >- else { >- debug(" ...nothing in $SCREENRC, defaulting $HOME/.screenrc\n"); >- if (strlen(home) > sizeof(buf) - 12) >- Panic(0, "Rc: home too large"); >- sprintf(buf, "%s/.screenrc", home); >- return SaveStr(buf); >- } >+static char * >+CatExtra(register char *str1, register char *str2) >+{ >+ register char *cp; >+ register int len1, len2, add_colon; >+ >+ len1 = strlen(str1); >+ if (len1 == 0) >+ return str2; >+ add_colon = (str1[len1 - 1] != ':'); >+ if (str2) { >+ len2 = strlen(str2); >+ if ((cp = realloc(str2, (unsigned)len1 + len2 + add_colon + 1)) == NULL) >+ Panic(0, "%s", strnomem); >+ bcopy(cp, cp + len1 + add_colon, len2 + 1); >+ } else { >+ if ((cp = malloc((unsigned)len1 + add_colon + 1)) == NULL) >+ Panic(0, "%s", strnomem); >+ cp[len1 + add_colon] = '\0'; >+ } >+ bcopy(str1, cp, len1); >+ if (add_colon) >+ cp[len1] = ':'; >+ return cp; >+} >+ >+static char * >+findrcfile(char *rcfile) >+{ >+ char buf[256]; >+ char *p; >+ >+ /* Tilde prefix support courtesy <hesso@pool.math.tu-berlin.de>, >+ * taken from a Debian patch. */ >+ if (rcfile && *rcfile == '~') { >+ static char rcfilename_tilde_exp[MAXPATHLEN + 1]; >+ char *slash_position = strchr(rcfile, '/'); >+ >+ if (slash_position == rcfile + 1) { >+ char *home = getenv("HOME"); >+ if (!home) { >+ Msg(0, "%s: source: tilde expansion failed", rc_name); >+ return NULL; >+ } >+ snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile + 2); >+ } else if (slash_position) { >+ struct passwd *p; >+ *slash_position = 0; >+ p = getpwnam(rcfile + 1); >+ if (!p) { >+ Msg(0, "%s: source: tilde expansion failed for user %s", rc_name, rcfile + 1); >+ return NULL; >+ } >+ snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position + 1); >+ } else { >+ Msg(0, "%s: source: illegal tilde expression.", rc_name); >+ return NULL; >+ } >+ rcfile = rcfilename_tilde_exp; >+ } >+ >+ if (rcfile) { >+ char *rcend = rindex(rc_name, '/'); >+ if (*rcfile != '/' && rcend && (rcend - rc_name) + strlen(rcfile) + 2 < sizeof(buf)) { >+ strncpy(buf, rc_name, rcend - rc_name + 1); >+ strcpy(buf + (rcend - rc_name) + 1, rcfile); >+ if (access(buf, R_OK) == 0) >+ return SaveStr(buf); >+ } >+ debug1("findrcfile: you specified '%s'\n", rcfile); >+ return SaveStr(rcfile); >+ } >+ >+ debug("findrcfile: you specified nothing...\n"); >+ if ((p = getenv("SCREENRC")) != NULL && *p != '\0') { >+ debug1(" $SCREENRC has: '%s'\n", p); >+ return SaveStr(p); >+ } else { >+ debug(" ...nothing in $SCREENRC, defaulting $HOME/.screenrc\n"); >+ if (strlen(home) > sizeof(buf) - 12) >+ Panic(0, "Rc: home too large"); >+ sprintf(buf, "%s/.screenrc", home); >+ return SaveStr(buf); >+ } > } > > /* >@@ -152,630 +151,638 @@ > * 1) rcfilename = "/etc/screenrc" > * 2) rcfilename = RcFileName > */ >-int StartRc(char *rcfilename, int nopanic) { >- register int argc, len; >- register char *p, *cp; >- char buf[2048]; >- char *args[MAXARGS]; >- int argl[MAXARGS]; >- FILE *fp; >- char *oldrc_name = rc_name; >- >- /* always fix termcap/info capabilities */ >- extra_incap = CatExtra("TF", extra_incap); >- >- /* Special settings for vt100 and others */ >- if (display && (!strncmp(D_termname, "vt", 2) || !strncmp(D_termname, "xterm", 5))) >- extra_incap = CatExtra("xn:f0=\033Op:f1=\033Oq:f2=\033Or:f3=\033Os:f4=\033Ot:f5=\033Ou:f6=\033Ov:f7=\033Ow:f8=\033Ox:f9=\033Oy:f.=\033On:f,=\033Ol:fe=\033OM:f+=\033Ok:f-=\033Om:f*=\033Oj:f/=\033Oo:fq=\033OX", extra_incap); >- >- rc_name = findrcfile(rcfilename); >- if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) { >- const char *rc_nonnull = rc_name ? rc_name : rcfilename; >- if (!rc_recursion && RcFileName && !strcmp(RcFileName, rc_nonnull)) { >- /* >- * User explicitly gave us that name, >- * this is the only case, where we get angry, if we can't read >- * the file. >- */ >- debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename); >- if (!nopanic) Panic(0, "Unable to open \"%s\".", rc_nonnull); >- /* possibly NOTREACHED */ >- } >- >- debug1("StartRc: '%s' no good. ignored\n", rc_nonnull); >- if (rc_name) >- Free(rc_name); >- rc_name = oldrc_name; >- return 1; >- } >- while (fgets(buf, sizeof buf, fp) != NULL) { >- if ((p = rindex(buf, '\n')) != NULL) >- *p = '\0'; >- >- if ((argc = Parse(buf, sizeof buf, args, argl)) == 0) >- continue; >- >- if (strcmp(args[0], "echo") == 0) { >- if (!display) >- continue; >- if (argc < 2 || (argc == 3 && strcmp(args[1], "-n")) || argc > 3) { >- Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name); >- continue; >- } >- AddStr(args[argc - 1]); >- if (argc != 3) { >- AddStr("\r\n"); >- Flush(0); >- } >- } >- >- else if (strcmp(args[0], "sleep") == 0) { >- if (!display) >- continue; >- debug("sleeeeeeep\n"); >- if (argc != 2) { >- Msg(0, "%s: sleep: one numeric argument expected.", rc_name); >- continue; >- } >- DisplaySleep1000(1000 * atoi(args[1]), 1); >- } >+int >+StartRc(char *rcfilename, int nopanic) >+{ >+ register int argc, len; >+ register char *p, *cp; >+ char buf[2048]; >+ char *args[MAXARGS]; >+ int argl[MAXARGS]; >+ FILE *fp; >+ char *oldrc_name = rc_name; >+ >+ /* always fix termcap/info capabilities */ >+ extra_incap = CatExtra("TF", extra_incap); >+ >+ /* Special settings for vt100 and others */ >+ if (display && (!strncmp(D_termname, "vt", 2) || !strncmp(D_termname, "xterm", 5))) >+ extra_incap = CatExtra("xn:f0=\033Op:f1=\033Oq:f2=\033Or:f3=\033Os:f4=\033Ot:f5=\033Ou:f6=\033Ov:f7=\033Ow:f8=\033Ox:f9=\033Oy:f.=\033On:f,=\033Ol:fe=\033OM:f+=\033Ok:f-=\033Om:f*=\033Oj:f/=\033Oo:fq=\033OX", extra_incap); >+ >+ rc_name = findrcfile(rcfilename); >+ if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) { >+ const char *rc_nonnull = rc_name ? rc_name : rcfilename; >+ if (!rc_recursion && RcFileName && !strcmp(RcFileName, rc_nonnull)) { >+ /* >+ * User explicitly gave us that name, >+ * this is the only case, where we get angry, if we can't read >+ * the file. >+ */ >+ debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename); >+ if (!nopanic) >+ Panic(0, "Unable to open \"%s\".", rc_nonnull); >+ /* possibly NOTREACHED */ >+ } >+ >+ debug1("StartRc: '%s' no good. ignored\n", rc_nonnull); >+ if (rc_name) >+ Free(rc_name); >+ rc_name = oldrc_name; >+ return 1; >+ } >+ while (fgets(buf, sizeof buf, fp) != NULL) { >+ if ((p = rindex(buf, '\n')) != NULL) >+ *p = '\0'; >+ >+ if ((argc = Parse(buf, sizeof buf, args, argl)) == 0) >+ continue; >+ >+ if (strcmp(args[0], "echo") == 0) { >+ if (!display) >+ continue; >+ if (argc < 2 || (argc == 3 && strcmp(args[1], "-n")) || argc > 3) { >+ Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name); >+ continue; >+ } >+ AddStr(args[argc - 1]); >+ if (argc != 3) { >+ AddStr("\r\n"); >+ Flush(0); >+ } >+ } else if (strcmp(args[0], "sleep") == 0) { >+ if (!display) >+ continue; >+ debug("sleeeeeeep\n"); >+ if (argc != 2) { >+ Msg(0, "%s: sleep: one numeric argument expected.", rc_name); >+ continue; >+ } >+ DisplaySleep1000(1000 * atoi(args[1]), 1); >+ } > #ifdef TERMINFO > else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "terminfo")) { > #else >- else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "termcap")) { >+ else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "termcap")) { > #endif >- if (!display) >- continue; >- if (argc < 3 || argc > 4) { >- Msg(0, "%s: %s: incorrect number of arguments.", rc_name, args[0]); >- continue; >- } >- >- for (p = args[1]; p && *p; p = cp) { >- if ((cp = index(p, '|')) != 0) >- *cp++ = '\0'; >- len = strlen(p); >- if (p[len - 1] == '*') { >- if (!(len - 1) || !strncmp(p, D_termname, len - 1)) >- break; >- } >- else if (!strcmp(p, D_termname)) >- break; >- } >- if (!(p && *p)) >- continue; >- extra_incap = CatExtra(args[2], extra_incap); >- if (argc == 4) >- extra_outcap = CatExtra(args[3], extra_outcap); >- } >- else if (!strcmp(args[0], "source")) { >- if (rc_recursion <= 10) { >- rc_recursion++; >- (void)StartRc(args[1], 0); >- rc_recursion--; >- } >- } >- } >- fclose(fp); >- Free(rc_name); >- rc_name = oldrc_name; >- return 0; >-} >- >-void FinishRc(char *rcfilename) { >- char buf[2048]; >- FILE *fp; >- char *oldrc_name = rc_name; >- >- rc_name = findrcfile(rcfilename); >- >- if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) { >- const char *rc_nonnull = rc_name ? rc_name : rcfilename; >- if (rc_recursion) >- Msg(errno, "%s: source %s", oldrc_name, rc_nonnull); >- else if (RcFileName && !strcmp(RcFileName, rc_nonnull)) { >+ if (!display) >+ continue; >+ if (argc < 3 || argc > 4) { >+ Msg(0, "%s: %s: incorrect number of arguments.", rc_name, args[0]); >+ continue; >+ } >+ >+ for (p = args[1]; p && *p; p = cp) { >+ if ((cp = index(p, '|')) != 0) >+ *cp++ = '\0'; >+ len = strlen(p); >+ if (p[len - 1] == '*') { >+ if (!(len - 1) || !strncmp(p, D_termname, len - 1)) >+ break; >+ } else if (!strcmp(p, D_termname)) >+ break; >+ } >+ if (!(p && *p)) >+ continue; >+ extra_incap = CatExtra(args[2], extra_incap); >+ if (argc == 4) >+ extra_outcap = CatExtra(args[3], extra_outcap); >+ } else if (!strcmp(args[0], "source")) { >+ if (rc_recursion <= 10) { >+ rc_recursion++; >+ (void)StartRc(args[1], 0); >+ rc_recursion--; >+ } >+ } >+ } >+ fclose(fp); >+ Free(rc_name); >+ rc_name = oldrc_name; >+ return 0; >+} >+ >+void >+FinishRc(char *rcfilename) >+{ >+ char buf[2048]; >+ FILE *fp; >+ char *oldrc_name = rc_name; >+ >+ rc_name = findrcfile(rcfilename); >+ >+ if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) { >+ const char *rc_nonnull = rc_name ? rc_name : rcfilename; >+ if (rc_recursion) >+ Msg(errno, "%s: source %s", oldrc_name, rc_nonnull); >+ else if (RcFileName && !strcmp(RcFileName, rc_nonnull)) { > /* > * User explicitly gave us that name, > * this is the only case, where we get angry, if we can't read > * the file. > */ >- debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename); >- Panic(0, "Unable to open \"%s\".", rc_nonnull); >- /* NOTREACHED */ >- } >- debug1("FinishRc: '%s' no good. ignored\n", rc_nonnull); >- if (rc_name) >- Free(rc_name); >- rc_name = oldrc_name; >- return; >- } >- >- debug("finishrc is going...\n"); >- while (fgets(buf, sizeof buf, fp) != NULL) >- RcLine(buf, sizeof buf); >- (void) fclose(fp); >- Free(rc_name); >- rc_name = oldrc_name; >-} >- >-void do_source(char *rcfilename) { >- if (rc_recursion > 10) { >- Msg(0, "%s: source: recursion limit reached", rc_name); >- return; >- } >- rc_recursion++; >- FinishRc(rcfilename); >- rc_recursion--; >+ debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename); >+ Panic(0, "Unable to open \"%s\".", rc_nonnull); >+ /* NOTREACHED */ >+ } >+ debug1("FinishRc: '%s' no good. ignored\n", rc_nonnull); >+ if (rc_name) >+ Free(rc_name); >+ rc_name = oldrc_name; >+ return; >+ } >+ >+ debug("finishrc is going...\n"); >+ while (fgets(buf, sizeof buf, fp) != NULL) >+ RcLine(buf, sizeof buf); >+ (void)fclose(fp); >+ Free(rc_name); >+ rc_name = oldrc_name; >+} >+ >+void >+do_source(char *rcfilename) >+{ >+ if (rc_recursion > 10) { >+ Msg(0, "%s: source: recursion limit reached", rc_name); >+ return; >+ } >+ rc_recursion++; >+ FinishRc(rcfilename); >+ rc_recursion--; > } > >- > /* > * Running a Command Line in the environment determined by the display. > * The fore window is taken from the display as well as the user. > * This is bad when we run detached. > */ >-void RcLine(char *ubuf, int ubufl) { >- char *args[MAXARGS]; >- int argl[MAXARGS]; >+void >+RcLine(char *ubuf, int ubufl) >+{ >+ char *args[MAXARGS]; >+ int argl[MAXARGS]; > #ifdef MULTIUSER >- extern struct acluser *EffectiveAclUser; /* acl.c */ >- extern struct acluser *users; /* acl.c */ >+ extern struct acluser *EffectiveAclUser; /* acl.c */ >+ extern struct acluser *users; /* acl.c */ > #endif > >- if (display) { >- fore = D_fore; >- flayer = D_forecv->c_layer; >- } >- else >- flayer = fore ? fore->w_savelayer : 0; >- if (Parse(ubuf, ubufl, args, argl) <= 0) >- return; >+ if (display) { >+ fore = D_fore; >+ flayer = D_forecv->c_layer; >+ } else >+ flayer = fore ? fore->w_savelayer : 0; >+ if (Parse(ubuf, ubufl, args, argl) <= 0) >+ return; > > #ifdef MULTIUSER >- if (!display) { >+ if (!display) { > /* the session owner does it, when there is no display here */ >- EffectiveAclUser = users; >- debug("RcLine: WARNING, no display no user! Session owner executes command\n"); >- } >+ EffectiveAclUser = users; >+ debug("RcLine: WARNING, no display no user! Session owner executes command\n"); >+ } > #endif > >- DoCommand(args, argl); >+ DoCommand(args, argl); > > #ifdef MULTIUSER >- EffectiveAclUser = 0; >+ EffectiveAclUser = 0; > #endif > } > > /* needs display for copybuffer access and termcap dumping */ >-void WriteFile(struct acluser *user, char *fn, int dump) { >+void >+WriteFile(struct acluser *user, char *fn, int dump) >+{ > /* dump==0: create .termcap, > * dump==1: hardcopy, > * #ifdef COPY_PASTE > * dump==2: BUFFERFILE >- * #endif COPY_PASTE >+ * #endif COPY_PASTE > * dump==1: scrollback, > */ >- register int i, j, k; >- register char *p; >- register FILE *f; >- char fnbuf[1024]; >- char *mode = "w"; >+ register int i, j, k; >+ register char *p; >+ register FILE *f; >+ char fnbuf[1024]; >+ char *mode = "w"; > > #ifdef COPY_PASTE >- int public = 0; >+ int public = 0; > # ifdef HAVE_LSTAT >- struct stat stb, stb2; >- int fd, exists = 0; >+ struct stat stb, stb2; >+ int fd, exists = 0; > # endif > #endif > >- switch (dump) { >- case DUMP_TERMCAP: >- if (fn == 0) { >- i = SockName - SockPath; >- if (i > (int)sizeof(fnbuf) - 9) >- i = 0; >- strncpy(fnbuf, SockPath, i); >- strcpy(fnbuf + i, ".termcap"); >- fn = fnbuf; >- } >- break; >- >- case DUMP_HARDCOPY: >- case DUMP_SCROLLBACK: >- if (fn == 0) { >- if (fore == 0) >- return; >- if (hardcopydir && *hardcopydir && strlen(hardcopydir) < sizeof(fnbuf) - 21) >- sprintf(fnbuf, "%s/hardcopy.%d", hardcopydir, fore->w_number); >- else >- sprintf(fnbuf, "hardcopy.%d", fore->w_number); >- fn = fnbuf; >- } >- if (hardcopy_append && !access(fn, W_OK)) >- mode = "a"; >- break; >+ switch (dump) { >+ case DUMP_TERMCAP: >+ if (fn == 0) { >+ i = SockName - SockPath; >+ if (i > (int)sizeof(fnbuf) - 9) >+ i = 0; >+ strncpy(fnbuf, SockPath, i); >+ strcpy(fnbuf + i, ".termcap"); >+ fn = fnbuf; >+ } >+ break; >+ >+ case DUMP_HARDCOPY: >+ case DUMP_SCROLLBACK: >+ if (fn == 0) { >+ if (fore == 0) >+ return; >+ if (hardcopydir && *hardcopydir && strlen(hardcopydir) < sizeof(fnbuf) - 21) >+ sprintf(fnbuf, "%s/hardcopy.%d", hardcopydir, fore->w_number); >+ else >+ sprintf(fnbuf, "hardcopy.%d", fore->w_number); >+ fn = fnbuf; >+ } >+ if (hardcopy_append && !access(fn, W_OK)) >+ mode = "a"; >+ break; > > #ifdef COPY_PASTE >- case DUMP_EXCHANGE: >- if (fn == 0) { >- strncpy(fnbuf, BufferFile, sizeof(fnbuf) - 1); >- fnbuf[sizeof(fnbuf) - 1] = 0; >- fn = fnbuf; >- } >- public = !strcmp(fn, bufferfile); >+ case DUMP_EXCHANGE: >+ if (fn == 0) { >+ strncpy(fnbuf, BufferFile, sizeof(fnbuf) - 1); >+ fnbuf[sizeof(fnbuf) - 1] = 0; >+ fn = fnbuf; >+ } >+ public = !strcmp(fn, DEFAULT_BUFFERFILE); > # ifdef HAVE_LSTAT >- exists = !lstat(fn, &stb); >- if (public && exists && (S_ISLNK(stb.st_mode) || stb.st_nlink > 1)) { >- Msg(0, "No write to links, please."); >- return; >- } >+ exists = !lstat(fn, &stb); >+ if (public && exists && (S_ISLNK(stb.st_mode) || stb.st_nlink > 1)) { >+ Msg(0, "No write to links, please."); >+ return; >+ } > # endif >- break; >+ break; > #endif >- } >+ } > >- debug2("WriteFile(%d) %s\n", dump, fn); >- if (UserContext() > 0) { >- debug("Writefile: usercontext\n"); >+ debug2("WriteFile(%d) %s\n", dump, fn); >+ if (UserContext() > 0) { >+ debug("Writefile: usercontext\n"); > #ifdef COPY_PASTE >- if (dump == DUMP_EXCHANGE && public) { >+ if (dump == DUMP_EXCHANGE && public) { > # ifdef HAVE_LSTAT >- if (exists) { >- if ((fd = open(fn, O_WRONLY, 0666)) >= 0) { >- if (fstat(fd, &stb2) == 0 && stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino) >- if (ftruncate(fd, 0) < 0) { >- close(fd); >- fd = -1; >- } >- else { >- close(fd); >- fd = -1; >- } >- } >- } >- else >- fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0666); >- f = fd >= 0 ? fdopen(fd, mode) : 0; >+ if (exists) { >+ if ((fd = open(fn, O_WRONLY, 0666)) >= 0) { >+ if (fstat(fd, &stb2) == 0 && stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino) >+ ftruncate(fd, 0); >+ else { >+ close(fd); >+ fd = -1; >+ } >+ } >+ } else >+ fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0666); >+ f = fd >= 0 ? fdopen(fd, mode) : 0; > # else >- f = fopen(fn, mode); >+ f = fopen(fn, mode); > # endif >- } >- else >+ } else > #endif /* COPY_PASTE */ >- f = fopen(fn, mode); >- if (f == NULL) { >- debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode); >- UserReturn(0); >- } >- else { >- switch (dump) { >- case DUMP_HARDCOPY: >- case DUMP_SCROLLBACK: >- if (!fore) >- break; >- if (*mode == 'a') { >- putc('>', f); >- for (j = fore->w_width - 2; j > 0; j--) >- putc('=', f); >- fputs("<\n", f); >- } >- if (dump == DUMP_SCROLLBACK) { >+ f = fopen(fn, mode); >+ if (f == NULL) { >+ debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode); >+ UserReturn(0); >+ } else { >+ switch (dump) { >+ case DUMP_HARDCOPY: >+ case DUMP_SCROLLBACK: >+ if (!fore) >+ break; >+ if (*mode == 'a') { >+ putc('>', f); >+ for (j = fore->w_width - 2; j > 0; j--) >+ putc('=', f); >+ fputs("<\n", f); >+ } >+ if (dump == DUMP_SCROLLBACK) { > #ifdef COPY_PASTE >- for (i = fore->w_histheight - fore->w_scrollback_height; i < fore->w_histheight; i++) { >- p = (char *)(WIN(i)->image); >- for (k = fore->w_width - 1; k >= 0 && p[k] == ' '; k--) >- ; >- for (j = 0; j <= k; j++) >- putc(p[j], f); >- putc('\n', f); >- } >-#endif >- } >- for (i = 0; i < fore->w_height; i++) { >- p = (char *)fore->w_mlines[i].image; >- for (k = fore->w_width - 1; k >= 0 && p[k] == ' '; k--) >- ; >- for (j = 0; j <= k; j++) >- putc(p[j], f); >- putc('\n', f); >- } >- break; >- >- case DUMP_TERMCAP: >- DumpTermcap(fore->w_aflag, f); >- break; >+ for (i = fore->w_histheight - fore->w_scrollback_height; i < fore->w_histheight; i++) { >+ p = (char *)(WIN(i)->image); >+ for (k = fore->w_width - 1; >+ k >= 0 && p[k] == ' '; k--) >+ ; >+ for (j = 0; j <= k; j++) >+ putc(p[j], f); >+ putc('\n', f); >+ } >+#endif >+ } >+ for (i = 0; i < fore->w_height; i++) { >+ p = (char *)fore->w_mlines[i].image; >+ for (k = fore->w_width - 1; >+ k >= 0 && p[k] == ' '; k--) >+ ; >+ for (j = 0; j <= k; j++) >+ putc(p[j], f); >+ putc('\n', f); >+ } >+ break; >+ >+ case DUMP_TERMCAP: >+ DumpTermcap(fore->w_aflag, f); >+ break; > > #ifdef COPY_PASTE >- case DUMP_EXCHANGE: >- p = user->u_plop.buf; >- for (i = user->u_plop.len; i-- > 0; p++) >- if (*p == '\r' && (i == 0 || p[1] != '\n')) >- putc('\n', f); >- else >- putc(*p, f); >- break; >-#endif >- } >- (void) fclose(f); >- UserReturn(1); >- } >- } >- if (UserStatus() <= 0) >- Msg(0, "Cannot open \"%s\"", fn); >- else if (display && !*rc_name) { >- switch (dump) { >- case DUMP_TERMCAP: >- Msg(0, "Termcap entry written to \"%s\".", fn); >- break; >- case DUMP_HARDCOPY: >- case DUMP_SCROLLBACK: >- Msg(0, "Screen image %s to \"%s\".", (*mode == 'a') ? "appended" : "written", fn); >- break; >+ case DUMP_EXCHANGE: >+ p = user->u_plop.buf; >+ for (i = user->u_plop.len; i-- > 0; p++) >+ if (*p == '\r' && (i == 0 || p[1] != '\n')) >+ putc('\n', f); >+ else >+ putc(*p, f); >+ break; >+#endif >+ } >+ (void)fclose(f); >+ UserReturn(1); >+ } >+ } >+ if (UserStatus() <= 0) >+ Msg(0, "Cannot open \"%s\"", fn); >+ else if (display && !*rc_name) { >+ switch (dump) { >+ case DUMP_TERMCAP: >+ Msg(0, "Termcap entry written to \"%s\".", fn); >+ break; >+ case DUMP_HARDCOPY: >+ case DUMP_SCROLLBACK: >+ Msg(0, "Screen image %s to \"%s\".", (*mode == 'a') ? "appended" : "written", fn); >+ break; > #ifdef COPY_PASTE >- case DUMP_EXCHANGE: >- Msg(0, "Copybuffer written to \"%s\".", fn); >+ case DUMP_EXCHANGE: >+ Msg(0, "Copybuffer written to \"%s\".", fn); > #endif >- } >- } >+ } >+ } > } > > #ifdef COPY_PASTE > > /* > * returns an allocated buffer which holds a copy of the file named fn. >- * lenp (if nonzero) points to a location, where the buffer size should be >+ * lenp (if nonzero) points to a location, where the buffer size should be > * stored. > */ >-char *ReadFile(char *fn, int *lenp) { >- int i, l, size; >- char c, *bp, *buf; >- struct stat stb; >- >- ASSERT(lenp); >- debug1("ReadFile(%s)\n", fn); >- >- if ((i = secopen(fn, O_RDONLY, 0)) < 0) { >- Msg(errno, "no %s -- no slurp", fn); >- return NULL; >- } >- >- if (fstat(i, &stb)) { >- Msg(errno, "no good %s -- no slurp", fn); >- close(i); >- return NULL; >- } >- size = stb.st_size; >- >- if ((buf = malloc(size)) == NULL) { >- close(i); >- Msg(0, "%s", strnomem); >- return NULL; >- } >- errno = 0; >- >- if ((l = read(i, buf, size)) != size) { >- if (l < 0) >- l = 0; >- Msg(errno, "Got only %d bytes from %s", l, fn); >- } >- else { >- if (read(i, &c, 1) > 0) >- Msg(0, "Slurped only %d characters (of %d) into buffer - try again", l, size); >- else >- Msg(0, "Slurped %d characters into buffer", l); >- } >- close(i); >- *lenp = l; >- for (bp = buf; l-- > 0; bp++) >- if (*bp == '\n' && (bp == buf || bp[-1] != '\r')) >- *bp = '\r'; >- return buf; >-} >- >-void KillBuffers() { >- if (UserContext() > 0) >- UserReturn(unlink(BufferFile) ? errno : 0); >- errno = UserStatus(); >- Msg(errno, "%s %sremoved", BufferFile, errno ? "not " : ""); >+char * >+ReadFile(char *fn, int *lenp) >+{ >+ int i, l, size; >+ char c, *bp, *buf; >+ struct stat stb; >+ >+ ASSERT(lenp); >+ debug1("ReadFile(%s)\n", fn); >+ >+ if ((i = secopen(fn, O_RDONLY, 0)) < 0) { >+ Msg(errno, "no %s -- no slurp", fn); >+ return NULL; >+ } >+ >+ if (fstat(i, &stb)) { >+ Msg(errno, "no good %s -- no slurp", fn); >+ close(i); >+ return NULL; >+ } >+ size = stb.st_size; >+ >+ if ((buf = malloc(size)) == NULL) { >+ close(i); >+ Msg(0, "%s", strnomem); >+ return NULL; >+ } >+ errno = 0; >+ >+ if ((l = read(i, buf, size)) != size) { >+ if (l < 0) >+ l = 0; >+ Msg(errno, "Got only %d bytes from %s", l, fn); >+ } else { >+ if (read(i, &c, 1) > 0) >+ Msg(0, "Slurped only %d characters (of %d) into buffer - try again", l, size); >+ else >+ Msg(0, "Slurped %d characters into buffer", l); >+ } >+ close(i); >+ *lenp = l; >+ for (bp = buf; l-- > 0; bp++) >+ if (*bp == '\n' && (bp == buf || bp[-1] != '\r')) >+ *bp = '\r'; >+ return buf; >+} >+ >+void >+KillBuffers() >+{ >+ if (UserContext() > 0) >+ UserReturn(unlink(BufferFile) ? errno : 0); >+ errno = UserStatus(); >+ Msg(errno, "%s %sremoved", BufferFile, errno ? "not " : ""); > } > #endif /* COPY_PASTE */ > > > /* (Almost) secure open and fopen... */ > >-FILE *secfopen(char *name, char *mode) { >- FILE *fi; >+FILE * >+secfopen(char *name, char *mode) >+{ >+ FILE *fi; > #ifndef USE_SETEUID >- int flags, fd; >+ int flags, fd; > #endif > >- debug2("secfopen(%s, %s)\n", name, mode); >+ debug2("secfopen(%s, %s)\n", name, mode); > #ifdef USE_SETEUID >- xseteuid(real_uid); >- xsetegid(real_gid); >- fi = fopen(name, mode); >- xseteuid(eff_uid); >- xsetegid(eff_gid); >- return fi; >- >+ xseteuid(real_uid); >+ xsetegid(real_gid); >+ fi = fopen(name, mode); >+ xseteuid(eff_uid); >+ xsetegid(eff_gid); >+ return fi; > #else >- if (eff_uid == real_uid) >- return fopen(name, mode); >- if (mode[0] && mode[1] == '+') >- flags = O_RDWR; >- else >- flags = (mode[0] == 'r') ? O_RDONLY : O_WRONLY; >- if (mode[0] == 'w') >- flags |= O_CREAT | O_TRUNC; >- else if (mode[0] == 'a') >- flags |= O_CREAT | O_APPEND; >- else if (mode[0] != 'r') { >- errno = EINVAL; >- return 0; >- } >- if ((fd = secopen(name, flags, 0666)) < 0) >- return 0; >- if ((fi = fdopen(fd, mode)) == 0) { >- close(fd); >- return 0; >- } >- return fi; >+ if (eff_uid == real_uid) >+ return fopen(name, mode); >+ if (mode[0] && mode[1] == '+') >+ flags = O_RDWR; >+ else >+ flags = (mode[0] == 'r') ? O_RDONLY : O_WRONLY; >+ if (mode[0] == 'w') >+ flags |= O_CREAT | O_TRUNC; >+ else if (mode[0] == 'a') >+ flags |= O_CREAT | O_APPEND; >+ else if (mode[0] != 'r') { >+ errno = EINVAL; >+ return 0; >+ } >+ if ((fd = secopen(name, flags, 0666)) < 0) >+ return 0; >+ if ((fi = fdopen(fd, mode)) == 0) { >+ close(fd); >+ return 0; >+ } >+ return fi; > #endif > } > >- >-int secopen(char *name, int flags, int mode) { >- int fd; >+int >+secopen(char *name, int flags, int mode) >+{ >+ int fd; > #ifndef USE_SETEUID >- int q; >- struct stat stb; >+ int q; >+ struct stat stb; > #endif > >- debug3("secopen(%s, 0x%x, 0%03o)\n", name, flags, mode); >+ debug3("secopen(%s, 0x%x, 0%03o)\n", name, flags, mode); > #ifdef USE_SETEUID >- xseteuid(real_uid); >- xsetegid(real_gid); >- fd = open(name, flags, mode); >- xseteuid(eff_uid); >- xsetegid(eff_gid); >- return fd; >+ xseteuid(real_uid); >+ xsetegid(real_gid); >+ fd = open(name, flags, mode); >+ xseteuid(eff_uid); >+ xsetegid(eff_gid); >+ return fd; > #else >- if (eff_uid == real_uid) >- return open(name, flags, mode); >- /* Truncation/creation is done in UserContext */ >- if ((flags & O_TRUNC) || ((flags & O_CREAT) && access(name, F_OK))) { >- if (UserContext() > 0) { >- if ((fd = open(name, flags, mode)) >= 0) { >- close(fd); >- UserReturn(0); >- } >- if (errno == 0) >- errno = EACCES; >- UserReturn(errno); >- } >- if ((q = UserStatus())) { >- if (q > 0) >- errno = q; >- return -1; >- } >- } >- if (access(name, F_OK)) >- return -1; >- if ((fd = open(name, flags & ~(O_TRUNC | O_CREAT), 0)) < 0) >- return -1; >- debug("open successful\n"); >- if (fstat(fd, &stb)) { >- close(fd); >- return -1; >- } >- debug("fstat successful\n"); >- if (stb.st_uid != real_uid) { >- switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) { >- case O_RDONLY: >- q = 0004; >- break; >- case O_WRONLY: >- q = 0002; >- break; >- default: >- q = 0006; >- break; >- } >- if ((stb.st_mode & q) != q) { >- debug1("secopen: permission denied (%03o)\n", stb.st_mode & 07777); >- close(fd); >- errno = EACCES; >- return -1; >- } >- } >- debug1("secopen ok - returning %d\n", fd); >- return fd; >-#endif >-} >- >- >-int printpipe(struct win *p, char *cmd) { >- int pi[2]; >- if (pipe(pi)) { >- WMsg(p, errno, "printing pipe"); >- return -1; >- } >- fflush(NULL); >- switch (fork()) { >- case -1: >- WMsg(p, errno, "printing fork"); >- return -1; >- case 0: >- display = p->w_pdisplay; >- displays = 0; >- ServerSocket = -1; >+ if (eff_uid == real_uid) >+ return open(name, flags, mode); >+ >+ /* Truncation/creation is done in UserContext */ >+ if ((flags & O_TRUNC) || ((flags & O_CREAT) && access(name, F_OK))) { >+ if (UserContext() > 0) { >+ if ((fd = open(name, flags, mode)) >= 0) { >+ close(fd); >+ UserReturn(0); >+ } >+ if (errno == 0) >+ errno = EACCES; >+ UserReturn(errno); >+ } >+ if ((q = UserStatus())) { >+ if (q > 0) >+ errno = q; >+ return -1; >+ } >+ } >+ if (access(name, F_OK)) >+ return -1; >+ if ((fd = open(name, flags & ~(O_TRUNC | O_CREAT), 0)) < 0) >+ return -1; >+ debug("open successful\n"); >+ if (fstat(fd, &stb)) { >+ close(fd); >+ return -1; >+ } >+ debug("fstat successful\n"); >+ if (stb.st_uid != real_uid) { >+ switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) { >+ case O_RDONLY: >+ q = 0004; >+ break; >+ case O_WRONLY: >+ q = 0002; >+ break; >+ default: >+ q = 0006; >+ break; >+ } >+ if ((stb.st_mode & q) != q) { >+ debug1("secopen: permission denied (%03o)\n", stb.st_mode & 07777); >+ close(fd); >+ errno = EACCES; >+ return -1; >+ } >+ } >+ debug1("secopen ok - returning %d\n", fd); >+ return fd; >+#endif >+} >+ >+int >+printpipe(struct win *p, char *cmd) >+{ >+ int pi[2]; >+ if (pipe(pi)) { >+ WMsg(p, errno, "printing pipe"); >+ return -1; >+ } >+ switch (fork()) { >+ case -1: >+ WMsg(p, errno, "printing fork"); >+ return -1; >+ case 0: >+ display = p->w_pdisplay; >+ displays = 0; >+ ServerSocket = -1; > #ifdef DEBUG >- if (dfp && dfp != stderr) >- fclose(dfp); >+ if (dfp && dfp != stderr) >+ fclose(dfp); > #endif >- if (dup2(pi[0], 0) < 0) >- Panic(errno, "printpipe dup2"); >- closeallfiles(0); >- if (setgid(real_gid) || setuid(real_uid)) >- Panic(errno, "printpipe setuid"); >- eff_uid = real_uid; >- eff_gid = real_gid; >+ close(0); >+ dup(pi[0]); >+ closeallfiles(0); >+ if (setgid(real_gid) || setuid(real_uid)) >+ Panic(errno, "printpipe setuid"); >+ eff_uid = real_uid; >+ eff_gid = real_gid; > > #ifdef SIGPIPE >- signal(SIGPIPE, SIG_DFL); >+ signal(SIGPIPE, SIG_DFL); > #endif >- execl("/bin/sh", "sh", "-c", cmd, NULL); >- Panic(errno, "/bin/sh"); >- default: >- break; >- } >- close(pi[0]); >- return pi[1]; >-} >- >-int readpipe(char **cmdv) { >- int pi[2]; >- >- if (pipe(pi)) { >- Msg(errno, "pipe"); >- return -1; >- } >- >- fflush(NULL); >- switch (fork()) { >- case -1: >- Msg(errno, "fork"); >- return -1; >- case 0: >- displays = 0; >- ServerSocket = -1; >+ execl("/bin/sh", "sh", "-c", cmd, (char *)0); >+ Panic(errno, "/bin/sh"); >+ default: >+ break; >+ } >+ close(pi[0]); >+ return pi[1]; >+} >+ >+int >+readpipe(char **cmdv) >+{ >+ int pi[2]; >+ >+ if (pipe(pi)) { >+ Msg(errno, "pipe"); >+ return -1; >+ } >+ >+ switch (fork()) { >+ case -1: >+ Msg(errno, "fork"); >+ return -1; >+ case 0: >+ displays = 0; >+ ServerSocket = -1; > #ifdef DEBUG >- if (dfp && dfp != stderr) >- fclose(dfp); >+ if (dfp && dfp != stderr) >+ fclose(dfp); > #endif >- close(1); >- if (dup(pi[1]) != 1) { >- close(pi[1]); >- Panic(0, "dup"); >- } >- closeallfiles(1); >- >- if (setgid(real_gid) || setuid(real_uid)) { >- close(1); >- Panic(errno, "setuid/setgid"); >- } >- eff_uid = real_uid; >- eff_gid = real_gid; >+ close(1); >+ if (dup(pi[1]) != 1) { >+ close(pi[1]); >+ Panic(0, "dup"); >+ } >+ closeallfiles(1); >+ >+ if (setgid(real_gid) || setuid(real_uid)) { >+ close(1); >+ Panic(errno, "setuid/setgid"); >+ } >+ eff_uid = real_uid; >+ eff_gid = real_gid; > #ifdef SIGPIPE >- signal(SIGPIPE, SIG_DFL); >+ signal(SIGPIPE, SIG_DFL); > #endif >- execvp(*cmdv, cmdv); >- close(1); >- Panic(errno, "%s", *cmdv); >- default: >- break; >- } >- close(pi[1]); >- return pi[0]; >+ execvp(*cmdv, cmdv); >+ close(1); >+ Panic(errno, "%s", *cmdv); >+ default: >+ break; >+ } >+ close(pi[1]); >+ return pi[0]; > } >diff -ur screen.orig/HACKING screen/HACKING >--- screen.orig/HACKING 2023-06-01 14:58:17.228665002 +0300 >+++ screen/HACKING 2022-01-28 17:06:02.662611403 +0300 >@@ -4,7 +4,7 @@ > The local variable nr is set to an integer value representing the > command to be evaluated; for every command `foo', there is an > integer value RC_FOO for use as nr's value to represent it. Find >- the matching case label to follow procesing of the command. >+ the matching case label to follow processing of the command. > > The RC_FOO values are defined in comm.h, which is automatically > generated by comm.sh, based on the names of the commands >diff -ur screen.orig/help.c screen/help.c >--- screen.orig/help.c 2023-06-01 14:58:17.240665030 +0300 >+++ screen/help.c 2022-01-28 17:06:02.686611998 +0300 >@@ -111,8 +111,9 @@ > printf("\nError: "); > printf(message, arg); > printf("\n"); >+ exit(1); > } >- exit(1); >+ exit(0); > } > > /* Here come the help page routines */ >diff -ur screen.orig/INSTALL screen/INSTALL >--- screen.orig/INSTALL 2023-06-01 14:58:17.228665002 +0300 >+++ screen/INSTALL 2022-01-28 17:06:02.662611403 +0300 >@@ -40,7 +40,7 @@ > not. At least it must be on a filesystem that supports sockets/fifos. > SOCKDIR must not point into an AFS (Andrew File System) mounted directory. > If you are uncertain about your NFS implementation, use a UFS directory for >-SOCKDIR. Personally, I favour a users home directory and recommend the the >+SOCKDIR. Personally, I favour a user's home directory and recommend the the > /tmp/ area. > The path for ETCSCREENRC may also need to be adapted. > >@@ -58,7 +58,7 @@ > -------------------- > You may well run screen from your private binary directory and with a > private socket directory like $HOME/.screen. But to have a full featured >-screen and (from a users point of view) more secure pty's you should >+screen and (from a user's point of view) more secure pty's you should > consult a system administrator and discuss installing screen setuid-root > in some globally accessible directory like /usr/local/bin. > >@@ -94,7 +94,7 @@ > The files screenrc and etc/etcscreenrc are instructive samples that > demonstrate what can/should be done from your private .screenrc and from > $ETCSCREENRC -- do not just copy them. Read them. Look through the >-etcscreenrc file for system wide defaults that you like to set. e.g. >+etcscreenrc file for system wide defaults that you like to set, e.g. > autodetach off, startup_message off, vbell on, ... > Since version 3.2.15 the screenrc file syntax changed slightly. All rc files > from previous versions should be run through the 'newsyntax' script that comes >diff -ur screen.orig/.iscreenrc screen/.iscreenrc >--- screen.orig/.iscreenrc 2023-06-01 14:58:17.227665000 +0300 >+++ screen/.iscreenrc 2022-01-28 17:06:02.662611403 +0300 >@@ -17,7 +17,7 @@ > echo -n "booting screen" > > # let it flash, not horn! >-#vbell on # "vbell" don't work any longer, sorry. >+#vbell on # "vbell" doesn't work any longer, sorry. > #vbell_msg " Wuff, Wuff!! " # this is the default message > #bell "Bimmmel No. %" # sounds the bell and shows a message > >@@ -45,11 +45,11 @@ > # Printing in the leftmost column is not save. We express that fact as :LP@: > # > # Emacs tends to smear it's highlighted status bar across the screen, producing >-# ugly areas of bright background, if termcap is'nt perfectly sober. >+# ugly areas of bright background, if termcap isn't perfectly sober. > # Give a little :ms@: in the termcap, this may help. > # > # And who invented the initialisation for facit terminals? We tell him that >-# we non't like smooth scroll, by specifying :ti=\E[?l:. >+# we don't like smooth scroll, by specifying :ti=\E[?l:. > # \E[?3l 80 Zeichen > # \E[?3h 132 Zeichen > # LP Last column Printable >@@ -92,11 +92,11 @@ > # ICL 6402 testing: > termcap icl* G0:S0=\E$[start]:E0=\E%[end]:C0=j9k<l6m3n?q\:t7u=v;w>x5 GS=\E(0^O:GE=\E(B^O:G1=k:G2=l:G3=m:G4=j:GV=x:GH=q:GR=u:GL=t:GU=w:GD=v:GC=n > >-# Flowcontrol produces trouble. ^S und ^Q will never reach screen, as our >+# Flow control produces trouble. ^S und ^Q will never reach screen, as our > # terminals catch them locally. Who can explain that to me?: > #flow on|off|auto [interrupt] > >-# Long Lines get wrapped around (the back of your terminal). This is the >+# Long lines get wrapped around (the back of your terminal). This is the > # default for vt100. But now programs make different asumptions about your > # terminal. You may find two linefeeds where you'd expect one, or you may > # be confronted with a truncated line. Currently there is no fix, but pressing >@@ -106,10 +106,10 @@ > # the autoaka allows you to see the currently executing shell command in the > # window name field. To use that, your shell prompt must contain ^[k^[\ or > # you will see the string "(init)" as a name. >-# in my .cshrc I may use this for a wonderfull tcsh-prompt: >+# in my .cshrc I may use this for a wonderful tcsh-prompt: > # set prompt="%{^[k^[\\%}%h %c2(%m)%# " > # >-# defining a shellaka that contains a pipe-symbol (|) activites the >+# defining a shellaka that contains a pipe-symbol (|) activates the > # autoaka feature. To the left of that | you specify a constant part of > # your prompt as a trigger, to the right you may place a default string > # as in >@@ -121,8 +121,8 @@ > # ... now a little bit of key bindings > # In case we don't have write permission for /etc/utmp (no s-bit) > # we create even local windows via rlogin. -> Et voila: a utmp-slot >-# utmp-slots are strongly recomended to keep sccs and talk happy. >-# (thus we have ^A# or. ^Ac for windowcreation with or without utmp-slot.) >+# utmp-slots are strongly recommended to keep sccs and talk happy. >+# (thus we have ^A# or. ^Ac for window creation with or without utmp-slot.) > # but if we run suid-root, we produce all the rlogins with -ln, > # as nobody shall refer to these pty's. > bind '!' screen -ln -k faui41 rlogin faui41 >@@ -151,7 +151,7 @@ > # What happens, when you 'think emacs' and want to erase a whole > # line? You type ^A^K right? Under screen it should be ^Aa^K. But... > # killing the window would be a real punishment for a little mistyping. >-bind k #wow! I even amange to type ^Ak by accident. >+bind k #wow! I even mange to type ^Ak by accident. > #bind ^k > #bind K kill > >diff -ur screen.orig/layer.c screen/layer.c >--- screen.orig/layer.c 2023-06-01 14:58:17.241665032 +0300 >+++ screen/layer.c 2022-01-28 17:06:02.686611998 +0300 >@@ -876,26 +876,22 @@ > { > VA_LIST(ap) > char buf[MAXPATHLEN*2]; >- ssize_t len; >- const int errlen = err ? 100 : 0; >+ char *p = buf; > struct canvas *cv; > > VA_START(ap, fmt); > fmt = DoNLS(fmt); >- len = vsnprintf(buf, sizeof(buf) - errlen, fmt, VA_ARGS(ap)); >+ (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap)); > VA_END(ap); > >- if (len < 0) { >- strncpy(buf, fmt, sizeof(buf) - errlen); >- buf[sizeof(buf) - errlen - 1] = 0; >- } > if (err) { >- const char *strerr = strerror(err); >- if (strerr) { >- strncat(buf, ": ", 2); >- strncat(buf, strerr, errlen - 3); >- } >+ p += strlen(p); >+ *p++ = ':'; >+ *p++ = ' '; >+ strncpy(p, strerror(err), buf + sizeof(buf) - p - 1); >+ buf[sizeof(buf) - 1] = 0; > } >+ > debug2("LMsg('%s') (%#x);\n", buf, (unsigned int)flayer); > for (display = displays; display; display = display->d_next) { > for (cv = D_cvlist; cv; cv = cv->c_next) >@@ -943,7 +939,7 @@ > for (l = lay; l; l = l->l_next) { > if (l->l_layfn == &WinLf || l->l_layfn == &BlankLf) > break; >- debug1("- killing %p\n", l); >+ debug1("- killing %#x\n", l); > if (oldflayer == l) > oldflayer = 0; > for (cv = l->l_cvlist; cv; cv = ncv) { >@@ -977,7 +973,7 @@ > Msg(0, "No memory for layer struct"); > return -1; > } >- debug2("Entering new layer on top of %p: %p\n", (unsigned int)flayer, newlay); >+ debug2("Entering new layer on top of %#x: %#x\n", (unsigned int)flayer, newlay); > data = 0; > if (datasize) { > if ((data = calloc(1, datasize)) == 0) { >diff -ur screen.orig/layer.h screen/layer.h >--- screen.orig/layer.h 2023-06-01 14:58:17.241665032 +0300 >+++ screen/layer.h 2022-01-28 17:06:02.686611998 +0300 >@@ -106,7 +106,7 @@ > debug("LayCallUp\n"); \ > flayer = flayer->l_next; \ > oldcvlist = flayer->l_cvlist; \ >- debug1("oldcvlist: %p\n", oldcvlist); \ >+ debug1("oldcvlist: %x\n", oldcvlist); \ > flayer->l_cvlist = oldlay->l_cvlist; \ > for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext) \ > cv->c_layer = flayer; \ >diff -ur screen.orig/list_window.c screen/list_window.c >--- screen.orig/list_window.c 2023-06-01 14:58:17.242665034 +0300 >+++ screen/list_window.c 2022-01-28 17:06:02.686611998 +0300 >@@ -515,7 +515,7 @@ > > if (onblank) > { >- debug3("flayer %p %d %x\n", flayer, flayer->l_width, flayer->l_height); >+ debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height); > if (!display) > { > LMsg(0, "windowlist -b: display required"); >diff -ur screen.orig/loadav.c screen/loadav.c >--- screen.orig/loadav.c 2023-06-01 14:58:17.242665034 +0300 >+++ screen/loadav.c 2022-01-28 17:06:02.686611998 +0300 >@@ -85,13 +85,13 @@ > > if ((fp = secfopen("/proc/loadavg", "r")) == NULL) > return 0; >- s = fgets(buf, sizeof(buf), fp); >+ *buf = 0; >+ fgets(buf, sizeof(buf), fp); > fclose(fp); >- if (s == NULL) >- return 0; > /* can't use fscanf because the decimal point symbol depends on > * the locale but the kernel uses always '.'. > */ >+ s = buf; > for (i = 0; i < (LOADAV_NUM > 3 ? 3 : LOADAV_NUM); i++) > { > d = e = 0; >diff -ur screen.orig/Makefile.in screen/Makefile.in >--- screen.orig/Makefile.in 2023-06-01 14:58:17.228665002 +0300 >+++ screen/Makefile.in 2022-01-28 17:06:02.662611403 +0300 >@@ -67,7 +67,7 @@ > sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \ > list_display.c list_generic.c list_window.c > OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ >- search.o tty.o term.o window.o utmp.o loadav.o help.o \ >+ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ > termcap.o input.o attacher.o pty.o process.o display.o comm.o \ > kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \ > list_generic.o list_display.o list_window.o \ >@@ -91,15 +91,15 @@ > -if [ -f $(DESTDIR)$(bindir)/screen ] && [ ! -f $(DESTDIR)$(bindir)/screen.old ]; then mv $(DESTDIR)$(bindir)/screen $(DESTDIR)$(bindir)/screen.old; fi > rm -f $(DESTDIR)$(bindir)/screen > (cd $(DESTDIR)$(bindir) && ln -f -s $(SCREEN) screen) >- cp $(srcdir)/utf8encodings/?? $(RPM_BUILD_ROOT)$(SCREENENCODINGS) >+ cp $(srcdir)/utf8encodings/?? $(DESTDIR)$(SCREENENCODINGS) > > ############################################################################### > install: installdirs install_bin >- pushd doc ; $(MAKE) install; popd >- -(export TERMINFO="$(DESTDIR)$(datadir)/terminfo"; if [ -d "$$TERMINFO" ]; then \ >- tic ${srcdir}/terminfo/screeninfo.src; \ >- chmod 644 "$$TERMINFO"/s/screen*; \ >- fi) >+ cd doc ; $(MAKE) install >+ -if [ -d $(DESTDIR)/usr/lib/terminfo ]; then \ >+ PATH="$$PATH:/usr/5bin" tic ${srcdir}/terminfo/screeninfo.src; \ >+ chmod 644 $(DESTDIR)/usr/lib/terminfo/s/screen*; \ >+ fi > # Better do this by hand. E.g. under RCS... > # cat ${srcdir}/terminfo/screencap >> /etc/termcap > @echo "termcap entry (${srcdir}/terminfo/screencap) should be installed manually." >@@ -107,7 +107,7 @@ > > installdirs: > # Path leading to ETCSCREENRC and Socketdirectory not checked. >- $(srcdir)/etc/mkinstalldirs $(DESTDIR)$(bindir) $(RPM_BUILD_ROOT)$(SCREENENCODINGS) >+ $(srcdir)/etc/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(SCREENENCODINGS) > cd doc ; $(MAKE) installdirs > > uninstall: .version >diff -ur screen.orig/mark.c screen/mark.c >--- screen.orig/mark.c 2023-06-01 14:58:17.242665034 +0300 >+++ screen/mark.c 2022-01-28 17:06:02.690612097 +0300 >@@ -45,12 +45,12 @@ > * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > */ > >-static int is_letter __P((int)); >+static int is_letter __P((char)); > static void nextword __P((int *, int *, int, int)); > static int linestart __P((int)); > static int lineend __P((int)); >-static int rem __P((int, int , int , int , int , char *, int)); >-static int eq __P((int, int )); >+static int rem __P((int, int, int, int, int, char *, int)); >+static int eq __P((int, int)); > static int MarkScrollDownDisplay __P((int)); > static int MarkScrollUpDisplay __P((int)); > >@@ -69,76 +69,72 @@ > int pastefont = 1; > #endif > >-struct LayFuncs MarkLf = >-{ >- MarkProcess, >- MarkAbort, >- MarkRedisplayLine, >- DefClearLine, >- MarkRewrite, >- DefResize, >- DefRestore, >- 0 >+struct LayFuncs MarkLf = { >+ MarkProcess, >+ MarkAbort, >+ MarkRedisplayLine, >+ DefClearLine, >+ MarkRewrite, >+ DefResize, >+ DefRestore, >+ 0 > }; > >-int join_with_cr = 0; >+int join_with_cr = 0; > int compacthist = 0; > > unsigned char mark_key_tab[256]; /* this array must be initialised first! */ > > static struct markdata *markdata; > >- > /* > * VI like is_letter: 0 - whitespace > * 1 - letter >- * 2 - other >+ * 2 - other > */ >-static int is_letter(c) >-char c; >+static int >+is_letter(char c) > { >- if ((c >= 'a' && c <= 'z') || >- (c >= 'A' && c <= 'Z') || >- (c >= '0' && c <= '9') || >- c == '_' || c == '.' || >- c == '@' || c == ':' || >- c == '%' || c == '!' || >- c == '-' || c == '+') >+ if ((c >= 'a' && c <= 'z') || >+ (c >= 'A' && c <= 'Z') || >+ (c >= '0' && c <= '9') || >+ c == '_' || c == '.' || >+ c == '@' || c == ':' || >+ c == '%' || c == '!' || >+ c == '-' || c == '+') > /* thus we can catch email-addresses as a word :-) */ >- return 1; >- else if (c != ' ') >- return 2; >- return 0; >+ return 1; >+ else if (c != ' ') >+ return 2; >+ return 0; > } > > static int >-linestart(y) >-int y; >+linestart(int y) > { >- register int x; >- register unsigned char *i; >+ register int x; >+ register unsigned char *i; > >- for (x = markdata->left_mar, i = WIN(y)->image + x; x < fore->w_width - 1; x++) >- if (*i++ != ' ') >- break; >- if (x == fore->w_width - 1) >- x = markdata->left_mar; >- return x; >+ for (x = markdata->left_mar, i = WIN(y)->image + x; x < fore->w_width - 1; x++) >+ if (*i++ != ' ') >+ break; >+ if (x == fore->w_width - 1) >+ x = markdata->left_mar; >+ return x; > } > > static int >-lineend(y) >-int y; >+lineend(int y) > { >- register int x; >- register unsigned char *i; >+ register int x; >+ register unsigned char *i; > >- for (x = markdata->right_mar, i = WIN(y)->image + x; x >= 0; x--) >- if (*i-- != ' ') >- break; >- if (x < 0) >- x = markdata->left_mar; >- return x; >+ for (x = markdata->right_mar, i = WIN(y)->image + x; x >= 0; x--) >+ if (*i-- != ' ') >+ break; >+ if (x < 0) >+ x = markdata->left_mar; >+ return x; > } > > /* >@@ -149,50 +145,50 @@ > static int > nextchar(int *xp, int *yp, int direction, char target, int num) > { >- int width; /* width of the current window. */ >- int x; /* x coordinate of the current cursor position. */ >- int step; /* amount to increment x (+1 or -1) */ >- int adjust; /* Final adjustment of cursor position. */ >- char *displayed_line; /* Line in which search takes place. */ >- >- debug("nextchar\n"); >- >- x = *xp; >- step = 1; >- adjust = 0; >- width = fore->w_width; >- displayed_line = (char *)WIN(*yp) -> image; >- >- switch(direction) { >- case 't': >- adjust = -1; /* fall through */ >- case 'f': >- step = 1; >- break; >- case 'T': >- adjust = 1; /* fall through */ >- case 'F': >- step = -1; >- break; >- default: >- ASSERT(0); >- } >- >- x += step; >- >- debug1("ml->image = %s\n", displayed_line); >- debug2("num = %d, width = %d\n",num, width); >- debug2("x = %d target = %c\n", x, target ); >- >- for ( ;x>=0 && x <= width; x += step) { >- if (displayed_line[x] == target) { >- if (--num == 0) { >- *xp = x + adjust; >- return 0; >- } >- } >- } >- return -1; >+ int width; /* width of the current window. */ >+ int x; /* x coordinate of the current cursor position. */ >+ int step; /* amount to increment x (+1 or -1) */ >+ int adjust; /* Final adjustment of cursor position. */ >+ char *displayed_line; /* Line in which search takes place. */ >+ >+ debug("nextchar\n"); >+ >+ x = *xp; >+ step = 1; >+ adjust = 0; >+ width = fore->w_width; >+ displayed_line = (char *)WIN(*yp)->image; >+ >+ switch (direction) { >+ case 't': >+ adjust = -1; /* fall through */ >+ case 'f': >+ step = 1; >+ break; >+ case 'T': >+ adjust = 1; /* fall through */ >+ case 'F': >+ step = -1; >+ break; >+ default: >+ ASSERT(0); >+ } >+ >+ x += step; >+ >+ debug1("ml->image = %s\n", displayed_line); >+ debug2("num = %d, width = %d\n", num, width); >+ debug2("x = %d target = %c\n", x, target); >+ >+ for (; x >= 0 && x <= width; x += step) { >+ if (displayed_line[x] == target) { >+ if (--num == 0) { >+ *xp = x + adjust; >+ return 0; >+ } >+ } >+ } >+ return -1; > } > > /* >@@ -204,222 +200,201 @@ > * NW_BIG: match WORDs not words > */ > >-#define NW_BACK (1<<0) >-#define NW_ENDOFWORD (1<<1) >-#define NW_MUSTMOVE (1<<2) >-#define NW_BIG (1<<3) >- >- >+#define NW_BACK (1<<0) >+#define NW_ENDOFWORD (1<<1) >+#define NW_MUSTMOVE (1<<2) >+#define NW_BIG (1<<3) > > static void >-nextword(xp, yp, flags, num) >-int *xp, *yp, flags, num; >+nextword(int *xp, int *yp, int flags, int num) > { >- int xx = fore->w_width, yy = fore->w_histheight + fore->w_height; >- register int sx, oq, q, x, y; >- struct mline *ml; >- >- x = *xp; >- y = *yp; >- sx = (flags & NW_BACK) ? -1 : 1; >- if ((flags & NW_ENDOFWORD) && (flags & NW_MUSTMOVE)) >- x += sx; >- ml = WIN(y); >- for (oq = -1; ; x += sx, oq = q) >- { >- if (x >= xx || x < 0) >- q = 0; >- else if (flags & NW_BIG) >- q = ml->image[x] == ' '; >- else >- q = is_letter(ml->image[x]); >- if (oq >= 0 && oq != q) >- { >- if (oq == 0 || !(flags & NW_ENDOFWORD)) >- *xp = x; >- else >- *xp = x-sx; >- *yp = y; >- if ((!(flags & NW_ENDOFWORD) && q) || >- ((flags & NW_ENDOFWORD) && oq)) >- { >- if (--num <= 0) >- return; >- } >- } >- if (x == xx) >- { >- x = -1; >- if (++y >= yy) >- return; >- ml = WIN(y); >- } >- else if (x < 0) >- { >- x = xx; >- if (--y < 0) >- return; >- ml = WIN(y); >+ int xx = fore->w_width, yy = fore->w_histheight + fore->w_height; >+ register int sx, oq, q, x, y; >+ struct mline *ml; >+ >+ x = *xp; >+ y = *yp; >+ sx = (flags & NW_BACK) ? -1 : 1; >+ if ((flags & NW_ENDOFWORD) && (flags & NW_MUSTMOVE)) >+ x += sx; >+ ml = WIN(y); >+ for (oq = -1;; x += sx, oq = q) { >+ if (x >= xx || x < 0) >+ q = 0; >+ else if (flags & NW_BIG) >+ q = ml->image[x] == ' '; >+ else >+ q = is_letter(ml->image[x]); >+ >+ if (oq >= 0 && oq != q) { >+ if (oq == 0 || !(flags & NW_ENDOFWORD)) >+ *xp = x; >+ else >+ *xp = x - sx; >+ *yp = y; >+ >+ if ((!(flags & NW_ENDOFWORD) && q) || ((flags & NW_ENDOFWORD) && oq)) { >+ if (--num <= 0) >+ return; >+ } >+ } >+ >+ if (x == xx) { >+ x = -1; >+ if (++y >= yy) >+ return; >+ ml = WIN(y); >+ } else if (x < 0) { >+ x = xx; >+ if (--y < 0) >+ return; >+ ml = WIN(y); >+ } > } >- } > } > >- > /* > * y1, y2 are WIN coordinates > * >- * redisplay: 0 - just copy >- * 1 - redisplay + copy >- * 2 - count + copy, don't redisplay >+ * redisplay: 0 - just copy >+ * 1 - redisplay + copy >+ * 2 - count + copy, don't redisplay > */ > > static int >-rem(x1, y1, x2, y2, redisplay, pt, yend) >-int x1, y1, x2, y2, redisplay, yend; >-char *pt; >+rem(int x1, int y1, int x2, int y2, int redisplay, char *pt, int yend) > { >- int i, j, from, to, ry, c; >- int l = 0; >- unsigned char *im; >- struct mline *ml; >+ int i, j, from, to, ry, c; >+ int l = 0; >+ unsigned char *im; >+ struct mline *ml; > #ifdef FONT >- int cf, cfx, font; >- unsigned char *fo, *fox; >+ int cf, cfx, font; >+ unsigned char *fo, *fox; > #endif > >- markdata->second = 0; >- if (y2 < y1 || ((y2 == y1) && (x2 < x1))) >- { >- i = y2; >- y2 = y1; >- y1 = i; >- i = x2; >- x2 = x1; >- x1 = i; >- } >- ry = y1 - markdata->hist_offset; >- >- i = y1; >- if (redisplay != 2 && pt == 0 && ry <0) >- { >- i -= ry; >- ry = 0; >- } >- for (; i <= y2; i++, ry++) >- { >- if (redisplay != 2 && pt == 0 && ry > yend) >- break; >- ml = WIN(i); >- from = (i == y1) ? x1 : 0; >- if (from < markdata->left_mar) >- from = markdata->left_mar; >- for (to = fore->w_width, im = ml->image + to; to >= 0; to--) >- if (*im-- != ' ') >- break; >- if (i == y2 && x2 < to) >- to = x2; >- if (to > markdata->right_mar) >- to = markdata->right_mar; >- if (redisplay == 1 && from <= to && ry >=0 && ry <= yend) >- MarkRedisplayLine(ry, from, to, 0); >- if (redisplay != 2 && pt == 0) /* don't count/copy */ >- continue; >- j = from; >+ markdata->second = 0; >+ if (y2 < y1 || ((y2 == y1) && (x2 < x1))) { >+ i = y2; >+ y2 = y1; >+ y1 = i; >+ i = x2; >+ x2 = x1; >+ x1 = i; >+ } >+ ry = y1 - markdata->hist_offset; >+ >+ i = y1; >+ if (redisplay != 2 && pt == 0 && ry < 0) { >+ i -= ry; >+ ry = 0; >+ } >+ for (; i <= y2; i++, ry++) { >+ if (redisplay != 2 && pt == 0 && ry > yend) >+ break; >+ ml = WIN(i); >+ from = (i == y1) ? x1 : 0; >+ >+ if (from < markdata->left_mar) >+ from = markdata->left_mar; >+ for (to = fore->w_width, im = ml->image + to; to >= 0; to--) >+ if (*im-- != ' ') >+ break; >+ if (i == y2 && x2 < to) >+ to = x2; >+ if (to > markdata->right_mar) >+ to = markdata->right_mar; >+ if (redisplay == 1 && from <= to && ry >= 0 && ry <= yend) >+ MarkRedisplayLine(ry, from, to, 0); >+ if (redisplay != 2 && pt == 0) /* don't count/copy */ >+ continue; >+ j = from; > #ifdef DW_CHARS >- if (dw_right(ml, j, fore->w_encoding)) >- j--; >+ if (dw_right(ml, j, fore->w_encoding)) >+ j--; > #endif >- im = ml->image + j; >+ im = ml->image + j; > #ifdef FONT >- fo = ml->font + j; >- fox = ml->fontx + j; >- font = ASCII; >+ fo = ml->font + j; >+ fox = ml->fontx + j; >+ font = ASCII; > #endif >- for (; j <= to; j++) >- { >- c = (unsigned char)*im++; >+ for (; j <= to; j++) { >+ c = (unsigned char)*im++; > #ifdef FONT >- cf = (unsigned char)*fo++; >- cfx = (unsigned char)*fox++; >+ cf = (unsigned char)*fo++; >+ cfx = (unsigned char)*fox++; > # ifdef UTF8 >- if (fore->w_encoding == UTF8) >- { >- c |= cf << 8 | cfx << 16; >- if (c == UCS_HIDDEN) >- continue; >- c = ToUtf8_comb(pt, c); >- l += c; >- if (pt) >- pt += c; >- continue; >- } >+ if (fore->w_encoding == UTF8) { >+ c |= cf << 8 | cfx << 16; >+ if (c == UCS_HIDDEN) >+ continue; >+ c = ToUtf8_comb(pt, c); >+ l += c; >+ if (pt) >+ pt += c; >+ continue; >+ } > # endif > # ifdef DW_CHARS >- if (is_dw_font(cf)) >- { >- c = c << 8 | (unsigned char)*im++; >- fo++; >- j++; >- } >+ if (is_dw_font(cf)) { >+ c = c << 8 | (unsigned char)*im++; >+ fo++; >+ j++; >+ } > # endif >- if (pastefont) >- { >- c = EncodeChar(pt, c | cf << 16, fore->w_encoding, &font); >- l += c; >- if (pt) >- pt += c; >- continue; >- } >+ if (pastefont) { >+ c = EncodeChar(pt, c | cf << 16, fore->w_encoding, &font); >+ l += c; >+ if (pt) >+ pt += c; >+ continue; >+ } > #endif /* FONT */ >- if (pt) >- *pt++ = c; >- l++; >- } >+ if (pt) >+ *pt++ = c; >+ l++; >+ } > #ifdef FONT >- if (pastefont && font != ASCII) >- { >- if (pt) >- { >- strcpy(pt, "\033(B"); >- pt += 3; >- } >- l += 3; >- } >+ if (pastefont && font != ASCII) { >+ if (pt) { >+ strcpy(pt, "\033(B"); >+ pt += 3; >+ } >+ l += 3; >+ } > #endif >- if (i != y2 && (to != fore->w_width - 1 || ml->image[to + 1] == ' ')) >- { >- /* >- * this code defines, what glues lines together >- */ >- switch (markdata->nonl) >- { >- case 0: /* lines separated by newlines */ >- if (pt) >- *pt++ = '\r'; >- l++; >- if (join_with_cr) >- { >- if (pt) >- *pt++ = '\n'; >- l++; >+ if (i != y2 && (to != fore->w_width - 1 || ml->image[to + 1] == ' ')) { >+ /* >+ * this code defines, what glues lines together >+ */ >+ switch (markdata->nonl) { >+ case 0: /* lines separated by newlines */ >+ if (pt) >+ *pt++ = '\r'; >+ l++; >+ if (join_with_cr) { >+ if (pt) >+ *pt++ = '\n'; >+ l++; >+ } >+ break; >+ case 1: /* nothing to separate lines */ >+ break; >+ case 2: /* lines separated by blanks */ >+ if (pt) >+ *pt++ = ' '; >+ l++; >+ break; >+ case 3: /* seperate by comma, for csh junkies */ >+ if (pt) >+ *pt++ = ','; >+ l++; >+ break; >+ } > } >- break; >- case 1: /* nothing to separate lines */ >- break; >- case 2: /* lines separated by blanks */ >- if (pt) >- *pt++ = ' '; >- l++; >- break; >- case 3: /* seperate by comma, for csh junkies */ >- if (pt) >- *pt++ = ','; >- l++; >- break; >- } > } >- } >- return l; >+ return l; > } > > /* Check if two chars are identical. All digits are treated >@@ -427,67 +402,63 @@ > */ > > static int >-eq(a, b) >-int a, b; >+eq(int a, int b) > { >- if (a == b) >- return 1; >- if (a == 0 || b == 0) >- return 1; >- if (a <= '9' && a >= '0' && b <= '9' && b >= '0') >- return 1; >- return 0; >+ if (a == b) >+ return 1; >+ if (a == 0 || b == 0) >+ return 1; >+ if (a <= '9' && a >= '0' && b <= '9' && b >= '0') >+ return 1; >+ return 0; > } > >- > /**********************************************************************/ > > int > GetHistory() /* return value 1 if copybuffer changed */ > { >- int i = 0, q = 0, xx, yy, x, y; >- unsigned char *linep; >- struct mline *ml; >- >- ASSERT(display && fore); >- x = fore->w_x; >- if (x >= fore->w_width) >- x = fore->w_width - 1; >- y = fore->w_y + fore->w_histheight; >- debug2("cursor is at x=%d, y=%d\n", x, y); >- ml = WIN(y); >- for (xx = x - 1, linep = ml->image + xx; xx >= 0; xx--) >- if ((q = *linep--) != ' ' ) >- break; >- debug3("%c at (%d,%d)\n", q, xx, y); >- for (yy = y - 1; yy >= 0; yy--) >- { >- ml = WIN(yy); >- linep = ml->image; >- if (xx < 0 || eq(linep[xx], q)) >- { /* line is matching... */ >- for (i = fore->w_width - 1, linep += i; i >= x; i--) >- if (*linep-- != ' ') >- break; >- if (i >= x) >- break; >- } >- } >- if (yy < 0) >- return 0; >- if (D_user->u_plop.buf) >- UserFreeCopyBuffer(D_user); >- if ((D_user->u_plop.buf = (char *)malloc((unsigned) (i - x + 2))) == NULL) >- { >- LMsg(0, "Not enough memory... Sorry."); >- return 0; >- } >- bcopy((char *)linep - i + x + 1, D_user->u_plop.buf, i - x + 1); >- D_user->u_plop.len = i - x + 1; >+ int i = 0, q = 0, xx, yy, x, y; >+ unsigned char *linep; >+ struct mline *ml; >+ >+ ASSERT(display && fore); >+ x = fore->w_x; >+ if (x >= fore->w_width) >+ x = fore->w_width - 1; >+ y = fore->w_y + fore->w_histheight; >+ debug2("cursor is at x=%d, y=%d\n", x, y); >+ ml = WIN(y); >+ for (xx = x - 1, linep = ml->image + xx; xx >= 0; xx--) >+ if ((q = *linep--) != ' ') >+ break; >+ debug3("%c at (%d,%d)\n", q, xx, y); >+ for (yy = y - 1; yy >= 0; yy--) { >+ ml = WIN(yy); >+ linep = ml->image; >+ if (xx < 0 || eq(linep[xx], q)) { /* line is matching... */ >+ for (i = fore->w_width - 1, linep += i; i >= x; i--) >+ if (*linep-- != ' ') >+ break; >+ if (i >= x) >+ break; >+ } >+ } >+ if (yy < 0) >+ return 0; >+ if (D_user->u_plop.buf) >+ UserFreeCopyBuffer(D_user); >+ if ((D_user->u_plop.buf = (char *)malloc((unsigned)(i - x + 2))) == >+ NULL) { >+ LMsg(0, "Not enough memory... Sorry."); >+ return 0; >+ } >+ bcopy((char *)linep - i + x + 1, D_user->u_plop.buf, i - x + 1); >+ D_user->u_plop.len = i - x + 1; > #ifdef ENCODINGS >- D_user->u_plop.enc = fore->w_encoding; >+ D_user->u_plop.enc = fore->w_encoding; > #endif >- return 1; >+ return 1; > } > > /**********************************************************************/ >@@ -496,98 +467,88 @@ > void > MarkRoutine() > { >- int x, y; >+ int x, y; > >- ASSERT(fore && display && D_user); >+ ASSERT(fore && display && D_user); > >- debug2("MarkRoutine called: fore nr %d, display %s\n", >- fore->w_number, D_usertty); >+ debug2("MarkRoutine called: fore nr %d, display %s\n", fore->w_number, D_usertty); > >- if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1)) >- return; >- flayer->l_encoding = fore->w_encoding; >- flayer->l_mode = 1; >- markdata = (struct markdata *)flayer->l_data; >- markdata->md_user = D_user; /* XXX: Correct? */ >- markdata->md_window = fore; >- markdata->second = 0; >- markdata->rep_cnt = 0; >- markdata->append_mode = 0; >- markdata->write_buffer = 0; >- markdata->nonl = 0; >- markdata->left_mar = 0; >- markdata->right_mar = fore->w_width - 1; >- markdata->hist_offset = fore->w_histheight; >- x = fore->w_x; >- y = D2W(fore->w_y); >- if (x >= fore->w_width) >- x = fore->w_width - 1; >- >- LGotoPos(flayer, x, W2D(y)); >- LMsg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)", >- x + 1, W2D(y + 1), fore->w_histheight, fore->w_width, fore->w_height); >- markdata->cx = markdata->x1 = x; >- markdata->cy = markdata->y1 = y; >- flayer->l_x = x; >- flayer->l_y = W2D(y); >+ if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1)) >+ return; >+ flayer->l_encoding = fore->w_encoding; >+ flayer->l_mode = 1; >+ markdata = (struct markdata *)flayer->l_data; >+ markdata->md_user = D_user; /* XXX: Correct? */ >+ markdata->md_window = fore; >+ markdata->second = 0; >+ markdata->rep_cnt = 0; >+ markdata->append_mode = 0; >+ markdata->write_buffer = 0; >+ markdata->nonl = 0; >+ markdata->left_mar = 0; >+ markdata->right_mar = fore->w_width - 1; >+ markdata->hist_offset = fore->w_histheight; >+ x = fore->w_x; >+ y = D2W(fore->w_y); >+ if (x >= fore->w_width) >+ x = fore->w_width - 1; >+ >+ LGotoPos(flayer, x, W2D(y)); >+ LMsg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)", x + 1, W2D(y + 1), fore->w_histheight, fore->w_width, fore->w_height); >+ markdata->cx = markdata->x1 = x; >+ markdata->cy = markdata->y1 = y; >+ flayer->l_x = x; >+ flayer->l_y = W2D(y); > } > > static void >-MarkProcess(inbufp,inlenp) >-char **inbufp; >-int *inlenp; >+MarkProcess(char **inbufp, int *inlenp) > { >- char *inbuf, *pt; >- int inlen; >- int cx, cy, x2, y2, j, yend; >- int newcopylen = 0, od; >- int in_mark; >- int rep_cnt; >- struct acluser *md_user; >+ char *inbuf, *pt; >+ int inlen; >+ int cx, cy, x2, y2, j, yend; >+ int newcopylen = 0, od; >+ int in_mark; >+ int rep_cnt; >+ struct acluser *md_user; > > /* > char *extrap = 0, extrabuf[100]; > */ > >- markdata = (struct markdata *)flayer->l_data; >- fore = markdata->md_window; >- md_user = markdata->md_user; >- if (inbufp == 0) >- { >- MarkAbort(); >- return; >- } >- >- LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >- inbuf= *inbufp; >- inlen= *inlenp; >- pt = inbuf; >- in_mark = 1; >- while (in_mark && (inlen /* || extrap */)) >- { >- unsigned char ch = (unsigned char )*pt++; >- inlen--; >- if (flayer->l_mouseevent.start) >- { >- int r = LayProcessMouse(flayer, ch); >- if (r == -1) >- LayProcessMouseSwitch(flayer, 0); >- else >- { >- if (r) >- ch = 0222; >- else >- continue; >- } >- } >- od = mark_key_tab[(int)ch]; >- rep_cnt = markdata->rep_cnt; >- if (od >= '0' && od <= '9' && !markdata->f_cmd.flag) >- { >- if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0)) >- { >- markdata->rep_cnt = 10 * rep_cnt + od - '0'; >- continue; >+ markdata = (struct markdata *)flayer->l_data; >+ fore = markdata->md_window; >+ md_user = markdata->md_user; >+ if (inbufp == 0) { >+ MarkAbort(); >+ return; >+ } >+ >+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >+ inbuf = *inbufp; >+ inlen = *inlenp; >+ pt = inbuf; >+ in_mark = 1; >+ while (in_mark && (inlen /* || extrap */)) { >+ unsigned char ch = (unsigned char)*pt++; >+ inlen--; >+ if (flayer->l_mouseevent.start) { >+ int r = LayProcessMouse(flayer, ch); >+ if (r == -1) >+ LayProcessMouseSwitch(flayer, 0); >+ else { >+ if (r) >+ ch = 0222; >+ else >+ continue; >+ } >+ } >+ od = mark_key_tab[(int)ch]; >+ rep_cnt = markdata->rep_cnt; >+ if (od >= '0' && od <= '9' && !markdata->f_cmd.flag) { >+ if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0)) { >+ markdata->rep_cnt = 10 * rep_cnt + od - '0'; >+ continue; > /* > * Now what is that 1001 here? Well, we have a screen with > * 25 * 80 = 2000 characters. Movement is at most across the full >@@ -598,32 +559,31 @@ > * words, as they should be more advanced. jw. > * Oh, wrong. We still give even the experienced user a factor of ten. > */ >- } >- } >- cx = markdata->cx; >- cy = markdata->cy; >+ } >+ } >+ cx = markdata->cx; >+ cy = markdata->cy; > >- if (markdata -> f_cmd.flag) { >- debug2("searching for %c:%d\n",od,rep_cnt); >- markdata->f_cmd.flag = 0; >- markdata->rep_cnt = 0; >- >- if (isgraph (od)) { >- markdata->f_cmd.target = od; >- rep_cnt = (rep_cnt) ? rep_cnt : 1; >- nextchar(&cx, &cy, markdata->f_cmd.direction, od, rep_cnt ); >- revto(cx, cy); >- continue; >- } >- } >+ if (markdata->f_cmd.flag) { >+ debug2("searching for %c:%d\n", od, rep_cnt); >+ markdata->f_cmd.flag = 0; >+ markdata->rep_cnt = 0; >+ >+ if (isgraph(od)) { >+ markdata->f_cmd.target = od; >+ rep_cnt = (rep_cnt) ? rep_cnt : 1; >+ nextchar(&cx, &cy, markdata->f_cmd.direction, od, rep_cnt); >+ revto(cx, cy); >+ continue; >+ } >+ } > > processchar: >- switch (od) >- { >- case 'f': /* fall through */ >- case 'F': /* fall through */ >- case 't': /* fall through */ >- case 'T': /* fall through */ >+ switch (od) { >+ case 'f': /* fall through */ >+ case 'F': /* fall through */ >+ case 't': /* fall through */ >+ case 'T': /* fall through */ > /* > * Set f_cmd to do a search on the next key stroke. > * If we break, rep_cnt will be reset, so we >@@ -632,905 +592,857 @@ > * break here so later followon code will be > * hit. > */ >- markdata->f_cmd.flag = 1; >- markdata->f_cmd.direction = od; >- debug("entering char search\n"); >- continue; >- case ';': >- case ',': >- if (!markdata->f_cmd.target) >- break; >- if (!rep_cnt) >- rep_cnt = 1; >- nextchar(&cx, &cy, >- od == ';' ? markdata->f_cmd.direction : (markdata->f_cmd.direction ^ 0x20), >- markdata->f_cmd.target, rep_cnt ); >- revto(cx, cy); >- break; >- case 'o': >- case 'x': >- if (!markdata->second) >- break; >- markdata->cx = markdata->x1; >- markdata->cy = markdata->y1; >- markdata->x1 = cx; >- markdata->y1 = cy; >- revto(markdata->cx, markdata->cy); >- break; >- case '\014': /* CTRL-L Redisplay */ >- Redisplay(0); >- LGotoPos(flayer, cx, W2D(cy)); >- break; >- case 0202: /* M-C-b */ >- case '\010': /* CTRL-H Backspace */ >- case 'h': >- if (rep_cnt == 0) >- rep_cnt = 1; >- revto(cx - rep_cnt, cy); >- break; >- case 0216: /* M-C-p */ >- case '\016': /* CTRL-N */ >- case 'j': >- if (rep_cnt == 0) >- rep_cnt = 1; >- revto(cx, cy + rep_cnt); >- break; >- case '+': >- if (rep_cnt == 0) >- rep_cnt = 1; >- j = cy + rep_cnt; >- if (j > fore->w_histheight + fore->w_height - 1) >- j = fore->w_histheight + fore->w_height - 1; >- revto(linestart(j), j); >- break; >- case '-': >- if (rep_cnt == 0) >- rep_cnt = 1; >- cy -= rep_cnt; >- if (cy < 0) >- cy = 0; >- revto(linestart(cy), cy); >- break; >- case '^': >- revto(linestart(cy), cy); >- break; >- case '\n': >- revto(markdata->left_mar, cy + 1); >- break; >- case 0220: /* M-C-p */ >- case '\020': /* CTRL-P */ >- case 'k': >- if (rep_cnt == 0) >- rep_cnt = 1; >- revto(cx, cy - rep_cnt); >- break; >- case 0206: /* M-C-f */ >- case 'l': >- if (rep_cnt == 0) >- rep_cnt = 1; >- revto(cx + rep_cnt, cy); >- break; >- case '\001': /* CTRL-A from tcsh/emacs */ >- case '0': >- revto(markdata->left_mar, cy); >- break; >- case '\004': /* CTRL-D down half screen */ >- if (rep_cnt == 0) >- rep_cnt = (fore->w_height + 1) >> 1; >- revto_line(cx, cy + rep_cnt, W2D(cy)); >- break; >- case '$': >- revto(lineend(cy), cy); >- break; >- case '\022': /* CTRL-R emacs style backwards search */ >- ISearch(-1); >- in_mark = 0; >- break; >- case '\023': /* CTRL-S emacs style search */ >- ISearch(1); >- in_mark = 0; >- break; >- case '\025': /* CTRL-U up half screen */ >- if (rep_cnt == 0) >- rep_cnt = (fore->w_height + 1) >> 1; >- revto_line(cx, cy - rep_cnt, W2D(cy)); >- break; >- case '\007': /* CTRL-G show cursorpos */ >- if (markdata->left_mar == 0 && markdata->right_mar == fore->w_width - 1) >- LMsg(0, "Column %d Line %d(+%d)", cx+1, W2D(cy)+1, >- markdata->hist_offset); >- else >- LMsg(0, "Column %d(%d..%d) Line %d(+%d)", cx+1, >- markdata->left_mar+1, markdata->right_mar+1, W2D(cy)+1, markdata->hist_offset); >- break; >- case '\002': /* CTRL-B back one page */ >- if (rep_cnt == 0) >- rep_cnt = 1; >- rep_cnt *= fore->w_height; >- revto(cx, cy - rep_cnt); >- break; >- case '\006': /* CTRL-F forward one page */ >- if (rep_cnt == 0) >- rep_cnt = 1; >- rep_cnt *= fore->w_height; >- revto(cx, cy + rep_cnt); >- break; >- case '\005': /* CTRL-E scroll up */ >- if (rep_cnt == 0) >- rep_cnt = 1; >- rep_cnt = MarkScrollUpDisplay(rep_cnt); >- if (cy < D2W(0)) >- revto(cx, D2W(0)); >- else >- LGotoPos(flayer, cx, W2D(cy)); >- break; >- case '\031': /* CTRL-Y scroll down */ >- if (rep_cnt == 0) >- rep_cnt = 1; >- rep_cnt = MarkScrollDownDisplay(rep_cnt); >- if (cy > D2W(fore->w_height-1)) >- revto(cx, D2W(fore->w_height-1)); >- else >- LGotoPos(flayer, cx, W2D(cy)); >- break; >- case '@': >+ markdata->f_cmd.flag = 1; >+ markdata->f_cmd.direction = od; >+ debug("entering char search\n"); >+ continue; >+ case ';': >+ case ',': >+ if (!markdata->f_cmd.target) >+ break; >+ if (!rep_cnt) >+ rep_cnt = 1; >+ nextchar(&cx, >+ &cy, >+ od == ';' ? markdata->f_cmd.direction : (markdata->f_cmd.direction ^ 0x20), >+ markdata->f_cmd.target, >+ rep_cnt); >+ revto(cx, cy); >+ break; >+ case 'o': >+ case 'x': >+ if (!markdata->second) >+ break; >+ markdata->cx = markdata->x1; >+ markdata->cy = markdata->y1; >+ markdata->x1 = cx; >+ markdata->y1 = cy; >+ revto(markdata->cx, markdata->cy); >+ break; >+ case '\014': /* CTRL-L Redisplay */ >+ Redisplay(0); >+ LGotoPos(flayer, cx, W2D(cy)); >+ break; >+ case 0202: /* M-C-b */ >+ case '\010': /* CTRL-H Backspace */ >+ case 'h': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ revto(cx - rep_cnt, cy); >+ break; >+ case 0216: /* M-C-p */ >+ case '\016': /* CTRL-N */ >+ case 'j': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ revto(cx, cy + rep_cnt); >+ break; >+ case '+': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ j = cy + rep_cnt; >+ if (j > fore->w_histheight + fore->w_height - 1) >+ j = fore->w_histheight + fore->w_height - 1; >+ revto(linestart(j), j); >+ break; >+ case '-': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ cy -= rep_cnt; >+ if (cy < 0) >+ cy = 0; >+ revto(linestart(cy), cy); >+ break; >+ case '^': >+ revto(linestart(cy), cy); >+ break; >+ case '\n': >+ revto(markdata->left_mar, cy + 1); >+ break; >+ case 0220: /* M-C-p */ >+ case '\020': /* CTRL-P */ >+ case 'k': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ revto(cx, cy - rep_cnt); >+ break; >+ case 0206: /* M-C-f */ >+ case 'l': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ revto(cx + rep_cnt, cy); >+ break; >+ case '\001': /* CTRL-A from tcsh/emacs */ >+ case '0': >+ revto(markdata->left_mar, cy); >+ break; >+ case '\004': /* CTRL-D down half screen */ >+ if (rep_cnt == 0) >+ rep_cnt = (fore->w_height + 1) >> 1; >+ revto_line(cx, cy + rep_cnt, W2D(cy)); >+ break; >+ case '$': >+ revto(lineend(cy), cy); >+ break; >+ case '\022': /* CTRL-R emacs style backwards search */ >+ ISearch(-1); >+ in_mark = 0; >+ break; >+ case '\023': /* CTRL-S emacs style search */ >+ ISearch(1); >+ in_mark = 0; >+ break; >+ case '\025': /* CTRL-U up half screen */ >+ if (rep_cnt == 0) >+ rep_cnt = (fore->w_height + 1) >> 1; >+ revto_line(cx, cy - rep_cnt, W2D(cy)); >+ break; >+ case '\007': /* CTRL-G show cursorpos */ >+ if (markdata->left_mar == 0 && markdata->right_mar == fore->w_width - 1) >+ LMsg(0, "Column %d Line %d(+%d)", cx + 1, W2D(cy) + 1, markdata->hist_offset); >+ else >+ LMsg(0, "Column %d(%d..%d) Line %d(+%d)", >+ cx + 1, markdata->left_mar + 1, >+ markdata->right_mar + 1, W2D(cy) + 1, >+ markdata->hist_offset); >+ break; >+ case '\002': /* CTRL-B back one page */ >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ rep_cnt *= fore->w_height; >+ revto(cx, cy - rep_cnt); >+ break; >+ case '\006': /* CTRL-F forward one page */ >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ rep_cnt *= fore->w_height; >+ revto(cx, cy + rep_cnt); >+ break; >+ case '\005': /* CTRL-E scroll up */ >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ rep_cnt = MarkScrollUpDisplay(rep_cnt); >+ if (cy < D2W(0)) >+ revto(cx, D2W(0)); >+ else >+ LGotoPos(flayer, cx, W2D(cy)); >+ break; >+ case '\031': /* CTRL-Y scroll down */ >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ rep_cnt = MarkScrollDownDisplay(rep_cnt); >+ if (cy > D2W(fore->w_height - 1)) >+ revto(cx, D2W(fore->w_height - 1)); >+ else >+ LGotoPos(flayer, cx, W2D(cy)); >+ break; >+ case '@': > /* it may be useful to have a key that does nothing */ >- break; >- case '%': >+ break; >+ case '%': > /* rep_cnt is a percentage for the history buffer */ >- if (rep_cnt < 0) >- rep_cnt = 0; >- if (rep_cnt > 100) >- rep_cnt = 100; >- revto_line(markdata->left_mar, >- fore->w_histheight - fore->w_scrollback_height + >- (int)(rep_cnt * (fore->w_scrollback_height + fore->w_height) / 100.0), >- (fore->w_height - 1) / 2); >- break; >- case 0201: >- case 'g': >- rep_cnt = 1; >+ if (rep_cnt < 0) >+ rep_cnt = 0; >+ if (rep_cnt > 100) >+ rep_cnt = 100; >+ >+ revto_line(markdata->left_mar, >+ fore->w_histheight - fore->w_scrollback_height + >+ (int)(rep_cnt * (fore->w_scrollback_height + >+ fore->w_height) / 100.0), (fore->w_height - 1) / 2); >+ break; >+ case 0201: >+ case 'g': >+ rep_cnt = 1; > /* FALLTHROUGH */ >- case 0205: >- case 'G': >+ case 0205: >+ case 'G': > /* rep_cnt is here the WIN line number */ >- if (rep_cnt == 0) >- rep_cnt = fore->w_histheight + fore->w_height; >- revto_line(markdata->left_mar, --rep_cnt, (fore->w_height - 1) / 2); >- break; >- case 'H': >- revto(markdata->left_mar, D2W(0)); >- break; >- case 'M': >- revto(markdata->left_mar, D2W((fore->w_height - 1) / 2)); >- break; >- case 'L': >- revto(markdata->left_mar, D2W(fore->w_height - 1)); >- break; >- case '|': >- revto(--rep_cnt, cy); >- break; >- case 'w': >- if (rep_cnt == 0) >- rep_cnt = 1; >- nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt); >- revto(cx, cy); >- break; >- case 'e': >- case 'E': >- if (rep_cnt == 0) >- rep_cnt = 1; >- nextword(&cx, &cy, NW_ENDOFWORD|NW_MUSTMOVE | (od == 'E' ? NW_BIG : 0), rep_cnt); >- revto(cx, cy); >- break; >- case 'b': >- case 'B': >- if (rep_cnt == 0) >- rep_cnt = 1; >- nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD|NW_MUSTMOVE | (od == 'B' ? NW_BIG : 0), rep_cnt); >- revto(cx, cy); >- break; >- case 'a': >- markdata->append_mode = 1 - markdata->append_mode; >- debug1("append mode %d--\n", markdata->append_mode); >- LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend"); >- break; >- case 'v': >- case 'V': >+ if (rep_cnt == 0) >+ rep_cnt = fore->w_histheight + fore->w_height; >+ revto_line(markdata->left_mar, --rep_cnt, (fore->w_height - 1) / 2); >+ break; >+ case 'H': >+ revto(markdata->left_mar, D2W(0)); >+ break; >+ case 'M': >+ revto(markdata->left_mar, D2W((fore->w_height - 1) / 2)); >+ break; >+ case 'L': >+ revto(markdata->left_mar, D2W(fore->w_height - 1)); >+ break; >+ case '|': >+ revto(--rep_cnt, cy); >+ break; >+ case 'w': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt); >+ revto(cx, cy); >+ break; >+ case 'e': >+ case 'E': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ nextword(&cx, &cy, NW_ENDOFWORD|NW_MUSTMOVE | (od == 'E' ? NW_BIG : 0), rep_cnt); >+ revto(cx, cy); >+ break; >+ case 'b': >+ case 'B': >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD|NW_MUSTMOVE | (od == 'B' ? NW_BIG : 0), rep_cnt); >+ revto(cx, cy); >+ break; >+ case 'a': >+ markdata->append_mode = 1 - markdata->append_mode; >+ debug1("append mode %d--\n", markdata->append_mode); >+ LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend"); >+ break; >+ case 'v': >+ case 'V': > /* this sets start column to column 9 for VI :set nu users */ >- if (markdata->left_mar == 8) >- rep_cnt = 1; >- else >- rep_cnt = 9; >+ if (markdata->left_mar == 8) >+ rep_cnt = 1; >+ else >+ rep_cnt = 9; > /* FALLTHROUGH */ >- case 'c': >- case 'C': >+ case 'c': >+ case 'C': > /* set start column (c) and end column (C) */ >- if (markdata->second) >- { >- rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, fore->w_height-1); /* Hack */ >- markdata->second = 1; /* rem turns off second */ >- } >- rep_cnt--; >- if (rep_cnt < 0) >- rep_cnt = cx; >- if (od != 'C') >- { >- markdata->left_mar = rep_cnt; >- if (markdata->left_mar > markdata->right_mar) >- markdata->left_mar = markdata->right_mar; >- } >- else >- { >- markdata->right_mar = rep_cnt; >- if (markdata->left_mar > markdata->right_mar) >- markdata->right_mar = markdata->left_mar; >- } >- if (markdata->second) >- { >- markdata->cx = markdata->x1; markdata->cy = markdata->y1; >- revto(cx, cy); >- } >- if (od == 'v' || od == 'V') >- LMsg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu"); >- break; >- case 'J': >- /* how do you join lines in VI ? */ >- markdata->nonl = (markdata->nonl + 1) % 4; >- switch (markdata->nonl) >- { >- case 0: >- if (join_with_cr) >- LMsg(0, "Multiple lines (CR/LF)"); >- else >- LMsg(0, "Multiple lines (LF)"); >- break; >- case 1: >- LMsg(0, "Lines joined"); >- break; >- case 2: >- LMsg(0, "Lines joined with blanks"); >- break; >- case 3: >- LMsg(0, "Lines joined with comma"); >- break; >- } >- break; >- case '/': >- Search(1); >- in_mark = 0; >- break; >- case '?': >- Search(-1); >- in_mark = 0; >- break; >- case 'n': >- Search(0); >- break; >- case 'N': >- markdata->isdir = -markdata->isdir; >- Search(0); >- markdata->isdir = -markdata->isdir; >- break; >- case 'y': >- case 'Y': >- if (markdata->second == 0) >- { >- revto(linestart(cy), cy); >- markdata->second++; >- cx = markdata->x1 = markdata->cx; >- cy = markdata->y1 = markdata->cy; >- } >- if (--rep_cnt > 0) >- revto(cx, cy + rep_cnt); >- revto(lineend(markdata->cy), markdata->cy); >- if (od == 'y') >- break; >+ if (markdata->second) { >+ rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, fore->w_height - 1); /* Hack */ >+ markdata->second = 1; /* rem turns off second */ >+ } >+ rep_cnt--; >+ if (rep_cnt < 0) >+ rep_cnt = cx; >+ if (od != 'C') { >+ markdata->left_mar = rep_cnt; >+ if (markdata->left_mar > markdata->right_mar) >+ markdata->left_mar = markdata->right_mar; >+ } else { >+ markdata->right_mar = rep_cnt; >+ if (markdata->left_mar > markdata->right_mar) >+ markdata->right_mar = markdata->left_mar; >+ } >+ if (markdata->second) { >+ markdata->cx = markdata->x1; >+ markdata->cy = markdata->y1; >+ revto(cx, cy); >+ } >+ if (od == 'v' || od == 'V') >+ LMsg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu"); >+ break; >+ case 'J': >+ /* how do you join lines in VI ? */ >+ markdata->nonl = (markdata->nonl + 1) % 4; >+ switch (markdata->nonl) { >+ case 0: >+ if (join_with_cr) >+ LMsg(0, "Multiple lines (CR/LF)"); >+ else >+ LMsg(0, "Multiple lines (LF)"); >+ break; >+ case 1: >+ LMsg(0, "Lines joined"); >+ break; >+ case 2: >+ LMsg(0, "Lines joined with blanks"); >+ break; >+ case 3: >+ LMsg(0, "Lines joined with comma"); >+ break; >+ } >+ break; >+ case '/': >+ Search(1); >+ in_mark = 0; >+ break; >+ case '?': >+ Search(-1); >+ in_mark = 0; >+ break; >+ case 'n': >+ Search(0); >+ break; >+ case 'N': >+ markdata->isdir = -markdata->isdir; >+ Search(0); >+ markdata->isdir = -markdata->isdir; >+ break; >+ case 'y': >+ case 'Y': >+ if (markdata->second == 0) { >+ revto(linestart(cy), cy); >+ markdata->second++; >+ cx = markdata->x1 = markdata->cx; >+ cy = markdata->y1 = markdata->cy; >+ } >+ if (--rep_cnt > 0) >+ revto(cx, cy + rep_cnt); >+ revto(lineend(markdata->cy), markdata->cy); >+ if (od == 'y') >+ break; > /* FALLTHROUGH */ >- case 'W': >- if (od == 'W') >- { >- if (rep_cnt == 0) >- rep_cnt = 1; >- if (!markdata->second) >- { >- nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD, 1); >- revto(cx, cy); >- markdata->second++; >- cx = markdata->x1 = markdata->cx; >- cy = markdata->y1 = markdata->cy; >- } >- nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt); >- revto(cx, cy); >- } >- cx = markdata->cx; >- cy = markdata->cy; >+ case 'W': >+ if (od == 'W') { >+ if (rep_cnt == 0) >+ rep_cnt = 1; >+ if (!markdata->second) { >+ nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD, 1); >+ revto(cx, cy); >+ markdata->second++; >+ cx = markdata->x1 = markdata->cx; >+ cy = markdata->y1 = markdata->cy; >+ } >+ nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt); >+ revto(cx, cy); >+ } >+ cx = markdata->cx; >+ cy = markdata->cy; > /* FALLTHROUGH */ >- case 'A': >- if (od == 'A') >- markdata->append_mode = 1; >+ case 'A': >+ if (od == 'A') >+ markdata->append_mode = 1; > /* FALLTHROUGH */ >- case '>': >- if (od == '>') >- markdata->write_buffer = 1; >+ case '>': >+ if (od == '>') >+ markdata->write_buffer = 1; > /* FALLTHROUGH */ >- case ' ': >- case '\r': >- if (!markdata->second) >- { >- markdata->second++; >- markdata->x1 = cx; >- markdata->y1 = cy; >- revto(cx, cy); >- LMsg(0, "First mark set - Column %d Line %d", cx+1, W2D(cy)+1); >- break; >- } >- else >- { >- int append_mode = markdata->append_mode; >- int write_buffer = markdata->write_buffer; >- >- x2 = cx; >- y2 = cy; >- newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */ >- if (md_user->u_plop.buf && !append_mode) >- UserFreeCopyBuffer(md_user); >- yend = fore->w_height - 1; >- if (fore->w_histheight - markdata->hist_offset < fore->w_height) >- { >- markdata->second = 0; >- yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset); >- } >- if (newcopylen > 0) >- { >+ case ' ': >+ case '\r': >+ if (!markdata->second) { >+ markdata->second++; >+ markdata->x1 = cx; >+ markdata->y1 = cy; >+ revto(cx, cy); >+ LMsg(0, "First mark set - Column %d Line %d", cx + 1, W2D(cy) + 1); >+ break; >+ } else { >+ int append_mode = markdata->append_mode; >+ int write_buffer = markdata->write_buffer; >+ >+ x2 = cx; >+ y2 = cy; >+ newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */ >+ if (md_user->u_plop.buf && !append_mode) >+ UserFreeCopyBuffer(md_user); >+ yend = fore->w_height - 1; >+ if (fore->w_histheight - markdata->hist_offset < fore->w_height) { >+ markdata->second = 0; >+ yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset); >+ } >+ if (newcopylen > 0) { > /* the +3 below is for : cr + lf + \0 */ >- if (md_user->u_plop.buf) >- md_user->u_plop.buf = realloc(md_user->u_plop.buf, >- (unsigned) (md_user->u_plop.len + newcopylen + 3)); >- else >- { >- md_user->u_plop.len = 0; >- md_user->u_plop.buf = malloc((unsigned) (newcopylen + 3)); >- } >- if (!md_user->u_plop.buf) >- { >- MarkAbort(); >- in_mark = 0; >- LMsg(0, "Not enough memory... Sorry."); >- md_user->u_plop.len = 0; >- md_user->u_plop.buf = 0; >- break; >- } >- if (append_mode) >- { >- switch (markdata->nonl) >- { >+ if (md_user->u_plop.buf) >+ md_user->u_plop.buf = realloc(md_user->u_plop.buf, (unsigned)(md_user->u_plop.len + newcopylen + 3)); >+ else { >+ md_user->u_plop.len = 0; >+ md_user->u_plop.buf = malloc((unsigned)(newcopylen + 3)); >+ } >+ if (!md_user->u_plop.buf) { >+ MarkAbort(); >+ in_mark = 0; >+ LMsg(0, "Not enough memory... Sorry."); >+ md_user->u_plop.len = 0; >+ md_user->u_plop.buf = 0; >+ break; >+ } >+ if (append_mode) { >+ switch (markdata->nonl) { > /* > * this code defines, what glues lines together > */ >- case 0: >- if (join_with_cr) >- { >- md_user->u_plop.buf[md_user->u_plop.len] = '\r'; >- md_user->u_plop.len++; >- } >- md_user->u_plop.buf[md_user->u_plop.len] = '\n'; >- md_user->u_plop.len++; >- break; >- case 1: >- break; >- case 2: >- md_user->u_plop.buf[md_user->u_plop.len] = ' '; >- md_user->u_plop.len++; >- break; >- case 3: >- md_user->u_plop.buf[md_user->u_plop.len] = ','; >- md_user->u_plop.len++; >- break; >- } >- } >- md_user->u_plop.len += rem(markdata->x1, markdata->y1, x2, y2, >- markdata->hist_offset == fore->w_histheight, >- md_user->u_plop.buf + md_user->u_plop.len, yend); >+ case 0: >+ if (join_with_cr) { >+ md_user->u_plop.buf[md_user->u_plop.len] = '\r'; >+ md_user->u_plop.len++; >+ } >+ md_user->u_plop.buf[md_user->u_plop.len] = '\n'; >+ md_user->u_plop.len++; >+ break; >+ case 1: >+ break; >+ case 2: >+ md_user->u_plop.buf[md_user->u_plop.len] = ' '; >+ md_user->u_plop.len++; >+ break; >+ case 3: >+ md_user->u_plop.buf[md_user->u_plop.len] = ','; >+ md_user->u_plop.len++; >+ break; >+ } >+ } >+ md_user->u_plop.len += rem(markdata->x1, >+ markdata->y1, >+ x2, >+ y2, >+ markdata->hist_offset == fore->w_histheight, >+ md_user->u_plop.buf + md_user->u_plop.len, >+ yend); > #ifdef ENCODINGS >- md_user->u_plop.enc = fore->w_encoding; >+ md_user->u_plop.enc = fore->w_encoding; > #endif >- } >- if (markdata->hist_offset != fore->w_histheight) >- { >- LAY_CALL_UP(LRefreshAll(flayer, 0)); >- } >- ExitOverlayPage(); >- WindowChanged(fore, 'P'); >- if (append_mode) >- LMsg(0, "Appended %d characters to buffer", >- newcopylen); >- else >- LMsg(0, "Copied %d characters into buffer", md_user->u_plop.len); >- if (write_buffer) >- WriteFile(md_user, (char *)0, DUMP_EXCHANGE); >- in_mark = 0; >- break; >- } >- >- case 0222: >- if (flayer->l_mouseevent.start) >- { >- int button = flayer->l_mouseevent.buffer[0]; >- if (button == 'a') >- { >- /* Scroll down */ >- od = 'j'; >- } >- else if (button == '`') >- { >- /* Scroll up */ >- od = 'k'; >- } >- else if (button == ' ') >- { >- /* Left click */ >- cx = flayer->l_mouseevent.buffer[1]; >- cy = D2W(flayer->l_mouseevent.buffer[2]); >- revto(cx, cy); >- od = ' '; >- } >- else >- od = 0; >- LayProcessMouseSwitch(flayer, 0); >- if (od) >- goto processchar; >- } >- else >- LayProcessMouseSwitch(flayer, 1); >- break; >+ } >+ if (markdata->hist_offset != fore->w_histheight) { >+ LAY_CALL_UP(LRefreshAll(flayer, 0)); >+ } >+ ExitOverlayPage(); >+ WindowChanged(fore, 'P'); >+ >+ if (append_mode) >+ LMsg(0, "Appended %d characters to buffer", newcopylen); >+ else >+ LMsg(0, "Copied %d characters into buffer", md_user->u_plop.len); >+ >+ if (write_buffer) >+ WriteFile(md_user, (char *)0, DUMP_EXCHANGE); >+ in_mark = 0; >+ break; >+ } > >- default: >- MarkAbort(); >- LMsg(0, "Copy mode aborted"); >- in_mark = 0; >- break; >- } >- if (in_mark) /* markdata may be freed */ >- markdata->rep_cnt = 0; >- } >- if (in_mark) >- { >- flayer->l_x = markdata->cx; >- flayer->l_y = W2D(markdata->cy); >- } >- *inbufp = pt; >- *inlenp = inlen; >+ case 0222: >+ if (flayer->l_mouseevent.start) { >+ int button = flayer->l_mouseevent.buffer[0]; >+ if (button == 'a') { >+ /* Scroll down */ >+ od = 'j'; >+ } else if (button == '`') { >+ /* Scroll up */ >+ od = 'k'; >+ } else if (button == ' ') { >+ /* Left click */ >+ cx = flayer->l_mouseevent.buffer[1]; >+ cy = D2W(flayer->l_mouseevent.buffer[2]); >+ revto(cx, cy); >+ od = ' '; >+ } else >+ od = 0; >+ LayProcessMouseSwitch(flayer, 0); >+ if (od) >+ goto processchar; >+ } else >+ LayProcessMouseSwitch(flayer, 1); >+ break; >+ >+ default: >+ MarkAbort(); >+ LMsg(0, "Copy mode aborted"); >+ in_mark = 0; >+ break; >+ } >+ if (in_mark) /* markdata may be freed */ >+ markdata->rep_cnt = 0; >+ } >+ if (in_mark) { >+ flayer->l_x = markdata->cx; >+ flayer->l_y = W2D(markdata->cy); >+ } >+ *inbufp = pt; >+ *inlenp = inlen; > } > >-void revto(tx, ty) >-int tx, ty; >+void >+revto(int tx, int ty) > { >- revto_line(tx, ty, -1); >+ revto_line(tx, ty, -1); > } > > /* tx, ty: WINDOW, line: DISPLAY */ >-void revto_line(tx, ty, line) >-int tx, ty, line; >+void >+revto_line(int tx, int ty, int line) > { >- int fx, fy; >- int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0; >- int ystart = 0, yend = fore->w_height-1; >- int i, ry; >- unsigned char *wi; >- struct mline *ml; >- struct mchar mc; >- >- if (tx < 0) >- tx = 0; >- else if (tx > fore->w_width - 1) >- tx = fore->w_width -1; >- if (ty < fore->w_histheight - fore->w_scrollback_height) >- ty = fore->w_histheight - fore->w_scrollback_height; >- else if (ty > fore->w_histheight + fore->w_height - 1) >- ty = fore->w_histheight + fore->w_height - 1; >+ int fx, fy; >+ int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0; >+ int ystart = 0, yend = fore->w_height - 1; >+ int i, ry; >+ unsigned char *wi; >+ struct mline *ml; >+ struct mchar mc; >+ >+ if (tx < 0) >+ tx = 0; >+ else if (tx > fore->w_width - 1) >+ tx = fore->w_width - 1; >+ if (ty < fore->w_histheight - fore->w_scrollback_height) >+ ty = fore->w_histheight - fore->w_scrollback_height; >+ else if (ty > fore->w_histheight + fore->w_height - 1) >+ ty = fore->w_histheight + fore->w_height - 1; > >- fx = markdata->cx; fy = markdata->cy; >+ fx = markdata->cx; >+ fy = markdata->cy; > > #ifdef DW_CHARS >- /* don't just move inside of a kanji, the user wants to see something */ >- ml = WIN(ty); >- if (ty == fy && fx + 1 == tx && dw_right(ml, tx, fore->w_encoding) && tx < D_width - 1) >- tx++; >- if (ty == fy && fx - 1 == tx && dw_right(ml, fx, fore->w_encoding) && tx) >- tx--; >+ /* don't just move inside of a kanji, the user wants to see something */ >+ ml = WIN(ty); >+ if (ty == fy && fx + 1 == tx && dw_right(ml, tx, fore->w_encoding) && tx < D_width - 1) >+ tx++; >+ if (ty == fy && fx - 1 == tx && dw_right(ml, fx, fore->w_encoding) && tx) >+ tx--; > #endif > >- markdata->cx = tx; markdata->cy = ty; >+ markdata->cx = tx; >+ markdata->cy = ty; > > /* > * if we go to a position that is currently offscreen > * then scroll the screen > */ >- i = 0; >- if (line >= 0 && line < fore->w_height) >- i = W2D(ty) - line; >- else if (ty < markdata->hist_offset) >- i = ty - markdata->hist_offset; >- else if (ty > markdata->hist_offset + (fore->w_height - 1)) >- i = ty - markdata->hist_offset - (fore->w_height - 1); >- if (i > 0) >- yend -= MarkScrollUpDisplay(i); >- else if (i < 0) >- ystart += MarkScrollDownDisplay(-i); >- >- if (markdata->second == 0) >- { >- flayer->l_x = tx; >- flayer->l_y = W2D(ty); >- LGotoPos(flayer, tx, W2D(ty)); >- return; >- } >- >- qq = markdata->x1 + markdata->y1 * fore->w_width; >- ff = fx + fy * fore->w_width; /* "from" offset in WIN coords */ >- tt = tx + ty * fore->w_width; /* "to" offset in WIN coords*/ >- >- if (ff > tt) >- { >- st = tt; en = ff; >- x = tx; y = ty; >- } >- else >- { >- st = ff; en = tt; >- x = fx; y = fy; >- } >- if (st > qq) >- { >- st++; >- x++; >- } >- if (en < qq) >- en--; >- if (tt > qq) >- { >- revst = qq; reven = tt; >- } >- else >- { >- revst = tt; reven = qq; >- } >- ry = y - markdata->hist_offset; >- if (ry < ystart) >- { >- y += (ystart - ry); >- x = 0; >- st = y * fore->w_width; >- ry = ystart; >- } >- ml = WIN(y); >- for (t = st; t <= en; t++, x++) >- { >- if (x >= fore->w_width) >- { >- x = 0; >- y++, ry++; >- ml = WIN(y); >- } >- if (ry > yend) >- break; >- if (t == st || x == 0) >- { >- wi = ml->image + fore->w_width; >- for (ce = fore->w_width; ce >= 0; ce--, wi--) >- if (*wi != ' ') >- break; >+ i = 0; >+ >+ if (line >= 0 && line < fore->w_height) >+ i = W2D(ty) - line; >+ else if (ty < markdata->hist_offset) >+ i = ty - markdata->hist_offset; >+ else if (ty > markdata->hist_offset + (fore->w_height - 1)) >+ i = ty - markdata->hist_offset - (fore->w_height - 1); >+ >+ if (i > 0) >+ yend -= MarkScrollUpDisplay(i); >+ else if (i < 0) >+ ystart += MarkScrollDownDisplay(-i); >+ >+ if (markdata->second == 0) { >+ flayer->l_x = tx; >+ flayer->l_y = W2D(ty); >+ LGotoPos(flayer, tx, W2D(ty)); >+ return; >+ } >+ >+ qq = markdata->x1 + markdata->y1 * fore->w_width; >+ ff = fx + fy * fore->w_width; /* "from" offset in WIN coords */ >+ tt = tx + ty * fore->w_width; /* "to" offset in WIN coords*/ >+ >+ if (ff > tt) { >+ st = tt; >+ en = ff; >+ x = tx; >+ y = ty; >+ } else { >+ st = ff; >+ en = tt; >+ x = fx; >+ y = fy; >+ } >+ >+ if (st > qq) { >+ st++; >+ x++; > } >- if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar) >- { >+ >+ if (en < qq) >+ en--; >+ >+ if (tt > qq) { >+ revst = qq; >+ reven = tt; >+ } else { >+ revst = tt; >+ reven = qq; >+ } >+ ry = y - markdata->hist_offset; >+ >+ if (ry < ystart) { >+ y += (ystart - ry); >+ x = 0; >+ st = y * fore->w_width; >+ ry = ystart; >+ } >+ ml = WIN(y); >+ >+ for (t = st; t <= en; t++, x++) { >+ if (x >= fore->w_width) { >+ x = 0; >+ y++, ry++; >+ ml = WIN(y); >+ } >+ if (ry > yend) >+ break; >+ if (t == st || x == 0) { >+ wi = ml->image + fore->w_width; >+ for (ce = fore->w_width; ce >= 0; ce--, wi--) >+ if (*wi != ' ') >+ break; >+ } >+ >+ if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar) { > #ifdef DW_CHARS >- if (dw_right(ml, x, fore->w_encoding)) >- { >- if (t == revst) >- revst--; >- t--; >- x--; >- } >+ if (dw_right(ml, x, fore->w_encoding)) { >+ if (t == revst) >+ revst--; >+ t--; >+ x--; >+ } > #endif >- if (t >= revst && t <= reven) >- { >- mc = mchar_so; >+ if (t >= revst && t <= reven) { >+ mc = mchar_so; > #ifdef FONT >- if (pastefont) >- { >- mc.font = ml->font[x]; >- mc.fontx = ml->fontx[x]; >- } >+ if (pastefont) { >+ mc.font = ml->font[x]; >+ mc.fontx = ml->fontx[x]; >+ } > #endif >- mc.image = ml->image[x]; >- } >- else >- copy_mline2mchar(&mc, ml, x); >+ mc.image = ml->image[x]; >+ } else >+ copy_mline2mchar(&mc, ml, x); > #ifdef DW_CHARS >- if (dw_left(ml, x, fore->w_encoding)) >- { >- mc.mbcs = ml->image[x + 1]; >- LPutChar(flayer, &mc, x, W2D(y)); >- t++; >- } >+ if (dw_left(ml, x, fore->w_encoding)) { >+ mc.mbcs = ml->image[x + 1]; >+ LPutChar(flayer, &mc, x, W2D(y)); >+ t++; >+ } > #endif >- LPutChar(flayer, &mc, x, W2D(y)); >+ LPutChar(flayer, &mc, x, W2D(y)); > #ifdef DW_CHARS >- if (dw_left(ml, x, fore->w_encoding)) >- x++; >+ if (dw_left(ml, x, fore->w_encoding)) >+ x++; > #endif >+ } > } >- } >- flayer->l_x = tx; >- flayer->l_y = W2D(ty); >- LGotoPos(flayer, tx, W2D(ty)); >+ flayer->l_x = tx; >+ flayer->l_y = W2D(ty); >+ LGotoPos(flayer, tx, W2D(ty)); > } > > static void > MarkAbort() > { >- int yend, redisp; >+ int yend, redisp; > >- debug("MarkAbort\n"); >- markdata = (struct markdata *)flayer->l_data; >- fore = markdata->md_window; >- yend = fore->w_height - 1; >- redisp = markdata->second; >- if (fore->w_histheight - markdata->hist_offset < fore->w_height) >- { >- markdata->second = 0; >- yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset); >- } >- if (markdata->hist_offset != fore->w_histheight) >- { >- LAY_CALL_UP(LRefreshAll(flayer, 0)); >- } >- else >- { >- rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend); >- } >- ExitOverlayPage(); >- WindowChanged(fore, 'P'); >+ debug("MarkAbort\n"); >+ markdata = (struct markdata *)flayer->l_data; >+ fore = markdata->md_window; >+ yend = fore->w_height - 1; >+ redisp = markdata->second; >+ if (fore->w_histheight - markdata->hist_offset < fore->w_height) { >+ markdata->second = 0; >+ yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset); >+ } >+ if (markdata->hist_offset != fore->w_histheight) { >+ LAY_CALL_UP(LRefreshAll(flayer, 0)); >+ } else { >+ rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend); >+ } >+ ExitOverlayPage(); >+ WindowChanged(fore, 'P'); > } > >- > static void >-MarkRedisplayLine(y, xs, xe, isblank) >-int y; /* NOTE: y is in DISPLAY coords system! */ >-int xs, xe; >-int isblank; >+MarkRedisplayLine(int y, int xs, int xe, int isblank) /* NOTE: y is in DISPLAY coords system! */ > { >- int wy, x, i, rm; >- int sta, sto, cp; /* NOTE: these 3 are in WINDOW coords system */ >- unsigned char *wi; >- struct mline *ml; >- struct mchar mchar_marked; >- >- if (y < 0) /* No special full page handling */ >- return; >- >- markdata = (struct markdata *)flayer->l_data; >- fore = markdata->md_window; >- >- mchar_marked = mchar_so; >- >- wy = D2W(y); >- ml = WIN(wy); >- >- if (markdata->second == 0) >- { >- if (dw_right(ml, xs, fore->w_encoding) && xs > 0) >- xs--; >- if (dw_left(ml, xe, fore->w_encoding) && xe < fore->w_width - 1) >- xe++; >- if (xs == 0 && y > 0 && wy > 0 && WIN(wy - 1)->image[flayer->l_width] == 0) >- LCDisplayLineWrap(flayer, ml, y, xs, xe, isblank); >- else >- LCDisplayLine(flayer, ml, y, xs, xe, isblank); >- return; >- } >- >- sta = markdata->y1 * fore->w_width + markdata->x1; >- sto = markdata->cy * fore->w_width + markdata->cx; >- if (sta > sto) >- { >- i=sta; sta=sto; sto=i; >- } >- cp = wy * fore->w_width + xs; >- >- rm = markdata->right_mar; >- for (x = fore->w_width, wi = ml->image + fore->w_width; x >= 0; x--, wi--) >- if (*wi != ' ') >- break; >- if (x < rm) >- rm = x; >- >- for (x = xs; x <= xe; x++, cp++) >- if (cp >= sta && x >= markdata->left_mar) >- break; >+ int wy, x, i, rm; >+ int sta, sto, cp; /* NOTE: these 3 are in WINDOW coords system */ >+ unsigned char *wi; >+ struct mline *ml; >+ struct mchar mchar_marked; >+ >+ if (y < 0) /* No special full page handling */ >+ return; >+ >+ markdata = (struct markdata *)flayer->l_data; >+ fore = markdata->md_window; >+ >+ mchar_marked = mchar_so; >+ >+ wy = D2W(y); >+ ml = WIN(wy); >+ >+ if (markdata->second == 0) { >+ if (dw_right(ml, xs, fore->w_encoding) && xs > 0) >+ xs--; >+ if (dw_left(ml, xe, fore->w_encoding) && xe < fore->w_width - 1) >+ xe++; >+ if (xs == 0 && y > 0 && wy > 0 && WIN(wy - 1)->image[flayer->l_width] == 0) >+ LCDisplayLineWrap(flayer, ml, y, xs, xe, isblank); >+ else >+ LCDisplayLine(flayer, ml, y, xs, xe, isblank); >+ return; >+ } >+ >+ sta = markdata->y1 * fore->w_width + markdata->x1; >+ sto = markdata->cy * fore->w_width + markdata->cx; >+ if (sta > sto) { >+ i = sta; >+ sta = sto; >+ sto = i; >+ } >+ cp = wy * fore->w_width + xs; >+ >+ rm = markdata->right_mar; >+ for (x = fore->w_width, wi = ml->image + fore->w_width; x >= 0; x--, wi--) >+ if (*wi != ' ') >+ break; >+ if (x < rm) >+ rm = x; >+ >+ for (x = xs; x <= xe; x++, cp++) >+ if (cp >= sta && x >= markdata->left_mar) >+ break; > #ifdef DW_CHARS >- if (dw_right(ml, x, fore->w_encoding)) >- x--; >+ if (dw_right(ml, x, fore->w_encoding)) >+ x--; > #endif >- if (x > xs) >- LCDisplayLine(flayer, ml, y, xs, x - 1, isblank); >- for (; x <= xe; x++, cp++) >- { >- if (cp > sto || x > rm) >- break; >+ if (x > xs) >+ LCDisplayLine(flayer, ml, y, xs, x - 1, isblank); >+ for (; x <= xe; x++, cp++) { >+ if (cp > sto || x > rm) >+ break; > #ifdef FONT >- if (pastefont) >- { >- mchar_marked.font = ml->font[x]; >- mchar_marked.fontx = ml->fontx[x]; >- } >+ if (pastefont) { >+ mchar_marked.font = ml->font[x]; >+ mchar_marked.fontx = ml->fontx[x]; >+ } > #endif >- mchar_marked.image = ml->image[x]; >+ mchar_marked.image = ml->image[x]; > #ifdef DW_CHARS >- mchar_marked.mbcs = 0; >- if (dw_left(ml, x, fore->w_encoding)) >- { >- mchar_marked.mbcs = ml->image[x + 1]; >- cp++; >- } >+ mchar_marked.mbcs = 0; >+ if (dw_left(ml, x, fore->w_encoding)) { >+ mchar_marked.mbcs = ml->image[x + 1]; >+ cp++; >+ } > #endif >- LPutChar(flayer, &mchar_marked, x, y); >+ LPutChar(flayer, &mchar_marked, x, y); > #ifdef DW_CHARS >- if (dw_left(ml, x, fore->w_encoding)) >- x++; >+ if (dw_left(ml, x, fore->w_encoding)) >+ x++; > #endif >- } >- if (x <= xe) >- LCDisplayLine(flayer, ml, y, x, xe, isblank); >+ } >+ if (x <= xe) >+ LCDisplayLine(flayer, ml, y, x, xe, isblank); > } > >- > /* > * This ugly routine is to speed up GotoPos() > */ > static int >-MarkRewrite(ry, xs, xe, rend, doit) >-int ry, xs, xe, doit; >-struct mchar *rend; >+MarkRewrite(int ry, int xs, int xe, struct mchar *rend, int doit) > { >- int dx, x, y, st, en, t, rm; >- unsigned char *i; >- struct mline *ml; >- struct mchar mchar_marked; >- >- mchar_marked = mchar_so; >- >- debug3("MarkRewrite %d, %d-%d\n", ry, xs, xe); >- markdata = (struct markdata *)flayer->l_data; >- fore = markdata->md_window; >- y = D2W(ry); >- ml = WIN(y); >+ int dx, x, y, st, en, t, rm; >+ unsigned char *i; >+ struct mline *ml; >+ struct mchar mchar_marked; >+ >+ mchar_marked = mchar_so; >+ >+ debug3("MarkRewrite %d, %d-%d\n", ry, xs, xe); >+ markdata = (struct markdata *)flayer->l_data; >+ fore = markdata->md_window; >+ y = D2W(ry); >+ ml = WIN(y); > #ifdef UTF8 >- if (fore->w_encoding && fore->w_encoding != UTF8 && D_encoding == UTF8 && ContainsSpecialDeffont(ml, xs, xe, fore->w_encoding)) >- return EXPENSIVE; >+ if (fore->w_encoding && fore->w_encoding != UTF8 && D_encoding == UTF8 && ContainsSpecialDeffont(ml, xs, xe, fore->w_encoding)) >+ return EXPENSIVE; > #endif >- dx = xe - xs + 1; >- if (doit) >- { >- i = ml->image + xs; >- while (dx--) >- PUTCHAR(*i++); >- return 0; >- } >- >- if (markdata->second == 0) >- st = en = -1; >- else >- { >- st = markdata->y1 * fore->w_width + markdata->x1; >- en = markdata->cy * fore->w_width + markdata->cx; >- if (st > en) >- { >- t = st; st = en; en = t; >- } >- } >- t = y * fore->w_width + xs; >- for (rm = fore->w_width, i = ml->image + fore->w_width; rm >= 0; rm--) >- if (*i-- != ' ') >- break; >- if (rm > markdata->right_mar) >- rm = markdata->right_mar; >- x = xs; >- while (dx--) >- { >- if (t >= st && t <= en && x >= markdata->left_mar && x <= rm) >- { >+ dx = xe - xs + 1; >+ if (doit) { >+ i = ml->image + xs; >+ while (dx--) >+ PUTCHAR(*i++); >+ return 0; >+ } >+ >+ if (markdata->second == 0) >+ st = en = -1; >+ else { >+ st = markdata->y1 * fore->w_width + markdata->x1; >+ en = markdata->cy * fore->w_width + markdata->cx; >+ if (st > en) { >+ t = st; >+ st = en; >+ en = t; >+ } >+ } >+ t = y * fore->w_width + xs; >+ for (rm = fore->w_width, i = ml->image + fore->w_width; rm >= 0; rm--) >+ if (*i-- != ' ') >+ break; >+ if (rm > markdata->right_mar) >+ rm = markdata->right_mar; >+ x = xs; >+ while (dx--) { >+ if (t >= st && t <= en && x >= markdata->left_mar && x <= rm) { > #ifdef FONT >- if (pastefont) >- { >- mchar_marked.font = ml->font[x]; >- mchar_marked.fontx = ml->fontx[x]; >- } >+ if (pastefont) { >+ mchar_marked.font = ml->font[x]; >+ mchar_marked.fontx = ml->fontx[x]; >+ } > #endif >- rend->image = mchar_marked.image; >- if (!cmp_mchar(rend, &mchar_marked)) >- return EXPENSIVE; >- } >- else >- { >- rend->image = ml->image[x]; >- if (!cmp_mchar_mline(rend, ml, x)) >- return EXPENSIVE; >- } >- x++; >- } >- return xe - xs + 1; >+ rend->image = mchar_marked.image; >+ if (!cmp_mchar(rend, &mchar_marked)) >+ return EXPENSIVE; >+ } else { >+ rend->image = ml->image[x]; >+ if (!cmp_mchar_mline(rend, ml, x)) >+ return EXPENSIVE; >+ } >+ x++; >+ } >+ return xe - xs + 1; > } > >- > /* > * scroll the screen contents up/down. > */ >-static int MarkScrollUpDisplay(n) >-int n; >+static int >+MarkScrollUpDisplay(int n) > { >- int i; >+ int i; > >- debug1("MarkScrollUpDisplay(%d)\n", n); >- if (n <= 0) >- return 0; >- if (n > fore->w_histheight - markdata->hist_offset) >- n = fore->w_histheight - markdata->hist_offset; >- markdata->hist_offset += n; >- i = (n < flayer->l_height) ? n : (flayer->l_height); >- LScrollV(flayer, i, 0, flayer->l_height - 1, 0); >- while (i-- > 0) >- MarkRedisplayLine(flayer->l_height - i - 1, 0, flayer->l_width - 1, 1); >- return n; >+ debug1("MarkScrollUpDisplay(%d)\n", n); >+ if (n <= 0) >+ return 0; >+ if (n > fore->w_histheight - markdata->hist_offset) >+ n = fore->w_histheight - markdata->hist_offset; >+ >+ markdata->hist_offset += n; >+ i = (n < flayer->l_height) ? n : (flayer->l_height); >+ LScrollV(flayer, i, 0, flayer->l_height - 1, 0); >+ while (i-- > 0) >+ MarkRedisplayLine(flayer->l_height - i - 1, 0, flayer->l_width - 1, 1); >+ return n; > } > > static int >-MarkScrollDownDisplay(n) >-int n; >+MarkScrollDownDisplay(int n) > { >- int i; >+ int i; > >- debug1("MarkScrollDownDisplay(%d)\n", n); >- if (n <= 0) >- return 0; >- if (n > markdata->hist_offset) >- n = markdata->hist_offset; >- markdata->hist_offset -= n; >- i = (n < flayer->l_height) ? n : (flayer->l_height); >- LScrollV(flayer, -i, 0, fore->w_height - 1, 0); >- while (i-- > 0) >- MarkRedisplayLine(i, 0, flayer->l_width - 1, 1); >- return n; >+ debug1("MarkScrollDownDisplay(%d)\n", n); >+ if (n <= 0) >+ return 0; >+ if (n > markdata->hist_offset) >+ n = markdata->hist_offset; >+ markdata->hist_offset -= n; >+ i = (n < flayer->l_height) ? n : (flayer->l_height); >+ LScrollV(flayer, -i, 0, fore->w_height - 1, 0); >+ while (i-- > 0) >+ MarkRedisplayLine(i, 0, flayer->l_width - 1, 1); >+ return n; > } > > void >-MakePaster(pa, buf, len, bufiscopy) >-struct paster *pa; >-char *buf; >-int len; >-int bufiscopy; >+MakePaster(struct paster *pa, char *buf, int len, int bufiscopy) > { >- FreePaster(pa); >- pa->pa_pasteptr = buf; >- pa->pa_pastelen = len; >- if (bufiscopy) >- pa->pa_pastebuf = buf; >- pa->pa_pastelayer = flayer; >- DoProcess(Layer2Window(flayer), &pa->pa_pasteptr, &pa->pa_pastelen, pa); >+ FreePaster(pa); >+ pa->pa_pasteptr = buf; >+ pa->pa_pastelen = len; >+ if (bufiscopy) >+ pa->pa_pastebuf = buf; >+ pa->pa_pastelayer = flayer; >+ DoProcess(Layer2Window(flayer), &pa->pa_pasteptr, &pa->pa_pastelen, pa); > } > > void >-FreePaster(pa) >-struct paster *pa; >+FreePaster(struct paster *pa) > { >- if (pa->pa_pastebuf) >- free(pa->pa_pastebuf); >- pa->pa_pastebuf = 0; >- pa->pa_pasteptr = 0; >- pa->pa_pastelen = 0; >- pa->pa_pastelayer = 0; >- evdeq(&pa->pa_slowev); >+ if (pa->pa_pastebuf) >+ free(pa->pa_pastebuf); >+ pa->pa_pastebuf = 0; >+ pa->pa_pasteptr = 0; >+ pa->pa_pastelen = 0; >+ pa->pa_pastelayer = 0; >+ evdeq(&pa->pa_slowev); > } > > #endif /* COPY_PASTE */ >diff -ur screen.orig/misc.c screen/misc.c >--- screen.orig/misc.c 2023-06-01 14:58:17.242665034 +0300 >+++ screen/misc.c 2022-01-28 17:06:02.690612097 +0300 >@@ -378,9 +378,7 @@ > f = rl.rlim_max; > else > #endif /* SVR4 */ >-#ifdef _SC_OPEN_MAX >- f = sysconf(_SC_OPEN_MAX); >-#elif defined(SYSV) && defined(NOFILE) && !defined(ISC) >+#if defined(SYSV) && defined(NOFILE) && !defined(ISC) > f = NOFILE; > while (--f > 2) > if (f != except) >@@ -437,7 +435,6 @@ > return 1; > Usersigcld = signal(SIGCHLD, SIG_DFL); > debug("UserContext: forking.\n"); >- fflush(NULL); > switch (UserPID = fork()) > { > case -1: >diff -ur screen.orig/NEWS.3.5 screen/NEWS.3.5 >--- screen.orig/NEWS.3.5 2023-06-01 14:58:17.229665004 +0300 >+++ screen/NEWS.3.5 2022-01-28 17:06:02.662611403 +0300 >@@ -27,7 +27,7 @@ > Please run the 'newsyntax' script on your old screenrc files! > > * Emacs style isearch added to copy mode. Try ^A ESC ^R screen ^R ^R >- to locate the last three occurences of the word 'screen' in the >+ to locate the last three occurrences of the word 'screen' in the > history buffer. > > * New command 'silence'. Alarms the user whenever there was inactivity >diff -ur screen.orig/osdef.h.in screen/osdef.h.in >--- screen.orig/osdef.h.in 2023-06-01 14:58:17.243665036 +0300 >+++ screen/osdef.h.in 2022-01-28 17:06:02.690612097 +0300 >@@ -95,6 +95,9 @@ > extern int setegid __P((int)); > #endif > >+extern char *crypt __P((char *, char *)); >+extern int putenv __P((char *)); >+ > extern int tgetent __P((char *, char *)); > extern char *tgetstr __P((char *, char **)); > extern int tgetnum __P((char *)); >@@ -108,7 +111,7 @@ > extern int setpgid __P((int, int)); > extern int tcsetpgrp __P((int, int)); > #endif >-extern int ioctl __P((int, int, char *)); >+extern int ioctl __P((int, unsigned long, char *)); > > extern int kill __P((int, int)); > >diff -ur screen.orig/osdef.sh screen/osdef.sh >--- screen.orig/osdef.sh 2023-06-01 14:58:17.243665036 +0300 >+++ screen/osdef.sh 2022-01-28 17:06:02.690612097 +0300 >@@ -27,7 +27,6 @@ > #ifdef linux > #include <string.h> > #include <stdlib.h> >-#include <unistd.h> > #endif > #include <sys/socket.h> > #ifndef NOSYSLOG >diff -ur screen.orig/os.h screen/os.h >--- screen.orig/os.h 2023-06-01 14:58:17.243665036 +0300 >+++ screen/os.h 2022-01-28 17:06:02.690612097 +0300 >@@ -281,7 +281,7 @@ > # ifdef _PATH_UTMP > # define UTMPFILE _PATH_UTMP > # else >-# define UTMPFILE "/var/run/utmp" >+# define UTMPFILE "/etc/utmp" > # endif /* _PATH_UTMP */ > # endif > # endif >diff -ur screen.orig/patchlevel.h screen/patchlevel.h >--- screen.orig/patchlevel.h 2023-06-01 14:58:17.243665036 +0300 >+++ screen/patchlevel.h 2022-01-28 17:06:02.690612097 +0300 >@@ -532,7 +532,7 @@ > > #define ORIGIN "GNU" > #define REV 4 >-#define VERS 8 >+#define VERS 9 > #define PATCHLEVEL 0 >-#define DATE "05-Feb-20" >+#define DATE "30-Jan-22" > #define STATE "" >diff -ur screen.orig/process.c screen/process.c >--- screen.orig/process.c 2023-06-01 14:58:17.245665041 +0300 >+++ screen/process.c 2022-01-28 17:06:02.694612196 +0300 >@@ -2741,7 +2741,7 @@ > #ifdef COPY_PASTE > case RC_BUFFERFILE: > if (*args == 0) >- BufferFile = SaveStr(bufferfile); >+ BufferFile = SaveStr(DEFAULT_BUFFERFILE); > else if (ParseSaveStr(act, &BufferFile)) > break; > if (msgok) >@@ -5401,6 +5401,7 @@ > static int > MoreWindows() > { >+ char *m = "No other window."; > if (windows && (fore == 0 || windows->w_next)) > return 1; > if (fore == 0) >@@ -5408,7 +5409,7 @@ > Msg(0, "No window available"); > return 0; > } >- Msg(0, "No other window%s.", fore->w_number > 1 ? "s" : ""); >+ Msg(0, m, fore->w_number); /* other arg for nethack */ > return 0; > } > >@@ -6273,8 +6274,7 @@ > if (ktab[(int)(unsigned char)*buf].nr != RC_POW_DETACH) > { > if (display) >- if (write(D_userfd, "\007", 1) < 1) >- ; >+ write(D_userfd, "\007", 1); > Msg(0, "Detach aborted."); > } > else >diff -ur screen.orig/pty.c screen/pty.c >--- screen.orig/pty.c 2023-06-01 14:58:17.245665041 +0300 >+++ screen/pty.c 2022-01-28 17:06:02.694612196 +0300 >@@ -31,6 +31,10 @@ > #include <fcntl.h> > #include <signal.h> > >+#if defined(__OpenBSD__) >+#include <utils.h> /* for openpty() */ >+#endif >+ > #include "config.h" > #include "screen.h" > >@@ -77,10 +81,7 @@ > extern int eff_uid; > > /* used for opening a new pty-pair: */ >-#ifndef HAVE_GETPT >-static char PtyName[32]; >-#endif >-static char TtyName[32]; >+static char PtyName[32], TtyName[32]; > > #if !(defined(sequent) || defined(_SEQUENT_) || defined(HAVE_SVR4_PTYS)) > # ifdef hpux >@@ -262,10 +263,10 @@ > #endif > sigret_t (*sigcld)__P(SIGPROTOARG); > >+ strcpy(PtyName, "/dev/ptmx"); > #if defined(HAVE_GETPT) && (defined(linux) || defined(__GLIBC__)) > if ((f = getpt()) == -1) > #else >- strcpy(PtyName, "/dev/ptmx"); > if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1) > #endif > return -1; >diff -ur screen.orig/resize.c screen/resize.c >--- screen.orig/resize.c 2023-06-01 14:58:17.245665041 +0300 >+++ screen/resize.c 2022-01-28 17:06:02.694612196 +0300 >@@ -683,17 +683,6 @@ > he = MAXWIDTH; > } > >- if (wi > 1000) >- { >- Msg(0, "Window width too large, truncated"); >- wi = 1000; >- } >- if (he > 1000) >- { >- Msg(0, "Window height too large, truncated"); >- he = 1000; >- } >- > if (p->w_width == wi && p->w_height == he && p->w_histheight == hi) > { > debug("ChangeWindowSize: No change.\n"); >diff -ur screen.orig/sched.c screen/sched.c >--- screen.orig/sched.c 2023-06-01 14:58:17.245665041 +0300 >+++ screen/sched.c 2022-01-28 17:06:02.694612196 +0300 >@@ -47,244 +47,226 @@ > #endif > > void >-evenq(ev) >-struct event *ev; >+evenq(struct event *ev) > { >- struct event *evp, **evpp; >- debug3("New event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued); >- if (ev->queued) >- return; >- evpp = &evs; >- if (ev->type == EV_TIMEOUT) >- { >- calctimeout = 1; >- evpp = &tevs; >- } >- for (; (evp = *evpp); evpp = &evp->next) >- if (ev->pri > evp->pri) >- break; >- ev->next = evp; >- *evpp = ev; >- ev->queued = 1; >+ struct event *evp, **evpp; >+ debug3("New event fd %d type %d queued %d\n", ev -> fd, ev -> type, ev -> queued); >+ if (ev->queued) >+ return; >+ evpp = &evs; >+ if (ev->type == EV_TIMEOUT) { >+ calctimeout = 1; >+ evpp = &tevs; >+ } >+ for (; (evp = *evpp); evpp = &evp->next) >+ if (ev->pri > evp->pri) >+ break; >+ ev->next = evp; >+ *evpp = ev; >+ ev->queued = 1; > } > > void >-evdeq(ev) >-struct event *ev; >+evdeq(struct event *ev) > { >- struct event *evp, **evpp; >- debug3("Deq event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued); >- if (!ev->queued) >- return; >- evpp = &evs; >- if (ev->type == EV_TIMEOUT) >- { >- calctimeout = 1; >- evpp = &tevs; >- } >- for (; (evp = *evpp); evpp = &evp->next) >- if (evp == ev) >- break; >- ASSERT(evp); >- *evpp = ev->next; >- ev->queued = 0; >- if (ev == nextev) >- nextev = nextev->next; >+ struct event *evp, **evpp; >+ debug3("Deq event fd %d type %d queued %d\n", ev -> fd, ev -> type, ev -> queued); >+ if (!ev->queued) >+ return; >+ evpp = &evs; >+ if (ev->type == EV_TIMEOUT) { >+ calctimeout = 1; >+ evpp = &tevs; >+ } >+ for (; (evp = *evpp); evpp = &evp->next) >+ if (evp == ev) >+ break; >+ ASSERT(evp); >+ *evpp = ev->next; >+ ev->queued = 0; >+ if (ev == nextev) >+ nextev = nextev->next; > } > > static struct event * > calctimo() > { >- struct event *ev, *min; >- long mins; >+ struct event *ev, *min; >+ long mins; > >- if ((min = tevs) == 0) >- return 0; >- mins = min->timeout.tv_sec; >- for (ev = tevs->next; ev; ev = ev->next) >- { >- ASSERT(ev->type == EV_TIMEOUT); >- if (mins < ev->timeout.tv_sec) >- continue; >- if (mins > ev->timeout.tv_sec || min->timeout.tv_usec > ev->timeout.tv_usec) >- { >- min = ev; >- mins = ev->timeout.tv_sec; >+ if ((min = tevs) == 0) >+ return 0; >+ mins = min->timeout.tv_sec; >+ for (ev = tevs->next; ev; ev = ev->next) { >+ ASSERT(ev->type == EV_TIMEOUT); >+ if (mins < ev->timeout.tv_sec) >+ continue; >+ if (mins > ev->timeout.tv_sec || min->timeout.tv_usec > ev->timeout.tv_usec) { >+ min = ev; >+ mins = ev->timeout.tv_sec; >+ } > } >- } >- return min; >+ return min; > } > > void > sched() > { >- struct event *ev; >- fd_set r, w, *set; >- struct event *timeoutev = 0; >- struct timeval timeout; >- int nsel; >- >- for (;;) >- { >- if (calctimeout) >- timeoutev = calctimo(); >- if (timeoutev) >- { >- gettimeofday(&timeout, NULL); >- /* tp - timeout */ >- timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_sec; >- timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv_usec; >- if (timeout.tv_usec < 0) >- { >- timeout.tv_usec += 1000000; >- timeout.tv_sec--; >- } >- if (timeout.tv_sec < 0) >- { >- timeout.tv_usec = 0; >- timeout.tv_sec = 0; >- } >- } >+ struct event *ev; >+ fd_set r, w, *set; >+ struct event *timeoutev = 0; >+ struct timeval timeout; >+ int nsel; >+ >+ for (;;) { >+ if (calctimeout) >+ timeoutev = calctimo(); >+ if (timeoutev) { >+ gettimeofday(&timeout, NULL); >+ /* tp - timeout */ >+ timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_sec; >+ timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv_usec; >+ >+ if (timeout.tv_usec < 0) { >+ timeout.tv_usec += 1000000; >+ timeout.tv_sec--; >+ } >+ if (timeout.tv_sec < 0) { >+ timeout.tv_usec = 0; >+ timeout.tv_sec = 0; >+ } >+ } > #ifdef DEBUG >- debug("waiting for events"); >- if (timeoutev) >- debug2(" timeout %ld secs %ld usecs", timeout.tv_sec, timeout.tv_usec); >- debug(":\n"); >- for (ev = evs; ev; ev = ev->next) >- debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev->pri); >- if (tevs) >- debug("timed events:\n"); >- for (ev = tevs; ev; ev = ev->next) >- debug3(" - pri %d sec %ld usec %ld\n", ev->pri, ev->timeout.tv_sec, ev->timeout.tv_usec); >-#endif >- >- FD_ZERO(&r); >- FD_ZERO(&w); >- for (ev = evs; ev; ev = ev->next) >- { >- if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) >- { >- debug2(" - cond ev fd %d type %d failed\n", ev->fd, ev->type); >- continue; >- } >- if (ev->type == EV_READ) >- FD_SET(ev->fd, &r); >- else if (ev->type == EV_WRITE) >- FD_SET(ev->fd, &w); >- } >+ debug("waiting for events"); >+ if (timeoutev) >+ debug2(" timeout %d secs %d usecs", timeout.tv_sec, timeout.tv_usec); >+ debug(":\n"); >+ for (ev = evs; ev; ev = ev->next) >+ debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev->pri); >+ if (tevs) >+ debug("timed events:\n"); >+ for (ev = tevs; ev; ev = ev->next) >+ debug3(" - pri %d sec %d usec %d\n", ev->pri, >+ ev->timeout.tv_sec, ev->timeout.tv_usec); >+#endif >+ >+ FD_ZERO(&r); >+ FD_ZERO(&w); >+ for (ev = evs; ev; ev = ev->next) { >+ if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) { >+ debug2(" - cond ev fd %d type %d failed\n", ev->fd, ev->type); >+ continue; >+ } >+ if (ev->type == EV_READ) >+ FD_SET(ev->fd, &r); >+ else if (ev->type == EV_WRITE) >+ FD_SET(ev->fd, &w); >+ } > > #ifdef DEBUG >- debug("readfds:"); >- for (nsel = 0; nsel < FD_SETSIZE; nsel++) >- if (FD_ISSET(nsel, &r)) >- debug1(" %d", nsel); >- debug("\n"); >- debug("writefds:"); >- for (nsel = 0; nsel < FD_SETSIZE; nsel++) >- if (FD_ISSET(nsel, &w)) >- debug1(" %d", nsel); >- debug("\n"); >-#endif >- >- nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeout : (struct timeval *) 0); >- if (nsel < 0) >- { >- if (errno != EINTR) >- { >+ debug("readfds:"); >+ for (nsel = 0; nsel < FD_SETSIZE; nsel++) >+ if (FD_ISSET(nsel, &r)) >+ debug1(" %d", nsel); >+ debug("\n"); >+ debug("writefds:"); >+ for (nsel = 0; nsel < FD_SETSIZE; nsel++) >+ if (FD_ISSET(nsel, &w)) >+ debug1(" %d", nsel); >+ debug("\n"); >+#endif >+ >+ nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeout : (struct timeval *)0); >+ if (nsel < 0) { >+ if (errno != EINTR) { > #if defined(sgi) && defined(SVR4) >- if (errno == EIO && sgihack()) >- continue; >+ if (errno == EIO && sgihack()) >+ continue; > #endif > #if defined(__osf__) || defined(M_UNIX) >- /* OSF/1 3.x, SCO bug: EBADF */ >- /* OSF/1 4.x bug: EIO */ >- if ((errno == EIO || errno == EBADF) && sgihack()) >- continue; >-#endif >- Panic(errno, "select"); >- } >- nsel = 0; >- } >- else if (nsel == 0) /* timeout */ >- { >- debug("TIMEOUT!\n"); >- ASSERT(timeoutev); >- evdeq(timeoutev); >- timeoutev->handler(timeoutev, timeoutev->data); >- } >+ /* OSF/1 3.x, SCO bug: EBADF */ >+ /* OSF/1 4.x bug: EIO */ >+ if ((errno == EIO || errno == EBADF) && sgihack()) >+ continue; >+#endif >+ Panic(errno, "select"); >+ } >+ nsel = 0; >+ } else if (nsel == 0) { /* timeout */ >+ debug("TIMEOUT!\n"); >+ ASSERT(timeoutev); >+ evdeq(timeoutev); >+ timeoutev->handler(timeoutev, timeoutev->data); >+ } > #ifdef SELECT_BROKEN > /* > * Sequents select emulation counts a descriptor which is > * readable and writeable only as one hit. Waaaaa. > */ >- if (nsel) >- nsel = 2 * FD_SETSIZE; >+ if (nsel) >+ nsel = 2 * FD_SETSIZE; > #endif > >- for (ev = evs; ev; ev = nextev) >- { >- nextev = ev->next; >- if (ev->type != EV_ALWAYS) >- { >- set = ev->type == EV_READ ? &r : &w; >- if (nsel == 0 || !FD_ISSET(ev->fd, set)) >- continue; >- nsel--; >- } >- if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) >- continue; >- debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type); >- ev->handler(ev, ev->data); >- } >- } >+ for (ev = evs; ev; ev = nextev) { >+ nextev = ev->next; >+ if (ev->type != EV_ALWAYS) { >+ set = ev->type == EV_READ ? &r : &w; >+ if (nsel == 0 || !FD_ISSET(ev->fd, set)) >+ continue; >+ nsel--; >+ } >+ if (ev->condpos && >+ *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) >+ continue; >+ debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type); >+ ev->handler(ev, ev->data); >+ } >+ } > } > > void >-SetTimeout(ev, timo) >-struct event *ev; >-int timo; >-{ >- ASSERT(ev->type == EV_TIMEOUT); >- debug2("event %p new timeout %d ms\n", ev, timo); >- gettimeofday(&ev->timeout, NULL); >- ev->timeout.tv_sec += timo / 1000; >- ev->timeout.tv_usec += (timo % 1000) * 1000; >- if (ev->timeout.tv_usec > 1000000) >- { >- ev->timeout.tv_usec -= 1000000; >- ev->timeout.tv_sec++; >- } >- if (ev->queued) >- calctimeout = 1; >+SetTimeout(struct event *ev, int timo) >+{ >+ ASSERT(ev->type == EV_TIMEOUT); >+ debug2("event %x new timeout %d ms\n", ev, timo); >+ gettimeofday(&ev->timeout, NULL); >+ ev->timeout.tv_sec += timo / 1000; >+ ev->timeout.tv_usec += (timo % 1000) * 1000; >+ >+ if (ev->timeout.tv_usec > 1000000) { >+ ev->timeout.tv_usec -= 1000000; >+ ev->timeout.tv_sec++; >+ } >+ if (ev->queued) >+ calctimeout = 1; > } > >- > #if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX) >- >+/* do we still need it? >+ @anaumov */ > extern struct display *display, *displays; >-static int sgihack() >+static int >+sgihack() > { >- fd_set r, w; >- struct timeval tv; >+ fd_set r, w; >+ struct timeval tv; > >- debug("IRIX5.2 workaround: searching for bad display\n"); >- for (display = displays; display; ) >- { >- FD_ZERO(&r); >- FD_ZERO(&w); >- FD_SET(D_userfd, &r); >- FD_SET(D_userfd, &w); >- tv.tv_sec = tv.tv_usec = 0; >- if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1) >- { >- if (errno == EINTR) >- continue; >- Hangup(); /* goodbye display */ >- return 1; >- } >- display = display->d_next; >- } >- return 0; >+ debug("IRIX5.2 workaround: searching for bad display\n"); >+ for (display = displays; display;) { >+ FD_ZERO(&r); >+ FD_ZERO(&w); >+ FD_SET(D_userfd, &r); >+ FD_SET(D_userfd, &w); >+ tv.tv_sec = tv.tv_usec = 0; >+ if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1) { >+ if (errno == EINTR) >+ continue; >+ Hangup(); /* goodbye display */ >+ return 1; >+ } >+ display = display->d_next; >+ } >+ return 0; > } > > #endif >diff -ur screen.orig/screen.c screen/screen.c >--- screen.orig/screen.c 2023-06-01 14:58:17.246665043 +0300 >+++ screen/screen.c 2022-01-28 17:06:02.694612196 +0300 >@@ -122,7 +122,6 @@ > FILE *dfp; > #endif > >-char bufferfile[MAXPATHLEN]; > > extern char Term[], screenterm[], **environ, Termcap[]; > int force_vt = 1; >@@ -154,9 +153,7 @@ > static void SigChldHandler __P((void)); > static sigret_t SigChld __P(SIGPROTOARG); > static sigret_t SigInt __P(SIGPROTOARG); >-#if 0 > static sigret_t CoreDump __P(SIGPROTOARG); >-#endif > static sigret_t FinitHandler __P(SIGPROTOARG); > static void DoWait __P((void)); > static void serv_read_fn __P((struct event *, char *)); >@@ -239,7 +236,7 @@ > > char HostName[MAXSTR]; > int MasterPid, PanicPid; >-int real_uid, real_gid, eff_uid, eff_gid, init_eff_gid; >+int real_uid, real_gid, eff_uid, eff_gid; > int default_startup; > int ZombieKey_destroy, ZombieKey_resurrect, ZombieKey_onerror; > char *preselect = NULL; /* only used in Attach() */ >@@ -271,7 +268,7 @@ > */ > #include "extern.h" > >-const char strnomem[] = "Out of memory."; >+char strnomem[] = "Out of memory."; > > static int InterruptPlease; > static int GotSigChld; >@@ -470,6 +467,9 @@ > timestring = SaveStr("%c:%s %M %d %H%? %l%?"); > wlisttit = SaveStr(" Num Name%=Flags"); > wliststr = SaveStr("%4n %t%=%f"); >+#ifdef COPY_PASTE >+ BufferFile = SaveStr(DEFAULT_BUFFERFILE); >+#endif > ShellProg = NULL; > #ifdef POW_DETACH > PowDetachString = 0; >@@ -509,7 +509,7 @@ > real_uid = getuid(); > real_gid = getgid(); > eff_uid = geteuid(); >- init_eff_gid = eff_gid = getegid(); >+ eff_gid = getegid(); > > logreopen_register(lf_secreopen); > >@@ -778,6 +778,10 @@ > if (--ac == 0) > exit_with_usage(myname, "Specify session-name with -S", NULL); > SockMatch = *++av; >+ debug1("SockMatch: '%s'\n", SockMatch); >+ debug1("SockMatch len: '%d'\n", (int)strlen(SockMatch)); >+ if (strlen(SockMatch) > 80) >+ exit_with_usage(myname, "Session-name is too long (max length is 80 symbols)", NULL); > } > if (!*SockMatch) > exit_with_usage(myname, "Empty session-name?", NULL); >@@ -806,19 +810,11 @@ > break; > } > >-#if 0 >- if (eff_uid != real_uid) >- { >- /* if running with s-bit, we must install a special signal >- * handler routine that resets the s-bit, so that we get a >- * core file anyway. >- */ > #ifdef SIGBUS /* OOPS, linux has no bus errors! */ > signal(SIGBUS, CoreDump); > #endif /* SIGBUS */ > signal(SIGSEGV, CoreDump); > >-#endif > > #ifdef USE_LOCALE > setlocale(LC_ALL, ""); >@@ -1042,11 +1038,6 @@ > #endif /* DEBUG */ > } > >-#ifdef COPY_PASTE >- snprintf(bufferfile, sizeof(bufferfile), "%s/.screen-exchange", home); >- BufferFile = SaveStr(bufferfile); >-#endif >- > #ifdef _MODE_T > oumask = umask(0); /* well, unsigned never fails? jw. */ > #else >@@ -1130,6 +1121,7 @@ > if (access(SockPath, F_OK)) { > if (mkdir(SockPath, 0700) == -1 && errno != EEXIST) > Panic(errno, "Cannot make directory '%s'", SockPath); >+ (void) chown(SockPath, real_uid, real_gid); > } > } > #endif >@@ -1203,11 +1195,25 @@ > eexit(0); > } > signal(SIG_BYE, AttacherFinit); /* prevent races */ >+ > if (cmdflag) { >+ >+#ifdef MULTIUSER >+ if (multi) >+ real_uid = multi_uid; >+#endif >+ > /* attach_tty is not mandatory */ > SetTtyname(false, &st); > if (!*av) > Panic(0, "Please specify a command."); >+ if (!strncmp("sessionname", *av, 11)) { >+ if (!*++av) >+ Panic(0, "Please specify a parameter."); >+ if (strlen(*av) > 80) >+ Panic(0, "Parameter of command 'sessionname' is too long."); >+ *--av; >+ } > SET_GUID(); > SendCmdMessage(sty, SockMatch, av, queryflag >= 0); > exit(0); >@@ -1244,10 +1250,7 @@ > nwin_compose(&nwin_default, &nwin_options, &nwin_default); > > if (!detached || dflag != 2) >- { >- fflush(NULL); >- MasterPid = fork(); >- } >+ MasterPid = fork(); > else > MasterPid = 0; > >@@ -1320,40 +1323,14 @@ > } > else > n = -1; >- >- { >- const char devnull[] = "/dev/null"; >- int nullfdr, nullfdw; >- >- if (fflush(NULL)) >- Panic(errno, "Cannot flush stdio streams"); >- >- nullfdr = open(devnull, O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK); >- if (nullfdr < 0) >- Panic(errno, "Cannot open '%s' for reading", devnull); >- >- nullfdw = open(devnull, O_WRONLY|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK); >- if (nullfdw < 0) >- Panic(errno, "Cannot open '%s' for writing", devnull); >- >- if (dup2(nullfdr, fileno(stdin)) < 0) >- Panic(errno, "Cannot reditect '%s' to '%s'", "stdin", devnull); >- >- close(nullfdr); >- >- if (dup2(nullfdw, fileno(stdout)) < 0) >- Panic(errno, "Cannot reditect '%s' to '%s'", "stdout", devnull); >+ freopen("/dev/null", "r", stdin); >+ freopen("/dev/null", "w", stdout); > > #ifdef DEBUG > if (dfp != stderr) > #endif >- if (dup2(nullfdw, fileno(stderr)) < 0) >- Panic(errno, "Cannot reditect '%s' to '%s'", "stderr", devnull); >- >- close(nullfdw); >- >- debug("-- screen.back debug started\n"); >- } >+ freopen("/dev/null", "w", stderr); >+ debug("-- screen.back debug started\n"); > > /* This guarantees that the session owner is listed, even when we > * start detached. From now on we should not refer to 'LoginName' >@@ -1672,7 +1649,6 @@ > SIGRETURN; > } > >-#if 0 > static sigret_t CoreDump SIGDEFARG > { > /* if running with s-bit, we must reset the s-bit, so that we get a >@@ -1723,7 +1699,6 @@ > > SIGRETURN; > } >-#endif > > static void DoWait() > { >@@ -1896,7 +1871,7 @@ > { > if (display == 0) > return; >- debug1("Hangup %p\n", display); >+ debug1("Hangup %x\n", display); > if (D_userfd >= 0) { > close(D_userfd); > D_userfd = -1; >@@ -2108,29 +2083,20 @@ > #endif > > #define PROCESS_MESSAGE(B) do { \ >+ char *p = B; \ > VA_LIST(ap) \ >- ssize_t len; \ >- const int errlen = err ? 100 : 0; \ > VA_START(ap, fmt); \ > fmt = DoNLS(fmt); \ >- len = vsnprintf(B, sizeof(B) - errlen, fmt, VA_ARGS(ap)); \ >+ (void)vsnprintf(p, sizeof(B) - 100, fmt, VA_ARGS(ap)); \ > VA_END(ap); \ >- if (len < 0) \ >- { \ >- strncpy(B, fmt, sizeof(B) - errlen); \ >- B[sizeof(B) - errlen - 1] = 0; \ >- len = strlen(B); \ >- } \ > if (err) \ >- { \ >- const char *strerr = strerror(err); \ >- if (strerr) \ >- { \ >- strncat(B, ": ", 2); \ >- strncat(B, strerr, errlen - 3); \ >- len = strlen(B); \ >- } \ >- } \ >+ { \ >+ p += strlen(p); \ >+ *p++ = ':'; \ >+ *p++ = ' '; \ >+ strncpy(p, strerror(err), B + sizeof(B) - p - 1); \ >+ B[sizeof(B) - 1] = 0; \ >+ } \ > } while (0) > > DEFINE_VARARGS_FN(Msg) >@@ -2157,12 +2123,7 @@ > display = olddisplay; > } > else >- { >- ssize_t len = strlen(buf); >- if (write(fileno(stderr), buf, len) > 0) >- if (write(fileno(stderr), "\r\n", 2) > 0) >- ; >- } >+ printf("%s\r\n", buf); > > if (queryflag >= 0) > write(queryflag, buf, strlen(buf)); >@@ -2175,15 +2136,12 @@ > { > char buf[MAXPATHLEN*2]; > PROCESS_MESSAGE(buf); >- ssize_t len = strlen(buf); > >- debug3("Panic('%s'); display=%p displays=%p\n", buf, display, displays); >+ debug3("Panic('%s'); display=%x displays=%x\n", buf, display, displays); > if (displays == 0 && display == 0) { >- if (write(fileno(stderr), buf, len) > 0) >- if (write(fileno(stderr), "\r\n", 2) > 0) >- ; >- if (PanicPid) >- Kill(PanicPid, SIG_BYE); >+ printf("%s\r\n", buf); >+ if (PanicPid) >+ Kill(PanicPid, SIG_BYE); > } > else if (displays == 0) { > /* no displays but a display - must have forked. >@@ -2206,9 +2164,8 @@ > #endif > SetTTY(D_userfd, &D_OldMode); > fcntl(D_userfd, F_SETFL, 0); >- if (write(D_userfd, buf, len) > 0) >- if (write(D_userfd, "\n", 1) > 0) >- ; >+ write(D_userfd, buf, strlen(buf)); >+ write(D_userfd, "\n", 1); > freetty(); > if (D_userpid) > Kill(D_userpid, SIG_BYE); >@@ -2816,6 +2773,18 @@ > p += strlen(p) - 1; > break; > >+#ifdef ENCODINGS >+ case 'e': >+ *p = 0; >+ D_encoding = nwin_options.encoding > 0 ? nwin_options.encoding : 0; >+ if (win && win->w_encoding) { >+ *p++ = ' '; >+ strcpy(p, EncodingName(win->w_encoding)); >+ } >+ p += strlen(p) - 1; >+ break; >+#endif >+ > case '{': > { > char rbuf[128]; >@@ -3065,7 +3034,7 @@ > else > now.tv_sec += tick - (now.tv_sec % tick); > ev->timeout = now; >- debug2("NEW timeout %ld %d\n", ev->timeout.tv_sec, tick); >+ debug2("NEW timeout %d %d\n", ev->timeout.tv_sec, tick); > } > return winmsg_buf; > } >@@ -3193,15 +3162,12 @@ > > > #ifdef PSEUDOS >- if (write(W_UWP(fore) ? fore->w_pwin->p_ptyfd : fore->w_ptyfd, &ibuf, 1) == 1) { >- debug1("Backend wrote interrupt to %d", fore->w_number); >- debug1("%s\n", W_UWP(fore) ? " (pseudowin)" : ""); >- } >+ write(W_UWP(fore) ? fore->w_pwin->p_ptyfd : fore->w_ptyfd, &ibuf, 1); >+ debug1("Backend wrote interrupt to %d", fore->w_number); >+ debug1("%s\n", W_UWP(fore) ? " (pseudowin)" : ""); > #else >- if (write(fore->w_ptyfd, &ibuf, 1) == 1) >- debug1("Backend wrote interrupt to %d\n", fore->w_number); >- else >- debug1("Backend FAILED to write interrupt to %d\n", fore->w_number); >+ write(fore->w_ptyfd, &ibuf, 1); >+ debug1("Backend wrote interrupt to %d\n", fore->w_number); > #endif > } > InterruptPlease = 0; >diff -ur screen.orig/screen.h screen/screen.h >--- screen.orig/screen.h 2023-06-01 14:58:17.246665043 +0300 >+++ screen/screen.h 2022-01-28 17:06:02.694612196 +0300 >@@ -49,7 +49,6 @@ > #include "layer.h" > #include "term.h" > >-extern char bufferfile[MAXPATHLEN]; > > #ifdef DEBUG > # define STATIC /* a function that the debugger should see */ >@@ -104,6 +103,11 @@ > */ > #define MAXHISTHEIGHT 3000 > #define DEFAULTHISTHEIGHT 100 >+#if defined(NAME_MAX) && NAME_MAX < 16 >+# define DEFAULT_BUFFERFILE "/tmp/screen-xchg" >+#else >+# define DEFAULT_BUFFERFILE "/tmp/screen-exchange" >+#endif > > > #if defined(hpux) && !(defined(VSUSP) && defined(VDSUSP) && defined(VWERASE) && defined(VLNEXT)) >@@ -275,7 +279,7 @@ > #define SILENCE_FOUND 2 /* Window is silent */ > #define SILENCE_DONE 3 /* Window is silent and user is notified */ > >-extern const char strnomem[]; >+extern char strnomem[]; > > /* > * line modes used by Input() >diff -ur screen.orig/search.c screen/search.c >--- screen.orig/search.c 2023-06-01 14:58:17.246665043 +0300 >+++ screen/search.c 2022-01-28 17:06:02.694612196 +0300 >@@ -46,92 +46,80 @@ > * VI style Search > */ > >-static int matchword __P((char *, int, int, int)); >-static void searchend __P((char *, int, char *)); >-static void backsearchend __P((char *, int, char *)); >+static int matchword __P((char*, int, int, int)); >+static void searchend __P((char*, int, char *)); >+static void backsearchend __P((char*, int, char *)); > > void >-Search(dir) >-int dir; >+Search(int dir) > { >- struct markdata *markdata; >- if (dir == 0) >- { >- markdata = (struct markdata *)flayer->l_data; >- if (markdata->isdir > 0) >- searchend(0, 0, NULL); >- else if (markdata->isdir < 0) >- backsearchend(0, 0, NULL); >- else >- LMsg(0, "No previous pattern"); >- } >- else >- Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr)-1, INP_COOKED, >- (dir > 0 ? searchend : backsearchend), NULL, 0); >+ struct markdata *markdata; >+ if (dir == 0) { >+ markdata = (struct markdata *)flayer->l_data; >+ if (markdata->isdir > 0) >+ searchend(0, 0, NULL); >+ else if (markdata->isdir < 0) >+ backsearchend(0, 0, NULL); >+ else >+ LMsg(0, "No previous pattern"); >+ } else >+ Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr) - 1, >+ INP_COOKED, (dir > 0 ? searchend : backsearchend), NULL, 0); > } > > static void >-searchend(buf, len, data) >-char *buf; >-int len; >-char *data; /* dummy */ >+searchend(char *buf, int len, char *data) > { >- int x = 0, sx, ex, y; >- struct markdata *markdata; >- struct win *p; >- >- markdata = (struct markdata *)flayer->l_data; >- p = markdata->md_window; >- markdata->isdir = 1; >- if (len) >- strcpy(markdata->isstr, buf); >- sx = markdata->cx + 1; >- ex = flayer->l_width - 1; >- for (y = markdata->cy; y < p->w_histheight + flayer->l_height; y++, sx = 0) >- { >- if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0) >- break; >- } >- if (y >= p->w_histheight + flayer->l_height) >- { >- LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >- LMsg(0, "Pattern not found"); >- } >- else >- revto(x, y); >+ int x = 0, sx, ex, y; >+ struct markdata *markdata; >+ struct win *p; >+ >+ markdata = (struct markdata *)flayer->l_data; >+ p = markdata->md_window; >+ markdata->isdir = 1; >+ if (len) >+ strcpy(markdata->isstr, buf); >+ sx = markdata->cx + 1; >+ ex = flayer->l_width - 1; >+ for (y = markdata->cy; y < p->w_histheight + flayer->l_height; >+ y++, sx = 0) { >+ if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0) >+ break; >+ } >+ if (y >= p->w_histheight + flayer->l_height) { >+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >+ LMsg(0, "Pattern not found"); >+ } else >+ revto(x, y); > } > > static void >-backsearchend(buf, len, data) >-char *buf; >-int len; >-char *data; /* dummy */ >+backsearchend(char *buf, int len, char *data) > { >- int sx, ex, x = -1, y; >- struct markdata *markdata; >+ int sx, ex, x = -1, y; >+ struct markdata *markdata; > >- markdata = (struct markdata *)flayer->l_data; >- markdata->isdir = -1; >- if (len) >- strcpy(markdata->isstr, buf); >- ex = markdata->cx - 1; >- for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1) >- { >- sx = 0; >- while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0) >- x = sx++; >- if (x >= 0) >- break; >- } >- if (y < 0) >- { >- LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >- LMsg(0, "Pattern not found"); >- } >- else >- revto(x, y); >-} >+ markdata = (struct markdata *)flayer->l_data; >+ markdata->isdir = -1; >+ >+ if (len) >+ strcpy(markdata->isstr, buf); >+ ex = markdata->cx - 1; >+ >+ for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1) { >+ sx = 0; >+ while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0) >+ x = sx++; >+ if (x >= 0) >+ break; >+ } > >+ if (y < 0) { >+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >+ LMsg(0, "Pattern not found"); >+ } else >+ revto(x, y); >+} > > /* > * Search for a string that matches pattern. The first character of the >@@ -141,259 +129,255 @@ > * or -1 if there's no match. > */ > static int >-matchword(pattern, y, sx, ex) >-char *pattern; >-int y, sx, ex; >+matchword(char *pattern, int y, int sx, int ex) > { >- unsigned char *ip, *cp, *pp, *cpe; >- int cy; >+ unsigned char *cp, *pp, *cpe; >+ int cy; > >- fore = ((struct markdata *)flayer->l_data)->md_window; >+ fore = ((struct markdata *)flayer->l_data)->md_window; > >- for (;sx <= ex; sx++) >- { >- cy = y; >- cp = WIN(cy)->image + sx; >- cpe = WIN(cy)->image + flayer->l_width; >- pp = (unsigned char *)pattern; >- for (;;) >- { >- if (*cp != *pp) >- if (!search_ic || ((*cp ^ *pp) & 0xdf) || (*cp | 0x20) < 'a' || (*cp | 0x20) > 'z') >- break; >- cp++; >- pp++; >- if (*pp == 0) >- return sx; >- if (cp == cpe) { >+ for (; sx <= ex; sx++) { >+ cy = y; >+ cp = WIN(cy)->image + sx; >+ cpe = WIN(cy)->image + flayer->l_width; >+ pp = (unsigned char *)pattern; >+ for (;;) { >+ if (*cp != *pp) >+ if (!search_ic || ((*cp ^ *pp) & 0xdf) || >+ (*cp | 0x20) < 'a' || (*cp | 0x20) > 'z') >+ break; >+ cp++; >+ pp++; >+ if (*pp == 0) >+ return sx; >+ if (cp == cpe) { > /* > * We have a partial match, but we've hit > * the end of this line. Does it wrap onto > * the following line? If not, we're done. > */ >- if (*cp == ' ' || cy >= fore->w_histheight + flayer->l_height - 1) >- break; >+ if (*cp == ' ' || >+ cy >= >+ fore->w_histheight + flayer->l_height - 1) >+ break; > > /* > * This line does wrap, so look on the next > * line for the rest of our match. > */ >- cy++; >- cp = WIN(cy)->image; >- cpe = WIN(cy)->image + flayer->l_width; >+ cy++; >+ cp = WIN(cy)->image; >+ cpe = WIN(cy)->image + flayer->l_width; >+ } > } > } >- } >- return -1; >+ return -1; > } > >- > /******************************************************************** > * Emacs style ISearch > */ > > static char *isprompts[] = { >- "I-search backward: ", "failing I-search backward: ", >- "I-search: ", "failing I-search: " >+ "I-search backward: ", "failing I-search backward: ", >+ "I-search: ", "failing I-search: " > }; > >- >-static int is_redo __P((struct markdata *)); >-static void is_process __P((char *, int, char *)); >-static int is_bm __P((char *, int, int, int, int)); >- >+static int is_redo __P((struct markdata*)); >+static void is_process __P((char*, int, char *)); >+static int is_bm __P((char*, int, int, int, int)); > > static int >-is_bm(str, l, p, end, dir) >-char *str; >-int l, p, end, dir; >+is_bm(char *str, int l, int p, int end, int dir) > { >- int tab[256]; >- int i, q; >- unsigned char *s, c; >- int w = flayer->l_width; >+ int tab[256]; >+ int i, q; >+ unsigned char *s, c; >+ int w = flayer->l_width; > > /* *sigh* to make WIN work */ >- fore = ((struct markdata *)flayer->l_next->l_data)->md_window; >- debug2("is_bm: searching for %s len %d\n", str, l); >- debug3("start at %d end %d dir %d\n", p, end, dir); >- if (p < 0 || p + l > end) >- return -1; >- if (l == 0) >- return p; >- if (dir < 0) >- str += l - 1; >- for (i = 0; i < 256; i++) >- tab[i] = l * dir; >- for (i = 0; i < l - 1; i++, str += dir) >- { >- q = *(unsigned char *)str; >- tab[q] = (l - 1 - i) * dir; >- if (search_ic && (q | 0x20) >= 'a' && ((q | 0x20) <= 'z')) >- tab[q ^ 0x20] = (l - 1 - i) * dir; >- } >- if (dir > 0) >- p += l - 1; >- debug1("first char to match: %c\n", *str); >- while (p >= 0 && p < end) >- { >- q = p; >- s = (unsigned char *)str; >- for (i = 0;;) >- { >- c = (WIN(q / w))->image[q % w]; >- if (i == 0) >- p += tab[(int)(unsigned char) c]; >- if (c != *s) >- if (!search_ic || ((c ^ *s) & 0xdf) || (c | 0x20) < 'a' || (c | 0x20) > 'z') >- break; >- q -= dir; >- s -= dir; >- if (++i == l) >- return q + (dir > 0 ? 1 : -l); >+ fore = ((struct markdata *)flayer->l_next->l_data)->md_window; >+ debug2("is_bm: searching for %s len %d\n", str, l); >+ debug3("start at %d end %d dir %d\n", p, end, dir); >+ >+ if (p < 0 || p + l > end) >+ return -1; >+ if (l == 0) >+ return p; >+ if (dir < 0) >+ str += l - 1; >+ for (i = 0; i < 256; i++) >+ tab[i] = l * dir; >+ >+ for (i = 0; i < l - 1; i++, str += dir) { >+ q = *(unsigned char *)str; >+ tab[q] = (l - 1 - i) * dir; >+ if (search_ic && (q | 0x20) >= 'a' && ((q | 0x20) <= 'z')) >+ tab[q ^ 0x20] = (l - 1 - i) * dir; > } >- } >- return -1; >-} > >+ if (dir > 0) >+ p += l - 1; >+ >+ debug1("first char to match: %c\n", *str); >+ >+ while (p >= 0 && p < end) { >+ q = p; >+ s = (unsigned char *)str; >+ for (i = 0;;) { >+ c = (WIN(q / w))->image[q % w]; >+ if (i == 0) >+ p += tab[(int)(unsigned char)c]; >+ if (c != *s) >+ if (!search_ic || ((c ^ *s) & 0xdf) || >+ (c | 0x20) < 'a' || (c | 0x20) > 'z') >+ break; >+ q -= dir; >+ s -= dir; >+ if (++i == l) >+ return q + (dir > 0 ? 1 : -l); >+ } >+ } >+ return -1; >+} > > /*ARGSUSED*/ > static void >-is_process(p, n, data) /* i-search */ >-char *p; >-int n; >-char *data; /* dummy */ >+is_process(char *p, int n, char *data) /* i-search */ > { >- int pos, x, y, dir; >- struct markdata *markdata; >+ int pos, x, y, dir; >+ struct markdata *markdata; > >- if (n == 0) >- return; >- ASSERT(p); >- markdata = (struct markdata *)flayer->l_next->l_data; >- >- pos = markdata->cx + markdata->cy * flayer->l_width; >- LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >- >- switch (*p) >- { >- case '\007': /* CTRL-G */ >- pos = markdata->isstartpos; >+ if (n == 0) >+ return; >+ ASSERT(p); >+ markdata = (struct markdata *)flayer->l_next->l_data; >+ >+ pos = markdata->cx + markdata->cy * flayer->l_width; >+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >+ >+ switch (*p) { >+ case '\007': /* CTRL-G */ >+ pos = markdata->isstartpos; > /*FALLTHROUGH*/ >- case '\033': /* ESC */ >- *p = 0; >- break; >- case '\013': /* CTRL-K */ >- case '\027': /* CTRL-W */ >- markdata->isistrl = 1; >+ case '\033': /* ESC */ >+ *p = 0; >+ break; >+ case '\013': /* CTRL-K */ >+ case '\027': /* CTRL-W */ >+ markdata->isistrl = 1; > /*FALLTHROUGH*/ >- case '\b': >- case '\177': >- if (markdata->isistrl == 0) >- return; >- markdata->isistrl--; >- pos = is_redo(markdata); >- *p = '\b'; >- break; >- case '\023': /* CTRL-S */ >- case '\022': /* CTRL-R */ >- if (markdata->isistrl >= (int)sizeof(markdata->isistr)) >- return; >- dir = (*p == '\023') ? 1 : -1; >- pos += dir; >- if (markdata->isdir == dir && markdata->isistrl == 0) >- { >- strcpy(markdata->isistr, markdata->isstr); >- markdata->isistrl = markdata->isstrl = strlen(markdata->isstr); >- break; >+ case '\b': >+ case '\177': >+ if (markdata->isistrl == 0) >+ return; >+ markdata->isistrl--; >+ pos = is_redo(markdata); >+ *p = '\b'; >+ break; >+ case '\023': /* CTRL-S */ >+ case '\022': /* CTRL-R */ >+ if (markdata->isistrl >= (int)sizeof(markdata->isistr)) >+ return; >+ dir = (*p == '\023') ? 1 : -1; >+ pos += dir; >+ if (markdata->isdir == dir && markdata->isistrl == 0) { >+ strcpy(markdata->isistr, markdata->isstr); >+ markdata->isistrl = markdata->isstrl = strlen(markdata->isstr); >+ break; >+ } >+ markdata->isdir = dir; >+ markdata->isistr[markdata->isistrl++] = *p; >+ break; >+ default: >+ if (*p < ' ' || >+ markdata->isistrl >= >+ (int)sizeof(markdata->isistr) || >+ markdata->isstrl >= (int)sizeof(markdata->isstr) - 1) >+ return; >+ markdata->isstr[markdata->isstrl++] = *p; >+ markdata->isistr[markdata->isistrl++] = *p; >+ markdata->isstr[markdata->isstrl] = 0; >+ debug2("New char: %c - left %d\n", *p, >+ (int)sizeof(markdata->isistr) - markdata->isistrl); > } >- markdata->isdir = dir; >- markdata->isistr[markdata->isistrl++] = *p; >- break; >- default: >- if (*p < ' ' || markdata->isistrl >= (int)sizeof(markdata->isistr) >- || markdata->isstrl >= (int)sizeof(markdata->isstr) - 1) >- return; >- markdata->isstr[markdata->isstrl++] = *p; >- markdata->isistr[markdata->isistrl++] = *p; >- markdata->isstr[markdata->isstrl] = 0; >- debug2("New char: %c - left %d\n", *p, (int)sizeof(markdata->isistr) - markdata->isistrl); >- } >- if (*p && *p != '\b') >- pos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), markdata->isdir); >- if (pos >= 0) >- { >- x = pos % flayer->l_width; >- y = pos / flayer->l_width; >- LAY_CALL_UP >- ( >- LayRedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0); >- revto(x, y); >- if (W2D(markdata->cy) == INPUTLINE) >- revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1); >- ); >- } >- if (*p) >- inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], markdata->isstrl ? markdata->isstr : ""); >- flayer->l_x = markdata->cx; >- flayer->l_y = W2D(markdata->cy); >- LGotoPos(flayer, flayer->l_x, flayer->l_y); >- if (!*p) >- { >+ if (*p && *p != '\b') >+ pos = is_bm(markdata->isstr, markdata->isstrl, pos, >+ flayer->l_width * >+ (markdata->md_window->w_histheight + flayer->l_height), >+ markdata->isdir); >+ if (pos >= 0) { >+ x = pos % flayer->l_width; >+ y = pos / flayer->l_width; >+ LAY_CALL_UP(LayRedisplayLine(INPUTLINE, 0, flayer -> l_width - 1, >+ 0) ; revto(x, y) ; if(W2D(markdata -> cy) == INPUTLINE) revto_line(markdata >+ -> cx, markdata -> cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1) ;); >+ } >+ if (*p) >+ inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], >+ markdata->isstrl ? markdata->isstr : ""); >+ flayer->l_x = markdata->cx; >+ flayer->l_y = W2D(markdata->cy); >+ LGotoPos(flayer, flayer->l_x, flayer->l_y); >+ if (!*p) { > /* we are about to finish, keep cursor position */ >- flayer->l_next->l_x = markdata->cx; >- flayer->l_next->l_y = W2D(markdata->cy); >- } >+ flayer->l_next->l_x = markdata->cx; >+ flayer->l_next->l_y = W2D(markdata->cy); >+ } > } > > static int >-is_redo(markdata) >-struct markdata *markdata; >+is_redo(struct markdata *markdata) > { >- int i, pos, npos, dir; >- char c; >+ int i, pos, npos, dir; >+ char c; > >- npos = pos = markdata->isstartpos; >- dir = markdata->isstartdir; >- markdata->isstrl = 0; >- for (i = 0; i < markdata->isistrl; i++) >- { >- c = markdata->isistr[i]; >- if (c == '\022') /* ^R */ >- pos += (dir = -1); >- else if (c == '\023') /* ^S */ >- pos += (dir = 1); >- else >- markdata->isstr[markdata->isstrl++] = c; >- if (pos >= 0) >- { >- npos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), dir); >- if (npos >= 0) >- pos = npos; >+ npos = pos = markdata->isstartpos; >+ dir = markdata->isstartdir; >+ markdata->isstrl = 0; >+ >+ for (i = 0; i < markdata->isistrl; i++) { >+ c = markdata->isistr[i]; >+ if (c == '\022') /* ^R */ >+ pos += (dir = -1); >+ else if (c == '\023') /* ^S */ >+ pos += (dir = 1); >+ else >+ markdata->isstr[markdata->isstrl++] = c; >+ if (pos >= 0) { >+ npos = is_bm(markdata->isstr, markdata->isstrl, pos, >+ flayer->l_width * >+ (markdata->md_window->w_histheight + >+ flayer->l_height), dir); >+ if (npos >= 0) >+ pos = npos; >+ } > } >- } >- markdata->isstr[markdata->isstrl] = 0; >- markdata->isdir = dir; >- return npos; >+ markdata->isstr[markdata->isstrl] = 0; >+ markdata->isdir = dir; >+ return npos; > } > > void >-ISearch(dir) >-int dir; >+ISearch(int dir) > { >- struct markdata *markdata; >+ struct markdata *markdata; > >- markdata = (struct markdata *)flayer->l_data; >- markdata->isdir = markdata->isstartdir = dir; >- markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width; >- markdata->isistrl = markdata->isstrl = 0; >- if (W2D(markdata->cy) == INPUTLINE) >- revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1); >- Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW, >- is_process, NULL, 0); >- LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >- flayer->l_x = markdata->cx; >- flayer->l_y = W2D(markdata->cy); >+ markdata = (struct markdata *)flayer->l_data; >+ markdata->isdir = markdata->isstartdir = dir; >+ markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width; >+ markdata->isistrl = markdata->isstrl = 0; >+ >+ if (W2D(markdata->cy) == INPUTLINE) >+ revto_line(markdata->cx, markdata->cy, >+ INPUTLINE > 0 ? INPUTLINE - 1 : 1); >+ >+ Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW, >+ is_process, NULL, 0); >+ >+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); >+ flayer->l_x = markdata->cx; >+ flayer->l_y = W2D(markdata->cy); > } > > #endif /* COPY_PASTE */ >diff -ur screen.orig/socket.c screen/socket.c >--- screen.orig/socket.c 2023-06-01 14:58:17.247665046 +0300 >+++ screen/socket.c 2022-01-28 17:06:02.698612295 +0300 >@@ -393,10 +393,11 @@ > } > if (ndead && !quietflag) > { >+ char *m = "Remove dead screens with 'screen -wipe'."; > if (wipeflag) > Msg(0, "%d socket%s wiped out.", nwipe, nwipe > 1 ? "s" : ""); > else >- Msg(0, "Remove dead screen%s with 'screen -wipe'.", ndead > 1 ? "s" : ""); >+ Msg(0, m, ndead > 1 ? "s" : "", ndead > 1 ? "" : "es"); /* other args for nethack */ > } > if (firsts != -1) > { >@@ -462,7 +463,7 @@ > # ifdef USE_SETEUID > (void) unlink(SockPath); > if (mkfifo(SockPath, SOCKMODE) < 0) >- Panic(errno, "mkfifo %s failed", SockPath); >+ Panic(0, "mkfifo %s failed", SockPath); > # ifdef BROKEN_PIPE > s = open(SockPath, O_RDWR | O_NONBLOCK, 0); > # else >@@ -753,11 +754,7 @@ > m.m_tty[sizeof(m.m_tty) - 1] = 0; > m.protocol_revision = MSG_REVISION; > debug1("SendErrorMsg(): writing to '%s'\n", SockPath); >- if (write(s, &m, sizeof(m)) < sizeof(m)) >- { >- close(s); >- return -1; >- } >+ (void) write(s, (char *) &m, sizeof m); > close(s); > return 0; > } >@@ -1879,7 +1876,7 @@ > { > char *oldrcname = rc_name; > rc_name = "-X"; >- debug3("Running command on display %p window %p (%d)\n", display, fore, fore ? fore->w_number : -1); >+ debug3("Running command on display %x window %x (%d)\n", display, fore, fore ? fore->w_number : -1); > flayer = fore ? &fore->w_layer : 0; > if (fore && fore->w_savelayer && (fore->w_blocked || fore->w_savelayer->l_cvlist == 0)) > flayer = fore->w_savelayer; >diff -ur screen.orig/teln.c screen/teln.c >--- screen.orig/teln.c 2023-06-01 14:58:17.247665046 +0300 >+++ screen/teln.c 2022-01-28 17:06:02.698612295 +0300 >@@ -280,7 +280,7 @@ > break; > } > if (l) >- memmove(p + 1, p, l); >+ bcopy(p, p + 1, l); > if (c == TC_IAC) > *p++ = c; > else if (c == '\r') >@@ -369,7 +369,7 @@ > if (free-- > 0) > { > if (len) >- memmove(rp + 1, rp, len); >+ bcopy(rp, rp + 1, len); > rp++; > *wp++ = '\r'; > } >@@ -397,7 +397,7 @@ > Msg(0, "Warning: telnet protocol overrun!"); > return; > } >- memcpy(p->w_inbuf + p->w_inlen, str, len); >+ bcopy(str, p->w_inbuf + p->w_inlen, len); > p->w_inlen += len; > } > >diff -ur screen.orig/termcap.c screen/termcap.c >--- screen.orig/termcap.c 2023-06-01 14:58:17.247665046 +0300 >+++ screen/termcap.c 2022-01-28 17:06:02.698612295 +0300 >@@ -1068,7 +1068,7 @@ > { > if (i >= T_KEYPAD) /* don't put keypad codes in TERMCAP */ > continue; /* - makes it too big */ >-#if (TERMCAP_BUF < 1024) >+#if (TERMCAP_BUFSIZE < 1024) > if (i >= T_FEXTRA && i < T_BACKTAB) /* also skip extra vt220 keys */ > continue; > if (i > T_BACKTAB && i < T_NAVIGATE) /* more vt220 keys */ >ТолÑко в screen.orig/utf8encodings: a3 >diff -ur screen.orig/utmp.c screen/utmp.c >--- screen.orig/utmp.c 2023-06-01 14:58:17.252665057 +0300 >+++ screen/utmp.c 2022-01-28 17:06:02.698612295 +0300 >@@ -505,11 +505,7 @@ > slot_t slot; > > slot = wi->w_slot; >-#ifdef GETUTENT >- debug1("RemoveUtmp slot=%p\n", slot); >-#else > debug1("RemoveUtmp slot=%#x\n", slot); >-#endif > if (!utmpok) > return -1; > if (slot == (slot_t)0 || slot == (slot_t)-1) >@@ -581,11 +577,12 @@ > #ifdef HAVE_UTEMPTER > if (eff_uid && wi && wi->w_ptyfd != -1) > { >- utempter_set_helper ("/usr/lib/screen/utempter"); /* %_libexecdir */ >+ /* sigh, linux hackers made the helper functions void */ > if (SLOT_USED(u)) >- return utempter_add_record (wi->w_ptyfd, host); >+ addToUtmp(wi->w_tty, host, wi->w_ptyfd); > else >- return utempter_remove_record (wi->w_ptyfd); >+ removeLineFromUtmp(wi->w_tty, wi->w_ptyfd); >+ return 1; /* pray for success */ > } > #endif > setutent(); >diff -ur screen.orig/window.c screen/window.c >--- screen.orig/window.c 2023-06-01 14:58:17.252665057 +0300 >+++ screen/window.c 2022-01-28 17:06:02.698612295 +0300 >@@ -979,10 +979,8 @@ > if (wp->w_type == W_TYPE_PTY) > { > /* pty 4 SALE */ >- if (fchown(wp->w_ptyfd, 0, 0) < 0) >- ; >- if (fchmod(wp->w_ptyfd, 0666) < 0) >- ; >+ (void)chmod(wp->w_tty, 0666); >+ (void)chown(wp->w_tty, 0, 0); > } > close(wp->w_ptyfd); > wp->w_ptyfd = -1; >@@ -1247,7 +1245,8 @@ > args = ShellArgs; > proc = *args; > } >- fflush(NULL); >+ fflush(stdout); >+ fflush(stderr); > switch (pid = fork()) > { > case -1: >@@ -1294,16 +1293,11 @@ > #endif > if (slave != -1) > { >- /* preserver slave across closeallfiles(), along with w_ptyfd */ >- if (dup2(slave, 0) < 0) >- Panic(errno, "ForkWindow dup2"); >- if (slave > 0) >- close(slave); >+ close(0); >+ dup(slave); >+ close(slave); > closeallfiles(win->w_ptyfd); >- if (dup2(0, slave) < 0) >- Panic(errno, "ForkWindow dup2"); >- if (slave > 0) >- close(0); >+ slave = dup(0); > } > else > closeallfiles(win->w_ptyfd); >@@ -1320,10 +1314,14 @@ > } > debug1("=== ForkWindow: pid %d\n", (int)getpid()); > #endif >+ /* Close the three /dev/null descriptors */ >+ close(0); >+ close(1); >+ close(2); >+ newfd = -1; > /* > * distribute filedescriptors between the ttys > */ >- newfd = -1; > #ifdef PSEUDOS > pat = pwin ? pwin->p_fdpat : > ((F_PFRONT<<(F_PSHIFT*2)) | (F_PFRONT<<F_PSHIFT) | F_PFRONT); >@@ -1346,13 +1344,12 @@ > if (newfd < 0) > Panic(errno, "Cannot open %s", ttyn); > } >- if (dup2(newfd, i) < 0) >- Panic(errno, "Cannot duplicate %s", ttyn); >+ else >+ dup(newfd); > } > else > { >- if (dup2(win->w_ptyfd, i) < 0) >- Panic(errno, "Cannot duplicate %s", win->w_tty); >+ dup(win->w_ptyfd); > wfdused = 1; > } > } >@@ -1375,18 +1372,13 @@ > # else > newfd = open(ttyn, O_RDWR); > # endif >- if (newfd < 0) >+ if (newfd != 0) > Panic(errno, "Cannot open %s", ttyn); >- if (dup2(newfd, 0) < 0) >- Panic(errno, "Cannot duplicate %s", ttyn); >- if (dup2(newfd, 1) < 0) >- Panic(errno, "Cannot duplicate %s", ttyn); >- if (dup2(newfd, 2) < 0) >- Panic(errno, "Cannot duplicate %s", ttyn); >+ dup(0); >+ dup(0); > #endif /* PSEUDOS */ >- if (win->w_ptyfd > 2) >- close(win->w_ptyfd); >- if (slave > 2) >+ close(win->w_ptyfd); >+ if (slave != -1) > close(slave); > if (newfd >= 0) > { >@@ -1432,8 +1424,6 @@ > /* Always turn off nonblocking mode */ > (void)fcntl(newfd, F_SETFL, 0); > } >- if (newfd > 2) >- close(newfd); > #ifndef TIOCSWINSZ > sprintf(libuf, "LINES=%d", h); > sprintf(cobuf, "COLUMNS=%d", w); >@@ -1710,10 +1700,8 @@ > } > #endif > /* should be able to use CloseDevice() here */ >- if (fchown(pwin->p_ptyfd, 0, 0) < 0) >- ; >- if (fchmod(pwin->p_ptyfd, 0666) < 0) >- ; >+ (void)chmod(pwin->p_tty, 0666); >+ (void)chown(pwin->p_tty, 0, 0); > if (pwin->p_ptyfd >= 0) > close(pwin->p_ptyfd); > evdeq(&pwin->p_readev);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 46359
: 13358 |
13359