/* P/390 VM/ESA Source disk Installation program            7/07/95 JAH         */
/*                                                                              */
/*  1. Copy programs from optical disk to hard drive                            */
/*  2. Update \VMSRC DEVMAP to installed-on drive                               */
/*                                                                              */
/*                                                                              */
trace o
"@ECHO OFF"

title = 'VM/ESA Source disks'
include = '\VMSRC'     /* Search this source subdirectory */

Parse upper arg x .
If x = '?' then do
Say 'Correct Form is:'
Say '                 INSTSRC [s: [d:]]'
Say ''
Say 'Use this program to install the VM/ESA source maintenance minidisks from'
Say 'the optical disk onto your hard disk. If you do not specify parameters,'
Say 'then you will be prompted for source and destination drive letters.'
Say ''
Say ''
   Exit
   End

/* Load REXXUTIL */
call rxfuncadd sysloadfuncs, rexxutil, sysloadfuncs
call sysloadfuncs
Parse Source . . sletter ':' .

"MODE CO80 32"
Call SysCls
Say ''; Say title 'Installation';
Say '--------------------------------'
parse upper arg fletter tletter .
If tletter = '' then do
   Say ''; Say 'To continue with installation press Y';
   Say '(any other key to EXIT).';
   parse upper value SysGetKey('NOECHO') with key
   If key<>'Y' Then Exit 1
   End;

/*--------------------------------------------------------------------*/
/* Check for a drive letter(s) passed as parameter to INSTALL         */
/*--------------------------------------------------------------------*/
   parse upper arg fletter tletter .   /* from drive, to drive */
   parse var fletter fletter ':' .  /* strip off : if provided */
   parse var tletter tletter ':' .

If fletter='' then do
   Say '';
   Say 'What disk drive contains the' title'?';
   Say 'Type in the letter of the source disk (default = 'sletter').';
   parse upper value SysGetKey('NOECHO') with key
   If key='0D'x Then fletter=sletter;
                Else fletter=key;
   end

If tletter='' then do
   Say '';
   Say 'Where do you want to install the' title'?';
   Say 'Type in the letter of the destination disk (default = D).';
   parse upper value SysGetKey('NOECHO') with key
   If key='0D'x Then Do
                    tpath='D:'include;
                    tletter='D';
                    end;
                Else Do
                    tpath=key':'include;
                    tletter=key;
                    end;
   end
Else tpath=tletter':'include;

/* Make sure the drive letters are a single, uppercase alphabetic */
If (length(fletter)<>1 | Datatype(fletter,'U')<>1),
   |(length(tletter)<>1 | Datatype(tletter,'U')<>1) Then do
   Say ''
   Say "Invalid parameters: '"fletter tletter"'. They must be valid OS/2 drive letters."
   Say '*** No' title 'installed ***'
   Exit 1;
   End;

fpath = fletter':'include
Log   = tletter':\VM.LOG'
temp  = tletter':\AWSDEV.LOC'
slist = tletter':\VMSRC.SIZ' /* Directory list of files that comprise the product */
cmsg  = tletter':\VMSRC.MSG' /* Output file for messages from XCOPY & PKUNZIP2 */
complete=0  /* non-zero if any files were copied */
Dev_Mod=0   /* non-zero if any DEVMAP DASD records were updated */
Error=0     /* non-zero if any errors */

/*--------------------------------------------------------------------*/
/* Check to see if the product has already been installed             */
/*--------------------------------------------------------------------*/
replace = 0
ee = stream(tpath||include'.PAC','C','QUERY EXISTS')
If ee <> '' then Do
   Say '';
   Say '************************** WARNING **************************'
   msg=title 'are already installed on' tpath'\'
   Say msg; x=Lineout(Log,msg); x=Lineout(Log);
   Say 'If you want to REPLACE the existing files then type "Y".'
   Say 'If you want to exit the' title 'install then type "N".'
   Do until key = 'Y' | key = 'N'
      parse upper value SysGetKey('NOECHO') with key
      End; /* wait for a Yes or No */
   If key = 'N' then Signal exit
   replace = 1   /* means we are replacing existing files */
   End;

/*--------------------------------------------------------------------*/
/*  Check source disk                                                 */
/*--------------------------------------------------------------------*/
d1=0
Disk_1:
finfo = SysDriveInfo(fletter':')
Parse var finfo . . . label
/*          R/W Optical           JohnA's CD            Applic dev CD */
If label = 'P390VMSRC' | label = 'P390VMESACD' | label = 'P390VMADCD'
Then flabel=label     /* This tells us whether it is a R/W optical or CD-ROM   */
Else do
   If d1=0 then do
     Say ''
     Say 'Insert the CD-ROM containing the' title 'into drive' fletter'.';
     Say 'and press ENTER to copy programs (any other key to EXIT).';
     end
   Else do
     Call Beep 600,250
     Say ''
     Say 'Incorrect CD-ROM inserted.  Please verify that the disk containing '
     Say  'the' title 'is in drive' fletter'.'
     Say 'Then press ENTER (any other key to EXIT).';
     end

   parse upper value SysGetKey('NOECHO') with key
   If key<>'0D'x Then Signal NodiskF

   d1=1
   Signal Disk_1
   End; /* incorrect disk */

