131158Sminshall /* 231158Sminshall * This file implements the API used in the PC version. 331158Sminshall */ 431158Sminshall 531158Sminshall #include <stdio.h> 631158Sminshall #include <dos.h> 731158Sminshall #include <stdlib.h> 831158Sminshall 931158Sminshall #include "spint.h" 1031158Sminshall #include "api.h" 1131158Sminshall #include "../general.h" 1231158Sminshall 1331158Sminshall 1431158Sminshall /* 1531158Sminshall * Supervisor Services. 1631158Sminshall */ 1731158Sminshall 1831158Sminshall static void 1931158Sminshall name_resolve(regs, sregs) 2031158Sminshall union REGS *regs; 2131158Sminshall struct SREGS *sregs; 2231158Sminshall { 23*31161Sminshall char buffer[9]; 24*31161Sminshall 25*31161Sminshall movetous(buffer, sregs->es, regs->x.di, sizeof buffer-1); 26*31161Sminshall 27*31161Sminshall regs->h.cl = 0; 28*31161Sminshall if (strcmp(buffer, NAME_SESSMGR) == 0) { 29*31161Sminshall regs->x.dx = GATE_SESSMGR; 30*31161Sminshall } else if (strcmp(buffer, NAME_KEYBOARD) == 0) { 31*31161Sminshall regs->x.dx = GATE_KEYBOARD; 32*31161Sminshall } else if (strcmp(buffer, NAME_COPY) == 0) { 33*31161Sminshall regs->x.dx = GATE_COPY; 34*31161Sminshall } else if (strcmp(buffer, NAME_OIAM) == 0) { 35*31161Sminshall regs->x.dx = GATE_OIAM; 36*31161Sminshall } else { 37*31161Sminshall regs->h.cl = 0x2e; /* Name not found */ 38*31161Sminshall } 39*31161Sminshall regs->h.ch = 0x12; 40*31161Sminshall regs->h.bh = 7; 4131158Sminshall } 4231158Sminshall 4331158Sminshall /* 4431158Sminshall * Session Information Services. 4531158Sminshall */ 4631158Sminshall 4731158Sminshall static void 4831158Sminshall query_session_id(regs, sregs) 4931158Sminshall union REGS *regs; 5031158Sminshall struct SREGS *sregs; 5131158Sminshall { 52*31161Sminshall char buffer[16]; 53*31161Sminshall 54*31161Sminshall movetous(buffer, sregs->es, regs->h.di, sizeof buffer); 55*31161Sminshall 56*31161Sminshall if (buffer[0] != 0) { 57*31161Sminshall regs->cl = 0x0c; 58*31161Sminshall } else { 59*31161Sminshall if (buffer[2] != 0x01) { 60*31161Sminshall regs->h.cl = 0x0d; /* Invalid option code */ 61*31161Sminshall } else if (buffer[3] != 0x45) { 62*31161Sminshall regs->h.cl = 0x0b; 63*31161Sminshall } else { 64*31161Sminshall buffer[0] = 0; 65*31161Sminshall buffer[1] = 0x6d; 66*31161Sminshall regs->h.cl = 0; 67*31161Sminshall } 68*31161Sminshall } 69*31161Sminshall movetothem(sregs->es, regs->h.di, sizeof buffer); 7031158Sminshall } 7131158Sminshall 7231158Sminshall static void 7331158Sminshall query_session_parameters(regs, sregs) 7431158Sminshall union REGS *regs; 7531158Sminshall struct SREGS *sregs; 7631158Sminshall { 7731158Sminshall } 7831158Sminshall 7931158Sminshall static void 8031158Sminshall query_session_cursor(regs, sregs) 8131158Sminshall union REGS *regs; 8231158Sminshall struct SREGS *sregs; 8331158Sminshall { 8431158Sminshall } 8531158Sminshall 8631158Sminshall /* 8731158Sminshall * Keyboard Services. 8831158Sminshall */ 8931158Sminshall 9031158Sminshall 9131158Sminshall static void 9231158Sminshall connect_to_keyboard(regs, sregs) 9331158Sminshall union REGS *regs; 9431158Sminshall struct SREGS *sregs; 9531158Sminshall { 9631158Sminshall } 9731158Sminshall 9831158Sminshall static void 9931158Sminshall disable_input(regs, sregs) 10031158Sminshall union REGS *regs; 10131158Sminshall struct SREGS *sregs; 10231158Sminshall { 10331158Sminshall } 10431158Sminshall 10531158Sminshall static void 10631158Sminshall write_keystroke(regs, sregs) 10731158Sminshall union REGS *regs; 10831158Sminshall struct SREGS *sregs; 10931158Sminshall { 11031158Sminshall } 11131158Sminshall 11231158Sminshall static void 11331158Sminshall enable_input(regs, sregs) 11431158Sminshall union REGS *regs; 11531158Sminshall struct SREGS *sregs; 11631158Sminshall { 11731158Sminshall } 11831158Sminshall 11931158Sminshall /* 12031158Sminshall * Copy Services. 12131158Sminshall */ 12231158Sminshall 12331158Sminshall static void 12431158Sminshall disconnect_from_keyboard(regs, sregs) 12531158Sminshall union REGS *regs; 12631158Sminshall struct SREGS *sregs; 12731158Sminshall { 12831158Sminshall } 12931158Sminshall 13031158Sminshall /* 13131158Sminshall * Operator Information Area Services. 13231158Sminshall */ 13331158Sminshall 13431158Sminshall static void 13531158Sminshall read_oia_group(regs, sregs) 13631158Sminshall union REGS *regs; 13731158Sminshall struct SREGS *sregs; 13831158Sminshall { 13931158Sminshall } 14031158Sminshall 14131158Sminshall static void 14231158Sminshall unknown_op(regs, sregs) 14331158Sminshall union REGS *regs; 14431158Sminshall struct SREGS *sregs; 14531158Sminshall { 14631158Sminshall regs->h.ch = 0x12; 14731158Sminshall regs->h.cl = 0x05; 14831158Sminshall } 14931158Sminshall 15031158Sminshall 15131158Sminshall handle_api(regs, sregs) 15231158Sminshall union REGS *regs; 15331158Sminshall struct SREGS *sregs; 15431158Sminshall { 15531158Sminshall if (regs->h.ah == NAME_RESOLUTION) { 15631158Sminshall name_resolution(regs, sregs); 15731158Sminshall } else { 15831158Sminshall switch (regs->x.dx) { 15931158Sminshall case GATE_SESSMGR: 16031158Sminshall switch (regs->h.al) { 16131158Sminshall case QUERY_SESSION_ID: 16231158Sminshall query_session_id(regs, sregs); 16331158Sminshall break; 16431158Sminshall case QUERY_SESSION_PARMS: 16531158Sminshall query_session_parms(regs, sregs); 16631158Sminshall break; 16731158Sminshall case QUERY_SESSION_CURSOR: 16831158Sminshall query_session_cursor(regs, sregs); 16931158Sminshall break; 17031158Sminshall default: 17131158Sminshall unknown_op(regs, sregs); 17231158Sminshall break; 17331158Sminshall } 17431158Sminshall break; 17531158Sminshall case GATE_KEYBOARD: 17631158Sminshall switch (regs->h.al) { 17731158Sminshall case CONNECT_TO_KEYBOARD: 17831158Sminshall connect_to_keyboard(regs, sregs); 17931158Sminshall break; 18031158Sminshall case DISABLE_INPUT: 18131158Sminshall disable_input(regs, sregs); 18231158Sminshall break; 18331158Sminshall case WRITE_KEYSTROKE: 18431158Sminshall write_keystroke(regs, sregs); 18531158Sminshall break; 18631158Sminshall case ENABLE_INPUT: 18731158Sminshall enable_input(regs, sregs); 18831158Sminshall break; 18931158Sminshall case DISCONNECT_FROM_KEYBOARD: 19031158Sminshall disconnect_from_keyboard(regs, sregs); 19131158Sminshall break; 19231158Sminshall default: 19331158Sminshall unknown_op(regs, sregs); 19431158Sminshall break; 19531158Sminshall } 19631158Sminshall break; 19731158Sminshall case GATE_COPY: 19831158Sminshall switch (regs->h.al) { 19931158Sminshall case COPY_STRING: 20031158Sminshall copy_string(regs, sregs); 20131158Sminshall break; 20231158Sminshall default: 20331158Sminshall unknown_op(regs, sregs); 20431158Sminshall break; 20531158Sminshall } 20631158Sminshall break; 20731158Sminshall case GATE_OIAM: 20831158Sminshall switch (regs->h.al) { 20931158Sminshall case READ_OIA_GROUP: 21031158Sminshall read_oia_group(regs, sregs); 21131158Sminshall break; 21231158Sminshall default: 21331158Sminshall unknown_op(regs, sregs); 21431158Sminshall break; 21531158Sminshall } 21631158Sminshall break; 21731158Sminshall default: 21831158Sminshall unknown_op(regs, sregs); 21931158Sminshall break; 22031158Sminshall } 22131158Sminshall } 22231158Sminshall } 22331158Sminshall 22431158Sminshall 22531158Sminshall /* 22631158Sminshall * Called from telnet.c to fork a lower command.com. We 22731158Sminshall * use the spint... routines so that we can pick up 22831158Sminshall * interrupts generated by application programs. 22931158Sminshall */ 23031158Sminshall 23131158Sminshall 23231158Sminshall int 23331158Sminshall shell(argc,argv) 23431158Sminshall int argc; 23531158Sminshall char *argv[]; 23631158Sminshall { 23731158Sminshall Spint spinted; 23831158Sminshall static char command[256]; 23931158Sminshall 24031158Sminshall ClearElement(spinted); 24131158Sminshall spinted.int_no = API_INTERRUPT_NUMBER; 24231158Sminshall if (argc == 1) { 24331158Sminshall command[0] = 0; 24431158Sminshall } else { 24531158Sminshall char *cmdptr; 24631158Sminshall int length; 24731158Sminshall 24831158Sminshall argc--; 24931158Sminshall argv++; 25031158Sminshall strcpy(command, " /c"); 25131158Sminshall cmdptr = command+strlen(command); 25231158Sminshall while (argc) { 25331158Sminshall if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) { 25431158Sminshall fprintf(stderr, "Argument list too long at argument *%s*.\n", 25531158Sminshall *argv); 25631158Sminshall return 0; 25731158Sminshall } 25831158Sminshall *cmdptr++ = ' '; /* Blank separators */ 25931158Sminshall strcpy(cmdptr, *argv); 26031158Sminshall cmdptr += strlen(cmdptr); 26131158Sminshall argc--; 26231158Sminshall argv++; 26331158Sminshall } 26431158Sminshall length = strlen(command)-1; 26531158Sminshall if (length < 0) { 26631158Sminshall length = 0; 26731158Sminshall } 26831158Sminshall command[0] = length; 26931158Sminshall } 27031158Sminshall 27131158Sminshall /* 27231158Sminshall * spint_start() returns when either the command has finished, or when 27331158Sminshall * the required interrupt comes in. In the latter case, the appropriate 27431158Sminshall * thing to do is to process the interrupt, and then return to 27531158Sminshall * the interrupt issuer by calling spint_continue(). 27631158Sminshall */ 27731158Sminshall spint_start(command, &spinted); 27831158Sminshall while (spinted.done == 0) { 27931158Sminshall /* Process request */ 28031158Sminshall handle_api(&spinted.regs, &spinted.sregs); 28131158Sminshall spint_continue(&spinted); 28231158Sminshall } 28331158Sminshall if (spinted.rc != 0) { 28431158Sminshall fprintf(stderr, "Process generated a return code of 0x%x.\n", 28531158Sminshall spinted.rc); 28631158Sminshall } 28731158Sminshall return 0; 28831158Sminshall } 289