aboutsummaryrefslogtreecommitdiff
path: root/miscutils/eject.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/eject.c')
-rw-r--r--miscutils/eject.c95
1 files changed, 49 insertions, 46 deletions
diff --git a/miscutils/eject.c b/miscutils/eject.c
index 3d27ce545..42e071941 100644
--- a/miscutils/eject.c
+++ b/miscutils/eject.c
@@ -22,68 +22,71 @@
22/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ 22/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
23#define CDS_TRAY_OPEN 2 23#define CDS_TRAY_OPEN 2
24 24
25#define FLAG_CLOSE 1 25#define dev_fd 3
26#define FLAG_SMART 2
27
28 26
29/* Code taken from the original eject (http://eject.sourceforge.net/), 27/* Code taken from the original eject (http://eject.sourceforge.net/),
30 * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ 28 * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */
31#define FLAG_SCSI 4
32 29
33#include <scsi/sg.h> 30#include <scsi/sg.h>
34#include <scsi/scsi.h> 31#include <scsi/scsi.h>
35static void eject_scsi(const int fd, const char * const dev) 32
33static void eject_scsi(const char *dev)
36{ 34{
37 int i; 35 static const char sg_commands[3][6] = {
38 unsigned char sense_buffer[32]; 36 { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 },
39 unsigned char inqBuff[2]; 37 { START_STOP, 0, 0, 0, 1, 0 },
40 sg_io_hdr_t io_hdr; 38 { START_STOP, 0, 0, 0, 2, 0 }
41 char sg_commands[3][6] = { 39 };
42 {ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0}, 40
43 {START_STOP, 0, 0, 0, 1, 0}, 41 int i;
44 {START_STOP, 0, 0, 0, 2, 0} 42 unsigned char sense_buffer[32];
45 }; 43 unsigned char inqBuff[2];
46 44 sg_io_hdr_t io_hdr;
47 if ((ioctl(fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000)) 45
48 bb_error_msg_and_die("not an sg device or old sg driver"); 46 if ((ioctl(dev_fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000))
49 47 bb_error_msg_and_die("not a sg device or old sg driver");
50 memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); 48
51 io_hdr.interface_id = 'S'; 49 memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
52 io_hdr.cmd_len = 6; 50 io_hdr.interface_id = 'S';
53 io_hdr.mx_sb_len = sizeof(sense_buffer); 51 io_hdr.cmd_len = 6;
54 io_hdr.dxfer_direction = SG_DXFER_NONE; 52 io_hdr.mx_sb_len = sizeof(sense_buffer);
55 /* io_hdr.dxfer_len = 0; */ 53 io_hdr.dxfer_direction = SG_DXFER_NONE;
56 io_hdr.dxferp = inqBuff; 54 /* io_hdr.dxfer_len = 0; */
57 io_hdr.sbp = sense_buffer; 55 io_hdr.dxferp = inqBuff;
58 io_hdr.timeout = 2000; 56 io_hdr.sbp = sense_buffer;
59 57 io_hdr.timeout = 2000;
60 for (i=0; i < 3; i++) { 58
61 io_hdr.cmdp = sg_commands[i]; 59 for (i = 0; i < 3; i++) {
62 ioctl_or_perror_and_die(fd, SG_IO, (void *)&io_hdr, "%s", dev); 60 io_hdr.cmdp = (char*)sg_commands[i];
63 } 61 ioctl_or_perror_and_die(dev_fd, SG_IO, (void *)&io_hdr, "%s", dev);
64 62 }
65 /* force kernel to reread partition table when new disc inserted */ 63
66 ioctl(fd, BLKRRPART); 64 /* force kernel to reread partition table when new disc is inserted */
65 ioctl(dev_fd, BLKRRPART);
67} 66}
68 67
69static void eject_cdrom(const int fd, const unsigned long flags, 68#define FLAG_CLOSE 1
70 const char * const dev) 69#define FLAG_SMART 2
70#define FLAG_SCSI 4
71
72static void eject_cdrom(unsigned flags, const char *dev)
71{ 73{
72 int cmd = CDROMEJECT; 74 int cmd = CDROMEJECT;
73 75
74 if (flags & FLAG_CLOSE 76 if (flags & FLAG_CLOSE
75 || (flags & FLAG_SMART && ioctl(fd, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)) 77 || (flags & FLAG_SMART && ioctl(dev_fd, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)
78 ) {
76 cmd = CDROMCLOSETRAY; 79 cmd = CDROMCLOSETRAY;
80 }
77 81
78 return ioctl_or_perror_and_die(fd, cmd, NULL, "%s", dev); 82 ioctl_or_perror_and_die(dev_fd, cmd, NULL, "%s", dev);
79} 83}
80 84
81int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 85int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
82int eject_main(int argc ATTRIBUTE_UNUSED, char **argv) 86int eject_main(int argc ATTRIBUTE_UNUSED, char **argv)
83{ 87{
84 unsigned long flags; 88 unsigned flags;
85 const char *device; 89 const char *device;
86 int dev;
87 90
88 opt_complementary = "?1:t--T:T--t"; 91 opt_complementary = "?1:t--T:T--t";
89 flags = getopt32(argv, "tT" USE_FEATURE_EJECT_SCSI("s")); 92 flags = getopt32(argv, "tT" USE_FEATURE_EJECT_SCSI("s"));
@@ -96,18 +99,18 @@ int eject_main(int argc ATTRIBUTE_UNUSED, char **argv)
96 This works equally well (or better): 99 This works equally well (or better):
97 #!/bin/sh 100 #!/bin/sh
98 umount /dev/cdrom 101 umount /dev/cdrom
99 eject 102 eject /dev/cdrom
100 */ 103 */
101 104
102 dev = xopen(device, O_RDONLY|O_NONBLOCK); 105 xmove_fd(xopen(device, O_RDONLY|O_NONBLOCK), dev_fd);
103 106
104 if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI)) 107 if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI))
105 eject_scsi(dev, device); 108 eject_scsi(device);
106 else 109 else
107 eject_cdrom(dev, flags, device); 110 eject_cdrom(flags, device);
108 111
109 if (ENABLE_FEATURE_CLEAN_UP) 112 if (ENABLE_FEATURE_CLEAN_UP)
110 close(dev); 113 close(dev_fd);
111 114
112 return EXIT_SUCCESS; 115 return EXIT_SUCCESS;
113} 116}