Esempio n. 1
0
int
vfs_file_begin (int const d_type, register const VFS_Query* const q)
{
    int rc = 0;

    Log_Printf (LOG_DEBUG, "%s_BEGIN '%s'",
                (d_type == DT_LNK ? "SYMLINK" : "FILE"), q->path);

    if (q->stbuf) {
        q->stbuf->st_mode  = DTTOIF(d_type) | 0444;
        q->stbuf->st_nlink = 1;
        q->stbuf->st_size  = DEFAULT_SIZE; // to be computed latter
        vfs_set_time (DEFAULT_TIME, q);
    }
    if (q->filler) {
        Log_Printf (LOG_DEBUG, "error, listing not a directory : '%s'",
                    q->path);
        rc = -ENOTDIR;
    }
    if (q->file) {
        *(q->file) = NULL;
    }
    if (q->lnk_buf) {
        if (d_type == DT_LNK) {
            if (q->lnk_bufsiz > 0)
                *(q->lnk_buf) = NUL;
        } else {
            Log_Printf (LOG_DEBUG,
                        "error, readlink on regular file : '%s'",
                        q->path);
            rc = -EINVAL;
        }
    }
    return rc;
}
Esempio n. 2
0
static int
select_dirs (const struct dirent *dirent)
{
        int result = 0;

        if (strcmp (dirent->d_name, ".") != 0 && strcmp (dirent->d_name, "..") != 0) {
                mode_t mode = 0;

#ifdef _DIRENT_HAVE_D_TYPE
                if (dirent->d_type != DT_UNKNOWN && dirent->d_type != DT_LNK) {
                        mode = DTTOIF (dirent->d_type);
                } else
#endif
                        {
                                struct stat st;
                                g_autofree char *path = NULL;

                                path = g_build_filename (LIBLOCALEDIR, dirent->d_name, NULL);
                                if (g_stat (path, &st) == 0) {
                                        mode = st.st_mode;
                                }
                        }

                result = S_ISDIR (mode);
        }

        return result;
}
Esempio n. 3
0
File: lposix.c Progetto: ktf/apt-rpm
static int aux_files(lua_State *L)
{
	DIR *d = lua_touserdata(L, lua_upvalueindex(1));
	struct dirent *entry;
	if (d == NULL) luaL_error(L, "attempt to use closed dir");
	entry = readdir(d);
	if (entry == NULL)
	{
		closedir(d);
		lua_pushnil(L);
		lua_replace(L, lua_upvalueindex(1));
		lua_pushnil(L);
	}
	else
	{
		lua_pushstring(L, entry->d_name);
#if 0
#ifdef _DIRENT_HAVE_D_TYPE
		lua_pushstring(L, filetype(DTTOIF(entry->d_type)));
		return 2;
#endif
#endif
	}
	return 1;
}
Esempio n. 4
0
  static
  int
  readdir(const Branches        &branches_,
          const char            *dirname_,
          void                  *buf_,
          const fuse_fill_dir_t  filler_)
  {
    HashSet names;
    string basepath;
    struct stat st = {0};

    for(size_t i = 0, ei = branches_.size(); i != ei; i++)
      {
        int rv;
        int dirfd;
        DIR *dh;

        basepath = fs::path::make(&branches_[i].path,dirname_);

        dh = fs::opendir(basepath);
        if(!dh)
          continue;

        dirfd     = fs::dirfd(dh);
        st.st_dev = fs::devid(dirfd);
        if(st.st_dev == (dev_t)-1)
          st.st_dev = i;

        rv = 0;
        for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh))
          {
            rv = names.put(de->d_name);
            if(rv == 0)
              continue;

            st.st_ino  = de->d_ino;
            st.st_mode = DTTOIF(de->d_type);

            fs::inode::recompute(&st);

            rv = filler_(buf_,de->d_name,&st,NO_OFFSET);
            if(rv)
              return (fs::closedir(dh),-ENOMEM);
          }

        fs::closedir(dh);
      }

    return 0;
  }
