📄 main.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;#endifchar *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 + -