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