text: /* radare - LGPL - Copyright 2006-2019 - esteve, pancake */
  
  #include <r_search.h>
  #include <r_util.h>
  #include <r_util/r_print.h>
  
  #define CTXMINB 5
  #define BSIZE (1024*1024)
  #define MAX_PATLEN 1024
  
  typedef struct _fnditem {
  	unsigned char str[MAX_PATLEN];
  	void* next;
  } fnditem;
  
  static fnditem* init_fi(void) {
  	fnditem* n;
  	n = (fnditem*) malloc (sizeof (fnditem));
  	if (!n) {
  		return NULL;
  	}
  	n->next = NULL;
  	return n;
  }
  
  static void fini_fi(fnditem* fi) {
  	fnditem *fu;
  	fu = fi;
  	while (fi->next) {
  		fu = fi;
  		fi = fi->next;
  		free (fu);
  		fu = NULL;
  	}
  	free (fu);
  }
  
  static void add_fi (fnditem* n, unsigned char* blk, int patlen) {
  	fnditem* p;
  	for (p = n; p->next != NULL; p = p->next) {
  		;
  	}
  	p->next = (fnditem*) malloc (sizeof (fnditem));
  	p = p->next;
  	memcpy (p->str, blk, patlen);
  	p->next = NULL;
  }
  
  static int is_fi_present(fnditem* n, unsigned char* blk , int patlen) {
  	fnditem* p;
  	for (p = n; p->next != NULL; p = p->next) {
  		if (!memcmp (blk, p->str, patlen)) {
  			return true;
  		}
  	}
  	return false;
  }
  
  R_API int r_search_pattern(RSearch *s, ut64 from, ut64 to) {
  	ut8 block[BSIZE+MAX_PATLEN], sblk[BSIZE+MAX_PATLEN+1];
  	ut64 addr, bact, bytes, intaddr, rb, bproc = 0;
  	int nr,i, moar=0, pcnt, cnt = 0, k = 0;
  	int patlen = s->pattern_size;
  	fnditem* root;
  
  	eprintf ("Searching patterns between 0x%08"PFMT64x" and 0x%08"PFMT64x"\n", from, to);
  	if (patlen < 1 || patlen > MAX_PATLEN) {
  		eprintf ("Invalid pattern length (must be > 1 and < %d)\n", MAX_PATLEN);
  		return false;
  	}
  	bact = from;
  	bytes = to;
  	//bytes += bact;
  	root = init_fi ();
  	pcnt = -1;
  
  // bact = from
  // bytes = to
  // bproc = from2
  	while (bact < bytes) {
  		addr = bact;
  		if (r_print_is_interrupted ()) {
  			break;
  		}
  
  		bproc = bact + patlen ;
  //		read ( fd, sblk, patlen );
  //XXX bytepattern should be used with a read callback
  		nr = ((bytes - bproc) < BSIZE)?(bytes - bproc):BSIZE;
  	//XXX	radare_read_at(bact, sblk, patlen);
  		rb = s->iob.read_at (s->iob.io, addr, sblk, nr);
  		sblk[patlen] = 0; // XXX
  
  		intaddr = bact;
  		cnt = 0;
  		while (bproc < bytes) {
  			// TODO: handle ^C here
  			nr = ((bytes - bproc) < BSIZE)?(bytes - bproc):BSIZE;
  			nr += (patlen - (nr % patlen)); // tamany de bloc llegit multiple superior de tamany busqueda
  			rb = s->iob.read_at (s->iob.io, bproc, block, nr);
  			if (rb < 1) {
  				break;
  			}
  			nr = rb;
  			addr += nr;
  			moar = 0;
  			for (i = 0; i<nr; i++) {
  				if (!memcmp (&block[i], sblk, patlen) && !is_fi_present (root, sblk, patlen)){
  					if (cnt == 0) {
  						add_fi (root, sblk, patlen);
  						pcnt++;
  						eprintf ("\nbytes: %d: ", pcnt);
  						for (k = 0; k < patlen; k++) {
  							eprintf ("%02x", sblk[k]);
  						}
  						eprintf ("\nfound: %d: 0x%08"PFMT64x" ", pcnt, intaddr);
  					}
  					moar++;
  					cnt++;
  					eprintf ("0x%08"PFMT64x" ", bproc+i);
  				}
  			}
  			if (moar > 0) {
  				eprintf ("\ncount: %d: %d\n", pcnt, moar + 1);
  			}
  			bproc += rb;
  		}
  		bact += (moar > 0)? patlen: 1;
  	}
  	eprintf ("\n");
  	fini_fi (root);
  	return 0;
  }
  