readcd.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:18k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)readcd.c 1.10 00/01/17 Copyright 1987 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)readcd.c 1.10 00/01/17 Copyright 1987 J. Schilling";
  5. #endif
  6. /*
  7.  * Skeleton for the use of the scg genearal SCSI - driver
  8.  *
  9.  * Copyright (c) 1987 J. Schilling
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2, or (at your option)
  15.  * any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; see the file COPYING.  If not, write to
  24.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  */
  26. #include <mconfig.h>
  27. #include <stdio.h>
  28. #include <standard.h>
  29. #include <unixstd.h>
  30. #include <stdxlib.h>
  31. #include <strdefs.h>
  32. #include <fctldefs.h>
  33. #include <timedefs.h>
  34. #include <scg/scgcmd.h>
  35. #include <scg/scsireg.h>
  36. #include <scg/scsitransp.h>
  37. #include "cdrecord.h"
  38. char cdr_version[] = "1.8";
  39. extern BOOL getlong __PR((char *, long *, long, long));
  40. extern BOOL getint __PR((char *, int *, int, int));
  41. typedef struct {
  42. long start;
  43. long end;
  44. char *name;
  45. } parm_t;
  46. EXPORT BOOL cvt_cyls __PR((void));
  47. EXPORT BOOL cvt_bcyls __PR((void));
  48. EXPORT void print_defect_list __PR((void));
  49. LOCAL void usage __PR((int ret));
  50. EXPORT int main __PR((int ac, char **av));
  51. LOCAL int prstats __PR((void));
  52. LOCAL void dorw __PR((SCSI *scgp, char *filename, char* sectors));
  53. LOCAL void doit __PR((SCSI *scgp));
  54. #ifdef used
  55. LOCAL int read_scsi_g1 __PR((SCSI *scgp, caddr_t bp, long addr, int cnt));
  56. #endif
  57. EXPORT int write_scsi __PR((SCSI *scgp, caddr_t bp, long addr, int cnt));
  58. EXPORT int write_g0 __PR((SCSI *scgp, caddr_t bp, long addr, int cnt));
  59. EXPORT int write_g1 __PR((SCSI *scgp, caddr_t bp, long addr, int cnt));
  60. #ifdef used
  61. LOCAL void Xrequest_sense __PR((SCSI *scgp));
  62. #endif
  63. LOCAL int rrr __PR((SCSI *scgp, long addr, long cnt));
  64. LOCAL void read_disk __PR((SCSI *scgp, parm_t *parmp));
  65. LOCAL void write_disk __PR((SCSI *scgp, parm_t *parmp));
  66. LOCAL int choice __PR((int n));
  67. LOCAL void ra __PR((SCSI *scgp));
  68. #ifndef TRUE
  69. # define TRUE 1
  70. # define FALSE 0
  71. #endif
  72. struct timeval starttime;
  73. struct timeval stoptime;
  74. char *Sbuf;
  75. long Sbufsize;
  76. int help;
  77. BOOL is_suid;
  78. BOOL is_cdrom;
  79. BOOL do_write;
  80. struct scsi_format_data fmt;
  81. /*XXX*/EXPORT BOOL cvt_cyls(){ return (FALSE);}
  82. /*XXX*/EXPORT BOOL cvt_bcyls(){ return (FALSE);}
  83. /*XXX*/EXPORT void print_defect_list(){}
  84. LOCAL void
  85. usage(ret)
  86. int ret;
  87. {
  88. error("Usage:treadcd [options]n");
  89. error("options:n");
  90. error("t-version print version information and exitn");
  91. error("tdev=target SCSI target to usen");
  92. error("tf=filename Name of file to read/writen");
  93. error("tsectors=range Range of sectors to read/writen");
  94. error("t-w Switch to write moden");
  95. error("tkdebug=#,kd=#tdo Kernel debuggingn");
  96. error("t-V increment SCSI command transport verbose level by onen");
  97. error("t-silent,-stdo not print status of erreneous commandsn");
  98. exit(ret);
  99. }
  100. char opts[]   = "kdebug#,kd#,Verbose,V+,silent,s,debug,help,h,version,dev*,f*,sectors*,w";
  101. EXPORT int
  102. main(ac, av)
  103. int ac;
  104. char *av[];
  105. {
  106. char *dev = NULL;
  107. int fcount;
  108. int cac;
  109. char * const *cav;
  110. int scsibus = 0;
  111. int target = 0;
  112. int lun = 0;
  113. int silent = 0;
  114. int verbose = 0;
  115. int lverbose= 0;
  116. int kdebug = 0;
  117. int debug = 0;
  118. int pversion = 0;
  119. SCSI *scgp;
  120. char *filename= NULL;
  121. char *sectors = NULL;
  122. save_args(ac, av);
  123. cac = --ac;
  124. cav = ++av;
  125. if(getallargs(&cac, &cav, opts,
  126. &kdebug, &kdebug,
  127. &verbose, &verbose,
  128. &silent, &silent, &debug,
  129. &help, &help, &pversion,
  130. &dev, &filename, &sectors, &do_write) < 0) {
  131. errmsgno(EX_BAD, "Bad flag: %s.n", cav[0]);
  132. usage(EX_BAD);
  133. }
  134. if (help)
  135. usage(0);
  136. if (pversion) {
  137. printf("readcd %s (%s-%s-%s) Copyright (C) 1987, 1995-2000 J鰎g Schillingn",
  138. cdr_version,
  139. HOST_CPU, HOST_VENDOR, HOST_OS);
  140. exit(0);
  141. }
  142. fcount = 0;
  143. cac = ac;
  144. cav = av;
  145. while(getfiles(&cac, &cav, opts) > 0) {
  146. fcount++;
  147. if (fcount == 1) {
  148. if (*astoi(cav[0], &target) != '') {
  149. errmsgno(EX_BAD,
  150. "Target '%s' is not a Number.n",
  151. cav[0]);
  152. usage(EX_BAD);
  153. /* NOTREACHED */
  154. }
  155. }
  156. if (fcount == 2) {
  157. if (*astoi(cav[0], &lun) != '') {
  158. errmsgno(EX_BAD,
  159. "Lun is '%s' not a Number.n",
  160. cav[0]);
  161. usage(EX_BAD);
  162. /* NOTREACHED */
  163. }
  164. }
  165. if (fcount == 3) {
  166. if (*astoi(cav[0], &scsibus) != '') {
  167. errmsgno(EX_BAD,
  168. "Scsibus is '%s' not a Number.n",
  169. cav[0]);
  170. usage(EX_BAD);
  171. /* NOTREACHED */
  172. }
  173. } else {
  174. scsibus = 0;
  175. }
  176. cac--;
  177. cav++;
  178. }
  179. /*error("dev: '%s'n", dev);*/
  180. if (dev) {
  181. char errstr[80];
  182. if ((scgp = open_scsi(dev, errstr, sizeof(errstr), debug, lverbose)) == (SCSI *)0)
  183. comerr("%s%sCannot open SCSI driver.n", errstr, errstr[0]?". ":"");
  184. /* scsi_settimeout(scgp, timeout);*/
  185. } else {
  186. if (scsibus == -1 && target >= 0 && lun >= 0)
  187. scsibus = 0;
  188. scgp = scsi_smalloc();
  189. scgp->debug = debug;
  190. scgp->kdebug = kdebug;
  191. scgp->scsibus = scsibus;
  192. scgp->target = target;
  193. scgp->lun = lun;
  194. if (!scsi_open(scgp, NULL, scsibus, target, lun))
  195. comerr("Cannot open SCSI driver.n");
  196. scgp->scsibus = scsibus;
  197. scgp->target = target;
  198. scgp->lun = lun;
  199. }
  200. scgp->silent = silent;
  201. scgp->verbose = verbose;
  202. scgp->debug = debug;
  203. scgp->kdebug = kdebug;
  204. Sbufsize = scsi_bufsize(scgp, 256*1024L);
  205. if ((Sbuf = scsi_getbuf(scgp, Sbufsize)) == NULL)
  206. comerr("Cannot get SCSI I/O buffer.n");
  207. is_suid = geteuid() != getuid();
  208. /*
  209.  * We don't need root privilleges anymore.
  210.  */
  211. #ifdef HAVE_SETREUID
  212. if (setreuid(-1, getuid()) < 0)
  213. #else
  214. #ifdef HAVE_SETEUID
  215. if (seteuid(getuid()) < 0)
  216. #else
  217. if (setuid(getuid()) < 0)
  218. #endif
  219. #endif
  220. comerr("Panic cannot set back efective uid.n");
  221. /* code to use SCG */
  222. do_inquiry(scgp, FALSE);
  223. if (is_suid) {
  224. if (scgp->inq->type != INQ_ROMD)
  225. comerrno(EX_BAD, "Not root. Will only work on CD-ROM in suid moden");
  226. }
  227. if (filename || sectors) {
  228. dorw(scgp, filename, sectors);
  229. } else {
  230. doit(scgp);
  231. }
  232. return (0);
  233. }
  234. LOCAL int
  235. prstats()
  236. {
  237. int sec;
  238. int usec;
  239. int tmsec;
  240. if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
  241. comerr("Cannot get timen");
  242. sec = stoptime.tv_sec - starttime.tv_sec;
  243. usec = stoptime.tv_usec - starttime.tv_usec;
  244. tmsec = sec*1000 + usec/1000;
  245. #ifdef lint
  246. tmsec = tmsec; /* Bisz spaeter */
  247. #endif
  248. if (usec < 0) {
  249. sec--;
  250. usec += 1000000;
  251. }
  252. error("Time total: %d.%03dsecn", sec, usec/1000);
  253. /* return (sec + (usec / 500000));*/
  254. return (1000*sec + (usec / 1000));
  255. }
  256. LOCAL void
  257. dorw(scgp, filename, sectors)
  258. SCSI *scgp;
  259. char *filename;
  260. char *sectors;
  261. {
  262. parm_t params;
  263. char *p = NULL;
  264. params.start = 0;
  265. params.end = -1;
  266. params.name = NULL;
  267. if (filename)
  268. params.name = filename;
  269. if (sectors)
  270. p = astol(sectors, &params.start);
  271. if (p && *p == '-')
  272. p = astol(++p, &params.end);
  273. if (p && *p != '')
  274. comerrno(EX_BAD, "Not a valid sector range '%s'n", sectors);
  275. if (!wait_unit_ready(scgp, 60))
  276. comerr("Device not ready.n");
  277. if (do_write)
  278. write_disk(scgp, &params);
  279. else
  280. read_disk(scgp, &params);
  281. }
  282. LOCAL void
  283. doit(scgp)
  284. SCSI *scgp;
  285. {
  286. int i = 0;
  287. for(;;) {
  288. if (!wait_unit_ready(scgp, 60))
  289. comerr("Device not ready.n");
  290. printf("0:read 1:veri   2:erase   3:read buffer 4:cache 5:ovtime 6:capn");
  291. printf("7:wne  8:floppy 9:verify 10:checkcmds  11:read disk 12:write diskn");
  292. printf("13:scsireset 14:seektest 15: readdan");
  293. getint("Enter selection:", &i, 0, 15);
  294. switch (i) {
  295. case 11: read_disk(scgp, 0); break;
  296. case 12: write_disk(scgp, 0); break;
  297. case 15: ra(scgp); break;
  298. }
  299. }
  300. }
  301. #ifdef used
  302. LOCAL int
  303. read_scsi_g1(scgp, bp, addr, cnt)
  304. SCSI *scgp;
  305. caddr_t bp;
  306. long addr;
  307. int cnt;
  308. {
  309. register struct scg_cmd *scmd = scgp->scmd;
  310. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  311. scmd->addr = bp;
  312. /* scmd->size = cnt*512;*/
  313. scmd->size = cnt*scgp->cap->c_bsize;
  314. scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
  315. scmd->cdb_len = SC_G1_CDBLEN;
  316. scmd->sense_len = CCS_SENSE_LEN;
  317. scmd->target = scgp->target;
  318. scmd->cdb.g1_cdb.cmd = 0x28;
  319. scmd->cdb.g1_cdb.lun = scgp->lun;
  320. g1_cdbaddr(&scmd->cdb.g1_cdb, addr);
  321. g1_cdblen(&scmd->cdb.g1_cdb, cnt);
  322. scgp->cmdname = "read extended";
  323. return (scsicmd(scgp));
  324. }
  325. #endif
  326. #define G0_MAXADDR 0x1FFFFFL
  327. EXPORT int
  328. write_scsi(scgp, bp, addr, cnt)
  329. SCSI *scgp;
  330. caddr_t bp;
  331. long addr;
  332. int cnt;
  333. {
  334. if(addr <= G0_MAXADDR)
  335. return(write_g0(scgp, bp, addr, cnt));
  336. else
  337. return(write_g1(scgp, bp, addr, cnt));
  338. }
  339. EXPORT int
  340. write_g0(scgp, bp, addr, cnt)
  341. SCSI *scgp;
  342. caddr_t bp;
  343. long addr;
  344. int cnt;
  345. {
  346. register struct scg_cmd *scmd = scgp->scmd;
  347. if (scgp->cap->c_bsize <= 0)
  348. raisecond("capacity_not_set", 0L);
  349. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  350. scmd->addr = bp;
  351. scmd->size = cnt*scgp->cap->c_bsize;
  352. scmd->flags = SCG_DISRE_ENA;
  353. scmd->cdb_len = SC_G0_CDBLEN;
  354. scmd->sense_len = CCS_SENSE_LEN;
  355. scmd->target = scgp->target;
  356. scmd->cdb.g0_cdb.cmd = SC_WRITE;
  357. scmd->cdb.g0_cdb.lun = scgp->lun;
  358. g0_cdbaddr(&scmd->cdb.g0_cdb, addr);
  359. scmd->cdb.g0_cdb.count = cnt;
  360. scgp->cmdname = "write_g0";
  361. return (scsicmd(scgp));
  362. }
  363. EXPORT int
  364. write_g1(scgp, bp, addr, cnt)
  365. SCSI *scgp;
  366. caddr_t bp;
  367. long addr;
  368. int cnt;
  369. {
  370. register struct scg_cmd *scmd = scgp->scmd;
  371. if (scgp->cap->c_bsize <= 0)
  372. raisecond("capacity_not_set", 0L);
  373. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  374. scmd->addr = bp;
  375. scmd->size = cnt*scgp->cap->c_bsize;
  376. scmd->flags = SCG_DISRE_ENA;
  377. scmd->cdb_len = SC_G1_CDBLEN;
  378. scmd->sense_len = CCS_SENSE_LEN;
  379. scmd->target = scgp->target;
  380. scmd->cdb.g1_cdb.cmd = SC_EWRITE;
  381. scmd->cdb.g1_cdb.lun = scgp->lun;
  382. g1_cdbaddr(&scmd->cdb.g1_cdb, addr);
  383. g1_cdblen(&scmd->cdb.g1_cdb, cnt);
  384. scgp->cmdname = "write_g1";
  385. return (scsicmd(scgp));
  386. }
  387. #ifdef used
  388. LOCAL void
  389. Xrequest_sense(scgp)
  390. SCSI *scgp;
  391. {
  392. char sense_buf[32];
  393. struct scg_cmd ocmd;
  394. int sense_count;
  395. char *cmdsave;
  396. register struct scg_cmd *scmd = scgp->scmd;
  397. cmdsave = scgp->cmdname;
  398. movebytes(scmd, &ocmd, sizeof(*scmd));
  399. fillbytes((caddr_t)sense_buf, sizeof(sense_buf), '');
  400. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  401. scmd->addr = (caddr_t)sense_buf;
  402. scmd->size = sizeof(sense_buf);
  403. scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
  404. scmd->cdb_len = SC_G0_CDBLEN;
  405. scmd->sense_len = CCS_SENSE_LEN;
  406. scmd->target = scgp->target;
  407. scmd->cdb.g1_cdb.cmd = 0x3;
  408. scmd->cdb.g1_cdb.lun = scgp->lun;
  409. scmd->cdb.g0_cdb.count = sizeof(sense_buf);
  410. scgp->cmdname = "request sense";
  411. scsicmd(scgp);
  412. sense_count = sizeof(sense_buf) - scsigetresid(scgp);
  413. movebytes(&ocmd, scmd, sizeof(*scmd));
  414. scmd->sense_count = sense_count;
  415. movebytes(sense_buf, (u_char *)&scmd->sense, scmd->sense_count);
  416. scgp->cmdname = cmdsave;
  417. scsiprinterr(scgp);
  418. scsiprintresult(scgp); /* XXX restore key/code in future */
  419. }
  420. #endif
  421. /*#define MAX_RETRY 32*/
  422. #define MAX_RETRY 128
  423. LOCAL int
  424. rrr(scgp, addr, cnt)
  425. SCSI *scgp;
  426. long addr;
  427. long cnt;
  428. {
  429. int secsize = scgp->cap->c_bsize;
  430. int try = 0;
  431. int err;
  432. char dummybuf[4000];
  433. errmsgno(EX_BAD, "Retrying from sector %d.n", addr);
  434. while (cnt > 0) {
  435. error(".");
  436. do {
  437. if (try != 0) {
  438. if ((try % 8) == 0) {
  439. error("+");
  440. scgp->silent++;
  441. read_g1(scgp, dummybuf, scgp->cap->c_baddr, 1);
  442. scgp->silent--;
  443. } else if ((try % 4) == 0) {
  444. error("-");
  445. scgp->silent++;
  446. read_g1(scgp, dummybuf, 0, 1);
  447. scgp->silent--;
  448. } else {
  449. error("~");
  450. scgp->silent++;
  451. read_g1(scgp, dummybuf, choice(scgp->cap->c_baddr), 1);
  452. scgp->silent--;
  453. }
  454. }
  455. scgp->silent++;
  456. /* err = read_scsi(scgp, Sbuf, addr, 1);*/
  457. err = read_g1(scgp, Sbuf, addr, 1);
  458. scgp->silent--;
  459. if (err < 0) {
  460. /* err = geterrno();*/
  461. err = scgp->scmd->ux_errno;
  462. /* error("n");*/
  463. /* errmsgno(err, "Cannot read source diskn");*/
  464. } else {
  465. break;
  466. }
  467. } while (++try < MAX_RETRY);
  468. if (try >= MAX_RETRY) {
  469. errmsgno(err, "Error not corrected.n");
  470. return (-1);
  471. } else {
  472. if (try > 1)
  473. errmsgno(EX_BAD, "Error corrected after %d tries.n", try);
  474. }
  475. try = 0;
  476. cnt -= 1;
  477. addr += 1;
  478. Sbuf += secsize;
  479. }
  480. return (0);
  481. }
  482. LOCAL void
  483. read_disk(scgp, parmp)
  484. SCSI *scgp;
  485. parm_t *parmp;
  486. {
  487. char filename[512];
  488. char *defname = "disk.out";
  489. FILE *f;
  490. long addr;
  491. long cnt;
  492. long end;
  493. int nsec;
  494. long start = 0L;
  495. int err = 0;
  496. /*int try;*/
  497. if (is_suid) {
  498. if (scgp->inq->type != INQ_ROMD)
  499. comerrno(EX_BAD, "Not root. Will only read from CD in suid moden");
  500. }
  501. filename[0] ='';
  502. read_capacity(scgp);
  503. end = scgp->cap->c_baddr + 1;
  504. if (end <= 0)
  505. end = 10000000; /* Hack to read empty (e.g. blank=fast) disks */
  506. if (parmp) {
  507. if (parmp->name)
  508. defname = parmp->name;
  509. error("Copy from SCSI (%d,%d,%d) disk to file '%s'n",
  510. scgp->scsibus, scgp->target, scgp->lun,
  511. defname);
  512. addr = start = parmp->start;
  513. if (parmp->end != -1 && parmp->end < end)
  514. end = parmp->end;
  515. cnt = Sbufsize / scgp->cap->c_bsize;
  516. }
  517. else {
  518. error("Copy from SCSI (%d,%d,%d) disk to filen",
  519. scgp->scsibus, scgp->target, scgp->lun);
  520. error("Enter filename [%s]: ", defname);flush();
  521. (void)getline(filename, sizeof(filename));
  522. addr = start;
  523. getlong("Enter starting sector for copy:", &addr, start, end-1);
  524. start = addr;
  525. cnt = end - addr;
  526. getlong("Enter number of sectors to copy:", &cnt, 1L, cnt);
  527. end = addr + cnt;
  528. cnt = Sbufsize / scgp->cap->c_bsize;
  529. getlong("Enter number of sectors per copy:", &cnt, 1L, cnt);
  530. /* error("end:  %8ldn", end);*/
  531. }
  532. if (filename[0] == '')
  533. strcpy(filename, defname);
  534. if (streql(filename, "-")) {
  535. f = stdout;
  536. #if defined(__CYGWIN32__) || defined(__EMX__)
  537. setmode(STDOUT_FILENO, O_BINARY);
  538. #endif
  539. } else if ((f = fileopen(filename, "wcub")) == NULL)
  540. comerr("Cannot open '%s'.n", filename);
  541. error("end:  %8ldn", end);
  542. if (gettimeofday(&starttime, (struct timezone *)0) < 0)
  543. comerr("Cannot get start timen");
  544. for(;addr < end; addr += cnt)                         {
  545. if ((addr + cnt) > end)
  546. cnt = end - addr;
  547. error("addr: %8d cnt: %dr", addr, cnt);
  548. /* try = 0;*/
  549. /* do {*/
  550. /* if (read_scsi(scgp, Sbuf, addr, cnt) < 0) {*/
  551. if (read_g1(scgp, Sbuf, addr, cnt) < 0) {
  552. /* err = geterrno();*/
  553. err = scgp->scmd->ux_errno;
  554. error("n");
  555. errmsgno(err, "Cannot read source diskn");
  556. /* break;*/
  557. if (rrr(scgp, addr, cnt) < 0)
  558. goto out;
  559. }
  560. /* else break;*/
  561. /* } while (++try < 10);*/
  562. /* if (try >= 10)*/
  563. /* break;*/
  564. if (filewrite(f, Sbuf, cnt * scgp->cap->c_bsize) < 0) {
  565. err = geterrno();
  566. error("n");
  567. errmsgno(err, "Cannot write '%s'n", filename);
  568. break;
  569. }
  570. }
  571. error("addr: %8d", addr);
  572. out:
  573. error("n");
  574. nsec = prstats();
  575. /* error("%dn",nsec);*/
  576. error("Read %.2f kB at %.1f kB/sec.n",
  577. (addr - start)/(1024.0/scgp->cap->c_bsize),
  578. ((addr - start)/(1024.0/scgp->cap->c_bsize)) / (0.001*nsec));
  579. if (err)
  580. exit(err);
  581. }
  582. LOCAL void
  583. write_disk(scgp, parmp)
  584. SCSI *scgp;
  585. parm_t *parmp;
  586. {
  587. char filename[512];
  588. char *defname = "disk.out";
  589. FILE *f;
  590. long addr = 0L;
  591. long cnt;
  592. long amt;
  593. long end;
  594. int nsec;
  595. int start;
  596. if (is_suid)
  597. comerrno(EX_BAD, "Not root. Will not write in suid moden");
  598. read_capacity(scgp);
  599. end = scgp->cap->c_baddr + 1;
  600. if (end <= 0)
  601. end = 10000000; /* Hack to write empty disks */
  602. if (parmp) {
  603. if (parmp->name)
  604. defname = parmp->name;
  605. error("Copy from file '%s' tp SCSI (%d,%d,%d) diskn",
  606. defname,
  607. scgp->scsibus, scgp->target, scgp->lun);
  608. addr = start = parmp->start;
  609. if (parmp->end != -1 && parmp->end < end)
  610. end = parmp->end;
  611. cnt = Sbufsize / scgp->cap->c_bsize;
  612. }
  613. else {
  614. error("Copy from file to SCSI (%d,%d,%d) diskn",
  615. scgp->scsibus, scgp->target, scgp->lun);
  616. error("Enter filename [%s]: ", defname);flush();
  617. (void)getline(filename, sizeof(filename));
  618. error("Notice: reading from file always starts at file offset 0.n");
  619. getlong("Enter starting sector for copy:", &addr, 0L, end-1);
  620. start = addr;
  621. cnt = end - addr;
  622. getlong("Enter number of sectors to copy:", &end, 1L, end);
  623. end = addr + cnt;
  624. cnt = Sbufsize / scgp->cap->c_bsize;
  625. getlong("Enter number of sectors per copy:", &cnt, 1L, cnt);
  626. /* error("end:  %8ldn", end);*/
  627. }
  628. if (filename[0] == '')
  629. strcpy(filename, defname);
  630. if (streql(filename, "-")) {
  631. f = stdin;
  632. #if defined(__CYGWIN32__) || defined(__EMX__)
  633. setmode(STDIN_FILENO, O_BINARY);
  634. #endif
  635. } else if ((f = fileopen(filename, "rub")) == NULL)
  636. comerr("Cannot open '%s'.n", filename);
  637. error("end:  %8ldn", end);
  638. if (gettimeofday(&starttime, (struct timezone *)0) < 0)
  639. comerr("Cannot get start timen");
  640. for(;addr < end; addr += cnt) {
  641. if ((addr + cnt) > end)
  642. cnt = end - addr;
  643. error("addr: %8d cnt: %dr", addr, cnt);
  644. if ((amt = fileread(f, Sbuf, cnt * scgp->cap->c_bsize)) < 0)
  645. comerr("Cannot read '%s'n", filename);
  646. if (amt == 0)
  647. break;
  648. if ((amt / scgp->cap->c_bsize) < cnt)
  649. cnt = amt / scgp->cap->c_bsize;
  650. if (write_scsi(scgp, Sbuf, addr, cnt) < 0)
  651. comerrno(scgp->scmd->ux_errno,
  652. "Cannot write destination diskn");
  653. }
  654. error("addr: %8dn", addr);
  655. nsec = prstats();
  656. error("Wrote %.2f kB at %.1f kB/sec.n",
  657. (double)(addr - start)/(1024.0/scgp->cap->c_bsize),
  658. (double)((addr - start)/(1024.0/scgp->cap->c_bsize)) / nsec);
  659. }
  660. LOCAL int
  661. choice(n)
  662. int n;
  663. {
  664. #if !defined(__CYGWIN32__) && !defined(__EMX__)
  665. extern double drand48 __PR((void));
  666. return drand48() * n;
  667. #else
  668. return (0);
  669. #endif
  670. }
  671. LOCAL void
  672. ra(scgp)
  673. SCSI *scgp;
  674. {
  675. /* char filename[512];*/
  676. FILE *f;
  677. /* long addr = 0L;*/
  678. /* long cnt;*/
  679. /* long end;*/
  680. /* int nsec;*/
  681. /* int start;*/
  682. /* int err = 0;*/
  683. select_secsize(scgp, 2352);
  684. read_capacity(scgp);
  685. fillbytes(Sbuf, 50*2352, 0);
  686. if (read_g1(scgp, Sbuf, 0, 50) < 0)
  687. errmsg("read CDn");
  688. f = fileopen("DDA", "wctb");
  689. /* filewrite(f, Sbuf, 50 * 2352 - scsigetresid(scgp));*/
  690. filewrite(f, Sbuf, 50 * 2352 );
  691. fclose(f);
  692. }
  693. #ifdef XXX
  694. EXPORT int
  695. read_da(scgp, bp, addr, cnt)
  696. SCSI *scgp;
  697. caddr_t bp;
  698. long addr;
  699. int cnt;
  700. {
  701. register struct scg_cmd *scmd = scgp->scmd;
  702. if (scgp->cap->c_bsize <= 0)
  703. raisecond("capacity_not_set", 0L);
  704. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  705. scmd->addr = bp;
  706. scmd->size = cnt*scgp->cap->c_bsize;
  707. scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
  708. scmd->cdb_len = SC_G5_CDBLEN;
  709. scmd->sense_len = CCS_SENSE_LEN;
  710. scmd->target = scgp->target;
  711. /* scmd->cdb.g5_cdb.cmd = SC_EREAD;*/
  712. scmd->cdb.g5_cdb.cmd = 0xd9;
  713. scmd->cdb.g5_cdb.lun = scgp->lun;
  714. g5_cdbaddr(&scmd->cdb.g1_cdb, addr);
  715. g5_cdblen(&scmd->cdb.g1_cdb, cnt);/* XXX subscript out of range ?? */
  716. scgp->cmdname = "read_g1";
  717. return (scsicmd(scgp));
  718. }
  719. #endif