void priv_vfs_extattr_system(int asroot, int injail, struct test *test) { ssize_t ret; int error; ret = extattr_set_file(fpath, EA_NAMESPACE, EA_NAME, EA_DATA, EA_SIZE); if (ret < 0) error = -1; else if (ret == EA_SIZE) error = 0; else err(-1, "priv_vfs_extattr_system: set returned %zd", ret); if (asroot && injail) expect("priv_vfs_extattr_system(asroot, injail)", error, -1, EPERM); if (asroot && !injail) expect("priv_vfs_extattr_system(asroot, !injail)", error, 0, 0); if (!asroot && injail) expect("priv_vfs_extattr_system(!asroot, injail)", error, -1, EPERM); if (!asroot && !injail) expect("priv_vfs_extattr_system(!asroot, !injail)", error, -1, EPERM); }
ssize_t setAttr( const char* path, const char *attrname, const void* data, size_t nbytes ) { ssize_t ret = extattr_set_file( path, EXTATTR_NAMESPACE_USER, attrname, data, nbytes ); checkReturnValue( "setAttr", ret ); return ret; }
/* * Set attributes for a file. */ void set_extattr_file(char *name, void *buf, int size) { struct extattr *eap, *eaend; vprintf(stdout, "Set attributes for %s:", name); eaend = buf + size; for (eap = buf; eap < eaend; eap = EXTATTR_NEXT(eap)) { /* * Make sure this entry is complete. */ if (EXTATTR_NEXT(eap) > eaend || eap->ea_length <= 0) { dprintf(stdout, "\n\t%scorrupted", eap == buf ? "" : "remainder "); break; } if (eap->ea_namespace == EXTATTR_NAMESPACE_EMPTY) continue; vprintf(stdout, "\n\t%s, (%d bytes), %*s", namespace_names[eap->ea_namespace], eap->ea_length, eap->ea_namelength, eap->ea_name); /* * First we try the general attribute setting interface. * However, some attributes can only be set by root or * by using special interfaces (for example, ACLs). */ if (extattr_set_file(name, eap->ea_namespace, eap->ea_name, EXTATTR_CONTENT(eap), EXTATTR_CONTENT_SIZE(eap)) != -1) { dprintf(stdout, " (set using extattr_set_file)"); continue; } /* * If the general interface refuses to set the attribute, * then we try all the specialized interfaces that we * know about. */ if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM && !strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME)) { if (acl_set_file(name, ACL_TYPE_ACCESS, EXTATTR_CONTENT(eap)) != -1) { dprintf(stdout, " (set using acl_set_file)"); continue; } } if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM && !strcmp(eap->ea_name, POSIX1E_ACL_DEFAULT_EXTATTR_NAME)) { if (acl_set_file(name, ACL_TYPE_DEFAULT, EXTATTR_CONTENT(eap)) != -1) { dprintf(stdout, " (set using acl_set_file)"); continue; } } vprintf(stdout, " (unable to set)"); } vprintf(stdout, "\n"); }
void priv_vfs_clearsugid_extattr(int asroot, int injail, struct test *test) { if (extattr_set_file(fpath, EA_NAMESPACE, EA_NAME, EA_DATA, EA_SIZE) < 0) err(-1, "priv_vfs_clearsugid_extattr(%s, %s): extattr_set_file", asroot ? "root" : "!root", injail ? "jail" : "!jail"); confirm_sugid("priv_vfs_clearsugid_extattr", asroot, injail); }
/* * Sets extended attribute on a file. * Returns 0 on success, -1 on failure. */ int ceph_os_setxattr(const char *path, const char *name, const void *value, size_t size) { int error = -1; #if defined(__FreeBSD__) error = extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, value, size); if (error > 0) error = 0; #elif defined(__linux__) || defined(DARWIN) error = setxattr(path, name, value, size, 0); #endif return (error); }
static ssize_t xattr_setxattr(const char *path, const char *name, void *value, ssize_t size, u_int32_t position, int options) { int rv = 0; int nofollow; if (position != 0) { return -1; } nofollow = options & XATTR_XATTR_NOFOLLOW; options &= ~XATTR_XATTR_NOFOLLOW; if (options == XATTR_XATTR_CREATE || options == XATTR_XATTR_REPLACE) { /* meh. FreeBSD doesn't really have this in its * API... Oh well. */ } else if (options != 0) { return -1; } if (nofollow) { rv = extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size); } else { rv = extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, value, size); } /* freebsd returns the written length on success, not zero. */ if (rv >= 0) { return 0; } else { return rv; } }
int sys_setxattr (const char *path, const char *uname, const void *value, size_t size, int flags) { const char *name = prefix(uname); #if defined(HAVE_SETXATTR) #ifndef XATTR_ADD_OPT return setxattr(path, name, value, size, flags); #else int options = 0; return setxattr(path, name, value, size, 0, options); #endif #elif defined(HAVE_SETEA) return setea(path, name, value, size, flags); #elif defined(HAVE_EXTATTR_SET_FILE) int retval = 0; if (flags) { /* Check attribute existence */ retval = extattr_get_file(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0); if (retval < 0) { /* REPLACE attribute, that doesn't exist */ if (flags & XATTR_REPLACE && errno == ENOATTR) { errno = ENOATTR; return -1; } /* Ignore other errors */ } else { /* CREATE attribute, that already exists */ if (flags & XATTR_CREATE) { errno = EEXIST; return -1; } } } retval = extattr_set_file(path, EXTATTR_NAMESPACE_USER, uname, value, size); return (retval < 0) ? -1 : 0; #elif defined(HAVE_ATTR_SET) int myflags = 0; char *attrname = strchr(name,'.') + 1; if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; return attr_set(path, attrname, (const char *)value, size, myflags); #elif defined(HAVE_ATTROPEN) int ret = -1; int myflags = O_RDWR; int attrfd; if (flags & XATTR_CREATE) myflags |= O_EXCL; if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE); if (attrfd >= 0) { ret = solaris_write_xattr(attrfd, value, size); close(attrfd); } return ret; #else errno = ENOSYS; return -1; #endif }
int main(int argc, char *argv[]) { char *buf, *visbuf, *p; const char *options, *attrname; size_t len; ssize_t ret; int buflen, visbuflen, ch, error, i, arg_counter, attrnamespace, minargc; int flag_force = 0; int flag_nofollow = 0; int flag_null = 0; int flag_quiet = 0; int flag_string = 0; int flag_hex = 0; visbuflen = buflen = 0; visbuf = buf = NULL; p = basename(argv[0]); if (p == NULL) p = argv[0]; if (!strcmp(p, "getextattr")) { what = EAGET; options = "fhqsx"; minargc = 3; } else if (!strcmp(p, "setextattr")) { what = EASET; options = "fhnq"; minargc = 4; } else if (!strcmp(p, "rmextattr")) { what = EARM; options = "fhq"; minargc = 3; } else if (!strcmp(p, "lsextattr")) { what = EALS; options = "fhq"; minargc = 2; } else { usage(); } while ((ch = getopt(argc, argv, options)) != -1) { switch (ch) { case 'f': flag_force = 1; break; case 'h': flag_nofollow = 1; break; case 'n': flag_null = 1; break; case 'q': flag_quiet = 1; break; case 's': flag_string = 1; break; case 'x': flag_hex = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc < minargc) usage(); error = extattr_string_to_namespace(argv[0], &attrnamespace); if (error) err(-1, "%s", argv[0]); argc--; argv++; if (what != EALS) { attrname = argv[0]; argc--; argv++; } else attrname = NULL; if (what == EASET) { mkbuf(&buf, &buflen, strlen(argv[0]) + 1); strcpy(buf, argv[0]); argc--; argv++; } for (arg_counter = 0; arg_counter < argc; arg_counter++) { switch (what) { case EARM: if (flag_nofollow) error = extattr_delete_link(argv[arg_counter], attrnamespace, attrname); else error = extattr_delete_file(argv[arg_counter], attrnamespace, attrname); if (error >= 0) continue; break; case EASET: len = strlen(buf) + flag_null; if (flag_nofollow) ret = extattr_set_link(argv[arg_counter], attrnamespace, attrname, buf, len); else ret = extattr_set_file(argv[arg_counter], attrnamespace, attrname, buf, len); if (ret >= 0) { if ((size_t)ret != len && !flag_quiet) { warnx("Set %zd bytes of %zu for %s", ret, len, attrname); } continue; } break; case EALS: if (flag_nofollow) ret = extattr_list_link(argv[arg_counter], attrnamespace, NULL, 0); else ret = extattr_list_file(argv[arg_counter], attrnamespace, NULL, 0); if (ret < 0) break; mkbuf(&buf, &buflen, ret); if (flag_nofollow) ret = extattr_list_link(argv[arg_counter], attrnamespace, buf, buflen); else ret = extattr_list_file(argv[arg_counter], attrnamespace, buf, buflen); if (ret < 0) break; if (!flag_quiet) printf("%s\t", argv[arg_counter]); for (i = 0; i < ret; i += ch + 1) { /* The attribute name length is unsigned. */ ch = (unsigned char)buf[i]; printf("%s%*.*s", i ? "\t" : "", ch, ch, buf + i + 1); } if (!flag_quiet || ret > 0) printf("\n"); continue; case EAGET: if (flag_nofollow) ret = extattr_get_link(argv[arg_counter], attrnamespace, attrname, NULL, 0); else ret = extattr_get_file(argv[arg_counter], attrnamespace, attrname, NULL, 0); if (ret < 0) break; mkbuf(&buf, &buflen, ret); if (flag_nofollow) ret = extattr_get_link(argv[arg_counter], attrnamespace, attrname, buf, buflen); else ret = extattr_get_file(argv[arg_counter], attrnamespace, attrname, buf, buflen); if (ret < 0) break; if (!flag_quiet) printf("%s\t", argv[arg_counter]); if (flag_string) { mkbuf(&visbuf, &visbuflen, ret * 4 + 1); strvisx(visbuf, buf, ret, VIS_SAFE | VIS_WHITE); printf("\"%s\"\n", visbuf); continue; } else if (flag_hex) { for (i = 0; i < ret; i++) printf("%s%02x", i ? " " : "", buf[i]); printf("\n"); continue; } else { fwrite(buf, ret, 1, stdout); printf("\n"); continue; } default: break; } if (!flag_quiet) warn("%s: failed", argv[arg_counter]); if (flag_force) continue; return(1); } return (0); }
/* Bring the given attributes and/or ACLs into effect with the given file. @param flag Bitfield for control purposes bit0= decode and set ACLs bit1= first clear all existing attributes of the file bit2= do not set attributes other than ACLs bit3= do not ignore eventual non-user attributes. I.e. those with a name which does not begin by "user." bit5= in case of symbolic link: manipulate link target bit6= tolerate inappropriate presence or absence of directory default ACL @return 1 success -1 error memory allocation -2 error with decoding of ACL -3 error with setting ACL -4 error with setting attribute -5 error with deleting attributes -6 support of xattr not enabled at compile time -7 support of ACL not enabled at compile time -8 unsupported xattr namespace ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other:: */ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, size_t *value_lengths, char **values, int flag) { int ret, has_default_acl= 0; size_t i, consumed, acl_text_fill, acl_idx= 0; char *acl_text= NULL; #ifdef Libisofs_with_freebsd_extattR char *user_list= NULL, *sys_list= NULL, *namept; ssize_t user_list_size= 0, sys_list_size= 0; int attrnamespace; #endif #ifdef Libisofs_with_freebsd_extattR if(flag & 2) { /* Delete all file attributes */ ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER, &user_list, &user_list_size, flag & 32); if(ret <= 0) {ret= -1; goto ex;} ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_USER, user_list, user_list_size, flag & 32); if(ret <= 0) {ret= -5; goto ex;} if(flag & 8) { ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM, &sys_list, &sys_list_size, flag & 32); if(ret <= 0) {ret= -5; goto ex;} ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_SYSTEM, sys_list, sys_list_size, flag & 32); if(ret <= 0) {ret= -5; goto ex;} } } #endif /* Libisofs_with_freebsd_extattR */ for(i= 0; i < num_attrs; i++) { if(names[i] == NULL || values[i] == NULL) continue; if(names[i][0] == 0) { /* ACLs */ if(flag & 1) acl_idx= i + 1; continue; } /* Extended Attribute */ if(flag & 4) continue; #ifdef Libisofs_with_freebsd_extattR if(strncmp(names[i], "user.", 5) == 0) { attrnamespace= EXTATTR_NAMESPACE_USER; namept= names[i] + 5; } else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8)) { continue; } else if(strncmp(names[i], "system.", 7) == 0) { attrnamespace= EXTATTR_NAMESPACE_SYSTEM; namept= names[i] + 7; } else { {ret= -8; goto ex;} } if(flag & 32) ret= extattr_set_file(path, attrnamespace, namept, values[i], value_lengths[i]); else ret= extattr_set_link(path, attrnamespace, namept, values[i], value_lengths[i]); if(ret == -1) {ret= -4; goto ex;} #else if(strncmp(names[i], "user.", 5) == 0) ; else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8)) continue; {ret= -6; goto ex;} #endif /* Libisofs_with_freebsd_extattR */ } /* Decode ACLs */ if(acl_idx == 0) {ret= 1; goto ex;} i= acl_idx - 1; ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i], &consumed, NULL, 0, &acl_text_fill, 1); if(ret < -3) goto ex; if(ret <= 0) {ret= -2; goto ex;} acl_text= calloc(acl_text_fill, 1); if(acl_text == NULL) {ret= -1; goto ex;} ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i], &consumed, acl_text, acl_text_fill, &acl_text_fill, 0); if(ret < -3) goto ex; if(ret <= 0) {ret= -2; goto ex;} has_default_acl= (ret == 2); #ifdef Libisofs_with_aaip_acL ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64)); if(ret <= 0) {ret= -3; goto ex;} #else {ret= -7; goto ex;} #endif if(has_default_acl && !(flag & 64)) {ret= -3; goto ex;} ret= 1; ex:; if(acl_text != NULL) free(acl_text); #ifdef Libisofs_with_freebsd_extattR if(user_list != NULL) free(user_list); if(sys_list != NULL) free(sys_list); #endif /* Libisofs_with_freebsd_extattR */ return(ret); }
/* * This program displays the location information of a data storage file * for a given file on a MetaData Server (MDS) in a pNFS service. This program * must be run on the MDS and the file argument must be a file in a local * file system that has been exported for the pNFS service. */ int main(int argc, char *argv[]) { struct addrinfo *res, *ad, *newres; struct sockaddr_in *sin, adsin; struct sockaddr_in6 *sin6, adsin6; char hostn[2 * NI_MAXHOST + 2], *cp; struct pnfsdsfile dsfile[NFSDEV_MAXMIRRORS]; int ch, dosetxattr, i, mirrorcnt, mirrorit, quiet, zerods, zerofh; in_port_t tport; ssize_t xattrsize, xattrsize2; zerods = 0; zerofh = 0; mirrorit = 0; quiet = 0; dosetxattr = 0; res = NULL; newres = NULL; cp = NULL; while ((ch = getopt_long(argc, argv, "c:m:qr:s:z", longopts, NULL)) != -1) { switch (ch) { case 'c': /* Replace the first DS server with the second one. */ if (zerofh != 0 || zerods != 0 || mirrorit != 0 || newres != NULL || res != NULL) errx(1, "-c, -m, -r, -s and -z are mutually " "exclusive and only can be used once"); strlcpy(hostn, optarg, 2 * NI_MAXHOST + 2); cp = strchr(hostn, ','); if (cp == NULL) errx(1, "Bad -c argument %s", hostn); *cp = '\0'; if (getaddrinfo(hostn, NULL, NULL, &res) != 0) errx(1, "Can't get IP# for %s", hostn); *cp++ = ','; if (getaddrinfo(cp, NULL, NULL, &newres) != 0) errx(1, "Can't get IP# for %s", cp); break; case 'm': /* Add 0.0.0.0 entries up to mirror level. */ if (zerofh != 0 || zerods != 0 || mirrorit != 0 || newres != NULL || res != NULL) errx(1, "-c, -m, -r, -s and -z are mutually " "exclusive and only can be used once"); mirrorit = atoi(optarg); if (mirrorit < 2 || mirrorit > NFSDEV_MAXMIRRORS) errx(1, "-m %d out of range", mirrorit); break; case 'q': quiet = 1; break; case 'r': /* Reset the DS server in a mirror with 0.0.0.0. */ if (zerofh != 0 || zerods != 0 || mirrorit != 0 || newres != NULL || res != NULL) errx(1, "-c, -m, -r, -s and -z are mutually " "exclusive and only can be used once"); zerods = 1; /* Translate the server name to an IP address. */ if (getaddrinfo(optarg, NULL, NULL, &res) != 0) errx(1, "Can't get IP# for %s", optarg); break; case 's': /* Translate the server name to an IP address. */ if (zerods != 0 || mirrorit != 0 || newres != NULL || res != NULL) errx(1, "-c, -m and -r are mutually exclusive " "from use with -s and -z"); if (getaddrinfo(optarg, NULL, NULL, &res) != 0) errx(1, "Can't get IP# for %s", optarg); break; case 'z': if (zerofh != 0 || zerods != 0 || mirrorit != 0 || newres != NULL) errx(1, "-c, -m and -r are mutually exclusive " "from use with -s and -z"); zerofh = 1; break; default: usage(); } } argc -= optind; if (argc != 1) usage(); argv += optind; /* * The host address and directory where the data storage file is * located is in the extended attribute "pnfsd.dsfile". */ xattrsize = extattr_get_file(*argv, EXTATTR_NAMESPACE_SYSTEM, "pnfsd.dsfile", dsfile, sizeof(dsfile)); mirrorcnt = xattrsize / sizeof(struct pnfsdsfile); xattrsize2 = mirrorcnt * sizeof(struct pnfsdsfile); if (mirrorcnt < 1 || xattrsize != xattrsize2) err(1, "Can't get extattr pnfsd.dsfile for %s", *argv); if (quiet == 0) printf("%s:\t", *argv); for (i = 0; i < mirrorcnt; i++) { if (i > 0 && quiet == 0) printf("\t"); /* Do the zerofh option. You must be root. */ if (zerofh != 0) { if (geteuid() != 0) errx(1, "Must be root/su to zerofh"); /* * Do it for the server specified by -s/--ds or all * servers, if -s/--ds was not specified. */ sin = &dsfile[i].dsf_sin; sin6 = &dsfile[i].dsf_sin6; ad = res; while (ad != NULL) { if (ad->ai_addr->sa_family == AF_INET && sin->sin_family == AF_INET && ad->ai_addrlen >= sizeof(adsin)) { memcpy(&adsin, ad->ai_addr, sizeof(adsin)); if (sin->sin_addr.s_addr == adsin.sin_addr.s_addr) break; } if (ad->ai_addr->sa_family == AF_INET6 && sin6->sin6_family == AF_INET6 && ad->ai_addrlen >= sizeof(adsin6)) { memcpy(&adsin6, ad->ai_addr, sizeof(adsin6)); if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &adsin6.sin6_addr)) break; } ad = ad->ai_next; } if (res == NULL || ad != NULL) { memset(&dsfile[i].dsf_fh, 0, sizeof(fhandle_t)); dosetxattr = 1; } } /* Do the zerods option. You must be root. */ if (zerods != 0 && mirrorcnt > 1) { if (geteuid() != 0) errx(1, "Must be root/su to zerods"); /* * Do it for the server specified. */ sin = &dsfile[i].dsf_sin; sin6 = &dsfile[i].dsf_sin6; ad = res; while (ad != NULL) { if (ad->ai_addr->sa_family == AF_INET && sin->sin_family == AF_INET && ad->ai_addrlen >= sizeof(adsin)) { memcpy(&adsin, ad->ai_addr, sizeof(adsin)); if (sin->sin_addr.s_addr == adsin.sin_addr.s_addr) break; } if (ad->ai_addr->sa_family == AF_INET6 && sin6->sin6_family == AF_INET6 && ad->ai_addrlen >= sizeof(adsin6)) { memcpy(&adsin6, ad->ai_addr, sizeof(adsin6)); if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &adsin6.sin6_addr)) break; } ad = ad->ai_next; } if (ad != NULL) { sin->sin_family = AF_INET; sin->sin_len = sizeof(*sin); sin->sin_port = 0; sin->sin_addr.s_addr = 0; dosetxattr = 1; } } /* Do the -c option to replace the DS host address. */ if (newres != NULL) { if (geteuid() != 0) errx(1, "Must be root/su to replace the host" " addr"); /* * Check that the old host address matches. */ sin = &dsfile[i].dsf_sin; sin6 = &dsfile[i].dsf_sin6; ad = res; while (ad != NULL) { if (ad->ai_addr->sa_family == AF_INET && sin->sin_family == AF_INET && ad->ai_addrlen >= sizeof(adsin)) { memcpy(&adsin, ad->ai_addr, sizeof(adsin)); if (sin->sin_addr.s_addr == adsin.sin_addr.s_addr) break; } if (ad->ai_addr->sa_family == AF_INET6 && sin6->sin6_family == AF_INET6 && ad->ai_addrlen >= sizeof(adsin6)) { memcpy(&adsin6, ad->ai_addr, sizeof(adsin6)); if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &adsin6.sin6_addr)) break; } ad = ad->ai_next; } if (ad != NULL) { if (sin->sin_family == AF_INET) tport = sin->sin_port; else tport = sin6->sin6_port; /* * We have a match, so replace it with the first * AF_INET or AF_INET6 address in the newres * list. */ while (newres->ai_addr->sa_family != AF_INET && newres->ai_addr->sa_family != AF_INET6) { newres = newres->ai_next; if (newres == NULL) errx(1, "Hostname %s has no" " IP#", cp); } if (newres->ai_addr->sa_family == AF_INET) { memcpy(sin, newres->ai_addr, sizeof(*sin)); sin->sin_port = tport; } else if (newres->ai_addr->sa_family == AF_INET6) { memcpy(sin6, newres->ai_addr, sizeof(*sin6)); sin6->sin6_port = tport; } dosetxattr = 1; } } if (quiet == 0) { /* Translate the IP address to a hostname. */ if (getnameinfo((struct sockaddr *)&dsfile[i].dsf_sin, dsfile[i].dsf_sin.sin_len, hostn, sizeof(hostn), NULL, 0, 0) < 0) err(1, "Can't get hostname"); printf("%s\tds%d/%s", hostn, dsfile[i].dsf_dir, dsfile[i].dsf_filename); } } /* Add entrie(s) with IP address set to 0.0.0.0, as required. */ for (i = mirrorcnt; i < mirrorit; i++) { dsfile[i] = dsfile[0]; dsfile[i].dsf_sin.sin_family = AF_INET; dsfile[i].dsf_sin.sin_len = sizeof(struct sockaddr_in); dsfile[i].dsf_sin.sin_addr.s_addr = 0; dsfile[i].dsf_sin.sin_port = 0; if (quiet == 0) { /* Print out the 0.0.0.0 entry. */ printf("\t0.0.0.0\tds%d/%s", dsfile[i].dsf_dir, dsfile[i].dsf_filename); } } if (mirrorit > mirrorcnt) { xattrsize = mirrorit * sizeof(struct pnfsdsfile); dosetxattr = 1; } if (quiet == 0) printf("\n"); if (dosetxattr != 0 && extattr_set_file(*argv, EXTATTR_NAMESPACE_SYSTEM, "pnfsd.dsfile", dsfile, xattrsize) != xattrsize) err(1, "Can't set pnfsd.dsfile"); }