1150305Smarcel/*-
2157621Smarcel * Copyright (c) 2005, 2006 Marcel Moolenaar
3150305Smarcel * All rights reserved.
4150305Smarcel *
5150305Smarcel * Redistribution and use in source and binary forms, with or without
6150305Smarcel * modification, are permitted provided that the following conditions
7150305Smarcel * are met:
8150305Smarcel *
9150305Smarcel * 1. Redistributions of source code must retain the above copyright
10150305Smarcel *    notice, this list of conditions and the following disclaimer.
11150305Smarcel * 2. Redistributions in binary form must reproduce the above copyright
12150305Smarcel *    notice, this list of conditions and the following disclaimer in the
13150305Smarcel *    documentation and/or other materials provided with the distribution.
14150305Smarcel *
15150305Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16150305Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17150305Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18150305Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19150305Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20150305Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21150305Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22150305Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23150305Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24150305Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25150305Smarcel */
26150305Smarcel
27150305Smarcel#include <sys/cdefs.h>
28150305Smarcel__FBSDID("$FreeBSD$");
29150305Smarcel
30157621Smarcel#include <sys/param.h>
31150305Smarcel#include <errno.h>
32150305Smarcel#include <libgeom.h>
33150305Smarcel#include <limits.h>
34150305Smarcel#include <stdio.h>
35150305Smarcel#include <stdlib.h>
36150305Smarcel#include <string.h>
37150305Smarcel#include <unistd.h>
38150305Smarcel
39157621Smarcelstruct retval {
40157621Smarcel	struct retval *retval;
41157621Smarcel	const char *param;
42157621Smarcel	char *value;
43157621Smarcel};
44157621Smarcel
45157621Smarcelstruct retval *retval;
46150305Smarcelint verbose;
47150305Smarcel
48150305Smarcelstatic void
49150305Smarcelusage()
50150305Smarcel{
51157621Smarcel	fprintf(stdout, "usage: %s [-v] param[:len][=value] ...\n",
52157621Smarcel	    getprogname());
53150305Smarcel	exit(1);
54150305Smarcel}
55150305Smarcel
56150305Smarcelstatic int
57157621Smarcelparse(char *arg, char **param, char **value, int *len)
58150305Smarcel{
59157621Smarcel	char *e, *colon, *equal;
60150305Smarcel
61157621Smarcel	if (*arg == '\0')
62157621Smarcel		return (EINVAL);
63157621Smarcel
64157621Smarcel	colon = strchr(arg, ':');
65157621Smarcel	equal = strchr(arg, '=');
66157621Smarcel	if (colon == NULL && equal == NULL)
67157621Smarcel		return (EINVAL);
68157621Smarcel	if (colon == arg || equal == arg)
69157621Smarcel		return (EINVAL);
70157621Smarcel	if (colon != NULL && equal != NULL && equal < colon)
71157621Smarcel		return (EINVAL);
72157621Smarcel
73157621Smarcel	if (colon != NULL)
74157621Smarcel		*colon++ = '\0';
75157621Smarcel	if (equal != NULL)
76157621Smarcel		*equal++ = '\0';
77157621Smarcel
78150305Smarcel	*param = arg;
79157621Smarcel	if (colon != NULL) {
80157621Smarcel		/* Length specification. This parameter is RW. */
81157621Smarcel		if (*colon == '\0')
82157621Smarcel			return (EINVAL);
83157621Smarcel		*len = strtol(colon, &e, 0);
84157621Smarcel		if (*e != '\0')
85157621Smarcel			return (EINVAL);
86157621Smarcel		if (*len <= 0 || *len > PATH_MAX)
87157621Smarcel			return (EINVAL);
88157621Smarcel		*value = malloc(*len);
89157621Smarcel		if (*value == NULL)
90157621Smarcel			return (ENOMEM);
91157621Smarcel		memset(*value, 0, *len);
92157621Smarcel		if (equal != NULL) {
93157621Smarcel			if (strlen(equal) >= PATH_MAX)
94157621Smarcel				return (ENOMEM);
95157621Smarcel			strcpy(*value, equal);
96157621Smarcel		}
97157621Smarcel	} else {
98157621Smarcel		/* This parameter is RO. */
99157621Smarcel		*len = -1;
100157621Smarcel		if (*equal == '\0')
101157621Smarcel			return (EINVAL);
102157621Smarcel		*value = equal;
103157621Smarcel	}
104157621Smarcel
105150305Smarcel	return (0);
106150305Smarcel}
107150305Smarcel
108150305Smarcelint main(int argc, char *argv[])
109150305Smarcel{
110157621Smarcel	struct retval *rv;
111150305Smarcel	struct gctl_req *req;
112150308Smarcel	char *param, *value;
113150305Smarcel	const char *s;
114157621Smarcel	int c, len;
115150305Smarcel
116150305Smarcel	req = gctl_get_handle();
117150305Smarcel	gctl_ro_param(req, "class", -1, "GPT");
118150305Smarcel
119150308Smarcel	while ((c = getopt(argc, argv, "v")) != -1) {
120150305Smarcel		switch (c) {
121150305Smarcel		case 'v':
122150305Smarcel			verbose = 1;
123150305Smarcel			break;
124150305Smarcel		case '?':
125150305Smarcel		default:
126150305Smarcel			usage();
127150305Smarcel			/* NOTREACHED */
128150305Smarcel			break;
129150305Smarcel		}
130150305Smarcel	}
131150305Smarcel
132150308Smarcel	while (optind < argc) {
133157621Smarcel		if (!parse(argv[optind++], &param, &value, &len)) {
134157621Smarcel			if (len > 0) {
135157621Smarcel				rv = malloc(sizeof(struct retval));
136157621Smarcel				rv->param = param;
137157621Smarcel				rv->value = value;
138157621Smarcel				rv->retval = retval;
139157621Smarcel				retval = rv;
140157621Smarcel				gctl_rw_param(req, param, len, value);
141157621Smarcel			} else
142157621Smarcel				gctl_ro_param(req, param, -1, value);
143157621Smarcel		}
144150308Smarcel	}
145150308Smarcel
146150305Smarcel	if (verbose)
147150305Smarcel		gctl_dump(req, stdout);
148150305Smarcel
149150305Smarcel	s = gctl_issue(req);
150157621Smarcel	if (s == NULL) {
151157621Smarcel		printf("PASS");
152157621Smarcel		while (retval != NULL) {
153157621Smarcel			rv = retval->retval;
154157621Smarcel			printf(" %s=%s", retval->param, retval->value);
155157621Smarcel			free(retval->value);
156157621Smarcel			free(retval);
157157621Smarcel			retval = rv;
158157621Smarcel		}
159157621Smarcel		printf("\n");
160157621Smarcel	} else
161150305Smarcel		printf("FAIL %s\n", s);
162157621Smarcel
163150305Smarcel	gctl_free(req);
164150305Smarcel	return (0);
165150305Smarcel}
166