1 diff --git a/eject.c b/eject.c
2 index 4175756..057d2ea 100644
13 @@ -1133,6 +1134,145 @@ static char *MultiplePartitions(const char *name)
18 + * Find device name in /sys/block/. Returns NULL if not
19 + * found. The returned pointer must be free()'d.
21 +static char* FindDeviceSysBlock(const char* deviceName)
23 + DIR *dir = opendir("/sys/block");
25 + const char *baseName = strrchr(deviceName, '/');
29 + baseName = baseName ? baseName + 1 : deviceName;
31 + fprintf(stderr, _("%s: can not open directory /sys/block/"), programName);
34 + while ((d = readdir(dir)) != NULL) {
35 + if (d->d_type != DT_DIR && d->d_type != DT_LNK && d->d_type != DT_UNKNOWN)
37 + len = strlen(d->d_name);
38 + if (!strncmp(baseName, d->d_name, len)) {
39 + if ((*(baseName+len) >= '0' &&
40 + *(baseName+len) <= '9') ||
41 + *(baseName+len) == '\0') {
42 + device = strdup(d->d_name);
53 + * From given path gets a subsystem. Returns subsystem if any found
54 + * otherwise returns NULL. Returned value must not be free()'d
56 +static char *GetSubSystem(const char *sysfspath)
58 + static char subsystem[PATH_MAX];
59 + char link_subsystem[PATH_MAX];
63 + snprintf(link_subsystem, sizeof(link_subsystem), "%s/subsystem", sysfspath);
65 + if (lstat(link_subsystem, &buf) == -1)
67 + if (!S_ISLNK(buf.st_mode))
69 + if (readlink(link_subsystem, subsystem, sizeof(subsystem)) == -1)
71 + if ((pos = strrchr(subsystem, '/')) == NULL)
73 + strncpy(subsystem, pos+1, sizeof(subsystem));
79 + * Check content of /sys/block/<dev>/removable. Returns 1 if the file
80 + * contains '1' otherwise returns 0.
82 +static int CheckRemovable(const char* deviceName)
87 + char path[PATH_MAX];
89 + if ((device = FindDeviceSysBlock(deviceName)) == NULL) {
91 + _("%s: did not find a device %s in /sys/block/\n"),
92 + programName, deviceName);
95 + snprintf(path, sizeof(path), "/sys/block/%s/removable", device);
97 + if((fp = fopen(path, "r")) == NULL)
99 + if (fgetc(fp) == '1')
106 +/* Check if a device is on hotpluggable subsystem. Returns 1 if is
107 + * otherwise returns 0.
109 +static int CheckHotpluggable(const char* deviceName)
111 + int hotpluggable = 0;
113 + char path[PATH_MAX];
114 + char *device_chain;
119 + if ((device = FindDeviceSysBlock(deviceName)) == NULL) {
120 + fprintf(stderr, _("%s: did not find a device %s in /sys/block/\n"),
121 + programName, deviceName);
124 + snprintf(path, sizeof(path), "/sys/block/%s/device", device);
127 + if (lstat(path, &buf) == -1)
128 + return hotpluggable;
129 + if (!S_ISLNK(buf.st_mode))
130 + return hotpluggable;
131 + if ((device_chain = SymLink(path)) == NULL)
132 + return hotpluggable;
133 + while ( strncmp(device_chain, "", sizeof(device_chain) != 0)) {
134 + subsystem = GetSubSystem(device_chain);
136 + /* as hotpluggable we assume devices on these buses */
137 + if (strncmp("usb", subsystem, sizeof("usb")) == 0 ||
138 + strncmp("ieee1394", subsystem, sizeof("ieee1394")) == 0 ||
139 + strncmp("pcmcia", subsystem, sizeof("pcmcia")) == 0 ||
140 + strncmp("mmc", subsystem, sizeof("mmc")) == 0 ||
141 + strncmp("ccw", subsystem, sizeof("ccw")) == 0) {
146 + /* remove one member from devicechain */
147 + pos = strrchr(device_chain, '/');
151 + device_chain[0] = '\0';
154 + return hotpluggable;
157 /* handle -x option */
158 static void HandleXOption(char *deviceName)
159 @@ -1276,6 +1416,17 @@ int main(int argc, char **argv)
163 + /* Check if device has removable flag*/
165 + printf(_("%s: checking if device \"%s\" has a removable or hotpluggable flag\n"),
166 + programName, deviceName);
167 + if (!CheckRemovable(deviceName) && !CheckHotpluggable(deviceName))
169 + fprintf(stderr, _("%s: device \"%s\" doesn't have a removable or hotpluggable flag\n"),
170 + programName, deviceName);
174 /* handle -i option */
176 fd = OpenDevice(deviceName);