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