?? downloads.c
字號:
do_download_regular_file(tcp_con_t *con, const char *filepath,size_t file_size,size_t *written,GtkTreeModel *model,GtkTreeIter *iter){ int rc; int fd; char *buff=NULL; ssize_t recv_len; ssize_t write_len; size_t total_write=0; ssize_t file_remains; int wait_max=TCP_DOWNLOAD_RETRY; if ( (!con) || (!filepath) || (!written) || (!model) || (!iter) ) return -EINVAL; buff=g_malloc(_MSG_BUF_SIZE); if (!buff) return -ENOMEM; fd=open(filepath,O_RDWR|O_EXCL|O_CREAT,S_IRWXU); if (fd<0) { if (errno == EEXIST) { GtkWidget *dialog=create_ipmsgDownloadOverWrite (); GtkWidget *label; gint result; g_assert(dialog); label=GTK_WIDGET(lookup_widget(dialog,"overwriteFileNameLabel")); gtk_label_set_text(GTK_LABEL(label),filepath); result=gtk_dialog_run (GTK_DIALOG (dialog)); switch (result) { case GTK_RESPONSE_OK: dbg_out("Accept for overwrite\n"); fd=open(filepath,O_RDWR|O_CREAT,S_IRWXU); if (fd<0) { err_out("Can not open file:%s %s (%d)\n",filepath,strerror(errno),errno); gtk_widget_destroy (dialog); rc=-errno; goto no_close_out; } break; default: if (errno) err_out("response:%d Can not open file:%s (%d)\n",result,strerror(errno),errno); else err_out("Can not open file %s fd: %d :%s (%d)\n",filepath,fd,strerror(errno),errno); gtk_widget_destroy (dialog); rc=-ENOENT; goto no_close_out; break; } err_out("Can not open file:%s (%d)\n",strerror(errno),errno); gtk_widget_destroy (dialog); } else{ err_out("Can not open file:%s (%d)\n",strerror(errno),errno); rc=-errno; goto no_close_out; } } retry_this_file: lseek(fd, 0,SEEK_SET); total_write=0; file_remains=file_size; dbg_out("Try to read %d byte total\n", file_remains); /* * 同期のためのselect */ wait_max=TCP_DOWNLOAD_RETRY; wait_peer: ipmsg_update_ui(); rc=wait_socket(con->soc,WAIT_FOR_READ,TCP_SELECT_SEC); if (rc<0) { --wait_max; if (wait_max) goto wait_peer; err_out("Can not wait for peer %s (%d)\n",strerror(-rc),-rc); goto file_close_out; } /* *読み取り */ wait_max=TCP_DOWNLOAD_RETRY; read_wait:/* 同期のためにウエイト付きで読む */ memset(buff,0,_MSG_BUF_SIZE); recv_len=(file_remains>_MSG_BUF_SIZE)?(_MSG_BUF_SIZE):(file_remains); recv_len=recv(con->soc,buff,recv_len,(MSG_PEEK)); /* 仮読み */ if ( (wait_max) && ( (!recv_len) || (errno == EINTR) || (errno == EAGAIN) ) ) { ipmsg_update_ui(); --wait_max; goto read_wait; } if (recv_len<0) { err_out("Can not peek message %s(errno:%d)\n",strerror(errno),errno); rc=-errno; goto file_close_out; /* err or end */ } recv_len=recv(con->soc,buff,recv_len,0); /* 読み込み */ while(recv_len >= 0){ write_len=write(fd,buff,recv_len); if (write_len<0) { err_out("Can not write file %s(errno:%d)\n",strerror(errno),errno); rc=-errno; goto file_close_out; /* err or end */ } total_write += write_len; file_remains -= recv_len; if (!GTK_IS_LIST_STORE (model)) { war_out("Download window is destroyed.\n"); rc=-EFAULT; /* 仮にEFAULTを返す */ goto file_close_out; /* window destory */ } gtk_list_store_set(GTK_LIST_STORE(model), iter, 2, total_write, -1); ipmsg_update_ui(); dbg_out("tcp write file :%d\n",total_write); if (file_remains==0){ dbg_out("OK :%d\n",total_write); rc=0; break; } retry_recv: wait_max=TCP_DOWNLOAD_RETRY; memset(buff,0,_MSG_BUF_SIZE); recv_len=(file_remains>_MSG_BUF_SIZE)?(_MSG_BUF_SIZE):(file_remains); recv_len=recv(con->soc,buff,recv_len,(MSG_PEEK)); if (recv_len<=0) { if ( (wait_max) && ((!recv_len) || (errno == EINTR) || (errno == EAGAIN) ) ) { ipmsg_update_ui(); --wait_max; goto retry_recv; } err_out("Can not recv message %s(errno:%d)\n",strerror(errno),errno); rc=-errno; goto file_close_out; /* err or end */ } recv_len=recv(con->soc,buff,recv_len,0); /* 読み込み */ } /* 0バイトファイル対策のためもう一度書き込む */ gtk_list_store_set(GTK_LIST_STORE(model), iter, 2, total_write, -1); ipmsg_update_ui(); rc=0; file_close_out: close(fd); no_close_out: *written=total_write; if (buff) g_free(buff); return rc;}intdo_download_directory(tcp_con_t *con, const char *top_dir,GtkTreeModel *model,GtkTreeIter *iter){ int rc; int fd; char *buff=NULL; ssize_t recv_len; ssize_t drop_len; size_t total_write=0; int wait_max=TCP_DOWNLOAD_RETRY; dir_request_t dir_info; char *current_dir; char *new_dir=NULL; gchar *regular_file; size_t written; gboolean is_cont=TRUE; if ( (!con) || (!top_dir) || (!model) || (!iter) ) return -EINVAL; if (!g_path_is_absolute(top_dir)) return -EINVAL; buff=g_malloc(_MSG_BUF_SIZE); if (!buff) return -ENOMEM; current_dir=g_strdup(top_dir); if (!current_dir) { g_free(buff); return -ENOMEM; } do{ /* * 同期のためのselect */ wait_max=TCP_DOWNLOAD_RETRY; wait_peer: ipmsg_update_ui(); rc=wait_socket(con->soc,WAIT_FOR_READ,TCP_SELECT_SEC); if (rc<0) { --wait_max; if (wait_max) goto wait_peer; err_out("Can not wait for peer %s (%d)\n",strerror(-rc),-rc); goto error_out; } /* *読み取り */ wait_max=TCP_DOWNLOAD_RETRY; read_wait:/* 同期のためにウエイト付きで読む */ memset(buff,0,_MSG_BUF_SIZE); recv_len=recv(con->soc,buff,_MSG_BUF_SIZE,(MSG_PEEK)); /* 仮読み */ if ( (wait_max) && ( (!recv_len) || (errno == EINTR) || (errno == EAGAIN) ) ) { ipmsg_update_ui(); --wait_max; goto read_wait; } if (recv_len<0) { err_out("Can not peek message %s(errno:%d)\n",strerror(errno),errno); rc=-errno; goto error_out; /* err or end */ } /* *一度で読み取れなければ再トライ */ memset(&dir_info,0,sizeof(dir_request_t)); rc=parse_dir_request(buff,&dir_info,recv_len); if (rc) { release_dir_info_contents(&dir_info); --wait_max; goto read_wait; } if (!dir_info.header_size) { release_dir_info_contents(&dir_info); break; } drop_len=dir_info.header_size; drop_len=recv(con->soc,buff,drop_len,0); /* ヘッダ読み捨て */ if (drop_len<0) { err_out("Can not drop message %s(errno:%d)\n",strerror(errno),errno); rc=-errno; goto error_out; /* err or end */ } dbg_out("OK Drop:%d\n",drop_len); switch(download_base_cmd(dir_info.ipmsg_fattr)){ case IPMSG_FILE_DIR: rc=update_file_display(dir_info.ipmsg_fattr,dir_info.filename,dir_info.file_size,model,iter); if (rc<0) { release_dir_info_contents(&dir_info); goto error_out; } rc=emulate_chdir(current_dir,dir_info.filename,&new_dir); if (rc<0) { release_dir_info_contents(&dir_info); goto error_out; } g_free(current_dir); current_dir=new_dir; dbg_out("Chdir to:%s\n",current_dir); if (dir_info.file_size > 0) { drop_len=(dir_info.file_size<_MSG_BUF_SIZE)?(dir_info.file_size):(_MSG_BUF_SIZE); drop_len=recv(con->soc,buff,drop_len,0); /* 継続読み捨て */ if (drop_len<0) { err_out("Can not drop message %s(errno:%d)\n",strerror(errno),errno); rc=-errno; release_dir_info_contents(&dir_info); goto error_out; /* err or end */ } } break; case IPMSG_FILE_RETPARENT: dbg_out("Return to parent:cur=%s\n",current_dir); rc=update_file_display(dir_info.ipmsg_fattr,dir_info.filename,dir_info.file_size,model,iter); if (rc<0) { release_dir_info_contents(&dir_info); goto error_out; } create_parent_dir(current_dir,&new_dir); if (rc<0) { release_dir_info_contents(&dir_info); goto error_out; } g_free(current_dir); current_dir=new_dir; dbg_out("Chdir to:%s\n",current_dir); rc=check_end_condition(top_dir,current_dir,&is_cont); if (rc<0){ release_dir_info_contents(&dir_info); goto error_out; } break; case IPMSG_FILE_REGULAR: rc=update_file_display(dir_info.ipmsg_fattr,dir_info.filename,dir_info.file_size,model,iter); if (rc<0) { release_dir_info_contents(&dir_info); goto error_out; } dbg_out("Download : %s/%s but drop at this time\n",current_dir,dir_info.filename); regular_file=g_build_filename(current_dir,dir_info.filename,NULL); if (!regular_file) { release_dir_info_contents(&dir_info); goto error_out; } rc=do_download_regular_file(con,regular_file,dir_info.file_size,&written,model,iter); g_free(regular_file); if ( (rc<0) || (written != dir_info.file_size) ){ release_dir_info_contents(&dir_info); goto error_out; } break; default: break; } }while(is_cont); error_out: if (current_dir) g_free(current_dir); if (buff) g_free(buff); return rc;}intsend_download_request(tcp_con_t *con, unsigned long ftype,long pkt_no,int fileid){ int rc; char *buff=NULL; char *req_message=NULL; ssize_t len; ssize_t soc_remains; ssize_t write_len; int wait_max=TCP_DOWNLOAD_RETRY; struct sigaction saved_act; buff=g_malloc(_MSG_BUF_SIZE); if (!buff) return -ENOMEM; memset(buff,0,_MSG_BUF_SIZE); snprintf(buff,_MSG_BUF_SIZE-1, (ftype == IPMSG_FILE_DIR)?("%lx:%x"):("%lx:%x:0:"), (long)pkt_no,(unsigned int)fileid); buff[_MSG_BUF_SIZE-1]='\0'; dbg_out("request:%s\n",buff); rc=ipmsg_construct_getfile_message(ftype,buff,0,(size_t *)&len,&req_message,ipmsg_get_pkt_no()); if (rc<0) { goto free_buff_out; } dbg_out("request message:%s\n",req_message); wait_max=TCP_DOWNLOAD_RETRY; wrtite_wait_start: ipmsg_update_ui(); rc=wait_socket(con->soc,WAIT_FOR_WRITE,TCP_SELECT_SEC); if (rc<0) { --wait_max; if (wait_max) goto wrtite_wait_start; err_out("Can not write for socket %s (%d)\n",strerror(-rc),-rc); goto error_out; } soc_remains=len; while(soc_remains > 0) { disable_pipe_signal(&saved_act); write_len=send(con->soc, req_message,len, 0); enable_pipe_signal(&saved_act); if (write_len < 0) { err_out("Can not write socket :%s (%d)\n",strerror(errno),errno); rc=-errno; goto error_out; } soc_remains -= write_len; dbg_out("Write remains:%d\n",soc_remains); } rc=0; error_out: g_free(req_message); free_buff_out: if (buff) g_free(buff); return rc;}gboolean is_supported_file_type(unsigned long ipmsg_fattr){ switch(download_base_cmd(ipmsg_fattr)) { case IPMSG_FILE_REGULAR: case IPMSG_FILE_DIR: return TRUE; break; default: break; } return FALSE; }/* recv attachments */voidrecv_attachments(gpointer data) { GtkButton *button; int rc; GtkWidget *window; ipmsg_recvmsg_private_t *sender_info; ipmsg_private_data_t *priv; GtkWidget *dirbtn; GtkWidget *okbtn; GtkWidget *all_check; GtkWidget *dir_entry; GtkWidget *view; GtkTreeSelection *sel; GtkTreeModel *model; GtkTreeIter iter; GList *pathes,*node; gboolean noneed_to_destory; dbg_out("here:\n"); if (!data) return; button=GTK_BUTTON(data); window=lookup_widget(GTK_WIDGET(button),"downloadWindow"); g_assert(window); dirbtn=lookup_widget(GTK_WIDGET(window),"DownLoadOpenBtn"); g_assert(dirbtn); okbtn=lookup_widget(GTK_WIDGET(window),"DownLoadOKBtn"); g_assert(okbtn); all_check=lookup_widget(GTK_WIDGET(window),"DownLoadAllCheckBtn"); g_assert(all_check); dir_entry=lookup_widget(GTK_WIDGET(window),"DownLoadDirectoryEntry"); g_assert(dir_entry); priv=(ipmsg_private_data_t *)lookup_widget(GTK_WIDGET(window),"senderInfo"); g_assert(priv); sender_info=priv->data; g_assert(sender_info->ipaddr); gtk_widget_set_sensitive(dirbtn,FALSE); gtk_widget_set_sensitive(okbtn,FALSE); gtk_widget_set_sensitive(all_check,FALSE); gtk_widget_set_sensitive(dir_entry,FALSE); view=lookup_widget(GTK_WIDGET(window),"DownLoadFileTree"); g_assert(view); /* *Do send */ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); pathes=gtk_tree_selection_get_selected_rows(sel,&model); for(node=g_list_first(pathes);node;node=g_list_next(node)) { g_assert( (node) && (node->data)); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(view), node->data, NULL, FALSE, 0.0, 0.0); gtk_tree_model_get_iter(model,&iter,node->data); rc=do_download(model,node->data,&iter,window); if ( (rc < 0) && (!GTK_IS_WINDOW(window)) ){ /* window destroyed */ g_list_foreach (pathes, (GFunc)gtk_tree_path_free, NULL); g_list_free (pathes); return; } } g_list_foreach (pathes, (GFunc)gtk_tree_path_free, NULL); g_list_free (pathes); /* * remove */ for(sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); gtk_tree_selection_count_selected_rows (sel)>0;){ pathes=gtk_tree_selection_get_selected_rows(sel,&model); node=g_list_first(pathes); g_assert( (node) && (node->data)); gtk_tree_model_get_iter(model,&iter,node->data); gtk_list_store_remove(GTK_LIST_STORE(model), &iter); g_list_foreach (pathes, (GFunc)gtk_tree_path_free, NULL); g_list_free (pathes); } if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(all_check))) download_dir_open_operation(gtk_entry_get_text(GTK_ENTRY(dir_entry))); gtk_widget_set_sensitive(dirbtn,TRUE); gtk_widget_set_sensitive(okbtn,TRUE); gtk_widget_set_sensitive(all_check,TRUE); gtk_widget_set_sensitive(dir_entry,TRUE); noneed_to_destory = gtk_tree_model_get_iter_first (model, &iter); if (noneed_to_destory) dbg_out("some element remains\n"); else gtk_widget_destroy (window);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -