2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * CDDL HEADER START
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * The contents of this file are subject to the terms of the
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Common Development and Distribution License (the "License").
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * You may not use this file except in compliance with the License.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * or http://www.opensolaris.org/os/licensing.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * See the License for the specific language governing permissions
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * and limitations under the License.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * When distributing Covered Code, include this CDDL HEADER in each
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * If applicable, add the following below this CDDL HEADER, with the
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * fields enclosed by brackets "[]" replaced with your own identifying
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * information: Portions Copyright [yyyy] [name of copyright owner]
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * CDDL HEADER END
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Use is subject to license terms.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <stdio.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <unistd.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <strings.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <string.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <limits.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <libnvpair.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <locale.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/stat.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/fs_reparse.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rp_plugin.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <uuid/uuid.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/types.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/stat.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <fcntl.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <priv.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <nfs/nfs4.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rpcsvc/nfs4_prot.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include "ref_subr.h"
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifndef TEXT_DOMAIN
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#define TEXT_DOMAIN "SUNW_OST_OSCMD"
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif /* TEXT_DOMAIN */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowextern int errno;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowvoid
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowusage()
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr, gettext("Usage:\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow gettext("\tnfsref [-t type] add path location [location ...]\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr, gettext("\tnfsref [-t type] remove path\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr, gettext("\tnfsref [-t type] lookup path\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Copy a string from source to destination, escaping space
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * with a backslash and escaping the escape character as well.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowadd_escape(char *src, char *dest, int limit)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char *sp, *dp;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int destlen = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp = src;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow dp = dest;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow while (*sp && destlen < limit) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (*sp == '\\') {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *dp++ = '\\';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *dp++ = '\\';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow destlen++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else if (*sp == ' ') {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *dp++ = '\\';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *dp++ = ' ';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow destlen++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *dp++ = *sp;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow destlen++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (limit <= 0)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (-1);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (destlen);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowaddref(char *sl_path, char *svc_type, int optind, int argc, char *argv[])
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int err, fd, i, len, oldlen, notfound = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char *text, *location;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nvlist_t *nvl = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char buf[SYMLINK_MAX];
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow struct stat sbuf;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get an nvlist */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nvl = reparse_init();
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (nvl == NULL)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (ENOMEM);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get the reparse point data, if the RP exists */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = readlink(sl_path, buf, SYMLINK_MAX);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err == -1) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (errno == ENOENT) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow notfound = 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (errno);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow buf[err] = '\0';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get any data into nvlist */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (notfound == 0)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_parse(buf, nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err != 0) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Accumulate multiple locations on the command line into 'buf'
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow oldlen = len = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow location = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow for (i = optind; i < argc; i++) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow bzero(buf, sizeof (buf));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow len += add_escape(argv[i], buf, SYMLINK_MAX) + 2;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow location = realloc(location, len);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow location[oldlen] = '\0';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow oldlen = len;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow strlcat(location, buf, len);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow strlcat(location, " ", len);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow location[len - 2] = '\0';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Add to the list */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_add(nvl, svc_type, location);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get the new or modified symlink contents */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_unparse(nvl, &text);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Delete first if found */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (notfound == 0) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_delete(sl_path);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(text);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Finally, write out the reparse point */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_create(sl_path, text);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(text);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = lstat(sl_path, &sbuf);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err == 0 && strcasecmp(sbuf.st_fstype, "ZFS") != 0)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf(gettext(
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow "Warning: referrals do not work on this filesystem\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (notfound)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf(gettext("Created reparse point %s\n"), sl_path);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow else
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf(gettext("Added to reparse point %s\n"), sl_path);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (0);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowdelref(char *sl_path, char *svc_type)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char *cp;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char *svc_data;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int err;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nvlist_t *nvl;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nvpair_t *curr;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char buf[SYMLINK_MAX];
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int fd, fd2;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow FILE *fp, *fp2;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char uuid[UUID_PRINTABLE_STRING_LENGTH], path[256], loc[2048];
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get an nvlist */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (!(nvl = reparse_init()))
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (ENOMEM);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get the symlink data (should be there) */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = readlink(sl_path, buf, SYMLINK_MAX);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err == -1) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (errno);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow buf[err] = '\0';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get the records into the nvlist */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_parse(buf, nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Remove from nvlist */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_remove(nvl, svc_type);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Any list entries left? If so, turn nvlist back to string. */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow curr = nvlist_next_nvpair(nvl, NULL);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (curr != NULL) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_unparse(nvl, &cp);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow cp = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Finally, delete and perhaps recreate the reparse point */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_delete(sl_path);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(cp);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (cp != NULL) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_create(sl_path, cp);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(cp);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf(gettext("Removed svc_type '%s' from %s\n"), svc_type, sl_path);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowlookup(char *sl_path, char *svc_type, int type_set)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int err;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow size_t bufsize;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char buf[1024];
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char *type, *svc_data;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nvlist_t *nvl;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nvpair_t *curr;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fs_locations4 fsl;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow XDR xdr;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (!(nvl = reparse_init()))
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (-1);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get reparse point data */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = readlink(sl_path, buf, SYMLINK_MAX);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err == -1)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (errno);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow buf[err] = '\0';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Parse it to an nvlist */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_parse(buf, nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Look for entries of the requested service type */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow curr = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow while ((curr = nvlist_next_nvpair(nvl, curr)) != NULL) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow type = nvpair_name(curr);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (type_set && strcasecmp(type, svc_type) == 0)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow break;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (!type_set && strncasecmp(type, "nfs", 3) == 0)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow break;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (curr == NULL) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (ENOENT);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Get the service data and look it up */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nvpair_value_string(curr, &svc_data);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow bufsize = sizeof (buf);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = reparse_deref(type, svc_data, buf, &bufsize);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow reparse_free(nvl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow xdrmem_create(&xdr, buf, bufsize, XDR_DECODE);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = xdr_fs_locations4(&xdr, &fsl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow XDR_DESTROY(&xdr);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err != TRUE)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (ENOENT);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf(gettext("%s points to: "), sl_path);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow print_referral_summary(&fsl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (0);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowextern char *optarg;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowextern int optind, optopt;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowmain(int argc, char *argv[])
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char c, *command, *sl_path, *svc_type;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int type_set, err;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow (void) setlocale(LC_ALL, "");
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow (void) textdomain(TEXT_DOMAIN);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow svc_type = "nfs-basic"; /* Default from SMF some day */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow type_set = 0; /* Lookup any nfs type */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Look for options (just the service type now) */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow while ((c = getopt(argc, argv, "t:")) != -1) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow switch (c) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow case 't':
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow svc_type = optarg;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow type_set = 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow break;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow default:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow usage();
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow exit(1);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Make sure there's at least a command and one argument */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (optind + 1 >= argc) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow usage();
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow exit(1);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = rp_plugin_init();
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow switch (err) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow case RP_OK:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow break;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow case RP_NO_PLUGIN_DIR:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow gettext("Warning: no plugin directory, continuing...\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow break;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow case RP_NO_PLUGIN:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow gettext("Warning: no plugin found, continuing...\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow break;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow case RP_NO_MEMORY:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow gettext("rp_plugin_init failed, no memory\n"));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow exit(0);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow default:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow gettext("rp_plugin_init failed, error %d\n"), err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow exit(0);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow command = argv[optind++];
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sl_path = argv[optind++];
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (strcmp(command, "add") == 0) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (optind >= argc) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow usage();
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow exit(1);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = addref(sl_path, svc_type, optind, argc, argv);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else if (strcmp(command, "remove") == 0) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = delref(sl_path, svc_type);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else if (strcmp(command, "lookup") == 0) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = lookup(sl_path, svc_type, type_set);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow usage();
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow exit(1);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err != 0)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fprintf(stderr, gettext("Command %s failed: %s\n"), command,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow strerror(err));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (err);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}