aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bunzip.c2
-rw-r--r--lib/lib.c7
-rw-r--r--lib/lib.h2
-rw-r--r--toys/cksum.c33
4 files changed, 29 insertions, 15 deletions
diff --git a/lib/bunzip.c b/lib/bunzip.c
index 18984af4..f860aa64 100644
--- a/lib/bunzip.c
+++ b/lib/bunzip.c
@@ -609,7 +609,7 @@ int start_bunzip(struct bunzip_data **bdp, int src_fd, char *inbuf, int len)
bd->in_fd = src_fd;
}
- crc_init(bd->crc32Table);
+ crc_init(bd->crc32Table, 0);
// Ensure that file starts with "BZh".
for (i=0;i<3;i++)
diff --git a/lib/lib.c b/lib/lib.c
index f94d6fdf..89c8781b 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -721,15 +721,16 @@ void replace_tempfile(int fdin, int fdout, char **tempname)
// Create a 256 entry CRC32 lookup table.
-void crc_init(unsigned int *crc_table)
+void crc_init(unsigned int *crc_table, int little_endian)
{
unsigned int i;
// Init the CRC32 table (big endian)
for (i=0; i<256; i++) {
- unsigned int j, c = i<<24;
+ unsigned int j, c = little_endian ? i : i<<24;
for (j=8; j; j--)
- c=c&0x80000000 ? (c<<1)^0x04c11db7 : (c<<1);
+ if (little_endian) c = (c&1) ? (c>>1)^0xEDB88320 : c>>1;
+ else c=c&0x80000000 ? (c<<1)^0x04c11db7 : (c<<1);
crc_table[i] = c;
}
}
diff --git a/lib/lib.h b/lib/lib.h
index 2fcdaa4d..a473b546 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -96,7 +96,7 @@ void xsendfile(int in, int out);
int copy_tempfile(int fdin, char *name, char **tempname);
void delete_tempfile(int fdin, int fdout, char **tempname);
void replace_tempfile(int fdin, int fdout, char **tempname);
-void crc_init(unsigned int *crc_table);
+void crc_init(unsigned int *crc_table, int little_endian);
// getmountlist.c
struct mtab_list {
diff --git a/toys/cksum.c b/toys/cksum.c
index a54738cc..9b616671 100644
--- a/toys/cksum.c
+++ b/toys/cksum.c
@@ -6,18 +6,21 @@
*
* See http://www.opengroup.org/onlinepubs/009695399/utilities/cksum.html
-USE_CKSUM(NEWTOY(cksum, "F", TOYFLAG_BIN))
+USE_CKSUM(NEWTOY(cksum, "IPLN", TOYFLAG_BIN))
config CKSUM
bool "cksum"
default y
help
- usage: cksum [-F] [file...]
+ usage: cksum [-FL] [file...]
For each file, output crc32 checksum value, length and name of file.
If no files listed, copy from stdin. Filename "-" is a synonym for stdin.
- -F Start with 0xffffffff instead of 0.
+ -L Little endian (defaults to big endian)
+ -P Skip pre-inversion
+ -I Skip post-inversion
+ -N No length
*/
#include "toys.h"
@@ -28,16 +31,24 @@ DEFINE_GLOBALS(
#define TT this.cksum
-static unsigned cksum(unsigned crc, unsigned char c)
+static unsigned cksum_be(unsigned crc, unsigned char c)
{
return (crc<<8)^TT.crc_table[(crc>>24)^c];
}
+static unsigned cksum_le(unsigned crc, unsigned char c)
+{
+ return TT.crc_table[(crc^c)&0xff] ^ (crc>>8);
+}
+
static void do_cksum(int fd, char *name)
{
- unsigned crc = toys.optflags ? 0xffffffff : 0;
+ unsigned crc = (toys.optflags&4) ? 0 : 0xffffffff;
uint64_t llen = 0, llen2;
+ unsigned (*cksum)(unsigned crc, unsigned char c);
+
+ cksum = (toys.optflags&2) ? cksum_le : cksum_be;
// CRC the data
for (;;) {
@@ -57,18 +68,20 @@ static void do_cksum(int fd, char *name)
// CRC the length
llen2 = llen;
- while (llen) {
- crc = cksum(crc, llen);
- llen >>= 8;
+ if (!(toys.optflags&1)) {
+ while (llen) {
+ crc = cksum(crc, llen);
+ llen >>= 8;
+ }
}
- printf("%u %"PRIu64, ~crc, llen2);
+ printf("%u %"PRIu64, (toys.optflags&8) ? crc : ~crc, llen2);
if (strcmp("-", name)) printf(" %s", name);
xputc('\n');
}
void cksum_main(void)
{
- crc_init(TT.crc_table);
+ crc_init(TT.crc_table, toys.optflags&2);
loopfiles(toys.optargs, do_cksum);
}