home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
pc
/
source
/
mmv10src.zoo
/
mmvpatch.c
< prev
next >
Wrap
Text File
|
1989-11-22
|
6KB
|
253 lines
/*
mmvpatch 1.0
Copyright (c) 1989 by Vladimir Lanin.
This program may be freely used and copied on a non-commercial basis.
*/
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <process.h>
#define PATCHOFF 0x6C04
#define CLUSTOFF1 19
#define CLUSTOFF2 15
#define DRIVEOFF1 0
#define TEMPLOFF1 1
#define ATTROFF1 12
#define DRIVEOFF2 1
#define TEMPLOFF2 2
#define ATTROFF2 0
#define NORMCOPY 0x002
#define OVERWRITE 0x004
#define NORMMOVE 0x008
#define XMOVE 0x010
#define DIRMOVE 0x020
#define NORMAPPEND 0x040
#define ZAPPEND 0x080
static void checkid(char *n, int *i1, int *i2, int *d1, int *d2);
static void quit(void);
static int curdrive;
static struct {
char ph_banner[30];
char ph_name[9];
int ph_dfltop;
int ph_safeid;
int ph_clustoff;
int ph_driveoff;
int ph_drivea;
} patch;
int main(int argc, char *(argv[]))
{
int binary;
char *popname;
char buf[80];
int i;
static char opnames[] = "xmrcoaz";
static int ops[] =
{XMOVE, NORMMOVE, DIRMOVE, NORMCOPY, OVERWRITE, NORMAPPEND, ZAPPEND};
static char dirname[] = "$$tmpdir.tmp";
int ci1, ci2, cd1, cd2;
int si1, si2, sd1, sd2;
int ni1, ni2, nd1, nd2;
int ai1, ai2, ad1, ad2;
int d1, d2, i1, i2;
if (argc == 1)
argv[1] = "mmv.exe";
else if (argc > 2) {
fprintf(stderr,
"Usage: mmvpatch [mmv_copy]\n");
quit();
}
if ((binary = open(argv[1], O_RDWR | O_BINARY)) < 0) {
fprintf(stderr, "%s: file not found.\n", argv[1]);
quit();
}
if (
lseek(binary, PATCHOFF, 0) != PATCHOFF ||
read(binary, &patch, sizeof(patch)) != sizeof(patch) ||
strcmp(patch.ph_banner, "mmv 1.0 patchable flags")
) {
fprintf(stderr, "Can't find patch area in %s.\n", argv[1]);
quit();
}
fnsplit(argv[1], NULL, NULL, patch.ph_name, NULL);
for (i = 0; i < sizeof(ops) && ops[i] != patch.ph_dfltop; i++)
;
if (i > sizeof(ops)) {
i = 0;
patch.ph_dfltop = ops[i];
}
do {
printf("Enter default task option [x|m|r|c|o|a|z|CR=%c]: ",
opnames[i]);
gets(buf);
*buf = tolower(*buf);
} while ((popname = strchr(opnames, *buf)) == NULL);
if ((i = popname - opnames) < sizeof(opnames) - 1)
patch.ph_dfltop = ops[i];
curdrive = getdisk();
strcpy(buf, "*.*");
checkid(buf, &ci1, &ci2, &cd1, &cd2);
if (mkdir(dirname)) {
fprintf(stderr, "Couldn't mkdir %s.\n", dirname);
quit();
}
strcpy(buf, dirname);
strcat(buf, "/*.*");
checkid(buf, &si1, &si2, &sd1, &sd2);
strcpy(buf, dirname);
strcat(buf, "/../*.*");
checkid(buf, &ni1, &ni2, &nd1, &nd2);
rmdir(dirname);
fprintf(stderr,
"Put a formatted disk in drive A (no data will be lost).\n"
"Hit any key when ready... ");
getchar();
strcpy(buf, "a:/");
strcat(buf, dirname);
if (mkdir(buf)) {
fprintf(stderr, "Couldn't mkdir %s.\n", buf);
quit();
}
checkid("a:/*.*", &ai1, &ai2, &ad1, &ad2);
rmdir(buf);
d1 = (
cd1 != -1 &&
cd1 == sd1 &&
sd1 == nd1 &&
ad1 != -1 &&
cd1 - curdrive == ad1
);
d2 = (
cd2 != -1 &&
cd2 == sd2 &&
sd2 == nd2 &&
ad2 != -1 &&
cd2 - curdrive == ad2
);
i1 = (
ci1 == ni1 &&
ci1 != si1 &&
si1 != 0 &&
ai1 == 0
);
i2 = (
ci2 == ni2 &&
ci2 != si2 &&
si2 != 0 &&
ai2 == 0
);
if (!(d1 || d2) && !(i1 || i2))
patch.ph_safeid = 1;
else {
patch.ph_safeid = 0;
if (d1) {
patch.ph_driveoff = DRIVEOFF1;
patch.ph_drivea = ad1;
}
else {
patch.ph_driveoff = DRIVEOFF2;
patch.ph_drivea = ad2;
}
if (i1)
patch.ph_clustoff = CLUSTOFF1;
else
patch.ph_clustoff = CLUSTOFF2;
}
if (patch.ph_safeid)
printf("Must use slow directory identification method.\n");
else {
printf(
"The fast dir-id method works.\n"
"(clustoff == %d, driveoff == %d, drivea == %d).\n",
patch.ph_clustoff, patch.ph_driveoff, patch.ph_drivea);
do {
printf("Do you wish to use it [y/n]? ");
gets(buf);
*buf = tolower(*buf);
} while (*buf != 'y' && *buf != 'n');
if (*buf == 'n')
patch.ph_safeid = 1;
}
do {
printf("Is all of the above satisfactory [y/n]? ");
gets(buf);
*buf = tolower(*buf);
} while (*buf != 'y' && *buf != 'n');
if (*buf == 'n')
printf("Ok, will not write patch.\n");
else if (
lseek(binary, PATCHOFF, 0) != PATCHOFF ||
write(binary, &patch, sizeof(patch)) != sizeof(patch) ||
close(binary)
) {
fprintf(stderr, "Error writing patch to %s.\n", argv[1]);
quit();
}
return(0);
}
static void checkid(char *n, int *id1, int *id2, int *d1, int *d2)
{
struct ffblk ff;
*(int *)(&(ff.ff_reserved[CLUSTOFF1])) = 0;
*(int *)(&(ff.ff_reserved[CLUSTOFF2])) = 0;
ff.ff_reserved[ATTROFF1] = -1;
ff.ff_reserved[TEMPLOFF1] = -1;
ff.ff_reserved[DRIVEOFF1] = -1;
ff.ff_reserved[ATTROFF2] = -1;
ff.ff_reserved[TEMPLOFF2] = -1;
ff.ff_reserved[DRIVEOFF2] = -1;
if (findfirst(n, &ff, FA_DIREC | FA_HIDDEN | FA_SYSTEM)) {
fprintf(stderr, "Can't findfirst %s.\n", n);
quit();
}
*id1 = *(int *)(&(ff.ff_reserved[CLUSTOFF1]));
*id2 = *(int *)(&(ff.ff_reserved[CLUSTOFF2]));
*d1 = ff.ff_reserved[DRIVEOFF1];
*d2 = ff.ff_reserved[DRIVEOFF2];
if (
ff.ff_reserved[ATTROFF1] != (FA_DIREC | FA_HIDDEN | FA_SYSTEM) ||
ff.ff_reserved[TEMPLOFF1] != '?'
)
*d1 = -1;
if (
ff.ff_reserved[ATTROFF2] != (FA_DIREC | FA_HIDDEN | FA_SYSTEM) ||
ff.ff_reserved[TEMPLOFF2] != '?'
)
*d2 = -1;
}
static void quit(void)
{
fprintf(stderr, "Aborting. No updates made.\n");
exit(1);
}