Logo Search packages:      
Sourcecode: dcgui version File versions  Download package

do_connect.c

/* dc_gui2 - a GTK+2 GUI for DCTC
 * Copyright (C) 2002 Eric Prevoteau
 *
 * do_connect.c: Copyright (C) Eric Prevoteau <www@a2pb.gotdns.org>
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
/*
$Id: do_connect.c,v 1.13 2004/01/14 18:56:34 ericprev Exp $
*/

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <limits.h>
#include <sys/wait.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <signal.h>
#include <gtk/gtk.h>
#include <gnome.h>

#include "do_connect.h"
#include "gui_layout.h"
#include "main.h"
#include "misc_gtk.h"
#include "dctc_process.h"
#include "init_fnc.h"
#include "timed_out_string.h"
#include "gui_define.h"
#include "gtk_helper.h"

/**********************************/
/* empty some list and tree store */
/**********************************/
/* GTK2: to test */
/*****************/
static void reset_interface(void)
{
      char *clst[]={    "download_clist", /* list store */
                                    "upload_clist",   /* list store */
                                    "queue_clist",          /* list store */
                                    "user_clist",           /* list store */
                                    "uaddr_clist",          /* list store */
                                    NULL};

#if 0
      char *ctree[]={ "gdl_ctree",        /* tree store */
                                    NULL};
#endif


      int i;

      /* unref all user in the global user list and mark them as unconnected */
      gu_unref_model_and_disconnect(gtk_tree_view_get_model(GTK_TREE_VIEW(get_widget_by_widget_name(main_window,"user_clist"))));

      i=0;
      while(clst[i]!=NULL)
      {
            gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(get_widget_by_widget_name(main_window,clst[i])))));
            i++;
      }

#if 0
      i=0;
      while(ctree[i]!=NULL)
      {
            gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(get_widget_by_widget_name(main_window,ctree[i])))));
            i++;
      }
#endif
}

static GHashTable *vars=NULL;

/***********************************/
/* add a new var to the vars array */
/***********************************/
void add_var(char *var_name, char *var_value)
{
      if(vars==NULL)
            vars=g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);

      g_hash_table_insert(vars,g_strdup(var_name),g_strdup(var_value));

      fix_pref_window();
}

/***********************************/
/* get a value from the vars array */
/***********************************/
const char *get_var(char* var_name)
{
      if(vars==NULL)
            return NULL;

      return g_hash_table_lookup(vars,var_name);
}


static void clear_var_array(void)
{
      if(vars!=NULL)
      {
            g_hash_table_destroy(vars);
      }
      vars=g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
}

static guint timeout_hdl=0;
static guint timeout_hdl_master=0;

/**************************************/
/* get the size of the file dir/fname */
/**********************************************/
/* output: file size. On error, 0 is returned */
/**********************************************/
unsigned long get_file_size(const char *dir, char *fname)
{
      char buf[51200];
      struct stat st;

      if(fname[0]!='/')
      {
            sprintf(buf,"%s/%s",dir,fname);
      }
      else
      {
            strcpy(buf,fname);
      }

      if(stat(buf,&st))
            return 0;
      return st.st_size;
}

/******************************************************************************************/
/* update the line i of the clist (clst) with the name 't' in the dir (cur_dir="dl_path") */
/******************************************************************************************/
void update_dl_clist_size(GtkTreeModel *gtm,GtkListStore *gls, GtkTreeIter *iter,const char *cur_dir)
{
      char *t;
      unsigned long full_size;
      unsigned long xfer_id;
      unsigned long start_time,start_pos;
      gboolean has_start;

      if(cur_dir==NULL)
            return;

      gtk_tree_model_get(gtm,iter,DLC_ID_COL,&xfer_id,DLC_SIZE_AS_VAL,&full_size,DLC_LFNAME_COL,&t,
                                                                  DLC_HAS_START_INFO,&has_start,DLC_START_TIME,&start_time,DLC_START_POS,&start_pos,-1);
      if((t!=NULL)&&(strlen(t)))
      {
            char buf[5120];
            unsigned long cur_size;
                              
            cur_size=get_file_size(cur_dir,t);

            if(has_start==FALSE)
                  sprintf(buf,"%15lu (%.2f%%)",cur_size,100.0*(double)cur_size/(double)full_size);
            else
            {
                  double spd;
                  time_t ttl_time;
                  sprintf(buf,"%15lu (%.2f%%)",cur_size,100.0*(double)cur_size/(double)full_size);

                  ttl_time=time(NULL)-(time_t)start_time;
                  
                  spd=((double)cur_size-(double)start_pos)/((double)ttl_time);

                  if(spd<1024.0)
                  {
                        sprintf(buf+strlen(buf)," %.2fB/s",spd);
                  }
                  else if(spd<(1024.0*1024.0))
                  {
                        sprintf(buf+strlen(buf)," %.2fKB/s",spd/1024.0);
                  }
            }
      
            gtk_list_store_set(gls,iter,DLC_SPEED_COL,buf,-1);
      }

      if(t!=NULL)
            free(t);
}

