home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / disk / Misc / dd / dd.c < prev    next >
C/C++ Source or Header  |  1992-06-29  |  5KB  |  254 lines

  1. /*
  2.  * dd.c - copies raw data from/to any DOS-mounted drive to/from a file
  3.  *
  4.  * Bruno Costa - 27 Nov 91 - 7 May 92
  5.  */
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9. #include <exec/errors.h>
  10. #include <devices/trackdisk.h>
  11. #include <dos/dos.h>
  12. #include <dos/filehandler.h>
  13. #include <dos/dosextens.h>
  14. #include <clib/exec_protos.h>
  15. #include <clib/dos_protos.h>
  16. #include <pragmas/exec_pragmas.h>
  17. #include <pragmas/dos_pragmas.h>
  18.  
  19. #include <string.h>
  20. #include <stdarg.h>
  21.  
  22. #include "getoption.h"
  23. #include "dossupport.h"
  24. #include "dev.h"
  25.  
  26. extern struct Library *DOSBase;
  27. extern struct Library *SysBase;
  28.  
  29. char version[] = "$VER: dd 1.1b (" __DATE__ ") by Bruno Costa [bruno@impa.br]\n";
  30.  
  31. typedef enum {
  32.   UNIT_BLOCKS,
  33.   UNIT_SECTORS,
  34.   UNIT_KBYTES,
  35.   UNIT_BYTES,
  36.   UNIT_MBYTES,    /* !!! */
  37.   UNIT_SIZEOF
  38. } unit;
  39.  
  40. char unitid[UNIT_SIZEOF] = {
  41.   'B', 's', 'k', 'b', 'M'
  42. };
  43.  
  44. int quiet = FALSE;
  45.  
  46.  
  47. /* This prevents Lattice ctrl-C processing... */
  48. int CXBRK (void)
  49. {
  50.   return (0);
  51. }
  52.  
  53.  
  54. void doserror (long err)
  55. {
  56.  PrintFault (err, "dd: ");
  57. }
  58.  
  59.  
  60. void usage (void)
  61. {
  62.  Printf ("\x1b[1mdd 1.1b\x1b[0m - \2511992 by Bruno Costa [bruno@brlncc.bitnet]\n");
  63.  Printf ("usage: dd [-q] [-c<count>] [-s<skip>] -i<dev>|-r<dev>|-w<dev> <file>\n"
  64.          "       -q = quiet operation\n"
  65.          "       -c = amount to be read\n"
  66.          "       -s = amount to be skipped before reading (relative to start of disk)\n"
  67.          "       -i = just print OS information on given device and exit\n"
  68.          "       -r = device to read data from\n"
  69.          "       -w = device to write data to\n"
  70.          "       -h = help (this message)\n"
  71.          "\n");
  72.  Printf ("where: <dev> is any AmigaDOS device (DF0:, DH0:, etc.)\n"
  73.          "       <file> is the name of the file the data will be written to/read from\n"
  74.          "       <count>,<skip> are integers followed by a unit specifier:\n"
  75.          "        B = blocks [default]; s = sectors; b = bytes; k = kbytes; M = megabytes\n"
  76.         );
  77.  exit (10);
  78. }
  79.  
  80.  
  81. void convert (long int *count, unit countunit)
  82. {
  83.  switch (countunit)
  84.  {
  85.    case UNIT_BLOCKS:
  86.      *count *= devblocksize ();
  87.      break;
  88.  
  89.    case UNIT_SECTORS:
  90.      *count *= devsectorsize ();
  91.      break;
  92.  
  93.    case UNIT_KBYTES:
  94.      *count = (*count) << 10;
  95.      break;
  96.  
  97.    case UNIT_MBYTES:
  98.      *count = (*count) << 20;
  99.      break;
  100.  
  101.    case UNIT_BYTES:
  102.    default:
  103.      break;
  104.  }
  105. }
  106.  
  107.  
  108. int getcount (char *data, long int *count, unit *countunit)
  109. {
  110.  unit i;
  111.  int n = StrToLong (data, count);
  112.  
  113.  if (n > 0)
  114.  {
  115.    for (i = 0; i < UNIT_SIZEOF; i++)
  116.      if (data[n] == unitid[i])
  117.      {
  118.        *countunit = i;
  119.        return TRUE;
  120.      }
  121.    *countunit = UNIT_BLOCKS;
  122.    return TRUE;
  123.  }
  124.  
  125.  return FALSE;
  126. }
  127.  
  128.  
  129. #define REQUIRES_2_0 "Sorry, you have to upgrade to Workbench 2.0 to run this program...\n"
  130.  
  131. void main (int argc, char *argv[])
  132. {
  133.  char data[100];
  134.  int c;
  135.  char *file = NULL;
  136.  int write = FALSE;
  137.  int info = TRUE;
  138.  long int count = -1;
  139.  unit countunit = UNIT_BYTES;
  140.  long int skip = 0;
  141.  unit skipunit = UNIT_BYTES;
  142.  char *dev = NULL;
  143.  struct IOExtTD *devreq;
  144.  
  145.  if (DOSBase->lib_Version < 36)
  146.  {
  147.    Write (Output (), REQUIRES_2_0, sizeof (REQUIRES_2_0));
  148.    exit (100);
  149.  }
  150.  
  151.  while (c = getoption (argc, argv, "csrwi", "qh", data))
  152.    if (c < 0)
  153.    {
  154.      Printf ("dd: unknown option %c\n", -c);
  155.      usage ();
  156.    }
  157.    else if (c == 1)
  158.    {
  159.      if (file)
  160.        usage ();
  161.      else
  162.        file = strdup (data);
  163.    }
  164.    else
  165.      switch (c)
  166.      {
  167.        case 'i':
  168.          if (dev)
  169.            usage ();
  170.          else
  171.            dev = strdup (data);
  172.          write = FALSE;
  173.          info = TRUE;
  174.          break;
  175.  
  176.        case 'r':
  177.          if (dev)
  178.            usage ();
  179.          else
  180.            dev = strdup (data);
  181.          write = FALSE;
  182.          info = FALSE;
  183.          break;
  184.  
  185.        case 'w':
  186.          if (dev)
  187.            usage ();
  188.          else
  189.            dev = strdup (data);
  190.          write = TRUE;
  191.          info = FALSE;
  192.          break;
  193.  
  194.        case 'c':
  195.          if (!getcount (data, &count, &countunit))
  196.            usage ();
  197.          break;
  198.  
  199.        case 's':
  200.          if (!getcount (data, &skip, &skipunit))
  201.            usage ();
  202.          break;
  203.  
  204.        case 'q':
  205.          quiet = TRUE;
  206.          break;
  207.  
  208.        case 'h':
  209.          usage ();
  210.          break;
  211.      }
  212.  
  213.  if (!dev  ||  (!info && !file))
  214.    usage ();
  215.  
  216.  devreq = opendev (dev, info);
  217.  if (devreq)
  218.  {
  219.    int err = -1;
  220.  
  221.    if (!info)
  222.    {
  223.      convert (&count, countunit);
  224.      convert (&skip, skipunit);
  225.  
  226.      if (write)
  227.      {
  228.        BPTR f = Open (file, MODE_OLDFILE);
  229.        if (f)
  230.        {
  231.          err = devwrite (f, devreq, skip, count);
  232.          Close (f);
  233.        }
  234.      }
  235.      else
  236.      {
  237.        BPTR f = Open (file, MODE_NEWFILE);
  238.        if (f)
  239.        {
  240.          err = devread (devreq, f, skip, count);
  241.          Close (f);
  242.        }
  243.      }
  244.    }
  245.    closedev (dev, devreq);
  246.  
  247.    if (err)
  248.    {
  249.      if (!deverror (err))
  250.        doserror (err);
  251.    }
  252.  }
  253. }
  254.