#!/usr/bin/perl
while
(
@ARGV
&&
$ARGV
[0] =~ s/^-//) {
local
$_
=
shift
;
while
(/([cdfq])/g) {
if
($1 eq
'd'
) {
$opts
{
'd'
} = /\G(.*)/g && $1 ? $1 :
shift
;
}
else
{
$opts
{$1}++;
}
}
}
local
$SIG
{__WARN__} =
$opts
{
'q'
} ?
sub
{} :
sub
{
print
@_
};
$ENV
{1} =
$opts
{
'c'
} ||
$opts
{
'f'
} ?
'-c'
:
''
;
while
(<>) {
last
if
/^[
}
die
"No script found.\n"
unless
$_
;
if
(
$opts
{
'd'
}) {
chdir
$opts
{
'd'
} ||
die
"Can't chdir '$opts{'d'}': $!"
;
}
%test
= (
'eq'
,
'=='
,
'ne'
,
'!='
,
'gt'
,
'>'
,
'ge'
,
'>='
,
'lt'
,
'<'
,
'le'
,
'<='
,
'='
,
'eq'
,
'!='
,
'ne'
,
'<'
,
'lt'
,
'>'
,
'gt'
,
);
while
(<>) {
next
if
/^[
s/^\s+//;
s/\$(\w+)/
$ENV
{$1}/g;
for
(/`([^`]+)`/g) {
if
(/wc -c < (\S+)/) {
$filename
= $1;
$filename
=~ s/^
'(.*)'
$/$1/ ||
$filename
=~ s/^
"(.*)"
$/$1/ ||
$filename
=~ s/\\(.)/$1/;
$ENV
{
$_
} = -s
$filename
;
}
else
{
$ENV
{
$_
} = `
$_
`;
}
}
s/`([^`]+)`/
$ENV
{$1}/g;
if
(
$if
) {
if
(/^fi/) {
$if
--;
pop
@expr
;
next
;
}
if
(/^
else
/ &&
defined
$expr
[
$#expr
]) {
$expr
[
$#expr
] =
$expr
[
$#expr
] ? 0 : 1;
next
;
}
next
unless
$expr
[
$#expr
];
}
$endmark
= $1
if
s/<<\s*(\S+)//;
if
(
$endmark
) {
$endmark
=~ s/^
'(.*)'
$/$1/ ||
$endmark
=~ s/^
"(.*)"
$/$1/ ||
$endmark
=~ s/\\(.)/$1/;
$endmark
.=
"\n"
;
}
if
(s/^echo //) {
s/["']//g;
warn
$_
;
}
elsif
(/^export\s+PATH|^PATH\s*=/) {
next
;
}
elsif
(s/^
mkdir
\s*//) {
die
"Reference to parent directory"
if
m|\.\./|;
die
"Reference to absolute directory"
if
m|\s[/~]|;
if
(s/;(.*)//) {
$rem
= $1;
}
else
{
$rem
=
''
;
}
s/\s+$//;
s/^
'(.*)'
$/$1/ || s/^
"(.*)"
$/$1/ || s/\\(.)/$1/;
mkdir
(
$_
, 0777) ||
die
"Couldn't mkdir '$_': $!"
;
$_
=
$rem
;
redo
if
$rem
;
}
elsif
(/^cat\s+(>+)\s*(\S+)\s*$/) {
$redir
= $1;
$filename
= $2;
$filename
=~ s/^
'(.*)'
$/$1/ ||
$filename
=~ s/^
"(.*)"
$/$1/ ||
$filename
=~ s/\\(.)/$1/;
die
"Reference to parent directory"
if
$filename
=~ m|\.\./|;
die
"Reference to absolute directory"
if
$filename
=~ m|^[/~]|;
open
(FILE,
'<'
,
"$redir$filename"
) ||
die
"Can't create $filename"
;
while
(<>) {
last
if
$_
eq
$endmark
;
print
FILE
$_
;
}
close
FILE;
}
elsif
(/^sed\s+(.*\S)\s+(>+|\|)\s*(\S+)\s*$/ ||
/^sed\s+(>+|\|)\s*(\S+)\s+(.*\S)\s*$/) {
if
(
substr
($1,0,1) eq
'>'
) {
$redir
= $1;
$filename
= $2;
$sedcmd
= $3;
}
else
{
$sedcmd
= $1;
$redir
= $2;
$filename
= $3;
}
$filename
=~ s/^
'(.*)'
$/$1/ ||
$filename
=~ s/^
"(.*)"
$/$1/ ||
$filename
=~ s/\\(.)/$1/;
die
"Reference to parent directory"
if
$filename
=~ m|\.\./|;
die
"Reference to absolute directory"
if
$filename
=~ m|^\s*[/~]|;
die
"Illegal sed command"
if
$sedcmd
=~ /[|;`<\$]/;
$sedcmd
=~ s/^-e\s*//;
$sedcmd
=~ s/^
'(.*)'
$/$1/ ||
$sedcmd
=~ s/^
"(.*)"
$/$1/ ||
$sedcmd
=~ s/\\(.)/$1/;
die
"Can only do s command in sed"
unless
$sedcmd
=~ /^s/;
die
"Can't do multiple commands"
if
$sedcmd
=~ /;/;
warn
"$redir$filename\n"
;
if
(
$filename
eq
'uudecode'
) {
$_
= <ARGV>;
/^begin\s+(\d+)\s+(\S+)/ ||
die
'Missing uuencode header'
;
open
(FILE,
'>'
, $2) ||
die
"Can't create '$2'"
;
binmode
FILE;
eval
sprintf
'
while
(<>) {
warn
$_
;
last
if
/^end$/;
%s
;
$_
=
unpack
(
"u"
,
$_
);
print
FILE;
}
',
$sedcmd
;
while
(
$_
= <>) {
last
if
$_
eq
$endmark
;
}
}
else
{
open
(FILE,
'>'
,
$filename
) ||
die
"Can't create $filename: $!"
;
binmode
FILE;
eval
sprintf
'
while
(<>) {
warn
$_
;
last
if
$_
eq
$endmark
;
%s
;
print
FILE;
}
',
$sedcmd
;
}
close
FILE;
}
elsif
(/^
exit
/) {
$_
= <>
until
$_
eq
''
|| /^[
exit
unless
$_
;
}
elsif
(/^
chmod
\s+(0\d{3})\s+(\S+)\s*$/) {
(
$mode
,
$filename
) = ($1, $2);
$filename
=~ s/^
'(.*)'
$/$1/ ||
$filename
=~ s/^
"(.*)"
$/$1/ ||
$filename
=~ s/\\(.)/$1/;
$mode
=
oct
(
$mode
);
chmod
(
$mode
,
$filename
);
}
elsif
(/^touch\s+-([am]+t)\s+(\d{8})(\.\d\d)?\s+(\S+)\s*$/) {
(
$type
,
$date
,
$sec
,
$filename
) = ($1, $2, $3, $4);
eval
(
'use Time::Local'
);
next
if
$@;
$filename
=~ s/^
'(.*)'
$/$1/ ||
$filename
=~ s/^
"(.*)"
$/$1/ ||
$filename
=~ s/\\(.)/$1/;
(
$mon
,
$mday
,
$hour
,
$min
) =
$date
=~ /(..)/g;
$sec
||= 0;
$sec
=~
tr
/.//d;
$time
= timelocal(
$sec
,
$min
,
$hour
,
$mday
,
$mon
- 1, (
localtime
)[5]);
$atime
=
$type
=~ /a/ ?
$time
: (
stat
$filename
)[8];
$mtime
=
$type
=~ /m/ ?
$time
: (
stat
$filename
)[9];
utime
(
$atime
,
$mtime
,
$filename
);
}
elsif
(/^(\w+)=(\S*)/) {
(
$name
,
$value
) = ($1, $2);
$value
=~ s/^
'(.*)'
$/$1/ ||
$value
=~ s/^
"(.*)"
$/$1/ ||
$value
=~ s/\\(.)/$1/;
$ENV
{
$name
} =
$value
;
}
elsif
(s/^
if
\s+//) {
$if
++;
$a
=
'test\s+'
;
$z
=
'\s*(;|&&|\|\|)'
;
s/
$a
(-[df])\s+(\S+)
$z
/$1 $2 $3/go;
s/
$a
(\d+)\s+-(eq|ne|gt|ge|lt|le)\s+(\d+)
$z
/$1
$test
{$2} $3 $4/go;
s/
$a
([^
']+)\s+(!?=|>|<)\s+([^'
]+)
$z
/
'$1'
$test
{$2}
'$3'
$4/go;
s/
$a
([^
"]+)\s+(!?=|>|<)\s+([^"
]+)
$z
/
"$1"
$test
{$2}
"$3"
$4/go;
s/
$a
(\w+)
$z
/
length
$1 $2/go;
s/;\s
*then
\s*$/\n/;
push
@expr
,
/test/ ?
undef
:
eval
(
$_
) ? 1 : 0;
}
else
{
$r
=
$_
;
$lines
= 1;
while
(<>) {
++
$lines
;
$r
.=
$_
;
last
if
/^
exit
/;
}
if
(
$_
) {
$_
= <>
until
$_
eq
''
|| /^[
}
open
(REM,
'>'
,
".r"
) ||
die
"Can't create .r"
;
print
REM
$r
;
close
REM;
chmod
0700,
'.r'
;
if
(
$lines
> 21 || !
open
(TTY,
'<'
,
'/dev/tty'
)) {
print
"Could not run remainder of kit. Inspect .r and run it\n"
;
exit
;
}
else
{
print
"Could not run remainder of kit. Inspect this.\n$r"
;
print
"Run it? [y] "
;
$ans
= <TTY>;
system
'.r'
if
$ans
=~ /^y/i;
}
exit
unless
$_
;
}
}