1e802abbdSTim Haley /* 2e802abbdSTim Haley * CDDL HEADER START 3e802abbdSTim Haley * 4e802abbdSTim Haley * The contents of this file are subject to the terms of the 5e802abbdSTim Haley * Common Development and Distribution License (the "License"). 6e802abbdSTim Haley * You may not use this file except in compliance with the License. 7e802abbdSTim Haley * 8e802abbdSTim Haley * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9e802abbdSTim Haley * or http://www.opensolaris.org/os/licensing. 10e802abbdSTim Haley * See the License for the specific language governing permissions 11e802abbdSTim Haley * and limitations under the License. 12e802abbdSTim Haley * 13e802abbdSTim Haley * When distributing Covered Code, include this CDDL HEADER in each 14e802abbdSTim Haley * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15e802abbdSTim Haley * If applicable, add the following below this CDDL HEADER, with the 16e802abbdSTim Haley * fields enclosed by brackets "[]" replaced with your own identifying 17e802abbdSTim Haley * information: Portions Copyright [yyyy] [name of copyright owner] 18e802abbdSTim Haley * 19e802abbdSTim Haley * CDDL HEADER END 20e802abbdSTim Haley */ 21e802abbdSTim Haley 22e802abbdSTim Haley /* 23*6a45aeb4STim Haley * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24e802abbdSTim Haley */ 25e802abbdSTim Haley 26e802abbdSTim Haley /* 27e802abbdSTim Haley * This is a test program that uses ioctls to the ZFS Unit Test driver 28e802abbdSTim Haley * to perform readdirs or lookups using flags not normally available 29e802abbdSTim Haley * to user-land programs. This allows testing of the flags' 30e802abbdSTim Haley * behavior outside of a complicated consumer, such as the SMB driver. 31e802abbdSTim Haley */ 32e802abbdSTim Haley 33e802abbdSTim Haley #include <stdio.h> 34e802abbdSTim Haley #include <stdlib.h> 35e802abbdSTim Haley #include <unistd.h> 36e802abbdSTim Haley #include <stropts.h> 37e802abbdSTim Haley #include <errno.h> 38e802abbdSTim Haley #include <sys/stat.h> 39e802abbdSTim Haley #include <sys/types.h> 40e802abbdSTim Haley #include <sys/dirent.h> 41e802abbdSTim Haley #include <sys/attr.h> 42e802abbdSTim Haley #include <stddef.h> 43e802abbdSTim Haley #include <fcntl.h> 44e802abbdSTim Haley #include <string.h> 45e802abbdSTim Haley #include <time.h> 46e802abbdSTim Haley 47e802abbdSTim Haley #define _KERNEL 48e802abbdSTim Haley 49e802abbdSTim Haley #include <sys/fs/zut.h> 50e802abbdSTim Haley #include <sys/extdirent.h> 51e802abbdSTim Haley 52e802abbdSTim Haley #undef _KERNEL 53e802abbdSTim Haley 54e802abbdSTim Haley #define MAXBUF (64 * 1024) 55e802abbdSTim Haley #define BIGBUF 4096 56*6a45aeb4STim Haley #define LILBUF (sizeof (dirent_t)) 57e802abbdSTim Haley 58e802abbdSTim Haley #define DIRENT_NAMELEN(reclen) \ 59e802abbdSTim Haley ((reclen) - (offsetof(dirent_t, d_name[0]))) 60e802abbdSTim Haley 61e802abbdSTim Haley static void 62e802abbdSTim Haley usage(char *pnam) 63e802abbdSTim Haley { 64e802abbdSTim Haley (void) fprintf(stderr, "Usage:\n %s -l [-is] dir-to-look-in " 65e802abbdSTim Haley "file-in-dir [xfile-on-file]\n", pnam); 66e802abbdSTim Haley (void) fprintf(stderr, " %s -i [-ls] dir-to-look-in " 67e802abbdSTim Haley "file-in-dir [xfile-on-file]\n", pnam); 68e802abbdSTim Haley (void) fprintf(stderr, " %s -s [-il] dir-to-look-in " 69e802abbdSTim Haley "file-in-dir [xfile-on-file]\n", pnam); 70e802abbdSTim Haley (void) fprintf(stderr, "\t Perform a lookup\n"); 71e802abbdSTim Haley (void) fprintf(stderr, "\t -l == lookup\n"); 72e802abbdSTim Haley (void) fprintf(stderr, "\t -i == request FIGNORECASE\n"); 73e802abbdSTim Haley (void) fprintf(stderr, "\t -s == request stat(2) and xvattr info\n"); 74e802abbdSTim Haley (void) fprintf(stderr, " %s -r [-ea] [-b buffer-size-in-bytes] " 75e802abbdSTim Haley "dir-to-look-in [file-in-dir]\n", pnam); 76e802abbdSTim Haley (void) fprintf(stderr, " %s -e [-ra] [-b buffer-size-in-bytes] " 77e802abbdSTim Haley "dir-to-look-in [file-in-dir]\n", pnam); 78e802abbdSTim Haley (void) fprintf(stderr, " %s -a [-re] [-b buffer-size-in-bytes] " 79e802abbdSTim Haley "dir-to-look-in [file-in-dir]\n", pnam); 80e802abbdSTim Haley (void) fprintf(stderr, "\t Perform a readdir\n"); 81e802abbdSTim Haley (void) fprintf(stderr, "\t -r == readdir\n"); 82e802abbdSTim Haley (void) fprintf(stderr, "\t -e == request extended entries\n"); 83e802abbdSTim Haley (void) fprintf(stderr, "\t -a == request access filtering\n"); 84e802abbdSTim Haley (void) fprintf(stderr, "\t -b == buffer size (default 4K)\n"); 85e802abbdSTim Haley (void) fprintf(stderr, " %s -A path\n", pnam); 86e802abbdSTim Haley (void) fprintf(stderr, "\t Look up _PC_ACCESS_FILTERING " 87e802abbdSTim Haley "for path with pathconf(2)\n"); 88e802abbdSTim Haley (void) fprintf(stderr, " %s -E path\n", pnam); 89e802abbdSTim Haley (void) fprintf(stderr, "\t Look up _PC_SATTR_EXISTS " 90e802abbdSTim Haley "for path with pathconf(2)\n"); 91e802abbdSTim Haley (void) fprintf(stderr, " %s -S path\n", pnam); 92e802abbdSTim Haley (void) fprintf(stderr, "\t Look up _PC_SATTR_EXISTS " 93e802abbdSTim Haley "for path with pathconf(2)\n"); 94e802abbdSTim Haley exit(EINVAL); 95e802abbdSTim Haley } 96e802abbdSTim Haley 97e802abbdSTim Haley static void 98e802abbdSTim Haley print_extd_entries(zut_readdir_t *r) 99e802abbdSTim Haley { 100e802abbdSTim Haley struct edirent *eodp; 101e802abbdSTim Haley char *bufstart; 102e802abbdSTim Haley 103e802abbdSTim Haley eodp = (edirent_t *)(uintptr_t)r->zr_buf; 104e802abbdSTim Haley bufstart = (char *)eodp; 105e802abbdSTim Haley while ((char *)eodp < bufstart + r->zr_bytes) { 106e802abbdSTim Haley char *blanks = " "; 107e802abbdSTim Haley int i = 0; 108e802abbdSTim Haley while (i < EDIRENT_NAMELEN(eodp->ed_reclen)) { 109e802abbdSTim Haley if (!eodp->ed_name[i]) 110e802abbdSTim Haley break; 111e802abbdSTim Haley (void) printf("%c", eodp->ed_name[i++]); 112e802abbdSTim Haley } 113e802abbdSTim Haley if (i < 16) 114e802abbdSTim Haley (void) printf("%.*s", 16 - i, blanks); 115e802abbdSTim Haley (void) printf("\t%x\n", eodp->ed_eflags); 116e802abbdSTim Haley eodp = (edirent_t *)((intptr_t)eodp + eodp->ed_reclen); 117e802abbdSTim Haley } 118e802abbdSTim Haley } 119e802abbdSTim Haley 120e802abbdSTim Haley static void 121e802abbdSTim Haley print_entries(zut_readdir_t *r) 122e802abbdSTim Haley { 123e802abbdSTim Haley dirent64_t *dp; 124e802abbdSTim Haley char *bufstart; 125e802abbdSTim Haley 126c5c8461eSTim Haley dp = (dirent64_t *)(intptr_t)r->zr_buf; 127e802abbdSTim Haley bufstart = (char *)dp; 128e802abbdSTim Haley while ((char *)dp < bufstart + r->zr_bytes) { 129e802abbdSTim Haley int i = 0; 130e802abbdSTim Haley while (i < DIRENT_NAMELEN(dp->d_reclen)) { 131e802abbdSTim Haley if (!dp->d_name[i]) 132e802abbdSTim Haley break; 133e802abbdSTim Haley (void) printf("%c", dp->d_name[i++]); 134e802abbdSTim Haley } 135e802abbdSTim Haley (void) printf("\n"); 136e802abbdSTim Haley dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen); 137e802abbdSTim Haley } 138e802abbdSTim Haley } 139e802abbdSTim Haley 140e802abbdSTim Haley static void 141e802abbdSTim Haley print_stats(struct stat64 *sb) 142e802abbdSTim Haley { 143e802abbdSTim Haley char timebuf[512]; 144e802abbdSTim Haley 145e802abbdSTim Haley (void) printf("st_mode\t\t\t%04lo\n", (unsigned long)sb->st_mode); 146e802abbdSTim Haley (void) printf("st_ino\t\t\t%llu\n", (unsigned long long)sb->st_ino); 147e802abbdSTim Haley (void) printf("st_nlink\t\t%lu\n", (unsigned long)sb->st_nlink); 148e802abbdSTim Haley (void) printf("st_uid\t\t\t%d\n", sb->st_uid); 149e802abbdSTim Haley (void) printf("st_gid\t\t\t%d\n", sb->st_gid); 150e802abbdSTim Haley (void) printf("st_size\t\t\t%lld\n", (long long)sb->st_size); 151e802abbdSTim Haley (void) printf("st_blksize\t\t%ld\n", (long)sb->st_blksize); 152e802abbdSTim Haley (void) printf("st_blocks\t\t%lld\n", (long long)sb->st_blocks); 153e802abbdSTim Haley 154e802abbdSTim Haley timebuf[0] = 0; 155e802abbdSTim Haley if (ctime_r(&sb->st_atime, timebuf, 512)) { 156e802abbdSTim Haley (void) printf("st_atime\t\t"); 157e802abbdSTim Haley (void) printf("%s", timebuf); 158e802abbdSTim Haley } 159e802abbdSTim Haley timebuf[0] = 0; 160e802abbdSTim Haley if (ctime_r(&sb->st_mtime, timebuf, 512)) { 161e802abbdSTim Haley (void) printf("st_mtime\t\t"); 162e802abbdSTim Haley (void) printf("%s", timebuf); 163e802abbdSTim Haley } 164e802abbdSTim Haley timebuf[0] = 0; 165e802abbdSTim Haley if (ctime_r(&sb->st_ctime, timebuf, 512)) { 166e802abbdSTim Haley (void) printf("st_ctime\t\t"); 167e802abbdSTim Haley (void) printf("%s", timebuf); 168e802abbdSTim Haley } 169e802abbdSTim Haley } 170e802abbdSTim Haley 171e802abbdSTim Haley static void 172e802abbdSTim Haley print_xvs(uint64_t xvs) 173e802abbdSTim Haley { 174e802abbdSTim Haley uint_t bits; 175e802abbdSTim Haley int idx = 0; 176e802abbdSTim Haley 177e802abbdSTim Haley if (xvs == 0) 178e802abbdSTim Haley return; 179e802abbdSTim Haley 180e802abbdSTim Haley (void) printf("-------------------\n"); 181e802abbdSTim Haley (void) printf("Attribute bit(s) set:\n"); 182e802abbdSTim Haley (void) printf("-------------------\n"); 183e802abbdSTim Haley 184e802abbdSTim Haley bits = xvs & ((1 << F_ATTR_ALL) - 1); 185e802abbdSTim Haley while (bits) { 186e802abbdSTim Haley uint_t rest = bits >> 1; 187e802abbdSTim Haley if (bits & 1) { 188e802abbdSTim Haley (void) printf("%s", attr_to_name((f_attr_t)idx)); 189e802abbdSTim Haley if (rest) 190e802abbdSTim Haley (void) printf(", "); 191e802abbdSTim Haley } 192e802abbdSTim Haley idx++; 193e802abbdSTim Haley bits = rest; 194e802abbdSTim Haley } 195e802abbdSTim Haley (void) printf("\n"); 196e802abbdSTim Haley } 197e802abbdSTim Haley 198e802abbdSTim Haley int 199e802abbdSTim Haley main(int argc, char **argv) 200e802abbdSTim Haley { 201e802abbdSTim Haley zut_lookup_t lk = {0}; 202e802abbdSTim Haley zut_readdir_t rd = {0}; 203e802abbdSTim Haley boolean_t checking = B_FALSE; 204e802abbdSTim Haley boolean_t looking = B_FALSE; 205e802abbdSTim Haley boolean_t reading = B_FALSE; 206e802abbdSTim Haley boolean_t bflag = B_FALSE; 207e802abbdSTim Haley long rddir_bufsize = BIGBUF; 208e802abbdSTim Haley int error = 0; 209e802abbdSTim Haley int check; 210e802abbdSTim Haley int fd; 211e802abbdSTim Haley int c; 212e802abbdSTim Haley 213e802abbdSTim Haley while ((c = getopt(argc, argv, "lisaerb:ASE")) != -1) { 214e802abbdSTim Haley switch (c) { 215e802abbdSTim Haley case 'l': 216e802abbdSTim Haley looking = B_TRUE; 217e802abbdSTim Haley break; 218e802abbdSTim Haley case 'i': 219e802abbdSTim Haley lk.zl_reqflags |= ZUT_IGNORECASE; 220e802abbdSTim Haley looking = B_TRUE; 221e802abbdSTim Haley break; 222e802abbdSTim Haley case 's': 223e802abbdSTim Haley lk.zl_reqflags |= ZUT_GETSTAT; 224e802abbdSTim Haley looking = B_TRUE; 225e802abbdSTim Haley break; 226e802abbdSTim Haley case 'a': 227e802abbdSTim Haley rd.zr_reqflags |= ZUT_ACCFILTER; 228e802abbdSTim Haley reading = B_TRUE; 229e802abbdSTim Haley break; 230e802abbdSTim Haley case 'e': 231e802abbdSTim Haley rd.zr_reqflags |= ZUT_EXTRDDIR; 232e802abbdSTim Haley reading = B_TRUE; 233e802abbdSTim Haley break; 234e802abbdSTim Haley case 'r': 235e802abbdSTim Haley reading = B_TRUE; 236e802abbdSTim Haley break; 237e802abbdSTim Haley case 'b': 238e802abbdSTim Haley reading = B_TRUE; 239e802abbdSTim Haley bflag = B_TRUE; 240e802abbdSTim Haley rddir_bufsize = strtol(optarg, NULL, 0); 241e802abbdSTim Haley break; 242e802abbdSTim Haley case 'A': 243e802abbdSTim Haley checking = B_TRUE; 244e802abbdSTim Haley check = _PC_ACCESS_FILTERING; 245e802abbdSTim Haley break; 246e802abbdSTim Haley case 'S': 247e802abbdSTim Haley checking = B_TRUE; 248e802abbdSTim Haley check = _PC_SATTR_ENABLED; 249e802abbdSTim Haley break; 250e802abbdSTim Haley case 'E': 251e802abbdSTim Haley checking = B_TRUE; 252e802abbdSTim Haley check = _PC_SATTR_EXISTS; 253e802abbdSTim Haley break; 254e802abbdSTim Haley case '?': 255e802abbdSTim Haley default: 256e802abbdSTim Haley usage(argv[0]); /* no return */ 257e802abbdSTim Haley } 258e802abbdSTim Haley } 259e802abbdSTim Haley 260e802abbdSTim Haley if ((checking && looking) || (checking && reading) || 261e802abbdSTim Haley (looking && reading) || (!reading && bflag) || 262e802abbdSTim Haley (!checking && !reading && !looking)) 263e802abbdSTim Haley usage(argv[0]); /* no return */ 264e802abbdSTim Haley 265e802abbdSTim Haley if (rddir_bufsize < LILBUF || rddir_bufsize > MAXBUF) { 266e802abbdSTim Haley (void) fprintf(stderr, "Sorry, buffer size " 267e802abbdSTim Haley "must be >= %d and less than or equal to %d bytes.\n", 268*6a45aeb4STim Haley (int)LILBUF, MAXBUF); 269e802abbdSTim Haley exit(EINVAL); 270e802abbdSTim Haley } 271e802abbdSTim Haley 272e802abbdSTim Haley if (checking) { 273e802abbdSTim Haley char pathbuf[MAXPATHLEN]; 274e802abbdSTim Haley long result; 275e802abbdSTim Haley 276e802abbdSTim Haley if (argc - optind < 1) 277e802abbdSTim Haley usage(argv[0]); /* no return */ 278e802abbdSTim Haley (void) strlcpy(pathbuf, argv[optind], MAXPATHLEN); 279e802abbdSTim Haley result = pathconf(pathbuf, check); 280e802abbdSTim Haley (void) printf("pathconf(2) check for %s\n", pathbuf); 281e802abbdSTim Haley switch (check) { 282e802abbdSTim Haley case _PC_SATTR_ENABLED: 283e802abbdSTim Haley (void) printf("System attributes "); 284e802abbdSTim Haley if (result != 0) 285e802abbdSTim Haley (void) printf("Enabled\n"); 286e802abbdSTim Haley else 287e802abbdSTim Haley (void) printf("Not enabled\n"); 288e802abbdSTim Haley break; 289e802abbdSTim Haley case _PC_SATTR_EXISTS: 290e802abbdSTim Haley (void) printf("System attributes "); 291e802abbdSTim Haley if (result != 0) 292e802abbdSTim Haley (void) printf("Exist\n"); 293e802abbdSTim Haley else 294e802abbdSTim Haley (void) printf("Do not exist\n"); 295e802abbdSTim Haley break; 296e802abbdSTim Haley case _PC_ACCESS_FILTERING: 297e802abbdSTim Haley (void) printf("Access filtering "); 298e802abbdSTim Haley if (result != 0) 299e802abbdSTim Haley (void) printf("Available\n"); 300e802abbdSTim Haley else 301e802abbdSTim Haley (void) printf("Not available\n"); 302e802abbdSTim Haley break; 303e802abbdSTim Haley } 304e802abbdSTim Haley return (result); 305e802abbdSTim Haley } 306e802abbdSTim Haley 307e802abbdSTim Haley if ((fd = open(ZUT_DEV, O_RDONLY)) < 0) { 308e802abbdSTim Haley perror(ZUT_DEV); 309e802abbdSTim Haley return (ENXIO); 310e802abbdSTim Haley } 311e802abbdSTim Haley 312e802abbdSTim Haley if (reading) { 313e802abbdSTim Haley char *buf; 314e802abbdSTim Haley 315e802abbdSTim Haley if (argc - optind < 1) 316e802abbdSTim Haley usage(argv[0]); /* no return */ 317e802abbdSTim Haley 318e802abbdSTim Haley (void) strlcpy(rd.zr_dir, argv[optind], MAXPATHLEN); 319e802abbdSTim Haley if (argc - optind > 1) { 320e802abbdSTim Haley (void) strlcpy(rd.zr_file, argv[optind + 1], 321e802abbdSTim Haley MAXNAMELEN); 322e802abbdSTim Haley rd.zr_reqflags |= ZUT_XATTR; 323e802abbdSTim Haley } 324e802abbdSTim Haley 325e802abbdSTim Haley if ((buf = malloc(rddir_bufsize)) == NULL) { 326e802abbdSTim Haley error = errno; 327e802abbdSTim Haley perror("malloc"); 328e802abbdSTim Haley (void) close(fd); 329e802abbdSTim Haley return (error); 330e802abbdSTim Haley } 331e802abbdSTim Haley 332e802abbdSTim Haley rd.zr_buf = (uint64_t)(uintptr_t)buf; 333e802abbdSTim Haley rd.zr_buflen = rddir_bufsize; 334e802abbdSTim Haley 335e802abbdSTim Haley while (!rd.zr_eof) { 336e802abbdSTim Haley int ierr; 337e802abbdSTim Haley 338e802abbdSTim Haley if ((ierr = ioctl(fd, ZUT_IOC_READDIR, &rd)) != 0) { 339e802abbdSTim Haley (void) fprintf(stderr, 340e802abbdSTim Haley "IOCTL error: %s (%d)\n", 341e802abbdSTim Haley strerror(ierr), ierr); 342e802abbdSTim Haley free(buf); 343e802abbdSTim Haley (void) close(fd); 344e802abbdSTim Haley return (ierr); 345e802abbdSTim Haley } 346e802abbdSTim Haley if (rd.zr_retcode) { 347e802abbdSTim Haley (void) fprintf(stderr, 348e802abbdSTim Haley "readdir result: %s (%d)\n", 349e802abbdSTim Haley strerror(rd.zr_retcode), rd.zr_retcode); 350e802abbdSTim Haley free(buf); 351e802abbdSTim Haley (void) close(fd); 352e802abbdSTim Haley return (rd.zr_retcode); 353e802abbdSTim Haley } 354e802abbdSTim Haley if (rd.zr_reqflags & ZUT_EXTRDDIR) 355e802abbdSTim Haley print_extd_entries(&rd); 356e802abbdSTim Haley else 357e802abbdSTim Haley print_entries(&rd); 358e802abbdSTim Haley } 359e802abbdSTim Haley free(buf); 360e802abbdSTim Haley } else { 361e802abbdSTim Haley int ierr; 362e802abbdSTim Haley 363e802abbdSTim Haley if (argc - optind < 2) 364e802abbdSTim Haley usage(argv[0]); /* no return */ 365e802abbdSTim Haley 366e802abbdSTim Haley (void) strlcpy(lk.zl_dir, argv[optind], MAXPATHLEN); 367e802abbdSTim Haley (void) strlcpy(lk.zl_file, argv[optind + 1], MAXNAMELEN); 368e802abbdSTim Haley if (argc - optind > 2) { 369e802abbdSTim Haley (void) strlcpy(lk.zl_xfile, 370e802abbdSTim Haley argv[optind + 2], MAXNAMELEN); 371e802abbdSTim Haley lk.zl_reqflags |= ZUT_XATTR; 372e802abbdSTim Haley } 373e802abbdSTim Haley 374e802abbdSTim Haley if ((ierr = ioctl(fd, ZUT_IOC_LOOKUP, &lk)) != 0) { 375e802abbdSTim Haley (void) fprintf(stderr, 376e802abbdSTim Haley "IOCTL error: %s (%d)\n", 377e802abbdSTim Haley strerror(ierr), ierr); 378e802abbdSTim Haley (void) close(fd); 379e802abbdSTim Haley return (ierr); 380e802abbdSTim Haley } 381e802abbdSTim Haley 382e802abbdSTim Haley (void) printf("\nLookup of "); 383e802abbdSTim Haley if (lk.zl_reqflags & ZUT_XATTR) { 384e802abbdSTim Haley (void) printf("extended attribute \"%s\" of ", 385e802abbdSTim Haley lk.zl_xfile); 386e802abbdSTim Haley } 387e802abbdSTim Haley (void) printf("file \"%s\" ", lk.zl_file); 388e802abbdSTim Haley (void) printf("in directory \"%s\" ", lk.zl_dir); 389e802abbdSTim Haley if (lk.zl_retcode) { 390e802abbdSTim Haley (void) printf("failed: %s (%d)\n", 391e802abbdSTim Haley strerror(lk.zl_retcode), lk.zl_retcode); 392e802abbdSTim Haley (void) close(fd); 393e802abbdSTim Haley return (lk.zl_retcode); 394e802abbdSTim Haley } 395e802abbdSTim Haley 396e802abbdSTim Haley (void) printf("succeeded.\n"); 397e802abbdSTim Haley if (lk.zl_reqflags & ZUT_IGNORECASE) { 398e802abbdSTim Haley (void) printf("----------------------------\n"); 399e802abbdSTim Haley (void) printf("dirent flags: 0x%0x\n", lk.zl_deflags); 400e802abbdSTim Haley (void) printf("real name: %s\n", lk.zl_real); 401e802abbdSTim Haley } 402e802abbdSTim Haley if (lk.zl_reqflags & ZUT_GETSTAT) { 403e802abbdSTim Haley (void) printf("----------------------------\n"); 404e802abbdSTim Haley print_stats(&lk.zl_statbuf); 405e802abbdSTim Haley print_xvs(lk.zl_xvattrs); 406e802abbdSTim Haley } 407e802abbdSTim Haley } 408e802abbdSTim Haley 409e802abbdSTim Haley (void) close(fd); 410e802abbdSTim Haley return (0); 411e802abbdSTim Haley } 412