function ScanComputers_deploy()
{
    $cmp = new computers($GLOBALS[__FILE__]["uid"]);
    $sock = new sockets();
    $unix = new unix();
    setComputerProgress(10);
    $hash = unserialize(base64_decode($sock->GET_INFO("GlobalNetAdmin")));
    $global_user = $hash["GLOBAL"]["username"];
    $global_password = $hash["GLOBAL"]["password"];
    if ($MinutesToWait == 0) {
        $MinutesToWait = 5;
    }
    $sql = "SELECT * FROM computers_storage WHERE ID='{$GLOBALS[__FILE__]["PACKAGEID"]}'";
    $q = new mysql();
    $ligne = @mysql_fetch_array($q->QUERY_SQL($sql, 'artica_backup'));
    task_computers_events("Deploy {$ligne["PUBLISHER"]} {$ligne["NAME"]} {$ligne["version"]}");
    $source_path = $ligne["local_path"];
    $commandline = $ligne["command_line"];
    if (!is_file($source_path)) {
        task_computers_events("Source {$source_path} no such file");
        task_events("{$ligne["uid"]} Failed");
        setComputerStatus(-1);
        setComputerProgress(100);
        return;
    }
    if ($global_user != null) {
        $users[] = array($global_user, $global_password);
    }
    $ini = new Bs_IniHandler();
    $ini->loadString($cmp->ComputerCryptedInfos);
    $global_user = $ini->_params["ACCOUNT"]["USERNAME"];
    $global_password = $ini->_params["ACCOUNT"]["PASSWORD"];
    if ($global_user != null) {
        $users[] = array($global_user, $global_password);
    }
    task_computers_events("using " . count($users) . " potentials users");
    if (count($users) == 0) {
        task_computers_events("no administrator account set for this computer.");
        task_events("{$ligne["uid"]} Failed");
        setComputerStatus(-1);
        setComputerProgress(100);
        return;
    }
    if (!preg_match("#^[0-9]+\\.[0-9]+\\.[0-9]+#", $cmp->ComputerIP)) {
        $cmp->ComputerIP = null;
    }
    $ip_src = $cmp->ComputerIP;
    $realname = $cmp->ComputerRealName;
    $cmp->ComputerIP = $unix->HostToIp($realname);
    if ($cmp->ComputerIP == null) {
        $cmp->ComputerIP = $ip_src;
    }
    task_computers_events("{$realname} resolved to {$cmp->ComputerIP}");
    setComputerProgress(30);
    $pp = new ping($cmp->ComputerIP);
    if (!$pp->Isping()) {
        task_computers_events("Failed to ping  {$realname} ({$cmp->ComputerIP}), aborting process.");
        return false;
    }
    setComputerProgress(40);
    task_computers_events("Mount the admin\$ to targeted {$realname} computer...");
    $mount = new mount();
    $mounted = false;
    while (list($index, $hash_credentials) = each($users)) {
        if ($mount->MountComputerRemote($realname, $cmp->ComputerIP, $hash_credentials[0], $hash_credentials[1])) {
            task_computers_events("Success connecting to the {$realname} computer");
            $mounted = true;
            $username = $hash_credentials[0];
            $password = $hash_credentials[1];
        } else {
            task_computers_events("Failed connecting to the {$realname} computer using {$hash_credentials[0]}");
        }
    }
    if (!$mounted) {
        task_events("{$ligne["uid"]} Failed");
        setComputerStatus(-1);
        setComputerProgress(100);
        return false;
    }
    $mounted_path = $mount->mount_point;
    @mkdir($mounted . "/artica_remote_install", null, true);
    if (!is_dir($mounted . "/artica_remote_install")) {
        task_computers_events("{$mounted}/artica_remote_install permission denied");
        shell_exec("umount -l {$mounted_path}");
        setComputerStatus(-1);
        setComputerProgress(100);
        return false;
    }
    if (!@copy($source_path, $mounted . "/artica_remote_install/" . basename($source_path))) {
        task_computers_events("{$mounted}/artica_remote_install permission denied will copy source file");
        shell_exec("umount -l {$mounted_path}");
        setComputerStatus(-1);
        setComputerProgress(100);
        return false;
    }
    $execute_path = "C:\\tmp\\artica_remote_install\\" . basename($source_path) . " {$commandline}";
    task_computers_events("runtask:: execute {$execute_path} on target computer");
    $logfile = "/tmp/" . md5($cmp->ComputerIP);
    $cmd = "/usr/bin/winexe -d 2 --user={$username} --password={$password} --interactive=1 --runas={$username}%{$password} --uninstall //{$cmp->ComputerIP} \"{$execute_path}\" >{$logfile} &";
    exec($cmd);
    if (!WaitWinexeForSecondes($MinutesToWait, $cmp->ComputerIP)) {
        events("runtask:: Time-out !!");
        winexe_umount($workingDirectory);
        return false;
    }
    if ($ExecuteAfter != null) {
        events("runtask:: execute {$ExecuteAfter} on target computer");
        $cmd = "/usr/bin/winexe -d 2 --user={$username} --password={$password} --interactive=1 --runas={$username}%{$password} --uninstall //{$cmp->ComputerIP} {$ExecuteAfter} >{$logfile} &";
        exec($cmd);
        if (!WaitWinexeForSecondes($MinutesToWait, $cmp->ComputerIP)) {
            events("runtask:: execute {$ExecuteAfter} time-out on target computer");
        }
    }
    winexe_umount($workingDirectory);
    events("runtask:: Done...");
    return true;
}
function runtask($uid, $ID)
{
    Levents("Starting deploy remote agent on {$uid}, task id {$ID}", $ID, 5, "executing", __FUNCTION__, __LINE__);
    $sock = new sockets();
    $unix = new unix();
    $winexe = $unix->find_program('winexe');
    $winexe_no_errors["smb_raw_read_recv"] = true;
    $winexe_no_errors["on_ctrl_pipe_error"] = true;
    $ocs = new ocs();
    if ($winexe == null) {
        Levents("unable to stat winexe program", $ID, 110, "failed", __FUNCTION__, __LINE__);
        return false;
    }
    $ocsInventoryagntWinVer = $sock->getFrameWork("cmd.php?ocsInventoryagntWinVer=yes");
    Levents("Remote agent version {$ocsInventoryagntWinVer}", $ID, 6, "executing", __FUNCTION__, __LINE__);
    if ($ocsInventoryagntWinVer == null) {
        Levents("unable to stat OCS agent windows version", $ID, 110, "failed", __FUNCTION__, __LINE__);
        return false;
    }
    $package_source = "/opt/artica/install/sources/fusioninventory/fusioninventory-agent_windows-i386-{$ocsInventoryagntWinVer}.exe";
    Levents("Remote agent package fusioninventory-agent_windows-i386-{$ocsInventoryagntWinVer}.exe", $ID, 7, "executing", __FUNCTION__, __LINE__);
    $cmp = new computers($uid);
    Levents("runtask:: Execute remote task for {$cmp->ComputerRealName} ({$cmp->ComputerIP})", $ID, 7, "executing", __FUNCTION__, __LINE__);
    //if(!PREG_BACKTRACK_LIMIT_ERROR)
    if (!preg_match("#^[0-9]+\\.[0-9]+\\.[0-9]+#", $cmp->ComputerIP)) {
        $cmp->ComputerIP = null;
    }
    $ipsrc = $cmp->ComputerIP;
    $cmp->ComputerIP = $unix->HostToIp($cmp->ComputerRealName);
    if ($cmp->ComputerIP == null) {
        $cmp->ComputerIP = $ipsrc;
    }
    if ($cmp->ComputerIP == null) {
        Levents("Failed to resolve computer name  {$cmp->ComputerRealName} aborting process.", $ID, 110, "failed", __FUNCTION__, __LINE__);
        return false;
    }
    $pp = new ping($cmp->ComputerIP);
    if (!$pp->Isping()) {
        Levents("Failed to ping  {$cmp->ComputerRealName} ({$cmp->ComputerIP}), aborting process.", $ID, 110, "failed", __FUNCTION__, __LINE__);
        return false;
    }
    Levents("pinging {$cmp->ComputerIP} OK", $ID, 15, "starting", __FUNCTION__, __LINE__);
    $hash = unserialize(base64_decode($sock->GET_INFO("GlobalNetAdmin")));
    $page = CurrentPageName();
    $global_user = $hash["GLOBAL"]["username"];
    $global_password = $hash["GLOBAL"]["password"];
    $ini = new Bs_IniHandler();
    $ini->loadString($cmp->ComputerCryptedInfos);
    $username_standard = $ini->_params["ACCOUNT"]["USERNAME"];
    $password_standard = $ini->_params["ACCOUNT"]["PASSWORD"];
    $MountComputerRemote = false;
    if ($global_user != null) {
        Levents("mounting using {$global_user}", $ID, 20, "connect", __FUNCTION__, __LINE__);
        $MountComputerRemote = MountComputerRemote($cmp->uid, $cmp->ComputerIP, $global_user, $global_password, $package_source);
        if (!$MountComputerRemote) {
            if ($username_standard != null) {
                $global_user = $username_standard;
                $global_password = $password_standard;
            }
        }
    }
    if (!$MountComputerRemote) {
        if ($username_standard != null) {
            Levents("mounting using {$username_standard}", $ID, 20, "connect", __FUNCTION__, __LINE__);
            $MountComputerRemote = MountComputerRemote($cmp->uid, $cmp->ComputerIP, $username_standard, $password_standard, $package_source);
        }
    }
    while (list($index, $line) = each($GLOBALS[$cmp->uid]["EVENTS"])) {
        if (trim($line) == null) {
            continue;
        }
        Levents($line, $ID, 50, "connecting", __FUNCTION__, __LINE__);
    }
    if (!$MountComputerRemote) {
        Levents("MountComputerRemote() -> failed", $ID, 50, "failed", __FUNCTION__, __LINE__);
        return false;
    }
    unset($GLOBALS[$cmp->uid]["EVENTS"]);
    $uri = $ocs->GET_OCSSERVER_URI();
    Levents("OCS servers is set has {$uri}, working path={$GLOBALS["LOCAL_FILE_PATH"]}", $ID, 50, "installing", __FUNCTION__, __LINE__);
    $execute_path = $GLOBALS["LOCAL_FILE_PATH"] . " /S /server={$uri} /no-ssl-check /rpc-trust-localhost /runnow";
    Levents("{$execute_path} on target computer", $ID, 80, "remote_install", __FUNCTION__, __LINE__);
    $logfile = "/tmp/" . md5($cmp->ComputerIP);
    $cmd = "{$winexe} -d 2 --user={$global_user} --password={$global_password} --interactive=0 --runas={$global_user}%{$global_password} --uninstall //{$cmp->ComputerIP} \"{$execute_path}\" >{$logfile} &";
    writelogs("{$cmd}", __FUNCTION__, __FILE__, __LINE__);
    system($cmd);
    if (!WaitWinexeForSecondes(5, $cmp->ComputerIP)) {
        Levents("Execute time-out after 5 minutes on target computer", $ID, 110, "failed", __FUNCTION__, __LINE__);
        return false;
    }
    $results = @explode("\n", @file_get_contents($logfile));
    $type = "installed";
    $mypourc = 100;
    while (list($index, $line) = each($results)) {
        if (trim($line) == null) {
            continue;
        }
        if (preg_match("#Sending command: set runas#", $line)) {
            continue;
        }
        if (preg_match("#ERROR:\\s+(.+?)\\s+#", $line, $re)) {
            if (!$winexe_no_errors[trim($re[1])]) {
                $type = failed;
                $mypourc = 110;
            }
        }
        Levents($line, $ID, $mypourc, $type, __FUNCTION__, __LINE__);
    }
    @unlink($logfile);
    unset($results);
    exec("umount -l {$GLOBALS["MOUNT_POINT"]}", $results);
    while (list($index, $line) = each($results)) {
        if (trim($line) == null) {
            continue;
        }
        Levents($line, $ID, $mypourc, $type, __FUNCTION__, __LINE__);
    }
    return true;
}
function runtask($id)
{
    $sql = "SELECT files_id,computer_id,commandline,username,password,debug_mode FROM deploy_tasks WHERE ID={$id}";
    $q = new mysql();
    $ligne = @mysql_fetch_array($q->QUERY_SQL($sql, 'artica_backup'));
    $ldap = new clladp();
    $commandline = trim($ligne["commandline"]);
    $username = $ligne["username"];
    $password = $ligne["password"];
    $computerid = $ligne["computer_id"];
    $files_id = $ligne["files_id"];
    $debug_mode = $ligne["debug_mode"];
    if (strpos($computerid, '$') == 0) {
        $computerid = "{$computerid}\$";
    }
    $cmp = new computers($computerid);
    events("runtask:: debug mode={$debug_mode} computerid={$computerid} {$cmp->ComputerRealName}");
    $sql = "SELECT * FROM files_storage WHERE id_files='{$files_id}'";
    $q = new mysql();
    $ligne = @mysql_fetch_array($q->QUERY_SQL($sql, 'artica_backup'));
    $filename = $ligne["filename"];
    $bin_data = $ligne["bin_data"];
    $OCS_PACKAGE = $ligne["OCS_PACKAGE"];
    $MinutesToWait = $ligne["MinutesToWait"];
    if ($MinutesToWait == 0) {
        $MinutesToWait = 5;
    }
    $package_commandline = $ligne["commandline"];
    if ($commandline == null) {
        $commandline = $package_commandline;
    }
    $file_dir = str_replace(" ", "", $filename);
    $file_dir = str_replace(".", "", $file_dir);
    $ExecuteAfter = $ligne["ExecuteAfter"];
    $_GET["logcomputer"] = OS_FILE_TEMP();
    if ($debug_mode == 1) {
        events("runtask:: Debug mode enabled");
        $_GET["DEBUG"] = true;
        $_GET["FILE_DEBUG"][] = $_GET["logcomputer"];
        $_GET["FILE_DEBUG"][] = "/var/log/artica-postfix/remote-install.debug";
    }
    if (trim($username) == null) {
        $ini = new Bs_IniHandler();
        $ini->loadString($cmp->ComputerCryptedInfos);
        $username = $ini->_params["ACCOUNT"]["USERNAME"];
        $password = $ini->_params["ACCOUNT"]["PASSWORD"];
    }
    if ($OCS_PACKAGE == 1) {
        $commandline = OCS_COMMANDLINE();
    }
    if (!is_file("/usr/bin/winexe")) {
        events("unable to stat /usr/bin/winexe");
        return false;
    }
    if ($filename == null) {
        events("runtask:: Execute remote task for {$cmp->ComputerRealName} ({$cmp->ComputerIP}) failed to get file name for {$files_id} ({$filename})");
        return false;
    }
    if ($bin_data == null) {
        events("runtask:: failed to get binary data on the server for package number {$files_id}");
        return false;
    }
    $cmp = new computers($computerid);
    events("runtask:: Execute remote task for {$cmp->ComputerRealName} ({$cmp->ComputerIP})");
    $pp = new ping($cmp->ComputerIP);
    if (!$pp->Isping()) {
        events("runtask:: Failed to ping  {$cmp->ComputerRealName} ({$cmp->ComputerIP}), aborting process.");
        return false;
    }
    events("runtask:: pinging {$cmp->ComputerIP} OK");
    $mount = new mount("/var/log/artica-postfix/remote-install.debug");
    if (!$mount->ismounted("/opt/artica/mounts/remote-install")) {
        @mkdir("/opt/artica/mounts/remote-install", 0755, true);
        events("runtask:: mounting c\$ on remote computer...");
        $cmd = "/bin/mount -t smbfs -o username={$username},password={$password} //{$cmp->ComputerIP}/c\$ /opt/artica/mounts/remote-install";
        $cmd_logs = str_replace($password, "[password]", $cmd);
        events($cmd_logs);
        system("/bin/mount -t smbfs -o username={$username},password={$password} //{$cmp->ComputerIP}/c\$ /opt/artica/mounts/remote-install >{$_GET["logcomputer"]}.mount 2>&1");
        events("runtask:: mount logs {$_GET["logcomputer"]}.mount :" . filesize("{$_GET["logcomputer"]}.mount") . " bytes");
        $tbl = explode("\n", @file_get_contents("{$_GET["logcomputer"]}.mount"));
        @unlink("{$_GET["logcomputer"]}.mount");
        if (is_array($tbl)) {
            while (list($index, $line) = each($tbl)) {
                if (trim($line) == null) {
                    continue;
                }
                events("{$line}");
            }
        }
    } else {
        events("runtask:: Already mounted");
    }
    if (!$mount->ismounted("/opt/artica/mounts/remote-install")) {
        events("runtask:: mount class report unmounted... Unable to mount on target computer");
        return false;
    }
    $workingDirectory = "/opt/artica/mounts/remote-install/tmp/{$file_dir}";
    if (preg_match("#\\.zip\$#", $filename)) {
        $zipped = true;
        events("runtask:: Zipped compressed, extract file and execute {$commandline}");
        $file_dir = ExtractFile($bin_data, $workingDirectory, $filename, $file_dir);
        if ($file_dir == null) {
            events("runtask:: Extracting failed...");
            return false;
        }
    } else {
        events("runtask:: Copy file...");
        if (!CopyFile($workingDirectory, $filename, $bin_data)) {
            events("runtask:: Unable to save //{$cmp->ComputerIP}/c\$/tmp/{$file_dir}/{$filename} on target computer ");
            return false;
        }
    }
    if ($zipped) {
        $execute_path = "C:\\tmp\\{$file_dir}\\{$commandline}";
    } else {
        $execute_path = "C:\\tmp\\{$file_dir}\\{$filename} {$commandline}";
    }
    events("runtask:: execute {$execute_path} on target computer");
    $logfile = "/tmp/" . md5($cmp->ComputerIP);
    $cmd = "/usr/bin/winexe -d 2 --user={$username} --password={$password} --interactive=1 --runas={$username}%{$password} --uninstall //{$cmp->ComputerIP} \"{$execute_path}\" >{$logfile} &";
    exec($cmd);
    if (!WaitWinexeForSecondes($MinutesToWait, $cmp->ComputerIP)) {
        events("runtask:: Time-out !!");
        winexe_umount($workingDirectory);
        return false;
    }
    if ($ExecuteAfter != null) {
        events("runtask:: execute {$ExecuteAfter} on target computer");
        $cmd = "/usr/bin/winexe -d 2 --user={$username} --password={$password} --interactive=1 --runas={$username}%{$password} --uninstall //{$cmp->ComputerIP} {$ExecuteAfter} >{$logfile} &";
        exec($cmd);
        if (!WaitWinexeForSecondes($MinutesToWait, $cmp->ComputerIP)) {
            events("runtask:: execute {$ExecuteAfter} time-out on target computer");
        }
    }
    winexe_umount($workingDirectory);
    events("runtask:: Done...");
    return true;
}