home *** CD-ROM | disk | FTP | other *** search
- #define Version "DOSCVT V2.4"
-
- /*
-
- doscvt [-d | -u ] [-v] [-z] [filename ...]
-
- -d convert to MSDOS format.
- -u convert to UNIX.
- -v display the program version id.
- -z append a ^Z to the end of the DOS file
-
- defaults to -d on dos systems and -u on unix systems.
-
- Convert MS-DOS text file format to UNIX text file format
- Namely, convert <CR><LF> pairs to just <LF> and remove
- trailing ^Z EOF marker.
- Also converts Unix format to MS-DOS format by adding <CR>
- before <LF> and, optionally, adding ^Z at the end.
- Works by converting the specified file into a temp file and,
- when finished, renaming the temp over the original file name.
- The accessed and modified times of the original are preserved.
- Multiple filenames may be specified and each will be converted
- in turn. If no filename is specified, stdin will be converted
- and written on stdout.
-
- Norm Brake
- Modular Computer Systems, Inc.
-
- Internet: norm@modcomp.com
- Snailmail: PO Box 6099
- Ft. Lauderdale, FL 33340-6099
-
- */
-
- #include <stdio.h>
-
- /* include the stuff to preserve the time stamp. */
- /* this stuff is not ANSI, but I'm not proud */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/utime.h>
-
- #ifdef MSDOS
-
- # define SUCCESS (1) /* DOS success and failure exit codes */
- # define FAILURE (0)
-
- /* include the stuff we need under DOS to change stdin and stdout */
- /* to binary mode */
-
- #include <fcntl.h>
- #include <io.h>
-
- #else
-
- # define SUCCESS (0) /* UNIX success and failure exit codes */
- # define FAILURE (1)
-
- #endif
-
- #define EPUTCHAR(c, f, n) if (fputc(c, f) == EOF) file_error(n);
-
- struct stat hstat;
- struct utimbuf utb;
-
- FILE *f; /* file to be converted */
- FILE *t; /* temp file */
-
- int fn = 1; /* argv entry currently being processed */
- char ts[255]; /* temp string for errors and system calls */
- char *tn; /* temp file name, gets results of tmpnam() */
-
- typedef enum format {dos, unx} format_t;
-
- #ifdef MSDOS
- /* under dos, we want the default to convert unix to dos */
- format_t fmt = dos;
- #else
- /* under unix, we want the default to convert dos to unix */
- format_t fmt = unx;
- #endif
-
- int vflag=0; /* if true, -v specified on command line */
- int zflag=0; /* if true, append a ^Z to the file */
-
- char *cmd; /* pointer to argv[0] */
- char *filename; /* name of file being processed */
-
- /* display usage instructions */
- void
- usage(int vflag)
- {
- fprintf(stderr,"%s\n",Version);
- if ( ! vflag ) {
- fprintf(stderr,"usage: %s [-u | -d ] [-v] [-z] [ <filename> ]\n", cmd);
- fprintf(stderr," -u : convert <filename> to unix format\n");
- fprintf(stderr," -d : convert <filename> to DOS format\n");
- fprintf(stderr," -v : display the program version and exit\n");
- fprintf(stderr," -z : append a CTRL-Z to the converted file\n");
- exit(FAILURE);
- } else {
- exit(SUCCESS);
- }
- }
-
- /* issue a FATAL warning concerning a filename */
- void
- file_error(char *fname)
- {
- sprintf(ts, "%s - '%s'", cmd, filename);
- perror(ts);
- exit(FAILURE);
- }
-
- /* issue a FATAL warning message */
- void
- fatal(char *msg)
- {
- fprintf(stderr,"%s: error: '%s' - %s\n",cmd, filename, msg);
- remove(tn);
- exit(FAILURE);
- }
-
- /* Issue a non-fatal warning message */
- void
- warning(char *msg)
- {
- fprintf(stderr,"%s: warning: '%s' - %s\n", cmd, filename, msg);
- }
-
- /* MAIN Program */
- int
- main(int argc, char *argv[])
- {
- int c1, c2;
-
- #ifdef MSDOS
- /* With Microsoft C 5.1, tempnam ignores the directory parameter */
- /* if the environment variable "TMP" is defined and allocates the */
- /* file in "TMP" instead. If "TMP" points to another device */
- /* (such as a RAM Drive), the rename operation at the end will */
- /* fail. Thus, we can not use "tempnam" under DOS. */
-
- tn = "~dc~321~.tm~"; /* MSDOS temp file for conversion */
-
- /* MSDOS puts the entire path of the program into argv[0] which */
- /* makes error and usage reporting a little messy. So... */
-
- cmd = "doscvt"; /* program name for reporting errors */
-
- #else
-
- /* Under a UNIX system, we need the tempnam routine due to the */
- /* multi-user nature of the world. We would not want concurrent */
- /* executions of the program to be using the same temp file. */
- /* Fortunately, tempnam works correctly under UNIX. */
-
- tn = tempnam(".", "dc"); /* Unix temp file for conversion */
-
- cmd = argv[0]; /* program name for reporting errors */
-
- #endif
-
- if (argc > 1) { /* if we had some command args */
- while (argv[fn][0]=='-') { /* process any option switches */
- switch (c1=argv[fn][1]) {
- case 'd': fmt=dos; break;
- case 'u': fmt=unx; break;
- case 'z': zflag++; break;
- case 'v': vflag++;
- default: usage(vflag); /* if we got an option we didn't */
- /* know, display how to run doscvt */
- }
- fn++;
- argc--;
- }
- }
-
- /* We have processed all of the option args, now do the files */
- do {
- if (argc > 1) { /* if a file was specified */
- filename = argv[fn]; /* remember the file name */
- if (stat(filename, &hstat) != 0) /* get the file modified time */
- file_error(filename); /* if stat failed, it won't read */
- utb.actime = hstat.st_atime; /* copy the timestamp */
- utb.modtime = hstat.st_mtime; /* both accessed and modified */
- #if defined(__m88k__) && defined(realix)
- utb.acusec = hstat.st_ausec; /* if this is realix and moto 88k, */
- utb.modusec = hstat.st_musec; /* time does down to micro seconds */
- #endif
- if ((f = freopen(filename, "rb", stdin)) == NULL) /* open in as stdin */
- file_error(filename);
- if ((f = freopen(tn, "wb", stdout)) == NULL) /* open tn as stdout */
- file_error(tn);
- }
- #ifdef MSDOS
- else {
- /* Under MSDOS, stdin and stdout are text mode files by default. */
- /* If there were no files on the command files, we are filtering */
- /* stdin to stdout. Under MSDOS, we need to change their modes */
- /* to binary for the following algorithm to work. */
- /* The code to do this is MSDOS (maybe MicroSoft C) specific. */
-
- if (setmode(fileno(stdin), O_BINARY) == -1)
- file_error("<STDIN>");
- if (setmode(fileno(stdout), O_BINARY) == -1)
- file_error("<STDOUT>");
- }
- #endif
-
- /* copy and convert loop */
- /* stop on a CTRL-Z or end-of-file */
- /* if we see a CR and the next char is LF and */
- /* we are converting to unix format, delete the CR */
- /* If we se a CR-LF and converting to DOS, complain */
- /* if we see a LF and converting to DOS, add the CR */
- /* Check errors on the output since if we got a write */
- /* error, we REALLY do not want to replace the input */
- /* file with the output! */
-
- while (((c1=getchar()) != EOF) && (c1 != '\032')) {
- if (c1 == '\r') {
- if ((c2 = getchar())=='\n') {
- if (fmt == unx)
- c1 = '\n';
- else
- if (fmt == dos)
- fatal("is already MS-DOS format");
- } else
- ungetc(c2, stdin);
- } else if (c1 == '\n') {
- if (fmt == dos)
- EPUTCHAR('\r', stdout, tn);
- }
- EPUTCHAR(c1, stdout, tn);
- }
-
- /* if converting to DOS and the user wants it, */
- /* put out a CTRL-Z EOF flag */
- if ((fmt == dos) && (zflag))
- EPUTCHAR('\032', stdout, tn);
-
- /* if we opened a file name, rename the tempfile */
- /* to the original filename, and set it's timestamp */
- /* to match that of the original file. */
- if (argc > 1) {
- fclose(stdin);
- fclose(stdout);
- remove(filename);
- rename(tn, filename);
- if (utime(filename, &utb) != 0)
- warning("unable to copy file's timestamp");
- }
-
- fn++; /* bump the argv index */
- argc--; /* count down until no more files to convert */
- } while (argc > 1);
- exit(SUCCESS);
- }