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

bittorrent_clist.c

/* dc_gui2 - a GTK+2 GUI for DCTC
 * Copyright (C) 2002 Eric Prevoteau
 *
 * bittorrent_clist.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: bittorrent_clist.c,v 1.5 2004/01/20 16:16:24 ericprev Exp $
*/

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <dirent.h>
#include <signal.h>
#include <gnome.h>

#include "gtkcellrenderertextx.h"
#include "misc_gtk.h"
#include "bittorrent_clist.h"
#include "main.h"
#include "gui_define.h"
#include "macro.h"
#include "bt2dc_gui2_io.h"

typedef struct
{
      gboolean in_dir;        /* TRUE if the entry is visible in the directory */
      gboolean in_list;       /* TRUE if the entry is in the clist */
      gboolean is_new;        /* TRUE if the entry was just created */
      pid_t bt_pid;
      time_t last_update;
      BT_DL_STRUCT *map;      /* mapped file */
} BT_ENTRY;

static GArray *available_bt_entry=NULL;

/***************************************************************************************/
/* set the in_dir and is_new flags of all entries of available_bt_entry array to FALSE */
/***************************************************************************************/
static void clear_dir_and_new_flags(void)
{
      int i;
      for(i=0;i<available_bt_entry->len;i++)
      {
            g_array_index(available_bt_entry,BT_ENTRY,i).in_dir=FALSE;
            g_array_index(available_bt_entry,BT_ENTRY,i).is_new=FALSE;
      }
}

/************************************************************************************/
/* get the array index of an entry of the available_bt_entry array from the process */
/************************************************************************************/
/* output: array index or -1 */
/*****************************/
static int get_idx_by_pid(int pid)
{
      int i;

      for(i=0;i<available_bt_entry->len;i++)
      {
            if(g_array_index(available_bt_entry,BT_ENTRY,i).bt_pid==pid)
                  return i;
      }
      return -1;
}

/********************************************************************************************************/
/* search inside the available_bt_entry array an entry with an map->original_url matching the given one */
/********************************************************************************************************/
/* ouput: -1=not found else the pid of the entry (which can be the one of a not running client) */
/************************************************************************************************/
pid_t get_bt_pid_by_bt_url(const char *url)
{
      int i;

      for(i=0;i<available_bt_entry->len;i++)
      {
            BT_ENTRY *be;

            be=&(g_array_index(available_bt_entry,BT_ENTRY,i));
            if((be->map!=NULL)&&(!strcmp(url,be->map->original_url)))
                  return be->bt_pid;
      }
      return -1;
}

/*****************************************************************************************/
/* search inside the available_bt_entry array an entry with a pid matching the given one */
/*****************************************************************************************/
/* output: NULL=not found else a copy of the url of the entry (must be free() at end) */
/**************************************************************************************/
char *get_bt_url_by_bt_pid(const pid_t pid)
{
      int i;

      for(i=0;i<available_bt_entry->len;i++)
      {
            BT_ENTRY *be;

            be=&(g_array_index(available_bt_entry,BT_ENTRY,i));
            if((be->map!=NULL)&&(be->bt_pid==pid))
                  return strdup(be->map->original_url);
      }
      return NULL;
}

/************************************/
/* open and map the given new entry */
/************************************/
static void add_new_entry(const char *filepath, int proc_pid)
{
      int fd;
      BT_ENTRY new_bt;

      fd=open(filepath,O_RDWR);
      if(fd==-1)
      {
            fprintf(stderr,"Fail to open file '%s': %s\n",filepath,strerror(errno));
            return;
      }

      new_bt.in_dir=TRUE;
      new_bt.in_list=FALSE;
      new_bt.is_new=TRUE;
      new_bt.bt_pid=proc_pid;
      new_bt.last_update=0;
      new_bt.map=mmap(NULL,sizeof(BT_DL_STRUCT),PROT_READ|PROT_WRITE,MAP_SHARED, fd,0);
      if(new_bt.map==MAP_FAILED)
      {
            fprintf(stderr,"Fail to map file '%s': %s\n",filepath,strerror(errno));
            close(fd);
            return;
      }

      close(fd);
      g_array_append_val(available_bt_entry,new_bt);
}

