/[suikacvs]/test/suika-accounts/edit.cgi
Suika

Diff of /test/suika-accounts/edit.cgi

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by wakaba, Wed Oct 29 16:27:15 2008 UTC revision 1.3 by wakaba, Thu Oct 30 11:57:07 2008 UTC
# Line 8  use CGI::Carp qw[fatalsToBrowser]; Line 8  use CGI::Carp qw[fatalsToBrowser];
8  require Message::CGI::Carp;  require Message::CGI::Carp;
9    
10  require 'users.pl';  require 'users.pl';
11    require 'texts.pl';
12    
13  require Message::CGI::HTTP;  require Message::CGI::HTTP;
14  require Encode;  require Encode;
# Line 16  $cgi->{decoder}->{'#default'} = sub { Line 17  $cgi->{decoder}->{'#default'} = sub {
17    return Encode::decode ('utf-8', $_[1]);    return Encode::decode ('utf-8', $_[1]);
18  };  };
19    
20    our $Lang = 'ja'
21        if $cgi->get_meta_variable ('HTTP_ACCEPT_LANGUAGE') =~ /\bja\b/; ## TODO: ...
22    
23  require Message::DOM::DOMImplementation;  require Message::DOM::DOMImplementation;
24  my $dom = Message::DOM::DOMImplementation->new;  my $dom = Message::DOM::DOMImplementation->new;
25    
# Line 39  if (@path == 3 and Line 43  if (@path == 3 and
43                
44        my $e_user_id = htescape ($user_id);        my $e_user_id = htescape ($user_id);
45                
46        print qq[Content-Type: text/html; charset=utf-8        print q[Content-Type: text/html; charset=utf-8
47    
48  <!DOCTYPE HTML>  <!DOCTYPE HTML>
49  <html lang=en>  <html lang=en>
50  <title>User $e_user_id</title>  <title>];
51          print_text ('User %s', sub { print $e_user_id });
52          print q[</title>
53  <link rel=stylesheet href="/www/style/html/xhtml">  <link rel=stylesheet href="/www/style/html/xhtml">
54  <h1>User $e_user_id</h1>  <h1>];
55  ];        print_text ('User %s', sub { print $e_user_id });
56          print q[</h1>];
57    
58        my @joined;        my @joined;
59        my @requested;        my @requested;
# Line 73  if (@path == 3 and Line 80  if (@path == 3 and
80          }          }
81        }        }
82    
83        print qq[<section id=groups><h2>Groups</h2>];        print q[<section id=groups><h2>];
84          print_text ('Groups');
85          print q[</h2>];
86                
87        if (@joined) {        if (@joined) {
88          print_list_section          print_list_section
# Line 87  if (@path == 3 and Line 96  if (@path == 3 and
96                 print q[<a href="../../groups/].htescape ($group_id) . '/';                 print q[<a href="../../groups/].htescape ($group_id) . '/';
97                 print q[">] . htescape ($group_id), q[</a> ];                 print q[">] . htescape ($group_id), q[</a> ];
98                 print q[<input type=hidden name=action value=leave>];                 print q[<input type=hidden name=action value=leave>];
99                 print q[<input type=submit value="Leave this group"></form>];                 print q[<input type=submit value="];
100                   print_text ('Leave this group');
101                   print q["></form>];
102               });               });
103        }        }
104                
# Line 103  if (@path == 3 and Line 114  if (@path == 3 and
114                 print q[<a href="../../groups/].htescape ($group_id) . '/';                 print q[<a href="../../groups/].htescape ($group_id) . '/';
115                 print q[">] . htescape ($group_id), q[</a> ];                 print q[">] . htescape ($group_id), q[</a> ];
116                 print q[<input type=hidden name=action value=leave>];                 print q[<input type=hidden name=action value=leave>];
117                 print q[<input type=submit value="Cancel the request"></form>];                 print q[<input type=submit value="];
118                   print_text ('Cancel the request');
119                   print q["></form>];
120               });               });
121        }        }
122                
# Line 119  if (@path == 3 and Line 132  if (@path == 3 and
132                 print q[<a href="../../groups/].htescape ($group_id) . '/';                 print q[<a href="../../groups/].htescape ($group_id) . '/';
133                 print q[">] . htescape ($group_id), q[</a> ];                 print q[">] . htescape ($group_id), q[</a> ];
134                 print q[<input type=hidden name=action value=join>];                 print q[<input type=hidden name=action value=join>];
135                 print q[<input type=submit value="Join this group"></form>];                 print q[<input type=submit value="];
136                   print_text ('Join this group');
137                   print q["></form>];
138               });               });
139        }        }
140                
# Line 135  if (@path == 3 and Line 150  if (@path == 3 and
150                 print q[<a href="../../groups/].htescape ($group_id) . '/';                 print q[<a href="../../groups/].htescape ($group_id) . '/';
151                 print q[">] . htescape ($group_id), q[</a>];                 print q[">] . htescape ($group_id), q[</a>];
152                 print q[<input type=hidden name=action value=join>];                 print q[<input type=hidden name=action value=join>];
153                 print q[<input type=submit value="Join this group"></form>];                 print q[<input type=submit value="];
154                   print_text ('Join this group');
155                   print q["></form>];
156               });               });
157        }        }
158                
# Line 151  if (@path == 3 and Line 168  if (@path == 3 and
168                 print q[<a href="../../groups/].htescape ($group_id) . '/';                 print q[<a href="../../groups/].htescape ($group_id) . '/';
169                 print q[">] . htescape ($group_id), q[</a> ];                 print q[">] . htescape ($group_id), q[</a> ];
170                 print q[<input type=hidden name=action value=join>];                 print q[<input type=hidden name=action value=join>];
171                 print q[<input type=submit value="Join this group"></form>];                 print q[<input type=submit value="];
172                   print_text ('Join this group');
173                   print q["></form>];
174               });               });
175        }        }
176                
177        print q[</section><section id=props><h2>Properties</h2>        print q[</section><section id=props><h2>];
178          print_text ('Properties');
179  <p><em>Though these properties are only accessible to administrators,        print q[</h2><p><em>];
180  you are advised not to expose any confidential data.</em>];        print_text (q[Don't expose any confidential data.]);
181          print q[</em>];
182    
183        print_prop_list ($ac, $user_prop,        print_prop_list ($ac, $user_prop,
184          {          {
# Line 178  you are advised not to expose any confid Line 198  you are advised not to expose any confid
198          },          },
199        );        );
200    
201        print qq[</section><section id=password>        print qq[</section><section id=password><h2>];
202  <h2>Password</h2>        print_text ('Password');
203          print q[</h2>
204    
205  <form action=password method=post accept-charset=utf-8>  <form action=password method=post accept-charset=utf-8>
206    
207  <p>You can change the password.  <p>];
208          print_text ('You can change the password.');
 <p><strong>New password</strong>: <input type=password name=user-pass  
 size=10 required pattern=".{4,}" title="Type 4 characters at minimum">  
209    
210  <p><strong>New password</strong> (type again): <input type=password        print q[<p><strong>];
211          print_text ('New password');
212          print q[</strong>: <input type=password name=user-pass
213    size=10 required pattern=".{4,}"> (];
214          print_text ('Type 4 characters at minimum');
215          print q[) <p><strong>];
216          print_text ('New password');
217          print q[</strong> (];
218          print_text ('type again');
219          print q[): <input type=password
220  name=user-pass2 size=10 required pattern=".{4,}">  name=user-pass2 size=10 required pattern=".{4,}">
221    
222  <p><input type=submit value=Change>  <p><input type=submit value="];
223         print_text ('Change');
224         print q[">
225    
226  </form>  </form>
227  </section>  </section>
228    
229  <section id=disable-account><h2>Disable account</h2>  <section id=disable-account><h2>];
230         print_text ('Disable account');
231         print q[</h2>
232    
233  <form action=disabled method=post accept-charset=utf-8>  <form action=disabled method=post accept-charset=utf-8>
234    
235  <p><label><input type=checkbox name=action value=enable  <p><label><input type=checkbox name=action value=enable ];
236  @{[$user_prop->{disabled} ? '' : 'checked']}> Enable this      print 'checked' unless $user_prop->{disabled};
237  account.</label>      print q[> ];
238        print_text ('Enable this account');
239        print q[</label>
240    
241    <p><strong>];
242        print_text ('Caution!');
243        print q[</strong> ];
244        print_text ('Once you disable your own account, you cannot enable your account by yourself.');
245    
246  <p><strong>Caution!</strong> Once you disable your own account, you      print q[<p><input type=submit value="];
247  cannot enable your account by yourself.      print_text ('Change');
248      
249  <p><input type=submit value=Change>    print q["></form></section>];
   
 </form>  
   
 </section>];  
250    
251        exit;        exit;
252      }      }
# Line 257  cannot enable your account by yourself. Line 292  cannot enable your account by yourself.
292              }              }
293            } else {            } else {
294              my $e_group_id = htescape ($group_id);              my $e_group_id = htescape ($group_id);
295              print qq[Content-Type: text/html; charset=utf-8              print q[Content-Type: text/html; charset=utf-8
296    
297  <!DOCTYPE HTML>  <!DOCTYPE HTML>
298  <html lang=en>  <html lang=en>
299  <title>Joining the group $e_group_id</title>  <title>];
300                print_text ('Joining the group %s', sub { print $e_group_id });
301                print q[</title>
302  <link rel=stylesheet href="/www/style/html/xhtml">  <link rel=stylesheet href="/www/style/html/xhtml">
303  <h1>Joining the group $e_group_id</h1>  <h1>];
304                print_text ('Joining the group %s', sub { print $e_group_id });
305                print q[</h1>
306    
307  <dl>  <dl>
308  <dt>Description  <dt>];
309  <dd>@{[$group_prop->{desc}]}              print_text ('Description');
310                print qq[<dd>@{[$group_prop->{desc}]}
311  </dl>  </dl>
312    
313  <form action="@{[htescape ($cgi->request_uri)]}" accept-charset=utf-8 method=post>  <form action="@{[htescape ($cgi->request_uri)]}" accept-charset=utf-8 method=post>
314  <input type=hidden name=action value=join>  <input type=hidden name=action value=join>
315    
316  <p>Do you really want to join this group?  <p>];
317  <input type=submit name=agreed value=yes>              print_text ('Do you really want to join this group?');
318  <input type=button value=no onclick="history.back ()">              print q[ <input type=submit name=agreed value="];
319                print_text ('Yes');
320  </form>];              print q["> <input type=button value="];
321                print_text ('No');
322                print q[" onclick="history.back ()"></form>];
323              exit;              exit;
324            }            }
325          } elsif ($action eq 'leave') {          } elsif ($action eq 'leave') {
# Line 393  cannot enable your account by yourself. Line 435  cannot enable your account by yourself.
435                
436        my $e_group_id = htescape ($group_id);        my $e_group_id = htescape ($group_id);
437                
438        print qq[Content-Type: text/html; charset=utf-8        print q[Content-Type: text/html; charset=utf-8
439    
440  <!DOCTYPE HTML>  <!DOCTYPE HTML>
441  <html lang=en>  <html lang=en>
442  <title>Group $e_group_id</title>  <title>];
443          print_text ('Group %s', sub { print $e_group_id });
444          print q[</title>
445  <link rel=stylesheet href="/www/style/html/xhtml">  <link rel=stylesheet href="/www/style/html/xhtml">
446  <h1>Group $e_group_id</h1>];  <h1>];
447                print_text ('Group %s', sub { print $e_group_id });
448        print q[<section id=props><h2>Properties</h2>];        print q[</h1>];
449          
450          print q[<section id=props><h2>];
451          print_text ('Properties');
452          print q[</h2>];
453    
454        print_prop_list ($ac, $group_prop,        print_prop_list ($ac, $group_prop,
455             {             {
# Line 417  cannot enable your account by yourself. Line 465  cannot enable your account by yourself.
465             },             },
466            );            );
467    
468        print q[</section><section id=members><h2>Members</h2>];        print q[</section><section id=members><h2>];
469          print_text ('Members');
470          print q[</h2>];
471    
472        if ($ac->{read_group_member_list}) {        if ($ac->{read_group_member_list}) {
473          my @members;          my @members;
# Line 443  cannot enable your account by yourself. Line 493  cannot enable your account by yourself.
493                 print_item => sub {                 print_item => sub {
494                   my $user_id = shift;                   my $user_id = shift;
495                   print q[<form action="user.] . htescape ($user_id);                   print q[<form action="user.] . htescape ($user_id);
496                 print q[" accept-charset=utf-8 method=post>];                   print q[" accept-charset=utf-8 method=post>];
497                   print qq[<a href="../../users/@{[htescape ($user_id)]}/">];                   print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
498                   print '' . htescape ($user_id) . q[</a> ];                   print '' . htescape ($user_id) . q[</a> ];
499                   print q[<input type=hidden name=action value=unapprove>];                   print q[<input type=hidden name=action value=unapprove>];
500                   print q[<input type=submit value="Kick"></form>];                   print q[<input type=submit value="];
501                     print_text ('Kick');
502                     print q["></form>];
503                 });                 });
504          }          }
505                    
# Line 463  cannot enable your account by yourself. Line 515  cannot enable your account by yourself.
515                   print qq[<a href="../../users/@{[htescape ($user_id)]}/">];                   print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
516                   print '' . htescape ($user_id) . q[</a> ];                   print '' . htescape ($user_id) . q[</a> ];
517                   print q[<input type=hidden name=action value=approve>];                   print q[<input type=hidden name=action value=approve>];
518                   print q[<input type=submit value=Approve></form>];                   print q[<input type=submit value="];
519                     print_text ('Approve');
520                     print q["></form>];
521                 });                 });
522          }          }
523                    
# Line 479  cannot enable your account by yourself. Line 533  cannot enable your account by yourself.
533                   print qq[<a href="../../users/@{[htescape ($user_id)]}/">];                   print qq[<a href="../../users/@{[htescape ($user_id)]}/">];
534                   print '' . htescape ($user_id), q[</a> ];                   print '' . htescape ($user_id), q[</a> ];
535                   print q[<input type=hidden name=action value=unapprove>];                   print q[<input type=hidden name=action value=unapprove>];
536                   print q[<input type=submit value="Cancel invitation"></form>];                   print q[<input type=submit value="];
537                     print_text ('Cancel invitation');
538                     print q["></form>];
539                 });                 });
540          }          }
541        }        }
542    
543        my $join_condition = $group_prop->{join_condition};        my $join_condition = $group_prop->{join_condition};
544        my $disabled = $ac->{write} ? '' : 'disabled';        my $disabled = $ac->{write} ? '' : 'disabled';
545        print qq[<section id=member-approval>        print qq[<section id=member-approval><h3>];
546  <h3>Member approval policy</h3>        print_text ('Member approval policy');
547          print qq[</h3>
548    
549  <form action=join-condition method=post accept-charset=utf-8>  <form action=join-condition method=post accept-charset=utf-8>
550    
551  <p><label><input type=radio name=condition value=invitation $disabled  <p><label><input type=radio name=condition value=invitation $disabled
552  @{[$join_condition->{invitation} ? 'checked' : '']}> A user who is  @{[$join_condition->{invitation} ? 'checked' : '']}> ];
553  invited by an administrator of the group can join the group.</label>        print_text ('A user who is invited by an administrator of the group can join the group.');
554          print qq[</label>
555    
556  <p><label><input type=radio name=condition value=approval $disabled  <p><label><input type=radio name=condition value=approval $disabled
557  @{[(not $join_condition->{invitation} and $join_condition->{approval})  @{[(not $join_condition->{invitation} and $join_condition->{approval})
558  ?  'checked' : '']}> A user who is invited or approved by an  ?  'checked' : '']}> ];
559  administrator of the group can join the group.</label>         print_text ('A user who is invited or approved by an administrator of the group can join the group.');
560           print qq[</label>
561    
562  <p><label><input type=radio name=condition value=anyone $disabled  <p><label><input type=radio name=condition value=anyone $disabled
563  @{[(not $join_condition->{invitation} and not  @{[(not $join_condition->{invitation} and not
564  $join_condition->{approval}) ?  'checked' : '']}> Any user can join  $join_condition->{approval}) ?  'checked' : '']}> ];
565  the group.</label>         print_text ('Any user can join the group.');
566           print q[</label>];
567  @{[$disabled ? '' : '<p><input type=submit value=Change>']}         unless ($disabled) {
568             print q[<p><input type=submit value="];
569  </form>           print_text ('Change');
570             print q[">];
571  </section>];         }
572           print q[</form></section>];
573    
574        if ($ac->{write}) {        if ($ac->{write}) {
575          print q[<section id=member-invitation>          print q[<section id=member-invitation><h3>];
576  <h3>Invite a user</h3>          print_text ('Invite a user');
577            print q[</h3>
578    
579  <form action=invite-user accept-charset=utf-8 method=post>  <form action=invite-user accept-charset=utf-8 method=post>
580    
581  <p><strong>User id</strong>: <input type=text name=user-id  <p><strong>];
582            print_text ('User id');
583            print q[</strong>: <input type=text name=user-id
584  maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}">  maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}">
585    
586  <p><input type=submit value=Invite>  <p><input type=submit value="];
587            print_text ('Invite');
588  </form>          print q["></form></section>];
   
 </section>];  
589        }        }
590    
591        print q[</section>];        print q[</section>];
# Line 657  maxlength=20 size=10 required pattern="[ Line 718  maxlength=20 size=10 required pattern="[
718      my $group_id = $cgi->get_parameter ('group-id');      my $group_id = $cgi->get_parameter ('group-id');
719    
720      if ($group_id !~ /\A[0-9a-z-]{4,20}\z/) {      if ($group_id !~ /\A[0-9a-z-]{4,20}\z/) {
721        print_error (400, qq[Group id "$group_id" is invalid; use characters [0-9a-z-]{4,20}]);        print_error (400,
722                       q[Group id %s is invalid; use characters [0-9a-z-]{4,20}],
723                       $group_id);
724        exit;        exit;
725      }      }
726            
727      if (get_group_prop ($group_id)) {      if (get_group_prop ($group_id)) {
728        print_error (400, qq[Group id "$group_id" is already used]);        print_error (400, q[Group id %s is already used], $group_id);
729        exit;        exit;
730      }      }
731    
# Line 679  Content-Type: text/html; charset=utf-8 Line 742  Content-Type: text/html; charset=utf-8
742    
743  <!DOCTYPE HTML>  <!DOCTYPE HTML>
744  <html lang=en>  <html lang=en>
745  <title>Group "@{[htescape ($group_id)]}" registered</title>  <title>];
746        print_text ('Group %s registered', sub { print '', htescape ($group_id) });
747        print q[</title>
748  <link rel=stylesheet href="/www/style/html/xhtml">  <link rel=stylesheet href="/www/style/html/xhtml">
749  <h1>Group "@{[htescape ($group_id)]}" registered</h1>  <h1>];
750  <p>The new group is created successfully.      print_text ('Group %s registered', sub { print '', htescape ($group_id) });
751  <p>See <a href="@{[htescape ($group_url)]}">the group information page</a>.];      print q[</h1><p>];
752        print_text ('The new group is created successfully.');
753        print q[<p>];
754        print_text ('See %s.', sub {
755          print qq[<a href="@{[htescape ($group_url)]}">];
756          print_text ('the group information page');
757          print qq[</a>];
758        });
759      exit;      exit;
760    } else {    } else {
761      binmode STDOUT, ":encoding(utf-8)";      binmode STDOUT, ":encoding(utf-8)";
762      print qq[Content-Type: text/html; charset=utf-8      print q[Content-Type: text/html; charset=utf-8
763    
764  <!DOCTYPE HTML>  <!DOCTYPE HTML>
765  <html lang=en>  <html lang=en>
766  <title>Create a new group</title>  <title>];
767        print_text ('Create a new group');
768        print q[</title>
769  <link rel=stylesheet href="/www/style/html/xhtml">  <link rel=stylesheet href="/www/style/html/xhtml">
770  <h1>Create a new group</h1>  <h1>];
771        print_text ('Create a new group');
772        print q[</h1>
773    
774  <form action=new-group accept-charset=utf-8 method=post>  <form action=new-group accept-charset=utf-8 method=post>
775    
776  <p><strong>Group id</strong>: <input type=text name=group-id  <p><strong>];
777  maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}"      print_text ('Group id');
778  title="Use a string of characters 'a'..'z', '0'..'9', and '-' with length 4..10 (inclusive)">      print q[</strong>: <input type=text name=group-id
779    maxlength=20 size=10 required pattern="[0-9a-z-]{4,20}"> (];
780  <p><input type=submit value=Create>      print_text ('Use [0-9a-z-]{4,20}.');
781        print q[) <p><input type=submit value="];
782  </form>];      print_text ('Create');
783        print q["></form>];
784      exit;      exit;
785    }    }
786  } elsif (@path == 1 and $path[0] eq '') {  } elsif (@path == 1 and $path[0] eq '') {
# Line 725  sub print_list_section (%) { Line 802  sub print_list_section (%) {
802    $opt{level} ||= 3;    $opt{level} ||= 3;
803        
804    print q[<section id="] . htescape ($opt{id});    print q[<section id="] . htescape ($opt{id});
805    print q["><h] . $opt{level} . q[>] . htescape ($opt{title});    print q["><h] . $opt{level} . q[>];
806      print_text ($opt{title});
807    print q[</h] . $opt{level} . q[><ul>];    print q[</h] . $opt{level} . q[><ul>];
808    for my $item (sort {$a cmp $b} @{$opt{items}}) {    for my $item (sort {$a cmp $b} @{$opt{items}}) {
809      print q[<li>];      print q[<li>];
# Line 740  sub print_prop_list ($$@) { Line 818  sub print_prop_list ($$@) {
818    
819    for my $prop (@_) {    for my $prop (@_) {
820      if ($prop->{public}) {      if ($prop->{public}) {
821        print q[<p><strong>], htescape ($prop->{label}), q[</strong>: ];        print q[<p><strong>];
822          print_text ($prop->{label});
823          print q[</strong>: ];
824        print $prop_hash->{$prop->{name}};        print $prop_hash->{$prop->{name}};
825      }      }
826            
# Line 748  sub print_prop_list ($$@) { Line 828  sub print_prop_list ($$@) {
828        print q[<form action="prop" accept-charset=utf-8 method=post>];        print q[<form action="prop" accept-charset=utf-8 method=post>];
829        print q[<input type=hidden name=name value="], htescape ($prop->{name}), q[">];        print q[<input type=hidden name=name value="], htescape ($prop->{name}), q[">];
830        if ($prop->{field_type} eq 'textarea') {        if ($prop->{field_type} eq 'textarea') {
831          print q[<p><label><strong>], htescape ($prop->{label});          print q[<p><label><strong>];
832            print_text ($prop->{label});
833          print q[</strong>: <br><textarea name="value"];          print q[</strong>: <br><textarea name="value"];
834          print q[>], htescape ($prop_hash->{$prop->{name}} // '');          print q[>], htescape ($prop_hash->{$prop->{name}} // '');
835          print q[</textarea></label>];          print q[</textarea></label>];
836          print q[<p><input type=submit value=Save>];          print q[<p><input type=submit value="];
837            print_text ('Save');
838            print q[">];
839        } else {        } else {
840          print q[<p><label><strong>], htescape ($prop->{label});          print q[<p><label><strong>];
841            print_text ($prop->{label});
842          print q[</strong>: <input type="] . $prop->{field_type};          print q[</strong>: <input type="] . $prop->{field_type};
843          print q[" name="value" ];          print q[" name="value" ];
844          print q[value="], htescape ($prop_hash->{$prop->{name}} // '');          print q[value="], htescape ($prop_hash->{$prop->{name}} // '');
845          print q["></label> ];          print q["></label> ];
846          print q[<input type=submit value=Save>];          print q[<input type=submit value="];
847            print_text ('Save');
848            print q[">];
849        }        }
850        print q[</form>];        print q[</form>];
851      }      }
# Line 825  sub check_access_right (%) { Line 911  sub check_access_right (%) {
911  sub forbidden () {  sub forbidden () {
912    my $user = $cgi->remote_user;    my $user = $cgi->remote_user;
913    if (defined $user) {    if (defined $user) {
914      print_error (403, q[Forbidden (you've logged in as ] . $user . ')');      print_error (403, q[Forbidden (you've logged in as %s)], $user);
915    } else {    } else {
916      print_error (403, 'Forbidden');      print_error (403, 'Forbidden');
917    }    }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24