Sigrid Solveig Haflínudóttirfirst747746c4 years agoHistory
164 lines · 3.1 KB · C
RawDownload
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/wait.h>#include <libgen.h>#include <openssl/sha.h> #define nil NULL intmain(int argc, char **argv){	char *path, *e, *origexe, *s, exe[4096], *argv0, *in, *out, *dirout, dhh[SHA256_DIGEST_LENGTH*2+1];	uint8_t tmp[65536], dh[SHA256_DIGEST_LENGTH];	int d, f, i, argout;	SHA256_CTX shactx;	struct stat st;	ssize_t n;	pid_t pid; 	if((dirout = getenv("LLCACHE_DIR")) == nil){		fprintf(stderr, "LLCACHE_DIR not set\n");		goto err;	}	if((argv0 = basename(argv[0])) == nil){		fprintf(stderr, "argv[0] is not a proper path\n");		goto err;	} 	if((n = readlink("/proc/self/exe", exe, sizeof(exe))) >= (ssize_t)sizeof(exe)){exesmall:		fprintf(stderr, "exe buffer too small\n");		goto err;	}else if(n < 0){		perror("exe buffer");		goto err;	}	exe[n] = 0;	origexe = realpath(exe, nil); 	path = strdup(getenv("PATH"));	for(s = path; s != nil; s = e ? e + 1 : nil){		if((e = strchr(s, ':')) != nil)			*e = 0;		if((d = open(s, O_DIRECTORY|O_RDONLY)) < 0)			continue;		n = readlinkat(d, argv0, exe, sizeof(exe));		if(n >= (ssize_t)sizeof(exe))			goto exesmall;		if(n < 0){			if((n = fstatat(d, argv0, &st, 0)) == 0)				exe[0] = 0;		}		close(d);		if(n < 0 || strcmp(origexe, exe) == 0)			continue;		if(snprintf(exe, sizeof(exe), "%s/%s", s, argv0) >= (int)sizeof(exe))			goto exesmall;		if((s = realpath(exe, nil)) == nil || strcmp(origexe, s) == 0){			free(s);			continue;		} 		break;	}	if(s == nil){		fprintf(stderr, "%s: not found\n", argv0);		goto err;	} 	SHA256_Init(&shactx);	SHA256_Update(&shactx, s, strlen(s)+1); 	in = nil;	out = nil;	argout = -1;	for(i = 1; i < argc; i++){		if(argv[i][0] == '/'){			if(strcmp(argv[i-1], "-o") == 0){				out = argv[i];				argout = i;			}else{				in = argv[i];			}		}else{			SHA256_Update(&shactx, argv[i], strlen(argv[i])+1);		}	}	if(in == nil || out == nil)		goto run; 	if((f = open(in, O_RDONLY)) < 0){inerr:		perror("input");		goto err;	}	for(;;){		if((n = read(f, tmp, sizeof(tmp))) == 0)			break;		if(n < 0)			goto inerr;		SHA256_Update(&shactx, tmp, n);	}	close(f); 	SHA256_Final(dh, &shactx);	for(i = 0; i < (int)sizeof(dh); i++)		sprintf(&dhh[i*2], "%02x", dh[i]); 	pid = 0;copy:	if((d = open(dirout, O_DIRECTORY)) >= 0 && (f = openat(d, dhh, O_RDONLY)) >= 0 && fstat(f, &st) == 0){		close(d);		if((d = creat(out, st.st_mode)) < 0){			perror("creat");			goto err;		}		for(;;){			if((n = read(f, tmp, sizeof(tmp))) == 0)				break;			if(n < 0)				goto inerr;			if(write(d, tmp, n) != n){				perror("output");				goto err;			}		}		close(f);		close(d);		return 0;	} 	if(pid != 0){		fprintf(stderr, "endless loop?\n");		goto err;	} run:	if((pid = fork()) < 0){		perror("fork");		goto err;	}else if(pid == 0){		if(argout > 0){			snprintf((char*)tmp, sizeof(tmp), "%s/%s", dirout, dhh);			argv[argout] = (char*)tmp;		}		execvp(s, argv);		perror("exec");		goto err;	} 	if(waitpid(pid, &i, 0) < 0){		perror("waitpid");		goto err;	}	if(i == 0)		goto copy;err:	return 1;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t