/*****************************************************************************/
/*  connect_dialog.c - has the quick connect dialog                          */
/*  Copyright (C) 1998 Brian Masney <masneyb@newwave.net>                    */
/*                                                                           */
/*  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.                                      */
/*                                                                           */
/*  This program is distributed in the hope that it will be useful,          */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
/*  GNU General Public License for more details.                             */
/*                                                                           */
/*  You should have received a copy of the GNU General Public License        */
/*  along with this program; if not, write to the Free Software              */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
/*****************************************************************************/

#include "ftp.h"

void add_categories(void);
void add_sites(void);
static void cattoggle(GtkList *list, GtkWidget *child, gpointer data);
static void sitetoggle(GtkList *list, GtkWidget *child, gpointer data);
static void clear_text(void);
static void save_txt(GtkWidget *widget, char *dest, size_t size);
static void adddialog(GtkWidget *widget, int catorsite);
static void doadd(GtkWidget *widget, int catorsite);
static void deldialog(GtkWidget *widget, int catorsite);
static void dodel(GtkWidget *widget, int catorsite);
static void rendialog(GtkWidget *widget, int catorsite);
static void doren(GtkWidget *widget, int catorsite);
static void delete_newdiag(GtkWidget *widget, gpointer data);
static void ok_button(GtkWidget *widget, struct ftp_window_data *wdata);
static void destroy_main_dialog(GtkWidget *widget, gpointer data);
static void AskSave(GtkWidget *widget, gpointer data);
static void dosave(GtkWidget *widget, gpointer data);
static void cleanup_data(GtkWidget *widget, gpointer data);
static void backup_data(void);
static void set_userpass_visible(GtkWidget *checkbutton, GtkWidget *entry);

extern char emailaddr[MAXSTR];
extern struct conn_categories *hostcat;

static GtkWidget *hostedit, *portedit, *diredit, *useredit, *passedit, *anonchk, *catcombo, 
   *sitecombo, *newdiag, *edit, *dialog;
static GList *catlist = NULL, *sitelist = NULL;
static struct conn_categories *curcat, *origcat;
static struct conn_hosts *curhost;
static int modified;

