Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented cksum #40

Merged
merged 20 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ src/rm/rm
src/rmdir/rmdir
src/sh/sh
src/sleep/sleep
src/cksum/cksum

bin/

Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ BINS += mv
BINS += chmod
BINS += sh
BINS += sleep
BINS += cksum

BINARIES := $(foreach b, $(BINS), src/$b/$b)
BINS-COPY := $(foreach b, $(BINS), bin/$b)
Expand Down
5 changes: 5 additions & 0 deletions src/cksum/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
OUT := cksum

SRC := cksum.c

include ../shared.mk
1 change: 1 addition & 0 deletions src/cksum/cksum.1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
\" TODO
149 changes: 149 additions & 0 deletions src/cksum/cksum.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME "cksum (canoutils)"
#define VERSION "0.0.1"
#define AUTHOR "cospplredman"

#include "cgetopt.h"
#include "version_info.h"

static const char usage[] = {"Usage: cksum [Option]... [File]...\n"
" --version version information\n"
" --help display this help and exit\n"
" --raw output raw crc\n"
" --tag default output style\n"};

// flags
static int output_format = 't';

static struct option long_options[] = {
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{"raw", no_argument, NULL, 'r'},
{"tag", no_argument, NULL, 't'},
};

static const uint32_t crc32_ = 0x04c11db7;

static uint32_t crc32(FILE *file, size_t *octets) {
uint32_t remainder = 0;
uint8_t difference = 0;

size_t length = 0;

/* calculate crc of file contents */
int cur_char;
while ((cur_char = getc(file)) != EOF) {
remainder = (remainder << 8) ^ (difference & 0xff) ^ cur_char;
difference = 0;
for (int i = 31; i > 23; i--) {
if (remainder & (1 << i)) {
remainder ^= (1 << i) | (crc32_ >> (32 - i));
difference ^= crc32_ << (i - 24);
}
}
length++;
}

*octets = length;

/* calculate crc of file contents + length of files in bytes */
while (length) {
cur_char = (length & 0xff);
length >>= 8;

remainder = (remainder << 8) ^ (difference & 0xff) ^ cur_char;
difference = 0;
for (int i = 31; i > 23; i--) {
if (remainder & (1 << i)) {
remainder ^= (1 << i) | (crc32_ >> (32 - i));
difference ^= crc32_ << (i - 24);
}
}
}

/* work through the remaining 3 bytes */
for (int j = 0; j < 3; j++) {
remainder = (remainder << 8) ^ (difference & 0xff);
difference = 0;
for (int i = 31; i > 23; i--) {
if (remainder & (1 << i)) {
remainder ^= (1 << i) | (crc32_ >> (32 - i));
difference ^= crc32_ << (i - 24);
}
}
}

return ~((remainder << 8) | (difference & 0xff));
}

static void crc_print(char *filename, uint32_t crc, size_t octets) {
switch (output_format) {
case 't':
if (filename == NULL)
printf("%u %lu\n", crc, octets);
else
printf("%u %lu %s\n", crc, octets, filename);
break;
case 'r':
printf("%c%c%c%c", (crc >> 24) & 255, (crc >> 16) & 255, (crc >> 8) & 255,
crc & 255);
break;
}
}

int main(int argc, char **argv) {

int opt, option_index;
while ((opt = getopt_long(argc, argv, "", long_options, &option_index)) !=
-1) {
switch (opt) {
case 0:
break;
case 'v':
proh14 marked this conversation as resolved.
Show resolved Hide resolved
print_version();
return EXIT_SUCCESS;
break;
case 'h':
printf("%s\n", usage);
return EXIT_SUCCESS;
case 'r':
output_format = 'r';
break;
case 't':
output_format = 't';
break;
}
}

argc -= optind;
argv += optind;

int index = 0;
size_t octets;
uint32_t crc;

if (argc < 1) {
crc = crc32(stdin, &octets);
crc_print(NULL, crc, octets);
return EXIT_SUCCESS;
}

for (; index < argc; index++) {
FILE *file = fopen(argv[index], "r+");

if (file == NULL) {
fprintf(stderr, "cksum: %s: %s\n", argv[index], strerror(errno));
continue;
}

crc = crc32(file, &octets);
crc_print(argv[index], crc, octets);

fclose(file);
}
}
1 change: 1 addition & 0 deletions utils.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ pwd
rm
rmdir
sleep
cksum