/* this function is called 2 times per second */
static gint update_counter(gpointer data)
{
      const char *cur_dir;
      GtkWidget *w;

      if(current_dctc==NULL)
            goto eofunc;

      /* update download status */
      if((vars==NULL)||(g_hash_table_size(vars)==0))
            goto eofunc;

      cur_dir=get_var("dl_path");
      if(cur_dir!=NULL)
      {
            GtkTreeModel *gtm;
            GtkListStore *gls;
            GtkTreeIter iter;
            int valid;

            w=get_widget_by_widget_name(main_window,"download_clist");
            if(w==NULL)
                  goto eofunc;

            gls=GTK_LIST_STORE(gtm=gtk_tree_view_get_model(GTK_TREE_VIEW(w)));

            valid=gtk_tree_model_get_iter_first(gtm,&iter);
            while(valid)
            {
                  update_dl_clist_size(gtm,gls,&iter,cur_dir);
                  valid=gtk_tree_model_iter_next(gtm,&iter);
            }
      }

      eofunc:
      return TRUE;            /* keep this function alive */
}

/* this function is called 2 times per second */
static gint update_counter_master(gpointer data)
{
      if(gdl_dctc==NULL)
            goto eofunc;

      /* update GDL status */
      {
            static int counter=0;

            if(counter!=20)
                  counter++;
            else
            {
                  counter=0;
                  send_data_to_gdl_dctc("/SLOWGDLLST\n");         /* force a refresh of the GDL list */
            }
      }

      /* update download status */
      timeout_tos();                      /* purge TOS string */

      if((vars==NULL)||(g_hash_table_size(vars)==0))
            goto eofunc;

      eofunc:
      return TRUE;            /* keep this function alive */
}

/*********************************************************/
/* find a DCTC client already connected to the given hub */
/***********************************************************************************/
/* if a client still exists, connect_to_a_running_dctc is called and 1 is returned */
/***********************************************************************************/
/* if no_wait is not set, if a client already exist, the GUI switches to it, else */
/* the client remains unchanged, only the status is returned                      */
/**********************************************************************************/
static int already_connected(const char *hub_address, int no_wait)
{
      DIR *dir;
      struct dirent *obj;

      dir=opendir(dctc_dir->str);
      if(dir==NULL)
            return 0;

      while((obj=readdir(dir))!=NULL)
      {
            if(strlen(obj->d_name)<=(5+8+1))          /* size should be at least enough for "dctc-xxxxxxxx-" */
                  continue;

            if(!strcmp(hub_address,obj->d_name+(5+8+1)))
            {
                  if(no_wait==0)
                        connect_to_a_running_dctc(obj->d_name);
                  closedir(dir);
                  return 1;
            }

      }
      closedir(dir);
      return 0;
}

#if 0
/*********************************************************/
/* add the given opt_name according to widget_name value */
/*********************************************************/
static void add_cmd_line_opt(GPtrArray *cmd_line, GStringChunk **sc,char *widget_name, char *opt_name)
{
      char *t;

      t=get_gtk_entry_by_name(main_window,widget_name);
      if(strlen(t)!=0)
      {
            g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),opt_name));
            g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),t));
      }
      g_free(t);
}
#endif

/******************************************************************************/
/* add the given opt_name according to widget_name value in the given profile */
/******************************************************************************/
/* gconf: ok */
/*************/
static void add_prof_cmd_line_opt(const char *profile_to_use, GPtrArray *cmd_line, GStringChunk **sc,char *widget_name, char *opt_name)
{
      gchar *path;
      GConfValue *gcv;
      gchar *v;

      if(profile_to_use!=NULL)
            path=g_strconcat("/apps/" PROGNAME "/Profile/",profile_to_use,"/",widget_name,NULL);
      else
            path=g_strconcat("/apps/" PROGNAME "/Geometry/",widget_name,NULL);

      gcv=gconf_client_get(engine,path,NULL);
      g_free(path);

      if(gcv==NULL)
            return;

      v=gconf_value_to_string(gcv);
      if(strlen(v))
      {
            g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),opt_name));
            g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),v));
      }

      g_free(v);
      gconf_value_free(gcv);
}

#if 0
/*********************************************************/
/* add the given opt_name according to widget_name value */
/* same version as before except a --precmd prefix is put */
/*********************************************************/
static void add_cmd_line_opt_precmd(GPtrArray *cmd_line, GStringChunk **sc,char *widget_name, char *opt_name)
{
      GtkWidget *w;
      const char *t;

      w=get_widget_by_widget_name(main_window,widget_name);
      if(w==NULL)
      {
            fprintf(stderr,"add_cmd_line_opt_precmd: aborting, unknown widget: %s\n",widget_name);
            exit(1);
      }

      t=gtk_entry_get_text(GTK_ENTRY(w));
      if((t==NULL)||(strlen(t)==0))
            return;

      g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),"--precmd"));

      {
            GString *nw;

            nw=g_string_new(opt_name);
            nw=g_string_append_c(nw,' ');
            nw=g_string_append(nw,t);
            g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),nw->str));
            g_string_free(nw,TRUE);
      }
}
#endif

