add netbsd nl(1)
[rofl0r-hardcore-utils.git] / fastfind.c
blobec15c2e507d0dc82689eaa8f4e7712dcd19dbcc3
1 #define _ALL_SOURCE
2 #include <fcntl.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <signal.h>
10 #define BLOCKSIZE 64*1024
11 #define ATIME 1
13 static int usage(const char *a0) {
14 dprintf(2, "usage: %s file term\n"
15 "search for term in file and print the offset if found\n\n"
16 "optimized for big block reads\n"
17 "designed to find strings of accidentally "
18 "deleted files in blockdevices.\n"
19 , a0);
20 return 1;
23 static off_t offset = 0;
24 static int sigc, neednl;
25 static void sigh(int nsig) {
26 sigc++;
27 dprintf(2, "\rcurrent offset: 0x%llx, elapsed %d", offset, sigc*ATIME);
28 alarm(ATIME);
29 neednl = 1;
32 int main(int argc, char **argv) {
33 if(argc != 3) return usage(argv[0]);
34 const char* file = argv[1], *term = argv[2];
35 unsigned char *dblbuf = calloc(1, BLOCKSIZE * 2);
36 unsigned char *readbuf = dblbuf + BLOCKSIZE;
37 size_t termlen = strlen(term);
38 unsigned char *searchbuf = readbuf - termlen;
39 unsigned char *copybuf = readbuf + BLOCKSIZE - termlen;
40 int fd = open(file, O_RDONLY), success=0;
41 if(fd == -1) {
42 perror("open");
43 return 1;
45 signal(SIGALRM, sigh);
46 alarm(ATIME);
47 while(1) {
48 ssize_t n = read(fd, readbuf, BLOCKSIZE);
49 if(n <= 0) break;
50 void* res = memmem(searchbuf, BLOCKSIZE+termlen, term, termlen);
51 if(res) {
52 if(neednl) dprintf(2, "\n");
53 neednl = 0;
54 dprintf(1, "bingo: 0x%llx\n", (unsigned long long) offset + ((uintptr_t) res - (uintptr_t)readbuf));
55 fflush(stdout);
56 success = 1;
58 memcpy(searchbuf, copybuf, termlen);
59 offset += n;
61 return !success;