#!/usr/bin/perl # # Zebra does not create the directories where it stores MRT dumps, they # must already exist. MRT dumps are configured thusly # # dump bgp updates /storage/bgpdata/%Y.%m/UPDATES/updates.%Y%m%d.%H%M 15m # dump bgp routes-mrt /storage/bgpdata/%Y.%m/RIBS/rib.%Y%m%d.%H%M 2h # # take a FQPN as an argument: # # mkzebradirs /storage/bgpdata/%Y.%m/RIBS # # for each path component, make sure that the directory exists. if the path # component contains a strftime formatting token, one which does not contain # a token resulting in whitespace or /'s (eg: %h = " 2" for 2 oclock) or # seconds (which are just silly) (see strftimechars below), and make sure the # directory exists for the cases: # - current time # - +interval (-i) [default 1 hour] # - +1 day # # require module Time::CTime, available from CPAN.org. # BEGIN { $me = $0; $me =~ s/.*\/(\S+)$/$1/; } require 'newgetopt.pl'; require 'time.ph'; use Time::CTime; # process command line options $newgetopt'ignorecase=0; $newgetopt'autoabbrev=1; $result = &NGetOpt('d','h','i=i','m=i'); &usage($result) if (defined($opt_h) || $result == 0); my($debug) = (defined $opt_d) ? 1 : 0; my($interval) = (defined $opt_i) ? $opt_i : (60*60); my($mask) = (defined $opt_m) ? oct($opt_m) : 022; my($ts) = time(); # current time since epoch my($ecode) = 0; my($path); my($strftimechars) = "AaBbhCdGgHIjkMmpRTUuVWYymZz"; umask($mask); # there must be at least 1 arg if ($#ARGV < 0) { printf(STDERR "$me: too few arguments\n"); &usage(); } foreach $path (@ARGV) { my(@pathv) = split(/\//, $path); $ecode += pathrecurse(\@pathv); } exit($ecode); sub usage { print STDERR < -d prints useful debugging -h prints this message -i second offset from now in seconds [default 1 hour] -m umask for directory creation [default 022] USAGE exit $_; } sub pathrecurse { my($pathv) = @_; my(@pathv) = @$pathv; # dereference pathv[] my($i, $tmppath); my($ecode) = 0; for ($i = 0; $i <= $#pathv; $i++) { if ($pathv[$i] =~ /^$/) { next; } if ($pathv[$i] =~ /%[$strftimechars]/) { # once we hit a strftime path component we go recursive, looping # for each of the 3 time intervals. my($t); $tmppath .= "/" . $pathv[$i]; foreach $t (($ts, $ts + $interval, $ts + (60*60*24))) { my(@newpath); push(@newpath, strftime($tmppath, localtime($t))); for $t ($i+1 .. $#pathv) { push(@newpath, $pathv[$t]); } $ecode += pathrecurse(\@newpath); } return($ecode); } else { # just a plain path $tmppath .= "/" . $pathv[$i]; if (createdir($tmppath)) { $ecode++; break; } } } return($ecode); } sub createdir { my($path) = @_; my($ecode) = 0; if (! -e $path) { if (! mkdir($path)) { printf(STDERR "could not create dir $path: %s\n", $!); $ecode++; } } elsif (! -d $path) { printf(STDERR "$path exists but is not a directory\n"); $ecode++; } else { # stat data my($junk,$mode,$uid,$gid); ($junk,$junk,$mode,$junk,$uid,$gid,$junk,$junk,$junk,$junk, $junk,$junk,$junk) = stat($path); } return($ecode); }