#include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd, fd1, fd2, i; char buf[512], *cp; ssize_t siz; off_t offs; struct dirent *dp; long named_enabled; fhandle_t fh; if (argc != 2) errx(1, "Usage: xattrtest2 "); if (getuid() != 0) errx(1, "Must be run as root"); named_enabled = pathconf(argv[1], _PC_NAMEDATTR_ENABLED); if (named_enabled <= 0) err(1, "Named attributes not enabled"); fd1 = open(argv[1], O_RDONLY, 0); if (fd1 < 0) err(1, "can't open %s", argv[1]); fd = openat(fd1, ".", O_NAMEDATTR, 0); if (fd < 0) err(1, "can't open named attr dir for %s", argv[1]); printf("Open xattr successful\n"); siz = getdents(fd, buf, 512); if (siz < 0) err(1, "Cannot getdents"); cp = buf; while (cp < &buf[siz]) { dp = (struct dirent *)cp; printf("name=%s ino=%ld\n", dp->d_name, dp->d_ino); cp += dp->d_reclen; } if (getfhat(fd, ".", &fh, AT_RESOLVE_BENEATH) < 0) err(1, "Cannot getfh ."); printf("Getfh . len=%d ", fh.fh_fid.fid_len); for (i = 0; i < MAXFIDSZ; i++) printf("0x%x ", fh.fh_fid.fid_data[i]); printf("\n"); fd2 = fhopen(&fh, O_RDONLY | O_NAMEDATTR); if (fd2 < 0) err(1, "Cannot open . fh"); close(fd2); fd2 = openat(fd1, "def", O_CREAT | O_RDWR | O_NAMEDATTR, 0600); if (fd2 < 0) err(1, "can't openat def"); siz = write(fd2, "xxxyyy", 6); if (siz != 6) err(1, "can't write xxxyyy"); offs = lseek(fd2, 0, SEEK_SET); if (offs != 0) err(1, "Can't lseek %ld", offs); siz = read(fd2, buf, 512); if (siz != 6) err(1, "Can't read xxxyyy"); buf[6] = '\0'; printf("got=%s\n", buf); close(fd2); if (getfhat(fd, "def", &fh, AT_RESOLVE_BENEATH) < 0) err(1, "cannot getfh def"); printf("Getfh def len=%d ", fh.fh_fid.fid_len); for (i = 0; i < MAXFIDSZ; i++) printf("0x%x ", fh.fh_fid.fid_data[i]); printf("\n"); fd2 = fhopen(&fh, O_RDONLY | O_NAMEDATTR); if (fd2 < 0) err(1, "Cannot open def fh"); siz = read(fd2, buf, 512); if (siz != 6) err(1, "Can't read xxxyyy"); buf[6] = '\0'; printf("fhopen got=%s\n", buf); if (linkat(fd, "def", fd, "aaa", 0) >= 0) err(1, "link succeeded"); if (mkdirat(fd, "subdir", 0777) >= 0) err(1, "mkdir succeeded"); if (symlinkat("mysym", fd, "def") >= 0) err(1, "symlinkat succeeded"); if (renameat(fd, "def", fd, "abc") < 0) err(1, "Cannot rename def to abc"); printf("Renamed def to abc\n"); fd2 = openat(fd1, "abc", O_RDWR | O_NAMEDATTR); if (fd2 < 0) err(1, "Cannot open abc"); printf("Did openat of abc\n"); close(fd2); if (unlinkat(fd, "abc", 0) < 0) err(1, "Cannot unlink abc"); printf("Unlinked abc\n"); fd2 = openat(fd1, "abc", O_RDWR | O_NAMEDATTR); if (fd2 >= 0) err(1, "opened abc after unlink"); printf("Open of abc failed as it should\n"); offs = lseek(fd, 0, SEEK_SET); if (offs != 0) err(1, "Can't lseek %ld", offs); siz = getdents(fd, buf, 512); if (siz < 0) err(1, "Cannot getdents"); cp = buf; while (cp < &buf[siz]) { dp = (struct dirent *)cp; printf("name=%s\n", dp->d_name); cp += dp->d_reclen; } }