nightcracker 0 Newbie Poster

No error checking and other features, but a very basic .tar extracting snippet:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

struct tarheader { // for parsing the tar headers
	char name[100];
	char mode[8];
	char uid[8];
	char gid[8];
	char size[12];
	char mtime[12];
	char chksum[8];
	char typeflag;
	char linkname[100];
	char magic[8];
	char uname[32];
	char gname[32];
	char devmajor[8];
	char devminor[8];
	char prefix[155];
	char padding[12];
};


static void _mkdir(const char *dir, __mode_t mode) { // mkdir with parent tree
	char tmp[256];
	char *p = NULL;
	size_t len;

	snprintf(tmp, sizeof(tmp), "%s", dir);
	len = strlen(tmp);
	if (tmp[len - 1] == '/') tmp[len - 1] = 0;
	for (p = tmp + 1; *p; p++)
		if(*p == '/') {
			*p = 0;
			mkdir(tmp, mode);
			*p = '/';
		}
	mkdir(tmp, mode);
}

int unpack_tar(const char* tarname, const char* prefix) {
	struct tarheader header;
	char buf[512];
	long size;
	
	FILE* tar = fopen(tarname, "rb");
	FILE* output; // reuse same pointer for every file

	while (fread(&header, 1, 512, tar)!=0) {
		size = strtol(header.size, NULL, 8); // octal numbers, who doesn't love them?
		if (header.typeflag == '0') {
			char filename[FILENAME_MAX];
			strcpy(filename, prefix);
			strcat(filename, "/");
			strcat(filename, header.name);
			output = fopen(filename, "wb");
			printf("%s\n", filename);
			while (size > 512) {
				fread(&buf, 1, 512, tar);
				fwrite(&buf, 1, 512, output);
				size -= 512;
			}
			fread(&buf, 1, 512, tar);
			fwrite(&buf, 1, size, output); // don't write those pesky zeroes out
			fclose(output);
		} else if (header.typeflag == '5') {
			char foldername[FILENAME_MAX];
			strcpy(foldername, prefix);
			strcat(foldername, "/");
			strcat(foldername, header.name);
			_mkdir(foldername, (__mode_t) strtol(header.mode, NULL, 8));
			fseek(tar, size + (512 - size & 0x1ff), SEEK_CUR);
		} else {
			fseek(tar, size + (512 - size & 0x1ff), SEEK_CUR);
		}
	}
}

int main(int argc, char* argv[]) {
	unpack_tar("test.tar", ".");
	return 0;
}