copycd.c revision 416baccdfbdf5cf94094097179a33abd373ed35e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <libintl.h>
#include <string.h>
#include "main.h"
#include "util.h"
#include "misc_scsi.h"
#include "mmc.h"
#include "bstream.h"
#include "device.h"
#include "msgs.h"
#include "transport.h"
struct t_data {
struct track_info ti;
};
/*
* This reads the data off of a cd while updating the progress indicator.
* We want to do this in smaller chunks since some CD drives have
* problems with larger reads.
*/
static int
{
int blksize;
int link_blks_count;
ret = 0;
/*
* the last link_blks_count blocks may not exist or be completely
* filled. We need to record the amount to avoid bailing out if
* they cannot be read.
*/
blksize = 512;
link_blks_count = 8;
} else {
blksize = 2048;
link_blks_count = 2;
}
if (verbose)
blks_read = 0;
/* Last few are special */
if (read_chunk == 0) {
/* Time for last link blocks */
}
goto read_data_track_failed;
}
} else {
if (blks_read !=
goto read_data_track_failed;
} else {
/* Read can fail for last link sectors */
errno = 0;
}
}
blks_read += read_chunk;
cblk += read_chunk;
}
/* l10n_NOTE : 'done' as in "Reading track 1...done" */
ret = 1;
return (ret);
}
static void
{
if (use_media_stated_capacity) {
if (nblks_avail <= 0) {
/* most newer drives use READ FORMAT CAPACITY */
&bsize);
/* if both methods fail no choice but to bail out */
if (nblks_avail <= 0) {
"Cannot find out media capacity.\n"));
exit(1);
}
}
} else {
if (device_type == CD_RW) {
} else {
/*
* For DVD drives use read_format_capacity as default
* retrieve the media size, it can be 3.6, 3.9, 4.2,
* 4.7, or 9.2 GB
*/
/* sanity check. if not reasonable default to 4.7 GB */
if (nblks_avail < MAX_CD_BLKS) {
}
}
}
if (debug) {
(void) printf("Need %u only found %u \n",
}
exit(1);
}
}
/*
* This copies both audio and data CDs. It first reads the TOC of the source CD
* and creates a temp file with the CD image. After this is completed it creates
* the target CD using TAO mode.
*/
void
copy_cd(void)
{
char *p;
int blksize, i;
int ret;
(void) check_device(target,
/* if source drive is specified on the command line */
if (copy_src) {
if (lookup_device(copy_src, p) == 0) {
exit(1);
}
exit(1);
}
free(p);
} else {
/* source is same as target drive */
}
exit(1);
}
total_nblks = 0;
/* build track information so we can copy it over */
for (i = 1; i <= end_tno; i++) {
struct track_info *ti;
"Cannot get information for track %d\n"), i);
exit(1);
}
data_cd = 1;
else
audio_cd = 1;
/* Now some sanity checks on the track information */
gettext("Copying multisession CD is not supported\n"));
exit(1);
}
exit(1);
}
exit(1);
}
}
/* l10n_NOTE : 'done' as in "Analyzing source CD...done" */
if (data_cd) {
blksize = 2048;
} else {
/* audio cd */
blksize = 2352;
}
/* In case of audio CDs, build_track_info() returns 2352 sized nblks */
total_nblks /= 4;
}
" temporary directory\n"));
exit(1);
}
/*
* If we can check available space on the target media at this
* Stage, then it is always better. We cannot check DVD+R(W)
* as this media may be formatted and not blank.
*/
}
/* for each track */
for (i = 1; i <= end_tno; i++) {
get_err_str());
exit(1);
}
if (audio_cd)
tlist[i - 1].h);
else
tlist[i - 1].h);
if (ret == 0) {
get_err_str());
if (debug)
exit(1);
}
}
/*
* We've finished copying the CD. If source and destination are the same
* or they where not specified then eject the disk and wait for a new
* disk to be inserted.
*/
(void) eject_media(target);
}
(void) printf("\n");
gettext("Insert a blank media in the drive and press Enter."));
if (target) {
}
(void) getchar();
(void) sleep(4);
(void) setup_target(SCAN_WRITERS);
}
(void) printf("\n");
}
/* for each track */
for (i = 0; i < end_tno; i++) {
/*
* DVD's dont contain tracks and need to be written in DAO
* mode.
*/
if (device_type != CD_RW) {
if (end_tno > 1) {
"Media state is not suitable for this"
" write mode.\n"));
}
/*
* DVD-R(W) and DVD+R needs to have space reserved
* prior to writing.
*/
if ((device_type == DVD_MINUS) ||
(device_type == DVD_PLUS)) {
total_nblks + 1)) {
"Setting reservation failed\n"));
exit(1);
}
}
}
tlist[i].h);
/*
* Running in simulation mode and writing several tracks is
* useless so bail after the first track is done.
*/
"Simulation mode : skipping remaining tracks\n"));
break;
}
}
write_fini();
/* close the temp file handles */
for (i = 0; i < end_tno; i++)
exit(0);
}