aboutsummaryrefslogtreecommitdiffstats
path: root/src/sash/cmd_dd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sash/cmd_dd.c')
-rw-r--r--src/sash/cmd_dd.c372
1 files changed, 0 insertions, 372 deletions
diff --git a/src/sash/cmd_dd.c b/src/sash/cmd_dd.c
deleted file mode 100644
index 80338b6..0000000
--- a/src/sash/cmd_dd.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (c) 2014 by David I. Bell
- * Permission is granted to use, distribute, or modify this source,
- * provided that this copyright notice remains intact.
- *
- * The "dd" built-in command.
- */
-
-#include "sash.h"
-
-
-#define PAR_NONE 0
-#define PAR_IF 1
-#define PAR_OF 2
-#define PAR_BS 3
-#define PAR_COUNT 4
-#define PAR_SEEK 5
-#define PAR_SKIP 6
-
-
-typedef struct
-{
- const char * name;
- int value;
-} PARAM;
-
-
-static const PARAM params[] =
-{
- {"if", PAR_IF},
- {"of", PAR_OF},
- {"bs", PAR_BS},
- {"count", PAR_COUNT},
- {"seek", PAR_SEEK},
- {"skip", PAR_SKIP},
- {NULL, PAR_NONE}
-};
-
-
-static long getNum(const char * cp);
-
-
-int
-do_dd(int argc, const char ** argv)
-{
- const char * str;
- const PARAM * par;
- const char * inFile;
- const char * outFile;
- char * cp;
- int inFd;
- int outFd;
- int inCc;
- int outCc;
- int blockSize;
- long count;
- long seekVal;
- long skipVal;
- long inFull;
- long inPartial;
- long outFull;
- long outPartial;
- char * buf;
- char localBuf[BUF_SIZE];
- int r;
-
- inFile = NULL;
- outFile = NULL;
- seekVal = 0;
- skipVal = 0;
- blockSize = 512;
- count = -1;
- r = 0;
-
- while (--argc > 0)
- {
- str = *++argv;
- cp = strchr(str, '=');
-
- if (cp == NULL)
- {
- fprintf(stderr, "Bad dd argument\n");
-
- return 1;
- }
-
- *cp++ = '\0';
-
- for (par = params; par->name; par++)
- {
- if (strcmp(str, par->name) == 0)
- break;
- }
-
- switch (par->value)
- {
- case PAR_IF:
- if (inFile)
- {
- fprintf(stderr, "Multiple input files illegal\n");
-
- return 1;
- }
-
- inFile = cp;
- break;
-
- case PAR_OF:
- if (outFile)
- {
- fprintf(stderr, "Multiple output files illegal\n");
-
- return 1;
- }
-
- outFile = cp;
- break;
-
- case PAR_BS:
- blockSize = getNum(cp);
-
- if (blockSize <= 0)
- {
- fprintf(stderr, "Bad block size value\n");
-
- return 1;
- }
-
- break;
-
- case PAR_COUNT:
- count = getNum(cp);
-
- if (count < 0)
- {
- fprintf(stderr, "Bad count value\n");
-
- return 1;
- }
-
- break;
-
- case PAR_SEEK:
- seekVal = getNum(cp);
-
- if (seekVal < 0)
- {
- fprintf(stderr, "Bad seek value\n");
-
- return 1;
- }
-
- break;
-
- case PAR_SKIP:
- skipVal = getNum(cp);
-
- if (skipVal < 0)
- {
- fprintf(stderr, "Bad skip value\n");
-
- return 1;
- }
-
- break;
-
- default:
- fprintf(stderr, "Unknown dd parameter\n");
-
- return 1;
- }
- }
-
- if (inFile == NULL)
- {
- fprintf(stderr, "No input file specified\n");
-
- return 1;
- }
-
- if (outFile == NULL)
- {
- fprintf(stderr, "No output file specified\n");
-
- return 1;
- }
-
- buf = localBuf;
-
- if (blockSize > sizeof(localBuf))
- {
- buf = malloc(blockSize);
-
- if (buf == NULL)
- {
- fprintf(stderr, "Cannot allocate buffer\n");
-
- return 1;
- }
- }
-
- inFull = 0;
- inPartial = 0;
- outFull = 0;
- outPartial = 0;
-
- inFd = open(inFile, 0);
-
- if (inFd < 0)
- {
- perror(inFile);
-
- if (buf != localBuf)
- free(buf);
-
- return 1;
- }
-
- outFd = creat(outFile, 0666);
-
- if (outFd < 0)
- {
- perror(outFile);
- close(inFd);
-
- if (buf != localBuf)
- free(buf);
-
- return 1;
- }
-
- if (skipVal)
- {
- if (lseek(inFd, skipVal * blockSize, 0) < 0)
- {
- while (skipVal-- > 0)
- {
- inCc = read(inFd, buf, blockSize);
-
- if (inCc < 0)
- {
- perror(inFile);
- r = 1;
- goto cleanup;
- }
-
- if (inCc == 0)
- {
- fprintf(stderr, "End of file while skipping\n");
- r = 1;
- goto cleanup;
- }
- }
- }
- }
-
- if (seekVal)
- {
- if (lseek(outFd, seekVal * blockSize, 0) < 0)
- {
- perror(outFile);
- r = 1;
- goto cleanup;
- }
- }
-
- inCc = 0;
-
- while (((count < 0) || (inFull + inPartial < count)) &&
- (inCc = read(inFd, buf, blockSize)) > 0)
- {
- if (inCc < blockSize)
- inPartial++;
- else
- inFull++;
- cp = buf;
-
- if (intFlag)
- {
- fprintf(stderr, "Interrupted\n");
- r = 1;
- goto cleanup;
- }
-
- while (inCc > 0)
- {
- outCc = write(outFd, cp, inCc);
-
- if (outCc < 0)
- {
- perror(outFile);
- r = 1;
- goto cleanup;
- }
-
- if (outCc < blockSize)
- outPartial++;
- else
- outFull++;
- cp += outCc;
- inCc -= outCc;
- }
- }
-
- if (inCc < 0)
- perror(inFile);
-
-cleanup:
- close(inFd);
-
- if (close(outFd) < 0)
- {
- perror(outFile);
- r = 1;
- }
-
- if (buf != localBuf)
- free(buf);
-
- printf("%ld+%ld records in\n", inFull, inPartial);
-
- printf("%ld+%ld records out\n", outFull, outPartial);
-
- return r;
-}
-
-
-/*
- * Read a number with a possible multiplier.
- * Returns -1 if the number format is illegal.
- */
-static long
-getNum(const char * cp)
-{
- long value;
-
- if (!isDecimal(*cp))
- return -1;
-
- value = 0;
-
- while (isDecimal(*cp))
- value = value * 10 + *cp++ - '0';
-
- switch (*cp++)
- {
- case 'k':
- value *= 1024;
- break;
-
- case 'b':
- value *= 512;
- break;
-
- case 'w':
- value *= 2;
- break;
-
- case '\0':
- return value;
-
- default:
- return -1;
- }
-
- if (*cp)
- return -1;
-
- return value;
-}
-
-/* END CODE */