コード例 #1
0
ファイル: filtering.c プロジェクト: vifm/vifm
/* Use parent_entry to make filtered list not empty, or create such entry (if
 * parent_entry is NULL) and put it to original list. */
static void
ensure_filtered_list_not_empty(view_t *view, dir_entry_t *parent_entry)
{
	if(view->list_rows != 0U)
	{
		return;
	}

	if(parent_entry == NULL)
	{
		add_parent_dir(view);
		if(view->list_rows > 0)
		{
			(void)add_dir_entry(&view->local_filter.unfiltered,
					&view->local_filter.unfiltered_count,
					&view->dir_entry[view->list_rows - 1]);
		}
	}
	else
	{
		size_t list_size = 0U;
		(void)add_dir_entry(&view->dir_entry, &list_size, parent_entry);
		view->list_rows = list_size;
	}
}
コード例 #2
0
static struct dir_info *dir_new(struct dir_info *parent, const char *name)
{
	struct dir_info *dir;
	size_t sz;
	char *path;

	path = dir_path(parent, name);
	if (mkdir(path, 0777) == -1) {
		CHECK(errno == ENOSPC);
		full = 1;
		free(path);
		return NULL;
	}
	free(path);

	sz = sizeof(struct dir_info);
	dir = (struct dir_info *) malloc(sz);
	CHECK(dir != NULL);
	memset(dir, 0, sz);
	dir->name = copy_string(name);
	dir->parent = parent;
	if (parent)
		add_dir_entry(parent, 'd', name, dir);
	return dir;
}
コード例 #3
0
static struct file_info *file_new(struct dir_info *parent, const char *name)
{
	struct file_info *file = NULL;
	char *path;
	mode_t mode;
	int fd;
	size_t sz;

	CHECK(parent != NULL);

	path = dir_path(parent, name);
	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
	fd = open(path, O_CREAT | O_EXCL | O_RDWR, mode);
	if (fd == -1) {
		CHECK(errno == ENOSPC);
		free(path);
		full = 1;
		return NULL;
	}
	free(path);

	sz = sizeof(struct file_info);
	file = (struct file_info *) malloc(sz);
	CHECK(file != NULL);
	memset(file, 0, sz);
	file->name = copy_string(name);

	add_dir_entry(parent, 'f', name, file);

	add_fd(file, fd);

	return file;
}
コード例 #4
0
static void link_new(struct dir_info *parent, const char *name,
		     struct file_info *file)
{
	struct dir_entry_info *entry;
	char *path, *target;
	int ret;

	if (!file)
		return;
	entry = file->links;
	if (!entry)
		return;
	path = dir_path(parent, name);
	target = dir_path(entry->parent, entry->name);
	ret = link(target, path);
	if (ret == -1) {
		CHECK(errno == ENOSPC);
		free(target);
		free(path);
		full = 1;
		return;
	}
	free(target);
	free(path);

	add_dir_entry(parent, 'f', name, file);
}
コード例 #5
0
ファイル: plog.c プロジェクト: AmesianX/panda
// compress current chunk and write it to file,
// also update directory map
void write_current_chunk(void) {
    // uncompressed chunk size
    unsigned long cs = thePandalog->chunk.buf_p - thePandalog->chunk.buf;
    unsigned long ccs = thePandalog->chunk.zsize;
    int ret;
    // loop allows compress2 to fail and resize output buffer as needed
    // not sure why compress2 needs output buf to be bigger than input
    // even though ultimately it is smaller.  scratch space?
    // 10 is just a random guess.  shouldn't need more than 1 re-try
    uint32_t i;
    for (i=0; i<10; i++) {
        ret = compress2(thePandalog->chunk.zbuf, &ccs, thePandalog->chunk.buf, cs, Z_BEST_COMPRESSION);
        if (ret == Z_OK) break;
        // bigger output buffer needed to perform compression?
        thePandalog->chunk.zsize *= 2;
        thePandalog->chunk.zbuf = (unsigned char *) realloc(thePandalog->chunk.zbuf, thePandalog->chunk.zsize);
        assert (thePandalog->chunk.zbuf != NULL);
    }
    // ccs is final compressed chunk size
    assert (ret == Z_OK);
    assert(ccs > 0);
    assert(cs >= ccs);
    printf ("writing chunk %d of pandalog %d / %d = %.2f compression\n",
            (int) thePandalog->chunk_num, (int) cs, (int) ccs, ((float) cs) / ((float) ccs));
    fwrite(thePandalog->chunk.zbuf, 1, ccs, thePandalog->file);
    add_dir_entry(thePandalog->chunk_num);
    // reset start instr / pos
    thePandalog->chunk.start_instr = rr_get_guest_instr_count();
    thePandalog->chunk.start_pos = ftell(thePandalog->file);
    // rewind chunk buf and inc chunk #
    thePandalog->chunk.buf_p = thePandalog->chunk.buf;
    thePandalog->chunk_num ++;
    thePandalog->chunk.ind_entry = 0;
}
コード例 #6
0
ファイル: file.c プロジェクト: rkd77/elinks-tv
/* First information such as permissions is gathered for each directory entry.
 * Finally the sorted entries are added to the @data->fragment one by one. */
static inline void
add_dir_entries(struct directory_entry *entries, unsigned char *dirpath,
		struct string *page)
{
	unsigned char dircolor[8];
	int dirpathlen = strlen((const char *)dirpath);
	int i;

	/* Setup @dircolor so it's easy to check if we should color dirs. */
	if (get_opt_bool((const unsigned char *)"document.browse.links.color_dirs", NULL)) {
		color_to_string(get_opt_color((const unsigned char *)"document.colors.dirs", NULL),
				(unsigned char *) &dircolor);
	} else {
		dircolor[0] = 0;
	}

