📄 fileattach.c
字号:
show_upload_queue(); return 0;}intremove_link_from_upload_queue(long pktno,GList **r_node) { GList *node; attach_file_block_t chk_blk; int rc; if (!r_node) return -EINVAL; chk_blk.pkt_no=pktno; g_static_mutex_lock(&upload_queue_mutex); rc=-ENOENT; node=g_list_find_custom(uploads,&chk_blk,find_attach_file_block); if (!node) goto unlock_out; uploads=g_list_remove_link(uploads,node); *r_node=node; unlock_out: g_static_mutex_unlock(&upload_queue_mutex); show_upload_queue(); return rc;}static gintfind_attach_file_info(gconstpointer a,gconstpointer b){ file_info_t *info_a,*info_b; if ( (!a) || (!b) ) return -EINVAL; info_a=(file_info_t *)a; info_b=(file_info_t *)b; return (!(info_a->fileid == info_b->fileid));}int release_attach_file_block(const long pktno,gboolean force){ GList *node; attach_file_block_t chk_blk; attach_file_block_t *afcb; int rc=-ENOENT; chk_blk.pkt_no=pktno; g_static_mutex_lock(&upload_queue_mutex); rc=-ENOENT; node=g_list_find_custom(uploads,&chk_blk,find_attach_file_block); if (!node) goto unlock_out; afcb=(attach_file_block_t *)node->data; g_assert(afcb); g_mutex_lock(afcb->mutex); if (afcb->count>0) --afcb->count; /* 1度も送信されていなければ, 0になりうるため判定後にデクリメント */ if (force) /* 強制開放 */ afcb->count=0; if (afcb->count>0) { dbg_out("Attach file still alive:count=%d\n",afcb->count); g_mutex_unlock(afcb->mutex); goto unlock_out; } g_mutex_unlock(afcb->mutex); uploads=g_list_remove_link(uploads,node); g_list_free_1(node); rc=destroy_attach_file_block(&afcb); unlock_out: g_static_mutex_unlock(&upload_queue_mutex); return rc;}/* *download_monitor_release_attach_file経由以外で呼び出してはならない. */intrelease_attach_file(const long pktno,int fileid){ GList *node; GList *fnode,*flist; attach_file_block_t chk_blk; attach_file_block_t *afcb; file_info_t chk_info; file_info_t *finfo; int rc=-ENOENT; int remains=-ENOENT; chk_blk.pkt_no=pktno; g_static_mutex_lock(&upload_queue_mutex); rc=-ENOENT; node=g_list_find_custom(uploads,&chk_blk,find_attach_file_block); if (!node) goto unlock_out; afcb=node->data; g_assert(afcb); g_mutex_lock(afcb->mutex); flist=afcb->files; chk_info.fileid=fileid; fnode=g_list_find_custom(flist,&chk_info,find_attach_file_info); if (!fnode) goto afcb_unlock_out; finfo=fnode->data; g_mutex_lock(finfo->mutex); g_assert(finfo); g_assert(finfo->filepath); dbg_out("fileinfo found: path=%s size=%d(%x)\n", finfo->filepath, finfo->size, finfo->size); afcb->files=g_list_remove(afcb->files,finfo); g_mutex_unlock(finfo->mutex); destroy_file_info(finfo); remains=g_list_length(afcb->files); rc=0; afcb_unlock_out: g_mutex_unlock(afcb->mutex); unlock_out: g_static_mutex_unlock(&upload_queue_mutex); if (remains==0) rc=release_attach_file_block(pktno,FALSE); show_upload_queue(); return rc;}int refer_attach_file(const long pktno,int fileid,unsigned long *ipmsg_fattr,const char **path,size_t *size){ GList *node; GList *fnode,*flist; attach_file_block_t chk_blk; attach_file_block_t *afcb; file_info_t chk_info; file_info_t *finfo; char *fpath; int rc=-ENOENT; if ( (!path) || (!size) ) return -EINVAL; chk_blk.pkt_no=pktno; g_static_mutex_lock(&upload_queue_mutex); rc=-ENOENT; node=g_list_find_custom(uploads,&chk_blk,find_attach_file_block); if (!node) goto unlock_out; afcb=node->data; g_assert(afcb); g_mutex_lock(afcb->mutex); flist=afcb->files; chk_info.fileid=fileid; fnode=g_list_find_custom(flist,&chk_info,find_attach_file_info); if (!fnode) goto afcb_unlock_out; finfo=fnode->data; g_mutex_lock(finfo->mutex); g_assert(finfo); g_assert(finfo->filepath); dbg_out("fileinfo found: pktno=%d id:%d type=%d (%s) path=%s size=%d(%x)\n", pktno, fileid, finfo->ipmsg_fattr, get_file_type_name(finfo->ipmsg_fattr), finfo->filepath, finfo->size, finfo->size); *ipmsg_fattr=finfo->ipmsg_fattr; fpath=strdup(finfo->filepath); rc=-ENOMEM; if (!fpath) goto finfo_unlock_out; *path=fpath; *size=finfo->size; rc=0; finfo_unlock_out: g_mutex_unlock(finfo->mutex); afcb_unlock_out: g_mutex_unlock(afcb->mutex); unlock_out: g_static_mutex_unlock(&upload_queue_mutex); show_upload_queue(); return rc;}static intdestroy_download_file_info(download_file_block_t **ret_info) { download_file_block_t *remove_info; if ( (!ret_info) || (!(*ret_info) ) ) return -EINVAL; remove_info=*ret_info; if (remove_info->filename) { free(remove_info->filename); remove_info->filename=NULL; } dbg_out("Free: %x\n",(unsigned int)remove_info); g_slice_free(download_file_block_t,remove_info); return 0;}static intinit_download_file_info(download_file_block_t **ret_info) { download_file_block_t *new_info; int rc; if (!ret_info) return -EINVAL; rc=-ENOMEM; new_info=g_slice_new(download_file_block_t); if (!new_info) return rc; memset(new_info,0,sizeof(download_file_block_t)); *ret_info=new_info; return 0; free_out: dbg_out("Free: %x\n",(unsigned int)new_info); g_slice_free(download_file_block_t,new_info); return rc;}static int get_one_download_file_info(const gchar *string,download_file_block_t **new_info_ref){ int rc; char *buffer; char *sp=NULL; char *ep=NULL; long int_val; download_file_block_t * new_info; size_t len; size_t remains; if ( (!string) || (!new_info_ref) ) return -EINVAL; rc=init_download_file_info(&new_info); if (rc<0) return rc; rc=-ENOMEM; buffer=strdup(string); if (!buffer) goto free_slice_out; len=strlen(string); remains=len; rc=-ENOENT; sp=buffer; /* * file id */ ep=memchr(sp,':',remains); rc=-EINVAL; if (!ep) goto free_out; *ep='\0'; errno=0; int_val=strtol(sp, (char **)NULL, 10); g_assert(!errno); new_info->fileid=int_val; dbg_out("file id:%d(%x)\n",new_info->fileid,new_info->fileid); sp=++ep; remains =len - ((unsigned long)ep-(unsigned long)buffer); /* * file name */ ep=memchr(sp,':',remains); rc=-EINVAL; if (!ep) goto free_out; *ep='\0'; new_info->filename=strdup(sp); rc=-ENOMEM; if (!(new_info->filename)) goto free_out; dbg_out("file name:%s\n",new_info->filename); sp=++ep; /* * size */ ep=memchr(sp,':',remains); rc=-EINVAL; if (!ep) goto free_out; *ep='\0'; errno=0; int_val=strtol(sp, (char **)NULL, 16); g_assert(!errno); new_info->size=int_val; dbg_out("size:%d(%x)\n",new_info->size,new_info->size); sp=++ep; remains =len - ((unsigned long)ep-(unsigned long)buffer); /* * m_time */ ep=memchr(sp,':',remains); rc=-EINVAL; if (!ep) goto free_out; *ep='\0'; errno=0; int_val=strtol(sp, (char **)NULL, 16); g_assert(!errno); new_info->m_time=int_val; dbg_out("mtime:%s(%x)\n", ctime(&(new_info->m_time)), (unsigned int)new_info->m_time); sp=++ep; remains =len - ((unsigned long)ep-(unsigned long)buffer); /* * type */ ep=memchr(sp,':',remains); rc=-EINVAL; if (ep) /* 拡張属性がある場合を考慮してこの判定は他とは逆になる */ *ep='\0'; errno=0; int_val=strtol(sp, (char **)NULL, 16); g_assert(!errno); new_info->ipmsg_fattr=int_val; dbg_out("type:%x\n",new_info->ipmsg_fattr); /* 拡張属性は無視する(FSによって使用できないことがあるので) */ *new_info_ref=new_info; free(buffer); return 0; free_out: free(buffer); free_slice_out: dbg_out("Free: %x\n",(unsigned int)new_info); g_slice_free(download_file_block_t,new_info); return rc;}static int show_download_list(const GList *download_list) { GList *node; download_file_block_t *info; if (!download_list) return -EINVAL; for(node=g_list_first ((GList *)download_list);node;node=g_list_next(node)) { info=(download_file_block_t *)(node->data); dbg_out("file-id:%x filename:%s size:%d date:%s\n", info->fileid, info->filename, info->size, ctime(&(info->m_time))); } return 0;}int destroy_download_list(const GList **download_list) { GList *node; download_file_block_t *info; GList *remove_list; if ( (!download_list) || (!(*download_list)) ) return -EINVAL; remove_list=(GList *)(*download_list); for(node=g_list_first (remove_list);node;node=g_list_next(node)) { info=(download_file_block_t *)(node->data); dbg_out("remove file-id:%x filename:%s size:%d date:%s\n", info->fileid, info->filename, info->size, ctime(&(info->m_time))); dbg_out("Free: %x\n",(unsigned int)info); g_slice_free(download_file_block_t,info); } g_list_free(remove_list); *download_list=NULL; return 0;}intparse_download_string(const char *string, GList **list){ char *sp=NULL; char *ep=NULL; char *buffer; ssize_t len; download_file_block_t *new_info; GList *new_list=NULL; if ( (!string) || (!list) ) return -EINVAL; dbg_out("attachment string:%s\n",string); buffer=strdup(string); if (!buffer) return -EINVAL; sp=buffer; for(len=strlen(sp),ep=memchr(sp,FILELIST_SEPARATOR,len);; ) { dbg_out("new string:%s\n",sp); len=strlen(sp),ep=memchr(sp,FILELIST_SEPARATOR,len); if (ep) { *ep='\0'; if (!get_one_download_file_info(sp,&new_info)) new_list=g_list_append(new_list,new_info); sp=++ep; }else{ if (!get_one_download_file_info(sp,&new_info)) new_list=g_list_append(new_list,new_info); break; } } show_download_list(new_list); *list=new_list; free(buffer); return 0;}static intget_filename_list(attach_file_block_t *afcb, gchar **string){ size_t len; GList *node; file_info_t *info; gchar *fnames; if ( (!afcb) || (!string) ) return -EINVAL; len=0; for(node=g_list_first (afcb->files);node;node=g_list_next(node)) { info=(file_info_t *)(node->data); g_assert(info); g_mutex_lock(info->mutex); if (info->filename) len+=(strlen(info->filename)+2); /* null終端と空白があるので+2 */ g_mutex_unlock(info->mutex); } fnames=malloc(len); if (!fnames) return -ENOMEM; memset(fnames,0,len); for(node=g_list_first (afcb->files);node;node=g_list_next(node)) { info=(file_info_t *)(node->data); g_assert(info); g_mutex_lock(info->mutex); if (info->filename) { strcat(fnames,info->filename); strcat(fnames," "); } g_mutex_unlock(info->mutex); } fnames[len-1]='\0'; *string=fnames; return 0;}static intafcb_get_username(attach_file_block_t *afcb, gchar **string){ int rc=0; gchar *username; userdb_t *entry=NULL; char buff[256]; if ( (!afcb) || (!string) ) return -EINVAL; dbg_out("retrive:%s\n",afcb->ipaddr); userdb_search_user_by_addr(afcb->ipaddr,(const userdb_t **)&entry); if (entry) { dbg_out("get:%s %s\n" ,entry->nickname ,entry->ipaddr); memset(buff,0,256); snprintf(buff,255,"%s@%s(%s)", entry->nickname, entry->group, entry->ipaddr); buff[255]='\0'; destroy_user_info(entry); username=strdup(buff); if (username) *string=username; else rc=-ENOMEM; } return rc;}void update_download_view(GtkWidget *window) { attach_file_block_t *afcb; GList *node; GtkWidget *view; GtkTreeModel *model; GtkTreeIter iter; attach_file_block_t *blk; dbg_out("here\n"); g_static_mutex_lock(&upload_queue_mutex); g_assert(window); view=lookup_widget(GTK_WIDGET(window),"treeview5"); g_assert(view); model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); if (gtk_tree_model_get_iter_first(model,&iter)) { gtk_list_store_clear(GTK_LIST_STORE(model)); } model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); gtk_tree_model_get_iter_first(model,&iter); for(node=g_list_first (uploads);node;node=g_list_next(node)) { blk=node->data; if (blk){ char *files=NULL; char *name=NULL; int count=0; g_mutex_lock(blk->mutex); if (get_filename_list(blk, &files)) goto unlock_blk; if (afcb_get_username(blk, &name)) goto free_files; count=g_list_length(blk->files); gtk_list_store_append(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, DOWNLOAD_VIEW_FNAME,files, DOWNLOAD_VIEW_REMAIN,count, DOWNLOAD_VIEW_USER,name, DOWNLOAD_VIEW_PKTNO,blk->pkt_no, -1); if (name) free(name); free_files: if (files) free(files); unlock_blk: g_mutex_unlock(blk->mutex); } } g_static_mutex_unlock(&upload_queue_mutex);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -