Mercurial > ~darius > hgwebdir.cgi > cddb-stuff
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); +}