#
# This script was written by Carsten Koch-Mauthe <c.koch-mauthe at dn-systems.de>
#
# This script is released under the GNU GPLv2
#
# $Revision: 9 $

# XXX: the version tests should be eventually consolidated with
# the methods from revisions-lib.inc.

include("ssh_func.inc");

function find_bin(prog_name, sock) {
  local_var r, whe, whi;
  whe = "";
  whi = "";
  if (islocalhost()) {
     r = split(pread(cmd:"locate", argv:make_list("locate", "-i", "*bin/"+prog_name)) );
     whe = pread(cmd: "whereis", argv:make_list("whereis", "-b", prog_name));
     whi = pread(cmd:"which", argv:make_list("which", "-a", prog_name));
  } else {
      if(! sock) {
        sock = ssh_login_or_reuse_connection();
      }
      if(sock) {
        r = split(ssh_cmd(socket:sock, cmd:"locate -i *bin/"+prog_name, timeout:60));
        whe = ssh_cmd(socket:sock, cmd:"whereis -b "+prog_name, timeout:60);
        whi = ssh_cmd(socket:sock, cmd:"which -a "+prog_name, timeout:60);
      } else {
         r = NULL;
      }
  }
  if( "bin/"+prog_name >!< r ) {
    if( "bin/"+prog_name >< whe ) {
       r = split(substr(whe - (prog_name + ":"), 1), sep:" ");
    } else {
       r = NULL;
    }
  }
  if(isnull(r) ) {
    if(("which: no "+prog_name) >!< whi) {
       r = split(whi);
    } else {
       r = NULL;
    }
  }
  return (r);
}

function find_file(file_name, file_path, useregex, regexpar, sock ) {
  local_var r, f, fname, lparam;

  r = NULL;
  if( useregex ) {
    lparam = "-ir";
  } else {
    lparam = "-i";
  }
  if (islocalhost()) {
     r = split(pread(cmd:"locate", argv:make_list("locate", lparam, file_path+file_name+regexpar )) );
     if(! isnull(file_path) ) {
       f = split(pread(cmd:"find", argv:make_list("find", file_path , "-maxdepth", "7",
                           "-mindepth", "1", "-name",  file_name, "-type", "f")));
     }
  } else {
      if(! sock) {
        sock = ssh_login_or_reuse_connection();
      }
      if(sock) {
        r = split(ssh_cmd(socket:sock, cmd:"locate "+lparam+" "+raw_string(0x22)+file_path+file_name+
                                            regexpar+raw_string(0x22), timeout:60));
        if(!isnull(file_path) ) {
          f = split(ssh_cmd(socket:sock, cmd:"find "+raw_string(0x22)+file_path+raw_string(0x22)+
                                             " -maxdepth 7 -mindepth 1"+" -name "+raw_string(0x22)+
                                             file_name+raw_string(0x22)+" -type f", timeout:60));
        }
      } 
  }
  fname = ereg_replace(pattern:"\*.+", string:file_name, replace:"");
  if( fname >!< r ) {
    if( fname >< f ) {
      r = f;
    } else {
      r = NULL;
    }
  }
  return (r);
}

function get_bin_version(full_prog_name, version_argv, ver_pattern, sock) {
  local_var loc_version, r, report;

  if (islocalhost()) {
     r = pread(cmd:full_prog_name, argv:make_list(full_prog_name, version_argv) );
  } else {
     if(! sock) {
       sock = ssh_login_or_reuse_connection();
     }
     if(sock) {
       r = ssh_cmd(socket:sock, cmd:full_prog_name +" "+version_argv, timeout:60);
     }
  }
  loc_version = eregmatch(pattern:ver_pattern, string:r);
  if(loc_version != NULL) loc_version[max_index(loc_version)] = r;
  return (loc_version);
}

