TCLUG Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [TCLUG:13375] dos file format to linux



On Fri, Feb 04, 2000 at 10:45:21AM -0600, John Hawley wrote:
> Sorry to bother the list with a novice question but how is it again,
> that I get rid of the <CR> at the end of each line in a file created
> in dos?  I thought there was a little utility, but apropos doesn't
> come up with anything.  I'd make it a little programming 101
> project, but I'm pressed for time.  :(

	This works too, should be extra fast, and even does it in
place.  :-)

#include <stddef.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

static int translateFile(const char * const progname, const char * const fname);

int main(int argc, char *argv[])
{
    const char *progname = argv[0];

    if (argc <= 1)
    {
        fprintf(stderr, "Usage: %s <file> [<file> ....]\n", progname);
    }
    else
    {
        int i = 1;
        for (i = 1; i < argc; ++i)
        {
            if (translateFile(progname, argv[i]) == 0)
            {
                return(1);
            }
        }
    }
    return(0);
}

static int translateFile(const char * const progname, const char * const fname)
{
    struct stat buf;
    int fd = open(fname, O_RDWR);

    if (fd < 0)
    {
        perror(progname);
        fprintf(stderr, "Unable to open \"%s\"\n", fname);
        return(0);
    }
    else if (fstat(fd, &buf) != 0)
    {
        perror(progname);
        fprintf(stderr, "Unable to stat \"%s\"\n", fname);
        close(fd);
        fd = -1;
        return(0);
    }
    else
    {
        off_t fsize = buf.st_size;
        unsigned char * const mem = mmap(NULL, fsize, PROT_READ | PROT_WRITE,
                                         MAP_SHARED, fd, 0);
        if (mem == MAP_FAILED)
        {
            perror(progname);
            fprintf(stderr, "Unable to mmap \"%s\"\n", fname);
            close(fd);
            fd = -1;
            return(0);
        }
        else
        {
            off_t source, dest;
            {
                unsigned char *temp = memchr(mem, '\r', fsize);
                if (temp == NULL)
                {
                    source = dest = fsize;
                }
                else
                {
                    source = dest = temp - mem;
                    assert(dest < fsize);
                }
            }
            while (++source < fsize)
            {
                if (mem[source] != '\r')
                {
                    mem[dest++] = mem[source];
                }
            }
            munmap(mem, fsize);
            if (dest < fsize)
            {
                if (ftruncate(fd, dest) != 0)
                {
                    perror(progname);
                    fprintf(stderr, "Unable to truncate \"%s\", so file may "
                            "be corrupted.\n", fname);
                    close(fd);
                    fd = -1;
                    return(1);
                }
                else
                {
                    close(fd);
                    fd = -1;
                }
            }
            else
            {
                close(fd);
                fd = -1;
            }
        }
    }
    assert(fd == -1);
    return(0);
}

*grin*,
-- 
Its name is Public Opinion.  It is held in reverence. It settles everything.
Some think it is the voice of God.  Loyalty to petrified opinion never yet
broke a chain or freed a human soul.     ---Mark Twain
-- Eric Hopper (hopper@omnifarious.mn.org  http://omnifarious.mn.org/~hopper) --
#include <stddef.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

static int translateFile(const char * const progname, const char * const fname);

int main(int argc, char *argv[])
{
    const char *progname = argv[0];

    if (argc <= 1)
    {
        fprintf(stderr, "Usage: %s <file> [<file> ....]\n", progname);
    }
    else
    {
        int i = 1;
        for (i = 1; i < argc; ++i)
        {
            if (translateFile(progname, argv[i]) == 0)
            {
                return(1);
            }
        }
    }
    return(0);
}

static int translateFile(const char * const progname, const char * const fname)
{
    struct stat buf;
    int fd = open(fname, O_RDWR);

    if (fd < 0)
    {
        perror(progname);
        fprintf(stderr, "Unable to open \"%s\"\n", fname);
        return(0);
    }
    else if (fstat(fd, &buf) != 0)
    {
        perror(progname);
        fprintf(stderr, "Unable to stat \"%s\"\n", fname);
        close(fd);
        fd = -1;
        return(0);
    }
    else
    {
        off_t fsize = buf.st_size;
        unsigned char * const mem = mmap(NULL, fsize, PROT_READ | PROT_WRITE,
                                         MAP_SHARED, fd, 0);
        if (mem == MAP_FAILED)
        {
            perror(progname);
            fprintf(stderr, "Unable to mmap \"%s\"\n", fname);
            close(fd);
            fd = -1;
            return(0);
        }
        else
        {
            off_t source, dest;
            {
                unsigned char *temp = memchr(mem, '\r', fsize);
                if (temp == NULL)
                {
                    source = dest = fsize;
                }
                else
                {
                    source = dest = temp - mem;
                    assert(dest < fsize);
                }
            }
            while (++source < fsize)
            {
                if (mem[source] != '\r')
                {
                    mem[dest++] = mem[source];
                }
            }
            munmap(mem, fsize);
            if (dest < fsize)
            {
                if (ftruncate(fd, dest) != 0)
                {
                    perror(progname);
                    fprintf(stderr, "Unable to truncate \"%s\", so file may "
                            "be corrupted.\n", fname);
                    close(fd);
                    fd = -1;
                    return(1);
                }
                else
                {
                    close(fd);
                    fd = -1;
                }
            }
            else
            {
                close(fd);
                fd = -1;
            }
        }
    }
    assert(fd == -1);
    return(0);
}

PGP signature