SystemVariables
Home
About

FAQs

General
Admin
Assist
Student

Docs

Admin
Assistant

CGI

Admin
Assistant
Download
Form
Student

Packages

AdminInterface
Assignments
AssistantInterface
Form
Interface
Record
Roster
StudentInterface
SystemVariables
Teams
VincentFile
VincentLog


  0 #System Variables Maintenance Package
  1 #Copyright 2000 Matt Jadud
  2 #This program is free software; you can redistribute it and/or
  3 #modify it under the terms of the GNU General Public License
  4 #as published by the Free Software Foundation; either version 2
  5 #of the License, or (at your option) any later version.
  6 #
  7 #This program is distributed in the hope that it will be useful,
  8 #but WITHOUT ANY WARRANTY; without even the implied warranty of
  9 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10 #GNU General Public License for more details.
 11 #
 12 #You should have received a copy of the GNU General Public License
 13 #along with this program; if not, write to the Free Software
 14 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 15 
 16 
 17 package SystemVariables; 
 18 $| = 1;
 19 
 20 use Fcntl qw(:flock);  # imports LOCK_EX, LOCK_SH, LOCK_NB
 21 use English;
 22 use VincentLog;
 23 use Record;
 24 
 25 my ( $key,
 26      $value,
 27      %Variables,
 28      %ConfigVariables,
 29      %StudentDefaults,
 30      $localpath,
 31      $SYSDEBUG,
 32      $ADMINDEBUG,
 33      $debuglevel,
 34      $user,
 35      $dbl
 36      );
 37 
 38 
 39 #Load the Variables
 40 
 41 #print STDERR "\n$UID - $EUID - $0\n";
 42 $USEBELOW = 1;
 43 
 44 
 45 
 46 ($account) = getpwuid($UID);
 47 
 48 loadVariables(%Variables, "/u/$account/.vincent3/config/.vp");
 49 loadVariables(%ConfigVariables, getCourseConfigFile());
 50 loadVariables(%StudentDefaults, getStudentDefaultsFile());
 51 
 52 return 1;
 53 
 54 sub useDebugging  {
 55 
 56     return $SYSDEBUG;
 57 
 58 }
 59 
 60 sub getLogPath  {
 61     return processVariable($Variables{"LOGPATH"});
 62 }
 63 
 64 sub getAllPostProcessors  {
 65 
 66     my(@proc,
 67        @trim,
 68        $item,
 69        $path);
 70     $path = getCallbackPath();
 71     @proc = glob($path . "*.vpp");
 72     
 73     foreach $item (@proc) {
 74 	$item =~ /.*/(.*).vpp$/;
 75 	push(@trim, $1);
 76     }
 77 
 78     return @trim;
 79 }
 80 
 81 
 82 sub useDoneness  {
 83     
 84     my ($done);
 85     $done = getStudentDefault("_DONENESS");
 86     chomp $done;
 87    
 88     #This information is stored as a 
 89     # "YES" or "NO" in the defaults file.
 90     # It should be converted into a boolean here,
 91     # not somewhere else.
 92     if($done eq "YES") {
 93 	return 1;
 94     } else {
 95 	return 0;
 96     }
 97 }
 98 
 99 sub useTeams  {
 100     
 101     my ($team);
 102     $team = getStudentDefault("_USETEAMS");
 103     chomp $team;
 104    
 105     #This information is stored as a 
 106     # "YES" or "NO" in the defaults file.
 107     # It should be converted into a boolean here,
 108     # not somewhere else.
 109     if($team eq "YES") {
 110 	return 1;
 111     } else {
 112 	return 0;
 113     }
 114 }
 115 
 116 ##CONTRACT
 117 # getAllGradeMappings : void -> ArrayRef
 118 ##PURPOSE
 119 # Returns a list of all grade mappings in the system. In particular,
 120 # it returns the user's names for the mappings, not the system names.
 121 ##DEPENDANCIES
 122 # SystemVariables::getCourseConfigPath()
 123 sub getAllGradeMappings  {
 124 
 125     my($path,
 126        @mappings,
 127        $file,
 128        @mapname);
 129 
 130     #All mappings are stored in the course 
 131     # config area. 
 132     $path = getCourseConfigPath();
 133     
 134     #Grab all files matching the MAPPING* pattern. These
 135     # are grade mapping files.
 136     @mappings = glob("$path" . "MAPPING*");
 137     
 138     #For each file found
 139     # Open the file, grab the name
 140     # (the first line of the file is #NAME: ),
 141     # and push it onto an array
 142     foreach $file (@mappings) {
 143 	open(MAP, $file);
 144 	while(<MAP>) {
 145 	    if(/#NAME: (.*)/) {
 146 		push(@mapname, $1);
 147 	    }
 148 	}
 149 	close(MAP);
 150     }
 151 
 152     #Chomp the array
 153     chomp(@mapname);
 154 
 155     #SystemVariables::DEBUG("SysVar:", @mapname);
 156     
 157     #Return a reference to the list of mapping names.
 158     return @mapname;
 159 }
 160 
 161 ##CONTRACT
 162 # existInList : scalar(String) ListRef -> boolean
 163 ##PURPOSE
 164 # If the item passed in (string, or other scalar)
 165 # is contained in the list referenced by ListRef,
 166 # 1 (true) is returned. Otherwise, a 0 is returned (false).
 167 ##DEPENDANCIES
 168 # None.
 169 sub existInList  {
 170     
 171     my($item, $litem, $list);
 172     
 173     ($item, $list) = @_;
 174     chomp $item;
 175 
 176     #For each item in the list, if it is
 177     # equal to the test item, return one. 
 178     # This halts the loop.
 179     foreach $litem (@{$list}) {
 180 	chomp $litem;
 181 	if("$litem" eq "$item") {
 182 	    return 1;
 183 	}
 184     }
 185     
 186     #If no matches were found, return zero.
 187     return 0;
 188 }
 189 
 190 ##CONTRACT
 191 # getDownloadableFileDataPath : String -> String
 192 ##PURPOSE
 193 # Consumes a string representing the system ID for
 194 # a file previously submitted for download by the course
 195 # administrator. This is typically of the form "DOWNLOAD\d+",
 196 # or "DOWNLOAD0", "DOWNLOAD1", etc. Returns the full path
 197 # to the .data file containing information regarding download
 198 # permissions and download dates, if applicable.
 199 ##DEPENDANCIES
 200 # SystemVariables::getCourseConfigPath()
 201 sub getDownloadableFileDataPath  {
 202     
 203     my ($sysID);
 204     $sysID = $_[0];
 205 
 206     return getCourseConfigPath() . $sysID . ".data";
 207 }
 208 
 209 
 210 ##CONTRACT
 211 # _getAdminIndex : String -> Number
 212 ##PURPOSE
 213 # Takes a file path for a downloadable 
 214 # file submitted by the course administrator,
 215 # and returns the index of the file.
 216 ##EXAMPLE
 217 # Given "DOWNLOAD5," it would return '5'.
 218 ##DEPENDANCIES
 219 # None.
 220 sub _getAdminIndex  {
 221 
 222     my($name);
 223     $name = $_[0];
 224 
 225     #Pull the index out with a regular expression
 226     # and return the result of the match.
 227     $name =~ /.*DOWNLOAD(d+)/;
 228     return $1;    
 229 }
 230 
 231 
 232 ##CONTRACT
 233 # getNextAdminFileUploadName : void -> String
 234 ##PURPOSE
 235 # Returns the next index for files submitted for
 236 # download by the course administrator. For example:
 237 ##EXAMPLE
 238 # If the only file in the system is "DOWNLOAD0", it 
 239 # should return "DOWNLOAD1," and so on.
 240 ##DEPENDANCIES
 241 # SystemVariables::_getAdminIndex()
 242 # SystemVariables::getCourseConfigPath();
 243 sub getNextAdminFileUploadName  {
 244 
 245     my($path,
 246        @files,
 247        $filename,
 248        $filenumber
 249        );
 250 
 251     #Get the path to the course config area, and
 252     # glob all files marked as available for download.
 253     $path = getCourseConfigPath();
 254     @files = glob($path . "DOWNLOAD*");
 255     
 256     #If any files were found, sort them by index
 257       #Pop the highest number found
 258       #Increment the index
 259       #Return the next system filename
 260     #If no files were found
 261       #Return the zeroth index.
 262     if(@files) {
 263 
 264 	@files = sort { _getAdminIndex($a) <=> _getAdminIndex($b) } @files;
 265 	$filename = pop(@files);
 266 	
 267 	$filename =~ /DOWNLOAD(d+)/;
 268 	$filenumber = $1;
 269 	
 270 	$filenumber++;
 271 
 272 	return "DOWNLOAD$filenumber";
 273     } else {
 274 	return "DOWNLOAD0";
 275     }
 276 		 
 277 }
 278 
 279 ##CONTRACT
 280 # getAdminList : void -> ArrayRef
 281 ##PURPOSE
 282 # Returns a list of usernames
 283 # allowed to access the administrator script.
 284 # Also captures the GODs, who should ALWAYS be present;
 285 # The system is installed incorrectly if it is installed
 286 # without individuals placed in a GOD field.
 287 ##DEPENDANCIES
 288 # SystemVariables::getCourseConfigPath().
 289 sub getAdminList  {
 290 
 291     my (@admins,
 292 	@gods,
 293 	$path);
 294 
 295 
 296     #Grab a path to the list
 297     $listpath = getCourseConfigPath() . "adminassistlist";
 298 
 299     #If the list exists (which the installer should have handled)
 300        #Read the list, grabbing any administrators and gods
 301     if(open(LIST, $listpath)) {
 302 	
 303 	while(<LIST>) {
 304 	    if(/ADMINISTRATORS/) {
 305 		($tag, @admins) = (split(/|/));
 306 	    }
 307 	    if(/GOD/) {
 308 		($tag, @gods) = (split(/|/));
 309 	    }
 310 	}
 311     }
 312     
 313     #Append the gods to the list of valid administrators,
 314     # and return a reference to the administrator list.
 315     @admins = (@admins, @gods);
 316 	
 317     return @admins;
 318     
 319 }
 320 
 321 ##CONTRACT
 322 # getGodList : void -> ArrayRef
 323 ##PURPOSE
 324 # Returns a list of usernames
 325 # allowed to access the administrator script as GODS.
 326 # These should have been added by the installer,
 327 # and cannot be edited from within the system itself.
 328 ##DEPENDANCIES
 329 # SystemVariables::getCourseConfigPath().
 330 sub getGodList  {
 331 
 332     my (@gods,
 333 	$path);
 334 
 335 
 336     #Grab a path to the list
 337     $listpath = getCourseConfigPath() . "adminassistlist";
 338 
 339     #If the list exists (which the installer should have handled)
 340        #Read the list, grabbing any gods
 341     if(open(LIST, $listpath)) {
 342 	
 343 	while(<LIST>) {
 344 	    
 345 	    if(/GOD/) {
 346 		($tag, @gods) = (split(/|/));
 347 	    }
 348 	}
 349     }
 350     
 351     #SystemVariables::DEBUG("SysVar:", "Found Gods: ", @gods);
 352 
 353     #Append the gods to the list of valid administrators,
 354     # and return a reference to the administrator list.
 355 
 356     return @gods;
 357     
 358 }
 359 
 360 ##CONTRACT
 361 # getGodString : void -> String
 362 ##PURPOSE
 363 # Take the list of gods in the system, and 
 364 # turn them into a space-delimited string.
 365 ##DEPENDANCIES
 366 # SystemVariables::getAdminList()
 367 sub getGodString  {
 368     
 369     my ($gods, $string);
 370     
 371     $gods = getGodList();
 372     $string = "";
 373 
 374     #Concatonate each admin in the 
 375     # list onto an empty string.
 376     foreach (@{$gods}) {
 377 	$string .= $_;
 378 	$string .= " ";
 379     }
 380       
 381     return $string;
 382 }
 383 
 384 
 385 ##CONTRACT
 386 # getAdminString : void -> String
 387 ##PURPOSE
 388 # Take the list of administrators in the system, and 
 389 # turn them into a space-delimited string.
 390 ##DEPENDANCIES
 391 # SystemVariables::getAdminList()
 392 sub getAdminString  {
 393     
 394     my ($admins, $string);
 395     
 396     $admins = getAdminList();
 397     $string = "";
 398 
 399     #Concatonate each admin in the 
 400     # list onto an empty string.
 401     foreach (@{$admins}) {
 402 	$string .= $_;
 403 	$string .= " ";
 404     }
 405       
 406     return $string;
 407 }
 408 
 409 ##CONTRACT
 410 # getAssistList : void : ArrayRef
 411 ##PURPOSE
 412 # Returns an array reference containing
 413 # the usernames of all individuals allowed
 414 # to serve as assistants/TAs in the course.
 415 ##DEPENDANCIES
 416 # SystemVariables::getCourseConfigPath()
 417 sub getAssistList  {
 418 
 419     my (@assists,
 420 	$path);
 421 
 422     @assists = ();
 423     
 424     #Grab the path to the file.
 425     $listpath = getCourseConfigPath() . "adminassistlist";
 426 
 427     #If the file can be opened
 428        # Grab all the assistants in the list into an array.
 429     if(open(LIST, $listpath)) {
 430 	
 431 	while(<LIST>) {
 432 	    if(/ASSISTANTS/) {
 433 		($tag, @assists) = (split(/|/));
 434 	    }
 435 	}
 436     }
 437 	
 438     #Return a reference to the assistants array.
 439     return @assists;
 440 
 441 }
 442 
 443 ##CONTRACT
 444 # getAssistString : void -> String
 445 ##PURPOSE
 446 # Return the list of assistants in the course
 447 # as a space-delimited string.
 448 ##DEPENDANCIES
 449 # SystemVariables::getAssistList()
 450 sub getAssistString  {
 451     
 452     my ($assists, $string);
 453     
 454     $assists = getAssistList();
 455     $string  = "";
 456 
 457     #Concatonate each assistant in the 
 458     # list onto an empty string.
 459     foreach (@{$assists}) {
 460 	$string .= $_;
 461 	$string .= " ";
 462     }
 463    
 464     return $string;
 465 }
 466 
 467 ##CONTRACT
 468 # updateAdminAssistList : ArrayRef ArrayRef -> void
 469 ##PURPOSE
 470 # Takes a reference containing an array of username
 471 # for administrators, an array of usernames for
 472 # assistants, and updates the file 'adminassistlist'.
 473 ##DEPENDANCIES
 474 # SystemVariables::getCourseConfigPath();
 475 sub updateAdminAssistList  {
 476 
 477     my ($listpath,
 478 	$admins,
 479 	$assists,
 480 	$gods);
 481     
 482     #The new list of admins and assistants
 483     # should have been passed in as array references.
 484     $admins  = $_[0];
 485     $assists = $_[1];
 486     $gods    = getGodList();
 487     $listpath = getCourseConfigPath() . "adminassistlist";
 488 
 489     #Open the file for writing, overwrite old data.
 490     open(LIST, ">$listpath");
 491 
 492     #Filelock. There shouldn't be multiple writes, but 
 493     # better safe than sorry.
 494     flock(LIST, LOCK_EX);
 495    
 496     #Update the administrators.
 497     print LIST "_ADMINISTRATORS";
 498     foreach (@{$admins}) {
 499 	print LIST "|$_";
 500     }
 501     print LIST "n";
 502 
 503     #Update the assistants
 504     print LIST "_ASSISTANTS";
 505     foreach (@{$assists}) {
 506 	print LIST "|$_";
 507     }
 508     print LIST "n";
 509 
 510     #Reprint the gods
 511     print LIST "_GODS";
 512     foreach (@{$gods}) {
 513 	print LIST "|$_";
 514     }
 515     print LIST "n";    
 516 
 517     
 518     close(LIST);
 519 }
 520 
 521 ##CONTRACT
 522 # canStudentDownload : void -> SysValue (string)
 523 ##PURPOSE
 524 # Returns the system wide variable set by the administrator
 525 # determining whether students are or are not allowed to
 526 # download their own files. This value is either "YES" or "NO".
 527 ##DEPENDANCIES
 528 # None.
 529 sub canStudentsDownload  {
 530     return $StudentDefaults{"_STUFILEDOWNLOAD"};
 531 }
 532 
 533 ##CONTRACT
 534 # canAssistantEditTeams : void -> boolean
 535 ##PURPOSE
 536 # If assistants can currently edit teams, returns 1.
 537 ##DEPENDANCIES
 538 # None.
 539 sub canAssistantEditTeams  {
 540     if($StudentDefaults{"_ASSISTANTEDITTEAMS"} eq "YES") {
 541 	return 1;
 542     } else {
 543 	return 0;
 544     }
 545 }
 546 
 547 
 548 ##CONTRACT
 549 # getCallingScript : void -> String
 550 ##PURPOSE
 551 # Gets the calling script from the environment,
 552 # and returns the short form of the script 
 553 # that is currently executing.
 554 ##EXAMPLES
 555 # If the admin script is currently executing, it 
 556 # returns "admin." Student and Assistant are
 557 # likewise returned for student.cgi and assistant.cgi
 558 ##DEPENDANCIES
 559 # Browser Evironment.
 560 sub getCallingScript  {
 561     
 562     my($string, $script);
 563     
 564     $string = $ENV{SCRIPT_NAME};
 565     
 566     if($string =~ /student/) {
 567 	return "student";
 568     } elsif ($string =~ /assistant/) {
 569 	return "assistant";
 570     } elsif ($string =~ /admin/) {
 571 	return "admin";
 572     }
 573 }
 574 
 575 ##CONTRACT
 576 # getCurrentYear : Number -> Number
 577 ##PURPOSE
 578 # Returns the current year, plus or minus any and
 579 # all arguments passed in.
 580 ##EXAMPLE
 581 # getCurrentYear() returns the current year.
 582 # getCurrentYear(1) returns the current year + 1.
 583 # getCurrentYear(-1) returns the current year -1.
 584 ##DEPENDANCIES
 585 # SystemVariables::currentTime();
 586 sub getCurrentYear  { 
 587     my($value, $arg);
 588     
 589     $value = (split(/,/, currentTime()))[0];
 590     foreach $arg (@_) {
 591 	$value += $arg;
 592     }
 593     
 594     #Check for leading zeroness.
 595     if(($value !~ /0/) && ($value < 10)) {
 596 	$value = "0$arg";
 597     }
 598     
 599     return $value;
 600 }
 601 
 602 ##CONTRACT
 603 # getCurrentMonth : Number -> Number
 604 ##PURPOSE
 605 # Returns the current year, plus any values passed in.
 606 ##EXAMPLE
 607 # getCurrentMonth() returns the current month as 01 -> 12
 608 # getNextMonth(+1) returns the current month +1, mod 12
 609 ##DEPENDANCIES
 610 # SystemVariables::currentTime()
 611 sub getCurrentMonth  {
 612     my($value, $arg);
 613     
 614     $value = (split(/,/, currentTime()))[1];
 615     foreach $arg (@_) {
 616 	$value += $arg;
 617     }
 618 
 619     #Check for leading zeroness.
 620      if(($value !~ /0/) && ($value < 10)) {
 621 	$value = "0" . $value;
 622     }
 623     
 624     #Nasty, two step process; take the modulo.
 625     # if we somehow ended up with 0, add one.
 626     # This handles a case where someone wanted 
 627     # December plus some multiple of 12 months.
 628     if($value > 12) {
 629 	$value = $value%12;
 630     } 
 631     if($value == 0) {
 632 	$value = 12;
 633     }
 634     
 635     return $value;  
 636 }
 637 
 638 ##CONTRACT
 639 # getCurrentTime : void -> VincentDateString
 640 ##PURPOSE
 641 # currentTime() was named incorrectly. It should
 642 # have been named getCurrentTime, in keeping with 
 643 # all other system 'gets.' Unfortunately, this was
 644 # not the case. 'getCurrentTime' is nothing more 
 645 # than a wrapper.
 646 ##DEPENDANCIES
 647 # SystemVariables::currentTime()
 648 sub getCurrentTime  {
 649 
 650     return currentTime();
 651 }
 652 
 653 ############################DANGER
 654 #
 655 # This function allows the addition
 656 # of a number to the current day. However,
 657 # there was _no_ checking of the number
 658 # based on the current month. This being the 
 659 # case, things like "2000,01,32" could be
 660 # valid dates.
 661 #
 662 # Given that all date sorting is completely
 663 # numeric, this would not be a problem... 
 664 # the "currentTime" compared to an incorrect
 665 # date like this would yield
 666 #
 667 # 20000201120000 vs. 200001321120000
 668 #
 669 # Comparing Feb 1, 2000 vs. Jan 32, 2000. 
 670 # Feb 1 is still "greater," although Jan 32 is
 671 # invalid as a date.
 672 #
 673 # It is currently unknown as to whether this is a problem.
 674 # An analysis of what functions depend on this is forthcoming.
 675 ##CONTRACT
 676 # getCurrentDay : Number -> Number
 677 ##PURPOSE
 678 #  Return the current day, plus any arguments.
 679 ##DEPENDANCIES
 680 # SystemVariables::currentTime()
 681 sub getCurrentDay  {
 682     my($value, $arg);
 683     
 684     $value = (split(/,/, currentTime()))[2];
 685     foreach $arg (@_) {
 686 	$value += $arg;
 687     }
 688     
 689     if(($value !~ /0/) && ($value < 10)) {
 690 	$value = "0" . $value;
 691     }
 692     
 693     return $value;
 694 }
 695 
 696 ##CONTRACT
 697 # getCallbackPath : void -> String
 698 ##PURPOSE
 699 # Returns the path to the directory where callback scripts
 700 # should live.
 701 ##DEPENDANCIES
 702 # None.
 703 sub getCallbackPath  {
 704     return processVariable($Variables{"CALLBACKPATH"});
 705 }
 706 
 707 ##CONTRACT
 708 # getJulesPath : void -> String
 709 ##PURPOSE
 710 # Returns the string to where Jules files should end
 711 # up in the system. Currently no longer used.
 712 ##DEPENDANCIES
 713 # None.
 714 sub getJulesPath  {
 715     return processVariable($Variables{"JULESPATH"});
 716 }
 717 
 718 ##CONTRACT
 719 # getStudentRecordPath : String -> $String
 720 ##PURPOSE
 721 # Takes a username, and returns a path to
 722 # that student's personal record space in the system.
 723 ##DEPENDANCIES
 724 # SystemVariables::getRecordPath()
 725 sub getStudentRecordPath  {
 726     
 727     my ($username);
 728     
 729     $username = $_[0];
 730     
 731     return getRecordPath() . $username . "/";
 732 }
 733 
 734 ##CONTRACT
 735 # useSlipTime : void -> boolean
 736 ##PURPOSE
 737 # Returns true if the system uses sliptime; false otherwise.
 738 ##DEPENDANCIES
 739 # SystemVariables::getStudentDefault()
 740 sub useSlipTime  {
 741 
 742     my ($slip);
 743     $slip = getStudentDefault("_USESLIPTIME");
 744     chomp $slip;
 745    
 746     #This information is stored as a 
 747     # "YES" or "NO" in the defaults file.
 748     # It should be converted into a boolean here,
 749     # not somewhere else.
 750     if($slip eq "YES") {
 751 	return 1;
 752     } else {
 753 	return 0;
 754     }
 755 
 756 }
 757 
 758 
 759 ##CONTRACT
 760 # showAverage : void -> boolean
 761 ##PURPOSE
 762 # Returns 1 if the administrator
 763 # would like students to see the class average
 764 # along with their grades.
 765 ##DEPENDANCIES
 766 # SystemVariables::getStudentDefault()
 767 sub showAverage  {
 768 
 769     my ($avg);
 770     $avg = getStudentDefault("_SHOWAVERAGE");
 771     chomp $avg;
 772    
 773 
 774     #This information is stored as a 
 775     # "YES" or "NO" in the defaults file.
 776     # It should be converted into a boolean here,
 777     # not somewhere else.
 778     if($avg eq "YES") {
 779 	return 1;
 780     } else {
 781 	return 0;
 782     }
 783 
 784 }
 785 
 786 
 787 ##CONTRACT
 788 # getEarlierDate : string string -> string
 789 ##PURPOSE
 790 # Takes two strings of the format "YYYY,MM,DD,HH:MM:SS" and
 791 # returns the earlier of the two.
 792 # Uses string comparison to find the earlier of the two.
 793 ##DEPENDANCIES
 794 # None.
 795 sub getEarlierDate  {
 796 
 797     my ( $date1,
 798 	 $date2,
 799 	 $y1,
 800 	 $y2,
 801 	 $m1,
 802 	 $m2,
 803 	 $d1,
 804 	 $d2,
 805 	 $t1,
 806 	 $t2,
 807 	 @earlier,
 808 	 $fix,
 809 	 $index,
 810 	 $earlier
 811 	 );
 812 
 813     #The two dates should both be strings in VincentDate format.
 814     ($date1, $date2) = @_;
 815     chomp $date1;
 816     chomp $date2;
 817 
 818     SystemVariables::DEBUG("SysVar:", "Comparing $date1 and $date2");
 819 
 820     #Split the strings into their various components.
 821     ($y1, $m1, $d1, $t1) = (split(/,/, $date1));
 822     ($y2, $m2, $d2, $t2) = (split(/,/, $date2));
 823 
 824     #Now, fix the months and days
 825     @fix = ($m1, $m2, $d1, $d2);
 826     $index = 0;
 827     foreach (@fix) {
 828 	if(($_ < 10) && ($_ !~ /^0/)) {
 829 	    $fix[$index] = "0$_";
 830 	}
 831 	$index++;
 832     }
 833     
 834     #Place values back in variables
 835     ($m1, $m2, $d1, $d2) = @fix;
 836     
 837     #Repack the date strings
 838     $date1 = "$y1,$m1,$d1,$t1";
 839     $date2 = "$y2,$m2,$d2,$t2";
 840 
 841     #For cleanup and comparison
 842     $d1 = $date1;
 843     $d2 = $date2;
 844 
 845     #Strip all commas, colons
 846     # from both strings. This converts
 847     # 
 848     # 2000,01,31,12:00:00 
 849     #          to
 850     # 20000131120000
 851     # 
 852     # which can be compared numerically.
 853     $d1 =~ s/,//g;
 854     $d1 =~ s/://g;
 855     $d2 =~ s/,//g;
 856     $d2 =~ s/://g;
 857 
 858     #Return the smaller of the two dates.
 859     if($d1 < $d2) {
 860 	#SystemVariables::DEBUG("SysVar:", $d1, " ", $d2, " ", "$date1 is the earlier date.");
 861 	return $date1;
 862     } else {
 863 	#SystemVariables::DEBUG("SysVar:", $d1, " ", $d2, " ", "$date2 is the earlier date.");
 864 	return $date2;
 865     }
 866     
 867 
 868 }
 869 
 870 
 871 #Returns difference between first and second time submitted
 872 sub deltaTime  {
 873 
 874     my( $stamp1,
 875 	$stamp2,
 876 	$year1,
 877 	$year2,
 878 	$month1,
 879 	$month2,
 880 	$day1,
 881 	$day2,
 882 	$time1,
 883 	$time2,
 884 	$hours1,
 885 	$hours2,
 886 	$minutes1,
 887 	$minutes2,
 888 	$seconds1,
 889 	$seconds2,
 890 	$delta
 891 	);
 892 
 893     $stamp1 = $_[0];
 894     $stamp2 = $_[1];
 895 
 896     ($year1, $month1, $day1, $time1) = (split(/,/, $stamp1));
 897     ($year2, $month2, $day2, $time2) = (split(/,/, $stamp2));
 898 
 899     ($hours1, $minutes1, $seconds1) = (split(/:/, $time1));
 900     ($hours2, $minutes2, $seconds2) = (split(/:/, $time2));
 901 
 902     #Convert everything to seconds
 903     $seconds1 += 60 * $minutes1;
 904     $seconds1 += 60 * 60 * $hours1;
 905     $seconds1 += 24 * 60 * 60 * $day1;
 906     #Assume all months have 30 days.
 907     $seconds1 += 30 * 24 * 60 * 60 * $month1;
 908     $seconds1 += 365 * 24 * 60 * 60 * $year1;
 909 
 910     #Convert everything to seconds
 911     $seconds2 += 60 * $minutes2;
 912     $seconds2 += 60 * 60 * $hours2;
 913     $seconds2 += 24 * 60 * 60 * $day2;
 914     #Assume all months have 30 days.
 915     $seconds2 += 30 * 24 * 60 * 60 * $month2;
 916     $seconds2 += 365 * 24 * 60 * 60 * $year2;
 917     
 918     $delta = $seconds1 - $seconds2;
 919     
 920     return $delta;
 921 }
 922 
 923 sub addMinutes  {
 924 
 925     my($date,
 926        $addmin,
 927        $year,
 928        $month,
 929        $day,
 930        $hours,
 931        $minutes,
 932        $seconds,
 933        $string);
 934 
 935     $date = $_[0];
 936     $addmin = $_[1];
 937     
 938     ($year, $month, $day, $time) = (split(/,/, $date));
 939     
 940     ($hours, $minutes, $seconds) = (split(/:/, $time));
 941    
 942     $minutes += $addmin;
 943 
 944     #If we are over 60 minutes, take the mod60 and
 945     # bump hours by one.
 946     if($minutes >= 60) {
 947 	$minutes = $minutes%60;
 948 	
 949 	$hours += 1;
 950 	
 951 	#If hours broke 24, take the mod24, and bump days.
 952 	# If someone is permitting files over a month boundary,
 953 	# this will break.
 954 	if($hours >= 24) {
 955 	    $hours = $hours%24;
 956 	    $day += 1;
 957 	}
 958     }
 959     
 960     if(($minutes < 10) && ($minutes !~ /^0/)) {
 961 	$minutes = "0$minutes";
 962     }
 963 
 964     if(($hours < 10) && ($hours !~ /^0/)) {
 965 	$hours = "0$hours";
 966     }
 967     
 968     if(($day < 10) && ($day !~ /^0/)) {
 969 	$day = "0$day";
 970     }
 971 
 972     $string = $year . "," . $month . "," . $day . "," . 
 973 	$hours . ":" . $minutes . ":" . "00";
 974 
 975     return $string;
 976 }
 977 
 978 
 979 ##CONTRACT
 980 # currentTime : void -> string
 981 ##PURPOSE
 982 # Returns the current time in YYYY,MM,DD,HH:MM:SS format.
 983 ##DEPENDANCIES
 984 # SystemVariables::vincentDate()
 985 sub currentTime  {
 986   return vincentDate(scalar localtime);
 987 }
 988 
 989 ##CONTRACT
 990 # vincentDate : string -> string
 991 ##PURPOSE
 992 # Takes a date in the string format returned by the "date" command
 993 # in Perl, and returns it in a YYYY,MM,DD,HH:MM:SS format.
 994 ##DEPENDANCIES
 995 # None.
 996 sub vincentDate  {
 997     
 998     my ($date,
 999 	%Months,
 1000 	$month,
 1001 	$day,
 1002 	$year,
 1003 	$time);
 1004 
 1005     #The current date in Perl (scalar, or string) date format.
 1006     $date = $_[0];
 1007 
 1008     %Months = ("Jan", "01",
 1009 	       "Feb", "02",
 1010 	       "Mar", "03",
 1011 	       "Apr", "04",
 1012 	       "May", "05",
 1013 	       "Jun", "06",
 1014 	       "Jul", "07",
 1015 	       "Aug", "08",
 1016 	       "Sep", "09",
 1017 	       "Oct", "10",
 1018 	       "Nov", "11",
 1019 	       "Dec", "12");
 1020     
 1021     
 1022     ($month, $day, $year, $time) = (split(/s+/, $date))[1,2,4,3];
 1023     chomp $month;
 1024     chomp $day;
 1025     chomp $year;
 1026     chomp $time;
 1027     
 1028 
 1029     $month = $Months{$month};
 1030 
 1031 # HACK ALERT ***************** robh
 1032     # '0' pad the date if 1-9
 1033     $day = "0$day" if ($day < 10);
 1034 
 1035     $date = "$year,$month,$day,$time";
 1036     return $date;
 1037 }
 1038 
 1039 ##CONTRACT
 1040 # getStudentDefaultsFile : void -> string
 1041 ##PURPOSE
 1042 # Returns the full path to the file containing
 1043 # defaults for all students in the system.
 1044 ##DEPENDANCIES
 1045 # SystemVariables::processVariable()
 1046 sub getStudentDefaultsFile  {
 1047     return processVariable($Variables{"STUDENTDEFAULTS"});
 1048 }
 1049 
 1050 ##CONTRACT
 1051 # getStudentDefaults : void -> REF(hash)
 1052 ##PURPOSE
 1053 # Returns a hash reference to a hash containing all the defaults 
 1054 # for all students in the system.
 1055 ##DEPENDANCIES
 1056 # None.
 1057 sub getStudentDefaults  {
 1058     return %StudentDefaults;
 1059 }
 1060 
 1061 ##CONTRACT 
 1062 # getStudentDefault : string -> string
 1063 ##PURPOSE
 1064 # Looks up the given key in the student default
 1065 # file and returns the value found.
 1066 ##DEPENDANCIES
 1067 # SystemVariables::getStudentDefaults()
 1068 sub getStudentDefault  { 
 1069     my ($variable,
 1070 	$defaults);
 1071 
 1072     $variable = $_[0];
 1073 
 1074     $defaults = getStudentDefaults();
 1075     
 1076     return $$defaults{$variable};
 1077 }
 1078 
 1079 ##CONTRACT
 1080 # writeStudentDefaults : REF(hash) -> void
 1081 ##PURPOSE
 1082 # Takes a hash reference containing student defaults, and 
 1083 # writes those defaults to the system-wide defaults file.
 1084 # Old defaults are overwritten.
 1085 #
 1086 # THIS DOES NOT UPDATE ALL STUDENTS.
 1087 ##DEPENDANCIES
 1088 # SystemVariables::getStudentDefaultsFile()
 1089 sub writeStudentDefaults  {
 1090     
 1091     my ($file,
 1092 	$defaults,
 1093 	$param,
 1094 	%StuUpdate
 1095 	);
 1096     %StuUpdate = ();
 1097 
 1098     $file = getStudentDefaultsFile();
 1099     chomp $file;
 1100     $defaults = $_[0];
 1101    
 1102     SystemVariables::DEBUG("SysVar:", "Writing defaults.");
 1103     
 1104     open(DEFAULTS, ">$file") || 
 1105 	die("Can't open defaults at $file.");    
 1106 
 1107     foreach $param (keys %{$defaults}) {
 1108 	if($param =~ /^_/) {
 1109 	    print DEFAULTS $param, "|", $$defaults{$param}, "n";
 1110 	    SystemVariables::DEBUG("SysVar:", $param, "::", $$defaults{$param});
 1111 	
 1112             #Build an update hash. This hash will
 1113 	    # filter out sliptime, unless it is explicitly 
 1114 	    # tagged to be updated by the course administrator.
 1115 	    if($param eq "_SLIPTIME") {
 1116 		if(defined($$defaults{"resetsliptime"})
 1117 		   && 
 1118 		   $$defaults{"resetsliptime"} eq "1") {
 1119 		    SystemVariables::DEBUG("SysVar:", "<STRONG>Resetting sliptime.</STRONG>");
 1120 		    $StuUpdate{$param} = $$defaults{$param};
 1121 		}
 1122 	    } elsif($param eq "_CLASSEXPIRATION") {
 1123 		if(defined($$defaults{"updateallexp"})
 1124 		   &&
 1125 		   $$defaults{"updateallexp"} eq "1") {
 1126 		    SystemVariables::DEBUG("SysVar:", "<STRONG>Setting expiration to </STRONG>", $$defaults{"_CLASSEXPIRATION"});
 1127 		    $StuUpdate{"_EXPIRATION"} = $$defaults{"_CLASSEXPIRATION"};
 1128 		}
 1129 	    } else {
 1130 		$StuUpdate{$param} = $$defaults{$param};
 1131 	    }
 1132 	}
 1133     }
 1134     
 1135     close(DEFAULTS);
 1136 
 1137     
 1138 
 1139     #Update all the student records with this data.
 1140     
 1141   Record::updateAllStudentRecords(%StuUpdate);
 1142 }
 1143 
 1144 ##CONTRACT
 1145 # getStudentWebPath : void -> string
 1146 ##PURPOSE
 1147 # Returns a string representing the full http:// URL to the
 1148 # student-side script.
 1149 ##DEPENDANCIES
 1150 # SystemVariables::processVariable()
 1151 sub getStudentWebPath  {
 1152     return processVariable($Variables{"STUDENTWEBPATH"});
 1153 }
 1154 
 1155 ##CONTRACT
 1156 # getStudentRealPath : void -> String
 1157 ##PURPOSE
 1158 # Returns a path to the student script, in terms
 1159 # of the filesystem, not the WWW (URL).
 1160 ##DEPENDANCIES
 1161 # SystemVariables::processVariable()
 1162 sub getStudentRealPath  {
 1163     return processVariable($Variables{"STUDENTREALPATH"});
 1164 }
 1165 
 1166 ########################DEPRECATED
 1167 #
 1168 # This function should not be used anymore. This 
 1169 # predates when downloads were handled by download.cgi.
 1170 # This function is useless, but remains until it is 
 1171 # known that it can be safely removed.
 1172 ##CONTRACT
 1173 # getDownloadWebPath : void -> String
 1174 ##PURPOSE
 1175 # Returns the URL to the download area of the script
 1176 ##DEPENDANCIES
 1177 # SystemVariables::processVariable()
 1178 sub getDownloadWebPath  {
 1179     return processVariable($Variables{"DOWNLOADWEBPATH"});
 1180 }
 1181 
 1182 sub getFormWebPath  {
 1183     return processVariable($Variables{"FORMWEBPATH"});
 1184 }
 1185 
 1186 ##CONTRACT
 1187 # getImageWebPath : void -> String
 1188 ##PURPOSE
 1189 # Returns the URL to the system images directory.
 1190 ##DEPENDANCIES
 1191 # SystemVariables::processVariable()
 1192 sub getImageWebPath  {
 1193     return processVariable($Variables{"IMAGEWEBPATH"});
 1194 }
 1195 
 1196 ########################DEPRECATED
 1197 #
 1198 # This function should not be used anymore. This 
 1199 # predates when downloads were handled by download.cgi.
 1200 # This function is useless, but remains until it is 
 1201 # known that it can be safely removed.
 1202 ##CONTRACT
 1203 # getLinkRealPath : void -> String
 1204 ##PURPOSE
 1205 # Returns the path to where links for the system
 1206 # should be created and destroyed
 1207 ##DEPENDANCIES
 1208 # SystemVariables::processVariable()
 1209 sub getLinkRealPath  {
 1210     return processVariable($Variables{"LINKREALPATH"});
 1211 }
 1212 
 1213 ########################DEPRECATED
 1214 #
 1215 # This function should not be used anymore. This 
 1216 # predates when downloads were handled by download.cgi.
 1217 # This function is useless, but remains until it is 
 1218 # known that it can be safely removed.
 1219 ##CONTRACT
 1220 # getLinkWWWPath : void -> String
 1221 ##PURPOSE
 1222 # Returns the system path to where softlinks should 
 1223 # be created and destroyed.
 1224 ##DEPENDANCIES
 1225 # SystemVariables::processVariable()
 1226 sub getLinkWWWPath  {
 1227     return processVariable($Variables{"LINKWEBPATH"});
 1228 }
 1229 
 1230 
 1231 ##CONTRACT
 1232 # getAdminWebPath : void -> string
 1233 ##PURPOSE
 1234 # Returns a string representing the full http:// URL to
 1235 # the admin-side script.
 1236 ##DEPENDANCIES
 1237 # SystemVariables::processVariable()
 1238 sub getAdminWebPath  {
 1239     
 1240     return processVariable($Variables{"ADMINWEBPATH"});
 1241 }
 1242 
 1243 ##CONTRACT
 1244 # getAdminRealPath : void -> String
 1245 ##PURPOSE
 1246 # Returns the system path to where the administrator
 1247 # script lives.
 1248 ##DEPENDANCIES
 1249 # SystemVariables::processVariable()
 1250 sub getAdminRealPath  {
 1251     return processVariable($Variables{"ADMINREALPATH"});
 1252 }
 1253 
 1254 ##CONTRACT
 1255 # getAssistantWebPath : void -> String
 1256 ##PURPOSE
 1257 # Returns the URL to where the assistant script lives.
 1258 ##DEPENDANCIES
 1259 # SystemVariables::processVariable()
 1260 sub getAssistantWebPath  {
 1261     return processVariable($Variables{"ASSISTANTWEBPATH"});
 1262 }
 1263 
 1264 ##CONTRACT
 1265 # getAssistantRealPath : void -> String
 1266 ##PURPOSE
 1267 # Returns the system path to where the assistant script lives.
 1268 ##DEPENDANCIES
 1269 # SystemVariables::processVariable()
 1270 sub getAssistantRealPath  {
 1271     return processVariable($Variables{"ASSISTANTREALPATH"});
 1272 }
 1273 
 1274 ##CONTRACT
 1275 # getClassTagline : void -> string
 1276 ##PURPOSE
 1277 # Returns the description of the course as set by the 
 1278 # course administrator.
 1279 ##DEPENDANCIES
 1280 # SystemVariables::getVariable()
 1281 sub getClassTagline  {
 1282     return getVariable("TAGLINE");
 1283 }
 1284 
 1285 ##CONTRACT
 1286 # setClassTagline : string -> void
 1287 ##PURPOSE
 1288 # Sets the class tagline. 
 1289 ##DEPENDANCIES
 1290 # SystemVariables::setVariable()
 1291 sub setClassTagline  {
 1292     
 1293     my ($value);
 1294     $value = $_[0];
 1295     chomp $value;
 1296 
 1297     setVariable("TAGLINE", $value);
 1298 }
 1299 
 1300 ##CONTRACT
 1301 # getClassID : void -> string
 1302 ##PURPOSE
 1303 # Returns the course ID as set by the administrator. 
 1304 ##DEPENDANCIES
 1305 # SystemVariables::getVariable()
 1306 sub getClassID  {
 1307     return getVariable("CLASSID");
 1308 }
 1309 
 1310 
 1311 ##CONTRACT
 1312 # setClassID : string -> void
 1313 ##PURPOSE
 1314 # Sets the class ID.
 1315 ##DEPENDANCIES
 1316 # SystemVariables::setVariable()
 1317 sub setClassID  {
 1318     
 1319     my ($value);
 1320     $value = $_[0];
 1321     chomp $value;
 1322 
 1323     setVariable("CLASSID", $value);
 1324 }
 1325 
 1326 ##CONTRACT
 1327 # getVariable : string -> string
 1328 ##PURPOSE
 1329 # Takes a string representing a DB key for the desired 
 1330 # value, and returns the value of the system variable associated
 1331 # with that key.
 1332 ##DEPENDANCIES
 1333 # None.
 1334 sub getVariable  {
 1335     
 1336     my ($variable);
 1337     $variable = $_[0];
 1338     chomp $variable;
 1339 
 1340     return $ConfigVariables{$variable};
 1341 }
 1342 
 1343 ##CONTRACT
 1344 # setVariable : string string -> void.
 1345 ##PURPOSE
 1346 # Takes a record key and a value, and writes them into
 1347 # the system config variables.
 1348 ##DEPENDANCIES
 1349 # SystemVariables::writeConfigVariables()
 1350 sub setVariable  {
 1351 
 1352 
 1353     my ( %config,
 1354 	 $record,
 1355 	 $value
 1356 	 );
 1357 
 1358     $record = $_[0];
 1359     $value  = $_[1];
 1360     
 1361     #Take the hashtable currently loaded into memory
 1362     # and modify the keyed value.
 1363     $ConfigVariables{$record} = $value;
 1364     
 1365     #webErrOut("Setting ", $record, " to ", $value);
 1366     
 1367     #Write it to disc.
 1368     writeConfigVariables();
 1369 
 1370 }
 1371 
 1372 ##CONTRACT
 1373 # writeConfigVariables : void -> void
 1374 ##PURPOSE
 1375 # Takes no arguments; writes the current system config
 1376 # variable hash to disk. 
 1377 ##DEPENDANCIES
 1378 # SystemVariables::getCourseConfigFile()
 1379 sub writeConfigVariables  {
 1380 
 1381     my ($config);
 1382 
 1383     $config = getCourseConfigFile();
 1384 
 1385     #webErrOut("Write to: ", $config);
 1386     
 1387     open(CONFIG, ">$config") 
 1388 	|| 
 1389 	    die("No config file at $config");
 1390 
 1391     #LOCK THE FILE
 1392     flock(CONFIG, LOCK_EX);
 1393 
 1394     foreach $key (keys %ConfigVariables) {
 1395 	print CONFIG "$key|", $ConfigVariables{$key}, "n";
 1396     }
 1397     
 1398     #FREE THE FILE
 1399     close(CONFIG);
 1400 
 1401 }
 1402 
 1403 ##CONTRACT
 1404 # loadVariables : REF(hash) string -> REF(hash)
 1405 ##PURPOSE
 1406 # Takes a hash reference and a string representing the path to a 
 1407 # config file, and reads those values into the hash passed in.
 1408 # This hash is then returned.
 1409 #
 1410 ##NOTICE
 1411 # The installer must put the .vp file in the root 
 1412 # of the administrator's home directory. The .vp
 1413 # file dictates where everything else can be
 1414 # found, and that is unique to each user. Hence,
 1415 # if it cannot be assumed to be in the root of the user's 
 1416 # home directory, then the install script must be modified accordingly,
 1417 # as must this module.
 1418 ##DEPENDANCIES
 1419 # None.
 1420 sub loadVariables  {
 1421 
 1422     my ($hash, $file);
 1423     
 1424     $hash = $_[0];
 1425     $file = $_[1];
 1426     
 1427     open(VARIABLES, $file) 
 1428 	||
 1429 	    die("No $file file in SystemVariables.pm");
 1430 
 1431     #LOCK THE FILE
 1432     flock(VARIABLES, LOCK_EX);
 1433 
 1434     while(<VARIABLES>) {
 1435 	
 1436 	#Allow for comments and spaces
 1437 	if(!(/^#/) && !(/^$/)) {
 1438 	    ($key, $value) = (split(/|/));
 1439 	
 1440 	    chomp $key;
 1441 	    chomp $value;
 1442 	
 1443 	    ${%$hash}\{$key} = $value;
 1444 	}
 1445     }
 1446     
 1447     #FREE THE FILE
 1448     close(VARIABLES);
 1449 
 1450     return $hash;
 1451 }
 1452 
 1453 ##CONTRACT
 1454 # loadConfigVariables : void -> REF(hash)
 1455 ##PURPOSE
 1456 # Takes no arguments; returns a hash reference pointing
 1457 # to a hash containing the system-wide config variables.
 1458 ##DEPENDANCIES
 1459 # SystemVariables::getCourseConfigFile()
 1460 sub loadConfigVariables  {
 1461 
 1462     my ( $config,
 1463 	 );
 1464 
 1465     $config = getCourseConfigFile();
 1466     
 1467     open(VARIABLES, $config) 
 1468 	||
 1469 	    die("No $config file in SystemVariables.pm");
 1470     
 1471     while(<VARIABLES>) {
 1472 	
 1473 	($key, $value) = (split(/|/));
 1474 	
 1475 	chomp $key;
 1476 	chomp $value;
 1477 	
 1478 	$ConfigVariables{$key} = $value;
 1479     }
 1480 
 1481     return %ConfigVariables;
 1482 }
 1483 
 1484 ##CONTRACT
 1485 # processVariable : string -> string
 1486 ##PURPOSE
 1487 # Takes a variable as defined in a config file, and 
 1488 # expands any variable references embedded in it
 1489 # inside of < .... >'s. This way, variables
 1490 # can depend on each-other.
 1491 ##DEPENDANCIES
 1492 # Self-referential.
 1493 sub processVariable  {
 1494     
 1495     my ( $variable,
 1496 	 $temp,
 1497 	 $orig
 1498 	 );
 1499     
 1500     $variable = $_[0];
 1501     
 1502     if($variable =~ /.*(<.*>).*/) {
 1503 	$temp = $1;
 1504 	$orig = $1;
 1505 
 1506 	#DEBUGGING
 1507 	#errOut($temp);
 1508 	#errOut();
 1509 
 1510 	$temp =~ s/<//g;
 1511 	$temp =~ s/>//g;
 1512 	$temp = processVariable($Variables{$temp});
 1513 	$variable =~ s/$orig/$temp/;
 1514     }
 1515 
 1516     return $variable;
 1517 }
 1518 
 1519 ##CONTRACT
 1520 # getRecordPath : void -> string
 1521 ##PURPOSE
 1522 # Returns a string representing a path to the 
 1523 # records directory in the system.
 1524 ##DEPENDANCIES
 1525 # SystemVariables::processVariable()
 1526 sub getRecordPath  {
 1527 
 1528     #errOut("SV: ", $Variables{"RECORDPATH"\}, "n");
 1529     #foreach $key (keys %AssignmentHash) {
 1530     #print "$key::", $AssignmentHash{$key}, "<P>";
 1531     #}
 1532    
 1533     return processVariable($Variables{"RECORDPATH"});
 1534 }
 1535 
 1536 ##CONTRACT
 1537 # getCourseConfigFile : void -> string
 1538 ##PURPOSE
 1539 # Returns a string representing the path
 1540 # to the course config file.
 1541 ##DEPENDANCIES
 1542 # SystemVariables::processVariable()
 1543 sub getCourseConfigFile  {
 1544     return processVariable($Variables{"CONFIGFILE"});
 1545 }
 1546 
 1547 ##CONTRACT
 1548 # getCourseConfigPath : void -> string
 1549 ##PURPOSE
 1550 # Returns a string representing the path to the system
 1551 # config directory.
 1552 ##DEPENDANCIES
 1553 # SystemVariables::processVariable()
 1554 sub getCourseConfigPath  {   
 1555     return processVariable($Variables{"CONFIGPATH"});
 1556 }
 1557 
 1558 ##CONTRACT
 1559 # getCourseCorrellationFile : void -> string
 1560 ##PURPOSE
 1561 # Returns the path to the system-wide correllation file
 1562 # that associates usernames with other student data.
 1563 ##DEPENDANCIES
 1564 # SystemVariables::processVariable()
 1565 sub getCourseCorrellationFile  {
 1566     return processVariable($Variables{"CONFIGPATH"}) . 
 1567 	".correllation";
 1568 }
 1569 
 1570 ##CONTRACT
 1571 # webErrOut : array -> void
 1572 ##PURPOSE
 1573 # Takes an array, and prints the contents to STDOUT.
 1574 ##DEPENDANCIES
 1575 # None.
 1576 sub webErrOut  {
 1577     
 1578     if($DEBUG){
 1579 	print STDOUT @_;
 1580 	print STDOUT "<P>n";
 1581     }
 1582     
 1583 }
 1584 
 1585 ##CONTRACT
 1586 # errOut : array -> void
 1587 ##PURPOSE
 1588 # Writes the contents of the passed array to
 1589 # STDERR. 
 1590 ##DEPENDANCIES
 1591 # None.
 1592 sub errOut  {
 1593     
 1594     if($DEBUG) {
 1595 	print STDERR @_;
 1596 	print "n";
 1597     }
 1598 }
 1599 
 1600 ##CONTRACT
 1601 # DEBUG : array -> void
 1602 ##PURPOSE
 1603 # Writes the contents of the passed array to STDOUT.
 1604 # This is a non-explicit print to STDOUT, and
 1605 # Perl CGIs seem to occasionally treat this 
 1606 # differently than explicitly declaring STDOUT... 
 1607 # This is not understood.
 1608 ##DEPENDANCIES
 1609 # None.
 1610 sub DEBUG  { 
 1611     my($script,
 1612        @args,
 1613        $debuglevel,
 1614        $user,
 1615        $dbl);
 1616     
 1617     ($script, @args) = @_;
 1618     chomp $script;
 1619     chomp @args;
 1620 
 1621 #Turn debugging on or off for the entire system;
 1622 $SYSDEBUG = 0;
 1623 $ADMINDEBUG = 0;
 1624 
 1625 
 1626    
 1627     $debuglevel = 0;
 1628     $user = $ENV{REMOTE_USER};
 1629     
 1630     if($dbl = Record::getDebugLevel($user)) {
 1631 	$debuglevel = $dbl;
 1632     } else {
 1633 	$debuglevel = $ADMINDEBUG;
 1634     }
 1635    
 1636 
 1637        #Level 0 is nothing.
 1638        #Level 1 prints to the class log
 1639        #Level 2 prints to the class log and server log
 1640        #Level 3 prints to the class log, server log, and screen
 1641 
 1642        if ($debuglevel == 1) {
 1643 	 VincentLog::clickLog("DEBUG", "$script: @args"); 
 1644        } elsif ($debuglevel == 2) {
 1645 	 VincentLog::clickLog("DEBUG", "$script: @args"); 
 1646 	   print STDERR "VINCENTDEBUG $script: @argsn";
 1647        } elsif ($debuglevel == 3) {
 1648 	 VincentLog::clickLog("DEBUG", "$script: @args"); 
 1649 	   print STDERR "VINCENTDEBUG $script: @argsn";
 1650 	   print "$script: ", @_, "n<P>"; 
 1651        } else {
 1652 	   #Nothing
 1653        }
 1654 
 1655 }
 1656 
 1657 
 1658 
 1659 
 1660 

Last update: 1/6/01; 9:32:38 AM