aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-11-26 02:48:55 -0500
committerB. Watson <urchlay@slackware.uk>2025-11-26 02:48:55 -0500
commitbfb8916059a8eed4d0d1318ca3e5d3048067014b (patch)
treebfef07a9ea1a2cb2ddda85d9c54740ace078b58e
parentea892c661a48c27ba5f3e8223f840631c9bb8e48 (diff)
downloadunalf-bfb8916059a8eed4d0d1318ca3e5d3048067014b.tar.gz
Implement append, overwrite options for alf. Also -h/--help.
-rw-r--r--src/alf.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/src/alf.c b/src/alf.c
index 8a230a2..0dd8d88 100644
--- a/src/alf.c
+++ b/src/alf.c
@@ -8,6 +8,10 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <unistd.h>
+#include <limits.h>
+
+#define self "unalf"
#ifndef u8
#define u8 unsigned char
@@ -28,6 +32,9 @@ u8 output_buf[MAX_INPUT_SIZE];
u8 byte_tokens[256];
int input_len, output_len, out_bitpos;
+int opt_append = 0;
+int opt_overwrite = 0;
+
typedef struct s_token {
u8 *start;
u16 length;
@@ -185,15 +192,15 @@ int match_token(int pos) {
void make_token(int start, int end) {
if(curr_token == max_token) {
- printf("%d: curr_token %d == max_token, ", in_pos, curr_token);
+ // printf("%d: curr_token %d == max_token, ", in_pos, curr_token);
if(token_bits == MAX_BITS) {
- printf("token_bits %d == MAX_BITS, reset\n", token_bits);
+ // printf("token_bits %d == MAX_BITS, reset\n", token_bits);
store_token(TOK_RESET); /* stored at the *old* token size! */
token_bits = 9;
init_table();
return;
} else {
- printf("token_bits %d < MAX_BITS, inc\n", token_bits);
+ // printf("token_bits %d < MAX_BITS, inc\n", token_bits);
token_bits++;
}
max_token = 1 << token_bits;
@@ -242,26 +249,65 @@ void crunch_file(const char *filename) {
create_header();
+ /* crunches the entire input to memory! */
crunch();
+
fwrite(output_buf, 1, output_len, out_file);
}
+void make_backup(void) {
+ char bak[PATH_MAX + 2];
+ strncpy(bak, out_filename, PATH_MAX);
+ strcat(bak, "~");
+ rename(out_filename, bak);
+}
+
int main(int argc, char **argv) {
- if(argc < 3) {
- fprintf(stderr, "usage: alf archive.alf file [file ...]\n");
+ int opt;
+
+ if(argc < 2 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
+ fprintf(stderr, "Usage: %s [-a|-o] archive.alf file [file ...]\n", self);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -a: append to archive\n");
+ fprintf(stderr, " -o: overwrite archive (don't make backup with ~)\n");
exit(1);
}
- argv++;
- out_file = fopen(*argv, "wb");
+ while((opt = getopt(argc, argv, "ao")) != -1) {
+ switch(opt) {
+ case 'a': opt_append = 1; opt_overwrite = 1; break;
+ case 'o': opt_overwrite = 1; opt_append = 0; break;
+ default:
+ fprintf(stderr, "%s: fatal: invalid option '-%c' (try -h or --help)\n", self, optopt);
+ exit(1);
+ }
+ }
+
+ if(optind >= argc) {
+ fprintf(stderr, "%s: fatal: missing alf file argument (try -h or --help)\n", self);
+ exit(1);
+ }
+
+ out_filename = argv[optind];
+
+ optind++;
+
+ if(optind >= argc) {
+ fprintf(stderr, "%s: fatal: no filenames (nothing to compress) (try -h or --help)\n", self);
+ exit(1);
+ }
+
+ if(!opt_overwrite) make_backup();
+
+ out_file = fopen(out_filename, opt_append ? "ab" : "wb");
if(!out_file) {
perror(*argv);
exit(1);
}
- argv++;
- while(*argv)
- crunch_file(*argv++);
+ while(optind < argc) {
+ crunch_file(argv[optind++]);
+ }
fclose(out_file);