/*
 * Initial main.c file generated by Glade. Edit as required.
 * Glade will not overwrite this file.
 */

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

#define _REENTRANT

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>       

#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#else
#ifdef HAVE_NETINET_IN_SYSTEM_H
#include <netinet/in_system.h>
#endif
#endif

#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>

#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#ifdef HAVE_BSTRING_H
#include <bstring.h>
#endif

#ifdef STDC_HEADERS
#include <stdlib.h>
#endif

#include <stdarg.h>

#include <netinet/tcp.h>

#ifdef SOLARIS
#include <pthread.h>
#include <thread.h>
#else
#include <pthread.h>
#endif

#include <gtk/gtk.h>

#include "gtk-gui.h"
#include "gtk-interface.h"
#include "gtk-support.h"

void
gtk_gui (void *args)
{
   int tmp;
   struct term_node *term_node = NULL;
   time_t this_time;
   sigset_t mask;
   struct gtk_s_helper helper;
   struct interface_data *iface_data, *iface;
   GtkWidget *Main;
   GtkWidget *warningdialog;

   pthread_mutex_lock(&terms->gui_gtk_th.finished);

   terms->work_state = RUNNING;
   
   write_log(0,"\n gtk_gui_th = %d\n",(int)pthread_self());
   iface_data = NULL;

   sigfillset(&mask);

   if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
   {
      thread_error("gtk_gui_th pthread_sigmask()",errno);
      gtk_gui_th_exit(NULL);
   }

   if (pthread_mutex_lock(&terms->mutex) != 0) {
      thread_error("gtk_gui_th pthread_mutex_lock",errno);
      gtk_gui_th_exit(NULL);
   }

   if (term_add_node(&term_node, TERM_CON, (int)NULL, pthread_self()) < 0)
   {
      if (pthread_mutex_unlock(&terms->mutex) != 0)
         thread_error("gtk_gui_th pthread_mutex_unlock",errno);
      gtk_gui_th_exit(NULL);
   }

   if (term_node == NULL)
   {
      write_log(0, "Ouch!! No more than %d %s accepted!!\n", 
            term_type[TERM_CON].max, term_type[TERM_CON].name);
      if (pthread_mutex_unlock(&terms->mutex) != 0)
         thread_error("gtk_gui_th pthread_mutex_unlock",errno);
      gtk_gui_th_exit(NULL);
   }

   this_time = time(NULL);

#ifdef HAVE_CTIME_R
#ifdef SOLARIS
   ctime_r(&this_time,term_node->since, sizeof(term_node->since));
#else
   ctime_r(&this_time,term_node->since);
#endif
#else
   pthread_mutex_lock(&mutex_ctime);
   strncpy(term_node->since, ctime(&this_time), sizeof(term_node->since));
   pthread_mutex_unlock(&mutex_ctime);
#endif

   /* Just to remove the cr+lf...*/
   term_node->since[sizeof(term_node->since)-2] = 0;

   /* This is a console so, man... ;) */
   strncpy(term_node->from_ip, "127.0.0.1", sizeof(term_node->from_ip));

   /* Parse config file */
   if (strlen(tty_tmp->config_file))
      if (parser_read_config_file(tty_tmp, term_node) < 0)
      {
         write_log(0, "Error reading configuration file\n");
         gtk_gui_th_exit(term_node);
      }

   if (pthread_mutex_unlock(&terms->mutex) != 0) {
      thread_error("gtk_gui_th pthread_mutex_unlock",errno);
      gtk_gui_th_exit(term_node);
   }

#ifdef ENABLE_NLS
   bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
   textdomain (GETTEXT_PACKAGE);
#endif

   gtk_set_locale ();
   gtk_init (NULL, NULL);

   add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");

   if (interfaces->list)
      iface_data = dlist_data(interfaces->list);
   else {
      gtk_i_create_warningdialog("Hmm... you don't have any valid interface. \
            %s is useless. Go and get a life!", PACKAGE);
      gtk_gui_th_exit(term_node);
   }

   /* take the first valid interface */
   if (strlen(iface_data->ifname)) {
      if (gtk_i_create_warningdialog(0,
               "Warning: interface %s selected as the default one", 
               iface_data->ifname) < 0)
         gtk_gui_th_exit(term_node);
      if ((tmp = interfaces_enable(iface_data->ifname)) == -1) {
         if (gtk_i_create_warningdialog("Unable to use interface %s!! (Maybe nonexistent?)\n\n", 
                  iface_data->ifname) < 0)
            gtk_gui_th_exit(term_node);
      } else {
         iface = (struct interface_data *) calloc(1, sizeof(struct interface_data));
         memcpy((void *)iface, (void *)iface_data, sizeof(struct interface_data));
         term_node->used_ints->list = dlist_append(term_node->used_ints->list, iface);
      }
   } else {
      if (gtk_i_create_warningdialog("Hmm... you don't have any valid interface. \
               %s is useless. Go and get a life!", PACKAGE) < 0)
         gtk_gui_th_exit(term_node);
   }

   helper.node = (struct term_node *)term_node;
   helper.edit_mode = 0;
   Main = gtk_i_create_Main (&helper);
   gtk_widget_show (Main);
   warningdialog = gtk_i_create_warningdialog ("%s", "Warning!!!  This is an alpha version of the GTK GUI. Not all the options are implemented in this GUI, but if you are brave enough, you are allowed to test it and tell us all the bugs you could find (if you are able to survive!)"); 

   gtk_widget_show (warningdialog);

   gtk_main ();

   write_log(0, "Exiting GTK mode...\n");

   gtk_gui_th_exit(term_node);
}


/* 
 * GUI destroy. End
 */
void
gtk_gui_th_exit(struct term_node *term_node)
{
   dlist_t *p;
   struct interface_data *iface_data;

   write_log(0, "\n gtk_gui_th_exit start...\n");

   if (term_node)
   {
      for (p = term_node->used_ints->list; p; p = dlist_next(term_node->used_ints->list, p)) {
         iface_data = (struct interface_data *) dlist_data(p);
         interfaces_disable(iface_data->ifname);
      }

      attack_kill_th(term_node,ALL_ATTACK_THREADS);

      if (pthread_mutex_lock(&terms->mutex) != 0)
         thread_error("gtk_gui_th pthread_mutex_lock",errno);

      term_delete_node(term_node, NOKILL_THREAD);               

      if (pthread_mutex_unlock(&terms->mutex) != 0)
         thread_error("gtk_gui_th pthread_mutex_unlock",errno);
   }

   write_log(0," gtk_gui_th_exit finish...\n");   

   terms->gui_gtk_th.id = 0;

   if (pthread_mutex_unlock(&terms->gui_gtk_th.finished) != 0)
      thread_error("gtk_gui_th pthread_mutex_unlock",errno);
   
   terms->work_state = STOPPED;
   
   pthread_exit(NULL);
}
