#!/usr/bin/perl # # cgi-cal.pl by Anthony Anderberg (ant@anderbergfamily.net) # # A simple online calendar program that uses cal for the heavy lifting. # # Notes: # - By default this will only display options for years 2000 - 2010 # since that's all I need. See code below for easy fixes. # - Beware: This is far from safe from multi-instance database # trashing, some kind of filelocking should be implemented if # more than one user could be updating this at the same time. # # Feel free to download and use this software as you wish but # remember that I am not responsible for anything that occurs # to your computer. # # http://www.anderbergfamily.net/ant/cgi-cal/ # # Version 1.0 - 5.14.2002 # # Version 1.1 - 7.30.2002 # - Added code to convert <'s and >'s to ['s and ]'s to prevent # cross-site scripting concerns... # # # File locations # $database = '/usr/local/home/cgi-cal/database.txt'; $thisprog = '/cgi-bin/cgi-cal'; $calprog = '/usr/bin/cal'; # # CGI work... # use CGI qw(:standard); $day = param('d'); $month = param('m'); $year = param('y'); $entry = param('e'); # # Get current date information, months are numbered 0-11 # and the year returned is the year - 1900. # ($sec, $min, $hour, $today_day, $today_month, $today_year, $wday, $yday, $isdst) = localtime(time); $today_month++; $today_year = $today_year + 1900; # # If no month or year were specified it must be the # first screen of a session, display today's data. # if ((!$year)||(!$month)) { $year = $today_year; $month = $today_month; $day = $today_day; } # # If an entry has been specified we need # to write to or update the database. # if ($entry) { # We use semicolons to denote carriage returns $entry =~ s/\n/;/g; $entry =~ s/\r//g; # # <'s and >'s can be used for evil things, replace them with ['s and ]'s # $entry =~ s//]/g; # Remove the old entry (if there is one) @tmpdata = (); open (DATA, "$database"); while () { ($y, $m, $d, $t) = split(/;/, $_, 4); if (($y != $year)||($m != $month)||($d != $day)) { push @tmpdata, $_; } } close(DATA); # # Write the database with the updated entry. # open (DATA, ">$database"); print DATA @tmpdata; print DATA "$year;$month;$day;$entry\n"; close (DATA); } # # Run the external cal program, collect it's # output and remove the carrige returns. # First make sure these are real digits for # month and year and not something like: # ; cat /etc/passwd > mailer badguy@hacker.com # if (($year =~ m/\d+/ )&&($month =~ m/\d+/ )) { @cal = `$calprog $month $year`; chomp(@cal); } # # Let the user go one month ahead and behind # without using the drop-down lists. # $next_month = $month + 1; $next_year = $year; if ($next_month > 12) { $next_month = 1; $next_year = $next_year + 1; } $prev_month = $month - 1; $prev_year = $year; if ($prev_month < 1) { $prev_month = 12; $prev_year = $prev_year - 1; } # # Make the current month and year the defaults # @mselect = (); @yselect = (); $mselect[$month] = 'SELECTED'; $yselect[$year] = 'SELECTED'; # # Write out the top of the web page # print <<"EOF"; Content-type: text/html Online Calendar
  

  Previous Month   Go To Today   Next Month

EOF ; # # Get the database entry for today and record what # days this month have entrys. # $entry = ''; @importantdays = (); open (DATA, "$database"); while () { ($y, $m, $d, $t) = split(/;/, $_, 4); # Look for entrys matching the selected date if (($y == $year)&&($m == $month)&&($d == $day)) { $entry = $t; } # Flag days this month that have entrys. if (($y == $year)&&($m == $month)) { $importantdays[$d] = 1; } } close(DATA); # # Print out the first two lines from cal, which are something like: # May 2002 # Su Mo Tu We Th Fr Sa # print "
$cal[0]\n";
print "$cal[1]\n";


#
# Go through the other lines in cal's output, 
# turn each day into a hyperlink to ourself 
# with it's date as input.
#
$count = @cal;
for ($i = 2 ; $i <= $count ; $i++)
 {
  if ($cal[$i]) # sometimes we get blanks.
   {
    $line = "$cal[$i] "; # This way each number has a trailing space.
    @days = split(/\s+/, $line);
    foreach $value (@days)
     {
      if (($value)&&($value != $day)) # Don't hyperlink todays number.
       {
        $new = "$value";

        # Make days with entrys bold
        if ($importantdays[$value])
         {
          $new = "$new";
         }

        # Replace the existing number with our hyperlinked version.
        $line =~ s/$value /$new /;
       }
      elsif ($value == $day)
       {
        # Make today's number bold
        $new = "$value";

        # Replace the existing number with our hyperlinked version.
        $line =~ s/$value /$new /;
       }
     }
    print "$line\n";
   }
 }
print "
"; # # We used semicolons to replace \n's, put them back. # chomp($entry); $entry =~ s/;/\n/g; # # <'s and >'s can be used for evil things, replace them with ['s and ]'s # $entry =~ s//]/g; # # Write out the rest of the page. # print "
"; print "\n"; print "\n"; print "\n"; print "\n"; print '

  '; print '

';