/* public domain stuff, hacked in a minute by holger */
/* $Header: /cvsroot/posix2/posix2/fixcrcr.c,v 1.6 2000/04/17 08:29:27 veit Exp $ */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <unistd.h>
#include <stdio.h>

	int
main(int argc, const char*argv[]) 
{
	if (argc != 2) {
		fprintf(stderr,"\
%s: Fix dangerous DOS control characters in ASCII file: \n\
 CR (\'\\r\'), <CTRL Z> (0x1A).  - Public domain by holger, for posix/2.\n\
 WARNING:\n\
         Use only for plain ASCII files, will damage binaries! \n\n\
 Usage:\n\
   %s FILENAME\n",
		argv[0], argv[0]);
		exit(1);
	} {
	FILE *fin,*fout;
	char tmppath[MAXPATHLEN];
	if ((fin = fopen(argv[1],"rb")) == NULL) {
		fprintf(stderr,"%s: Error open file %s\n",argv[0],argv[1]);
		return(2);
	}
	sprintf(tmppath,"%s.tmp",argv[1]);
	if ((fout = fopen(tmppath,"wb")) == NULL) {
		fprintf(stderr,"%s: Error open file %s\n",argv[0],tmppath);
		return(3);
	}{
	 register int c;
	while ( EOF != (c = getc(fin)) ) {
		if (c == '\r' ||			/* CR detected, just ignore and skip over it */
			  c == 0x1a) 	/* sub/<CTRL Z>, ignore and skip DOS end marker */
			continue;
		if (EOF == 			/* error indicator; evaluate later */
				putc(c, fout))	/* Poof, we met neither CR nor CTRL Z: Write! */
			break;
	}}
	if ( ferror(fin) || 	/* this is severe, exit to prevent data loss! */
		   ferror(fout) ) { 
		fprintf(stderr,"\
%s: I/O-error while reading file %s\n. Exiting to prevent data corruption...",
			argv[0],tmppath);
		fclose(fin); fclose(fout); 
		unlink(tmppath);
		return(4);
	}
	/* cleanup */
	if ( fclose(fin) || fclose(fout) ) {
		fprintf(stderr,"\
%s: Error closing file %s or file %s\n",
			argv[0], argv[1], tmppath);
		return(5);
	}
	if (chmod(argv[1],0777) != 0) {
		fprintf(stderr,"%s: Error chmod file %s\n",argv[0],argv[1]);
		return(6);
	}
	if (unlink(argv[1]) != 0) {
		fprintf(stderr,"%s: Error unlink file %s\n",argv[0],argv[1]);
		return(7);
	}
	if (rename(tmppath,argv[1]) != 0) {
		fprintf(stderr,"%s: Error updating file %s\n",argv[0],argv[1]);
		return(8);
	}}
	return(0);
}
