1 /*
2  *	Copyright (c) 1984-1987 by the Regents of the
3  *	University of California and by Gregory Glenn Minshall.
4  *
5  *	Permission to use, copy, modify, and distribute these
6  *	programs and their documentation for any purpose and
7  *	without fee is hereby granted, provided that this
8  *	copyright and permission appear on all copies and
9  *	supporting documentation, the name of the Regents of
10  *	the University of California not be used in advertising
11  *	or publicity pertaining to distribution of the programs
12  *	without specific prior permission, and notice be given in
13  *	supporting documentation that copying and distribution is
14  *	by permission of the Regents of the University of California
15  *	and by Gregory Glenn Minshall.  Neither the Regents of the
16  *	University of California nor Gregory Glenn Minshall make
17  *	representations about the suitability of this software
18  *	for any purpose.  It is provided "as is" without
19  *	express or implied warranty.
20  */
21 
22 #ifndef lint
23 static char sccsid[] = "@(#)system.c	1.6 (Berkeley) 07/17/87";
24 #endif	/* not lint */
25 
26 #include <stdio.h>
27 
28 #include "../general/general.h"
29 #include "../ctlr/api.h"
30 #include "spint.h"
31 
32 #include "../general/globals.h"
33 
34 
35 static Spint spinted;
36 static char command[256];
37 static int need_to_start = 0;
38 
39 /*
40  * shell_continue() actually runs the command, and looks for API
41  * requests coming back in.
42  *
43  * We are called from the main loop in telnet.c.
44  */
45 
46 int
47 shell_continue()
48 {
49     /*
50      * spint_start() returns when either the command has finished, or when
51      * the required interrupt comes in.  In the latter case, the appropriate
52      * thing to do is to process the interrupt, and then return to
53      * the interrupt issuer by calling spint_continue().
54      */
55     if (need_to_start) {
56 	need_to_start = 0;
57 	spint_start(command, &spinted);
58     }
59 
60     if (spinted.done == 0) {
61 	/* Process request */
62 	handle_api(&spinted.regs, &spinted.sregs);
63 	spint_continue(&spinted);
64     } else {
65 	char inputbuffer[100];
66 
67 	if (spinted.rc != 0) {
68 	    fprintf(stderr, "Process generated a return code of 0x%x.\n",
69 								spinted.rc);
70 	}
71 	printf("[Hit return to continue]");
72 	fflush(stdout);
73 	(void) gets(inputbuffer);
74 	shell_active = 0;
75 	setconnmode();
76 	ConnectScreen();
77     }
78     return shell_active;
79 }
80 
81 
82 /*
83  * Called from telnet.c to fork a lower command.com.  We
84  * use the spint... routines so that we can pick up
85  * interrupts generated by application programs.
86  */
87 
88 
89 int
90 shell(argc,argv)
91 int	argc;
92 char	*argv[];
93 {
94 
95     ClearElement(spinted);
96     spinted.int_no = API_INTERRUPT_NUMBER;
97     if (argc == 1) {
98 	command[0] = 0;
99     } else {
100 	char *cmdptr;
101 	int length;
102 
103 	argc--;
104 	argv++;
105 	strcpy(command, " /c");
106 	cmdptr = command+strlen(command);
107 	while (argc) {
108 	    if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) {
109 		fprintf(stderr, "Argument list too long at argument *%s*.\n",
110 			    *argv);
111 		return 0;
112 	    }
113 	    *cmdptr++ = ' ';		/* Blank separators */
114 	    strcpy(cmdptr, *argv);
115 	    cmdptr += strlen(cmdptr);
116 	    argc--;
117 	    argv++;
118 	}
119 	length = strlen(command)-1;
120 	if (length < 0) {
121 	    length = 0;
122 	}
123 	command[0] = length;
124     }
125     need_to_start = 1;
126     shell_active = 1;
127     return 1;			/* Go back to main loop */
128 }
129