+++ /dev/null
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-static dev_t try_name(char *name, int part)
-{
- char path[64];
- char buf[32];
- int range;
- dev_t res;
- char *s;
- int len;
- int fd;
- unsigned int maj, min;
-
- /* read device number from .../dev */
-
- sprintf(path, "/sys/block/%s/dev", name);
- fd = open(path, O_RDONLY);
- if (fd < 0)
- goto fail;
- len = read(fd, buf, 32);
- close(fd);
- if (len <= 0 || len == 32 || buf[len - 1] != '\n')
- goto fail;
- buf[len - 1] = '\0';
- if (sscanf(buf, "%u:%u", &maj, &min) != 2)
- goto fail;
- res = makedev(maj, min);
- if (maj != major(res) || min != minor(res))
- goto fail;
-
- /* if it's there and we are not looking for a partition - that's it */
- if (!part)
- return res;
-
- /* otherwise read range from .../range */
- snprintf(path, 64, "/sys/block/%s/range", name);
- fd = open(path, O_RDONLY);
- if (fd < 0)
- goto fail;
- len = read(fd, buf, 32);
- close(fd);
- if (len <= 0 || len == 32 || buf[len - 1] != '\n')
- goto fail;
- buf[len - 1] = '\0';
- range = strtoul(buf, &s, 10);
- if (*s)
- goto fail;
-
- /* if partition is within range - we got it */
- if (part < range)
- return res + part;
-fail:
- return 0;
-}
-
-/*
- * Convert a name into device number. We accept the following variants:
- *
- * 1) device number in hexadecimal represents itself
- * 2) /dev/nfs represents Root_NFS (0xff)
- * 3) /dev/<disk_name> represents the device number of disk
- * 4) /dev/<disk_name><decimal> represents the device number
- * of partition - device number of disk plus the partition number
- * 5) /dev/<disk_name>p<decimal> - same as the above, that form is
- * used when disk name of partitioned disk ends on a digit.
- *
- * If name doesn't have fall into the categories above, we return 0.
- * sysfs is used to check if something is a disk name - it has
- * all known disks under bus/block/devices. If the disk name
- * contains slashes, name of driverfs node has them replaced with
- * bangs. try_name() does the actual checks, assuming that sysfs
- * is mounted on /sys.
- *
- * Note that cases (1) and (2) are already handled by the kernel,
- * so we can ifdef them out, provided that we check real-root-dev
- * first.
- */
-
-dev_t name_to_dev_t(char *name)
-{
- char s[32];
- char *p;
- dev_t res = 0;
- int part;
-
- if (strncmp(name, "/dev/", 5) != 0) {
-#if 1 /* kernel used to do this */
- unsigned maj, min;
-
- if (sscanf(name, "%u:%u", &maj, &min) == 2) {
- res = makedev(maj, min);
- if (maj != major(res) || min != minor(res))
- return 0;
- } else {
- res = strtoul(name, &p, 16);
- if (*p)
- return 0;
- }
-#endif
- return res;
- }
-
- name += 5;
-
-#if 1 /* kernel used to do this */
- if (strcmp(name, "nfs") == 0)
- return makedev(0, 255);
-#endif
-
- if (strlen(name) > 31)
- return 0;
- strcpy(s, name);
- for (p = s; *p; p++)
- if (*p == '/')
- *p = '!';
- res = try_name(s, 0);
- if (res)
- return res;
-
- while (p > s && isdigit(p[-1]))
- p--;
- if (p == s || !*p || *p == '0')
- return 0;
- part = strtoul(p, NULL, 10);
- *p = '\0';
- res = try_name(s, part);
- if (res)
- return res;
-
- if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
- return 0;
- p[-1] = '\0';
- return try_name(s, part);
-}