Created
August 26, 2017 22:18
-
-
Save julian-klode/b36f02037bf8347dc1ddc6e548bdfb4e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "jkdiff.h" | |
struct tar_header { | |
char name[100]; | |
char mode[8]; | |
char uid[8]; | |
char gid[8]; | |
char size[12]; | |
char mtime[12]; | |
char checksum[8]; | |
char linkflag; | |
char linkname[100]; | |
/* Only valid on ustar and gnu. */ | |
char magic[8]; | |
char user[32]; | |
char group[32]; | |
char devmajor[8]; | |
char devminor[8]; | |
/* Only valid on ustar. */ | |
char prefix[155]; | |
}; | |
void skip(FILE *input, long size) | |
{ | |
char buf[32*1024]; | |
while (size > 0) { | |
long skip = 4096; | |
if (skip > size) | |
skip = size; | |
if (fread(buf, skip, 1, input) < 0) | |
perror("fread"); | |
size -= skip; | |
} | |
} | |
//#define setvbuf(...) (void)0 | |
typedef struct { | |
int bar[sizeof(struct tar_header) <= 512 ? 1 : -1]; | |
} foo; | |
int main(int argc, char *argv[]) | |
{ | |
union { | |
struct tar_header t; | |
char buf[512]; | |
} header; | |
char pathbuf[4096]; | |
FILE *input = fopen(argv[3], "rb"); | |
setvbuf(input, 0, _IONBF,0); | |
while (fread(&header, sizeof(header), 1, input)) { | |
char buf[13]; | |
buf[12] = 0; | |
memcpy(buf, header.t.size, sizeof(header.t.size)); | |
long long size = strtoll(buf, NULL, 8); | |
long long toskip = strtoll(buf, NULL, 8); | |
long long toskip512 = toskip; | |
while (toskip512 % 512 != 0) | |
toskip512++; | |
//printf("Found: %.100s with size %.12s %lld\n", header.t.name, header.t.size, strtoll(buf, NULL, 8)); | |
if (strlen(header.t.name) > 7 | |
&& memcmp(header.t.name + strlen(header.t.name) - 7, ".jkdiff", | |
7) == 0) { | |
header.t.name[strlen(header.t.name) - 7] = 0; | |
//fprintf(stderr, "%s\n", header.t.name); | |
#if 1 | |
sprintf(pathbuf, "%s/%s", argv[1], header.t.name); | |
FILE *old = fopen(pathbuf, "rb"); | |
if (old == NULL) | |
return perror(pathbuf), 1; | |
sprintf(pathbuf, "%s/%s", argv[2], header.t.name); | |
FILE *new = fopen(pathbuf, "wb"); | |
if (new == NULL) | |
return perror(pathbuf), 1; | |
#if 0 | |
int fd = limit_fd(fileno(input), size); | |
if (fd == -1) | |
return perror("limit input"), 1; | |
FILE *patch = fdopen(fd, "rb"); | |
if (patch == NULL) | |
return perror("limit input"), 1; | |
#else | |
FILE *patch = input; | |
#endif | |
if (jkpatch(patch, old, new) != 0) { | |
fprintf(stderr, "Error patching %s", header.t.name); | |
} | |
fclose(old); | |
fclose(new); | |
toskip512 -= toskip; | |
} | |
#endif | |
skip(input, toskip512); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment