]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
eject: add -X from Fedora
authorKarel Zak <kzak@redhat.com>
Tue, 27 Mar 2012 15:36:47 +0000 (17:36 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 27 Mar 2012 15:38:28 +0000 (17:38 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/pathnames.h
misc-utils/eject.1
misc-utils/eject.c

index 70c6ecfb313557bf118851d9d4b540653ec4b650..28f8d6f4f2b106592bfc11a828eb31f0396aec58 100644 (file)
@@ -81,6 +81,7 @@
 #define _PATH_PROC_DEVICES     "/proc/devices"
 #define _PATH_PROC_MOUNTINFO   "/proc/self/mountinfo"
 #define _PATH_PROC_LOCKS        "/proc/locks"
+#define _PATH_PROC_CDROMINFO   "/proc/sys/dev/cdrom/info"
 
 #define _PATH_SYS_BLOCK                "/sys/block"
 #define _PATH_SYS_DEVBLOCK     "/sys/dev/block"
index 26a427dbfea59bea6517d5780b4a88cafbef5a0e..4839152a835469bc6fe1b1f45fe28894ae456898 100644 (file)
@@ -25,6 +25,8 @@ eject [-vn] -T [<name>]
 .br
 eject [\-vn] \-x <speed> [<name>]
 .br
+eject [\-vn] \-X [<name>]
+.br
 eject \-V
 
 .SH DESCRIPTION
@@ -110,6 +112,15 @@ this command and you can only specify speeds that the drive is capable
 of. Every time the media is changed this option is cleared. This
 option can be used alone, or with the \-t and \-c options.
 
+.TP 0.5i
+.B \-X 
+With this option the CD-ROM drive will be probed to detect the
+available speeds. The output is a list of speeds which can be used as
+an argument of the \-x option. This only works with Linux 2.6.13 or
+higher, on previous versions solely the maximum speed will be
+reported. Also note that some drive may not correctly report the speed
+and therefore this option does not work with them.
+
 .TP 0.5i
 .B \-n
 With this option the selected device is displayed but no action is
@@ -311,10 +322,12 @@ The \-x option was added by Nobuyuki Tsuchimura (tutimura@nn.iij4u.or.jp),
 with thanks to Roland Krivanek (krivanek@fmph.uniba.sk) and his
 cdrom_speed command.
 
-The -T option was added by Sybren Stuvel (sybren@thirdtower.com), with
+The \-T option was added by Sybren Stuvel (sybren@thirdtower.com), with
 big thanks to Benjamin Schwenk (benjaminschwenk@yahoo.de).
 
- .SH SEE ALSO
+The \-X option was added by Eric Piel (Eric.Piel@tremplin-utc.net).
+
+.SH SEE ALSO
 
  mount(2), umount(2), mount(8), umount(8)
 
index daa9b0630196795230fe380463c095d16ac1f737..c37930177a42a023b842ecd3d94e80113c98adfc 100644 (file)
@@ -49,6 +49,7 @@
 #include "strutils.h"
 #include "xalloc.h"
 #include "canonicalize.h"
+#include "pathnames.h"
 
 #define EJECT_DEFAULT_DEVICE "/dev/cdrom"
 
@@ -71,6 +72,7 @@ static int r_option;
 static int s_option;
 static int t_option;
 static int T_option;
+static int X_option;
 static int v_option;
 static int x_option;
 static int p_option;
@@ -142,6 +144,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
                " -t, --trayclose    close tray\n"
                " -T, --traytoggle   toggle tray\n"
                " -x, --cdspeed      set CD-ROM max speed\n"
+               " -X, --listspeed    list CD-ROM available speeds\n"
                " -v, --verbose      enable verbose output\n"
                " -n, --noop         don't eject, just show device found\n"
                " -r, --cdrom        eject CD-ROM\n"
@@ -173,6 +176,7 @@ static void parse_args(int argc, char **argv, char **device)
                {"trayclose",   no_argument,       NULL, 't'},
                {"traytoggle",  no_argument,       NULL, 'T'},
                {"cdspeed",     required_argument, NULL, 'x'},
+               {"listspeed",   no_argument,       NULL, 'X'},
                {"noop",        no_argument,       NULL, 'n'},
                {"cdrom",       no_argument,       NULL, 'r'},
                {"scsi",        no_argument,       NULL, 's'},
@@ -186,7 +190,7 @@ static void parse_args(int argc, char **argv, char **device)
        int c;
 
        while ((c = getopt_long(argc, argv,
-                               "a:c:i:x:dfhnqrstTvVpm", long_opts, NULL)) != -1) {
+                               "a:c:i:x:dfhnqrstTXvVpm", long_opts, NULL)) != -1) {
                switch (c) {
                case 'a':
                        a_option = 1;
@@ -247,6 +251,9 @@ static void parse_args(int argc, char **argv, char **device)
                case 'T':
                        T_option = 1;
                        break;
+               case 'X':
+                       X_option = 1;
+                       break;
                case 'v':
                        v_option = 1;
                        break;
@@ -412,6 +419,92 @@ static void select_speed(int fd, int speed)
 #endif
 }
 
+/*
+ * Read Speed of CD-ROM drive. From Linux 2.6.13, the current speed
+ * is correctly reported
+ */
+static int read_speed(const char *devname)
+{
+       int drive_number = -1;
+       char *name;
+       FILE *f;
+
+       f = fopen(_PATH_PROC_CDROMINFO, "r");
+       if (!f)
+               err(EXIT_FAILURE, _("%s: open failed"), _PATH_PROC_CDROMINFO);
+
+       name = rindex(devname, '/') + 1;
+
+       while (!feof(f)) {
+               char line[512];
+               char *str;
+
+               if (!fgets(line, sizeof(line), f))
+                       break;
+
+               /* find drive number in line "drive name" */
+               if (drive_number == -1) {
+                       if (strncmp(line, "drive name:", 11) == 0) {
+                               str = strtok(&line[11], "\t ");
+                               drive_number = 0;
+                               while (strncmp(name, str, strlen(name)) != 0) {
+                                       drive_number++;
+                                       str = strtok(NULL, "\t ");
+                                       if (!str)
+                                               errx(EXIT_FAILURE,
+                                                    _("%s: failed to finding CD-ROM name"),
+                                                    _PATH_PROC_CDROMINFO);
+                               }
+                       }
+               /* find line "drive speed" and read the correct speed */
+               } else {
+                       if (strncmp(line, "drive speed:", 12) == 0) {
+                               int i;
+                               char *str;
+
+                               str = strtok(&line[12], "\t ");
+                               for (i = 1; i < drive_number; i++)
+                                       str = strtok(NULL, "\t ");
+
+                               if (!str)
+                                       errx(EXIT_FAILURE,
+                                               _("%s: failed to read speed"),
+                                               _PATH_PROC_CDROMINFO);
+                               return atoi(str);
+                       }
+               }
+       }
+
+       errx(EXIT_FAILURE, _("failed to read speed"));
+}
+
+/*
+ * List Speed of CD-ROM drive.
+ */
+static void list_speeds(const char *name, int fd)
+{
+#ifdef CDROM_SELECT_SPEED
+       int max_speed, curr_speed = 0, prev_speed;
+
+       select_speed(fd, 0);
+       max_speed = read_speed(name);
+
+       while (curr_speed < max_speed) {
+               prev_speed = curr_speed;
+               select_speed(fd, prev_speed + 1);
+               curr_speed = read_speed(name);
+               if (curr_speed > prev_speed)
+                       printf("%d ", curr_speed);
+               else
+                       curr_speed = prev_speed + 1;
+       }
+
+       printf("\n");
+#else
+       warnx(_("CD-ROM select speed command not supported by this kernel"));
+#endif
+}
+
 /*
  * Eject using CDROMEJECT ioctl. Return 1 if successful, 0 otherwise.
  */
@@ -787,6 +880,14 @@ int main(int argc, char **argv)
                exit(0);
        }
 
+       /* handle -X option */
+       if (X_option) {
+               verbose(_("%s: listing CD-ROM speed"), device);
+               fd = open_device(device);
+               list_speeds(device, fd);
+               exit(0);
+       }
+
        /* handle -x option only */
        if (!c_option)
                set_device_speed(device);