diff options
author | jnweiger <jnweiger> | 2005-12-16 14:32:16 +0000 |
---|---|---|
committer | jnweiger <jnweiger> | 2005-12-16 14:32:16 +0000 |
commit | 64434f463765093be5bc53f313848a897ef49c66 (patch) | |
tree | 9c331dcb26a0bf5021384eca945d6d631a141d33 /src | |
parent | 8f0dedbec36c89c4b9ac9abcedb3180757fddbd7 (diff) | |
download | screen-64434f463765093be5bc53f313848a897ef49c66.tar.gz |
oops, still there?
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/README | 102 | ||||
-rw-r--r-- | src/ansi.c | 3061 | ||||
-rw-r--r-- | src/screen.c | 3176 | ||||
-rw-r--r-- | src/screen.h | 295 |
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 |