diff cddb-id.c @ 3:74031379d3cb CDDB-STUFF_1_0

Initial revision
author darius
date Wed, 09 Aug 2000 02:18:47 +0000
parents
children ad83a38c3f5a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cddb-id.c	Wed Aug 09 02:18:47 2000 +0000
@@ -0,0 +1,182 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sysexits.h>
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/cdio.h>
+
+int cddb_sum(int n);
+unsigned long cddb_discid(int tot_trks, struct cd_toc_entry *cdtoc);
+void usage(void);
+
+int
+main(int argc, char **argv)
+{
+    int 			cd_fd, tot_tracks, i, machine, disc_length, tracknums;
+    unsigned long		disc_id;
+    struct ioc_toc_header	toc_head;
+    struct ioc_read_toc_entry	toc_entries_head;
+    struct cd_toc_entry		*toc_entries;
+    char			cd_path[256], ch;
+
+    /* Default CD path */
+    strcpy(cd_path, "/dev/cd0c");
+
+    /* Default to human readable */
+    machine = 0;
+
+    /* Default to no track number stuff */
+    tracknums = 0;
+
+    while ((ch = getopt(argc, argv, "f:mhn")) != -1) {
+	switch(ch) {
+	case 'f':
+	    if (strlen(optarg) > 255) {
+		warnx("Filename too long");
+		exit(EX_USAGE);
+	    }
+	    
+	    strcpy(cd_path, optarg);
+	    break;
+	    
+	case 'm':
+	    machine = 1;
+	    break;
+	    
+	case 'n':
+	    tracknums = 1;
+	    break;
+	    
+	case '?':
+	case 'h':
+	default:
+	    usage();
+	    break;
+	}
+    }
+    
+    if ((cd_fd = open(cd_path, O_RDWR)) == -1) {
+	warnx("Failed to open %s, reason: %s", cd_path, strerror(errno));
+	exit(EX_IOERR);
+    }
+
+    if (ioctl(cd_fd, CDIOREADTOCHEADER, &toc_head) == -1) {
+	warnx("Failed to get TOC header, reason: %s", strerror(errno));
+	exit(EX_UNAVAILABLE);
+    }
+    
+    tot_tracks = toc_head.ending_track - toc_head.starting_track + 1;
+
+    toc_entries = (struct cd_toc_entry *)malloc(sizeof(struct cd_toc_entry) * (tot_tracks + 1));
+    if (toc_entries == NULL) {
+	warnx("Couldn't allocate memeory for TOC entries");
+	exit(EX_UNAVAILABLE);
+    }
+    
+    toc_entries_head.data = toc_entries;
+    toc_entries_head.data_len = sizeof(struct cd_toc_entry) * (tot_tracks + 1);
+    toc_entries_head.starting_track = 0;
+    toc_entries_head.address_format = CD_MSF_FORMAT;
+
+    if (ioctl(cd_fd, CDIOREADTOCENTRYS, &toc_entries_head) == -1) {
+	warnx("Failed to get TOC entries, reason: %s\n", strerror(errno));
+	exit(EX_UNAVAILABLE);
+    }
+    
+    if (tracknums) {
+	for (i = 1; i <= tot_tracks; i++)
+	    if (!(toc_entries[i].control & 4))
+	        printf("%d ", i);
+	
+	printf("\n");
+	
+	exit(0);
+    }
+    
+    disc_id = cddb_discid(tot_tracks, toc_entries);
+    disc_length = (toc_entries[tot_tracks].addr.msf.minute * 60) +
+	(toc_entries[tot_tracks].addr.msf.second);
+
+    if (machine == 0) {
+	printf("Start track = %d, end track = %d, length = %d\n", toc_head.starting_track,
+	       toc_head.ending_track, toc_head.len);
+	printf("Disc ID is %08x\n", disc_id);
+	printf("Length is %d seconds\n", disc_length);
+    } else {
+	printf("%08x", disc_id);
+    }
+    
+    for (i = 0; i < tot_tracks; i++) {
+	if (machine == 0) {
+	    printf("Track %d, Minute = %d, Second = %d, Frame = %d, Type = %s, Offset = %d\n", 
+		   toc_entries[i].track, toc_entries[i].addr.msf.minute,
+		   toc_entries[i].addr.msf.second, toc_entries[i].addr.msf.frame,
+		   (toc_entries[i].control & 4) ? "data" : "audio",
+		   (toc_entries[i].addr.msf.minute * 60 * 75) +
+		   (toc_entries[i].addr.msf.second * 75) +
+		   toc_entries[i].addr.msf.frame);
+	} else {
+	    printf(" %d", (toc_entries[i].addr.msf.minute * 60 * 75) +
+		   (toc_entries[i].addr.msf.second * 75) +
+		   toc_entries[i].addr.msf.frame);
+	}
+
+    }
+
+    if (machine == 1) {
+	printf(" %d\n", disc_length);
+    }
+}
+    
+int
+cddb_sum(int n)
+{
+        int     ret;
+
+	/* For backward compatibility this algorithm must not change */
+
+	ret = 0;
+
+	while (n > 0) {
+		ret = ret + (n % 10);
+		n = n / 10;
+	}
+
+	return (ret);
+}
+
+unsigned long
+cddb_discid(int tot_trks, struct cd_toc_entry *cdtoc)
+{
+        int     i,
+		t = 0,
+		n = 0;
+
+	/* For backward compatibility this algorithm must not change */
+
+	i = 0;
+
+	while (i < tot_trks) {
+		n = n + cddb_sum((cdtoc[i].addr.msf.minute * 60)
+		      + cdtoc[i].addr.msf.second);
+		i++;
+	}
+	t = ((cdtoc[tot_trks].addr.msf.minute * 60) +
+	      cdtoc[tot_trks].addr.msf.second) -
+	    ((cdtoc[0].addr.msf.minute * 60) +
+	      cdtoc[0].addr.msf.second);
+
+	return ((n % 0xff) << 24 | t << 8 | tot_trks);
+}
+
+void
+usage(void)
+{
+    printf("Usage:\n");
+    printf("cddb-id [-f <cd-dev>] [-m]\n");
+    printf("<cd-dev> is the cd device to use (Default: /dev/cd0c)\n");
+    printf("-m causes machine readable output\n");
+    exit(EX_USAGE);
+}