00039 {
00040 static struct entry
00041 {
00042 unsigned char major;
00043 unsigned char minor;
00044 char *name;
00045 enum { ENTRY_TYPE_ONE, ENTRY_TYPE_NUMBER, ENTRY_TYPE_DISC } type;
00046 unsigned char entry_first;
00047 unsigned char entry_disc_minor_shift;
00048 }
00049 entries[] =
00050 {
00051
00052
00053
00054 { 2, 0, "fd", ENTRY_TYPE_NUMBER, 0, 0 },
00055 { 3, 0, "hd", ENTRY_TYPE_DISC, 0, 6 },
00056 { 4, 64, "ttyS", ENTRY_TYPE_NUMBER, 0, 6 },
00057 { 4, 0, "tty", ENTRY_TYPE_NUMBER, 0, 6 },
00058 { 8, 0, "sd", ENTRY_TYPE_DISC, 0, 4 },
00059 { 9, 0, "md", ENTRY_TYPE_NUMBER, 0, 0 },
00060 { 22, 0, "hd", ENTRY_TYPE_DISC, 2, 6 },
00061 { 33, 0, "hd", ENTRY_TYPE_DISC, 4, 6 },
00062 { 34, 0, "hd", ENTRY_TYPE_DISC, 6, 6 },
00063 { 56, 0, "hd", ENTRY_TYPE_DISC, 8, 6 },
00064 { 57, 0, "hd", ENTRY_TYPE_DISC, 10, 6 },
00065 { 65, 0, "sd", ENTRY_TYPE_DISC, 16, 4 },
00066 { 66, 0, "sd", ENTRY_TYPE_DISC, 32, 4 },
00067 { 67, 0, "sd", ENTRY_TYPE_DISC, 48, 4 },
00068 { 68, 0, "sd", ENTRY_TYPE_DISC, 64, 4 },
00069 { 69, 0, "sd", ENTRY_TYPE_DISC, 80, 4 },
00070 { 70, 0, "sd", ENTRY_TYPE_DISC, 96, 4 },
00071 { 71, 0, "sd", ENTRY_TYPE_DISC, 112, 4 },
00072 { 88, 0, "hd", ENTRY_TYPE_DISC, 12, 6 },
00073 { 89, 0, "hd", ENTRY_TYPE_DISC, 14, 6 },
00074 { 90, 0, "hd", ENTRY_TYPE_DISC, 16, 6 },
00075 { 91, 0, "hd", ENTRY_TYPE_DISC, 18, 6 },
00076 { 94, 0, "dasd", ENTRY_TYPE_DISC, 0, 2 },
00077 { 0, 0, NULL, ENTRY_TYPE_ONE, 0, 0 },
00078 };
00079
00080 struct stat s;
00081 struct entry *e;
00082
00083 ssize_t ret = 0;
00084
00085 unsigned int unit;
00086 unsigned int part;
00087
00088 if (!strcmp ("none", path))
00089 return snprintf (buf, n, "%s", path);
00090
00091 if (stat (path,&s) == -1)
00092 return 0;
00093
00094 e = entries;
00095 while (e->name != NULL) {
00096 if (major (s.st_rdev) == e->major &&
00097 ((e->type == ENTRY_TYPE_ONE && minor (s.st_rdev) == e->minor) ||
00098 (e->type != ENTRY_TYPE_ONE && minor (s.st_rdev) >= e->minor))) {
00099 break;
00100 }
00101 e++;
00102 }
00103 if (!e->name)
00104
00105 return snprintf (buf, n, "%s", path);
00106
00107 switch (e->type)
00108 {
00109 case ENTRY_TYPE_ONE:
00110 ret = snprintf (buf, n, "/dev/%s", e->name);
00111 break;
00112
00113 case ENTRY_TYPE_NUMBER:
00114 unit = minor (s.st_rdev) - e->minor + e->entry_first;
00115
00116 ret = snprintf (buf, n, "/dev/%s%d", e->name, unit);
00117 break;
00118
00119 case ENTRY_TYPE_DISC:
00120 unit = (minor (s.st_rdev) >> e->entry_disc_minor_shift);
00121 part = (minor (s.st_rdev) & ((1 << e->entry_disc_minor_shift) -1 ));
00122
00123 unit += e->entry_first;
00124
00125 if (unit+'a' > 'z') {
00126 unit -= 26;
00127 ret = snprintf (buf, n, "/dev/%s%c%c", e->name, 'a' + unit / 26, 'a' + unit % 26);
00128 }
00129 else
00130 ret = snprintf (buf, n, "/dev/%s%c", e->name, 'a' + unit);
00131
00132 if (part)
00133 ret = snprintf (buf + ret, n - ret, "%d", part);
00134
00135 break;
00136 };
00137
00138 return ret;
00139 }