/*--------------------------------------------------------------------*/
/* Check to see if a default DEVMAP has been set                      */
/*--------------------------------------------------------------------*/
z=SysSearchPath('PATH','AWSPROF.EXE')
If z = '' then do
   Say 'Required program AWSPROF.EXE missing. Did you install the'
   Say 'P/390 programs, modify CONFIG.SYS and reboot the PC?.'
   Exit 1
   End;

'awsprof /q >' temp
If rc <> 0 then exit rc  /* RC = 1 if drive is write protected */
idev=linein(temp);
x=Lineout(temp);
If idev='' then do;
        say 'There is a problem with the destination drive' tletter':'
        say 'Check if the disk is full.'
        Exit 1
        end
rc=SysFileDelete(temp)
If idev='(Not Found)'
   then do;
        say 'A default location for the DEVMAP.1VM configuration file has not'
        say 'been established.  You MUST run the INSTALL program from the VM/ESA'
        say 'Starter System CD-ROM before installing' title'.  If you'
        say 'have already done this, then use AWSPROF to set a default DEVMAP.'
        Exit 2
        End;
Parse var idev name '.' ext
sav_dev = SysTempFileName(name'.0??')

Numeric Digits 16  /* Allows whole numbers up to 16 digits */
/*--------------------------------------------------------------------*/
/* Check free space on the destination disk                           */
/*--------------------------------------------------------------------*/
tinfo = SysDriveInfo(tletter':')
If tinfo = '' then Signal NodiskT
Parse var tinfo . tfree . .

/*--------------------------------------------------------------------*/
/* Check how much space is needed for a complete install              */
/*--------------------------------------------------------------------*/
"DIR /N" fpath  ">" slist
If rc <> 0 then do
   Say 'There are no' title 'on disk' fletter':'
   Exit 3
   End;

total = 0; copy = '';
Do While Lines(slist)
   size = 0
   w = Linein(slist)   /* Read a line from the DIR results */
   If Pos('-',w)=3 & Lastpos('-',w)=6 then do  /* looks like a file line */
      Parse upper var w date time size attr name .
      If Datatype(size,'W')=1 then nop  /* Yes, a real file */
         Else Iterate  /* Not a file line */
      Parse var name fn '.' ext .
      If ext = 'ZIP' then call QZIP  /* process PKZIP files */
      copy = fpath'\'name copy  /*  Make a list of files to be copied */
      total = total + size
      End;
   End; /* lines */

Call Stream slist,'C','CLOSE'
rc=SysFileDelete(slist)

/* Start the message log entry */
msg='0D0A'x||'===== INSTSRC started' Date() Time() '======================================'
x=Lineout(Log,msg); x=Lineout(Log);

If tfree < total then Signal Nospace1

/*--------------------------------------------------------------------*/
/* Copy the VM Source disk files and update DEVMAP                    */
/*--------------------------------------------------------------------*/

Say ''
msg='COPYING' title 'from 'fletter': to' tletter': ...';
Say msg; x=Lineout(Log,msg); x=Lineout(Log);

copycnt= Words(copy)
Do k=1 to copycnt
   filename = Word(copy,k)
   If Right(filename,3) = 'ZIP' Then Do
      Say 'Unzipping' filename
      fletter":\PKUNZIP2 -o -d" filename tpath"\  > " cmsg
      If rc <> 0 then Do
         Say '** ERROR unzipping' filename'. Check' log ' for messages.'
         msg='** ERROR unzipping' filename'. See "(xnn)" messages, below.'
         x=Lineout(Log,msg); x=Lineout(Log);
         error = error+1
         End; /* error */
      End; /* Unzip file */
   Else Do
      Say 'Copying' filename
     "XCOPY"  filename tpath"\  > " cmsg
      If rc <> 0 then Do
         Say '** ERROR copying  ' filename'. See "SYSnnn" message displayed above.'
         msg='** ERROR copying  ' filename'. See "SYSnnn" message that was displayed on the console.'
         x=Lineout(Log,msg); x=Lineout(Log);
         error = error+1
         End; /* error */
      End; /* Xcopy file */
   "COPY" Log"+"cmsg Log">NUL:" /* append messages to Log */
   End; /* k */

msg='Copy of' title 'is complete.'
Say msg; x=Lineout(Log,msg); x=Lineout(Log);
rc=SysFileDelete(cmsg)

