2 # This is a module with functions for HTML output.
4 # I separate it from the main STUMP stuff because these functions are
5 # bulky and not very interesting.
10 use CGI qw/escapeHTML/;
13 my $title = pop( @_ );
15 "Content-Type: text/html\n\n
21 print "<B> You are operating in demonstration mode. User actions will have no effect.</B><HR>\n";
27 print "\n<HR>Thank you for using <A HREF=$STUMP_URL>STUMP Robomoderator</A>.
29 Click <A HREF=$base_address>here</A> to return to WebSTUMP. -->
33 # prints a link to help
34 # accepts topic id and topic name.
37 my $topic_name = pop( @_ );
38 my $topic = pop( @_ );
40 #&print_image( "help.gif", "" );
42 print "<A HREF=$base_address?action=help&topic=$topic TARGET=new>Click here for help on $topic_name</A>\n";
46 # prints image and an alt text
48 sub print_image { # image_file, alt_text
52 print "<IMG SRC=$base_address_for_files/images/$file ALT=\"$alt\" ALIGN=BOTTOMP>\n";
55 # prints the welcome page and login screen.
56 sub html_welcome_page {
57 &begin_html( "Welcome to WebSTUMP" );
61 "Welcome to WebSTUMP, the moderators' front end for <A
62 HREF=http://www.algebra.com/~ichudov/stump>STUMP</A> users -- USENET newsgroup
63 moderators. Only authorized users are allowed to log into this
68 my $motd_file = "$webstump_home/config/motd";
70 if( -f $motd_file && -r $motd_file ){
71 open( MOTD, $motd_file );
72 print "<B>Message of the Day:</B><BR><PRE>\n";
73 print while( <MOTD> );
79 Newsgroups Status:<BR>
82 for( sort @newsgroups_array ) {
85 my $count = &get_article_count( $_ );
87 print " <A HREF=$base_address?action=login_screen\&newsgroup=$_>$_</A>";
88 &print_image( "smiley.gif", "" ) if $count;
92 print "<TD>$count messages in queue<BR></TD>";
93 # print "<TD><A HREF=$base_address?action=init_request_newsgroup_creation\&newsgroup=$_>Request creation</A></TD>\n";
97 print "<HR>Note: click on the newsgroup to login in as moderator.
98 <!-- Click on 'Request Creation' to ask a sysadmin at a specific domain
99 to carry your newsgroup. -->\n<HR>
100 <A HREF=$base_address?action=admin_login>Click here to administer this WebSTUMP installation</A>
105 # prints the login screen for newsgroup.
106 sub html_login_screen {
107 my $newsgroup = $request{'newsgroup'} || &error( "newsgroup not defined" );
109 my $count = &get_article_count( $newsgroup );
113 &begin_html( "$count articles in queue for $newsgroup" );
115 &begin_html( "Empty Queue for $newsgroup" );
119 " Welcome to the Moderation Center for $newsgroup. Please bookmark
123 my $color = "", $end_color = "";
126 $color = "<font color=red>";
127 $end_color = "<font color=black>";
131 "<FORM METHOD=$request_method action=$base_address>
132 <INPUT NAME=action VALUE=moderation_screen TYPE=hidden>
135 &print_image( "new_tiny2.gif", "new" ) if $count;
137 print " articles available)<BR> $end_color
138 Login: <INPUT NAME=moderator VALUE=\"\" SIZE=20>
140 Password: <INPUT NAME=password TYPE=password VALUE=\"\" SIZE=20>
142 <INPUT TYPE=submit VALUE=\"Proceed with Login\">
143 <INPUT TYPE=reset VALUE=\"Reset\">
144 <INPUT NAME=newsgroup VALUE=\"$newsgroup\" TYPE=hidden>
146 Please log into $newsgroup. You can only log in if you know your login id
147 and know the secret password. You should not give your password to any
148 unauthorized user. Your login id and password are NOT case sentitive,
150 for example, \"xyzzy\" and \"XyZZY\" are equally valid.<P>
154 # Log in as \"admin\" if you want to
156 # <LI> edit filtering lists.";
158 # &link_to_help( "filter-lists", "Filter Lists" );
161 # <LI> add/delete users or change their passwords.
162 # <LI> First Time Users: You have to log in as admin and add a moderator user
163 # who will be able to moderate the newsgroup. Then log in again as that
164 # user. If you are a new user, you have to have your admin password assigned to
165 # you by the administrator.
172 # prints the login screen for newsgroup.
173 sub admin_login_screen {
174 &begin_html( "Administrative login" );
178 Attention: this page is only for the maintainer of the whole WebSTUMP
179 installation. Please return to the main page if you are not the maintainer
180 of this installation. <HR>
184 "<FORM METHOD=$request_method action=$base_address>
185 <INPUT NAME=action VALUE=webstump_admin_screen TYPE=hidden>
186 Password: <INPUT NAME=password TYPE=password VALUE=\"\" SIZE=20>
188 <INPUT TYPE=submit VALUE=\"Proceed with Login\">
189 <INPUT TYPE=reset VALUE=\"Reset\">
196 # main moderation page -- old version
197 sub html_moderate_article {
198 my $newsgroup = &required_parameter( 'newsgroup' );
199 my $moderator = $request{'moderator'};
200 my $password = $request{'password'};
201 my $file = shift @_ || &required_parameter('file');
203 &begin_html( "Main Moderation Screen: $newsgroup" );
206 &read_rejection_reasons;
208 my $dir = "$queues_dir/$newsgroup";
210 if( -d "$dir/$file" && open( TEXT_FILES, "$dir/$file/text.files.lst" ) ) {
212 print "<HR>\n" if &print_article_warning( $file );
217 while( $filename = <TEXT_FILES> ) {
218 open( ARTICLE, "$dir/$file/$filename" );
220 $embolden= m/^(?:from|subject)\s*\:/i;
224 $_= "<strong>$_</strong>" if $embolden;
226 $inhead= 0 unless m/\S/;
232 print "\n</PRE>\n\n";
234 &print_images( $newsgroup, "$dir/$file", $file);
237 print "This message ($dir/$file) no longer exists -- maybe it was " .
238 "approved or rejected by another moderator.";
242 <FORM NAME=decision METHOD=$request_method action=$base_address>
246 <INPUT NAME=action VALUE=approval_decision TYPE=hidden>";
247 &html_print_credentials;
248 print "<SELECT NAME=\"decision_$file\">
249 <OPTION VALUE=\"approve\">Approve</OPTION>
250 <OPTION VALUE=\"leave\" SELECTED>Put to back of queue</OPTION>
251 <OPTION VALUE=\"consider\">Back of queue, adding mark requesting further consideration</OPTION>
254 foreach (sort(keys %rejection_reasons)) {
255 print "<OPTION VALUE=\"reject $_\">Reject -- $rejection_reasons{$_}</OPTION>\n";
260 print "</SELECT><BR> Comment: <INPUT NAME=comment VALUE=\"\" SIZE=80><BR>";
263 <INPUT TYPE=radio NAME=poster_decision VALUE=nothing CHECKED>Don't change poster's status</INPUT>
264 <INPUT TYPE=radio NAME=poster_decision VALUE=preapprove
265 >White-list poster</INPUT>
266 <INPUT TYPE=radio NAME=poster_decision VALUE=ban
267 ONCLICK=\"alert( 'Banning a poster is a controversial practice'); \"
268 > Ban All Posts by this Person (Careful!)</INPUT>
270 <INPUT TYPE=radio NAME=thread_decision VALUE=nothing CHECKED>Don't change thread's status</INPUT>
271 <!-- <INPUT TYPE=radio NAME=thread_decision VALUE=preapprove>Preapprove thread, by Subject:</INPUT> -->
274 <!-- <INPUT TYPE=radio NAME=thread_decision VALUE=ban
275 ONCLICK=\"alert( 'Banning a thread is a controversial practice'); \"
276 >Ban Entire Thread By Subject (Careful!)</INPUT> -->
277 <!-- <INPUT TYPE=radio NAME=thread_decision VALUE=watch>Put Entire thread on a Watch, by Subject:</INPUT> -->
281 NOTE: Decisions to ban and whitelist posters can be reversed by
282 logging in as \"admin\" and editing respective lists of whitelisted
286 &link_to_help( "filter-lists", "automatic filtering and filter lists, blacklisting and preapproved threads." );
288 print "Be really careful about blacklisting of everyone except spammers.</I><BR><BR>
290 <INPUT TYPE=radio NAME=next_screen VALUE=single CHECKED>
291 Review ONE article in next screen
292 <INPUT TYPE=radio NAME=next_screen VALUE=multiple>
293 Review multiple articles in next screen
296 <INPUT TYPE=submit VALUE=\"Submit\">
297 <INPUT TYPE=submit NAME=skip_submit VALUE=\"Skip\">
298 <INPUT TYPE=reset VALUE=\"Reset\">
302 print "<BR><A HREF=$base_address?action=change_password&newsgroup=$newsgroup&" .
303 "moderator=$moderator&password=$password>Change Password</A>";
309 # WebSTUMP administrative screen
310 sub webstump_admin_screen {
312 &verify_admin_password;
314 my $password = $request{'password'};
316 &begin_html( "WebSTUMP Administration" );
318 <FORM METHOD=$request_method action=$base_address>
319 <INPUT NAME=action VALUE=admin_add_newsgroup TYPE=hidden>
320 <INPUT NAME=password VALUE=\"$password\" TYPE=hidden>\n";
325 Create a new newsgroup on the server:<BR>
327 Newsgroup:<BR> <INPUT NAME=newsgroup_name VALUE=\"\" SIZE=50><BR>
328 Address to send approved/rejected messages <BR>
329 <INPUT NAME=newsgroup_approved_address VALUE=\"\" SIZE=30><BR>
330 Admin Password For this group:<BR> <INPUT NAME=newsgroup_password VALUE=\"\" SIZE=10><BR>
331 <INPUT TYPE=submit VALUE=\"Submit\">
332 <INPUT TYPE=reset VALUE=\"Reset\"><HR>
335 print "</FORM>\n\n<PRE>\n";
340 # WebSTUMP "add newsgroup" function
341 sub admin_add_newsgroup {
343 &verify_admin_password;
345 my $newsgroup = &required_parameter( 'newsgroup_name' );
347 $newsgroup =~ s/\///g;
348 $newsgroup = &untaint( $newsgroup );
350 my $address = &required_parameter( 'newsgroup_approved_address' );
351 my $password = &required_parameter( 'newsgroup_password' );
353 &user_error( "Newsgroup $newsgroup already exists" )
354 if defined $newsgroups_index{$newsgroup};
356 &user_error( "Password may only contain letters and digits" )
357 if( ! ($password =~ /^[a-zA-Z0-9]+$/ ) );
359 &begin_html( "WebSTUMP Administration: Newsgroup created" );
363 print "Adding $newsgroup to $webstump_home/config/newsgroups.lst...";
364 mkdir "$webstump_home/queues/$newsgroup", 0755;
367 $dir = "$webstump_home/config/newsgroups/$newsgroup";
369 print "Creating $dir...";
373 print "Creating files in $dir...";
375 &append_to_file( "$dir/address.txt", "$address\n" );
376 &append_to_file( "$dir/moderators", "ADMIN \U$password\n" );
377 &append_to_file( "$dir/rejection-reasons",
378 "offtopic::a blatantly offtopic article, spam
379 harassing::message of harassing content
380 charter::message poorly formatted
393 $web_subdir = pop( @_ );
395 $newsgroup = pop( @_ );
397 opendir( SUBDIR, $subdir );
401 while( $_ = readdir( SUBDIR ) ) {
402 my $file = "$subdir/$_";
403 next if( ! -f $file || ! -r $file );
404 my $extension = $file;
405 $extension =~ s/^.*\.//;
406 $extension = "\L$extension";
408 if( $extension eq "gif" || $extension eq "jpg" || $extension eq "jpeg" ) {
409 print "<CENTER> <IMG SRC=$base_address_for_files/queues/$newsgroup/$web_subdir/$_></CENTER><HR>\n";
413 $filename =~ s/^.*\///;
414 next if $filename eq "skeleton.skeleton"
415 || $filename eq "headers.txt"
416 || $filename eq "full_message.txt"
417 || $filename eq "text.files.lst"
418 || $filename eq "stump-prolog.txt"
419 || $filename eq "stump-warning.txt"
420 || $filename =~ /msg-.*\.doc/;
422 &print_image( "no_image.gif", "security warning" );
423 print "<B>Non-image attachment:</B><CODE>$filename</CODE> NOT SHOWN for security reasons.<BR>\n";
429 # prints warning if there is warning stored about the article
430 sub print_article_warning { # short-subdir
431 my $file = pop( @_ );
433 my $warning_file = &article_file_name( $file ) . "/stump-warning.txt";
435 if( -r $warning_file ) {
436 open( WARNING, $warning_file );
437 while ($warning = <WARNING>) {
438 next unless $warning =~ m/\S/;
439 $warning =~ s/\&/&/g;
440 $warning =~ s/</</g;
441 $warning =~ s/>/>/g;
442 &print_image( "star.gif", "warning" );
443 print "<FONT COLOR=red>$warning</FONT><br>\n";
452 sub get_queue_list ($) {
453 my ($newsgroup) = @_;
454 my $dir = "$queues_dir/$newsgroup";
457 opendir(QUEUED, $dir) or &error("could not open directory $dir");
461 my $subdir= scalar readdir(QUEUED);
462 last unless defined $subdir;
464 my $subpath= "$dir/$subdir";
465 next if $subdir =~ /^\.+/;
466 next unless -d $subpath;
468 if (!stat "$subpath/stump-warning.txt") {
469 $!==&ENOENT or die "$subpath $!";
472 $sortkey= (stat _)[9];
474 $sortkeys{$subdir}= $sortkey;
477 my @articles= sort { $sortkeys{$a} <=> $sortkeys{$b} } keys %sortkeys;
478 return ($dir, @articles);
481 # main moderation page
482 sub html_moderation_screen {
483 my $newsgroup = &required_parameter( 'newsgroup' );
484 my $moderator = $request{'moderator'};
485 my $password = $request{'password'};
488 if( $request{'next_screen'} eq 'single' ) {
489 # we show a single article if the user so requested.
490 # just get the first article from the queue if any, otherwise show
491 # an empty main screen.
493 my ($dir, @articles)= get_queue_list($newsgroup);
496 for ($i=0; $i<@articles; $i++) {
497 my $subdir= shift @articles;
498 push @articles, $subdir;
499 last if $request{"decision_$subdir"};
502 while( $subdir = shift @articles ) {
503 if( -d "$dir/$subdir" && !($subdir =~ /^\.+/)
504 && open( PROLOG, "$dir/$subdir/stump-prolog.txt" ) ) {
505 &html_moderate_article( $subdir );
510 # otherwise just show the moderator an empty main screen.
513 &begin_html( "Main Moderation Screen: $newsgroup" );
514 print "Welcome to the main moderation screen. Its main purpose is to
515 help you process most messages extremely quickly. For every message, it
516 presents you who sent it, as well as the first three non-blank lines.
517 For those messages where the decision is obvious, simply select your
518 decision (approve/reject etc) and click submit. For those messages which
519 you would like to review in more details, do not select anything and
520 use Review/Comment function from this screen or from a subsequent screen.
521 Remember that if you do not make any decision, the article would stay in the
524 &read_rejection_reasons;
526 my ($dir, @articles)= get_queue_list($newsgroup);
529 <FORM METHOD=$request_method action=$base_address>
530 <INPUT NAME=action VALUE=approval_decision TYPE=hidden>";
531 &html_print_credentials;
533 print "<HR> <INPUT TYPE=submit VALUE=Submit>
534 <INPUT TYPE=reset VALUE=Reset>
537 my $file, $subject = "No Subject", $from = "From nobody";
538 my $form_not_empty = "";
539 my $article_count = 0;
541 while( ($subdir = shift @articles) && $article_count++ < 40 ) {
543 if( -d "$dir/$subdir" && !($subdir =~ /^\.+/)
544 && open( PROLOG, "$dir/$subdir/stump-prolog.txt" ) ) {
547 if( /^Real-Subject: /i ) {
551 s/^Real-Subject: //g;
552 $subject = substr( $_, 0, 50 );
553 } elsif( /^From: /i ){
557 $from = substr( $_, 0, 50 );
563 print "<HR><B>$from: $subject</B>(";
564 print "<A HREF=$base_address?action=moderate_article&newsgroup=$newsgroup&" .
565 "moderator=$moderator&password=$password&file=$subdir>Review/Comment/Whitelist</A>)<BR>\n";
566 print "<INPUT TYPE=radio NAME=\"decision_$file\" VALUE=approve>Approve\n";
567 print "<INPUT TYPE=radio NAME=\"decision_$file\" VALUE=skip>Leave\n";
568 print "<INPUT TYPE=radio NAME=\"decision_$file\" VALUE=leave>Back of queue\n";
569 foreach (@short_rejection_reasons) {
570 print "<INPUT TYPE=radio NAME=\"decision_$file\" VALUE=\"reject $_\">Reject \u$_\n";
575 &print_article_warning( $file );
581 while( ($_ = <PROLOG>) && $i < 5 ) {
588 print "] " . substr( $_, 0, 75 ) . "\n";
594 $form_not_empty = "yes";
596 $article_count += &print_images( $newsgroup, "$dir/$subdir", $subdir );
600 if( $form_not_empty ) {
601 print "<HR> <INPUT TYPE=submit VALUE=Submit>
602 <INPUT TYPE=reset VALUE=Reset>
607 No articles present in the queue
608 <INPUT TYPE=submit VALUE=Refresh>
612 print "<A HREF=$base_address?action=change_password&newsgroup=$newsgroup&" .
613 "moderator=$moderator&password=$password>Change Password</A>";
617 print "<FORM METHOD=$request_method action=$base_address>";
618 &html_print_credentials;
619 print "<INPUT NAME=action VALUE=moderator_admin TYPE=hidden>
620 <INPUT TYPE=submit VALUE=\"Management\">
626 # prints hidden fields -- credentials
627 sub html_print_credentials {
628 my $newsgroup = $request{'newsgroup'};
629 my $moderator = $request{'moderator'};
630 my $password = $request{'password'};
633 <INPUT NAME=newsgroup VALUE=\"$newsgroup\" TYPE=hidden>
634 <INPUT NAME=moderator VALUE=\"$moderator\" TYPE=hidden>
635 <INPUT NAME=password VALUE=\"$password\" TYPE=hidden>\n";
641 my ($forwards, $gotr, $callback) = @_;
642 my $dir= "$webstump_home/..";
643 opendir LOGSDIR, "$dir" or die "$dir $!";
648 m/^errs\.(\d+)(?:\.gz$)$/ ? $1 :
653 sort { $num->($a) <=> $num->($b) }
654 grep { defined $num->($_) }
657 my $file= "$dir/$leaf";
658 if ($file =~ m/\.gz$/) {
659 open LOGFILE, "zcat $file |" or die "zcat $file $!";
661 open LOGFILE, "< $file" or die "$file $!";
664 my $tgot= $callback->();
666 $$gotr= $tgot if $tgot > $$gotr;
669 $!=0; $?=0; close LOGFILE or die "$file $? $!";
672 closedir LOGSDIR or die "$dir $!";
675 sub html_search_logs {
676 &begin_html("Search logs for $request{'newsgroup'}");
680 if ($request{'download_logs'}) {
681 print "<h2>Complete log download</h2>\n";
683 } elsif ($request{'messagenum'} =~ m/^\s*(\d+)\s*$/) {
687 print "<h2>Log entry for single message $reqnum</h2>\n";
689 print "<h2>Log lookup - bad reference</h2>
690 Please supply the numerical reference as found in the \"recent activity\"
691 log or message headers. Reference numbers consist entirely of digits,
692 and are often quoted in message headers in [square brackets].<p>
697 if ($mod_log_access < $min) {
698 print "Not permitted [$mod_log_access<$min]. Consult administrator.\n";
704 &scanlogs($forwards, \$sofar, sub {
705 return 0 unless chomp;
706 return 0 unless m/^DECISION: /;
707 my @vals = split / \| /, $';
708 return 0 unless @vals >= 5;
710 my ($group,$dir,$act,$reason,$timet) = @vals;
711 my $date= $timet ? (strftime "%Y-%m-%d %H:%M:%S GMT", gmtime $timet)
713 return 0 unless $group eq $request{'newsgroup'};
714 return 0 unless $subj =~ m,/(\d+)$,;
716 return 0 if defined($reqnum) and $treqnum ne $reqnum;
717 print "<table rules=all><tr><th>Date<th>Reference<th>Disposal<th>Reason</tr>\n"
719 print "<tr>", (map { "<td>".escapeHTML($_) }
720 $date,$treqnum,$act,$reason);
722 return defined($reqnum) ? 2 : 1;
725 print "</table>" if $sofar;
728 print "Reference not found.".
729 " (Perhaps message has expired, or is still in the queue?)";
734 # newsgroup admin page
735 sub html_newsgroup_management {
736 &begin_html( "Administer $request{'newsgroup'}" );
738 print "All usernames and passwords are not case sensitive.\n";
739 print "<HR>Use this form to add new moderators or change passwords:<BR>
740 <FORM METHOD=$request_method action=$base_address>
741 <INPUT NAME=action VALUE=add_user TYPE=hidden>";
742 &html_print_credentials;
744 Username: <INPUT NAME=user VALUE=\"\" SIZE=20>
746 Password: <INPUT NAME=new_password VALUE=\"\" SIZE=20>
748 <INPUT TYPE=submit VALUE=\"Add/Change\">
749 <INPUT TYPE=reset VALUE=Reset>
753 print "<HR>Use this form to delete moderators:<BR>
754 <FORM METHOD=$request_method action=$base_address>
755 <INPUT NAME=action VALUE=delete_user TYPE=hidden>";
756 &html_print_credentials;
758 Username: <INPUT NAME=user VALUE=\"\" SIZE=20>
760 <INPUT TYPE=submit VALUE=\"Delete Moderator\">
761 <INPUT TYPE=reset VALUE=Reset>
764 <FORM METHOD=$request_method action=$base_address>
765 <INPUT NAME=action VALUE=edit_list TYPE=hidden>";
766 &html_print_credentials;
768 Configuration List: <SELECT NAME=list_to_edit>
770 <OPTION VALUE=good.posters.list>Good Posters List
771 <OPTION VALUE=bad.posters.list>Banned Posters List
772 <OPTION VALUE=watch.words.list>Suspicious Words List
775 <INPUT TYPE=submit VALUE=\"Edit\">
776 <INPUT TYPE=reset VALUE=Reset>";
778 &link_to_help( "filter-lists", "filtering lists" );
782 if ($mod_log_access) {
784 Use this form to search logs of past moderation decisions:
786 <form method=$request_method action=$base_address>
787 <input name=action value=search_logs type=hidden>";
789 &html_print_credentials;
792 Reference number: <input name=messagenum size=30>
793 <input type=submit value=\"Lookup\">";
796 <input type=submit value=\"Download all logs\" name=\"download_logs\">"
797 if $mod_log_access >= 2;
799 print "</form><hr>\n";
804 List of current moderators:<P>
808 foreach (keys %moderators) {
819 sub edit_configuration_list {
821 my $list_to_edit = &required_parameter( 'list_to_edit' );
823 $list_to_edit = &check_config_list( $list_to_edit );
825 my $list_file = &full_config_file_name( $list_to_edit );
827 my $list_content = "";
829 if( open( LIST, $list_file ) ) {
830 $list_content .= $_ while( <LIST> );
834 $list_content =~ s/\&/&/g;
835 $list_content =~ s/</</g;
836 $list_content =~ s/>/>/g;
838 &begin_html( "Edit $list_to_edit" );
841 " <FORM METHOD=$request_method action=$base_address>
842 <INPUT NAME=action VALUE=set_config_list TYPE=hidden>
843 <INPUT NAME=list_to_edit VALUE=$list_to_edit TYPE=hidden>";
844 &html_print_credentials;
845 &link_to_help( $list_to_edit, "$list_to_edit" );
848 <TEXTAREA NAME=list rows=20 COLS=50>
849 $list_content</TEXTAREA>
852 <INPUT TYPE=submit VALUE=\"Set\">
859 # password change page
860 sub html_change_password{
861 &begin_html( "Change Password" );
863 print "All usernames and passwords are not case sensitive.\n";
864 print "<HR>Use this form to change your password:<BR>
865 <FORM METHOD=$request_method action=$base_address>
866 <INPUT NAME=action VALUE=validate_change_password TYPE=hidden>";
867 &html_print_credentials;
870 New Password: <INPUT NAME=new_password VALUE=\"\" SIZE=20>
872 <INPUT TYPE=submit VALUE=Submit>
873 <INPUT TYPE=reset VALUE=Reset>
881 # newsgroup creation form
882 sub init_request_newsgroup_creation{
883 my $newsgroup = &required_parameter( 'newsgroup' );
885 &begin_html( "Request Creation of $newsgroup" );
887 print "This page helps you ask the system administrator of your domain
888 to create <B>$newsgroup</B> on your server. Type in your domain name and
889 click SUBMIT. An email will be sent to news\@domain and usenet\@domain
890 and postmaster\@domain
891 asking them to create your newsgroup. Please do NOT abuse this system.
892 NOTE: You can give the URL of this page to your group readers so that
893 they could request creation of their newsgroups by themselves.\n";
896 <FORM METHOD=$request_method action=$base_address>
897 <INPUT NAME=action VALUE=complete_newsgroup_creation_request TYPE=hidden>\n";
898 &html_print_credentials;
901 Domain Name ONLY: <INPUT NAME=domain_name VALUE=\"\" SIZE=40>
903 <INPUT TYPE=submit VALUE=Submit>
904 <INPUT TYPE=reset VALUE=Reset>
912 # newsgroup creation completion
913 sub complete_newsgroup_creation_request{
914 my $newsgroup = &required_parameter( 'newsgroup' );
915 my $domain_name = &required_parameter( 'domain_name' );
917 if( !($domain_name =~ /(^[a-zA-Z0-9\.-_]+$)/) ) {
918 &user_error( "invalid domain name" );
924 my $request = "To: news\@$domain_name, usenet\@$domain_name, postmaster\@$domain_name
925 Subject: Please create $newsgroup (Moderated)
926 From: devnull\@algebra.com ($newsgroup Moderator)
927 Organization: stump.algebra.com
929 Dear News Administrator:
931 A user of $domain_name has requested that you create a newsgroup
933 $newsgroup (Moderated)
935 on your server. $newsgroup
936 is a legitimately created moderated newsgroup that is available worldwide.
938 Thank you very much for your help and cooperation.
942 - Moderator of $newsgroup.
946 &email_message( $request, "news\@$domain_name" );
947 &email_message( $request, "usenet\@$domain_name" );
948 &email_message( $request, "postmaster\@$domain_name" );
950 &begin_html( "Request to create $newsgroup sent" );
952 print "The following request has been sent:<HR><PRE>\n";
954 print "$request</PRE>\n";
961 my $topic_name = &required_parameter( "topic" );
963 $topic_name =~ s/\///g;
964 $topic_name =~ s/\.\.//g;
965 $topic_name = &untaint( $topic_name );
967 my $file = "$webstump_home/doc/help/$topic_name.html";
969 &error( "Topic $topic_name not found in $file." )
972 open( FILE, "$file" );
974 $help .= $_ while( <FILE> );
977 $help =~ s/##/$base_address?action=help&topic=/g;
979 &begin_html( "$topic_name" );