With FreeDB announcing[0] that the service will be shutting down as of March 31st of 2020, and the only other alternative (MusicBrainz) already having shutdown their freedb/cddb gateway in favour of their own API early this year, it likely makes sense to remove support from cdio(1).
CDDB is used to retrieve music CD metadata over the Internet, e.g: Artist and Track names. I left in support for the "cdid" command as it may be useful for archival(?) purposes, if not that can go too. Cc: espie@ as he wrote this code, & maybe he still has music on CDs. ok? -Bryan. [0] http://www.freedb.org/en/ [1] https://blog.metabrainz.org/2018/09/18/freedb-gateway-end-of-life-notice-march-18-2019/ Index: Makefile =================================================================== RCS file: /cvs/src/usr.bin/cdio/Makefile,v retrieving revision 1.6 diff -u -p -u -r1.6 Makefile --- Makefile 29 Nov 2008 08:57:10 -0000 1.6 +++ Makefile 29 Dec 2019 00:34:51 -0000 @@ -3,7 +3,7 @@ PROG= cdio DPADD= ${LIBUTIL} ${LIBEDIT} ${LIBTERMCAP} LDADD= -lutil -ledit -ltermcap -lsndio -SRCS= cdio.c cddb.c mmc.c rip.c +SRCS= cdio.c mmc.c rip.c CDIAGFLAGS=-Wall -W -Wmissing-prototypes -pedantic .include <bsd.prog.mk> Index: cddb.c =================================================================== RCS file: cddb.c diff -N cddb.c --- cddb.c 7 Dec 2017 02:08:44 -0000 1.22 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,396 +0,0 @@ -/* $OpenBSD: cddb.c,v 1.22 2017/12/07 02:08:44 krw Exp $ */ -/* - * Copyright (c) 2002 Marc Espie. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD - * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/socket.h> -#include <netinet/in.h> -#include <sys/cdio.h> -#include <err.h> -#include <netdb.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> -#include <vis.h> -#include "extern.h" - -unsigned long cddb_sum(unsigned long); -void send_hello(FILE *); -void send_query(FILE *, int, struct cd_toc_entry *); -int further_query(FILE *, char *); -int connect_to(const char *, const char *); -int parse_connect_to(const char *, const char *); -char * get_line(FILE *); -char * get_answer(FILE *); -void verify_track_names(char **, int, struct cd_toc_entry *); -void safe_copy(char **, const char *); - -unsigned long -cddb_sum(unsigned long v) -{ - unsigned long sum = 0; - - while (v > 0) { - sum += v % 10; - v /= 10; - } - return (sum); -} - -unsigned long -cddb_discid(int n, struct cd_toc_entry *e) -{ - unsigned long sum; - int i; - - sum = 0; - for (i =0; i < n; i++) - sum += cddb_sum(entry2time(e+i)); - return (((sum % 0xff) << 24) | - ((entry2time(e+n) - entry2time(e)) << 8) | n); -} - -void -send_hello(FILE *cout) -{ - char hostname[HOST_NAME_MAX+1]; - - if (gethostname(hostname, sizeof(hostname)) == -1) - strlcpy(hostname, "unknown", sizeof hostname); - fprintf(cout, "CDDB HELLO %s %s cdio " VERSION "\r\n", - getlogin(), hostname); - fflush(cout); -} - -void -send_query(FILE *f, int n, struct cd_toc_entry *e) -{ - int i; - - fprintf(f, "cddb query %8lx %d", cddb_discid(n, e), n); - for (i = 0; i < n; i++) - fprintf(f, " %lu", entry2frames(e+i)); - fprintf(f, " %lu\r\n", (entry2frames(e+n)-entry2frames(e)) /75); - fflush(f); -} - -#define MAXSIZE 256 -char copy_buffer[MAXSIZE]; - -void -safe_copy(char **p, const char *title) -{ - strnvis(copy_buffer, title, MAXSIZE-1, VIS_TAB|VIS_NL); - if (*p == NULL) - *p = strdup(copy_buffer); - else { - char *n; - - if (asprintf(&n, "%s%s", *p, copy_buffer) == -1) - return; - free(*p); - *p = n; - } -} - -int -further_query(FILE *cout, char *line) -{ - char *key; - char *title; - - key = strchr(line, ' '); - if (!key) - return 0; - *key++ = 0; - title = strchr(key, ' '); - if (!title) - return 0; - *title++ = 0; - strnvis(copy_buffer, title, MAXSIZE-1, VIS_TAB|VIS_NL); - printf("%s", copy_buffer); - strnvis(copy_buffer, line, MAXSIZE-1, VIS_TAB|VIS_NL); - printf("(%s)\n", copy_buffer); - fprintf(cout, "CDDB READ %s %s\r\n", line, key); - fflush(cout); - return 1; -} - - -int -connect_to(const char *host, const char *serv) -{ - int s = -1; - struct addrinfo hints, *res0 = NULL, *res; - int error; - - memset(&hints, 0, sizeof hints); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - error = getaddrinfo(host, serv, &hints, &res0); - if (error) { - warnx("%s", gai_strerror(error)); - return -1; - } - - for (res = res0; res; res = res->ai_next) { - s = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - if (s == -1) - continue; - if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { - close(s); - s = -1; - continue; - } - break; - } - if (s == -1) - warn("cddb"); - freeaddrinfo(res0); - return s; -} - -int -parse_connect_to(const char *host_port, const char *port) -{ - int s; - char *last, *host; - - host = (char *)host_port; - - last = strrchr(host_port, ':'); - if (last != 0 && !(last != host && last[-1] == ':')) { - port = last + 1; - host = malloc(last - host_port + 1); - if (!host) - return -1; - memcpy(host, host_port, last-host_port); - host[last-host_port] = 0; - } - s = connect_to(host, port); - if (host != host_port) - free(host); - return s; -} - -char * -get_line(FILE *cin) -{ - char *line; - size_t len; - - line = fgetln(cin, &len); - if (!line) - return NULL; - if (len == 0) - return NULL; - if (line[len-1] == '\n') - line[--len] = 0; - if (len != 0 && line[len-1] == '\r') - line[--len] = 0; - if (line[len] != 0) - return NULL; - return line; -} - -char * -get_answer(FILE *cin) -{ - char *line; - - line = get_line(cin); - if (!line || *line != '2') - return NULL; - else - return line; -} - -void -verify_track_names(char **names, int n, struct cd_toc_entry *e) -{ - int i; - - for (i = 0; i < n; i++) { - if (names[i] == 0) - names[i] = strdup(e->control & 4 ? "data" : "audio"); - } -} - -char ** -cddb(const char *host_port, int n, struct cd_toc_entry *e, char *arg) -{ - int s = -1; - int s2 = -1; - FILE *cin = NULL; - FILE *cout = NULL; - char *type; - char *line; - char **result = NULL; - int i; - const char *errstr; - - s = parse_connect_to(host_port, "cddb"); - if (s == -1) - goto end; - s2 = dup(s); - if (s2 == -1) - goto end; - cin = fdopen(s, "r"); - if (!cin) { - warn("cddb: fdopen"); - goto end; - } - s = -1; - cout = fdopen(s2, "w"); - if (!cout) { - warn("cddb: fdopen"); - goto end; - } - s2 = -1; - line = get_answer(cin); - if (!line) { - warnx("cddb: won't talk to us"); - goto end; - } - - send_hello(cout); - line = get_answer(cin); - if (!line) { - warnx("cddb: problem in hello"); - goto end; - } - - send_query(cout, n, e); - line = get_answer(cin); - if (!line) { - warnx("cddb: problem in query"); - goto end; - } - type = strchr(line, ' '); - if (!type) - goto end; - *type++ = 0; - /* no match or other issue */ - if (strcmp(line, "202") == 0) { - printf("cddb: No match in database\n"); - goto end; - } - if (strcmp(line, "211") == 0 || strcmp(line, "212") == 0) { - int number = strtonum(arg, 0, INT_MAX, &errstr); - if (errstr != NULL && *arg != '\0') { - warnx("cddb: invalid index"); - goto end; - } - if (number == 0) { - if (strcmp(line, "211") == 0) - printf("cddb: multiple matches\n"); - else { - printf("cddb: inexact match\n"); - number = 1; - } - } - if (number == 0) { - for (i = 1;; i++) { - line = get_line(cin); - if (!line || strcmp(line, ".") == 0) - goto end; - printf("%d: %s\n", i, line); - } - } else { - int ok = 0; - - for (i = 1;; i++) { - line = get_line(cin); - if (!line) - break; - if (strcmp(line, ".") == 0) - break; - if (i == number) - ok = further_query(cout, line); - } - if (!ok) - goto end; - } - } else if (strcmp(line, "200") != 0 || !further_query(cout, type)) - goto end; - result = calloc(sizeof(char *), n + 1); - if (!result) - goto end; - for (i = 0; i <= n; i++) - result[i] = NULL; - line = get_answer(cin); - if (!line) - goto end2; - for (;;) { - int k; - char *end; - - line = get_line(cin); - if (!line) - goto end2; - if (strcmp(line, ".") == 0) - break; - if (strncmp(line, "TTITLE", 6) != 0) - continue; - line += 6; - end = strchr(line, '='); - if (end == NULL) - continue; - *end++ = '\0'; - k = strtonum(line, 0, n - 1, &errstr); - if (errstr != NULL) - continue; - safe_copy(&result[k], end); - } - fprintf(cout, "QUIT\r\n"); - verify_track_names(result, n, e); - goto end; -end2: - free(result); - result = NULL; -end: - if (cout) - fclose(cout); - if (cin) - fclose(cin); - if (s != -1) - close(s); - if (s2 != -1) - close(s2); - return result; -} - -void -free_names(char **names) -{ - int i; - - for (i = 0; names[i]; i++) - free(names[i]); - free(names); -} Index: cdio.1 =================================================================== RCS file: /cvs/src/usr.bin/cdio/cdio.1,v retrieving revision 1.63 diff -u -p -u -r1.63 cdio.1 --- cdio.1 2 Oct 2019 07:43:20 -0000 1.63 +++ cdio.1 29 Dec 2019 00:34:51 -0000 @@ -53,12 +53,6 @@ enters interactive mode, reading command .Pp The options are as follows: .Bl -tag -width Ds -.It Xo -.Fl d -.Ar host : Ns Ar port -.Xc -Specifies a CDDB host -.Bq default: freedb.freedb.org:cddb . .It Fl f Ar device Specifies the name of the CD device, such as .Pa /dev/rcd0c . @@ -87,12 +81,8 @@ is assumed. .Bl -tag -width Ds .It Ic blank Minimally blank the disc. -.It Ic cddbinfo Op Ar n -Print the Table Of Contents (TOC) after matching the disc with the CDDB. -In case of multiple matches, reissue the command with -.Ar n . .It Ic cdid -Print the disc ID that will be used for matching with the CDDB. +Print the disc ID that will be generated from the TOC. .It Ic cdplay Op Ar track1-trackN ... Play specified tracks from disk. Unlike Index: cdio.c =================================================================== RCS file: /cvs/src/usr.bin/cdio/cdio.c,v retrieving revision 1.78 diff -u -p -u -r1.78 cdio.c --- cdio.c 3 Jul 2019 03:24:02 -0000 1.78 +++ cdio.c 29 Dec 2019 00:34:51 -0000 @@ -103,11 +103,10 @@ #define CMD_NEXT 16 #define CMD_PREV 17 #define CMD_REPLAY 18 -#define CMD_CDDB 19 -#define CMD_CDID 20 -#define CMD_BLANK 21 -#define CMD_CDRIP 22 -#define CMD_CDPLAY 23 +#define CMD_CDID 19 +#define CMD_BLANK 20 +#define CMD_CDRIP 21 +#define CMD_CDPLAY 22 struct cmdtab { int command; @@ -116,7 +115,6 @@ struct cmdtab { char *args; } cmdtab[] = { { CMD_BLANK, "blank", 1, "" }, -{ CMD_CDDB, "cddbinfo", 2, "[n]" }, { CMD_CDID, "cdid", 3, "" }, { CMD_CDPLAY, "cdplay", 3, "[track1-trackN ...]" }, { CMD_CDRIP, "cdrip", 3, "[track1-trackN ...]" }, @@ -154,8 +152,6 @@ int writeperm = 0; u_int8_t mediacap[MMC_FEATURE_MAX / NBBY]; int verbose = 1; int msf = 1; -const char *cddb_host; -char **track_names; EditLine *el = NULL; /* line-editing structure */ History *hist = NULL; /* line-editing history */ @@ -172,7 +168,6 @@ int is_wave(int); __dead void tao(int argc, char **argv); int play(char *arg); int info(char *arg); -int cddbinfo(char *arg); int pstatus(char *arg); int play_next(char *arg); int play_prev(char *arg); @@ -222,7 +217,7 @@ help(void) void usage(void) { - fprintf(stderr, "usage: %s [-sv] [-d host:port] [-f device] [command args ...]\n", + fprintf(stderr, "usage: %s [-sv] [-f device] [command args ...]\n", __progname); exit(1); } @@ -237,11 +232,7 @@ main(int argc, char **argv) if (!cdname) cdname = getenv("CDROM"); - cddb_host = getenv("CDDB"); - if (!cddb_host) - cddb_host = "freedb.freedb.org"; - - while ((ch = getopt(argc, argv, "svd:f:")) != -1) + while ((ch = getopt(argc, argv, "svf:")) != -1) switch (ch) { case 's': verbose = 0; @@ -252,9 +243,6 @@ main(int argc, char **argv) case 'f': cdname = optarg; break; - case 'd': - cddb_host = optarg; - break; default: usage(); } @@ -334,12 +322,6 @@ run(int cmd, char *arg) return info(arg); - case CMD_CDDB: - if (!open_cd(cdname, 0)) - return (0); - - return cddbinfo(arg); - case CMD_CDID: if (!open_cd(cdname, 0)) return (0); @@ -430,9 +412,6 @@ run(int cmd, char *arg) close(fd); fd = -1; #endif - if (track_names) - free_names(track_names); - track_names = NULL; return (0); case CMD_CLOSE: @@ -1136,17 +1115,10 @@ pstatus(char *arg) rc = status(&trk, &m, &s, &f); if (rc >= 0) { if (verbose) { - if (track_names) - printf("Audio status = %d<%s>, " - "current track = %d (%s)\n" - "\tcurrent position = %d:%02d.%02d\n", - rc, strstatus(rc), trk, - trk ? track_names[trk-1] : "", m, s, f); - else - printf("Audio status = %d<%s>, " - "current track = %d, " - "current position = %d:%02d.%02d\n", - rc, strstatus(rc), trk, m, s, f); + 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 @@ -1184,6 +1156,31 @@ pstatus(char *arg) return(0); } +unsigned long +cdid_sum(unsigned long v) +{ + unsigned long sum = 0; + + while (v > 0) { + sum += v % 10; + v /= 10; + } + return (sum); +} + +unsigned long +toc2cdid(int n, struct cd_toc_entry *e) +{ + unsigned long sum; + int i; + + sum = 0; + for (i =0; i < n; i++) + sum += cdid_sum(entry2time(e+i)); + return (((sum % 0xff) << 24) | + ((entry2time(e+n) - entry2time(e)) << 8) | n); +} + int cdid(void) { @@ -1202,7 +1199,7 @@ cdid(void) if (rc < 0) return (rc); - id = cddb_discid(n, toc_buffer); + id = toc2cdid(n, toc_buffer); if (id) { if (verbose) printf("CDID="); @@ -1250,42 +1247,6 @@ info(char *arg) } printf("%5d ", toc_buffer[n].track); prtrack(toc_buffer + n, 1, NULL); - return (0); -} - -int -cddbinfo(char *arg) -{ - struct ioc_toc_header h; - int rc, i, n; - - rc = ioctl(fd, CDIOREADTOCHEADER, &h); - if (rc == -1) { - warn("getting toc header"); - 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 (track_names) - free_names(track_names); - track_names = NULL; - - track_names = cddb(cddb_host, n, toc_buffer, arg); - if (!track_names) - return(0); - - printf("-------------------------------------------------\n"); - - for (i = 0; i < n; i++) { - printf("%5d ", toc_buffer[i].track); - prtrack(toc_buffer + i, 0, track_names[i]); - } - printf("%5d ", toc_buffer[n].track); - prtrack(toc_buffer + n, 1, ""); return (0); }