⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btoa.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -