#!/usr/bin/perl
###########################################################################
# checkmail.pl - Retreive a list of the users POP messages
###########################################################################
require "common.pl";
use Socket;

if (($remip ne $fromip) && ($sid ne "") && ($button eq $check_button)) {
 &diffip;
}

if ($button eq $cancel_button){
 &cancel;
}

if (($folder) && ($folder ne 'POP') && ($feature_folders == 1)) { 
 if ($feature_pop == 0){
  $buton = $query->escape($openfolder_button);
  print "Location: $folder_pl?SESSIONID=$sid&FOLDER=INBOX&BUTTON=$buton\n\n";
  exit;
 }
}

&print_header;

###########################################################################
# Present a login sequence for those who need it
###########################################################################
if (!($button)){
 print $query->startform($method, $checkmail_pl, $CGI::URL_ENCODED);
 print "<TABLE BORDER=\"0\"><TR><TD>";
 print $username_input;
 print "</TD><TD>";
 print $query->textfield('POPUSERNAME', '', 24);
 print "</TD></TR>";
 if ($feature_pop == 0){
  print "<TR><TD>";
  print $popserv_input;
  print "</TD><TD>";
  print $query->textfield('POPSERVER', '', 24);
  print "</TD></TR>";
 }
 print "<TR><TD>";
 print $poppass_input;
 print "</TD><TD>";
 print $query->password_field('POPPASS', '', 24);
 print "</TD></TR></TABLE>";
 print $query->submit('BUTTON', $login_button);
 print $query->endform;
 &print_footer;
 exit;
}

###########################################################################
# Create a session id or get POP information
###########################################################################
if ($sid eq "") {
 if ($feature_pop == 0){
  $sessionid = $popusername . "\@" . $popserver . " " . time;
 } else {
  $sessionid = $popusername . "\@" . $singlepop . " " . time;
 }
 $a = time;
 srand($a);
 $one = int(rand($a)) + 1;
 $two = int(rand($a)) + 1;
 $salt = "$one$two";
 $sid = crypt($sessionid, $salt);
 $cryptpass = pack("u*", $poppass);
 $cryptsess = pack("u*", $sessionid);
 $remip = pack("u*", $fromip);
 dbmopen(%sess, $sessiondb, 0600) || die "Error opening db $sessiondb";
 $sess{$sid} = $cryptsess . "\0" . $cryptpass . "\0" . $remip;
 dbmclose(%sess);
} elsif ($sessionid =~ /\@/) {
 dbmopen (%sess, $sessiondb, 0600) || die "Error opening db $sessiondb";
 $poppass = unpack("u*", $cryptpass);
 dbmclose(%sess);
 @pop = split (/ /, $sessionid);
 $popaccount = $pop[0];
 ($popusername, $popserver) = split(/\@/, $popaccount);
} else {
 @username = split (/ /, $sessionid);
 $username = $username[0];
 dbmopen(%serv, $serverdb, 0600) || die "Error opening db $serverdb";
 $popserver = $serv{$username};
 dbmclose(%serv);
 dbmopen(%popname, $popdb, 0600) || die "Error opening db $popdb";
 $popusername = $popname{$username};
 dbmclose(%popname);
 dbmopen(%sess, $sessiondb, 0600) || die "Error opening db $sessiondb";
 $sessentry = $sess{$sid};
 $poppass = unpack("u*", $cryptpass);
 dbmclose(%sess);
}

###########################################################################
# Print the header
###########################################################################
if ($btns eq 'top' || $btns eq 'both' ) { &print_options; }

