1 SUB M11CHN & 2 !******************************************************************** & ! & ! M11CHN & ! & ! Initializes the system and puts up the first screens & ! (chained to after sorting) & ! & ! & !******************************************************************** & ! 3 ! Subprogram : M11CHN & ! Version : 00 21-Jan-82 & ! Programmer : John Montrym & ! Jean Fullerton & ! Releaser : & ! & ! 11 !-------------------------------------------------------------------- & ! & ! & ! C O P Y R I G H T & ! & ! & ! & ! (C) Copyright 1982 & ! Digital Equipment Corporation, Maynard, Massachusetts & ! & ! This software is furnished under a license for use only & ! on a single computer system and may be copied only with & ! the inclusion of the above copyright notice. This & ! software, or any other copies thereof, may not be pro- & ! vided or otherwise made available to any other person & ! except for use of such system and to one who agrees to & ! these license terms. Title to and ownership of the & ! software shall at all times remain in DIGITAL. & ! & ! The information in this software is subject to change & ! without notice and should not be construed as a commit- & ! ment by Digital Equipment Corporation. & ! & ! DIGITAL assumes no responsibility for the use or relia- & ! bility of its software on equipment that is not sup- & ! plied by DIGITAL. & ! 100 !-------------------------------------------------------------------- & ! & ! & ! Description & ! & ! & ! This subprogram performs the top-level tasks of the Smart Mailer & ! system, such as the welcome screen, and the main menu. & ! It also takes care of the Mailing List File name entry and loads & ! the system parameters into MAPPRM. & ! The argument INT.CODE% is used to instruct M11INT what to & ! do on entry. If INT.CODE% = 1% then we are being & ! called to start a session in Smart Mailer so we should put & ! up the welcome screen. If INT.CODE% = 2% then & ! we should skip the opening dialog and go straight to the & ! main menu. & ! & ! & ! M11INT returns with M11.FUNC$ set according to what was & ! typed, in response to the main menu: & ! & ! Desired function M11.FUNC$ & ! ---------------- --------- & ! & ! Update the mailing list U & ! Print (sub)list P & ! Display (sub)list D & ! Category maintenance C & ! Sublist maintenance S & ! & ! End Smart Mailer session E & ! & ! Go directly to "Add address" A & ! function within M11ACR. & ! & ! & ! & ! Calling module: SMAIL & ! & ! & ! Assumptions: & ! & ! * M11PAR.DAT is in the same account as SMAIL.TSK and it contains & ! the system parameters. & ! & ! System Dependent Functions: & ! & ! * determining the type of terminal & ! & ! * setting up the terminal for screen work & ! & ! * all code associated with file specs & ! & ! 250 !-------------------------------------------------------------------- & ! & ! Interface & ! & ! Common Areas: & ! & ! COMERR - Common area for error codes, tracebacks and messages & ! COMCON - System constants & ! COMVAR - System variables & ! & ! MAPMLF - MAP for the Mailing List File & ! MAPHDR - Area for the Mailing List File header record & ! MAPSEL - Area for the sublist selection & ! MAPSCR - Screen variables & ! MAPPRM - Area for system parameters & ! & ! Arguments: & ! & ! INT.CODE% - Flag to indicate whether to put up the initial & ! screen (1% = first time, 2% = subsequent time) & ! 300 !-------------------------------------------------------------------- & ! & ! Channel Assignments & ! & ! Channel Filename Map name Status at entry/exit & ! ------- ---------- -------- -------------------- & ! CH.KB% closed / open (mode 8) & ! CH.ADD% user-def MAPMLF closed / open & ! CH.PARM% M11PAR.DAT closed / closed & ! CH.SCR% M11SCR.DAT closed / open & ! 400 !******************************************************************** & ! & ! & ! Variables and Arrays & ! & ! & ! & ! ANS% User answer to Smart Mailer question (number) & ! ANS$ User answer to Smart Mailer question (string) & ! BASE% Offset for placement on the screen & ! DF$ Default answer & ! ERL Line where error occurred & ! ERR Set to error after error & ! F.END% Flag to indicate that the user typed 'END' or ^Z & ! HEADER.MISSING% Flag to inidicate that the Mailing List File header & ! if not there & ! I% loop variable & ! INT.CODE% M11INT argument & ! PROG.NUM% Programmer number & ! PROG.NUM$ Programmer number & ! PROJ.NUM% Project number & ! PROJ.NUM$ Project number & ! SLEN% Length of the Mailing List File header record & ! SWITCH.TO.VT52$ Command string to switch a VT100 to VT52 mode & ! T% Number to indicate the type of terminal & ! WORK$ Temporary work variable & ! 600 !******************************************************************** & ! & ! & ! Common Declarations & ! & ! & !******************************************************************** & 650 !******************************************************************** & ! & ! & ! Map Statements & ! & ! & !******************************************************************** & & 700 !-------------------------------------------------------------------- & ! & ! Subprograms & ! & ! & ! M11SCW Writes a line of text to the CRT & ! M11SCR Reads a line of text from the CRT & ! M11SCD Displays a screen full of text on the CRT & ! & ! 800 !-------------------------------------------------------------------- & ! & ! Subroutines & ! & ! & ! 11000 Reads in the printer parameters from the Parameter & ! File and transfers them to the parameter arrays & ! & ! 14800 Displays an informational message for the user & ! & ! 14900 Displays an error message and waits for the user & ! to acknowledge it & ! & !-------------------------------------------------------------------- & ! & ! Functions & ! & ! & ! 15100 FN.GET.DATA% Returns the value of the number on & ! the next data line in the parameter & ! file & ! & ! 15200 FN.GET.DATA$ Returns the string data from the & ! next line of the parameter file & ! & ! 15300 FN.TERM% Returns the type of terminal the user is & ! running from & ! & 1000 !******************************************************************** & ! & ! & ! S T A R T S U B P R O G R A M L O G I C & ! & ! & !******************************************************************** & 1010 ON ERROR GOTO 19000 & \ ERR.CALLNAM$ = ERR.PROGNAM$ ! Save the calling subprogram & \ ERR.PROGNAM$ = "M11CHN VER:00" ! Set up our name. & \ ERR.SUBNAM$ = "" & \ ERR.MSG$ = "Unexpected fatal error." & ! Set standard error trap. & ! Set up COMMON for error reporting. & 1400 !-------------------------------------------------------------------- & ! & ! Initialize System & ! & !-------------------------------------------------------------------- & 1405 WORK$ = SYS(CHR$(12%)) & \ ACT$ = '[' + NUM1$ (ASCII (MID(WORK$,6%,1%))) + ',' & + NUM1$ (ASCII (MID(WORK$,5%,1%))) + ']' & \ IF (ASCII (MID(WORK$,26%,1%)) AND 3%) = 0% & THEN DEV$ = "SY:" & ELSE DEV$ =MID(WORK$,23%,2%)+NUM1$(ASCII(MID(WORK$,25%,1%)))+':' & ! Get the device and account where this program (.TSK file) is. & ! The M11PAR.DAT file should be on the same device and account. & 1406 M11.TSK.ACCT$ = DEV$ + ACT$ & ! Set up the account of the Mail11 task file. & & 1410 ESC$ = CHR$(155%) & \ HOME.UP$ = ESC$ + "H" & \ ERASE.EOS$ = ESC$ + "J" & \ ERASE.EOL$ = ESC$ + "K" & & \ HDR.CHR$ = CHR$ (29%) ! first header record char. & \ SUB.CHR$ = CHR$ (30%) ! first sublist record char. & \ DELIM$ = CHR$ (31%) ! ASCII unit separator char. & ! used as address field delim & \ CNTRL.Z% = 11% ! ASCII value for control Z & \ CNTRL.C% = 28% ! ASCII value for control C & & \ EXIT.M11% = 2% ! Code to exit from Mail-11 & \ MAIN.MENU% = 1% ! Code to return to main menu & \ OK% = 0% ! Code for no errors & \ FATAL.ERROR% = -1% ! Code for a fatal error & \ WARN% = -2% ! Code for a non-fatal error & & \ TRUE% = -1% ! Logical true value & \ FALSE% = 0% ! Logical false value & & \ TEMP% = 1% ! Temporary sublist code & \ PERM% = 2% ! Permenant sublist code & & \ MAX.LINES% = 30% ! Max lines in sublist def & & \ CH.KB% = 1% & \ CH.PARM% = 2% & \ CH.SCR% = 2% & \ CH.ADD% = 3% & \ CH.SORTED% = 4% & \ CH.SORT% = 5% & \ CH.INDEX% = 6% & \ CH.PRT% = 9% & & \ SWITCH.TO.VT52$ = CHR$(155%) + "[?2l" & & ! Define some constants. & & 1460 OPEN "KB:" AS FILE #CH.KB%, MODE 8% & ! Finally, reopen keyboard in simulated block mode. & & 1470 !-------------------------------------------------------------------- & ! & ! Get Core Common information & ! & !-------------------------------------------------------------------- & 1475 WORK$ = SYS (CHR$(7%)) & \ M11.MAIL.FILE$ = SEG$ (WORK$, 1%, 30%) & \ M11.SORTED.FILE$ = SEG$ (WORK$, 31%, 60%) & \ PRT.FILE$ = SEG$ (WORK$, 61%, 90%) & \ M11.SORT.CODE$ = SEG$ (WORK$, 91%, 93%) & \ M11.SUBLIST.NAME$ = SEG$ (WORK$, 94%, 103%) & \ M11.LIST.CODE$ = SEG$ (WORK$, 104%, 104%) & \ M11.OUTPUT.FORM$ = SEG$ (WORK$, 105%, 105%) & \ PRT.DEV$ = SEG$ (WORK$, 106%, 109%) & \ PRT.DEVICE.ANS$ = SEG$ (WORK$, 110%, 112%) & \ print #ch.kb%,"chained to M11CHN" & \ print #ch.kb%,m11.mail.file$, m11.sorted.file$, prt.file$, & m11.sort.code$, & \ sleep 5% & ! Extract passed values from core common. & 1480 M11.FUNC$ = "P" & \ M11.SUBLIST.CODE% = 0% & \ M11.LAST.LINE% = 0% & \ M11.FIELD.WAS.CNVTD% = FALSE% & \ M11.PRESORT% = FALSE% & \ M11.PRESORT% = TRUE% IF SEG$(M11.SORT.CODE$,1%,2%) = "PR" & \ SEL.ALL$ = "" & ! Reset some predicatable variable values. & 1485 PRT.QUE.STRING$ = & CHR$(6%) ! FIP - File Processor & + CHR$(-28%) ! Spooling request code & + STRING$ (2%, 0%) ! not used & + STRING$ (2%, 0%) ! use current user account & + SEG$ (FSS$ (PRT.FILE$, 1%), 7%, 12%) & + PRT.DEV$ ! spool to requested device & + STRING$ (2%, 0%) ! reserved, must be zero & + CHR$(4%) ! delete file when thru & + STRING$ (2%, 0%) ! reserved, must be zero & + STRING$ (8%, 0%) & ! Build string used in que file SYS call. & 1500 !-------------------------------------------------------------------- & ! & ! Read in System Parameters & ! & !-------------------------------------------------------------------- & 1510 OPEN M11.TSK.ACCT$ + "M11PAR.DAT" FOR INPUT AS FILE #CH.PARM% & ! Open system Parameter File. & 1600 PRM.SCREEN.FILE$ = FN.GET.DATA$ & \ PRM.LOC.WORK.FILES$ = FN.GET.DATA$ & & \ PRM.LABEL.TST$ = FN.GET.DATA$ & \ PRM.LABEL.PID$ = FN.GET.DATA$ & \ PRM.LABEL.MSG$ = FN.GET.DATA$ & \ PRM.LABEL.IDR$ = FN.GET.DATA$ & \ PRM.LABEL.NUM% = FN.GET.DATA% & \ PRM.LABEL.COP% = FN.GET.DATA% & \ PRM.LABEL.LAB% = FN.GET.DATA% & \ PRM.LABEL.MAR% = FN.GET.DATA% & \ PRM.LABEL.CHR% = FN.GET.DATA% & \ PRM.LABEL.HOR% = FN.GET.DATA% & \ PRM.LABEL.LIN% = FN.GET.DATA% & \ PRM.LABEL.VER% = FN.GET.DATA% & & \ GO SUB 11000 & \ GO TO 32767 IF ERR.CODE% <> 0% & ! Read in printer parameters. & & ! Load up all the data from the Parameter File. & 1690 CLOSE #CH.PARM% & ! Close the system Parameter File. & & 1700 !-------------------------------------------------------------------- & ! & ! & ! Determine User's Privilege & ! & ! & !-------------------------------------------------------------------- & 698 MAP (OVR) PROJ.NUM$ = 1%, FILL$ = 1% & ,PROG.NUM$ = 1%, FILL$ = 1% & \ MAP (OVR) PROJ.NUM% & ,PROG.NUM% & 1720 WORK$ = SYS (CHR$( 6%) ! FIP - File Processor & + CHR$(26%) ! request return job status & + CHR$( 0%) ! info on current user's job & + CHR$( 0%) ! S code & + STRING$ (26%, 0%)) ! the rest is null & ! Get current job status. & ! RSTS SYS Call - see RSTS Programming Manual, section 7.2.24. & 1740 PROJ.NUM% = 0% & \ PROJ.NUM$ = SEG$ (WORK$, 22%, 22%) & \ PROG.NUM% = 0% & \ PROG.NUM$ = SEG$ (WORK$, 21%, 21%) & \ M11.USER.ACCT$ = "[" + NUM1$(PROJ.NUM%) +"," +NUM1$(PROG.NUM%) +"]" & \ IF PROJ.NUM% = 1% THEN M11.USER.PRIV% = TRUE% & ELSE M11.USER.PRIV% = FALSE% & ! Determine if this user is privileged. & & 1800 !-------------------------------------------------------------------- & ! & ! & ! Initialize & ! & ! & !-------------------------------------------------------------------- & 1810 SCR.NUMBER%(I%) = I% * 3% + 1% FOR I% = 0% TO 42% & ! Set up relative screen numbers. & 2000 !-------------------------------------------------------------------- & ! & ! & ! Open Screen File & ! & ! & !-------------------------------------------------------------------- & 2020 OPEN PRM.SCREEN.FILE$ FOR INPUT AS FILE #CH.SCR% & ,ORGANIZATION RELATIVE FIXED & ,RECORDSIZE 510% & ,ACCESS READ & ,ALLOW READ & 3000 !-------------------------------------------------------------------- & ! & ! & ! Open Mail File & ! & ! & !-------------------------------------------------------------------- & & 3100 WORK$ = FN.DROP.PRIV$ & \ OPEN M11.MAIL.FILE$ FOR INPUT AS FILE #CH.ADD% & ,ORGANIZATION INDEXED VARIABLE & ,ACCESS MODIFY & ,ALLOW MODIFY & ,BUCKETSIZE 2% & ,RECORDSIZE 350% & ,MAP MAPMLF & ,PRIMARY KEY MLF.KEY0$ NODUPLICATES & ,ALTERNATE KEY MLF.KEY1$ DUPLICATES CHANGES & \ GET #CH.ADD%, KEY #0% EQ HDR.CHR$ + "000000000000001" & \ MOVE FROM #CH.ADD%, HDR.ALL$ = RECOUNT & \ WORK$ = FN.REGAIN.PRIV$ & ! Temporarily drop privilege to deny access of files to non- & ! privileged users. & ! Try to open the input file. If file does not exist, error & ! traps to 4300. If file exists, but the header record doesn't, & ! error traps to 4300 with HEADER.MISSING% set. & ! Any other file error traps to 4200 -- illegal file. & ! If we do open the file, get the header record & ! & load up the parameters. Regain privilege. & 9000 !******************************************************************** & ! & ! & ! E N D O F P R O C E S S I N G & ! & ! & !******************************************************************** & 9100 ERR.PROGNAM$ = ERR.CALLNAM$ & \ ERR.SUBNAM$ = "" & ! Restore the caller's name as the current program. & & 9900 GOTO 32767 & ! Go to the end of the subprogram. & 10000 !******************************************************************** & ! & ! & ! S U B R O U T I N E S L O C A L T O & ! & ! T H I S S U B P R O G R A M & ! & ! & !******************************************************************** 11000 ! & ! Load the printer parameter arrays & ! & ! input: (from M11PAR.DAT) & ! & ! output: PRM.PRT.- & ! & ! local: COLON% position of the colon in the printer string & ! COMMA position of a comma in the printer string & ! J% loop index & ! J$ string representation of loop index & ! K% loop index & ! NAME$ printer name & ! PRINTER$ printer parameter string from parameter file & ! START% position variable & !-------------------------------------------------------------------- & & 11100 FOR J% = 0% TO 4% ! For each possible printer & & \ J$ = STR$ (J%+1%) & \ PRINTER$ = FN.GET.DATA$ & ! Get printer parameter line from Parameter File. & & 11400 ERR.MSG$ = "First printer must be an actual device." & \ IF SEG$ (PRINTER$, 1%, 2%) = "NL" & OR SEG$ (PRINTER$, 1%, 2%) = "nl" & THEN PRM.PRT.DEV$(J%) = "NL:" & \ IF J% = 0% THEN GO TO 11900 & ELSE GO TO 11700 & ! Pass any null devices, unless it is the first one. & ! In that case, it is an error. & 11420 ERR.MSG$ = "Too few printer parameters on line" & \ START% = 1% & \ FOR K% = 1% TO 4% & \ COMMA% = POS (PRINTER$, ",", START%) & \ GO TO 11900 IF COMMA% = 0% & \ START% = COMMA% + 1% & \ NEXT K% & ! Check for 4 commas (i.e., all 5 parameters) & 11440 NAME$ = SEG$ (PRINTER$, START%, LEN (PRINTER$)) & \ NAME$ = EDIT$ (NAME$, 12%) & \ NAME$ = "Printing device " + J$ IF LEN (NAME$) = 0% & \ PRM.PRT.NAM$(J%) = NAME$ & ! Extract the name of the printer from the end of the line. & ! Give it a default name if the name is null. & 11500 PRINTER$ = EDIT$ (PRINTER$, 38%) & ! Compress the rest of the line, and change to upper case. & 11520 ERR.MSG$ = "Invalid device for printer " + J$ & \ COMMA% = POS (PRINTER$, ",", 1%) & \ COLON% = COMMA% - 1% & \ GO TO 11900 IF COMMA% < 4% & \ GO TO 11900 IF SEG$ (PRINTER$, COLON%, COLON%) <> ":" & \ PRM.PRT.DEV$(J%) = SEG$ (PRINTER$, 1%, COLON%) & ! Check and then extract the printer device name. & 11540 ERR.MSG$ = "Invalid printer queable code, must be Q or N" & \ START% = COMMA% + 1% & \ COMMA% = POS (PRINTER$, ",", START%) & \ GO TO 11900 IF COMMA% = START% & \ PRM.PRT.COD$(J%) = SEG$ (PRINTER$, START%, COMMA%-1%) & \ GO TO 11900 IF PRM.PRT.COD$(J%) <> "Q" & AND PRM.PRT.COD$(J%) <> "N" & ! Extract and check the printer queable code. & 11560 ERR.MSG$ = "Invalid printer line length, must be 80 - 132" & \ START% = COMMA% + 1% & \ COMMA% = POS (PRINTER$, ",", START%) & \ GO TO 11900 IF COMMA% = START% & \ PRM.PRT.LEN%(J%) = VAL (SEG$ (PRINTER$, START%, COMMA%-1%)) & \ GO TO 11900 IF PRM.PRT.LEN%(J%) < 80% & OR PRM.PRT.LEN%(J%) > 132% & ! Extract and check the printer line length. & 11580 ERR.MSG$ = "Invalid printer type, must be F or V" & \ START% = COMMA% + 1% & \ COMMA% = POS (PRINTER$, ",", START%) & \ GO TO 11900 IF COMMA% = START% & \ PRM.PRT.TYP$(J%) = SEG$ (PRINTER$, START%, COMMA%-1%) & \ GO TO 11900 IF PRM.PRT.TYP$(J%) <> "F" & AND PRM.PRT.TYP$(J%) <> "V" & ! Extract and check the printer type. & 11700 NEXT J% & ! Do next printer. & 11800 ERR.MSG$ = "" & \ RETURN & & 11900 ERR.CODE% = FATAL.ERROR% & \ RETURN & ! Something is wrong with the printer parameters, tell user and stop. & & 15000 !******************************************************************** & ! & ! & ! F U N C T I O N S L O C A L T O & ! & ! T H I S S U B P R O G R A M & ! & ! & !******************************************************************** & & 15100 !******************************************************************** & ! & ! & ! FN.GET.DATA% & ! & ! Gets numeric data item from next line of input & ! parameter file. & ! & ! & !******************************************************************** & 15110 DEF FN.GET.DATA% & 15115 INPUT LINE #CH.PARM%, WORK$ & \ COMMENT% = POS (WORK$, "!", 1%) & \ IF COMMENT% > 0% THEN WORK$ = SEG$ (WORK$, 1%, COMMENT%-1%) & ! Strip away the comment, if any. & 15120 WORK$ = EDIT$ (WORK$, -1%) & ! Remove extraneous characters. & 15130 FN.GET.DATA% = VAL (WORK$) & \ FNEND & ! Set the numeric value of our function, return. & & 15200 !******************************************************************** & ! & ! & ! FN.GET.DATA$ & ! & ! Gets data string from next line of input file & ! & ! & !******************************************************************** & 15210 DEF FN.GET.DATA$ & 15215 INPUT LINE #CH.PARM%, WORK$ & \ COMMENT% = POS (WORK$, "!", 1%) & \ IF COMMENT% > 0% THEN WORK$ = SEG$ (WORK$, 1%, COMMENT% -1%) & ! Strip away the comment, if any. & 15220 WORK$ = EDIT$ (WORK$, 141%) & ! Remove leading and trailing space/tabs, remove extraneous char.s & 15230 FN.GET.DATA$ = WORK$ & \ FNEND & ! Set the string value of our function, return. & & 19000 !******************************************************************** & ! & ! & ! S T A N D A R D E R R O R H A N D L I N G & ! & ! & !******************************************************************** & 19010 GO TO 19990 IF ERN$ <> SEG$ (ERR.PROGNAM$,1%,6%) & ! Only tracing back an error from another subprogram. & 19100 RESUME 11900 IF ERL = 11560 & ! Handle anticipated errors. & 19800 ERR.MSG$ = "Unexpected fatal error" & \ ERR.MSG$ = "Problem accessing the Screen File (not there?)" & IF ERL = 2020 & \ ERR.MSG$ = "Problem reading Parameter File (wrong order?)" & IF ERL = 15130 & \ ERR.MSG$ = "System files have the wrong protection code." & IF ERR = 10 & \ ERR.MSG$ = "Problem re-opening Mail File after sort" & IF ERL = 3100 & ! Define error messages for known (but unexpected) errors. & & 19850 ERR.ERL% = ERL & \ ERR.ERR% = ERR & \ ERR.CODE% = FATAL.ERROR% & ! On fatal error, set the error code. & 19990 ON ERROR GO BACK & ! Return to calling program for fatal error processing. & 32766 !******************************************************************** & ! & ! E N D O F S U B - P R O G R A M & ! & !******************************************************************** & 32767 SUBEND