kgroup.cpp
1 // "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman 2 // Ken Silverman's official web site: "http://www.advsys.net/ken" 3 // See the included license file "BUILDLIC.TXT" for license info. 4 // 5 // This file has been modified from Ken Silverman's original release 6 // by Jonathon Fowler (jf@jonof.id.au) 7 8 #include "compat.h" 9 #include "kplib.h" 10 11 // Glibc doesn't provide this function, so for the sake of less ugliess 12 // for all platforms, here's a replacement just for this program. 13 static void jstrupr(char *s) { while (*s) { *s = Btoupper(*s); s++; } } 14 15 #define MAXFILES 4096 16 17 static char buf[65536]; // These limits should be abolished one day 18 19 static int numfiles; 20 static char filespec[MAXFILES][128], filelist[MAXFILES][16]; 21 static int fileleng[MAXFILES]; 22 23 24 static char const * matchstr = "*.*"; 25 int checkmatch(const struct Bdirent *a) 26 { 27 if (a->mode & BS_IFDIR) return 0; // is a directory 28 if (a->namlen > 12) return 0; // name too long 29 return Bwildmatch(a->name, matchstr); 30 } 31 32 int filesize(const char *path, const char *name) 33 { 34 char p[BMAX_PATH]; 35 struct stat st; 36 37 strcpy(p, path); 38 strcat(p, "/"); 39 strcat(p, name); 40 41 if (!stat(p, &st)) return st.st_size; 42 return 0; 43 } 44 45 void findfiles(const char *dafilespec) 46 { 47 struct Bdirent *name; 48 int daspeclen; 49 char daspec[128]; 50 char const * dir; 51 BDIR *di; 52 53 strcpy(daspec,dafilespec); 54 daspeclen=strlen(daspec); 55 while ((daspec[daspeclen] != '\\') && (daspec[daspeclen] != '/') && (daspeclen > 0)) daspeclen--; 56 if (daspeclen > 0) { 57 daspec[daspeclen]=0; 58 dir = daspec; 59 matchstr = &daspec[daspeclen+1]; 60 } else { 61 dir = "."; 62 matchstr = daspec; 63 } 64 65 di = Bopendir(dir); 66 if (!di) return; 67 68 while ((name = Breaddir(di))) { 69 if (!checkmatch(name)) continue; 70 71 strcpy(&filelist[numfiles][0],name->name); 72 jstrupr(&filelist[numfiles][0]); 73 fileleng[numfiles] = name->size; 74 filelist[numfiles][12] = (char)(fileleng[numfiles]&255); 75 filelist[numfiles][13] = (char)((fileleng[numfiles]>>8)&255); 76 filelist[numfiles][14] = (char)((fileleng[numfiles]>>16)&255); 77 filelist[numfiles][15] = (char)((fileleng[numfiles]>>24)&255); 78 79 strcpy(filespec[numfiles],dir); 80 strcat(filespec[numfiles], "/"); 81 strcat(filespec[numfiles],name->name); 82 83 numfiles++; 84 if (numfiles > MAXFILES) 85 { 86 Bprintf("FATAL ERROR: TOO MANY FILES SELECTED! (MAX is 4096)\n"); 87 exit(0); 88 } 89 } 90 91 Bclosedir(di); 92 } 93 94 int main(int argc, char **argv) 95 { 96 int i, j, k, l, fil, fil2; 97 98 if (argc < 3) 99 { 100 Bprintf("KGROUP <grouped file><@file or filespec...> by Kenneth Silverman\n"); 101 Bprintf(" This program collects many files into 1 big uncompressed file called a\n"); 102 Bprintf(" group file\n"); 103 Bprintf(" Ex: kgroup stuff.dat *.art *.map *.k?? palette.dat tables.dat\n"); 104 Bprintf(" (stuff.dat is the group file, the rest are the files to add)\n"); 105 exit(0); 106 } 107 108 engineCreateAllocator(); 109 110 numfiles = 0; 111 for(i=argc-1;i>1;i--) 112 { 113 if (argv[i][0] == '@') 114 { 115 if ((fil = Bopen(&argv[i][1],BO_BINARY|BO_RDONLY,BS_IREAD)) != -1) 116 { 117 l = Bread(fil,buf,65536); 118 j = 0; 119 while ((j < l) && (buf[j] <= 32)) j++; 120 while (j < l) 121 { 122 k = j; 123 while ((k < l) && (buf[k] > 32)) k++; 124 125 buf[k] = 0; 126 findfiles(&buf[j]); 127 j = k+1; 128 129 while ((j < l) && (buf[j] <= 32)) j++; 130 } 131 Bclose(fil); 132 } 133 } 134 else 135 findfiles(argv[i]); 136 } 137 138 if ((fil = Bopen(argv[1],BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1) 139 { 140 Bprintf("Error: %s could not be opened\n",argv[1]); 141 exit(0); 142 } 143 Bwrite(fil,"KenSilverman",12); 144 Bwrite(fil,&numfiles,4); 145 Bwrite(fil,filelist,numfiles<<4); 146 147 for(i=0;i<numfiles;i++) 148 { 149 Bprintf("Adding %s...\n",filespec[i]); 150 if ((fil2 = Bopen(filespec[i],BO_BINARY|BO_RDONLY,BS_IREAD)) == -1) 151 { 152 Bprintf("Error: %s not found\n",filespec[i]); 153 Bclose(fil); 154 return(0); 155 } 156 for(j=0;j<fileleng[i];j+=65536) 157 { 158 k = min(fileleng[i]-j,65536); 159 Bread(fil2,buf,k); 160 if (Bwrite(fil,buf,k) < k) 161 { 162 Bclose(fil2); 163 Bclose(fil); 164 Bprintf("OUT OF HD SPACE!\n"); 165 return(0); 166 } 167 } 168 Bclose(fil2); 169 } 170 Bclose(fil); 171 Bprintf("Saved to %s.\n",argv[1]); 172 173 return 0; 174 } 175