/* * This file implements the API used in the PC version. */ #include #include #include #include "spint.h" #include "api.h" #include "../general.h" /* * Supervisor Services. */ static void name_resolve(regs, sregs) union REGS *regs; struct SREGS *sregs; { } /* * Session Information Services. */ static void query_session_id(regs, sregs) union REGS *regs; struct SREGS *sregs; { } static void query_session_parameters(regs, sregs) union REGS *regs; struct SREGS *sregs; { } static void query_session_cursor(regs, sregs) union REGS *regs; struct SREGS *sregs; { } /* * Keyboard Services. */ static void connect_to_keyboard(regs, sregs) union REGS *regs; struct SREGS *sregs; { } static void disable_input(regs, sregs) union REGS *regs; struct SREGS *sregs; { } static void write_keystroke(regs, sregs) union REGS *regs; struct SREGS *sregs; { } static void enable_input(regs, sregs) union REGS *regs; struct SREGS *sregs; { } /* * Copy Services. */ static void disconnect_from_keyboard(regs, sregs) union REGS *regs; struct SREGS *sregs; { } /* * Operator Information Area Services. */ static void read_oia_group(regs, sregs) union REGS *regs; struct SREGS *sregs; { } static void unknown_op(regs, sregs) union REGS *regs; struct SREGS *sregs; { regs->h.ch = 0x12; regs->h.cl = 0x05; } handle_api(regs, sregs) union REGS *regs; struct SREGS *sregs; { if (regs->h.ah == NAME_RESOLUTION) { name_resolution(regs, sregs); } else { switch (regs->x.dx) { case GATE_SESSMGR: switch (regs->h.al) { case QUERY_SESSION_ID: query_session_id(regs, sregs); break; case QUERY_SESSION_PARMS: query_session_parms(regs, sregs); break; case QUERY_SESSION_CURSOR: query_session_cursor(regs, sregs); break; default: unknown_op(regs, sregs); break; } break; case GATE_KEYBOARD: switch (regs->h.al) { case CONNECT_TO_KEYBOARD: connect_to_keyboard(regs, sregs); break; case DISABLE_INPUT: disable_input(regs, sregs); break; case WRITE_KEYSTROKE: write_keystroke(regs, sregs); break; case ENABLE_INPUT: enable_input(regs, sregs); break; case DISCONNECT_FROM_KEYBOARD: disconnect_from_keyboard(regs, sregs); break; default: unknown_op(regs, sregs); break; } break; case GATE_COPY: switch (regs->h.al) { case COPY_STRING: copy_string(regs, sregs); break; default: unknown_op(regs, sregs); break; } break; case GATE_OIAM: switch (regs->h.al) { case READ_OIA_GROUP: read_oia_group(regs, sregs); break; default: unknown_op(regs, sregs); break; } break; default: unknown_op(regs, sregs); break; } } } /* * Called from telnet.c to fork a lower command.com. We * use the spint... routines so that we can pick up * interrupts generated by application programs. */ int shell(argc,argv) int argc; char *argv[]; { Spint spinted; static char command[256]; ClearElement(spinted); spinted.int_no = API_INTERRUPT_NUMBER; if (argc == 1) { command[0] = 0; } else { char *cmdptr; int length; argc--; argv++; strcpy(command, " /c"); cmdptr = command+strlen(command); while (argc) { if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) { fprintf(stderr, "Argument list too long at argument *%s*.\n", *argv); return 0; } *cmdptr++ = ' '; /* Blank separators */ strcpy(cmdptr, *argv); cmdptr += strlen(cmdptr); argc--; argv++; } length = strlen(command)-1; if (length < 0) { length = 0; } command[0] = length; } /* * spint_start() returns when either the command has finished, or when * the required interrupt comes in. In the latter case, the appropriate * thing to do is to process the interrupt, and then return to * the interrupt issuer by calling spint_continue(). */ spint_start(command, &spinted); while (spinted.done == 0) { /* Process request */ handle_api(&spinted.regs, &spinted.sregs); spint_continue(&spinted); } if (spinted.rc != 0) { fprintf(stderr, "Process generated a return code of 0x%x.\n", spinted.rc); } return 0; }