/**************************************************************************/
/* remove all entries with in_dir=FALSE from the clist and from the array */
/**************************************************************************/
static void remove_dead_entries(void)
{
      GtkTreeView *gtv;
      GtkTreeModel *gtm;
      GtkListStore *gls;
      GtkTreeIter iter;
      GtkWidget *w;
      int i;

      w=get_widget_by_widget_name(main_window,"bittorrent_treeview");
      gls=GTK_LIST_STORE(gtm=gtk_tree_view_get_model(gtv=GTK_TREE_VIEW(w)));

      i=gtk_tree_model_iter_n_children(gtm,NULL)-1;
      while(i>=0)
      {
            if(gtk_tree_model_iter_nth_child(gtm,&iter,NULL,i)==TRUE)
            {
                  gint proc_pid;
                  int idx;
                  
                  gtk_tree_model_get(gtm,&iter,BTC_BITTORRENT_PID,&proc_pid,-1);
                  if((idx=get_idx_by_pid(proc_pid))==-1)
                  {
                        /* entry no more exists */
                        gtk_list_store_remove(gls,&iter);         /* delete it from the list */
                                                                                                      /* and delete its entry */
                  }
                  else
                  {
                        if(g_array_index(available_bt_entry,BT_ENTRY,idx).in_dir==FALSE)
                        {
                              /* entry no more exists */
                              gtk_list_store_remove(gls,&iter);         /* delete it from the list */
                                                                                                            /* and delete its entry */

                              munmap(g_array_index(available_bt_entry,BT_ENTRY,idx).map,sizeof(BT_DL_STRUCT));
                              g_array_remove_index_fast(available_bt_entry,idx);
                        }
                  }

                  i--;
            }
      }
}

/*********************************************************************/
/* check if the given pid is the one of a running bittorrent process */
/*********************************************************************/
/* output: TRUE=dead, FALSE=running */
/************************************/
gboolean is_a_dead_bittorrent(pid_t bt_pid)
{
      int ret=FALSE;          /* process is running by default */
      int fd;

      /* create a path "$HOME/.dc_gui2/bt2dc_gui2/bt_xfer.%d.lock" and try to lock it */
      /* if it is not lockable, the process is running */
      GString *lpath;

      lpath=g_string_new(bt2dc_gui2_directory->str);  /* $HOME/.dc_gui2/bt2dc_gui2 */
      g_string_sprintfa(lpath,"/bt_xfer.%d.lock",bt_pid);
      
      fd=open(lpath->str,O_RDWR);
      if(fd!=-1)
      {     /* ignore errors, assume the process is still running */
            int o;

            o=lockf(fd,F_TEST,1);
            if(o==0)          /* not locked ? */
            {
                  ret=TRUE;
            }
            close(fd);
      }
      else
      {
            fprintf(stderr,"is_a_dead_bittorrent: %s: %s\n",lpath->str,strerror(errno));
      }
      g_string_free(lpath,TRUE);

      return ret;
}

/********************************/
/* delete data of a dead client */
/***********************************************************************************************************/
/* the function deletes the .lock file and the info file of the bt client and can also the downloaded data */
/***********************************************************************************************************/
/* input: pid of the dead client                                                                      */
/*        with_dled_data: TRUE => all files, including downloaded data, FALSE= only map and lock file */
/******************************************************************************************************/
void delete_bittorrent_file(pid_t bt_pid, gboolean with_dled_data)
{
      int idx;

      if((idx=get_idx_by_pid(bt_pid))!=-1)
      {
            /* it is a known bt process */
            GString *lpath;

            if(with_dled_data==TRUE)
            {
                  BT_ENTRY *be;
                  be=&(g_array_index(available_bt_entry,BT_ENTRY,idx));
                  if(strlen(be->map->downloadTo))
                  {
                        unlink(be->map->downloadTo);        /* discard already downloaded data */
                  }
            }
            
            /* unlink the map file and the lock file */
            lpath=g_string_new(bt2dc_gui2_directory->str);  /* $HOME/.dc_gui2/bt2dc_gui2 */
            g_string_sprintfa(lpath,"/bt_xfer.%d",bt_pid);
            unlink(lpath->str);

            g_string_append(lpath,".lock");
            unlink(lpath->str);

            g_string_free(lpath,TRUE);
      }
}

