Index: cddb-submit.1
===================================================================
--- cddb-submit.1	(revision 0)
+++ cddb-submit.1	(revision 138949)
@@ -0,0 +1,42 @@
+.\"	$OpenBSD: mdoc.template,v 1.12 2010/09/04 08:00:15 jmc Exp $
+.\"
+.Dd $Mdocdate$
+.Dt cddb-submit 1
+.Os
+.Sh NAME
+.Nm cddb-submit
+.Nd creates a email to be submitted to freedb.org.
+.Sh SYNOPSIS
+.Nm cddb-submit
+.Op Fl h
+.Op Fl f Fa device
+.Fa category
+.Sh DESCRIPTION
+The
+.Nm
+utility read CD from
+.Fa device
+and creates a mail message template to be submitted to freedb.org.
+.\" The following requests should be uncommented and used where appropriate.
+.\" .Sh RETURN VALUES
+.\" For sections 2, 3, and 9 function return values only.
+.\" .Sh ENVIRONMENT
+.\" For sections 1, 6, 7 & 8 only.
+.\" .Sh FILES
+.\" .Sh EXIT STATUS
+.\" For sections 1, 6, & 8 only.
+.\" .Sh EXAMPLES
+.\" .Sh DIAGNOSTICS
+.\" For sections 1, 4, 6, 7, and 8 only.
+.\" .Sh ERRORS
+.\" For sections 2, 3, and 9 error and signal handling only.
+.Sh SEE ALSO
+.Xr cddb 1
+.\" .Sh STANDARDS
+.\" .Sh HISTORY
+.Sh AUTHORS
+The
+.Nm
+utility was written by YASUOKA Masahiko <yasuoka@yasuoka.net>.
+.\" .Sh CAVEATS
+.\" .Sh BUGS
Index: Makefile
===================================================================
--- Makefile	(revision 0)
+++ Makefile	(revision 138949)
@@ -0,0 +1,4 @@
+#	$Id$
+PROG=		cddb-submit
+
+.include <bsd.prog.mk>

