www.pudn.com > cryptfs030905.rar > sca_write.c


/*
 * Copyright (c) 1997-2003 Erez Zadok
 * Copyright (c) 2001-2003 Stony Brook University
 *
 * For specific licensing information, see the COPYING file distributed with
 * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.
 *
 * This Copyright notice must be kept intact and distributed with all
 * fistgen sources INCLUDING sources generated by fistgen.
 */
/*
 *  $Id: sca_write.c,v 1.8 2003/07/29 18:17:21 ezk Exp $
 */
#include 
#include 
#include 
#include 
#include 
#include 

#include "sca_aux.h"
#include "sca_code.h"


int
encode_file(char *name)
     /* Write out a gzipfs'ed version of file . Return 0 for success,
        errno for error. */
{
    char filename[MAXPATHLEN];
    struct fistfs_header hdr;
    int infd, outfd;	/* File to be read, file to be written, and
			   the index file */
    struct stat sb;
    int base = 0;			/* Unencoded length, encoded length */
    unsigned char *data = NULL;	/* For mmaping the infile */
    unsigned char *page;		/* A pointer that steps through data */
    int cnt;

    if (name == NULL)
	return(-1);

    if ((infd = open(name, O_RDONLY)) < 0)
	return(errno);
    if ((fstat(infd, &sb)) < 0)
	return(errno);
    if (S_ISDIR(sb.st_mode))
	return(EISDIR);

    sprintf(filename, "%s.sca", name);
    fprintf(stderr, "encoding %s into %s...\n", name, filename);
    if ((outfd = open(filename, O_RDWR|O_TRUNC|O_CREAT, 00600)) < 0)
	return(errno);

    sprintf(filename, "%s.idx", name);
    if (read_idx(filename, &hdr) < 0) { /* Not there, make one! */
	hdr.num_pages = 0;
	hdr.real_size = 0;
	hdr.offsets = NULL;
    }

    if ((data = mmap((void *)data, sb.st_size, PROT_READ,
		     MAP_PRIVATE, infd, 0)) == NULL)
	return(errno);

    while (base < sb.st_size) {	/* Now step through the input file */
	cnt = sb.st_size - base;	/* How much is left? */
	if (cnt > chunksize)
	    cnt = chunksize;		/* Do 1 page at a time */

	page = &(data[base]);
	base += cnt;		/* base contains the position of the last
				   unencoded byte we've read */

	if (put_page(outfd, &hdr, hdr.num_pages, page, cnt) < 0) {
	    return(-1);
	}
    }

    if (write_idx(filename, &hdr) < 0)
	return(-1);

    free(hdr.offsets);

    munmap(data, sb.st_size);

    close(outfd);
    close(infd);
    return(0);
}


void
usage(const char *progname)
{
    fprintf(stderr, "Usage: %s: [-c chunksize] [-f] [-d] file1 [file2 file3 ...]\n", progname);
}


int
main(int argc, char **argv)
{
    int i, rc, cnt = 0;
    int debug=0;

    if (argc < 2) {
	usage(argv[0]);
	exit(1);
    }

    while ((i = getopt(argc, argv, "c:fd")) != EOF) {
	switch(i) {
	case 'c':
	    chunksize = atoi(optarg);
	    if (chunksize < 0) {
		fprintf(stderr, "Please use a positive chunk size\n");
		exit(1);
	    }
	    break;
	case 'f':
	    do_fast_tails = 1;
	    break;
	case 'd':
	    debug=1;
	    break;
	default:
	    usage(argv[0]);
	    exit(1);
	}
    }

    for (i = optind; i < argc; i++) {
	if ((rc = encode_file(argv[i])) < 0) {
	    fprintf(stderr, "\tError encoding %s (%d)\n", argv[i], rc);
	    cnt++;
	}
    }

    if (debug) {
	fprintf(stderr, "encodes: %d\n", encode_counter);
	fprintf(stderr, "decodes: %d\n", decode_counter);
	fprintf(stderr, "writes:  %d\n", write_counter);
    }
    exit(cnt);
}

/*
 * Local variables:
 * c-basic-offset: 4
 * End:
 */