delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/01/27/21:06:48

Date: Fri, 27 Jan 1995 16:32:03 -0500 (CDT)
From: Aaron Ucko <UCKO AT VAX1 DOT ROCKHURST DOT EDU>
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 <CR>, 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 <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 AT modcomp DOT 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);
}
  

--- 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?

- Raw text -


  webmaster     delorie software   privacy  
  Copyright 2019   by DJ Delorie     Updated Jul 2019