Category : Utilities for DOS and Windows Machines
Archive   : BZIP.ZIP
Filename : BZIP.C

 
Output of file : BZIP.C contained in archive : BZIP.ZIP
/* this is a little utility used
to backup files compressed by pkzip to a disk

the first argument is the name of the diskdrive to use for backup

if no other arguments are given:

it first compresses all files in the current directory (which can
be the root) to a file root.zip and stores this file to disk

then it compresses all directories, one by one, and stores these
to disk

if other arguments are given they are compressed one by one and stored
to disk

when storing a zipped file, it splits the file into parts on separate
disks if necessary. These parts are called name.p# where # is a
number from 1 to 99. The last part is called name.-#
They can easily be restored.

normally the program signals only when it needs a new disk.
it deletes anything on the disk and calls a format program if necessary

*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define true 1
#define false 0


#define ROOTFILES 1
#define DIRFILES 2
#define SINGLEFILE 3


int dnum = 0; /* current backup disk */

char zipdir[64];
char zipname[128];
char zipsname[18];

char cmdline[128];
char drive = 'A';
char *buf;

typedef struct his {char s[128]; struct his * n;} his;

struct his * history = NULL, *th;

char bleepkey()
{
time_t tp, tn;

while(! kbhit()){
sound(600);delay(100);nosound();delay(100);
sound(600);delay(100);nosound();delay(100);
sound(600);delay(100);nosound();delay(100);
sound(860);delay(400);nosound();

(void) time(&tp);

do (void)time(&tn); while((! kbhit()) && (tn - tp < 4));
}
return getch();
}


int askcontin()
{
char c;

for(;;){
fprintf(stdout, "Continue? (n)o [y]es ");
c = bleepkey();
switch(c){
case 10: case 13: case 'y': case 'Y': puts("YES"); return true;
case 'n': case 'N': puts("NO"); return false;
otherwise: break;
}
}
}

void deletedir(char *path){
char spath[128];
char npath[128];
struct ffblk fs;

strcpy(spath, path);
strcat(spath, "*.*");

if(findfirst(spath, &fs, FA_DIREC) == 0){
do{
if(fs.ff_attrib & FA_DIREC){
if(fs.ff_name[0] != '.'){
strcpy(npath, path);
strcat(npath, fs.ff_name);
strcat(npath, "\\");
deletedir(npath);
strcpy(npath, path);
strcat(npath, fs.ff_name);
puts(npath);
if(rmdir(npath) != 0) perror("Ignored delete directory error: ");
}
}
else{
strcpy(npath, path);
strcat(npath, fs.ff_name);
puts(npath);
if(remove(npath)!= 0) if(errno == EACCES){
chmod(npath, S_IREAD | S_IWRITE);
if(remove(npath) != 0) perror("Ignored delete file error: ");
}
}
}while(findnext(&fs) == 0);
}
}







void cleandisk(){
char spath[10];

struct ffblk fs;

strcpy(spath, "x:\\*.*");
spath[0] = drive;

if(findfirst(spath, &fs, FA_DIREC) == 0){
fprintf(stdout, "Deleting existing files %s\n", spath);
strcpy(spath, "x:\\");
spath[0] = drive;
deletedir(spath);
}
}

int getinsertnew(){
char c;

char fcmd[20];
char t[3];


dnum++;

strcpy(fcmd, "format ");
strcpy(t, "x:");
t[0] = drive;
strcat(fcmd, t);


for(;;){
fprintf(stdout, "Insert new backup disk %d in drive %c\nALL EXISTING FILES WILL BE DELETED\n", dnum, drive);
fprintf(stdout, "Enter (f)ormat (s)top [c]ontinue ");

c = bleepkey();

switch(c){
case 'f': case 'F': puts("FORMAT"); system(fcmd); break;
case 's': case 'S': puts("STOP"); return false;
case 13: case 10: case 'c': case 'C': puts("CONTINUE"); cleandisk(); return true;
}
}
}


long df()
{
int cnt = false;
int dr;
struct dfree free;

/* we need to know drive free space */

dr = (int)(drive - 'A') + 1;

do{
getdfree(dr, &free);
if(free.df_sclus == 0xFFFF){
fprintf(stderr, "Can not get drive free space for %c\n", drive);
cnt = askcontin();
if(!cnt) return -1L;
}
}while(cnt);

return (long) free.df_avail
* (long) free.df_bsec
* (long) free.df_sclus;
}

#define maxbuf 16384

