Date: Sun, 10 Dec 1995 17:42:30 +0300 From: vak@cronyx.ru To: FreeBSD-gnats-submit@freebsd.org Subject: bin/889: [patch] version 1.3 of /usr/sbin/cdcontrol Message-ID: <199512101442.RAA02429@crox.net.kiae.su> Resent-Message-ID: <199512101450.GAA15893@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 889 >Category: bin >Synopsis: update from version 1.0 to version 1.3 >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Class: support >Submitter-Id: current-users >Arrival-Date: Sun Dec 10 06:50:02 PST 1995 >Last-Modified: >Originator: Serge V.Vakulenko >Organization: Cronyx Ltd. >Release: FreeBSD 2.1-STABLE i386 >Environment: >Description: New command formats added, some bugs fixed. >How-To-Repeat: >Fix: diff -u ../cdcontrol~/cdcontrol.c ./cdcontrol.c --- ../cdcontrol~/cdcontrol.c Fri Aug 18 15:41:32 1995 +++ ./cdcontrol.c Sun Dec 10 17:36:29 1995 @@ -2,7 +2,22 @@ * Compact Disc Control Utility by Serge V. Vakulenko, <vak@cronyx.ru>. * Based on the non-X based CD player by Jean-Marc Zucconi and * Andrew A. Chernov. + * + * Fixed and further modified on 5-Sep-1995 by Jukka Ukkonen <jau@funet.fi>. + * + * 11-Sep-1995: Jukka A. Ukkonen <jau@funet.fi> + * A couple of further fixes to my own earlier "fixes". + * + * 18-Sep-1995: Jukka A. Ukkonen <jau@funet.fi> + * Added an ability to specify addresses relative to the + * beginning of a track. This is in fact a variation of + * doing the simple play_msf() call. + * + * 11-Oct-1995: Serge V.Vakulenko <vak@cronyx.ru> + * New eject algorithm. + * Some code style reformatting. */ + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -11,78 +26,101 @@ #include <sys/file.h> #include <sys/cdio.h> #include <sys/ioctl.h> +#include <ctype.h> -#define VERSION "1.0" +#define VERSION "1.3" /* * Audio Status Codes */ -#define ASTS_INVALID 0x00 /* Audio status byte not valid */ -#define ASTS_PLAYING 0x11 /* Audio play operation in progress */ -#define ASTS_PAUSED 0x12 /* Audio play operation paused */ -#define ASTS_COMPLETED 0x13 /* Audio play operation successfully completed */ -#define ASTS_ERROR 0x14 /* Audio play operation stopped due to error */ -#define ASTS_VOID 0x15 /* No current audio status to return */ +#define ASTS_INVALID 0x00 /* Audio status byte not valid */ +#define ASTS_PLAYING 0x11 /* Audio play operation in progress */ +#define ASTS_PAUSED 0x12 /* Audio play operation paused */ +#define ASTS_COMPLETED 0x13 /* Audio play operation successfully completed */ +#define ASTS_ERROR 0x14 /* Audio play operation stopped due to error */ +#define ASTS_VOID 0x15 /* No current audio status to return */ + +#undef _P +#ifdef __STDC__ +# define _P(x) x +#else +# define _P(x) () +# define const /**/ +#endif + +#ifndef DEFAULT_CD_DRIVE +# define DEFAULT_CD_DRIVE "/dev/cd0a" +#endif + +#ifndef DEFAULT_CD_PARTITION +# define DEFAULT_CD_PARTITION "a" +#endif -struct cmdtab { - int command; - char *name; - char *args; -} cmdtab[] = { #define CMD_DEBUG 1 - { CMD_DEBUG, "Debug", "[ on | off | reset ]", }, #define CMD_EJECT 2 - { CMD_EJECT, "Eject", "", }, #define CMD_HELP 3 - { CMD_HELP, "?", 0, }, - { CMD_HELP, "Help", "", }, #define CMD_INFO 4 - { CMD_INFO, "Info", "", }, #define CMD_PAUSE 5 - { CMD_PAUSE, "PAuse", "", }, #define CMD_PLAY 6 - { CMD_PLAY, "P", 0, }, - { CMD_PLAY, "Play", "min1:sec1.fr1 [ min2:sec2.fr2 ]", }, - { CMD_PLAY, "Play", "track1.index1 [ track2.index2 ]", }, - { CMD_PLAY, "Play", "#block [ len ]", }, #define CMD_QUIT 7 - { CMD_QUIT, "Quit", "", }, #define CMD_RESUME 8 - { CMD_RESUME, "Resume", "", }, #define CMD_STOP 9 - { CMD_STOP, "Stop", "", }, #define CMD_VOLUME 10 - { CMD_VOLUME, "Volume", "<l> <r> | left | right | mute | mono | stereo", }, - { 0, 0, }, -}; - -struct cd_toc_entry toc_buffer[100]; - -char *cdname; -int fd = -1; -int verbose = 1; - -extern char *optarg; -extern int optind; - -int setvol (int, int); -int read_toc_entrys (int); -int play_msf (int, int, int, int, int, int); -int play_track (int, int, int, int); -int get_vol (int *, int *); -int status (int *, int *, int *, int *); -int open_cd (void); -int play (char *arg); -int info (char *arg); -char *input (int*); -void prtrack (struct cd_toc_entry *e, int lastflag); -void lba2msf (int lba, u_char *m, u_char *s, u_char *f); -int msf2lba (u_char m, u_char s, u_char f); -int play_blocks (int blk, int len); -int run (int cmd, char *arg); -char *parse (char *buf, int *cmd); +#define CMD_CLOSE 11 -extern int errno; +struct cmdtab { + int command; + char *name; + unsigned min; + char *args; +} cmdtab[] = { +{ CMD_DEBUG, "Debug", 1, "[ on | off | reset ]" }, +{ CMD_EJECT, "Eject", 1, "" }, +{ CMD_HELP, "?", 1, 0 }, +{ CMD_HELP, "Help", 1, "" }, +{ CMD_INFO, "Info", 1, "" }, +{ CMD_PAUSE, "PAuse", 2, "" }, +{ CMD_PLAY, "P", 1, 0 }, +{ CMD_PLAY, "Play", 1, "[track1] min1:sec1[.fr1] [[track2] [min2:sec2[.fr2]]]" }, +{ CMD_PLAY, "Play", 1, "track1.index1 [track2.index2]" }, +{ CMD_PLAY, "Play", 1, "#block [length_in_blocks]" }, +{ CMD_QUIT, "Quit", 1, "" }, +{ CMD_RESUME, "Resume", 1, "" }, +{ CMD_STOP, "Stop", 1, "" }, +{ CMD_VOLUME, "Volume", 1, "<l> <r> | left | right | mute | mono | stereo" }, +{ CMD_CLOSE, "Close", 1, "" }, +{ 0 }}; + +struct cd_toc_entry toc_buffer[100]; + +const char *cdname; +int fd = -1; +int verbose = 1; + +extern char *optarg; +extern int optind; + +const char *prog; + +int setvol _P((int, int)); +int read_toc_entrys _P((int)); +int play_msf _P((int, int, int, int, int, int)); +int play_track _P((int, int, int, int)); +int get_vol _P((int *, int *)); +int status _P((int *, int *, int *, int *)); +int open_cd _P((void)); +int play _P((char *arg)); +int info _P((char *arg)); +char *input _P((int *)); +void prtrack _P((struct cd_toc_entry *e, int lastflag)); +void lba2msf _P((unsigned int lba, + u_char *m, u_char *s, u_char *f)); +unsigned int msf2lba _P((u_char m, u_char s, u_char f)); +int play_blocks _P((int blk, int len)); +int run _P((int cmd, char *arg)); +char *parse _P((char *buf, int *cmd)); + +extern int errno; void help () { @@ -96,16 +134,18 @@ printf (" %s", c->args); printf ("\n"); } + printf ("\n\tThe word \"play\" is not required for the play commands.\n"); + printf ("\tThe plain target address is taken as a synonym for play.\n\n"); } void usage () { - printf ("Usage:\n\tcdcontrol [ -vs ] [ -f disc ] [ command args... ]\n"); + printf ("Usage:\n\t%s [ -vs ] [ -f disc ] [ command args... ]\n", prog); printf ("Options:\n"); printf ("\t-v - verbose mode\n"); printf ("\t-s - silent mode\n"); - printf ("\t-f disc - device name such as /dev/cd0c\n"); - printf ("\tDISC - shell variable with device name\n"); + printf ("\t-f disc - a block device name such as /dev/cd0c\n"); + printf ("\tMUSIC_CD - shell variable with device name\n"); printf ("Commands:\n"); help (); exit (1); @@ -116,7 +156,19 @@ int cmd; char *arg; - cdname = getenv ("DISC"); + /* + * Use only the basename part of the program name. + * This will be shown e.g. in prompts and error messages. + */ + prog = strrchr (argv[0], '/'); + if (! prog) + prog = argv[0]; + + cdname = getenv ("MUSIC_CD"); + if (! cdname) + cdname = getenv ("CD_DRIVE"); + if (! cdname) + cdname = getenv ("DISC"); if (! cdname) cdname = getenv ("CDPLAY"); @@ -142,36 +194,41 @@ argc -= optind; argv += optind; - if (argc > 0 && strcasecmp (*argv, "help") == 0) + if (argc > 0 && ! strcasecmp (*argv, "help")) usage (); if (! cdname) { - fprintf (stderr, "No CD device name specified.\n"); - usage (); + cdname = DEFAULT_CD_DRIVE; + fprintf (stderr, + "No CD device name specified. Defaulting to %s.\n", cdname); } if (argc > 0) { char buf[80], *p; int len; - for (p=buf; argc-- > 0; ++argv) { + for (p=buf; argc-->0; ++argv) { len = strlen (*argv); + if (p + len >= buf + sizeof (buf) - 1) usage (); + if (p > buf) *p++ = ' '; + strcpy (p, *argv); p += len; } *p = 0; arg = parse (buf, &cmd); - return run (cmd, arg); + return (run (cmd, arg)); } if (verbose == 1) verbose = isatty (0); + if (verbose) { - printf ("Compact Disc Control Utility, Version %s\n", VERSION); + printf ("Compact Disc Control utility, version %s\n", VERSION); printf ("Type `?' for command list\n\n"); } @@ -179,7 +236,7 @@ arg = input (&cmd); if (run (cmd, arg) < 0) { if (verbose) - perror ("cdplay"); + perror (prog); close (fd); fd = -1; } @@ -192,74 +249,117 @@ int l, r, rc; switch (cmd) { + case CMD_QUIT: exit (0); - default: - case CMD_HELP: - help (); - return (0); - case CMD_INFO: - if (fd<0 && ! open_cd ()) return (0); - return info (arg); + if ((fd < 0) && ! open_cd ()) + return (0); + + return (info (arg)); case CMD_PAUSE: - if (fd<0 && ! open_cd ()) return (0); - return ioctl (fd, CDIOCPAUSE); + if ((fd < 0) && ! open_cd ()) + return (0); + + return (ioctl (fd, CDIOCPAUSE)); case CMD_RESUME: - if (fd<0 && ! open_cd ()) return (0); - return ioctl (fd, CDIOCRESUME); + if ((fd < 0) && ! open_cd ()) + return (0); + + return (ioctl (fd, CDIOCRESUME)); case CMD_STOP: - if (fd<0 && ! open_cd ()) return (0); - return ioctl (fd, CDIOCSTOP); + if ((fd < 0) && ! open_cd ()) + return (0); + + rc = ioctl (fd, CDIOCSTOP); + + (void) ioctl (fd, CDIOCALLOW); + + return (rc); case CMD_DEBUG: - if (fd<0 && ! open_cd ()) return (0); - if (strcasecmp (arg, "on") == 0) - return ioctl (fd, CDIOCSETDEBUG); - if (strcasecmp (arg, "off") == 0) - return ioctl (fd, CDIOCCLRDEBUG); - if (strcasecmp (arg, "reset") == 0) - return ioctl (fd, CDIOCRESET); - printf ("Invalid command arguments\n"); + if ((fd < 0) && ! open_cd ()) + return (0); + + if (! strcasecmp (arg, "on")) + return (ioctl (fd, CDIOCSETDEBUG)); + + if (! strcasecmp (arg, "off")) + return (ioctl (fd, CDIOCCLRDEBUG)); + + if (! strcasecmp (arg, "reset")) + return (ioctl (fd, CDIOCRESET)); + + printf ("%s: Invalid command arguments\n", prog); + return (0); case CMD_EJECT: - if (fd<0 && ! open_cd ()) return (0); + if ((fd < 0) && ! open_cd ()) + return (0); + (void) ioctl (fd, CDIOCALLOW); rc = ioctl (fd, CDIOCEJECT); if (rc < 0) return (rc); - close (fd); - fd = -1; + return (0); + + case CMD_CLOSE: + if ((fd < 0) && ! open_cd ()) + return (0); + + (void) ioctl (fd, CDIOCALLOW); +#ifdef CDIOCCLOSE + rc = ioctl (fd, CDIOCCLOSE); + if (rc < 0) + return (rc); +#endif return (0); case CMD_PLAY: - if (fd<0 && ! open_cd ()) return (0); - return play (arg); + if ((fd < 0) && ! open_cd ()) + return (0); + + while (isspace (*arg)) + arg++; + + return (play (arg)); case CMD_VOLUME: - if (fd<0 && ! open_cd ()) return (0); + if ((fd < 0) && ! open_cd ()) + return (0); - if (strcasecmp (arg, "left") == 0) - return ioctl (fd, CDIOCSETLEFT); - else if (strcasecmp (arg, "right") == 0) - return ioctl (fd, CDIOCSETRIGHT); - else if (strcasecmp (arg, "mute") == 0) - return ioctl (fd, CDIOCSETMUTE); - else if (strcasecmp (arg, "mono") == 0) - return ioctl (fd, CDIOCSETMONO); - else if (strcasecmp (arg, "stereo") == 0) - return ioctl (fd, CDIOCSETSTERIO); + if (! strncasecmp (arg, "left", strlen (arg))) { + return (ioctl (fd, CDIOCSETLEFT)); + } + else if (! strncasecmp (arg, "right", strlen (arg))) { + return (ioctl (fd, CDIOCSETRIGHT)); + } + else if (! strncasecmp (arg, "mono", strlen (arg))) { + return (ioctl (fd, CDIOCSETMONO)); + } + else if (! strncasecmp (arg, "stereo", strlen (arg))) { + return (ioctl (fd, CDIOCSETSTERIO)); + } + else if (! strncasecmp (arg, "mute", strlen (arg))) { + return (ioctl (fd, CDIOCSETMUTE)); + } if (2 != sscanf (arg, "%d %d", &l, &r)) { - printf ("Invalid command arguments\n"); + printf ("%s: Invalid command arguments\n", prog); return (0); } + return setvol (l, r); + + case CMD_HELP: + default: + help (); + return (0); } } @@ -269,53 +369,208 @@ int rc, n, start, end = 0, istart = 1, iend = 1; rc = ioctl (fd, CDIOREADTOCHEADER, &h); + if (rc < 0) return (rc); n = h.ending_track - h.starting_track + 1; rc = read_toc_entrys ((n + 1) * sizeof (struct cd_toc_entry)); + if (rc < 0) return (rc); - if (! *arg) - /* - * Play the whole disc - */ + if (! arg || ! *arg) + /* Play the whole disc */ return play_blocks (0, msf2lba (toc_buffer[n].addr.msf.minute, - toc_buffer[n].addr.msf.second, - toc_buffer[n].addr.msf.frame)); + toc_buffer[n].addr.msf.second, + toc_buffer[n].addr.msf.frame)); if (strchr (arg, '#')) { - /* - * Play block #blk [ len ] - */ + /* Play block #blk [ len ] */ int blk, len = 0; if (2 != sscanf (arg, "#%d%d", &blk, &len) && - 1 != sscanf (arg, "#%d", &blk)) { -err: printf ("Invalid command arguments\n"); - return (0); - } + 1 != sscanf (arg, "#%d", &blk)) + goto Clean_up; + if (len == 0) - len = msf2lba (toc_buffer[n].addr.msf.minute, - toc_buffer[n].addr.msf.second, - toc_buffer[n].addr.msf.frame) - blk; + len = msf2lba (toc_buffer[n].addr.msf.minute, + toc_buffer[n].addr.msf.second, + toc_buffer[n].addr.msf.frame) - blk; return play_blocks (blk, len); } if (strchr (arg, ':')) { /* * Play MSF m1:s1 [ .f1 ] [ m2:s2 [ .f2 ] ] + * + * Will now also undestand timed addresses relative + * to the beginning of a track in the form... + * + * tr1 m1:s1[.f1] [[tr2] [m2:s2[.f2]]] */ - int m1, m2 = 0, s1, s2 = 0, f1 = 0, f2 = 0; + unsigned tr1, tr2; + unsigned m1, m2, s1, s2, f1, f2; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (8 == sscanf (arg, "%d %d:%d.%d %d %d:%d.%d", + &tr1, &m1, &s1, &f1, &tr2, &m2, &s2, &f2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (7 == sscanf (arg, "%d %d:%d %d %d:%d.%d", + &tr1, &m1, &s1, &tr2, &m2, &s2, &f2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (7 == sscanf (arg, "%d %d:%d.%d %d %d:%d", + &tr1, &m1, &s1, &f1, &tr2, &m2, &s2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (7 == sscanf (arg, "%d %d:%d.%d %d:%d.%d", + &tr1, &m1, &s1, &f1, &m2, &s2, &f2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (6 == sscanf (arg, "%d %d:%d.%d %d:%d", + &tr1, &m1, &s1, &f1, &m2, &s2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (6 == sscanf (arg, "%d %d:%d %d:%d.%d", + &tr1, &m1, &s1, &m2, &s2, &f2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (6 == sscanf (arg, "%d %d:%d.%d %d %d", + &tr1, &m1, &s1, &f1, &tr2, &m2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (5 == sscanf (arg, "%d %d:%d %d:%d", &tr1, &m1, &s1, &m2, &s2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (5 == sscanf (arg, "%d %d:%d %d %d", + &tr1, &m1, &s1, &tr2, &m2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (5 == sscanf (arg, "%d %d:%d.%d %d", + &tr1, &m1, &s1, &f1, &tr2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (4 == sscanf (arg, "%d %d:%d %d", &tr1, &m1, &s1, &tr2)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (4 == sscanf (arg, "%d %d:%d.%d", &tr1, &m1, &s1, &f1)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + if (3 == sscanf (arg, "%d %d:%d", &tr1, &m1, &s1)) + goto Play_Relative_Addresses; + + tr2 = m2 = s2 = f2 = f1 = 0; + goto Try_Absolute_Timed_Addresses; + +Play_Relative_Addresses: + if (! tr1) + tr1 = 1; + else if (tr1 > n) + tr1 = n; + + if ((m1 > toc_buffer[tr1].addr.msf.minute) + || ((m1 == toc_buffer[tr1].addr.msf.minute) + && ((s1 > toc_buffer[tr1].addr.msf.second) + || ((s1 == toc_buffer[tr1].addr.msf.second) + && (f1 > toc_buffer[tr1].addr.msf.frame))))) { + printf ("Track %d is not that long.\n", tr1); + return (0); + } - if (6 != sscanf (arg, "%d:%d.%d%d:%d.%d", &m1, &s1, &f1, &m2, &s2, &f2) && + tr1--; + + f1 += toc_buffer[tr1].addr.msf.frame; + if (f1 >= 75) { + s1 += f1 / 75; + f1 %= 75; + } + + s1 += toc_buffer[tr1].addr.msf.second; + if (s1 >= 60) { + m1 += s1 / 60; + s1 %= 60; + } + + m1 += toc_buffer[tr1].addr.msf.minute; + + if (! tr2) { + if (m2 || s2 || f2) { + tr2 = tr1; + f2 += f1; + if (f2 >= 75) { + s2 += f2 / 75; + f2 %= 75; + } + + s2 += s1; + if (s2 > 60) { + m2 += s2 / 60; + s2 %= 60; + } + + m2 += m1; + } else { + tr2 = n; + m2 = toc_buffer[n].addr.msf.minute; + s2 = toc_buffer[n].addr.msf.second; + f2 = toc_buffer[n].addr.msf.frame; + } + } else if (tr2 > n) { + tr2 = n; + m2 = s2 = f2 = 0; + } else { + if (m2 || s2 || f2) + tr2--; + f2 += toc_buffer[tr2].addr.msf.frame; + if (f2 >= 75) { + s2 += f2 / 75; + f2 %= 75; + } + + s2 += toc_buffer[tr2].addr.msf.second; + if (s2 > 60) { + m2 += s2 / 60; + s2 %= 60; + } + + m2 += toc_buffer[tr2].addr.msf.minute; + } + + if ((tr2 < n) + && ((m2 > toc_buffer[n].addr.msf.minute) + || ((m2 == toc_buffer[n].addr.msf.minute) + && ((s2 > toc_buffer[n].addr.msf.second) + || ((s2 == toc_buffer[n].addr.msf.second) + && (f2 > toc_buffer[n].addr.msf.frame)))))) { + printf ("The playing time of the disc is not that long.\n"); + return (0); + } + return (play_msf (m1, s1, f1, m2, s2, f2)); + +Try_Absolute_Timed_Addresses: + if (6 != sscanf (arg, "%d:%d.%d%d:%d.%d", + &m1, &s1, &f1, &m2, &s2, &f2) && 5 != sscanf (arg, "%d:%d.%d%d:%d", &m1, &s1, &f1, &m2, &s2) && 5 != sscanf (arg, "%d:%d%d:%d.%d", &m1, &s1, &m2, &s2, &f2) && 3 != sscanf (arg, "%d:%d.%d", &m1, &s1, &f1) && 4 != sscanf (arg, "%d:%d%d:%d", &m1, &s1, &m2, &s2) && 2 != sscanf (arg, "%d:%d", &m1, &s1)) - goto err; + goto Clean_up; + if (m2 == 0) { m2 = toc_buffer[n].addr.msf.minute; s2 = toc_buffer[n].addr.msf.second; @@ -333,10 +588,15 @@ 2 != sscanf (arg, "%d.%d", &start, &istart) && 2 != sscanf (arg, "%d%d", &start, &end) && 1 != sscanf (arg, "%d", &start)) - goto err; + goto Clean_up; + if (end == 0) end = n; - return play_track (start, istart, end, iend); + return (play_track (start, istart, end, iend)); + +Clean_up: + printf ("%s: Invalid command arguments\n", prog); + return (0); } char *strstatus (int sts) @@ -358,47 +618,48 @@ struct ioc_vol v; int rc, i, n, trk, m, s, f; + rc = ioctl (fd, CDIOREADTOCHEADER, &h); + if (rc < 0) { + perror ("getting toc header"); + return (rc); + } + rc = status (&trk, &m, &s, &f); - if (rc >= 0) + if (rc >= 0) { if (verbose) printf ("Audio status = %d<%s>, current track = %d, current position = %d:%02d.%02d\n", rc, strstatus (rc), trk, m, s, f); else printf ("%d %d %d:%02d.%02d\n", rc, trk, m, s, f); - else + } else printf ("No current status info\n"); rc = ioctl (fd, CDIOCGETVOL, &v); - if (rc >= 0) + if (rc >= 0) { if (verbose) printf ("Left volume = %d, right volume = %d\n", v.vol[0], v.vol[1]); else printf ("%d %d\n", v.vol[0], v.vol[1]); - else + } else printf ("No volume info\n"); - rc = ioctl (fd, CDIOREADTOCHEADER, &h); - if (rc >= 0) - if (verbose) - printf ("Starting track = %d, ending track = %d, TOC size = %d bytes\n", - h.starting_track, h.ending_track, h.len); - else - printf ("%d %d %d\n", h.starting_track, - h.ending_track, h.len); - else { - perror ("getting toc header"); - return (rc); - } + if (verbose) + printf ("First track = %d, last track = %d, TOC size = %d bytes\n", + h.starting_track, h.ending_track, h.len); + else + printf ("%d %d %d\n", h.starting_track, h.ending_track, h.len); n = h.ending_track - h.starting_track + 1; rc = read_toc_entrys ((n + 1) * sizeof (struct cd_toc_entry)); if (rc < 0) return (rc); + if (verbose) { printf ("track start duration block length type\n"); printf ("-------------------------------------------------\n"); } + for (i = 0; i < n; i++) { printf ("%5d ", toc_buffer[i].track); prtrack (toc_buffer + i, 0); @@ -408,17 +669,17 @@ return (0); } -void lba2msf (int lba, u_char *m, u_char *s, u_char *f) +void lba2msf (unsigned int lba, u_char *m, u_char *s, u_char *f) { - lba += 150; /* block start offset */ - lba &= 0xffffff; /* negative lbas use only 24 bits */ + lba += 150; /* block start offset */ + lba &= 0xffffff; /* negative lbas use only 24 bits */ *m = lba / (60 * 75); lba %= (60 * 75); *s = lba / 75; *f = lba % 75; } -int msf2lba (u_char m, u_char s, u_char f) +unsigned int msf2lba (u_char m, u_char s, u_char f) { return (((m * 60) + s) * 75 + f) - 150; } @@ -447,7 +708,7 @@ /* Print duration, block, length, type */ printf ("%2d:%02d.%02d %6d %6d %5s\n", m, s, f, block, len, - e->control & 4 ? "data" : "audio"); + (e->control & 4) ? "data" : "audio"); } int play_track (int tstart, int istart, int tend, int iend) @@ -458,26 +719,29 @@ t.start_index = istart; t.end_track = tend; t.end_index = iend; + return ioctl (fd, CDIOCPLAYTRACKS, &t); } int play_blocks (int blk, int len) { - struct ioc_play_blocks t; + struct ioc_play_blocks t; t.blk = blk; t.len = len; + return ioctl (fd, CDIOCPLAYBLOCKS, &t); } -int setvol (int l, int r) +int setvol (int left, int right) { - struct ioc_vol v; + struct ioc_vol v; - v.vol[0] = l; - v.vol[1] = r; + v.vol[0] = left; + v.vol[1] = right; v.vol[2] = 0; v.vol[3] = 0; + return ioctl (fd, CDIOCSETVOL, &v); } @@ -489,13 +753,14 @@ t.starting_track = 1; t.data_len = len; t.data = toc_buffer; - return ioctl (fd, CDIOREADTOCENTRYS, (char *) &t); + + return (ioctl (fd, CDIOREADTOCENTRYS, (char *) &t)); } int play_msf (int start_m, int start_s, int start_f, - int end_m, int end_s, int end_f) + int end_m, int end_s, int end_f) { - struct ioc_play_msf a; + struct ioc_play_msf a; a.start_m = start_m; a.start_s = start_s; @@ -503,26 +768,30 @@ a.end_m = end_m; a.end_s = end_s; a.end_f = end_f; - return ioctl (fd, CDIOCPLAYMSF, (char *) &a); + + return (ioctl (fd, CDIOCPLAYMSF, (char *) &a)); } int status (int *trk, int *min, int *sec, int *frame) { - struct ioc_read_subchannel s; - struct cd_sub_channel_info data; + struct ioc_read_subchannel s; + struct cd_sub_channel_info data; bzero (&s, sizeof (s)); s.data = &data; s.data_len = sizeof (data); s.address_format = CD_MSF_FORMAT; s.data_format = CD_CURRENT_POSITION; + if (ioctl (fd, CDIOCREADSUBCHANNEL, (char *) &s) < 0) - return -1; + return -1; + *trk = s.data->what.position.track_number; *min = s.data->what.position.reladdr.msf.minute; *sec = s.data->what.position.reladdr.msf.second; *frame = s.data->what.position.reladdr.msf.frame; - return s.data->header.audio_status; + + return (s.data->header.audio_status); } char *input (int *cmd) @@ -532,10 +801,11 @@ do { if (verbose) - fprintf (stderr, "cd> "); + fprintf (stderr, "%s> ", prog); if (! fgets (buf, sizeof (buf), stdin)) { *cmd = CMD_QUIT; - return 0; + fprintf (stderr, "\r\n"); + return (0); } p = parse (buf, cmd); } while (! p); @@ -548,48 +818,57 @@ char *p; int len; - for (p=buf; *p; ++p) - if (*p == '\t') - *p = ' '; - else if (*p == '\n') - *p = 0; - - for (p=buf; *p; ++p) - if (*p == ' ') { - *p++ = 0; - break; - } - while (*p == ' ') - ++p; + for (p=buf; isspace (*p); p++) + continue; + + if (isdigit (*p) || ((p[0] == '#') && isdigit (p[1]))) { + *cmd = CMD_PLAY; + return (p); + } + + for (buf = p; *p && ! isspace (*p); p++) + continue; - len = strlen (buf); + len = p - buf; if (! len) return (0); + + if (*p) { /* It must be a spacing character! */ + char *q; + + *p++ = 0; + for (q=p; *q && *q != '\n' && *q != '\r'; q++) + continue; + *q = 0; + } + *cmd = -1; for (c=cmdtab; c->name; ++c) { - /* Try short command form. */ - if (! c->args && len == strlen (c->name) && - strncasecmp (buf, c->name, len) == 0) { + /* Is it an exact match? */ + if (! strcasecmp (buf, c->name)) { *cmd = c->command; break; } - /* Try long form. */ - if (strncasecmp (buf, c->name, len) != 0) - continue; - - /* Check inambiguity. */ - if (*cmd != -1) { - fprintf (stderr, "Ambiguous command\n"); - return (0); + /* Try short hand forms then... */ + if (len >= c->min && ! strncasecmp (buf, c->name, len)) { + if (*cmd != -1 && *cmd != c->command) { + fprintf (stderr, "Ambiguous command\n"); + return (0); + } + *cmd = c->command; } - *cmd = c->command; } + if (*cmd == -1) { - fprintf (stderr, "Invalid command, enter ``help'' for command list\n"); + fprintf (stderr, "%s: Invalid command, enter ``help'' for commands.\n", + prog); return (0); } - return p; + + while (isspace (*p)) + p++; + return (p); } int open_cd () @@ -598,25 +877,31 @@ if (fd > -1) return (1); + if (*cdname == '/') strcpy (devbuf, cdname); else if (*cdname == 'r') sprintf (devbuf, "/dev/%s", cdname); else sprintf (devbuf, "/dev/r%s", cdname); + fd = open (devbuf, O_RDONLY); + if (fd < 0 && errno == ENOENT) { - strcat (devbuf, "c"); + strcat (devbuf, DEFAULT_CD_PARTITION); fd = open (devbuf, O_RDONLY); } + if (fd < 0) { - if (errno != ENXIO) { - perror (devbuf); - exit (1); + if (errno == ENXIO) { + /* ENXIO has an overloaded meaning here. + * The original "Device not configured" should + * be interpreted as "No disc in drive %s". */ + fprintf (stderr, "%s: No disc in drive %s.\n", prog, devbuf); + return (0); } - /* open says 'Device not configured' if no cd in */ - fprintf (stderr, "open: No CD in\n"); - return (0); + perror (devbuf); + exit (1); } return (1); } >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199512101442.RAA02429>