1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)system.c	4.1 (Berkeley) 12/04/88";
20 #endif /* not lint */
21 
22 #include <stdio.h>
23 
24 #include "../general/general.h"
25 #include "../ctlr/api.h"
26 #include "spint.h"
27 
28 #include "../general/globals.h"
29 
30 
31 static Spint spinted;
32 static char command[256];
33 static int need_to_start = 0;
34 
35 /*
36  * shell_continue() actually runs the command, and looks for API
37  * requests coming back in.
38  *
39  * We are called from the main loop in telnet.c.
40  */
41 
42 int
43 shell_continue()
44 {
45     /*
46      * spint_start() returns when either the command has finished, or when
47      * the required interrupt comes in.  In the latter case, the appropriate
48      * thing to do is to process the interrupt, and then return to
49      * the interrupt issuer by calling spint_continue().
50      */
51     if (need_to_start) {
52 	need_to_start = 0;
53 	spint_start(command, &spinted);
54     }
55 
56     if (spinted.done == 0) {
57 	/* Process request */
58 	handle_api(&spinted.regs, &spinted.sregs);
59 	spint_continue(&spinted);
60     } else {
61 	char inputbuffer[100];
62 
63 	if (spinted.rc != 0) {
64 	    fprintf(stderr, "Process generated a return code of 0x%x.\n",
65 								spinted.rc);
66 	}
67 	printf("[Hit return to continue]");
68 	fflush(stdout);
69 	(void) gets(inputbuffer);
70 	shell_active = 0;
71 	setconnmode();
72 	ConnectScreen();
73     }
74     return shell_active;
75 }
76 
77 
78 /*
79  * Called from telnet.c to fork a lower command.com.  We
80  * use the spint... routines so that we can pick up
81  * interrupts generated by application programs.
82  */
83 
84 
85 int
86 shell(argc,argv)
87 int	argc;
88 char	*argv[];
89 {
90 
91     ClearElement(spinted);
92     spinted.int_no = API_INTERRUPT_NUMBER;
93     if (argc == 1) {
94 	command[0] = 0;
95     } else {
96 	char *cmdptr;
97 	int length;
98 
99 	argc--;
100 	argv++;
101 	strcpy(command, " /c");
102 	cmdptr = command+strlen(command);
103 	while (argc) {
104 	    if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) {
105 		fprintf(stderr, "Argument list too long at argument *%s*.\n",
106 			    *argv);
107 		return 0;
108 	    }
109 	    *cmdptr++ = ' ';		/* Blank separators */
110 	    strcpy(cmdptr, *argv);
111 	    cmdptr += strlen(cmdptr);
112 	    argc--;
113 	    argv++;
114 	}
115 	length = strlen(command)-1;
116 	if (length < 0) {
117 	    length = 0;
118 	}
119 	command[0] = length;
120     }
121     need_to_start = 1;
122     shell_active = 1;
123     return 1;			/* Go back to main loop */
124 }
125