int splitcopy()
{
long avail, filelen, r, w, wrote = 0L, readd = 0L;
int fn = 0; int zf, czf, ctrl;
char t[4];
char zipcopy[20];

/* we need to know length of zipfile */



zf = _open(zipname, O_RDONLY | O_BINARY);

/* ctrl = ioctl(zf, 0);
ioctl(zf, 1, (ctrl | 0x20) & 0xff); */ /* no ^Z intervention! */

if(zf < 0){
fprintf(stderr, "Can not open %s for reading\n", zipname);
exit(-1);
}

filelen = filelength(zf);

for(;;){
/* available on disk */
avail = df();

/* if error */
if(avail < 0){
close(zf);
return false;
}

if(avail == 0) if(! getinsertnew()){ close(zf); return false; }

printf("Drive %c: has %ld bytes available\n", drive, avail);


strcpy(zipcopy, "x:\\");
zipcopy[0] = drive;
strcat(zipcopy, zipsname);

if((fn == 0) && (filelen <= avail))
strcat(zipcopy, ".zip");
else{
if((filelen - readd) < avail)
strcat(zipcopy, ".-");
else
strcat(zipcopy, ".p");
fn++;
strcat(zipcopy, itoa(fn,t,10));
}

fprintf(stdout, "Creating %s\n", zipcopy);

th = (struct his*) malloc(sizeof(struct his));
if(th != NULL){
sprintf(th->s, "%3d %s\n", dnum, zipcopy);
th->n = history;
history = th;
}

czf = open(zipcopy, O_CREAT | O_BINARY | O_RDWR /*, S_IFREG | S_IREAD | S_IWRITE*/ );

if(czf < 0){
fprintf(stderr, "Can not open %s for writing\n", zipcopy);
exit(-1);
}


/* what to do with read/write errors??? */

do{
r = _read(zf, buf, (avail > maxbuf ? maxbuf : avail));

if(r < 0){
fprintf(stderr, "\nRead error");
exit(-1);
}

w = 0L;
if(r > 0){
w = _write(czf, buf, r);
if(r != w){
fprintf(stderr, "\nWrite error");
exit(-1);
}
}

avail -= w;
readd += r;
wrote += w;
fprintf(stdout, "\rWrote %ld of %ld", wrote, filelen);
}while((avail > 0L ) && (r == maxbuf));

fprintf(stdout, "\n");

_close(czf);

if(readd == filelen) {
_close(zf);
return true;
}

if(!getinsertnew()){
close(zf);
return false;
}
}
}

int compcopy(char * name, int mode)
{
char *t;
int rv;
struct ffblk fs;

/* if first disk */
if(dnum == 0) if(!getinsertnew()) return false;

/* extract zipname */
t = name;
while(*t) t++;
t--;
while((t > name) && (*t != '\\')) t--;

strcpy(zipsname, t);
t = zipsname;
while(*t) t++;
while((t > zipsname) && (*t != '.') && (*t != '\\')) t--;
if(*t == '.') *t = 0;

if(*zipdir){
strcpy(zipname, zipdir);
strcat(zipname, "\\");
strcat(zipname, zipsname);
}
else strcpy(zipname, zipsname);
strcat(zipname, ".zip");

/* construct pkzip command */

switch(mode){
case ROOTFILES:
strcpy(cmdline, "pkzip ");
strcat(cmdline, zipname);
strcat(cmdline, " *.*");
break;
case DIRFILES:
strcpy(cmdline, "pkzip -Pr ");
strcat(cmdline, zipname);
strcat(cmdline, " ");
strcat(cmdline, name);
strcat(cmdline, "\\*.*");
break;
case SINGLEFILE:
strcpy(cmdline, "pkzip ");
strcat(cmdline, zipname);
strcat(cmdline, " ");
strcat(cmdline, name);
break;
}

rv = system(cmdline);


if(findfirst(zipname, &fs, 0) != 0){
fprintf(stdout, "No zipfile created! (possibly empty directory or disk full)\n");
return askcontin();
}
else if(rv != 0){
fprintf(stderr, "PKZIP returned error value %d\n", rv);
remove(zipname);
return askcontin();
}

printf("Now split-copy %s to %c:\n", zipname, drive);

rv = splitcopy();

if(remove(zipname)){

fprintf(stderr, "Fatal error: Can not remove %s\n", zipname);
exit(-1);
}

return rv;

}


void printhistory(struct his * history, FILE * t)
{
if(history == NULL) return;
printhistory(history -> n,t);
fputs(history -> s, stdout);
fputs(history -> s, t);
}









