ftp.nice.ch/pub/next/tools/archiver/SmartPackage.NIHS.bs.tar.gz#/SmartPackage/Sources/bsplit/bsplit.c

This is bsplit.c in view mode; [Download] [Up]

#ifndef lint
static char* rcs_id = "$Id: bsplit.c,v 1.1 1992/09/05 15:26:05 arrouye Exp arrouye $";
#endif

/*
 * $Header: /tmp_mnt/users/mistral2/arrouye/sevy-src/RCS/bsplit.c,v 1.1 1992/09/05 15:26:05 arrouye Exp arrouye $
 * $Revision: 1.1 $ $State: Exp $
 *
 * $Author: arrouye $ $Date: 1992/09/05 15:26:05 $ $Locked$
 *
 */

/*
 * $Log: bsplit.c,v $
 * Revision 1.1  1992/09/05  15:26:05  arrouye
 * Initial revision
 *
 * Changed Fri Apr 15 07:44:19 MET DST 1994 to support multiple sizes.

 *
 */

#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#include <sys/param.h>

#ifndef CHUNK
#define CHUNK	(32 * 1024)
#endif

#ifndef OUT
#define OUT	"bx"
#endif

#ifndef OUTSUFFIX
#define OUTSUFFIX	"aaa"
#endif

struct blksize_elem {
    int blksize;
    struct blksize_elem* next;
};

static void usage(pname)
    char* pname; {

    fprintf(stderr,
	"usage: %s [-n] [-blksize[b|k|m]] [input|- [oprefix [osuffix]]]\n", pname);
    exit(1);
}

static int size(sz)
    char* sz; {

    int thesize;

    for (thesize = 0; *sz && isdigit(*sz); ++sz) {
	thesize = thesize * 10 + *sz - '0';
    }

    if (*sz) {
	if (sz[1]) {
	    thesize = -1;
	} else {
	    switch (islower(*sz) ? *sz : tolower(*sz)) {
	        case 'm':
		    thesize = thesize * 1024;
    
	        case 'k':
		    thesize = thesize * 1024;
		    break;
    
	        case 'b':
		    break;
    
	        default:
		    thesize = -1;
		    break;
	    }
        }
    }

    return thesize;
}

static int bsplit(pname, ifile, oprefix, osuffix, blksz, alphabetic)
    char* pname;
    char* ifile;
    char* oprefix;
    char* osuffix;
    struct blksize_elem* blksz;
    int alphabetic; {

    char outfile[MAXPATHLEN]; 
    char* outletter;

    char* pool;
    int ninpool;
    int res;

    int filenum = 1;
    
    int fd;
    int fmdsk;

    int size = 0;
    
    struct blksize_elem sentinel;
    
    sentinel.next = blksz, blksz = &sentinel;
    
    if (strcmp(ifile, "-")) {
        fd = open(ifile, O_RDONLY);
        if (fd == -1) {
	    fprintf(stderr, "%s: cannot open %s\n", pname, ifile);
	    res = 4;
	    goto end;
        }
    } else {
	fd = 0;
    }

    if (alphabetic) {
    	strcpy(outfile, oprefix);
        strcat(outfile, osuffix);
        outletter = outfile + (strlen(outfile) - 1);
        --*outletter;
    }
    
    do {
	int out;
	int num;

	if (blksz->next) {
	    blksz = blksz->next;
	    
	    if (!(size = blksz->blksize)) {
		fprintf(stderr, "%s: zero block size\n", pname);
		return 7;
	    }
	}
	
	for (ninpool = 1; size && !(pool = (char*) malloc(size));
	    ++ninpool, size /= 2)
	    ;
    
	if (!size) {
	    fprintf(stderr, "%s: not enough memory\n", pname);
	    return 3;
	}
	
	if (alphabetic) {
	    char* theletter = outletter;
	    do {
		if (++*theletter > 'z') {
		    *theletter = OUTSUFFIX[strlen(OUTSUFFIX) -
		    	(outletter - theletter) - 1];
		    --theletter;
		} else {
		    break;
		}
	    } while (outletter - theletter < strlen(OUTSUFFIX));
    
	    if (outletter - theletter == strlen(OUTSUFFIX)) {
		fprintf(stderr, "%s: cannot generate filename after %s\n",
		    pname, outfile);
		res = 5;
		goto end;
	    }
	} else {
	    sprintf(outfile, "%s%d", oprefix, filenum++);
	}
	
	out = creat(outfile, 0666);
	if (out == -1) {
	    fprintf(stderr, "%s: cannot create %s\n", pname, outfile);
	    res = 6;
	    goto end;
	}

	for (fmdsk = 1, num = ninpool; fmdsk && num; --num) {
	    if ((fmdsk = read(fd, pool, size)) > 0) {
	        write(out, pool, fmdsk);
	    } else if (fmdsk == -1) {
		fprintf(stderr, "%s: error reading %s\n", pname, ifile);
		res = 7;
		goto end;
	    }
	}

	close(out);
    } while (fmdsk == size);

    close(fd);

end:
    free(pool);
    return res;
}

main(argc, argv)
    int argc;
    char** argv; {

    char* pname = *argv++;
    struct blksize_elem* blksz = (struct blksize_elem*) 0;
    struct blksize_elem* lstsz = blksz;
    char* ifile;
    char* oprefix = OUT;
    char* osuffix = OUTSUFFIX;

    int alphabetic = 1;
    
    if (*argv && !strcmp(*argv, "-n")) {
    	alphabetic = 0;
	++argv;
    }
    
    while (*argv && **argv == '-' && (*argv)[1]) {
	/* Block size */
	
	int thesize = size(*argv++ + 1);
	
	if (!thesize) {
	    fprintf(stderr, "%s: bad size %s\n", pname, blksz);
	    return 2;
	} else if (thesize == -1) {
	    usage(pname);
        } else {
	    struct blksize_elem* el =
	    	(struct blksize_elem*) malloc(sizeof(struct blksize_elem));
	    
	    if (!el) {
		fprintf(stderr, "%s: not enough memory\n", pname);
		exit(3);
	    } else {
	    	el->blksize = thesize;
		el->next = (struct blksize_elem*) 0;
		
	    	if (lstsz) {
		    lstsz->next = el;
		} else {
		    blksz = lstsz = el;
		}
	    }
	}
    }

    if (!*argv) {
	ifile = "-";
    } else {
	ifile = *argv++;
    }

    if (*argv) {
	oprefix = *argv++;
    }

    if (*argv) {
	osuffix = *argv++;
    }
	
    if (*argv) {
	usage(pname);
    }

    if (!blksz) {
	struct blksize_elem* el =
	    (struct blksize_elem*) malloc(sizeof(struct blksize_elem));
	
	if (!el) {
	    fprintf(stderr, "%s: not enough memory\n", pname);
	    exit(3);
	} else {
	    el->blksize = CHUNK;
	    el->next = (struct blksize_elem*) 0;
	    
	    blksz = lstsz = el;
	}
    }
    
    return bsplit(pname, ifile, oprefix, osuffix, blksz, alphabetic);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.