###########################################################################
# Connect the socket to the POP server
###########################################################################
 if (($folder eq 'POP')||($button eq $check_button)||($button eq $login_button)){
  $folder = 'POP';
  $proto = getprotobyname('tcp');
  socket(SOCK, PF_INET, SOCK_STREAM, $proto);
  if ($feature_pop == 0){
   $iaddr = gethostbyname($popserver);
  } else {
   $iaddr = gethostbyname($singlepop);
  }
  $sin = pack('Sna4x8', AF_INET, 110, $iaddr);
  connect(SOCK, $sin);

###########################################################################
# Login to the POP server and verify server auth info
###########################################################################
  recv SOCK, $junk, 512, 0;
  send SOCK, "USER $popusername\r\n", 0;
  recv SOCK, $junk, 512, 0;
  send SOCK, "PASS $poppass\r\n", 0;
  recv SOCK, $junk, 512, 0;
  $pop = 'yes';

 } else {
###########################################################################
# For folders other than INBOX, or local INBOX
###########################################################################
  $fold = $folderdir . "/" . $username . "/" . $folder;
  dbmopen(%folder, $fold, 0600) || die "Error opening db $fold";
  $pop = 'no';
  @key_temp = split(/\t/, $folder{'MESSAGES'});
  $num_messages = $#key_temp;
  foreach (@key_temp) { unless ($_ == 0) { $mess_list[++$i] = $_; } }
 }

 if ($junk =~ /^-ERR/) {
###########################################################################
# User has entered the wrong server auth info
###########################################################################
  print $pop_wrong_info;
  &print_footer;
  if ($button eq $login_button){
   dbmopen(%sess, $sessiondb, 0600) || die "Error opening db $sessiondb";
   delete ($sess{$sid});
   dbmclose(%sess);
  }
  exit;

 } else {
###########################################################################
# Determine the number of messages
###########################################################################
 if ($pop eq 'yes'){
  $junk = "";
  send SOCK, "STAT\r\n", 0;
  recv SOCK, $num_messages, 512, 0;
  @messages = split(/ /, $num_messages, 3);
  $num_messages = $messages[1];
  for ($i = 0; $i < $num_messages; $i++) { $mess_list[$i] = $i; }
 }

###########################################################################
# Make a list of the user's messages
###########################################################################
 unless ($num_messages < 1) {
  print $query->startform($method, $messact_pl, $CGI::URL_ENCODED);
  if ($btns eq 'top' || $btns eq 'both') {
   print "<TABLE WIDTH=\"100%\" BORDER=\"0\"><TR>\n";
   print "<TD WIDTH=\"50%\" ALIGN=\"LEFT\">";
   print $query->submit('BUTTON', $delmarked_button);
   print "</TD><TD WIDTH=\"50%\" ALIGN=\"RIGHT\">";
   print $query->reset($clrcheck_button);
   if(!(($sessionid =~ /\@/) || ($sid eq ""))){
    $index = $folderdir . "/" . $username . "-index";
    dbmopen(%index, $index, 0600) || die "Error opening db $index";
    @index = keys %index;
    if (@index){
     print "</TD></TR><TR><TD ALIGN=\"LEFT\">";
     print $query->submit('BUTTON', $movemarked_button);
     print "</TD><TD ALIGN=\"RIGHT\">";
     print $query->popup_menu('NEWFOLDER', \@index, '', \%index);
    }
    dbmclose(%index);
   }
   print "</TD></TR></TABLE>\n";
  }
  print "<H3>$num_messages $total_mess_info</H3>";
  print $query->hidden('SESSIONID', $sid);
  print $query->hidden('FOLDER', $folder);
  print "<TABLE WIDTH=\"100%\" BORDER=\"0\">\n";
  print "<TR>";
  #print "<TD WIDTH=\"5%\"><B>$status_info</B></TD>\n";
  print "<TD WIDTH=\"30%\"><B>$from_info</B></TD>\n";
  print "<TD WIDTH=\"30%\"><B>$subj_info</B></TD>\n";
  print "<TD WIDTH=\"30%\"><B>$date_info</B></TD>\n";
  print "<TD WIDTH=\"5%\"><B>$size_info</B></TD>\n";
  print "<TD WIDTH=\"5%\"><B>$mark_info</B></TR>\n";
 
  for($i = 1; $i <= $num_messages; $i++){
 
###########################################################################
# Clear out the temporary buffer thingies
###########################################################################
   $from = "";
   $subject = "";
   $date = "";
   $message_size = "";
   $header = "";

###########################################################################
# Get the size of the message
###########################################################################
   if($pop eq 'yes'){
    send SOCK, "LIST $i\r\n", 0;
    recv SOCK, $temp, 80, 0;
    ($junk, $junk, $message_size) = split (/\s/, $temp, 3);
  
###########################################################################
# Get the header of the message - first try TOP, then fall back on RETR
###########################################################################
    $temp = "";
    send SOCK, "TOP $i 0\r\n", 0;
    $stop = "no";
    $toperr = "no";
    while ($stop !~ "yes") {
     recv SOCK, $temp, 1024, 0;
     $header = $header . $temp;
     if ($temp =~ /\r*\n\.\r*\n/) { $stop= "yes";}
     if ($temp =~ /^\-ERR/) { $stop = "yes"; $toperr = "yes";};
    }
  
    if($toperr eq "yes") {
     send SOCK, "RETR $i\r\n", 0;
     $stop = "no";
     while ($stop !~ "yes") {
      recv SOCK, $temp, 1024, 0;
      $header = $header . $temp;
      if ($temp =~ /\r*\n\.\r*\n/) { $stop= "yes";}
     }
    }

   } else {
###########################################################################
# Local folders
###########################################################################
    $header = $folder{$keys[$i]};
    $message_size = length($header);
   } 
 
###########################################################################
# Parse the header of the message for From, Subject, and Date line,
# also make it play nicely with HTML
###########################################################################
   $header =~ s/</\&lt\;/g;
   $header =~ s/>/\&gt\;/g;
   $header =~ s/(.*)?\r*\n\r*\n(.*)/$1/;
   @header = split(/\n/, $header);
   foreach $line (@header){
    if ($line =~ /^From:/i && $from eq ""){
     $from = $line;
    } elsif ($line =~ /^Subject:/i && $subject eq "") {
     $subject = $line;
    } elsif ($line =~ /^Date:/i && $date eq "") {
     $date = $line;
    } elsif ($line =~ /^Status:/i && $date eq "") {
     if ($line =~ /R/) { $status = ''; }
     else { $status = $new_info; }
    }
   }
 
###########################################################################
# We don't need the "From: " part, etc.
###########################################################################
   ($junk, $from) = split (/\s/, $from, 2);
   ($junk, $subject) = split (/\s/, $subject, 2);
   ($junk, $date) = split (/\s/, $date, 2);
   chomp $from;
   chomp $subject;
   chomp $date;
 
###########################################################################
# Get the from address for a nice link
###########################################################################
   @fromaddress = split (/\s/, $from);
   foreach $line (@fromaddress) {
    if ($line =~ /\@.*\./) {
     $fromaddress = $line;
    }
   }
   $fromaddress =~ s/<//g;
   $fromaddress =~ s/>//g;
   $fromaddress =~ s/\&lt\;//ig;
   $fromaddress =~ s/\&gt\;//ig;
 
###########################################################################
# Display the information and a couple of buttons for each message
###########################################################################
   if ($i % 2 == 1) {
    $cellcolor = $odd_row_color;
   } else {
    $cellcolor = $even_row_color;
   }
   print "<TR>";
   #print "<TD BGCOLOR=\"$cellcolor\">";
   #print $status;
   #print "</TD>";
   print "<TD BGCOLOR=\"$cellcolor\">";
   $butt = CGI::escape($sendto_button);
   print $query->a({href=>"$options_pl?SESSIONID=$sid&TO=$fromaddress&BUTTON=$butt"}, $from);
   print "</TD>\n";
   if ($subject eq "") {
    $subject = "$nosubj_info";
   }
   print "<TD BGCOLOR=\"$cellcolor\">";
   if ($folder eq 'POP'){
   print $query->a({href=>"$messact_pl?SESSIONID=$sid&FOLDER=$folder&BUTTON=$read_button&MESSAGES=$i&ATTACHMENT=NONE"}, $subject);
   } else {
    print $query->a({href=>"$messact_pl?SESSIONID=$sid&FOLDER=$folder&BUTTON=$read_button&MESSAGES=$keys[$i]&ATTACHMENT=NONE"}, $subject);
   }
   print "</TD>\n";
   print "<TD BGCOLOR=\"$cellcolor\">";
   print $date;
   print "</TD>\n";
   print "<TD BGCOLOR=\"$cellcolor\">";
   print $message_size;
   print "</TD><TD BGCOLOR=\"$cellcolor\">";
   print $query->checkbox('MESSAGES', '', $i, '');
  }

###########################################################################
# Good HTML
###########################################################################
  print "</TABLE>";
  if ($btns eq 'bottom' || $btns eq 'both') {
   print "<TABLE WIDTH=\"100%\" BORDER=\"0\"><TR>\n";
   print "<TD WIDTH=\"50%\" ALIGN=\"LEFT\">";
   print $query->submit('BUTTON', $delmarked_button);
   print "</TD><TD WIDTH=\"50%\" ALIGN=\"RIGHT\">";
   print $query->reset($clrcheck_button);
   if(!(($sessionid =~ /\@/) || ($sid eq ""))){
    $index = $folderdir . "/" . $username . "-index";
    dbmopen(%index, $index, 0600) || die "Error opening db $index";
    @index = keys %index;
    if (@index){
     print "</TD></TR><TR><TD ALIGN=\"LEFT\">";
     print $query->submit('BUTTON', $movemarked_button);
     print "</TD><TD ALIGN=\"RIGHT\">";
     $index = $folderdir . "/" . $username . "-index";
     print $query->popup_menu('NEWFOLDER', \@index, '', \%index);
    }
    dbmclose(%index);
   }
   print "</TD></TR></TABLE>\n";
  }
  print $query->endform;
 } else {
  print "<H3>$num_messages $total_mess_info</H3>";
 }
}

###########################################################################
# Close the socket or folder
###########################################################################
if ($pop eq 'yes'){
 send SOCK, "QUIT\r\n", 0;
 close(SOCK);
} else {
 dbmclose(%folder);
}

 
###########################################################################
# Done
###########################################################################
if ($btns eq 'bottom' || $btns eq 'both') { &print_options; }
&update_sess;
&print_footer;
