* NebulaSave program * Tony Gravagno, Nebula Research and Development * http://Nebula-RnD.com * * Open Source v1.0 for D3 : 12 jun 2004 * Originally written : june 2004 * * Please e-mail comments, enhancements, and other platform-specfic * versions to Freeware@Nebula-RnD.com. * * Updates may be available at http://Nebula-Rnd.com/freeware * * Responsibility for implementation and use of this program rests * entirely with the user. Nebula R&D will not be liable for any * time, data, financial, or other loss incurred as a result of * execution of this program. This software is distributed as-is * with no warranties or guarantees, explicit or implied. * * Please be sure to include comments for changes, note * conventions being used for Mod 1. * Author: Tony Gravagno (TG) * Contributors: xxxxxxxxxxxx * * Mod-001 TG 040612 Warn user if no config item, set defaults, * then terminate. Defaults will NOT be suitable for all * environments! * Mod-00n XX yymmdd text.... * * Make sure program is cataloged in dm,md. * Update md User-Shutdown macro with "nebulasave". * That causes a selective backup to occur when you * shutdown the system. * To avoid the auto-save, type "nebulasave skip" at TCL * prior to the shutdown command. * The save will be done to a pseudo-floppy created with * this key structure: autobackup00011.d3p * "000" is a zero filled numeric value representing * the day of the week. "11" is the current hour of the * day in 24 hour format. acctsave00516.d3p was saved on * Friday at 4PM. * * How this is intended to be used: Developers will * often write a lot of code and then shutdown and go off * to other things. This ensures that a snapshot is taken * at the time of shutdown, in case the system gets * corrupted or in case a back-step is required to code. * The automated process removes the requirement to remember * to save, manage devices, and manually enter required * accounts. * * Possible enhancements: * 1) Use config file to save with a different ID for * rotation. Default is days 0 to 7. Nice option would * be yymmdd. * 2) Allow for delete of old archives on a rotation cycle. * Feel free to add more here and return to Nebula R&D. * 3) Making the config user-specific so different developers * on the same system can periodically save their work. * 4) The program should determine if it's Windows or *nix and * set a reasonable default save directory like c:\temp or /tmp. * 5) Add a new config value to specify save options like "A". * 6) Add error handling in case dev-make or set-device fail. * 7) Because we have no UI, all output is hushed except the * account-saves themselves. A flag would be nice so that * output could optionally be displayed, based on the UI that's * in effect. * 8) Add ability to save different data at different times. * This could turn into a replacement for a nightly file-save. * * Interesting uses: * - have a phantom do periodic snapshot saves. * - move, copy, or zip saves so some process can archive the * data away from the host system. * - since this program has no user interface, maybe it can * be used from an alternative UI. * * Structure of Config record: * 001 = "" or "SKIP" * 002 = "autobackup" or user-specified filename * 003 = path to directory where saves are stored. * default is currently hardcoded. * 010 = MV list of accounts to save. ********* ********* * * MOD-001-START-INSERT * This program has no UI, but MOD-001 includes a * displayed warning, so I figured I'd start from the * beginning with a device-configurable UI. UI = "screen" * MOD-001-END-INSERT * * using md rather than creating a custom config file ckey = "nebulasave-config" open "md" to f.md else stop read config from f.md,ckey then gosub Main end else * currently hardcoded default save dir: config = "" config<2> = "autobackup" config<3> = "C:\Documents and Settings\Tony" config<3> := "\My Documents\D3Pseudo\" config<10> = "dm" * MOD-001-START-INSERT gosub Warn.New.Config * MOD-001-END-INSERT end write config on f.md,ckey * Is closing MD required? Probably not but D3 has * many issues with open pointers causing problems. close f.md stop * Main: * * tclread cmd if index(cmd,"skip",1) then config<1> = "skip" return * If "nebulasave" is in user-shutdown then this * program is initiated. To skip the save, enter * "nebulasave skip" at TCL before shutdown and * this code will set a flag so that the save will * be skipped at shutdown time. end if config<1> = "skip" then * Check for the token. If found, delete it for next * time, skip the save and proceed with shutdown. * just entering "nebulasave" at TCL has the same * effect of re-enabling the save. config<1> = "" return end else null * * Build the key for the save file. today = oconv(date(),"dw") "r%3" hour = field( oconv(time(),"mt") , ":", 1) now = today:hour:".d3p" * ".d3p" is, or should be, a common extension for * D3 Pseudo files. We need the extension there for * the Get.Device subroutine. * fname = config<2> if fname = "" then config<2> = "autobackup" media = fname:now * last.device = -1 ; * in case we need to create one device = -1 ; * in case a good device exists gosub Get.Device if device = -1 then * we didn't find an existing device gosub Create.Device end gosub Perform.Saves * all done! return * Get.Device: * * * this routine needs improvement. It parses the output * of list-device. Might be better to work from raw data. * execute "list-device" capturing out dc = dcount(out,@am) for n = 1 to dc * since pipes are used in list-device to delimit * fields, we assume that a pipe means we're on * a device line, and the beginning of that line * has a device number. if index(out,"|",1) then last.device = field(trim(out)," ",1) * look for the 00011.d3p signature. we don't * want to create a device if it already exists. * (That's not really important though.) if index(out,now,1) then device = last.device end end next n last.device += 1 return * Create.Device: * pseudo = '"' : config<3> : media:',p"' cmd = 'dev-make -t tape -n ':last.device:' -a ':pseudo device = last.device execute cmd capturing out return * Perform.Saves: * cmd = 'set-device ':device execute cmd capturing out cmd = 't-rew' execute cmd capturing out dc = dcount(config<10>,@vm) for n = 1 to dc cmd = 'account-save ':config<10,n> execute cmd next n cmd = 't-rew' :@am: 't-rew' execute cmd capturing out cmd = 't-det' execute cmd capturing out return * * MOD-001-START-INSERT Warn.New.Config: * begin case case UI = "screen" print "************************" print "************************" print "No nebulasave-config item in dm,md," print "No accounts will be saved." print "Default data stored in new config item." print print "Enter to Continue:": input z case 1 print "************************" print "************************" print "Variable UI not set to known value." print "Defaulting to 'screen' UI." UI = "screen" gosub Warn.New.Config ; * recursive end case return * MOD-001-END-INSERT