Annotation of capa/capa51/Discuss/Ver1.2/capadiscuss, revision 1.1.1.1
1.1 albertel 1: #!/usr/ucb/perl
2: #
3: # CAPA Discussion Forum
4: # version 1.2c
5: #
6: # Michigan State University
7: # Department of Physics and Astronomy
8: #
9: # Ryan J. Shaltry
10: # tech4@msue.msu.edu
11:
12: require "capadiscuss.setup";
13: require "capadiscuss_html";
14:
15: ################################################
16: ## Configuration - Change these appropriately ##
17: ################################################
18:
19: # capadiscuss.setup
20:
21: ################################################
22: ## End Configuration ###########################
23: ################################################
24:
25: print "Content-type: text/html\n\n";
26:
27: &form_info;
28:
29: $yp = "19";
30:
31: # define variables
32: $class = $form{'CLASS'};
33: $snum = $form{'SNUM'};
34: $capaid = $form{'CAPAID'};
35: $setid = $form{'SETID'};
36: $action = $form{'ACTION'};
37: $file = $form{'FILE'};
38: $probnum = $form{'PROBNUM'};
39: $replynum = $form{'REPLYNUM'};
40: $psetid = $form{'PSETID'};
41:
42: if($psetid eq "") { $psetid = $setid; }
43:
44: &GetTeacherInfo;
45:
46: # check for valid studentnumber/capaid
47: &ValidateUser;
48:
49: # grab username from student number
50: &UserInfo($snum);
51: &GetDateTime;
52:
53: # call appropriate sr
54: if($action eq "newset" ) { &NewSet; }
55: if($action eq "viewset" || $action eq "" ) { &ViewSet; }
56: if($action eq "viewproblem" ) { &ViewProblem; }
57: if($action eq "post" ) { &Post; }
58: if($action eq "postsubmit" ) { &PostSubmit; }
59: if($action eq "delmsgpre" ) { &DelMsgPre; }
60: if($action eq "delmsg" ) { &DelMsg; }
61: if($action eq "hidemsgpre" ) { &HideMsgPre; }
62: if($action eq "hidemsg" ) { &HideMsg; }
63: if($action eq "unhidemsgpre" ) { &UnHideMsgPre; }
64: if($action eq "unhidemsg" ) { &UnHideMsg; }
65:
66: if($action eq "admin" ) { &AdminMain; }
67: if($action eq "adminusersearch" ) { &AdminUserSearch; }
68: if($action eq "adminusersearchsubmit" ) { &AdminUserSearchSubmit; }
69:
70: if($action eq "viewinfofile" ) { &ViewInfoFile; }
71:
72: if($action eq "topmsg" ) { &TopMsg("top"); }
73: if($action eq "untopmsg" ) { &TopMsg(""); }
74:
75: exit;
76:
77: #######################
78: ## Begin Subroutines ##
79: #######################
80:
81: sub NewSet {
82: &Log("NewSet");
83:
84: if($setid <= $psetid) { #grab capaid
85: @allcapaid = `allcapaid -s $setid -e $setid -stu $snum -c $capadir/$class -i`;
86:
87: $capaid = $allcapaid[2];
88: chop $capaid;
89: chop $capaid;
90: &ViewSet;
91: }
92:
93: opendir(DDIR,"$capadir/$class/discussion");
94: @sets = grep(/[0-9]/,sort(readdir(DDIR)));
95: closedir(DDIR);
96:
97: $pdset = "<select name=\"SETID\">\n";
98: foreach $setnum(@sets) {
99: $selected = "";
100: if($setnum eq $setid) { $selected = "selected"; }
101: $pdset .= "<option value=\"$setnum\" $selected>$setnum\n";
102: }
103: $pdset .= "</select>\n";
104:
105: &NewSetHTML;
106: exit;
107: }
108:
109: sub ViewSet {
110: &Log("ViewSet");
111:
112: &CheckAdmin;
113:
114: $adminbutton = "";
115: if($validadmin eq "yes") {
116: $adminbutton = &AdminButtonHTML;
117: }
118:
119: $capasbin = "$capasbin/$teachdir/capasbin";
120: &SetJumpBox;
121:
122: opendir(FORUM,"$capadir/$class/discussion/$setid");
123: @dir = sort(readdir(FORUM));
124: closedir(FORUM);
125:
126: @infofiles = grep(/.info/,@dir);
127: $infostring = "";
128: $backfunction = "viewset";
129: foreach $infofile(@infofiles) {
130: $infodesc = $infofile;
131: $infodesc =~ s/.info//g;
132: $infodesc =~ s/_/ /g;
133: $infostring .= &InfoButtonHTML;
134: }
135:
136:
137: foreach $i(@dir) {
138: $probnum = &RemZero(substr($i,0,6));
139: if($found[$probnum] eq "") { $found[$probnum] = "0"; }
140: $found[$probnum] = $found[$probnum] + 1;
141: }
142:
143: $maxprobs = &MaxProbs($setid);
144:
145: # split table (if more than 15 problems)
146: $bigtable = "no";
147: if($maxprobs > 5) {
148: $bigtable = "yes";
149: $col1size = int ($maxprobs / 2);
150: $col2size = $maxprobs - $col1size;
151: if($col1size < $col2size) {
152: $t = $col1size;
153: $col1size = $col2size;
154: $col2size = $t;
155: }
156: }
157:
158: &ViewSetTitleHTML;
159:
160: if($bigtable eq "no") { &ViewSetTopSmallHTML; }
161: else { &ViewSetTopBigHTML; }
162:
163: $col = 1;
164: for($probnum=1; $probnum<=$maxprobs; $probnum++) {
165: if($col eq "1" && $probnum > $col1size && $bigtable eq "yes") {
166: $col = 2;
167: &ViewSetEndColHTML;
168: &ViewSetTopSmallHTML;
169: }
170: if($found[$probnum] ne "") {
171: opendir(MSG,"$capadir/$class/discussion/$setid");
172: @msgs = grep(/.msg/,sort(readdir(MSG)));
173: closedir(MSG);
174: foreach $msg(@msgs) {
175: if(&RemZero(substr($msg,0,6)) eq $probnum) {
176: push(@good,$msg);
177: }
178: }
179:
180: &OpenMsg("$capadir/$class/discussion/$setid/$good[$#good]");
181: $lastpost = "$date at $time";
182: $posts = $found[$probnum];
183: }
184: else {
185: $lastpost = "--";
186: $posts = "0"; }
187: &ViewSetGutsHTML;
188: }
189: &ViewSetBotHTML;
190: exit;
191: }
192:
193: sub ViewProblem {
194: &Log("ViewProblem");
195:
196: # check if user is administrator (for admin button)
197: &CheckAdmin;
198: if($validadmin eq "yes") {
199: $adminbutton = &AdminButtonHTML;
200: }
201: else {
202: $adminbutton = "";
203: }
204:
205: opendir (MSGS,"$capadir/$class/discussion/$setid");
206: @msgs = sort(readdir(MSGS));
207: closedir(MSGS);
208:
209: # search for top message
210: @top = grep (/top/, @msgs);
211: $topmsg = "";
212: print "$#top";
213: if($#top ne "0") {
214: $pnum = &AddZero($probnum);
215: foreach $entry(@top) {
216: $find = $entry =~ s/\A$pnum/$pnum/o;
217: if($find eq "1") {
218: $topmsg = $entry;
219: @msgs = grep(!/$topmsg/,@msgs);
220: unshift(@msgs,$topmsg);
221: print "$topmsg";
222: }
223: }
224: }
225:
226: $msgfind = "no";
227: $msgcount = 0;
228:
229: $capasbin = "$capasbin/$teachdir/capasbin";
230:
231: foreach $i(@msgs) {
232: $pn = &RemZero(substr($i,0,6));
233: if($pn eq $probnum) {
234: $msgcount++;
235: $msgfind = "yes";
236: &OpenMsg("$capadir/$class/discussion/$setid/$i");
237:
238: if($status eq "hidden" && $validadmin ne "yes") {
239: $msgcount--;
240: $msgfind = "no";
241: }
242:
243: if($msgcount eq "1") {
244: $postbutton = &ReplyButtonHTML;
245: &ProblemJumpBox;
246: &ViewProblemTopHTML;
247: }
248:
249: ($token1,$token2) = split(/\|/,$poster);
250: chop $token2;
251: if($token1 eq "Anonymous") {
252: if($validadmin eq "yes") {
253: $poster = "$token2 (anonymously)";
254: }
255: else {
256: $poster = "$token1";
257: $email = "";
258: }
259: }
260: $topfind = grep(/-top.msg/,$i);
261: if($validadmin eq "yes") {
262: $file = "$i";
263: $delbutton = &DelButtonHTML;
264: $hidebutton = &HideButtonHTML;
265: $topbutton = &TopButtonHTML;
266: if($topfind eq "1") { $topbutton = &UnTopButtonHTML; }
267: }
268: $subjectbgcolor = "#92D1D0";
269: if($topfind eq "1") { $subjectbgcolor = "blue"; }
270: $messagenote = "";
271: if($validadmin eq "yes" || $status eq "public") {
272: if($status eq "hidden") {
273: $subjectbgcolor = "red";
274: $hidebutton = &UnHideButtonHTML;
275: $messagenote = "Hidden by $hiddenuser on $hiddendate at $hiddentime from $hiddenaddr";
276: }
277: &ViewProblemGutsHTML;
278: }
279: }
280: }
281: &ViewProblemBotHTML;
282:
283: if($msgfind eq "no") {
284: $postbutton = &PostNewButtonHTML;
285: &ProblemJumpBox;
286: &ViewProblemTopHTML;
287: &ViewProblemNoneHTML;
288: &ViewProblemBotHTML;
289: }
290:
291: exit;
292: }
293:
294: sub ViewInfoFile {
295: open(INFOFILE,"$capadir/$class/discussion/$setid/$file");
296: @file = <INFOFILE>;
297: closedir(INFOFILE);
298:
299: print "<html><head></head><body bgcolor=\"#ffffff\">";
300: $backfunction = $form{'BACKFUNCTION'};
301: &InfoBackButtonHTML;
302: foreach $line(@file) {
303: print "$line";
304: }
305:
306: exit;
307: }
308:
309: sub Post {
310: local(@msgs,$pn,$msg);
311:
312: # grab last message in thread
313: opendir(MSGS,"$capadir/$class/discussion/$setid");
314: @msgs = grep(/.msg/,sort(readdir(MSGS)));
315: closedir(MSGS);
316:
317: foreach $msg(@msgs) {
318: $pn = &RemZero(substr($msg,0,6));
319: if($pn eq $probnum) {
320: $lastfile = $msg;
321: }
322: }
323:
324: $PostType = "New Message";
325: if($lastfile ne "") {
326: &OpenMsg("$capadir/$class/discussion/$setid/$lastfile");
327: if($status eq "public" || $validadmin eq "yes") {
328: ($poster,$rposter) = split(/\|/,$poster);
329: $inreplyto = &InReplyToHTML;
330: $PostType = "Reply";
331: }
332: }
333:
334: &PostHTML;
335: exit;
336: }
337:
338: sub PostSubmit {
339: local($message,$subject,$date);
340:
341: $message = $form{'message'};
342: $subject = $form{'subject'};
343:
344: if($message eq "" || $subject eq "") { &MFPostReplyHTML; }
345:
346: &Log("Post");
347:
348: # find last message in thread
349: opendir(FORUM,"$capadir/$class/discussion/$setid");
350: @dir = sort(readdir(FORUM));
351: closedir(FORUM);
352:
353: $probnum = &AddZero($probnum);
354: $replynum = "000000";
355: foreach $msg(@dir) {
356: if(substr($msg,0,6) eq $probnum) {
357: $replynum = &AddZero(&RemZero(substr($msg,7,6)) + 1);
358: }
359: }
360:
361: $date = substr($RunonDate,0,4) . $yp . substr($RunonDate,4,2);
362: &WriteMsg("$capadir/$class/discussion/$setid/$probnum-$replynum-$date-000000.msg");
363:
364: $probnum = &RemZero($probnum);
365: &PostDoneHTML;
366: exit;
367: }
368:
369: sub DelMsgPre {
370: &CheckAdmin('kill');
371: &OpenMsg("$capadir/$class/discussion/$setid/$file");
372: &DelMsgPreHTML;
373: exit;
374: }
375:
376: sub DelMsg {
377: &CheckAdmin('kill');
378: unlink("$capadir/$class/discussion/$setid/$file");
379: &DelMsgDoneHTML;
380: exit;
381: }
382:
383: sub HideMsgPre {
384: &CheckAdmin('kill');
385: &OpenMsg("$capadir/$class/discussion/$setid/$file");
386: &HideMsgPreHTML;
387: exit;
388: }
389:
390: sub HideMsg {
391: &CheckAdmin('kill');
392: open(MSG,"$capadir/$class/discussion/$setid/$file");
393: @msg = <MSG>;
394: close(MSG);
395:
396: unlink("$capadir/$class/discussion/$setid/$file");
397:
398: open(MSG,">$capadir/$class/discussion/$setid/$file");
399: for($i=0;$i<=5;$i++) {
400: print MSG "$msg[$i]";
401: }
402: print MSG "hidden|$username|$HyphenDate|$Time|$ENV{'REMOTE_ADDR'}\n";
403: close(MSG);
404:
405: &HideMsgDoneHTML;
406: }
407:
408: sub UnHideMsgPre {
409: &CheckAdmin('kill');
410: &OpenMsg("$capadir/$class/discussion/$setid/$file");
411: &UnHideMsgPreHTML;
412: exit;
413: }
414:
415: sub UnHideMsg {
416: &CheckAdmin('kill');
417: open(MSG,"$capadir/$class/discussion/$setid/$file");
418: @msg = <MSG>;
419: close(MSG);
420:
421: unlink("$capadir/$class/discussion/$setid/$file");
422:
423: open(MSG,">$capadir/$class/discussion/$setid/$file");
424: for($i=0;$i<=5;$i++) {
425: print MSG "$msg[$i]";
426: }
427: print MSG "public||||}\n";
428: close(MSG);
429:
430: &UnHideMsgDoneHTML;
431: }
432:
433:
434: sub TopMsg {
435: &CheckAdmin('kill');
436:
437: $ext = shift(@_);
438:
439: open(MSG,"$capadir/$class/discussion/$setid/$file");
440: @msg = <MSG>;
441: close(MSG);
442:
443: unlink("$capadir/$class/discussion/$setid/$file");
444:
445: ($filename, $extension) = split(/\./,$file);
446: $filename = "$filename-$ext.msg";
447: open(MSG,">$capadir/$class/discussion/$setid/$filename");
448: for($i=0;$i<=6;$i++) {
449: print MSG "$msg[$i]";
450: }
451: close(MSG);
452:
453: if($ext eq "") {
454: $function = "restored to its original position in the thread.";
455: }
456: else {
457: $function = "moved to the top of the thread list.";
458: }
459:
460: &TopMsgDoneHTML;
461: }
462:
463: ###############################
464: ## Administrator Subroutines ##
465: ###############################
466:
467: sub AdminMain {
468: &CheckAdmin('kill');
469: &AdminMainHTML;
470: exit;
471: }
472:
473:
474: sub AdminUserSearch {
475: &CheckAdmin('kill');
476: &AdminUserSearchHTML;
477: exit;
478: }
479:
480:
481: sub AdminUserSearchSubmit {
482: local($sname,$semail,$saction,$sset,$sprob,$sdate,$stime);
483: &CheckAdmin('kill');
484:
485: $query = $form{'usersearch'};
486: open(LOG,"$capadir/$class/discussion/logs/access.log");
487: @log = <LOG>;
488: close(LOG);
489:
490: @linematches = grep /$query/, @log;
491:
492: foreach $line(@linematches) { print $line; }
493:
494: exit;
495: }
496:
497: ######################
498: ## Misc Subroutines ##
499: ######################
500:
501: sub OpenMsg {
502: local($filename,$statusl);
503:
504: $filename = shift(@_);
505:
506: open (MSG,"$filename");
507: @msg = <MSG>;
508: close(MSG);
509:
510: $poster = $msg[0];
511: $date = $msg[1];
512: $time = $msg[2];
513: $subject = $msg[3];
514: $email = $msg[4];
515: $message = $msg[5];
516: $statusl = $msg[6];
517:
518: ($status, $hiddenuser, $hiddendate, $hiddentime, $hiddenaddr) = split(/\|/,$statusl);
519: }
520:
521: sub WriteMsg {
522: local($filename,$message);
523:
524: $filename = shift(@_);
525: # add sr to grab e-mail address of user
526:
527: $message = $form{'message'};
528: $message =~ s/\n\r\n/<p>/g;
529: $message =~ s/\n/<br>/g;
530:
531: # check if posted anonymously
532: if($form{'ANONYMOUS'} eq "yes") {
533: $username = "Anonymous|$username";
534: }
535:
536: open (MSG,">$filename");
537: print MSG "$username\n";
538: print MSG "$HyphenDate\n";
539: print MSG "$Time\n";
540: print MSG "$subject\n";
541: print MSG "$email\n";
542: print MSG "$message\n";
543: print MSG "public||||\n";
544: close(MSG);
545: }
546:
547: sub GetTeacherInfo {
548: local($capa5dir,$classname,$tdir,@classconf);
549:
550: # open/read class.conf file
551: open (CLASSCONF,"$capabin/class.conf");
552: @classconf = <CLASSCONF>;
553: close(CLASSCONF);
554:
555: $found eq "no";
556: foreach $line(@classconf) {
557: ($classname,$capa5dir,$tdir) = split(/[\t\ ]+/,$line);
558:
559: if($classname eq $class) {
560: $teachdir = $tdir;
561: $capadir = $capa5dir;
562: $found = "yes";
563: }
564: }
565: if($found eq "no") { &InvalidVarsHTML; }
566: chop $teachdir;
567: }
568:
569: sub CheckAdmin {
570: local($asection,@adminsections,$line,@capaconfig,$command,$value,
571: $adminsection,@classl,$course,$coursenum,$section,$stunum,$a);
572:
573: $validadmin = "no";
574: $mode = shift(@_);
575:
576: # open 'capa.config' file (for admin section read)
577: open(CAPACONFIG,"$capadir/$class/capa.config");
578: @capaconfig = <CAPACONFIG>;
579: close(CAPACONFIG);
580: foreach $line(@capaconfig) {
581: chop $line;
582: ($command,$value) = split(/\ =\ /,$line);
583: if($command eq "admin_section") {
584: $adminsection = $value;
585: }
586: }
587:
588: @adminsections = split(/\,/,$adminsection);
589:
590: # open 'classl' file
591: open(CLASSL,"$capadir/$class/classl");
592: @classl = <CLASSL>;
593: close(CLASSL);
594:
595: foreach $line(@classl) {
596: chop $line;
597: ($course,$coursenum,$section,$stunum,$a) = split(/\ +/,$line);
598: $snum =~ tr/a-z/A-Z/;
599: $stunum =~ tr/a-z/A-Z/;
600: $section = &RemZero($section);
601: foreach $asection(@adminsections) {
602: if(&RemZero($section) eq &RemZero($asection) && $stunum eq $snum) {
603: $validadmin = "yes";
604: }
605: }
606: }
607: if($validadmin eq "no" && $mode eq "kill") { &NotAdminHTML; }
608: }
609:
610: sub ValidateUser {
611: local(@allcapaid,@classl,$line);
612:
613: open (CLASSL,"$capadir/$class/classl");
614: @classl = <CLASSL>;
615: close(CLASSL);
616:
617: $valid = "no";
618: foreach $line(@classl) {
619: if(substr($line,15,8) eq substr($snum,1,8)) {
620: $valid = yes;
621: }
622: }
623: if($valid eq "no") { &InvalidVarsHTML; }
624:
625: # check w/ allcapaid program
626: @allcapaid = `allcapaid -s $setid -e $setid -stu $snum -c $capadir/$class -i`;
627:
628: chop $allcapaid[2];
629: chop $allcapaid[2];
630: if($allcapaid[2] ne $capaid) {
631: if($action ne "newset") { &BadPassHTML; }
632: &NewSet;
633: }
634: }
635:
636: sub UserInfo {
637: local($line,@classl,$last,$first,$middle);
638:
639: open (CLASSL,"$capadir/$class/classl");
640: @classl = <CLASSL>;
641: close(CLASSL);
642:
643: foreach $line(@classl) {
644: if(substr($line,15,8) eq substr($snum,1,8)) {
645: $username = substr($line,24,36);
646: $email = substr($line,60,45);
647: }
648: }
649: ($last, $first, $middle) = split(/\ +/,$username);
650:
651: chop $last;
652: $username = "$first $last";
653: $email =~ s/\ //g;
654: chop $email;
655: }
656:
657: sub MaxProbs {
658: open (SETRECORD,"$capadir/$class/records/set$setid.db");
659: @setrecord = <SETRECORD>;
660: close(SETRECORD);
661: chop $setrecord[0];
662: return $setrecord[0];
663: }
664:
665: sub ProblemJumpBox {
666: $pdprob = "<select name=\"PROBNUM\">\n";
667: for($jumpnum=1;$jumpnum<=&MaxProbs;$jumpnum++) {
668: $selected = "";
669: if($jumpnum eq $probnum) { $selected = " selected"; }
670: $pdprob .= " <option value=$jumpnum$selected>$jumpnum\n";
671: }
672: $pdprob .= "</select>";
673: }
674:
675: sub SetJumpBox {
676: opendir(DDIR,"$capadir/$class/discussion");
677: @sets = grep(/[0-9]/,sort(readdir(DDIR)));
678: closedir(DDIR);
679:
680: $pdset = "<select name=\"SETID\">\n";
681: foreach $set(@sets) {
682: $selected = "";
683: if($set eq $setid) { $selected = " selected"; }
684: $pdset .= " <option value=\"$set\"$selected>$set\n";
685: }
686: $pdset .= "</select>";
687: }
688:
689: sub AddZero {
690: $string = shift(@_);
691:
692: while(length($string) < 6) {
693: $string = "0$string";
694: }
695: return $string;
696: }
697:
698: sub RemZero {
699: $string = shift(@_);
700:
701: $fc = substr($string,0,1);
702: while($fc eq "0") {
703: $string =~ s/.//;
704: $fc = substr($string,0,1);
705: }
706: return $string;
707: }
708:
709: sub FormatDate {
710: $string = shift(@_);
711:
712: $month = substr($string,0,2);
713: $day = substr($string,2,2);
714: $year = substr($string,4,4);
715:
716: $string = "$month-$day-$year";
717:
718: return $string;
719: }
720:
721: ####################
722: ## Get SubRoutine ##
723: ####################
724: sub form_info {
725: read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
726:
727: # Split the name-value pairs
728: @pairs = split(/&/, $buffer);
729:
730: foreach $pair (@pairs) {
731: ($name, $value) = split(/=/, $pair);
732:
733: # Un-Webify plus signs and %-encoding
734: $value =~ tr/+/ /;
735: $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
736: $value =~ s/<!--(.|\n)*-->//g;
737:
738: if ($allow_html != 1) {
739: $value =~ s/<([^>]|\n)*>//g;
740: }
741: $form{$name} = $value;
742: }
743: }
744:
745: ##################
746: ## Date/Time sr ##
747: ##################
748: sub GetDateTime {
749: ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime (time);
750: $mon++;
751:
752: if ($hour < 12) {
753: $AMPM = "AM";
754: }
755:
756: if ($hour > 12) {
757: $hour = $hour - 12;
758: $AMPM = "PM";
759: }
760: if ($hour == 12) {
761: $AMPM = "PM";
762: }
763:
764: if ($hour == 0) {
765: $hour = "12";
766: }
767:
768: $min = sprintf ("%2d", $min);
769: $min =~tr/ /0/;
770: $mon = sprintf ("%2d", $mon);
771: $mon =~tr/ /0/;
772: $mday = sprintf ("%2d", $mday);
773: $mday =~tr/ /0/;
774: $HyphenDate = ("$mon" . "-" . "$mday" . "-" . "$year");
775: $RunonDate = ("$mon$mday$year");
776: $Time = ("$hour" . ":" . "$min" . " " . "$AMPM");
777: }
778:
779: ########################
780: ## Logging Subroutine ##
781: ########################
782: sub Log {
783: $logmsg = shift(@_);
784:
785: &GetDateTime;
786:
787: &Lock("lock.file");
788: open(LOG,">>$capadir/$class/discussion/logs/access.log");
789: print LOG "$snum|$capaid|$username|$email|$logmsg|$setid|$probnum|$HyphenDate|$Time\n";
790: close(LOG);
791: &Unlock("lock.file");
792: }
793:
794: ############################
795: ## Lock/Unlock Subroutine ##
796: ############################
797: sub Lock {
798: local ($lockname) = @_;
799: local ($endtime);
800: $endtime = 15;
801: $endtime = time + $endtime;
802:
803: while (-e $lockname && time < $endtime) {
804: open (LOCKFILE, ">$lockname");
805: }
806:
807: sub Unlock {
808: local ($lockname) = @_;
809: close (LOCKFILE);
810: unlink ($lockname);
811: }
812: }
813:
814:
815: ######################
816: ## HTML Subroutines ##
817: ######################
818:
819: ## CapaDiscuss HTML Subroutines
820:
821: # capadiscuss_html
822:
823: ## end capadiscuss
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>