	for (i = 0; entries[i].name; i++) {
		add_dir_entry(&entries[i], page, dirpathlen, dircolor);
		mem_free(entries[i].attrib);
		mem_free(entries[i].name);
	}

	/* We may have allocated space for entries but added none. */
	mem_free_if(entries);
}
コード例 #7
0
ファイル: ext2_functions.c プロジェクト: desiros777/desiros
int ext2_rename(inode_t *old_dir, dentry_t *old_dentry, inode_t *new_dir, dentry_t *new_dentry) {
        // Remove inode from parent dir.
        remove_dir_entry((ext2_fs_instance_t*)old_dir->i_instance, old_dir->i_ino, old_dentry->d_name);

        add_dir_entry((ext2_fs_instance_t*)new_dir->i_instance, new_dir->i_ino, new_dentry->d_name, EXT2_FT_REG_FILE, old_dentry->d_inode->i_ino); //XXX

        return 0;
}
コード例 #8
0
ファイル: plog.c プロジェクト: AmesianX/panda
int pandalog_close_write(void) {
    // finish current chunk then write directory info and header
    write_current_chunk();
    // Not a mistake!
    // this will add one more dir entry for last instr and file pos
    add_dir_entry(thePandalog->chunk_num);
    write_dir();
    return 0;
}
コード例 #9
0
ファイル: lists.c プロジェクト: TheKeyboardist/interface
void list_path(char *path, list_t *list)
{
	int fd;
	int n = 0;

	iox_dirent_t buf;

	if(!strncmp(path,"cdfs:",5))
	{
		CDVD_FlushCache();
	}

	// Add fake .. directory entry
	add_reg_entry(list->entries, "..", n++);

	// Try to open the path
	if((fd=fileXioDopen(path)) < 0)
	{
		list->num = n;
		return;
	}
	else
	{

		// Add directories first
		while(fileXioDread(fd, &buf) > 0)
		{

			if(buf.stat.mode & FIO_S_IFDIR && (!strcmp(buf.name,".") || !strcmp(buf.name,"..")))
				continue;

			if(buf.stat.mode & FIO_S_IFDIR)
			{
				add_dir_entry(list->entries, buf.name, n++);
			}

			if (buf.stat.mode & FIO_S_IFREG)
			{
				add_reg_entry(list->entries, buf.name, n++);
			}

			// Prevent overflowing the list
			if (n >= list->size)
			{
				break;
			}

		}

		list->num = n;

		fileXioDclose(fd);

	}

}
コード例 #10
0
ファイル: name-hash.c プロジェクト: 0369/git
static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
{
	if (ce->ce_flags & CE_HASHED)
		return;
	ce->ce_flags |= CE_HASHED;
	hashmap_entry_init(ce, memihash(ce->name, ce_namelen(ce)));
	hashmap_add(&istate->name_hash, ce);

	if (ignore_case)
		add_dir_entry(istate, ce);
}
コード例 #11
0
ファイル: file.c プロジェクト: HarryR/sanos
static struct inode *open_always(struct filsys *fs, char *name, int len, int mode)
{
  struct inode *dir;
  struct inode *inode;
  vfs_ino_t ino;

  dir = parse_name(fs, &name, &len);
  if (!dir) return NULL;

  ino = find_dir_entry(dir, name, len);
  if (ino == -1)
  {
    inode = alloc_inode(dir, VFS_S_IFREG | mode);
    if (!inode) 
    {
      release_inode(dir);
      return NULL;
    }

    inode->desc->linkcount++;
    mark_inode_dirty(inode);

    if (add_dir_entry(dir, name, len, inode->ino) < 0)
    {
      unlink_inode(inode);
      release_inode(inode);
      release_inode(dir);
      return NULL;
    }
  }
  else
  {
    inode = get_inode(fs, ino);
    if (!inode) 
    {
      release_inode(dir);
      return NULL;
    }

    if (VFS_S_ISDIR(inode->desc->mode))
    {
      release_inode(dir);
      release_inode(inode);
      return NULL;
    }
  }

  release_inode(dir);
  return inode;
}
コード例 #12
0
ファイル: file-map.c プロジェクト: samath/140-v2
struct file_synch_status *status_for_inode (struct inode *inode)
{
  if (inode_get_inumber (inode) == FREE_MAP_SECTOR) return &free_map_synch;

