1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#!/usr/bin/env slsh
try
{
require ("cmdopt");
require ("fswalk");
}
catch AnyError:
{
() = fprintf (stderr, "error while evaluating\n%s\n", __get_exception_info.message);
exit (1);
}
private variable
MAXDEPTH = NULL,
DIR_SEPARATOR = "/",
VERSION = "0.2",
LICENSE = "GNU GPL version 2 or later";
#ifdef WIN32
DIR_SEPARATOR = "\\";
#endif
private define print_version ()
{
() = fprintf (stdout, "%s (version %s)\nLicense: %s\n", path_basename (__argv[0]),
VERSION, LICENSE);
exit (0);
}
private define print_usage ()
{
variable
if_opt_err = _NARGS ? () : "",
msg = [
_NARGS ? sprintf (" OPTION ERROR\n%s\n", if_opt_err) : "",
"Description:",
" Search for dangling symbolic links in the filesystem",
"",
sprintf ("Usage:\n %s [options] [dir] [dir...]\n", path_basename (__argv[0])),
"Options:",
" --maxdepth=depth descend to 'depth' level into the directory hierarchy",
" -h, --help print this message",
" --version print version and license",
"",
"If no `dir' is specified in the command line arguments `dir' defaults to the",
"current directory.",
"",
"If no `--maxdepth' is specified then the script \"walks\" into the directory",
"hierarchy, untill no other directories have to be proceed.",
"",
"If `--maxdepth=0' is specified then the search for dangling links is done",
"only to the top level directory.",
];
() = array_map (Integer_Type, &fprintf, _NARGS ? stderr : stdout, "%s\n",
_NARGS ? msg : msg[[1:]]);
exit (_NARGS);
}
private define file_callback (file, st)
{
if (stat_is ("lnk", st.st_mode))
if ((NULL == stat_file (file)) && (errno == ENOENT))
{
() = fprintf (stdout, "\e[31mBroken link found: %s %s\e[m\n", file,
errno_string (errno));
#ifexists readlink
() = fprintf (stdout, "\e[33m%s: points to %s\e[m\n", file, readlink (file));
#endif
}
return 1;
}
private define dir_callback (dir, st)
{
if (length (strtok (dir, DIR_SEPARATOR)) > MAXDEPTH)
return 0;
return 1;
}
private define get_badlinks (dir, maxdepth)
{
ifnot (NULL == maxdepth)
MAXDEPTH = length (strtok (dir, DIR_SEPARATOR)) + maxdepth;
variable w = fswalk_new (NULL == MAXDEPTH ? NULL : &dir_callback, &file_callback);
w.walk (dir);
}
define slsh_main ()
{
variable
i,
dir,
maxdepth = NULL,
c = cmdopt_new (&print_usage);
c.add("maxdepth", &maxdepth;type = "int");
c.add("h|help", &print_usage);
c.add("version", &print_version);
i = c.process (__argv, 1);
dir = (i < __argc) ? __argv[[i:]] : ["."];
array_map (Void_Type, &get_badlinks, dir, maxdepth);
exit (0);
}
|