3
0

base_device.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * base_device.c
  3. *
  4. * Return the "base device" given a particular device; this is used to
  5. * assure that we only fsck one partition on a particular drive at any
  6. * one time. Otherwise, the disk heads will be seeking all over the
  7. * place. If the base device can not be determined, return NULL.
  8. *
  9. * The base_device() function returns an allocated string which must
  10. * be freed.
  11. *
  12. * Written by Theodore Ts'o, <tytso@mit.edu>
  13. *
  14. * Copyright (C) 2000 Theodore Ts'o.
  15. *
  16. * %Begin-Header%
  17. * This file may be redistributed under the terms of the GNU Public
  18. * License.
  19. * %End-Header%
  20. */
  21. #include <stdio.h>
  22. #include <unistd.h>
  23. #include <stdlib.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include "busybox.h"
  27. #ifdef CONFIG_FEATURE_DEVFS
  28. /*
  29. * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3
  30. * pathames.
  31. */
  32. static const char *devfs_hier[] = {
  33. "host", "bus", "target", "lun", 0
  34. };
  35. #endif
  36. char *base_device(const char *device)
  37. {
  38. char *str, *cp;
  39. #ifdef CONFIG_FEATURE_DEVFS
  40. const char **hier, *disk;
  41. int len;
  42. #endif
  43. cp = str = bb_xstrdup(device);
  44. /* Skip over /dev/; if it's not present, give up. */
  45. if (strncmp(cp, "/dev/", 5) != 0)
  46. goto errout;
  47. cp += 5;
  48. #if 0 /* this is for old stuff no one uses anymore ? */
  49. /* Skip over /dev/dsk/... */
  50. if (strncmp(cp, "dsk/", 4) == 0)
  51. cp += 4;
  52. #endif
  53. /*
  54. * For md devices, we treat them all as if they were all
  55. * on one disk, since we don't know how to parallelize them.
  56. */
  57. if (cp[0] == 'm' && cp[1] == 'd') {
  58. *(cp+2) = 0;
  59. return str;
  60. }
  61. /* Handle DAC 960 devices */
  62. if (strncmp(cp, "rd/", 3) == 0) {
  63. cp += 3;
  64. if (cp[0] != 'c' || cp[2] != 'd' ||
  65. !isdigit(cp[1]) || !isdigit(cp[3]))
  66. goto errout;
  67. *(cp+4) = 0;
  68. return str;
  69. }
  70. /* Now let's handle /dev/hd* and /dev/sd* devices.... */
  71. if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) {
  72. cp += 2;
  73. /* If there's a single number after /dev/hd, skip it */
  74. if (isdigit(*cp))
  75. cp++;
  76. /* What follows must be an alpha char, or give up */
  77. if (!isalpha(*cp))
  78. goto errout;
  79. *(cp + 1) = 0;
  80. return str;
  81. }
  82. #ifdef CONFIG_FEATURE_DEVFS
  83. /* Now let's handle devfs (ugh) names */
  84. len = 0;
  85. if (strncmp(cp, "ide/", 4) == 0)
  86. len = 4;
  87. if (strncmp(cp, "scsi/", 5) == 0)
  88. len = 5;
  89. if (len) {
  90. cp += len;
  91. /*
  92. * Now we proceed down the expected devfs hierarchy.
  93. * i.e., .../host1/bus2/target3/lun4/...
  94. * If we don't find the expected token, followed by
  95. * some number of digits at each level, abort.
  96. */
  97. for (hier = devfs_hier; *hier; hier++) {
  98. len = strlen(*hier);
  99. if (strncmp(cp, *hier, len) != 0)
  100. goto errout;
  101. cp += len;
  102. while (*cp != '/' && *cp != 0) {
  103. if (!isdigit(*cp))
  104. goto errout;
  105. cp++;
  106. }
  107. cp++;
  108. }
  109. *(cp - 1) = 0;
  110. return str;
  111. }
  112. /* Now handle devfs /dev/disc or /dev/disk names */
  113. disk = 0;
  114. if (strncmp(cp, "discs/", 6) == 0)
  115. disk = "disc";
  116. else if (strncmp(cp, "disks/", 6) == 0)
  117. disk = "disk";
  118. if (disk) {
  119. cp += 6;
  120. if (strncmp(cp, disk, 4) != 0)
  121. goto errout;
  122. cp += 4;
  123. while (*cp != '/' && *cp != 0) {
  124. if (!isdigit(*cp))
  125. goto errout;
  126. cp++;
  127. }
  128. *cp = 0;
  129. return str;
  130. }
  131. #endif
  132. errout:
  133. free(str);
  134. return NULL;
  135. }