~ubuntu-branches/debian/stretch/screen/stretch

« back to all changes in this revision

Viewing changes to .pc/50increase-max-TERM-length.patch/process.c

  • Committer: Package Import Robot
  • Author(s): Axel Beckert
  • Date: 2014-07-26 14:05:20 UTC
  • mfrom: (7.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20140726140520-68d50x42gevcjy5e
Tags: 4.2.1-2
* Upload to unstable again
* Enable parallel building

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2010
2
 
 *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3
 
 *      Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
4
 
 * Copyright (c) 2008, 2009
5
 
 *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
6
 
 *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
7
 
 *      Micah Cowan (micah@cowan.name)
8
 
 *      Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
9
 
 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
10
 
 *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
11
 
 *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
12
 
 * Copyright (c) 1987 Oliver Laumann
13
 
 *
14
 
 * This program is free software; you can redistribute it and/or modify
15
 
 * it under the terms of the GNU General Public License as published by
16
 
 * the Free Software Foundation; either version 3, or (at your option)
17
 
 * any later version.
18
 
 *
19
 
 * This program is distributed in the hope that it will be useful,
20
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 
 * GNU General Public License for more details.
23
 
 *
24
 
 * You should have received a copy of the GNU General Public License
25
 
 * along with this program (see the file COPYING); if not, see
26
 
 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
27
 
 * 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
28
 
 *
29
 
 ****************************************************************
30
 
 */
31
 
 
32
 
#include "config.h"
33
 
 
34
 
#include <sys/types.h>
35
 
#include <sys/stat.h>
36
 
#include <signal.h>
37
 
#include <fcntl.h>
38
 
#if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX)
39
 
# include <time.h>
40
 
#endif
41
 
#include <sys/time.h>
42
 
#ifndef sun
43
 
#include <sys/ioctl.h>
44
 
#endif
45
 
 
46
 
 
47
 
/* for solaris 2.1, Unixware (SVR4.2) and possibly others: */
48
 
#ifdef HAVE_STROPTS_H
49
 
# include <sys/stropts.h>
50
 
#endif
51
 
 
52
 
#include "screen.h"
53
 
#include "extern.h"
54
 
#include "logfile.h"
55
 
#include "layout.h"
56
 
#include "viewport.h"
57
 
#include "list_generic.h"
58
 
 
59
 
extern struct comm comms[];
60
 
extern char *rc_name;
61
 
extern char *RcFileName, *home;
62
 
extern char *BellString, *ActivityString, *ShellProg, *ShellArgs[];
63
 
extern char *hstatusstring, *captionstring, *timestring;
64
 
extern char *wliststr, *wlisttit;
65
 
extern int captionalways;
66
 
extern int queryflag;
67
 
extern char *hardcopydir, *screenlogfile, *logtstamp_string;
68
 
extern int log_flush, logtstamp_on, logtstamp_after;
69
 
extern char *VisualBellString;
70
 
extern int VBellWait, MsgWait, MsgMinWait, SilenceWait;
71
 
extern char SockPath[], *SockName;
72
 
extern int TtyMode, auto_detach, use_altscreen;
73
 
extern int iflag, maxwin;
74
 
extern int focusminwidth, focusminheight;
75
 
extern int use_hardstatus, visual_bell;
76
 
#ifdef COLOR
77
 
extern int attr2color[][4];
78
 
extern int nattr2color;
79
 
#endif
80
 
extern int hardstatusemu;
81
 
extern char *printcmd;
82
 
extern int default_startup;
83
 
extern int defobuflimit;
84
 
extern int defnonblock;
85
 
extern int defmousetrack;
86
 
extern int ZombieKey_destroy;
87
 
extern int ZombieKey_resurrect;
88
 
extern int ZombieKey_onerror;
89
 
#ifdef AUTO_NUKE
90
 
extern int defautonuke;
91
 
#endif
92
 
extern int separate_sids;
93
 
extern struct NewWindow nwin_default, nwin_undef;
94
 
#ifdef COPY_PASTE
95
 
extern int join_with_cr;
96
 
extern int compacthist;
97
 
extern int search_ic;
98
 
# ifdef FONT
99
 
extern int pastefont;
100
 
# endif
101
 
extern unsigned char mark_key_tab[];
102
 
extern char *BufferFile;
103
 
#endif
104
 
#ifdef POW_DETACH
105
 
extern char *BufferFile, *PowDetachString;
106
 
#endif
107
 
#ifdef MULTIUSER
108
 
extern struct acluser *EffectiveAclUser;        /* acl.c */
109
 
#endif
110
 
extern struct term term[];      /* terminal capabilities */
111
 
#ifdef MAPKEYS
112
 
extern char *kmapdef[];
113
 
extern char *kmapadef[];
114
 
extern char *kmapmdef[];
115
 
#endif
116
 
extern struct mchar mchar_so, mchar_null;
117
 
extern int renditions[];
118
 
extern int VerboseCreate;
119
 
#ifdef UTF8
120
 
extern char *screenencodings;
121
 
#endif
122
 
#ifdef DW_CHARS
123
 
extern int cjkwidth;
124
 
#endif
125
 
 
126
 
static int  CheckArgNum __P((int, char **));
127
 
static void ClearAction __P((struct action *));
128
 
static void SaveAction __P((struct action *, int, char **, int *));
129
 
static int  NextWindow __P((void));
130
 
static int  PreviousWindow __P((void));
131
 
static int  MoreWindows __P((void));
132
 
static void LogToggle __P((int));
133
 
static void ShowInfo __P((void));
134
 
static void ShowDInfo __P((void));
135
 
static struct win *WindowByName __P((char *));
136
 
static int  WindowByNumber __P((char *));
137
 
static int  ParseOnOff __P((struct action *, int *));
138
 
static int  ParseWinNum __P((struct action *, int *));
139
 
static int  ParseBase __P((struct action *, char *, int *, int, char *));
140
 
static int  ParseNum1000 __P((struct action *, int *));
141
 
static char **SaveArgs __P((char **));
142
 
static int  IsNum __P((char *, int));
143
 
static void Colonfin __P((char *, int, char *));
144
 
static void InputSelect __P((void));
145
 
static void InputSetenv __P((char *));
146
 
static void InputAKA __P((void));
147
 
#ifdef MULTIUSER
148
 
static int  InputSu __P((struct win *, struct acluser **, char *));
149
 
static void su_fin __P((char *, int, char *));
150
 
#endif
151
 
static void AKAfin __P((char *, int, char *));
152
 
#ifdef COPY_PASTE
153
 
static void copy_reg_fn __P((char *, int, char *));
154
 
static void ins_reg_fn __P((char *, int, char *));
155
 
#endif
156
 
static void process_fn __P((char *, int, char *));
157
 
#ifdef PASSWORD
158
 
static void pass1 __P((char *, int, char *));
159
 
static void pass2 __P((char *, int, char *));
160
 
#endif
161
 
#ifdef POW_DETACH
162
 
static void pow_detach_fn __P((char *, int, char *));
163
 
#endif
164
 
static void digraph_fn __P((char *, int, char *));
165
 
static int  digraph_find __P((const char *buf));
166
 
static void confirm_fn __P((char *, int, char *));
167
 
static int  IsOnDisplay __P((struct win *));
168
 
static void ResizeRegions __P((char *, int));
169
 
static void ResizeFin __P((char *, int, char *));
170
 
static struct action *FindKtab __P((char *, int));
171
 
static void SelectFin __P((char *, int, char *));
172
 
static void SelectLayoutFin __P((char *, int, char *));
173
 
 
174
 
 
175
 
extern struct layer *flayer;
176
 
extern struct display *display, *displays;
177
 
extern struct win *fore, *console_window, *windows;
178
 
extern struct acluser *users;
179
 
extern struct layout *layouts, *layout_attach, layout_last_marker;
180
 
extern struct layout *laytab[];
181
 
 
182
 
extern char screenterm[], HostName[], version[];
183
 
extern struct NewWindow nwin_undef, nwin_default;
184
 
extern struct LayFuncs WinLf, MarkLf;
185
 
 
186
 
extern int Z0width, Z1width;
187
 
extern int real_uid, real_gid;
188
 
 
189
 
#ifdef NETHACK
190
 
extern int nethackflag;
191
 
#endif
192
 
 
193
 
 
194
 
extern struct win **wtab;
195
 
 
196
 
#ifdef MULTIUSER
197
 
extern char *multi;
198
 
extern int maxusercount;
199
 
#endif
200
 
char NullStr[] = "";
201
 
 
202
 
struct plop plop_tab[MAX_PLOP_DEFS];
203
 
 
204
 
#ifndef PTYMODE
205
 
# define PTYMODE 0622
206
 
#endif
207
 
 
208
 
int TtyMode = PTYMODE;
209
 
int hardcopy_append = 0;
210
 
int all_norefresh = 0;
211
 
#ifdef ZMODEM
212
 
int zmodem_mode = 0;
213
 
char *zmodem_sendcmd;
214
 
char *zmodem_recvcmd;
215
 
static char *zmodes[4] = {"off", "auto", "catch", "pass"};
216
 
#endif
217
 
 
218
 
int idletimo;
219
 
struct action idleaction;
220
 
#ifdef BLANKER_PRG
221
 
char **blankerprg;
222
 
#endif
223
 
 
224
 
struct action ktab[256 + KMAP_KEYS];    /* command key translation table */
225
 
struct kclass {
226
 
  struct kclass *next;
227
 
  char *name;
228
 
  struct action ktab[256 + KMAP_KEYS];
229
 
};
230
 
struct kclass *kclasses;
231
 
 
232
 
#ifdef MAPKEYS
233
 
struct action umtab[KMAP_KEYS+KMAP_AKEYS];
234
 
struct action dmtab[KMAP_KEYS+KMAP_AKEYS];
235
 
struct action mmtab[KMAP_KEYS+KMAP_AKEYS];
236
 
struct kmap_ext *kmap_exts;
237
 
int kmap_extn;
238
 
static int maptimeout = 300;
239
 
#endif
240
 
 
241
 
#ifndef MAX_DIGRAPH
242
 
#define MAX_DIGRAPH 512
243
 
#endif
244
 
 
245
 
struct digraph
246
 
{
247
 
  unsigned char d[2];
248
 
  int value;
249
 
};
250
 
 
251
 
/* digraph table taken from old vim and rfc1345 */
252
 
static struct digraph digraphs[MAX_DIGRAPH + 1] = {
253
 
    {{' ', ' '},   0x00a0},   /* NO-BREAK SPACE */
254
 
    {{'N', 'S'},   0x00a0},   /* NO-BREAK SPACE */
255
 
    {{'~', '!'},   0x00a1},   /* INVERTED EXCLAMATION MARK */
256
 
    {{'!', '!'},   0x00a1},   /* INVERTED EXCLAMATION MARK */
257
 
    {{'!', 'I'},   0x00a1},   /* INVERTED EXCLAMATION MARK */
258
 
    {{'c', '|'},   0x00a2},   /* CENT SIGN */
259
 
    {{'c', 't'},   0x00a2},   /* CENT SIGN */
260
 
    {{'$', '$'},   0x00a3},   /* POUND SIGN */
261
 
    {{'P', 'd'},   0x00a3},   /* POUND SIGN */
262
 
    {{'o', 'x'},   0x00a4},   /* CURRENCY SIGN */
263
 
    {{'C', 'u'},   0x00a4},   /* CURRENCY SIGN */
264
 
    {{'C', 'u'},   0x00a4},   /* CURRENCY SIGN */
265
 
    {{'E', 'u'},   0x00a4},   /* CURRENCY SIGN */
266
 
    {{'Y', '-'},   0x00a5},   /* YEN SIGN */
267
 
    {{'Y', 'e'},   0x00a5},   /* YEN SIGN */
268
 
    {{'|', '|'},   0x00a6},   /* BROKEN BAR */
269
 
    {{'B', 'B'},   0x00a6},   /* BROKEN BAR */
270
 
    {{'p', 'a'},   0x00a7},   /* SECTION SIGN */
271
 
    {{'S', 'E'},   0x00a7},   /* SECTION SIGN */
272
 
    {{'"', '"'},   0x00a8},   /* DIAERESIS */
273
 
    {{'\'', ':'},  0x00a8},   /* DIAERESIS */
274
 
    {{'c', 'O'},   0x00a9},   /* COPYRIGHT SIGN */
275
 
    {{'C', 'o'},   0x00a9},   /* COPYRIGHT SIGN */
276
 
    {{'-', 'a'},   0x00aa},   /* FEMININE ORDINAL INDICATOR */
277
 
    {{'<', '<'},   0x00ab},   /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
278
 
    {{'-', ','},   0x00ac},   /* NOT SIGN */
279
 
    {{'N', 'O'},   0x00ac},   /* NOT SIGN */
280
 
    {{'-', '-'},   0x00ad},   /* SOFT HYPHEN */
281
 
    {{'r', 'O'},   0x00ae},   /* REGISTERED SIGN */
282
 
    {{'R', 'g'},   0x00ae},   /* REGISTERED SIGN */
283
 
    {{'-', '='},   0x00af},   /* MACRON */
284
 
    {{'\'', 'm'},  0x00af},   /* MACRON */
285
 
    {{'~', 'o'},   0x00b0},   /* DEGREE SIGN */
286
 
    {{'D', 'G'},   0x00b0},   /* DEGREE SIGN */
287
 
    {{'+', '-'},   0x00b1},   /* PLUS-MINUS SIGN */
288
 
    {{'2', '2'},   0x00b2},   /* SUPERSCRIPT TWO */
289
 
    {{'2', 'S'},   0x00b2},   /* SUPERSCRIPT TWO */
290
 
    {{'3', '3'},   0x00b3},   /* SUPERSCRIPT THREE */
291
 
    {{'3', 'S'},   0x00b3},   /* SUPERSCRIPT THREE */
292
 
    {{'\'', '\''}, 0x00b4},   /* ACUTE ACCENT */
293
 
    {{'j', 'u'},   0x00b5},   /* MICRO SIGN */
294
 
    {{'M', 'y'},   0x00b5},   /* MICRO SIGN */
295
 
    {{'p', 'p'},   0x00b6},   /* PILCROW SIGN */
296
 
    {{'P', 'I'},   0x00b6},   /* PILCROW SIGN */
297
 
    {{'~', '.'},   0x00b7},   /* MIDDLE DOT */
298
 
    {{'.', 'M'},   0x00b7},   /* MIDDLE DOT */
299
 
    {{',', ','},   0x00b8},   /* CEDILLA */
300
 
    {{'\'', ','},  0x00b8},   /* CEDILLA */
301
 
    {{'1', '1'},   0x00b9},   /* SUPERSCRIPT ONE */
302
 
    {{'1', 'S'},   0x00b9},   /* SUPERSCRIPT ONE */
303
 
    {{'-', 'o'},   0x00ba},   /* MASCULINE ORDINAL INDICATOR */
304
 
    {{'>', '>'},   0x00bb},   /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
305
 
    {{'1', '4'},   0x00bc},   /* VULGAR FRACTION ONE QUARTER */
306
 
    {{'1', '2'},   0x00bd},   /* VULGAR FRACTION ONE HALF */
307
 
    {{'3', '4'},   0x00be},   /* VULGAR FRACTION THREE QUARTERS */
308
 
    {{'~', '?'},   0x00bf},   /* INVERTED QUESTION MARK */
309
 
    {{'?', '?'},   0x00bf},   /* INVERTED QUESTION MARK */
310
 
    {{'?', 'I'},   0x00bf},   /* INVERTED QUESTION MARK */
311
 
    {{'A', '`'},   0x00c0},   /* LATIN CAPITAL LETTER A WITH GRAVE */
312
 
    {{'A', '!'},   0x00c0},   /* LATIN CAPITAL LETTER A WITH GRAVE */
313
 
    {{'A', '\''},  0x00c1},   /* LATIN CAPITAL LETTER A WITH ACUTE */
314
 
    {{'A', '^'},   0x00c2},   /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
315
 
    {{'A', '>'},   0x00c2},   /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
316
 
    {{'A', '~'},   0x00c3},   /* LATIN CAPITAL LETTER A WITH TILDE */
317
 
    {{'A', '?'},   0x00c3},   /* LATIN CAPITAL LETTER A WITH TILDE */
318
 
    {{'A', '"'},   0x00c4},   /* LATIN CAPITAL LETTER A WITH DIAERESIS */
319
 
    {{'A', ':'},   0x00c4},   /* LATIN CAPITAL LETTER A WITH DIAERESIS */
320
 
    {{'A', '@'},   0x00c5},   /* LATIN CAPITAL LETTER A WITH RING ABOVE */
321
 
    {{'A', 'A'},   0x00c5},   /* LATIN CAPITAL LETTER A WITH RING ABOVE */
322
 
    {{'A', 'E'},   0x00c6},   /* LATIN CAPITAL LETTER AE */
323
 
    {{'C', ','},   0x00c7},   /* LATIN CAPITAL LETTER C WITH CEDILLA */
324
 
    {{'E', '`'},   0x00c8},   /* LATIN CAPITAL LETTER E WITH GRAVE */
325
 
    {{'E', '!'},   0x00c8},   /* LATIN CAPITAL LETTER E WITH GRAVE */
326
 
    {{'E', '\''},  0x00c9},   /* LATIN CAPITAL LETTER E WITH ACUTE */
327
 
    {{'E', '^'},   0x00ca},   /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
328
 
    {{'E', '>'},   0x00ca},   /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
329
 
    {{'E', '"'},   0x00cb},   /* LATIN CAPITAL LETTER E WITH DIAERESIS */
330
 
    {{'E', ':'},   0x00cb},   /* LATIN CAPITAL LETTER E WITH DIAERESIS */
331
 
    {{'I', '`'},   0x00cc},   /* LATIN CAPITAL LETTER I WITH GRAVE */
332
 
    {{'I', '!'},   0x00cc},   /* LATIN CAPITAL LETTER I WITH GRAVE */
333
 
    {{'I', '\''},  0x00cd},   /* LATIN CAPITAL LETTER I WITH ACUTE */
334
 
    {{'I', '^'},   0x00ce},   /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
335
 
    {{'I', '>'},   0x00ce},   /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
336
 
    {{'I', '"'},   0x00cf},   /* LATIN CAPITAL LETTER I WITH DIAERESIS */
337
 
    {{'I', ':'},   0x00cf},   /* LATIN CAPITAL LETTER I WITH DIAERESIS */
338
 
    {{'D', '-'},   0x00d0},   /* LATIN CAPITAL LETTER ETH */
339
 
    {{'N', '~'},   0x00d1},   /* LATIN CAPITAL LETTER N WITH TILDE */
340
 
    {{'N', '?'},   0x00d1},   /* LATIN CAPITAL LETTER N WITH TILDE */
341
 
    {{'O', '`'},   0x00d2},   /* LATIN CAPITAL LETTER O WITH GRAVE */
342
 
    {{'O', '!'},   0x00d2},   /* LATIN CAPITAL LETTER O WITH GRAVE */
343
 
    {{'O', '\''},  0x00d3},   /* LATIN CAPITAL LETTER O WITH ACUTE */
344
 
    {{'O', '^'},   0x00d4},   /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
345
 
    {{'O', '>'},   0x00d4},   /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
346
 
    {{'O', '~'},   0x00d5},   /* LATIN CAPITAL LETTER O WITH TILDE */
347
 
    {{'O', '?'},   0x00d5},   /* LATIN CAPITAL LETTER O WITH TILDE */
348
 
    {{'O', '"'},   0x00d6},   /* LATIN CAPITAL LETTER O WITH DIAERESIS */
349
 
    {{'O', ':'},   0x00d6},   /* LATIN CAPITAL LETTER O WITH DIAERESIS */
350
 
    {{'/', '\\'},  0x00d7},   /* MULTIPLICATION SIGN */
351
 
    {{'*', 'x'},   0x00d7},   /* MULTIPLICATION SIGN */
352
 
    {{'O', '/'},   0x00d8},   /* LATIN CAPITAL LETTER O WITH STROKE */
353
 
    {{'U', '`'},   0x00d9},   /* LATIN CAPITAL LETTER U WITH GRAVE */
354
 
    {{'U', '!'},   0x00d9},   /* LATIN CAPITAL LETTER U WITH GRAVE */
355
 
    {{'U', '\''},  0x00da},   /* LATIN CAPITAL LETTER U WITH ACUTE */
356
 
    {{'U', '^'},   0x00db},   /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
357
 
    {{'U', '>'},   0x00db},   /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
358
 
    {{'U', '"'},   0x00dc},   /* LATIN CAPITAL LETTER U WITH DIAERESIS */
359
 
    {{'U', ':'},   0x00dc},   /* LATIN CAPITAL LETTER U WITH DIAERESIS */
360
 
    {{'Y', '\''},  0x00dd},   /* LATIN CAPITAL LETTER Y WITH ACUTE */
361
 
    {{'I', 'p'},   0x00de},   /* LATIN CAPITAL LETTER THORN */
362
 
    {{'T', 'H'},   0x00de},   /* LATIN CAPITAL LETTER THORN */
363
 
    {{'s', 's'},   0x00df},   /* LATIN SMALL LETTER SHARP S */
364
 
    {{'s', '"'},   0x00df},   /* LATIN SMALL LETTER SHARP S */
365
 
    {{'a', '`'},   0x00e0},   /* LATIN SMALL LETTER A WITH GRAVE */
366
 
    {{'a', '!'},   0x00e0},   /* LATIN SMALL LETTER A WITH GRAVE */
367
 
    {{'a', '\''},  0x00e1},   /* LATIN SMALL LETTER A WITH ACUTE */
368
 
    {{'a', '^'},   0x00e2},   /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
369
 
    {{'a', '>'},   0x00e2},   /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
370
 
    {{'a', '~'},   0x00e3},   /* LATIN SMALL LETTER A WITH TILDE */
371
 
    {{'a', '?'},   0x00e3},   /* LATIN SMALL LETTER A WITH TILDE */
372
 
    {{'a', '"'},   0x00e4},   /* LATIN SMALL LETTER A WITH DIAERESIS */
373
 
    {{'a', ':'},   0x00e4},   /* LATIN SMALL LETTER A WITH DIAERESIS */
374
 
    {{'a', 'a'},   0x00e5},   /* LATIN SMALL LETTER A WITH RING ABOVE */
375
 
    {{'a', 'e'},   0x00e6},   /* LATIN SMALL LETTER AE */
376
 
    {{'c', ','},   0x00e7},   /* LATIN SMALL LETTER C WITH CEDILLA */
377
 
    {{'e', '`'},   0x00e8},   /* LATIN SMALL LETTER E WITH GRAVE */
378
 
    {{'e', '!'},   0x00e8},   /* LATIN SMALL LETTER E WITH GRAVE */
379
 
    {{'e', '\''},  0x00e9},   /* LATIN SMALL LETTER E WITH ACUTE */
380
 
    {{'e', '^'},   0x00ea},   /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
381
 
    {{'e', '>'},   0x00ea},   /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
382
 
    {{'e', '"'},   0x00eb},   /* LATIN SMALL LETTER E WITH DIAERESIS */
383
 
    {{'e', ':'},   0x00eb},   /* LATIN SMALL LETTER E WITH DIAERESIS */
384
 
    {{'i', '`'},   0x00ec},   /* LATIN SMALL LETTER I WITH GRAVE */
385
 
    {{'i', '!'},   0x00ec},   /* LATIN SMALL LETTER I WITH GRAVE */
386
 
    {{'i', '\''},  0x00ed},   /* LATIN SMALL LETTER I WITH ACUTE */
387
 
    {{'i', '^'},   0x00ee},   /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
388
 
    {{'i', '>'},   0x00ee},   /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
389
 
    {{'i', '"'},   0x00ef},   /* LATIN SMALL LETTER I WITH DIAERESIS */
390
 
    {{'i', ':'},   0x00ef},   /* LATIN SMALL LETTER I WITH DIAERESIS */
391
 
    {{'d', '-'},   0x00f0},   /* LATIN SMALL LETTER ETH */
392
 
    {{'n', '~'},   0x00f1},   /* LATIN SMALL LETTER N WITH TILDE */
393
 
    {{'n', '?'},   0x00f1},   /* LATIN SMALL LETTER N WITH TILDE */
394
 
    {{'o', '`'},   0x00f2},   /* LATIN SMALL LETTER O WITH GRAVE */
395
 
    {{'o', '!'},   0x00f2},   /* LATIN SMALL LETTER O WITH GRAVE */
396
 
    {{'o', '\''},  0x00f3},   /* LATIN SMALL LETTER O WITH ACUTE */
397
 
    {{'o', '^'},   0x00f4},   /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
398
 
    {{'o', '>'},   0x00f4},   /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
399
 
    {{'o', '~'},   0x00f5},   /* LATIN SMALL LETTER O WITH TILDE */
400
 
    {{'o', '?'},   0x00f5},   /* LATIN SMALL LETTER O WITH TILDE */
401
 
    {{'o', '"'},   0x00f6},   /* LATIN SMALL LETTER O WITH DIAERESIS */
402
 
    {{'o', ':'},   0x00f6},   /* LATIN SMALL LETTER O WITH DIAERESIS */
403
 
    {{'-', ':'},   0x00f7},   /* DIVISION SIGN */
404
 
    {{'o', '/'},   0x00f8},   /* LATIN SMALL LETTER O WITH STROKE */
405
 
    {{'u', '`'},   0x00f9},   /* LATIN SMALL LETTER U WITH GRAVE */
406
 
    {{'u', '!'},   0x00f9},   /* LATIN SMALL LETTER U WITH GRAVE */
407
 
    {{'u', '\''},  0x00fa},   /* LATIN SMALL LETTER U WITH ACUTE */
408
 
    {{'u', '^'},   0x00fb},   /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
409
 
    {{'u', '>'},   0x00fb},   /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
410
 
    {{'u', '"'},   0x00fc},   /* LATIN SMALL LETTER U WITH DIAERESIS */
411
 
    {{'u', ':'},   0x00fc},   /* LATIN SMALL LETTER U WITH DIAERESIS */
412
 
    {{'y', '\''},  0x00fd},   /* LATIN SMALL LETTER Y WITH ACUTE */
413
 
    {{'i', 'p'},   0x00fe},   /* LATIN SMALL LETTER THORN */
414
 
    {{'t', 'h'},   0x00fe},   /* LATIN SMALL LETTER THORN */
415
 
    {{'y', '"'},   0x00ff},   /* LATIN SMALL LETTER Y WITH DIAERESIS */
416
 
    {{'y', ':'},   0x00ff},   /* LATIN SMALL LETTER Y WITH DIAERESIS */
417
 
    {{'"', '['},   0x00c4},   /* LATIN CAPITAL LETTER A WITH DIAERESIS */
418
 
    {{'"', '\\'},  0x00d6},   /* LATIN CAPITAL LETTER O WITH DIAERESIS */
419
 
    {{'"', ']'},   0x00dc},   /* LATIN CAPITAL LETTER U WITH DIAERESIS */
420
 
    {{'"', '{'},   0x00e4},   /* LATIN SMALL LETTER A WITH DIAERESIS */
421
 
    {{'"', '|'},   0x00f6},   /* LATIN SMALL LETTER O WITH DIAERESIS */
422
 
    {{'"', '}'},   0x00fc},   /* LATIN SMALL LETTER U WITH DIAERESIS */
423
 
    {{'"', '~'},   0x00df},   /* LATIN SMALL LETTER SHARP S */
424
 
};
425
 
 
426
 
#define RESIZE_FLAG_H 1
427
 
#define RESIZE_FLAG_V 2
428
 
#define RESIZE_FLAG_L 4
429
 
 
430
 
static char *resizeprompts[] = {
431
 
  "resize # lines: ",
432
 
  "resize -h # lines: ",
433
 
  "resize -v # lines: ",
434
 
  "resize -b # lines: ",
435
 
  "resize -l # lines: ",
436
 
  "resize -l -h # lines: ",
437
 
  "resize -l -v # lines: ",
438
 
  "resize -l -b # lines: ",
439
 
};
440
 
 
441
 
static int
442
 
parse_input_int(buf, len, val)
443
 
const char *buf;
444
 
int len;
445
 
int *val;
446
 
{
447
 
  int x = 0, i;
448
 
  if (len >= 1 && ((*buf == 'U' && buf[1] == '+') || (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X'))))
449
 
    {
450
 
      x = 0;
451
 
      for (i = 2; i < len; i++)
452
 
        {
453
 
          if (buf[i] >= '0' && buf[i] <= '9')
454
 
            x = x * 16 | (buf[i] - '0');
455
 
          else if (buf[i] >= 'a' && buf[i] <= 'f')
456
 
            x = x * 16 | (buf[i] - ('a' - 10));
457
 
          else if (buf[i] >= 'A' && buf[i] <= 'F')
458
 
            x = x * 16 | (buf[i] - ('A' - 10));
459
 
          else
460
 
            return 0;
461
 
        }
462
 
    }
463
 
  else if (buf[0] == '0')
464
 
    {
465
 
      x = 0;
466
 
      for (i = 1; i < len; i++)
467
 
        {
468
 
          if (buf[i] < '0' || buf[i] > '7')
469
 
            return 0;
470
 
          x = x * 8 | (buf[i] - '0');
471
 
        }
472
 
    }
473
 
  else
474
 
    return 0;
475
 
  *val = x;
476
 
  return 1;
477
 
}
478
 
 
479
 
char *noargs[1];
480
 
 
481
 
void
482
 
InitKeytab()
483
 
{
484
 
  register unsigned int i;
485
 
#ifdef MAPKEYS
486
 
  char *argarr[2];
487
 
#endif
488
 
 
489
 
  for (i = 0; i < sizeof(ktab)/sizeof(*ktab); i++)
490
 
    {
491
 
      ktab[i].nr = RC_ILLEGAL;
492
 
      ktab[i].args = noargs;
493
 
      ktab[i].argl = 0;
494
 
    }
495
 
#ifdef MAPKEYS
496
 
  for (i = 0; i < KMAP_KEYS+KMAP_AKEYS; i++)
497
 
    {
498
 
      umtab[i].nr = RC_ILLEGAL;
499
 
      umtab[i].args = noargs;
500
 
      umtab[i].argl = 0;
501
 
      dmtab[i].nr = RC_ILLEGAL;
502
 
      dmtab[i].args = noargs;
503
 
      dmtab[i].argl = 0;
504
 
      mmtab[i].nr = RC_ILLEGAL;
505
 
      mmtab[i].args = noargs;
506
 
      mmtab[i].argl = 0;
507
 
    }
508
 
  argarr[1] = 0;
509
 
  for (i = 0; i < NKMAPDEF; i++)
510
 
    {
511
 
      if (i + KMAPDEFSTART < T_CAPS)
512
 
        continue;
513
 
      if (i + KMAPDEFSTART >= T_CAPS + KMAP_KEYS)
514
 
        continue;
515
 
      if (kmapdef[i] == 0)
516
 
        continue;
517
 
      argarr[0] = kmapdef[i];
518
 
      SaveAction(dmtab + i + (KMAPDEFSTART - T_CAPS), RC_STUFF, argarr, 0);
519
 
    }
520
 
  for (i = 0; i < NKMAPADEF; i++)
521
 
    {
522
 
      if (i + KMAPADEFSTART < T_CURSOR)
523
 
        continue;
524
 
      if (i + KMAPADEFSTART >= T_CURSOR + KMAP_AKEYS)
525
 
        continue;
526
 
      if (kmapadef[i] == 0)
527
 
        continue;
528
 
      argarr[0] = kmapadef[i];
529
 
      SaveAction(dmtab + i + (KMAPADEFSTART - T_CURSOR + KMAP_KEYS), RC_STUFF, argarr, 0);
530
 
    }
531
 
  for (i = 0; i < NKMAPMDEF; i++)
532
 
    {
533
 
      if (i + KMAPMDEFSTART < T_CAPS)
534
 
        continue;
535
 
      if (i + KMAPMDEFSTART >= T_CAPS + KMAP_KEYS)
536
 
        continue;
537
 
      if (kmapmdef[i] == 0)
538
 
        continue;
539
 
      argarr[0] = kmapmdef[i];
540
 
      argarr[1] = 0;
541
 
      SaveAction(mmtab + i + (KMAPMDEFSTART - T_CAPS), RC_STUFF, argarr, 0);
542
 
    }
543
 
#endif
544
 
 
545
 
  ktab['h'].nr = RC_HARDCOPY;
546
 
#ifdef BSDJOBS
547
 
  ktab['z'].nr = ktab[Ctrl('z')].nr = RC_SUSPEND;
548
 
#endif
549
 
  ktab['c'].nr = ktab[Ctrl('c')].nr = RC_SCREEN;
550
 
  ktab[' '].nr = ktab[Ctrl(' ')].nr =
551
 
    ktab['n'].nr = ktab[Ctrl('n')].nr = RC_NEXT;
552
 
  ktab['N'].nr = RC_NUMBER;
553
 
  ktab[Ctrl('h')].nr = ktab[0177].nr = ktab['p'].nr = ktab[Ctrl('p')].nr = RC_PREV;
554
 
  ktab['k'].nr = ktab[Ctrl('k')].nr = RC_KILL;
555
 
  ktab['l'].nr = ktab[Ctrl('l')].nr = RC_REDISPLAY;
556
 
  ktab['w'].nr = ktab[Ctrl('w')].nr = RC_WINDOWS;
557
 
  ktab['v'].nr = RC_VERSION;
558
 
  ktab[Ctrl('v')].nr = RC_DIGRAPH;
559
 
  ktab['q'].nr = ktab[Ctrl('q')].nr = RC_XON;
560
 
  ktab['s'].nr = ktab[Ctrl('s')].nr = RC_XOFF;
561
 
  ktab['t'].nr = ktab[Ctrl('t')].nr = RC_TIME;
562
 
  ktab['i'].nr = ktab[Ctrl('i')].nr = RC_INFO;
563
 
  ktab['m'].nr = ktab[Ctrl('m')].nr = RC_LASTMSG;
564
 
  ktab['A'].nr = RC_TITLE;
565
 
#if defined(UTMPOK) && defined(LOGOUTOK)
566
 
  ktab['L'].nr = RC_LOGIN;
567
 
#endif
568
 
  ktab[','].nr = RC_LICENSE;
569
 
  ktab['W'].nr = RC_WIDTH;
570
 
  ktab['.'].nr = RC_DUMPTERMCAP;
571
 
  ktab[Ctrl('\\')].nr = RC_QUIT;
572
 
#ifdef DETACH
573
 
  ktab['d'].nr = ktab[Ctrl('d')].nr = RC_DETACH;
574
 
# ifdef POW_DETACH
575
 
  ktab['D'].nr = RC_POW_DETACH;
576
 
# endif
577
 
#endif
578
 
  ktab['r'].nr = ktab[Ctrl('r')].nr = RC_WRAP;
579
 
  ktab['f'].nr = ktab[Ctrl('f')].nr = RC_FLOW;
580
 
  ktab['C'].nr = RC_CLEAR;
581
 
  ktab['Z'].nr = RC_RESET;
582
 
  ktab['H'].nr = RC_LOG;
583
 
  ktab['M'].nr = RC_MONITOR;
584
 
  ktab['?'].nr = RC_HELP;
585
 
#ifdef MULTI
586
 
  ktab['*'].nr = RC_DISPLAYS;
587
 
#endif
588
 
  {
589
 
    char *args[2];
590
 
    args[0] = "-";
591
 
    args[1] = NULL;
592
 
    SaveAction(ktab + '-', RC_SELECT, args, 0);
593
 
  }
594
 
  for (i = 0; i < ((maxwin && maxwin < 10) ? maxwin : 10); i++)
595
 
    {
596
 
      char *args[2], arg1[10];
597
 
      args[0] = arg1;
598
 
      args[1] = 0;
599
 
      sprintf(arg1, "%d", i);
600
 
      SaveAction(ktab + '0' + i, RC_SELECT, args, 0);
601
 
    }
602
 
  ktab['\''].nr = RC_SELECT; /* calling a window by name */
603
 
  {
604
 
    char *args[2];
605
 
    args[0] = "-b";
606
 
    args[1] = 0;
607
 
    SaveAction(ktab + '"', RC_WINDOWLIST, args, 0);
608
 
  }
609
 
  ktab[Ctrl('G')].nr = RC_VBELL;
610
 
  ktab[':'].nr = RC_COLON;
611
 
#ifdef COPY_PASTE
612
 
  ktab['['].nr = ktab[Ctrl('[')].nr = RC_COPY;
613
 
  {
614
 
    char *args[2];
615
 
    args[0] = ".";
616
 
    args[1] = 0;
617
 
    SaveAction(ktab + ']', RC_PASTE, args, 0);
618
 
    SaveAction(ktab + Ctrl(']'), RC_PASTE, args, 0);
619
 
  }
620
 
  ktab['{'].nr = RC_HISTORY;
621
 
  ktab['}'].nr = RC_HISTORY;
622
 
  ktab['>'].nr = RC_WRITEBUF;
623
 
  ktab['<'].nr = RC_READBUF;
624
 
  ktab['='].nr = RC_REMOVEBUF;
625
 
#endif
626
 
#ifdef POW_DETACH
627
 
  ktab['D'].nr = RC_POW_DETACH;
628
 
#endif
629
 
#ifdef LOCK
630
 
  ktab['x'].nr = ktab[Ctrl('x')].nr = RC_LOCKSCREEN;
631
 
#endif
632
 
  ktab['b'].nr = ktab[Ctrl('b')].nr = RC_BREAK;
633
 
  ktab['B'].nr = RC_POW_BREAK;
634
 
  ktab['_'].nr = RC_SILENCE;
635
 
  ktab['S'].nr = RC_SPLIT;
636
 
  ktab['Q'].nr = RC_ONLY;
637
 
  ktab['X'].nr = RC_REMOVE;
638
 
  ktab['F'].nr = RC_FIT;
639
 
  ktab['\t'].nr = RC_FOCUS;
640
 
  {
641
 
    char *args[2];
642
 
    args[0] = "prev";
643
 
    args[1] = 0;
644
 
    SaveAction(ktab + T_BACKTAB - T_CAPS + 256, RC_FOCUS, args, 0);
645
 
  }
646
 
  {
647
 
    char *args[2];
648
 
    args[0] = "-v";
649
 
    args[1] = 0;
650
 
    SaveAction(ktab + '|', RC_SPLIT, args, 0);
651
 
  }
652
 
  /* These come last; they may want overwrite others: */
653
 
  if (DefaultEsc >= 0)
654
 
    {
655
 
      ClearAction(&ktab[DefaultEsc]);
656
 
      ktab[DefaultEsc].nr = RC_OTHER;
657
 
    }
658
 
  if (DefaultMetaEsc >= 0)
659
 
    {
660
 
      ClearAction(&ktab[DefaultMetaEsc]);
661
 
      ktab[DefaultMetaEsc].nr = RC_META;
662
 
    }
663
 
 
664
 
  idleaction.nr = RC_BLANKER;
665
 
  idleaction.args = noargs;
666
 
  idleaction.argl = 0;
667
 
}
668
 
 
669
 
static struct action *
670
 
FindKtab(class, create)
671
 
char *class;
672
 
int create;
673
 
{
674
 
  struct kclass *kp, **kpp;
675
 
  int i;
676
 
 
677
 
  if (class == 0)
678
 
    return ktab;
679
 
  for (kpp = &kclasses; (kp = *kpp) != 0; kpp = &kp->next)
680
 
    if (!strcmp(kp->name, class))
681
 
      break;
682
 
  if (kp == 0)
683
 
    {
684
 
      if (!create)
685
 
        return 0;
686
 
      if (strlen(class) > 80)
687
 
        {
688
 
          Msg(0, "Command class name too long.");
689
 
          return 0;
690
 
        }
691
 
      kp = malloc(sizeof(*kp));
692
 
      if (kp == 0)
693
 
        {
694
 
          Msg(0, "%s", strnomem);
695
 
          return 0;
696
 
        }
697
 
      kp->name = SaveStr(class);
698
 
      for (i = 0; i < (int)(sizeof(kp->ktab)/sizeof(*kp->ktab)); i++)
699
 
        {
700
 
          kp->ktab[i].nr = RC_ILLEGAL;
701
 
          kp->ktab[i].args = noargs;
702
 
          kp->ktab[i].argl = 0;
703
 
          kp->ktab[i].quiet = 0;
704
 
        }
705
 
      kp->next = 0;
706
 
      *kpp = kp;
707
 
    }
708
 
  return kp->ktab;
709
 
}
710
 
 
711
 
static void
712
 
ClearAction(act)
713
 
struct action *act;
714
 
{
715
 
  char **p;
716
 
 
717
 
  if (act->nr == RC_ILLEGAL)
718
 
    return;
719
 
  act->nr = RC_ILLEGAL;
720
 
  if (act->args == noargs)
721
 
    return;
722
 
  for (p = act->args; *p; p++)
723
 
    free(*p);
724
 
  free((char *)act->args);
725
 
  act->args = noargs;
726
 
  act->argl = 0;
727
 
}
728
 
 
729
 
/*
730
 
 * ProcessInput: process input from display and feed it into
731
 
 * the layer on canvas D_forecv.
732
 
 */
733
 
 
734
 
#ifdef MAPKEYS
735
 
 
736
 
/*
737
 
 *  This ProcessInput just does the keybindings and passes
738
 
 *  everything else on to ProcessInput2.
739
 
 */
740
 
 
741
 
void
742
 
ProcessInput(ibuf, ilen)
743
 
char *ibuf;
744
 
int ilen;
745
 
{
746
 
  int ch, slen;
747
 
  unsigned char *s, *q;
748
 
  int i, l;
749
 
  char *p;
750
 
 
751
 
  debug1("ProcessInput: %d bytes\n", ilen);
752
 
  if (display == 0 || ilen == 0)
753
 
    return;
754
 
  if (D_seql)
755
 
    evdeq(&D_mapev);
756
 
  slen = ilen;
757
 
  s = (unsigned char *)ibuf;
758
 
  while (ilen-- > 0)
759
 
    {
760
 
      ch = *s++;
761
 
      if (D_dontmap || !D_nseqs)
762
 
        {
763
 
          D_dontmap = 0;
764
 
          continue;
765
 
        }
766
 
      for (;;)
767
 
        {
768
 
          debug3("cmp %c %c[%d]\n", ch, *D_seqp, D_seqp - D_kmaps);
769
 
          if (*D_seqp != ch)
770
 
            {
771
 
              l = D_seqp[D_seqp[-D_seql-1] + 1];
772
 
              if (l)
773
 
                {
774
 
                  D_seqp += l * 2 + 4;
775
 
                  debug1("miss %d\n", D_seqp - D_kmaps);
776
 
                  continue;
777
 
                }
778
 
              debug("complete miss\n");
779
 
              D_mapdefault = 0;
780
 
              l = D_seql;
781
 
              p = (char *)D_seqp - l;
782
 
              D_seql = 0;
783
 
              D_seqp = D_kmaps + 3;
784
 
              if (l == 0)
785
 
                break;
786
 
              if ((q = D_seqh) != 0)
787
 
                {
788
 
                  D_seqh = 0;
789
 
                  i = q[0] << 8 | q[1];
790
 
                  i &= ~KMAP_NOTIMEOUT;
791
 
                  debug1("Mapping former hit #%d - ", i);
792
 
                  debug2("%d(%s) - ", q[2], q + 3);
793
 
                  if (StuffKey(i))
794
 
                    ProcessInput2((char *)q + 3, q[2]);
795
 
                  if (display == 0)
796
 
                    return;
797
 
                  l -= q[2];
798
 
                  p += q[2];
799
 
                }
800
 
              else
801
 
                D_dontmap = 1;
802
 
              debug1("flush old %d\n", l);
803
 
              ProcessInput(p, l);
804
 
              if (display == 0)
805
 
                return;
806
 
              evdeq(&D_mapev);
807
 
              continue;
808
 
            }
809
 
          if (D_seql++ == 0)
810
 
            {
811
 
              /* Finish old stuff */
812
 
              slen -= ilen + 1;
813
 
              debug1("finish old %d\n", slen);
814
 
              if (slen)
815
 
                ProcessInput2(ibuf, slen);
816
 
              if (display == 0)
817
 
                return;
818
 
              D_seqh = 0;
819
 
            }
820
 
          ibuf = (char *)s;
821
 
          slen = ilen;
822
 
          D_seqp++;
823
 
          l = D_seql;
824
 
          debug2("length am %d, want %d\n", l, D_seqp[-l - 1]);
825
 
          if (l == D_seqp[-l - 1])
826
 
            {
827
 
              if (D_seqp[l] != l)
828
 
                {
829
 
                  q = D_seqp + 1 + l;
830
 
                  if (D_kmaps + D_nseqs > q && q[2] > l && !bcmp(D_seqp - l, q + 3, l))
831
 
                    {
832
 
                      debug1("have another mapping (%s), delay execution\n", q + 3);
833
 
                      D_seqh = D_seqp - 3 - l;
834
 
                      D_seqp = q + 3 + l;
835
 
                      break;
836
 
                    }
837
 
                }
838
 
              i = D_seqp[-l - 3] << 8 | D_seqp[-l - 2];
839
 
              i &= ~KMAP_NOTIMEOUT;
840
 
              debug1("Mapping #%d - ", i);
841
 
              p = (char *)D_seqp - l;
842
 
              debug2("%d(%s) - ", l, p);
843
 
              D_seql = 0;
844
 
              D_seqp = D_kmaps + 3;
845
 
              D_seqh = 0;
846
 
              if (StuffKey(i))
847
 
                ProcessInput2(p, l);
848
 
              if (display == 0)
849
 
                return;
850
 
            }
851
 
          break;
852
 
        }
853
 
    }
854
 
  if (D_seql)
855
 
    {
856
 
      debug("am in sequence -> check for timeout\n");
857
 
      l = D_seql;
858
 
      for (s = D_seqp; ; s += i * 2 + 4)
859
 
        {
860
 
          if (s[-l-3] & KMAP_NOTIMEOUT >> 8)
861
 
            break;
862
 
          if ((i = s[s[-l-1] + 1]) == 0)
863
 
            {
864
 
              SetTimeout(&D_mapev, maptimeout);
865
 
              evenq(&D_mapev);
866
 
              break;
867
 
            }
868
 
        }
869
 
    }
870
 
  ProcessInput2(ibuf, slen);
871
 
}
872
 
 
873
 
#else
874
 
# define ProcessInput2 ProcessInput
875
 
#endif
876
 
 
877
 
 
878
 
/*
879
 
 *  Here only the screen escape commands are handled.
880
 
 */
881
 
 
882
 
void
883
 
ProcessInput2(ibuf, ilen)
884
 
char *ibuf;
885
 
int ilen;
886
 
{
887
 
  char *s;
888
 
  int ch, slen;
889
 
  struct action *ktabp;
890
 
 
891
 
  debug1("ProcessInput2: %d bytes\n", ilen);
892
 
  while (ilen && display)
893
 
    {
894
 
      debug1(" - ilen now %d bytes\n", ilen);
895
 
      flayer = D_forecv->c_layer;
896
 
      fore = D_fore;
897
 
      slen = ilen;
898
 
      s = ibuf;
899
 
      if (!D_ESCseen)
900
 
        {
901
 
          while (ilen > 0)
902
 
            {
903
 
              if ((unsigned char)*s++ == D_user->u_Esc)
904
 
                break;
905
 
              ilen--;
906
 
            }
907
 
          slen -= ilen;
908
 
          if (slen)
909
 
            DoProcess(fore, &ibuf, &slen, 0);
910
 
          if (--ilen == 0)
911
 
            {
912
 
              D_ESCseen = ktab;
913
 
              WindowChanged(fore, 'E');
914
 
            }
915
 
        }
916
 
      if (ilen <= 0)
917
 
        return;
918
 
      ktabp = D_ESCseen ? D_ESCseen : ktab;
919
 
      if (D_ESCseen)
920
 
        {
921
 
          D_ESCseen = 0;
922
 
          WindowChanged(fore, 'E');
923
 
        }
924
 
      ch = (unsigned char)*s;
925
 
 
926
 
      /* 
927
 
       * As users have different esc characters, but a common ktab[],
928
 
       * we fold back the users esc and meta-esc key to the Default keys
929
 
       * that can be looked up in the ktab[]. grmbl. jw.
930
 
       * XXX: make ktab[] a per user thing.
931
 
       */
932
 
      if (ch == D_user->u_Esc) 
933
 
        ch = DefaultEsc;
934
 
      else if (ch == D_user->u_MetaEsc) 
935
 
        ch = DefaultMetaEsc;
936
 
 
937
 
      if (ch >= 0)
938
 
        DoAction(&ktabp[ch], ch);
939
 
      ibuf = (char *)(s + 1);
940
 
      ilen--;
941
 
    }
942
 
}
943
 
 
944
 
void
945
 
DoProcess(p, bufp, lenp, pa)
946
 
struct win *p;
947
 
char **bufp;
948
 
int *lenp;
949
 
struct paster *pa;
950
 
{
951
 
  int oldlen;
952
 
  struct display *d = display;
953
 
 
954
 
#ifdef COPY_PASTE
955
 
  /* XXX -> PasteStart */
956
 
  if (pa && *lenp > 1 && p && p->w_slowpaste)
957
 
    {
958
 
      /* schedule slowpaste event */
959
 
      SetTimeout(&p->w_paster.pa_slowev, p->w_slowpaste);
960
 
      evenq(&p->w_paster.pa_slowev);
961
 
      return;
962
 
    }
963
 
#endif
964
 
  while (flayer && *lenp)
965
 
    {
966
 
#ifdef COPY_PASTE
967
 
      if (!pa && p && p->w_paster.pa_pastelen && flayer == p->w_paster.pa_pastelayer)
968
 
        {
969
 
          debug("layer is busy - beep!\n");
970
 
          WBell(p, visual_bell);
971
 
          *bufp += *lenp;
972
 
          *lenp = 0;
973
 
          display = d;
974
 
          return;
975
 
        }
976
 
#endif
977
 
      oldlen = *lenp;
978
 
      LayProcess(bufp, lenp);
979
 
#ifdef COPY_PASTE
980
 
      if (pa && !pa->pa_pastelayer)
981
 
        break;          /* flush rest of paste */
982
 
#endif
983
 
      if (*lenp == oldlen)
984
 
        {
985
 
          if (pa)
986
 
            {
987
 
              display = d;
988
 
              return;
989
 
            }
990
 
          /* We're full, let's beep */
991
 
          debug("layer is full - beep!\n");
992
 
          WBell(p, visual_bell);
993
 
          break;
994
 
        }
995
 
    }
996
 
  *bufp += *lenp;
997
 
  *lenp = 0;
998
 
  display = d;
999
 
#ifdef COPY_PASTE
1000
 
  if (pa && pa->pa_pastelen == 0)
1001
 
    FreePaster(pa);
1002
 
#endif
1003
 
}
1004
 
 
1005
 
int
1006
 
FindCommnr(str)
1007
 
const char *str;
1008
 
{
1009
 
  int x, m, l = 0, r = RC_LAST;
1010
 
  while (l <= r)
1011
 
    {
1012
 
      m = (l + r) / 2;
1013
 
      x = strcmp(str, comms[m].name);
1014
 
      if (x > 0)
1015
 
        l = m + 1;
1016
 
      else if (x < 0)
1017
 
        r = m - 1;
1018
 
      else
1019
 
        return m;
1020
 
    }
1021
 
  return RC_ILLEGAL;
1022
 
}
1023
 
 
1024
 
static int
1025
 
CheckArgNum(nr, args)
1026
 
int nr;
1027
 
char **args;
1028
 
{
1029
 
  int i, n;
1030
 
  static char *argss[] = {"no", "one", "two", "three", "four", "OOPS"};
1031
 
  static char *orformat[] = 
1032
 
    {
1033
 
      "%s: %s: %s argument%s required",
1034
 
      "%s: %s: %s or %s argument%s required",
1035
 
      "%s: %s: %s, %s or %s argument%s required",
1036
 
      "%s: %s: %s, %s, %s or %s argument%s required"
1037
 
    };
1038
 
 
1039
 
  n = comms[nr].flags & ARGS_MASK;
1040
 
  for (i = 0; args[i]; i++)
1041
 
    ;
1042
 
  if (comms[nr].flags & ARGS_ORMORE)
1043
 
    {
1044
 
      if (i < n)
1045
 
        {
1046
 
          Msg(0, "%s: %s: at least %s argument%s required", 
1047
 
              rc_name, comms[nr].name, argss[n], n != 1 ? "s" : "");
1048
 
          return -1;
1049
 
        }
1050
 
    }
1051
 
  else if ((comms[nr].flags & ARGS_PLUS1) && 
1052
 
           (comms[nr].flags & ARGS_PLUS2) &&
1053
 
           (comms[nr].flags & ARGS_PLUS3))
1054
 
    {
1055
 
      if (i != n && i != n + 1 && i != n + 2 && i != n + 3)
1056
 
        {
1057
 
          Msg(0, orformat[3], rc_name, comms[nr].name, argss[n], 
1058
 
              argss[n + 1], argss[n + 2], argss[n + 3], "");
1059
 
          return -1;
1060
 
        }
1061
 
    }
1062
 
  else if ((comms[nr].flags & ARGS_PLUS1) &&
1063
 
           (comms[nr].flags & ARGS_PLUS2))
1064
 
    {
1065
 
      if (i != n && i != n + 1 && i != n + 2)
1066
 
        {
1067
 
          Msg(0, orformat[2], rc_name, comms[nr].name, argss[n], 
1068
 
              argss[n + 1], argss[n + 2], "");
1069
 
          return -1;
1070
 
        }
1071
 
    }
1072
 
  else if ((comms[nr].flags & ARGS_PLUS1) &&
1073
 
           (comms[nr].flags & ARGS_PLUS3))
1074
 
    {
1075
 
      if (i != n && i != n + 1 && i != n + 3)
1076
 
        {
1077
 
          Msg(0, orformat[2], rc_name, comms[nr].name, argss[n], 
1078
 
              argss[n + 1], argss[n + 3], "");
1079
 
          return -1;
1080
 
        }
1081
 
    }
1082
 
  else if ((comms[nr].flags & ARGS_PLUS2) &&
1083
 
           (comms[nr].flags & ARGS_PLUS3))
1084
 
    {
1085
 
      if (i != n && i != n + 2 && i != n + 3)
1086
 
        {
1087
 
          Msg(0, orformat[2], rc_name, comms[nr].name, argss[n], 
1088
 
              argss[n + 2], argss[n + 3], "");
1089
 
          return -1;
1090
 
        }
1091
 
    }
1092
 
  else if (comms[nr].flags & ARGS_PLUS1)
1093
 
    {
1094
 
      if (i != n && i != n + 1)
1095
 
        {
1096
 
          Msg(0, orformat[1], rc_name, comms[nr].name, argss[n], 
1097
 
              argss[n + 1], n != 0 ? "s" : "");
1098
 
          return -1;
1099
 
        }
1100
 
    }
1101
 
  else if (comms[nr].flags & ARGS_PLUS2)
1102
 
    {
1103
 
      if (i != n && i != n + 2)
1104
 
        {
1105
 
          Msg(0, orformat[1], rc_name, comms[nr].name, argss[n], 
1106
 
              argss[n + 2], "s");
1107
 
          return -1;
1108
 
        }
1109
 
    }
1110
 
  else if (comms[nr].flags & ARGS_PLUS3)
1111
 
    {
1112
 
      if (i != n && i != n + 3)
1113
 
        {
1114
 
          Msg(0, orformat[1], rc_name, comms[nr].name, argss[n], 
1115
 
              argss[n + 3], "");
1116
 
          return -1;
1117
 
        }
1118
 
    }
1119
 
  else if (i != n)
1120
 
    {
1121
 
      Msg(0, orformat[0], rc_name, comms[nr].name, argss[n], n != 1 ? "s" : "");
1122
 
      return -1;
1123
 
    }
1124
 
  return i;
1125
 
}
1126
 
 
1127
 
static void
1128
 
StuffFin(buf, len, data)
1129
 
char *buf;
1130
 
int len;
1131
 
char *data;
1132
 
{
1133
 
  if (!flayer)
1134
 
    return;
1135
 
  while(len)
1136
 
    LayProcess(&buf, &len);
1137
 
}
1138
 
 
1139
 
/* If the command is not 'quieted', then use Msg to output the message. If it's a remote
1140
 
 * query, then Msg takes care of also outputting the message to the querying client.
1141
 
 *
1142
 
 * If we want the command to be quiet, and it's a remote query, then use QueryMsg so that
1143
 
 * the response does go back to the querying client.
1144
 
 *
1145
 
 * If the command is quieted, and it's not a remote query, then just don't print the message.
1146
 
 */
1147
 
#define OutputMsg       (!act->quiet ? Msg : queryflag >= 0 ? QueryMsg : Dummy)
1148
 
 
1149
 
/*ARGSUSED*/
1150
 
void
1151
 
DoAction(act, key)
1152
 
struct action *act;
1153
 
int key;
1154
 
{
1155
 
  int nr = act->nr;
1156
 
  char **args = act->args;
1157
 
  int *argl = act->argl;
1158
 
  struct win *p;
1159
 
  int argc, i, n, msgok;
1160
 
  char *s;
1161
 
  char ch;
1162
 
  struct display *odisplay = display;
1163
 
  struct acluser *user;
1164
 
 
1165
 
  user = display ? D_user : users;
1166
 
  if (nr == RC_ILLEGAL)
1167
 
    {
1168
 
      debug1("key '%c': No action\n", key);
1169
 
      return;
1170
 
    }
1171
 
  n = comms[nr].flags;
1172
 
  /* Commands will have a CAN_QUERY flag, depending on whether they have
1173
 
   * something to return on a query. For example, 'windows' can return a result,
1174
 
   * but 'other' cannot.
1175
 
   * If some command causes an error, then it should reset queryflag to -1, so that
1176
 
   * the process requesting the query can be notified that an error happened.
1177
 
   */
1178
 
  if (!(n & CAN_QUERY) && queryflag >= 0)
1179
 
    {
1180
 
      /* Query flag is set, but this command cannot be queried. */
1181
 
      OutputMsg(0, "%s command cannot be queried.", comms[nr].name);
1182
 
      queryflag = -1;
1183
 
      return;
1184
 
    }
1185
 
  if ((n & NEED_DISPLAY) && display == 0)
1186
 
    {
1187
 
      OutputMsg(0, "%s: %s: display required", rc_name, comms[nr].name);
1188
 
      queryflag = -1;
1189
 
      return;
1190
 
    }
1191
 
  if ((n & NEED_FORE) && fore == 0)
1192
 
    {
1193
 
      OutputMsg(0, "%s: %s: window required", rc_name, comms[nr].name);
1194
 
      queryflag = -1;
1195
 
      return;
1196
 
    }
1197
 
  if ((n & NEED_LAYER) && flayer == 0)
1198
 
    {
1199
 
      OutputMsg(0, "%s: %s: display or window required", rc_name, comms[nr].name);
1200
 
      queryflag = -1;
1201
 
      return;
1202
 
    }
1203
 
  if ((argc = CheckArgNum(nr, args)) < 0)
1204
 
    return;
1205
 
#ifdef MULTIUSER
1206
 
  if (display)
1207
 
    {
1208
 
      if (AclCheckPermCmd(D_user, ACL_EXEC, &comms[nr]))
1209
 
        {
1210
 
          OutputMsg(0, "%s: %s: permission denied (user %s)", 
1211
 
              rc_name, comms[nr].name, (EffectiveAclUser ? EffectiveAclUser : D_user)->u_name);
1212
 
          queryflag = -1;
1213
 
          return;
1214
 
        }
1215
 
    }
1216
 
#endif /* MULTIUSER */
1217
 
 
1218
 
  msgok = display && !*rc_name;
1219
 
  switch(nr)
1220
 
    {
1221
 
    case RC_SELECT:
1222
 
      if (!*args)
1223
 
        InputSelect();
1224
 
      else if (args[0][0] == '-' && !args[0][1])
1225
 
        {
1226
 
          SetForeWindow((struct win *)0);
1227
 
          Activate(0);
1228
 
        }
1229
 
      else if (args[0][0] == '.' && !args[0][1])
1230
 
        {
1231
 
          if (!fore)
1232
 
            {
1233
 
              OutputMsg(0, "select . needs a window");
1234
 
              queryflag = -1;
1235
 
            }
1236
 
          else
1237
 
            {
1238
 
              SetForeWindow(fore);
1239
 
              Activate(0);
1240
 
            }
1241
 
        }
1242
 
      else if (ParseWinNum(act, &n) == 0)
1243
 
        SwitchWindow(n);
1244
 
      else if (queryflag >= 0)
1245
 
        queryflag = -1; /* ParseWinNum already prints out an appropriate error message. */
1246
 
      break;
1247
 
#ifdef AUTO_NUKE
1248
 
    case RC_DEFAUTONUKE:
1249
 
      if (ParseOnOff(act, &defautonuke) == 0 && msgok)
1250
 
        OutputMsg(0, "Default autonuke turned %s", defautonuke ? "on" : "off");
1251
 
      if (display && *rc_name)
1252
 
        D_auto_nuke = defautonuke;
1253
 
      break;
1254
 
    case RC_AUTONUKE:
1255
 
      if (ParseOnOff(act, &D_auto_nuke) == 0 && msgok)
1256
 
        OutputMsg(0, "Autonuke turned %s", D_auto_nuke ? "on" : "off");
1257
 
      break;
1258
 
#endif
1259
 
    case RC_DEFOBUFLIMIT:
1260
 
      if (ParseNum(act, &defobuflimit) == 0 && msgok)
1261
 
        OutputMsg(0, "Default limit set to %d", defobuflimit);
1262
 
      if (display && *rc_name)
1263
 
        {
1264
 
          D_obufmax = defobuflimit;
1265
 
          D_obuflenmax = D_obuflen - D_obufmax;
1266
 
        }
1267
 
      break;
1268
 
    case RC_OBUFLIMIT:
1269
 
      if (*args == 0)
1270
 
        OutputMsg(0, "Limit is %d, current buffer size is %d", D_obufmax, D_obuflen);
1271
 
      else if (ParseNum(act, &D_obufmax) == 0 && msgok)
1272
 
        OutputMsg(0, "Limit set to %d", D_obufmax);
1273
 
      D_obuflenmax = D_obuflen - D_obufmax;
1274
 
      break;
1275
 
    case RC_DUMPTERMCAP:
1276
 
      WriteFile(user, (char *)0, DUMP_TERMCAP);
1277
 
      break;
1278
 
    case RC_HARDCOPY:
1279
 
      {
1280
 
        int mode = DUMP_HARDCOPY;
1281
 
        char *file = NULL;
1282
 
 
1283
 
        if (args[0])
1284
 
          {
1285
 
            if (!strcmp(*args, "-h"))
1286
 
              {
1287
 
                mode = DUMP_SCROLLBACK;
1288
 
                file = args[1];
1289
 
              }
1290
 
            else if (!strcmp(*args, "--") && args[1])
1291
 
              file = args[1];
1292
 
            else
1293
 
              file = args[0];
1294
 
          }
1295
 
 
1296
 
        if (args[0] && file == args[0] && args[1])
1297
 
          {
1298
 
            OutputMsg(0, "%s: hardcopy: too many arguments", rc_name);
1299
 
            break;
1300
 
          }
1301
 
        WriteFile(user, file, mode);
1302
 
      }
1303
 
      break;
1304
 
    case RC_DEFLOG:
1305
 
      (void)ParseOnOff(act, &nwin_default.Lflag);
1306
 
      break;
1307
 
    case RC_LOG:
1308
 
      n = fore->w_log ? 1 : 0;
1309
 
      ParseSwitch(act, &n);
1310
 
      LogToggle(n);
1311
 
      break;
1312
 
#ifdef BSDJOBS
1313
 
    case RC_SUSPEND:
1314
 
      Detach(D_STOP);
1315
 
      break;
1316
 
#endif
1317
 
    case RC_NEXT:
1318
 
      if (MoreWindows())
1319
 
        SwitchWindow(NextWindow());
1320
 
      break;
1321
 
    case RC_PREV:
1322
 
      if (MoreWindows())
1323
 
        SwitchWindow(PreviousWindow());
1324
 
      break;
1325
 
    case RC_KILL:
1326
 
      {
1327
 
        char *name;
1328
 
 
1329
 
        if (key >= 0)
1330
 
          {
1331
 
#ifdef PSEUDOS
1332
 
            Input(fore->w_pwin ? "Really kill this filter [y/n]" : "Really kill this window [y/n]", 1, INP_RAW, confirm_fn, NULL, RC_KILL);
1333
 
#else
1334
 
            Input("Really kill this window [y/n]", 1, INP_RAW, confirm_fn, NULL, RC_KILL);
1335
 
#endif
1336
 
            break;
1337
 
          }
1338
 
        n = fore->w_number;
1339
 
#ifdef PSEUDOS
1340
 
        if (fore->w_pwin)
1341
 
          {
1342
 
            FreePseudowin(fore);
1343
 
            OutputMsg(0, "Filter removed.");
1344
 
            break;
1345
 
          }
1346
 
#endif
1347
 
        name = SaveStr(fore->w_title);
1348
 
        KillWindow(fore);
1349
 
        OutputMsg(0, "Window %d (%s) killed.", n, name);
1350
 
        if (name)
1351
 
          free(name);
1352
 
        break;
1353
 
      }
1354
 
    case RC_QUIT:
1355
 
      if (key >= 0)
1356
 
        {
1357
 
          Input("Really quit and kill all your windows [y/n]", 1, INP_RAW, confirm_fn, NULL, RC_QUIT);
1358
 
          break;
1359
 
        }
1360
 
      Finit(0);
1361
 
      /* NOTREACHED */
1362
 
#ifdef DETACH
1363
 
    case RC_DETACH:
1364
 
      if (*args && !strcmp(*args, "-h"))
1365
 
        Hangup();
1366
 
      else
1367
 
        Detach(D_DETACH);
1368
 
      break;
1369
 
# ifdef POW_DETACH
1370
 
    case RC_POW_DETACH:
1371
 
      if (key >= 0)
1372
 
        {
1373
 
          static char buf[2];
1374
 
 
1375
 
          buf[0] = key;
1376
 
          Input(buf, 1, INP_RAW, pow_detach_fn, NULL, 0);
1377
 
        }
1378
 
      else
1379
 
        Detach(D_POWER); /* detach and kill Attacher's parent */
1380
 
      break;
1381
 
# endif
1382
 
#endif
1383
 
    case RC_DEBUG:
1384
 
#ifdef DEBUG
1385
 
      if (!*args)
1386
 
        {
1387
 
          if (dfp)
1388
 
            OutputMsg(0, "debugging info is written to %s/", DEBUGDIR);
1389
 
          else
1390
 
            OutputMsg(0, "debugging is currently off. Use 'debug on' to enable.");
1391
 
          break;
1392
 
        }
1393
 
      if (dfp)
1394
 
        {
1395
 
          debug("debug: closing debug file.\n");
1396
 
          fflush(dfp);
1397
 
          fclose(dfp);
1398
 
          dfp = NULL;
1399
 
        }
1400
 
      if (strcmp("off", *args))
1401
 
        opendebug(0, 1);
1402
 
# ifdef SIG_NODEBUG
1403
 
      else if (display)
1404
 
        kill(D_userpid, SIG_NODEBUG);   /* a one shot item, but hey... */
1405
 
# endif /* SIG_NODEBUG */
1406
 
#else
1407
 
      if (*args == 0 || strcmp("off", *args))
1408
 
        OutputMsg(0, "Sorry, screen was compiled without -DDEBUG option.");
1409
 
#endif
1410
 
      break;
1411
 
#ifdef ZMODEM
1412
 
    case RC_ZMODEM:
1413
 
      if (*args && !strcmp(*args, "sendcmd"))
1414
 
        {
1415
 
          if (args[1])
1416
 
            {
1417
 
              free(zmodem_sendcmd);
1418
 
              zmodem_sendcmd = SaveStr(args[1]);
1419
 
            }
1420
 
          if (msgok)
1421
 
            OutputMsg(0, "zmodem sendcmd: %s", zmodem_sendcmd);
1422
 
          break;
1423
 
        }
1424
 
      if (*args && !strcmp(*args, "recvcmd"))
1425
 
        {
1426
 
          if (args[1])
1427
 
            {
1428
 
              free(zmodem_recvcmd);
1429
 
              zmodem_recvcmd = SaveStr(args[1]);
1430
 
            }
1431
 
          if (msgok)
1432
 
            OutputMsg(0, "zmodem recvcmd: %s", zmodem_recvcmd);
1433
 
          break;
1434
 
        }
1435
 
      if (*args)
1436
 
        {
1437
 
          for (i = 0; i < 4; i++)
1438
 
            if (!strcmp(zmodes[i], *args))
1439
 
              break;
1440
 
          if (i == 4 && !strcmp(*args, "on"))
1441
 
            i = 1;
1442
 
          if (i == 4)
1443
 
            {
1444
 
              OutputMsg(0, "usage: zmodem off|auto|catch|pass");
1445
 
              break;
1446
 
            }
1447
 
          zmodem_mode = i;
1448
 
        }
1449
 
      if (msgok)
1450
 
        OutputMsg(0, "zmodem mode is %s", zmodes[zmodem_mode]);
1451
 
      break;
1452
 
#endif
1453
 
    case RC_UNBINDALL:
1454
 
      {
1455
 
        register unsigned int i;
1456
 
 
1457
 
        for (i = 0; i < sizeof(ktab)/sizeof(*ktab); i++)
1458
 
          ClearAction(&ktab[i]);
1459
 
        OutputMsg(0, "Unbound all keys." );
1460
 
        break;
1461
 
      }
1462
 
    case RC_ZOMBIE:
1463
 
      {
1464
 
        if (!(s = *args))
1465
 
          {
1466
 
            ZombieKey_destroy = 0;
1467
 
            break;
1468
 
          }
1469
 
        if (*argl == 0 || *argl > 2)
1470
 
          {
1471
 
            OutputMsg(0, "%s:zombie: one or two characters expected.", rc_name);
1472
 
            break;
1473
 
          }
1474
 
        if (args[1])
1475
 
          {
1476
 
            if (!strcmp(args[1], "onerror"))
1477
 
              {
1478
 
                ZombieKey_onerror = 1;
1479
 
              } else {
1480
 
                OutputMsg(0, "usage: zombie [keys [onerror]]");
1481
 
                break;
1482
 
              }
1483
 
          } else
1484
 
            ZombieKey_onerror = 0;
1485
 
        ZombieKey_destroy = args[0][0];
1486
 
        ZombieKey_resurrect = *argl == 2 ? args[0][1] : 0;
1487
 
      }
1488
 
      break;
1489
 
    case RC_WALL:
1490
 
#ifdef MULTIUSER
1491
 
      s = D_user->u_name;
1492
 
#else
1493
 
      s = D_usertty;
1494
 
#endif
1495
 
        {
1496
 
          struct display *olddisplay = display;
1497
 
          display = 0;          /* no display will cause a broadcast */
1498
 
          OutputMsg(0, "%s: %s", s, *args);
1499
 
          display = olddisplay;
1500
 
        }
1501
 
      break;
1502
 
    case RC_AT:
1503
 
      /* where this AT command comes from: */
1504
 
      if (!user)
1505
 
        break;
1506
 
#ifdef MULTIUSER
1507
 
      s = SaveStr(user->u_name);
1508
 
      /* DO NOT RETURN FROM HERE WITHOUT RESETTING THIS: */
1509
 
      EffectiveAclUser = user;
1510
 
#else
1511
 
      s = SaveStr(display ? D_usertty : user->u_name);
1512
 
#endif
1513
 
      n = strlen(args[0]);
1514
 
      if (n) n--;
1515
 
      /*
1516
 
       * the windows/displays loops are quite dangerous here, take extra
1517
 
       * care not to trigger landmines. Things may appear/disappear while
1518
 
       * we are walking along.
1519
 
       */
1520
 
      switch (args[0][n])
1521
 
        {
1522
 
        case '*':               /* user */
1523
 
          {
1524
 
            struct display *nd;
1525
 
            struct acluser *u;
1526
 
 
1527
 
            if (!n)
1528
 
              u = user;
1529
 
            else
1530
 
              {
1531
 
                for (u = users; u; u = u->u_next)
1532
 
                  {
1533
 
                    debug3("strncmp('%s', '%s', %d)\n", *args, u->u_name, n);
1534
 
                    if (!strncmp(*args, u->u_name, n))
1535
 
                      break;
1536
 
                  }
1537
 
                if (!u)
1538
 
                  {
1539
 
                    args[0][n] = '\0';
1540
 
                    OutputMsg(0, "Did not find any user matching '%s'", args[0]);
1541
 
                    break;
1542
 
                  }
1543
 
              }
1544
 
            debug1("at all displays of user %s\n", u->u_name);
1545
 
            for (display = displays; display; display = nd)
1546
 
              {
1547
 
                nd = display->d_next;
1548
 
                if (D_forecv == 0)
1549
 
                  continue;
1550
 
                flayer = D_forecv->c_layer;
1551
 
                fore = D_fore;
1552
 
                if (D_user != u)
1553
 
                  continue;
1554
 
                debug1("AT display %s\n", D_usertty);
1555
 
                DoCommand(args + 1, argl + 1);
1556
 
                if (display)
1557
 
                  OutputMsg(0, "command from %s: %s %s", 
1558
 
                      s, args[1], args[2] ? args[2] : "");
1559
 
                display = NULL;
1560
 
                flayer = 0;
1561
 
                fore = NULL;
1562
 
              }
1563
 
            break;
1564
 
          }
1565
 
        case '%':               /* display */
1566
 
          {
1567
 
            struct display *nd;
1568
 
 
1569
 
            debug1("at display matching '%s'\n", args[0]);
1570
 
            for (display = displays; display; display = nd)
1571
 
              {
1572
 
                nd = display->d_next;
1573
 
                if (D_forecv == 0)
1574
 
                  continue;
1575
 
                fore = D_fore;
1576
 
                flayer = D_forecv->c_layer;
1577
 
                if (strncmp(args[0], D_usertty, n) && 
1578
 
                    (strncmp("/dev/", D_usertty, 5) || 
1579
 
                     strncmp(args[0], D_usertty + 5, n)) &&
1580
 
                    (strncmp("/dev/tty", D_usertty, 8) ||
1581
 
                     strncmp(args[0], D_usertty + 8, n)))
1582
 
                  continue;
1583
 
                debug1("AT display %s\n", D_usertty);
1584
 
                DoCommand(args + 1, argl + 1);
1585
 
                if (display)
1586
 
                  OutputMsg(0, "command from %s: %s %s", 
1587
 
                      s, args[1], args[2] ? args[2] : "");
1588
 
                display = NULL;
1589
 
                fore = NULL;
1590
 
                flayer = 0;
1591
 
              }
1592
 
            break;
1593
 
          }
1594
 
        case '#':               /* window */
1595
 
          n--;
1596
 
          /* FALLTHROUGH */
1597
 
        default:
1598
 
          {
1599
 
            struct win *nw;
1600
 
            int ch;
1601
 
 
1602
 
            n++;
1603
 
            ch = args[0][n];
1604
 
            args[0][n] = '\0';
1605
 
            if (!*args[0] || (i = WindowByNumber(args[0])) < 0)
1606
 
              {
1607
 
                args[0][n] = ch;      /* must restore string in case of bind */
1608
 
                /* try looping over titles */
1609
 
                for (fore = windows; fore; fore = nw)
1610
 
                  {
1611
 
                    nw = fore->w_next;
1612
 
                    if (strncmp(args[0], fore->w_title, n))
1613
 
                      continue;
1614
 
                    debug2("AT window %d(%s)\n", fore->w_number, fore->w_title);
1615
 
                    /*
1616
 
                     * consider this a bug or a feature: 
1617
 
                     * while looping through windows, we have fore AND
1618
 
                     * display context. This will confuse users who try to 
1619
 
                     * set up loops inside of loops, but often allows to do 
1620
 
                     * what you mean, even when you adress your context wrong.
1621
 
                     */
1622
 
                    i = 0;
1623
 
                    /* XXX: other displays? */
1624
 
                    if (fore->w_layer.l_cvlist)
1625
 
                      display = fore->w_layer.l_cvlist->c_display;
1626
 
                    flayer = fore->w_savelayer ? fore->w_savelayer : &fore->w_layer;
1627
 
                    DoCommand(args + 1, argl + 1);      /* may destroy our display */
1628
 
                    if (fore && fore->w_layer.l_cvlist)
1629
 
                      {
1630
 
                        display = fore->w_layer.l_cvlist->c_display;
1631
 
                        OutputMsg(0, "command from %s: %s %s", 
1632
 
                            s, args[1], args[2] ? args[2] : "");
1633
 
                      }
1634
 
                  }
1635
 
                display = NULL;
1636
 
                fore = NULL;
1637
 
                if (i < 0)
1638
 
                  OutputMsg(0, "%s: at '%s': no such window.\n", rc_name, args[0]);
1639
 
                break;
1640
 
              }
1641
 
            else if (i < maxwin && (fore = wtab[i]))
1642
 
              {
1643
 
                args[0][n] = ch;      /* must restore string in case of bind */
1644
 
                debug2("AT window %d (%s)\n", fore->w_number, fore->w_title);
1645
 
                if (fore->w_layer.l_cvlist)
1646
 
                  display = fore->w_layer.l_cvlist->c_display;
1647
 
                flayer = fore->w_savelayer ? fore->w_savelayer : &fore->w_layer;
1648
 
                DoCommand(args + 1, argl + 1);
1649
 
                if (fore && fore->w_layer.l_cvlist)
1650
 
                  {
1651
 
                    display = fore->w_layer.l_cvlist->c_display;
1652
 
                    OutputMsg(0, "command from %s: %s %s", 
1653
 
                        s, args[1], args[2] ? args[2] : "");
1654
 
                  }
1655
 
                display = NULL;
1656
 
                fore = NULL;
1657
 
              }
1658
 
            else
1659
 
              OutputMsg(0, "%s: at [identifier][%%|*|#] command [args]", rc_name);
1660
 
            break;
1661
 
          }
1662
 
        }
1663
 
      free(s);
1664
 
#ifdef MULTIUSER
1665
 
      EffectiveAclUser = NULL;
1666
 
#endif
1667
 
      break;
1668
 
 
1669
 
#ifdef COPY_PASTE
1670
 
    case RC_READREG:
1671
 
#ifdef ENCODINGS
1672
 
      i = fore ? fore->w_encoding : display ? display->d_encoding : 0;
1673
 
      if (args[0] && args[1] && !strcmp(args[0], "-e"))
1674
 
        {
1675
 
          i = FindEncoding(args[1]);
1676
 
          if (i == -1)
1677
 
            {
1678
 
              OutputMsg(0, "%s: readreg: unknown encoding", rc_name);
1679
 
              break;
1680
 
            }
1681
 
          args += 2;
1682
 
        }
1683
 
#endif
1684
 
      /* 
1685
 
       * Without arguments we prompt for a destination register.
1686
 
       * It will receive the copybuffer contents.
1687
 
       * This is not done by RC_PASTE, as we prompt for source
1688
 
       * (not dest) there.
1689
 
       */
1690
 
      if ((s = *args) == NULL)
1691
 
        {
1692
 
          Input("Copy to register:", 1, INP_RAW, copy_reg_fn, NULL, 0);
1693
 
          break;
1694
 
        }
1695
 
      if (*argl != 1)
1696
 
        {
1697
 
          OutputMsg(0, "%s: copyreg: character, ^x, or (octal) \\032 expected.", rc_name);
1698
 
          break;
1699
 
        }
1700
 
      ch = args[0][0];
1701
 
      /* 
1702
 
       * With two arguments we *really* read register contents from file
1703
 
       */
1704
 
      if (args[1])
1705
 
        {
1706
 
          if (args[2])
1707
 
            {
1708
 
              OutputMsg(0, "%s: readreg: too many arguments", rc_name);
1709
 
              break;
1710
 
            }
1711
 
          if ((s = ReadFile(args[1], &n)))
1712
 
            {
1713
 
              struct plop *pp = plop_tab + (int)(unsigned char)ch;
1714
 
 
1715
 
              if (pp->buf)
1716
 
                free(pp->buf);
1717
 
              pp->buf = s;
1718
 
              pp->len = n;
1719
 
#ifdef ENCODINGS
1720
 
              pp->enc = i;
1721
 
#endif
1722
 
            }
1723
 
        }
1724
 
      else
1725
 
        /*
1726
 
         * with one argument we copy the copybuffer into a specified register
1727
 
         * This could be done with RC_PASTE too, but is here to be consistent
1728
 
         * with the zero argument call.
1729
 
         */
1730
 
        copy_reg_fn(&ch, 0, NULL);
1731
 
      break;
1732
 
#endif
1733
 
    case RC_REGISTER:
1734
 
#ifdef ENCODINGS
1735
 
      i = fore ? fore->w_encoding : display ? display->d_encoding : 0;
1736
 
      if (args[0] && args[1] && !strcmp(args[0], "-e"))
1737
 
        {
1738
 
          i = FindEncoding(args[1]);
1739
 
          if (i == -1)
1740
 
            {
1741
 
              OutputMsg(0, "%s: register: unknown encoding", rc_name);
1742
 
              break;
1743
 
            }
1744
 
          args += 2;
1745
 
          argc -= 2;
1746
 
        }
1747
 
#endif
1748
 
      if (argc != 2)
1749
 
        {
1750
 
          OutputMsg(0, "%s: register: illegal number of arguments.", rc_name);
1751
 
          break;
1752
 
        }
1753
 
      if (*argl != 1)
1754
 
        {
1755
 
          OutputMsg(0, "%s: register: character, ^x, or (octal) \\032 expected.", rc_name);
1756
 
          break;
1757
 
        }
1758
 
      ch = args[0][0];
1759
 
#ifdef COPY_PASTE
1760
 
      if (ch == '.')
1761
 
        {
1762
 
          if (user->u_plop.buf != NULL)
1763
 
            UserFreeCopyBuffer(user);
1764
 
          if (args[1] && args[1][0])
1765
 
            {
1766
 
              user->u_plop.buf = SaveStrn(args[1], argl[1]);
1767
 
              user->u_plop.len = argl[1];
1768
 
#ifdef ENCODINGS
1769
 
              user->u_plop.enc = i;
1770
 
#endif
1771
 
            }
1772
 
        }
1773
 
      else
1774
 
#endif
1775
 
        {
1776
 
          struct plop *plp = plop_tab + (int)(unsigned char)ch;
1777
 
 
1778
 
          if (plp->buf)
1779
 
            free(plp->buf);
1780
 
          plp->buf = SaveStrn(args[1], argl[1]);
1781
 
          plp->len = argl[1];
1782
 
#ifdef ENCODINGS
1783
 
          plp->enc = i;
1784
 
#endif
1785
 
        }
1786
 
      break;
1787
 
    case RC_PROCESS:
1788
 
      if ((s = *args) == NULL)
1789
 
        {
1790
 
          Input("Process register:", 1, INP_RAW, process_fn, NULL, 0);
1791
 
          break;
1792
 
        }
1793
 
      if (*argl != 1)
1794
 
        {
1795
 
          OutputMsg(0, "%s: process: character, ^x, or (octal) \\032 expected.", rc_name);
1796
 
          break;
1797
 
        }
1798
 
      ch = args[0][0];
1799
 
      process_fn(&ch, 0, NULL);
1800
 
      break;
1801
 
    case RC_STUFF:
1802
 
      s = *args;
1803
 
      if (!args[0])
1804
 
        {
1805
 
          Input("Stuff:", 100, INP_COOKED, StuffFin, NULL, 0);
1806
 
          break;
1807
 
        }
1808
 
      n = *argl;
1809
 
      if (args[1])
1810
 
        {
1811
 
          if (strcmp(s, "-k"))
1812
 
            {
1813
 
              OutputMsg(0, "%s: stuff: invalid option %s", rc_name, s);
1814
 
              break;
1815
 
            }
1816
 
          s = args[1];
1817
 
          for (i = T_CAPS; i < T_OCAPS; i++)
1818
 
            if (strcmp(term[i].tcname, s) == 0)
1819
 
              break;
1820
 
          if (i == T_OCAPS)
1821
 
            {
1822
 
              OutputMsg(0, "%s: stuff: unknown key '%s'", rc_name, s);
1823
 
              break;
1824
 
            }
1825
 
#ifdef MAPKEYS
1826
 
          if (StuffKey(i - T_CAPS) == 0)
1827
 
            break;
1828
 
#endif
1829
 
          s = display ? D_tcs[i].str : 0;
1830
 
          if (s == 0)
1831
 
            break;
1832
 
          n = strlen(s);
1833
 
        }
1834
 
      while(n)
1835
 
        LayProcess(&s, &n);
1836
 
      break;
1837
 
    case RC_REDISPLAY:
1838
 
      Activate(-1);
1839
 
      break;
1840
 
    case RC_WINDOWS:
1841
 
      ShowWindows(-1);
1842
 
      break;
1843
 
    case RC_VERSION:
1844
 
      OutputMsg(0, "screen %s", version);
1845
 
      break;
1846
 
    case RC_TIME:
1847
 
      if (*args)
1848
 
        {
1849
 
          timestring = SaveStr(*args);
1850
 
          break;
1851
 
        }
1852
 
      OutputMsg(0, "%s", MakeWinMsg(timestring, fore, '%'));
1853
 
      break;
1854
 
    case RC_INFO:
1855
 
      ShowInfo();
1856
 
      break;
1857
 
    case RC_DINFO:
1858
 
      ShowDInfo();
1859
 
      break;
1860
 
    case RC_COMMAND:
1861
 
        {
1862
 
          struct action *ktabp = ktab;
1863
 
          if (argc == 2 && !strcmp(*args, "-c"))
1864
 
            {
1865
 
              if ((ktabp = FindKtab(args[1], 0)) == 0)
1866
 
                {
1867
 
                  OutputMsg(0, "Unknown command class '%s'", args[1]);
1868
 
                  break;
1869
 
                }
1870
 
            }
1871
 
          if (D_ESCseen != ktab || ktabp != ktab)
1872
 
            {
1873
 
              if (D_ESCseen != ktabp)
1874
 
                {
1875
 
                  D_ESCseen = ktabp;
1876
 
                  WindowChanged(fore, 'E');
1877
 
                }
1878
 
              break;
1879
 
            }
1880
 
          if (D_ESCseen)
1881
 
            {
1882
 
              D_ESCseen = 0;
1883
 
              WindowChanged(fore, 'E');
1884
 
            }
1885
 
        }
1886
 
      /* FALLTHROUGH */
1887
 
    case RC_OTHER:
1888
 
      if (MoreWindows())
1889
 
        SwitchWindow(display && D_other ? D_other->w_number : NextWindow());
1890
 
      break;
1891
 
    case RC_META:
1892
 
      if (user->u_Esc == -1)
1893
 
        break;
1894
 
      ch = user->u_Esc;
1895
 
      s = &ch;
1896
 
      n = 1;
1897
 
      LayProcess(&s, &n);
1898
 
      break;
1899
 
    case RC_XON:
1900
 
      ch = Ctrl('q');
1901
 
      s = &ch;
1902
 
      n = 1;
1903
 
      LayProcess(&s, &n);
1904
 
      break;
1905
 
    case RC_XOFF:
1906
 
      ch = Ctrl('s');
1907
 
      s = &ch;
1908
 
      n = 1;
1909
 
      LayProcess(&s, &n);
1910
 
      break;
1911
 
    case RC_DEFBREAKTYPE:
1912
 
    case RC_BREAKTYPE:
1913
 
        {
1914
 
          static char *types[] = { "TIOCSBRK", "TCSBRK", "tcsendbreak", NULL };
1915
 
          extern int breaktype;
1916
 
 
1917
 
          if (*args)
1918
 
            {
1919
 
              if (ParseNum(act, &n))
1920
 
                for (n = 0; n < (int)(sizeof(types)/sizeof(*types)); n++)
1921
 
                  {
1922
 
                    for (i = 0; i < 4; i++)
1923
 
                      {
1924
 
                        ch = args[0][i];
1925
 
                        if (ch >= 'a' && ch <= 'z')
1926
 
                          ch -= 'a' - 'A';
1927
 
                        if (ch != types[n][i] && (ch + ('a' - 'A')) != types[n][i])
1928
 
                          break;
1929
 
                      }
1930
 
                    if (i == 4)
1931
 
                      break;
1932
 
                  }
1933
 
              if (n < 0 || n >= (int)(sizeof(types)/sizeof(*types)))
1934
 
                OutputMsg(0, "%s invalid, chose one of %s, %s or %s", *args, types[0], types[1], types[2]);
1935
 
              else
1936
 
                {
1937
 
                  breaktype = n;
1938
 
                  OutputMsg(0, "breaktype set to (%d) %s", n, types[n]);
1939
 
                }
1940
 
            }
1941
 
          else
1942
 
            OutputMsg(0, "breaktype is (%d) %s", breaktype, types[breaktype]);
1943
 
        }
1944
 
      break;
1945
 
    case RC_POW_BREAK:
1946
 
    case RC_BREAK:
1947
 
      n = 0;
1948
 
      if (*args && ParseNum(act, &n))
1949
 
        break;
1950
 
      SendBreak(fore, n, nr == RC_POW_BREAK);
1951
 
      break;
1952
 
#ifdef LOCK
1953
 
    case RC_LOCKSCREEN:
1954
 
      Detach(D_LOCK);
1955
 
      break;
1956
 
#endif
1957
 
    case RC_WIDTH:
1958
 
    case RC_HEIGHT:
1959
 
      {
1960
 
        int w, h;
1961
 
        int what = 0;
1962
 
        
1963
 
        i = 1;
1964
 
        if (*args && !strcmp(*args, "-w"))
1965
 
          what = 1;
1966
 
        else if (*args && !strcmp(*args, "-d"))
1967
 
          what = 2;
1968
 
        if (what)
1969
 
          args++;
1970
 
        if (what == 0 && flayer && !display)
1971
 
          what = 1;
1972
 
        if (what == 1)
1973
 
          {
1974
 
            if (!flayer)
1975
 
              {
1976
 
                OutputMsg(0, "%s: %s: window required", rc_name, comms[nr].name);
1977
 
                break;
1978
 
              }
1979
 
            w = flayer->l_width;
1980
 
            h = flayer->l_height;
1981
 
          }
1982
 
        else
1983
 
          {
1984
 
            if (!display)
1985
 
              {
1986
 
                OutputMsg(0, "%s: %s: display required", rc_name, comms[nr].name);
1987
 
                break;
1988
 
              }
1989
 
            w = D_width;
1990
 
            h = D_height;
1991
 
          }
1992
 
        if (*args && args[0][0] == '-')
1993
 
          {
1994
 
            OutputMsg(0, "%s: %s: unknown option %s", rc_name, comms[nr].name, *args);
1995
 
            break;
1996
 
          }
1997
 
        if (nr == RC_HEIGHT)
1998
 
          {
1999
 
            if (!*args)
2000
 
              {
2001
 
#define H0height 42
2002
 
#define H1height 24
2003
 
                if (h == H0height)
2004
 
                  h = H1height;
2005
 
                else if (h == H1height)
2006
 
                  h = H0height;
2007
 
                else if (h > (H0height + H1height) / 2)
2008
 
                  h = H0height;
2009
 
                else
2010
 
                  h = H1height;
2011
 
              }
2012
 
            else
2013
 
              {
2014
 
                h = atoi(*args);
2015
 
                if (args[1])
2016
 
                  w = atoi(args[1]);
2017
 
              }
2018
 
          }
2019
 
        else
2020
 
          {
2021
 
            if (!*args)
2022
 
              {
2023
 
                if (w == Z0width)
2024
 
                  w = Z1width;
2025
 
                else if (w == Z1width)
2026
 
                  w = Z0width;
2027
 
                else if (w > (Z0width + Z1width) / 2)
2028
 
                  w = Z0width;
2029
 
                else
2030
 
                  w = Z1width;
2031
 
              }
2032
 
            else
2033
 
              {
2034
 
                w = atoi(*args);
2035
 
                if (args[1])
2036
 
                  h = atoi(args[1]);
2037
 
              }
2038
 
          }
2039
 
        if (*args && args[1] && args[2])
2040
 
          {
2041
 
            OutputMsg(0, "%s: %s: too many arguments", rc_name, comms[nr].name);
2042
 
            break;
2043
 
          }
2044
 
        if (w <= 0)
2045
 
          {
2046
 
            OutputMsg(0, "Illegal width");
2047
 
            break;
2048
 
          }
2049
 
        if (h <= 0)
2050
 
          {
2051
 
            OutputMsg(0, "Illegal height");
2052
 
            break;
2053
 
          }
2054
 
        if (what == 1)
2055
 
          {
2056
 
            if (flayer->l_width == w && flayer->l_height == h)
2057
 
              break;
2058
 
            ResizeLayer(flayer, w, h, (struct display *)0);
2059
 
            break;
2060
 
          }
2061
 
        if (D_width == w && D_height == h)
2062
 
          break;
2063
 
        if (what == 2)
2064
 
          {
2065
 
            ChangeScreenSize(w, h, 1);
2066
 
          }
2067
 
        else
2068
 
          {
2069
 
            if (ResizeDisplay(w, h) == 0)
2070
 
              {
2071
 
                Activate(D_fore ? D_fore->w_norefresh : 0);
2072
 
                /* autofit */
2073
 
                ResizeLayer(D_forecv->c_layer, D_forecv->c_xe - D_forecv->c_xs + 1, D_forecv->c_ye - D_forecv->c_ys + 1, 0);
2074
 
                break;
2075
 
              }
2076
 
            if (h == D_height)
2077
 
              OutputMsg(0, "Your termcap does not specify how to change the terminal's width to %d.", w);
2078
 
            else if (w == D_width)
2079
 
              OutputMsg(0, "Your termcap does not specify how to change the terminal's height to %d.", h);
2080
 
            else
2081
 
              OutputMsg(0, "Your termcap does not specify how to change the terminal's resolution to %dx%d.", w, h);
2082
 
          }
2083
 
      }
2084
 
      break;
2085
 
    case RC_TITLE:
2086
 
      if (queryflag >= 0)
2087
 
        {
2088
 
          if (fore)
2089
 
            OutputMsg(0, "%s", fore->w_title);
2090
 
          else
2091
 
            queryflag = -1;
2092
 
          break;
2093
 
        }
2094
 
      if (*args == 0)
2095
 
        InputAKA();
2096
 
      else
2097
 
        ChangeAKA(fore, *args, strlen(*args));
2098
 
      break;
2099
 
    case RC_COLON:
2100
 
      Input(":", MAXSTR, INP_EVERY, Colonfin, NULL, 0);
2101
 
      if (*args && **args)
2102
 
        {
2103
 
          s = *args;
2104
 
          n = strlen(s);
2105
 
          LayProcess(&s, &n);
2106
 
        }
2107
 
      break;
2108
 
    case RC_LASTMSG:
2109
 
      if (D_status_lastmsg)
2110
 
        OutputMsg(0, "%s", D_status_lastmsg);
2111
 
      break;
2112
 
    case RC_SCREEN:
2113
 
      DoScreen("key", args);
2114
 
      break;
2115
 
    case RC_WRAP:
2116
 
      if (ParseSwitch(act, &fore->w_wrap) == 0 && msgok)
2117
 
        OutputMsg(0, "%cwrap", fore->w_wrap ? '+' : '-');
2118
 
      break;
2119
 
    case RC_FLOW:
2120
 
      if (*args)
2121
 
        {
2122
 
          if (args[0][0] == 'a')
2123
 
            {
2124
 
              fore->w_flow = (fore->w_flow & FLOW_AUTO) ? FLOW_AUTOFLAG |FLOW_AUTO|FLOW_NOW : FLOW_AUTOFLAG;
2125
 
            }
2126
 
          else
2127
 
            {
2128
 
              if (ParseOnOff(act, &n))
2129
 
                break;
2130
 
              fore->w_flow = (fore->w_flow & FLOW_AUTO) | n;
2131
 
            }
2132
 
        }
2133
 
      else
2134
 
        {
2135
 
          if (fore->w_flow & FLOW_AUTOFLAG)
2136
 
            fore->w_flow = (fore->w_flow & FLOW_AUTO) | FLOW_NOW;
2137
 
          else if (fore->w_flow & FLOW_NOW)
2138
 
            fore->w_flow &= ~FLOW_NOW;
2139
 
          else
2140
 
            fore->w_flow = fore->w_flow ? FLOW_AUTOFLAG|FLOW_AUTO|FLOW_NOW : FLOW_AUTOFLAG;
2141
 
        }
2142
 
      SetFlow(fore->w_flow & FLOW_NOW);
2143
 
      if (msgok)
2144
 
        OutputMsg(0, "%cflow%s", (fore->w_flow & FLOW_NOW) ? '+' : '-',
2145
 
            (fore->w_flow & FLOW_AUTOFLAG) ? "(auto)" : "");
2146
 
      break;
2147
 
#ifdef MULTIUSER
2148
 
    case RC_DEFWRITELOCK:
2149
 
      if (args[0][0] == 'a')
2150
 
        nwin_default.wlock = WLOCK_AUTO;
2151
 
      else
2152
 
        {
2153
 
          if (ParseOnOff(act, &n))
2154
 
            break;
2155
 
          nwin_default.wlock = n ? WLOCK_ON : WLOCK_OFF;
2156
 
        }
2157
 
      break;
2158
 
    case RC_WRITELOCK:
2159
 
      if (*args)
2160
 
        {
2161
 
          if (args[0][0] == 'a')
2162
 
            {
2163
 
              fore->w_wlock = WLOCK_AUTO;
2164
 
            }
2165
 
          else
2166
 
            {
2167
 
              if (ParseOnOff(act, &n))
2168
 
                break;
2169
 
              fore->w_wlock = n ? WLOCK_ON : WLOCK_OFF;
2170
 
            }
2171
 
          /* 
2172
 
           * user may have permission to change the writelock setting, 
2173
 
           * but he may never aquire the lock himself without write permission
2174
 
           */
2175
 
          if (!AclCheckPermWin(D_user, ACL_WRITE, fore))
2176
 
            fore->w_wlockuser = D_user;
2177
 
        }
2178
 
      OutputMsg(0, "writelock %s", (fore->w_wlock == WLOCK_AUTO) ? "auto" :
2179
 
          ((fore->w_wlock == WLOCK_OFF) ? "off" : "on"));
2180
 
      break;
2181
 
#endif
2182
 
    case RC_CLEAR:
2183
 
      ResetAnsiState(fore);
2184
 
      WriteString(fore, "\033[H\033[J", 6);
2185
 
      break;
2186
 
    case RC_RESET:
2187
 
      ResetAnsiState(fore);
2188
 
#ifdef ZMODEM
2189
 
      if (fore->w_zdisplay)
2190
 
        zmodem_abort(fore, fore->w_zdisplay);
2191
 
#endif
2192
 
      WriteString(fore, "\033c", 2);
2193
 
      break;
2194
 
    case RC_MONITOR:
2195
 
      n = fore->w_monitor != MON_OFF;
2196
 
#ifdef MULTIUSER
2197
 
      if (display)
2198
 
        n = n && (ACLBYTE(fore->w_mon_notify, D_user->u_id) & ACLBIT(D_user->u_id));
2199
 
#endif
2200
 
      if (ParseSwitch(act, &n))
2201
 
        break;
2202
 
      if (n)
2203
 
        {
2204
 
#ifdef MULTIUSER
2205
 
          if (display)  /* we tell only this user */
2206
 
            ACLBYTE(fore->w_mon_notify, D_user->u_id) |= ACLBIT(D_user->u_id);
2207
 
          else
2208
 
            for (i = 0; i < maxusercount; i++)
2209
 
              ACLBYTE(fore->w_mon_notify, i) |= ACLBIT(i);
2210
 
#endif
2211
 
          if (fore->w_monitor == MON_OFF)
2212
 
            fore->w_monitor = MON_ON;
2213
 
          OutputMsg(0, "Window %d (%s) is now being monitored for all activity.", fore->w_number, fore->w_title);
2214
 
        }
2215
 
      else
2216
 
        {
2217
 
#ifdef MULTIUSER
2218
 
          if (display) /* we remove only this user */
2219
 
            ACLBYTE(fore->w_mon_notify, D_user->u_id) 
2220
 
              &= ~ACLBIT(D_user->u_id);
2221
 
          else
2222
 
            for (i = 0; i < maxusercount; i++)
2223
 
              ACLBYTE(fore->w_mon_notify, i) &= ~ACLBIT(i);
2224
 
          for (i = maxusercount - 1; i >= 0; i--)
2225
 
            if (ACLBYTE(fore->w_mon_notify, i))
2226
 
              break;
2227
 
          if (i < 0)
2228
 
#endif
2229
 
            fore->w_monitor = MON_OFF;
2230
 
          OutputMsg(0, "Window %d (%s) is no longer being monitored for activity.", fore->w_number, fore->w_title);
2231
 
        }
2232
 
      break;
2233
 
#ifdef MULTI
2234
 
    case RC_DISPLAYS:
2235
 
      display_displays();
2236
 
      break;
2237
 
#endif
2238
 
    case RC_WINDOWLIST:
2239
 
      if (!*args)
2240
 
        display_windows(0, WLIST_NUM, (struct win *)0);
2241
 
      else if (!strcmp(*args, "string"))
2242
 
        {
2243
 
          if (args[1])
2244
 
            {
2245
 
              if (wliststr)
2246
 
                free(wliststr);
2247
 
              wliststr = SaveStr(args[1]);
2248
 
            }
2249
 
          if (msgok)
2250
 
            OutputMsg(0, "windowlist string is '%s'", wliststr);
2251
 
        }
2252
 
      else if (!strcmp(*args, "title"))
2253
 
        {
2254
 
          if (args[1])
2255
 
            {
2256
 
              if (wlisttit)
2257
 
                free(wlisttit);
2258
 
              wlisttit = SaveStr(args[1]);
2259
 
            }
2260
 
          if (msgok)
2261
 
            OutputMsg(0, "windowlist title is '%s'", wlisttit);
2262
 
        }
2263
 
      else
2264
 
        {
2265
 
          int flag = 0;
2266
 
          int blank = 0;
2267
 
          for (i = 0; i < argc; i++)
2268
 
            if (!args[i])
2269
 
              continue;
2270
 
            else if (!strcmp(args[i], "-m"))
2271
 
              flag |= WLIST_MRU;
2272
 
            else if (!strcmp(args[i], "-b"))
2273
 
              blank = 1;
2274
 
            else if (!strcmp(args[i], "-g"))
2275
 
              flag |= WLIST_NESTED;
2276
 
            else
2277
 
              {
2278
 
                OutputMsg(0, "usage: windowlist [-b] [-g] [-m] [string [string] | title [title]]");
2279
 
                break;
2280
 
              }
2281
 
          if (i == argc)
2282
 
            display_windows(blank, flag, (struct win *)0);
2283
 
        }
2284
 
      break;
2285
 
    case RC_HELP:
2286
 
      if (argc == 2 && !strcmp(*args, "-c"))
2287
 
        {
2288
 
          struct action *ktabp;
2289
 
          if ((ktabp = FindKtab(args[1], 0)) == 0)
2290
 
            {
2291
 
              OutputMsg(0, "Unknown command class '%s'", args[1]);
2292
 
              break;
2293
 
            }
2294
 
          display_help(args[1], ktabp);
2295
 
        }
2296
 
      else
2297
 
        display_help((char *)0, ktab);
2298
 
      break;
2299
 
    case RC_LICENSE:
2300
 
      display_copyright();
2301
 
      break;
2302
 
#ifdef COPY_PASTE
2303
 
    case RC_COPY:
2304
 
      if (flayer->l_layfn != &WinLf)
2305
 
        {
2306
 
          OutputMsg(0, "Must be on a window layer");
2307
 
          break;
2308
 
        }
2309
 
      MarkRoutine();
2310
 
      WindowChanged(fore, 'P');
2311
 
      break;
2312
 
    case RC_HISTORY:
2313
 
      {
2314
 
        static char *pasteargs[] = {".", 0};
2315
 
        static int pasteargl[] = {1};
2316
 
 
2317
 
        if (flayer->l_layfn != &WinLf)
2318
 
          {
2319
 
            OutputMsg(0, "Must be on a window layer");
2320
 
            break;
2321
 
          }
2322
 
        if (GetHistory() == 0)
2323
 
          break;
2324
 
        if (user->u_plop.buf == NULL)
2325
 
          break;
2326
 
        args = pasteargs;
2327
 
        argl = pasteargl;
2328
 
      }
2329
 
      /*FALLTHROUGH*/
2330
 
    case RC_PASTE:
2331
 
      {
2332
 
        char *ss, *dbuf, dch;
2333
 
        int l = 0;
2334
 
# ifdef ENCODINGS
2335
 
        int enc = -1;
2336
 
# endif
2337
 
 
2338
 
        /*
2339
 
         * without args we prompt for one(!) register to be pasted in the window
2340
 
         */
2341
 
        if ((s = *args) == NULL)
2342
 
          {
2343
 
            Input("Paste from register:", 1, INP_RAW, ins_reg_fn, NULL, 0);
2344
 
            break;
2345
 
          }
2346
 
        if (args[1] == 0 && !fore)      /* no window? */
2347
 
          break;
2348
 
        /*      
2349
 
         * with two arguments we paste into a destination register
2350
 
         * (no window needed here).
2351
 
         */
2352
 
        if (args[1] && argl[1] != 1)
2353
 
          {
2354
 
            OutputMsg(0, "%s: paste destination: character, ^x, or (octal) \\032 expected.",
2355
 
                rc_name);
2356
 
            break;
2357
 
          }
2358
 
# ifdef ENCODINGS
2359
 
        else if (fore)
2360
 
          enc = fore->w_encoding;
2361
 
# endif
2362
 
 
2363
 
        /*
2364
 
         * measure length of needed buffer 
2365
 
         */
2366
 
        for (ss = s = *args; (ch = *ss); ss++)
2367
 
          {
2368
 
            if (ch == '.')
2369
 
              {
2370
 
# ifdef ENCODINGS
2371
 
                if (enc == -1)
2372
 
                  enc = user->u_plop.enc;
2373
 
                if (enc != user->u_plop.enc)
2374
 
                  l += RecodeBuf((unsigned char *)user->u_plop.buf, user->u_plop.len, user->u_plop.enc, enc, (unsigned char *)0);
2375
 
                else
2376
 
# endif
2377
 
                  l += user->u_plop.len;
2378
 
              }
2379
 
            else
2380
 
              {
2381
 
# ifdef ENCODINGS
2382
 
                if (enc == -1)
2383
 
                  enc = plop_tab[(int)(unsigned char)ch].enc;
2384
 
                if (enc != plop_tab[(int)(unsigned char)ch].enc)
2385
 
                  l += RecodeBuf((unsigned char *)plop_tab[(int)(unsigned char)ch].buf, plop_tab[(int)(unsigned char)ch].len, plop_tab[(int)(unsigned char)ch].enc, enc, (unsigned char *)0);
2386
 
                else
2387
 
# endif
2388
 
                  l += plop_tab[(int)(unsigned char)ch].len;
2389
 
              }
2390
 
          }
2391
 
        if (l == 0)
2392
 
          {
2393
 
            OutputMsg(0, "empty buffer");
2394
 
            break;
2395
 
          }
2396
 
        /*
2397
 
         * shortcut: 
2398
 
         * if there is only one source and the destination is a window, then
2399
 
         * pass a pointer rather than duplicating the buffer.
2400
 
         */
2401
 
        if (s[1] == 0 && args[1] == 0)
2402
 
# ifdef ENCODINGS
2403
 
          if (enc == (*s == '.' ? user->u_plop.enc : plop_tab[(int)(unsigned char)*s].enc))
2404
 
# endif
2405
 
            {
2406
 
              MakePaster(&fore->w_paster, *s == '.' ? user->u_plop.buf : plop_tab[(int)(unsigned char)*s].buf, l, 0);
2407
 
              break;
2408
 
            }
2409
 
        /*
2410
 
         * if no shortcut, we construct a buffer
2411
 
         */
2412
 
        if ((dbuf = (char *)malloc(l)) == 0)
2413
 
          {
2414
 
            OutputMsg(0, "%s", strnomem);
2415
 
            break;
2416
 
          }
2417
 
        l = 0;
2418
 
        /*
2419
 
         * concatenate all sources into our own buffer, copy buffer is
2420
 
         * special and is skipped if no display exists.
2421
 
         */
2422
 
        for (ss = s; (ch = *ss); ss++)
2423
 
          {
2424
 
            struct plop *pp = (ch == '.' ? &user->u_plop : &plop_tab[(int)(unsigned char)ch]);
2425
 
#ifdef ENCODINGS
2426
 
            if (pp->enc != enc)
2427
 
              {
2428
 
                l += RecodeBuf((unsigned char *)pp->buf, pp->len, pp->enc, enc, (unsigned char *)dbuf + l);
2429
 
                continue;
2430
 
              }
2431
 
#endif
2432
 
            bcopy(pp->buf, dbuf + l, pp->len);
2433
 
            l += pp->len;
2434
 
          }
2435
 
        /*
2436
 
         * when called with one argument we paste our buffer into the window 
2437
 
         */
2438
 
        if (args[1] == 0)
2439
 
          {
2440
 
            MakePaster(&fore->w_paster, dbuf, l, 1);
2441
 
          }
2442
 
        else
2443
 
          {
2444
 
            /*
2445
 
             * we have two arguments, the second is already in dch.
2446
 
             * use this as destination rather than the window.
2447
 
             */
2448
 
            dch = args[1][0];
2449
 
            if (dch == '.')
2450
 
              {
2451
 
                if (user->u_plop.buf != NULL)
2452
 
                  UserFreeCopyBuffer(user);
2453
 
                user->u_plop.buf = dbuf;
2454
 
                user->u_plop.len = l;
2455
 
#ifdef ENCODINGS
2456
 
                user->u_plop.enc = enc;
2457
 
#endif
2458
 
              }
2459
 
            else
2460
 
              {
2461
 
                struct plop *pp = plop_tab + (int)(unsigned char)dch;
2462
 
                if (pp->buf)
2463
 
                  free(pp->buf);
2464
 
                pp->buf = dbuf;
2465
 
                pp->len = l;
2466
 
#ifdef ENCODINGS
2467
 
                pp->enc = enc;
2468
 
#endif
2469
 
              }
2470
 
          }
2471
 
        break;
2472
 
      }
2473
 
    case RC_WRITEBUF:
2474
 
      if (!user->u_plop.buf)
2475
 
        {
2476
 
          OutputMsg(0, "empty buffer");
2477
 
          break;
2478
 
        }
2479
 
#ifdef ENCODINGS
2480
 
        {
2481
 
          struct plop oldplop;
2482
 
 
2483
 
          oldplop = user->u_plop;
2484
 
          if (args[0] && args[1] && !strcmp(args[0], "-e"))
2485
 
            {
2486
 
              int enc, l;
2487
 
              char *newbuf;
2488
 
 
2489
 
              enc = FindEncoding(args[1]);
2490
 
              if (enc == -1)
2491
 
                {
2492
 
                  OutputMsg(0, "%s: writebuf: unknown encoding", rc_name);
2493
 
                  break;
2494
 
                }
2495
 
              if (enc != oldplop.enc)
2496
 
                {
2497
 
                  l = RecodeBuf((unsigned char *)oldplop.buf, oldplop.len, oldplop.enc, enc, (unsigned char *)0);
2498
 
                  newbuf = malloc(l + 1);
2499
 
                  if (!newbuf)
2500
 
                    {
2501
 
                      OutputMsg(0, "%s", strnomem);
2502
 
                      break;
2503
 
                    }
2504
 
                  user->u_plop.len = RecodeBuf((unsigned char *)oldplop.buf, oldplop.len, oldplop.enc, enc, (unsigned char *)newbuf);
2505
 
                  user->u_plop.buf = newbuf;
2506
 
                  user->u_plop.enc = enc;
2507
 
                }
2508
 
              args += 2;
2509
 
            }
2510
 
#endif
2511
 
          if (args[0] && args[1])
2512
 
            OutputMsg(0, "%s: writebuf: too many arguments", rc_name);
2513
 
          else
2514
 
            WriteFile(user, args[0], DUMP_EXCHANGE);
2515
 
#ifdef ENCODINGS
2516
 
          if (user->u_plop.buf != oldplop.buf)
2517
 
            free(user->u_plop.buf);
2518
 
          user->u_plop = oldplop;
2519
 
        }
2520
 
#endif
2521
 
      break;
2522
 
    case RC_READBUF:
2523
 
#ifdef ENCODINGS
2524
 
      i = fore ? fore->w_encoding : display ? display->d_encoding : 0;
2525
 
      if (args[0] && args[1] && !strcmp(args[0], "-e"))
2526
 
        {
2527
 
          i = FindEncoding(args[1]);
2528
 
          if (i == -1)
2529
 
            {
2530
 
              OutputMsg(0, "%s: readbuf: unknown encoding", rc_name);
2531
 
              break;
2532
 
            }
2533
 
          args += 2;
2534
 
        }
2535
 
#endif
2536
 
      if (args[0] && args[1])
2537
 
        {
2538
 
          OutputMsg(0, "%s: readbuf: too many arguments", rc_name);
2539
 
          break;
2540
 
        }
2541
 
      if ((s = ReadFile(args[0] ? args[0] : BufferFile, &n)))
2542
 
        {
2543
 
          if (user->u_plop.buf)
2544
 
            UserFreeCopyBuffer(user);
2545
 
          user->u_plop.len = n;
2546
 
          user->u_plop.buf = s;
2547
 
#ifdef ENCODINGS
2548
 
          user->u_plop.enc = i;
2549
 
#endif
2550
 
        }
2551
 
      break;
2552
 
    case RC_REMOVEBUF:
2553
 
      KillBuffers();
2554
 
      break;
2555
 
    case RC_IGNORECASE:
2556
 
      (void)ParseSwitch(act, &search_ic);
2557
 
      if (msgok)
2558
 
        OutputMsg(0, "Will %signore case in searches", search_ic ? "" : "not ");
2559
 
      break;
2560
 
#endif                          /* COPY_PASTE */
2561
 
    case RC_ESCAPE:
2562
 
      if (*argl == 0)
2563
 
        SetEscape(user, -1, -1);
2564
 
      else if (*argl == 2)
2565
 
        SetEscape(user, (int)(unsigned char)args[0][0], (int)(unsigned char)args[0][1]);
2566
 
      else
2567
 
        {
2568
 
          OutputMsg(0, "%s: two characters required after escape.", rc_name);
2569
 
          break;
2570
 
        }
2571
 
      /* Change defescape if master user. This is because we only
2572
 
       * have one ktab.
2573
 
       */
2574
 
      if (display && user != users)
2575
 
        break;
2576
 
      /* FALLTHROUGH */
2577
 
    case RC_DEFESCAPE:
2578
 
      if (*argl == 0)
2579
 
        SetEscape(NULL, -1, -1);
2580
 
      else if (*argl == 2)
2581
 
        SetEscape(NULL, (int)(unsigned char)args[0][0], (int)(unsigned char)args[0][1]);
2582
 
      else
2583
 
        {
2584
 
          OutputMsg(0, "%s: two characters required after defescape.", rc_name);
2585
 
          break;
2586
 
        }
2587
 
#ifdef MAPKEYS
2588
 
      CheckEscape();
2589
 
#endif
2590
 
      break;
2591
 
    case RC_CHDIR:
2592
 
      s = *args ? *args : home;
2593
 
      if (chdir(s) == -1)
2594
 
        OutputMsg(errno, "%s", s);
2595
 
      break;
2596
 
    case RC_SHELL:
2597
 
    case RC_DEFSHELL:
2598
 
      if (ParseSaveStr(act, &ShellProg) == 0)
2599
 
        ShellArgs[0] = ShellProg;
2600
 
      break;
2601
 
    case RC_HARDCOPYDIR:
2602
 
      if (*args)
2603
 
        (void)ParseSaveStr(act, &hardcopydir);
2604
 
      if (msgok)
2605
 
        OutputMsg(0, "hardcopydir is %s\n", hardcopydir && *hardcopydir ? hardcopydir : "<cwd>");
2606
 
      break;
2607
 
    case RC_LOGFILE:
2608
 
      if (*args)
2609
 
        {
2610
 
          if (args[1] && !(strcmp(*args, "flush")))
2611
 
            {
2612
 
              log_flush = atoi(args[1]);
2613
 
              if (msgok)
2614
 
                OutputMsg(0, "log flush timeout set to %ds\n", log_flush);
2615
 
              break;
2616
 
            }
2617
 
          if (ParseSaveStr(act, &screenlogfile) || !msgok)
2618
 
            break;
2619
 
        }
2620
 
      OutputMsg(0, "logfile is '%s'", screenlogfile);
2621
 
      break;
2622
 
    case RC_LOGTSTAMP:
2623
 
      if (!*args || !strcmp(*args, "on") || !strcmp(*args, "off"))
2624
 
        {
2625
 
          if (ParseSwitch(act, &logtstamp_on) == 0 && msgok)
2626
 
            OutputMsg(0, "timestamps turned %s", logtstamp_on ? "on" : "off");
2627
 
        }
2628
 
      else if (!strcmp(*args, "string"))
2629
 
        {
2630
 
          if (args[1])
2631
 
            {
2632
 
              if (logtstamp_string)
2633
 
                free(logtstamp_string);
2634
 
              logtstamp_string = SaveStr(args[1]);
2635
 
            }
2636
 
          if (msgok)
2637
 
            OutputMsg(0, "logfile timestamp is '%s'", logtstamp_string);
2638
 
        }
2639
 
      else if (!strcmp(*args, "after"))
2640
 
        {
2641
 
          if (args[1])
2642
 
            {
2643
 
              logtstamp_after = atoi(args[1]);
2644
 
              if (!msgok)
2645
 
                break;
2646
 
            }
2647
 
          OutputMsg(0, "timestamp printed after %ds\n", logtstamp_after);
2648
 
        }
2649
 
      else
2650
 
        OutputMsg(0, "usage: logtstamp [after [n]|string [str]|on|off]");
2651
 
      break;
2652
 
    case RC_SHELLTITLE:
2653
 
      (void)ParseSaveStr(act, &nwin_default.aka);
2654
 
      break;
2655
 
    case RC_TERMCAP:
2656
 
    case RC_TERMCAPINFO:
2657
 
    case RC_TERMINFO:
2658
 
      if (!rc_name || !*rc_name)
2659
 
        OutputMsg(0, "Sorry, too late now. Place that in your .screenrc file.");
2660
 
      break;
2661
 
    case RC_SLEEP:
2662
 
      break;                    /* Already handled */
2663
 
    case RC_TERM:
2664
 
      s = NULL;
2665
 
      if (ParseSaveStr(act, &s))
2666
 
        break;
2667
 
      if (strlen(s) >= 20)
2668
 
        {
2669
 
          OutputMsg(0, "%s: term: argument too long ( < 20)", rc_name);
2670
 
          free(s);
2671
 
          break;
2672
 
        }
2673
 
      strcpy(screenterm, s);
2674
 
      free(s);
2675
 
      debug1("screenterm set to %s\n", screenterm);
2676
 
      MakeTermcap((display == 0));
2677
 
      debug("new termcap made\n");
2678
 
      break;
2679
 
    case RC_ECHO:
2680
 
      if (!msgok && (!rc_name || strcmp(rc_name, "-X")))
2681
 
        break;
2682
 
      /*
2683
 
       * user typed ^A:echo... well, echo isn't FinishRc's job,
2684
 
       * but as he wanted to test us, we show good will
2685
 
       */
2686
 
      if (argc > 1 && !strcmp(*args, "-n"))
2687
 
        {
2688
 
          args++;
2689
 
          argc--;
2690
 
        }
2691
 
      s = *args;
2692
 
      if (argc > 1 && !strcmp(*args, "-p"))
2693
 
        {
2694
 
          args++;
2695
 
          argc--;
2696
 
          s = *args;
2697
 
          if (s)
2698
 
            s = MakeWinMsg(s, fore, '%');
2699
 
        }
2700
 
      if (s)
2701
 
        OutputMsg(0, "%s", s);
2702
 
      else
2703
 
        {
2704
 
          OutputMsg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name);
2705
 
          queryflag = -1;
2706
 
        }
2707
 
      break;
2708
 
    case RC_BELL:
2709
 
    case RC_BELL_MSG:
2710
 
      if (*args == 0)
2711
 
        {
2712
 
          char buf[256];
2713
 
          AddXChars(buf, sizeof(buf), BellString);
2714
 
          OutputMsg(0, "bell_msg is '%s'", buf);
2715
 
          break;
2716
 
        }
2717
 
      (void)ParseSaveStr(act, &BellString);
2718
 
      break;
2719
 
#ifdef COPY_PASTE
2720
 
    case RC_BUFFERFILE:
2721
 
      if (*args == 0)
2722
 
        BufferFile = SaveStr(DEFAULT_BUFFERFILE);
2723
 
      else if (ParseSaveStr(act, &BufferFile))
2724
 
        break;
2725
 
      if (msgok)
2726
 
        OutputMsg(0, "Bufferfile is now '%s'", BufferFile);
2727
 
      break;
2728
 
#endif
2729
 
    case RC_ACTIVITY:
2730
 
      (void)ParseSaveStr(act, &ActivityString);
2731
 
      break;
2732
 
#if defined(DETACH) && defined(POW_DETACH)
2733
 
    case RC_POW_DETACH_MSG:
2734
 
      if (*args == 0)
2735
 
        {
2736
 
          char buf[256];
2737
 
          AddXChars(buf, sizeof(buf), PowDetachString);
2738
 
          OutputMsg(0, "pow_detach_msg is '%s'", buf);
2739
 
          break;
2740
 
        }
2741
 
      (void)ParseSaveStr(act, &PowDetachString);
2742
 
      break;
2743
 
#endif
2744
 
#if defined(UTMPOK) && defined(LOGOUTOK)
2745
 
    case RC_LOGIN:
2746
 
      n = fore->w_slot != (slot_t)-1;
2747
 
      if (*args && !strcmp(*args, "always"))
2748
 
        {
2749
 
          fore->w_lflag = 3;
2750
 
          if (!displays && n)
2751
 
            SlotToggle(n);
2752
 
          break;
2753
 
        }
2754
 
      if (*args && !strcmp(*args, "attached"))
2755
 
        {
2756
 
          fore->w_lflag = 1;
2757
 
          if (!displays && n)
2758
 
            SlotToggle(0);
2759
 
          break;
2760
 
        }
2761
 
      if (ParseSwitch(act, &n) == 0)
2762
 
        SlotToggle(n);
2763
 
      break;
2764
 
    case RC_DEFLOGIN:
2765
 
      if (!strcmp(*args, "always"))
2766
 
        nwin_default.lflag |= 2;
2767
 
      else if (!strcmp(*args, "attached"))
2768
 
        nwin_default.lflag &= ~2;
2769
 
      else
2770
 
        (void)ParseOnOff(act, &nwin_default.lflag);
2771
 
      break;
2772
 
#endif
2773
 
    case RC_DEFFLOW:
2774
 
      if (args[0] && args[1] && args[1][0] == 'i')
2775
 
        {
2776
 
          iflag = 1;
2777
 
          for (display = displays; display; display = display->d_next)
2778
 
            {
2779
 
              if (!D_flow)
2780
 
                continue;
2781
 
#if defined(TERMIO) || defined(POSIX)
2782
 
              D_NewMode.tio.c_cc[VINTR] = D_OldMode.tio.c_cc[VINTR];
2783
 
              D_NewMode.tio.c_lflag |= ISIG;
2784
 
#else /* TERMIO || POSIX */
2785
 
              D_NewMode.m_tchars.t_intrc = D_OldMode.m_tchars.t_intrc;
2786
 
#endif /* TERMIO || POSIX */
2787
 
              SetTTY(D_userfd, &D_NewMode);
2788
 
            }
2789
 
        }
2790
 
      if (args[0] && args[0][0] == 'a')
2791
 
        nwin_default.flowflag = FLOW_AUTOFLAG;
2792
 
      else
2793
 
        (void)ParseOnOff(act, &nwin_default.flowflag);
2794
 
      break;
2795
 
    case RC_DEFWRAP:
2796
 
      (void)ParseOnOff(act, &nwin_default.wrap);
2797
 
      break;
2798
 
    case RC_DEFC1:
2799
 
      (void)ParseOnOff(act, &nwin_default.c1);
2800
 
      break;
2801
 
#ifdef COLOR
2802
 
    case RC_DEFBCE:
2803
 
      (void)ParseOnOff(act, &nwin_default.bce);
2804
 
      break;
2805
 
#endif
2806
 
    case RC_DEFGR:
2807
 
      (void)ParseOnOff(act, &nwin_default.gr);
2808
 
      break;
2809
 
    case RC_DEFMONITOR:
2810
 
      if (ParseOnOff(act, &n) == 0)
2811
 
        nwin_default.monitor = (n == 0) ? MON_OFF : MON_ON;
2812
 
      break;
2813
 
    case RC_DEFMOUSETRACK:
2814
 
      if (ParseOnOff(act, &n) == 0)
2815
 
        defmousetrack = (n == 0) ? 0 : 1000;
2816
 
      break;
2817
 
    case RC_MOUSETRACK:
2818
 
      if (!args[0])
2819
 
        {
2820
 
          OutputMsg(0, "Mouse tracking for this display is turned %s", D_mousetrack ? "on" : "off");
2821
 
        }
2822
 
      else if (ParseOnOff(act, &n) == 0)
2823
 
        {
2824
 
          D_mousetrack = n == 0 ? 0 : 1000;
2825
 
          if (D_fore)
2826
 
            MouseMode(D_fore->w_mouse);
2827
 
        }
2828
 
      break;
2829
 
    case RC_DEFSILENCE:
2830
 
      if (ParseOnOff(act, &n) == 0)
2831
 
        nwin_default.silence = (n == 0) ? SILENCE_OFF : SILENCE_ON;
2832
 
      break;
2833
 
    case RC_VERBOSE:
2834
 
      if (!*args)
2835
 
        OutputMsg(0, "W%s echo command when creating windows.", 
2836
 
          VerboseCreate ? "ill" : "on't");
2837
 
      else if (ParseOnOff(act, &n) == 0)
2838
 
        VerboseCreate = n;
2839
 
      break;
2840
 
    case RC_HARDSTATUS:
2841
 
      if (display)
2842
 
        {
2843
 
          OutputMsg(0, "%s", "");       /* wait till mintime (keep gcc quiet) */
2844
 
          RemoveStatus();
2845
 
        }
2846
 
      if (args[0] && strcmp(args[0], "on") && strcmp(args[0], "off"))
2847
 
        {
2848
 
          struct display *olddisplay = display;
2849
 
          int old_use, new_use = -1;
2850
 
 
2851
 
          s = args[0];
2852
 
          if (!strncmp(s, "always", 6))
2853
 
            s += 6;
2854
 
          if (!strcmp(s, "lastline"))
2855
 
            new_use = HSTATUS_LASTLINE;
2856
 
          else if (!strcmp(s, "ignore"))
2857
 
            new_use = HSTATUS_IGNORE;
2858
 
          else if (!strcmp(s, "message"))
2859
 
            new_use = HSTATUS_MESSAGE;
2860
 
          else if (!strcmp(args[0], "string"))
2861
 
            {
2862
 
              if (!args[1])
2863
 
                {
2864
 
                  char buf[256];
2865
 
                  AddXChars(buf, sizeof(buf), hstatusstring);
2866
 
                  OutputMsg(0, "hardstatus string is '%s'", buf);
2867
 
                  break;
2868
 
                }
2869
 
            }
2870
 
          else
2871
 
            {
2872
 
              OutputMsg(0, "%s: usage: hardstatus [always]lastline|ignore|message|string [string]", rc_name);
2873
 
              break;
2874
 
            }
2875
 
          if (new_use != -1)
2876
 
            {
2877
 
              hardstatusemu = new_use | (s == args[0] ? 0 : HSTATUS_ALWAYS);
2878
 
              for (display = displays; display; display = display->d_next)
2879
 
                {
2880
 
                  RemoveStatus();
2881
 
                  new_use = hardstatusemu & ~HSTATUS_ALWAYS;
2882
 
                  if (D_HS && s == args[0])
2883
 
                    new_use = HSTATUS_HS;
2884
 
                  ShowHStatus((char *)0);
2885
 
                  old_use = D_has_hstatus;
2886
 
                  D_has_hstatus = new_use;
2887
 
                  if ((new_use == HSTATUS_LASTLINE && old_use != HSTATUS_LASTLINE) || (new_use != HSTATUS_LASTLINE && old_use == HSTATUS_LASTLINE))
2888
 
                    ChangeScreenSize(D_width, D_height, 1);
2889
 
                  RefreshHStatus();
2890
 
                }
2891
 
            }
2892
 
          if (args[1])
2893
 
            {
2894
 
              if (hstatusstring)
2895
 
                free(hstatusstring);
2896
 
              hstatusstring = SaveStr(args[1]);
2897
 
              for (display = displays; display; display = display->d_next)
2898
 
                RefreshHStatus();
2899
 
            }
2900
 
          display = olddisplay;
2901
 
          break;
2902
 
        }
2903
 
      (void)ParseSwitch(act, &use_hardstatus);
2904
 
      if (msgok)
2905
 
        OutputMsg(0, "messages displayed on %s", use_hardstatus ? "hardstatus line" : "window");
2906
 
      break;
2907
 
    case RC_CAPTION:
2908
 
      if (strcmp(args[0], "always") == 0 || strcmp(args[0], "splitonly") == 0)
2909
 
        {
2910
 
          struct display *olddisplay = display;
2911
 
 
2912
 
          captionalways = args[0][0] == 'a';
2913
 
          for (display = displays; display; display = display->d_next)
2914
 
            ChangeScreenSize(D_width, D_height, 1);
2915
 
          display = olddisplay;
2916
 
        }
2917
 
      else if (strcmp(args[0], "string") == 0)
2918
 
        {
2919
 
          if (!args[1])
2920
 
            {
2921
 
              char buf[256];
2922
 
              AddXChars(buf, sizeof(buf), captionstring);
2923
 
              OutputMsg(0, "caption string is '%s'", buf);
2924
 
              break;
2925
 
            }
2926
 
        }
2927
 
      else
2928
 
        {
2929
 
          OutputMsg(0, "%s: usage: caption always|splitonly|string <string>", rc_name);
2930
 
          break;
2931
 
        }
2932
 
      if (!args[1])
2933
 
        break;
2934
 
      if (captionstring)
2935
 
        free(captionstring);
2936
 
      captionstring = SaveStr(args[1]);
2937
 
      RedisplayDisplays(0);
2938
 
      break;
2939
 
    case RC_CONSOLE:
2940
 
      n = (console_window != 0);
2941
 
      if (ParseSwitch(act, &n))
2942
 
        break;
2943
 
      if (TtyGrabConsole(fore->w_ptyfd, n, rc_name))
2944
 
        break;
2945
 
      if (n == 0)
2946
 
          OutputMsg(0, "%s: releasing console %s", rc_name, HostName);
2947
 
      else if (console_window)
2948
 
          OutputMsg(0, "%s: stealing console %s from window %d (%s)", rc_name, 
2949
 
              HostName, console_window->w_number, console_window->w_title);
2950
 
      else
2951
 
          OutputMsg(0, "%s: grabbing console %s", rc_name, HostName);
2952
 
      console_window = n ? fore : 0;
2953
 
      break;
2954
 
    case RC_ALLPARTIAL:
2955
 
      if (ParseOnOff(act, &all_norefresh))
2956
 
        break;
2957
 
      if (!all_norefresh && fore)
2958
 
        Activate(-1);
2959
 
      if (msgok)
2960
 
        OutputMsg(0, all_norefresh ? "No refresh on window change!\n" :
2961
 
                               "Window specific refresh\n");
2962
 
      break;
2963
 
    case RC_PARTIAL:
2964
 
      (void)ParseSwitch(act, &n);
2965
 
      fore->w_norefresh = n;
2966
 
      break;
2967
 
    case RC_VBELL:
2968
 
      if (ParseSwitch(act, &visual_bell) || !msgok)
2969
 
        break;
2970
 
      if (visual_bell == 0)
2971
 
        OutputMsg(0, "switched to audible bell.");
2972
 
      else
2973
 
        OutputMsg(0, "switched to visual bell.");
2974
 
      break;
2975
 
    case RC_VBELLWAIT:
2976
 
      if (ParseNum1000(act, &VBellWait) == 0 && msgok)
2977
 
        OutputMsg(0, "vbellwait set to %.10g seconds", VBellWait/1000.);
2978
 
      break;
2979
 
    case RC_MSGWAIT:
2980
 
      if (ParseNum1000(act, &MsgWait) == 0 && msgok)
2981
 
        OutputMsg(0, "msgwait set to %.10g seconds", MsgWait/1000.);
2982
 
      break;
2983
 
    case RC_MSGMINWAIT:
2984
 
      if (ParseNum1000(act, &MsgMinWait) == 0 && msgok)
2985
 
        OutputMsg(0, "msgminwait set to %.10g seconds", MsgMinWait/1000.);
2986
 
      break;
2987
 
    case RC_SILENCEWAIT:
2988
 
      if (ParseNum(act, &SilenceWait))
2989
 
        break;
2990
 
      if (SilenceWait < 1)
2991
 
        SilenceWait = 1;
2992
 
      for (p = windows; p; p = p->w_next)
2993
 
        p->w_silencewait = SilenceWait;
2994
 
      if (msgok)
2995
 
        OutputMsg(0, "silencewait set to %d seconds", SilenceWait);
2996
 
      break;
2997
 
    case RC_NUMBER:
2998
 
      if (*args == 0)
2999
 
        OutputMsg(0, queryflag >= 0 ? "%d (%s)" : "This is window %d (%s).", fore->w_number, fore->w_title);
3000
 
      else
3001
 
        {
3002
 
          int old = fore->w_number;
3003
 
          int rel = 0, parse;
3004
 
          if (args[0][0] == '+')
3005
 
            rel = 1;
3006
 
          else if (args[0][0] == '-')
3007
 
            rel = -1;
3008
 
          if (rel)
3009
 
            ++act->args[0];
3010
 
          parse = ParseNum(act, &n);
3011
 
          if (rel)
3012
 
            --act->args[0];
3013
 
          if (parse)
3014
 
            break;
3015
 
          if (rel > 0)
3016
 
            n += old;
3017
 
          else if (rel < 0)
3018
 
            n = old - n;
3019
 
          if (!WindowChangeNumber(fore, n))
3020
 
            {
3021
 
              /* Window number could not be changed. */
3022
 
              queryflag = -1;
3023
 
              return;
3024
 
            }
3025
 
        }
3026
 
      break;
3027
 
    case RC_SILENCE:
3028
 
      n = fore->w_silence != 0;
3029
 
      i = fore->w_silencewait;
3030
 
      if (args[0] && (args[0][0] == '-' || (args[0][0] >= '0' && args[0][0] <= '9')))
3031
 
        {
3032
 
          if (ParseNum(act, &i))
3033
 
            break;
3034
 
          n = i > 0;
3035
 
        }
3036
 
      else if (ParseSwitch(act, &n))
3037
 
        break;
3038
 
      if (n)
3039
 
        {
3040
 
#ifdef MULTIUSER
3041
 
          if (display)  /* we tell only this user */
3042
 
            ACLBYTE(fore->w_lio_notify, D_user->u_id) |= ACLBIT(D_user->u_id);
3043
 
          else
3044
 
            for (n = 0; n < maxusercount; n++)
3045
 
              ACLBYTE(fore->w_lio_notify, n) |= ACLBIT(n);
3046
 
#endif
3047
 
          fore->w_silencewait = i;
3048
 
          fore->w_silence = SILENCE_ON;
3049
 
          SetTimeout(&fore->w_silenceev, fore->w_silencewait * 1000);
3050
 
          evenq(&fore->w_silenceev);
3051
 
 
3052
 
          if (!msgok)
3053
 
            break;
3054
 
          OutputMsg(0, "The window is now being monitored for %d sec. silence.", fore->w_silencewait);
3055
 
        }
3056
 
      else
3057
 
        {
3058
 
#ifdef MULTIUSER
3059
 
          if (display) /* we remove only this user */
3060
 
            ACLBYTE(fore->w_lio_notify, D_user->u_id) 
3061
 
              &= ~ACLBIT(D_user->u_id);
3062
 
          else
3063
 
            for (n = 0; n < maxusercount; n++)
3064
 
              ACLBYTE(fore->w_lio_notify, n) &= ~ACLBIT(n);
3065
 
          for (i = maxusercount - 1; i >= 0; i--)
3066
 
            if (ACLBYTE(fore->w_lio_notify, i))
3067
 
              break;
3068
 
          if (i < 0)
3069
 
#endif
3070
 
            {
3071
 
              fore->w_silence = SILENCE_OFF;
3072
 
              evdeq(&fore->w_silenceev);
3073
 
            }
3074
 
          if (!msgok)
3075
 
            break;
3076
 
          OutputMsg(0, "The window is no longer being monitored for silence.");
3077
 
        }
3078
 
      break;
3079
 
#ifdef COPY_PASTE
3080
 
    case RC_DEFSCROLLBACK:
3081
 
      (void)ParseNum(act, &nwin_default.histheight);
3082
 
      break;
3083
 
    case RC_SCROLLBACK:
3084
 
      if (flayer->l_layfn == &MarkLf)
3085
 
        {
3086
 
          OutputMsg(0, "Cannot resize scrollback buffer in copy/scrollback mode.");
3087
 
          break;
3088
 
        }
3089
 
      (void)ParseNum(act, &n);
3090
 
      ChangeWindowSize(fore, fore->w_width, fore->w_height, n);
3091
 
      if (msgok)
3092
 
        OutputMsg(0, "scrollback set to %d", fore->w_histheight);
3093
 
      break;
3094
 
#endif
3095
 
    case RC_SESSIONNAME:
3096
 
      if (*args == 0)
3097
 
        OutputMsg(0, "This session is named '%s'\n", SockName);
3098
 
      else
3099
 
        {
3100
 
          char buf[MAXPATHLEN];
3101
 
 
3102
 
          s = 0;
3103
 
          if (ParseSaveStr(act, &s))
3104
 
            break;
3105
 
          if (!*s || strlen(s) + (SockName - SockPath) > MAXPATHLEN - 13 || index(s, '/'))
3106
 
            {
3107
 
              OutputMsg(0, "%s: bad session name '%s'\n", rc_name, s);
3108
 
              free(s);
3109
 
              break;
3110
 
            }
3111
 
          strncpy(buf, SockPath, SockName - SockPath);
3112
 
          sprintf(buf + (SockName - SockPath), "%d.%s", (int)getpid(), s); 
3113
 
          free(s);
3114
 
          if ((access(buf, F_OK) == 0) || (errno != ENOENT))
3115
 
            {
3116
 
              OutputMsg(0, "%s: inappropriate path: '%s'.", rc_name, buf);
3117
 
              break;
3118
 
            }
3119
 
          if (rename(SockPath, buf))
3120
 
            {
3121
 
              OutputMsg(errno, "%s: failed to rename(%s, %s)", rc_name, SockPath, buf);
3122
 
              break;
3123
 
            }
3124
 
          debug2("rename(%s, %s) done\n", SockPath, buf);
3125
 
          strcpy(SockPath, buf);
3126
 
          MakeNewEnv();
3127
 
          WindowChanged((struct win *)0, 'S');
3128
 
        }
3129
 
      break;
3130
 
    case RC_SETENV:
3131
 
      if (!args[0] || !args[1])
3132
 
        {
3133
 
          debug1("RC_SETENV arguments missing: %s\n", args[0] ? args[0] : "");
3134
 
          InputSetenv(args[0]);
3135
 
        }
3136
 
      else
3137
 
        {
3138
 
          xsetenv(args[0], args[1]);
3139
 
          MakeNewEnv();
3140
 
        }
3141
 
      break;
3142
 
    case RC_UNSETENV:
3143
 
      unsetenv(*args);
3144
 
      MakeNewEnv();
3145
 
      break;
3146
 
#ifdef COPY_PASTE
3147
 
    case RC_DEFSLOWPASTE:
3148
 
      (void)ParseNum(act, &nwin_default.slow);
3149
 
      break;
3150
 
    case RC_SLOWPASTE:
3151
 
      if (*args == 0)
3152
 
        OutputMsg(0, fore->w_slowpaste ? 
3153
 
               "Slowpaste in window %d is %d milliseconds." :
3154
 
               "Slowpaste in window %d is unset.", 
3155
 
            fore->w_number, fore->w_slowpaste);
3156
 
      else if (ParseNum(act, &fore->w_slowpaste) == 0 && msgok)
3157
 
        OutputMsg(0, fore->w_slowpaste ?
3158
 
               "Slowpaste in window %d set to %d milliseconds." :
3159
 
               "Slowpaste in window %d now unset.", 
3160
 
            fore->w_number, fore->w_slowpaste);
3161
 
      break;
3162
 
    case RC_MARKKEYS:
3163
 
      if (CompileKeys(*args, *argl, mark_key_tab))
3164
 
        {
3165
 
          OutputMsg(0, "%s: markkeys: syntax error.", rc_name);
3166
 
          break;
3167
 
        }
3168
 
      debug1("markkeys %s\n", *args);
3169
 
      break;
3170
 
# ifdef FONT
3171
 
    case RC_PASTEFONT:
3172
 
      if (ParseSwitch(act, &pastefont) == 0 && msgok)
3173
 
        OutputMsg(0, "Will %spaste font settings", pastefont ? "" : "not ");
3174
 
      break;
3175
 
# endif
3176
 
    case RC_CRLF:
3177
 
      (void)ParseSwitch(act, &join_with_cr);
3178
 
      break;
3179
 
    case RC_COMPACTHIST:
3180
 
      if (ParseSwitch(act, &compacthist) == 0 && msgok)
3181
 
        OutputMsg(0, "%scompacting history lines", compacthist ? "" : "not ");
3182
 
      break;
3183
 
#endif
3184
 
#ifdef NETHACK
3185
 
    case RC_NETHACK:
3186
 
      (void)ParseOnOff(act, &nethackflag);
3187
 
      break;
3188
 
#endif
3189
 
    case RC_HARDCOPY_APPEND:
3190
 
      (void)ParseOnOff(act, &hardcopy_append);
3191
 
      break;
3192
 
    case RC_VBELL_MSG:
3193
 
      if (*args == 0) 
3194
 
        { 
3195
 
          char buf[256];
3196
 
          AddXChars(buf, sizeof(buf), VisualBellString);
3197
 
          OutputMsg(0, "vbell_msg is '%s'", buf);
3198
 
          break; 
3199
 
        }
3200
 
      (void)ParseSaveStr(act, &VisualBellString);
3201
 
      debug1(" new vbellstr '%s'\n", VisualBellString);
3202
 
      break;
3203
 
    case RC_DEFMODE:
3204
 
      if (ParseBase(act, *args, &n, 8, "octal"))
3205
 
        break;
3206
 
      if (n < 0 || n > 0777)
3207
 
        {
3208
 
          OutputMsg(0, "%s: mode: Invalid tty mode %o", rc_name, n);
3209
 
          break;
3210
 
        }
3211
 
      TtyMode = n;
3212
 
      if (msgok)
3213
 
        OutputMsg(0, "Ttymode set to %03o", TtyMode);
3214
 
      break;
3215
 
    case RC_AUTODETACH:
3216
 
      (void)ParseOnOff(act, &auto_detach);
3217
 
      break;
3218
 
    case RC_STARTUP_MESSAGE:
3219
 
      (void)ParseOnOff(act, &default_startup);
3220
 
      break;
3221
 
#ifdef PASSWORD
3222
 
    case RC_PASSWORD:
3223
 
      if (*args)
3224
 
        {
3225
 
          n = (*user->u_password) ? 1 : 0;
3226
 
          if (user->u_password != NullStr) free((char *)user->u_password);
3227
 
          user->u_password = SaveStr(*args);
3228
 
          if (!strcmp(user->u_password, "none"))
3229
 
            {
3230
 
              if (n)
3231
 
                OutputMsg(0, "Password checking disabled");
3232
 
              free(user->u_password);
3233
 
              user->u_password = NullStr;
3234
 
            }
3235
 
        }
3236
 
      else
3237
 
        {
3238
 
          if (!fore)
3239
 
            {
3240
 
              OutputMsg(0, "%s: password: window required", rc_name);
3241
 
              break;
3242
 
            }
3243
 
          Input("New screen password:", 100, INP_NOECHO, pass1, display ? (char *)D_user : (char *)users, 0);
3244
 
        }
3245
 
      break;
3246
 
#endif                          /* PASSWORD */
3247
 
    case RC_BIND:
3248
 
        {
3249
 
          struct action *ktabp = ktab;
3250
 
          int kflag = 0;
3251
 
 
3252
 
          for (;;)
3253
 
            {
3254
 
              if (argc > 2 && !strcmp(*args, "-c"))
3255
 
                {
3256
 
                  ktabp = FindKtab(args[1], 1);
3257
 
                  if (ktabp == 0)
3258
 
                    break;
3259
 
                  args += 2;
3260
 
                  argl += 2;
3261
 
                  argc -= 2;
3262
 
                }
3263
 
              else if (argc > 1 && !strcmp(*args, "-k"))
3264
 
                {
3265
 
                  kflag = 1;
3266
 
                  args++;
3267
 
                  argl++;
3268
 
                  argc--;
3269
 
                }
3270
 
              else
3271
 
                break;
3272
 
            }
3273
 
#ifdef MAPKEYS
3274
 
          if (kflag)
3275
 
            {
3276
 
              for (n = 0; n < KMAP_KEYS; n++)
3277
 
                if (strcmp(term[n + T_CAPS].tcname, *args) == 0)
3278
 
                  break;
3279
 
              if (n == KMAP_KEYS)
3280
 
                {
3281
 
                  OutputMsg(0, "%s: bind: unknown key '%s'", rc_name, *args);
3282
 
                  break;
3283
 
                }
3284
 
              n += 256;
3285
 
            }
3286
 
          else
3287
 
#endif
3288
 
          if (*argl != 1)
3289
 
            {
3290
 
              OutputMsg(0, "%s: bind: character, ^x, or (octal) \\032 expected.", rc_name);
3291
 
              break;
3292
 
            }
3293
 
          else
3294
 
            n = (unsigned char)args[0][0];
3295
 
 
3296
 
          if (args[1])
3297
 
            {
3298
 
              if ((i = FindCommnr(args[1])) == RC_ILLEGAL)
3299
 
                {
3300
 
                  OutputMsg(0, "%s: bind: unknown command '%s'", rc_name, args[1]);
3301
 
                  break;
3302
 
                }
3303
 
              if (CheckArgNum(i, args + 2) < 0)
3304
 
                break;
3305
 
              ClearAction(&ktabp[n]);
3306
 
              SaveAction(ktabp + n, i, args + 2, argl + 2);
3307
 
            }
3308
 
          else
3309
 
            ClearAction(&ktabp[n]);
3310
 
        }
3311
 
      break;
3312
 
#ifdef MAPKEYS
3313
 
    case RC_BINDKEY:
3314
 
        {
3315
 
          struct action *newact;
3316
 
          int newnr, fl = 0, kf = 0, af = 0, df = 0, mf = 0;
3317
 
          struct display *odisp = display;
3318
 
          int used = 0;
3319
 
          struct kmap_ext *kme = NULL;
3320
 
 
3321
 
          for (; *args && **args == '-'; args++, argl++)
3322
 
            {
3323
 
              if (strcmp(*args, "-t") == 0)
3324
 
                fl = KMAP_NOTIMEOUT;
3325
 
              else if (strcmp(*args, "-k") == 0)
3326
 
                kf = 1;
3327
 
              else if (strcmp(*args, "-a") == 0)
3328
 
                af = 1;
3329
 
              else if (strcmp(*args, "-d") == 0)
3330
 
                df = 1;
3331
 
              else if (strcmp(*args, "-m") == 0)
3332
 
                mf = 1;
3333
 
              else if (strcmp(*args, "--") == 0)
3334
 
                {
3335
 
                  args++;
3336
 
                  argl++;
3337
 
                  break;
3338
 
                }
3339
 
              else
3340
 
                {
3341
 
                  OutputMsg(0, "%s: bindkey: invalid option %s", rc_name, *args);
3342
 
                  return;
3343
 
                }
3344
 
            }
3345
 
          if (df && mf)
3346
 
            {
3347
 
              OutputMsg(0, "%s: bindkey: -d does not work with -m", rc_name);
3348
 
              break;
3349
 
            }
3350
 
          if (*args == 0)
3351
 
            {
3352
 
              if (mf)
3353
 
                display_bindkey("Edit mode", mmtab);
3354
 
              else if (df)
3355
 
                display_bindkey("Default", dmtab);
3356
 
              else
3357
 
                display_bindkey("User", umtab);
3358
 
              break;
3359
 
            }
3360
 
          if (kf == 0)
3361
 
            {
3362
 
              if (af)
3363
 
                {
3364
 
                  OutputMsg(0, "%s: bindkey: -a only works with -k", rc_name);
3365
 
                  break;
3366
 
                }
3367
 
              if (*argl == 0)
3368
 
                {
3369
 
                  OutputMsg(0, "%s: bindkey: empty string makes no sense", rc_name);
3370
 
                  break;
3371
 
                }
3372
 
              for (i = 0, kme = kmap_exts; i < kmap_extn; i++, kme++)
3373
 
                if (kme->str == 0)
3374
 
                  {
3375
 
                    if (args[1])
3376
 
                      break;
3377
 
                  }
3378
 
                else
3379
 
                  if (*argl == (kme->fl & ~KMAP_NOTIMEOUT) && bcmp(kme->str, *args, *argl) == 0)
3380
 
                      break;
3381
 
              if (i == kmap_extn)
3382
 
                {
3383
 
                  if (!args[1])
3384
 
                    {
3385
 
                      OutputMsg(0, "%s: bindkey: keybinding not found", rc_name);
3386
 
                      break;
3387
 
                    }
3388
 
                  kmap_extn += 8;
3389
 
                  kmap_exts = (struct kmap_ext *)xrealloc((char *)kmap_exts, kmap_extn * sizeof(*kmap_exts));
3390
 
                  kme = kmap_exts + i;
3391
 
                  bzero((char *)kme, 8 * sizeof(*kmap_exts));
3392
 
                  for (; i < kmap_extn; i++, kme++)
3393
 
                    {
3394
 
                      kme->str = 0;
3395
 
                      kme->dm.nr = kme->mm.nr = kme->um.nr = RC_ILLEGAL;
3396
 
                      kme->dm.args = kme->mm.args = kme->um.args = noargs;
3397
 
                      kme->dm.argl = kme->mm.argl = kme->um.argl = 0;
3398
 
                    }
3399
 
                  i -= 8;
3400
 
                  kme -= 8;
3401
 
                }
3402
 
              if (df == 0 && kme->dm.nr != RC_ILLEGAL)
3403
 
                used = 1;
3404
 
              if (mf == 0 && kme->mm.nr != RC_ILLEGAL)
3405
 
                used = 1;
3406
 
              if ((df || mf) && kme->um.nr != RC_ILLEGAL)
3407
 
                used = 1;
3408
 
              i += KMAP_KEYS + KMAP_AKEYS;
3409
 
              newact = df ? &kme->dm : mf ? &kme->mm : &kme->um;
3410
 
            }
3411
 
          else
3412
 
            {
3413
 
              for (i = T_CAPS; i < T_OCAPS; i++)
3414
 
                if (strcmp(term[i].tcname, *args) == 0)
3415
 
                  break;
3416
 
              if (i == T_OCAPS)
3417
 
                {
3418
 
                  OutputMsg(0, "%s: bindkey: unknown key '%s'", rc_name, *args);
3419
 
                  break;
3420
 
                }
3421
 
              if (af && i >= T_CURSOR && i < T_OCAPS)
3422
 
                i -=  T_CURSOR - KMAP_KEYS;
3423
 
              else
3424
 
                i -=  T_CAPS;
3425
 
              newact = df ? &dmtab[i] : mf ? &mmtab[i] : &umtab[i];
3426
 
            }
3427
 
          if (args[1])
3428
 
            {
3429
 
              if ((newnr = FindCommnr(args[1])) == RC_ILLEGAL)
3430
 
                {
3431
 
                  OutputMsg(0, "%s: bindkey: unknown command '%s'", rc_name, args[1]);
3432
 
                  break;
3433
 
                }
3434
 
              if (CheckArgNum(newnr, args + 2) < 0)
3435
 
                break;
3436
 
              ClearAction(newact);
3437
 
              SaveAction(newact, newnr, args + 2, argl + 2);
3438
 
              if (kf == 0 && args[1])
3439
 
                {
3440
 
                  if (kme->str)
3441
 
                    free(kme->str);
3442
 
                  kme->str = SaveStrn(*args, *argl);
3443
 
                  kme->fl = fl | *argl;
3444
 
                }
3445
 
            }
3446
 
          else
3447
 
            ClearAction(newact);
3448
 
          for (display = displays; display; display = display->d_next)
3449
 
            remap(i, args[1] ? 1 : 0);
3450
 
          if (kf == 0 && !args[1])
3451
 
            {
3452
 
              if (!used && kme->str)
3453
 
                {
3454
 
                  free(kme->str);
3455
 
                  kme->str = 0;
3456
 
                  kme->fl = 0;
3457
 
                }
3458
 
            }
3459
 
          display = odisp;
3460
 
        }
3461
 
      break;
3462
 
    case RC_MAPTIMEOUT:
3463
 
      if (*args)
3464
 
        {
3465
 
          if (ParseNum(act, &n))
3466
 
            break;
3467
 
          if (n < 0)
3468
 
            {
3469
 
              OutputMsg(0, "%s: maptimeout: illegal time %d", rc_name, n);
3470
 
              break;
3471
 
            }
3472
 
          maptimeout = n;
3473
 
        }
3474
 
      if (*args == 0 || msgok)
3475
 
        OutputMsg(0, "maptimeout is %dms", maptimeout);
3476
 
      break;
3477
 
    case RC_MAPNOTNEXT:
3478
 
      D_dontmap = 1;
3479
 
      break;
3480
 
    case RC_MAPDEFAULT:
3481
 
      D_mapdefault = 1;
3482
 
      break;
3483
 
#endif
3484
 
#ifdef MULTIUSER
3485
 
    case RC_ACLCHG:
3486
 
    case RC_ACLADD:
3487
 
    case RC_ADDACL:
3488
 
    case RC_CHACL:
3489
 
      UsersAcl(NULL, argc, args);
3490
 
      break;
3491
 
    case RC_ACLDEL:
3492
 
      if (UserDel(args[0], NULL))
3493
 
        break;
3494
 
      if (msgok)
3495
 
        OutputMsg(0, "%s removed from acl database", args[0]);
3496
 
      break;
3497
 
    case RC_ACLGRP:
3498
 
      /*
3499
 
       * modify a user to gain or lose rights granted to a group.
3500
 
       * This group is actually a normal user whose rights were defined
3501
 
       * with chacl in the usual way.
3502
 
       */
3503
 
      if (args[1])
3504
 
        {
3505
 
          if (strcmp(args[1], "none"))  /* link a user to another user */
3506
 
            {
3507
 
              if (AclLinkUser(args[0], args[1]))
3508
 
                break;
3509
 
              if (msgok)
3510
 
                OutputMsg(0, "User %s joined acl-group %s", args[0], args[1]);
3511
 
            }
3512
 
          else                          /* remove all groups from user */
3513
 
            {
3514
 
              struct acluser *u;
3515
 
              struct aclusergroup *g;
3516
 
 
3517
 
              if (!(u = *FindUserPtr(args[0])))
3518
 
                break;
3519
 
              while ((g = u->u_group))
3520
 
                {
3521
 
                  u->u_group = g->next;
3522
 
                  free((char *)g);
3523
 
                }
3524
 
            }
3525
 
        }
3526
 
      else                              /* show all groups of user */
3527
 
        {
3528
 
          char buf[256], *p = buf;
3529
 
          int ngroups = 0;
3530
 
          struct acluser *u;
3531
 
          struct aclusergroup *g;
3532
 
 
3533
 
          if (!(u = *FindUserPtr(args[0])))
3534
 
            {
3535
 
              if (msgok)
3536
 
                OutputMsg(0, "User %s does not exist.", args[0]);
3537
 
              break;
3538
 
            }
3539
 
          g = u->u_group;
3540
 
          while (g)
3541
 
            {
3542
 
              ngroups++;
3543
 
              sprintf(p, "%s ", g->u->u_name);
3544
 
              p += strlen(p);
3545
 
              if (p > buf+200)
3546
 
                break;
3547
 
              g = g->next;
3548
 
            }
3549
 
          if (ngroups)
3550
 
            *(--p) = '\0';
3551
 
          OutputMsg(0, "%s's group%s: %s.", args[0], (ngroups == 1) ? "" : "s",
3552
 
              (ngroups == 0) ? "none" : buf);
3553
 
        }
3554
 
      break;
3555
 
    case RC_ACLUMASK:
3556
 
    case RC_UMASK:
3557
 
      while ((s = *args++))
3558
 
        {
3559
 
          char *err = 0;
3560
 
 
3561
 
          if (AclUmask(display ? D_user : users, s, &err))
3562
 
            OutputMsg(0, "umask: %s\n", err);
3563
 
        }
3564
 
      break;
3565
 
    case RC_MULTIUSER:
3566
 
      if (ParseOnOff(act, &n))
3567
 
        break;
3568
 
      multi = n ? "" : 0;
3569
 
      chsock();
3570
 
      if (msgok)
3571
 
        OutputMsg(0, "Multiuser mode %s", multi ? "enabled" : "disabled");
3572
 
      break;
3573
 
#endif /* MULTIUSER */
3574
 
#ifdef PSEUDOS
3575
 
    case RC_EXEC:
3576
 
      winexec(args);
3577
 
      break;
3578
 
#endif
3579
 
#ifdef MULTI
3580
 
    case RC_NONBLOCK:
3581
 
      i = D_nonblock >= 0;
3582
 
      if (*args && ((args[0][0] >= '0' && args[0][0] <= '9') || args[0][0] == '.'))
3583
 
        {
3584
 
          if (ParseNum1000(act, &i))
3585
 
            break;
3586
 
        }
3587
 
      else if (!ParseSwitch(act, &i))
3588
 
        i = i == 0 ? -1 : 1000;
3589
 
      else
3590
 
        break;
3591
 
      if (msgok && i == -1)
3592
 
        OutputMsg(0, "display set to blocking mode");
3593
 
      else if (msgok && i == 0)
3594
 
        OutputMsg(0, "display set to nonblocking mode, no timeout");
3595
 
      else if (msgok)
3596
 
        OutputMsg(0, "display set to nonblocking mode, %.10gs timeout", i/1000.);
3597
 
      D_nonblock = i;
3598
 
      if (D_nonblock <= 0)
3599
 
        evdeq(&D_blockedev);
3600
 
      break;
3601
 
    case RC_DEFNONBLOCK:
3602
 
      if (*args && ((args[0][0] >= '0' && args[0][0] <= '9') || args[0][0] == '.'))
3603
 
        {
3604
 
          if (ParseNum1000(act, &defnonblock))
3605
 
            break;
3606
 
        }
3607
 
      else if (!ParseOnOff(act, &defnonblock))
3608
 
        defnonblock = defnonblock == 0 ? -1 : 1000;
3609
 
      else
3610
 
        break;
3611
 
      if (display && *rc_name)
3612
 
        {
3613
 
          D_nonblock = defnonblock;
3614
 
          if (D_nonblock <= 0)
3615
 
            evdeq(&D_blockedev);
3616
 
        }
3617
 
      break;
3618
 
#endif
3619
 
    case RC_GR:
3620
 
#ifdef ENCODINGS
3621
 
      if (fore->w_gr == 2)
3622
 
        fore->w_gr = 0;
3623
 
#endif
3624
 
      if (ParseSwitch(act, &fore->w_gr) == 0 && msgok)
3625
 
        OutputMsg(0, "Will %suse GR", fore->w_gr ? "" : "not ");
3626
 
#ifdef ENCODINGS
3627
 
      if (fore->w_gr == 0 && fore->w_FontE)
3628
 
        fore->w_gr = 2;
3629
 
#endif
3630
 
      break;
3631
 
    case RC_C1:
3632
 
      if (ParseSwitch(act, &fore->w_c1) == 0 && msgok)
3633
 
        OutputMsg(0, "Will %suse C1", fore->w_c1 ? "" : "not ");
3634
 
      break;
3635
 
#ifdef COLOR
3636
 
    case RC_BCE:
3637
 
      if (ParseSwitch(act, &fore->w_bce) == 0 && msgok)
3638
 
        OutputMsg(0, "Will %serase with background color", fore->w_bce ? "" : "not ");
3639
 
      break;
3640
 
#endif
3641
 
#ifdef ENCODINGS
3642
 
    case RC_KANJI:
3643
 
    case RC_ENCODING:
3644
 
#ifdef UTF8
3645
 
      if (*args && !strcmp(args[0], "-d"))
3646
 
        {
3647
 
          if (!args[1])
3648
 
            OutputMsg(0, "encodings directory is %s", screenencodings ? screenencodings : "<unset>");
3649
 
          else
3650
 
            {
3651
 
              free(screenencodings);
3652
 
              screenencodings = SaveStr(args[1]);
3653
 
            }
3654
 
          break;
3655
 
        }
3656
 
      if (*args && !strcmp(args[0], "-l"))
3657
 
        {
3658
 
          if (!args[1])
3659
 
            OutputMsg(0, "encoding: -l: argument required");
3660
 
          else if (LoadFontTranslation(-1, args[1]))
3661
 
            OutputMsg(0, "encoding: could not load utf8 encoding file");
3662
 
          else if (msgok)
3663
 
            OutputMsg(0, "encoding: utf8 encoding file loaded");
3664
 
          break;
3665
 
        }
3666
 
#else
3667
 
      if (*args && (!strcmp(args[0], "-l") || !strcmp(args[0], "-d")))
3668
 
        {
3669
 
          if (msgok)
3670
 
            OutputMsg(0, "encoding: screen is not compiled for UTF-8.");
3671
 
          break;
3672
 
        }
3673
 
#endif
3674
 
      for (i = 0; i < 2; i++)
3675
 
        {
3676
 
          if (args[i] == 0)
3677
 
            break;
3678
 
          if (!strcmp(args[i], "."))
3679
 
            continue;
3680
 
          n = FindEncoding(args[i]);
3681
 
          if (n == -1)
3682
 
            {
3683
 
              OutputMsg(0, "encoding: unknown encoding '%s'", args[i]);
3684
 
              break;
3685
 
            }
3686
 
          if (i == 0 && fore)
3687
 
            {
3688
 
              WinSwitchEncoding(fore, n);
3689
 
              ResetCharsets(fore);
3690
 
            }
3691
 
          else if (i && display)
3692
 
            D_encoding  = n;
3693
 
        }
3694
 
      break;
3695
 
    case RC_DEFKANJI:
3696
 
    case RC_DEFENCODING:
3697
 
      n = FindEncoding(*args);
3698
 
      if (n == -1)
3699
 
        {
3700
 
          OutputMsg(0, "defencoding: unknown encoding '%s'", *args);
3701
 
          break;
3702
 
        }
3703
 
      nwin_default.encoding = n;
3704
 
      break;
3705
 
#endif
3706
 
 
3707
 
#ifdef UTF8
3708
 
    case RC_DEFUTF8:
3709
 
      n = nwin_default.encoding == UTF8;
3710
 
      if (ParseSwitch(act, &n) == 0)
3711
 
        {
3712
 
          nwin_default.encoding = n ? UTF8 : 0;
3713
 
          if (msgok)
3714
 
            OutputMsg(0, "Will %suse UTF-8 encoding for new windows", n ? "" : "not ");
3715
 
        }
3716
 
      break;
3717
 
    case RC_UTF8:
3718
 
      for (i = 0; i < 2; i++)
3719
 
        {
3720
 
          if (i && args[i] == 0)
3721
 
            break;
3722
 
          if (args[i] == 0)
3723
 
            n = fore->w_encoding != UTF8;
3724
 
          else if (strcmp(args[i], "off") == 0)
3725
 
            n = 0;
3726
 
          else if (strcmp(args[i], "on") == 0)
3727
 
            n = 1;
3728
 
          else
3729
 
            {
3730
 
              OutputMsg(0, "utf8: illegal argument (%s)", args[i]);
3731
 
              break;
3732
 
            }
3733
 
          if (i == 0)
3734
 
            {
3735
 
              WinSwitchEncoding(fore, n ? UTF8 : 0);
3736
 
              if (msgok)
3737
 
                OutputMsg(0, "Will %suse UTF-8 encoding", n ? "" : "not ");
3738
 
            }
3739
 
          else if (display)
3740
 
            D_encoding = n ? UTF8 : 0;
3741
 
          if (args[i] == 0)
3742
 
            break;
3743
 
        }
3744
 
      break;
3745
 
#endif
3746
 
 
3747
 
    case RC_PRINTCMD:
3748
 
      if (*args)
3749
 
        {
3750
 
          if (printcmd)
3751
 
            free(printcmd);
3752
 
          printcmd = 0;
3753
 
          if (**args)
3754
 
            printcmd = SaveStr(*args);
3755
 
        }
3756
 
      if (*args == 0 || msgok)
3757
 
        {
3758
 
          if (printcmd)
3759
 
            OutputMsg(0, "using '%s' as print command", printcmd);
3760
 
          else
3761
 
            OutputMsg(0, "using termcap entries for printing");
3762
 
            break;
3763
 
        }
3764
 
      break;
3765
 
 
3766
 
    case RC_DIGRAPH:
3767
 
      if (argl && argl[0] > 0 && argl[1] > 0)
3768
 
        {
3769
 
          if (argl[0] != 2)
3770
 
            {
3771
 
              OutputMsg(0, "Two characters expected to define a digraph");
3772
 
              break;
3773
 
            }
3774
 
          i = digraph_find(args[0]);
3775
 
          digraphs[i].d[0] = args[0][0];
3776
 
          digraphs[i].d[1] = args[0][1];
3777
 
          if (!parse_input_int(args[1], argl[1], &digraphs[i].value))
3778
 
            {
3779
 
              if (!(digraphs[i].value = atoi(args[1])))
3780
 
                {
3781
 
                  if (!args[1][1])
3782
 
                    digraphs[i].value = (int)args[1][0];
3783
 
#ifdef UTF8
3784
 
                  else
3785
 
                    {
3786
 
                      int t;
3787
 
                      unsigned char *s = (unsigned char *)args[1];
3788
 
                      digraphs[i].value = 0;
3789
 
                      while (*s)
3790
 
                        {
3791
 
                          t = FromUtf8(*s++, &digraphs[i].value);
3792
 
                          if (t == -1)
3793
 
                            continue;
3794
 
                          if (t == -2)
3795
 
                            digraphs[i].value = 0;
3796
 
                          else
3797
 
                            digraphs[i].value = t;
3798
 
                          break;
3799
 
                        }
3800
 
                    }
3801
 
#endif
3802
 
                }
3803
 
            }
3804
 
          break;
3805
 
        }
3806
 
      Input("Enter digraph: ", 10, INP_EVERY, digraph_fn, NULL, 0);
3807
 
      if (*args && **args)
3808
 
        {
3809
 
          s = *args;
3810
 
          n = strlen(s);
3811
 
          LayProcess(&s, &n);
3812
 
        }
3813
 
      break;
3814
 
 
3815
 
    case RC_DEFHSTATUS:
3816
 
      if (*args == 0)
3817
 
        {
3818
 
          char buf[256];
3819
 
          *buf = 0;
3820
 
          if (nwin_default.hstatus)
3821
 
            AddXChars(buf, sizeof(buf), nwin_default.hstatus);
3822
 
          OutputMsg(0, "default hstatus is '%s'", buf);
3823
 
          break;
3824
 
        }
3825
 
      (void)ParseSaveStr(act, &nwin_default.hstatus);
3826
 
      if (*nwin_default.hstatus == 0)
3827
 
        {
3828
 
          free(nwin_default.hstatus);
3829
 
          nwin_default.hstatus = 0;
3830
 
        }
3831
 
      break;
3832
 
    case RC_HSTATUS:
3833
 
      (void)ParseSaveStr(act, &fore->w_hstatus);
3834
 
      if (*fore->w_hstatus == 0)
3835
 
        {
3836
 
          free(fore->w_hstatus);
3837
 
          fore->w_hstatus = 0;
3838
 
        }
3839
 
      WindowChanged(fore, 'h');
3840
 
      break;
3841
 
 
3842
 
#ifdef FONT
3843
 
    case RC_DEFCHARSET:
3844
 
    case RC_CHARSET:
3845
 
      if (*args == 0)
3846
 
        {
3847
 
          char buf[256];
3848
 
          *buf = 0;
3849
 
          if (nwin_default.charset)
3850
 
            AddXChars(buf, sizeof(buf), nwin_default.charset);
3851
 
          OutputMsg(0, "default charset is '%s'", buf);
3852
 
          break;
3853
 
        }
3854
 
      n = strlen(*args);
3855
 
      if (n == 0 || n > 6)
3856
 
        {
3857
 
          OutputMsg(0, "%s: %s: string has illegal size.", rc_name, comms[nr].name);
3858
 
          break;
3859
 
        }
3860
 
      if (n > 4 && (
3861
 
        ((args[0][4] < '0' || args[0][4] > '3') && args[0][4] != '.') ||
3862
 
        ((args[0][5] < '0' || args[0][5] > '3') && args[0][5] && args[0][5] != '.')))
3863
 
        {
3864
 
          OutputMsg(0, "%s: %s: illegal mapping number.", rc_name, comms[nr].name);
3865
 
          break;
3866
 
        }
3867
 
      if (nr == RC_CHARSET)
3868
 
        {
3869
 
          SetCharsets(fore, *args);
3870
 
          break;
3871
 
        }
3872
 
      if (nwin_default.charset)
3873
 
        free(nwin_default.charset);
3874
 
      nwin_default.charset = SaveStr(*args);
3875
 
      break;
3876
 
#endif
3877
 
#ifdef COLOR
3878
 
    case RC_ATTRCOLOR:
3879
 
      s = args[0];
3880
 
      if (*s >= '0' && *s <= '9')
3881
 
        i = *s - '0';
3882
 
      else
3883
 
        for (i = 0; i < 8; i++)
3884
 
          if (*s == "dubrsBiI"[i])
3885
 
            break;
3886
 
      s++;
3887
 
      nr = 0;
3888
 
      if (*s && s[1] && !s[2])
3889
 
        {
3890
 
          if (*s == 'd' && s[1] == 'd')
3891
 
            nr = 3;
3892
 
          else if (*s == '.' && s[1] == 'd')
3893
 
            nr = 2;
3894
 
          else if (*s == 'd' && s[1] == '.')
3895
 
            nr = 1;
3896
 
          else if (*s != '.' || s[1] != '.')
3897
 
            s--;
3898
 
          s += 2;
3899
 
        }
3900
 
      if (*s || i < 0 || i >= 8)
3901
 
        {
3902
 
          OutputMsg(0, "%s: attrcolor: unknown attribute '%s'.", rc_name, args[0]);
3903
 
          break;
3904
 
        }
3905
 
      n = 0;
3906
 
      if (args[1])
3907
 
        n = ParseAttrColor(args[1], args[2], 1);
3908
 
      if (n == -1)
3909
 
        break;
3910
 
      attr2color[i][nr] = n;
3911
 
      n = 0;
3912
 
      for (i = 0; i < 8; i++)
3913
 
        if (attr2color[i][0] || attr2color[i][1] || attr2color[i][2] || attr2color[i][3])
3914
 
          n |= 1 << i;
3915
 
      nattr2color = n;
3916
 
      break;
3917
 
#endif
3918
 
    case RC_RENDITION:
3919
 
      i = -1;
3920
 
      if (strcmp(args[0], "bell") == 0)
3921
 
        {
3922
 
          i = REND_BELL;
3923
 
        }
3924
 
      else if (strcmp(args[0], "monitor") == 0)
3925
 
        {
3926
 
          i = REND_MONITOR;
3927
 
        }
3928
 
      else if (strcmp(args[0], "silence") == 0)
3929
 
        {
3930
 
          i = REND_SILENCE;
3931
 
        }
3932
 
      else if (strcmp(args[0], "so") != 0)
3933
 
        {
3934
 
          OutputMsg(0, "Invalid option '%s' for rendition", args[0]);
3935
 
          break;
3936
 
        }
3937
 
 
3938
 
      ++args;
3939
 
      ++argl;
3940
 
 
3941
 
      if (i != -1)
3942
 
        {
3943
 
          renditions[i] = ParseAttrColor(args[0], args[1], 1);
3944
 
          WindowChanged((struct win *)0, 'w');
3945
 
          WindowChanged((struct win *)0, 'W');
3946
 
          WindowChanged((struct win *)0, 0);
3947
 
          break;
3948
 
        }
3949
 
 
3950
 
      /* We are here, means we want to set the sorendition. */
3951
 
      /* FALLTHROUGH*/
3952
 
    case RC_SORENDITION:
3953
 
      i = 0;
3954
 
      if (*args)
3955
 
        {
3956
 
          i = ParseAttrColor(*args, args[1], 1);
3957
 
          if (i == -1)
3958
 
            break;
3959
 
          ApplyAttrColor(i, &mchar_so);
3960
 
          WindowChanged((struct win *)0, 0);
3961
 
          debug2("--> %x %x\n", mchar_so.attr, mchar_so.color);
3962
 
        }
3963
 
      if (msgok)
3964
 
#ifdef COLOR
3965
 
        OutputMsg(0, "Standout attributes 0x%02x  color 0x%02x", (unsigned char)mchar_so.attr, 0x99 ^ (unsigned char)mchar_so.color);
3966
 
#else
3967
 
        OutputMsg(0, "Standout attributes 0x%02x ", (unsigned char)mchar_so.attr);
3968
 
#endif
3969
 
      break;
3970
 
 
3971
 
      case RC_SOURCE:
3972
 
        do_source(*args);
3973
 
        break;
3974
 
 
3975
 
#ifdef MULTIUSER
3976
 
    case RC_SU:
3977
 
      s = NULL;
3978
 
      if (!*args)
3979
 
        {
3980
 
          OutputMsg(0, "%s:%s screen login", HostName, SockPath);
3981
 
          InputSu(D_fore, &D_user, NULL);
3982
 
        }
3983
 
      else if (!args[1])
3984
 
        InputSu(D_fore, &D_user, args[0]);
3985
 
      else if (!args[2])
3986
 
        s = DoSu(&D_user, args[0], args[1], "\377");
3987
 
      else
3988
 
        s = DoSu(&D_user, args[0], args[1], args[2]);
3989
 
      if (s)
3990
 
        OutputMsg(0, "%s", s);
3991
 
      break;
3992
 
#endif /* MULTIUSER */
3993
 
    case RC_SPLIT:
3994
 
      s = args[0];
3995
 
      if (s && !strcmp(s, "-v"))
3996
 
        AddCanvas(SLICE_HORI);
3997
 
      else
3998
 
        AddCanvas(SLICE_VERT);
3999
 
      Activate(-1);
4000
 
      break;
4001
 
    case RC_REMOVE:
4002
 
      RemCanvas();
4003
 
      Activate(-1);
4004
 
      break;
4005
 
    case RC_ONLY:
4006
 
      OneCanvas();
4007
 
      Activate(-1);
4008
 
      break;
4009
 
    case RC_FIT:
4010
 
      D_forecv->c_xoff = D_forecv->c_xs;
4011
 
      D_forecv->c_yoff = D_forecv->c_ys;
4012
 
      RethinkViewportOffsets(D_forecv);
4013
 
      ResizeLayer(D_forecv->c_layer, D_forecv->c_xe - D_forecv->c_xs + 1, D_forecv->c_ye - D_forecv->c_ys + 1, 0);
4014
 
      flayer = D_forecv->c_layer;
4015
 
      LaySetCursor();
4016
 
      break;
4017
 
    case RC_FOCUS:
4018
 
      {
4019
 
        struct canvas *cv = 0;
4020
 
        if (!*args || !strcmp(*args, "next"))
4021
 
          cv = D_forecv->c_next ? D_forecv->c_next : D_cvlist;
4022
 
        else if (!strcmp(*args, "prev"))
4023
 
          {
4024
 
            for (cv = D_cvlist; cv->c_next && cv->c_next != D_forecv; cv = cv->c_next)
4025
 
              ;
4026
 
          }
4027
 
        else if (!strcmp(*args, "top"))
4028
 
          cv = D_cvlist;
4029
 
        else if (!strcmp(*args, "bottom"))
4030
 
          {
4031
 
            for (cv = D_cvlist; cv->c_next; cv = cv->c_next)
4032
 
              ;
4033
 
          }
4034
 
        else if (!strcmp(*args, "up"))
4035
 
          cv = FindCanvas(D_forecv->c_xs, D_forecv->c_ys - 1);
4036
 
        else if (!strcmp(*args, "down"))
4037
 
          cv = FindCanvas(D_forecv->c_xs, D_forecv->c_ye + 2);
4038
 
        else if (!strcmp(*args, "left"))
4039
 
          cv = FindCanvas(D_forecv->c_xs - 1, D_forecv->c_ys);
4040
 
        else if (!strcmp(*args, "right"))
4041
 
          cv = FindCanvas(D_forecv->c_xe + 1, D_forecv->c_ys);
4042
 
        else
4043
 
          {
4044
 
            OutputMsg(0, "%s: usage: focus [next|prev|up|down|left|right|top|bottom]", rc_name);
4045
 
            break;
4046
 
          }
4047
 
        SetForeCanvas(display, cv);
4048
 
      }
4049
 
      break;
4050
 
    case RC_RESIZE:
4051
 
      i = 0;
4052
 
      if (D_forecv->c_slorient == SLICE_UNKN)
4053
 
        {
4054
 
          OutputMsg(0, "resize: need more than one region");
4055
 
          break;
4056
 
        }
4057
 
      for (; *args; args++)
4058
 
        {
4059
 
          if (!strcmp(*args, "-h"))
4060
 
            i |= RESIZE_FLAG_H;
4061
 
          else if (!strcmp(*args, "-v"))
4062
 
            i |= RESIZE_FLAG_V;
4063
 
          else if (!strcmp(*args, "-b"))
4064
 
            i |= RESIZE_FLAG_H | RESIZE_FLAG_V;
4065
 
          else if (!strcmp(*args, "-p"))
4066
 
            i |= D_forecv->c_slorient == SLICE_VERT ? RESIZE_FLAG_H : RESIZE_FLAG_V;
4067
 
          else if (!strcmp(*args, "-l"))
4068
 
            i |= RESIZE_FLAG_L;
4069
 
          else
4070
 
            break;
4071
 
        }
4072
 
      if (*args && args[1])
4073
 
        {
4074
 
          OutputMsg(0, "%s: usage: resize [-h] [-v] [-l] [num]\n", rc_name);
4075
 
          break;
4076
 
        }
4077
 
      if (*args)
4078
 
        ResizeRegions(*args, i);
4079
 
      else
4080
 
        Input(resizeprompts[i], 20, INP_EVERY, ResizeFin, (char*)0, i);
4081
 
      break;
4082
 
    case RC_SETSID:
4083
 
      (void)ParseSwitch(act, &separate_sids);
4084
 
      break;
4085
 
    case RC_EVAL:
4086
 
      args = SaveArgs(args);
4087
 
      for (i = 0; args[i]; i++)
4088
 
        {
4089
 
          if (args[i][0])
4090
 
            Colonfin(args[i], strlen(args[i]), (char *)0);
4091
 
          free(args[i]);
4092
 
        }
4093
 
      free(args);
4094
 
      break;
4095
 
    case RC_ALTSCREEN:
4096
 
      (void)ParseSwitch(act, &use_altscreen);
4097
 
      if (msgok)
4098
 
        OutputMsg(0, "Will %sdo alternate screen switching", use_altscreen ? "" : "not ");
4099
 
      break;
4100
 
    case RC_MAXWIN:
4101
 
      if (!args[0])
4102
 
        {
4103
 
          OutputMsg(0, "maximum windows allowed: %d", maxwin);
4104
 
          break;
4105
 
        }
4106
 
      if (ParseNum(act, &n))
4107
 
        break;
4108
 
      if (n < 1)
4109
 
        OutputMsg(0, "illegal maxwin number specified");
4110
 
      else if (n > 2048)
4111
 
        OutputMsg(0, "maximum 2048 windows allowed");
4112
 
      else if (n > maxwin && windows)
4113
 
        OutputMsg(0, "may increase maxwin only when there's no window");
4114
 
      else
4115
 
        {
4116
 
          if (!windows)
4117
 
            wtab = realloc(wtab, n * sizeof(struct win *));
4118
 
          maxwin = n;
4119
 
        }
4120
 
      break;
4121
 
    case RC_BACKTICK:
4122
 
      if (ParseBase(act, *args, &n, 10, "decimal"))
4123
 
        break;
4124
 
      if (!args[1])
4125
 
        setbacktick(n, 0, 0, (char **)0);
4126
 
      else
4127
 
        {
4128
 
          int lifespan, tick;
4129
 
          if (argc < 4)
4130
 
            {
4131
 
              OutputMsg(0, "%s: usage: backtick num [lifespan tick cmd args...]", rc_name);
4132
 
              break;
4133
 
            }
4134
 
          if (ParseBase(act, args[1], &lifespan, 10, "decimal"))
4135
 
            break;
4136
 
          if (ParseBase(act, args[2], &tick, 10, "decimal"))
4137
 
            break;
4138
 
          setbacktick(n, lifespan, tick, SaveArgs(args + 3));
4139
 
        }
4140
 
      WindowChanged(0, '`');
4141
 
      break;
4142
 
    case RC_BLANKER:
4143
 
#ifdef BLANKER_PRG
4144
 
      if (blankerprg)
4145
 
        {
4146
 
          RunBlanker(blankerprg);
4147
 
          break;
4148
 
        }
4149
 
#endif
4150
 
      ClearAll();
4151
 
      CursorVisibility(-1);
4152
 
      D_blocked = 4;
4153
 
      break;
4154
 
#ifdef BLANKER_PRG
4155
 
    case RC_BLANKERPRG:
4156
 
      if (!args[0])
4157
 
        {
4158
 
          if (blankerprg)
4159
 
            {
4160
 
              char path[MAXPATHLEN];
4161
 
              char *p = path, **pp;
4162
 
              for (pp = blankerprg; *pp; pp++)
4163
 
                p += snprintf(p, sizeof(path) - (p - path) - 1, "%s ", *pp);
4164
 
              *(p - 1) = '\0';
4165
 
              OutputMsg(0, "blankerprg: %s", path);
4166
 
            }
4167
 
          else
4168
 
            OutputMsg(0, "No blankerprg set.");
4169
 
          break;
4170
 
        }
4171
 
      if (blankerprg)
4172
 
        {
4173
 
          char **pp;
4174
 
          for (pp = blankerprg; *pp; pp++)
4175
 
            free(*pp);
4176
 
          free(blankerprg);
4177
 
          blankerprg = 0;
4178
 
        }
4179
 
      if (args[0][0])
4180
 
        blankerprg = SaveArgs(args);
4181
 
      break;
4182
 
#endif
4183
 
    case RC_IDLE:
4184
 
      if (*args)
4185
 
        {
4186
 
          struct display *olddisplay = display;
4187
 
          if (!strcmp(*args, "off"))
4188
 
            idletimo = 0;
4189
 
          else if (args[0][0])
4190
 
            idletimo = atoi(*args) * 1000;
4191
 
          if (argc > 1)
4192
 
            {
4193
 
              if ((i = FindCommnr(args[1])) == RC_ILLEGAL)
4194
 
                {
4195
 
                  OutputMsg(0, "%s: idle: unknown command '%s'", rc_name, args[1]);
4196
 
                  break;
4197
 
                }
4198
 
              if (CheckArgNum(i, args + 2) < 0)
4199
 
                break;
4200
 
              ClearAction(&idleaction);
4201
 
              SaveAction(&idleaction, i, args + 2, argl + 2);
4202
 
            }
4203
 
          for (display = displays; display; display = display->d_next)
4204
 
            ResetIdle();
4205
 
          display = olddisplay;
4206
 
        }
4207
 
      if (msgok)
4208
 
        {
4209
 
          if (idletimo)
4210
 
            OutputMsg(0, "idle timeout %ds, %s", idletimo / 1000, comms[idleaction.nr].name);
4211
 
          else
4212
 
            OutputMsg(0, "idle off");
4213
 
        }
4214
 
      break;
4215
 
    case RC_FOCUSMINSIZE:
4216
 
      for (i = 0; i < 2 && args[i]; i++)
4217
 
        {
4218
 
          if (!strcmp(args[i], "max") || !strcmp(args[i], "_"))
4219
 
            n = -1;
4220
 
          else
4221
 
            n = atoi(args[i]);
4222
 
          if (i == 0)
4223
 
            focusminwidth = n;
4224
 
          else
4225
 
            focusminheight = n;
4226
 
        }
4227
 
      if (msgok)
4228
 
        {
4229
 
          char b[2][20];
4230
 
          for (i = 0; i < 2; i++)
4231
 
            {
4232
 
              n = i == 0 ? focusminwidth : focusminheight;
4233
 
              if (n == -1)
4234
 
                strcpy(b[i], "max");
4235
 
              else
4236
 
                sprintf(b[i], "%d", n);
4237
 
            }
4238
 
          OutputMsg(0, "focus min size is %s %s\n", b[0], b[1]);
4239
 
        }
4240
 
      break;
4241
 
    case RC_GROUP:
4242
 
      if (*args)
4243
 
        {
4244
 
          fore->w_group = 0;
4245
 
          if (args[0][0])
4246
 
            {
4247
 
              fore->w_group = WindowByName(*args);
4248
 
              if (fore->w_group == fore || (fore->w_group && fore->w_group->w_type != W_TYPE_GROUP))
4249
 
                fore->w_group = 0;
4250
 
            }
4251
 
          WindowChanged((struct win *)0, 'w');
4252
 
          WindowChanged((struct win *)0, 'W');
4253
 
          WindowChanged((struct win *)0, 0);
4254
 
        }
4255
 
      if (msgok)
4256
 
        {
4257
 
          if (fore->w_group)
4258
 
            OutputMsg(0, "window group is %d (%s)\n", fore->w_group->w_number, fore->w_group->w_title);
4259
 
          else
4260
 
            OutputMsg(0, "window belongs to no group");
4261
 
        }
4262
 
      break;
4263
 
    case RC_LAYOUT:
4264
 
      // A number of the subcommands for "layout" are ignored, or not processed correctly when there
4265
 
      // is no attached display.
4266
 
 
4267
 
      if (!strcmp(args[0], "title"))
4268
 
        {
4269
 
          if (!display)
4270
 
            {
4271
 
              if (!args[1])  // There is no display, and there is no new title. Ignore.
4272
 
                break;
4273
 
              if (!layout_attach || layout_attach == &layout_last_marker)
4274
 
                layout_attach = CreateLayout(args[1], 0);
4275
 
              else
4276
 
                RenameLayout(layout_attach, args[1]);
4277
 
              break;
4278
 
            }
4279
 
 
4280
 
          if (!D_layout)
4281
 
            {
4282
 
              OutputMsg(0, "not on a layout");
4283
 
              break;
4284
 
            }
4285
 
          if (!args[1])
4286
 
            {
4287
 
              OutputMsg(0, "current layout is %d (%s)", D_layout->lay_number, D_layout->lay_title);
4288
 
              break;
4289
 
            }
4290
 
          RenameLayout(D_layout, args[1]);
4291
 
        }
4292
 
      else if (!strcmp(args[0], "number"))
4293
 
        {
4294
 
          if (!display)
4295
 
            {
4296
 
              if (args[1] && layout_attach && layout_attach != &layout_last_marker)
4297
 
                RenumberLayout(layout_attach, atoi(args[1]));
4298
 
              break;
4299
 
            }
4300
 
 
4301
 
          if (!D_layout)
4302
 
            {
4303
 
              OutputMsg(0, "not on a layout");
4304
 
              break;
4305
 
            }
4306
 
          if (!args[1])
4307
 
            {
4308
 
              OutputMsg(0, "This is layout %d (%s).\n", D_layout->lay_number, D_layout->lay_title);
4309
 
              break;
4310
 
            }
4311
 
           RenumberLayout(D_layout, atoi(args[1]));
4312
 
           break;
4313
 
        }
4314
 
      else if (!strcmp(args[0], "autosave"))
4315
 
        {
4316
 
          if (!display)
4317
 
            {
4318
 
              if (args[1] && layout_attach && layout_attach != &layout_last_marker)
4319
 
                {
4320
 
                  if (!strcmp(args[1], "on"))
4321
 
                    layout_attach->lay_autosave = 1;
4322
 
                  else if (!strcmp(args[1], "off"))
4323
 
                    layout_attach->lay_autosave = 0;
4324
 
                }
4325
 
              break;
4326
 
            }
4327
 
 
4328
 
          if (!D_layout)
4329
 
            {
4330
 
              OutputMsg(0, "not on a layout");
4331
 
              break;
4332
 
            }
4333
 
          if (args[1])
4334
 
            {
4335
 
              if (!strcmp(args[1], "on"))
4336
 
                D_layout->lay_autosave = 1;
4337
 
              else if (!strcmp(args[1], "off"))
4338
 
                D_layout->lay_autosave = 0;
4339
 
              else
4340
 
                {
4341
 
                  OutputMsg(0, "invalid argument. Give 'on' or 'off");
4342
 
                  break;
4343
 
                }
4344
 
            }
4345
 
          if (msgok)
4346
 
            OutputMsg(0, "autosave is %s", D_layout->lay_autosave ? "on" : "off");
4347
 
        }
4348
 
      else if (!strcmp(args[0], "new"))
4349
 
        {
4350
 
          char *t = args[1];
4351
 
          n = 0;
4352
 
          if (t)
4353
 
            {
4354
 
              while (*t >= '0' && *t <= '9')
4355
 
                t++;
4356
 
              if (t != args[1] && (!*t || *t == ':'))
4357
 
                {
4358
 
                  n = atoi(args[1]);
4359
 
                  if (*t)
4360
 
                    t++;
4361
 
                }
4362
 
              else
4363
 
                t = args[1];
4364
 
            }
4365
 
          if (!t || !*t)
4366
 
            t = "layout";
4367
 
          NewLayout(t, n);
4368
 
          Activate(-1);
4369
 
        }
4370
 
      else if (!strcmp(args[0], "save"))
4371
 
        {
4372
 
          if (!args[1])
4373
 
            {
4374
 
              OutputMsg(0, "usage: layout save <name>");
4375
 
              break;
4376
 
            }
4377
 
          if (display)
4378
 
            SaveLayout(args[1], &D_canvas);
4379
 
        }
4380
 
      else if (!strcmp(args[0], "select"))
4381
 
        {
4382
 
          if (!display)
4383
 
            {
4384
 
              if (args[1])
4385
 
                layout_attach = FindLayout(args[1]);
4386
 
              break;
4387
 
            }
4388
 
          if (!args[1])
4389
 
            {
4390
 
              Input("Switch to layout: ", 20, INP_COOKED, SelectLayoutFin, NULL, 0);
4391
 
              break;
4392
 
            }
4393
 
          SelectLayoutFin(args[1], strlen(args[1]), (char *)0);
4394
 
        }
4395
 
      else if (!strcmp(args[0], "next"))
4396
 
        {
4397
 
          if (!display)
4398
 
            {
4399
 
              if (layout_attach && layout_attach != &layout_last_marker)
4400
 
                layout_attach = layout_attach->lay_next ? layout_attach->lay_next : layouts;;
4401
 
              break;
4402
 
            }
4403
 
          struct layout *lay = D_layout;
4404
 
          if (lay)
4405
 
            lay = lay->lay_next ? lay->lay_next : layouts;
4406
 
          else
4407
 
            lay = layouts;
4408
 
          if (!lay)
4409
 
            {
4410
 
              OutputMsg(0, "no layout defined");
4411
 
              break;
4412
 
            }
4413
 
          if (lay == D_layout)
4414
 
            break;
4415
 
          LoadLayout(lay, &D_canvas);
4416
 
          Activate(-1);
4417
 
        }
4418
 
      else if (!strcmp(args[0], "prev"))
4419
 
        {
4420
 
          struct layout *lay = display ? D_layout : layout_attach;
4421
 
          struct layout *target = lay;
4422
 
          if (lay)
4423
 
            {
4424
 
              for (lay = layouts; lay->lay_next && lay->lay_next != target; lay = lay->lay_next)
4425
 
                ;
4426
 
            }
4427
 
          else
4428
 
            lay = layouts;
4429
 
 
4430
 
          if (!display)
4431
 
            {
4432
 
              layout_attach = lay;
4433
 
              break;
4434
 
            }
4435
 
 
4436
 
          if (!lay)
4437
 
            {
4438
 
              OutputMsg(0, "no layout defined");
4439
 
              break;
4440
 
            }
4441
 
          if (lay == D_layout)
4442
 
            break;
4443
 
          LoadLayout(lay, &D_canvas);
4444
 
          Activate(-1);
4445
 
        }
4446
 
      else if (!strcmp(args[0], "attach"))
4447
 
        {
4448
 
          if (!args[1])
4449
 
            {
4450
 
              if (!layout_attach)
4451
 
                OutputMsg(0, "no attach layout set");
4452
 
              else if (layout_attach == &layout_last_marker)
4453
 
                OutputMsg(0, "will attach to last layout");
4454
 
              else
4455
 
                OutputMsg(0, "will attach to layout %d (%s)", layout_attach->lay_number, layout_attach->lay_title);
4456
 
              break;
4457
 
            }
4458
 
          if (!strcmp(args[1], ":last"))
4459
 
            layout_attach = &layout_last_marker;
4460
 
          else if (!args[1][0])
4461
 
            layout_attach = 0;
4462
 
          else
4463
 
            {
4464
 
              struct layout *lay;
4465
 
              lay = FindLayout(args[1]);
4466
 
              if (!lay)
4467
 
                {
4468
 
                  OutputMsg(0, "unknown layout '%s'", args[1]);
4469
 
                  break;
4470
 
                }
4471
 
              layout_attach = lay;
4472
 
            }
4473
 
        }
4474
 
      else if (!strcmp(args[0], "show"))
4475
 
        {
4476
 
          ShowLayouts(-1);
4477
 
        }
4478
 
      else if (!strcmp(args[0], "remove"))
4479
 
        {
4480
 
          struct layout *lay = display ? D_layout : layouts;
4481
 
          if (args[1])
4482
 
            {
4483
 
              lay = layouts ? FindLayout(args[1]) : (struct layout *)0;
4484
 
              if (!lay)
4485
 
                {
4486
 
                  OutputMsg(0, "unknown layout '%s'", args[1]);
4487
 
                  break;
4488
 
                }
4489
 
            }
4490
 
          if (lay)
4491
 
            RemoveLayout(lay);
4492
 
        }
4493
 
      else if (!strcmp(args[0], "dump"))
4494
 
        {
4495
 
          if (!display)
4496
 
            OutputMsg(0, "Must have a display for 'layout dump'.");
4497
 
          else if (!LayoutDumpCanvas(&D_canvas, args[1] ? args[1] : "layout-dump"))
4498
 
            OutputMsg(errno, "Error dumping layout.");
4499
 
          else
4500
 
            OutputMsg(0, "Layout dumped to \"%s\"", args[1] ? args[1] : "layout-dump");
4501
 
        }
4502
 
      else
4503
 
        OutputMsg(0, "unknown layout subcommand");
4504
 
      break;
4505
 
#ifdef DW_CHARS
4506
 
    case RC_CJKWIDTH:
4507
 
      if(ParseSwitch(act, &cjkwidth) == 0)
4508
 
      {
4509
 
        if(msgok)
4510
 
          OutputMsg(0, "Treat ambiguous width characters as %s width", cjkwidth ? "full" : "half");
4511
 
      }
4512
 
      break;
4513
 
#endif
4514
 
    default:
4515
 
#ifdef HAVE_BRAILLE
4516
 
      /* key == -2: input from braille keybord, msgok always 0 */
4517
 
      DoBrailleAction(act, key == -2 ? 0 : msgok);
4518
 
#endif
4519
 
      break;
4520
 
    }
4521
 
  if (display != odisplay)
4522
 
    {
4523
 
      for (display = displays; display; display = display->d_next)
4524
 
        if (display == odisplay)
4525
 
          break;
4526
 
    }
4527
 
}
4528
 
#undef OutputMsg
4529
 
 
4530
 
void
4531
 
DoCommand(argv, argl) 
4532
 
char **argv;
4533
 
int *argl;
4534
 
{
4535
 
  struct action act;
4536
 
  const char *cmd = *argv;
4537
 
 
4538
 
  act.quiet = 0;
4539
 
  /* For now, we actually treat both 'supress error' and 'suppress normal message' as the
4540
 
   * same, and ignore all messages on either flag. If we wanted to do otherwise, we would
4541
 
   * need to change the definition of 'OutputMsg' slightly. */
4542
 
  if (*cmd == '@')      /* Suppress error */
4543
 
    {
4544
 
      act.quiet |= 0x01;
4545
 
      cmd++;
4546
 
    }
4547
 
  if (*cmd == '-')      /* Suppress normal message */
4548
 
    {
4549
 
      act.quiet |= 0x02;
4550
 
      cmd++;
4551
 
    }
4552
 
 
4553
 
  if ((act.nr = FindCommnr(cmd)) == RC_ILLEGAL)
4554
 
    {
4555
 
      Msg(0, "%s: unknown command '%s'", rc_name, cmd);
4556
 
      return;
4557
 
    }
4558
 
  act.args = argv + 1;
4559
 
  act.argl = argl + 1;
4560
 
  DoAction(&act, -1);
4561
 
}
4562
 
 
4563
 
static void
4564
 
SaveAction(act, nr, args, argl)
4565
 
struct action *act;
4566
 
int nr;
4567
 
char **args;
4568
 
int *argl;
4569
 
{
4570
 
  register int argc = 0;
4571
 
  char **pp;
4572
 
  int *lp;
4573
 
 
4574
 
  if (args)
4575
 
    while (args[argc])
4576
 
      argc++;
4577
 
  if (argc == 0)
4578
 
    {
4579
 
      act->nr = nr;
4580
 
      act->args = noargs;
4581
 
      act->argl = 0;
4582
 
      return;
4583
 
    }
4584
 
  if ((pp = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0)
4585
 
    Panic(0, "%s", strnomem);
4586
 
  if ((lp = (int *)malloc((unsigned)(argc) * sizeof(int *))) == 0)
4587
 
    Panic(0, "%s", strnomem);
4588
 
  act->nr = nr;
4589
 
  act->args = pp;
4590
 
  act->argl = lp;
4591
 
  while (argc--)
4592
 
    {
4593
 
      *lp = argl ? *argl++ : (int)strlen(*args);
4594
 
      *pp++ = SaveStrn(*args++, *lp++);
4595
 
    }
4596
 
  *pp = 0;
4597
 
}
4598
 
 
4599
 
static char **
4600
 
SaveArgs(args)
4601
 
char **args;
4602
 
{
4603
 
  register char **ap, **pp;
4604
 
  register int argc = 0;
4605
 
 
4606
 
  while (args[argc])
4607
 
    argc++;
4608
 
  if ((pp = ap = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0)
4609
 
    Panic(0, "%s", strnomem);
4610
 
  while (argc--)
4611
 
    *pp++ = SaveStr(*args++);
4612
 
  *pp = 0;
4613
 
  return ap;
4614
 
}
4615
 
 
4616
 
 
4617
 
/*
4618
 
 * buf is split into argument vector args.
4619
 
 * leading whitespace is removed.
4620
 
 * @!| abbreviations are expanded.
4621
 
 * the end of buffer is recognized by '\0' or an un-escaped '#'.
4622
 
 * " and ' are interpreted.
4623
 
 *
4624
 
 * argc is returned.
4625
 
 */
4626
 
int 
4627
 
Parse(buf, bufl, args, argl)
4628
 
char *buf, **args;
4629
 
int bufl, *argl;
4630
 
{
4631
 
  register char *p = buf, **ap = args, *pp;
4632
 
  register int delim, argc;
4633
 
  int *lp = argl;
4634
 
 
4635
 
  debug2("Parse %d %s\n", bufl, buf);
4636
 
  argc = 0;
4637
 
  pp = buf;
4638
 
  delim = 0;
4639
 
  for (;;)
4640
 
    {
4641
 
      *lp = 0;
4642
 
      while (*p && (*p == ' ' || *p == '\t'))
4643
 
        ++p;
4644
 
#ifdef PSEUDOS
4645
 
      if (argc == 0 && *p == '!')
4646
 
        {
4647
 
          *ap++ = "exec";
4648
 
          *lp++ = 4;
4649
 
          p++;
4650
 
          argc++;
4651
 
          continue;
4652
 
        }
4653
 
#endif
4654
 
      if (*p == '\0' || *p == '#' || *p == '\n')
4655
 
        {
4656
 
          *p = '\0';
4657
 
          for (delim = 0; delim < argc; delim++)
4658
 
            debug1("-- %s\n", args[delim]);
4659
 
          args[argc] = 0;
4660
 
          return argc;
4661
 
        }
4662
 
      if (++argc >= MAXARGS)
4663
 
        {
4664
 
          Msg(0, "%s: too many tokens.", rc_name);
4665
 
          return 0;
4666
 
        }
4667
 
      *ap++ = pp;
4668
 
 
4669
 
      debug1("- new arg %s\n", p);
4670
 
      while (*p)
4671
 
        {
4672
 
          if (*p == delim)
4673
 
            delim = 0;
4674
 
          else if (delim != '\'' && *p == '\\' && (p[1] == 'n' || p[1] == 'r' || p[1] == 't' || p[1] == '\'' || p[1] == '"' || p[1] == '\\' || p[1] == '$' || p[1] == '#' || p[1] == '^' || (p[1] >= '0' && p[1] <= '7')))
4675
 
            {
4676
 
              p++;
4677
 
              if (*p >= '0' && *p <= '7')
4678
 
                {
4679
 
                  *pp = *p - '0';
4680
 
                  if (p[1] >= '0' && p[1] <= '7')
4681
 
                    {
4682
 
                      p++;
4683
 
                      *pp = (*pp << 3) | (*p - '0');
4684
 
                      if (p[1] >= '0' && p[1] <= '7')
4685
 
                        {
4686
 
                          p++;
4687
 
                          *pp = (*pp << 3) | (*p - '0');
4688
 
                        }
4689
 
                    }
4690
 
                  pp++;
4691
 
                }
4692
 
              else
4693
 
                {
4694
 
                  switch (*p)
4695
 
                    {
4696
 
                      case 'n': *pp = '\n'; break;
4697
 
                      case 'r': *pp = '\r'; break;
4698
 
                      case 't': *pp = '\t'; break;
4699
 
                      default: *pp = *p; break;
4700
 
                    }
4701
 
                  pp++;
4702
 
                }
4703
 
            }
4704
 
          else if (delim != '\'' && *p == '$' && (p[1] == '{' || p[1] == ':' || (p[1] >= 'a' && p[1] <= 'z') || (p[1] >= 'A' && p[1] <= 'Z') || (p[1] >= '0' && p[1] <= '9') || p[1] == '_'))
4705
 
 
4706
 
            {
4707
 
              char *ps, *pe, op, *v, xbuf[11], path[MAXPATHLEN];
4708
 
              int vl;
4709
 
 
4710
 
              ps = ++p;
4711
 
              debug1("- var %s\n", ps);
4712
 
              p++;
4713
 
              while (*p)
4714
 
                {
4715
 
                  if (*ps == '{' && *p == '}')
4716
 
                    break;
4717
 
                  if (*ps == ':' && *p == ':')
4718
 
                    break;
4719
 
                  if (*ps != '{' && *ps != ':' && (*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9') && *p != '_')
4720
 
                    break;
4721
 
                  p++;
4722
 
                }
4723
 
              pe = p;
4724
 
              if (*ps == '{' || *ps == ':')
4725
 
                {
4726
 
                  if (!*p)
4727
 
                    {
4728
 
                      Msg(0, "%s: bad variable name.", rc_name);
4729
 
                      return 0;
4730
 
                    }
4731
 
                  p++;
4732
 
                }
4733
 
              op = *pe;
4734
 
              *pe = 0;
4735
 
              debug1("- var is '%s'\n", ps);
4736
 
              if (*ps == ':')
4737
 
                v = gettermcapstring(ps + 1);
4738
 
              else
4739
 
                {
4740
 
                  if (*ps == '{')
4741
 
                    ps++;
4742
 
                  v = xbuf;
4743
 
                  if (!strcmp(ps, "TERM"))
4744
 
                    v = display ? D_termname : "unknown";
4745
 
                  else if (!strcmp(ps, "COLUMNS"))
4746
 
                    sprintf(xbuf, "%d", display ? D_width : -1);
4747
 
                  else if (!strcmp(ps, "LINES"))
4748
 
                    sprintf(xbuf, "%d", display ? D_height : -1);
4749
 
                  else if (!strcmp(ps, "PID"))
4750
 
                    sprintf(xbuf, "%d", getpid());
4751
 
                  else if (!strcmp(ps, "PWD"))
4752
 
                    {
4753
 
                      if (getcwd(path, sizeof(path) - 1) == 0)
4754
 
                        v = "?";
4755
 
                      else
4756
 
                        v = path;
4757
 
                    }
4758
 
                  else if (!strcmp(ps, "STY"))
4759
 
                    {
4760
 
                      if ((v = strchr(SockName, '.')))  /* Skip the PID */
4761
 
                        v++;
4762
 
                      else
4763
 
                        v = SockName;
4764
 
                    }
4765
 
                  else
4766
 
                    v = getenv(ps);
4767
 
                }
4768
 
              *pe = op;
4769
 
              vl = v ? strlen(v) : 0;
4770
 
              if (vl)
4771
 
                {
4772
 
                  debug1("- sub is '%s'\n", v);
4773
 
                  if (p - pp < vl)
4774
 
                    {
4775
 
                      int right = buf + bufl - (p + strlen(p) + 1);
4776
 
                      if (right > 0)
4777
 
                        {
4778
 
                          bcopy(p, p + right, strlen(p) + 1);
4779
 
                          p += right;
4780
 
                        }
4781
 
                    }
4782
 
                  if (p - pp < vl)
4783
 
                    {
4784
 
                      Msg(0, "%s: no space left for variable expansion.", rc_name);
4785
 
                      return 0;
4786
 
                    }
4787
 
                  bcopy(v, pp, vl);
4788
 
                  pp += vl;
4789
 
                }
4790
 
              continue;
4791
 
            }
4792
 
          else if (delim != '\'' && *p == '^' && p[1])
4793
 
            {
4794
 
              p++;
4795
 
              *pp++ = *p == '?' ? '\177' : *p & 0x1f;
4796
 
            }
4797
 
          else if (delim == 0 && (*p == '\'' || *p == '"'))
4798
 
            delim = *p;
4799
 
          else if (delim == 0 && (*p == ' ' || *p == '\t' || *p == '\n'))
4800
 
            break;
4801
 
          else
4802
 
            *pp++ = *p;
4803
 
          p++;
4804
 
        }
4805
 
      if (delim)
4806
 
        {
4807
 
          Msg(0, "%s: Missing %c quote.", rc_name, delim);
4808
 
          return 0;
4809
 
        }
4810
 
      if (*p)
4811
 
        p++;
4812
 
      *pp = 0;
4813
 
      debug2("- arg done, '%s' rest %s\n", ap[-1], p);
4814
 
      *lp++ = pp - ap[-1];
4815
 
      pp++;
4816
 
    }
4817
 
}
4818
 
 
4819
 
void
4820
 
SetEscape(u, e, me)
4821
 
struct acluser *u;
4822
 
int e, me;
4823
 
{
4824
 
  if (u)
4825
 
    {
4826
 
      u->u_Esc = e;
4827
 
      u->u_MetaEsc = me;
4828
 
    }
4829
 
  else
4830
 
    {
4831
 
      if (users)
4832
 
        {
4833
 
          if (DefaultEsc >= 0)
4834
 
            ClearAction(&ktab[DefaultEsc]);
4835
 
          if (DefaultMetaEsc >= 0)
4836
 
            ClearAction(&ktab[DefaultMetaEsc]);
4837
 
        }
4838
 
      DefaultEsc = e;
4839
 
      DefaultMetaEsc = me;
4840
 
      if (users)
4841
 
        {
4842
 
          if (DefaultEsc >= 0)
4843
 
            {
4844
 
              ClearAction(&ktab[DefaultEsc]);
4845
 
              ktab[DefaultEsc].nr = RC_OTHER;
4846
 
            }
4847
 
          if (DefaultMetaEsc >= 0)
4848
 
            {
4849
 
              ClearAction(&ktab[DefaultMetaEsc]);
4850
 
              ktab[DefaultMetaEsc].nr = RC_META;
4851
 
            }
4852
 
        }
4853
 
    }
4854
 
}
4855
 
 
4856
 
int
4857
 
ParseSwitch(act, var)
4858
 
struct action *act;
4859
 
int *var;
4860
 
{
4861
 
  if (*act->args == 0)
4862
 
    {
4863
 
      *var ^= 1;
4864
 
      return 0;
4865
 
    }
4866
 
  return ParseOnOff(act, var);
4867
 
}
4868
 
 
4869
 
static int
4870
 
ParseOnOff(act, var)
4871
 
struct action *act;
4872
 
int *var;
4873
 
{
4874
 
  register int num = -1;
4875
 
  char **args = act->args;
4876
 
 
4877
 
  if (args[1] == 0)
4878
 
    {
4879
 
      if (strcmp(args[0], "on") == 0)
4880
 
        num = 1;
4881
 
      else if (strcmp(args[0], "off") == 0)
4882
 
        num = 0;
4883
 
    }
4884
 
  if (num < 0)
4885
 
    {
4886
 
      Msg(0, "%s: %s: invalid argument. Give 'on' or 'off'", rc_name, comms[act->nr].name);
4887
 
      return -1;
4888
 
    }
4889
 
  *var = num;
4890
 
  return 0;
4891
 
}
4892
 
 
4893
 
int
4894
 
ParseSaveStr(act, var)
4895
 
struct action *act;
4896
 
char **var;
4897
 
{
4898
 
  char **args = act->args;
4899
 
  if (*args == 0 || args[1])
4900
 
    {
4901
 
      Msg(0, "%s: %s: one argument required.", rc_name, comms[act->nr].name);
4902
 
      return -1;
4903
 
    }
4904
 
  if (*var)
4905
 
    free(*var);
4906
 
  *var = SaveStr(*args);
4907
 
  return 0;
4908
 
}
4909
 
 
4910
 
int
4911
 
ParseNum(act, var)
4912
 
struct action *act;
4913
 
int *var;
4914
 
{
4915
 
  int i;
4916
 
  char *p, **args = act->args;
4917
 
 
4918
 
  p = *args;
4919
 
  if (p == 0 || *p == 0 || args[1])
4920
 
    {
4921
 
      Msg(0, "%s: %s: invalid argument. Give one argument.",
4922
 
          rc_name, comms[act->nr].name);
4923
 
      return -1;
4924
 
    }
4925
 
  i = 0; 
4926
 
  while (*p)
4927
 
    {
4928
 
      if (*p >= '0' && *p <= '9')
4929
 
        i = 10 * i + (*p - '0');
4930
 
      else
4931
 
        {
4932
 
          Msg(0, "%s: %s: invalid argument. Give numeric argument.",
4933
 
              rc_name, comms[act->nr].name);
4934
 
          return -1;
4935
 
        }    
4936
 
      p++;
4937
 
    }
4938
 
  debug1("ParseNum got %d\n", i);
4939
 
  *var = i;
4940
 
  return 0;
4941
 
}
4942
 
 
4943
 
static int
4944
 
ParseNum1000(act, var)
4945
 
struct action *act;
4946
 
int *var;
4947
 
{
4948
 
  int i;
4949
 
  char *p, **args = act->args;
4950
 
  int dig = 0;
4951
 
 
4952
 
  p = *args;
4953
 
  if (p == 0 || *p == 0 || args[1])
4954
 
    {
4955
 
      Msg(0, "%s: %s: invalid argument. Give one argument.",
4956
 
          rc_name, comms[act->nr].name);
4957
 
      return -1;
4958
 
    }
4959
 
  i = 0; 
4960
 
  while (*p)
4961
 
    {
4962
 
      if (*p >= '0' && *p <= '9')
4963
 
        {
4964
 
          if (dig < 4)
4965
 
            i = 10 * i + (*p - '0');
4966
 
          else if (dig == 4 && *p >= '5')
4967
 
            i++;
4968
 
          if (dig)
4969
 
            dig++;
4970
 
        }
4971
 
      else if (*p == '.' && !dig)
4972
 
        dig++;
4973
 
      else
4974
 
        {
4975
 
          Msg(0, "%s: %s: invalid argument. Give floating point argument.",
4976
 
              rc_name, comms[act->nr].name);
4977
 
          return -1;
4978
 
        }    
4979
 
      p++;
4980
 
    }
4981
 
  if (dig == 0)
4982
 
    i *= 1000;
4983
 
  else
4984
 
    while (dig++ < 4)
4985
 
      i *= 10;
4986
 
  if (i < 0)
4987
 
    i = (int)((unsigned int)~0 >> 1);
4988
 
  debug1("ParseNum1000 got %d\n", i);
4989
 
  *var = i;
4990
 
  return 0;
4991
 
}
4992
 
 
4993
 
static struct win *
4994
 
WindowByName(s)
4995
 
char *s;
4996
 
{
4997
 
  struct win *p;
4998
 
 
4999
 
  for (p = windows; p; p = p->w_next)
5000
 
    if (!strcmp(p->w_title, s))
5001
 
      return p;
5002
 
  for (p = windows; p; p = p->w_next)
5003
 
    if (!strncmp(p->w_title, s, strlen(s)))
5004
 
      return p;
5005
 
  return 0;
5006
 
}
5007
 
 
5008
 
static int
5009
 
WindowByNumber(str)
5010
 
char *str;
5011
 
{
5012
 
  int i;
5013
 
  char *s;
5014
 
 
5015
 
  for (i = 0, s = str; *s; s++)
5016
 
    {
5017
 
      if (*s < '0' || *s > '9')
5018
 
        break;
5019
 
      i = i * 10 + (*s - '0');
5020
 
    }
5021
 
  return *s ? -1 : i;
5022
 
}
5023
 
 
5024
 
/* 
5025
 
 * Get window number from Name or Number string.
5026
 
 * Numbers are tried first, then names, a prefix match suffices.
5027
 
 * Be careful when assigning numeric strings as WindowTitles.
5028
 
 */
5029
 
int
5030
 
WindowByNoN(str)
5031
 
char *str;
5032
 
{
5033
 
  int i;
5034
 
  struct win *p;
5035
 
  
5036
 
  if ((i = WindowByNumber(str)) < 0 || i >= maxwin)
5037
 
    {
5038
 
      if ((p = WindowByName(str)))
5039
 
        return p->w_number;
5040
 
      return -1;
5041
 
    }
5042
 
  return i;
5043
 
}
5044
 
 
5045
 
static int
5046
 
ParseWinNum(act, var)
5047
 
struct action *act;
5048
 
int *var;
5049
 
{
5050
 
  char **args = act->args;
5051
 
  int i = 0;
5052
 
 
5053
 
  if (*args == 0 || args[1])
5054
 
    {
5055
 
      Msg(0, "%s: %s: one argument required.", rc_name, comms[act->nr].name);
5056
 
      return -1;
5057
 
    }
5058
 
  
5059
 
  i = WindowByNoN(*args);
5060
 
  if (i < 0)
5061
 
    {
5062
 
      Msg(0, "%s: %s: invalid argument. Give window number or name.",
5063
 
          rc_name, comms[act->nr].name);
5064
 
      return -1;
5065
 
    }
5066
 
  debug1("ParseWinNum got %d\n", i);
5067
 
  *var = i;
5068
 
  return 0;
5069
 
}
5070
 
 
5071
 
static int
5072
 
ParseBase(act, p, var, base, bname)
5073
 
struct action *act;
5074
 
char *p;
5075
 
int *var;
5076
 
int base;
5077
 
char *bname;
5078
 
{
5079
 
  int i = 0;
5080
 
  int c;
5081
 
 
5082
 
  if (*p == 0)
5083
 
    {
5084
 
      Msg(0, "%s: %s: empty argument.", rc_name, comms[act->nr].name);
5085
 
      return -1;
5086
 
    }
5087
 
  while ((c = *p++))
5088
 
    {
5089
 
      if (c >= 'a' && c <= 'z')
5090
 
        c -= 'a' - 'A';
5091
 
      if (c >= 'A' && c <= 'Z')
5092
 
        c -= 'A' - ('0' + 10);
5093
 
      c -= '0';
5094
 
      if (c < 0 || c >= base)
5095
 
        {
5096
 
          Msg(0, "%s: %s: argument is not %s.", rc_name, comms[act->nr].name, bname);
5097
 
          return -1;
5098
 
        }    
5099
 
      i = base * i + c;
5100
 
    }
5101
 
  debug1("ParseBase got %d\n", i);
5102
 
  *var = i;
5103
 
  return 0;
5104
 
}
5105
 
 
5106
 
static int
5107
 
IsNum(s, base)
5108
 
register char *s;
5109
 
register int base;
5110
 
{
5111
 
  for (base += '0'; *s; ++s)
5112
 
    if (*s < '0' || *s > base)
5113
 
      return 0;
5114
 
  return 1;
5115
 
}
5116
 
 
5117
 
int
5118
 
IsNumColon(s, base, p, psize)
5119
 
int base, psize;
5120
 
char *s, *p;
5121
 
{
5122
 
  char *q;
5123
 
  if ((q = rindex(s, ':')) != 0)
5124
 
    {
5125
 
      strncpy(p, q + 1, psize - 1);
5126
 
      p[psize - 1] = '\0';
5127
 
      *q = '\0';
5128
 
    }
5129
 
  else
5130
 
    *p = '\0';
5131
 
  return IsNum(s, base);
5132
 
}
5133
 
 
5134
 
void
5135
 
SwitchWindow(n)
5136
 
int n;
5137
 
{
5138
 
  struct win *p;
5139
 
 
5140
 
  debug1("SwitchWindow %d\n", n);
5141
 
  if (n < 0 || n >= maxwin)
5142
 
    {
5143
 
      ShowWindows(-1);
5144
 
      return;
5145
 
    }
5146
 
  if ((p = wtab[n]) == 0)
5147
 
    {
5148
 
      ShowWindows(n);
5149
 
      return;
5150
 
    }
5151
 
  if (display == 0)
5152
 
    {
5153
 
      fore = p;
5154
 
      return;
5155
 
    }
5156
 
  if (p == D_fore)
5157
 
    {
5158
 
      Msg(0, "This IS window %d (%s).", n, p->w_title);
5159
 
      return;
5160
 
    }
5161
 
#ifdef MULTIUSER
5162
 
  if (AclCheckPermWin(D_user, ACL_READ, p))
5163
 
    {
5164
 
      Msg(0, "Access to window %d denied.", p->w_number);
5165
 
      return;
5166
 
    }
5167
 
#endif
5168
 
  SetForeWindow(p);
5169
 
  Activate(fore->w_norefresh);  
5170
 
}
5171
 
 
5172
 
/*
5173
 
 * SetForeWindow changes the window in the input focus of the display.
5174
 
 * Puts window wi in canvas display->d_forecv.
5175
 
 */
5176
 
void
5177
 
SetForeWindow(wi)
5178
 
struct win *wi;
5179
 
{
5180
 
  struct win *p;
5181
 
  if (display == 0)
5182
 
    {
5183
 
      fore = wi;
5184
 
      return;
5185
 
    }
5186
 
  p = Layer2Window(D_forecv->c_layer);
5187
 
  SetCanvasWindow(D_forecv, wi);
5188
 
  if (p)
5189
 
    WindowChanged(p, 'u');
5190
 
  if (wi)
5191
 
    WindowChanged(wi, 'u');
5192
 
  flayer = D_forecv->c_layer;
5193
 
  /* Activate called afterwards, so no RefreshHStatus needed */
5194
 
}
5195
 
 
5196
 
 
5197
 
/*****************************************************************/
5198
 
 
5199
 
/* 
5200
 
 *  Activate - make fore window active
5201
 
 *  norefresh = -1 forces a refresh, disregard all_norefresh then.
5202
 
 */
5203
 
void
5204
 
Activate(norefresh)
5205
 
int norefresh;
5206
 
{
5207
 
  debug1("Activate(%d)\n", norefresh);
5208
 
  if (display == 0)
5209
 
    return;
5210
 
  if (D_status)
5211
 
    {
5212
 
      Msg(0, "%s", ""); /* wait till mintime (keep gcc quiet) */
5213
 
      RemoveStatus();
5214
 
    }
5215
 
 
5216
 
  if (MayResizeLayer(D_forecv->c_layer))
5217
 
    ResizeLayer(D_forecv->c_layer, D_forecv->c_xe - D_forecv->c_xs + 1, D_forecv->c_ye - D_forecv->c_ys + 1, display);
5218
 
 
5219
 
  fore = D_fore;
5220
 
  if (fore)
5221
 
    {
5222
 
      /* XXX ? */
5223
 
      if (fore->w_monitor != MON_OFF)
5224
 
        fore->w_monitor = MON_ON;
5225
 
      fore->w_bell = BELL_ON;
5226
 
      WindowChanged(fore, 'f');
5227
 
 
5228
 
#if 0
5229
 
      if (ResizeDisplay(fore->w_width, fore->w_height))
5230
 
        {
5231
 
          debug2("Cannot resize from (%d,%d)", D_width, D_height);
5232
 
          debug2(" to (%d,%d) -> resize window\n", fore->w_width, fore->w_height);
5233
 
          DoResize(D_width, D_height);
5234
 
        }
5235
 
#endif
5236
 
    }
5237
 
  Redisplay(norefresh + all_norefresh);
5238
 
}
5239
 
 
5240
 
 
5241
 
static int
5242
 
NextWindow()
5243
 
{
5244
 
  register struct win **pp;
5245
 
  int n = fore ? fore->w_number : maxwin;
5246
 
  struct win *group = fore ? fore->w_group : 0;
5247
 
 
5248
 
  for (pp = fore ? wtab + n + 1 : wtab; pp != wtab + n; pp++)
5249
 
    {
5250
 
      if (pp == wtab + maxwin)
5251
 
        pp = wtab;
5252
 
      if (*pp)
5253
 
        {
5254
 
          if (!fore || group == (*pp)->w_group)
5255
 
            break;
5256
 
        }
5257
 
    }
5258
 
  if (pp == wtab + n)
5259
 
    return -1;
5260
 
  return pp - wtab;
5261
 
}
5262
 
 
5263
 
static int
5264
 
PreviousWindow()
5265
 
{
5266
 
  register struct win **pp;
5267
 
  int n = fore ? fore->w_number : -1;
5268
 
  struct win *group = fore ? fore->w_group : 0;
5269
 
 
5270
 
  for (pp = wtab + n - 1; pp != wtab + n; pp--)
5271
 
    {
5272
 
      if (pp == wtab - 1)
5273
 
        pp = wtab + maxwin - 1;
5274
 
      if (*pp)
5275
 
        {
5276
 
          if (!fore || group == (*pp)->w_group)
5277
 
            break;
5278
 
        }
5279
 
    }
5280
 
  if (pp == wtab + n)
5281
 
    return -1;
5282
 
  return pp - wtab;
5283
 
}
5284
 
 
5285
 
static int
5286
 
MoreWindows()
5287
 
{
5288
 
  char *m = "No other window.";
5289
 
  if (windows && (fore == 0 || windows->w_next))
5290
 
    return 1;
5291
 
  if (fore == 0)
5292
 
    {
5293
 
      Msg(0, "No window available");
5294
 
      return 0;
5295
 
    }
5296
 
  Msg(0, m, fore->w_number);    /* other arg for nethack */
5297
 
  return 0;
5298
 
}
5299
 
 
5300
 
void
5301
 
KillWindow(wi)
5302
 
struct win *wi;
5303
 
{
5304
 
  struct win **pp, *p;
5305
 
  struct canvas *cv;
5306
 
  int gotone;
5307
 
  struct layout *lay;
5308
 
 
5309
 
  /*
5310
 
   * Remove window from linked list.
5311
 
   */
5312
 
  for (pp = &windows; (p = *pp); pp = &p->w_next)
5313
 
    if (p == wi)
5314
 
      break;
5315
 
  ASSERT(p);
5316
 
  *pp = p->w_next;
5317
 
  wi->w_inlen = 0;
5318
 
  wtab[wi->w_number] = 0;
5319
 
 
5320
 
  if (windows == 0)
5321
 
    {
5322
 
      FreeWindow(wi);
5323
 
      Finit(0);
5324
 
    }
5325
 
 
5326
 
  /*
5327
 
   * switch to different window on all canvases
5328
 
   */
5329
 
  for (display = displays; display; display = display->d_next)
5330
 
    {
5331
 
      gotone = 0;
5332
 
      for (cv = D_cvlist; cv; cv = cv->c_next)
5333
 
        {
5334
 
          if (Layer2Window(cv->c_layer) != wi)
5335
 
            continue;
5336
 
          /* switch to other window */
5337
 
          SetCanvasWindow(cv, FindNiceWindow(D_other, 0));
5338
 
          gotone = 1;
5339
 
        }
5340
 
      if (gotone)
5341
 
        {
5342
 
#ifdef ZMODEM
5343
 
          if (wi->w_zdisplay == display)
5344
 
            {
5345
 
              D_blocked = 0;
5346
 
              D_readev.condpos = D_readev.condneg = 0;
5347
 
            }
5348
 
#endif
5349
 
          Activate(-1);
5350
 
        }
5351
 
    }
5352
 
 
5353
 
  /* do the same for the layouts */
5354
 
  for (lay = layouts; lay; lay = lay->lay_next)
5355
 
    UpdateLayoutCanvas(&lay->lay_canvas, wi);
5356
 
 
5357
 
  FreeWindow(wi);
5358
 
  WindowChanged((struct win *)0, 'w');
5359
 
  WindowChanged((struct win *)0, 'W');
5360
 
  WindowChanged((struct win *)0, 0);
5361
 
}
5362
 
 
5363
 
static void
5364
 
LogToggle(on)
5365
 
int on;
5366
 
{
5367
 
  char buf[1024];
5368
 
 
5369
 
  if ((fore->w_log != 0) == on)
5370
 
    {
5371
 
      if (display && !*rc_name)
5372
 
        Msg(0, "You are %s logging.", on ? "already" : "not");
5373
 
      return;
5374
 
    }
5375
 
  if (fore->w_log != 0)
5376
 
    {
5377
 
      Msg(0, "Logfile \"%s\" closed.", fore->w_log->name);
5378
 
      logfclose(fore->w_log);
5379
 
      fore->w_log = 0;
5380
 
      WindowChanged(fore, 'f');
5381
 
      return;
5382
 
    }
5383
 
  if (DoStartLog(fore, buf, sizeof(buf)))
5384
 
    {
5385
 
      Msg(errno, "Error opening logfile \"%s\"", buf);
5386
 
      return;
5387
 
    }
5388
 
  if (ftell(fore->w_log->fp) == 0)
5389
 
    Msg(0, "Creating logfile \"%s\".", fore->w_log->name);
5390
 
  else
5391
 
    Msg(0, "Appending to logfile \"%s\".", fore->w_log->name);
5392
 
  WindowChanged(fore, 'f');
5393
 
}
5394
 
 
5395
 
char *
5396
 
AddWindows(buf, len, flags, where)
5397
 
char *buf;
5398
 
int len;
5399
 
int flags;
5400
 
int where;
5401
 
{
5402
 
  register char *s, *ss;
5403
 
  register struct win **pp, *p;
5404
 
  register char *cmd;
5405
 
  int l;
5406
 
 
5407
 
  s = ss = buf;
5408
 
  if ((flags & 8) && where < 0)
5409
 
    {
5410
 
      *s = 0;
5411
 
      return ss;
5412
 
    }
5413
 
  for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + maxwin; pp++)
5414
 
    {
5415
 
      int rend = -1;
5416
 
      if (pp - wtab == where && ss == buf)
5417
 
        ss = s;
5418
 
      if ((p = *pp) == 0)
5419
 
        continue;
5420
 
      if ((flags & 1) && display && p == D_fore)
5421
 
        continue;
5422
 
      if (display && D_fore && D_fore->w_group != p->w_group)
5423
 
        continue;
5424
 
 
5425
 
      cmd = p->w_title;
5426
 
      l = strlen(cmd);
5427
 
      if (l > 20)
5428
 
        l = 20;
5429
 
      if (s - buf + l > len - 24)
5430
 
        break;
5431
 
      if (s > buf || (flags & 4))
5432
 
        {
5433
 
          *s++ = ' ';
5434
 
          *s++ = ' ';
5435
 
        }
5436
 
      if (p->w_number == where)
5437
 
        {
5438
 
          ss = s;
5439
 
          if (flags & 8)
5440
 
            break;
5441
 
        }
5442
 
      if (!(flags & 4) || where < 0 || ((flags & 4) && where < p->w_number))
5443
 
        {
5444
 
          if (p->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1)
5445
 
            rend = renditions[REND_MONITOR];
5446
 
          else if ((p->w_bell == BELL_DONE || p->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1)
5447
 
            rend = renditions[REND_BELL];
5448
 
          else if ((p->w_silence == SILENCE_FOUND || p->w_silence == SILENCE_DONE) && renditions[REND_SILENCE] != -1)
5449
 
            rend = renditions[REND_SILENCE];
5450
 
        }
5451
 
      if (rend != -1)
5452
 
        AddWinMsgRend(s, rend);
5453
 
      sprintf(s, "%d", p->w_number);
5454
 
      s += strlen(s);
5455
 
      if (display && p == D_fore)
5456
 
        *s++ = '*';
5457
 
      if (!(flags & 2))
5458
 
        {
5459
 
          if (display && p == D_other)
5460
 
            *s++ = '-';
5461
 
          s = AddWindowFlags(s, len, p);
5462
 
        }
5463
 
      *s++ = ' ';
5464
 
      strncpy(s, cmd, l);
5465
 
      s += l;
5466
 
      if (rend != -1)
5467
 
        AddWinMsgRend(s, -1);
5468
 
    }
5469
 
  *s = 0;
5470
 
  return ss;
5471
 
}
5472
 
 
5473
 
char *
5474
 
AddWindowFlags(buf, len, p)
5475
 
char *buf;
5476
 
int len;
5477
 
struct win *p;
5478
 
{
5479
 
  char *s = buf;
5480
 
  if (p == 0 || len < 12)
5481
 
    {
5482
 
      *s = 0;
5483
 
      return s;
5484
 
    }
5485
 
#if 0
5486
 
  if (display && p == D_fore)
5487
 
    *s++ = '*';
5488
 
  if (display && p == D_other)
5489
 
    *s++ = '-';
5490
 
#endif
5491
 
  if (p->w_layer.l_cvlist && p->w_layer.l_cvlist->c_lnext)
5492
 
    *s++ = '&';
5493
 
  if (p->w_monitor == MON_DONE
5494
 
#ifdef MULTIUSER
5495
 
      && (ACLBYTE(p->w_mon_notify, D_user->u_id) & ACLBIT(D_user->u_id))
5496
 
#endif
5497
 
     )
5498
 
    *s++ = '@';
5499
 
  if (p->w_bell == BELL_DONE)
5500
 
    *s++ = '!';
5501
 
#ifdef UTMPOK
5502
 
  if (p->w_slot != (slot_t) 0 && p->w_slot != (slot_t) -1)
5503
 
    *s++ = '$';
5504
 
#endif
5505
 
  if (p->w_log != 0)
5506
 
    {
5507
 
      strcpy(s, "(L)");
5508
 
      s += 3;
5509
 
    }
5510
 
  if (p->w_ptyfd < 0 && p->w_type != W_TYPE_GROUP)
5511
 
    *s++ = 'Z';
5512
 
  *s = 0;
5513
 
  return s;
5514
 
}
5515
 
 
5516
 
char *
5517
 
AddOtherUsers(buf, len, p)
5518
 
char *buf;
5519
 
int len;
5520
 
struct win *p;
5521
 
{
5522
 
  struct display *d, *olddisplay = display;
5523
 
  struct canvas *cv;
5524
 
  char *s;
5525
 
  int l;
5526
 
 
5527
 
  s = buf;
5528
 
  for (display = displays; display; display = display->d_next)
5529
 
    {
5530
 
      if (olddisplay && D_user == olddisplay->d_user)
5531
 
        continue;
5532
 
      for (cv = D_cvlist; cv; cv = cv->c_next)
5533
 
        if (Layer2Window(cv->c_layer) == p)
5534
 
          break;
5535
 
      if (!cv)
5536
 
        continue;
5537
 
      for (d = displays; d && d != display; d = d->d_next)
5538
 
        if (D_user == d->d_user)
5539
 
          break;
5540
 
      if (d && d != display)
5541
 
        continue;
5542
 
      if (len > 1 && s != buf)
5543
 
        {
5544
 
          *s++ = ',';
5545
 
          len--;
5546
 
        }
5547
 
      l = strlen(D_user->u_name);
5548
 
      if (l + 1 > len)
5549
 
        break;
5550
 
      strcpy(s, D_user->u_name);
5551
 
      s += l;
5552
 
      len -= l;
5553
 
    }
5554
 
  *s = 0;
5555
 
  display = olddisplay;
5556
 
  return s;
5557
 
}
5558
 
 
5559
 
void
5560
 
ShowWindows(where)
5561
 
int where;
5562
 
{
5563
 
  char buf[1024];
5564
 
  char *s, *ss;
5565
 
 
5566
 
  if (display && where == -1 && D_fore)
5567
 
    where = D_fore->w_number;
5568
 
  ss = AddWindows(buf, sizeof(buf), 0, where);
5569
 
  s = buf + strlen(buf);
5570
 
  if (display && ss - buf > D_width / 2)
5571
 
    {
5572
 
      ss -= D_width / 2;
5573
 
      if (s - ss < D_width)
5574
 
        {
5575
 
          ss = s - D_width;
5576
 
          if (ss < buf)
5577
 
            ss = buf;
5578
 
        }
5579
 
    }
5580
 
  else
5581
 
    ss = buf;
5582
 
  Msg(0, "%s", ss);
5583
 
}
5584
 
 
5585
 
static void
5586
 
ShowInfo()
5587
 
{
5588
 
  char buf[512], *p;
5589
 
  register struct win *wp = fore;
5590
 
  register int i;
5591
 
 
5592
 
  if (wp == 0)
5593
 
    {
5594
 
      Msg(0, "(%d,%d)/(%d,%d) no window", D_x + 1, D_y + 1, D_width, D_height);
5595
 
      return;
5596
 
    }
5597
 
  p = buf;
5598
 
  if (buf < (p += GetAnsiStatus(wp, p)))
5599
 
    *p++ = ' ';
5600
 
  sprintf(p, "(%d,%d)/(%d,%d)",
5601
 
    wp->w_x + 1, wp->w_y + 1, wp->w_width, wp->w_height);
5602
 
#ifdef COPY_PASTE
5603
 
  sprintf(p += strlen(p), "+%d", wp->w_histheight);
5604
 
#endif
5605
 
  sprintf(p += strlen(p), " %c%sflow",
5606
 
          (wp->w_flow & FLOW_NOW) ? '+' : '-',
5607
 
          (wp->w_flow & FLOW_AUTOFLAG) ? "" : 
5608
 
           ((wp->w_flow & FLOW_AUTO) ? "(+)" : "(-)"));
5609
 
  if (!wp->w_wrap) sprintf(p += strlen(p), " -wrap");
5610
 
  if (wp->w_insert) sprintf(p += strlen(p), " ins");
5611
 
  if (wp->w_origin) sprintf(p += strlen(p), " org");
5612
 
  if (wp->w_keypad) sprintf(p += strlen(p), " app");
5613
 
  if (wp->w_log)    sprintf(p += strlen(p), " log");
5614
 
  if (wp->w_monitor != MON_OFF
5615
 
#ifdef MULTIUSER
5616
 
      && (ACLBYTE(wp->w_mon_notify, D_user->u_id) & ACLBIT(D_user->u_id))
5617
 
#endif
5618
 
     )
5619
 
    sprintf(p += strlen(p), " mon");
5620
 
  if (wp->w_mouse) sprintf(p += strlen(p), " mouse");
5621
 
#ifdef COLOR
5622
 
  if (wp->w_bce) sprintf(p += strlen(p), " bce");
5623
 
#endif
5624
 
  if (!wp->w_c1) sprintf(p += strlen(p), " -c1");
5625
 
  if (wp->w_norefresh) sprintf(p += strlen(p), " nored");
5626
 
 
5627
 
  p += strlen(p);
5628
 
#ifdef FONT
5629
 
# ifdef ENCODINGS
5630
 
  if (wp->w_encoding && (display == 0 || D_encoding != wp->w_encoding || EncodingDefFont(wp->w_encoding) <= 0))
5631
 
    {
5632
 
      *p++ = ' ';
5633
 
      strcpy(p, EncodingName(wp->w_encoding));
5634
 
      p += strlen(p);
5635
 
    }
5636
 
#  ifdef UTF8
5637
 
  if (wp->w_encoding != UTF8)
5638
 
#  endif
5639
 
# endif
5640
 
    if (D_CC0 || (D_CS0 && *D_CS0))
5641
 
      {
5642
 
        if (wp->w_gr == 2)
5643
 
          {
5644
 
            sprintf(p, " G%c", wp->w_Charset + '0');
5645
 
            if (wp->w_FontE >= ' ')
5646
 
              p[3] = wp->w_FontE;
5647
 
            else
5648
 
              {
5649
 
                p[3] = '^';
5650
 
                p[4] = wp->w_FontE ^ 0x40;
5651
 
                p++;
5652
 
              }
5653
 
            p[4] = '[';
5654
 
            p++;
5655
 
          }
5656
 
        else if (wp->w_gr)
5657
 
          sprintf(p++, " G%c%c[", wp->w_Charset + '0', wp->w_CharsetR + '0');
5658
 
        else
5659
 
          sprintf(p, " G%c[", wp->w_Charset + '0');
5660
 
        p += 4;
5661
 
        for (i = 0; i < 4; i++)
5662
 
          {
5663
 
            if (wp->w_charsets[i] == ASCII)
5664
 
              *p++ = 'B';
5665
 
            else if (wp->w_charsets[i] >= ' ')
5666
 
              *p++ = wp->w_charsets[i];
5667
 
            else
5668
 
              {
5669
 
                *p++ = '^';
5670
 
                *p++ = wp->w_charsets[i] ^ 0x40;
5671
 
              }
5672
 
          }
5673
 
        *p++ = ']';
5674
 
        *p = 0;
5675
 
      }
5676
 
#endif
5677
 
 
5678
 
  if (wp->w_type == W_TYPE_PLAIN)
5679
 
    {
5680
 
      /* add info about modem control lines */
5681
 
      *p++ = ' ';
5682
 
      TtyGetModemStatus(wp->w_ptyfd, p);
5683
 
    }
5684
 
#ifdef BUILTIN_TELNET
5685
 
  else if (wp->w_type == W_TYPE_TELNET)
5686
 
    {
5687
 
      *p++ = ' ';
5688
 
      TelStatus(wp, p, sizeof(buf) - 1 - (p - buf));
5689
 
    }
5690
 
#endif
5691
 
  Msg(0, "%s %d(%s)", buf, wp->w_number, wp->w_title);
5692
 
}
5693
 
 
5694
 
static void
5695
 
ShowDInfo()
5696
 
{
5697
 
  char buf[512], *p;
5698
 
  if (display == 0)
5699
 
    return;
5700
 
  p = buf;
5701
 
  sprintf(p, "(%d,%d)", D_width, D_height),
5702
 
  p += strlen(p);
5703
 
#ifdef ENCODINGS
5704
 
  if (D_encoding)
5705
 
    {
5706
 
      *p++ = ' ';
5707
 
      strcpy(p, EncodingName(D_encoding));
5708
 
      p += strlen(p);
5709
 
    }
5710
 
#endif
5711
 
  if (D_CXT)
5712
 
    {
5713
 
      strcpy(p, " xterm");
5714
 
      p += strlen(p);
5715
 
    }
5716
 
#ifdef COLOR
5717
 
  if (D_hascolor)
5718
 
    {
5719
 
      strcpy(p, " color");
5720
 
      p += strlen(p);
5721
 
    }
5722
 
#endif
5723
 
#ifdef FONT
5724
 
  if (D_CG0)
5725
 
    {
5726
 
      strcpy(p, " iso2022");
5727
 
      p += strlen(p);
5728
 
    }
5729
 
  else if (D_CS0 && *D_CS0)
5730
 
    {
5731
 
      strcpy(p, " altchar");
5732
 
      p += strlen(p);
5733
 
    }
5734
 
#endif
5735
 
  Msg(0, "%s", buf);
5736
 
}
5737
 
 
5738
 
static void
5739
 
AKAfin(buf, len, data)
5740
 
char *buf;
5741
 
int len;
5742
 
char *data;     /* dummy */
5743
 
{
5744
 
  ASSERT(display);
5745
 
  if (len && fore)
5746
 
    ChangeAKA(fore, buf, strlen(buf));
5747
 
}
5748
 
 
5749
 
static void
5750
 
InputAKA()
5751
 
{
5752
 
  char *s, *ss;
5753
 
  int n;
5754
 
  Input("Set window's title to: ", sizeof(fore->w_akabuf) - 1, INP_COOKED, AKAfin, NULL, 0);
5755
 
  s = fore->w_title;
5756
 
  if (!s)
5757
 
    return;
5758
 
  for (; *s; s++)
5759
 
    {
5760
 
      if ((*(unsigned char *)s & 0x7f) < 0x20 || *s == 0x7f)
5761
 
        continue;
5762
 
      ss = s;
5763
 
      n = 1;
5764
 
      LayProcess(&ss, &n);
5765
 
    }
5766
 
}
5767
 
 
5768
 
static void
5769
 
Colonfin(buf, len, data)
5770
 
char *buf;
5771
 
int len;
5772
 
char *data;     /* dummy */
5773
 
{
5774
 
  char mbuf[256];
5775
 
 
5776
 
  RemoveStatus();
5777
 
  if (buf[len] == '\t')
5778
 
    {
5779
 
      int m, x;
5780
 
      int l = 0, r = RC_LAST;
5781
 
      int showmessage = 0;
5782
 
      char *s = buf;
5783
 
 
5784
 
      while (*s && s - buf < len)
5785
 
        if (*s++ == ' ')
5786
 
          return;
5787
 
 
5788
 
      /* Showing a message when there's no hardstatus or caption cancels the input */
5789
 
      if (display &&
5790
 
          (captionalways || D_has_hstatus == HSTATUS_LASTLINE || (D_canvas.c_slperp && D_canvas.c_slperp->c_slnext)))
5791
 
        showmessage = 1;
5792
 
 
5793
 
      while (l <= r)
5794
 
        {
5795
 
          m = (l + r) / 2;
5796
 
          x = strncmp(buf, comms[m].name, len);
5797
 
          if (x > 0)
5798
 
            l = m + 1;
5799
 
          else if (x < 0)
5800
 
            r = m - 1;
5801
 
          else
5802
 
            {
5803
 
              s = mbuf;
5804
 
              for (l = m - 1; l >= 0 && strncmp(buf, comms[l].name, len) == 0; l--)
5805
 
                ;
5806
 
              for (m = ++l; m <= r && strncmp(buf, comms[m].name, len) == 0 && s - mbuf < sizeof(mbuf); m++)
5807
 
                s += snprintf(s, sizeof(mbuf) - (s - mbuf), " %s", comms[m].name);
5808
 
              if (l < m - 1)
5809
 
                {
5810
 
                  if (showmessage)
5811
 
                    Msg(0, "Possible commands:%s", mbuf);
5812
 
                }
5813
 
              else
5814
 
                {
5815
 
                  s = mbuf;
5816
 
                  len = snprintf(mbuf, sizeof(mbuf), "%s \t", comms[l].name + len);
5817
 
                  if (len > 0 && len < sizeof(mbuf))
5818
 
                    LayProcess(&s, &len);
5819
 
                }
5820
 
              break;
5821
 
            }
5822
 
        }
5823
 
      if (l > r && showmessage)
5824
 
        Msg(0, "No commands matching '%*s'", len, buf);
5825
 
      return;
5826
 
    }
5827
 
 
5828
 
  if (!len || buf[len])
5829
 
    return;
5830
 
 
5831
 
  len = strlen(buf) + 1;
5832
 
  if (len > (int)sizeof(mbuf))
5833
 
    RcLine(buf, len);
5834
 
  else
5835
 
    {
5836
 
      bcopy(buf, mbuf, len);
5837
 
      RcLine(mbuf, sizeof mbuf);
5838
 
    }
5839
 
}
5840
 
 
5841
 
static void
5842
 
SelectFin(buf, len, data)
5843
 
char *buf;
5844
 
int len;
5845
 
char *data;     /* dummy */
5846
 
{
5847
 
  int n;
5848
 
 
5849
 
  if (!len || !display)
5850
 
    return;
5851
 
  if (len == 1 && *buf == '-')
5852
 
    {
5853
 
      SetForeWindow((struct win *)0);
5854
 
      Activate(0);
5855
 
      return;
5856
 
    }
5857
 
  if ((n = WindowByNoN(buf)) < 0)
5858
 
    return;
5859
 
  SwitchWindow(n);
5860
 
}
5861
 
 
5862
 
static void
5863
 
SelectLayoutFin(buf, len, data)
5864
 
char *buf;
5865
 
int len;
5866
 
char *data;     /* dummy */
5867
 
{
5868
 
  struct layout *lay;
5869
 
 
5870
 
  if (!len || !display)
5871
 
    return;
5872
 
  if (len == 1 && *buf == '-')
5873
 
    {
5874
 
      LoadLayout((struct layout *)0, (struct canvas *)0);
5875
 
      Activate(0);
5876
 
      return;
5877
 
    }
5878
 
  lay = FindLayout(buf);
5879
 
  if (!lay)
5880
 
    Msg(0, "No such layout\n");
5881
 
  else if (lay == D_layout)
5882
 
    Msg(0, "This IS layout %d (%s).\n", lay->lay_number, lay->lay_title);
5883
 
  else
5884
 
    {
5885
 
      LoadLayout(lay, &D_canvas);
5886
 
      Activate(0);
5887
 
    }
5888
 
}
5889
 
 
5890
 
    
5891
 
static void
5892
 
InputSelect()
5893
 
{
5894
 
  Input("Switch to window: ", 20, INP_COOKED, SelectFin, NULL, 0);
5895
 
}
5896
 
 
5897
 
static char setenv_var[31];
5898
 
 
5899
 
 
5900
 
static void
5901
 
SetenvFin1(buf, len, data)
5902
 
char *buf;
5903
 
int len;
5904
 
char *data;     /* dummy */
5905
 
{
5906
 
  if (!len || !display)
5907
 
    return;
5908
 
  InputSetenv(buf);
5909
 
}
5910
 
  
5911
 
static void
5912
 
SetenvFin2(buf, len, data)
5913
 
char *buf;
5914
 
int len;
5915
 
char *data;     /* dummy */
5916
 
{
5917
 
  if (!len || !display)
5918
 
    return;
5919
 
  debug2("SetenvFin2: setenv '%s' '%s'\n", setenv_var, buf);
5920
 
  xsetenv(setenv_var, buf);
5921
 
  MakeNewEnv();
5922
 
}
5923
 
 
5924
 
static void
5925
 
InputSetenv(arg)
5926
 
char *arg;
5927
 
{
5928
 
  static char setenv_buf[50 + sizeof(setenv_var)];      /* need to be static here, cannot be freed */
5929
 
 
5930
 
  if (arg)
5931
 
    {
5932
 
      strncpy(setenv_var, arg, sizeof(setenv_var) - 1);
5933
 
      sprintf(setenv_buf, "Enter value for %s: ", setenv_var);
5934
 
      Input(setenv_buf, 30, INP_COOKED, SetenvFin2, NULL, 0);
5935
 
    }
5936
 
  else
5937
 
    Input("Setenv: Enter variable name: ", 30, INP_COOKED, SetenvFin1, NULL, 0);
5938
 
}
5939
 
 
5940
 
/*
5941
 
 * the following options are understood by this parser:
5942
 
 * -f, -f0, -f1, -fy, -fa
5943
 
 * -t title, -T terminal-type, -h height-of-scrollback, 
5944
 
 * -ln, -l0, -ly, -l1, -l
5945
 
 * -a, -M, -L
5946
 
 */
5947
 
void
5948
 
DoScreen(fn, av)
5949
 
char *fn, **av;
5950
 
{
5951
 
  struct NewWindow nwin;
5952
 
  register int num;
5953
 
  char buf[20];
5954
 
 
5955
 
  nwin = nwin_undef;
5956
 
  while (av && *av && av[0][0] == '-')
5957
 
    {
5958
 
      if (av[0][1] == '-')
5959
 
        {
5960
 
          av++;
5961
 
          break;
5962
 
        }
5963
 
      switch (av[0][1])
5964
 
        {
5965
 
        case 'f':
5966
 
          switch (av[0][2])
5967
 
            {
5968
 
            case 'n':
5969
 
            case '0':
5970
 
              nwin.flowflag = FLOW_NOW * 0;
5971
 
              break;
5972
 
            case 'y':
5973
 
            case '1':
5974
 
            case '\0':
5975
 
              nwin.flowflag = FLOW_NOW * 1;
5976
 
              break;
5977
 
            case 'a':
5978
 
              nwin.flowflag = FLOW_AUTOFLAG;
5979
 
              break;
5980
 
            default:
5981
 
              break;
5982
 
            }
5983
 
          break;
5984
 
        case 't':       /* no more -k */
5985
 
          if (av[0][2])
5986
 
            nwin.aka = &av[0][2];
5987
 
          else if (*++av)
5988
 
            nwin.aka = *av;
5989
 
          else
5990
 
            --av;
5991
 
          break;
5992
 
        case 'T':
5993
 
          if (av[0][2])
5994
 
            nwin.term = &av[0][2];
5995
 
          else if (*++av)
5996
 
            nwin.term = *av;
5997
 
          else
5998
 
            --av;
5999
 
          break;
6000
 
        case 'h':
6001
 
          if (av[0][2])
6002
 
            nwin.histheight = atoi(av[0] + 2);
6003
 
          else if (*++av)
6004
 
            nwin.histheight = atoi(*av);
6005
 
          else 
6006
 
            --av;
6007
 
          break;
6008
 
#ifdef LOGOUTOK
6009
 
        case 'l':
6010
 
          switch (av[0][2])
6011
 
            {
6012
 
            case 'n':
6013
 
            case '0':
6014
 
              nwin.lflag = 0;
6015
 
              break;
6016
 
            case 'y':
6017
 
            case '1':
6018
 
            case '\0':
6019
 
              nwin.lflag = 1;
6020
 
              break;
6021
 
            case 'a':
6022
 
              nwin.lflag = 3;
6023
 
              break;
6024
 
            default:
6025
 
              break;
6026
 
            }
6027
 
          break;
6028
 
#endif
6029
 
        case 'a':
6030
 
          nwin.aflag = 1;
6031
 
          break;
6032
 
        case 'M':
6033
 
          nwin.monitor = MON_ON;
6034
 
          break;
6035
 
        case 'L':
6036
 
          nwin.Lflag = 1;
6037
 
          break;
6038
 
        default:
6039
 
          Msg(0, "%s: screen: invalid option -%c.", fn, av[0][1]);
6040
 
          break;
6041
 
        }
6042
 
      ++av;
6043
 
    }
6044
 
  num = 0;
6045
 
  if (av && *av && IsNumColon(*av, 10, buf, sizeof(buf)))
6046
 
    {
6047
 
      if (*buf != '\0')
6048
 
        nwin.aka = buf;
6049
 
      num = atoi(*av);
6050
 
      if (num < 0 || (maxwin && num > maxwin - 1) || (!maxwin && num > MAXWIN - 1))
6051
 
        {
6052
 
          Msg(0, "%s: illegal screen number %d.", fn, num);
6053
 
          num = 0;
6054
 
        }
6055
 
      nwin.StartAt = num;
6056
 
      ++av;
6057
 
    }
6058
 
  if (av && *av)
6059
 
    {
6060
 
      nwin.args = av;
6061
 
      if (!nwin.aka)
6062
 
        nwin.aka = Filename(*av);
6063
 
    }
6064
 
  MakeWindow(&nwin);
6065
 
}
6066
 
 
6067
 
#ifdef COPY_PASTE
6068
 
/*
6069
 
 * CompileKeys must be called before Markroutine is first used.
6070
 
 * to initialise the keys with defaults, call CompileKeys(NULL, mark_key_tab);
6071
 
 *
6072
 
 * s is an ascii string in a termcap-like syntax. It looks like
6073
 
 *   "j=u:k=d:l=r:h=l: =.:" and so on...
6074
 
 * this example rebinds the cursormovement to the keys u (up), d (down),
6075
 
 * l (left), r (right). placing a mark will now be done with ".".
6076
 
 */
6077
 
int
6078
 
CompileKeys(s, sl, array)
6079
 
char *s;
6080
 
int sl;
6081
 
unsigned char *array;
6082
 
{
6083
 
  int i;
6084
 
  unsigned char key, value;
6085
 
 
6086
 
  if (sl == 0)
6087
 
    {
6088
 
      for (i = 0; i < 256; i++)
6089
 
        array[i] = i;
6090
 
      return 0;
6091
 
    }
6092
 
  debug1("CompileKeys: '%s'\n", s);
6093
 
  while (sl)
6094
 
    {
6095
 
      key = *(unsigned char *)s++;
6096
 
      if (*s != '=' || sl < 3)
6097
 
        return -1;
6098
 
      sl--;
6099
 
      do 
6100
 
        {
6101
 
          s++;
6102
 
          sl -= 2;
6103
 
          value = *(unsigned char *)s++;
6104
 
          array[value] = key;
6105
 
        }
6106
 
      while (*s == '=' && sl >= 2);
6107
 
      if (sl == 0) 
6108
 
        break;
6109
 
      if (*s++ != ':')
6110
 
        return -1;
6111
 
      sl--;
6112
 
    }
6113
 
  return 0;
6114
 
}
6115
 
#endif /* COPY_PASTE */
6116
 
 
6117
 
/*
6118
 
 *  Asynchronous input functions
6119
 
 */
6120
 
 
6121
 
#if defined(DETACH) && defined(POW_DETACH)
6122
 
static void
6123
 
pow_detach_fn(buf, len, data)
6124
 
char *buf;
6125
 
int len;
6126
 
char *data;     /* dummy */
6127
 
{
6128
 
  debug("pow_detach_fn called\n");
6129
 
  if (len)
6130
 
    {
6131
 
      *buf = 0;
6132
 
      return;
6133
 
    }
6134
 
  if (ktab[(int)(unsigned char)*buf].nr != RC_POW_DETACH)
6135
 
    {
6136
 
      if (display)
6137
 
        write(D_userfd, "\007", 1);
6138
 
      Msg(0, "Detach aborted.");
6139
 
    }
6140
 
  else
6141
 
    Detach(D_POWER);
6142
 
}
6143
 
#endif /* POW_DETACH */
6144
 
 
6145
 
#ifdef COPY_PASTE
6146
 
static void
6147
 
copy_reg_fn(buf, len, data)
6148
 
char *buf;
6149
 
int len;
6150
 
char *data;     /* dummy */
6151
 
{
6152
 
  struct plop *pp = plop_tab + (int)(unsigned char)*buf;
6153
 
 
6154
 
  if (len)
6155
 
    {
6156
 
      *buf = 0;
6157
 
      return;
6158
 
    }
6159
 
  if (pp->buf)
6160
 
    free(pp->buf);
6161
 
  pp->buf = 0;
6162
 
  pp->len = 0;
6163
 
  if (D_user->u_plop.len)
6164
 
    {
6165
 
      if ((pp->buf = (char *)malloc(D_user->u_plop.len)) == NULL)
6166
 
        {
6167
 
          Msg(0, "%s", strnomem);
6168
 
          return;
6169
 
        }
6170
 
      bcopy(D_user->u_plop.buf, pp->buf, D_user->u_plop.len);
6171
 
    }
6172
 
  pp->len = D_user->u_plop.len;
6173
 
#ifdef ENCODINGS
6174
 
  pp->enc = D_user->u_plop.enc;
6175
 
#endif
6176
 
  Msg(0, "Copied %d characters into register %c", D_user->u_plop.len, *buf);
6177
 
}
6178
 
 
6179
 
static void
6180
 
ins_reg_fn(buf, len, data)
6181
 
char *buf;
6182
 
int len;
6183
 
char *data;     /* dummy */
6184
 
{
6185
 
  struct plop *pp = plop_tab + (int)(unsigned char)*buf;
6186
 
 
6187
 
  if (len)
6188
 
    {
6189
 
      *buf = 0;
6190
 
      return;
6191
 
    }
6192
 
  if (!fore)
6193
 
    return;     /* Input() should not call us w/o fore, but you never know... */
6194
 
  if (*buf == '.')
6195
 
    Msg(0, "ins_reg_fn: Warning: pasting real register '.'!");
6196
 
  if (pp->buf)
6197
 
    {
6198
 
      MakePaster(&fore->w_paster, pp->buf, pp->len, 0);
6199
 
      return;
6200
 
    }
6201
 
  Msg(0, "Empty register.");
6202
 
}
6203
 
#endif /* COPY_PASTE */
6204
 
 
6205
 
static void
6206
 
process_fn(buf, len, data)
6207
 
char *buf;
6208
 
int len;
6209
 
char *data;     /* dummy */
6210
 
{
6211
 
  struct plop *pp = plop_tab + (int)(unsigned char)*buf;
6212
 
 
6213
 
  if (len)
6214
 
    {
6215
 
      *buf = 0;
6216
 
      return;
6217
 
    }
6218
 
  if (pp->buf)
6219
 
    {
6220
 
      ProcessInput(pp->buf, pp->len);
6221
 
      return;
6222
 
    }
6223
 
  Msg(0, "Empty register.");
6224
 
}
6225
 
 
6226
 
static void
6227
 
confirm_fn(buf, len, data)
6228
 
char *buf;
6229
 
int len;
6230
 
char *data;
6231
 
{
6232
 
  struct action act;
6233
 
 
6234
 
  if (len || (*buf != 'y' && *buf != 'Y'))
6235
 
    {
6236
 
      *buf = 0;
6237
 
      return;
6238
 
    }
6239
 
  act.nr = *(int *)data;
6240
 
  act.args = noargs;
6241
 
  act.argl = 0;
6242
 
  act.quiet = 0;
6243
 
  DoAction(&act, -1);
6244
 
}
6245
 
 
6246
 
#ifdef MULTIUSER
6247
 
struct inputsu
6248
 
{
6249
 
  struct acluser **up;
6250
 
  char name[24];
6251
 
  char pw1[130];        /* FreeBSD crypts to 128 bytes */
6252
 
  char pw2[130];
6253
 
};
6254
 
 
6255
 
static void
6256
 
su_fin(buf, len, data)
6257
 
char *buf;
6258
 
int len;
6259
 
char *data;
6260
 
{
6261
 
  struct inputsu *i = (struct inputsu *)data;
6262
 
  char *p;
6263
 
  int l;
6264
 
 
6265
 
  if (!*i->name)
6266
 
    { p = i->name; l = sizeof(i->name) - 1; }
6267
 
  else if (!*i->pw1)
6268
 
    { strcpy(p = i->pw1, "\377"); l = sizeof(i->pw1) - 1; }
6269
 
  else
6270
 
    { strcpy(p = i->pw2, "\377"); l = sizeof(i->pw2) - 1; }
6271
 
  if (buf && len)
6272
 
    strncpy(p, buf, 1 + (l < len) ? l : len);
6273
 
  if (!*i->name)
6274
 
    Input("Screen User: ", sizeof(i->name) - 1, INP_COOKED, su_fin, (char *)i, 0);
6275
 
  else if (!*i->pw1)
6276
 
    Input("User's UNIX Password: ", sizeof(i->pw1)-1, INP_COOKED|INP_NOECHO, su_fin, (char *)i, 0);
6277
 
  else if (!*i->pw2)
6278
 
    Input("User's Screen Password: ", sizeof(i->pw2)-1, INP_COOKED|INP_NOECHO, su_fin, (char *)i, 0);
6279
 
  else
6280
 
    {
6281
 
      if ((p = DoSu(i->up, i->name, i->pw2, i->pw1)))
6282
 
        Msg(0, "%s", p);
6283
 
      free((char *)i);
6284
 
    }
6285
 
}
6286
 
 
6287
 
static int
6288
 
InputSu(w, up, name)
6289
 
struct win *w;
6290
 
struct acluser **up;
6291
 
char *name;
6292
 
{
6293
 
  struct inputsu *i;
6294
 
 
6295
 
  if (!(i = (struct inputsu *)calloc(1, sizeof(struct inputsu))))
6296
 
    return -1;
6297
 
 
6298
 
  i->up = up;
6299
 
  if (name && *name)
6300
 
    su_fin(name, (int)strlen(name), (char *)i); /* can also initialise stuff */
6301
 
  else
6302
 
    su_fin((char *)0, 0, (char *)i);
6303
 
  return 0;
6304
 
}
6305
 
#endif  /* MULTIUSER */
6306
 
 
6307
 
#ifdef PASSWORD
6308
 
 
6309
 
static void
6310
 
pass1(buf, len, data)
6311
 
char *buf;
6312
 
int len;
6313
 
char *data;
6314
 
{
6315
 
  struct acluser *u = (struct acluser *)data;
6316
 
 
6317
 
  if (!*buf)
6318
 
    return;
6319
 
  ASSERT(u);
6320
 
  if (u->u_password != NullStr)
6321
 
    free((char *)u->u_password);
6322
 
  u->u_password = SaveStr(buf);
6323
 
  bzero(buf, strlen(buf));
6324
 
  Input("Retype new password:", 100, INP_NOECHO, pass2, data, 0);
6325
 
}
6326
 
 
6327
 
static void
6328
 
pass2(buf, len, data)
6329
 
char *buf;
6330
 
int len;
6331
 
char *data;
6332
 
{
6333
 
  int st;
6334
 
  char salt[3];
6335
 
  struct acluser *u = (struct acluser *)data;
6336
 
 
6337
 
  ASSERT(u);
6338
 
  if (!buf || strcmp(u->u_password, buf))
6339
 
    {
6340
 
      Msg(0, "[ Passwords don't match - checking turned off ]");
6341
 
      if (u->u_password != NullStr)
6342
 
        {
6343
 
          bzero(u->u_password, strlen(u->u_password));
6344
 
          free((char *)u->u_password);
6345
 
        }
6346
 
      u->u_password = NullStr;
6347
 
    }
6348
 
  else if (u->u_password[0] == '\0')
6349
 
    {
6350
 
      Msg(0, "[ No password - no secure ]");
6351
 
      if (buf)
6352
 
        bzero(buf, strlen(buf));
6353
 
    }
6354
 
  
6355
 
  if (u->u_password != NullStr)
6356
 
    {
6357
 
      for (st = 0; st < 2; st++)
6358
 
        salt[st] = 'A' + (int)((time(0) >> 6 * st) % 26);
6359
 
      salt[2] = 0;
6360
 
      buf = crypt(u->u_password, salt);
6361
 
      bzero(u->u_password, strlen(u->u_password));
6362
 
      free((char *)u->u_password);
6363
 
      if (!buf)
6364
 
        {
6365
 
          Msg(0, "[ crypt() error - no secure ]");
6366
 
          u->u_password = NullStr;
6367
 
          return;
6368
 
        }
6369
 
      u->u_password = SaveStr(buf);
6370
 
      bzero(buf, strlen(buf));
6371
 
#ifdef COPY_PASTE
6372
 
      if (u->u_plop.buf)
6373
 
        UserFreeCopyBuffer(u);
6374
 
      u->u_plop.len = strlen(u->u_password);
6375
 
# ifdef ENCODINGS
6376
 
      u->u_plop.enc = 0;
6377
 
#endif
6378
 
      if (!(u->u_plop.buf = SaveStr(u->u_password)))
6379
 
        {
6380
 
          Msg(0, "%s", strnomem);
6381
 
          D_user->u_plop.len = 0;
6382
 
        }
6383
 
      else
6384
 
        Msg(0, "[ Password moved into copybuffer ]");
6385
 
#else                           /* COPY_PASTE */
6386
 
      Msg(0, "[ Crypted password is \"%s\" ]", u->u_password);
6387
 
#endif                          /* COPY_PASTE */
6388
 
    }
6389
 
}
6390
 
#endif /* PASSWORD */
6391
 
 
6392
 
static int
6393
 
digraph_find(buf)
6394
 
const char *buf;
6395
 
{
6396
 
  int i;
6397
 
  for (i = 0; i < MAX_DIGRAPH && digraphs[i].d[0]; i++)
6398
 
    if ((digraphs[i].d[0] == (unsigned char)buf[0] && digraphs[i].d[1] == (unsigned char)buf[1]) ||
6399
 
        (digraphs[i].d[0] == (unsigned char)buf[1] && digraphs[i].d[1] == (unsigned char)buf[0]))
6400
 
      break;
6401
 
  return i;
6402
 
}
6403
 
 
6404
 
static void
6405
 
digraph_fn(buf, len, data)
6406
 
char *buf;
6407
 
int len;
6408
 
char *data;     /* dummy */
6409
 
{
6410
 
  int ch, i, x;
6411
 
 
6412
 
  ch = buf[len];
6413
 
  if (ch)
6414
 
    {
6415
 
      buf[len + 1] = ch;                /* so we can restore it later */
6416
 
      if (ch < ' ' || ch == '\177')
6417
 
        return;
6418
 
      if (len >= 1 && ((*buf == 'U' && buf[1] == '+') || (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X'))))
6419
 
        {
6420
 
          if (len == 1)
6421
 
            return;
6422
 
          if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f') && (ch < 'A' || ch > 'F'))
6423
 
            {
6424
 
              buf[len] = '\034';        /* ^] is ignored by Input() */
6425
 
              return;
6426
 
            }
6427
 
          if (len == (*buf == 'U' ? 5 : 3))
6428
 
            buf[len] = '\n';
6429
 
          return;
6430
 
        }
6431
 
      if (len && *buf == '0')
6432
 
        {
6433
 
          if (ch < '0' || ch > '7')
6434
 
            {
6435
 
              buf[len] = '\034';        /* ^] is ignored by Input() */
6436
 
              return;
6437
 
            }
6438
 
          if (len == 3)
6439
 
            buf[len] = '\n';
6440
 
          return;
6441
 
        }
6442
 
      if (len == 1)
6443
 
        buf[len] = '\n';
6444
 
      return;
6445
 
    }
6446
 
  if (len < 1)
6447
 
    return;
6448
 
  if (buf[len + 1])
6449
 
    {
6450
 
      buf[len] = buf[len + 1];  /* stored above */
6451
 
      len++;
6452
 
    }
6453
 
  if (len < 2)
6454
 
    return;
6455
 
  if (!parse_input_int(buf, len, &x))
6456
 
    {
6457
 
      i = digraph_find(buf);
6458
 
      if ((x = digraphs[i].value) <= 0)
6459
 
        {
6460
 
          Msg(0, "Unknown digraph");
6461
 
          return;
6462
 
        }
6463
 
    }
6464
 
  i = 1;
6465
 
  *buf = x;
6466
 
#ifdef UTF8
6467
 
  if (flayer->l_encoding == UTF8)
6468
 
    i = ToUtf8(buf, x); /* buf is big enough for all UTF-8 codes */
6469
 
#endif
6470
 
  while(i)
6471
 
    LayProcess(&buf, &i);
6472
 
}
6473
 
 
6474
 
#ifdef MAPKEYS
6475
 
int
6476
 
StuffKey(i)
6477
 
int i;
6478
 
{
6479
 
  struct action *act;
6480
 
  int discard = 0;
6481
 
  int keyno = i;
6482
 
 
6483
 
  debug1("StuffKey #%d", i);
6484
 
#ifdef DEBUG
6485
 
  if (i < KMAP_KEYS)
6486
 
    debug1(" - %s", term[i + T_CAPS].tcname);
6487
 
#endif
6488
 
 
6489
 
  if (i < KMAP_KEYS && D_ESCseen)
6490
 
    {
6491
 
      struct action *act = &D_ESCseen[i + 256];
6492
 
      if (act->nr != RC_ILLEGAL)
6493
 
        {
6494
 
          D_ESCseen = 0;
6495
 
          WindowChanged(fore, 'E');
6496
 
          DoAction(act, i + 256);
6497
 
          return 0;
6498
 
        }
6499
 
      discard = 1;
6500
 
    }
6501
 
 
6502
 
  if (i >= T_CURSOR - T_CAPS && i < T_KEYPAD - T_CAPS && D_cursorkeys)
6503
 
    i += T_OCAPS - T_CURSOR;
6504
 
  else if (i >= T_KEYPAD - T_CAPS && i < T_OCAPS - T_CAPS && D_keypad)
6505
 
    i += T_OCAPS - T_CURSOR;
6506
 
  debug1(" - action %d\n", i);
6507
 
  flayer = D_forecv->c_layer;
6508
 
  fore = D_fore;
6509
 
  act = 0;
6510
 
#ifdef COPY_PASTE
6511
 
  if (flayer && flayer->l_mode == 1)
6512
 
    act = i < KMAP_KEYS+KMAP_AKEYS ? &mmtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].mm;
6513
 
#endif
6514
 
  if ((!act || act->nr == RC_ILLEGAL) && !D_mapdefault)
6515
 
    act = i < KMAP_KEYS+KMAP_AKEYS ? &umtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].um;
6516
 
  if (!act || act->nr == RC_ILLEGAL)
6517
 
    act = i < KMAP_KEYS+KMAP_AKEYS ? &dmtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].dm;
6518
 
 
6519
 
  if (discard && (!act || act->nr != RC_COMMAND))
6520
 
    {
6521
 
      /* if the input was just a single byte we let it through */
6522
 
      if (D_tcs[keyno + T_CAPS].str && strlen(D_tcs[keyno + T_CAPS].str) == 1)
6523
 
        return -1;
6524
 
      if (D_ESCseen)
6525
 
        {
6526
 
          D_ESCseen = 0;
6527
 
          WindowChanged(fore, 'E');
6528
 
        }
6529
 
      return 0;
6530
 
    }
6531
 
  D_mapdefault = 0;
6532
 
 
6533
 
  if (act == 0 || act->nr == RC_ILLEGAL)
6534
 
    return -1;
6535
 
  DoAction(act, 0);
6536
 
  return 0;
6537
 
}
6538
 
#endif
6539
 
 
6540
 
 
6541
 
static int
6542
 
IsOnDisplay(wi)
6543
 
struct win *wi;
6544
 
{
6545
 
  struct canvas *cv;
6546
 
  ASSERT(display);
6547
 
  for (cv = D_cvlist; cv; cv = cv->c_next)
6548
 
    if (Layer2Window(cv->c_layer) == wi)
6549
 
      return 1;
6550
 
  return 0;
6551
 
}
6552
 
 
6553
 
struct win *
6554
 
FindNiceWindow(wi, presel)
6555
 
struct win *wi;
6556
 
char *presel;
6557
 
{
6558
 
  int i;
6559
 
 
6560
 
  debug2("FindNiceWindow %d %s\n", wi ? wi->w_number : -1 , presel ? presel : "NULL");
6561
 
  if (presel)
6562
 
    {
6563
 
      i = WindowByNoN(presel);
6564
 
      if (i >= 0)
6565
 
        wi = wtab[i];
6566
 
    }
6567
 
  if (!display)
6568
 
    return wi;
6569
 
#ifdef MULTIUSER
6570
 
  if (wi && AclCheckPermWin(D_user, ACL_READ, wi))
6571
 
    wi = 0;
6572
 
#endif
6573
 
  if (!wi || (IsOnDisplay(wi) && !presel))
6574
 
    {
6575
 
      /* try to get another window */
6576
 
      wi = 0;
6577
 
#ifdef MULTIUSER
6578
 
      for (wi = windows; wi; wi = wi->w_next)
6579
 
        if (!wi->w_layer.l_cvlist && !AclCheckPermWin(D_user, ACL_WRITE, wi))
6580
 
          break;
6581
 
      if (!wi)
6582
 
        for (wi = windows; wi; wi = wi->w_next)
6583
 
          if (wi->w_layer.l_cvlist && !IsOnDisplay(wi) && !AclCheckPermWin(D_user, ACL_WRITE, wi))
6584
 
            break;
6585
 
      if (!wi)
6586
 
        for (wi = windows; wi; wi = wi->w_next)
6587
 
          if (!wi->w_layer.l_cvlist && !AclCheckPermWin(D_user, ACL_READ, wi))
6588
 
            break;
6589
 
      if (!wi)
6590
 
        for (wi = windows; wi; wi = wi->w_next)
6591
 
          if (wi->w_layer.l_cvlist && !IsOnDisplay(wi) && !AclCheckPermWin(D_user, ACL_READ, wi))
6592
 
            break;
6593
 
#endif
6594
 
      if (!wi)
6595
 
        for (wi = windows; wi; wi = wi->w_next)
6596
 
          if (!wi->w_layer.l_cvlist)
6597
 
            break;
6598
 
      if (!wi)
6599
 
        for (wi = windows; wi; wi = wi->w_next)
6600
 
          if (wi->w_layer.l_cvlist && !IsOnDisplay(wi))
6601
 
            break;
6602
 
    }
6603
 
#ifdef MULTIUSER
6604
 
  if (wi && AclCheckPermWin(D_user, ACL_READ, wi))
6605
 
    wi = 0;
6606
 
#endif
6607
 
  return wi;
6608
 
}
6609
 
 
6610
 
#if 0
6611
 
 
6612
 
/* sorted list of all commands */
6613
 
static struct comm **commtab;
6614
 
static int ncommtab;
6615
 
 
6616
 
void
6617
 
AddComms(cos, hand)
6618
 
struct comm *cos;
6619
 
void (*hand) __P((struct comm *, char **, int));
6620
 
{
6621
 
  int n, i, j, r;
6622
 
  for (n = 0; cos[n].name; n++)
6623
 
    ;
6624
 
  if (n == 0)
6625
 
    return;
6626
 
  if (commtab)
6627
 
    commtab = (struct commt *)realloc(commtab, sizeof(*commtab) * (ncommtab + n));
6628
 
  else
6629
 
    commtab = (struct commt *)malloc(sizeof(*commtab) * (ncommtab + n));
6630
 
  if (!commtab)
6631
 
    Panic(0, strnomem);
6632
 
  for (i = 0; i < n; i++)
6633
 
    {
6634
 
      for (j = 0; j < ncommtab; j++)
6635
 
        {
6636
 
          r = strcmp(cos[i].name, commtab[j]->name);
6637
 
          if (r == 0)
6638
 
            Panic(0, "Duplicate command: %s\n", cos[i].name);
6639
 
          if (r < 0)
6640
 
            break;
6641
 
        }
6642
 
      for (r = ncommtab; r > j; r--)
6643
 
        commtab[r] = commtab[r - 1];
6644
 
      commtab[j] = cos + i;
6645
 
      cos[i].handler = hand;
6646
 
      bzero(cos[i].userbits, sizeof(cos[i].userbits));
6647
 
      ncommtab++;
6648
 
    }
6649
 
}
6650
 
 
6651
 
struct comm *
6652
 
FindComm(str)
6653
 
char *str;
6654
 
{
6655
 
  int x, m, l = 0, r = ncommtab - 1;
6656
 
  while (l <= r)
6657
 
    {
6658
 
      m = (l + r) / 2;
6659
 
      x = strcmp(str, commtab[m]->name);
6660
 
      if (x > 0)
6661
 
        l = m + 1;
6662
 
      else if (x < 0)
6663
 
        r = m - 1;
6664
 
      else
6665
 
        return commtab[m];
6666
 
    }
6667
 
  return 0;
6668
 
}
6669
 
 
6670
 
#endif
6671
 
 
6672
 
static int
6673
 
CalcSlicePercent(cv, percent)
6674
 
struct canvas *cv;
6675
 
int percent;
6676
 
{
6677
 
  int w, wsum, up;
6678
 
  if (!cv || !cv->c_slback)
6679
 
    return percent;
6680
 
  up = CalcSlicePercent(cv->c_slback->c_slback, percent);
6681
 
  w = cv->c_slweight;
6682
 
  for (cv = cv->c_slback->c_slperp, wsum = 0; cv; cv = cv->c_slnext)
6683
 
    wsum += cv->c_slweight;
6684
 
  if (wsum == 0)
6685
 
    return 0;
6686
 
  return (up * w) / wsum;
6687
 
}
6688
 
 
6689
 
static int
6690
 
ChangeCanvasSize(fcv, abs, diff, gflag, percent)
6691
 
struct canvas *fcv;     /* make this canvas bigger */
6692
 
int abs;                /* mode: 0:rel 1:abs 2:max */
6693
 
int diff;               /* change this much */
6694
 
int gflag;              /* go up if neccessary */
6695
 
int percent;
6696
 
{
6697
 
  struct canvas *cv;
6698
 
  int done, have, m, dir;
6699
 
 
6700
 
  debug3("ChangeCanvasSize abs %d diff %d percent=%d\n", abs, diff, percent);
6701
 
  if (abs == 0 && diff == 0)
6702
 
    return 0;
6703
 
  if (abs == 2)
6704
 
    {
6705
 
      if (diff == 0)
6706
 
          fcv->c_slweight = 0;
6707
 
      else
6708
 
        {
6709
 
          for (cv = fcv->c_slback->c_slperp; cv; cv = cv->c_slnext)
6710
 
            cv->c_slweight = 0;
6711
 
          fcv->c_slweight = 1;
6712
 
          cv = fcv->c_slback->c_slback;
6713
 
          if (gflag && cv && cv->c_slback)
6714
 
            ChangeCanvasSize(cv, abs, diff, gflag, percent);
6715
 
        }
6716
 
      return diff;
6717
 
    }
6718
 
  if (abs)
6719
 
    {
6720
 
      if (diff < 0)
6721
 
        diff = 0;
6722
 
      if (percent && diff > percent)
6723
 
        diff = percent;
6724
 
    }
6725
 
  if (percent)
6726
 
    {
6727
 
      int wsum, up;
6728
 
      for (cv = fcv->c_slback->c_slperp, wsum = 0; cv; cv = cv->c_slnext)
6729
 
        wsum += cv->c_slweight;
6730
 
      if (wsum)
6731
 
        {
6732
 
          up = gflag ? CalcSlicePercent(fcv->c_slback->c_slback, percent) : percent;
6733
 
          debug3("up=%d, wsum=%d percent=%d\n", up, wsum, percent);
6734
 
          if (wsum < 1000)
6735
 
            {
6736
 
              int scale = wsum < 10 ? 1000 : 100;
6737
 
              for (cv = fcv->c_slback->c_slperp; cv; cv = cv->c_slnext)
6738
 
                cv->c_slweight *= scale;
6739
 
              wsum *= scale;
6740
 
              debug1("scaled wsum to %d\n", wsum);
6741
 
            }
6742
 
          for (cv = fcv->c_slback->c_slperp; cv; cv = cv->c_slnext)
6743
 
            {
6744
 
              if (cv->c_slweight)
6745
 
                {
6746
 
                  cv->c_slweight = (cv->c_slweight * up) / percent;
6747
 
                  if (cv->c_slweight == 0)
6748
 
                    cv->c_slweight = 1;
6749
 
                }
6750
 
              debug1("  - weight %d\n", cv->c_slweight);
6751
 
            }
6752
 
          diff = (diff * wsum) / percent;
6753
 
          percent = wsum;
6754
 
        }
6755
 
    }
6756
 
  else
6757
 
    {
6758
 
      if (abs && diff == (fcv->c_slorient == SLICE_VERT ? fcv->c_ye - fcv->c_ys + 2 : fcv->c_xe - fcv->c_xs + 2))
6759
 
        return 0;
6760
 
      /* fix weights to real size (can't be helped, sorry) */
6761
 
      for (cv = fcv->c_slback->c_slperp; cv; cv = cv->c_slnext)
6762
 
        {
6763
 
          cv->c_slweight = cv->c_slorient == SLICE_VERT ? cv->c_ye - cv->c_ys + 2 : cv->c_xe - cv->c_xs + 2;
6764
 
          debug1("  - weight %d\n", cv->c_slweight);
6765
 
        }
6766
 
    }
6767
 
  if (abs)
6768
 
    diff = diff - fcv->c_slweight;
6769
 
  debug1("diff = %d\n", diff);
6770
 
  if (diff == 0)
6771
 
    return 0;
6772
 
  if (diff < 0)
6773
 
    {
6774
 
      cv = fcv->c_slnext ? fcv->c_slnext : fcv->c_slprev;
6775
 
      fcv->c_slweight += diff;
6776
 
      cv->c_slweight -= diff;
6777
 
      return diff;
6778
 
    }
6779
 
  done = 0;
6780
 
  dir = 1;
6781
 
  for (cv = fcv->c_slnext; diff > 0; cv = dir > 0 ? cv->c_slnext : cv->c_slprev)
6782
 
    {
6783
 
      if (!cv)
6784
 
        {
6785
 
          debug1("reached end, dir is %d\n", dir);
6786
 
          if (dir == -1)
6787
 
            break;
6788
 
          dir = -1;
6789
 
          cv = fcv;
6790
 
          continue;
6791
 
        }
6792
 
      if (percent)
6793
 
        m = 1;
6794
 
      else
6795
 
        m = cv->c_slperp ? CountCanvasPerp(cv) * 2 : 2;
6796
 
      debug2("min is %d, have %d\n", m, cv->c_slweight);
6797
 
      if (cv->c_slweight > m)
6798
 
        {
6799
 
          have = cv->c_slweight - m;
6800
 
          if (have > diff)
6801
 
            have = diff;
6802
 
          debug1("subtract %d\n", have);
6803
 
          cv->c_slweight -= have;
6804
 
          done += have;
6805
 
          diff -= have;
6806
 
        }
6807
 
    }
6808
 
  if (diff && gflag)
6809
 
    {
6810
 
      /* need more room! */
6811
 
      cv = fcv->c_slback->c_slback;
6812
 
      if (cv && cv->c_slback)
6813
 
        done += ChangeCanvasSize(fcv->c_slback->c_slback, 0, diff, gflag, percent);
6814
 
    }
6815
 
  fcv->c_slweight += done;
6816
 
  debug1("ChangeCanvasSize returns %d\n", done);
6817
 
  return done;
6818
 
}
6819
 
 
6820
 
static void
6821
 
ResizeRegions(arg, flags)
6822
 
char *arg;
6823
 
int flags;
6824
 
{
6825
 
  struct canvas *cv;
6826
 
  int diff, l;
6827
 
  int gflag = 0, abs = 0, percent = 0;
6828
 
  int orient = 0;
6829
 
 
6830
 
  ASSERT(display);
6831
 
  if (!*arg)
6832
 
    return;
6833
 
  if (D_forecv->c_slorient == SLICE_UNKN)
6834
 
    {
6835
 
      Msg(0, "resize: need more than one region");
6836
 
      return;
6837
 
    }
6838
 
  gflag = flags & RESIZE_FLAG_L ? 0 : 1;
6839
 
  orient |= flags & RESIZE_FLAG_H ? SLICE_HORI : 0;
6840
 
  orient |= flags & RESIZE_FLAG_V ? SLICE_VERT : 0;
6841
 
  if (orient == 0)
6842
 
    orient = D_forecv->c_slorient;
6843
 
  l = strlen(arg);
6844
 
  if (*arg == '=')
6845
 
    {
6846
 
      /* make all regions the same height */
6847
 
      struct canvas *cv = gflag ? &D_canvas : D_forecv->c_slback;
6848
 
      if (cv->c_slperp->c_slorient & orient)
6849
 
        EqualizeCanvas(cv->c_slperp, gflag);
6850
 
      /* can't use cv->c_slorient directly as it can be D_canvas */
6851
 
      if ((cv->c_slperp->c_slorient ^ (SLICE_HORI ^ SLICE_VERT)) & orient)
6852
 
        {
6853
 
          if (cv->c_slback)
6854
 
            {
6855
 
              cv = cv->c_slback;
6856
 
              EqualizeCanvas(cv->c_slperp, gflag);
6857
 
            }
6858
 
          else
6859
 
           EqualizeCanvas(cv, gflag);
6860
 
        }
6861
 
      ResizeCanvas(cv);
6862
 
      RecreateCanvasChain();
6863
 
      RethinkDisplayViewports();
6864
 
      ResizeLayersToCanvases();
6865
 
      return;
6866
 
    }
6867
 
  if (!strcmp(arg, "min") || !strcmp(arg, "0"))
6868
 
    {
6869
 
      abs = 2;
6870
 
      diff = 0;
6871
 
    }
6872
 
  else if (!strcmp(arg, "max") || !strcmp(arg, "_"))
6873
 
    {
6874
 
      abs = 2;
6875
 
      diff = 1;
6876
 
    }
6877
 
  else
6878
 
    {
6879
 
      if (l > 0 && arg[l - 1] == '%')
6880
 
        percent = 1000;
6881
 
      if (*arg == '+')
6882
 
        diff = atoi(arg + 1);
6883
 
      else if (*arg == '-')
6884
 
        diff = -atoi(arg + 1);
6885
 
      else
6886
 
        {
6887
 
          diff = atoi(arg);             /* +1 because of caption line */
6888
 
          if (diff < 0)
6889
 
            diff = 0;
6890
 
          abs = diff == 0 ? 2 : 1;
6891
 
        }
6892
 
    }
6893
 
  if (!abs && !diff)
6894
 
    return;
6895
 
  if (percent)
6896
 
    diff = diff * percent / 100;
6897
 
  cv = D_forecv;
6898
 
  if (cv->c_slorient & orient)
6899
 
    ChangeCanvasSize(cv, abs, diff, gflag, percent);
6900
 
  if (cv->c_slback->c_slorient & orient)
6901
 
    ChangeCanvasSize(cv->c_slback, abs, diff, gflag, percent);
6902
 
 
6903
 
  ResizeCanvas(&D_canvas);
6904
 
  RecreateCanvasChain();
6905
 
  RethinkDisplayViewports();
6906
 
  ResizeLayersToCanvases();
6907
 
  return;
6908
 
 
6909
 
#if 0
6910
 
 
6911
 
  if (siz + diff < 1)
6912
 
    diff = 1 - siz;
6913
 
  if (siz + diff > dsize - (nreg - 1) * 2 - 1)
6914
 
    diff = dsize - (nreg - 1) * 2 - 1 - siz;
6915
 
  if (diff == 0 || siz + diff < 1)
6916
 
    return;
6917
 
 
6918
 
  if (diff < 0)
6919
 
    {
6920
 
      if (D_forecv->c_next)
6921
 
        {
6922
 
          D_forecv->c_ye += diff;
6923
 
          D_forecv->c_next->c_ys += diff;
6924
 
          D_forecv->c_next->c_yoff += diff;
6925
 
        }
6926
 
      else
6927
 
        {
6928
 
          for (cv = D_cvlist; cv; cv = cv->c_next)
6929
 
            if (cv->c_next == D_forecv)
6930
 
              break;
6931
 
          ASSERT(cv);
6932
 
          cv->c_ye -= diff;
6933
 
          D_forecv->c_ys -= diff;
6934
 
          D_forecv->c_yoff -= diff;
6935
 
        }
6936
 
    }
6937
 
  else
6938
 
    {
6939
 
      int s, i = 0, found = 0, di = diff, d2;
6940
 
      s = dsize - (nreg - 1) * 2 - 1 - siz;
6941
 
      for (cv = D_cvlist; cv; i = cv->c_ye + 2, cv = cv->c_next)
6942
 
        {
6943
 
          if (cv == D_forecv)
6944
 
            {
6945
 
              cv->c_ye = i + (cv->c_ye - cv->c_ys) + diff;
6946
 
              cv->c_yoff -= cv->c_ys - i;
6947
 
              cv->c_ys = i;
6948
 
              found = 1;
6949
 
              continue;
6950
 
            }
6951
 
          s -= cv->c_ye - cv->c_ys;
6952
 
          if (!found)
6953
 
            {
6954
 
              if (s >= di)
6955
 
                continue;
6956
 
              d2 = di - s;
6957
 
            }
6958
 
          else
6959
 
            d2 = di > cv->c_ye - cv->c_ys ? cv->c_ye - cv->c_ys : di;
6960
 
          di -= d2;
6961
 
          cv->c_ye = i + (cv->c_ye - cv->c_ys) - d2;
6962
 
          cv->c_yoff -= cv->c_ys - i;
6963
 
          cv->c_ys = i;
6964
 
        }
6965
 
    }
6966
 
  RethinkDisplayViewports();
6967
 
  ResizeLayersToCanvases();
6968
 
#endif
6969
 
}
6970
 
 
6971
 
static void
6972
 
ResizeFin(buf, len, data)
6973
 
char *buf;
6974
 
int len;
6975
 
char *data;
6976
 
{
6977
 
  int ch;
6978
 
  int flags = *(int *)data;
6979
 
  ch = ((unsigned char *)buf)[len];
6980
 
  if (ch == 0)
6981
 
    {
6982
 
      ResizeRegions(buf, flags);
6983
 
      return;
6984
 
    }
6985
 
  if (ch == 'h')
6986
 
    flags ^= RESIZE_FLAG_H;
6987
 
  else if (ch == 'v')
6988
 
    flags ^= RESIZE_FLAG_V;
6989
 
  else if (ch == 'b')
6990
 
    flags |= RESIZE_FLAG_H|RESIZE_FLAG_V;
6991
 
  else if (ch == 'p')
6992
 
    flags ^= D_forecv->c_slorient == SLICE_VERT ? RESIZE_FLAG_H : RESIZE_FLAG_V;
6993
 
  else if (ch == 'l')
6994
 
    flags ^= RESIZE_FLAG_L;
6995
 
  else
6996
 
    return;
6997
 
  inp_setprompt(resizeprompts[flags], NULL);
6998
 
  *(int *)data = flags;
6999
 
  buf[len] = '\034';
7000
 
}
7001
 
 
7002
 
void
7003
 
SetForeCanvas(d, cv)
7004
 
struct display *d;
7005
 
struct canvas *cv;
7006
 
{
7007
 
  struct display *odisplay = display;
7008
 
  if (d->d_forecv == cv)
7009
 
    return;
7010
 
 
7011
 
  display = d;
7012
 
  D_forecv = cv;
7013
 
  if ((focusminwidth && (focusminwidth < 0 || D_forecv->c_xe - D_forecv->c_xs + 1 < focusminwidth)) ||
7014
 
      (focusminheight && (focusminheight < 0 || D_forecv->c_ye - D_forecv->c_ys + 1 < focusminheight)))
7015
 
    {
7016
 
      ResizeCanvas(&D_canvas);
7017
 
      RecreateCanvasChain();
7018
 
      RethinkDisplayViewports();
7019
 
      ResizeLayersToCanvases(); /* redisplays */
7020
 
    }
7021
 
  fore = D_fore = Layer2Window(D_forecv->c_layer);
7022
 
  if (D_other == fore)
7023
 
    D_other = 0;
7024
 
  flayer = D_forecv->c_layer;
7025
 
#ifdef RXVT_OSC
7026
 
  if (D_xtermosc[2] || D_xtermosc[3])
7027
 
    {
7028
 
      Activate(-1);
7029
 
    }
7030
 
  else
7031
 
#endif
7032
 
    {
7033
 
      RefreshHStatus();
7034
 
#ifdef RXVT_OSC
7035
 
      RefreshXtermOSC();
7036
 
#endif
7037
 
      flayer = D_forecv->c_layer;
7038
 
      CV_CALL(D_forecv, LayRestore();LaySetCursor());
7039
 
      WindowChanged(0, 'F');
7040
 
    }
7041
 
 
7042
 
  display = odisplay;
7043
 
}
7044
 
 
7045
 
#ifdef RXVT_OSC
7046
 
void
7047
 
RefreshXtermOSC()
7048
 
{
7049
 
  int i;
7050
 
  struct win *p;
7051
 
 
7052
 
  p = Layer2Window(D_forecv->c_layer);
7053
 
  for (i = 3; i >=0; i--)
7054
 
    SetXtermOSC(i, p ? p->w_xtermosc[i] : 0);
7055
 
}
7056
 
#endif
7057
 
 
7058
 
int
7059
 
ParseAttrColor(s1, s2, msgok)
7060
 
char *s1, *s2;
7061
 
int msgok;
7062
 
{
7063
 
  int i, n;
7064
 
  char *s, *ss;
7065
 
  int r = 0;
7066
 
 
7067
 
  s = s1;
7068
 
  while (*s == ' ')
7069
 
    s++;
7070
 
  ss = s;
7071
 
  while (*ss && *ss != ' ')
7072
 
    ss++;
7073
 
  while (*ss == ' ')
7074
 
    ss++;
7075
 
  if (*s && (s2 || *ss || !((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || *s == '.')))
7076
 
    {
7077
 
      int mode = 0, n = 0;
7078
 
      if (*s == '+')
7079
 
        {
7080
 
          mode = 1;
7081
 
          s++;
7082
 
        }
7083
 
      else if (*s == '-')
7084
 
        {
7085
 
          mode = -1;
7086
 
          s++;
7087
 
        }
7088
 
      else if (*s == '!')
7089
 
        {
7090
 
          mode = 2;
7091
 
          s++;
7092
 
        }
7093
 
      else if (*s == '=')
7094
 
        s++;
7095
 
      if (*s >= '0' && *s <= '9')
7096
 
        {
7097
 
          n = *s++ - '0';
7098
 
          if (*s >= '0' && *s <= '9')
7099
 
            n = n * 16 + (*s++ - '0');
7100
 
          else if (*s >= 'a' && *s <= 'f')
7101
 
            n = n * 16 + (*s++ - ('a' - 10));
7102
 
          else if (*s >= 'A' && *s <= 'F')
7103
 
            n = n * 16 + (*s++ - ('A' - 10));
7104
 
          else if (*s && *s != ' ')
7105
 
            {
7106
 
              if (msgok)
7107
 
                Msg(0, "Illegal attribute hexchar '%c'", *s);
7108
 
              return -1;
7109
 
            }
7110
 
        }
7111
 
      else
7112
 
        {
7113
 
          while (*s && *s != ' ')
7114
 
            {
7115
 
              if (*s == 'd')
7116
 
                n |= A_DI;
7117
 
              else if (*s == 'u')
7118
 
                n |= A_US;
7119
 
              else if (*s == 'b')
7120
 
                n |= A_BD;
7121
 
              else if (*s == 'r')
7122
 
                n |= A_RV;
7123
 
              else if (*s == 's')
7124
 
                n |= A_SO;
7125
 
              else if (*s == 'B')
7126
 
                n |= A_BL;
7127
 
              else
7128
 
                {
7129
 
                  if (msgok)
7130
 
                    Msg(0, "Illegal attribute specifier '%c'", *s);
7131
 
                  return -1;
7132
 
                }
7133
 
              s++;
7134
 
            }
7135
 
        }
7136
 
      if (*s && *s != ' ')
7137
 
        {
7138
 
          if (msgok)
7139
 
            Msg(0, "junk after attribute description: '%c'", *s);
7140
 
          return -1;
7141
 
        }
7142
 
      if (mode == -1)
7143
 
        r = n << 8 | n;
7144
 
      else if (mode == 1)
7145
 
        r = n << 8;
7146
 
      else if (mode == 2)
7147
 
        r = n;
7148
 
      else if (mode == 0)
7149
 
        r = 0xffff ^ n;
7150
 
    }
7151
 
  while (*s && *s == ' ')
7152
 
    s++;
7153
 
 
7154
 
  if (s2)
7155
 
    {
7156
 
      if (*s)
7157
 
        {
7158
 
          if (msgok)
7159
 
            Msg(0, "junk after description: '%c'", *s);
7160
 
          return -1;
7161
 
        }
7162
 
      s = s2;
7163
 
      while (*s && *s == ' ')
7164
 
        s++;
7165
 
    }
7166
 
 
7167
 
#ifdef COLOR
7168
 
  if (*s)
7169
 
    {
7170
 
      static char costr[] = "krgybmcw d    i.01234567 9     f               FKRGYBMCW      I ";
7171
 
      int numco = 0, j;
7172
 
 
7173
 
      n = 0;
7174
 
      if (*s == '.')
7175
 
        {
7176
 
          numco++;
7177
 
          n = 0x0f;
7178
 
          s++;
7179
 
        }
7180
 
      for (j = 0; j < 2 && *s && *s != ' '; j++)
7181
 
        {
7182
 
          for (i = 0; costr[i]; i++)
7183
 
            if (*s == costr[i])
7184
 
              break;
7185
 
          if (!costr[i])
7186
 
            {
7187
 
              if (msgok)
7188
 
                Msg(0, "illegal color descriptor: '%c'", *s);
7189
 
              return -1;
7190
 
            }
7191
 
          numco++;
7192
 
          n = n << 4 | (i & 15);
7193
 
#ifdef COLORS16
7194
 
          if (i >= 48)
7195
 
            n = (n & 0x20ff) | 0x200;
7196
 
#endif
7197
 
          s++;
7198
 
        }
7199
 
      if ((n & 0xf00) == 0xf00)
7200
 
        n ^= 0xf00;     /* clear superflous bits */
7201
 
#ifdef COLORS16
7202
 
      if (n & 0x2000)
7203
 
        n ^= 0x2400;    /* shift bit into right position */
7204
 
#endif
7205
 
      if (numco == 1)
7206
 
        n |= 0xf0;      /* don't change bg color */
7207
 
      if (numco != 2 && n != 0xff)
7208
 
        n |= 0x100;     /* special invert mode */
7209
 
      if (*s && *s != ' ')
7210
 
        {
7211
 
          if (msgok)
7212
 
            Msg(0, "junk after color description: '%c'", *s);
7213
 
          return -1;
7214
 
        }
7215
 
      n ^= 0xff;
7216
 
      r |= n << 16;
7217
 
    }
7218
 
#endif
7219
 
 
7220
 
  while (*s && *s == ' ')
7221
 
    s++;
7222
 
  if (*s)
7223
 
    {
7224
 
      if (msgok)
7225
 
        Msg(0, "junk after description: '%c'", *s);
7226
 
      return -1;
7227
 
    }
7228
 
  debug1("ParseAttrColor %06x\n", r);
7229
 
  return r;
7230
 
}
7231
 
 
7232
 
/*
7233
 
 *  Color coding:
7234
 
 *    0-7 normal colors
7235
 
 *    9   default color
7236
 
 *    e   just set intensity
7237
 
 *    f   don't change anything
7238
 
 *  Intensity is encoded into bits 17(fg) and 18(bg).
7239
 
 */
7240
 
void
7241
 
ApplyAttrColor(i, mc)
7242
 
int i;
7243
 
struct mchar *mc;
7244
 
{
7245
 
  debug1("ApplyAttrColor %06x\n", i);
7246
 
  mc->attr |= i >> 8 & 255;
7247
 
  mc->attr ^= i & 255;
7248
 
#ifdef COLOR
7249
 
  i = (i >> 16) ^ 0xff;
7250
 
  if ((i & 0x100) != 0)
7251
 
    {
7252
 
      i &= 0xeff;
7253
 
      if (mc->attr & (A_SO|A_RV))
7254
 
# ifdef COLORS16
7255
 
        i = ((i & 0x0f) << 4) | ((i & 0xf0) >> 4) | ((i & 0x200) << 1) | ((i & 0x400) >> 1);
7256
 
# else
7257
 
        i = ((i & 0x0f) << 4) | ((i & 0xf0) >> 4);
7258
 
# endif
7259
 
    }
7260
 
# ifdef COLORS16
7261
 
  if ((i & 0x0f) != 0x0f)
7262
 
    mc->attr = (mc->attr & 0xbf) | ((i >> 3) & 0x40);
7263
 
  if ((i & 0xf0) != 0xf0)
7264
 
    mc->attr = (mc->attr & 0x7f) | ((i >> 3) & 0x80);
7265
 
# endif
7266
 
  mc->color = 0x99 ^ mc->color;
7267
 
  if ((i & 0x0e) == 0x0e)
7268
 
    i = (i & 0xf0) | (mc->color & 0x0f);
7269
 
  if ((i & 0xe0) == 0xe0)
7270
 
    i = (i & 0x0f) | (mc->color & 0xf0);
7271
 
  mc->color = 0x99 ^ i;
7272
 
  debug2("ApplyAttrColor - %02x %02x\n", mc->attr, i);
7273
 
#endif
7274
 
}