clean_dir.php: A php shell script

Purpose: Clean out a directory tree without deleting the directories or destroying their permissions. Don't delete files with certain extensions no matter where they are encountered. This is used to clean out a directory tree before using cvs export to publish new code.

clean_dir.php is pretty hastily hacked together - I'm sure others have written similar routines more gracefully - but it presented some interesting challenges:

  • I han't written php for the shell for a while. Had to review how to take user input from STDIN. Had to use ob_flush() to get win32 to display preliminary text before waiting for input .
  • subdirs() is a recursive function populating the variable $children which is passed as a reference.


<?php
include("lib_util.php"); //'n' = "\n"

// - and / will be parsed by php.exe on win32.
$help = array("-h", "-H", "/h", "/H", "help", "HELP", "?", "/?");

$USAGE = "Usage: ".$argv[0]." [x:\path\to\directory]".n;

$dbexts = array('cdx','dbf','tbk','dbc','qpr','dct','dcx','fxp','prg');

if (in_array(trim($argv[1]), $help) or (count($argv) > 2)) {
print $USAGE;
exit;
}

if ($argv[1]) {
//double \ widows path for php. trim trailing slash. trim whitespace.
$start = trim(trim(preg_replace("/(\\\)/", "\\\\\\", $argv[1]), "\\"));
// print "test: $start".n;
if (!preg_match("/^[a-z,A-Z]:\\\/", $start)) {
print "I don't like this path: $start".n;
print $USAGE;
exit;
}
} else {
$start = "E:\\foo\\bar";
}

print "REMOVE ALL FILES (but preserve directories and permissions)".n;
print "beginning here: " .preg_replace("/[\\\]{2}/", "\\", $start) .n.n;
print "Please confirm (y/n): ";
ob_flush(); //needed
$conf = getInput(2); //1 doesn't wait

if (stristr($conf, "y")) {
print n."Proceeding...".n.n;
} else {
print n."Exiting!".n;
exit;
}
ob_flush();

$children = array();
subdirs($start, &$children);

function subdirs($dir,&$children) {
global $today, $earliest, $limit;
$i = 1;

//print "got $dir, $chidren";

if($handle = @opendir($dir)) {
while(false !== ($file = readdir($handle))) {
// if (($limit <> 0) && ($i == $limit)) {print "hit limit".n; return;} //testing
if ($file != "." && $file != ".." ) {
if (is_dir($dir."\\".$file) == true) {
$fullpath = $dir."\\".$file;
// print n."Found Dir $fullpath".n.t;
array_push($children,$fullpath);
subdirs($fullpath, $children); //recurse!
$i++;
}
}
}
closedir($handle);
} else {
print "Error opening $dir".n;
}
}

foreach($children as $child) {

if($handle = @opendir(addslashes($child))) {
print "In Directory: $child".n;
while($file = readdir($handle)) {
if (($file == ".") || ($file == "..")) continue;
$pathfile = $child ."\\".$file;
if (is_file($pathfile)) {
if (in_array(strtolower(substr($file, strlen($file) - 3, strlen($file))), $dbexts)) {
print " NOT DELETING database file: $pathfile".n;
} else {
if (!unlink($pathfile)) print t."COULD NOT DELETE: $file".n;
}
}
}
} else {
print "*** ERROR OPENING $child".n;
}

}

function getInput($length = 255) {
$fr = fopen("php://stdin", "r");
$input = fgets($fr, $length);
$input = rtrim($input);
fclose($fr);
return $input;
}
?>