xref: /freebsd/sbin/geom/misc/subr.c (revision f13942a7469cd93e7f22f5fdc49d866ba488a982)
105c91076SPawel Jakub Dawidek /*-
205c91076SPawel Jakub Dawidek  * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
305c91076SPawel Jakub Dawidek  * All rights reserved.
405c91076SPawel Jakub Dawidek  *
505c91076SPawel Jakub Dawidek  * Redistribution and use in source and binary forms, with or without
605c91076SPawel Jakub Dawidek  * modification, are permitted provided that the following conditions
705c91076SPawel Jakub Dawidek  * are met:
805c91076SPawel Jakub Dawidek  * 1. Redistributions of source code must retain the above copyright
905c91076SPawel Jakub Dawidek  *    notice, this list of conditions and the following disclaimer.
1005c91076SPawel Jakub Dawidek  * 2. Redistributions in binary form must reproduce the above copyright
1105c91076SPawel Jakub Dawidek  *    notice, this list of conditions and the following disclaimer in the
1205c91076SPawel Jakub Dawidek  *    documentation and/or other materials provided with the distribution.
1305c91076SPawel Jakub Dawidek  *
1405c91076SPawel Jakub Dawidek  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1505c91076SPawel Jakub Dawidek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1605c91076SPawel Jakub Dawidek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1705c91076SPawel Jakub Dawidek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
1805c91076SPawel Jakub Dawidek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1905c91076SPawel Jakub Dawidek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2005c91076SPawel Jakub Dawidek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2105c91076SPawel Jakub Dawidek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2205c91076SPawel Jakub Dawidek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2305c91076SPawel Jakub Dawidek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2405c91076SPawel Jakub Dawidek  * SUCH DAMAGE.
2505c91076SPawel Jakub Dawidek  */
2605c91076SPawel Jakub Dawidek 
2705c91076SPawel Jakub Dawidek #include <sys/cdefs.h>
2805c91076SPawel Jakub Dawidek __FBSDID("$FreeBSD$");
2905c91076SPawel Jakub Dawidek 
3005c91076SPawel Jakub Dawidek #include <sys/param.h>
3105c91076SPawel Jakub Dawidek #include <sys/disk.h>
3205c91076SPawel Jakub Dawidek #include <sys/endian.h>
3305c91076SPawel Jakub Dawidek #include <sys/uio.h>
3405c91076SPawel Jakub Dawidek #include <errno.h>
3505c91076SPawel Jakub Dawidek #include <fcntl.h>
3605c91076SPawel Jakub Dawidek #include <paths.h>
3705c91076SPawel Jakub Dawidek #include <stdio.h>
3805c91076SPawel Jakub Dawidek #include <stdlib.h>
3905c91076SPawel Jakub Dawidek #include <stdarg.h>
4005c91076SPawel Jakub Dawidek #include <string.h>
4105c91076SPawel Jakub Dawidek #include <strings.h>
4205c91076SPawel Jakub Dawidek #include <unistd.h>
4305c91076SPawel Jakub Dawidek #include <assert.h>
4405c91076SPawel Jakub Dawidek #include <libgeom.h>
4505c91076SPawel Jakub Dawidek 
4605c91076SPawel Jakub Dawidek #include "misc/subr.h"
4705c91076SPawel Jakub Dawidek 
4805c91076SPawel Jakub Dawidek 
4905c91076SPawel Jakub Dawidek struct std_metadata {
5005c91076SPawel Jakub Dawidek 	char		md_magic[16];
5105c91076SPawel Jakub Dawidek 	uint32_t	md_version;
5205c91076SPawel Jakub Dawidek };
5305c91076SPawel Jakub Dawidek 
5405c91076SPawel Jakub Dawidek static void
5505c91076SPawel Jakub Dawidek std_metadata_decode(const u_char *data, struct std_metadata *md)
5605c91076SPawel Jakub Dawidek {
5705c91076SPawel Jakub Dawidek 
5805c91076SPawel Jakub Dawidek         bcopy(data, md->md_magic, sizeof(md->md_magic));
5905c91076SPawel Jakub Dawidek         md->md_version = le32dec(data + 16);
6005c91076SPawel Jakub Dawidek }
6105c91076SPawel Jakub Dawidek 
6205c91076SPawel Jakub Dawidek static void
6305c91076SPawel Jakub Dawidek pathgen(const char *name, char *path, size_t size)
6405c91076SPawel Jakub Dawidek {
6505c91076SPawel Jakub Dawidek 
6605c91076SPawel Jakub Dawidek 	if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) != 0)
6705c91076SPawel Jakub Dawidek 		snprintf(path, size, "%s%s", _PATH_DEV, name);
6805c91076SPawel Jakub Dawidek 	else
6905c91076SPawel Jakub Dawidek 		strlcpy(path, name, size);
7005c91076SPawel Jakub Dawidek }
7105c91076SPawel Jakub Dawidek 
7209cc9ab6SPawel Jakub Dawidek /*
7309cc9ab6SPawel Jakub Dawidek  * Greatest Common Divisor.
7409cc9ab6SPawel Jakub Dawidek  */
7509cc9ab6SPawel Jakub Dawidek static unsigned
7609cc9ab6SPawel Jakub Dawidek gcd(unsigned a, unsigned b)
7709cc9ab6SPawel Jakub Dawidek {
7809cc9ab6SPawel Jakub Dawidek 	u_int c;
7909cc9ab6SPawel Jakub Dawidek 
8009cc9ab6SPawel Jakub Dawidek 	while (b != 0) {
8109cc9ab6SPawel Jakub Dawidek 		c = a;
8209cc9ab6SPawel Jakub Dawidek 		a = b;
8309cc9ab6SPawel Jakub Dawidek 		b = (c % b);
8409cc9ab6SPawel Jakub Dawidek 	}
8509cc9ab6SPawel Jakub Dawidek 	return (a);
8609cc9ab6SPawel Jakub Dawidek }
8709cc9ab6SPawel Jakub Dawidek 
8809cc9ab6SPawel Jakub Dawidek /*
8909cc9ab6SPawel Jakub Dawidek  * Least Common Multiple.
9009cc9ab6SPawel Jakub Dawidek  */
9109cc9ab6SPawel Jakub Dawidek unsigned
9209cc9ab6SPawel Jakub Dawidek g_lcm(unsigned a, unsigned b)
9309cc9ab6SPawel Jakub Dawidek {
9409cc9ab6SPawel Jakub Dawidek 
9509cc9ab6SPawel Jakub Dawidek 	return ((a * b) / gcd(a, b));
9609cc9ab6SPawel Jakub Dawidek }
9709cc9ab6SPawel Jakub Dawidek 
9882978104SPawel Jakub Dawidek uint32_t
9982978104SPawel Jakub Dawidek bitcount32(uint32_t x)
10082978104SPawel Jakub Dawidek {
10182978104SPawel Jakub Dawidek 
10282978104SPawel Jakub Dawidek 	x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
10382978104SPawel Jakub Dawidek 	x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
10482978104SPawel Jakub Dawidek 	x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
10582978104SPawel Jakub Dawidek 	x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
10682978104SPawel Jakub Dawidek 	x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
10782978104SPawel Jakub Dawidek 	return (x);
10882978104SPawel Jakub Dawidek }
10982978104SPawel Jakub Dawidek 
11009cc9ab6SPawel Jakub Dawidek off_t
11109cc9ab6SPawel Jakub Dawidek g_get_mediasize(const char *name)
11209cc9ab6SPawel Jakub Dawidek {
11309cc9ab6SPawel Jakub Dawidek 	char path[MAXPATHLEN];
11409cc9ab6SPawel Jakub Dawidek 	off_t mediasize;
11509cc9ab6SPawel Jakub Dawidek 	int fd;
11609cc9ab6SPawel Jakub Dawidek 
11709cc9ab6SPawel Jakub Dawidek 	pathgen(name, path, sizeof(path));
11809cc9ab6SPawel Jakub Dawidek 	fd = open(path, O_RDONLY);
11909cc9ab6SPawel Jakub Dawidek 	if (fd == -1)
12009cc9ab6SPawel Jakub Dawidek 		return (0);
12109cc9ab6SPawel Jakub Dawidek 	if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) {
12209cc9ab6SPawel Jakub Dawidek 		close(fd);
12309cc9ab6SPawel Jakub Dawidek 		return (0);
12409cc9ab6SPawel Jakub Dawidek 	}
12509cc9ab6SPawel Jakub Dawidek 	close(fd);
12609cc9ab6SPawel Jakub Dawidek 	return (mediasize);
12709cc9ab6SPawel Jakub Dawidek }
12809cc9ab6SPawel Jakub Dawidek 
12909cc9ab6SPawel Jakub Dawidek unsigned
13009cc9ab6SPawel Jakub Dawidek g_get_sectorsize(const char *name)
13109cc9ab6SPawel Jakub Dawidek {
13209cc9ab6SPawel Jakub Dawidek 	char path[MAXPATHLEN];
13309cc9ab6SPawel Jakub Dawidek 	unsigned sectorsize;
13409cc9ab6SPawel Jakub Dawidek 	int fd;
13509cc9ab6SPawel Jakub Dawidek 
13609cc9ab6SPawel Jakub Dawidek 	pathgen(name, path, sizeof(path));
13709cc9ab6SPawel Jakub Dawidek 	fd = open(path, O_RDONLY);
13809cc9ab6SPawel Jakub Dawidek 	if (fd == -1)
13909cc9ab6SPawel Jakub Dawidek 		return (0);
14009cc9ab6SPawel Jakub Dawidek 	if (ioctl(fd, DIOCGSECTORSIZE, &sectorsize) < 0) {
14109cc9ab6SPawel Jakub Dawidek 		close(fd);
14209cc9ab6SPawel Jakub Dawidek 		return (0);
14309cc9ab6SPawel Jakub Dawidek 	}
14409cc9ab6SPawel Jakub Dawidek 	close(fd);
14509cc9ab6SPawel Jakub Dawidek 	return (sectorsize);
14609cc9ab6SPawel Jakub Dawidek }
14709cc9ab6SPawel Jakub Dawidek 
14805c91076SPawel Jakub Dawidek int
14910fa0ebeSPawel Jakub Dawidek g_metadata_read(const char *name, u_char *md, size_t size, const char *magic)
15010fa0ebeSPawel Jakub Dawidek {
15110fa0ebeSPawel Jakub Dawidek 	struct std_metadata stdmd;
15210fa0ebeSPawel Jakub Dawidek 	char path[MAXPATHLEN];
15310fa0ebeSPawel Jakub Dawidek 	unsigned sectorsize;
15410fa0ebeSPawel Jakub Dawidek 	off_t mediasize;
15510fa0ebeSPawel Jakub Dawidek 	u_char *sector;
15610fa0ebeSPawel Jakub Dawidek 	int error, fd;
15710fa0ebeSPawel Jakub Dawidek 
15810fa0ebeSPawel Jakub Dawidek 	pathgen(name, path, sizeof(path));
15910fa0ebeSPawel Jakub Dawidek 	sector = NULL;
16010fa0ebeSPawel Jakub Dawidek 	error = 0;
16110fa0ebeSPawel Jakub Dawidek 
16210fa0ebeSPawel Jakub Dawidek 	fd = open(path, O_RDONLY);
16310fa0ebeSPawel Jakub Dawidek 	if (fd == -1)
16410fa0ebeSPawel Jakub Dawidek 		return (errno);
16510fa0ebeSPawel Jakub Dawidek 	mediasize = g_get_mediasize(name);
16610fa0ebeSPawel Jakub Dawidek 	if (mediasize == 0) {
16710fa0ebeSPawel Jakub Dawidek 		error = errno;
16810fa0ebeSPawel Jakub Dawidek 		goto out;
16910fa0ebeSPawel Jakub Dawidek 	}
17010fa0ebeSPawel Jakub Dawidek 	sectorsize = g_get_sectorsize(name);
17110fa0ebeSPawel Jakub Dawidek 	if (sectorsize == 0) {
17210fa0ebeSPawel Jakub Dawidek 		error = errno;
17310fa0ebeSPawel Jakub Dawidek 		goto out;
17410fa0ebeSPawel Jakub Dawidek 	}
17510fa0ebeSPawel Jakub Dawidek 	assert(sectorsize >= size);
17610fa0ebeSPawel Jakub Dawidek 	sector = malloc(sectorsize);
17710fa0ebeSPawel Jakub Dawidek 	if (sector == NULL) {
17810fa0ebeSPawel Jakub Dawidek 		error = ENOMEM;
17910fa0ebeSPawel Jakub Dawidek 		goto out;
18010fa0ebeSPawel Jakub Dawidek 	}
18110fa0ebeSPawel Jakub Dawidek 	if (pread(fd, sector, sectorsize, mediasize - sectorsize) !=
18210fa0ebeSPawel Jakub Dawidek 	    (ssize_t)sectorsize) {
18310fa0ebeSPawel Jakub Dawidek 		error = errno;
18410fa0ebeSPawel Jakub Dawidek 		goto out;
18510fa0ebeSPawel Jakub Dawidek 	}
18610fa0ebeSPawel Jakub Dawidek 	if (magic != NULL) {
18710fa0ebeSPawel Jakub Dawidek 		std_metadata_decode(sector, &stdmd);
18810fa0ebeSPawel Jakub Dawidek 		if (strcmp(stdmd.md_magic, magic) != 0) {
18910fa0ebeSPawel Jakub Dawidek 			error = EINVAL;
19010fa0ebeSPawel Jakub Dawidek 			goto out;
19110fa0ebeSPawel Jakub Dawidek 		}
19210fa0ebeSPawel Jakub Dawidek 	}
19310fa0ebeSPawel Jakub Dawidek 	bcopy(sector, md, size);
19410fa0ebeSPawel Jakub Dawidek out:
19510fa0ebeSPawel Jakub Dawidek 	if (sector != NULL)
19610fa0ebeSPawel Jakub Dawidek 		free(sector);
19710fa0ebeSPawel Jakub Dawidek 	close(fd);
19810fa0ebeSPawel Jakub Dawidek 	return (error);
19910fa0ebeSPawel Jakub Dawidek }
20010fa0ebeSPawel Jakub Dawidek 
20110fa0ebeSPawel Jakub Dawidek int
20205c91076SPawel Jakub Dawidek g_metadata_store(const char *name, u_char *md, size_t size)
20305c91076SPawel Jakub Dawidek {
20405c91076SPawel Jakub Dawidek 	char path[MAXPATHLEN];
20505c91076SPawel Jakub Dawidek 	unsigned sectorsize;
20605c91076SPawel Jakub Dawidek 	off_t mediasize;
20705c91076SPawel Jakub Dawidek 	u_char *sector;
20805c91076SPawel Jakub Dawidek 	int error, fd;
20905c91076SPawel Jakub Dawidek 
21005c91076SPawel Jakub Dawidek 	pathgen(name, path, sizeof(path));
21105c91076SPawel Jakub Dawidek 	sector = NULL;
21205c91076SPawel Jakub Dawidek 	error = 0;
21305c91076SPawel Jakub Dawidek 
21405c91076SPawel Jakub Dawidek 	fd = open(path, O_WRONLY);
21505c91076SPawel Jakub Dawidek 	if (fd == -1)
21605c91076SPawel Jakub Dawidek 		return (errno);
21709cc9ab6SPawel Jakub Dawidek 	mediasize = g_get_mediasize(name);
21809cc9ab6SPawel Jakub Dawidek 	if (mediasize == 0) {
21905c91076SPawel Jakub Dawidek 		error = errno;
22005c91076SPawel Jakub Dawidek 		goto out;
22105c91076SPawel Jakub Dawidek 	}
22209cc9ab6SPawel Jakub Dawidek 	sectorsize = g_get_sectorsize(name);
22309cc9ab6SPawel Jakub Dawidek 	if (sectorsize == 0) {
22405c91076SPawel Jakub Dawidek 		error = errno;
22505c91076SPawel Jakub Dawidek 		goto out;
22605c91076SPawel Jakub Dawidek 	}
22705c91076SPawel Jakub Dawidek 	assert(sectorsize >= size);
22805c91076SPawel Jakub Dawidek 	sector = malloc(sectorsize);
22905c91076SPawel Jakub Dawidek 	if (sector == NULL) {
23005c91076SPawel Jakub Dawidek 		error = ENOMEM;
23105c91076SPawel Jakub Dawidek 		goto out;
23205c91076SPawel Jakub Dawidek 	}
23305c91076SPawel Jakub Dawidek 	bcopy(md, sector, size);
23405c91076SPawel Jakub Dawidek 	if (pwrite(fd, sector, sectorsize, mediasize - sectorsize) !=
23505c91076SPawel Jakub Dawidek 	    (ssize_t)sectorsize) {
23605c91076SPawel Jakub Dawidek 		error = errno;
23705c91076SPawel Jakub Dawidek 		goto out;
23805c91076SPawel Jakub Dawidek 	}
23905c91076SPawel Jakub Dawidek out:
24005c91076SPawel Jakub Dawidek 	if (sector != NULL)
24105c91076SPawel Jakub Dawidek 		free(sector);
24205c91076SPawel Jakub Dawidek 	close(fd);
24305c91076SPawel Jakub Dawidek 	return (error);
24405c91076SPawel Jakub Dawidek }
24505c91076SPawel Jakub Dawidek 
24605c91076SPawel Jakub Dawidek int
24705c91076SPawel Jakub Dawidek g_metadata_clear(const char *name, const char *magic)
24805c91076SPawel Jakub Dawidek {
24905c91076SPawel Jakub Dawidek 	struct std_metadata md;
25005c91076SPawel Jakub Dawidek 	char path[MAXPATHLEN];
25105c91076SPawel Jakub Dawidek 	unsigned sectorsize;
25205c91076SPawel Jakub Dawidek 	off_t mediasize;
25305c91076SPawel Jakub Dawidek 	u_char *sector;
25405c91076SPawel Jakub Dawidek 	int error, fd;
25505c91076SPawel Jakub Dawidek 
25605c91076SPawel Jakub Dawidek 	pathgen(name, path, sizeof(path));
25705c91076SPawel Jakub Dawidek 	sector = NULL;
25805c91076SPawel Jakub Dawidek 	error = 0;
25905c91076SPawel Jakub Dawidek 
26005c91076SPawel Jakub Dawidek 	fd = open(path, O_RDWR);
26105c91076SPawel Jakub Dawidek 	if (fd == -1)
26205c91076SPawel Jakub Dawidek 		return (errno);
26309cc9ab6SPawel Jakub Dawidek 	mediasize = g_get_mediasize(name);
26409cc9ab6SPawel Jakub Dawidek 	if (mediasize == 0) {
26505c91076SPawel Jakub Dawidek 		error = errno;
26605c91076SPawel Jakub Dawidek 		goto out;
26705c91076SPawel Jakub Dawidek 	}
26809cc9ab6SPawel Jakub Dawidek 	sectorsize = g_get_sectorsize(name);
26909cc9ab6SPawel Jakub Dawidek 	if (sectorsize == 0) {
27005c91076SPawel Jakub Dawidek 		error = errno;
27105c91076SPawel Jakub Dawidek 		goto out;
27205c91076SPawel Jakub Dawidek 	}
27305c91076SPawel Jakub Dawidek 	sector = malloc(sectorsize);
27405c91076SPawel Jakub Dawidek 	if (sector == NULL) {
27505c91076SPawel Jakub Dawidek 		error = ENOMEM;
27605c91076SPawel Jakub Dawidek 		goto out;
27705c91076SPawel Jakub Dawidek 	}
27805c91076SPawel Jakub Dawidek 	if (magic != NULL) {
27905c91076SPawel Jakub Dawidek 		if (pread(fd, sector, sectorsize, mediasize - sectorsize) !=
28005c91076SPawel Jakub Dawidek 		    (ssize_t)sectorsize) {
28105c91076SPawel Jakub Dawidek 			error = errno;
28205c91076SPawel Jakub Dawidek 			goto out;
28305c91076SPawel Jakub Dawidek 		}
28405c91076SPawel Jakub Dawidek 		std_metadata_decode(sector, &md);
28505c91076SPawel Jakub Dawidek 		if (strcmp(md.md_magic, magic) != 0) {
28605c91076SPawel Jakub Dawidek 			error = EINVAL;
28705c91076SPawel Jakub Dawidek 			goto out;
28805c91076SPawel Jakub Dawidek 		}
28905c91076SPawel Jakub Dawidek 	}
29005c91076SPawel Jakub Dawidek 	bzero(sector, sectorsize);
29105c91076SPawel Jakub Dawidek 	if (pwrite(fd, sector, sectorsize, mediasize - sectorsize) !=
29205c91076SPawel Jakub Dawidek 	    (ssize_t)sectorsize) {
29305c91076SPawel Jakub Dawidek 		error = errno;
29405c91076SPawel Jakub Dawidek 		goto out;
29505c91076SPawel Jakub Dawidek 	}
29605c91076SPawel Jakub Dawidek out:
29705c91076SPawel Jakub Dawidek 	if (sector != NULL)
29805c91076SPawel Jakub Dawidek 		free(sector);
29905c91076SPawel Jakub Dawidek 	close(fd);
30005c91076SPawel Jakub Dawidek 	return (error);
30105c91076SPawel Jakub Dawidek }
30205c91076SPawel Jakub Dawidek 
30305c91076SPawel Jakub Dawidek /*
30405c91076SPawel Jakub Dawidek  * Set an error message, if one does not already exist.
30505c91076SPawel Jakub Dawidek  */
30605c91076SPawel Jakub Dawidek void
30705c91076SPawel Jakub Dawidek gctl_error(struct gctl_req *req, const char *error, ...)
30805c91076SPawel Jakub Dawidek {
30905c91076SPawel Jakub Dawidek 	va_list ap;
31005c91076SPawel Jakub Dawidek 
31105c91076SPawel Jakub Dawidek 	if (req->error != NULL)
31205c91076SPawel Jakub Dawidek 		return;
31305c91076SPawel Jakub Dawidek 	va_start(ap, error);
31405c91076SPawel Jakub Dawidek 	vasprintf(&req->error, error, ap);
31505c91076SPawel Jakub Dawidek 	va_end(ap);
31605c91076SPawel Jakub Dawidek }
31705c91076SPawel Jakub Dawidek 
318f13942a7SPawel Jakub Dawidek static void *
319f13942a7SPawel Jakub Dawidek gctl_get_param(struct gctl_req *req, size_t len, const char *pfmt, va_list ap)
32005c91076SPawel Jakub Dawidek {
321f13942a7SPawel Jakub Dawidek 	struct gctl_req_arg *argp;
322f13942a7SPawel Jakub Dawidek 	char param[256];
32305c91076SPawel Jakub Dawidek 	void *p;
32405c91076SPawel Jakub Dawidek 	unsigned i;
32505c91076SPawel Jakub Dawidek 
326f13942a7SPawel Jakub Dawidek 	vsnprintf(param, sizeof(param), pfmt, ap);
32705c91076SPawel Jakub Dawidek 	for (i = 0; i < req->narg; i++) {
328f13942a7SPawel Jakub Dawidek 		argp = &req->arg[i];
329f13942a7SPawel Jakub Dawidek 		if (strcmp(param, argp->name))
33005c91076SPawel Jakub Dawidek 			continue;
331f13942a7SPawel Jakub Dawidek 		if (!(argp->flag & GCTL_PARAM_RD))
33205c91076SPawel Jakub Dawidek 			continue;
333f13942a7SPawel Jakub Dawidek 		p = argp->value;
334f13942a7SPawel Jakub Dawidek 		if (len == 0) {
335f13942a7SPawel Jakub Dawidek 			/* We are looking for a string. */
336f13942a7SPawel Jakub Dawidek 			if (argp->len < 1) {
337f13942a7SPawel Jakub Dawidek 				fprintf(stderr, "No length argument (%s).\n",
338f13942a7SPawel Jakub Dawidek 				    param);
339f13942a7SPawel Jakub Dawidek 				abort();
34005c91076SPawel Jakub Dawidek 			}
341f13942a7SPawel Jakub Dawidek 			if (((char *)p)[argp->len - 1] != '\0') {
342f13942a7SPawel Jakub Dawidek 				fprintf(stderr, "Unterminated argument (%s).\n",
343f13942a7SPawel Jakub Dawidek 				    param);
344f13942a7SPawel Jakub Dawidek 				abort();
345f13942a7SPawel Jakub Dawidek 			}
346f13942a7SPawel Jakub Dawidek 		} else if ((int)len != argp->len) {
347f13942a7SPawel Jakub Dawidek 			fprintf(stderr, "Wrong length %s argument.\n", param);
348f13942a7SPawel Jakub Dawidek 			abort();
34905c91076SPawel Jakub Dawidek 		}
35005c91076SPawel Jakub Dawidek 		return (p);
35105c91076SPawel Jakub Dawidek 	}
352f13942a7SPawel Jakub Dawidek 	fprintf(stderr, "No such argument (%s).\n", param);
353f13942a7SPawel Jakub Dawidek 	abort();
35405c91076SPawel Jakub Dawidek }
35505c91076SPawel Jakub Dawidek 
356f13942a7SPawel Jakub Dawidek int
357f13942a7SPawel Jakub Dawidek gctl_get_int(struct gctl_req *req, const char *pfmt, ...)
35805c91076SPawel Jakub Dawidek {
359f13942a7SPawel Jakub Dawidek 	int *p;
360f13942a7SPawel Jakub Dawidek 	va_list ap;
36105c91076SPawel Jakub Dawidek 
362f13942a7SPawel Jakub Dawidek 	va_start(ap, pfmt);
363f13942a7SPawel Jakub Dawidek 	p = gctl_get_param(req, sizeof(int), pfmt, ap);
364f13942a7SPawel Jakub Dawidek 	va_end(ap);
365f13942a7SPawel Jakub Dawidek 	return (*p);
36605c91076SPawel Jakub Dawidek }
367f13942a7SPawel Jakub Dawidek 
368f13942a7SPawel Jakub Dawidek intmax_t
369f13942a7SPawel Jakub Dawidek gctl_get_intmax(struct gctl_req *req, const char *pfmt, ...)
370f13942a7SPawel Jakub Dawidek {
371f13942a7SPawel Jakub Dawidek 	intmax_t *p;
372f13942a7SPawel Jakub Dawidek 	va_list ap;
373f13942a7SPawel Jakub Dawidek 
374f13942a7SPawel Jakub Dawidek 	va_start(ap, pfmt);
375f13942a7SPawel Jakub Dawidek 	p = gctl_get_param(req, sizeof(intmax_t), pfmt, ap);
376f13942a7SPawel Jakub Dawidek 	va_end(ap);
377f13942a7SPawel Jakub Dawidek 	return (*p);
378f13942a7SPawel Jakub Dawidek }
379f13942a7SPawel Jakub Dawidek 
380f13942a7SPawel Jakub Dawidek const char *
381f13942a7SPawel Jakub Dawidek gctl_get_ascii(struct gctl_req *req, const char *pfmt, ...)
382f13942a7SPawel Jakub Dawidek {
383f13942a7SPawel Jakub Dawidek 	const char *p;
384f13942a7SPawel Jakub Dawidek 	va_list ap;
385f13942a7SPawel Jakub Dawidek 
386f13942a7SPawel Jakub Dawidek 	va_start(ap, pfmt);
387f13942a7SPawel Jakub Dawidek 	p = gctl_get_param(req, 0, pfmt, ap);
388f13942a7SPawel Jakub Dawidek 	va_end(ap);
38905c91076SPawel Jakub Dawidek 	return (p);
39005c91076SPawel Jakub Dawidek }
391