master xplshn/aruu / cmd / linux / swaplabel.c
 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}