static void destroy_node (FMTreeModel *model, TreeNode *node) { TreeNode *parent; gboolean parent_had_dummy_child; GtkTreePath *path; parent = node->parent; parent_had_dummy_child = tree_node_has_dummy_child (parent); path = get_node_path (model, node); /* Report row_deleted before actually deleting */ gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path); gtk_tree_path_free (path); destroy_node_without_reporting (model, node); if (tree_node_has_dummy_child (parent)) { if (!parent_had_dummy_child) { report_dummy_row_inserted (model, parent); } } else { g_assert (!parent_had_dummy_child); } }
int bproc_nodeinfo(int node, struct bproc_node_info_t *info) { char *path; struct stat buf; get_node_path(path, node); if (stat(path, &buf) != 0) { errno = BE_INVALIDNODE; return -1; } info->node = node; info->mode = buf.st_mode & 0111; /* */ info->user = buf.st_uid; info->group = buf.st_gid; if (getxattr(path, BPROC_STATE_XATTR, info->status, sizeof(info->status)) < 0) { errno = BE_INVALIDNODE; return -1; } if (getxattr(path, BPROC_ADDR_XATTR, &info->addr, sizeof(info->addr)) < 0) { errno = BE_INVALIDNODE; return -1; } return 0; }
/* get target of a symlink. At this time symlinks are not implemented. */ static int callback_readlink(const char *path, char *buf, size_t size) { Node *node; int lng; mylog("::readlink(%s)\n", path); node = get_node_path(path); if (node == NULL) { return(-ENOENT); } stat_stat++; /* not a symlink */ if (node->symlink == NULL) { return(-EINVAL); } /* check length */ lng = strlen(node->symlink); if ((size <= 0)||(lng <= 0)) { return(-EINVAL); } strncpy(buf, node->symlink, MIN(size,lng)); if (MIN(size,lng) == size) { buf[size-1] = '\0'; } else { buf[lng] = '\0'; } return 0; }
static int callback_open(const char *path, struct fuse_file_info *finfo) { Node *node; mylog("::open(%s)\n", path); /* We allow opens, unless they're tring to write, sneaky * people. */ int flags = finfo->flags; if ((flags & O_WRONLY) || (flags & O_RDWR) || (flags & O_CREAT) || (flags & O_EXCL) || (flags & O_TRUNC) || (flags & O_APPEND)) { return(-EROFS); } node = get_node_path(path); if (node == NULL) { return(-ENOENT); } /* create the associated cache */ if ((node->file)&&(!node->special)) { /* only handle cache for files */ /* do not create cache for empty files */ if (node->size > 0) { if (cache_create(path, node->size) == NULL) { /* something goes wrong. Refuse open */ return(-EBUSY); } } } stat_open++; stat_used++; /* ok */ return(0); }
int bproc_chgrp(int node, int group) { char *path; get_node_path(path, node); if (!path) return -1; return chown(path, -1, group); }
int bproc_nodesetstatus(int node, char *status) { char *path; get_node_path(path, node); if (!path) return -1; return setxattr(path, BPROC_STATE_XATTR, status, strlen(status), 0); }
int bproc_chmod(int node, int mode) { char *path; get_node_path(path, node); if (!path) return -1; return chmod(path, mode); }
int bproc_getnodeattr(int node, char *name, void *value, int size) { char *p; char *nametmp; get_node_path(p, node); nametmp = alloca(strlen(name) + 7); sprintf(nametmp, "bproc.%s", name); return getxattr(p, nametmp, value, size); }
int bproc_chown(int node, int user) { char *path; get_node_path(path, node); if (!path) return -1; return chown(path, user, -1); }
int bproc_nodestatus(int num, char *status, int len) { int r; char *path; get_node_path(path, num); r = getxattr(path, BPROC_STATE_XATTR, status, len); if (r != -1 && r < len) /* null terminate if there's room */ status[r] = 0; return r; }
int bproc_nodeaddr(int node, struct sockaddr *s, int *size) { int len; char *p; get_node_path(p, node); len = getxattr(p, BPROC_ADDR_XATTR, s, *size); if (len < 0) return -1; *size = len; return 0; }
NodePath SceneState::get_connection_target(int p_idx) const{ ERR_FAIL_INDEX_V(p_idx,connections.size(),NodePath()); if (connections[p_idx].to&FLAG_ID_IS_PATH) { return node_paths[connections[p_idx].to&FLAG_MASK]; } else { return get_node_path(connections[p_idx].to&FLAG_MASK); } }
NodePath SceneState::get_node_owner_path(int p_idx) const { ERR_FAIL_INDEX_V(p_idx,nodes.size(),NodePath()); if (nodes[p_idx].owner<0 || nodes[p_idx].owner==NO_PARENT_SAVED) return NodePath(); //root likely if (nodes[p_idx].owner&FLAG_ID_IS_PATH) { return node_paths[nodes[p_idx].owner&FLAG_MASK]; } else { return get_node_path(nodes[p_idx].owner&FLAG_MASK); } }
static int callback_access(const char *path, int mode) { Node *node; mylog("::access(%s)\n", path); node = get_node_path(path); if (node == NULL) { return(-ENOENT); } if (mode & W_OK) return(-EROFS); /* in fact we ignore access... */ return(0); }
void fm_tree_model_remove_root_uri (FMTreeModel *model, const char *uri) { TreeNode *node; GtkTreePath *path; FMTreeModelRoot *root; NemoFile *file; file = nemo_file_get_by_uri (uri); for (node = model->details->root_node; node != NULL; node = node->next) { if (file == node->file) { break; } } nemo_file_unref (file); if (node) { /* remove the node */ if (node->mount) { g_object_unref (node->mount); node->mount = NULL; } nemo_file_monitor_remove (node->file, model); path = get_node_path (model, node); /* Report row_deleted before actually deleting */ gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path); gtk_tree_path_free (path); if (node->prev) { node->prev->next = node->next; } if (node->next) { node->next->prev = node->prev; } if (node == model->details->root_node) { model->details->root_node = node->next; } /* destroy the root identifier */ root = node->root; destroy_node_without_reporting (model, node); g_hash_table_destroy (root->file_to_node_map); g_free (root); } }
/* perform a 'stat' on the file */ static int callback_getattr(const char *path, struct stat *st_data) { Node *node; mylog("::getattr(%s)\n", path); node = get_node_path(path); if (node == NULL) { return(-ENOENT); } stat_stat++; mylog(":::find node %p [%s]\n", node, node->name!=NULL?node->name:"<null>"); /* fill the answer */ getattr_from_node(node, st_data); return 0; }
static void reparent_node (FMTreeModel *model, TreeNode *node) { GtkTreePath *path; TreeNode *new_parent; new_parent = get_parent_node_from_file (node->root, node->file); if (new_parent == NULL || new_parent->directory == NULL) { destroy_node (model, node); return; } path = get_node_path (model, node); /* Report row_deleted before actually deleting */ gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path); gtk_tree_path_free (path); abandon_node_ref_count (model, node); tree_node_unparent (model, node); insert_node (model, new_parent, node); }
/* get content of a directory */ static int callback_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { Node *node; int i, cur, ret; struct stat stmp; (void) fi; mylog("::readdir(%s)\n", path); node = get_node_path(path); if (node == NULL) { return(-ENOENT); } /* check offset */ if (offset-2 >= node->nb_entries) { /* request for an offset outbound */ mylog(":::EINVAL: '%s', offset=%d\n", path, (int)offset); return(0); } stat_dir++; /* Note: here I suppose that we *always* able to store '.' & '..' in the buffer. If not, this may failed/crash/whatever */ /* 1st call? */ if (offset == 0) { getattr_from_node(node, &stmp); filler(buf, ".", &stmp, 1); getattr_from_node(node->parent, &stmp); /* any entry? */ if (node->nb_entries == 0) filler(buf, "..", &stmp, 0); /* no -> no 'next' */ else filler(buf, "..", &stmp, 2); /* set next */ cur = 2; /* fill with entries until buffer is full */ for(i=0; i<node->nb_entries; i++) { getattr_from_node(node->entries[i], &stmp); /* for last, prevent offset */ if (i == node->nb_entries-1) ret = filler(buf, node->entries[i]->name, &stmp, 0); else ret = filler(buf, node->entries[i]->name, &stmp, ++cur); /* full? quit the loop */ if (ret == 1) break; } /* done */ return(0); } /* else this is a "continue". Start from given offset */ cur = (int)offset; for(i=cur-2; i<node->nb_entries; i++) { getattr_from_node(node->entries[i], &stmp); /* for last, prevent offset */ if (i == node->nb_entries-1) ret = filler(buf, node->entries[i]->name, &stmp, 0); else ret = filler(buf, node->entries[i]->name, &stmp, ++cur); /* full? quit the loop */ if (ret == 1) break; } /* done */ return(0); }
static int callback_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *finfo) { char buffer[MAX_NAME], *tmp; int lng; int res; Node *node; time_t ttmp; unsigned int totread; unsigned int curoffset; unsigned int cursize; (void)finfo; mylog("::read(%s, %p, %u, %u, -)\n", path, buf, (unsigned int)size, (unsigned int)offset); node = get_node_path(path); if (node == NULL) { return(-ENOENT); } stat_read++; /* special treatment for "special" files */ if (node->special) { mylog(":::this node is special! (type=%d)\n", node->special); /* only this one supported at this time */ if (node->special == 1) { /* if offset > 0, do nothing: this is a one-shor read */ if (offset > 0) return(0); /* return current time */ ttmp = time(NULL); tmp = ctime(&ttmp); if (tmp == NULL) { return(-EBUSY); } buffer[0] = '\0'; strcat(buffer, tmp); lng = strlen(buffer); strncpy(buf, buffer, MIN(size,lng)); return(MIN(size,lng)); } else if (node->special == 2) { /* internal status */ /* if offset > 0, do nothing: this is a one-shot read */ if (offset > 0) return(0); if (update_ok == UP_OK) { sprintf(buffer, "Update ok (last update at %u)\n" "%d entries in FS tree.\n", last_dl, update_nbent); } else { sprintf(buffer, "Error: %s\n", update_str[update_ok]); } lng = strlen(buffer); strncpy(buf, buffer, MIN(size,lng)); return(MIN(size,lng)); } else if (node->special == 3) { /* internal info */ /* if offset > 0, do nothing: this is a one-shot read */ if (offset > 0) return(0); sprintf(buffer, "Base URL: %s\nMetadata: %s\n" "Update interval: %u\n" "# chunks / size: %u / %u\n", url_path, metaurl, intv_dl, cache_chunks, cache_chunksize); lng = strlen(buffer); strncpy(buf, buffer, MIN(size,lng)); return(MIN(size,lng)); } else if (node->special == 4) { /* webfs data */ /* if offset > 0, do nothing: this is a one-shot read */ if (offset > 0) return(0); sprintf(buffer, "%s V%s\n%s", webfsName, webfsVersion, webfsDescription); lng = strlen(buffer); strncpy(buf, buffer, MIN(size,lng)); return(MIN(size,lng)); } else if (node->special == 5) { /* stats data */ /* if offset > 0, do nothing: this is a one-shot read */ if (offset > 0) return(0); sprintf(buffer, "Access statistics:\n" "Current opened files: %d\n" "Total number of [fl]stat, access...: %llu\n" "Total number of dir access: %llu\n" "Total number of open: %llu\n" "Total number of read: %llu\n" "Total number of bytes read: %llu\n", stat_used, stat_stat, stat_dir, stat_open, stat_read, stat_data); lng = strlen(buffer); strncpy(buf, buffer, MIN(size,lng)); return(MIN(size,lng)); } else { return(-EOPNOTSUPP); } } /* for empty files, just do nothing */ if (node->size == 0) { return(0); } /* loop on read until we reach the requested size */ totread = 0; curoffset = offset; cursize = size; while(1) { /* call the cache system to get data from file */ res = cache_read(node->size, path, curoffset, cursize, buf+totread); /* just give the result */ mylog("::read(%s, %u, %u, %p) = %d\n", path, curoffset, cursize, buf+totread, res); if (res == 0) { /* let stop, no more to read */ break; } totread += res; /* same size? stop */ if (totread >= size) break; /* need to loop again. compute new offset/size */ curoffset += res; cursize -= res; } if (totread >= 0) stat_data += totread; return(totread); }
inline std::basic_string<typename ID::char_type> get_node_path_string(node<ID>* p, bool add_leading_dot=true) { return make_path_string(get_node_path(p,false),add_leading_dot); }
int bproc_access(int node, int mode) { char *path; get_node_path(path, node); return access(path, mode); }
void get_dnode_of_data(struct f2fs_sb_info *sbi, struct dnode_of_data *dn, pgoff_t index, int mode) { int offset[4]; unsigned int noffset[4]; struct f2fs_node *parent = NULL; nid_t nids[4]; block_t nblk[4]; struct node_info ni; int level, i; int ret; level = get_node_path(index, offset, noffset); nids[0] = dn->nid; parent = dn->inode_blk; if (level != 0) nids[1] = get_nid(parent, offset[0], 1); else dn->node_blk = dn->inode_blk; get_node_info(sbi, nids[0], &ni); nblk[0] = ni.blk_addr; for (i = 1; i <= level; i++) { if (!nids[i] && mode == ALLOC_NODE) { f2fs_alloc_nid(sbi, &nids[i], 0); dn->nid = nids[i]; /* Function new_node_blk get a new f2fs_node blk and update*/ /* We should make sure that dn->node_blk == NULL*/ nblk[i] = new_node_block(sbi, dn, noffset[i]); ASSERT(nblk[i]); set_nid(parent, offset[i - 1], nids[i], i == 1); } else { /* If Sparse file no read API, */ struct node_info ni; get_node_info(sbi, nids[i], &ni); dn->node_blk = calloc(BLOCK_SZ, 1); ASSERT(dn->node_blk); ret = dev_read_block(dn->node_blk, ni.blk_addr); ASSERT(ret >= 0); nblk[i] = ni.blk_addr; } if (mode == ALLOC_NODE){ /* Parent node may have changed */ ret = dev_write_block(parent, nblk[i - 1]); ASSERT(ret >= 0); } if (i != 1) free(parent); if (i < level) { parent = dn->node_blk; nids[i + 1] = get_nid(parent, offset[i], 0); } } dn->nid = nids[level]; dn->ofs_in_node = offset[level]; dn->data_blkaddr = datablock_addr(dn->node_blk, dn->ofs_in_node); dn->node_blkaddr = nblk[level]; }