// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman // Ken Silverman's official web site: "http://www.advsys.net/ken" // See the included license file "BUILDLIC.TXT" for license info. // // This file has been modified from Ken Silverman's original release // by Jonathon Fowler (jf@jonof.id.au) #include "compat.h" // Glibc doesn't provide this function, so for the sake of less ugliess // for all platforms, here's a replacement just for this program. static void jstrupr(char *s) { while (*s) { *s = Btoupper(*s); s++; } } #define MAXFILES 4096 static char buf[65536]; // These limits should be abolished one day static int numfiles; static char filespec[MAXFILES][128], filelist[MAXFILES][16]; static int fileleng[MAXFILES]; static char *matchstr = "*.*"; int checkmatch(const struct Bdirent *a) { if (a->mode & BS_IFDIR) return 0; // is a directory if (a->namlen > 12) return 0; // name too long return Bwildmatch(a->name, matchstr); } int filesize(const char *path, const char *name) { char p[BMAX_PATH]; struct stat st; strcpy(p, path); strcat(p, "/"); strcat(p, name); if (!stat(p, &st)) return st.st_size; return 0; } void findfiles(const char *dafilespec) { struct Bdirent *name; int daspeclen; char daspec[128], *dir; BDIR *di; strcpy(daspec,dafilespec); daspeclen=strlen(daspec); while ((daspec[daspeclen] != '\\') && (daspec[daspeclen] != '/') && (daspeclen > 0)) daspeclen--; if (daspeclen > 0) { daspec[daspeclen]=0; dir = daspec; matchstr = &daspec[daspeclen+1]; } else { dir = "."; matchstr = daspec; } di = Bopendir(dir); if (!di) return; while ((name = Breaddir(di))) { if (!checkmatch(name)) continue; strcpy(&filelist[numfiles][0],name->name); jstrupr(&filelist[numfiles][0]); fileleng[numfiles] = name->size; filelist[numfiles][12] = (char)(fileleng[numfiles]&255); filelist[numfiles][13] = (char)((fileleng[numfiles]>>8)&255); filelist[numfiles][14] = (char)((fileleng[numfiles]>>16)&255); filelist[numfiles][15] = (char)((fileleng[numfiles]>>24)&255); strcpy(filespec[numfiles],dir); strcat(filespec[numfiles], "/"); strcat(filespec[numfiles],name->name); numfiles++; if (numfiles > MAXFILES) { Bprintf("FATAL ERROR: TOO MANY FILES SELECTED! (MAX is 4096)\n"); exit(0); } } Bclosedir(di); } int main(int argc, char **argv) { int i, j, k, l, fil, fil2; if (argc < 3) { Bprintf("KGROUP <@file or filespec...> by Kenneth Silverman\n"); Bprintf(" This program collects many files into 1 big uncompressed file called a\n"); Bprintf(" group file\n"); Bprintf(" Ex: kgroup stuff.dat *.art *.map *.k?? palette.dat tables.dat\n"); Bprintf(" (stuff.dat is the group file, the rest are the files to add)\n"); exit(0); } numfiles = 0; for(i=argc-1;i>1;i--) { if (argv[i][0] == '@') { if ((fil = Bopen(&argv[i][1],BO_BINARY|BO_RDONLY,BS_IREAD)) != -1) { l = Bread(fil,buf,65536); j = 0; while ((j < l) && (buf[j] <= 32)) j++; while (j < l) { k = j; while ((k < l) && (buf[k] > 32)) k++; buf[k] = 0; findfiles(&buf[j]); j = k+1; while ((j < l) && (buf[j] <= 32)) j++; } Bclose(fil); } } else findfiles(argv[i]); } if ((fil = Bopen(argv[1],BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1) { Bprintf("Error: %s could not be opened\n",argv[1]); exit(0); } Bwrite(fil,"KenSilverman",12); Bwrite(fil,&numfiles,4); Bwrite(fil,filelist,numfiles<<4); for(i=0;i