xref: /netbsd-src/sbin/gpt/label.c (revision e003a26f4c045a107e32f411093c2c6729750c7c)
15819a8c0Schristos /*-
25819a8c0Schristos  * Copyright (c) 2005 Marcel Moolenaar
35819a8c0Schristos  * All rights reserved.
45819a8c0Schristos  *
55819a8c0Schristos  * Redistribution and use in source and binary forms, with or without
65819a8c0Schristos  * modification, are permitted provided that the following conditions
75819a8c0Schristos  * are met:
85819a8c0Schristos  *
95819a8c0Schristos  * 1. Redistributions of source code must retain the above copyright
105819a8c0Schristos  *    notice, this list of conditions and the following disclaimer.
115819a8c0Schristos  * 2. Redistributions in binary form must reproduce the above copyright
125819a8c0Schristos  *    notice, this list of conditions and the following disclaimer in the
135819a8c0Schristos  *    documentation and/or other materials provided with the distribution.
145819a8c0Schristos  *
155819a8c0Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
165819a8c0Schristos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
175819a8c0Schristos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
185819a8c0Schristos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
195819a8c0Schristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
205819a8c0Schristos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
215819a8c0Schristos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
225819a8c0Schristos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235819a8c0Schristos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
245819a8c0Schristos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255819a8c0Schristos  */
265819a8c0Schristos 
27a50708a1Schristos #if HAVE_NBTOOL_CONFIG_H
28a50708a1Schristos #include "nbtool_config.h"
29a50708a1Schristos #endif
30a50708a1Schristos 
315819a8c0Schristos #include <sys/cdefs.h>
329b522365Schristos #ifdef __FBSDID
335819a8c0Schristos __FBSDID("$FreeBSD: src/sbin/gpt/label.c,v 1.3 2006/10/04 18:20:25 marcel Exp $");
349b522365Schristos #endif
359b522365Schristos #ifdef __RCSID
36*e003a26fSjnemeth __RCSID("$NetBSD: label.c,v 1.30 2019/06/21 02:14:59 jnemeth Exp $");
379b522365Schristos #endif
385819a8c0Schristos 
395819a8c0Schristos #include <sys/types.h>
405819a8c0Schristos 
415819a8c0Schristos #include <err.h>
425819a8c0Schristos #include <stddef.h>
435819a8c0Schristos #include <stdio.h>
445819a8c0Schristos #include <stdlib.h>
455819a8c0Schristos #include <string.h>
465819a8c0Schristos #include <unistd.h>
475819a8c0Schristos 
485819a8c0Schristos #include "map.h"
495819a8c0Schristos #include "gpt.h"
500b43d398Schristos #include "gpt_private.h"
5121c34dbbSchristos #include "gpt_uuid.h"
525819a8c0Schristos 
538ca93e46Schristos static int cmd_label(gpt_t, int, char *[]);
540fac2edbSriz 
558ca93e46Schristos static const char *labelhelp[] = {
568ca93e46Schristos 	"-a <-l label | -f file>",
57da0a3b4cSchristos 	"[-b blocknr] [-i index] [-L label] [-s sectors] [-t uuid] "
58da0a3b4cSchristos 	    "<-l label | -f file>",
598ca93e46Schristos };
608ca93e46Schristos 
618ca93e46Schristos struct gpt_cmd c_label = {
628ca93e46Schristos 	"label",
638ca93e46Schristos 	cmd_label,
648ca93e46Schristos 	labelhelp, __arraycount(labelhelp),
65aa3b5bb2Sjnemeth 	GPT_SYNC,
668ca93e46Schristos };
678ca93e46Schristos 
688ca93e46Schristos #define usage() gpt_usage(NULL, &c_label)
695819a8c0Schristos 
705819a8c0Schristos static void
change(struct gpt_ent * ent,void * v,int backup)71*e003a26fSjnemeth change(struct gpt_ent *ent, void *v, int backup)
72bbb4a8abSchristos {
73bbb4a8abSchristos 	uint8_t *name = v;
74cdf86847Schristos 	utf8_to_utf16(name, ent->ent_name, __arraycount(ent->ent_name));
75bbb4a8abSchristos }
76bbb4a8abSchristos 
770f004afeSchristos static int
name_from_file(gpt_t gpt,void * v)780f004afeSchristos name_from_file(gpt_t gpt, void *v)
795819a8c0Schristos {
805819a8c0Schristos 	FILE *f;
815819a8c0Schristos 	char *p;
825819a8c0Schristos 	size_t maxlen = 1024;
835819a8c0Schristos 	size_t len;
840f004afeSchristos 	const char *fn = optarg;
850f004afeSchristos 	char **name = v;
860f004afeSchristos 
870f004afeSchristos 	if (*name != NULL)
880f004afeSchristos 		return -1;
895819a8c0Schristos 
905819a8c0Schristos 	if (strcmp(fn, "-") != 0) {
915819a8c0Schristos 		f = fopen(fn, "r");
920f004afeSchristos 		if (f == NULL) {
930f004afeSchristos 			gpt_warn(gpt, "Can't open `%s'", fn);
940f004afeSchristos 			return -1;
950f004afeSchristos 		}
965819a8c0Schristos 	} else
975819a8c0Schristos 		f = stdin;
980f004afeSchristos 
990f004afeSchristos 	if ((*name = malloc(maxlen)) == NULL) {
1000f004afeSchristos 		gpt_warn(gpt, "Can't copy string");
101b58e9ed6Schristos 		goto cleanup;
1020f004afeSchristos 	}
1030f004afeSchristos 	len = fread(*name, 1, maxlen - 1, f);
1040f004afeSchristos 	if (ferror(f)) {
1050f004afeSchristos 		gpt_warn(gpt, "Can't label from `%s'", fn);
106b58e9ed6Schristos 		goto cleanup;
1070f004afeSchristos 	}
1085819a8c0Schristos 	if (f != stdin)
1095819a8c0Schristos 		fclose(f);
1100f004afeSchristos 	(*name)[len] = '\0';
1115819a8c0Schristos 	/* Only keep the first line, excluding the newline character. */
1120f004afeSchristos 	p = strchr(*name, '\n');
1135819a8c0Schristos 	if (p != NULL)
1145819a8c0Schristos 		*p = '\0';
1150f004afeSchristos 	return 0;
116b58e9ed6Schristos cleanup:
117b58e9ed6Schristos 	free(*name);
118b58e9ed6Schristos 	if (f != stdin)
119b58e9ed6Schristos 		fclose(f);
120b58e9ed6Schristos 	return -1;
1215819a8c0Schristos }
1225819a8c0Schristos 
1238ca93e46Schristos static int
cmd_label(gpt_t gpt,int argc,char * argv[])1240b43d398Schristos cmd_label(gpt_t gpt, int argc, char *argv[])
1255819a8c0Schristos {
1260b43d398Schristos 	int ch;
127bbb4a8abSchristos 	struct gpt_find find;
128bbb4a8abSchristos 	char *name = NULL;
129bbb4a8abSchristos 
130bbb4a8abSchristos 	memset(&find, 0, sizeof(find));
131bbb4a8abSchristos 	find.msg = "label changed";
1325819a8c0Schristos 
1335819a8c0Schristos 	/* Get the label options */
134bbb4a8abSchristos 	while ((ch = getopt(argc, argv, GPT_FIND "f:l:")) != -1) {
1355819a8c0Schristos 		switch(ch) {
1365819a8c0Schristos 		case 'f':
1370f004afeSchristos 			if (name_from_file(gpt, &name) == -1)
138e3058c5eSchristos 				goto usage;
139ac204e48Sjnemeth 			break;
1405819a8c0Schristos 		case 'l':
1410f004afeSchristos 			if (gpt_name_get(gpt, &name) == -1)
142e3058c5eSchristos 				goto usage;
1435819a8c0Schristos 			break;
1445819a8c0Schristos 		default:
145bbb4a8abSchristos 			if (gpt_add_find(gpt, &find, ch) == -1)
146e3058c5eSchristos 				goto usage;
147bbb4a8abSchristos 			break;
1485819a8c0Schristos 		}
1495819a8c0Schristos 	}
1505819a8c0Schristos 
1510b43d398Schristos 	if (name == NULL || argc != optind)
152e3058c5eSchristos 		goto usage;
1535819a8c0Schristos 
154bbb4a8abSchristos 	return gpt_change_ent(gpt, &find, change, name);
155e3058c5eSchristos usage:
156a69d504eSchristos 	usage();
157e3058c5eSchristos 	free(name);
158e3058c5eSchristos 	return -1;
1595819a8c0Schristos }
160