www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2002/12/05/17:45:13

From: "Eric" <eric AT replytogroup DOT net>
Newsgroups: comp.os.msdos.djgpp
Subject: Files fread() in and fread() out get garbled
Date: Thu, 5 Dec 2002 22:33:00 -0000
Lines: 209
Message-ID: <asok7c$tj8$1@news7.svr.pol.co.uk>
NNTP-Posting-Host: 62.136.211.85
X-Trace: news7.svr.pol.co.uk 1039127596 30312 62.136.211.85 (5 Dec 2002 22:33:16 GMT)
NNTP-Posting-Date: 5 Dec 2002 22:33:16 GMT
X-Complaints-To: abuse AT theplanet DOT net
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.00.2919.6700
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Hello. I've been staring at my program for an hour and can't find the bug.
Hope you can help :-)

My code is supposed to break up a large file into several small files for
transfer on floppy disks, then re-assemble the large file from the parts
given the -r command. Trouble is, the re-assembled file, although the right
size, is messed up in some way: whenever I split a large .exe, for example,
re-assemble it and then run it, all sorts of weirdness occurs.

PS: I'm a newbie and this is my most ambitious program ever, so please go
easy :-)

/* split.c
  Compiled with DJGPP
  Place file to split in dir with split.exe, run split.exe specifying file
  to split on the command line, then, with all the parts in the same dir as
  split.exe, run split.exe again with argument -r to merge parts into
  "split.out" then (cough) manually rename (Oh, and for safety reasons,
  run in an empty dir!)
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>

#define MB 1048576
#define FLOPPY_CAPACITY 1457664


enum errcode {FILE_IO, MEMORY, FILE_SIZE};

typedef enum errcode error_c;


void split(char *);
void reassemble(void);
void error(error_c);
void exitClean(void);
void allocBuffer(long);


FILE *f = NULL;
char *buffer = NULL;
const char *name = "abcdefghijklmnopqrstuvwxyz";


void split(char *argv1)
{
        long size, bytes, unit;
        char fname[2] = "\0\0";

        f = fopen(argv1, "rb");
        if (f == NULL) {
                error(FILE_IO);
        }
        size = filelength(fileno(f)); /**** non-standard ****/
        if (size == -1L) {
                error(FILE_IO);
        }
        if (size <= FLOPPY_CAPACITY || size > 26 * FLOPPY_CAPACITY) {
                error(FILE_SIZE);
        }

        printf("File \"%s\" is %ld bytes (%.1f Mb), requiring %.1f floppy
disks.\n",
        argv1, size, size / (double)MB, size / (double)FLOPPY_CAPACITY);

        allocBuffer(size);

        puts("Reading file...");

        bytes = fread(buffer, 1, size, f);
        if (bytes != size) {
                error(FILE_IO);
        }

        fclose(f);
        f = NULL;

        unit = FLOPPY_CAPACITY;

        while (size) {
                *fname = *name++;
                f = fopen(fname, "wb");
                if (f == NULL) {
                        error(FILE_IO);
                }
                puts("Writing...");
                bytes = fwrite(buffer, 1, unit, f);
                if (bytes != unit) {
                        error(FILE_IO);
                }
                fclose(f);
                f = NULL;
                size -= unit;
                if (size < FLOPPY_CAPACITY) {
                        unit = size;
                }
        }

        puts("Split successful");
}

void reassemble(void)
{
        long size, bytes, total_size = 0;
        FILE *fout;
        char fname[2] = "a";

        fout = fopen("split.out", "ab");
        if (fout == NULL) {
                error(FILE_IO);
        }

        name++;

        while ((f = fopen(fname, "rb")) != NULL) {
                size = filelength(fileno(f));
                if (size == -1L) {
                        error(FILE_IO);
                }
                puts("Reading...");
                allocBuffer(size);
                bytes = fread(buffer, 1, size, f);
                if (bytes != size) {
                        error(FILE_IO);
                }
                puts("Writing...");
                bytes = fwrite(buffer, 1, size, fout);
                if (bytes != size) {
                        error(FILE_IO);
                }
                total_size += size;
                fclose(f);
                f = NULL;
                *fname = *name++;
        }

        if (total_size == 0) {
                error(FILE_IO);
        }

        printf("Files merged into %ld bytes\n", total_size);
        puts("Re-assembly completed");
}

void error(error_c err)
{
        switch (err) {
        case (FILE_IO):
                puts("File I/O error. Check filename is correct or that
files exist.");
                break;
        case (FILE_SIZE):
                puts("Input file size error");
                break;
        case (MEMORY):
                puts("Memory error");
                break;
        }
        exitClean();
        exit(EXIT_FAILURE);
}

void exitClean(void)
{
        if (f != NULL) {
                fclose(f);
        }
        if (buffer != NULL) {
                free(buffer);
        }
}

void allocBuffer(long size)
{
        puts("Allocating memory...");
        buffer = malloc(size);
        if (buffer == NULL) {
                error(MEMORY);
        }
}

int main(int argc, char *argv[])
{
        if (argc < 2) {
                puts("SPLIT [drive:][path][filename] [-R]\n");
                puts("[drive:][path][filename]");
                puts("\tSpecifies file to split.");
                puts("-R");
                puts("\tRe-assemble mode.\n");
                return 0;
        }

        if (!(strcmp(argv[1], "-R")) || !(strcmp(argv[1], "-r"))) {
                reassemble();
        } else {
                split(argv[1]);
        }

        exitClean();
        return 0;
}



- Raw text -


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