summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/cdcontrol/cdcontrol.118
-rw-r--r--usr.sbin/cdcontrol/cdcontrol.c71
2 files changed, 78 insertions, 11 deletions
diff --git a/usr.sbin/cdcontrol/cdcontrol.1 b/usr.sbin/cdcontrol/cdcontrol.1
index 010e783..12afdd5 100644
--- a/usr.sbin/cdcontrol/cdcontrol.1
+++ b/usr.sbin/cdcontrol/cdcontrol.1
@@ -44,9 +44,17 @@ Suffix `c' is added to the device name if needed.
The available commands are listed below. Only as many
characters as are required to uniquely identify a command
need be specified.
-Word
-.Em play
-can be omitted.
+The word
+.Cm play
+can be omitted or the characters
+.Dq +
+and
+.Dq -
+can be used in the
+place of
+.Cm next
+and
+.Cm prev .
.Bl -tag -width Cm
.It Cm play Ar first_track Op Ar last_track
Play from track
@@ -82,6 +90,10 @@ Play starting from the logical block
using
.Ar length
logical blocks.
+.It Cm next Op Ar tracks
+Skip forward a number of tracks (default 1).
+.It Cm prev Op Ar tracks
+Skip backward a number of tracks (default 1).
.It Cm pause
Stop playing.
Do not stop the disc.
diff --git a/usr.sbin/cdcontrol/cdcontrol.c b/usr.sbin/cdcontrol/cdcontrol.c
index 94ae357..e8ab6c7 100644
--- a/usr.sbin/cdcontrol/cdcontrol.c
+++ b/usr.sbin/cdcontrol/cdcontrol.c
@@ -23,19 +23,20 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
+#include <sys/cdio.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
+#include <histedit.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <sys/file.h>
-#include <sys/cdio.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <histedit.h>
+#include <vis.h>
#define VERSION "2.0"
@@ -69,6 +70,8 @@ static const char rcsid[] =
#define CMD_SET 13
#define CMD_STATUS 14
#define CMD_CDID 15
+#define CMD_NEXT 16
+#define CMD_PREVIOUS 17
#define STATUS_AUDIO 0x1
#define STATUS_MEDIA 0x2
#define STATUS_VOLUME 0x4
@@ -85,11 +88,13 @@ struct cmdtab {
{ CMD_HELP, "?", 1, 0 },
{ CMD_HELP, "help", 1, "" },
{ 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, "[#block [len]]" },
+{ CMD_PREVIOUS, "previous", 2, "" },
{ CMD_QUIT, "quit", 1, "" },
{ CMD_RESET, "reset", 4, "" },
{ CMD_RESUME, "resume", 1, "" },
@@ -115,6 +120,7 @@ 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 next_prev __P((char *arg, int));
int play __P((char *arg));
int info __P((char *arg));
int cdid __P((void));
@@ -287,6 +293,16 @@ int run (int cmd, char *arg)
return pstatus (arg);
+ case CMD_NEXT:
+ case CMD_PREVIOUS:
+ if (fd < 0 && ! open_cd ())
+ return (0);
+
+ while (isspace (*arg))
+ arg++;
+
+ return next_prev (arg, cmd);
+
case CMD_PAUSE:
if (fd < 0 && ! open_cd ())
return (0);
@@ -690,6 +706,36 @@ Clean_up:
return (0);
}
+int next_prev (char *arg, int cmd)
+{
+ struct ioc_toc_header h;
+ int dir, junk, n, off, rc, trk;
+
+ dir = (cmd == CMD_NEXT) ? 1 : -1;
+ rc = ioctl (fd, CDIOREADTOCHEADER, &h);
+ if (rc < 0)
+ return (rc);
+
+ n = h.ending_track - h.starting_track + 1;
+ rc = status (&trk, &junk, &junk, &junk);
+ if (rc < 0)
+ return (-1);
+
+ if (arg && *arg) {
+ if (sscanf (arg, "%u", &off) != 1) {
+ warnx("invalid command argument");
+ return (0);
+ } else
+ trk += off * dir;
+ } else
+ trk += dir;
+
+ if (trk > h.ending_track)
+ trk = 1;
+
+ return (play_track (trk, 1, n, 1));
+}
+
char *strstatus (int sts)
{
switch (sts) {
@@ -710,7 +756,7 @@ int pstatus (char *arg)
struct cd_sub_channel_info data;
int rc, trk, m, s, f;
int what = 0;
- char *p;
+ char *p, vmcn[(4 * 15) + 1];
while ((p = strtok(arg, " \t"))) {
arg = 0;
@@ -750,8 +796,11 @@ int pstatus (char *arg)
ss.data->what.media_catalog.mc_valid ? "": "in");
if (ss.data->what.media_catalog.mc_valid &&
ss.data->what.media_catalog.mc_number[0])
- printf(", number \"%.15s\"",
- ss.data->what.media_catalog.mc_number);
+ {
+ strvisx (vmcn, ss.data->what.media_catalog.mc_number,
+ (sizeof (vmcn) - 1) / 4, VIS_OCTAL | VIS_NL);
+ printf(", number \"%.*s\"", (int)sizeof (vmcn), vmcn);
+ }
putchar('\n');
} else
printf("No media catalog info available\n");
@@ -1103,6 +1152,12 @@ char *parse (char *buf, int *cmd)
if (isdigit (*p) || (p[0] == '#' && isdigit (p[1]))) {
*cmd = CMD_PLAY;
return (p);
+ } else if (*p == '+') {
+ *cmd = CMD_NEXT;
+ return (p + 1);
+ } else if (*p == '-') {
+ *cmd = CMD_PREVIOUS;
+ return (p + 1);
}
for (buf = p; *p && ! isspace (*p); p++)
OpenPOWER on IntegriCloud