Subject: Re: Backing up CD's
To: Brian Rose <>
From: Steven M. Bellovin <>
List: current-users
Date: 07/23/2003 14:41:11
This is a multipart MIME message.

Content-Type: text/plain; charset=us-ascii

In message <>, Brian Rose writes:
>I'm backing up a game I purchased recently and I am having some issues. I am c
>urrently using good ole dd in the following way...
>dd if=/dev/cd0a of=filename.iso bs=2k
>I've used this on other CDs without issue. But on this game CD I get the follo
>bash-2.05b# dd if=/dev/cd0a of=Comanche4.iso bs=2k ; ls -la
>dd: /dev/cd0a: Input/output error
>821+0 records in
>821+0 records out
>1681408 bytes transferred in 2.174 secs (773416 bytes/sec)
>dd transfers 1.6 megabytes before dying. It should have 686,510,080 bytes (acc
>ording to my Windows box). I found some information on the net that suggests t
>hat multi-session CD's may not work with this method, but there was no informa
>tion about how to make it work.
>Any ideas?
Here's a simple program I wrote a while back to copy CDs.

Content-Type: text/plain ; name="cdread.c"; charset=us-ascii
Content-Description: cdread.c
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="cdread.c"

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/disklabel.h>
#include <sys/ioctl.h>

char	*buf;

main(int argc, char *argv[])
	int infd =3D 0, outfd =3D 1;
	int n;
	int full =3D 0, notfull =3D 0;
	off_t here;
	size_t bufsize =3D 30720;
	struct disklabel dlab;
	long btot =3D 0L;

	switch (argc) {
		case 1:
		case 2:
			infd =3D open(argv[1], O_RDONLY, 0);
		case 3:
			infd =3D open(argv[1], O_RDONLY);
			outfd =3D open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
			err(1, "usage error");
	if (infd < 0) err(2, "input file");
	if (outfd < 0) err(2, "output file");

	if (ioctl(infd, DIOCGDINFO, &dlab) < 0) err(5, "DIOCGDINFO");
	buf =3D malloc(bufsize);
	if (buf =3D=3D NULL) err(6, "malloc");
	while (1) {
		here =3D lseek(infd, (off_t) 0, SEEK_CUR);
		if (here < 0) err(11, "tell");
		if ((n =3D read(infd, buf, bufsize)) <=3D 0) break;
		if (n !=3D bufsize) warn("notfull long read %d", n);
		if (write(outfd, buf, (size_t) n) !=3D n)
			err(10, "big write");
		btot +=3D n;
	if (n !=3D 0) {
		if (lseek(infd, here, SEEK_SET) < 0)
			err(12, "lseek");
		while ((n =3D read(infd, buf, (size_t) dlab.d_secsize)) > 0) {
			if (n !=3D dlab.d_secsize) warn("notfull short read %d", n);
			if (write(outfd, buf, (size_t) n) !=3D n)
				err(10, "small write");
			btot +=3D n;
		if (n < 0) warn("last read");
	fprintf(stderr, "%d full, %d notfull, %ld bytes\n", full, notfull, btot)=
	return 0;

Content-Type: text/plain; charset=us-ascii

		--Steve Bellovin,