+++ /dev/null
-###############################################################################
-# IPFire.org - An Open Source Firewall Solution #
-# Copyright (C) - IPFire Development Team <info@ipfire.org> #
-###############################################################################
-
-name = eject
-version = 2.1.5
-release = 1
-
-groups = System/Base
-url = http://www.pobox.com/~tranter
-license = GPLv2+
-summary = A program that ejects removable media using software control.
-
-description
- The eject program allows the user to eject removable media (typically \
- CD-ROMs, floppy disks or Iomega Jaz or Zip disks) using software \
- control. Eject can also control some multi-disk CD changers and even \
- some devices' auto-eject features.
-end
-
-source_dl =
-
-build
- requires
- gettext
- libtool
- end
-
- DIR_APP = %{DIR_SRC}/%{name}
-
- configure_options += \
- --mandir=/usr/share/man
-end
-
-packages
- package %{name}
- end
-
- package %{name}-debuginfo
- template DEBUGINFO
- end
-end
+++ /dev/null
-diff --git a/eject.c b/eject.c
-index b14d5f2..662ba54 100644
---- a/eject.c
-+++ b/eject.c
-@@ -709,7 +709,9 @@ static int EjectScsi(int fd)
- unsigned char sense_buffer[32];
-
- if ((ioctl(fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) {
-- printf("not an sg device, or old sg driver\n");
-+ if (v_option) {
-+ printf(_("not an sg device, or old sg driver\n"));
-+ }
- return 0;
- }
-
+++ /dev/null
- eject.1 | 13 +++++++++++--
- eject.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 63 insertions(+), 4 deletions(-)
-
-diff --git a/eject.1 b/eject.1
-index 3c388c6..315dc6d 100644
---- a/eject.1
-+++ b/eject.1
-@@ -17,6 +17,8 @@ eject [\-vn] \-a on|off|1|0 [<name>]
- .br
- eject [\-vn] \-c slot [<name>]
- .br
-+eject [\-vn] \-i on|off|1|0 [<name>]
-+.br
- eject [\-vn] \-t [<name>]
- .br
- eject [\-vn] \-T [<name>]
-@@ -83,6 +85,13 @@ for a change request to work. Please also note that the first slot of
- the changer is referred to as 0, not 1.
-
- .TP 0.5i
-+.B \-i on|1|off|0
-+This option controls locking of the hardware eject button. When
-+enabled, the drive will not be ejected when the button is pressed.
-+This is useful when you are carrying a laptop in a bag or case and
-+don't want it to eject if the button is inadvertently pressed.
-+
-+.TP 0.5i
- .B \-t
- With this option the drive is given a CD-ROM tray close command. Not
- all devices support this command.
-@@ -121,8 +130,8 @@ performed.
- .B \-r
- This option specifies that the drive should be ejected using a
- CDROM eject command.
--.TP 0.5i
-
-+.TP 0.5i
- .B \-s
- This option specifies that the drive should be ejected using
- SCSI commands.
-@@ -145,7 +154,7 @@ also passes the \-n option to umount(1).
- .TP 0.5i
- .B \-m
- This option allows eject to work with device drivers which automatically
--mount removable media and therefore must be always mount()ed.
-+mount removable media and therefore must be always mount(1)ed.
- The option tells eject to not try to unmount the given device,
- even if it is mounted according to /etc/mtab or /proc/mounts.
-
-diff --git a/eject.c b/eject.c
-index f7b2a2e..4175756 100644
---- a/eject.c
-+++ b/eject.c
-@@ -116,6 +116,7 @@ int d_option = 0;
- int f_option = 0;
- int h_option = 0;
- int n_option = 0;
-+int i_option = 0;
- int q_option = 0;
- int r_option = 0;
- int s_option = 0;
-@@ -129,6 +130,7 @@ int m_option = 0;
- int a_arg = 0;
- int c_arg = 0;
- int x_arg = 0;
-+int i_arg = 0;
- static char *programName; /* used in error messages */
-
- /*
-@@ -163,6 +165,7 @@ static void usage()
- " eject [-vn] -c <slot> [<name>] -- switch discs on a CD-ROM changer\n"
- " eject [-vn] -t [<name>] -- close tray\n"
- " eject [-vn] -T [<name>] -- toggle tray\n"
-+" eject [-vn] -i on|off|1|0 [<name>] -- toggle manual eject protection on/off\n"
- " eject [-vn] -x <speed> [<name>] -- set CD-ROM max speed\n"
- " eject [-vn] -X [<name>] -- list CD-ROM available speeds\n"
- "Options:\n"
-@@ -200,7 +203,7 @@ static void usage()
- #endif
- "\n"
- " -n --noop -V --version\n"
--" -p --proc -m --no-unmount -T --traytoggle\n"));
-+" -p --proc -m --no-unmount -T --traytoggle -i --manualeject\n"));
- #endif /* GETOPTLONG */
- fprintf(stderr,_(
- "Parameter <name> can be a device file or a mount point.\n"
-@@ -214,7 +217,7 @@ static void usage()
- /* Handle command line options. */
- static void parse_args(int argc, char **argv, char **device)
- {
-- const char *flags = "a:c:x:dfhnqrstTXvVpm";
-+ const char *flags = "a:c:x:i:dfhnqrstTXvVpm";
- #ifdef GETOPTLONG
- static struct option long_options[] =
- {
-@@ -223,6 +226,7 @@ static void parse_args(int argc, char **argv, char **device)
- {"default", no_argument, NULL, 'd'},
- {"auto", required_argument, NULL, 'a'},
- {"changerslot", required_argument, NULL, 'c'},
-+ {"manualeject", required_argument, NULL, 'i'},
- {"trayclose", no_argument, NULL, 't'},
- {"traytoggle", no_argument, NULL, 'T'},
- {"cdspeed", required_argument, NULL, 'x'},
-@@ -297,6 +301,21 @@ static void parse_args(int argc, char **argv, char **device)
- usage();
- exit(0);
- break;
-+ case 'i':
-+ i_option = 1;
-+ if (!strcmp(optarg, "0"))
-+ i_arg = 0;
-+ else if (!strcmp(optarg, "off"))
-+ i_arg = 0;
-+ else if (!strcmp(optarg, "1"))
-+ i_arg = 1;
-+ else if (!strcmp(optarg, "on"))
-+ i_arg = 1;
-+ else {
-+ fprintf(stderr, _("%s: invalid argument to -i option\n"), programName);
-+ exit(1);
-+ }
-+ break;
- case 'm':
- m_option = 1;
- break;
-@@ -482,6 +501,30 @@ static char *FindDevice(const char *name)
- }
-
-
-+/*
-+ * Stops CDROM from opening on manual eject pressing the button.
-+ * This can be useful when you carry your laptop
-+ * in your bag while it's on and no CD inserted in it's drive.
-+ * Implemented as found in Documentation/ioctl/cdrom.txt
-+ *
-+ * TODO: Maybe we should check this also:
-+ * EDRIVE_CANT_DO_THIS Door lock function not supported.
-+ * EBUSY Attempt to unlock when multiple users
-+ * have the drive open and not CAP_SYS_ADMIN
-+ */
-+static void ManualEject(int fd, int onOff)
-+{
-+ if (ioctl(fd, CDROM_LOCKDOOR, onOff) < 0) {
-+ perror("ioctl on CDROM_LOCKDOOR");
-+ } else {
-+ if (onOff)
-+ printf("CD-Drive may NOT be ejected with device button\n");
-+ else
-+ printf("CD-Drive may be ejected with device button\n");
-+ }
-+}
-+
-+
- /* Set or clear auto-eject mode. */
- static void AutoEject(int fd, int onOff)
- {
-@@ -1233,6 +1276,13 @@ int main(int argc, char **argv)
- exit(0);
- }
-
-+ /* handle -i option */
-+ if (i_option) {
-+ fd = OpenDevice(deviceName);
-+ ManualEject(fd, i_arg);
-+ exit(0);
-+ }
-+
- /* handle -a option */
- if (a_option) {
- if (v_option) {
+++ /dev/null
-diff --git a/eject.c b/eject.c
-index 79fd01b..d67089c 100644
---- a/eject.c
-+++ b/eject.c
-@@ -543,10 +543,11 @@ static void ToggleTray(int fd)
-
- #ifdef CDROMCLOSETRAY
-
-- /* Try to open the CDROM tray and measure the time therefor
-- * needed. In my experience the function needs less than 0.05
-+ /* Try to open the CDROM tray and measure the time needed.
-+ * In my experience the function needs less than 0.05
- * seconds if the tray was already open, and at least 1.5 seconds
-- * if it was closed. */
-+ * if it was closed.
-+ */
- gettimeofday(&time_start, NULL);
-
- /* Send the CDROMEJECT command to the device. */
-@@ -815,10 +816,17 @@ static void Unmount(const char *fullName)
- }
-
-
--/* Open a device file. */
-+/* Open a device file. Try opening first read/write, and if that fails then read only. */
- static int OpenDevice(const char *fullName)
- {
-- int fd = open(fullName, O_RDONLY|O_NONBLOCK);
-+ int fd;
-+
-+ fd = open(fullName, O_RDWR|O_NONBLOCK);
-+ if (fd != -1) {
-+ return fd;
-+ }
-+
-+ fd = open(fullName, O_RDONLY|O_NONBLOCK);
- if (fd == -1) {
- fprintf(stderr, _("%s: unable to open `%s'\n"), programName, fullName);
- exit(1);
+++ /dev/null
-diff --git a/eject.c b/eject.c
-index d67089c..f7b2a2e 100644
---- a/eject.c
-+++ b/eject.c
-@@ -370,6 +370,30 @@ static int FileExists(const char *name, const int try, int *found)
-
-
- /*
-+ * Linux mangles spaces in mount points by changing them to an octal string
-+ * of '\040'. So lets scan the mount point and fix it up by replacing all
-+ * occurrences off '\0##' with the ASCII value of 0##. Requires a writable
-+ * string as input as we mangle in place. Some of this was taken from the
-+ * util-linux package.
-+ */
-+#define octalify(a) ((a) & 7)
-+#define tooctal(s) (64*octalify(s[1]) + 8*octalify(s[2]) + octalify(s[3]))
-+#define isoctal(a) (((a) & ~7) == '0')
-+static char *DeMangleMount(char *s)
-+{
-+ char *tmp = s;
-+ while ((tmp = strchr(tmp, '\\')) != NULL) {
-+ if (isoctal(tmp[1]) && isoctal(tmp[2]) && isoctal(tmp[3])) {
-+ tmp[0] = tooctal(tmp);
-+ memmove(tmp+1, tmp+4, strlen(tmp)-3);
-+ }
-+ ++tmp;
-+ }
-+ return s;
-+}
-+
-+
-+/*
- * Given name, such as foo, see if any of the following exist:
- *
- * foo (if foo starts with '.' or '/')
-@@ -882,6 +906,8 @@ static int MountedDevice(const char *name, char **mountName, char **deviceName)
- rc = sscanf(line, "%1023s %1023s", s1, s2);
- if (rc >= 2) {
- int mtabmaj, mtabmin;
-+ DeMangleMount(s1);
-+ DeMangleMount(s2);
- GetMajorMinor(s1, &mtabmaj, &mtabmin);
- if (((strcmp(s1, name) == 0) || (strcmp(s2, name) == 0)) ||
- ((maj != -1) && (maj == mtabmaj) && (min == mtabmin))) {
-@@ -928,6 +954,8 @@ static int MountableDevice(const char *name, char **mountName, char **deviceName
-
- while (fgets(line, sizeof(line), fp) != 0) {
- rc = sscanf(line, "%1023s %1023s", s1, s2);
-+ DeMangleMount(s1);
-+ DeMangleMount(s2);
- if (rc >= 2 && s1[0] != '#' && strcmp(s2, name) == 0) {
- FCLOSE(fp);
- *deviceName = strdup(s1);
-@@ -968,6 +996,8 @@ static void UnmountDevices(const char *pattern)
- while (fgets(line, sizeof(line), fp) != 0) {
- status = sscanf(line, "%1023s %1023s", s1, s2);
- if (status >= 2) {
-+ DeMangleMount(s1);
-+ DeMangleMount(s2);
- status = regexec(&preg, s1, 0, 0, 0);
- if (status == 0) {
- if (v_option)
+++ /dev/null
-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);
+++ /dev/null
---- eject/eject.c.orig 2006-08-07 16:35:15.000000000 +0200
-+++ eject/eject.c 2006-08-07 16:35:54.000000000 +0200
-@@ -723,7 +723,7 @@
- io_hdr.dxfer_len = 0;
- io_hdr.dxferp = inqBuff;
- io_hdr.sbp = sense_buffer;
-- io_hdr.timeout = 2000;
-+ io_hdr.timeout = 10000;
-
- io_hdr.cmdp = allowRmBlk;
- status = ioctl(fd, SG_IO, (void *)&io_hdr);