#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include /* for the value of SEMVMX */ #include #include #include #include #include "misc_gtk.h" #include "init_fnc.h" #include "main.h" #include "do_connect.h" #include "dctc_process.h" #include "status.h" #include "gui_layout.h" #include "bookmark.h" #include "bdb.h" #include "gdl_ctree.h" #include "gui_define.h" #include "find_result_clist.h" #include "user_file_list_clist.h" #include "ls_cache_clist.h" GtkStyle *fast_style=NULL; /* style for fast user */ char *lbl_chat[]={"pchat_label1", "pchat_label2", "pchat_label3", "pchat_label4", "pchat_label5", "pchat_label6", "pchat_label7", "pchat_label8", "pchat_label9"}; char *chat_text[]={ "chat1_text", "chat2_text", "chat3_text", "chat4_text", "chat5_text", "chat6_text", "chat7_text", "chat8_text", "chat9_text"}; /**********************************************************/ /* copie the given file (filename) into another file (fd) */ /* output: 0=ok, 1=error */ /**********************************************************/ static int copy_file(char *filename, int dest_fd) { char buf[512]; FILE *f; int ln; int err=0; f=fopen(filename,"rb"); if(f==NULL) return 1; while( (ln=fread(buf,1,sizeof(buf),f))!=0) { if(write(dest_fd,buf,ln)!=ln) { err=1; break; } } fclose(f); return err; } /*********************************************************************************************/ /* merge .done files into done+exited if there is no socket linked with them and remove them */ /*********************************************************************************************/ static void clean_directory(char *base_dir) { int fd; GString *p; GString *q; p=g_string_new(base_dir); q=g_string_new(NULL); g_string_sprintfa(p,"/done+exited"); fd=open(p->str,O_CREAT|O_RDWR,0666); if(fd==-1) { perror("clean_directory - open fails"); } else { if(flock(fd,LOCK_EX)!=0) { perror("clean_directory - lock fails"); } else { DIR *dir; struct stat st; lseek(fd,0,SEEK_END); dir=opendir(base_dir); if(dir!=NULL) { struct dirent *obj; while((obj=readdir(dir))!=NULL) { int a; if(strncmp(obj->d_name,"dctc-",5)) continue; a=strlen(obj->d_name); if(a<5) continue; if(!strcmp(obj->d_name+a-4,".udp")) /* ignore .udp file */ continue; if(!strcmp(obj->d_name+a-4,".userinfo")) /* ignore .udp file */ continue; if(!strcmp(obj->d_name+a-5,".done")) { g_string_sprintf(q,"%s/%s",base_dir,obj->d_name); q=g_string_truncate(q,q->len-5); /* remove the .done */ if(stat(q->str,&st)) { process_no_more_exist: g_string_sprintf(q,"%s/%s",base_dir,obj->d_name); /* copy q->str into fd */ if(!copy_file(q->str,fd)) unlink(q->str); } else { /* unix socket exist but does the process exists ? */ pid_t num; /* extract the number */ if(sscanf(obj->d_name+5,"%08X",&num)==1) { if(kill(num,SIGQUIT)!=0) { /* process is dead, remove the socket */ unlink(q->str); /* and the udp socket */ q=g_string_append(q,".udp"); unlink(q->str); q=g_string_truncate(q,q->len-4); /* remove the ".udp" */ q=g_string_append(q,".userinfo"); unlink(q->str); del_client_status(num); goto process_no_more_exist; } } } } else { /* well, the file start with dctc but has no .done at the end */ /* it is the socket */ pid_t num; /* extract the number */ if(sscanf(obj->d_name+5,"%08X",&num)==1) { if(kill(num,SIGQUIT)!=0) { g_string_sprintf(q,"%s/%s",base_dir,obj->d_name); /* process is dead, remove the socket */ unlink(q->str); /* and the udp socket */ { GString *p; p=g_string_new(q->str); p=g_string_append(p,".udp"); unlink(p->str); /* and the userinfo file */ p=g_string_assign(p,q->str); p=g_string_append(p,".userinfo"); unlink(p->str); g_string_free(p,TRUE); } q=g_string_append(q,".done"); /* copy q->str into fd */ if(!copy_file(q->str,fd)) unlink(q->str); del_client_status(num); } } } } closedir(dir); } flock(fd,LOCK_UN); } close(fd); } g_string_free(p,TRUE); g_string_free(q,TRUE); } /***********************************************************************/ /* search inside the "hub_recent_clist" a hub having the given address */ /***********************************************************************/ static char *get_hubname_from_recent(char *hub_addr) { GtkWidget *rhcw; rhcw=get_widget_by_widget_name("hub_recent_clist"); if(rhcw) { GtkCList *clst; int i; clst=GTK_CLIST(rhcw); for(i=0;irows;i++) { char *t; gtk_clist_get_text(clst,i,3,&t); if((t!=NULL)&&(!strcmp(t,hub_addr))) { gtk_clist_get_text(clst,i,0,&t); return t; } } } return NULL; } /********************************************************************************/ /* fill the clist named "running_hub_clist" with the list of all running client */ /********************************************************************************/ /* NOTE: each clist row data is the pid of the process */ /*******************************************************/ void fill_running_hub_clist(void) { #if 1 running_client_list_periodic_refresh(NULL); #else GtkWidget *rhcw; rhcw=get_widget_by_widget_name("running_hub_clist"); if(rhcw) { gtk_clist_freeze(GTK_CLIST(rhcw)); gtk_clist_clear(GTK_CLIST(rhcw)); clean_directory(dctc_dir->str); /* we read the directory ~/.dctc/running */ /* each entry has the format "dctc-xxxxxxxx-aaaaaaaaaaaa" where xxxxxxxx is the dctc pid (8 hexdigits) and aaaaaaaaa is the hubname */ { DIR *dir; dir=opendir(dctc_dir->str); if(dir!=NULL) { struct dirent *obj; while((obj=readdir(dir))!=NULL) { char *ent[7]; int a; char *hn; int row_num; int stt; pid_t the_pid; char str_gdl[20]; char str_ul[20]; char str_users[20]; unsigned long cli_param[NB_LONG_PER_ENTRY]; GdkColor *row_col; if(strncmp(obj->d_name,"dctc-",5)) continue; a=strlen(obj->d_name); if((a>5)&&(!strcmp(obj->d_name+a-5,".done"))) continue; if((a>4)&&(!strcmp(obj->d_name+a-4,".udp"))) continue; if((a>9)&&(!strcmp(obj->d_name+a-9,".userinfo"))) continue; hn=get_hubname_from_recent(obj->d_name+5+8+1); ent[0]=obj->d_name+5+8+1; ent[1]=obj->d_name; if(hn!=NULL) ent[2]=hn; else ent[2]=""; sscanf(obj->d_name+5,"%08X",&the_pid); stt=get_client_status(the_pid,cli_param); switch(stt) { default: case NOT_EXIST: ent[3]=""; ent[4]=""; ent[5]=""; ent[6]=""; row_col=&white; break; case IS_OFFLINE: ent[3]="0"; ent[4]=str_gdl; ent[5]=str_ul; ent[6]=(((FLAG1_STRUCT)(cli_param[GSTATUS_FLAG1])).bf.is_clock_master)?_("Master"):""; sprintf(str_gdl,"%lu",cli_param[GSTATUS_NB_GDL]); sprintf(str_ul,"%lu",cli_param[GSTATUS_NB_UL]); row_col=&light_orange; break; case IS_ONLINE: ent[3]=str_users; sprintf(str_users,"%lu",cli_param[GSTATUS_NB_USERS]); ent[4]=str_gdl; ent[5]=str_ul; ent[6]=(((FLAG1_STRUCT)(cli_param[GSTATUS_FLAG1])).bf.is_clock_master)?_("Master"):""; sprintf(str_gdl,"%lu",cli_param[GSTATUS_NB_GDL]); sprintf(str_ul,"%lu",cli_param[GSTATUS_NB_UL]); row_col=&green; break; } row_num=gtk_clist_append(GTK_CLIST(rhcw),ent); gtk_clist_set_row_data(GTK_CLIST(rhcw),row_num,GINT_TO_POINTER(the_pid)); gtk_clist_set_background(GTK_CLIST(rhcw),row_num,row_col); } closedir(dir); } } gtk_clist_thaw(GTK_CLIST(rhcw)); } colorize_favorite(GTK_CLIST(get_widget_by_widget_name("hub_favorite_clist")),GTK_CLIST(rhcw)); #endif } /*******************************************************************************/ /* fill the clist named "hub_recent_clist" with the list of all running client */ /*******************************************************************************/ void fill_recent_hub_clist(void) { GtkWidget *rhcw; rhcw=get_widget_by_widget_name("hub_recent_clist"); if(rhcw) { FILE *f; GString *s; char *path; gtk_clist_freeze(GTK_CLIST(rhcw)); gtk_clist_clear(GTK_CLIST(rhcw)); gtk_clist_set_auto_sort(GTK_CLIST(rhcw),TRUE); s=g_string_new(NULL); path=getenv("HOME"); g_string_sprintf(s,"%s/.dctc/recent",(path!=NULL)?path:"."); /* we read the file ~/.dctc/recent */ f=fopen(s->str,"rb"); if(f!=NULL) { char *ent[4]; char buf[51200]; char *t; GStringChunk *gsc; GPtrArray *gpa; gpa=g_ptr_array_new(); gsc=g_string_chunk_new(48); ent[1]=""; ent[2]=""; ent[3]=buf; while(fgets(buf,sizeof(buf),f)!=NULL) { ent[0]=strchr(buf,'|'); if(ent[0]!=NULL) { int i; int fnd=0; *(ent[0])++='\0'; t=strchr(ent[0],'\n'); if(t!=NULL) *t='\0'; /* site already added ? */ for(i=0;ilen;i++) { char *p; p=g_ptr_array_index(gpa,i); if(!strcmp(p,ent[0])) { fnd=1; break; } } if(!fnd) { gtk_clist_append(GTK_CLIST(rhcw),ent); /* add the site name to the list of already added site */ g_ptr_array_add(gpa,g_string_chunk_insert(gsc,ent[0])); } } } if(gpa!=NULL) g_ptr_array_free(gpa,TRUE); if(gsc!=NULL) g_string_chunk_free(gsc); fclose(f); } g_string_free(s,TRUE); gtk_clist_sort(GTK_CLIST(rhcw)); gtk_clist_thaw(GTK_CLIST(rhcw)); } } /*************************************************************************************/ /* this function updates the gnome vector containing seen hub to include the new one */ /*************************************************************************************/ void update_seen_hub_list(GPtrArray *new_seen) { int i; GString *tmp; tmp=g_string_new(""); for(i=0;ilen;i++) { char *v; char *toadd; toadd=g_ptr_array_index(new_seen,i); /* build the key */ v=strchr(toadd,'|')+1; tmp=g_string_assign(tmp,v); v=strchr(tmp->str,'|'); tmp=g_string_truncate(tmp,v-tmp->str); /* to ease future usage of values, the key and its value is stored with the trailing '\0' (==C string format)*/ set_key_data(seen_hub_db,tmp->str,tmp->len+1,toadd,strlen(toadd)+1); } } /**********************************************************/ /* build hublist command line according to GUI parameters */ /**********************************************************/ static void start_hublist(void) { GStringChunk *gsc=NULL; GPtrArray *gpa=NULL; int valid_len; int i; char *cnxtype; char *hubcnxtype[3]={_("No proxy needed"), _("Use SOCKS parameters"), _("Use Web proxy")}; GtkWidget *w; char *t; gsc=g_string_chunk_new(128); gpa=g_ptr_array_new(); g_ptr_array_add(gpa,g_string_chunk_insert(gsc,"dc_hublist")); /* argv[0] */ cnxtype=gtk_entry_get_text(GTK_ENTRY(get_widget_by_widget_name("hublist_cnxtype_entry"))); for(i=0;i<3;i++) { if(!strcmp(cnxtype,hubcnxtype[i])) break; } valid_len=gpa->len; switch(i) { case 0: /* no proxy needed */ break; case 1: /* use socks param */ g_ptr_array_add(gpa,g_string_chunk_insert(gsc,"--socks")); { /* add socks proxy address */ w=get_widget_by_widget_name("socks_address_entry"); if(w==NULL) break; t=gtk_entry_get_text(GTK_ENTRY(w)); if((t==NULL)||(strlen(t)==0)) break; g_ptr_array_add(gpa,g_string_chunk_insert(gsc,t)); } { /* add socks proxy port */ w=get_widget_by_widget_name("socks_port_entry"); if(w==NULL) break; t=gtk_entry_get_text(GTK_ENTRY(w)); if((t==NULL)||(strlen(t)==0)) break; g_ptr_array_add(gpa,g_string_chunk_insert(gsc,t)); valid_len=gpa->len; } { /* add socks user ID (if exist) */ w=get_widget_by_widget_name("socks_userid_entry"); if(w==NULL) break; t=gtk_entry_get_text(GTK_ENTRY(w)); if((t==NULL)||(strlen(t)==0)) break; g_ptr_array_add(gpa,g_string_chunk_insert(gsc,t)); valid_len=gpa->len; } break; case 2: /* use web proxy */ g_ptr_array_add(gpa,g_string_chunk_insert(gsc,"--proxy")); { /* add web proxy address */ w=get_widget_by_widget_name("web_proxy_host_entry"); if(w==NULL) break; t=gtk_entry_get_text(GTK_ENTRY(w)); if((t==NULL)||(strlen(t)==0)) break; g_ptr_array_add(gpa,g_string_chunk_insert(gsc,t)); } { /* add socks proxy port */ w=get_widget_by_widget_name("web_proxy_port_entry"); if(w==NULL) break; t=gtk_entry_get_text(GTK_ENTRY(w)); if((t==NULL)||(strlen(t)==0)) break; g_ptr_array_add(gpa,g_string_chunk_insert(gsc,t)); valid_len=gpa->len; } break; default: /* eh ??? */ break; } /* discard any incomplete parameter */ if(valid_len==gpa->len) g_ptr_array_add(gpa,NULL); /* ends the array */ else gpa->pdata[valid_len]=NULL; /* and start hublist */ execvp(gpa->pdata[0],(char **)(gpa->pdata)); /* on error, we leave */ g_string_chunk_free(gsc); g_ptr_array_free(gpa,TRUE); } static guint fill_pubhub_handle_id=-1; /* when !=-1, it is the gdk_input handle for the function updating the hub_public_clist */ static int fill_pubhub_pipe=-1; /* pipe used to communicate with hub list (it is a read only pipe) */ static pid_t fill_pubhub_procpid=-1; /* when !=-1, it is the pid of the hublist program */ static GtkWidget *fill_pubhub_hpc_wid=NULL; /* it is the GtkWidget named "hub_public_clist" */ static GString *fill_pubhub_incoming_data=NULL; /* string containing received data */ /****************************************************************************************/ /* check if the given address exist in a row of the given clist (column 3: hub address) */ /****************************************************************************************/ /* output: 0=no, !=0=yes */ /*************************/ static int has_the_same_hub(GtkCList *pubhub_clst, char *hub_address) { int i; char *t; for(i=0;irows;i++) { gtk_clist_get_text(pubhub_clst,i,3,&t); if((t!=NULL)&&(!strcmp(t,hub_address))) return 1; } return 0; } /**************************************************************************/ /* fill the clist named "hub_public_clist" with the list of existing hubs */ /**************************************************************************/ static void async_fill_pub_hub_clist(gpointer data, gint source, GdkInputCondition condition) { int rd; gchar **row=NULL; GPtrArray *gpa=NULL; GStringChunk *gsc=NULL; int i; char buf[1024+1]; rd=read(source,buf,sizeof(buf)-1); if(rd==-1) { if((errno==EAGAIN)||(errno==EINTR)) /* come back later */ return; } else if(rd!=0) /* we have something */ { buf[rd]='\0'; fill_pubhub_incoming_data=g_string_append(fill_pubhub_incoming_data,buf); return; } /* we come here either after an error on read or when no more data are available */ /* 1) remove the gdk tag */ gdk_input_remove(fill_pubhub_handle_id); fill_pubhub_handle_id=-1; /* 2) close the com pipe */ close(fill_pubhub_pipe); fill_pubhub_pipe=-1; /* 3) just to avoid problem, kill the hublist process */ kill(fill_pubhub_procpid,SIGKILL); waitpid(fill_pubhub_procpid,NULL,0); fill_pubhub_procpid=-1; /* now, it's time to process the result */ gtk_clist_freeze(GTK_CLIST(fill_pubhub_hpc_wid)); row=g_strsplit(fill_pubhub_incoming_data->str,"\r\n",0); /* expand data */ gpa=g_ptr_array_new(); gsc=g_string_chunk_new(128); for(i=0;row[i]!=NULL;i++) { char *ent[4]; char *buf=row[i]; char buf_cpy[51200]; char *t; strcpy(buf_cpy,buf); ent[0]=buf; t=strchr(buf,'|'); if(t==NULL) continue; *t++='\0'; ent[3]=t; t=strchr(t,'|'); if(t==NULL) continue; *t++='\0'; ent[2]=t; t=strchr(t,'|'); if(t==NULL) continue; *t++='\0'; ent[1]=t; t=strchr(t,'|'); if(t==NULL) continue; *t++='\0'; if(!has_the_same_hub(GTK_CLIST(fill_pubhub_hpc_wid),ent[3])) { gtk_clist_append(GTK_CLIST(fill_pubhub_hpc_wid),ent); g_ptr_array_add(gpa,g_string_chunk_insert(gsc,buf_cpy)); } } gtk_clist_sort(GTK_CLIST(fill_pubhub_hpc_wid)); gtk_clist_thaw(GTK_CLIST(fill_pubhub_hpc_wid)); if(gpa!=NULL) { update_seen_hub_list(gpa); g_ptr_array_free(gpa,TRUE); } if(gsc) g_string_chunk_free(gsc); if(row) g_strfreev(row); if(fill_pubhub_incoming_data) { g_string_free(fill_pubhub_incoming_data,TRUE); fill_pubhub_incoming_data=NULL; } if(gtk_notebook_get_current_page(GTK_NOTEBOOK(get_widget_by_widget_name("main_notebook")))!=CONNECT_TAB) blink_on("connect_page"); if(gtk_notebook_get_current_page(GTK_NOTEBOOK(get_widget_by_widget_name("connect_notebook")))!=PUBLIC_HUB_TAB) blink_on("connect_public_label"); } /*****************************************************/ /* routine fixant le flag non bloquant sur un socket */ /*****************************************************/ void set_non_bloquant_sock(int socket_fd) { long retval; retval=fcntl(socket_fd,F_GETFL); retval|= O_NONBLOCK; fcntl(socket_fd,F_SETFL,retval); } /**************************************************************************/ /* fill the clist named "hub_public_clist" with the list of existing hubs */ /**************************************************************************/ void fill_pub_hub_clist(int flag) { int com_pipe[2]; if(fill_pubhub_handle_id!=-1) /* update already in progress */ return; fill_pubhub_hpc_wid=get_widget_by_widget_name("hub_public_clist"); if(fill_pubhub_hpc_wid==NULL) return; /* reload only when required */ if((flag==FALSE)&&(GTK_CLIST(fill_pubhub_hpc_wid)->rows!=0)) return; if(pipe(com_pipe)==-1) { perror("fill_pub_hub_clist: pipe fail"); return; } gtk_clist_clear(GTK_CLIST(fill_pubhub_hpc_wid)); /* array must have been set to NULL at the end */ if(fill_pubhub_incoming_data) g_string_free(fill_pubhub_incoming_data,TRUE); fill_pubhub_incoming_data=g_string_new(""); switch(fill_pubhub_procpid=fork()) { case -1: perror("fill_pub_hub_clist: fork fail"); /* close communication pipe */ close(com_pipe[0]); close(com_pipe[1]); /* and free memory */ if(fill_pubhub_incoming_data) { g_string_free(fill_pubhub_incoming_data,TRUE); fill_pubhub_incoming_data=NULL; } return; case 0: /* it is the son, it will start hublist */ close(com_pipe[0]); dup2(com_pipe[1],1); /* connect the com_pipe to stdout */ start_hublist(); close(1); close(com_pipe[1]); _exit(0); default: close(com_pipe[1]); fill_pubhub_pipe=com_pipe[0]; /* pipe used to communicate with hub list (it is a read only pipe) */ set_non_bloquant_sock(fill_pubhub_pipe); fill_pubhub_handle_id=gdk_input_add(fill_pubhub_pipe,GDK_INPUT_READ,async_fill_pub_hub_clist,NULL); break; } } /********************************************************************/ /* fill the clist named "seen_hub_clist" with the list of seen hubs */ /********************************************************************/ void fill_seen_hub_clist(int flag) { GtkWidget *rhcw; rhcw=get_widget_by_widget_name("seen_hub_clist"); if(rhcw) { DBC *cursor; int ret; if((flag==FALSE)&&(GTK_CLIST(rhcw)->rows!=0)) return; gtk_clist_freeze(GTK_CLIST(rhcw)); gtk_clist_clear(GTK_CLIST(rhcw)); /* we must get all keys of seen_hub berkeley Database */ /* the value of the keys are to put in buf and to process */ ret=seen_hub_db->cursor(seen_hub_db,NULL,&cursor,0); if(ret==0) { DBT key; DBT data; int counter=0; char buf1[8192]; char buf2[8192]; memset(&key,0,sizeof(key)); memset(&data,0,sizeof(data)); key.data=buf1; key.ulen=sizeof(buf1)-1; key.flags=DB_DBT_USERMEM; data.data=buf2; data.ulen=sizeof(buf2)-1; data.flags=DB_DBT_USERMEM; ret=cursor->c_get(cursor,&key,&data,DB_FIRST); while(ret==0) { char *ent[4]; char *t; /* should not be useful but who knows what appends if someone enters invalid keys */ buf2[data.size]='\0'; ent[0]=buf2; t=strchr(buf2,'|'); if(t==NULL) continue; *t++='\0'; ent[3]=t; t=strchr(t,'|'); if(t==NULL) continue; *t++='\0'; ent[2]=t; t=strchr(t,'|'); if(t==NULL) continue; *t++='\0'; ent[1]=t; t=strchr(t,'|'); if(t==NULL) continue; *t++='\0'; gtk_clist_append(GTK_CLIST(rhcw),ent); counter++; #if 0 if((counter&0xF)==0) printf("%d entrys.\n",counter); #endif ret=cursor->c_get(cursor,&key,&data,DB_NEXT); } /* end of scan, destroy the cursor */ cursor->c_close(cursor); printf("total: %d entrys.\n",counter); } gtk_clist_sort(GTK_CLIST(rhcw)); gtk_clist_thaw(GTK_CLIST(rhcw)); } } static gint hub_pub_comp(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GtkCListRow *row1 = (GtkCListRow *) p1; GtkCListRow *row2 = (GtkCListRow *) p2; char *text1=NULL; char *text2=NULL; int col; switch((col=clist->sort_column)) { case 1: /* #users */ text1=GTK_CELL_TEXT(row1->cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) { unsigned long v1,v2; sscanf(text1,"%lu",&v1); sscanf(text2,"%lu",&v2); /* don't replace the following code by return v1-v2; because v1 and v2 are unsigned */ if(v1cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) return strcmp(text1,text2); return -1; } } static gint dl_clist_comp(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GtkCListRow *row1 = (GtkCListRow *) p1; GtkCListRow *row2 = (GtkCListRow *) p2; char *text1=NULL; char *text2=NULL; int col; switch((col=clist->sort_column)) { case 2: /* size */ text1=GTK_CELL_TEXT(row1->cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) { unsigned long v1,v2; sscanf(text1,"%lu",&v1); sscanf(text2,"%lu",&v2); /* don't replace the following code by return v1-v2; because v1 and v2 are unsigned */ if(v1cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) return strcmp(text1,text2); return -1; case 1: /* nick */ text1=GTK_CELL_TEXT(row1->cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) return (*nickname_sort_function)(text1,text2); return -1; } } static gint user_clist_comp(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GtkCListRow *row1 = (GtkCListRow *) p1; GtkCListRow *row2 = (GtkCListRow *) p2; char *text1=NULL; char *text2=NULL; int col; switch((col=clist->sort_column)) { case 2: /* size */ text1=GTK_CELL_TEXT(row1->cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) { float v1=0; float v2=0; unsigned int i; char unit1[3]; char unit2[3]; double scale[4]={1.0,1024.0, 1024.0*1024.0, 1024.0*1024.0*1024.0}; char *unit_name[4]={"B","KB","MB","GB"}; if(sscanf(text1,"%f%2s",&v1,unit1)) { for(i=0;i<4;i++) { if(strcmp(unit1,unit_name[i]) == 0) { v1=v1*scale[i]; } } } if(sscanf(text2,"%f%2s",&v2,unit2)) { for(i=0;i<4;i++) { if(strcmp(unit2,unit_name[i]) == 0) { v2=v2*scale[i]; } } } /* don't replace the following code by return v1-v2; because v1 and v2 are unsigned */ if(v1cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) return (*nickname_sort_function)(text1,text2); return -1; default: text1=GTK_CELL_TEXT(row1->cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) return strcmp(text1,text2); return -1; } } static gint find_result_clist_comp(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GtkCListRow *row1 = (GtkCListRow *) p1; GtkCListRow *row2 = (GtkCListRow *) p2; FIND_CL_ENTRY *fce1, *fce2; char *txt1, *txt2; int (*srt_fnc)(const char*,const char*)=strcmp; fce1=row1->data; fce2=row2->data; if(fce1==NULL) { if(fce2==NULL) return 0; return -1; } else { if(fce2==NULL) return 1; } switch(clist->sort_column) { case FRC_NICK_COL: txt1=fce1->nickname; txt2=fce2->nickname; srt_fnc=(*nickname_sort_function); break; case FRC_FULL_PATH_COL: txt1=fce1->filename; txt2=fce2->filename; break; case FRC_SIZE_COL: return fce1->file_size-fce2->file_size; case FRC_SLOT_COL: return fce1->free_slot-fce2->free_slot; case FRC_HUBNAME_COL: txt1=fce1->hubname; txt2=fce2->hubname; break; case FRC_SPEED_COL: txt1=fce1->connection_speed; txt2=fce2->connection_speed; break; default: return 0; } if(txt1==NULL) { if(txt2==NULL) return 0; return -1; } else { if(txt2==NULL) return 1; return (*srt_fnc)(txt1,txt2); } } static gint ls_cache_clist_comp(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GtkCListRow *row1 = (GtkCListRow *) p1; GtkCListRow *row2 = (GtkCListRow *) p2; LS_CACHE_CL_ENTRY *lcce1, *lcce2; char *txt1, *txt2; lcce1=row1->data; lcce2=row2->data; if(lcce1==NULL) { if(lcce2==NULL) return 0; return -1; } else { if(lcce2==NULL) return 1; } switch(clist->sort_column) { case CULC_NICK_COL: txt1=lcce1->nickname; txt2=lcce2->nickname; if(txt1==NULL) { if(txt2==NULL) return 0; return -1; } else { if(txt2==NULL) return 1; return (*nickname_sort_function)(txt1,txt2); } break; case CULC_SIZE_COL: /* don't replace by return lcce1->shared_size-lcce2->shared_size; because values are unsigned */ if(lcce1->shared_sizeshared_size) return -1; else if(lcce1->shared_size>lcce2->shared_size) return 1; return 0; case CULC_DATE_COL: /* don't replace by return lcce1->retrieve_date-lcce2->retrieve_date; because dates are unsigned */ if(lcce1->retrieve_dateretrieve_date) return -1; else if(lcce1->retrieve_date>lcce2->retrieve_date) return 1; return 0; default: return 0; } } static gint clist_comp_num_is_1(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GtkCListRow *row1 = (GtkCListRow *) p1; GtkCListRow *row2 = (GtkCListRow *) p2; char *text1=NULL; char *text2=NULL; int col; switch((col=clist->sort_column)) { case 1: /* size */ text1=GTK_CELL_TEXT(row1->cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) { unsigned long v1,v2; sscanf(text1,"%lu",&v1); sscanf(text2,"%lu",&v2); /* don't replace the following code by return v1-v2; because v1 and v2 are unsigned */ if(v1cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) return strcmp(text1,text2); return -1; } } static gint clist_comp_num_is_3_4_and_5(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GtkCListRow *row1 = (GtkCListRow *) p1; GtkCListRow *row2 = (GtkCListRow *) p2; char *text1=NULL; char *text2=NULL; int col; switch((col=clist->sort_column)) { case 3: /* number of users */ case 4: /* number of GDL */ case 5: /* number of UL */ if( (GTK_CELL_TEXT(row1->cell[col])->type==GTK_CELL_TEXT) && (GTK_CELL_TEXT(row2->cell[col])->type==GTK_CELL_TEXT) ) { /* the size can be CELL_EMPTY (for non leaf node), that's why we verify the cell type here */ text1=GTK_CELL_TEXT(row1->cell[col])->text; text2=GTK_CELL_TEXT(row2->cell[col])->text; if(text1&&text2) { unsigned long v1,v2; sscanf(text1,"%lu",&v1); sscanf(text2,"%lu",&v2); /* don't replace the following code by return v1-v2; because v1 and v2 are unsigned */ if(v1cell[col])->text; text2=GTK_CELL_PIXTEXT(row2->cell[col])->text; if(text1&&text2) return strcmp(text1,text2); return -1; } } static gint gdl_ctree_sort_fnc(GtkCList *clist, gconstpointer p1, gconstpointer p2) { GDL_CT_ENTRY *gce_p1,*gce_p2; int col; /* TYPE \ colonne 0 1 2 3 */ /* GDL_ROOT gdl_id local_filename gdl_size received_bytes */ /* GDL_SEARCH_PATTERN autoscan_id autoscan_type+search_pattern empty=>1 empty=>1 */ /* GDL_ACTIVE_SEGMENT nickname remote_filename remote_file_size status */ /* GDL_STORED_SEGMENT empty=>2 stored_filename stored_interval empty=>2 */ /* GDL_RENAME_AT_END empty=>1 final_filename empty=>1 empty=>1 */ gce_p1=((GtkCListRow *)p1)->data; gce_p2=((GtkCListRow *)p2)->data; if(gce_p1==NULL) { if(gce_p2==NULL) return 0; return -1; } else { if(gce_p2==NULL) return 1; } /* type must be comparable */ if(gce_p1->ct_type!=gce_p2->ct_type) { return ((int)gce_p1->ct_type-(int)gce_p2->ct_type); } col=clist->sort_column; switch(gce_p1->ct_type) { case GDL_ROOT: switch(col) { case 0: return gce_p1->c.root.gdl_id - gce_p2->c.root.gdl_id; case 1: return strcmp(gce_p1->c.root.local_filename , gce_p2->c.root.local_filename); case 2: return gce_p1->c.root.gdl_size - gce_p2->c.root.gdl_size; case 3: return gce_p1->c.root.received_bytes - gce_p2->c.root.received_bytes; } break; case GDL_SEARCH_PATTERN: switch(col) { case 0: return gce_p1->c.search_pattern.autoscan_id - gce_p2->c.search_pattern.autoscan_id; case 2: case 3: case 1: if(gce_p1->c.search_pattern.autoscan_type - gce_p2->c.search_pattern.autoscan_type) return gce_p1->c.search_pattern.autoscan_type - gce_p2->c.search_pattern.autoscan_type; return strcmp(gce_p1->c.search_pattern.search_pattern, gce_p2->c.search_pattern.search_pattern); } break; case GDL_ACTIVE_SEGMENT: switch(col) { case 0: return (*nickname_sort_function)(gce_p1->c.active_segment.nickname, gce_p2->c.active_segment.nickname); case 1: return strcmp(gce_p1->c.active_segment.remote_filename, gce_p2->c.active_segment.remote_filename); case 2: return gce_p1->c.active_segment.remote_file_size - gce_p2->c.active_segment.remote_file_size; case 3: return strcmp(gce_p1->c.active_segment.status, gce_p2->c.active_segment.status); } break; case GDL_STORED_SEGMENT: switch(col) { case 1: return strcmp(gce_p1->c.stored_segment.stored_filename,gce_p2->c.stored_segment.stored_filename); case 0: case 2: case 3: if((gce_p1->c.stored_segment.stored_interval[0]=='[')&&(gce_p2->c.stored_segment.stored_interval[0]=='[')) return atoi(gce_p1->c.stored_segment.stored_interval+1)-atoi(gce_p2->c.stored_segment.stored_interval+1); printf("gdl_ctree_sort_fnc: ???\n"); return 0; } break; case GDL_RENAME_AT_END: /* column is not meaningful here */ return strcmp(gce_p1->c.rename_at_end.final_filename,gce_p2->c.rename_at_end.final_filename); break; default: break; } return 0; } static gint user_file_list_clist_sort_fnc(GtkCList *clist, gconstpointer p1, gconstpointer p2) { USER_FILE_CL_ENTRY *ufce_p1,*ufce_p2; int col; ufce_p1=((GtkCListRow *)p1)->data; ufce_p2=((GtkCListRow *)p2)->data; if(ufce_p1==NULL) { if(ufce_p2==NULL) return 0; return -1; } else { if(ufce_p2==NULL) return 1; } /* type must be comparable */ if(ufce_p1->entry_type!=ufce_p2->entry_type) { return ((int)ufce_p1->entry_type-(int)ufce_p2->entry_type); } col=clist->sort_column; switch(col) { case UFLC_TREE_COL: default_sort: switch(ufce_p1->entry_type) { case UFL_NICK_ROOT_ENTRY: return (*nickname_sort_function)(ufce_p1->c.nickname,ufce_p2->c.nickname); case UFL_DIR_ENTRY: return strcmp(ufce_p1->c.dir_name,ufce_p2->c.dir_name); case UFL_FILE_ENTRY: return strcmp(ufce_p1->c.file.filename,ufce_p2->c.file.filename); } break; case UFLC_SIZE_COL: if(ufce_p1->entry_type!=UFL_FILE_ENTRY) goto default_sort; return ufce_p1->c.file.file_size - ufce_p2->c.file.file_size; } return 0; } /********************************************************************************************************************/ /* the following function makes some adjustements that cannot be done inside glade (or I don't know how to do them) */ /********************************************************************************************************************/ void init_clist(void) { GtkWidget *w; int i; w=get_widget_by_widget_name("running_hub_clist"); if(w!=NULL) { gtk_clist_set_auto_sort(GTK_CLIST(w),TRUE); gtk_clist_set_column_visibility(GTK_CLIST(w),1,FALSE); /* hide process_id column */ gtk_clist_set_column_justification(GTK_CLIST(w),3,GTK_JUSTIFY_RIGHT); gtk_clist_set_column_justification(GTK_CLIST(w),4,GTK_JUSTIFY_RIGHT); gtk_clist_set_column_justification(GTK_CLIST(w),5,GTK_JUSTIFY_RIGHT); } w=get_widget_by_widget_name("download_clist"); if(w!=NULL) { gtk_clist_freeze(GTK_CLIST(w)); gtk_clist_clear(GTK_CLIST(w)); gtk_clist_set_column_visibility(GTK_CLIST(w),0,FALSE); gtk_clist_set_compare_func(GTK_CLIST(w),dl_clist_comp); gtk_clist_set_auto_sort(GTK_CLIST(w),TRUE); gtk_clist_set_column_justification(GTK_CLIST(w),2,GTK_JUSTIFY_RIGHT); gtk_clist_set_column_justification(GTK_CLIST(w),3,GTK_JUSTIFY_RIGHT); gtk_clist_thaw(GTK_CLIST(w)); } w=get_widget_by_widget_name("upload_clist"); if(w!=NULL) { gtk_clist_freeze(GTK_CLIST(w)); gtk_clist_clear(GTK_CLIST(w)); gtk_clist_set_column_visibility(GTK_CLIST(w),0,FALSE); gtk_clist_set_compare_func(GTK_CLIST(w),dl_clist_comp); /* works because order of columns are identical, only less columns */ gtk_clist_set_auto_sort(GTK_CLIST(w),TRUE); gtk_clist_set_column_justification(GTK_CLIST(w),2,GTK_JUSTIFY_RIGHT); gtk_clist_set_column_justification(GTK_CLIST(w),3,GTK_JUSTIFY_RIGHT); gtk_clist_thaw(GTK_CLIST(w)); } w=get_widget_by_widget_name("queue_clist"); if(w!=NULL) { gtk_clist_freeze(GTK_CLIST(w)); gtk_clist_clear(GTK_CLIST(w)); gtk_clist_set_column_visibility(GTK_CLIST(w),0,FALSE); gtk_clist_set_auto_sort(GTK_CLIST(w),TRUE); gtk_clist_set_column_visibility(GTK_CLIST(w),3,FALSE); /* hide speed column (it is empty) */ #if 0 gtk_clist_set_column_justification(GTK_CLIST(w),3,GTK_JUSTIFY_RIGHT); /* right align size column */ #endif gtk_clist_thaw(GTK_CLIST(w)); } w=get_widget_by_widget_name("done_clist"); if(w!=NULL) { gtk_clist_set_column_visibility(GTK_CLIST(w),2,FALSE); /* hide speed column (it is empty) */ gtk_clist_set_column_justification(GTK_CLIST(w),1,GTK_JUSTIFY_RIGHT); /* right align size column */ gtk_clist_set_compare_func(GTK_CLIST(w),clist_comp_num_is_1); /* and sort the column 1 numerically */ } { GString *str; str=g_string_new(dctc_dir->str); g_string_sprintfa(str,"/done+exited"); load_done_xfer(str->str,0); g_string_free(str,TRUE); } w=get_widget_by_widget_name("find_result"); if(w) { #if 0 gtk_clist_set_auto_sort(GTK_CLIST(w),TRUE); /* don't set this list in autosort because */ /* the sort is called immediatly after row insertion ... before */ /* row data was set and row data is needed to sort */ #endif gtk_clist_set_column_justification(GTK_CLIST(w),2,GTK_JUSTIFY_RIGHT); gtk_clist_set_compare_func(GTK_CLIST(w),find_result_clist_comp); } w=get_widget_by_widget_name("user_file_list_clist"); if(w) { gtk_clist_set_compare_func(GTK_CLIST(w),user_file_list_clist_sort_fnc); gtk_clist_set_column_justification(GTK_CLIST(w),1,GTK_JUSTIFY_RIGHT); } w=get_widget_by_widget_name("gdl_ctree"); if(w) { gtk_clist_set_compare_func(GTK_CLIST(w),gdl_ctree_sort_fnc); gtk_clist_set_column_justification(GTK_CLIST(w),2,GTK_JUSTIFY_RIGHT); gtk_ctree_set_indent(GTK_CTREE(w),10); } w=get_widget_by_widget_name("cached_user_list_clist"); if(w) { gtk_clist_set_column_justification(GTK_CLIST(w),1,GTK_JUSTIFY_RIGHT); gtk_clist_set_compare_func(GTK_CLIST(w),ls_cache_clist_comp); } /* create a special style for fast user */ w=get_widget_by_widget_name("user_clist"); if(w) { fast_style=gtk_style_copy(GTK_WIDGET (w)->style); fast_style->bg[GTK_STATE_NORMAL]=green; fast_style->bg[GTK_STATE_ACTIVE]=green; fast_style->bg[GTK_STATE_PRELIGHT]=green; fast_style->bg[GTK_STATE_SELECTED]=green; fast_style->bg[GTK_STATE_INSENSITIVE]=green; fast_style->base[GTK_STATE_NORMAL]=green; fast_style->base[GTK_STATE_ACTIVE]=green; fast_style->base[GTK_STATE_PRELIGHT]=green; fast_style->base[GTK_STATE_SELECTED]=green; fast_style->base[GTK_STATE_INSENSITIVE]=green; gtk_clist_set_compare_func(GTK_CLIST(w),user_clist_comp); } w=get_widget_by_widget_name("running_hub_clist"); if(w) { gtk_clist_set_compare_func(GTK_CLIST(w),clist_comp_num_is_3_4_and_5); } for(i=0;i<9;i++) { w=get_widget_by_widget_name(lbl_chat[i]); if(w) { gtk_label_set(GTK_LABEL(w),_("empty")); } } w=get_widget_by_widget_name("hub_public_clist"); if(w) { gtk_clist_set_compare_func(GTK_CLIST(w),hub_pub_comp); gtk_clist_set_column_justification(GTK_CLIST(w),1,GTK_JUSTIFY_RIGHT); } w=get_widget_by_widget_name("seen_hub_clist"); if(w) { gtk_clist_set_compare_func(GTK_CLIST(w),hub_pub_comp); gtk_clist_set_column_justification(GTK_CLIST(w),1,GTK_JUSTIFY_RIGHT); } w=get_widget_by_widget_name("find_history_combo"); if(w) { gtk_combo_disable_activate(GTK_COMBO(w)); } load_profile_name_combo(); } /***********************************************/ /* load the combo containing all profile names */ /***********************************************/ void load_profile_name_combo(void) { GtkWidget *w; w=get_widget_by_widget_name("profile_name_combo"); if(w) { void *iter; GList *glst=NULL; GStringChunk *gsc=g_string_chunk_new(32); /* we must get all kets: "/PROGNAME/ProfileNames/" */ iter=gnome_config_init_iterator("/" PROGNAME "/ProfileNames/"); while(iter!=NULL) { char *prof_name=NULL; char *buf=NULL; iter=gnome_config_iterator_next(iter,&prof_name,&buf); if(iter!=NULL) { /* prof_name is the profile name, buf is unused */ if((prof_name!=NULL)&&(strlen(prof_name))) { glst=g_list_append(glst,g_string_chunk_insert(gsc,prof_name)); } } } if(glst!=NULL) { gtk_combo_set_popdown_strings(GTK_COMBO(w),glst); g_list_free(glst); } g_string_chunk_free(gsc); } } static void clist_add_uniq_row(GtkCList *w, char *nw[5]) { int i; char *t; for(i=0;irows;i++) { gtk_clist_get_text(w,i,0,&t); if(t==NULL) continue; if(strcmp(t,nw[0])) continue; gtk_clist_get_text(w,i,1,&t); if(t==NULL) continue; if(strcmp(t,nw[1])) continue; gtk_clist_get_text(w,i,2,&t); if(t==NULL) continue; if(strcmp(t,nw[2])) continue; gtk_clist_get_text(w,i,3,&t); if(t==NULL) continue; if(strcmp(t,nw[3])) continue; gtk_clist_get_text(w,i,4,&t); if(t==NULL) continue; if(strcmp(t,nw[4])) continue; /* we have found an identical row */ return; } gtk_clist_append(GTK_CLIST(w),nw); } /********************************************/ /* load the .done file list into done_clist */ /********************************************/ void load_done_xfer(char *fname,int with_clear) { GtkWidget *w; FILE *f; char buf[51200]; w=get_widget_by_widget_name("done_clist"); if(w==NULL) return; if(with_clear==1) gtk_clist_clear(GTK_CLIST(w)); f=fopen(fname,"rb"); if(f==NULL) return; gtk_clist_freeze(GTK_CLIST(w)); while(fgets(buf,sizeof(buf),f)!=NULL) { char *t; char *u; char *nw[5]; t=strrchr(buf,'\n'); if(t!=NULL) *t='\0'; /* string format is: nick|DL/remote_fic$v|local_fic|start_pos|filesize|start_time */ /* or: nick|XDL|local_fic|filesize */ t=strstr(buf,"|DL/"); if(t==NULL) { /* not a |DL/, maybe a |XDL| */ t=strstr(buf,"|XDL|"); if(t!=NULL) { gchar **fields; fields=g_strsplit(buf,"|",0); if(gchar_array_len(fields)==4) { nw[0]=fields[0]; /* nickname */ nw[1]=fields[3]; /* local filesize */ nw[2]=""; nw[3]="XDL (multiple sources)"; /* remote filename */ nw[4]=fields[2]; /* local filename */ clist_add_uniq_row(GTK_CLIST(w),nw); } g_strfreev(fields); } } else { /* it is a |DL/ */ *t='\0'; nw[0]=buf; nw[3]=strtok_r(t+4,"|",&u); if(nw[3]==NULL) continue; nw[4]=strtok_r(NULL,"|",&u); if(nw[4]==NULL) continue; t=strtok_r(NULL,"|",&u); if(t==NULL) continue; nw[1]=strtok_r(NULL,"|",&u); if(nw[1]==NULL) continue; nw[2]=""; t=strrchr(nw[3],'$'); if(t!=NULL) *t='\0'; clist_add_uniq_row(GTK_CLIST(w),nw); } } gtk_clist_thaw(GTK_CLIST(w)); fclose(f); } typedef struct { char *widget_name; char *var_name; } LNK; static void set_tos_string(char *widget_name, int tos_value) { char *t; switch(tos_value) { case 2: t=_("Low Cost"); break; case 4: t=_("High Reliability"); break; case 8: t=_("High Throughput"); break; case 16: t=_("Low Latency"); break; default: fprintf(stderr,"Unknown tos value: %d for %s\n",tos_value,widget_name); case 0: t=_("Normal"); break; } gtk_entry_set_text(GTK_ENTRY(get_widget_by_widget_name(widget_name)), t); } /************************************************************/ /* set all fields of preference_box according to vars value */ /************************************************************/ void fix_pref_window(void) { static const LNK v[]={ {"nickname_entry","nickname"}, {"user_description_entry","user_desc"}, {"cnx_type_entry","cnx_type"}, {"e_mail_entry","email"}, {"incoming_port_number_entry","com_port"}, {"xfer_host_ip_entry","hostip"}, {"dl_dir_entry","dl_path"}, {"socks_address_entry","socks_ip"}, {"socks_port_entry","socks_port"}, {"socks_userid_entry","socks_name"}, {"unodeport_entry","unode_port"}, {"min_gdl_wake_up_delay_entry","min_gdl_wake_up_delay"}, {"vshare_dir_entry","vshare_dir"}, {NULL,NULL}}; static const LNK tgl_bt[]={ {"enable_upload_checkbutton","dl_on"}, {"follow_forcemove_checkbutton","follow_force_move"}, {"md5sum_computation_checkbutton","with_md5sum"}, {"use_done_dir_checkbutton","when_done"}, {"ddl_checkbutton","with_ddl"}, {"dctclink_checkbutton","with_dctclink"}, {"force_dl_checkbutton","with_dl_force"}, {"hide_abscheckbutton","hide_absolute"}, {"hide_kick_checkbutton","hide_kick"}, {"abort_upload_checkbutton","abort_upload_when_user_leaves"}, {"lazykc_checkbutton","lazy_key_check"}, {"incoming_wake_up_checkbutton","with_incoming_wake_up"}, {"sr_wake_up_checkbutton","with_sr_wake_up"}, {"dynipcheckbutton","dynamic_ip"}, {NULL,NULL}}; int i; const char *t; /* initialize gtk entry from base */ i=0; while(v[i].widget_name!=NULL) { t=get_var(v[i].var_name); if(t!=NULL) { gtk_entry_set_text(GTK_ENTRY(get_widget_by_widget_name(v[i].widget_name)), t); } else { if(current_dctc!=NULL) gtk_entry_set_text(GTK_ENTRY(get_widget_by_widget_name(v[i].widget_name)), ""); } i++; } /* adjust toggle buttons */ i=0; while(tgl_bt[i].widget_name!=NULL) { t=get_var(tgl_bt[i].var_name); if(t!=NULL) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( get_widget_by_widget_name(tgl_bt[i].widget_name)), atoi(t)); } i++; } t=get_var("offset"); if(t!=NULL) { double val; double scale[4]={1.0,1024.0, 1024.0*1024.0, 1024.0*1024.0*1024.0}; char *unit_name[4]={_("Bytes"), _("KBytes"), _("MBytes"), _("GBytes")}; int i=0; char buf[512]; val=strtod(t,NULL); while(i<3) { double res,ent; res=modf(val/scale[i+1],&ent); if(res!=0.0) break; i++; } gtk_entry_set_text(GTK_ENTRY(get_widget_by_widget_name("size_offset_unit_entry")), unit_name[i]); sprintf(buf,"%.0f",val/scale[i]); gtk_entry_set_text(GTK_ENTRY(get_widget_by_widget_name("size_offset_entry")), buf); } t=get_var("dl_slot"); if(t!=NULL) { gtk_adjustment_set_value( gtk_range_get_adjustment(GTK_RANGE( get_widget_by_widget_name("sim_dl_hscale"))), atoi(t)); } t=get_var("recon_delay"); if(t!=NULL) { gtk_adjustment_set_value( gtk_range_get_adjustment(GTK_RANGE( get_widget_by_widget_name("reconnect_delay_scale"))), atoi(t)); } t=get_var("auto_rebuild_delay"); if(t!=NULL) { gtk_adjustment_set_value( gtk_range_get_adjustment(GTK_RANGE( get_widget_by_widget_name("rebuild_delay_scale"))), atoi(t)/60); } t=get_var("max_running_source_per_gdl"); if(t!=NULL) { gtk_spin_button_set_value(GTK_SPIN_BUTTON( get_widget_by_widget_name("maxrunspinbutton")), atoi(t)); } t=get_var("max_dl_per_user"); if(t!=NULL) { gtk_spin_button_set_value(GTK_SPIN_BUTTON( get_widget_by_widget_name("maxudl_spinbutton")), atoi(t)); } t=get_var("disable_gdl_as_when_enough_running"); if(t!=NULL) { gtk_spin_button_set_value(GTK_SPIN_BUTTON( get_widget_by_widget_name("maxasoffspinbutton")), atoi(t)); } t=get_var("min_delay_between_search"); if(t!=NULL) { gtk_spin_button_set_value(GTK_SPIN_BUTTON( get_widget_by_widget_name("min_delay_between_search_spinbutton")), atoi(t)); } t=get_var("behind_fw"); if(t!=NULL) { if(atoi(t)==1) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( get_widget_by_widget_name("passive_mode_radio_button")), TRUE); } else { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( get_widget_by_widget_name("active_mode_radio_button")), TRUE); } } { GtkWidget *w; w=get_widget_by_widget_name("shared_dir_clist"); if(w!=NULL) { GtkWidget *w2; char *pt, *pos,*nxt; w2=get_widget_by_widget_name("hidden_shared_dir_entry"); gtk_clist_freeze(GTK_CLIST(w)); gtk_clist_clear(GTK_CLIST(w)); t=get_var("ul_path"); if(t==NULL) { /* if ul_path does not exist, we use "hidden_shared_dir_entry" content */ t=gtk_entry_get_text(GTK_ENTRY(w2)); } pt=strdup(t); /* we put its value into "hidden_shared_dir_entry" so it will be saved */ gtk_entry_set_text(GTK_ENTRY(w2),pt); pos=strtok_r(pt,"|",&nxt); while(pos!=NULL) { gtk_clist_append(GTK_CLIST(w),&pos); pos=strtok_r(NULL,"|",&nxt); } free(pt); gtk_clist_thaw(GTK_CLIST(w)); } } /* set xbl values */ { struct { char *cmd_name; char *check_widget; char *val_widget; } sema_bl[]={ {"ubl","ubl_checkbutton","ubl_entry"}, {"dbl","dbl_checkbutton","dbl_entry"}, {"gbl","gbl_checkbutton","gbl_entry"}, {NULL,NULL,NULL}}; i=0; while(sema_bl[i].cmd_name!=NULL) { t=get_var(sema_bl[i].cmd_name); if(t!=NULL) { if(atoi(t)==SEMVMX) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( get_widget_by_widget_name(sema_bl[i].check_widget)),FALSE); } else { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( get_widget_by_widget_name(sema_bl[i].check_widget)),TRUE); gtk_entry_set_text(GTK_ENTRY(get_widget_by_widget_name(sema_bl[i].val_widget)), t); } } i++; } } t=get_var("cnx_opt"); if(t!=NULL) { unsigned int v=atoi(t); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( get_widget_by_widget_name("away_togglebutton")), ((v&2)?TRUE:FALSE)); } t=get_var("cnx_status"); if(t!=NULL) { /* we have a connection status */ GtkWidget *w; w=get_widget_by_widget_name("appbar1"); if(w!=NULL) { unsigned int a; a=atoi(t); gnome_appbar_clear_stack(GNOME_APPBAR(w)); switch(a&3) { case 3: /* green, connection established */ gnome_appbar_set_status(GNOME_APPBAR(w),_("Online")); break; case 1: /* orange, connection in progress */ gnome_appbar_set_status(GNOME_APPBAR(w),_("Trying to establish connection with hub")); break; default: /* red, connection lost */ case 2: case 0: t=get_var("main_sck"); if((t==NULL)||(t[0]!='=')||(t[1]!='>')) { gnome_appbar_set_status(GNOME_APPBAR(w),"Offline"); } else { char buf_time[512]; struct tm tm; GString *rcn_msg; time_t tt; tt=atoi(t+2); localtime_r(&tt,&tm); strftime(buf_time,sizeof(buf_time)-1,"%c",&tm); rcn_msg=g_string_new(_("Offline, reconnect time: ")); rcn_msg=g_string_append(rcn_msg,buf_time); gnome_appbar_set_status(GNOME_APPBAR(w),rcn_msg->str); g_string_free(rcn_msg,TRUE); } w=get_widget_by_widget_name("user_clist"); if(w!=NULL) gtk_clist_clear(GTK_CLIST(w)); break; } } } { GtkWidget *w; w=get_widget_by_widget_name("current_hub_address_label"); if(w!=NULL) { t=get_var("hub_addr"); if(t==NULL) { gtk_label_set(GTK_LABEL(w),""); } else { gtk_label_set(GTK_LABEL(w),t); } } } { GtkWidget *w; w=get_widget_by_widget_name("dctc_version_label"); if(w!=NULL) { t=get_var("version"); if(t==NULL) { gtk_label_set(GTK_LABEL(w),""); } else { gtk_label_set(GTK_LABEL(w),t); } } } t=get_var("tos"); if(t!=NULL) { unsigned int hub_tos,udp_tos,dl_tos,ul_tos; if(sscanf(t,"%u,%u,%u,%u",&hub_tos,&udp_tos,&dl_tos,&ul_tos)!=4) { fprintf(stderr,"Invalid \"tos\" variable, 4 values are required and '%s' is given.\n",t); } else { set_tos_string("hub_tos_entry",hub_tos); set_tos_string("udp_tos_entry",udp_tos); set_tos_string("dl_tos_entry",dl_tos); set_tos_string("ul_tos_entry",ul_tos); } } } static int compare_pid(const void *a, const void *b) { return *((pid_t*)a) - *((pid_t*)b); } /******************************/ /* periodic functions to call */ /******************************/ gint running_client_list_periodic_refresh(gpointer data) { GtkWidget *rhcw; /* the following function is nearly identical to fill_running_hub_clist */ /* the main difference is it does not clear the clist before starting */ rhcw=get_widget_by_widget_name("running_hub_clist"); if(rhcw) { GtkCList *clist; GArray *pid_array; pid_t the_pid; int i; clist=GTK_CLIST(rhcw); gtk_clist_freeze(clist); clean_directory(dctc_dir->str); pid_array=g_array_new(FALSE,FALSE,sizeof(pid_t)); /* we read the directory ~/.dctc/running */ /* each entry has the format "dctc-xxxxxxxx-aaaaaaaaaaaa" where xxxxxxxx is the dctc pid (8 hexdigits) and aaaaaaaaa is the hubname */ { DIR *dir; dir=opendir(dctc_dir->str); if(dir!=NULL) { struct dirent *obj; while((obj=readdir(dir))!=NULL) { char *ent[7]; int a; char *hn; int row_num; int stt; char str_gdl[20]; char str_ul[20]; char str_users[20]; unsigned long cli_param[NB_LONG_PER_ENTRY]; GdkColor *row_col; if(strncmp(obj->d_name,"dctc-",5)) continue; a=strlen(obj->d_name); if((a>5)&&(!strcmp(obj->d_name+a-5,".done"))) continue; if((a>4)&&(!strcmp(obj->d_name+a-4,".udp"))) continue; if((a>9)&&(!strcmp(obj->d_name+a-9,".userinfo"))) continue; hn=get_hubname_from_recent(obj->d_name+5+8+1); ent[0]=obj->d_name+5+8+1; ent[1]=obj->d_name; if(hn!=NULL) ent[2]=hn; else ent[2]=""; sscanf(obj->d_name+5,"%08X",&the_pid); stt=get_client_status(the_pid,cli_param); switch(stt) { default: case NOT_EXIST: ent[3]=""; ent[4]=""; ent[5]=""; ent[6]=""; row_col=&white; break; case IS_OFFLINE: ent[3]="0"; ent[4]=str_gdl; ent[5]=str_ul; ent[6]=(((FLAG1_STRUCT)(cli_param[GSTATUS_FLAG1])).bf.is_clock_master)?_("Master"):""; sprintf(str_gdl,"%lu",cli_param[GSTATUS_NB_GDL]); sprintf(str_ul,"%lu",cli_param[GSTATUS_NB_UL]); row_col=&light_orange; break; case IS_ONLINE: ent[3]=str_users; sprintf(str_users,"%lu",cli_param[GSTATUS_NB_USERS]); ent[4]=str_gdl; ent[5]=str_ul; ent[6]=(((FLAG1_STRUCT)(cli_param[GSTATUS_FLAG1])).bf.is_clock_master)?_("Master"):""; sprintf(str_gdl,"%lu",cli_param[GSTATUS_NB_GDL]); sprintf(str_ul,"%lu",cli_param[GSTATUS_NB_UL]); row_col=&green; break; } /* add the pid to the list of encountered pid */ pid_array=g_array_append_val(pid_array,the_pid); row_num=gtk_clist_find_row_from_data(clist,GINT_TO_POINTER(the_pid)); if(row_num==-1) /* this should occurs when a new running client appears */ { row_num=gtk_clist_append(clist,ent); gtk_clist_set_row_data(clist,row_num,GINT_TO_POINTER(the_pid)); } else { /* the only changing columns are the columns: 3,4,5 and 6 */ gtk_clist_set_text(clist,row_num,3,ent[3]); gtk_clist_set_text(clist,row_num,4,ent[4]); gtk_clist_set_text(clist,row_num,5,ent[5]); gtk_clist_set_text(clist,row_num,6,ent[6]); } gtk_clist_set_background(clist,row_num,row_col); } closedir(dir); } } /* now, we must remove clist row having a pid not in pid_array */ if(pid_array->len!=clist->rows) { /* the number of clist rows and pid are different, we must really do some cleaning */ qsort(pid_array->data,pid_array->len,sizeof(pid_t),compare_pid); i=clist->rows-1; while(i>=0) { the_pid=GPOINTER_TO_INT(gtk_clist_get_row_data(clist,i)); if(bsearch(&the_pid,pid_array->data,pid_array->len,sizeof(pid_t),compare_pid)==NULL) { /* the value no more exists */ gtk_clist_remove(clist,i); } i--; } } gtk_clist_thaw(clist); g_array_free(pid_array,TRUE); } colorize_favorite(GTK_CLIST(get_widget_by_widget_name("hub_favorite_clist")),GTK_CLIST(rhcw)); return TRUE; /* don't stop periodic calling */ } gint favorite_client_periodic_autostart(gpointer data) { int i; GtkWidget *rhcw; GtkCList *fav_clist; if(auto_start_disabled==TRUE) /* auto start client is disabled */ return TRUE; rhcw=get_widget_by_widget_name("hub_favorite_clist"); if(rhcw==NULL) return TRUE; fav_clist=GTK_CLIST(rhcw); /* scan the favorite clist and find row not in green (==running client) */ /* and having the autoscan flag set */ i=0; while(irows) { GtkCListRow *crow; crow=g_list_nth(fav_clist->row_list,i)->data; if(memcmp(&(crow->background),&green,sizeof(green))) { /* green row are running one */ char *flg; if(gtk_clist_get_text(fav_clist,i,4,&flg)) { if(flag_is_set(flg,AUTOSTART_FLAG)) { char *col; char *prof_name; if( (gtk_clist_get_text(fav_clist,i,2,&col))&& (gtk_clist_get_text(fav_clist,i,3,&prof_name)) ) { if((prof_name==NULL)||(strlen(prof_name)==0)) start_a_new_dctc(col,1,NULL); else start_a_new_dctc(col,1,prof_name); break; /* don't start more than one client at the same time */ } } } } i++; } return TRUE; /* don't stop periodic calling */ }