Ejemplo n.º 1
0
int find_path(xfs_mount_t *mp, const char *path, xfs_inode_t **result) {
    xfs_inode_t *current;
    xfs_ino_t inode;
    struct xfs_name xname;
    int error;
   
    error = libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &current, 0);
    assert(error==0);
    
    xname = first_name(path);
    while (xname.len != 0) {
        if (!(current->i_d.di_mode & S_IFDIR)) {
            libxfs_iput(current, 0);
            return XFS_ERROR(ENOTDIR);
        }
        
        error = libxfs_dir_lookup(NULL, current, &xname, &inode, NULL);
        if (error != 0) {
            return error;
        }

        /* Done with current: make it available */
        libxfs_iput(current, 0);

        error = libxfs_iget(mp, NULL, inode, 0, &current, 0);
        if (error != 0) {
            printf("Failed to get inode for %s %d\n", xname.name, xname.len);
            return XFS_ERROR(EIO);
        }
        xname = next_name(xname);
    }
    *result = current;
    return 0;
}
Ejemplo n.º 2
0
int copy_filldir(void *dirents, const char *name, int namelen, off_t offset, uint64_t inumber, unsigned flags) {
    char dname[256];
    char lname[256];
    int r;
    xfs_inode_t *inode=NULL;
    struct stat fstats;
    char mode[]="rwxrwxrwx";
    int tests[]={S_IRUSR,S_IWUSR,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,S_IWOTH,S_IXOTH};

    struct filldir_data *data = (struct filldir_data *) dirents;

    strcpy(dname, data->base);
    strcat(dname, "/");
    strncat(dname, name, namelen);

    strcpy(lname, data->local);
    strcat(lname, "/");
    strncat(lname, name, namelen);

    r = libxfs_iget(data->mp, NULL, inumber, 0, &inode, 0);
    if (r) printf("Panic! %d\n", r);
    r = xfs_stat(inode, &fstats);
    if (r) printf("Panic! stats %d\n", r);
    if (xfs_is_dir(inode)) {
        printf("d");
    } else if (xfs_is_link(inode)) {
        printf("l");
    } else printf("-");

    for (r=0; r<9; r++) {
        if (fstats.st_mode & tests[r]) {
            printf("%c", mode[r]);
        } else {
            printf("-");
        }
    }
    
    printf(" %s -> %s\n", dname, lname);
    if (strncmp(name, ".", namelen) == 0)
        libxfs_iput(inode, 0);
    else if (strncmp(name, "..", namelen) == 0)
        libxfs_iput(inode, 0);
    else {
        copy_tree(data->mp, dname, lname, inode);
        libxfs_iput(inode, 0);
    }
    return 0;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[]) {
    xfs_mount_t	*mp;
    xfs_inode_t *inode = NULL;
    char *progname;
    char *source_name;
    char *parent;
    int r;

    if (argc != 3) {
        printf("Usage: xfs-rcopy raw_device directory\n");
        printf("Copies the named directory from an XFS file system to the current directory\n");
        return 1;
    }
    progname = argv[0];
    source_name = argv[1];
    parent = argv[2];
    
    mp = mount_xfs(progname, source_name);
    
    if (mp == NULL) 
        return 1;
    
    r = find_path(mp, parent, &inode);
    if (r) {
        printf("Can't find %s\n", parent);
        libxfs_umount(mp);
        return 1;
    }

    copy_tree(mp, parent, last(parent), inode);
    libxfs_iput(inode, 0);
    libxfs_umount(mp);
    return 0;
}
Ejemplo n.º 4
0
int fuse_xfs_opendir(const char *path, struct fuse_file_info *fi) {
    int r;
    xfs_inode_t *inode=NULL;
    log_debug("opendir %s\n", path); 
    
    r = find_path(current_xfs_mount(), path, &inode);
    if (r) {
        return -ENOENT;
    }
    
    libxfs_iput(inode, 0);
    return 0;
}
Ejemplo n.º 5
0
int cli_ls_xfs_filldir(void *dirents, const char *name, int namelen, off_t offset, uint64_t inumber, unsigned flags) {
    char dname[256];
    char symlink[256];
    int r;
    xfs_inode_t *inode=NULL;
    struct stat fstats;
    char mode[]="rwxrwxrwx";
    int tests[]={S_IRUSR,S_IWUSR,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,S_IWOTH,S_IXOTH};

    struct filldir_data *data = (struct filldir_data *) dirents;
    memcpy(dname, name, namelen);
    dname[namelen] = '\0';
    r = libxfs_iget(data->mp, NULL, inumber, 0, &inode, 0);
    if (r) printf("Panic! %d\n", r);
    r = xfs_stat(inode, &fstats);
    if (r) printf("Panic! stats %d\n", r);
    if (xfs_is_dir(inode)) {
        printf("d");
    } else if (xfs_is_link(inode)) {
        printf("l");
    } else printf("-");

    for (r=0; r<9; r++) {
        if (fstats.st_mode & tests[r]) {
            printf("%c", mode[r]);
        } else {
            printf("-");
        }
    }
    
    print_int(fstats.st_uid, 6);
    print_int(fstats.st_gid, 6);
    print_int(fstats.st_size, 12);
    
    printf(" %s", dname);
    if (xfs_is_link(inode)) {
        r = xfs_readlink(inode, symlink, 0, 255, NULL);
        if (r > 0) {
            symlink[r] = '\0';
            printf("->%s", symlink);
        }
    }
    printf("\n");
    libxfs_iput(inode, 0);
    return 0;
}
Ejemplo n.º 6
0
static int fuse_xfs_readdir(const char *path, void *buf, //fuse_fill_dir_t filler,
                 off_t offset, struct fuse_file_info *fi) {
    log_debug("readdir %s\n", path);
    int r;
    struct filler_info_struct filler_info;
    xfs_inode_t *inode=NULL;
    
    r = find_path(current_xfs_mount(), path, &inode);
    if (r) {
        return -ENOENT;
    }
    
    filler_info.buf = buf;
    //filler_info.filler = filler;
    xfs_readdir(inode, (void *)&filler_info, 1024000, &offset, fuse_xfs_filldir);
    libxfs_iput(inode, 0);
    return 0;
}
Ejemplo n.º 7
0
static int
fuse_xfs_readlink(const char *path, char *buf, size_t size) {
    int r;
    xfs_inode_t *inode=NULL;

    log_debug("readlink %s\n", path); 
    
    r = find_path(current_xfs_mount(), path, &inode);
    if (r) {
        return -ENOENT;
    }
    
    r = xfs_readlink(inode, buf, 0, size, NULL);
    if (r < 0) {
        return r;
    }
    libxfs_iput(inode, 0);
    return 0;
}
Ejemplo n.º 8
0
char *fetchline(xfs_mount_t *mp, char *path) {
    xfs_inode_t *inode;
    xfs_off_t ofs = 0;
    char *line;
    int r;

    free_completions();
    r = find_path(mp, path, &inode);
    if (r == 0) {
        r = xfs_readdir(inode, NULL, 102400, &ofs, cli_complete_xfs_filldir);
        libxfs_iput(inode, 0);
    }

    rl_completion_entry_function = (Function *)dir_generator;
    rl_bind_key('\t', rl_complete);
    line = readline(get_prompt(path));
    if (line && *line)
        add_history(line);
    return line;
}
Ejemplo n.º 9
0
int fuse_xfs_filldir(void *filler_info, const char *name, int namelen, off_t offset, uint64_t inumber, unsigned flags) {
    int r;
    char dir_entry[256];
    xfs_inode_t *inode=NULL;    
    struct stat stbuf;
    struct stat *stats = NULL;
    struct filler_info_struct *filler_data = (struct filler_info_struct *) filler_info;
    
    memcpy(dir_entry, name, namelen);
    dir_entry[namelen] = '\0';
    if (libxfs_iget(current_xfs_mount(), NULL, inumber, 0, &inode, 0)) {
        return 0;
    }
    if (!xfs_stat(inode, &stbuf)) {
        stats = &stbuf;
    }
    log_debug("Direntry %s\n", dir_entry);
    r = filler_data->filler(filler_data->buf, dir_entry, stats, 0);
    libxfs_iput(inode, 0);
    return r;
}
Ejemplo n.º 10
0
static int
fuse_xfs_release(const char *path, struct fuse_file_info *fi) {
    log_debug("release %s\n", path); 
    libxfs_iput((xfs_inode_t *)fi->fh, 0);
    return 0;
}
Ejemplo n.º 11
0
static void
parseproto(
	xfs_mount_t	*mp,
	xfs_inode_t	*pip,
	struct fsxattr	*fsxp,
	char		**pp,
	char		*name)
{
#define	IF_REGULAR	0
#define	IF_RESERVED	1
#define	IF_BLOCK	2
#define	IF_CHAR		3
#define	IF_DIRECTORY	4
#define	IF_SYMLINK	5
#define	IF_FIFO		6

	char		*buf;
	int		committed;
	int		error;
	xfs_fsblock_t	first;
	int		flags;
	xfs_bmap_free_t	flist;
	int		fmt;
	int		i;
	xfs_inode_t	*ip;
	int		len;
	long long	llen;
	int		majdev;
	int		mindev;
	int		mode;
	char		*mstr;
	xfs_trans_t	*tp;
	int		val;
	int		isroot = 0;
	cred_t		creds;
	char		*value;
	struct xfs_name	xname;

	memset(&creds, 0, sizeof(creds));
	mstr = getstr(pp);
	switch (mstr[0]) {
	case '-':
		fmt = IF_REGULAR;
		break;
	case 'r':
		fmt = IF_RESERVED;
		break;
	case 'b':
		fmt = IF_BLOCK;
		break;
	case 'c':
		fmt = IF_CHAR;
		break;
	case 'd':
		fmt = IF_DIRECTORY;
		break;
	case 'l':
		fmt = IF_SYMLINK;
		break;
	case 'p':
		fmt = IF_FIFO;
		break;
	default:
		fprintf(stderr, _("%s: bad format string %s\n"),
			progname, mstr);
		exit(1);
	}
	mode = 0;
	switch (mstr[1]) {
	case '-':
		break;
	case 'u':
		mode |= S_ISUID;
		break;
	default:
		fprintf(stderr, _("%s: bad format string %s\n"),
			progname, mstr);
		exit(1);
	}
	switch (mstr[2]) {
	case '-':
		break;
	case 'g':
		mode |= S_ISGID;
		break;
	default:
		fprintf(stderr, _("%s: bad format string %s\n"),
			progname, mstr);
		exit(1);
	}
	val = 0;
	for (i = 3; i < 6; i++) {
		if (mstr[i] < '0' || mstr[i] > '7') {
			fprintf(stderr, _("%s: bad format string %s\n"),
				progname, mstr);
			exit(1);
		}
		val = val * 8 + mstr[i] - '0';
	}
	mode |= val;
	creds.cr_uid = (int)getnum(pp);
	creds.cr_gid = (int)getnum(pp);
	xname.name = (uchar_t *)name;
	xname.len = name ? strlen(name) : 0;
	tp = libxfs_trans_alloc(mp, 0);
	flags = XFS_ILOG_CORE;
	xfs_bmap_init(&flist, &first);
	switch (fmt) {
	case IF_REGULAR:
		buf = newregfile(pp, &len);
		getres(tp, XFS_B_TO_FSB(mp, len));
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
					   &creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		flags |= newfile(tp, ip, &flist, &first, 0, 0, buf, len);
		if (buf)
			free(buf);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		break;

	case IF_RESERVED:			/* pre-allocated space only */
		value = getstr(pp);
		llen = cvtnum(mp->m_sb.sb_blocksize, mp->m_sb.sb_sectsize, value);
		getres(tp, XFS_B_TO_FSB(mp, llen));

		error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
					  &creds, fsxp, &ip);
		if (error)
			fail(_("Inode pre-allocation failed"), error);

		libxfs_trans_ijoin(tp, pip, 0);

		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		libxfs_trans_log_inode(tp, ip, flags);

		error = libxfs_bmap_finish(&tp, &flist, &committed);
		if (error)
			fail(_("Pre-allocated file creation failed"), error);
		libxfs_trans_commit(tp, 0);
		rsvfile(mp, ip, llen);
		return;

	case IF_BLOCK:
		getres(tp, 0);
		majdev = (int)getnum(pp);
		mindev = (int)getnum(pp);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFBLK, 1,
				IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
		if (error) {
			fail(_("Inode allocation failed"), error);
		}
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		flags |= XFS_ILOG_DEV;
		break;

	case IF_CHAR:
		getres(tp, 0);
		majdev = (int)getnum(pp);
		mindev = (int)getnum(pp);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFCHR, 1,
				IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		flags |= XFS_ILOG_DEV;
		break;

	case IF_FIFO:
		getres(tp, 0);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFIFO, 1, 0,
				&creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		break;
	case IF_SYMLINK:
		buf = getstr(pp);
		len = (int)strlen(buf);
		getres(tp, XFS_B_TO_FSB(mp, len));
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFLNK, 1, 0,
				&creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		flags |= newfile(tp, ip, &flist, &first, 1, 1, buf, len);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		break;
	case IF_DIRECTORY:
		getres(tp, 0);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFDIR, 1, 0,
				&creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		ip->i_d.di_nlink++;		/* account for . */
		if (!pip) {
			pip = ip;
			mp->m_sb.sb_rootino = ip->i_ino;
			libxfs_mod_sb(tp, XFS_SB_ROOTINO);
			mp->m_rootip = ip;
			isroot = 1;
		} else {
			libxfs_trans_ijoin(tp, pip, 0);
			newdirent(mp, tp, pip, &xname, ip->i_ino,
				  &first, &flist, 1);
			pip->i_d.di_nlink++;
			libxfs_trans_ihold(tp, pip);
			libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
		}
		newdirectory(mp, tp, ip, pip);
		libxfs_trans_log_inode(tp, ip, flags);
		error = libxfs_bmap_finish(&tp, &flist, &committed);
		if (error)
			fail(_("Directory creation failed"), error);
		libxfs_trans_ihold(tp, ip);
		libxfs_trans_commit(tp, 0);
		/*
		 * RT initialization.  Do this here to ensure that
		 * the RT inodes get placed after the root inode.
		 */
		if (isroot)
			rtinit(mp);
		tp = NULL;
		for (;;) {
			name = getstr(pp);
			if (!name)
				break;
			if (strcmp(name, "$") == 0)
				break;
			parseproto(mp, ip, fsxp, pp, name);
		}
		libxfs_iput(ip, 0);
		return;
	}
	libxfs_trans_log_inode(tp, ip, flags);
	error = libxfs_bmap_finish(&tp, &flist, &committed);
	if (error) {
		fail(_("Error encountered creating file from prototype file"),
			error);
	}
	libxfs_trans_commit(tp, 0);
}
Ejemplo n.º 12
0
int main(int argc, char *argv[]) {
    xfs_mount_t	*mp;
    xfs_inode_t *inode = NULL;
    xfs_off_t ofs;
    struct filldir_data filldata;
    char *progname;
    char *source_name;
    int r, fd;
    char *line;
    char path[FILENAME_MAX] = "/";
    char newpath[FILENAME_MAX] = "/";
    char *buffer[BUFSIZE];
    off_t offset;

    if (argc != 2) {
        printf("Usage: xfs-cli raw_device\n");
        return 1;
    }
    progname = argv[0];
    source_name = argv[1];
    
    mp = mount_xfs(progname, source_name);
    
    if (mp == NULL) 
        return 1;
    
    while (line == fetchline(mp, path)) {
        inode = NULL;
        strip(line, ' ');
        if (strncmp(line, "cd ", 3) == 0) {
            if (strcmp(line+3, "..") == 0) {
                goto_parent(path);
            } else {
                strcpy(newpath, path);
                strcat(newpath, line+3);
                r = find_path(mp, newpath, &inode);
                if ((!r) && (xfs_is_dir(inode))) {
                    //TODO: check if it is a directory
                    strcpy(path, newpath);
                    strcat(path, "/");
                    printf("%s\n", path);
                } else {
                    if (r) {
                        printf("No such directory\n");
                    } else {
                        printf("Not a directory\n");
                    }
                }
            }
        }
        else if (strcmp(line, "ls") == 0) {
            r = find_path(mp, path, &inode);
            if (!r) {
                //TODO: check if it is a directory
                ofs=0;
                filldata.mp = mp;
                filldata.base = inode;
                r = xfs_readdir(inode, (void *)&filldata, 102400, &ofs, cli_ls_xfs_filldir);
                if (r != 0) {
                    printf("Not a directory\n");
                }
            } else {
                printf("No such directory\n");
            }
        }
        else if (strncmp(line, "cat ", 4) == 0) {
            strcpy(newpath, path);
            strcat(newpath, line+4);
            r = find_path(mp, newpath, &inode);
            if (r)
                printf("File not found\n");
            else if (xfs_is_regular(inode)) {
                //TODO: check if it is a file
                r = 10;
                offset = 0;
                while (r) {
                    r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL);
                    if (r) {
                        write(1, buffer, r);
                        offset += r;
                    }
                }
            } else if (xfs_is_link(inode)) {
                r = 10;
                offset = 0;
                while (r) {
                    r = xfs_readlink(inode, buffer, offset, BUFSIZE, NULL);
                    if (r) {
                        write(1, buffer, r);
                        offset += r;
                    }
                }
            } else {
                printf("Not a regular file\n");
            }
        }
        else if (strncmp(line, "get ", 4) == 0) {
            strcpy(newpath, path);
            strcat(newpath, line+4);
            r = find_path(mp, newpath, &inode);
            if ((!r) && (xfs_is_regular(inode))) {
                //TODO: check if it is a file
                r = 10;
                offset = 0;
                fd = open(line+4, O_WRONLY|O_CREAT, 0660);
                if (fd < 0) {
                    printf("Failed to open local file\n");
                } else {
                    while (r) {
                        r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL);
                        if (r) {
                            write(fd, buffer, r);
                            offset += r;
                        }
                    }
                    close(fd);
                    printf("Retrieved %ld bytes\n", offset);
                }
            } else {
                if (r) 
                    printf("File not found\n");
                else
                    printf("Not a regular file\n");
            }
        }
        else if (strcmp(line, "exit") == 0) {
            libxfs_umount(mp);
            return 0;
        }
        else if (strcmp(line, "pwd") == 0) {
            printf("%s\n", path);
        } else {
            printf("Unknown command\n");
        }
        free(line);
        if (inode) {
            libxfs_iput(inode, 0);
        }
    }
    libxfs_umount(mp);
    return 0;
}