home *** CD-ROM | disk | FTP | other *** search
- /*
-
- LookFor Version 1.0
- Copyright © 1989 by Ray Lambert
- Created by Ray Lambert
-
- Searches for the specified string (either ASCII or HEX) in
- the specified file(s) and displays absolute offset in
- file where string is located, and approximate line number.
-
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <libraries/dos.h>
- #include <exec/memory.h>
- #include <proto/exec.h>
-
- #define FALSE 0
- #define TRUE 1
- #define iswhite(c) (((c)=='\t')||((c)==' '))
-
- unsigned char /* global switches */
- hex_search=FALSE,
- ignore_case=FALSE,
- text_mode=FALSE;
-
- int
- count,
- bytes; /* number of bytes in search string */
-
- unsigned int
- line,
- j,
- size;
-
- char
- path[255],
- name[255],
- orig_pattern[100],
- pattern[100];
-
- char *buf=NULL;
-
- struct FileInfoBlock *info;
-
- FILE *f;
-
- extern int msflag;
-
- /** ********* **/
-
- void clean_exit(char *message, int xcode)
- {
- if (buf) FreeMem(buf,size);
- if (info) FreeMem(info,sizeof(struct FileInfoBlock));
- if (message) printf("\n%s\n",message);
- printf("\n");
- exit(xcode);
- }
-
- /** ********* **/
-
- void make_hex(char *S)
- {
- char lookup[] = "0123456789ABCDEF";
- int cnt=1; /* indexes characters in S */
- int i; /* \ Used in building */
- int n; /* / Hex bytes */
-
- strupr(S);
-
- for(j=0; S[cnt]; j++)
- {
- if (!isxdigit(S[cnt]))
- clean_exit("\23333mInvalid digit in Hex String\2330m",5);
- i=0; /* Get first digit */
- while( (i<16) && (S[cnt]!=lookup[i]) ) i++;
- n=(i<<4);
- cnt++;
- if (S[cnt]) /* Get second digit */
- {
- i=0;
- while( (i<16) && (S[cnt]!=lookup[i]) ) i++;
- n|=i;
- orig_pattern[j]=(char)n;
- cnt++;
- }
- }
-
- orig_pattern[j]='\0';
- hex_search=TRUE;
- }
-
- /** ********* **/
-
- void get_buffer()
- {
- size=0x20000;
-
- info=AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
- if (!info)
- {
- clean_exit("\23333mInsufficient memory!\nLookFor halted.\2330m",21);
- }
-
- do
- {
- buf=(char *)AllocMem(size,MEMF_CLEAR);
- if (!buf)
- {
- size-=0x0400;
- if (size<0x0400)
- {
- clean_exit("\23333mInsufficient memory!\nLookFor halted.\2330m",21);
- }
- }
- }
- while(!buf);
- }
-
- /** ********* **/
-
- void extract_path(char *n)
- {
- register char *c=path;
-
- strcpy(path,n);
- c+=(strlen(c)-1);
- while( (c>path) && (*c!='/') && (*c!=':') ) c--;
- if (c<=path)
- {
- *path='\0';
- }
- else
- {
- c++;
- *c='\0';
- }
- }
-
- /** ********* **/
-
- void set_msflag(char *n)
- {
- while(*n)
- {
- if (*n=='*')
- {
- msflag=1;
- return;
- }
- n++;
- }
- msflag=0;
- }
-
- /** ********* **/
-
- int match(char *wild)
- {
- int status;
-
- if (name[0]=='\0') /* find first */
- {
- extract_path(wild);
- set_msflag(wild);
- status=dfind(info,wild,1);
- if (status) printf("\nNo match for: '%s'\n",wild);
- }
- else /* find next */
- {
- skipdir:
- status=dnext(info);
- }
-
- if (status==0)
- {
- if (info->fib_DirEntryType > 0) /* a directory */
- {
- goto skipdir;
- }
- strcpy(name,path);
- strcat(name,info->fib_FileName);
- }
- return(!status);
- }
-
- /** ********* **/
-
- #define LINE_LEN 50 /* maximum length of line of text that can be printed */
-
- void print_line(char *line, char *match)
- {
- int lead=((LINE_LEN-bytes)>>1);
- char *c=(match-lead);
- char str[LINE_LEN+1];
- int cnt=0; /* count of characters that have been placed in string */
-
- if (c<line) c=line;
- line=str;
-
- while(iswhite(*c)) c++; /* strip leading white space */
-
- while( (cnt<=LINE_LEN) && (*c) && (*c!='\n') )
- {
- if (isprint(*c))
- {
- *line=*c;
- line++;
- cnt++;
- }
- c++;
- }
- *line='\0';
-
- printf("\"%s\"\n",str);
- }
-
- /** ********* **/
-
- char search()
- {
- unsigned long int pos; /* actual file position at read-time */
- unsigned long int temp; /* used to calculate offset for report */
- unsigned int red; /* holds number of bytes read by Read() */
- char *top; /* last byte to search at */
- char *P; /* used to scan the buffer */
- char test; /* the actual byte from the file to test */
- char firsttime=TRUE; /* flag for error conditions */
- char *lastline; /* tracks beginning of text line for printing */
-
- strcpy(pattern,orig_pattern);
- if (ignore_case) strupr(pattern);
-
- line=1;
- count=0;
- pos=0;
-
- do
- {
- if (pos>0) fseek(f,pos,0);
- red=fread(buf,1,size,f);
- if (red<1)
- {
- if (firsttime) /* couldn't read on first try - error */
- {
- return(FALSE);
- }
- else /* reached EOF */
- {
- return(TRUE);
- }
- }
-
- firsttime=FALSE;
- top=buf+(red-(bytes-1));
- P=buf;
-
- do
- {
- test=(ignore_case)?toupper(*P):*P;
-
- /* scan for match of first character */
- while( (test!=pattern[0]) && (P<=top) )
- {
- if (*P=='\n')
- {
- line++;
- lastline=(P+1);
- }
- P++;
- test=(ignore_case)?toupper(*P):*P;
- }
-
- /* first character matches - now check rest of pattern */
- if (P<=top)
- {
- j=0;
- do
- {
- j++;
- test=(ignore_case)?toupper(*(P+j)):*(P+j);
- }
- while( (test==pattern[j]) && (j<bytes) );
-
- if (j>=bytes) /* found a match! */
- {
- count++;
- temp=(pos+((unsigned long int)P-(unsigned long int)buf));
- printf(" Found match at offset %07lu ($%06lX)\n",temp,temp);
- if (text_mode)
- {
- printf(" Line #%u: ",line);
- print_line(lastline,P);
- }
- }
-
- P++;
- }
- }
- while(P<=top);
- pos+=(size-(bytes-1));
- }
- while(red==size);
- return(TRUE);
- }
-
- /** ********* **/
-
- void usage()
- {
- printf("\n\2333mUsage:\2330m LookFor SEARCHSTRING [OPTIONS ] FILE [FILE...]\n");
- printf("\n All command-line arguments must be seperated by at least one\n");
- printf(" space character. Arguments which contain spaces must be\n");
- printf(" enclosed in quotes.\n");
- printf("\n SEARCHSTRING: can be ASCII, eg. \"This is an ASCII string\"\n");
- printf(" or HEX, eg. $1A2B3C4D5E6F\n");
- printf("\n OPTIONS: May be mixed between filenames.\n");
- printf(" Options are turned ON if they are prefixed with a '+' (plus)\n");
- printf(" and are turned OFF if prefixed with a '-' (minus)\n");
- printf(" Current valid options are:\n");
- printf(" +I Ignore case ON (HEX searches are always case sensitive)\n");
- printf(" -I Ignore case OFF (This is the default)\n");
- printf(" +T Text mode ON (Report matched line # and line)\n");
- printf(" -T Text mode OFF (This is the default)\n");
- printf("\n FILE: Multiple complete filenames are allowed and each may\n");
- printf(" contain either AmigaDOS or MS-DOS wildcards.\n");
- clean_exit(NULL,5);
- }
-
- /** ********* **/
-
- void process_switch(char *sw)
- {
- switch(sw[0])
- {
- case '-':
- {
- switch(toupper(sw[1]))
- {
- case 'I':
- {
- ignore_case=FALSE;
- break;
- }
- case 'T':
- {
- text_mode=FALSE;
- break;
- }
- }
- break;
- }
- case '+':
- {
- switch(toupper(sw[1]))
- {
- case 'I':
- {
- ignore_case=TRUE;
- break;
- }
- case 'T':
- {
- text_mode=TRUE;
- break;
- }
- }
- break;
- }
- }
- }
-
- /** ********* **/
-
- void main(int argc,char *argv[])
- {
- int cnt=2;
- printf("\n\23333m\2333mLookFor\2330m\23332m Copyright © 1989 by Ray Lambert\n");
- printf(" Created by Ray Lambert\2330m\n");
-
- if (argc<3) usage();
-
- if (argv[1][0]=='$')
- {
- make_hex(argv[1]);
- }
- else
- {
- strcpy(orig_pattern,argv[1]);
- }
-
- bytes=strlen(orig_pattern);
-
- get_buffer(); /* allocate work buffer */
-
- do /* search loop */
- {
- if ( (argv[cnt][0]=='-') || (argv[cnt][0]=='+') )
- {
- process_switch(argv[cnt]);
- continue;
- }
-
- name[0]='\0'; /* initialize global search name (flag a findfirst) */
-
- while(match(argv[cnt]))
- {
- f=fopen(name,"rt");
- if (f)
- {
- printf("\nSearching file: '%s'\n",name);
- if (!search())
- {
- printf(" \23333mCan't read this file!\2330m\n");
- }
- else
- {
- switch(count)
- {
- case 0:
- {
- printf("No matches found\n");
- break;
- }
- case 1:
- {
- printf("One match found\n");
- break;
- }
- default:
- {
- printf("%d matches found in file: '%s'\n",count,name);
- break;
- }
- }
- }
- fclose(f);
- }
- else
- {
- printf("\n\23333mError opening file: '%s'\2330m\n",name);
- }
- }
- }
- while((++cnt)<argc);
-
- clean_exit("All files searched.",0);
- }
-
-