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