From: Michael Tremer Date: Sun, 19 Sep 2010 21:15:13 +0000 (+0200) Subject: eject: New package. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38fa6f0076982b4bf6f3bdca4981831555c6db2b;p=ipfire-3.x.git eject: New package. --- diff --git a/pkgs/core/eject/eject.nm b/pkgs/core/eject/eject.nm new file mode 100644 index 000000000..5370f2f5d --- /dev/null +++ b/pkgs/core/eject/eject.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = eject +PKG_VER = 2.1.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.pobox.com/~tranter +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A program that ejects removable media using software control. + +PKG_BUILD_DEPS+= gettext libtool + +define PKG_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. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +DIR_APP = $(DIR_SRC)/$(PKG_NAME) + +CONFIGURE_OPTIONS += \ + --mandir=/usr/share/man diff --git a/pkgs/core/eject/patches/eject-2.1.1-verbose.patch b/pkgs/core/eject/patches/eject-2.1.1-verbose.patch new file mode 100644 index 000000000..44c05d881 --- /dev/null +++ b/pkgs/core/eject/patches/eject-2.1.1-verbose.patch @@ -0,0 +1,15 @@ +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; + } + diff --git a/pkgs/core/eject/patches/eject-2.1.5-lock.patch b/pkgs/core/eject/patches/eject-2.1.5-lock.patch new file mode 100644 index 000000000..25f84651e --- /dev/null +++ b/pkgs/core/eject/patches/eject-2.1.5-lock.patch @@ -0,0 +1,171 @@ + 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 [] + .br + eject [\-vn] \-c slot [] + .br ++eject [\-vn] \-i on|off|1|0 [] ++.br + eject [\-vn] \-t [] + .br + eject [\-vn] \-T [] +@@ -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 [] -- switch discs on a CD-ROM changer\n" + " eject [-vn] -t [] -- close tray\n" + " eject [-vn] -T [] -- toggle tray\n" ++" eject [-vn] -i on|off|1|0 [] -- toggle manual eject protection on/off\n" + " eject [-vn] -x [] -- set CD-ROM max speed\n" + " eject [-vn] -X [] -- 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 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) { diff --git a/pkgs/core/eject/patches/eject-2.1.5-opendevice.patch b/pkgs/core/eject/patches/eject-2.1.5-opendevice.patch new file mode 100644 index 000000000..c85a91032 --- /dev/null +++ b/pkgs/core/eject/patches/eject-2.1.5-opendevice.patch @@ -0,0 +1,39 @@ +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); diff --git a/pkgs/core/eject/patches/eject-2.1.5-spaces.patch b/pkgs/core/eject/patches/eject-2.1.5-spaces.patch new file mode 100644 index 000000000..40834d902 --- /dev/null +++ b/pkgs/core/eject/patches/eject-2.1.5-spaces.patch @@ -0,0 +1,62 @@ +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) diff --git a/pkgs/core/eject/patches/eject-2.1.5-umount.patch b/pkgs/core/eject/patches/eject-2.1.5-umount.patch new file mode 100644 index 000000000..2c588a01d --- /dev/null +++ b/pkgs/core/eject/patches/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 + #include + #include ++#include + + #ifdef GETOPTLONG + #include +@@ -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//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); diff --git a/pkgs/core/eject/patches/eject-timeout.patch b/pkgs/core/eject/patches/eject-timeout.patch new file mode 100644 index 000000000..a542d2c2f --- /dev/null +++ b/pkgs/core/eject/patches/eject-timeout.patch @@ -0,0 +1,11 @@ +--- 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);