#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use constant BASE_DIR => '/home/ken/tmp/pm_11143050';
use constant {
LEN_BASE_DIR => length BASE_DIR,
FS_DIR => BASE_DIR . '/fs',
};
use Cwd 'abs_path';
use Data::Dump;
my %fs_map;
walk_fs(FS_DIR, \%fs_map);
dd \%fs_map;
sub walk_fs {
my ($path, $fs_map) = @_;
opendir(my $dh, $path);
while (readdir $dh) {
next if /^\.{1,2}$/;
my $entry = "$path/$_";
my $fs_path = fs_path($entry);
if (-f $entry) {
$fs_map->{$fs_path} = [file => []];
}
elsif (-l $entry) {
$fs_map->{$fs_path} = [link => [canon_path($entry)]];
}
elsif (-d $entry) {
if (exists $fs_map->{fs_path($path)}) {
push @{$fs_map->{fs_path($path)}[1]}, canon_path($entry);
}
$fs_map->{$fs_path} = [dir => []];
walk_fs($entry, $fs_map);
}
else {
warn "IGNORED '$entry': not a plain file, link or directory.\n";
}
}
closedir $dh;
return;
}
sub fs_path {
return substr $_[0], LEN_BASE_DIR;
}
sub canon_path {
return substr abs_path($_[0]), LEN_BASE_DIR;
}
####
ken@titan ~/tmp/pm_11143050
$ ls -lR fs
fs:
total 0
drwxr-xr-x+ 1 ken None 0 Apr 19 03:49 a
drwxr-xr-x+ 1 ken None 0 Apr 19 02:46 t
fs/a:
total 1
prw-rw-rw- 1 ken None 0 Apr 19 03:49 a_named_pipe
drwxr-xr-x+ 1 ken None 0 Apr 19 02:46 b
-rw-r--r-- 1 ken None 0 Apr 19 02:36 d
lrwxrwxrwx 1 ken None 5 Apr 19 02:42 r -> b/c/z
drwxr-xr-x+ 1 ken None 0 Apr 19 02:46 u
lrwxrwxrwx 1 ken None 8 Apr 19 02:35 x -> ../a/b/c
fs/a/b:
total 0
drwxr-xr-x+ 1 ken None 0 Apr 19 02:46 c
-rw-r--r-- 1 ken None 0 Apr 19 02:37 e
lrwxrwxrwx 1 ken None 1 Apr 19 02:40 q -> y
drwxr-xr-x+ 1 ken None 0 Apr 19 02:46 v
lrwxrwxrwx 1 ken None 1 Apr 19 02:37 y -> .
fs/a/b/c:
total 0
-rw-r--r-- 1 ken None 0 Apr 19 02:38 f
lrwxrwxrwx 1 ken None 7 Apr 19 02:40 p -> ../../x
drwxr-xr-x+ 1 ken None 0 Apr 19 02:46 w
lrwxrwxrwx 1 ken None 6 Apr 19 02:38 z -> ../../
fs/a/b/c/w:
total 0
fs/a/b/v:
total 0
fs/a/u:
total 0
fs/t:
total 0
####
ken@titan ~/tmp/pm_11143050
$ ./mapfs.pl
IGNORED '/home/ken/tmp/pm_11143050/fs/a/a_named_pipe': not a plain file, link or directory.
{
"/fs/a" => ["dir", ["/fs/a/b", "/fs/a/u"]],
"/fs/a/b" => ["dir", ["/fs/a/b/c", "/fs/a/b/v"]],
"/fs/a/b/c" => ["dir", ["/fs/a/b/c/w"]],
"/fs/a/b/c/f" => ["file", []],
"/fs/a/b/c/p" => ["link", ["/fs/a/b/c"]],
"/fs/a/b/c/w" => ["dir", []],
"/fs/a/b/c/z" => ["link", ["/fs/a"]],
"/fs/a/b/e" => ["file", []],
"/fs/a/b/q" => ["link", ["/fs/a/b"]],
"/fs/a/b/v" => ["dir", []],
"/fs/a/b/y" => ["link", ["/fs/a/b"]],
"/fs/a/d" => ["file", []],
"/fs/a/r" => ["link", ["/fs/a"]],
"/fs/a/u" => ["dir", []],
"/fs/a/x" => ["link", ["/fs/a/b/c"]],
"/fs/t" => ["dir", []],
}