  lock_acquire (&(fm->file_map_lock));
  struct fpm_info *start = fm->fp_map[hash_inode(inode)];
  while (start) {
    if (start->inode == inode) break;
    start = start->next;
  }
  struct file_synch_status *retval = 
      (start == NULL) ? add_dir_entry (inode) : &start->status;
  lock_release (&(fm->file_map_lock));
  return retval;
}
コード例 #13
0
ファイル: file.c プロジェクト: HarryR/sanos
static int create_new(struct filsys *fs, char *name, ino_t ino, int mode, struct inode **retval) {
  struct inode *dir;
  struct inode *inode;
  int rc;
  int len = strlen(name);

  rc = diri(fs, &name, &len, &dir);
  if (rc < 0) return rc;

  rc = find_dir_entry(dir, name, len, NULL);
  if (rc != -ENOENT) {
    release_inode(dir);
    return rc >= 0 ? -EEXIST : rc;
  }

  if (ino == NOINODE) {
    inode = alloc_inode(dir, S_IFREG | (mode & S_IRWXUGO));
    if (!inode) rc = -ENOSPC;
  } else {
    rc = get_inode(fs, ino, &inode);
    if (rc < 0) inode = NULL;
    if (inode) {
      inode->desc->ctime = inode->desc->mtime = time(NULL);
      inode->desc->uid = inode->desc->gid = 0;
      inode->desc->mode = S_IFREG | 0700;
      inode->desc->linkcount++;
      mark_inode_dirty(inode);
    }
  }

  if (!inode) {
    release_inode(dir);
    return rc;
  }

  rc = add_dir_entry(dir, name, len, inode->ino);
  if (rc < 0) {
    unlink_inode(inode);
    release_inode(inode);
    release_inode(dir);
    return rc;
  }

  release_inode(dir);
  *retval = inode;
  return 0;
}
コード例 #14
0
static void symlink_new(struct dir_info *dir, const char *name)
{
	struct symlink_info *s;
	char *path;
	size_t sz;

	sz = sizeof(struct symlink_info);
	s = malloc(sz);
	CHECK(s != NULL);
	memset(s, 0, sz);
	add_dir_entry(dir, 's', name, s);

	path = dir_path(dir, name);
	s->target_pathname = pick_symlink_target(path);
	CHECK(symlink(s->target_pathname, path) != -1);
	free(path);
}
コード例 #15
0
ファイル: file.c プロジェクト: HarryR/sanos
static struct inode *create_new(struct filsys *fs, char *name, int len, int mode)
{
  struct inode *dir;
  struct inode *inode;
  struct inode *oldinode;
  vfs_ino_t oldino;

  dir = parse_name(fs, &name, &len);
  if (!dir) return NULL;

  inode = alloc_inode(dir, VFS_S_IFREG | mode);
  if (!inode)
  {
    release_inode(dir);
    return NULL;
  }

  inode->desc->linkcount++;
  mark_inode_dirty(inode);

  oldino = modify_dir_entry(dir, name, len, inode->ino);
  if (oldino != -1)
  {
    oldinode = get_inode(fs, oldino);
    if (oldinode)
    {
      unlink_inode(oldinode);
      release_inode(oldinode);
    }
  }
  else
  {
    if (add_dir_entry(dir, name, len, inode->ino) < 0)
    {
      unlink_inode(inode);
      release_inode(inode);
      release_inode(dir);
      return NULL;
    }
  }

  release_inode(dir);
  return inode;
}
コード例 #16
0
ファイル: file.c プロジェクト: HarryR/sanos
static struct inode *create_always(struct filsys *fs, char *name, int len, vfs_ino_t ino, int mode)
{
  struct inode *dir;
  struct inode *inode;

  dir = parse_name(fs, &name, &len);
  if (!dir) return NULL;

  if (find_dir_entry(dir, name, len) != -1)
  {
    release_inode(dir);
    return NULL;
  }

  if (ino == -1)
    inode = alloc_inode(dir, VFS_S_IFREG | mode);
  else
  {
    inode = get_inode(fs, ino);
    if (inode->desc->ctime == 0) inode->desc->ctime = time(NULL);
    inode->desc->mode = VFS_S_IFREG | mode;
  }

  if (!inode)
  {
    release_inode(dir);
    return NULL;
  }

  inode->desc->linkcount++;
  mark_inode_dirty(inode);

  if (add_dir_entry(dir, name, len, inode->ino) < 0)
  {
    unlink_inode(inode);
    release_inode(inode);
    release_inode(dir);
    return NULL;
  }

  release_inode(dir);
  return inode;
}
コード例 #17
0
ファイル: file.c プロジェクト: HarryR/sanos
static int open_always(struct filsys *fs, char *name, int mode, struct inode **retval) {
  struct inode *dir;
  struct inode *inode;
  ino_t ino;
  int rc;
  int len = strlen(name);

  rc = diri(fs, &name, &len, &dir);
  if (rc < 0) return rc;

  rc = find_dir_entry(dir, name, len, &ino);
  if (rc < 0 && rc != -ENOENT) {
    release_inode(dir);
    return rc;
  }

  if (rc == -ENOENT) {
    inode = alloc_inode(dir, S_IFREG | (mode & S_IRWXUGO));
    if (!inode) {
      release_inode(dir);
      return -ENOSPC;
    }

    rc = add_dir_entry(dir, name, len, inode->ino);
    if (rc < 0) {
      unlink_inode(inode);
      release_inode(inode);
      release_inode(dir);
      return rc;
    }
  } else {
    rc = get_inode(fs, ino, &inode);
    if (rc < 0) {
      release_inode(dir);
      return rc;
    }
  }

  release_inode(dir);
  *retval = inode;
  return 0;
}
コード例 #18
0
ファイル: filtering.c プロジェクト: vifm/vifm
void
filters_drop_temporaries(view_t *view, dir_entry_t entries[])
{
	/* This is basically a simplified version of update_filtering_lists().  Not
	 * sure if it's worth merging them. */

	int i;
	size_t list_size = 0U;

	for(i = 0; i < view->list_rows; ++i)
	{
		dir_entry_t *new_entry;
		dir_entry_t *const entry = &view->dir_entry[i];

		/* The tag field links to position of nodes passed through filter in the
		 * list of visible files.  Removed nodes have -1. */
		entry->tag = -1;

		if(entry->temporary)
		{
			fentry_free(view, entry);
			continue;
		}

		new_entry = add_dir_entry(&entries, &list_size, entry);
		if(new_entry != NULL)
		{
			entry->tag = list_size - 1U;
			/* We basically grow the tree node by node while performing
			 * reparenting. */
			reparent_tree_node(entry, new_entry);
		}
	}

	dynarray_free(view->dir_entry);
	view->dir_entry = entries;
	view->list_rows = list_size;
}
コード例 #19
0
ファイル: filtering.c プロジェクト: vifm/vifm
/* Copies/moves elements of the unfiltered list into dir_entry list.  add
 * parameter controls whether entries matching filter are copied into dir_entry
 * list.  clear parameter controls whether entries not matching filter are
 * cleared in unfiltered list.  Returns zero unless addition is performed in
 * which case can return non-zero when all files got filtered out. */
