diff options
Diffstat (limited to 'extra/eject/eject-2.1.5-umount.patch')
-rw-r--r-- | extra/eject/eject-2.1.5-umount.patch | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/extra/eject/eject-2.1.5-umount.patch b/extra/eject/eject-2.1.5-umount.patch new file mode 100644 index 000000000..2c588a01d --- /dev/null +++ b/extra/eject/eject-2.1.5-umount.patch @@ -0,0 +1,176 @@ +diff --git a/eject.c b/eject.c +index 4175756..057d2ea 100644 +--- a/eject.c ++++ b/eject.c +@@ -42,6 +42,7 @@ + #include <string.h> + #include <fcntl.h> + #include <limits.h> ++#include <dirent.h> + + #ifdef GETOPTLONG + #include <getopt.h> +@@ -1133,6 +1134,145 @@ static char *MultiplePartitions(const char *name) + return 0; + } + ++/* ++ * Find device name in /sys/block/. Returns NULL if not ++ * found. The returned pointer must be free()'d. ++ */ ++static char* FindDeviceSysBlock(const char* deviceName) ++{ ++ DIR *dir = opendir("/sys/block"); ++ struct dirent *d; ++ const char *baseName = strrchr(deviceName, '/'); ++ char *device; ++ int len; ++ ++ baseName = baseName ? baseName + 1 : deviceName; ++ if (!dir) { ++ fprintf(stderr, _("%s: can not open directory /sys/block/"), programName); ++ return NULL; ++ } ++ while ((d = readdir(dir)) != NULL) { ++ if (d->d_type != DT_DIR && d->d_type != DT_LNK && d->d_type != DT_UNKNOWN) ++ continue; ++ len = strlen(d->d_name); ++ if (!strncmp(baseName, d->d_name, len)) { ++ if ((*(baseName+len) >= '0' && ++ *(baseName+len) <= '9') || ++ *(baseName+len) == '\0') { ++ device = strdup(d->d_name); ++ closedir(dir); ++ return device; ++ } ++ } ++ } ++ closedir(dir); ++ return NULL; ++} ++ ++/* ++ * From given path gets a subsystem. Returns subsystem if any found ++ * otherwise returns NULL. Returned value must not be free()'d ++ */ ++static char *GetSubSystem(const char *sysfspath) ++{ ++ static char subsystem[PATH_MAX]; ++ char link_subsystem[PATH_MAX]; ++ struct stat buf; ++ char *pos; ++ ++ snprintf(link_subsystem, sizeof(link_subsystem), "%s/subsystem", sysfspath); ++ ++ if (lstat(link_subsystem, &buf) == -1) ++ return NULL; ++ if (!S_ISLNK(buf.st_mode)) ++ return NULL; ++ if (readlink(link_subsystem, subsystem, sizeof(subsystem)) == -1) ++ return NULL; ++ if ((pos = strrchr(subsystem, '/')) == NULL) ++ return NULL; ++ strncpy(subsystem, pos+1, sizeof(subsystem)); ++ ++ return subsystem; ++} ++ ++/* ++ * Check content of /sys/block/<dev>/removable. Returns 1 if the file ++ * contains '1' otherwise returns 0. ++ */ ++static int CheckRemovable(const char* deviceName) ++{ ++ FILE *fp; ++ int removable = 0; ++ char *device; ++ char path[PATH_MAX]; ++ ++ if ((device = FindDeviceSysBlock(deviceName)) == NULL) { ++ fprintf(stderr, ++ _("%s: did not find a device %s in /sys/block/\n"), ++ programName, deviceName); ++ exit(1); ++ } ++ snprintf(path, sizeof(path), "/sys/block/%s/removable", device); ++ free(device); ++ if((fp = fopen(path, "r")) == NULL) ++ return removable; ++ if (fgetc(fp) == '1') ++ removable = 1; ++ ++ fclose(fp); ++ return removable; ++} ++ ++/* Check if a device is on hotpluggable subsystem. Returns 1 if is ++ * otherwise returns 0. ++ */ ++static int CheckHotpluggable(const char* deviceName) ++{ ++ int hotpluggable = 0; ++ char *device; ++ char path[PATH_MAX]; ++ char *device_chain; ++ struct stat buf; ++ char *subsystem; ++ char *pos; ++ ++ if ((device = FindDeviceSysBlock(deviceName)) == NULL) { ++ fprintf(stderr, _("%s: did not find a device %s in /sys/block/\n"), ++ programName, deviceName); ++ exit(1); ++ } ++ snprintf(path, sizeof(path), "/sys/block/%s/device", device); ++ free(device); ++ ++ if (lstat(path, &buf) == -1) ++ return hotpluggable; ++ if (!S_ISLNK(buf.st_mode)) ++ return hotpluggable; ++ if ((device_chain = SymLink(path)) == NULL) ++ return hotpluggable; ++ while ( strncmp(device_chain, "", sizeof(device_chain) != 0)) { ++ subsystem = GetSubSystem(device_chain); ++ if (subsystem) { ++ /* as hotpluggable we assume devices on these buses */ ++ if (strncmp("usb", subsystem, sizeof("usb")) == 0 || ++ strncmp("ieee1394", subsystem, sizeof("ieee1394")) == 0 || ++ strncmp("pcmcia", subsystem, sizeof("pcmcia")) == 0 || ++ strncmp("mmc", subsystem, sizeof("mmc")) == 0 || ++ strncmp("ccw", subsystem, sizeof("ccw")) == 0) { ++ hotpluggable = 1; ++ break; ++ } ++ } ++ /* remove one member from devicechain */ ++ pos = strrchr(device_chain, '/'); ++ if (pos) ++ pos[0] = '\0'; ++ else ++ device_chain[0] = '\0'; ++ } ++ ++ return hotpluggable; ++} + + /* handle -x option */ + static void HandleXOption(char *deviceName) +@@ -1276,6 +1416,17 @@ int main(int argc, char **argv) + exit(0); + } + ++ /* Check if device has removable flag*/ ++ if (v_option) ++ printf(_("%s: checking if device \"%s\" has a removable or hotpluggable flag\n"), ++ programName, deviceName); ++ if (!CheckRemovable(deviceName) && !CheckHotpluggable(deviceName)) ++ { ++ fprintf(stderr, _("%s: device \"%s\" doesn't have a removable or hotpluggable flag\n"), ++ programName, deviceName); ++ exit(1); ++ } ++ + /* handle -i option */ + if (i_option) { + fd = OpenDevice(deviceName); |