File indexing completed on 2024-11-28 03:54:34
0001 #include "GeneratorInterface/SherpaInterface/interface/SherpackUtilities.h"
0002 #include "Utilities/OpenSSL/interface/openssl_init.h"
0003 #include <unistd.h>
0004 #include <cstdlib>
0005 namespace spu {
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 int def(FILE *source, FILE *dest, int level) {
0016 int ret, flush;
0017 unsigned have;
0018 z_stream strm;
0019 unsigned char in[CHUNK];
0020 unsigned char out[CHUNK];
0021
0022
0023 strm.zalloc = Z_NULL;
0024 strm.zfree = Z_NULL;
0025 strm.opaque = Z_NULL;
0026 ret = deflateInit(&strm, level);
0027 if (ret != Z_OK)
0028 return ret;
0029
0030
0031 do {
0032 strm.avail_in = fread(in, 1, CHUNK, source);
0033 if (ferror(source)) {
0034 (void)deflateEnd(&strm);
0035 return Z_ERRNO;
0036 }
0037 flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
0038 strm.next_in = in;
0039
0040
0041
0042 do {
0043 strm.avail_out = CHUNK;
0044 strm.next_out = out;
0045 ret = deflate(&strm, flush);
0046 assert(ret != Z_STREAM_ERROR);
0047 have = CHUNK - strm.avail_out;
0048 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
0049 (void)deflateEnd(&strm);
0050 return Z_ERRNO;
0051 }
0052 } while (strm.avail_out == 0);
0053 assert(strm.avail_in == 0);
0054
0055
0056 } while (flush != Z_FINISH);
0057 assert(ret == Z_STREAM_END);
0058
0059
0060 (void)deflateEnd(&strm);
0061 return Z_OK;
0062 }
0063
0064
0065
0066
0067
0068
0069
0070 int inf(FILE *source, FILE *dest) {
0071 int ret;
0072 unsigned have;
0073 z_stream strm;
0074 unsigned char in[CHUNK];
0075 unsigned char out[CHUNK];
0076
0077
0078 strm.zalloc = Z_NULL;
0079 strm.zfree = Z_NULL;
0080 strm.opaque = Z_NULL;
0081 strm.avail_in = 0;
0082 strm.next_in = Z_NULL;
0083
0084 ret = inflateInit2(&strm, (16 + MAX_WBITS));
0085 if (ret != Z_OK)
0086 return ret;
0087
0088
0089 do {
0090 strm.avail_in = fread(in, 1, CHUNK, source);
0091 if (ferror(source)) {
0092 (void)inflateEnd(&strm);
0093 return Z_ERRNO;
0094 }
0095 if (strm.avail_in == 0)
0096 break;
0097 strm.next_in = in;
0098
0099
0100 do {
0101 strm.avail_out = CHUNK;
0102 strm.next_out = out;
0103 ret = inflate(&strm, Z_NO_FLUSH);
0104 assert(ret != Z_STREAM_ERROR);
0105 switch (ret) {
0106 case Z_NEED_DICT:
0107 ret = Z_DATA_ERROR;
0108 [[fallthrough]];
0109 case Z_DATA_ERROR:
0110 case Z_MEM_ERROR:
0111 (void)inflateEnd(&strm);
0112 return ret;
0113 }
0114 have = CHUNK - strm.avail_out;
0115 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
0116 (void)inflateEnd(&strm);
0117 return Z_ERRNO;
0118 }
0119 } while (strm.avail_out == 0);
0120
0121
0122 } while (ret != Z_STREAM_END);
0123
0124
0125 (void)inflateEnd(&strm);
0126 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
0127 }
0128
0129
0130 void zerr(int ret) {
0131 fputs("zpipe: ", stderr);
0132 switch (ret) {
0133 case Z_ERRNO:
0134 if (ferror(stdin))
0135 fputs("error reading stdin\n", stderr);
0136 if (ferror(stdout))
0137 fputs("error writing stdout\n", stderr);
0138 break;
0139 case Z_STREAM_ERROR:
0140 fputs("invalid compression level\n", stderr);
0141 break;
0142 case Z_DATA_ERROR:
0143 fputs("invalid or incomplete deflate data\n", stderr);
0144 break;
0145 case Z_MEM_ERROR:
0146 fputs("out of memory\n", stderr);
0147 break;
0148 case Z_VERSION_ERROR:
0149 fputs("zlib version mismatch!\n", stderr);
0150 }
0151 }
0152
0153
0154 int Unzip(std::string infile, std::string outfile) {
0155
0156
0157
0158 const char *tmpdir = std::getenv("TMPDIR");
0159 if (tmpdir && (strlen(tmpdir) > 50)) {
0160 setenv("TMPDIR", "/tmp", true);
0161 }
0162
0163
0164
0165 int ret;
0166 FILE *in = fopen(infile.c_str(), "r");
0167 if (!in)
0168 return -1;
0169 FILE *out = fopen(outfile.c_str(), "w");
0170 if (!out)
0171 return -2;
0172
0173 SET_BINARY_MODE(in);
0174 SET_BINARY_MODE(out);
0175
0176 ret = inf(in, out);
0177 if (ret != Z_OK)
0178 zerr(ret);
0179
0180 fclose(in);
0181 fclose(out);
0182 return ret;
0183 }
0184
0185
0186
0187 int parseoct(const char *p, size_t n) {
0188 int i = 0;
0189
0190 while (*p < '0' || *p > '7') {
0191 ++p;
0192 --n;
0193 }
0194 while (*p >= '0' && *p <= '7' && n > 0) {
0195 i *= 8;
0196 i += *p - '0';
0197 ++p;
0198 --n;
0199 }
0200 return (i);
0201 }
0202
0203
0204 int is_end_of_archive(const char *p) {
0205 int n;
0206 for (n = 511; n >= 0; --n)
0207 if (p[n] != '\0')
0208 return (0);
0209 return (1);
0210 }
0211
0212
0213 void create_dir(char *pathname, int mode) {
0214 char *p;
0215 int r;
0216
0217
0218 if (pathname[strlen(pathname) - 1] == '/')
0219 pathname[strlen(pathname) - 1] = '\0';
0220
0221
0222 r = mkdir(pathname, mode);
0223
0224 if (r != 0) {
0225
0226 p = strrchr(pathname, '/');
0227 if (p != nullptr) {
0228 *p = '\0';
0229 create_dir(pathname, 0755);
0230 *p = '/';
0231 r = mkdir(pathname, mode);
0232 }
0233 }
0234 if (r != 0)
0235 fprintf(stderr, "Could not create directory %s\n", pathname);
0236 }
0237
0238
0239 FILE *create_file(char *pathname, int mode) {
0240 FILE *f;
0241 f = fopen(pathname, "w+");
0242 if (f == nullptr) {
0243
0244 char *p = strrchr(pathname, '/');
0245 if (p != nullptr) {
0246 *p = '\0';
0247 create_dir(pathname, 0755);
0248 *p = '/';
0249 f = fopen(pathname, "w+");
0250 }
0251 }
0252 return (f);
0253 }
0254
0255
0256 int verify_checksum(const char *p) {
0257 int n, u = 0;
0258 for (n = 0; n < 512; ++n) {
0259 if (n < 148 || n > 155)
0260
0261 u += ((unsigned char *)p)[n];
0262 else
0263 u += 0x20;
0264 }
0265 return (u == parseoct(p + 148, 8));
0266 }
0267
0268
0269 void Untar(FILE *a, const char *path) {
0270 bool longpathname = false;
0271 bool longlinkname = false;
0272 char newlongpathname[512];
0273 char newlonglinkname[512];
0274 char buff[512];
0275 FILE *f = nullptr;
0276 size_t bytes_read;
0277 int filesize;
0278
0279 printf("Extracting from %s\n", path);
0280 for (;;) {
0281 bytes_read = fread(buff, 1, 512, a);
0282 if (bytes_read < 512) {
0283 fprintf(stderr, "Short read on %s: expected 512, got %d\n", path, (int)bytes_read);
0284 return;
0285 }
0286 if (is_end_of_archive(buff)) {
0287 printf("End of %s\n", path);
0288 return;
0289 }
0290 if (!verify_checksum(buff)) {
0291 fprintf(stderr, "Checksum failure\n");
0292 return;
0293 }
0294 filesize = parseoct(buff + 124, 12);
0295
0296 switch (buff[156]) {
0297 case '1':
0298 printf(" Ignoring hardlink %s\n", buff);
0299 break;
0300 case '2':
0301 if (longpathname && longlinkname) {
0302 longlinkname = false;
0303 longpathname = false;
0304 printf(" Extracting symlink %s\n", newlongpathname);
0305 symlink(newlonglinkname, newlongpathname);
0306 } else if (longpathname) {
0307 longpathname = false;
0308 printf(" Extracting symlink %s\n", newlongpathname);
0309 symlink(buff + 157, newlongpathname);
0310 } else if (longlinkname) {
0311 longlinkname = false;
0312 printf(" Extracting symlink %s\n", buff);
0313 symlink(newlonglinkname, buff);
0314 } else {
0315 printf(" Extracting symlink %s\n", buff);
0316 symlink(buff + 157, buff);
0317 }
0318 break;
0319 case '3':
0320 printf(" Ignoring character device %s\n", buff);
0321 break;
0322 case '4':
0323 printf(" Ignoring block device %s\n", buff);
0324 break;
0325 case '5':
0326 if (!longpathname) {
0327 int endposition = -1;
0328 for (int k = 99; k >= 0; k--) {
0329 if (buff[k] == '\0')
0330 endposition = k;
0331 }
0332 if (endposition == -1) {
0333
0334 longpathname = true;
0335 for (int k = 0; k < 100; k++) {
0336 newlongpathname[k] = buff[k];
0337 }
0338 newlongpathname[100] = '\0';
0339
0340 }
0341 }
0342
0343 if (longpathname) {
0344 printf(" Extracting dir %s\n", newlongpathname);
0345 create_dir(newlongpathname, parseoct(buff + 100, 8));
0346 longpathname = false;
0347 } else {
0348 printf(" Extracting dir %s\n", buff);
0349 create_dir(buff, parseoct(buff + 100, 8));
0350 }
0351
0352
0353 filesize = 0;
0354 break;
0355 case '6':
0356 printf(" Ignoring FIFO %s\n", buff);
0357 break;
0358 case 'L':
0359 longpathname = true;
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 break;
0381
0382 case 'K':
0383 longlinkname = true;
0384 break;
0385
0386 default:
0387 if (!longpathname) {
0388 int endposition = -1;
0389 for (int k = 99; k >= 0; k--) {
0390 if (buff[k] == '\0')
0391 endposition = k;
0392 }
0393 if (endposition == -1) {
0394
0395 longpathname = true;
0396 for (int k = 0; k < 100; k++) {
0397 newlongpathname[k] = buff[k];
0398 }
0399 newlongpathname[100] = '\0';
0400
0401 }
0402 }
0403 if (longpathname) {
0404 printf(" Extracting file %s\n", newlongpathname);
0405 f = create_file(newlongpathname, parseoct(buff + 100, 8));
0406 longpathname = false;
0407 } else {
0408 printf(" Extracting file %s\n", buff);
0409 f = create_file(buff, parseoct(buff + 100, 8));
0410 }
0411 break;
0412 }
0413
0414 if (longlinkname || longpathname) {
0415 if (buff[156] == 'K') {
0416 for (int ll = 0; ll < 512; ll++) {
0417 printf("%c", buff[ll]);
0418 }
0419 printf("\n");
0420 for (int ll = 0; ll < 512; ll++) {
0421 printf("%c", buff[ll]);
0422 }
0423 printf("\n");
0424 for (int k = 0; k < filesize; k++) {
0425 newlonglinkname[k] = buff[k];
0426 }
0427 newlonglinkname[filesize] = '\0';
0428 for (int k = filesize + 1; k < 512; k++) {
0429 newlonglinkname[k] = '0';
0430 }
0431
0432 } else if (buff[156] == 'L') {
0433 for (int k = 0; k < filesize; k++) {
0434 newlongpathname[k] = buff[k];
0435 }
0436 newlongpathname[filesize] = '\0';
0437 for (int k = filesize + 1; k < 512; k++) {
0438 newlongpathname[k] = '0';
0439 }
0440
0441 }
0442 }
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458 if (!longpathname && !longlinkname) {
0459 while (filesize > 0) {
0460 bytes_read = fread(buff, 1, 512, a);
0461 if (bytes_read < 512) {
0462 fprintf(stderr, "Short read on %s: Expected 512, got %d\n", path, (int)bytes_read);
0463 return;
0464 }
0465 if (filesize < 512)
0466 bytes_read = filesize;
0467 if (f != nullptr) {
0468 if (fwrite(buff, 1, bytes_read, f) != bytes_read) {
0469 fprintf(stderr, "Failed write\n");
0470 fclose(f);
0471 f = nullptr;
0472 }
0473 }
0474 filesize -= bytes_read;
0475 }
0476 if (f != nullptr) {
0477 fclose(f);
0478 f = nullptr;
0479 }
0480 }
0481 }
0482 }
0483
0484
0485 void md5_File(std::string filename, char *result) {
0486 char buffer[4096];
0487 cms::openssl_init();
0488 EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
0489 const EVP_MD *md = EVP_get_digestbyname("MD5");
0490 EVP_DigestInit_ex(mdctx, md, nullptr);
0491
0492
0493 int fd = open(filename.c_str(), O_RDONLY);
0494 int nb_read;
0495 while ((nb_read = read(fd, buffer, 4096 - 1))) {
0496 EVP_DigestUpdate(mdctx, buffer, nb_read);
0497 memset(buffer, 0, 4096);
0498 }
0499
0500 unsigned int md_len = 0;
0501 unsigned char tmp[EVP_MAX_MD_SIZE];
0502 EVP_DigestFinal_ex(mdctx, tmp, &md_len);
0503 EVP_MD_CTX_free(mdctx);
0504
0505 assert(result);
0506
0507 for (unsigned int k = 0; k < md_len; ++k) {
0508 sprintf(result + k * 2, "%02x", tmp[k]);
0509 }
0510 }
0511
0512 }