Subject: proposal: fix for PR 18444
To: None <tech-userlevel@netbsd.org>
From: Ignatios Souvatzis <is@netbsd.org>
List: tech-userlevel
Date: 01/25/2003 19:14:57
--Dxnq1zWXvFF0Q93v
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi folks,

I fixed cdplays misbehaviour documented in PR 18444, and a few other corner
cases which were wrong, too. Comments?

Index: cdplay.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/cdplay/cdplay.c,v
retrieving revision 1.21
diff -u -r1.21 cdplay.c
--- cdplay.c	2002/09/28 21:48:35	1.21
+++ cdplay.c	2003/01/25 18:08:39
@@ -50,6 +50,8 @@
 #include <sys/file.h>
 #include <sys/cdio.h>
=20
+#include <assert.h>
+
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
@@ -148,6 +150,10 @@
 const char	*strstatus(int);
 void 	usage(void);
=20
+void	toc2msf(u_int, u_int *, u_int *, u_int *);
+int	toc2lba(u_int);
+void	addmsf(u_int *, u_int *, u_int *, u_int, u_int, u_int);
+
 int
 main(int argc, char **argv)
 {
@@ -451,7 +457,7 @@
 int
 play(const char *arg, int fromuser)
 {
-	int rv, n, start, end, istart, iend, blk, len;
+	int rv, n, start, end, istart, iend, blk, len, relend;
 	u_int tr1, tr2, m1, m2, s1, s2, f1, f2, tm, ts, tf;
 	struct ioc_toc_header h;
=20
@@ -486,12 +492,7 @@
 			goto Clean_up;
=20
 		if (len =3D=3D 0) {
-			if (msf)
-				len =3D msf2lba(toc_buffer[n].addr.msf.minute,
-				    toc_buffer[n].addr.msf.second,
-				    toc_buffer[n].addr.msf.frame) - blk;
-			else
-				len =3D be32toh(toc_buffer[n].addr.lba) - blk;
+			len =3D toc2lba(n);
 		}
 		return (play_blocks(blk, len));
 	}
@@ -505,6 +506,7 @@
 		 *
 		 *      tr1 m1:s1[.f1] [[tr2] [m2:s2[.f2]]]
 		 */
+		relend =3D 1;
 		tr2 =3D m2 =3D s2 =3D f2 =3D f1 =3D 0;
 		if (8 =3D=3D sscanf(arg, "%d %d:%d.%d %d %d:%d.%d", &tr1, &m1,
 		    &s1, &f1, &tr2, &m2, &s2, &f2))
@@ -541,6 +543,11 @@
 			goto Play_Relative_Addresses;
=20
 		tr2 =3D m2 =3D s2 =3D f2 =3D f1 =3D 0;
+		if (6 =3D=3D sscanf(arg, "%d %d:%d %d %d:%d", &tr1, &m1, &s1, &tr2,
+		    &m2, &s2))
+			goto Play_Relative_Addresses;
+
+		tr2 =3D m2 =3D s2 =3D f2 =3D f1 =3D 0;
 		if (5 =3D=3D sscanf(arg, "%d %d:%d %d:%d", &tr1, &m1, &s1, &m2,
 		    &s2))
 			goto Play_Relative_Addresses;
@@ -550,6 +557,7 @@
 		    &m2))
 			goto Play_Relative_Addresses;
=20
+		relend=3D0;
 		tr2 =3D m2 =3D s2 =3D f2 =3D f1 =3D 0;
 		if (5 =3D=3D sscanf(arg, "%d %d:%d.%d %d", &tr1, &m1, &s1, &f1,
 		    &tr2))
@@ -576,93 +584,43 @@
 		else if (tr1 > n)
 			tr1 =3D n;
=20
-		if (msf) {
-			tm =3D toc_buffer[tr1].addr.msf.minute;
-			ts =3D toc_buffer[tr1].addr.msf.second;
-			tf =3D toc_buffer[tr1].addr.msf.frame;
-		} else
-			lba2msf(be32toh(toc_buffer[tr1].addr.lba), &tm, &ts, &tf);
+		toc2msf(tr1-1, &tm, &ts, &tf);
+		addmsf(&m1, &s1, &f1, tm, ts, tf);
+
+		toc2msf(tr1, &tm, &ts, &tf);
+
 		if ((m1 > tm) || ((m1 =3D=3D tm) && ((s1 > ts) || ((s1 =3D=3D ts) &&
 		    (f1 > tf))))) {
 			warnx("Track %d is not that long.", tr1);
 			return (0);
 		}
