<?_code

 my ($ret, $sth);

 my $DEF_ROW = 30;
 my $DEF_COL = 80;

 my $remote = LJ::get_remote();

 my %files = ();  # keys: files remote user has access to, value: 1
 my $INC_DIR = $LJ::BML_INC_DIR_ADMIN || $LJ::BML_INC_DIR || "$LJ::HTDOCS/inc";

 unless (LJ::remote_has_priv($remote, "fileedit", \%files)) {
     return "You don't have access to edit any files, or you're not logged in.";
 }

 my $valid_filename = sub 
 {
     my $filename = shift;
     return ($filename =~ /^[a-zA-Z0-9-\_]{1,80}$/);
 };

 my $save_file = sub 
 {
     my ($filename, $content) = @_;
     return 0 unless $valid_filename->($filename);

     if ($LJ::FILEEDIT_VIA_DB || $LJ::FILEEDIT_VIA_DB{$filename}) {
         my $dbh = LJ::get_db_writer();
         $dbh->do("REPLACE INTO includetext (incname, inctext, updatetime) ".
                   "VALUES (?, ?, UNIX_TIMESTAMP())", undef, $filename, $content);
         return 0 if $dbh->err;
         LJ::MemCache::set("includefile:$filename", $content);
         return 1;
     }

     open (FILE, ">$INC_DIR/$filename") or return 0;
     print FILE $content;
     close FILE;
     return 1;
 };

 my $load_file = sub
 {
     my ($filename) = @_;
     return undef unless $valid_filename->($filename);

     my $contents;
     if ($LJ::FILEEDIT_VIA_DB || $LJ::FILEEDIT_VIA_DB{$filename}) {
         my $dbh = LJ::get_db_writer();
         $contents = $dbh->selectrow_array("SELECT inctext FROM includetext WHERE incname=?", undef, $filename);
         return $contents if defined $contents;
     }

     open (FILE, "$INC_DIR/$filename") or return undef;
     while (<FILE>) { $contents .= $_; }
     close FILE;
     return $contents;
 };

 if ($files{'*'}) 
 {
     # if user has access to edit all files, find what those files are!
     delete $files{'*'};
     opendir (DIR, $INC_DIR);
     while (my $file = readdir(DIR)) {
         $files{$file} = 1;
     }
     closedir (DIR);
 }

 ## get rid of files that don't match our safe pattern
 {
     my @del;
     foreach my $k (keys %files) {
         push @del, $k
             unless $valid_filename->($k);
     }
     foreach my $k (@del) { delete $files{$k}; }
 }

 my $mode = $FORM{'mode'};
 unless ($mode) {
     $mode = $FORM{'file'} ? "edit" : "pick";
 }

 if ($mode eq "pick")
 {
     $ret .= "<FORM METHOD=GET>\n";
     $ret .= "Pick file to edit: <SELECT NAME=\"file\">";
     foreach my $file (sort keys %files) {
         $ret .= "<OPTION VALUE=\"$file\">$file\n";
     }
     $ret .= "</SELECT> <INPUT TYPE=SUBMIT VALUE=\"load...\"><BR>";
     $ret .= "Wordwrap? <INPUT TYPE=CHECKBOX VALUE=1 NAME=w> ";
     $ret .= "Rows: <INPUT SIZE=3 NAME=r VALUE=$DEF_ROW> ";
     $ret .= "Cols: <INPUT SIZE=3 NAME=c VALUE=$DEF_COL> ";
     $ret .= "</FORM>";
     return $ret;
 }

 my $file = $FORM{'file'};
 unless ($files{$file}) {
     return "<B>ERROR!</B> you don't have access to this document.";
 }

 if ($mode eq "edit") 
 {
     $ret .= "<B>Editing:</B> <tt>$file</tt><P>";
     my $contents = $load_file->($file);

     return "<B>Error:</B> Couldn't open file" 
         unless defined $contents;

     my $r = ($FORM{'r'}+0) || $DEF_ROW;
     my $c = ($FORM{'c'}+0) || $DEF_COL;
     my $wrap = $FORM{'w'} ? "SOFT" : "OFF";

     $ret .= "<FORM METHOD=POST>\n";
     $ret .= "<INPUT TYPE=HIDDEN NAME=mode VALUE=\"save\">";
     $ret .= "<INPUT TYPE=HIDDEN NAME=file VALUE=\"$file\">";
     $ret .= "<TEXTAREA ROWS=$r COLS=$c WRAP=$wrap NAME=contents>";
     $ret .= BML::eall($contents);
     $ret .= "</TEXTAREA><P><INPUT TYPE=SUBMIT VALUE=\"Save\"> (no undo.. are you sure?)";
     $ret .= "</FORM>\n";
     return $ret;
 }

 if ($mode eq "save") 
 {
     unless (LJ::did_post()) {
         return "<b>Error:</b> requires post";
     }

     $ret .= "<B>Saving:</B> <tt>$file</tt><p>";
     if ($save_file->($file, $FORM{'contents'})) {
         $ret .= "saved.";
     } else {
         $ret .= "<b>Error saving</b>";
     }
     return $ret;
 }

 return "unknown mode";

_code?><?_c <LJDEP>
lib: cgi-bin/ljlib.pl
form: htdocs/admin/fileedit/index.bml
post: htdocs/admin/fileedit/index.bml
</LJDEP> _c?>
