xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31168)
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 
13*31168Sminshall #include "../ctlr/screen.h"
14*31168Sminshall #include "../system/globals.h"
1531158Sminshall 
16*31168Sminshall int ApiDisableInput = 0;
17*31168Sminshall 
1831158Sminshall /*
1931158Sminshall  * Supervisor Services.
2031158Sminshall  */
2131158Sminshall 
2231158Sminshall static void
2331158Sminshall name_resolve(regs, sregs)
2431158Sminshall union REGS *regs;
2531158Sminshall struct SREGS *sregs;
2631158Sminshall {
2731167Sminshall     NameResolveParms parms;
2831161Sminshall 
2931167Sminshall     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
3031161Sminshall 
3131161Sminshall     regs->h.cl = 0;
3231167Sminshall     if (strcmp((char *)&parms, NAME_SESSMGR) == 0) {
3331161Sminshall 	regs->x.dx = GATE_SESSMGR;
3431167Sminshall     } else if (strcmp((char *)&parms, NAME_KEYBOARD) == 0) {
3531161Sminshall 	regs->x.dx = GATE_KEYBOARD;
3631167Sminshall     } else if (strcmp((char *)&parms, NAME_COPY) == 0) {
3731161Sminshall 	regs->x.dx = GATE_COPY;
3831167Sminshall     } else if (strcmp((char *)&parms, NAME_OIAM) == 0) {
3931161Sminshall 	regs->x.dx = GATE_OIAM;
4031161Sminshall     } else {
4131161Sminshall 	regs->h.cl = 0x2e;	/* Name not found */
4231161Sminshall     }
4331161Sminshall     regs->h.ch = 0x12;
4431161Sminshall     regs->h.bh = 7;
4531158Sminshall }
4631158Sminshall 
4731158Sminshall /*
4831158Sminshall  * Session Information Services.
4931158Sminshall  */
5031158Sminshall 
5131158Sminshall static void
5231158Sminshall query_session_id(regs, sregs)
5331158Sminshall union REGS *regs;
5431158Sminshall struct SREGS *sregs;
5531158Sminshall {
5631167Sminshall     QuerySessionIdParms parms;
5731161Sminshall 
5831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
5931161Sminshall 
6031167Sminshall     if (parms.rc != 0) {
6131167Sminshall 	regs->h.cl = 0x0c;
6231167Sminshall 	return;
6331167Sminshall     }
6431167Sminshall     if (parms.option_code != 0x01) {
6531167Sminshall 	regs->h.cl = 0x0d;	/* Invalid option code */
6631167Sminshall     } else if (parms.data_code != 0x45) {
6731167Sminshall 	regs->h.cl = 0x0b;
6831161Sminshall     } else {
69*31168Sminshall 	NameArray list;
7031167Sminshall 	NameArrayElement element;
7131167Sminshall 
7231167Sminshall 	movetous((char *)&list, FP_SEG(parms.name_array),
7331167Sminshall 			    FP_OFFSET(parms.name_array), sizeof list);
74*31168Sminshall 	if ((list.length < 14) || (list.length > 170)) {
7531167Sminshall 	    parms.rc = 0x12;
76*31168Sminshall 	    regs->h.cl = 0x12;
7731161Sminshall 	} else {
7831167Sminshall 	    list.number_matching_session = 1;
7931167Sminshall 	    list.name_array_element.short_name = parms.data_code;
8031167Sminshall 	    list.name_array_element.type = TYPE_DFT;
8131167Sminshall 	    list.name_array_element.session_id = 23;
8231167Sminshall 	    memcpy(list.name_array_element.long_name, "ONLYSESS",
8331167Sminshall 			    sizeof list.name_array_element.long_name);
8431167Sminshall 	    movetothem(FP_SEG(parms.name_array),
8531167Sminshall 		FP_OFFSET(parms.name_array), (char *)&list, sizeof list);
8631167Sminshall 	    parms.rc = 0;
8731161Sminshall 	    regs->h.cl = 0;
8831161Sminshall 	}
8931161Sminshall     }
90*31168Sminshall     parms.function_id = 0x6d;
9131167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
9231158Sminshall }
9331158Sminshall 
9431158Sminshall static void
9531158Sminshall query_session_parameters(regs, sregs)
9631158Sminshall union REGS *regs;
9731158Sminshall struct SREGS *sregs;
9831158Sminshall {
9931167Sminshall     QuerySessionParametersParms parms;
10031167Sminshall 
10131167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
10231167Sminshall 
103*31168Sminshall     if ((parms.rc !=0) || (parms.function_id != 0)) {
10431167Sminshall 	regs->h.cl = 0x0c;
10531167Sminshall 	return;
10631167Sminshall     }
10731167Sminshall     if (parms.session_id != 23) {
108*31168Sminshall 	regs->h.cl = parms.rc = 0x02;
10931167Sminshall     } else {
110*31168Sminshall 	regs->h.cl = parms.rc = 0;
11131167Sminshall 	parms.function_id = 0x6b;
11231167Sminshall 	parms.session_type = TYPE_DFT;
11331167Sminshall 	parms.session_characteristics = 0;	/* Neither EAB nor PSS */
11431167Sminshall 	parms.rows = MaxNumberLines;
11531167Sminshall 	parms.columns = MaxNumberColumns;
11631167Sminshall 	parms.presentation_space = 0;
11731167Sminshall     }
118*31168Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
11931158Sminshall }
12031158Sminshall 
12131158Sminshall static void
12231158Sminshall query_session_cursor(regs, sregs)
12331158Sminshall union REGS *regs;
12431158Sminshall struct SREGS *sregs;
12531158Sminshall {
12631167Sminshall     QuerySessionCursorParms parms;
12731167Sminshall 
12831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
12931167Sminshall 
13031167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
13131167Sminshall 	parms.rc = 0x0c;
13231167Sminshall     } else if (parms.session_id != 23) {
13331167Sminshall 	parms.rc = 0x02;
13431167Sminshall     } else {
13531167Sminshall 	parms.rc = 0;
13631167Sminshall 	parms.function_id = 0x6b;
13731167Sminshall 	parms.cursor_type = CURSOR_BLINKING;	/* XXX what is inhibited? */
13831167Sminshall 	parms.row_address = ScreenLine(CursorAddress);
13931167Sminshall 	parms.column_address = ScreenLineOffset(CursorAddress);
14031167Sminshall     }
14131167Sminshall 
14231167Sminshall     movetothem(sregs->es, regs->x.di, sizeof parms);
14331158Sminshall }
14431158Sminshall 
14531158Sminshall /*
14631158Sminshall  * Keyboard Services.
14731158Sminshall  */
14831158Sminshall 
14931158Sminshall 
15031158Sminshall static void
15131158Sminshall connect_to_keyboard(regs, sregs)
15231158Sminshall union REGS *regs;
15331158Sminshall struct SREGS *sregs;
15431158Sminshall {
15531167Sminshall     ConnectToKeyboardParms parms;
15631167Sminshall 
15731167Sminshall     movetous((char *)parms, sregs->es, regs->x.di, sizeof parms);
15831167Sminshall 
15931167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
16031167Sminshall 	parms.rc = 0x0c;
16131167Sminshall     } else if (parms.session_id != 23) {
16231167Sminshall 	parms.rc = 0x02;
16331167Sminshall     } else if (parms.intercept_options != 0) {
16431167Sminshall 	parms.rc = 0x01;
16531167Sminshall     } else {
16631167Sminshall 	parms.rc = 0;
16731167Sminshall 	parms.first_connection_identifier = 0;
16831167Sminshall     }
16931167Sminshall     parms.function_id = 0x62;
17031167Sminshall 
17131167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
17231158Sminshall }
17331158Sminshall 
17431158Sminshall static void
17531167Sminshall disconnect_from_keyboard(regs, sregs)
17631158Sminshall union REGS *regs;
17731158Sminshall struct SREGS *sregs;
17831158Sminshall {
17931167Sminshall     DisconnectFromKeyboardParms parms;
18031167Sminshall 
18131167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
18231167Sminshall 
18331167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
18431167Sminshall 	parms.rc = 0x0c;
18531167Sminshall     } else if (parms.session_id != 23) {
18631167Sminshall 	parms.rc = 0x02;
18731167Sminshall     } else if (parms.connectors_task_id != 0) {
18831167Sminshall 	parms.rc = 04;			/* XXX */
18931167Sminshall     } else {
19031167Sminshall 	parms.rc = 0;
19131167Sminshall     }
19231167Sminshall     parms.function_id = 0x62;
19331167Sminshall 
19431167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
19531158Sminshall }
19631158Sminshall 
19731158Sminshall static void
19831158Sminshall write_keystroke(regs, sregs)
19931158Sminshall union REGS *regs;
20031158Sminshall struct SREGS *sregs;
20131158Sminshall {
20231167Sminshall /* XXX */
20331158Sminshall }
20431158Sminshall 
20531167Sminshall 
20631158Sminshall static void
20731167Sminshall disable_input(regs, sregs)
20831167Sminshall union REGS *regs;
20931167Sminshall struct SREGS *sregs;
21031167Sminshall {
21131167Sminshall     DisableInputParms parms;
21231167Sminshall 
21331167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
21431167Sminshall 
21531167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
21631167Sminshall 	parms.rc = 0x0c;
21731167Sminshall     } else if (parms.session_id != 23) {
21831167Sminshall 	parms.rc = 0x02;
21931167Sminshall     } else if (parms.connectors_task_id != 0) {
22031167Sminshall 	parms.rc = 0x04;
22131167Sminshall     } else {
22231167Sminshall 	ApiDisableInput = 1;
22331167Sminshall 	parms.rc = 0;
22431167Sminshall     }
22531167Sminshall     parms.function_id = 0x62;
22631167Sminshall 
22731167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
22831167Sminshall }
22931167Sminshall 
23031167Sminshall static void
23131158Sminshall enable_input(regs, sregs)
23231158Sminshall union REGS *regs;
23331158Sminshall struct SREGS *sregs;
23431158Sminshall {
23531167Sminshall     EnableInputParms parms;
23631167Sminshall 
23731167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
23831167Sminshall 
23931167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
24031167Sminshall 	parms.rc = 0x0c;
24131167Sminshall     } else if (parms.session_id != 23) {
24231167Sminshall 	parms.rc = 0x02;
24331167Sminshall     } else if (parms.connectors_task_id != 0) {
24431167Sminshall 	parms.rc = 0x04;
24531167Sminshall     } else {
24631167Sminshall 	ApiDisableInput = 0;
24731167Sminshall 	parms.rc = 0;
24831167Sminshall     }
24931167Sminshall     parms.function_id = 0x62;
25031167Sminshall 
25131167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
25231158Sminshall }
25331158Sminshall 
25431158Sminshall /*
25531158Sminshall  * Copy Services.
25631158Sminshall  */
25731158Sminshall 
25831158Sminshall static void
25931167Sminshall copy_string(regs, sregs)
26031158Sminshall union REGS *regs;
26131158Sminshall struct SREGS *sregs;
26231158Sminshall {
26331167Sminshall     CopyStringParms parms;
26431167Sminshall     BufferDescriptor *target, *source;
26531167Sminshall 
26631167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
26731167Sminshall 
26831167Sminshall     if ((parms.rc != 0) || (parms.function_id !=0)) {
26931167Sminshall 	parms.rc = 0x0c;
27031167Sminshall     }
27131167Sminshall     /* XXX do something! */
27231167Sminshall     movetothem(sregs->es, regs->x.di, (char *)parms, sizeof parms);
27331158Sminshall }
27431158Sminshall /*
27531158Sminshall  * Operator Information Area Services.
27631158Sminshall  */
27731158Sminshall 
27831158Sminshall static void
27931158Sminshall read_oia_group(regs, sregs)
28031158Sminshall union REGS *regs;
28131158Sminshall struct SREGS *sregs;
28231158Sminshall {
28331167Sminshall     ReadOiaGroupParms parms;
28431167Sminshall 
28531167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
28631167Sminshall 
28731167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
28831167Sminshall 	parms.rc = 0x0c;
28931167Sminshall     } else if (parms.session_id != 23) {
29031167Sminshall 	parms.rc = 0x02;
29131167Sminshall     } else {
29231167Sminshall 	int group = parms.oia_group_number;
29331167Sminshall 	char far *where = parms.oia_buffer;
29431167Sminshall 
29531167Sminshall 	switch (group) {
29631167Sminshall 	case OIA_ALL_GROUPS:
29731167Sminshall 	case OIA_ONLINE_OWNERSHIP:
29831167Sminshall 	    if (group != OIA_ALL_GROUPS) {
29931167Sminshall 		break;
30031167Sminshall 	    } /* else, fall through */
30131167Sminshall 	case OIA_CHARACTER_SELECTION:
30231167Sminshall 	    if (group != OIA_ALL_GROUPS) {
30331167Sminshall 		break;
30431167Sminshall 	    } /* else, fall through */
30531167Sminshall 	case OIA_SHIFT_STATE:
30631167Sminshall 	    if (group != OIA_ALL_GROUPS) {
30731167Sminshall 		break;
30831167Sminshall 	    } /* else, fall through */
30931167Sminshall 	case OIA_PSS_GROUP_1:
31031167Sminshall 	    if (group != OIA_ALL_GROUPS) {
31131167Sminshall 		break;
31231167Sminshall 	    } /* else, fall through */
31331167Sminshall 	case OIA_HIGHLIGHT_GROUP_1:
31431167Sminshall 	    if (group != OIA_ALL_GROUPS) {
31531167Sminshall 		break;
31631167Sminshall 	    } /* else, fall through */
31731167Sminshall 	case OIA_COLOR_GROUP_1:
31831167Sminshall 	    if (group != OIA_ALL_GROUPS) {
31931167Sminshall 		break;
32031167Sminshall 	    } /* else, fall through */
32131167Sminshall 	case OIA_INSERT:
32231167Sminshall 	    if (group != OIA_ALL_GROUPS) {
32331167Sminshall 		break;
32431167Sminshall 	    } /* else, fall through */
32531167Sminshall 	case OIA_INPUT_INHIBITED:
32631167Sminshall 	    if (group != OIA_ALL_GROUPS) {
32731167Sminshall 		break;
32831167Sminshall 	    } /* else, fall through */
32931167Sminshall 	case OIA_PSS_GROUP_2:
33031167Sminshall 	    if (group != OIA_ALL_GROUPS) {
33131167Sminshall 		break;
33231167Sminshall 	    } /* else, fall through */
33331167Sminshall 	case OIA_HIGHLIGHT_GROUP_2:
33431167Sminshall 	    if (group != OIA_ALL_GROUPS) {
33531167Sminshall 		break;
33631167Sminshall 	    } /* else, fall through */
33731167Sminshall 	case OIA_COLOR_GROUP_2:
33831167Sminshall 	    if (group != OIA_ALL_GROUPS) {
33931167Sminshall 		break;
34031167Sminshall 	    } /* else, fall through */
34131167Sminshall 	case OIA_COMMUNICATION_ERROR_REMINDER:
34231167Sminshall 	    if (group != OIA_ALL_GROUPS) {
34331167Sminshall 		break;
34431167Sminshall 	    } /* else, fall through */
34531167Sminshall 	case OIA_PRINTER_STATUS:
34631167Sminshall 	    if (group != OIA_ALL_GROUPS) {
34731167Sminshall 		break;
34831167Sminshall 	    } /* else, fall through */
34931167Sminshall 	case OIA_AUTOKEY_PLAY_RECORD_STATUS:
35031167Sminshall 	    if (group != OIA_ALL_GROUPS) {
35131167Sminshall 		break;
35231167Sminshall 	    } /* else, fall through */
35331167Sminshall 	case OIA_AUTOKEY_ABORT_PAUSE_STATUS:
35431167Sminshall 	    if (group != OIA_ALL_GROUPS) {
35531167Sminshall 		break;
35631167Sminshall 	    } /* else, fall through */
35731167Sminshall 	case OIA_ENLARGE_STATE:
35831167Sminshall 	    if (group != OIA_ALL_GROUPS) {
35931167Sminshall 		break;
36031167Sminshall 	    } /* else, fall through */
36131167Sminshall 
36231167Sminshall 	    /* oops, we are done! */
36331167Sminshall 	    break;
36431167Sminshall 	default:
36531167Sminshall 	    break;
366*31168Sminshall 	}
36731167Sminshall     }
368*31168Sminshall     parms.function_id = 0x6d;
36931167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
37031158Sminshall }
37131158Sminshall 
37231158Sminshall static void
37331158Sminshall unknown_op(regs, sregs)
37431158Sminshall union REGS *regs;
37531158Sminshall struct SREGS *sregs;
37631158Sminshall {
37731158Sminshall     regs->h.ch = 0x12;
37831158Sminshall     regs->h.cl = 0x05;
37931158Sminshall }
38031158Sminshall 
38131158Sminshall 
38231158Sminshall handle_api(regs, sregs)
38331158Sminshall union REGS *regs;
38431158Sminshall struct SREGS *sregs;
38531158Sminshall {
38631158Sminshall     if (regs->h.ah == NAME_RESOLUTION) {
38731158Sminshall 	name_resolution(regs, sregs);
388*31168Sminshall     } else if (regs->h.ah != 0x09) {
389*31168Sminshall 	regs->h.ch = 0x12;
390*31168Sminshall 	regs->h.cl = 0x0f;		/* XXX Invalid environmental access */
391*31168Sminshall     } else if (regs->x.bx != 0x8020) {
392*31168Sminshall 	regs->h.ch = 0x12;
393*31168Sminshall 	regs->h.cl = 0x08;		/* XXX Invalid wait specified */
394*31168Sminshall     } else if (regs->h.ch != 0) {
395*31168Sminshall 	regs->h.ch = 0x12;
396*31168Sminshall 	regs->h.cl = 0x07;		/* XXX Invalid reply specified */
39731158Sminshall     } else {
39831158Sminshall 	switch (regs->x.dx) {
39931158Sminshall 	case GATE_SESSMGR:
40031158Sminshall 	    switch (regs->h.al) {
40131158Sminshall 	    case QUERY_SESSION_ID:
402*31168Sminshall 		if (regs->h.cl != 0) {
403*31168Sminshall 		} else {
404*31168Sminshall 		    query_session_id(regs, sregs);
405*31168Sminshall 		}
40631158Sminshall 		break;
40731158Sminshall 	    case QUERY_SESSION_PARMS:
408*31168Sminshall 		if (regs->h.cl != 0) {
409*31168Sminshall 		} else {
410*31168Sminshall 		    query_session_parms(regs, sregs);
411*31168Sminshall 		}
41231158Sminshall 		break;
41331158Sminshall 	    case QUERY_SESSION_CURSOR:
414*31168Sminshall 		if (regs->h.cl != 0xff) {
415*31168Sminshall 		} else {
416*31168Sminshall 		    query_session_cursor(regs, sregs);
417*31168Sminshall 		}
41831158Sminshall 		break;
41931158Sminshall 	    default:
42031158Sminshall 		unknown_op(regs, sregs);
42131158Sminshall 		break;
42231158Sminshall 	    }
42331158Sminshall 	    break;
42431158Sminshall 	case GATE_KEYBOARD:
425*31168Sminshall 	    if (regs->h.cl != 00) {
426*31168Sminshall 	    } else {
427*31168Sminshall 		switch (regs->h.al) {
428*31168Sminshall 		case CONNECT_TO_KEYBOARD:
429*31168Sminshall 		    connect_to_keyboard(regs, sregs);
430*31168Sminshall 		    break;
431*31168Sminshall 		case DISABLE_INPUT:
432*31168Sminshall 		    disable_input(regs, sregs);
433*31168Sminshall 		    break;
434*31168Sminshall 		case WRITE_KEYSTROKE:
435*31168Sminshall 		    write_keystroke(regs, sregs);
436*31168Sminshall 		    break;
437*31168Sminshall 		case ENABLE_INPUT:
438*31168Sminshall 		    enable_input(regs, sregs);
439*31168Sminshall 		    break;
440*31168Sminshall 		case DISCONNECT_FROM_KEYBOARD:
441*31168Sminshall 		    disconnect_from_keyboard(regs, sregs);
442*31168Sminshall 		    break;
443*31168Sminshall 		default:
444*31168Sminshall 		    unknown_op(regs, sregs);
445*31168Sminshall 		    break;
446*31168Sminshall 		}
44731158Sminshall 	    }
44831158Sminshall 	    break;
44931158Sminshall 	case GATE_COPY:
450*31168Sminshall 	    if (regs->h.cl != 0xff) {
451*31168Sminshall 	    } else {
452*31168Sminshall 		switch (regs->h.al) {
453*31168Sminshall 		case COPY_STRING:
454*31168Sminshall 		    copy_string(regs, sregs);
455*31168Sminshall 		    break;
456*31168Sminshall 		default:
457*31168Sminshall 		    unknown_op(regs, sregs);
458*31168Sminshall 		    break;
459*31168Sminshall 		}
46031158Sminshall 	    }
46131158Sminshall 	    break;
46231158Sminshall 	case GATE_OIAM:
463*31168Sminshall 	    if (regs->h.cl != 0xff) {
464*31168Sminshall 	    } else {
465*31168Sminshall 		switch (regs->h.al) {
466*31168Sminshall 		case READ_OIA_GROUP:
467*31168Sminshall 		    read_oia_group(regs, sregs);
468*31168Sminshall 		    break;
469*31168Sminshall 		default:
470*31168Sminshall 		    unknown_op(regs, sregs);
471*31168Sminshall 		    break;
472*31168Sminshall 		}
47331158Sminshall 	    }
47431158Sminshall 	    break;
47531158Sminshall 	default:
476*31168Sminshall 	    regs->h.ch = 0x12;
477*31168Sminshall 	    regs->h.cl = 0x34;		/* Invalid GATE entry */
47831158Sminshall 	    break;
47931158Sminshall 	}
48031158Sminshall     }
48131158Sminshall }
48231158Sminshall 
48331158Sminshall 
48431158Sminshall /*
48531158Sminshall  * Called from telnet.c to fork a lower command.com.  We
48631158Sminshall  * use the spint... routines so that we can pick up
48731158Sminshall  * interrupts generated by application programs.
48831158Sminshall  */
48931158Sminshall 
49031158Sminshall 
49131158Sminshall int
49231158Sminshall shell(argc,argv)
49331158Sminshall int	argc;
49431158Sminshall char	*argv[];
49531158Sminshall {
49631158Sminshall     Spint spinted;
497*31168Sminshall     char command[256];
49831158Sminshall 
49931158Sminshall     ClearElement(spinted);
50031158Sminshall     spinted.int_no = API_INTERRUPT_NUMBER;
50131158Sminshall     if (argc == 1) {
50231158Sminshall 	command[0] = 0;
50331158Sminshall     } else {
50431158Sminshall 	char *cmdptr;
50531158Sminshall 	int length;
50631158Sminshall 
50731158Sminshall 	argc--;
50831158Sminshall 	argv++;
50931158Sminshall 	strcpy(command, " /c");
51031158Sminshall 	cmdptr = command+strlen(command);
51131158Sminshall 	while (argc) {
51231158Sminshall 	    if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) {
51331158Sminshall 		fprintf(stderr, "Argument list too long at argument *%s*.\n",
51431158Sminshall 			    *argv);
51531158Sminshall 		return 0;
51631158Sminshall 	    }
51731158Sminshall 	    *cmdptr++ = ' ';		/* Blank separators */
51831158Sminshall 	    strcpy(cmdptr, *argv);
51931158Sminshall 	    cmdptr += strlen(cmdptr);
52031158Sminshall 	    argc--;
52131158Sminshall 	    argv++;
52231158Sminshall 	}
52331158Sminshall 	length = strlen(command)-1;
52431158Sminshall 	if (length < 0) {
52531158Sminshall 	    length = 0;
52631158Sminshall 	}
52731158Sminshall 	command[0] = length;
52831158Sminshall     }
52931158Sminshall 
53031158Sminshall     /*
53131158Sminshall      * spint_start() returns when either the command has finished, or when
53231158Sminshall      * the required interrupt comes in.  In the latter case, the appropriate
53331158Sminshall      * thing to do is to process the interrupt, and then return to
53431158Sminshall      * the interrupt issuer by calling spint_continue().
53531158Sminshall      */
53631158Sminshall     spint_start(command, &spinted);
53731158Sminshall     while (spinted.done == 0) {
53831158Sminshall 	/* Process request */
53931158Sminshall 	handle_api(&spinted.regs, &spinted.sregs);
54031158Sminshall 	spint_continue(&spinted);
54131158Sminshall     }
54231158Sminshall     if (spinted.rc != 0) {
54331158Sminshall 	fprintf(stderr, "Process generated a return code of 0x%x.\n",
54431158Sminshall 								spinted.rc);
54531158Sminshall     }
54631158Sminshall     return 0;
54731158Sminshall }
548