function get_string_version(text, ver_pattern) {
  local_var loc_version;

  if( isnull( ver_pattern) ) {           # Standard Version Pattern for most cases
    ver_pattern = "([0-9\.]+)";
  }
  loc_version = eregmatch(pattern:ver_pattern, string:text);
  if(loc_version != NULL) loc_version[max_index(loc_version)] = text;
  return (loc_version);
}

function version_is_less(version ,test_version, icase) {
  return (version_test(version:version, test_version:test_version, less:TRUE, icase:icase));
}

function version_is_equal(version, test_version, icase) {
  return (version_test(version:version, test_version:test_version, less:FALSE, icase:icase));
}

function version_test(version, test_version, less, icase) {
  local_var ver_ary, test_ary, ver_num, ver_sep, i, r, s, char_found;
  if(isnull(icase) ) icase = TRUE;
  if(icase) {
    version = tolower(version);
    test_version = tolower(test_version);
  }
  ver_sep = ereg_replace(pattern:"([A-Za-z0-9])", string: version, replace:"");
  if( ver_sep == "" ) ver_sep = ".";   # Set Standard Separator
  ver_ary = split(version, sep:ver_sep[0], keep:0);
  ver_sep = ereg_replace(pattern:"([A-Za-z0-9])", string: test_version, replace:"");
  if( ver_sep == "" ) ver_sep = ".";   # Set Standard Separator
  test_ary = split(test_version, sep:ver_sep[0], keep:0);
  while(max_index(ver_ary) < max_index(test_ary) ) {
    ver_ary[max_index(ver_ary)] = "0";
  }
  while(max_index(ver_ary) > max_index(test_ary) ) {
    test_ary[max_index(test_ary)] = "0";
  }
  foreach i (keys(test_ary) ) {
    r = eregmatch(pattern:"([0-9]+)", string:test_ary[i]);
    s = eregmatch(pattern:"([A-Za-z])", string:test_ary[i]);
    if(isnull(s) ) {
      test_ary[i] = int(r[0]) * 128;                         # Changed to * 128 so if a char follows a number the number is more significant 
      char_found = FALSE;
    } else {
      test_ary[i] = (int(r[0]) * 128) + ord(s[0]);
      char_found = TRUE;
    }
    r = eregmatch(pattern:"([0-9]+)", string:ver_ary[i]);
    s = eregmatch(pattern:"([A-Za-z])", string:ver_ary[i]);
    if(isnull(s) ) {
      ver_ary[i] = int(r[0]) * 128;
    } else if(char_found) {
             ver_ary[i] = (int(r[0]) * 128) + ord(s[0]);
           } else {
             if(isnull(r) ) {
               ver_ary[i] = ord(s[0]);
             } else {
               if(! less) return (0);			     # If char found in test_version and no char in version it is not equal
	       ver_ary[i] = int(r[0]) * 128;                 # No chars if test_version has no chars on this position else 1.1.1a is > 1.1.2
             }
    }
    if(less) {
      if(ver_ary[i] < test_ary[i]) return (1);
      if(ver_ary[i] > test_ary[i]) return (0);
    } else {
      if(ver_ary[i] != test_ary[i]) return (0);
    }
  }
  if(less) return (0); else return (1);
}

function version_is_less_equal(version, test_version) {
  if(version_is_equal(version:version, test_version:test_version) ) return (1);
  if(version_is_less(version:version, test_version:test_version) ) return (1);
  return (0);
}

function version_is_greater_equal(version, test_version) {
  if(version_is_equal(version:version, test_version:test_version) ) return (1);
  if(version_is_less(version:test_version, test_version:version) ) return (1);
  return (0);
}

function version_is_greater(version, test_version) {
  if(version_is_less(version:test_version, test_version:version) ) return (1);
  return (0);
}

function version_in_range(version, test_version, test_version2){
  if(version_is_greater_equal(version:version, test_version:test_version)){
    if(version_is_less_equal(version:version, test_version:test_version2)) return (1);
  }
  return (0);
}