/*                                                                    */
/* Update DEVMAP drive and path entries                               */
/*                                                                    */
/* The DEVMAP on the CD-ROM will have D:\VMSRC\ as the default path and drive */
/* We will update them to the destination drive letter.                                */
/*                                                                                     */
"COPY" idev sav_dev ">NUL:"

msg='Updating all' 'D:'include'\' 'DASD entries in current DEVMAP to' tpath
x=Lineout(Log,msg); x=Lineout(Log);
old = 'D:'include'\'
new = tpath'\'

Call UpDev

Dev_mod=totalm           /* Save how many DEVMAP entries were altered */
complete=complete+1      /* non-zero if we have completed this step   */


/*--------------------------------------------------------------------*/
/*  E X I T  code                                                     */
/*--------------------------------------------------------------------*/
Exit:
If complete > 0 then do  /* Only say if we have actually done something */
   Say ''
   If error<>0 then Do
      msg=title 'installation is complete, but errors occurred.'
      Say msg; x=Lineout(Log,msg); x=Lineout(Log);
      Say '-----------------------------------------------------------------'
      Say 'Check install log' log'.'
      End
   Else Do
      msg=title 'installation is complete.'
      Say msg; x=Lineout(Log,msg); x=Lineout(Log);
      Say '---------------------------------------------'
      End
   If Dev_mod > 0 then do /* Only say if DEVMAP has been modified */
      Say ''
      msg='Your original DEVMAP file "'idev'"';
      Say msg; x=Lineout(Log,msg); x=Lineout(Log);
      msg='has been saved in "'sav_dev'"';
      Say msg; x=Lineout(Log,msg); x=Lineout(Log);
      Say 'You can view a record of this install in' Log;
      End;
   Else rc=SysFileDelete(sav_dev) /* DEVMAP was not modified */
End;


Say ''
Say 'If you wish to install any' title 'in the future,'
Say 'insert the appropriate disk and type: 'sletter':INSTSRC 'fletter': 'tletter':'
Say '(or supply any other source and destinations drive letters).'

Exit 0

/*------**********************----------------------------------------*/
/*----- S U B R O U T I N E S ----------------------------------------*/
/*------**********************----------------------------------------*/
QZIP:
/*--------------------------------------------------------------------*/
/* Determine the uncompressed size of a PKZIP file                    */
/*--------------------------------------------------------------------*/
/*  "UNZIP32 -Zt name.ext" gives the following line:

nn files, xxxxxxxx bytes uncompressed, yyyyyy bytes compressed: nn.n%

This routine redirects this "view" output to a file and then parses
the line to extract the xxxxxxxx number of uncompressed bytes.
*/

zlist = tletter":\PKZ.SIZ" /* captured output from unzip32 */
fletter":\UNZIP32 -Zt" fpath"\"name ">" zlist
If rc = 0 then do
   dfound = 0               /* Size found?  */
   Do While Lines(zlist)
      z = Linein(zlist)
      Parse var z . . size .
      size = Strip(size)  /* Just the digits of the size */
      End; /* search all lines */
   Call Stream zlist,'C','CLOSE'
   rc=SysFileDelete(zlist)
   If Datatype(size,'W') = 0 then do
      msg='** ERROR: size for' fpath'\'name ' could not be determined.'
      Say msg; x=Lineout(Log,msg); x=Lineout(Log); /* Log message */
      error = error+1
      End;
   End;
Else do
   msg='** ERROR: size for' fpath'\'name ' could not be determined.'
   Say msg; x=Lineout(Log,msg); x=Lineout(Log); /* Log message */
   error = error+1
   End;

Return;
/*====================================================================*/

UpDEV:
/*------------------------------------------------------------------*/
/* Update DEVMAP file 'idev' with destination drive letter          */
/* Input: idev = x:\path\devmap.1vm                                 */
/*        old  = y:\oldpath\                                        */
/*        new  = z:\newpath\                                        */
/*------------------------------------------------------------------*/
If stream(idev,'C','QUERY EXISTS') = '' then do
   msg='** ERROR:' idev' file was not found. Did you run VM/ESA INSTALL?'
   Say msg; x=Lineout(Log,msg); x=Lineout(Log); /* Log message */
   Say 'If this error persists, call for service.'
   Exit 1
   end
Parse var idev name '.' ext

odev=name'.TMP'         /* temporary work file   */
rc=SysFileDelete(odev)  /* Erase it if it exists */

dasdlist='3370 3310 0671 9332 9335 9336 FB-5 3375 3380'
totalm=0 /* Count of DASD records modified */

/*                                                               */
/* Search DEVMAP and replace 'old' with 'new' DASD paths         */
/*                                                               */
Do j=0 to 400;
z=charin(idev,1+j*64,64);            /* read a line from devmap */
If length(z)=0 then leave;             /* ..exit if we are done   */

