#!/usr/local/bin/perl -w
# Copyright (C) 2003,2004 Robert Casties, IT-Group MPIWG
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# Please read license.txt for the full details. A copy of the GPL may be found
# at http://www.gnu.org/copyleft/lgpl.html
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# Library with definitions and common routines for MPIWG storage system
# scripts
#
package MPIWGlib;
use strict;
use vars qw(@ISA @EXPORT $VERSION
$debug %junk_files $file_perm $index_file_perm);
use Exporter;
$VERSION = 0.1; # ROC 19.2.2004
@ISA = qw(Exporter);
@EXPORT = qw($debug %junk_files $file_perm $index_file_perm
&parseargs &logger &stime &ymd_date &split_file_path &sstrip &valid_file_name
&valid_dir_name &read_xml &write_xml);
# debug level
$debug = 0;
# junk files
%junk_files = (
'.HSResource' => '.HSResource',
'.HSancillary' => '.HSancillary',
'.HSicon' => '.HSicon',
'Network Trash Folder' => 'Network Trash Folder',
'TheVolumeSettingsFolder' => 'TheVolumeSettingsFolder',
'.DS_Store' => '.DS_Store'
);
# default permissions for normal index files (rw-rw-r--)
$index_file_perm = 0664;
# default permissions for other files (rw-rw-r--)
$file_perm = 0664;
#
# $param_hash = parseargs;
#
# reads @ARGV and returns a hash with all options like "-option=value"
# and the last part of the string as "path"
#
sub parseargs {
my %opts;
foreach my $s (@ARGV) {
if ($s =~ /^-([^=]+)=*(.*)$/) {
$opts{$1} = ($2) ? $2 : $1;
} else {
$opts{'path'} = $s;
}
}
return \%opts;
}
#
# logger($level, $message)
#
# logs the $message (mostly to stdout)
# Messages with the level DEBUG will be suppressed if $debug is false.
#
sub logger {
my ($level, $message) = @_;
if ($debug || ($level ne "DEBUG")) {
print "$level: $message\n";
}
}
#
# $stime = stime($utime)
#
# format utime (seconds since epoch) into string
# representation: "YYYY/MM/DD HH:MM:SS"
#
sub stime {
my ($utime) = @_;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime($utime);
my $yy = $year + 1900;
my $mm = $mon + 1;
my $stime = sprintf("%d/%02d/%02d %02d:%02d:%02d",
$yy, $mm, $mday, $hour, $min, $sec);
return $stime;
}
#
# $date = ymd_date($olddate)
#
# converts a date string in mm/dd/yy format to yyyy/mm/dd format
#
sub ymd_date {
my ($mdy) = @_;
my $ydm;
if ($mdy =~ /(\d+)\/(\d+)\/(\d+)/) {
my $m = $1;
my $d = $2;
my $y = $3;
# extend yy to yyyy
$y = ($y < 70) ? (2000 + $y) : (($y < 100) ? ($y + 1900) : $y);
$ydm = sprintf "%d/%02d/%02d", $y, $m, $d;
}
return $ydm;
}
#
# ($name, $path) = split_file_path($fn)
#
# splits the file path $fn into
# file name (the last path element) and path
#
sub split_file_path {
my ($fn) = @_;
if ($fn =~ /^(.*)\/([^\/]+)$/) {
return ($2, $1);
}
return $fn;
}
#
# $name = sstrip($name)
#
# strips leading and trailing whitespace from $name
#
sub sstrip {
my ($name) = @_;
if ($name =~ /\s*(.*)\s*/) {
return $1;
}
return $name;
}
#
# $valid = valid_file_name($name)
#
# checks if $name is a valid file name
#
sub valid_file_name {
return valid_name($_[0], 0);
}
#
# $valid = valid_dir_name($name)
#
# checks if $name is a valid directory name
#
sub valid_dir_name {
return valid_name($_[0], 1);
}
#
# $valid = valid_name($name, $mode)
#
# checks if $name is a valid file ($mode=0) or directory name (mode=1)
#
sub valid_name {
my ($name, $mode) = @_;
# whitespace?
if ($name =~ /\s+/) {
return 0;
}
# invalid characters
if ($name !~ /^[-\w.\/]+$/) {
return 0;
}
# files have extension
if ($mode == 0) {
if ($name !~ /\.[-\w]+$/) {
return 0;
}
}
return 1;
}
#
# ($document, $rootnode) = read_xml($file)
#
# reads xml meta file $file
# returns root node element
#
sub read_xml {
my ($file) = @_;
my $document;
my $parser = XML::LibXML->new();
if (! $parser) {
logger("ABORT", "unable to create parser for metadata index file!!");
exit 1;
}
logger("INFO", "index file: $file");
eval { $document = $parser->parse_file($file) };
# catch parsing errors
if ($@) {
logger("ABORT", "XML syntax error in index file!!");
exit 1;
}
my $rootnode = $document->documentElement;
logger("INFO", "root element: \'" . $rootnode->nodeName . "\'");
return ($document, $rootnode);
}
#
# write_xml($document, $file)
#
# saves the XML tree of $document to the file $file
#
sub write_xml {
my ($document, $filename) = @_;
# keep backup copy
if (-f $filename) {
if (! rename $filename, "$filename.old") {
logger("ABORT", "unable to change file $filename!");
exit 1;
}
}
# write new file
if ($document->toFile($filename)) {
logger("INFO", "written new file $filename");
chmod $index_file_perm, $filename;
} else {
logger("ABORT", "unable to write file $filename!");
exit 1;
}
}
# module init
return 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>