"Linux Gazette...making Linux just a little more fun!"
Displaying CVS Version Control Numbers in Webpages
By
- Introduction
- Perl script displaying version number
- Security
- Conclusion
- References
Introduction
For a few years, I have been writing articles. A silly person named Phil Hunter from Central Ohio Linux User Group suggested to me several times to put version control on the articles. Of course, that is just one more thing to do in a long list of things to do. As usual, when certain things come together, then I pick up on old ideas and make them happen. The conditions were the following:
- After working at Cisco in the EMAN and INFOSEC groups, I learned how to use CVS in some detail. I printed out the CVS manual available at genericbooks.com. Now I use CVS for everything I do.
- After using SSI, PHP, Mason, ASP, EmbPerl, ePerl, and other Perl server side include modules for Apache for quite a few years, it became trivial to create a Perl script to open of a CVS file, read it contents, and print out the results.
- I have a lot of documents, and it is time I keep version control.
Perl script displaying version number
In order to make it easy so that every document can use the same command, I use this server side include command that comes with Apache. PHP, Perl ASP, Mason, and other server side scripting languages also have similar commands.
<!--#include virtual="/ssi/cvs_version.pl" -->
I also have it configured so that all webpage can use server side includes commands by putting this into my apache httpd.conf file.
<Directory "/usr/local/apache_gnujobs/htdocs">
Options All Indexes FollowSymLinks MultiViews ExecCGI Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
AddType text/html .shtml
AddHandler server-parsed .shtml .html .htm .shtm
Here is a text version of the perl script, or you can also copy and paste it from this document below.
#!/usr/bin/perl
print "Content-type: text/html\n\n\n\n";
### Get the name of the file being requested.
my $Temp = $ENV{'REQUEST_URI'};
my $Cvs = $Temp;
### Split the url by "/".
my (@Junk) = split(/\//, $Cvs);
### Get the end of the url, which is the filename.
my $File = pop @Junk;
$Cvs =~ s/[^\/]+$//g;
### Attach the document root directory so we get the complete path to the
### file on our computer server. Also, attach the CVS/Entries name so that
### we get the CVS information.
$Cvs = $ENV{'DOCUMENT_ROOT'} . $Cvs . "CVS/Entries";
### Open the file, and if we find a match, record it to $Match
my $Match = "";
open(FILE,$Cvs);
while (my $Line = <FILE>)
{
if ($Line =~ /$File/) {$Match = $Line; chomp $Line}
}
close FILE;
### If match is not found, print not found, otherwise get the information.
if ($Match eq "") {print "No CVS information found. '$File'\n";}
else
{
### Get the information we want and print it out.
my ($Junk,$File,$Version,$Date,@Junk) = split(/\//, $Match);
print "Version <b>$Version</b> : Date Last Changed <b>$Date</b>\n";
}
Security
There is a potential problem with security when you use my perl script above. Anybody can read your files located in the CVS directories. I don't know if this is a big concern to most people, and it really isn't a concern to me, but just in case, I blocked reading of the files in any CVS directory by using these commands in my httpd.conf file for my Apache webserver. This is a simple way of doing it. I am not going to have any files or directories that end their names with the words "Root", "CVS", "Repository", or "Entries", so to me it works fine.
<Files ~ "CVS$">
Order allow,deny
Deny from all
</Files>
<Files ~ "Root$">
Order allow,deny
Deny from all
</Files>
<Files ~ "Repository$">
Order allow,deny
Deny from all
</Files>
<Files ~ "Entries$">
Order allow,deny
Deny from all
</Files>
Conclusion
Using CVS to manage version control of documents, programs, and scripts is great. Using CVS and my perl script to display the version number of the document is a satisfactory way of keeping version control of your documents. I have no need to make it more advanced, so it works for me.
Some silly things to do:
- Check to see if CVS directory and files exist before opening up to read them. Doesn't matter since I assume the person putting in the server side include command should know what they are doing and it wouldn't really do anything bad anyways.
- Use a better regular expression match which will make the webserver reject "/CVS/" anywhere in the requested url from the client browser. This would be better than rejecting only specific files. This doesn't matter to me.
- This doesn't work with Alias in the httpd.conf file. At least, I don't think it does.
- Check to see if the date of the file matches the date in CVS. This lets you know if your document is out of sync with the CVS respository. This isn't important to me.
References
- If this article changes, it will be available here http://www.gnujobs.com/Articles/15/CVS_SSI.html.
- CVS: Concurrent Versions System by Mark Nielsen
Mark works as an independent consultant donating time to causes like GNUJobs.com, writing articles, writing free software, and working as a volunteer at eastmont.net.
Copyright © 1/2001 Mark Nielsen
Article Version 1.3 : Date Last Changed Sun Feb 25 21:13:16 2001
Copyright © 2001, Mark Nielsen.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 64 of Linux Gazette, March 2001