1#!/usr/bin/perl 2# 3# odlaw - the waldo file viewer and manipulator 4# 5 6use strict; 7use warnings; 8#use 5.010; 9 10# 11# PERL INCLUDES 12# 13use Data::Dumper; 14use Getopt::Long; 15 16use constant { MAX_FILEPATH_BUF => 1024 }; 17 18my $options = { 19 file_read => '', 20 file_edit => '', 21 help => 0, 22 spooler_dir => '', 23 spooler_filebase => '', 24 record => 0, 25 timestamp => 0, 26 verbose => 0, 27 force => 0, 28}; 29 30 31# 32# 33# 34sub usage 35{ 36 print "\n"; 37 print "USAGE: $0 [-options]\n"; 38 print "\n"; 39 print " General Options:\n"; 40 print " -h You're reading it.\n"; 41 print " -v Verbose output.\n"; 42 print " -f Force (skip validation).\n"; 43 print " -r <file> File to read.\n"; 44 print " -e <file> File to edit.\n"; 45 print "\n"; 46 print " Long Options:\n"; 47 print " --help Same as '?'\n"; 48 print " --verbose Same as 'v'\n"; 49 print " --force Same as 'f'\n"; 50 print " --read Same as 'r'\n"; 51 print " --edit Same as 'e'\n"; 52 print " --filebase Filebase to filter files on.\n"; 53 print " --directory Directory to spool for files.\n"; 54 print " --timestamp Timestamp of file being processed (default: 0).\n"; 55 print " --record Record index of file being processed (default: 0).\n"; 56 print "\n"; 57} 58 59sub waldo_read 60{ 61 my ($file) = @_; 62 63 my @fields = ('spooler_dir', 'spooler_filebase', 'timestamp', 'record'); 64 my %values; 65 @values{@fields} = ('', '', 0, 0); 66 67 # read the data 68 if ( open (FD, "<$file") ) 69 { 70 my $waldo_raw = <FD>; 71 # unpack 72 @values{@fields} = unpack("Z[".MAX_FILEPATH_BUF."] Z[".MAX_FILEPATH_BUF."] L L", $waldo_raw); 73 74 close(FD); 75 } 76 77 # return as hash reference 78 return \%values; 79} 80 81sub waldo_validate 82{ 83 my ($data) = @_; 84 85 return ( $options->{force} || ( 86 defined($data->{spooler_dir}) && ( -e $data->{spooler_dir} ) && 87 defined($data->{spooler_filebase}) && 88 defined($data->{timestamp}) && 89 defined($data->{record}) 90 ) 91 ); 92} 93 94sub waldo_print 95{ 96 my ($data) = @_; 97 98 print "{\n"; 99 print " directory = " . $data->{spooler_dir} . "\n"; 100 print " filebase = " . $data->{spooler_filebase} . "\n"; 101 print " timestamp = " . $data->{timestamp} . "\n"; 102 print " record = " . $data->{record} . "\n"; 103 print "}\n"; 104} 105 106sub waldo_write 107{ 108 my ($file, $data) = @_; 109 110 # validate input 111 if ( ! waldo_validate($data) ) 112 { 113 print "[!] Provided waldo data is incomplete or corrupted."; 114 return; 115 } 116 117 # open and write 118 open (FD, ">$file") or die ('Unable to read file'); 119 120 my $packed = pack("Z[".MAX_FILEPATH_BUF."] Z[".MAX_FILEPATH_BUF."] L L", $data->{spooler_dir}, $data->{spooler_filebase}, $data->{timestamp}, $data->{record}); 121 print FD $packed; 122 123 close(FD); 124} 125 126 127# 128# MAIN 129# 130my $res = GetOptions( 131 'r|read=s' => \$options->{file_read}, 132 'e|edit=s' => \$options->{file_edit}, 133 'directory=s' => \$options->{spooler_dir}, 134 'filebase=s' => \$options->{spooler_filebase}, 135 'record=s' => \$options->{record}, 136 'timestamp=s' => \$options->{timestamp}, 137 'v|verbose' => \$options->{verbose}, 138 'f|force' => \$options->{force}, 139 'help|?' => \$options->{help}, 140); 141 142if( $options->{help} > 0 ) 143{ 144 usage(); 145 exit(0); 146} 147elsif( $options->{file_read} ) 148{ 149 my $data = waldo_read($options->{file_read}); 150 print 'waldo: ' . $options->{file_read} . "\n"; 151 waldo_print($data); 152 153 if ( ! waldo_validate($data) ) 154 { 155 print "[!] Read waldo data is incomplete or corrupted.\n"; 156 } 157} 158elsif( $options->{file_edit} ) 159{ 160 my $data = waldo_read($options->{file_edit}); 161 162 $data->{spooler_dir} = defined($options->{spooler_dir}) ? $options->{spooler_dir} : $data->{spooler_dir}; 163 $data->{spooler_filebase} = defined($options->{spooler_filebase}) ? $options->{spooler_filebase} : $data->{spooler_filebase}; 164 $data->{timestamp} = (defined($options->{timestamp}) ? $options->{timestamp} : $data->{timestamp}) + 0; 165 $data->{record} = (defined($options->{record}) ? $options->{record} : $data->{record}) + 0; 166 167 print "Preparing to write:\n"; 168 waldo_print($data); 169 170 waldo_write($options->{file_edit}, $data); 171} 172else 173{ 174 usage(); 175 exit(1); 176} 177 178