#!/bin/bash
#which cc 1>/dev/null 2>/dev/null || exit 1
Me=$(true_path $0)
PATH=${PATH}:${Me%/*}/${BASE_ARCH}
[[ "$1" != Force ]] && which r.fix_the_paths 2>/dev/null >/dev/null && exit 0
[[ -x $TMPDIR/bin/r.fix_the_paths ]] && exit 0
cd $TMPDIR/bin || exit 1
[[ -x ${Me%/bin/*}/bin/r.fix_the_paths ]] && \
   cp ${Me%/bin/*}/bin/r.fix_the_paths $TMPDIR/bin/r.fix_the_paths && \
   echo "=== using ./r.fix_the_paths ==="
[[ -x $TMPDIR/bin/r.fix_the_paths ]] && exit 0
cat <<"EOT" >r.fix_the_paths.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>


static  char **eliminate=NULL;
static  int n_eliminate=0;
static  char extra_path[1204], env_value[32768], ovbin[1024], tmpdir_bin[1024], tmpdir_ovbin[1024];

print_usage(char *name)
{
   fprintf(stderr,"USAGE: %s [-v|--verbose] -pat1 -pat2 ... -patn [+supp1a[+supp1b[+supp1c]]] item1 [+supp2] item2 ... [+suppn] itemn \n",name);
   fprintf(stderr,"       pat1..patn simple patterns to eliminate\n");
   fprintf(stderr,"       supp1..suppn if item/supp is a directory, add it in front of item\n");
   fprintf(stderr,"       item = EnvName \n");
   fprintf(stderr,"       EnvName is the name of an environment variable containing a path\n");
   fprintf(stderr,"ex:    %s PATH MANPATH EC_LD_LIBRARY_PATH\n",name);
   fprintf(stderr,"       %s +$BASE_ARCH PATH MANPATH +$EC_ARCH EC_LD_LIBRARY_PATH\n",name);
   fprintf(stderr,"       %s LD_LIBRARY_PATH +$EC_ARCH EC_INCLUDE_PATH\n",name);
   fprintf(stderr,"ex:    %s -/a/b/ -machin/patente PATH MANPATH EC_LD_LIBRARY_PATH\n",name);
}

int dir_entries(const char *path)  /* number of entries in directory. -1 directory does not exist, 0 directory is empty */
{
  DIR *dirp;
  struct dirent *entry;
  int entries = 0;

  if(path[0] != '/') return(1) ; /* a relative path is always considered non empty */
/*  if(strcmp(".",path) == 0) return(1) ; */ /* directory . is always considered non empty */
  dirp = opendir(path);
  if(dirp == NULL) return -1;
  while ( (entry = readdir(dirp)) != NULL) {
   entries++;
   if(entries >= 3) break ;    /* in this program we only want to know if directory has at least one entry other than . and .. */
  }
  closedir(dirp);
  return(entries - 2);  /* account for . and .. */
}

int is_dir_element(char *base, char *subpath)   /* is subpath a subdirectory of base ? */
{
  DIR *dirfd;
  struct dirent *my_dirent;
  struct stat stat_buf;
  int found = 0;
  char full_path[2048];

  if(  dirfd = opendir(base) ){                          /* directory base exists and can be read */
    while( (my_dirent = readdir(dirfd)) != NULL ) {      /* read directory entries */
      if (0 == strcmp(my_dirent->d_name,subpath) ) {     /* subpath found in directory  */
        snprintf(full_path,2047,"%s/%s",base,subpath);   /* build fullpath (used later by stat)   */
        found = (dir_entries(full_path) > 0);            /* it is a non empty directory */
#if defined(OBSOLETE)
        if ( 0 == stat(full_path,&stat_buf) ) {          /* name match, stat the full path */
          found = S_ISDIR(stat_buf.st_mode) ;            /* must be a directory to be considered found */
        }
#endif
        break ;
      }
    }   /* while */
    closedir(dirfd);
  }
  return found ;
}

#define MAXSUB 8
int is_a_dir(const char *base_path, const char *extra)   /* is base_path + extra a directory ? */
{
  char extra_path[1024], full_base[2048] ;
  char *pname, *subdirs[MAXSUB] ;
  int nsub, j, found, base_length;

  if(*extra == '\0') return 0;            /* no extra path, return false */
  strncpy(extra_path,extra,1023);         /* make local copy of extra */
  extra_path[1023] = '\0' ;               /* make sure extra_path is null terminated */

  for(j=0 ; j<MAXSUB ; j++) subdirs[j] = "";   /* initialize subpaths to null string */
  pname = extra_path;
  nsub = 0;
  subdirs[0] = pname;
  while(*pname != '\0') {                 /* break extra_path into constituent subdirectories */
    if(*pname == '/') {
      *pname = '\0';                      /* locate / characters and replace with nulls */
      while(*pname == '/') pname++;       /* get rid of consecutive / characters */
      if(nsub == MAXSUB) return 0 ;       /* too many subpaths, return failure */
      subdirs[++nsub] = pname++ ;         /* remember starting positions of subdirectories */
    }else{
      pname++;
    }
  }

  strncpy(full_base,base_path,2047) ; full_base[2047] = '\0' ;
  base_length = strlen(full_base);            /* base length of path */
  found = 0;
  for (j=0 ; j<=nsub ; j++){                  /* check one level at a time */
    char *temp = subdirs[j];
    if (*temp == '\0') break;                 /* nothing to add any more */
    found = is_dir_element(full_base,temp);   /* check if current path + addon is a directory */
    if(found == 0) return found;              /* not found, no need to look further, return negative */
    snprintf(full_base+base_length,2047-base_length,"/%s",temp);   /* add subpath at end of base path  */
    base_length = strlen(full_base);          /* update base length of path */
  }
  return found ;   /* all subdirs checked, return */
}

int is_duplicate(char *what, char **table, int nentries)  /* a non existent or empty directory is treated like a duplicate */
{
  int i;
  struct stat stat_buf;

  for(i=0;i<n_eliminate;i++) { if ( strstr(what,1+eliminate[i]) ) return 1; } /* if found in list to eliminate, treat as duplicate */
  for(i=0;i<nentries;i++){
    if(table[i] != NULL) {
      if(strcmp(what,table[i]) == 0) return 1;    /* found in current list, it is a duplicate */
    }
  }
  /* override directories (~/ovbin , $TMPDIR/bin, $TMPDIR/ovbin) are kept even if empty or non existent */
  if( (0 == strncmp(what,tmpdir_bin,strlen(tmpdir_bin))) ||  (0 == strncmp(what,tmpdir_ovbin,strlen(tmpdir_ovbin))) || (0 == strncmp(what,ovbin,strlen(ovbin))) ) return 0 ;
  if (dir_entries(what) > 0) return 0 ;  /* directory exists and is not empty */
#if defined(OBSOLETE)
  if ( 0 != stat(what,&stat_buf) ) return 1 ;  /* does not exist, act as if it were a duplicate */
  if( S_ISDIR(stat_buf.st_mode) )  return 0 ;  /* it is a directory and was not found in list */
#endif
  return 1;   /* directory does not exist or is empty, act as if it were a duplicate */
}

#define MAXAUG 8
main(int argc, char **argv)
{
  char *progname, *env_var, *supplement;
  char augment[1024];     /* compound augmentation string */
  char *augptr[MAXAUG];   /* list of pointers to paths augmentations */
  int found[MAXAUG];
  char *sub_path[1204];   /* used to split path variables into constituent elements */
  int i, j, nsubpath, len_ovbin, augmentable;
  char separator=':';
  char *temp, *varname;
  char *TMPDIR=getenv("TMPDIR");
  char *HOME=getenv("HOME");
  int verbose=0;

  progname=argv[0];
  if(argc < 2 ) { print_usage(argv[0]) ; exit(1); }

  if(strcmp( "-h",argv[1])==0 || strcmp("--help",argv[1])==0 ) { print_usage(argv[0]) ; exit(1); }
  argc-- ; argv++;
  if(strcmp( "-v",*argv)==0 || strcmp( "--verbose",*argv)==0 ) {verbose=1 ; argc-- ; argv++; }
  if(**argv == '-') {
    eliminate=argv;
    while(argc > 0 && **argv == '-') { n_eliminate++ ; argc-- ; argv++ ; }
  }

  tmpdir_bin[0]='\0';  /* tempdir/bin, top override */
  if(TMPDIR != NULL) snprintf(tmpdir_bin,1023,"%s/bin%c",TMPDIR,'\0'); tmpdir_bin[1023]='\0';
  tmpdir_ovbin[0]='\0';
  if(TMPDIR != NULL) snprintf(tmpdir_ovbin,1023,"%s/ovbin%c",TMPDIR,'\0'); tmpdir_ovbin[1023]='\0';
  ovbin[0]='\0';  /* base of ovbin directories, ~/ovbin */
  if(HOME   != NULL) snprintf(ovbin     ,1023,"%s/ovbin%c",HOME,'\0'); ovbin[1023]='\0';
  len_ovbin=strlen(ovbin);

  supplement="";
  augment[0] = '\0';
  for(i=0;i<MAXAUG;i++) augptr[i]=NULL;
  while(argc--){                /* loop over arguments */
    varname=argv[0];
    if( *varname == '+' ) {     /* +dir1[+dir2][+dir3]... path augmentations */
      supplement=varname+1;
      strncpy(augment,supplement,sizeof(augment));
      augment[sizeof(augment)-1] = '\0';
      augptr[0] = &augment[0];
      i = 0;
      temp = &augment[0];
      while( *temp != '\0' ) {     /* break into components */
        if (*temp == '+' ) { 
          *temp = '\0' ;
          if(temp[1] != '+') augptr[++i] = temp+1 ;  /* ignore multiple consecutive + */
        }
        temp++ ;
        if( i == MAXAUG-1 ) break ;   /* too many augmentations */
      }
      for( ; i>=0 ; i--){    /* get rid of duplicate augmentations */
        if(augptr[i] != NULL){
          for(j=i-1 ; j>=0 ; j--){
            if(augptr[j] != NULL){
              if(0 == strcmp(augptr[i],augptr[j])) {
                augptr[i] = NULL; /* duplicate augmentation */
                break;
              }
            }
          }
        }
      }
/*      while( i<MAXAUG ) augptr[++i] = NULL; */ /* nullify rest of table */
      argv++;
      continue;
    }
    if( isalnum(*varname) || *varname=='_' ) {  /* if first char of environment variable name not alphnum or _ , it is the separator */
      separator = '\0';                         /* separator will be determined later from vartiable contents */
    }else{
      separator = *varname++;
    }
    env_var=getenv(varname);    /* get value of environment variable */
    if(env_var != NULL){        /* make sure it exists */
      fprintf(stdout,"%s=''\n",varname);   /* set variable to '' */
      strncpy(env_value,env_var,32767); env_value[32767]='\0';  /* take a copy */
      temp=env_value;
      if(separator == '\0') {   /* if separator flagged as auto */
        while(*temp != '\0' && *temp != ':' &&  *temp != ' ' && *temp != ';') temp++;  /* find separator, one of blank , colon, semicolon */
        separator=*temp;
      }
      temp=env_value;
      if(separator == '\0') separator = ':' ;                   /* default if nothing was found */
      while( *temp == separator && *temp != '\0') temp++;       /* get rid of leading separators */

      nsubpath=1;
      sub_path[0]=temp;

      while(1){                                                 /* split path into separate entries */
        while( *temp != separator && *temp != '\0') temp++;     /* skip to next separator */
        if(*temp == '\0') break;                                /* OOPS end */
        *temp='\0'; temp++;
        if(is_duplicate(sub_path[nsubpath-1],sub_path,nsubpath-1)) /* duplicate entry in path ? */
          nsubpath--;
        while( *temp == separator && *temp != '\0') temp++;     /* skip all consecutive separators */
        if(*temp == '\0') break;                                /* OOPS end */
        sub_path[nsubpath++]=temp;                              /* update path element table */
      }
      if(nsubpath < 1) goto try_next;                            /* nothing was found */
      if(is_duplicate(sub_path[nsubpath-1],sub_path,nsubpath-1)) /* is last entry in path a duplicate ? */
        nsubpath--;
      if(nsubpath < 1) goto try_next;                            /* nothing was found */

      fprintf(stdout,"%s='",varname);                            /* print variable_name= */

      /* OVERRIDE directories (non augmentable) */
      for(i=0 ; i<nsubpath ; i++){
         if(0 == strncmp(sub_path[i],tmpdir_bin,strlen(tmpdir_bin)) ){               /* $TMPDIR/bin ? */
           fprintf(stdout,"%s%c",sub_path[i],separator);         /* print it immediately */
           sub_path[i]=NULL;                                     /* and suppress entry */
         }
      }
      while(sub_path[nsubpath-1] == NULL) nsubpath--;            /* suppress NULLs at tail of list */
      for(i=0 ; i<nsubpath ; i++){
         if(sub_path[i] == NULL) continue;
         if(0 == strncmp(sub_path[i],tmpdir_ovbin,strlen(tmpdir_ovbin)) ){               /* $TMPDIR/ovbin ? */
           fprintf(stdout,"%s%c",sub_path[i],separator);         /* print it immediately */
           sub_path[i]=NULL;                                     /* and suppress entry */
         }
      }
      while(sub_path[nsubpath-1] == NULL) nsubpath--;            /* suppress NULLs at tail of list */
      for(i=0 ; i<nsubpath ; i++){
         if(sub_path[i] == NULL) continue;
         if(0 == strncmp(sub_path[i],ovbin,len_ovbin) ){         /* $HOME/ovbin... ? */
           fprintf(stdout,"%s%c",sub_path[i],separator);         /* print it immediately */
           sub_path[i]=NULL;                                     /* and suppress entry */
         }
      }
      while(sub_path[nsubpath-1] == NULL) nsubpath--;            /* suppress NULLs at tail of list */

      for(i=0 ; i<nsubpath ; i++) {                              /* output non override values */
        augmentable = 1;
        if(sub_path[i] != NULL) {
          temp = sub_path[i] ;
          augmentable = strncmp("/usr/",temp,5) * strncmp("/opt",temp,4) * 
                        strncmp("/bin",temp,4)  * strncmp("/etc",temp,4) *
                        strncmp("/sbin",temp,5);
          if( *supplement != '\0' && augmentable ) {             /* path must be "augmentable" */
            for(j=0 ; j<MAXAUG ; j++) found[j] = 0;
            for(j=0 ; j<MAXAUG ; j++) {
              if(augptr[j] != NULL) {
                snprintf(extra_path,1023,"%s/%s",sub_path[i],augptr[j]);
                found[j] = is_a_dir(sub_path[i],augptr[j]);
              }
            }
            for(j=0 ; j<MAXAUG ; j++) {
              if(augptr[j] != NULL) {
                char *tempo = augptr[j];
                int ltempo = strlen(tempo)-1;
                if(tempo[ltempo] == '/') tempo[ltempo] = '\0';   /* get rid of a trailing / */
                if(found[j]) { fprintf(stdout,"%s/%s%c",sub_path[i],augptr[j],separator); }
                else { if(verbose) fprintf(stderr,"directory '%s/%s' does not exist\n",sub_path[i],augptr[j]); }
              }
            }
          }else{   /* path is not augmentable or there is no augmentation request */
            if(verbose && *supplement != '\0') fprintf(stderr,"no lookup for '%s'\n",temp);
          }
          if( i == nsubpath-1 )
            fprintf(stdout,"%s'\n",sub_path[i]);
          else
            fprintf(stdout,"%s%c",sub_path[i],separator);
        }
      }
    }else{   /* specified path environment variable does not exist, do nothing */
      if(verbose) fprintf(stderr,"%s: ERROR environment variable %s not found\n",progname,*argv);
    }
try_next:
    if(nsubpath == 0) {
      if(verbose) fprintf(stderr,"%s: ERROR no valid directory found in path variable %s\n",progname,*argv);
    }
    supplement="";
    augment[0] = '\0';
    for(i=0;i<MAXAUG;i++) augptr[i]=NULL;
    argv++;
  }
}
EOT
#cc r.fix_the_paths.c -o r.fix_the_paths
# [[ $(which gcc) ]]  && export CC=gcc
if [[ "$ARCH" == AIX* ]]; then
   export CC=cc
else
   export CC=gcc
fi
make r.fix_the_paths
#rm -f r.fix_the_paths.c