/* If this is a DASD record, then change the disk drive letter  */
   If Wordpos(substr(z,3,4),dasdlist) <> 0 then
   Do;
   If substr(z,19,1)='*'              /* if it's commented out    */
      then nstart=20                  /* the drive letter is here */
      Else nstart=19                  /* otherwise, it's here     */
   zz=Substr(z,nstart)
   Lrec=Length(Filespec('D',zz)||Filespec('P',zz))
/* Found a match  */
   If Substr(zz,1,Lrec) = old then do
      Lold=Length(old); Lnew=Length(new);
      If Lold=Lnew
      Then do  /* Same length */
         z=overlay(new,z,nstart,Lnew)
         totalm=totalm+1
         end;
      Else do /* Different length */
         /* Find the end of the name (excluding blanks & nulls) */
         eblank=Pos(' ',zz)
         enull=Pos('00'x,zz)
         ename=Min(enull,eblank)
         If ename=0 then ename=Max(enull,eblank)
         old_name=Filespec('N',Substr(zz,1,ename-1))||'00'x
         Loldline=Lold + Length(old_name) /* total length of existing line    */
         Lnewline=Lnew + Length(old_name) /* Total length of proposed new line */
         If Lnewline <= 33 then do
            If Lnew < Lold then Lnewline=Loldline
            z=overlay(new||old_name,z,nstart,Lnewline)
            totalm=totalm+1
            end
         Else do  /* TOO long to fit - should never happen with Starter System */
            oldline =old||old_name; newline =new||old_name
            msg='Cannot update' idev ' record "'oldline'" to "'newline'" because length of filename ('Lnewline') is > 33 characters.'
            x=Lineout(Log,msg); x=Lineout(Log);
            say ''
            say 'ERROR: Cannot update DEVMAP' idev 'record'
            say '       "'oldline'" to'
            say '       "'newline'"'
            say '       because the resulting filename would be' Lnewline 'characters long,'
            say '       which is greater than the allowable maximum of 33 characters.'
            say ''
            say '       Update of this record will be bypassed. Press ENTER to continue.'
            parse upper value SysGetKey('NOECHO') with key
            say ''
            error = error+1
            end; /* Too long to fit */
         End; /* Diff length */
      End; /* Match */
   End; /* This is a DASD record */
   x=charout(odev,z)        /* Write a line to the output file */
End; /* Read thru devmap loop */

/*                          */
/* Done with DEVMAP update  */
/*                          */
x=Lineout(odev);   /* Close file */
x=Lineout(idev);   /* Close file */

msg=totalm 'DASD records modified.'
x=Lineout(Log,msg); x=Lineout(Log);
If totalm > 0 then
    "COPY" odev idev" >NUL:" /* Copy new DEVMAP over the old DEVMAP */
Else If replace=0 then do  /* no DASD records modified */
   msg='*** Note: DEVMAP could not be updated for' title'.'
   Say msg; x=Lineout(Log,msg); x=Lineout(Log);
   msg='    Run the P/390 Configurator and check the drive and path for these files.'
   Say msg; x=Lineout(Log,msg); x=Lineout(Log);
   End

rc=SysFileDelete(odev)  /* Erase temp file */
Return;

/*------***************************-----------------------------------*/
/*----- E R R O R   R O U T I N E S ----------------------------------*/
/*------***************************-----------------------------------*/

Nospace1:
ndigits=Length(total);
tdigits=Length(tfree);
tfree=Right(tfree,Max(ndigits,tdigits));
Say ''
msg='** ERROR: Not enough space on 'tletter': to install' title'.'
Say msg; x=Lineout(Log,msg);
Say ''
msg=total' bytes ('Trunc( total/1048576,1) 'MB) are needed on drive 'tletter'.  There are only'
Say msg; x=Lineout(Log,msg);
msg=tfree' bytes ('Trunc(tfree/1048576,1) 'MB) available.'
Say msg; x=Lineout(Log,msg);
Say ''
Say 'Free up enough space on drive 'tletter', or choose a drive that has enough space,'
Say 'and then rerun   '  sletter':INSTSRC 'fletter': 'tletter':'
Exit 3

NodiskF:
Say ''
Say 'Source disk' Fletter': does not exist.  Check parameters and rerun'
Say '  'sletter':INSTSRC s: d:'
Say "where 's:' and 'd:' are valid OS/2 drive letters specifying the"
Say 'source and destination disks.'
Exit 2

NodiskT:
Say ''
Say 'Destination disk' Tletter': does not exist.  Check parameters and rerun'
Say '  'sletter':INSTSRC 'fletter': d:'
Say "where 'd:' is a valid OS/2 drive letter specifying the destination disk."
Exit 2
