home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / 3b1 / volume02 / fdcopy / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-06-22  |  22.6 KB

  1. Path: comp-sources-3b1
  2. From: dave@galaxia.network23.com (David H. Brierley)
  3. Subject:  v02i007:  fdcopy: floppy disk copy program, Part01/01
  4. Newsgroups: comp.sources.3b1
  5. Approved: dave@galaxia.network23.com
  6. X-Checksum-Snefru: df142178 d2520e76 ce247b12 8c6d0e9c
  7.  
  8. Submitted-by: dave@galaxia.network23.com (David H. Brierley)
  9. Posting-number: Volume 2, Issue 7
  10. Archive-name: fdcopy/part01
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 1 (of 1)."
  19. # Contents:  MANIFEST README.fdcopy fdcopy.c makefile
  20. # Wrapped by dave@galaxia on Mon Jun 22 22:59:19 1992
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  24. else
  25. echo shar: Extracting \"'MANIFEST'\" \(220 characters\)
  26. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  27. X   File Name        Archive #    Description
  28. X-----------------------------------------------------------
  29. X MANIFEST                   1    
  30. X README.fdcopy              1    
  31. X fdcopy.c                   1    
  32. X makefile                   1    
  33. END_OF_FILE
  34. if test 220 -ne `wc -c <'MANIFEST'`; then
  35.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  36. fi
  37. # end of 'MANIFEST'
  38. fi
  39. if test -f 'README.fdcopy' -a "${1}" != "-c" ; then 
  40.   echo shar: Will not clobber existing file \"'README.fdcopy'\"
  41. else
  42. echo shar: Extracting \"'README.fdcopy'\" \(3619 characters\)
  43. sed "s/^X//" >'README.fdcopy' <<'END_OF_FILE'
  44. XProgram: fdcopy
  45. XAuthor:  David H. Brierley
  46. X     dave@galaxia.network23.com
  47. X
  48. XCopyright 1992 David H. Brierley, All Rights Reserved
  49. X
  50. XNOTE: This software is currently in beta-test status and could potentially
  51. Xcrash your system.  See warnings at end of this README for details.
  52. X
  53. XFdcopy is a program which was designed and developed for running on an
  54. XAT&T 3B1 computer which will duplicate virtually any disk which is
  55. Xphysically readable on the 3B1 floppy disk drive.  The stock 3B1 floppy
  56. Xdrive can read any 5.25" disk which is formatted with 8, 9, or 10 sectors
  57. Xper track, 40 cylinders per disk.  It is also possible to replace the
  58. Xfloppy drive with a low density 3.5" drive (up to 10 sectors per track,
  59. X80 cylinders) or with a 720K 5.25" drive (up to 10 sectors per track, 80
  60. Xcylinders).
  61. X
  62. XIn its normal mode of operation the program uses a curses based interface
  63. Xwhich allows you to set all the required parameters for the copy.  This
  64. Xinterface generally obviates the need for a man page and hence none is
  65. Xprovided.  If you really enjoy specifying lots of command line options,
  66. Xor if you really abhor using the curses interface, here is a list of the
  67. Xcommand line options that are available.  Note that the first two options
  68. Xon the list are only available via the command line.  In the case of the
  69. X"-n" option the reason should be obvious, in the case of the "-z" option
  70. XI don't remember why this is so.
  71. X
  72. X-n    = dont use curses interface (command line only)
  73. X-z    = use verbose mode when formatting floppy (command line only)
  74. X-c nn    = number of cylinders in source disk
  75. X-h nn    = number of heads
  76. X-s nn    = number of sectors per track
  77. X-v    = verify target disk after making copy
  78. X-f    = format traget disk before making copy
  79. X-m    = make multiple copies of source disk
  80. X
  81. XThe default value for the -z flag is controlled by a compile-time option.
  82. XRead the source file for details.  The -v, -f, and -m options are all off
  83. Xbe default.
  84. X
  85. XThe default number of cylinders is a compile-time option.  The program will
  86. Xautomatically determine the number of cylinders present on the source disk,
  87. Xup to the number specified by the -c option (or the default).  The default
  88. Xnumber of sectors is 10 and the program will automatically sense if the
  89. Xdisk actually has less than this number.  The default number of heads is 2
  90. Xand the program has never been tested with any other value.
  91. X
  92. XThis program has been successfully used to duplicate 3b1 floppies, using the
  93. Xstock floppy drive, a 720K 3.5" drive, and a 720K 5.25" drive.  It has also
  94. Xbeen used to duplicate MS-DOS floppies in each of those formats and IMAGEN
  95. Xsystem disks.
  96. X
  97. X
  98. XWARNING! WARNING! WARNING! Danger Will Robinson!
  99. X
  100. XDue to either a bug in the gd driver or the complete lack of documentation
  101. Xof how to use the special ioctl() interface for direct access to the floppy
  102. Xdrive, if you use this program to duplicate a floppy with more than 80
  103. Xcylinders (ie. a 3.5" floppy formatted to 84 cylinders) there is a high
  104. Xprobability that your system will "panic" and print some totally meaningless
  105. Xnumbers on the screen and wait for you to press the reset button.  The bug
  106. Xonly seems to manifest itself when you let the program dynamically figure
  107. Xout how many cylinders there are on the disk so the workaround is to specify
  108. Xexactly how many cylinders you have on the source disk.  If you can figure
  109. Xout what I'm doing wrong, or if you have access to the source and can tell
  110. Xme how the ioctl interface is supposed to work, I would appreciate hearing
  111. Xfrom you.
  112. X
  113. XDespite the warnings, for the cases where the program works correctly it is
  114. Xa really handy program.  I use it all the time to duplicate MS-DOS disks.
  115. END_OF_FILE
  116. if test 3619 -ne `wc -c <'README.fdcopy'`; then
  117.     echo shar: \"'README.fdcopy'\" unpacked with wrong size!
  118. fi
  119. # end of 'README.fdcopy'
  120. fi
  121. if test -f 'fdcopy.c' -a "${1}" != "-c" ; then 
  122.   echo shar: Will not clobber existing file \"'fdcopy.c'\"
  123. else
  124. echo shar: Extracting \"'fdcopy.c'\" \(15050 characters\)
  125. sed "s/^X//" >'fdcopy.c' <<'END_OF_FILE'
  126. X#include <stdio.h>
  127. X#include <curses.h>
  128. X#include <ctype.h>
  129. X#include <sys/types.h>
  130. X#include <fcntl.h>
  131. X#include <errno.h>
  132. X#include <malloc.h>
  133. X#include <memory.h>
  134. X#include <string.h>
  135. X#include <stdlib.h>
  136. X#include <unistd.h>
  137. X/*
  138. X * F_LOCK in unistd.h conflicts with F_LOCK in gdioctl.h
  139. X * sys/gdioctl.h includes sys/param.h which redefines NULL
  140. X */
  141. X#undef    F_LOCK
  142. X#undef    NULL
  143. X#include <sys/gdioctl.h>
  144. X
  145. X/*
  146. X * Define IV_VERBOSE if you want the iv command run in verbose mode when
  147. X * formatting the target disk.
  148. X */
  149. X/* #define        IV_VERBOSE */
  150. X
  151. X/*
  152. X * Define the size of a standard sector on the floppy.
  153. X */
  154. X#define        SECTOR        512
  155. X
  156. X/*
  157. X * Define the default number of cylinders on a floppy.
  158. X */
  159. X#define        DEFAULT_CYLS    80
  160. X
  161. X/*
  162. X * Define the name of the floppy device.
  163. X */
  164. X#define        FLOPPY        "/dev/rfp020"
  165. X
  166. X/*
  167. X * Some extra defines that are handy for dealing with curses input
  168. X */
  169. X#define        ENTER        012
  170. X#define        RETURN        015
  171. X#define        ESCAPE        033
  172. X
  173. X
  174. X/* fdcopy.c */
  175. Xint             main (int argc, char *argv[]);
  176. Xint             init_floppy (int fd, int ncyl, int nheads, int nsect);
  177. Xvoid            wait_for_return (char *msg);
  178. Xint             set_sectors (int fd, int cyls, int hds, int sect);
  179. Xint             read_source (int fd, int cyls, int hds, int sect, char *buf);
  180. Xint             write_target (int cyls, int hds, int sect, char *buf, int vflg);
  181. Xvoid            format_disk (int cyls, int hds, int sect, int verbose);
  182. Xvoid            set_options (int *c, int *h, int *s, int *v, int *f, int *m);
  183. Xint             yes_or_no (char *msg);
  184. X
  185. X/* external routines */
  186. Xextern int      getopt (int argc, char *argv[], char *key);
  187. Xextern char    *mktemp (char *key);
  188. X
  189. Xint
  190. Xmain (int argc, char *argv[])
  191. X{
  192. X    int             fd_floppy;
  193. X    char           *buf;
  194. X    int             blksize;
  195. X    unsigned int    bufsize;
  196. X    int             cyls;
  197. X    int             save_cyls;
  198. X    int             heads;
  199. X    int             sectors;
  200. X    int             verify;
  201. X    int             fmt_flag;
  202. X    int             no_curses;
  203. X    int             multi_copy;
  204. X    int             rc;
  205. X    int             re_format;
  206. X    int             iv_verbose;
  207. X    int             optc;
  208. X    extern char    *optarg;
  209. X
  210. X    cyls = DEFAULT_CYLS;
  211. X    heads = 2;
  212. X    sectors = 10;
  213. X    multi_copy = no_curses = fmt_flag = verify = 0;
  214. X#ifdef    IV_VERBOSE
  215. X    iv_verbose = 1;
  216. X#else
  217. X    iv_verbose = 0;
  218. X#endif
  219. X
  220. X    while ((optc = getopt (argc, argv, "c:h:s:vfnmz")) != EOF) {
  221. X    switch (optc) {
  222. X    case 'c':
  223. X        cyls = atoi (optarg);
  224. X        break;
  225. X    case 'h':
  226. X        heads = atoi (optarg);
  227. X        break;
  228. X    case 's':
  229. X        sectors = atoi (optarg);
  230. X        break;
  231. X    case 'v':
  232. X        verify = 1;
  233. X        break;
  234. X    case 'f':
  235. X        fmt_flag = 1;
  236. X        break;
  237. X    case 'n':
  238. X        no_curses = 1;
  239. X        break;
  240. X    case 'm':
  241. X        multi_copy = 1;
  242. X        break;
  243. X    case 'z':
  244. X        iv_verbose = 1 - iv_verbose;
  245. X        break;
  246. X    }
  247. X    }
  248. X
  249. X    if (no_curses == 0) {
  250. X    set_options (&cyls, &heads, §ors, &verify, &fmt_flag, &multi_copy);
  251. X    }
  252. X
  253. X    wait_for_return ("Insert source floppy and press RETURN: ");
  254. X
  255. X    if ((fd_floppy = open (FLOPPY, O_RDONLY)) == -1) {
  256. X    (void) printf ("Open of %s failed\n", FLOPPY);
  257. X    exit (1);
  258. X    }
  259. X
  260. X    sectors = set_sectors (fd_floppy, cyls, heads, sectors);
  261. X    blksize = (sectors * heads) * SECTOR;
  262. X    save_cyls = cyls;
  263. X    buf = NULL;
  264. X    while (cyls > 0) {
  265. X    bufsize = blksize * cyls;
  266. X    if ((buf = malloc (bufsize)) != NULL) {
  267. X        break;
  268. X    }
  269. X    --cyls;
  270. X    }
  271. X    if (buf == NULL) {
  272. X    (void) printf ("Error: unable to allocate buffer space\n");
  273. X    exit (1);
  274. X    }
  275. X    if (save_cyls != cyls) {
  276. X    (void) printf ("Disk geometry of %d heads", heads);
  277. X    (void) printf (" and %d sectors limits", sectors);
  278. X    (void) printf (" number of cylinders to %d.\n", cyls);
  279. X    }
  280. X
  281. X    cyls = read_source (fd_floppy, cyls, heads, sectors, buf);
  282. X    (void) close (fd_floppy);
  283. X
  284. X    re_format = 0;
  285. X    do {
  286. X    wait_for_return ("Insert target floppy and press RETURN: ");
  287. X    if (fmt_flag || re_format) {
  288. X        format_disk (cyls, heads, sectors, iv_verbose);
  289. X        re_format = 0;
  290. X    }
  291. X    rc = write_target (cyls, heads, sectors, buf, verify);
  292. X    if (rc) {
  293. X        re_format = yes_or_no ("Do you want to reformat and try again");
  294. X        if (re_format) {
  295. X        continue;
  296. X        }
  297. X    }
  298. X    if (rc || multi_copy) {
  299. X        multi_copy = yes_or_no ("Make another copy");
  300. X    }
  301. X    } while (re_format || multi_copy);
  302. X
  303. X    return (0);
  304. X
  305. X}
  306. X
  307. Xint
  308. Xinit_floppy (int fd, int ncyl, int nheads, int nsect)
  309. X{
  310. X
  311. X    static struct gdctl gdbuf;
  312. X
  313. X    if (ioctl (fd, GDGETA, &gdbuf) == -1) {
  314. X    ioctl (fd, GDDISMNT, &gdbuf);
  315. X    return (1);
  316. X    }
  317. X
  318. X    gdbuf.params.cyls = ncyl;
  319. X    gdbuf.params.heads = nheads;
  320. X    gdbuf.params.psectrk = nsect;
  321. X    gdbuf.params.pseccyl = gdbuf.params.psectrk * gdbuf.params.heads;
  322. X    gdbuf.params.flags = 1;    /* disk type flag */
  323. X    gdbuf.params.step = 0;    /* step rate for contoller */
  324. X    gdbuf.params.sectorsz = SECTOR;    /* sector size */
  325. X
  326. X    if (ioctl (fd, GDSETA, &gdbuf) < 0) {
  327. X    ioctl (fd, GDDISMNT, &gdbuf);
  328. X    return (2);
  329. X    }
  330. X
  331. X    return (0);
  332. X}
  333. X
  334. Xvoid
  335. Xwait_for_return (char *msg)
  336. X{
  337. X    static char     testbuf[2];
  338. X    int             ch;
  339. X
  340. X    (void) printf ("%s", msg);
  341. X    (void) fflush (stdout);
  342. X    while (1) {
  343. X    if (read (0, testbuf, 1) != 1) {
  344. X        (void) printf ("\nError on input.\n");
  345. X        exit (1);
  346. X    }
  347. X    ch = testbuf[0] & 0x7f;
  348. X    if ((ch == '\r') || (ch == '\n')) {
  349. X        break;
  350. X    }
  351. X    }
  352. X
  353. X}
  354. X
  355. Xint
  356. Xset_sectors (int fd, int cyls, int hds, int sect)
  357. X{
  358. X    int             rc;
  359. X    long            lpos;
  360. X    static char     testbuf[SECTOR];
  361. X
  362. X    for (; sect > 0; --sect) {
  363. X    if ((rc = init_floppy (fd, cyls, hds, sect)) != 0) {
  364. X        (void) printf ("init_floppy returned %d\n", rc);
  365. X        exit (1);
  366. X    }
  367. X    lpos = (sect - 1) * SECTOR;
  368. X    if (lseek (fd, lpos, 0) == -1) {
  369. X        perror ("fdcopy");
  370. X        (void) fprintf (stderr,
  371. X                "Unable to seek to beginning of sector %d\n",
  372. X                sect);
  373. X        exit (1);
  374. X    }
  375. X    if (read (fd, testbuf, SECTOR) == SECTOR) {
  376. X        if (lseek (fd, 0L, 0) == -1) {
  377. X        perror ("fdcopy");
  378. X        (void) fprintf (stderr,
  379. X                "Unable to seek to location zero on disk\n");
  380. X        exit (1);
  381. X        }
  382. X        break;
  383. X    }
  384. X    }
  385. X
  386. X    if (sect < 1) {
  387. X    (void) fprintf (stderr,
  388. X            "Unable to determine number of sectors per track\n");
  389. X    exit (1);
  390. X    }
  391. X    (void) printf ("Floppy is formatted with %d sectors per track\n",
  392. X           sect);
  393. X
  394. X    return (sect);
  395. X
  396. X}
  397. X
  398. Xint
  399. Xread_source (int fd, int cyls, int hds, int sect, char *buf)
  400. X{
  401. X    char           *bufp;
  402. X    int             cylno;
  403. X    long            lpos;
  404. X    int             rc;
  405. X    int             save_errno;
  406. X    int             blksize;
  407. X    static char     testbuf[SECTOR];
  408. X    struct fdrq    *command;
  409. X
  410. X    save_errno = rc = 0;
  411. X    bufp = buf;
  412. X    blksize = (sect * hds) * SECTOR;
  413. X
  414. X    (void) printf ("Reading source disk: %d cylinders, %d heads, %d sectors\n",
  415. X           cyls, hds, sect);
  416. X
  417. X    for (cylno = 0; cylno < cyls; ++cylno) {
  418. X    (void) printf ("%3d\r", cylno);
  419. X    (void) fflush (stdout);
  420. X    lpos = cylno * blksize;
  421. X    if (lseek (fd, lpos, 0) == -1) {
  422. X        save_errno = errno;
  423. X        (void) printf ("Unable to seek to location %ld\n", lpos);
  424. X        break;
  425. X    }
  426. X    rc = read (fd, testbuf, SECTOR);
  427. X    if (rc != SECTOR) {
  428. X        save_errno = errno;
  429. X        (void) printf ("Error reading block at cylinder %d, rc=%d\n",
  430. X               cylno, rc);
  431. X        break;
  432. X    }
  433. X    (void) memset (testbuf, 0x11, SECTOR);
  434. X    command = (struct fdrq *) testbuf;
  435. X    command -> cmd = F_READADR;
  436. X    command -> cyl = cylno;
  437. X    command -> sec = 2;
  438. X    command -> count = 6;
  439. X    rc = ioctl (fd, GDCMD, testbuf);
  440. X    if (rc == -1) {
  441. X        (void) printf ("Error reading track address at cylinder %d\n",
  442. X               cylno);
  443. X        break;
  444. X    }
  445. X    if (command -> cyl != cylno) {
  446. X        (void) printf ("Disk has %d cylinders\n", cylno);
  447. X        break;
  448. X    }
  449. X    if (lseek (fd, lpos, 0) == -1) {
  450. X        save_errno = errno;
  451. X        (void) printf ("Unable to seek to location %ld\n", lpos);
  452. X        break;
  453. X    }
  454. X    if ((rc = read (fd, bufp, blksize)) != blksize) {
  455. X        save_errno = errno;
  456. X        (void) printf ("Error reading cylinder %d, blksize = %d, rc = %d\n",
  457. X               cylno, blksize, rc);
  458. X        break;
  459. X    }
  460. X    bufp += blksize;
  461. X    }
  462. X
  463. X    if (rc == -1) {
  464. X    errno = save_errno;
  465. X    perror ("fdcopy");
  466. X    exit (1);
  467. X    }
  468. X
  469. X    return (cylno);
  470. X
  471. X}
  472. X
  473. Xint
  474. Xwrite_target (int cyls, int hds, int sect, char *buf, int vflg)
  475. X{
  476. X    int             rc;
  477. X    int             cylno;
  478. X    long            lpos;
  479. X    char           *bufp;
  480. X    char           *vbuf;
  481. X    int             fd;
  482. X    int             blksize;
  483. X    int             save_errno;
  484. X
  485. X    if ((fd = open (FLOPPY, O_RDWR)) == -1) {
  486. X    (void) printf ("Open of %s failed\n", FLOPPY);
  487. X    return (1);
  488. X    }
  489. X
  490. X    if ((rc = init_floppy (fd, cyls, hds, sect)) != 0) {
  491. X    (void) printf ("init_floppy returned %d\n", rc);
  492. X    (void) close (fd);
  493. X    return (1);
  494. X    }
  495. X
  496. X    bufp = buf;
  497. X    save_errno = 0;
  498. X    blksize = (sect * hds) * SECTOR;
  499. X
  500. X    (void) printf ("Writing target disk: %d cylinders, %d heads, %d sectors\n",
  501. X           cyls, hds, sect);
  502. X
  503. X    for (cylno = 0; cylno < cyls; ++cylno) {
  504. X    (void) printf ("%3d\r", cylno);
  505. X    (void) fflush (stdout);
  506. X    lpos = cylno * blksize;
  507. X    if (lseek (fd, lpos, 0) == -1) {
  508. X        save_errno = errno;
  509. X        (void) printf ("Unable to seek to location %ld\n", lpos);
  510. X        break;
  511. X    }
  512. X    if ((rc = write (fd, bufp, blksize)) != blksize) {
  513. X        save_errno = errno;
  514. X        (void) printf ("Error writing cylinder %d, rc = %d\n", cylno, rc);
  515. X        break;
  516. X    }
  517. X    bufp += blksize;
  518. X    }
  519. X
  520. X    if (rc == -1) {
  521. X    errno = save_errno;
  522. X    perror ("fdcopy");
  523. X    (void) close (fd);
  524. X    return (1);
  525. X    }
  526. X
  527. X    if (vflg) {
  528. X    (void) printf ("Verifying duplicate\n");
  529. X    if ((vbuf = malloc (blksize)) == NULL) {
  530. X        perror ("fdcopy");
  531. X        (void) fprintf (stderr,
  532. X              "Unable to allocate dynamic buffer of %d bytes\n",
  533. X                blksize);
  534. X        exit (1);
  535. X    }
  536. X    bufp = buf;
  537. X    for (cylno = 0; cylno < cyls; ++cylno) {
  538. X        (void) printf ("%3d\r", cylno);
  539. X        (void) fflush (stdout);
  540. X        lpos = cylno * blksize;
  541. X        if (lseek (fd, lpos, 0) == -1) {
  542. X        save_errno = errno;
  543. X        (void) printf ("Unable to seek to location %ld\n", lpos);
  544. X        break;
  545. X        }
  546. X        if ((rc = read (fd, vbuf, blksize)) != blksize) {
  547. X        save_errno = errno;
  548. X        (void) printf ("Error reading cylinder %d, blksize=%d, rc=%d\n",
  549. X                   cylno, blksize, rc);
  550. X        break;
  551. X        }
  552. X        if ((rc = memcmp (vbuf, bufp, blksize)) != 0) {
  553. X        (void) printf ("Data compare error at cylinder %d, rc=%d\n",
  554. X                   cylno, rc);
  555. X        rc = -1;
  556. X        save_errno = EIO;
  557. X        break;
  558. X        }
  559. X        bufp += blksize;
  560. X    }
  561. X    if (rc == -1) {
  562. X        errno = save_errno;
  563. X        perror ("fdcopy");
  564. X        (void) close (fd);
  565. X        return (1);
  566. X    }
  567. X    (void) printf ("Floppy verified successfully.\n");
  568. X    (void) free (vbuf);
  569. X    }
  570. X
  571. X    (void) close (fd);
  572. X    return (0);
  573. X
  574. X}
  575. X
  576. Xvoid
  577. Xformat_disk (int cyls, int hds, int sect, int verbose)
  578. X{
  579. X    FILE           *fp_iv;
  580. X    static char     filename[32];
  581. X    static char     cmd_buff[128];
  582. X    char            vflag;
  583. X    int             rc;
  584. X
  585. X    (void) strcpy (filename, "/tmp/iv_XXXXXX");
  586. X    (void) mktemp (filename);
  587. X
  588. X    if ((fp_iv = fopen (filename, "w")) == NULL) {
  589. X    perror ("fdcopy");
  590. X    (void) fprintf (stderr, "Unable to format target disk\n");
  591. X    exit (1);
  592. X    }
  593. X
  594. X    (void) fprintf (fp_iv, "type FD\n");
  595. X    (void) fprintf (fp_iv, "name floppy\n");
  596. X    (void) fprintf (fp_iv, "cylinders %d\n", cyls);
  597. X    (void) fprintf (fp_iv, "heads %d\n", hds);
  598. X    (void) fprintf (fp_iv, "sectors %d\n", sect);
  599. X    (void) fprintf (fp_iv, "steprate 0\n");
  600. X    (void) fprintf (fp_iv, "$\n");
  601. X    if ((sect % 2) == 1) {
  602. X    (void) fprintf (fp_iv, "badblocktable 1\n");
  603. X    }
  604. X    (void) fprintf (fp_iv, "$\n");
  605. X    (void) fprintf (fp_iv, "$\n");
  606. X    (void) fprintf (fp_iv, "0\n");
  607. X    (void) fprintf (fp_iv, "1\n");
  608. X    (void) fprintf (fp_iv, "$\n");
  609. X    (void) fprintf (fp_iv, "$\n");
  610. X
  611. X    if (fclose (fp_iv) == -1) {
  612. X    perror ("fdcopy");
  613. X    (void) fprintf (stderr, "Unable to format target disk\n");
  614. X    exit (1);
  615. X    }
  616. X
  617. X    vflag = (verbose) ? 'v' : ' ';
  618. X
  619. X    (void) sprintf (cmd_buff, "iv -i%c %s %s", vflag, FLOPPY, filename);
  620. X
  621. X    (void) printf ("Formatting target floppy: ");
  622. X    (void) printf ("%d cylinders, %d heads, %d sectors\n",
  623. X           cyls, hds, sect);
  624. X    (void) printf ("+ %s\n", cmd_buff);
  625. X
  626. X    rc = system (cmd_buff);
  627. X    (void) printf ("Format done: exit status = %d\n", rc);
  628. X    (void) unlink (filename);
  629. X
  630. X}
  631. X
  632. Xvoid
  633. Xset_options (int *cyls, int *hds, int *sect, int *vflag, int *fmt, int *multi)
  634. X{
  635. X    int             line;
  636. X    int             pos;
  637. X    char            value[8];
  638. X    int             ch;
  639. X    int             quit_flag = 0;
  640. X
  641. X    (void) initscr ();
  642. X    (void) keypad (stdscr, TRUE);
  643. X    (void) noecho ();
  644. X    (void) cbreak ();
  645. X    (void) nonl ();
  646. X
  647. X    (void) clear ();
  648. X    (void) move (2, 23);
  649. X    (void) addstr ("UNIX-pc Floppy Duplication Program");
  650. X    (void) move (3, 24);
  651. X    (void) addstr ("Copyright 1991 David H. Brierley");
  652. X
  653. X    line = 6;
  654. X    pos = 0;
  655. X    value[pos] = '\0';
  656. X
  657. X    while (quit_flag == 0) {
  658. X    if (line < 6) {
  659. X        line = 11;
  660. X    }
  661. X    if (line > 11) {
  662. X        line = 6;
  663. X    }
  664. X    (void) move (6, 0);
  665. X    if (*cyls == DEFAULT_CYLS) {
  666. X        (void) printw ("*  ");
  667. X    }
  668. X    else {
  669. X        (void) printw ("%-3d", *cyls);
  670. X    }
  671. X    (void) printw ("\tcylinders (* == determine disk size dynamically)");
  672. X    (void) move (7, 0);
  673. X    (void) printw ("%-3d\theads", *hds);
  674. X    (void) move (8, 0);
  675. X    (void) printw ("%-3d\tsectors per track", *sect);
  676. X    (void) move (9, 0);
  677. X    (void) printw ("%-3s\tverify duplicate after copy",
  678. X               (*vflag) ? "yes" : "no");
  679. X    (void) move (10, 0);
  680. X    (void) printw ("%-3s\tformat target disk before making duplicate",
  681. X               (*fmt) ? "yes" : "no");
  682. X    (void) move (11, 0);
  683. X    (void) printw ("%-3s\tmake multiple copies", (*multi) ? "yes" : "no");
  684. X    (void) move (13, 0);
  685. X    (void) printw ("Use arrow keys to move up/down. Press ESC to quit");
  686. X    (void) move (line, pos);
  687. X    (void) refresh ();
  688. X    ch = getch ();
  689. X    switch (ch) {
  690. X    case KEY_UP:
  691. X        if (pos == 0) {
  692. X        line--;
  693. X        continue;
  694. X        }
  695. X        break;
  696. X    case RETURN:
  697. X    case ENTER:
  698. X        line++;
  699. X        pos = 0;
  700. X        continue;
  701. X    case KEY_DOWN:
  702. X        if (pos == 0) {
  703. X        line++;
  704. X        continue;
  705. X        }
  706. X        break;
  707. X    case ESCAPE:
  708. X        if (pos == 0) {
  709. X        quit_flag = 1;
  710. X        continue;
  711. X        }
  712. X        break;
  713. X    }
  714. X    if (isupper (ch)) {
  715. X        ch = tolower (ch);
  716. X    }
  717. X    if ((line == 6) && (ch == '*')) {
  718. X        *cyls = DEFAULT_CYLS;
  719. X        line++;
  720. X        continue;
  721. X    }
  722. X    if (line >= 9) {
  723. X        if ((ch == 'y') || (ch == 'n')) {
  724. X        if (ch == 'y') {
  725. X            ch = 1;
  726. X        }
  727. X        else {
  728. X            ch = 0;
  729. X        }
  730. X        switch (line) {
  731. X        case 9:
  732. X            *vflag = ch;
  733. X            break;
  734. X        case 10:
  735. X            *fmt = ch;
  736. X            break;
  737. X        case 11:
  738. X            *multi = ch;
  739. X            break;
  740. X        }
  741. X        ++line;
  742. X        }
  743. X        else {
  744. X        beep ();
  745. X        }
  746. X        continue;
  747. X    }
  748. X    if (!isdigit (ch)) {
  749. X        beep ();
  750. X        continue;
  751. X    }
  752. X    value[pos] = ch;
  753. X    pos++;
  754. X    value[pos] = '\0';
  755. X    ch = atoi (value);
  756. X    switch (line) {
  757. X    case 6:
  758. X        *cyls = ch;
  759. X        break;
  760. X    case 7:
  761. X        *hds = ch;
  762. X        break;
  763. X    case 8:
  764. X        *sect = ch;
  765. X        break;
  766. X    }
  767. X    }
  768. X
  769. X    (void) move (12, 0);
  770. X    (void) clrtoeol ();
  771. X    (void) move (12, 0);
  772. X    (void) refresh ();
  773. X    (void) endwin ();
  774. X
  775. X}
  776. X
  777. Xint
  778. Xyes_or_no (char *msg)
  779. X{
  780. X    static char     buffer[64];
  781. X
  782. X    (void) printf ("%s? (y/n) ", msg);
  783. X    (void) fflush (stdout);
  784. X    if (fgets (buffer, 64, stdin) == NULL) {
  785. X    return (0);
  786. X    }
  787. X
  788. X    switch (buffer[0]) {
  789. X    case 'y':
  790. X    case 'Y':
  791. X    return (1);
  792. X    case 'n':
  793. X    case 'N':
  794. X    return (0);
  795. X    }
  796. X
  797. X    return (yes_or_no (msg));
  798. X
  799. X}
  800. END_OF_FILE
  801. if test 15050 -ne `wc -c <'fdcopy.c'`; then
  802.     echo shar: \"'fdcopy.c'\" unpacked with wrong size!
  803. fi
  804. # end of 'fdcopy.c'
  805. fi
  806. if test -f 'makefile' -a "${1}" != "-c" ; then 
  807.   echo shar: Will not clobber existing file \"'makefile'\"
  808. else
  809. echo shar: Extracting \"'makefile'\" \(571 characters\)
  810. sed "s/^X//" >'makefile' <<'END_OF_FILE'
  811. X#
  812. X# Makefile for fdcopy program
  813. X#
  814. X# compile using gcc and link using ccc front end to take advantage of shlib.
  815. X#
  816. X# if you have problems using ccc, or if you don't have ccc, you can try
  817. X# using gcc with the -shlib option or just using straight gcc and ignoring
  818. X# the shared library.
  819. X#
  820. XCC        = gcc
  821. XCOPTS        = -Wall -fstrength-reduce -fpcc-struct-return
  822. XLD        = ccc
  823. XLDFLAGS        = 
  824. XGNULIB        = /usr/local/lib/gcc-gnulib
  825. X
  826. XDEF        =
  827. XDEBUG        = -g
  828. XOPTIMIZE    = -O
  829. XCFLAGS         = $(COPTS) $(DEF) $(DEBUG) $(OPTIMIZE)
  830. X
  831. Xfdcopy    :    fdcopy.o
  832. X        $(LD) $(LDFLAGS) fdcopy.o $(GNULIB) -lcurses
  833. X        mv a.out fdcopy
  834. END_OF_FILE
  835. if test 571 -ne `wc -c <'makefile'`; then
  836.     echo shar: \"'makefile'\" unpacked with wrong size!
  837. fi
  838. # end of 'makefile'
  839. fi
  840. echo shar: End of archive 1 \(of 1\).
  841. cp /dev/null ark1isdone
  842. MISSING=""
  843. for I in 1 ; do
  844.     if test ! -f ark${I}isdone ; then
  845.     MISSING="${MISSING} ${I}"
  846.     fi
  847. done
  848. if test "${MISSING}" = "" ; then
  849.     echo You have the archive.
  850.     rm -f ark[1-9]isdone
  851. else
  852.     echo You still need to unpack the following archives:
  853.     echo "        " ${MISSING}
  854. fi
  855. ##  End of shell archive.
  856. exit 0
  857. -- 
  858. David H. Brierley
  859. Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
  860. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
  861. %% Can I be excused, my brain is full. **
  862.