1 /*
2 * shl - shell layer manager
3 *
4 * Gunnar Ritter, Freiburg i. Br., Germany, April 2001.
5 *
6 * This software is provided 'as-is', without any express or implied
7 * warranty. In no event will the authors be held liable for any damages
8 * arising from the use of this software.
9 *
10 * Permission is granted to anyone to use this software for any purpose,
11 * including commercial applications, and to alter it and redistribute
12 * it freely, subject to the following restrictions:
13 *
14 * 1. The origin of this software must not be misrepresented; you must not
15 * claim that you wrote the original software. If you use this software
16 * in a product, an acknowledgment in the product documentation would be
17 * appreciated but is not required.
18 *
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
21 *
22 * 3. This notice may not be removed or altered from any source distribution.
23 */
24
25
26 #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
27 #define USED __attribute__ ((used))
28 #elif defined __GNUC__
29 #define USED __attribute__ ((unused))
30 #else
31 #define USED
32 #endif
33 static const char sccsid[] USED = "@(#)shl.sl 1.29 (gritter) 12/25/06";
34
35 #if !defined (__FreeBSD__) && !defined (__hpux) && !defined (_AIX) && \
36 !defined (__NetBSD__) && !defined (__OpenBSD__) && \
37 !defined (__DragonFly__) && !defined (__APPLE__)
38
39 /*
40 * UnixWare 2.1 needs _KMEMUSER to access some flags for STREAMS. Maybe other
41 * SVR4 do too, so define it on non-Sun systems for now.
42 */
43 #ifndef sun
44 #define _KMEMUSER
45 #endif
46
47 #include <sys/types.h>
48 #include <termios.h>
49
50 /*
51 * Structure for a single shell layer.
52 */
53 struct layer {
54 struct layer *l_prev; /* previous node in layer list */
55 struct layer *l_next; /* next node in layer list */
56 struct termios l_tio; /* termios struct of layer */
57 char l_name[9]; /* name of layer */
58 char l_line[64]; /* device name for tty */
59 pid_t l_pid; /* pid/pgid of layer */
60 int l_pty; /* pty master */
61 int l_blk; /* output is blocked */
62 };
63
64 extern int sysv3;
65
66 #ifdef __dietlibc__
67 #define _XOPEN_SOURCE 600L
68 #endif
69
70 /*
71 * This implements the interface of the SVID3 shl command using regular
72 * SVR4-type pseudo terminal mechanisms. Each layer gets its own pty,
73 * and shl poll()s them and writes their output to its own tty. Input
74 * is collected by the same mechanism in reverse direction.
75 */
76
77 #include <sys/wait.h>
78 #include <sys/stat.h>
79 #include <sys/ioctl.h>
80 #include <fcntl.h>
81 #include <signal.h>
82 #include <unistd.h>
83 #include <string.h>
84 #include <stdlib.h>
85 #include <errno.h>
86 #include <libgen.h>
87 #include <limits.h>
88 #include <stdarg.h>
89 #if !defined (__dietlibc__) && !defined (__UCLIBC__)
90 #include <stropts.h>
91 #endif
92 #include <poll.h>
93 #include <stdio.h>
94 #include <ctype.h>
95 #include <time.h>
96 #include <utmpx.h>
97 #include <sigset.h>
98 #include <pathconf.h>
99 #if !defined (__dietlibc__) && !defined (__UCLIBC__)
100 #define WORDEXP
101 #endif
102 #ifdef WORDEXP
103 #include <wordexp.h>
104 #endif /* WORDEXP */
105 #include <pwd.h>
106 #include <locale.h>
107 #ifndef __linux__
108 #include <termio.h>
109 #include <sys/stream.h>
110 #include <sys/ptms.h>
111 #endif /* !__linux__ */
112
113 /*
114 * Linux systems call VSWTC what the SVID calls VSWTCH.
115 */
116 #ifndef VSWTCH
117 #ifdef VSWTC
118 #define VSWTCH VSWTC
119 #else
120 #error "Cannot find a VSWTCH or VSWTC key definition"
121 #endif /* VSWTC */
122 #endif /* !VSWTCH */
123
124 /*
125 * The SVID specifies ^Z to be used as switch character if it is unset
126 * when shl starts. As this implementation can co-exist with job control
127 * within its layers, it might be a good idea to change either the susp
128 * or the switch key before starting shl.
129 */
130 #define DEFSWTCH '\32' /* default switch character (^Z) */
131
132 /*
133 * Only used if $SHELL is not set.
134 */
135 #define DEFSHELL "/bin/sh" /* default shell */
136
137 /*
138 * This implementation of shl can support an arbitrary number of layers. As
139 * pseudo-terminals are a sparse resource on most systems, the old default
140 * of seven layers as a maximum is retained here. It can be raised without
141 * problems if suitable.
142 */
143 #define MAXLAYER 7 /* maximum layers */
144
145 /*
146 * Locale-independent whitespace recognition.
147 */
148 #define blankchar(c) ((c) == ' ' || (c) == '\t')
149
150 /*
151 * Constants for utmp handling.
152 */
153 enum {
154 UTMP_ADD, UTMP_DEL
155 };
156
157 /*
158 * This structure describes a shl command. A table of all commands resides
159 * at the bottom end of this file.
160 */
161 struct command {
162 char *c_string; /* command's name */
163 int (*c_func)(char *); /* function to do it */
164 char *c_arg; /* argument to command */
165 char *c_desc; /* command's description */
166 int c_dnum; /* description's number in msg cat. */
167 };
168
169 unsigned errstat; /* error status of last command */
170 char *progname; /* argv[0] to main() */
171 char *shell; /* $SHELL */
172 char *dashell; /* -`basename $SHELL` */
173 pid_t mypid; /* shl's own pid */
174 uid_t myuid; /* shl's own uid */
175 uid_t myeuid; /* shl's own euid/saved set-user-ID */
176 gid_t mygid; /* shl's own gid */
177 gid_t myegid; /* shl's own egid/saved set-group-ID */
178 unsigned lcount; /* count of layers */
179 char cmdbuf[LINE_MAX]; /* buffer for commands */
180 char *cmdptr; /* current pointer for cmdbuf */
181 int hadquit; /* quit cmd executed but layers run */
182 struct layer *l0; /* begin of layer chain */
183 struct layer *lcur; /* current layer */
184 struct termios otio; /* old terminal attributes */
185 struct termios dtio; /* default terminal attributes */
186 struct termios rtio; /* raw terminal attributes */
187 struct winsize winsz; /* window sizes */
188 void (*oldhup)(int); /* old SIGHUP handler */
189 void (*oldint)(int); /* old SIGINT handler */
190 void (*oldquit)(int); /* old SIGQUIT handler */
191 void (*oldttou)(int); /* old SIGTTOU handler */
192 void (*oldtstp)(int); /* old SIGTSTP handler */
193 void (*oldttin)(int); /* old SIGTTIN handler */
194 void (*oldwinch)(int); /* old SIGWINCH handler */
195
196 /*
197 * Common english error messages.
198 */
199 const char *syntax = "syntax error";
200 const char *lnotfound = "layer %s not found";
201 const char *nocurl = "no current layer";
202
203 /*
204 * The table of all shl commands residing at the bottom end of this file.
205 */
206 extern struct command commands[];
207
208 /*
209 * Messages to stdout.
210 */
211 void
msg(const char * fmt,...)212 msg(const char *fmt, ...)
213 {
214 char buf[256];
215 va_list ap;
216
217 va_start(ap, fmt);
218 vsnprintf(buf, sizeof buf - 1, fmt, ap);
219 va_end(ap);
220 strcat(buf, "\n");
221 write(2, buf, strlen(buf));
222 }
223
224 /*
225 * Memory allocation with check.
226 */
227 void *
srealloc(void * vp,size_t nbytes)228 srealloc(void *vp, size_t nbytes)
229 {
230 void *p;
231
232 if ((p = (void *)realloc(vp, nbytes)) == NULL) {
233 write(2, "no memory\n", 10);
234 exit(077);
235 }
236 return p;
237 }
238
239 void *
smalloc(size_t nbytes)240 smalloc(size_t nbytes)
241 {
242 return srealloc(NULL, nbytes);
243 }
244
245 /*
246 * Allocate pty master (APUE, p. 638).
247 */
248 int
ptym_open(char * pts_name,size_t namsz)249 ptym_open(char *pts_name, size_t namsz)
250 {
251 char *ptr;
252 int fdm;
253
254 strcpy(pts_name, "/dev/ptmx");
255 if ((fdm = open(pts_name, O_RDWR)) < 0)
256 return -1;
257 if (grantpt(fdm) < 0) {
258 close(fdm);
259 return -2;
260 }
261 if (unlockpt(fdm) < 0) {
262 close(fdm);
263 return -3;
264 }
265 if ((ptr = ptsname(fdm)) == NULL) {
266 close(fdm);
267 return -4;
268 }
269 strncpy(pts_name, ptr, namsz);
270 #ifndef __linux__
271 if (ioctl(fdm, I_PUSH, "pckt") < 0) {
272 close(fdm);
273 return -5;
274 }
275 #endif /* !__linux__ */
276 return fdm;
277 }
278
279 /*
280 * Allocate a pty slave (APUE, p. 639).
281 */
282 int
ptys_open(int fdm,char * pts_name)283 ptys_open(int fdm, char *pts_name)
284 {
285 int fds;
286
287 if ((fds = open(pts_name, O_RDWR)) < 0) {
288 close(fdm);
289 return -5;
290 }
291 #ifndef __linux__
292 if (ioctl(fds, I_PUSH, "ptem") < 0) {
293 close(fdm);
294 close(fds);
295 return -6;
296 }
297 if (ioctl(fds, I_PUSH, "ldterm") < 0) {
298 close(fdm);
299 close(fds);
300 return -7;
301 }
302 if (ioctl(fds, I_PUSH, "ttcompat") < 0) {
303 close(fdm);
304 close(fds);
305 return -8;
306 }
307 #endif /* !__linux__ */
308 return fds;
309 }
310
311 /*
312 * Add or delete an entry in the system's utmp file.
313 */
314 void
doutmp(int action,struct layer * l)315 doutmp(int action, struct layer *l)
316 {
317 /*
318 * Note that pututxline() may need privileges to work; but at least
319 * on Solaris, it does not as the libc arranges this for us. If shl
320 * has suid or sgid privileges, these are reset on startup and
321 * restored for utmp handling here.
322 */
323 struct passwd *pwd = getpwuid(myuid);
324 struct utmpx utx;
325 char *id;
326
327 memset(&utx, 0, sizeof utx);
328 strncpy(utx.ut_line, l->l_line + 5, sizeof utx.ut_line);
329 strncpy(utx.ut_user, pwd->pw_name, sizeof utx.ut_user);
330 utx.ut_pid = l->l_pid;
331 gettimeofday(&utx.ut_tv, NULL);
332 if ((id = strrchr(l->l_line, '/')) != NULL)
333 strncpy(utx.ut_id, id, sizeof utx.ut_id);
334 switch (action) {
335 case UTMP_ADD:
336 utx.ut_type = USER_PROCESS;
337 break;
338 case UTMP_DEL:
339 utx.ut_type = DEAD_PROCESS;
340 break;
341 }
342 if (myuid != myeuid)
343 setuid(myeuid);
344 if (mygid != myegid)
345 setgid(myegid);
346 #ifndef __linux__
347 if (action == UTMP_DEL) {
348 /*
349 * On (at least) Solaris 8, /usr/lib/utmp_update will hang at
350 * ioctl(tty, TCGETA, ...) respective isatty() when the pty is
351 * in packet mode, but removing the pckt module we once pushed
352 * fails with EPERM in some circumstances (exact conditions
353 * unknown). If it does, close the pty master; pututxline()
354 * refuses to work then, but utmpd(1M) will remove the stale
355 * entry a few seconds later. This is not the ultimate
356 * solution, but better than hanging, of course. If shl needs
357 * privilegues to call pututxline(), these calls will not cause
358 * any harm since there is no dependency on the actual terminal
359 * device then.
360 */
361 if (ioctl(l->l_pty, I_POP, 0) < 0) {
362 close(l->l_pty);
363 l->l_pty = -1;
364 }
365 }
366 #endif /* !__linux__ */
367 setutxent();
368 getutxline(&utx);
369 pututxline(&utx);
370 endutxent();
371 if (myuid != myeuid)
372 setuid(myuid);
373 if (mygid != myegid)
374 setgid(mygid);
375 }
376
377 /*
378 * Quit shl, killing all active layers.
379 */
380 void
quit(int status)381 quit(int status)
382 {
383 struct layer *l;
384
385 for (l = l0; l; l = l->l_next) {
386 kill(0 - l->l_pid, SIGHUP);
387 doutmp(UTMP_DEL, l);
388 }
389 tcsetattr(0, TCSADRAIN, &otio);
390 exit(status);
391 }
392
393 /*
394 * Check for valid layer name.
395 */
396 int
invlname(char * name)397 invlname(char *name)
398 {
399 int err = 0;
400
401 if (strpbrk(name, " \t"))
402 err++;
403 if (name[0] == '(' && isdigit(name[1] & 0377) && name[2] == ')'
404 && name[3] == '\0')
405 err++;
406 if (err)
407 msg(syntax);
408 return err;
409 }
410
411 /*
412 * Find a layer by its pid.
413 */
414 struct layer *
lbypid(pid_t pid)415 lbypid(pid_t pid)
416 {
417 struct layer *l;
418
419 for (l = l0; l; l = l->l_next)
420 if (l->l_pid == pid)
421 return l;
422 return NULL;
423 }
424
425 /*
426 * Find a layer by its pty.
427 */
428 struct layer *
lbypty(int pty)429 lbypty(int pty)
430 {
431 struct layer *l;
432
433 for (l = l0; l; l = l->l_next)
434 if (l->l_pty == pty)
435 return l;
436 return NULL;
437 }
438
439 /*
440 * Find a layer by its name.
441 */
442 struct layer *
lbyname(char * name)443 lbyname(char *name)
444 {
445 struct layer *l;
446 char bname[11];
447
448 for (l = l0; l; l = l->l_next)
449 if (strncmp(l->l_name, name, 8) == 0)
450 return l;
451 snprintf(bname, sizeof bname, "(%s)", name);
452 for (l = l0; l; l = l->l_next)
453 if (strncmp(l->l_name, bname, 8) == 0)
454 return l;
455 return NULL;
456 }
457
458 /*
459 * Guess a layer by a possibly incomplete name part.
460 */
461 struct layer *
lguess(char * name)462 lguess(char *name)
463 {
464 struct layer *l, *lm = NULL;
465 size_t nmlen = strlen(name);
466 char bname[11];
467
468 if (nmlen > 8)
469 nmlen = 8;
470 for (l = l0; l; l = l->l_next) {
471 if (strncmp(l->l_name, name, nmlen) == 0) {
472 if (lm) {
473 msg("layer %s not unique", name);
474 return NULL;
475 }
476 lm = l;
477 }
478 }
479 if (lm == NULL) {
480 snprintf(bname, sizeof bname, "(%s)", name);
481 nmlen += 2;
482 for (l = l0; l; l = l->l_next) {
483 if (strncmp(l->l_name, bname, nmlen) == 0) {
484 if (lm) {
485 msg("layer %s not unique", name);
486 return NULL;
487 }
488 lm = l;
489 }
490 }
491 }
492 if (lm == NULL)
493 msg(lnotfound, name);
494 return lm;
495 }
496
497 /*
498 * Allocate a layer structure.
499 */
500 struct layer *
lalloc(char * name,int accept)501 lalloc(char *name, int accept)
502 {
503 struct layer *l, *lp;
504
505 if (lcount >= MAXLAYER) {
506 msg("only %u layers allowed", MAXLAYER);
507 return NULL;
508 }
509 if (accept == 0 && invlname(name))
510 return NULL;
511 if (lbyname(name)) {
512 msg("layer %s already exists", name);
513 return NULL;
514 }
515 l = (struct layer *)smalloc(sizeof *l);
516 if (l0 == NULL) {
517 l0 = l;
518 l->l_prev = NULL;
519 } else {
520 for (lp = l0; lp->l_next != NULL; lp = lp->l_next);
521 lp->l_next = l;
522 l->l_prev = lp;
523 }
524 l->l_next = NULL;
525 strncpy(l->l_name, name, 8);
526 l->l_name[8] = '\0';
527 l->l_pty = -1;
528 l->l_blk = 0;
529 lcount++;
530 return l;
531 }
532
533 /*
534 * Deallocate a layer structure.
535 */
536 void
lfree(struct layer * l)537 lfree(struct layer *l)
538 {
539 if (l->l_prev)
540 l->l_prev->l_next = l->l_next;
541 if (l->l_next)
542 l->l_next->l_prev = l->l_prev;
543 if (l == l0)
544 l0 = l->l_next;
545 close(l->l_pty);
546 free(l);
547 lcount--;
548 }
549
550 /*
551 * Block a layer.
552 */
553 int
lblock(struct layer * l)554 lblock(struct layer *l)
555 {
556 l->l_blk = 1;
557 return 0;
558 }
559
560 /*
561 * Unblock a layer.
562 */
563 int
lunblock(struct layer * l)564 lunblock(struct layer *l)
565 {
566 l->l_blk = 0;
567 return 0;
568 }
569
570 /*
571 * Set a layer as current layer, that is, assign it to lcur and put it at
572 * the end of the layer list.
573 */
574 void
setcur(struct layer * l)575 setcur(struct layer *l)
576 {
577 struct layer *lp;
578
579 if (l->l_next) {
580 if (l->l_prev)
581 l->l_prev->l_next = l->l_next;
582 else
583 l0 = l->l_next;
584 l->l_next->l_prev = l->l_prev;
585 for (lp = l; lp->l_next; lp = lp->l_next);
586 l->l_prev = lp;
587 lp->l_next = l;
588 l->l_next = NULL;
589 }
590 lcur = l;
591 }
592
593 /*
594 * Set the previous layer to the current.
595 */
596 void
setprev(int nullok)597 setprev(int nullok)
598 {
599 struct layer *l = lcur;
600
601 if ((lcur = l->l_prev) == NULL) {
602 if (nullok)
603 l0 = NULL;
604 else
605 lcur = l0;
606 }
607 }
608
609 /*
610 * Pass input from terminal to pty, or read shl commands.
611 */
612 int
doinput(void)613 doinput(void)
614 {
615 int seen = 0;
616 char c;
617
618 #ifdef __linux__
619 if (cmdptr == NULL)
620 tcgetattr(lcur->l_pty, &lcur->l_tio);
621 #endif /* __linux__ */
622 while (read(0, &c, 1) == 1) {
623 if (cmdptr) {
624 /*
625 * Do control character processing for shl commands.
626 */
627 if ((c == '\n' && (otio.c_iflag & INLCR) == 0)
628 || (c == '\r' && (otio.c_iflag & ICRNL))) {
629 write(1, "\r\n", 2);
630 *cmdptr = '\0';
631 seen++;
632 break;
633 } else if (cmdptr == cmdbuf &&
634 (c&0377) == (dtio.c_cc[VEOF]&0377)) {
635 /*EMPTY*/;
636 } else if ((c&0377) == (dtio.c_cc[VERASE]&0377)) {
637 if (cmdptr > cmdbuf)
638 *cmdptr-- = '\0';
639 write(1, "\b \b", 3);
640 } else if ((c&0377) == (dtio.c_cc[VKILL]&0377)) {
641 *(cmdptr = cmdbuf) = '\0';
642 write(1, "\r\n", 2);
643 } else {
644 write(1, &c, 1);
645 *cmdptr++ = c & 0377;
646 }
647 if (cmdptr == cmdbuf + sizeof cmdbuf) {
648 msg("\r\nInput string too long, limit %u",
649 sizeof cmdbuf - 1);
650 *--cmdptr = '\0';
651 write(1, "\r", 1);
652 write(1, cmdbuf, strlen(cmdbuf));
653 }
654 } else {
655 /*
656 * Pass input to the currently active layer and
657 * look for SWTCH character. If a LNEXT character
658 * is found, keep it so it can escape a following
659 * SWTCH.
660 */
661 static char hadlnext;
662
663 #ifdef VLNEXT
664 if (c && (c&0377) == (lcur->l_tio.c_cc[VLNEXT]&0377) &&
665 hadlnext == 0) {
666 hadlnext = c;
667 } else
668 #endif /* VLNEXT */
669 {
670 if (c && (c&0377) ==
671 (lcur->l_tio.c_cc[VSWTCH]&0377)) {
672 if (hadlnext) {
673 hadlnext = 0;
674 } else {
675 seen++;
676 break;
677 }
678 }
679 if (hadlnext) {
680 write(lcur->l_pty, &hadlnext, 1);
681 hadlnext = 0;
682 }
683 write(lcur->l_pty, &c, 1);
684 }
685 }
686 }
687 return seen;
688 }
689
690 /*
691 * Write to a file descriptor with possible restart.
692 */
693 ssize_t
swrite(int fd,const char * data,size_t sz)694 swrite(int fd, const char *data, size_t sz)
695 {
696 ssize_t wo, wt = 0;
697
698 do {
699 if ((wo = write(fd, data + wt, sz - wt)) < 0) {
700 if (errno == EINTR)
701 continue;
702 else
703 return -1;
704 }
705 wt += wo;
706 } while (wt < sz);
707 return sz;
708 }
709
710 /*
711 * Pass output from pty to terminal. On Linux systems, this is a simple
712 * task as we can issue tcgetattr() on the pty master to get the slave's
713 * settings. On SVR4 however, we have to use getmsg() for this and must
714 * update our copy of the slave's settings whenever a M_IOCTL message
715 * is received.
716 */
717 int
dooutput(int pty,struct layer * l)718 dooutput(int pty, struct layer *l)
719 #ifdef __linux__
720 {
721 char buf[4096];
722 ssize_t sz;
723
724 if ((sz = read(pty, buf, sizeof buf)) > 0)
725 swrite(1, buf, sz);
726 return 0;
727 }
728 #else /* !__linux__ */
729 {
730 char cbuf[64], dbuf[1024];
731 struct strbuf cs, ds;
732 struct iocblk *ib;
733 struct termio *to;
734 int more, flag, maybehup = 0;
735
736 if (l == NULL)
737 l = lbypty(pty);
738 for (;;) {
739 cs.maxlen = sizeof cbuf;
740 cs.buf = cbuf;
741 ds.maxlen = sizeof dbuf;
742 ds.buf = dbuf;
743 flag = 0;
744 if ((more = getmsg(l->l_pty, &cs, &ds, &flag)) < 0)
745 break;
746 switch (cbuf[0] & 0377) {
747 case M_IOCTL:
748 /*LINTED*/
749 ib = (struct iocblk *)dbuf;
750 switch (ib->ioc_cmd) {
751 case TCSETS:
752 case TCSETSW:
753 case TCSETSF:
754 memcpy(&l->l_tio, dbuf + sizeof *ib,
755 sizeof l->l_tio);
756 break;
757 case TCSETA:
758 case TCSETAW:
759 case TCSETAF:
760 /*LINTED*/
761 to = (struct termio *)(dbuf + sizeof *ib);
762 l->l_tio.c_iflag = to->c_iflag;
763 l->l_tio.c_oflag = to->c_oflag;
764 l->l_tio.c_cflag = to->c_cflag;
765 l->l_tio.c_lflag = to->c_lflag;
766 memcpy(l->l_tio.c_cc, to->c_cc, NCC);
767 break;
768 }
769 break;
770 case M_DATA:
771 if (ds.len == 0)
772 maybehup++;
773 else
774 swrite(1, ds.buf, ds.len);
775 break;
776 }
777 if (more == 0)
778 break;
779 }
780 return maybehup;
781 }
782 #endif /* !__linux__ */
783
784 /*
785 * Wait for children.
786 */
787 struct layer *
await(void)788 await(void)
789 {
790 struct layer *l;
791 int status;
792 pid_t pid;
793
794 for (;;) {
795 if ((pid = waitpid(-1, &status, WNOHANG)) < 0)
796 return NULL;
797 if ((l = lbypid(pid)) == NULL) /* not our job */
798 continue;
799 errstat = status;
800 break;
801 }
802 return l;
803 }
804
805 /*
806 * Input/output loop. Poll for input or status change on stdin and all pty
807 * descriptors and invoke the appropriate handler.
808 */
809 void
doio(void)810 doio(void)
811 {
812 struct pollfd pfd[MAXLAYER + 1];
813 struct layer *l;
814 int nfds, nevents, i;
815 int endloop = 0;
816
817 tcsetattr(0, TCSADRAIN, &rtio);
818 pfd[0].fd = 0;
819 pfd[0].events = POLLIN;
820 pfd[0].revents = 0;
821 for (nfds = 0, l = l0; nfds <= MAXLAYER && l; l = l->l_next) {
822 nfds++;
823 pfd[nfds].fd = l->l_pty;
824 pfd[nfds].events = POLLIN;
825 pfd[nfds].revents = 0;
826 }
827 while (endloop == 0) {
828 nevents = poll(pfd, nfds + 1, -1);
829 if (nevents == -1 && errno == EINTR)
830 continue;
831 for (i = 0; i <= nfds && nevents; i++) {
832 if (pfd[i].revents == 0)
833 continue;
834 nevents--;
835 if (pfd[i].revents & POLLIN) {
836 if (i == 0)
837 endloop += doinput();
838 else {
839 /*
840 * Check whether output is blocked.
841 * i != nfds does the same as
842 * l != lcur but is faster here.
843 */
844 if (i != nfds || cmdptr != NULL) {
845 l = lbypty(pfd[i].fd);
846 if (l->l_blk) {
847 pfd[i].events = 0;
848 continue;
849 }
850 } else
851 l = NULL;
852 if (dooutput(pfd[i].fd, l))
853 goto maybehup;
854 }
855 /*
856 * Do not check for other conditions as
857 * dooutput() possibly did not fetch all
858 * waiting data.
859 */
860 continue;
861 }
862 if (pfd[i].revents & (POLLERR | POLLHUP)) {
863 if (i == 0) {
864 /*
865 * This is an error on input. What
866 * can we do to recover from here?
867 */
868 msg("input error; retrying");
869 sleep(1);
870 continue;
871 }
872 maybehup:
873 l = await();
874 if (l == lcur)
875 endloop++;
876 if (l != NULL) {
877 if (l == lcur)
878 setprev(1);
879 doutmp(UTMP_DEL, l);
880 lfree(l);
881 }
882
883 }
884 }
885 }
886 tcsetattr(0, TCSADRAIN, &dtio);
887 }
888
889 /*
890 * Delete a layer, kill its residents.
891 */
892 int
ldelete(struct layer * l)893 ldelete(struct layer *l)
894 {
895 kill(0 - l->l_pid, SIGHUP);
896 /*
897 * Do not remove the utmp entry now; this will be done once the
898 * process has been waited for.
899 */
900 if (l == lcur)
901 setprev(0);
902 return 0;
903 }
904
905 /*
906 * Determine blocking status of a layer.
907 */
908 char *
blockstat(struct layer * l)909 blockstat(struct layer *l)
910 {
911 /*
912 * There is an additional message "blocked on input", but its
913 * conditions are unclear.
914 */
915 if (l->l_blk) {
916 struct pollfd pfd[1];
917
918 pfd[0].fd = l->l_pty;
919 pfd[0].events = POLLIN;
920 pfd[0].revents = 0;
921 if (poll(pfd, 1, 0) > 0 && (pfd[0].revents & POLLIN))
922 return "blocked on output";
923 }
924 return "executing or awaiting input";
925 }
926
927 /*
928 * List a layer, simple format.
929 */
930 int
llist(struct layer * l)931 llist(struct layer *l)
932 {
933 msg("%s (%ld) %s", l->l_name, (long)l->l_pid, blockstat(l));
934 return 0;
935 }
936
937 /*
938 * List a layer, extended ("ps"-like) format.
939 */
940 int
lpslist(struct layer * l)941 lpslist(struct layer *l)
942 {
943 pid_t pid;
944 int status;
945
946 llist(l);
947 switch (pid = fork()) {
948 case -1:
949 return 1;
950 default:
951 while (waitpid(pid, &status, 0) != pid);
952 msg("");
953 break;
954 case 0:
955 putenv("PATH=" SV3BIN ":" DEFBIN ":/bin:/usr/bin");
956 if (sysv3 && getenv("SYSV3") == NULL)
957 putenv("SYSV3=set");
958 dup2(2, 1);
959 execlp("ps", "ps", "-f", "-t", &l->l_line[5], NULL);
960 msg("no ps command found");
961 _exit(0177);
962 }
963 return status;
964 }
965
966 /*
967 * Resume a layer.
968 */
969 int
lresume(struct layer * l)970 lresume(struct layer *l)
971 {
972 msg("resuming %s", l->l_name);
973 setcur(l);
974 doio();
975 return 0;
976 }
977
978 /*
979 * Execute a command on a layer list.
980 */
981 int
foreach(char * list,int (* func)(struct layer *))982 foreach(char *list, int (*func)(struct layer *))
983 {
984 struct layer *l;
985 char *cp = list;
986 int ecnt = 0;
987
988 do {
989 if ((cp = strpbrk(cp, " \t")) != NULL)
990 while (blankchar(*cp))
991 *cp++ = '\0';
992 if ((l = lbyname(list)) == NULL) {
993 msg(lnotfound, list);
994 ecnt++;
995 } else {
996 ecnt += func(l);
997 }
998 } while ((list = cp) != NULL);
999 return ecnt;
1000 }
1001
1002 /*
1003 * Child command for new layer.
1004 */
1005 void
child(char * arg0,char * arg,char ** args)1006 child(char *arg0, char *arg, char **args)
1007 {
1008 int estat;
1009
1010 sigset(SIGHUP, oldhup);
1011 sigset(SIGINT, oldint);
1012 sigset(SIGQUIT, oldquit);
1013 sigset(SIGTTOU, oldttou);
1014 sigset(SIGTSTP, oldtstp);
1015 sigset(SIGTTIN, oldttin);
1016 sigset(SIGWINCH, oldwinch);
1017 if (args)
1018 execvp(args[0], args);
1019 else
1020 execlp(arg0, arg, NULL);
1021 switch (errno) {
1022 case ELOOP:
1023 case ENAMETOOLONG:
1024 case ENOENT:
1025 estat = 0176;
1026 break;
1027 default:
1028 estat = 0177;
1029 }
1030 msg("cannot exec %s", args ? args[0] : arg0);
1031 _exit(estat);
1032 }
1033
1034 /*
1035 * Execute a new layer. If args is not NULL, use it for execution, else,
1036 * use arg0 and arg.
1037 */
1038 pid_t
lspawn(struct layer * l,char * arg0,char * arg,char ** args)1039 lspawn(struct layer *l, char *arg0, char *arg, char **args)
1040 {
1041 char *ps1;
1042 size_t sz;
1043 pid_t pid;
1044 int fds;
1045
1046 if ((l->l_pty = ptym_open(l->l_line, sizeof l->l_line)) < 0) {
1047 msg("control channel unavailable");
1048 return -1;
1049 }
1050 fcntl(l->l_pty, F_SETFD, FD_CLOEXEC);
1051 switch (pid = fork()) {
1052 case -1:
1053 msg("cannot fork");
1054 break;
1055 case 0:
1056 setsid();
1057 if ((fds = ptys_open(l->l_pty, l->l_line)) < 0) {
1058 msg("virtual tty %s open failed", l->l_line);
1059 _exit(0177);
1060 }
1061 close(l->l_pty);
1062 if (tcsetattr(fds, TCSADRAIN, &dtio) < 0) {
1063 msg("virtual tty %s stty failed", l->l_line);
1064 _exit(0177);
1065 }
1066 if (winsz.ws_row)
1067 ioctl(fds, TIOCSWINSZ, &winsz);
1068 dup2(fds, 0);
1069 dup2(fds, 1);
1070 dup2(fds, 2);
1071 close(fds);
1072 ps1 = smalloc(sz = strlen(l->l_name) + 7);
1073 snprintf(ps1, sz, "PS1=%s%s ", l->l_name, myuid ? "" : "#");
1074 putenv(ps1);
1075 child(arg0, arg, args);
1076 /*NOTREACHED*/
1077 default:
1078 memcpy(&l->l_tio, &dtio, sizeof l->l_tio);
1079 }
1080 return pid;
1081 }
1082
1083 /*
1084 * Create a default layer name formed (digit).
1085 */
1086 char *
defnumlnam(void)1087 defnumlnam(void)
1088 {
1089 static char str[6];
1090 unsigned int count;
1091
1092 for (count = 1; count <= MAXLAYER; count++) {
1093 snprintf(str, sizeof str, "(%u)", count);
1094 if (lbyname(str) == NULL)
1095 break;
1096 }
1097 return str;
1098 }
1099
1100 /*
1101 * Create a new layer.
1102 */
1103 int
c_create(char * arg)1104 c_create(char *arg)
1105 {
1106 #ifdef WORDEXP
1107 wordexp_t we;
1108 int usewe = 0;
1109 #endif /* WORDEXP */
1110 char cmd0[_POSIX_PATH_MAX];
1111 char *cmd;
1112 const char *cp;
1113 struct layer *l;
1114 int accept = 0;
1115
1116 if (arg == NULL) {
1117 arg = defnumlnam();
1118 accept++;
1119 }
1120 if (*arg == '-') {
1121 arg++;
1122 cmd = dashell;
1123 strncpy(cmd0, shell, sizeof cmd0);
1124 } else if ((cmd = strpbrk(arg, " \t")) == NULL) {
1125 cmd = dashell + 1;
1126 strncpy(cmd0, shell, sizeof cmd0);
1127 } else {
1128 while (blankchar(*cmd))
1129 *cmd++ = '\0';
1130 #ifdef WORDEXP
1131 usewe++;
1132 switch (wordexp(cmd, &we, 0)) {
1133 case 0: /* success */
1134 cp = NULL;
1135 break;
1136 case WRDE_NOSPACE:
1137 cp = "no memory";
1138 break;
1139 case WRDE_BADCHAR:
1140 case WRDE_SYNTAX:
1141 default:
1142 cp = syntax;
1143 }
1144 if (cp != NULL) {
1145 msg(cp);
1146 return 1;
1147 }
1148 #else /* !WORDEXP */
1149 cp = cmd + strlen(cmd) - 1;
1150 while (blankchar(*cmd))
1151 *cmd-- = '\0';
1152 strncpy(cmd0, cmd, sizeof cmd0);
1153 #endif /* !WORDEXP */
1154 }
1155 cmd0[sizeof cmd0 - 1] = '\0';
1156 if ((l = lalloc(arg, accept)) == NULL)
1157 return 1;
1158 setcur(l);
1159 if ((l->l_pid = lspawn(l, cmd0, cmd,
1160 #ifdef WORDEXP
1161 usewe ? we.we_wordv :
1162 #endif /* WORDEXP */
1163 NULL))
1164 == -1) {
1165 setprev(1);
1166 lfree(l);
1167 #ifdef WORDEXP
1168 if (usewe)
1169 wordfree(&we);
1170 #endif /* WORDEXP */
1171 return 1;
1172 }
1173 doutmp(UTMP_ADD, l);
1174 #ifdef WORDEXP
1175 if (usewe)
1176 wordfree(&we);
1177 #endif /* WORDEXP */
1178 doio();
1179 return 0;
1180 }
1181
1182 /*
1183 * Rename a layer.
1184 */
1185 int
c_name(char * arg)1186 c_name(char *arg)
1187 {
1188 struct layer *l;
1189 char *newname;
1190
1191 if (arg == NULL) {
1192 msg(syntax);
1193 return 1;
1194 }
1195 if ((newname = strpbrk(arg, " \t")) != NULL) {
1196 while (blankchar(*newname))
1197 *newname++ = '\0';
1198 if ((l = lbyname(arg)) == NULL) {
1199 msg(lnotfound, arg);
1200 return 1;
1201 }
1202 } else {
1203 newname = arg;
1204 if ((l = lcur) == NULL) {
1205 msg(nocurl);
1206 return 1;
1207 }
1208 }
1209 if (invlname(newname))
1210 return 1;
1211 strcpy(l->l_name, newname);
1212 return 0;
1213 }
1214
1215 /*
1216 * Invoke a subshell on the same tty as shl.
1217 */
1218 int
c_bang(char * arg)1219 c_bang(char *arg)
1220 {
1221 if (arg == NULL)
1222 arg = shell;
1223 errstat = system(arg);
1224 return 0;
1225 }
1226
1227 /*
1228 * Block layer output.
1229 */
1230 int
c_block(char * arg)1231 c_block(char *arg)
1232 {
1233 if (arg == NULL) {
1234 msg(syntax);
1235 return 1;
1236 }
1237 return foreach(arg, lblock);
1238 }
1239
1240 /*
1241 * Delete a layer.
1242 */
1243 int
c_delete(char * arg)1244 c_delete(char *arg)
1245 {
1246 if (arg == NULL) {
1247 msg(syntax);
1248 return 1;
1249 }
1250 return foreach(arg, ldelete);
1251 }
1252
1253 /*
1254 * Print summary for all commands.
1255 */
1256 /*ARGSUSED*/
1257 int
c_help(char * arg)1258 c_help(char *arg)
1259 {
1260 int i;
1261
1262 /*msg("\nshl %s %s by Gunnar Ritter\n", shl_version, shl_date);*/
1263 for (i = 0; commands[i].c_string; i++)
1264 if (commands[i].c_desc)
1265 msg("%s", commands[i].c_desc);
1266 /*msg("");*/
1267 return 0;
1268 }
1269
1270 /*
1271 * List current layers.
1272 */
1273 int
c_layers(char * arg)1274 c_layers(char *arg)
1275 {
1276 int (*lfunc)(struct layer *);
1277 struct layer *l;
1278
1279 if (arg && arg[0] == '-' && arg[1] == 'l'
1280 && (arg[2] == '\0' || blankchar(arg[2]))) {
1281 lfunc = lpslist;
1282 arg += 2;
1283 while (blankchar(*arg))
1284 arg++;
1285 if (*arg == '\0')
1286 arg = NULL;
1287 } else
1288 lfunc = llist;
1289 if (arg)
1290 return foreach(arg, lfunc);
1291 for (l = l0; l; l = l->l_next)
1292 lfunc(l);
1293 return 0;
1294 }
1295
1296 /*
1297 * Resume a background layer.
1298 */
1299 int
c_resume(char * arg)1300 c_resume(char *arg)
1301 {
1302 struct layer *l;
1303
1304 if (arg != NULL) {
1305 if ((l = lbyname(arg)) == NULL) {
1306 msg(lnotfound, arg);
1307 return 1;
1308 }
1309 } else {
1310 if ((l = lcur) == NULL) {
1311 msg(nocurl);
1312 return 1;
1313 }
1314 }
1315 return lresume(l);
1316 }
1317
1318 /*
1319 * Resume the previously backgrounded layer.
1320 */
1321 /*ARGSUSED*/
1322 int
c_toggle(char * arg)1323 c_toggle(char *arg)
1324 {
1325 if (lcur != NULL) {
1326 if (lcur->l_prev != NULL)
1327 setcur(lcur->l_prev);
1328 } else {
1329 msg(nocurl);
1330 return 1;
1331 }
1332 return lresume(lcur);
1333 }
1334
1335 /*
1336 * Unblock a layer.
1337 */
1338 int
c_unblock(char * arg)1339 c_unblock(char *arg)
1340 {
1341 if (arg == NULL) {
1342 msg(syntax);
1343 return 1;
1344 }
1345 return foreach(arg, lunblock);
1346 }
1347
1348 /*
1349 * Quit shl.
1350 */
1351 int
c_quit(char * arg)1352 c_quit(char *arg)
1353 {
1354 if (arg) {
1355 msg(syntax);
1356 return 1;
1357 }
1358 if (l0 != NULL && hadquit == 0) {
1359 msg("warning: there may still be shl layers running");
1360 hadquit++;
1361 return 0;
1362 }
1363 quit(errstat);
1364 /*NOTREACHED*/
1365 return 0;
1366 }
1367
1368 /*
1369 * Do nothing.
1370 */
1371 /*ARGSUSED*/
1372 int
c_null(char * arg)1373 c_null(char *arg)
1374 {
1375 return 0;
1376 }
1377
1378 /*
1379 * Read a line from standard input, without terminating newline.
1380 */
1381 char *
getaline(void)1382 getaline(void)
1383 {
1384 cmdbuf[0] = '\n';
1385 cmdptr = cmdbuf;
1386 while (cmdbuf[0] == '\n')
1387 doio();
1388 if (cmdptr == NULL)
1389 return NULL;
1390 cmdptr = NULL;
1391 return cmdbuf;
1392 }
1393
1394 /*
1395 * Prompt for command and do initial splitting.
1396 */
1397 struct command *
prompt(void)1398 prompt(void)
1399 {
1400 static struct command pc;
1401 char *cmdstr = NULL, *argument;
1402 size_t cmdlen;
1403 int i;
1404
1405 write(1, ">>> ", 4);
1406 if ((cmdstr = getaline()) == NULL) {
1407 pc.c_func = c_quit;
1408 pc.c_arg = NULL;
1409 return &pc;
1410 }
1411 while (blankchar(*cmdstr))
1412 cmdstr++;
1413 argument = cmdstr + strlen(cmdstr) - 1;
1414 while (blankchar(*argument))
1415 *argument-- = '\0';
1416 if (*cmdstr == '!' && cmdstr[1] != '\0') {
1417 cmdlen = 1;
1418 pc.c_arg = argument = &cmdstr[1];
1419 } else {
1420 if ((argument = strpbrk(cmdstr, " \t")) != NULL)
1421 while (blankchar(*argument))
1422 *argument++ = '\0';
1423 pc.c_arg = argument;
1424 cmdlen = strlen(cmdstr);
1425 }
1426 pc.c_func = c_null;
1427 if (cmdlen == 0)
1428 return &pc;
1429 for (i = 0; commands[i].c_string; i++) {
1430 if (strncmp(commands[i].c_string, cmdstr, cmdlen) == 0) {
1431 if (pc.c_func != c_null) {
1432 msg(syntax);
1433 pc.c_func = c_null;
1434 return &pc;
1435 }
1436 pc.c_func = commands[i].c_func;
1437 }
1438 }
1439 if (pc.c_func == c_null && *cmdstr) {
1440 struct layer *l;
1441
1442 if ((l = lguess(cmdstr)) != NULL)
1443 lresume(l);
1444 }
1445 if (pc.c_func != c_quit)
1446 hadquit = 0;
1447 return &pc;
1448 }
1449
1450 /*
1451 * SIGHUP handler.
1452 */
1453 void
onhup(int signum)1454 onhup(int signum)
1455 {
1456 quit(signum | 0200);
1457 }
1458
1459 /*
1460 * SIGWINCH handler.
1461 */
1462 /*ARGSUSED*/
1463 void
onwinch(int signum)1464 onwinch(int signum)
1465 {
1466 struct layer *l;
1467
1468 if (ioctl(0, TIOCGWINSZ, &winsz) != -1)
1469 for (l = l0; l; l = l->l_next)
1470 ioctl(l->l_pty, TIOCSWINSZ, &winsz);
1471 }
1472
1473 /*ARGSUSED*/
1474 int
main(int argc,char ** argv)1475 main(int argc, char **argv)
1476 {
1477 struct command *p;
1478 char *cp;
1479 char vdis;
1480
1481 progname = basename(argv[0]);
1482 mypid = getpid();
1483 myuid = getuid();
1484 myeuid = geteuid();
1485 mygid = getgid();
1486 myegid = getegid();
1487 if (myuid != myeuid)
1488 setuid(myuid);
1489 if (mygid != myegid)
1490 setgid(mygid);
1491 if (getenv("SYSV3") != 0)
1492 sysv3 = 1;
1493 if ((cp = getenv("SHELL")) == NULL)
1494 cp = DEFSHELL;
1495 shell = smalloc(strlen(cp) + 1);
1496 strcpy(shell, cp);
1497 cp = basename(cp);
1498 dashell = smalloc(strlen(cp) + 2);
1499 *dashell = '-';
1500 strcpy(dashell + 1, cp);
1501 if ((oldhup = sigset(SIGHUP, SIG_IGN)) != SIG_IGN)
1502 sigset(SIGHUP, onhup);
1503 oldint = sigset(SIGINT, SIG_IGN);
1504 oldquit = sigset(SIGQUIT, SIG_IGN);
1505 oldttou = sigset(SIGTTOU, SIG_IGN);
1506 oldtstp = sigset(SIGTSTP, SIG_IGN);
1507 oldttin = sigset(SIGTTIN, SIG_IGN);
1508 oldwinch = sigset(SIGWINCH, onwinch);
1509 if (tcgetattr(0, &otio) < 0) {
1510 msg("not using a tty device");
1511 quit(1);
1512 }
1513 memcpy(&dtio, &otio, sizeof dtio);
1514 vdis = fpathconf(0, _PC_VDISABLE);
1515 if (dtio.c_cc[VSWTCH] == vdis) {
1516 if (dtio.c_cc[VSUSP] == DEFSWTCH) {
1517 msg("warning: default swtch same as susp, disabling susp");
1518 dtio.c_cc[VSUSP] = vdis;
1519 }
1520 dtio.c_cc[VSWTCH] = DEFSWTCH;
1521 }
1522 memcpy(&rtio, &dtio, sizeof rtio);
1523 rtio.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN);
1524 rtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
1525 rtio.c_cflag &= ~(CSIZE | PARENB);
1526 rtio.c_cflag |= CS8;
1527 rtio.c_oflag &= ~(OPOST);
1528 rtio.c_cc[VMIN] = 0;
1529 rtio.c_cc[VTIME] = 0;
1530 if (ioctl(0, TIOCGWINSZ, &winsz) == -1)
1531 winsz.ws_row = 0;
1532 while ((p = prompt()) != NULL)
1533 p->c_func(p->c_arg);
1534 quit(errstat);
1535 /*NOTREACHED*/
1536 return 0;
1537 }
1538
1539 /*
1540 * Table of shl commands.
1541 */
1542 struct command commands[] = {
1543 { "block", c_block, NULL,
1544 "block name [name ...]", 23 },
1545 { "create", c_create, NULL,
1546 "create [-[name] | name [command]]", 20 },
1547 { "delete", c_delete, NULL,
1548 "delete name [name ...]", 24 },
1549 { "help", c_help, NULL,
1550 "help or ?", 25 },
1551 { "?", c_help, NULL,
1552 NULL, 25 },
1553 { "layers", c_layers, NULL,
1554 "layers [-l] [name ...]", 26 },
1555 { "name", c_name, NULL,
1556 "name [oldname] newname", 21 },
1557 { "quit", c_quit, NULL,
1558 "quit", 30 },
1559 { "toggle", c_toggle, NULL,
1560 "toggle", 28 },
1561 { "resume", c_resume, NULL,
1562 "resume [name]", 27 },
1563 { "unblock", c_unblock, NULL,
1564 "unblock name [name ...]", 29 },
1565 { "!", c_bang, NULL,
1566 "! [command]", 22 },
1567 { NULL, NULL, NULL,
1568 NULL, 0 }
1569 };
1570
1571 #else /* __FreeBSD__, __hpux, _AIX, __NetBSD__, __OpenBSD__, __DragonFly__,
1572 __APPLE__ */
1573
1574 #include <stdio.h>
1575
1576 int
main(void)1577 main(void)
1578 {
1579 fprintf(stderr, "command not supported\n");
1580 return 1;
1581 }
1582
1583 #endif /* __FreeBSD__, __hpux, _AIX, __NetBSD__, __OpenBSD__, __DragonFly__,
1584 __APPLE__ */
1585