ftp.nice.ch/pub/next/database/plz/xplz.3.4.s.tar.gz#/xplz-3.4/libzip/plzip.c

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

#include <malloc.h> 
#include <stdio.h>

#if defined (SVR4)
#  include <string.h>
#  define rindex strrchr
#else
#  include <strings.h>
#endif

#ifdef SYSV
#include <getopt.h>
#else
extern int getopt(int argc, char **argv, char *optstring);
extern char *optarg;
extern int optind, opterr;
#endif

#define putlong(l,f) {putc(l,f); putc(l>>8,f); putc(l>>16,f); putc(l>>24,f);}
#define getlong(l,f) {l=getc(f)&0xff; l|=(getc(f)&0xff)<<8; l|=(getc(f)&0xff)<<16; l|=(getc(f)&0xff)<<24;}


main(int argc, char *argv[])
{
  char *ibuf, *obuf, *wrk_mem;
  int ilen,olen,rlen;
  int is=0, os=0;
  int bsize = 100;
  int compress_flag = 1, index_flag = 0, verbose=0;
  struct compress_identity *cid;
  char *pname = argv[0];
  FILE *infile, *outfile;
  int i;
  extern int level;
  int nindex;
  long *index;
  int *keypos, *keylen;
  char **keys;

  int rsize, insize, outsize, rnum, bnum, r, b;

  int c,err=0;


  if (rindex(pname,'/')) pname = rindex(pname,'/')+1;

  while	((c = getopt(argc, argv, "r:l:cdiv")) != -1) {
    switch (c) {
    case 'c': compress_flag = 1;
      break;
    case 'd': compress_flag = 0;
      break;
    case 'i': index_flag = 1;
      break;
    case 'v': verbose = 1;
      break;
    case 'r': bsize = atoi(optarg);
      break;
    case 'l': level = atoi(optarg);
      break;
    case '?': err=1;
    }
  }
  if (err || argc-(optind-1) < 3) {
    fprintf(stderr,"usage: plzip [-cdv] [-l level] [-r recs]  infile outfile   [ keypos keylen  [ keypos keylen ]  ... ] \n");
    exit(1);
  }

  argc -= optind-1;
  argv += optind-1;

  if (!index_flag) {
    if ((infile = fopen(argv[1],compress_flag?"r":"rb")) == NULL) {
      fprintf(stderr,"Can't open input file %s:",argv[1]);
      perror(NULL);
      exit(1);
    }
  }
  if ((outfile = fopen(argv[2],index_flag?"r+b":(compress_flag?"wb":"w"))) == NULL) {
    fprintf(stderr,"Can't open output file %s:",argv[2]);
    perror(NULL);
    exit(1);
  }
  
  argc -= 2;
  argv += 2;

  if (index_flag || compress_flag) {
    nindex = (argc-1)/2;
    keys = (char**) malloc(nindex*sizeof(char*));
    keypos = (int*) malloc(nindex*sizeof(int));
    keylen = (int*) malloc(nindex*sizeof(int));
    for(i=0; i<nindex; i++) {
      keypos[i] = atoi(*(++argv))-1;
      keylen[i] = atoi(*(++argv));
    }
  }

  if (index_flag) {
    extern char* outptr;	    
    extern char* outbuf;
    outbuf=malloc(2048+1);

    infile = outfile;
    fseek(infile,0,0);
    
    getlong(rsize,infile);
    getlong(bsize,infile);
    getlong(rnum ,infile);
    fseek(outfile,ftell(infile),0);
    putlong(nindex,outfile);  
    fseek(infile,ftell(outfile),0);
    getlong(i    ,infile);
    fseek(infile, i, 0);

    bnum = (rnum+bsize-1)/bsize;
    
    ibuf = malloc(bsize*rsize);
    obuf = malloc(bsize*rsize);

    index = (long*) malloc((bnum+1)*sizeof(long));
    for(i=0; i<nindex; i++) 
      keys[i] = (char*) malloc((bnum+1)*keylen[i]*sizeof(char));

    for(i=0; i<bnum+1; i++) 
      getlong(index[i],infile);

    for(b=r=0; r<rnum; r+=bsize,b++) {
      outsize = (rnum-r)*rsize;
      if (outsize > rsize*bsize) outsize = rsize*bsize; 
      fseek(infile, index[b], 0); 
      ilen = fread(ibuf, 1, index[b+1]-index[b], infile);
      is += ilen;
      if (ilen != index[b+1]-index[b]) { 
	fprintf(stderr,"b=%d bnum=%d  r=%d rnum=%d   outsize=%d ilen=%d  %d\n",b,bnum,r,rnum,outsize,ilen,index[b+1]-index[b]);
	perror("short input file"); exit(1); 
      }
      
      outptr = obuf;
      memextract(obuf,outsize,ibuf,ilen);
      os += outsize;
/*      if (verbose)  fprintf(stderr,"%8d => %8d\n",ilen,outsize); /**/
      for(i=0; i<nindex; i++)
	strncpy(keys[i]+b*keylen[i],obuf+keypos[i],keylen[i]);
    }
    for(i=0; i<nindex; i++)
      strncpy(keys[i]+b*keylen[i],obuf + outsize-rsize + keypos[i],keylen[i]);
    

    /* write new indices */

    fseek(outfile,ftell(infile),0);

    for(i=0; i<bnum+1; i++) 
      putlong(index[i],outfile);

    for(i=0; i<nindex; i++) {
      putlong(keypos[i],outfile);
      putlong(keylen[i],outfile);
      fwrite(keys[i], 1, (bnum+1)*keylen[i], outfile);
    }

    ftruncate(fileno(outfile),ftell(outfile));
    fclose(outfile);
    if (verbose) fprintf(stderr,"input: %9u => output: %9u  (ratio %5.3f)\n",is,os,(os+0.0)/is); /**/
    
  } 
  else if (compress_flag) {
    for (rsize=1; getc (infile) != '\n'; rsize++);
    fseek(infile, 0L, 2);
    insize = ftell(infile);
    fseek(infile, 0L, 0);
    rnum = insize/rsize;
    bnum = (rnum+bsize-1)/bsize;

    printf("rsize  = %d\n",rsize);
    printf("insize = %d\n",insize);
    printf("recs   = %d\n",rnum);
    printf("blocks = %d\n",bnum);
    
    if (insize%rsize) {
      fprintf(stderr,"Warning: input file size is no integer multiple of record size %d\nLast %d bytes are skipped.\n",rsize,insize%rsize);
    }
    
    putlong(rsize,outfile);
    putlong(bsize,outfile);
    putlong(rnum ,outfile);
    putlong(nindex,outfile);
    putlong(0    ,outfile);

    ibuf = malloc(bsize*rsize);
    obuf = malloc(bsize*rsize);

    index = (long*) malloc((bnum+1)*sizeof(long));
    for(i=0; i<nindex; i++) 
      keys[i] = (char*) malloc((bnum+1)*keylen[i]*sizeof(char));

   
    for(b=r=0; r<rnum; r+=bsize,b++) {
      insize = (rnum-r)*rsize;
      if (insize > rsize*bsize) insize = rsize*bsize; 
      ilen = fread(ibuf, 1, insize, infile);
      is += ilen;
      if (ilen != insize) { 
	fprintf(stderr,"b=%d bnum=%d  r=%d rnum=%d   insize=%d ilen=%d\n",b,bnum,r,rnum,insize,ilen);
	perror("short input file"); exit(1); 
      }
      
      olen=memcompress(obuf,bsize*rsize,ibuf,insize);
      os += olen;
/*      if (verbose)  fprintf(stderr,"%8d => %8d\n",ilen,olen); /**/
      index[b] = ftell(outfile);
      for(i=0; i<nindex; i++)
	strncpy(keys[i]+b*keylen[i],ibuf+keypos[i],keylen[i]);
      fwrite(obuf,1,olen,outfile);
    }
    index[b] = ftell(outfile);
    for(i=0; i<nindex; i++)
      strncpy(keys[i]+b*keylen[i],ibuf + insize-rsize + keypos[i],keylen[i]);
    
    fseek(outfile, index[0]-4, 0);
    putlong(index[b],outfile);
    fseek(outfile, index[b], 0);

    for(i=0; i<bnum+1; i++) 
      putlong(index[i],outfile);

    for(i=0; i<nindex; i++) {
      putlong(keypos[i],outfile);
      putlong(keylen[i],outfile);
      fwrite(keys[i], 1, (bnum+1)*keylen[i], outfile);
    }

    if (verbose) fprintf(stderr,"input: %9u => output: %9u  (ratio %5.3f)\n",is,os,(is+0.0)/os); /**/
  }
  else {
    extern char* outptr;	    
    extern char* outbuf;
    outbuf=malloc(2048+1);
    
    getlong(rsize,infile);
    getlong(bsize,infile);
    getlong(rnum ,infile);
    getlong(nindex,infile);
    getlong(i    ,infile);
    fseek(infile, i, 0);

    bnum = (rnum+bsize-1)/bsize;
    
    ibuf = malloc(bsize*rsize);
    obuf = malloc(bsize*rsize);

    keys = (char**) malloc(nindex*sizeof(char*));
    keypos = (int*) malloc(nindex*sizeof(int));
    keylen = (int*) malloc(nindex*sizeof(int));
    
    index = (long*) malloc((bnum+1)*sizeof(long));

    for(i=0; i<bnum+1; i++) 
      getlong(index[i],infile);

    for(i=0; i<nindex; i++) {
      getlong(keypos[i],infile);
      getlong(keylen[i],infile);
      keys[i] = (char*) malloc((bnum+1)*keylen[i]*sizeof(char));
      fread(keys[i], 1, (bnum+1)*keylen[i], infile);
    }


    for(b=r=0; r<rnum; r+=bsize,b++) {
      outsize = (rnum-r)*rsize;
      if (outsize > rsize*bsize) outsize = rsize*bsize; 
      fseek(infile, index[b], 0); 
      ilen = fread(ibuf, 1, index[b+1]-index[b], infile);
      is += ilen;
      if (ilen != index[b+1]-index[b]) { 
	fprintf(stderr,"b=%d bnum=%d  r=%d rnum=%d   outsize=%d ilen=%d  %d\n",b,bnum,r,rnum,outsize,ilen,index[b+1]-index[b]);
	perror("short input file"); exit(1); 
      }
      
      outptr = obuf;
      memextract(obuf,outsize,ibuf,ilen);
      os += outsize;
/*      if (verbose)  fprintf(stderr,"%8d => %8d\n",ilen,outsize); /**/
      fwrite(obuf,1,outsize,outfile);
    }
    
    if (verbose) fprintf(stderr,"input: %9u => output: %9u  (ratio %5.3f)\n",is,os,(os+0.0)/is); /**/
  }      
}


void error(h)
  char *h;
{
  fprintf(stderr,"%s\n", h);
}

void warn(a, b)
char *a, *b;            /* message strings juxtaposed in output */
/* Print a warning message to stderr and return. */
{
  fprintf(stderr, "zip warning: %s%s\n", a, b);
}


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