1 1.1 christos /*- 2 1.1 christos * Copyright (c) 2005 Marcel Moolenaar 3 1.1 christos * All rights reserved. 4 1.1 christos * 5 1.1 christos * Redistribution and use in source and binary forms, with or without 6 1.1 christos * modification, are permitted provided that the following conditions 7 1.1 christos * are met: 8 1.1 christos * 9 1.1 christos * 1. Redistributions of source code must retain the above copyright 10 1.1 christos * notice, this list of conditions and the following disclaimer. 11 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 christos * notice, this list of conditions and the following disclaimer in the 13 1.1 christos * documentation and/or other materials provided with the distribution. 14 1.1 christos * 15 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 1.1 christos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 1.1 christos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 1.1 christos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 1.1 christos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 1.1 christos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 1.1 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 1.1 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 1.1 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 1.1 christos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 1.1 christos */ 26 1.1 christos 27 1.16 christos #if HAVE_NBTOOL_CONFIG_H 28 1.16 christos #include "nbtool_config.h" 29 1.16 christos #endif 30 1.16 christos 31 1.1 christos #include <sys/cdefs.h> 32 1.2 christos #ifdef __FBSDID 33 1.1 christos __FBSDID("$FreeBSD: src/sbin/gpt/label.c,v 1.3 2006/10/04 18:20:25 marcel Exp $"); 34 1.2 christos #endif 35 1.2 christos #ifdef __RCSID 36 1.31 christos __RCSID("$NetBSD: label.c,v 1.31 2025/02/23 20:47:19 christos Exp $"); 37 1.2 christos #endif 38 1.1 christos 39 1.1 christos #include <sys/types.h> 40 1.1 christos 41 1.1 christos #include <err.h> 42 1.1 christos #include <stddef.h> 43 1.1 christos #include <stdio.h> 44 1.1 christos #include <stdlib.h> 45 1.1 christos #include <string.h> 46 1.1 christos #include <unistd.h> 47 1.1 christos 48 1.1 christos #include "map.h" 49 1.1 christos #include "gpt.h" 50 1.20 christos #include "gpt_private.h" 51 1.18 christos #include "gpt_uuid.h" 52 1.1 christos 53 1.21 christos static int cmd_label(gpt_t, int, char *[]); 54 1.5 riz 55 1.21 christos static const char *labelhelp[] = { 56 1.25 christos "-a <-l label | -f file>", 57 1.25 christos "[-b blocknr] [-i index] [-L label] [-s sectors] [-t uuid] " 58 1.25 christos "<-l label | -f file>", 59 1.21 christos }; 60 1.21 christos 61 1.31 christos const struct gpt_cmd c_label = { 62 1.21 christos "label", 63 1.21 christos cmd_label, 64 1.21 christos labelhelp, __arraycount(labelhelp), 65 1.29 jnemeth GPT_SYNC, 66 1.21 christos }; 67 1.21 christos 68 1.21 christos #define usage() gpt_usage(NULL, &c_label) 69 1.1 christos 70 1.22 christos static void 71 1.31 christos change(struct gpt_ent *ent, void *v, int backup __unused) 72 1.1 christos { 73 1.22 christos uint8_t *name = v; 74 1.24 christos utf8_to_utf16(name, ent->ent_name, __arraycount(ent->ent_name)); 75 1.1 christos } 76 1.1 christos 77 1.23 christos static int 78 1.23 christos name_from_file(gpt_t gpt, void *v) 79 1.1 christos { 80 1.1 christos FILE *f; 81 1.1 christos char *p; 82 1.1 christos size_t maxlen = 1024; 83 1.1 christos size_t len; 84 1.23 christos const char *fn = optarg; 85 1.23 christos char **name = v; 86 1.23 christos 87 1.23 christos if (*name != NULL) 88 1.23 christos return -1; 89 1.1 christos 90 1.1 christos if (strcmp(fn, "-") != 0) { 91 1.1 christos f = fopen(fn, "r"); 92 1.23 christos if (f == NULL) { 93 1.23 christos gpt_warn(gpt, "Can't open `%s'", fn); 94 1.23 christos return -1; 95 1.23 christos } 96 1.1 christos } else 97 1.1 christos f = stdin; 98 1.23 christos 99 1.23 christos if ((*name = malloc(maxlen)) == NULL) { 100 1.23 christos gpt_warn(gpt, "Can't copy string"); 101 1.26 christos goto cleanup; 102 1.23 christos } 103 1.23 christos len = fread(*name, 1, maxlen - 1, f); 104 1.23 christos if (ferror(f)) { 105 1.23 christos gpt_warn(gpt, "Can't label from `%s'", fn); 106 1.26 christos goto cleanup; 107 1.23 christos } 108 1.1 christos if (f != stdin) 109 1.1 christos fclose(f); 110 1.23 christos (*name)[len] = '\0'; 111 1.1 christos /* Only keep the first line, excluding the newline character. */ 112 1.23 christos p = strchr(*name, '\n'); 113 1.1 christos if (p != NULL) 114 1.1 christos *p = '\0'; 115 1.23 christos return 0; 116 1.26 christos cleanup: 117 1.26 christos free(*name); 118 1.26 christos if (f != stdin) 119 1.26 christos fclose(f); 120 1.26 christos return -1; 121 1.1 christos } 122 1.1 christos 123 1.21 christos static int 124 1.20 christos cmd_label(gpt_t gpt, int argc, char *argv[]) 125 1.1 christos { 126 1.20 christos int ch; 127 1.22 christos struct gpt_find find; 128 1.22 christos char *name = NULL; 129 1.22 christos 130 1.22 christos memset(&find, 0, sizeof(find)); 131 1.22 christos find.msg = "label changed"; 132 1.1 christos 133 1.1 christos /* Get the label options */ 134 1.22 christos while ((ch = getopt(argc, argv, GPT_FIND "f:l:")) != -1) { 135 1.1 christos switch(ch) { 136 1.1 christos case 'f': 137 1.23 christos if (name_from_file(gpt, &name) == -1) 138 1.27 christos goto usage; 139 1.15 jnemeth break; 140 1.1 christos case 'l': 141 1.23 christos if (gpt_name_get(gpt, &name) == -1) 142 1.27 christos goto usage; 143 1.1 christos break; 144 1.31 christos case 'L': 145 1.31 christos case 'a': 146 1.31 christos case 'b': 147 1.31 christos case 'i': 148 1.31 christos case 's': 149 1.31 christos case 't': 150 1.22 christos if (gpt_add_find(gpt, &find, ch) == -1) 151 1.27 christos goto usage; 152 1.1 christos break; 153 1.31 christos default: 154 1.31 christos goto usage; 155 1.1 christos } 156 1.1 christos } 157 1.1 christos 158 1.20 christos if (name == NULL || argc != optind) 159 1.27 christos goto usage; 160 1.1 christos 161 1.22 christos return gpt_change_ent(gpt, &find, change, name); 162 1.27 christos usage: 163 1.28 christos usage(); 164 1.27 christos free(name); 165 1.27 christos return -1; 166 1.1 christos } 167