Skip to content

Instantly share code, notes, and snippets.

@julian-klode
Created August 26, 2017 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save julian-klode/b36f02037bf8347dc1ddc6e548bdfb4e to your computer and use it in GitHub Desktop.
Save julian-klode/b36f02037bf8347dc1ddc6e548bdfb4e to your computer and use it in GitHub Desktop.
#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