1/* See LICENSE file for copyright and license details. */
2
3
4#include <sys/types.h>
5
6#include <fcntl.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11
12#include "util.h"
13
14#define SWAP_MAGIC1 "SWAPSPACE2"
15#define SWAP_MAGIC2 "SWAP-SPACE"
16#define SWAP_MAGIC_LENGTH (10)
17#define SWAP_MAGIC_OFFSET (sysconf(_SC_PAGESIZE) - SWAP_MAGIC_LENGTH)
18#define SWAP_LABEL_LENGTH (16)
19#define SWAP_LABEL_OFFSET (1024 + 4 + 4 + 4 + 16)
20
21static void
22usage(void)
23{
24 eprintf("usage: %s [-L label] device\n", argv0);
25}
26
27// ?man swaplabel: print or change swap label
28// ?man arguments: device
29// ?man display or modify the label and uuid of a swap device
30int
31main(int argc, char *argv[])
32{
33 int setlabel = 0;
34 int fd;
35 char magic[SWAP_MAGIC_LENGTH];
36 char *label;
37 char *device;
38 int i;
39
40 ARGBEGIN {
41 // ?man -L:str: specify option flag
42 case 'L':
43 setlabel = 1;
44 label = EARGF(usage());
45 break;
46 default:
47 usage();
48 } ARGEND;
49
50 if (argc < 1)
51 usage();
52 device = argv[0];
53
54 fd = open(device, O_RDWR);
55 if (fd < 0)
56 eprintf("open %s:", device);
57
58 if (lseek(fd, SWAP_MAGIC_OFFSET, SEEK_SET) != SWAP_MAGIC_OFFSET)
59 eprintf("failed seeking to magic position:");
60 if (read(fd, magic, SWAP_MAGIC_LENGTH) != SWAP_MAGIC_LENGTH)
61 eprintf("reading magic failed:");
62 if (memcmp(magic, SWAP_MAGIC1, 10) && memcmp(magic, SWAP_MAGIC2, 10))
63 eprintf("%s: is not a swap partition\n", device);
64 if (lseek(fd, SWAP_LABEL_OFFSET, SEEK_SET) != SWAP_LABEL_OFFSET)
65 eprintf("failed seeking to label position:");
66
67 if (!setlabel) {
68 label = emalloc(SWAP_LABEL_LENGTH);
69 if (read(fd, label, SWAP_LABEL_LENGTH) != SWAP_LABEL_LENGTH)
70 eprintf("reading label failed:");
71 for (i = 0; i < SWAP_LABEL_LENGTH && label[i] != '\0'; i++)
72 if (i == (SWAP_LABEL_LENGTH - 1) && label[i] != '\0')
73 eprintf("invalid label\n");
74 printf("label: %s\n", label);
75 free(label);
76 } else {
77 if (strlen(label) + 1 > SWAP_LABEL_LENGTH)
78 eprintf("label too long\n");
79 if (write(fd, label, strlen(label) + 1) != (ssize_t)strlen(label) + 1)
80 eprintf("writing label failed:");
81 }
82
83 fsync(fd);
84 close(fd);
85 return 0;
86}