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*31167Sminshall NameResolveParms parms; 2431161Sminshall 25*31167Sminshall movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); 2631161Sminshall 2731161Sminshall regs->h.cl = 0; 28*31167Sminshall if (strcmp((char *)&parms, NAME_SESSMGR) == 0) { 2931161Sminshall regs->x.dx = GATE_SESSMGR; 30*31167Sminshall } else if (strcmp((char *)&parms, NAME_KEYBOARD) == 0) { 3131161Sminshall regs->x.dx = GATE_KEYBOARD; 32*31167Sminshall } else if (strcmp((char *)&parms, NAME_COPY) == 0) { 3331161Sminshall regs->x.dx = GATE_COPY; 34*31167Sminshall } else if (strcmp((char *)&parms, NAME_OIAM) == 0) { 3531161Sminshall regs->x.dx = GATE_OIAM; 3631161Sminshall } else { 3731161Sminshall regs->h.cl = 0x2e; /* Name not found */ 3831161Sminshall } 3931161Sminshall regs->h.ch = 0x12; 4031161Sminshall 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*31167Sminshall QuerySessionIdParms parms; 5331161Sminshall 54*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 5531161Sminshall 56*31167Sminshall if (parms.rc != 0) { 57*31167Sminshall regs->h.cl = 0x0c; 58*31167Sminshall return; 59*31167Sminshall } 60*31167Sminshall if (parms.option_code != 0x01) { 61*31167Sminshall regs->h.cl = 0x0d; /* Invalid option code */ 62*31167Sminshall } else if (parms.data_code != 0x45) { 63*31167Sminshall regs->h.cl = 0x0b; 6431161Sminshall } else { 65*31167Sminshall NameArrayList list; 66*31167Sminshall NameArrayElement element; 67*31167Sminshall 68*31167Sminshall movetous((char *)&list, FP_SEG(parms.name_array), 69*31167Sminshall FP_OFFSET(parms.name_array), sizeof list); 70*31167Sminshall if (list.length < 14) || (list.length > 170)) { 71*31167Sminshall parms.rc = 0x12; 72*31167Sminshall regs.h.cl = 0x12; 7331161Sminshall } else { 74*31167Sminshall list.number_matching_session = 1; 75*31167Sminshall list.name_array_element.short_name = parms.data_code; 76*31167Sminshall list.name_array_element.type = TYPE_DFT; 77*31167Sminshall list.name_array_element.session_id = 23; 78*31167Sminshall memcpy(list.name_array_element.long_name, "ONLYSESS", 79*31167Sminshall sizeof list.name_array_element.long_name); 80*31167Sminshall movetothem(FP_SEG(parms.name_array), 81*31167Sminshall FP_OFFSET(parms.name_array), (char *)&list, sizeof list); 82*31167Sminshall parms.rc = 0; 8331161Sminshall regs->h.cl = 0; 8431161Sminshall } 8531161Sminshall } 86*31167Sminshall parms.function_code = 0x6d; 87*31167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 8831158Sminshall } 8931158Sminshall 9031158Sminshall static void 9131158Sminshall query_session_parameters(regs, sregs) 9231158Sminshall union REGS *regs; 9331158Sminshall struct SREGS *sregs; 9431158Sminshall { 95*31167Sminshall QuerySessionParametersParms parms; 96*31167Sminshall 97*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 98*31167Sminshall 99*31167Sminshall if (parms.rc[0] !=0) || (parms.function_id != 0)) { 100*31167Sminshall regs->h.cl = 0x0c; 101*31167Sminshall return; 102*31167Sminshall } 103*31167Sminshall if (parms.session_id != 23) { 104*31167Sminshall regs.h.cl = parms.rc = 0x02; 105*31167Sminshall } else { 106*31167Sminshall regs.h.cl = parms.rc = 0; 107*31167Sminshall parms.function_id = 0x6b; 108*31167Sminshall parms.session_type = TYPE_DFT; 109*31167Sminshall parms.session_characteristics = 0; /* Neither EAB nor PSS */ 110*31167Sminshall parms.rows = MaxNumberLines; 111*31167Sminshall parms.columns = MaxNumberColumns; 112*31167Sminshall parms.presentation_space = 0; 113*31167Sminshall } 114*31167Sminshall movetothem(sregs->es, regs.x.di, (char *)&parms, sizeof parms); 11531158Sminshall } 11631158Sminshall 11731158Sminshall static void 11831158Sminshall query_session_cursor(regs, sregs) 11931158Sminshall union REGS *regs; 12031158Sminshall struct SREGS *sregs; 12131158Sminshall { 122*31167Sminshall QuerySessionCursorParms parms; 123*31167Sminshall 124*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 125*31167Sminshall 126*31167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 127*31167Sminshall parms.rc = 0x0c; 128*31167Sminshall } else if (parms.session_id != 23) { 129*31167Sminshall parms.rc = 0x02; 130*31167Sminshall } else { 131*31167Sminshall parms.rc = 0; 132*31167Sminshall parms.function_id = 0x6b; 133*31167Sminshall parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ 134*31167Sminshall parms.row_address = ScreenLine(CursorAddress); 135*31167Sminshall parms.column_address = ScreenLineOffset(CursorAddress); 136*31167Sminshall } 137*31167Sminshall 138*31167Sminshall movetothem(sregs->es, regs->x.di, sizeof parms); 13931158Sminshall } 14031158Sminshall 14131158Sminshall /* 14231158Sminshall * Keyboard Services. 14331158Sminshall */ 14431158Sminshall 14531158Sminshall 14631158Sminshall static void 14731158Sminshall connect_to_keyboard(regs, sregs) 14831158Sminshall union REGS *regs; 14931158Sminshall struct SREGS *sregs; 15031158Sminshall { 151*31167Sminshall ConnectToKeyboardParms parms; 152*31167Sminshall 153*31167Sminshall movetous((char *)parms, sregs->es, regs->x.di, sizeof parms); 154*31167Sminshall 155*31167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 156*31167Sminshall parms.rc = 0x0c; 157*31167Sminshall } else if (parms.session_id != 23) { 158*31167Sminshall parms.rc = 0x02; 159*31167Sminshall } else if (parms.intercept_options != 0) { 160*31167Sminshall parms.rc = 0x01; 161*31167Sminshall } else { 162*31167Sminshall parms.rc = 0; 163*31167Sminshall parms.first_connection_identifier = 0; 164*31167Sminshall } 165*31167Sminshall parms.function_id = 0x62; 166*31167Sminshall 167*31167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 16831158Sminshall } 16931158Sminshall 17031158Sminshall static void 171*31167Sminshall disconnect_from_keyboard(regs, sregs) 17231158Sminshall union REGS *regs; 17331158Sminshall struct SREGS *sregs; 17431158Sminshall { 175*31167Sminshall DisconnectFromKeyboardParms parms; 176*31167Sminshall 177*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 178*31167Sminshall 179*31167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 180*31167Sminshall parms.rc = 0x0c; 181*31167Sminshall } else if (parms.session_id != 23) { 182*31167Sminshall parms.rc = 0x02; 183*31167Sminshall } else if (parms.connectors_task_id != 0) { 184*31167Sminshall parms.rc = 04; /* XXX */ 185*31167Sminshall } else { 186*31167Sminshall parms.rc = 0; 187*31167Sminshall } 188*31167Sminshall parms.function_id = 0x62; 189*31167Sminshall 190*31167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 19131158Sminshall } 19231158Sminshall 19331158Sminshall static void 19431158Sminshall write_keystroke(regs, sregs) 19531158Sminshall union REGS *regs; 19631158Sminshall struct SREGS *sregs; 19731158Sminshall { 198*31167Sminshall /* XXX */ 19931158Sminshall } 20031158Sminshall 201*31167Sminshall 20231158Sminshall static void 203*31167Sminshall disable_input(regs, sregs) 204*31167Sminshall union REGS *regs; 205*31167Sminshall struct SREGS *sregs; 206*31167Sminshall { 207*31167Sminshall DisableInputParms parms; 208*31167Sminshall 209*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 210*31167Sminshall 211*31167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 212*31167Sminshall parms.rc = 0x0c; 213*31167Sminshall } else if (parms.session_id != 23) { 214*31167Sminshall parms.rc = 0x02; 215*31167Sminshall } else if (parms.connectors_task_id != 0) { 216*31167Sminshall parms.rc = 0x04; 217*31167Sminshall } else { 218*31167Sminshall ApiDisableInput = 1; 219*31167Sminshall parms.rc = 0; 220*31167Sminshall } 221*31167Sminshall parms.function_id = 0x62; 222*31167Sminshall 223*31167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 224*31167Sminshall } 225*31167Sminshall 226*31167Sminshall static void 22731158Sminshall enable_input(regs, sregs) 22831158Sminshall union REGS *regs; 22931158Sminshall struct SREGS *sregs; 23031158Sminshall { 231*31167Sminshall EnableInputParms parms; 232*31167Sminshall 233*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 234*31167Sminshall 235*31167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 236*31167Sminshall parms.rc = 0x0c; 237*31167Sminshall } else if (parms.session_id != 23) { 238*31167Sminshall parms.rc = 0x02; 239*31167Sminshall } else if (parms.connectors_task_id != 0) { 240*31167Sminshall parms.rc = 0x04; 241*31167Sminshall } else { 242*31167Sminshall ApiDisableInput = 0; 243*31167Sminshall parms.rc = 0; 244*31167Sminshall } 245*31167Sminshall parms.function_id = 0x62; 246*31167Sminshall 247*31167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 24831158Sminshall } 24931158Sminshall 25031158Sminshall /* 25131158Sminshall * Copy Services. 25231158Sminshall */ 25331158Sminshall 25431158Sminshall static void 255*31167Sminshall copy_string(regs, sregs) 25631158Sminshall union REGS *regs; 25731158Sminshall struct SREGS *sregs; 25831158Sminshall { 259*31167Sminshall CopyStringParms parms; 260*31167Sminshall BufferDescriptor *target, *source; 261*31167Sminshall 262*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 263*31167Sminshall 264*31167Sminshall if ((parms.rc != 0) || (parms.function_id !=0)) { 265*31167Sminshall parms.rc = 0x0c; 266*31167Sminshall } 267*31167Sminshall /* XXX do something! */ 268*31167Sminshall movetothem(sregs->es, regs->x.di, (char *)parms, sizeof parms); 26931158Sminshall } 27031158Sminshall /* 27131158Sminshall * Operator Information Area Services. 27231158Sminshall */ 27331158Sminshall 27431158Sminshall static void 27531158Sminshall read_oia_group(regs, sregs) 27631158Sminshall union REGS *regs; 27731158Sminshall struct SREGS *sregs; 27831158Sminshall { 279*31167Sminshall ReadOiaGroupParms parms; 280*31167Sminshall 281*31167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 282*31167Sminshall 283*31167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 284*31167Sminshall parms.rc = 0x0c; 285*31167Sminshall } else if (parms.session_id != 23) { 286*31167Sminshall parms.rc = 0x02; 287*31167Sminshall } else { 288*31167Sminshall int group = parms.oia_group_number; 289*31167Sminshall char far *where = parms.oia_buffer; 290*31167Sminshall 291*31167Sminshall switch (group) { 292*31167Sminshall case OIA_ALL_GROUPS: 293*31167Sminshall case OIA_ONLINE_OWNERSHIP: 294*31167Sminshall if (group != OIA_ALL_GROUPS) { 295*31167Sminshall break; 296*31167Sminshall } /* else, fall through */ 297*31167Sminshall case OIA_CHARACTER_SELECTION: 298*31167Sminshall if (group != OIA_ALL_GROUPS) { 299*31167Sminshall break; 300*31167Sminshall } /* else, fall through */ 301*31167Sminshall case OIA_SHIFT_STATE: 302*31167Sminshall if (group != OIA_ALL_GROUPS) { 303*31167Sminshall break; 304*31167Sminshall } /* else, fall through */ 305*31167Sminshall case OIA_PSS_GROUP_1: 306*31167Sminshall if (group != OIA_ALL_GROUPS) { 307*31167Sminshall break; 308*31167Sminshall } /* else, fall through */ 309*31167Sminshall case OIA_HIGHLIGHT_GROUP_1: 310*31167Sminshall if (group != OIA_ALL_GROUPS) { 311*31167Sminshall break; 312*31167Sminshall } /* else, fall through */ 313*31167Sminshall case OIA_COLOR_GROUP_1: 314*31167Sminshall if (group != OIA_ALL_GROUPS) { 315*31167Sminshall break; 316*31167Sminshall } /* else, fall through */ 317*31167Sminshall case OIA_INSERT: 318*31167Sminshall if (group != OIA_ALL_GROUPS) { 319*31167Sminshall break; 320*31167Sminshall } /* else, fall through */ 321*31167Sminshall case OIA_INPUT_INHIBITED: 322*31167Sminshall if (group != OIA_ALL_GROUPS) { 323*31167Sminshall break; 324*31167Sminshall } /* else, fall through */ 325*31167Sminshall case OIA_PSS_GROUP_2: 326*31167Sminshall if (group != OIA_ALL_GROUPS) { 327*31167Sminshall break; 328*31167Sminshall } /* else, fall through */ 329*31167Sminshall case OIA_HIGHLIGHT_GROUP_2: 330*31167Sminshall if (group != OIA_ALL_GROUPS) { 331*31167Sminshall break; 332*31167Sminshall } /* else, fall through */ 333*31167Sminshall case OIA_COLOR_GROUP_2: 334*31167Sminshall if (group != OIA_ALL_GROUPS) { 335*31167Sminshall break; 336*31167Sminshall } /* else, fall through */ 337*31167Sminshall case OIA_COMMUNICATION_ERROR_REMINDER: 338*31167Sminshall if (group != OIA_ALL_GROUPS) { 339*31167Sminshall break; 340*31167Sminshall } /* else, fall through */ 341*31167Sminshall case OIA_PRINTER_STATUS: 342*31167Sminshall if (group != OIA_ALL_GROUPS) { 343*31167Sminshall break; 344*31167Sminshall } /* else, fall through */ 345*31167Sminshall case OIA_AUTOKEY_PLAY_RECORD_STATUS: 346*31167Sminshall if (group != OIA_ALL_GROUPS) { 347*31167Sminshall break; 348*31167Sminshall } /* else, fall through */ 349*31167Sminshall case OIA_AUTOKEY_ABORT_PAUSE_STATUS: 350*31167Sminshall if (group != OIA_ALL_GROUPS) { 351*31167Sminshall break; 352*31167Sminshall } /* else, fall through */ 353*31167Sminshall case OIA_ENLARGE_STATE: 354*31167Sminshall if (group != OIA_ALL_GROUPS) { 355*31167Sminshall break; 356*31167Sminshall } /* else, fall through */ 357*31167Sminshall 358*31167Sminshall /* oops, we are done! */ 359*31167Sminshall break; 360*31167Sminshall default: 361*31167Sminshall break; 362*31167Sminshall } 363*31167Sminshall parms->function_id = 0x6d; 364*31167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 36531158Sminshall } 36631158Sminshall 36731158Sminshall static void 36831158Sminshall unknown_op(regs, sregs) 36931158Sminshall union REGS *regs; 37031158Sminshall struct SREGS *sregs; 37131158Sminshall { 37231158Sminshall regs->h.ch = 0x12; 37331158Sminshall regs->h.cl = 0x05; 37431158Sminshall } 37531158Sminshall 37631158Sminshall 37731158Sminshall handle_api(regs, sregs) 37831158Sminshall union REGS *regs; 37931158Sminshall struct SREGS *sregs; 38031158Sminshall { 38131158Sminshall if (regs->h.ah == NAME_RESOLUTION) { 38231158Sminshall name_resolution(regs, sregs); 38331158Sminshall } else { 38431158Sminshall switch (regs->x.dx) { 38531158Sminshall case GATE_SESSMGR: 38631158Sminshall switch (regs->h.al) { 38731158Sminshall case QUERY_SESSION_ID: 38831158Sminshall query_session_id(regs, sregs); 38931158Sminshall break; 39031158Sminshall case QUERY_SESSION_PARMS: 39131158Sminshall query_session_parms(regs, sregs); 39231158Sminshall break; 39331158Sminshall case QUERY_SESSION_CURSOR: 39431158Sminshall query_session_cursor(regs, sregs); 39531158Sminshall break; 39631158Sminshall default: 39731158Sminshall unknown_op(regs, sregs); 39831158Sminshall break; 39931158Sminshall } 40031158Sminshall break; 40131158Sminshall case GATE_KEYBOARD: 40231158Sminshall switch (regs->h.al) { 40331158Sminshall case CONNECT_TO_KEYBOARD: 40431158Sminshall connect_to_keyboard(regs, sregs); 40531158Sminshall break; 40631158Sminshall case DISABLE_INPUT: 40731158Sminshall disable_input(regs, sregs); 40831158Sminshall break; 40931158Sminshall case WRITE_KEYSTROKE: 41031158Sminshall write_keystroke(regs, sregs); 41131158Sminshall break; 41231158Sminshall case ENABLE_INPUT: 41331158Sminshall enable_input(regs, sregs); 41431158Sminshall break; 41531158Sminshall case DISCONNECT_FROM_KEYBOARD: 41631158Sminshall disconnect_from_keyboard(regs, sregs); 41731158Sminshall break; 41831158Sminshall default: 41931158Sminshall unknown_op(regs, sregs); 42031158Sminshall break; 42131158Sminshall } 42231158Sminshall break; 42331158Sminshall case GATE_COPY: 42431158Sminshall switch (regs->h.al) { 42531158Sminshall case COPY_STRING: 42631158Sminshall copy_string(regs, sregs); 42731158Sminshall break; 42831158Sminshall default: 42931158Sminshall unknown_op(regs, sregs); 43031158Sminshall break; 43131158Sminshall } 43231158Sminshall break; 43331158Sminshall case GATE_OIAM: 43431158Sminshall switch (regs->h.al) { 43531158Sminshall case READ_OIA_GROUP: 43631158Sminshall read_oia_group(regs, sregs); 43731158Sminshall break; 43831158Sminshall default: 43931158Sminshall unknown_op(regs, sregs); 44031158Sminshall break; 44131158Sminshall } 44231158Sminshall break; 44331158Sminshall default: 44431158Sminshall unknown_op(regs, sregs); 44531158Sminshall break; 44631158Sminshall } 44731158Sminshall } 44831158Sminshall } 44931158Sminshall 45031158Sminshall 45131158Sminshall /* 45231158Sminshall * Called from telnet.c to fork a lower command.com. We 45331158Sminshall * use the spint... routines so that we can pick up 45431158Sminshall * interrupts generated by application programs. 45531158Sminshall */ 45631158Sminshall 45731158Sminshall 45831158Sminshall int 45931158Sminshall shell(argc,argv) 46031158Sminshall int argc; 46131158Sminshall char *argv[]; 46231158Sminshall { 46331158Sminshall Spint spinted; 46431158Sminshall static char command[256]; 46531158Sminshall 46631158Sminshall ClearElement(spinted); 46731158Sminshall spinted.int_no = API_INTERRUPT_NUMBER; 46831158Sminshall if (argc == 1) { 46931158Sminshall command[0] = 0; 47031158Sminshall } else { 47131158Sminshall char *cmdptr; 47231158Sminshall int length; 47331158Sminshall 47431158Sminshall argc--; 47531158Sminshall argv++; 47631158Sminshall strcpy(command, " /c"); 47731158Sminshall cmdptr = command+strlen(command); 47831158Sminshall while (argc) { 47931158Sminshall if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) { 48031158Sminshall fprintf(stderr, "Argument list too long at argument *%s*.\n", 48131158Sminshall *argv); 48231158Sminshall return 0; 48331158Sminshall } 48431158Sminshall *cmdptr++ = ' '; /* Blank separators */ 48531158Sminshall strcpy(cmdptr, *argv); 48631158Sminshall cmdptr += strlen(cmdptr); 48731158Sminshall argc--; 48831158Sminshall argv++; 48931158Sminshall } 49031158Sminshall length = strlen(command)-1; 49131158Sminshall if (length < 0) { 49231158Sminshall length = 0; 49331158Sminshall } 49431158Sminshall command[0] = length; 49531158Sminshall } 49631158Sminshall 49731158Sminshall /* 49831158Sminshall * spint_start() returns when either the command has finished, or when 49931158Sminshall * the required interrupt comes in. In the latter case, the appropriate 50031158Sminshall * thing to do is to process the interrupt, and then return to 50131158Sminshall * the interrupt issuer by calling spint_continue(). 50231158Sminshall */ 50331158Sminshall spint_start(command, &spinted); 50431158Sminshall while (spinted.done == 0) { 50531158Sminshall /* Process request */ 50631158Sminshall handle_api(&spinted.regs, &spinted.sregs); 50731158Sminshall spint_continue(&spinted); 50831158Sminshall } 50931158Sminshall if (spinted.rc != 0) { 51031158Sminshall fprintf(stderr, "Process generated a return code of 0x%x.\n", 51131158Sminshall spinted.rc); 51231158Sminshall } 51331158Sminshall return 0; 51431158Sminshall } 515