static int
update_filtering_lists(view_t *view, int add, int clear)
{
	/* filters_drop_temporaries() is a similar function. */

	size_t i;
	size_t list_size = 0U;
	dir_entry_t *parent_entry = NULL;
	int parent_added = 0;

	for(i = 0; i < view->local_filter.unfiltered_count; ++i)
	{
		/* FIXME: some very long file names won't be matched against some
		 * regexps. */
		char name_with_slash[NAME_MAX + 1 + 1];

		dir_entry_t *const entry = &view->local_filter.unfiltered[i];
		const char *name = entry->name;

		if(is_parent_dir(name))
		{
			if(entry->child_pos == 0)
			{
				parent_entry = entry;
				if(add && cfg_parent_dir_is_visible(is_root_dir(view->curr_dir)))
				{
					(void)add_dir_entry(&view->dir_entry, &list_size, entry);

					parent_added = 1;
				}
				continue;
			}
			else if(!filter_is_empty(&view->local_filter.filter))
			{
				if(clear)
				{
					fentry_free(view, entry);
				}
				continue;
			}
		}

		if(fentry_is_dir(entry))
		{
			append_slash(name, name_with_slash, sizeof(name_with_slash));
			name = name_with_slash;
		}

		/* tag links to position of nodes passed through filter in list of visible
		 * files.  Nodes that didn't pass have -1. */
		entry->tag = -1;
		if(filter_matches(&view->local_filter.filter, name) != 0)
		{
			if(add)
			{
				dir_entry_t *e = add_dir_entry(&view->dir_entry, &list_size, entry);
				if(e != NULL)
				{
					entry->tag = list_size - 1U;
					/* We basically grow the tree node by node while performing
					 * reparenting. */
					reparent_tree_node(entry, e);
				}
			}
		}
		else
		{
			if(clear)
			{
				fentry_free(view, entry);
			}
		}
	}

	if(clear)
	{
		/* XXX: the check of name pointer is horrible, but is needed to prevent
		 *      freeing of entry in use. */
		if(!parent_added && parent_entry != NULL && list_size != 0U &&
				view->dir_entry[0].name != parent_entry->name)
		{
			fentry_free(view, parent_entry);
		}
	}
	if(add)
	{
		view->list_rows = list_size;
		view->filtered = view->local_filter.prefiltered_count
		               + view->local_filter.unfiltered_count - list_size;
		ensure_filtered_list_not_empty(view, parent_entry);
		return list_size == 0U
		    || (list_size == 1U && parent_added &&
						(filter_matches(&view->local_filter.filter, "../") == 0));
	}
	return 0;
}
コード例 #20
0
ファイル: fscalls.c プロジェクト: sunank200/ATOM-OS
int syscall_rename(const char *a_oldpath, const char *a_newpath)
{
	int ohandle, nhandle;
	int drive1, drive2;
	char dir_path1[512], dir_path2[512];
	char name_comp1[13], name_comp2[13], conv_name1[11], conv_name2[11];
	char oldpath[512], newpath[512];
	struct dir_entry dent1, dent2;
	int exist1, exist2;
	struct DIR_FILE *dirf;
	int len1, len2;
	int i,t;

	len1 = strlen(a_oldpath);
	len2 = strlen(a_newpath);

	if (len1 > 512 || len2 > 512) return ELONGPATH;

	strcpy(oldpath,a_oldpath);
	strcpy(newpath,a_newpath);

	if (oldpath[len1-1] == '/' || oldpath[len1-1] == '\\') oldpath[len1-1] = '\0';
	if (newpath[len2-1] == '/' || newpath[len2-1] == '\\') newpath[len2-1] = '\0';
	parse_path(oldpath, &drive1, dir_path1, name_comp1);
	parse_path(newpath, &drive2, dir_path2, name_comp2);

	if (drive1 != drive2) return EDEVICE_DIFFERENT;

	nhandle = open_path(drive2, dir_path2);
	if (nhandle < 0) return nhandle;

	if (name_comp2[0] !='\0')
	{
		if (convert_name(name_comp2, conv_name2) < 0)
		{
			close_dir(nhandle);
			return EINVALIDNAME; // Error
		}

		exist2 = find_entry(nhandle, conv_name2, &dent2);
	}
	
	ohandle = open_path(drive1, dir_path1);
	if (ohandle < 0)
	{
		close_dir(nhandle);
		return ohandle;
	}
	if (name_comp1[0] != '\0')
	{
		if (convert_name(name_comp1, conv_name1) < 0)
		{
			close_dir(nhandle);
			close_dir(ohandle);
			return EINVALIDNAME; // Error
		}

		exist1 = find_entry(ohandle, conv_name1, &dent1);
	}

	// Check whether new path exists and is removable
	if ((exist2 == 1) && ((dent2.attrib & FTYPE_READONLY) || ((dent2.attrib & FTYPE_DIR) && (empty_dir(nhandle, &dent2) != 1))))
	{
		close_dir(nhandle);
		close_dir(ohandle);
		return ETARGET_EXISTS;
	}

	// Check if source exists and is movable
	if (exist1 != 1)
	{
		close_dir(nhandle);
		close_dir(ohandle);
		return EPATH_NOT_EXISTS;
	}
	if ((dent1.attrib & FTYPE_READONLY) != 0)
	{
		close_dir(nhandle);
		close_dir(ohandle);
		return EREADONLY;
	}
	// Check whether oldpath is not a subpath of newpath
	if ((dent1.attrib & FTYPE_DIR) && (ohandle != nhandle))
	{	
		t = nhandle;
		dirf = &dir_file_list[t];

		while (dirf->parent_index >= 0 && dirf->parent_index != ohandle)
		{
			t = dirf->parent_index;
			dirf = &dir_file_list[t];
		}
		
		if (dirf->parent_index == ohandle)
		{
			close_dir(nhandle);
			close_dir(ohandle);
			return EOLDPATH_PARENT_OF_NEWPATH;
		}
	}

	// Check if newpath already exists whether it is compatible or not
	if ((exist2 == 1) && (((dent1.attrib & FTYPE_DIR) != 0 && (dent2.attrib & FTYPE_DIR) == 0) || ((dent1.attrib & FTYPE_DIR) == 0 && (dent2.attrib & FTYPE_DIR) != 0))) 
	{
		close_dir(nhandle);
		close_dir(ohandle);
		return ESRC_DEST_NOT_SAME_TYPE;
	}

	// Remove destination entry if exists
	if (exist2 == 1)
	{
		if (dent2.attrib & FTYPE_DIR)
			syscall_rmdir(newpath);
		else	syscall_unlink(newpath);
	}

	// Add the source dir entry after changing the name
	// to destination directory
	bcopy( (char *)&dent1, (char *)&dent2, sizeof(struct dir_entry));
	for (i=0; i<11; i++)	// Both name and extension
		dent2.name[i] = conv_name2[i];

	t = add_dir_entry(nhandle, &dent2);
	if (t == 1)
	{
		delete_dir_entry(ohandle, dent1.name);
	}

	// Close the handles of parent directories
	close_dir(ohandle);
	close_dir(nhandle);
	
	if (t == 1) return 0;
	else	return t;

}
コード例 #21
0
ファイル: fs.c プロジェクト: kshmir/so-2011-2
// Used to move a file
unsigned int fs_mv(char * name, char * newname, int from_inode) {
	int i1 = fs_open_file(name, from_inode, O_WR | O_RD, EXT2_S_IFREG);
	if(i1 < 0)	{
		return i1; // If there's an error with the first name then there's nothing to do actually.
	}
	
	int i2 = fs_indir(newname, from_inode);
	if(i2 == 0)	{
		folder_rem_direntry(i1, n._dir_inode);

		inode_read(from_inode, &n);
		int log_block = n.blocks / 2;

		block_clear(&b);
		dir_op_offset = 0;
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, i1, newname, &log_block);
		log_block_write(&n, &log_block);		
		
		n.blocks = log_block * 2;
		inode_write(from_inode, &n);
		
		return 1;
	} else {
		inode_read(i2, &n);

		if(!fs_has_perms(&n, ACTION_READ))	{
			return ERR_PERMS;
		}
		
		if(!(n.mode & EXT2_S_IFDIR))	{
			return ERR_INVALID_TYPE;
		}
		
		if (fs_indir(name, i2)) {
			return ERR_REPEATED;
		}

		int log_block = n.blocks / 2;

		block_clear(&b);
		dir_op_offset = 0;
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, i1, name, &log_block);
		log_block_write(&n, &log_block);

		n.blocks = log_block * 2;
		inode_write(i2, &n);

		inode_read(i1, &n);
		folder_rem_direntry(i1, n._dir_inode);
		inode_read(i1, &n);
		folder_rem_direntry(n._dir_inode, i1);
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, i2, "..", &log_block);
		log_block_write(&n, &log_block);
		n._dir_inode = i2;
		inode_write(i1, &n);
	}	
	return i1;
	
}
コード例 #22
0
ファイル: fs.c プロジェクト: kshmir/so-2011-2
// Makes a new directory
unsigned int fs_mkdir(char * name, unsigned int parent_inode) {
	unsigned int inode_id = 0;
	if ((inode_id = fs_indir(name, parent_inode))) {
		return 0;
	}
	inode_id = bitmap_first_valued(bm_inodes, FS_INODE_BITMAP_SIZE, 0) + 1;
	
	if (!parent_inode) {
		parent_inode = inode_id;
	}
	
	int log_block;
	
	if (parent_inode != inode_id) {
		inode_read(parent_inode, &n);
		
		if(!fs_has_perms(&n, ACTION_WRITE))	{
			return ERR_PERMS;
		}
		
		log_block = n.blocks / 2;
		
		block_clear(&b);
		dir_op_offset = 0;
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, inode_id, name, &log_block);
		log_block_write(&n, &log_block);
		
		inode_write(parent_inode, &n);	
	}
	bitmap_write(bm_inodes, inode_id - 1, 1);

	
	

	
	inode_clear(&n);
	

	if(!fs_done)
	{
		n.uid = 0;
	} else {
		n.uid = current_ttyc()->uid;
	}

	n.mode = EXT2_S_IFDIR;
	n.size = 0;
	n.blocks = 0; // Beware! This represents the SECTORS!
	
	
	log_block = n.blocks / 2;
	
	block_clear(&b);
	dir_op_offset = 0;
	
	add_dir_entry(&n, EXT2_FT_DIR, inode_id, ".", &log_block);
	add_dir_entry(&n, EXT2_FT_DIR, parent_inode, "..", &log_block);

	log_block_write(&n, &log_block);
	
	n.blocks = (log_block) * 2;
	
	n.i_file_acl = 511;
	n._dir_inode = parent_inode;
	n._last_write_offset = dir_op_offset;
	
	inode_write(inode_id, &n);	
	



	
	fs_bitmaps_write_all();
	return inode_id;
}
コード例 #23
0
ファイル: fs.c プロジェクト: kshmir/so-2011-2
// Opens a file
unsigned int fs_open_file(char * name, unsigned int folder_inode, int mode, int type) {
	unsigned int inode_id = 0;

	if(strcmp(name, "/") == 0 && strlen(name) == strlen("/"))	{
		return 1; // root
	}


	if(name[0] == 0)
	{
		inode_id = current_ttyc()->pwd;
	} else {
		inode_id = fs_indir(name, folder_inode);
	}
	
	if (inode_id) {
		if (mode & O_CREAT) {
			int _rm_res = fs_rm(inode_id, 0);
			if(_rm_res < 0) {
				return _rm_res;
			}
		} else if(mode & O_NEW) {
			inode_read(inode_id, &n);
			if(n.mode == EXT2_S_IFLNK)	{
				return n.data_blocks[0];
			}
			return inode_id;
		} 
		else {
			inode_read(inode_id, &n);
			int can = 1;
			if((mode & O_RD) && !fs_has_perms(&n, ACTION_READ))	{
				can = 0;
			}
			if((mode & O_WR) && !fs_has_perms(&n, ACTION_WRITE))	{
				can = 0;
			}
			if(can || !fs_done)	{
				if(n.mode == EXT2_S_IFLNK)	{
					return n.data_blocks[0];
				}
				return inode_id;
			} else {
				return ERR_PERMS;
			}
		}
	} else if (!(mode & (O_NEW | O_CREAT))) {
		return ERR_NO_EXIST;
	}
	
	inode_id = bitmap_first_valued(bm_inodes, FS_INODE_BITMAP_SIZE, 0) + 1;
	
	if (!folder_inode) {
		folder_inode = inode_id;
	}
	
	int log_block;
	
	if (folder_inode != inode_id) {
		inode_read(folder_inode, &n);
		
		if(!fs_has_perms(&n, ACTION_WRITE))	{
			return ERR_PERMS;
		}
		
		log_block = n.blocks / 2;
		
		block_clear(&b);
		dir_op_offset = 0;
		log_block_read(&n, &log_block);
		add_dir_entry(&n, EXT2_FT_DIR, inode_id, name, &log_block);
		log_block_write(&n, &log_block);
		
		inode_write(folder_inode, &n);	
	}
	bitmap_write(bm_inodes, inode_id - 1, 1);
		
	inode_clear(&n);
	
	
	if(!fs_done)
	{
		n.uid = 0;
	} else {
		n.uid = current_ttyc()->uid;
	}
	
	n.mode =  type;
	n.size = 0;
	n.blocks = 0; // Beware! This represents the SECTORS!
	
	
	n._last_write_offset = 0;
	n.i_file_acl = 511;
	n._dir_inode = folder_inode;
	
	inode_write(inode_id, &n);	
	
	inode_clear(&n);

	if(n.mode == EXT2_S_IFLNK)	{
		return n.data_blocks[0];
	}
	
	return inode_id;
}
コード例 #24
0
ファイル: ns_od.c プロジェクト: RomiPierre/osx
static callback_ret_t
readdir_callback(CFStringRef inkey, CFStringRef value, void *udata)
{
	char *str;
	CFIndex inkeylen, value_len;
	struct dir_cbdata *temp = (struct dir_cbdata *)udata;
	struct dir_entry **list = temp->list;
	struct dir_entry *last = temp->last;
	char key[MAXFILENAMELEN+1];
	char linebuf[LINESZ], lineqbuf[LINESZ];
	int error;

	if (trace > 1) {
		str = od_CFStringtoCString(inkey);
		if (str != NULL) {
			trace_prt(1, "  readdir_callback called: key %s\n",
			    str);
			free(str);
		}
	}

	inkeylen = od_cfstrlen(inkey);
	if (inkeylen > (CFIndex)MAXFILENAMELEN)
		return (OD_CB_KEEPGOING);

	if (inkeylen == 0)
		return (OD_CB_KEEPGOING);	/* ignore empty lines */
	if (!od_cfstrlcpy(key, inkey, inkeylen))
		return (OD_CB_KEEPGOING);
	if (isspace((unsigned char)key[0]) || key[0] == '#')
		return (OD_CB_KEEPGOING);	/* ignore blank lines and comments */

	/*
	 * Wildcard entry should be ignored - following entries should continue
	 * to be read to corroborate with the way we search for entries in
	 * LDAP, i.e., first for an exact key match and then a wildcard
	 * if there's no exact key match.
	 */
	if (key[0] == '*' && key[1] == '\0')
		return (OD_CB_KEEPGOING);

	value_len = od_cfstrlen(value);
	if (value_len >= LINESZ)
		return (OD_CB_KEEPGOING);
	if (value_len < 2)
		return (OD_CB_KEEPGOING);

	if (!od_cfstrlcpy(linebuf, value, value_len))
		return (OD_CB_KEEPGOING);
	unquote(linebuf, lineqbuf);
	error = add_dir_entry(key, linebuf, lineqbuf, list, &last);
	if (error != -1) {
		if (error != 0) {
			temp->error = error;
			return (OD_CB_ERROR);
		}
		temp->last = last;
	}

	if (trace > 1)
		trace_prt(1, "readdir_callback returning OD_CB_KEEPGOING...\n");

	return (OD_CB_KEEPGOING);
}
コード例 #25
0
static void rename_entry(struct dir_entry_info *entry)
{
	struct dir_entry_info *rename_entry = NULL;
	struct dir_info *parent;
	char *path, *to, *name;
	int ret, isdir, retry;

	if (!entry->parent)
		return;

	for (retry = 0; retry < 3; retry++) {
		path = dir_path(entry->parent, entry->name);
		isdir = entry->type == 'd' ? 1 : 0;
		name = pick_rename_name(&parent, &rename_entry, isdir);
		to = dir_path(parent, name);
		/*
		 * Check we are not trying to move a directory to a subdirectory
		 * of itself.
		 */
		if (isdir) {
			struct dir_info *p;

			for (p = parent; p; p = p->parent)
				if (p == entry->entry.dir)
					break;
			if (p == entry->entry.dir) {
				free(path);
				free(name);
				free(to);
				path = NULL;
				continue;
			}
		}
		break;
	}

	if (!path)
		return;

	ret = rename(path, to);
	if (ret == -1) {
		if (errno == ENOSPC)
			full = 1;
		CHECK(errno == ENOSPC || errno == EBUSY);
		free(path);
		free(name);
		free(to);
		return;
	}

	free(path);
	free(to);

	if (rename_entry && rename_entry->type == entry->type &&
	    rename_entry->entry.target == entry->entry.target) {
		free(name);
		return;
	}

	add_dir_entry(parent, entry->type, name, entry->entry.target);
	if (rename_entry)
		remove_dir_entry(rename_entry);
	remove_dir_entry(entry);
	free(name);
}
コード例 #26
0
ファイル: lists.c プロジェクト: TheKeyboardist/interface
void list_mountable_devices(char *device, list_t *list)
{

	int i,n = 0;

	iox_stat_t stat;

	char mc_path[6] = "mc0:";
	char mass_device[8] = "mass0:";

	add_reg_entry(list->entries,"..",n++);

	if (!strcmp(device,"mc"))
	{
		for (i = 0; i < 2; i++)
		{
			mc_path[2] = '0' + i;
			if(!fileXioGetStat(mc_path,&stat))
			{
				add_dir_entry(list->entries,mc_path,n++);
			}
		}

		list->num = n;

	}

	if (!strcmp(device,"mass"))
	{
		for(i=0; i < 10; i++)
		{

			mass_device[4] = '0'+i;

			if(!(fileXioGetStat(mass_device, &stat) < 0))
			{
				add_dir_entry(list->entries,mass_device,n++);
			}
		}

	// Older versions of the module only support "mass:"
		if (!n)
		{
			if (!(fileXioGetStat("mass:",&stat) < 0))
			{
				add_dir_entry(list->entries,"mass:",n++);
			}

		}

		list->num = n;

	}

	if (!strcmp(device,"hdd"))
	{

		// Checking for "hdd0:" doesn't work, maybe since it's a block device
		//if (!(fileXioGetStat("hdd0:",&stat) < 0))
		{
			list_partitions(list);
		}
	}

	if (!strcmp(device,"cdfs"))
	{
		//if(!(fileXioGetStat("cdfs:",&stat) < 0))
		{
			add_dir_entry(list->entries,"cdfs:", n++);
		}

		CDVD_FlushCache();
		refresh_cdfs();

		list->num = n;

	}
	else
	{
		CDVD_Stop();
	}

}
コード例 #27
0
ファイル: file.c プロジェクト: HarryR/sanos
static int create_always(struct filsys *fs, char *name, int mode, struct inode **retval) {
  struct inode *dir;
  struct inode *inode;
  struct inode *oldinode;
  ino_t oldino;
  int rc;
  int len = strlen(name);

  rc = diri(fs, &name, &len, &dir);
  if (rc < 0) return rc;

  rc = find_dir_entry(dir, name, len, &oldino);
  if (rc == 0) {
    rc = get_inode(fs, oldino, &oldinode);
    if (rc < 0) {
      release_inode(dir);
      return rc;
    }

    if (S_ISDIR(oldinode->desc->mode) && oldinode->desc->linkcount == 1) {
      release_inode(dir);
      return -EISDIR;
    }

    inode = alloc_inode(dir, S_IFREG | (mode & S_IRWXUGO));
    if (!inode) {
      release_inode(dir);
      return -ENOSPC;
    }

    rc = modify_dir_entry(dir, name, len, inode->ino, NULL);
    if (rc < 0) {
      unlink_inode(inode);
      release_inode(inode);
      release_inode(dir);
      return rc;
    }

    unlink_inode(oldinode);
    release_inode(oldinode);
  } else if (rc == -ENOENT) {
    inode = alloc_inode(dir, S_IFREG | (mode & S_IRWXUGO));
    if (!inode) {
      release_inode(dir);
      return -ENOSPC;
    }

    rc = add_dir_entry(dir, name, len, inode->ino);
    if (rc < 0) {
      unlink_inode(inode);
      release_inode(inode);
      release_inode(dir);
      return rc;
    }
  } else {
    release_inode(dir);
    return rc;
  }

  release_inode(dir);
  *retval = inode;
  return 0;
}
コード例 #28
0
ファイル: mux.c プロジェクト: GNUHurdTR/hurd
/* Implement the netfs_get_directs callback as described in
   <hurd/netfs.h>. */
