/***************************************************************************
                          main.cpp  -  description
                             -------------------
    begin                : Thu Nov 20 12:07:25 CST 2003
    copyright            : (C) 2003 by Wei Zheng
    email                : v_zheng@yahoo.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream.h>
#include <getopt.h>

#include <signal.h>
#include <stdlib.h>
#include "notification.h"
#include "notificationhttp.h"

onlineusers usersqueue;

extern char *optarg;
extern int optind, opterr, optopt;

void catch_int_signal(int signo){
  usersqueue.list_online_user();
  usersqueue.eliminate_online_queue();
  exit(1);
}

void catch_child_signal(int signo)
{
  int status;
  pid_t pidtmp;
  online_userinfo * current;

  pidtmp = wait(&status);
  current = * (usersqueue.headuserpp);
  while(current!=NULL)
  {
    if(current->pid==pidtmp)
    {
      memset(current->userinfop->ip,'\0',strlen(current->userinfop->ip));
      memset(current->userinfop->port,'\0',strlen(current->userinfop->port));
      memset(current->userinfop->authid,'\0',strlen(current->userinfop->authid));
      memset(current->userinfop->sessionid,'\0',strlen(current->userinfop->sessionid));
      memset(current->userinfop->username,'\0',strlen(current->userinfop->username));
      memset(current->userinfop->proxyaddr,'\0',strlen(current->userinfop->proxyaddr));
      current->userinfop->proxyport = 0;
      memset(&(current->userinfop->prp),0,sizeof(post_request_parameters));
      current->pid = 0;
      break;
    }
    else
      current=current->next;
  }
}

void init_daemon(void)
{
  int pid;

  if(pid=fork())
    exit(0);
  else if(pid< 0)
    exit(1);
  setsid();
  if(pid=fork())
    exit(0);
  else if(pid< 0)
    exit(1);
  umask(0);
  return;
}

void usage(void) {
  fprintf( stderr,
    "msnshell 1.11\n"
    "Usage: msnshell --account ******@hotmail.com --password ****** --protocol [tcp|http] [--proxyhost *.*.*.* --proxyport num]\n"
    "Options:\n"
    "  -a --account ACCOUNT     Msn Account\n"
    "  -p --password PASSWORD   Msn Password \n"
    "  -c --protocol [tcp|http] Protocol\n"
    "  -x --proxyhost *.*.*.*   Proxy server\n"
    "  -o --proxyport NUMBER    Proxy port\n"
    "  -v --version             Print version information and exit.\n"
    "  -h --help                Print usage information and exit.\n" );
    return;
}

int main(int argc, char * argv[])
{
  int proxy_existence = -1;
  int c;
  int protocol = 0;
  int httpproxyport = 0;
  char account[50];
  char password[50];
  char httpproxyaddr[50];

  memset(account,0,sizeof(account));
  memset(password,0,sizeof(password));
  memset(httpproxyaddr,0,sizeof(httpproxyaddr));

  signal(SIGINT,catch_int_signal);
  signal(SIGCHLD,catch_child_signal);

	while (1)
	{
    int this_option_optind = optind ? optind : 1;
		int option_index = 0;
		static struct option long_options[] = {
      {"account",    1, 0, 'a'},
      {"password",   1, 0, 'p'},
      {"protocol",   1, 0, 'c'},
      {"proxyhost",  1, 0, 'x'},
      {"proxyport",  1, 0, 'o'},
			{"version",    0, 0, 'v'},
			{"help",       0, 0, 'h'},
			{0,            0, 0,  0}
		};
		c = getopt_long (argc, argv, "a:p:c:x:o:vh",long_options, &option_index);

		if (c == -1)
			break;
		switch(c)
		{
			case 'a':
				if(strlen(optarg)<=sizeof(account))
					strcat(account,optarg);
				else
				{
					fprintf(stderr,"ERROR: The Account Parameter Too Long\n");
					usage();
					exit(1);
				}
				break;

			case 'p':
				if(strlen(optarg)<=sizeof(password))
					strcat(password,optarg);
				else
				{
					fprintf(stderr,"ERROR: The Password Parameter Too Long\n");
					usage();
					exit(1);
				}
				break;

      case 'c':
        if(strcmp(optarg,"tcp")==0)
          protocol = 1;
        else if(strcmp(optarg,"http")==0)
          protocol = 2;
        else
        {
          printf("c\n");
          usage();
          exit(1);
        }
        break;

			case 'x':
				if(strlen(optarg)<sizeof(httpproxyaddr))
				{
					strcat(httpproxyaddr,optarg);
					proxy_existence++;
        }
				else
				{
					fprintf(stderr,"ERROR: The Proxyhost Parameter Too Long\n");
					usage();
					exit(1);
				}
				break;

			case 'o':
				if(strlen(optarg)<=5 && atoi(optarg)>0)
				{
          httpproxyport = atoi(optarg);
					proxy_existence++;
				}
				else
				{
					if(strlen(optarg)>5)
						fprintf(stderr,"ERROR: The Proxyport Parameter Too Long\n");
					if(atoi(optarg)==0)
						fprintf(stderr,"ERROR: The Proxyport Parameter must be a number\n");
					usage();
					exit(1);
				}
				break;

      case 'v':
        fprintf(stderr,"msnshell version 1.10\n");
        exit(0);
        break;

			case 'h':
				usage();
				exit(0);
				break;

			default:
				printf ("?? getopt returned character code 0%o ??\n", c);
		}
	}

  if (optind < argc)
  {
    printf ("non-option ARGV-elements: ");
		while (optind < argc)
			printf ("%s ", argv[optind++]);
		printf ("\n");
		exit(1);
	}

	if(account[0]==0 || password[0]==0 || proxy_existence==0 || protocol == 0)
	{
		usage();
		exit(1);
	}

  init_daemon();
  if(protocol==1)
    notification noti(account,password,NULL);
  if(protocol==2)
  {
    if(proxy_existence==1)
      notificationhttp noti(account,password,NULL,httpproxyaddr,httpproxyport);
    else
      notificationhttp noti(account,password,NULL,NULL,0);
  }
  return EXIT_SUCCESS;
}
