NAME
CGI::Application::Util::Diff
- Diff 2 directories or files, or run other commands
Synopsis
A classic CGI script:
use strict;
use warnings;
use CGI;
use CGI::Application::Dispatch;
# ---------------------
my($cgi) = CGI -> new();
CGI::Application::Dispatch -> dispatch
(
args_to_new => {QUERY => $cgi},
prefix => 'CGI::Application::Util',
table =>
[
'' => {app => 'Diff', rm => 'initialize'},
'/diff' => {app => 'Diff', rm => 'diff'},
],
);
A modern FCGI script:
use strict;
use warnings;
use CGI::Application::Dispatch;
use CGI::Fast;
use FCGI::ProcManager;
# ---------------------
my($proc_manager) = FCGI::ProcManager -> new({processes => 2});
$proc_manager -> pm_manage();
my($cgi);
while ($cgi = CGI::Fast -> new() )
{
$proc_manager -> pm_pre_dispatch();
CGI::Application::Dispatch -> dispatch
(
args_to_new => {QUERY => $cgi},
prefix => 'CGI::Application::Util',
table =>
[
'' => {app => 'Diff', rm => 'initialize'},
'/diff' => {app => 'Diff', rm => 'diff'},
],
);
$proc_manager -> pm_post_dispatch();
}
Description
CGI::Application::Util::Diff
diffs 2 directories or files, or runs other commands. on the web server's machine.
The output of a directory diff is a table, where the Match column contains a red 'x' if there is a mis-match in the sizes of a file or sub-directory in the 2 given directories.
You click on a file name, or any field in the row, and a menu appears (beside the Diff button) which contains the actions available.
The output of a file diff is the output of the shell's diff command.
Available actions are in the file lib/CGI/Application/Util/Diff/.htutil.diff.actions.conf. They are listed below.
There is an action confirmation option in this file, which you are strongly advised to leave as is.
The confirmation is effected by means of a call to the Javascript confirm() function.
I hope this will be the first in a set of such tools. I plan to release any of my own under the same namespace CGI::Application::Util::*
.
Since I expect this set to grow, I've decided to immediately adopt a Javascript library, rather than struggle with a more ad hoc approach. And the Yahoo User Interface, YUI, is the one I like the most.
This module was developed using YUI V 2.7.0b.
Security
This module does not incorporate any security protection whatsoever.
If you need any more convincing that this module is unsafe because it runs shell commands, there is plenty of info on the net about this topic. For instance:
http://hea-www.harvard.edu/~fine/Tech/cgi-safe.html
Actions
Overview
The actions will actually be run under the user who is running the web server.
This is often a fake human called nobody or daemon.
Such special user accounts normally have deliberately restricted permissions, so you might find the commands don't appear to do anything.
How you solve that on your machine is a security issue you must deal with.
Details
This is the contents of .htutil.diff.actions.conf:
[global]
# This option, when 1, causes a Javascript confirm() message box
# to pop-up before the action is sent to the server.
# If not present, the value defaults to 1.
confirm_action = 1
# The option limits output of the file_diff action.
# If not present, the value defaults to 100.
max_diff_line_count = 100
# Actions
# -------
# Format: Name = Shell command (except for 'cd') = Javascript menu text.
# The duplication is deliberate. It allows 'action' to be validated, because the first token
# on each line is sent to the client, and returned by the CGI form field 'action'
# when the user selects an action from the menu.
#
# Also, in CGI::Application::Util::Diff::Actions, all of these keys are stored in a single hash.
#
# For Perl equivalents of these shell commands, see:
# o File::Copy::Recursive
# o File::Tools
# o File::Util
[dir]
# The 'cd' commands don't actually use the shell's 'cd',
# and neither do they use Perl's 'chdir'.
# Rather, the CGI form fields 'left' and 'right'
# have the chosen directory appended. This emulates 'cd'.
dir_cd_both = cd = Change directory on both sides
dir_cd_left = cd = Change directory on left side
dir_cd_right = cd = Change directory on right side
# For here on down, they are shell commands.
# Warning: Don't use anything which prompts, e.g. mv -i,
# or your app will hang, making you look r-e-a-l-l-y stupid!
dir_cp_left2right = cp -fprv = Copy directory from left side to right
dir_cp_right2left = cp -fprv = Copy directory from right side to left
dir_mv_left2right = mv -fv = Move directory from left side to right
dir_mv_right2left = mv -fv = Move directory from right side to left
dir_rm_both = rm -frv = Remove directory from both sides
dir_rm_left = rm -frv = Remove directory from left side
dir_rm_right = rm -frv = Remove directory from right side
[file]
file_cp_left2right = cp -fpv = Copy file from left side to right
file_cp_right2left = cp -fpv = Copy file from right side to left
file_diff = diff = Run 'diff' on left and right files
file_mv_left2right = mv -fv = Move file from left side to right
file_mv_right2left = mv -fv = Move file from right side to left
file_rm_both = rm -frv = Remove file from both sides
file_rm_left = rm -frv = Remove file from left side
file_rm_right = rm -frv = Remove file from right side
A Note on Diff
The file_diff action, unlike the other actions, has the potential to output a great deal of text.
To help protect against that, the file .htutil.diff.actions.conf has a [global] section containing the line:
max_diff_line_count = 100
This is the maximum number of lines of output from diff which are transferred from this module to the web client.
It's set large enough to give you a clear indicator that the 2 files being diffed are indeed different, without being so large as to overwhelm the web client.
Contents
CGI::Application::Util::Diff
ships with:
- Two instance scripts: util.diff.cgi and util.diff
-
util.diff.cgi is a trivial
CGI
script, while util.diff is a fancy script which usesFCGI::ProcManager
.Both use
CGI::Application::Dispatch
.Trivial here refers to using a classic
CGI
-style script, while fancy refers to using a modernFCGID
-style script.The word fancy was chosen because it allows you to use fancier URLs. For samples, see Start Testing, below.
The scripts are shipped as httpd/cgi-bin/util.diff.cgi and htdocs/local/util.diff.
These directory names were chosen because you'll be installing util.diff.cgi in your web server's cgi-bin/ directory, whereas you'll install util.diff in a directory under your web server's doc root.
For home-grown modules, I use the namespace Local::*, and for local web server scripts I use the directory local/ under Apache's doc root.
For
FCGID
, see http://fastcgi.coremail.cn/.FCGID
is a replacement for the olderFastCGI
. ForFastCGI
, see http://www.fastcgi.com/drupal/.Also, edit util.diff.cgi and util.diff to fix the 'use lib' line. See the Note in those files for details.
- A set of
HTML::Template
templates: *.tmpl -
See htdocs/assets/templates/cgi/application/util/diff/*.
- A config file for
CGI::Application::Util::Diff
-
See lib/CGI/Application/Util/Diff/.htutil.diff.conf.
- A config file for
CGI::Application::Util::Diff::Actions
-
See lib/CGI/Application/Util/Diff/.htutil.diff.actions.conf.
- A config file for
CGI::Application::Util::Logger
-
See lib/CGI/Application/Util/.htutil.logger.conf.
- A patch to httpd.conf, if you run Apache and FCGID.
-
See httpd/conf/httpd.conf.
Yes, I realise that if you run FCGID you already have this patch installed, but there's nothing wrong with having such information documented in various places.
Lastly, the config files .htutil.*.conf are installed by both Build.PL and Makefile.PL.
Bells and Whistles
For a huge range of features, in a package developed over many years, see Webmin:
http://www.webmin.com/
However, I could not see anything in Webmin's standard packages which offered the same features as this module. And that's probably because of security concerns.
Logging
CGI::Application::Util::Diff
ships with a default logging module, CGI::Application::Util::Logger
.
The option to activate logging is 'logging', in .htutil.diff.conf.
If this line is missing, no attempt is made to log.
Note: The logger's own config file, .htutil.logger.conf by default, might also turn logging off.
The default 'logging' line looks something like:
logger=CGI::Application::Util::Logger=/some/dir/CGI/Application/Util/.htutil.logger.conf
You'll notice it refers to the Util/ directory, not the Util/Diff/ directory.
This is because this logging mechanism is meant to be shared among all modules in the CGI::Application::Util::*
namespace.
This version of CGI::Application::Util::Diff
does not contain a menuing system for such utilities, because there is as yet only this 1 module, but later versions will.
If the logging class cannot be loaded (with 'require'), the error is ignored, and no logging takes place, but a message is written to the web-server's log with Carp::carp
.
Distributions
This module is available as a Unix-style distro (*.tgz).
See http://savage.net.au/Perl-modules/html/installing-a-module.html for help on unpacking and installing distros.
Installation
At the very least, you will need to patch .htutil.diff.conf, since that's where HTML::Template
's tmpl_path is stored, if using another path.
Config file options are documented in the config file itself.
Also, you may want to edit .htutil.logger.conf and .htutil.diff.actions.conf.
Install the module
Note: Build.PL and Makefile.PL refer to FCGI::ProcManager
. If you are not going to use the fancy script, you don't need FCGI::ProcManager
.
Install CGI::Application::Util::Diff
as you would for any Perl
module:
Run cpan: shell>sudo cpan CGI::Application::Util::Diff
or unpack the distro, and then either:
perl Build.PL
./Build
./Build test
sudo ./Build install
or:
perl Makefile.PL
make (or dmake)
make test
make install
Install the HTML::Template
files.
Copy the distro's htdocs/assets/ directory to your doc root.
Install the trivial instance script
Copy the distro's httpd/cgi-bin/util.diff.cgi to your cgi-bin/ directory, and make util.diff.cgi executable.
Install the fancy instance script
Copy the distro's htdocs/local/ directory to your doc root, and make util.diff executable.
Configure Apache
to use /local/util.diff
If in fancy mode, add these to Apache
's httpd.conf:
LoadModule fcgid_module modules/mod_fcgid.so
and:
<Location /local>
SetHandler fcgid-script
Options ExecCGI
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
Of course, use of '/local' is not mandatory; you could use any URL fragment there.
And don't forget to restart Apache
after editing it's httpd.conf.
Start testing
Point your broswer at http://127.0.0.1/cgi-bin/util.diff.cgi (trivial script), or http://127.0.0.1/local/util.diff (fancy script).
FAQ
- The command did nothing!
-
What you mean is that it did not perform according to your false expectations, and/or you did not read the section called Actions.
The user running the web server is the user who runs these actions, and hence their limited permissions means the actions are limited in what they are allowed to do.
- The log always contains the word 'message'!
-
Right! The log is a database table, and the column heading you refer to should be there.
Author
CGI::Application::Util::Diff
was written by Ron Savage <ron@savage.net.au> in 2009.
Home page: http://savage.net.au/index.html
Copyright
Australian copyright (c) 2009, Ron Savage. All Programs of mine are 'OSI Certified Open Source Software'; you can redistribute them and/or modify them under the terms of The Artistic License, a copy of which is available at: http://www.opensource.org/licenses/index.html