diff -r 8e03adc56a1d config.mk --- a/config.mk Sun Feb 10 12:24:10 2008 +0100 +++ b/config.mk Thu May 19 19:15:18 2011 +0100 @@ -12,8 +12,9 @@ LIBS = -L/usr/lib -lc # flags -CFLAGS = -static -Os -g -Wall -Werror ${INCS} -DVERSION=\"${VERSION}\" -LDFLAGS = -g ${LIBS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" +CFLAGS = -static -ansi -Os -g -Wall ${INCS} ${CPPFLAGS} +LDFLAGS = -g ${LIBS} # compiler and linker CC = cc diff -r 8e03adc56a1d sltar.c --- a/sltar.c Sun Feb 10 12:24:10 2008 +0100 +++ b/sltar.c Thu May 19 19:15:18 2011 +0100 @@ -10,14 +10,119 @@ #include enum Header { - MODE = 100, UID = 108, GID = 116, SIZE = 124, MTIME = 136, - TYPE = 156, LINK = 157, MAJ = 329, MIN = 337, END = 512 + NAME = 0, MODE = 100, UID = 108, GID = 116, SIZE = 124, MTIME = 136, + SUM = 148, TYPE = 156, LINK = 157, MAJ = 329, MIN = 337, END = 512 }; -int c() { - fputs("Creating tars does not work yet\n", stderr); + +static int append(const char *file); +static int cksum(unsigned char *b); +static int create(void); +static int xtract(char a); + +int +main(int argc, char *argv[]) { + char a; + + if(argc == 2 && strlen(argv[1]) == 1) + switch((a = argv[1][0])) { + case 'c': + return create(); + case 'x': + case 't': + return xtract(a); + } + + /* should not reach */ + fputs("sltar-" VERSION " - suckless tar\n" + "sltar [ctx]\n", stderr); return EXIT_FAILURE; } -int xt(char a) { + +int +append(const char *file) +{ + char buf[END]; + size_t n; + struct stat st; + FILE *fp; + + if(stat(file, &st) == -1) { + fprintf(stderr, "%s: cannot stat\n", file); + return EXIT_FAILURE; + } + memset(buf, 0, sizeof buf); + snprintf(&buf[NAME], 100, "%s", file); + snprintf(&buf[MODE], 8, "%07o", st.st_mode); + snprintf(&buf[UID], 8, "%07o", st.st_uid); + snprintf(&buf[GID], 8, "%07o", st.st_gid); + snprintf(&buf[SIZE], 12, "%011lo", st.st_size); + snprintf(&buf[MTIME], 12, "%011lo", st.st_mtime); + + if(S_ISREG(st.st_mode)) + buf[TYPE] = '0'; + /* no hard link check yet */ + else if(S_ISLNK(st.st_mode)) { + buf[TYPE] = '2'; + if(readlink(file, &buf[LINK], 100) == -1) { + fprintf(stderr, "%s: cannot readlink\n", file); + return EXIT_FAILURE; + } + } + else if(S_ISCHR(st.st_mode)) + buf[TYPE] = '3'; + else if(S_ISBLK(st.st_mode)) + buf[TYPE] = '4'; + else if(S_ISDIR(st.st_mode)) + buf[TYPE] = '5'; + else { + fprintf(stderr, "%s: unsupported file type\n", file); + return EXIT_FAILURE; + } + if(buf[TYPE] == '3' || buf[TYPE] == '4') { + snprintf(&buf[MAJ], 8, "%07o", major(st.st_rdev)); + snprintf(&buf[MIN], 8, "%07o", minor(st.st_rdev)); + } + snprintf(&buf[SUM], 8, "%06o", cksum((unsigned char *)buf)); + buf[SUM+7] = ' '; + + if(!(fp = fopen(file, "r"))) { + fprintf(stderr, "%s: cannot open\n", file); + return EXIT_FAILURE; + } + for(n = 1; n > 0; n = fread(buf, 1, sizeof buf, fp)) { + fwrite(buf, sizeof buf, 1, stdout); + memset(buf, 0, sizeof buf); + } + fclose(fp); + return EXIT_SUCCESS; +} + +int +cksum(unsigned char *b) +{ + int i, n = 0; + + for(i = 0; i < END; i++) + n += (i >= SUM && i < SUM + 8) ? ' ' : b[i]; + return n; +} + +int +create(void) { + char buf[BUFSIZ], *p; + int ret = EXIT_SUCCESS; + + while(fgets(buf, sizeof buf, stdin)) { + if((p = strchr(buf, '\n'))) + *p = '\0'; + if(append(buf) == EXIT_FAILURE) + ret = EXIT_FAILURE; + } + return ret; +} + +int +xtract(char a) { int l; char b[END],fname[101],lname[101]; FILE *f = NULL; @@ -80,20 +185,3 @@ fclose(f); return EXIT_SUCCESS; } - -int main(int argc, char *argv[]) { - char a = 0; - - if(argc == 2 && argv[1][0] != 0 && argv[1][1] == 0) - a = argv[1][0]; - switch(a) { - case 'c': - return c(); - case 'x': - case 't': - return xt(a); - default: - fputs("sltar-" VERSION " - suckless tar\nsltar [ctx]\n",stderr); - return EXIT_SUCCESS; - } -}