⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloads.c

📁 linux下的飞鸽传书 日本人设计 使用非常方便
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <gnome.h>#include <glib.h>#include <gconf/gconf-client.h>#include "callbacks.h"#include "interface.h"#include "support.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/time.h>#include <errno.h>#include <libgnomevfs/gnome-vfs.h>#include <libgnomevfs/gnome-vfs-utils.h>#include <libgnomevfs/gnome-vfs-mime-handlers.h>#include "common.h"/* static */static intrelease_dir_info_contents(dir_request_t *info){  if (info->filename)    g_free(info->filename);  return 0;}static intparse_dir_request(const char *message,dir_request_t *ret,size_t max_len){  int rc;  char *buff;  char *token;  long int_val;  char *sp=NULL;  char *ep=NULL;  char *basename;  char *filename;  ssize_t remains;  if ( (!message) || (!ret) || (!max_len) )    return -EINVAL;    buff=malloc(max_len+1); /* 最終パケットは\0終端されていないことに注意 */  if (!buff)    return -ENOMEM;  memset(ret,0,sizeof(dir_request_t)); /*  念のため */  memcpy(buff,message,max_len);  buff[max_len]='\0';  dbg_out("buff(len:%d):%s\n",strlen(buff),buff);  remains=max_len;  /*書式: header-size:filename:file-size:fileattr:*/    /*   * ヘッダサイズ   */  sp=buff;  ep=memchr(sp, ':', remains);  if (!ep) {    rc=-EINVAL;    goto error_out;  }  *ep='\0';  remains =max_len - ((unsigned long)ep-(unsigned long)buff);  if (remains<=0) {    rc=-EINVAL;    goto error_out;  }  ++ep;  int_val=strtol(sp, (char **)NULL, 16);  ret->header_size=int_val;  dbg_out("header size:%d(%x)\n",ret->header_size,ret->header_size);  sp=ep;  /*   * ファイル名   */  ep=memchr(sp, ':', remains);  if (!ep) {    rc=-EINVAL;    goto error_out;  }  *ep='\0';  remains =max_len - ((unsigned long)ep-(unsigned long)buff);  if (remains<=0) {    rc=-EINVAL;    goto error_out;  }  ++ep;  rc=-ENOMEM;  basename=g_path_get_basename(sp);  if  (!basename)    goto error_out;  rc=convert_string_internal(basename,(const gchar **)&filename);  if (rc<0) {    err_out("Can not convert this request:%s\n",sp);    err_out("Can not convert file name:%s\n",basename);    g_free(basename);    goto error_out;  }    g_free(basename);  ret->filename=filename;  dbg_out("filename:%s\n",ret->filename);  sp=ep;  /*   * ファイルサイズ   */  ep=memchr(sp, ':', remains);  if (!ep) {    rc=-EINVAL;    goto error_out;  }  *ep='\0';  remains =max_len - ((unsigned long)ep-(unsigned long)buff);  if (remains<=0) {    rc=-EINVAL;    goto error_out;  }  ++ep;  int_val=strtol(sp, (char **)NULL, 16);  ret->file_size=int_val;  dbg_out("file size:%d(%x)\n",ret->file_size,ret->file_size);  sp=ep;  /*   * ファイル種別   */  ep=memchr(sp, ':', remains);  if (!ep) {    rc=-EINVAL;    goto error_out;  }  *ep='\0';  remains =max_len - ((unsigned long)ep-(unsigned long)buff);  if (remains<=0) {    rc=-EINVAL;    goto error_out;  }  ++ep;  int_val=strtol(sp, (char **)NULL, 16);  ret->ipmsg_fattr=int_val;  dbg_out("ipmsg file attr:%d(%x)\n",ret->ipmsg_fattr,ret->ipmsg_fattr);  sp=ep;  if (download_base_cmd(ret->ipmsg_fattr) != IPMSG_FILE_RETPARENT) {    rc=-EPERM;    if (!strcmp(G_DIR_SEPARATOR_S,basename)) {      g_free(basename);      goto error_out;    }    if (!strcmp(basename,"..")){      g_free(basename); /* 上位への移動は禁止 */      goto error_out;    }    if (!strcmp(basename,".")){      g_free(basename); /* コマンド以外でのカレントへの移動は禁止 */      goto error_out;    }  }  rc=0; error_out:  free(buff);  return rc;}static intemulate_chdir(const char *current_dir,char *subdir,char **new_dir){  int rc;  char *buff;  gchar *dir_uri;  GnomeVFSResult result;  if ( (!current_dir) || (!subdir) || (!new_dir) )     return -EINVAL;  if (!strcmp(subdir,".."))    return -EINVAL; /* コマンド以外で上位には移動しない  */  if (!strcmp(subdir,"."))    return -EINVAL; /* コマンド以外でカレントには移動しない  */  if (!g_path_is_absolute(current_dir))    return -EINVAL;  buff=g_build_filename(current_dir,subdir,NULL);  if (!buff)    return -ENOMEM;  rc=-ENOMEM;  dir_uri=gnome_vfs_get_uri_from_local_path(buff);  if (!dir_uri)     goto error_out;  result=gnome_vfs_make_directory(dir_uri,GNOME_VFS_PERM_USER_ALL);  if ( (result != GNOME_VFS_OK) && (result != GNOME_VFS_ERROR_FILE_EXISTS) ) {    err_out("Can not create directory:%s\n",gnome_vfs_result_to_string(result));    rc=-result;    goto error_out;  }  if ( (result == GNOME_VFS_ERROR_FILE_EXISTS) &&       (download_overwrite_confirm_generic(buff)) ) {    rc=-result;    goto error_out;  }  *new_dir=buff;  return 0; error_out:  free(buff);  return rc;}static intcreate_parent_dir(const char *current_dir,char **parent){  int rc;  char *buff;  char *new_dir;  gchar *ep;  if ( (!current_dir) || (!parent) )    return -EINVAL;  buff=strdup(current_dir);  if (!buff)    return -ENOMEM;  rc=-ENOENT;  ep=g_strrstr(buff,G_DIR_SEPARATOR_S);  if ( (!ep) || (buff == ep) )    goto error_out;  *ep='\0';  rc=-ENOMEM;  new_dir=strdup(buff);  if (!new_dir)    goto error_out;  *parent=new_dir;  rc=0; error_out:  free(buff);  return rc;}static intcheck_end_condition(const char *top_dir,const char *current_dir,gboolean *is_cont){  size_t top_len;  size_t dir_len;    if ( (!top_dir) || (!current_dir) || (!is_cont) )    return -EINVAL;  *is_cont=TRUE;  top_len=strlen(top_dir);  dir_len=strlen(current_dir);  if (top_len >= dir_len)    *is_cont=FALSE;  return 0;}static intupdate_file_display(unsigned long filetype,const char *filename,size_t size,GtkTreeModel *model,GtkTreeIter *iter){  if ( (!filename) || (!model) || (!iter) )    return -EINVAL;  if (!GTK_IS_LIST_STORE (model)) {      war_out("Download window is destroyed.\n");      return -EFAULT; /*  仮にEFAULTを返す  */  }  gtk_list_store_set(GTK_LIST_STORE(model), iter, 		     1, filename, 		     2, 0,		     3, size,		     4, 0,		     5, filetype,		     6, get_file_type_name(filetype),		     -1);  ipmsg_update_ui();  return 0;}intdo_download(GtkTreeModel *model,	       GtkTreePath *path,	       GtkTreeIter *iter,	       gpointer data){  int rc;  tcp_con_t con;  GtkWidget *window;  GtkWidget *entry;  GtkWidget *all_check;  ipmsg_recvmsg_private_t *sender_info;  ipmsg_private_data_t *priv;  long pkt_no;  int fileid;  size_t total_write;  size_t may_read;  char filepath[PATH_MAX];  char *filename;  char *dirname;  char *req_message=NULL;  int is_retry;  int ftype;  gboolean is_interactive;  char *basename;    window=GTK_WIDGET(data);  if (!GTK_IS_WINDOW(window))    return -EFAULT;   entry=lookup_widget(GTK_WIDGET(window),"DownLoadDirectoryEntry");  if (!GTK_IS_ENTRY(entry))    return -EFAULT;   all_check=lookup_widget(GTK_WIDGET(window),"DownLoadAllCheckBtn");  if (!GTK_IS_CHECK_BUTTON(all_check))    return -EFAULT;   priv=(ipmsg_private_data_t *)lookup_widget(GTK_WIDGET(window),"senderInfo");  g_assert(priv);  sender_info=priv->data;   g_assert(sender_info->ipaddr);  pkt_no=sender_info->pktno;  gtk_tree_model_get (model, iter, 		      0, &fileid,		      1, &filename,		      3, &may_read,		      5, &ftype,		      -1);  basename=g_path_get_basename(filename);  g_free(filename);  if (!basename) {    return -ENOMEM;  }  dirname=(char *)gtk_entry_get_text(GTK_ENTRY(entry));  snprintf(filepath,PATH_MAX-1,"%s/%s",dirname,basename);  filepath[PATH_MAX-1]='\0';  g_free(basename);  dbg_out("download %d th element of %ld from %s into %s\n",fileid,pkt_no,sender_info->ipaddr,filepath); retry_this_file:  memset(&con,0,sizeof(tcp_con_t));  rc=tcp_setup_client(hostinfo_get_ipmsg_system_addr_family(),sender_info->ipaddr,hostinfo_refer_ipmsg_port(),&con);  if (rc<0) {    rc=-errno;    goto error_out;  }  /*    * ロックアップ対策のためのタイムアウト設定   */  rc=sock_recv_time_out(con.soc,TCP_CLIENT_TMOUT_MS);   if (rc<0) {    rc=-errno;    goto error_out;  }  /*  リクエスト送信  */  send_download_request(&con, ftype,pkt_no,fileid);  is_interactive=    ((gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(all_check)))?     (FALSE):(TRUE) );  switch(download_base_cmd(ftype)) {  case IPMSG_FILE_DIR:       /*  階層ディレクトリ受信  */      ipmsg_update_ui();      dbg_out("This is directory ignored.\n");      rc=do_download_directory(&con, dirname,model,iter);      if ( (!rc) && (is_interactive) )	rc=download_dir_open_operation(dirname);      break;  case IPMSG_FILE_REGULAR:   /*  通常ファイル受信  */    rc=do_download_regular_file(&con,filepath,may_read,&total_write,model,iter);    dbg_out("Retry:rc=%d file:%s write:%d expected read :%d dir:%s\n",	    rc,filepath,total_write,may_read,dirname);    is_retry=post_download_operation(rc,				   filepath,				   total_write,				   may_read,				   dirname,				   is_interactive);		       if ( (rc) && (is_retry == -EAGAIN) ) {      /* 0リセット */      gtk_list_store_set(GTK_LIST_STORE(model), iter, 			 2, 0,			 -1);      ipmsg_update_ui();      close(con.soc);      goto retry_this_file;    }    break;  default:    err_out("Unknown file type:%d\n",ftype);    break;  }  close(con.soc); /* 端点のクローズは, 受信側で行うのがipmsgの仕様  */ error_out:  return rc;}static voidprogress_cell_data_func(GtkTreeViewColumn *col,                    GtkCellRenderer   *renderer,                    GtkTreeModel      *model,                    GtkTreeIter       *iter,                    gpointer           user_data){  GtkTreeView *view;  GtkEntry *entry;  GtkWidget *window;  int   fd;  gint  sent;  gint  size;  int   fattr_num;  gint  persent;  gchar size_string[32];  gchar path_string[PATH_MAX];  gchar *filename;  gboolean is_exist=FALSE;  g_assert(user_data);  view=(GtkTreeView *)user_data;  window=lookup_widget(GTK_WIDGET(view),"downloadWindow");  g_assert(window);  entry=GTK_ENTRY(lookup_widget(GTK_WIDGET(view),"DownLoadDirectoryEntry"));  g_assert(entry);  gtk_tree_model_get(model, iter, 		     DOWNLOAD_FILENAME_NUM, &filename,		     DOWNLOAD_RECVSIZE_NUM, &sent,		     DOWNLOAD_FILESIZE_NUM, &size,		     DOWNLOAD_FILEATTR_NUM, &fattr_num,		     -1);  snprintf(path_string,PATH_MAX-1,"%s/%s",gtk_entry_get_text(GTK_ENTRY(entry)),filename);  path_string[PATH_MAX-1]='\0';  dbg_out("Check path:%s\n",path_string);/*   if ( (fattr_num != IPMSG_FILE_REGULAR) && (!size) ) *//*     return; */  switch(fattr_num) {  default:  case IPMSG_FILE_REGULAR:    break;  case IPMSG_FILE_DIR:    /* ディレクトリのダウンロードが完了したら     * 親ディレクトリへの復帰になるはずなので     * 0として扱う.     */       persent=0;    goto output_out;    break;  case IPMSG_FILE_RETPARENT:    /* ディレクトリの完了通知なので, 100%とみなす.     * 厳密にいえば手抜きだが,      * 中途のディレクトリも同様にあつかう         */       persent=100;    goto output_out;        break;  }  if (size>0)    persent=(gint)((sent/(double)size)*100);  else { /* 0バイトファイル対策  */    persent=0;    fd=open(path_string,O_RDONLY);    if (fd>0) {      is_exist=TRUE;      close(fd);      persent=100;    }  }  //  dbg_out("transfer: %d/%d(%3d)\n",sent,size,persent);  g_free(filename); output_out:  if (persent<0)    persent=0;  if (persent>100)    persent=100;  snprintf(size_string,31,"%d %%",persent);  size_string[31]='\0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -