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