/******************************************************************************/
/* add the given opt_name according to widget_name value of the given profile */
/* same version as before except a --precmd prefix is put                     */
/******************************************************************************/
/* gconf: ok */
/*************/
static void add_prof_cmd_line_opt_precmd(const char *profile_to_use, GPtrArray *cmd_line, GStringChunk **sc,char *widget_name, char *opt_name)
{
      gchar *path;
      GConfValue *gcv;
      gchar *v;

      if(profile_to_use!=NULL)
            path=g_strconcat("/apps/" PROGNAME "/Profile/",profile_to_use,"/",widget_name,NULL);
      else
            path=g_strconcat("/apps/" PROGNAME "/Geometry/",widget_name,NULL);

      gcv=gconf_client_get(engine,path,NULL);
      g_free(path);

      if(gcv==NULL)
            return;

      v=gconf_value_to_string(gcv);
      if(strlen(v))
      {
            GString *nw;

            g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),"--precmd"));

            nw=g_string_new(opt_name);
            nw=g_string_append_c(nw,' ');
            nw=g_string_append(nw,v);
            g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),nw->str));
            g_string_free(nw,TRUE);
      }

      g_free(v);
      gconf_value_free(gcv);
}

#if 0
/*********************************************************/
/* add the given opt_name according to widget_name value */
/***************************************************************************************************************************/
/* if the GTK_BUTTON is true, on_true1 is appended and if on_true2 is not null, it is also appended (as a 2nd argument)    */
/* if the GTK_BUTTON is false, on_false1 is appended and if on_false2 is not null, it is also appended (as a 2nd argument) */
/***************************************************************************************************************************/
static void add_cmd_line_opt_radio(GPtrArray *cmd_line, GStringChunk **sc,char *widget_name,
                                                                        const char *on_true1, const char *on_true2,
                                                                        const char *on_false1, const char *on_false2)
{
      GtkWidget *w;

      w=get_widget_by_widget_name(main_window,widget_name);
      if(w==NULL)
      {
            fprintf(stderr,"add_cmd_line_opt_radio: aborting, unknown widget: %s\n",widget_name);
            exit(1);
      }

      if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))==TRUE)
      {
            if(on_true1)
            {
                  g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_true1));
                  if(on_true2)
                        g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_true2));
            }
      }
      else
      {
            if(on_false1)
            {
                  g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_false1));
                  if(on_false2)
                        g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_false2));
            }
      }
}
#endif

/******************************************************************************/
/* add the given opt_name according to widget_name value of the given profile */
/***************************************************************************************************************************/
/* if the GTK_BUTTON is true, on_true1 is appended and if on_true2 is not null, it is also appended (as a 2nd argument)    */
/* if the GTK_BUTTON is false, on_false1 is appended and if on_false2 is not null, it is also appended (as a 2nd argument) */
/***************************************************************************************************************************/
/* gconf: ok */
/*************/
static void add_prof_cmd_line_opt_radio(const char *profile_to_use, GPtrArray *cmd_line, GStringChunk **sc,char *widget_name,
                                                                        const char *on_true1, const char *on_true2,
                                                                        const char *on_false1, const char *on_false2)
{
      gchar *path;
      GConfValue *gcv;

      if(profile_to_use!=NULL)
            path=g_strconcat("/apps/" PROGNAME "/Profile/",profile_to_use,"/",widget_name,NULL);
      else
            path=g_strconcat("/apps/" PROGNAME "/Geometry/",widget_name,NULL);

      gcv=gconf_client_get(engine,path,NULL);
      g_free(path);

      if(gcv==NULL)
            return;

      if(gcv->type==GCONF_VALUE_INT)
      {
            int flag_val=gconf_value_get_int(gcv);
            if(flag_val)
            {
                  if(on_true1)
                  {
                        g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_true1));
                        if(on_true2)
                              g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_true2));
                  }
            }
            else
            {
                  if(on_false1)
                  {
                        g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_false1));
                        if(on_false2)
                              g_ptr_array_add(cmd_line,g_string_chunk_insert((*sc),on_false2));
                  }
            }
      }
      gconf_value_free(gcv);
}

/*********************************************/
/* returned string must be freed with g_free */
/*********************************************/
/* gconf: ok */
/*************/
char *get_profile_value_as_string(char *profile_to_use, char *widget_name)
{
      gchar *path;
      GConfValue *gcv;
      gchar *v;

      if(profile_to_use!=NULL)
            path=g_strconcat("/apps/" PROGNAME "/Profile/",profile_to_use,"/",widget_name,NULL);
      else
            path=g_strconcat("/apps/" PROGNAME "/Geometry/",widget_name,NULL);

      gcv=gconf_client_get(engine,path,NULL);
      g_free(path);

      if(gcv==NULL)
            return NULL;

      v=gconf_value_to_string(gcv);
      gconf_value_free(gcv);
      return v;
}

static int get_profile_int_entry(char *profile_to_use, char *widget_name)
{
      gchar *path;
      int t;

      path=g_strconcat("/" PROGNAME "/Geometry/Profile.",profile_to_use,".",widget_name,NULL);
      t=gnome_config_get_int(path);
      g_free(path);
      return t;
}


/***********************************************************/
/* convert the given tos_string into a DCTC (IP) TOS value */
/***********************************************************/
unsigned int tos_string_to_num(const char *tos_string)
{
      if(tos_string==NULL)
      {
            fprintf(stderr,"Warning: tos_string_to_num : NULL tos_string\n");
            return 0;
      }
      if(!strcmp(tos_string, _("Normal")))
      {
            return 0;
      }
      if(!strcmp(tos_string, _("Low Cost")))
      {
            return 2;
      }

      if(!strcmp(tos_string, _("High Reliability")))
      {
            return 4;
      }

      if(!strcmp(tos_string, _("High Throughput")))
      {
            return 8;
      }

      if(!strcmp(tos_string, _("Low Latency")))
      {
            return 16;
      }

      fprintf(stderr,"Warning: tos_string_to_num : unknown tos_string: '%s'\n",tos_string);
      return 0;
}


