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