/* 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 <STDIO.H> /* Standard AlphaC definitions. */
#include <TBXC.H> /* Standard ESP definitions. */
/*************************************************************************
** 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 definit
ion 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. */
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. */
}