📄 btoa.c
字号:
LONG *lastline, filepos;int maxperline;{ register int length; int ch; register BYTE stop, error, newerror, errorstart; register LONG line, prevfilepos, startpos; struct Diagnosis diaglist; error = FALSE; line = 1; /* Current line number. */ /* A sequence of errors is indicated by errorstart. When it */ /* Changes from TRUE to FALSE a diag record will be */ /* Generated. */ stop = errorstart = FALSE; /* File position of the line before the error sequence. */ /* That is the last correct line. */ startpos = 0; while (!stop) { prevfilepos = filepos; filepos = ftell(infile); /* Newerror indicates an error on the current line. */ newerror = FALSE; line++; if (readbuffer(buffer, "archive", infile)) newerror = stop = TRUE; else if (buffer[0] == 'x') /* End of archive found. */ stop = TRUE; else if ((length = strlen(buffer) - 1) != maxperline || buffer[length] != '\n') { /* If last character wasn't end-of-line, then we */ /* Have to read until it is found. */ if (buffer[length] != '\n') { newerror = TRUE; while ((ch = fgetc(infile)) != EOF && (BYTE) ch != '\n'); if (ch == EOF) stop = TRUE; } else if (length > maxperline || nextbyte(infile) != 'x') { newerror = TRUE; Csum = DECODE(buffer[length - 1]); /* Make Csum correct * (modulo 85). */ } if (newerror) fprintf(stderr, "btoa: Bad line length on line %ld.\n", line); if (!(newerror || stop)) { if (decode_line(buffer, length - 1)) { if (!error) fprintf(stderr, "btoa: Bad character on line %ld.\n", line); newerror = TRUE; } /* Examine checksum. */ if ((ch = buffer[length - 1]) == ENCODE(Csum % 85)) { if (errorstart) { intodiaglist(&diaglist, startpos, filepos); errorstart = FALSE; } } else { newerror = TRUE; fprintf(stderr, "btoa: Bad checksum on line %ld.\n", line); Csum = DECODE(ch); /* Make Csum correct * (modulo 85). */ } } } if (newerror) { if (!error) { fprintf(stderr, "btoa: Starting diag.\n"); diaglist.next = diaglist.last = NULL; } error = TRUE; if (!errorstart) { errorstart = TRUE; startpos = prevfilepos; } } } if (error) { if (errorstart) intodiaglist(&diaglist, startpos, filepos); producediag(&diaglist, infile); } *lastline = line; return(error);}BYTE old_decodefile(infile, lastline)register FILE *infile;LONG *lastline;{ register int length; register BYTE stop, error; register LONG line; error = FALSE; line = 1; stop = FALSE; while (!stop) { line++; if (readbuffer(buffer, "archive", infile)) error = stop = TRUE; else if (buffer[0] == 'x') /* End of archive found. */ stop = TRUE; else { length = strlen(buffer) - 1; if (buffer[length] != '\n') error = stop = TRUE; /* The line was longer * than the buffer. */ else { if (decode_line(buffer, length)) { fprintf(stderr, "btoa: Bad character on line %ld.\n", line); error = stop = TRUE; } } } } *lastline = line; return(error);}BYTE decode_line(buf, length)register BYTE *buf;register int length;{ register int ch; register BYTE error; register LONG tmp_codeword; static LONG codeword; static int ch1, ch2, ch3, ch4; static BYTE bytecount = 0; error = FALSE; if (buf == NULL) { /* Flush last characters. */ if (bytecount > 0) { fputc(ch1, outfile); if (length > 0) fputc(ch2, outfile); if (length > 1) fputc(ch3, outfile); if (length > 2) fputc(ch4, outfile); } } else { while (length > 0) { length--; ch = *buf++; /* Delayed output. This is to make sure that files * with lengths */ /* That are not multiples of 4 won't become too long. */ if (bytecount == 5) { fputc(ch1, outfile); fputc(ch2, outfile); fputc(ch3, outfile); fputc(ch4, outfile); bytecount = 0; } if (new_version) calcchecksum(ch); if (((BYTE) ch >= '!') && ((BYTE) ch < ('!' + 85))) { /* Valid characters. */ /* See if we can take all 5 bytes and decode * them right away. */ /* That is, if all remaining bytes are on the * current line. */ if (length >= 4 - bytecount) { length -= 4 - bytecount; if (bytecount == 0) codeword = DECODE(ch); else codeword = codeword * 85 + DECODE(ch); for (bytecount++; bytecount < 5; bytecount++) { ch = *buf++; if (new_version) calcchecksum(ch); codeword = codeword * 85 + DECODE(ch); } } else { /* Shift codeword and insert character. */ if (bytecount == 0) { codeword = DECODE(ch); bytecount = 1; } else { /* bytecount < 5 */ codeword = codeword * 85 + DECODE(ch); bytecount++; } } if (bytecount == 5) { tmp_codeword = codeword; ch4 = (int) tmp_codeword & 0xFF; ch3 = (int) (tmp_codeword >>= 8) & 0xFF; ch2 = (int) (tmp_codeword >>= 8) & 0xFF; ch1 = (int) (tmp_codeword >> 8) & 0xFF; if (!new_version) { calcchecksum(ch1); calcchecksum(ch2); calcchecksum(ch3); calcchecksum(ch4); } } } else if ((BYTE) ch == 'z' || (new_version && (BYTE) ch == 'y')) { if (bytecount != 0) error = TRUE; else { ch1 = ch2 = ch3 = ch4 = (ch == 'z') ? 0 : ' '; if (!new_version) { calcchecksum(ch1); calcchecksum(ch1); calcchecksum(ch1); calcchecksum(ch1); } bytecount = 5; } } else error = TRUE; } } return(error);}/* Repair.c *//* Written by Stefan Parmark. */#ifdef AMIGA#include <stdlib.h>#include <string.h>#endif /* AMIGA *//* File names. */BYTE *diagname = "btoa.dia";BYTE *repairname = "btoa.rep";BYTE *repairedname = "btoa.rdy";/* File headers. */BYTE *diagheader = "xdiag\n";BYTE *repairheader = "xrepair\n";/* Produce diag file from diagnoses records created by atob(). *//* It contains the lines immediately before and after the error *//* Sequence. */void producediag(diaglist, infile)register struct Diagnosis *diaglist;register FILE *infile;{ register FILE *diagfile; LONG startpos, endpos; register LONG currentpos; currentpos = ftell(infile); if ((diagfile = fopen_write(diagname)) != NULL) { fprintf(stderr, "btoa: Diagnosis output to '%s'.\n", diagname); fputs(diagheader, diagfile); do { /* Extract startpos & endpos from diaglist. */ outdiaglist(diaglist, &startpos, &endpos); if (startpos != -1) { /* Print line before error. */ fseek(infile, startpos, 0); fgets(buffer, BUFSIZE, infile); fputs(buffer, diagfile); /* Print line after error. */ fseek(infile, endpos, 0); fgets(buffer, BUFSIZE, infile); fputs(buffer, diagfile); } } while (startpos != -1); fputs(diagheader, diagfile); fclose(diagfile); } /* Move file pointer to where it was when we entered. */ fseek(infile, currentpos, 0);}/* Insert two file positions into diaglist. */void intodiaglist(diaglist, startpos, endpos)register struct Diagnosis *diaglist;register LONG startpos, endpos;{ register struct Diagnosis *diagitem, *lastitem; diagitem = (struct Diagnosis *) malloc(sizeof(struct Diagnosis)); diagitem->startpos = startpos; diagitem->endpos = endpos; diagitem->next = NULL; if ((lastitem = diaglist->last) == NULL) /* List is empty */ diaglist->next = diaglist->last = diagitem; else { if (lastitem->endpos >= startpos) { lastitem->endpos = endpos; free((BYTE *) diagitem); } else { lastitem->next = diagitem; diaglist->last = diagitem; } }}/* Extract two file positions from diaglist. */void outdiaglist(diaglist, startpos, endpos)register struct Diagnosis *diaglist;LONG *startpos, *endpos;{ register struct Diagnosis *diagitem; if ((diagitem = diaglist->next) == NULL) /* List is empty */ *startpos = *endpos = -1; else { *startpos = diagitem->startpos; *endpos = diagitem->endpos; diaglist->next = diagitem->next; free((BYTE *) diagitem); if (diaglist->next == NULL) diaglist->last = NULL; }}/* Copy infile to outfile until searchstring is found. If outfile *//* Is NULL nothing will be written. */BYTE copyfile(infile, outfil, searchstring)register FILE *infile, *outfil;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 (outfil != NULL) fputs(copybuffer, outfil); 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(buf, errormsg, infile)register BYTE *buf, *errormsg;register FILE *infile;{ register BYTE error; error = FALSE; if (fgets(buf, 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 *outfil; if ((outfil = fopen(filename, "w")) == NULL) fprintf(stderr, "btoa: Can't open '%s' for output.\n", filename); return(outfil);}/* Extract lines from original archive to fix the damaged one. */BYTE pro_repair(infile)register FILE *infile;{ register FILE *repairfile, *diagfile; register BYTE error, stop; static BYTE *errormsg = "diag"; error = FALSE; diagfile = repairfile = NULL; fprintf(stderr, "btoa: Repair output to '%s'.\n", repairname); if ((diagfile = fopen_read(diagname)) == NULL) error = TRUE; else if ((repairfile = fopen_write(repairname)) == NULL) { fclose(diagfile); diagfile = 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, diagfile)) error = TRUE; } while (!error && strcmp(buffer, diagheader) != 0); fputs(repairheader, repairfile); } stop = FALSE; while (!(error || stop)) { /* Loop until header is found again. */ if (readbuffer(buffer, errormsg, diagfile)) error = TRUE; else if (strcmp(buffer, diagheader) == 0) stop = TRUE; else { /* Read until line before error is found. */ error = copyfile(infile, (FILE *) NULL, buffer); if (!error) { /* Print line before error. */ fputs(buffer, repairfile); if (readbuffer(buffer, errormsg, diagfile)) 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 (diagfile != NULL) fclose(diagfile); 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"; 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, (FILE *) NULL, buffer); } } } if (!error) /* Write rest of archive. */ while (fgets(buffer, BUFSIZE, infile) != (char *)NULL) fputs(buffer, outfile); if (outfile != (FILE *)NULL) fclose(outfile); if (repairfile != (FILE *)NULL) fclose(repairfile); return(error);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -