View | Details | Raw Unified | Return to bug 46359
Collapse All | Expand All

(-)screen.orig/ansi.c (-3 / +3 lines)
Lines 727-734 Link Here
727
		  break;
727
		  break;
728
		}
728
		}
729
#  ifdef DW_CHARS
729
#  ifdef DW_CHARS
730
	      if (curr->w_encoding == UTF8 && utf8_isdouble(c))
730
		if (curr->w_encoding == UTF8 && utf8_isdouble(c))
731
		curr->w_mbcs = 0xff;
731
		  curr->w_mbcs = 0xff;
732
#  endif
732
#  endif
733
	      font = curr->w_rend.font;
733
	      font = curr->w_rend.font;
734
# endif
734
# endif
Lines 3027-3033 Link Here
3027
WMsg(p, err, str)
3027
WMsg(p, err, str)
3028
struct win *p;
3028
struct win *p;
3029
int err;
3029
int err;
3030
const char *str;
3030
char *str;
3031
{
3031
{
3032
  extern struct layer *flayer;
3032
  extern struct layer *flayer;
3033
  struct layer *oldflayer = flayer;
3033
  struct layer *oldflayer = flayer;
(-)screen.orig/attacher.c (-47 / +22 lines)
Lines 33-46 Link Here
33
#include <sys/ioctl.h>
33
#include <sys/ioctl.h>
34
#include <fcntl.h>
34
#include <fcntl.h>
35
#include <signal.h>
35
#include <signal.h>
36
#include <syslog.h>
37
#include "screen.h"
36
#include "screen.h"
38
#include "extern.h"
37
#include "extern.h"
39
38
40
#ifdef USE_PAM
41
#include <security/pam_userpass.h>
42
#endif
43
44
#include <pwd.h>
39
#include <pwd.h>
45
40
46
static int WriteMessage __P((int, struct msg *));
41
static int WriteMessage __P((int, struct msg *));
Lines 59-65 Link Here
59
#endif
54
#endif
60
static sigret_t AttachSigCont __P(SIGPROTOARG);
55
static sigret_t AttachSigCont __P(SIGPROTOARG);
61
56
62
extern int real_uid, real_gid, eff_uid, eff_gid, init_eff_gid;
57
extern int real_uid, real_gid, eff_uid, eff_gid;
63
extern int ServerSocket;
58
extern int ServerSocket;
64
extern struct display *displays;
59
extern struct display *displays;
65
extern char *SockName, *SockMatch, SockPath[];
60
extern char *SockName, *SockMatch, SockPath[];
Lines 704-710 Link Here
704
/* ADDED by Rainer Pruy 10/15/87 */
699
/* ADDED by Rainer Pruy 10/15/87 */
705
/* POLISHED by mls. 03/10/91 */
700
/* POLISHED by mls. 03/10/91 */
706
701
707
static const char LockEnd[] = "Welcome back to screen !!\n";
702
static char LockEnd[] = "Welcome back to screen !!\n";
708
703
709
static sigret_t
704
static sigret_t
710
LockHup SIGDEFARG
705
LockHup SIGDEFARG
Lines 741-747 Link Here
741
    {
736
    {
742
      signal(SIGCHLD, SIG_DFL);
737
      signal(SIGCHLD, SIG_DFL);
743
      debug1("lockterminal: '%s' seems executable, execl it!\n", prg);
738
      debug1("lockterminal: '%s' seems executable, execl it!\n", prg);
744
      fflush(NULL);
745
      if ((pid = fork()) == 0)
739
      if ((pid = fork()) == 0)
746
        {
740
        {
747
          /* Child */
741
          /* Child */
Lines 821-827 Link Here
821
815
822
#ifdef USE_PAM
816
#ifdef USE_PAM
823
817
824
#if 0
825
/*
818
/*
826
 *  PAM support by Pablo Averbuj <pablo@averbuj.com>
819
 *  PAM support by Pablo Averbuj <pablo@averbuj.com>
827
 */
820
 */
Lines 876-888 Link Here
876
    &PAM_conv,
869
    &PAM_conv,
877
    NULL
870
    NULL
878
};
871
};
879
#endif
880
872
881
static pam_userpass_t userpass;
873
882
static struct pam_conv conv = {
883
    &pam_userpass_conv,
884
    &userpass
885
};
886
#endif
874
#endif
887
875
888
/* -- original copyright by Luigi Cannelloni 1985 (luigi@faui70.UUCP) -- */
876
/* -- original copyright by Luigi Cannelloni 1985 (luigi@faui70.UUCP) -- */
Lines 891-900 Link Here
891
{
879
{
892
  char fullname[100], *cp1, message[100 + 100];
880
  char fullname[100], *cp1, message[100 + 100];
893
#ifdef USE_PAM
881
#ifdef USE_PAM
894
  int status;
882
  pam_handle_t *pamh = 0;
895
  pam_handle_t *pamh = NULL;
883
  int pam_error;
896
#else
884
  char *tty_name;
897
  char *pass, mypass[16 + 1], salt[3];
898
#endif
885
#endif
899
  char *pass = 0, mypass[16 + 1], salt[3];
886
  char *pass = 0, mypass[16 + 1], salt[3];
900
  int using_pam = 1;
887
  int using_pam = 1;
Lines 976-1010 Link Here
976
      if (using_pam)
963
      if (using_pam)
977
        {
964
        {
978
#ifdef USE_PAM
965
#ifdef USE_PAM
979
      userpass.user = ppp->pw_name;
966
      PAM_conversation.appdata_ptr = cp1;
980
      userpass.pass = cp1;
967
      pam_error = pam_start("screen", ppp->pw_name, &PAM_conversation, &pamh);
981
968
      if (pam_error != PAM_SUCCESS)
982
      openlog("screen", LOG_PID, LOG_AUTH);
969
	AttacherFinit(SIGARG);		/* goodbye */
983
      status = pam_start("screen", ppp->pw_name, &conv, &pamh);
984
985
      if (status == PAM_SUCCESS)
986
	{
987
	  /* Let the PAM modules make use of our SGID privileges. */
988
	  xsetegid(init_eff_gid);
989
	  if ((status = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
990
            {
991
	       xsetegid(real_gid);
992
	       pam_end(pamh, status);
993
	       continue;
994
	    }
995
	  xsetegid(real_gid);
996
970
997
	  status = pam_end(pamh, PAM_SUCCESS);
971
      if (strncmp(attach_tty, "/dev/", 5) == 0)
998
	  if (status == PAM_SUCCESS)
972
	tty_name = attach_tty + 5;
999
	    {
973
      else
1000
	       memset(cp1, 0, strlen(cp1));
974
	tty_name = attach_tty;
1001
	       userpass.pass = NULL;
975
      pam_error = pam_set_item(pamh, PAM_TTY, tty_name);
1002
	       break;
976
      if (pam_error != PAM_SUCCESS)
1003
	    }
977
	AttacherFinit(SIGARG);		/* goodbye */
1004
	}
978
1005
979
      pam_error = pam_authenticate(pamh, 0);
1006
#else
980
      pam_end(pamh, pam_error);
1007
      if (!strncmp(crypt(cp1, pass), pass, strlen(pass)))
981
      PAM_conversation.appdata_ptr = 0;
982
      if (pam_error == PAM_SUCCESS)
1008
	break;
983
	break;
1009
#endif
984
#endif
1010
        }
985
        }
(-)screen.orig/autogen.sh (-1 / +1 lines)
Lines 1-2 Link Here
1
#!/bin/sh
1
#!/bin/sh
2
exec autoreconf
2
autoreconf -i
(-)screen.orig/braille_tsi.c (-215 / +210 lines)
Lines 6-12 Link Here
6
 *                Bill Barry         barryb@dots.physics.orst.edu
6
 *                Bill Barry         barryb@dots.physics.orst.edu
7
 *
7
 *
8
 * Copyright (c) 1995 by Science Access Project, Oregon State University.
8
 * Copyright (c) 1995 by Science Access Project, Oregon State University.
9
 *      
9
 *
10
 *
10
 *
11
 * This program is free software; you can redistribute it and/or modify
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
12
 * it under the terms of the GNU General Public License as published by
Lines 36-56 Link Here
36
extern struct display *display;
36
extern struct display *display;
37
37
38
struct key2rc {
38
struct key2rc {
39
  int key;
39
	int key;
40
  int nr;
40
	int nr;
41
  char *arg1;
41
	char *arg1;
42
  char *arg2;
42
	char *arg2;
43
};
43
};
44
44
45
static int  tsi_ctype = 1;       /* cursor type, 0,1,2 */
45
46
46
static int tsi_ctype = 1;        /* cursor type, 0,1,2 */
47
static int  tsi_line_type; /* indicates number of cells on powerbraille
47
48
                              display 01=20 cells 02=40 cells 03=80 cells */
48
static int tsi_line_type; /* indicates number of cells on powerbraille
49
                          display 01=20 cells 02=40 cells 03=80 cells */
50
49
51
static int  display_status_tsi __P((void));
50
static int  display_status_tsi __P((void));
52
static int  write_line_tsi __P((char *, int, int));
51
static int  write_line_tsi __P((char*, int, int));
53
static void buttonpress_tsi __P((struct key2rc *));
52
static void buttonpress_tsi __P((structkey2rc*));
54
static void buttonpress_navigator_40 __P((void));
53
static void buttonpress_navigator_40 __P((void));
55
static void buttonpress_powerbraille_40 __P((void));
54
static void buttonpress_powerbraille_40 __P((void));
56
static void buttonpress_powerbraille_80 __P((void));
55
static void buttonpress_powerbraille_80 __P((void));
Lines 58-319 Link Here
58
int
57
int
59
bd_init_powerbraille_40()
58
bd_init_powerbraille_40()
60
{
59
{
61
  bd.write_line_braille = write_line_tsi;
60
	bd.write_line_braille = write_line_tsi;
62
  bd.buttonpress = buttonpress_powerbraille_40;
61
	bd.buttonpress = buttonpress_powerbraille_40;
63
  bd.bd_response_test = display_status_tsi;
62
	bd.bd_response_test = display_status_tsi;
64
  bd.bd_ncells = 40;
63
	bd.bd_ncells = 40;
65
  tsi_line_type = 2;
64
	tsi_line_type = 2;
66
  return 0;
65
	return 0;
67
}
66
}
68
67
69
int
68
int
70
bd_init_powerbraille_80()
69
bd_init_powerbraille_80()
71
{
70
{
72
  bd.write_line_braille = write_line_tsi;
71
	bd.write_line_braille = write_line_tsi;
73
  bd.buttonpress = buttonpress_powerbraille_80;
72
	bd.buttonpress = buttonpress_powerbraille_80;
74
  bd.bd_response_test = display_status_tsi;
73
	bd.bd_response_test = display_status_tsi;
75
  bd.bd_ncells = 80;
74
	bd.bd_ncells = 80;
76
  tsi_line_type = 3;
75
	tsi_line_type = 3;
77
  return 0;
76
	return 0;
78
}
77
}
79
78
80
int
79
int
81
bd_init_navigator_40()
80
bd_init_navigator_40()
82
{
81
{
83
  bd.write_line_braille = write_line_tsi;
82
	bd.write_line_braille = write_line_tsi;
84
  bd.buttonpress = buttonpress_navigator_40;
83
	bd.buttonpress = buttonpress_navigator_40;
85
  bd.bd_response_test = display_status_tsi;
84
	bd.bd_response_test = display_status_tsi;
86
  bd.bd_ncells = 40;
85
	bd.bd_ncells = 40;
87
  tsi_line_type = 2;
86
	tsi_line_type = 2;
88
  return 0;
87
	return 0;
89
}
88
}
90
89
91
static int 
90
static int
92
display_status_tsi()
91
display_status_tsi()
93
{
92
{
94
  char obuf[3],ibuf[20];
93
	char obuf[3], ibuf[20];
95
  int r;
94
	int r;
96
95
97
  obuf[0] = 0xff;
96
	obuf[0] = 0xff;
98
  obuf[1] = 0xff;
97
	obuf[1] = 0xff;
99
  obuf[2] = 0x0a;
98
	obuf[2] = 0x0a;
100
  r = read(bd.bd_fd, ibuf, 20);		/* flush the input port */
99
	r = read(bd.bd_fd, ibuf, 20);		/* flush the input port */
101
  r = write(bd.bd_fd, obuf, 3);
100
	r = write(bd.bd_fd, obuf, 3);
102
  if (r != 3)
101
	if (r != 3)
103
    return -1;
102
		return -1;
104
103
105
  /* we have written to the display asking for a response
104
  /* we have written to the display asking for a response
106
     we wait 1 second for the response, read it and if no 
105
     we wait 1 second for the response, read it and if no
107
     response we wait 2 seconds, if still no response,
106
     response we wait 2 seconds, if still no response,
108
     return -1 to indicate no braille  display available */
107
     return -1 to indicate no braille  display available */
109
  sleep(1);
108
110
  r = read(bd.bd_fd, ibuf, 2);
109
	sleep(1);
111
  if (r == -1)
110
	r = read(bd.bd_fd, ibuf, 2);
112
    {
111
	if (r == -1) {
113
      sleep(2);
112
		sleep(2);
114
      r = read(bd.bd_fd, ibuf, 2);
113
		r = read(bd.bd_fd, ibuf, 2);
115
    }
114
	}
116
  debug2("first chars from braille display %d %d\n",ibuf[0],ibuf[1]);
115
117
  if (r != 2 || ibuf[0] != 0 || ibuf[1] != 5)
116
	debug2("first chars from braille display %d %d\n", ibuf[0], ibuf[1]);
118
    return -1;
117
	if (r != 2 || ibuf[0] != 0 || ibuf[1] != 5)
119
  
118
		return -1;
120
  r= read(bd.bd_fd,ibuf,2);
119
121
  if (r != 2)
120
	r = read(bd.bd_fd, ibuf, 2);
122
    return -1;
121
	if (r != 2)
123
  debug2("braille display size:%d dots:%d\n", ibuf[0], ibuf[1]);
122
		return -1;
124
  bd.bd_ncells = (unsigned char)ibuf[0];
123
125
  if (bd.bd_ncells <= 1)
124
	debug2("braille display size:%d dots:%d\n", ibuf[0], ibuf[1]);
126
    return -1;
125
	bd.bd_ncells = (unsigned char)ibuf[0];
127
  r = read(bd.bd_fd,ibuf,1);
126
	if (bd.bd_ncells <= 1)
128
  if (r != 1)
127
		return -1;
129
    return -1;
128
130
  if (ibuf[0] == 'V')
129
	r = read(bd.bd_fd, ibuf, 1);
131
    r = read(bd.bd_fd, ibuf, 3);
130
	if (r != 1)
132
  else
131
		return -1;
133
    r = read(bd.bd_fd, ibuf + 1, 2) + 1;
132
134
  if (r != 3)
133
	if (ibuf[0] == 'V')
135
    return -1;
134
		r = read(bd.bd_fd, ibuf, 3);
136
  ibuf[3] = 0;
135
	else
137
  debug1("braille display version %s\n", ibuf); 
136
		r = read(bd.bd_fd, ibuf + 1, 2) + 1;
138
  bd.bd_version = atof(ibuf);
137
139
  return 0;
138
	if (r != 3)
139
		return -1;
140
141
	ibuf[3] = 0;
142
	debug1("braille display version %s\n", ibuf);
143
	bd.bd_version = atof(ibuf);
144
	return 0;
140
}
145
}
141
		
142
146
143
static int 
147
static int
144
write_line_tsi (bstr,line_length,  cursor_pos) 
148
write_line_tsi(char *bstr, int line_length, int cursor_pos)
145
char *bstr;
146
int line_length, cursor_pos; 
147
{
149
{
148
  int obp, i;
150
	int obp, i;
149
  bd.bd_obuf[0] = 0xff;
151
	bd.bd_obuf[0] = 0xff;
150
  bd.bd_obuf[1] = 0xff;
152
	bd.bd_obuf[1] = 0xff;
151
  bd.bd_obuf[2] = tsi_line_type;
153
	bd.bd_obuf[2] = tsi_line_type;
152
  bd.bd_obuf[3] = 0x07;
154
	bd.bd_obuf[3] = 0x07;
153
  bd.bd_obuf[4] = cursor_pos;
155
	bd.bd_obuf[4] = cursor_pos;
154
  bd.bd_obuf[5] = tsi_ctype;
156
	bd.bd_obuf[5] = tsi_ctype;
155
  obp=6;
157
	obp = 6;
156
158
157
  for (i=0; i < line_length; i++) 
159
	for (i = 0; i < line_length; i++) {
158
    {
160
		bd.bd_obuf[2*i + obp] = 0;
159
      bd.bd_obuf[2*i+obp] = 0; 
161
		bd.bd_obuf[2*i + 1 + obp] = bd.bd_btable[(int)(unsigned char)bstr[i]];
160
      bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)(unsigned char)bstr[i]];
162
	}
161
    }      
163
	for (i = line_length; i < bd.bd_ncells; i++) {
162
  for (i=line_length; i < bd.bd_ncells; i++) 
164
		bd.bd_obuf[2*i + obp] = 0;
163
    {
165
		bd.bd_obuf[2*i + 1 + obp] = bd.bd_btable[(int)' '];
164
      bd.bd_obuf[2*i+obp] = 0; 
166
	}
165
      bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)' '];
166
    }      
167
167
168
  bd.bd_obuflen = 2*bd.bd_ncells + obp ;  
168
	bd.bd_obuflen = 2*bd.bd_ncells + obp;
169
  return 0;
169
	return 0;
170
}
170
}
171
171
172
static struct key2rc keys_navigator_40[] = {
172
static struct key2rc keys_navigator_40[] = {
173
  {0x4000000,	RC_STUFF, "-k", "kl"},		/* 1 */
173
	{0x4000000,     RC_STUFF,          "-k", "kl"}, /* 1 */
174
  {0x10000000, 	RC_STUFF, "-k", "kr"},		/* 3 */
174
	{0x10000000,    RC_STUFF,          "-k", "kr"}, /* 3 */
175
  {0x8000000,	RC_STUFF, "-k", "ku"},		/* 2 */
175
	{0x8000000,     RC_STUFF,          "-k", "ku"}, /* 2 */
176
  {0x20000000,	RC_STUFF, "-k", "kd"},		/* 4 */
176
	{0x20000000,    RC_STUFF,          "-k", "kd"}, /* 4 */
177
  {0x2000,	RC_BD_BC_LEFT, 0, 0},		/* 6 */
177
	{0x2000,        RC_BD_BC_LEFT,     0,       0}, /* 6 */
178
  {0x8000,	RC_BD_BC_RIGHT, 0, 0},		/* 8 */
178
	{0x8000,        RC_BD_BC_RIGHT,    0,       0}, /* 8 */
179
  {0x4000,	RC_BD_BC_UP, 0, 0},		/* 7 */
179
	{0x4000,        RC_BD_BC_UP,       0,       0}, /* 7 */
180
  {0x10000,	RC_BD_BC_DOWN, 0, 0},		/* 9 */
180
	{0x10000,       RC_BD_BC_DOWN,     0,       0}, /* 9 */
181
  {0x6000,	RC_BD_UPPER_LEFT, 0, 0},	/* 6, 7 */
181
	{0x6000,        RC_BD_UPPER_LEFT,  0,       0}, /* 6, 7 */
182
  {0xc000,	RC_BD_UPPER_RIGHT, 0, 0},	/* 7, 8 */
182
	{0xc000,        RC_BD_UPPER_RIGHT, 0,       0}, /* 7, 8 */
183
  {0x12000,	RC_BD_LOWER_LEFT, 0, 0},	/* 6, 9 */
183
	{0x12000,       RC_BD_LOWER_LEFT,  0,       0}, /* 6, 9 */
184
  {0x18000,	RC_BD_LOWER_RIGHT, 0, 0},	/* 8, 9 */
184
	{0x18000,       RC_BD_LOWER_RIGHT, 0,       0}, /* 8, 9 */
185
  {0xa000,	RC_BD_INFO, "1032", 0},		/* bc 6, 8 */
185
	{0xa000,        RC_BD_INFO,        "1032",  0}, /* bc 6, 8 */
186
  {0x14000000,	RC_BD_INFO, "2301", 0},		/* sc 1, 3 */
186
	{0x14000000,    RC_BD_INFO,        "2301",  0}, /* sc 1, 3 */
187
  {0x4008000,	RC_BD_INFO, "3330", 0},		/* bc+sc 1, 8 */
187
	{0x4008000,     RC_BD_INFO,        "3330",  0}, /* bc+sc 1, 8 */
188
  {0x8010000,	RC_BD_BELL, 0, 0},		/* 2, 9 */
188
	{0x8010000,     RC_BD_BELL,        0,       0}, /* 2, 9 */
189
  {0x8004000,	RC_BD_EIGHTDOT, 0, 0},		/* 2, 7 */
189
	{0x8004000,     RC_BD_EIGHTDOT,    0,       0}, /* 2, 7 */
190
  {0x40000000,	RC_STUFF, "\015", 0},		/* 5 */
190
	{0x40000000,    RC_STUFF,          "\015",  0}, /* 5 */
191
  {0x20000,	RC_BD_LINK, 0, 0},		/* 10 */
191
	{0x20000,       RC_BD_LINK,        0,       0}, /* 10 */
192
  {0x10002000,	RC_BD_SCROLL, 0, 0},		/* 3, 6 */
192
	{0x10002000,    RC_BD_SCROLL,      0,       0}, /* 3, 6 */
193
  {0x20010000,	RC_BD_NCRC, "+", 0},		/* 4, 9 */
193
	{0x20010000,    RC_BD_NCRC,        "+",     0}, /* 4, 9 */
194
  {0x14000,	RC_BD_SKIP, 0, 0},		/* 7, 9*/
194
	{0x14000,       RC_BD_SKIP,        0,       0}, /* 7, 9*/
195
  {-1,		RC_ILLEGAL, 0, 0}
195
	{-1,            RC_ILLEGAL,        0,       0}
196
};
196
};
197
197
198
static struct key2rc keys_powerbraille_40[] = {
198
static struct key2rc keys_powerbraille_40[] = {
199
  {0x4000000,	RC_STUFF, "-k", "kl"},		/* 1 */
199
	{0x4000000,     RC_STUFF,          "-k", "kl"}, /* 1 */
200
  {0x10000000, 	RC_STUFF, "-k", "kr"},		/* 3 */
200
	{0x10000000,    RC_STUFF,          "-k", "kr"}, /* 3 */
201
  {0x8000000,	RC_STUFF, "-k", "ku"},		/* 2 */
201
	{0x8000000,     RC_STUFF,          "-k", "ku"}, /* 2 */
202
  {0x20000000,	RC_STUFF, "-k", "kd"},		/* 4 */
202
	{0x20000000,    RC_STUFF,          "-k", "kd"}, /* 4 */
203
  {0x2000,	RC_BD_BC_LEFT, 0, 0},		/* 6 */
203
	{0x2000,        RC_BD_BC_LEFT,     0,       0}, /* 6 */
204
  {0x8000,	RC_BD_BC_RIGHT, 0, 0},		/* 8 */
204
	{0x8000,        RC_BD_BC_RIGHT,    0,       0}, /* 8 */
205
  {0x4000,	RC_BD_BC_UP, 0, 0},		/* 7 */
205
	{0x4000,        RC_BD_BC_UP,       0,       0}, /* 7 */
206
  {0x10000,	RC_BD_BC_DOWN, 0, 0},		/* 9 */
206
	{0x10000,       RC_BD_BC_DOWN,     0,       0}, /* 9 */
207
  {0x8002000,	RC_BD_UPPER_LEFT, 0, 0},	/* 2, 6 */
207
	{0x8002000,     RC_BD_UPPER_LEFT,  0,       0}, /* 2, 6 */
208
  {0xc000,	RC_BD_UPPER_RIGHT, 0, 0},	/* 7, 8 */
208
	{0xc000,        RC_BD_UPPER_RIGHT, 0,       0}, /* 7, 8 */
209
  {0x20002000,	RC_BD_LOWER_LEFT, 0, 0},	/* 3, 6 */
209
	{0x20002000,    RC_BD_LOWER_LEFT,  0,       0}, /* 3, 6 */
210
  {0x18000,	RC_BD_LOWER_RIGHT, 0, 0},	/* 8, 9 */
210
	{0x18000,       RC_BD_LOWER_RIGHT, 0,       0}, /* 8, 9 */
211
  {0x8008000,	RC_BD_INFO, "1032", 0},		/* bc 2, 8 */
211
	{0x8008000,     RC_BD_INFO,        "1032",  0}, /* bc 2, 8 */
212
  {0x6000,	RC_BD_INFO, "2301", 0},		/* 6, 7 */
212
	{0x6000,        RC_BD_INFO,        "2301",  0}, /* 6, 7 */
213
  {0x8004000,	RC_BD_INFO, "3330", 0},		/* bc+sc 2, 7 */
213
	{0x8004000,     RC_BD_INFO,        "3330",  0}, /* bc+sc 2, 7 */
214
  {0x8010000,	RC_BD_BELL, 0, 0},		/* 2, 9 */
214
	{0x8010000,     RC_BD_BELL,        0,       0}, /* 2, 9 */
215
  {0x20008000,	RC_BD_EIGHTDOT, 0, 0},		/* 4, 6 */
215
	{0x20008000,    RC_BD_EIGHTDOT,    0,       0}, /* 4, 6 */
216
  {0x40000000,	RC_STUFF, "\015", 0},		/* 5 */
216
	{0x40000000,    RC_STUFF,          "\015",  0}, /* 5 */
217
  {0x20000,	RC_BD_LINK, 0, 0},		/* 10 */
217
	{0x20000,       RC_BD_LINK,        0,       0}, /* 10 */
218
  {0xa000,	RC_BD_SCROLL, 0, 0},		/* 6, 8 */
218
	{0xa000,        RC_BD_SCROLL,      0,       0}, /* 6, 8 */
219
  {0x20010000,	RC_BD_NCRC, "+", 0},		/* 4, 9 */
219
	{0x20010000,    RC_BD_NCRC,        "+",     0}, /* 4, 9 */
220
  {0x20004000,	RC_BD_SKIP, 0, 0},		/* 4, 7 */
220
	{0x20004000,    RC_BD_SKIP,        0,       0}, /* 4, 7 */
221
  {-1,		RC_ILLEGAL, 0, 0}
221
	{-1,            RC_ILLEGAL,        0,       0}
222
};
222
};
223
223
224
225
static struct key2rc keys_powerbraille_80[] = {
224
static struct key2rc keys_powerbraille_80[] = {
226
  {0x4000000,	RC_STUFF, "-k", "kl"},		/* 1 */
225
	{0x4000000,     RC_STUFF,          "-k", "kl"}, /* 1 */
227
  {0x10000000, 	RC_STUFF, "-k", "kr"},		/* 3 */
226
	{0x10000000,    RC_STUFF,          "-k", "kr"}, /* 3 */
228
  {0x8000000,	RC_STUFF, "-k", "ku"},		/* 2 */
227
	{0x8000000,     RC_STUFF,          "-k", "ku"}, /* 2 */
229
  {0x20000000,	RC_STUFF, "-k", "kd"},		/* 4 */
228
	{0x20000000,    RC_STUFF,          "-k", "kd"}, /* 4 */
230
  {0x40000,	RC_BD_BC_LEFT, 0, 0},		/* 6 */
229
	{0x40000,       RC_BD_BC_LEFT,     0,       0}, /* 6 */
231
  {0x100000,	RC_BD_BC_RIGHT, 0, 0},		/* 8 */
230
	{0x100000,      RC_BD_BC_RIGHT,    0,       0}, /* 8 */
232
  {0x4000,	RC_BD_BC_UP, 0, 0},		/* 7 */
231
	{0x4000,        RC_BD_BC_UP,       0,       0}, /* 7 */
233
  {0x10000,	RC_BD_BC_DOWN, 0, 0},		/* 9 */
232
	{0x10000,       RC_BD_BC_DOWN,     0,       0}, /* 9 */
234
  {0x44000,	RC_BD_UPPER_LEFT, 0, 0},	/* 6, 7 */
233
	{0x44000,       RC_BD_UPPER_LEFT,  0,       0}, /* 6, 7 */
235
  {0x104000,	RC_BD_UPPER_RIGHT, 0, 0},	/* 7, 8 */
234
	{0x104000,      RC_BD_UPPER_RIGHT, 0,       0}, /* 7, 8 */
236
  {0x50000,	RC_BD_LOWER_LEFT, 0, 0},	/* 6, 9 */
235
	{0x50000,       RC_BD_LOWER_LEFT,  0,       0}, /* 6, 9 */
237
  {0x110000,	RC_BD_LOWER_RIGHT, 0, 0},	/* 8, 9 */
236
	{0x110000,      RC_BD_LOWER_RIGHT, 0,       0}, /* 8, 9 */
238
  {0x8100000,	RC_BD_INFO, "1032", 0},		/* 2, 8 */
237
	{0x8100000,     RC_BD_INFO,        "1032",  0}, /* 2, 8 */
239
  {0x8040000,	RC_BD_INFO, "2301", 0},		/* 2, 6 */
238
	{0x8040000,     RC_BD_INFO,        "2301",  0}, /* 2, 6 */
240
  {0x140000,	RC_BD_INFO, "3330", 0},		/* 6, 8 */
239
	{0x140000,      RC_BD_INFO,        "3330",  0}, /* 6, 8 */
241
  {0x8010000,	RC_BD_BELL, 0, 0},		/* 2, 9 */
240
	{0x8010000,     RC_BD_BELL,        0,       0}, /* 2, 9 */
242
  {0x8004000,	RC_BD_EIGHTDOT, 0, 0},		/* 2, 7 */
241
	{0x8004000,     RC_BD_EIGHTDOT,    0,       0}, /* 2, 7 */
243
  {0x40000000,	RC_STUFF, "\015", 0},		/* 5 */
242
	{0x40000000,    RC_STUFF,          "\015",  0}, /* 5 */
244
  {0x20000,	RC_BD_LINK, 0, 0},		/* 10 */
243
	{0x20000,       RC_BD_LINK,        0,       0}, /* 10 */
245
  {0x20004000,	RC_BD_SCROLL, 0, 0},		/* 4, 7 */
244
	{0x20004000,    RC_BD_SCROLL,      0,       0}, /* 4, 7 */
246
  {0x20010000,	RC_BD_NCRC, "+", 0},		/* 4, 9 */
245
	{0x20010000,    RC_BD_NCRC,        "+",     0}, /* 4, 9 */
247
  {0x40010000,	RC_BD_SKIP, 0, 0},		/* 5, 9 */
246
	{0x40010000,    RC_BD_SKIP,        0,       0}, /* 5, 9 */
248
  {-1,		RC_ILLEGAL, 0, 0}
247
	{-1,            RC_ILLEGAL,        0,       0}
249
};
248
};
250
249
251
static void
250
static void
252
buttonpress_tsi(tab)
251
buttonpress_tsi(struct key2rc *tab)
253
struct key2rc *tab;
254
{
252
{
255
  int i, nb;
253
	int i, nb;
256
  int bkeys;
254
	int bkeys;
257
  unsigned char buf[10];
255
	unsigned char buf[10];
258
  nb = read(bd.bd_fd, buf, 10);
256
	nb = read(bd.bd_fd, buf, 10);
259
  debug1("buttonpress_tsi: read %d bytes\n", nb);
257
	debug1("buttonpress_tsi: read %d bytes\n", nb);
260
  for (i=0, bkeys=0; i < nb; i++)
258
	for (i = 0, bkeys = 0; i < nb; i++) {
261
    {   
259
		switch (buf[i] & 0xE0) {
262
      switch (buf[i] & 0xE0)
260
			case 0x00: bkeys += ((int)(buf[i] & 0x1f)); break;
263
	{
261
			case 0x20: bkeys += ((int)(buf[i] & 0x1f) << 5); break;
264
	case 0x00: bkeys += ((int)(buf[i] & 0x1f)       );  break;
262
			case 0x40: bkeys += ((int)(buf[i] & 0x1f) << 9); break;
265
	case 0x20: bkeys += ((int)(buf[i] & 0x1f) <<  5 );  break;
263
			case 0x60: bkeys += ((int)(buf[i] & 0x1f) << 13); break;
266
	case 0x40: bkeys += ((int)(buf[i] & 0x1f) <<  9 );  break;
264
			case 0xA0: bkeys += ((int)(buf[i] & 0x1f) << 18); break;
267
	case 0x60: bkeys += ((int)(buf[i] & 0x1f) <<  13 ); break;
265
			case 0xC0: bkeys += ((int)(buf[i] & 0x1f) << 22); break;
268
	case 0xA0: bkeys += ((int)(buf[i] & 0x1f) <<  18 ); break;
266
			case 0xE0: bkeys += ((int)(buf[i] & 0x1f) << 26); break;
269
	case 0xC0: bkeys += ((int)(buf[i] & 0x1f) <<  22 ); break;
267
			default: break;
270
	case 0xE0: bkeys += ((int)(buf[i] & 0x1f) <<  26 ); break;
268
		}
271
	default: break;
272
	}
269
	}
273
    }
270
	debug1("bkeys %x\n", bkeys);
274
  debug1("bkeys %x\n", bkeys);
275
  for (i = 0; tab[i].key != -1; i++)
276
    if (bkeys == tab[i].key)
277
      break;
278
  debug1("bkey index %d\n", i);
279
  if (tab[i].key != -1 && tab[i].nr != RC_ILLEGAL)
280
    {
281
      char *args[3];
282
      int argl[2];
283
      
284
      struct action act;
285
      args[0] = tab[i].arg1;
286
      args[1] = tab[i].arg2;
287
      args[2] = 0;
288
      argl[0] = args[0] ? strlen(args[0]) : 0;
289
      argl[1] = args[1] ? strlen(args[1]) : 0;
290
      act.nr = tab[i].nr;
291
      act.args = args;
292
      act.argl = argl;
293
      display = bd.bd_dpy;
294
      DoAction(&act, -2);
295
    }
296
}
297
271
272
	for (i = 0; tab[i].key != -1; i++)
273
		if (bkeys == tab[i].key)
274
			break;
275
276
	debug1("bkey index %d\n", i);
277
278
	if (tab[i].key != -1 && tab[i].nr != RC_ILLEGAL) {
279
		char *args[3];
280
		int argl[2];
281
282
		struct action act;
283
		args[0] = tab[i].arg1;
284
		args[1] = tab[i].arg2;
285
		args[2] = 0;
286
		argl[0] = args[0] ? strlen(args[0]) : 0;
287
		argl[1] = args[1] ? strlen(args[1]) : 0;
288
		act.nr = tab[i].nr;
289
		act.args = args;
290
		act.argl = argl;
291
		display = bd.bd_dpy;
292
		DoAction(&act, -2);
293
	}
294
}
298
295
299
static void
296
static void
300
buttonpress_navigator_40()
297
buttonpress_navigator_40()
301
{
298
{
302
  buttonpress_tsi(keys_navigator_40);
299
	buttonpress_tsi(keys_navigator_40);
303
}
300
}
304
301
305
static void
302
static void
306
buttonpress_powerbraille_40()
303
buttonpress_powerbraille_40()
307
{
304
{
308
  buttonpress_tsi(keys_powerbraille_40);
305
	buttonpress_tsi(keys_powerbraille_40);
309
}
306
}
310
307
311
static void
308
static void
312
buttonpress_powerbraille_80()
309
buttonpress_powerbraille_80()
313
{
310
{
314
  buttonpress_tsi(keys_powerbraille_80);
311
	buttonpress_tsi(keys_powerbraille_80);
315
}
312
}
316
313
317
#endif /* HAVE_BRAILLE */
314
#endif /* HAVE_BRAILLE */
318
319
(-)screen.orig/ChangeLog (-21 / +29 lines)
Lines 1-18 Link Here
1
Version 4.8.0 (05/02/2020)
1
Version 4.9.0 (30/01/2022):
2
  * Hardstatus option for used encoding (escape string '%e')
3
  * OpenBSD uses native openpty() from its utils.h
4
  * Fixes:
5
    - fix combining char handling that could lead to a segfault
6
    - CVE-2021-26937: possible denial of service via a crafted UTF-8 character sequence (bug #60030)
7
    - make screen exit code be 0 when checking --help
8
    - session names limit is 80 symbols (bug #61534)
9
    - option -X ignores specified user in multiuser env (bug #37437)
10
    - a lot of reformations/fixes/cleanups (man page and source code)
11
12
Version 4.8.0 (05/02/2020):
2
  * Improve startup time by only polling for files to close
13
  * Improve startup time by only polling for files to close
3
  Fixes:
14
  * Fixes:
4
	- Fix for segfault if termcap doesn't have Km entry
15
	- Fix for segfault if termcap doesn't have Km entry
5
	- Make screen exit code be 0 when checking --version
16
	- Make screen exit code be 0 when checking --version
6
	- Fix potential memory corruption when using OSC 49
17
	- Fix potential memory corruption when using OSC 49
7
18
8
19
Version 4.7.0 (02/10/2019):
9
Version 4.7.0 (02/10/2019)
10
  * Add support for SGR (1006) mouse mode
20
  * Add support for SGR (1006) mouse mode
11
  * Add support for OSC 11
21
  * Add support for OSC 11
12
  * Update Unicode ambiguous and wide tables to 12.1.0
22
  * Update Unicode ambiguous and wide tables to 12.1.0
13
  * Fixes:
23
  * Fixes:
14
  - cross-compilation support (bug #43223)
24
	- cross-compilation support (bug #43223)
15
  - a lot of manpage fixes and cleanups
25
	- a lot of manpage fixes and cleanups
16
26
17
Version 4.6.2 (23/10/2017):
27
Version 4.6.2 (23/10/2017):
18
  * Fixes:
28
  * Fixes:
Lines 62-73 Link Here
62
  * Introduce Xx string escape showing the executed command of a window
72
  * Introduce Xx string escape showing the executed command of a window
63
  * Implement dead/zombie window polling, allowing for auto reconnecting
73
  * Implement dead/zombie window polling, allowing for auto reconnecting
64
  * Allow setting hardstatus on first line
74
  * Allow setting hardstatus on first line
65
75
  * New Commands:
66
  New Commands:
76
	- 'sort' command sorting windows by title
67
  * 'sort' command sorting windows by title
77
	- 'bumpleft', 'bumpright' - manually move windows on window list
68
  * 'bumpleft', 'bumpright' - manually move windows on window list
78
	- 'collapse' removing numbering 'gaps' between windows, by renumbering
69
  * 'collapse' removing numbering 'gaps' between windows, by renumbering
79
	- 'windows' command now accepts arguments for use with querying
70
  * 'windows' command now accepts arguments for use with querying
71
80
72
Version 4.2.1 (28/04/2014):
81
Version 4.2.1 (28/04/2014):
73
  * allow for terminal with long $TERM (up to 32 characters)
82
  * allow for terminal with long $TERM (up to 32 characters)
Lines 79-86 Link Here
79
  New Commands:
88
  New Commands:
80
  * 'unbindall' to unbind all commands
89
  * 'unbindall' to unbind all commands
81
  * 'up', 'down', 'left', 'right' sub-commands for 'focus'
90
  * 'up', 'down', 'left', 'right' sub-commands for 'focus'
82
  * 'rendition' to specify rendition to use in caption/hardstatus for
91
  * 'rendition' to specify rendition to use in caption/hardstatus for window-names that have bell/monitor/silence/so turned on.
83
    window-names that have bell/monitor/silence/so turned on.
84
  * 'layout', with the following sub-commands
92
  * 'layout', with the following sub-commands
85
	- 'title'
93
	- 'title'
86
	- 'number'
94
	- 'number'
Lines 372-379 Link Here
372
=======================
380
=======================
373
381
374
.screenrc:
382
.screenrc:
375
  screen now only opens the windows you explicitly ask for. if you 
383
  screen now only opens the windows you explicitly ask for.
376
  specify none, you still get one window, of course.
384
  If you specify none, you still get one window, of course.
377
385
378
screen 3.0. Patchlevel 5
386
screen 3.0. Patchlevel 5
379
========================
387
========================
Lines 391-397 Link Here
391
  by a colon. Oldchar and newchar are either single ascii characters, 
399
  by a colon. Oldchar and newchar are either single ascii characters, 
392
  or the two character sequence ^x, where x is an ascii character, or
400
  or the two character sequence ^x, where x is an ascii character, or
393
  a 3 digit octal value prepended with '\'. the string "\040=.:^M=q"
401
  a 3 digit octal value prepended with '\'. the string "\040=.:^M=q"
394
  rebinds '.' to set marks, and the return rey will abort copy mode.
402
  rebinds '.' to set marks, and the return key will abort copy mode.
395
403
396
set scrollback 100
404
set scrollback 100
397
  resizes the scrollback history buffer to 100 lines. a default of 50
405
  resizes the scrollback history buffer to 100 lines. a default of 50
Lines 426-432 Link Here
426
434
427
^A : set vbell_msg "Wuff Wuff"
435
^A : set vbell_msg "Wuff Wuff"
428
436
429
Thousand enhancements: help resizible, copy'n'paste in main
437
Thousand enhancements: help resizable, copy'n'paste in main
430
  socket loop, and no more '\0' hackin'. :WS=\E8;%d;%dt:
438
  socket loop, and no more '\0' hackin'. :WS=\E8;%d;%dt:
431
439
432
screen can now resize windows under sunview.
440
screen can now resize windows under sunview.
Lines 454-465 Link Here
454
  bind 'O' set login off
462
  bind 'O' set login off
455
  is valid in your .screenrc as well as typed at the ':' prompt.
463
  is valid in your .screenrc as well as typed at the ':' prompt.
456
  a bonus is ":set all" which is synonym to ":help".
464
  a bonus is ":set all" which is synonym to ":help".
457
  At the Colon prompt also KeyNames can be entered, alothough that makes
465
  At the Colon prompt also KeyNames can be entered, although that makes
458
  not always sense.
466
  not always sense.
459
467
460
^A x uses a builtin lockprg, if 
468
^A x uses a builtin lockprg, if 
461
  a) we don't find our lockprg, or
469
  a) we don't find our lockprg, or
462
  b) user supplies us with the environmet variable LOCKPRG set to "builtin"
470
  b) user supplies us with the environment variable LOCKPRG set to "builtin"
463
  the builtin locks until your login password is typed. on systems using
471
  the builtin locks until your login password is typed. on systems using
464
  "shadow password files" you are prompted for a password.
472
  "shadow password files" you are prompted for a password.
465
473
Lines 480-486 Link Here
480
488
481
rare markroutine bug fixed.
489
rare markroutine bug fixed.
482
490
483
we dont open every file the attacher tells us.
491
we don't open every file the attacher tells us.
484
492
485
we have now our wonderful "Wuff, Wuff" visual_bell
493
we have now our wonderful "Wuff, Wuff" visual_bell
486
494
(-)screen.orig/configure.ac (-29 / +70 lines)
Lines 172-177 Link Here
172
#include <signal.h>
172
#include <signal.h>
173
#include <fcntl.h>], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV))
173
#include <fcntl.h>], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV))
174
174
175
AC_CHECKING(for sequent/ptx)
176
AC_EGREP_CPP(YES_IS_DEFINED,
177
[#ifdef _SEQUENT_
178
  YES_IS_DEFINED;
179
#endif
180
], LIBS="$LIBS -lsocket -linet";seqptx=1)
181
182
AC_CHECKING(SVR4)
183
AC_EGREP_CPP(yes,
184
[main () {
185
#if defined(SVR4) || defined(__SVR4)
186
  yes;
187
#endif
188
], AC_NOTE(- you have a SVR4 system) AC_DEFINE(SVR4) svr4=1)
189
if test -n "$svr4" ; then
190
oldlibs="$LIBS"
191
LIBS="$LIBS -lelf"
192
AC_CHECKING(SVR4)
193
AC_TRY_LINK([#include <utmpx.h>
194
],,
195
[AC_CHECK_HEADER(dwarf.h, AC_DEFINE(BUGGYGETLOGIN),
196
[AC_CHECK_HEADER(elf.h, AC_DEFINE(BUGGYGETLOGIN))])]
197
,LIBS="$oldlibs")
198
fi
199
200
AC_CHECK_HEADERS([stropts.h string.h strings.h])
201
202
AC_CHECKING(for Solaris 2.x)
203
AC_EGREP_CPP(YES_IS_DEFINED,
204
[#if defined(SVR4) && defined(sun)
205
  YES_IS_DEFINED;
206
#endif
207
], LIBS="$LIBS -lsocket -lnsl -lkstat")
208
175
dnl
209
dnl
176
dnl    ****  typedefs ****
210
dnl    ****  typedefs ****
177
dnl
211
dnl
Lines 280-286 Link Here
280
#define S_IFIFO 0010000
314
#define S_IFIFO 0010000
281
#endif
315
#endif
282
316
283
char *fin = "conftest$$";
317
char *fin = "/tmp/conftest$$";
284
318
285
main()
319
main()
286
{
320
{
Lines 328-334 Link Here
328
], AC_NOTE(- your fifos are usable) fifo=1,
362
], AC_NOTE(- your fifos are usable) fifo=1,
329
AC_NOTE(- your fifos are not usable),
363
AC_NOTE(- your fifos are not usable),
330
AC_NOTE(- skipping check because we are cross compiling; assuming fifos are usable) fifo=1)
364
AC_NOTE(- skipping check because we are cross compiling; assuming fifos are usable) fifo=1)
331
rm -f conftest*
365
rm -f /tmp/conftest*
332
366
333
if test -n "$fifo"; then
367
if test -n "$fifo"; then
334
AC_CHECKING(for broken fifo implementation)
368
AC_CHECKING(for broken fifo implementation)
Lines 351-357 Link Here
351
#define S_IFIFO 0010000
385
#define S_IFIFO 0010000
352
#endif
386
#endif
353
387
354
char *fin = "conftest$$";
388
char *fin = "/tmp/conftest$$";
355
389
356
main()
390
main()
357
{
391
{
Lines 377-383 Link Here
377
], AC_NOTE(- your implementation is ok), 
411
], AC_NOTE(- your implementation is ok), 
378
AC_NOTE(- you have a broken implementation) AC_DEFINE(BROKEN_PIPE) fifobr=1,
412
AC_NOTE(- you have a broken implementation) AC_DEFINE(BROKEN_PIPE) fifobr=1,
379
AC_NOTE(- skipping check because we are cross compiling; assuming fifo implementation is ok))
413
AC_NOTE(- skipping check because we are cross compiling; assuming fifo implementation is ok))
380
rm -f conftest*
414
rm -f /tmp/conftest*
381
fi
415
fi
382
416
383
dnl
417
dnl
Lines 401-407 Link Here
401
#include <sys/socket.h>
435
#include <sys/socket.h>
402
#include <sys/un.h>
436
#include <sys/un.h>
403
437
404
char *son = "conftest$$";
438
char *son = "/tmp/conftest$$";
405
439
406
main()
440
main()
407
{
441
{
Lines 440-446 Link Here
440
], AC_NOTE(- your sockets are usable) sock=1,
474
], AC_NOTE(- your sockets are usable) sock=1,
441
AC_NOTE(- your sockets are not usable),
475
AC_NOTE(- your sockets are not usable),
442
AC_NOTE(- skipping check because we are cross compiling; assuming sockets are usable) sock=1)
476
AC_NOTE(- skipping check because we are cross compiling; assuming sockets are usable) sock=1)
443
rm -f conftest*
477
rm -f /tmp/conftest*
444
478
445
if test -n "$sock"; then
479
if test -n "$sock"; then
446
AC_CHECKING(socket implementation)
480
AC_CHECKING(socket implementation)
Lines 457-463 Link Here
457
#include <sys/socket.h>
491
#include <sys/socket.h>
458
#include <sys/un.h>
492
#include <sys/un.h>
459
493
460
char *son = "conftest$$";
494
char *son = "/tmp/conftest$$";
461
495
462
main()
496
main()
463
{
497
{
Lines 480-486 Link Here
480
AC_NOTE(- unix domain sockets are not kept in the filesystem)
514
AC_NOTE(- unix domain sockets are not kept in the filesystem)
481
AC_DEFINE(SOCK_NOT_IN_FS) socknofs=1,
515
AC_DEFINE(SOCK_NOT_IN_FS) socknofs=1,
482
AC_NOTE(- skipping check because we are cross compiling; assuming sockets are normal))
516
AC_NOTE(- skipping check because we are cross compiling; assuming sockets are normal))
483
rm -f conftest*
517
rm -f /tmp/conftest*
484
fi
518
fi
485
519
486
520
Lines 502-508 Link Here
502
#include <sys/stat.h>
536
#include <sys/stat.h>
503
#include <fcntl.h>
537
#include <fcntl.h>
504
538
505
char *nam = "conftest$$";
539
char *nam = "/tmp/conftest$$";
506
540
507
#ifdef NAMEDPIPE
541
#ifdef NAMEDPIPE
508
542
Lines 601-607 Link Here
601
tgetent((char *)0, (char *)0);
635
tgetent((char *)0, (char *)0);
602
#endif
636
#endif
603
],,
637
],,
604
LIBS="-ltinfo $olibs"
638
LIBS="-ltermcap $olibs"
605
AC_CHECKING(libtermcap)
639
AC_CHECKING(libtermcap)
606
AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
640
AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
607
LIBS="-ltermlib $olibs"
641
LIBS="-ltermlib $olibs"
Lines 622-630 Link Here
622
AC_MSG_ERROR(!!! no tgetent - no screen)))))))))
656
AC_MSG_ERROR(!!! no tgetent - no screen)))))))))
623
657
624
AC_TRY_RUN([
658
AC_TRY_RUN([
625
626
extern char *tgoto(char *,int,int);
627
628
main()
659
main()
629
{
660
{
630
 exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
661
 exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
Lines 638-648 Link Here
638
dnl    ****  PTY specific things  ****
669
dnl    ****  PTY specific things  ****
639
dnl
670
dnl
640
if test "$cross_compiling" = no ; then
671
if test "$cross_compiling" = no ; then
672
AC_CHECKING(for /dev/ptc)
673
if test -r /dev/ptc; then
674
AC_DEFINE(HAVE_DEV_PTC)
675
fi
676
fi
677
678
if test "$cross_compiling" = no ; then
641
AC_CHECKING(for SVR4 ptys)
679
AC_CHECKING(for SVR4 ptys)
642
sysvr4ptys=
680
sysvr4ptys=
681
if test -c /dev/ptmx ; then
643
AC_TRY_LINK([],[ptsname(0);grantpt(0);unlockpt(0);],[AC_DEFINE(HAVE_SVR4_PTYS)
682
AC_TRY_LINK([],[ptsname(0);grantpt(0);unlockpt(0);],[AC_DEFINE(HAVE_SVR4_PTYS)
644
sysvr4ptys=1])
683
sysvr4ptys=1])
645
fi
684
fi
685
fi
646
686
647
AC_CHECK_FUNCS(getpt)
687
AC_CHECK_FUNCS(getpt)
648
688
Lines 824-829 Link Here
824
dnl
864
dnl
825
dnl    ****  loadav  ****
865
dnl    ****  loadav  ****
826
dnl
866
dnl
867
if test "$cross_compiling" = no ; then
868
AC_CHECKING(for libutil(s))
869
test -f /usr/lib/libutils.a && LIBS="$LIBS -lutils"
870
test -f /usr/lib/libutil.a && LIBS="$LIBS -lutil"
871
fi
827
872
828
AC_CHECKING(getloadavg)
873
AC_CHECKING(getloadavg)
829
AC_TRY_LINK(,[getloadavg((double *)0, 0);],
874
AC_TRY_LINK(,[getloadavg((double *)0, 0);],
Lines 1053-1058 Link Here
1053
LIBS="$LIBS -lcrypt"
1098
LIBS="$LIBS -lcrypt"
1054
AC_CHECKING(crypt)
1099
AC_CHECKING(crypt)
1055
AC_TRY_LINK(,,,LIBS="$oldlibs")
1100
AC_TRY_LINK(,,,LIBS="$oldlibs")
1101
if test "$cross_compiling" = no ; then
1102
test -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec"
1103
test -f /lib/libshadow.a || test -f /usr/lib/libshadow.a && LIBS="$LIBS -lshadow"
1104
fi
1105
1056
oldlibs="$LIBS"
1106
oldlibs="$LIBS"
1057
LIBS="$LIBS -lsun"
1107
LIBS="$LIBS -lsun"
1058
AC_CHECKING(IRIX sun library)
1108
AC_CHECKING(IRIX sun library)
Lines 1194-1219 Link Here
1194
1244
1195
AC_CHECK_FUNCS(rename fchmod fchown strerror lstat _exit utimes vsnprintf getcwd setlocale strftime)
1245
AC_CHECK_FUNCS(rename fchmod fchown strerror lstat _exit utimes vsnprintf getcwd setlocale strftime)
1196
1246
1197
AC_CHECK_LIB(dl, dlopen)
1198
1199
AC_ARG_ENABLE(pam, [  --enable-pam            enable PAM support])
1247
AC_ARG_ENABLE(pam, [  --enable-pam            enable PAM support])
1200
if test "$enable_pam" = "yes"; then
1248
if test "$enable_pam" = "yes"; then
1201
    AC_MSG_CHECKING(for PAM support)
1249
    AC_MSG_CHECKING(for PAM support)
1202
    oldlibs="$LIBS"
1250
    oldlibs="$LIBS"
1203
    cf_result=no
1251
    LIBS="$LIBS -lpam"
1204
1252
    AC_TRY_LINK([#include <security/pam_appl.h>], [
1205
    AC_CHECK_LIB(pam, pam_start, LIBS="$LIBS -lpam";cf_result=yes, cf_result=no)
1253
	pam_start(0, 0, 0, 0);
1206
1254
	pam_authenticate(0, 0);
1207
    if test "$cf_result" = yes; then
1255
	pam_end(0,0);
1208
    	AC_CHECK_LIB(pam_userpass, pam_userpass_conv, LIBS="$LIBS -lpam_userpass";cf_result=yes, cf_result=no)
1256
    ], AC_MSG_RESULT(yes);AC_DEFINE(USE_PAM),
1209
    fi
1257
       AC_MSG_RESULT(no);LIBS="$oldlibs")
1210
1211
    if test "$cf_result" = yes; then
1212
	AC_DEFINE(USE_PAM)
1213
    else
1214
    	LIBS="$oldlibs"
1215
    fi
1216
    AC_MSG_RESULT($cf_result);
1217
fi
1258
fi
1218
1259
1219
AC_ARG_ENABLE(use-locale,
1260
AC_ARG_ENABLE(use-locale,
(-)screen.orig/display.c (-49 / +15 lines)
Lines 28-34 Link Here
28
28
29
#include <sys/types.h>
29
#include <sys/types.h>
30
#include <signal.h>
30
#include <signal.h>
31
#include <setjmp.h>
32
#include <fcntl.h>
31
#include <fcntl.h>
33
#ifndef sun
32
#ifndef sun
34
# include <sys/ioctl.h>
33
# include <sys/ioctl.h>
Lines 327-343 Link Here
327
  return display;
326
  return display;
328
}
327
}
329
328
330
static sigjmp_buf alarm_jump;
331
332
static sigret_t
333
FlushSigAlarm SIGDEFARG
334
{
335
#ifdef DEBUG
336
    debug("FlushSigAlarm\n");
337
#endif
338
    siglongjmp (alarm_jump, 1);
339
}
340
341
329
342
void
330
void
343
FreeDisplay()
331
FreeDisplay()
Lines 358-369 Link Here
358
      Flush(3);
346
      Flush(3);
359
      if (!display)
347
      if (!display)
360
	return;
348
	return;
361
      if (sigsetjmp(alarm_jump,1)==0) {
349
      SetTTY(D_userfd, &D_OldMode);
362
        signal(SIGALRM, FlushSigAlarm);
363
        alarm(10);
364
        SetTTY(D_userfd, &D_OldMode);
365
        alarm(0);
366
      }
367
      fcntl(D_userfd, F_SETFL, 0);
350
      fcntl(D_userfd, F_SETFL, 0);
368
    }
351
    }
369
  freetty();
352
  freetty();
Lines 2332-2338 Link Here
2332
{
2315
{
2333
  char *buf;
2316
  char *buf;
2334
#ifdef UTF8
2317
#ifdef UTF8
2335
  int extrabytes = strlen(hstatusstring) - strlen_onscreen(hstatusstring, NULL);
2318
  int extrabytes = strlen(hstatusstring) - strlen_onscreen((unsigned char *)hstatusstring, NULL);
2336
#else
2319
#else
2337
  int extrabytes = 0;
2320
  int extrabytes = 0;
2338
#endif
2321
#endif
Lines 2435-2441 Link Here
2435
	  if (y == cv->c_ye + 1 && from >= cv->c_xs && from <= cv->c_xe)
2418
	  if (y == cv->c_ye + 1 && from >= cv->c_xs && from <= cv->c_xe)
2436
	    {
2419
	    {
2437
#ifdef UTF8
2420
#ifdef UTF8
2438
	      int extrabytes = strlen(captionstring) - strlen_onscreen(captionstring, NULL);
2421
	      int extrabytes = strlen(captionstring) - strlen_onscreen((unsigned char *)captionstring, NULL);
2439
#else
2422
#else
2440
	      int extrabytes = 0;
2423
	      int extrabytes = 0;
2441
#endif
2424
#endif
Lines 3040-3046 Link Here
3040
    AddChar(' ');
3023
    AddChar(' ');
3041
}
3024
}
3042
3025
3043
3044
void
3026
void
3045
Flush(progress)
3027
Flush(progress)
3046
int progress;
3028
int progress;
Lines 3092-3106 Link Here
3092
	      break;
3074
	      break;
3093
	    }
3075
	    }
3094
	}
3076
	}
3095
      if (sigsetjmp (alarm_jump,1) == 0) {
3077
      wr = write(D_userfd, p, l);
3096
        signal(SIGALRM, FlushSigAlarm);
3097
	alarm(10);
3098
	wr = write(D_userfd, p, l);
3099
	alarm(0);
3100
      } else {
3101
	debug1("Warning: We spent too long in flush: %d\n", errno);
3102
	return;
3103
      }
3104
      if (wr <= 0)
3078
      if (wr <= 0)
3105
	{
3079
	{
3106
	  if (errno == EINTR)
3080
	  if (errno == EINTR)
Lines 3208-3215 Link Here
3208
    {
3182
    {
3209
      debug("display activity stopped sleep\n");
3183
      debug("display activity stopped sleep\n");
3210
      if (eat)
3184
      if (eat)
3211
        if (read(D_userfd, &buf, 1) < 1)
3185
        read(D_userfd, &buf, 1);
3212
	  ;
3213
    }
3186
    }
3214
  debug2("DisplaySleep(%d) ending, eat was %d\n", n, eat);
3187
  debug2("DisplaySleep(%d) ending, eat was %d\n", n, eat);
3215
}
3188
}
Lines 3432-3438 Link Here
3432
   */
3405
   */
3433
  int size;
3406
  int size;
3434
  char bufspace[MAX_MOUSE_SEQUENCE + IOSIZE];
3407
  char bufspace[MAX_MOUSE_SEQUENCE + IOSIZE];
3435
  unsigned char *buf = bufspace + MAX_MOUSE_SEQUENCE;
3408
  unsigned char *buf = (unsigned char*)bufspace + MAX_MOUSE_SEQUENCE;
3436
3409
3437
  struct canvas *cv;
3410
  struct canvas *cv;
3438
3411
Lines 3507-3513 Link Here
3507
	if (p->w_zdisplay == display)
3480
	if (p->w_zdisplay == display)
3508
	  {
3481
	  {
3509
	    flayer = &p->w_layer;
3482
	    flayer = &p->w_layer;
3510
	    bufp = buf;
3483
	    bufp = (char *)buf;
3511
	    while (size > 0)
3484
	    while (size > 0)
3512
	      LayProcess(&bufp, &size);
3485
	      LayProcess(&bufp, &size);
3513
	    return;
3486
	    return;
Lines 3790-3796 Link Here
3790
      return;
3763
      return;
3791
    }
3764
    }
3792
#endif
3765
#endif
3793
  (*D_processinput)(buf, size);
3766
  (*D_processinput)((char *)buf, size);
3794
}
3767
}
3795
3768
3796
static void
3769
static void
Lines 4015-4021 Link Here
4015
	}
3988
	}
4016
    }
3989
    }
4017
#endif
3990
#endif
4018
  fflush(NULL);
4019
  switch (pid = (int)fork())
3991
  switch (pid = (int)fork())
4020
    {
3992
    {
4021
    case -1:
3993
    case -1:
Lines 4063-4081 Link Here
4063
	}
4035
	}
4064
      debug1("=== RunBlanker: pid %d\n", (int)getpid());
4036
      debug1("=== RunBlanker: pid %d\n", (int)getpid());
4065
#endif
4037
#endif
4066
      {
4038
      close(0);
4067
        int fd = open(m, O_RDWR);
4039
      close(1);
4068
        if (fd < 0)
4040
      close(2);
4069
          Panic(errno, "Cannot open %s", m);
4041
      if (open(m, O_RDWR))
4070
        if (dup2(fd, 0) < 0)
4042
	Panic(errno, "Cannot open %s", m);
4071
          Panic(errno, "Cannot redirect %s to %s", "stdin", m);
4043
      dup(0);
4072
        if (dup2(fd, 1) < 0)
4044
      dup(0);
4073
          Panic(errno, "Cannot redirect %s to %s", "stdout", m);
4074
        if (dup2(fd, 2) < 0)
4075
          Panic(errno, "Cannot redirect %s to %s", "stderr", m);
4076
        if (fd > 2)
4077
          close(fd);
4078
      }
4079
      close(D_blankerev.fd);
4045
      close(D_blankerev.fd);
4080
      if (slave != -1)
4046
      if (slave != -1)
4081
	close(slave);
4047
	close(slave);
(-)screen.orig/display.h (-2 / +2 lines)
Lines 61-67 Link Here
61
struct mouse_parse
61
struct mouse_parse
62
{
62
{
63
  char sgrmode;                 /* non-zero if parsing an SGR sequence */
63
  char sgrmode;                 /* non-zero if parsing an SGR sequence */
64
  char state;                   /* current state of parsing */
64
  int state;                    /* current state of parsing */
65
  int params[3];                /* parsed params: button, x, y */
65
  int params[3];                /* parsed params: button, x, y */
66
};
66
};
67
67
Lines 112-118 Link Here
112
  int	d_mousetrack;		/* set when user wants to use mouse even when the window
112
  int	d_mousetrack;		/* set when user wants to use mouse even when the window
113
				   does not */
113
				   does not */
114
#ifdef RXVT_OSC
114
#ifdef RXVT_OSC
115
  int   d_xtermosc[4];		/* osc used */
115
  int   d_xtermosc[5];		/* osc used */
116
#endif
116
#endif
117
  struct mchar d_lpchar;	/* missing char */
117
  struct mchar d_lpchar;	/* missing char */
118
  struct timeval d_status_time;	/* time of status display */
118
  struct timeval d_status_time;	/* time of status display */
(-)screen.orig/doc/FAQ (-1 / +1 lines)
Lines 191-197 Link Here
191
Q:   The "talk" command does not work when Screen is active.
191
Q:   The "talk" command does not work when Screen is active.
192
 
192
 
193
A:   Talk  and several  other programs  rely on entries  in the  Utmp-
193
A:   Talk  and several  other programs  rely on entries  in the  Utmp-
194
     Database  (/var/run/utmp).  On some  systems this  Database is  world 
194
     Database  (/etc/utmp).  On some  systems this  Database is  world 
195
     writable,  on others  it is not.  If it  is not,  screen must  be 
195
     writable,  on others  it is not.  If it  is not,  screen must  be 
196
     installed with the appropriate  permissions (user or group s-bit)
196
     installed with the appropriate  permissions (user or group s-bit)
197
     just like any  program that uses  PTYs (rlogin, xterm, ...). When
197
     just like any  program that uses  PTYs (rlogin, xterm, ...). When
(-)screen.orig/doc/screen.1 (-153 / +162 lines)
Lines 1-10 Link Here
1
.\" vi:set wm=5
1
.\" vi:set wm=5
2
.TH SCREEN 1 "Feb 2020"
2
.TH SCREEN 1 "2022 Jan 30" "GNU Screen 4.9.0"
3
.if n .ds Q \&"
3
.
4
.if n .ds U \&"
4
.
5
.if t .ds Q ``
6
.if t .ds U ''
7
.UC 4
8
.SH NAME
5
.SH NAME
9
screen \- screen manager with VT100/ANSI terminal emulation
6
screen \- screen manager with VT100/ANSI terminal emulation
10
7
Lines 80-93 Link Here
80
.I Screen
77
.I Screen
81
will also print out control characters in caret notation.
78
will also print out control characters in caret notation.
82
.PP
79
.PP
83
The standard way to create a new window is to type \*QC-a c\*U.
80
The standard way to create a new window is to type \fBC-a c\fP.
84
This creates a new window running a shell and switches to that
81
This creates a new window running a shell and switches to that
85
window immediately, regardless of the state of the process running
82
window immediately, regardless of the state of the process running
86
in the current window.
83
in the current window.
87
Similarly, you can create a new window with a custom command in it by
84
Similarly, you can create a new window with a custom command in it by
88
first binding the command to a keystroke (in your .screenrc file or at the
85
first binding the command to a keystroke (in your .screenrc file or at the
89
\*QC-a :\*U command line) and
86
\fBC-a :\fP command line) and
90
then using it just like the \*QC-a c\*U command.
87
then using it just like the \fBC-a c\fP command.
91
In addition, new windows can be created by running a command like:
88
In addition, new windows can be created by running a command like:
92
.IP
89
.IP
93
screen emacs prog.c
90
screen emacs prog.c
Lines 103-109 Link Here
103
the invoking shell to the application (emacs in this case), because it is
100
the invoking shell to the application (emacs in this case), because it is
104
forked from the parent screen process, not from the invoking shell.
101
forked from the parent screen process, not from the invoking shell.
105
.PP
102
.PP
106
If \*Q/var/run/utmp\*U is writable by
103
If \*Q/etc/utmp\*U is writable by
107
.IR screen ,
104
.IR screen ,
108
an appropriate record will be written to this file for each window, and
105
an appropriate record will be written to this file for each window, and
109
removed when the window is terminated.
106
removed when the window is terminated.
Lines 121-131 Link Here
121
you'll need to make sure you have correctly selected your terminal type,
118
you'll need to make sure you have correctly selected your terminal type,
122
just as you would for any other termcap/terminfo program.
119
just as you would for any other termcap/terminfo program.
123
(You can do this by using
120
(You can do this by using
124
.IR tset
121
.IR test
125
for example.)
122
for example.)
126
.PP
123
.PP
127
If you're impatient and want to get started without doing a lot more reading,
124
If you're impatient and want to get started without doing a lot more reading,
128
you should remember this one command:  \*QC-a ?\*U.
125
you should remember this one command:  \fBC-a ?\fP.
129
Typing these two characters will display a list of the available
126
Typing these two characters will display a list of the available
130
.I screen
127
.I screen
131
commands and their bindings. Each keystroke is discussed in
128
commands and their bindings. Each keystroke is discussed in
Lines 232-238 Link Here
232
The use of this option is discouraged.
229
The use of this option is discouraged.
233
.TP 5
230
.TP 5
234
.BR \-l " and " \-ln
231
.BR \-l " and " \-ln
235
turns login mode on or off (for /var/run/utmp updating).
232
turns login mode on or off (for /etc/utmp updating).
236
This can also be defined through the \*Qdeflogin\*U .screenrc command.
233
This can also be defined through the \*Qdeflogin\*U .screenrc command.
237
.TP 5
234
.TP 5
238
.BR \-ls " [" \fImatch ]
235
.BR \-ls " [" \fImatch ]
Lines 257-268 Link Here
257
Sessions marked as `dead' should be thoroughly checked and removed. 
254
Sessions marked as `dead' should be thoroughly checked and removed. 
258
Ask your system administrator if you are not sure. Remove sessions with the 
255
Ask your system administrator if you are not sure. Remove sessions with the 
259
\fB-wipe\fP option. 
256
\fB-wipe\fP option. 
260
.IP "" 5
261
Note:
262
  If sockets are missing (and because of this, your sessions are not
263
listed), you may send a SIGCHLD to its `SCREEN'
264
process and the process will re-establish the socket (think of
265
someone cleaning /tmp thoroughly).
266
.TP 5
257
.TP 5
267
.B \-L
258
.B \-L
268
tells
259
tells
Lines 378-384 Link Here
378
When creating a new session, this option can be used to specify a
369
When creating a new session, this option can be used to specify a
379
meaningful name for the session. This name identifies the session for
370
meaningful name for the session. This name identifies the session for
380
\*Qscreen \-list\*U and \*Qscreen \-r\*U actions. It substitutes the
371
\*Qscreen \-list\*U and \*Qscreen \-r\*U actions. It substitutes the
381
default [\fItty.host\fP] suffix.
372
default [\fItty.host\fP] suffix. This name should not be longer
373
then 80 symbols.
382
.TP 5
374
.TP 5
383
.BI "\-t " name
375
.BI "\-t " name
384
sets the title (a.\|k.\|a.) for the default shell or specified program.
376
sets the title (a.\|k.\|a.) for the default shell or specified program.
Lines 788-794 Link Here
788
When
780
When
789
.I screen
781
.I screen
790
is invoked, it executes initialization commands from the files
782
is invoked, it executes initialization commands from the files
791
\*Q/etc/screenrc\*U and
783
\*Q/usr/local/etc/screenrc\*U and
792
\*Q.screenrc\*U in the user's home directory. These are the \*Qprogrammer's
784
\*Q.screenrc\*U in the user's home directory. These are the \*Qprogrammer's
793
defaults\*U that can be overridden in the following ways: for the
785
defaults\*U that can be overridden in the following ways: for the
794
global screenrc file 
786
global screenrc file 
Lines 930-943 Link Here
930
and each occurrence of `^G' is replaced by the definition for bell
922
and each occurrence of `^G' is replaced by the definition for bell
931
in your termcap (usually an audible bell).
923
in your termcap (usually an audible bell).
932
The default message is
924
The default message is
933
.sp
925
.PP
926
.nf
934
	'Activity in window %n'
927
	'Activity in window %n'
935
.sp
928
.fi
929
.PP
936
Note that monitoring is off for all windows by default, but can be altered
930
Note that monitoring is off for all windows by default, but can be altered
937
by use of the \*Qmonitor\*U command (C-a M).
931
by use of the \*Qmonitor\*U command (C-a M).
938
.RE
932
.RE
939
.TP
933
.TP
940
.BR "allpartial on" | off
934
.BR "allpartial [ on | off ]"
941
.RS 0
935
.RS 0
942
.PP
936
.PP
943
If set to on, only the current cursor line is refreshed on window change.
937
If set to on, only the current cursor line is refreshed on window change.
Lines 948-954 Link Here
948
default redraw behavior of newly created windows.
942
default redraw behavior of newly created windows.
949
.RE
943
.RE
950
.TP
944
.TP
951
.BR "altscreen on" | off
945
.BR "altscreen [ on | off ]"
952
.RS 0
946
.RS 0
953
.PP
947
.PP
954
If set to on, "alternate screen" support is enabled in virtual terminals,
948
If set to on, "alternate screen" support is enabled in virtual terminals,
Lines 1021-1027 Link Here
1021
Make bright colored text also bold.
1015
Make bright colored text also bold.
1022
.RE
1016
.RE
1023
.TP
1017
.TP
1024
.BR "autodetach on" | off
1018
.BR "autodetach [ on | off ]"
1025
.RS 0
1019
.RS 0
1026
.PP
1020
.PP
1027
Sets whether 
1021
Sets whether 
Lines 1035-1041 Link Here
1035
and all the processes it contains. Autodetach is on by default.
1029
and all the processes it contains. Autodetach is on by default.
1036
.RE
1030
.RE
1037
.TP
1031
.TP
1038
.BR "autonuke on" | off
1032
.BR "autonuke [ on | off ]"
1039
.RS 0
1033
.RS 0
1040
.PP
1034
.PP
1041
Sets whether a clear screen sequence should nuke all the output
1035
Sets whether a clear screen sequence should nuke all the output
Lines 1069-1075 Link Here
1069
with the numerical id \fIid\fP.
1063
with the numerical id \fIid\fP.
1070
.RE
1064
.RE
1071
.TP
1065
.TP
1072
.BR "bce " [ on | off ]
1066
.BR "bce [ on | off ]"
1073
.RS 0
1067
.RS 0
1074
.PP
1068
.PP
1075
Change background-color-erase setting. If \*Qbce\*U is set to on, all
1069
Change background-color-erase setting. If \*Qbce\*U is set to on, all
Lines 1090-1100 Link Here
1090
and each occurrence of `^G' is replaced by the definition for bell
1084
and each occurrence of `^G' is replaced by the definition for bell
1091
in your termcap (usually an audible bell).
1085
in your termcap (usually an audible bell).
1092
The default message is
1086
The default message is
1093
.sp
1087
.PP
1094
.RS
1088
.nf
1095
	'Bell in window %n'
1089
	'Bell in window %n'
1096
.RE
1090
.fi
1097
.sp
1091
.PP
1098
An empty message can be supplied to the \*Qbell_msg\*U command to suppress
1092
An empty message can be supplied to the \*Qbell_msg\*U command to suppress
1099
output of a message line (bell_msg "").
1093
output of a message line (bell_msg "").
1100
Without parameter, the current message is shown.
1094
Without parameter, the current message is shown.
Lines 1248-1254 Link Here
1248
escape (besides ^A).
1242
escape (besides ^A).
1249
.RE
1243
.RE
1250
.TP
1244
.TP
1251
.BR break [ \fIduration\fR ]
1245
.BR "break " [ \fIduration\fR ]
1252
.RS 0
1246
.RS 0
1253
.PP
1247
.PP
1254
Send a break signal for \fIduration\fP*0.25 seconds to this window.
1248
Send a break signal for \fIduration\fP*0.25 seconds to this window.
Lines 1318-1327 Link Here
1318
Swaps window with next one on window list.
1312
Swaps window with next one on window list.
1319
.RE
1313
.RE
1320
.TP
1314
.TP
1321
.BR "c1 " [ on | off ]
1315
.BR "c1 [ on | off ]"
1322
.RS 0
1316
.RS 0
1323
.PP
1317
.PP
1324
Change c1 code processing. \*QC1 on\*U tells screen to treat
1318
Change c1 code processing. \fBC1 on\fP tells screen to treat
1325
the input characters between 128 and 159 as control functions.
1319
the input characters between 128 and 159 as control functions.
1326
Such an 8-bit code is normally the same as ESC followed by the
1320
Such an 8-bit code is normally the same as ESC followed by the
1327
corresponding 7-bit code. The default setting is to process c1
1321
corresponding 7-bit code. The default setting is to process c1
Lines 1426-1432 Link Here
1426
you may regard \*QC-a esc\*U (copy mode) as its `Vi command mode'.
1420
you may regard \*QC-a esc\*U (copy mode) as its `Vi command mode'.
1427
.RE
1421
.RE
1428
.TP
1422
.TP
1429
.BR "command " [ \-c " \fIclass\fP" ]
1423
.BR "command [ \-c " \fIclass\fP" ]"
1430
.RS 0
1424
.RS 0
1431
.PP
1425
.PP
1432
This command has the same effect as typing the screen escape
1426
This command has the same effect as typing the screen escape
Lines 1435-1448 Link Here
1435
class.  See also \*Qbind\*U and \*Qbindkey\*U.
1429
class.  See also \*Qbind\*U and \*Qbindkey\*U.
1436
.RE
1430
.RE
1437
.TP
1431
.TP
1438
.BR "compacthist " [ on | off ]
1432
.BR "compacthist [ on | off ]"
1439
.RS 0
1433
.RS 0
1440
.PP
1434
.PP
1441
This tells screen whether to suppress trailing blank lines when
1435
This tells screen whether to suppress trailing blank lines when
1442
scrolling up text into the history buffer.
1436
scrolling up text into the history buffer.
1443
.RE
1437
.RE
1444
.TP
1438
.TP
1445
.BR "console " [ on | off ]
1439
.BR "console [ on | off ]"
1446
.RS 0
1440
.RS 0
1447
.PP
1441
.PP
1448
Grabs or un-grabs the machines console output to a window.
1442
Grabs or un-grabs the machines console output to a window.
Lines 1517-1523 Link Here
1517
\fBB\fP, \fBE\fP@move the cursor WORD by WORD (as in vi).
1511
\fBB\fP, \fBE\fP@move the cursor WORD by WORD (as in vi).
1518
_
1512
_
1519
\fBf/F\fP, \fBt/T\fP@T{
1513
\fBf/F\fP, \fBt/T\fP@T{
1520
move the cursor forward/backward to the next occurence of the
1514
move the cursor forward/backward to the next occurrence of the
1521
target. (eg, '3fy' will move the cursor to the 3rd 'y' to the right.)
1515
target. (eg, '3fy' will move the cursor to the 3rd 'y' to the right.)
1522
T}
1516
T}
1523
_
1517
_
Lines 1539-1545 Link Here
1539
_
1533
_
1540
.TE
1534
.TE
1541
.\"\fBf\fP,\fBt\fP, \fBF\fP, \fBT\fP@T{
1535
.\"\fBf\fP,\fBt\fP, \fBF\fP, \fBT\fP@T{
1542
.\"move the cursor forward/backward to the next occurence of the target.
1536
.\"move the cursor forward/backward to the next occurrence of the target.
1543
.\"T}
1537
.\"T}
1544
1538
1545
.PP
1539
.PP
Lines 1571-1577 Link Here
1571
Example: \*QC-a C-[ H 10 j 5 Y\*U will copy lines
1565
Example: \*QC-a C-[ H 10 j 5 Y\*U will copy lines
1572
11 to 15 into the paste buffer.
1566
11 to 15 into the paste buffer.
1573
.PP
1567
.PP
1574
The folllowing search keys are defined:
1568
The following search keys are defined:
1575
.IP
1569
.IP
1576
\fB/\fP \fIVi\fP-like search forward.
1570
\fB/\fP \fIVi\fP-like search forward.
1577
.IP
1571
.IP
Lines 1652-1658 Link Here
1652
No longer exists, use \*Qreadreg\*U instead.
1646
No longer exists, use \*Qreadreg\*U instead.
1653
.RE
1647
.RE
1654
.TP
1648
.TP
1655
.BR "crlf " [ on | off ]
1649
.BR "crlf [ on | off ]"
1656
.RS 0
1650
.RS 0
1657
.PP
1651
.PP
1658
This affects the copying of text regions with the `C-a [' command. If it is set
1652
This affects the copying of text regions with the `C-a [' command. If it is set
Lines 1661-1667 Link Here
1661
When no parameter is given, the state is toggled.
1655
When no parameter is given, the state is toggled.
1662
.RE
1656
.RE
1663
.TP
1657
.TP
1664
.BR "debug on" | off
1658
.BR "debug [ on | off ]"
1665
.RS 0
1659
.RS 0
1666
.PP
1660
.PP
1667
Turns runtime debugging on or off. If 
1661
Turns runtime debugging on or off. If 
Lines 1672-1685 Link Here
1672
be turned off once and forever.
1666
be turned off once and forever.
1673
.RE
1667
.RE
1674
.TP
1668
.TP
1675
.BR "defc1 on" | off
1669
.BR "defc1 [ on | off ]"
1676
.RS 0
1670
.RS 0
1677
.PP
1671
.PP
1678
Same as the \fBc1\fP command except that the default setting for new
1672
Same as the \fBc1\fP command except that the default setting for new
1679
windows is changed. Initial setting is `on'.
1673
windows is changed. Initial setting is `on'.
1680
.RE
1674
.RE
1681
.TP
1675
.TP
1682
.BR "defautonuke on" | off
1676
.BR "defautonuke [ on | off ]"
1683
.RS 0
1677
.RS 0
1684
.PP
1678
.PP
1685
Same as the \fBautonuke\fP command except that the default setting for new displays is changed. Initial setting is `off'.
1679
Same as the \fBautonuke\fP command except that the default setting for new displays is changed. Initial setting is `off'.
Lines 1687-1693 Link Here
1687
want to have a dependency on the terminal type.
1681
want to have a dependency on the terminal type.
1688
.RE
1682
.RE
1689
.TP
1683
.TP
1690
.BR "defbce on" | off
1684
.BR "defbce [ on | off ]"
1691
.RS 0
1685
.RS 0
1692
.PP
1686
.PP
1693
Same as the \fBbce\fP command except that the default setting for new
1687
Same as the \fBbce\fP command except that the default setting for new
Lines 1721-1727 Link Here
1721
argument.
1715
argument.
1722
.RE
1716
.RE
1723
.TP
1717
.TP
1724
.BR "defdynamictitle on" | off
1718
.BR "defdynamictitle [ on | off ]"
1725
.RS 0
1719
.RS 0
1726
.PP
1720
.PP
1727
Set default behaviour for new windows regarding if screen should change window
1721
Set default behaviour for new windows regarding if screen should change window
Lines 1739-1756 Link Here
1739
characters for users that will be added later.
1733
characters for users that will be added later.
1740
.RE
1734
.RE
1741
.TP
1735
.TP
1742
.BR "defflow " on | off | "auto " [ interrupt ]
1736
.BR "defflow [ on | off | auto [ interrupt ]]
1743
.RS 0
1737
.RS 0
1744
.PP
1738
.PP
1745
Same as the \fBflow\fP command except that the default setting for new windows 
1739
Same as the \fBflow\fP command except that the default setting for new windows 
1746
is changed. Initial setting is `auto'.
1740
is changed. Initial setting is `auto'.
1747
Specifying \*Qdefflow auto interrupt\*U is the same as the command-line options
1741
Specifying \fBdefflow auto interrupt\fP is the same as the command-line options
1748
.B \-fa
1742
.B \-fa
1749
and
1743
and
1750
.BR \-i . 
1744
.BR \-i . 
1751
.RE
1745
.RE
1752
.TP
1746
.TP
1753
.BR "defgr on" | off
1747
.BR "defgr [ on | off ]"
1754
.RS 0
1748
.RS 0
1755
.PP
1749
.PP
1756
Same as the \fBgr\fP command except that the default setting for new
1750
Same as the \fBgr\fP command except that the default setting for new
Lines 1783-1796 Link Here
1783
terminal.
1777
terminal.
1784
.RE
1778
.RE
1785
.TP
1779
.TP
1786
.BR "deflog on" | off
1780
.BR "deflog [ on | off ]"
1787
.RS 0
1781
.RS 0
1788
.PP
1782
.PP
1789
Same as the \fBlog\fP command except that the default setting for new windows 
1783
Same as the \fBlog\fP command except that the default setting for new windows 
1790
is changed. Initial setting is `off'.
1784
is changed. Initial setting is `off'.
1791
.RE
1785
.RE
1792
.TP
1786
.TP
1793
.BR "deflogin on" | off
1787
.BR "deflogin [ on | off ]"
1794
.RS 0
1788
.RS 0
1795
.PP
1789
.PP
1796
Same as the \fBlogin\fP command except that the default setting for new windows 
1790
Same as the \fBlogin\fP command except that the default setting for new windows 
Lines 1805-1825 Link Here
1805
When no \*Qdefmode\*U command is given, mode 0622 is used.
1799
When no \*Qdefmode\*U command is given, mode 0622 is used.
1806
.RE
1800
.RE
1807
.TP
1801
.TP
1808
.BR "defmonitor on" | off
1802
.BR "defmonitor [ on | off]"
1809
.RS 0
1803
.RS 0
1810
.PP
1804
.PP
1811
Same as the \fBmonitor\fP command except that the default setting for new 
1805
Same as the \fBmonitor\fP command except that the default setting for new 
1812
windows is changed. Initial setting is `off'.
1806
windows is changed. Initial setting is `off'.
1813
.RE
1807
.RE
1814
.TP
1808
.TP
1815
.BR "defmousetrack on" | off
1809
.BR "defmousetrack [ on | off ]"
1816
.RS 0
1810
.RS 0
1817
.PP
1811
.PP
1818
Same as the \fBmousetrack\fP command except that the default setting for new
1812
Same as the \fBmousetrack\fP command except that the default setting for new
1819
windows is changed. Initial setting is `off'.
1813
windows is changed. Initial setting is `off'.
1820
.RE
1814
.RE
1821
.TP
1815
.TP
1822
.BR "defnonblock on" | off | \fInumsecs\fP
1816
.BR "defnonblock [ on | off | \fInumsecs\fP]
1823
.RS 0
1817
.RS 0
1824
.PP
1818
.PP
1825
Same as the \fBnonblock\fP command except that the default setting for
1819
Same as the \fBnonblock\fP command except that the default setting for
Lines 1847-1853 Link Here
1847
Synonym to the \fBshell\fP .screenrc command. See there.
1841
Synonym to the \fBshell\fP .screenrc command. See there.
1848
.RE
1842
.RE
1849
.TP
1843
.TP
1850
.BR "defsilence on" | off
1844
.BR "defsilence [ on | off ]"
1851
.RS 0
1845
.RS 0
1852
.PP
1846
.PP
1853
Same as the \fBsilence\fP command except that the default setting for new
1847
Same as the \fBsilence\fP command except that the default setting for new
Lines 1861-1867 Link Here
1861
windows is changed. Initial setting is 0 milliseconds, meaning `off'.
1855
windows is changed. Initial setting is 0 milliseconds, meaning `off'.
1862
.RE
1856
.RE
1863
.TP
1857
.TP
1864
.BR "defutf8 on" | off
1858
.BR "defutf8 [ on | off ]"
1865
.RS 0
1859
.RS 0
1866
.PP
1860
.PP
1867
Same as the \fButf8\fP command except that the default setting for new
1861
Same as the \fButf8\fP command except that the default setting for new
Lines 1869-1875 Link Here
1869
\*Q\-U\*U, otherwise `off'.
1863
\*Q\-U\*U, otherwise `off'.
1870
.RE
1864
.RE
1871
.TP
1865
.TP
1872
.BR "defwrap on" | off
1866
.BR "defwrap [ on | off ]"
1873
.RS 0
1867
.RS 0
1874
.PP
1868
.PP
1875
Same as the \fBwrap\fP command except that the default setting for new 
1869
Same as the \fBwrap\fP command except that the default setting for new 
Lines 1877-1883 Link Here
1877
\*Qwrap\*U command (\*QC-a r\*U) or by means of "C-a : wrap on|off".
1871
\*Qwrap\*U command (\*QC-a r\*U) or by means of "C-a : wrap on|off".
1878
.RE
1872
.RE
1879
.TP
1873
.TP
1880
.BR "defwritelock on" | off | auto
1874
.BR "defwritelock [ on | off | auto ]"
1881
.RS 0
1875
.RS 0
1882
.PP
1876
.PP
1883
Same as the \fBwritelock\fP command except that the default setting for new 
1877
Same as the \fBwritelock\fP command except that the default setting for new 
Lines 2043-2049 Link Here
2043
.IR tic .
2037
.IR tic .
2044
.RE
2038
.RE
2045
.TP
2039
.TP
2046
.BR "dynamictitle on" | off
2040
.BR "dynamictitle [ on | off ]"
2047
.RS 0
2041
.RS 0
2048
.PP
2042
.PP
2049
Change behaviour for windows regarding if screen should change window title
2043
Change behaviour for windows regarding if screen should change window title
Lines 2056-2062 Link Here
2056
The echo command may be used to annoy 
2050
The echo command may be used to annoy 
2057
.I screen
2051
.I screen
2058
users with a 'message of the
2052
users with a 'message of the
2059
day'. Typically installed in a global /etc/screenrc.
2053
day'. Typically installed in a global /local/etc/screenrc. 
2060
The option \*Q\-n\*U may be used to suppress the line feed.
2054
The option \*Q\-n\*U may be used to suppress the line feed.
2061
See also \*Qsleep\*U.
2055
See also \*Qsleep\*U.
2062
Echo is also useful for online checking of environment variables.
2056
Echo is also useful for online checking of environment variables.
Lines 2201-2208 Link Here
2201
automatically if the window is displayed more than once.
2195
automatically if the window is displayed more than once.
2202
.RE
2196
.RE
2203
.TP
2197
.TP
2204
.B flow
2198
.BR "flow [ on | off | auto]"
2205
.RB [ on | off | "auto\fR]\fP"
2206
.RS 0
2199
.RS 0
2207
.PP
2200
.PP
2208
Sets the flow-control mode for this window.
2201
Sets the flow-control mode for this window.
Lines 2213-2219 Link Here
2213
Default is set by `defflow'.
2206
Default is set by `defflow'.
2214
.RE
2207
.RE
2215
.TP
2208
.TP
2216
.BR "focus " [ next|prev|up|down|left|right|top|bottom ]
2209
.BR "focus [ next | prev | up | down | left | right | top | bottom ]"
2217
.RS 0
2210
.RS 0
2218
.PP
2211
.PP
2219
Move the input focus to the next region. This is done in a cyclic
2212
Move the input focus to the next region. This is done in a cyclic
Lines 2264-2270 Link Here
2264
This forces any currently selected region to be automatically
2257
This forces any currently selected region to be automatically
2265
resized at least a certain \fIwidth\fP and \fIheight\fP. All
2258
resized at least a certain \fIwidth\fP and \fIheight\fP. All
2266
other surrounding regions will be resized in order to accommodate.
2259
other surrounding regions will be resized in order to accommodate.
2267
This constraint follows everytime the \*Qfocus\*U command is
2260
This constraint follows every time the \*Qfocus\*U command is
2268
used. The \*Qresize\*U command can be used to increase either
2261
used. The \*Qresize\*U command can be used to increase either
2269
dimension of a region, but never below what is set with
2262
dimension of a region, but never below what is set with
2270
\*Qfocusminsize\*U. The underscore `_' is a synonym for
2263
\*Qfocusminsize\*U. The underscore `_' is a synonym for
Lines 2273-2279 Link Here
2273
Without any parameters, the minimum width and height is shown.
2266
Without any parameters, the minimum width and height is shown.
2274
.RE
2267
.RE
2275
.TP
2268
.TP
2276
.BR "gr " [ on | off ]
2269
.BR "gr [ on | off ]"
2277
.RS 0
2270
.RS 0
2278
.PP
2271
.PP
2279
Turn GR charset switching on/off. Whenever screen sees an input
2272
Turn GR charset switching on/off. Whenever screen sees an input
Lines 2303-2309 Link Here
2303
scrollback buffer.
2296
scrollback buffer.
2304
.RE
2297
.RE
2305
.TP
2298
.TP
2306
.BR "hardcopy_append on" | off
2299
.BR "hardcopy_append [ on | off ]"
2307
.RS 0
2300
.RS 0
2308
.PP
2301
.PP
2309
If set to "on", 
2302
If set to "on", 
Lines 2322-2332 Link Here
2322
current working directory.
2315
current working directory.
2323
.RE
2316
.RE
2324
.TP
2317
.TP
2325
.BR "hardstatus " [ on | off ]
2318
.BR "hardstatus [ on | off ]"
2326
.TP
2319
.TP
2327
.BR "hardstatus \fR[\fBalways\fR]\fBfirstline" | lastline | message | ignore [ \fIstring\fR ]
2320
.BR "hardstatus [ always ] firstline | lastline | message | ignore [ string ]"
2328
.TP
2321
.TP
2329
.BR "hardstatus string" [ \fIstring\fR ]
2322
.BR "hardstatus string [ string ]"
2330
.RS 0
2323
.RS 0
2331
.PP
2324
.PP
2332
This command configures the use and emulation of the terminal's
2325
This command configures the use and emulation of the terminal's
Lines 2386-2393 Link Here
2386
.BR help [ \fIclass\fP ]
2379
.BR help [ \fIclass\fP ]
2387
.RS 0
2380
.RS 0
2388
.PP
2381
.PP
2389
Not really a online help, but 
2382
Not really a online help, but displays a help
2390
displays a help 
2391
.I screen 
2383
.I screen 
2392
showing you all the key bindings.
2384
showing you all the key bindings.
2393
The first pages list all the internal commands followed by their current
2385
The first pages list all the internal commands followed by their current
Lines 2432-2438 Link Here
2432
If no arguments are given, the current settings are displayed.
2424
If no arguments are given, the current settings are displayed.
2433
.RE
2425
.RE
2434
.TP
2426
.TP
2435
.BR "ignorecase " [ on | off ]
2427
.BR "ignorecase [ on | off ]"
2436
.RS 0
2428
.RS 0
2437
.PP
2429
.PP
2438
Tell screen to ignore the case of characters in searches. Default is
2430
Tell screen to ignore the case of characters in searches. Default is
Lines 2492-2499 Link Here
2492
(shell) running in the window receives a HANGUP condition, 
2484
(shell) running in the window receives a HANGUP condition, 
2493
the window structure is removed and 
2485
the window structure is removed and 
2494
.I screen 
2486
.I screen 
2495
(your display) switches to another
2487
(your display) switches to another window.  When the last window is destroyed,
2496
window.  When the last window is destroyed, 
2497
.I screen
2488
.I screen
2498
exits.
2489
exits.
2499
After a kill 
2490
After a kill 
Lines 2613-2619 Link Here
2613
\fBlayout autosave\fP command.
2604
\fBlayout autosave\fP command.
2614
.RE
2605
.RE
2615
.TP
2606
.TP
2616
.BR "layout autosave " [\fBon|off\fP]
2607
.BR "layout autosave [ on | off]"
2617
.RS 0
2608
.RS 0
2618
.PP
2609
.PP
2619
Change or display the status of automatcally saving layouts. The
2610
Change or display the status of automatcally saving layouts. The
Lines 2652-2658 Link Here
2652
Display the disclaimer page. This is done whenever
2643
Display the disclaimer page. This is done whenever
2653
.I screen
2644
.I screen
2654
is started without options, which should be often enough. See also 
2645
is started without options, which should be often enough. See also 
2655
the \*Qstartup_message\*U command.
2646
the \fBstartup_message\fP command.
2656
.RE
2647
.RE
2657
.TP
2648
.TP
2658
.B lockscreen
2649
.B lockscreen
Lines 2674-2680 Link Here
2674
shell. This feature should rather be called `lockterminal'.
2665
shell. This feature should rather be called `lockterminal'.
2675
.RE
2666
.RE
2676
.TP
2667
.TP
2677
.BR "log " [ on | off ]
2668
.BR "log [ on | off ]"
2678
.RS 0
2669
.RS 0
2679
.PP
2670
.PP
2680
Start/stop writing output of the current window to a file 
2671
Start/stop writing output of the current window to a file 
Lines 2699-2705 Link Here
2699
default value is 10 seconds.
2690
default value is 10 seconds.
2700
.RE
2691
.RE
2701
.TP
2692
.TP
2702
.BR "login " [ on | off ]
2693
.BR "login [ on | off ]"
2703
.RS 0
2694
.RS 0
2704
.PP
2695
.PP
2705
Adds or removes the entry in the utmp database file for the current window.
2696
Adds or removes the entry in the utmp database file for the current window.
Lines 2798-2804 Link Here
2798
Insert the command character (C-a) in the current window's input stream.
2789
Insert the command character (C-a) in the current window's input stream.
2799
.RE
2790
.RE
2800
.TP
2791
.TP
2801
.BR "monitor " [ on | off ]
2792
.BR "monitor [ on | off ]"
2802
.RS 0
2793
.RS 0
2803
.PP
2794
.PP
2804
Toggles activity monitoring of windows.
2795
Toggles activity monitoring of windows.
Lines 2809-2815 Link Here
2809
Monitoring is initially off for all windows.
2800
Monitoring is initially off for all windows.
2810
.RE
2801
.RE
2811
.TP
2802
.TP
2812
.BR "mousetrack " [ on | off ]
2803
.BR "mousetrack [ on | off ]"
2813
.RS 0
2804
.RS 0
2814
.PP
2805
.PP
2815
This command determines whether
2806
This command determines whether
Lines 2819-2825 Link Here
2819
been split in various ways can be selected by pointing to them
2810
been split in various ways can be selected by pointing to them
2820
with a mouse and left-clicking them. Without specifying \fBon\fP
2811
with a mouse and left-clicking them. Without specifying \fBon\fP
2821
or \fBoff\fP, the current state is displayed. The default state
2812
or \fBoff\fP, the current state is displayed. The default state
2822
is determined by the \*Qdefmousetrack\*U command.
2813
is determined by the \fBdefmousetrack\fP command.
2823
.RE
2814
.RE
2824
.TP
2815
.TP
2825
.BI "msgminwait " sec
2816
.BI "msgminwait " sec
Lines 2839-2845 Link Here
2839
is not disturbed by other activity. The default is 5 seconds.
2830
is not disturbed by other activity. The default is 5 seconds.
2840
.RE
2831
.RE
2841
.TP
2832
.TP
2842
.BR "multiuser on" | off
2833
.BR "multiuser [ on | off ]"
2843
.RS 0
2834
.RS 0
2844
.PP
2835
.PP
2845
Switch between singleuser and multiuser mode. Standard
2836
Switch between singleuser and multiuser mode. Standard
Lines 2851-2857 Link Here
2851
session. 
2842
session. 
2852
.RE
2843
.RE
2853
.TP
2844
.TP
2854
.BR "nethack on" | off
2845
.BR "nethack [ on | off ]"
2855
.RS 0
2846
.RS 0
2856
.PP
2847
.PP
2857
Changes the kind of error messages used by
2848
Changes the kind of error messages used by
Lines 2861-2868 Link Here
2861
much funnier to read. Anyway, standard messages often tend to be unclear as
2852
much funnier to read. Anyway, standard messages often tend to be unclear as
2862
well.
2853
well.
2863
.br
2854
.br
2864
This option is only 
2855
This option is only available if
2865
available if
2866
.I screen
2856
.I screen
2867
was compiled with the NETHACK flag defined. The
2857
was compiled with the NETHACK flag defined. The
2868
default setting is then determined by the presence of the environment 
2858
default setting is then determined by the presence of the environment 
Lines 2877-2884 Link Here
2877
This command can be used repeatedly to cycle through the list of windows.
2867
This command can be used repeatedly to cycle through the list of windows.
2878
.RE
2868
.RE
2879
.PP
2869
.PP
2880
.B nonblock 
2870
.BR "nonblock [ on | off | numsecs ]"
2881
.RB [ on | off | \fInumsecs ]
2882
.RS 0
2871
.RS 0
2883
.PP
2872
.PP
2884
Tell screen how to deal with user interfaces (displays) that cease to
2873
Tell screen how to deal with user interfaces (displays) that cease to
Lines 2925-2931 Link Here
2925
\fIother\fP has the same effect as \fInext\fP.
2914
\fIother\fP has the same effect as \fInext\fP.
2926
.RE
2915
.RE
2927
.TP
2916
.TP
2928
.BR "partial on" | off
2917
.BR "partial [ on | off ]"
2929
.RS 0
2918
.RS 0
2930
.PP
2919
.PP
2931
Defines whether the display should be refreshed (as with \fIredisplay\fP) after
2920
Defines whether the display should be refreshed (as with \fIredisplay\fP) after
Lines 2940-2948 Link Here
2940
.PP
2929
.PP
2941
Present a crypted password in your \*Q.screenrc\*U file and
2930
Present a crypted password in your \*Q.screenrc\*U file and
2942
.I screen
2931
.I screen
2943
will ask
2932
will ask for it, whenever someone attempts to resume a detached.
2944
for it, whenever someone attempts to resume a detached. This is useful
2933
This is useful if you have privileged programs running under
2945
if you have privileged programs running under
2946
.I screen
2934
.I screen
2947
and you want to protect your session from reattach attempts by another user
2935
and you want to protect your session from reattach attempts by another user
2948
masquerading as your uid (i.e. any superuser.)
2936
masquerading as your uid (i.e. any superuser.)
Lines 2960-2981 Link Here
2960
of the current window. The register '.' is treated as the
2948
of the current window. The register '.' is treated as the
2961
paste buffer. If no parameter is given the user is prompted for a single 
2949
paste buffer. If no parameter is given the user is prompted for a single 
2962
register to paste.
2950
register to paste.
2963
The paste buffer can be filled with the \fIcopy\fP, \fIhistory\fP and 
2951
The paste buffer can be filled with the \fBcopy\fP, \fBhistory\fP and
2964
\fIreadbuf\fP commands. 
2952
\fBreadbuf\fP commands.
2965
Other registers can be filled with the \fIregister\fP, \fIreadreg\fP and 
2953
Other registers can be filled with the \fBregister\fP, \fBreadreg\fP and
2966
\fIpaste\fP commands.
2954
\fBpaste\fP commands.
2967
If \fIpaste\fP is called with a second argument, the contents of the specified
2955
If \fBpaste\fP is called with a second argument, the contents of the specified
2968
registers is pasted into the named destination register rather than 
2956
registers is pasted into the named destination register rather than
2969
the window. If '.' is used as the second argument, the displays paste buffer is
2957
the window. If '.' is used as the second argument, the displays paste buffer is
2970
the destination.
2958
the destination.
2971
Note, that \*Qpaste\*U uses a wide variety of resources: Whenever a second 
2959
Note, that \fBpaste\fP uses a wide variety of resources: Whenever a second
2972
argument is specified no current window is needed. When the source specification
2960
argument is specified no current window is needed. When the source specification
2973
only contains registers (not the paste buffer) then there need not be a current 
2961
only contains registers (not the paste buffer) then there need not be a current
2974
display (terminal attached), as the registers are a global resource. The 
2962
display (terminal attached), as the registers are a global resource. The
2975
paste buffer exists once for every user.
2963
paste buffer exists once for every user.
2976
.RE
2964
.RE
2977
.TP
2965
.TP
2978
.BR "pastefont " [ on | off ]
2966
.BR "pastefont [ on | off ]"
2979
.RS 0
2967
.RS 0
2980
.PP
2968
.PP
2981
Tell 
2969
Tell 
Lines 3070-3076 Link Here
3070
Reads the contents of the specified file into the paste buffer.
3058
Reads the contents of the specified file into the paste buffer.
3071
You can tell screen the encoding of the file via the \fB\-e\fP option.
3059
You can tell screen the encoding of the file via the \fB\-e\fP option.
3072
If no file is specified, the screen-exchange filename is used.
3060
If no file is specified, the screen-exchange filename is used.
3073
See also \*Qbufferfile\*U command.
3061
See also \fBbufferfile\fP command.
3074
.RE
3062
.RE
3075
.TP
3063
.TP
3076
.IR "\fBreadreg\fP " [ encoding "] [" register " [" filename ]]
3064
.IR "\fBreadreg\fP " [ encoding "] [" register " [" filename ]]
Lines 3117-3133 Link Here
3117
.B "removebuf"
3105
.B "removebuf"
3118
.RS 0
3106
.RS 0
3119
.PP
3107
.PP
3120
Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and 
3108
Unlinks the screen-exchange file used by the commands
3121
\*Qreadbuf\*U. 
3109
\fBwritebuf\fP and \fBreadbuf\fP.
3122
.RE
3110
.RE
3123
.TP
3111
.TP
3124
.B "rendition bell" | monitor | silence | so " \fIattr\fR " \fR[\fP \fIcolor\fP \fR]\fP
3112
.B "rendition [ bell | monitor | silence | so ] attr [ color ]"
3125
.RS 0
3113
.RS 0
3126
.PP
3114
.PP
3127
Change the way
3115
Change the way
3128
.I screen
3116
.I screen
3129
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.
3117
renders the titles of windows that have monitor or bell flags set in
3130
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.
3118
caption or hardstatus or windowlist. See the \*QSTRING ESCAPES\*U
3119
chapter for the syntax of the modifiers.
3120
The default for monitor is currently \*Q=b \*U (bold, active colors),
3121
for bell \*Q=ub \*U (underline, bold and active colors), and \*Q=u \*U
3122
for silence.
3131
.RE
3123
.RE
3132
.TP
3124
.TP
3133
.B "reset"
3125
.B "reset"
Lines 3197-3203 Link Here
3197
.I screen
3189
.I screen
3198
will prompt for how you would like to resize the current region.
3190
will prompt for how you would like to resize the current region.
3199
3191
3200
See \*Qfocusminsize\*U if you want to restrict the minimun size a region
3192
See \*Qfocusminsize\*U if you want to restrict the minimum size a region
3201
can have.
3193
can have.
3202
.RE
3194
.RE
3203
.RE
3195
.RE
Lines 3294-3300 Link Here
3294
and value. The environment is inherited by all subsequently forked shells.
3286
and value. The environment is inherited by all subsequently forked shells.
3295
.RE
3287
.RE
3296
.TP
3288
.TP
3297
.BR "setsid " [ on | off ]
3289
.BR "setsid [ on | off ]"
3298
.RS 0
3290
.RS 0
3299
.PP
3291
.PP
3300
Normally screen uses different sessions and process groups for
3292
Normally screen uses different sessions and process groups for
Lines 3326-3332 Link Here
3326
entitled \*QTITLES (naming windows)\*U.
3318
entitled \*QTITLES (naming windows)\*U.
3327
.RE
3319
.RE
3328
.TP
3320
.TP
3329
.BR "silence " [ on | off "|\fIsec\fP]"
3321
.BR "silence [ on | off | sec ]"
3330
.RS 0
3322
.RS 0
3331
.PP
3323
.PP
3332
Toggles silence monitoring of windows.
3324
Toggles silence monitoring of windows.
Lines 3414-3431 Link Here
3414
With this current implementation of screen, scrolling data
3406
With this current implementation of screen, scrolling data
3415
will appear much slower in a vertically split region than one
3407
will appear much slower in a vertically split region than one
3416
that is not. This should be taken into consideration if you need
3408
that is not. This should be taken into consideration if you need
3417
to use system commands such as \*Qcat\*U or \*Qtail -f\*U.
3409
to use system commands such as \fBcat\fP or \fBtail -f\fP.
3418
.RE
3410
.RE
3419
.TP
3411
.TP
3420
.B "startup_message on\fP|\fBoff"
3412
.B "startup_message [ on | off ]"
3421
.RS 0
3413
.RS 0
3422
.PP
3414
.PP
3423
Select whether you want to see the copyright notice during startup.
3415
Select whether you want to see the copyright notice during startup.
3424
Default is `on', as you probably noticed.
3416
Default is `on', as you probably noticed.
3425
.RE
3417
.RE
3426
.PP
3418
.PP
3427
.BR "status " [ top | up | down | bottom ]
3419
.BR "status [ top | up | down | bottom ] [ left | right ]"
3428
.RB [ left | right ]
3429
.RS 0
3420
.RS 0
3430
.PP
3421
.PP
3431
The status window by default is in bottom-left corner. This command can move
3422
The status window by default is in bottom-left corner. This command can move
Lines 3630-3636 Link Here
3630
Unset an environment variable.
3621
Unset an environment variable.
3631
.RE
3622
.RE
3632
.TP
3623
.TP
3633
.BR "utf8 " [ on | off [ on | off ]]
3624
.BR "utf8 [ on | off [ on | off ]]"
3634
.RS 0
3625
.RS 0
3635
.PP
3626
.PP
3636
Change the encoding used in the current window. If utf8 is enabled, the
3627
Change the encoding used in the current window. If utf8 is enabled, the
Lines 3642-3648 Link Here
3642
window.
3633
window.
3643
.RE
3634
.RE
3644
.TP
3635
.TP
3645
.BR "vbell " [ on | off ]
3636
.BR "vbell [ on | off ]"
3646
.RS 0
3637
.RS 0
3647
.PP
3638
.PP
3648
Sets the visual bell setting for this window. Omitting the parameter
3639
Sets the visual bell setting for this window. Omitting the parameter
Lines 3674-3680 Link Here
3674
visual bell message. The default is 1 second.
3665
visual bell message. The default is 1 second.
3675
.RE
3666
.RE
3676
.TP
3667
.TP
3677
.BR "verbose " [ on | off ]
3668
.BR "verbose [ on | off ]"
3678
.RS 0
3669
.RS 0
3679
.PP
3670
.PP
3680
If verbose is switched on, the command name is echoed, whenever a window
3671
If verbose is switched on, the command name is echoed, whenever a window
Lines 3711-3717 Link Here
3711
vice versa.
3702
vice versa.
3712
.RE
3703
.RE
3713
.TP
3704
.TP
3714
.BR "windowlist " [ \-b "] [" \-m "] [" \-g ]
3705
.BR "windowlist [ \-b ] [ \-m ] [ \-g ]"
3715
.TP
3706
.TP
3716
.IR "\fBwindowlist string\fR " [ string ]
3707
.IR "\fBwindowlist string\fR " [ string ]
3717
.TP
3708
.TP
Lines 3819-3825 Link Here
3819
The default command without any parameter is limited to a size of 1024 bytes.
3810
The default command without any parameter is limited to a size of 1024 bytes.
3820
.RE
3811
.RE
3821
.TP
3812
.TP
3822
.BR "wrap " [ on | off ]
3813
.BR "wrap [ on | off ]"
3823
.RS 0
3814
.RS 0
3824
.PP
3815
.PP
3825
Sets the line-wrap setting for the current window.
3816
Sets the line-wrap setting for the current window.
Lines 3842-3848 Link Here
3842
command and defaults to \*Q/tmp/screen\-exchange\*U.
3833
command and defaults to \*Q/tmp/screen\-exchange\*U.
3843
.RE
3834
.RE
3844
.TP
3835
.TP
3845
.BR "writelock " [ on | "off\fR|\fBauto\fR]"
3836
.BR "writelock [ on | off | auto]"
3846
.RS 0
3837
.RS 0
3847
.PP
3838
.PP
3848
In addition to access control lists, not all users may be able to write to
3839
In addition to access control lists, not all users may be able to write to
Lines 3864-3870 Link Here
3864
current window.
3855
current window.
3865
.RE
3856
.RE
3866
.TP
3857
.TP
3867
.BR "zmodem " [ off\fR|\fPauto\fR|\fPcatch\fR|\fPpass ]
3858
.BR "zmodem [ off | auto | catch | pass ]"
3868
.TP
3859
.TP
3869
.IR "\fBzmodem sendcmd\fR " [ string ]
3860
.IR "\fBzmodem sendcmd\fR " [ string ]
3870
.TP
3861
.TP
Lines 4068-4073 Link Here
4068
the escape character itself
4059
the escape character itself
4069
.IP E
4060
.IP E
4070
sets %? to true if the escape character has been pressed.
4061
sets %? to true if the escape character has been pressed.
4062
.IP e
4063
encoding
4071
.IP f
4064
.IP f
4072
flags of the window, see \*Qwindows\*U for meanings of the various flags
4065
flags of the window, see \*Qwindows\*U for meanings of the various flags
4073
.IP F
4066
.IP F
Lines 4163-4169 Link Here
4163
.IP r
4156
.IP r
4164
reverse
4157
reverse
4165
.IP s
4158
.IP s
4166
standout
4159
/standout
4167
.IP B
4160
.IP B
4168
blinking
4161
blinking
4169
.PD
4162
.PD
Lines 4347-4355 Link Here
4347
history recall commands.
4340
history recall commands.
4348
.PP
4341
.PP
4349
Here's some .screenrc examples:
4342
Here's some .screenrc examples:
4350
.IP
4343
.sp
4351
screen \-t top 2 nice top
4344
.nf
4352
.PP
4345
	screen \-t top 2 nice top
4346
.fi
4347
.sp
4353
Adding this line to your .screenrc would start a nice-d version of the
4348
Adding this line to your .screenrc would start a nice-d version of the
4354
\*Qtop\*U command in window 2 named \*Qtop\*U rather than \*Qnice\*U.
4349
\*Qtop\*U command in window 2 named \*Qtop\*U rather than \*Qnice\*U.
4355
.sp
4350
.sp
Lines 4361-4375 Link Here
4361
These commands would start a shell with the given shelltitle.
4356
These commands would start a shell with the given shelltitle.
4362
The title specified is an auto-title that would expect the prompt and
4357
The title specified is an auto-title that would expect the prompt and
4363
the typed command to look something like the following:
4358
the typed command to look something like the following:
4364
.IP
4359
.sp
4365
/usr/joe/src/dir> trn
4360
.nf
4366
.PP
4361
	/usr/joe/src/dir> trn
4362
.fi
4363
.sp
4367
(it looks after the '> ' for the command name).
4364
(it looks after the '> ' for the command name).
4368
The window status would show the name \*Qtrn\*U while the command was
4365
The window status would show the name \*Qtrn\*U while the command was
4369
running, and revert to \*Qcsh\*U upon completion.
4366
running, and revert to \*Qcsh\*U upon completion.
4370
.IP
4367
.sp
4371
bind R screen \-t '% |root:' su
4368
.nf
4372
.PP
4369
	bind R screen \-t '% |root:' su
4370
.fi
4371
.sp
4373
Having this command in your .screenrc would bind the key
4372
Having this command in your .screenrc would bind the key
4374
sequence \*QC-a R\*U to the \*Qsu\*U command and give it an
4373
sequence \*QC-a R\*U to the \*Qsu\*U command and give it an
4375
auto-title name of \*Qroot:\*U.
4374
auto-title name of \*Qroot:\*U.
Lines 4404-4420 Link Here
4404
If these invisible characters aren't a multiple of 8 then backspacing over
4403
If these invisible characters aren't a multiple of 8 then backspacing over
4405
a tab will result in an incorrect display.
4404
a tab will result in an incorrect display.
4406
One way to get around this is to use a prompt like this:
4405
One way to get around this is to use a prompt like this:
4407
.IP
4406
.sp
4408
set prompt='^[[0000m^[k^[\e% '
4407
.nf
4409
.PP
4408
	set prompt='^[[0000m^[k^[\e% '
4409
.fi
4410
.sp
4410
The escape-sequence \*Q<esc>[0000m\*U not only normalizes the character
4411
The escape-sequence \*Q<esc>[0000m\*U not only normalizes the character
4411
attributes, but all the zeros round the length of the invisible characters
4412
attributes, but all the zeros round the length of the invisible characters
4412
up to 8.
4413
up to 8.
4413
Bash users will probably want to echo the escape sequence in the
4414
Bash users will probably want to echo the escape sequence in the
4414
PROMPT_COMMAND:
4415
PROMPT_COMMAND:
4415
.IP
4416
.sp
4416
PROMPT_COMMAND='printf "\e033k\e033\e134"'
4417
.nf
4417
.PP
4418
	PROMPT_COMMAND='printf "\e033k\e033\e134"'
4419
.fi
4420
.sp
4418
(I used \*Q\e134\*U to output a `\e' because of a bug in bash v1.04).
4421
(I used \*Q\e134\*U to output a `\e' because of a bug in bash v1.04).
4419
4422
4420
4423
Lines 5202-5213 Link Here
5202
.I screen
5205
.I screen
5203
distribution package for private and global initialization files.
5206
distribution package for private and global initialization files.
5204
.IP $SYSSCREENRC 
5207
.IP $SYSSCREENRC 
5205
.IP /etc/screenrc
5208
.IP /usr/local/etc/screenrc
5206
.I screen
5209
.I screen
5207
initialization commands
5210
initialization commands
5208
.IP $SCREENRC
5211
.IP $SCREENRC
5209
.IP $HOME/.screenrc
5212
.IP $HOME/.screenrc
5210
Read in after /etc/screenrc
5213
Read in after /usr/local/etc/screenrc
5211
.IP $SCREENDIR/S\-<login>
5214
.IP $SCREENDIR/S\-<login>
5212
.IP /local/screens/S\-<login>
5215
.IP /local/screens/S\-<login>
5213
Socket directories (default)
5216
Socket directories (default)
Lines 5228-5243 Link Here
5228
or
5231
or
5229
.IP /etc/termcap
5232
.IP /etc/termcap
5230
Terminal capability databases
5233
Terminal capability databases
5231
.IP /var/run/utmp
5234
.IP /etc/utmp
5232
Login records
5235
Login records
5233
.IP $LOCKPRG
5236
.IP $LOCKPRG
5234
Program that locks a terminal.
5237
Program that locks a terminal.
5235
5238
5236
5237
.SH "SEE ALSO"
5238
termcap(5), utmp(5), vi(1), captoinfo(1), tic(1)
5239
5240
5241
.SH AUTHORS
5239
.SH AUTHORS
5242
Originally created by Oliver Laumann. For a long time maintained
5240
Originally created by Oliver Laumann. For a long time maintained
5243
and developed by Juergen Weigert, Michael Schroeder, Micah Cowan
5241
and developed by Juergen Weigert, Michael Schroeder, Micah Cowan
Lines 5247-5253 Link Here
5247
5245
5248
.SH COPYLEFT
5246
.SH COPYLEFT
5249
.nf
5247
.nf
5250
Copyright (c) 2018-2020
5248
Copyright (c) 2018-2022
5251
	Alexander Naumov <alexander_naumov@opensuse.org>
5249
	Alexander Naumov <alexander_naumov@opensuse.org>
5252
	Amadeusz Slawinski <amade@asmblr.net>
5250
	Amadeusz Slawinski <amade@asmblr.net>
5253
Copyright (c) 2015-2017
5251
Copyright (c) 2015-2017
Lines 5267-5272 Link Here
5267
	Michael Schroeder <mlschroe@immd4.informatik.uni\-erlangen.de>
5265
	Michael Schroeder <mlschroe@immd4.informatik.uni\-erlangen.de>
5268
Copyright (C) 1987 Oliver Laumann
5266
Copyright (C) 1987 Oliver Laumann
5269
.fi
5267
.fi
5268
5270
.PP
5269
.PP
5271
This program is free software; you can redistribute it and/or modify
5270
This program is free software; you can redistribute it and/or modify
5272
it under the terms of the GNU General Public License as published by
5271
it under the terms of the GNU General Public License as published by
Lines 5324-5333 Link Here
5324
.I screen
5323
.I screen
5325
available via anonymous ftp from ftp.gnu.org/gnu/screen/ or any other 
5324
available via anonymous ftp from ftp.gnu.org/gnu/screen/ or any other 
5326
.I GNU 
5325
.I GNU 
5327
distribution site. The home site of
5326
distribution site. The home page of
5328
.I screen
5327
.I screen
5329
is savannah.gnu.org/projects/screen/. If you want to help, send a note to
5328
is https://savannah.gnu.org/projects/screen/ and the git repo
5330
screen-devel@gnu.org.
5329
is https://git.savannah.gnu.org/cgit/screen.git.
5330
If you want to help, send a note to
5331
.BR screen-devel@gnu.org.
5331
5332
5332
.SH BUGS
5333
.SH BUGS
5333
.PD
5334
.PD
Lines 5355-5363 Link Here
5355
must be installed as set-uid with owner root on most systems in order
5356
must be installed as set-uid with owner root on most systems in order
5356
to be able to correctly change the owner of the tty device file for
5357
to be able to correctly change the owner of the tty device file for
5357
each window.
5358
each window.
5358
Special permission may also be required to write the file \*Q/var/run/utmp\*U.
5359
Special permission may also be required to write the file \*Q/etc/utmp\*U.
5359
.IP \(bu
5360
.IP \(bu
5360
Entries in \*Q/var/run/utmp\*U are not removed when
5361
Entries in \*Q/etc/utmp\*U are not removed when
5361
.I screen
5362
.I screen
5362
is killed with SIGKILL.
5363
is killed with SIGKILL.
5363
This will cause some programs (like "w" or "rwho")
5364
This will cause some programs (like "w" or "rwho")
Lines 5387-5393 Link Here
5387
file from which the session is booted, or have to be changed manually.
5388
file from which the session is booted, or have to be changed manually.
5388
.IP \(bu
5389
.IP \(bu
5389
A weird imagination is most useful to gain full advantage of all the features.
5390
A weird imagination is most useful to gain full advantage of all the features.
5390
.IP \(bu
5391
.PP
5391
Send bug-reports, fixes, enhancements, t-shirts, money, beer & pizza to
5392
Send bug-reports, fixes, enhancements, t-shirts, money, beer & pizza to
5392
.BR screen-devel@gnu.org .
5393
.BR screen-devel@gnu.org .
5393
5394
5395
.SH "SEE ALSO"
5396
.BR termcap(5),
5397
.BR utmp(5),
5398
.BR vi(1),
5399
.BR captoinfo(1),
5400
.BR tic(1),
5401
.BR tty(4),
5402
.BR pty(7)
(-)screen.orig/doc/screen.texinfo (-30 / +26 lines)
Lines 4-17 Link Here
4
@documentencoding ISO-8859-15
4
@documentencoding ISO-8859-15
5
@setfilename screen.info
5
@setfilename screen.info
6
@settitle Screen User's Manual
6
@settitle Screen User's Manual
7
@dircategory Terminals
7
@dircategory General Commands
8
@finalout
8
@finalout
9
@setchapternewpage odd
9
@setchapternewpage odd
10
@c %**end of header
10
@c %**end of header
11
@set version 4.8.0
11
@set version 4.9.0
12
12
13
@direntry
13
@direntry
14
* Screen: (screen).             The virtual terminal manager.
14
* Screen: (screen).             Full-screen window manager.
15
@end direntry
15
@end direntry
16
16
17
@c For examples, use a literal escape in info.
17
@c For examples, use a literal escape in info.
Lines 25-31 Link Here
25
@ifinfo
25
@ifinfo
26
This file documents the @code{Screen} virtual terminal manager.
26
This file documents the @code{Screen} virtual terminal manager.
27
27
28
Copyright (c) 1993-2018 Free Software Foundation, Inc.
28
Copyright (c) 1993-2022 Free Software Foundation, Inc.
29
29
30
Permission is granted to make and distribute verbatim copies of
30
Permission is granted to make and distribute verbatim copies of
31
this manual provided the copyright notice and this permission notice
31
this manual provided the copyright notice and this permission notice
Lines 53-63 Link Here
53
@title Screen
53
@title Screen
54
@subtitle The virtual terminal manager
54
@subtitle The virtual terminal manager
55
@subtitle for Version @value{version}
55
@subtitle for Version @value{version}
56
@subtitle Feb 2020
56
@subtitle Jan 2022
57
57
58
@page
58
@page
59
@vskip 0pt plus 1filll
59
@vskip 0pt plus 1filll
60
Copyright @copyright{} 1993-2018 Free Software Foundation, Inc.
60
Copyright @copyright{} 1993-2022 Free Software Foundation, Inc.
61
61
62
Permission is granted to make and distribute verbatim copies of
62
Permission is granted to make and distribute verbatim copies of
63
this manual provided the copyright notice and this permission notice
63
this manual provided the copyright notice and this permission notice
Lines 185-191 Link Here
185
the invoking shell to the application (emacs in this case), because it is
185
the invoking shell to the application (emacs in this case), because it is
186
forked from the parent screen process, not from the invoking shell.
186
forked from the parent screen process, not from the invoking shell.
187
187
188
If @file{/var/run/utmp} is writable by @code{screen}, an appropriate record
188
If @file{/etc/utmp} is writable by @code{screen}, an appropriate record
189
will be written to this file for each window, and removed when the
189
will be written to this file for each window, and removed when the
190
window is closed.  This is useful for working with @code{talk},
190
window is closed.  This is useful for working with @code{talk},
191
@code{script}, @code{shutdown}, @code{rsend}, @code{sccs} and other
191
@code{script}, @code{shutdown}, @code{rsend}, @code{sccs} and other
Lines 314-320 Link Here
314
314
315
@item -l
315
@item -l
316
@itemx -ln
316
@itemx -ln
317
Turn login mode on or off (for @file{/var/run/utmp} updating).  This option
317
Turn login mode on or off (for @file{/etc/utmp} updating).  This option
318
is equivalent to the @code{deflogin} command (@pxref{Login}).
318
is equivalent to the @code{deflogin} command (@pxref{Login}).
319
319
320
@item -ls [@var{match}]
320
@item -ls [@var{match}]
Lines 333-345 Link Here
333
Ask your system administrator if you are not sure.
333
Ask your system administrator if you are not sure.
334
Remove sessions with the @samp{-wipe} option.
334
Remove sessions with the @samp{-wipe} option.
335
335
336
@emph{Note}:
337
  If sockets are missing (and because of this, your sessions are not
338
  listed), you may send a @code{SIGCHLD} to its `SCREEN'
339
  process and the process will re-establish the socket (think of
340
  someone cleaning @file{/tmp} thoroughly).
341
342
343
@item -L
336
@item -L
344
Tell @code{screen} to turn on automatic output logging for the
337
Tell @code{screen} to turn on automatic output logging for the
345
windows.
338
windows.
Lines 504-517 Link Here
504
@cindex screenrc
497
@cindex screenrc
505
When @code{screen} is invoked, it executes initialization commands from
498
When @code{screen} is invoked, it executes initialization commands from
506
the files @file{.screenrc} in the user's home directory and
499
the files @file{.screenrc} in the user's home directory and
507
@file{/etc/screenrc}.  These defaults can be overridden in the
500
@file{/usr/local/etc/screenrc}.  These defaults can be overridden in the 
508
following ways:
501
following ways:
509
For the global screenrc file @code{screen} searches for the environment
502
For the global screenrc file @code{screen} searches for the environment
510
variable @code{$SYSSCREENRC} (this override feature may be disabled at
503
variable @code{$SYSSCREENRC} (this override feature may be disabled at
511
compile-time).  The user specific screenrc file is
504
compile-time).  The user specific screenrc file is
512
searched for in @code{$SCREENRC}, then 
505
searched for in @code{$SCREENRC}, then 
513
@file{@code{$HOME}/.screenrc}.  The command line option @samp{-c}
506
@file{@code{$HOME}/.screenrc}.  The command line option @samp{-c}
514
specifies which file to use (@pxref{Invoking Screen}.  Commands in these
507
specifies which file to use (@pxref{Invoking Screen}).  Commands in these
515
files are used to set options, bind commands to keys, and to
508
files are used to set options, bind commands to keys, and to
516
automatically establish one or more windows at the beginning of
509
automatically establish one or more windows at the beginning of
517
your @code{screen} session.  Commands are listed one per line, with
510
your @code{screen} session.  Commands are listed one per line, with
Lines 1096-1102 Link Here
1096
@item logfile @var{filename}
1089
@item logfile @var{filename}
1097
Place where to collect logfiles.  @xref{Log}.
1090
Place where to collect logfiles.  @xref{Log}.
1098
@item login [@var{state}]
1091
@item login [@var{state}]
1099
Log the window in @file{/var/run/utmp}.  @xref{Login}.
1092
Log the window in @file{/etc/utmp}.  @xref{Login}.
1100
@item logtstamp [@var{state}]
1093
@item logtstamp [@var{state}]
1101
Configure logfile time-stamps.  @xref{Log}.
1094
Configure logfile time-stamps.  @xref{Log}.
1102
@item mapdefault
1095
@item mapdefault
Lines 2219-2225 Link Here
2219
Without any arguments, @code{screen} will prompt for how you would
2212
Without any arguments, @code{screen} will prompt for how you would
2220
like to resize the current region.
2213
like to resize the current region.
2221
2214
2222
See @code{focusminsize} if you want to restrict the minimun size a region can have.
2215
See @code{focusminsize} if you want to restrict the minimum size a region can have.
2223
2216
2224
@end deffn
2217
@end deffn
2225
2218
Lines 2412-2418 Link Here
2412
* Naming Windows::		Control the name of the window
2405
* Naming Windows::		Control the name of the window
2413
* Console::			See the host's console messages
2406
* Console::			See the host's console messages
2414
* Kill::                        Destroy an unwanted window
2407
* Kill::                        Destroy an unwanted window
2415
* Login::                       Control @file{/var/run/utmp} logging
2408
* Login::                       Control @file{/etc/utmp} logging
2416
* Mode::                        Control the file mode of the pty
2409
* Mode::                        Control the file mode of the pty
2417
* Monitor::                     Watch for activity or inactivity in a window
2410
* Monitor::                     Watch for activity or inactivity in a window
2418
* Windows::			List the active windows
2411
* Windows::			List the active windows
Lines 2621-2627 Link Here
2621
@kindex L
2614
@kindex L
2622
@deffn Command login [state]
2615
@deffn Command login [state]
2623
(@kbd{C-a L})@*
2616
(@kbd{C-a L})@*
2624
Adds or removes the entry in @file{/var/run/utmp} for the current window.
2617
Adds or removes the entry in @file{/etc/utmp} for the current window.
2625
This controls whether or not the window is @dfn{logged in}.  In addition
2618
This controls whether or not the window is @dfn{logged in}.  In addition
2626
to this toggle, it is convenient to have ``log in'' and ``log out''
2619
to this toggle, it is convenient to have ``log in'' and ``log out''
2627
keys.  For instance, @code{bind I login on} and @code{bind O 
2620
keys.  For instance, @code{bind I login on} and @code{bind O 
Lines 3696-3702 Link Here
3696
3689
3697
@noindent
3690
@noindent
3698
@kbd{f}/@kbd{F}, @kbd{t}/@kbd{T} move the cursor forward/backward to the 
3691
@kbd{f}/@kbd{F}, @kbd{t}/@kbd{T} move the cursor forward/backward to the 
3699
next occurence of the target. (eg, '3fy' will move the cursor to the 3rd 
3692
next occurrence of the target. (eg, '3fy' will move the cursor to the 3rd
3700
'y' to the right.)
3693
'y' to the right.)
3701
3694
3702
@noindent
3695
@noindent
Lines 3877-3883 Link Here
3877
(none)@*
3870
(none)@*
3878
Stuff the string @var{string} in the input buffer of the current window.
3871
Stuff the string @var{string} in the input buffer of the current window.
3879
This is like the @code{paste} command, but with much less overhead.
3872
This is like the @code{paste} command, but with much less overhead.
3880
Without a paramter, @code{screen} will prompt for a string to stuff.
3873
Without a parameter, @code{screen} will prompt for a string to stuff.
3881
You cannot paste large buffers with the @code{stuff} command. It is most
3874
You cannot paste large buffers with the @code{stuff} command. It is most
3882
useful for key bindings. @xref{Bindkey}.
3875
useful for key bindings. @xref{Bindkey}.
3883
@end deffn
3876
@end deffn
Lines 5328-5334 Link Here
5328
load averages over 1, 5, and 15 minutes (if this is available on your
5321
load averages over 1, 5, and 15 minutes (if this is available on your
5329
system).  For window-specific information use @code{info} (@pxref{Info}).
5322
system).  For window-specific information use @code{info} (@pxref{Info}).
5330
If a @var{string} is specified, it changes the format of the time report
5323
If a @var{string} is specified, it changes the format of the time report
5331
like it is described in the string escapes chapter (@pxref{String Escapes}). Screen uses a default of @samp{%c:%s %M %d %H%? %l%?}.
5324
like it is described in the string escapes chapter (@pxref{String Escapes}).
5325
Screen uses a default of @samp{%c:%s %M %d %H%? %l%?}.
5332
@end deffn
5326
@end deffn
5333
5327
5334
@node Verbose, Version, Time, Miscellaneous
5328
@node Verbose, Version, Time, Miscellaneous
Lines 5578-5583 Link Here
5578
weekday name
5572
weekday name
5579
@item E
5573
@item E
5580
sets %? to true if the escape character has been pressed.
5574
sets %? to true if the escape character has been pressed.
5575
@item e
5576
encoding
5581
@item f
5577
@item f
5582
flags of the window. @xref{Windows}, for meanings of the various flags.
5578
flags of the window. @xref{Windows}, for meanings of the various flags.
5583
@item F
5579
@item F
Lines 5809-5821 Link Here
5809
global initialization files.
5805
global initialization files.
5810
5806
5811
@item @code{$SYSSCREENRC}
5807
@item @code{$SYSSCREENRC}
5812
@itemx /etc/screenrc
5808
@itemx /local/etc/screenrc
5813
@code{screen} initialization commands
5809
@code{screen} initialization commands
5814
5810
5815
@item @code{$SCREENRC}
5811
@item @code{$SCREENRC}
5816
@itemx @code{$HOME}/.iscreenrc
5812
@itemx @code{$HOME}/.iscreenrc
5817
@itemx @code{$HOME}/.screenrc
5813
@itemx @code{$HOME}/.screenrc
5818
Read in after /etc/screenrc
5814
Read in after /local/etc/screenrc
5819
5815
5820
@item @code{$SCREENDIR}/S-@var{login}
5816
@item @code{$SCREENDIR}/S-@var{login}
5821
5817
Lines 5842-5848 Link Here
5842
@itemx /etc/termcap
5838
@itemx /etc/termcap
5843
Terminal capability databases
5839
Terminal capability databases
5844
5840
5845
@item /var/run/utmp
5841
@item /etc/utmp
5846
Login records
5842
Login records
5847
5843
5848
@item @code{$LOCKPRG}
5844
@item @code{$LOCKPRG}
Lines 5954-5963 Link Here
5954
in order to be able to
5950
in order to be able to
5955
correctly change the owner of the tty device file for each window.
5951
correctly change the owner of the tty device file for each window.
5956
Special permission may also be required to write the file
5952
Special permission may also be required to write the file
5957
@file{/var/run/utmp}.
5953
@file{/etc/utmp}.
5958
5954
5959
@item
5955
@item
5960
Entries in @file{/var/run/utmp} are not removed when @code{screen} is killed
5956
Entries in @file{/etc/utmp} are not removed when @code{screen} is killed
5961
with SIGKILL.  This will cause some programs (like "w" or "rwho") to
5957
with SIGKILL.  This will cause some programs (like "w" or "rwho") to
5962
advertise that a user is logged on who really isn't.
5958
advertise that a user is logged on who really isn't.
5963
5959
Lines 5995-6001 Link Here
5995
@section Reporting Bugs
5991
@section Reporting Bugs
5996
@cindex bug report
5992
@cindex bug report
5997
5993
5998
If you find a bug in @code{Screen}, please send electronic mail to
5994
If you find a bug in @code{Screen}, please send mail to
5999
@w{@samp{screen-devel@@gnu.org}}.  Include the version number
5995
@w{@samp{screen-devel@@gnu.org}}.  Include the version number
6000
of @code{Screen} which you are using.  Also include in your message the
5996
of @code{Screen} which you are using.  Also include in your message the
6001
hardware and operating system, the compiler used to compile, a
5997
hardware and operating system, the compiler used to compile, a
(-)screen.orig/encoding.c (-1 / +1 lines)
Lines 1264-1270 Link Here
1264
  };
1264
  };
1265
1265
1266
  if (c >= 0xdf00 && c <= 0xdfff)
1266
  if (c >= 0xdf00 && c <= 0xdfff)
1267
    return 1;          /* dw combining sequence */
1267
    return 1;			/* dw combining sequence */
1268
  return ((bisearch(c, wide, sizeof(wide) / sizeof(struct interval) - 1)) ||
1268
  return ((bisearch(c, wide, sizeof(wide) / sizeof(struct interval) - 1)) ||
1269
          (cjkwidth &&
1269
          (cjkwidth &&
1270
           bisearch(c, ambiguous,
1270
           bisearch(c, ambiguous,
(-)screen.orig/etc/etcscreenrc (-8 / +1 lines)
Lines 1-6 Link Here
1
#
1
#
2
# This is an example for the global screenrc file.
2
# This is an example for the global screenrc file.
3
# You may want to install this file as /etc/screenrc.
3
# You may want to install this file as /usr/local/etc/screenrc.
4
# Check config.h for the exact location.
4
# Check config.h for the exact location.
5
#
5
#
6
# Flaws of termcap and standard settings are done here.
6
# Flaws of termcap and standard settings are done here.
Lines 92-101 Link Here
92
bind O login off
92
bind O login off
93
bind } history
93
bind } history
94
94
95
# Red Hat Hack^H^H^H^HPatch
96
# This makes screen treat backspaces '^?' as
97
# deletes. There should be a fix in the code
98
# for the way termcap inheritance works,
99
# but I dont know where to put it, and this works.
100
bindkey -d -k kb stuff \010
101
# /Red Hat Patch
(-)screen.orig/etc/screenrc (-9 lines)
Lines 130-144 Link Here
130
register ] "\033:se ai\015a"
130
register ] "\033:se ai\015a"
131
bind ^] paste [.]
131
bind ^] paste [.]
132
132
133
# Red Hat Hack^H^H^H^HPatch
134
# This makes screen treat backspaces '^?' as
135
# deletes. There should be a fix in the code
136
# for the way termcap inheritance works,
137
# but I dont know where to put it, and this works.
138
bindkey -d -k kb stuff \010
139
# /Red Hat Patch
140
141
142
################
133
################
143
#
134
#
144
# default windows
135
# default windows
(-)screen.orig/extern.h (-1 / +1 lines)
Lines 75-81 Link Here
75
extern int   GetAnsiStatus __P((struct win *, char *));
75
extern int   GetAnsiStatus __P((struct win *, char *));
76
extern void  WNewAutoFlow __P((struct win *, int));
76
extern void  WNewAutoFlow __P((struct win *, int));
77
extern void  WBell __P((struct win *, int));
77
extern void  WBell __P((struct win *, int));
78
extern void  WMsg __P((struct win *, int, const char *));
78
extern void  WMsg __P((struct win *, int, char *));
79
extern void  WChangeSize __P((struct win *, int, int));
79
extern void  WChangeSize __P((struct win *, int, int));
80
extern void  WindowChanged __P((struct win *, int));
80
extern void  WindowChanged __P((struct win *, int));
81
extern int   MFindUsedLine __P((struct win *, int, int));
81
extern int   MFindUsedLine __P((struct win *, int, int));
(-)screen.orig/FAQ (-1 / +1 lines)
Lines 191-197 Link Here
191
Q:   The "talk" command does not work when Screen is active.
191
Q:   The "talk" command does not work when Screen is active.
192
 
192
 
193
A:   Talk  and several  other programs  rely on entries  in the  Utmp-
193
A:   Talk  and several  other programs  rely on entries  in the  Utmp-
194
     Database  (/var/run/utmp).  On some  systems this  Database is  world 
194
     Database  (/etc/utmp).  On some  systems this  Database is  world 
195
     writable,  on others  it is not.  If it  is not,  screen must  be 
195
     writable,  on others  it is not.  If it  is not,  screen must  be 
196
     installed with the appropriate  permissions (user or group s-bit)
196
     installed with the appropriate  permissions (user or group s-bit)
197
     just like any  program that uses  PTYs (rlogin, xterm, ...). When
197
     just like any  program that uses  PTYs (rlogin, xterm, ...). When
(-)screen.orig/fileio.c (-628 / +635 lines)
Lines 42-150 Link Here
42
extern struct display *display, *displays;
42
extern struct display *display, *displays;
43
extern struct win *fore;
43
extern struct win *fore;
44
extern struct layer *flayer;
44
extern struct layer *flayer;
45
extern int ServerSocket;
45
extern int    ServerSocket;
46
extern int real_uid, eff_uid;
46
extern int    real_uid, eff_uid;
47
extern int real_gid, eff_gid;
47
extern int    real_gid, eff_gid;
48
extern char *extra_incap, *extra_outcap;
48
extern char  *extra_incap, *extra_outcap;
49
extern char *home, *RcFileName;
49
extern char  *home, *RcFileName;
50
extern char SockPath[], *SockName;
50
extern char   SockPath[], *SockName;
51
#ifdef COPY_PASTE
51
#ifdef COPY_PASTE
52
extern char *BufferFile;
52
extern char  *BufferFile;
53
#endif
53
#endif
54
extern int hardcopy_append;
54
extern int    hardcopy_append;
55
extern char *hardcopydir;
55
extern char  *hardcopydir;
56
57
static char *CatExtra __P((char *, char *));
58
static char *findrcfile __P((char *));
59
56
57
static char  *CatExtra __P((char *, char *));
58
static char  *findrcfile __P((char *));
60
59
61
char *rc_name = "";
60
char *rc_name = "";
62
int rc_recursion = 0;
61
int rc_recursion = 0;
63
62
64
static char * CatExtra(register char *str1, register char *str2) {
63
static char *
65
  register char *cp;
64
CatExtra(register char *str1, register char *str2)
66
  register int len1, len2, add_colon;
65
{
67
66
	register char *cp;
68
  len1 = strlen(str1);
67
	register int len1, len2, add_colon;
69
  if (len1 == 0)
68
70
    return str2;
69
	len1 = strlen(str1);
71
  add_colon = (str1[len1 - 1] != ':');
70
	if (len1 == 0)
72
  if (str2) {
71
		return str2;
73
    len2 = strlen(str2);
72
	add_colon = (str1[len1 - 1] != ':');
74
    if ((cp = realloc(str2, (unsigned) len1 + len2 + add_colon + 1)) == NULL)
73
	if (str2) {
75
      Panic(0, "%s", strnomem);
74
		len2 = strlen(str2);
76
    bcopy(cp, cp + len1 + add_colon, len2 + 1);
75
		if ((cp = realloc(str2, (unsigned)len1 + len2 + add_colon + 1)) == NULL)
77
  }
76
			Panic(0, "%s", strnomem);
78
  else {
77
		bcopy(cp, cp + len1 + add_colon, len2 + 1);
79
    if ((cp = malloc((unsigned) len1 + add_colon + 1)) == NULL)
78
	} else {
80
      Panic(0, "%s", strnomem);
79
		if ((cp = malloc((unsigned)len1 + add_colon + 1)) == NULL)
81
    cp[len1 + add_colon] = '\0';
80
			Panic(0, "%s", strnomem);
82
  }
81
		cp[len1 + add_colon] = '\0';
83
  bcopy(str1, cp, len1);
82
	}
84
  if (add_colon)
83
	bcopy(str1, cp, len1);
85
    cp[len1] = ':';
84
	if (add_colon)
86
  return cp;
85
		cp[len1] = ':';
87
}
86
	return cp;
88
87
}
89
static char *findrcfile(char *rcfile) {
88
90
  char buf[256];
89
static char *
91
  char *p;
90
findrcfile(char *rcfile)
92
91
{
93
  /* Tilde prefix support courtesy <hesso@pool.math.tu-berlin.de>,
92
	char buf[256];
94
   * taken from a Debian patch. */
93
	char *p;
95
  if (rcfile && *rcfile == '~') {
94
96
    static char rcfilename_tilde_exp[MAXPATHLEN+1];
95
	/* Tilde prefix support courtesy <hesso@pool.math.tu-berlin.de>,
97
    char *slash_position = strchr(rcfile, '/');
96
	 * taken from a Debian patch. */
98
97
	if (rcfile && *rcfile == '~') {
99
    if (slash_position == rcfile+1) {
98
		static char rcfilename_tilde_exp[MAXPATHLEN + 1];
100
      char *home = getenv("HOME");
99
		char *slash_position = strchr(rcfile, '/');
101
      if (!home) {
100
102
        Msg(0, "%s: source: tilde expansion failed", rc_name);
101
		if (slash_position == rcfile + 1) {
103
        return NULL;
102
			char *home = getenv("HOME");
104
      }
103
			if (!home) {
105
      snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile+2);
104
				Msg(0, "%s: source: tilde expansion failed", rc_name);
106
    }
105
				return NULL;
107
    else if (slash_position) {
106
			}
108
      struct passwd *p;
107
			snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile + 2);
109
      *slash_position = 0;
108
		} else if (slash_position) {
110
      p = getpwnam(rcfile+1);
109
			struct passwd *p;
111
      if (!p){
110
			*slash_position = 0;
112
        Msg(0, "%s: source: tilde expansion failed for user %s", rc_name, rcfile+1);
111
			p = getpwnam(rcfile + 1);
113
        return NULL;
112
			if (!p) {
114
      }
113
				Msg(0, "%s: source: tilde expansion failed for user %s", rc_name, rcfile + 1);
115
      snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position+1);
114
				return NULL;
116
    }
115
			}
117
    else {
116
			snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position + 1);
118
      Msg(0, "%s: source: illegal tilde expression.", rc_name);
117
		} else {
119
      return NULL;
118
			Msg(0, "%s: source: illegal tilde expression.", rc_name);
120
    }
119
			return NULL;
121
    rcfile = rcfilename_tilde_exp;
120
		}
122
  }
121
		rcfile = rcfilename_tilde_exp;
123
122
	}
124
  if (rcfile) {
123
125
    char *rcend = rindex(rc_name, '/');
124
	if (rcfile) {
126
    if (*rcfile != '/' && rcend && (rcend - rc_name) + strlen(rcfile) + 2 < sizeof(buf)) {
125
		char *rcend = rindex(rc_name, '/');
127
      strncpy(buf, rc_name, rcend - rc_name + 1);
126
		if (*rcfile != '/' && rcend && (rcend - rc_name) + strlen(rcfile) + 2 < sizeof(buf)) {
128
      strcpy(buf + (rcend - rc_name) + 1, rcfile);
127
			strncpy(buf, rc_name, rcend - rc_name + 1);
129
      if (access(buf, R_OK) == 0)
128
			strcpy(buf + (rcend - rc_name) + 1, rcfile);
130
        return SaveStr(buf);
129
			if (access(buf, R_OK) == 0)
131
    }
130
				return SaveStr(buf);
132
    debug1("findrcfile: you specified '%s'\n", rcfile);
131
		}
133
    return SaveStr(rcfile);
132
		debug1("findrcfile: you specified '%s'\n", rcfile);
134
  }
133
		return SaveStr(rcfile);
135
134
	}
136
  debug("findrcfile: you specified nothing...\n");
135
137
  if ((p = getenv("SCREENRC")) != NULL && *p != '\0') {
136
	debug("findrcfile: you specified nothing...\n");
138
    debug1("  $SCREENRC has: '%s'\n", p);
137
	if ((p = getenv("SCREENRC")) != NULL && *p != '\0') {
139
    return SaveStr(p);
138
		debug1("  $SCREENRC has: '%s'\n", p);
140
  }
139
		return SaveStr(p);
141
  else {
140
	} else {
142
    debug("  ...nothing in $SCREENRC, defaulting $HOME/.screenrc\n");
141
		debug("  ...nothing in $SCREENRC, defaulting $HOME/.screenrc\n");
143
    if (strlen(home) > sizeof(buf) - 12)
142
		if (strlen(home) > sizeof(buf) - 12)
144
      Panic(0, "Rc: home too large");
143
			Panic(0, "Rc: home too large");
145
    sprintf(buf, "%s/.screenrc", home);
144
		sprintf(buf, "%s/.screenrc", home);
146
    return SaveStr(buf);
145
		return SaveStr(buf);
147
  }
146
	}
148
}
147
}
149
148
150
/*
149
/*
Lines 152-781 Link Here
152
 * 1) rcfilename = "/etc/screenrc"
151
 * 1) rcfilename = "/etc/screenrc"
153
 * 2) rcfilename = RcFileName
152
 * 2) rcfilename = RcFileName
154
 */
153
 */
155
int StartRc(char *rcfilename, int nopanic) {
154
int
156
  register int argc, len;
155
StartRc(char *rcfilename, int nopanic)
157
  register char *p, *cp;
156
{
158
  char buf[2048];
157
	register int argc, len;
159
  char *args[MAXARGS];
158
	register char *p, *cp;
160
  int argl[MAXARGS];
159
	char buf[2048];
161
  FILE *fp;
160
	char *args[MAXARGS];
162
  char *oldrc_name = rc_name;
161
	int argl[MAXARGS];
163
162
	FILE *fp;
164
  /* always fix termcap/info capabilities */
163
	char *oldrc_name = rc_name;
165
  extra_incap = CatExtra("TF", extra_incap);
164
166
165
	/* always fix termcap/info capabilities */
167
  /* Special settings for vt100 and others */
166
	extra_incap = CatExtra("TF", extra_incap);
168
  if (display && (!strncmp(D_termname, "vt", 2) || !strncmp(D_termname, "xterm", 5)))
167
169
    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);
168
	/* Special settings for vt100 and others */
170
169
	if (display && (!strncmp(D_termname, "vt", 2) || !strncmp(D_termname, "xterm", 5)))
171
  rc_name = findrcfile(rcfilename);
170
		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);
172
  if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) {
171
173
    const char *rc_nonnull = rc_name ? rc_name : rcfilename;
172
	rc_name = findrcfile(rcfilename);
174
    if (!rc_recursion && RcFileName && !strcmp(RcFileName, rc_nonnull)) {
173
	if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) {
175
      /*
174
		const char *rc_nonnull = rc_name ? rc_name : rcfilename;
176
       * User explicitly gave us that name,
175
		if (!rc_recursion && RcFileName && !strcmp(RcFileName, rc_nonnull)) {
177
       * this is the only case, where we get angry, if we can't read
176
		/*
178
       * the file.
177
		 * User explicitly gave us that name,
179
       */
178
		 * this is the only case, where we get angry, if we can't read
180
      debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename);
179
		 * the file.
181
      if (!nopanic) Panic(0, "Unable to open \"%s\".", rc_nonnull);
180
		 */
182
      /* possibly NOTREACHED */
181
			debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename);
183
    }
182
			if (!nopanic)
184
183
				Panic(0, "Unable to open \"%s\".", rc_nonnull);
185
    debug1("StartRc: '%s' no good. ignored\n", rc_nonnull);
184
				/* possibly NOTREACHED */
186
    if (rc_name)
185
		}
187
      Free(rc_name);
186
188
    rc_name = oldrc_name;
187
		debug1("StartRc: '%s' no good. ignored\n", rc_nonnull);
189
    return 1;
188
		if (rc_name)
190
  }
189
			Free(rc_name);
191
  while (fgets(buf, sizeof buf, fp) != NULL) {
190
		rc_name = oldrc_name;
192
    if ((p = rindex(buf, '\n')) != NULL)
191
		return 1;
193
      *p = '\0';
192
	}
194
193
	while (fgets(buf, sizeof buf, fp) != NULL) {
195
    if ((argc = Parse(buf, sizeof buf, args, argl)) == 0)
194
		if ((p = rindex(buf, '\n')) != NULL)
196
      continue;
195
			*p = '\0';
197
196
198
    if (strcmp(args[0], "echo") == 0) {
197
		if ((argc = Parse(buf, sizeof buf, args, argl)) == 0)
199
      if (!display)
198
			continue;
200
        continue;
199
201
      if (argc < 2 || (argc == 3 && strcmp(args[1], "-n")) || argc > 3) {
200
		if (strcmp(args[0], "echo") == 0) {
202
        Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name);
201
			if (!display)
203
        continue;
202
				continue;
204
      }
203
			if (argc < 2 || (argc == 3 && strcmp(args[1], "-n")) || argc > 3) {
205
      AddStr(args[argc - 1]);
204
				Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name);
206
      if (argc != 3) {
205
				continue;
207
        AddStr("\r\n");
206
			}
208
        Flush(0);
207
			AddStr(args[argc - 1]);
209
      }
208
			if (argc != 3) {
210
    }
209
				AddStr("\r\n");
211
210
				Flush(0);
212
    else if (strcmp(args[0], "sleep") == 0) {
211
			}
213
      if (!display)
212
		} else if (strcmp(args[0], "sleep") == 0) {
214
        continue;
213
			if (!display)
215
      debug("sleeeeeeep\n");
214
				continue;
216
      if (argc != 2) {
215
			debug("sleeeeeeep\n");
217
        Msg(0, "%s: sleep: one numeric argument expected.", rc_name);
216
			if (argc != 2) {
218
        continue;
217
				Msg(0, "%s: sleep: one numeric argument expected.", rc_name);
219
      }
218
				continue;
220
      DisplaySleep1000(1000 * atoi(args[1]), 1);
219
			}
221
    }
220
			DisplaySleep1000(1000 * atoi(args[1]), 1);
221
		}
222
#ifdef TERMINFO
222
#ifdef TERMINFO
223
    else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "terminfo")) {
223
    else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "terminfo")) {
224
#else
224
#else
225
    else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "termcap")) {
225
		else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "termcap")) {
226
#endif
226
#endif
227
      if (!display)
227
			if (!display)
228
        continue;
228
				continue;
229
      if (argc < 3 || argc > 4) {
229
			if (argc < 3 || argc > 4) {
230
        Msg(0, "%s: %s: incorrect number of arguments.", rc_name, args[0]);
230
				Msg(0, "%s: %s: incorrect number of arguments.", rc_name, args[0]);
231
        continue;
231
				continue;
232
      }
232
			}
233
233
234
      for (p = args[1]; p && *p; p = cp) {
234
			for (p = args[1]; p && *p; p = cp) {
235
        if ((cp = index(p, '|')) != 0)
235
				if ((cp = index(p, '|')) != 0)
236
          *cp++ = '\0';
236
					*cp++ = '\0';
237
        len = strlen(p);
237
				len = strlen(p);
238
        if (p[len - 1] == '*') {
238
				if (p[len - 1] == '*') {
239
          if (!(len - 1) || !strncmp(p, D_termname, len - 1))
239
					if (!(len - 1) || !strncmp(p, D_termname, len - 1))
240
            break;
240
						break;
241
        }
241
				} else if (!strcmp(p, D_termname))
242
        else if (!strcmp(p, D_termname))
242
					break;
243
          break;
243
			}
244
      }
244
			if (!(p && *p))
245
      if (!(p && *p))
245
				continue;
246
        continue;
246
			extra_incap = CatExtra(args[2], extra_incap);
247
      extra_incap = CatExtra(args[2], extra_incap);
247
			if (argc == 4)
248
      if (argc == 4)
248
				extra_outcap = CatExtra(args[3], extra_outcap);
249
        extra_outcap = CatExtra(args[3], extra_outcap);
249
		} else if (!strcmp(args[0], "source")) {
250
    }
250
			if (rc_recursion <= 10) {
251
    else if (!strcmp(args[0], "source")) {
251
				rc_recursion++;
252
      if (rc_recursion <= 10) {
252
				(void)StartRc(args[1], 0);
253
        rc_recursion++;
253
				rc_recursion--;
254
        (void)StartRc(args[1], 0);
254
			}
255
        rc_recursion--;
255
		}
256
      }
256
	}
257
    }
257
	fclose(fp);
258
  }
258
	Free(rc_name);
259
  fclose(fp);
259
	rc_name = oldrc_name;
260
  Free(rc_name);
260
	return 0;
261
  rc_name = oldrc_name;
261
}
262
  return 0;
262
263
}
263
void
264
264
FinishRc(char *rcfilename)
265
void FinishRc(char *rcfilename) {
265
{
266
  char buf[2048];
266
	char buf[2048];
267
  FILE *fp;
267
	FILE *fp;
268
  char *oldrc_name = rc_name;
268
	char *oldrc_name = rc_name;
269
269
270
  rc_name = findrcfile(rcfilename);
270
	rc_name = findrcfile(rcfilename);
271
271
272
  if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) {
272
	if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) {
273
    const char *rc_nonnull = rc_name ? rc_name : rcfilename;
273
		const char *rc_nonnull = rc_name ? rc_name : rcfilename;
274
    if (rc_recursion)
274
		if (rc_recursion)
275
      Msg(errno, "%s: source %s", oldrc_name, rc_nonnull);
275
			Msg(errno, "%s: source %s", oldrc_name, rc_nonnull);
276
    else if (RcFileName && !strcmp(RcFileName, rc_nonnull)) {
276
		else if (RcFileName && !strcmp(RcFileName, rc_nonnull)) {
277
      /*
277
      /*
278
       * User explicitly gave us that name,
278
       * User explicitly gave us that name,
279
       * this is the only case, where we get angry, if we can't read
279
       * this is the only case, where we get angry, if we can't read
280
       * the file.
280
       * the file.
281
       */
281
       */
282
       debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename);
282
			debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename);
283
       Panic(0, "Unable to open \"%s\".", rc_nonnull);
283
			Panic(0, "Unable to open \"%s\".", rc_nonnull);
284
       /* NOTREACHED */
284
			/* NOTREACHED */
285
    }
285
		}
286
    debug1("FinishRc: '%s' no good. ignored\n", rc_nonnull);
286
		debug1("FinishRc: '%s' no good. ignored\n", rc_nonnull);
287
    if (rc_name)
287
		if (rc_name)
288
      Free(rc_name);
288
			Free(rc_name);
289
    rc_name = oldrc_name;
289
		rc_name = oldrc_name;
290
    return;
290
		return;
291
  }
291
	}
292
292
293
  debug("finishrc is going...\n");
293
	debug("finishrc is going...\n");
294
  while (fgets(buf, sizeof buf, fp) != NULL)
294
	while (fgets(buf, sizeof buf, fp) != NULL)
295
    RcLine(buf, sizeof buf);
295
		RcLine(buf, sizeof buf);
296
  (void) fclose(fp);
296
	(void)fclose(fp);
297
  Free(rc_name);
297
	Free(rc_name);
298
  rc_name = oldrc_name;
298
	rc_name = oldrc_name;
299
}
299
}
300
300
301
void do_source(char *rcfilename) {
301
void
302
  if (rc_recursion > 10) {
302
do_source(char *rcfilename)
303
    Msg(0, "%s: source: recursion limit reached", rc_name);
303
{
304
    return;
304
	if (rc_recursion > 10) {
305
  }
305
		Msg(0, "%s: source: recursion limit reached", rc_name);
306
  rc_recursion++;
306
		return;
307
  FinishRc(rcfilename);
307
	}
308
  rc_recursion--;
308
	rc_recursion++;
309
	FinishRc(rcfilename);
310
	rc_recursion--;
309
}
311
}
310
312
311
312
/*
313
/*
313
 * Running a Command Line in the environment determined by the display.
314
 * Running a Command Line in the environment determined by the display.
314
 * The fore window is taken from the display as well as the user.
315
 * The fore window is taken from the display as well as the user.
315
 * This is bad when we run detached.
316
 * This is bad when we run detached.
316
 */
317
 */
317
void RcLine(char *ubuf, int ubufl) {
318
void
318
  char *args[MAXARGS];
319
RcLine(char *ubuf, int ubufl)
319
  int argl[MAXARGS];
320
{
321
	char *args[MAXARGS];
322
	int argl[MAXARGS];
320
#ifdef MULTIUSER
323
#ifdef MULTIUSER
321
  extern struct acluser *EffectiveAclUser;      /* acl.c */
324
	extern struct acluser *EffectiveAclUser;      /* acl.c */
322
  extern struct acluser *users;                 /* acl.c */
325
	extern struct acluser *users;                 /* acl.c */
323
#endif
326
#endif
324
327
325
  if (display) {
328
	if (display) {
326
    fore = D_fore;
329
		fore = D_fore;
327
    flayer = D_forecv->c_layer;
330
		flayer = D_forecv->c_layer;
328
  }
331
	} else
329
  else
332
		flayer = fore ? fore->w_savelayer : 0;
330
    flayer = fore ? fore->w_savelayer : 0;
333
	if (Parse(ubuf, ubufl, args, argl) <= 0)
331
  if (Parse(ubuf, ubufl, args, argl) <= 0)
334
		return;
332
    return;
333
335
334
#ifdef MULTIUSER
336
#ifdef MULTIUSER
335
  if (!display) {
337
	if (!display) {
336
      /* the session owner does it, when there is no display here */
338
      /* the session owner does it, when there is no display here */
337
      EffectiveAclUser = users;        
339
		EffectiveAclUser = users;
338
      debug("RcLine: WARNING, no display no user! Session owner executes command\n");
340
		debug("RcLine: WARNING, no display no user! Session owner executes command\n");
339
  }
341
	}
340
#endif
342
#endif
341
343
342
  DoCommand(args, argl);
344
	DoCommand(args, argl);
343
345
344
#ifdef MULTIUSER
346
#ifdef MULTIUSER
345
  EffectiveAclUser = 0;
347
	EffectiveAclUser = 0;
346
#endif
348
#endif
347
}
349
}
348
350
349
/*  needs display for copybuffer access and termcap dumping  */
351
/*  needs display for copybuffer access and termcap dumping  */
350
void WriteFile(struct acluser *user, char *fn, int dump) {
352
void
353
WriteFile(struct acluser *user, char *fn, int dump)
354
{
351
  /* dump==0:	create .termcap,
355
  /* dump==0:	create .termcap,
352
   * dump==1:	hardcopy,
356
   * dump==1:	hardcopy,
353
   * #ifdef COPY_PASTE
357
   * #ifdef COPY_PASTE
354
   * dump==2:	BUFFERFILE
358
   * dump==2:	BUFFERFILE
355
   * #endif COPY_PASTE 
359
   * #endif COPY_PASTE
356
   * dump==1:	scrollback,
360
   * dump==1:	scrollback,
357
   */
361
   */
358
  register int i, j, k;
362
	register int i, j, k;
359
  register char *p;
363
	register char *p;
360
  register FILE *f;
364
	register FILE *f;
361
  char fnbuf[1024];
365
	char fnbuf[1024];
362
  char *mode = "w";
366
	char *mode = "w";
363
367
364
#ifdef COPY_PASTE
368
#ifdef COPY_PASTE
365
  int public = 0;
369
	int public = 0;
366
# ifdef HAVE_LSTAT
370
# ifdef HAVE_LSTAT
367
  struct stat stb, stb2;
371
	struct stat stb, stb2;
368
  int fd, exists = 0;
372
	int fd, exists = 0;
369
# endif
373
# endif
370
#endif
374
#endif
371
375
372
  switch (dump) {
376
	switch (dump) {
373
    case DUMP_TERMCAP:
377
	case DUMP_TERMCAP:
374
      if (fn == 0) {
378
		if (fn == 0) {
375
        i = SockName - SockPath;
379
			i = SockName - SockPath;
376
        if (i > (int)sizeof(fnbuf) - 9)
380
			if (i > (int)sizeof(fnbuf) - 9)
377
          i = 0;
381
				i = 0;
378
        strncpy(fnbuf, SockPath, i);
382
			strncpy(fnbuf, SockPath, i);
379
        strcpy(fnbuf + i, ".termcap");
383
			strcpy(fnbuf + i, ".termcap");
380
        fn = fnbuf;
384
			fn = fnbuf;
381
      }
385
		}
382
      break;
386
		break;
383
387
384
    case DUMP_HARDCOPY:
388
	case DUMP_HARDCOPY:
385
    case DUMP_SCROLLBACK:
389
	case DUMP_SCROLLBACK:
386
      if (fn == 0) {
390
		if (fn == 0) {
387
        if (fore == 0)
391
			if (fore == 0)
388
          return;
392
				return;
389
        if (hardcopydir && *hardcopydir && strlen(hardcopydir) < sizeof(fnbuf) - 21)
393
			if (hardcopydir && *hardcopydir && strlen(hardcopydir) < sizeof(fnbuf) - 21)
390
          sprintf(fnbuf, "%s/hardcopy.%d", hardcopydir, fore->w_number);
394
				sprintf(fnbuf, "%s/hardcopy.%d", hardcopydir, fore->w_number);
391
        else
395
			else
392
          sprintf(fnbuf, "hardcopy.%d", fore->w_number);
396
				sprintf(fnbuf, "hardcopy.%d", fore->w_number);
393
        fn = fnbuf;
397
			fn = fnbuf;
394
      }
398
		}
395
      if (hardcopy_append && !access(fn, W_OK))
399
		if (hardcopy_append && !access(fn, W_OK))
396
        mode = "a";
400
			mode = "a";
397
      break;
401
		break;
398
402
399
#ifdef COPY_PASTE
403
#ifdef COPY_PASTE
400
    case DUMP_EXCHANGE:
404
	case DUMP_EXCHANGE:
401
      if (fn == 0) {
405
		if (fn == 0) {
402
        strncpy(fnbuf, BufferFile, sizeof(fnbuf) - 1);
406
			strncpy(fnbuf, BufferFile, sizeof(fnbuf) - 1);
403
        fnbuf[sizeof(fnbuf) - 1] = 0;
407
			fnbuf[sizeof(fnbuf) - 1] = 0;
404
        fn = fnbuf;
408
			fn = fnbuf;
405
      }
409
		}
406
      public = !strcmp(fn, bufferfile);
410
		public = !strcmp(fn, DEFAULT_BUFFERFILE);
407
# ifdef HAVE_LSTAT
411
# ifdef HAVE_LSTAT
408
      exists = !lstat(fn, &stb);
412
		exists = !lstat(fn, &stb);
409
      if (public && exists && (S_ISLNK(stb.st_mode) || stb.st_nlink > 1)) {
413
		if (public && exists && (S_ISLNK(stb.st_mode) || stb.st_nlink > 1)) {
410
        Msg(0, "No write to links, please.");
414
			Msg(0, "No write to links, please.");
411
        return;
415
			return;
412
      }
416
		}
413
# endif
417
# endif
414
      break;
418
		break;
415
#endif
419
#endif
416
  }
420
	}
417
421
418
  debug2("WriteFile(%d) %s\n", dump, fn);
422
	debug2("WriteFile(%d) %s\n", dump, fn);
419
  if (UserContext() > 0) {
423
	if (UserContext() > 0) {
420
    debug("Writefile: usercontext\n");
424
		debug("Writefile: usercontext\n");
421
#ifdef COPY_PASTE
425
#ifdef COPY_PASTE
422
    if (dump == DUMP_EXCHANGE && public) {
426
		if (dump == DUMP_EXCHANGE && public) {
423
# ifdef HAVE_LSTAT
427
# ifdef HAVE_LSTAT
424
      if (exists) {
428
			if (exists) {
425
        if ((fd = open(fn, O_WRONLY, 0666)) >= 0) {
429
				if ((fd = open(fn, O_WRONLY, 0666)) >= 0) {
426
          if (fstat(fd, &stb2) == 0 && stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino)
430
					if (fstat(fd, &stb2) == 0 && stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino)
427
            if (ftruncate(fd, 0) < 0) {
431
						ftruncate(fd, 0);
428
              close(fd);
432
					else {
429
              fd = -1;
433
						close(fd);
430
            }
434
						fd = -1;
431
          else {
435
					}
432
            close(fd);
436
				}
433
            fd = -1;
437
			} else
434
          }
438
				fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0666);
435
        }
439
			f = fd >= 0 ? fdopen(fd, mode) : 0;
436
      }
437
      else
438
        fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0666);
439
      f = fd >= 0 ? fdopen(fd, mode) : 0;
440
# else
440
# else
441
      f = fopen(fn, mode);
441
			f = fopen(fn, mode);
442
# endif
442
# endif
443
    }
443
		} else
444
    else
445
#endif /* COPY_PASTE */
444
#endif /* COPY_PASTE */
446
      f = fopen(fn, mode);
445
			f = fopen(fn, mode);
447
        if (f == NULL) {
446
		if (f == NULL) {
448
          debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode);
447
			debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode);
449
          UserReturn(0);
448
			UserReturn(0);
450
        }
449
		} else {
451
        else {
450
			switch (dump) {
452
          switch (dump) {
451
			case DUMP_HARDCOPY:
453
            case DUMP_HARDCOPY:
452
			case DUMP_SCROLLBACK:
454
            case DUMP_SCROLLBACK:
453
				if (!fore)
455
              if (!fore)
454
					break;
456
                break;
455
				if (*mode == 'a') {
457
              if (*mode == 'a') {
456
					putc('>', f);
458
                putc('>', f);
457
					for (j = fore->w_width - 2; j > 0; j--)
459
                for (j = fore->w_width - 2; j > 0; j--)
458
						putc('=', f);
460
                  putc('=', f);
459
					fputs("<\n", f);
461
                  fputs("<\n", f);
460
				}
462
              }
461
				if (dump == DUMP_SCROLLBACK) {
463
              if (dump == DUMP_SCROLLBACK) {
464
#ifdef COPY_PASTE
462
#ifdef COPY_PASTE
465
                for (i = fore->w_histheight - fore->w_scrollback_height; i < fore->w_histheight; i++) {
463
					for (i = fore->w_histheight - fore->w_scrollback_height; i < fore->w_histheight; i++) {
466
                  p = (char *)(WIN(i)->image);
464
						p = (char *)(WIN(i)->image);
467
                    for (k = fore->w_width - 1; k >= 0 && p[k] == ' '; k--)
465
						for (k = fore->w_width - 1;
468
                      ;
466
						    k >= 0 && p[k] == ' '; k--)
469
                    for (j = 0; j <= k; j++)
467
							;
470
                      putc(p[j], f);
468
						for (j = 0; j <= k; j++)
471
                      putc('\n', f);
469
							putc(p[j], f);
472
                }
470
						putc('\n', f);
473
#endif
471
					}
474
              }
472
#endif
475
              for (i = 0; i < fore->w_height; i++) {
473
				}
476
                p = (char *)fore->w_mlines[i].image;
474
				for (i = 0; i < fore->w_height; i++) {
477
                for (k = fore->w_width - 1; k >= 0 && p[k] == ' '; k--)
475
					p = (char *)fore->w_mlines[i].image;
478
                  ;
476
					for (k = fore->w_width - 1;
479
                for (j = 0; j <= k; j++)
477
					    k >= 0 && p[k] == ' '; k--)
480
                  putc(p[j], f);
478
						;
481
                  putc('\n', f);
479
					for (j = 0; j <= k; j++)
482
                }
480
						putc(p[j], f);
483
                break;
481
					putc('\n', f);
484
482
				}
485
            case DUMP_TERMCAP:
483
				break;
486
              DumpTermcap(fore->w_aflag, f);
484
487
	      break;
485
			case DUMP_TERMCAP:
486
				DumpTermcap(fore->w_aflag, f);
487
				break;
488
488
489
#ifdef COPY_PASTE
489
#ifdef COPY_PASTE
490
            case DUMP_EXCHANGE:
490
			case DUMP_EXCHANGE:
491
              p = user->u_plop.buf;
491
				p = user->u_plop.buf;
492
              for (i = user->u_plop.len; i-- > 0; p++)
492
				for (i = user->u_plop.len; i-- > 0; p++)
493
                if (*p == '\r' && (i == 0 || p[1] != '\n'))
493
					if (*p == '\r' && (i == 0 || p[1] != '\n'))
494
                  putc('\n', f);
494
						putc('\n', f);
495
                else
495
					else
496
                  putc(*p, f);
496
						putc(*p, f);
497
              break;
497
				break;
498
#endif
498
#endif
499
        }
499
			}
500
        (void) fclose(f);
500
			(void)fclose(f);
501
        UserReturn(1);
501
			UserReturn(1);
502
      }
502
		}
503
    }
503
	}
504
  if (UserStatus() <= 0)
504
	if (UserStatus() <= 0)
505
    Msg(0, "Cannot open \"%s\"", fn);
505
		Msg(0, "Cannot open \"%s\"", fn);
506
  else if (display && !*rc_name) {
506
	else if (display && !*rc_name) {
507
    switch (dump) {
507
		switch (dump) {
508
      case DUMP_TERMCAP:
508
		case DUMP_TERMCAP:
509
        Msg(0, "Termcap entry written to \"%s\".", fn);
509
			Msg(0, "Termcap entry written to \"%s\".", fn);
510
        break;
510
			break;
511
      case DUMP_HARDCOPY:
511
		case DUMP_HARDCOPY:
512
      case DUMP_SCROLLBACK:
512
		case DUMP_SCROLLBACK:
513
        Msg(0, "Screen image %s to \"%s\".", (*mode == 'a') ? "appended" : "written", fn);
513
			Msg(0, "Screen image %s to \"%s\".", (*mode == 'a') ? "appended" : "written", fn);
514
        break;
514
			break;
515
#ifdef COPY_PASTE
515
#ifdef COPY_PASTE
516
      case DUMP_EXCHANGE:
516
		case DUMP_EXCHANGE:
517
        Msg(0, "Copybuffer written to \"%s\".", fn);
517
			Msg(0, "Copybuffer written to \"%s\".", fn);
518
#endif
518
#endif
519
    }
519
		}
520
  }
520
	}
521
}
521
}
522
522
523
#ifdef COPY_PASTE
523
#ifdef COPY_PASTE
524
524
525
/*
525
/*
526
 * returns an allocated buffer which holds a copy of the file named fn.
526
 * returns an allocated buffer which holds a copy of the file named fn.
527
 * lenp (if nonzero) points to a location, where the buffer size should be 
527
 * lenp (if nonzero) points to a location, where the buffer size should be
528
 * stored.
528
 * stored.
529
 */
529
 */
530
char *ReadFile(char *fn, int *lenp) {
530
char *
531
  int i, l, size;
531
ReadFile(char *fn, int *lenp)
532
  char c, *bp, *buf;
532
{
533
  struct stat stb;
533
	int i, l, size;
534
534
	char c, *bp, *buf;
535
  ASSERT(lenp);
535
	struct stat stb;
536
  debug1("ReadFile(%s)\n", fn);
536
537
537
	ASSERT(lenp);
538
  if ((i = secopen(fn, O_RDONLY, 0)) < 0) {
538
	debug1("ReadFile(%s)\n", fn);
539
    Msg(errno, "no %s -- no slurp", fn);
539
540
    return NULL;
540
	if ((i = secopen(fn, O_RDONLY, 0)) < 0) {
541
  }
541
		Msg(errno, "no %s -- no slurp", fn);
542
542
		return NULL;
543
  if (fstat(i, &stb)) {
543
	}
544
    Msg(errno, "no good %s -- no slurp", fn);
544
545
    close(i);
545
	if (fstat(i, &stb)) {
546
    return NULL;
546
		Msg(errno, "no good %s -- no slurp", fn);
547
  }
547
		close(i);
548
  size = stb.st_size;
548
		return NULL;
549
549
	}
550
  if ((buf = malloc(size)) == NULL) {
550
	size = stb.st_size;
551
    close(i);
551
552
    Msg(0, "%s", strnomem);
552
	if ((buf = malloc(size)) == NULL) {
553
    return NULL;
553
		close(i);
554
  }
554
		Msg(0, "%s", strnomem);
555
  errno = 0;
555
		return NULL;
556
556
	}
557
  if ((l = read(i, buf, size)) != size) {
557
	errno = 0;
558
    if (l < 0)
558
559
      l = 0;
559
	if ((l = read(i, buf, size)) != size) {
560
    Msg(errno, "Got only %d bytes from %s", l, fn);
560
		if (l < 0)
561
  }
561
			l = 0;
562
  else {
562
		Msg(errno, "Got only %d bytes from %s", l, fn);
563
    if (read(i, &c, 1) > 0)
563
	} else {
564
      Msg(0, "Slurped only %d characters (of %d) into buffer - try again", l, size);
564
		if (read(i, &c, 1) > 0)
565
    else
565
			Msg(0, "Slurped only %d characters (of %d) into buffer - try again", l, size);
566
      Msg(0, "Slurped %d characters into buffer", l);
566
		else
567
  }
567
			Msg(0, "Slurped %d characters into buffer", l);
568
  close(i);
568
	}
569
  *lenp = l;
569
	close(i);
570
  for (bp = buf; l-- > 0; bp++)
570
	*lenp = l;
571
    if (*bp == '\n' && (bp == buf || bp[-1] != '\r'))
571
	for (bp = buf; l-- > 0; bp++)
572
      *bp = '\r';
572
		if (*bp == '\n' && (bp == buf || bp[-1] != '\r'))
573
  return buf;
573
			*bp = '\r';
574
}
574
	return buf;
575
575
}
576
void KillBuffers() {
576
577
  if (UserContext() > 0)
577
void
578
    UserReturn(unlink(BufferFile) ? errno : 0);
578
KillBuffers()
579
  errno = UserStatus();
579
{
580
  Msg(errno, "%s %sremoved", BufferFile, errno ? "not " : "");
580
	if (UserContext() > 0)
581
		UserReturn(unlink(BufferFile) ? errno : 0);
582
	errno = UserStatus();
583
	Msg(errno, "%s %sremoved", BufferFile, errno ? "not " : "");
581
}
584
}
582
#endif	/* COPY_PASTE */
585
#endif	/* COPY_PASTE */
583
586
584
587
585
/* (Almost) secure open and fopen...  */
588
/* (Almost) secure open and fopen...  */
586
589
587
FILE *secfopen(char *name, char *mode) {
590
FILE *
588
  FILE *fi;
591
secfopen(char *name, char *mode)
592
{
593
	FILE *fi;
589
#ifndef USE_SETEUID
594
#ifndef USE_SETEUID
590
  int flags, fd;
595
	int flags, fd;
591
#endif
596
#endif
592
597
593
  debug2("secfopen(%s, %s)\n", name, mode);
598
	debug2("secfopen(%s, %s)\n", name, mode);
594
#ifdef USE_SETEUID
599
#ifdef USE_SETEUID
595
  xseteuid(real_uid);
600
	xseteuid(real_uid);
596
  xsetegid(real_gid);
601
	xsetegid(real_gid);
597
  fi = fopen(name, mode);
602
	fi = fopen(name, mode);
598
  xseteuid(eff_uid);
603
	xseteuid(eff_uid);
599
  xsetegid(eff_gid);
604
	xsetegid(eff_gid);
600
  return fi;
605
	return fi;
601
602
#else
606
#else
603
  if (eff_uid == real_uid)
607
	if (eff_uid == real_uid)
604
    return fopen(name, mode);
608
		return fopen(name, mode);
605
  if (mode[0] && mode[1] == '+')
609
	if (mode[0] && mode[1] == '+')
606
    flags = O_RDWR;
610
		flags = O_RDWR;
607
  else
611
	else
608
    flags = (mode[0] == 'r') ? O_RDONLY : O_WRONLY;
612
		flags = (mode[0] == 'r') ? O_RDONLY : O_WRONLY;
609
  if (mode[0] == 'w')
613
	if (mode[0] == 'w')
610
    flags |= O_CREAT | O_TRUNC;
614
		flags |= O_CREAT | O_TRUNC;
611
  else if (mode[0] == 'a')
615
	else if (mode[0] == 'a')
612
    flags |= O_CREAT | O_APPEND;
616
		flags |= O_CREAT | O_APPEND;
613
  else if (mode[0] != 'r') {
617
	else if (mode[0] != 'r') {
614
    errno = EINVAL;
618
		errno = EINVAL;
615
    return 0;
619
		return 0;
616
  }
620
	}
617
  if ((fd = secopen(name, flags, 0666)) < 0)
621
	if ((fd = secopen(name, flags, 0666)) < 0)
618
    return 0;
622
		return 0;
619
  if ((fi = fdopen(fd, mode)) == 0) {
623
	if ((fi = fdopen(fd, mode)) == 0) {
620
    close(fd);
624
		close(fd);
621
    return 0;
625
		return 0;
622
  }
626
	}
623
  return fi;
627
	return fi;
624
#endif
628
#endif
625
}
629
}
626
630
627
631
int
628
int secopen(char *name, int flags, int mode) {
632
secopen(char *name, int flags, int mode)
629
  int fd;
633
{
634
	int fd;
630
#ifndef USE_SETEUID
635
#ifndef USE_SETEUID
631
  int q;
636
	int q;
632
  struct stat stb;
637
	struct stat stb;
633
#endif
638
#endif
634
639
635
  debug3("secopen(%s, 0x%x, 0%03o)\n", name, flags, mode);
640
	debug3("secopen(%s, 0x%x, 0%03o)\n", name, flags, mode);
636
#ifdef USE_SETEUID
641
#ifdef USE_SETEUID
637
  xseteuid(real_uid);
642
	xseteuid(real_uid);
638
  xsetegid(real_gid);
643
	xsetegid(real_gid);
639
  fd = open(name, flags, mode);
644
	fd = open(name, flags, mode);
640
  xseteuid(eff_uid);
645
	xseteuid(eff_uid);
641
  xsetegid(eff_gid);
646
	xsetegid(eff_gid);
642
  return fd;
647
	return fd;
643
#else
648
#else
644
  if (eff_uid == real_uid)
649
	if (eff_uid == real_uid)
645
    return open(name, flags, mode);
650
		return open(name, flags, mode);
646
  /* Truncation/creation is done in UserContext */
651
647
  if ((flags & O_TRUNC) || ((flags & O_CREAT) && access(name, F_OK))) {
652
	/* Truncation/creation is done in UserContext */
648
    if (UserContext() > 0) {
653
	if ((flags & O_TRUNC) || ((flags & O_CREAT) && access(name, F_OK))) {
649
      if ((fd = open(name, flags, mode)) >= 0) {
654
		if (UserContext() > 0) {
650
        close(fd);
655
			if ((fd = open(name, flags, mode)) >= 0) {
651
        UserReturn(0);
656
				close(fd);
652
      }
657
				UserReturn(0);
653
      if (errno == 0)
658
			}
654
        errno = EACCES;
659
			if (errno == 0)
655
      UserReturn(errno);
660
				errno = EACCES;
656
    }
661
			UserReturn(errno);
657
    if ((q = UserStatus())) {
662
		}
658
      if (q > 0)
663
		if ((q = UserStatus())) {
659
        errno = q;
664
			if (q > 0)
660
      return -1;
665
				errno = q;
661
    }
666
			return -1;
662
  }
667
		}
663
  if (access(name, F_OK))
668
	}
664
    return -1;
669
	if (access(name, F_OK))
665
  if ((fd = open(name, flags & ~(O_TRUNC | O_CREAT), 0)) < 0)
670
		return -1;
666
    return -1;
671
	if ((fd = open(name, flags & ~(O_TRUNC | O_CREAT), 0)) < 0)
667
  debug("open successful\n");
672
		return -1;
668
  if (fstat(fd, &stb)) {
673
	debug("open successful\n");
669
    close(fd);
674
	if (fstat(fd, &stb)) {
670
    return -1;
675
		close(fd);
671
  }
676
		return -1;
672
  debug("fstat successful\n");
677
	}
673
  if (stb.st_uid != real_uid) {
678
	debug("fstat successful\n");
674
    switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) {
679
	if (stb.st_uid != real_uid) {
675
      case O_RDONLY:
680
		switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) {
676
        q = 0004;
681
		case O_RDONLY:
677
        break;
682
			q = 0004;
678
      case O_WRONLY:
683
			break;
679
        q = 0002;
684
		case O_WRONLY:
680
        break;
685
			q = 0002;
681
      default:
686
			break;
682
        q = 0006;
687
		default:
683
        break;
688
			q = 0006;
684
    }
689
			break;
685
    if ((stb.st_mode & q) != q) {
690
		}
686
      debug1("secopen: permission denied (%03o)\n", stb.st_mode & 07777);
691
		if ((stb.st_mode & q) != q) {
687
      close(fd);
692
			debug1("secopen: permission denied (%03o)\n", stb.st_mode & 07777);
688
      errno = EACCES;
693
			close(fd);
689
      return -1;
694
			errno = EACCES;
690
    }
695
			return -1;
691
  }
696
		}
692
  debug1("secopen ok - returning %d\n", fd);
697
	}
693
  return fd;
698
	debug1("secopen ok - returning %d\n", fd);
694
#endif
699
	return fd;
695
}
700
#endif
696
701
}
697
702
698
int printpipe(struct win *p, char *cmd) {
703
int
699
  int pi[2];
704
printpipe(struct win *p, char *cmd)
700
  if (pipe(pi)) {
705
{
701
    WMsg(p, errno, "printing pipe");
706
	int pi[2];
702
    return -1;
707
	if (pipe(pi)) {
703
  }
708
		WMsg(p, errno, "printing pipe");
704
  fflush(NULL);
709
		return -1;
705
  switch (fork()) {
710
	}
706
    case -1:
711
	switch (fork()) {
707
      WMsg(p, errno, "printing fork");
712
	case -1:
708
      return -1;
713
		WMsg(p, errno, "printing fork");
709
    case 0:
714
		return -1;
710
      display = p->w_pdisplay;
715
	case 0:
711
      displays = 0;
716
		display = p->w_pdisplay;
712
      ServerSocket = -1;
717
		displays = 0;
718
		ServerSocket = -1;
713
#ifdef DEBUG
719
#ifdef DEBUG
714
      if (dfp && dfp != stderr)
720
		if (dfp && dfp != stderr)
715
        fclose(dfp);
721
			fclose(dfp);
716
#endif
722
#endif
717
      if (dup2(pi[0], 0) < 0)
723
		close(0);
718
        Panic(errno, "printpipe dup2");
724
		dup(pi[0]);
719
      closeallfiles(0);
725
		closeallfiles(0);
720
      if (setgid(real_gid) || setuid(real_uid))
726
		if (setgid(real_gid) || setuid(real_uid))
721
        Panic(errno, "printpipe setuid");
727
			Panic(errno, "printpipe setuid");
722
      eff_uid = real_uid;
728
		eff_uid = real_uid;
723
      eff_gid = real_gid;
729
		eff_gid = real_gid;
724
730
725
#ifdef SIGPIPE
731
#ifdef SIGPIPE
726
      signal(SIGPIPE, SIG_DFL);
732
		signal(SIGPIPE, SIG_DFL);
727
#endif
733
#endif
728
      execl("/bin/sh", "sh", "-c", cmd, NULL);
734
		execl("/bin/sh", "sh", "-c", cmd, (char *)0);
729
      Panic(errno, "/bin/sh");
735
		Panic(errno, "/bin/sh");
730
    default:
736
	default:
731
      break;
737
		break;
732
  }
738
	}
733
  close(pi[0]);
739
	close(pi[0]);
734
  return pi[1];
740
	return pi[1];
735
}
741
}
736
742
737
int readpipe(char **cmdv) {
743
int
738
  int pi[2];
744
readpipe(char **cmdv)
739
745
{
740
  if (pipe(pi)) {
746
	int pi[2];
741
    Msg(errno, "pipe");
747
742
    return -1;
748
	if (pipe(pi)) {
743
  }
749
		Msg(errno, "pipe");
744
750
		return -1;
745
  fflush(NULL);
751
	}
746
  switch (fork()) {
752
747
  case -1:
753
	switch (fork()) {
748
    Msg(errno, "fork");
754
	case -1:
749
    return -1;
755
		Msg(errno, "fork");
750
  case 0:
756
		return -1;
751
    displays = 0;
757
	case 0:
752
    ServerSocket = -1;
758
		displays = 0;
759
		ServerSocket = -1;
753
#ifdef DEBUG
760
#ifdef DEBUG
754
    if (dfp && dfp != stderr)
761
		if (dfp && dfp != stderr)
755
      fclose(dfp);
762
			fclose(dfp);
756
#endif
763
#endif
757
    close(1);
764
		close(1);
758
    if (dup(pi[1]) != 1) {
765
		if (dup(pi[1]) != 1) {
759
      close(pi[1]);
766
			close(pi[1]);
760
      Panic(0, "dup");
767
			Panic(0, "dup");
761
    }
768
		}
762
    closeallfiles(1);
769
		closeallfiles(1);
763
770
764
    if (setgid(real_gid) || setuid(real_uid)) {
771
		if (setgid(real_gid) || setuid(real_uid)) {
765
      close(1);
772
			close(1);
766
      Panic(errno, "setuid/setgid");
773
			Panic(errno, "setuid/setgid");
767
    }
774
		}
768
    eff_uid = real_uid;
775
		eff_uid = real_uid;
769
    eff_gid = real_gid;
776
		eff_gid = real_gid;
770
#ifdef SIGPIPE
777
#ifdef SIGPIPE
771
    signal(SIGPIPE, SIG_DFL);
778
		signal(SIGPIPE, SIG_DFL);
772
#endif
779
#endif
773
    execvp(*cmdv, cmdv);
780
		execvp(*cmdv, cmdv);
774
    close(1);
781
		close(1);
775
    Panic(errno, "%s", *cmdv);
782
		Panic(errno, "%s", *cmdv);
776
  default:
783
	default:
777
    break;
784
		break;
778
  }
785
	}
779
  close(pi[1]);
786
	close(pi[1]);
780
  return pi[0];
787
	return pi[0];
781
}
788
}
(-)screen.orig/HACKING (-1 / +1 lines)
Lines 4-10 Link Here
4
  The local variable nr is set to an integer value representing the
4
  The local variable nr is set to an integer value representing the
5
  command to be evaluated; for every command `foo', there is an
5
  command to be evaluated; for every command `foo', there is an
6
  integer value RC_FOO for use as nr's value to represent it. Find
6
  integer value RC_FOO for use as nr's value to represent it. Find
7
  the matching case label to follow procesing of the command.
7
  the matching case label to follow processing of the command.
8
   
8
   
9
  The RC_FOO values are defined in comm.h, which is automatically
9
  The RC_FOO values are defined in comm.h, which is automatically
10
  generated by comm.sh, based on the names of the commands
10
  generated by comm.sh, based on the names of the commands
(-)screen.orig/help.c (-1 / +2 lines)
Lines 111-118 Link Here
111
    printf("\nError: ");
111
    printf("\nError: ");
112
    printf(message, arg);
112
    printf(message, arg);
113
    printf("\n");
113
    printf("\n");
114
    exit(1);
114
  }
115
  }
115
  exit(1);
116
  exit(0);
116
}
117
}
117
118
118
/* Here come the help page routines */
119
/* Here come the help page routines */
(-)screen.orig/INSTALL (-3 / +3 lines)
Lines 40-46 Link Here
40
not. At least it must be on a filesystem that supports sockets/fifos.
40
not. At least it must be on a filesystem that supports sockets/fifos.
41
SOCKDIR must not point into an AFS (Andrew File System) mounted directory. 
41
SOCKDIR must not point into an AFS (Andrew File System) mounted directory. 
42
If you are uncertain about your NFS implementation, use a UFS directory for 
42
If you are uncertain about your NFS implementation, use a UFS directory for 
43
SOCKDIR. Personally, I favour a users home directory and recommend the the 
43
SOCKDIR. Personally, I favour a user's home directory and recommend the the
44
/tmp/ area. 
44
/tmp/ area. 
45
The path for ETCSCREENRC may also need to be adapted.
45
The path for ETCSCREENRC may also need to be adapted.
46
46
Lines 58-64 Link Here
58
--------------------
58
--------------------
59
You may well run screen from your private binary directory and with a 
59
You may well run screen from your private binary directory and with a 
60
private socket directory like $HOME/.screen. But to have a full featured
60
private socket directory like $HOME/.screen. But to have a full featured
61
screen and (from a users point of view) more secure pty's you should
61
screen and (from a user's point of view) more secure pty's you should
62
consult a system administrator and discuss installing screen setuid-root
62
consult a system administrator and discuss installing screen setuid-root
63
in some globally accessible directory like /usr/local/bin.
63
in some globally accessible directory like /usr/local/bin.
64
64
Lines 94-100 Link Here
94
The files screenrc and etc/etcscreenrc are instructive samples that
94
The files screenrc and etc/etcscreenrc are instructive samples that
95
demonstrate what can/should be done from your private .screenrc and from
95
demonstrate what can/should be done from your private .screenrc and from
96
$ETCSCREENRC -- do not just copy them. Read them.  Look through the 
96
$ETCSCREENRC -- do not just copy them. Read them.  Look through the 
97
etcscreenrc file for system wide defaults that you like to set. e.g. 
97
etcscreenrc file for system wide defaults that you like to set, e.g.
98
autodetach off, startup_message off, vbell on, ...
98
autodetach off, startup_message off, vbell on, ...
99
Since version 3.2.15 the screenrc file syntax changed slightly. All rc files
99
Since version 3.2.15 the screenrc file syntax changed slightly. All rc files
100
from previous versions should be run through the 'newsyntax' script that comes 
100
from previous versions should be run through the 'newsyntax' script that comes 
(-)screen.orig/.iscreenrc (-10 / +10 lines)
Lines 17-23 Link Here
17
echo -n "booting screen"
17
echo -n "booting screen"
18
18
19
# let it flash, not horn!
19
# let it flash, not horn!
20
#vbell on                          # "vbell" don't work any longer, sorry.
20
#vbell on                          # "vbell" doesn't work any longer, sorry.
21
#vbell_msg "  Wuff,  Wuff!!  "     # this is the default message
21
#vbell_msg "  Wuff,  Wuff!!  "     # this is the default message
22
#bell "Bimmmel No. %"		   # sounds the bell and shows a message
22
#bell "Bimmmel No. %"		   # sounds the bell and shows a message
23
23
Lines 45-55 Link Here
45
# Printing in the leftmost column is not save. We express that fact as :LP@:
45
# Printing in the leftmost column is not save. We express that fact as :LP@:
46
#
46
#
47
# Emacs tends to smear it's highlighted status bar across the screen, producing
47
# Emacs tends to smear it's highlighted status bar across the screen, producing
48
# ugly areas of bright background, if termcap is'nt perfectly sober.
48
# ugly areas of bright background, if termcap isn't perfectly sober.
49
# Give a little :ms@: in the termcap, this may help.
49
# Give a little :ms@: in the termcap, this may help.
50
#
50
#
51
# And who invented the initialisation for facit terminals? We tell him that 
51
# And who invented the initialisation for facit terminals? We tell him that 
52
# we non't like smooth scroll, by specifying :ti=\E[?l:.
52
# we don't like smooth scroll, by specifying :ti=\E[?l:.
53
# \E[?3l   80 Zeichen
53
# \E[?3l   80 Zeichen
54
# \E[?3h   132 Zeichen
54
# \E[?3h   132 Zeichen
55
# LP       Last column Printable
55
# LP       Last column Printable
Lines 92-102 Link Here
92
# ICL 6402 testing:
92
# ICL 6402 testing:
93
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
93
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
94
94
95
# Flowcontrol produces trouble. ^S und ^Q will never reach screen, as our
95
# Flow control produces trouble. ^S und ^Q will never reach screen, as our
96
# terminals catch them locally. Who can explain that to me?:
96
# terminals catch them locally. Who can explain that to me?:
97
#flow on|off|auto [interrupt]
97
#flow on|off|auto [interrupt]
98
98
99
# Long Lines get wrapped around (the back of your terminal). This is the 
99
# Long lines get wrapped around (the back of your terminal). This is the
100
# default for vt100. But now programs make different asumptions about your
100
# default for vt100. But now programs make different asumptions about your
101
# terminal. You may find two linefeeds where you'd expect one, or you may
101
# terminal. You may find two linefeeds where you'd expect one, or you may
102
# be confronted with a truncated line. Currently there is no fix, but pressing
102
# be confronted with a truncated line. Currently there is no fix, but pressing
Lines 106-115 Link Here
106
# the autoaka allows you to see the currently executing shell command in the
106
# the autoaka allows you to see the currently executing shell command in the
107
# window name field. To use that, your shell prompt must contain ^[k^[\ or
107
# window name field. To use that, your shell prompt must contain ^[k^[\ or
108
# you will see the string "(init)" as a name.
108
# you will see the string "(init)" as a name.
109
# in my .cshrc I may use this for a wonderfull tcsh-prompt:
109
# in my .cshrc I may use this for a wonderful tcsh-prompt:
110
#	set prompt="%{^[k^[\\%}%h %c2(%m)%# "
110
#	set prompt="%{^[k^[\\%}%h %c2(%m)%# "
111
#
111
#
112
# defining a shellaka that contains a pipe-symbol (|) activites the
112
# defining a shellaka that contains a pipe-symbol (|) activates the
113
# autoaka feature. To the left of that | you specify a constant part of
113
# autoaka feature. To the left of that | you specify a constant part of
114
# your prompt as a trigger, to the right you may place a default string
114
# your prompt as a trigger, to the right you may place a default string
115
# as in
115
# as in
Lines 121-128 Link Here
121
# ... now a little bit of key bindings
121
# ... now a little bit of key bindings
122
# In case we don't have write permission for /etc/utmp (no s-bit)
122
# In case we don't have write permission for /etc/utmp (no s-bit)
123
# we create even local windows via rlogin. -> Et voila: a utmp-slot
123
# we create even local windows via rlogin. -> Et voila: a utmp-slot
124
# utmp-slots are strongly recomended to keep sccs and talk happy.
124
# utmp-slots are strongly recommended to keep sccs and talk happy.
125
# (thus we have ^A# or. ^Ac for windowcreation with or without utmp-slot.)
125
# (thus we have ^A# or. ^Ac for window creation with or without utmp-slot.)
126
# but if we run suid-root, we produce all the rlogins with -ln, 
126
# but if we run suid-root, we produce all the rlogins with -ln, 
127
# as nobody shall refer to these pty's.
127
# as nobody shall refer to these pty's.
128
bind '!' screen -ln -k faui41 rlogin faui41
128
bind '!' screen -ln -k faui41 rlogin faui41
Lines 151-157 Link Here
151
# What happens, when you 'think emacs' and want to erase a whole
151
# What happens, when you 'think emacs' and want to erase a whole
152
# line? You type ^A^K right? Under screen it should be ^Aa^K. But...
152
# line? You type ^A^K right? Under screen it should be ^Aa^K. But...
153
# killing the window would be a real punishment for a little mistyping.
153
# killing the window would be a real punishment for a little mistyping.
154
bind k		#wow! I even amange to type ^Ak by accident.
154
bind k		#wow! I even mange to type ^Ak by accident.
155
#bind ^k
155
#bind ^k
156
#bind K kill
156
#bind K kill
157
157
(-)screen.orig/layer.c (-14 / +10 lines)
Lines 876-901 Link Here
876
{
876
{
877
  VA_LIST(ap)
877
  VA_LIST(ap)
878
  char buf[MAXPATHLEN*2];
878
  char buf[MAXPATHLEN*2];
879
  ssize_t len;
879
  char *p = buf;
880
  const int errlen = err ? 100 : 0;
881
  struct canvas *cv;
880
  struct canvas *cv;
882
881
883
  VA_START(ap, fmt);
882
  VA_START(ap, fmt);
884
  fmt = DoNLS(fmt);
883
  fmt = DoNLS(fmt);
885
  len = vsnprintf(buf, sizeof(buf) - errlen, fmt, VA_ARGS(ap));
884
  (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap));
886
  VA_END(ap);
885
  VA_END(ap);
887
886
888
  if (len < 0) {
889
    strncpy(buf, fmt, sizeof(buf) - errlen);
890
    buf[sizeof(buf) - errlen - 1] = 0;
891
  }
892
  if (err) {
887
  if (err) {
893
    const char *strerr = strerror(err);
888
    p += strlen(p);
894
    if (strerr) {
889
    *p++ = ':';
895
      strncat(buf, ": ", 2);
890
    *p++ = ' ';
896
      strncat(buf, strerr, errlen - 3);
891
    strncpy(p, strerror(err), buf + sizeof(buf) - p - 1);
897
    }
892
    buf[sizeof(buf) - 1] = 0;
898
  }
893
  }
894
899
  debug2("LMsg('%s') (%#x);\n", buf, (unsigned int)flayer);
895
  debug2("LMsg('%s') (%#x);\n", buf, (unsigned int)flayer);
900
  for (display = displays; display; display = display->d_next) {
896
  for (display = displays; display; display = display->d_next) {
901
    for (cv = D_cvlist; cv; cv = cv->c_next)
897
    for (cv = D_cvlist; cv; cv = cv->c_next)
Lines 943-949 Link Here
943
  for (l = lay; l; l = l->l_next) {
939
  for (l = lay; l; l = l->l_next) {
944
    if (l->l_layfn == &WinLf || l->l_layfn == &BlankLf)
940
    if (l->l_layfn == &WinLf || l->l_layfn == &BlankLf)
945
      break;
941
      break;
946
    debug1("- killing %p\n", l);
942
    debug1("- killing %#x\n", l);
947
    if (oldflayer == l)
943
    if (oldflayer == l)
948
      oldflayer = 0;
944
      oldflayer = 0;
949
    for (cv = l->l_cvlist; cv; cv = ncv) {
945
    for (cv = l->l_cvlist; cv; cv = ncv) {
Lines 977-983 Link Here
977
    Msg(0, "No memory for layer struct");
973
    Msg(0, "No memory for layer struct");
978
      return -1;
974
      return -1;
979
  }
975
  }
980
  debug2("Entering new layer on top of %p: %p\n", (unsigned int)flayer, newlay);
976
  debug2("Entering new layer on top of %#x: %#x\n", (unsigned int)flayer, newlay);
981
  data = 0;
977
  data = 0;
982
  if (datasize) {
978
  if (datasize) {
983
    if ((data = calloc(1, datasize)) == 0) {
979
    if ((data = calloc(1, datasize)) == 0) {
(-)screen.orig/layer.h (-1 / +1 lines)
Lines 106-112 Link Here
106
	  debug("LayCallUp\n");				\
106
	  debug("LayCallUp\n");				\
107
	  flayer = flayer->l_next;			\
107
	  flayer = flayer->l_next;			\
108
	  oldcvlist = flayer->l_cvlist;			\
108
	  oldcvlist = flayer->l_cvlist;			\
109
	  debug1("oldcvlist: %p\n", oldcvlist);		\
109
	  debug1("oldcvlist: %x\n", oldcvlist);		\
110
	  flayer->l_cvlist = oldlay->l_cvlist;		\
110
	  flayer->l_cvlist = oldlay->l_cvlist;		\
111
	  for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext)	\
111
	  for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext)	\
112
		cv->c_layer = flayer;			\
112
		cv->c_layer = flayer;			\
(-)screen.orig/list_window.c (-1 / +1 lines)
Lines 515-521 Link Here
515
515
516
  if (onblank)
516
  if (onblank)
517
    {
517
    {
518
      debug3("flayer %p %d %x\n", flayer, flayer->l_width, flayer->l_height);
518
      debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height);
519
      if (!display)
519
      if (!display)
520
	{
520
	{
521
	  LMsg(0, "windowlist -b: display required");
521
	  LMsg(0, "windowlist -b: display required");
(-)screen.orig/loadav.c (-3 / +3 lines)
Lines 85-97 Link Here
85
85
86
  if ((fp = secfopen("/proc/loadavg", "r")) == NULL)
86
  if ((fp = secfopen("/proc/loadavg", "r")) == NULL)
87
    return 0;
87
    return 0;
88
  s = fgets(buf, sizeof(buf), fp);
88
  *buf = 0;
89
  fgets(buf, sizeof(buf), fp);
89
  fclose(fp);
90
  fclose(fp);
90
  if (s == NULL)
91
    return 0;
92
  /* can't use fscanf because the decimal point symbol depends on
91
  /* can't use fscanf because the decimal point symbol depends on
93
   * the locale but the kernel uses always '.'.
92
   * the locale but the kernel uses always '.'.
94
   */
93
   */
94
  s = buf;
95
  for (i = 0; i < (LOADAV_NUM > 3 ? 3 : LOADAV_NUM); i++)
95
  for (i = 0; i < (LOADAV_NUM > 3 ? 3 : LOADAV_NUM); i++)
96
    {
96
    {
97
      d = e = 0;
97
      d = e = 0;
(-)screen.orig/Makefile.in (-8 / +8 lines)
Lines 67-73 Link Here
67
	sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \
67
	sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \
68
	list_display.c list_generic.c list_window.c
68
	list_display.c list_generic.c list_window.c
69
OFILES=	screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \
69
OFILES=	screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \
70
	search.o tty.o term.o window.o utmp.o loadav.o help.o \
70
	search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \
71
	termcap.o input.o attacher.o pty.o process.o display.o comm.o \
71
	termcap.o input.o attacher.o pty.o process.o display.o comm.o \
72
	kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \
72
	kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \
73
	list_generic.o list_display.o list_window.o \
73
	list_generic.o list_display.o list_window.o \
Lines 91-105 Link Here
91
	-if [ -f $(DESTDIR)$(bindir)/screen ] && [ ! -f $(DESTDIR)$(bindir)/screen.old ]; then mv $(DESTDIR)$(bindir)/screen $(DESTDIR)$(bindir)/screen.old; fi
91
	-if [ -f $(DESTDIR)$(bindir)/screen ] && [ ! -f $(DESTDIR)$(bindir)/screen.old ]; then mv $(DESTDIR)$(bindir)/screen $(DESTDIR)$(bindir)/screen.old; fi
92
	rm -f $(DESTDIR)$(bindir)/screen
92
	rm -f $(DESTDIR)$(bindir)/screen
93
	(cd $(DESTDIR)$(bindir) && ln -f -s $(SCREEN) screen)
93
	(cd $(DESTDIR)$(bindir) && ln -f -s $(SCREEN) screen)
94
	cp $(srcdir)/utf8encodings/?? $(RPM_BUILD_ROOT)$(SCREENENCODINGS)
94
	cp $(srcdir)/utf8encodings/?? $(DESTDIR)$(SCREENENCODINGS)
95
95
96
###############################################################################
96
###############################################################################
97
install: installdirs install_bin
97
install: installdirs install_bin
98
	pushd doc ; $(MAKE) install; popd
98
	cd doc ; $(MAKE) install
99
	-(export TERMINFO="$(DESTDIR)$(datadir)/terminfo"; if [ -d "$$TERMINFO" ]; then \
99
	-if [ -d $(DESTDIR)/usr/lib/terminfo ]; then \
100
		tic ${srcdir}/terminfo/screeninfo.src; \
100
		PATH="$$PATH:/usr/5bin" tic ${srcdir}/terminfo/screeninfo.src; \
101
		chmod 644 "$$TERMINFO"/s/screen*; \
101
		chmod 644 $(DESTDIR)/usr/lib/terminfo/s/screen*; \
102
	fi)
102
	fi
103
# Better do this by hand. E.g. under RCS...
103
# Better do this by hand. E.g. under RCS...
104
#	cat ${srcdir}/terminfo/screencap >> /etc/termcap
104
#	cat ${srcdir}/terminfo/screencap >> /etc/termcap
105
	@echo "termcap entry (${srcdir}/terminfo/screencap) should be installed manually."
105
	@echo "termcap entry (${srcdir}/terminfo/screencap) should be installed manually."
Lines 107-113 Link Here
107
107
108
installdirs:
108
installdirs:
109
# Path leading to ETCSCREENRC and Socketdirectory not checked.
109
# Path leading to ETCSCREENRC and Socketdirectory not checked.
110
	$(srcdir)/etc/mkinstalldirs $(DESTDIR)$(bindir) $(RPM_BUILD_ROOT)$(SCREENENCODINGS)
110
	$(srcdir)/etc/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(SCREENENCODINGS)
111
	cd doc ; $(MAKE) installdirs
111
	cd doc ; $(MAKE) installdirs
112
112
113
uninstall: .version
113
uninstall: .version
(-)screen.orig/mark.c (-1238 / +1150 lines)
Lines 45-56 Link Here
45
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
45
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
46
 */
46
 */
47
47
48
static int  is_letter __P((int));
48
static int  is_letter __P((char));
49
static void nextword __P((int *, int *, int, int));
49
static void nextword __P((int *, int *, int, int));
50
static int  linestart __P((int));
50
static int  linestart __P((int));
51
static int  lineend __P((int));
51
static int  lineend __P((int));
52
static int  rem __P((int, int , int , int , int , char *, int));
52
static int  rem __P((int, int, int, int, int, char *, int));
53
static int  eq __P((int, int ));
53
static int  eq __P((int, int));
54
static int  MarkScrollDownDisplay __P((int));
54
static int  MarkScrollDownDisplay __P((int));
55
static int  MarkScrollUpDisplay __P((int));
55
static int  MarkScrollUpDisplay __P((int));
56
56
Lines 69-144 Link Here
69
int pastefont = 1;
69
int pastefont = 1;
70
#endif
70
#endif
71
71
72
struct LayFuncs MarkLf =
72
struct LayFuncs MarkLf = {
73
{
73
	MarkProcess,
74
  MarkProcess,
74
	MarkAbort,
75
  MarkAbort,
75
	MarkRedisplayLine,
76
  MarkRedisplayLine,
76
	DefClearLine,
77
  DefClearLine,
77
	MarkRewrite,
78
  MarkRewrite,
78
	DefResize,
79
  DefResize,
79
	DefRestore,
80
  DefRestore,
80
	0
81
  0
82
};
81
};
83
82
84
int join_with_cr =  0;
83
int join_with_cr = 0;
85
int compacthist = 0;
84
int compacthist = 0;
86
85
87
unsigned char mark_key_tab[256]; /* this array must be initialised first! */
86
unsigned char mark_key_tab[256]; /* this array must be initialised first! */
88
87
89
static struct markdata *markdata;
88
static struct markdata *markdata;
90
89
91
92
/*
90
/*
93
 * VI like is_letter: 0 - whitespace
91
 * VI like is_letter: 0 - whitespace
94
 *                    1 - letter
92
 *                    1 - letter
95
 *		      2 - other
93
 *                    2 - other
96
 */
94
 */
97
static int is_letter(c)
95
static int
98
char c;
96
is_letter(char c)
99
{
97
{
100
  if ((c >= 'a' && c <= 'z') ||
98
	if ((c >= 'a' && c <= 'z') ||
101
      (c >= 'A' && c <= 'Z') ||
99
	    (c >= 'A' && c <= 'Z') ||
102
      (c >= '0' && c <= '9') ||
100
	    (c >= '0' && c <= '9') ||
103
      c == '_' || c == '.' ||
101
	    c == '_' || c == '.' ||
104
      c == '@' || c == ':' ||
102
	    c == '@' || c == ':' ||
105
      c == '%' || c == '!' ||
103
	    c == '%' || c == '!' ||
106
      c == '-' || c == '+')
104
	    c == '-' || c == '+')
107
    /* thus we can catch email-addresses as a word :-) */
105
    /* thus we can catch email-addresses as a word :-) */
108
    return 1;
106
		return 1;
109
  else if (c != ' ')
107
	else if (c != ' ')
110
    return 2;
108
		return 2;
111
  return 0;
109
	return 0;
112
}
110
}
113
111
114
static int
112
static int
115
linestart(y)
113
linestart(int y)
116
int y;
117
{
114
{
118
  register int x;
115
	register int x;
119
  register unsigned char *i;
116
	register unsigned char *i;
120
117
121
  for (x = markdata->left_mar, i = WIN(y)->image + x; x < fore->w_width - 1; x++)
118
	for (x = markdata->left_mar, i = WIN(y)->image + x; x < fore->w_width - 1; x++)
122
    if (*i++ != ' ')
119
		if (*i++ != ' ')
123
      break;
120
			break;
124
  if (x == fore->w_width - 1)
121
	if (x == fore->w_width - 1)
125
    x = markdata->left_mar;
122
		x = markdata->left_mar;
126
  return x;
123
	return x;
127
}
124
}
128
125
129
static int
126
static int
130
lineend(y)
127
lineend(int y)
131
int y;
132
{
128
{
133
  register int x;
129
	register int x;
134
  register unsigned char *i;
130
	register unsigned char *i;
135
131
136
  for (x = markdata->right_mar, i = WIN(y)->image + x; x >= 0; x--)
132
	for (x = markdata->right_mar, i = WIN(y)->image + x; x >= 0; x--)
137
    if (*i-- != ' ')
133
		if (*i-- != ' ')
138
      break;
134
			break;
139
  if (x < 0)
135
	if (x < 0)
140
    x = markdata->left_mar;
136
		x = markdata->left_mar;
141
  return x;
137
	return x;
142
}
138
}
143
139
144
/*
140
/*
Lines 149-198 Link Here
149
static int
145
static int
150
nextchar(int *xp, int *yp, int direction, char target, int num)
146
nextchar(int *xp, int *yp, int direction, char target, int num)
151
{
147
{
152
  int width;  /* width of the current window. */
148
	int width;            /* width of the current window. */
153
  int x;      /* x coordinate of the current cursor position. */
149
	int x;                /* x coordinate of the current cursor position. */
154
  int step;   /* amount to increment x (+1 or -1) */
150
	int step;             /* amount to increment x (+1 or -1) */
155
  int adjust; /* Final adjustment of cursor position. */
151
	int adjust;           /* Final adjustment of cursor position. */
156
  char *displayed_line; /* Line in which search takes place. */
152
	char *displayed_line; /* Line in which search takes place. */
157
 
153
158
  debug("nextchar\n");
154
	debug("nextchar\n");
159
 
155
160
  x = *xp;
156
	x = *xp;
161
  step = 1;
157
	step = 1;
162
  adjust = 0;
158
	adjust = 0;
163
  width = fore->w_width;
159
	width = fore->w_width;
164
  displayed_line = (char *)WIN(*yp) -> image;
160
	displayed_line = (char *)WIN(*yp)->image;
165
 
161
166
  switch(direction) {
162
	switch (direction) {
167
    case 't':
163
	case 't':
168
      adjust = -1; /* fall through */
164
		adjust = -1; /* fall through */
169
    case 'f':
165
	case 'f':
170
      step = 1;
166
		step = 1;
171
      break;
167
		break;
172
    case 'T':
168
	case 'T':
173
      adjust = 1; /* fall through */
169
		adjust = 1; /* fall through */
174
    case 'F':
170
	case 'F':
175
      step = -1;
171
		step = -1;
176
      break;
172
		break;
177
    default:
173
	default:
178
      ASSERT(0);
174
		ASSERT(0);
179
  }
175
	}
180
 
176
181
  x += step;
177
	x += step;
182
 
178
183
  debug1("ml->image = %s\n", displayed_line);
179
	debug1("ml->image = %s\n", displayed_line);
184
  debug2("num = %d, width = %d\n",num, width);
180
	debug2("num = %d, width = %d\n", num, width);
185
  debug2("x = %d target = %c\n", x, target );
181
	debug2("x = %d target = %c\n", x, target);
186
 
182
187
  for ( ;x>=0 && x <= width; x += step) {
183
	for (; x >= 0 && x <= width; x += step) {
188
    if (displayed_line[x] == target) {
184
		if (displayed_line[x] == target) {
189
      if (--num == 0) {
185
			if (--num == 0) {
190
        *xp = x + adjust;
186
				*xp = x + adjust;
191
        return 0;
187
				return 0;
192
      }
188
			}
193
    }
189
		}
194
  }
190
	}
195
  return -1;
191
	return -1;
196
}
192
}
197
193
198
/*
194
/*
Lines 204-425 Link Here
204
 *  NW_BIG:             match WORDs not words
200
 *  NW_BIG:             match WORDs not words
205
 */
201
 */
206
202
207
#define NW_BACK		(1<<0)
203
#define NW_BACK      (1<<0)
208
#define NW_ENDOFWORD	(1<<1)
204
#define NW_ENDOFWORD (1<<1)
209
#define NW_MUSTMOVE	(1<<2)
205
#define NW_MUSTMOVE  (1<<2)
210
#define NW_BIG		(1<<3)
206
#define NW_BIG       (1<<3)
211
212
213
207
214
static void
208
static void
215
nextword(xp, yp, flags, num)
209
nextword(int *xp, int *yp, int flags, int num)
216
int *xp, *yp, flags, num;
217
{
210
{
218
  int xx = fore->w_width, yy = fore->w_histheight + fore->w_height;
211
	int xx = fore->w_width, yy = fore->w_histheight + fore->w_height;
219
  register int sx, oq, q, x, y;
212
	register int sx, oq, q, x, y;
220
  struct mline *ml;
213
	struct mline *ml;
221
214
222
  x = *xp;
215
	x = *xp;
223
  y = *yp;
216
	y = *yp;
224
  sx = (flags & NW_BACK) ? -1 : 1;
217
	sx = (flags & NW_BACK) ? -1 : 1;
225
  if ((flags & NW_ENDOFWORD) && (flags & NW_MUSTMOVE))
218
	if ((flags & NW_ENDOFWORD) && (flags & NW_MUSTMOVE))
226
    x += sx;
219
		x += sx;
227
  ml = WIN(y);
220
	ml = WIN(y);
228
  for (oq = -1; ; x += sx, oq = q)
221
	for (oq = -1;; x += sx, oq = q) {
229
    {
222
		if (x >= xx || x < 0)
230
      if (x >= xx || x < 0)
223
			q = 0;
231
	q = 0;
224
		else if (flags & NW_BIG)
232
      else if (flags & NW_BIG)
225
			q = ml->image[x] == ' ';
233
        q = ml->image[x] == ' ';
226
		else
234
      else
227
			q = is_letter(ml->image[x]);
235
        q = is_letter(ml->image[x]);
228
236
      if (oq >= 0 && oq != q)
229
		if (oq >= 0 && oq != q) {
237
	{
230
			if (oq == 0 || !(flags & NW_ENDOFWORD))
238
	  if (oq == 0 || !(flags & NW_ENDOFWORD))
231
				*xp = x;
239
	    *xp = x;
232
			else
240
	  else
233
				*xp = x - sx;
241
	    *xp = x-sx;
234
			*yp = y;
242
	  *yp = y;
235
243
	  if ((!(flags & NW_ENDOFWORD) && q) ||
236
			if ((!(flags & NW_ENDOFWORD) && q) || ((flags & NW_ENDOFWORD) && oq)) {
244
	      ((flags & NW_ENDOFWORD) && oq))
237
				if (--num <= 0)
245
	    {
238
					return;
246
	      if (--num <= 0)
239
			}
247
	        return;
240
		}
248
	    }
241
249
	}
242
		if (x == xx) {
250
      if (x == xx)
243
			x = -1;
251
	{
244
			if (++y >= yy)
252
	  x = -1;
245
				return;
253
	  if (++y >= yy)
246
			ml = WIN(y);
254
	    return;
247
		} else if (x < 0) {
255
	  ml = WIN(y);
248
			x = xx;
256
	}
249
			if (--y < 0)
257
      else if (x < 0)
250
				return;
258
	{
251
			ml = WIN(y);
259
	  x = xx;
252
		}
260
	  if (--y < 0)
261
	    return;
262
	  ml = WIN(y);
263
	}
253
	}
264
    }
265
}
254
}
266
255
267
268
/*
256
/*
269
 * y1, y2 are WIN coordinates
257
 * y1, y2 are WIN coordinates
270
 *
258
 *
271
 * redisplay:	0  -  just copy
259
 * redisplay: 0  -  just copy
272
 * 		1  -  redisplay + copy
260
 *            1  -  redisplay + copy
273
 *		2  -  count + copy, don't redisplay
261
 *            2  -  count + copy, don't redisplay
274
 */
262
 */
275
263
276
static int
264
static int
277
rem(x1, y1, x2, y2, redisplay, pt, yend)
265
rem(int x1, int y1, int x2, int y2, int redisplay, char *pt, int yend)
278
int x1, y1, x2, y2, redisplay, yend;
279
char *pt;
280
{
266
{
281
  int i, j, from, to, ry, c;
267
	int i, j, from, to, ry, c;
282
  int l = 0;
268
	int l = 0;
283
  unsigned char *im;
269
	unsigned char *im;
284
  struct mline *ml;
270
	struct mline *ml;
285
#ifdef FONT
271
#ifdef FONT
286
  int cf, cfx, font;
272
	int cf, cfx, font;
287
  unsigned char *fo, *fox;
273
	unsigned char *fo, *fox;
288
#endif
274
#endif
289
275
290
  markdata->second = 0;
276
	markdata->second = 0;
291
  if (y2 < y1 || ((y2 == y1) && (x2 < x1)))
277
	if (y2 < y1 || ((y2 == y1) && (x2 < x1))) {
292
    {
278
		i = y2;
293
      i = y2;
279
		y2 = y1;
294
      y2 = y1;
280
		y1 = i;
295
      y1 = i;
281
		i = x2;
296
      i = x2;
282
		x2 = x1;
297
      x2 = x1;
283
		x1 = i;
298
      x1 = i;
284
	}
299
    }
285
	ry = y1 - markdata->hist_offset;
300
  ry = y1 - markdata->hist_offset;
286
301
287
	i = y1;
302
  i = y1;
288
	if (redisplay != 2 && pt == 0 && ry < 0) {
303
  if (redisplay != 2 && pt == 0 && ry <0)
289
		i -= ry;
304
    {
290
		ry = 0;
305
      i -= ry;
291
	}
306
      ry = 0;
292
	for (; i <= y2; i++, ry++) {
307
    }
293
		if (redisplay != 2 && pt == 0 && ry > yend)
308
  for (; i <= y2; i++, ry++)
294
			break;
309
    {
295
		ml = WIN(i);
310
      if (redisplay != 2 && pt == 0 && ry > yend)
296
		from = (i == y1) ? x1 : 0;
311
	break;
297
312
      ml = WIN(i);
298
		if (from < markdata->left_mar)
313
      from = (i == y1) ? x1 : 0;
299
			from = markdata->left_mar;
314
      if (from < markdata->left_mar)
300
		for (to = fore->w_width, im = ml->image + to; to >= 0; to--)
315
	from = markdata->left_mar;
301
			if (*im-- != ' ')
316
      for (to = fore->w_width, im = ml->image + to; to >= 0; to--)
302
				break;
317
        if (*im-- != ' ')
303
		if (i == y2 && x2 < to)
318
	  break;
304
			to = x2;
319
      if (i == y2 && x2 < to)
305
		if (to > markdata->right_mar)
320
	to = x2;
306
			to = markdata->right_mar;
321
      if (to > markdata->right_mar)
307
		if (redisplay == 1 && from <= to && ry >= 0 && ry <= yend)
322
	to = markdata->right_mar;
308
			MarkRedisplayLine(ry, from, to, 0);
323
      if (redisplay == 1 && from <= to && ry >=0 && ry <= yend)
309
		if (redisplay != 2 && pt == 0)	/* don't count/copy */
324
	MarkRedisplayLine(ry, from, to, 0);
310
			continue;
325
      if (redisplay != 2 && pt == 0)	/* don't count/copy */
311
		j = from;
326
	continue;
327
      j = from;
328
#ifdef DW_CHARS
312
#ifdef DW_CHARS
329
      if (dw_right(ml, j, fore->w_encoding))
313
		if (dw_right(ml, j, fore->w_encoding))
330
	j--;
314
			j--;
331
#endif
315
#endif
332
      im = ml->image + j;
316
		im = ml->image + j;
333
#ifdef FONT
317
#ifdef FONT
334
      fo = ml->font + j;
318
		fo = ml->font + j;
335
      fox = ml->fontx + j;
319
		fox = ml->fontx + j;
336
      font = ASCII;
320
		font = ASCII;
337
#endif
321
#endif
338
      for (; j <= to; j++)
322
		for (; j <= to; j++) {
339
	{
323
			c = (unsigned char)*im++;
340
	  c = (unsigned char)*im++;
341
#ifdef FONT
324
#ifdef FONT
342
	  cf = (unsigned char)*fo++;
325
			cf = (unsigned char)*fo++;
343
	  cfx = (unsigned char)*fox++;
326
			cfx = (unsigned char)*fox++;
344
# ifdef UTF8
327
# ifdef UTF8
345
	  if (fore->w_encoding == UTF8)
328
			if (fore->w_encoding == UTF8) {
346
	    {
329
				c |= cf << 8 | cfx << 16;
347
	      c |= cf << 8 | cfx << 16;
330
				if (c == UCS_HIDDEN)
348
	      if (c == UCS_HIDDEN)
331
					continue;
349
		continue;
332
				c = ToUtf8_comb(pt, c);
350
	      c = ToUtf8_comb(pt, c);
333
				l += c;
351
	      l += c;
334
				if (pt)
352
	      if (pt)
335
					pt += c;
353
	        pt += c;
336
				continue;
354
	      continue;
337
			}
355
	    }
356
# endif
338
# endif
357
# ifdef DW_CHARS
339
# ifdef DW_CHARS
358
	  if (is_dw_font(cf))
340
			if (is_dw_font(cf)) {
359
	    {
341
				c = c << 8 | (unsigned char)*im++;
360
	      c = c << 8 | (unsigned char)*im++;
342
				fo++;
361
	      fo++;
343
				j++;
362
	      j++;
344
			}
363
	    }
364
# endif
345
# endif
365
	  if (pastefont)
346
			if (pastefont) {
366
	    {
347
				c = EncodeChar(pt, c | cf << 16, fore->w_encoding, &font);
367
	      c = EncodeChar(pt, c | cf << 16, fore->w_encoding, &font);
348
				l += c;
368
	      l += c;
349
				if (pt)
369
	      if (pt)
350
					pt += c;
370
		pt += c;
351
				continue;
371
	      continue;
352
			}
372
	    }
373
#endif /* FONT */
353
#endif /* FONT */
374
	  if (pt)
354
			if (pt)
375
	    *pt++ = c;
355
				*pt++ = c;
376
	  l++;
356
			l++;
377
	}
357
		}
378
#ifdef FONT
358
#ifdef FONT
379
      if (pastefont && font != ASCII)
359
		if (pastefont && font != ASCII) {
380
	{
360
			if (pt) {
381
	  if (pt)
361
				strcpy(pt, "\033(B");
382
	    {
362
				pt += 3;
383
	      strcpy(pt, "\033(B");
363
			}
384
	      pt += 3;
364
			l += 3;
385
	    }
365
		}
386
	  l += 3;
387
	}
388
#endif
366
#endif
389
      if (i != y2 && (to != fore->w_width - 1 || ml->image[to + 1] == ' '))
367
		if (i != y2 && (to != fore->w_width - 1 || ml->image[to + 1] == ' ')) {
390
	{
368
			/*
391
	  /*
369
			 * this code defines, what glues lines together
392
	   * this code defines, what glues lines together
370
			 */
393
	   */
371
			switch (markdata->nonl) {
394
	  switch (markdata->nonl)
372
			case 0:		/* lines separated by newlines */
395
	    {
373
				if (pt)
396
	    case 0:		/* lines separated by newlines */
374
					*pt++ = '\r';
397
	      if (pt)
375
				l++;
398
		*pt++ = '\r';
376
				if (join_with_cr) {
399
	      l++;
377
					if (pt)
400
	      if (join_with_cr)
378
						*pt++ = '\n';
401
		{
379
					l++;
402
		  if (pt)
380
				}
403
		    *pt++ = '\n';
381
				break;
404
		  l++;
382
			case 1:		/* nothing to separate lines */
383
				break;
384
			case 2:		/* lines separated by blanks */
385
				if (pt)
386
					*pt++ = ' ';
387
				l++;
388
				break;
389
			case 3:		/* seperate by comma, for csh junkies */
390
				if (pt)
391
					*pt++ = ',';
392
				l++;
393
				break;
394
			}
405
		}
395
		}
406
	      break;
407
	    case 1:		/* nothing to separate lines */
408
	      break;
409
	    case 2:		/* lines separated by blanks */
410
	      if (pt)
411
		*pt++ = ' ';
412
	      l++;
413
	      break;
414
	    case 3:		/* seperate by comma, for csh junkies */
415
	      if (pt)
416
	        *pt++ = ',';
417
	      l++;
418
	      break;
419
	    }
420
	}
396
	}
421
    }
397
	return l;
422
  return l;
423
}
398
}
424
399
425
/* Check if two chars are identical. All digits are treated
400
/* Check if two chars are identical. All digits are treated
Lines 427-493 Link Here
427
 */
402
 */
428
403
429
static int
404
static int
430
eq(a, b)
405
eq(int a, int b)
431
int a, b;
432
{
406
{
433
  if (a == b)
407
	if (a == b)
434
    return 1;
408
		return 1;
435
  if (a == 0 || b == 0)
409
	if (a == 0 || b == 0)
436
    return 1;
410
		return 1;
437
  if (a <= '9' && a >= '0' && b <= '9' && b >= '0')
411
	if (a <= '9' && a >= '0' && b <= '9' && b >= '0')
438
    return 1;
412
		return 1;
439
  return 0;
413
	return 0;
440
}
414
}
441
415
442
443
/**********************************************************************/
416
/**********************************************************************/
444
417
445
int
418
int
446
GetHistory()	/* return value 1 if copybuffer changed */
419
GetHistory()	/* return value 1 if copybuffer changed */
447
{
420
{
448
  int i = 0, q = 0, xx, yy, x, y;
421
	int i = 0, q = 0, xx, yy, x, y;
449
  unsigned char *linep;
422
	unsigned char *linep;
450
  struct mline *ml;
423
	struct mline *ml;
451
424
452
  ASSERT(display && fore);
425
	ASSERT(display && fore);
453
  x = fore->w_x;
426
	x = fore->w_x;
454
  if (x >= fore->w_width)
427
	if (x >= fore->w_width)
455
    x = fore->w_width - 1;
428
		x = fore->w_width - 1;
456
  y = fore->w_y + fore->w_histheight;
429
	y = fore->w_y + fore->w_histheight;
457
  debug2("cursor is at x=%d, y=%d\n", x, y);
430
	debug2("cursor is at x=%d, y=%d\n", x, y);
458
  ml = WIN(y);
431
	ml = WIN(y);
459
  for (xx = x - 1, linep = ml->image + xx; xx >= 0; xx--)
432
	for (xx = x - 1, linep = ml->image + xx; xx >= 0; xx--)
460
    if ((q = *linep--) != ' ' )
433
		if ((q = *linep--) != ' ')
461
      break;
434
			break;
462
  debug3("%c at (%d,%d)\n", q, xx, y);
435
	debug3("%c at (%d,%d)\n", q, xx, y);
463
  for (yy = y - 1; yy >= 0; yy--)
436
	for (yy = y - 1; yy >= 0; yy--) {
464
    {
437
		ml = WIN(yy);
465
      ml = WIN(yy);
438
		linep = ml->image;
466
      linep = ml->image;
439
		if (xx < 0 || eq(linep[xx], q)) {		/* line is matching... */
467
      if (xx < 0 || eq(linep[xx], q))
440
			for (i = fore->w_width - 1, linep += i; i >= x; i--)
468
	{		/* line is matching... */
441
				if (*linep-- != ' ')
469
	  for (i = fore->w_width - 1, linep += i; i >= x; i--)
442
					break;
470
	    if (*linep-- != ' ')
443
			if (i >= x)
471
	      break;
444
				break;
472
	  if (i >= x)
445
		}
473
	    break;
446
	}
474
	}
447
	if (yy < 0)
475
    }
448
		return 0;
476
  if (yy < 0)
449
	if (D_user->u_plop.buf)
477
    return 0;
450
		UserFreeCopyBuffer(D_user);
478
  if (D_user->u_plop.buf)
451
	if ((D_user->u_plop.buf = (char *)malloc((unsigned)(i - x + 2))) ==
479
    UserFreeCopyBuffer(D_user);
452
	    NULL) {
480
  if ((D_user->u_plop.buf = (char *)malloc((unsigned) (i - x + 2))) == NULL)
453
		LMsg(0, "Not enough memory... Sorry.");
481
    {
454
		return 0;
482
      LMsg(0, "Not enough memory... Sorry.");
455
	}
483
      return 0;
456
	bcopy((char *)linep - i + x + 1, D_user->u_plop.buf, i - x + 1);
484
    }
457
	D_user->u_plop.len = i - x + 1;
485
  bcopy((char *)linep - i + x + 1, D_user->u_plop.buf, i - x + 1);
486
  D_user->u_plop.len = i - x + 1;
487
#ifdef ENCODINGS
458
#ifdef ENCODINGS
488
  D_user->u_plop.enc = fore->w_encoding;
459
	D_user->u_plop.enc = fore->w_encoding;
489
#endif
460
#endif
490
  return 1;
461
	return 1;
491
}
462
}
492
463
493
/**********************************************************************/
464
/**********************************************************************/
Lines 496-593 Link Here
496
void
467
void
497
MarkRoutine()
468
MarkRoutine()
498
{
469
{
499
  int x, y;
470
	int x, y;
500
471
501
  ASSERT(fore && display && D_user);
472
	ASSERT(fore && display && D_user);
502
473
503
  debug2("MarkRoutine called: fore nr %d, display %s\n",
474
	debug2("MarkRoutine called: fore nr %d, display %s\n", fore->w_number, D_usertty);
504
         fore->w_number, D_usertty);
505
475
506
  if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1))
476
	if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1))
507
    return;
477
		return;
508
  flayer->l_encoding = fore->w_encoding;
478
	flayer->l_encoding = fore->w_encoding;
509
  flayer->l_mode = 1;
479
	flayer->l_mode = 1;
510
  markdata = (struct markdata *)flayer->l_data;
480
	markdata = (struct markdata *)flayer->l_data;
511
  markdata->md_user = D_user;	/* XXX: Correct? */
481
	markdata->md_user = D_user;	/* XXX: Correct? */
512
  markdata->md_window = fore;
482
	markdata->md_window = fore;
513
  markdata->second = 0;
483
	markdata->second = 0;
514
  markdata->rep_cnt = 0;
484
	markdata->rep_cnt = 0;
515
  markdata->append_mode = 0;
485
	markdata->append_mode = 0;
516
  markdata->write_buffer = 0;
486
	markdata->write_buffer = 0;
517
  markdata->nonl = 0;
487
	markdata->nonl = 0;
518
  markdata->left_mar  = 0;
488
	markdata->left_mar = 0;
519
  markdata->right_mar = fore->w_width - 1;
489
	markdata->right_mar = fore->w_width - 1;
520
  markdata->hist_offset = fore->w_histheight;
490
	markdata->hist_offset = fore->w_histheight;
521
  x = fore->w_x;
491
	x = fore->w_x;
522
  y = D2W(fore->w_y);
492
	y = D2W(fore->w_y);
523
  if (x >= fore->w_width)
493
	if (x >= fore->w_width)
524
    x = fore->w_width - 1;
494
		x = fore->w_width - 1;
525
495
526
  LGotoPos(flayer, x, W2D(y));
496
	LGotoPos(flayer, x, W2D(y));
527
  LMsg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)",
497
	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);
528
      x + 1, W2D(y + 1), fore->w_histheight, fore->w_width, fore->w_height);
498
	markdata->cx = markdata->x1 = x;
529
  markdata->cx = markdata->x1 = x;
499
	markdata->cy = markdata->y1 = y;
530
  markdata->cy = markdata->y1 = y;
500
	flayer->l_x = x;
531
  flayer->l_x = x;
501
	flayer->l_y = W2D(y);
532
  flayer->l_y = W2D(y);
533
}
502
}
534
503
535
static void
504
static void
536
MarkProcess(inbufp,inlenp)
505
MarkProcess(char **inbufp, int *inlenp)
537
char **inbufp;
538
int *inlenp;
539
{
506
{
540
  char *inbuf, *pt;
507
	char *inbuf, *pt;
541
  int inlen;
508
	int inlen;
542
  int cx, cy, x2, y2, j, yend;
509
	int cx, cy, x2, y2, j, yend;
543
  int newcopylen = 0, od;
510
	int newcopylen = 0, od;
544
  int in_mark;
511
	int in_mark;
545
  int rep_cnt;
512
	int rep_cnt;
546
  struct acluser *md_user;
513
	struct acluser *md_user;
547
514
548
/*
515
/*
549
  char *extrap = 0, extrabuf[100];
516
  char *extrap = 0, extrabuf[100];
550
*/
517
*/
551
518
552
  markdata = (struct markdata *)flayer->l_data;
519
	markdata = (struct markdata *)flayer->l_data;
553
  fore = markdata->md_window;
520
	fore = markdata->md_window;
554
  md_user = markdata->md_user;
521
	md_user = markdata->md_user;
555
  if (inbufp == 0)
522
	if (inbufp == 0) {
556
    {
523
		MarkAbort();
557
      MarkAbort();
524
		return;
558
      return;
525
	}
559
    }
526
560
527
	LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
561
  LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
528
	inbuf = *inbufp;
562
  inbuf= *inbufp;
529
	inlen = *inlenp;
563
  inlen= *inlenp;
530
	pt = inbuf;
564
  pt = inbuf;
531
	in_mark = 1;
565
  in_mark = 1;
532
	while (in_mark && (inlen /* || extrap */)) {
566
  while (in_mark && (inlen /* || extrap */))
533
		unsigned char ch = (unsigned char)*pt++;
567
    {
534
		inlen--;
568
      unsigned char ch = (unsigned char )*pt++;
535
		if (flayer->l_mouseevent.start) {
569
      inlen--;
536
			int r = LayProcessMouse(flayer, ch);
570
      if (flayer->l_mouseevent.start)
537
			if (r == -1)
571
	{
538
				LayProcessMouseSwitch(flayer, 0);
572
	  int r = LayProcessMouse(flayer, ch);
539
			else {
573
	  if (r == -1)
540
				if (r)
574
	    LayProcessMouseSwitch(flayer, 0);
541
					ch = 0222;
575
	  else
542
				else
576
	    {
543
					continue;
577
	      if (r)
544
			}
578
		ch = 0222;
545
		}
579
	      else
546
		od = mark_key_tab[(int)ch];
580
		continue;
547
		rep_cnt = markdata->rep_cnt;
581
	    }
548
		if (od >= '0' && od <= '9' && !markdata->f_cmd.flag) {
582
	}
549
			if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0)) {
583
      od = mark_key_tab[(int)ch];
550
				markdata->rep_cnt = 10 * rep_cnt + od - '0';
584
      rep_cnt = markdata->rep_cnt;
551
				continue;
585
      if (od >= '0' && od <= '9' && !markdata->f_cmd.flag)
586
        {
587
	  if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0))
588
	    {
589
	      markdata->rep_cnt = 10 * rep_cnt + od - '0';
590
	      continue;
591
 	      /*
552
 	      /*
592
	       * Now what is that 1001 here? Well, we have a screen with
553
	       * Now what is that 1001 here? Well, we have a screen with
593
	       * 25 * 80 = 2000 characters. Movement is at most across the full
554
	       * 25 * 80 = 2000 characters. Movement is at most across the full
Lines 598-629 Link Here
598
	       * words, as they should be more advanced. jw.
559
	       * words, as they should be more advanced. jw.
599
	       * Oh, wrong. We still give even the experienced user a factor of ten.
560
	       * Oh, wrong. We still give even the experienced user a factor of ten.
600
	       */
561
	       */
601
	    }
562
			}
602
	}
563
		}
603
      cx = markdata->cx;
564
		cx = markdata->cx;
604
      cy = markdata->cy;
565
		cy = markdata->cy;
605
566
606
      if (markdata -> f_cmd.flag) {
567
		if (markdata->f_cmd.flag) {
607
        debug2("searching for %c:%d\n",od,rep_cnt);
568
			debug2("searching for %c:%d\n", od, rep_cnt);
608
        markdata->f_cmd.flag = 0;
569
			markdata->f_cmd.flag = 0;
609
        markdata->rep_cnt = 0;
570
			markdata->rep_cnt = 0;
610
571
611
	if (isgraph (od)) {
572
			if (isgraph(od)) {
612
	  markdata->f_cmd.target = od;
573
				markdata->f_cmd.target = od;
613
	  rep_cnt = (rep_cnt) ? rep_cnt : 1;
574
				rep_cnt = (rep_cnt) ? rep_cnt : 1;
614
	  nextchar(&cx, &cy, markdata->f_cmd.direction, od, rep_cnt );
575
				nextchar(&cx, &cy, markdata->f_cmd.direction, od, rep_cnt);
615
	  revto(cx, cy);
576
				revto(cx, cy);
616
	  continue;
577
				continue;
617
	}
578
			}
618
      }
579
		}
619
580
620
processchar:
581
processchar:
621
      switch (od)
582
		switch (od) {
622
        {
583
		case 'f': /* fall through */
623
	case 'f': /* fall through */
584
		case 'F': /* fall through */
624
	case 'F': /* fall through */
585
		case 't': /* fall through */
625
	case 't': /* fall through */
586
		case 'T': /* fall through */
626
	case 'T': /* fall through */
627
	  /*
587
	  /*
628
	   * Set f_cmd to do a search on the next key stroke.
588
	   * Set f_cmd to do a search on the next key stroke.
629
	   * If we break, rep_cnt will be reset, so we
589
	   * If we break, rep_cnt will be reset, so we
Lines 632-1536 Link Here
632
	   * break here so later followon code will be
592
	   * break here so later followon code will be
633
	   * hit.
593
	   * hit.
634
	   */
594
	   */
635
	  markdata->f_cmd.flag = 1;
595
			markdata->f_cmd.flag = 1;
636
	  markdata->f_cmd.direction = od;
596
			markdata->f_cmd.direction = od;
637
	  debug("entering char search\n");
597
			debug("entering char search\n");
638
	  continue;
598
			continue;
639
	case ';':
599
		case ';':
640
	case ',':
600
		case ',':
641
	  if (!markdata->f_cmd.target)
601
			if (!markdata->f_cmd.target)
642
	    break;
602
				break;
643
	  if (!rep_cnt)
603
			if (!rep_cnt)
644
	    rep_cnt = 1;
604
				rep_cnt = 1;
645
	  nextchar(&cx, &cy,
605
			nextchar(&cx,
646
	      od == ';' ? markdata->f_cmd.direction : (markdata->f_cmd.direction ^ 0x20),
606
			         &cy,
647
	      markdata->f_cmd.target, rep_cnt );
607
			         od == ';' ? markdata->f_cmd.direction : (markdata->f_cmd.direction ^ 0x20),
648
	  revto(cx, cy);
608
			         markdata->f_cmd.target,
649
	  break;
609
			         rep_cnt);
650
	case 'o':
610
			         revto(cx, cy);
651
	case 'x':
611
			break;
652
	  if (!markdata->second)
612
		case 'o':
653
	    break;
613
		case 'x':
654
	  markdata->cx = markdata->x1;
614
			if (!markdata->second)
655
	  markdata->cy = markdata->y1;
615
				break;
656
	  markdata->x1 = cx;
616
			markdata->cx = markdata->x1;
657
	  markdata->y1 = cy;
617
			markdata->cy = markdata->y1;
658
	  revto(markdata->cx, markdata->cy);
618
			markdata->x1 = cx;
659
	  break;
619
			markdata->y1 = cy;
660
	case '\014':	/* CTRL-L Redisplay */
620
			revto(markdata->cx, markdata->cy);
661
	  Redisplay(0);
621
			break;
662
	  LGotoPos(flayer, cx, W2D(cy));
622
		case '\014':	/* CTRL-L Redisplay */
663
	  break;
623
			Redisplay(0);
664
	case 0202:	/* M-C-b */
624
			LGotoPos(flayer, cx, W2D(cy));
665
	case '\010':	/* CTRL-H Backspace */
625
			break;
666
	case 'h':
626
		case 0202:	/* M-C-b */
667
	  if (rep_cnt == 0)
627
		case '\010':	/* CTRL-H Backspace */
668
	    rep_cnt = 1;
628
		case 'h':
669
	  revto(cx - rep_cnt, cy);
629
			if (rep_cnt == 0)
670
	  break;
630
				rep_cnt = 1;
671
	case 0216:	/* M-C-p */
631
			revto(cx - rep_cnt, cy);
672
	case '\016':	/* CTRL-N */
632
			break;
673
	case 'j':
633
		case 0216:	/* M-C-p */
674
	  if (rep_cnt == 0)
634
		case '\016':	/* CTRL-N */
675
	    rep_cnt = 1;
635
		case 'j':
676
	  revto(cx, cy + rep_cnt);
636
			if (rep_cnt == 0)
677
	  break;
637
				rep_cnt = 1;
678
	case '+':
638
			revto(cx, cy + rep_cnt);
679
	  if (rep_cnt == 0)
639
			break;
680
	    rep_cnt = 1;
640
		case '+':
681
	  j = cy + rep_cnt;
641
			if (rep_cnt == 0)
682
	  if (j > fore->w_histheight + fore->w_height - 1)
642
				rep_cnt = 1;
683
	    j = fore->w_histheight + fore->w_height - 1;
643
			j = cy + rep_cnt;
684
	  revto(linestart(j), j);
644
			if (j > fore->w_histheight + fore->w_height - 1)
685
	  break;
645
				j = fore->w_histheight + fore->w_height - 1;
686
	case '-':
646
			revto(linestart(j), j);
687
	  if (rep_cnt == 0)
647
			break;
688
	    rep_cnt = 1;
648
		case '-':
689
	  cy -= rep_cnt;
649
			if (rep_cnt == 0)
690
	  if (cy < 0)
650
				rep_cnt = 1;
691
	    cy = 0;
651
			cy -= rep_cnt;
692
	  revto(linestart(cy), cy);
652
			if (cy < 0)
693
	  break;
653
				cy = 0;
694
	case '^':
654
			revto(linestart(cy), cy);
695
	  revto(linestart(cy), cy);
655
			break;
696
	  break;
656
		case '^':
697
	case '\n':
657
			revto(linestart(cy), cy);
698
	  revto(markdata->left_mar, cy + 1);
658
			break;
699
	  break;
659
		case '\n':
700
	case 0220:	/* M-C-p */
660
			revto(markdata->left_mar, cy + 1);
701
	case '\020':	/* CTRL-P */
661
			break;
702
	case 'k':
662
		case 0220:	/* M-C-p */
703
	  if (rep_cnt == 0)
663
		case '\020':	/* CTRL-P */
704
	    rep_cnt = 1;
664
		case 'k':
705
	  revto(cx, cy - rep_cnt);
665
			if (rep_cnt == 0)
706
	  break;
666
				rep_cnt = 1;
707
	case 0206:	/* M-C-f */
667
			revto(cx, cy - rep_cnt);
708
	case 'l':
668
			break;
709
	  if (rep_cnt == 0)
669
		case 0206:	/* M-C-f */
710
	    rep_cnt = 1;
670
		case 'l':
711
	  revto(cx + rep_cnt, cy);
671
			if (rep_cnt == 0)
712
	  break;
672
				rep_cnt = 1;
713
	case '\001':	/* CTRL-A from tcsh/emacs */
673
			revto(cx + rep_cnt, cy);
714
	case '0':
674
			break;
715
	  revto(markdata->left_mar, cy);
675
		case '\001':	/* CTRL-A from tcsh/emacs */
716
	  break;
676
		case '0':
717
	case '\004':    /* CTRL-D down half screen */
677
			revto(markdata->left_mar, cy);
718
	  if (rep_cnt == 0)
678
			break;
719
	    rep_cnt = (fore->w_height + 1) >> 1;
679
		case '\004':    /* CTRL-D down half screen */
720
	  revto_line(cx, cy + rep_cnt, W2D(cy));
680
			if (rep_cnt == 0)
721
	  break;
681
				rep_cnt = (fore->w_height + 1) >> 1;
722
	case '$':
682
			revto_line(cx, cy + rep_cnt, W2D(cy));
723
	  revto(lineend(cy), cy);
683
			break;
724
	  break;
684
		case '$':
725
        case '\022':	/* CTRL-R emacs style backwards search */
685
			revto(lineend(cy), cy);
726
	  ISearch(-1);
686
			break;
727
	  in_mark = 0;
687
		case '\022':	/* CTRL-R emacs style backwards search */
728
	  break;
688
			ISearch(-1);
729
        case '\023':	/* CTRL-S emacs style search */
689
			in_mark = 0;
730
	  ISearch(1);
690
			break;
731
	  in_mark = 0;
691
		case '\023':	/* CTRL-S emacs style search */
732
	  break;
692
			ISearch(1);
733
	case '\025':	/* CTRL-U up half screen */
693
			in_mark = 0;
734
	  if (rep_cnt == 0)
694
			break;
735
	    rep_cnt = (fore->w_height + 1) >> 1;
695
		case '\025':	/* CTRL-U up half screen */
736
	  revto_line(cx, cy - rep_cnt, W2D(cy));
696
			if (rep_cnt == 0)
737
	  break;
697
				rep_cnt = (fore->w_height + 1) >> 1;
738
	case '\007':	/* CTRL-G show cursorpos */
698
			revto_line(cx, cy - rep_cnt, W2D(cy));
739
	  if (markdata->left_mar == 0 && markdata->right_mar == fore->w_width - 1)
699
			break;
740
	    LMsg(0, "Column %d Line %d(+%d)", cx+1, W2D(cy)+1,
700
		case '\007':	/* CTRL-G show cursorpos */
741
		markdata->hist_offset);
701
			if (markdata->left_mar == 0 && markdata->right_mar == fore->w_width - 1)
742
	  else
702
				LMsg(0, "Column %d Line %d(+%d)", cx + 1, W2D(cy) + 1, markdata->hist_offset);
743
	    LMsg(0, "Column %d(%d..%d) Line %d(+%d)", cx+1,
703
			else
744
		markdata->left_mar+1, markdata->right_mar+1, W2D(cy)+1, markdata->hist_offset);
704
				LMsg(0, "Column %d(%d..%d) Line %d(+%d)",
745
	  break;
705
				    cx + 1, markdata->left_mar + 1,
746
	case '\002':	/* CTRL-B  back one page */
706
				    markdata->right_mar + 1, W2D(cy) + 1,
747
	  if (rep_cnt == 0)
707
				    markdata->hist_offset);
748
	    rep_cnt = 1;
708
			break;
749
	  rep_cnt *= fore->w_height;
709
		case '\002':	/* CTRL-B  back one page */
750
	  revto(cx, cy - rep_cnt);
710
			if (rep_cnt == 0)
751
	  break;
711
				rep_cnt = 1;
752
	case '\006':	/* CTRL-F  forward one page */
712
			rep_cnt *= fore->w_height;
753
	  if (rep_cnt == 0)
713
			revto(cx, cy - rep_cnt);
754
	    rep_cnt = 1;
714
			break;
755
	  rep_cnt *= fore->w_height;
715
		case '\006':	/* CTRL-F  forward one page */
756
	  revto(cx, cy + rep_cnt);
716
			if (rep_cnt == 0)
757
	  break;
717
				rep_cnt = 1;
758
	case '\005':	/* CTRL-E  scroll up */
718
			rep_cnt *= fore->w_height;
759
	  if (rep_cnt == 0)
719
			revto(cx, cy + rep_cnt);
760
	    rep_cnt = 1;
720
			break;
761
	  rep_cnt = MarkScrollUpDisplay(rep_cnt);
721
		case '\005':	/* CTRL-E  scroll up */
762
	  if (cy < D2W(0))
722
			if (rep_cnt == 0)
763
            revto(cx, D2W(0));
723
				rep_cnt = 1;
764
	  else
724
			rep_cnt = MarkScrollUpDisplay(rep_cnt);
765
            LGotoPos(flayer, cx, W2D(cy));
725
			if (cy < D2W(0))
766
	  break;
726
				revto(cx, D2W(0));
767
	case '\031': /* CTRL-Y  scroll down */
727
			else
768
	  if (rep_cnt == 0)
728
				LGotoPos(flayer, cx, W2D(cy));
769
	    rep_cnt = 1;
729
			break;
770
	  rep_cnt = MarkScrollDownDisplay(rep_cnt);
730
		case '\031': /* CTRL-Y  scroll down */
771
	  if (cy > D2W(fore->w_height-1))
731
			if (rep_cnt == 0)
772
            revto(cx, D2W(fore->w_height-1));
732
				rep_cnt = 1;
773
	  else
733
			rep_cnt = MarkScrollDownDisplay(rep_cnt);
774
            LGotoPos(flayer, cx, W2D(cy));
734
			if (cy > D2W(fore->w_height - 1))
775
	  break;
735
				revto(cx, D2W(fore->w_height - 1));
776
	case '@':
736
			else
737
				LGotoPos(flayer, cx, W2D(cy));
738
			break;
739
		case '@':
777
	  /* it may be useful to have a key that does nothing */
740
	  /* it may be useful to have a key that does nothing */
778
	  break;
741
			break;
779
	case '%':
742
		case '%':
780
	  /* rep_cnt is a percentage for the history buffer */
743
	  /* rep_cnt is a percentage for the history buffer */
781
	  if (rep_cnt < 0)
744
			if (rep_cnt < 0)
782
	    rep_cnt = 0;
745
				rep_cnt = 0;
783
	  if (rep_cnt > 100)
746
			if (rep_cnt > 100)
784
	    rep_cnt = 100;
747
				rep_cnt = 100;
785
	  revto_line(markdata->left_mar,
748
786
		     fore->w_histheight - fore->w_scrollback_height +
749
			revto_line(markdata->left_mar,
787
		     (int)(rep_cnt * (fore->w_scrollback_height + fore->w_height) / 100.0),
750
			    fore->w_histheight - fore->w_scrollback_height +
788
		     (fore->w_height - 1) / 2);
751
			    (int)(rep_cnt * (fore->w_scrollback_height +
789
	  break;
752
			    fore->w_height) / 100.0), (fore->w_height - 1) / 2);
790
	case 0201:
753
			break;
791
	case 'g':
754
		case 0201:
792
	  rep_cnt = 1;
755
		case 'g':
756
			rep_cnt = 1;
793
	  /* FALLTHROUGH */
757
	  /* FALLTHROUGH */
794
	case 0205:
758
		case 0205:
795
	case 'G':
759
		case 'G':
796
	  /* rep_cnt is here the WIN line number */
760
	  /* rep_cnt is here the WIN line number */
797
	  if (rep_cnt == 0)
761
			if (rep_cnt == 0)
798
	    rep_cnt = fore->w_histheight + fore->w_height;
762
				rep_cnt = fore->w_histheight + fore->w_height;
799
	  revto_line(markdata->left_mar, --rep_cnt, (fore->w_height - 1) / 2);
763
			revto_line(markdata->left_mar, --rep_cnt, (fore->w_height - 1) / 2);
800
	  break;
764
			break;
801
	case 'H':
765
		case 'H':
802
	  revto(markdata->left_mar, D2W(0));
766
			revto(markdata->left_mar, D2W(0));
803
	  break;
767
			break;
804
	case 'M':
768
		case 'M':
805
	  revto(markdata->left_mar, D2W((fore->w_height - 1) / 2));
769
			revto(markdata->left_mar, D2W((fore->w_height - 1) / 2));
806
	  break;
770
			break;
807
	case 'L':
771
		case 'L':
808
	  revto(markdata->left_mar, D2W(fore->w_height - 1));
772
			revto(markdata->left_mar, D2W(fore->w_height - 1));
809
	  break;
773
			break;
810
	case '|':
774
		case '|':
811
	  revto(--rep_cnt, cy);
775
			revto(--rep_cnt, cy);
812
	  break;
776
			break;
813
	case 'w':
777
		case 'w':
814
	  if (rep_cnt == 0)
778
			if (rep_cnt == 0)
815
	    rep_cnt = 1;
779
				rep_cnt = 1;
816
	  nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt);
780
			nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt);
817
	  revto(cx, cy);
781
			revto(cx, cy);
818
	  break;
782
			break;
819
	case 'e':
783
		case 'e':
820
	case 'E':
784
		case 'E':
821
	  if (rep_cnt == 0)
785
			if (rep_cnt == 0)
822
	    rep_cnt = 1;
786
				rep_cnt = 1;
823
	  nextword(&cx, &cy, NW_ENDOFWORD|NW_MUSTMOVE | (od == 'E' ? NW_BIG : 0), rep_cnt);
787
			nextword(&cx, &cy, NW_ENDOFWORD|NW_MUSTMOVE | (od == 'E' ? NW_BIG : 0), rep_cnt);
824
	  revto(cx, cy);
788
			revto(cx, cy);
825
	  break;
789
			break;
826
	case 'b':
790
		case 'b':
827
	case 'B':
791
		case 'B':
828
	  if (rep_cnt == 0)
792
			if (rep_cnt == 0)
829
	    rep_cnt = 1;
793
				rep_cnt = 1;
830
	  nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD|NW_MUSTMOVE | (od == 'B' ? NW_BIG : 0), rep_cnt);
794
			nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD|NW_MUSTMOVE | (od == 'B' ? NW_BIG : 0), rep_cnt);
831
	  revto(cx, cy);
795
			revto(cx, cy);
832
	  break;
796
			break;
833
	case 'a':
797
		case 'a':
834
	  markdata->append_mode = 1 - markdata->append_mode;
798
			markdata->append_mode = 1 - markdata->append_mode;
835
	  debug1("append mode %d--\n", markdata->append_mode);
799
			debug1("append mode %d--\n", markdata->append_mode);
836
	  LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend");
800
			LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend");
837
	  break;
801
			break;
838
	case 'v':
802
		case 'v':
839
	case 'V':
803
		case 'V':
840
	  /* this sets start column to column 9 for VI :set nu users */
804
	  /* this sets start column to column 9 for VI :set nu users */
841
	  if (markdata->left_mar == 8)
805
			if (markdata->left_mar == 8)
842
	    rep_cnt = 1;
806
				rep_cnt = 1;
843
	  else
807
			else
844
	    rep_cnt = 9;
808
				rep_cnt = 9;
845
	  /* FALLTHROUGH */
809
	  /* FALLTHROUGH */
846
	case 'c':
810
		case 'c':
847
	case 'C':
811
		case 'C':
848
	  /* set start column (c) and end column (C) */
812
	  /* set start column (c) and end column (C) */
849
	  if (markdata->second)
813
			if (markdata->second) {
850
	    {
814
				rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, fore->w_height - 1); /* Hack */
851
	      rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, fore->w_height-1); /* Hack */
815
				markdata->second = 1;	/* rem turns off second */
852
	      markdata->second = 1;	/* rem turns off second */
816
			}
853
	    }
817
			rep_cnt--;
854
	  rep_cnt--;
818
			if (rep_cnt < 0)
855
	  if (rep_cnt < 0)
819
				rep_cnt = cx;
856
	    rep_cnt = cx;
820
			if (od != 'C') {
857
	  if (od != 'C')
821
				markdata->left_mar = rep_cnt;
858
	    {
822
				if (markdata->left_mar > markdata->right_mar)
859
	      markdata->left_mar = rep_cnt;
823
					markdata->left_mar = markdata->right_mar;
860
	      if (markdata->left_mar > markdata->right_mar)
824
			} else {
861
		markdata->left_mar = markdata->right_mar;
825
				markdata->right_mar = rep_cnt;
862
	    }
826
				if (markdata->left_mar > markdata->right_mar)
863
	  else
827
					markdata->right_mar = markdata->left_mar;
864
	    {
828
			}
865
	      markdata->right_mar = rep_cnt;
829
			if (markdata->second) {
866
	      if (markdata->left_mar > markdata->right_mar)
830
				markdata->cx = markdata->x1;
867
		markdata->right_mar = markdata->left_mar;
831
				markdata->cy = markdata->y1;
868
	    }
832
				revto(cx, cy);
869
	  if (markdata->second)
833
			}
870
	    {
834
			if (od == 'v' || od == 'V')
871
	      markdata->cx = markdata->x1; markdata->cy = markdata->y1;
835
				LMsg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu");
872
	      revto(cx, cy);
836
			break;
873
	    }
837
		case 'J':
874
	  if (od == 'v' || od == 'V')
838
		/* how do you join lines in VI ? */
875
	    LMsg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu");
839
			markdata->nonl = (markdata->nonl + 1) % 4;
876
	  break;
840
			switch (markdata->nonl) {
877
	case 'J':
841
			case 0:
878
	  /* how do you join lines in VI ? */
842
				if (join_with_cr)
879
	  markdata->nonl = (markdata->nonl + 1) % 4;
843
					LMsg(0, "Multiple lines (CR/LF)");
880
	  switch (markdata->nonl)
844
				else
881
	    {
845
					LMsg(0, "Multiple lines (LF)");
882
	    case 0:
846
				break;
883
	      if (join_with_cr)
847
			case 1:
884
		LMsg(0, "Multiple lines (CR/LF)");
848
				LMsg(0, "Lines joined");
885
	      else
849
				break;
886
		LMsg(0, "Multiple lines (LF)");
850
			case 2:
887
	      break;
851
				LMsg(0, "Lines joined with blanks");
888
	    case 1:
852
				break;
889
	      LMsg(0, "Lines joined");
853
			case 3:
890
	      break;
854
				LMsg(0, "Lines joined with comma");
891
	    case 2:
855
				break;
892
	      LMsg(0, "Lines joined with blanks");
856
			}
893
	      break;
857
			break;
894
	    case 3:
858
		case '/':
895
	      LMsg(0, "Lines joined with comma");
859
			Search(1);
896
	      break;
860
			in_mark = 0;
897
	    }
861
			break;
898
	  break;
862
		case '?':
899
	case '/':
863
			Search(-1);
900
	  Search(1);
864
			in_mark = 0;
901
	  in_mark = 0;
865
			break;
902
	  break;
866
		case 'n':
903
	case '?':
867
			Search(0);
904
	  Search(-1);
868
			break;
905
	  in_mark = 0;
869
		case 'N':
906
	  break;
870
			markdata->isdir = -markdata->isdir;
907
	case 'n':
871
			Search(0);
908
	  Search(0);
872
			markdata->isdir = -markdata->isdir;
909
	  break;
873
			break;
910
	case 'N':
874
		case 'y':
911
	  markdata->isdir = -markdata->isdir;
875
		case 'Y':
912
	  Search(0);
876
			if (markdata->second == 0) {
913
	  markdata->isdir = -markdata->isdir;
877
				revto(linestart(cy), cy);
914
	  break;
878
				markdata->second++;
915
	case 'y':
879
				cx = markdata->x1 = markdata->cx;
916
	case 'Y':
880
				cy = markdata->y1 = markdata->cy;
917
	  if (markdata->second == 0)
881
			}
918
	    {
882
			if (--rep_cnt > 0)
919
	      revto(linestart(cy), cy);
883
				revto(cx, cy + rep_cnt);
920
	      markdata->second++;
884
			revto(lineend(markdata->cy), markdata->cy);
921
	      cx = markdata->x1 = markdata->cx;
885
			if (od == 'y')
922
	      cy = markdata->y1 = markdata->cy;
886
				break;
923
	    }
924
	  if (--rep_cnt > 0)
925
	    revto(cx, cy + rep_cnt);
926
	  revto(lineend(markdata->cy), markdata->cy);
927
	  if (od == 'y')
928
	    break;
929
	  /* FALLTHROUGH */
887
	  /* FALLTHROUGH */
930
	case 'W':
888
		case 'W':
931
	  if (od == 'W')
889
			if (od == 'W') {
932
	    {
890
				if (rep_cnt == 0)
933
	      if (rep_cnt == 0)
891
					rep_cnt = 1;
934
		rep_cnt = 1;
892
				if (!markdata->second) {
935
	      if (!markdata->second)
893
					nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD, 1);
936
		{
894
					revto(cx, cy);
937
		  nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD, 1);
895
					markdata->second++;
938
		  revto(cx, cy);
896
					cx = markdata->x1 = markdata->cx;
939
		  markdata->second++;
897
					cy = markdata->y1 = markdata->cy;
940
		  cx = markdata->x1 = markdata->cx;
898
				}
941
		  cy = markdata->y1 = markdata->cy;
899
				nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt);
942
		}
900
				revto(cx, cy);
943
	      nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt);
901
			}
944
	      revto(cx, cy);
902
			cx = markdata->cx;
945
	    }
903
			cy = markdata->cy;
946
	  cx = markdata->cx;
947
	  cy = markdata->cy;
948
	  /* FALLTHROUGH */
904
	  /* FALLTHROUGH */
949
	case 'A':
905
		case 'A':
950
	  if (od == 'A')
906
			if (od == 'A')
951
	    markdata->append_mode = 1;
907
				markdata->append_mode = 1;
952
	  /* FALLTHROUGH */
908
	  /* FALLTHROUGH */
953
	case '>':
909
		case '>':
954
	  if (od == '>')
910
			if (od == '>')
955
	    markdata->write_buffer = 1;
911
				markdata->write_buffer = 1;
956
	  /* FALLTHROUGH */
912
	  /* FALLTHROUGH */
957
	case ' ':
913
		case ' ':
958
	case '\r':
914
		case '\r':
959
	  if (!markdata->second)
915
			if (!markdata->second) {
960
	    {
916
				markdata->second++;
961
	      markdata->second++;
917
				markdata->x1 = cx;
962
	      markdata->x1 = cx;
918
				markdata->y1 = cy;
963
	      markdata->y1 = cy;
919
				revto(cx, cy);
964
	      revto(cx, cy);
920
				LMsg(0, "First mark set - Column %d Line %d", cx + 1, W2D(cy) + 1);
965
	      LMsg(0, "First mark set - Column %d Line %d", cx+1, W2D(cy)+1);
921
				break;
966
	      break;
922
			} else {
967
	    }
923
				int append_mode = markdata->append_mode;
968
	  else
924
				int write_buffer = markdata->write_buffer;
969
	    {
925
970
	      int append_mode = markdata->append_mode;
926
				x2 = cx;
971
	      int write_buffer = markdata->write_buffer;
927
				y2 = cy;
972
928
				newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */
973
	      x2 = cx;
929
				if (md_user->u_plop.buf && !append_mode)
974
	      y2 = cy;
930
					UserFreeCopyBuffer(md_user);
975
	      newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */
931
				yend = fore->w_height - 1;
976
	      if (md_user->u_plop.buf && !append_mode)
932
				if (fore->w_histheight - markdata->hist_offset < fore->w_height) {
977
		UserFreeCopyBuffer(md_user);
933
					markdata->second = 0;
978
	      yend = fore->w_height - 1;
934
					yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
979
	      if (fore->w_histheight - markdata->hist_offset < fore->w_height)
935
				}
980
		{
936
				if (newcopylen > 0) {
981
		  markdata->second = 0;
982
		  yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
983
		}
984
	      if (newcopylen > 0)
985
		{
986
		  /* the +3 below is for : cr + lf + \0 */
937
		  /* the +3 below is for : cr + lf + \0 */
987
		  if (md_user->u_plop.buf)
938
					if (md_user->u_plop.buf)
988
		    md_user->u_plop.buf = realloc(md_user->u_plop.buf,
939
						md_user->u_plop.buf = realloc(md_user->u_plop.buf, (unsigned)(md_user->u_plop.len + newcopylen + 3));
989
			(unsigned) (md_user->u_plop.len + newcopylen + 3));
940
					else {
990
		  else
941
						md_user->u_plop.len = 0;
991
		    {
942
						md_user->u_plop.buf = malloc((unsigned)(newcopylen + 3));
992
		      md_user->u_plop.len = 0;
943
					}
993
		      md_user->u_plop.buf = malloc((unsigned) (newcopylen + 3));
944
					if (!md_user->u_plop.buf) {
994
		    }
945
						MarkAbort();
995
		  if (!md_user->u_plop.buf)
946
						in_mark = 0;
996
		    {
947
						LMsg(0, "Not enough memory... Sorry.");
997
		      MarkAbort();
948
						md_user->u_plop.len = 0;
998
		      in_mark = 0;
949
						md_user->u_plop.buf = 0;
999
		      LMsg(0, "Not enough memory... Sorry.");
950
						break;
1000
		      md_user->u_plop.len = 0;
951
					}
1001
		      md_user->u_plop.buf = 0;
952
					if (append_mode) {
1002
		      break;
953
						switch (markdata->nonl) {
1003
		    }
1004
		  if (append_mode)
1005
		    {
1006
		      switch (markdata->nonl)
1007
			{
1008
			/*
954
			/*
1009
			 * this code defines, what glues lines together
955
			 * this code defines, what glues lines together
1010
			 */
956
			 */
1011
			case 0:
957
						case 0:
1012
			  if (join_with_cr)
958
							if (join_with_cr) {
1013
			    {
959
								md_user->u_plop.buf[md_user->u_plop.len] = '\r';
1014
			      md_user->u_plop.buf[md_user->u_plop.len] = '\r';
960
								md_user->u_plop.len++;
1015
			      md_user->u_plop.len++;
961
							}
1016
			    }
962
							md_user->u_plop.buf[md_user->u_plop.len] = '\n';
1017
			  md_user->u_plop.buf[md_user->u_plop.len] = '\n';
963
							md_user->u_plop.len++;
1018
			  md_user->u_plop.len++;
964
							break;
1019
			  break;
965
						case 1:
1020
			case 1:
966
							break;
1021
			  break;
967
						case 2:
1022
			case 2:
968
							md_user->u_plop.buf[md_user->u_plop.len] = ' ';
1023
			  md_user->u_plop.buf[md_user->u_plop.len] = ' ';
969
							md_user->u_plop.len++;
1024
			  md_user->u_plop.len++;
970
							break;
1025
			  break;
971
						case 3:
1026
			case 3:
972
							md_user->u_plop.buf[md_user->u_plop.len] = ',';
1027
			  md_user->u_plop.buf[md_user->u_plop.len] = ',';
973
							md_user->u_plop.len++;
1028
			  md_user->u_plop.len++;
974
							break;
1029
			  break;
975
						}
1030
			}
976
					}
1031
		    }
977
					md_user->u_plop.len += rem(markdata->x1,
1032
		  md_user->u_plop.len += rem(markdata->x1, markdata->y1, x2, y2,
978
					                           markdata->y1,
1033
		    markdata->hist_offset == fore->w_histheight,
979
					                           x2,
1034
		    md_user->u_plop.buf + md_user->u_plop.len, yend);
980
					                           y2,
981
					                           markdata->hist_offset == fore->w_histheight,
982
					                           md_user->u_plop.buf + md_user->u_plop.len,
983
					                           yend);
1035
#ifdef ENCODINGS
984
#ifdef ENCODINGS
1036
		  md_user->u_plop.enc = fore->w_encoding;
985
					md_user->u_plop.enc = fore->w_encoding;
1037
#endif
986
#endif
1038
		}
987
				}
1039
	      if (markdata->hist_offset != fore->w_histheight)
988
				if (markdata->hist_offset != fore->w_histheight) {
1040
		{
989
					LAY_CALL_UP(LRefreshAll(flayer, 0));
1041
		  LAY_CALL_UP(LRefreshAll(flayer, 0));
990
				}
1042
		}
991
				ExitOverlayPage();
1043
	      ExitOverlayPage();
992
				WindowChanged(fore, 'P');
1044
	      WindowChanged(fore, 'P');
993
1045
	      if (append_mode)
994
				if (append_mode)
1046
		LMsg(0, "Appended %d characters to buffer",
995
					LMsg(0, "Appended %d characters to buffer", newcopylen);
1047
		    newcopylen);
996
				else
1048
	      else
997
					LMsg(0, "Copied %d characters into buffer", md_user->u_plop.len);
1049
		LMsg(0, "Copied %d characters into buffer", md_user->u_plop.len);
998
1050
	      if (write_buffer)
999
				if (write_buffer)
1051
		WriteFile(md_user, (char *)0, DUMP_EXCHANGE);
1000
					WriteFile(md_user, (char *)0, DUMP_EXCHANGE);
1052
	      in_mark = 0;
1001
				in_mark = 0;
1053
	      break;
1002
				break;
1054
	    }
1003
			}
1055
1056
	case 0222:
1057
	  if (flayer->l_mouseevent.start)
1058
	    {
1059
	      int button = flayer->l_mouseevent.buffer[0];
1060
	      if (button == 'a')
1061
		{
1062
		  /* Scroll down */
1063
		  od = 'j';
1064
		}
1065
	      else if (button == '`')
1066
		{
1067
		  /* Scroll up */
1068
		  od = 'k';
1069
		}
1070
	      else if (button == ' ')
1071
		{
1072
		  /* Left click */
1073
		  cx = flayer->l_mouseevent.buffer[1];
1074
		  cy = D2W(flayer->l_mouseevent.buffer[2]);
1075
		  revto(cx, cy);
1076
		  od = ' ';
1077
		}
1078
	      else
1079
		od = 0;
1080
	      LayProcessMouseSwitch(flayer, 0);
1081
	      if (od)
1082
		goto processchar;
1083
	    }
1084
	  else
1085
	    LayProcessMouseSwitch(flayer, 1);
1086
	  break;
1087
1004
1088
	default:
1005
		case 0222:
1089
	  MarkAbort();
1006
			if (flayer->l_mouseevent.start) {
1090
	  LMsg(0, "Copy mode aborted");
1007
				int button = flayer->l_mouseevent.buffer[0];
1091
	  in_mark = 0;
1008
				if (button == 'a') {
1092
	  break;
1009
					/* Scroll down */
1093
	}
1010
					od = 'j';
1094
      if (in_mark)	/* markdata may be freed */
1011
				} else if (button == '`') {
1095
        markdata->rep_cnt = 0;
1012
					/* Scroll up */
1096
    }
1013
					od = 'k';
1097
  if (in_mark)
1014
				} else if (button == ' ') {
1098
    {
1015
					/* Left click */
1099
      flayer->l_x = markdata->cx;
1016
					cx = flayer->l_mouseevent.buffer[1];
1100
      flayer->l_y = W2D(markdata->cy);
1017
					cy = D2W(flayer->l_mouseevent.buffer[2]);
1101
    }
1018
					revto(cx, cy);
1102
  *inbufp = pt;
1019
					od = ' ';
1103
  *inlenp = inlen;
1020
				} else
1021
					od = 0;
1022
				LayProcessMouseSwitch(flayer, 0);
1023
				if (od)
1024
					goto processchar;
1025
			} else
1026
				LayProcessMouseSwitch(flayer, 1);
1027
			break;
1028
1029
		default:
1030
			MarkAbort();
1031
			LMsg(0, "Copy mode aborted");
1032
			in_mark = 0;
1033
			break;
1034
		}
1035
		if (in_mark)	/* markdata may be freed */
1036
			markdata->rep_cnt = 0;
1037
	}
1038
	if (in_mark) {
1039
		flayer->l_x = markdata->cx;
1040
		flayer->l_y = W2D(markdata->cy);
1041
	}
1042
	*inbufp = pt;
1043
	*inlenp = inlen;
1104
}
1044
}
1105
1045
1106
void revto(tx, ty)
1046
void
1107
int tx, ty;
1047
revto(int tx, int ty)
1108
{
1048
{
1109
  revto_line(tx, ty, -1);
1049
	revto_line(tx, ty, -1);
1110
}
1050
}
1111
1051
1112
/* tx, ty: WINDOW,  line: DISPLAY */
1052
/* tx, ty: WINDOW,  line: DISPLAY */
1113
void revto_line(tx, ty, line)
1053
void
1114
int tx, ty, line;
1054
revto_line(int tx, int ty, int line)
1115
{
1055
{
1116
  int fx, fy;
1056
	int fx, fy;
1117
  int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0;
1057
	int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0;
1118
  int ystart = 0, yend = fore->w_height-1;
1058
	int ystart = 0, yend = fore->w_height - 1;
1119
  int i, ry;
1059
	int i, ry;
1120
  unsigned char *wi;
1060
	unsigned char *wi;
1121
  struct mline *ml;
1061
	struct mline *ml;
1122
  struct mchar mc;
1062
	struct mchar mc;
1123
1063
1124
  if (tx < 0)
1064
	if (tx < 0)
1125
    tx = 0;
1065
		tx = 0;
1126
  else if (tx > fore->w_width - 1)
1066
	else if (tx > fore->w_width - 1)
1127
    tx = fore->w_width -1;
1067
		tx = fore->w_width - 1;
1128
  if (ty < fore->w_histheight - fore->w_scrollback_height)
1068
	if (ty < fore->w_histheight - fore->w_scrollback_height)
1129
    ty = fore->w_histheight - fore->w_scrollback_height;
1069
		ty = fore->w_histheight - fore->w_scrollback_height;
1130
  else if (ty > fore->w_histheight + fore->w_height - 1)
1070
	else if (ty > fore->w_histheight + fore->w_height - 1)
1131
    ty = fore->w_histheight + fore->w_height - 1;
1071
		ty = fore->w_histheight + fore->w_height - 1;
1132
1072
1133
  fx = markdata->cx; fy = markdata->cy;
1073
	fx = markdata->cx;
1074
	fy = markdata->cy;
1134
1075
1135
#ifdef DW_CHARS
1076
#ifdef DW_CHARS
1136
  /* don't just move inside of a kanji, the user wants to see something */
1077
	/* don't just move inside of a kanji, the user wants to see something */
1137
  ml = WIN(ty);
1078
	ml = WIN(ty);
1138
  if (ty == fy && fx + 1 == tx && dw_right(ml, tx, fore->w_encoding) && tx < D_width - 1)
1079
	if (ty == fy && fx + 1 == tx && dw_right(ml, tx, fore->w_encoding) && tx < D_width - 1)
1139
    tx++;
1080
		tx++;
1140
  if (ty == fy && fx - 1 == tx && dw_right(ml, fx, fore->w_encoding) && tx)
1081
	if (ty == fy && fx - 1 == tx && dw_right(ml, fx, fore->w_encoding) && tx)
1141
    tx--;
1082
		tx--;
1142
#endif
1083
#endif
1143
1084
1144
  markdata->cx = tx; markdata->cy = ty;
1085
	markdata->cx = tx;
1086
	markdata->cy = ty;
1145
1087
1146
  /*
1088
  /*
1147
   * if we go to a position that is currently offscreen
1089
   * if we go to a position that is currently offscreen
1148
   * then scroll the screen
1090
   * then scroll the screen
1149
   */
1091
   */
1150
  i = 0;
1092
	i = 0;
1151
  if (line >= 0 && line < fore->w_height)
1093
1152
    i = W2D(ty) - line;
1094
	if (line >= 0 && line < fore->w_height)
1153
  else if (ty < markdata->hist_offset)
1095
		i = W2D(ty) - line;
1154
    i = ty - markdata->hist_offset;
1096
	else if (ty < markdata->hist_offset)
1155
  else if (ty > markdata->hist_offset + (fore->w_height - 1))
1097
		i = ty - markdata->hist_offset;
1156
    i = ty - markdata->hist_offset - (fore->w_height - 1);
1098
	else if (ty > markdata->hist_offset + (fore->w_height - 1))
1157
  if (i > 0)
1099
		i = ty - markdata->hist_offset - (fore->w_height - 1);
1158
    yend -= MarkScrollUpDisplay(i);
1100
1159
  else if (i < 0)
1101
	if (i > 0)
1160
    ystart += MarkScrollDownDisplay(-i);
1102
		yend -= MarkScrollUpDisplay(i);
1161
1103
	else if (i < 0)
1162
  if (markdata->second == 0)
1104
		ystart += MarkScrollDownDisplay(-i);
1163
    {
1105
1164
      flayer->l_x = tx;
1106
	if (markdata->second == 0) {
1165
      flayer->l_y = W2D(ty);
1107
		flayer->l_x = tx;
1166
      LGotoPos(flayer, tx, W2D(ty));
1108
		flayer->l_y = W2D(ty);
1167
      return;
1109
		LGotoPos(flayer, tx, W2D(ty));
1168
    }
1110
		return;
1169
1111
	}
1170
  qq = markdata->x1 + markdata->y1 * fore->w_width;
1112
1171
  ff = fx + fy * fore->w_width; /* "from" offset in WIN coords */
1113
	qq = markdata->x1 + markdata->y1 * fore->w_width;
1172
  tt = tx + ty * fore->w_width; /* "to" offset  in WIN coords*/
1114
	ff = fx + fy * fore->w_width; /* "from" offset in WIN coords */
1173
1115
	tt = tx + ty * fore->w_width; /* "to" offset  in WIN coords*/
1174
  if (ff > tt)
1116
1175
    {
1117
	if (ff > tt) {
1176
      st = tt; en = ff;
1118
		st = tt;
1177
      x = tx; y = ty;
1119
		en = ff;
1178
    }
1120
		x = tx;
1179
  else
1121
		y = ty;
1180
    {
1122
	} else {
1181
      st = ff; en = tt;
1123
		st = ff;
1182
      x = fx; y = fy;
1124
		en = tt;
1183
    }
1125
		x = fx;
1184
  if (st > qq)
1126
		y = fy;
1185
    {
1127
	}
1186
      st++;
1128
1187
      x++;
1129
	if (st > qq) {
1188
    }
1130
		st++;
1189
  if (en < qq)
1131
		x++;
1190
    en--;
1191
  if (tt > qq)
1192
    {
1193
      revst = qq; reven = tt;
1194
    }
1195
  else
1196
    {
1197
      revst = tt; reven = qq;
1198
    }
1199
  ry = y - markdata->hist_offset;
1200
  if (ry < ystart)
1201
    {
1202
      y += (ystart - ry);
1203
      x = 0;
1204
      st = y * fore->w_width;
1205
      ry = ystart;
1206
    }
1207
  ml = WIN(y);
1208
  for (t = st; t <= en; t++, x++)
1209
    {
1210
      if (x >= fore->w_width)
1211
	{
1212
	  x = 0;
1213
	  y++, ry++;
1214
	  ml = WIN(y);
1215
	}
1216
      if (ry > yend)
1217
	break;
1218
      if (t == st || x == 0)
1219
	{
1220
	  wi = ml->image + fore->w_width;
1221
	  for (ce = fore->w_width; ce >= 0; ce--, wi--)
1222
	    if (*wi != ' ')
1223
	      break;
1224
	}
1132
	}
1225
      if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar)
1133
1226
	{
1134
	if (en < qq)
1135
		en--;
1136
1137
	if (tt > qq) {
1138
		revst = qq;
1139
		reven = tt;
1140
	} else {
1141
		revst = tt;
1142
		reven = qq;
1143
	}
1144
	ry = y - markdata->hist_offset;
1145
1146
	if (ry < ystart) {
1147
		y += (ystart - ry);
1148
		x = 0;
1149
		st = y * fore->w_width;
1150
		ry = ystart;
1151
	}
1152
	ml = WIN(y);
1153
1154
	for (t = st; t <= en; t++, x++) {
1155
		if (x >= fore->w_width) {
1156
			x = 0;
1157
			y++, ry++;
1158
			ml = WIN(y);
1159
		}
1160
		if (ry > yend)
1161
			break;
1162
		if (t == st || x == 0) {
1163
			wi = ml->image + fore->w_width;
1164
			for (ce = fore->w_width; ce >= 0; ce--, wi--)
1165
				if (*wi != ' ')
1166
					break;
1167
		}
1168
1169
		if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar) {
1227
#ifdef DW_CHARS
1170
#ifdef DW_CHARS
1228
	  if (dw_right(ml, x, fore->w_encoding))
1171
			if (dw_right(ml, x, fore->w_encoding)) {
1229
	      {
1172
				if (t == revst)
1230
		if (t == revst)
1173
					revst--;
1231
		  revst--;
1174
				t--;
1232
	        t--;
1175
				x--;
1233
		x--;
1176
			}
1234
	      }
1235
#endif
1177
#endif
1236
	  if (t >= revst && t <= reven)
1178
			if (t >= revst && t <= reven) {
1237
	    {
1179
				mc = mchar_so;
1238
	      mc = mchar_so;
1239
#ifdef FONT
1180
#ifdef FONT
1240
	      if (pastefont)
1181
				if (pastefont) {
1241
		{
1182
					mc.font = ml->font[x];
1242
		  mc.font = ml->font[x];
1183
					mc.fontx = ml->fontx[x];
1243
		  mc.fontx = ml->fontx[x];
1184
				}
1244
		}
1245
#endif
1185
#endif
1246
	      mc.image = ml->image[x];
1186
				mc.image = ml->image[x];
1247
	    }
1187
			} else
1248
	  else
1188
				copy_mline2mchar(&mc, ml, x);
1249
	    copy_mline2mchar(&mc, ml, x);
1250
#ifdef DW_CHARS
1189
#ifdef DW_CHARS
1251
	  if (dw_left(ml, x, fore->w_encoding))
1190
			if (dw_left(ml, x, fore->w_encoding)) {
1252
	    {
1191
				mc.mbcs = ml->image[x + 1];
1253
	      mc.mbcs = ml->image[x + 1];
1192
				LPutChar(flayer, &mc, x, W2D(y));
1254
	      LPutChar(flayer, &mc, x, W2D(y));
1193
				t++;
1255
	      t++;
1194
			}
1256
	    }
1257
#endif
1195
#endif
1258
	  LPutChar(flayer, &mc, x, W2D(y));
1196
			LPutChar(flayer, &mc, x, W2D(y));
1259
#ifdef DW_CHARS
1197
#ifdef DW_CHARS
1260
	  if (dw_left(ml, x, fore->w_encoding))
1198
			if (dw_left(ml, x, fore->w_encoding))
1261
	    x++;
1199
				x++;
1262
#endif
1200
#endif
1201
		}
1263
	}
1202
	}
1264
    }
1203
	flayer->l_x = tx;
1265
  flayer->l_x = tx;
1204
	flayer->l_y = W2D(ty);
1266
  flayer->l_y = W2D(ty);
1205
	LGotoPos(flayer, tx, W2D(ty));
1267
  LGotoPos(flayer, tx, W2D(ty));
1268
}
1206
}
1269
1207
1270
static void
1208
static void
1271
MarkAbort()
1209
MarkAbort()
1272
{
1210
{
1273
  int yend, redisp;
1211
	int yend, redisp;
1274
1212
1275
  debug("MarkAbort\n");
1213
	debug("MarkAbort\n");
1276
  markdata = (struct markdata *)flayer->l_data;
1214
	markdata = (struct markdata *)flayer->l_data;
1277
  fore = markdata->md_window;
1215
	fore = markdata->md_window;
1278
  yend = fore->w_height - 1;
1216
	yend = fore->w_height - 1;
1279
  redisp = markdata->second;
1217
	redisp = markdata->second;
1280
  if (fore->w_histheight - markdata->hist_offset < fore->w_height)
1218
	if (fore->w_histheight - markdata->hist_offset < fore->w_height) {
1281
    {
1219
		markdata->second = 0;
1282
      markdata->second = 0;
1220
		yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
1283
      yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
1221
	}
1284
    }
1222
	if (markdata->hist_offset != fore->w_histheight) {
1285
  if (markdata->hist_offset != fore->w_histheight)
1223
		LAY_CALL_UP(LRefreshAll(flayer, 0));
1286
    {
1224
	} else {
1287
      LAY_CALL_UP(LRefreshAll(flayer, 0));
1225
		rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend);
1288
    }
1226
	}
1289
  else
1227
	ExitOverlayPage();
1290
    {
1228
	WindowChanged(fore, 'P');
1291
      rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend);
1292
    }
1293
  ExitOverlayPage();
1294
  WindowChanged(fore, 'P');
1295
}
1229
}
1296
1230
1297
1298
static void
1231
static void
1299
MarkRedisplayLine(y, xs, xe, isblank)
1232
MarkRedisplayLine(int y, int xs, int xe, int isblank) /* NOTE: y is in DISPLAY coords system! */
1300
int y;	/* NOTE: y is in DISPLAY coords system! */
1301
int xs, xe;
1302
int isblank;
1303
{
1233
{
1304
  int wy, x, i, rm;
1234
	int wy, x, i, rm;
1305
  int sta, sto, cp;	/* NOTE: these 3 are in WINDOW coords system */
1235
	int sta, sto, cp;                                 /* NOTE: these 3 are in WINDOW coords system */
1306
  unsigned char *wi;
1236
	unsigned char *wi;
1307
  struct mline *ml;
1237
	struct mline *ml;
1308
  struct mchar mchar_marked;
1238
	struct mchar mchar_marked;
1309
1239
1310
  if (y < 0)	/* No special full page handling */
1240
	if (y < 0)	/* No special full page handling */
1311
    return;
1241
		return;
1312
1242
1313
  markdata = (struct markdata *)flayer->l_data;
1243
	markdata = (struct markdata *)flayer->l_data;
1314
  fore = markdata->md_window;
1244
	fore = markdata->md_window;
1315
1245
1316
  mchar_marked = mchar_so;
1246
	mchar_marked = mchar_so;
1317
1247
1318
  wy = D2W(y);
1248
	wy = D2W(y);
1319
  ml = WIN(wy);
1249
	ml = WIN(wy);
1320
1250
1321
  if (markdata->second == 0)
1251
	if (markdata->second == 0) {
1322
    {
1252
		if (dw_right(ml, xs, fore->w_encoding) && xs > 0)
1323
      if (dw_right(ml, xs, fore->w_encoding) && xs > 0)
1253
			xs--;
1324
	xs--;
1254
		if (dw_left(ml, xe, fore->w_encoding) && xe < fore->w_width - 1)
1325
      if (dw_left(ml, xe, fore->w_encoding) && xe < fore->w_width - 1)
1255
			xe++;
1326
	xe++;
1256
		if (xs == 0 && y > 0 && wy > 0 && WIN(wy - 1)->image[flayer->l_width] == 0)
1327
      if (xs == 0 && y > 0 && wy > 0 && WIN(wy - 1)->image[flayer->l_width] == 0)
1257
			LCDisplayLineWrap(flayer, ml, y, xs, xe, isblank);
1328
        LCDisplayLineWrap(flayer, ml, y, xs, xe, isblank);
1258
		else
1329
      else
1259
			LCDisplayLine(flayer, ml, y, xs, xe, isblank);
1330
        LCDisplayLine(flayer, ml, y, xs, xe, isblank);
1260
		return;
1331
      return;
1261
	}
1332
    }
1262
1333
1263
	sta = markdata->y1 * fore->w_width + markdata->x1;
1334
  sta = markdata->y1 * fore->w_width + markdata->x1;
1264
	sto = markdata->cy * fore->w_width + markdata->cx;
1335
  sto = markdata->cy * fore->w_width + markdata->cx;
1265
	if (sta > sto) {
1336
  if (sta > sto)
1266
		i = sta;
1337
    {
1267
		sta = sto;
1338
      i=sta; sta=sto; sto=i;
1268
		sto = i;
1339
    }
1269
	}
1340
  cp = wy * fore->w_width + xs;
1270
	cp = wy * fore->w_width + xs;
1341
1271
1342
  rm = markdata->right_mar;
1272
	rm = markdata->right_mar;
1343
  for (x = fore->w_width, wi = ml->image + fore->w_width; x >= 0; x--, wi--)
1273
	for (x = fore->w_width, wi = ml->image + fore->w_width; x >= 0; x--, wi--)
1344
    if (*wi != ' ')
1274
		if (*wi != ' ')
1345
      break;
1275
			break;
1346
  if (x < rm)
1276
	if (x < rm)
1347
    rm = x;
1277
		rm = x;
1348
1278
1349
  for (x = xs; x <= xe; x++, cp++)
1279
	for (x = xs; x <= xe; x++, cp++)
1350
    if (cp >= sta && x >= markdata->left_mar)
1280
		if (cp >= sta && x >= markdata->left_mar)
1351
      break;
1281
			break;
1352
#ifdef DW_CHARS
1282
#ifdef DW_CHARS
1353
  if (dw_right(ml, x, fore->w_encoding))
1283
	if (dw_right(ml, x, fore->w_encoding))
1354
    x--;
1284
		x--;
1355
#endif
1285
#endif
1356
  if (x > xs)
1286
	if (x > xs)
1357
    LCDisplayLine(flayer, ml, y, xs, x - 1, isblank);
1287
		LCDisplayLine(flayer, ml, y, xs, x - 1, isblank);
1358
  for (; x <= xe; x++, cp++)
1288
	for (; x <= xe; x++, cp++) {
1359
    {
1289
		if (cp > sto || x > rm)
1360
      if (cp > sto || x > rm)
1290
			break;
1361
	break;
1362
#ifdef FONT
1291
#ifdef FONT
1363
      if (pastefont)
1292
		if (pastefont) {
1364
	{
1293
			mchar_marked.font = ml->font[x];
1365
	  mchar_marked.font = ml->font[x];
1294
			mchar_marked.fontx = ml->fontx[x];
1366
	  mchar_marked.fontx = ml->fontx[x];
1295
		}
1367
	}
1368
#endif
1296
#endif
1369
      mchar_marked.image = ml->image[x];
1297
		mchar_marked.image = ml->image[x];
1370
#ifdef DW_CHARS
1298
#ifdef DW_CHARS
1371
      mchar_marked.mbcs = 0;
1299
		mchar_marked.mbcs = 0;
1372
      if (dw_left(ml, x, fore->w_encoding))
1300
		if (dw_left(ml, x, fore->w_encoding)) {
1373
	{
1301
			mchar_marked.mbcs = ml->image[x + 1];
1374
	  mchar_marked.mbcs = ml->image[x + 1];
1302
			cp++;
1375
	  cp++;
1303
		}
1376
	}
1377
#endif
1304
#endif
1378
      LPutChar(flayer, &mchar_marked, x, y);
1305
		LPutChar(flayer, &mchar_marked, x, y);
1379
#ifdef DW_CHARS
1306
#ifdef DW_CHARS
1380
      if (dw_left(ml, x, fore->w_encoding))
1307
		if (dw_left(ml, x, fore->w_encoding))
1381
	x++;
1308
			x++;
1382
#endif
1309
#endif
1383
    }
1310
	}
1384
  if (x <= xe)
1311
	if (x <= xe)
1385
    LCDisplayLine(flayer, ml, y, x, xe, isblank);
1312
		LCDisplayLine(flayer, ml, y, x, xe, isblank);
1386
}
1313
}
1387
1314
1388
1389
/*
1315
/*
1390
 * This ugly routine is to speed up GotoPos()
1316
 * This ugly routine is to speed up GotoPos()
1391
 */
1317
 */
1392
static int
1318
static int
1393
MarkRewrite(ry, xs, xe, rend, doit)
1319
MarkRewrite(int ry, int xs, int xe, struct mchar *rend, int doit)
1394
int ry, xs, xe, doit;
1395
struct mchar *rend;
1396
{
1320
{
1397
  int dx, x, y, st, en, t, rm;
1321
	int dx, x, y, st, en, t, rm;
1398
  unsigned char *i;
1322
	unsigned char *i;
1399
  struct mline *ml;
1323
	struct mline *ml;
1400
  struct mchar mchar_marked;
1324
	struct mchar mchar_marked;
1401
1325
1402
  mchar_marked = mchar_so;
1326
	mchar_marked = mchar_so;
1403
1327
1404
  debug3("MarkRewrite %d, %d-%d\n", ry, xs, xe);
1328
	debug3("MarkRewrite %d, %d-%d\n", ry, xs, xe);
1405
  markdata = (struct markdata *)flayer->l_data;
1329
	markdata = (struct markdata *)flayer->l_data;
1406
  fore = markdata->md_window;
1330
	fore = markdata->md_window;
1407
  y = D2W(ry);
1331
	y = D2W(ry);
1408
  ml = WIN(y);
1332
	ml = WIN(y);
1409
#ifdef UTF8
1333
#ifdef UTF8
1410
  if (fore->w_encoding && fore->w_encoding != UTF8 && D_encoding == UTF8 && ContainsSpecialDeffont(ml, xs, xe, fore->w_encoding))
1334
	if (fore->w_encoding && fore->w_encoding != UTF8 && D_encoding == UTF8 && ContainsSpecialDeffont(ml, xs, xe, fore->w_encoding))
1411
    return EXPENSIVE;
1335
		return EXPENSIVE;
1412
#endif
1336
#endif
1413
  dx = xe - xs + 1;
1337
	dx = xe - xs + 1;
1414
  if (doit)
1338
	if (doit) {
1415
    {
1339
		i = ml->image + xs;
1416
      i = ml->image + xs;
1340
		while (dx--)
1417
      while (dx--)
1341
			PUTCHAR(*i++);
1418
        PUTCHAR(*i++);
1342
		return 0;
1419
      return 0;
1343
	}
1420
    }
1344
1421
1345
	if (markdata->second == 0)
1422
  if (markdata->second == 0)
1346
		st = en = -1;
1423
    st = en = -1;
1347
	else {
1424
  else
1348
		st = markdata->y1 * fore->w_width + markdata->x1;
1425
    {
1349
		en = markdata->cy * fore->w_width + markdata->cx;
1426
      st = markdata->y1 * fore->w_width + markdata->x1;
1350
		if (st > en) {
1427
      en = markdata->cy * fore->w_width + markdata->cx;
1351
			t = st;
1428
      if (st > en)
1352
			st = en;
1429
        {
1353
			en = t;
1430
          t = st; st = en; en = t;
1354
		}
1431
        }
1355
	}
1432
    }
1356
	t = y * fore->w_width + xs;
1433
  t = y * fore->w_width + xs;
1357
	for (rm = fore->w_width, i = ml->image + fore->w_width; rm >= 0; rm--)
1434
  for (rm = fore->w_width, i = ml->image + fore->w_width; rm >= 0; rm--)
1358
		if (*i-- != ' ')
1435
    if (*i-- != ' ')
1359
			break;
1436
      break;
1360
	if (rm > markdata->right_mar)
1437
  if (rm > markdata->right_mar)
1361
		rm = markdata->right_mar;
1438
    rm = markdata->right_mar;
1362
	x = xs;
1439
  x = xs;
1363
	while (dx--) {
1440
  while (dx--)
1364
		if (t >= st && t <= en && x >= markdata->left_mar && x <= rm) {
1441
    {
1442
      if (t >= st && t <= en && x >= markdata->left_mar && x <= rm)
1443
        {
1444
#ifdef FONT
1365
#ifdef FONT
1445
	  if (pastefont)
1366
			if (pastefont) {
1446
	    {
1367
				mchar_marked.font = ml->font[x];
1447
	      mchar_marked.font = ml->font[x];
1368
				mchar_marked.fontx = ml->fontx[x];
1448
	      mchar_marked.fontx = ml->fontx[x];
1369
			}
1449
	    }
1450
#endif
1370
#endif
1451
	  rend->image = mchar_marked.image;
1371
			rend->image = mchar_marked.image;
1452
	  if (!cmp_mchar(rend, &mchar_marked))
1372
			if (!cmp_mchar(rend, &mchar_marked))
1453
	    return EXPENSIVE;
1373
				return EXPENSIVE;
1454
        }
1374
		} else {
1455
      else
1375
			rend->image = ml->image[x];
1456
        {
1376
			if (!cmp_mchar_mline(rend, ml, x))
1457
	  rend->image = ml->image[x];
1377
				return EXPENSIVE;
1458
	  if (!cmp_mchar_mline(rend, ml, x))
1378
		}
1459
	    return EXPENSIVE;
1379
		x++;
1460
        }
1380
	}
1461
      x++;
1381
	return xe - xs + 1;
1462
    }
1463
  return xe - xs + 1;
1464
}
1382
}
1465
1383
1466
1467
/*
1384
/*
1468
 * scroll the screen contents up/down.
1385
 * scroll the screen contents up/down.
1469
 */
1386
 */
1470
static int MarkScrollUpDisplay(n)
1387
static int
1471
int n;
1388
MarkScrollUpDisplay(int n)
1472
{
1389
{
1473
  int i;
1390
	int i;
1474
1391
1475
  debug1("MarkScrollUpDisplay(%d)\n", n);
1392
	debug1("MarkScrollUpDisplay(%d)\n", n);
1476
  if (n <= 0)
1393
	if (n <= 0)
1477
    return 0;
1394
		return 0;
1478
  if (n > fore->w_histheight - markdata->hist_offset)
1395
	if (n > fore->w_histheight - markdata->hist_offset)
1479
    n = fore->w_histheight - markdata->hist_offset;
1396
		n = fore->w_histheight - markdata->hist_offset;
1480
  markdata->hist_offset += n;
1397
1481
  i = (n < flayer->l_height) ? n : (flayer->l_height);
1398
	markdata->hist_offset += n;
1482
  LScrollV(flayer, i, 0, flayer->l_height - 1, 0);
1399
	i = (n < flayer->l_height) ? n : (flayer->l_height);
1483
  while (i-- > 0)
1400
	LScrollV(flayer, i, 0, flayer->l_height - 1, 0);
1484
    MarkRedisplayLine(flayer->l_height - i - 1, 0, flayer->l_width - 1, 1);
1401
	while (i-- > 0)
1485
  return n;
1402
		MarkRedisplayLine(flayer->l_height - i - 1, 0, flayer->l_width - 1, 1);
1403
	return n;
1486
}
1404
}
1487
1405
1488
static int
1406
static int
1489
MarkScrollDownDisplay(n)
1407
MarkScrollDownDisplay(int n)
1490
int n;
1491
{
1408
{
1492
  int i;
1409
	int i;
1493
1410
1494
  debug1("MarkScrollDownDisplay(%d)\n", n);
1411
	debug1("MarkScrollDownDisplay(%d)\n", n);
1495
  if (n <= 0)
1412
	if (n <= 0)
1496
    return 0;
1413
		return 0;
1497
  if (n > markdata->hist_offset)
1414
	if (n > markdata->hist_offset)
1498
    n = markdata->hist_offset;
1415
		n = markdata->hist_offset;
1499
  markdata->hist_offset -= n;
1416
	markdata->hist_offset -= n;
1500
  i = (n < flayer->l_height) ? n : (flayer->l_height);
1417
	i = (n < flayer->l_height) ? n : (flayer->l_height);
1501
  LScrollV(flayer, -i, 0, fore->w_height - 1, 0);
1418
	LScrollV(flayer, -i, 0, fore->w_height - 1, 0);
1502
  while (i-- > 0)
1419
	while (i-- > 0)
1503
    MarkRedisplayLine(i, 0, flayer->l_width - 1, 1);
1420
		MarkRedisplayLine(i, 0, flayer->l_width - 1, 1);
1504
  return n;
1421
	return n;
1505
}
1422
}
1506
1423
1507
void
1424
void
1508
MakePaster(pa, buf, len, bufiscopy)
1425
MakePaster(struct paster *pa, char *buf, int len, int bufiscopy)
1509
struct paster *pa;
1510
char *buf;
1511
int len;
1512
int bufiscopy;
1513
{
1426
{
1514
  FreePaster(pa);
1427
	FreePaster(pa);
1515
  pa->pa_pasteptr = buf;
1428
	pa->pa_pasteptr = buf;
1516
  pa->pa_pastelen = len;
1429
	pa->pa_pastelen = len;
1517
  if (bufiscopy)
1430
	if (bufiscopy)
1518
    pa->pa_pastebuf = buf;
1431
		pa->pa_pastebuf = buf;
1519
  pa->pa_pastelayer = flayer;
1432
	pa->pa_pastelayer = flayer;
1520
  DoProcess(Layer2Window(flayer), &pa->pa_pasteptr, &pa->pa_pastelen, pa);
1433
	DoProcess(Layer2Window(flayer), &pa->pa_pasteptr, &pa->pa_pastelen, pa);
1521
}
1434
}
1522
1435
1523
void
1436
void
1524
FreePaster(pa)
1437
FreePaster(struct paster *pa)
1525
struct paster *pa;
1526
{
1438
{
1527
  if (pa->pa_pastebuf)
1439
	if (pa->pa_pastebuf)
1528
    free(pa->pa_pastebuf);
1440
		free(pa->pa_pastebuf);
1529
  pa->pa_pastebuf = 0;
1441
	pa->pa_pastebuf = 0;
1530
  pa->pa_pasteptr = 0;
1442
	pa->pa_pasteptr = 0;
1531
  pa->pa_pastelen = 0;
1443
	pa->pa_pastelen = 0;
1532
  pa->pa_pastelayer = 0;
1444
	pa->pa_pastelayer = 0;
1533
  evdeq(&pa->pa_slowev);
1445
	evdeq(&pa->pa_slowev);
1534
}
1446
}
1535
1447
1536
#endif /* COPY_PASTE */
1448
#endif /* COPY_PASTE */
(-)screen.orig/misc.c (-4 / +1 lines)
Lines 378-386 Link Here
378
    f = rl.rlim_max;
378
    f = rl.rlim_max;
379
  else
379
  else
380
#endif /* SVR4 */
380
#endif /* SVR4 */
381
#ifdef _SC_OPEN_MAX
381
#if defined(SYSV) && defined(NOFILE) && !defined(ISC)
382
  f = sysconf(_SC_OPEN_MAX);
383
#elif defined(SYSV) && defined(NOFILE) && !defined(ISC)
384
  f = NOFILE;
382
  f = NOFILE;
385
  while (--f > 2)
383
  while (--f > 2)
386
    if (f != except)
384
    if (f != except)
Lines 437-443 Link Here
437
    return 1;
435
    return 1;
438
  Usersigcld = signal(SIGCHLD, SIG_DFL);
436
  Usersigcld = signal(SIGCHLD, SIG_DFL);
439
  debug("UserContext: forking.\n");
437
  debug("UserContext: forking.\n");
440
  fflush(NULL);
441
  switch (UserPID = fork())
438
  switch (UserPID = fork())
442
    {
439
    {
443
    case -1:
440
    case -1:
(-)screen.orig/NEWS.3.5 (-1 / +1 lines)
Lines 27-33 Link Here
27
  Please run the 'newsyntax' script on your old screenrc files!
27
  Please run the 'newsyntax' script on your old screenrc files!
28
28
29
* Emacs style isearch added to copy mode. Try ^A ESC ^R screen ^R ^R
29
* Emacs style isearch added to copy mode. Try ^A ESC ^R screen ^R ^R
30
  to locate the last three occurences of the word 'screen' in the
30
  to locate the last three occurrences of the word 'screen' in the
31
  history buffer.
31
  history buffer.
32
32
33
* New command 'silence'. Alarms the user whenever there was inactivity
33
* New command 'silence'. Alarms the user whenever there was inactivity
(-)screen.orig/osdef.h.in (-1 / +4 lines)
Lines 95-100 Link Here
95
extern int   setegid __P((int));
95
extern int   setegid __P((int));
96
#endif
96
#endif
97
97
98
extern char *crypt __P((char *, char *));
99
extern int   putenv __P((char *));
100
98
extern int   tgetent __P((char *, char *));
101
extern int   tgetent __P((char *, char *));
99
extern char *tgetstr __P((char *, char **));
102
extern char *tgetstr __P((char *, char **));
100
extern int   tgetnum __P((char *));
103
extern int   tgetnum __P((char *));
Lines 108-114 Link Here
108
extern int   setpgid __P((int, int));
111
extern int   setpgid __P((int, int));
109
extern int   tcsetpgrp __P((int, int));
112
extern int   tcsetpgrp __P((int, int));
110
#endif
113
#endif
111
extern int   ioctl __P((int, int, char *));
114
extern int   ioctl __P((int, unsigned long, char *));
112
115
113
extern int   kill __P((int, int));
116
extern int   kill __P((int, int));
114
117
(-)screen.orig/osdef.sh (-1 lines)
Lines 27-33 Link Here
27
#ifdef linux
27
#ifdef linux
28
#include <string.h>
28
#include <string.h>
29
#include <stdlib.h>
29
#include <stdlib.h>
30
#include <unistd.h>
31
#endif
30
#endif
32
#include <sys/socket.h>
31
#include <sys/socket.h>
33
#ifndef NOSYSLOG
32
#ifndef NOSYSLOG
(-)screen.orig/os.h (-1 / +1 lines)
Lines 281-287 Link Here
281
#   ifdef _PATH_UTMP
281
#   ifdef _PATH_UTMP
282
#    define UTMPFILE	_PATH_UTMP
282
#    define UTMPFILE	_PATH_UTMP
283
#   else
283
#   else
284
#    define UTMPFILE	"/var/run/utmp"
284
#    define UTMPFILE	"/etc/utmp"
285
#   endif /* _PATH_UTMP */
285
#   endif /* _PATH_UTMP */
286
#  endif
286
#  endif
287
# endif
287
# endif
(-)screen.orig/patchlevel.h (-2 / +2 lines)
Lines 532-538 Link Here
532
532
533
#define ORIGIN "GNU"
533
#define ORIGIN "GNU"
534
#define REV 4
534
#define REV 4
535
#define VERS 8
535
#define VERS 9
536
#define PATCHLEVEL 0
536
#define PATCHLEVEL 0
537
#define DATE "05-Feb-20"
537
#define DATE "30-Jan-22"
538
#define STATE ""
538
#define STATE ""
(-)screen.orig/process.c (-4 / +4 lines)
Lines 2741-2747 Link Here
2741
#ifdef COPY_PASTE
2741
#ifdef COPY_PASTE
2742
    case RC_BUFFERFILE:
2742
    case RC_BUFFERFILE:
2743
      if (*args == 0)
2743
      if (*args == 0)
2744
	BufferFile = SaveStr(bufferfile);
2744
	BufferFile = SaveStr(DEFAULT_BUFFERFILE);
2745
      else if (ParseSaveStr(act, &BufferFile))
2745
      else if (ParseSaveStr(act, &BufferFile))
2746
        break;
2746
        break;
2747
      if (msgok)
2747
      if (msgok)
Lines 5401-5406 Link Here
5401
static int
5401
static int
5402
MoreWindows()
5402
MoreWindows()
5403
{
5403
{
5404
  char *m = "No other window.";
5404
  if (windows && (fore == 0 || windows->w_next))
5405
  if (windows && (fore == 0 || windows->w_next))
5405
    return 1;
5406
    return 1;
5406
  if (fore == 0)
5407
  if (fore == 0)
Lines 5408-5414 Link Here
5408
      Msg(0, "No window available");
5409
      Msg(0, "No window available");
5409
      return 0;
5410
      return 0;
5410
    }
5411
    }
5411
  Msg(0, "No other window%s.", fore->w_number > 1 ? "s" : "");
5412
  Msg(0, m, fore->w_number);	/* other arg for nethack */
5412
  return 0;
5413
  return 0;
5413
}
5414
}
5414
5415
Lines 6273-6280 Link Here
6273
  if (ktab[(int)(unsigned char)*buf].nr != RC_POW_DETACH)
6274
  if (ktab[(int)(unsigned char)*buf].nr != RC_POW_DETACH)
6274
    {
6275
    {
6275
      if (display)
6276
      if (display)
6276
        if (write(D_userfd, "\007", 1) < 1)
6277
        write(D_userfd, "\007", 1);
6277
          ;
6278
      Msg(0, "Detach aborted.");
6278
      Msg(0, "Detach aborted.");
6279
    }
6279
    }
6280
  else
6280
  else
(-)screen.orig/pty.c (-5 / +6 lines)
Lines 31-36 Link Here
31
#include <fcntl.h>
31
#include <fcntl.h>
32
#include <signal.h>
32
#include <signal.h>
33
33
34
#if defined(__OpenBSD__)
35
#include <utils.h>  /* for openpty() */
36
#endif
37
34
#include "config.h"
38
#include "config.h"
35
#include "screen.h"
39
#include "screen.h"
36
40
Lines 77-86 Link Here
77
extern int eff_uid;
81
extern int eff_uid;
78
82
79
/* used for opening a new pty-pair: */
83
/* used for opening a new pty-pair: */
80
#ifndef HAVE_GETPT
84
static char PtyName[32], TtyName[32];
81
static char PtyName[32];
82
#endif
83
static char TtyName[32];
84
85
85
#if !(defined(sequent) || defined(_SEQUENT_) || defined(HAVE_SVR4_PTYS))
86
#if !(defined(sequent) || defined(_SEQUENT_) || defined(HAVE_SVR4_PTYS))
86
# ifdef hpux
87
# ifdef hpux
Lines 262-271 Link Here
262
#endif
263
#endif
263
  sigret_t (*sigcld)__P(SIGPROTOARG);
264
  sigret_t (*sigcld)__P(SIGPROTOARG);
264
265
266
  strcpy(PtyName, "/dev/ptmx");
265
#if defined(HAVE_GETPT) && (defined(linux) || defined(__GLIBC__))
267
#if defined(HAVE_GETPT) && (defined(linux) || defined(__GLIBC__))
266
  if ((f = getpt()) == -1)
268
  if ((f = getpt()) == -1)
267
#else
269
#else
268
  strcpy(PtyName, "/dev/ptmx");
269
  if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1)
270
  if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1)
270
#endif
271
#endif
271
    return -1;
272
    return -1;
(-)screen.orig/resize.c (-11 lines)
Lines 683-699 Link Here
683
      he = MAXWIDTH;
683
      he = MAXWIDTH;
684
    }
684
    }
685
685
686
  if (wi > 1000)
687
    {
688
      Msg(0, "Window width too large, truncated");
689
      wi = 1000;
690
    }
691
  if (he > 1000)
692
    {
693
      Msg(0, "Window height too large, truncated");
694
      he = 1000;
695
    }
696
697
  if (p->w_width == wi && p->w_height == he && p->w_histheight == hi)
686
  if (p->w_width == wi && p->w_height == he && p->w_histheight == hi)
698
    {
687
    {
699
      debug("ChangeWindowSize: No change.\n");
688
      debug("ChangeWindowSize: No change.\n");
(-)screen.orig/sched.c (-199 / +181 lines)
Lines 47-290 Link Here
47
#endif
47
#endif
48
48
49
void
49
void
50
evenq(ev)
50
evenq(struct event *ev)
51
struct event *ev;
52
{
51
{
53
  struct event *evp, **evpp;
52
	struct event *evp, **evpp;
54
  debug3("New event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued);
53
	debug3("New event fd %d type %d queued %d\n", ev -> fd, ev -> type, ev -> queued);
55
  if (ev->queued)
54
	if (ev->queued)
56
    return;
55
		return;
57
  evpp = &evs;
56
	evpp = &evs;
58
  if (ev->type == EV_TIMEOUT)
57
	if (ev->type == EV_TIMEOUT) {
59
    {
58
		calctimeout = 1;
60
      calctimeout = 1;
59
		evpp = &tevs;
61
      evpp = &tevs;
60
	}
62
    }
61
	for (; (evp = *evpp); evpp = &evp->next)
63
  for (; (evp = *evpp); evpp = &evp->next)
62
		if (ev->pri > evp->pri)
64
    if (ev->pri > evp->pri)
63
			break;
65
      break;
64
	ev->next = evp;
66
  ev->next = evp;
65
	*evpp = ev;
67
  *evpp = ev;
66
	ev->queued = 1;
68
  ev->queued = 1;
69
}
67
}
70
68
71
void
69
void
72
evdeq(ev)
70
evdeq(struct event *ev)
73
struct event *ev;
74
{
71
{
75
  struct event *evp, **evpp;
72
	struct event *evp, **evpp;
76
  debug3("Deq event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued);
73
	debug3("Deq event fd %d type %d queued %d\n", ev -> fd, ev -> type, ev -> queued);
77
  if (!ev->queued)
74
	if (!ev->queued)
78
    return;
75
		return;
79
  evpp = &evs;
76
	evpp = &evs;
80
  if (ev->type == EV_TIMEOUT)
77
	if (ev->type == EV_TIMEOUT) {
81
    {
78
		calctimeout = 1;
82
      calctimeout = 1;
79
		evpp = &tevs;
83
      evpp = &tevs;
80
	}
84
    }
81
	for (; (evp = *evpp); evpp = &evp->next)
85
  for (; (evp = *evpp); evpp = &evp->next)
82
		if (evp == ev)
86
    if (evp == ev)
83
			break;
87
      break;
84
	ASSERT(evp);
88
  ASSERT(evp);
85
	*evpp = ev->next;
89
  *evpp = ev->next;
86
	ev->queued = 0;
90
  ev->queued = 0;
87
	if (ev == nextev)
91
  if (ev == nextev)
88
		nextev = nextev->next;
92
    nextev = nextev->next;
93
}
89
}
94
90
95
static struct event *
91
static struct event *
96
calctimo()
92
calctimo()
97
{
93
{
98
  struct event *ev, *min;
94
	struct event *ev, *min;
99
  long mins;
95
	long mins;
100
96
101
  if ((min = tevs) == 0)
97
	if ((min = tevs) == 0)
102
    return 0;
98
		return 0;
103
  mins = min->timeout.tv_sec;
99
	mins = min->timeout.tv_sec;
104
  for (ev = tevs->next; ev; ev = ev->next)
100
	for (ev = tevs->next; ev; ev = ev->next) {
105
    {
101
		ASSERT(ev->type == EV_TIMEOUT);
106
      ASSERT(ev->type == EV_TIMEOUT);
102
		if (mins < ev->timeout.tv_sec)
107
      if (mins < ev->timeout.tv_sec)
103
			continue;
108
	continue;
104
		if (mins > ev->timeout.tv_sec || min->timeout.tv_usec > ev->timeout.tv_usec) {
109
      if (mins > ev->timeout.tv_sec || min->timeout.tv_usec > ev->timeout.tv_usec)
105
			min = ev;
110
	{
106
			mins = ev->timeout.tv_sec;
111
	  min = ev;
107
		}
112
	  mins = ev->timeout.tv_sec;
113
	}
108
	}
114
    }
109
	return min;
115
  return min;
116
}
110
}
117
111
118
void
112
void
119
sched()
113
sched()
120
{
114
{
121
  struct event *ev;
115
	struct event *ev;
122
  fd_set r, w, *set;
116
	fd_set r, w, *set;
123
  struct event *timeoutev = 0;
117
	struct event *timeoutev = 0;
124
  struct timeval timeout;
118
	struct timeval timeout;
125
  int nsel;
119
	int nsel;
126
120
127
  for (;;)
121
	for (;;) {
128
    {
122
		if (calctimeout)
129
      if (calctimeout)
123
			timeoutev = calctimo();
130
	timeoutev = calctimo();
124
		if (timeoutev) {
131
      if (timeoutev)
125
			gettimeofday(&timeout, NULL);
132
	{
126
			/* tp - timeout */
133
	  gettimeofday(&timeout, NULL);
127
			timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_sec;
134
	  /* tp - timeout */
128
			timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv_usec;
135
	  timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_sec;
129
136
	  timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv_usec;
130
			if (timeout.tv_usec < 0) {
137
	  if (timeout.tv_usec < 0)
131
				timeout.tv_usec += 1000000;
138
	    {
132
				timeout.tv_sec--;
139
	      timeout.tv_usec += 1000000;
133
			}
140
	      timeout.tv_sec--;
134
			if (timeout.tv_sec < 0) {
141
	    }
135
				timeout.tv_usec = 0;
142
	  if (timeout.tv_sec < 0)
136
				timeout.tv_sec = 0;
143
	    {
137
			}
144
	      timeout.tv_usec = 0;
138
		}
145
	      timeout.tv_sec = 0;
146
	    }
147
	}
148
#ifdef DEBUG
139
#ifdef DEBUG
149
      debug("waiting for events");
140
		debug("waiting for events");
150
      if (timeoutev)
141
		if (timeoutev)
151
        debug2(" timeout %ld secs %ld usecs", timeout.tv_sec, timeout.tv_usec);
142
			debug2(" timeout %d secs %d usecs", timeout.tv_sec, timeout.tv_usec);
152
      debug(":\n");
143
		debug(":\n");
153
      for (ev = evs; ev; ev = ev->next)
144
		for (ev = evs; ev; ev = ev->next)
154
        debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev->pri);
145
			debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev->pri);
155
      if (tevs)
146
		if (tevs)
156
        debug("timed events:\n");
147
			debug("timed events:\n");
157
      for (ev = tevs; ev; ev = ev->next)
148
		for (ev = tevs; ev; ev = ev->next)
158
        debug3(" - pri %d sec %ld usec %ld\n", ev->pri, ev->timeout.tv_sec, ev->timeout.tv_usec);
149
			debug3(" - pri %d sec %d usec %d\n", ev->pri,
159
#endif
150
			    ev->timeout.tv_sec, ev->timeout.tv_usec);
160
151
#endif
161
      FD_ZERO(&r);
152
162
      FD_ZERO(&w);
153
		FD_ZERO(&r);
163
      for (ev = evs; ev; ev = ev->next)
154
		FD_ZERO(&w);
164
        {
155
		for (ev = evs; ev; ev = ev->next) {
165
	  if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0))
156
			if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) {
166
	    {
157
				debug2(" - cond ev fd %d type %d failed\n", ev->fd, ev->type);
167
	      debug2(" - cond ev fd %d type %d failed\n", ev->fd, ev->type);
158
				continue;
168
	      continue;
159
			}
169
	    }
160
			if (ev->type == EV_READ)
170
	  if (ev->type == EV_READ)
161
				FD_SET(ev->fd, &r);
171
	    FD_SET(ev->fd, &r);
162
			else if (ev->type == EV_WRITE)
172
	  else if (ev->type == EV_WRITE)
163
				FD_SET(ev->fd, &w);
173
	    FD_SET(ev->fd, &w);
164
		}
174
        }
175
165
176
#ifdef DEBUG
166
#ifdef DEBUG
177
      debug("readfds:");
167
		debug("readfds:");
178
      for (nsel = 0; nsel < FD_SETSIZE; nsel++)
168
		for (nsel = 0; nsel < FD_SETSIZE; nsel++)
179
	if (FD_ISSET(nsel, &r))
169
			if (FD_ISSET(nsel, &r))
180
	  debug1(" %d", nsel);
170
				debug1(" %d", nsel);
181
      debug("\n");
171
		debug("\n");
182
      debug("writefds:");
172
		debug("writefds:");
183
      for (nsel = 0; nsel < FD_SETSIZE; nsel++)
173
		for (nsel = 0; nsel < FD_SETSIZE; nsel++)
184
	if (FD_ISSET(nsel, &w))
174
			if (FD_ISSET(nsel, &w))
185
	  debug1(" %d", nsel);
175
				debug1(" %d", nsel);
186
      debug("\n");
176
		debug("\n");
187
#endif
177
#endif
188
178
189
      nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeout : (struct timeval *) 0);
179
		nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeout : (struct timeval *)0);
190
      if (nsel < 0)
180
		if (nsel < 0) {
191
	{
181
			if (errno != EINTR) {
192
	  if (errno != EINTR)
193
	    {
194
#if defined(sgi) && defined(SVR4)
182
#if defined(sgi) && defined(SVR4)
195
	      if (errno == EIO && sgihack())
183
				if (errno == EIO && sgihack())
196
		continue;
184
					continue;
197
#endif
185
#endif
198
#if defined(__osf__) || defined(M_UNIX)
186
#if defined(__osf__) || defined(M_UNIX)
199
	      /* OSF/1 3.x, SCO bug: EBADF */
187
				/* OSF/1 3.x, SCO bug: EBADF */
200
	      /* OSF/1 4.x bug: EIO */
188
				/* OSF/1 4.x bug: EIO */
201
	      if ((errno == EIO || errno == EBADF) && sgihack())
189
				if ((errno == EIO || errno == EBADF) && sgihack())
202
		continue;
190
					continue;
203
#endif
191
#endif
204
	      Panic(errno, "select");
192
				Panic(errno, "select");
205
	    }
193
			}
206
	  nsel = 0;
194
			nsel = 0;
207
	}
195
		} else if (nsel == 0) {		/* timeout */
208
      else if (nsel == 0)	/* timeout */
196
			debug("TIMEOUT!\n");
209
	{
197
			ASSERT(timeoutev);
210
	  debug("TIMEOUT!\n");
198
			evdeq(timeoutev);
211
	  ASSERT(timeoutev);
199
			timeoutev->handler(timeoutev, timeoutev->data);
212
	  evdeq(timeoutev);
200
		}
213
	  timeoutev->handler(timeoutev, timeoutev->data);
214
	}
215
#ifdef SELECT_BROKEN
201
#ifdef SELECT_BROKEN
216
      /*
202
      /*
217
       * Sequents select emulation counts a descriptor which is
203
       * Sequents select emulation counts a descriptor which is
218
       * readable and writeable only as one hit. Waaaaa.
204
       * readable and writeable only as one hit. Waaaaa.
219
       */
205
       */
220
      if (nsel)
206
		if (nsel)
221
        nsel = 2 * FD_SETSIZE;
207
			nsel = 2 * FD_SETSIZE;
222
#endif
208
#endif
223
209
224
      for (ev = evs; ev; ev = nextev)
210
		for (ev = evs; ev; ev = nextev) {
225
        {
211
			nextev = ev->next;
226
          nextev = ev->next;
212
			if (ev->type != EV_ALWAYS) {
227
	  if (ev->type != EV_ALWAYS)
213
				set = ev->type == EV_READ ? &r : &w;
228
	    {
214
				if (nsel == 0 || !FD_ISSET(ev->fd, set))
229
	      set = ev->type == EV_READ ? &r : &w;
215
					continue;
230
	      if (nsel == 0 || !FD_ISSET(ev->fd, set))
216
				nsel--;
231
		continue;
217
			}
232
	      nsel--;
218
			if (ev->condpos &&
233
	    }
219
			    *ev->condpos <= (ev->condneg ? *ev->condneg : 0))
234
	  if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0))
220
				continue;
235
	    continue;
221
			debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type);
236
	  debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type);
222
			ev->handler(ev, ev->data);
237
	  ev->handler(ev, ev->data);
223
		}
238
        }
224
	}
239
    }
240
}
225
}
241
226
242
void
227
void
243
SetTimeout(ev, timo)
228
SetTimeout(struct event *ev, int timo)
244
struct event *ev;
229
{
245
int timo;
230
	ASSERT(ev->type == EV_TIMEOUT);
246
{
231
	debug2("event %x new timeout %d ms\n", ev, timo);
247
  ASSERT(ev->type == EV_TIMEOUT);
232
	gettimeofday(&ev->timeout, NULL);
248
  debug2("event %p new timeout %d ms\n", ev, timo);
233
	ev->timeout.tv_sec += timo / 1000;
249
  gettimeofday(&ev->timeout, NULL);
234
	ev->timeout.tv_usec += (timo % 1000) * 1000;
250
  ev->timeout.tv_sec  += timo / 1000;
235
251
  ev->timeout.tv_usec += (timo % 1000) * 1000;
236
	if (ev->timeout.tv_usec > 1000000) {
252
  if (ev->timeout.tv_usec > 1000000)
237
		ev->timeout.tv_usec -= 1000000;
253
    {
238
		ev->timeout.tv_sec++;
254
      ev->timeout.tv_usec -= 1000000;
239
	}
255
      ev->timeout.tv_sec++;
240
	if (ev->queued)
256
    }
241
		calctimeout = 1;
257
  if (ev->queued)
258
    calctimeout = 1;
259
}
242
}
260
243
261
262
#if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX)
244
#if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX)
263
245
/* do we still need it?
246
                    @anaumov */
264
extern struct display *display, *displays;
247
extern struct display *display, *displays;
265
static int sgihack()
248
static int
249
sgihack()
266
{
250
{
267
  fd_set r, w;
251
	fd_set r, w;
268
  struct timeval tv;
252
	struct timeval tv;
269
253
270
  debug("IRIX5.2 workaround: searching for bad display\n");
254
	debug("IRIX5.2 workaround: searching for bad display\n");
271
  for (display = displays; display; )
255
	for (display = displays; display;) {
272
    {
256
		FD_ZERO(&r);
273
      FD_ZERO(&r);
257
		FD_ZERO(&w);
274
      FD_ZERO(&w);
258
		FD_SET(D_userfd, &r);
275
      FD_SET(D_userfd, &r);
259
		FD_SET(D_userfd, &w);
276
      FD_SET(D_userfd, &w);
260
		tv.tv_sec = tv.tv_usec = 0;
277
      tv.tv_sec = tv.tv_usec = 0;
261
		if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1) {
278
      if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1)
262
			if (errno == EINTR)
279
	{
263
				continue;
280
	  if (errno == EINTR)
264
			Hangup();	/* goodbye display */
281
	    continue;
265
			return 1;
282
	  Hangup();	/* goodbye display */
266
		}
283
	  return 1;
267
		display = display->d_next;
284
	}
268
	}
285
      display = display->d_next;
269
	return 0;
286
    }
287
  return 0;
288
}
270
}
289
271
290
#endif
272
#endif
(-)screen.orig/screen.c (-99 / +65 lines)
Lines 122-128 Link Here
122
FILE *dfp;
122
FILE *dfp;
123
#endif
123
#endif
124
124
125
char bufferfile[MAXPATHLEN];
126
125
127
extern char Term[], screenterm[], **environ, Termcap[];
126
extern char Term[], screenterm[], **environ, Termcap[];
128
int force_vt = 1;
127
int force_vt = 1;
Lines 154-162 Link Here
154
static void  SigChldHandler __P((void));
153
static void  SigChldHandler __P((void));
155
static sigret_t SigChld __P(SIGPROTOARG);
154
static sigret_t SigChld __P(SIGPROTOARG);
156
static sigret_t SigInt __P(SIGPROTOARG);
155
static sigret_t SigInt __P(SIGPROTOARG);
157
#if 0
158
static sigret_t CoreDump __P(SIGPROTOARG);
156
static sigret_t CoreDump __P(SIGPROTOARG);
159
#endif
160
static sigret_t FinitHandler __P(SIGPROTOARG);
157
static sigret_t FinitHandler __P(SIGPROTOARG);
161
static void  DoWait __P((void));
158
static void  DoWait __P((void));
162
static void  serv_read_fn __P((struct event *, char *));
159
static void  serv_read_fn __P((struct event *, char *));
Lines 239-245 Link Here
239
236
240
char HostName[MAXSTR];
237
char HostName[MAXSTR];
241
int MasterPid, PanicPid;
238
int MasterPid, PanicPid;
242
int real_uid, real_gid, eff_uid, eff_gid, init_eff_gid;
239
int real_uid, real_gid, eff_uid, eff_gid;
243
int default_startup;
240
int default_startup;
244
int ZombieKey_destroy, ZombieKey_resurrect, ZombieKey_onerror;
241
int ZombieKey_destroy, ZombieKey_resurrect, ZombieKey_onerror;
245
char *preselect = NULL;		/* only used in Attach() */
242
char *preselect = NULL;		/* only used in Attach() */
Lines 271-277 Link Here
271
 */
268
 */
272
#include "extern.h"
269
#include "extern.h"
273
270
274
const char strnomem[] = "Out of memory.";
271
char strnomem[] = "Out of memory.";
275
272
276
static int InterruptPlease;
273
static int InterruptPlease;
277
static int GotSigChld;
274
static int GotSigChld;
Lines 470-475 Link Here
470
  timestring = SaveStr("%c:%s %M %d %H%? %l%?");
467
  timestring = SaveStr("%c:%s %M %d %H%? %l%?");
471
  wlisttit = SaveStr(" Num Name%=Flags");
468
  wlisttit = SaveStr(" Num Name%=Flags");
472
  wliststr = SaveStr("%4n %t%=%f");
469
  wliststr = SaveStr("%4n %t%=%f");
470
#ifdef COPY_PASTE
471
  BufferFile = SaveStr(DEFAULT_BUFFERFILE);
472
#endif
473
  ShellProg = NULL;
473
  ShellProg = NULL;
474
#ifdef POW_DETACH
474
#ifdef POW_DETACH
475
  PowDetachString = 0;
475
  PowDetachString = 0;
Lines 509-515 Link Here
509
  real_uid = getuid();
509
  real_uid = getuid();
510
  real_gid = getgid();
510
  real_gid = getgid();
511
  eff_uid = geteuid();
511
  eff_uid = geteuid();
512
  init_eff_gid = eff_gid = getegid();
512
  eff_gid = getegid();
513
513
514
  logreopen_register(lf_secreopen);
514
  logreopen_register(lf_secreopen);
515
515
Lines 778-783 Link Here
778
              if (--ac == 0)
778
              if (--ac == 0)
779
                exit_with_usage(myname, "Specify session-name with -S", NULL);
779
                exit_with_usage(myname, "Specify session-name with -S", NULL);
780
              SockMatch = *++av;
780
              SockMatch = *++av;
781
              debug1("SockMatch: '%s'\n", SockMatch);
782
              debug1("SockMatch len: '%d'\n", (int)strlen(SockMatch));
783
              if (strlen(SockMatch) > 80)
784
                exit_with_usage(myname, "Session-name is too long (max length is 80 symbols)", NULL);
781
            }
785
            }
782
            if (!*SockMatch)
786
            if (!*SockMatch)
783
              exit_with_usage(myname, "Empty session-name?", NULL);
787
              exit_with_usage(myname, "Empty session-name?", NULL);
Lines 806-824 Link Here
806
      break;
810
      break;
807
  }
811
  }
808
812
809
#if 0
810
  if (eff_uid != real_uid)
811
    {
812
      /* if running with s-bit, we must install a special signal
813
       * handler routine that resets the s-bit, so that we get a
814
       * core file anyway.
815
       */
816
#ifdef SIGBUS /* OOPS, linux has no bus errors! */
813
#ifdef SIGBUS /* OOPS, linux has no bus errors! */
817
  signal(SIGBUS, CoreDump);
814
  signal(SIGBUS, CoreDump);
818
#endif /* SIGBUS */
815
#endif /* SIGBUS */
819
  signal(SIGSEGV, CoreDump);
816
  signal(SIGSEGV, CoreDump);
820
817
821
#endif
822
818
823
#ifdef USE_LOCALE
819
#ifdef USE_LOCALE
824
  setlocale(LC_ALL, "");
820
  setlocale(LC_ALL, "");
Lines 1042-1052 Link Here
1042
#endif /* DEBUG */
1038
#endif /* DEBUG */
1043
    }
1039
    }
1044
1040
1045
#ifdef COPY_PASTE
1046
    snprintf(bufferfile, sizeof(bufferfile), "%s/.screen-exchange", home);
1047
    BufferFile = SaveStr(bufferfile);
1048
#endif
1049
1050
#ifdef _MODE_T
1041
#ifdef _MODE_T
1051
    oumask = umask(0);		/* well, unsigned never fails? jw. */
1042
    oumask = umask(0);		/* well, unsigned never fails? jw. */
1052
#else
1043
#else
Lines 1130-1135 Link Here
1130
      if (access(SockPath, F_OK)) {
1121
      if (access(SockPath, F_OK)) {
1131
        if (mkdir(SockPath, 0700) == -1 && errno != EEXIST)
1122
        if (mkdir(SockPath, 0700) == -1 && errno != EEXIST)
1132
          Panic(errno, "Cannot make directory '%s'", SockPath);
1123
          Panic(errno, "Cannot make directory '%s'", SockPath);
1124
        (void) chown(SockPath, real_uid, real_gid);
1133
      }
1125
      }
1134
    }
1126
    }
1135
#endif
1127
#endif
Lines 1203-1213 Link Here
1203
    eexit(0);
1195
    eexit(0);
1204
  }
1196
  }
1205
  signal(SIG_BYE, AttacherFinit);	/* prevent races */
1197
  signal(SIG_BYE, AttacherFinit);	/* prevent races */
1198
1206
  if (cmdflag) {
1199
  if (cmdflag) {
1200
1201
#ifdef MULTIUSER
1202
    if (multi)
1203
      real_uid = multi_uid;
1204
#endif
1205
1207
    /* attach_tty is not mandatory */
1206
    /* attach_tty is not mandatory */
1208
    SetTtyname(false, &st);
1207
    SetTtyname(false, &st);
1209
    if (!*av)
1208
    if (!*av)
1210
      Panic(0, "Please specify a command.");
1209
      Panic(0, "Please specify a command.");
1210
    if (!strncmp("sessionname", *av, 11)) {
1211
      if (!*++av)
1212
        Panic(0, "Please specify a parameter.");
1213
      if (strlen(*av) > 80)
1214
        Panic(0, "Parameter of command 'sessionname' is too long.");
1215
    *--av;
1216
    }
1211
    SET_GUID();
1217
    SET_GUID();
1212
    SendCmdMessage(sty, SockMatch, av, queryflag >= 0);
1218
    SendCmdMessage(sty, SockMatch, av, queryflag >= 0);
1213
    exit(0);
1219
    exit(0);
Lines 1244-1253 Link Here
1244
  nwin_compose(&nwin_default, &nwin_options, &nwin_default);
1250
  nwin_compose(&nwin_default, &nwin_options, &nwin_default);
1245
1251
1246
  if (!detached || dflag != 2)
1252
  if (!detached || dflag != 2)
1247
    {
1253
    MasterPid = fork();
1248
      fflush(NULL);
1249
      MasterPid = fork();
1250
    }
1251
  else
1254
  else
1252
    MasterPid = 0;
1255
    MasterPid = 0;
1253
1256
Lines 1320-1359 Link Here
1320
  }
1323
  }
1321
  else
1324
  else
1322
    n = -1;
1325
    n = -1;
1323
1326
  freopen("/dev/null", "r", stdin);
1324
  {
1327
  freopen("/dev/null", "w", stdout);
1325
    const char devnull[] = "/dev/null";
1326
    int nullfdr, nullfdw;
1327
1328
    if (fflush(NULL))
1329
      Panic(errno, "Cannot flush stdio streams");
1330
1331
    nullfdr = open(devnull, O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK);
1332
    if (nullfdr < 0)
1333
      Panic(errno, "Cannot open '%s' for reading", devnull);
1334
1335
    nullfdw = open(devnull, O_WRONLY|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK);
1336
    if (nullfdw < 0)
1337
      Panic(errno, "Cannot open '%s' for writing", devnull);
1338
1339
    if (dup2(nullfdr, fileno(stdin)) < 0)
1340
      Panic(errno, "Cannot reditect '%s' to '%s'", "stdin", devnull);
1341
1342
    close(nullfdr);
1343
1344
    if (dup2(nullfdw, fileno(stdout)) < 0)
1345
      Panic(errno, "Cannot reditect '%s' to '%s'", "stdout", devnull);
1346
1328
1347
#ifdef DEBUG
1329
#ifdef DEBUG
1348
  if (dfp != stderr)
1330
  if (dfp != stderr)
1349
#endif
1331
#endif
1350
    if (dup2(nullfdw, fileno(stderr)) < 0)
1332
  freopen("/dev/null", "w", stderr);
1351
      Panic(errno, "Cannot reditect '%s' to '%s'", "stderr", devnull);
1333
  debug("-- screen.back debug started\n");
1352
1353
    close(nullfdw);
1354
1355
    debug("-- screen.back debug started\n");
1356
  }
1357
1334
1358
  /*  This guarantees that the session owner is listed, even when we
1335
  /*  This guarantees that the session owner is listed, even when we
1359
   *  start detached. From now on we should not refer to 'LoginName'
1336
   *  start detached. From now on we should not refer to 'LoginName'
Lines 1672-1678 Link Here
1672
  SIGRETURN;
1649
  SIGRETURN;
1673
}
1650
}
1674
1651
1675
#if 0
1676
static sigret_t CoreDump SIGDEFARG
1652
static sigret_t CoreDump SIGDEFARG
1677
{
1653
{
1678
  /* if running with s-bit, we must reset the s-bit, so that we get a
1654
  /* if running with s-bit, we must reset the s-bit, so that we get a
Lines 1723-1729 Link Here
1723
1699
1724
  SIGRETURN;
1700
  SIGRETURN;
1725
}
1701
}
1726
#endif
1727
1702
1728
static void DoWait()
1703
static void DoWait()
1729
{
1704
{
Lines 1896-1902 Link Here
1896
{
1871
{
1897
  if (display == 0)
1872
  if (display == 0)
1898
    return;
1873
    return;
1899
  debug1("Hangup %p\n", display);
1874
  debug1("Hangup %x\n", display);
1900
  if (D_userfd >= 0) {
1875
  if (D_userfd >= 0) {
1901
    close(D_userfd);
1876
    close(D_userfd);
1902
    D_userfd = -1;
1877
    D_userfd = -1;
Lines 2108-2136 Link Here
2108
#endif
2083
#endif
2109
2084
2110
#define	PROCESS_MESSAGE(B) do { \
2085
#define	PROCESS_MESSAGE(B) do { \
2086
    char *p = B;	\
2111
    VA_LIST(ap)	\
2087
    VA_LIST(ap)	\
2112
    ssize_t len; \
2113
    const int errlen = err ? 100 : 0; \
2114
    VA_START(ap, fmt);	\
2088
    VA_START(ap, fmt);	\
2115
    fmt = DoNLS(fmt);	\
2089
    fmt = DoNLS(fmt);	\
2116
    len = vsnprintf(B, sizeof(B) - errlen, fmt, VA_ARGS(ap));	\
2090
    (void)vsnprintf(p, sizeof(B) - 100, fmt, VA_ARGS(ap));	\
2117
    VA_END(ap);	\
2091
    VA_END(ap);	\
2118
    if (len < 0) \
2119
    { \
2120
      strncpy(B, fmt, sizeof(B) - errlen);	\
2121
      B[sizeof(B) - errlen - 1] = 0;	\
2122
      len = strlen(B);	\
2123
    } \
2124
    if (err)	\
2092
    if (err)	\
2125
    { \
2093
      {	\
2126
	const char *strerr = strerror(err); \
2094
	p += strlen(p);	\
2127
	if (strerr) \
2095
	*p++ = ':';	\
2128
	{ \
2096
	*p++ = ' ';	\
2129
	  strncat(B, ": ", 2); \
2097
	strncpy(p, strerror(err), B + sizeof(B) - p - 1);	\
2130
	  strncat(B, strerr, errlen - 3); \
2098
	B[sizeof(B) - 1] = 0;	\
2131
	  len = strlen(B); \
2099
      }	\
2132
	} \
2133
    } \
2134
  } while (0)
2100
  } while (0)
2135
2101
2136
DEFINE_VARARGS_FN(Msg)
2102
DEFINE_VARARGS_FN(Msg)
Lines 2157-2168 Link Here
2157
    display = olddisplay;
2123
    display = olddisplay;
2158
  }
2124
  }
2159
  else
2125
  else
2160
    {
2126
    printf("%s\r\n", buf);
2161
      ssize_t len = strlen(buf);
2162
      if (write(fileno(stderr), buf, len) > 0)
2163
	if (write(fileno(stderr), "\r\n", 2) > 0)
2164
	  ;
2165
    }
2166
2127
2167
  if (queryflag >= 0)
2128
  if (queryflag >= 0)
2168
    write(queryflag, buf, strlen(buf));
2129
    write(queryflag, buf, strlen(buf));
Lines 2175-2189 Link Here
2175
{
2136
{
2176
  char buf[MAXPATHLEN*2];
2137
  char buf[MAXPATHLEN*2];
2177
  PROCESS_MESSAGE(buf);
2138
  PROCESS_MESSAGE(buf);
2178
  ssize_t len = strlen(buf);
2179
2139
2180
  debug3("Panic('%s'); display=%p displays=%p\n", buf, display, displays);
2140
  debug3("Panic('%s'); display=%x displays=%x\n", buf, display, displays);
2181
  if (displays == 0 && display == 0) {
2141
  if (displays == 0 && display == 0) {
2182
    if (write(fileno(stderr), buf, len) > 0)
2142
    printf("%s\r\n", buf);
2183
      if (write(fileno(stderr), "\r\n", 2) > 0)
2143
    if (PanicPid)
2184
	;
2144
      Kill(PanicPid, SIG_BYE);
2185
      if (PanicPid)
2186
	Kill(PanicPid, SIG_BYE);
2187
  }
2145
  }
2188
  else if (displays == 0) {
2146
  else if (displays == 0) {
2189
      /* no displays but a display - must have forked.
2147
      /* no displays but a display - must have forked.
Lines 2206-2214 Link Here
2206
#endif
2164
#endif
2207
      SetTTY(D_userfd, &D_OldMode);
2165
      SetTTY(D_userfd, &D_OldMode);
2208
      fcntl(D_userfd, F_SETFL, 0);
2166
      fcntl(D_userfd, F_SETFL, 0);
2209
      if (write(D_userfd, buf, len) > 0)
2167
      write(D_userfd, buf, strlen(buf));
2210
        if (write(D_userfd, "\n", 1) > 0)
2168
      write(D_userfd, "\n", 1);
2211
          ;
2212
      freetty();
2169
      freetty();
2213
      if (D_userpid)
2170
      if (D_userpid)
2214
        Kill(D_userpid, SIG_BYE);
2171
        Kill(D_userpid, SIG_BYE);
Lines 2816-2821 Link Here
2816
      p += strlen(p) - 1;
2773
      p += strlen(p) - 1;
2817
      break;
2774
      break;
2818
2775
2776
#ifdef ENCODINGS
2777
    case 'e':
2778
      *p = 0;
2779
      D_encoding = nwin_options.encoding > 0 ? nwin_options.encoding : 0;
2780
      if (win && win->w_encoding) {
2781
        *p++ = ' ';
2782
        strcpy(p, EncodingName(win->w_encoding));
2783
      }
2784
      p += strlen(p) - 1;
2785
      break;
2786
#endif
2787
2819
    case '{':
2788
    case '{':
2820
    {
2789
    {
2821
      char rbuf[128];
2790
      char rbuf[128];
Lines 3065-3071 Link Here
3065
    else
3034
    else
3066
      now.tv_sec += tick - (now.tv_sec % tick);
3035
      now.tv_sec += tick - (now.tv_sec % tick);
3067
    ev->timeout = now;
3036
    ev->timeout = now;
3068
    debug2("NEW timeout %ld %d\n", ev->timeout.tv_sec, tick);
3037
    debug2("NEW timeout %d %d\n", ev->timeout.tv_sec, tick);
3069
  }
3038
  }
3070
  return winmsg_buf;
3039
  return winmsg_buf;
3071
}
3040
}
Lines 3193-3207 Link Here
3193
3162
3194
3163
3195
#ifdef PSEUDOS
3164
#ifdef PSEUDOS
3196
      if (write(W_UWP(fore) ? fore->w_pwin->p_ptyfd : fore->w_ptyfd, &ibuf, 1) == 1) {
3165
      write(W_UWP(fore) ? fore->w_pwin->p_ptyfd : fore->w_ptyfd, &ibuf, 1);
3197
        debug1("Backend wrote interrupt to %d", fore->w_number);
3166
      debug1("Backend wrote interrupt to %d", fore->w_number);
3198
        debug1("%s\n", W_UWP(fore) ? " (pseudowin)" : "");
3167
      debug1("%s\n", W_UWP(fore) ? " (pseudowin)" : "");
3199
      }
3200
#else
3168
#else
3201
      if (write(fore->w_ptyfd, &ibuf, 1) == 1)
3169
      write(fore->w_ptyfd, &ibuf, 1);
3202
        debug1("Backend wrote interrupt to %d\n", fore->w_number);
3170
      debug1("Backend wrote interrupt to %d\n", fore->w_number);
3203
      else
3204
        debug1("Backend FAILED to write interrupt to %d\n", fore->w_number);
3205
#endif
3171
#endif
3206
    }
3172
    }
3207
    InterruptPlease = 0;
3173
    InterruptPlease = 0;
(-)screen.orig/screen.h (-2 / +6 lines)
Lines 49-55 Link Here
49
#include "layer.h"
49
#include "layer.h"
50
#include "term.h"
50
#include "term.h"
51
51
52
extern char bufferfile[MAXPATHLEN];
53
52
54
#ifdef DEBUG
53
#ifdef DEBUG
55
# define STATIC		/* a function that the debugger should see */
54
# define STATIC		/* a function that the debugger should see */
Lines 104-109 Link Here
104
 */
103
 */
105
#define MAXHISTHEIGHT		3000
104
#define MAXHISTHEIGHT		3000
106
#define DEFAULTHISTHEIGHT	100
105
#define DEFAULTHISTHEIGHT	100
106
#if defined(NAME_MAX) && NAME_MAX < 16
107
# define DEFAULT_BUFFERFILE     "/tmp/screen-xchg"
108
#else
109
# define DEFAULT_BUFFERFILE	"/tmp/screen-exchange"
110
#endif
107
111
108
112
109
#if defined(hpux) && !(defined(VSUSP) && defined(VDSUSP) && defined(VWERASE) && defined(VLNEXT))
113
#if defined(hpux) && !(defined(VSUSP) && defined(VDSUSP) && defined(VWERASE) && defined(VLNEXT))
Lines 275-281 Link Here
275
#define SILENCE_FOUND   2 /* Window is silent */
279
#define SILENCE_FOUND   2 /* Window is silent */
276
#define SILENCE_DONE    3 /* Window is silent and user is notified */
280
#define SILENCE_DONE    3 /* Window is silent and user is notified */
277
281
278
extern const char strnomem[];
282
extern char strnomem[];
279
283
280
/*
284
/*
281
 * line modes used by Input()
285
 * line modes used by Input()
(-)screen.orig/search.c (-275 / +259 lines)
Lines 46-137 Link Here
46
 *  VI style Search
46
 *  VI style Search
47
 */
47
 */
48
48
49
static int  matchword __P((char *, int, int, int));
49
static int  matchword __P((char*, int, int, int));
50
static void searchend __P((char *, int, char *));
50
static void searchend __P((char*, int, char *));
51
static void backsearchend __P((char *, int, char *));
51
static void backsearchend __P((char*, int, char *));
52
52
53
void
53
void
54
Search(dir)
54
Search(int dir)
55
int dir;
56
{
55
{
57
  struct markdata *markdata;
56
	struct markdata *markdata;
58
  if (dir == 0)
57
	if (dir == 0) {
59
    {
58
		markdata = (struct markdata *)flayer->l_data;
60
      markdata = (struct markdata *)flayer->l_data;
59
		if (markdata->isdir > 0)
61
      if (markdata->isdir > 0)
60
			searchend(0, 0, NULL);
62
	searchend(0, 0, NULL);
61
		else if (markdata->isdir < 0)
63
      else if (markdata->isdir < 0)
62
			backsearchend(0, 0, NULL);
64
	backsearchend(0, 0, NULL);
63
		else
65
      else
64
			LMsg(0, "No previous pattern");
66
	LMsg(0, "No previous pattern");
65
	} else
67
    }
66
		Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr) - 1,
68
  else
67
		    INP_COOKED, (dir > 0 ? searchend : backsearchend), NULL, 0);
69
    Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr)-1, INP_COOKED,
70
          (dir > 0 ? searchend : backsearchend), NULL, 0);
71
}
68
}
72
69
73
static void
70
static void
74
searchend(buf, len, data)
71
searchend(char *buf, int len, char *data)
75
char *buf;
76
int len;
77
char *data;	/* dummy */
78
{
72
{
79
  int x = 0, sx, ex, y;
73
	int x = 0, sx, ex, y;
80
  struct markdata *markdata;
74
	struct markdata *markdata;
81
  struct win *p;
75
	struct win *p;
82
76
83
  markdata = (struct markdata *)flayer->l_data;
77
	markdata = (struct markdata *)flayer->l_data;
84
  p = markdata->md_window;
78
	p = markdata->md_window;
85
  markdata->isdir = 1;
79
	markdata->isdir = 1;
86
  if (len)
80
	if (len)
87
    strcpy(markdata->isstr, buf);
81
		strcpy(markdata->isstr, buf);
88
  sx = markdata->cx + 1;
82
	sx = markdata->cx + 1;
89
  ex = flayer->l_width - 1;
83
	ex = flayer->l_width - 1;
90
  for (y = markdata->cy; y < p->w_histheight + flayer->l_height; y++, sx = 0)
84
	for (y = markdata->cy; y < p->w_histheight + flayer->l_height;
91
    {
85
	    y++, sx = 0) {
92
      if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0)
86
		if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0)
93
        break;
87
			break;
94
    }
88
	}
95
  if (y >= p->w_histheight + flayer->l_height)
89
	if (y >= p->w_histheight + flayer->l_height) {
96
    {
90
		LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
97
      LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
91
		LMsg(0, "Pattern not found");
98
      LMsg(0, "Pattern not found");
92
	} else
99
    }
93
		revto(x, y);
100
  else
101
    revto(x, y);
102
}
94
}
103
95
104
static void
96
static void
105
backsearchend(buf, len, data)
97
backsearchend(char *buf, int len, char *data)
106
char *buf;
107
int len;
108
char *data;	/* dummy */
109
{
98
{
110
  int sx, ex, x = -1, y;
99
	int sx, ex, x = -1, y;
111
  struct markdata *markdata;
100
	struct markdata *markdata;
112
101
113
  markdata = (struct markdata *)flayer->l_data;
102
	markdata = (struct markdata *)flayer->l_data;
114
  markdata->isdir = -1;
103
	markdata->isdir = -1;
115
  if (len)
104
116
    strcpy(markdata->isstr, buf);
105
	if (len)
117
  ex = markdata->cx - 1;
106
		strcpy(markdata->isstr, buf);
118
  for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1)
107
	ex = markdata->cx - 1;
119
    {
108
120
      sx = 0;
109
	for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1) {
121
      while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0)
110
		sx = 0;
122
	x = sx++;
111
		while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0)
123
      if (x >= 0)
112
			x = sx++;
124
	break;
113
		if (x >= 0)
125
    }
114
			break;
126
  if (y < 0)
115
	}
127
    {
128
      LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
129
      LMsg(0, "Pattern not found");
130
    }
131
  else
132
    revto(x, y);
133
}
134
116
117
	if (y < 0) {
118
		LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
119
		LMsg(0, "Pattern not found");
120
	} else
121
		revto(x, y);
122
}
135
123
136
/*
124
/*
137
 * Search for a string that matches pattern.  The first character of the
125
 * Search for a string that matches pattern.  The first character of the
Lines 141-399 Link Here
141
 * or -1 if there's no match.
129
 * or -1 if there's no match.
142
 */
130
 */
143
static int
131
static int
144
matchword(pattern, y, sx, ex)
132
matchword(char *pattern, int y, int sx, int ex)
145
char *pattern;
146
int y, sx, ex;
147
{
133
{
148
  unsigned char *ip, *cp, *pp, *cpe;
134
	unsigned char *cp, *pp, *cpe;
149
  int cy;
135
	int cy;
150
136
151
  fore = ((struct markdata *)flayer->l_data)->md_window;
137
	fore = ((struct markdata *)flayer->l_data)->md_window;
152
138
153
  for (;sx <= ex; sx++)
139
	for (; sx <= ex; sx++) {
154
    {
140
		cy = y;
155
			cy = y;
141
		cp = WIN(cy)->image + sx;
156
			cp = WIN(cy)->image + sx;
142
		cpe = WIN(cy)->image + flayer->l_width;
157
			cpe = WIN(cy)->image + flayer->l_width;
143
		pp = (unsigned char *)pattern;
158
      pp = (unsigned char *)pattern;
144
		for (;;) {
159
      for (;;)
145
			if (*cp != *pp)
160
	{
146
				if (!search_ic || ((*cp ^ *pp) & 0xdf) ||
161
	  if (*cp != *pp)
147
				    (*cp | 0x20) < 'a' || (*cp | 0x20) > 'z')
162
	    if (!search_ic || ((*cp ^ *pp) & 0xdf) || (*cp | 0x20) < 'a' || (*cp | 0x20) > 'z')
148
					break;
163
	      break;
149
			cp++;
164
	  cp++;
150
			pp++;
165
	  pp++;
151
			if (*pp == 0)
166
	  if (*pp == 0)
152
				return sx;
167
	    return sx;
153
			if (cp == cpe) {
168
		if (cp == cpe) {
169
		/*
154
		/*
170
		* We have a partial match, but we've hit
155
		* We have a partial match, but we've hit
171
		* the end of this line.  Does it wrap onto
156
		* the end of this line.  Does it wrap onto
172
		* the following line?  If not, we're done.
157
		* the following line?  If not, we're done.
173
		*/
158
		*/
174
		if (*cp == ' ' || cy >= fore->w_histheight + flayer->l_height - 1)
159
				if (*cp == ' ' ||
175
			break;
160
				    cy >=
161
				    fore->w_histheight + flayer->l_height - 1)
162
					break;
176
163
177
		/*
164
		/*
178
		* This line does wrap, so look on the next
165
		* This line does wrap, so look on the next
179
		* line for the rest of our match.
166
		* line for the rest of our match.
180
		*/
167
		*/
181
		cy++;
168
				cy++;
182
		cp = WIN(cy)->image;
169
				cp = WIN(cy)->image;
183
		cpe = WIN(cy)->image + flayer->l_width;
170
				cpe = WIN(cy)->image + flayer->l_width;
171
			}
184
		}
172
		}
185
	}
173
	}
186
    }
174
	return -1;
187
  return -1;
188
}
175
}
189
176
190
191
/********************************************************************
177
/********************************************************************
192
 *  Emacs style ISearch
178
 *  Emacs style ISearch
193
 */
179
 */
194
180
195
static char *isprompts[] = {
181
static char *isprompts[] = {
196
  "I-search backward: ", "failing I-search backward: ",
182
	"I-search backward: ", "failing I-search backward: ",
197
  "I-search: ", "failing I-search: "
183
	"I-search: ", "failing I-search: "
198
};
184
};
199
185
200
186
static int  is_redo __P((struct markdata*));
201
static int  is_redo __P((struct markdata *));
187
static void is_process __P((char*, int, char *));
202
static void is_process __P((char *, int, char *));
188
static int  is_bm __P((char*, int, int, int, int));
203
static int  is_bm __P((char *, int, int, int, int));
204
205
189
206
static int
190
static int
207
is_bm(str, l, p, end, dir)
191
is_bm(char *str, int l, int p, int end, int dir)
208
char *str;
209
int l, p, end, dir;
210
{
192
{
211
  int tab[256];
193
	int tab[256];
212
  int i, q;
194
	int i, q;
213
  unsigned char *s, c;
195
	unsigned char *s, c;
214
  int w = flayer->l_width;
196
	int w = flayer->l_width;
215
197
216
  /* *sigh* to make WIN work */
198
  /* *sigh* to make WIN work */
217
  fore = ((struct markdata *)flayer->l_next->l_data)->md_window;
199
	fore = ((struct markdata *)flayer->l_next->l_data)->md_window;
218
  debug2("is_bm: searching for %s len %d\n", str, l);
200
	debug2("is_bm: searching for %s len %d\n", str, l);
219
  debug3("start at %d end %d dir %d\n", p, end, dir);
201
	debug3("start at %d end %d dir %d\n", p, end, dir);
220
  if (p < 0 || p + l > end)
202
221
    return -1;
203
	if (p < 0 || p + l > end)
222
  if (l == 0)
204
		return -1;
223
    return p;
205
	if (l == 0)
224
  if (dir < 0)
206
		return p;
225
    str += l - 1;
207
	if (dir < 0)
226
  for (i = 0; i < 256; i++)
208
		str += l - 1;
227
    tab[i] = l * dir;
209
	for (i = 0; i < 256; i++)
228
  for (i = 0; i < l - 1; i++, str += dir)
210
		tab[i] = l * dir;
229
    {
211
230
      q = *(unsigned char *)str;
212
	for (i = 0; i < l - 1; i++, str += dir) {
231
      tab[q] = (l - 1 - i) * dir;
213
		q = *(unsigned char *)str;
232
      if (search_ic && (q | 0x20) >= 'a' && ((q | 0x20) <= 'z'))
214
		tab[q] = (l - 1 - i) * dir;
233
        tab[q ^ 0x20] = (l - 1 - i) * dir;
215
		if (search_ic && (q | 0x20) >= 'a' && ((q | 0x20) <= 'z'))
234
    }
216
			tab[q ^ 0x20] = (l - 1 - i) * dir;
235
  if (dir > 0)
236
    p += l - 1;
237
  debug1("first char to match: %c\n", *str);
238
  while (p >= 0 && p < end)
239
    {
240
      q = p;
241
      s = (unsigned char *)str;
242
      for (i = 0;;)
243
	{
244
          c = (WIN(q / w))->image[q % w];
245
	  if (i == 0)
246
            p += tab[(int)(unsigned char) c];
247
	  if (c != *s)
248
	    if (!search_ic || ((c ^ *s) & 0xdf) || (c | 0x20) < 'a' || (c | 0x20) > 'z')
249
	      break;
250
	  q -= dir;
251
	  s -= dir;
252
	  if (++i == l)
253
	    return q + (dir > 0 ? 1 : -l);
254
	}
217
	}
255
    }
256
  return -1;
257
}
258
218
219
	if (dir > 0)
220
		p += l - 1;
221
222
	debug1("first char to match: %c\n", *str);
223
224
	while (p >= 0 && p < end) {
225
		q = p;
226
		s = (unsigned char *)str;
227
		for (i = 0;;) {
228
			c = (WIN(q / w))->image[q % w];
229
			if (i == 0)
230
				p += tab[(int)(unsigned char)c];
231
			if (c != *s)
232
				if (!search_ic || ((c ^ *s) & 0xdf) ||
233
				    (c | 0x20) < 'a' || (c | 0x20) > 'z')
234
					break;
235
			q -= dir;
236
			s -= dir;
237
			if (++i == l)
238
				return q + (dir > 0 ? 1 : -l);
239
		}
240
	}
241
	return -1;
242
}
259
243
260
/*ARGSUSED*/
244
/*ARGSUSED*/
261
static void
245
static void
262
is_process(p, n, data)	/* i-search */
246
is_process(char *p, int n, char *data)	/* i-search */
263
char *p;
264
int n;
265
char *data;	/* dummy */
266
{
247
{
267
  int pos, x, y, dir;
248
	int pos, x, y, dir;
268
  struct markdata *markdata;
249
	struct markdata *markdata;
269
250
270
  if (n == 0)
251
	if (n == 0)
271
    return;
252
		return;
272
  ASSERT(p);
253
	ASSERT(p);
273
  markdata = (struct markdata *)flayer->l_next->l_data;
254
	markdata = (struct markdata *)flayer->l_next->l_data;
274
255
275
  pos = markdata->cx + markdata->cy * flayer->l_width;
256
	pos = markdata->cx + markdata->cy * flayer->l_width;
276
  LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
257
	LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
277
258
278
  switch (*p)
259
	switch (*p) {
279
    {
260
	case '\007':	/* CTRL-G */
280
    case '\007':	/* CTRL-G */
261
		pos = markdata->isstartpos;
281
      pos = markdata->isstartpos;
282
      /*FALLTHROUGH*/
262
      /*FALLTHROUGH*/
283
    case '\033':	/* ESC */
263
	case '\033':	/* ESC */
284
      *p = 0;
264
		*p = 0;
285
      break;
265
		break;
286
    case '\013':	/* CTRL-K */
266
	case '\013':	/* CTRL-K */
287
    case '\027':	/* CTRL-W */
267
	case '\027':	/* CTRL-W */
288
      markdata->isistrl = 1;
268
		markdata->isistrl = 1;
289
      /*FALLTHROUGH*/
269
      /*FALLTHROUGH*/
290
    case '\b':
270
	case '\b':
291
    case '\177':
271
	case '\177':
292
      if (markdata->isistrl == 0)
272
		if (markdata->isistrl == 0)
293
	return;
273
			return;
294
      markdata->isistrl--;
274
		markdata->isistrl--;
295
      pos = is_redo(markdata);
275
		pos = is_redo(markdata);
296
      *p = '\b';
276
		*p = '\b';
297
      break;
277
		break;
298
    case '\023':	/* CTRL-S */
278
	case '\023':	/* CTRL-S */
299
    case '\022': 	/* CTRL-R */
279
	case '\022': 	/* CTRL-R */
300
      if (markdata->isistrl >= (int)sizeof(markdata->isistr))
280
		if (markdata->isistrl >= (int)sizeof(markdata->isistr))
301
	return;
281
			return;
302
      dir = (*p == '\023') ? 1 : -1;
282
		dir = (*p == '\023') ? 1 : -1;
303
      pos += dir;
283
		pos += dir;
304
      if (markdata->isdir == dir && markdata->isistrl == 0)
284
		if (markdata->isdir == dir && markdata->isistrl == 0) {
305
	{
285
			strcpy(markdata->isistr, markdata->isstr);
306
	  strcpy(markdata->isistr, markdata->isstr);
286
			markdata->isistrl = markdata->isstrl = strlen(markdata->isstr);
307
	  markdata->isistrl = markdata->isstrl = strlen(markdata->isstr);
287
			break;
308
	  break;
288
		}
289
		markdata->isdir = dir;
290
		markdata->isistr[markdata->isistrl++] = *p;
291
		break;
292
	default:
293
		if (*p < ' ' ||
294
		    markdata->isistrl >=
295
		    (int)sizeof(markdata->isistr) ||
296
		    markdata->isstrl >= (int)sizeof(markdata->isstr) - 1)
297
			return;
298
		markdata->isstr[markdata->isstrl++] = *p;
299
		markdata->isistr[markdata->isistrl++] = *p;
300
		markdata->isstr[markdata->isstrl] = 0;
301
		debug2("New char: %c - left %d\n", *p,
302
		    (int)sizeof(markdata->isistr) - markdata->isistrl);
309
	}
303
	}
310
      markdata->isdir = dir;
304
	if (*p && *p != '\b')
311
      markdata->isistr[markdata->isistrl++] = *p;
305
		pos = is_bm(markdata->isstr, markdata->isstrl, pos,
312
      break;
306
		    flayer->l_width *
313
    default:
307
		    (markdata->md_window->w_histheight + flayer->l_height),
314
      if (*p < ' ' || markdata->isistrl >= (int)sizeof(markdata->isistr)
308
		    markdata->isdir);
315
	  || markdata->isstrl >= (int)sizeof(markdata->isstr) - 1)
309
	if (pos >= 0) {
316
	return;
310
		x = pos % flayer->l_width;
317
      markdata->isstr[markdata->isstrl++] = *p;
311
		y = pos / flayer->l_width;
318
      markdata->isistr[markdata->isistrl++] = *p;
312
		LAY_CALL_UP(LayRedisplayLine(INPUTLINE, 0, flayer -> l_width - 1,
319
      markdata->isstr[markdata->isstrl] = 0;
313
		0) ; revto(x, y) ; if(W2D(markdata -> cy) == INPUTLINE) revto_line(markdata
320
      debug2("New char: %c - left %d\n", *p, (int)sizeof(markdata->isistr) - markdata->isistrl);
314
		-> cx, markdata -> cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1) ;);
321
    }
315
	}
322
  if (*p && *p != '\b')
316
	if (*p)
323
    pos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), markdata->isdir);
317
		inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1],
324
  if (pos >= 0)
318
		    markdata->isstrl ? markdata->isstr : "");
325
    {
319
	flayer->l_x = markdata->cx;
326
      x = pos % flayer->l_width;
320
	flayer->l_y = W2D(markdata->cy);
327
      y = pos / flayer->l_width;
321
	LGotoPos(flayer, flayer->l_x, flayer->l_y);
328
      LAY_CALL_UP
322
	if (!*p) {
329
	(
330
          LayRedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0);
331
          revto(x, y);
332
          if (W2D(markdata->cy) == INPUTLINE)
333
	    revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1);
334
        );
335
    }
336
  if (*p)
337
    inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], markdata->isstrl ? markdata->isstr : "");
338
  flayer->l_x = markdata->cx;
339
  flayer->l_y = W2D(markdata->cy);
340
  LGotoPos(flayer, flayer->l_x, flayer->l_y);
341
  if (!*p)
342
    {
343
      /* we are about to finish, keep cursor position */
323
      /* we are about to finish, keep cursor position */
344
      flayer->l_next->l_x = markdata->cx;
324
		flayer->l_next->l_x = markdata->cx;
345
      flayer->l_next->l_y = W2D(markdata->cy);
325
		flayer->l_next->l_y = W2D(markdata->cy);
346
    }
326
	}
347
}
327
}
348
328
349
static int
329
static int
350
is_redo(markdata)
330
is_redo(struct markdata *markdata)
351
struct markdata *markdata;
352
{
331
{
353
  int i, pos, npos, dir;
332
	int i, pos, npos, dir;
354
  char c;
333
	char c;
355
334
356
  npos = pos = markdata->isstartpos;
335
	npos = pos = markdata->isstartpos;
357
  dir = markdata->isstartdir;
336
	dir = markdata->isstartdir;
358
  markdata->isstrl = 0;
337
	markdata->isstrl = 0;
359
  for (i = 0; i < markdata->isistrl; i++)
338
360
    {
339
	for (i = 0; i < markdata->isistrl; i++) {
361
      c = markdata->isistr[i];
340
		c = markdata->isistr[i];
362
      if (c == '\022')		/* ^R */
341
		if (c == '\022')		/* ^R */
363
	pos += (dir = -1);
342
			pos += (dir = -1);
364
      else if (c == '\023')	/* ^S */
343
		else if (c == '\023')	/* ^S */
365
	pos += (dir = 1);
344
			pos += (dir = 1);
366
      else
345
		else
367
	markdata->isstr[markdata->isstrl++] = c;
346
			markdata->isstr[markdata->isstrl++] = c;
368
      if (pos >= 0)
347
		if (pos >= 0) {
369
	{
348
			npos = is_bm(markdata->isstr, markdata->isstrl, pos,
370
          npos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), dir);
349
			    flayer->l_width *
371
	  if (npos >= 0)
350
			    (markdata->md_window->w_histheight +
372
	    pos = npos;
351
			     flayer->l_height), dir);
352
			if (npos >= 0)
353
				pos = npos;
354
		}
373
	}
355
	}
374
    }
356
	markdata->isstr[markdata->isstrl] = 0;
375
  markdata->isstr[markdata->isstrl] = 0;
357
	markdata->isdir = dir;
376
  markdata->isdir = dir;
358
	return npos;
377
  return npos;
378
}
359
}
379
360
380
void
361
void
381
ISearch(dir)
362
ISearch(int dir)
382
int dir;
383
{
363
{
384
  struct markdata *markdata;
364
	struct markdata *markdata;
385
365
386
  markdata = (struct markdata *)flayer->l_data;
366
	markdata = (struct markdata *)flayer->l_data;
387
  markdata->isdir = markdata->isstartdir = dir;
367
	markdata->isdir = markdata->isstartdir = dir;
388
  markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width;
368
	markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width;
389
  markdata->isistrl = markdata->isstrl = 0;
369
	markdata->isistrl = markdata->isstrl = 0;
390
  if (W2D(markdata->cy) == INPUTLINE)
370
391
    revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1);
371
	if (W2D(markdata->cy) == INPUTLINE)
392
  Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW,
372
		revto_line(markdata->cx, markdata->cy,
393
        is_process, NULL, 0);
373
		    INPUTLINE > 0 ? INPUTLINE - 1 : 1);
394
  LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
374
395
  flayer->l_x = markdata->cx;
375
	Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW,
396
  flayer->l_y = W2D(markdata->cy);
376
	    is_process, NULL, 0);
377
378
	LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
379
	flayer->l_x = markdata->cx;
380
	flayer->l_y = W2D(markdata->cy);
397
}
381
}
398
382
399
#endif /* COPY_PASTE */
383
#endif /* COPY_PASTE */
(-)screen.orig/socket.c (-8 / +5 lines)
Lines 393-402 Link Here
393
    }
393
    }
394
  if (ndead && !quietflag)
394
  if (ndead && !quietflag)
395
    {
395
    {
396
      char *m = "Remove dead screens with 'screen -wipe'.";
396
      if (wipeflag)
397
      if (wipeflag)
397
        Msg(0, "%d socket%s wiped out.", nwipe, nwipe > 1 ? "s" : "");
398
        Msg(0, "%d socket%s wiped out.", nwipe, nwipe > 1 ? "s" : "");
398
      else
399
      else
399
        Msg(0, "Remove dead screen%s with 'screen -wipe'.", ndead > 1 ? "s" : "");
400
        Msg(0, m, ndead > 1 ? "s" : "", ndead > 1 ? "" : "es");	/* other args for nethack */
400
    }
401
    }
401
  if (firsts != -1)
402
  if (firsts != -1)
402
    {
403
    {
Lines 462-468 Link Here
462
# ifdef USE_SETEUID
463
# ifdef USE_SETEUID
463
  (void) unlink(SockPath);
464
  (void) unlink(SockPath);
464
  if (mkfifo(SockPath, SOCKMODE) < 0)
465
  if (mkfifo(SockPath, SOCKMODE) < 0)
465
    Panic(errno, "mkfifo %s failed", SockPath);
466
    Panic(0, "mkfifo %s failed", SockPath);
466
#  ifdef BROKEN_PIPE
467
#  ifdef BROKEN_PIPE
467
  s = open(SockPath, O_RDWR | O_NONBLOCK, 0);
468
  s = open(SockPath, O_RDWR | O_NONBLOCK, 0);
468
#  else
469
#  else
Lines 753-763 Link Here
753
  m.m_tty[sizeof(m.m_tty) - 1] = 0;
754
  m.m_tty[sizeof(m.m_tty) - 1] = 0;
754
  m.protocol_revision = MSG_REVISION;
755
  m.protocol_revision = MSG_REVISION;
755
  debug1("SendErrorMsg(): writing to '%s'\n", SockPath);
756
  debug1("SendErrorMsg(): writing to '%s'\n", SockPath);
756
  if (write(s, &m, sizeof(m)) < sizeof(m))
757
  (void) write(s, (char *) &m, sizeof m);
757
    {
758
      close(s);
759
      return -1;
760
    }
761
  close(s);
758
  close(s);
762
  return 0;
759
  return 0;
763
}
760
}
Lines 1879-1885 Link Here
1879
    {
1876
    {
1880
      char *oldrcname = rc_name;
1877
      char *oldrcname = rc_name;
1881
      rc_name = "-X";
1878
      rc_name = "-X";
1882
      debug3("Running command on display %p window %p (%d)\n", display, fore, fore ? fore->w_number : -1);
1879
      debug3("Running command on display %x window %x (%d)\n", display, fore, fore ? fore->w_number : -1);
1883
      flayer = fore ? &fore->w_layer : 0;
1880
      flayer = fore ? &fore->w_layer : 0;
1884
      if (fore && fore->w_savelayer && (fore->w_blocked || fore->w_savelayer->l_cvlist == 0))
1881
      if (fore && fore->w_savelayer && (fore->w_blocked || fore->w_savelayer->l_cvlist == 0))
1885
	flayer = fore->w_savelayer;
1882
	flayer = fore->w_savelayer;
(-)screen.orig/teln.c (-3 / +3 lines)
Lines 280-286 Link Here
280
	      break;
280
	      break;
281
	    }
281
	    }
282
	  if (l)
282
	  if (l)
283
	    memmove(p + 1, p, l);
283
	    bcopy(p, p + 1, l);
284
	  if (c == TC_IAC)
284
	  if (c == TC_IAC)
285
	    *p++ = c;
285
	    *p++ = c;
286
	  else if (c == '\r')
286
	  else if (c == '\r')
Lines 369-375 Link Here
369
	      if (free-- > 0)
369
	      if (free-- > 0)
370
		{
370
		{
371
		  if (len)
371
		  if (len)
372
		    memmove(rp + 1, rp, len);
372
		    bcopy(rp, rp + 1, len);
373
		  rp++;
373
		  rp++;
374
		  *wp++ = '\r';
374
		  *wp++ = '\r';
375
		}
375
		}
Lines 397-403 Link Here
397
      Msg(0, "Warning: telnet protocol overrun!");
397
      Msg(0, "Warning: telnet protocol overrun!");
398
      return;
398
      return;
399
    }
399
    }
400
  memcpy(p->w_inbuf + p->w_inlen, str, len);
400
  bcopy(str, p->w_inbuf + p->w_inlen, len);
401
  p->w_inlen += len;
401
  p->w_inlen += len;
402
}
402
}
403
403
(-)screen.orig/termcap.c (-1 / +1 lines)
Lines 1068-1074 Link Here
1068
	{
1068
	{
1069
	  if (i >= T_KEYPAD)	/* don't put keypad codes in TERMCAP */
1069
	  if (i >= T_KEYPAD)	/* don't put keypad codes in TERMCAP */
1070
	    continue;		/* - makes it too big */
1070
	    continue;		/* - makes it too big */
1071
#if (TERMCAP_BUF < 1024)
1071
#if (TERMCAP_BUFSIZE < 1024)
1072
          if (i >= T_FEXTRA && i < T_BACKTAB) /* also skip extra vt220 keys */
1072
          if (i >= T_FEXTRA && i < T_BACKTAB) /* also skip extra vt220 keys */
1073
            continue;
1073
            continue;
1074
          if (i > T_BACKTAB && i < T_NAVIGATE) /* more vt220 keys */
1074
          if (i > T_BACKTAB && i < T_NAVIGATE) /* more vt220 keys */
(-)screen.orig/utmp.c (-7 / +4 lines)
Lines 505-515 Link Here
505
  slot_t slot;
505
  slot_t slot;
506
506
507
  slot = wi->w_slot;
507
  slot = wi->w_slot;
508
#ifdef GETUTENT
509
  debug1("RemoveUtmp slot=%p\n", slot);
510
#else
511
  debug1("RemoveUtmp slot=%#x\n", slot);
508
  debug1("RemoveUtmp slot=%#x\n", slot);
512
#endif
513
  if (!utmpok)
509
  if (!utmpok)
514
    return -1;
510
    return -1;
515
  if (slot == (slot_t)0 || slot == (slot_t)-1)
511
  if (slot == (slot_t)0 || slot == (slot_t)-1)
Lines 581-591 Link Here
581
#ifdef HAVE_UTEMPTER
577
#ifdef HAVE_UTEMPTER
582
  if (eff_uid && wi && wi->w_ptyfd != -1)
578
  if (eff_uid && wi && wi->w_ptyfd != -1)
583
    {
579
    {
584
      utempter_set_helper ("/usr/lib/screen/utempter"); /* %_libexecdir */
580
      /* sigh, linux hackers made the helper functions void */
585
      if (SLOT_USED(u))
581
      if (SLOT_USED(u))
586
	return utempter_add_record (wi->w_ptyfd, host);
582
	addToUtmp(wi->w_tty, host, wi->w_ptyfd);
587
      else
583
      else
588
	return utempter_remove_record (wi->w_ptyfd);
584
	removeLineFromUtmp(wi->w_tty, wi->w_ptyfd);
585
      return 1;	/* pray for success */
589
    }
586
    }
590
#endif
587
#endif
591
  setutent();
588
  setutent();
(-)screen.orig/window.c (-35 / +23 lines)
Lines 979-988 Link Here
979
  if (wp->w_type == W_TYPE_PTY)
979
  if (wp->w_type == W_TYPE_PTY)
980
    {
980
    {
981
      /* pty 4 SALE */
981
      /* pty 4 SALE */
982
      if (fchown(wp->w_ptyfd, 0, 0) < 0)
982
      (void)chmod(wp->w_tty, 0666);
983
	;
983
      (void)chown(wp->w_tty, 0, 0);
984
      if (fchmod(wp->w_ptyfd, 0666) < 0)
985
	;
986
    }
984
    }
987
  close(wp->w_ptyfd);
985
  close(wp->w_ptyfd);
988
  wp->w_ptyfd = -1;
986
  wp->w_ptyfd = -1;
Lines 1247-1253 Link Here
1247
      args = ShellArgs;
1245
      args = ShellArgs;
1248
      proc = *args;
1246
      proc = *args;
1249
    }
1247
    }
1250
  fflush(NULL);
1248
  fflush(stdout);
1249
  fflush(stderr);
1251
  switch (pid = fork())
1250
  switch (pid = fork())
1252
    {
1251
    {
1253
    case -1:
1252
    case -1:
Lines 1294-1309 Link Here
1294
#endif
1293
#endif
1295
      if (slave != -1)
1294
      if (slave != -1)
1296
	{
1295
	{
1297
	  /* preserver slave across closeallfiles(), along with w_ptyfd */
1296
	  close(0);
1298
	  if (dup2(slave, 0) < 0)
1297
	  dup(slave);
1299
	    Panic(errno, "ForkWindow dup2");
1298
	  close(slave);
1300
	  if (slave > 0)
1301
	    close(slave);
1302
	  closeallfiles(win->w_ptyfd);
1299
	  closeallfiles(win->w_ptyfd);
1303
	  if (dup2(0, slave) < 0)
1300
	  slave = dup(0);
1304
	    Panic(errno, "ForkWindow dup2");
1305
	  if (slave > 0)
1306
	    close(0);
1307
	}
1301
	}
1308
      else
1302
      else
1309
        closeallfiles(win->w_ptyfd);
1303
        closeallfiles(win->w_ptyfd);
Lines 1320-1329 Link Here
1320
	}
1314
	}
1321
      debug1("=== ForkWindow: pid %d\n", (int)getpid());
1315
      debug1("=== ForkWindow: pid %d\n", (int)getpid());
1322
#endif
1316
#endif
1317
      /* Close the three /dev/null descriptors */
1318
      close(0);
1319
      close(1);
1320
      close(2);
1321
      newfd = -1;
1323
      /*
1322
      /*
1324
       * distribute filedescriptors between the ttys
1323
       * distribute filedescriptors between the ttys
1325
       */
1324
       */
1326
      newfd = -1;
1327
#ifdef PSEUDOS
1325
#ifdef PSEUDOS
1328
      pat = pwin ? pwin->p_fdpat : 
1326
      pat = pwin ? pwin->p_fdpat : 
1329
		   ((F_PFRONT<<(F_PSHIFT*2)) | (F_PFRONT<<F_PSHIFT) | F_PFRONT);
1327
		   ((F_PFRONT<<(F_PSHIFT*2)) | (F_PFRONT<<F_PSHIFT) | F_PFRONT);
Lines 1346-1358 Link Here
1346
		  if (newfd < 0)
1344
		  if (newfd < 0)
1347
		    Panic(errno, "Cannot open %s", ttyn);
1345
		    Panic(errno, "Cannot open %s", ttyn);
1348
		}
1346
		}
1349
	      if (dup2(newfd, i) < 0)
1347
	      else
1350
		Panic(errno, "Cannot duplicate %s", ttyn);
1348
		dup(newfd);
1351
	    }
1349
	    }
1352
	  else
1350
	  else
1353
	    {
1351
	    {
1354
	      if (dup2(win->w_ptyfd, i) < 0)
1352
	      dup(win->w_ptyfd);
1355
		Panic(errno, "Cannot duplicate %s", win->w_tty);
1356
	      wfdused = 1;
1353
	      wfdused = 1;
1357
	    }
1354
	    }
1358
	}
1355
	}
Lines 1375-1392 Link Here
1375
# else
1372
# else
1376
      newfd = open(ttyn, O_RDWR);
1373
      newfd = open(ttyn, O_RDWR);
1377
# endif
1374
# endif
1378
      if (newfd < 0)
1375
      if (newfd != 0)
1379
	Panic(errno, "Cannot open %s", ttyn);
1376
	Panic(errno, "Cannot open %s", ttyn);
1380
      if (dup2(newfd, 0) < 0)
1377
      dup(0);
1381
	Panic(errno, "Cannot duplicate %s", ttyn);
1378
      dup(0);
1382
      if (dup2(newfd, 1) < 0)
1383
	Panic(errno, "Cannot duplicate %s", ttyn);
1384
      if (dup2(newfd, 2) < 0)
1385
	Panic(errno, "Cannot duplicate %s", ttyn);
1386
#endif /* PSEUDOS */
1379
#endif /* PSEUDOS */
1387
      if (win->w_ptyfd > 2)
1380
      close(win->w_ptyfd);
1388
        close(win->w_ptyfd);
1381
      if (slave != -1)
1389
      if (slave > 2)
1390
        close(slave);
1382
        close(slave);
1391
      if (newfd >= 0)
1383
      if (newfd >= 0)
1392
	{
1384
	{
Lines 1432-1439 Link Here
1432
	  /* Always turn off nonblocking mode */
1424
	  /* Always turn off nonblocking mode */
1433
	  (void)fcntl(newfd, F_SETFL, 0);
1425
	  (void)fcntl(newfd, F_SETFL, 0);
1434
	}
1426
	}
1435
      if (newfd > 2)
1436
	close(newfd);
1437
#ifndef TIOCSWINSZ
1427
#ifndef TIOCSWINSZ
1438
      sprintf(libuf, "LINES=%d", h);
1428
      sprintf(libuf, "LINES=%d", h);
1439
      sprintf(cobuf, "COLUMNS=%d", w);
1429
      sprintf(cobuf, "COLUMNS=%d", w);
Lines 1710-1719 Link Here
1710
    }
1700
    }
1711
#endif
1701
#endif
1712
  /* should be able to use CloseDevice() here */
1702
  /* should be able to use CloseDevice() here */
1713
  if (fchown(pwin->p_ptyfd, 0, 0) < 0)
1703
  (void)chmod(pwin->p_tty, 0666);
1714
    ;
1704
  (void)chown(pwin->p_tty, 0, 0);
1715
  if (fchmod(pwin->p_ptyfd, 0666) < 0)
1716
    ;
1717
  if (pwin->p_ptyfd >= 0)
1705
  if (pwin->p_ptyfd >= 0)
1718
    close(pwin->p_ptyfd);
1706
    close(pwin->p_ptyfd);
1719
  evdeq(&pwin->p_readev);
1707
  evdeq(&pwin->p_readev);

Return to bug 46359