summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--cpio.c85
-rw-r--r--pax.c19
-rw-r--r--pax.h4
-rw-r--r--tar.c85
5 files changed, 197 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index c6bbc04..d2a9e54 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,12 @@
CFLAGS=-Wall -Wextra -Wpedantic
+all: pax cpio tar
+
pax: pax.o tar.o cpio.o
+tar cpio: pax
+ ln -sf pax $@
+
clean:
rm -f $$(cat .gitignore)
diff --git a/cpio.c b/cpio.c
index d8be243..5aaae0f 100644
--- a/cpio.c
+++ b/cpio.c
@@ -24,10 +24,12 @@
#define _XOPEN_SOURCE 700
#include <cpio.h>
+#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <unistd.h>
#include "pax.h"
@@ -112,3 +114,86 @@ int cpio_list(FILE *input, size_t firstlen, void *firstblock)
return 0;
}
+
+int cpio_main(int argc, char *argv[])
+{
+ setlocale(LC_ALL, "");
+ int c;
+
+ while ((c = getopt(argc, argv, "oip")) != -1) {
+ switch (c) {
+ case 'o':
+ // create
+ break;
+
+ case 'i':
+ // extract
+ break;
+
+ case 'p':
+ // copy?
+ break;
+
+ default:
+ return 1;
+ }
+
+ break;
+ }
+
+ for (size_t i = 2; argv[optind][i] != '\0'; i++) {
+ printf("checking %c\n", argv[optind][i]);
+ switch (argv[optind][i]) {
+ case 'a':
+ // reset atimes
+ break;
+
+ case 'B':
+ // blocksize 5120
+ break;
+
+ case 'd':
+ // create directories
+ break;
+
+ case 'c':
+ // read and write in character form for portability
+ break;
+
+ case 'r':
+ // interactively rename files
+ break;
+
+ case 't':
+ // list table of contents
+ break;
+
+ case 'u':
+ // copy unconditionally
+ break;
+
+ case 'v':
+ // verbose
+ break;
+
+ case 'l':
+ // link instead of copy, requires -p
+ break;
+
+ case 'm':
+ // reset mtime
+ break;
+
+ case 'f':
+ // ignore files in pattern
+ break;
+
+ default:
+ fprintf(stderr, "cpio: unknown option '%c'\n",
+ argv[optind][i]);
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/pax.c b/pax.c
index 5e3be94..4cbd0f2 100644
--- a/pax.c
+++ b/pax.c
@@ -25,6 +25,7 @@
#define _XOPEN_SOURCE 700
#include <cpio.h>
#include <errno.h>
+#include <libgen.h>
#include <locale.h>
#include <inttypes.h>
#include <stdio.h>
@@ -82,7 +83,7 @@ int pax_list(FILE *input)
return 1;
}
-int main(int argc, char *argv[])
+int pax_main(int argc, char *argv[])
{
unsigned int flags = 0;
//unsigned int blocksize = 0;
@@ -200,6 +201,8 @@ int main(int argc, char *argv[])
if (mode == PAX_LIST) {
return pax_list(stdin);
}
+
+ return 1;
}
void pax_list_file(struct stat *st, const char *name)
@@ -267,3 +270,17 @@ uintmax_t pax_atoi(size_t n, const char _s[static n], int base)
strncpy(s, _s, n);
return strtoumax(s, NULL, base);
}
+
+int main(int argc, char *argv[])
+{
+ char *base = basename(argv[0]);
+ if (!strcmp(base, "tar")) {
+ return tar_main(argc, argv);
+ }
+
+ if (!strcmp(base, "cpio")) {
+ return cpio_main(argc, argv);
+ }
+
+ return pax_main(argc, argv);
+}
diff --git a/pax.h b/pax.h
index 46ed1f9..3856ee4 100644
--- a/pax.h
+++ b/pax.h
@@ -23,6 +23,7 @@
*/
#include <stdint.h>
+#include <sys/stat.h>
#define TAR_HEADER_SIZE 512
@@ -70,4 +71,7 @@ int tar_list(FILE *input, size_t firstlen, void *firstblock);
void pax_list_file(struct stat *st, const char *filename);
uintmax_t pax_atoi(size_t n, const char s[static n], int base);
+int tar_main(int argc, char *argv[]);
+int cpio_main(int argc, char *argv[]);
+
extern const size_t cpio_header_size;
diff --git a/tar.c b/tar.c
index 201b455..44ee678 100644
--- a/tar.c
+++ b/tar.c
@@ -23,11 +23,13 @@
*/
#define _XOPEN_SOURCE 700
+#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <tar.h>
+#include <unistd.h>
#include "pax.h"
@@ -125,3 +127,86 @@ int tar_list(FILE *input, size_t firstlen, void *firstblock)
}
return 0;
}
+
+int tar_main(int argc, char *argv[])
+{
+ setlocale(LC_ALL, "");
+ int c;
+
+ while ((c = getopt(argc, argv, "")) != -1) {
+ return 1;
+ }
+
+ if (optind >= argc) {
+ fprintf(stderr, "tar: missing operands\n");
+ return 1;
+ }
+
+ char buf[512];
+
+ switch (argv[optind][0]) {
+ case 'r':
+ // append
+ break;
+
+ case 'x':
+ // extract
+ break;
+
+ case 't':
+ fread(buf, 1, sizeof(buf), stdin);
+ return tar_list(stdin, 512, buf);
+ break;
+
+ case 'u':
+ // update
+ break;
+
+ case 'c':
+ // create
+ break;
+
+ default:
+ fprintf(stderr, "tar: unknown function '%c'\n",
+ argv[optind][0]);
+ return 1;
+ }
+
+ for (size_t i = 1; argv[optind][i] != '\0'; i++) {
+ switch(argv[optind][i]) {
+ case 'v':
+ // verbose
+ break;
+
+ case 'w':
+ // wait for confirmation
+ break;
+
+ case 'f':
+ // file = next operand
+ break;
+
+ case 'b':
+ // blocking factor = next operand
+ break;
+
+ case 'l':
+ // report if links are unresolved
+ break;
+
+ case 'm':
+ // ignore mtimes
+ break;
+
+ case 'o':
+ // assign user and group to getuid() and getgid()
+ break;
+
+ default:
+ fprintf(stderr, "unknown key '%c'\n", argv[optind][i]);
+ return 1;
+ }
+ }
+
+ return 0;
+}