/* String - Extract Ascii strings from a file. Base on the 'Strings' UNIX port by Egidio Casiraghi published in MC-Microcumputer 84, April 1989. Many enhancements by Fabio Rossetti: resident, wildcards, BANNER switch. (c) 1989 by Fabio Rossetti To compile under Lattice C v5.0x use: lc -O -cus -v string blink lib:cres.o string.o to string lib lib:a.lib lib:lc.lib sd nd */ #include #include #include #include #include #include #include #include #include #define START 1 #define ALPHA 2 #define BUFSIZE 512 #define FROM argv[0] #define MIN argv[1] #define BANNER argv[2] STRPTR argv[3]; struct ArpBase *ArpBase; struct UserAnchor { struct AnchorPath ua_AP; BYTE moremem[255]; /* extension */ }; struct UserAnchor *Anchor; /* These must be global because of shutdown on ^C */ TEXT *buffer=NULL; BPTR fh; TEXT Banner[256]; struct Process *Pr; ULONG count; LONG minlen; /* Delete Lattice func to keep down code size */ VOID MemCleanup() { } VOID Cleanup(r1,r2,msg) LONG r1,r2; STRPTR msg; { if (msg) Puts(msg); if (buffer) FreeMem(buffer,BUFSIZE); if (Anchor) FreeAnchorChain((struct AnchorPath *)Anchor); if (ArpBase) CloseLibrary((struct Library *)ArpBase); Pr->pr_Result2 = r2; exit(r1); } /* This is the real work, a buffer with a segment of the file being examinated is scanned for strings */ BOOL strings(buf,len,minlen) LONG len; LONG minlen; TEXT *buf; { REGISTER LONG k,n; REGISTER TEXT *start,c; REGISTER LONG status; status=START; for(k=0;k<(LONG)len;k++) { c=buf[k]; switch (status) { case START: if(c<32 || c >125) break; status=ALPHA; start=buf+k; n=1; break; case ALPHA: if(c>31 && c<126) { n++; break; } if((long)n>=minlen) { buf[k]='\0'; Printf("%s\n",start); /* Check for ^C */ if (SetSignal(0,0) & SIGBREAKF_CTRL_C) Cleanup(RETURN_WARN,NULL,"***BREAK"); if (CheckBreak(SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F,NULL)) { Puts("***WARN: file read abort"); return(TRUE); } } status=START; break; } } return (FALSE); } VOID Scan(filh) BPTR filh; { /* print banner, if requested */ if (BANNER) { PathName(ArpLock(Anchor->ua_AP.ap_Buf),Banner,255); Printf("*** File %s ***\n", Banner);} for (;;) { count=Read(filh,buffer,BUFSIZE); if ((!count) || (strings(buffer,count,minlen))) break; } } VOID _main(Line) STRPTR Line; { LONG Result,fl; ULONG argc; Pr = (struct Process*)FindTask(NULL); if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion))){ Cleanup(RETURN_FAIL,ERROR_INVALID_RESIDENT_LIBRARY,NULL); } /* parse command line */ for (argc=0;argc < 3;++argc) argv[argc] = (STRPTR) NULL; while(*Line > ' ') ++Line; if (GADS(++Line, strlen(Line), "\nUsage: String FROM pattern [MIN=M minlenght] [BANNER=B]\n", argv, "FROM,MIN=M/K,BANNER=B/S") <= 0) Cleanup(RETURN_WARN,NULL,argv[0]); /* Set minimum lenght of strings to be displayed */ if((minlen=Atol(MIN))<=0) minlen=4; if(!(buffer=(TEXT *)AllocMem(BUFSIZE,MEMF_CLEAR|MEMF_PUBLIC))) Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error: no memory"); /* Allocate space for anchorpath */ if ( Anchor = (struct UserAnchor *)ArpAlloc( (ULONG)sizeof( *Anchor )) ) { Anchor->ua_AP.ap_Length = 255; /* Want full path built */ } else Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error:No memory"); /* Looks for files matching pattern */ Result = FindFirst(argv[0],(struct AnchorPath*) Anchor); fl=-1; while ( Result == 0 ) { fl = 0; /* Get file if it is not a directory block */ if (Anchor->ua_AP.ap_Info.fib_DirEntryType < 0) { fh=ArpOpen(Anchor->ua_AP.ap_Buf,MODE_OLDFILE); Scan(fh); } Result = FindNext((struct AnchorPath*) Anchor ); } /* This in case a pattern with no matches is given */ if ((Result == ERROR_OBJECT_NOT_FOUND) || ((Result == ERROR_NO_MORE_ENTRIES) && fl) ) Cleanup(RETURN_ERROR,ERROR_OBJECT_NOT_FOUND,"Error:Can't get file"); /* if no FROM , look into stdin */ Cleanup(NULL,NULL,NULL); }