]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - lib.c
Discard devnum in favour of devnm
[thirdparty/mdadm.git] / lib.c
diff --git a/lib.c b/lib.c
index c04f6a0762d3ca14c4b782b88014169756d70c5d..1958029625160aafe39a5310b7a4abbd44d6ffcc 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -57,72 +57,59 @@ static int mdp_major = -1;
        return mdp_major;
 }
 
-
-void fmt_devname(char *name, int num)
-{
-       if (num >= 0)
-               sprintf(name, "md%d", num);
-       else
-               sprintf(name, "md_d%d", -1-num);
-}
-
-char *devnum2devname(int num)
-{
-       char name[100];
-       fmt_devname(name,num);
-       return strdup(name);
-}
-
-int devname2devnum(char *name)
-{
-       char *ep;
-       int num;
-       if (strncmp(name, "md_d", 4)==0)
-               num = -1-strtoul(name+4, &ep, 10);
-       else
-               num = strtoul(name+2, &ep, 10);
-       return num;
-}
-
-int stat2devnum(struct stat *st)
+char *devid2devnm(int devid)
 {
        char path[30];
        char link[200];
-       char *cp;
+       static char devnm[32];
+       char *cp, *ep;
        int n;
 
-       if ((S_IFMT & st->st_mode) == S_IFBLK) {
-               if (major(st->st_rdev) == MD_MAJOR)
-                       return minor(st->st_rdev);
-               else if (major(st->st_rdev) == (unsigned)get_mdp_major())
-                       return -1- (minor(st->st_rdev)>>MdpMinorShift);
-
-               /* must be an extended-minor partition. Look at the
-                * /sys/dev/block/%d:%d link which must look like
-                * ../../block/mdXXX/mdXXXpYY
-                */
-               sprintf(path, "/sys/dev/block/%d:%d", major(st->st_rdev),
-                       minor(st->st_rdev));
-               n = readlink(path, link, sizeof(link)-1);
-               if (n <= 0)
-                       return NoMdDev;
+       /* Might be an extended-minor partition or a
+        * named md device. Look at the
+        * /sys/dev/block/%d:%d link which must look like
+        *    ../../block/mdXXX/mdXXXpYY
+        * or
+        *    ...../block/md_FOO
+        */
+       sprintf(path, "/sys/dev/block/%d:%d", major(devid),
+               minor(devid));
+       n = readlink(path, link, sizeof(link)-1);
+       if (n > 0) {
                link[n] = 0;
-               cp = strrchr(link, '/');
-               if (cp) *cp = 0;
-               cp = strrchr(link, '/');
-               if (cp && strncmp(cp, "/md", 3) == 0)
-                       return devname2devnum(cp+1);
+               cp = strstr(link, "/block/");
+               if (cp) {
+                       cp += 7;
+                       ep = strchr(cp, '/');
+                       if (ep)
+                               *ep = 0;
+                       strcpy(devnm, cp);
+                       return devnm;
+               }
        }
-       return NoMdDev;
+       if (major(devid) == MD_MAJOR)
+               sprintf(devnm,"md%d", minor(devid));
+       else if (major(devid) == (unsigned)get_mdp_major())
+               sprintf(devnm,"md_d%d",
+                       (minor(devid)>>MdpMinorShift));
+       else
+               return NULL;
+       return devnm;
+}
 
+char *stat2devnm(struct stat *st)
+{
+       if ((S_IFMT & st->st_mode) != S_IFBLK)
+               return NULL;
+       return devid2devnm(st->st_rdev);
 }
 
-int fd2devnum(int fd)
+char *fd2devnm(int fd)
 {
        struct stat stb;
        if (fstat(fd, &stb) == 0)
-               return stat2devnum(&stb);
-       return NoMdDev;
+               return stat2devnm(&stb);
+       return NULL;
 }
 
 
@@ -133,9 +120,9 @@ int fd2devnum(int fd)
  * Put them in a simple linked listfor now.
  */
 struct devmap {
-    int major, minor;
-    char *name;
-    struct devmap *next;
+       int major, minor;
+       char *name;
+       struct devmap *next;
 } *devlist = NULL;
 int devlist_ready = 0;
 
@@ -150,8 +137,8 @@ int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s)
        }
 
        if ((stb->st_mode&S_IFMT)== S_IFBLK) {
-               char *n = strdup(name);
-               struct devmap *dm = malloc(sizeof(*dm));
+               char *n = xstrdup(name);
+               struct devmap *dm = xmalloc(sizeof(*dm));
                if (strncmp(n, "/dev/./", 7)==0)
                        strcpy(n+4, name+6);
                if (dm) {
@@ -262,9 +249,7 @@ char *conf_word(FILE *file, int allow_key)
        int c;
        int quote;
        int wordfound = 0;
-       char *word = malloc(wsize);
-
-       if (!word) abort();
+       char *word = xmalloc(wsize);
 
        while (wordfound==0) {
                /* at the end of a word.. */
@@ -294,8 +279,7 @@ char *conf_word(FILE *file, int allow_key)
                                else {
                                        if (len == wsize-1) {
                                                wsize += 100;
-                                               word = realloc(word, wsize);
-                                               if (!word) abort();
+                                               word = xrealloc(word, wsize);
                                        }
                                        word[len++] = c;
                                }
@@ -325,3 +309,84 @@ char *conf_word(FILE *file, int allow_key)
        }
        return word;
 }
+
+void print_quoted(char *str)
+{
+       /* Printf the string with surrounding quotes
+        * iff needed.
+        * If no space, tab, or quote - leave unchanged.
+        * Else print surrounded by " or ', swapping quotes
+        * when we find one that will cause confusion.
+        */
+
+       char first_quote = 0, q;
+       char *c;
+
+       for (c = str; *c; c++) {
+               switch(*c) {
+               case '\'':
+               case '"':
+                       first_quote = *c;
+                       break;
+               case ' ':
+               case '\t':
+                       first_quote = *c;
+                       continue;
+               default:
+                       continue;
+               }
+               break;
+       }
+       if (!first_quote) {
+               printf("%s", str);
+               return;
+       }
+
+       if (first_quote == '"')
+               q = '\'';
+       else
+               q = '"';
+       putchar(q);
+       for (c = str; *c; c++) {
+               if (*c == q) {
+                       putchar(q);
+                       q ^= '"' ^ '\'';
+                       putchar(q);
+               }
+               putchar(*c);
+       }
+       putchar(q);
+}
+
+void print_escape(char *str)
+{
+       /* print str, but change space and tab to '_'
+        * as is suitable for device names
+        */
+       for (; *str ; str++) {
+               switch (*str) {
+               case ' ':
+               case '\t':
+                       putchar('_');
+                       break;
+               case '/':
+                       putchar('-');
+                       break;
+               default:
+                       putchar(*str);
+               }
+       }
+}
+
+int use_udev(void)
+{
+       static int use = -1;
+       struct stat stb;
+
+       if (use < 0) {
+               use = ((stat("/dev/.udev", &stb) == 0
+                       || stat("/run/udev", &stb) == 0)
+                      && check_env("MDADM_NO_UDEV") == 0);
+       }
+       return use;
+}