CMS 3D CMS Logo

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