#!/usr/bin/perl -w

use Fcntl ':flock',':seek',':DEFAULT';
use POSIX;
&determine_o_nofollow();


@user=getpwuid($<);
$homedir=$user[7];
$user=$user[0];

&choose_addendat_cfg_path();
&choose_html_dir();
&choose_cgi_dir();
&choose_addendat_cfg();
open(FILE,"+<$addendat_cfg_path") || &fatalerror("Cannot open $addendat_cfg_path");
flock(FILE,LOCK_EX) || &fatalerror("Cannot lock config file.");
$oldslash=$/;
undef($/);
$file=<FILE>;
$/=$oldslash;
$pwd=`pwd`;
chop($pwd);
$blogfile="$htmldir/blog.html";
if (-f $blogfile) {
  &set_config($file,'blogfile',"$blogfile");
} else {
  &fatalerror("Cannot find blog.html");
}
&set_blogurl();
&set_access_code();
if (defined($using_comments)) {
  &set_comment_options();
}
&set_blog_title();
print "Config set:\n";
print "Blog URL: $url\n";
print "Blog filename: $blogfile\n";
seek(FILE,0,SEEK_SET);
truncate(FILE,0);
print FILE $file;
flock(FILE,LOCK_UN);
close(FILE);

print "Setting permissions.\n";
if (chmod(0644, $addendat_cfg_path, "$htmldir/add.html")) {
  print "addendat.cfg: World readable, writable by you.\n";
  print "add.cfg: World readable, writable by you.\n";
} else {
  print "Error setting permissions on addendat.cfg\n";
}
if (chmod(0666, "$htmldir/blog.html")) {
  print "blog.html: World readable, world writable.\n";
} else {
  print "Error setting permissions on blog.html\n";
}
if (chmod(0755, "$cgidir/addendat.cgi")) {
  print "addendat.cgi: World readable, world runnable, writable by you.\n";
} else {
  print "Error setting permissions on addendat.cgi\n";
}

open(FILE,"+<$cgidir/addendat.cgi") || &fatalerror("Cannot open $cgidir/addendat.cgi.");
flock(FILE,LOCK_EX)||&fatalerror("Cannot lock $cgidir/addendat.cgi");
undef($/);
$file=<FILE>;
$/=$oldslash;
$file=~s/\$configfile=\'(.*?)\';\n/\$configfile=\'$addendat_cfg_path\';\n/s;

seek(FILE,0,SEEK_SET);
print FILE $file;
truncate(FILE,tell(FILE));
flock(FILE,LOCK_UN);
close(FILE);
&install_blog_command();

exit;

sub install_blog_command()
{
  local *BLOG;
  open(BLOG,"<blog");
  local $/;
  $blog=<BLOG>;
  close(BLOG);
  mkdir("$homedir/bin",0700);
  $blog=~s/^\$addendat='(.*?)';$/\$addendat='$cgidir\/addendat.cgi';/m;
  $blog=~s/^\$accesscode=(.*?)';$/\$accesscode='$acccode';/m;
  if (open(BLOG,">$homedir/bin/blog")) {
    print BLOG $blog;
    close(BLOG);
    chmod(0755,"$homedir/bin/blog");
    print "Command-line blogging tool installed in $homedir/bin/blog\n";
  } else {
    print STDERR "Can't write $homedir/bin/blog.\n";
  }
}

sub set_blog_title()
{
  local $notdone=1;
  while ($notdone) {
    print "Enter your blog's title: ";
    $blogtitle=<STDIN>;
    $blogtitle=~s/[\r\n]//gs;
    $notdone=0;
    if ($blogtitle eq '') {
      print "Are you sure you want a blank blog name? ";
      local $line=<STDIN>;
      if ($line=~/^y/i) {
        $blogtitle='';
      } else {
        $notdone=1;
      }
    }
  }
  &set_config($file,'blogtitle',$blogtitle);
  local *BLOG;
  open(BLOG,"+<$htmldir/blog.html") || &fatalerror("Cannot open $htmldir/blog.html");
  flock(BLOG,LOCK_EX) || &fatalerror("Cannot lock $htmldir/blog.html");
  local $/;
  local $blog=<BLOG>;
  seek(BLOG,0,SEEK_SET);
  $blog=~s/\<title\>A new Addend\&aacute;t\<\/title\>/<title>$blogtitle<\/title>/;
  $blog=~s/\<h1\>A new Addend&aacute;t blog\<\/h1\>/<h1>$blogtitle<\/h1>/;
  print BLOG $blog;
  truncate(BLOG,tell(BLOG));
  flock(BLOG,LOCK_UN);
  close(BLOG);
}

