/* 13 functions; only on fridays... *\ \* HAVE FUN WITH MUCH PSEUDO CODE */ #include #include #include #include #include #include //#include #include #include #include /* I hate declarations... */ void debug(uint i) { fprintf(stderr,"[<3--6>] -69- [%d]\n\n",i); exit(13); } #define MAS 512 #define PAT 256 #define BUF 256 #define DP (uint)(sizeof(uint)*8) #define DEX (uint)((MAS+DP-1)/DP) /* I hate declarations... */ #define strsize(S) (snprintf(NULL,0,"%s",S)) #define D(i) (debug(i)) #define P(p) (pet[sdex(p)]) #define PT(p) (P(p).r) #define PC(p) (P(p).c) #define PB(p) (P(p).b[PC(p)]) #define PE(p) (P(p).e) #define Fin(b) (fread(b,sizeof(b[0]),sizeof(b),stdin)) typedef struct { u_char r; /* 0 inactive 1,2,3 active PET states : 1 new search 2,3 continue search : 2 joined strings 3 begin long-search : 4 :2+ sdex() return next 5 :3+ sdex() return next 6 :3+ at end. (without pattern-matching) :1+ */ u_char c; /* 0,ff current position here */ u_char e; /* 0,ff end (char b[]) at character n... */ u_char b[PAT]; } Pet; /* I hate pseudo-structuring... */ /* I very much dislike static(al) structures; which do not change based on state and usage... */ FILE *fy,*fn; Pet *pet; uint pta=0; uint ptb=0; /*backup*/ uint max=4096; u_char *dir; uint dlen; uint64_t fp=0; /* I hate declarations... */ uint64_t pu=0; uint *dex; /* logics array for indexing the start of search-sets see patdex(), sdex(x) and rdex(x). */ uint *bex; /* to backup dex, because of rdex(x). */ void candleout() { fprintf(fy," (end 0x%lx)\n",pu); fclose(fy); fclose(fn); } void panic(u_char *s) { fprintf(stderr,"[error] %s\n",s); } void usage(int h) { if (! h) { fprintf(stderr,"spine: ask -?, -h for help from me...\n"); return; } printf("spine [OPTION]... DIR PATTERN...\n\ DIR directory to create (must not exist)\n\ PATTERN\n\ A pattern consists of the symbols\n\ 0123456789AaBbCcDdEeFf\n\ to tell of the things expected in succession.\n\ A '.' means to start a long-search.\n\ \n\ Options:\n\ -l NUM\n\ limit search to NUM bytes.\n\ (default: 4096)\n\ \n\ Hints:\n\ A search starts when the first pattern\n\ before a '.' is found.\n\ Until a search is complete, no other\n\ patterns except those, who are to follow\n\ the currently searched ones are evaluated.\n\ If all the patterns of a search-string are found,\n\ the filename is written to 'found'.\n\ If a search is terminated by EOF or by limit,\n\ the filename is written to 'broken'.\n\ In both inventory files, occurrences are to be\n\ labeled with the first search-set index they do\n\ resemble (... partly, if broken by limit or EOF).\n\ \n\ Bugs:\n\ There is a hardcoded limit on possible PETs.\n\ Change definition of 'MAS' and 'PAT' in the sources...\n\ Default is:\n\ 512 active PET-instances,\n\ 256 8-bit patterns each.\n\ It doesn't matter if you search for one very long\n\ pattern which is saved in continuated PETs\n\ or many smaller patterns...\n\ Eventually they both add up in memory.\n\ Try to run the program multiple times and,\n\ reduce pattern-length if they do overflow,\n\ Of course you could try modifying this program\n\ like me; and burn your unstable mind in chaos\n\ because of C's terror-syntax...\n\ Be warned however; making the buffers and integers\n\ bigger never solved even one problem.\n"); } void dbg_dex() { uint p=DEX-1; uint i=0; fprintf(stderr,"[debug] dex\n "); p=0; while (p0) j=j*16; j=j+x; i++; } while (s[i]) { if (s[i]>0x2f && s[i]<0x3a) { ij(s[i]-0x30); continue; } switch(s[i]) { case 'A': case 'a': ij(10); continue; case 'B': case 'b': ij(11); continue; case 'C': case 'c': ij(12); continue; case 'D': case 'd': ij(13); continue; case 'E': case 'e': ij(14); continue; case 'F': case 'f': ij(15); continue; default: fprintf(stderr,"[digga], '%c' is'och net a hexl.\n",s[i]); exit(1); } } return(j); } void smax(u_char *s) { uint i=0; max=0; void imax(uint x) { if (i>0) max=max*10; max=max+x; i++; } while (s[i]) { if (s[i]>0x2f && s[i]<0x3a) { imax(s[i]-0x30); } else { fprintf(stderr,"[alder], '%s' is'ne falsche zahl.\n",s); exit(1); } } } void ipet(u_char r, u_char e) { if (pta==MAS) { fprintf(stderr,"[error] active pets: [%d] overflow.\n", MAS); exit(1); } pet[pta].r=r; pet[pta].e=e; pta++; if (pta==0) { panic("petpointer: buffer overflow.\n"); exit(1); } } void adpet(u_char *s) { u_char l[3]; l[2]=0; u_char c=0; u_char e=0; uint i=0; if (s[i]=='.') { panic("starting with '.'... (think of what to expect now?)"); exit(1); } while (s[i]) { l[0]=s[i];i++; switch(l[0]) { case '.': if (s[i]=='.') { panic("duplicated '.'... (lonely search:length addition not possible here...)"); exit(1); } else if (s[i]==0) { /* '.' at end. */ ipet(6,e-1); } else { ipet(3,e-1); } e=0; break; default: l[1]=s[i];i++; if (l[1]==0) { fprintf(stderr,"[error] '%c' only double-hex turns to byte.\n",l[0]); exit(1); } c=hex(l); pet[pta].b[e]=c; if (s[i]==0) { ipet(1,e); return; } else if ((e+1)%PAT==0) { if (s[i]=='.') { continue; } else { ipet(2,e); } } e++; } } } void petdex() { uint p=0; uint g=0; uint i=1; uint j=1; u_char t=0; pta=0; if (pet[0].r>0) dex[0]=1; while (p0) || (pet[i+(p*DP)].r==1 && pet[j+(g*DP)].r>0)) { t=1; } if (t==1) { pta++; dex[p]=dex[p]|(1<pta) { panic("internal sdex(x) > pta..."); exit(1); } while (1) { if (dex[p]>0) break; p++; if (p==DEX) { panic("internal sdex(x): no active pets"); exit(1); } } while (p%u,r:%u)\n",i+(p*i),y,pet[y].r); exit(1); } } } else x--; } i++; y++; y=y%MAS; } p++; i=0; } } uint sdex2(uint x) /* because C is dumb little shit, or because I am just too dumb!!!! probably the latter (some very clever people do C every day, and I wonder why they think all of this is necessary...) */ { uint p=0; uint i=0; uint y=0; if (x>pta) { panic("internal sdex(x) > pta..."); exit(1); } while (1) { if (dex[p]>0) break; p++; if (p==DEX) { panic("internal sdex(x): no active pets"); exit(1); } } while (p%u,r:%u)\n",i+(p*i),y,pet[y].r); exit(1); } } } else x--; } i++; y++; y=y%MAS; } p++; i=0; } } void xdex(uint x) { uint p=0; uint i=x%DP; while (p=MAS) { panic("internal rdex(x) > MAS..."); exit(1); } if (dex[p]&(1<u_char *c."); exit(1); } FILE *f; uint bs; u_char bp=0; u_char b[BUF]; u_char s=0; /* 0 no search (remove file) 1 active search (broken) 2 finished search (found) 3 PT()==6 long for end (found) */ uint sa=0;/* sdex(x) x:address */ uint sb=0; u_char * spath(u_char *c, u_char *a, u_char *b) { #ifdef WIN32 snprintf(c,dlen,"%s\\%s",a,b); #else snprintf(c,dlen,"%s/%s",a,b); #endif return(c); } u_char * ifile(u_char *c, uint64_t i) { snprintf(c,dlen,"%016lx",i); return(c); } u_char * ipath(u_char *c, u_char *a, uint64_t i) { #ifdef WIN32 snprintf(c,dlen,"%s\\%016lx",a,i); #else snprintf(c,dlen,"%s/%016lx",a,i); #endif return(c); } void ipu() { pu++; if (pu==0) { fprintf(stderr," [offset overflow] +16EiB"); } return; } void bread() { bs=Fin(b); } void incb() { ipu(); bp++; if (bp%bs==0) { bp=0; if (bs!=0) bread(); } } void fink(uint i) { fclose(f); if(i==0) remove(ipath(c,dir,fp)); fp=fp+i; f=fopen(ipath(c,dir,fp),"wb"); } void done(uint i) { if (i==0) { fprintf(fn,"%s %u,%lx\n",ifile(c,fp),sb,pu); fprintf(stderr,"+%s (broken): %u,%lx\n",ifile(c,fp),sb,pu); fink(1); s=2; } else if (i==1) { fprintf(fy,"%s %u,%lx\n",ifile(c,fp),sb,pu); fprintf(stderr,"+%s (found): %u,%lx\n",ifile(c,fp),sb,pu); fink(1); s=2; } else if (i==2) { bp--; fprintf(fy,"%s %u,%lx\n",ifile(c,fp),sb,pu); fprintf(stderr,"+%s (found): %u,%lx\n",ifile(c,fp),sb,pu); s=2; } } void identify(uint x) { /*fprintf(stderr," %c:%u",b[bp],x); /**/ /*fprintf(stderr,"t.%u ",PT(x)); /**/ /*fprintf(stderr,"[%d %d]",PC(x),PE(x)); /**/ if (PC(x)==PE(x)) { /*fprintf(stderr,"u:%u\n",sb); /**/ if (PT(x)==1) { done(1); } else if (PT(x)==3) { s=1; xi=0; } else if (PT(x)==6) { s=3; xi=0; } petit(sdex(x)); if (s==1) { sb=sb+x; xdex(sdex(x)); } } else { PC(x)++; } } void work() { if (s==1||s==3) { xi++; if (xi==0) { panic("search()->xi overflow?!"); exit(1); } fputc(b[bp],f); if (s==3) { if (xi>max) done(1); return; } if (PB(0)==b[bp]) { identify(0); } else { if (xi>max) done(0); } } else if (PB(sa)==b[bp]) { fputc(b[bp],f); identify(sa); } else if (pta>0) { sb++; rdex(sdex(sa)); } else { fink(0); rvsx(); sb=0; s=0; } } freopen(NULL,"rb",stdin); fy=fopen(spath(c,dir,"found"),"w"); fprintf(fy,"FILE PARAM,FILE-OFFSET\n"); fn=fopen(spath(c,dir,"broken"),"w"); fprintf(fn,"FILE PARAM,FILE-OFFSET\n"); /*dbg_pet(1); dbg_pet(2); /**/ /*dbg_pet(0); dbg_dex(); fprintf(stderr,"sdex(0): %d\nsdex(1): %d\n",sdex(0),sdex(1)); /**/ /*rdex(sdex(1)); sdex(1); /**/ f=fopen(ipath(c,dir,fp),"wb"); bread(); while (bs) { if (s==2) { sb=0; s=0; rvsx(); } /*fprintf(stderr,"%u,%u:",(uint)s,pta); /**/ if (s==1||s==3) { work(); } else { sa=0; while (sa<=pta) { work(); if (s==0) sa++; else break; } } incb(); } if (s==3) { done(2); } fclose(f); if (s==0) remove(ipath(c,dir,fp)); if (s==1) { fprintf(fn,"%s ?\n",ipath(c,dir,fp)); fprintf(stderr,"+%s (broken)\n",ifile(c,fp)); } } void main(int argc, u_char **argv) { struct sigaction sig; sig.sa_handler=candleout; struct stat sm; u_char opt=1; uint i=0; u_char t=0; if (pet=malloc(sizeof(Pet)*MAS)) { } else { panic("malloc: pet failed."); exit(1); } if (dex=malloc(sizeof(dex)*DEX)) { } else { panic("malloc: dex failed."); exit(1); } if (bex=malloc(sizeof(dex)*DEX)) { } else { panic("malloc: bex failed."); exit(1); } while (i