#
# 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.


function find_bin(prog_name, sock) {
  local_var r, whe, whi;
  whe = "";
  whi = "";
  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";
  }

  use_find = get_kb_item("Enable/find");
  descend_directories = get_kb_item("Descend/OFS");

  if(isnull(use_find))use_find="yes";
  if(isnull(descend_directories))descend_directories="yes";   

  fname = ereg_replace(pattern:"\*.+", string:file_name, replace:"");

  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(fname >!< r && "yes" >< use_find) {
      if(!isnull(file_path) ) {

	cmd =  "find "+raw_string(0x22)+file_path+raw_string(0x22);
	if("no" >< descend_directories) {
          cmd += " -xdev";
	}  
	cmd += " -maxdepth 7 -mindepth 1 -name "+raw_string(0x22);
	cmd += file_name+raw_string(0x22)+" -type f";

        f = split(ssh_cmd(socket:sock, cmd: cmd, timeout:60));
      }
    }
  }

  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(! 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);
}

function get_version_from_kb(port,app) {

  local_var port, app, vers, version, matches;

  if(isnull(port) || isnull(app))return FALSE;
  
  if(!version = get_kb_item(string("www/", port, "/",app)))return FALSE;
  if(!matches = eregmatch(string:version, pattern:"^(.+) under (/.*)$"))return FALSE;
  
  vers = matches[1];

  if(isnull(vers) || vers == "unknown") return FALSE;

  return string(vers); 

} 

function get_dir_from_kb(port,app) {

  local_var port, app, dir, version, matches;

  if(isnull(port) || isnull(app))return FALSE;
  
  if(!version = get_kb_item(string("www/", port, "/",app)))return FALSE;
  if(!matches = eregmatch(string:version, pattern:"^(.+) under (/.*)$"))return FALSE;

  dir = matches[2];

  if(isnull(dir)) return FALSE;

  return string(dir); 

}
