Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
Version 1.0.0 + phpunit tests
  • Loading branch information
finalclap committed May 17, 2015
1 parent 8044101 commit e23ef87
Show file tree
Hide file tree
Showing 14 changed files with 1,205 additions and 22 deletions.
8 changes: 2 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
composer.phar
vendor/

# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
/build/*.phar
/tests/sandbox
16 changes: 2 additions & 14 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Apache License
 Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

Expand Down Expand Up @@ -175,18 +175,7 @@

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright {yyyy} {name of copyright owner}
Copyright 2015 Vincent Paré

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -199,4 +188,3 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

46 changes: 44 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,44 @@
# DirScan
File system inventory
DirScan - file system inventory
-------------------------------
DirScan is a file cataloging command line tool that lists all files inside a directory and its sub-directories to a text file, with file attributes like timestamps and permissions.

It can be used to compare all files in an entire partition at different times and see what changed between.

Example :

```
dirscan --deep --same-device / > "drive-content.txt"
```

DirScan is bundled with a text reporter, but you can customize its output by creating a custom reporting class, allowing to save data to, say, CSV, XML or an SQLite database.

### Download ###
Download dirscan.phar, make it executable (chmod +x dirscan.phar) and rename it if you want. On Linux, store it to `/usr/local/bin` to make it available everywhere :

```
wget https://github.com/finalclap/DirScan/releases/download/1.0.0/dirscan.phar
chmod +x dirscan.phar
mv dirscan.phar /usr/local/bin/dirscan
```

### Requirement ###
Tested on PHP 5.3, 5.4, 5.5 & 5.6. There is also a [legacy release](https://raw.githubusercontent.com/finalclap/DirScan/master/src/legacy/dirscan) that works on PHP 5.2 with some limitations.

### Usage ###
```
Usage :
dirscan [OPTIONS] TARGET
Options :
--help, -h This help message
--deep, -d Explore symbolic links (default : skip)
--flat, -f Do not explore subdirectories
--access, -a Report access time
--htime Report user friendly date nearby unix timestamps
--same-device Explore only directories on the same device as the start directory
Useful on Linux, to ignore special mount points like /sys or /proc
```

### About windows ###

DirScan is designed to work a Unix environment (Linux or Mac OS) but you can also use it on Windows. In this case, beware of NTFS junction points and symbolic links that are not handled properly by old php releases (see [readlink](http://php.net/manual/en/function.readlink.php) & [is_link](http://php.net/manual/fr/function.is-link.php)). But you'd better use other tools like [WhereIsIt](http://www.whereisit-soft.com/).
30 changes: 30 additions & 0 deletions build/build.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
/**
* This file is part of DirScan.
*
* Package the app into a phar archive
* @package DirScan
*/

$srcRoot = __DIR__.'/../src';

$phar = new Phar(__DIR__.'/dirscan.phar', 0, 'dirscan.phar');
$phar->startBuffering();

// Removing shebang from dirscan
$dirscan = file_get_contents($srcRoot.'/dirscan');
$dirscan = preg_replace('/^#!.*?[\n\r]+/', '', $dirscan);

// Adding files
$phar['dirscan'] = $dirscan;
$phar['DirScan.php'] = file_get_contents($srcRoot.'/DirScan.php');
$phar['Reporter.php'] = file_get_contents($srcRoot.'/Reporter.php');
$phar['CliReporter.php'] = file_get_contents($srcRoot.'/CliReporter.php');

// Get the stub
$defaultStub = $phar->createDefaultStub('dirscan');
$stub = '#!/usr/bin/env php'."\n".$defaultStub;
$phar->setStub($stub);

$phar->stopBuffering();
echo "Build done (dirscan.phar)"."\n";
8 changes: 8 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="dirscan">
<directory>tests/DirScan</directory>
</testsuite>
</testsuites>
</phpunit>
148 changes: 148 additions & 0 deletions src/CliReporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php
/**
* This file is part of DirScan.
*
* Displays scanned files path and attributes (sent by DirScan::scan) on standard output
* @package DirScan
*/

namespace Finalclap\DirScan;

class CliReporter extends Reporter
{
protected $access; // bool Report node access time (default false)
protected $htime; // bool Display human readble date/time beside unix timestamp (default false)
protected $typeMapping; // array Short name for file types

/**
* Set report settings
*
* @param array $settings List of report settings
*/
public function __construct($settings)
{
$this->access = isset($settings['access']) ? $settings['access'] : false;
$this->htime = isset($settings['htime']) ? $settings['htime'] : false;
$this->typeMapping = array(
'dir' => 'd',
'file' => 'f',
'link' => 'l'
);
}

/**
* Print report header
*
* @param string $target Target directory
* @param array $settings List of report settings
* @param array $argv Command line arguments
*/
public function header($target, $settings, $argv)
{
$targetStat = DirScan::stat($target);

echo "time: ".time()."\n";
echo "date: ".date('r')."\n";
echo "getenv(TZ): ".getenv('TZ')."\n";
echo "date_default_timezone_get: ".date_default_timezone_get()."\n";
echo "php version: ".phpversion()."\n";
echo "cwd: ".getcwd()."\n";
echo "target: ".$target." (realpath: ".$targetStat['realpath'].")\n";
echo "start device: ".$targetStat['dev']."\n";
echo "settings: ".json_encode($settings)."\n";
echo "argv: ".json_encode($argv)."\n";
echo "=====================================\n";

$header = array(
'Unique path',
'Type',
'Size',
);

$header[] = 'ctime';
if ($this->htime) {
$header[] = 'Change time';
}

$header[] = 'mtime';
if ($this->htime) {
$header[] = 'Modify time';
}

if ($this->access) {
$header[] = 'atime';
if ($this->htime) {
$header[] = 'Access time';
}
}

$header[] = 'Extended';
echo implode("\t", $header)."\n";
}

/**
* Print node data
*
* @param array $node Data returned by DirScan::stat
* @param DirScan $scanner DirScan object
*/
public function push($node, DirScan $scanner)
{
$type = isset($this->typeMapping[$node['type']]) ? $this->typeMapping[$node['type']] : $node['type'];
$perms = substr(sprintf('%o', $node['mode']), -4);
if ($this->htime) {
$hctime = date('d/m/Y H:i:s', $node['ctime']);
$hmtime = date('d/m/Y H:i:s', $node['mtime']);
$hatime = date('d/m/Y H:i:s', $node['atime']);
}

$extended = array();
if (isset($node['target'])) {
$extended['target'] = $node['target'];
}
$startDevice = $scanner->startDevice;
if ($node['dev'] != $startDevice) {
$extended['device'] = $node['dev'];
}

$row = array(
$node['uniquepath'],
$type,
$node['size'],
);

$row[] = $node['ctime'];
if ($this->htime) {
$row[] = $hctime;
}

$row[] = $node['mtime'];
if ($this->htime) {
$row[] = $hmtime;
}

if ($this->access) {
$row[] = $node['atime'];
if ($this->htime) {
$row[] = $hatime;
}
}

if (!empty($extended)) {
$row[] = json_encode($extended);
}

echo implode("\t", $row)."\n";
}

/**
* Print error messages on stderr
*
* @param string $msg Error message
* @param int $code Error code
*/
public function error($msg, $code = null)
{
file_put_contents('php://stderr', $msg."\n");
}
}
Loading

0 comments on commit e23ef87

Please sign in to comment.