#!/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 - 2020 # 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... # # Version 2.0 - 12.29.2002 # - Converted to using tables with each day's entries. # # Version 2.1 - 12.10.2005 # - Handle dates further in the future. # # # File locations # $database = '/usr/local/www/data/calendardata.txt'; $thisprog = '/cgi-bin/cal.pl'; $calprog = '/usr/bin/cal'; # # 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; # # CGI work... # use CGI qw(:standard); $month = param('m'); $year = param('y'); if (param('update') eq 'true') { for($i = 1 ; $i < 32 ; $i++) { $entry = param("$i"); $day = $i; # 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; if ($entry) { print DATA "$year;$month;$day;$entry\n"; } close (DATA); } } # # 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; } # # 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); } # # Get the database entries for the days this month that have entries. # @importantdays = (); open (DATA, "$database"); while () { ($y, $m, $d, $t) = split(/;/, $_, 4); if (($y == $year)&&($m == $month)) { $importantdays[$d] = $t; } } close(DATA); # # Cleanse the data... # foreach $entry (@importantdays) { # # We used semicolons to replace \n's, put them back. # $entry =~ s/;/\n/g; chomp($entry); # # <'s and >'s can be used for evil things, replace them with ['s and ]'s # $entry =~ s//]/g; } # # Write out the top of the web page # print "Content-type: text/html\n\n"; print 'Online Calendar'; print "
"; print ''; print ' EOF ; # # Print out the column headings # print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print "\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]) # in case we get blank lines. { print ''; $line = "$cal[$i] "; # This way each line has a trailing space. $line =~ s/^\s+//g; @days = split(/\s+/, $line); $weekdays = @days; if (($weekdays < 7)&&($i <= 4)) { for ($j = $weekdays ; $j < 7 ; $j++) { print "\n"; } foreach $value (@days) { if ($value == $today_day) { print "\n"; } else { print "\n"; } } } else { foreach $value (@days) { if (($value == $today_day)&&($month == $today_month)&&($year == $today_year)) { print "\n"; } else { print "\n"; } } } print ''; } } # # Write out the rest of the page. # print '
'; # # Create the form to show the current month and let the user select a new month. # # Make the current month and year the defaults @mselect = (); @yselect = (); $mselect[$month] = 'SELECTED'; $yselect[$year] = 'SELECTED'; if (($year > 2020)||($year < 2000)) { $yselect['none'] = 'SELECTED'; } # # 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; } # # Print out the month form. # print <<"EOF";

Previous Month       Next Month

Sunday
Monday
Tueday
Wednesday
Thursday
Friday
Saturday
$value
$value
$value
$value
'; print "\n"; print ""; print ""; print '';