#!/usr/bin/perl -w # = HISTORY SECTION ===================================================================== # --------------------------------------------------------------------------------------- # version | date | author | changes # --------------------------------------------------------------------------------------- # 2.01 |30.12.99| ets | added more CPAN specific POD sections; # | | ets | first CPAN release; # 2.00 |16.09.99| ets | translated POD into English; # |28.12.99| ets | removed private module access; # | | ets | bugfix: option -nocopyright took no effect; # | | ets | replaced calls of bug() by Carp::confess(); # | | ets | made handling of non CPAN module Admin::File::Lock optional, # | | | depending on its availability; # | | ets | added usual option checks; # | | ets | removed unused temporary directory and file handling; # | | ets | translated remaining messages into English; # |30.12.99| ets | added CPAN script categories; # | | ets | replaced Admin::Oen::xxx() calls by internal code because # | | | Admin::Oen is no public module; # 1.12 |30.06.99| ets | class file2handle: added methods READ() and WRITE(); # | | ets | target script is forced now to run under perl 5.005 at least; # 1.11 |24.06.99| ets | bugfix in own open;$main::_runningUnderRSC; # | | ets | the tunneled script can now check if it runs under rsc # | | | control, because rsc sets $main::_runningUnderRSC now; # | | ets | bugfix in localized stat() and lstat() calls; # | | ets | modified file test operator translation slightly; # |25.06.99| ets | chmod() and chown() are overridden now; # 1.10 |25.03.99| ets | completed POD once more ...; # | | ets | removed forgotten debug traces; # | | ets | bugfixes in directive handling (complex conditions); # 1.09 |24.03.99| ets | target host is no longer pinged in tracelevel 1; # | | ets | added new tracelevel 256; # | | ets | added new directive #!TRACE##; # | | ets | directive can now contain a combined condition; # | | | (#TRACE#[\+|\|+]#); # | | ets | new option -lresponse; # | | ets | added trace to show tunneled @ARGV; # 1.08 |19.03.99| ets | added a restriction hint: interaction; # |23.03.99| ets | implemented real redirection of Storable::retrieve(); # 1.07 |19.03.99| ets | temporary files now named process specifically; # | | ets | calls of _rscFiletest() are now generated WITH parantheses; # 1.06 |19.03.99| ets | added target script support for Getopt::ArgvFile; # | | ets | rsc now checks the target host first by ping; # | | ets | documented default response file handling; # 1.05 |17.03.99| ets | switched from Admin::Oen::response() to # | | | Getopt::ArgvFile::argvFile(); # | | ets | completed POD; # |18.03.99| ets | improved AUTOLOAD(); # 1.04 |15.03.99| ets | added controlable remote traces; # | | ets | added really overloaded stat() and lstat(); # | | ets | overloaded file test operators, stat() and lstat() can # | | | handle the special argument '_' correctly now; # | | ets | improved by running a hpf script; # 1.03 |12.03.99| ets | added new option -interpreter; # | | ets | completed POD; # 1.02 |10.03.99| ets | added File::Path::mkpath() localization; # |11.03.99| ets | added AUTOLOAD() for non overriden file access functions; # | | ets | added file test operator localization; # | | ets | extended POD; # | | ets | fixes and improvements; # 1.01 |09.03.99| ets | the first version working with "serverspace -mode scan"; # 1.00 |09.03.99| ets | new. # --------------------------------------------------------------------------------------- # = POD SECTION ========================================================================= =head1 NAME rsc - "tunnels" another Perl script =head1 SCRIPT CATEGORIES Networking UNIX/System_administration =head1 VERSION This documentation describes version B<2.01>. =head1 DESCRIPTION =head2 Overview B executes a (Perl!-)Script on another host. Neither this target script, nor B or parts of it, nor input or output files I to be located on the target machine. There's no need to prepare the target system in any I way. No special deamon has to run there, only perl 5.005 or higher with a few modules installed and an rsh deamon are required. Additionally, this remote perl installation needs installations of the modules the executed script wants to use. If the work is done, B cleans up the target host even if it dies accidentially (or) by a signal. No zombie in the process list, no remaining file on disk (except of those which might be written by the executed script, of course). Communication is done I via STDIN, STDOUT and STDERR. (This makes it easy to establish a secure connection between the initiating and the target machine if B is installed. Encryption will be done automatically.) Ideally, the called script has not to be prepared for this kind of execution. Every script that runs standalone should be a good candidate for tunneling by B - well, in fact, there really I I which are documented in section "I". =head2 Why doing jobs this way? Of course, every script can be called I or via B if you need remote execution. But in reality, this is difficult sometimes: =over 4 =item In a network I saw, hosts for administration purposes were especially installed and prepared. A host inside the cell could access all other hosts in the net, but only cell hosts could access other cell hosts. Important scripts normally were located inside the cell to hide them from "normal" users and were intended to be executed only inside the cell. But some day there was a need to execute scripts I the cell - but still without making them available there. =item Mounts between servers are a real problem if NFS becomes unavailable. That's why administrators of a certain network decided to forbid such cross mounts. But now, if a script should be run on several servers and reads or produces data in a shared directory, there is a new problem because of the missed mounts, and finding a real good solution becomes difficult. =back B was designed as a solution to this kind of problem. =head2 How does it work? Well, this is hidden in tricky code. This section provides an overview of the used techniques. If it sounds too complicated, feel free to skip it and simply use the tool. 1) The target script is analyzed and modified I. Default option files are solved I if a call of B<(Getopt::ArgvFile::)argvFile()> is detected. 2) B starts a remote process which you can imagine a kind of a I. 3) The prepared target script is sent to the server. 4) The server executes the received target script on the remote machine. File handling is redirected to the I process on the I system if it works in directories the user predeclared as "local". (To do so, the I process called a server before takes control and acts as a I performing operations on the initial system via the initial process which acts as a I in this step. Just to confuse you. ;-) 5) If the target script is executed completely, remote and initial process terminate transparently without leaving zombies or helper files on the target system. =head2 Does it work for my script too? There is a real chance. That's why I decided to publish this script on CPAN. Nevertheless, it was designed to tunnel a I (large) script which is tunnelled successfully. The algorithm is complex and I restrictions, so there is no guarantee for other scripts to be executable this way too. Please check out the I section. =head1 SYNOPSIS rsc [] -- [] Please note that "--" is absolutely necessary to mark where B options are complete. Without this flag, B would read the target script options as well (and remove them from the command line). If the target script uses I by calling I<(Getopt::ArgvFile::)argvFile()>, B takes care of them automatically. They will be resolved on the I side, and B will pass them to the target script using @ARGV. =head2 Options All options can be abbreviated uniqly. =over 4 =item -help displays an online help and terminates the script. =item -interpreter The B which should be executed on the target machine to start the target script. Without such a hint, B tries to evaluate the target scripts "shebang" line. To make the target script runnable under B control, the passed interpreter should be a perl of version 5.003 or above, ideally 5.005 or above. The is no need of built in multitheading support. The modules I, I and I have to be installed. =item -localize redirects file access to this directory or any subdirectory from the target machine back to the initial system. This is useful if the path is (under your account) not to be found on the target host or if access to it should be avoided on the target system. Example: If the target script checks a directory for existence which is located under the specified path, B redirects this file check transparently a way that it is performed on the I system. The check result will be passed to the target script which is running on the target system. This option may be used multiply. =item lresponse Usually, B passes all target script options unmodified to the target script. With this option set, B is called on the I side so that option files are solved I. Example: If the target options include an option file hint like "-a -b @optionFile", it usually would be passed to the target script on the target machine, where "optionFile" would be searched and resolved. Now, possibly this file is located in a path not to be found on the target system. No problem, use -lresponse, and rsc will solve the option file on the initial system BEFORE the results are passed to the target side. Please see B for details about option files. =item -nocopyright suppresses the copyright message; =item -noinfo supresses runtime informations; =item -nowarn supresses warnings; =item -quiet a shortcut for "-nocopyright -noinfo -nowarn": all non critical runtime messages are suppressed; =item -trace [] activates traces of the specified level. You may use the environment variable SCRIPTDEBUG alternatively. Note: certain levels I the amount of data transfered between the involved machines and may slow down the operation therefore. Stufen: =over 20 =item one (1) The target script is not tunnelled but reported on STDOUT in its final generated represantation. One may redirect this to a file which can be executed on the target system manually, e.g. under debugger control. The behaviour of the generated script can be controled by level 256. =item two (2) This level is currently not in operation. =item four (4) traces everything the remote process sends to the initial side. =item eight (8) reports running local actions. =item sixteen (16) reports current remote actions. =item thirtytwo (32) traces everything the initial process sends to the target side. =item sixtyfour (64) traces code executed remotely. I =item hundredtwentyeight (128) activates hint messages pointing to function calls in the remote script which should better be redirected to the initial machine. See the I section for details. =item twohundredfiftysix (256) if you choose trace level 1 to execute the result on the target system yourself, the generated script will still iinteract with a "local" process via STDIN and SDOUT. Because the initial process is now I, and I are the one controling STDIN and STDOUT, I have to answer the script. This may become nerveracking ... To help you, level 256 activates I for the following operations: opening, closing, checking (, locking and releasing) of a file on the initial side are automatically flagged as I as well as making directories by I. =back Levels are combined by addition. To use levels 1 I 4, enter a level of 5. (Internally, combination is done bitwise, so if you use a random level, results depend from set bits of existing level numbers.) Examples: -trace 1 # 1 -trace 2 # 2 -trace 3 # 1 and 2 -trace 4 # 4 -trace 5 # 1 and 4 -trace 6 # 2 and 4 -trace 7 # 1, 2 and 4 =back =head2 Option files Options may be loaded from files where they are stored exactly as you write them in the command line, but may be spread to several lines and extended by comment lines which start with a "#" character. To mark an option file in the commandline, simply enter its (path and) name prededed by a "@" character. Option files may be nested. To avoid endless recursion, every option file is resolved only the first time it is detected. The script also takes care of a I. =head1 RETURN VALUES =head1 ENVIRONMENT VARIABLES =over 4 =item SCRIPTDEBUG may be set to a numeric value to activate certain trace levels. You can use option I<-trace> alternatively. The several levels are described with this option. =back =head1 NOTES The concept of B is new and only proved with a few scripts. (Nevertheless, proved successfully.) This is why I still call it alpha software which will grow for a certain period with every additionally tunnelled script. Please send a message if you see a way to improve it or anything does not work. This section describes both the ways of implementation and known problems. =head2 Implementation To work on another system, you need a kind of I to operate on your request. B initially uses B which can usually be found on every UNIX system around, and starts a short Perl script remotely. This first remote script works as follows: it receives the target task (as code and additional data) using a minimal protocol. After a startup signal, it translates the received code and executes it. From this point on, all operations are determined by this received and now running code, which communicates with the initial process on the initial machines which acts as a server now. This is possible because it was manipulated by the same initial process before it was sent to the remote side. That is why this concept offers a wide range of data transfer and remote control - the I (which is in fact B) prepared both sides and did it on the fly. This principle is the base concept of B. Thanks to perl and the work of certain module authors, namely B, the code which performes it is significantly shorter than my description above. To implement this concept, B uses a number of special Perl features. The original target script code is modified a way that it can act as a client which can delegate file access to the initial process if necessary. After modification, it is sent to the installed remote process. The modification is done using the following features: =over 4 =item tie() File access to directories in a path specified by option I<-localize> should be redirected to the initial machine. To enforce this behaviour, B overwrites B a way that it checks a passed file name for its path and generates a tied "handle" instead of a real one if necessary. This tied handle is an object of a small special class and works a way that all access to it is redirected to method calls of the tied class. These methods send commands via STDOUT to the server process acting at the initial side, which performs the file access I and sends results back to the target side where the methods receive it via STDIN. Literature note: See "perldoc perltie", "Programming Perl" and "Advanced Perl Programming" for details about B. =item Overidden functions The overiding of B was already mentioned in the section about B usage. Other functions need overiding, too, because they are working on file handles but are not integrated into I - currently these are B, B, B and B. So the overidden versions can work with the tied handles, too. And there are still more which are I currently overidden yet but should be done, these are B, B, B, B, B, B, B and B. The reason overidden versions are currently not there is simply that nobody used it in tunneled script until now. They should be added on request. =item Replaced functions There are cases when a redirection to the initial machine cannot be implemented via B. File check operators, for instance, currently cannot be overridden like B or B, nor are they covered by I. That is why B I them by calls of a special functions which redirects file access as necessary. Without further details, here comes a list of more replaced functions which may be extended if necessary: B. (The module B, if available, is overridden by a self defined subclass a way that its objects can act tunnelled as expected, this module is an internal wrapper around B and not currently published on CPAN.) =back =head2 Restrictions and Problems The following list is surely incomplete, but this is what I currently know. There are workarounds, but unfortunately they often break the concept of an "unprepared target code". B B cannot be used with I script. This restriction is caused by the way of implementation: =over 4 =item rsc needs to run under perl 5.005 or above. Earlier versions do not provide the necessary features. =item A script which already uses tricks of rsc cannot be tunneled. Obviously, the same trick cannot be used twice. That means that if the target script code overrides perl functions which are overridden by B as well, or uses B on handles B reclaims for itself, tunneling becomes a real challenge. =item Code replacements depend on style. Function replacements are done by pattern matching. Function calls not matching expected calling styles may remain undetected and unreplaced and could cause an unexpected behaviour when executed. These are the assumptions made: File check operators are expected at line start, after an opening paranthesis or after a whitespace. They are I before a closing bracket ("}"). Workaround if replacements fail: Modify the target script and use interpolated strings as file parameter, they should be detected correctly. =item Actions in used modules mostly I be redirected to the initial machine because B cannot see and modify the code for them which is hidden in the modules. This is true for both plain Perl and C modules. Exeption: if a file is opened in the I
script and tied by B, all functions which are wrapped by I (B, B, <>, B, B, B and B) should I even in C modules which use the Perl API. =item Files opened in modules cannot be redirected by B for the same reasons. Examples are B and B. Workaround: These calls have to be wrapped by B. For B and B, this wrapping is already implemented. =item Interaction cannot be fully provided yet. For instance, I found no way to make a remotley working texteditor be usable via B. =back B =over 4 =item Overloading There are more candidates for overriding: eof(), fileno(), ioctl(), fcntl(), chdir(), opendir(), readdir(), closedir(), Currently, all calls of them are performed unmodified (remotely). This is even true if a call of B leads the script to a directory in a path specified by I<-localize>. The tunneling of directory handling is an open question. Is it useful? Consequent tunneling here in fact means to install a virtual mount point. On teh other hand, it would fit the initial design targets of B. Ideas are welcome. =item select() Reading or writing files via this function is currently not possible. (I am speaking about the select(, , , []).) =back B A third group of problems is unfortunately caused by bugs in the current perl version. So teh following may be difficult: =over 4 =item Using a handle multiply if the connected files are located in pathes specified by I<-localize>. Workaround: sorry, use different handles. =item redirected handles passed to functions in C modules According to "Advanced Perl Programming", C modules should delegate access to a tied handle transparently to the specified "replacement function". Unfortunately, this does not work (or not everytime). Workaround: adding B wrappers. If this is impossible, there may be alternative functions using file names instead of handles which I be wrapped - e.g., you may use B and B instead of B and B. B and B are already wrapped by B. =back =head2 Runtime control A script can detect if it is currently executed under B control by checking $main::_runningUnderRSC. =head2 Troubleshooting Increase the trace level step by step. Note the possibilities given by level 1. =head2 Generating help The script description is stored I the script in POD and may be transformed into various formats by the usual converters like B, B etc. =head1 FILES =head2 Default option file At startup time, the script searches for a file I<.rsc> in its own installation directory (the path used to call it) and automatically resolves it as an I