summaryrefslogtreecommitdiff
path: root/usr.bin/cdio/cdio.c
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2006-01-20 00:58:33 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2006-01-20 00:58:33 +0000
commit9d45f58f48739d444863ef5368ca3fc46eead98e (patch)
tree33afc1d5096bd0e66a429bace2b10887c2dc492c /usr.bin/cdio/cdio.c
parent29249f496114688844de0baa9bcf908fe99b7dc3 (diff)
Clean up command line parsing, don't accept trailing garbage, add in
missing command line forms, zero variables that will not be filled in by a particular sscanf() call. Make 'play tr1 m1:s1 m2:s2' play from the point in time 'tr1 m1:s1' to the point in time 'm2:s2', instead of from 'tr1 m1:s1' for a period of m2:s2. Documenting this command is next. Closes last issues Juha Erkilla pointed out in PR #4957. Tested by Juha.
Diffstat (limited to 'usr.bin/cdio/cdio.c')
-rw-r--r--usr.bin/cdio/cdio.c453
1 files changed, 291 insertions, 162 deletions
diff --git a/usr.bin/cdio/cdio.c b/usr.bin/cdio/cdio.c
index a35bb65db1d..784d54f0a42 100644
--- a/usr.bin/cdio/cdio.c
+++ b/usr.bin/cdio/cdio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cdio.c,v 1.46 2006/01/11 01:29:07 krw Exp $ */
+/* $OpenBSD: cdio.c,v 1.47 2006/01/20 00:58:32 krw Exp $ */
/* Copyright (c) 1995 Serge V. Vakulenko
* All rights reserved.
@@ -117,9 +117,8 @@ struct cmdtab {
{ CMD_INFO, "info", 1, "" },
{ CMD_NEXT, "next", 1, "" },
{ CMD_PAUSE, "pause", 2, "" },
-{ CMD_PLAY, "play", 1, "min1:sec1[.fram1] [min2:sec2[.fram2]]" },
{ CMD_PLAY, "play", 1, "track1[.index1] [track2[.index2]]" },
-{ CMD_PLAY, "play", 1, "tr1 m1:s1[.f1] [[tr2] [m2:s2[.f2]]]" },
+{ CMD_PLAY, "play", 1, "[tr1] m1:s1[.f1] [tr2] [m2:s2[.f2]]" },
{ CMD_PLAY, "play", 1, "[#block [len]]" },
{ CMD_PREV, "previous", 2, "" },
{ CMD_QUIT, "quit", 1, "" },
@@ -471,7 +470,7 @@ run(int cmd, char *arg)
if (!strncasecmp(arg, "mute", strlen(arg)))
return ioctl(fd, CDIOCSETMUTE);
- if (2 != sscanf(arg, "%d %d", &l, &r)) {
+ if (2 != sscanf(arg, "%d%d", &l, &r)) {
printf("%s: Invalid command arguments\n", __progname);
return (0);
}
@@ -507,32 +506,50 @@ int
play(char *arg)
{
struct ioc_toc_header h;
- int rc, n, start, end = 0, istart = 1, iend = 1;
+ unsigned char tm, ts, tf;
+ unsigned int tr1, tr2, m1, m2, s1, s2, f1, f2, i1, i2;
+ unsigned int blk, len, n;
+ char c;
+ int rc;
rc = ioctl(fd, CDIOREADTOCHEADER, &h);
if (rc < 0)
return (rc);
+ if (h.starting_track > h.ending_track) {
+ printf("TOC starting_track > TOC ending_track\n");
+ return (0);
+ }
+
n = h.ending_track - h.starting_track + 1;
rc = read_toc_entrys((n + 1) * sizeof (struct cd_toc_entry));
if (rc < 0)
return (rc);
+ /*
+ * Truncate trailing white space. Then by adding %c to the end of the
+ * sscanf() formats we catch any errant trailing characters.
+ */
+ rc = strlen(arg) - 1;
+ while (rc >= 0 && isspace(arg[rc])) {
+ arg[rc] = '\0';
+ rc--;
+ }
+
if (! arg || ! *arg) {
/* Play the whole disc */
- return (play_track(h.starting_track, 1,
- h.ending_track, 1));
+ return (play_track(h.starting_track, 1, h.ending_track, 1));
}
if (strchr(arg, '#')) {
/* Play block #blk [ len ] */
- int blk, len = 0;
-
- if (2 != sscanf(arg, "#%d%d", &blk, &len) &&
- 1 != sscanf(arg, "#%d", &blk))
- goto Clean_up;
+ if (2 != sscanf(arg, "#%u%u%c", &blk, &len, &c) &&
+ 1 != sscanf(arg, "#%u%c", &blk, &c)) {
+ printf("%s: Invalid command arguments\n", __progname);
+ return (0);
+ }
if (len == 0) {
if (msf)
@@ -545,176 +562,288 @@ play(char *arg)
return play_blocks(blk, len);
}
- if (strchr(arg, ':')) {
+ if (strchr(arg, ':') == NULL) {
/*
- * 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]]]
+ * Play track tr1[.i1] [tr2[.i2]]
*/
- int tr1, tr2;
- unsigned int m1, m2, s1, s2, f1, f2;
- unsigned char tm, ts, tf;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (8 == sscanf(arg, "%d %u:%u.%u %d %u:%u.%u",
- &tr1, &m1, &s1, &f1, &tr2, &m2, &s2, &f2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (7 == sscanf(arg, "%d %u:%u %d %u:%u.%u",
- &tr1, &m1, &s1, &tr2, &m2, &s2, &f2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (7 == sscanf(arg, "%d %u:%u.%u %d %u:%u",
- &tr1, &m1, &s1, &f1, &tr2, &m2, &s2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (7 == sscanf(arg, "%d %u:%u.%u %u:%u.%u",
- &tr1, &m1, &s1, &f1, &m2, &s2, &f2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (6 == sscanf(arg, "%d %u:%u.%u %u:%u",
- &tr1, &m1, &s1, &f1, &m2, &s2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (6 == sscanf(arg, "%d %u:%u %u:%u.%u",
- &tr1, &m1, &s1, &m2, &s2, &f2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (6 == sscanf(arg, "%d %u:%u.%u %d %u",
- &tr1, &m1, &s1, &f1, &tr2, &m2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (5 == sscanf(arg, "%d %u:%u %u:%u", &tr1, &m1, &s1, &m2, &s2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (5 == sscanf(arg, "%d %u:%u %d %u",
- &tr1, &m1, &s1, &tr2, &m2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (5 == sscanf(arg, "%d %u:%u.%u %d",
- &tr1, &m1, &s1, &f1, &tr2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (4 == sscanf(arg, "%d %u:%u %u", &tr1, &m1, &s1, &tr2))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (4 == sscanf(arg, "%d %u:%u.%u", &tr1, &m1, &s1, &f1))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- if (3 == sscanf(arg, "%d %u:%u", &tr1, &m1, &s1))
- goto Play_Relative_Addresses;
-
- tr2 = m2 = s2 = f2 = f1 = 0;
- goto Try_Absolute_Timed_Addresses;
-
-Play_Relative_Addresses:
- if (tr1 < 1 || tr1 > n) {
- printf("Track %d not found\n", tr1);
+ if (4 == sscanf(arg, "%u.%u%u.%u%c", &tr1, &i1, &tr2, &i2, &c))
+ goto play_track;
+
+ i2 = 1;
+ if (3 == sscanf(arg, "%u.%u%u%c", &tr1, &i1, &tr2, &c))
+ goto play_track;
+
+ i1 = 1;
+ if (3 == sscanf(arg, "%u%u.%u%c", &tr1, &tr2, &i2, &c))
+ goto play_track;
+
+ tr2 = 0;
+ i2 = 1;
+ if (2 == sscanf(arg, "%u.%u%c", &tr1, &i1, &c))
+ goto play_track;
+
+ i1 = i2 = 1;
+ if (2 == sscanf(arg, "%u%u%c", &tr1, &tr2, &c))
+ goto play_track;
+
+ i1 = i2 = 1;
+ tr2 = 0;
+ if (1 == sscanf(arg, "%u%c", &tr1, &c))
+ goto play_track;
+
+ printf("%s: Invalid command arguments\n", __progname);
+ return (0);
+
+play_track:
+ if (tr1 > n || tr2 > n) {
+ printf("Track number must be between 0 and %u\n", n);
return (0);
- } else if (tr2 < 0 || tr2 > n) {
- printf("Track %d not found\n", tr2);
+ } else if (tr2 == 0)
+ tr2 = h.ending_track;
+
+ if (tr1 > tr2) {
+ printf("starting_track > ending_track\n");
return (0);
}
- /* Change (m1,s1,f1) from tr1 to disc relative. */
+ return (play_track(tr1, i1, tr2, i2));
+ }
+
+ /*
+ * Play MSF [tr1] m1:s1[.f1] [tr2] [m2:s2[.f2]]
+ *
+ * Start Time End Time
+ * ---------- --------
+ * tr1 m1:s1.f1 tr2 m2:s2.f2
+ * tr1 m1:s1 tr2 m2:s2.f2
+ * tr1 m1:s1.f1 tr2 m2:s2
+ * tr1 m1:s1 tr2 m2:s2
+ * m1:s1.f1 tr2 m2:s2.f2
+ * m1:s1 tr2 m2:s2.f2
+ * m1:s1.f1 tr2 m2:s2
+ * m1:s1 tr2 m2:s2
+ * tr1 m1:s1.f1 m2:s2.f2
+ * tr1 m1:s1 m2:s2.f2
+ * tr1 m1:s1.f1 m2:s2
+ * tr1 m1:s1 m2:s2
+ * m1:s1.f1 m2:s2.f2
+ * m1:s1 m2:s2.f2
+ * m1:s1.f1 m2:s2
+ * m1:s1 m2:s2
+ * tr1 m1:s1.f1 tr2
+ * tr1 m1:s1 tr2
+ * m1:s1.f1 tr2
+ * m1:s1 tr2
+ * tr1 m1:s1.f1 <end of disc>
+ * tr1 m1:s1 <end of disc>
+ * m1:s1.f1 <end of disc>
+ * m1:s1 <end of disc>
+ */
+
+ /* tr1 m1:s1.f1 tr2 m2:s2.f2 */
+ if (8 == sscanf(arg, "%u%u:%u.%u%u%u:%u.%u%c",
+ &tr1, &m1, &s1, &f1, &tr2, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1 tr2 m2:s2.f2 */
+ f1 = 0;
+ if (7 == sscanf(arg, "%u%u:%u%u%u:%u.%u%c",
+ &tr1, &m1, &s1, &tr2, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1.f1 tr2 m2:s2 */
+ f2 =0;
+ if (7 == sscanf(arg, "%u%u:%u.%u%u%u:%u%c",
+ &tr1, &m1, &s1, &f1, &tr2, &m2, &s2, &c))
+ goto play_msf;
+
+ /* m1:s1.f1 tr2 m2:s2.f2 */
+ tr1 = 0;
+ if (7 == sscanf(arg, "%u:%u.%u%u%u:%u.%u%c",
+ &m1, &s1, &f1, &tr2, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1.f1 m2:s2.f2 */
+ tr2 = 0;
+ if (7 == sscanf(arg, "%u%u:%u.%u%u:%u.%u%c",
+ &tr1, &m1, &s1, &f1, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* m1:s1 tr2 m2:s2.f2 */
+ tr1 = f1 = 0;
+ if (6 == sscanf(arg, "%u:%u%u%u:%u.%u%c",
+ &m1, &s1, &tr2, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* m1:s1.f1 tr2 m2:s2 */
+ tr1 = f2 = 0;
+ if (6 == sscanf(arg, "%u:%u.%u%u%u:%u%c",
+ &m1, &s1, &f1, &tr2, &m2, &s2, &c))
+ goto play_msf;
+
+ /* m1:s1.f1 m2:s2.f2 */
+ tr1 = tr2 = 0;
+ if (6 == sscanf(arg, "%u:%u.%u%u:%u.%u%c",
+ &m1, &s1, &f1, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1.f1 m2:s2 */
+ tr2 = f2 = 0;
+ if (6 == sscanf(arg, "%u%u:%u.%u%u:%u%c",
+ &tr1, &m1, &s1, &f1, &m2, &s2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1 m2:s2.f2 */
+ tr2 = f1 = 0;
+ if (6 == sscanf(arg, "%u%u:%u%u:%u.%u%c",
+ &tr1, &m1, &s1, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1 tr2 m2:s2 */
+ f1 = f2 = 0;
+ if (6 == sscanf(arg, "%u%u:%u%u%u:%u%c",
+ &tr1, &m1, &s1, &tr2, &m2, &s2, &c))
+ goto play_msf;
+
+ /* m1:s1 tr2 m2:s2 */
+ tr1 = f1 = f2 = 0;
+ if (5 == sscanf(arg, "%u:%u%u%u:%u%c", &m1, &s1, &tr2, &m2, &s2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1 m2:s2 */
+ f1 = tr2 = f2 = 0;
+ if (5 == sscanf(arg, "%u%u:%u%u:%u%c", &tr1, &m1, &s1, &m2, &s2, &c))
+ goto play_msf;
+
+ /* m1:s1 m2:s2.f2 */
+ tr1 = f1 = tr2 = 0;
+ if (5 == sscanf(arg, "%u:%u%u:%u.%u%c", &m1, &s1, &m2, &s2, &f2, &c))
+ goto play_msf;
+
+ /* m1:s1.f1 m2:s2 */
+ tr1 = tr2 = f2 = 0;
+ if (5 == sscanf(arg, "%u:%u.%u%u:%u%c", &m1, &s1, &f1, &m2, &s2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1.f1 tr2 */
+ m2 = s2 = f2 = 0;
+ if (5 == sscanf(arg, "%u%u:%u.%u%u%c", &tr1, &m1, &s1, &f1, &tr2, &c))
+ goto play_msf;
+
+ /* m1:s1 m2:s2 */
+ tr1 = f1 = tr2 = f2 = 0;
+ if (4 == sscanf(arg, "%u:%u%u:%u%c", &m1, &s1, &m2, &s2, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1.f1 <end of disc> */
+ tr2 = m2 = s2 = f2 = 0;
+ if (4 == sscanf(arg, "%u%u:%u.%u%c", &tr1, &m1, &s1, &f1, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1 tr2 */
+ f1 = m2 = s2 = f2 = 0;
+ if (4 == sscanf(arg, "%u%u:%u%u%c", &tr1, &m1, &s1, &tr2, &c))
+ goto play_msf;
+
+ /* m1:s1.f1 tr2 */
+ tr1 = m2 = s2 = f2 = 0;
+ if (4 == sscanf(arg, "%u%u:%u%u%c", &m1, &s1, &f1, &tr2, &c))
+ goto play_msf;
+
+ /* m1:s1.f1 <end of disc> */
+ tr1 = tr2 = m2 = s2 = f2 = 0;
+ if (3 == sscanf(arg, "%u:%u.%u%c", &m1, &s1, &f1, &c))
+ goto play_msf;
+
+ /* tr1 m1:s1 <end of disc> */
+ f1 = tr2 = m2 = s2 = f2 = 0;
+ if (3 == sscanf(arg, "%u%u:%u%c", &tr1, &m1, &s1, &c))
+ goto play_msf;
+
+ /* m1:s1 tr2 */
+ tr1 = f1 = m2 = s2 = f2 = 0;
+ if (3 == sscanf(arg, "%u:%u%u%c", &m1, &s1, &tr2, &c))
+ goto play_msf;
+
+ /* m1:s1 <end of disc> */
+ tr1 = f1 = tr2 = m2 = s2 = f2 = 0;
+ if (2 == sscanf(arg, "%u:%u%c", &m1, &s1, &c))
+ goto play_msf;
+
+ printf("%s: Invalid command arguments\n", __progname);
+ return (0);
+
+play_msf:
+ if (tr1 > n || tr2 > n) {
+ printf("Track number must be between 0 and %u\n", n);
+ return (0);
+ } else if (m1 > 99 || m2 > 99) {
+ printf("Minutes must be between 0 and 99\n");
+ return (0);
+ } else if (s1 > 59 || s2 > 59) {
+ printf("Seconds must be between 0 and 59\n");
+ return (0);
+ } if (f1 > 74 || f2 > 74) {
+ printf("Frames number must be between 0 and 74\n");
+ return (0);
+ }
+
+ if (tr1 > 0) {
+ /*
+ * Start time is relative to tr1, Add start time of tr1
+ * to (m1,s1,f1) to yield absolute start time.
+ */
toc2msf(tr1, &tm, &ts, &tf);
addmsf(&m1, &s1, &f1, tm, ts, tf);
/* Compare (m1,s1,f1) to start time of next track. */
toc2msf(tr1+1, &tm, &ts, &tf);
if (cmpmsf(m1, s1, f1, tm, ts, tf) == 1) {
- printf("Track %d is not that long.\n", tr1);
+ printf("Track %u is not that long.\n", tr1);
return (0);
}
+ }
- if (!(tr2 || m2 || s2 || f2)) {
- /* No end time specified. Play to end of disc. */
- toc2msf(n+1, &tm, &ts, &tf);
- m2 = tm;
- s2 = ts;
- f2 = tf;
- } else if (tr2 != 0) {
- /*
- * End time specified relative to tr2. Change
- * (m2,s2,f2) from tr2 to disc relative.
- */
- toc2msf(tr2, &tm, &ts, &tf);
- addmsf(&m2, &s2, &f2, tm, ts, tf);
- /* Compare (m2,s2,f2) to start time of next track. */
- toc2msf(tr2+1, &tm, &ts, &tf);
- if (cmpmsf(m2, s2, f2, tm, ts, tf) == 1) {
- printf("Track %d is not that long.\n", tr2);
- return (0);
- }
- } else {
- /*
- * Duration rather than end time specified. Change
- * (m2,s2,f2) from (m1,s1,f1) to disc relative.
- */
- addmsf(&m2, &s2, &f2, m1, s1, f1);
- /* Compare (m2,s2,f2) to end of disc. */
- toc2msf(tr2+1, &tm, &ts, &tf);
- if (cmpmsf(m2, s2, f2, tm, ts, tf) == 1) {
- printf("Disc is not that long.\n");
- return (0);
- }
- }
+ toc2msf(n+1, &tm, &ts, &tf);
+ if (cmpmsf(m1, s1, f1, tm, ts, tf) == 1) {
+ printf("Start time is after end of disc.\n");
+ return (0);
+ }
+
+ if (tr2 > 0) {
+ /*
+ * End time is relative to tr2, Add start time of tr2
+ * to (m2,s2,f2) to yield absolute end time.
+ */
+ toc2msf(tr2, &tm, &ts, &tf);
+ addmsf(&m2, &s2, &f2, tm, ts, tf);
- return (play_msf(m1, s1, f1, m2, s2, f2));
-
-Try_Absolute_Timed_Addresses:
- if (6 != sscanf(arg, "%u:%u.%u%u:%u.%u",
- &m1, &s1, &f1, &m2, &s2, &f2) &&
- 5 != sscanf(arg, "%u:%u.%u%u:%u", &m1, &s1, &f1, &m2, &s2) &&
- 5 != sscanf(arg, "%u:%u%u:%u.%u", &m1, &s1, &m2, &s2, &f2) &&
- 3 != sscanf(arg, "%u:%u.%u", &m1, &s1, &f1) &&
- 4 != sscanf(arg, "%u:%u%u:%u", &m1, &s1, &m2, &s2) &&
- 2 != sscanf(arg, "%u:%u", &m1, &s1))
- goto Clean_up;
-
- if (m2 == 0) {
- toc2msf(n+1, &tm, &ts, &tf);
- m2 = tm;
- s2 = ts;
- f2 = tf;
+ /* Compare (m2,s2,f2) to start time of next track. */
+ toc2msf(tr2+1, &tm, &ts, &tf);
+ if (cmpmsf(m2, s2, f2, tm, ts, tf) == 1) {
+ printf("Track %u is not that long.\n", tr2);
+ return (0);
}
+ }
- return play_msf(m1, s1, f1, m2, s2, f2);
+ toc2msf(n+1, &tm, &ts, &tf);
+
+ if (!(tr2 || m2 || s2 || f2)) {
+ /* Play to end of disc. */
+ m2 = tm;
+ s2 = ts;
+ f2 = tf;
+ } else if (cmpmsf(m2, s2, f2, tm, ts, tf) == 1) {
+ printf("End time is after end of disc.\n");
+ return (0);
}
- /*
- * Play track trk1 [ .idx1 ] [ trk2 [ .idx2 ] ]
- */
- if (4 != sscanf(arg, "%d.%d%d.%d", &start, &istart, &end, &iend) &&
- 3 != sscanf(arg, "%d.%d%d", &start, &istart, &end) &&
- 3 != sscanf(arg, "%d%d.%d", &start, &end, &iend) &&
- 2 != sscanf(arg, "%d.%d", &start, &istart) &&
- 2 != sscanf(arg, "%d%d", &start, &end) &&
- 1 != sscanf(arg, "%d", &start))
- goto Clean_up;
-
- if (end == 0)
- end = h.ending_track;
- return (play_track(start, istart, end, iend));
-
-Clean_up:
- printf("%s: Invalid command arguments\n", __progname);
- return (0);
+ if (cmpmsf(m1, s1, f1, m2, s2, f2) == 1) {
+ printf("Start time is after end time.\n");
+ return (0);
+ }
+
+ return play_msf(m1, s1, f1, m2, s2, f2);
}
/* ARGSUSED */