Date: Fri, 27 Jan 1995 16:32:03 -0500 (CDT) From: Aaron Ucko Subject: Re: utod/dtou for Unix (LONG) To: TAUPIN AT rsovax DOT lps DOT u-psud DOT fr Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Organization: Rockhurst College; Kansas City, MO >Subject: dtou and utod on UNIX computers Unfortunately, this does no good, as it is considered part of the message body rather than part of the header. >Thanks to several people I found the source of utod.c and dtou.c >in the DJ*.ZIP files. This osurce if fit for Turbo-C, not GCC, >but changing alloc.h to malloc.h, thigs run OK with GCC. > >Now my question is: has somebody ported dtou and utod on UNIX machines ? >Then I woukld like to get the modified source. The reason is that some >people (through unzip or uudecode) get DOS coded texts on UNIX machines, >and they are not very clever in removing the , so that they >complay about the source files ther have got. > >---> utod.c for UNIX (e.g. SUN or HP_UX). I found somewhere (I can't remember quite where) a better version of this called doscvt. (Yes, I've mentioned c-ascii, which can also deal with Mac formats, but I've lost that...) Source follows: [I had to make a minor change to the includes to get it to work with Linux, but I'm under DOS now and can't get at my Linux FS...sorry.] #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 pairs to just and remove trailing ^Z EOF marker. Also converts Unix format to MS-DOS format by adding before 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 AT modcomp DOT com Snailmail: PO Box 6099 Ft. Lauderdale, FL 33340-6099 */ #include /* include the stuff to preserve the time stamp. */ /* this stuff is not ANSI, but I'm not proud */ #include #include #include #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 #include #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] [ ]\n", cmd); fprintf(stderr," -u : convert to unix format\n"); fprintf(stderr," -d : convert 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(""); if (setmode(fileno(stdout), O_BINARY) == -1) file_error(""); } #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); } --- Aaron Ucko (ucko AT vax1 DOT rockhurst DOT edu; finger for PGP public key) -=- httyp! -=*=-Just because you're paranoid doesn't mean they aren't out to get you.-=*=- Geek code 2.1 [finger hayden AT vax1 DOT mankato DOT msus DOT edu for explanation]: GCS/M/S d(-) H s g+ p? !au a-- w+ v+ C++(+++)>++++ UL++(-)(S+)>++++ P++ L+(++) 3(-) E-(----) !N>++ K- W-(---) M-(--) V(--) po-(--) Y+(++) t(+) !5 j R G tv--(-) b+++ !D(--) B--(---) e>++++(*) u++(@) h!() f(+) r-(--)>+++ n+(-) y?