/* Maciej 'Yunta' Blomberg
	No warranty. It can destroy your data, and so on.
	
	usage:
	snuncancel file_for_uncancelation
*/

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>


int main(int argc,char* argv[]) 
{
	int header_start[10];
	int header_size[10];
	int body_start[10];
	int body_size[10];
	int boundary[20][3];
	int i;
	int count;
	char tmp1,tmp2;
	int fsize;
	char* data;
	int file=open(argv[1],O_RDWR);

	read(file,&i,4);
	

	for (i=0;i<20;i++) boundary[i][0]=boundary[i][1]=boundary[i][2]=0;
	
	for (i=0;i<10;i++) {
		read(file,&header_start[i],4);
		read(file,&header_size[i],4);
		read(file,&body_start[i],4);
		read(file,&body_size[i],4);
		fprintf(stderr,"Article #%d  %X %X %X %X\n",i,header_start[i],header_size[i],body_start[i],body_size[i]);
	};

	fprintf(stderr,"Zero's at:\n");
	count=0;
	while (read(file,&tmp1,1)==1 && count<40) {
		if (tmp1==0) {
			boundary[count/2][count%2]=lseek(file,0,SEEK_CUR)-1;
			fprintf(stderr,"%X ",boundary[count/2][count%2]);
			count++;
		};
	};
	fprintf(stderr,"\n");

	for (i=0;i<count;i+=2) {
		boundary[i/2][1]=boundary[i/2][1]-boundary[i/2][0]+1;
		fprintf(stderr,"Range %X:%X\n",boundary[i/2][0],boundary[i/2][1]);
	};

	for (i=0;i<10;i++) 
		if (header_start[i]!=0xFFFFFFFF && header_start[i]!=0) {
			int j;
			fprintf(stderr,"Article #%d - not canceled - marking ranges as used:\n",i);

			for (j=0;j<count;j+=2) 
				if (boundary[j/2][0]==header_start[i] && boundary[j/2][1]==header_size[i]) {
					boundary[j/2][2]=1;
					fprintf(stderr,"\t(header) %X:%X\n",header_start[i],header_size[i]);
				};

			for (j=0;j<count;j+=2) 
				if (boundary[j/2][0]==body_start[i] && boundary[j/2][1]==body_size[i]) {
					boundary[j/2][2]=1;
					fprintf(stderr,"\t(body)   %X:%X\n",body_start[i],body_size[i]);
				};
		};

	for (i=0;i<10;i++) {
		if (header_start[i]==0xFFFFFFFF) {
			int found=0;
			int header=0;
			int body=0;
			int j;
			fprintf(stderr,"Article #%d - canceled\n\theader at:\n",i);
			
			for (j=0;j<count;j+=2) 
				if (boundary[j/2][1]==header_size[i] && boundary[j/2][2]==0) {
					found++;
					header=j/2;
					fprintf(stderr,"\t\t%X:%X\n",boundary[header][0],boundary[header][1]);
				};
				
			if (found>1) {
				fprintf(stderr,"!!! 2 possibilities found, you have to uncancel this article manually\n");
				continue;
			};

			if (found==0) {
				fprintf(stderr,"!!! 0 possibilities found, you have to uncancel this article manually\n");
				continue;
			};
			
			found=0;
			fprintf(stderr,"\tbody at:\n",i);

			for (j=0;j<count;j+=2) 
				if (boundary[j/2][1]==body_size[i] && boundary[j/2][2]==0) {
					found++;
					body=j/2;
					fprintf(stderr,"\t\t%X:%X\n",boundary[body][0],boundary[body][1]);
				};
				
			if (found>1) {
				fprintf(stderr,"!!! 2 possibilities found, you have to uncancel this article manually\n");
				continue;
			};

			if (found==0) {
				fprintf(stderr,"!!! 0 possibilities found, you have to uncancel this article manually\n");
				continue;
			};
			
			fprintf(stderr,"\tOK, uncanceling.\n");
			lseek(file,4+i*16,SEEK_SET);
			write(file,&boundary[header][0],4);
			lseek(file,4+i*16+8,SEEK_SET);
			write(file,&boundary[body][0],4);
		};
	};

	close(file);
	return 0;
}

