This is repair.c in view mode; [Download] [Up]
/* 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); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.