home *** CD-ROM | disk | FTP | other *** search
- *****************************************************************
- FUNCTION SYSSAVE
- *****************************************************************
-
- * Back up and restore data files from Clipper
-
- * Copyright(c) 1991 -- James Occhiogrosso
-
- # include 'box.ch'
- # include 'inkey.ch'
- # include 'set.ch'
- # include 'setcurs.ch'
-
- # define drive_num ASC(drive) - 64
- # define K_f 102
- # define K_F 70
-
- LOCAL old_cursor := SETCURSOR(SC_NONE), old_screen := '', ;
- old_dateset := SET(_SET_DATEFORMAT)
-
- PARAMETERS mode, drive, filelist, msg_line
-
- * Initialize all variables
-
- PRIVATE initsize := needed := ret_value := remaining ;
- := total := shandle := size := thandle := 0
-
- PRIVATE backfile := backtext := backupid := buffer := ;
- disktext := sourcetime := source := target := ''
-
- PRIVATE diskno := 1, sourcedate
-
- * Test critical passed arguments
-
- IF PCOUNT()< 2 .OR. TYPE('mode') != 'N' .OR. TYPE('drive') != 'C'
- * Wrong parameters passed, return error
- RETURN -1
- ENDIF
-
- IF mode < 1 .OR. mode > 4
- * Check mode passed. If not between 1 and 4, return error
- RETURN -1
- ENDIF
-
- IF (mode = 1 .OR. mode = 3) .AND. TYPE('filelist') != 'A'
- * Both "Backup" modes require a filelist array
- RETURN -1
- ENDIF
-
- * Set up default message line if not passed
- IF msg_line = NIL
- msg_line = MAXROW()
- ENDIF
-
- * Save screen area
- IF mode < 3
- * Full screen mode
- IF MEMORY(1) <= 8
- * Insufficient memory to run in full screen mode
- ?? CHR(7)
- CENTERON(msg_line, 'Insufficient memory to run. ' + ;
- hitanykey)
- INKEY(0)
- RETURN (1)
- ELSE
- old_screen = SCRNSAVE(0, 0, msg_line, MAXCOL())
- ENDIF
- ELSE
- * Single line screen mode
- old_screen = SCRNSAVE(msg_line, 0, msg_line, MAXCOL())
- ENDIF
-
- * Strip all but first character of drive passed
- drive = UPPER(LEFT(drive,1)) + ':'
-
- backfile = drive + "BACKUP" + LTRIM(STR(diskno)) + ".DAT"
-
- IF mode = 1 .OR. mode = 2 && Full screen modes
- CLEAR
- @ 3, 0
- TEXT
- This function uses the DOS FORMAT program if it detects
- an unformatted disk during a BACKUP operation.
-
- FORMAT.COM must be present in the directory or on the
- DOS path, or the process will abort.
-
- Label and number all disks during BACKUP according to
- the screen instructions. Improperly numbering a disk
- may cause serious problems!
-
- When restoring, be sure to load the numbered disks in
- the sequence shown in the screen instructions.
-
- ENDTEXT
-
- SETCOLOR(colbarhi)
- @ 18, 7, 20, 72 BOX B_SINGLE + SPACE(1)
- @ 19, 9 SAY 'CAUTION: Files in current directory on drive ';
- + drive + ' will be erased.'
- SETCOLOR(colstd)
- ENDIF
-
-
- * Allocate copy buffer 1/4 of available free memory
- initsize = (MEMORY(1) * 1024)/ 4
-
- * Return if initial buffer size less than 2K
- IF initsize <= 2048
- ?? CHR(7)
- CENTERON(msg_line, 'Insufficient memory to run. ' + ;
- hitanykey)
- INKEY(0)
- RETURN(1)
- ENDIF
-
- * Initialize copy buffer size
- size = initsize
- buffer = SPACE(size)
-
- IF mode = 1 .OR. mode = 3
-
- * If this is a backup operation, check files in passed array
- * by checking size. FILESIZE returns -1 on any file error.
-
- num_files = LEN(filelist)
- FOR cntr = 1 to num_files
- curr_file = FILESIZE(filelist[cntr])
- IF curr_file <= 0
- CENTERON(msg_line, 'Error reading file ' + ;
- filelist[cntr] + '. ' + hitanykey)
- INKEY(0)
- RETURN(5)
- ENDIF
- needed = needed + curr_file
- NEXT
-
- * Advise operator of disk space needed for backup operation
- SETCURSOR(SC_INSERT)
- CENTERON(msg_line, 'Backup will need approximately ' + ;
- LTRIM(STR(INT((needed/1024) + 2))) + ;
- 'K of disk space. Proceed? Y/N ')
- ELSE
- CENTERON(msg_line, 'Proceed with restore operation? Y/N ')
- ENDIF
-
- @ msg_line, COL() -4 SAY ''
- IF .NOT. OPCONFIRM()
- * Operator aborted
- SCRNREST(old_screen)
- SETCURSOR(old_cursor)
- RETURN(0)
- ENDIF
-
- * Ask operator to insert a disk
- SETCURSOR(SC_NONE)
- DO INSERTDISK
- IF LASTKEY() = K_ESC
- SCRNREST(old_screen)
- SETCURSOR(old_cursor)
- RETURN(0)
- ENDIF
-
- * Perform selected operation.
- IF mode = 1 .OR. mode = 3
- DO BACKUP
- ELSE
- DO RESTORE
- ENDIF
-
- * Restore everything and return
- SCRNREST(old_screen)
- SETCURSOR(old_cursor)
- SET(_SET_DATEFORMAT, old_dateset)
- RETURN(ret_value)
-
- *****************************************************************
- STATIC PROCEDURE BACKUP
- *****************************************************************
-
- * Backup files to selected drive
-
- LOCAL counter := 1, disk_free := 0
-
- * Checkout and clear disk
- DO NEWDISK
-
- IF LASTKEY() = K_ESC
- * Abort if Esc terminated any operation
- ret_value = 12
- RETURN
- ENDIF
-
- SET CENTURY OFF
- backupid = DTOC(DATE()) + ' ' + TIME() + ' '
- backtext = backupid
-
- DO WHILE counter <= LEN(filelist)
-
- * Get the file to backup and create target file name.
- source = LTRIM(UPPER(filelist[counter]))
- target = UPPER(drive) + source
-
- * Open files
- IF .NOT. OPENSOURCE() .OR. .NOT. OPENTARGET()
- ret_value = 2
- RETURN
- ENDIF
-
- CENTERON(msg_line, 'Backing up file '+ source +' to drive ' ;
- + drive + ' - Disk No. ' + LTRIM(STR(diskno)))
-
- DO WHILE (remaining > 0)
-
- * Check disk space remaining
- disk_free = DISKSPACE(drive_num)
-
- IF disk_free <= 2048
- * Reset everything and get new disk
- size := initsize
- buffer := ''
- buffer := SPACE(size)
-
- * Close partial target file and date it
- FCLOSE(thandle)
- IF EMPTY(FILEDATE(target,sourcedate)) .OR. ;
- EMPTY(FILETIME(target,sourcetime))
-
- * Empty return is error in writing date or time
- CENTERON(msg_line, ;
- 'Error writing file date or time to ' + target)
- ?? CHR(7)
- ret_value = 6
- RETURN
- ENDIF
-
- * Add + to target file name if copy incomplete
-
- backfile = drive +"BACKUP"+ LTRIM(STR(diskno))+".DAT"
- backtext = backtext + SUBSTR(target,3) + '+ '
- IF .NOT. MEMOWRIT(backfile,backtext)
- CENTERON(msg_line, ;
- 'Error writing backup identification file')
- ?? CHR(7)
- ret_value = 7
- RETURN
- ENDIF
-
- * Prepare next disk
- backtext = backupid
- diskno++
- DO INSERTDISK
- DO NEWDISK
- IF LASTKEY() = K_ESC
- * Abort if Esc terminated any operation
- ret_value = 12
- RETURN
- ENDIF
-
- * Create target file on new disk
- thandle = FCREATE(target)
- IF FERROR() > 0
- CENTERON(msg_line, ;
- 'Fatal error! Cannot create file '+ target)
- ?? CHR(7)
- ret_value = 6
- RETURN
- ENDIF
- * Re-display current backup file/disk information
- CENTERON(msg_line, ;
- 'Backing up file ' + source + ' to drive ' ;
- + drive + ' - Disk No. ' + LTRIM(STR(diskno)))
-
- ELSE
- * Reset buffer size
- IF disk_free - 2048 > initsize
- size = initsize
- ELSE
- size = disk_free - 2048
- ENDIF
- buffer := ''
- buffer := SPACE(size)
- ENDIF
-
- IF .NOT. COPYBUFFER()
- RETURN
- ENDIF
- ENDDO
-
- * Done! Close files
- IF .NOT. CLOSEFILES()
- RETURN
- ENDIF
-
- * Add ! to target if complete
-
- backfile = drive + "BACKUP" + LTRIM(STR(diskno)) + ".DAT"
- backtext = backtext + SUBSTR(target,3) + '! '
- IF .NOT. MEMOWRIT(backfile,backtext)
- CENTERON(msg_line, 'Error writing backup data file')
- ?? CHR(7)
- ret_value = 7
- RETURN
- ENDIF
-
- * Set up for next file in array
- counter++
-
- ENDDO WHILE counter <= LEN(filelist)
- RETURN
-
- *****************************************************************
- STATIC PROCEDURE RESTORE
- *****************************************************************
- * Restore backed up files
-
- LOCAL splitfile := .F.
- diskno = 1
-
- * Verify correct restore disk
- IF .NOT. CHECKNEXT()
- RETURN
- ENDIF
-
- DO WHILE LEN(backtext) > 0
- IF .NOT. splitfile
-
- * Get source and target file names
- IF AT("!", backtext) > 0
- target = SUBSTR(backtext, 1, AT("!", backtext) -1 )
- ELSEIF AT("+", backtext) > 0
- target = SUBSTR(backtext, 1, AT("+", backtext) -1 )
- ENDIF
- source = drive + target
-
- * Open files
- IF .NOT. OPENSOURCE() .OR. .NOT. OPENTARGET()
- EXIT
- ENDIF
- ENDIF
-
- * Strip file name from list.
- backtext = SUBSTR(backtext,LEN(target)+1)
- CENTERON(msg_line, ;
- 'Restoring file ' + source + ' to hard disk.')
-
- * If marker is "!", copy is a complete file
- IF ASC(backtext) = 33
- splitfile = .F.
- DO WHILE remaining > 0
- IF .NOT. COPYBUFFER()
- EXIT
- ENDIF
- ENDDO
- * Strip file marker and space
- backtext = SUBSTR(backtext,3)
-
- * If marker is "+", copy is a split file
-
- ELSEIF ASC(backtext) = 43
- * Copy first disk unconditionally
- IF .NOT. splitfile
- DO WHILE remaining > 0
- IF .NOT. COPYBUFFER()
- EXIT
- ENDIF
- ENDDO
- ENDIF
- diskno = diskno + 1
- splitfile = .T.
-
- * Close source file on old disk
- FCLOSE(shandle)
- DO INSERTDISK
-
- * Reinitialize memory variables for next disk
- IF CHECKNEXT()
-
- * Reopen source file on new disk
- IF .NOT. OPENSOURCE()
- EXIT
- ENDIF
-
- * Continue copying source
- DO WHILE remaining > 0
- CENTERON(msg_line, 'Restoring file ' + source + ;
- ' to hard disk.')
- IF .NOT. COPYBUFFER()
- EXIT
- ENDIF
- ENDDO
- ELSE
- * Operator terminated with Esc
- ret_value = 12
- EXIT
- ENDIF
- ENDIF
-
- IF .NOT. splitfile .OR. (splitfile .AND. ;
- SUBSTR(backtext,LEN(target)+1,1) = '!')
-
- * Copy complete. Close and date target
- IF .NOT. CLOSEFILES()
- RETURN
- ENDIF
- ENDIF
- ENDDO
- @ msg_line, 0
- RETURN
-
- *****************************************************************
- STATIC PROCEDURE NEWDISK
- *****************************************************************
- * Check disk drive status and space
-
- LOCAL cnt := delcnt := errorcode := keypress := 0, delfiles := {}
-
- * Activate interrupt 24 handler
- SETINT24(.T.)
-
- DO WHILE .T.
- SETCOLOR(colhelp1)
-
- * Check for disk error
- FCLOSE(FCREATE(backfile))
- errorcode = GETINT24()
-
- IF errorcode = 1 .OR. errorcode = 3
- IF errorcode = 1
- CENTERON(msg_line, 'Disk in drive ' + drive + ;
- ' is write protected. ' + hitanykey)
- ELSE
- CENTERON(msg_line, ;
- 'Drive ' + drive + ' not ready. '+ hitanykey)
- ENDIF
- * Wait for operator to correct problem or abort
- ?? CHR(7)
- IF INKEY(0) != K_ESC
- LOOP
- ELSE
- ret_value = 12
- EXIT
- ENDIF
- ENDIF
-
- IF errorcode = 13
- CENTERON(msg_line, ;
- 'Disk is Unformatted. Press F to format it, ' + ;
- 'or any key to try again.')
- ?? CHR(7)
- keypress = INKEY(0)
- IF keypress = K_ESC
- * Operator aborted
- ret_value = 12
- EXIT
- ELSEIF keypress = K_F .OR. keypress = K_f
- IF FILE("FORMAT.COM") .OR. FILE("FORMAT.EXE") .OR. ;
- FILE("FORMAT.BAT") .AND. .NOT. EMPTY(drive)
- SAVE SCREEN
- CLEAR
- @ 1,0 SAY 'Running DOS format. ' + ;
- 'Follow screen instructions'
- ?
- ?
- RUN FORMAT &drive
- RESTORE SCREEN
- ELSE
- * DOS Format file missing
- CENTERON(msg_line, ;
- 'Format program not on DOS path. ' + ;
- 'Cannot proceed.')
- ?? CHR(7)
- PAUSE(2)
- * Force return to main menu on exit
- KEYBOARD CHR(K_ESC)
- ret_value = 11
- EXIT
- ENDIF
- ELSE
- * Operator pressed a key. Restart for disk change
- LOOP
- ENDIF
-
- ELSEIF errorcode > 0
- CENTERON(msg_line, ;
- 'Unknown error -- Press any key to abort')
- ?? CHR(7)
- INKEY(0)
- ret_value = 12
- ELSE
- * No errors. Delete files in root directory
- CENTERON(msg_line, ;
- 'Erasing files on disk in drive ' + drive)
- delcnt = ADIR(drive + "*.*")
- IF delcnt > 0
- ASIZE(delfiles,delcnt)
- ADIR(drive + "*.*", delfiles)
- FOR cnt = 1 to delcnt
- * Erase all files except COMMAND.COM
- IF delfiles[cnt] != 'COMMAND.COM'
- FERASE(drive + delfiles[cnt])
- ENDIF
- NEXT
- ENDIF
-
- * Check to see if all files were erased
- IF DISKSIZE(drive_num) != DISKSPACE(drive_num)
- ?? CHR(7)
- SETCURSOR(SC_INSERT)
- CENTERON(msg_line, ;
- 'All files on disk were not erased! ' + ;
- 'Do you want to change disks? ')
-
- * Position cursor and wait for operator
- SETPOS(ROW(), COL()-2)
- IF OPCONFIRM()
- SETCURSOR(SC_NONE)
- CENTERON(msg_line,'Insert new disk. '+ hitanykey)
- INKEY(0)
- LOOP
- ELSE
- SETCURSOR(SC_NONE)
- CENTERON(msg_line, ;
- hitanykey + ' (or Esc to abort)' )
- INKEY(0)
- ENDIF
-
- ENDIF
- EXIT
- ENDIF
-
- ENDDO
-
- SETINT24(.F.)
- SETCOLOR(colstd)
- @ msg_line, 0
- RETURN
-
- *****************************************************************
- STATIC FUNCTION CHECKNEXT
- *****************************************************************
- * Test and initialize parameters for next restore disk
-
- LOCAL errorcode := 0
-
- * Activate interrupt 24 handler
- SETINT24(.T.)
-
- DO WHILE .T.
- * Check for disk error
- DISKSPACE(drive_num)
- errorcode = GETINT24()
-
- IF errorcode > 0
- CENTERON(msg_line, ;
- 'Drive ' + drive + ' not ready. ' + hitanykey)
- ?? CHR(7)
- IF INKEY(0) != K_ESC
- LOOP
- ELSE
- * Operator aborted
- ret_value = 12
- RETURN(.F.)
- ENDIF
- ENDIF
- EXIT
- ENDDO
-
- * Clear the INT24 handler
- SETINT24(.F.)
-
- * Verify disk number
- backfile = drive + "BACKUP" + LTRIM(STR(diskno)) + ".DAT"
- DO WHILE .NOT. FILE(backfile)
- CENTERON(msg_line, ;
- 'Incorrect disk ID or disk is not a backup disk. ' + ;
- hitanykey)
- INKEY(0)
- DO INSERTDISK
- IF LASTKEY() = K_ESC
- ret_value = 12
- RETURN(.F.)
- ENDIF
- ENDDO
-
- * Read disk's backup identification file
- disktext = MEMOREAD(backfile)
- IF diskno = 1
- backupid = SUBSTR(disktext, 1, 17)
- ELSE
- * If not disk 1, verify it
- DO WHILE .NOT. backupid == SUBSTR(disktext, 1, 17) .OR. ;
- .NOT. target == SUBSTR(disktext, 19, LEN(target))
- CENTERON(msg_line, 'Disk ID invalid! - ' + hitanykey + ;
- ' (Esc to exit)' )
- ?? CHR(7)
- IF INKEY(0) = K_ESC
- ret_value = 12
- RETURN(.F.)
- ENDIF
- ENDDO
- ENDIF
- @ msg_line, 0
- backtext = SUBSTR(disktext, 19)
- RETURN(.T.)
- *
-
- *****************************************************************
- STATIC FUNCTION OPENSOURCE
- *****************************************************************
- * Open source file
-
- * Get date and time of source files
- sourcedate = FILEDATE(source)
- sourcetime = FILETIME(source)
-
- * Verify that everything is readable
- IF EMPTY(sourcedate) .OR. EMPTY(sourcetime)
- ?? CHR(7)
- CENTERON(msg_line, ;
- 'Error verifying ' + source + ' file. ' + hitanykey)
- ret_value = 3
- INKEY(0)
- RETURN(.F.)
- ENDIF
-
- shandle = FOPEN(source)
- * Open all files and check for errors
- IF FERROR() > 0
- * Source error
- CENTERON(msg_line, 'Fatal error! Cannot open file ' ;
- + source + ' ' + hitanykey)
- ?? CHR(7)
- INKEY(0)
- ret_value = 2
- RETURN(.F.)
- ENDIF
-
- * Get total source file size.
- total = FSEEK(shandle, 0, 2)
- remaining = total
-
- * Reset file pointer to BOF
- FSEEK(shandle, 0)
- RETURN(.T.)
-
- *****************************************************************
- STATIC FUNCTION OPENTARGET
- *****************************************************************
- * Open target file
-
- thandle = FCREATE(target)
- IF FERROR() > 0
- * Target error
- CENTERON(msg_line, 'Fatal error! Cannot create file ' ;
- + target + ' ' + hitanykey)
- ?? CHR(7)
- ret_value = 4
- INKEY(0)
- RETURN(.F.)
- ENDIF
- RETURN(.T.)
-
- *****************************************************************
- STATIC FUNCTION CLOSEFILES
- *****************************************************************
- * Close source and target files - redate target
-
- FCLOSE(thandle)
- FCLOSE(shandle)
- * Write date and time to target file before closing
-
- IF EMPTY(FILEDATE(target,sourcedate)) .OR. ;
- EMPTY(FILETIME(target,sourcetime))
- * Error occurred in writing date or time.
- CENTERON(msg_line, ;
- 'Error writing file date ' + target + ' ' + hitanykey)
- INKEY(0)
- ret_value = 10
- RETURN(.F.)
- ENDIF
-
- @ msg_line, 0
- RETURN(.T.)
-
- *****************************************************************
- STATIC FUNCTION COPYBUFFER
- *****************************************************************
- * Write buffer area to target disk
-
- size = LEN(buffer)
- IF (remaining < size)
- * Set size to remaining bytes in file
- size = remaining
- ENDIF
-
- * Read "size" bytes into buffer and check number read
- IF FREAD(shandle, @buffer, size) != size
- ?? CHR(7)
- CENTERON(msg_line, ;
- "Fatal error reading " + source + ' ' + hitanykey)
- INKEY(0)
- ret_value = 8
- RETURN(.F.)
- ENDIF
-
- * Write "size" bytes to target and check number written
- IF FWRITE(thandle, buffer, size) != size
- ?? CHR(7)
- CENTERON(msg_line, ;
- "Fatal error writing " + target + ' ' + hitanykey)
- INKEY(0)
- ret_value = 9
- RETURN(.F.)
- ENDIF
-
- * Compute remaining bytes in file
- remaining = remaining - size
- RETURN(.T.)
-
- *****************************************************************
- STATIC PROCEDURE INSERTDISK
- *****************************************************************
- * Display message and wait for operator to insert a disk
-
- CENTERON(msg_line, ;
- 'Insert backup disk # ' + LTRIM(STR(diskno)) + ;
- ' in drive ' + drive + '. ' + hitanykey)
- DONEBEEP()
- INKEY(0)
- @ msg_line, 0
- RETURN
-
-
-