CMS 3D CMS Logo

SherpackUtilities.cc
Go to the documentation of this file.
3 #include <unistd.h>
4 #include <cstdlib>
5 namespace spu {
6 
7  // functions for inflating (and deflating)
8 
9  //~ /* Compress from file source to file dest until EOF on source.
10  //~ def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
11  //~ allocated for processing, Z_STREAM_ERROR if an invalid compression
12  //~ level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
13  //~ version of the library linked do not match, or Z_ERRNO if there is
14  //~ an error reading or writing the files. */
15  int def(FILE *source, FILE *dest, int level) {
16  int ret, flush;
17  unsigned have;
18  z_stream strm;
19  unsigned char in[CHUNK];
20  unsigned char out[CHUNK];
21 
22  /* allocate deflate state */
23  strm.zalloc = Z_NULL;
24  strm.zfree = Z_NULL;
25  strm.opaque = Z_NULL;
26  ret = deflateInit(&strm, level);
27  if (ret != Z_OK)
28  return ret;
29 
30  /* compress until end of file */
31  do {
32  strm.avail_in = fread(in, 1, CHUNK, source);
33  if (ferror(source)) {
34  (void)deflateEnd(&strm);
35  return Z_ERRNO;
36  }
37  flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
38  strm.next_in = in;
39 
40  /* run deflate() on input until output buffer not full, finish
41  compression if all of source has been read in */
42  do {
43  strm.avail_out = CHUNK;
44  strm.next_out = out;
45  ret = deflate(&strm, flush); /* no bad return value */
46  assert(ret != Z_STREAM_ERROR); /* state not clobbered */
47  have = CHUNK - strm.avail_out;
48  if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
49  (void)deflateEnd(&strm);
50  return Z_ERRNO;
51  }
52  } while (strm.avail_out == 0);
53  assert(strm.avail_in == 0); /* all input will be used */
54 
55  /* done when last data in file processed */
56  } while (flush != Z_FINISH);
57  assert(ret == Z_STREAM_END); /* stream will be complete */
58 
59  /* clean up and return */
60  (void)deflateEnd(&strm);
61  return Z_OK;
62  }
63 
64  /* Decompress from file source to file dest until stream ends or EOF.
65  inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
66  allocated for processing, Z_DATA_ERROR if the deflate data is
67  invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
68  the version of the library linked do not match, or Z_ERRNO if there
69  is an error reading or writing the files. */
70  int inf(FILE *source, FILE *dest) {
71  int ret;
72  unsigned have;
73  z_stream strm;
74  unsigned char in[CHUNK];
75  unsigned char out[CHUNK];
76 
77  /* allocate inflate state */
78  strm.zalloc = Z_NULL;
79  strm.zfree = Z_NULL;
80  strm.opaque = Z_NULL;
81  strm.avail_in = 0;
82  strm.next_in = Z_NULL;
83  //~ ret = inflateInit(&strm,15);
84  ret = inflateInit2(&strm, (16 + MAX_WBITS));
85  if (ret != Z_OK)
86  return ret;
87 
88  /* decompress until deflate stream ends or end of file */
89  do {
90  strm.avail_in = fread(in, 1, CHUNK, source);
91  if (ferror(source)) {
92  (void)inflateEnd(&strm);
93  return Z_ERRNO;
94  }
95  if (strm.avail_in == 0)
96  break;
97  strm.next_in = in;
98 
99  /* run inflate() on input until output buffer not full */
100  do {
101  strm.avail_out = CHUNK;
102  strm.next_out = out;
103  ret = inflate(&strm, Z_NO_FLUSH);
104  assert(ret != Z_STREAM_ERROR); /* state not clobbered */
105  switch (ret) {
106  case Z_NEED_DICT:
107  ret = Z_DATA_ERROR;
108  [[fallthrough]];
109  case Z_DATA_ERROR:
110  case Z_MEM_ERROR:
111  (void)inflateEnd(&strm);
112  return ret;
113  }
114  have = CHUNK - strm.avail_out;
115  if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
116  (void)inflateEnd(&strm);
117  return Z_ERRNO;
118  }
119  } while (strm.avail_out == 0);
120 
121  /* done when inflate() says it's done */
122  } while (ret != Z_STREAM_END);
123 
124  /* clean up and return */
125  (void)inflateEnd(&strm);
126  return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
127  }
128 
129  /* report a zlib or i/o error */
130  void zerr(int ret) {
131  fputs("zpipe: ", stderr);
132  switch (ret) {
133  case Z_ERRNO:
134  if (ferror(stdin))
135  fputs("error reading stdin\n", stderr);
136  if (ferror(stdout))
137  fputs("error writing stdout\n", stderr);
138  break;
139  case Z_STREAM_ERROR:
140  fputs("invalid compression level\n", stderr);
141  break;
142  case Z_DATA_ERROR:
143  fputs("invalid or incomplete deflate data\n", stderr);
144  break;
145  case Z_MEM_ERROR:
146  fputs("out of memory\n", stderr);
147  break;
148  case Z_VERSION_ERROR:
149  fputs("zlib version mismatch!\n", stderr);
150  }
151  }
152 
153  /* compress or decompress from stdin to stdout */
158  const char *tmpdir = std::getenv("TMPDIR");
159  if (tmpdir && (strlen(tmpdir) > 50)) {
160  setenv("TMPDIR", "/tmp", true);
161  }
165  int ret;
166  FILE *in = fopen(infile.c_str(), "r");
167  if (!in)
168  return -1;
169  FILE *out = fopen(outfile.c_str(), "w");
170  if (!out)
171  return -2;
172  /* avoid end-of-line conversions */
175 
176  ret = inf(in, out);
177  if (ret != Z_OK)
178  zerr(ret);
179 
180  fclose(in);
181  fclose(out);
182  return ret;
183  }
184 
185  // functions for untaring Sherpacks
186  /* Parse an octal number, ignoring leading and trailing nonsense. */
187  int parseoct(const char *p, size_t n) {
188  int i = 0;
189 
190  while (*p < '0' || *p > '7') {
191  ++p;
192  --n;
193  }
194  while (*p >= '0' && *p <= '7' && n > 0) {
195  i *= 8;
196  i += *p - '0';
197  ++p;
198  --n;
199  }
200  return (i);
201  }
202 
203  /* Returns true if this is 512 zero bytes. */
204  int is_end_of_archive(const char *p) {
205  int n;
206  for (n = 511; n >= 0; --n)
207  if (p[n] != '\0')
208  return (0);
209  return (1);
210  }
211 
212  /* Create a directory, including parent directories as necessary. */
213  void create_dir(char *pathname, int mode) {
214  char *p;
215  int r;
216 
217  /* Strip trailing '/' */
218  if (pathname[strlen(pathname) - 1] == '/')
219  pathname[strlen(pathname) - 1] = '\0';
220 
221  /* Try creating the directory. */
222  r = mkdir(pathname, mode);
223 
224  if (r != 0) {
225  /* On failure, try creating parent directory. */
226  p = strrchr(pathname, '/');
227  if (p != nullptr) {
228  *p = '\0';
229  create_dir(pathname, 0755);
230  *p = '/';
231  r = mkdir(pathname, mode);
232  }
233  }
234  if (r != 0)
235  fprintf(stderr, "Could not create directory %s\n", pathname);
236  }
237 
238  /* Create a file, including parent directory as necessary. */
239  FILE *create_file(char *pathname, int mode) {
240  FILE *f;
241  f = fopen(pathname, "w+");
242  if (f == nullptr) {
243  /* Try creating parent dir and then creating file. */
244  char *p = strrchr(pathname, '/');
245  if (p != nullptr) {
246  *p = '\0';
247  create_dir(pathname, 0755);
248  *p = '/';
249  f = fopen(pathname, "w+");
250  }
251  }
252  return (f);
253  }
254 
255  /* Verify the tar checksum. */
256  int verify_checksum(const char *p) {
257  int n, u = 0;
258  for (n = 0; n < 512; ++n) {
259  if (n < 148 || n > 155)
260  /* Standard tar checksum adds unsigned bytes. */
261  u += ((unsigned char *)p)[n];
262  else
263  u += 0x20;
264  }
265  return (u == parseoct(p + 148, 8));
266  }
267 
268  /* Extract a tar archive. */
269  void Untar(FILE *a, const char *path) {
270  bool longpathname = false;
271  bool longlinkname = false;
272  char newlongpathname[512];
273  char newlonglinkname[512];
274  char buff[512];
275  FILE *f = nullptr;
276  size_t bytes_read;
277  int filesize;
278 
279  printf("Extracting from %s\n", path);
280  for (;;) {
281  bytes_read = fread(buff, 1, 512, a);
282  if (bytes_read < 512) {
283  fprintf(stderr, "Short read on %s: expected 512, got %d\n", path, (int)bytes_read);
284  return;
285  }
286  if (is_end_of_archive(buff)) {
287  printf("End of %s\n", path);
288  return;
289  }
290  if (!verify_checksum(buff)) {
291  fprintf(stderr, "Checksum failure\n");
292  return;
293  }
294  filesize = parseoct(buff + 124, 12);
295  // printf("%c %d\n",buff[156],filesize);
296  switch (buff[156]) {
297  case '1':
298  printf(" Ignoring hardlink %s\n", buff);
299  break;
300  case '2':
301  if (longpathname && longlinkname) {
302  longlinkname = false;
303  longpathname = false;
304  printf(" Extracting symlink %s\n", newlongpathname);
305  symlink(newlonglinkname, newlongpathname);
306  } else if (longpathname) {
307  longpathname = false;
308  printf(" Extracting symlink %s\n", newlongpathname);
309  symlink(buff + 157, newlongpathname);
310  } else if (longlinkname) {
311  longlinkname = false;
312  printf(" Extracting symlink %s\n", buff);
313  symlink(newlonglinkname, buff);
314  } else {
315  printf(" Extracting symlink %s\n", buff);
316  symlink(buff + 157, buff);
317  }
318  break;
319  case '3':
320  printf(" Ignoring character device %s\n", buff);
321  break;
322  case '4':
323  printf(" Ignoring block device %s\n", buff);
324  break;
325  case '5':
326  if (!longpathname) {
327  int endposition = -1;
328  for (int k = 99; k >= 0; k--) {
329  if (buff[k] == '\0')
330  endposition = k;
331  }
332  if (endposition == -1) {
333  //~ printf("OLDNAME : %s\n",buff);
334  longpathname = true;
335  for (int k = 0; k < 100; k++) {
336  newlongpathname[k] = buff[k];
337  }
338  newlongpathname[100] = '\0';
339  //~ printf("NEWNAME : %s\n",newlongpathname);
340  }
341  }
342 
343  if (longpathname) {
344  printf(" Extracting dir %s\n", newlongpathname);
345  create_dir(newlongpathname, parseoct(buff + 100, 8));
346  longpathname = false;
347  } else {
348  printf(" Extracting dir %s\n", buff);
349  create_dir(buff, parseoct(buff + 100, 8));
350  }
351  //~ printf(" Extracting dir %s\n", buff);
352  //~ create_dir(buff, parseoct(buff + 100, 8));
353  filesize = 0;
354  break;
355  case '6':
356  printf(" Ignoring FIFO %s\n", buff);
357  break;
358  case 'L':
359  longpathname = true;
360  //~ printf(" Long Filename found 0 %s\n", buff);
361  //~ printf(" Long Filename found 100 %s\n", buff+100);
362  //~ printf(" Long Filename found 108 %s\n", buff+108);
363  //~ printf(" Long Filename found 116 %s\n", buff+116);
364  //~ printf(" Long Filename found 124 %s\n", buff+124);
365  //~ printf(" Long Filename found 136 %s\n", buff+136);
366  //~ printf(" Long Filename found 148 %s\n", buff+148);
367  //~ printf(" Long Filename found 156 %s\n", buff+156);
368  //~ printf(" Long Filename found 157 %s\n", buff+157);
369  //~ printf(" Long Filename found 158 %s\n", buff+158);
370  //~ printf(" Long Filename found 159 %s\n", buff+159);
371  //~ printf(" Long Filename found 257 %s\n", buff+257);
372  //~ printf(" Long Filename found 263 %s\n", buff+263);
373  //~ printf(" Long Filename found 265 %s\n", buff+265);
374  //~ printf(" Long Filename found 297 %s\n", buff+297);
375  //~ printf(" Long Filename found 329 %s\n", buff+329);
376  //~ printf(" Long Filename found 337 %s\n", buff+337);
377  //~ printf(" Long Filename found 345 %s\n", buff+345);
378  //~ printf(" Long Filename found 346 %s\n", buff+346);
379  //~ printf(" Long Filename found 347 %s\n", buff+347);
380  break;
381 
382  case 'K':
383  longlinkname = true;
384  break;
385 
386  default:
387  if (!longpathname) {
388  int endposition = -1;
389  for (int k = 99; k >= 0; k--) {
390  if (buff[k] == '\0')
391  endposition = k;
392  }
393  if (endposition == -1) {
394  //~ printf("OLDNAME : %s\n",buff);
395  longpathname = true;
396  for (int k = 0; k < 100; k++) {
397  newlongpathname[k] = buff[k];
398  }
399  newlongpathname[100] = '\0';
400  //~ printf("NEWNAME : %s\n",newlongpathname);
401  }
402  }
403  if (longpathname) {
404  printf(" Extracting file %s\n", newlongpathname);
405  f = create_file(newlongpathname, parseoct(buff + 100, 8));
406  longpathname = false;
407  } else {
408  printf(" Extracting file %s\n", buff);
409  f = create_file(buff, parseoct(buff + 100, 8));
410  }
411  break;
412  }
413 
414  if (longlinkname || longpathname) {
415  if (buff[156] == 'K') {
416  for (int ll = 0; ll < 512; ll++) {
417  printf("%c", buff[ll]);
418  }
419  printf("\n");
420  bytes_read = fread(buff, 1, 512, a);
421  for (int ll = 0; ll < 512; ll++) {
422  printf("%c", buff[ll]);
423  }
424  printf("\n");
425  for (int k = 0; k < filesize; k++) {
426  newlonglinkname[k] = buff[k];
427  }
428  newlonglinkname[filesize] = '\0';
429  for (int k = filesize + 1; k < 512; k++) {
430  newlonglinkname[k] = '0';
431  }
432  //~ printf("NEW LinkNAME: %s\n",newlonglinkname);
433  } else if (buff[156] == 'L') {
434  bytes_read = fread(buff, 1, 512, a);
435  for (int k = 0; k < filesize; k++) {
436  newlongpathname[k] = buff[k];
437  }
438  newlongpathname[filesize] = '\0';
439  for (int k = filesize + 1; k < 512; k++) {
440  newlongpathname[k] = '0';
441  }
442  //~ printf("NEW FILENAME: %s\n",newlongpathname);
443  }
444  }
445 
446  //~
447  //~ if (longpathname) {
448  //~ bytes_read = fread(buff, 1, 512, a);
449  //~ for (int k=0; k<filesize; k++){
450  //~ newlongpathname[k]=buff[k];
451  //~ }
452  //~ newlongpathname[filesize]='\0';
453  //~ for (int k=filesize+1; k<512; k++){
454  //~ newlongpathname[k]='0';
455  //~ }
456  //~ printf("NEW FILENAME: %s\n",newlongpathname);
457  //~
458  //~ }
459  //~ else if (!longpathname && !longlinkname) {
460  if (!longpathname && !longlinkname) {
461  while (filesize > 0) {
462  bytes_read = fread(buff, 1, 512, a);
463  if (bytes_read < 512) {
464  fprintf(stderr, "Short read on %s: Expected 512, got %d\n", path, (int)bytes_read);
465  return;
466  }
467  if (filesize < 512)
468  bytes_read = filesize;
469  if (f != nullptr) {
470  if (fwrite(buff, 1, bytes_read, f) != bytes_read) {
471  fprintf(stderr, "Failed write\n");
472  fclose(f);
473  f = nullptr;
474  }
475  }
476  filesize -= bytes_read;
477  }
478  if (f != nullptr) {
479  fclose(f);
480  f = nullptr;
481  }
482  }
483  }
484  }
485 
486  // function for calculating the MD5 checksum of a file
488  char buffer[4096];
490  EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
491  const EVP_MD *md = EVP_get_digestbyname("MD5");
492  EVP_DigestInit_ex(mdctx, md, nullptr);
493 
494  //Open File
495  int fd = open(filename.c_str(), O_RDONLY);
496  int nb_read;
497  while ((nb_read = read(fd, buffer, 4096 - 1))) {
498  EVP_DigestUpdate(mdctx, buffer, nb_read);
499  memset(buffer, 0, 4096);
500  }
501 
502  unsigned int md_len = 0;
503  unsigned char tmp[EVP_MAX_MD_SIZE];
504  EVP_DigestFinal_ex(mdctx, tmp, &md_len);
505  EVP_MD_CTX_free(mdctx);
506 
507  //Convert the result
508  for (unsigned int k = 0; k < md_len; ++k) {
509  sprintf(result + k * 2, "%02x", tmp[k]);
510  }
511  }
512 
513 } // End namespace spu
int def(FILE *, FILE *, int)
void openssl_init()
Definition: openssl_init.cc:5
ret
prodAgent to be discontinued
void zerr(int)
void md5_File(std::string, char *)
FILE * create_file(char *, int)
assert(be >=bs)
#define EVP_MD_CTX_free
Definition: openssl_init.h:7
TEMPL(T2) struct Divides void
Definition: Factorize.h:24
int verify_checksum(const char *)
#define EVP_MD_CTX_new
Definition: openssl_init.h:6
#define CHUNK
double f[11][100]
void Untar(FILE *, const char *)
int is_end_of_archive(const char *)
#define SET_BINARY_MODE(file)
int inf(FILE *, FILE *)
def mkdir(path)
Definition: eostools.py:251
double a
Definition: hdecay.h:119
void create_dir(char *, int)
tmp
align.sh
Definition: createJobs.py:716
int parseoct(const char *, size_t)
fd
Definition: ztee.py:136
static std::string const source
Definition: EdmProvDump.cc:49
int Unzip(std::string, std::string)