From: Karel Zak Date: Tue, 27 Mar 2012 15:36:47 +0000 (+0200) Subject: eject: add -X from Fedora X-Git-Tag: v2.22-rc1~555^2~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1abc33266f3e6806c0c9637bd498b1ad0de6c50d;p=thirdparty%2Futil-linux.git eject: add -X from Fedora Signed-off-by: Karel Zak --- diff --git a/include/pathnames.h b/include/pathnames.h index 70c6ecfb31..28f8d6f4f2 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -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" diff --git a/misc-utils/eject.1 b/misc-utils/eject.1 index 26a427dbfe..4839152a83 100644 --- a/misc-utils/eject.1 +++ b/misc-utils/eject.1 @@ -25,6 +25,8 @@ eject [-vn] -T [] .br eject [\-vn] \-x [] .br +eject [\-vn] \-X [] +.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) diff --git a/misc-utils/eject.c b/misc-utils/eject.c index daa9b06301..c37930177a 100644 --- a/misc-utils/eject.c +++ b/misc-utils/eject.c @@ -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);