
#include <ctype.h>
#include <stdio.h>
#define MAXFSIZE 40 /* max chars in filename */
  char infile[MAXFSIZE], outfile[MAXFSIZE]; /* global storage */
  FILE *source, *destination;                         /* files */
  char old[52],new[52],origold[52],orignew[52];
  int verbose;
  long nc,nl,nr;
main(argc,argv)
int argc;
char *argv[];
{
    int c = 1;
    char verbuffer[5];
    verbose = 0;
    if(argc == 6)
      verbose = 1;
    if(argc == 5 || argc == 6)  
     {
      strcpy(infile,argv[1]); 
      strcpy(outfile,argv[2]); 
      strcpy(origold,argv[3]); 
      strcpy(orignew,argv[4]); 
      if(!strcmp(infile,outfile))
        exit(0);
     } 
    else  
     {
    if(argc != 1) 
     {
       printf("filefix v01 D. Wahl 3/3/88\n");
       printf("General search and replace routine.\n");
       printf("Replace any occurance of 1 - 40 chars\n");
       printf("with 0 - 40 others. You may use a '[n]'\n");
       printf("to force a newline, [aa] as hex string.\n");
       printf("filefix [in_file out_file search_for replace_with] [verbose[y]]\n");
       printf("Some common hex values:\n");
       printf("[20] = space, [0a] = lf, [0d] = cr, [22] = \", [30] = *\n");
       printf("[1b] = esc\n");
     }  
    do {
         if (c == 0)
     {  printf("      Input source and destination file names\n");
        printf("           file names cannot be the same\n"); }
       }
    while ((c = get_file_names(&infile[0], &outfile[0] )) == 0);
    c = 1;
    do {
         if (c == 0)
           printf("Search and replace strings cannot match\n");
       }
    while ((c = get_match_strings(origold,orignew)) == 0);
    printf("Verbose option (y/n) ? ");
    fgets(verbuffer,3,stdin);
    if(verbuffer[0] != 'y')
       verbose = 0;
    else   
       verbose = 1;
     } /* end else */  
    open_files(&infile[0], &outfile[0] );
    parse_string(origold,old);
    parse_string(orignew,new);
    process_file(old,new);
    printf("Replaced \"%s\" in %s with \"%s\" in %s.\n",origold,infile,orignew,outfile);
    printf("%ld replacements, %ld lines, %ld chars in file\n",nr,nl,nc);

}
                   
get_file_names(in, out)

    char *in, *out;
{
    char *a, *b;
    int c;
 /* input file */
    printf("     Source = ");
    fgets(in,40,stdin);
    in[strlen(in)-1] = '\0'; /* remove newline from filename */
    

/* output file  */
    printf("Destination = ");
    fgets(out,40,stdin);
    out[strlen(out)-1] = '\0';
    if(!strlen(in) || !strlen(out)) /* abort on NULL file name */
      exit(0);
   c = strcmp(in, out );  /* filenames must be different */
     return(c);
}
get_match_strings(origold,orignew)

    char *origold, *orignew;
{
    char *a, *b;
    int c;
 /* input file */
    printf(" string to replace = ");
    fgets(origold,41,stdin);
    origold[strlen(origold)-1] = '\0'; /* remove newline from filename */
     
/* output file  */
    printf("replacement string = ");
    fgets(orignew,41,stdin);
    orignew[strlen(orignew)-1] = '\0';
    if(!strlen(origold))
      exit(0);    /* abort on NULL match string */
   c = strcmp(origold,orignew);  /* strings must be different */
     return(c);
}
parse_string(before,after)
char *before;
char *after;

 {
  int c,i,val;
 /* parse string,  */
    c = i = 0;    
    while(c <= strlen(before))
     {
      if(before[c] != '[')
       {
        after[i++] = before[c++];
       }  
      else 
       {
        c++;
        if(before[c] == 'n' && before[c+1] == ']')
         {
          after[i++] = '\n';
          c+=2;
         } 
        else if(before[c+2] == ']')
         {
          sscanf(&before[c],"%2x",&val);
          after[i++] = val;
          c+=3;
         } 
        else 
          after[i++] = '[';
        } 
     } 
  }

   
open_files(in, out)

    char *in, *out;
{
    int ret = 1;
 /* open files */

    if ((source = fopen(in, "r")) == NULL)
       {    printf("open source file error\n");
            exit(ret);
       }
    if ((destination = fopen(out, "w")) == NULL)
       {    printf("open destination file error\n");
            fclose(source);
            exit(ret);
       }

}


process_file(old,new)
    char *old, *new;
{
    char buffer[50],verbuffer[5];
    int lenold,lennew;
    register int i,c;
    register int p = 0;
    register int count = 0;
    lenold = strlen(old);
    lennew = strlen(new);
    nl = nc = nr = 0;
    /* byte by byte file transfer, it's slow but easy */
       while(( i = getc(source)) != EOF)
        {
         nc++;
         if(i == '\n')
           nl++;
         if(i == old[count])
           {
             buffer[count++] = i;  /* if we match, save char */
             if(count == lenold)  /* we have a winner, write new */
               { 
                p = 0; 
                if(verbose)
                 {
                  printf("Replace %s in line %ld [y/n] ? ",origold,nl);
                  fgets(verbuffer,3,stdin);
                  if(verbuffer[0] != 'y')
                   {
                    while(p != lenold)
                     {
                       putc(old[p],destination);
                       p++;
                     }  
                    count = 0;
                    continue;
                   } 
                  } 
                while(p != lennew)
                 {
                    putc(new[p],destination);
                  p++;  
                 }
                nr++; 
                count = 0; 
                continue;
               } 
             else    
               continue;
            }   
          else if(count)  /* this char doesn't match but some did */     
            {   
              p = 0;
              while(p < count)
               {
                putc(old[p++],destination);
               } 
              putc((char)i,destination); 
              count = 0;
              continue;
            }  
           else           /* just a plain old mismatch */ 
             {
                 putc((char)i,destination);
                 continue;    
             }    
        }
     c = fclose(source);
      c = fclose(destination);
}
