home *** CD-ROM | disk | FTP | other *** search
- /*
- 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);
- }