-		tr1--;
+		tr1--;	/* XXXXX ???? */
=20
-		f1 +=3D tf;
-		if (f1 >=3D 75) {
-			s1 +=3D f1 / 75;
-			f1 %=3D 75;
-		}
-		s1 +=3D ts;
-		if (s1 >=3D 60) {
-			m1 +=3D s1 / 60;
-			s1 %=3D 60;
-		}
-		m1 +=3D tm;
=20
 		if (!tr2) {
-			if (m2 || s2 || f2) {
+			if (relend) {
 				tr2 =3D tr1;
-				f2 +=3D f1;
-				if (f2 >=3D 75) {
-					s2 +=3D f2 / 75;
-					f2 %=3D 75;
-				}
-				s2 +=3D s1;
-				if (s2 > 60) {
-					m2 +=3D s2 / 60;
-					s2 %=3D 60;
-				}
-				m2 +=3D m1;
+
+				addmsf(&m2, &s2, &f2, m1, s1, f1);
 			} else {
 				tr2 =3D n;
-				if (msf) {
-					m2 =3D toc_buffer[n].addr.msf.minute;
-					s2 =3D toc_buffer[n].addr.msf.second;
-					f2 =3D toc_buffer[n].addr.msf.frame;
-				} else {
-					lba2msf(be32toh(toc_buffer[n].addr.lba),
-					    &tm, &ts, &tf);
-					m2 =3D tm;
-					s2 =3D ts;
-					f2 =3D tf;
-				}
+
+				toc2msf(n, &m2, &s2, &f2);
 			}
 		} else {
 			if (tr2 > n) {
 				tr2 =3D n;
 				m2 =3D s2 =3D f2 =3D 0;
 			} else {
-				if (m2 || s2 || f2)
+				if (relend)
 					tr2--;
-				if (msf) {
-					tm =3D toc_buffer[tr2].addr.msf.minute;
-					ts =3D toc_buffer[tr2].addr.msf.second;
-					tf =3D toc_buffer[tr2].addr.msf.frame;
-				} else
-					lba2msf(be32toh(toc_buffer[tr2].addr.lba),
-					    &tm, &ts, &tf);
-				f2 +=3D tf;
-				if (f2 >=3D 75) {
-					s2 +=3D f2 / 75;
-					f2 %=3D 75;
-				}
-				s2 +=3D ts;
-				if (s2 > 60) {
-					m2 +=3D s2 / 60;
-					s2 %=3D 60;
-				}
-				m2 +=3D tm;
+
+				toc2msf(tr2, &tm, &ts, &tf);
+				addmsf(&m2, &s2, &f2, tm, ts, tf);
 			}
 		}
=20
-		if (msf) {
-			tm =3D toc_buffer[n].addr.msf.minute;
-			ts =3D toc_buffer[n].addr.msf.second;
-			tf =3D toc_buffer[n].addr.msf.frame;
-		} else
-			lba2msf(be32toh(toc_buffer[n].addr.lba), &tm, &ts, &tf);
+		toc2msf(n, &tm, &ts, &tf);
=20
 		if ((tr2 < n) && ((m2 > tm) || ((m2 =3D=3D tm) && ((s2 > ts) ||
 		    ((s2 =3D=3D ts) && (f2 > tf)))))) {
@@ -1136,4 +1094,61 @@
 	}
=20
 	return (1);
+}
+
+void
+toc2msf(u_int i, u_int *m, u_int *s, u_int *f)
+{
+	struct cd_toc_entry *ctep;
+
+	assert(i >=3D 0);
+	assert(i < 100);
+
+	ctep =3D &toc_buffer[i];
+
+	if (msf) {
+		*m =3D ctep->addr.msf.minute;
+		*s =3D ctep->addr.msf.second;
+		*f =3D ctep->addr.msf.frame;
+	} else {
+		lba2msf(be32toh(ctep->addr.lba), m, s, f);
+	}
+}
+
+int
+toc2lba(u_int i)
+{
+	struct cd_toc_entry *ctep;
+
+	assert(i > 0);
+	assert(i < 100);
+
+	ctep =3D &toc_buffer[i-1];
+
+	if (msf) {
+		return msf2lba(
+		    ctep->addr.msf.minute,
+		    ctep->addr.msf.second,
+		    ctep->addr.msf.frame);
+	} else {
+		return be32toh(ctep->addr.lba);
+	}
+}
+
+void
+addmsf(u_int *m, u_int *s, u_int *f, u_int m2, u_int s2, u_int f2)
+{
+	*f +=3D f2;
+	if (*f > 75) {
+		*s +=3D *f / 75;
+		*f %=3D 75;
+	}
+
+	*s +=3D s2;
+	if (*s > 60) {
+		*m +=3D *s / 60;
+		*s %=3D 60;
+	}
+
+	*m +=3D m2;
 }
--=20
seal your e-mail: http://www.gnupg.org/

--Dxnq1zWXvFF0Q93v
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (NetBSD)

iD8DBQE+MtQOPCRcZ/VMtk4RAoytAJ0Rv500f0CPwVvN2xs/WX8tsLBHpgCfbisO
nTrUDCopVg1w5g0uDoFVi0E=
=WCse
-----END PGP SIGNATURE-----

--Dxnq1zWXvFF0Q93v--