micro-utils/src/coreutils/cmp/cmp.c

123 lines
1.8 KiB
C
Raw Normal View History

2023-11-05 15:31:17 +00:00
#include <stdio.h>
#include <errno.h>
#include <string.h>
2023-11-07 14:06:27 +00:00
#include <unistd.h>
2023-11-05 15:31:17 +00:00
#include <stdlib.h>
2024-03-03 13:34:11 +00:00
char s_flag;
2023-11-05 15:31:17 +00:00
int compare(FILE *fp1, FILE *fp2) {
if (fp1 == fp2)
return 0;
int ch1;
int ch2;
size_t byte = 0;
do {
ch1 = getc(fp1);
ch2 = getc(fp2);
if (ch1 != ch2) {
if (!s_flag)
2023-12-21 18:59:54 +00:00
printf("files differ at byte %zu\n", byte);
2023-11-05 15:31:17 +00:00
return 1;
}
byte++;
} while(ch1 != EOF);
return 0;
}
long parse_int(const char *str) {
char *ptr;
long val = strtol(str, &ptr, 0);
if (*ptr || val < 0) {
fprintf(stderr, "cmp: invalid offset: %s\n", str);
exit(1);
}
return val;
}
FILE *file_open(const char *path) {
if (!strcmp(path, "-"))
return stdin;
FILE *fp = fopen(path, "r");
if (fp == NULL) {
fprintf(stderr, "cmp: %s\n", strerror(errno));
exit(1);
}
return fp;
}
2023-11-07 14:06:27 +00:00
int main(int argc, char **argv) {
2024-03-03 13:34:11 +00:00
2023-11-07 14:06:27 +00:00
int opt;
2024-03-03 13:34:11 +00:00
while ((opt = getopt(argc, argv, "s")) != -1) {
2023-11-07 14:06:27 +00:00
switch (opt) {
2023-11-12 08:31:14 +00:00
case 's':
2023-11-07 14:06:27 +00:00
s_flag = 1;
break;
default:
2024-03-03 13:34:11 +00:00
printf("cmp [s] [file1] [file2] [skip1] [skip2]\n\t-s Silent\n");
2023-11-07 14:06:27 +00:00
return 0;
2023-11-05 15:31:17 +00:00
}
}
2023-11-07 14:06:27 +00:00
argv += optind;
argc -= optind;
2023-11-05 15:31:17 +00:00
long skip1 = 0;
long skip2 = 0;
FILE *fp1 = NULL;
FILE *fp2 = stdin;
2023-11-07 14:06:27 +00:00
switch (argc) {
2023-11-05 15:31:17 +00:00
case 4:
2023-11-07 14:06:27 +00:00
skip2 = parse_int(argv[3]);
2023-11-05 18:42:26 +00:00
/* fallthrough */
2023-11-05 15:31:17 +00:00
case 3:
2023-11-07 14:06:27 +00:00
skip1 = parse_int(argv[2]);
2023-11-05 18:42:26 +00:00
/* fallthrough */
2023-11-05 15:31:17 +00:00
case 2:
2023-11-07 14:06:27 +00:00
fp2 = file_open(argv[1]);
2023-11-05 18:42:26 +00:00
/* fallthrough */
2023-11-05 15:31:17 +00:00
case 1:
2023-11-07 14:06:27 +00:00
fp1 = file_open(argv[0]);
2023-11-05 15:31:17 +00:00
break;
default:
2023-11-07 14:06:27 +00:00
fprintf(stderr, "cmp: missing operand\n");
2023-11-05 15:31:17 +00:00
return 1;
}
if (skip1 && fseek(fp1, skip1, SEEK_SET) < 0) {
if (!s_flag)
fprintf(stderr, "cmp: %s\n", strerror(errno));
return 1;
}
if (skip2 && fseek(fp2, skip2, SEEK_SET) < 0) {
if (!s_flag)
fprintf(stderr, "cmp: %s\n", strerror(errno));
return 1;
}
int ret = compare(fp1, fp2);
fclose(fp1);
fclose(fp2);
return ret;
}