⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 使用libscsi做的一系列cdrom操作工具程序。包含cdwrite,cdflush,cdda三个程序
💻 C
字号:
/*  main -- main function  Copyright (C) 1996 Dieter Baron and Armin Obersteiner  This file is part of cdwrite.  The authors can be contacted at	<dillo@giga.or.at>	<armin.obersteiner@giga.or.at>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <scsi/all.h>#include <scsi/cd.h>#include <scsi/hp.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include <errno.h>#include <sys/time.h>#include <sys/resource.h>#include <unistd.h>#include <getopt.h>#include "cdwrite.h"#ifndef DEFDEV#ifdef AMIGA#define DEFDEV "gvpscsi.device:2"#else#define DEFDEV "/dev/cdwriter"#endif#endif#ifdef AMIGA#include <exec/tasks.h>struct Task *task=0L;#endifchar *prg;#define USAGE "\Usage: %s [-hVvqncwFC] [-s speed] [-D device] [-m mode] [-f layout]\n\       %s [options] {[-iadpP] [-b bytes] file} ...\n"extern char version[];char help[] = "\  -h, --help            display this message and exit\n\  -V, --version         display version and exit\n\\n\Options:\n\  -v, --verbose         verbose output\n\  -q, --quiet           no output except errors, no confirmation on warnings\n\  -n, --no-confirm      no confirmation\n\  -c, --confirm         always ask for confirmation\n\\n\  -s, --speed SPEED     select writing speed\n\  -e, --emulate         emulation write [default]\n\  -w, --no-emulate      real write\n\  -D, --device DEVICE   select device [default: " DEFDEV "]\n\  -m, --mode MODE       select type of writer\n\  -F, --fixate          fixate after writing tracks\n\  -C, --close           close cd (no further sessions possible)\n\\n\  -f, --layout FILE     read FILE for track list\n\\n\Per Track Options:\n\  -b, --bytes BYTES     specify length of track\n\  -i, --iso             track is iso image\n\  -a, --audio           track is audio (red book) data\n\  -d, --data            track is cd-rom () data [default]\n\  -p, --preemp          audio track is preemphasised\n\  -P, --no-preemp       audio track is linar [default]\n";#define OPTS "+hVvqnFCs:ewD:m:cf:b:iadpP"#define TRACK_OPTS "+b:iadpP"struct option options[] = {    { "help",      0, 0, 'h' },    { "version",   0, 0, 'V' },    { "verbose",   0, 0, 'v' },    { "quiet",     0, 0, 'q' },    { "silent",    0, 0, 'q' },    { "no-confirm",0, 0, 'n' },    { "confirm",   0, 0, 'c' },        { "speed",     1, 0, 's' },    { "emulate",   0, 0, 'e' },    { "no-emulate",0, 0, 'w' },    { "device",    1, 0, 'D' },    { "mode",      1, 0, 'm' },    { "fixate",    0, 0, 'F' },    { "close",     0, 0, 'C' },    { "layout",    1, 0, 'f' },    { "bytes",     1, 0, 'b' },    { "iso",       0, 0, 'i' },    { "audio",     0, 0, 'a' },    { "data",      0, 0, 'd' },    { "preemp",    0, 0, 'p' },    { "no-preemp", 0, 0, 'P' },    { NULL,        0, 0, 0   }};struct option *track_options = &options[12];    struct plan {    char *name;    char *vendor;    char *product;    int mode;    int speed;};struct plan plan[] = {    { "hp",      "hp",      "", 0, 0 },    { "philips", "philips", "", 1, 2 },    { "ims",     "ims",     "", 1, 2 },    { "kodak",   "kodak",   "", 1, 2 },    { "yamaha",  "yamaha",  "", 2, 2 },    { NULL }};char *mode_name[] = {    "hp",    "philips",    "yamaha"};int mode;struct track tinfo[99];int track;int verbose, confirm, written, isdata;SCSI *scsi;#define BLKFUZZY  10240 /* 20M */intmain(int argc, char **argv){    int speed, dummy, close, blks, err, do_fixate;    u_long maxblks, blksize;    char *device, *layout;    char b[4096];    int c, i;    prg = argv[0];    err = opterr = 0;    layout = device = NULL;    written = isdata = confirm = track = close = verbose = speed = dummy = 0;    mode = -1;    do_fixate = 0;    dummy = 1;    while (argc) {    while ((c=getopt_long(argc, argv,                  (track ? TRACK_OPTS : OPTS),                  (track ? track_options : &options[0]),                  0)) != EOF) {        switch (c) {        case 'v':	    verbose = 1;	    break;        case 'c':	    confirm = 1;	    break;        case 'n':	    confirm = -1;	    break;        case 'q':	    verbose = -1;	    break;        case 's':	    speed = atoi(optarg);	    break;        case 'e':	    dummy = 1;	    break;        case 'w':	    dummy = 0;	    break;        case 'D':	    device = strdup(optarg);        break;        case 'm':	    for (i=0; plan[i].name; i++) {		if (strcasecmp(optarg, plan[i].name) == 0) {		    mode = i;		    break;		}	    }	    if (plan[i].name == NULL) {		fprintf(stderr, "%s: unknown mode `%s'\n",			prg, optarg);		exit(1);	    }	    break;        case 'F':	    do_fixate = 1;	    break;                case 'C':	    close = 1;	    do_fixate = 1;	    break;        case 'f':	    layout = strdup(optarg);	    break;#define LAYOUT_PRESENT if (layout) {fprintf(stderr, "%s: track options \cannot be used together with -f\n", prg); exit(1);}        case 'b':	    LAYOUT_PRESENT;	    tinfo[track].size = strtoul(optarg, NULL, 0);	    break;        case 'i':	    LAYOUT_PRESENT;	    tinfo[track].size = ULONG_MAX;	    tinfo[track].audio = 0;	    break;        case 'a':	    LAYOUT_PRESENT;	    tinfo[track].audio = 1;	    if (tinfo[track].size == ULONG_MAX)		tinfo[track].size = 0;	    break;        case 'd':	    LAYOUT_PRESENT;	    tinfo[track].audio = 0;	    if (tinfo[track].size == ULONG_MAX)		tinfo[track].size = 0;	    break;        case 'p':	    LAYOUT_PRESENT;	    tinfo[track].emp = 1;	    break;        case 'P':	    LAYOUT_PRESENT;	    tinfo[track].emp = 0;	    break;        #undef LAYOUT_PRESENT                case 'h':	    printf("%s\n\n", version);	    printf(USAGE "\n%s\n", prg, prg, help);	    exit(0);        case 'V':	    printf("%s\n", version);	    exit(0);        default:	    printf(USAGE, prg, prg);	    exit(0);        }    }    if ((layout == NULL) != (argc != optind)) {        fprintf(stderr, USAGE, prg, prg);        exit(1);    }    if (layout)        read_layout(layout);    else {        tinfo[track++].name = argv[optind++];        tinfo[track].audio = tinfo[track-1].audio;        tinfo[track].emp = tinfo[track-1].emp;        if (tinfo[track-1].size == ULONG_MAX)        tinfo[track].size = ULONG_MAX;    }    if (track > 99 && argc != optind) {        fprintf(stderr, "%s: too many tracks\n", prg);        exit(1);    }    if (argc != optind) {        argv += optind-1;        argc -= optind-1;        optind = 0;    }    else        argc = 0;    }    if (device == NULL)	device = DEFDEV;    if ((blks=open_files()) < 0)	exit(1);    if ((scsi=sc_open(device)) == NULL) {	fprintf(stderr, "%s: can't open device `%s': %s\n",		prg, device, strerror(errno));	exit(1);    }    if (mode == -1) {	struct sc_inquiry inq;	if (sc_inquiry(scsi, &inq) < 0) {	    sc_fstatus(scsi, stderr, prg, "inquiry", 3);	    sc_close(scsi);	    exit(1);	}	for (i=0; plan[i].name; i++)	    if (strncasecmp(inq.vendor, plan[i].vendor,			    strlen(plan[i].vendor)) == 0		&& strncasecmp(inq.product, plan[i].product,			       strlen(plan[i].product)) == 0) {		mode = i;		break;	    }	if (plan[i].name == NULL) {	    fprintf(stderr, "%s: unknown cd writer: [%s, %s]\n",		    prg, inq.vendor, inq.product);	    sc_close(scsi);	    exit(1);	}    }    if (speed == 0)	speed = plan[mode].speed;    if (sc_da_read_capacity(scsi, &maxblks, &blksize, 0) < 0) {	sc_fstatus(scsi, stderr, prg, "read-capacity", 3);	sc_close(scsi);	exit(1);    }    if (blksize != 0) {	fprintf(stderr, "%s: no write area on disk\n", prg);	sc_close(scsi);	exit(1);    }    if (blks > maxblks) {	fprintf(stderr, "%s: not enough space on disk (free: %ld, need: %d)\n",		prg, maxblks, blks);	sc_close(scsi);	exit(1);    }    if (blks > maxblks-BLKFUZZY && verbose > -1) {	fprintf(stderr, "%s: warning: little space left for leadin/leadout "		"(%d)\n",		prg, (int)maxblks-blks);	if (confirm > -1)	    confirm = 1;    }#ifdef AMIGA    task=FindTask(NULL);    SetTaskPri(task,-20);#else    if (setpriority(PRIO_PROCESS, 0, -20) < 0 && verbose > -1) {	fprintf(stderr, "%s: warning: can't renice\n");	if (confirm > -1)	    confirm = 1;    }#endif    if (verbose > 0 || confirm > 0) {	printf("\n");	printf("Plan:   %s\n", plan[mode].name);	printf("Speed:  %d\n", speed);	printf("Space:  needed %d, free %ld, excess %d\n",	       blks, maxblks, (int)maxblks-blks);	printf("Device: %s\n", device);	printf("Flags: %s%s%s\n",	       (do_fixate ? " fixating" : ""),	       (close ? " closing" : ""),	       (dummy ? " emulating" : ""));	printf("\n");	for (i=0; i<track; i++) {	    printf("%02d: `%s', %lu%s%s\n",		   i+1, tinfo[i].name, tinfo[i].size,		   (tinfo[i].audio ? " audio" : ""),		   (tinfo[i].audio && tinfo[i].emp ? " pre-emp" : ""));	}		if (confirm > 0) {	    printf("\ncontinue? ");	    fflush(stdout);	    fgets(b, 4096, stdin);	    if (tolower(b[0]) != 'y') {		sc_close(scsi);		exit(0);	    }	}	printf("\n");    }        if (setup(speed, dummy)) {	sc_close(scsi);	exit(1);    }    for (i=0; i<track; i++) {	switch (write_track(i)) {	case -1:	    fprintf(stderr, "%s: aborting; didn't start writing track\n",		    prg);	    do_fixate = 0;	    goto track_fail;	case -2:	    fprintf(stderr, "%s: aborting: writing track ended prematurely\n",		    prg);	    do_fixate = 0;	    goto track_fail;	case -3:	    fprintf(stderr, "%s: aborting: writer in inconsistent state\n",		    prg);	    do_fixate = 0;	    goto track_fail;	}    }track_fail:    if (do_fixate && written) {	if (verbose > 0)	    printf("fixating...\n");	if (sc_set_timeout(scsi, 600000 /* 10 mins */) < 0) {	    fprintf(stderr, "%s: warning: can't set scsi timeout\n");	}	if (sc_hp_fixation(scsi, 0 /* 1 */, !close, isdata) < 0) {	    sc_fstatus(scsi, stderr, prg, "fixate", 3);	    err = 1;	}    }    if (cleanup()) {	sc_close(scsi);	exit(1);    }    sc_close(scsi);    exit(err);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -