/* Updated on 03-May-89 at 5:54 PM by Creed A. Erickson; edit time: 1:06:08 */ /************************************************************************* ** * ** ERZ.C - Erstaz definitions display/edit utility. * ** * ************************************************************************** ** ** NOTICE ** ** COPYRIGHT (C) 1989 Professional Applied Computer Engineering, Inc. ** UNPUBLISHED -- ALL RIGHTS RESERVED. ** ** THIS PROGRAM IS CONFIDENTIAL AND TRADE SECRET OF PROFESSIONAL APPLIED ** COMPUTER ENGINEERING, INC. THE RECEIPT OR POSSESSION OF THIS PROGRAM DOES ** NOT CONVEY ANY RIGHTS TO REPRODUCE OR DISCLOSE ITS CONTENTS, OR TO ** MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN ** PART, WITHOUT THE SPECIFIC WRITTEN CONSENT OF PROFESSIONAL APPLIED ** COMPUTER ENGINEEERING, INC. ** ** Edit History: ** **[101] 05/03/89 Minor changes for release as ESP programming example. /CAE **[100] 04/14/89 Designed and implemented by Creed A. Erickson. ** ** ** What it is and what it does: ** ** ERZ is a utility for displaying and/or editing ersatz definitions on ** the system. The changes to the ersatz device table are made "real time" ** without having to reboot the system. Several ersatz devices may be ** changed at the same time. The program DOES NOT update the system ersatz ** initialization file(s) which define ersatz devices upon a system boot. ** ** What you need to run it: ** ** - ESP (run time or development pkg) or DART (which includes the former). ** - ERZ.LIT program. ** - ERZ.SCR screen file. ** ** If you want to manipulate the source code you need: ** ** - AlphaC compiler package (version 1.0B or later). ** - TBXC.H and TBXC.LIB ESP/TOOLBOX interface. ** - As written, source code is intended to compile using /NOINIT and ** the CNINIT.OBJ start-up code (I despise those silly .RTI files). ** ** How to work it: ** ** - From AMOS command level enter the command ERZ[ret]. ** - To page back and forth (assuming > 1 screen of ersatz devices), ** simply press NEXT-SCREEN or PREV-SCREEN. ** - To edit the current screen full of ersatz device definitions, press ** EDIT (F1 on most terminals). ** - If your user security has been defined to ESP as 254, you may also ** change the device names, as well as the definitions. ** - Once in edit mode, the changes made will take effect as soon as ** EXECUTE is pressed. ** - In edit mode, changes may be "abandoned" by pressing MENU. ** - The program is exited by pressing MENU from display mode. ** ** If you have problems: ** ** This utility is NOT downward compatible with earlier versions of ESP. ** If your version of ESP is 1.1(126) or less (as judged by the version of ** DSK0:SEDIT.LIT[1,4]) then you may need to upgrade before this utility ** will work. ** ** If you have any questions you may contact: ** ** Creed Erickson ** PACE, Inc. ** Post Office Box 278 ** Pleasanton, CA. 94566 ** (415) 462-2300 */ version "1.0(101),-1,PV$RSM!PV$RSM,PH$REE!PH$REU"; #include /* Standard AlphaC definitions. */ #include /* Standard ESP definitions. */ /************************************************************************* ** AMOS ersatz structures and typedefs. * ************************************************************************** */ typedef struct /* Ersatz table entry typedef. */ { rad50l nam; /* Ersatz device name. */ unsigned cpu; /* CPU id. */ rad50 dev; /* Device. */ unsigned short unt; /* Unit (or drive). */ rad50l fil; /* File name. */ rad50 ext; /* Extension. */ unsigned short ppn; /* PPN. */ } ERSATZ; /* Typedef named "ERSATZ". */ typedef ERSATZ *ERZPTR; /* Pointer to an ersatz entry. */ /************************************************************************* ** "#defined"'d constants and macro definitions. * ************************************************************************** */ #define LSTFLD 34 /* Last ersatz display field. */ #define DSPEDT 37 /* Display/Edit indicator fld. */ #define PAGNBR 38 /* "Page number" field. */ #define TOTPAG 39 /* Total # of pages field. */ #define EDTPRM 40 /* Edit mode prompt field. */ #define SCRMAX 17 /* Max # devices per page. */ #define ERSATZ_TABLE (syscom->ersatz) /* Where ersatz table starts. */ /************************************************************************* ** Global variable declarations. * ************************************************************************** */ ERZPTR ez; /* Pointer into ersatz table. */ pointer screen; /* Pointer to display/edit scr. */ int erzcnt; /* Number of ersatz devices. */ int scrcnt; /* Number of screens used. */ int curscr; /* Currently displayed screen # */ int keyhit; /* Display mode key pressed. */ int edtchr; /* Edit mode screen edit char. */ int edtfld; /* Edit mode screen field. */ ERZPTR where[SCRMAX]; /* Screen line to table xref. */ char erznam[10]; /* Ersatz name (ASCII). */ char defnam[70]; /* Ersatz definition (ASCII). */ char *msg[4]; /* Bottom line message pointers.*/ int msgidx; /* Idx to active bot. line msg. */ /*************************** ** main() * **************************** ** Program's main-line logic. ** */ void main() { /* Make sure that there are ersatz devices defined. */ if (nil == (ez = ERSATZ_TABLE)) /* If no ersatz devices... */ { printf("No ersatz defininition.\n"); /* Say none there. */ exit(); /* All done. */ } /* Count the number of ersatz devices. */ erzcnt = 0; /* Initialize count to none. */ while (ez->nam) /* While not at end of table. */ { erzcnt += 1; /* Increment the count. */ ez += 1; /* Increment the table pointer. */ } scrcnt = (erzcnt+SCRMAX-1)/SCRMAX; /* Calculate # of scrs to use. */ /* Miscellaneous initialization. */ msg[0] = "Press F1 to edit or MENU to exit"; msg[1] = "Press NEXT-SCREEN, PREV-SCREEN, F1 to edit, or MENU to exit "; msg[2] = "Press PREV-SCREEN, F1 to edit, or MENU to exit "; msg[3] = "Press NEXT-SCREEN, F1 to edit, or MENU to exit "; /* Fetch the display/edit screen form the disk. */ initrm("Ersatz Display/Edit Utility","Copyright (c) 1989 - P.A.C.E., Inc.", 0); screen = load_screen("DMSESP:ERZ.SCR");/* Get the screen file. */ opnscr(screen); /* Open screen for processing. */ hidfld(screen, EDTPRM); skpfld(screen, PAGNBR); /* Load up the fields for the first display. */ curscr = 1; /* Set the current screen. */ load_fields(curscr); /* Load up the fields. */ /* Get the fields displayed. */ while (keyhit != ESP_MENU) /* Until a MENU is pressed. */ { dspscr(screen); /* Display the screen. */ /* Setup the line 24 message index. */ if (scrcnt == 1) /* If only one screen... */ { msgidx = 0; /* Index F1 & MENU msg. */ } else { if ((curscr > 1) && (curscr < scrcnt)) /* If not 1st or last */ { msgidx = 1; /* Index NEXT, PREV, F1, MENU */ } else { if (curscr > 1) /* If not first screen. */ { msgidx = 2; /* Index PREV, F1, MENU msg. */ } else { msgidx = 3; /* Index NEXT, F1, MENU msg. */ } } } /* Display the indexed message. No ding, no acknowlegement, no blink. */ errdsp(msg[msgidx], ERRDSP_NDG|ERRDSP_NAK|ERRDSP_NBL); CUROFF; /* Turn the cursor back off. */ keyhit = gtchr(); /* Wait for user to press key. */ /* Perform action based on the key which was pressed. */ switch (keyhit) { /* If NEXT SCREEN pressed, go to the next display screen full. ** If no next screen is available then ding. */ case ESP_NXTSCREEN : { if (curscr < scrcnt) { load_fields(curscr += 1); } else { DING; } break; } /* End of case. */ /* If PREV SCREEN pressed, go to the previous display screen full. ** If no previous screen is available then ding. */ case ESP_PRVSCREEN : { if (curscr > 1) { load_fields(curscr -= 1); } else { DING; } break; } /* End of case. */ /* If F1 key pressed then go to edit mode. */ case ESP_F1 : { edit_ersatz(); } } /* End switch. */ } /* End of while loop. */ /* While loop has been exited, user must have pressed MENU. */ clsscr(screen); /* Close the screen. */ initrm(nil, nil, 0); /* Clear the display. */ CURON; /* Turn the cursor on. */ } /* --- end main() --- */ /*************************** ** load_fields() * **************************** ** Function to load the fields of the display/edit screen for a specified ** display page. ** ** Arguments/Dependencies: ** ** scrnbr := The display page (screen number) wich is to be loaded. ** ** Returned/Side effects: ** ** The display/edit screen is altered. ** The global array where[] is adjusted to reflect the ersatz table entries ** for each of the displayed ersatz devices. ** */ void load_fields(scrnbr) int scrnbr; /* Display page to load. */ { int i; /* Loop indexing variable. */ ERZPTR erz; /* Temp. ersatz table pointer. */ setbnm(screen, PAGNBR, scrnbr); /* Set page # */ setbnm(screen, TOTPAG, scrcnt); /* Set total pages count. */ clrfls(screen, 1, LSTFLD); /* Clear the screen fields. */ erz = ERSATZ_TABLE; /* Index start of ersatz table. */ scrnbr -= 1; /* Adjust page # to base 0. */ /* Index the proper point in the ersatz table for this display page. ** REMEMBER: Incrementing or decrementing a pointer always causes it ** to be adjusted according to the size of the object it points to. */ while (scrnbr) /* While not to page 0... */ { scrnbr -= 1; /* Decrement the page counter. */ erz += SCRMAX; /* Advance ersatz pointer. */ } /* Load the screen fields and adjust the where[] global array. */ for (i = 0; i < SCRMAX; i++) /* For all positions on screen. */ { if (erz->nam) /* If not at end of table... */ { where[i] = erz; /* Set table index for this one.*/ unpack_ersatz(erz, erznam, defnam); /* Unpack to ASCII. */ setstr(screen, (i*2)+1, erznam, sizeof(erznam)); /* Load name */ setstr(screen, (i*2)+2, defnam, sizeof(defnam)); /* Load def. */ shwfld(screen, (i*2)+1); shwfld(screen, (i*2)+2); erz += 1; /* Advance pointer. */ } else /* If at end of table.... */ { where[i] = nil; /* No index for this entry. */ hidfld(screen, (i*2)+1); hidfld(screen, (i*2)+2); } } /* End for loop. */ } /* --- end load_fields() --- */ /*************************** ** unpack_ersatz() * **************************** ** Function to unpack an ersatz table entry into an ASCII form. ** ** Arguments/Dependencies: ** ** eptr => erstaz table entry to unpack. ** enm => string buffer which will receive the ersatz device name. ** def => string buffer which will receive the expanded definition. ** ** Returned/Side effects: ** ** Upon return, strings *enm and *def contain the ASCII representation of ** the ersatz name and expanded definiition, respectivly. ** */ void unpack_ersatz(eptr, enm, def) ERZPTR eptr; char *enm, *def; { char *cptr; /* Working character pointer. */ rad50 *rptr; /* Working RAD50 pointer. */ *enm = *def = '\0'; /* Zap the passed strings. */ if (eptr->nam == 0) return(0); /* If no ersatz device, return. */ /* Unpack the ersatz device name into the name return buffer. */ rptr = &eptr->nam; /* Index the ersatz name. */ cptr = enm; /* Index the return buffer. */ unpack(&rptr, &cptr); /* Unpack the ersatz name. */ unpack(&rptr, &cptr); /* Both halves of it. */ while (*--cptr == ' ') ; /* Backup until non-space. */ cptr += 1; /* Advance to space char. */ *cptr++ = ':'; /* Replace it with a colon. */ *cptr = '\0'; /* Terminate the name. */ /* Unpack the ersatz defintion into the definition return buffer. */ cptr = def; /* Index the definition buffer. */ /* If there is a CPU ID associated with this ersatz definition ** then it gets unpacked first. */ if (eptr->cpu) /* If there is a CPU id... */ { dcvt(eptr->cpu, 0, _ot_mem, &cptr); /* Convert to decimal. */ *cptr++ = '-'; /* Add a trailing dash char. */ } /* Unpack the device and unit (if defined). */ if (eptr->dev) /* If there is a device... */ { rptr = &eptr->dev; /* Index the device spec. */ unpack(&rptr, &cptr); /* Unpack into buffer. */ while (*--cptr == ' '); /* Backup over trailing sp. */ cptr += 1; /* Point to 1st trailing sp. */ dcvt(eptr->unt, 0, _ot_mem, &cptr);/* Cvt unit nbr into buff. */ *cptr++ = ':'; /* Add colon terminator. */ } /* Unpack the file name associated with this definition (if any). */ if (eptr->fil) /* If there is a name... */ { rptr = &eptr->fil; /* Index the file name. */ unpack(&rptr, &cptr); /* Unpack into output buffer. */ unpack(&rptr, &cptr); /* Both halves of it. */ while (*--cptr == ' '); /* Backup over trailing space. */ cptr += 1; /* Point to 1st trailing space. */ } /* If the ersatz definition has an associated extension, buffer it. */ if (eptr->ext) /* If there is an extension... */ { *cptr++ = '.'; /* Leading period character. */ rptr = &eptr->ext; /* Index the extension. */ unpack(&rptr, &cptr); /* Unpack extension into buff. */ while (*--cptr == ' '); /* Backup over trailing space. */ cptr += 1; /* Index 1st trailing space. */ } /* Buffer PPN (if avail.) */ if (eptr->ppn) /* If there is a PPN... */ { *cptr++ = '['; /* Leading "[" character. */ ocvt(((eptr->ppn >> 8) & 255), 0, _ot_mem, &cptr); /* 1st part */ *cptr++ = ','; /* Comma separator. */ ocvt((eptr->ppn & 255), 0, _ot_mem, &cptr); /* 2nd part. */ *cptr++ = ']'; /* Conclude with "]" char. */ } *cptr = '\0'; /* Terminate the buffer. */ } /* --- end unpack_ersatz() --- */ /*************************** ** dspscr() * **************************** ** Function to display an ESP screen. All altered fields will be updated. ** ** Arguments/Dependencies: ** ** scr => pointer to the screen to be displayed. This screen is assumed ** to have already been opened via an opnscr() call. ** ** Returned/Side effects: ** ** Returns nothing. Passed screen is displayed/updated. ** */ void dspscr(scr) pointer scr; { int chr, fld; /* Temporary edit char, field. */ chr = ESP_MENU; /* Set edit char to MENU. */ fld = 1; /* Set edit field to field 1. */ gtscr(screen, &chr, &fld); /* Get the screen. */ } /* --- end dspscr() --- */ /*************************** ** pack_ersatz() * **************************** ** Function to pack an ersatz definition from ASCII string form into ersatz ** table form. ** ** Arguments/Dependencies: ** ** eptr => Type ERSATZ object which receives packed ersatz specification. ** enm => String buffer which holds ersatz device name to be packed. ** def => String buffer which holds ersatz definition to be packed. ** ** Returned/Side effects: ** ** Returns ddb error codes. ** Upon return, structure *eptr contains the packed definition. ** */ int pack_ersatz(eptr, enm, def) ERZPTR eptr; char *enm; char *def; { char *cptr; /* Temp character pointer. */ rad50 *rptr; /* Temp RAD50 pointer. */ ddb wrkddb; /* Temp DDB for FSPEC call. */ clear(*eptr); /* Preclear return structure. */ /* Pack the ersatz device name. */ rptr = &eptr->nam; /* Index ersatz name field. */ cptr = enm; /* index the ASCII name. */ pack(&cptr, &rptr); /* Pack the ersatz name. */ pack(&cptr, &rptr); /* Both halves of it. */ if (eptr->nam == 0) return(_d_espc);/* If no name then error. */ /* Pack the ersatz device definition. */ cptr = def; /* Index the device definition. */ byp(&cptr); /* Bypass leading white space. */ clear(wrkddb); /* Preclear the work DDB. */ fspec(&cptr, &wrkddb, \%%%\); /* Load DDB fields from string. */ if (wrkddb.ext == \%%%\) wrkddb.ext = 0; /* Adj. ext. if needed. */ if (wrkddb.err == 0) /* If no error... */ { eptr->cpu = wrkddb.cpu; /* Copy DDB flds to structure. */ eptr->dev = wrkddb.dev; /* Get the device. */ eptr->unt = wrkddb.drv; /* Get the unit (drive). */ eptr->fil = wrkddb.fil; /* Get the file name. */ eptr->ext = wrkddb.ext; /* Get the extension. */ eptr->ppn = wrkddb.ppn; /* Get the PPN. */ } return(wrkddb.err); /* Return DDB error code. */ } /* --- end pack_ersatz() --- */ /*************************** ** edit_ersatz() * **************************** ** Function to allow editing (changing) the current "page" of ersatz devices. ** ** Arguments/Dependencies: ** ** No arguments. Relies on screen being loaded with ersatz definitions. ** ** Returned/Side effects: ** ** The ersatz table entries indicated in the where[] array will be altered. ** */ void edit_ersatz() { ERSATZ edef; /* Temp table entry. */ int result; /* Temp result buf. */ int tstchr; /* Temp ESP edit character val. */ int i; /* Loop index. */ edtchr = ESP_BEGLIN; /* Initialize to ^U. */ edtfld = 1; /* Start editing at field 1. */ setpui(screen, DSPEDT, 2); /* Change disp/edit fld to EDIT */ shwfld(screen, EDTPRM); /* Enable edit mode prompt. */ for (;;) /* Loop for ever. */ { gtscr(screen, &edtchr, &edtfld); /* Edit the screen. */ tstchr = (edtchr & 255); /* Mask off character value.*/ if (tstchr == ESP_MENU) break; /* If MENU then stop loop. */ if (tstchr == ESP_EXECUTE) break; /* If EXEC then stop loop. */ } /* If loop was exited with EXECUTE keypress then update ersatz table. */ if (tstchr == ESP_EXECUTE) /* If EXECUTE pressed... */ { for(i = 0; i < SCRMAX; i++) /* For as many as are on scr. */ { getstr(screen, (i*2)+1, erznam, sizeof(erznam)); /* get name*/ getstr(screen, (i*2)+2, defnam, sizeof(defnam)); /* get def.*/ result = pack_ersatz(&edef, erznam, defnam); /* Pack. */ if (result == 0) /* If not error from pack.. */ { jlock(); /* Lock sys while fiddling. */ where[i]->nam = edef.nam; /* Copy the ersatz name. */ where[i]->cpu = edef.cpu; /* Copy the CPU id. */ where[i]->dev = edef.dev; /* Copy the device spec. */ where[i]->unt = edef.unt; /* Copy the unit (drive). */ where[i]->fil = edef.fil; /* Copy the file name. */ where[i]->ext = edef.ext; /* Copy the extension. */ where[i]->ppn = edef.ppn; /* Copy the PPN. */ junlok(); /* Release system lock. */ } /* Unpack the defintion and reload into screen. ** This insures that the screen is same as ersatz definition. */ unpack_ersatz(where[i], erznam, defnam); /* Unpack. */ setstr(screen, (i*2)+1, erznam, sizeof(erznam)); /* Load name.*/ setstr(screen, (i*2)+2, defnam, sizeof(defnam)); /* Load def.*/ } } else /* If not EXECUTE... */ { load_fields(curscr); /* Reload display fields. */ } setpui(screen, DSPEDT, 1); /* Reset disp/edit fld to disp. */ hidfld(screen, EDTPRM); /* Hide edit mode prompt fld. */ } /* --- end edit_ersatz() --- */ /* --- end of ERZ.C file --- */ .