/********************/
/* start a new DCTC */
/***********************************************************************************************/
/* if no_wait is set, the -l flag is not added and DCTC starts without waiting a UI connection */
/* if profile_to_use==NULL then a profile named "default" is used if it exists and if not the  */
/* current profile is used.                                                                    */
/***********************************************************************************************/
void start_a_new_dctc(const char *hub_address, int no_wait, char *profile_to_use)
{
      GPtrArray *cmd_line;
      GStringChunk *sc;
      int son;
      char *start_path=NULL;

      if(already_connected(hub_address,no_wait))
      {
            if(no_wait==0)
                  gnome_app_error(GNOME_APP(main_window),_("Using client already connected to this hub"));
            return;
      }

      if(profile_to_use==NULL)
      {
            gchar *def_prof=gnome_config_get_string("/" PROGNAME "/ProfileNames/default");
            if(def_prof!=NULL)
            {
                  profile_to_use="default";
                  g_free(def_prof);
            }
      }

      {
            printf("profile to use: %s\n",profile_to_use);
            /* we must create a new dctc with the following arguments and using the given profile */
            /* -n (GTK_ENTRY(nickname_entry)) [if not empty] */
            /* -i (GTK_ENTRY(user_description_entry))  [if not empty] */
            /* -c (GTK_ENTRY(cnx_type_entry)) */
            /* -e (GTK_ENTRY(e_mail_entry)) [if not empty] */
            /* -d (GTK_HSCALE(sim_dl_hscale)) */
            /* -s (one for each clistentry of GTK_CLIST(shared_dir_clist)) [if not empty] */
            /* -o (GTK_ENTRY(size_offset_entry) x GTK_ENTRY(size_offset_unit_entry)) [if size_offset_entry is not empty or null] */
            /* -a (GTK_ENTRY(xfer_host_ip_entry)) [if not empty] */
            /* -p (GTK_ENTRY(incoming_port_number_entry)) [if not empty] */
            /* -g hub_address */
            /* -f [if GTK_RADIO_BUTTON(passive_mode_radio_button) is set] */
            /* -x [if GTK_CHECK_BUTTON(enable_upload_checkbutton) is not set] */
            /* -v VERSION [if GTK_RADIO_BUTTON(override_version_check_button) is set and version_number_entry is not empty */
            /* -u UBL [if GTK_RADIO_BUTTON(ubl_check_button) is set and ubl_entry is not empty */
            cmd_line=g_ptr_array_new();
            sc=g_string_chunk_new(64);

            /* argv[0] */
            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"dctc"));

            /* argv[1] */
            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"dctc"));

            add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"nickname_entry_ent_cnt","-n");
            add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"user_description_entry_ent_cnt","-i");
            add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"cnx_type_entry_ent_cnt","-c");
            add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"e_mail_entry_ent_cnt","-e");
      
            add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"vshare_dir_entry_ent_cnt","-D");
            add_prof_cmd_line_opt_precmd(profile_to_use,cmd_line,&sc,"unodeport_entry_ent_cnt","/UNODEPORT");

            /* -X ? */
            {
                  char *t;

                  t=get_profile_value_as_string(profile_to_use, "socks_proxy_version_combo_entry_ent_cnt");
                  if(t!=NULL)
                  {
                        if(!strcmp(t,_("SOCKS v5")))
                        {
                              g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-X"));
                              add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"socks_address_entry_ent_cnt","-S");
                              add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"socks_port_entry_ent_cnt","-P");
                              add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"socks_userid_entry_ent_cnt","-U");
                              add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"socks_user_passwd_entry_ent_cnt","-K");
                        }
                        else if(!strcmp(t,_("SOCKS v4")))
                        {
                              add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"socks_address_entry_ent_cnt","-S");
                              add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"socks_port_entry_ent_cnt","-P");
                        }
                        else if(!strcmp(t,_("Web proxy")))
                        {
                              char *adr=get_profile_value_as_string(profile_to_use, "socks_address_entry_ent_cnt");

                              if((adr!=NULL)&&(strlen(adr)))
                              {
                                    gchar *ttt;
                                    char *port=get_profile_value_as_string(profile_to_use, "socks_port_entry_ent_cnt");
                                    if((port!=NULL)&&(strlen(port)))
                                          ttt=g_strconcat(adr,":",port,NULL);
                                    else
                                          ttt=g_strdup(adr);

                                    g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-C"));
                                    g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,ttt));

                                    g_free(ttt);

                                    if(port)
                                          g_free(port);
                              }

                              if(adr)
                                    g_free(adr);
                        }

                        g_free(t);
                  }
            }


            /* -d */
            {
                  char *t;

                  t=get_profile_value_as_string(profile_to_use, "sim_dl_hscale_scale_val");
                  if(t!=NULL)
                  {
                        g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-d"));
                        g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,t));
                  }
                  g_free(t);
            }

            /* -s */
            {
                  char *t;

                  t=get_profile_value_as_string(profile_to_use,"hidden_shared_dir_entry_ent_cnt");
                  if((t!=NULL)&&(strlen(t)))
                  {
                        gchar **sh;
                        int i;
                        gchar *t1;

                        if(utf8_mode==TRUE)
                              t1=g_strdup(t);
                        else
                              t1=g_locale_from_utf8(t,-1,NULL,NULL,NULL);
                        
                        sh=g_strsplit(t1,"|",0);
                        g_free(t1);

                        i=0;
                        while(sh[i]!=NULL)
                        {
                              if(strlen(sh[i])!=0)
                              {
                                    g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-s"));
                                    g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,sh[i]));
                              }
                              i++;
                        }
                        g_strfreev(sh);
                  }

                  if(t)
                        g_free(t);
            }

            /* -o */
            {
                  char *t;
                  double value;
      
                  t=get_profile_value_as_string(profile_to_use,"size_offset_entry_ent_cnt");
                  if(t==NULL)
                        fprintf(stderr,"cmd_line_opt: aborting, unknown widget: %s\n","size_offset_entry");
                  else
                  {
                        if(strlen(t)!=0)
                        {
                              value=strtod(t,NULL);
                              g_free(t);
                              t=get_profile_value_as_string(profile_to_use,"size_offset_unit_entry_ent_cnt");
                              if(t==NULL)
                                    fprintf(stderr,"cmd_line_opt: aborting, unknown widget: %s\n","size_offset_unit_entry");
                              else
                              {
                                    if(strlen(t)!=0)
                                    {
                                          char bf[512];
                                          if(!strcmp(t,_("Bytes")))
                                          {
                                                value*=1.0;
                                          }
                                          else if(!strcmp(t,_("KBytes")))
                                          {
                                                value*=1024.0;
                                          }
                                          else if(!strcmp(t,_("MBytes")))
                                          {
                                                value*=1024.0*1024.0;
                                          }
                                          else if(!strcmp(t,_("GBytes")))
                                          {
                                                value*=1024.0*1024.0*1024.0;
                                          }
                                          else
                                          {
                                                printf("unknown unit in size_offset_unit_entry\n");
                                          }

                                          g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-o"));
      
                                          sprintf(bf,"%.0f",value);
                                          g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
                                    }
                                    g_free(t);
                              }
                        }
                        else
                              g_free(t);
                  }
            }
      
            {     /* add the IP only if ignore ip is not set */
                  if(get_profile_int_entry(profile_to_use,"ignore_ipcheckbutton_toggle_val")==FALSE)
                        add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"xfer_host_ip_entry_ent_cnt","-a");
            }
      
            add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"incoming_port_number_entry_ent_cnt","-p");
      
            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-g"));
            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,hub_address));

            {
                  struct
                  {
                        char *widget_name;
                        const char *on_true1;
                        const char *on_true2;
                        const char *on_false1;
                        const char *on_false2;
                  } tbl_opt_radio[]={     {"passive_mode_radio_button_toggle_val", "-f",NULL,NULL,NULL},
                                                            {"enable_upload_checkbutton_toggle_val", NULL,NULL,"-x",NULL},
                                                            {"use_done_dir_checkbutton_toggle_val", "-w",NULL,NULL,NULL},
                                                            {"follow_forcemove_checkbutton_toggle_val", "--precmd","/FOLLOWFORCE","--precmd","/UNFOLLOWFORCE"},
                                                            {"ddl_checkbutton_toggle_val", "--precmd","/DDL","--precmd","/NODDL"},
                                                            {"away_togglebutton_toggle_val", "--precmd","/AWAY","--precmd","/HERE"},
                                                            {"grabip_checkbutton_toggle_val", "--precmd","/GBANIP","--precmd","/NOGBANIP"},
                                                            {"abort_upload_checkbutton_toggle_val", "--precmd","/ABORTLEAVED","--precmd","/NOABORTLEAVED"},
                                                            {"hide_kick_checkbutton_toggle_val", "--precmd","/HIDE_KICK","--precmd","/SHOW_KICK"},
                                                            {"lazykc_checkbutton_toggle_val", "--precmd","/LAZYKC","--precmd","/NOLAZYKC"},
                                                            {"incoming_wake_up_checkbutton_toggle_val", "--precmd","/DFLAG with_incoming_wake_up 1","--precmd","/DFLAG with_incoming_wake_up 0"},
                                                            {"sr_wake_up_checkbutton_toggle_val", "--precmd","/DFLAG with_sr_wake_up 1","--precmd","/DFLAG with_sr_wake_up 0"},
                                                            {"dynipcheckbutton_toggle_val", "--precmd","/DFLAG dynamic_ip 1","--precmd","/DFLAG dynamic_ip 0"},
                                                            {"sharelist_dl_checkbutton_toggle_val", "--precmd","/DFLAG sharelist_dl 1","--precmd","/DFLAG sharelist_dl 0"},
                                                            {"fake_dcpp_checkbutton_toggle_val", "--precmd","/DFLAG fake_dcpp_client 1","--precmd","/DFLAG fake_dcpp_client 0"},
                                                            {NULL,NULL,NULL,NULL,NULL}};
                  int i;
      
                  i=0;
                  while(tbl_opt_radio[i].widget_name!=NULL)
                  {
                        add_prof_cmd_line_opt_radio(profile_to_use,cmd_line, &sc,tbl_opt_radio[i].widget_name,
                                                                              tbl_opt_radio[i].on_true1,tbl_opt_radio[i].on_true2,
                                                                              tbl_opt_radio[i].on_false1,tbl_opt_radio[i].on_false2);
                        i++;
                  }
            }

            /* -v VERSION [if GTK_RADIO_BUTTON(override_version_check_button) is set and version_number_entry is not empty */
            {
                  if(get_profile_int_entry(profile_to_use,"override_version_checkbutton_toggle_val")==TRUE)
                  {
                        add_prof_cmd_line_opt(profile_to_use,cmd_line,&sc,"version_number_entry_ent_cnt","-v");
                  }
            }
      
            /* -u UBL [if GTK_RADIO_BUTTON(ubl_checkbutton) is set and ubl_entry is not empty */
            {
                  GString *xbl_string;
                  char *t;
      
                  xbl_string=g_string_new("");
      
                  /* add UBL value */
                  if(get_profile_int_entry(profile_to_use,"ubl_checkbutton_toggle_val")==TRUE)
                  {
                        t=get_profile_value_as_string(profile_to_use,"ubl_entry_ent_cnt");
                        if((t==NULL)||(strlen(t)==0))
                              g_string_sprintfa(xbl_string,"%d",INT_MAX);
                        else
                              xbl_string=g_string_append(xbl_string,t);
                        if(t)
                              g_free(t);
                  }
                  else
                        g_string_sprintfa(xbl_string,"%d",INT_MAX);

                  xbl_string=g_string_append_c(xbl_string,',');
      
                  /* add DBL value */
                  if(get_profile_int_entry(profile_to_use,"dbl_checkbutton_toggle_val")==TRUE)
                  {
                        t=get_profile_value_as_string(profile_to_use,"dbl_entry_ent_cnt");
                        if((t==NULL)||(strlen(t)==0))
                              g_string_sprintfa(xbl_string,"%d",INT_MAX);
                        else
                              xbl_string=g_string_append(xbl_string,t);
                        if(t)
                              g_free(t);
                  }
                  else
                        g_string_sprintfa(xbl_string,"%d",INT_MAX);

                  xbl_string=g_string_append_c(xbl_string,',');

                  /* add GBL value */
                  if(get_profile_int_entry(profile_to_use,"gbl_checkbutton_toggle_val")==TRUE)
                  {
                        t=get_profile_value_as_string(profile_to_use,"gbl_entry_ent_cnt");
                        if((t==NULL)||(strlen(t)==0))
                              g_string_sprintfa(xbl_string,"%d",INT_MAX);
                        else
                              xbl_string=g_string_append(xbl_string,t);
                        if(t)
                              g_free(t);
                  }
                  else
                        g_string_sprintfa(xbl_string,"%d",INT_MAX);

                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-u"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,xbl_string->str));
                  g_string_free(xbl_string,TRUE);
            }

            /* --precmd "/RECOND xxx" */
            {
                  char bf[512];
      
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                  sprintf(bf,"/RECOND %u",(unsigned int)get_profile_int_entry(profile_to_use,"reconnect_delay_scale_scale_val"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }

            /* --precmd "/REBUILD xxx" */
            {
                  char bf[512];
      
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                  sprintf(bf,"/REBUILD %u",60*(unsigned int)get_profile_int_entry(profile_to_use,"rebuild_delay_scale_scale_val"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }

            /* --precmd "/MAXRUNGDLSRC xxx" */
            {
                  char bf[512];
      
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                  sprintf(bf,"/MAXRUNGDLSRC %u",(unsigned int)get_profile_int_entry(profile_to_use,"maxrunspinbutton_spin_val"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }

            /* --precmd "/GDLASOFFAFT xxx" */
            {
                  char bf[512];
      
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                  sprintf(bf,"/GDLASOFFAFT %u",(unsigned int)get_profile_int_entry(profile_to_use,"maxasoffspinbutton_spin_val"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }

            /* --precmd "/MAXUDL xxx" */
            {
                  char bf[512];
      
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                  sprintf(bf,"/MAXUDL %u",(unsigned int)get_profile_int_entry(profile_to_use,"maxudl_spinbutton_spin_val"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }

            /* --precmd "/GDLASPORT xxx,yyy" */
            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));

            if(get_profile_int_entry(profile_to_use,"limit_as_port_checkbutton_val")==TRUE)
            {
                  char bf[512];
      
                  sprintf(bf,"/GDLASPORTS %u,%u",
                                                (unsigned int)get_profile_int_entry(profile_to_use,"low_as_port_spinbutton_spin_val"),
                                                (unsigned int)get_profile_int_entry(profile_to_use,"up_as_port_spinbutton_spin_val")
                              );
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }
            else
            {
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"/GDLASPORTS 0,0"));  /* no range limit */
            }


            /* --precmd "/DFLAG min_delay_between_search xxx" */
            {
                  char bf[512];
      
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                  sprintf(bf,"/DFLAG min_delay_between_search %u",(unsigned int)get_profile_int_entry(profile_to_use,"min_delay_between_search_spinbutton_spin_val"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }


            /* detach from tty */
            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-t"));

            /* wait GUI connection */
            if(no_wait==0)
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-l"));

            /* --precmd "/DFLAG min_gdl_wake_up_delay xxx" */
            {
                  char *t;
                  t=get_profile_value_as_string(profile_to_use,"min_gdl_wake_up_delay_entry_ent_cnt");
                  if(t==NULL)
                        fprintf(stderr,"cmd_line_opt: aborting, unknown widget: %s\n","min_gdl_wake_up_delay_entry");
                  else
                  {
                        char bf[512];
                        unsigned int v;
                        v=strtoul(t,NULL,10);
                        if(v<30)
                              v=30;
      
                        g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                        sprintf(bf,"/DFLAG min_gdl_wake_up_delay %u",v);
                        g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
                        g_free(t);
                  }
            }

            /* add TOS values */
            {
                  char bf[512];
                  char *t1,*t2,*t3,*t4;
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"-T"));
      
                  sprintf(bf,"%u,%u,%u,%u",
                              tos_string_to_num(t1=get_profile_value_as_string(profile_to_use,"hub_tos_entry_ent_cnt")),
                              tos_string_to_num(t2=get_profile_value_as_string(profile_to_use,"udp_tos_entry_ent_cnt")),
                              tos_string_to_num(t3=get_profile_value_as_string(profile_to_use,"dl_tos_entry_ent_cnt")),
                              tos_string_to_num(t4=get_profile_value_as_string(profile_to_use,"ul_tos_entry_ent_cnt")));

                  if(t1) g_free(t1);
                  if(t2) g_free(t2);
                  if(t3) g_free(t3);
                  if(t4) g_free(t4);
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }

            /* --precmd "/GDLMETDIR dir" */
            {
                  char *var_textvar;
                  char bf[512];

                  var_textvar=get_profile_value_as_string(profile_to_use,"lmule_temp_ent_cnt");
                  if(var_textvar)
                  {
                        g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));

                        if(utf8_mode==TRUE)
                        {
                              sprintf(bf,"/GDLMETDIR %s",var_textvar);
                        }
                        else
                        {
                              gchar *t1;
                              t1=g_locale_from_utf8(var_textvar,-1,NULL,NULL,NULL);
                              sprintf(bf,"/GDLMETDIR %s",t1);
                              g_free(t1);
                        }
                        g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
                        g_free(var_textvar);
                  }
            }

            /* --precmd "/GDLMETPOLL xxx" */
            {
                  char bf[512];
      
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                  sprintf(bf,"/GDLMETPOLL %u",(unsigned int)get_profile_int_entry(profile_to_use,"lmule_scan_spinbutton_spin_val"));
                  g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
            }

            /* add DC++ fake version */
            {
                  gchar *var_textvar;
                  char bf[512];

                  var_textvar=get_profile_value_as_string(profile_to_use,"fake_dcpp_version_entry_ent_cnt");
                  if(var_textvar)
                  {
                        if(strlen(var_textvar))
                        {
                              g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
                              sprintf(bf,"/DFLAG fake_dcpp_version %s",var_textvar);
                              g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,bf));
                        }
                        g_free(var_textvar);
                  }
            }

            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"--precmd"));
            g_ptr_array_add(cmd_line,g_string_chunk_insert(sc,"/DFLAG disp_user 0"));

            /* ... */
            g_ptr_array_add(cmd_line,NULL);           /* end the command line */

            /* get the path from where dctc must be started */
            {
                  start_path=get_profile_value_as_string(profile_to_use,"dl_dir_entry_ent_cnt");
                  if(start_path==NULL)
                        start_path=g_strdup(".");
                  else if(strlen(start_path)==0)
                  {
                        g_free(start_path);
                        start_path=g_strdup(".");
                  }
                  printf("start_path: %s\n",start_path);
            }
      }

      /* reset the away toggle */
      {
            GtkWidget *w;

            w=get_widget_by_widget_name(main_window,"away_togglebutton");
            if(w!=NULL)
            gtk_toggle_button_set_active(
                        GTK_TOGGLE_BUTTON(
                              get_widget_by_widget_name(main_window,"away_togglebutton")),
                        FALSE);
      }

      switch(son=fork())
      {
            case -1:
                              gnome_app_error(GNOME_APP(main_window),_("Fork fails. Unable to start a new client."));
                              break;

            case 0:     /* the son */
                              {
                                    chdir(start_path);
                                    execvp("dctc",(char**)cmd_line->pdata);
                              }
                              _exit(1);
                              break;

            default: /* the GUI */
                              {     
                                    GString *wanted;
                                    int i;
                                    char dc_name[5120];
                                    int have=0;
                                    int on_error=0;
                                    struct stat st;

                                    sprintf(dc_name,"dctc-%08X-%s",son,hub_address);
                                    wanted=g_string_new(dctc_dir->str);
                                    g_string_sprintfa(wanted,"/%s",dc_name);

                                    for(i=0;i<180;i++)
                                    {
                                          if(stat(wanted->str,&st)==0)
                                          {
                                                have=1;
                                                break;
                                          }

                                          /* child has exited ? */
                                          if(waitpid(son,NULL,WNOHANG)==-1)
                                          {
                                                on_error=1;
                                                break;
                                          }

                                          usleep( (1000000/180)*20);    /* 20 seconds sliced into 180 parts */
                                    }

                                    g_string_free(wanted,TRUE);
                                    if(have)
                                    {
                                          if(no_wait==0)
                                                connect_to_a_running_dctc(dc_name);
                                    }
                                    else
                                    {
                                          kill(son,SIGKILL);

                                          if(!on_error)
                                                gnome_app_error(GNOME_APP(main_window),_("new DCTC client fails to connect in 20 seconds."));
                                          else
                                                gnome_app_error(GNOME_APP(main_window),_("hub has closed its connection."));
                                    }
                              }
                              break;
                        
      }
      {
            int i;
            /* bug fixed by Glen Koundry: the NULL at the end of the array is no more displayed */
            for(i=0;i<cmd_line->len-1;i++)
            {
                  printf("%s\n",(char*)g_ptr_array_index(cmd_line,i));
            }
      }
      g_ptr_array_free(cmd_line,TRUE);
      g_string_chunk_free(sc);

      if(start_path)
            g_free(start_path);
}

