
/* CGI program to delete email from a pop server (port 110). */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>

extern int errno;  /* Error codes are returned here. */

struct hostent *hostent;
struct sockaddr_in sockaddr;
int sock,status,hostaddr,pop3_port=110,socket_option=0;
time_t current_time,hold_time;
char buffer[4096];
fd_set socket_read_status;
struct timeval socket_time_structure;

#define TIMEOUT_SECONDS 30

char pop3_server[128],pop3_account[32],pop3_password[32],numbers_list[64];
char temp_string[128],form_data_string[255];
int message_number,temp_int,temp_string_pointer,numbers_list_pointer;
char message_number_string[8],byte_count_string[8];
int byte_count,byte_count_string_pointer,message_bytes_read,extra_bytes_read;


/*----------------------------- Subroutines ----------------------------------*/

#include "web_based_email.h"


/*----------------------------- Main Program ---------------------------------*/
int main(void)
{
printf("Content-type: text/html\n");  /* We have to return this line first. */
printf("\n");

printf("<HTML>\n");
printf("<HEAD>\n");
printf("<H2>POP3 Message Deletion</H2>\n");
printf("</HEAD>\n");
printf("<BODY>\n");

gets(form_data_string);  /* Get form data. */
temp_int = 0;
while (form_data_string[temp_int])
  {
  if (form_data_string[temp_int] == '+')
    form_data_string[temp_int] = ' ';
  temp_int++;
  }

/* Figure out POP3 information and load variables. */
find_field_in_form_data_string("pop3_server");
strcpy(pop3_server,temp_string);
find_field_in_form_data_string("pop3_account");
strcpy(pop3_account,temp_string);
find_field_in_form_data_string("pop3_password");
strcpy(pop3_password,temp_string);
find_field_in_form_data_string("numbers_list");
strcpy(numbers_list,temp_string);

/* Now get connected. */
strcpy(temp_string,pop3_server);
hostent = gethostbyname(temp_string);  /* Do DNS lookup. */
if (hostent == NULL)
  {
  printf("Couldn't resolve POP3 server address; quitting.\n");
  goto exit_program;
  }

sock = socket(AF_INET,SOCK_STREAM,0);  /* Allocate a socket. */
if (sock < 0)
  {
  printf("Unable to allocate a socket; quitting.\n");
  goto exit_program;
  }

/* Initialize sockaddr fields. */
memset(&sockaddr,0,sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
memcpy((char *)&(sockaddr.sin_addr.s_addr),(char *)hostent->h_addr_list[0],
 (size_t)hostent->h_length);
sockaddr.sin_port = htons(pop3_port);

/* Connect to remote port now. */
if (connect(sock,(struct sockaddr *)&sockaddr,sizeof(sockaddr)) < 0)
  {
  printf("Unable to connect to your POP3 server; quitting.\n");
  close(sock);
  goto exit_program;
  }
fcntl(sock,F_SETFL,O_NONBLOCK);  /* Set socket to non-blocking. */

/*-------------------------------------*/
/* Now we're ready to talk with the pop3 server, with text messages. */

/* Get welcome message from server. */
if (get_message_from_socket())
  {
  printf("Didn't get welcome message from POP3 server; quitting.\n");
  goto shut_down_and_close;
  }
if (strncmp(temp_string,"+OK",3))  /* Not ok? */
  {
  printf("Bad welcome message from server: %s\n",temp_string);
  goto shut_down_and_close;
  }

strcpy(buffer,"USER ");
strcat(buffer,pop3_account);
strcat(buffer,"\r\n");
write(sock,buffer,strlen(buffer));
if (get_message_from_socket())
  {
  printf("Error getting USER response from POP3 server.\n");
  goto shut_down_and_close;
  }
if (strncmp(temp_string,"+OK",3))  /* Not ok? */
  {
  printf("Bad name response from server: %s\n",temp_string);
  goto shut_down_and_close;
  }

strcpy(buffer,"PASS ");
strcat(buffer,pop3_password);
strcat(buffer,"\r\n");
write(sock,buffer,strlen(buffer));
if (get_message_from_socket())
  {
  printf("Error getting PASS response from POP3 server.\n");
  goto shut_down_and_close;
  }
if (strncmp(temp_string,"+OK",3))  /* Didn't get +OK? */
  {
  printf("Bad password response from server; quitting.\n");
  goto shut_down_and_close;
  }
printf("<P>\n");
printf("Login message: %s\n",temp_string);
printf("<HR>\n");


/*--------------------*/

/* Get ready to find individual entries in list of messages to delete. */
numbers_list_pointer = 0;
while (numbers_list_pointer < strlen(numbers_list))
  {
  temp_string_pointer = 0;
  while ((numbers_list_pointer < strlen(numbers_list))
   && (numbers_list[numbers_list_pointer] != ' '))
    temp_string[temp_string_pointer++] = numbers_list[numbers_list_pointer++];
  temp_string[temp_string_pointer] = 0;  /* Terminate string. */
  printf("Deleting message number %s: ",temp_string);
  strcpy(buffer,"DELE ");
  strcat(buffer,temp_string);
  strcat(buffer,"\r\n");
  write(sock,buffer,strlen(buffer));
  if (get_message_from_socket())
    {
    printf("Timeout getting DELE response; quitting.\n");
    goto shut_down_and_close;
    }
  printf("%s<BR>\n",temp_string);
  numbers_list_pointer++;  /* Skip space (or go past end of string). */
  }


/*--------------------*/

/* Now log out from the pop3 server. */
strcpy(buffer,"QUIT\r\n");
write(sock,buffer,strlen(buffer));
if (get_message_from_socket())
  {
  printf("Error getting QUIT response from pop3 server.\n");
  goto shut_down_and_close;
  }
if (strncmp(temp_string,"+OK",3))
  printf("POP3 QUIT response was: %s\n",temp_string);

/* Produce the form here to go back to the message-reading screen. */
printf("<FORM METHOD=POST ACTION=\"pop3_read_email\">\n");
printf("<INPUT TYPE=HIDDEN NAME=\"pop3_server\"   VALUE=\"%s\">\n",pop3_server);
printf("<INPUT TYPE=HIDDEN NAME=\"pop3_account\"  VALUE=\"%s\">\n",pop3_account);
printf("<INPUT TYPE=HIDDEN NAME=\"pop3_password\" VALUE=\"%s\">\n",pop3_password);
printf("<INPUT TYPE=SUBMIT VALUE=\"Read email again\">\n");
printf("</FORM>\n");


/*-------------------------------------*/
shut_down_and_close:
shutdown(sock,2);
close(sock);

exit_program:
printf("<HR>\n");
printf("Please send any comments on this web-based email system to\n");
printf("<A HREF=""mailto:alton@alton-moore.net"">Alton Moore</A>.\n");
printf("</BODY>\n");
printf("</HTML>\n");

return(0);
}

