summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjnweiger <jnweiger>2005-12-16 14:32:16 +0000
committerjnweiger <jnweiger>2005-12-16 14:32:16 +0000
commit64434f463765093be5bc53f313848a897ef49c66 (patch)
tree9c331dcb26a0bf5021384eca945d6d631a141d33 /src
parent8f0dedbec36c89c4b9ac9abcedb3180757fddbd7 (diff)
downloadscreen-64434f463765093be5bc53f313848a897ef49c66.tar.gz
oops, still there?
Diffstat (limited to 'src')
-rw-r--r--src/Makefile3
-rw-r--r--src/README102
-rw-r--r--src/ansi.c3061
-rw-r--r--src/screen.c3176
-rw-r--r--src/screen.h295
5 files changed, 0 insertions, 6637 deletions
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 06b972a..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-install all Makefiles and config:
- rm -f config.cache
- sh ./configure
diff --git a/src/README b/src/README
deleted file mode 100644
index 217573e..0000000
--- a/src/README
+++ /dev/null
@@ -1,102 +0,0 @@
-
- [If you just got the screen package, it pays to read the file INSTALL]
- [This intro only describes the most common features to get you started]
- [A full description of all features is contained in the source package]
-
-
-
-Short introduction to screen (Version 3.6.0) lvirden 8-8-93
-
-Send bugreports, fixes, enhancements, t-shirts, money, beer & pizza to
- screen@uni-erlangen.de
-
-Screen provides you with an ANSI/vt100 terminal emulator, which can multiplex
-up to 10 pseudo-terminals. On startup, it executes $SHELL in window 0.
-Then it reads $HOME/.screenrc to learn configuration, keybindings, and
-possibly open more windows.
-
- C-a ? (help) Show all keybindings.
-
- C-a c (screen) Create new windows.
-
- C-a SPACE (next) Advance to next window (with wraparound).
-
- C-a C-a (other) Toggle between the current and previously
- displayed windows.
-
- C-a 0 (select n) Switch to window n=0 ... 9.
- ...
- C-a 9
-
- C-a w (windows) Show a list of window names in the status line.
-
- C-a a (meta) Send a literal C-a/C-s/C-q to the
- C-a s (xoff) process in the window.
- C-a q (xon) For instance, emacs uses C-a and C-s.
-
- C-a l (redisplay) Redraw this window.
-
- C-a W (width) Toggle between 80 & 132 columns mode.
-
- C-a L (login) Try to toggle the window's utmp-slot.
-
- C-a z (suspend) Suspend the whole screen session.
-
- C-a x (lockscreen) Execute /usr/bin/lock, $LOCKCMD or a
- built-in terminal lock.
-
- C-a H (log) Log stdout of window n to screenlog.n.
-
- C-a C-[ (copy) Start copy mode. Move cursor with h,j,k,l.
- Set 2 marks with SPACE or y. Abort with ESC.
- (C-[ is ESC.) Preceeding second mark with
- an a appends the text to the copy buffer.
-
- C-a C-] (paste) Output copy buffer to current window's stdin.
-
- C-a < (readbuf) Read the copy buffer from /tmp/screen-exchange.
- C-a > (writebuf) Write the copy buffer to /tmp/screen-exchange.
-
- C-a d (detach) Detach screen. All processes continue and may
- spool output to their pty's, but screen
- disconnects from your terminal.
-
- C-a D D (pow_detach) Power detach. Disconnect like C-a d but also
- kill the parent shell.
-
- C-a K (kill) Kill a window and send SIGHUP to its process
- group. Per default this would be C-a C-k,
- but it is redefined in the demo .screenrc
- (think of killing a whole line in emacs).
-
- C-a : (colon) Online configuration change.
-
-See the man page or TeXinfo manual for many more keybindings and commands.
-
-screen -r [pid.tty.host|tty.host]
- Reattach to a specific detached session. The terminal emulator
- reconfigures according to your $TERMCAP or $TERM settings.
- When you have multiple screens detached, you must supply the session
- name.
-
-screen -R reattaches to a detached session or (if none) creates a new
- session.
-
-screen -d [pid.tty.host|tty.host]
- Detach a screen session remotely. Has the same effect as typing 'C-a d'
- on the controlling terminal. 'screen -D' will power-detach.
-
-screen -list
-screen -ls
-screen -wipe
- Show all available sessions and their status. Use -wipe to remove
- DEAD sessions.
-
- If sockets are missing, you may send a SIGCHLD to its 'SCREEN'
- process and the process will re-establish the socket (think of
- someone cleaning /tmp thoroughly).
-
-screen -h 200
- Starts a new screen session and sets the number of lines in the scrollback
- buffer to 200. The default is 100 lines.
-
diff --git a/src/ansi.c b/src/ansi.c
deleted file mode 100644
index 4f92e58..0000000
--- a/src/ansi.c
+++ /dev/null
@@ -1,3061 +0,0 @@
-/* Copyright (c) 1993-2002
- * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- * Copyright (c) 1987 Oliver Laumann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- ****************************************************************
- */
-
-#include <sys/types.h>
-#include <fcntl.h>
-#ifndef sun /* we want to know about TIOCPKT. */
-# include <sys/ioctl.h>
-#endif
-
-#include "config.h"
-#include "screen.h"
-#include "braille.h"
-#include "extern.h"
-#include "logfile.h"
-
-extern struct display *display, *displays;
-extern struct win *fore; /* for 83 escape */
-extern struct layer *flayer; /* for 83 escape */
-
-extern struct NewWindow nwin_default; /* for ResetWindow() */
-extern int nversion; /* numerical version of screen */
-extern int log_flush, logtstamp_on, logtstamp_after;
-extern char *logtstamp_string;
-extern char *captionstring;
-extern char *hstatusstring;
-extern char *wliststr;
-#ifdef COPY_PASTE
-extern int compacthist;
-#endif
-#ifdef MULTIUSER
-extern struct acluser *EffectiveAclUser;
-#endif
-
-int Z0width, Z1width; /* widths for Z0/Z1 switching */
-
-/* globals set in WriteString */
-static struct win *curr; /* window we are working on */
-static int rows, cols; /* window size of the curr window */
-
-int visual_bell = 0;
-int use_hardstatus = 1; /* display status line in hs */
-char *printcmd = 0;
-int use_altscreen = 0; /* enable alternate screen support? */
-
-unsigned char *blank; /* line filled with spaces */
-unsigned char *null; /* line filled with '\0' */
-
-struct mline mline_old;
-struct mline mline_blank;
-struct mline mline_null;
-
-struct mchar mchar_null;
-struct mchar mchar_blank = {' ' /* , 0, 0, ... */};
-struct mchar mchar_so = {' ', A_SO /* , 0, 0, ... */};
-
-/* keep string_t and string_t_string in sync! */
-static char *string_t_string[] =
-{
- "NONE",
- "DCS", /* Device control string */
- "OSC", /* Operating system command */
- "APC", /* Application program command */
- /* - used for status change */
- "PM", /* Privacy message */
- "AKA", /* title for current screen */
- "GM", /* Global message to every display */
- "STATUS" /* User hardstatus line */
-};
-
-/* keep state_t and state_t_string in sync! */
-static char *state_t_string[] =
-{
- "LIT", /* Literal input */
- "ESC", /* Start of escape sequence */
- "ASTR", /* Start of control string */
- "STRESC", /* ESC seen in control string */
- "CSI", /* Reading arguments in "CSI Pn ;...*/
- "PRIN", /* Printer mode */
- "PRINESC", /* ESC seen in printer mode */
- "PRINCSI", /* CSI seen in printer mode */
- "PRIN4" /* CSI 4 seen in printer mode */
-};
-
-static int Special __P((int));
-static void DoESC __P((int, int));
-static void DoCSI __P((int, int));
-static void StringStart __P((enum string_t));
-static void StringChar __P((int));
-static int StringEnd __P((void));
-static void PrintStart __P((void));
-static void PrintChar __P((int));
-static void PrintFlush __P((void));
-#ifdef FONT
-static void DesignateCharset __P((int, int));
-static void MapCharset __P((int));
-static void MapCharsetR __P((int));
-#endif
-static void SaveCursor __P((void));
-static void RestoreCursor __P((void));
-static void BackSpace __P((void));
-static void Return __P((void));
-static void LineFeed __P((int));
-static void ReverseLineFeed __P((void));
-static void InsertChar __P((int));
-static void DeleteChar __P((int));
-static void DeleteLine __P((int));
-static void InsertLine __P((int));
-static void Scroll __P((char *, int, int, char *));
-static void ForwardTab __P((void));
-static void BackwardTab __P((void));
-static void ClearScreen __P((void));
-static void ClearFromBOS __P((void));
-static void ClearToEOS __P((void));
-static void ClearLineRegion __P((int, int));
-static void CursorRight __P((int));
-static void CursorUp __P((int));
-static void CursorDown __P((int));
-static void CursorLeft __P((int));
-static void ASetMode __P((int));
-static void SelectRendition __P((void));
-static void RestorePosRendition __P((void));
-static void FillWithEs __P((void));
-static void FindAKA __P((void));
-static void Report __P((char *, int, int));
-static void ScrollRegion __P((int));
-#ifdef COPY_PASTE
-static void WAddLineToHist __P((struct win *, struct mline *));
-#endif
-static void WLogString __P((struct win *, char *, int));
-static void WReverseVideo __P((struct win *, int));
-static int WindowChangedCheck __P((char *, int, int *));
-static void MFixLine __P((struct win *, int, struct mchar *));
-static void MScrollH __P((struct win *, int, int, int, int, int));
-static void MScrollV __P((struct win *, int, int, int, int));
-static void MClearArea __P((struct win *, int, int, int, int, int));
-static void MInsChar __P((struct win *, struct mchar *, int, int));
-static void MPutChar __P((struct win *, struct mchar *, int, int));
-static void MPutStr __P((struct win *, char *, int, struct mchar *, int, int));
-static void MWrapChar __P((struct win *, struct mchar *, int, int, int, int));
-#ifdef COLOR
-static void MBceLine __P((struct win *, int, int, int, int));
-#endif
-
-#ifdef COLOR
-# define CURR_BCE (curr->w_bce ? rend_getbg(&curr->w_rend) : 0)
-#else
-# define CURR_BCE 0
-#endif
-
-void
-ResetAnsiState(p)
-struct win *p;
-{
- p->w_state = LIT;
- p->w_StringType = NONE;
-}
-
-void
-ResetWindow(p)
-register struct win *p;
-{
- register int i;
-
- p->w_wrap = nwin_default.wrap;
- p->w_origin = 0;
- p->w_insert = 0;
- p->w_revvid = 0;
- p->w_mouse = 0;
- p->w_curinv = 0;
- p->w_curvvis = 0;
- p->w_autolf = 0;
- p->w_keypad = 0;
- p->w_cursorkeys = 0;
- p->w_top = 0;
- p->w_bot = p->w_height - 1;
- p->w_saved = 0;
- p->w_x = p->w_y = 0;
- p->w_state = LIT;
- p->w_StringType = NONE;
- bzero(p->w_tabs, p->w_width);
- for (i = 8; i < p->w_width; i += 8)
- p->w_tabs[i] = 1;
- p->w_rend = mchar_null;
-#ifdef FONT
- ResetCharsets(p);
-#endif
-#ifdef COLOR
- p->w_bce = nwin_default.bce;
-#endif
-}
-
-/* adds max 22 bytes */
-int
-GetAnsiStatus(w, buf)
-struct win *w;
-char *buf;
-{
- char *p = buf;
-
- if (w->w_state == LIT)
- return 0;
-
- strcpy(p, state_t_string[w->w_state]);
- p += strlen(p);
- if (w->w_intermediate)
- {
- *p++ = '-';
- if (w->w_intermediate > 0xff)
- p += AddXChar(p, w->w_intermediate >> 8);
- p += AddXChar(p, w->w_intermediate & 0xff);
- *p = 0;
- }
- if (w->w_state == ASTR || w->w_state == STRESC)
- sprintf(p, "-%s", string_t_string[w->w_StringType]);
- p += strlen(p);
- return p - buf;
-}
-
-
-#ifdef FONT
-
-void
-ResetCharsets(p)
-struct win *p;
-{
- p->w_gr = nwin_default.gr;
- p->w_c1 = nwin_default.c1;
- SetCharsets(p, "BBBB02");
- if (nwin_default.charset)
- SetCharsets(p, nwin_default.charset);
-#ifdef ENCODINGS
- ResetEncoding(p);
-#endif
-}
-
-void
-SetCharsets(p, s)
-struct win *p;
-char *s;
-{
- int i;
-
- for (i = 0; i < 4 && *s; i++, s++)
- if (*s != '.')
- p->w_charsets[i] = ((*s == 'B') ? ASCII : *s);
- if (*s && *s++ != '.')
- p->w_Charset = s[-1] - '0';
- if (*s && *s != '.')
- p->w_CharsetR = *s - '0';
- p->w_ss = 0;
- p->w_FontL = p->w_charsets[p->w_Charset];
- p->w_FontR = p->w_charsets[p->w_CharsetR];
-}
-#endif /* FONT */
-
-/*****************************************************************/
-
-
-/*
- * Here comes the vt100 emulator
- * - writes logfiles,
- * - sets timestamp and flags activity in window.
- * - record program output in window scrollback
- * - translate program output for the display and put it into the obuf.
- *
- */
-void
-WriteString(wp, buf, len)
-struct win *wp;
-register char *buf;
-register int len;
-{
- register int c;
-#ifdef FONT
- register int font;
-#endif
- struct canvas *cv;
-
- if (!len)
- return;
- if (wp->w_log)
- WLogString(wp, buf, len);
-
- /* set global variables (yuck!) */
- curr = wp;
- cols = curr->w_width;
- rows = curr->w_height;
-
- if (curr->w_silence)
- SetTimeout(&curr->w_silenceev, curr->w_silencewait * 1000);
-
- if (curr->w_monitor == MON_ON)
- {
- debug2("ACTIVITY %d %d\n", curr->w_monitor, curr->w_bell);
- curr->w_monitor = MON_FOUND;
- }
-
- do
- {
- c = (unsigned char)*buf++;
-#ifdef FONT
-# ifdef DW_CHARS
- if (!curr->w_mbcs)
-# endif
- curr->w_rend.font = curr->w_FontL; /* Default: GL */
-#endif
-
- /* The next part is only for speedup */
- if (curr->w_state == LIT &&
-#ifdef UTF8
- curr->w_encoding != UTF8 &&
-#endif
-#ifdef DW_CHARS
- !is_dw_font(curr->w_rend.font) &&
-# ifdef ENCODINGS
- curr->w_rend.font != KANA && !curr->w_mbcs &&
-# endif
-#endif
-#ifdef FONT
- curr->w_rend.font != '<' &&
-#endif
- c >= ' ' && c != 0x7f &&
- ((c & 0x80) == 0 || ((c >= 0xa0 || !curr->w_c1) && !curr->w_gr)) && !curr->w_ss &&
- !curr->w_insert && curr->w_x < cols - 1)
- {
- register int currx = curr->w_x;
- char *imp = buf - 1;
-
- while (currx < cols - 1)
- {
- currx++;
- if (--len == 0)
- break;
- c = (unsigned char)*buf++;
- if (c < ' ' || c == 0x7f || ((c & 0x80) && ((c < 0xa0 && curr->w_c1) || curr->w_gr)))
- break;
- }
- currx -= curr->w_x;
- if (currx > 0)
- {
- MPutStr(curr, imp, currx, &curr->w_rend, curr->w_x, curr->w_y);
- LPutStr(&curr->w_layer, imp, currx, &curr->w_rend, curr->w_x, curr->w_y);
- curr->w_x += currx;
- }
- if (len == 0)
- break;
- }
- /* end of speedup code */
-
-#ifdef UTF8
- if (curr->w_encoding == UTF8)
- {
- c = FromUtf8(c, &curr->w_decodestate);
- if (c == -1)
- continue;
- if (c == -2)
- {
- c = UCS_REPL;
- /* try char again */
- buf--;
- len++;
- }
- if (c > 0xff)
- debug1("read UNICODE %04x\n", c);
- }
-#endif
-
- tryagain:
- switch (curr->w_state)
- {
- case PRIN:
- switch (c)
- {
- case '\033':
- curr->w_state = PRINESC;
- break;
- default:
- PrintChar(c);
- }
- break;
- case PRINESC:
- switch (c)
- {
- case '[':
- curr->w_state = PRINCSI;
- break;
- default:
- PrintChar('\033');
- PrintChar(c);
- curr->w_state = PRIN;
- }
- break;
- case PRINCSI:
- switch (c)
- {
- case '4':
- curr->w_state = PRIN4;
- break;
- default:
- PrintChar('\033');
- PrintChar('[');
- PrintChar(c);
- curr->w_state = PRIN;
- }
- break;
- case PRIN4:
- switch (c)
- {
- case 'i':
- curr->w_state = LIT;
- PrintFlush();
- if (curr->w_pdisplay && curr->w_pdisplay->d_printfd >= 0)
- {
- close(curr->w_pdisplay->d_printfd);
- curr->w_pdisplay->d_printfd = -1;
- }
- curr->w_pdisplay = 0;
- break;
- default:
- PrintChar('\033');
- PrintChar('[');
- PrintChar('4');
- PrintChar(c);
- curr->w_state = PRIN;
- }
- break;
- case ASTR:
- if (c == 0)
- break;
- if (c == '\033')
- {
- curr->w_state = STRESC;
- break;
- }
- /* special xterm hack: accept SetStatus sequence. Yucc! */
- /* allow ^E for title escapes */
- if (!(curr->w_StringType == OSC && c < ' ' && c != '\005'))
- if (!curr->w_c1 || c != ('\\' ^ 0xc0))
- {
- StringChar(c);
- break;
- }
- c = '\\';
- /* FALLTHROUGH */
- case STRESC:
- switch (c)
- {
- case '\\':
- if (StringEnd() == 0 || len <= 1)
- break;
- /* check if somewhere a status is displayed */
- for (cv = curr->w_layer.l_cvlist; cv; cv = cv->c_lnext)
- {
- display = cv->c_display;
- if (D_status == STATUS_ON_WIN)
- break;
- }
- if (cv)
- {
- if (len > IOSIZE + 1)
- len = IOSIZE + 1;
- curr->w_outlen = len - 1;
- bcopy(buf, curr->w_outbuf, len - 1);
- return; /* wait till status is gone */
- }
- break;
- case '\033':
- StringChar('\033');
- break;
- default:
- curr->w_state = ASTR;
- StringChar('\033');
- StringChar(c);
- break;
- }
- break;
- case ESC:
- switch (c)
- {
- case '[':
- curr->w_NumArgs = 0;
- curr->w_intermediate = 0;
- bzero((char *) curr->w_args, MAXARGS * sizeof(int));
- curr->w_state = CSI;
- break;
- case ']':
- StringStart(OSC);
- break;
- case '_':
- StringStart(APC);
- break;
- case 'P':
- StringStart(DCS);
- break;
- case '^':
- StringStart(PM);
- break;
- case '!':
- StringStart(GM);
- break;
- case '"':
- case 'k':
- StringStart(AKA);
- break;
- default:
- if (Special(c))
- {
- curr->w_state = LIT;
- break;
- }
- debug1("not special. c = %x\n", c);
- if (c >= ' ' && c <= '/')
- {
- if (curr->w_intermediate)
- {
-#ifdef DW_CHARS
- if (curr->w_intermediate == '$')
- c |= '$' << 8;
- else
-#endif
- c = -1;
- }
- curr->w_intermediate = c;
- }
- else if (c >= '0' && c <= '~')
- {
- DoESC(c, curr->w_intermediate);
- curr->w_state = LIT;
- }
- else
- {
- curr->w_state = LIT;
- goto tryagain;
- }
- }
- break;
- case CSI:
- switch (c)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (curr->w_NumArgs < MAXARGS)
- {
- if (curr->w_args[curr->w_NumArgs] < 100000000)
- curr->w_args[curr->w_NumArgs] =
- 10 * curr->w_args[curr->w_NumArgs] + (c - '0');
- }
- break;
- case ';':
- case ':':
- if (curr->w_NumArgs < MAXARGS)
- curr->w_NumArgs++;
- break;
- default:
- if (Special(c))
- break;
- if (c >= '@' && c <= '~')
- {
- if (curr->w_NumArgs < MAXARGS)
- curr->w_NumArgs++;
- DoCSI(c, curr->w_intermediate);
- if (curr->w_state != PRIN)
- curr->w_state = LIT;
- }
- else if ((c >= ' ' && c <= '/') || (c >= '<' && c <= '?'))
- curr->w_intermediate = curr->w_intermediate ? -1 : c;
- else
- {
- curr->w_state = LIT;
- goto tryagain;
- }
- }
- break;
- case LIT:
- default:
-#ifdef DW_CHARS
- if (curr->w_mbcs)
- if (c <= ' ' || c == 0x7f || (c >= 0x80 && c < 0xa0 && curr->w_c1))
- curr->w_mbcs = 0;
-#endif
- if (c < ' ')
- {
- if (c == '\033')
- {
- curr->w_intermediate = 0;
- curr->w_state = ESC;
- if (curr->w_autoaka < 0)
- curr->w_autoaka = 0;
- }
- else
- Special(c);
- break;
- }
- if (c >= 0x80 && c < 0xa0 && curr->w_c1)
-#ifdef FONT
- if ((curr->w_FontR & 0xf0) != 0x20
-# ifdef UTF8
- || curr->w_encoding == UTF8
-# endif
- )
-#endif
- {
- switch (c)
- {
- case 0xc0 ^ 'D':
- case 0xc0 ^ 'E':
- case 0xc0 ^ 'H':
- case 0xc0 ^ 'M':
- case 0xc0 ^ 'N': /* SS2 */
- case 0xc0 ^ 'O': /* SS3 */
- DoESC(c ^ 0xc0, 0);
- break;
- case 0xc0 ^ '[':
- if (curr->w_autoaka < 0)
- curr->w_autoaka = 0;
- curr->w_NumArgs = 0;
- curr->w_intermediate = 0;
- bzero((char *) curr->w_args, MAXARGS * sizeof(int));
- curr->w_state = CSI;
- break;
- case 0xc0 ^ 'P':
- StringStart(DCS);
- break;
- default:
- break;
- }
- break;
- }
-
-#ifdef FONT
-# ifdef DW_CHARS
- if (!curr->w_mbcs)
- {
-# endif
- if (c < 0x80 || curr->w_gr == 0)
- curr->w_rend.font = curr->w_FontL;
-# ifdef ENCODINGS
- else if (curr->w_gr == 2 && !curr->w_ss)
- curr->w_rend.font = curr->w_FontE;
-# endif
- else
- curr->w_rend.font = curr->w_FontR;
-# ifdef DW_CHARS
- }
-# endif
-# ifdef UTF8
- if (curr->w_encoding == UTF8)
- {
- if (curr->w_rend.font == '0')
- {
- struct mchar mc, *mcp;
-
- debug1("SPECIAL %x\n", c);
- mc.image = c;
- mc.mbcs = 0;
- mc.font = '0';
- mcp = recode_mchar(&mc, 0, UTF8);
- debug2("%02x %02x\n", mcp->image, mcp->font);
- c = mcp->image | mcp->font << 8;
- }
- curr->w_rend.font = 0;
- }
-# ifdef DW_CHARS
- if (curr->w_encoding == UTF8 && c >= 0x1100 && utf8_isdouble(c))
- curr->w_mbcs = 0xff;
-# endif
- if (curr->w_encoding == UTF8 && c >= 0x0300 && utf8_iscomb(c))
- {
- int ox, oy;
- struct mchar omc;
-
- ox = curr->w_x - 1;
- oy = curr->w_y;
- if (ox < 0)
- {
- ox = curr->w_width - 1;
- oy--;
- }
- if (oy < 0)
- oy = 0;
- copy_mline2mchar(&omc, &curr->w_mlines[oy], ox);
- if (omc.image == 0xff && omc.font == 0xff)
- {
- ox--;
- if (ox >= 0)
- {
- copy_mline2mchar(&omc, &curr->w_mlines[oy], ox);
- omc.mbcs = 0xff;
- }
- }
- if (ox >= 0)
- {
- utf8_handle_comb(c, &omc);
- MFixLine(curr, oy, &omc);
- copy_mchar2mline(&omc, &curr->w_mlines[oy], ox);
- LPutChar(&curr->w_layer, &omc, ox, oy);
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- }
- break;
- }
- font = curr->w_rend.font;
-# endif
-# ifdef DW_CHARS
-# ifdef ENCODINGS
- if (font == KANA && curr->w_encoding == SJIS && curr->w_mbcs == 0)
- {
- /* Lets see if it is the first byte of a kanji */
- debug1("%x may be first of SJIS\n", c);
- if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))
- {
- debug("YES!\n");
- curr->w_mbcs = c;
- break;
- }
- }
-# endif
- if (font == 031 && c == 0x80 && !curr->w_mbcs)
- font = curr->w_rend.font = 0;
- if (is_dw_font(font) && c == ' ')
- font = curr->w_rend.font = 0;
- if (is_dw_font(font) || curr->w_mbcs)
- {
- int t = c;
- if (curr->w_mbcs == 0)
- {
- curr->w_mbcs = c;
- break;
- }
- if (curr->w_x == cols - 1)
- {
- curr->w_x += curr->w_wrap ? 1 : -1;
- debug1("Patched w_x to %d\n", curr->w_x);
- }
-# ifdef UTF8
- if (curr->w_encoding != UTF8)
-# endif
- {
- c = curr->w_mbcs;
-# ifdef ENCODINGS
- if (font == KANA && curr->w_encoding == SJIS)
- {
- debug2("SJIS !! %x %x\n", c, t);
- /*
- * SJIS -> EUC mapping:
- * First byte:
- * 81,82...9f -> 21,23...5d
- * e0,e1...ef -> 5f,61...7d
- * Second byte:
- * 40-7e -> 21-5f
- * 80-9e -> 60-7e
- * 9f-fc -> 21-7e (increment first byte!)
- */
- if (0x40 <= t && t <= 0xfc && t != 0x7f)
- {
- if (c <= 0x9f) c = (c - 0x81) * 2 + 0x21;
- else c = (c - 0xc1) * 2 + 0x21;
- if (t <= 0x7e) t -= 0x1f;
- else if (t <= 0x9e) t -= 0x20;
- else t -= 0x7e, c++;
- curr->w_rend.font = KANJI;
- }
- else
- {
- /* Incomplete shift-jis - skip first byte */
- c = t;
- t = 0;
- }
- debug2("SJIS after %x %x\n", c, t);
- }
-# endif
- if (t && curr->w_gr && font != 030 && font != 031)
- {
- t &= 0x7f;
- if (t < ' ')
- goto tryagain;
- }
- if (t == '\177')
- break;
- curr->w_mbcs = t;
- }
- }
-# endif /* DW_CHARS */
- if (font == '<' && c >= ' ')
- {
- font = curr->w_rend.font = 0;
- c |= 0x80;
- }
-# ifdef UTF8
- else if (curr->w_gr && curr->w_encoding != UTF8)
-# else
- else if (curr->w_gr)
-# endif
- {
-#ifdef ENCODINGS
- if (c == 0x80 && font == 0 && curr->w_encoding == GBK)
- c = 0xa4;
- else
- c &= 0x7f;
- if (c < ' ' && font != 031)
- goto tryagain;
-#else
- c &= 0x7f;
- if (c < ' ') /* this is ugly but kanji support */
- goto tryagain; /* prevents nicer programming */
-#endif
- }
-#endif /* FONT */
- if (c == '\177')
- break;
- curr->w_rend.image = c;
-#ifdef UTF8
- if (curr->w_encoding == UTF8)
- curr->w_rend.font = c >> 8;
-#endif
-#ifdef DW_CHARS
- curr->w_rend.mbcs = curr->w_mbcs;
-#endif
- if (curr->w_x < cols - 1)
- {
- if (curr->w_insert)
- {
- save_mline(&curr->w_mlines[curr->w_y], cols);
- MInsChar(curr, &curr->w_rend, curr->w_x, curr->w_y);
- LInsChar(&curr->w_layer, &curr->w_rend, curr->w_x, curr->w_y, &mline_old);
- curr->w_x++;
- }
- else
- {
- MPutChar(curr, &curr->w_rend, curr->w_x, curr->w_y);
- LPutChar(&curr->w_layer, &curr->w_rend, curr->w_x, curr->w_y);
- curr->w_x++;
- }
- }
- else if (curr->w_x == cols - 1)
- {
- MPutChar(curr, &curr->w_rend, curr->w_x, curr->w_y);
- LPutChar(&curr->w_layer, &curr->w_rend, curr->w_x, curr->w_y);
- if (curr->w_wrap)
- curr->w_x++;
- }
- else
- {
- MWrapChar(curr, &curr->w_rend, curr->w_y, curr->w_top, curr->w_bot, curr->w_insert);
- LWrapChar(&curr->w_layer, &curr->w_rend, curr->w_y, curr->w_top, curr->w_bot, curr->w_insert);
- if (curr->w_y != curr->w_bot && curr->w_y != curr->w_height - 1)
- curr->w_y++;
- curr->w_x = 1;
- }
-#ifdef FONT
-# ifdef DW_CHARS
- if (curr->w_mbcs)
- {
- curr->w_rend.mbcs = curr->w_mbcs = 0;
- curr->w_x++;
- }
-# endif
- if (curr->w_ss)
- {
- curr->w_FontL = curr->w_charsets[curr->w_Charset];
- curr->w_FontR = curr->w_charsets[curr->w_CharsetR];
- curr->w_rend.font = curr->w_FontL;
- LSetRendition(&curr->w_layer, &curr->w_rend);
- curr->w_ss = 0;
- }
-#endif /* FONT */
- break;
- }
- }
- while (--len);
- if (!printcmd && curr->w_state == PRIN)
- PrintFlush();
-}
-
-static void
-WLogString(p, buf, len)
-struct win *p;
-char *buf;
-int len;
-{
- if (!p->w_log)
- return;
- if (logtstamp_on && p->w_logsilence >= logtstamp_after * 2)
- {
- char *t = MakeWinMsg(logtstamp_string, p, '%');
- logfwrite(p->w_log, t, strlen(t)); /* long time no write */
- }
- p->w_logsilence = 0;
- if (logfwrite(p->w_log, buf, len) < 1)
- {
- WMsg(p, errno, "Error writing logfile");
- logfclose(p->w_log);
- p->w_log = 0;
- }
- if (!log_flush)
- logfflush(p->w_log);
-}
-
-static int
-Special(c)
-register int c;
-{
- switch (c)
- {
- case '\b':
- BackSpace();
- return 1;
- case '\r':
- Return();
- return 1;
- case '\n':
- if (curr->w_autoaka)
- FindAKA();
- LineFeed(0);
- return 1;
- case '\007':
- WBell(curr, visual_bell);
- return 1;
- case '\t':
- ForwardTab();
- return 1;
-#ifdef FONT
- case '\017': /* SI */
- MapCharset(G0);
- return 1;
- case '\016': /* SO */
- MapCharset(G1);
- return 1;
-#endif
- }
- return 0;
-}
-
-static void
-DoESC(c, intermediate)
-int c, intermediate;
-{
- debug2("DoESC: %x - inter = %x\n", c, intermediate);
- switch (intermediate)
- {
- case 0:
- switch (c)
- {
- case 'E':
- LineFeed(1);
- break;
- case 'D':
- LineFeed(0);
- break;
- case 'M':
- ReverseLineFeed();
- break;
- case 'H':
- curr->w_tabs[curr->w_x] = 1;
- break;
- case 'Z': /* jph: Identify as VT100 */
- Report("\033[?%d;%dc", 1, 2);
- break;
- case '7':
- SaveCursor();
- break;
- case '8':
- RestoreCursor();
- break;
- case 'c':
- ClearScreen();
- ResetWindow(curr);
- LKeypadMode(&curr->w_layer, 0);
- LCursorkeysMode(&curr->w_layer, 0);
-#ifndef TIOCPKT
- WNewAutoFlow(curr, 1);
-#endif
- /* XXX
- SetRendition(&mchar_null);
- InsertMode(0);
- ChangeScrollRegion(0, rows - 1);
- */
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- break;
- case '=':
- LKeypadMode(&curr->w_layer, curr->w_keypad = 1);
-#ifndef TIOCPKT
- WNewAutoFlow(curr, 0);
-#endif /* !TIOCPKT */
- break;
- case '>':
- LKeypadMode(&curr->w_layer, curr->w_keypad = 0);
-#ifndef TIOCPKT
- WNewAutoFlow(curr, 1);
-#endif /* !TIOCPKT */
- break;
-#ifdef FONT
- case 'n': /* LS2 */
- MapCharset(G2);
- break;
- case 'o': /* LS3 */
- MapCharset(G3);
- break;
- case '~':
- MapCharsetR(G1); /* LS1R */
- break;
- /* { */
- case '}':
- MapCharsetR(G2); /* LS2R */
- break;
- case '|':
- MapCharsetR(G3); /* LS3R */
- break;
- case 'N': /* SS2 */
- if (curr->w_charsets[curr->w_Charset] != curr->w_charsets[G2]
- || curr->w_charsets[curr->w_CharsetR] != curr->w_charsets[G2])
- curr->w_FontR = curr->w_FontL = curr->w_charsets[curr->w_ss = G2];
- else
- curr->w_ss = 0;
- break;
- case 'O': /* SS3 */
- if (curr->w_charsets[curr->w_Charset] != curr->w_charsets[G3]
- || curr->w_charsets[curr->w_CharsetR] != curr->w_charsets[G3])
- curr->w_FontR = curr->w_FontL = curr->w_charsets[curr->w_ss = G3];
- else
- curr->w_ss = 0;
- break;
-#endif /* FONT */
- case 'g': /* VBELL, private screen sequence */
- WBell(curr, 1);
- break;
- }
- break;
- case '#':
- switch (c)
- {
- case '8':
- FillWithEs();
- break;
- }
- break;
-#ifdef FONT
- case '(':
- DesignateCharset(c, G0);
- break;
- case ')':
- DesignateCharset(c, G1);
- break;
- case '*':
- DesignateCharset(c, G2);
- break;
- case '+':
- DesignateCharset(c, G3);
- break;
-# ifdef DW_CHARS
-/*
- * ESC $ ( Fn: invoke multi-byte charset, Fn, to G0
- * ESC $ Fn: same as above. (old sequence)
- * ESC $ ) Fn: invoke multi-byte charset, Fn, to G1
- * ESC $ * Fn: invoke multi-byte charset, Fn, to G2
- * ESC $ + Fn: invoke multi-byte charset, Fn, to G3
- */
- case '$':
- case '$'<<8 | '(':
- DesignateCharset(c & 037, G0);
- break;
- case '$'<<8 | ')':
- DesignateCharset(c & 037, G1);
- break;
- case '$'<<8 | '*':
- DesignateCharset(c & 037, G2);
- break;
- case '$'<<8 | '+':
- DesignateCharset(c & 037, G3);
- break;
-# endif
-#endif /* FONT */
- }
-}
-
-static void
-DoCSI(c, intermediate)
-int c, intermediate;
-{
- register int i, a1 = curr->w_args[0], a2 = curr->w_args[1];
-
- if (curr->w_NumArgs > MAXARGS)
- curr->w_NumArgs = MAXARGS;
- switch (intermediate)
- {
- case 0:
- switch (c)
- {
- case 'H':
- case 'f':
- if (a1 < 1)
- a1 = 1;
- if (curr->w_origin)
- a1 += curr->w_top;
- if (a1 > rows)
- a1 = rows;
- if (a2 < 1)
- a2 = 1;
- if (a2 > cols)
- a2 = cols;
- LGotoPos(&curr->w_layer, --a2, --a1);
- curr->w_x = a2;
- curr->w_y = a1;
- if (curr->w_autoaka)
- curr->w_autoaka = a1 + 1;
- break;
- case 'J':
- if (a1 < 0 || a1 > 2)
- a1 = 0;
- switch (a1)
- {
- case 0:
- ClearToEOS();
- break;
- case 1:
- ClearFromBOS();
- break;
- case 2:
- ClearScreen();
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- break;
- }
- break;
- case 'K':
- if (a1 < 0 || a1 > 2)
- a1 %= 3;
- switch (a1)
- {
- case 0:
- ClearLineRegion(curr->w_x, cols - 1);
- break;
- case 1:
- ClearLineRegion(0, curr->w_x);
- break;
- case 2:
- ClearLineRegion(0, cols - 1);
- break;
- }
- break;
- case 'X':
- a1 = curr->w_x + (a1 ? a1 - 1 : 0);
- ClearLineRegion(curr->w_x, a1 < cols ? a1 : cols - 1);
- break;
- case 'A':
- CursorUp(a1 ? a1 : 1);
- break;
- case 'B':
- CursorDown(a1 ? a1 : 1);
- break;
- case 'C':
- CursorRight(a1 ? a1 : 1);
- break;
- case 'D':
- CursorLeft(a1 ? a1 : 1);
- break;
- case 'E':
- curr->w_x = 0;
- CursorDown(a1 ? a1 : 1); /* positions cursor */
- break;
- case 'F':
- curr->w_x = 0;
- CursorUp(a1 ? a1 : 1); /* positions cursor */
- break;
- case 'G':
- case '`': /* HPA */
- curr->w_x = a1 ? a1 - 1 : 0;
- if (curr->w_x >= cols)
- curr->w_x = cols - 1;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- break;
- case 'd': /* VPA */
- curr->w_y = a1 ? a1 - 1 : 0;
- if (curr->w_y >= rows)
- curr->w_y = rows - 1;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- break;
- case 'm':
- SelectRendition();
- break;
- case 'g':
- if (a1 == 0)
- curr->w_tabs[curr->w_x] = 0;
- else if (a1 == 3)
- bzero(curr->w_tabs, cols);
- break;
- case 'r':
- if (!a1)
- a1 = 1;
- if (!a2)
- a2 = rows;
- if (a1 < 1 || a2 > rows || a1 >= a2)
- break;
- curr->w_top = a1 - 1;
- curr->w_bot = a2 - 1;
- /* ChangeScrollRegion(curr->w_top, curr->w_bot); */
- if (curr->w_origin)
- {
- curr->w_y = curr->w_top;
- curr->w_x = 0;
- }
- else
- curr->w_y = curr->w_x = 0;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- break;
- case 's':
- SaveCursor();
- break;
- case 't':
- if (a1 != 8)
- break;
- a1 = curr->w_args[2];
- if (a1 < 1)
- a1 = curr->w_width;
- if (a2 < 1)
- a2 = curr->w_height;
- if (a1 > 10000 || a2 > 10000)
- break;
- WChangeSize(curr, a1, a2);
- cols = curr->w_width;
- rows = curr->w_height;
- break;
- case 'u':
- RestoreCursor();
- break;
- case 'I':
- if (!a1)
- a1 = 1;
- while (a1--)
- ForwardTab();
- break;
- case 'Z':
- if (!a1)
- a1 = 1;
- while (a1--)
- BackwardTab();
- break;
- case 'L':
- InsertLine(a1 ? a1 : 1);
- break;
- case 'M':
- DeleteLine(a1 ? a1 : 1);
- break;
- case 'P':
- DeleteChar(a1 ? a1 : 1);
- break;
- case '@':
- InsertChar(a1 ? a1 : 1);
- break;
- case 'h':
- ASetMode(1);
- break;
- case 'l':
- ASetMode(0);
- break;
- case 'i': /* MC Media Control */
- if (a1 == 5)
- PrintStart();
- break;
- case 'n':
- if (a1 == 5) /* Report terminal status */
- Report("\033[0n", 0, 0);
- else if (a1 == 6) /* Report cursor position */
- Report("\033[%d;%dR", curr->w_y + 1, curr->w_x + 1);
- break;
- case 'c': /* Identify as VT100 */
- if (a1 == 0)
- Report("\033[?%d;%dc", 1, 2);
- break;
- case 'x': /* decreqtparm */
- if (a1 == 0 || a1 == 1)
- Report("\033[%d;1;1;112;112;1;0x", a1 + 2, 0);
- break;
- case 'p': /* obscure code from a 97801 term */
- if (a1 == 6 || a1 == 7)
- {
- curr->w_curinv = 7 - a1;
- LCursorVisibility(&curr->w_layer, curr->w_curinv ? -1 : curr->w_curvvis);
- }
- break;
- case 'S': /* code from a 97801 term / DEC vt400 */
- ScrollRegion(a1 ? a1 : 1);
- break;
- case 'T': /* code from a 97801 term / DEC vt400 */
- case '^': /* SD as per ISO 6429 */
- ScrollRegion(a1 ? -a1 : -1);
- break;
- }
- break;
- case '?':
- for (a2 = 0; a2 < curr->w_NumArgs; a2++)
- {
- a1 = curr->w_args[a2];
- debug2("\\E[?%d%c\n",a1,c);
- if (c != 'h' && c != 'l')
- break;
- i = (c == 'h');
- switch (a1)
- {
- case 1: /* CKM: cursor key mode */
- LCursorkeysMode(&curr->w_layer, curr->w_cursorkeys = i);
-#ifndef TIOCPKT
- WNewAutoFlow(curr, !i);
-#endif /* !TIOCPKT */
- break;
- case 2: /* ANM: ansi/vt52 mode */
- if (i)
- {
-#ifdef FONT
-# ifdef ENCODINGS
- if (curr->w_encoding)
- break;
-# endif
- curr->w_charsets[0] = curr->w_charsets[1] =
- curr->w_charsets[2] = curr->w_charsets[2] =
- curr->w_FontL = curr->w_FontR = ASCII;
- curr->w_Charset = 0;
- curr->w_CharsetR = 2;
- curr->w_ss = 0;
-#endif
- }
- break;
- case 3: /* COLM: column mode */
- i = (i ? Z0width : Z1width);
- WChangeSize(curr, i, curr->w_height);
- cols = curr->w_width;
- rows = curr->w_height;
- break;
- /* case 4: SCLM: scrolling mode */
- case 5: /* SCNM: screen mode */
- if (i != curr->w_revvid)
- WReverseVideo(curr, i);
- curr->w_revvid = i;
- break;
- case 6: /* OM: origin mode */
- if ((curr->w_origin = i) != 0)
- {
- curr->w_y = curr->w_top;
- curr->w_x = 0;
- }
- else
- curr->w_y = curr->w_x = 0;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- break;
- case 7: /* AWM: auto wrap mode */
- curr->w_wrap = i;
- break;
- /* case 8: ARM: auto repeat mode */
- /* case 9: INLM: interlace mode */
- case 9: /* X10 mouse tracking */
- curr->w_mouse = i ? 9 : 0;
- LMouseMode(&curr->w_layer, curr->w_mouse);
- break;
- /* case 10: EDM: edit mode */
- /* case 11: LTM: line transmit mode */
- /* case 13: SCFDM: space compression / field delimiting */
- /* case 14: TEM: transmit execution mode */
- /* case 16: EKEM: edit key execution mode */
- /* case 18: PFF: Printer term form feed */
- /* case 19: PEX: Printer extend screen / scroll. reg */
- case 25: /* TCEM: text cursor enable mode */
- curr->w_curinv = !i;
- LCursorVisibility(&curr->w_layer, curr->w_curinv ? -1 : curr->w_curvvis);
- break;
- /* case 34: RLM: Right to left mode */
- /* case 35: HEBM: hebrew keyboard map */
- /* case 36: HEM: hebrew encoding */
- /* case 38: TeK Mode */
- /* case 40: 132 col enable */
- /* case 42: NRCM: 7bit NRC character mode */
- /* case 44: margin bell enable */
- case 47: /* xterm-like alternate screen */
- case 1047: /* xterm-like alternate screen */
- case 1049: /* xterm-like alternate screen */
- if (use_altscreen)
- {
- if (i)
- EnterAltScreen(curr);
- else
- LeaveAltScreen(curr);
- if (a1 == 47 && !i)
- curr->w_saved = 0;
- LRefreshAll(&curr->w_layer, 0);
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- }
- break;
- /* case 66: NKM: Numeric keypad appl mode */
- /* case 68: KBUM: Keyboard usage mode (data process) */
- case 1000: /* VT200 mouse tracking */
- case 1001: /* VT200 highlight mouse */
- case 1002: /* button event mouse*/
- case 1003: /* any event mouse*/
- curr->w_mouse = i ? a1 : 0;
- LMouseMode(&curr->w_layer, curr->w_mouse);
- break;
- }
- }
- break;
- case '>':
- switch (c)
- {
- case 'c': /* secondary DA */
- if (a1 == 0)
- Report("\033[>%d;%d;0c", 83, nversion); /* 83 == 'S' */
- break;
- }
- break;
- }
-}
-
-
-static void
-StringStart(type)
-enum string_t type;
-{
- curr->w_StringType = type;
- curr->w_stringp = curr->w_string;
- curr->w_state = ASTR;
-}
-
-static void
-StringChar(c)
-int c;
-{
- if (curr->w_stringp >= curr->w_string + MAXSTR - 1)
- curr->w_state = LIT;
- else
- *(curr->w_stringp)++ = c;
-}
-
-/*
- * Do string processing. Returns -1 if output should be suspended
- * until status is gone.
- */
-static int
-StringEnd()
-{
- struct canvas *cv;
- char *p;
- int typ;
-
- curr->w_state = LIT;
- *curr->w_stringp = '\0';
- switch (curr->w_StringType)
- {
- case OSC: /* special xterm compatibility hack */
- if (curr->w_string[0] == ';' || (p = index(curr->w_string, ';')) == 0)
- break;
- typ = atoi(curr->w_string);
- p++;
-#ifdef MULTIUSER
- if (typ == 83) /* 83 = 'S' */
- {
- /* special execute commands sequence */
- char *args[MAXARGS];
- int argl[MAXARGS];
- struct acluser *windowuser;
-
- windowuser = *FindUserPtr(":window:");
- if (windowuser && Parse(p, sizeof(curr->w_string) - (p - curr->w_string), args, argl))
- {
- for (display = displays; display; display = display->d_next)
- if (D_forecv->c_layer->l_bottom == &curr->w_layer)
- break; /* found it */
- if (display == 0 && curr->w_layer.l_cvlist)
- display = curr->w_layer.l_cvlist->c_display;
- if (display == 0)
- display = displays;
- EffectiveAclUser = windowuser;
- fore = curr;
- flayer = fore->w_savelayer ? fore->w_savelayer : &fore->w_layer;
- DoCommand(args, argl);
- EffectiveAclUser = 0;
- fore = 0;
- flayer = 0;
- }
- break;
- }
-#endif
-#ifdef RXVT_OSC
- if (typ == 0 || typ == 1 || typ == 20 || typ == 39 || typ == 49)
- {
- int typ2;
- typ2 = typ / 10;
- if (--typ2 < 0)
- typ2 = 0;
- if (strcmp(curr->w_xtermosc[typ2], p))
- {
- strncpy(curr->w_xtermosc[typ2], p, sizeof(curr->w_xtermosc[typ2]) - 1);
- curr->w_xtermosc[typ2][sizeof(curr->w_xtermosc[typ2]) - 1] = 0;
-
- for (display = displays; display; display = display->d_next)
- {
- if (!D_CXT)
- continue;
- if (D_forecv->c_layer->l_bottom == &curr->w_layer)
- SetXtermOSC(typ2, curr->w_xtermosc[typ2]);
- if ((typ2 == 2 || typ2 == 3) && D_xtermosc[typ2])
- Redisplay(0);
- }
- }
- }
- if (typ != 0 && typ != 2)
- break;
-#else
- if (typ < 0 || typ > 2)
- break;
-#endif
-
- curr->w_stringp -= p - curr->w_string;
- if (curr->w_stringp > curr->w_string)
- bcopy(p, curr->w_string, curr->w_stringp - curr->w_string);
- *curr->w_stringp = '\0';
- /* FALLTHROUGH */
- case APC:
- if (curr->w_hstatus)
- {
- if (strcmp(curr->w_hstatus, curr->w_string) == 0)
- break; /* not changed */
- free(curr->w_hstatus);
- curr->w_hstatus = 0;
- }
- if (curr->w_string != curr->w_stringp)
- curr->w_hstatus = SaveStr(curr->w_string);
- WindowChanged(curr, 'h');
- break;
- case PM:
- case GM:
- for (display = displays; display; display = display->d_next)
- {
- for (cv = D_cvlist; cv; cv = cv->c_next)
- if (cv->c_layer->l_bottom == &curr->w_layer)
- break;
- if (cv || curr->w_StringType == GM)
- MakeStatus(curr->w_string);
- }
- return -1;
- case DCS:
- LAY_DISPLAYS(&curr->w_layer, AddStr(curr->w_string));
- break;
- case AKA:
- if (curr->w_title == curr->w_akabuf && !*curr->w_string)
- break;
- ChangeAKA(curr, curr->w_string, strlen(curr->w_string));
- if (!*curr->w_string)
- curr->w_autoaka = curr->w_y + 1;
- break;
- default:
- break;
- }
- return 0;
-}
-
-static void
-PrintStart()
-{
- curr->w_pdisplay = 0;
-
- /* find us a nice display to print on, fore prefered */
- display = curr->w_lastdisp;
- if (!(display && curr == D_fore && (printcmd || D_PO)))
- for (display = displays; display; display = display->d_next)
- if (curr == D_fore && (printcmd || D_PO))
- break;
- if (!display)
- {
- struct canvas *cv;
- for (cv = curr->w_layer.l_cvlist; cv; cv = cv->c_lnext)
- {
- display = cv->c_display;
- if (printcmd || D_PO)
- break;
- }
- if (!cv)
- {
- display = displays;
- if (!display || display->d_next || !(printcmd || D_PO))
- return;
- }
- }
- curr->w_pdisplay = display;
- curr->w_stringp = curr->w_string;
- curr->w_state = PRIN;
- if (printcmd && curr->w_pdisplay->d_printfd < 0)
- curr->w_pdisplay->d_printfd = printpipe(curr, printcmd);
-}
-
-static void
-PrintChar(c)
-int c;
-{
- if (curr->w_stringp >= curr->w_string + MAXSTR - 1)
- PrintFlush();
- *(curr->w_stringp)++ = c;
-}
-
-static void
-PrintFlush()
-{
- display = curr->w_pdisplay;
- if (display && printcmd)
- {
- char *bp = curr->w_string;
- int len = curr->w_stringp - curr->w_string;
- int r;
- while (len && display->d_printfd >= 0)
- {
- r = write(display->d_printfd, bp, len);
- if (r <= 0)
- {
- WMsg(curr, errno, "printing aborted");
- close(display->d_printfd);
- display->d_printfd = -1;
- break;
- }
- bp += r;
- len -= r;
- }
- }
- else if (display && curr->w_stringp > curr->w_string)
- {
- AddCStr(D_PO);
- AddStrn(curr->w_string, curr->w_stringp - curr->w_string);
- AddCStr(D_PF);
- Flush();
- }
- curr->w_stringp = curr->w_string;
-}
-
-
-void
-WNewAutoFlow(win, on)
-struct win *win;
-int on;
-{
- debug1("WNewAutoFlow: %d\n", on);
- if (win->w_flow & FLOW_AUTOFLAG)
- win->w_flow = FLOW_AUTOFLAG | (FLOW_AUTO|FLOW_NOW) * on;
- else
- win->w_flow = (win->w_flow & ~FLOW_AUTO) | FLOW_AUTO * on;
- LSetFlow(&win->w_layer, win->w_flow & FLOW_NOW);
-}
-
-
-#ifdef FONT
-
-static void
-DesignateCharset(c, n)
-int c, n;
-{
- curr->w_ss = 0;
-# ifdef ENCODINGS
- if (c == ('@' & 037)) /* map JIS 6226 to 0208 */
- c = KANJI;
-# endif
- if (c == 'B')
- c = ASCII;
- if (curr->w_charsets[n] != c)
- {
- curr->w_charsets[n] = c;
- if (curr->w_Charset == n)
- {
- curr->w_FontL = c;
- curr->w_rend.font = curr->w_FontL;
- LSetRendition(&curr->w_layer, &curr->w_rend);
- }
- if (curr->w_CharsetR == n)
- curr->w_FontR = c;
- }
-}
-
-static void
-MapCharset(n)
-int n;
-{
- curr->w_ss = 0;
- if (curr->w_Charset != n)
- {
- curr->w_Charset = n;
- curr->w_FontL = curr->w_charsets[n];
- curr->w_rend.font = curr->w_FontL;
- LSetRendition(&curr->w_layer, &curr->w_rend);
- }
-}
-
-static void
-MapCharsetR(n)
-int n;
-{
- curr->w_ss = 0;
- if (curr->w_CharsetR != n)
- {
- curr->w_CharsetR = n;
- curr->w_FontR = curr->w_charsets[n];
- }
- curr->w_gr = 1;
-}
-
-#endif /* FONT */
-
-static void
-SaveCursor()
-{
- curr->w_saved = 1;
- curr->w_Saved_x = curr->w_x;
- curr->w_Saved_y = curr->w_y;
- curr->w_SavedRend = curr->w_rend;
-#ifdef FONT
- curr->w_SavedCharset = curr->w_Charset;
- curr->w_SavedCharsetR = curr->w_CharsetR;
- bcopy((char *) curr->w_charsets, (char *) curr->w_SavedCharsets,
- 4 * sizeof(int));
-#endif
-}
-
-static void
-RestoreCursor()
-{
- if (!curr->w_saved)
- return;
- LGotoPos(&curr->w_layer, curr->w_Saved_x, curr->w_Saved_y);
- curr->w_x = curr->w_Saved_x;
- curr->w_y = curr->w_Saved_y;
- curr->w_rend = curr->w_SavedRend;
-#ifdef FONT
- bcopy((char *) curr->w_SavedCharsets, (char *) curr->w_charsets,
- 4 * sizeof(int));
- curr->w_Charset = curr->w_SavedCharset;
- curr->w_CharsetR = curr->w_SavedCharsetR;
- curr->w_ss = 0;
- curr->w_FontL = curr->w_charsets[curr->w_Charset];
- curr->w_FontR = curr->w_charsets[curr->w_CharsetR];
-#endif
- LSetRendition(&curr->w_layer, &curr->w_rend);
-}
-
-static void
-BackSpace()
-{
- if (curr->w_x > 0)
- {
- curr->w_x--;
- }
- else if (curr->w_wrap && curr->w_y > 0)
- {
- curr->w_x = cols - 1;
- curr->w_y--;
- }
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-Return()
-{
- if (curr->w_x == 0)
- return;
- curr->w_x = 0;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-LineFeed(out_mode)
-int out_mode;
-{
- /* out_mode: 0=lf, 1=cr+lf */
- if (out_mode)
- curr->w_x = 0;
- if (curr->w_y != curr->w_bot) /* Don't scroll */
- {
- if (curr->w_y < rows-1)
- curr->w_y++;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- return;
- }
- if (curr->w_autoaka > 1)
- curr->w_autoaka--;
- MScrollV(curr, 1, curr->w_top, curr->w_bot, CURR_BCE);
- LScrollV(&curr->w_layer, 1, curr->w_top, curr->w_bot, CURR_BCE);
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-ReverseLineFeed()
-{
- if (curr->w_y == curr->w_top)
- {
- MScrollV(curr, -1, curr->w_top, curr->w_bot, CURR_BCE);
- LScrollV(&curr->w_layer, -1, curr->w_top, curr->w_bot, CURR_BCE);
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- }
- else if (curr->w_y > 0)
- CursorUp(1);
-}
-
-static void
-InsertChar(n)
-int n;
-{
- register int y = curr->w_y, x = curr->w_x;
-
- if (n <= 0)
- return;
- if (x == cols)
- x--;
- save_mline(&curr->w_mlines[y], cols);
- MScrollH(curr, -n, y, x, curr->w_width - 1, CURR_BCE);
- LScrollH(&curr->w_layer, -n, y, x, curr->w_width - 1, CURR_BCE, &mline_old);
- LGotoPos(&curr->w_layer, x, y);
-}
-
-static void
-DeleteChar(n)
-int n;
-{
- register int y = curr->w_y, x = curr->w_x;
-
- if (x == cols)
- x--;
- save_mline(&curr->w_mlines[y], cols);
- MScrollH(curr, n, y, x, curr->w_width - 1, CURR_BCE);
- LScrollH(&curr->w_layer, n, y, x, curr->w_width - 1, CURR_BCE, &mline_old);
- LGotoPos(&curr->w_layer, x, y);
-}
-
-static void
-DeleteLine(n)
-int n;
-{
- if (curr->w_y < curr->w_top || curr->w_y > curr->w_bot)
- return;
- if (n > curr->w_bot - curr->w_y + 1)
- n = curr->w_bot - curr->w_y + 1;
- MScrollV(curr, n, curr->w_y, curr->w_bot, CURR_BCE);
- LScrollV(&curr->w_layer, n, curr->w_y, curr->w_bot, CURR_BCE);
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-InsertLine(n)
-int n;
-{
- if (curr->w_y < curr->w_top || curr->w_y > curr->w_bot)
- return;
- if (n > curr->w_bot - curr->w_y + 1)
- n = curr->w_bot - curr->w_y + 1;
- MScrollV(curr, -n, curr->w_y, curr->w_bot, CURR_BCE);
- LScrollV(&curr->w_layer, -n, curr->w_y, curr->w_bot, CURR_BCE);
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-ScrollRegion(n)
-int n;
-{
- MScrollV(curr, n, curr->w_top, curr->w_bot, CURR_BCE);
- LScrollV(&curr->w_layer, n, curr->w_top, curr->w_bot, CURR_BCE);
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-
-static void
-ForwardTab()
-{
- register int x = curr->w_x;
-
- if (x == cols)
- {
- LineFeed(1);
- x = 0;
- }
- if (curr->w_tabs[x] && x < cols - 1)
- x++;
- while (x < cols - 1 && !curr->w_tabs[x])
- x++;
- curr->w_x = x;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-BackwardTab()
-{
- register int x = curr->w_x;
-
- if (curr->w_tabs[x] && x > 0)
- x--;
- while (x > 0 && !curr->w_tabs[x])
- x--;
- curr->w_x = x;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-ClearScreen()
-{
- LClearArea(&curr->w_layer, 0, 0, curr->w_width - 1, curr->w_height - 1, CURR_BCE, 1);
-#ifdef COPY_PASTE
- MScrollV(curr, curr->w_height, 0, curr->w_height - 1, CURR_BCE);
-#else
- MClearArea(curr, 0, 0, curr->w_width - 1, curr->w_height - 1, CURR_BCE);
-#endif
-}
-
-static void
-ClearFromBOS()
-{
- register int y = curr->w_y, x = curr->w_x;
-
- LClearArea(&curr->w_layer, 0, 0, x, y, CURR_BCE, 1);
- MClearArea(curr, 0, 0, x, y, CURR_BCE);
- RestorePosRendition();
-}
-
-static void
-ClearToEOS()
-{
- register int y = curr->w_y, x = curr->w_x;
-
- if (x == 0 && y == 0)
- {
- ClearScreen();
- RestorePosRendition();
- return;
- }
- LClearArea(&curr->w_layer, x, y, cols - 1, rows - 1, CURR_BCE, 1);
- MClearArea(curr, x, y, cols - 1, rows - 1, CURR_BCE);
- RestorePosRendition();
-}
-
-static void
-ClearLineRegion(from, to)
-int from, to;
-{
- register int y = curr->w_y;
- LClearArea(&curr->w_layer, from, y, to, y, CURR_BCE, 1);
- MClearArea(curr, from, y, to, y, CURR_BCE);
- RestorePosRendition();
-}
-
-static void
-CursorRight(n)
-register int n;
-{
- register int x = curr->w_x;
-
- if (x == cols)
- {
- LineFeed(1);
- x = 0;
- }
- if ((curr->w_x += n) >= cols)
- curr->w_x = cols - 1;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-CursorUp(n)
-register int n;
-{
- if (curr->w_y < curr->w_top) /* if above scrolling rgn, */
- {
- if ((curr->w_y -= n) < 0) /* ignore its limits */
- curr->w_y = 0;
- }
- else
- if ((curr->w_y -= n) < curr->w_top)
- curr->w_y = curr->w_top;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-CursorDown(n)
-register int n;
-{
- if (curr->w_y > curr->w_bot) /* if below scrolling rgn, */
- {
- if ((curr->w_y += n) > rows - 1) /* ignore its limits */
- curr->w_y = rows - 1;
- }
- else
- if ((curr->w_y += n) > curr->w_bot)
- curr->w_y = curr->w_bot;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-CursorLeft(n)
-register int n;
-{
- if ((curr->w_x -= n) < 0)
- curr->w_x = 0;
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
-}
-
-static void
-ASetMode(on)
-int on;
-{
- register int i;
-
- for (i = 0; i < curr->w_NumArgs; ++i)
- {
- switch (curr->w_args[i])
- {
- /* case 2: KAM: Lock keyboard */
- case 4: /* IRM: Insert mode */
- curr->w_insert = on;
- LAY_DISPLAYS(&curr->w_layer, InsertMode(on));
- break;
- /* case 12: SRM: Echo mode on */
- case 20: /* LNM: Linefeed mode */
- curr->w_autolf = on;
- break;
- case 34:
- curr->w_curvvis = !on;
- LCursorVisibility(&curr->w_layer, curr->w_curinv ? -1 : curr->w_curvvis);
- break;
- default:
- break;
- }
- }
-}
-
-static char rendlist[] =
-{
- ~((1 << NATTR) - 1), A_BD, A_DI, A_SO, A_US, A_BL, 0, A_RV, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, ~(A_BD|A_SO|A_DI), ~A_SO, ~A_US, ~A_BL, 0, ~A_RV
-};
-
-static void
-SelectRendition()
-{
-#ifdef COLOR
- register int j, i = 0, a = curr->w_rend.attr, c = curr->w_rend.color;
-# ifdef COLORS256
- int cx = curr->w_rend.colorx;
-# endif
-#else
- register int j, i = 0, a = curr->w_rend.attr;
-#endif
-
- do
- {
- j = curr->w_args[i];
-#ifdef COLOR
- if ((j == 38 || j == 48) && i + 2 < curr->w_NumArgs && curr->w_args[i + 1] == 5)
- {
- int jj;
-
- i += 2;
- jj = curr->w_args[i];
- if (jj < 0 || jj > 255)
- continue;
-# ifdef COLORS256
- if (j == 38)
- {
- c = (c & 0xf0) | ((jj & 0x0f) ^ 9);
- a |= A_BFG;
- if (jj >= 8 && jj < 16)
- c |= 0x08;
- else
- a ^= A_BFG;
- a = (a & 0xbf) | (jj & 8 ? 0x40 : 0);
- cx = (cx & 0xf0) | (jj >> 4 & 0x0f);
- }
- else
- {
- c = (c & 0x0f) | ((jj & 0x0f) ^ 9) << 4;
- a |= A_BBG;
- if (jj >= 8 && jj < 16)
- c |= 0x80;
- else
- a ^= A_BBG;
- cx = (cx & 0x0f) | (jj & 0xf0);
- }
- continue;
-# else
- jj = color256to16(jj) + 30;
- if (jj >= 38)
- jj += 60 - 8;
- j = j == 38 ? jj : jj + 10;
-# endif
- }
-# ifdef COLORS16
- if (j == 0 || (j >= 30 && j <= 39 && j != 38))
- a &= 0xbf;
- if (j == 0 || (j >= 40 && j <= 49 && j != 48))
- a &= 0x7f;
- if (j >= 90 && j <= 97)
- a |= 0x40;
- if (j >= 100 && j <= 107)
- a |= 0x80;
-# endif
- if (j >= 90 && j <= 97)
- j -= 60;
- if (j >= 100 && j <= 107)
- j -= 60;
- if (j >= 30 && j <= 39 && j != 38)
- c = (c & 0xf0) | ((j - 30) ^ 9);
- else if (j >= 40 && j <= 49 && j != 48)
- c = (c & 0x0f) | (((j - 40) ^ 9) << 4);
- if (j == 0)
- c = 0;
-# ifdef COLORS256
- if (j == 0 || (j >= 30 && j <= 39 && j != 38))
- cx &= 0xf0;
- if (j == 0 || (j >= 40 && j <= 49 && j != 48))
- cx &= 0x0f;
-# endif
-#endif
- if (j < 0 || j >= (int)(sizeof(rendlist)/sizeof(*rendlist)))
- continue;
- j = rendlist[j];
- if (j & (1 << NATTR))
- a &= j;
- else
- a |= j;
- }
- while (++i < curr->w_NumArgs);
- curr->w_rend.attr = a;
-#ifdef COLOR
- curr->w_rend.color = c;
-# ifdef COLORS256
- curr->w_rend.colorx = cx;
-# endif
-#endif
- LSetRendition(&curr->w_layer, &curr->w_rend);
-}
-
-static void
-FillWithEs()
-{
- register int i;
- register unsigned char *p, *ep;
-
- LClearAll(&curr->w_layer, 1);
- curr->w_y = curr->w_x = 0;
- for (i = 0; i < rows; ++i)
- {
- clear_mline(&curr->w_mlines[i], 0, cols + 1);
- p = curr->w_mlines[i].image;
- ep = p + cols;
- while (p < ep)
- *p++ = 'E';
- }
- LRefreshAll(&curr->w_layer, 1);
-}
-
-
-/*
- * Ugly autoaka hack support:
- * ChangeAKA() sets a new aka
- * FindAKA() searches for an autoaka match
- */
-
-void
-ChangeAKA(p, s, l)
-struct win *p;
-char *s;
-int l;
-{
- int i, c;
-
- for (i = 0; l > 0; l--)
- {
- if (p->w_akachange + i == p->w_akabuf + sizeof(p->w_akabuf) - 1)
- break;
- c = (unsigned char)*s++;
- if (c == 0)
- break;
- if (c < 32 || c == 127 || (c >= 128 && c < 160 && p->w_c1))
- continue;
- p->w_akachange[i++] = c;
- }
- p->w_akachange[i] = 0;
- p->w_title = p->w_akachange;
- if (p->w_akachange != p->w_akabuf)
- if (p->w_akachange[0] == 0 || p->w_akachange[-1] == ':')
- p->w_title = p->w_akabuf + strlen(p->w_akabuf) + 1;
- WindowChanged(p, 't');
- WindowChanged((struct win *)0, 'w');
- WindowChanged((struct win *)0, 'W');
-}
-
-static void
-FindAKA()
-{
- register unsigned char *cp, *line;
- register struct win *wp = curr;
- register int len = strlen(wp->w_akabuf);
- int y;
-
- y = (wp->w_autoaka > 0 && wp->w_autoaka <= wp->w_height) ? wp->w_autoaka - 1 : wp->w_y;
- cols = wp->w_width;
- try_line:
- cp = line = wp->w_mlines[y].image;
- if (wp->w_autoaka > 0 && *wp->w_akabuf != '\0')
- {
- for (;;)
- {
- if (cp - line >= cols - len)
- {
- if (++y == wp->w_autoaka && y < rows)
- goto try_line;
- return;
- }
- if (strncmp((char *)cp, wp->w_akabuf, len) == 0)
- break;
- cp++;
- }
- cp += len;
- }
- for (len = cols - (cp - line); len && *cp == ' '; len--, cp++)
- ;
- if (len)
- {
- if (wp->w_autoaka > 0 && (*cp == '!' || *cp == '%' || *cp == '^'))
- wp->w_autoaka = -1;
- else
- wp->w_autoaka = 0;
- line = cp;
- while (len && *cp != ' ')
- {
- if (*cp++ == '/')
- line = cp;
- len--;
- }
- ChangeAKA(wp, (char *)line, cp - line);
- }
- else
- wp->w_autoaka = 0;
-}
-
-static void
-RestorePosRendition()
-{
- LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
- LSetRendition(&curr->w_layer, &curr->w_rend);
-}
-
-/* Send a terminal report as if it were typed. */
-static void
-Report(fmt, n1, n2)
-char *fmt;
-int n1, n2;
-{
- register int len;
- char rbuf[40]; /* enough room for all replys */
-
- sprintf(rbuf, fmt, n1, n2);
- len = strlen(rbuf);
-
- if ((unsigned)(curr->w_inlen + len) <= sizeof(curr->w_inbuf))
- {
- bcopy(rbuf, curr->w_inbuf + curr->w_inlen, len);
- curr->w_inlen += len;
- }
-}
-
-
-
-/*
- *====================================================================*
- *====================================================================*
- */
-
-/**********************************************************************
- *
- * Memory subsystem.
- *
- */
-
-static void
-MFixLine(p, y, mc)
-struct win *p;
-int y;
-struct mchar *mc;
-{
- struct mline *ml = &p->w_mlines[y];
- if (mc->attr && ml->attr == null)
- {
- if ((ml->attr = (unsigned char *)malloc(p->w_width + 1)) == 0)
- {
- ml->attr = null;
- mc->attr = p->w_rend.attr = 0;
- WMsg(p, 0, "Warning: no space for attr - turned off");
- }
- bzero((char *)ml->attr, p->w_width + 1);
- }
-#ifdef FONT
- if (mc->font && ml->font == null)
- {
- if ((ml->font = (unsigned char *)malloc(p->w_width + 1)) == 0)
- {
- ml->font = null;
- p->w_FontL = p->w_charsets[p->w_ss ? p->w_ss : p->w_Charset] = 0;
- p->w_FontR = p->w_charsets[p->w_ss ? p->w_ss : p->w_CharsetR] = 0;
- mc->font = p->w_rend.font = 0;
- WMsg(p, 0, "Warning: no space for font - turned off");
- }
- bzero((char *)ml->font, p->w_width + 1);
- }
-#endif
-#ifdef COLOR
- if (mc->color && ml->color == null)
- {
- if ((ml->color = (unsigned char *)malloc(p->w_width + 1)) == 0)
- {
- ml->color = null;
- mc->color = p->w_rend.color = 0;
- WMsg(p, 0, "Warning: no space for color - turned off");
- }
- bzero((char *)ml->color, p->w_width + 1);
- }
-# ifdef COLORS256
- if (mc->colorx && ml->colorx == null)
- {
- if ((ml->colorx = (unsigned char *)malloc(p->w_width + 1)) == 0)
- {
- ml->colorx = null;
- mc->colorx = p->w_rend.colorx = 0;
- WMsg(p, 0, "Warning: no space for extended colors - turned off");
- }
- bzero((char *)ml->colorx, p->w_width + 1);
- }
-# endif
-#endif
-}
-
-/*****************************************************************/
-
-#ifdef DW_CHARS
-# define MKillDwRight(p, ml, x) \
- if (dw_right(ml, x, p->w_encoding)) \
- { \
- if (x > 0) \
- copy_mchar2mline(&mchar_blank, ml, x - 1); \
- copy_mchar2mline(&mchar_blank, ml, x); \
- }
-
-# define MKillDwLeft(p, ml, x) \
- if (dw_left(ml, x, p->w_encoding)) \
- { \
- copy_mchar2mline(&mchar_blank, ml, x); \
- copy_mchar2mline(&mchar_blank, ml, x + 1); \
- }
-#else
-# define MKillDwRight(p, ml, x) ;
-# define MKillDwLeft(p, ml, x) ;
-#endif
-
-static void
-MScrollH(p, n, y, xs, xe, bce)
-struct win *p;
-int n, y, xs, xe, bce;
-{
- struct mline *ml;
-
- if (n == 0)
- return;
- ml = &p->w_mlines[y];
- MKillDwRight(p, ml, xs);
- MKillDwLeft(p, ml, xe);
- if (n > 0)
- {
- if (xe - xs + 1 > n)
- {
- MKillDwRight(p, ml, xs + n);
- bcopy_mline(ml, xs + n, xs, xe + 1 - xs - n);
- }
- else
- n = xe - xs + 1;
- clear_mline(ml, xe + 1 - n, n);
-#ifdef COLOR
- if (bce)
- MBceLine(p, y, xe + 1 - n, n, bce);
-#endif
- }
- else
- {
- n = -n;
- if (xe - xs + 1 > n)
- {
- MKillDwLeft(p, ml, xe - n);
- bcopy_mline(ml, xs, xs + n, xe + 1 - xs - n);
- }
- else
- n = xe - xs + 1;
- clear_mline(ml, xs, n);
-#ifdef COLOR
- if (bce)
- MBceLine(p, y, xs, n, bce);
-#endif
- }
-}
-
-static void
-MScrollV(p, n, ys, ye, bce)
-struct win *p;
-int n, ys, ye, bce;
-{
- int i, cnt1, cnt2;
- struct mline tmp[256];
- struct mline *ml;
-
- if (n == 0)
- return;
- if (n > 0)
- {
- if (n > 256)
- {
- MScrollV(p, n - 256, ys, ye, bce);
- n = 256;
- }
- if (ye - ys + 1 < n)
- n = ye - ys + 1;
-#ifdef COPY_PASTE
- if (compacthist)
- {
- ye = MFindUsedLine(p, ye, ys);
- if (ye - ys + 1 < n)
- n = ye - ys + 1;
- if (n <= 0)
- return;
- }
-#endif
- /* Clear lines */
- ml = p->w_mlines + ys;
- for (i = ys; i < ys + n; i++, ml++)
- {
-#ifdef COPY_PASTE
- if (ys == p->w_top)
- WAddLineToHist(p, ml);
-#endif
- if (ml->attr != null)
- free(ml->attr);
- ml->attr = null;
-#ifdef FONT
- if (ml->font != null)
- free(ml->font);
- ml->font = null;
-#endif
-#ifdef COLOR
- if (ml->color != null)
- free(ml->color);
- ml->color = null;
-# ifdef COLORS256
- if (ml->colorx != null)
- free(ml->colorx);
- ml->colorx = null;
-# endif
-#endif
- bclear((char *)ml->image, p->w_width + 1);
-#ifdef COLOR
- if (bce)
- MBceLine(p, i, 0, p->w_width, bce);
-#endif
- }
- /* switch 'em over */
- cnt1 = n * sizeof(struct mline);
- cnt2 = (ye - ys + 1 - n) * sizeof(struct mline);
- if (cnt1 && cnt2)
- Scroll((char *)(p->w_mlines + ys), cnt1, cnt2, (char *)tmp);
- }
- else
- {
- if (n < -256)
- {
- MScrollV(p, n + 256, ys, ye, bce);
- n = -256;
- }
- n = -n;
- if (ye - ys + 1 < n)
- n = ye - ys + 1;
-
- ml = p->w_mlines + ye;
- /* Clear lines */
- for (i = ye; i > ye - n; i--, ml--)
- {
- if (ml->attr != null)
- free(ml->attr);
- ml->attr = null;
-#ifdef FONT
- if (ml->font != null)
- free(ml->font);
- ml->font = null;
-#endif
-#ifdef COLOR
- if (ml->color != null)
- free(ml->color);
- ml->color = null;
-# ifdef COLORS256
- if (ml->colorx != null)
- free(ml->colorx);
- ml->colorx = null;
-# endif
-#endif
- bclear((char *)ml->image, p->w_width + 1);
-#ifdef COLOR
- if (bce)
- MBceLine(p, i, 0, p->w_width, bce);
-#endif
- }
- cnt1 = n * sizeof(struct mline);
- cnt2 = (ye - ys + 1 - n) * sizeof(struct mline);
- if (cnt1 && cnt2)
- Scroll((char *)(p->w_mlines + ys), cnt2, cnt1, (char *)tmp);
- }
-}
-
-static void
-Scroll(cp, cnt1, cnt2, tmp)
-char *cp, *tmp;
-int cnt1, cnt2;
-{
- if (!cnt1 || !cnt2)
- return;
- if (cnt1 <= cnt2)
- {
- bcopy(cp, tmp, cnt1);
- bcopy(cp + cnt1, cp, cnt2);
- bcopy(tmp, cp + cnt2, cnt1);
- }
- else
- {
- bcopy(cp + cnt1, tmp, cnt2);
- bcopy(cp, cp + cnt2, cnt1);
- bcopy(tmp, cp, cnt2);
- }
-}
-
-static void
-MClearArea(p, xs, ys, xe, ye, bce)
-struct win *p;
-int xs, ys, xe, ye, bce;
-{
- int n, y;
- int xxe;
- struct mline *ml;
-
- /* check for magic margin condition */
- if (xs >= p->w_width)
- xs = p->w_width - 1;
- if (xe >= p->w_width)
- xe = p->w_width - 1;
-
- MKillDwRight(p, p->w_mlines + ys, xs);
- MKillDwLeft(p, p->w_mlines + ye, xe);
-
- ml = p->w_mlines + ys;
- for (y = ys; y <= ye; y++, ml++)
- {
- xxe = (y == ye) ? xe : p->w_width - 1;
- n = xxe - xs + 1;
- if (n > 0)
- clear_mline(ml, xs, n);
-#ifdef COLOR
- if (n > 0 && bce)
- MBceLine(p, y, xs, xs + n - 1, bce);
-#endif
- xs = 0;
- }
-}
-
-static void
-MInsChar(p, c, x, y)
-struct win *p;
-struct mchar *c;
-int x, y;
-{
- int n;
- struct mline *ml;
-
- ASSERT(x >= 0 && x < p->w_width);
- MFixLine(p, y, c);
- ml = p->w_mlines + y;
- n = p->w_width - x - 1;
- MKillDwRight(p, ml, x);
- if (n > 0)
- {
- MKillDwRight(p, ml, p->w_width - 1);
- bcopy_mline(ml, x, x + 1, n);
- }
- copy_mchar2mline(c, ml, x);
-#ifdef DW_CHARS
- if (c->mbcs)
- {
- if (--n > 0)
- {
- MKillDwRight(p, ml, p->w_width - 1);
- bcopy_mline(ml, x + 1, x + 2, n);
- }
- copy_mchar2mline(c, ml, x + 1);
- ml->image[x + 1] = c->mbcs;
-# ifdef UTF8
- if (p->w_encoding != UTF8)
- ml->font[x + 1] |= 0x80;
- else if (p->w_encoding == UTF8 && c->mbcs)
- ml->font[x + 1] = c->mbcs;
-# else
- ml->font[x + 1] |= 0x80;
-# endif
- }
-#endif
-}
-
-static void
-MPutChar(p, c, x, y)
-struct win *p;
-struct mchar *c;
-int x, y;
-{
- struct mline *ml;
-
- MFixLine(p, y, c);
- ml = &p->w_mlines[y];
- MKillDwRight(p, ml, x);
- MKillDwLeft(p, ml, x);
- copy_mchar2mline(c, ml, x);
-#ifdef DW_CHARS
- if (c->mbcs)
- {
- MKillDwLeft(p, ml, x + 1);
- copy_mchar2mline(c, ml, x + 1);
- ml->image[x + 1] = c->mbcs;
-# ifdef UTF8
- if (p->w_encoding != UTF8)
- ml->font[x + 1] |= 0x80;
- else if (p->w_encoding == UTF8 && c->mbcs)
- ml->font[x + 1] = c->mbcs;
-# else
- ml->font[x + 1] |= 0x80;
-# endif
- }
-#endif
-}
-
-
-static void
-MWrapChar(p, c, y, top, bot, ins)
-struct win *p;
-struct mchar *c;
-int y, top, bot;
-int ins;
-{
- struct mline *ml;
- int bce;
-
-#ifdef COLOR
- bce = rend_getbg(c);
-#else
- bce = 0;
-#endif
- MFixLine(p, y, c);
- ml = &p->w_mlines[y];
- copy_mchar2mline(&mchar_null, ml, p->w_width);
- if (y == bot)
- MScrollV(p, 1, top, bot, bce);
- else if (y < p->w_height - 1)
- y++;
- if (ins)
- MInsChar(p, c, 0, y);
- else
- MPutChar(p, c, 0, y);
-}
-
-static void
-MPutStr(p, s, n, r, x, y)
-struct win *p;
-char *s;
-int n;
-struct mchar *r;
-int x, y;
-{
- struct mline *ml;
- int i;
- unsigned char *b;
-
- if (n <= 0)
- return;
- MFixLine(p, y, r);
- ml = &p->w_mlines[y];
- MKillDwRight(p, ml, x);
- MKillDwLeft(p, ml, x + n - 1);
- bcopy(s, (char *)ml->image + x, n);
- b = ml->attr + x;
- for (i = n; i-- > 0;)
- *b++ = r->attr;
-#ifdef FONT
- b = ml->font + x;
- for (i = n; i-- > 0;)
- *b++ = r->font;
-#endif
-#ifdef COLOR
- b = ml->color + x;
- for (i = n; i-- > 0;)
- *b++ = r->color;
-# ifdef COLORS256
- b = ml->colorx + x;
- for (i = n; i-- > 0;)
- *b++ = r->colorx;
-# endif
-#endif
-}
-
-#ifdef COLOR
-static void
-MBceLine(p, y, xs, xe, bce)
-struct win *p;
-int y, xs, xe, bce;
-{
- struct mchar mc;
- struct mline *ml;
- int x;
-
- mc = mchar_null;
- rend_setbg(&mc, bce);
- MFixLine(p, y, &mc);
- ml = p->w_mlines + y;
-# ifdef COLORS16
- if (mc.attr)
- for (x = xs; x <= xe; x++)
- ml->attr[x] = mc.attr;
-# endif
- if (mc.color)
- for (x = xs; x <= xe; x++)
- ml->color[x] = mc.color;
-# ifdef COLORS256
- if (mc.colorx)
- for (x = xs; x <= xe; x++)
- ml->colorx[x] = mc.colorx;
-# endif
-}
-#endif
-
-
-#ifdef COPY_PASTE
-static void
-WAddLineToHist(wp, ml)
-struct win *wp;
-struct mline *ml;
-{
- register unsigned char *q, *o;
- struct mline *hml;
-
- if (wp->w_histheight == 0)
- return;
- hml = &wp->w_hlines[wp->w_histidx];
- q = ml->image; ml->image = hml->image; hml->image = q;
-
- q = ml->attr; o = hml->attr; hml->attr = q; ml->attr = null;
- if (o != null)
- free(o);
-
-#ifdef FONT
- q = ml->font; o = hml->font; hml->font = q; ml->font = null;
- if (o != null)
- free(o);
-#endif
-
-#ifdef COLOR
- q = ml->color; o = hml->color; hml->color = q; ml->color = null;
- if (o != null)
- free(o);
-# ifdef COLORS256
- q = ml->colorx; o = hml->colorx; hml->colorx = q; ml->colorx = null;
- if (o != null)
- free(o);
-# endif
-#endif
-
- if (++wp->w_histidx >= wp->w_histheight)
- wp->w_histidx = 0;
-}
-#endif
-
-int
-MFindUsedLine(p, ye, ys)
-struct win *p;
-int ys, ye;
-{
- int y;
- struct mline *ml = p->w_mlines + ye;
-
- debug2("MFindUsedLine: %d %d\n", ye, ys);
- for (y = ye; y >= ys; y--, ml--)
- {
- if (bcmp((char*)ml->image, blank, p->w_width))
- break;
- if (ml->attr != null && bcmp((char*)ml->attr, null, p->w_width))
- break;
-#ifdef COLOR
- if (ml->color != null && bcmp((char*)ml->color, null, p->w_width))
- break;
-# ifdef COLORS256
- if (ml->colorx != null && bcmp((char*)ml->colorx, null, p->w_width))
- break;
-# endif
-#endif
- }
- debug1("MFindUsedLine returning %d\n", y);
- return y;
-}
-
-
-/*
- *====================================================================*
- *====================================================================*
- */
-
-/*
- * Tricky: send only one bell even if the window is displayed
- * more than once.
- */
-void
-WBell(p, visual)
-struct win *p;
-int visual;
-{
- struct canvas *cv;
- for (display = displays; display; display = display->d_next)
- {
- for (cv = D_cvlist; cv; cv = cv->c_next)
- if (cv->c_layer->l_bottom == &p->w_layer)
- break;
- if (cv && !visual)
- AddCStr(D_BL);
- else if (cv && D_VB)
- AddCStr(D_VB);
- else
- p->w_bell = visual ? BELL_VISUAL : BELL_FOUND;
- }
-}
-
-/*
- * This should be reverse video.
- * Only change video if window is fore.
- * Because it is used in some termcaps to emulate
- * a visual bell we do this hack here.
- * (screen uses \Eg as special vbell sequence)
- */
-static void
-WReverseVideo(p, on)
-struct win *p;
-int on;
-{
- struct canvas *cv;
- for (cv = p->w_layer.l_cvlist; cv; cv = cv->c_lnext)
- {
- display = cv->c_display;
- if (cv != D_forecv)
- continue;
- ReverseVideo(on);
- if (!on && p->w_revvid && !D_CVR)
- {
- if (D_VB)
- AddCStr(D_VB);
- else
- p->w_bell = BELL_VISUAL;
- }
- }
-}
-
-void
-WMsg(p, err, str)
-struct win *p;
-int err;
-char *str;
-{
- extern struct layer *flayer;
- struct layer *oldflayer = flayer;
- flayer = &p->w_layer;
- LMsg(err, str);
- flayer = oldflayer;
-}
-
-void
-WChangeSize(p, w, h)
-struct win *p;
-int w, h;
-{
- int wok = 0;
- struct canvas *cv;
-
- if (p->w_layer.l_cvlist == 0)
- {
- /* window not displayed -> works always */
- ChangeWindowSize(p, w, h, p->w_histheight);
- return;
- }
- for (cv = p->w_layer.l_cvlist; cv; cv = cv->c_lnext)
- {
- display = cv->c_display;
- if (p != D_fore)
- continue; /* change only fore */
- if (D_CWS)
- break;
- if (D_CZ0 && (w == Z0width || w == Z1width))
- wok = 1;
- }
- if (cv == 0 && wok == 0) /* can't change any display */
- return;
- if (!D_CWS)
- h = p->w_height;
- ChangeWindowSize(p, w, h, p->w_histheight);
- for (display = displays; display; display = display->d_next)
- {
- if (p == D_fore)
- {
- if (D_cvlist && D_cvlist->c_next == 0)
- ResizeDisplay(w, h);
- else
- ResizeDisplay(w, D_height);
- ResizeLayersToCanvases(); /* XXX Hmm ? */
- continue;
- }
- for (cv = D_cvlist; cv; cv = cv->c_next)
- if (cv->c_layer->l_bottom == &p->w_layer)
- break;
- if (cv)
- Redisplay(0);
- }
-}
-
-static int
-WindowChangedCheck(s, what, hp)
-char *s;
-int what;
-int *hp;
-{
- int h = 0;
- int l;
- while(*s)
- {
- if (*s++ != (hp ? '%' : '\005'))
- continue;
- l = 0;
- while (*s >= '0' && *s <= '9')
- s++;
- if (*s == 'L')
- {
- s++;
- l = 0x100;
- }
- if (*s == 'h')
- h = 1;
- if (*s == what || ((*s | l) == what) || what == 'd')
- break;
- if (*s)
- s++;
- }
- if (hp)
- *hp = h;
- return *s ? 1 : 0;
-}
-
-void
-WindowChanged(p, what)
-struct win *p;
-int what;
-{
- int inwstr, inhstr, inlstr;
- int inwstrh = 0, inhstrh = 0, inlstrh = 0;
- int got, ox, oy;
- struct display *olddisplay = display;
- struct canvas *cv;
-
- inwstr = inhstr = 0;
-
- if (what == 'f')
- {
- WindowChanged((struct win *)0, 'w'|0x100);
- WindowChanged((struct win *)0, 'W'|0x100);
- }
-
- if (what)
- {
- inwstr = WindowChangedCheck(captionstring, what, &inwstrh);
- inhstr = WindowChangedCheck(hstatusstring, what, &inhstrh);
- inlstr = WindowChangedCheck(wliststr, what, &inlstrh);
- }
- else
- {
- inwstr = inhstr = 0;
- inlstr = 1;
- }
-
- if (p == 0)
- {
- for (display = displays; display; display = display->d_next)
- {
- ox = D_x;
- oy = D_y;
- for (cv = D_cvlist; cv; cv = cv->c_next)
- {
- if (inlstr || (inlstrh && p && p->w_hstatus && *p->w_hstatus && WindowChangedCheck(p->w_hstatus, what, (int *)0)))
- WListUpdatecv(cv, (struct win *)0);
- p = Layer2Window(cv->c_layer);
- if (inwstr || (inwstrh && p && p->w_hstatus && *p->w_hstatus && WindowChangedCheck(p->w_hstatus, what, (int *)0)))
- if (cv->c_ye + 1 < D_height)
- RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0);
- }
- p = D_fore;
- if (inhstr || (inhstrh && p && p->w_hstatus && *p->w_hstatus && WindowChangedCheck(p->w_hstatus, what, (int *)0)))
- RefreshHStatus();
- if (ox != -1 && ox != -1)
- GotoPos(ox, oy);
- }
- display = olddisplay;
- return;
- }
-
- if (p->w_hstatus && *p->w_hstatus && (inwstrh || inhstrh || inlstrh) && WindowChangedCheck(p->w_hstatus, what, (int *)0))
- {
- inwstr |= inwstrh;
- inhstr |= inhstrh;
- inlstr |= inlstrh;
- }
- if (!inwstr && !inhstr && !inlstr)
- return;
- for (display = displays; display; display = display->d_next)
- {
- got = 0;
- ox = D_x;
- oy = D_y;
- for (cv = D_cvlist; cv; cv = cv->c_next)
- {
- if (inlstr)
- WListUpdatecv(cv, p);
- if (Layer2Window(cv->c_layer) != p)
- continue;
- got = 1;
- if (inwstr && cv->c_ye + 1 < D_height)
- RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0);
- }
- if (got && inhstr && p == D_fore)
- RefreshHStatus();
- if (ox != -1 && ox != -1)
- GotoPos(ox, oy);
- }
- display = olddisplay;
-}
-
diff --git a/src/screen.c b/src/screen.c
deleted file mode 100644
index 70741df..0000000
--- a/src/screen.c
+++ /dev/null
@@ -1,3176 +0,0 @@
-/* Copyright (c) 1993-2002
- * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- * Copyright (c) 1987 Oliver Laumann
-#ifdef HAVE_BRAILLE
- * Modified by:
- * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu
- * Bill Barry barryb@dots.physics.orst.edu
- * Randy Lundquist randyl@dots.physics.orst.edu
- *
- * Modifications Copyright (c) 1995 by
- * Science Access Project, Oregon State University.
-#endif
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- ****************************************************************
- */
-
-#include <sys/types.h>
-#include <ctype.h>
-
-#include <fcntl.h>
-
-#ifdef sgi
-# include <sys/sysmacros.h>
-#endif
-
-#include <sys/stat.h>
-#ifndef sun
-# include <sys/ioctl.h>
-#endif
-
-#ifndef SIGINT
-# include <signal.h>
-#endif
-
-#include "config.h"
-
-#ifdef SVR4
-# include <sys/stropts.h>
-#endif
-
-#if defined(SYSV) && !defined(ISC)
-# include <sys/utsname.h>
-#endif
-
-#if defined(sequent) || defined(SVR4)
-# include <sys/resource.h>
-#endif /* sequent || SVR4 */
-
-#ifdef ISC
-# include <sys/tty.h>
-# include <sys/sioctl.h>
-# include <sys/pty.h>
-#endif /* ISC */
-
-#if (defined(AUX) || defined(_AUX_SOURCE)) && defined(POSIX)
-# include <compat.h>
-#endif
-#if defined(USE_LOCALE) || defined(ENCODINGS)
-# include <locale.h>
-#endif
-#if defined(HAVE_NL_LANGINFO) && defined(ENCODINGS)
-# include <langinfo.h>
-#endif
-
-#include "screen.h"
-#ifdef HAVE_BRAILLE
-# include "braille.h"
-#endif
-
-#include "patchlevel.h"
-
-/*
- * At the moment we only need the real password if the
- * builtin lock is used. Therefore disable SHADOWPW if
- * we do not really need it (kind of security thing).
- */
-#ifndef LOCK
-# undef SHADOWPW
-#endif
-
-#include <pwd.h>
-#ifdef SHADOWPW
-# include <shadow.h>
-#endif /* SHADOWPW */
-
-#include "logfile.h" /* islogfile, logfflush */
-
-#ifdef DEBUG
-FILE *dfp;
-#endif
-
-
-extern char Term[], screenterm[], **environ, Termcap[];
-int force_vt = 1;
-int VBellWait, MsgWait, MsgMinWait, SilenceWait;
-
-extern struct acluser *users;
-extern struct display *displays, *display;
-
-
-extern int visual_bell;
-#ifdef COPY_PASTE
-extern unsigned char mark_key_tab[];
-#endif
-extern char version[];
-extern char DefaultShell[];
-#ifdef ZMODEM
-extern char *zmodem_sendcmd;
-extern char *zmodem_recvcmd;
-#endif
-
-
-char *ShellProg;
-char *ShellArgs[2];
-
-extern struct NewWindow nwin_undef, nwin_default, nwin_options;
-struct backtick;
-
-static struct passwd *getpwbyname __P((char *, struct passwd *));
-static void SigChldHandler __P((void));
-static sigret_t SigChld __P(SIGPROTOARG);
-static sigret_t SigInt __P(SIGPROTOARG);
-static sigret_t CoreDump __P(SIGPROTOARG);
-static sigret_t FinitHandler __P(SIGPROTOARG);
-static void DoWait __P((void));
-static void serv_read_fn __P((struct event *, char *));
-static void serv_select_fn __P((struct event *, char *));
-static void logflush_fn __P((struct event *, char *));
-static void backtick_filter __P((struct backtick *));
-static void backtick_fn __P((struct event *, char *));
-static char *runbacktick __P((struct backtick *, int *, time_t));
-static int IsSymbol __P((char *, char *));
-static char *ParseChar __P((char *, char *));
-static int ParseEscape __P((char *));
-static char *pad_expand __P((char *, char *, int, int));
-#ifdef DEBUG
-static void fds __P((void));
-#endif
-
-int nversion; /* numerical version, used for secondary DA */
-
-/* the attacher */
-struct passwd *ppp;
-char *attach_tty;
-char *attach_term;
-char *LoginName;
-struct mode attach_Mode;
-
-char SockPath[MAXPATHLEN + 2 * MAXSTR];
-char *SockName; /* SockName is pointer in SockPath */
-char *SockMatch = NULL; /* session id command line argument */
-int ServerSocket = -1;
-struct event serv_read;
-struct event serv_select;
-struct event logflushev;
-
-char **NewEnv = NULL;
-
-char *RcFileName = NULL;
-char *home;
-
-char *screenlogfile; /* filename layout */
-int log_flush = 10; /* flush interval in seconds */
-int logtstamp_on = 0; /* tstamp disabled */
-char *logtstamp_string; /* stamp layout */
-int logtstamp_after = 120; /* first tstamp after 120s */
-char *hardcopydir = NULL;
-char *BellString;
-char *VisualBellString;
-char *ActivityString;
-#ifdef COPY_PASTE
-char *BufferFile;
-#endif
-#ifdef POW_DETACH
-char *PowDetachString;
-#endif
-char *hstatusstring;
-char *captionstring;
-char *timestring;
-char *wliststr;
-char *wlisttit;
-int auto_detach = 1;
-int iflag, rflag, dflag, lsflag, quietflag, wipeflag, xflag;
-int cmdflag;
-int adaptflag;
-
-#ifdef MULTIUSER
-char *multi;
-char *multi_home;
-int multi_uid;
-int own_uid;
-int multiattach;
-int tty_mode;
-int tty_oldmode = -1;
-#endif
-
-char HostName[MAXSTR];
-int MasterPid;
-int real_uid, real_gid, eff_uid, eff_gid;
-int default_startup;
-int ZombieKey_destroy, ZombieKey_resurrect;
-char *preselect = NULL; /* only used in Attach() */
-
-#ifdef UTF8
-char *screenencodings;
-#endif
-
-#ifdef NETHACK
-int nethackflag = 0;
-#endif
-int maxwin = MAXWIN;
-
-
-struct layer *flayer;
-struct win *fore;
-struct win *windows;
-struct win *console_window;
-
-
-
-/*
- * Do this last
- */
-#include "extern.h"
-
-char strnomem[] = "Out of memory.";
-
-
-static int InterruptPlease;
-static int GotSigChld;
-
-static int
-lf_secreopen(name, wantfd, l)
-char *name;
-int wantfd;
-struct logfile *l;
-{
- int got_fd;
-
- close(wantfd);
- if (((got_fd = secopen(name, O_WRONLY | O_CREAT | O_APPEND, 0666)) < 0) ||
- lf_move_fd(got_fd, wantfd) < 0)
- {
- logfclose(l);
- debug1("lf_secreopen: failed for %s\n", name);
- return -1;
- }
- l->st->st_ino = l->st->st_dev = 0;
- debug2("lf_secreopen: %d = %s\n", wantfd, name);
- return 0;
-}
-
-/********************************************************************/
-/********************************************************************/
-/********************************************************************/
-
-
-static struct passwd *
-getpwbyname(name, ppp)
-char *name;
-struct passwd *ppp;
-{
- int n;
-#ifdef SHADOWPW
- struct spwd *sss = NULL;
- static char *spw = NULL;
-#endif
-
- if (!ppp && !(ppp = getpwnam(name)))
- return NULL;
-
- /* Do password sanity check..., allow ##user for SUN_C2 security */
-#ifdef SHADOWPW
-pw_try_again:
-#endif
- n = 0;
- if (ppp->pw_passwd[0] == '#' && ppp->pw_passwd[1] == '#' &&
- strcmp(ppp->pw_passwd + 2, ppp->pw_name) == 0)
- n = 13;
- for (; n < 13; n++)
- {
- char c = ppp->pw_passwd[n];
- if (!(c == '.' || c == '/' || c == '$' ||
- (c >= '0' && c <= '9') ||
- (c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z')))
- break;
- }
-
-#ifdef SHADOWPW
- /* try to determine real password */
- if (n < 13 && sss == 0)
- {
- sss = getspnam(ppp->pw_name);
- if (sss)
- {
- if (spw)
- free(spw);
- ppp->pw_passwd = spw = SaveStr(sss->sp_pwdp);
- endspent(); /* this should delete all buffers ... */
- goto pw_try_again;
- }
- endspent(); /* this should delete all buffers ... */
- }
-#endif
- if (n < 13)
- ppp->pw_passwd = 0;
-#ifdef linux
- if (ppp->pw_passwd && strlen(ppp->pw_passwd) == 13 + 11)
- ppp->pw_passwd[13] = 0; /* beware of linux's long passwords */
-#endif
-
- return ppp;
-}
-
-
-int
-main(ac, av)
-int ac;
-char **av;
-{
- register int n;
- char *ap;
- char *av0;
- char socknamebuf[2 * MAXSTR];
- int mflag = 0;
- char *myname = (ac == 0) ? "screen" : av[0];
- char *SockDir;
- struct stat st;
-#ifdef _MODE_T /* (jw) */
- mode_t oumask;
-#else
- int oumask;
-#endif
-#if defined(SYSV) && !defined(ISC)
- struct utsname utsnam;
-#endif
- struct NewWindow nwin;
- int detached = 0; /* start up detached */
-#ifdef MULTIUSER
- char *sockp;
-#endif
-
-#if (defined(AUX) || defined(_AUX_SOURCE)) && defined(POSIX)
- setcompat(COMPAT_POSIX|COMPAT_BSDPROT); /* turn on seteuid support */
-#endif
-#if defined(sun) && defined(SVR4)
- {
- /* Solaris' login blocks SIGHUP! This is _very bad_ */
- sigset_t sset;
- sigemptyset(&sset);
- sigprocmask(SIG_SETMASK, &sset, 0);
- }
-#endif
-
- /*
- * First, close all unused descriptors
- * (otherwise, we might have problems with the select() call)
- */
- closeallfiles(0);
-#ifdef DEBUG
- opendebug(1, 0);
-#endif
- sprintf(version, "%d.%.2d.%.2d%s (%s) %s", REV, VERS,
- PATCHLEVEL, STATE, ORIGIN, DATE);
- nversion = REV * 10000 + VERS * 100 + PATCHLEVEL;
- debug2("-- screen debug started %s (%s)\n", *av, version);
-#ifdef POSIX
- debug("POSIX\n");
-#endif
-#ifdef TERMIO
- debug("TERMIO\n");
-#endif
-#ifdef SYSV
- debug("SYSV\n");
-#endif
-#ifdef SYSVSIGS
- debug("SYSVSIGS\n");
-#endif
-#ifdef NAMEDPIPE
- debug("NAMEDPIPE\n");
-#endif
-#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- debug("Window size changing enabled\n");
-#endif
-#ifdef HAVE_SETREUID
- debug("SETREUID\n");
-#endif
-#ifdef HAVE_SETEUID
- debug("SETEUID\n");
-#endif
-#ifdef hpux
- debug("hpux\n");
-#endif
-#ifdef USEBCOPY
- debug("USEBCOPY\n");
-#endif
-#ifdef UTMPOK
- debug("UTMPOK\n");
-#endif
-#ifdef LOADAV
- debug("LOADAV\n");
-#endif
-#ifdef NETHACK
- debug("NETHACK\n");
-#endif
-#ifdef TERMINFO
- debug("TERMINFO\n");
-#endif
-#ifdef SHADOWPW
- debug("SHADOWPW\n");
-#endif
-#ifdef NAME_MAX
- debug1("NAME_MAX = %d\n", NAME_MAX);
-#endif
-
- BellString = SaveStr("Bell in window %n");
- VisualBellString = SaveStr(" Wuff, Wuff!! ");
- ActivityString = SaveStr("Activity in window %n");
- screenlogfile = SaveStr("screenlog.%n");
- logtstamp_string = SaveStr("-- %n:%t -- time-stamp -- %M/%d/%y %c:%s --\n");
- hstatusstring = SaveStr("%h");
- captionstring = SaveStr("%3n %t");
- timestring = SaveStr("%c:%s %M %d %H%? %l%?");
- wlisttit = SaveStr("Num Name%=Flags");
- wliststr = SaveStr("%3n %t%=%f");
-#ifdef COPY_PASTE
- BufferFile = SaveStr(DEFAULT_BUFFERFILE);
-#endif
- ShellProg = NULL;
-#ifdef POW_DETACH
- PowDetachString = 0;
-#endif
- default_startup = (ac > 1) ? 0 : 1;
- adaptflag = 0;
- VBellWait = VBELLWAIT * 1000;
- MsgWait = MSGWAIT * 1000;
- MsgMinWait = MSGMINWAIT * 1000;
- SilenceWait = SILENCEWAIT;
-#ifdef HAVE_BRAILLE
- InitBraille();
-#endif
-#ifdef ZMODEM
- zmodem_sendcmd = SaveStr("!!! sz -vv -b ");
- zmodem_recvcmd = SaveStr("!!! rz -vv -b -E");
-#endif
-
-#ifdef COPY_PASTE
- CompileKeys((char *)0, 0, mark_key_tab);
-#endif
-#ifdef UTF8
- InitBuiltinTabs();
- screenencodings = SaveStr(SCREENENCODINGS);
-#endif
- nwin = nwin_undef;
- nwin_options = nwin_undef;
- strcpy(screenterm, "screen");
-
- logreopen_register(lf_secreopen);
-
- av0 = *av;
- /* if this is a login screen, assume -RR */
- if (*av0 == '-')
- {
- rflag = 4;
-#ifdef MULTI
- xflag = 1;
-#else
- dflag = 1;
-#endif
- ShellProg = SaveStr(DefaultShell); /* to prevent nasty circles */
- }
- while (ac > 0)
- {
- ap = *++av;
- if (--ac > 0 && *ap == '-')
- {
- if (ap[1] == '-' && ap[2] == 0)
- {
- av++;
- ac--;
- break;
- }
- if (ap[1] == '-' && !strcmp(ap, "--version"))
- Panic(0, "Screen version %s", version);
- if (ap[1] == '-' && !strcmp(ap, "--help"))
- exit_with_usage(myname, NULL, NULL);
- while (ap && *ap && *++ap)
- {
- switch (*ap)
- {
- case 'a':
- nwin_options.aflag = 1;
- break;
- case 'A':
- adaptflag = 1;
- break;
- case 'p': /* preselect */
- if (*++ap)
- preselect = ap;
- else
- {
- if (!--ac)
- exit_with_usage(myname, "Specify a window to preselect with -p", NULL);
- preselect = *++av;
- }
- ap = NULL;
- break;
-#ifdef HAVE_BRAILLE
- case 'B':
- bd.bd_start_braille = 1;
- break;
-#endif
- case 'c':
- if (*++ap)
- RcFileName = ap;
- else
- {
- if (--ac == 0)
- exit_with_usage(myname, "Specify an alternate rc-filename with -c", NULL);
- RcFileName = *++av;
- }
- ap = NULL;
- break;
- case 'e':
- if (!*++ap)
- {
- if (--ac == 0)
- exit_with_usage(myname, "Specify command characters with -e", NULL);
- ap = *++av;
- }
- if (ParseEscape(ap))
- Panic(0, "Two characters are required with -e option, not '%s'.", ap);
- ap = NULL;
- break;
- case 'f':
- ap++;
- switch (*ap++)
- {
- case 'n':
- case '0':
- nwin_options.flowflag = FLOW_NOW * 0;
- break;
- case '\0':
- ap--;
- /* FALLTHROUGH */
- case 'y':
- case '1':
- nwin_options.flowflag = FLOW_NOW * 1;
- break;
- case 'a':
- nwin_options.flowflag = FLOW_AUTOFLAG;
- break;
- default:
- exit_with_usage(myname, "Unknown flow option -%s", --ap);
- }
- break;
- case 'h':
- if (--ac == 0)
- exit_with_usage(myname, NULL, NULL);
- nwin_options.histheight = atoi(*++av);
- if (nwin_options.histheight < 0)
- exit_with_usage(myname, "-h: %s: negative scrollback size?", *av);
- break;
- case 'i':
- iflag = 1;
- break;
- case 't': /* title, the former AkA == -k */
- if (--ac == 0)
- exit_with_usage(myname, "Specify a new window-name with -t", NULL);
- nwin_options.aka = *++av;
- break;
- case 'l':
- ap++;
- switch (*ap++)
- {
- case 'n':
- case '0':
- nwin_options.lflag = 0;
- break;
- case '\0':
- ap--;
- /* FALLTHROUGH */
- case 'y':
- case '1':
- nwin_options.lflag = 1;
- break;
- case 'a':
- nwin_options.lflag = 3;
- break;
- case 's': /* -ls */
- case 'i': /* -list */
- lsflag = 1;
- if (ac > 1 && !SockMatch)
- {
- SockMatch = *++av;
- ac--;
- }
- ap = NULL;
- break;
- default:
- exit_with_usage(myname, "%s: Unknown suboption to -l", --ap);
- }
- break;
- case 'w':
- lsflag = 1;
- wipeflag = 1;
- if (ac > 1 && !SockMatch)
- {
- SockMatch = *++av;
- ac--;
- }
- break;
- case 'L':
- nwin_options.Lflag = 1;
- break;
- case 'm':
- mflag = 1;
- break;
- case 'O': /* to be (or not to be?) deleted. jw. */
- force_vt = 0;
- break;
- case 'T':
- if (--ac == 0)
- exit_with_usage(myname, "Specify terminal-type with -T", NULL);
- if (strlen(*++av) < 20)
- strcpy(screenterm, *av);
- else
- Panic(0, "-T: terminal name too long. (max. 20 char)");
- nwin_options.term = screenterm;
- break;
- case 'q':
- quietflag = 1;
- break;
- case 'r':
- case 'R':
-#ifdef MULTI
- case 'x':
-#endif
- if (ac > 1 && *av[1] != '-' && !SockMatch)
- {
- SockMatch = *++av;
- ac--;
- debug2("rflag=%d, SockMatch=%s\n", dflag, SockMatch);
- }
-#ifdef MULTI
- if (*ap == 'x')
- xflag = 1;
-#endif
- if (rflag)
- rflag = 2;
- rflag += (*ap == 'R') ? 2 : 1;
- break;
-#ifdef REMOTE_DETACH
- case 'd':
- dflag = 1;
- /* FALLTHROUGH */
- case 'D':
- if (!dflag)
- dflag = 2;
- if (ac == 2)
- {
- if (*av[1] != '-' && !SockMatch)
- {
- SockMatch = *++av;
- ac--;
- debug2("dflag=%d, SockMatch=%s\n", dflag, SockMatch);
- }
- }
- break;
-#endif
- case 's':
- if (--ac == 0)
- exit_with_usage(myname, "Specify shell with -s", NULL);
- if (ShellProg)
- free(ShellProg);
- ShellProg = SaveStr(*++av);
- debug1("ShellProg: '%s'\n", ShellProg);
- break;
- case 'S':
- if (!SockMatch)
- {
- if (--ac == 0)
- exit_with_usage(myname, "Specify session-name with -S", NULL);
- SockMatch = *++av;
- }
- if (!*SockMatch)
- exit_with_usage(myname, "Empty session-name?", NULL);
- break;
- case 'X':
- cmdflag = 1;
- break;
- case 'v':
- Panic(0, "Screen version %s", version);
- /* NOTREACHED */
-#ifdef UTF8
- case 'U':
- nwin_options.encoding = nwin_options.encoding == -1 ? UTF8 : 0;
- break;
-#endif
- default:
- exit_with_usage(myname, "Unknown option %s", --ap);
- }
- }
- }
- else
- break;
- }
-
- real_uid = getuid();
- real_gid = getgid();
- eff_uid = geteuid();
- eff_gid = getegid();
- if (eff_uid != real_uid)
- {
- /* if running with s-bit, we must install a special signal
- * handler routine that resets the s-bit, so that we get a
- * core file anyway.
- */
-#ifdef SIGBUS /* OOPS, linux has no bus errors! */
- signal(SIGBUS, CoreDump);
-#endif /* SIGBUS */
- signal(SIGSEGV, CoreDump);
- }
-
-#ifdef USE_LOCALE
- setlocale(LC_ALL, "");
-#endif
-#ifdef ENCODINGS
- if (nwin_options.encoding == -1)
- {
- /* ask locale if we should start in UTF-8 mode */
-# ifdef HAVE_NL_LANGINFO
-# ifndef USE_LOCALE
- setlocale(LC_CTYPE, "");
-# endif
- nwin_options.encoding = FindEncoding(nl_langinfo(CODESET));
- debug1("locale says encoding = %d\n", nwin_options.encoding);
-# else
-# ifdef UTF8
- char *s;
- if (((s = getenv("LC_ALL")) || (s = getenv("LC_CTYPE")) ||
- (s = getenv("LANG"))) && InStr(s, "UTF-8"))
- nwin_options.encoding = UTF8;
-# endif
- debug1("environment says encoding=%d\n", nwin_options.encoding);
-#endif
- }
-#endif
- if (SockMatch && strlen(SockMatch) >= MAXSTR)
- Panic(0, "Ridiculously long socketname - try again.");
- if (cmdflag && !rflag && !dflag && !xflag)
- xflag = 1;
- if (!cmdflag && dflag && mflag && !(rflag || xflag))
- detached = 1;
- nwin = nwin_options;
-#ifdef ENCODINGS
- nwin.encoding = nwin_undef.encoding; /* let screenrc overwrite it */
-#endif
- if (ac)
- nwin.args = av;
-
- /* make the write() calls return -1 on all errors */
-#ifdef SIGXFSZ
- /*
- * Ronald F. Guilmette, Oct 29 '94, bug-gnu-utils@prep.ai.mit.edu:
- * It appears that in System V Release 4, UNIX, if you are writing
- * an output file and you exceed the currently set file size limit,
- * you _don't_ just get the call to `write' returning with a
- * failure code. Rather, you get a signal called `SIGXFSZ' which,
- * if neither handled nor ignored, will cause your program to crash
- * with a core dump.
- */
- signal(SIGXFSZ, SIG_IGN);
-#endif /* SIGXFSZ */
-
-#ifdef SIGPIPE
- signal(SIGPIPE, SIG_IGN);
-#endif
-
- if (!ShellProg)
- {
- register char *sh;
-
- sh = getenv("SHELL");
- ShellProg = SaveStr(sh ? sh : DefaultShell);
- }
- ShellArgs[0] = ShellProg;
- home = getenv("HOME");
-
-#ifdef NETHACK
- if (!(nethackflag = (getenv("NETHACKOPTIONS") != NULL)))
- {
- char nethackrc[MAXPATHLEN];
-
- if (home && (strlen(home) < (MAXPATHLEN - 20)))
- {
- sprintf(nethackrc,"%s/.nethackrc", home);
- nethackflag = !access(nethackrc, F_OK);
- }
- }
-#endif
-
-#ifdef MULTIUSER
- own_uid = multi_uid = real_uid;
- if (SockMatch && (sockp = index(SockMatch, '/')))
- {
- if (eff_uid)
- Panic(0, "Must run suid root for multiuser support.");
- *sockp = 0;
- multi = SockMatch;
- SockMatch = sockp + 1;
- if (*multi)
- {
- struct passwd *mppp;
- if ((mppp = getpwnam(multi)) == (struct passwd *)0)
- Panic(0, "Cannot identify account '%s'.", multi);
- multi_uid = mppp->pw_uid;
- multi_home = SaveStr(mppp->pw_dir);
- if (strlen(multi_home) > MAXPATHLEN - 10)
- Panic(0, "home directory path too long");
-# ifdef MULTI
- /* always fake multi attach mode */
- if (rflag || lsflag)
- xflag = 1;
-# endif /* MULTI */
- detached = 0;
- multiattach = 1;
- }
- }
- if (SockMatch && *SockMatch == 0)
- SockMatch = 0;
-#endif /* MULTIUSER */
-
- if ((LoginName = getlogin()) && LoginName[0] != '\0')
- {
- if ((ppp = getpwnam(LoginName)) != (struct passwd *) 0)
- if ((int)ppp->pw_uid != real_uid)
- ppp = (struct passwd *) 0;
- }
- if (ppp == 0)
- {
- if ((ppp = getpwuid(real_uid)) == 0)
- {
- Panic(0, "getpwuid() can't identify your account!");
- exit(1);
- }
- LoginName = ppp->pw_name;
- }
- LoginName = SaveStr(LoginName);
-
- ppp = getpwbyname(LoginName, ppp);
-
-#if !defined(SOCKDIR) && defined(MULTIUSER)
- if (multi && !multiattach)
- {
- if (home && strcmp(home, ppp->pw_dir))
- Panic(0, "$HOME must match passwd entry for multiuser screens.");
- }
-#endif
-
- if (home == 0 || *home == '\0')
- home = ppp->pw_dir;
- if (strlen(LoginName) > 20)
- Panic(0, "LoginName too long - sorry.");
-#ifdef MULTIUSER
- if (multi && strlen(multi) > 20)
- Panic(0, "Screen owner name too long - sorry.");
-#endif
- if (strlen(home) > MAXPATHLEN - 25)
- Panic(0, "$HOME too long - sorry.");
-
- attach_tty = "";
- if (!detached && !lsflag && !cmdflag && !(dflag && !mflag && !rflag && !xflag))
- {
- /* ttyname implies isatty */
- if (!(attach_tty = ttyname(0)))
- Panic(0, "Must be connected to a terminal.");
- if (strlen(attach_tty) >= MAXPATHLEN)
- Panic(0, "TtyName too long - sorry.");
- if (stat(attach_tty, &st))
- Panic(errno, "Cannot access '%s'", attach_tty);
-#ifdef MULTIUSER
- tty_mode = (int)st.st_mode & 0777;
-#endif
- if ((n = secopen(attach_tty, O_RDWR | O_NONBLOCK, 0)) < 0)
- Panic(0, "Cannot open your terminal '%s' - please check.", attach_tty);
- close(n);
- debug1("attach_tty is %s\n", attach_tty);
- if ((attach_term = getenv("TERM")) == 0 || *attach_term == 0)
- Panic(0, "Please set a terminal type.");
- if (strlen(attach_term) > sizeof(D_termname) - 1)
- Panic(0, "$TERM too long - sorry.");
- GetTTY(0, &attach_Mode);
-#ifdef DEBUGGGGGGGGGGGGGGG
- DebugTTY(&attach_Mode);
-#endif /* DEBUG */
- }
-
-#ifdef _MODE_T
- oumask = umask(0); /* well, unsigned never fails? jw. */
-#else
- if ((oumask = (int)umask(0)) == -1)
- Panic(errno, "Cannot change umask to zero");
-#endif
- SockDir = getenv("SCREENDIR");
- if (SockDir)
- {
- if (strlen(SockDir) >= MAXPATHLEN - 1)
- Panic(0, "Ridiculously long $SCREENDIR - try again.");
-#ifdef MULTIUSER
- if (multi)
- Panic(0, "No $SCREENDIR with multi screens, please.");
-#endif
- }
-#ifdef MULTIUSER
- if (multiattach)
- {
-# ifndef SOCKDIR
- sprintf(SockPath, "%s/.screen", multi_home);
- SockDir = SockPath;
-# else
- SockDir = SOCKDIR;
- sprintf(SockPath, "%s/S-%s", SockDir, multi);
-# endif
- }
- else
-#endif
- {
-#ifndef SOCKDIR
- if (SockDir == 0)
- {
- sprintf(SockPath, "%s/.screen", home);
- SockDir = SockPath;
- }
-#endif
- if (SockDir)
- {
- if (access(SockDir, F_OK))
- {
- debug1("SockDir '%s' missing ...\n", SockDir);
- if (UserContext() > 0)
- {
- if (mkdir(SockDir, 0700))
- UserReturn(0);
- UserReturn(1);
- }
- if (UserStatus() <= 0)
- Panic(0, "Cannot make directory '%s'.", SockDir);
- }
- if (SockDir != SockPath)
- strcpy(SockPath, SockDir);
- }
-#ifdef SOCKDIR
- else
- {
- SockDir = SOCKDIR;
- if (lstat(SockDir, &st))
- {
- n = (eff_uid == 0 && (real_uid || eff_gid == real_gid)) ? 0755 :
- (eff_gid != real_gid) ? 0775 :
-#ifdef S_ISVTX
- 0777|S_ISVTX;
-#else
- 0777;
-#endif
- if (mkdir(SockDir, n) == -1)
- Panic(errno, "Cannot make directory '%s'", SockDir);
- }
- else
- {
- if (!S_ISDIR(st.st_mode))
- Panic(0, "'%s' must be a directory.", SockDir);
- if (eff_uid == 0 && real_uid && (int)st.st_uid != eff_uid)
- Panic(0, "Directory '%s' must be owned by root.", SockDir);
- n = (eff_uid == 0 && (real_uid || (st.st_mode & 0775) != 0775)) ? 0755 :
- (eff_gid == (int)st.st_gid && eff_gid != real_gid) ? 0775 :
- 0777;
- if (((int)st.st_mode & 0777) != n)
- Panic(0, "Directory '%s' must have mode %03o.", SockDir, n);
- }
- sprintf(SockPath, "%s/S-%s", SockDir, LoginName);
- if (access(SockPath, F_OK))
- {
- if (mkdir(SockPath, 0700) == -1)
- Panic(errno, "Cannot make directory '%s'", SockPath);
- (void) chown(SockPath, real_uid, real_gid);
- }
- }
-#endif
- }
-
- if (stat(SockPath, &st) == -1)
- Panic(errno, "Cannot access %s", SockPath);
- else
- if (!S_ISDIR(st.st_mode))
- Panic(0, "%s is not a directory.", SockPath);
-#ifdef MULTIUSER
- if (multi)
- {
- if ((int)st.st_uid != multi_uid)
- Panic(0, "%s is not the owner of %s.", multi, SockPath);
- }
- else
-#endif
- {
- if ((int)st.st_uid != real_uid)
- Panic(0, "You are not the owner of %s.", SockPath);
- }
- if ((st.st_mode & 0777) != 0700)
- Panic(0, "Directory %s must have mode 700.", SockPath);
- if (SockMatch && index(SockMatch, '/'))
- Panic(0, "Bad session name '%s'", SockMatch);
- SockName = SockPath + strlen(SockPath) + 1;
- *SockName = 0;
- (void) umask(oumask);
- debug2("SockPath: %s SockMatch: %s\n", SockPath, SockMatch ? SockMatch : "NULL");
-
-#if defined(SYSV) && !defined(ISC)
- if (uname(&utsnam) == -1)
- Panic(errno, "uname");
- strncpy(HostName, utsnam.nodename, sizeof(utsnam.nodename) < MAXSTR ? sizeof(utsnam.nodename) : MAXSTR - 1);
- HostName[sizeof(utsnam.nodename) < MAXSTR ? sizeof(utsnam.nodename) : MAXSTR - 1] = '\0';
-#else
- (void) gethostname(HostName, MAXSTR);
- HostName[MAXSTR - 1] = '\0';
-#endif
- if ((ap = index(HostName, '.')) != NULL)
- *ap = '\0';
-
- if (lsflag)
- {
- int i, fo, oth;
-
-#ifdef MULTIUSER
- if (multi)
- real_uid = multi_uid;
-#endif
- setgid(real_gid);
- setuid(real_uid);
- eff_uid = real_uid;
- eff_gid = real_gid;
- i = FindSocket((int *)NULL, &fo, &oth, SockMatch);
- if (quietflag)
- exit(8 + (fo ? ((oth || i) ? 2 : 1) : 0) + i);
- if (fo == 0)
- Panic(0, "No Sockets found in %s.\n", SockPath);
- Panic(0, "%d Socket%s in %s.\n", fo, fo > 1 ? "s" : "", SockPath);
- /* NOTREACHED */
- }
- signal(SIG_BYE, AttacherFinit); /* prevent races */
- if (cmdflag)
- {
- char *sty = 0;
-
- /* attach_tty is not mandatory */
- if ((attach_tty = ttyname(0)) == 0)
- attach_tty = "";
- if (strlen(attach_tty) >= MAXPATHLEN)
- Panic(0, "TtyName too long - sorry.");
- if (!*av)
- Panic(0, "Please specify a command.");
- setgid(real_gid);
- setuid(real_uid);
- eff_uid = real_uid;
- eff_gid = real_gid;
- if (!mflag && !SockMatch)
- {
- sty = getenv("STY");
- if (sty && *sty == 0)
- sty = 0;
- }
- SendCmdMessage(sty, SockMatch, av);
- exit(0);
- }
- else if (rflag || xflag)
- {
- debug("screen -r: - is there anybody out there?\n");
- if (Attach(MSG_ATTACH))
- {
- Attacher();
- /* NOTREACHED */
- }
-#ifdef MULTIUSER
- if (multiattach)
- Panic(0, "Can't create sessions of other users.");
-#endif
- debug("screen -r: backend not responding -- still crying\n");
- }
- else if (dflag && !mflag)
- {
- (void) Attach(MSG_DETACH);
- Msg(0, "[%s %sdetached.]\n", SockName, (dflag > 1 ? "power " : ""));
- eexit(0);
- /* NOTREACHED */
- }
- if (!SockMatch && !mflag)
- {
- register char *sty;
-
- if ((sty = getenv("STY")) != 0 && *sty != '\0')
- {
- setgid(real_gid);
- setuid(real_uid);
- eff_uid = real_uid;
- eff_gid = real_gid;
- nwin_options.args = av;
- SendCreateMsg(sty, &nwin);
- exit(0);
- /* NOTREACHED */
- }
- }
- nwin_compose(&nwin_default, &nwin_options, &nwin_default);
-
- if (!detached || dflag != 2)
- MasterPid = fork();
- else
- MasterPid = 0;
-
- switch (MasterPid)
- {
- case -1:
- Panic(errno, "fork");
- /* NOTREACHED */
- case 0:
- break;
- default:
- if (detached)
- exit(0);
- if (SockMatch)
- sprintf(socknamebuf, "%d.%s", MasterPid, SockMatch);
- else
- sprintf(socknamebuf, "%d.%s.%s", MasterPid, stripdev(attach_tty), HostName);
- for (ap = socknamebuf; *ap; ap++)
- if (*ap == '/')
- *ap = '-';
-#ifdef NAME_MAX
- if (strlen(socknamebuf) > NAME_MAX)
- socknamebuf[NAME_MAX] = 0;
-#endif
- sprintf(SockPath + strlen(SockPath), "/%s", socknamebuf);
- setgid(real_gid);
- setuid(real_uid);
- eff_uid = real_uid;
- eff_gid = real_gid;
- Attacher();
- /* NOTREACHED */
- }
-
- if (DefaultEsc == -1)
- DefaultEsc = Ctrl('a');
- if (DefaultMetaEsc == -1)
- DefaultMetaEsc = 'a';
-
- ap = av0 + strlen(av0) - 1;
- while (ap >= av0)
- {
- if (!strncmp("screen", ap, 6))
- {
- strncpy(ap, "SCREEN", 6); /* name this process "SCREEN-BACKEND" */
- break;
- }
- ap--;
- }
- if (ap < av0)
- *av0 = 'S';
-
-#ifdef DEBUG
- {
- char buf[256];
-
- if (dfp && dfp != stderr)
- fclose(dfp);
- sprintf(buf, "%s/SCREEN.%d", DEBUGDIR, (int)getpid());
- if ((dfp = fopen(buf, "w")) == NULL)
- dfp = stderr;
- else
- (void) chmod(buf, 0666);
- }
-#endif
- if (!detached)
- {
- /* reopen tty. must do this, because fd 0 may be RDONLY */
- if ((n = secopen(attach_tty, O_RDWR, 0)) < 0)
- Panic(0, "Cannot reopen '%s' - please check.", attach_tty);
- }
- else
- n = -1;
- freopen("/dev/null", "r", stdin);
- freopen("/dev/null", "w", stdout);
-
-#ifdef DEBUG
- if (dfp != stderr)
-#endif
- freopen("/dev/null", "w", stderr);
- debug("-- screen.back debug started\n");
-
- /*
- * This guarantees that the session owner is listed, even when we
- * start detached. From now on we should not refer to 'LoginName'
- * any more, use users->u_name instead.
- */
- if (UserAdd(LoginName, (char *)0, (struct acluser **)0) < 0)
- Panic(0, "Could not create user info");
- if (!detached)
- {
- if (MakeDisplay(LoginName, attach_tty, attach_term, n, getppid(), &attach_Mode) == 0)
- Panic(0, "Could not alloc display");
-#ifdef ENCODINGS
- D_encoding = nwin_options.encoding > 0 ? nwin_options.encoding : 0;
- debug1("D_encoding = %d\n", D_encoding);
-#endif
- }
-
- if (SockMatch)
- {
- /* user started us with -S option */
- sprintf(socknamebuf, "%d.%s", (int)getpid(), SockMatch);
- }
- else
- {
- sprintf(socknamebuf, "%d.%s.%s", (int)getpid(), stripdev(attach_tty),
- HostName);
- }
- for (ap = socknamebuf; *ap; ap++)
- if (*ap == '/')
- *ap = '-';
-#ifdef NAME_MAX
- if (strlen(socknamebuf) > NAME_MAX)
- {
- debug2("Socketname %s truncated to %d chars\n", socknamebuf, NAME_MAX);
- socknamebuf[NAME_MAX] = 0;
- }
-#endif
- sprintf(SockPath + strlen(SockPath), "/%s", socknamebuf);
-
- ServerSocket = MakeServerSocket();
- InitKeytab();
-#ifdef ETCSCREENRC
-# ifdef ALLOW_SYSSCREENRC
- if ((ap = getenv("SYSSCREENRC")))
- StartRc(ap);
- else
-# endif
- StartRc(ETCSCREENRC);
-#endif
- StartRc(RcFileName);
-# ifdef UTMPOK
-# ifndef UTNOKEEP
- InitUtmp();
-# endif /* UTNOKEEP */
-# endif /* UTMPOK */
- if (display)
- {
- if (InitTermcap(0, 0))
- {
- debug("Could not init termcap - exiting\n");
- fcntl(D_userfd, F_SETFL, 0); /* Flush sets FNBLOCK */
- freetty();
- if (D_userpid)
- Kill(D_userpid, SIG_BYE);
- eexit(1);
- }
- MakeDefaultCanvas();
- InitTerm(0);
-#ifdef UTMPOK
- RemoveLoginSlot();
-#endif
- }
- else
- MakeTermcap(1);
-#ifdef LOADAV
- InitLoadav();
-#endif /* LOADAV */
- MakeNewEnv();
- signal(SIGHUP, SigHup);
- signal(SIGINT, FinitHandler);
- signal(SIGQUIT, FinitHandler);
- signal(SIGTERM, FinitHandler);
-#ifdef BSDJOBS
- signal(SIGTTIN, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
-#endif
-
- if (display)
- {
- brktty(D_userfd);
- SetMode(&D_OldMode, &D_NewMode, D_flow, iflag);
- /* Note: SetMode must be called _before_ FinishRc. */
- SetTTY(D_userfd, &D_NewMode);
- if (fcntl(D_userfd, F_SETFL, FNBLOCK))
- Msg(errno, "Warning: NBLOCK fcntl failed");
- }
- else
- brktty(-1); /* just try */
- signal(SIGCHLD, SigChld);
-#ifdef ETCSCREENRC
-# ifdef ALLOW_SYSSCREENRC
- if ((ap = getenv("SYSSCREENRC")))
- FinishRc(ap);
- else
-# endif
- FinishRc(ETCSCREENRC);
-#endif
- FinishRc(RcFileName);
-
- debug2("UID %d EUID %d\n", (int)getuid(), (int)geteuid());
- if (windows == NULL)
- {
- debug("We open one default window, as screenrc did not specify one.\n");
- if (MakeWindow(&nwin) == -1)
- {
- Msg(0, "Sorry, could not find a PTY.");
- sleep(5);
- Finit(0);
- /* NOTREACHED */
- }
- }
-
-#ifdef HAVE_BRAILLE
- StartBraille();
-#endif
-
- if (display && default_startup)
- display_copyright();
- signal(SIGINT, SigInt);
- if (rflag && (rflag & 1) == 0)
- {
- Msg(0, "New screen...");
- rflag = 0;
- }
-
- serv_read.type = EV_READ;
- serv_read.fd = ServerSocket;
- serv_read.handler = serv_read_fn;
- evenq(&serv_read);
-
- serv_select.pri = -10;
- serv_select.type = EV_ALWAYS;
- serv_select.handler = serv_select_fn;
- evenq(&serv_select);
-
- logflushev.type = EV_TIMEOUT;
- logflushev.handler = logflush_fn;
-
- sched();
- /* NOTREACHED */
- return 0;
-}
-
-void
-WindowDied(p)
-struct win *p;
-{
- if (ZombieKey_destroy)
- {
- char buf[100], *s;
- time_t now;
-
- (void) time(&now);
- s = ctime(&now);
- if (s && *s)
- s[strlen(s) - 1] = '\0';
- debug3("window %d (%s) going into zombie state fd %d",
- p->w_number, p->w_title, p->w_ptyfd);
-#ifdef UTMPOK
- if (p->w_slot != (slot_t)0 && p->w_slot != (slot_t)-1)
- {
- RemoveUtmp(p);
- p->w_slot = 0; /* "detached" */
- }
-#endif
- CloseDevice(p);
-
- p->w_pid = 0;
- ResetWindow(p);
- /* p->w_y = p->w_bot; */
- p->w_y = MFindUsedLine(p, p->w_bot, 1);
- sprintf(buf, "\n\r=== Window terminated (%s) ===", s ? s : "?");
- WriteString(p, buf, strlen(buf));
- WindowChanged(p, 'f');
- }
- else
- KillWindow(p);
-#ifdef UTMPOK
- CarefulUtmp();
-#endif
-}
-
-static void
-SigChldHandler()
-{
- struct stat st;
-#ifdef DEBUG
- fds();
-#endif
- while (GotSigChld)
- {
- GotSigChld = 0;
- DoWait();
-#ifdef SYSVSIGS
- signal(SIGCHLD, SigChld);
-#endif
- }
- if (stat(SockPath, &st) == -1)
- {
- debug1("SigChldHandler: Yuck! cannot stat '%s'\n", SockPath);
- if (!RecoverSocket())
- {
- debug("SCREEN cannot recover from corrupt Socket, bye\n");
- Finit(1);
- }
- else
- debug1("'%s' reconstructed\n", SockPath);
- }
- else
- debug2("SigChldHandler: stat '%s' o.k. (%03o)\n", SockPath, (int)st.st_mode);
-}
-
-static sigret_t
-SigChld SIGDEFARG
-{
- debug("SigChld()\n");
- GotSigChld = 1;
- SIGRETURN;
-}
-
-sigret_t
-SigHup SIGDEFARG
-{
- /* Hangup all displays */
- while ((display = displays) != 0)
- Hangup();
- SIGRETURN;
-}
-
-/*
- * the backend's Interrupt handler
- * we cannot insert the intrc directly, as we never know
- * if fore is valid.
- */
-static sigret_t
-SigInt SIGDEFARG
-{
-#if HAZARDOUS
- char ibuf;
-
- debug("SigInt()\n");
- if (fore && displays)
- {
-# if defined(TERMIO) || defined(POSIX)
- ibuf = displays->d_OldMode.tio.c_cc[VINTR];
-# else
- ibuf = displays->d_OldMode.m_tchars.t_intrc;
-# endif
- fore->w_inlen = 0;
- write(fore->w_ptyfd, &ibuf, 1);
- }
-#else
- signal(SIGINT, SigInt);
- debug("SigInt() careful\n");
- InterruptPlease = 1;
-#endif
- SIGRETURN;
-}
-
-static sigret_t
-CoreDump SIGDEFARG
-{
- struct display *disp;
- char buf[80];
-
-#if defined(SYSVSIGS) && defined(SIGHASARG)
- signal(sigsig, SIG_IGN);
-#endif
- setgid(getgid());
- setuid(getuid());
- unlink("core");
-#ifdef SIGHASARG
- sprintf(buf, "\r\n[screen caught signal %d.%s]\r\n", sigsig,
-#else
- sprintf(buf, "\r\n[screen caught a fatal signal.%s]\r\n",
-#endif
-#if defined(SHADOWPW) && !defined(DEBUG) && !defined(DUMPSHADOW)
- ""
-#else /* SHADOWPW && !DEBUG */
- " (core dumped)"
-#endif /* SHADOWPW && !DEBUG */
- );
- for (disp = displays; disp; disp = disp->d_next)
- {
- fcntl(disp->d_userfd, F_SETFL, 0);
- SetTTY(disp->d_userfd, &D_OldMode);
- write(disp->d_userfd, buf, strlen(buf));
- Kill(disp->d_userpid, SIG_BYE);
- }
-#if defined(SHADOWPW) && !defined(DEBUG) && !defined(DUMPSHADOW)
- Kill(getpid(), SIGKILL);
- eexit(11);
-#else /* SHADOWPW && !DEBUG */
- abort();
-#endif /* SHADOWPW && !DEBUG */
- SIGRETURN;
-}
-
-static void
-DoWait()
-{
- register int pid;
- struct win *p, *next;
-#ifdef BSDWAIT
- union wait wstat;
-#else
- int wstat;
-#endif
-
-#ifdef BSDJOBS
-# ifndef BSDWAIT
- while ((pid = waitpid(-1, &wstat, WNOHANG | WUNTRACED)) > 0)
-# else
-# ifdef USE_WAIT2
- /*
- * From: rouilj@sni-usa.com (John Rouillard)
- * note that WUNTRACED is not documented to work, but it is defined in
- * /usr/include/sys/wait.h, so it may work
- */
- while ((pid = wait2(&wstat, WNOHANG | WUNTRACED )) > 0)
-# else /* USE_WAIT2 */
- while ((pid = wait3(&wstat, WNOHANG | WUNTRACED, (struct rusage *) 0)) > 0)
-# endif /* USE_WAIT2 */
-# endif
-#else /* BSDJOBS */
- while ((pid = wait(&wstat)) < 0)
- if (errno != EINTR)
- break;
- if (pid > 0)
-#endif /* BSDJOBS */
- {
- for (p = windows; p; p = next)
- {
- next = p->w_next;
- if (pid == p->w_pid)
- {
-#ifdef BSDJOBS
- if (WIFSTOPPED(wstat))
- {
- debug3("Window %d pid %d: WIFSTOPPED (sig %d)\n", p->w_number, p->w_pid, WSTOPSIG(wstat));
-#ifdef SIGTTIN
- if (WSTOPSIG(wstat) == SIGTTIN)
- {
- Msg(0, "Suspended (tty input)");
- continue;
- }
-#endif
-#ifdef SIGTTOU
- if (WSTOPSIG(wstat) == SIGTTOU)
- {
- Msg(0, "Suspended (tty output)");
- continue;
- }
-#endif
- /* Try to restart process */
- Msg(0, "Child has been stopped, restarting.");
- if (killpg(p->w_pid, SIGCONT))
- kill(p->w_pid, SIGCONT);
- }
- else
-#endif
- {
- WindowDied(p);
- }
- break;
- }
-#ifdef PSEUDOS
- if (p->w_pwin && pid == p->w_pwin->p_pid)
- {
- debug2("pseudo of win Nr %d died. pid == %d\n", p->w_number, p->w_pwin->p_pid);
- FreePseudowin(p);
- break;
- }
-#endif
- }
- if (p == 0)
- {
- debug1("pid %d not found - hope that's ok\n", pid);
- }
- }
-}
-
-
-static sigret_t
-FinitHandler SIGDEFARG
-{
-#ifdef SIGHASARG
- debug1("FinitHandler called, sig %d.\n", sigsig);
-#else
- debug("FinitHandler called.\n");
-#endif
- Finit(1);
- SIGRETURN;
-}
-
-void
-Finit(i)
-int i;
-{
- struct win *p, *next;
-
- signal(SIGCHLD, SIG_DFL);
- signal(SIGHUP, SIG_IGN);
- debug1("Finit(%d);\n", i);
- for (p = windows; p; p = next)
- {
- next = p->w_next;
- FreeWindow(p);
- }
- if (ServerSocket != -1)
- {
- debug1("we unlink(%s)\n", SockPath);
-#ifdef USE_SETEUID
- xseteuid(real_uid);
- xsetegid(real_gid);
-#endif
- (void) unlink(SockPath);
-#ifdef USE_SETEUID
- xseteuid(eff_uid);
- xsetegid(eff_gid);
-#endif
- }
- for (display = displays; display; display = display->d_next)
- {
- if (D_status)
- RemoveStatus();
- FinitTerm();
-#ifdef UTMPOK
- RestoreLoginSlot();
-#endif
- AddStr("[screen is terminating]\r\n");
- Flush();
- SetTTY(D_userfd, &D_OldMode);
- fcntl(D_userfd, F_SETFL, 0);
- freetty();
- Kill(D_userpid, SIG_BYE);
- }
- /*
- * we _cannot_ call eexit(i) here,
- * instead of playing with the Socket above. Sigh.
- */
- exit(i);
-}
-
-void
-eexit(e)
-int e;
-{
- debug("eexit\n");
- if (ServerSocket != -1)
- {
- debug1("we unlink(%s)\n", SockPath);
- setgid(real_gid);
- setuid(real_uid);
- (void) unlink(SockPath);
- }
- exit(e);
-}
-
-void
-Hangup()
-{
- if (display == 0)
- return;
- debug1("Hangup %x\n", display);
- if (D_userfd >= 0)
- {
- close(D_userfd);
- D_userfd = -1;
- }
- if (auto_detach || displays->d_next)
- Detach(D_HANGUP);
- else
- Finit(0);
-}
-
-/*
- * Detach now has the following modes:
- *D_DETACH SIG_BYE detach backend and exit attacher
- *D_HANGUP SIG_BYE detach backend and exit attacher
- *D_STOP SIG_STOP stop attacher (and detach backend)
- *D_REMOTE SIG_BYE remote detach -- reattach to new attacher
- *D_POWER SIG_POWER_BYE power detach -- attacher kills his parent
- *D_REMOTE_POWER SIG_POWER_BYE remote power detach -- both
- *D_LOCK SIG_LOCK lock the attacher
- * (jw)
- * we always remove our utmp slots. (even when "lock" or "stop")
- * Note: Take extra care here, we may be called by interrupt!
- */
-void
-Detach(mode)
-int mode;
-{
- int sign = 0, pid;
- struct canvas *cv;
- struct win *p;
-
- if (display == 0)
- return;
-
- signal(SIGHUP, SIG_IGN);
- debug1("Detach(%d)\n", mode);
- if (D_status)
- RemoveStatus();
- FinitTerm();
- if (!display)
- return;
- switch (mode)
- {
- case D_HANGUP:
- sign = SIG_BYE;
- break;
- case D_DETACH:
- AddStr("[detached]\r\n");
- sign = SIG_BYE;
- break;
-#ifdef BSDJOBS
- case D_STOP:
- sign = SIG_STOP;
- break;
-#endif
-#ifdef REMOTE_DETACH
- case D_REMOTE:
- AddStr("[remote detached]\r\n");
- sign = SIG_BYE;
- break;
-#endif
-#ifdef POW_DETACH
- case D_POWER:
- AddStr("[power detached]\r\n");
- if (PowDetachString)
- {
- AddStr(PowDetachString);
- AddStr("\r\n");
- }
- sign = SIG_POWER_BYE;
- break;
-#ifdef REMOTE_DETACH
- case D_REMOTE_POWER:
- AddStr("[remote power detached]\r\n");
- if (PowDetachString)
- {
- AddStr(PowDetachString);
- AddStr("\r\n");
- }
- sign = SIG_POWER_BYE;
- break;
-#endif
-#endif
- case D_LOCK:
- ClearAll();
- sign = SIG_LOCK;
- /* tell attacher to lock terminal with a lockprg. */
- break;
- }
-#ifdef UTMPOK
- if (displays->d_next == 0)
- {
- for (p = windows; p; p = p->w_next)
- {
- if (p->w_slot != (slot_t) -1 && !(p->w_lflag & 2))
- {
- RemoveUtmp(p);
- /*
- * Set the slot to 0 to get the window
- * logged in again.
- */
- p->w_slot = (slot_t) 0;
- }
- }
- }
- if (mode != D_HANGUP)
- RestoreLoginSlot();
-#endif
- if (displays->d_next == 0 && console_window)
- {
- if (TtyGrabConsole(console_window->w_ptyfd, 0, "detach"))
- {
- debug("could not release console - killing window\n");
- KillWindow(console_window);
- display = displays; /* restore display */
- }
- }
- if (D_fore)
- {
-#ifdef MULTIUSER
- ReleaseAutoWritelock(display, D_fore);
-#endif
- D_user->u_detachwin = D_fore->w_number;
- D_user->u_detachotherwin = D_other ? D_other->w_number : -1;
- }
- for (cv = D_cvlist; cv; cv = cv->c_next)
- {
- p = Layer2Window(cv->c_layer);
- SetCanvasWindow(cv, 0);
- if (p)
- WindowChanged(p, 'u');
- }
-
- pid = D_userpid;
- debug2("display: %#x displays: %#x\n", (unsigned int)display, (unsigned int)displays);
- FreeDisplay();
- if (displays == 0)
- /* Flag detached-ness */
- (void) chsock();
- /*
- * tell father what to do. We do that after we
- * freed the tty, thus getty feels more comfortable on hpux
- * if it was a power detach.
- */
- Kill(pid, sign);
- debug2("Detach: Signal %d to Attacher(%d)!\n", sign, pid);
- debug("Detach returns, we are successfully detached.\n");
- signal(SIGHUP, SigHup);
-}
-
-static int
-IsSymbol(e, s)
-char *e, *s;
-{
- register int l;
-
- l = strlen(s);
- return strncmp(e, s, l) == 0 && e[l] == '=';
-}
-
-void
-MakeNewEnv()
-{
- register char **op, **np;
- static char stybuf[MAXSTR];
-
- for (op = environ; *op; ++op)
- ;
- if (NewEnv)
- free((char *)NewEnv);
- NewEnv = np = (char **) malloc((unsigned) (op - environ + 7 + 1) * sizeof(char **));
- if (!NewEnv)
- Panic(0, strnomem);
- sprintf(stybuf, "STY=%s", strlen(SockName) <= MAXSTR - 5 ? SockName : "?");
- *np++ = stybuf; /* NewEnv[0] */
- *np++ = Term; /* NewEnv[1] */
- np++; /* room for SHELL */
-#ifdef TIOCSWINSZ
- np += 2; /* room for TERMCAP and WINDOW */
-#else
- np += 4; /* room for TERMCAP WINDOW LINES COLUMNS */
-#endif
-
- for (op = environ; *op; ++op)
- {
- if (!IsSymbol(*op, "TERM") && !IsSymbol(*op, "TERMCAP")
- && !IsSymbol(*op, "STY") && !IsSymbol(*op, "WINDOW")
- && !IsSymbol(*op, "SCREENCAP") && !IsSymbol(*op, "SHELL")
- && !IsSymbol(*op, "LINES") && !IsSymbol(*op, "COLUMNS")
- )
- *np++ = *op;
- }
- *np = 0;
-}
-
-void
-/*VARARGS2*/
-#if defined(USEVARARGS) && defined(__STDC__)
-Msg(int err, char *fmt, VA_DOTS)
-#else
-Msg(err, fmt, VA_DOTS)
-int err;
-char *fmt;
-VA_DECL
-#endif
-{
- VA_LIST(ap)
- char buf[MAXPATHLEN*2];
- char *p = buf;
-
- VA_START(ap, fmt);
- fmt = DoNLS(fmt);
- (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap));
- VA_END(ap);
- if (err)
- {
- p += strlen(p);
- *p++ = ':';
- *p++ = ' ';
- strncpy(p, strerror(err), buf + sizeof(buf) - p - 1);
- buf[sizeof(buf) - 1] = 0;
- }
- debug2("Msg('%s') (%#x);\n", buf, (unsigned int)display);
-
- if (display && displays)
- MakeStatus(buf);
- else if (displays)
- {
- for (display = displays; display; display = display->d_next)
- MakeStatus(buf);
- }
- else if (display)
- {
- /* no displays but a display - must have forked.
- * send message to backend!
- */
- char *tty = D_usertty;
- struct display *olddisplay = display;
- display = 0; /* only send once */
- SendErrorMsg(tty, buf);
- display = olddisplay;
- }
- else
- printf("%s\r\n", buf);
-}
-
-/*
- * Call FinitTerm for all displays, write a message to each and call eexit();
- */
-void
-/*VARARGS2*/
-#if defined(USEVARARGS) && defined(__STDC__)
-Panic(int err, char *fmt, VA_DOTS)
-#else
-Panic(err, fmt, VA_DOTS)
-int err;
-char *fmt;
-VA_DECL
-#endif
-{
- VA_LIST(ap)
- char buf[MAXPATHLEN*2];
- char *p = buf;
-
- VA_START(ap, fmt);
- fmt = DoNLS(fmt);
- (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap));
- VA_END(ap);
- if (err)
- {
- p += strlen(p);
- *p++ = ':';
- *p++ = ' ';
- strncpy(p, strerror(err), buf + sizeof(buf) - p - 1);
- buf[sizeof(buf) - 1] = 0;
- }
- debug3("Panic('%s'); display=%x displays=%x\n", buf, display, displays);
- if (displays == 0 && display == 0)
- printf("%s\r\n", buf);
- else if (displays == 0)
- {
- /* no displays but a display - must have forked.
- * send message to backend!
- */
- char *tty = D_usertty;
- display = 0;
- SendErrorMsg(tty, buf);
- sleep(2);
- _exit(1);
- }
- else
- for (display = displays; display; display = display->d_next)
- {
- if (D_status)
- RemoveStatus();
- FinitTerm();
- Flush();
-#ifdef UTMPOK
- RestoreLoginSlot();
-#endif
- SetTTY(D_userfd, &D_OldMode);
- fcntl(D_userfd, F_SETFL, 0);
- write(D_userfd, buf, strlen(buf));
- write(D_userfd, "\n", 1);
- freetty();
- if (D_userpid)
- Kill(D_userpid, SIG_BYE);
- }
-#ifdef MULTIUSER
- if (tty_oldmode >= 0)
- {
-# ifdef USE_SETEUID
- if (setuid(own_uid))
- xseteuid(own_uid); /* may be a loop. sigh. */
-# else
- setuid(own_uid);
-# endif
- debug1("Panic: changing back modes from %s\n", attach_tty);
- chmod(attach_tty, tty_oldmode);
- }
-#endif
- eexit(1);
-}
-
-
-/*
- * '^' is allowed as an escape mechanism for control characters. jw.
- *
- * Added time insertion using ideas/code from /\ndy Jones
- * (andy@lingua.cltr.uq.OZ.AU) - thanks a lot!
- *
- */
-
-#ifndef USE_LOCALE
-static const char days[] = "SunMonTueWedThuFriSat";
-static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
-#endif
-
-static char winmsg_buf[MAXSTR];
-#define MAX_WINMSG_REND 16 /* rendition changes */
-static int winmsg_rend[MAX_WINMSG_REND];
-static int winmsg_rendpos[MAX_WINMSG_REND];
-static int winmsg_numrend;
-
-static char *
-pad_expand(buf, p, numpad, padlen)
-char *buf;
-char *p;
-int numpad;
-int padlen;
-{
- char *pn, *pn2;
- int i, r;
-
- padlen = padlen - (p - buf); /* space for rent */
- if (padlen < 0)
- padlen = 0;
- pn2 = pn = p + padlen;
- r = winmsg_numrend;
- while (p >= buf)
- {
- if (r && p - buf == winmsg_rendpos[r - 1])
- {
- winmsg_rendpos[--r] = pn - buf;
- continue;
- }
- *pn-- = *p;
- if (*p-- == 127)
- {
- pn[1] = ' ';
- i = numpad > 0 ? (padlen + numpad - 1) / numpad : 0;
- padlen -= i;
- while (i-- > 0)
- *pn-- = ' ';
- numpad--;
- }
- }
- return pn2;
-}
-
-struct backtick {
- struct backtick *next;
- int num;
- int tick;
- int lifespan;
- time_t bestbefore;
- char result[MAXSTR];
- char **cmdv;
- struct event ev;
- char *buf;
- int bufi;
-};
-
-struct backtick *backticks;
-
-static void
-backtick_filter(bt)
-struct backtick *bt;
-{
- char *p, *q;
- int c;
-
- for (p = q = bt->result; (c = (unsigned char)*p++) != 0;)
- {
- if (c == '\t')
- c = ' ';
- if (c >= ' ' || c == '\005')
- *q++ = c;
- }
- *q = 0;
-}
-
-static void
-backtick_fn(ev, data)
-struct event *ev;
-char *data;
-{
- struct backtick *bt;
- int i, j, k, l;
-
- bt = (struct backtick *)data;
- debug1("backtick_fn for #%d\n", bt->num);
- i = bt->bufi;
- l = read(ev->fd, bt->buf + i, MAXSTR - i);
- if (l <= 0)
- {
- debug1("EOF on backtick #%d\n", bt->num);
- evdeq(ev);
- close(ev->fd);
- ev->fd = -1;
- return;
- }
- debug1("read %d bytes\n", l);
- i += l;
- for (j = 0; j < l; j++)
- if (bt->buf[i - j - 1] == '\n')
- break;
- if (j < l)
- {
- for (k = i - j - 2; k >= 0; k--)
- if (bt->buf[k] == '\n')
- break;
- k++;
- bcopy(bt->buf + k, bt->result, i - j - k);
- bt->result[i - j - k - 1] = 0;
- backtick_filter(bt);
- WindowChanged(0, '`');
- }
- if (j == l && i == MAXSTR)
- {
- j = MAXSTR/2;
- l = j + 1;
- }
- if (j < l)
- {
- if (j)
- bcopy(bt->buf + i - j, bt->buf, j);
- i = j;
- }
- bt->bufi = i;
-}
-
-void
-setbacktick(num, lifespan, tick, cmdv)
-int num;
-int lifespan;
-int tick;
-char **cmdv;
-{
- struct backtick **btp, *bt;
- char **v;
-
- debug1("setbacktick called for backtick #%d\n", num);
- for (btp = &backticks; (bt = *btp) != 0; btp = &bt->next)
- if (bt->num == num)
- break;
- if (!bt && !cmdv)
- return;
- if (bt)
- {
- for (v = bt->cmdv; *v; v++)
- free(*v);
- free(bt->cmdv);
- if (bt->buf)
- free(bt->buf);
- if (bt->ev.fd >= 0)
- close(bt->ev.fd);
- evdeq(&bt->ev);
- }
- if (bt && !cmdv)
- {
- *btp = bt->next;
- free(bt);
- return;
- }
- if (!bt)
- {
- bt = (struct backtick *)malloc(sizeof *bt);
- if (!bt)
- {
- Msg(0, strnomem);
- return;
- }
- bzero(bt, sizeof(*bt));
- bt->next = 0;
- *btp = bt;
- }
- bt->num = num;
- bt->tick = tick;
- bt->lifespan = lifespan;
- bt->bestbefore = 0;
- bt->result[0] = 0;
- bt->buf = 0;
- bt->bufi = 0;
- bt->cmdv = cmdv;
- bt->ev.fd = -1;
- if (bt->tick == 0 && bt->lifespan == 0)
- {
- debug("setbacktick: continuous mode\n");
- bt->buf = (char *)malloc(MAXSTR);
- if (bt->buf == 0)
- {
- Msg(0, strnomem);
- setbacktick(num, 0, 0, (char **)0);
- return;
- }
- bt->ev.type = EV_READ;
- bt->ev.fd = readpipe(bt->cmdv);
- bt->ev.handler = backtick_fn;
- bt->ev.data = (char *)bt;
- if (bt->ev.fd >= 0)
- evenq(&bt->ev);
- }
-}
-
-static char *
-runbacktick(bt, tickp, now)
-struct backtick *bt;
-int *tickp;
-time_t now;
-{
- int f, i, l, j;
- time_t now2;
-
- debug1("runbacktick called for backtick #%d\n", bt->num);
- if (bt->tick && (!*tickp || bt->tick < *tickp))
- *tickp = bt->tick;
- if ((bt->lifespan == 0 && bt->tick == 0) || now < bt->bestbefore)
- {
- debug1("returning old result (%d)\n", bt->lifespan);
- return bt->result;
- }
- f = readpipe(bt->cmdv);
- if (f == -1)
- return bt->result;
- i = 0;
- while ((l = read(f, bt->result + i, sizeof(bt->result) - i)) > 0)
- {
- debug1("runbacktick: read %d bytes\n", l);
- i += l;
- for (j = 1; j < l; j++)
- if (bt->result[i - j - 1] == '\n')
- break;
- if (j == l && i == sizeof(bt->result))
- {
- j = sizeof(bt->result) / 2;
- l = j + 1;
- }
- if (j < l)
- {
- bcopy(bt->result + i - j, bt->result, j);
- i = j;
- }
- }
- close(f);
- bt->result[sizeof(bt->result) - 1] = '\n';
- if (i && bt->result[i - 1] == '\n')
- i--;
- debug1("runbacktick: finished, %d bytes\n", i);
- bt->result[i] = 0;
- backtick_filter(bt);
- (void)time(&now2);
- bt->bestbefore = now2 + bt->lifespan;
- return bt->result;
-}
-
-char *
-MakeWinMsgEv(str, win, esc, padlen, ev, rec)
-char *str;
-struct win *win;
-int esc;
-int padlen;
-struct event *ev;
-int rec;
-{
- static int tick;
- char *s = str;
- register char *p = winmsg_buf;
- register int ctrl;
- struct timeval now;
- struct tm *tm;
- int l, i, r;
- int num;
- int zeroflg;
- int longflg;
- int minusflg;
- int plusflg;
- int qmflag = 0, omflag = 0, qmnumrend = 0;
- char *qmpos = 0;
- int numpad = 0;
- int lastpad = 0;
- int truncpos = -1;
- int truncper = 0;
- int trunclong = 0;
- struct backtick *bt;
-
- if (winmsg_numrend >= 0)
- winmsg_numrend = 0;
- else
- winmsg_numrend = -winmsg_numrend;
-
- tick = 0;
- tm = 0;
- ctrl = 0;
- gettimeofday(&now, NULL);
- for (; *s && (l = winmsg_buf + MAXSTR - 1 - p) > 0; s++, p++)
- {
- *p = *s;
- if (ctrl)
- {
- ctrl = 0;
- if (*s != '^' && *s >= 64)
- *p &= 0x1f;
- continue;
- }
- if (*s != esc)
- {
- if (esc == '%')
- {
- switch (*s)
- {
-#if 0
- case '~':
- *p = BELL;
- break;
-#endif
- case '^':
- ctrl = 1;
- *p-- = '^';
- break;
- default:
- break;
- }
- }
- continue;
- }
- if (*++s == esc) /* double escape ? */
- continue;
- if ((plusflg = *s == '+') != 0)
- s++;
- if ((minusflg = *s == '-') != 0)
- s++;
- if ((zeroflg = *s == '0') != 0)
- s++;
- num = 0;
- while(*s >= '0' && *s <= '9')
- num = num * 10 + (*s++ - '0');
- if ((longflg = *s == 'L') != 0)
- s++;
- switch (*s)
- {
- case '?':
- p--;
- if (qmpos)
- {
- if ((!qmflag && !omflag) || omflag == 1)
- {
- p = qmpos;
- if (qmnumrend < winmsg_numrend)
- winmsg_numrend = qmnumrend;
- }
- qmpos = 0;
- break;
- }
- qmpos = p;
- qmnumrend = winmsg_numrend;
- qmflag = omflag = 0;
- break;
- case ':':
- p--;
- if (!qmpos)
- break;
- if (qmflag && omflag != 1)
- {
- omflag = 1;
- qmpos = p;
- qmnumrend = winmsg_numrend;
- }
- else
- {
- p = qmpos;
- if (qmnumrend < winmsg_numrend)
- winmsg_numrend = qmnumrend;
- omflag = -1;
- }
- break;
- case 'd': case 'D': case 'm': case 'M': case 'y': case 'Y':
- case 'a': case 'A': case 's': case 'c': case 'C':
- if (l < 4)
- break;
- if (tm == 0)
- {
- time_t nowsec = now.tv_sec;
- tm = localtime(&nowsec);
- }
- qmflag = 1;
- if (!tick || tick > 3600)
- tick = 3600;
- switch (*s)
- {
- case 'd':
- sprintf(p, "%02d", tm->tm_mday % 100);
- break;
- case 'D':
-#ifdef USE_LOCALE
- strftime(p, l, (longflg ? "%A" : "%a"), tm);
-#else
- sprintf(p, "%3.3s", days + 3 * tm->tm_wday);
-#endif
- break;
- case 'm':
- sprintf(p, "%02d", tm->tm_mon + 1);
- break;
- case 'M':
-#ifdef USE_LOCALE
- strftime(p, l, (longflg ? "%B" : "%b"), tm);
-#else
- sprintf(p, "%3.3s", months + 3 * tm->tm_mon);
-#endif
- break;
- case 'y':
- sprintf(p, "%02d", tm->tm_year % 100);
- break;
- case 'Y':
- sprintf(p, "%04d", tm->tm_year + 1900);
- break;
- case 'a':
- sprintf(p, tm->tm_hour >= 12 ? "pm" : "am");
- break;
- case 'A':
- sprintf(p, tm->tm_hour >= 12 ? "PM" : "AM");
- break;
- case 's':
- sprintf(p, "%02d", tm->tm_sec);
- tick = 1;
- break;
- case 'c':
- sprintf(p, zeroflg ? "%02d:%02d" : "%2d:%02d", tm->tm_hour, tm->tm_min);
- if (!tick || tick > 60)
- tick = 60;
- break;
- case 'C':
- sprintf(p, zeroflg ? "%02d:%02d" : "%2d:%02d", (tm->tm_hour + 11) % 12 + 1, tm->tm_min);
- if (!tick || tick > 60)
- tick = 60;
- break;
- default:
- break;
- }
- p += strlen(p) - 1;
- break;
- case 'l':
-#ifdef LOADAV
- *p = 0;
- if (l > 20)
- AddLoadav(p);
- if (*p)
- {
- qmflag = 1;
- p += strlen(p) - 1;
- }
- else
- *p = '?';
- if (!tick || tick > 60)
- tick = 60;
-#else
- *p = '?';
-#endif
- p += strlen(p) - 1;
- break;
- case '`':
- case 'h':
- if (rec >= 10 || (*s == 'h' && (win == 0 || win->w_hstatus == 0 || *win->w_hstatus == 0)))
- {
- p--;
- break;
- }
- if (*s == '`')
- {
- for (bt = backticks; bt; bt = bt->next)
- if (bt->num == num)
- break;
- if (bt == 0)
- {
- p--;
- break;
- }
- }
- {
- char savebuf[sizeof(winmsg_buf)];
- int oldtick = tick;
- int oldnumrend = winmsg_numrend;
-
- *p = 0;
- strcpy(savebuf, winmsg_buf);
- winmsg_numrend = -winmsg_numrend;
- MakeWinMsgEv(*s == 'h' ? win->w_hstatus : runbacktick(bt, &oldtick, now.tv_sec), win, '\005', 0, (struct event *)0, rec + 1);
- debug2("oldtick=%d tick=%d\n", oldtick, tick);
- if (!tick || oldtick < tick)
- tick = oldtick;
- if ((int)strlen(winmsg_buf) < l)
- strcat(savebuf, winmsg_buf);
- strcpy(winmsg_buf, savebuf);
- while (oldnumrend < winmsg_numrend)
- winmsg_rendpos[oldnumrend++] += p - winmsg_buf;
- if (*p)
- qmflag = 1;
- p += strlen(p) - 1;
- }
- break;
- case 'w':
- case 'W':
- {
- struct win *oldfore = 0;
- char *ss;
-
- if (display)
- {
- oldfore = D_fore;
- D_fore = win;
- }
- ss = AddWindows(p, l - 1, (*s == 'w' ? 0 : 1) | (longflg ? 0 : 2) | (plusflg ? 4 : 0), win ? win->w_number : -1);
- if (minusflg)
- *ss = 0;
- if (display)
- D_fore = oldfore;
- }
- if (*p)
- qmflag = 1;
- p += strlen(p) - 1;
- break;
- case 'u':
- *p = 0;
- if (win)
- AddOtherUsers(p, l - 1, win);
- if (*p)
- qmflag = 1;
- p += strlen(p) - 1;
- break;
- case 'f':
- *p = 0;
- if (win)
- AddWindowFlags(p, l - 1, win);
- if (*p)
- qmflag = 1;
- p += strlen(p) - 1;
- break;
- case 't':
- *p = 0;
- if (win && (int)strlen(win->w_title) < l)
- {
- strcpy(p, win->w_title);
- if (*p)
- qmflag = 1;
- }
- p += strlen(p) - 1;
- break;
- case '{':
- {
- char rbuf[128];
- s++;
- for (i = 0; i < 127; i++)
- if (s[i] && s[i] != '}')
- rbuf[i] = s[i];
- else
- break;
- if (s[i] == '}' && winmsg_numrend < MAX_WINMSG_REND)
- {
- r = -1;
- rbuf[i] = 0;
- debug1("MakeWinMsg attrcolor %s\n", rbuf);
- if (i != 1 || rbuf[0] != '-')
- r = ParseAttrColor(rbuf, (char *)0, 0);
- if (r != -1 || (i == 1 && rbuf[0] == '-'))
- {
- winmsg_rend[winmsg_numrend] = r;
- winmsg_rendpos[winmsg_numrend] = p - winmsg_buf;
- winmsg_numrend++;
- }
- }
- s += i;
- p--;
- }
- break;
- case 'H':
- *p = 0;
- if ((int)strlen(HostName) < l)
- {
- strcpy(p, HostName);
- if (*p)
- qmflag = 1;
- }
- p += strlen(p) - 1;
- break;
- case 'F':
- p--;
- /* small hack */
- if (display && ((ev && ev == &D_forecv->c_captev) || (!ev && win && win == D_fore)))
- qmflag = 1;
- break;
- case '>':
- truncpos = p - winmsg_buf;
- truncper = num > 100 ? 100 : num;
- trunclong = longflg;
- p--;
- break;
- case '=':
- case '<':
- *p = ' ';
- if (num || zeroflg || plusflg || longflg || (*s != '='))
- {
- /* expand all pads */
- if (minusflg)
- {
- num = (plusflg ? lastpad : padlen) - num;
- if (!plusflg && padlen == 0)
- num = p - winmsg_buf;
- plusflg = 0;
- }
- else if (!zeroflg)
- {
- if (*s != '=' && num == 0 && !plusflg)
- num = 100;
- if (num > 100)
- num = 100;
- if (padlen == 0)
- num = p - winmsg_buf;
- else
- num = (padlen - (plusflg ? lastpad : 0)) * num / 100;
- }
- if (num < 0)
- num = 0;
- if (plusflg)
- num += lastpad;
- if (num > MAXSTR - 1)
- num = MAXSTR - 1;
- if (numpad)
- p = pad_expand(winmsg_buf, p, numpad, num);
- numpad = 0;
- if (p - winmsg_buf > num && !longflg)
- {
- int left, trunc;
-
- if (truncpos == -1)
- {
- truncpos = lastpad;
- truncper = 0;
- }
- trunc = lastpad + truncper * (num - lastpad) / 100;
- if (trunc > num)
- trunc = num;
- if (trunc < lastpad)
- trunc = lastpad;
- left = truncpos - trunc;
- if (left > p - winmsg_buf - num)
- left = p - winmsg_buf - num;
- debug1("lastpad = %d, ", lastpad);
- debug3("truncpos = %d, trunc = %d, left = %d\n", truncpos, trunc, left);
- if (left > 0)
- {
- if (left + lastpad > p - winmsg_buf)
- left = p - winmsg_buf - lastpad;
- if (p - winmsg_buf - lastpad - left > 0)
- bcopy(winmsg_buf + lastpad + left, winmsg_buf + lastpad, p - winmsg_buf - lastpad - left);
- p -= left;
- r = winmsg_numrend;
- while (r && winmsg_rendpos[r - 1] > lastpad)
- {
- r--;
- winmsg_rendpos[r] -= left;
- if (winmsg_rendpos[r] < lastpad)
- winmsg_rendpos[r] = lastpad;
- }
- if (trunclong)
- {
- if (p - winmsg_buf > lastpad)
- winmsg_buf[lastpad] = '.';
- if (p - winmsg_buf > lastpad + 1)
- winmsg_buf[lastpad + 1] = '.';
- if (p - winmsg_buf > lastpad + 2)
- winmsg_buf[lastpad + 2] = '.';
- }
- }
- if (p - winmsg_buf > num)
- {
- p = winmsg_buf + num;
- if (trunclong)
- {
- if (num - 1 >= lastpad)
- p[-1] = '.';
- if (num - 2 >= lastpad)
- p[-2] = '.';
- if (num - 3 >= lastpad)
- p[-3] = '.';
- }
- r = winmsg_numrend;
- while (r && winmsg_rendpos[r - 1] > num)
- winmsg_rendpos[--r] = num;
- }
- truncpos = -1;
- trunclong = 0;
- if (lastpad > p - winmsg_buf)
- lastpad = p - winmsg_buf;
- debug1("lastpad now %d\n", lastpad);
- }
- if (*s == '=')
- {
- while (p - winmsg_buf < num)
- *p++ = ' ';
- lastpad = p - winmsg_buf;
- truncpos = -1;
- trunclong = 0;
- debug1("lastpad2 now %d\n", lastpad);
- }
- p--;
- }
- else if (padlen)
- {
- *p = 127; /* internal pad representation */
- numpad++;
- }
- break;
- case 'n':
- s++;
- /* FALLTHROUGH */
- default:
- s--;
- if (l > 10 + num)
- {
- if (num == 0)
- num = 1;
- if (!win)
- sprintf(p, "%*s", num, num > 1 ? "--" : "-");
- else
- sprintf(p, "%*d", num, win->w_number);
- qmflag = 1;
- p += strlen(p) - 1;
- }
- break;
- }
- }
- if (qmpos && !qmflag)
- p = qmpos + 1;
- *p = '\0';
- if (numpad)
- {
- if (padlen > MAXSTR - 1)
- padlen = MAXSTR - 1;
- p = pad_expand(winmsg_buf, p, numpad, padlen);
- }
- if (ev)
- {
- evdeq(ev); /* just in case */
- ev->timeout.tv_sec = 0;
- ev->timeout.tv_usec = 0;
- }
- if (ev && tick)
- {
- now.tv_usec = 100000;
- if (tick == 1)
- now.tv_sec++;
- else
- now.tv_sec += tick - (now.tv_sec % tick);
- ev->timeout = now;
- debug2("NEW timeout %d %d\n", ev->timeout.tv_sec, tick);
- }
- return winmsg_buf;
-}
-
-char *
-MakeWinMsg(s, win, esc)
-char *s;
-struct win *win;
-int esc;
-{
- return MakeWinMsgEv(s, win, esc, 0, (struct event *)0, 0);
-}
-
-int
-PutWinMsg(s, start, max)
-char *s;
-int start, max;
-{
- int i, p, l, r, n;
- struct mchar rend;
- struct mchar rendstack[MAX_WINMSG_REND];
- int rendstackn = 0;
-
- if (s != winmsg_buf)
- return 0;
- rend = D_rend;
- p = 0;
- l = strlen(s);
- debug2("PutWinMsg %s start attr %x\n", s, rend.attr);
- for (i = 0; i < winmsg_numrend && max > 0; i++)
- {
- if (p > winmsg_rendpos[i] || winmsg_rendpos[i] > l)
- break;
- if (p < winmsg_rendpos[i])
- {
- n = winmsg_rendpos[i] - p;
- if (n > max)
- n = max;
- max -= n;
- p += n;
- while(n-- > 0)
- {
- if (start-- > 0)
- s++;
- else
- PUTCHARLP(*s++);
- }
- }
- r = winmsg_rend[i];
- if (r == -1)
- {
- if (rendstackn > 0)
- rend = rendstack[--rendstackn];
- }
- else
- {
- rendstack[rendstackn++] = rend;
- ApplyAttrColor(r, &rend);
- }
- SetRendition(&rend);
- }
- if (p < l)
- {
- n = l - p;
- if (n > max)
- n = max;
- while(n-- > 0)
- {
- if (start-- > 0)
- s++;
- else
- PUTCHARLP(*s++);
- }
- }
- return 1;
-}
-
-
-#ifdef DEBUG
-static void
-fds1(i, j)
-int i, j;
-{
- while (i < j)
- {
- debug1("%d ", i);
- i++;
- }
- if ((j = open("/dev/null", 0)) >= 0)
- {
- fds1(i + 1, j);
- close(j);
- }
- else
- {
- while (dup(++i) < 0 && errno != EBADF)
- debug1("%d ", i);
- debug1(" [%d]\n", i);
- }
-}
-
-static void
-fds()
-{
- debug("fds: ");
- fds1(-1, -1);
-}
-#endif
-
-static void
-serv_read_fn(ev, data)
-struct event *ev;
-char *data;
-{
- debug("Knock - knock!\n");
- ReceiveMsg();
-}
-
-static void
-serv_select_fn(ev, data)
-struct event *ev;
-char *data;
-{
- struct win *p;
-
- debug("serv_select_fn called\n");
- /* XXX: messages?? */
- if (GotSigChld)
- {
- SigChldHandler();
- }
- if (InterruptPlease)
- {
- debug("Backend received interrupt\n");
- /* This approach is rather questionable in a multi-display
- * environment */
- if (fore && displays)
- {
-#if defined(TERMIO) || defined(POSIX)
- char ibuf = displays->d_OldMode.tio.c_cc[VINTR];
-#else
- char ibuf = displays->d_OldMode.m_tchars.t_intrc;
-#endif
-#ifdef PSEUDOS
- write(W_UWP(fore) ? fore->w_pwin->p_ptyfd : fore->w_ptyfd,
- &ibuf, 1);
- debug1("Backend wrote interrupt to %d", fore->w_number);
- debug1("%s\n", W_UWP(fore) ? " (pseudowin)" : "");
-#else
- write(fore->w_ptyfd, &ibuf, 1);
- debug1("Backend wrote interrupt to %d\n", fore->w_number);
-#endif
- }
- InterruptPlease = 0;
- }
-
- for (p = windows; p; p = p->w_next)
- {
- if (p->w_bell == BELL_FOUND || p->w_bell == BELL_VISUAL)
- {
- struct canvas *cv;
- int visual = p->w_bell == BELL_VISUAL || visual_bell;
- p->w_bell = BELL_ON;
- for (display = displays; display; display = display->d_next)
- {
- for (cv = D_cvlist; cv; cv = cv->c_next)
- if (cv->c_layer->l_bottom == &p->w_layer)
- break;
- if (cv == 0)
- {
- p->w_bell = BELL_DONE;
- Msg(0, "%s", MakeWinMsg(BellString, p, '%'));
- }
- else if (visual && !D_VB && (!D_status || !D_status_bell))
- {
- Msg(0, "%s", VisualBellString);
- if (D_status)
- {
- D_status_bell = 1;
- debug1("using vbell timeout %d\n", VBellWait);
- SetTimeout(&D_statusev, VBellWait );
- }
- }
- }
- /* don't annoy the user with two messages */
- if (p->w_monitor == MON_FOUND)
- p->w_monitor = MON_DONE;
- WindowChanged(p, 'f');
- }
- if (p->w_monitor == MON_FOUND)
- {
- struct canvas *cv;
- p->w_monitor = MON_ON;
- for (display = displays; display; display = display->d_next)
- {
- for (cv = D_cvlist; cv; cv = cv->c_next)
- if (cv->c_layer->l_bottom == &p->w_layer)
- break;
- if (cv)
- continue; /* user already sees window */
-#ifdef MULTIUSER
- if (!(ACLBYTE(p->w_mon_notify, D_user->u_id) & ACLBIT(D_user->u_id)))
- continue; /* user doesn't care */
-#endif
- Msg(0, "%s", MakeWinMsg(ActivityString, p, '%'));
- p->w_monitor = MON_DONE;
- }
- WindowChanged(p, 'f');
- }
- }
-
- for (display = displays; display; display = display->d_next)
- {
- struct canvas *cv;
- if (D_status == STATUS_ON_WIN)
- continue;
- /* XXX: should use display functions! */
- for (cv = D_cvlist; cv; cv = cv->c_next)
- {
- int lx, ly;
-
- /* normalize window, see resize.c */
- lx = cv->c_layer->l_x;
- ly = cv->c_layer->l_y;
- if (lx == cv->c_layer->l_width)
- lx--;
- if (ly + cv->c_yoff < cv->c_ys)
- {
- int i, n = cv->c_ys - (ly + cv->c_yoff);
- cv->c_yoff = cv->c_ys - ly;
- RethinkViewportOffsets(cv);
- if (n > cv->c_layer->l_height)
- n = cv->c_layer->l_height;
- CV_CALL(cv,
- LScrollV(flayer, -n, 0, flayer->l_height - 1, 0);
- LayRedisplayLine(-1, -1, -1, 1);
- for (i = 0; i < n; i++)
- LayRedisplayLine(i, 0, flayer->l_width - 1, 1);
- if (cv == cv->c_display->d_forecv)
- LaySetCursor();
- );
- }
- else if (ly + cv->c_yoff > cv->c_ye)
- {
- int i, n = ly + cv->c_yoff - cv->c_ye;
- cv->c_yoff = cv->c_ye - ly;
- RethinkViewportOffsets(cv);
- if (n > cv->c_layer->l_height)
- n = cv->c_layer->l_height;
- CV_CALL(cv,
- LScrollV(flayer, n, 0, cv->c_layer->l_height - 1, 0);
- LayRedisplayLine(-1, -1, -1, 1);
- for (i = 0; i < n; i++)
- LayRedisplayLine(i + flayer->l_height - n, 0, flayer->l_width - 1, 1);
- if (cv == cv->c_display->d_forecv)
- LaySetCursor();
- );
- }
- if (lx + cv->c_xoff < cv->c_xs)
- {
- int i, n = cv->c_xs - (lx + cv->c_xoff);
- if (n < (cv->c_xe - cv->c_xs + 1) / 2)
- n = (cv->c_xe - cv->c_xs + 1) / 2;
- if (cv->c_xoff + n > cv->c_xs)
- n = cv->c_xs - cv->c_xoff;
- cv->c_xoff += n;
- RethinkViewportOffsets(cv);
- if (n > cv->c_layer->l_width)
- n = cv->c_layer->l_width;
- CV_CALL(cv,
- LayRedisplayLine(-1, -1, -1, 1);
- for (i = 0; i < flayer->l_height; i++)
- {
- LScrollH(flayer, -n, i, 0, flayer->l_width - 1, 0, 0);
- LayRedisplayLine(i, 0, n - 1, 1);
- }
- if (cv == cv->c_display->d_forecv)
- LaySetCursor();
- );
- }
- else if (lx + cv->c_xoff > cv->c_xe)
- {
- int i, n = lx + cv->c_xoff - cv->c_xe;
- if (n < (cv->c_xe - cv->c_xs + 1) / 2)
- n = (cv->c_xe - cv->c_xs + 1) / 2;
- if (cv->c_xoff - n + cv->c_layer->l_width - 1 < cv->c_xe)
- n = cv->c_xoff + cv->c_layer->l_width - 1 - cv->c_xe;
- cv->c_xoff -= n;
- RethinkViewportOffsets(cv);
- if (n > cv->c_layer->l_width)
- n = cv->c_layer->l_width;
- CV_CALL(cv,
- LayRedisplayLine(-1, -1, -1, 1);
- for (i = 0; i < flayer->l_height; i++)
- {
- LScrollH(flayer, n, i, 0, flayer->l_width - 1, 0, 0);
- LayRedisplayLine(i, flayer->l_width - n, flayer->l_width - 1, 1);
- }
- if (cv == cv->c_display->d_forecv)
- LaySetCursor();
- );
- }
- }
- }
-
- for (display = displays; display; display = display->d_next)
- {
- if (D_status == STATUS_ON_WIN || D_cvlist == 0 || D_cvlist->c_next == 0)
- continue;
- debug1("serv_select_fn: Restore on cv %#x\n", (int)D_forecv);
- CV_CALL(D_forecv, LayRestore();LaySetCursor());
- }
-}
-
-static void
-logflush_fn(ev, data)
-struct event *ev;
-char *data;
-{
- struct win *p;
- char *buf;
- int n;
-
- if (!islogfile(NULL))
- return; /* no more logfiles */
- logfflush(NULL);
- n = log_flush ? log_flush : (logtstamp_after + 4) / 5;
- if (n)
- {
- SetTimeout(ev, n * 1000);
- evenq(ev); /* re-enqueue ourself */
- }
- if (!logtstamp_on)
- return;
- /* write fancy time-stamp */
- for (p = windows; p; p = p->w_next)
- {
- if (!p->w_log)
- continue;
- p->w_logsilence += n;
- if (p->w_logsilence < logtstamp_after)
- continue;
- if (p->w_logsilence - n >= logtstamp_after)
- continue;
- buf = MakeWinMsg(logtstamp_string, p, '%');
- logfwrite(p->w_log, buf, strlen(buf));
- }
-}
-
-/*
- * Interprets ^?, ^@ and other ^-control-char notation.
- * Interprets \ddd octal notation
- *
- * The result is placed in *cp, p is advanced behind the parsed expression and
- * returned.
- */
-static char *
-ParseChar(p, cp)
-char *p, *cp;
-{
- if (*p == 0)
- return 0;
- if (*p == '^' && p[1])
- {
- if (*++p == '?')
- *cp = '\177';
- else if (*p >= '@')
- *cp = Ctrl(*p);
- else
- return 0;
- ++p;
- }
- else if (*p == '\\' && *++p <= '7' && *p >= '0')
- {
- *cp = 0;
- do
- *cp = *cp * 8 + *p - '0';
- while (*++p <= '7' && *p >= '0');
- }
- else
- *cp = *p++;
- return p;
-}
-
-static int
-ParseEscape(p)
-char *p;
-{
- unsigned char buf[2];
-
- if (*p == 0)
- SetEscape((struct acluser *)0, -1, -1);
- else
- {
- if ((p = ParseChar(p, (char *)buf)) == NULL ||
- (p = ParseChar(p, (char *)buf+1)) == NULL || *p)
- return -1;
- SetEscape((struct acluser *)0, buf[0], buf[1]);
- }
- return 0;
-}
-
diff --git a/src/screen.h b/src/screen.h
deleted file mode 100644
index 832fe6c..0000000
--- a/src/screen.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/* Copyright (c) 1993-2002
- * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- * Copyright (c) 1987 Oliver Laumann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- ****************************************************************
- * $Id$ FAU
- */
-
-#include "os.h"
-
-#if defined(__STDC__)
-# ifndef __P
-# define __P(a) a
-# endif
-#else
-# ifndef __P
-# define __P(a) ()
-# endif
-# define const
-#endif
-
-#include "osdef.h"
-
-#include "ansi.h"
-#include "sched.h"
-#include "acls.h"
-#include "comm.h"
-#include "layer.h"
-#include "term.h"
-
-
-#ifdef DEBUG
-# define STATIC /* a function that the debugger should see */
-#else
-# define STATIC static
-#endif
-
-#ifdef DEBUG
-# define DEBUGDIR "/tmp/debug"
-# define debugf(a) do {if(dfp){fprintf a;fflush(dfp);}} while (0)
-# define debug(x) debugf((dfp,x))
-# define debug1(x,a) debugf((dfp,x,a))
-# define debug2(x,a,b) debugf((dfp,x,a,b))
-# define debug3(x,a,b,c) debugf((dfp,x,a,b,c))
- extern FILE *dfp;
-#else
-# define debugf(a) do {} while (0)
-# define debug(x) debugf(x)
-# define debug1(x,a) debugf(x)
-# define debug2(x,a,b) debugf(x)
-# define debug3(x,a,b,c) debugf(x)
-#endif
-
-#ifndef DEBUG
-# define NOASSERT
-#endif
-
-#ifndef NOASSERT
-# if defined(__STDC__)
-# define ASSERT(lousy_cpp) do {if (!(lousy_cpp)) {if (!dfp) opendebug(0, 1);debug2("ASSERT("#lousy_cpp") failed file %s line %d\n", __FILE__, __LINE__);abort();}} while (0)
-# else
-# define ASSERT(lousy_cpp) do {if (!(lousy_cpp)) {if (!dfp) opendebug(0, 1);debug2("ASSERT(lousy_cpp) failed file %s line %d\n", __FILE__, __LINE__);abort();}} while (0)
-# endif
-#else
-# define ASSERT(lousy_cpp) do {} while (0)
-#endif
-
-/* here comes my own Free: jw. */
-#define Free(a) {if ((a) == 0) abort(); else free((void *)(a)); (a)=0;}
-
-#define Ctrl(c) ((c)&037)
-
-#define MAXSTR 256
-#define MAXARGS 64
-#define MSGWAIT 5
-#define MSGMINWAIT 1
-#define SILENCEWAIT 30
-
-/*
- * if a nasty user really wants to try a history of 3000 lines on all 10
- * windows, he will allocate 8 MegaBytes of memory, which is quite enough.
- */
-#define MAXHISTHEIGHT 3000
-#define DEFAULTHISTHEIGHT 100
-#if defined(NAME_MAX) && NAME_MAX < 16
-# define DEFAULT_BUFFERFILE "/tmp/screen-xchg"
-#else
-# define DEFAULT_BUFFERFILE "/tmp/screen-exchange"
-#endif
-
-
-#if defined(hpux) && !(defined(VSUSP) && defined(VDSUSP) && defined(VWERASE) && defined(VLNEXT))
-# define HPUX_LTCHARS_HACK
-#endif
-
-struct mode
-{
-#ifdef POSIX
- struct termios tio;
-# ifdef HPUX_LTCHARS_HACK
- struct ltchars m_ltchars;
-# endif /* HPUX_LTCHARS_HACK */
-#else /* POSIX */
-# ifdef TERMIO
- struct termio tio;
-# ifdef CYTERMIO
- int m_mapkey;
- int m_mapscreen;
- int m_backspace;
-# endif
-# else /* TERMIO */
- struct sgttyb m_ttyb;
- struct tchars m_tchars;
- struct ltchars m_ltchars;
- int m_ldisc;
- int m_lmode;
-# endif /* TERMIO */
-#endif /* POSIX */
-#if defined(KANJI) && defined(TIOCKSET)
- struct jtchars m_jtchars;
- int m_knjmode;
-#endif
-};
-
-
-/* #include "logfile.h" */ /* (requires stat.h) struct logfile */
-#include "image.h"
-#include "display.h"
-#include "window.h"
-
-/*
- * Parameters for the Detach() routine
- */
-#define D_DETACH 0
-#define D_STOP 1
-#define D_REMOTE 2
-#define D_POWER 3
-#define D_REMOTE_POWER 4
-#define D_LOCK 5
-#define D_HANGUP 6
-
-/*
- * Here are the messages the attacher sends to the backend
- */
-#define MSG_CREATE 0
-#define MSG_ERROR 1
-#define MSG_ATTACH 2
-#define MSG_CONT 3
-#define MSG_DETACH 4
-#define MSG_POW_DETACH 5
-#define MSG_WINCH 6
-#define MSG_HANGUP 7
-#define MSG_COMMAND 8
-
-/*
- * versions of struct msg:
- * 0: screen version 3.6.6 (version count introduced)
- */
-#define MSG_VERSION 0
-#define MSG_REVISION (('m'<<24) | ('s'<<16) | ('g'<<8) | MSG_VERSION)
-struct msg
-{
- int protocol_revision; /* reduce harm done by incompatible messages */
- int type;
- char m_tty[MAXPATHLEN]; /* ttyname */
- union
- {
- struct
- {
- int lflag;
- int aflag;
- int flowflag;
- int hheight; /* size of scrollback buffer */
- int nargs;
- char line[MAXPATHLEN];
- char dir[MAXPATHLEN];
- char screenterm[20]; /* is screen really "screen" ? */
- }
- create;
- struct
- {
- char auser[20 + 1]; /* username */
- int apid; /* pid of frontend */
- int adaptflag; /* adapt window size? */
- int lines, columns; /* display size */
- char preselect[20];
- int esc; /* his new escape character unless -1 */
- int meta_esc; /* his new meta esc character unless -1 */
- char envterm[20 + 1]; /* terminal type */
- int encoding; /* encoding of display */
- }
- attach;
- struct
- {
- char duser[20 + 1]; /* username */
- int dpid; /* pid of frontend */
- }
- detach;
- struct
- {
- char auser[20 + 1]; /* username */
- int nargs;
- char cmd[MAXPATHLEN]; /* command */
- int apid; /* pid of frontend */
- char preselect[20];
- }
- command;
- char message[MAXPATHLEN * 2];
- } m;
-};
-
-/*
- * And the signals the attacher receives from the backend
- */
-#define SIG_BYE SIGHUP
-#define SIG_POWER_BYE SIGUSR1
-#define SIG_LOCK SIGUSR2
-#define SIG_STOP SIGTSTP
-#ifdef SIGIO
-#define SIG_NODEBUG SIGIO /* triggerd by command 'debug off' */
-#endif
-
-
-#define BELL (Ctrl('g'))
-#define VBELLWAIT 1 /* No. of seconds a vbell will be displayed */
-
-#define BELL_ON 0 /* No bell has occurred in the window */
-#define BELL_FOUND 1 /* A bell has occurred, but user not yet notified */
-#define BELL_DONE 2 /* A bell has occured, user has been notified */
-
-#define BELL_VISUAL 3 /* A bell has occured in fore win, notify him visually */
-
-#define MON_OFF 0 /* Monitoring is off in the window */
-#define MON_ON 1 /* No activity has occurred in the window */
-#define MON_FOUND 2 /* Activity has occured, but user not yet notified */
-#define MON_DONE 3 /* Activity has occured, user has been notified */
-
-#define DUMP_TERMCAP 0 /* WriteFile() options */
-#define DUMP_HARDCOPY 1
-#define DUMP_EXCHANGE 2
-#define DUMP_SCROLLBACK 3
-
-#define SILENCE_OFF 0
-#define SILENCE_ON 1
-
-extern char strnomem[];
-
-/*
- * line modes used by Input()
- */
-#define INP_COOKED 0
-#define INP_NOECHO 1
-#define INP_RAW 2
-#define INP_EVERY 4
-
-
-#ifdef MULTIUSER
-struct acl
-{
- struct acl *next;
- char *name;
-};
-#endif
-
-/* register list */
-#define MAX_PLOP_DEFS 256
-
-struct baud_values
-{
- int idx; /* the index in the bsd-is padding lookup table */
- int bps; /* bits per seconds */
- int sym; /* symbol defined in ttydev.h */
-};
-
-/*
- * windowlist orders
- */
-#define WLIST_NUM 0
-#define WLIST_MRU 1