home *** CD-ROM | disk | FTP | other *** search
- /* XF.C by Mark Adler 8 Oct 89
- Find a hexadecimal pattern in a set of files, recursing down the
- directories if need be. Type just 'xf' for instructions.
- */
-
- #pragma inline
-
- #include <stdio.h>
- #include <io.h>
- #include <fcntl.h>
- #include <string.h>
- #include <dir.h>
- #include <dos.h>
-
- #define FIND (FA_RDONLY | FA_HIDDEN | FA_SYSTEM)
- #define BUFSZ 512
- #define NAMLN 512
-
- long fls, fnd; /* Files searched, pattern hits */
- unsigned char pat[BUFSZ]; /* Pattern of bytes to search for */
- int pln; /* Number of bytes */
-
-
- void scan(unsigned char *b, int m, char *f, long n)
- /* Search for the pattern pat of length pln which can start anywhere in
- b..b+m-1. If found, report file (f) and location (n + offset in b).
- Also, update fnd for each pattern match. */
- {
- if (pln == 1)
- {
- /* Scan for a single byte */
- asm mov di,b
- asm mov si,m
- while (_SI)
- {
- asm mov cx,si
- asm mov ax,ds
- asm mov es,ax
- asm mov al,pat
- asm cld
- asm repne scasb
- asm mov si,cx
- asm jne nf1
- printf("%s: found pattern at offset %lx\n", f,
- n + ((unsigned char *)_DI - b) - 1);
- fnd++;
- nf1: ;
- }
- }
- else
- {
- /* Scan at even boundaries */
- asm mov di,b
- asm mov si,m
- asm inc si
- asm shr si,1
- while (_SI)
- {
- asm mov cx,si
- asm mov ax,ds
- asm mov es,ax
- asm mov ax,word ptr pat
- asm cld
- asm repne scasw
- asm mov si,cx
- asm jne nf2
- if (pln == 2 || memcmp((void *) _DI, pat + 2, pln - 2) == 0)
- {
- printf("%s: found pattern at offset %lx\n", f,
- n + ((unsigned char *)_DI - b) - 2);
- fnd++;
- }
- nf2: ;
- }
-
- /* Scan at odd boundaries */
- asm mov di,b
- asm inc di
- asm mov si,m
- asm shr si,1
- while (_SI)
- {
- asm mov cx,si
- asm mov ax,ds
- asm mov es,ax
- asm mov ax,word ptr pat
- asm cld
- asm repne scasw
- asm mov si,cx
- asm jne nf3
- if (pln == 2 || memcmp((void *) _DI, pat + 2, pln - 2) == 0)
- {
- printf("%s: found pattern at offset %lx\n", f,
- n + ((unsigned char *)_DI - b) - 2);
- fnd++;
- }
- nf3: ;
- }
- }
- }
-
-
- void search(char *f)
- /* Search the file f for the pattern pat of length pln. Abort the
- search on an open or read error. Update fls for a successfully
- searched file. */
- {
- int h, j, m;
- long n;
- unsigned char b[2*BUFSZ];
-
- strlwr(f);
- if ((h = _open(f, O_RDONLY)) == -1)
- {
- printf("!couldn't open %s for reading\n", f);
- return;
- }
- n = 0;
- m = _read(h, b, 2 * BUFSZ);
- if (m == -1)
- {
- _close(h);
- printf("!error reading %s\n", f);
- return;
- }
- while (m >= pln)
- {
- j = m - pln + 1;
- if (j > BUFSZ)
- j = BUFSZ;
- scan(b, j, f, n); /* Search for pattern pat starting */
- m -= j; /* at b..b+j-1 with file offset n */
- memcpy(b, b + j, m);
- n += j;
- if ((j = _read(h, b + m, BUFSZ)) == -1)
- {
- _close(h);
- printf("!error reading %s\n", f);
- return;
- }
- m += j;
- }
- _close(h);
- fls++;
- }
-
-
- int recurse(char *a)
- /* Find all files that match 'a' and all files anywhere in the tree
- under the path in 'a' that match the name in 'a'. */
- {
- int r;
- char *p, *q;
- struct ffblk f;
- char b[13];
-
- /* Point p to start of name, copy name into b */
- p = strrchr(a, '\\');
- q = strrchr(a, '/');
- if (q > p && q != NULL)
- p = q;
- q = strrchr(a, ':');
- if (q > p && q != NULL)
- p = q;
- if (p == NULL)
- p = a;
- else
- p++;
- if (strlen(p) > 12)
- return 1;
- strcpy(b, p);
-
- /* Find files */
- r = findfirst(a, &f, FIND);
- while (r == 0)
- {
- if ((p - a) + strlen(f.ff_name) >= NAMLN)
- {
- printf("??name got too long---abandoning this recursion\n");
- return 0;
- }
- strcpy(p, f.ff_name);
- search(a); /* Search for pattern in file a */
- r = findnext(&f);
- }
-
- /* Find directories */
- strcpy(p, "*.*");
- r = findfirst(a, &f, FIND | FA_DIREC);
- while (r == 0)
- {
- if (f.ff_attrib & FA_DIREC &&
- strcmp(f.ff_name, ".") && strcmp(f.ff_name, ".."))
- {
- if ((p - a) + strlen(f.ff_name) + 1 + strlen(b) >= NAMLN)
- {
- printf("??name got too long---abandoning this recursion\n");
- return 0;
- }
- strcpy(p, f.ff_name);
- strcat(a, "\\");
- strcat(a, b);
- recurse(a);
- }
- r = findnext(&f);
- }
- return 0;
- }
-
-
- void main(int argc, char *argv[])
- {
- int j, k;
- char *p;
- char a[NAMLN];
-
- /* Help if one or no arguments */
- if (argc < 3)
- {
- printf("XF version 1.0 Mark Adler 8 Oct 1989\n\
- \n\
- XF hex file1 file2 ... will search for the hexadecimal pattern 'hex'\n\
- in all files matching the (possibly ambiguous) file name in 'filen',\n\
- that are in the path in 'filen', and any matching files in any\n\
- subdirectories, subsubdirectories, etc. in that path. (If there is\n\
- no path, the current path is assumed.) For example:\n\
- \n\
- xf 12ff \\*.com\n\
- \n\
- will search all the *.com files on the current device, wherever they\n\
- are, for the hex bytes 0x12, 0xff.\n");
- return;
- }
-
- /* Get hex search pattern */
- pln = 0;
- for (j = 0, p = argv[1]; *p; p++, j = !j)
- {
- if ((k = *p) >= '0' && k <= '9')
- k -= '0';
- else if ((k &= 0x5f) >= 'A' && k <= 'F')
- k -= 'A' - 10;
- else
- {
- printf("?invalid hexadecimal search value---bad character\n");
- return;
- }
- if (j)
- pat[pln++] += k;
- else
- pat[pln] = k << 4;
- }
- if (j)
- {
- printf("?invalid hexadecimal search value---odd # of digits\n");
- return;
- }
-
- /* Search arguments */
- fls = 0;
- fnd = 0;
- for (j = 2; j < argc; j++)
- if (recurse(strcpy(a, argv[j])))
- printf("?arg <%s> invalid---name too long\n", argv[j]);
-
- /* Show overall results */
- printf("searched %ld file%s, ", fls, fls == 1 ? "" : "s");
- if (fnd)
- printf("found pattern %ld time%s\n", fnd, fnd == 1 ? "" : "s");
- else
- printf("pattern not found\n");
- }