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