|
|
1.1 root 1: /*
2: * @(#)main.c 1.15 (Berkeley/CSRG) 5/31/88
3: * $Source: /u1/X/xterm/RCS/main.c,v $
4: * $Header: main.c,v 10.101 86/12/01 16:58:10 swick Rel $
5: */
6:
7: #include <X/mit-copyright.h>
8:
9: /* Copyright Massachusetts Institute of Technology 1984, 1985 */
10:
11: /* main.c */
12:
13: #ifndef lint
14: static char csrg_id[] = "@(#)main.c 1.15\t(Berkeley/CSRG)\t5/31/88";
15: static char sccs_id[] = "@(#)main.c\tX10/6.6B\t12/28/86";
16: #endif lint
17:
18: #include <sys/param.h> /* for NOFILE */
19: #include <pwd.h>
20: #include <grp.h>
21: #include <sgtty.h>
22: #include <sys/wait.h>
23: #include <sys/time.h>
24: #include <sys/resource.h>
25: #include <sys/socket.h>
26: #include <stdio.h>
27: #include <sys/file.h>
28: #include <errno.h>
29: #include <signal.h>
30: #include <strings.h>
31: #include <setjmp.h>
32: #include <utmp.h>
33: #include <X/Xlib.h>
34: #include "scrollbar.h"
35: #include "ptyx.h"
36: #include "data.h"
37: #include "error.h"
38: #include "main.h"
39:
40: int switchfb[] = {0, 2, 1, 3};
41:
42: static int reapchild ();
43:
44: static char *brdr_color;
45: static char **command_to_exec;
46: #ifdef TIOCCONS
47: static int Console;
48: #endif TIOCCONS
49: static struct sgttyb d_sg = {
50: 0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
51: };
52: static struct tchars d_tc = {
53: CINTR, CQUIT, CSTART,
54: CSTOP, CEOF, CBRK,
55: };
56: static struct ltchars d_ltc = {
57: CSUSP, CDSUSP, CRPRNT,
58: CFLUSH, CWERASE, CLNEXT
59: };
60: static int d_disipline = NTTYDISC;
61: static int d_lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
62: static char def_bold_font[] = DEFBOLDFONT;
63: static char def_font[] = DEFFONT;
64: static char def_title_font[] = DEFTITLEFONT;
65: static char def_icon_font[] = DEFICONFONT;
66: static char display[256];
67: static char etc_utmp[] = "/etc/utmp";
68: static char *get_ty;
69: static char *iconbitmap;
70: static int inhibit;
71: static int log_on;
72: static int login_shell;
73: static char passedPty[2]; /* name if pty if slave */
74: static int loginpty;
75: static char *tekiconbitmap;
76: static int tslot;
77: static char *xdef[] = {
78: "ActiveIcon", /* DEF_ACTIVEICON */
79: "AllowIconInput", /* DEF_ALLOWICONINPUT */
80: "AutoRaise", /* DEF_AUTORAISE */
81: "Background", /* DEF_BACKGROUND */
82: "BodyFont", /* DEF_BODYFONT */
83: "BoldFont", /* DEF_BOLDFONT */
84: "Border", /* DEF_BORDER */
85: "BorderWidth", /* DEF_BORDERWIDTH */
86: "C132", /* DEF_C132 */
87: "Curses", /* DEF_CURSES */
88: "Cursor", /* DEF_CURSOR */
89: "cursorShape", /* DEF_CURSORSHAPE */
90: "DeiconifyWarp", /* DEF_DEICONWARP */
91: "Foreground", /* DEF_FOREGROUND */
92: "GrayBorder", /* DEF_GRAYBORDER */
93: "IconBitmap", /* DEF_ICONBITMAP */
94: "IconFont", /* DEF_ICONFONT */
95: "IconStartup", /* DEF_ICONSTARTUP */
96: "InternalBorder", /* DEF_INTERNALBORDER */
97: "JumpScroll", /* DEF_JUMPSCROLL */
98: #ifdef KEYBD
99: "KeyBoard", /* DEF_KEYBOARD */
100: #endif KEYBD
101: "LogFile", /* DEF_LOGFILE */
102: "Logging", /* DEF_LOGGING */
103: "LogInhibit", /* DEF_LOGINHIBIT */
104: "LoginShell", /* DEF_LOGINSHELL */
105: "MarginBell", /* DEF_MARGINBELL */
106: "Mouse", /* DEF_MOUSE */
107: "NMarginBell", /* DEF_NMARGINBELL */
108: "PageOverlap", /* DEF_PAGEOVERLAP */
109: "PageScroll", /* DEF_PAGESCROLL */
110: "ReverseVideo", /* DEF_REVERSEVIDEO */
111: "ReverseWrap", /* DEF_REVERSEWRAP */
112: "SaveLines", /* DEF_SAVELINES */
113: "ScrollBar", /* DEF_SCROLLBAR */
114: "ScrollInput", /* DEF_SCROLLINPUT */
115: "ScrollKey", /* DEF_SCROLLKEY */
116: "SignalInhibit", /* DEF_SIGNALINHIBIT */
117: "StatusLine", /* DEF_STATUSLINE */
118: "StatusNormal", /* DEF_STATUSNORMAL */
119: "TekIconBitmap", /* DEF_TEKICONBITMAP */
120: "TekInhibit", /* DEF_TEKINHIBIT */
121: "TextUnderIcon", /* DEF_TEXTUNDERICON */
122: "TitleBar", /* DEF_TITLEBAR */
123: "TitleFont", /* DEF_TITLEFONT */
124: "VisualBell", /* DEF_VISUALBELL */
125: "VisBellDelay", /* DEF_VISBELLDELAY */
126: "AudibleBell", /* DEF_AUDIBLEBELL */
127: "DropMenu", /* DEF_DROPMENU */
128: "UniqueSuffix", /* DEF_UNIQUESUFFIX */
129: #ifdef ALLOWUNSHIFTEDSELECTION
130: "UnshiftedSelection", /* DEF_UNSHIFTEDSELECTION */
131: #endif
132: 0,
133: };
134: #ifdef UTMP
135: static int added_utmp_entry;
136: #endif UTMP
137:
138: main (argc, argv)
139: int argc;
140: char **argv;
141: {
142: register Screen *screen = &term.screen;
143: register char *strind;
144: register int i, pty;
145: register char **cp;
146: short fnflag = 0; /* True iff -fn option used */
147: short fbflag = 0; /* True iff -fb option used */
148: int Xsocket, mode;
149: extern onalarm();
150: char *malloc();
151: char *basename();
152: int xerror(), xioerror();
153: #ifdef KEYBD
154: extern char *keyboardtype; /* used in XKeyBind.c */
155: char *getenv();
156: #endif KEYBD
157:
158: xterm_name = (strcmp(*argv, "-") == 0) ? "xterm" : basename(*argv);
159:
160: term.flags = WRAPAROUND | SMOOTHSCROLL | AUTOREPEAT;
161: screen->border = DEFBORDER;
162: screen->borderwidth = DEFBORDERWIDTH;
163: screen->reversestatus = TRUE;
164: screen->mappedVwin = &screen->fullVwin;
165: screen->mappedTwin = &screen->fullTwin;
166: screen->audiblebell = TRUE;
167: screen->visbelldelay = VISBELLDELAY;
168: f_b = def_bold_font;
169: f_n = def_font;
170: f_t = def_title_font;
171: f_i = def_icon_font;
172:
173: display[0] = '\0';
174: #ifdef KEYBD
175: if((strind = getenv("KEYBD")) && *strind) {
176: if((keyboardtype = malloc(strlen(strind) + 1)) == NULL)
177: SysError(ERROR_KMALLOC);
178: strcpy(keyboardtype, strind);
179: }
180: #endif KEYBD
181:
182: /*
183: * go get options out of default file
184: */
185: for(i = 0, cp = xdef ; *cp ; i++, cp++) {
186: if(!(strind = XGetDefault(xterm_name, *cp)))
187: continue;
188: switch(i) {
189: case DEF_ACTIVEICON:
190: if (strcmp (strind, "on") == 0)
191: screen->active_icon = TRUE;
192: continue;
193: case DEF_ALLOWICONINPUT:
194: if (strcmp (strind, "on") == 0)
195: term.flags |= ICONINPUT;
196: continue;
197: case DEF_AUTORAISE:
198: if (strcmp (strind, "on") == 0)
199: screen->autoraise = TRUE;
200: continue;
201: case DEF_BACKGROUND:
202: back_color = strind;
203: continue;
204: case DEF_BODYFONT:
205: f_n = strind;
206: fnflag = TRUE;
207: continue;
208: case DEF_BOLDFONT:
209: f_b = strind;
210: fbflag = TRUE;
211: continue;
212: case DEF_BORDER:
213: brdr_color = strind;
214: continue;
215: case DEF_BORDERWIDTH:
216: screen->borderwidth = atoi (strind);
217: continue;
218: case DEF_C132:
219: if (strcmp (strind, "on") == 0)
220: screen->c132 = TRUE;
221: continue;
222: case DEF_CURSES:
223: if (strcmp (strind, "on") == 0)
224: screen->curses = TRUE;
225: continue;
226: case DEF_CURSOR:
227: curs_color = strind;
228: continue;
229: case DEF_CURSORSHAPE:
230: if (curs_shape)
231: free(curs_shape);
232: if ((curs_shape = malloc(strlen(strind) + 1)) == NULL)
233: SysError(ERROR_KMALLOC); /* not correct error */
234: strcpy(curs_shape, strind);
235: continue;
236: case DEF_DEICONWARP:
237: if (strcmp (strind, "on") == 0)
238: screen->deiconwarp = TRUE;
239: continue;
240: case DEF_FOREGROUND:
241: fore_color = strind;
242: continue;
243: case DEF_GRAYBORDER:
244: if (strcmp (strind, "off") == 0)
245: grayborder=FALSE;
246: continue;
247: case DEF_ICONBITMAP:
248: iconbitmap = strind;
249: continue;
250: case DEF_ICONFONT:
251: f_i = strind;
252: continue;
253: case DEF_ICONSTARTUP:
254: if (strcmp (strind, "on") == 0)
255: screen->icon_show = -1;
256: continue;
257: case DEF_INTERNALBORDER:
258: screen->border = atoi (strind);
259: continue;
260: case DEF_JUMPSCROLL:
261: if (strcmp (strind, "on") == 0) {
262: screen->jumpscroll = TRUE;
263: term.flags &= ~SMOOTHSCROLL;
264: }
265: continue;
266: #ifdef KEYBD
267: case DEF_KEYBOARD:
268: if(keyboardtype)
269: free(keyboardtype);
270: keyboardtype = strind;
271: continue;
272: #endif KEYBD
273: case DEF_LOGFILE:
274: if(screen->logfile = malloc(strlen(strind) + 1))
275: strcpy(screen->logfile, strind);
276: continue;
277: case DEF_LOGGING:
278: if (strcmp (strind, "on") == 0)
279: log_on = TRUE;
280: continue;
281: case DEF_LOGINHIBIT:
282: if (strcmp (strind, "on") == 0)
283: inhibit |= I_LOG;
284: continue;
285: case DEF_LOGINSHELL:
286: if (strcmp (strind, "on") == 0)
287: login_shell = TRUE;
288: continue;
289: case DEF_MARGINBELL:
290: if (strcmp (strind, "on") == 0)
291: screen->marginbell = TRUE;
292: continue;
293: case DEF_MOUSE:
294: mous_color = strind;
295: continue;
296: case DEF_NMARGINBELL:
297: n_marginbell = atoi (strind);
298: continue;
299: case DEF_PAGEOVERLAP:
300: if((screen->pageoverlap = atoi (strind) - 1) < 0)
301: screen->pageoverlap = -1;
302: continue;
303: case DEF_PAGESCROLL:
304: if (strcmp (strind, "on") == 0)
305: screen->pagemode = TRUE;
306: continue;
307: case DEF_REVERSEVIDEO:
308: if (strcmp (strind, "on") == 0)
309: re_verse = TRUE;
310: continue;
311: case DEF_REVERSEWRAP:
312: if (strcmp (strind, "on") == 0)
313: term.flags |= REVERSEWRAP;
314: continue;
315: case DEF_SAVELINES:
316: save_lines = atoi (strind);
317: continue;
318: case DEF_SCROLLBAR:
319: if (strcmp (strind, "on") == 0)
320: screen->scrollbar = SCROLLBARWIDTH;
321: continue;
322: case DEF_SCROLLINPUT:
323: if (strcmp (strind, "on") == 0)
324: screen->scrollinput = TRUE;
325: continue;
326: case DEF_SCROLLKEY:
327: if (strcmp (strind, "on") == 0)
328: screen->scrollkey = TRUE;
329: continue;
330: case DEF_SIGNALINHIBIT:
331: if (strcmp (strind, "on") == 0)
332: inhibit |= I_SIGNAL;
333: continue;
334: case DEF_STATUSLINE:
335: if (strcmp (strind, "on") == 0)
336: screen->statusline = TRUE;
337: continue;
338: case DEF_STATUSNORMAL:
339: screen->reversestatus = (strcmp (strind, "on") != 0);
340: continue;
341: case DEF_TEKICONBITMAP:
342: tekiconbitmap = strind;
343: continue;
344: case DEF_TEKINHIBIT:
345: if (strcmp (strind, "on") == 0)
346: inhibit |= I_TEK;
347: continue;
348: case DEF_TEXTUNDERICON:
349: if (strcmp (strind, "on") == 0)
350: screen->textundericon = TRUE;
351: continue;
352: case DEF_TITLEBAR:
353: if (strcmp (strind, "on") == 0)
354: screen->fullVwin.titlebar = TRUE;
355: continue;
356: case DEF_TITLEFONT:
357: f_t = strind;
358: continue;
359: case DEF_VISUALBELL:
360: if (strcmp (strind, "on") == 0)
361: screen->visualbell = TRUE;
362: continue;
363: case DEF_VISBELLDELAY:
364: screen->visbelldelay = atoi(strind);
365: continue;
366: case DEF_AUDIBLEBELL:
367: if (strcmp (strind, "off") == 0)
368: screen->audiblebell = FALSE;
369: continue;
370: case DEF_DROPMENU:
371: if (strcmp (strind, "on") == 0)
372: dropmenu = TRUE;
373: continue;
374: case DEF_UNIQUESUFFIX:
375: if (strcmp (strind, "off") == 0)
376: douniquesuffix = FALSE;
377: continue;
378: #ifdef ALLOWUNSHIFTEDSELECTION
379: case DEF_UNSHIFTEDSELECTION:
380: if (strcmp (strind, "on") == 0)
381: UnshiftedSelectionInit();
382: continue;
383: #endif
384:
385: }
386: }
387:
388: /* parse command line */
389:
390: for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
391: if (**argv == '=') {
392: geo_metry = *argv;
393: continue;
394: }
395:
396: if (**argv == '%') {
397: T_geometry = *argv;
398: *T_geometry = '=';
399: continue;
400: }
401:
402: if (**argv == '#') {
403: icon_geom = *argv;
404: *icon_geom = '=';
405: continue;
406: }
407:
408: if((strind = index (*argv, ':')) != NULL) {
409: strncpy(display, *argv, sizeof(display));
410: continue;
411: }
412:
413: if(!(i = (**argv == '-')) && **argv != '+') Syntax ();
414:
415: switch(argument(&(*argv)[1])) {
416: case ARG_132:
417: screen->c132 = i;
418: continue;
419: #ifdef TIOCCONS
420: case ARG__C:
421: Console = i;
422: continue;
423: #endif TIOCCONS
424: case ARG__L:
425: {
426: char tt[32];
427:
428: L_flag = 1;
429: get_ty = argv[--argc];
430: strcpy(tt,"/dev/");
431: strcat(tt, get_ty);
432: tt[5] = 'p';
433: loginpty = open( tt, O_RDWR, 0 );
434: dup2( loginpty, 4 );
435: close( loginpty );
436: loginpty = 4;
437: tt[5] = 't';
438: chown(tt, 0, 0);
439: chmod(tt, 0622);
440: if (open(tt, O_RDWR) < 0) {
441: consolepr("open failed\n");
442: }
443: signal(SIGHUP, SIG_IGN);
444: vhangup();
445: setpgrp(0,0);
446: signal(SIGHUP, SIG_DFL);
447: (void) close(0);
448: open(tt, O_RDWR, 0);
449: dup2(0, 1);
450: dup2(0, 2);
451: continue;
452: }
453: case ARG__S:
454: if(i) {
455: if (--argc <= 0) Syntax ();
456: sscanf(*++argv, "%c%c%d", passedPty, passedPty+1,
457: &am_slave);
458: if (am_slave <= 0) Syntax();
459: } else
460: am_slave = 0;
461: continue;
462: case ARG_AI:
463: screen->active_icon = i;
464: continue;
465: case ARG_AR:
466: screen->autoraise = i;
467: continue;
468: case ARG_B:
469: if(i) {
470: if (--argc <= 0) Syntax ();
471: screen->border = atoi (*++argv);
472: } else
473: screen->border = DEFBORDER;
474: continue;
475: case ARG_BD:
476: if(i) {
477: if (--argc <= 0) Syntax ();
478: brdr_color = *++argv;
479: } else
480: brdr_color = NULL;
481: continue;
482: case ARG_BG:
483: if(i) {
484: if (--argc <= 0) Syntax ();
485: back_color = *++argv;
486: } else
487: back_color = NULL;
488: continue;
489: case ARG_BW:
490: if(i) {
491: if (--argc <= 0) Syntax ();
492: screen->borderwidth = atoi (*++argv);
493: } else
494: screen->borderwidth = DEFBORDERWIDTH;
495: continue;
496: case ARG_CR:
497: if(i) {
498: if (--argc <= 0) Syntax ();
499: curs_color = *++argv;
500: } else
501: curs_color = NULL;
502: continue;
503: case ARG_CU:
504: screen->curses = i;
505: continue;
506: #ifdef DEBUG
507: case ARG_D:
508: debug = i;
509: continue;
510: #endif DEBUG
511: case ARG_DW:
512: screen->deiconwarp = i;
513: continue;
514: case ARG_E:
515: if(!i) Syntax();
516: if (argc <= 1) Syntax ();
517: command_to_exec = ++argv;
518: break;
519: case ARG_FB:
520: if(fbflag = i) {
521: if (--argc <= 0) Syntax ();
522: f_b = *++argv;
523: fbflag = TRUE;
524: } else {
525: f_b = def_bold_font;
526: fbflag = FALSE;
527: }
528: continue;
529: case ARG_FG:
530: if(i) {
531: if (--argc <= 0) Syntax ();
532: fore_color = *++argv;
533: } else
534: fore_color = NULL;
535: continue;
536: case ARG_FI:
537: if (i) {
538: if (--argc <= 0) Syntax();
539: f_i = *++argv;
540: } else
541: f_i = def_icon_font;
542: continue;
543: case ARG_FN:
544: if(fnflag = i) {
545: if (--argc <= 0) Syntax ();
546: f_n = *++argv;
547: fnflag = TRUE;
548: } else {
549: f_n = def_font;
550: fnflag = FALSE;
551: }
552: continue;
553: case ARG_FT:
554: if(i) {
555: if (--argc <= 0) Syntax ();
556: f_t = *++argv;
557: } else
558: f_t = def_title_font;
559: continue;
560: case ARG_I:
561: screen->icon_show = i ? -1 : 0;
562: continue;
563: case ARG_IB:
564: if(i) {
565: if (--argc <= 0) Syntax ();
566: iconbitmap = *++argv;
567: } else
568: iconbitmap = NULL;
569: continue;
570: case ARG_IT:
571: if(i) {
572: if (--argc <= 0) Syntax ();
573: tekiconbitmap = *++argv;
574: } else
575: tekiconbitmap = NULL;
576: continue;
577: case ARG_J:
578: if(screen->jumpscroll = i)
579: term.flags &= ~SMOOTHSCROLL;
580: else
581: term.flags |= SMOOTHSCROLL;
582: continue;
583: #ifdef KEYBD
584: case ARG_K:
585: if(i) {
586: if (--argc <= 0) Syntax ();
587: keyboardtype = *++argv;
588: } else
589: keyboardtype = NULL;
590: continue;
591: #endif KEYBD
592: case ARG_L:
593: log_on = i;
594: continue;
595: case ARG_LF:
596: if(screen->logfile)
597: free(screen->logfile);
598: if(i) {
599: if (--argc <= 0) Syntax ();
600: if(screen->logfile = malloc(strlen(*++argv) + 1))
601: strcpy(screen->logfile, *argv);
602: } else
603: screen->logfile = NULL;
604: continue;
605: case ARG_LS:
606: login_shell = i;
607: continue;
608: case ARG_MB:
609: screen->marginbell = i;
610: continue;
611: case ARG_MS:
612: if(i) {
613: if (--argc <= 0) Syntax ();
614: mous_color = *++argv;
615: } else
616: mous_color = NULL;
617: continue;
618: case ARG_N:
619: if(i) {
620: if (--argc <= 0) Syntax ();
621: win_name = *++argv;
622: } else
623: win_name = NULL;
624: continue;
625: case ARG_NB:
626: if(i) {
627: if (--argc <= 0) Syntax ();
628: n_marginbell = atoi (*++argv);
629: } else
630: n_marginbell = N_MARGINBELL;
631: continue;
632: case ARG_PO:
633: if(i) {
634: if (--argc <= 0) Syntax ();
635: if((screen->pageoverlap = atoi (*++argv) - 1) < 0)
636: screen->pageoverlap = -1;
637: } else
638: screen->pageoverlap = 0;
639: continue;
640: case ARG_PS:
641: screen->pagemode = i;
642: continue;
643: case ARG_RV:
644: re_verse = i;
645: continue;
646: case ARG_RW:
647: if(i)
648: term.flags |= REVERSEWRAP;
649: else
650: term.flags &= ~REVERSEWRAP;
651: continue;
652: case ARG_S:
653: screen->multiscroll = i;
654: continue;
655: case ARG_SB:
656: screen->scrollbar = i ? SCROLLBARWIDTH : 0;
657: continue;
658: case ARG_SI:
659: screen->scrollinput = i;
660: continue;
661: case ARG_SK:
662: screen->scrollkey = i;
663: continue;
664: case ARG_SL:
665: if(i) {
666: if (--argc <= 0) Syntax ();
667: save_lines = atoi (*++argv);
668: } else
669: save_lines = SAVELINES;
670: continue;
671: case ARG_SN:
672: screen->reversestatus = !i;
673: continue;
674: case ARG_ST:
675: screen->statusline = i;
676: continue;
677: case ARG_T:
678: screen->TekEmu = i;
679: continue;
680: case ARG_TB:
681: screen->fullVwin.titlebar = i;
682: continue;
683: case ARG_TI:
684: screen->textundericon = i;
685: continue;
686: case ARG_AB:
687: screen->audiblebell = i;
688: continue;
689: case ARG_VB:
690: screen->visualbell = i;
691: continue;
692: case ARG_VD:
693: if(i) {
694: if (--argc <= 0) Syntax ();
695: screen->visbelldelay = atoi (*++argv);
696: } else
697: screen->visbelldelay = VISBELLDELAY;
698: continue;
699: default:
700: Syntax ();
701: }
702: break;
703: }
704:
705: term.initflags = term.flags;
706:
707: if (fnflag && !fbflag) f_b = NULL;
708: if (!fnflag && fbflag) f_n = f_b;
709: if(!win_name) {
710: if(get_ty) {
711: char b[256];
712:
713: gethostname(b, sizeof(b) - 1);
714: b[sizeof(b) - 1] = 0;
715: if(strind = index(b, '.')) /* remove domain */
716: *strind = 0;
717: win_name = malloc(strlen(b) + 8);
718: strcpy(win_name, "login(");
719: strcat(win_name, b);
720: strcat(win_name, ")");
721: } else
722: win_name = (am_slave ? "xterm slave" :
723: (command_to_exec ? basename(command_to_exec[0]) :
724: xterm_name));
725: }
726: if(inhibit & I_TEK)
727: screen->TekEmu = FALSE;
728:
729: /* set up stderr properly */
730: i = -1;
731: #ifdef DEBUG
732: if(debug)
733: i = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC,
734: 0666);
735: else
736: #endif DEBUG
737: if(get_ty)
738: i = open("/dev/console", O_WRONLY);
739: if(i >= 0)
740: fileno(stderr) = i;
741: if(fileno(stderr) != (NOFILE - 1)) {
742: dup2(fileno(stderr), (NOFILE - 1));
743: if(fileno(stderr) >= 3)
744: close(fileno(stderr));
745: fileno(stderr) = (NOFILE - 1);
746: }
747:
748: signal (SIGCHLD, reapchild);
749: signal (SIGHUP, SIG_IGN);
750: signal(SIGALRM, onalarm);
751:
752: /* open a terminal for client */
753: get_terminal ();
754: spawn ();
755:
756: Xsocket = screen->display->fd;
757: pty = screen->respond;
758:
759: if (am_slave) { /* Write window id so master end can read and use */
760: write(pty, screen->TekEmu ? (char *)&TWindow(screen) :
761: (char *)&VWindow(screen), sizeof(Window));
762: write(pty, "\n", 1);
763: }
764:
765: if(log_on) {
766: log_on = FALSE;
767: StartLog(screen);
768: }
769: screen->inhibit = inhibit;
770: mode = 1;
771: if (ioctl (pty, FIONBIO, &mode) == -1) SysError (ERROR_FIONBIO);
772:
773: pty_mask = 1 << pty;
774: X_mask = 1 << Xsocket;
775: Select_mask = pty_mask | X_mask;
776: max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
777:
778: #ifdef DEBUG
779: if (debug) printf ("debugging on\n");
780: #endif DEBUG
781: XErrorHandler(xerror);
782: XIOErrorHandler(xioerror);
783: for( ; ; )
784: if(screen->TekEmu)
785: TekRun();
786: else
787: VTRun();
788: }
789:
790: char *basename(name)
791: char *name;
792: {
793: register char *cp;
794: char *rindex();
795:
796: return((cp = rindex(name, '/')) ? cp + 1 : name);
797: }
798:
799: static struct argstr {
800: char *arg;
801: int val;
802: } arg[] = {
803: {"132", ARG_132},
804: #ifdef TIOCCONS
805: {"C", ARG__C},
806: #endif TIOCCONS
807: {"L", ARG__L},
808: {"S", ARG__S},
809: {"ab", ARG_AB},
810: {"ai", ARG_AI},
811: {"ar", ARG_AR},
812: {"b", ARG_B},
813: {"bd", ARG_BD},
814: {"bg", ARG_BG},
815: {"bw", ARG_BW},
816: {"cr", ARG_CR},
817: {"cu", ARG_CU},
818: #ifdef DEBUG
819: {"d", ARG_D},
820: #endif DEBUG
821: {"dw", ARG_DW},
822: {"e", ARG_E},
823: {"fb", ARG_FB},
824: {"fg", ARG_FG},
825: {"fi", ARG_FI},
826: {"fn", ARG_FN},
827: {"ft", ARG_FT},
828: {"i", ARG_I},
829: {"ib", ARG_IB},
830: {"it", ARG_IT},
831: {"j", ARG_J},
832: #ifdef KEYBD
833: {"k", ARG_K},
834: #endif KEYBD
835: {"l", ARG_L},
836: {"lf", ARG_LF},
837: {"ls", ARG_LS},
838: {"mb", ARG_MB},
839: {"ms", ARG_MS},
840: {"n", ARG_N},
841: {"nb", ARG_NB},
842: {"po", ARG_PO},
843: {"ps", ARG_PS},
844: {"r", ARG_RV},
845: {"rv", ARG_RV},
846: {"rw", ARG_RW},
847: {"s", ARG_S},
848: {"sb", ARG_SB},
849: {"si", ARG_SI},
850: {"sk", ARG_SK},
851: {"sl", ARG_SL},
852: {"sn", ARG_SN},
853: {"st", ARG_ST},
854: {"t", ARG_T},
855: {"tb", ARG_TB},
856: {"ti", ARG_TI},
857: {"vb", ARG_VB},
858: {"vd", ARG_VD},
859: {"w", ARG_BW},
860: };
861:
862: argument(s)
863: register char *s;
864: {
865: register int i, low, high, com;
866:
867: low = 0;
868: high = sizeof(arg) / sizeof(struct argstr) - 1;
869: while(low <= high) {/* use binary search, arg in lexigraphic order */
870: i = (low + high) / 2;
871: if ((com = strcmp(s, arg[i].arg)) == 0)
872: return(arg[i].val);
873: if(com > 0)
874: low = i + 1;
875: else
876: high = i - 1;
877: }
878: return(-1);
879: }
880:
881: static char *ustring[] = {
882: "Usage: xterm [-132] [-ab] [-ai] [-ar] [-b margin_width] [-bd border_color] \\\n",
883: #ifdef ARG__C
884: " [-bg backgrnd_color] [-bw border_width] [-C] [-cr cursor_color] [-cu] \\\n",
885: #else ARG__C
886: " [-bg backgrnd_color] [-bw border_width] [-cr cursor_color] [-cu] \\\n",
887: #endif ARG__C
888: " [-dw] [-fb bold_font] [-fg foregrnd_color] [-fi icon_font] [-fn norm_font] \\\n",
889: " [-ft title_font] [-i] [-ib iconbitmap] [-it tekiconbitmap] [-j] \\\n",
890: #ifdef ARG_K
891: " [-k keybd] [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
892: #else ARG_K
893: " [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
894: #endif ARG_K
895: " [-n name] [-nb bell_margin] [-po] [-ps] [-rv] [-rw] [-s] \\\n",
896: " [-sb] [-si] [-sk] [-sl save_lines] [-sn] [-st] [-t] [-tb] \\\n",
897: " [-ti] [-vb] [-vd visbelldelay] [=[width]x[height][[+-]xoff[[+-]yoff]]] \\\n",
898: " [%[width]x[height][[+-]xoff[[+-]yoff]]] [#[+-]xoff[[+-]yoff]] \\\n",
899: " [-e command_to_exec]\n\n",
900: "Fonts must be of fixed width and of same size;\n",
901: "If only one font is specified, it will be used for normal and bold text\n",
902: "The -132 option allows 80 <-> 132 column escape sequences\n",
903: "The -ab option enables audible bell\n",
904: "The -ai option turns on miniature (active) icons\n",
905: "The -ar option turns auto raise window mode on\n",
906: #ifdef ARG__C
907: "The -C option forces output to /dev/console to appear in this window\n",
908: #endif ARG__C
909: "The -cu option turns a curses bug fix on\n",
910: "The -dw option warps the mouse on deiconify\n",
911: "The -i option enables icon startup\n",
912: "The -j option enables jump scroll\n",
913: "The -l option enables logging\n",
914: "The -ls option makes the shell a login shell\n",
915: "The -mb option turns the margin bell on\n",
916: "The -ps option turns page scroll on\n",
917: "The -rv option turns reverse video on\n",
918: "The -rw option turns reverse wraparound on\n",
919: "The -s option enables asynchronous scrolling\n",
920: "The -sb option enables the scrollbar\n",
921: "The -si option enables re-positioning the scrollbar at the bottom on input\n",
922: "The -sk option causes the scrollbar to position at the bottom on a key\n",
923: "The -sn option makes the status line normal video \n",
924: "The -st option enables the status line\n",
925: "The -t option starts Tektronix mode\n",
926: "The -tb option enables the titlebar\n",
927: "The -ti option places the window name under the icon\n",
928: "The -vb option enables visual bell\n",
929: 0
930: };
931:
932: Syntax ()
933: {
934: register char **us = ustring;
935:
936: while (*us) fputs(*us++, stderr);
937: exit (1);
938: }
939:
940: get_pty (pty, tty)
941: /*
942: opens a pty, storing fildes in pty and tty.
943: */
944: int *pty, *tty;
945: {
946: int devindex, letter = 0;
947:
948: while (letter < 4) {
949: ttydev [8] = ptydev [8] = "pqrs" [letter++];
950: devindex = 0;
951:
952: while (devindex < 16) {
953: ttydev [9] = ptydev [9] = "0123456789abcdef" [devindex++];
954: if ((*pty = open (ptydev, O_RDWR)) < 0)
955: continue;
956: if ((*tty = open (ttydev, O_RDWR)) < 0) {
957: close(*pty);
958: continue;
959: }
960: return;
961: }
962: }
963:
964: fprintf (stderr, "%s: Not enough available pty's\n", xterm_name);
965: exit (ERROR_PTYS);
966: }
967:
968: #if BSD >= 43
969: #define TTYGRPNAME "tty" /* name of group to own ttys */
970: #define TTYGID(gid) tty_gid(gid) /* gid that owns all ttys */
971:
972: tty_gid(default_gid)
973: int default_gid;
974: {
975: struct group *getgrnam(), *gr;
976: int gid = default_gid;
977:
978: gr = getgrnam(TTYGRPNAME);
979: if (gr != (struct group *) 0)
980: gid = gr->gr_gid;
981:
982: endgrent();
983:
984: return (gid);
985: }
986: #endif
987:
988: get_terminal ()
989: /*
990: * sets up X and initializes the terminal structure except for term.buf.fildes.
991: */
992: {
993: register Screen *screen = &term.screen;
994: register int try;
995: int on = 1;
996: Color cdef;
997: char *malloc();
998:
999: for (try = 10 ; ; ) {
1000: if (screen->display = XOpenDisplay(display))
1001: break;
1002: if (!get_ty) {
1003: #ifdef TIOCCONS
1004: /*
1005: * Hack: if console is set, this is probably
1006: * the login window from xinit.
1007: */
1008: if (Console)
1009: continue;
1010: #endif TIOCCONS
1011: fprintf(stderr, "%s: No such display server %s\n", xterm_name,
1012: XDisplayName(display));
1013: exit(ERROR_NOX);
1014: }
1015: if (--try <= 0) {
1016: fprintf (stderr, "%s: Can't connect to display server %s\n",
1017: xterm_name, XDisplayName(display));
1018: exit (ERROR_NOX2);
1019: }
1020: sleep (5);
1021: }
1022: (void) setsockopt(screen->display->fd, SOL_SOCKET, SO_KEEPALIVE,
1023: &on, sizeof(on));
1024:
1025: if(re_verse) {
1026: B_Pixel = WhitePixel;
1027: B_Pixmap = WhitePixmap;
1028: W_Pixel = BlackPixel;
1029: W_Pixmap = BlackPixmap;
1030: } else {
1031: B_Pixel = BlackPixel;
1032: B_Pixmap = BlackPixmap;
1033: W_Pixel = WhitePixel;
1034: W_Pixmap = WhitePixmap;
1035: }
1036:
1037: if (brdr_color && DisplayCells() > 2 &&
1038: XParseColor(brdr_color, &cdef) && XGetHardwareColor(&cdef)) {
1039: if(!(screen->bordertile = XMakeTile(cdef.pixel)))
1040: Error(ERROR_BORDER);
1041: } else
1042: screen->bordertile = B_Pixmap;
1043: screen->graybordertile = make_gray();
1044:
1045: screen->foreground = B_Pixel;
1046: screen->background = W_Pixel;
1047: screen->cursorcolor = B_Pixel;
1048: screen->mousecolor = B_Pixel;
1049:
1050: if (DisplayCells() > 2 && (fore_color || back_color ||
1051: curs_color)) {
1052: if (fore_color && XParseColor(fore_color, &cdef) &&
1053: XGetHardwareColor(&cdef)) {
1054: screen->foreground = cdef.pixel;
1055: screen->color |= C_FOREGROUND;
1056: }
1057: if (back_color && XParseColor(back_color, &cdef) &&
1058: XGetHardwareColor(&cdef)) {
1059: screen->background = cdef.pixel;
1060: screen->color |= C_BACKGROUND;
1061: }
1062: if (curs_color && XParseColor(curs_color, &cdef) &&
1063: XGetHardwareColor(&cdef)) {
1064: screen->cursorcolor = cdef.pixel;
1065: screen->color |= C_CURSOR;
1066: } else
1067: screen->cursorcolor = screen->foreground;
1068: }
1069:
1070: if (mous_color && DisplayCells() > 2 &&
1071: XParseColor(mous_color, &cdef) && XGetHardwareColor(&cdef)) {
1072: screen->mousecolor = cdef.pixel;
1073: screen->color |= C_MOUSE;
1074: } else
1075: screen->mousecolor = screen->cursorcolor;
1076:
1077: if(screen->color & C_BACKGROUND) {
1078: if(!(screen->bgndtile = XMakeTile(screen->background)))
1079: Error(ERROR_BACK);
1080: } else
1081: screen->bgndtile = W_Pixmap;
1082: screen->arrow = make_arrow(screen->mousecolor, screen->background,
1083: GXcopy);
1084:
1085: XAutoRepeatOn();
1086: if((screen->titlefont = XOpenFont(f_t)) == NULL) {
1087: fprintf(stderr, "%s: Can't get title font %s\n", xterm_name,
1088: f_t);
1089: exit(ERROR_TITLEFONT);
1090: }
1091: screen->title_n_size= XQueryWidth("m", screen->titlefont->id);
1092: screen->titleheight = screen->titlefont->height + 2 * TITLEPAD + 1;
1093: if(screen->fullVwin.titlebar)
1094: screen->fullVwin.titlebar =
1095: screen->fullTwin.titlebar = screen->titleheight;
1096: IconInit(screen, iconbitmap, tekiconbitmap);
1097: }
1098:
1099: static char *tekterm[] = {
1100: "tek4015",
1101: "tek4014",
1102: "tek4013",
1103: "tek4010",
1104: "dumb",
1105: 0
1106: };
1107:
1108: static char *vtterm[] = {
1109: "xterms",
1110: "xterm",
1111: "vt102",
1112: "vt100",
1113: "ansi",
1114: "dumb",
1115: 0
1116: };
1117:
1118: spawn ()
1119: /*
1120: * Inits pty and tty and forks a login process.
1121: * Does not close fd Xsocket.
1122: * If getty, execs getty rather than csh and uses std fd's rather
1123: * than opening a pty/tty pair.
1124: * If slave, the pty named in passedPty is already open for use
1125: */
1126: {
1127: register Screen *screen = &term.screen;
1128: int Xsocket = screen->display->fd;
1129: int index1, tty = -1;
1130: int discipline;
1131: unsigned lmode;
1132: struct tchars tc;
1133: struct ltchars ltc;
1134: struct sgttyb sg;
1135:
1136: char termcap [1024];
1137: char newtc [1024];
1138: char *ptr, *shname;
1139: int i, no_dev_tty = FALSE;
1140: char **envnew; /* new environment */
1141: char buf[32];
1142: char *TermName = NULL;
1143: int ldisc = 0;
1144: #ifdef sun
1145: #ifdef TIOCSSIZE
1146: struct ttysize ts;
1147: #endif TIOCSSIZE
1148: #else sun
1149: #ifdef TIOCSWINSZ
1150: struct winsize ws;
1151: #endif TIOCSWINSZ
1152: #endif sun
1153: struct passwd *pw = NULL;
1154: #ifdef UTMP
1155: struct utmp utmp;
1156: #endif UTMP
1157: extern int Exit();
1158: struct passwd *getpwuid();
1159: char *getenv();
1160: char *index (), *rindex (), *strindex ();
1161:
1162: screen->uid = getuid();
1163: screen->gid = getgid();
1164:
1165: #ifdef UTMP
1166: added_utmp_entry = FALSE;
1167: #endif UTMP
1168: /* so that TIOCSWINSZ || TIOCSIZE doesn't block */
1169: signal(SIGTTOU,SIG_IGN);
1170: if(!(screen->TekEmu ? TekInit() : VTInit()))
1171: exit(ERROR_INIT);
1172:
1173: if(screen->TekEmu) {
1174: envnew = tekterm;
1175: ptr = newtc;
1176: } else {
1177: /*
1178: * Special case of a 80x24 window, use "xterms"
1179: */
1180: envnew = (screen->max_col == 79 && screen->max_row ==
1181: 23) ? vtterm : &vtterm[1];
1182: ptr = termcap;
1183: }
1184: while(*envnew) {
1185: if(tgetent(ptr, *envnew) == 1) {
1186: TermName = *envnew;
1187: if(!screen->TekEmu)
1188: resize(screen, TermName, termcap, newtc);
1189: break;
1190: }
1191: envnew++;
1192: }
1193:
1194: if (get_ty) {
1195: screen->respond = loginpty;
1196: if((tslot = ttyslot()) <= 0)
1197: SysError(ERROR_TSLOT);
1198: #ifdef TIOCCONS
1199: if (Console) {
1200: int on = 1;
1201: if (ioctl (tty, TIOCCONS, &on) == -1) {
1202: perror("xterm: ioctl TIOCCONS");
1203: Console = 0;
1204: }
1205: }
1206: #endif TIOCCONS
1207: } else if (am_slave) {
1208: screen->respond = am_slave;
1209: ptydev[8] = ttydev[8] = passedPty[0];
1210: ptydev[9] = ttydev[9] = passedPty[1];
1211: if((tslot = ttyslot()) <= 0)
1212: SysError(ERROR_TSLOT2);
1213: setgid (screen->gid);
1214: setuid (screen->uid);
1215: } else {
1216: if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) {
1217: if (errno != ENXIO) SysError(ERROR_OPDEVTTY);
1218: else {
1219: no_dev_tty = TRUE;
1220: sg = d_sg;
1221: tc = d_tc;
1222: discipline = d_disipline;
1223: ltc = d_ltc;
1224: lmode = d_lmode;
1225: }
1226: } else {
1227: /* get a copy of the current terminal's state */
1228:
1229: if(ioctl(tty, TIOCGETP, &sg) == -1)
1230: SysError (ERROR_TIOCGETP);
1231: if(ioctl(tty, TIOCGETC, &tc) == -1)
1232: SysError (ERROR_TIOCGETC);
1233: if(ioctl(tty, TIOCGETD, &discipline) == -1)
1234: SysError (ERROR_TIOCGETD);
1235: if(ioctl(tty, TIOCGLTC, <c) == -1)
1236: SysError (ERROR_TIOCGLTC);
1237: if(ioctl(tty, TIOCLGET, &lmode) == -1)
1238: SysError (ERROR_TIOCLGET);
1239: close (tty);
1240:
1241: /* close all std file descriptors */
1242: for (index1 = 0; index1 < 3; index1++)
1243: close (index1);
1244: if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
1245: SysError (ERROR_OPDEVTTY2);
1246:
1247: if (ioctl (tty, TIOCNOTTY, 0) == -1)
1248: SysError (ERROR_NOTTY);
1249: close (tty);
1250: }
1251:
1252: get_pty (&screen->respond, &tty);
1253:
1254: if (screen->respond != Xsocket + 1) {
1255: dup2 (screen->respond, Xsocket + 1);
1256: close (screen->respond);
1257: screen->respond = Xsocket + 1;
1258: }
1259:
1260: #if BSD >= 43
1261: /* change ownership of tty to real user id and tty gid */
1262: chown (ttydev, screen->uid, TTYGID(screen->gid));
1263:
1264: /* change protection of tty */
1265: chmod (ttydev, 0620);
1266: #else
1267: /* change ownership of tty to real group and user id */
1268: chown (ttydev, screen->uid, screen->gid);
1269:
1270: /* change protection of tty */
1271: chmod (ttydev, 0622);
1272: #endif
1273:
1274: if (tty != Xsocket + 2) {
1275: dup2 (tty, Xsocket + 2);
1276: close (tty);
1277: tty = Xsocket + 2;
1278: }
1279:
1280: /* set the new terminal's state to be the old one's
1281: with minor modifications for efficiency */
1282:
1283: sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
1284: sg.sg_flags |= ECHO | CRMOD;
1285: /* make sure speed is set on pty so that editors work right*/
1286: sg.sg_ispeed = B9600;
1287: sg.sg_ospeed = B9600;
1288: /* reset t_brkc to default value */
1289: tc.t_brkc = -1;
1290:
1291: if (ioctl (tty, TIOCSETP, &sg) == -1)
1292: SysError (ERROR_TIOCSETP);
1293: if (ioctl (tty, TIOCSETC, &tc) == -1)
1294: SysError (ERROR_TIOCSETC);
1295: if (ioctl (tty, TIOCSETD, &discipline) == -1)
1296: SysError (ERROR_TIOCSETD);
1297: if (ioctl (tty, TIOCSLTC, <c) == -1)
1298: SysError (ERROR_TIOCSLTC);
1299: if (ioctl (tty, TIOCLSET, &lmode) == -1)
1300: SysError (ERROR_TIOCLSET);
1301: #ifdef TIOCCONS
1302: if (Console) {
1303: int on = 1;
1304: if (ioctl (tty, TIOCCONS, &on) == -1) {
1305: perror("xterm: ioctl TIOCCONS");
1306: Console = 0;
1307: }
1308: }
1309: #endif TIOCCONS
1310:
1311: close (open ("/dev/null", O_RDWR, 0));
1312:
1313: for (index1 = 0; index1 < 3; index1++)
1314: dup2 (tty, index1);
1315: if((tslot = ttyslot()) <= 0)
1316: SysError(ERROR_TSLOT3);
1317: #ifdef UTMP
1318: if(login_shell && (pw = getpwuid(screen->uid)) &&
1319: (i = open(etc_utmp, O_WRONLY)) >= 0) {
1320: bzero((char *)&utmp, sizeof(struct utmp));
1321: (void) strcpy(utmp.ut_line, &ttydev[5]);
1322: (void) strcpy(utmp.ut_name, pw->pw_name);
1323: if (strncmp(DisplayName(), "unix:", 5) != 0)
1324: (void) strcpy(utmp.ut_host, DisplayName());
1325: time(&utmp.ut_time);
1326: lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
1327: write(i, (char *)&utmp, sizeof(struct utmp));
1328: close(i);
1329: added_utmp_entry = TRUE;
1330: }
1331: #endif UTMP
1332: }
1333:
1334: #ifdef sun
1335: #ifdef TIOCSSIZE
1336: /* tell tty how big window is */
1337: if(screen->TekEmu) {
1338: ts.ts_lines = 38;
1339: ts.ts_cols = 81;
1340: } else {
1341: ts.ts_lines = screen->max_row + 1;
1342: ts.ts_cols = screen->max_col + 1;
1343: }
1344: ioctl (screen->respond, TIOCSSIZE, &ts);
1345: #endif TIOCSSIZE
1346: #else sun
1347: #ifdef TIOCSWINSZ
1348: /* tell tty how big window is */
1349: if(screen->TekEmu) {
1350: ws.ws_row = 38;
1351: ws.ws_col = 81;
1352: ws.ws_xpixel = TFullWidth(screen);
1353: ws.ws_ypixel = TFullHeight(screen);
1354: } else {
1355: ws.ws_row = screen->max_row + 1;
1356: ws.ws_col = screen->max_col + 1;
1357: ws.ws_xpixel = FullWidth(screen);
1358: ws.ws_ypixel = FullHeight(screen);
1359: }
1360: ioctl (screen->respond, TIOCSWINSZ, &ws);
1361: #endif TIOCSWINSZ
1362: #endif sun
1363:
1364: if (!am_slave) {
1365: if ((screen->pid = fork ()) == -1)
1366: SysError (ERROR_FORK);
1367:
1368: if (screen->pid == 0) {
1369: extern char **environ;
1370: int pgrp = getpid();
1371: char shell_name[64];
1372:
1373: close (Xsocket);
1374: close (screen->respond);
1375: if(fileno(stderr) >= 3)
1376: close (fileno(stderr));
1377:
1378: if (tty >= 0) close (tty);
1379:
1380: signal (SIGCHLD, SIG_DFL);
1381: signal (SIGHUP, SIG_IGN);
1382:
1383: /* copy the environment before Setenving */
1384: for (i = 0 ; environ [i] != NULL ; i++) ;
1385: /*
1386: * The `4' is the number of Setenv() calls which may add
1387: * a new entry to the environment. The `1' is for the
1388: * NULL terminating entry.
1389: */
1390: envnew = (char **) calloc (i + (4 + 1), sizeof(char *));
1391: bcopy((char *)environ, (char *)envnew, i * sizeof(char *));
1392: environ = envnew;
1393: Setenv ("TERM=", TermName);
1394: if(!TermName)
1395: *newtc = 0;
1396: Setenv ("TERMCAP=", newtc);
1397: sprintf(buf, "%d", screen->TekEmu ? (int)TWindow(screen) :
1398: (int)VWindow(screen));
1399: Setenv ("WINDOWID=", buf);
1400: /* put the display into the environment of the shell*/
1401: if (display[0] != '\0')
1402: Setenv ("DISPLAY=", screen->display->displayname);
1403:
1404: signal(SIGTERM, SIG_DFL);
1405: ioctl(0, TIOCSPGRP, &pgrp);
1406: setpgrp (0, 0);
1407: close(open(ttyname(0), O_WRONLY, 0));
1408: setpgrp (0, pgrp);
1409:
1410: setgid (screen->gid);
1411: setuid (screen->uid);
1412:
1413: if (command_to_exec) {
1414: execvp(*command_to_exec, command_to_exec);
1415: /* print error message on screen */
1416: fprintf(stderr, "%s: Can't execvp %s\n", xterm_name,
1417: *command_to_exec);
1418: }
1419: signal(SIGHUP, SIG_IGN);
1420: if (get_ty) {
1421: ioctl (0, TIOCNOTTY, 0);
1422: execl ("/etc/getty", "+", "Xwindow", get_ty, 0);
1423: }
1424: signal(SIGHUP, SIG_DFL);
1425:
1426: #ifdef UTMP
1427: if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
1428: ((pw == NULL && (pw = getpwuid(screen->uid)) == NULL) ||
1429: *(ptr = pw->pw_shell) == 0))
1430: #else UTMP
1431: if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
1432: ((pw = getpwuid(screen->uid)) == NULL ||
1433: *(ptr = pw->pw_shell) == 0))
1434: #endif UTMP
1435: ptr = "/bin/sh";
1436: if(shname = rindex(ptr, '/'))
1437: shname++;
1438: else
1439: shname = ptr;
1440: i = strlen(shname) - 3;
1441: ldisc = (strcmp("csh", shname + i) == 0 ||
1442: strcmp("ksh", shname + i) == 0) ? NTTYDISC : 0;
1443: ioctl(0, TIOCSETD, &ldisc);
1444: if (login_shell) {
1445: strcpy(shell_name, "-");
1446: strcat(shell_name, shname);
1447: } else
1448: strcpy(shell_name, shname);
1449: execl (ptr, shell_name, 0);
1450: fprintf (stderr, "%s: Could not exec %s!\n", xterm_name, ptr);
1451: sleep(5);
1452: exit(ERROR_EXEC);
1453: }
1454: }
1455:
1456: if(tty >= 0) close (tty);
1457: signal(SIGHUP,SIG_IGN);
1458:
1459: if (!no_dev_tty) {
1460: if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
1461: SysError(ERROR_OPDEVTTY3);
1462: for (index1 = 0; index1 < 3; index1++)
1463: dup2 (tty, index1);
1464: if (tty > 2) close (tty);
1465: }
1466:
1467: signal(SIGINT, Exit);
1468: signal(SIGQUIT, Exit);
1469: signal(SIGTERM, Exit);
1470: }
1471:
1472: Exit(n)
1473: int n;
1474: {
1475: register Screen *screen = &term.screen;
1476: #ifdef UTMP
1477: register int i;
1478: struct utmp utmp;
1479:
1480: if(added_utmp_entry && (i = open(etc_utmp, O_WRONLY)) >= 0) {
1481: bzero((char *)&utmp, sizeof(struct utmp));
1482: lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
1483: write(i, (char *)&utmp, sizeof(struct utmp));
1484: close(i);
1485: }
1486: #endif UTMP
1487: if(screen->logging)
1488: CloseLog(screen);
1489:
1490: if(!get_ty && !am_slave) {
1491: /* restore ownership of tty */
1492: chown (ttydev, 0, 0);
1493:
1494: /* restore modes of tty */
1495: chmod (ttydev, 0666);
1496: }
1497: (void) close(screen->respond);
1498: exit(n);
1499: }
1500:
1501: resize(screen, TermName, oldtc, newtc)
1502: Screen *screen;
1503: char *TermName;
1504: register char *oldtc, *newtc;
1505: {
1506: register char *ptr1, *ptr2;
1507: register int i;
1508: register int li_first = 0;
1509: register char *temp;
1510: char *index(), *strindex();
1511:
1512: if ((ptr1 = strindex (oldtc, "co#")) == NULL){
1513: fprintf(stderr, "%s: Can't find co# in termcap string %s\n",
1514: xterm_name, TermName);
1515: exit (ERROR_NOCO);
1516: }
1517: if ((ptr2 = strindex (oldtc, "li#")) == NULL){
1518: fprintf(stderr, "%s: Can't find li# in termcap string %s\n",
1519: xterm_name, TermName);
1520: exit (ERROR_NOLI);
1521: }
1522: if(ptr1 > ptr2) {
1523: li_first++;
1524: temp = ptr1;
1525: ptr1 = ptr2;
1526: ptr2 = temp;
1527: }
1528: ptr1 += 3;
1529: ptr2 += 3;
1530: strncpy (newtc, oldtc, i = ptr1 - oldtc);
1531: newtc += i;
1532: sprintf (newtc, "%d", li_first ? screen->max_row + 1 :
1533: screen->max_col + 1);
1534: newtc += strlen(newtc);
1535: ptr1 = index (ptr1, ':');
1536: strncpy (newtc, ptr1, i = ptr2 - ptr1);
1537: newtc += i;
1538: sprintf (newtc, "%d", li_first ? screen->max_col + 1 :
1539: screen->max_row + 1);
1540: ptr2 = index (ptr2, ':');
1541: strcat (newtc, ptr2);
1542: }
1543:
1544: static reapchild ()
1545: {
1546: union wait status;
1547: register int pid;
1548:
1549: #ifdef DEBUG
1550: if (debug) fputs ("Exiting\n", stderr);
1551: #endif DEBUG
1552: pid = wait3 (&status, WNOHANG, NULL);
1553: if (!pid) return;
1554: if (pid != term.screen.pid) return;
1555:
1556: Cleanup(0);
1557: }
1558:
1559: consolepr(string)
1560: char *string;
1561: {
1562: extern int errno;
1563: extern char *sys_errlist[];
1564: int oerrno;
1565: int f;
1566:
1567: oerrno = errno;
1568: f = open("/dev/console",O_WRONLY);
1569: write(f, "xterm: ", 7);
1570: write(f, string, strlen(string));
1571: write(f, ": ", 2);
1572: write(f, sys_errlist[oerrno],strlen(sys_errlist[oerrno]));
1573: write(f, "\n", 1);
1574: close(f);
1575: if ((f = open("/dev/tty", 2)) >= 0) {
1576: ioctl(f, TIOCNOTTY, 0);
1577: close(f);
1578: }
1579: }
1580:
1581: checklogin()
1582: {
1583: register int i, j;
1584: register struct passwd *pw;
1585: struct utmp utmp;
1586:
1587: if((i = open(etc_utmp, O_RDONLY)) < 0)
1588: return(FALSE);
1589: lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
1590: j = read(i, (char *)&utmp, sizeof(utmp));
1591: close(i);
1592: if(j != sizeof(utmp) || strcmp(get_ty, utmp.ut_line) != 0 ||
1593: !*utmp.ut_name || (pw = getpwnam(utmp.ut_name)) == NULL)
1594: return(FALSE);
1595: chdir(pw->pw_dir);
1596: setgid(pw->pw_gid);
1597: setuid(pw->pw_uid);
1598: L_flag = 0;
1599: return(TRUE);
1600: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.