00001 #include "GeneratorInterface/SherpaInterface/interface/SherpackUtilities.h"
00002 #include <unistd.h>
00003 namespace spu {
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 int def(FILE *source, FILE *dest, int level)
00014 {
00015 int ret, flush;
00016 unsigned have;
00017 z_stream strm;
00018 unsigned char in[CHUNK];
00019 unsigned char out[CHUNK];
00020
00021
00022 strm.zalloc = Z_NULL;
00023 strm.zfree = Z_NULL;
00024 strm.opaque = Z_NULL;
00025 ret = deflateInit(&strm, level);
00026 if (ret != Z_OK)
00027 return ret;
00028
00029
00030 do {
00031 strm.avail_in = fread(in, 1, CHUNK, source);
00032 if (ferror(source)) {
00033 (void)deflateEnd(&strm);
00034 return Z_ERRNO;
00035 }
00036 flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
00037 strm.next_in = in;
00038
00039
00040
00041 do {
00042 strm.avail_out = CHUNK;
00043 strm.next_out = out;
00044 ret = deflate(&strm, flush);
00045 assert(ret != Z_STREAM_ERROR);
00046 have = CHUNK - strm.avail_out;
00047 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
00048 (void)deflateEnd(&strm);
00049 return Z_ERRNO;
00050 }
00051 } while (strm.avail_out == 0);
00052 assert(strm.avail_in == 0);
00053
00054
00055 } while (flush != Z_FINISH);
00056 assert(ret == Z_STREAM_END);
00057
00058
00059 (void)deflateEnd(&strm);
00060 return Z_OK;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 int inf(FILE *source, FILE *dest)
00070 {
00071 int ret;
00072 unsigned have;
00073 z_stream strm;
00074 unsigned char in[CHUNK];
00075 unsigned char out[CHUNK];
00076
00077
00078 strm.zalloc = Z_NULL;
00079 strm.zfree = Z_NULL;
00080 strm.opaque = Z_NULL;
00081 strm.avail_in = 0;
00082 strm.next_in = Z_NULL;
00083
00084 ret = inflateInit2(&strm, (16+MAX_WBITS));
00085 if (ret != Z_OK)
00086 return ret;
00087
00088
00089 do {
00090 strm.avail_in = fread(in, 1, CHUNK, source);
00091 if (ferror(source)) {
00092 (void)inflateEnd(&strm);
00093 return Z_ERRNO;
00094 }
00095 if (strm.avail_in == 0)
00096 break;
00097 strm.next_in = in;
00098
00099
00100 do {
00101 strm.avail_out = CHUNK;
00102 strm.next_out = out;
00103 ret = inflate(&strm, Z_NO_FLUSH);
00104 assert(ret != Z_STREAM_ERROR);
00105 switch (ret) {
00106 case Z_NEED_DICT:
00107 ret = Z_DATA_ERROR;
00108 case Z_DATA_ERROR:
00109 case Z_MEM_ERROR:
00110 (void)inflateEnd(&strm);
00111 return ret;
00112 }
00113 have = CHUNK - strm.avail_out;
00114 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
00115 (void)inflateEnd(&strm);
00116 return Z_ERRNO;
00117 }
00118 } while (strm.avail_out == 0);
00119
00120
00121 } while (ret != Z_STREAM_END);
00122
00123
00124 (void)inflateEnd(&strm);
00125 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
00126 }
00127
00128
00129 void zerr(int ret)
00130 {
00131 fputs("zpipe: ", stderr);
00132 switch (ret) {
00133 case Z_ERRNO:
00134 if (ferror(stdin))
00135 fputs("error reading stdin\n", stderr);
00136 if (ferror(stdout))
00137 fputs("error writing stdout\n", stderr);
00138 break;
00139 case Z_STREAM_ERROR:
00140 fputs("invalid compression level\n", stderr);
00141 break;
00142 case Z_DATA_ERROR:
00143 fputs("invalid or incomplete deflate data\n", stderr);
00144 break;
00145 case Z_MEM_ERROR:
00146 fputs("out of memory\n", stderr);
00147 break;
00148 case Z_VERSION_ERROR:
00149 fputs("zlib version mismatch!\n", stderr);
00150 }
00151 }
00152
00153
00154 int Unzip(std::string infile, std::string outfile)
00155 {
00156 int ret;
00157 FILE *in = fopen(infile.c_str(),"r");
00158 if (!in) return -1;
00159 FILE *out = fopen(outfile.c_str(),"w");
00160 if (!out) return -2;
00161
00162 SET_BINARY_MODE(in);
00163 SET_BINARY_MODE(out);
00164
00165 ret = inf(in, out);
00166 if (ret != Z_OK)
00167 zerr(ret);
00168
00169 fclose(in);
00170 fclose(out);
00171 return ret;
00172 }
00173
00174
00175
00176
00177
00178 int parseoct(const char *p, size_t n) {
00179 int i = 0;
00180
00181 while (*p < '0' || *p > '7') {
00182 ++p;
00183 --n;
00184 }
00185 while (*p >= '0' && *p <= '7' && n > 0) {
00186 i *= 8;
00187 i += *p - '0';
00188 ++p;
00189 --n;
00190 }
00191 return (i);
00192 }
00193
00194
00195 int is_end_of_archive(const char *p) {
00196 int n;
00197 for (n = 511; n >= 0; --n)
00198 if (p[n] != '\0')
00199 return (0);
00200 return (1);
00201 }
00202
00203
00204 void create_dir(char *pathname, int mode) {
00205 char *p;
00206 int r;
00207
00208
00209 if (pathname[strlen(pathname) - 1] == '/')
00210 pathname[strlen(pathname) - 1] = '\0';
00211
00212
00213 r = mkdir(pathname, mode);
00214
00215 if (r != 0) {
00216
00217 p = strrchr(pathname, '/');
00218 if (p != NULL) {
00219 *p = '\0';
00220 create_dir(pathname, 0755);
00221 *p = '/';
00222 r = mkdir(pathname, mode);
00223 }
00224 }
00225 if (r != 0)
00226 fprintf(stderr, "Could not create directory %s\n", pathname);
00227 }
00228
00229
00230 FILE* create_file(char *pathname, int mode) {
00231 FILE *f;
00232 f = fopen(pathname, "w+");
00233 if (f == NULL) {
00234
00235 char *p = strrchr(pathname, '/');
00236 if (p != NULL) {
00237 *p = '\0';
00238 create_dir(pathname, 0755);
00239 *p = '/';
00240 f = fopen(pathname, "w+");
00241 }
00242 }
00243 return (f);
00244 }
00245
00246
00247 int verify_checksum(const char *p) {
00248 int n, u = 0;
00249 for (n = 0; n < 512; ++n) {
00250 if (n < 148 || n > 155)
00251
00252 u += ((unsigned char *)p)[n];
00253 else
00254 u += 0x20;
00255
00256 }
00257 return (u == parseoct(p + 148, 8));
00258 }
00259
00260
00261 void Untar(FILE *a, const char *path) {
00262 bool longpathname=false;
00263 bool longlinkname=false;
00264 char newlongpathname[512];
00265 char newlonglinkname[512];
00266 char buff[512];
00267 FILE *f = NULL;
00268 size_t bytes_read;
00269 int filesize;
00270
00271 printf("Extracting from %s\n", path);
00272 for (;;) {
00273
00274 bytes_read = fread(buff, 1, 512, a);
00275 if (bytes_read < 512) {
00276 fprintf(stderr,
00277 "Short read on %s: expected 512, got %d\n",path, (int)bytes_read);
00278 return;
00279 }
00280 if (is_end_of_archive(buff)) {
00281 printf("End of %s\n", path);
00282 return;
00283 }
00284 if (!verify_checksum(buff)) {
00285 fprintf(stderr, "Checksum failure\n");
00286 return;
00287 }
00288 filesize = parseoct(buff + 124, 12);
00289
00290 switch (buff[156]) {
00291 case '1':
00292 printf(" Ignoring hardlink %s\n", buff);
00293 break;
00294 case '2':
00295 if (longpathname && longlinkname){
00296 longlinkname=false;
00297 longpathname=false;
00298 printf(" Extracting symlink %s\n", newlongpathname);
00299 symlink(newlonglinkname,newlongpathname);
00300 } else if (longpathname) {
00301 longpathname=false;
00302 printf(" Extracting symlink %s\n", newlongpathname);
00303 symlink(buff+157,newlongpathname);
00304 } else if (longlinkname) {
00305 longlinkname=false;
00306 printf(" Extracting symlink %s\n", buff);
00307 symlink(newlonglinkname,buff);
00308 } else {
00309 printf(" Extracting symlink %s\n", buff);
00310 symlink(buff+157,buff);
00311 }
00312 break;
00313 case '3':
00314 printf(" Ignoring character device %s\n", buff);
00315 break;
00316 case '4':
00317 printf(" Ignoring block device %s\n", buff);
00318 break;
00319 case '5':
00320 if (!longpathname){
00321 int endposition=-1;
00322 for (int k=99; k>=0; k--){
00323 if (buff[k]=='\0') endposition=k;
00324 }
00325 if (endposition==-1) {
00326
00327 longpathname=true;
00328 for (int k=0; k<100; k++){
00329 newlongpathname[k]=buff[k];
00330 }
00331 newlongpathname[100]='\0';
00332
00333 }
00334 }
00335
00336 if (longpathname) {
00337 printf(" Extracting dir %s\n", newlongpathname);
00338 create_dir(newlongpathname, parseoct(buff + 100, 8));
00339 longpathname=false;
00340 } else {
00341
00342 printf(" Extracting dir %s\n", buff);
00343 create_dir(buff, parseoct(buff + 100, 8));
00344 }
00345
00346
00347 filesize = 0;
00348 break;
00349 case '6':
00350 printf(" Ignoring FIFO %s\n", buff);
00351 break;
00352 case 'L':
00353 longpathname=true;
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 break;
00375
00376 case 'K':
00377 longlinkname=true;
00378 break;
00379
00380 default:
00381 if (!longpathname){
00382 int endposition=-1;
00383 for (int k=99; k>=0; k--){
00384 if (buff[k]=='\0') endposition=k;
00385 }
00386 if (endposition==-1) {
00387
00388 longpathname=true;
00389 for (int k=0; k<100; k++){
00390 newlongpathname[k]=buff[k];
00391 }
00392 newlongpathname[100]='\0';
00393
00394 }
00395 }
00396 if (longpathname) {
00397 printf(" Extracting file %s\n", newlongpathname);
00398 f = create_file(newlongpathname, parseoct(buff + 100, 8));
00399 longpathname=false;
00400 } else {
00401
00402 printf(" Extracting file %s\n", buff);
00403 f = create_file(buff, parseoct(buff + 100, 8));
00404 }
00405 break;
00406 }
00407
00408 if (longlinkname || longpathname) {
00409 if (buff[156]=='K'){
00410
00411 for (int ll=0; ll<512; ll++){ printf("%c",buff[ll]);} printf("\n");
00412 bytes_read = fread(buff, 1, 512, a);
00413 for (int ll=0; ll<512; ll++){ printf("%c",buff[ll]);} printf("\n");
00414 for (int k=0; k<filesize; k++){
00415 newlonglinkname[k]=buff[k];
00416 }
00417 newlonglinkname[filesize]='\0';
00418 for (int k=filesize+1; k<512; k++){
00419 newlonglinkname[k]='0';
00420 }
00421
00422 } else if (buff[156]=='L'){
00423 bytes_read = fread(buff, 1, 512, a);
00424 for (int k=0; k<filesize; k++){
00425 newlongpathname[k]=buff[k];
00426 }
00427 newlongpathname[filesize]='\0';
00428 for (int k=filesize+1; k<512; k++){
00429 newlongpathname[k]='0';
00430 }
00431
00432 }
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 if (!longpathname && !longlinkname) {
00450 while (filesize > 0) {
00451 bytes_read = fread(buff, 1, 512, a);
00452 if (bytes_read < 512) {
00453 fprintf(stderr,
00454 "Short read on %s: Expected 512, got %d\n", path, (int)bytes_read);
00455 return;
00456 }
00457 if (filesize < 512)
00458 bytes_read = filesize;
00459 if (f != NULL) {
00460 if (fwrite(buff, 1, bytes_read, f)
00461 != bytes_read)
00462 {
00463 fprintf(stderr, "Failed write\n");
00464 fclose(f);
00465 f = NULL;
00466 }
00467 }
00468 filesize -= bytes_read;
00469 }
00470 if (f != NULL) {
00471 fclose(f);
00472 f = NULL;
00473 }
00474 }
00475 }
00476 }
00477
00478
00479
00480
00481 void md5_File(std::string filename, char* result ) {
00482 char buffer[4096];
00483 MD5_CTX md5;
00484 MD5_Init(&md5);
00485
00486
00487 int fd = open(filename.c_str(), O_RDONLY);
00488 int nb_read;
00489 while ((nb_read = read(fd, buffer, 4096 - 1)))
00490 {
00491 MD5_Update(&md5, buffer, nb_read);
00492 memset(buffer, 0, 4096);
00493 }
00494 unsigned char tmp[MD5_DIGEST_LENGTH];
00495 MD5_Final(tmp, &md5);
00496
00497
00498 for (int k = 0; k < MD5_DIGEST_LENGTH; ++k) {
00499 sprintf(result + k * 2, "%02x", tmp[k]);
00500 }
00501 }
00502
00503
00504 }
00505