#! /tools/ns/bin/perl5.004 # The contents of this file are subject to the Netscape Public # License Version 1.1 (the "License"); you may not use this file # except in compliance with the License. You may obtain a copy of # the License at http://www.mozilla.org/NPL/ # # Software distributed under the License is distributed on an "AS # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or # implied. See the License for the specific language governing # rights and limitations under the License. # # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is Netscape # Communications Corporation. Portions created by Netscape are # Copyright (C) 1998 Netscape Communications Corporation. All # Rights Reserved. # # Contributor(s): ################################################################### # file: rical.pl # A random iCalendar file generator for testing the icalendar parser. # Set the DATE_CMD environment variable if you are on Windows or Mac # to point to the unix 'date' equivalent program. # I have arbitrarily defined 3 categories of randomness that determine # whether or not a property or parameter appears in the output. These # are: # $MAY_prop_chances # defaults to 5% # $SHOULD_prop_chances # defaults to 65% # $MUST_prop_chances # defaults to 95% # You can vary these chances with command line options. # sman # 29-May-1998 ############################################################# # Arrays for populating properties and parameters ############################################################# @categories = ('SPORTS','THEATER','CONVENTION','MEAL','VACATION', 'BIRTHDAY'); @class = ("PUBLIC", "PRIVATE", "CONFIDENTIAL", "X-VALUE"); @cnFirst = ("Steve", "Joe", "Eric", "John", "Greg", "Terry", "Dave", "Scott", "Kevin", "Poindexter" ); @cnLast = ("Smith", "Jones", "Washington", "DuBois", "Wells", "Vaughn", "Flintstone", "Simpson", "Smithers", "Gumble"); @cutypeparm = ("INDIVIDUAL", "GROUP", "RESOURCE", "ROOM", "UNKNOWN", "X-TOKEN" ); @fbtypeparm = ("FREE","BUSY","BUSY-UNAVAILABLE", "BUSY-TENTATIVE"); @method = ("PUBLISH", "REQUEST", "REFRESH", "CANCEL", "ADD", "REPLY", "COUNTER", "DECLINECOUNTER" ); @partstatparm =("NEEDS-ACTION", "ACCEPTED", "DECLINED", "TENTATIVE", "DELEGATED", "x-name" ); @resources = ("CAR", "TRUCK", "THEATER", "COUNTRY", "MILITARY", "PROJECTOR", "STEREO", "CDPLAYER" ); @roleparm = ("CHAIR", "REQ-PARTICIPANT", "OPT-PARTICIPANT", "NON-PARTICIPANT", "X-NAME" ); @status = ("TENTATIVE", "CONFIRMED", "CANCELLED" ); @transparm = ("OPAQUE","TRANSPARENT"); @rrules = ( "FREQ=DAILY;COUNT=10", "FREQ=DAILY;UNTIL=19981224T000000Z", "FREQ=DAILY;INTERVAL=2", "FREQ=DAILY;INTERVAL=10;COUNT=5", "FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1", "FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA", "FREQ=WEEKLY;COUNT=10", "FREQ=WEEKLY;UNTIL=19981224T000000Z", "FREQ=WEEKLY;INTERVAL=2;WKST=SU", "FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH", "FREQ=WEEKLY;COUNT=10;INTERVAL=2;WKST=SU;BYDAY=TU,TH", "FREQ=MONTHLY;COUNT=10;INTERVAL=2;BYDAY=1FR", "FREQ=MONTHLY;COUNT=10;INTERVAL=2;BYDAY=1SU,-1SU", "FREQ=MONTHLY;COUNT=6;BYDAY=-2MO", "FREQ=MONTHLY;BYMONTHDAY=-3", "FREQ=MONTHLY;BYMONTHDAY=2,15", "FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1", "FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,15", "FREQ=MONTHLY;INTERVAL=2;BYDAY=TU", "FREQ=YEARLY;COUNT=10;BYMONTH=6,7", "FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3", "FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200", "FREQ=YEARLY;BYDAY=20MO", "FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO", "FREQ=YEARLY;BYMONTH=3;BYDAY=TH", "FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8", "FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13", "FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13", "FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8", "FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3", "FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2", "FREQ=HOURLY;INTERVAL=3;UNTIL19981224T080000Z", "FREQ=MINUTELY;INTERVAL=15;COUNT=6", "FREQ=MINUTELY;INTERVAL=20;BYHOUR=9,10,11,12,13,14,15,16", "FREQ=MINUTELY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40", "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO" ); @exrules = ( "FREQ=WEEKLY;COUNT=4;INTERVAL=2;BYDAY=TU,TH", "FREQ=DAILY;COUNT=10", "FREQ=YEARLY;COUNT=8;BYMONTH=6,7" ); @return_codes = ( "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8", "2.9", "2.10", "2.11", "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "4.0", "5.0", "5.1", "5.2", "5.3" ); ############################################################# # Varios buttons and nobs that can tweek the output... ############################################################# $recur = 0; # flag: allow recurring params $rand_component_count = 0; # flag: allow random number of components per ical obj $date_cmd = "date"; # the date command $hostname = "host"; $domain = "example.com"; $bad_key_words = 0; # 0 = no bad keywords, 1 = may generate bad keywords $component_type = 1; # component type to generate $max_comp_type = 2; # 1-Events,2-Freebusy $SHOULD_prop_chances = 65; # 0 - 100, % chance that SHOULD properties will appear $MUST_prop_chances = 95; # 0 - 100, % chance that MUST properties will appear $MAY_prop_chances = 10; # 0 - 100, % chance that MAY properties will appear $RUIN_prop_chances = 10; # 0 - 100, only valid when $bad_key_words is 1. # it is the % chance that a keword will be bad $max_fb_dur_hrs = 4; # maximum number of hours that a busy time can be # the larger this number, the less the chances # of multiple busy times per day. ############################################################# # ICALENDAR WRAPPER ############################################################# &process_args(); &init(); &check_for_cgi_buttons(); if ($component_type == 2) { # 0 = Publish, 5 = Reply $itip_method = $method[ ((int(rand(2)) == 0) ? 0 : 5) ]; } else { $itip_method = $method[int(rand(1 + $#method))]; } printf("Content-Type:text/calendar; method=%s; charset=US-ASCII\n",$itip_method); printf("Content-Transfer-Encoding: 7bit\n"); printf("\n"); printf("%s:%s\n", &ruin_keyword("BEGIN"), &ruin_keyword("VCALENDAR") ); printf("%s:-//seasnake/RandomICALgenerator//EN\n", &ruin_keyword("PRODID") ); printf("%s:2.0\n",&ruin_keyword("VERSION")); printf("%s:%s\n",&ruin_keyword("METHOD"),$itip_method); if ($component_type == 1) { $numevents = 1; $numevents += int(rand(7)) if (1 == $rand_component_count); for ($iouter = 0; $iouter < $numevents; $iouter++) { &add_event(); } } elsif ($component_type == 2) { &add_freebusy(); } printf("%s:%s\n", &ruin_keyword("END"), &ruin_keyword("VCALENDAR")); 0; sub process_args { while (@ARGV) { $arg = shift @ARGV; if ($arg eq '-d') { $debug = 1; print STDERR "Debug turned on...\n"; } elsif ($arg eq '-r') { $recur = 1; print STDERR "Recur turned on...\n" if ($debug == 1); } elsif ($arg eq '-rcc') { $rand_component_count = 1; print STDERR "Random component count turned on...\n" if ($debug == 1); } elsif ($arg eq '-bkw') { $bad_key_words = 1; print STDERR "component_type = 2, freebusy...\n" if ($debug == 1); } elsif( $arg eq '-may') { $arg = shift @ARGV; $MAY_prop_chances = $arg; $MAY_prop_chances = 0 if ($MAY_prop_chances < 0); $MAY_prop_chances = 100 if ($MAY_prop_chances > 100); printf( STDERR "MAY_prop_chances = %d\n",$MAY_prop_chances) if ($debug == 1); } elsif( $arg eq '-must') { $arg = shift @ARGV; $MUST_prop_chances = $arg; $MUST_prop_chances = 0 if ($MUST_prop_chances < 0); $MUST_prop_chances = 100 if ($MUST_prop_chances > 100); printf( STDERR "MUST_prop_chances = %d\n",$MUST_prop_chances) if ($debug == 1); } elsif( $arg eq '-ruin') { $arg = shift @ARGV; $RUIN_prop_chances = $arg; $RUIN_prop_chances = 0 if ($RUIN_prop_chances < 0); $RUIN_prop_chances = 100 if ($RUIN_prop_chances > 100); printf( STDERR "RUIN_prop_chances = %d\n",$RUIN_prop_chances) if ($debug == 1); } elsif( $arg eq '-should') { $arg = shift @ARGV; $SHOULD_prop_chances = $arg; $SHOULD_prop_chances = 0 if ($SHOULD_prop_chances < 0); $SHOULD_prop_chances = 100 if ($SHOULD_prop_chances > 100); printf( STDERR "SHOULD_prop_chances = %d\n",$SHOULD_prop_chances) if ($debug == 1); } elsif ($arg eq '-fb') { $component_type = 2; print STDERR "component_type = 2, freebusy...\n" if ($debug == 1); } elsif ($arg eq '-fbdh') { $arg = shift @ARGV; $max_fb_dur_hrs = $arg; $max_fb_dur_hrs = 4 if ($max_fb_dur_hrs < 1); printf(STDERR "max_fb_dur_hrs = %d\n",$max_fb_dur_hrs) if ($debug == 1); } else { push(@mailto, $arg); } } } sub init { srand(); $uname = `uname -a`; if ($uname =~ /Windows/) { local($h); $date_cmd = ""; $date_cmd = $ENV{'DATE_CMD'} if ($ENV{'DATE_CMD'} =~ /date/); $hostname = $ENV{'COMPUTERNAME'} unless !($ENV{'COMPUTERNAME'}); } else { chop($hostname = `hostname`); chop($domain = `domainname`); } } ############################################################# # Build an indexed array. The index is the property name, # the value is the property value. ############################################################# sub check_for_cgi_buttons { @parms = split('&',$ENV{'QUERY_STRING'}); # printf("
\n");
foreach $val (@parms)
{
($p, $v) = split('=',$val);
#printf("%s
\n", $val);
#printf("p = %s, v = %s
\n", $p, $v);
# this filtering is a very cheap hack
$v =~ s/(%40)/@/g;
$v =~ s/\+/ /g;
$v =~ s/%0D/\r/g;
$v =~ s/%0A/\n /g;
$vals{$p} = $v;
}
#
# Now treat the button name just like the command line options...
#
$component_type = 2 if ( $vals{'btnFreeBusy'} eq "Random Freebusy" )
}
#############################################################
# Event
# The SUMMARY may exceed 80 characters.
# The end time may come before the start time.
#############################################################
sub add_event
{
printf("%s:%s\n",&ruin_keyword("BEGIN"), &ruin_keyword("VEVENT"));
&attach();
&attendee(rand(10));
&categories();
&class();
&comment();
&contact();
&created();
&description();
&dtstart_dtend_duration();
&dtstamp();
&geo();
&last_modified();
&location();
&organizer();
&priority();
&relatedto();
&resources();
&recurrence();
&sequence();
&status();
&summary("event");
&transp();
&uid();
&url();
&xprop();
printf("%s:%s\n", &ruin_keyword("END"), &ruin_keyword("VEVENT"));
}
sub add_freebusy
{
printf("%s:%s\n", &ruin_keyword("BEGIN"), &ruin_keyword("VFREEBUSY"));
&attendee(1) if ($itip_method eq "REPLY");
&comment();
&contact();
&dtstamp();
&freebusy();
&request_status();
&organizer();
&uid();
&url();
printf("%s:%s\n", &ruin_keyword("END"), &ruin_keyword("VFREEBUSY"));
}
sub attendee
{
($n) = @_;
local($i);
for ($i = 0; $i < $n; $i++)
{
printf( "%s", &ruin_keyword("ATTENDEE") );
&cutype();
&delegate();
&member();
&role();
&partstat();
&rsvp();
&sentby();
&common_name();
&dir();
&language();
&xparam();
printf( ":mailto:user$i\@example.com\n" );
}
}
sub attach
{
printf("%s:http://www.example%d.com/",&ruin_keyword("ATTACH"),int(rand(100)) )
if ( int(rand(100)) < $SHOULD_prop_chances);
}
sub categories
{
printf("%s:%s\n", &ruin_keyword("CATEGORIES"), $categories[int(rand(1 + $#categories))] )
if ( int(rand(100)) < $SHOULD_prop_chances);
}
sub class
{
printf("%s:%s\n", &ruin_keyword("CLASS"), $class[int(rand(1 + $#class))] )
if ( int(rand(100)) < $SHOULD_prop_chances);
}
sub comment
{
printf("%s:You are a weasel\n",&ruin_keyword("COMMENT") )
if ( int(rand(100)) < $SHOULD_prop_chances);
}
sub common_name
{
if ( int(rand(100)) < $MAY_prop_chances )
{
printf(";%s=\"%s\"", &ruin_keyword("CN"), &common_person_name());
}
}
sub common_person_name
{
$cnFirst[int(rand(1 + $#cnFirst))]." ".$cnLast[int(rand(1 + $#cnLast))];
}
sub contact
{
local($r) = 1 + int(rand(100));
if ( int(rand(100)) < 5 )
{
printf("%s",&ruin_keyword("CONTACT"));
if ( 1 <= $r && $r < 33)
{
printf(":Jim Dolittle\\, ABC Industries\\, +1-919-555-1234\n");
}
elsif (33 <= $r && $r < 67)
{
printf(";ALTREP=\"CID=