char last_known_running_dctc_name[512]={'\0'};

/**************************************/
/* connect to an already running DCTC */
/**************************************/
void connect_to_a_running_dctc(char *dctc_entry)
{
      GString *fpath;
      int a;
      struct sockaddr_un name;
      int nw_dctc_fd;

      /* close the connection to the current dctc if exists */
      close_dctc_com(&current_dctc);

      reset_interface();

      nw_dctc_fd=socket(AF_UNIX,SOCK_STREAM,0);
      if(nw_dctc_fd==-1)
      {
            perror("connect_to_running_dctc - socket");
            return;
      }

      strcpy(last_known_running_dctc_name,dctc_entry);

      fpath=g_string_new(dctc_dir->str);
      g_string_sprintfa(fpath,"/%s",dctc_entry);

      current_dctc=create_new_dctc_com(nw_dctc_fd, (const char*)(fpath->str));

      name.sun_family=AF_UNIX;
      strcpy(name.sun_path,fpath->str);

      a=connect(current_dctc->dctc_fd,(void *)&name,sizeof(struct sockaddr_un));
      if(a==-1)
      {
            int err=errno;

            GString *emsg;

            emsg=g_string_new(_("Unable to contact this client: "));
            g_string_sprintfa(emsg,_("%s\nThis client is probably already dead."),strerror(err));
            
            gnome_app_error(GNOME_APP(main_window),emsg->str);
            g_string_free(emsg,TRUE);
            close_dctc_com(&current_dctc);
            return;
      }
      
      current_dctc->tag_read=gdk_input_add(current_dctc->dctc_fd, GDK_INPUT_READ, process_data_from_dctc, &current_dctc);

      printf("a\n");
      clear_var_array();

      /* get the current hubname, the user list and the transfer list */
      send_data_to_dctc("/VARS\n/ULIST\n/HUBNAME\n/XFER\n");

      if(timeout_hdl==0)
            timeout_hdl=gtk_timeout_add(500,update_counter,NULL);

      g_string_free(fpath,TRUE);

      connect_to_the_master_dctc();
}

