|
|
1.1 root 1: /*
2: * $Source: /orpheus/u1/X11/clients/xterm/RCS/main.c,v $
3: * $Header: main.c,v 1.29 87/08/03 17:05:39 swick Locked $
4: */
5:
6: #include <X11/copyright.h>
7:
8: /*
9: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
10: *
11: * All Rights Reserved
12: *
13: * Permission to use, copy, modify, and distribute this software and its
14: * documentation for any purpose and without fee is hereby granted,
15: * provided that the above copyright notice appear in all copies and that
16: * both that copyright notice and this permission notice appear in
17: * supporting documentation, and that the name of Digital Equipment
18: * Corporation not be used in advertising or publicity pertaining to
19: * distribution of the software without specific, written prior permission.
20: *
21: *
22: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
23: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
24: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
25: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
26: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
27: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
28: * SOFTWARE.
29: */
30:
31: /* main.c */
32:
33: #ifndef lint
34: static char rcs_id[] = "$Header: main.c,v 1.29 87/08/03 17:05:39 swick Locked $";
35: #endif lint
36:
37: #include <pwd.h>
1.1.1.2 ! root 38: #include <sys/ioctl.h>
! 39: #include <sys/ttyld.h>
! 40: #include <wait.h>
1.1 root 41: #include <stdio.h>
42: #include <errno.h>
43: #include <signal.h>
44: #include <strings.h>
45: #include <setjmp.h>
46:
47: #ifdef apollo
48: #include <sys/types.h>
49: #define ttyslot() 1
50: #define vhangup() ;
51: #endif
52:
53: #include <utmp.h>
54: #include <sys/param.h> /* for NOFILE */
55: #include <X11/Xlib.h>
56: #include <X11/Xtlib.h>
57: #include "ptyx.h"
58: #include "data.h"
59: #include "error.h"
60: #include "main.h"
61:
62: extern Pixmap make_gray();
63: extern char *malloc();
64: extern char *calloc();
65: extern char *ttyname();
66: extern void exit();
67: extern void sleep();
68: extern void bcopy();
69: extern void vhangup();
70: extern long lseek();
1.1.1.2 ! root 71: extern int tty_ld, mesg_ld;
1.1 root 72:
73: XrmNameList nameList;
74: XrmClassList classList;
75:
76: int switchfb[] = {0, 2, 1, 3};
77:
78: static int reapchild ();
79:
80: static char **command_to_exec;
81: static struct sgttyb d_sg = {
82: 0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
83: };
84: static struct tchars d_tc = {
85: CINTR, CQUIT, CSTART,
1.1.1.2 ! root 86: CSTOP, CEOT, 0377,
1.1 root 87: };
88: static char display[256];
89: static char etc_utmp[] = "/etc/utmp";
90: static char *get_ty;
91: static int inhibit;
92: static int log_on;
93: static int login_shell;
94: static char passedPty[2]; /* name if pty if slave */
95: static int loginpty;
96: #ifdef TIOCCONS
97: static int Console;
98: #endif TIOCCONS
99: static int tslot;
100: static jmp_buf env;
101:
102: #define XtNxterm "xterm"
103: #define XtNwindowName "windowName"
104: #define XtNboldFont "boldFont"
105: #define XtNc132 "c132"
106: #define XtNtitle "title"
107: #define XtNcurses "curses"
108: #define XtNcursor "cursor"
109: #define XtNcursorShape "cursorShape"
110: #define XtNgeometry "geometry"
111: #define XtNiconStartup "iconStartup"
112: #define XtNinternalBorder "internalBorder"
113: #define XtNjumpScroll "jumpScroll"
114: #define XtNlogFile "logFile"
115: #define XtNlogging "logging"
116: #define XtNlogInhibit "logInhibit"
117: #define XtNloginShell "loginShell"
118: #define XtNmarginBell "marginBell"
119: #define XtNmouse "mouse"
120: #define XtNmultiScroll "multiScroll"
121: #define XtNnMarginBell "nMarginBell"
122: #define XtNreverseWrap "reverseWrap"
123: #define XtNsaveLines "saveLines"
124: #define XtNscrollBar "scrollBar"
125: #define XtNscrollInput "scrollInput"
126: #define XtNscrollKey "scrollKey"
127: #define XtNsignalInhibit "signalInhibit"
128: #define XtNtekInhibit "tekInhibit"
129: #define XtNtekStartup "tekStartup"
130: #define XtNvisualBell "visualBell"
131:
132: #define XtCApp "App"
133: #define XtCC132 "C132"
134: #define XtCCurses "Curses"
135: #define XtCBitmapbits "Bitmapbits"
136: #define XtCGeometry "Geometry"
137: #define XtCIconstartup "Iconstartup"
138: #define XtCJumpscroll "Jumpscroll"
139: #define XtCLogfile "Logfile"
140: #define XtCLogging "Logging"
141: #define XtCLoginhibit "Loginhibit"
142: #define XtCLoginshell "Loginshell"
143: #define XtCMarginbell "Marginbell"
144: #define XtCMultiscroll "Multiscroll"
145: #define XtCColumn "Column"
146: #define XtCReverseVideo "ReverseVideo"
147: #define XtCReverseWrap "ReverseWrap"
148: #define XtCRows "Rows"
149: #define XtCScrollbar "ScrollBar"
150: #define XtCScrollcond "Scrollcond"
151: #define XtCSignalInibit "SignalInibit"
152: #define XtCTekInhibit "TekInhibit"
153: #define XtCTekStartup "TekStartup"
154: #define XtCVisualbell "Visualbell"
155:
156:
157: /* Defaults */
158: static Boolean defaultFALSE = FALSE;
159: static Boolean defaultTRUE = TRUE;
160: static char *defaultNULL = NULL;
161: static int defaultBorderWidth = DEFBORDERWIDTH;
162: static int defaultIntBorder = DEFBORDER;
163: static int defaultSaveLines = SAVELINES;
164: static int defaultNMarginBell = N_MARGINBELL;
165: static char *defaultFont = DEFFONT;
166: static char *defaultBoldFont = DEFBOLDFONT;
167:
168: /* term.screen.flags things that don't map directly from option */
169: static Boolean reverseWrap;
170: static Boolean logInhibit;
171: static Boolean signalInhibit;
172: static Boolean tekInhibit;
173:
174: /* term.screen.xxx things that don't map directly from option */
175: static Boolean scrollbar;
176:
177:
178: /*static*/ Resource resourceList[] = {
179: {XtNbackground, XtCColor, XrmRPixel, sizeof(Pixel),
180: (caddr_t) &term.screen.background, (caddr_t) &XtDefaultBGPixel},
181: {XtNforeground, XtCColor, XrmRPixel, sizeof(Pixel),
182: (caddr_t) &term.screen.foreground, (caddr_t) &XtDefaultFGPixel},
183: {XtNfont, XtCFont, XrmRString, sizeof(char *),
184: (caddr_t) &f_n, (caddr_t) &defaultNULL},
185: {XtNboldFont, XtCFont, XrmRString, sizeof(char *),
186: (caddr_t) &f_b, (caddr_t) &defaultNULL},
187: {XtNborder, XtCColor, XrmRPixel, sizeof(Pixel),
188: (caddr_t) &term.screen.bordercolor, (caddr_t) &XtDefaultFGPixel},
189: {XtNborderWidth,XtCBorderWidth, XrmRInt, sizeof(int),
190: (caddr_t) &term.screen.borderwidth, (caddr_t)&defaultBorderWidth},
191: {XtNc132, XtCC132, XrmRBoolean, sizeof(Boolean),
192: (caddr_t) &term.screen.c132, (caddr_t) &defaultFALSE},
193: {XtNcurses, XtCCurses, XrmRBoolean, sizeof(Boolean),
194: (caddr_t) &term.screen.curses, (caddr_t) &defaultFALSE},
195: {XtNcursor, XtCColor, XrmRPixel, sizeof(Pixel),
196: (caddr_t) &term.screen.cursorcolor,
197: (caddr_t) &term.screen.foreground},
198: {XtNcursorShape,XtCCursor, XrmRString, sizeof(char *),
199: (caddr_t) &curs_shape, (caddr_t) &defaultNULL},
200: {XtNgeometry,XtCGeometry, XrmRString, sizeof(char *),
201: (caddr_t) &geo_metry, (caddr_t) &defaultNULL},
202: {XtNiconStartup,XtCIconstartup, XrmRBoolean, sizeof(Boolean),
203: (caddr_t) &iconstartup, (caddr_t) &defaultFALSE},
204: {XtNinternalBorder,XtCBorderWidth,XrmRInt, sizeof(int),
205: (caddr_t) &term.screen.border, (caddr_t) &defaultIntBorder},
206: {XtNjumpScroll, XtCJumpscroll, XrmRBoolean, sizeof(Boolean),
207: (caddr_t) &term.screen.jumpscroll, (caddr_t) &defaultTRUE},
208: {XtNlogFile, XtCLogfile, XrmRString, sizeof(char *),
209: (caddr_t) &term.screen.logfile, (caddr_t) &defaultNULL},
210: {XtNlogging, XtCLogging, XrmRBoolean, sizeof(Boolean),
211: (caddr_t) &log_on, (caddr_t) &defaultFALSE},
212: {XtNlogInhibit, XtCLoginhibit, XrmRBoolean, sizeof(Boolean),
213: (caddr_t) &logInhibit, (caddr_t) &defaultFALSE},
214: {XtNloginShell, XtCLoginshell, XrmRBoolean, sizeof(Boolean),
215: (caddr_t) &login_shell, (caddr_t) &defaultFALSE},
216: {XtNmarginBell, XtCMarginbell, XrmRBoolean, sizeof(Boolean),
217: (caddr_t) &term.screen.marginbell, (caddr_t) &defaultFALSE},
218: {XtNmouse, XtCColor, XrmRPixel, sizeof(Pixel),
219: /* (caddr_t) &term.screen.mousecolor, (caddr_t) &XtDefaultFGPixel},
220: */
221: (caddr_t) &term.screen.mousecolor,
222: (caddr_t) &term.screen.cursorcolor},
223: {XtNmultiScroll,XtCMultiscroll, XrmRBoolean, sizeof(Boolean),
224: (caddr_t) &term.screen.multiscroll, (caddr_t) &defaultFALSE},
225: {XtNnMarginBell,XtCColumn, XrmRInt, sizeof(int),
226: (caddr_t) &term.screen.nmarginbell, (caddr_t) &defaultNMarginBell},
227: {XtNreverseVideo,XtCReverseVideo,XrmRBoolean, sizeof(Boolean),
228: (caddr_t) &re_verse, (caddr_t) &defaultFALSE},
229: {XtNreverseWrap,XtCReverseWrap, XrmRBoolean, sizeof(Boolean),
230: (caddr_t) &reverseWrap, (caddr_t) &defaultFALSE},
231: {XtNsaveLines, XtCRows, XrmRInt, sizeof(int),
232: (caddr_t) &save_lines, (caddr_t) &defaultSaveLines},
233: {XtNscrollBar, XtCScrollbar, XrmRBoolean, sizeof(Boolean),
234: (caddr_t) &scrollbar, (caddr_t) &defaultFALSE},
235: {XtNscrollInput,XtCScrollcond, XrmRBoolean, sizeof(Boolean),
236: (caddr_t) &term.screen.scrollinput, (caddr_t) &defaultTRUE},
237: {XtNscrollKey, XtCScrollcond, XrmRBoolean, sizeof(Boolean),
238: (caddr_t) &term.screen.scrollkey, (caddr_t) &defaultFALSE},
239: {XtNsignalInhibit,XtCSignalInibit,XrmRBoolean, sizeof(Boolean),
240: (caddr_t) &signalInhibit, (caddr_t) &defaultFALSE},
241: {XtNtekInhibit, XtCTekInhibit, XrmRBoolean, sizeof(Boolean),
242: (caddr_t) &tekInhibit, (caddr_t) &defaultFALSE},
243: {XtNtekStartup, XtCTekStartup, XrmRBoolean, sizeof(Boolean),
244: (caddr_t) &term.screen.TekEmu, (caddr_t) &defaultFALSE},
245: {XtNtitle, XtCString, XrmRString, sizeof(char *),
246: (caddr_t) &title_name, (caddr_t) &defaultNULL},
247: {XtNvisualBell,XtCVisualbell, XrmRBoolean, sizeof(Boolean),
248: (caddr_t) &term.screen.visualbell, (caddr_t) &defaultFALSE},
249: {XtNwindowName, XtCString, XrmRString, sizeof(char *),
250: (caddr_t) &window_name, (caddr_t) &defaultNULL},
251:
252: };
253:
254:
255: /* Command line options table. Only resources are entered here...there is a
256: pass over the remaining options after XtParseCommand is let loose. */
257:
258: static XrmOptionDescRec optionDescList[] = {
259: {"=", XtNgeometry, XrmoptionIsArg, (caddr_t) NULL},
260: {"-132", XtNc132, XrmoptionNoArg, (caddr_t) "on"},
261: {"+132", XtNc132, XrmoptionNoArg, (caddr_t) "off"},
262: {"-T", XtNtitle, XrmoptionSepArg, (caddr_t) NULL},
263: {"-b", XtNinternalBorder,XrmoptionSepArg, (caddr_t) NULL},
264: {"-bd", XtNborder, XrmoptionSepArg, (caddr_t) NULL},
265: {"-bg", XtNbackground, XrmoptionSepArg, (caddr_t) NULL},
266: {"-bw", XtNborderWidth, XrmoptionSepArg, (caddr_t) NULL},
267: {"-cr", XtNcursor, XrmoptionSepArg, (caddr_t) NULL},
268: {"-cu", XtNcurses, XrmoptionNoArg, (caddr_t) "on"},
269: {"+cu", XtNcurses, XrmoptionNoArg, (caddr_t) "off"},
270: {"-e", NULL, XrmoptionSkipLine, (caddr_t) NULL},
271: {"-fb", XtNboldFont, XrmoptionSepArg, (caddr_t) NULL},
272: {"-fg", XtNforeground, XrmoptionSepArg, (caddr_t) NULL},
273: {"-fn", XtNfont, XrmoptionSepArg, (caddr_t) NULL},
274: {"-i", XtNiconStartup, XrmoptionNoArg, (caddr_t) "on"},
275: {"-j", XtNjumpScroll, XrmoptionNoArg, (caddr_t) "on"},
276: {"+j", XtNjumpScroll, XrmoptionNoArg, (caddr_t) "off"},
277: {"-l", XtNlogging, XrmoptionNoArg, (caddr_t) "on"},
278: {"+l", XtNlogging, XrmoptionNoArg, (caddr_t) "off"},
279: {"-lf", XtNlogFile, XrmoptionSepArg, (caddr_t) NULL},
280: {"-ls", XtNloginShell, XrmoptionNoArg, (caddr_t) "on"},
281: {"+ls", XtNloginShell, XrmoptionNoArg, (caddr_t) "off"},
282: {"-mb", XtNmarginBell, XrmoptionNoArg, (caddr_t) "on"},
283: {"+mb", XtNmarginBell, XrmoptionNoArg, (caddr_t) "off"},
284: {"-ms", XtNmouse, XrmoptionSepArg, (caddr_t) NULL},
285: {"-n", XtNwindowName, XrmoptionSepArg, (caddr_t) NULL},
286: {"-nb", XtNnMarginBell, XrmoptionSepArg, (caddr_t) NULL},
287: {"-r", XtNreverseVideo,XrmoptionNoArg, (caddr_t) "on"},
288: {"+r", XtNreverseVideo,XrmoptionNoArg, (caddr_t) "off"},
289: {"-rv", XtNreverseVideo,XrmoptionNoArg, (caddr_t) "on"},
290: {"+rv", XtNreverseVideo,XrmoptionNoArg, (caddr_t) "off"},
291: {"-rw", XtNreverseWrap, XrmoptionNoArg, (caddr_t) "on"},
292: {"+rw", XtNreverseWrap, XrmoptionNoArg, (caddr_t) "off"},
293: {"-s", XtNmultiScroll, XrmoptionNoArg, (caddr_t) "on"},
294: {"+s", XtNmultiScroll, XrmoptionNoArg, (caddr_t) "off"},
295: {"-sb", XtNscrollBar, XrmoptionNoArg, (caddr_t) "on"},
296: {"+sb", XtNscrollBar, XrmoptionNoArg, (caddr_t) "off"},
297: {"-si", XtNscrollInput, XrmoptionNoArg, (caddr_t) "off"},
298: {"+si", XtNscrollInput, XrmoptionNoArg, (caddr_t) "on"},
299: {"-sk", XtNscrollKey, XrmoptionNoArg, (caddr_t) "on"},
300: {"+sk", XtNscrollKey, XrmoptionNoArg, (caddr_t) "off"},
301: {"-sl", XtNsaveLines, XrmoptionSepArg, (caddr_t) NULL},
302: {"-t", XtNtekStartup, XrmoptionNoArg, (caddr_t) "on"},
303: {"+t", XtNtekStartup, XrmoptionNoArg, (caddr_t) "off"},
304: {"-vb", XtNvisualBell, XrmoptionNoArg, (caddr_t) "on"},
305: {"+vb", XtNvisualBell, XrmoptionNoArg, (caddr_t) "off"},
306: {"-w", XtNborderWidth, XrmoptionSepArg, (caddr_t) NULL},
307: };
308:
309: void XtGetUsersDataBase()
310: {
311: XrmResourceDataBase resources, userResources;
312: int uid;
313: extern struct passwd *getpwuid();
314: struct passwd *pw;
315: char filename[1024];
316: FILE *f;
317:
318: strcpy(filename, LIBDIR);
319: strcat(filename, "/Xdefaults" );
320: f = fopen(filename, "r");
321: if (f) {
322: XrmGetDataBase(f, &resources);
323: fclose(f);
324: } else
325: resources = NULL;
326:
327: /* Open .Xdefaults file and merge into existing data base */
328: uid = getuid();
329: pw = getpwuid(uid);
330: if (pw) {
331: strcpy(filename, pw->pw_dir);
332: strcat(filename, "/.Xdefaults");
333: f = fopen(filename, "r");
334: if (f) {
335: XrmGetDataBase(f, &userResources);
336: if (resources)
337: XrmMergeDataBases(userResources, &resources);
338: else
339: resources = userResources;
340: fclose(f);
341: }
342: strcpy(filename, pw->pw_dir);
343: strcat(filename, "/.X11defaults");
344: f = fopen(filename, "r");
345: if (f) {
346: XrmGetDataBase(f, &userResources);
347: if (resources)
348: XrmMergeDataBases(userResources, &resources);
349: else
350: resources = userResources;
351: fclose(f);
352: }
353: }
354: if (resources) XrmSetCurrentDataBase(resources);
355: }
356:
357:
358: OpenDisplay()
359: {
360: register TScreen *screen = &term.screen;
361: register int try;
362: for (try = 10 ; ; ) {
363: if (screen->display = XOpenDisplay(display))
364: break;
365: if (!get_ty) {
366: fprintf(stderr, "%s: No such display server %s\n", xterm_name,
367: XDisplayName(display));
368: exit(ERROR_NOX);
369: }
370: if (--try <= 0) {
371: fprintf (stderr, "%s: Can't connect to display server %s\n",
372: xterm_name, XDisplayName(display));
373: exit (ERROR_NOX2);
374: }
375: sleep (5);
376: }
377:
378: if (screen->display->fd > 31) {
379: fprintf(stderr,
380: "%s: Display server returned bogus file descriptor %d\n",
381: xterm_name, screen->display->fd);
382: exit (ERROR_NOX3);
383: };
384: }
385:
386: /* ||| */
1.1.1.2 ! root 387: /* struct timeb startT, initT, endT; */
1.1 root 388:
389: main (argc, argv)
390: int argc;
391: char **argv;
392: {
393: register TScreen *screen = &term.screen;
394: register int i, pty;
395: int Xsocket, mode;
396: char *malloc();
397: char *basename();
398: int xerror(), xioerror();
399:
400: xterm_name = (XStrCmp(*argv, "-") == 0) ? "xterm" : basename(*argv);
401:
402: /* |||
403: gettimeofday(&startT, &tz);
404: */
405: /* Init the Toolkit. */
406: XtInitialize();
407: /* |||
408: gettimeofday(&initT, &tz);
409: */
410: /* Parse the command line for resources */
411: XtGetUsersDataBase();
412: XrmParseCommand(optionDescList, XtNumber(optionDescList), XtNxterm,
413: &argc, argv);
414:
415: /* Parse the rest of the command line */
416: display[0] = '\0';
417: for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
418: if (**argv == '%') {
419: T_geometry = *argv;
420: *T_geometry = '=';
421: continue;
422: }
423:
424: if (**argv == '#') {
425: icon_geom = *argv;
426: *icon_geom = '=';
427: continue;
428: }
429:
430: if(index(*argv, ':') != NULL) {
431: strncpy(display, *argv, sizeof(display));
432: continue;
433: }
434:
435: if(!(i = (**argv == '-'))) Syntax (*argv);
436:
437: switch(argv[0][1]) {
438: #ifdef TIOCCONS
439: case 'C':
440: Console = TRUE;
441: continue;
442: #endif TIOCCONS
1.1.1.2 ! root 443: /*
1.1 root 444: case 'L':
445: {
446: char tt[32];
447:
448: L_flag = 1;
449: get_ty = argv[--argc];
450: strcpy(tt,"/dev/");
451: strcat(tt, get_ty);
452: tt[5] = 'p';
453: loginpty = open( tt, O_RDWR, 0 );
454: dup2( loginpty, 4 );
455: close( loginpty );
456: loginpty = 4;
457: tt[5] = 't';
458: chown(tt, 0, 0);
459: chmod(tt, 0622);
460: if (open(tt, O_RDWR, 0) < 0) {
461: consolepr("open(%s) failed\n", tt);
462: }
463: signal(SIGHUP, SIG_IGN);
464: vhangup();
465: setpgrp(0,0);
466: signal(SIGHUP, SIG_DFL);
467: (void) close(0);
468: open(tt, O_RDWR, 0);
469: dup2(0, 1);
470: dup2(0, 2);
471: continue;
472: }
473: case 'S':
474: sscanf(*argv + 2, "%c%c%d", passedPty, passedPty+1,
475: &am_slave);
476: if (am_slave <= 0) Syntax(*argv);
477: continue;
1.1.1.2 ! root 478: */
1.1 root 479: #ifdef DEBUG
480: case 'D':
481: debug = TRUE;
482: continue;
483: #endif DEBUG
484: case 'e':
485: if (argc <= 1) Syntax (*argv);
486: command_to_exec = ++argv;
487: break;
488: default:
489: Syntax (*argv);
490: }
491: break;
492: }
493:
494:
495: /* Initialize the display connection */
496: OpenDisplay();
497: /* Get initial values from .Xdefaults file */
498: XtGetResources(
499: screen->display,
500: resourceList,
501: XtNumber(resourceList),
502: (ArgList) NULL,
503: 0,
504: DefaultRootWindow(screen->display),
505: XtNxterm,
506: XtCApp,
507: &nameList,
508: &classList);
509:
510: /* |||
511: gettimeofday(&endT, &tz);
512: printf("init: %8.3f, total: %8.3f\n",
513: ((initT.tv_sec*1000000.0+initT.tv_usec)
514: - (startT.tv_sec*1000000.0+startT.tv_usec))/1000000.0,
515: ((endT.tv_sec*1000000.0+endT.tv_usec)
516: - (startT.tv_sec*1000000.0+startT.tv_usec))/1000000.0);
517: exit(0);
518: */
519: /* Do additional processing on complex .Xdefaults stuff */
520:
521: if (!f_n) {
522: if (f_b)
523: f_n = f_b;
524: else {
525: f_n = defaultFont;
526: f_b = defaultBoldFont;
527: }
528: }
529:
530: term.flags = WRAPAROUND | AUTOREPEAT;
531: if (!screen->jumpscroll) term.flags |= SMOOTHSCROLL;
532: if (reverseWrap) term.flags |= REVERSEWRAP;
533:
534: inhibit = 0;
535: if (logInhibit) inhibit |= I_LOG;
536: if (signalInhibit) inhibit |= I_SIGNAL;
537: if (tekInhibit) inhibit |= I_TEK;
538:
539: if (scrollbar) screen->scrollbar = SCROLLBARWIDTH;
540:
541: screen->color = 0;
542: if (screen->foreground != XtDefaultFGPixel)
543: screen->color |= C_FOREGROUND;
544: if (screen->background != XtDefaultBGPixel) {
545: screen->color |= C_BACKGROUND;
546: }
547: if (screen->cursorcolor != XtDefaultFGPixel)
548: screen->color |= C_CURSOR;
549: if (screen->mousecolor != XtDefaultFGPixel)
550: screen->color |= C_MOUSE;
551:
552: term.initflags = term.flags;
553:
554: if(!window_name)
555: window_name = (get_ty ? "login" : (am_slave ? "xterm slave" :
556: (command_to_exec ? basename(command_to_exec[0]) :
557: xterm_name)));
558: if (!title_name)
559: title_name = window_name;
560: if(inhibit & I_TEK)
561: screen->TekEmu = FALSE;
562:
563: /* set up stderr properly */
564: i = -1;
565: #ifdef DEBUG
566: if(debug)
1.1.1.2 ! root 567: i = creat ("xterm.debug", 0666);
1.1 root 568: else
569: #endif DEBUG
570: if(get_ty)
1.1.1.2 ! root 571: i = open("/dev/console", 1);
1.1 root 572: if(i >= 0)
573: fileno(stderr) = i;
574: if(fileno(stderr) != (NOFILE - 1)) {
575: dup2(fileno(stderr), (NOFILE - 1));
576: if(fileno(stderr) >= 3)
577: close(fileno(stderr));
578: fileno(stderr) = (NOFILE - 1);
579: }
580:
581: signal (SIGCHLD, reapchild);
582:
583: /* open a terminal for client */
584: get_terminal ();
585: spawn ();
586:
587: Xsocket = screen->display->fd;
588: pty = screen->respond;
589:
590: if (am_slave) { /* Write window id so master end can read and use */
591: write(pty, screen->TekEmu ? (char *)&TWindow(screen) :
592: (char *)&VWindow(screen), sizeof(Window));
593: write(pty, "\n", 1);
594: }
595:
596: if(log_on) {
597: log_on = FALSE;
598: StartLog(screen);
599: }
600: screen->inhibit = inhibit;
601: mode = 1;
602:
603: pty_mask = 1 << pty;
604: X_mask = 1 << Xsocket;
605: Select_mask = pty_mask | X_mask;
606: max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
607:
608: #ifdef DEBUG
609: if (debug) printf ("debugging on\n");
610: #endif DEBUG
611: XSetErrorHandler(xerror);
612: XSetIOErrorHandler(xioerror);
613: for( ; ; )
614: if(screen->TekEmu)
615: TekRun();
616: else
617: VTRun();
618: }
619:
620: char *basename(name)
621: char *name;
622: {
623: register char *cp;
624: char *rindex();
625:
626: return((cp = rindex(name, '/')) ? cp + 1 : name);
627: }
628:
629: static char *ustring[] = {
630: "Usage: xterm [-132] [-b inner_border_width] [-bd border_color] \\\n",
631: #ifdef TIOCCONS
632: " [-bg backgrnd_color] [-bw border_width] [-C] [-cr cursor_color] [-cu] \\\n",
633: #else TIOCCONS
634: " [-bg backgrnd_color] [-bw border_width] [-cr cursor_color] [-cu] \\\n",
635: #endif TIOCCONS
636: " [-fb bold_font] [-fg foregrnd_color] [-fn norm_font] \\\n",
637: " [-i] [-j] [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
638: " [-n name] [-nb bell_margin] [-rv] [-rw] [-s] \\\n",
639: " [-sb] [-si] [-sk] [-sl save_lines] [-sn] [-st] [-T title] [-t] [-tb] \\\n",
640: " [-vb] [=[width]x[height][[+-]xoff[[+-]yoff]]] \\\n",
641: " [%[width]x[height][[+-]xoff[[+-]yoff]]] [#[+-]xoff[[+-]yoff]] \\\n",
642: " [-e command_to_exec]\n\n",
643: "Fonts must be of fixed width and of same size;\n",
644: "If only one font is specified, it will be used for normal and bold text\n",
645: "The -132 option allows 80 <-> 132 column escape sequences\n",
646: #ifdef TIOCCONS
647: "The -C option forces output to /dev/console to appear in this window\n",
648: #endif TIOCCONS
649: "The -cu option turns a curses bug fix on\n",
650: "The -i option enables iconic startup\n",
651: "The -j option enables jump scroll\n",
652: "The -l option enables logging\n",
653: "The -ls option makes the shell a login shell\n",
654: "The -mb option turns the margin bell on\n",
655: "The -rv option turns reverse video on\n",
656: "The -rw option turns reverse wraparound on\n",
657: "The -s option enables asynchronous scrolling\n",
658: "The -sb option enables the scrollbar\n",
659: "The -si option disables re-positioning the scrollbar at the bottom on input\n",
660: "The -sk option causes the scrollbar to position at the bottom on a key\n",
661: "The -t option starts Tektronix mode\n",
662: "The -vb option enables visual bell\n",
663: 0
664: };
665:
666: Syntax (badOption)
667: char *badOption;
668: {
669: register char **us = ustring;
670:
671: fprintf(stderr, "Unknown option \"%s\"\n\n", badOption);
672: while (*us) fputs(*us++, stderr);
673: exit (1);
674: }
675:
676: get_pty (pty, tty)
677: /*
678: opens a pty, storing fildes in pty and tty.
679: */
680: int *pty, *tty;
681: {
1.1.1.2 ! root 682: if ((*pty = ptopen (ttydev)) >= 0) {
! 683: if ((*tty = open (ttydev, 2)) >= 0) {
! 684: if(ioctl(*pty, FIOPUSHLD, &mesg_ld) != -1 &&
! 685: ioctl(*tty, FIOPUSHLD, &tty_ld) != -1)
! 686: return;
! 687: else {
! 688: close(*tty);
! 689: close(*pty);
! 690: fprintf(stderr, "FIOPUSHLD fails, errno=%d\n", errno);
! 691: }
! 692: } else {
! 693: fprintf(stderr, "Can't open slave pty\n");
1.1 root 694: close(*pty);
695: }
1.1.1.2 ! root 696: } else
! 697: fprintf (stderr, "%s: Not enough available pty's\n", xterm_name);
1.1 root 698: exit (ERROR_PTYS);
699: }
700:
701: get_terminal ()
702: /*
703: * sets up X and initializes the terminal structure except for term.buf.fildes.
704: */
705: {
706: register TScreen *screen = &term.screen;
707: char *malloc();
708:
709: screen->graybordertile = make_gray(screen->bordercolor,
710: screen->background,
711: DefaultDepth(screen->display, DefaultScreen(screen->display)));
712:
713: screen->arrow = make_arrow(screen->mousecolor, screen->background);
714:
715: XAutoRepeatOn(screen->display);
716:
717: if((screen->iconname = malloc((unsigned) strlen(window_name) + 10)) == NULL)
718: Error(ERROR_WINNAME);
719: strcpy(screen->iconname, window_name);
720: screen->iconnamelen = strlen(screen->iconname);
721: if((screen->titlename = malloc((unsigned) strlen(title_name) + 10)) == NULL)
722: Error(ERROR_WINNAME);
723: strcpy(screen->titlename, title_name);
724: screen->titlenamelen = strlen(screen->titlename);
725:
726: }
727:
728: static char *tekterm[] = {
729: "tek4015",
730: "tek4014",
731: "tek4013",
732: "tek4010",
733: "dumb",
734: 0
735: };
736:
737: static char *vtterm[] = {
738: "xterm",
739: "vt102",
740: "vt100",
741: "ansi",
742: "dumb",
743: 0
744: };
745:
746: hungtty()
747: {
748: longjmp(env, 1);
749: }
750:
751: spawn ()
752: /*
753: * Inits pty and tty and forks a login process.
754: * Does not close fd Xsocket.
755: * If getty, execs getty rather than csh and uses std fd's rather
756: * than opening a pty/tty pair.
757: * If slave, the pty named in passedPty is already open for use
758: */
759: {
760: register TScreen *screen = &term.screen;
761: int Xsocket = screen->display->fd;
762: int index1, tty = -1;
763: unsigned lmode;
764: struct tchars tc;
765: struct sgttyb sg;
1.1.1.2 ! root 766: struct ttydevb devmodes;
1.1 root 767:
768: char termcap [1024];
769: char newtc [1024];
770: char *ptr, *shname;
771: int i, no_dev_tty = FALSE;
772: char **envnew; /* new environment */
773: char buf[32];
774: char *TermName = NULL;
775: struct passwd *pw = NULL;
776: #ifdef UTMP
777: struct utmp utmp;
778: #endif UTMP
779: extern int Exit();
780: char *getenv();
781: char *index (), *rindex (), *strindex ();
782:
783: screen->uid = getuid();
784: screen->gid = getgid();
785:
786: if(!(screen->TekEmu ? TekInit() : VTInit()))
787: exit(ERROR_INIT);
788:
789: if(screen->TekEmu) {
790: envnew = tekterm;
791: ptr = newtc;
792: } else {
793: envnew = vtterm;
794: ptr = termcap;
795: }
796: while(*envnew) {
797: if(tgetent(ptr, *envnew) == 1) {
798: TermName = *envnew;
799: if(!screen->TekEmu)
800: resize(screen, TermName, termcap, newtc);
801: break;
802: }
803: envnew++;
804: }
805:
806: if (get_ty) {
807: screen->respond = loginpty;
808: } else if (am_slave) {
809: setgid (screen->gid);
810: setuid (screen->uid);
811: } else {
812: /*
813: * Sometimes /dev/tty hangs on open (as in the case of a pty
814: * that has gone away). Simply make up some reasonable
815: * defaults.
816: */
817: signal(SIGALRM, hungtty);
818: alarm(1);
819: if (! setjmp(env)) {
1.1.1.2 ! root 820: tty = open ("/dev/tty", 2);
1.1 root 821: alarm(0);
822: } else {
823: tty = -1;
824: errno = ENXIO;
825: }
826: signal(SIGALRM, SIG_DFL);
827:
828: if (tty < 0) {
829: if (errno != ENXIO) SysError(ERROR_OPDEVTTY);
830: else {
831: no_dev_tty = TRUE;
832: sg = d_sg;
833: tc = d_tc;
834: }
835: } else {
836: /* get a copy of the current terminal's state */
837:
1.1.1.2 ! root 838: if(ioctl(tty, TIOCGETP, (char *)&sg) == -1) {
! 839: char filename[256], *p;
! 840: int fd;
! 841:
! 842: if((p=getenv("HOME")) == 0)
! 843: exit(1);
! 844: strcpy(filename, p);
! 845: strcat(filename, "/.sttymodes");
! 846: if ((fd = open(filename, 0)) < 0)
! 847: exit(1);
! 848: read(fd, &sg, sizeof(struct sgttyb));
! 849: read(fd, &devmodes, sizeof(struct ttydevb));
! 850: read(fd, &tc, sizeof(struct tchars));
! 851: close(fd);
! 852: }
! 853: else {
! 854: if(ioctl(tty, TIOCGETC, (char *)&tc) == -1)
! 855: SysError (ERROR_TIOCGETC);
! 856: }
1.1 root 857: close (tty);
858:
859: /* close all std file descriptors */
1.1.1.2 ! root 860: for (index1 = 0; index1 < 4; index1++)
1.1 root 861: close (index1);
862: }
863:
864: get_pty (&screen->respond, &tty);
865:
866: if (screen->respond != Xsocket + 1) {
867: dup2 (screen->respond, Xsocket + 1);
868: close (screen->respond);
869: screen->respond = Xsocket + 1;
870: }
871:
872: /* change ownership of tty to real group and user id */
873: chown (ttydev, screen->uid, screen->gid);
874:
875: /* change protection of tty */
876: chmod (ttydev, 0622);
877:
878: if (tty != Xsocket + 2) {
879: dup2 (tty, Xsocket + 2);
880: close (tty);
881: tty = Xsocket + 2;
882: }
883:
884: /* set the new terminal's state to be the old one's
885: with minor modifications for efficiency */
886:
887: sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
888: sg.sg_flags |= ECHO | CRMOD;
889: /* make sure speed is set on pty so that editors work right*/
890: sg.sg_ispeed = B9600;
891: sg.sg_ospeed = B9600;
892: /* reset t_brkc to default value */
893: tc.t_brkc = -1;
894:
895: if (ioctl (tty, TIOCSETP, (char *)&sg) == -1)
896: SysError (ERROR_TIOCSETP);
897: if (ioctl (tty, TIOCSETC, (char *)&tc) == -1)
898: SysError (ERROR_TIOCSETC);
899: #ifdef TIOCCONS
900: if (Console) {
901: int on = 1;
902: if (ioctl (tty, TIOCCONS, (char *)&on) == -1)
903: SysError(ERROR_TIOCCONS);
904: }
905: #endif TIOCCONS
1.1.1.2 ! root 906: for (index1 = 0; index1 < 4; index1++)
1.1 root 907: dup2 (tty, index1);
908: #ifdef UTMP
909: if((pw = getpwuid(screen->uid)) &&
1.1.1.2 ! root 910: (i = open(etc_utmp, 1)) >= 0) {
1.1 root 911: bzero((char *)&utmp, sizeof(struct utmp));
912: (void) strcpy(utmp.ut_line, &ttydev[5]);
913: (void) strcpy(utmp.ut_name, pw->pw_name);
914: time(&utmp.ut_time);
915: lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
916: write(i, (char *)&utmp, sizeof(struct utmp));
917: close(i);
918: } else
919: tslot = -tslot;
920: #endif UTMP
921: }
922:
923: if (!am_slave) {
924: if ((screen->pid = fork ()) == -1)
925: SysError (ERROR_FORK);
926:
927: if (screen->pid == 0) {
928: extern char **environ;
929: int pgrp = getpid();
930:
931: close (Xsocket);
932: close (screen->respond);
1.1.1.2 ! root 933: if(fileno(stderr) >= 4)
1.1 root 934: close (fileno(stderr));
935:
936: if (tty >= 0) close (tty);
937:
938: signal (SIGCHLD, SIG_DFL);
939: signal (SIGHUP, SIG_IGN);
940:
941: /* copy the environment before Setenving */
942: for (i = 0 ; environ [i] != NULL ; i++) ;
943: /*
944: * The `4' is the number of Setenv() calls which may add
945: * a new entry to the environment. The `1' is for the
946: * NULL terminating entry.
947: */
948: envnew = (char **) calloc ((unsigned) i + (4 + 1), sizeof(char *));
949: bcopy((char *)environ, (char *)envnew, i * sizeof(char *));
950: environ = envnew;
951: Setenv ("TERM=", TermName);
952: if(!TermName)
953: *newtc = 0;
954: Setenv ("TERMCAP=", newtc);
955: sprintf(buf, "%d", screen->TekEmu ? (int)TWindow(screen) :
956: (int)VWindow(screen));
957: Setenv ("WINDOWID=", buf);
958: /* put the display into the environment of the shell*/
959: if (display[0] != '\0')
960: Setenv ("DISPLAY=", XDisplayName(display));
961:
962: signal(SIGTERM, SIG_DFL);
1.1.1.2 ! root 963: ioctl(0, TIOCSPGRP, 0);
1.1 root 964:
965: setgid (screen->gid);
966: setuid (screen->uid);
967:
968: if (command_to_exec) {
969: execvp(*command_to_exec, command_to_exec);
970: /* print error message on screen */
971: fprintf(stderr, "%s: Can't execvp %s\n", xterm_name,
972: *command_to_exec);
973: }
974: signal(SIGHUP, SIG_IGN);
975: if (get_ty) {
976: execl ("/etc/getty", "+", "Xwindow", get_ty, 0);
977: }
978: signal(SIGHUP, SIG_DFL);
979:
980: #ifdef UTMP
981: if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
982: ((pw == NULL && (pw = getpwuid(screen->uid)) == NULL) ||
983: *(ptr = pw->pw_shell) == 0))
984: #else UTMP
985: if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
986: ((pw = getpwuid(screen->uid)) == NULL ||
987: *(ptr = pw->pw_shell) == 0))
988: #endif UTMP
989: ptr = "/bin/sh";
990: if(shname = rindex(ptr, '/'))
991: shname++;
992: else
993: shname = ptr;
994: execl (ptr, login_shell ? "-" : shname, 0);
995: fprintf (stderr, "%s: Could not exec %s!\n", xterm_name, ptr);
996: sleep(5);
997: exit(ERROR_EXEC);
998: }
999: }
1000:
1001: if(tty >= 0) close (tty);
1002: signal(SIGHUP,SIG_IGN);
1003:
1004: if (!no_dev_tty) {
1.1.1.2 ! root 1005: if ((tty = open ("/dev/tty", 2)) < 0)
1.1 root 1006: SysError(ERROR_OPDEVTTY3);
1.1.1.2 ! root 1007: for (index1 = 0; index1 < 4; index1++)
1.1 root 1008: dup2 (tty, index1);
1009: if (tty > 2) close (tty);
1010: }
1011:
1012: signal(SIGINT, Exit);
1013: signal(SIGQUIT, Exit);
1014: signal(SIGTERM, Exit);
1015: }
1016:
1017: Exit(n)
1018: int n;
1019: {
1020: register TScreen *screen = &term.screen;
1021: int pty = term.screen.respond; /* file descriptor of pty */
1022: #ifdef UTMP
1023: register int i;
1024: struct utmp utmp;
1025:
1.1.1.2 ! root 1026: if(!am_slave && tslot > 0 && (i = open(etc_utmp, 1)) >= 0) {
1.1 root 1027: bzero((char *)&utmp, sizeof(struct utmp));
1028: lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
1029: write(i, (char *)&utmp, sizeof(struct utmp));
1030: close(i);
1031: }
1032: #endif UTMP
1033: close(pty); /* close explicitly to avoid race with slave side */
1034: if(screen->logging)
1035: CloseLog(screen);
1036:
1037: if(!get_ty && !am_slave) {
1038: /* restore ownership of tty */
1039: chown (ttydev, 0, 0);
1040:
1041: /* restore modes of tty */
1042: chmod (ttydev, 0666);
1043: }
1044: exit(n);
1045: }
1046:
1047: resize(screen, TermName, oldtc, newtc)
1048: TScreen *screen;
1049: char *TermName;
1050: register char *oldtc, *newtc;
1051: {
1052: register char *ptr1, *ptr2;
1053: register int i;
1054: register int li_first = 0;
1055: register char *temp;
1056: char *index(), *strindex();
1057:
1058: if ((ptr1 = strindex (oldtc, "co#")) == NULL){
1059: fprintf(stderr, "%s: Can't find co# in termcap string %s\n",
1060: xterm_name, TermName);
1061: exit (ERROR_NOCO);
1062: }
1063: if ((ptr2 = strindex (oldtc, "li#")) == NULL){
1064: fprintf(stderr, "%s: Can't find li# in termcap string %s\n",
1065: xterm_name, TermName);
1066: exit (ERROR_NOLI);
1067: }
1068: if(ptr1 > ptr2) {
1069: li_first++;
1070: temp = ptr1;
1071: ptr1 = ptr2;
1072: ptr2 = temp;
1073: }
1074: ptr1 += 3;
1075: ptr2 += 3;
1076: strncpy (newtc, oldtc, i = ptr1 - oldtc);
1077: newtc += i;
1078: sprintf (newtc, "%d", li_first ? screen->max_row + 1 :
1079: screen->max_col + 1);
1080: newtc += strlen(newtc);
1081: ptr1 = index (ptr1, ':');
1082: strncpy (newtc, ptr1, i = ptr2 - ptr1);
1083: newtc += i;
1084: sprintf (newtc, "%d", li_first ? screen->max_col + 1 :
1085: screen->max_row + 1);
1086: ptr2 = index (ptr2, ':');
1087: strcat (newtc, ptr2);
1088: }
1089:
1090: static reapchild ()
1091: {
1092: union wait status;
1093: register int pid;
1094:
1095: #ifdef DEBUG
1096: if (debug) fputs ("Exiting\n", stderr);
1097: #endif DEBUG
1098: pid = wait3 (&status, WNOHANG, (struct rusage *)NULL);
1099: if (!pid) return;
1100: if (pid != term.screen.pid) return;
1101:
1102: Cleanup(0);
1103: }
1104:
1105: /* VARARGS1 */
1106: consolepr(fmt,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
1107: char *fmt;
1108: {
1109: extern int errno;
1110: extern char *sys_errlist[];
1111: int oerrno;
1112: int f;
1113: char buf[ BUFSIZ ];
1114:
1115: oerrno = errno;
1116: strcpy(buf, "xterm: ");
1117: sprintf(buf+strlen(buf), fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
1118: strcat(buf, ": ");
1119: strcat(buf, sys_errlist[oerrno]);
1120: strcat(buf, "\n");
1.1.1.2 ! root 1121: f = open("/dev/console",1);
1.1 root 1122: write(f, buf, strlen(buf));
1123: close(f);
1124: }
1125:
1126: checklogin()
1127: {
1128: register int ts, i;
1129: register struct passwd *pw;
1130: struct utmp utmp;
1131:
1132: ts = tslot > 0 ? tslot : -tslot;
1.1.1.2 ! root 1133: if((i = open(etc_utmp, 0)) < 0)
1.1 root 1134: return(FALSE);
1135: lseek(i, (long)(ts * sizeof(struct utmp)), 0);
1136: ts = read(i, (char *)&utmp, sizeof(utmp));
1137: close(i);
1138: if(ts != sizeof(utmp) || XStrCmp(get_ty, utmp.ut_line) != 0 ||
1139: !*utmp.ut_name || (pw = getpwnam(utmp.ut_name)) == NULL)
1140: return(FALSE);
1141: chdir(pw->pw_dir);
1142: setgid(pw->pw_gid);
1143: setuid(pw->pw_uid);
1144: L_flag = 0;
1145: return(TRUE);
1146: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.