home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.uv.es
/
2014.11.ftp.uv.es.tar
/
ftp.uv.es
/
pub
/
unix
/
btoa5.2.tar.Z
/
btoa5.2.tar
/
btoa5.2
/
repair.c
< prev
Wrap
C/C++ Source or Header
|
1989-04-24
|
8KB
|
339 lines
/* repair.c */
/* Written by Stefan Parmark. */
#include <stdio.h>
#ifdef AMIGA
#include <stdlib.h>
#include <string.h>
#endif AMIGA
#include "btoa.h"
/* File names. */
BYTE *diagnosisname = "btoa.dia";
BYTE *repairname = "btoa.rep";
BYTE *repairedname = "btoa.rdy";
/* File headers. */
BYTE *diagnosisheader = "xdiagnosis\n";
BYTE *repairheader = "xrepair\n";
/* Produce diagnosis file from diagnoses records created by atob(). */
/* It contains the lines immediately before and after the error */
/* sequence. */
void producediagnosis(diagnosislist, infile)
register struct Diagnosis *diagnosislist;
register FILE *infile;
{
register FILE *diagnosisfile;
LONG startpos, endpos;
register LONG currentpos;
extern BYTE *diagnosisname, *diagnosisheader, buffer[BUFSIZE];
currentpos = ftell(infile);
if ((diagnosisfile = fopen_write(diagnosisname)) != NULL)
{
fprintf(stderr, "btoa: Diagnosis output to '%s'.\n", diagnosisname);
fputs(diagnosisheader, diagnosisfile);
do
{
/* Extract startpos & endpos from diagnosislist. */
outdiagnosislist(diagnosislist, &startpos, &endpos);
if (startpos != -1)
{
/* Print line before error. */
fseek(infile, startpos, 0);
fgets(buffer, BUFSIZE, infile);
fputs(buffer, diagnosisfile);
/* Print line after error. */
fseek(infile, endpos, 0);
fgets(buffer, BUFSIZE, infile);
fputs(buffer, diagnosisfile);
}
}
while (startpos != -1);
fputs(diagnosisheader, diagnosisfile);
fclose(diagnosisfile);
}
/* Move file pointer to where it was when we entered. */
fseek(infile, currentpos, 0);
}
/* Insert two file positions into diagnosislist. */
void intodiagnosislist(diagnosislist, startpos, endpos)
register struct Diagnosis *diagnosislist;
register LONG startpos, endpos;
{
register struct Diagnosis *diagnosisitem, *lastitem;
diagnosisitem = (struct Diagnosis *)malloc(sizeof(struct Diagnosis));
diagnosisitem->startpos = startpos;
diagnosisitem->endpos = endpos;
diagnosisitem->next = NULL;
if ((lastitem = diagnosislist->last) == NULL) /* List is empty */
diagnosislist->next = diagnosislist->last = diagnosisitem;
else
{
if (lastitem->endpos >= startpos)
{
lastitem->endpos = endpos;
free((BYTE *) diagnosisitem);
}
else
{
lastitem->next = diagnosisitem;
diagnosislist->last = diagnosisitem;
}
}
}
/* Extract two file positions from diagnosislist. */
void outdiagnosislist(diagnosislist, startpos, endpos)
register struct Diagnosis *diagnosislist;
LONG *startpos, *endpos;
{
register struct Diagnosis *diagnosisitem;
if ((diagnosisitem = diagnosislist->next) == NULL) /* List is empty */
*startpos = *endpos = -1;
else
{
*startpos = diagnosisitem->startpos;
*endpos = diagnosisitem->endpos;
diagnosislist->next = diagnosisitem->next;
free((BYTE *)diagnosisitem);
if (diagnosislist->next == NULL)
diagnosislist->last = NULL;
}
}
/* Copy infile to outfile until searchstring is found. If outfile */
/* is NULL nothing will be written. */
BYTE copyfile(infile, outfile, searchstring)
register FILE *infile, *outfile;
register BYTE *searchstring;
{
register BYTE stop, error;
static BYTE copybuffer[BUFSIZE];
stop = error = FALSE;
while (!(stop || error))
if (readbuffer(copybuffer, "archive", infile))
error = TRUE;
else
{
if (outfile != NULL)
fputs(copybuffer, outfile);
if (strcmp(copybuffer, searchstring) == 0)
stop = TRUE;
}
return(error);
}
/* Read a line from infile into buffer. Returns TRUE if */
/* end-of-file has been reached. */
BYTE readbuffer(buffer, errormsg, infile)
register BYTE *buffer, *errormsg;
register FILE *infile;
{
register BYTE error;
error = FALSE;
if (fgets(buffer, BUFSIZE, infile) == NULL)
{
fprintf(stderr, "btoa: Unexpected end of %s file.\n", errormsg);
error = TRUE;
}
return(error);
}
FILE *fopen_read(filename)
register BYTE *filename;
{
register FILE *infile;
if ((infile = fopen(filename, "r")) == NULL)
fprintf(stderr, "btoa: Can't open '%s' for input.\n", filename);
return(infile);
}
FILE *fopen_write(filename)
register BYTE *filename;
{
register FILE *outfile;
if ((outfile = fopen(filename, "w")) == NULL)
fprintf(stderr, "btoa: Can't open '%s' for output.\n", filename);
return(outfile);
}
/* Extract lines from original archive to fix the damaged one. */
BYTE producerepair(infile)
register FILE *infile;
{
register FILE *repairfile, *diagnosisfile;
register BYTE error, stop;
static BYTE *errormsg = "diagnosis";
extern BYTE *diagnosisname, *diagnosisheader, *repairname, *repairheader,
buffer[BUFSIZE];
error = FALSE;
diagnosisfile = repairfile = NULL;
fprintf(stderr, "btoa: Repair output to '%s'.\n", repairname);
if ((diagnosisfile = fopen_read(diagnosisname)) == NULL)
error = TRUE;
else if ((repairfile = fopen_write(repairname)) == NULL)
{
fclose(diagnosisfile);
diagnosisfile = NULL;
error = TRUE;
}
else
{
/* Read until header is found. This makes it possible to */
/* have junk before the header, such as an article header. */
do
{
if (readbuffer(buffer, errormsg, diagnosisfile))
error = TRUE;
}
while (!error && strcmp(buffer, diagnosisheader) != 0);
fputs(repairheader, repairfile);
}
stop = FALSE;
while (!(error || stop))
{
/* Loop until header is found again. */
if (readbuffer(buffer, errormsg, diagnosisfile))
error = TRUE;
else if (strcmp(buffer, diagnosisheader) == 0)
stop = TRUE;
else
{
/* Read until line before error is found. */
error = copyfile(infile, NULL, buffer);
if (!error)
{
/* Print line before error. */
fputs(buffer, repairfile);
if (readbuffer(buffer, errormsg, diagnosisfile))
error = TRUE;
else
{
/* Print line after error */
fputs(buffer, repairfile);
/* Copy infile to repairfile until line after error */
error = copyfile(infile, repairfile, buffer);
}
}
}
}
if (!error)
fputs(repairheader, repairfile);
if (repairfile != NULL)
fclose(repairfile);
if (diagnosisfile != NULL)
fclose(diagnosisfile);
return(error);
}
/* Repair damaged archive from repair file. */
BYTE performrepair(infile)
register FILE *infile;
{
register FILE *repairfile, *outfile;
register BYTE error, stop;
static BYTE *errormsg = "repair";
extern BYTE *repairname, *repairedname, *repairheader, buffer[BUFSIZE];
error = FALSE;
repairfile = outfile = NULL;
if ((repairfile = fopen_read(repairname)) == NULL)
error = TRUE;
else if ((outfile = fopen_write(repairedname)) == NULL)
{
fclose(repairfile);
repairfile = NULL;
error = TRUE;
}
else
{
fprintf(stderr, "btoa: Repaired archive written to '%s'.\n", repairedname);
/* Read until header is found. */
do
{
if (readbuffer(buffer, errormsg, repairfile))
error = TRUE;
}
while (!error && strcmp(buffer, repairheader) != 0);
}
stop = FALSE;
while (!(error || stop))
{
/* Loop until header is found. */
if (readbuffer(buffer, errormsg, repairfile))
error = TRUE;
else if (strcmp(buffer, repairheader) == 0)
stop = TRUE;
else
{
/* Read and write until line before error. */
error = copyfile(infile, outfile, buffer);
if (!error)
if (readbuffer(buffer, errormsg, repairfile))
error = TRUE;
else
{
/* Read and write until line after error. */
error = copyfile(repairfile, outfile, buffer);
/* Skip until line after error */
copyfile(infile, NULL, buffer);
}
}
}
if (!error) /* Write rest of archive. */
while (fgets(buffer, BUFSIZE, infile) != NULL)
fputs(buffer, outfile);
if (outfile != NULL)
fclose(outfile);
if (repairfile != NULL)
fclose(repairfile);
return(error);
}