A sample Perl CGI program that can be used to edit files on a web site

Below I've included a sample Perl CGI program that I use to edit some files on my web sites. I've modified the file a little bit for the purposes of this example, but it's essentially what I use.

Very Important: This program by itself is not secure in any way. It does not require a user login, etc. At the very least you will want to secure access to this program with an Apache htaccess configuration, or something similar on other Perl CGI web servers. This program is shown here for demonstration purposes only.

As an end user of this program, I basically hit the URL that corresponds to the location of this CGI program. The Perl CGI program first displays the contents of the desired file in a textarea, and lets me make changes to the file within that textarea. I can edit the contents of the file, then press Save, and it writes my changes back to the file. Simple, quick, efficient.

The biggest change I've made to this example is to hard-code the path to the data file that will be edited. A more flexible version of this program would leave the file path as a variable, letting you edit any file on your web site ... but that doesn't always strike me as a really safe thing to do, and I especially don't want to encourage something like that in a sample program like this.

Without any more delay here is the sample file. Like anything else I know if can be improved, but hey, it works fine for what I need.

#!/usr/bin/perl
#
# created by devdaily.com, for demonstration purposes only.
#
# note: this program is not secure, and must be secured by apache htaccess
#       or other security mechanisms.
#

$FILE = '/home/apache/htdocs/blog/blog.rss';

#------------------------<<  htmlDie  >>-----------------------#
#
#  print an error message to stdout, then exit
#
#--------------------------------------------------------------#

sub htmlDie 
{
  $msg = shift;
  print $msg;
  exit;
}

#-------------------<<  writeOutputFile  >>--------------------#
#
#  USAGE: writeOutputFile $filename @whatToWrite
#
#--------------------------------------------------------------#

sub writeOutputFile 
{
  my $theFilename = shift;
  my $theContents = shift;

  open (OUT, "> $theFilename") || \
    &htmlDie ("Error: Could not open output file!\n");

  my @contents = split '\n', $theContents;
  my $line;
  foreach $line (@contents)
  {
    chomp($line);
    next if ( $line =~ /^\s*$/m );
    print OUT "$line\n";
  }
  close (OUT);
}


#---------------------<<  readContents  >>--------------------#
#
#  USAGE:  @contents = &readContents(filename);
#
#--------------------------------------------------------------#

sub readContents
{
  my $fullFilename = shift;
  my @contents;
  open(FILE,$fullFilename);
  while (<FILE>)
  {
    push @contents, $_;
  }
  close(FILE);
  return @contents;
}
  
#---------------------<<  printEditForm  >>--------------------#
#
#  USAGE:  &printEditForm($header,@contents);
#
#--------------------------------------------------------------#

sub printEditForm
{
  my ($header,@contents) = @_;
  my $theContents;
  foreach $line (@contents)
  {
    next if ( $line =~ /^\s*$/m );
    $theContents = $theContents . $line;
  }
  print $query->h3($header);
  print $query->startform;
  print $query->hidden('action', "save");
  print $query->textarea(-name=>'TEXT_AREA',
        -default=>$theContents,
        -rows=>30,
        -columns=>80);
  print $query->br;
  print $query->submit(-value=>'Save Changes');
  print $query->endform;
  print $query->end_html;
}


#------------------------------#
#  1. Create a new CGI object  #
#------------------------------#

use CGI;
$query = new CGI;


#----------------------------------#
#  2. Print the doctype statement  #
#----------------------------------#

print $query->header;


#----------------------------------------------------#
#  3. Start the HTML doc, and give the page a title  #
#----------------------------------------------------#

print $query->start_html('RSS File Editor');


#---------------#
#  4. Do it. :) #
#---------------#

my $action = $query->param('action');
my $textAreaContents = $query->param('TEXT_AREA');

if ( $action eq "" )
{
  $fullFilename = $FILE;
  my @contents = &readContents($fullFilename);
  &printEditForm("Editing the RSS File",@contents);
  exit;
}
elsif ( $action eq "save" )
{
  my $fullFilename = $FILE;
  &writeOutputFile($fullFilename,$textAreaContents);
  my $header = "Editing File:  $FILE";
  $header = $header . "
(file saved)";
  my @contents = &readContents($fullFilename);
  &printEditForm($header,@contents);
  exit;
}

Note that you will need the Perl CGI module for this application.