Property changes on: Makefile
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
Index: cddb-submit.c
===================================================================
--- cddb-submit.c	(revision 0)
+++ cddb-submit.c	(revision 138949)
@@ -0,0 +1,197 @@
+/*	$Id$	*/
+
+/*
+ * Copyright (c) 2012 YASUOKA Masahiko <yasuoka@yasuoka.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/param.h>
+#include <sys/cdio.h>
+#include <sys/socket.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef nitems
+#define	nitems(x)	(sizeof(x) / sizeof(x[0]))
+#endif
+
+#define FPS		75		/* frames per sec */
+#define	PROGNAME	__progname
+#define	VERSION		"1.0"
+
+static int   entry2sec (struct cd_toc_entry *);
+static void  cdread (int, int, char *[]);
+static void  read_line (FILE *);
+static int   valid_category (const char *);
+
+extern char               *__progname;
+
+static void
+usage(void)
+{
+	fprintf(stderr,
+"usage: %s [-h] [-f device] category\n"
+"\n"
+"    CDDB categories: blues classical  country data folk jazz misc newage\n"
+"                     reggae rock soundtrack\n", __progname);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int		 ch, devf;
+	extern int	 optind;
+	const char	*cmd;
+	char		 devpath[MAXPATHLEN];
+
+	devf = -1;
+	while ((ch = getopt(argc, argv, "hf:")) != -1)
+		switch (ch) {
+		case 'f':
+			if (optarg[0] != '/') {
+				snprintf(devpath, sizeof(devpath), "/dev/r%sc",
+					optarg);
+				devf = open(devpath, O_RDONLY, 0644);
+			} else
+				devf = open(optarg, O_RDONLY, 0644);
+			if (devf < 0)
+				err(1, "open(%s)", optarg);
+			break;
+		case 'h':
+		default:
+			goto usage;
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (devf == -1 && (devf = open("/dev/rcd0c", O_RDONLY, 0644)) < 0)
+		err(1, "open()");
+
+	cdread(devf, argc, argv);
+usage:
+	usage();
+	exit(EXIT_FAILURE);
+}
+
+void
+cdread(int devf, int argc, char *argv[])
+{
+	int				 i, n;
+	struct ioc_toc_header		 h;
+	struct ioc_read_toc_entry	 toc;
+	struct cd_toc_entry		 data[100];
+	uint32_t			 diskid = 0;
+	const char			*category;
+
+	if (argc != 1)
+		return;
+
+	category = *(argv++); argc--;
+	if (!is_valid_category(category))
+		errx(1, "invalid cddb category: %s\n", category);
+
+	if (ioctl(devf, CDIOREADTOCHEADER, &h, sizeof(h)) != 0)
+		err(1, "CDIOREADTOCHEADER");
+
+	if (nitems(data) < h.ending_track - h.starting_track)
+		errx(1, "Too many tracks");
+
+	memset(&toc, 0, sizeof(toc));
+
+	toc.address_format = CD_MSF_FORMAT;
+	if ((toc.data = malloc(h.len)) == NULL)
+		err(1, "calloc");
+	toc.data_len = h.len;
+
+	if (ioctl(devf, CDIOREADTOCENTRIES, &toc, sizeof(toc)) != 0)
+		err(1, "ioctl(CDIOREADTOCENTRIES)");
+	n = h.ending_track - h.starting_track + 1;
+
+	/* calculate cdid */
+	for (i = 0; i < n; i++) {
+		int s = entry2sec(&toc.data[i]);
+		while (s > 0) {
+			diskid += s % 10;
+			s /= 10;
+		}
+	}
+	diskid = (diskid % 0xff) << 24 |
+	    (entry2sec(&toc.data[n]) - entry2sec(&toc.data[0])) << 8 | n;
+	fprintf(stdout,
+	    "To: freedb-submit@freedb.org\n"
+	    "Subject: cddb %s %08x\n"
+	    "\n"
+	    "# xmcd CD database file\n"
+	    "#\n"
+	    "# Track frame offsets:\n", category, diskid);
+
+	for (i = 0; i < n; i++) {
+		fprintf(stdout, "#\t%d\n", 
+		    entry2sec(&toc.data[i]) * FPS + toc.data[i].addr.msf.frame);
+	}
+
+	fprintf(stdout,
+	    "#\n"
+	    "# Disc length: %d seconds\n"
+	    "#\n"
+	    "# Revision: 0\n"
+	    "# Submitted via: %s %s\n"
+	    "#\n",
+	    entry2sec(&toc.data[i]), PROGNAME, VERSION);
+
+
+	fprintf(stdout,
+	    "DISCID=%08x\n"
+	    "DTITLE=XXX_ARTIST_NAME / XXX_ALBUM_NAME\n"
+	    "DYEAR=XXX_YEAR\n"
+	    "DGENRE=XXX_GENRE\n", diskid);
+	for (i = 0; i < n; i++)
+		fprintf(stdout, "TTITLE%d=\n", i);
+	fprintf(stdout, "EXTD=\n");
+	for (i = 0; i < n; i++)
+		fprintf(stdout, "EXTT%d=\n", i);
+	fprintf(stdout, "PLAYORDER=\n");
+	free(toc.data);
+
+	close(devf);
+
+	exit(EXIT_SUCCESS);
+}
+
+int
+entry2sec(struct cd_toc_entry *entry)
+{
+	return entry->addr.msf.minute * 60 + entry->addr.msf.second;
+}
+
+int
+is_valid_category(const char *category)
+{
+	int			 i;
+	static const char	*catego[] =
+	    { "blues","classical","country", "data", "folk","jazz","misc",
+	      "newage","reggae","rock","soundtrack" };
+
+	for (i = 0; i < nitems(catego); i++) {
+		if (strcmp(category, catego[i]) == 0)
+			return 1;
+	}
+
+	return 0;
+}

Property changes on: cddb-submit.c
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
