Category : C Source Code
Archive   : LSAM23.ZIP
Filename : BKUP.C
Output of file : BKUP.C contained in archive : LSAM23.ZIP
BKUP.c
C J Starr
12-13-87
Description:
File backup demonstrating selected LSAM functions.
Generates a resequenced backup file and its primary index
from a corresponding master file and its primary index.
Output record sequence is determined by 'keys' parameter
specified in '.bin' parameter/control file for the backup.
Program usage:
bkup inp_parm bkp_parm
where:
inp_parm is a defined DOS environment variable
containing the exact path and filespec
of the binary parameter/control file
describing the INPUT or 'master' file/index.
bkp_parm is a defined DOS environment variable
containing the exact path and filespec
of the binary parameter/control file
describing the OUTPUT or backup file/index.
Note to users:
The following assumes its reader has already read the
documentation included with the LSAM package, and is
familiar with the section entitled 'SUPPORT PROGRAMS',
where coding and generation of LSAM's binary parameter/con-
trol files is discussed. If this is NOT the case, STOP.
Read at least the 'SYSTEM OVERVIEW' and 'SUPPORT PROGRAMS'
sections in the file LSAM.DOC before continuing here.
If you wish to try this pgm with your own dataset,
may copy and modify this pgm to do so. Also, you must:
1) Adjust the structure typedef to conform to
the length of your 'master' file's logical record.
(For LSAM v2.02, this length must be fixed.)
2) Define and generate a base/index control file
for each of the 'master' and backup datasets
using genparm.exe. The specs for the backup
files must be identical to the 'master' files
except for the filenames (suggestion: copy
the 'master' definition .txt file and change
all the filenames to any names you choose).
If you have not yet built an index for your 'master'
file, this pgm contains code to do so.
3) Using the DOS 'set' command, define an environment
variable containing the EXACT path specification
for the location of each of the two base/index
parameter/control files generated in step 2) above.
4) Ensure that there does not exist already a file
with the same name as you chose for the backup
base or index file(s) whose names you chose
in step 2) above. For brevity sake, this pgm
does not contain code to handle a pre-existing
index file. You must ensure it is deleted before
running this pgm.
5) Compile and link the revised version of this pgm.
6) Invoke the pgm as above under Program usage.
*/
#define LINT_ARGS YES
#include "stdio.h"
#include "dos.h"
#include "string.h"
#include "lsam.h"
#include "stdlib.h"
/* symbolics for readability */
#define NO 0 /* boolean switch constants */
#define YES 1
#define TIME_START 0 /* local ftime() parm values */
#define TIME_IN_PROCESS 1
#define TIME_END 2
/* demo user data record layout 143 bytes */
typedef struct record { /* matches supplied sample.dat file */
char field0 [1+1];
char field1 [15+1];
char field2 [11+1];
char field3 [1+1];
char field4 [11+1];
char field5 [20+1];
char field6 [20+1];
char field7 [20+1];
char field8 [2+1];
char field9 [5+1];
char field10 [15+1];
char field11 [1+1];
char field12 [2+1];
char field13 [2+1];
char field14 [2+1];
} DATAREC, *DATARECP;
DATAREC usr_rec; /* USER DATA RECORD AREA */
char workstr[80];
char timestr[10];
char durastr[16];
unsigned int h,m,s,t; /* hour, minute, second, tic vars for get_time()*/
unsigned long begin_secs, end_secs, duration_secs;
void ftime(int); /* local get-and-format-time routine */
void get_time(unsigned *,unsigned *,unsigned *,unsigned *); /*lcl DOS get time*/
extern int lsam(void);
void main(argc,argv)
int argc;
char **argv;
{
LSBFPP fp1, fp2;
register int ret;
int recsi = 0, recso = 0;
char fini = NO;
ret = RGOOD;
if(argc < 3) {
printf("\nBKUP Usage error: requires 2 env. vars. pointing to input and backup parm files");
exit(1);
}
/* TRACE FACILITY call example */
/* ls_trace(ON,ALL,NULL,0); ON FOR ALL (valid ANY time) */
/* OPEN INPUT FILE,IX */
fp1 = ls_open(strupr(argv[1]),PARM_ENV_VAR,"rb",(UCHAR *)&usr_rec);
/* OPEN OUTPUT FILE,IX */
fp2 = ls_open(strupr(argv[2]),PARM_ENV_VAR,"wb",(UCHAR *)&usr_rec);
/* test for open error(s) */
if(fp1 == NULL || fp2 == NULL) {
printf("\nBKUP Open error: input ptr = 0x%04x, output ptr = 0x%04x",
fp1,fp2);
printf("\n Check that %s and %s are correctly DEFINED in the DOS environment",
argv[1],argv[2]);
ls_fn_ret(); /* if trouble, display 'lstat' block */
exit(2);
} else {
/* TRACE FACILITY call examples */
/* ls_trace(ON,BASE,fp1,0); ON FOR BASE fp1 all ixs (valid AFTER open) */
/* ls_trace(ON,INDEX,fp2,0); ON FOR INDEX fp2 ix 0 only (valid AFTER open) */
ret = ls_is_ix_new(fp1,0);
if(ret) { /* did we JUST NOW create index ? */
setindex(fp1,0); /* build 'master' file index */
}
ftime(TIME_START); /* take 1st time stamp */
printf("\nBKUP %s Backing up input",timestr);
}
while(!fini) {
ret = ls_readnext(fp1,0); /* read next 'logical' master record */
if(ret != REOF) { /* NOT EOF ? */
recsi++; /* bump input counter */
ret = ls_write(fp2); /* write backup record, upd. index */
if(ret != RGOOD) /* Return not OK ? */
fini = YES; /* indicate loop end */
else /* otherwise */
recso++; /* bump output counter */
} else /* otherwise (it IS EOF) */
fini = YES; /* indicate loop end */
}
ftime(TIME_IN_PROCESS); /* take interim time stamp */
printf("\nBKUP %s Backup complete (ret=%d, %s): %d records in, %d records out",
timestr,ret,(ret==REOF) ? "EOF" : "ERR",recsi,recso);
ret = ls_close(fp1); /* close input */
ftime(TIME_IN_PROCESS); /* take interim time stamp */
printf("\nBKUP %s Closed inputs (ret=%d, %s)",
timestr,ret,(ret==RGOOD) ? "OK" : "ERR");
ret = ls_close(fp2); /* close output */
ftime(TIME_IN_PROCESS); /* take interim time stamp */
printf("\nBKUP %s Closed outputs (ret=%d, %s)",
timestr,ret,(ret==RGOOD) ? "OK" : "ERR");
ftime(TIME_END); /* take last time stamp, calc run time */
printf("\nBKUP %s End of processing, duration %s",timestr,durastr);
/*
Done. Backup base file is now resequenced by specified key and backup
index reflects the resequencing specified in its generated parm file.
If 'backup complete' return code is 11 ('EOF') AND return codes for
input and output closes were both 0, it should be safe to delete old
base/index, and rename the backup base/index to the original 'master'
names. This is left to the user.
*/
ls_exit(ret); /* normal release and exit */
}
int setindex(base,ix) /* build index for file BASE w/handle at slot IX */
LSBFPP base;
UINT ix;
{
int ret;
ftime(TIME_IN_PROCESS);
printf("\nBKUP %s Constructing index for input",timestr);
ret = ls_bldindx(base,ix);
ftime(TIME_IN_PROCESS);
printf("\nBKUP %s Index build complete for input, ret=%d",
timestr,ret);
return ret;
}
void ftime(which)
int which;
{
unsigned long hmodsec;
get_time(&h,&m,&s,&t); /* get system time */
sprintf(timestr,"%2d:%02d:%02d",h,m,s); /* format time output */
switch(which) {
case TIME_START:
begin_secs = (unsigned long)((h*3600) + (m*60) + s); /* save seconds */
break;
case TIME_IN_PROCESS:
break;
case TIME_END:
end_secs = (unsigned long)((h*3600) + (m*60) + s); /* save seconds */
duration_secs = end_secs - begin_secs;
h = duration_secs / 3600;
hmodsec = duration_secs % 3600;
m = hmodsec / 60;
s = hmodsec % 60;
sprintf(durastr,"%02d:%02d:%02d",h,m,s); /* format time output */
break;
}
}
void get_time(h,m,s,t)
unsigned *h, *m, *s, *t;
{
union REGS srv;
srv.h.ah = 0x2C; /* ah=0x2c - DOS get time request */
intdos(&srv,&srv); /* call DOS for time in cx, dx */
*h = (srv.x.cx >> 8); /* high byte of cx is hours */
*m = (srv.x.cx & 0x00ff); /* low byte of cx is minutes */
*s = (srv.x.dx >> 8); /* high byte of dx is seconds */
*t = (srv.x.dx & 0x00ff); /* low byte of dx is 'tics' */
return;
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/