sub determine_o_nofollow()
{
  $O_NOFOLLOW=O_NOFOLLOW;
  if ($O_NOFOLLOW+0 eq $O_NOFOLLOW) {
    return;
  }
  $O_NOFOLLOW=POSIX::O_NOFOLLOW;
  if ($O_NOFOLLOW+0 eq $O_NOFOLLOW) {
    return;
  }
  print STDERR "I can't find O_NOFOLLOW in your perl installation.\n";
  print STDERR "Trying to get it from your C include files.\n";
  local *INCLUDE;
  if (open(INCLUDE,"</usr/include/asm/fcntl.h")) {
    local @include=<INCLUDE>;
    @include=grep{/^#define(.*?)O_NOFOLLOW(.*?)([0-9]+)/} @include;
    if ($include[0]=~/^#define(.*?)O_NOFOLLOW(.*?)([0-9]+)/) {
      local $val=$3;
      if ($val=~/^0/) {
        $O_NOFOLLOW=oct($val);
      } else {
        $O_NOFOLLOW=$val;
      }
      return;
    }
  }
  print STDERR "Can't find O_NOFOLLOW.  Guessing that it's 0400000.  If you're\n";
  print STDERR "not running Linux/i386, this is probably wrong.\n";
}

sub read_line_defaulted()
{
  print "$_[0]\n(Enter for $_[1]): ";
  local $line=<STDIN>;
  $line=~s/[\r\n]//gs;
  if ($line eq '') {
    return $_[1];
  }
  return $line;
}

sub choose_comments_url()
{
  local $suffix;
  if ($commentsdir=~/^\Q$htmldir\E(.*?)$/) {
    $suffix=$1;
  } else {
    $suffix='/comments';
  }
  $commentsurl=$blogurl;
  if ($commentsurl !~ /\/$/) {
    $commentsurl=~s/^(.*)\/(.*?)$/$1$suffix/;
  } else {
    $commentsurl.=$suffix;
  }
  $commentsurl=&read_line_defaulted("Enter the base URL for comments.",$commentsurl);
}

sub choose_comments_dir()
{
  $commentsdir="$htmldir/comments";
#  $commentsdir=&read_line_defaulted("Enter the directory for comments files",$commentsdir);
  print "Comments are going in $commentsdir.\n";
  if (!(-d $commentsdir)) {
    if (mkdir($commentsdir,01777)) {
      chmod (01777,$commentsdir) ||
        &fatalerror("Could not chmod $commentsdir");
    }
  }
}

sub init_entryidfile()
{
  if (-f "$homedir/.addendat-entryid") {
    print "$homedir/.addendat-entryid already exists.  Not changing.\n";
  } else {
    local *ENTRYID;
    sysopen(ENTRYID,"$homedir/.addendat-entryid",O_WRONLY|O_CREAT|O_EXCL|$O_NOFOLLOW) ||
      &fatalerror("Cannot create $homedir/.addendat-entryid");
    chmod(0666,"$homedir/.addendat-entryid") ||
      &fatalerror("Cannot chmod 0666 $homedir/.addendat-entryid");
    close(ENTRYID);
  }
  &set_config($file,'entryidfile()',"$homedir/.addendat-entryid");
}

sub set_cgiurl()
{
  $cgiurl=$blogurl;
  if ($cgidir eq $htmldir) {
    $cgiurl=~s/blog\.html$/addendat.cgi/;
  } else {
    if ($cgidir=~/^\Q$htmldir\E(.*?)$/) {
      local $suffix=$1;
      $cgiurl=~s/blog\.html$/$suffix\/addendat.cgi/;
    }
  }
  if ($cgiurl=~/\/$/) {
    $cgiurl.='addendat.cgi';
  }
  $cgiurl=&read_line_defaulted("URL to addendat.cgi", $cgiurl);
  &set_config($file,'cgiurl',$cgiurl);
}

sub set_comment_options()
{
  &choose_comments_dir();
  &choose_comments_url();
  &set_cgiurl();
  $file=~s/\<a href="http:\/\/yourdomain\/addendat\/comments\/\%entryid\%\.html"\>/<a href="$commentsurl\/\%entryid\%.html">/s;
  &init_entryidfile();
  # Yep, this will wind up putting the comments in a dir called comments,
  # regardless of your selection.
  &set_config($file,'blogfile(comments/)',"$htmldir/\%blog\%.html");
  &set_config($file,'blogfile(commentpage)',"$commentsdir/\%entryid\%.html");
#  &set_config($file,'',$commentsdir);
}

sub choose_html_dir()
{
  $htmldir=$homedir.'/public_html';
  print "What directory should Addendat put its HTML in?\n(enter for $htmldir): ";
  local $line=<STDIN>;
  $line=~s/[\r\n]//sg;
  if ($line ne '') {
    $htmldir=$line;
  }
  if (!(-d $htmldir)) {
    die "$htmldir doesn't exist or is not a directory.\n";
  }
  system('cp','blog.html','add.html',$htmldir);
}

sub choose_cgi_dir()
{
  $cgidir=$htmldir;
  print "What directory should Addendat put its CGI scripts in?\n(enter for $cgidir): ";
  local $line=<STDIN>;
  $line=~s/[\r\n]//sg;
  if ($line ne '') {
    $cgidir=$line;
  }
  if (!(-d $cgidir)) {
    die "$cgidir doesn't exist or is not a directory.\n";
  }
  system('cp','addendat.cgi',$cgidir);
}

sub choose_addendat_cfg_path()
{
  print "Placing addendat.cfg in $homedir/addendat.cfg\n";
  $addendat_cfg_path=$homedir.'/addendat.cfg';
}

sub choose_addendat_cfg()
{
  local $notdone=1;
  if (-f $addendat_cfg_path) {
    local $notdone=1;
    while ($notdone) {
      print "$addendat_cfg_path already exists.\n";
      print "Overwrite it? ";
      local $line=<STDIN>;
      if ($line=~/^y/i) {
        $notdone=0;
      } else {
        $notdone=1;
      }
    }
  }
  while ($notdone) {
    print "Do you want to use the comments system? ";
    local $line=<STDIN>;
    $notdone=0;
    if ($line=~/^Y/i) {
      print "Using comments.\n";
      system('cp', 'configs/comments.cfg', $addendat_cfg_path);
      $using_comments=1;
    } elsif ($line=~/^N/i) {
      print "Not using comments.\n";
      system('cp', 'configs/simple.cfg', $addendat_cfg_path);
    } else {
      print "Answer is not yes or no.  Try again.\n";
      $notdone=1;
    }
  }
}

sub fatalerror()
{
  die $_[0];
}

sub set_config()
{
  if ($_[0]=~/\<\%\Q$_[1]\E%\>(.*?)\<\/\%\Q$_[1]\E\%\>/s) {
    $_[0]=~s/\<\%\Q$_[1]\E%\>$1\<\/\%\Q$_[1]\E\%\>/\<%$_[1]%\>$_[2]\<\/%$_[1]%\>/s;
  } else {
    $_[0].="\n<\%$_[1]\%>$_[2]</\%$_[1]\%>\n";
  }
}

sub set_access_code()
{
  local ($acccode,$acccode2)=(1,2);
  while ($acccode ne $acccode2) {
    print "Enter the access code to add to your blog.  DO NOT make this the\nsame as any other password you use.\n";
    $acccode=<STDIN>;
    print "Confirm access code: ";
    $acccode2=<STDIN>;
    if ($acccode ne $acccode2) {
      print "Access codes don't match.  Retry.\n";
    }
  }
  $acccode=~s/[\r\n]$//gs;
  &set_config($file,'accesscode',$acccode);
}

sub set_blogurl()
{
  local $line;
  $homedir=$ENV{HOME};
  if ($homedir ne '') {
    $hostname=`hostname --fqdn`;
    chop($hostname);
    $url="http://$hostname/~$user/blog.html";
  }
  local $notdone=1;
  while ($notdone) {
    print "Blog URL (Hit enter for $url)\n: ";
    $line=<STDIN>;
    $line=~s/[\r\n]//gs;
    if ($line eq '') {
      $line=$url;
    }
    if (&url_ok($line)) {
      $url=$line;
      $notdone=0;
    }
  }
  $blogurl=$url;
#  $baseurl=$url;
#  if ($baseurl!~/\/$/) {
#    $baseurl=~s/^(.*)\/(.*?)$/$1\//;
#  }
  &set_config($file,'blogurl',$url);
}

sub url_ok()
{
  if ($_[0]!~/^http(s*):\/\/[a-zA-Z0-9]/) {
    print "$_[0] doesn't look like a valid URL.\n";
    print "Are you sure you want to use this URL?\n";
    if (<STDIN>=~/^y/i) {
      return 1;
    }
    return 0;
  }
  return 1;
}

#sub url_ok()
#{
#  print "Testing url $_[0]\n";
#  local $result=`$httpclient -head $_[0]`;
#  if ($result=~/^(.*?) ([0-9]+)/s) {
#    local $code=$2;
#    if ($code eq '200') {
#      return 1;
#    }
#    print "URL returns error code $code.\n";
#  } else {
#    print "Unable to parse error code.\n";
#  }
#  return 0;
#}
