Metropoli BBS
VIEWER: packit.c MODE: TEXT (ASCII)
/* PACKIT v2.11

v2.11 - exits nicely if there are no files
v2.10 - can output header to another file (see pack.txt)
v2.01 - will no longer add fileout to itself if it already exists
v2.00 - 32bit version...
v1.00 - simple 16bit version...

*/

#include <qlib.h>
#include <dos.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

byte fixer;

struct bufs{
  byte fn[13];  //0-12
  word fh;      //always 0
  dword off;    //offset
  dword siz;    //size of file
} sample;

struct bufs *buf;

dword coff;  //current offset
word cbuf;
dword siz;
int hi,ho,t;
byte str[80];
#define tbufsiz 16*1024
byte tbuf[tbufsiz];
dword a;
word cnt;
dword head1=0x1a4b4150;   //"PAK",26
dword head2=0x1a484150;   //"PAH",26
byte fo[80];
byte fohdr[80];
byte mode;  //0=normal 1=output header to other file

struct ffblk ff;

void main(byte argc,byte **args) {

  dword siz;

  if (argc<2 || argc>3) {
    printf(" PACKIT v2.11 (32bit) by : Peter Quiring\n");
    printf(" Usage: PACKIT fileout [header_fileout]\n");
    exit(0);
  }

  strcpy(fo,args[1]);
  strupr(fo);
  buf=(void*)malloc(sizeof(sample)*65000);
  if ( ((dword)buf)==ERROR) {
    printf("Out of ram...\n");
    abort();
  }

  if (argc==2) mode=0;
  else {
    mode=1;
    strcpy(fohdr,args[2]);
    strupr(fohdr);
  }

  coff=0;    //current offset
  cbuf=0;    //current buffer

  printf("Gathering file info...");
  if (findfirst("*.*",FA_ARCH,&ff)) {
    printf("No files found!");
    exit(0);
  }
  while (1) {
    _int3_();
    strcpy(str,ff.ff_name);
    strupr(str);
    if (!strcmp(str,fo)) {
      if (findnext(&ff)) break;
      continue;
    }
    if (!strcmp(str,fohdr)) {
      if (findnext(&ff)) break;
      continue;
    }
    t=open(str,O_BINARY);
    if (t==-1) {
      printf("\nUnable to open:%s",str);
      exit(0);
    }
    siz=filelength(t);
    memset(buf[cbuf].fn,0,13);
    strcpy(buf[cbuf].fn,str);
    buf[cbuf].fh=0;
    buf[cbuf].off=coff;
    buf[cbuf].siz=siz;
    close(t);
    cbuf++;
    if (cbuf>=65000) {
      printf("File limit: 65000 files");
      abort();
    }
    coff+=siz;
    if (findnext(&ff)) break;
  }
  printf("# files found=%d\n",cbuf);

  if (mode)
    ho=open(fohdr,O_BINARY|O_CREAT|O_TRUNC|O_RDWR);
  else
    ho=open(fo,O_BINARY|O_CREAT|O_TRUNC|O_RDWR);

  if (ho==-1) {
    printf("File I/O error"); exit(0);
  }

  if (!mode) write(ho,&head1,4);

  write(ho,&cbuf,2);   //# of files (part of header)
  buf[cbuf].fn[0]=0;
  /* now create packfile output
  format =
    filename [13]
    handle [2]  ;not used in file
    offset [4]
    size [4]
  */
  if (mode) a=4;
  else a=6+cbuf*23;
  cbuf=0;
  while(buf[cbuf].fn[0]){
    buf[cbuf].off+=a;
    write(ho,&buf[cbuf],sizeof(buf[0]));
    cbuf++;
  }
  if (mode) {
    close(ho);
    ho=open(fo,O_BINARY|O_CREAT|O_TRUNC|O_RDWR);
    if (ho==-1) {
      printf("File I/O error"); exit(0);
    }
    write(ho,&head2,4);
  }
  //output the actual files!
  cbuf=0;
  while(buf[cbuf].fn[0]){
    hi=open(buf[cbuf].fn,O_BINARY|O_RDONLY);
    while (1) {
      a=read(hi,tbuf,tbufsiz);
      if (!a) break;
      write(ho,tbuf,a);
    }
    close(hi);
    printf("%s - done!\n",buf[cbuf].fn);
    cbuf++;
  }
  close(hi);
  printf("\n all done!!\n");
}
[ RETURN TO DIRECTORY ]