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