/*********************************************/
/* (re)connect to the master DCTC (gdl dctc) */
/*********************************************/
void connect_to_the_master_dctc(void)
{
      GString *fpath;
      int a;
      struct sockaddr_un name;
      int nw_dctc_fd;

      /* keep the current structure if it exists and it has a valid socket fd */
      if((gdl_dctc!=NULL)&&(gdl_dctc->dctc_fd!=-1))
            return;

      close_dctc_com(&gdl_dctc);

      nw_dctc_fd=socket(AF_UNIX,SOCK_STREAM,0);
      if(nw_dctc_fd==-1)
      {
            perror("connect_to_running_dctc - socket");
            return;
      }

      fpath=g_string_new(dctc_dir->str);
      g_string_sprintfa(fpath,"/master");

      gdl_dctc=create_new_dctc_com(nw_dctc_fd, (const char*)(fpath->str));

      name.sun_family=AF_UNIX;
      strcpy(name.sun_path,fpath->str);

      a=connect(gdl_dctc->dctc_fd,(void *)&name,sizeof(struct sockaddr_un));
      if(a==-1)
      {
            perror("connect_to_the_master_dctc");
            close_dctc_com(&gdl_dctc);
            return;
      }
      
      gdl_dctc->tag_read=gdk_input_add(gdl_dctc->dctc_fd, GDK_INPUT_READ, process_data_from_gdl_dctc, &gdl_dctc);

#if 0
      printf("b\n");
      clear_var_array();
#endif

      /* get the current hubname, the user list and the transfer list */
      send_data_to_gdl_dctc("/GDLLST\n/UADDRLST\n");

      if(timeout_hdl_master==0)
            timeout_hdl_master=gtk_timeout_add(500,update_counter_master,NULL);

      g_string_free(fpath,TRUE);

      /* refresh done list */
#if 0
      load_all_done_lists();
#endif
}

/*************************************************************************/
/* send the redirection message to force the client to go to another hub */
/*************************************************************************/
void go_to_another_hub(const char *hubname)
{
      gchar *c;

      c=g_strconcat("/GOTO ",hubname,"\n",NULL);
      send_data_to_dctc(c);
      g_free(c);

      /* reset all previous hub parameters */
      reset_interface();
      printf("c\n");
      clear_var_array();            /* this should not be necessary because we remain on the same client */

      /* get the current hubname, the user list and the transfer list */
      send_data_to_dctc("VARS\n/ULIST\n/HUBNAME\n/XFER\n");
      send_data_to_gdl_dctc("SLOWGDLLST\n/UADDRLST\n");
}


Generated by  Doxygen 1.6.0   Back to index