/*********************************************************************************************/
/* append the first error message (ending by |, \0 or reaching max len) to the given string) */
/*********************************************************************************************/
static void append_first_error_message(GString *str, BT_ENTRY *be)
{
      char *t=be->map->error_string;
      int nb=MAX_ERROR_LEN;

      while((nb>0)&&(*t!='|'))
      {
            g_string_append_c(str,*t);
            t++;
            nb--;
      }
}

/********************************************************************/
/* build an UTF8 status string mixing BT status and BT latest error */
/********************************************************************/
/* output: utf8 (result of g_locale_to_utf8) */
/*********************************************/
static gchar *build_status_string(BT_ENTRY *be)
{
      GString *str;
      gchar *utf8;

      str=g_string_new("");

      if((strlen(be->map->status))==0)
      {
            append_first_error_message(str,be);
      }
      else
      {
            g_string_append(str,be->map->status);

            if((be->map->downRate==0.0)&&(be->map->error_string[0]!='\0')&&(be->map->error_string[0]!='|'))
            {
                  g_string_append_c(str,';');
                  append_first_error_message(str,be);
            }
      }
      utf8=g_locale_to_utf8(str->str,str->len,NULL,NULL,NULL);
      g_string_free(str,TRUE);
      return utf8;
}

/**************************************************************************************************************************************************/
/* for each entry of the array with in_list=TRUE, check if they are still running and update their entry in the clist (and the time in the array) */
/**************************************************************************************************************************************************/
static void update_listed_entries(void)
{
      int i=0;
      GtkWidget *w;
      GtkTreeModel *gtm;
      GtkListStore *gls;

      w=get_widget_by_widget_name(main_window,"bittorrent_treeview");
      gls=GTK_LIST_STORE(gtm=gtk_tree_view_get_model(GTK_TREE_VIEW(w)));

      while(i<available_bt_entry->len)
      {
            BT_ENTRY *be;

            be=&(g_array_index(available_bt_entry,BT_ENTRY,i));
            if((be!=NULL)&&(be->in_list==TRUE))
            {
                  int j;
                  gint row_btpid;

                  /* get the iter of the row having the same BTC_BITTORRENT_PID content as bt_pid */
                  j=gtk_tree_model_iter_n_children(gtm,NULL)-1;
                  while(j>=0)
                  {
                        GtkTreeIter iter;
                        if(gtk_tree_model_iter_nth_child(gtm,&iter,NULL,j)==TRUE)
                        {
                              gtk_tree_model_get(gtm,&iter,BTC_BITTORRENT_PID,&row_btpid,-1);

                              if(row_btpid==be->bt_pid)
                              {
                                    /* we now have an array entry and its matching displayed row */
                                    /* we must: 1) check if the process still exists */
                                    /*          2) check if the display is accurate */
                                    if(be->map->client_is_running==TRUE)
                                    {
                                          if(is_a_dead_bittorrent(be->bt_pid))
                                          {
                                                be->map->client_is_running=FALSE;
                                                be->map->last_updated_time=time(NULL);
                                          }
                                    }

                                    if(be->last_update!=be->map->last_updated_time)
                                    {
                                          gchar *utf8_fname;
                                          char fsize[128];
                                          guint64 adapted_size;

                                          be->last_update=be->map->last_updated_time;
                                          if(strlen(be->map->file))
                                                utf8_fname=g_locale_to_utf8(be->map->file,-1,NULL,NULL,NULL);
                                          else
                                          {
                                                char *partial_url;
                        
                                                partial_url=strrchr(be->map->original_url,'/');
                                                if(partial_url!=NULL)
                                                      partial_url++;
                                                else
                                                      partial_url=be->map->original_url;
                                                utf8_fname=g_locale_to_utf8(partial_url,-1,NULL,NULL,NULL);
                                          }

#ifndef NO_PRINTF_LOCALE
                                          sprintf(fsize,"%'lld b = ",be->map->filesize);
#else
                                          sprintf(fsize,"%lld b = ",be->map->filesize);
#endif
                                          adapted_size=be->map->filesize;
                                          if(adapted_size>1024)
                                          {
                                                adapted_size/=1024;
                                                if(adapted_size>1024)
                                                {
                                                      adapted_size/=1024;
                                                      if(adapted_size>1024)
                                                      {
                                                            double final_size=be->map->filesize;
                                                            final_size/=(1024*1024*1024);
                                                            sprintf(fsize+strlen(fsize),"%.2lfGB",final_size);          /* we want 2 decimal number unlike other rounded size */
                                                      }
                                                      else
                                                      {
                                                            sprintf(fsize+strlen(fsize),"%lldMB",adapted_size);
                                                      }
                                                }
                                                else
                                                {
                                                      sprintf(fsize+strlen(fsize),"%lldKB",adapted_size);
                                                }
                                          }


                                          /* static columns: BTC_FILENAME_COL, BTC_SIZE_COL, BTC_BITTORRENT_PID */
                                          if(be->map->client_is_running==TRUE)
                                          {
                                                char dl_txt[64];
                                                char ul_txt[64];
                                                gchar *utf8;

#ifndef NO_PRINTF_LOCALE
                                                if(be->map->downRate>=0.01)
                                                      sprintf(dl_txt,"%'.2lf KB/s",be->map->downRate/1024);
                                                else
                                                      strcpy(dl_txt,_("stalled"));
                                                if(be->map->upRate>=0.01)
                                                      sprintf(ul_txt,"%'.2lf KB/s",be->map->upRate/1024);
                                                else
                                                      strcpy(ul_txt,_("stalled"));
#else
                                                if(be->map->downRate>=0.01)
                                                      sprintf(dl_txt,"%.2lf KB/s",be->map->downRate/1024);
                                                else
                                                      strcpy(dl_txt,_("stalled"));
                                                if(be->map->upRate>=0.01)
                                                      sprintf(ul_txt,"%.2lf KB/s",be->map->upRate/1024);
                                                else
                                                      strcpy(ul_txt,_("stalled"));
#endif

                                                utf8=build_status_string(be);
                                                /* update as running client */
                                                if(be->map->done==FALSE)
                                                {
                                                      gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_fname,
                                                                                                                  BTC_SIZE_COL,fsize,
                                                                                                                  BTC_STATUS_COL,utf8,
                                                                                                                  BTC_DL_SPEED_COL,dl_txt,
                                                                                                                  BTC_UL_SPEED_COL,ul_txt,
                                                                                                                  BTC_DL_SPEED,(gfloat)be->map->downRate,
                                                                                                                  BTC_UL_SPEED,(gfloat)be->map->upRate,
                                                                                                                  BTC_BACKGROUND_COL,NULL,
                                                                                                                  -1);
                                                }
                                                else
                                                {
                                                      if(be->map->percentDone==0.0)
                                                      {
                                                            /* client running: fatal error */
                                                            gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_fname,
                                                                                                                        BTC_SIZE_COL,fsize,
                                                                                                                        BTC_STATUS_COL,utf8,
                                                                                                                        BTC_DL_SPEED_COL,dl_txt,
                                                                                                                        BTC_UL_SPEED_COL,ul_txt,
                                                                                                                        BTC_DL_SPEED,(gfloat)be->map->downRate,
                                                                                                                        BTC_UL_SPEED,(gfloat)be->map->upRate,
                                                                                                                        BTC_BACKGROUND_COL,"IndianRed1",
                                                                                                                        -1);
                                                      }
                                                      else
                                                      {
                                                            /* client running: successful end */
                                                            gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_fname,
                                                                                                                        BTC_SIZE_COL,fsize,
                                                                                                                        BTC_STATUS_COL,utf8,
                                                                                                                        BTC_DL_SPEED_COL,_("over"),
                                                                                                                        BTC_UL_SPEED_COL,ul_txt,
                                                                                                                        BTC_DL_SPEED,(gfloat)be->map->downRate,
                                                                                                                        BTC_UL_SPEED,(gfloat)be->map->upRate,
                                                                                                                        BTC_BACKGROUND_COL,"SeaGreen1",
                                                                                                                        -1);
                                                      }
                                                }
                                                g_free(utf8);
                                          }
                                          else
                                          {
                                                gchar *utf8;
                                                utf8=g_locale_to_utf8(be->map->status,-1,NULL,NULL,NULL);

                                                /* update as inactive client */
                                                gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_fname,
                                                                                                            BTC_SIZE_COL,fsize,
                                                                                                            BTC_STATUS_COL,utf8,
                                                                                                            BTC_DL_SPEED_COL,"--", 
                                                                                                            BTC_UL_SPEED_COL,"--",
                                                                                                            BTC_DL_SPEED,(gfloat)0,
                                                                                                            BTC_UL_SPEED,(gfloat)0,
                                                                                                            BTC_BACKGROUND_COL,"LightGoldenrod1",
                                                                                                            -1);
                                                g_free(utf8);
                                          }
                                          g_free(utf8_fname);
                                    }
                                    break;
                              }
                        }
                        j--;
                  }
            }
            i++;
      }
}

