diff options
| author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-02-08 15:04:00 +0000 |
|---|---|---|
| committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-02-08 15:04:00 +0000 |
| commit | afdad653ac62e99d8da30e441d3414684146db19 (patch) | |
| tree | f0b120ffa8686518f4914ce32f8a07aa5874f01c /miscutils | |
| parent | 534b8d04832bc28f16fde1f8473139c0f004ed25 (diff) | |
| download | busybox-w32-afdad653ac62e99d8da30e441d3414684146db19.tar.gz busybox-w32-afdad653ac62e99d8da30e441d3414684146db19.tar.bz2 busybox-w32-afdad653ac62e99d8da30e441d3414684146db19.zip | |
- add eject -s for SCSI- and USB-devices (Nico Erfurth)
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/Config.in | 8 | ||||
| -rw-r--r-- | miscutils/eject.c | 87 |
2 files changed, 78 insertions, 17 deletions
diff --git a/miscutils/Config.in b/miscutils/Config.in index e6c65044a..d64d05345 100644 --- a/miscutils/Config.in +++ b/miscutils/Config.in | |||
| @@ -126,6 +126,14 @@ config EJECT | |||
| 126 | help | 126 | help |
| 127 | Used to eject cdroms. (defaults to /dev/cdrom) | 127 | Used to eject cdroms. (defaults to /dev/cdrom) |
| 128 | 128 | ||
| 129 | config FEATURE_EJECT_SCSI | ||
| 130 | bool "eject scsi support" | ||
| 131 | default n | ||
| 132 | depends on EJECT | ||
| 133 | help | ||
| 134 | Add the -s option to eject, this allows to eject SCSI-Devices and | ||
| 135 | usb-storage devices. | ||
| 136 | |||
| 129 | config LAST | 137 | config LAST |
| 130 | bool "last" | 138 | bool "last" |
| 131 | default n | 139 | default n |
diff --git a/miscutils/eject.c b/miscutils/eject.c index 99f01aba9..746a0184e 100644 --- a/miscutils/eject.c +++ b/miscutils/eject.c | |||
| @@ -25,33 +25,86 @@ | |||
| 25 | #define FLAG_CLOSE 1 | 25 | #define FLAG_CLOSE 1 |
| 26 | #define FLAG_SMART 2 | 26 | #define FLAG_SMART 2 |
| 27 | 27 | ||
| 28 | |||
| 29 | /* Code taken from the original eject (http://eject.sourceforge.net/), | ||
| 30 | * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ | ||
| 31 | #define FLAG_SCSI 4 | ||
| 32 | |||
| 33 | #include <scsi/sg.h> | ||
| 34 | #include <scsi/scsi.h> | ||
| 35 | static void eject_scsi(const int fd, const char * const dev) | ||
| 36 | { | ||
| 37 | int i; | ||
| 38 | unsigned char sense_buffer[32]; | ||
| 39 | unsigned char inqBuff[2]; | ||
| 40 | sg_io_hdr_t io_hdr; | ||
| 41 | char sg_commands[3][6] = { | ||
| 42 | {ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0}, | ||
| 43 | {START_STOP, 0, 0, 0, 1, 0}, | ||
| 44 | {START_STOP, 0, 0, 0, 2, 0} | ||
| 45 | }; | ||
| 46 | |||
| 47 | if ((ioctl(fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000)) | ||
| 48 | bb_error_msg_and_die("not an sg device or old sg driver"); | ||
| 49 | |||
| 50 | memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); | ||
| 51 | io_hdr.interface_id = 'S'; | ||
| 52 | io_hdr.cmd_len = 6; | ||
| 53 | io_hdr.mx_sb_len = sizeof(sense_buffer); | ||
| 54 | io_hdr.dxfer_direction = SG_DXFER_NONE; | ||
| 55 | /* io_hdr.dxfer_len = 0; */ | ||
| 56 | io_hdr.dxferp = inqBuff; | ||
| 57 | io_hdr.sbp = sense_buffer; | ||
| 58 | io_hdr.timeout = 2000; | ||
| 59 | |||
| 60 | for (i=0; i < 3; i++) { | ||
| 61 | io_hdr.cmdp = sg_commands[i]; | ||
| 62 | ioctl_or_perror_and_die(fd, SG_IO, (void *)&io_hdr, "%s", dev); | ||
| 63 | } | ||
| 64 | |||
| 65 | /* force kernel to reread partition table when new disc inserted */ | ||
| 66 | ioctl(fd, BLKRRPART); | ||
| 67 | } | ||
| 68 | |||
| 69 | static void eject_cdrom(const int fd, const unsigned long flags, | ||
| 70 | const char * const dev) | ||
| 71 | { | ||
| 72 | int cmd = CDROMEJECT; | ||
| 73 | |||
| 74 | if (flags & FLAG_CLOSE | ||
| 75 | || (flags & FLAG_SMART && ioctl(fd, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)) | ||
| 76 | cmd = CDROMCLOSETRAY; | ||
| 77 | |||
| 78 | return ioctl_or_perror_and_die(fd, cmd, NULL, "%s", dev); | ||
| 79 | } | ||
| 80 | |||
| 28 | int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 81 | int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 29 | int eject_main(int argc, char **argv) | 82 | int eject_main(int argc, char **argv) |
| 30 | { | 83 | { |
| 31 | unsigned long flags; | 84 | unsigned long flags; |
| 32 | const char *device; | 85 | const char *device; |
| 33 | int dev, cmd; | 86 | int dev; |
| 34 | 87 | ||
| 35 | opt_complementary = "?1:t--T:T--t"; | 88 | opt_complementary = "?1:t--T:T--t"; |
| 36 | flags = getopt32(argv, "tT"); | 89 | flags = getopt32(argv, "tT" USE_FEATURE_EJECT_SCSI("s")); |
| 37 | device = argv[optind] ? : "/dev/cdrom"; | 90 | device = argv[optind] ? argv[optind] : "/dev/cdrom"; |
| 38 | 91 | ||
| 39 | // We used to do "umount <device>" here, but it was buggy | 92 | /* We used to do "umount <device>" here, but it was buggy |
| 40 | // if something was mounted OVER cdrom and | 93 | if something was mounted OVER cdrom and |
| 41 | // if cdrom is mounted many times. | 94 | if cdrom is mounted many times. |
| 42 | // | 95 | |
| 43 | // This works equally well (or better): | 96 | This works equally well (or better): |
| 44 | // #!/bin/sh | 97 | #!/bin/sh |
| 45 | // umount /dev/cdrom | 98 | umount /dev/cdrom |
| 46 | // eject | 99 | eject |
| 100 | */ | ||
| 47 | 101 | ||
| 48 | dev = xopen(device, O_RDONLY|O_NONBLOCK); | 102 | dev = xopen(device, O_RDONLY|O_NONBLOCK); |
| 49 | cmd = CDROMEJECT; | ||
| 50 | if (flags & FLAG_CLOSE | ||
| 51 | || (flags & FLAG_SMART && ioctl(dev, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)) | ||
| 52 | cmd = CDROMCLOSETRAY; | ||
| 53 | 103 | ||
| 54 | ioctl_or_perror_and_die(dev, cmd, NULL, "%s", device); | 104 | if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI)) |
| 105 | eject_scsi(dev, device); | ||
| 106 | else | ||
| 107 | eject_cdrom(dev, flags, device); | ||
| 55 | 108 | ||
| 56 | if (ENABLE_FEATURE_CLEAN_UP) | 109 | if (ENABLE_FEATURE_CLEAN_UP) |
| 57 | close(dev); | 110 | close(dev); |
