sltar

a simple tar implementation
git clone git://git.suckless.org/sltar
Log | Files | Refs | LICENSE

commit b28e88a9158caca85042a9f49953c334e2343da4
parent 0c3b317cab86de9a9ac645d4155c7238956bfd0c
Author: gottox@rootkit.lan <unknown>
Date:   Wed, 19 Dec 2007 10:12:10 +0100

Seems to extract now properly; renaming tar to sltar
Diffstat:
Makefile | 6+++---
config.mk | 2+-
tar.c | 97+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
3 files changed, 62 insertions(+), 43 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,11 +1,11 @@ -# tar - a minimal implementation of tar +# sltar - a minimal implementation of tar # (c) 2007 Enno Boland include config.mk -SRC = tar.c +SRC = sltar.c OBJ = ${SRC:.c=.o} -TARGET = tar +TARGET = sltar all: options ${TARGET} diff --git a/config.mk b/config.mk @@ -1,4 +1,4 @@ -# tar version +# sltar version VERSION = 0.0 # Customize below to fit your system diff --git a/tar.c b/tar.c @@ -1,57 +1,76 @@ #include <stdlib.h> #include <unistd.h> #include <stdio.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> #define USAGE { puts("tar [xt]"); exit(EXIT_FAILURE); } -#define FORBLOCK(x,b) for(l = x; l > 0 && (n = read(0,(void *)(b),512)) > 0; l -= n) -/* POSIX tar Header Block, from POSIX 1003.1-1990 */ -struct Header -{ - /* Header: 512 Byte */ - char name[100]; /* 0-99 */ - char mode[8]; /* 100-107 */ - char uid[8]; /* 108-115 */ - char gid[8]; /* 116-123 */ - char size[12]; /* 124-135 */ - char mtime[12]; /* 136-147 */ - char chksum[8]; /* 148-155 */ - char typeflag; /* 156-156 */ - char linkname[100]; /* 157-256 */ - char magic[6]; /* 257-262 */ - char version[2]; /* 263-264 */ - char uname[32]; /* 265-296 */ - char gname[32]; /* 297-328 */ - char devmajor[8]; /* 329-336 */ - char devminor[8]; /* 337-344 */ - char prefix[155]; /* 345-499 */ - char padding[12]; /* 500-512 */ +enum Header { + MODE = 100, UID = 108, GID = 116, SIZE = 124, MTIME = 136, + TYPE = 156, LINK = 157, DEVMAJOR = 329, DEVMINOR = 337, + END = 512 }; int main(int argc, char *argv[]) { - int a, l, n; - char b[512]; - struct Header h; + int a, l; + char b[END],fname[101],lname[101]; + FILE *f; if((argc != 2 || (a = argv[1][0]) == '\0') || argv[1][1] != '\0' || (a != 't' && a != 'x')) USAGE; - while(1) { - FORBLOCK(sizeof(h),&h); - if(*h.name == '\0') - break; - else if(l != 0) { - fputs("Garbage!\n",stderr); - return EXIT_FAILURE; + lname[100] = fname[100] = '\0'; + for(l = 0, f = NULL; fread(b,END,1,stdin); l -= END) { + if(l <= 0) { + if(*b == '\0') + break; + memcpy(fname,b,100); + memcpy(lname,b+LINK,100); + switch(a) { + case 't': + puts(fname); + break; + case 'x': + if(f) { + fclose(f); + f = NULL; + } + unlink(b); + switch(b[TYPE]) { + case '0': /* file */ + if(!(f = fopen(b,"w"))) + perror(fname); + break; + case '1': /* hardlink */ + if(!link(lname,fname)) + perror(fname); + break; + case '2': /* symlink */ + if(!symlink(lname,fname)) + perror(fname); + break; + case '5': /* directory */ + if(mkdir(fname,(mode_t) strtoull(b+MODE,0,8))) + perror(fname); + break; + case '4': /* block device */ + case '3': /* char device */ + break; + case '6': /* fifo */ + break; + default: + fprintf(stderr,"%s: type `%c` is not supported",fname,b[TYPE]); + } + } + l = strtoull(b+SIZE,0,8)+END; } - if(a == 't') { - puts(h.name); - FORBLOCK(strtoull(h.size,0,8),b); - } - else { - FORBLOCK(strtoull(h.size,0,8),b) - puts("open, write, close, chmod, chown"); + else if(a == 'x' && f) { + } } + if(f) + fclose(f); return EXIT_SUCCESS; }