Esempio n. 5
0
/* We use this function for lstat as well since we don't have any.  */
static int
my_stat (const char *name, struct stat *st)
{
  long int idx = find_file (name);

  if (idx == -1)
    {
      PRINTF ("my_stat (\"%s\", ...) = -1 (%s)\n", name, strerror (errno));
      return -1;
    }

  memset (st, '\0', sizeof (*st));

  if (filesystem[idx].type == DT_UNKNOWN)
    st->st_mode = DTTOIF (idx + 1 < nfiles
			  && filesystem[idx].level < filesystem[idx + 1].level
			  ? DT_DIR : DT_REG) | 0777;
  else
    st->st_mode = DTTOIF (filesystem[idx].type) | 0777;

  PRINTF ("my_stat (\"%s\", { st_mode: %o }) = 0\n", name, st->st_mode);

  return 0;
}
Esempio n. 6
0
static inline void osd_it_append_attrs(struct lu_dirent *ent, __u32 attr,
				       int len, __u16 type)
{
	const unsigned    align = sizeof(struct luda_type) - 1;
	struct luda_type *lt;

	/* check if file type is required */
	if (attr & LUDA_TYPE) {
		len = (len + align) & ~align;

		lt = (void *)ent->lde_name + len;
		lt->lt_type = cpu_to_le16(DTTOIF(type));
		ent->lde_attrs |= LUDA_TYPE;
	}

	ent->lde_attrs = cpu_to_le32(ent->lde_attrs);
}
Esempio n. 7
0
static void walk_readdir_process_dir(const char* dir, CIRCLE_handle* handle)
{
    /* TODO: may need to try these functions multiple times */
    DIR* dirp = mfu_opendir(dir);

    /* if there is a permissions error and the usr read & execute are being turned
     * on when walk_stat=0 then catch the permissions error and turn the bits on */
    if (dirp == NULL) {
        if (errno == EACCES && SET_DIR_PERMS) {
            struct stat st;
            mfu_lstat(dir, &st);
            // turn on the usr read & execute bits
            st.st_mode |= S_IRUSR;
            st.st_mode |= S_IXUSR;
            mfu_chmod(dir, st.st_mode);
            dirp = mfu_opendir(dir);
            if (dirp == NULL) {
                if (errno == EACCES) {
                    MFU_LOG(MFU_LOG_ERR, "Failed to open directory with opendir: `%s' (errno=%d %s)", dir, errno, strerror(errno));
                }
            }
        }
    }

    if (! dirp) {
        /* TODO: print error */
    }
    else {
        /* Read all directory entries */
        while (1) {
            /* read next directory entry */
            struct dirent* entry = mfu_readdir(dirp);
            if (entry == NULL) {
                break;
            }

            /* process component, unless it's "." or ".." */
            char* name = entry->d_name;
            if ((strncmp(name, ".", 2)) && (strncmp(name, "..", 3))) {
                /* <dir> + '/' + <name> + '/0' */
                char newpath[CIRCLE_MAX_STRING_LEN];
                size_t len = strlen(dir) + 1 + strlen(name) + 1;
                if (len < sizeof(newpath)) {
                    /* build full path to item */
                    strcpy(newpath, dir);
                    strcat(newpath, "/");
                    strcat(newpath, name);

#ifdef _DIRENT_HAVE_D_TYPE
                    /* record info for item */
                    mode_t mode;
                    int have_mode = 0;
                    if (entry->d_type != DT_UNKNOWN) {
                        /* unlink files here if remove option is on,
                         * and dtype is known without a stat */
                        if (REMOVE_FILES && (entry->d_type != DT_DIR)) {
                            mfu_unlink(newpath);
                        } else {
                            /* we can read object type from directory entry */
                            have_mode = 1;
                            mode = DTTOIF(entry->d_type);
                            mfu_flist_insert_stat(CURRENT_LIST, newpath, mode, NULL);
                        }
                    }
                    else {
                        /* type is unknown, we need to stat it */
                        struct stat st;
                        int status = mfu_lstat(newpath, &st);
                        if (status == 0) {
                            have_mode = 1;
                            mode = st.st_mode;
                            /* unlink files here if remove option is on,
                             * and stat was necessary to get type */
                            if (REMOVE_FILES && !S_ISDIR(st.st_mode)) {
                                mfu_unlink(newpath);
                            } else {
                                mfu_flist_insert_stat(CURRENT_LIST, newpath, mode, &st);
                            }
                        }
                        else {
                            /* error */
                        }
                    }

                    /* increment our item count */
                    reduce_items++;

                    /* recurse into directories */
                    if (have_mode && S_ISDIR(mode)) {
                        handle->enqueue(newpath);
                    }
#endif
                }
                else {
                    /* TODO: print error in correct format */
                    /* name is too long */
                    MFU_LOG(MFU_LOG_ERR, "Path name is too long: %lu chars exceeds limit %lu", len, sizeof(newpath));
                }
            }
        }
    }

    mfu_closedir(dirp);

    return;
}
Esempio n. 8
0
/*
=================
Sys_ListFiles_r

Internal function to filesystem. Conventions apply:
    - files should hold at least MAX_LISTED_FILES
    - *count_p must be initialized in range [0, MAX_LISTED_FILES - 1]
    - depth must be 0 on the first call
=================
*/
void Sys_ListFiles_r(const char  *path,
                     const char  *filter,
                     unsigned    flags,
                     size_t      baselen,
                     int         *count_p,
                     void        **files,
                     int         depth)
{
    struct dirent *ent;
    DIR *dir;
    struct stat st;
    char fullpath[MAX_OSPATH];
    char *name;
    size_t len;
    void *info;

    if ((dir = opendir(path)) == NULL) {
        return;
    }

    while ((ent = readdir(dir)) != NULL) {
        if (ent->d_name[0] == '.') {
            continue; // ignore dotfiles
        }

        len = Q_concat(fullpath, sizeof(fullpath),
                       path, "/", ent->d_name, NULL);
        if (len >= sizeof(fullpath)) {
            continue;
        }

        st.st_mode = 0;

#ifdef _DIRENT_HAVE_D_TYPE
        // try to avoid stat() if possible
        if (!(flags & FS_SEARCH_EXTRAINFO)
            && ent->d_type != DT_UNKNOWN
            && ent->d_type != DT_LNK) {
            st.st_mode = DTTOIF(ent->d_type);
        }
#endif

        if (st.st_mode == 0 && stat(fullpath, &st) == -1) {
            continue;
        }

        // pattern search implies recursive search
        if ((flags & FS_SEARCH_BYFILTER) &&
            S_ISDIR(st.st_mode) && depth < MAX_LISTED_DEPTH) {
            Sys_ListFiles_r(fullpath, filter, flags, baselen,
                            count_p, files, depth + 1);

            // re-check count
            if (*count_p >= MAX_LISTED_FILES) {
                break;
            }
        }

        // check type
        if (flags & FS_SEARCH_DIRSONLY) {
            if (!S_ISDIR(st.st_mode)) {
                continue;
            }
        } else {
            if (!S_ISREG(st.st_mode)) {
                continue;
            }
        }

        // check filter
        if (filter) {
            if (flags & FS_SEARCH_BYFILTER) {
                if (!FS_WildCmp(filter, fullpath + baselen)) {
                    continue;
                }
            } else {
                if (!FS_ExtCmp(filter, ent->d_name)) {
                    continue;
                }
            }
        }

        // strip path
        if (flags & FS_SEARCH_SAVEPATH) {
            name = fullpath + baselen;
        } else {
            name = ent->d_name;
        }

        // strip extension
        if (flags & FS_SEARCH_STRIPEXT) {
            *COM_FileExtension(name) = 0;

            if (!*name) {
                continue;
            }
        }

        // copy info off
        if (flags & FS_SEARCH_EXTRAINFO) {
            info = FS_CopyInfo(name,
                               st.st_size,
                               st.st_ctime,
                               st.st_mtime);
        } else {
            info = FS_CopyString(name);
        }

        files[(*count_p)++] = info;

        if (*count_p >= MAX_LISTED_FILES) {
            break;
        }
    }

    closedir(dir);
}
Esempio n. 9
0
static void overlay_readdirplus_full(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    struct fuse_entry_param e;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct overlay_readdir_struct *overlay_readdir=(struct overlay_readdir_struct *)dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    unsigned char dtype;
    struct name_struct xname={NULL, 0, 0};
    int res=0;

    memset(&e, 0, sizeof(struct fuse_entry_param));

    e.generation = 1;
    e.attr_timeout = fs_options.attr_timeout;
    e.entry_timeout = fs_options.entry_timeout;

    e.attr.st_blksize=4096;
    e.attr.st_blocks=0;

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

    	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = 0;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotname;

	    inode->nlookup++;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if ( ! dh->parent->parent ) {

		inode=dh->parent->inode;

	    } else {

		inode=dh->parent->parent->inode;

	    }

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = 0;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotdotname;

	    inode->nlookup++;

    	} else {

	    if (! dh->entry) {

		readdir:

		res=get_direntry(overlay_readdir, &xname, &dtype, &error);

		if (res<=0) {

		    if (res==-1) {

			free(buff);
			unlock_directory(directory, _DIRECTORY_LOCK_EXCL);
			goto error;

		    }

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		if (fstatat(overlay_readdir->fd, xname.name, &e.attr, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT)==-1) {

		    goto readdir;

		}

		logoutput("overlayfs_readdirplus_real_full: read %s", xname.name);

		xname.len=strlen(xname.name);
		calculate_nameindex(&xname);

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {

			memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));
			inode->mode=DTTOIF(dtype);

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		    e.attr.st_ino=inode->ino;
		    e.ino=inode->ino;
		    e.attr.st_rdev = inode->rdev;
		    e.attr.st_dev = 0;
		    name=entry->name.name;

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		name=entry->name.name;
		dh->entry=entry;

		inode->mode = e.attr.st_mode;
		inode->nlink = e.attr.st_nlink;
		inode->uid = e.attr.st_uid;
		inode->gid = e.attr.st_gid;
		inode->rdev = e.attr.st_rdev;

		inode->mtim.tv_sec = e.attr.st_mtim.tv_sec;
		inode->mtim.tv_nsec = e.attr.st_mtim.tv_nsec;
		inode->ctim.tv_sec = e.attr.st_ctim.tv_sec;
		inode->ctim.tv_nsec = e.attr.st_ctim.tv_nsec;

		if (S_ISDIR(e.attr.st_mode)) {

		    e.attr.st_size=0;

		} else {

		    inode->size=e.attr.st_size;

		}

	    } else {

		entry=dh->entry;
		inode=entry->inode;
		name=entry->name.name;

		e.attr.st_mode = inode->mode;
		e.attr.st_nlink = inode->nlink;
		e.attr.st_uid = inode->uid;
		e.attr.st_gid = inode->gid;
		e.attr.st_rdev = inode->rdev;

		if (S_ISDIR(inode->mode)) {

		    e.attr.st_size = 0;

		} else {

		    e.attr.st_size = inode->size;

		}

		e.attr.st_atim.tv_sec = 0;
		e.attr.st_atim.tv_nsec = 0;
		e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
		e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
		e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
		e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

		inode->nlookup++;

	    }

	    e.ino = inode->ino;
	    e.attr.st_ino = e.ino;

	}

    	dirent_size=fuse_add_direntry_plus(req, buff+pos, size-pos, name, &e, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset=offset+1;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
Esempio n. 10
0
static void overlay_readdir_full(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    struct stat st;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct overlay_readdir_struct *overlay_readdir=(struct overlay_readdir_struct *)dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    struct name_struct xname={NULL, 0, 0};
    unsigned char dtype=0;
    int res;

    memset(&st, 0, sizeof(struct stat));

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

    	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

    	    st.st_ino = inode->ino;
	    st.st_mode = S_IFDIR;
	    name = (char *) dotname;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if ( ! dh->parent->parent ) {

		inode=dh->parent->inode;
	    	st.st_ino = inode->ino;

	    } else {
		struct entry_struct *parent=dh->parent->parent;

		inode=parent->inode;
	    	st.st_ino=inode->ino;

	    }

	    st.st_mode = S_IFDIR;
	    name = (char *) dotdotname;

    	} else {

	    if (! dh->entry) {

		readdir:

		res=get_direntry(overlay_readdir, &xname, &dtype, &error);

		if (res<=0) {

		    if (res==-1) {

			free(buff);
			unlock_directory(directory, _DIRECTORY_LOCK_EXCL);
			goto error;

		    }

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		xname.len=strlen(xname.name);
		calculate_nameindex(&xname);

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {

			entry->inode->mode=DTTOIF(dtype);

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		    st.st_mode=entry->inode->mode;
		    st.st_ino=entry->inode->ino;
		    name=entry->name.name;

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		dh->entry=entry;

	    } else {

		entry=dh->entry;

		st.st_ino=entry->inode->ino;
		st.st_mode=entry->inode->mode;
		name=entry->name.name;

	    }

	}

    	dirent_size=fuse_add_direntry(req, buff+pos, size-pos, name, &st, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset = offset + 1;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
Esempio n. 11
0
int
main(
    int argc, char *argv[]) 
{
    (void) argc;
    (void) argv;

    /* File type macros */
    {
        assert (DTTOIF(DT_REG) == S_IFREG);
        assert (DTTOIF(DT_DIR) == S_IFDIR);
        assert (DTTOIF(DT_FIFO) == S_IFIFO);
        assert (DTTOIF(DT_SOCK) == S_IFSOCK);
        assert (DTTOIF(DT_CHR) == S_IFCHR);
        assert (DTTOIF(DT_BLK) == S_IFBLK);

        assert (IFTODT(S_IFREG) == DT_REG);
        assert (IFTODT(S_IFDIR) == DT_DIR);
        assert (IFTODT(S_IFIFO) == DT_FIFO);
        assert (IFTODT(S_IFSOCK) == DT_SOCK);
        assert (IFTODT(S_IFCHR) == DT_CHR);
        assert (IFTODT(S_IFBLK) == DT_BLK);
    }

    /* Basic directory retrieval */
    {
        DIR *dir;
        struct dirent *ent;
        int found = 0;

        /* Open directory */
        dir = opendir ("tests/1");
        if (dir == NULL) {
            fprintf (stderr, "Directory tests not found\n");
            abort ();
        }

        /* Read entries */
        while ((ent = readdir (dir)) != NULL) {

            /* Check each file */
            if (strcmp (ent->d_name, ".") == 0) {
                /* Directory itself */
#ifdef _DIRENT_HAVE_D_TYPE
                assert (ent->d_type == DT_DIR);
#endif
#ifdef _DIRENT_HAVE_D_NAMLEN
                assert (ent->d_namlen == 1);
#endif
#ifdef _D_EXACT_NAMLEN
                assert (_D_EXACT_NAMLEN(ent) == 1);
#endif
#ifdef _D_ALLOC_NAMLEN
                assert (_D_ALLOC_NAMLEN(ent) > 1);
#endif
                found |= 1;

            } else if (strcmp (ent->d_name, "..") == 0) {
                /* Parent directory */
#ifdef _DIRENT_HAVE_D_TYPE
                assert (ent->d_type == DT_DIR);
#endif
#ifdef _DIRENT_HAVE_D_NAMLEN
                assert (ent->d_namlen == 2);
#endif
#ifdef _D_EXACT_NAMLEN
                assert (_D_EXACT_NAMLEN(ent) == 2);
#endif
#ifdef _D_ALLOC_NAMLEN
                assert (_D_ALLOC_NAMLEN(ent) > 2);
#endif
                found |= 2;

            } else if (strcmp (ent->d_name, "file") == 0) {
                /* Regular file */
#ifdef _DIRENT_HAVE_D_TYPE
                assert (ent->d_type == DT_REG);
#endif
#ifdef _DIRENT_HAVE_D_NAMLEN
                assert (ent->d_namlen == 4);
#endif
#ifdef _D_EXACT_NAMLEN
                assert (_D_EXACT_NAMLEN(ent) == 4);
#endif
#ifdef _D_ALLOC_NAMLEN
                assert (_D_ALLOC_NAMLEN(ent) > 4);
#endif
                found |= 4;

            } else if (strcmp (ent->d_name, "dir") == 0) {
                /* Just a directory */
#ifdef _DIRENT_HAVE_D_TYPE
                assert (ent->d_type == DT_DIR);
#endif
#ifdef _DIRENT_HAVE_D_NAMLEN
                assert (ent->d_namlen == 3);
#endif
#ifdef _D_EXACT_NAMLEN
                assert (_D_EXACT_NAMLEN(ent) == 3);
#endif
#ifdef _D_ALLOC_NAMLEN
                assert (_D_ALLOC_NAMLEN(ent) > 3);
#endif
                found |= 8;

            } else {
                /* Other file */
                fprintf (stderr, "Unexpected file %s\n", ent->d_name);
                abort ();
            }

        }

        /* Make sure that all files were found */
        assert (found == 0xf);

        closedir (dir);
    }

    /* Rewind of directory stream */
    {
        DIR *dir;
        struct dirent *ent;
        int found = 0;

        /* Open directory */
        dir = opendir ("tests/1");
        assert (dir != NULL);

        /* Read entries */
        while ((ent = readdir (dir)) != NULL) {

            /* Check each file */
            if (strcmp (ent->d_name, ".") == 0) {
                /* Directory itself */
                found |= 1;

            } else if (strcmp (ent->d_name, "..") == 0) {
                /* Parent directory */
                found |= 2;

            } else if (strcmp (ent->d_name, "file") == 0) {
                /* Regular file */
                found |= 4;

            } else if (strcmp (ent->d_name, "dir") == 0) {
                /* Just a directory */
                found |= 8;

            } else {
                /* Other file */
                fprintf (stderr, "Unexpected file %s\n", ent->d_name);
                abort ();
            }

        }

        /* Make sure that all files were found */
        assert (found == 0xf);

        /* Rewind stream and read entries again */
        rewinddir (dir);
        found = 0;

        /* Read entries */
        while ((ent = readdir (dir)) != NULL) {

            /* Check each file */
            if (strcmp (ent->d_name, ".") == 0) {
                /* Directory itself */
                found |= 1;

            } else if (strcmp (ent->d_name, "..") == 0) {
                /* Parent directory */
                found |= 2;

            } else if (strcmp (ent->d_name, "file") == 0) {
                /* Regular file */
                found |= 4;

            } else if (strcmp (ent->d_name, "dir") == 0) {
                /* Just a directory */
                found |= 8;

            } else {
                /* Other file */
                fprintf (stderr, "Unexpected file %s\n", ent->d_name);
                abort ();
            }

        }

        /* Make sure that all files were found */
        assert (found == 0xf);

        closedir (dir);
    }

    printf ("OK\n");
    return EXIT_SUCCESS;
}
Esempio n. 12
0
static int ufs_mkdir(uufsd_t *ufs, ino_t parent, ino_t inum, char *name)
{
	int		retval;
	struct ufs_vnode	*parent_vnode = NULL, *vnode = NULL;
	struct inode *parent_inode, *inode;
	ino_t		ino = inum;
	ino_t		scratch_ino;
	ufs2_daddr_t		blk;
	char			*block = 0;
	struct fs *fs = &ufs->d_fs;
	int dirsize = DIRBLKSIZ;
	int blocksize = fragroundup(fs, dirsize);

	parent_vnode = vnode_get(ufs, parent);
	if (!parent_vnode) {
		return ENOENT;
	}

	parent_inode = vnode2inode(parent_vnode);
	/*
	 * Allocate an inode, if necessary
	 */
	if (!ino) {
		retval = ufs_valloc(parent_vnode, DTTOIF(DT_DIR), &vnode);
		if (retval)
			goto cleanup;
		ino = vnode->inode.i_number;
		inode = vnode2inode(vnode);
	}

	/*
	 * Allocate a data block for the directory
	 */
	retval = ufs_block_alloc(ufs, inode, fragroundup(fs, dirsize), &blk);
	if (retval)
		goto cleanup;

	/*
	 * Create a scratch template for the directory
	 */
	retval = ufs_new_dir_block(ufs, vnode->inode.i_number, parent_vnode, &block);
	if (retval)
		goto cleanup;

	/*
	 * Get the parent's inode, if necessary
	if (parent != ino) {
		parent_vnode = vnode_get(ufs, parent);
		if (retval)
			goto cleanup;
	} else
		memset(&parent_inode, 0, sizeof(parent_inode));
	 */

	/*
	 * Create the inode structure....
	 */
	inode->i_mode = DT_DIR | (0777);
	inode->i_uid = inode->i_gid = 0;
	UFS_DINODE(inode)->di_db[0] = blk;
	inode->i_nlink = 1;
	inode->i_size = dirsize;

	/*
	 * Write out the inode and inode data block
	 */
	retval = blkwrite(ufs, fsbtodb(fs, blk), block, blocksize);
	if (retval == -1)
		goto cleanup;

	/*
	 * Link the directory into the filesystem hierarchy
	 */
	if (name) {
		retval = ufs_lookup(ufs, parent, name, strlen(name),
				       &scratch_ino);
		if (!retval) {
			retval = EEXIST;
			name = 0;
			goto cleanup;
		}
		if (retval != ENOENT)
			goto cleanup;
		retval = ufs_link(ufs, parent, name, vnode, DTTOIF(DT_DIR));
		if (retval)
			goto cleanup;
	}

	/*
	 * Update parent inode's counts
	 */
	if (parent != ino) {
		parent_inode->i_nlink++;
	}

cleanup:
	if (vnode)
		vnode_put(vnode, 1);

	if (parent_vnode)
		vnode_put(parent_vnode, 1);
	if (block)
		ufs_free_mem(&block);
	return retval;


}
Esempio n. 13
0
/* MyPrintDirectoryListing prints a FTP directory entry, represented by a CFDictionary 
as returned by CFFTPCreateParsedResourceListing, as a single line of text, much like 
you'd get from "ls -l". */
static void
MyPrintDirectoryListing(CFDictionaryRef dictionary)
{
    CFDateRef             cfModDate;
    CFNumberRef           cfType, cfMode, cfSize;
    CFStringRef           cfOwner, cfName, cfLink, cfGroup;
    char                  owner[256], group[256], name[256];
    char                  permString[12], link[1024];
    SInt64                size;
    SInt32                mode, type;

    assert(dictionary != NULL);

    /* You should not assume that the directory entry dictionary will contain all the possible keys.
    Most of the time it will, however, depending on the FTP server, some of the keys may be missing. */
        
    cfType = CFDictionaryGetValue(dictionary, kCFFTPResourceType);
    if (cfType) {
        assert(CFGetTypeID(cfType) == CFNumberGetTypeID());
        CFNumberGetValue(cfType, kCFNumberSInt32Type, &type);
        
        cfMode = CFDictionaryGetValue(dictionary, kCFFTPResourceMode);
        if (cfMode) {
            assert(CFGetTypeID(cfMode) == CFNumberGetTypeID());
            CFNumberGetValue(cfMode, kCFNumberSInt32Type, &mode);
            
            /* Converts inode status information into a symbolic string */
            strmode(mode + DTTOIF(type), permString);
            
            fprintf(stderr, "%s ", permString);
        }
    }
    
    cfOwner = CFDictionaryGetValue(dictionary, kCFFTPResourceOwner);
    if (cfOwner) {
        assert(CFGetTypeID(cfOwner) == CFStringGetTypeID());
        CFStringGetCString(cfOwner, owner, sizeof(owner), kCFStringEncodingASCII);
        fprintf(stderr, "%9s", owner);
    }
    
    cfGroup = CFDictionaryGetValue(dictionary, kCFFTPResourceGroup);
    if (cfGroup) {
        assert(CFGetTypeID(cfGroup) == CFStringGetTypeID());
        CFStringGetCString(cfGroup, group, sizeof(group), kCFStringEncodingASCII);
        fprintf(stderr, "%9s", group);
    }
    
    cfSize = CFDictionaryGetValue(dictionary, kCFFTPResourceSize);
    if (cfSize) {
        assert(CFGetTypeID(cfSize) == CFNumberGetTypeID());
        CFNumberGetValue(cfSize, kCFNumberSInt64Type, &size);
        fprintf(stderr, "%9lld ", size);
    }
    
    cfModDate = CFDictionaryGetValue(dictionary, kCFFTPResourceModDate);
    if (cfModDate) {
        CFLocaleRef           locale;
        CFDateFormatterRef    formatDate;
        CFDateFormatterRef    formatTime;
        CFStringRef           cfDate;
        CFStringRef           cfTime;
        char                  date[256];
        char                  time[256];

        assert(CFGetTypeID(cfModDate) == CFDateGetTypeID());

        locale = CFLocaleCopyCurrent();
        assert(locale != NULL);
        
        formatDate = CFDateFormatterCreate(kCFAllocatorDefault, locale, kCFDateFormatterShortStyle, kCFDateFormatterNoStyle   );
        assert(formatDate != NULL);

        formatTime = CFDateFormatterCreate(kCFAllocatorDefault, locale, kCFDateFormatterNoStyle,    kCFDateFormatterShortStyle);
        assert(formatTime != NULL);

        cfDate = CFDateFormatterCreateStringWithDate(kCFAllocatorDefault, formatDate, cfModDate);
        assert(cfDate != NULL);

        cfTime = CFDateFormatterCreateStringWithDate(kCFAllocatorDefault, formatTime, cfModDate);
        assert(cfTime != NULL);

        CFStringGetCString(cfDate, date, sizeof(date), kCFStringEncodingUTF8);
        CFStringGetCString(cfTime, time, sizeof(time), kCFStringEncodingUTF8);
        fprintf(stderr, "%10s %5s ", date, time);

        CFRelease(cfTime);
        CFRelease(cfDate);
        CFRelease(formatTime);
        CFRelease(formatDate);
        CFRelease(locale);
    }

    /* Note that this sample assumes UTF-8 since that's what the Mac OS X
    FTP server returns, however, some servers may use a different encoding. */
    cfName = CFDictionaryGetValue(dictionary, kCFFTPResourceName);
    if (cfName) {
        assert(CFGetTypeID(cfName) == CFStringGetTypeID());
        CFStringGetCString(cfName, name, sizeof(name), kCFStringEncodingUTF8);
        fprintf(stderr, "%s", name);

        cfLink = CFDictionaryGetValue(dictionary, kCFFTPResourceLink);
        if (cfLink) {
            assert(CFGetTypeID(cfLink) == CFStringGetTypeID());
            CFStringGetCString(cfLink, link, sizeof(link), kCFStringEncodingUTF8);
            if (strlen(link) > 0) fprintf(stderr, " -> %s", link);
        }
    }

    fprintf(stderr, "\n");
}
Esempio n. 14
0
enum dir_visit_next_op
dir_search_i(
    dir_visitor_t visitor, void * ctx,
    int maxLevel,
    error_monitor_t em,
    mem_buffer_t buffer)
{
    DIR * dirp;
    struct dirent dbuf;
    struct dirent * dp;
    char * path;
    int rv;
    size_t bufSize;
    enum dir_visit_next_op nextOp;

    if (maxLevel == 0) return dir_visit_next_go;

    path = (char *)mem_buffer_make_continuous(buffer, 0);
    bufSize = mem_buffer_size(buffer);

    dirp = dir_open(path, 0, em);
    if (dirp == NULL) return dir_visit_next_go;

    nextOp = dir_visit_next_go;

    while((rv = readdir_r(dirp, &dbuf, &dp)) == 0 && dp) {
        if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue;

        if (
            mem_buffer_strcat(buffer, "/") != 0 || 
            mem_buffer_strcat(buffer, dp->d_name) != 0) break;

        if (S_ISDIR(DTTOIF(dp->d_type))) {
            if (visitor->on_dir_enter) {
                nextOp = visitor->on_dir_enter(
                    (const char *)mem_buffer_make_continuous(buffer, 0),
                    dp->d_name,
                    ctx);

                if (nextOp == dir_visit_next_exit) break;
            }
            else {
                nextOp = dir_visit_next_go;
            }

            if (nextOp == dir_visit_next_go) {
                nextOp = dir_search_i(
                    visitor, ctx,
                    maxLevel > 0 ? maxLevel - 1 : maxLevel,
                    em, buffer);

                if (nextOp == dir_visit_next_exit) break;
            }

            if (visitor->on_dir_leave) {
                nextOp = visitor->on_dir_leave(
                    (const char *)mem_buffer_make_continuous(buffer, 0),
                    dp->d_name,
                    ctx);

                if (nextOp == dir_visit_next_exit) break;
            }
        }
        else if (S_ISREG(DTTOIF(dp->d_type))) {
            if (visitor->on_file) {
                nextOp = visitor->on_file(
                    (const char *)mem_buffer_make_continuous(buffer, 0),
                    dp->d_name,
                    ctx);

                if (nextOp == dir_visit_next_exit) break;
            }
        }

        /*restore curent path*/
        mem_buffer_set_size(buffer, bufSize);
        path = (char *)mem_buffer_make_continuous(buffer, 0);
        if (path == NULL) {
            CPE_ERROR_EX(em, ENOMEM, "no memory for dir search path");
            nextOp = dir_visit_next_exit;
            break;
        }
        path[bufSize - 1] = 0;

    }

    /*clear resources*/
    dir_close(dirp, em);

    return nextOp == dir_visit_next_exit ?  dir_visit_next_exit : dir_visit_next_go;
}