/**********************************************************************/
/* for each entry of the array with is_new=TRUE, add them to the list */
/**********************************************************************/
static void add_new_entries(void)
{
      int i=0;
      GtkWidget *w;
      GtkTreeModel *gtm;
      GtkListStore *gls;

      w=get_widget_by_widget_name(main_window,"bittorrent_treeview");
      gls=GTK_LIST_STORE(gtm=gtk_tree_view_get_model(GTK_TREE_VIEW(w)));

      while(i<available_bt_entry->len)
      {
            BT_ENTRY *be;

            be=&(g_array_index(available_bt_entry,BT_ENTRY,i));
            if((be!=NULL)&&(be->is_new==TRUE))
            {
                  GtkTreeIter iter;
                  gchar *utf8_file;
                  gchar *utf8_status;
                  char fsize[128];
                  guint64 adapted_size;

                  be->is_new=FALSE;
                  be->in_list=TRUE;
                  be->last_update=be->map->last_updated_time;

                  gtk_list_store_append(gls,&iter);

                  if(strlen(be->map->file))
                        utf8_file=g_locale_to_utf8(be->map->file,-1,NULL,NULL,NULL);
                  else
                  {
                        char *partial_url;

                        partial_url=strrchr(be->map->original_url,'/');
                        if(partial_url!=NULL)
                              partial_url++;
                        else
                              partial_url=be->map->original_url;
                        utf8_file=g_locale_to_utf8(partial_url,-1,NULL,NULL,NULL);
                  }
                  utf8_status=build_status_string(be);
#ifndef NO_PRINTF_LOCALE
                  sprintf(fsize,"%'lld b = ",be->map->filesize);
#else
                  sprintf(fsize,"%lld b = ",be->map->filesize);
#endif
                  adapted_size=be->map->filesize;
                  if(adapted_size>1024)
                  {
                        adapted_size/=1024;
                        if(adapted_size>1024)
                        {
                              adapted_size/=1024;
                              if(adapted_size>1024)
                              {
                                    double final_size=be->map->filesize;
                                    final_size/=(1024*1024*1024);
                                    sprintf(fsize+strlen(fsize),"%.2lfGB",final_size);          /* we want 2 decimal number unlike other rounded size */
                              }
                              else
                              {
                                    sprintf(fsize+strlen(fsize),"%lldMB",adapted_size);
                              }
                        }
                        else
                        {
                              sprintf(fsize+strlen(fsize),"%lldKB",adapted_size);
                        }
                  }

                  if(be->map->client_is_running==TRUE)
                  {
                        char dl_txt[64];
                        char ul_txt[64];

#ifndef NO_PRINTF_LOCALE
                        if(be->map->downRate>=0.01)
                              sprintf(dl_txt,"%'.2lf KB/s",be->map->downRate/1024);
                        else
                              strcpy(dl_txt,_("stalled"));
                        if(be->map->upRate>=0.01)
                              sprintf(ul_txt,"%'.2lf KB/s",be->map->upRate/1024);
                        else
                              strcpy(ul_txt,_("stalled"));
#else
                        if(be->map->downRate>=0.01)
                              sprintf(dl_txt,"%.2lf KB/s",be->map->downRate/1024);
                        else
                              strcpy(dl_txt,_("stalled"));
                        if(be->map->upRate>=0.01)
                              sprintf(ul_txt,"%.2lf KB/s",be->map->upRate/1024);
                        else
                              strcpy(ul_txt,_("stalled"));
#endif

                        /* update as running client */
                        if(be->map->done==FALSE)
                        {
                              gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_file,
                                                                                          BTC_SIZE_COL,fsize,
                                                                                          BTC_STATUS_COL,utf8_status,
                                                                                          BTC_DL_SPEED_COL,dl_txt,
                                                                                          BTC_UL_SPEED_COL,ul_txt,
                                                                                          BTC_DL_SPEED,(gfloat)be->map->downRate,
                                                                                          BTC_UL_SPEED,(gfloat)be->map->upRate,
                                                                                          BTC_BACKGROUND_COL,NULL,
                                                                                          BTC_BITTORRENT_PID,be->bt_pid,
                                                                                          -1);
                        }
                        else
                        {
                              if(be->map->percentDone==0.0)
                              {
                                    /* client running: fatal error */
                                    gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_file,
                                                                                                BTC_SIZE_COL,fsize,
                                                                                                BTC_STATUS_COL,utf8_status,
                                                                                                BTC_DL_SPEED_COL,dl_txt,
                                                                                                BTC_UL_SPEED_COL,ul_txt,
                                                                                                BTC_DL_SPEED,(gfloat)be->map->downRate,
                                                                                                BTC_UL_SPEED,(gfloat)be->map->upRate,
                                                                                                BTC_BACKGROUND_COL,"IndianRed1",
                                                                                                BTC_BITTORRENT_PID,be->bt_pid,
                                                                                                -1);
                              }
                              else
                              {
                                    /* client running: successful end */
                                    gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_file,
                                                                                                BTC_SIZE_COL,fsize,
                                                                                                BTC_STATUS_COL,utf8_status,
                                                                                                BTC_DL_SPEED_COL,_("over"),
                                                                                                BTC_UL_SPEED_COL,ul_txt,
                                                                                                BTC_DL_SPEED,(gfloat)be->map->downRate,
                                                                                                BTC_UL_SPEED,(gfloat)be->map->upRate,
                                                                                                BTC_BACKGROUND_COL,"SeaGreen1",
                                                                                                BTC_BITTORRENT_PID,be->bt_pid,
                                                                                                -1);
                              }
                        }
                  }
                  else
                  {
                        if(be->map->done==FALSE)
                        {
                              /* update as inactive client */
                              gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_file,
                                                                                          BTC_SIZE_COL,fsize,
                                                                                          BTC_STATUS_COL,utf8_status,
                                                                                          BTC_DL_SPEED_COL,"--", 
                                                                                          BTC_UL_SPEED_COL,"--",
                                                                                          BTC_DL_SPEED,(gfloat)0,
                                                                                          BTC_UL_SPEED,(gfloat)0,
                                                                                          BTC_BACKGROUND_COL,"LightGoldenrod1",
                                                                                          BTC_BITTORRENT_PID,be->bt_pid,
                                                                                          -1);
                        }
                        else
                        {
                              if(be->map->percentDone==0.0)
                              {
                                    /* if done is set and %age of completion == 0, this is a fatal error */
                                    /* update as inactive client */
                                    gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_file,
                                                                                                BTC_SIZE_COL,fsize,
                                                                                                BTC_STATUS_COL,utf8_status,
                                                                                                BTC_DL_SPEED_COL,"--", 
                                                                                                BTC_UL_SPEED_COL,"--",
                                                                                                BTC_DL_SPEED,(gfloat)0,
                                                                                                BTC_UL_SPEED,(gfloat)0,
                                                                                                BTC_BACKGROUND_COL,"RosyBrown1",
                                                                                                BTC_BITTORRENT_PID,be->bt_pid,
                                                                                                -1);
                              }
                              else
                              {
                                    /* if done is set and %age of completion == 100.0, this is a completed download */
                                    /* update as inactive client */
                                    gtk_list_store_set(gls,&iter, BTC_FILENAME_COL,utf8_file,
                                                                                                BTC_SIZE_COL,fsize,
                                                                                                BTC_STATUS_COL,utf8_status,
                                                                                                BTC_DL_SPEED_COL,"--", 
                                                                                                BTC_UL_SPEED_COL,"--",
                                                                                                BTC_DL_SPEED,(gfloat)0,
                                                                                                BTC_UL_SPEED,(gfloat)0,
                                                                                                BTC_BACKGROUND_COL,"DarkSeaGreen1",
                                                                                                BTC_BITTORRENT_PID,be->bt_pid,
                                                                                                -1);
                              }
                        }
                  }
                  g_free(utf8_file);
                  g_free(utf8_status);
            }
            i++;
      }
}