void main(argc, argv)
int argc;
char **argv;
{
int fspecified = 0;
struct ffblk fs;

buf = (char *) malloc(maxbuf);

if(buf == NULL){
fprintf(stderr, "Can not allocate copy buffer, sorry ...");
exit(-1);
}

strcpy(zipdir, ".");

if((argc > 1) && (strcmp(argv[1], "-r") == 0)){
rzip( --argc, ++argv);
exit(0);
}

argc--;
argv++;


while(argc--){
if(argv[0][0] == '-') switch(argv[0][1]){
case 'd':
if(strlen(argv) == 2){
fprintf(stderr, "Need directory name for -d switch\n");
exit(-1);
}
strcpy(zipdir, &argv[0][2]);
printf("Temporary directory for zipfiles is %s\n", zipdir);
break;
otherwise: break;
}
else if((strlen(argv[0]) == 2) && (argv[0][1] == ':')){
drive = toupper(argv[0][0]);
if(drive > 'B'){
fprintf(stderr, "drive specification must one of A: or B:\n");
exit(-1);
}
}
else{
fspecified = true;
if(! findfirst(argv[0], &fs, FA_DIREC)){
if(fs.ff_attrib == FA_DIREC){
if(!compcopy(argv[0], DIRFILES)) exit(-1);
}
else if(!compcopy(argv[1], SINGLEFILE)) exit(-1);
}
else{
fprintf(stderr, "\007File not found %s\n", argv[0]);
}
}
argv++;
}

if(! fspecified){
if(!compcopy("root", ROOTFILES)) exit(-1);
if(! findfirst("*.*", &fs, FA_DIREC)) do{
if((fs.ff_attrib == FA_DIREC) && (fs.ff_name[0] != '.'))
if(!compcopy(fs.ff_name, DIRFILES)) exit(-1);
}while(findnext(&fs) != -1);
}

if(history != NULL){
char tn[20];
FILE *t;

strcpy(tn, "x:\\BZIP.CNT");
*tn = drive;

t = fopen(tn, "w");
if(t == NULL){
fprintf(stderr, "Cannot create table of contents file\n");
exit(-1);
}
fputs("\nTable of contents:\n\n", stdout);
fputs("Table of contents:\n\n", t);
printhistory(history, t);
fclose(t);
fprintf(stdout, "Table of contents written on %s\n", tn);
}
printf("Done, press a a key \n"); bleepkey();
}


/* =============== source for rzip ============== */

rzip(argc,argv)
int argc;
char **argv;
{
char c, spath[80], drive[3], dir[66], file[9], ext[5], npath[80], zipname[80], *t;
int fnum = 1, fc, fo, flags, lastfile = false;
int r, w;
long tw = 0L;
struct ffblk fs;

if(argc != 2){
fprintf(stderr, "Usage: rzip drive:zipname\n");
exit(-1);
}

strcpy(spath, argv[1]);

flags = fnsplit(spath, drive, dir, file, ext);
if((flags & WILDCARDS) || (!(flags & FILENAME))){
fprintf(stderr, "Illegal filename: %s\n", spath);
exit(-1);
}

strcpy(zipname, file);
strcat(zipname, ".zip");

/* remove extension (if any) from specified name */
if(flags & EXTENSION)
spath[strlen(spath) - strlen(ext)] = 0;

printf("Restoring split zipfile %s\n", zipname);

fc = open(zipname, O_CREAT | O_BINARY | O_RDWR, S_IWRITE | S_IREAD);
if(fc < 0){
fprintf(stderr, "Cannot open zipfile %s\n", zipname);
exit(-1);
}

for(;;){
do{
if(fnum == 1)
printf("Enter first disk: (a)bort [c]ontinue ");
else
printf("Enter next disk: (a)bort [c]ontinue ");
c = toupper(bleepkey());
switch(c){
case 10: case 13: case 'C': c= 'C'; puts("CONTINUE"); break;
case 'A': puts("ABORT"); close(fc); remove(zipname); exit(-1); break;
}
}while(c != 'C');

do{
c = 'D';
sprintf(npath, "%s.-%d", spath, fnum);
if(findfirst(npath, &fs, 0) == 0)
lastfile = true;
else{
sprintf(npath, "%s.p%d", spath, fnum);
if(findfirst(npath, &fs, 0) != 0){
printf("\007File %s.[p-]%d not found (r)etry (a)bort", spath, fnum);
c = toupper(bleepkey());
switch(c){
case 'R': puts("RETRY"); break;
case 'A': puts("ABORT"); exit(-1); break;
otherwise: c = 'R'; break;
}
}
}
}while(c == 'R');

printf("Copying %s to %s\n", npath, zipname);

fnum++;
printf("Reading %s\n", npath);
fo = open(npath, O_RDONLY | O_BINARY);
if(fo < 0){
fprintf(stderr, "Can not open file %s\n", npath);
exit(-1);
}

do{
r = _read(fo, buf, maxbuf);

if(r > 0){
w = _write(fc, buf, r);
tw += w;
printf("\rWrote %ld", tw);
if(w < r){
fprintf(stderr, "\nwrite error on temporary zipfile");
close(fo);
close(fc);
remove(zipname);
exit(-1);
}
}
}while(r == maxbuf);
putchar('\n');

close(fo);

if(lastfile){
close(fc);
printf("DONE, Press a key\n");
bleepkey();
exit(0);
}
}
}


  3 Responses to “Category : Utilities for DOS and Windows Machines
Archive   : BZIP.ZIP
Filename : BZIP.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. 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/