void connect_dialog(GtkWidget *widget, struct ftp_window_data *wdata) {
   GtkWidget *frame, *table, *label, *sep, *connbut, *cancelbut;
   GtkWidget *box, *addbut, *renbut, *delbut;
   
   modified = 0;
   backup_data();
   
   dialog = gtk_dialog_new();
   gtk_window_set_title(GTK_WINDOW(dialog), "Connection Manager");
   gtk_container_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 10);
   
   frame = gtk_frame_new(NULL);
   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, TRUE, TRUE, FALSE);
   gtk_widget_show(frame);
   
   table = gtk_table_new(14, 2, FALSE);
   gtk_container_border_width(GTK_CONTAINER(table), 5);
   gtk_table_set_row_spacings(GTK_TABLE(table), 5);
   gtk_container_add(GTK_CONTAINER(frame), table);
   gtk_widget_show(table);
   
   label = gtk_label_new("Categories:");
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
   gtk_widget_show(label);
   
   catcombo = gtk_combo_new();
   gtk_table_attach_defaults(GTK_TABLE(table), catcombo, 1, 2, 0, 1);
   gtk_widget_show(catcombo);

   curcat = hostcat;
   add_categories();
   gtk_signal_connect(GTK_OBJECT(GTK_COMBO(catcombo)->list), "select_child", GTK_SIGNAL_FUNC(cattoggle), NULL);

   box = gtk_hbox_new(TRUE, 5);
   gtk_table_attach_defaults(GTK_TABLE(table), box, 1, 2, 1, 2);
   gtk_widget_show(box);
   
   addbut = gtk_button_new_with_label("Add");
   gtk_box_pack_start(GTK_BOX(box), addbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(addbut), "clicked", GTK_SIGNAL_FUNC(adddialog), (gpointer) 1);
   gtk_widget_show(addbut);

   delbut = gtk_button_new_with_label("Delete");
   gtk_box_pack_start(GTK_BOX(box), delbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(delbut), "clicked", GTK_SIGNAL_FUNC(deldialog), (gpointer) 1);
   gtk_widget_show(delbut);

   renbut = gtk_button_new_with_label("Rename");
   gtk_box_pack_start(GTK_BOX(box), renbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(renbut), "clicked", GTK_SIGNAL_FUNC(rendialog), (gpointer) 1);
   gtk_widget_show(renbut);
   
   sep = gtk_hseparator_new();
   gtk_table_attach_defaults(GTK_TABLE(table), sep, 0, 2, 2, 3);
   gtk_widget_show(sep);

   label = gtk_label_new("Sites:");
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4);
   gtk_widget_show(label);

   sitecombo = gtk_combo_new();
   gtk_table_attach_defaults(GTK_TABLE(table), sitecombo, 1, 2, 3, 4);
   gtk_widget_show(sitecombo);

   if(curcat != NULL) curhost = curcat->hosts;
   else curhost = NULL;
   add_sites();   
   gtk_signal_connect(GTK_OBJECT(GTK_COMBO(sitecombo)->list), "select_child", GTK_SIGNAL_FUNC(sitetoggle), NULL);

   box = gtk_hbox_new(TRUE, 5);
   gtk_table_attach_defaults(GTK_TABLE(table), box, 1, 2, 4, 5);
   gtk_widget_show(box);
   
   addbut = gtk_button_new_with_label("Add");
   gtk_box_pack_start(GTK_BOX(box), addbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(addbut), "clicked", GTK_SIGNAL_FUNC(adddialog), (gpointer) 0);
   gtk_widget_show(addbut);

   delbut = gtk_button_new_with_label("Delete");
   gtk_box_pack_start(GTK_BOX(box), delbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(delbut), "clicked", GTK_SIGNAL_FUNC(deldialog), (gpointer) 0);
   gtk_widget_show(delbut);

   renbut = gtk_button_new_with_label("Rename");
   gtk_box_pack_start(GTK_BOX(box), renbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(renbut), "clicked", GTK_SIGNAL_FUNC(rendialog), (gpointer) 0);
   gtk_widget_show(renbut);

   sep = gtk_hseparator_new();
   gtk_table_attach_defaults(GTK_TABLE(table), sep, 0, 2, 5, 6);
   gtk_widget_show(sep);

   label = gtk_label_new("Hostname:");
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 6, 7);
   gtk_widget_show(label);

   hostedit = gtk_entry_new_with_max_length(MAXSTR);
   gtk_table_attach_defaults(GTK_TABLE(table), hostedit, 1, 2, 6, 7);
   gtk_widget_show(hostedit);

   label = gtk_label_new("Port:");
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 7, 8);
   gtk_widget_show(label);

   portedit = gtk_entry_new_with_max_length(MAXSTR);
   gtk_table_attach_defaults(GTK_TABLE(table), portedit, 1, 2, 7, 8);
   gtk_widget_show(portedit);

   label = gtk_label_new("Directory:");
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 8, 9);
   gtk_widget_show(label);

   diredit = gtk_entry_new_with_max_length(MAXSTR);
   gtk_table_attach_defaults(GTK_TABLE(table), diredit, 1, 2, 8, 9);
   gtk_widget_show(diredit);

   sep = gtk_hseparator_new();
   gtk_table_attach_defaults(GTK_TABLE(table), sep, 0, 2, 9, 10);
   gtk_widget_show(sep);

   label = gtk_label_new("Username:");
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 10, 11);
   gtk_widget_show(label);

   useredit = gtk_entry_new_with_max_length(MAXSTR);
   gtk_table_attach_defaults(GTK_TABLE(table), useredit, 1, 2, 10, 11);
   gtk_widget_show(useredit);

   label = gtk_label_new("Password:");
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 11, 12);
   gtk_widget_show(label);

   passedit = gtk_entry_new_with_max_length(MAXSTR);
   gtk_table_attach_defaults(GTK_TABLE(table), passedit, 1, 2, 11, 12);
   gtk_entry_set_visibility(GTK_ENTRY(passedit), FALSE);
   gtk_widget_show(passedit);
   
   anonchk = gtk_check_button_new_with_label("Log in as ANONYMOUS");
   gtk_table_attach_defaults(GTK_TABLE(table), anonchk, 0, 2, 12, 13);
   gtk_signal_connect(GTK_OBJECT(anonchk), "toggled", GTK_SIGNAL_FUNC(set_userpass_visible), NULL);
   gtk_widget_show(anonchk);

   connbut = gtk_button_new_with_label("Connect");
   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), connbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(connbut), "clicked", GTK_SIGNAL_FUNC(ok_button), (gpointer) wdata);
   gtk_widget_show(connbut);

   cancelbut = gtk_button_new_with_label("Cancel");
   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), cancelbut, TRUE, TRUE, FALSE);
   gtk_signal_connect(GTK_OBJECT(cancelbut), "clicked", GTK_SIGNAL_FUNC(destroy_main_dialog), NULL);
   gtk_signal_connect(GTK_OBJECT(cancelbut), "clicked", GTK_SIGNAL_FUNC(AskSave), NULL);
   gtk_widget_show(cancelbut);
   
   gtk_widget_show(dialog);
}
/*****************************************************************************/
void add_categories(void) {
   struct conn_categories *tempcat;
   GtkWidget *label;
   
   if(curcat == NULL) {
      label = gtk_list_item_new_with_label("<No Categories>");
      gtk_widget_show(label);
      catlist = g_list_append(catlist, label);
   }

   tempcat = hostcat;
   while(tempcat != NULL) {
      label = gtk_list_item_new_with_label(tempcat->name);
      gtk_widget_show(label);
      catlist = g_list_append(catlist, label);
      tempcat = tempcat->next;
   }
   gtk_list_prepend_items(GTK_LIST(GTK_COMBO(catcombo)->list), catlist);
}
/*****************************************************************************/
void add_sites(void) {
   struct conn_hosts *temphost;
   GtkWidget *label;

   label = gtk_list_item_new_with_label("** Quick Connect **");
   gtk_widget_show(label);
   sitelist = g_list_append(sitelist, label);

   if(curcat != NULL) temphost = curcat->hosts;
   else temphost = NULL;
   while(temphost != NULL) {
      label = gtk_list_item_new_with_label(temphost->hostdescr);
      gtk_widget_show(label);
      sitelist = g_list_append(sitelist, label);
      temphost = temphost->next;
   }
   gtk_list_prepend_items(GTK_LIST(GTK_COMBO(sitecombo)->list), sitelist);
   curhost = NULL;
}
/*****************************************************************************/
static void cattoggle(GtkList *list, GtkWidget *child, gpointer data) {
   gint pos, i;
   
   clear_text();
   pos = gtk_list_child_position(list, child);
   curcat = hostcat;
   if(curcat == NULL) return;
   for(i=0; i<pos; i++) {
      curcat = curcat->next;
      if(curcat == NULL) return;
   }
   gtk_list_remove_items(GTK_LIST(GTK_COMBO(sitecombo)->list), sitelist);
   curhost = NULL;
   sitelist = NULL;
   add_sites();
}                              
/*****************************************************************************/
static void sitetoggle(GtkList *list, GtkWidget *child, gpointer data) {
   gint pos, i;
   
   clear_text();
   pos = gtk_list_child_position(list, child);
   if(pos == 0) {
      curhost = NULL;
      return;
   }
   curhost = curcat->hosts;
   if(curhost == NULL) return;
   for(i=0; i<pos-1; i++) {
      curhost = curhost->next;
      if(curhost == NULL) return;
   }
   gtk_entry_set_text(GTK_ENTRY(hostedit), curhost->hostname);
   gtk_entry_set_text(GTK_ENTRY(portedit), curhost->port);
   gtk_entry_set_text(GTK_ENTRY(diredit), curhost->dir);
   gtk_entry_set_text(GTK_ENTRY(useredit), curhost->user);
   if(strcmp(curhost->pass, "@EMAIL@") == 0) {
      gtk_entry_set_text(GTK_ENTRY(passedit), emailaddr);
   }
   else {
      gtk_entry_set_text(GTK_ENTRY(passedit), curhost->pass);
   }
}
/*****************************************************************************/
static void clear_text(void) {
   if(curhost != NULL) {
      save_txt(hostedit, curhost->hostname, sizeof(curhost->hostname));
      save_txt(portedit, curhost->port, sizeof(curhost->port));
      save_txt(diredit, curhost->dir, sizeof(curhost->dir));
      save_txt(useredit, curhost->user, sizeof(curhost->user));
      save_txt(passedit, curhost->pass, sizeof(curhost->pass));
   }
   gtk_entry_set_text(GTK_ENTRY(hostedit), "");
   gtk_entry_set_text(GTK_ENTRY(portedit), "");
   gtk_entry_set_text(GTK_ENTRY(diredit), "");
   gtk_entry_set_text(GTK_ENTRY(useredit), "");
   gtk_entry_set_text(GTK_ENTRY(passedit), "");
}
/*****************************************************************************/
static void save_txt(GtkWidget *widget, char *dest, size_t size) {
   char *temptxt;

   temptxt = gtk_entry_get_text(GTK_ENTRY(widget));
   if(strcmp(temptxt, dest) != 0) {
      strncpy(dest, temptxt, size);
      dest[size-1] = '\0';
      modified = 1;
   }
}
/*****************************************************************************/
static void adddialog(GtkWidget *widget, int catorsite) {
   if(catorsite) { 
      edit = MakeEditDialog(&newdiag, "Add Category", "Enter the name of the category to create", 
         "Create", doadd, (gpointer) catorsite,
         "Cancel", delete_newdiag, NULL);
   }
   else {
      if(curcat == NULL) return;
      edit = MakeEditDialog(&newdiag, "Add Site", "Enter the name of the site to create",
         "Create", doadd, (gpointer) catorsite,
         "Cancel", delete_newdiag, NULL);
   }
}
/*****************************************************************************/
static void doadd(GtkWidget *widget, int catorsite) {
   struct conn_categories *newcat, *tempcat, *prevcat;
   struct conn_hosts *newhost, *temphost, *prevhost;
   char edttxt[MAXSTR];
   int newpos;
   
   modified = 1;
   strncpy(edttxt, gtk_entry_get_text(GTK_ENTRY(edit)), sizeof(edttxt));
   edttxt[sizeof(edttxt)-1] = '\0';
   clear_text();
   delete_newdiag(NULL, NULL);
   if(catorsite) {
      newpos = 0;
      tempcat = prevcat = hostcat;
      newcat = mymalloc(sizeof(struct conn_categories));
      while(tempcat != NULL) {
         if(strcmp(tempcat->name, edttxt) > 0) {
            newcat->next = tempcat;
            if(prevcat == tempcat) hostcat = newcat;
            else prevcat->next = newcat;
            strncpy(newcat->name, edttxt, sizeof(newcat->name));
            newcat->name[sizeof(newcat->name)-1] = '\0';
            newcat->hosts = NULL;
            break;
         }
         prevcat = tempcat;
         tempcat = tempcat->next;
         newpos++;
      }
      if(tempcat == NULL) {
         if(prevcat == NULL) hostcat = newcat;
         else prevcat->next = newcat;
         newcat->next = NULL;
         newcat->hosts = NULL;
         strncpy(newcat->name, edttxt, sizeof(newcat->name));
         newcat->name[sizeof(newcat->name)-1] = '\0';
      }
      curcat = newcat;

      gtk_list_remove_items(GTK_LIST(GTK_COMBO(catcombo)->list), catlist);
      catlist = NULL;
      add_categories();
   }
   else {
      newpos = 1;
      temphost = prevhost = curcat->hosts;
      newhost = mymalloc(sizeof(struct conn_hosts));
      while(temphost != NULL) {
         if(strcmp(temphost->hostdescr, edttxt) > 0) {
            newhost->next = temphost;
            if(prevhost == temphost) curcat->hosts = newhost;
            else prevhost->next = newhost;
            strncpy(newhost->hostdescr, edttxt, sizeof(newhost->hostdescr));
            newhost->hostdescr[sizeof(newhost->hostdescr)-1] = '\0';
            break;
         }
         prevhost = temphost;
         temphost = temphost->next;
         newpos++;
      }
      if(temphost == NULL) {
         if(prevhost == NULL) curcat->hosts = newhost;
         else prevhost->next = newhost;
         newhost->next = NULL;
         strncpy(newhost->hostdescr, edttxt, sizeof(newhost->hostdescr));
         newhost->hostdescr[sizeof(newhost->hostdescr)-1] = '\0';
      }
      curhost = newhost;

      gtk_list_remove_items(GTK_LIST(GTK_COMBO(sitecombo)->list), sitelist);
      sitelist = NULL;
      add_sites();
   }
}
/*****************************************************************************/
static void deldialog(GtkWidget *widget, int catorsite) {
   char tempstr[MAXSTR];
   
   if(catorsite) {
      if(curcat == NULL) return;
      snprintf(tempstr, sizeof(tempstr), "Are you sure you want to delete the category %s?", curcat->name);
      tempstr[sizeof(tempstr)-1] = '\0';
      MakeYesNoDialog(&newdiag, "Delete Category", tempstr, 2,
         dodel, "Yes", 1, 
         delete_newdiag, "No", NULL);
   }
   else { 
      if(curhost == NULL) return;
      snprintf(tempstr, sizeof(tempstr), "Are you sure you want to delete the site %s?", curhost->hostdescr);
      tempstr[sizeof(tempstr)-1] = '\0';
      MakeYesNoDialog(&newdiag, "Delete Site", tempstr, 2,
         dodel, "Yes", 0,
         delete_newdiag, "No", NULL);
   }
}
/*****************************************************************************/
static void dodel(GtkWidget *widget, int catorsite) {
   struct conn_categories *tempcat, *prevcat;
   struct conn_hosts *temphost, *prevhost;
   
   delete_newdiag(NULL, NULL);
   clear_text();
   modified = 1;
   if(catorsite) {
      tempcat = prevcat = hostcat;
      while(tempcat != NULL) {
         if(tempcat == curcat) break;
         prevcat = tempcat;
         tempcat = tempcat->next;
      }
      if(prevcat == tempcat) hostcat = hostcat->next;
      else prevcat->next = tempcat->next;
      free(curcat);
      curcat = hostcat;

      gtk_list_remove_items(GTK_LIST(GTK_COMBO(catcombo)->list), catlist);
      catlist = NULL;
      add_categories();
   }
   else {
      temphost = prevhost = curcat->hosts;
      while(temphost != NULL) {
         if(temphost == curhost) break;
         prevhost = temphost;
         temphost = temphost->next;
      }
      if(prevhost == temphost) curcat->hosts = curcat->hosts->next;
      else prevhost->next = temphost->next;
      free(curhost);
      curhost = curcat->hosts;
   }

   gtk_list_remove_items(GTK_LIST(GTK_COMBO(sitecombo)->list), sitelist);
   sitelist = NULL;
   add_sites();
}
/*****************************************************************************/
static void rendialog(GtkWidget *widget, int catorsite) {
   char tempstr[MAXSTR];
   
   if(catorsite) {
      if(curcat == NULL) return;
      snprintf(tempstr, sizeof(tempstr), "What do you want to rename %s to?", curcat->name);
      tempstr[sizeof(tempstr)-1] = '\0';
      edit = MakeEditDialog(&newdiag, "Rename Category", tempstr, 
         "Rename", doren, (gpointer) catorsite,
         "Cancel", delete_newdiag, NULL);
   }
   else { 
      if(curhost == NULL) return;
      snprintf(tempstr, sizeof(tempstr), "What do you want to rename %s to?", curhost->hostdescr);
      tempstr[sizeof(tempstr)-1] = '\0';
      edit = MakeEditDialog(&newdiag, "Rename Site", tempstr, 
         "Rename", doren, (gpointer) catorsite,
         "Cancel", delete_newdiag, NULL);
   }
}
/*****************************************************************************/
static void doren(GtkWidget *widget, int catorsite) {
   struct conn_categories *tempcat, *prevcat;
   struct conn_hosts *temphost, *prevhost;
   char edttxt[MAXSTR];
   
   modified = 1;
   strncpy(edttxt, gtk_entry_get_text(GTK_ENTRY(edit)), sizeof(edttxt));
   edttxt[sizeof(edttxt)-1] = '\0';
   clear_text();
   delete_newdiag(NULL, NULL);
   if(catorsite) {
      tempcat = prevcat = hostcat;
      while(tempcat != curcat) {
         prevcat = tempcat;
         tempcat = tempcat->next;
      }
      if(prevcat != tempcat) prevcat->next = tempcat->next;
      else hostcat = hostcat->next;
      strncpy(tempcat->name, edttxt, sizeof(tempcat->name));
      tempcat->name[sizeof(tempcat->name)-1] = '\0';
      tempcat = prevcat = hostcat;
      while(tempcat != NULL) {
         if(strcmp(tempcat->name, edttxt) > 0) {
            curcat->next = tempcat;
            if(tempcat == prevcat) hostcat = curcat;
            else prevcat->next = curcat;
            break;
         }
         prevcat = tempcat;
         tempcat = tempcat->next;
      }
      if(tempcat == NULL) {
         if(prevcat != NULL) prevcat->next = curcat;
         else hostcat = curcat;
         curcat->next = NULL;
      }

      gtk_list_remove_items(GTK_LIST(GTK_COMBO(catcombo)->list), catlist);
      catlist = NULL;
      add_categories();
   }
   else {
      temphost = prevhost = curcat->hosts;
      while(temphost != curhost) {
         prevhost = temphost;
         temphost = temphost->next;
      }
      if(prevhost != temphost) prevhost->next = temphost->next;
      else curcat->hosts = curcat->hosts->next;
      strncpy(temphost->hostdescr, edttxt, sizeof(temphost->hostdescr));
      temphost->hostdescr[sizeof(temphost->hostdescr)-1] = '\0';
      temphost = prevhost = curcat->hosts;
      while(temphost != NULL) {
         if(strcmp(temphost->hostdescr, edttxt) > 0) {
            curhost->next = temphost;
            if(temphost == prevhost) curcat->hosts = curhost;
            else prevhost->next = curhost;
            break;
         }
         prevhost = temphost;
         temphost = temphost->next;
      }
      if(temphost == NULL) {
         if(prevhost != NULL) prevhost->next = curhost;
         else curcat->hosts = curhost;
         curhost->next = NULL;
      }

      gtk_list_remove_items(GTK_LIST(GTK_COMBO(sitecombo)->list), sitelist);
      sitelist = NULL;
      add_sites();
   }
}
/*****************************************************************************/
static void delete_newdiag(GtkWidget *widget, gpointer data) {
   gtk_grab_remove(newdiag);
   gtk_widget_destroy(newdiag);
}
/*****************************************************************************/
static void ok_button(GtkWidget *widget, struct ftp_window_data *wdata) {
   if(wdata->local != -1) ftp_disconnect(wdata, wdata->host, TRUE);

   if(GTK_TOGGLE_BUTTON(anonchk)->active) {
      printf("LOgin as anon\n");
      strncpy(wdata->host->user, ANON_LOGIN, sizeof(wdata->host->user));
      strncpy(wdata->host->passwd, emailaddr, sizeof(wdata->host->passwd));
   }
   else {
      strncpy(wdata->host->user, gtk_entry_get_text(GTK_ENTRY(useredit)), sizeof(wdata->host->user));
      strncpy(wdata->host->passwd, gtk_entry_get_text(GTK_ENTRY(passedit)), sizeof(wdata->host->passwd));
   }
   wdata->host->user[sizeof(wdata->host->user)-1] = '\0';
   wdata->host->passwd[sizeof(wdata->host->passwd)] = '\0';

   strncpy(wdata->host->host, gtk_entry_get_text(GTK_ENTRY(hostedit)), sizeof(wdata->host->host));
   wdata->host->host[sizeof(wdata->host->host)-1] = '\0';

   strncpy(wdata->host->dir, gtk_entry_get_text(GTK_ENTRY(diredit)), sizeof(wdata->host->dir));
   wdata->host->dir[sizeof(wdata->host->dir)-1] = '\0';
   
   wdata->host->port = strtol(gtk_entry_get_text(GTK_ENTRY(portedit)), (char **) NULL, 10);
 
   clear_text();
   destroy_main_dialog(NULL, NULL);
   fix_display();
   if(ftp_connect(wdata, wdata->host, NULL)) ftp_list_files(wdata, wdata->host);
   AskSave(NULL, NULL);
}
/*****************************************************************************/
static void destroy_main_dialog(GtkWidget *widget, gpointer data) {
   gtk_list_remove_items(GTK_LIST(GTK_COMBO(catcombo)->list), catlist);
   catlist = NULL;
   gtk_list_remove_items(GTK_LIST(GTK_COMBO(sitecombo)->list), sitelist);
   sitelist = NULL;
   gtk_widget_destroy(dialog);
}
/*****************************************************************************/
static void AskSave(GtkWidget *widget, gpointer data) {
   if(modified) {
      MakeYesNoDialog(&newdiag, "Save Changes", "Do you want to save the changes made to the config file?", 2,
         dosave, "Yes", NULL, 
         cleanup_data, "No", (void *) 1);
   }
   else cleanup_data(widget, data);
}
/*****************************************************************************/
static void dosave(GtkWidget *widget, gpointer data) {
   cleanup_data(widget, data);
   write_config_file();
}
/*****************************************************************************/
static void cleanup_data(GtkWidget *widget, gpointer data) {
   struct conn_categories *tempcat, *temp1cat;
   struct conn_hosts *temphost;
   
   if(modified) delete_newdiag(NULL, NULL);
   if((int) data) tempcat = hostcat;
   else tempcat = origcat;
   while(tempcat != NULL) {
      while(tempcat->hosts != NULL) {
         temphost = tempcat->hosts;
         tempcat->hosts = tempcat->hosts->next;
         free(temphost);
      }
      temp1cat = tempcat;
      tempcat = tempcat->next;
      free(temp1cat);
   }
   if((int) data) hostcat = origcat;
}
/*****************************************************************************/
static void backup_data(void) {
   struct conn_categories *newcat, *prevcat, *curcat;
   struct conn_hosts *newhost, *prevhost, *curhost;
   
   origcat = NULL;
   curcat = prevcat = hostcat;
   while(curcat != NULL) {
      newcat = mymalloc(sizeof(struct conn_categories));
      *newcat = *curcat;
      newcat->next = NULL;
      if(origcat == NULL) origcat = newcat;
      else prevcat->next = newcat;
      newcat->hosts = NULL;
      curhost = prevhost = curcat->hosts;
      while(curhost != NULL) {
         newhost = mymalloc(sizeof(struct conn_hosts));
         *newhost = *curhost;
         newhost->next = NULL;
         if(newcat->hosts == NULL) newcat->hosts = newhost;
         else prevhost->next = newhost;
         prevhost = newhost;
         curhost = curhost->next;
      }
      prevcat = newcat;
      curcat = curcat->next;
   }
}
/*****************************************************************************/
static void set_userpass_visible(GtkWidget *checkbutton, GtkWidget *entry) {
   gtk_widget_set_sensitive(useredit, !GTK_TOGGLE_BUTTON(anonchk)->active);
   gtk_widget_set_sensitive(passedit, !GTK_TOGGLE_BUTTON(anonchk)->active);
}
/*****************************************************************************/
