/******************************************************************** Copyright (C) 2000 Bassoukos Tassos This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include "tasks.h" #include "connection.h" #include "protocol.h" #include "messages.h" #include "transaction.h" #include "guiprefs.h" #include "guiutils.h" #include "files.h" #include "filelist.h" #include "filetransfer.h" #include "smalltrans.h" #include "privs.h" #include "pixmap.h" #include "hldat.h" #define FILES "Files" static void files_transfer_folder(FileData *fd,TransferFolder *tf,gboolean is_download); static void remote_dir_download_check(TransferFolder *tf); static void transfer_folder_destroy(TransferFolder *tf); /* ====================================== */ static void fileinfo_close(GtkButton *b,GtkWidget *top){ gtk_widget_destroy(top); } static void fileinfo_delete(GtkButton *b,GdkEvent *ev,GtkWidget *top){ gtk_widget_destroy(top); } static void create_fileinfo(Connection *c,FileEntry *fe, char *comment, time_t mod_t, time_t cre_t){ GtkWidget *top,*table,*hbox,*vbox,*pixmap; GtkWidget *name_w,*t; GdkPixmap *pix,*mask; char buf[128],buf2[128]; top=gnome_dialog_new(_("File Info"),GNOME_STOCK_BUTTON_CLOSE,NULL); vbox=GNOME_DIALOG(top)->vbox; hbox=gtk_hbox_new(FALSE,0); gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,2); fileentry_get_icon(fe,&pix,&mask); pixmap=gtk_pixmap_new(pix,mask); gtk_box_pack_start(GTK_BOX(hbox),pixmap,FALSE,FALSE,2); name_w=gtk_entry_new(); if(fe->name!=NULL) gtk_entry_set_text(GTK_ENTRY(name_w),fe->name); gtk_entry_set_editable(GTK_ENTRY(name_w),FALSE); gtk_box_pack_start(GTK_BOX(hbox),name_w,TRUE,TRUE,2); hbox=gtk_hbox_new(FALSE,0); gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,2); table=gtk_table_new(2,5,FALSE); gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(_("File type : ")),0,1,0,1); gtk_misc_set_alignment(GTK_MISC(t),1.0,0.0); gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(_("File creator : ")),0,1,1,2); gtk_misc_set_alignment(GTK_MISC(t),1.0,0.0); gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(_("Date modified : ")),0,1,2,3); gtk_misc_set_alignment(GTK_MISC(t),1.0,0.0); gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(_("Date created : ")),0,1,3,4); gtk_misc_set_alignment(GTK_MISC(t),1.0,0.0); gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(_("Size : ")),0,1,4,5); gtk_misc_set_alignment(GTK_MISC(t),1.0,0.0); gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new((fe->type==NULL || fe->is_folder)?"n/a":fe->type),1,2,0,1); gtk_misc_set_alignment(GTK_MISC(t),0.0,0.0); gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new((fe->creator==NULL || fe->is_folder)?"n/a":fe->creator),1,2,1,2); gtk_misc_set_alignment(GTK_MISC(t),0.0,0.0); strcpy(buf,ctime(&mod_t));buf[strlen(buf)-1]=0; gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(buf),1,2,2,3); gtk_misc_set_alignment(GTK_MISC(t),0.0,0.0); strcpy(buf,ctime(&cre_t));buf[strlen(buf)-1]=0; gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(buf),1,2,3,4); gtk_misc_set_alignment(GTK_MISC(t),0.0,0.0); if(fe->is_folder){ strcpy(buf,"n/a"); } else { if(fe->size>1024){ if(fe->size>(1024*1024)){ sprintf(buf2,"%d MB",fe->size>>20); } else { sprintf(buf2,"%d KB",fe->size>>10); } sprintf(buf,"%s (%d bytes)",buf2,fe->size); } else { sprintf(buf,"%d bytes",fe->size); } } gtk_table_attach_defaults(GTK_TABLE(table),t=gtk_label_new(buf),1,2,4,5); gtk_misc_set_alignment(GTK_MISC(t),0.0,0.0); gtk_box_pack_start(GTK_BOX(hbox),table,FALSE,FALSE,2); pixmap=gtk_label_new(_("Comment:")); gtk_misc_set_alignment(GTK_MISC(pixmap),0.0,0.0); gtk_box_pack_start(GTK_BOX(vbox),pixmap,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(vbox),t=gtk_text_new(NULL,NULL),TRUE,TRUE,0); if(comment!=NULL) gtk_text_insert(GTK_TEXT(t),NULL,NULL,NULL,comment,strlen(comment)); gnome_dialog_button_connect(GNOME_DIALOG(top),0, GTK_SIGNAL_FUNC(fileinfo_close), (gpointer)top); gtk_signal_connect(GTK_OBJECT(top),"delete-event", GTK_SIGNAL_FUNC(fileinfo_delete), (gpointer)top); gtk_signal_connect_object_while_alive(GTK_OBJECT(c),"destroy", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(top)); gtk_widget_show_all(top); } /* ====================================== */ static void localfiles_chdir_to_path(FileList *fl,int num,gpointer data); void fileentry_free(FileEntry *fe){ if(fe){ if(fe->name!=NULL) free(fe->name); free(fe); } } FileEntry *fileentry_new_from_object(HLObject *o){ FileEntry *fe=(FileEntry *)malloc(sizeof(FileEntry)); fe->name=strdup(o->data.filelistentry->name); memcpy(fe->type,o->data.filelistentry->f.type,4); memcpy(fe->creator,o->data.filelistentry->f.creator,4); fe->type[4]=0;fe->creator[4]=0; fe->is_folder=FALSE; fe->is_selected=FALSE; if(strncmp(fe->type,"fldr",4)==0) fe->is_folder=TRUE; else fe->is_folder=FALSE; fe->size=o->data.filelistentry->f.size; return fe; } FileEntry *fileentry_new_from_stat(char *name, struct stat *buf){ FileEntry *fe=(FileEntry *)malloc(sizeof(FileEntry)); fe->name=strdup(name); strcpy(fe->type,"n/a"); strcpy(fe->creator,"n/a"); if(S_ISDIR(buf->st_mode)){ fe->size=buf->st_nlink; fe->is_folder=TRUE; } else { fe->size=buf->st_size; fe->is_folder=FALSE; } fe->is_selected=FALSE; return fe; } void fileentry_get_icon(FileEntry *fe, GdkPixmap **icon, GdkPixmap **mask){ char *name=NULL; int icon_num=-1; static struct { int icon; char *ext; char *type; char *creator; } types[]={ {402,".hpf","HTft","HTLC"}, {403,".sit","SIT5", NULL }, {403,".hqx", NULL , NULL }, {404,".txt","TEXT", NULL }, {405,".pdf", NULL , NULL }, {405,".doc", NULL , NULL }, {406,".gif","GIFf", NULL }, {406,".jpg","JPEG", NULL }, {406,".jpeg","JPEG",NULL }, {406,".png", NULL , NULL }, {407,".exe","DEXE", NULL }, {407, NULL ,"APPL", NULL }, {423,".iso","rohd", NULL }, {424,".mp3","Mp3 ", NULL }, {424,".wav","WAVE", NULL }, {424,".au" , NULL , NULL }, {424,".aif","AIFF", NULL }, {425,".mov","MooV", NULL }, {425,".avi","VfW ", NULL }, {425,".mpg","MPEG", NULL }, {425,".mpeg","MPEG",NULL }, {425,".moov","MooV",NULL }, {426,".zip","ZIP ","ZIP "}, {425,".gz" , NULL , NULL }, {425,".tgz", NULL , NULL }, {-1,NULL,NULL,NULL} }; char buf[1024]; strcpy(buf,fe->name); g_strdown(buf); if(fe->is_folder){ if(strstr(buf,"upload")!=NULL || strstr(buf,"drop box")) { icon_num=421; name="folder_green"; } else { icon_num=401; name="folder_blue"; } } else { int len=strlen(buf); int i; icon_num=400; if(strncmp(fe->type,"HTft",4)==0) { name="file_red"; } else { name="file"; } for(i=0;types[i].icon!=-1;i++){ if(types[i].ext!=NULL){ int l=strlen(types[i].ext); if(ltype)==0){ icon_num=types[i].icon; break; } } } if(icon_num!=-1){ get_image_of_icon(icon_num,icon,mask); if(icon!=NULL && *icon==NULL) icon_num=-1; } if(icon_num==-1) pixmap_get(name,icon,mask); } void file_format_size(char *buf,int size, gboolean with_bytes){ if(files_small_sizes==FALSE || size<1024) sprintf(buf,"%d%s",size,with_bytes?_(" bytes"):""); else if(size>=1024.0*1024.0) sprintf(buf,_("%.1f MB"),size/(1024.0*1024.0)); else sprintf(buf,_("%.1f KB"),size/1024.0); } static gboolean files_cache_remove_item(gpointer key, gpointer value, gpointer data){ free(key); objects_destroy((HLObject **)data); return TRUE; } static void files_clear_cache(gpointer dummy, FileData *f){ if(f->remote_cache) { g_hash_table_foreach_remove(f->remote_cache,files_cache_remove_item,NULL); g_hash_table_destroy(f->remote_cache); f->remote_cache=NULL; } } char *files_get_path(FileList *fl){ char *p,*t; if(fl->numpaths<=0) return strdup("/"); p=g_strjoinv("/",fl->path); t=g_strconcat("/",p,NULL); free(p); return t; } /* ================================================= */ static void localfiles_refresh(FileList *fl, gpointer data){ FileData *f=(FileData *)data; int count=0,alloc=0; FileEntry **fe=NULL; DIR *dir; char *path=NULL,*t=NULL; struct stat buf; struct dirent *d; path=files_get_path(f->local_files); if(!(dir=opendir(path))){ show_error_errno(f->c,NULL,path); free(path); count=f->local_files->numpaths-2; if(count<-1) count=-1; localfiles_chdir_to_path(f->local_files,count,f); return; } while((d=readdir(dir))){ if((hide_local_dotfiles==TRUE && d->d_name[0]=='.') || strcmp(d->d_name,".")==0 || strcmp(d->d_name,"..")==0) continue; if(t!=NULL) free(t); t=g_strconcat(path,"/",d->d_name,NULL); if(stat(t,&buf)!=0){ show_error_errno(f->c,NULL,t); continue; } if(count==alloc){ if(alloc==0) alloc=10; else alloc*=2; fe=realloc(fe,sizeof(FileEntry *)*alloc); } fe[count++]=fileentry_new_from_stat(d->d_name,&buf); } if(t!=NULL) free(t); free(path); closedir(dir); filelist_clear(f->local_files); filelist_set_contents(f->local_files,count,fe); } static char **files_parse_path(char *path) { char **v; if(strcmp(path,"/")==0) v=NULL; else { while(path[0]=='/') path++; v=g_strsplit(path,"/",-1); } return v; } static void localfiles_chdir_to(FileData *f,char *path){ filelist_set_path(f->local_files,files_parse_path(path)); localfiles_refresh(NULL,f); } static void localfiles_chdir_to_path(FileList *fl,int num,gpointer data){ FileData *f=(FileData *)data; char *path,*t; if(num==-1){ localfiles_chdir_to(f,"/"); return; } if(num==fl->numpaths-1) return; t=fl->path[num+1]; fl->path[num+1]=NULL; path=files_get_path(fl); fl->path[num+1]=t; localfiles_chdir_to(f,path); if(fl->view > fl->numpaths) filelist_viewpopsel(fl); free(path); } static void localfiles_change_selection(FileList *fl,gpointer data){ FileData *fd=(FileData *)data; gutils_nbpage_toolbar_set_sensitive(fd->notebook_page,2, (fl->count_selected>0 && privs_check(fd->c,PRIV_UPLOAD_FILE) && fd->recursive_transfer==FALSE) ?TRUE:FALSE); } static void localfiles_select_one(FileList *fl,FileEntry *which,gpointer data){ FileData *fd=(FileData *)data; if(which->is_folder==TRUE){ char *p=files_get_path(fl); char *t=g_strconcat(p,"/",which->name,NULL); free(p); localfiles_chdir_to(fd,t); free(t); } else { filetransfer_start(fd,TRUE,which); } } static void localfiles_mkdir(FileList *fl,char *name, gpointer data){ char *p,*t; if(name==NULL || strlen(name)==0) return; p=files_get_path(fl); t=g_strconcat(p,"/",name,NULL); free(p); if(mkdir(t,0777)==-1) show_error_errno(((FileData *)data)->c,NULL,_("Could not create directory\n%s:\n"),t); free(t); } static void dir_clean(char *path, Connection *c) { DIR *mydir; char buf[1024]; struct stat myst; struct dirent *myfile; mydir = opendir(path); /* grmbl ... dirent->d_type isn't implemented. We'll have to use stat */ while((myfile = readdir(mydir))) { if(!strcmp(myfile->d_name, "..") || !strcmp(myfile->d_name, ".")) continue; g_snprintf(buf, 1024, "%s/%s", path, myfile->d_name); lstat(buf, &myst); if(S_ISDIR(myst.st_mode)) { dir_clean(buf, c); if(rmdir(buf)) show_error_errno(c,NULL,_("Unable to remove\n%s:\n"),buf); } else unlink(buf); } } static void localfiles_delete(FileList *fl,int which, gpointer data){ char *p,*t; if(which==-1) return; p=files_get_path(fl); t=g_strconcat(p,"/",fl->files[which]->name,NULL); free(p); if(fl->files[which]->is_folder) dir_clean(t,((FileData *)data)->c); if(remove(t)==-1) show_error_errno(((FileData *)data)->c,NULL,_("Unable to remove\n%s:\n"),t); free(t); } static void localfiles_stat(FileList *fl,FileEntry *which, gpointer data){ char *p,*t; struct stat st; if(which==NULL) return; p=files_get_path(fl); t=g_strconcat(p,"/",which->name,NULL); free(p); if(lstat(t,&st)==-1) show_error_errno(((FileData *)data)->c,NULL,_("Unable to stat\n%s:\n"),t); else { create_fileinfo(((FileData *)data)->c,which,NULL,st.st_mtime,st.st_ctime); } free(t); } static void local_start_upload(FileList *fl, FileEntry *which, gpointer data){ FileData *fd=(FileData *)data; if(!which->is_folder) filetransfer_start(fd,TRUE,which); } /* =================================================== */ static char **headandappend_path(char **path,int count,char *tail){ char **p; int i; if(count<0) return NULL; p=malloc(sizeof(char *)*(count+((tail==NULL)?1:2))); for(i=0;inotebook_page,3, (fl->count_selected>0 && privs_check(fd->c,PRIV_DOWNLOAD_FILE) && fd->recursive_transfer==FALSE) ?TRUE:FALSE); } static void remote_filelist_fill_from_objects(FileData *fd,HLObject **ob){ FileEntry **fe=NULL; int i,count; if(ob==NULL){ filelist_set_contents(fd->remote_files,0,NULL); return; } for(count=0;ob[count]!=NULL;count++); if(count==0) return; fe=malloc(sizeof(FileData *)*count); for(i=0;iremote_files,count,fe); if(fd->recursive_transfer==TRUE && fd->recursive_is_download==TRUE && fd->recursive_folders_list!=NULL){ remote_dir_download_check(fd->recursive_folders_list->data); } } static void remote_filelist_fill_list(Transaction *t,Message *m,FileData *f){ HLObject **o; int count; char *p; if(!message_is_error(m)){ o=message_extract_objects(m,HLO_FILEENTRY,&count); p=files_get_path(f->remote_files); g_hash_table_insert(f->remote_cache,p,o); remote_filelist_fill_from_objects(f,o); } f->t=NULL; } static void remote_refresh(FileList *fl,gpointer data){ FileData *f=(FileData *)data; char *p,*s; Transaction *t; HLObject **ob; if(f->t!=NULL) return; filelist_clear(f->remote_files); p=files_get_path(fl); if((ob=g_hash_table_lookup(f->remote_cache,p))!=NULL){ remote_filelist_fill_from_objects(f,ob); free(p); return; } filelist_set_busy(f->remote_files); t=transaction_new(fl->c,HLCT_FOLDERLIST); f->t=t; if(f->remote_files->numpaths>0){ message_add_object(t->request,path_new(f->remote_files->path, f->remote_files->numpaths)); } s=g_strdup_printf(_("Retrieving %s ..."),p); transaction_add_task(t,s,HL_STOCK_PIXMAP_FILES,0.1); transaction_set_error_check(t,strdup(_("Can't list directory:"))); gtk_signal_connect(GTK_OBJECT(t),"response-received", GTK_SIGNAL_FUNC(remote_filelist_fill_list),f); transaction_start(t); free(p); free(s); } static void remote_real_refresh(FileList *fl,gpointer data){ FileData *f=(FileData *)data; char *p,*orig_p; HLObject **ob; if(f->t!=NULL) return; p=files_get_path(fl); if(g_hash_table_lookup_extended(f->remote_cache,p, (gpointer *)&orig_p, (gpointer *)&ob)==TRUE){ g_hash_table_remove(f->remote_cache,p); free(orig_p); objects_destroy(ob); } free(p); remote_refresh(fl,data); } static void remote_chdir_to_path(FileList *fl,int num,gpointer data){ FileData *f=(FileData *)data; char **p; if(f->t!=NULL || num==fl->numpaths) return; if(num==-1) p=NULL; else p=headandappend_path(fl->path,num+1,NULL); filelist_set_path(fl,p); remote_refresh(fl,f); if(fl->view > fl->numpaths) filelist_viewpopsel(fl); } static void remote_mkdir(FileList *fl,char *name, gpointer data){ Transaction *t; FileData *f=(FileData *)data; if(name==NULL || strlen(name)==0) return; t=transaction_new(f->c,HLCT_CREATEFOLDER); message_add_object(t->request,create_string(HLO_FILENAME,name)); if(fl->numpaths>0){ message_add_object(t->request,path_new(fl->path, fl->numpaths)); } transaction_set_error_check(t,strdup(_("Could not make directory:\n"))); transaction_add_task(t,_("Creating directory..."),HL_STOCK_PIXMAP_FILES,0.5); transaction_start(t); } static void remote_delete(FileList *fl,int which, gpointer data){ FileData *f=(FileData *)data; Transaction *t; if(which==-1) return; t=transaction_new(f->c,HLCT_MOVETOTRASH); message_add_object(t->request,create_string(HLO_FILENAME,fl->files[which]->name)); if(fl->numpaths>0){ message_add_object(t->request,path_new(fl->path, fl->numpaths)); } transaction_set_error_check(t,strdup(_("Could not delete:\n"))); transaction_add_task(t,_("Deleting..."),HL_STOCK_PIXMAP_FILES,0.5); transaction_start(t); } static void remote_got_stat(Transaction *t,Message *m,FileData *f){ HLObject *filename,*comment=NULL,*size,*type,*creator,*created,*modified; FileEntry fe; time_t mod_t,cre_t; if(message_is_error(m)) return; filename=message_find_object(m,HLO_FILENAME); comment=message_find_object(m,HLO_COMMENT); size=message_find_object(m,HLO_INFOSIZE); created=message_find_object(m,HLO_INFOCREATED); modified=message_find_object(m,HLO_INFOMODIFIED); creator=message_find_object(m,HLO_INFOCREATOR); type=message_find_object(m,HLO_INFOTYPE); fe.name=filename->data.string; if(size!=NULL) fe.size=size->data.number; else fe.size=0; strncpy(fe.type,type->data.string,4); strncpy(fe.creator,creator->data.string,4); fe.type[4]=0;fe.creator[5]=0; mod_t=date_to_unix(modified->data.datetime); cre_t=date_to_unix(created->data.datetime); fe.is_folder=(strncmp(fe.type,"fldr",4)==0)?TRUE:FALSE; create_fileinfo(f->c,&fe,comment==NULL?NULL:comment->data.string,mod_t,cre_t); } static void remote_stat(FileList *fl,FileEntry *which, gpointer data){ FileData *f=(FileData *)data; Transaction *t; char *s; if(which==NULL) return; t=transaction_new(f->c,HLCT_GETFILEINFO); message_add_object(t->request,create_string(HLO_FILENAME,which->name)); if(fl->numpaths>0){ message_add_object(t->request,path_new(fl->path, fl->numpaths)); } gtk_signal_connect(GTK_OBJECT(t),"response-received", GTK_SIGNAL_FUNC(remote_got_stat),f); s=g_strdup_printf(_("Retrieving info for %s..."),which->name); transaction_add_task(t,s,HL_STOCK_PIXMAP_FILE_INFO,0.5); transaction_set_error_check(t,strdup(_("Can't get file info:\n%s"))); transaction_start(t); free(s); } static void remote_select_one(FileList *fl,FileEntry *which,gpointer data){ FileData *fd=(FileData *)data; if(which->is_folder==TRUE){ char **p=headandappend_path(fl->path,fl->numpaths,which->name); filelist_set_path(fl,p); remote_refresh(fl,fd); } else { filetransfer_start(fd,FALSE,which); } } static void remote_dir_download_check(TransferFolder *tf) { FileList *mylist = tf->fd->remote_files; if(mylist->numfiles>0){ /* We only do this for directories with files */ filelist_select_all(mylist); filelist_start_transfer(mylist); } transfer_folder_destroy(tf); } static void remote_dir_download(TransferFolder *tf) { char *buf,*local_name; FileList *local; struct stat st; FileList *mylist = tf->fd->remote_files; local = tf->fd->local_files; localfiles_chdir_to(tf->fd, tf->local_path); local_name=files_convert_name_to_local(tf->folder_name); buf=g_strconcat(tf->local_path, "/", local_name, NULL); if(stat(buf, &st) && errno == ENOENT) localfiles_mkdir(local, local_name, tf->fd); localfiles_chdir_to(tf->fd, buf); free(local_name); free(buf); buf=g_strconcat(tf->remote_path, "/", tf->folder_name, NULL); filelist_set_path(mylist, files_parse_path(buf)); remote_refresh(mylist, tf->fd); free(buf); } static void remote_start_download(FileList *fl, FileEntry *which, gpointer data){ FileData *fd=(FileData *)data; if(which->is_folder==FALSE) filetransfer_start(fd,FALSE,which); else if(enable_recursive_downloads) { if(!which->size){ localfiles_mkdir(fd->local_files, which->name, fd); } else { TransferFolder *tf=malloc(sizeof(TransferFolder)); tf->local_path = files_get_path(fd->local_files); tf->remote_path = files_get_path(fl); tf->folder_name = strdup(which->name); tf->fd=fd; if(!fd->recursive_orig_remote_path) filelist_viewpush(fl, gtk_clist_find_row_from_data(GTK_CLIST(fl->list), which)); files_transfer_folder(fd,tf,TRUE); } } } static gboolean files_start_folder_transfer(FileData *fd){ TransferFolder *tf; if(fd->recursive_folders_list==NULL){ fd->recursive_transfer=FALSE; /* NOTREACHED */ return FALSE; } tf=fd->recursive_folders_list->data; if(fd->recursive_is_download){ remote_dir_download(tf); } else { /* FIXME */ } return FALSE; } static void files_check_gui_sensitive(FileData *fd){ gboolean is_recursive=fd->recursive_transfer?FALSE:TRUE; gtk_widget_set_sensitive(fd->local_files->frame,is_recursive); gtk_widget_set_sensitive(fd->remote_files->frame,is_recursive); localfiles_change_selection(fd->local_files,fd); remote_change_selection(fd->local_files,fd); } static void transfer_folder_destroy(TransferFolder *tf){ FileData *fd=tf->fd; fd->recursive_folders_list=g_list_remove(fd->recursive_folders_list,tf); free(tf->folder_name); free(tf->local_path); free(tf->remote_path); free(tf); if(fd->recursive_folders_list==NULL){ filelist_set_path(fd->remote_files,files_parse_path(fd->recursive_orig_remote_path)); remote_refresh(fd->remote_files,fd); filelist_viewpopsel(fd->remote_files); localfiles_chdir_to(fd,fd->recursive_orig_local_path); fd->recursive_transfer=FALSE; fd->recursive_is_download=FALSE; if(fd->recursive_orig_local_path!=NULL) free(fd->recursive_orig_local_path); if(fd->recursive_orig_remote_path!=NULL) free(fd->recursive_orig_remote_path); fd->recursive_orig_local_path=NULL; fd->recursive_orig_remote_path=NULL; files_check_gui_sensitive(fd); } else { files_start_folder_transfer(fd); } } static void files_transfer_folder(FileData *fd,TransferFolder *tf,gboolean is_download){ fd->recursive_folders_list=g_list_append(fd->recursive_folders_list,tf); if(fd->recursive_transfer==FALSE){ fd->recursive_transfer=TRUE; fd->recursive_is_download=is_download; fd->recursive_orig_local_path=strdup(tf->local_path); fd->recursive_orig_remote_path=strdup(tf->remote_path); files_check_gui_sensitive(fd); gtk_idle_add((GSourceFunc)files_start_folder_transfer,fd); } } static void files_destroy_gui(gpointer dummy, FileData *f){ while(f->recursive_folders_list!=NULL){ transfer_folder_destroy(f->recursive_folders_list->data); } if(f->remote_files!=NULL) filelist_destroy(f->remote_files); if(f->local_files!=NULL) filelist_destroy(f->local_files); if(f->notebook_page!=NULL) gutils_nbpage_destroy(f->notebook_page); f->notebook_page=NULL; f->local_files=NULL; f->remote_files=NULL; } static void files_destroy(Connection *c,FileData *f){ connection_set_data(c,FILES,NULL); /* FIXME: crashes when you list a directory then * close the file pane. */ /* if(f->t!=NULL) transaction_destroy(f->trans); */ files_destroy_gui(NULL,f); files_clear_cache(NULL,f); gtk_signal_disconnect_by_data(GTK_OBJECT(c),f); free(f); } static void files_upload(GtkButton *b, gpointer data){ FileData *f=(FileData *)data; filelist_start_transfer(f->local_files); } static void files_download(GtkButton *b, gpointer data){ FileData *f=(FileData *)data; filelist_start_transfer(f->remote_files); } static GnomeUIInfo files_toolbar[]={ GNOMEUIINFO_ITEM_STOCK("Close",N_("Close userlist"), files_destroy_gui, HL_STOCK_PIXMAP_CLOSE_PAGE), GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_ITEM_STOCK(N_("Upload"),N_("Upload file(s)"), files_upload, HL_STOCK_PIXMAP_UPLOAD), GNOMEUIINFO_ITEM_STOCK(N_("Download"),N_("Upload file(s)"), files_download, HL_STOCK_PIXMAP_DOWNLOAD), GNOMEUIINFO_END }; static FLOps remote_ops={ TRUE, remote_change_selection, remote_real_refresh, remote_mkdir, remote_start_download, remote_delete, remote_chdir_to_path, remote_select_one, remote_stat }; static FLOps local_ops={ FALSE, localfiles_change_selection, localfiles_refresh, localfiles_mkdir, local_start_upload, localfiles_delete, localfiles_chdir_to_path, localfiles_select_one, localfiles_stat }; static void files_create_gui(FileData *f){ GtkWidget *paned; if(f->notebook_page!=NULL) return; f->notebook_page=gutils_nbpage_new("Main",files_toolbar,f->c,_("Files"),"files",f); paned=gtk_hpaned_new(); f->remote_files=filelist_new(f->c,&remote_ops,f); gtk_paned_add1(GTK_PANED(paned),f->remote_files->frame); f->local_files=filelist_new(f->c,&local_ops,f); gtk_paned_add2(GTK_PANED(paned),f->local_files->frame); guiprefs_add_paned(GTK_PANED(paned),"Main/Files/PanePos"); gutils_nbpage_set_main(f->notebook_page,paned); localfiles_chdir_to(f,default_local_dir); remote_chdir_to_path(f->remote_files,-1,f); } void check_files(Connection *c){ FileData *f; if((f=(FileData *)connection_get_data(c,FILES))==NULL){ f=(FileData *)malloc(sizeof(FileData)); connection_set_data(c,FILES,f); gtk_signal_connect(GTK_OBJECT(c),"destroy",GTK_SIGNAL_FUNC(files_destroy),f); /* hooks_create(c,FILES,f,NULL,files_destroy); */ f->c=c; f->local_files=NULL; f->remote_cache=g_hash_table_new(g_str_hash,g_str_equal); f->notebook_page=NULL; f->remote_files=NULL; f->t=NULL; f->recursive_transfer=FALSE; f->recursive_is_download=FALSE; f->recursive_folders_list=NULL; f->recursive_orig_local_path=NULL; f->recursive_orig_remote_path=NULL; } if(auto_open_files==TRUE) files_create_gui(f); } void show_files(Connection *c){ FileData *f=(FileData *)connection_get_data(c,FILES); if(f==NULL) check_files(c); f=(FileData *)connection_get_data(c,FILES); if(f->notebook_page==NULL) files_create_gui(f); gutils_nbpage_to_front(f->notebook_page); } char *files_convert_name_to_local(char *filename){ char *r; if(filename==NULL) return NULL; r=strdup(filename); if(strip_spaces_on_local_files==TRUE) g_strstrip(r); g_strdelimit(r,"/",'_'); if(sanitize_local_filenames==TRUE) g_strdelimit(r," <>|\\()[]*?",'_'); return r; }