$VERSION
=
do
{
my
@r
= (
q$Revision: 1.53 $
=~ /\d+/g);
sprintf
"%d."
.
"%02d"
x
$#r
,
@r
};
$| = 1;
my
$LOG_COUNTER
= 0;
my
$FILE_OPEN
= 0;
my
$LOG
=
''
;
sub
new {
my
$proto
=
shift
;
my
$class
=
ref
(
$proto
) ||
$proto
;
my
$o_conf
=
shift
;
if
(!
ref
(
$o_conf
)) {
croak(
"Log requires Perlbug::Config object($o_conf)!"
);
}
my
$sep
=
$o_conf
->
system
(
'separator'
);
my
$self
=
bless
({
'_file'
=> {
'handle'
=>
''
,
'status'
=>
''
,
'target'
=>
''
,
},
'_regex'
=>
'^(.+)'
.
$sep
.
'?([\w_]*)\.(\w+)'
,
},
$class
);
my
$rex
=
$self
->{
'_regex'
};
TGT:
foreach
my
$tgt
(
$self
->files) {
my
$target
=
$o_conf
->current(
"${tgt}_file"
);
if
(
$target
!~ /
$rex
$/) {
croak(
"Log tgt($tgt) doesn't match($rex) -> target($target)"
);
}
else
{
my
(
$dir
,
$file
) = ($1, $2.
'.'
.$3);
if
(!(
$dir
=~ /\w+/o && -d
$dir
&& -w _)) {
croak(
"Log can't log to $tgt dir($dir): $!"
);
}
else
{
$self
->
open
(
$tgt
,
$target
);
}
}
}
$LOG
=
$o_conf
->current(
'log_file'
);
$self
->set_user(
$o_conf
->
system
(
'user'
));
$self
->debug(0,
"INIT ($$) scr($0), debug($Perlbug::Debug) $self"
)
if
$Perlbug::DEBUG
;
return
$self
;
}
sub
files {
my
$self
=
shift
;
my
$pat
=
shift
||
'.+'
;
my
@files
=
grep
(/^
$pat
$/, @{
$self
->{
'_files'
}});
return
@files
;
}
sub
handle {
my
$self
=
shift
;
my
$tgt
=
shift
||
'log'
;
my
$fh
=
$self
->{
'_handle'
}{
$tgt
};
return
$fh
;
}
sub
DESTROY {
my
$self
=
shift
;
foreach
my
$tgt
(
$self
->files()) {
my
$fh
=
$self
->handle(
$tgt
);
undef
$fh
;
}
}
sub
debug {
my
$self
=
shift
;
my
$flag
=
shift
;
my
$debug
=
$Perlbug::Debug
||
''
;
if
(!
defined
(
$flag
)) {
$self
->logg(
"XXX: debug called with DUFF args($self, $flag, data(@_)"
);
}
else
{
my
$DATA
=
''
;
if
(
$flag
=~ /^([aAsS0123xX])$/o) {
if
((
$flag
=~ /^(\d)$/io &&
$debug
>=
$flag
) || (
$debug
=~ /
$flag
/)) {
if
(
$debug
=~ /[mM]/o) {
my
@caller
= ();
CALLER:
foreach
my
$i
(0..4) {
@caller
=
caller
(
$i
);
last
CALLER
if
$caller
[3] !~ /debug/i;
}
my
$caller
= ((
$debug
=~ /M/o) ?
"$caller[0]::$caller[3]"
:
"$caller[3]"
);
$caller
=~ s/^(?:\w+::)+(\w+)$/$1/;
$DATA
.=
"$caller: "
;
}
}
if
(
$flag
=~ /^(\d)$/io &&
$debug
>=
$flag
) {
$DATA
.=
"@_"
.((
$flag
>= 2) ?
"<- flag($flag)"
:
''
);
}
elsif
(
$debug
=~ /
$flag
/) {
$DATA
.=
"@_"
;
}
}
$self
->logg(
$DATA
)
if
$DATA
;
}
}
sub
_debug {
my
$self
=
shift
;
return
$self
->logg(
@_
);
}
sub
open
{
my
$self
=
shift
;
my
$file
=
shift
;
my
$perm
=
shift
;
my
$num
=
shift
;
my
$fh
=
$self
->handle(
$self
->fh(
$file
,
$perm
,
$num
));
if
(!
$fh
) {
$self
->error(
"no handle returned!"
);
}
else
{
$self
->status(
'open'
);
}
return
$self
;
}
sub
logg {
my
$self
=
shift
;
my
@args
=
@_
;
unshift
(
@args
, (
ref
(
$self
)) ?
''
:
$self
);
my
$data
=
substr
(
"[$LOG_COUNTER] "
, 0, 15).
join
(
' '
,
@args
,
"\n"
);
if
(
length
(
$data
) >= 25600) {
my
@caller
=
caller
(2);
$data
=
"Excessive data length("
.
length
(
$data
).
") called from @caller!\n"
;
}
my
$fh
=
$self
->fh(
'log'
,
'+>>'
, 0766);
if
(
defined
$fh
) {
flock
(
$fh
, 2);
$fh
->
seek
(0, 2);
print
$fh
$data
;
flock
(
$fh
, 8);
print
$data
;
}
else
{
carp(
"logg couldn't log($data) to undefined fh($fh)"
);
}
$LOG_COUNTER
++;
}
sub
fh {
my
$self
=
shift
;
my
$arg
=
shift
;
my
$ctl
=
shift
||
'+>>'
||
'<'
;
if
(
$arg
=~ /^[\w_]+$/o) {
my
$FH
=
$self
->{
"_${arg}_fh"
};
if
(!((
defined
(
$FH
)) && (
ref
(
$FH
)) && (
$FH
->isa(
'FileHandle'
)))) {
my
$file
=
$self
->{
"_${arg}_file"
};
if
(
$file
!~ /\w+/) {
my
$tgt
= (
$Perlbug::FATAL
>= 1) ?
$LOG
:
$arg
;
if
(-e
$tgt
&& -f _) {
$self
->{
$arg
.
'_file'
} =
$tgt
;
}
else
{
croak(
"Log::fh($arg) can't locate target($tgt) file."
);
}
}
my
$fh
= new FileHandle(
$file
,
$ctl
);
if
(
defined
$fh
) {
$fh
->autoflush(1);
$self
->{
"_${arg}_fh"
} =
$fh
;
$FILE_OPEN
++;
}
else
{
croak(
"Log::fh($arg) -> can't define filehandle($fh) for file($file) with ctl($ctl) $!"
);
}
}
}
else
{
return
new FileHandle(
$arg
,
$ctl
);
}
return
$self
->{
"_${arg}_fh"
};
}
sub
append {
my
$self
=
shift
;
my
$file
=
shift
;
my
$data
=
shift
;
my
$perm
=
shift
||
'0766'
;
my
$pos
=
''
;
if
(
$file
!~ /^\w{3,4}$/) {
$self
->error(
"Can't append to unrecognised key: '$file'"
);
}
else
{
$self
->debug(3,
'result storing '
.
$data
)
if
$Perlbug::DEBUG
;
my
$fh
=
$self
->fh(
$file
,
'+>>'
,
$perm
);
if
(
defined
$fh
) {
flock
(
$fh
, 2);
$fh
->
seek
(0, 2);
print
$fh
$data
;
$pos
=
$fh
->
tell
;
flock
(
$fh
, 8);
$self
->debug(3,
"Depth into '$file' file ($pos)"
)
if
$Perlbug::DEBUG
;
}
else
{
$self
->error(
"Didn't get a $file filehandle($fh) to append to. $!"
);
}
}
return
$pos
;
}
sub
read
{
my
$self
=
shift
;
my
$file
=
shift
;
my
@data
= ();
if
(
$file
!~ /\w+/) {
$self
->error(
"Can't read from '$file'"
);
}
else
{
my
$fh
=
$self
->fh(
$file
,
'<'
);
if
(
defined
(
$fh
)) {
$fh
->
seek
(0, 0);
@data
=
$fh
->getlines;
$self
->debug(2,
"Read '"
.
@data
.
"' $file lines"
)
if
$Perlbug::DEBUG
;
}
else
{
$self
->error(
"Unable to open $file file ($fh) for read: $!"
);
}
if
(!
scalar
@data
>= 1) {
$self
->debug(1,
"read($file) -> data($#data) looks short!"
)
if
$Perlbug::DEBUG
;
}
}
return
\
@data
;
}
sub
truncate
{
my
$self
=
shift
;
my
$file
=
shift
;
my
$i_ok
= 1;
if
(
$file
!~ /^\w+$/) {
$i_ok
= 0;
$self
->error(
"Can't truncate '$file'"
);
}
else
{
my
$fh
=
$self
->fh(
$file
,
'+<'
);
if
(
defined
(
$fh
)) {
$fh
->
seek
(0, 2);
$fh
->
seek
(0, 0);
$fh
->
truncate
(0);
$fh
->
seek
(0, 8);
$self
->debug(2,
"Truncated $file"
)
if
$Perlbug::DEBUG
;
}
else
{
$i_ok
= 0;
$self
->error(
"Unable to truncate file($file): $!"
);
}
}
return
$i_ok
;
}
sub
prioritise {
my
$self
=
shift
;
my
(
$priority
) = (
$_
[0] =~ /^\d+$/o) ?
$_
[0] : 12;
$self
->debug(2,
"priority'ing ($priority)"
)
if
$Perlbug::DEBUG
;
my
$pre
=
getpriority
(0, 0);
setpriority
(0, 0,
$priority
);
my
$post
=
getpriority
(0, 0);
$self
->debug(2,
"Priority: pre ($pre), post ($post)"
)
if
$Perlbug::DEBUG
;
return
$self
;
}
sub
set_user {
my
$self
=
shift
;
my
$user
=
shift
;
my
$oname
=
getpwuid
($<);
my
$original
=
qq|orig($oname, $<, [$(])|
;
my
@data
=
getpwnam
(
$user
);
($>, $), $<, $() = (
$data
[2],
$data
[3],
$data
[2],
$data
[3]);
my
$pname
=
getpwuid
($>);
my
$post
=
qq|curr($pname, $<, [$(])|
;
$self
->debug(2,
"user($user) original($original) post($post)"
)
if
$Perlbug::DEBUG
;
return
$self
;
}
sub
copy {
my
$self
=
shift
;
my
$orig
=
shift
;
my
$targ
=
shift
;
my
$perm
=
shift
||
'0766'
;
my
@data
= ();
my
$ok
= 1;
$self
->debug(1,
"copy called with orig($orig) and target($targ) and perms($perm)"
)
if
$Perlbug::DEBUG
;
my
$oldfh
= new FileHandle(
$orig
,
'<'
);
my
$newfh
= new FileHandle(
$targ
,
'+<'
,
$perm
);
if
(!(
defined
(
$oldfh
)) || (!
defined
(
$newfh
))) {
$ok
= 0;
$self
->error(
"Filehandle failures for copy: orig($orig -> '$oldfh'), targ($targ -> '$newfh')"
);
}
if
(
$ok
== 1) {
flock
(
$newfh
, 2);
while
(<
$oldfh
>) {
if
(
print
$newfh
$_
) {
push
(
@data
,
$_
);
}
else
{
$ok
= 0;
$self
->error(
"can't write to $targ: $!"
);
last
;
}
}
flock
(
$newfh
, 8);
}
close
(
$oldfh
)
if
defined
$oldfh
;
close
(
$newfh
)
if
defined
$newfh
;
if
(
$ok
== 1) {
$self
->debug(1,
"Copy ok($ok)"
)
if
$Perlbug::DEBUG
;
}
else
{
$self
->error(
"Copy($orig, $targ) failed($ok)"
);
}
return
(
wantarray
?
@data
:
$ok
);
}
sub
link
{
my
$self
=
shift
;
my
$orig
=
shift
;
my
$targ
=
shift
;
my
$mod
=
shift
||
''
;
my
$ok
= 1;
$self
->debug(1,
"link called with orig($orig) and target($targ)"
)
if
$Perlbug::DEBUG
;
if
(
$ok
== 1) {
if
(! -e
$orig
) {
$self
->error(
"Link failure: original($orig) doesn't exist to link from: $!"
);
}
else
{
my
$cmd
=
"ln $mod -s $orig $targ"
;
my
$res
=
system
(
$cmd
);
if
(
$res
== 1 || ! -l
$targ
) {
$self
->debug(0,
"Link($cmd) failed($res): $!"
)
if
$Perlbug::DEBUG
;
}
else
{
$self
->debug(1,
"Link($cmd) success"
)
if
$Perlbug::DEBUG
;
}
}
}
if
(
$ok
== 1) {
$self
->debug(1,
"Link ok($ok)"
)
if
$Perlbug::DEBUG
;
}
else
{
$self
->error(
"Link($orig, $targ) failed($ok)"
);
}
return
$ok
;
}
sub
create {
my
$self
=
shift
;
my
$file
=
shift
;
my
$data
=
shift
;
my
$perm
=
shift
||
'0766'
;
my
$ok
= 1;
if
((
$file
=~ /\w+/o) && (
$data
=~ /\w+/o)) {
$self
->debug(1,
"create called with file($file) and data("
.
length
(
$data
).
", perm($perm))"
)
if
$Perlbug::DEBUG
;
}
else
{
$ok
= 0;
$self
->error(
"Duff args given to create($file, $data, $perm)"
);
}
if
(
$ok
== 1) {
my
$fh
= new FileHandle(
$file
,
'>'
,
$perm
);
if
(
defined
(
$fh
)) {
flock
(
$fh
, 2);
print
$fh
$data
;
flock
(
$fh
, 8);
}
else
{
$ok
= 0;
$self
->error(
"Undefined target filehandle ($fh): $!"
);
}
}
return
$ok
;
}
sub
_syntax_check {
my
$self
=
shift
;
my
$file
=
shift
;
my
$ok
= 1;
if
(
$file
=~ /\w+/o) {
$self
->debug(1,
"syntax_check called with file($file)"
)
if
$Perlbug::DEBUG
;
if
(!-f
$file
) {
$ok
= 0;
$self
->error(
"File ($file) doesn't exist"
);
}
}
else
{
$ok
= 0;
$self
->error(
"Duff args given to syntax_check($file)"
);
}
if
(
$ok
== 1) {
eval
{
require
"$file"
;
};
if
($@) {
$ok
= 0;
$self
->error(
"Syntax problem with '$file': $@"
);
}
else
{
$self
->debug(1,
"Syntax looks OK for '$file': $@"
)
if
$Perlbug::DEBUG
;
}
}
return
$ok
;
}
1;