home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 3
/
Meeting_Pearls_III.iso
/
Pearls
/
disk
/
Misc
/
dd
/
dd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-29
|
5KB
|
254 lines
/*
* dd.c - copies raw data from/to any DOS-mounted drive to/from a file
*
* Bruno Costa - 27 Nov 91 - 7 May 92
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/errors.h>
#include <devices/trackdisk.h>
#include <dos/dos.h>
#include <dos/filehandler.h>
#include <dos/dosextens.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <string.h>
#include <stdarg.h>
#include "getoption.h"
#include "dossupport.h"
#include "dev.h"
extern struct Library *DOSBase;
extern struct Library *SysBase;
char version[] = "$VER: dd 1.1b (" __DATE__ ") by Bruno Costa [bruno@impa.br]\n";
typedef enum {
UNIT_BLOCKS,
UNIT_SECTORS,
UNIT_KBYTES,
UNIT_BYTES,
UNIT_MBYTES, /* !!! */
UNIT_SIZEOF
} unit;
char unitid[UNIT_SIZEOF] = {
'B', 's', 'k', 'b', 'M'
};
int quiet = FALSE;
/* This prevents Lattice ctrl-C processing... */
int CXBRK (void)
{
return (0);
}
void doserror (long err)
{
PrintFault (err, "dd: ");
}
void usage (void)
{
Printf ("\x1b[1mdd 1.1b\x1b[0m - \2511992 by Bruno Costa [bruno@brlncc.bitnet]\n");
Printf ("usage: dd [-q] [-c<count>] [-s<skip>] -i<dev>|-r<dev>|-w<dev> <file>\n"
" -q = quiet operation\n"
" -c = amount to be read\n"
" -s = amount to be skipped before reading (relative to start of disk)\n"
" -i = just print OS information on given device and exit\n"
" -r = device to read data from\n"
" -w = device to write data to\n"
" -h = help (this message)\n"
"\n");
Printf ("where: <dev> is any AmigaDOS device (DF0:, DH0:, etc.)\n"
" <file> is the name of the file the data will be written to/read from\n"
" <count>,<skip> are integers followed by a unit specifier:\n"
" B = blocks [default]; s = sectors; b = bytes; k = kbytes; M = megabytes\n"
);
exit (10);
}
void convert (long int *count, unit countunit)
{
switch (countunit)
{
case UNIT_BLOCKS:
*count *= devblocksize ();
break;
case UNIT_SECTORS:
*count *= devsectorsize ();
break;
case UNIT_KBYTES:
*count = (*count) << 10;
break;
case UNIT_MBYTES:
*count = (*count) << 20;
break;
case UNIT_BYTES:
default:
break;
}
}
int getcount (char *data, long int *count, unit *countunit)
{
unit i;
int n = StrToLong (data, count);
if (n > 0)
{
for (i = 0; i < UNIT_SIZEOF; i++)
if (data[n] == unitid[i])
{
*countunit = i;
return TRUE;
}
*countunit = UNIT_BLOCKS;
return TRUE;
}
return FALSE;
}
#define REQUIRES_2_0 "Sorry, you have to upgrade to Workbench 2.0 to run this program...\n"
void main (int argc, char *argv[])
{
char data[100];
int c;
char *file = NULL;
int write = FALSE;
int info = TRUE;
long int count = -1;
unit countunit = UNIT_BYTES;
long int skip = 0;
unit skipunit = UNIT_BYTES;
char *dev = NULL;
struct IOExtTD *devreq;
if (DOSBase->lib_Version < 36)
{
Write (Output (), REQUIRES_2_0, sizeof (REQUIRES_2_0));
exit (100);
}
while (c = getoption (argc, argv, "csrwi", "qh", data))
if (c < 0)
{
Printf ("dd: unknown option %c\n", -c);
usage ();
}
else if (c == 1)
{
if (file)
usage ();
else
file = strdup (data);
}
else
switch (c)
{
case 'i':
if (dev)
usage ();
else
dev = strdup (data);
write = FALSE;
info = TRUE;
break;
case 'r':
if (dev)
usage ();
else
dev = strdup (data);
write = FALSE;
info = FALSE;
break;
case 'w':
if (dev)
usage ();
else
dev = strdup (data);
write = TRUE;
info = FALSE;
break;
case 'c':
if (!getcount (data, &count, &countunit))
usage ();
break;
case 's':
if (!getcount (data, &skip, &skipunit))
usage ();
break;
case 'q':
quiet = TRUE;
break;
case 'h':
usage ();
break;
}
if (!dev || (!info && !file))
usage ();
devreq = opendev (dev, info);
if (devreq)
{
int err = -1;
if (!info)
{
convert (&count, countunit);
convert (&skip, skipunit);
if (write)
{
BPTR f = Open (file, MODE_OLDFILE);
if (f)
{
err = devwrite (f, devreq, skip, count);
Close (f);
}
}
else
{
BPTR f = Open (file, MODE_NEWFILE);
if (f)
{
err = devread (devreq, f, skip, count);
Close (f);
}
}
}
closedev (dev, devreq);
if (err)
{
if (!deverror (err))
doserror (err);
}
}
}