]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/swaplabel.c
Merge branch 'meson-more-build-options' of https://github.com/jwillikers/util-linux
[thirdparty/util-linux.git] / disk-utils / swaplabel.c
CommitLineData
4dddc2d4 1/*
9e95aa12
KZ
2 * SPDX-License-Identifier: GPL-2.0-or-later
3 *
4dddc2d4
JB
4 * swaplabel.c - Print or change the label / UUID of a swap partition
5 *
6 * Copyright (C) 2010 Jason Borden <jborden@bluehost.com>
7 * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
8 *
9 * Usage: swaplabel [-L label] [-U UUID] device
10 *
f4cb44bd 11 * This file may be redistributed under the terms of the GNU General Public License
4dddc2d4
JB
12 * version 2 or later.
13 *
14 */
15#include <stdio.h>
16#include <stddef.h>
17#include <string.h>
18#include <fcntl.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <unistd.h>
22#include <stdlib.h>
4dddc2d4
JB
23#include <getopt.h>
24
25#ifdef HAVE_LIBUUID
7ee96990 26# include <uuid.h>
4dddc2d4
JB
27#endif
28
29#include "c.h"
18b3e549 30#include "nls.h"
e12c9866 31#include "all-io.h"
8abcf290 32#include "strutils.h"
18b3e549
KZ
33#include "closestream.h"
34
35#include "swapheader.h"
36#include "swapprober.h"
4dddc2d4
JB
37
38#define SWAP_UUID_OFFSET (offsetof(struct swap_header_v1_2, uuid))
39#define SWAP_LABEL_OFFSET (offsetof(struct swap_header_v1_2, volume_name))
40
4dddc2d4 41/* Print the swap partition information */
ae7ec06b 42static int print_info(blkid_probe pr)
4dddc2d4
JB
43{
44 const char *data;
45
46 if (!blkid_probe_lookup_value(pr, "LABEL", &data, NULL))
47 printf("LABEL: %s\n", data);
48
49 if (!blkid_probe_lookup_value(pr, "UUID", &data, NULL))
50 printf("UUID: %s\n", data);
51
52 return 0;
53}
54
55/* Change the swap partition info */
3da94b11 56#ifdef HAVE_LIBUUID
4dddc2d4 57static int change_info(const char *devname, const char *label, const char *uuid)
3da94b11
KZ
58#else
59static int change_info(const char *devname, const char *label,
60 const char *uuid __attribute__((__unused__)))
61#endif
4dddc2d4
JB
62{
63 int fd;
64
65 fd = open(devname, O_RDWR);
66 if (fd < 0) {
289dcc90 67 warn(_("cannot open %s"), devname);
4dddc2d4
JB
68 goto err;
69 }
70#ifdef HAVE_LIBUUID
71 /* Write the uuid if it was provided */
72 if (uuid) {
73 uuid_t newuuid;
74
75 if (uuid_parse(uuid, newuuid) == -1)
76 warnx(_("failed to parse UUID: %s"), uuid);
77 else {
78 if (lseek(fd, SWAP_UUID_OFFSET, SEEK_SET) !=
79 SWAP_UUID_OFFSET) {
80 warn(_("%s: failed to seek to swap UUID"), devname);
81 goto err;
82
83 } else if (write_all(fd, newuuid, sizeof(newuuid))) {
84 warn(_("%s: failed to write UUID"), devname);
85 goto err;
86 }
87 }
88 }
89#endif
90 /* Write the label if it was provided */
91 if (label) {
92 char newlabel[SWAP_LABEL_LENGTH];
93
94 if (lseek(fd, SWAP_LABEL_OFFSET, SEEK_SET) != SWAP_LABEL_OFFSET) {
95 warn(_("%s: failed to seek to swap label "), devname);
96 goto err;
97 }
98 memset(newlabel, 0, sizeof(newlabel));
99 xstrncpy(newlabel, label, sizeof(newlabel));
100
101 if (strlen(label) > strlen(newlabel))
102 warnx(_("label is too long. Truncating it to '%s'"),
103 newlabel);
104 if (write_all(fd, newlabel, sizeof(newlabel))) {
105 warn(_("%s: failed to write label"), devname);
106 goto err;
107 }
108 }
109
de2ca559
SK
110 if (close_fd(fd) != 0) {
111 warn(_("write failed: %s"), devname);
112 return -1;
113 }
4dddc2d4
JB
114 return 0;
115err:
116 if (fd >= 0)
117 close(fd);
118 return -1;
119}
120
6e1eda6f 121static void __attribute__((__noreturn__)) usage(void)
4dddc2d4 122{
6e1eda6f 123 FILE *out = stdout;
1275d8a1
SK
124 fputs(USAGE_HEADER, out);
125 fprintf(out, _(" %s [options] <device>\n"),
126 program_invocation_short_name);
451dbcfa
BS
127
128 fputs(USAGE_SEPARATOR, out);
129 fputs(_("Display or change the label or UUID of a swap area.\n"), out);
130
1275d8a1
SK
131 fputs(USAGE_OPTIONS, out);
132 fputs(_(" -L, --label <label> specify a new label\n"
133 " -U, --uuid <uuid> specify a new uuid\n"), out);
134 fputs(USAGE_SEPARATOR, out);
bad4c729
MY
135 fprintf(out, USAGE_HELP_OPTIONS(21));
136 fprintf(out, USAGE_MAN_TAIL("swaplabel(8)"));
6e1eda6f 137 exit(EXIT_SUCCESS);
4dddc2d4
JB
138}
139
140int main(int argc, char *argv[])
141{
142 blkid_probe pr = NULL;
143 char *uuid = NULL, *label = NULL, *devname;
144 int c, rc = -1;
145
6c7d5ae9 146 static const struct option longopts[] = {
87918040
SK
147 { "help", no_argument, NULL, 'h' },
148 { "version", no_argument, NULL, 'V' },
149 { "label", required_argument, NULL, 'L' },
150 { "uuid", required_argument, NULL, 'U' },
151 { NULL, 0, NULL, 0 }
4dddc2d4
JB
152 };
153
154 setlocale(LC_ALL, "");
155 bindtextdomain(PACKAGE, LOCALEDIR);
156 textdomain(PACKAGE);
2c308875 157 close_stdout_atexit();
4dddc2d4 158
1275d8a1 159 while ((c = getopt_long(argc, argv, "hVL:U:", longopts, NULL)) != -1) {
4dddc2d4
JB
160 switch (c) {
161 case 'h':
6e1eda6f 162 usage();
4dddc2d4 163 break;
1275d8a1 164 case 'V':
2c308875 165 print_version(EXIT_SUCCESS);
4dddc2d4
JB
166 case 'L':
167 label = optarg;
168 break;
169 case 'U':
170#ifdef HAVE_LIBUUID
171 uuid = optarg;
172#else
173 warnx(_("ignore -U (UUIDs are unsupported)"));
174#endif
175 break;
176 default:
677ec86c 177 errtryhelp(EXIT_FAILURE);
4dddc2d4
JB
178 }
179 }
180
6e1eda6f
RM
181 if (optind == argc) {
182 warnx(_("no device specified"));
183 errtryhelp(EXIT_FAILURE);
184 }
4dddc2d4
JB
185 devname = argv[optind];
186 pr = get_swap_prober(devname);
187 if (pr) {
188 if (uuid || label)
189 rc = change_info(devname, label, uuid);
190 else
ae7ec06b 191 rc = print_info(pr);
4dddc2d4
JB
192 blkid_free_probe(pr);
193 }
194 return rc ? EXIT_FAILURE : EXIT_SUCCESS;
195}