error_t
netfs_get_dirents (struct iouser *cred, struct node *dir,
		   int first_entry, int num_entries, char **data,
		   mach_msg_type_number_t *data_len,
		   vm_size_t max_data_len, int *data_entries)
{
  error_t err;
  int count;
  size_t size = 0;		/* Total size of our return block.  */
  struct hostmux_name *first_name, *nm;

  /* Add the length of a directory entry for NAME to SIZE and return true,
     unless it would overflow MAX_DATA_LEN or NUM_ENTRIES, in which case
     return false.  */
  int bump_size (const char *name)
    {
      if (num_entries == -1 || count < num_entries)
	{
	  size_t new_size = size + DIRENT_LEN (strlen (name));
	  if (max_data_len > 0 && new_size > max_data_len)
	    return 0;
	  size = new_size;
	  count++;
	  return 1;
	}
      else
	return 0;
    }

  if (dir->nn->name)
    return ENOTDIR;

  pthread_rwlock_rdlock (&dir->nn->mux->names_lock);

  /* Find the first entry.  */
  for (first_name = dir->nn->mux->names, count = 2;
       first_name && first_entry > count;
       first_name = first_name->next)
    if (first_name->node)
      count++;

  count = 0;

  /* Make space for the `.' and `..' entries.  */
  if (first_entry == 0)
    bump_size (".");
  if (first_entry <= 1)
    bump_size ("..");

  /* See how much space we need for the result.  */
  for (nm = first_name; nm; nm = nm->next)
    if (nm->node && !bump_size (nm->name))
      break;

  /* Allocate it.  */
  *data = mmap (0, size, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
  err = ((void *) *data == (void *) -1) ? errno : 0;

  if (! err)
    /* Copy out the result.  */
    {
      char *p = *data;

      int add_dir_entry (const char *name, ino_t fileno, int type)
	{
	  if (num_entries == -1 || count < num_entries)
	    {
	      struct dirent hdr;
	      size_t name_len = strlen (name);
	      size_t sz = DIRENT_LEN (name_len);

	      if (sz > size)
		return 0;
	      else
		size -= sz;

	      hdr.d_fileno = fileno;
	      hdr.d_reclen = sz;
	      hdr.d_type = type;
	      hdr.d_namlen = name_len;

	      memcpy (p, &hdr, DIRENT_NAME_OFFS);
	      strcpy (p + DIRENT_NAME_OFFS, name);
	      p += sz;

	      count++;

	      return 1;
	    }
	  else
	    return 0;
	}

      *data_len = size;
      *data_entries = count;

      count = 0;

      /* Add `.' and `..' entries.  */
      if (first_entry == 0)
	add_dir_entry (".", 2, DT_DIR);
      if (first_entry <= 1)
	add_dir_entry ("..", 2, DT_DIR);

      /* Fill in the real directory entries.  */
      for (nm = first_name; nm; nm = nm->next)
	if (nm->node
	    && !add_dir_entry (nm->name, nm->fileno,
			       strcmp (nm->canon, nm->name) == 0
			         ? DT_REG : DT_LNK))
	  break;
    }
コード例 #29
0
ファイル: mkfs.gnordofs.c プロジェクト: holzplatten/gnordofs
int main(int argc, char **argv)
{
  int dev, i;
  char *zeros;
  unsigned long size;
  superblock_t *sb, *sb_dup;
  inode_t *rootdir;

  openlog("GNORDOFS", LOG_PID, LOG_LOCAL0);

  // Size = 10Mib
  size = 1024*1024*10;

  dev = open("gnordofs.img", O_RDWR | O_CREAT, 0666);
  if (dev < 0)
    {
      perror(NULL);
      exit(1);
    }

  /* Inicializar superbloque y zona de inodos. */
  sb = superblock_init(size);
  inode_list_init(dev, sb);
  //superblock_print_dump(sb);

  /* Poner cero toda la zona de bloques, por si acaso. */
  if (lseek(dev, sb->block_zone_base, SEEK_SET) < 0)
    {
      printf("Dude, WTF???\n");
      exit(1);
    }
  zeros = malloc(BLOCK_SIZE);
  memset(zeros, 0, BLOCK_SIZE);
  for (i=sb->block_zone_base;
       i < size - BLOCK_SIZE;
       i += BLOCK_SIZE)
    {
      write(dev, zeros, BLOCK_SIZE);
    }
  if (size > i)
    write(dev, zeros, size - i);

  /* Inicializar lista de bloques libres. */
  free_block_list_init(dev, sb);

  /* ¡Que no se me olvide salvar el maldito superbloque! */
  superblock_write(dev, sb);

  /* A partir de aquí se maneja casi como si estuviese inicializado. */

  /* Reservar el primer inodo libre, marcarlo como directorio,
     añadir las entradas . y .., salvarlo en disco y hacer que
     first_directory del superbloque apunte a dicho inodo.
  */
  rootdir = ialloc(dev, sb);
  // Modificar rootdir con entradas . y ..
  rootdir->type = I_DIR;
  rootdir->perms = S_IFDIR | 0755;
  add_dir_entry(dev, sb, rootdir, rootdir, ".");
  add_dir_entry(dev, sb, rootdir, rootdir, "..");
  rootdir->atime = rootdir->ctime = rootdir->mtime = time(NULL);
  iput(dev, sb, rootdir);

  sb->first_inode = rootdir->n;
  superblock_write(dev, sb);

  printf("rootdir->type = %d\n", rootdir->type);
  printf("rootdir->size = %d\n", rootdir->size);
  printf("rootdir->link_counter = %d\n", rootdir->link_counter);
  printf("rootdir->owner = %d\n", rootdir->owner);
  printf("rootdir->group = %d\n", rootdir->group);
  printf("rootdir->perms = %o\n", rootdir->perms);
  printf("rootdir->n = %d\n", rootdir->n);
  printf("rootdir->offset_ptr = %d\n", rootdir->offset_ptr);

  /* Comprobar que se puede leer el superbloque. */
  sb_dup = superblock_read(dev);
  if (!sb_dup
      || memcmp(sb, sb_dup, sizeof(struct persistent_superblock) != 0))
    {
      printf("WTF?\n");
      exit(1);
    }
  superblock_print_dump(sb_dup);
  print_free_block_list(dev, sb);

  free(sb);
  free(sb_dup);

  close(dev);

  return 0;
}