aboutsummaryrefslogtreecommitdiff
path: root/audio/dcd
diff options
context:
space:
mode:
authorPietro Cerutti <gahr@FreeBSD.org>2008-06-20 21:13:54 +0000
committerPietro Cerutti <gahr@FreeBSD.org>2008-06-20 21:13:54 +0000
commit1ae5fdeb101fe8079966e70a17b9dd977c918ee6 (patch)
tree57f43d1221997e63d3cd4943ba0543e0a2250e1d /audio/dcd
parent6b72e93a452b7600f360b3eebbe6cb836c8bc5a2 (diff)
downloadports-1ae5fdeb101fe8079966e70a17b9dd977c918ee6.tar.gz
ports-1ae5fdeb101fe8079966e70a17b9dd977c918ee6.zip
- New port: dcd
dcd is originally a console CD player for Linux. This version uses libcdaudio in order to run on FreeBSD. It integrates MusicBrainz! and local look-ups.
Notes
Notes: svn path=/head/; revision=215390
Diffstat (limited to 'audio/dcd')
-rw-r--r--audio/dcd/Makefile34
-rw-r--r--audio/dcd/distinfo3
-rw-r--r--audio/dcd/files/patch-Makefile38
-rw-r--r--audio/dcd/files/patch-libcdplay.c652
-rw-r--r--audio/dcd/files/patch-libcdplay.h43
-rw-r--r--audio/dcd/files/patch-mbo.c20
-rw-r--r--audio/dcd/files/patch-mbo.h10
-rw-r--r--audio/dcd/files/patch-screenop.c37
-rw-r--r--audio/dcd/pkg-descr8
9 files changed, 845 insertions, 0 deletions
diff --git a/audio/dcd/Makefile b/audio/dcd/Makefile
new file mode 100644
index 000000000000..94508e0fc919
--- /dev/null
+++ b/audio/dcd/Makefile
@@ -0,0 +1,34 @@
+# New ports collection Makefile for: dcd
+# Date created: 20 June 2008
+# Whom: gahr
+#
+# $FreeBSD$
+#
+
+PORTNAME= dcd
+PORTVERSION= 0.99.2
+CATEGORIES= audio
+MASTER_SITES= SF/dcdplayer
+
+MAINTAINER= gahr@FreeBSD.org
+COMMENT= A simple, programmable, intelligent CD player
+
+LIB_DEPENDS= musicbrainz.4:${PORTSDIR}/audio/libmusicbrainz \
+ cdaudio.1:${PORTSDIR}/audio/libcdaudio
+
+USE_GMAKE= yes
+
+MAN1= dcd.1
+PLIST_FILES= bin/dcd
+
+post-patch:
+ # Handle namespace collision with libcdaudio
+ ${REINPLACE_CMD} -e 's|cd_stop|dcd_stop|g; s|cd_eject|dcd_eject|g; \
+ s|cd_pause|dcd_pause|g; s|cd_play_track|dcd_play_track|g' \
+ ${WRKSRC}/dcd.c ${WRKSRC}/infinite.c
+ # Linux? Bugger off!
+ ${REINPLACE_CMD} -e 's|linux/||' ${WRKSRC}/process.c
+ ${REINPLACE_CMD} -e 's|<endian|<sys/endian|; s|__BYTE_ORDER|_BYTE_ORDER|' \
+ ${WRKSRC}/endian.h
+
+.include <bsd.port.mk>
diff --git a/audio/dcd/distinfo b/audio/dcd/distinfo
new file mode 100644
index 000000000000..ab9ed48e01b9
--- /dev/null
+++ b/audio/dcd/distinfo
@@ -0,0 +1,3 @@
+MD5 (dcd-0.99.2.tar.gz) = 94d8e5bdcd1961998d4c3bd80155e5d7
+SHA256 (dcd-0.99.2.tar.gz) = 124db8cbe9f2bbcb3ecec1393e4d3d1ec081004190faee4423107c700f3bdfa2
+SIZE (dcd-0.99.2.tar.gz) = 49749
diff --git a/audio/dcd/files/patch-Makefile b/audio/dcd/files/patch-Makefile
new file mode 100644
index 000000000000..fd60e4b8c0bd
--- /dev/null
+++ b/audio/dcd/files/patch-Makefile
@@ -0,0 +1,38 @@
+--- Makefile.orig 2003-08-28 03:44:07.000000000 +0200
++++ Makefile 2008-06-20 21:57:34.000000000 +0200
+@@ -1,11 +1,11 @@
+ ## This is the makefile for dcd, dave's cd player.
+
+ # Select your compiler; gcc is probably just fine.
+-CC = gcc
++#CC = gcc
+
+ # Prefix for installing dcd. `make install' will put files in PREFIX/bin
+ # and PREFIX/man/man1 .
+-PREFIX = /usr
++#PREFIX = /usr
+
+ # Where should dcd store its process ID? (relative to ~)
+ # This is the default, which you probably don't need to change.
+@@ -21,7 +21,7 @@
+ # with that, you don't even need to uncomment the next line.
+ # CDROM = /dev/cdrom
+ # Or, if you use devfs, uncomment this line:
+-CDROM = /dev/cdroms/cdrom0
++CDROM = /dev/cdrom
+
+
+
+@@ -94,10 +94,10 @@
+ all: ${PROGS}
+
+ .c.o: ${SRCS}
+- $(CC) -c $(CFLAGS) ${EXTRA_CFLAGS} -I/usr/local/include $< -o $@
++ $(CC) -c $(CFLAGS) ${EXTRA_CFLAGS} -I${LOCALBASE}/include $< -o $@
+
+ ${PROGS}: ${OBJECTS}
+- ${CC} ${CFLAGS} ${EXTRA_CFLAGS} *.o ${EXTRA_LFLAGS} -o dcd
++ ${CC} ${CFLAGS} ${EXTRA_CFLAGS} *.o ${EXTRA_LFLAGS} -L${LOCALBASE}/lib -lcdaudio -o dcd
+
+ clean:;
+ -${RM} *.o ${PROGS}
diff --git a/audio/dcd/files/patch-libcdplay.c b/audio/dcd/files/patch-libcdplay.c
new file mode 100644
index 000000000000..38f805def96a
--- /dev/null
+++ b/audio/dcd/files/patch-libcdplay.c
@@ -0,0 +1,652 @@
+--- libcdplay.c.orig 2003-04-10 19:19:44.000000000 +0200
++++ libcdplay.c 2008-06-20 22:38:39.000000000 +0200
+@@ -1,484 +1,179 @@
+-/* $Revision: 1.4 $ */
+-/*
+- * This is libcdplay, a Linux-specific CD-ROM playing library.
+- *
+- * This code is (C) 1998-2001 David E. Smith <dave@technopagan.org>
+- * and released under the GNU GPL. See `COPYING' for details.
++/*-
++ * Copyright (c) 2008 Pietro Cerutti <gahr@gahr.ch>
+ *
+- * (Old versions were under the LGPL. This is no longer the case.)
++ * 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.
++ * 3. All advertising materials mentioning features or use of this software
++ * must display the following acknowledgement:
++ * This product includes software developed by the University of
++ * California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
+ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
++ */
++
++
++/*
++ * This is a wrapper around libcdaudio
+ */
+
+ #include "libcdplay.h"
+-#include "sha.h"
+-#include "mbo.h"
+-#include "dcd.h"
+-#include "base64.h"
+-#include <unistd.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <fcntl.h>
+-#include <linux/cdrom.h>
+-#include <sys/ioctl.h>
+-#include <stdlib.h>
+ #include <stdio.h>
+-#include <signal.h>
++#include <cdaudio.h>
+
++static int cd_desc;
++static struct disc_status status;
++static struct disc_info info;
++static char disc_id[9];
+
+-#define DISC_MAGIC 42
+-static int cdrive; /* fd for the cd, natch */
+-static int disc_present = DISC_MAGIC; /* ugly hack for cd_present() */
+-static char discid[33];
+-
+-static void int_cd_discid();
+-
+-/* Plays just the one track specified by trknum. */
+-u_char cd_play_track (u_char trknum) {
+- struct cdrom_ti trkidx;
+- #ifdef DEBUG
+- fprintf (stderr,"Entering cd_play_track (%i)\n", trknum);
+- #endif
+- if (!cd_present()) return -1;
+- memset (&trkidx, 0, sizeof (struct cdrom_ti));
+- trkidx.cdti_trk0 = trkidx.cdti_trk1 = trknum;
+- if (cd_data_track(trknum)) return -1;
+-#ifdef OLD_STOP_BEHAVIOUR
+- if(ioctl (cdrive, CDROMSTOP) == -1)
+- fprintf(stderr, "CDROMSTOP failed: %s\n", strerror(errno));
+-#else
+- if(ioctl (cdrive, CDROMSTART) == -1)
+- fprintf(stderr, "CDROMSTART failed: %s\n", strerror(errno));
+-#endif
+- if(ioctl (cdrive, CDROMPLAYTRKIND, &trkidx) == -1) {
+- struct cdrom_tocentry toce0, toce1;
+- struct cdrom_msf play;
+- toce0.cdte_format = CDROM_MSF;
+- toce0.cdte_track = trknum;
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce0) == -1)
+- fprintf(stderr, "CDROMREADTOCENTRY[1] failed: %s\n", strerror(errno));
+- toce1.cdte_format = CDROM_MSF;
+- toce1.cdte_track = ((trknum == cd_last_track()) ? CDROM_LEADOUT : (trknum+1));
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce1) == -1) {
+- fprintf(stderr, "CDROMREADTOCENTRY[2] (CDROM_LEADOUT) failed: %s\n",
+- strerror(errno));
+- }
+- play.cdmsf_min0=toce0.cdte_addr.msf.minute;
+- play.cdmsf_sec0=toce0.cdte_addr.msf.second;
+- play.cdmsf_frame0=toce0.cdte_addr.msf.frame;
+- play.cdmsf_min1=toce1.cdte_addr.msf.minute;
+- play.cdmsf_sec1=toce1.cdte_addr.msf.second;
+- play.cdmsf_frame1=toce1.cdte_addr.msf.frame;
+- if(ioctl (cdrive, CDROMPLAYMSF, &play) == -1)
+- fprintf(stderr, "CDROMPLAYMSF failed: %s\n", strerror(errno));
+- }
+- return trknum;
+-} /* cd_play_track */
+-
+-/* Plays a sequential list of tracks, from trk1 to trk2. Unused. ;) */
+-u_char cd_play_sequence (u_char trk1, u_char trk2) {
+- struct cdrom_ti trkidx;
+- #ifdef DEBUG
+- fprintf (stderr, "Entering cd_play_sequence (%i to %i)\n", trk1, trk2);
+- #endif
+- if (!cd_present()) return -1;
+- memset (&trkidx, 0, sizeof (struct cdrom_ti));
+- trkidx.cdti_trk0 = trk1;
+- trkidx.cdti_trk1 = trk2;
+-#ifdef OLD_STOP_BEHAVIOUR
+- if(ioctl (cdrive, CDROMSTOP) == -1)
+- fprintf(stderr, "CDROMSTOP failed: %s\n", strerror(errno));
+-#else
+- if(ioctl (cdrive, CDROMSTART) == -1)
+- fprintf(stderr, "CDROMSTART failed: %s\n", strerror(errno));
+-#endif
+- if(ioctl (cdrive, CDROMPLAYTRKIND, &trkidx) == -1) {
+- struct cdrom_tocentry toce0, toce1;
+- struct cdrom_msf play;
+- toce0.cdte_format = CDROM_MSF;
+- toce0.cdte_track = trk1;
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce0) == -1)
+- fprintf(stderr, "CDROMREADTOCENTRY[1] failed: %s\n", strerror(errno));
+- toce1.cdte_format = CDROM_MSF;
+- toce1.cdte_track = ((trk2 == cd_last_track()) ? CDROM_LEADOUT : (trk2+1));
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce1) == -1) {
+- fprintf(stderr, "CDROMREADTOCENTRY[2] (CDROM_LEADOUT) failed: %s\n",
+- strerror(errno));
+- }
+- play.cdmsf_min0=toce0.cdte_addr.msf.minute;
+- play.cdmsf_sec0=toce0.cdte_addr.msf.second;
+- play.cdmsf_frame0=toce0.cdte_addr.msf.frame;
+- play.cdmsf_min1=toce1.cdte_addr.msf.minute;
+- play.cdmsf_sec1=toce1.cdte_addr.msf.second;
+- play.cdmsf_frame1=toce1.cdte_addr.msf.frame;
+- if(ioctl (cdrive, CDROMPLAYMSF, &play) == -1)
+- fprintf(stderr, "CDROMPLAYMSF failed: %s\n", strerror(errno));
+- }
+- return trk2;
+-} /* play_seq */
+-
+-/* Plays from trknum to the end of the disc */
+-u_char cd_play_disc (u_char trknum) {
+- struct cdrom_ti trkidx;
+- #ifdef DEBUG
+- fprintf (stderr,"Entering cd_play_disc (%i)\n", trknum);
+- #endif
+- if (!cd_present()) return -1;
+- memset (&trkidx, 0, sizeof(struct cdrom_ti));
+- trkidx.cdti_trk0 = trknum;
+- trkidx.cdti_trk1 = cd_last_track();
+-#ifdef OLD_STOP_BEHAVIOUR
+- if(ioctl(cdrive, CDROMSTOP) == -1) /* has to be stopped to reset */
+- fprintf(stderr, "CDROMSTOP failed: %s\n", strerror(errno));
+-#else
+- if(ioctl(cdrive, CDROMSTART) == -1)
+- fprintf(stderr, "CDROMSTART failed: %s\n", strerror(errno));
+-#endif
+- if(ioctl(cdrive, CDROMPLAYTRKIND, &trkidx) == -1) {
+- struct cdrom_tocentry toce0, toce1;
+- struct cdrom_msf play;
+- toce0.cdte_format = CDROM_MSF;
+- toce0.cdte_track = trknum;
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce0) == -1)
+- fprintf(stderr, "CDROMREADTOCENTRY[1] failed: %s\n", strerror(errno));
+- toce1.cdte_format = CDROM_MSF;
+- toce1.cdte_track = CDROM_LEADOUT;
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce1) == -1) {
+- fprintf(stderr, "CDROMREADTOCENTRY[2] (CDROM_LEADOUT) failed: %s\n",
+- strerror(errno));
+- }
+- play.cdmsf_min0=toce0.cdte_addr.msf.minute;
+- play.cdmsf_sec0=toce0.cdte_addr.msf.second;
+- play.cdmsf_frame0=toce0.cdte_addr.msf.frame;
+- play.cdmsf_min1=toce1.cdte_addr.msf.minute;
+- play.cdmsf_sec1=toce1.cdte_addr.msf.second;
+- play.cdmsf_frame1=toce1.cdte_addr.msf.frame;
+- if(ioctl (cdrive, CDROMPLAYMSF, &play) == -1)
+- fprintf(stderr, "CDROMPLAYMSF failed: %s\n", strerror(errno));
+- }
+- return trknum;
+-} /* play_track */
+-
+-
+-/* This doesn't do what you think. That's why you shouldn't use it... */
+-int cd_active() {
+- struct cdrom_subchnl subchnl;
+- #if DEBUG > 1
+- fprintf (stderr, "Entering cd_active()\n");
+- #endif
+- memset (&subchnl, '\0', sizeof (struct cdrom_subchnl));
+- subchnl.cdsc_format=CDROM_MSF;
+- if(ioctl (cdrive, CDROMSUBCHNL, &subchnl) == -1)
+- fprintf(stderr, "CDROMSUBCHNL failed: %s\n", strerror(errno));
+- #ifdef DEBUG
+- fprintf (stderr, "subchannel status is %i\n", subchnl.cdsc_audiostatus);
+- #endif
+- switch (subchnl.cdsc_audiostatus) {
+- case CDROM_AUDIO_INVALID: return TRUE;
+- case CDROM_AUDIO_PLAY:
+- case CDROM_AUDIO_PAUSED: return TRUE; /* no, it's NOT a typo */
+- default: return FALSE;
+- }
+- return FALSE;
+-}
+-
+-/* return the track that's playing (or zero) */
+-u_char cd_current_track() {
+- struct cdrom_subchnl subchnl;
+- #ifdef DEBUG
+- fprintf (stderr, "Calling cd_current_track()... ");
+- #endif
+- if (!cd_present()) return 0;
+- memset (&subchnl, '\0', sizeof(struct cdrom_subchnl));
+- subchnl.cdsc_format = CDROM_MSF;
+- if(ioctl(cdrive, CDROMSUBCHNL, &subchnl) == -1)
+- fprintf(stderr, "CDROMSUBCHNL failed: %s\n", strerror(errno));
+- if (FALSE == cd_active()) return 0;
+- #ifdef DEBUG
+- fprintf (stderr, "returning %i\n", subchnl.cdsc_trk);
+- #endif
+- return subchnl.cdsc_trk;
+-} /* current_track */
+-
+-unsigned long raw_track_length (u_char trknum) {
+- long frames = 0;
+- struct cdrom_tocentry toce;
+- if (!cd_present()) return 0;
+- toce.cdte_format = CDROM_MSF;
+- toce.cdte_track = (trknum == cd_last_track()) ? CDROM_LEADOUT : trknum+1;
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce) == -1)
+- fprintf(stderr, "CDROMREADTOCENTRY[3] failed: %s\n", strerror(errno));
+- frames = (toce.cdte_addr.msf.minute) * CD_FRAMES * 60;
+- frames += (toce.cdte_addr.msf.second) * CD_FRAMES;
+- frames += toce.cdte_addr.msf.frame;
+- return frames;
+-} /* raw */
+-
+-unsigned long cd_track_length_frames (u_char trknum) {
+- long frames = raw_track_length(trknum);
+- long prevframes = raw_track_length (trknum-1);
+- if (!cd_present()) return 0;
+- frames -= prevframes;
+- #if DEBUG > 1
+- fprintf (stderr, "cd_track_length_frames: track %i is %lu frames\n",
+- trknum, frames);
+- #endif
+- return frames;
+-}
+-
+-/* returns length of track trknum, rounded to nearest second */
+-int cd_track_length (u_char trknum) {
+- long frames = cd_track_length_frames(trknum);
+- int seconds = frames / CD_FRAMES;
+- if (!cd_present()) return 0;
+- if ((frames % CD_FRAMES) > (CD_FRAMES / 2)) seconds++;
+- #ifdef DEBUG
+- fprintf (stderr, "cd_track_length: track %i is %i seconds\n",
+- trknum, seconds);
+- #endif
+- return seconds;
+-} /* track_length */
+-
+-unsigned long cd_disc_length_frames (void) {
+- long frames = raw_track_length(cd_last_track());
+- #if DEBUG > 1
+- fprintf (stderr, "cd_disc_length_frames: %lu\n", frames);
+- #endif
+- if (!cd_present()) return 0;
+- return frames;
+-}
+-
+-int cd_disc_length (void) {
+- long frames = cd_disc_length_frames();
+- int seconds = frames / CD_FRAMES;
+- if (!cd_present()) return 0;
+- if ((frames % CD_FRAMES) > (CD_FRAMES / 2)) seconds++;
+- #ifdef DEBUG
+- fprintf (stderr, "cd_disc_length: %i\n", seconds);
+- #endif
+- return seconds;
+-}
+-
+-int cd_hw_status (void) {
+- struct cdrom_subchnl cdsc;
+- memset (&cdsc, '\0', sizeof (struct cdrom_subchnl));
+- cdsc.cdsc_format = CDROM_MSF;
+- if(ioctl (cdrive, CDROMSUBCHNL, &cdsc) == -1)
+- fprintf(stderr, "CDROMSUBCHNL failed: %s\n", strerror(errno));
+- return cdsc.cdsc_audiostatus;
+-}
+-/* The status codes are defined in cdrom.h. They may include:
+- CDROM_AUDIO_PLAY (cd playing)
+- CDROM_AUDIO_PAUSED
+- CDROM_AUDIO_ERROR
+- CDROM_AUDIO_COMPLETED (done with last request, drive stopped)
+- CDROM_AUDIO_NO_STATUS (drive ready)
+-
+- Unless you know what you're doing, you probably don't want to use this.
+-*/
+-
+-/* this was Othmar's, but I sorta reversed it. */
+-int cd_present(void) {
+- int status;
+- if (disc_present != DISC_MAGIC) status = disc_present;
+- else {
+- status = ioctl(cdrive, CDROM_DRIVE_STATUS);
+- disc_present = status;
+- }
+- #ifdef DEBUG
+- // fprintf (stderr, "cd_present(), status is %i\n", status);
+- #endif
+- if ((status == CDS_DISC_OK) || (status == CDS_NO_INFO)) return TRUE;
+- /* returning TRUE if the drive doesn't support the status ioctl is,
+- perhaps, risky, but one can only wonder... */
+- /* other status codes: no disc, tray open, drive not ready */
+- return FALSE;
+-}
+-
+-/* toggle pause state */
+-void cd_pause (void) {
+- int pause = cd_hw_status();
+- #ifdef DEBUG
+- fprintf (stderr, "Entering cd_pause. Current status is %i\n", pause);
+- #endif
+- switch (pause) {
+- case CDROM_AUDIO_PAUSED:
+- if(ioctl (cdrive, CDROMRESUME) == -1)
+- fprintf(stderr, "CDROMRESUME failed: %s\n", strerror(errno));
+- break;
+- case CDROM_AUDIO_PLAY:
+- if(ioctl (cdrive, CDROMPAUSE) == -1)
+- fprintf(stderr, "CDROMPAUSE failed: %s\n", strerror(errno));
+- break;
+- default: cd_play_disc(cd_first_track()); break;
+- /* the above was a really cool idea from Ronald Tol */
+- /* Any state other than CDROM_AUDIO_PLAY implies that we're not */
+- /* playing right now, so what the hell? :) linux/cdrom.h lists */
+- /* all the possible states, and this seems to make sense... */
+- }
+-}
+-
+-
+-int cd_paused (void) {
+- int pause = cd_hw_status();
+- #ifdef DEBUG
+- fprintf (stderr, "Entering cd_paused\n");
+- #endif
+- if (CDROM_AUDIO_PAUSED == pause) return TRUE;
+- return FALSE;
+-}
+-
+-
+-void cd_stop (void) {
+- #ifdef DEBUG
+- fprintf (stderr, "Entering cd_stop()\n");
+- #endif
+- if(ioctl (cdrive, CDROMSTOP) == -1)
+- fprintf(stderr, "CDROMSTOP failed: %s\n", strerror(errno));
+-}
+-
+-void cd_eject (void) {
+- #ifdef DEBUG
+- fprintf (stderr, "Entering cd_eject()\n");
+- #endif
+- if (ioctl(cdrive,CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)
+- ioctl(cdrive,CDROMCLOSETRAY);
+- else ioctl (cdrive, CDROMEJECT);
+-}
+-
+-u_char cd_first_track (void) {
+- struct cdrom_tochdr tochdr;
+- #ifdef DEBUG
+- fprintf (stderr, "Calling cd_first_track()... ");
+- #endif
+- if (!cd_present()) return 0;
+- if(ioctl (cdrive, CDROMREADTOCHDR, &tochdr) == -1)
+- fprintf(stderr, "CDROMREADTOCHDR failed: %s\n", strerror(errno));
+- #ifdef DEBUG
+- fprintf (stderr, "returning %i\n", tochdr.cdth_trk0);
+- #endif
+- return tochdr.cdth_trk0;
+-}
+-
+-u_char cd_last_track (void) {
+- struct cdrom_tochdr tochdr;
+- #ifdef DEBUG
+- fprintf (stderr, "Calling cd_last_track()... ");
+- #endif
+- if (!cd_present()) return 0;
+- if(ioctl (cdrive, CDROMREADTOCHDR, &tochdr) == -1)
+- fprintf(stderr, "CDROMREADTOCHDR failed: %s\n", strerror(errno));
+- #ifdef DEBUG
+- fprintf (stderr, "returning %i\n", tochdr.cdth_trk1);
+- #endif
+- return tochdr.cdth_trk1;
+-}
+-
+-int cd_data_track (u_char trknum) {
+- struct cdrom_tocentry toce;
+- int i;
+- if (!cd_present()) return -1;
+- memset (&toce, '\0', sizeof(struct cdrom_tocentry));
+- toce.cdte_format = CDROM_MSF;
+- toce.cdte_track = trknum;
+- ioctl(cdrive, CDROMREADTOCENTRY, &toce);
+- /* if(ioctl (cdrive, CDROMREADTOCENTRY, &toce) == -1) */
+- /* fprintf(stderr, "CDROMREADTOCENTRY[4] failed: %s\n", strerror(errno)); */
+- /* apparently this fails randomly on some drives for no good reason. */
+- i = (toce.cdte_ctrl & CDROM_DATA_TRACK ? TRUE : FALSE);
+- #ifdef DEBUG
+- fprintf (stderr, "toce.cdte_ctrl is %i\n", toce.cdte_ctrl);
+- fprintf (stderr, "cd_data_track(%i) returning %i\n", trknum, i);
+- #endif
+- return i;
+-}
+-
+-/* Hey, wow, it's the mandatory `initialize the drive' function. */
+-int cd_init_player (char *device) {
+- #ifdef DEBUG
+- fprintf(stderr, "Calling cd_init_player(%s). Debugging ON.\n", device);
+- #endif
+-
+- cdrive = open(device, O_RDONLY | O_NONBLOCK);
+- if (!cdrive) return -1;
+-
+- if (!cd_present()) return -1;
+-
+- int_cd_discid();
+- mbo_init(device);
+- return cdrive;
+-}
+-
+-/* never use this either. */
+-int cd_fd (void) {
+- return cdrive;
+-}
+-
+-/* Okay, this is just f'n silly. musicbrainz has a "Get CD Index"
+- * function, but it won't work unless you've already retrieved
+- * the information from the network. So I have to keep all the
+- * "Get CD Index ID" code here.
+- */
++int
++cd_init_player(char *device)
++{
++ cd_desc = cd_init_device(device);
++ mbo_init(device);
++ cd_stat(cd_desc, &info);
++ return (cd_desc);
++}
++
++u_char
++dcd_play_track(u_char trknum)
++{
++ return (cd_play_sequence(trknum, trknum));
++}
++
++u_char
++cd_play_disc(u_char trknum)
++{
++ return (cd_play_sequence(trknum, info.disc_total_tracks));
++}
++
++u_char
++cd_play_sequence(u_char trk1, u_char trk2)
++{
++ return (cd_play_track(cd_desc, (int) trk1, (int) trk2) ? -1 : trk1);
++}
++
++u_char
++cd_current_track(void)
++{
++ cd_poll(cd_desc, &status);
++ return (status.status_current_track);
++}
++
++unsigned long
++cd_disc_length_frames(void)
++{
++ cd_poll(cd_desc, &status);
++ return (status.status_disc_time.frames);
++}
++
++unsigned long
++cd_track_length_frames(u_char trknum)
++{
++ return (info.disc_track[trknum-1].track_length.frames);
++}
+
+-char *cd_discid(void) {
+- return discid;
++int
++cd_disc_length(void)
++{
++ return (info.disc_length.minutes * 60 +
++ info.disc_length.seconds);
+ }
+
+-static void int_cd_discid (void) {
+- SHA_INFO sha;
+- unsigned char digest[20];
+- unsigned long size;
+- char temp[9];
+- int i, lba;
+- int trackz = cd_last_track();
+- struct cdrom_tocentry toce;
+-
+- if (!cd_present()) return;;
+-
+- #if DEBUG > 1
+- fprintf (stderr, "Entering cd_discid()\n");
+- #endif
+-
+- memset (discid, '\0', sizeof(discid));
+- memset (&toce, '\0', sizeof(toce));
+-
+- sha_init(&sha);
+- sprintf (temp, "%02X", cd_first_track());
+- sha_update(&sha, (unsigned char *)temp, strlen(temp));
+- sprintf (temp, "%02X", cd_last_track());
+- sha_update(&sha, (unsigned char *)temp, strlen(temp));
+-
+- toce.cdte_track = CDROM_LEADOUT;
+- toce.cdte_format = CDROM_LBA;
+- if(ioctl(cdrive, CDROMREADTOCENTRY, &toce) == -1)
+- fprintf(stderr, "CDROMREADTOCENTRY[5] failed: %s\n", strerror(errno));
+- lba = toce.cdte_addr.lba + 150;
+- sprintf (temp, "%08X", lba);
+- sha_update(&sha, (unsigned char *)temp, strlen(temp));
+-
+- for (i=1; i < 100; i++) {
+- if (i <= trackz) {
+- toce.cdte_format = CDROM_LBA;
+- toce.cdte_track = i;
+- if(ioctl (cdrive, CDROMREADTOCENTRY, &toce) == -1)
+- fprintf(stderr, "CDROMREADTOCENTRY[6] failed: %s\n", strerror(errno));
+- lba = toce.cdte_addr.lba + 150;
+- sprintf(temp, "%08X", lba);
+- }
+- else sprintf (temp, "%08X", 0);
+- sha_update(&sha, (unsigned char *)temp, strlen(temp));
+- }
+- sha_final(digest, &sha);
+- #if DEBUG > 1
+- fprintf (stderr, "SHA digest finalized.\n");
+- #endif
+- bin_to_base64(discid, digest, 20, size);
+- #ifdef DEBUG
+- fprintf (stderr, "cd_discid returning %s\n", discid);
+- #endif
++int
++cd_track_length(u_char trknum)
++{
++ return (info.disc_track[trknum-1].track_length.minutes * 60 +
++ info.disc_track[trknum-1].track_length.seconds);
+ }
+
+-/* there used to be more stuff here, but it's been more-or-less
+- subsumed by the musicbrainz crapulence. */
++int
++cd_data_track(u_char trknum)
++{
++ return (info.disc_track[trknum-1].track_type == CDAUDIO_TRACK_DATA);
++}
++
++u_char
++cd_first_track(void)
++{
++ return (1);
++}
++
++u_char
++cd_last_track(void)
++{
++ return (info.disc_total_tracks);
++}
++
++int
++cd_active(void)
++{
++ cd_poll(cd_desc, &status);
++ return (status.status_mode == CDAUDIO_PLAYING ||
++ status.status_mode == CDAUDIO_PAUSED);
++}
++
++int
++cd_paused(void)
++{
++ cd_poll(cd_desc, &status);
++ return (status.status_mode == CDAUDIO_PAUSED);
++}
++
++int
++cd_present(void)
++{
++ return (info.disc_present);
++}
++
++int
++cd_hw_status(void)
++{
++ return 0;
++}
++
++char *
++cd_discid(void)
++{
++ snprintf(disc_id, sizeof(disc_id), "%0x", cddb_discid(cd_desc));
++ return (disc_id);
++}
+
+-/* char *cd_discid(void); */
+-/* char *cd_subid(void); */
++void
++dcd_stop(void)
++{
++ cd_stop(cd_desc);
++}
++
++void
++dcd_pause(void)
++{
++ if(cd_paused())
++ cd_resume(cd_desc);
++ else
++ cd_pause(cd_desc);
++}
++
++void
++dcd_eject(void)
++{
++ cd_eject(cd_desc);
++}
diff --git a/audio/dcd/files/patch-libcdplay.h b/audio/dcd/files/patch-libcdplay.h
new file mode 100644
index 000000000000..c6564b50ef62
--- /dev/null
+++ b/audio/dcd/files/patch-libcdplay.h
@@ -0,0 +1,43 @@
+--- libcdplay.h.orig 2003-01-04 03:15:49.000000000 +0100
++++ libcdplay.h 2008-06-20 22:32:40.000000000 +0200
+@@ -11,7 +11,8 @@
+ #define __CD_PLAYER_LIB
+
+ #include <sys/types.h>
+-#include <linux/cdrom.h>
++
++typedef unsigned char u_char;
+
+ /* Initialization. Takes the drive to set up (like "/dev/cdrom") and
+ * returns the drive's file descriptor. Note that you shouldn't ever
+@@ -23,11 +24,11 @@
+
+ /* Playing operations - tracks, disc, etc.
+ * These operations return the track number you fed them, or -1 in case of
+- * an error (like trying to play a data track in cd_play_track).
++ * an error (like trying to play a data track in dcd_play_track).
+ */
+-u_char cd_play_track (u_char trknum);
+-u_char cd_play_sequence (u_char trk1, u_char trk2);
++u_char dcd_play_track (u_char trknum);
+ u_char cd_play_disc (u_char trknum);
++u_char cd_play_sequence (u_char trk1, u_char trk2);
+
+
+ /* Informational operations */
+@@ -45,11 +46,11 @@
+
+
+ /* Simple commands. */
+-void cd_stop(void);
+-void cd_eject(void);
+-void cd_pause(void); /* toggles pause/resume status internally */
++void dcd_stop(void);
++void dcd_eject(void);
++void dcd_pause(void); /* toggles pause/resume status internally */
+ int cd_active(void); /* if playing or paused, return TRUE */
+-int cd_paused(void); /* boolean for pause(TRUE) or not */
++int dcd_paused(void); /* boolean for pause(TRUE) or not */
+ int cd_present(void); /* is there a disc in the drive? */
+
+ /* The RAW frame count is really only useful for cddb calculations. */
diff --git a/audio/dcd/files/patch-mbo.c b/audio/dcd/files/patch-mbo.c
new file mode 100644
index 000000000000..10af204e0f38
--- /dev/null
+++ b/audio/dcd/files/patch-mbo.c
@@ -0,0 +1,20 @@
+--- mbo.c.orig 2003-08-28 01:34:12.000000000 +0200
++++ mbo.c 2008-06-20 22:20:40.000000000 +0200
+@@ -46,6 +46,17 @@
+ return FALSE;
+ }
+
++char *mbo_artistname (void) {
++ char *res = (char *)malloc(255);
++ if (mbo_ok == FALSE) return "";
++ memset(res, '\0', 255);
++ mb_GetResultData(mbo, MBE_AlbumGetAlbumArtistName, res, 255);
++ #ifdef DEBUG
++ fprintf (stderr, "cd_get_artistname: %s\n", res);
++ #endif
++ return res;
++}
++
+ /* convenience hack. 0 is disc name, others are track names. */
+ /* guess what, this too is XXX UNSAFE */
+ char *mbo_trackname (int i) {
diff --git a/audio/dcd/files/patch-mbo.h b/audio/dcd/files/patch-mbo.h
new file mode 100644
index 000000000000..b6b9345d9ec7
--- /dev/null
+++ b/audio/dcd/files/patch-mbo.h
@@ -0,0 +1,10 @@
+--- mbo.h.orig 2003-08-28 03:36:01.000000000 +0200
++++ mbo.h 2008-06-20 22:15:46.000000000 +0200
+@@ -6,6 +6,7 @@
+ #endif
+
+ int mbo_init(char *device);
++char *mbo_artistname (void);
+ char *mbo_trackname (int i);
+
+ #define CDI_HOME ".cdindex" /* for historical reasons */
diff --git a/audio/dcd/files/patch-screenop.c b/audio/dcd/files/patch-screenop.c
new file mode 100644
index 000000000000..a7a1f24080b6
--- /dev/null
+++ b/audio/dcd/files/patch-screenop.c
@@ -0,0 +1,37 @@
+--- screenop.c.orig 2003-08-28 01:42:36.000000000 +0200
++++ screenop.c 2008-06-20 23:06:36.000000000 +0200
+@@ -15,23 +15,27 @@
+
+ void disk_directory(void) {
+ u_char ct = cd_current_track();
++ char *art_name, *trk_name;
+ int tl;
+- char outline[80];
+ int disc_length = cd_disc_length();
+ int i;
+ #ifdef DEBUG
+ fprintf (stderr, "Entering directory. tz is %i\n", cd_last_track());
+ #endif
+
+- sprintf (outline, "Track Time (%i tracks / %2i:%02i) %30s",
+- cd_last_track(), disc_length/60, disc_length%60, mbo_trackname(0));
+- printf ("%s\n", outline);
++ art_name = mbo_artistname();
++ trk_name = mbo_trackname(0);
++ printf ("Artist: %s\nAlbum : %s\nTrack Time (%i tracks / %2i:%02i)\n",
++ art_name, trk_name, cd_last_track(), disc_length/60, disc_length%60);
++ free(art_name);
++ free(trk_name);
+
+ for (i=1; i<=cd_last_track(); i++) {
+ tl = cd_track_length(i);
+- sprintf (outline, "%s %2i %2i:%02i %-45s", (i==ct ? "*" : " "),
+- i, (tl/60), (tl%60), mbo_trackname(i));
+- printf ("%s\n", outline);
++ trk_name = mbo_trackname(i);
++ printf ("%s %2i %2i:%02i %-45s\n", (i==ct ? "*" : " "),
++ i, (tl/60), (tl%60), trk_name);
++ free(trk_name);
+ } /* for */
+ }
+
diff --git a/audio/dcd/pkg-descr b/audio/dcd/pkg-descr
new file mode 100644
index 000000000000..2533a77b9f73
--- /dev/null
+++ b/audio/dcd/pkg-descr
@@ -0,0 +1,8 @@
+This is the port to libcdaudio of the original dcd player.
+
+dcd plays CDs, lets you set up CD playlists, and does most of what
+a conventional CD player does, in a (hopefully) intuitive manner.
+
+
+
+WWW: http://dcdplayer.sf.net