<?php
/*
 * $RCSfile: WinNtPlatform.class,v $
 *
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2005 Bharat Mediratta
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 */
/**
 * @version $Revision: 1.30 $ $Date: 2005/08/23 03:49:03 $
 * @package GalleryCore
 * @author Bharat Mediratta <bharat@menalto.com>
 */

/**
 * Load required class
 */
GalleryCoreApi::relativeRequireOnce('modules/core/classes/GalleryPlatform.class');

/**
 * An WindowsNT based version of the GalleryPlatform class
 *
 * @package GalleryCore
 * @subpackage Platform
 * @access public
 */
class WinNtPlatform extends GalleryPlatform {

    /**
     * @see GalleryPlatform::rename()
     */
    function rename($oldname, $newname) {
	/*
	 * Windows gets upset if the new file already exists.  If that's
	 * the case, remove the new file before renaming.
	 */
	if ($this->file_exists($newname)) {
	    @$this->unlink($newname);
	}
	return parent::rename($oldname, $newname);
    }

    /**
     * @see GalleryPlatform::exec()
     */
    function exec($cmdArray, $returnErrorOutput=false) {
	global $gallery;
	$gallery->guaranteeTimeLimit(5);

	/* Assemble the command array into a pipeline */
	$command = '';
	foreach ($cmdArray as $cmdAndArgs) {

	    if (!empty($command)) {
		$command .= ' | ';
	    }

	    foreach ($cmdAndArgs as $arg) {
		if ($arg === '>') {
		    $command .= '>';
		} else {
		    $command .= ' "' . $arg . '" ';
		}
	    }
	}

	/* We're going to redirect STDERR to a file */
	$tmpDir = $gallery->getConfig('data.gallery.tmp');
	$debugFile = tempnam($tmpDir, 'g2dbg');

	/*
	 * Ok, this is screwy, but for some reason these
	 * don't work:
	 *
	 *    cmd /c "c:\path with\spaces\binary" "arg"
	 *    cmd /c " c:\path\\ with\spaces\binary arg "
	 *    cmd /c " 'c:\path\ with\spaces\binary' 'arg' "
	 *
	 * But this does:
	 *
	 *    cmd /c " "c:\path with\spaces\binary" "arg" "
	 *
	 * Turns out that this is a documented feature of cmd.exe.
	 * See "cmd.exe /help" for more details
	 *
	 */
	$command = 'cmd /c "' . $command . ' 2> "' . $debugFile . '" "';

	if ($gallery->getDebug()) {
	    $gallery->debug("Executing: $command");
	}
	$results = array();
	exec($command, $results, $status);

	list ($ret, $expected) =
	    GalleryCoreApi::getPluginParameter('module', 'core', 'exec.expectedStatus');
	if ($ret->isError()) {
	    if ($gallery->getDebug()) {
		$gallery->debug('Unable to look up core.exec.expectedStatus param');
	    }
	    $expected = 0;
	}

	$stderr = array();
	if ($this->file_exists($debugFile)) {
	    if ($this->filesize($debugFile) > 0) {
		if ($fd = $this->fopen($debugFile, "r")) {
		    while (!$this->feof($fd)) {
			$buf = $this->fgets($fd, 4096);
			$buf = rtrim($buf);
			if (!empty($buf)) {
			    $stderr[] = $buf;
			}
		    }
		    $this->fclose($fd);
		}
	    }
	    $this->unlink($debugFile);
	}

	/* Dump any output we have */
	if ($gallery->getDebug()) {
	    $gallery->debug("Regular Output:");
	    foreach ($results as $line) {
		$gallery->debug($line);
	    }

	    $gallery->debug("Error Output:");
	    foreach ($stderr as $line) {
		$gallery->debug($line);
	    }
	    $gallery->debug("Status: $status (expected $expected)");
	}

	return array($status == $expected, $results, $stderr);
    }

    /**
     * @see GalleryPlatform::isRestrictedByOpenBaseDir
     */
    function isRestrictedByOpenBaseDir($path) {
	return $this->_isRestrictedByOpenBaseDir($path, ';', false);
    }

    /**
     * @see GalleryPlatform::is_executable
     */
    function is_executable($filename) {
	/* Any existing file is considered executable on Windows */
	return $this->file_exists($filename);
    }

    /**
     * @see GalleryPlatform::splitPath
     */
    function splitPath($path) {
	$list = array();
	if (preg_match('|^([A-Za-z]:)?[\\\/]|', $path, $match)) {
	    $list[] = $match[0];
	    $path = substr($path, strlen($match[0]));
	}
	foreach (preg_split('|[\\\/]|', $path) as $element) {
	    if (!empty($element)) {
		$list[] = $element;
	    }
	}
	return $list;
    }


    /**
     * @see GalleryPlatform::isSymlinkSupported
     */
    function isSymlinkSupported() {
	return false;
    }

    /**
     * @see GalleryPlatform::getLineEnding
     */
    function getLineEnding() {
	return "\r\n";
    }

    /**
     * @see GalleryPlatform::strftime
     */
    function strftime($format, $timestamp=null) {
	/* Windows doesn't have %e but has %#d, same thing but without leading space for 1-9 */
	return parent::strftime(str_replace('%e', '%#d', $format), $timestamp);
    }
}
?>