/*****************************/
/* create the empty bt array */
/*****************************/
void init_bt_array(void)
{
      if(available_bt_entry==NULL)
      {
            available_bt_entry=g_array_new(FALSE,FALSE,sizeof(BT_ENTRY));
      }
}

/**********************************************************************************************************/
/* update the content of the bittorrent clist with the content of the directory $HOME/.dc_gui2/bt2dc_gui2 */
/**********************************************************************************************************/
void reload_bittorrent_clist(void)
{
      DIR *dir;
      struct dirent *obj;
      int base_len;
      GString *fpath;

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

      clear_dir_and_new_flags();

      fpath=g_string_new(bt2dc_gui2_directory->str);
      base_len=fpath->len;

      while((obj=readdir(dir))!=NULL)
      {
            int proc_pid;
            int idx;
            int ln_obj;

            if(obj->d_name[0]=='.')
                  continue;

            if(strncmp(obj->d_name,"bt_xfer.",8))
                  continue;

            ln_obj=strlen(obj->d_name);
            if(!strcmp(obj->d_name+ln_obj-5,".lock"))       /* avoid .lock files */
                  continue;

            proc_pid=atoi(obj->d_name+8);
            idx=get_idx_by_pid(proc_pid);
            if(idx!=-1)
            {
                  g_array_index(available_bt_entry,BT_ENTRY,idx).in_dir=TRUE;
            }
            else
            {
                  g_string_append(fpath,obj->d_name);
                  add_new_entry(fpath->str,proc_pid);
                  g_string_truncate(fpath,base_len);
            }
      }
      g_string_free(fpath,TRUE);
      closedir(dir);

      /* now, we have 3 tasks to do: */
      /* 1) for each entry of the array with in_dir=FALSE, remove them from the clist and from the array */
      /* 2) for each entry of the array with in_list=TRUE, check if they are still running and update their entry in the clist (and the time in the array) */
      /* 3) for each entry of the array with is_new=TRUE, create them in the clist */

      remove_dead_entries();        /* (1) */

      update_listed_entries();      /* (2) */

      add_new_entries();                  /* (3) */
}

