blob: 1033a57f74426c6faf0a70d9b553f223e90c2909 [file] [log] [blame]
/* $Id: /var/cvsroot/gentoo-src/portage/src/tbz2tool.c,v 1.3.2.1 2004/11/05 13:49:22 jstubbs Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
/*buffered reading/writing size*/
#define BUFLEN 262144
char *myname="tbz2tool";
struct stat *mystat=NULL;
void *mybuf;
FILE *datafile, *dbfile, *outfile, *infile;
unsigned char endbuf[8];
long seekto,insize;
int exists(const char *myfile) {
int result;
result=stat(myfile,mystat);
if (result==-1)
return 0;
return 1;
}
void writefile(FILE *src, FILE *dest) {
int count=1;
while (count) {
count=fread(mybuf, 1, BUFLEN, src);
fwrite(mybuf, 1, count, dest);
}
}
void writefileto(FILE *src, FILE *dest, int endpos) {
int pos=ftell(src);
int thiscount;
while (pos < endpos) {
/* thiscount=how much to read */
thiscount=endpos-pos;
if (thiscount>BUFLEN)
thiscount=BUFLEN;
thiscount=fread(mybuf, 1, thiscount , src);
/* thiscount=how much we actually did read */
if (thiscount==0)
/* eof -- shouldn't happen */
break;
/* update internal position counter */
pos+=thiscount;
fwrite(mybuf, 1, thiscount, dest);
}
}
int main(int argc, char **argv) {
if ((argc==2) && (!(strcmp(argv[1],"--help"))))
goto usage;
if (argc!=5) {
printf("%s: four arguments expected\n",myname);
goto error;
}
if (!(mystat=(struct stat *) malloc(sizeof(struct stat))))
goto memalloc;
if (!(mybuf=(void *) malloc(BUFLEN))) {
free(mystat);
goto memalloc;
}
/* JOIN MODE */
if (!(strcmp(argv[1],"join"))) {
/* check if datafile exists */
if (!(exists(argv[2]))) {
printf("%s: %s doesn't exist\n",myname,argv[2]);
free(mystat);
goto error;
}
/* check if dbfile exists */
if (!(exists(argv[3]))) {
printf("%s: %s doesn't exist\n",myname,argv[3]);
free(mystat);
goto error;
}
/* create end buffer for later use */
endbuf[0]=((mystat->st_size) & 0xff000000) >> 24;
endbuf[1]=((mystat->st_size) & 0x00ff0000) >> 16;
endbuf[2]=((mystat->st_size) & 0x0000ff00) >> 8;
endbuf[3]=(mystat->st_size) & 0x000000ff;
endbuf[4]='S';
endbuf[5]='T';
endbuf[6]='O';
endbuf[7]='P';
/* if outfile exists, unlink first (safer) */
if (exists(argv[4]))
unlink(argv[4]);
/* open datafile for reading */
if ((datafile=fopen(argv[2],"r"))==NULL) {
free(mybuf);
free(mystat);
printf("%s: Error opening %s\n",myname,argv[2]);
goto error;
}
/* open dbfile for reading */
if ((dbfile=fopen(argv[3],"r"))==NULL) {
fclose(datafile);
free(mybuf);
free(mystat);
printf("%s: Error opening %s\n",myname,argv[3]);
goto error;
}
/* open outfile for writing */
if ((outfile=fopen(argv[4],"a"))==NULL) {
fclose(dbfile);
fclose(datafile);
free(mybuf);
free(mystat);
printf("%s: Error opening %s\n",myname,argv[4]);
goto error;
}
writefile(datafile,outfile);
writefile(dbfile,outfile);
fwrite(endbuf,1,8,outfile);
fclose(outfile);
fclose(dbfile);
fclose(datafile);
free(mybuf);
free(mystat);
exit(0);
/* SPLIT MODE */
} else if (!(strcmp(argv[1],"split"))) {
/* check if infile exists */
if (!(exists(argv[2]))) {
printf("%s: %s doesn't exist\n",myname,argv[2]);
free(mystat);
goto error;
}
/* store infile size for later use */
insize=mystat->st_size;
/* if datafile exists, unlink first (safer) */
if (exists(argv[3]))
unlink(argv[3]);
/* if dbfile exists, unlink first (safer) */
if (exists(argv[4]))
unlink(argv[4]);
/* open infile for reading */
if ((infile=fopen(argv[2],"r"))==NULL) {
free(mybuf);
free(mystat);
printf("%s: Error opening %s\n",myname,argv[2]);
goto error;
}
/* read in end buffer */
fseek(infile,-8,SEEK_END);
fread(endbuf,1,8,infile);
/* quick end buffer read and verification */
if ( (endbuf[4]!='S') || (endbuf[5]!='T') || (endbuf[6]!='O') || (endbuf[7]!='P') ) {
fclose(infile);
free(mybuf);
free(mystat);
printf("%s: %s appears to be corrupt (end buffer invalid)\n",myname,argv[2]);
goto error;
}
seekto=0;
seekto=seekto+endbuf[0]*256*256*256;
seekto=seekto+endbuf[1]*256*256;
seekto=seekto+endbuf[2]*256;
seekto=seekto+endbuf[3];
/* open datafile for writing */
if ((datafile=fopen(argv[3],"a"))==NULL) {
fclose(infile);
free(mybuf);
free(mystat);
printf("%s: Error opening %s\n",myname,argv[3]);
goto error;
}
/* open dbfile for writing */
if ((dbfile=fopen(argv[4],"a"))==NULL) {
fclose(datafile);
fclose(infile);
free(mybuf);
free(mystat);
printf("%s: Error opening %s\n",myname,argv[4]);
goto error;
}
rewind(infile);
writefileto(infile,datafile,insize-(seekto+8));
fseek(infile,-(seekto+8),SEEK_END);
writefileto(infile,dbfile,insize-8);
fclose(infile);
fclose(dbfile);
fclose(datafile);
free(mybuf);
free(mystat);
exit(0);
} else {
free(mybuf);
free(mystat);
goto usage;
}
usage:
printf("Usage: %s join DATAFILE DBFILE OUTFILE (datafile + dbfile -> outfile)\n %s split INFILE DATAFILE DBFILE (infile -> datafile + dbfile)\n",myname,myname);
error:
exit(1);
memalloc:
printf("%s: memory allocation error\n",myname);
exit(2);
}