#!/usr/local/bin/perl # # An implementation of 'unstr' in Perl. Written for the Perl # Power Tools (PPT) project by Theo Van Dinter (felicity@kluge.net). (C) 2000 # # $Id: unstr,v 1.2 2000/02/20 16:42:53 felicity Exp felicity $ # use Getopt::Std; use strict; use vars qw/$opt_c $opt_h $dfile $sfile $ofile $flags @offsets $delim/; &help unless getopts('hc:'); &help if ( $opt_h ); $dfile = shift || &help; $ofile = shift || "-"; $opt_c ||= "%"; # delimiter &help if ( @ARGV || length($opt_c) > 1 ); if ( $dfile =~ /\../ ) { # there's an extension ... ($sfile = $dfile) =~ s/\..+?$//; } else { # no extension ... $sfile = $dfile; $dfile .= ".dat"; } open(DAT,"<$dfile") || die "Can't open $dfile:$!"; # Read the flags and delimiter from the header... seek DAT, 16, 0; unless ( read(DAT, $flags, 4) == 4 && read(DAT, $delim, 1) ) { warn "Error reading header in $dfile!\n"; exit 1; } $delim = "$delim\n"; unless ( unpack("N",$flags) & 0x3 ) { # not ordered or random ... warn "Nothing to do, just use the source file (table in file order).\n"; exit 1; } seek DAT, 24, 0; # skip the header... { local $/=undef; # file slurp ... @offsets = unpack("N*", ); # suck the offsets into the array } close(DAT); # we're done with the input file... # No fortunes? Just quit, an empty dat file is useless. unless ( @offsets ) { warn "No fortunes found in file! Exiting!\n"; exit 1; } # Need to have at least 2 offsets in the file! unless ( $#offsets > 0 ) { warn "Incorrect number of offsets in $dfile! (<2)\n"; exit 1; } # Start the output phase! # open(FORT,"<$sfile") || die "Can't open $sfile:$!"; open(OUT,">$ofile") || die "Can't open $ofile:$!"; for(my($oset) = 0; $oset < $#offsets; $oset++ ) { seek FORT, $offsets[$oset], 0; # seek to head of fortune # everything up to EOF or delimiter char is the fortune, print it! print OUT while ( defined($_=) && ($_ ne $delim) ); # print the (possibly new) delimiter print OUT "$opt_c\n"; } close(OUT); close(FORT); # Print the darned usage statement! # sub help { print " usage: $0 [-h] [-c char] data_file[.ext] [output_file] -c char\tChange the output delimiter from the standard \"\%\". -h\tThis help message. "; exit 1; } # Pod Documentation ... =head1 NAME unstr - dump strings in pointer order =head1 SYNOPSIS B [ B<-h> ] [ B<-c char> ] I [ I ] =head1 DESCRIPTION The purpose of unstr is to undo the work of strfile. It prints out the strings contained in the source file, which is data_file.ext without its extension, or datafile if no extension is specified (in this case, the extension .dat is added to the name of the datafile) in the order that they are listed in the header file data_file. If output_file is not specified, it prints to standard output; otherwise it prints to the file specified. unstr can also universally change the delimiter character in a strings file. It is possible to create sorted versions of input files by using C and then using unstr to dump them out in the table order. =head1 OPTIONS AND ARGUMENTS =over 8 =item I<-h> Display the usage help message. =item I<-c char> Change the output delimiting character from the percent sign to C. =back =head1 RETURN VALUES strfile returns 0 on success or 1 if an error occurred. =head1 HISTORY Perl version written for the Perl Power Tools project from the description of the unstr program in RedHat Linux 6.1. =head1 AUTHOR Theo Van Dinter (felicity@kluge.net) =head1 SEE ALSO fortune(1), strfile(1)