/*****************************************************************/
/* check each entry of the array to autokill finished bittorrent */
/*****************************************************************/
static void post_process_bittorrent_entries(void)
{
      int i;
      time_t oldest_time;
      gint ivalue;
      gfloat fvalue;
      
      /* auto-kill enabled ? */
      ivalue=gconf_client_get_int(gconf_engine,"/apps/Dc_gui2/GUIPrefs/autokill_bt_at_end_checkbutton_toggle_val",NULL);
      if(ivalue==0)
            return;

      fvalue=gconf_client_get_float(gconf_engine,"/apps/Dc_gui2/GUIPrefs/bittorrent_autokill_delay_spinbutton_spin_val",NULL);
      if(fvalue<5)
            fvalue=5;

      oldest_time=time(NULL)-60*fvalue;

      i=0;
      while(i<available_bt_entry->len)
      {
            BT_ENTRY *be;

            be=&(g_array_index(available_bt_entry,BT_ENTRY,i));

            if((be->map->done==TRUE)&&(be->map->done_time<oldest_time))
            {
                  kill(be->bt_pid,SIGINT);            /* send ctrl-C to terminate */
            }
            i++;
      }
}

/********************************/
/* periodic bittorrent function */
/********************************/
gint bittorrent_list_periodic_refresh(gpointer data)
{
      reload_bittorrent_clist();

      post_process_bittorrent_entries();
      return TRUE;   /* don't stop periodic calling */
}

