1 /* 2 * This file implements the API used in the PC version. 3 */ 4 5 #include <stdio.h> 6 #include <dos.h> 7 #include <stdlib.h> 8 9 #include "spint.h" 10 #include "api.h" 11 #include "../general.h" 12 13 14 /* 15 * Supervisor Services. 16 */ 17 18 static void 19 name_resolve(regs, sregs) 20 union REGS *regs; 21 struct SREGS *sregs; 22 { 23 char buffer[9]; 24 25 movetous(buffer, sregs->es, regs->x.di, sizeof buffer-1); 26 27 regs->h.cl = 0; 28 if (strcmp(buffer, NAME_SESSMGR) == 0) { 29 regs->x.dx = GATE_SESSMGR; 30 } else if (strcmp(buffer, NAME_KEYBOARD) == 0) { 31 regs->x.dx = GATE_KEYBOARD; 32 } else if (strcmp(buffer, NAME_COPY) == 0) { 33 regs->x.dx = GATE_COPY; 34 } else if (strcmp(buffer, NAME_OIAM) == 0) { 35 regs->x.dx = GATE_OIAM; 36 } else { 37 regs->h.cl = 0x2e; /* Name not found */ 38 } 39 regs->h.ch = 0x12; 40 regs->h.bh = 7; 41 } 42 43 /* 44 * Session Information Services. 45 */ 46 47 static void 48 query_session_id(regs, sregs) 49 union REGS *regs; 50 struct SREGS *sregs; 51 { 52 char buffer[16]; 53 54 movetous(buffer, sregs->es, regs->h.di, sizeof buffer); 55 56 if (buffer[0] != 0) { 57 regs->cl = 0x0c; 58 } else { 59 if (buffer[2] != 0x01) { 60 regs->h.cl = 0x0d; /* Invalid option code */ 61 } else if (buffer[3] != 0x45) { 62 regs->h.cl = 0x0b; 63 } else { 64 buffer[0] = 0; 65 buffer[1] = 0x6d; 66 regs->h.cl = 0; 67 } 68 } 69 movetothem(sregs->es, regs->h.di, sizeof buffer); 70 } 71 72 static void 73 query_session_parameters(regs, sregs) 74 union REGS *regs; 75 struct SREGS *sregs; 76 { 77 } 78 79 static void 80 query_session_cursor(regs, sregs) 81 union REGS *regs; 82 struct SREGS *sregs; 83 { 84 } 85 86 /* 87 * Keyboard Services. 88 */ 89 90 91 static void 92 connect_to_keyboard(regs, sregs) 93 union REGS *regs; 94 struct SREGS *sregs; 95 { 96 } 97 98 static void 99 disable_input(regs, sregs) 100 union REGS *regs; 101 struct SREGS *sregs; 102 { 103 } 104 105 static void 106 write_keystroke(regs, sregs) 107 union REGS *regs; 108 struct SREGS *sregs; 109 { 110 } 111 112 static void 113 enable_input(regs, sregs) 114 union REGS *regs; 115 struct SREGS *sregs; 116 { 117 } 118 119 /* 120 * Copy Services. 121 */ 122 123 static void 124 disconnect_from_keyboard(regs, sregs) 125 union REGS *regs; 126 struct SREGS *sregs; 127 { 128 } 129 130 /* 131 * Operator Information Area Services. 132 */ 133 134 static void 135 read_oia_group(regs, sregs) 136 union REGS *regs; 137 struct SREGS *sregs; 138 { 139 } 140 141 static void 142 unknown_op(regs, sregs) 143 union REGS *regs; 144 struct SREGS *sregs; 145 { 146 regs->h.ch = 0x12; 147 regs->h.cl = 0x05; 148 } 149 150 151 handle_api(regs, sregs) 152 union REGS *regs; 153 struct SREGS *sregs; 154 { 155 if (regs->h.ah == NAME_RESOLUTION) { 156 name_resolution(regs, sregs); 157 } else { 158 switch (regs->x.dx) { 159 case GATE_SESSMGR: 160 switch (regs->h.al) { 161 case QUERY_SESSION_ID: 162 query_session_id(regs, sregs); 163 break; 164 case QUERY_SESSION_PARMS: 165 query_session_parms(regs, sregs); 166 break; 167 case QUERY_SESSION_CURSOR: 168 query_session_cursor(regs, sregs); 169 break; 170 default: 171 unknown_op(regs, sregs); 172 break; 173 } 174 break; 175 case GATE_KEYBOARD: 176 switch (regs->h.al) { 177 case CONNECT_TO_KEYBOARD: 178 connect_to_keyboard(regs, sregs); 179 break; 180 case DISABLE_INPUT: 181 disable_input(regs, sregs); 182 break; 183 case WRITE_KEYSTROKE: 184 write_keystroke(regs, sregs); 185 break; 186 case ENABLE_INPUT: 187 enable_input(regs, sregs); 188 break; 189 case DISCONNECT_FROM_KEYBOARD: 190 disconnect_from_keyboard(regs, sregs); 191 break; 192 default: 193 unknown_op(regs, sregs); 194 break; 195 } 196 break; 197 case GATE_COPY: 198 switch (regs->h.al) { 199 case COPY_STRING: 200 copy_string(regs, sregs); 201 break; 202 default: 203 unknown_op(regs, sregs); 204 break; 205 } 206 break; 207 case GATE_OIAM: 208 switch (regs->h.al) { 209 case READ_OIA_GROUP: 210 read_oia_group(regs, sregs); 211 break; 212 default: 213 unknown_op(regs, sregs); 214 break; 215 } 216 break; 217 default: 218 unknown_op(regs, sregs); 219 break; 220 } 221 } 222 } 223 224 225 /* 226 * Called from telnet.c to fork a lower command.com. We 227 * use the spint... routines so that we can pick up 228 * interrupts generated by application programs. 229 */ 230 231 232 int 233 shell(argc,argv) 234 int argc; 235 char *argv[]; 236 { 237 Spint spinted; 238 static char command[256]; 239 240 ClearElement(spinted); 241 spinted.int_no = API_INTERRUPT_NUMBER; 242 if (argc == 1) { 243 command[0] = 0; 244 } else { 245 char *cmdptr; 246 int length; 247 248 argc--; 249 argv++; 250 strcpy(command, " /c"); 251 cmdptr = command+strlen(command); 252 while (argc) { 253 if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) { 254 fprintf(stderr, "Argument list too long at argument *%s*.\n", 255 *argv); 256 return 0; 257 } 258 *cmdptr++ = ' '; /* Blank separators */ 259 strcpy(cmdptr, *argv); 260 cmdptr += strlen(cmdptr); 261 argc--; 262 argv++; 263 } 264 length = strlen(command)-1; 265 if (length < 0) { 266 length = 0; 267 } 268 command[0] = length; 269 } 270 271 /* 272 * spint_start() returns when either the command has finished, or when 273 * the required interrupt comes in. In the latter case, the appropriate 274 * thing to do is to process the interrupt, and then return to 275 * the interrupt issuer by calling spint_continue(). 276 */ 277 spint_start(command, &spinted); 278 while (spinted.done == 0) { 279 /* Process request */ 280 handle_api(&spinted.regs, &spinted.sregs); 281 spint_continue(&spinted); 282 } 283 if (spinted.rc != 0) { 284 fprintf(stderr, "Process generated a return code of 0x%x.\n", 285 spinted.rc); 286 } 287 return 0; 288 } 289