]> bicyclesonthemoon.info Git - ott/bsta/blob - 2words.1.pl
start rework of 2words
[ott/bsta] / 2words.1.pl
1 ###RUN_PERL: #!/usr/bin/perl
2
3 # /bsta/2words
4 # 2words is generated from 2words.1.pl.
5 #
6 # The wordgame interface
7 #
8 # Copyright (C) 2016 - 2017, 2023  Balthasar SzczepaƄski
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU Affero General Public License as
12 # published by the Free Software Foundation, either version 3 of the
13 # License, or (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU Affero General Public License for more details.
19 #
20 # You should have received a copy of the GNU Affero General Public License
21 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23 use strict;
24 use utf8;
25 # use Encode::Locale ('decode_argv');
26 use Encode ('encode', 'decode');
27
28 ###PERL_LIB: use lib /botm/lib/bsta
29 use botm_common (
30         'read_data_file', 'write_data_file'
31 );
32 use bsta_lib (
33         'STATE', 'INTF_STATE',
34         'fail_method', 'fail_content_type',
35         'read_header_env',
36         'url_query_decode',
37         
38         
39         
40         # to replace
41         'failpage',
42         'gethttpheader',
43         'getcgi',
44         'entityencode',
45         'readdatafile',
46         'writedatafile',
47         'urlencode',
48         'bb2ht'
49 );
50 use  File::Copy;
51
52 ###PERL_CGI_PATH:           CGI_PATH           = /bsta/
53 ###PERL_CGI_2WORDS_PATH:    CGI_2WORDS_PATH    = /bsta/2words
54 ###PERL_CGI_CSS_PATH:       CGI_CSS_PATH       = /bsta/bsta.css
55 ###PERL_CGI_LOGO_PATH:      CGI_LOGO_PATH      = /bsta/botmlogo.png
56 ###PERL_CGI_VIEWER_PATH:    CGI_VIEWER_PATH    = /bsta/v
57
58 ###PERL_DATA_PATH:          DATA_PATH          = /botm/data/bsta/
59 ###PERL_DATA_COIN_PATH:     DATA_COIN_PATH     = /botm/data/bsta/coincidence
60 ###PERL_DATA_DEFAULT_PATH:  DATA_DEFAULT_PATH  = /botm/data/bsta/default
61 ###PERL_DATA_LIST_PATH:     DATA_LIST_PATH     = /botm/data/bsta/list
62 ###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings
63 ###PERL_DATA_STATE_PATH:    DATA_STATE_PATH    = /botm/data/bsta/state
64 ###PERL_DATA_STORY_PATH:    DATA_STORY_PATH    = /botm/data/bsta/story
65
66 ###PERL_WWW_PATH:           WWW_PATH           = /botm/www/1190/bsta/
67 ###PERL_WWW_INDEX_PATH:     WWW_INDEX_PATH     = /botm/www/1190/bsta/index.htm
68
69 ###PERL_WEBSITE:            WEBSITE            = 1190.bicyclesonthemoon.info
70 ###PERL_WEBSITE_NAME:       WEBSITE_NAME       = Bicycles on the Moon
71 ###PERL_FAVICON_PATH:       FAVICON_PATH       = /img/favicon.png
72
73 ###PERL_COIN_DATE:          COIN_DATE          = 13-Nov-2016 22:15
74 ###PERL_INTF_DATE:          INTF_DATE          = 28-Sep-2016 20:34
75
76 ###PERL_STORY_LENGTH:       STORY_LENGTH       = 16
77 ###PERL_PAGE_LENGTH:        PAGE_LENGTH        = 16
78 ###PERL_FIRSTPAGE_LENGTH:   FIRSTPAGE_LENGTH   = 4
79
80 binmode STDIN,  ':encoding(UTF-8)';
81 binmode STDOUT, ':encoding(UTF-8)';
82 binmode STDERR, ':encoding(UTF-8)';
83 # decode_argv();
84
85 my %http;
86 my %cgi;
87 my %story;
88 my %new_story;
89 my %settings;
90 my %state;
91 my %goto_list;
92
93 my $time = time();
94 srand ($time-$$);
95
96 my $method;
97 my $IP;
98 my $words;
99 my $color2;
100 my $last_IP;
101 my $story_id;
102 my $turn;
103 my $message;
104 my $first_letter;
105 my $second_letter;
106 my $intf_state;
107 my $intf_pass;
108 my $intf_pause;
109 my $intf_mode;
110 my $story_path;
111 my $story_file;
112 my $story_lock;
113 my @storylines;
114 my $ong_state;
115 my $page;
116 my $cmd_clear;
117 my $cmd_clear_all;
118
119
120 delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
121 ###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin;
122
123 if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) {
124         $method = $1;
125 }
126 else{
127         exit fail_method($ENV{'REQUEST_METHOD'}, 'GET, POST, HEAD');
128 }
129
130 %http = read_header_env(\%ENV);
131 %cgi = url_query_decode($ENV{'QUERY_STRING'});
132 if ($method eq 'POST') {
133         if ($http{'content-type'} eq 'application/x-www-form-urlencoded') {
134                 my %cgi_post=url_query_decode( <STDIN> );
135                 foreach my $ind (keys %cgi_post) {
136                         $cgi{$ind} = $cgi_post{$ind};
137                 }
138         }
139         # multipart not supported
140         else{
141                 exit fail_content_type($http{'content-type'}, $method);
142         }
143 }
144 $IP = get_remote_addr();
145 if ($ENV{'PATH_INFO'} =~ /^\/(.+)$/) {
146         $page=int($1);
147 }
148 else {
149         $page=0;
150 }
151 if ($cgi{'words'} ne '') {
152         $words=$cgi{'words'};
153 }
154
155 %settings = read_data_file(DATA_SETTINGS_PATH());
156 %state    = read_data_file(DATA_STATE_PATH());
157 $ong_state = int($state{'state'});
158 $cmd_clear     = settings{'password'}.' clear';
159 $cmd_clear_all = settings{'password'}.' clearall';
160
161 $story_lock=0;
162 if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
163         $story_lock=1;
164         if (flock($story_file,2)) {
165                 $story_lock=2;
166         }
167         %story = $read_data_file($story_file);
168         
169         if ($story{'lastip'} =~ /^.+$/) {
170                 $last_IP=$&;
171         }
172         else {
173                 $last_IP='0.0.0.0';
174         }
175         
176         $last_letter = lc($story{'letter'});
177         $story_id   = int($story{'id'});
178         $intf_pass  = int($story{'pass'});
179         $intf_state = int($story{'state'});
180         $intf_mode  = $intf_state;
181         $intf_pause = $intf_state & 0x01;
182         if ($intf_pause) {
183                 $intf_mode &= 0xFE;
184         }
185         
186         if ($IP ne $last_IP) {
187                 $turn = 1;
188         }
189         else {
190                 $turn = 0       ;
191         }
192         
193         if (
194                 ($words eq $cmd_clear) ||
195                 ($words eq $cmd_clear_all) ||
196                 ($intf_state < 0)
197         ) {
198                 if (
199                         ($words eq $cmd_clear_all) ||
200                         ($intf_state < -1)
201                 ) {
202                         $story{'id'} = 0;
203                 }
204                 $story{'content'} = '';
205                 $story{'lastip' } = '0.0.0.0';
206                 $story{'letter' } = '';
207                 $story{'pass'   } = 0;
208                 $story{'state'  } = INTF_STATE->{'X'};
209                 $turn = 0;
210                 if($ong_state == STATE->{'inactive'}) {
211                         writeindex(WWW_INDEX_PATH,0,0,0);  # TO REPLACE
212                 }
213                 write_data_file($story_file, '', '', \%story);
214         }
215         
216         if ($words ne '') {
217                 if (!$turn) {
218                         $message = "It's not your turn.";
219                 }
220                 # TODO: consider allowing non-ASCII letters in words.
221                 # (not very important in English language)
222                 elsif ($words =~ /^([!"\(\),\.:;\?][ \t]*)?([A-Za-z][A-Za-z'\-]*[A-Za-z']?)([!"\(\),\.:;\? \t][ \t]*)([A-Za-z][A-Za-z'\-]*[A-Za-z']?)([!"\(\),\.:;\?]?[ \t]*)$/) {
223                         $first_letter  = lc(substr($2, 0, 1));
224                         $second_letter = lc(substr($4, 0, 1));
225                         if (
226                                 ($first_letter ne $last_letter) &&
227                                 ($last_letter ne '')
228                         ) {
229                                 $message = 'The first word must start with '.uc($last_letter).'.';
230                         }
231                         elsif ($first_letter eq $second_letter) {
232                                 $message = 'The second word can\'t also start with '.uc($first_letter).'.';
233                         }
234                         else {
235                                 $story{'content'} = $story{'content'} . $words."\n";
236                                 $turn = 0;
237                                 $story{'lastip'} = $IP;
238                                 $story{'letter'} = $second_letter;
239                                 
240                                 if ($cgi{'next'} ne '') {
241                                         if (split(/\r?\n/,$story{'content'}) >= (STORY_LENGTH-1)) {
242                                                 $story_path = DATA_STORY_PATH.$story_id;
243                                                 write_data_file($story_path, '', '', \%story);
244                                                 $new_story{'id'     } = $story_id + 1;
245                                                 $new_story{'letter' } = '';
246                                                 $new_story{'lastip' } = $IP;
247                                                 $new_story{'content'} = '';
248                                                 $new_story{'pass'   } = 0;
249                                                 $new_story{'state'  } = INTF_STATE->{'X'};
250                                                 $intf_state = INTF_STATE->{'X'};
251                                                 $intf_pass = 0;
252                                                 $intf_mode = INTF_STATE->{'X'};
253                                                 $intf_pause= 0;
254                                                 if($ong_state == STATE->{'inactive'}) {
255                                                         writeindex(WWW_INDEX_PATH,0,0,0); # TO REPLACE
256                                                 }
257                                                 write_data_file($story_file, '', '', \%new_story);
258                                         }
259                                         else {
260                                                 $message = 'To early to finish this wordgame.';
261                                                 write_data_file($story_file, '', '', \%story);
262                                         }
263                                 }
264                                 else {
265                                         if ($intf_pass == 1) {
266                                                 $intf_pass = 2;
267                                                 $story{'pass'} = 2;
268                                                 if($ong_state == STATE->{'inactive'}) {
269                                                         writeindex(WWW_INDEX_PATH,2,0,0); # TO REPLACE
270                                                 }
271                                         }
272                                         elsif(lc($2).' '.lc($4) eq $settings{'unlock'}) {
273                                                 if ($intf_pass != 0) {
274                                                         $message = 'The password has already been used in this story.';
275                                                 }
276                                                 elsif ($ong_state != STATE->{'inactive'}) {
277                                                         $message = "???";
278                                                 }
279                                                 else {
280                                                         my %frame_data = read_data_file(DATA_PATH.0);
281                                                         my %default = read_data_file(DATA_DEFAULT_PATH());
282                                                         my $in_path;
283                                                         my $out_path;
284                                                         
285                                                         $frame_data{'ongtime'} = $time;
286                                                         $goto_list{'title-0'} = $frame_data{'title'};
287                                                         $goto_list{'ongtime-0'} = $frame_data{'ongtime'};
288                                                         writedatafile(DATA_PATH.0,%frame_data);
289                                                         writedatafile(DATA_LIST_PATH,%goto_list);
290                                                         
291                                                         foreach my $ind (keys %default) {
292                                                                 unless(defined($frame_data{$ind})){
293                                                                         $frame_data{$ind}=$default{$ind};
294                                                                 }
295                                                         }
296                                                         
297                                                         $inpath = DATA_PATH.sprintf($settings{'frame'},0,$frame_data{'ext'});
298                                                         $outpath = WWW_PATH.sprintf($settings{'frame'},0,$frame_data{'ext'});
299                                                         
300                                                         if(copy ($inpath, $outpath)) {
301                                                                 $intf_pass = 1;
302                                                                 $intf_state = 0;
303                                                                 $intf_mode=0;
304                                                                 $intf_pause=0;
305                                                                 $story{'pass'} = '1';
306                                                                 $story{'state'} = '0';
307                                                                 writeindex(WWW_INDEX_PATH,1,0,0);
308                                                         }
309                                                 }
310                                         }
311                                         writedatafile($story_file,%story);
312                                 }
313                         }
314                         else {
315                                 $message = 'Please, two words, not more, not less (some punctuation is allowed).';
316                         }
317                 }
318         }
319         elsif (($cgi{'s'} ne '') && ($intf_pass==1) && ($ong_state == 0)) {
320                 $intf_state = int($cgi{'s'});
321                 if($intf_state > 63 || $intf_state <0) {
322                         $intf_state = 0;
323                 }
324                 $intf_mode = $intf_state;
325                 $intf_pause = $intf_state & 1;
326                 if ($intf_pause) {
327                         $intf_mode -= 1;
328                 }
329                 $story{'state'} = $intf_state;
330                 writeindex(WWW_INDEX_PATH,1,$intf_mode,$intf_pause);
331                 writedatafile($story_file,%story);
332         }
333         @storylines = split(/\r?\n/,$story{'content'});
334         if(@storylines & 1) {
335                 $turn = !$turn;
336         }
337         
338         close($story_file);
339 }
340
341 print "Content-type: text/html\n\n";
342 if($method eq 'HEAD') {
343         exit;
344 }
345
346 print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">'."\n";
347 print '<html lang="en"><head>'."\n";
348 print '<title>Two words &bull; '.WEBSITE_NAME.'</title>'."\n";
349 print '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">'."\n";
350 print '<link rel="icon" type="image/png" href="'.FAVICON_PATH.'">'."\n";
351 print '<link rel="stylesheet" href="'.CGI_CSS_PATH.'">'."\n";
352 print '</head><body>'."\n";
353 print '<a href="/"><img id="botmlogo" src="'.CGI_LOGO_PATH.'" alt="'.WEBSITE.'"></a>'."\n";
354 print '<div id="all">'."\n";
355
356 print '<div id="inst" class="ins">'."\n";
357
358 print '<div id="title">'."\n";
359 print '<H1 id="titletext">Two words</H1>'."\n";
360 print '</div>'."\n";
361
362 if ($page == 0) {
363         print '<div id="storypuzzle">'."\n";
364         for (my $i = 0; $i < @storylines; ++$i){
365                 print '<span class="'.($turn?'ni':'br').'">'.entityencode($storylines[$i]).'</span>'."\n";
366                 $turn = !$turn;
367         }
368         print '</div>'."\n";
369
370         print '<div id="command">'."\n";
371         if ($message ne '') {
372                 print '<span class="br">'.entityencode($message).'</span>'."\n";
373         }
374         
375         if ($turn) {
376                 print '<form method="post" action="'.CGI_2WORDS_PATH.'">'."\n";
377                 if ($message eq '') {
378                         if ($story{"content"} eq '') {
379                                 print 'Two words, please:<br>'."\n";
380                         }
381                         else {
382                                 print 'Please continue, two words:<br>'."\n";
383                         }
384                 }
385                 print '<input class="intx" type="text" name="words">'."\n";
386                 print '<input class="inbt" type="submit" value="enter">'."\n";
387                 if(@storylines >= (STORY_LENGTH-1)) {
388                         print '<input class="inbt" type="submit" name="next" value="enter and then start a new one">'."\n";
389                 }
390                 print '</form>'."\n";
391         }
392         else {
393                 if ($message eq '') {
394                         print 'Wait for it.'."\n";
395                 }
396         }
397         print '</div>'."\n";
398 }
399 elsif ($message ne '') {
400         print '<div id="command">'."\n";
401         print '<span class="br">'.entityencode($message).'</span>'."\n";
402         print '</div>'."\n";
403 }
404
405 if(($intf_pass == 1) && ($ong_state == 0)) {
406         print '</div><div id="framespace">'."\n";
407         print '<table id="intftable" cellspacing="0" cellpadding="0"><tr class="intf">'."\n";
408         
409         print '<td colspan="6" class="intf"><img src="'.CGI_PATH.'intf-00';
410         if ($intf_mode == 4) {
411                 print '_04';
412         }
413         elsif ($intf_mode == 8) {
414                 print '_08';
415         }
416         elsif ($intf_state == 16) {
417                 print '_10';
418         }       
419         print'.gif" alt="" class="intf"></td>'."\n";
420         
421         print '</tr><tr class="intf">'."\n";
422         print '<td class="intf"><img src="'.CGI_PATH.'intf-20.gif" alt="o" class="intf"></td>'."\n";
423         print '<td class="intf"><a href="'.CGI_PATH.'2words?s='.($intf_pause?17:16).'"><img src="'.CGI_PATH.'intf-10'.(($intf_mode==16)?'_':'').'.gif" class="intf" alt="&gt"></td>'."\n";
424         print '<td class="intf"><a href="'.CGI_PATH.'2words?s='.($intf_pause?9:8).'"><img src="'.CGI_PATH.'intf-08'.(($intf_mode==8)?'_':'').'.gif" class="intf" alt="&lt;&lt;"></td>'."\n";
425         print '<td class="intf"><a href="'.CGI_PATH.'2words?s='.($intf_pause?5:4).'"><img src="'.CGI_PATH.'intf-04'.(($intf_mode==4)?'_':'').'.gif" class="intf" alt="&gt;&gt;"></td>'."\n";
426         print '<td class="intf"><a href="'.CGI_PATH.'2words?s='.($intf_pause?0:0).'"><img src="'.CGI_PATH.'intf-02.gif" class="intf" alt="^"></td>'."\n";
427         print '<td class="intf"><a href="'.CGI_PATH.'2words?s='.($intf_pause?$intf_mode:$intf_mode+1).'"><img src="'.CGI_PATH.'intf-01'.($intf_pause?'_':'').'.gif" class="intf" alt="||"></td>'."\n";
428         print '</tr></table>'."\n";
429 }
430
431 print '</div><div id="insb" class="ins">'."\n";
432 print '<div id="undertext">'."\n";
433 for (my $i = $story_id-1-(($page!=0)?((($page-1)*PAGE_LENGTH)+FIRSTPAGE_LENGTH):0); $i > ($story_id-1-($page*PAGE_LENGTH)- FIRSTPAGE_LENGTH) && $i >= 0; --$i) {
434         $story_path = DATA_STORY_PATH.$i;
435         %new_story = readdatafile($story_path);
436         print '<p class="'.(($i&1)?'br':'ni').'" id="s'.$i.'">'.entityencode($new_story{'content'}).'</p>'."\n";
437 }
438
439 print '</div>'."\n";
440 print '<div id="underlinks">'."\n";
441 print '<a href="'.CGI_PATH.'">BSTA</a> | <a href="'.CGI_2WORDS_PATH.'">Once again</a>';
442 if(($story_id - ($page*PAGE_LENGTH)) - FIRSTPAGE_LENGTH > 0) {
443         print ' | <a href="'.CGI_2WORDS_PATH.'/'.($page+1).'">Before</a>';
444 }
445 if($page > 0) {
446         print ' | <a href="'.CGI_2WORDS_PATH.'/'.($page-1).'">Unbefore</a>';
447 }
448 if(($story_id - ($page*PAGE_LENGTH)) - FIRSTPAGE_LENGTH > 0) {
449         print ' | <a href="'.CGI_2WORDS_PATH.'/'.(int(($story_id - FIRSTPAGE_LENGTH - 1) / PAGE_LENGTH) + 1).'">Initially</a>';
450 }
451 if($turn) {
452         print ' | (Entering words here is irreversible. Your actions might be remembered forever. So please be reasonable.)';
453 }
454 print "\n";
455 print '</div>'."\n";
456
457 print '</div>'."\n";
458 print '</div>'."\n";
459 print '<a href="/" class="cz">'.WEBSITE.'</a>'."\n";
460 print '</body></html>'."\n";
461
462 sub writeindex {
463         (my $indexpath, my $pass, my $mode, my $pause) = @_;
464         my $indexfile;
465         my $indexof;
466                 
467         if(ref($indexpath)) {
468                 $indexfile=$indexpath;
469                 unless (seek($indexfile, 0, 0)) {
470                         return 0;
471                 }
472         }
473         else {
474                 unless (open ($indexfile, ">", $indexpath)) {
475                         return 0;
476                 }
477         }
478         
479         $indexof = CGI_PATH;
480         $indexof =~ s/\/$//g;
481         
482         my %coin = readdatafile(DATA_COIN_PATH);
483         
484         if ($pass != 1) {
485                 print $indexfile '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'."\n";
486                 print $indexfile '<html>'."\n";
487                 print $indexfile ' <head>'."\n";
488                 print $indexfile '  <title>Index of '.$indexof.'</title>'."\n";
489                 print $indexfile ' </head>'."\n";
490                 print $indexfile ' <body>'."\n";
491                 print $indexfile '<h1>Index of '.$indexof.'</h1>'."\n";
492                 print $indexfile '<table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>'."\n";
493                 print $indexfile '<tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>'."\n";
494                 print $indexfile '<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="2words/">2words/</a></td><td align="right">'.INTF_DATE.'  </td><td align="right">  - </td><td>&nbsp;</td></tr>'."\n";
495                 print $indexfile '<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="coin/">coin/</a></td><td align="right">'.COIN_DATE.'  </td><td align="right">  - </td><td> Coincidence </td></tr>'."\n";
496                 print $indexfile '<tr><th colspan="5"><hr></th></tr>'."\n";
497                 print $indexfile '</table>'."\n";
498                 print $indexfile '<address>Apache/2.2.22 (Debian) Server at '.WEBSITE.' Port 80</address>'."\n";
499                 print $indexfile '</body></html>'."\n";
500         }
501         else {
502                 my %framedata;
503                 my %nextframedata;
504                 my %default;
505                 
506                 %framedata = readdatafile(DATA_PATH.0);
507                 %nextframedata = readdatafile(DATA_PATH.1);
508                 %default=readdatafile(DATA_DEFAULT_PATH);
509                 
510                 # if($mode == 16 && $pause) {
511                         # $framedata{'ongtime'} = $time;
512                         # writedatafile(DATA_PATH.0,%framedata);
513                 # }
514                 
515                 foreach my $ind (keys %default) {
516                         unless(defined($framedata{$ind})){
517                                 $framedata{$ind}=$default{$ind};
518                         }
519                         unless(defined($nextframedata{$ind})){
520                                 $nextframedata{$ind}=$default{$ind};
521                         }
522                 }
523                 
524                 
525                 print $indexfile '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">'."\n";
526                 print $indexfile '<html lang="en"><head>'."\n";
527                 print $indexfile '<title>';
528                 if($mode == 8 || $mode == 4) {
529                         print $indexfile 'Index of';
530                 }
531                 elsif($mode == 16) {
532                         print $indexfile entityencode($settings{'story'});
533                         if($pause) {
534                                 print $indexfile ' &bull; '.WEBSITE_NAME;
535                         }
536                 }
537                 else {
538                         print $indexfile 'Index of '.$indexof;
539                 }
540                 print $indexfile '</title>'."\n";
541                 print $indexfile '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">'."\n";
542                 print $indexfile '<link rel="icon" type="image/png" href="'.FAVICON_PATH.'">'."\n";
543                 print $indexfile '<link rel="stylesheet" href="'.CGI_CSS_PATH.'">'."\n";
544                 print $indexfile '</head><body>'."\n";
545                 print $indexfile '<a href="/"><img id="botmlogo" src="'.CGI_LOGO_PATH.'" alt="'.WEBSITE.'"></a>'."\n";
546                 print $indexfile '<div id="all">'."\n";
547                 
548                 print $indexfile '<div id="inst" class="ins">'."\n";
549                 
550                 print $indexfile '<div id="title">'."\n";
551                 print $indexfile '<H1 id="titletext">';
552                 if($mode == 8 || $mode == 4) {
553                         print $indexfile 'Index of';
554                 }
555                 elsif($mode == 16) {
556                         print $indexfile entityencode($settings{'story'});
557                 }
558                 else {
559                         print $indexfile 'Index of '.$indexof;
560                 }
561                 print $indexfile '</H1>'."\n";
562                 print $indexfile '</div>'."\n";
563                 
564                 print $indexfile '</div><div id="framespace">'."\n";
565                 print $indexfile '<img src="'.CGI_PATH;
566                 if($mode == 8) {
567                         print $indexfile 'intf-ll.gif'
568                 }
569                 elsif($mode == 4) {
570                         print $indexfile 'intf-pp.gif'
571                 }
572                 elsif($mode == 16) {
573                         if($pause) {
574                                 print $indexfile sprintf($settings{'frame'},0,$framedata{'ext'}).'" title="'.entityencode($framedata{'title'});
575                         }
576                         else {
577                                 print $indexfile 'intf-tr.gif'
578                         }
579                 }
580                 else {
581                         print $indexfile 'intf-kw.gif'
582                 }
583                 print $indexfile '" alt="0" id="frame">'."\n";
584                 
585                 print $indexfile '</div><div id="insb" class="ins">'."\n";
586                 print $indexfile '<div id="undertext">'."\n";
587                 if($mode == 8 || $mode == 4) {
588                         print $indexfile '<img src="/icons/back.gif" alt="[DIR]"> <a href="/">Parent Directory</a><br><img src="/icons/folder.gif" alt="[DIR]"> <a href="#">yyyyb/</a>'."\n";
589                 }
590                 elsif ($mode == 16) {
591                         if($pause) {
592                                 print $indexfile bb2ht($framedata{'content'})."\n";
593                         }
594                         else {
595                                 print $indexfile "...\n";
596                         }
597                 }
598                 else {
599                         print $indexfile '<img src="/icons/back.gif" alt="[DIR]"> <a href="/">Parent Directory</a><br>'."\n";
600                         print $indexfile '<img src="/icons/folder.gif" alt="[DIR]"> <a href="2words/">2words/</a> '.INTF_DATE.' - <br>'."\n";
601                         print $indexfile '<img src="/icons/folder.gif" alt="[DIR]"> <a href="coin/">coin/</a> '.COIN_DATE.' - '.entityencode($coin{'server'})."\n";
602                 }
603                 print $indexfile '</div>'."\n";
604                 
605                 print $indexfile '<div id="command">'."\n";
606                 if ($mode == 8) {
607                         print $indexfile '[<span class="br">EE</span>:<span class="br">EE</span>:<span class="br">EE</span>]'."\n";
608                 }
609                 elsif ($mode == 4) {
610                         print $indexfile '[<span class="ni">EE</span>:<span class="ni">EE</span>:<span class="ni">EE</span>]'."\n";
611                 }
612                 elsif ($mode == 16) {
613                         if($pause) {
614                                 print $indexfile '[<span class="br">00</span>:<span class="br">00</span>:<span class="br">00</span>]<br>'."\n";
615                                 print $indexfile '&gt;<a href="'.CGI_VIEWER_PATH.'/1">'.entityencode($nextframedata{'title'}).'</a>'."\n";
616                         }
617                         else {
618                                 print $indexfile '[<span class="ni">--</span>:<span class="ni">--</span>:<span class="ni">--</span>]<br>'."\n";
619                                 print $indexfile '&gt;...<span class="inp">_</span>'."\n";
620                         }
621                 }
622                 else {
623                 }
624                 print $indexfile '</div>'."\n";
625                 
626                 print $indexfile '</div>'."\n";
627                 
628                 print $indexfile '</div>'."\n";
629                 print $indexfile '<a href="/" class="cz">'.WEBSITE.'</a>'."\n";
630                 
631                 print $indexfile '</body></html>'."\n";
632         }
633         
634         unless (ref($indexpath)) {
635                 close ($indexfile);
636         }
637         else {
638                 truncate ($indexfile , tell($indexfile));
639         }
640         
641         return 1;
642 }