/***************************************************************************************************/
/* this function calls the given fnc for each selected entry of the "bittorrent_treeview" treeview */
/***************************************************************************************************/
void generic_selected_bittorrent_clist_calls(GtkTreeSelectionForeachFunc fnc, void *data)
{
   GtkWidget *w;
   GtkTreeSelection *slc;

      w=get_widget_by_widget_name(main_window,"bittorrent_treeview");
   if(w==NULL)
      return;

   slc=gtk_tree_view_get_selection(GTK_TREE_VIEW(w));
   gtk_tree_selection_selected_foreach(slc,fnc,data);
}

/**************************************************/
/* build modele and view for the queue user clist */
/**************************************************/
void bmav4_bittorrent_clist(void)
{
      GtkListStore *model;
      GtkWidget *view;
      GtkCellRenderer *rend;
      GtkTreeSelection *slc;

      model=gtk_list_store_new(NB_BTC_COL,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,
                                                                              G_TYPE_STRING,G_TYPE_STRING,G_TYPE_FLOAT,
                                                                              G_TYPE_FLOAT,G_TYPE_STRING, G_TYPE_INT);

      view=get_widget_by_widget_name(main_window,"bittorrent_treeview");

      gtk_tree_view_set_model(GTK_TREE_VIEW(view),GTK_TREE_MODEL(model));
      gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view),TRUE);

      slc=gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
      gtk_tree_selection_set_mode(slc,GTK_SELECTION_MULTIPLE);
      
      /* the first column of the view display the first column of the model, and so on. The 4th entry of the model is not displayed */
      rend=gtk_cell_renderer_textx_new();
      g_object_set(rend,"rowspacing",TRUE,NULL);
      MY_RS_gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),BTC_FILENAME_COL,_("Filename"),rend,"text",BTC_FILENAME_COL,"background",BTC_BACKGROUND_COL,NULL);

      rend=gtk_cell_renderer_textx_new();
      g_object_set(rend,"rowspacing",TRUE,NULL);
      MY_RS_gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),BTC_SIZE_COL,_("Size"),rend,"text",BTC_SIZE_COL,"background",BTC_BACKGROUND_COL,NULL);

      rend=gtk_cell_renderer_textx_new();
      g_object_set(rend,"rowspacing",TRUE,NULL);
      MY_RS_gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),BTC_STATUS_COL,_("Status"),rend,"text",BTC_STATUS_COL,"background",BTC_BACKGROUND_COL,NULL);

      rend=gtk_cell_renderer_textx_new();
      g_object_set(rend,"rowspacing",TRUE,NULL);
      MY_RS_gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),BTC_DL_SPEED_COL,_("DL spd"),rend,"text",BTC_DL_SPEED_COL,"background",BTC_BACKGROUND_COL,NULL);

      rend=gtk_cell_renderer_textx_new();
      g_object_set(rend,"rowspacing",TRUE,NULL);
      MY_RS_gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),BTC_UL_SPEED_COL,_("UL spd"),rend,"text",BTC_UL_SPEED_COL,"background",BTC_BACKGROUND_COL,NULL);

/* The view now holds a reference.  We can get rid of our own
       * reference */
      g_object_unref (G_OBJECT (model));
}


Generated by  Doxygen 1.6.0   Back to index