FOSSology  4.4.0
Open Source License Compliance by Open Source Software
traverse.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2011 Hewlett-Packard Development Company, L.P.
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
12 #include "ununpack.h"
13 #include "externs.h"
14 
23 void TraverseStart (char *Filename, char *Label, char *NewDir,
24  int Recurse)
25 {
26  dirlist *DLhead, *DLentry;
27  char Name[FILENAME_MAX];
28  char *Basename; /* the filename without the path */
29  ParentInfo PI;
30 
31  PI.Cmd = 0;
32  PI.StartTime = time(NULL);
33  PI.EndTime = PI.StartTime;
34  PI.uploadtree_pk = 0;
35  Basename = strrchr(Filename,'/');
36  if (Basename) Basename++;
37  else Basename = Filename;
38  memset(SQL,'\0',MAXSQL);
39  if (!IsDir(Filename))
40  {
41  memset(Name,'\0',sizeof(Name));
42  strcpy(Name,Filename);
43  Traverse(Filename,Basename,Label,NewDir,Recurse,&PI);
44  }
45  else /* process directory */
46  {
47  DLhead = MakeDirList(Filename);
48  for(DLentry=DLhead; DLentry; DLentry=DLentry->Next)
49  {
50  /* Now process the filename */
51  memset(Name,'\0',sizeof(Name));
52  strcpy(Name,Filename);
53  if (Last(Name) != '/') strcat(Name,"/");
54  strcat(Name,DLentry->Name);
55  TraverseStart(Name,Label,NewDir,Recurse);
56  }
57  FreeDirList(DLhead);
58  }
59 
60  /* remove anything that we needed to create */
61  if (UnlinkAll)
62  {
63  struct stat Src,Dst;
64  int i;
65  /* build the destination name */
66  SetDir(Name,sizeof(Name),NewDir,Basename);
67  for(i=strlen(Filename)-1; (i>=0) && (Filename[i] != '/'); i--)
68  ;
69  if (strcmp(Filename+i+1,".")) strcat(Name,Filename+i+1);
70  lstat(Filename,&Src);
71  lstat(Name,&Dst);
72 #if 0
73  printf("End:\n");
74  printf(" Src: %ld %s\n",(long)Src.st_ino,Filename);
75  printf(" Dst: %ld %s\n",(long)Dst.st_ino,Name);
76 #endif
77  /* only delete them if they are different! (Different inodes) */
78  if (Src.st_ino != Dst.st_ino)
79  {
80  if (IsDir(Name)) rmdir(Name);
81  else unlink(Name);
82  }
83  } /* if UnlinkAll */
84 } /* TraverseStart() */
85 
86 
96 void TraverseChild (int Index, ContainerInfo *CI, char *NewDir)
97 {
98  int rc;
99  int PlainCopy=0;
100  cmdtype Type;
101  Type = CMD[CI->PI.Cmd].Type;
102  if (CMD[CI->PI.Cmd].Status == 0) Type=CMD_DEFAULT;
103  switch(Type)
104  {
105  case CMD_PACK:
126  if (CI->TopContainer && UseRepository)
127  {
129  memcpy(CI->PartnameNew, UploadFileName, sizeof(CI->PartnameNew));
130  CI->PartnameNew[sizeof(CI->PartnameNew)-1] = 0;
131  }
132  else
145  {
148  }
149 
150  /* unpack in a sub-directory */
151  rc=RunCommand(CMD[CI->PI.Cmd].Cmd,CMD[CI->PI.Cmd].CmdPre,CI->Source,
152  CMD[CI->PI.Cmd].CmdPost,CI->PartnameNew,Queue[Index].ChildRecurse);
153  break;
154  case CMD_RPM:
155  /* unpack in the current directory */
156  rc=RunCommand(CMD[CI->PI.Cmd].Cmd,CMD[CI->PI.Cmd].CmdPre,CI->Source,
157  CMD[CI->PI.Cmd].CmdPost,CI->PartnameNew,CI->Partdir);
158  break;
159  case CMD_ARC:
160  case CMD_PARTITION:
161  /* unpack in a sub-directory */
162  rc=RunCommand(CMD[CI->PI.Cmd].Cmd,CMD[CI->PI.Cmd].CmdPre,CI->Source,
163  CMD[CI->PI.Cmd].CmdPost,CI->PartnameNew,Queue[Index].ChildRecurse);
164  if (!strcmp(CMD[CI->PI.Cmd].Magic,"application/x-zip") &&
165  ((rc==1) || (rc==2) || (rc==51)) )
166  {
167  LOG_WARNING("pfile %s Minor zip error(%d)... ignoring error.",Pfile_Pk,rc)
168  rc=0; /* lots of zip return codes */
169  }
170  break;
171  case CMD_AR:
172  /* unpack an AR: source file and destination directory */
173  rc=ExtractAR(CI->Source,Queue[Index].ChildRecurse);
174  break;
175  case CMD_ISO:
176  /* unpack an ISO: source file and destination directory */
177  rc=ExtractISO(CI->Source,Queue[Index].ChildRecurse);
178  break;
179  case CMD_DISK:
180  /* unpack a DISK: source file, FS type, and destination directory */
181  rc=ExtractDisk(CI->Source,CMD[CI->PI.Cmd].Cmd,Queue[Index].ChildRecurse);
182  break;
183  case CMD_DEB:
184  /* unpack a DEBIAN source:*/
185  rc=RunCommand(CMD[CI->PI.Cmd].Cmd,CMD[CI->PI.Cmd].CmdPre,CI->Source,
186  CMD[CI->PI.Cmd].CmdPost,CI->PartnameNew,CI->Partdir);
187  break;
188  case CMD_ZSTD:
189  /* unpack a ZSTD: source file, source name and destination directory */
190  rc = ExtractZstd(CI->Source, CI->Partname, Queue[Index].ChildRecurse);
191  break;
192  case CMD_DEFAULT:
193  default:
194  /* use the original name */
195  PlainCopy=1;
196  if (!IsFile(Queue[Index].ChildRecurse,0))
197  {
198  CopyFile(CI->Source,Queue[Index].ChildRecurse);
199  }
200  rc=0;
201  break;
202  } /* switch type of processing */
203 
204  /* Child: Unpacks */
205  /* remove source */
206  if (UnlinkSource && (rc==0) && !NewDir && !PlainCopy)
207  {
208  /* if we're unlinking AND command worked AND it's not original... */
209  unlink(CI->Source);
210  }
211  if (rc)
212  {
213  /* if command failed but we want to continue anyway */
214  /* Note: CMD_DEFAULT will never get here because rc==0 */
215  if (strstr(CMD[CI->PI.Cmd].Cmd, "unzip") && (rc == 82))
216  {
217  LOG_ERROR("pfile %s Command %s failed on: %s, Password required.",
218  Pfile_Pk, CMD[CI->PI.Cmd].Cmd, CI->Source);
219  }
220  else
221  {
222  LOG_ERROR("pfile %s Command %s failed on: %s",
223  Pfile_Pk, CMD[CI->PI.Cmd].Cmd, CI->Source);
224  }
225  if (ForceContinue) rc=-1;
226  }
227  exit(rc);
228 } /* TraverseChild() */
229 
230 
238 int CountFilename(char *Pathname, char *Dirname)
239 {
240  char *FullDirname;
241  char *sp;
242  int FoundCount = 0;
243  int NameLen;
244 
245  FullDirname = calloc(strlen(Dirname) + 3, sizeof(char));
246  sprintf(FullDirname, "/%s/", Dirname);
247  NameLen = strlen(FullDirname);
248 
249  sp = Pathname;
250  while (((sp = strstr(sp, FullDirname)) != NULL))
251  {
252  FoundCount++;
253  sp += NameLen;
254  }
255 
256  free(FullDirname);
257  return(FoundCount);
258 }
259 
260 
275 int Traverse (char *Filename, char *Basename,
276  char *Label, char *NewDir, int Recurse, ParentInfo *PI)
277 {
278  int rc;
279  PGresult *result;
280  int i;
281  ContainerInfo CI,CImeta;
282  int IsContainer=0;
283  int RecurseOk=1; /* should it recurse? (only on unique inserts) */
284  int MaxRepeatingName = 3;
285 
286  if (!Filename || (Filename[0]=='\0')) return(IsContainer);
287  if (Verbose > 0) LOG_DEBUG("Traverse(%s) -- %s",Filename,Label)
288 
289  /* to prevent infinitely recursive test archives, count how many times the basename
290  occurs in Filename. If over MaxRepeatingName, then return 0
291  */
292  if (CountFilename(Filename, basename(Filename)) >= MaxRepeatingName)
293  {
294  LOG_NOTICE("Traverse() recursion terminating due to max directory repetition: %s", Filename);
295  return 0;
296  }
297 
298  /* clear the container */
299  memset(&CI,0,sizeof(ContainerInfo));
300 
301  /* check for top containers */
302  CI.TopContainer = (NewDir!=NULL);
303 
304  /***********************************************/
305  /* Populate CI and CI.PI structure */
306  /***********************************************/
307  CI.PI.Cmd=PI->Cmd; /* inherit */
308  CI.PI.StartTime = PI->StartTime;
309  CI.PI.EndTime = PI->EndTime;
310  CI.PI.uploadtree_pk = PI->uploadtree_pk;
312  /* the item is processed; log all children */
313  if (CI.Artifact > 0) PI->ChildRecurseArtifact=CI.Artifact-1;
314  else PI->ChildRecurseArtifact=0;
315 
316  rc = lstat(Filename,&CI.Stat);
317 
318  /* Source filename may be from another Queue element.
319  Copy the name over so it does not accidentally change. */
320  strcpy(CI.Source,Filename);
321 
322  /* split directory and filename */
323  if (Basename) SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,Basename);
324  else SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,CI.Source);
325 
326  /* count length of filename */
327  for(i=strlen(CI.Source)-1; (i>=0) && (CI.Source[i] != '/'); i--)
328  ;
329  strcpy(CI.Partname,CI.Source+i+1);
330  strcpy(CI.PartnameNew,CI.Partname);
331 
332  /***********************************************/
333  /* ignore anything that is not a directory or a file */
334  /***********************************************/
335  if (CI.Stat.st_mode & S_IFMT & ~(S_IFREG | S_IFDIR))
336  {
337  if (PI->Cmd) DisplayContainerInfo(&CI,PI->Cmd);
338  goto TraverseEnd;
339  }
340 
341  if (rc != 0)
342  {
343  /* this should never happen... */
344  LOG_ERROR("pfile %s \"%s\" DOES NOT EXIST!!!",Pfile_Pk,Filename)
345  /* goto TraverseEnd; */
346  return(0);
347  }
348 
349  /***********************************************/
350  /* handle pruning (on recursion only -- never delete originals) */
351  /***********************************************/
352  if (PruneFiles && !NewDir && Prune(Filename,CI.Stat))
353  {
354  /* pruned! */
355  if (PI->Cmd)
356  {
357  CI.Pruned=1;
358  DisplayContainerInfo(&CI,PI->Cmd);
359  }
360  goto TraverseEnd;
361  }
362 
363  /***********************************************/
364  /* check the type of file in filename: file or directory */
365  /***********************************************/
366  if (S_ISDIR(CI.Stat.st_mode))
367  {
368  /***********************************************/
369  /* if it's a directory, then recurse! */
370  /***********************************************/
371  dirlist *DLhead, *DLentry;
372  long TmpPk;
373 
374  /* record stats */
375  CI.IsDir=1;
376  CI.HasChild=1;
377  IsContainer=1;
378 
379  /* make sure it is accessible */
380  if (!NewDir && ((CI.Stat.st_mode & 0700) != 0700))
381  {
382  chmod(Filename,(CI.Stat.st_mode | 0700));
383  }
384 
385  if (CI.Source[strlen(CI.Source)-1] != '/') strcat(CI.Source,"/");
386  DLhead = MakeDirList(CI.Source);
387  /* process inode in the directory (only if unique) */
388  if (DisplayContainerInfo(&CI,PI->Cmd))
389  {
390  for(DLentry=DLhead; DLentry; DLentry=DLentry->Next)
391  {
392  SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,CI.Source);
393  strcat(CI.Partdir,DLentry->Name);
394  TmpPk = CI.PI.uploadtree_pk;
396  /* don't decrement just because it is a directory */
397  Traverse(CI.Partdir,NULL,"Called by dir",NULL,Recurse,&(CI.PI));
398  CI.PI.uploadtree_pk = TmpPk;
399  }
400  }
401  if (PI->Cmd && ListOutFile)
402  {
403  fputs("</item>\n",ListOutFile);
404  }
405  FreeDirList(DLhead);
406  } /* if S_ISDIR() */
407 
408 #if 0
409  else if (S_ISLNK(CI.Stat.st_mode) || S_ISCHR(CI.Stat.st_mode) ||
410  S_ISBLK(CI.Stat.st_mode) || S_ISFIFO(CI.Stat.st_mode) ||
411  S_ISSOCK(CI.Stat.st_mode))
412  {
413  /* skip symbolic links, blocks, and special devices */
416  }
417 #endif
418 
419  /***********************************************/
420  else if (S_ISREG(CI.Stat.st_mode))
421  {
422  if(IsInflatedFile(CI.Source, 1000)) return 0; // if the file is one compression bombs, do not unpack this file
423 
424  /***********************************************/
425  /* if it's a regular file, then process it! */
426  /***********************************************/
427  int Pid;
428  int Index; /* child index into queue table */
429 
430  CI.PI.Cmd = FindCmd(CI.Source);
431  if (CI.PI.Cmd < 0) goto TraverseEnd;
432 
433  /* make sure it is accessible */
434  if (!NewDir && ((CI.Stat.st_mode & 0600) != 0600))
435  {
436  chmod(Filename,(CI.Stat.st_mode | 0600));
437  }
438 
439  /* if it made it this far, then it's spawning time! */
440  /* Determine where to put the output */
441  Index=0;
442  while((Index < MAXCHILD) && (Queue[Index].ChildPid != 0))
443  Index++;
444 
445  /* determine output location */
446  memset(Queue+Index,0,sizeof(unpackqueue)); /* clear memory */
447  strcpy(Queue[Index].ChildRecurse,CI.Partdir);
448  strcat(Queue[Index].ChildRecurse,CI.Partname);
449  Queue[Index].PI.StartTime = CI.PI.StartTime;
450  Queue[Index].ChildEnd=0;
451  Queue[Index].PI.Cmd = CI.PI.Cmd;
452  Queue[Index].PI.uploadtree_pk = CI.PI.uploadtree_pk;
453  Queue[Index].ChildStat = CI.Stat;
454  switch(CMD[CI.PI.Cmd].Type)
455  {
456  case CMD_ARC:
457  case CMD_AR:
458  case CMD_ISO:
459  case CMD_DISK:
460  case CMD_PARTITION:
461  case CMD_PACK:
462  case CMD_ZSTD:
463  CI.HasChild=1;
464  IsContainer=1;
465  strcat(Queue[Index].ChildRecurse,".dir");
466  strcat(CI.PartnameNew,".dir");
467  Queue[Index].PI.ChildRecurseArtifact=1;
468  /* make the directory */
469  if (MkDir(Queue[Index].ChildRecurse))
470  {
471  LOG_FATAL("Unable to mkdir(%s) in Traverse", Queue[Index].ChildRecurse)
472  if (!ForceContinue)
473  {
474  SafeExit(30);
475  }
476  }
477  if (CMD[CI.PI.Cmd].Type == CMD_PARTITION)
478  Queue[Index].PI.ChildRecurseArtifact=2;
479 
480  /* get the upload file name */
481  /* if the type of the upload file is CMD_PACK, and is top container,
482  * and using repository, then get the upload file name from DB
483  */
484  if (CMD_PACK == CMD[CI.PI.Cmd].Type && CI.TopContainer && UseRepository)
485  {
486  char *UFileName;
487  char SQL[MAXSQL];
488  snprintf(SQL, MAXSQL,"SELECT upload_filename FROM upload WHERE upload_pk = %s;",Upload_Pk);
489  result = PQexec(pgConn, SQL); // get name of the upload file
490  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
491  {
492  SafeExit(31);
493  }
494  UFileName = PQgetvalue(result,0,0);
495  PQclear(result);
496  if (strchr(UFileName, '/')) UFileName = strrchr(UFileName, '/') + 1;
497  memset(UploadFileName, '\0', FILENAME_MAX);
498  strncpy(UploadFileName, UFileName, FILENAME_MAX - 1);
499  }
500 
501  break;
502  case CMD_DEB:
503  case CMD_RPM:
504  CI.HasChild=1;
505  IsContainer=1;
506  strcat(Queue[Index].ChildRecurse,".unpacked");
507  strcat(CI.PartnameNew,".unpacked");
508  Queue[Index].PI.ChildRecurseArtifact=1;
509  if (CMD[CI.PI.Cmd].Type == CMD_PACK)
510  {
511  CI.IsCompressed = 1;
512  }
513  break;
514  case CMD_DEFAULT:
515  default:
516  /* use the original name */
517  CI.HasChild=0;
518  Queue[Index].ChildEnd=1;
519  break;
520  }
521  Queue[Index].ChildHasChild = CI.HasChild;
522 
523  /* save the file's data */
524  RecurseOk = DisplayContainerInfo(&CI,PI->Cmd);
525 
526  /* extract meta info if we added it */
527  if (RecurseOk && CMD[CI.PI.Cmd].MetaCmd && CMD[CI.PI.Cmd].MetaCmd[0])
528  {
529  /* extract meta info */
530  /* This needs to call AddToRepository() or DisplayContainerInfo() */
531  char Cmd[2*FILENAME_MAX];
532  char Fname[FILENAME_MAX];
533  memcpy(&CImeta,&CI,sizeof(CI));
534  CImeta.Artifact=1;
535  CImeta.HasChild=0;
536  CImeta.TopContainer = 0;
537  CImeta.PI.uploadtree_pk = CI.uploadtree_pk;
538  CImeta.PI.Cmd = 0; /* no meta type */
539  memset(Cmd,0,sizeof(Cmd));
540  memset(Fname,0,sizeof(Fname));
541  strcpy(Fname,CImeta.Source);
542  strcat(CImeta.Source,".meta");
543  strcat(CImeta.Partname,".meta");
544 
545  /* remove the destination file if it exists */
546  /* this gets past any permission problems with read-only files */
547  unlink(CImeta.Source);
548 
549  /* build the command and run it */
550  sprintf(Cmd,CMD[CI.PI.Cmd].MetaCmd,Fname,CImeta.Source);
551  rc = system(Cmd);
552  if (WIFSIGNALED(rc))
553  {
554  LOG_ERROR("Process killed by signal (%d): %s",WTERMSIG(rc),Cmd)
555  SafeExit(32);
556  }
557  if (WIFEXITED(rc)) rc = WEXITSTATUS(rc);
558  else rc=-1;
559  if (rc != 0) LOG_ERROR("Unable to run command '%s'",Cmd)
560  /* add it to the list of files */
561  RecurseOk = DisplayContainerInfo(&CImeta,PI->Cmd);
562  if (UnlinkAll) unlink(CImeta.Source);
563  }
564 
565  /* see if I need to spawn (if not, then save time by not!) */
566  if ((Queue[Index].ChildEnd == 1) && IsFile(Queue[Index].ChildRecurse,0))
567  {
568  goto TraverseEnd;
569  }
570 
571  /* spawn unpacker */
572  fflush(stdout); /* if no flush, then child may duplicate output! */
573  if (ListOutFile) fflush(ListOutFile);
574  if (RecurseOk)
575  {
576  Pid = fork();
577  if (Pid == 0) TraverseChild(Index,&CI,NewDir);
578  else
579  {
580  /* Parent: Save child info */
581  if (Pid == -1)
582  {
583  LOG_FATAL("Unable to fork child.")
584  SafeExit(33);
585  }
586  Queue[Index].ChildPid = Pid;
587 
588  // add by larry, start
589  Queue[Index].PI.uploadtree_pk = CI.uploadtree_pk;
590  // add by larry, end
591 
592  Thread++;
593  /* Parent: Continue testing files */
594  if (Thread >= MaxThread)
595  {
596  /* Too many children. Wait for one to end */
597  Index=ParentWait();
598  if (Index < 0) goto TraverseEnd; /* no more children (shouldn't happen here!) */
599  Thread--;
600  /* the value for ChildRecurse can/will be overwitten quickly, but
601  it will be overwritten AFTER it is used */
602  /* Only recurse if the name is different */
603  if (strcmp(Queue[Index].ChildRecurse,CI.Source) && !Queue[Index].ChildEnd)
604  {
605  /* copy over data */
606  CI.Corrupt = Queue[Index].ChildCorrupt;
607  CI.PI.StartTime = Queue[Index].PI.StartTime;
608  CI.PI.EndTime = Queue[Index].PI.EndTime;
609  CI.PI.uploadtree_pk = Queue[Index].PI.uploadtree_pk;
610  CI.HasChild = Queue[Index].ChildHasChild;
611  CI.Stat = Queue[Index].ChildStat;
612 #if 0
613  Queue[Index].PI.uploadtree_pk = CI.uploadtree_pk;
614 #endif
615  if (Recurse > 0)
616  Traverse(Queue[Index].ChildRecurse,NULL,"Called by dir/wait",NULL,Recurse-1,&Queue[Index].PI);
617  else if (Recurse < 0)
618  Traverse(Queue[Index].ChildRecurse,NULL,"Called by dir/wait",NULL,Recurse,&Queue[Index].PI);
619  if (ListOutFile)
620  {
621  fputs("</item>\n",ListOutFile);
622  TotalContainers++;
623  }
624  }
625  } /* if waiting for a child */
626  } /* if parent */
627  } /* if RecurseOk */
628  } /* if S_ISREG() */
629 
630  /***********************************************/
631  else
632  {
633  /* Not a file and not a directory */
634  if (PI->Cmd)
635  {
636  CI.HasChild = 0;
637  DisplayContainerInfo(&CI,PI->Cmd);
638  }
639  LOG_DEBUG("Skipping (not a file or directory): %s",CI.Source)
640  }
641 
642  TraverseEnd:
643  if (UnlinkAll && MaxThread <=1)
644  {
645 #if 0
646  printf("===\n");
647  printf("Source: '%s'\n",CI.Source);
648  printf("NewDir: '%s'\n",NewDir ? NewDir : "");
649  printf("Name: '%s' '%s'\n",CI.Partdir,CI.Partname);
650 #endif
651  if (!NewDir)
652  {
653  if (IsDir(CI.Source)) RemoveDir(CI.Source);
654  // else unlink(CI.Source);
655  }
656  else RemoveDir(NewDir);
657  }
658  return(IsContainer);
659 } /* Traverse() */
char SQL[256]
SQL query to execute.
Definition: adj2nest.c:78
PGconn * pgConn
Database connection.
Definition: adj2nest.c:86
int Verbose
Verbose level.
Definition: util.c:19
Stores all extern variables used by the agent.
char * Pfile_Pk
Pfile pk in DB.
int UseRepository
Using files from the repository?
int MaxThread
Value between 1 and MAXCHILD.
int UnlinkSource
Remove recursive sources after unpacking?
unpackqueue Queue[MAXCHILD+1]
Manage children.
int Thread
Number of threads in execution.
cmdlist CMD[]
Global command table.
int PruneFiles
Remove links? >1 hard links, zero files, etc.
int TotalContainers
Number of containers.
char UploadFileName[FILENAME_MAX]
Upload file name.
char * Upload_Pk
Upload pk in DB.
int UnlinkAll
Remove ALL unpacked files when done (clean up)?
FILE * ListOutFile
File to store unpack list.
int ForceContinue
Force continue when unpack tool fails?
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:170
void CopyFile(char *Source, char *Type, char *Name)
Definition: repcopyin.c:39
Structure for storing information about a particular file.
Definition: ununpack.h:116
int IsCompressed
Definition: ununpack.h:129
int TopContainer
Definition: ununpack.h:121
ParentInfo PI
Definition: ununpack.h:126
char Partname[FILENAME_MAX]
Definition: ununpack.h:119
long uploadtree_pk
Definition: ununpack.h:130
struct stat Stat
Definition: ununpack.h:125
char PartnameNew[FILENAME_MAX]
Definition: ununpack.h:120
char Partdir[FILENAME_MAX]
Definition: ununpack.h:118
time_t StartTime
Definition: ununpack.h:78
long uploadtree_pk
Definition: ununpack.h:81
int ChildRecurseArtifact
Definition: ununpack.h:80
time_t EndTime
Definition: ununpack.h:79
cmdtype Type
Definition: ununpack.h:149
int Status
Definition: ununpack.h:150
char * MetaCmd
Definition: ununpack.h:148
char * Cmd
Definition: ununpack.h:145
char * CmdPost
Definition: ununpack.h:147
char * CmdPre
Definition: ununpack.h:146
Directory linked list.
Definition: ununpack.h:105
struct dirlist * Next
Definition: ununpack.h:107
Queue for files to be unpacked.
Definition: ununpack.h:89
ParentInfo PI
Definition: ununpack.h:97
struct stat ChildStat
Definition: ununpack.h:96
int ChildEnd
Definition: ununpack.h:94
char ChildRecurse[FILENAME_MAX+1]
Definition: ununpack.h:91
int ChildCorrupt
Definition: ununpack.h:93
int ChildHasChild
Definition: ununpack.h:95
static char * Dst
Destination location.
Definition: test_CopyFile.c:14
static char * Src
Souce location.
Definition: test_CopyFile.c:13
void TraverseStart(char *Filename, char *Label, char *NewDir, int Recurse)
Find all files (assuming a directory) and process (unpack) all of them.
Definition: traverse.c:23
int CountFilename(char *Pathname, char *Dirname)
Count the number of times Dirname appears in Pathname This is used to limit recursion in test archive...
Definition: traverse.c:238
void TraverseChild(int Index, ContainerInfo *CI, char *NewDir)
Called by exec'd child to process.
Definition: traverse.c:96
int Traverse(char *Filename, char *Basename, char *Label, char *NewDir, int Recurse, ParentInfo *PI)
Find all files, traverse all directories. This is a depth-first search, in inode order!
Definition: traverse.c:275
int ExtractAR(char *Source, char *Destination)
Given an AR file, extract the contents to the directory. This uses the command ar.
Definition: ununpack-ar.c:26
int ExtractDisk(char *Source, char *FStype, char *Destination)
Given a disk image, type of system, and a directory, extract all files!
int ExtractISO(char *Source, char *Destination)
Given an ISO image and a directory, extract the image to the directory.
Definition: ununpack-iso.c:68
int ExtractZstd(char *Source, const char *OrigName, char *Destination)
Given a ZSTd file, extract the contents to the directory.
Definition: ununpack-zstd.c:23
int RunCommand(char *Cmd, char *CmdPre, char *File, char *CmdPost, char *Out, char *Where)
Try a command and return command code.
Definition: utils.c:621
int DisplayContainerInfo(ContainerInfo *CI, int Cmd)
Print what can be printed in XML.
Definition: utils.c:1457
int RemoveDir(char *dirpath)
Remove all files under dirpath (rm -rf)
Definition: utils.c:1641
int Prune(char *Fname, struct stat Stat)
Given a filename and its stat, prune it.
Definition: utils.c:217
int MkDir(char *Fname)
Smart mkdir.
Definition: utils.c:303
void SetDir(char *Dest, int DestLen, char *Smain, char *Sfile)
Set a destination directory name.
Definition: utils.c:1047
int ParentWait()
Wait for a child. Sets child status.
Definition: utils.c:509
void RemovePostfix(char *Name)
get rid of the postfix
Definition: utils.c:90
void FreeDirList(dirlist *DL)
Free a list of files in a directory list.
Definition: utils.c:951
void SafeExit(int rc)
Close scheduler and database connections, then exit.
Definition: utils.c:77
int FindCmd(char *Filename)
Given a file name, determine the type of extraction command. This uses Magic.
Definition: utils.c:850
int IsInflatedFile(char *FileName, int InflateSize)
Test if the file is a compression bomb.
Definition: utils.c:40
dirlist * MakeDirList(char *Fullname)
Create a list of files in a directory.
Definition: utils.c:970
int IsDir(char *Fname)
Given a filename, is it a directory?
Definition: utils.c:319
int Recurse
Level of unpack recursion. Default to infinite.
Definition: run_tests.c:19
char * NewDir
Test result directory.
Definition: run_tests.c:18
char * Filename
Filename.
Definition: run_tests.c:17
int IsFile(long mode)
Check if the pfile_id is a file.
Definition: wc_agent.c:55