viric@0: #include viric@0: #include viric@0: #include viric@0: #include viric@0: #include viric@0: #include viric@2: #include viric@0: viric@0: #include "dictre.h" viric@0: viric@1: enum viric@1: { viric@3: SIZESTEP=1000 viric@1: }; viric@1: viric@0: extern struct Def defs[]; viric@0: extern int ndefs; viric@0: extern int dont_touch[]; viric@0: extern int ndont_touch; viric@0: viric@0: static void more_memory(void **ptr, int size) viric@0: { viric@0: void *new; viric@0: viric@0: new = realloc(*ptr, size); viric@0: *ptr = new; viric@0: } viric@0: viric@0: static viric@0: char * manage_filter(const char *def, int deflen, int writeto, int readfrom, viric@0: int *outlen) viric@0: { viric@0: int maxfd; viric@0: int defptr; viric@0: int outptr; viric@0: char *out; viric@0: int outsize; viric@0: int outrest; viric@2: int res; viric@0: viric@0: out = 0; viric@1: outsize = SIZESTEP; viric@0: outptr = 0; viric@0: more_memory((void **) &out, outsize); viric@1: outrest = SIZESTEP; viric@0: viric@2: /* We need unblocking write for select() */ viric@2: res = fcntl(writeto, F_SETFL, O_NONBLOCK); viric@2: if (res == -1) viric@2: { viric@2: perror("Error setting nonblock to writeto"); viric@2: exit(-1); viric@2: } viric@2: viric@0: maxfd = writeto; viric@0: if (readfrom > maxfd) viric@0: maxfd = readfrom; viric@0: viric@0: defptr = 0; viric@0: do viric@0: { viric@0: fd_set writeset, readset; viric@0: FD_ZERO(&writeset); viric@0: FD_ZERO(&readset); viric@0: if (defptr < deflen) viric@0: FD_SET(writeto, &writeset); viric@0: FD_SET(readfrom, &readset); viric@0: viric@0: select(maxfd+1, &readset, &writeset, 0, 0); viric@0: viric@0: if (FD_ISSET(readfrom, &readset)) viric@0: { viric@0: int res; viric@0: res = read(readfrom, out + outptr, outrest); viric@0: if (res == 0) viric@0: { viric@0: close(readfrom); viric@0: break; viric@0: } viric@0: outrest -= res; viric@0: outptr += res; viric@0: if (outrest == 0) viric@0: { viric@1: outrest = SIZESTEP; viric@1: outsize += SIZESTEP; viric@0: more_memory((void **) &out, outsize); viric@0: } viric@0: } viric@0: viric@0: if (FD_ISSET(writeto, &writeset)) viric@0: { viric@0: int res; viric@1: res = write(writeto, def+defptr, deflen - defptr); viric@1: defptr += res; viric@0: if (defptr >= deflen) viric@0: close(writeto); viric@0: } viric@0: } while(1); viric@0: viric@2: /* viric@2: { viric@2: int i; viric@2: printf("In : "); viric@2: for(i=0; i < deflen; ++i) viric@2: putchar(def[i]); viric@2: printf("\nOut: "); viric@2: for(i=0; i < outptr; ++i) viric@2: putchar(out[i]); viric@2: putchar('\n'); viric@2: } viric@2: */ viric@2: viric@0: if (defptr < deflen) viric@0: { viric@0: fprintf(stderr, "Error in filter! not all written.\n"); viric@0: exit(-1); viric@0: } viric@0: viric@3: /* Give away memory don't needed */ viric@3: more_memory((void **) &out, outptr); viric@3: viric@0: *outlen = outptr; viric@0: return out; viric@0: } viric@0: viric@0: static char * filter(char *def, int deflen, const char *filter_par, int *outlen) viric@0: { viric@0: int write_pipe[2]; viric@0: int read_pipe[2]; viric@0: int pid; viric@0: int res; viric@0: int status; viric@0: char *out; viric@0: viric@0: pipe(write_pipe); viric@0: pipe(read_pipe); viric@0: viric@0: viric@0: pid = fork(); viric@0: switch(pid) viric@0: { viric@0: case 0: /* child */ viric@0: close(0); viric@0: dup(write_pipe[0]); viric@0: close(write_pipe[0]); viric@0: close(write_pipe[1]); viric@0: close(1); viric@0: dup(read_pipe[1]); viric@0: close(read_pipe[1]); viric@0: close(read_pipe[0]); viric@2: execl(filter_par, filter_par, 0); viriketo@31: perror("execl"); viric@0: exit(-1); viric@0: break; viric@0: case -1: viric@0: perror("fork"); viric@0: exit(-1); viric@0: break; viric@0: default: /* parent */ viric@0: close(write_pipe[0]); viric@0: close(read_pipe[1]); viric@0: break; viric@0: } viric@0: viric@0: /* parent */ viric@0: out = manage_filter(def, deflen, write_pipe[1], read_pipe[0], outlen); viric@0: viric@0: res = wait(&status); viric@0: if (res != pid || WEXITSTATUS(status) != 0) viric@0: { viric@0: fprintf(stderr, "Error filtering: pid=%i status=%i", viric@0: pid, WEXITSTATUS(status)); viric@0: exit(-1); viric@0: } viric@0: viric@0: return out; viric@0: } viric@0: viric@0: static int in_dont_touch(int n) viric@0: { viric@0: int i; viric@0: for(i =0; i < ndont_touch; ++i) viric@0: { viric@0: if (n == dont_touch[i]) viric@0: { viric@0: return 1; viric@0: } viric@0: } viric@0: return 0; viric@0: } viric@0: viric@0: void filter_all(const char *filter_par) viric@0: { viric@0: int i; viric@2: static int dispndefs = 0; viric@2: static int filtereddefs = 0; viric@0: viric@0: for(i=0; i < ndefs; ++i) viric@0: { viric@0: char *newdef; viric@0: int newdeflen; viric@0: if (!in_dont_touch(i)) viric@0: { viric@1: if (defs[i].length > 0) viric@1: { viric@1: newdef = filter(defs[i].d, defs[i].length, viric@1: filter_par, &newdeflen); viric@1: defs[i].length = newdeflen; viric@1: free(defs[i].d); viric@1: defs[i].d = newdef; viric@1: } viric@2: filtereddefs++; /* Not really all filtered. All but the 00-database* */ viric@2: dispndefs++; viric@3: if (dispndefs >= 1000) viric@2: { viric@2: dispndefs = 0; viric@3: printf("Filtered: %i/%i (%f%%)\n", filtereddefs, ndefs, viric@4: (float) filtereddefs / (float) ndefs * 100.); viric@2: } viric@0: } viric@0: } viric@0: }