FOSSology  4.6.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 
24 void TraverseStart(char *Filename, char *Label, char *NewDir, int Recurse, char *ExcludePatterns)
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,ExcludePatterns);
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, ExcludePatterns);
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_LZIP:
193  /* unpack an LZIP: source file and destination directory */
194  rc = ExtractLzip(CI->Source, CI->Partname, Queue[Index].ChildRecurse);
195  break;
196  case CMD_DEFAULT:
197  default:
198  /* use the original name */
199  PlainCopy=1;
200  if (!IsFile(Queue[Index].ChildRecurse,0))
201  {
202  CopyFile(CI->Source,Queue[Index].ChildRecurse);
203  }
204  rc=0;
205  break;
206  } /* switch type of processing */
207 
208  /* Child: Unpacks */
209  /* remove source */
210  if (UnlinkSource && (rc==0) && !NewDir && !PlainCopy)
211  {
212  /* if we're unlinking AND command worked AND it's not original... */
213  unlink(CI->Source);
214  }
215  if (rc)
216  {
217  /* if command failed but we want to continue anyway */
218  /* Note: CMD_DEFAULT will never get here because rc==0 */
219  if (strstr(CMD[CI->PI.Cmd].Cmd, "unzip") && (rc == 82))
220  {
221  LOG_ERROR("pfile %s Command %s failed on: %s, Password required.",
222  Pfile_Pk, CMD[CI->PI.Cmd].Cmd, CI->Source);
223  }
224  else
225  {
226  LOG_ERROR("pfile %s Command %s failed on: %s",
227  Pfile_Pk, CMD[CI->PI.Cmd].Cmd, CI->Source);
228  }
229  if (ForceContinue) rc=-1;
230  }
231  exit(rc);
232 } /* TraverseChild() */
233 
234 
242 int CountFilename(char *Pathname, char *Dirname)
243 {
244  char *FullDirname;
245  char *sp;
246  int FoundCount = 0;
247  int NameLen;
248 
249  FullDirname = calloc(strlen(Dirname) + 3, sizeof(char));
250  sprintf(FullDirname, "/%s/", Dirname);
251  NameLen = strlen(FullDirname);
252 
253  sp = Pathname;
254  while (((sp = strstr(sp, FullDirname)) != NULL))
255  {
256  FoundCount++;
257  sp += NameLen;
258  }
259 
260  free(FullDirname);
261  return(FoundCount);
262 }
263 
264 
279 int Traverse (char *Filename, char *Basename,
280  char *Label, char *NewDir, int Recurse, ParentInfo *PI, char *ExcludePatterns)
281 {
282  if (ShouldExclude(Filename, ExcludePatterns)) {
283  if (Verbose) LOG_DEBUG("Skipping excluded file or folder: %s", Filename);
284  return 0;
285  }
286  int rc;
287  PGresult *result;
288  int i;
289  ContainerInfo CI,CImeta;
290  int IsContainer=0;
291  int RecurseOk=1; /* should it recurse? (only on unique inserts) */
292  int MaxRepeatingName = 3;
293 
294  if (!Filename || (Filename[0]=='\0')) return(IsContainer);
295  if (Verbose > 0) LOG_DEBUG("Traverse(%s) -- %s",Filename,Label)
296 
297  /* to prevent infinitely recursive test archives, count how many times the basename
298  occurs in Filename. If over MaxRepeatingName, then return 0
299  */
300  if (CountFilename(Filename, basename(Filename)) >= MaxRepeatingName)
301  {
302  LOG_NOTICE("Traverse() recursion terminating due to max directory repetition: %s", Filename);
303  return 0;
304  }
305 
306  /* clear the container */
307  memset(&CI,0,sizeof(ContainerInfo));
308 
309  /* check for top containers */
310  CI.TopContainer = (NewDir!=NULL);
311 
312  /***********************************************/
313  /* Populate CI and CI.PI structure */
314  /***********************************************/
315  CI.PI.Cmd=PI->Cmd; /* inherit */
316  CI.PI.StartTime = PI->StartTime;
317  CI.PI.EndTime = PI->EndTime;
318  CI.PI.uploadtree_pk = PI->uploadtree_pk;
320  /* the item is processed; log all children */
321  if (CI.Artifact > 0) PI->ChildRecurseArtifact=CI.Artifact-1;
322  else PI->ChildRecurseArtifact=0;
323 
324  rc = lstat(Filename,&CI.Stat);
325 
326  /* Source filename may be from another Queue element.
327  Copy the name over so it does not accidentally change. */
328  strcpy(CI.Source,Filename);
329 
330  /* split directory and filename */
331  if (Basename) SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,Basename);
332  else SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,CI.Source);
333 
334  /* count length of filename */
335  for(i=strlen(CI.Source)-1; (i>=0) && (CI.Source[i] != '/'); i--)
336  ;
337  strcpy(CI.Partname,CI.Source+i+1);
338  strcpy(CI.PartnameNew,CI.Partname);
339 
340  /***********************************************/
341  /* ignore anything that is not a directory or a file */
342  /***********************************************/
343  if (CI.Stat.st_mode & S_IFMT & ~(S_IFREG | S_IFDIR))
344  {
345  if (PI->Cmd) DisplayContainerInfo(&CI,PI->Cmd);
346  goto TraverseEnd;
347  }
348 
349  if (rc != 0)
350  {
351  /* this should never happen... */
352  LOG_ERROR("pfile %s \"%s\" DOES NOT EXIST!!!",Pfile_Pk,Filename)
353  /* goto TraverseEnd; */
354  return(0);
355  }
356 
357  /***********************************************/
358  /* handle pruning (on recursion only -- never delete originals) */
359  /***********************************************/
360  if (PruneFiles && !NewDir && Prune(Filename,CI.Stat))
361  {
362  /* pruned! */
363  if (PI->Cmd)
364  {
365  CI.Pruned=1;
366  DisplayContainerInfo(&CI,PI->Cmd);
367  }
368  goto TraverseEnd;
369  }
370 
371  /***********************************************/
372  /* check the type of file in filename: file or directory */
373  /***********************************************/
374  if (S_ISDIR(CI.Stat.st_mode))
375  {
376  /***********************************************/
377  /* if it's a directory, then recurse! */
378  /***********************************************/
379  dirlist *DLhead, *DLentry;
380  long TmpPk;
381 
382  /* record stats */
383  CI.IsDir=1;
384  CI.HasChild=1;
385  IsContainer=1;
386 
387  /* make sure it is accessible */
388  if (!NewDir && ((CI.Stat.st_mode & 0700) != 0700))
389  {
390  chmod(Filename,(CI.Stat.st_mode | 0700));
391  }
392 
393  if (CI.Source[strlen(CI.Source)-1] != '/') strcat(CI.Source,"/");
394  DLhead = MakeDirList(CI.Source);
395  /* process inode in the directory (only if unique) */
396  if (DisplayContainerInfo(&CI,PI->Cmd))
397  {
398  for(DLentry=DLhead; DLentry; DLentry=DLentry->Next)
399  {
400  SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,CI.Source);
401  strcat(CI.Partdir,DLentry->Name);
402  TmpPk = CI.PI.uploadtree_pk;
404  /* don't decrement just because it is a directory */
405  Traverse(CI.Partdir,NULL,"Called by dir",NULL,Recurse,&(CI.PI), ExcludePatterns);
406  CI.PI.uploadtree_pk = TmpPk;
407  }
408  }
409  if (PI->Cmd && ListOutFile)
410  {
411  fputs("</item>\n",ListOutFile);
412  }
413  FreeDirList(DLhead);
414  } /* if S_ISDIR() */
415 
416 #if 0
417  else if (S_ISLNK(CI.Stat.st_mode) || S_ISCHR(CI.Stat.st_mode) ||
418  S_ISBLK(CI.Stat.st_mode) || S_ISFIFO(CI.Stat.st_mode) ||
419  S_ISSOCK(CI.Stat.st_mode))
420  {
421  /* skip symbolic links, blocks, and special devices */
424  }
425 #endif
426 
427  /***********************************************/
428  else if (S_ISREG(CI.Stat.st_mode))
429  {
430  if(IsInflatedFile(CI.Source, 1000)) return 0; // if the file is one compression bombs, do not unpack this file
431 
432  /***********************************************/
433  /* if it's a regular file, then process it! */
434  /***********************************************/
435  int Pid;
436  int Index; /* child index into queue table */
437 
438  CI.PI.Cmd = FindCmd(CI.Source);
439  if (CI.PI.Cmd < 0) goto TraverseEnd;
440 
441  /* make sure it is accessible */
442  if (!NewDir && ((CI.Stat.st_mode & 0600) != 0600))
443  {
444  chmod(Filename,(CI.Stat.st_mode | 0600));
445  }
446 
447  /* if it made it this far, then it's spawning time! */
448  /* Determine where to put the output */
449  Index=0;
450  while((Index < MAXCHILD) && (Queue[Index].ChildPid != 0))
451  Index++;
452 
453  /* determine output location */
454  memset(Queue+Index,0,sizeof(unpackqueue)); /* clear memory */
455  strcpy(Queue[Index].ChildRecurse,CI.Partdir);
456  strcat(Queue[Index].ChildRecurse,CI.Partname);
457  Queue[Index].PI.StartTime = CI.PI.StartTime;
458  Queue[Index].ChildEnd=0;
459  Queue[Index].PI.Cmd = CI.PI.Cmd;
460  Queue[Index].PI.uploadtree_pk = CI.PI.uploadtree_pk;
461  Queue[Index].ChildStat = CI.Stat;
462  switch(CMD[CI.PI.Cmd].Type)
463  {
464  case CMD_ARC:
465  case CMD_AR:
466  case CMD_ISO:
467  case CMD_DISK:
468  case CMD_PARTITION:
469  case CMD_PACK:
470  case CMD_ZSTD:
471  case CMD_LZIP:
472  CI.HasChild=1;
473  IsContainer=1;
474  strcat(Queue[Index].ChildRecurse,".dir");
475  strcat(CI.PartnameNew,".dir");
476  Queue[Index].PI.ChildRecurseArtifact=1;
477  /* make the directory */
478  if (MkDir(Queue[Index].ChildRecurse))
479  {
480  LOG_FATAL("Unable to mkdir(%s) in Traverse", Queue[Index].ChildRecurse)
481  if (!ForceContinue)
482  {
483  SafeExit(30);
484  }
485  }
486  if (CMD[CI.PI.Cmd].Type == CMD_PARTITION)
487  Queue[Index].PI.ChildRecurseArtifact=2;
488 
489  /* get the upload file name */
490  /* if the type of the upload file is CMD_PACK, and is top container,
491  * and using repository, then get the upload file name from DB
492  */
493  if (CMD_PACK == CMD[CI.PI.Cmd].Type && CI.TopContainer && UseRepository)
494  {
495  char *UFileName;
496  char SQL[MAXSQL];
497  snprintf(SQL, MAXSQL,"SELECT upload_filename FROM upload WHERE upload_pk = %s;",Upload_Pk);
498  result = PQexec(pgConn, SQL); // get name of the upload file
499  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
500  {
501  SafeExit(31);
502  }
503  UFileName = PQgetvalue(result,0,0);
504  PQclear(result);
505  if (strchr(UFileName, '/')) UFileName = strrchr(UFileName, '/') + 1;
506  memset(UploadFileName, '\0', FILENAME_MAX);
507  strncpy(UploadFileName, UFileName, FILENAME_MAX - 1);
508  }
509 
510  break;
511  case CMD_DEB:
512  case CMD_RPM:
513  CI.HasChild=1;
514  IsContainer=1;
515  strcat(Queue[Index].ChildRecurse,".unpacked");
516  strcat(CI.PartnameNew,".unpacked");
517  Queue[Index].PI.ChildRecurseArtifact=1;
518  if (CMD[CI.PI.Cmd].Type == CMD_PACK)
519  {
520  CI.IsCompressed = 1;
521  }
522  break;
523  case CMD_DEFAULT:
524  default:
525  /* use the original name */
526  CI.HasChild=0;
527  Queue[Index].ChildEnd=1;
528  break;
529  }
530  Queue[Index].ChildHasChild = CI.HasChild;
531 
532  /* save the file's data */
533  RecurseOk = DisplayContainerInfo(&CI,PI->Cmd);
534 
535  /* extract meta info if we added it */
536  if (RecurseOk && CMD[CI.PI.Cmd].MetaCmd && CMD[CI.PI.Cmd].MetaCmd[0])
537  {
538  /* extract meta info */
539  /* This needs to call AddToRepository() or DisplayContainerInfo() */
540  char Cmd[2*FILENAME_MAX];
541  char Fname[FILENAME_MAX];
542  memcpy(&CImeta,&CI,sizeof(CI));
543  CImeta.Artifact=1;
544  CImeta.HasChild=0;
545  CImeta.TopContainer = 0;
546  CImeta.PI.uploadtree_pk = CI.uploadtree_pk;
547  CImeta.PI.Cmd = 0; /* no meta type */
548  memset(Cmd,0,sizeof(Cmd));
549  memset(Fname,0,sizeof(Fname));
550  strcpy(Fname,CImeta.Source);
551  strcat(CImeta.Source,".meta");
552  strcat(CImeta.Partname,".meta");
553 
554  /* remove the destination file if it exists */
555  /* this gets past any permission problems with read-only files */
556  unlink(CImeta.Source);
557 
558  /* build the command and run it */
559  sprintf(Cmd,CMD[CI.PI.Cmd].MetaCmd,Fname,CImeta.Source);
560  rc = system(Cmd);
561  if (WIFSIGNALED(rc))
562  {
563  LOG_ERROR("Process killed by signal (%d): %s",WTERMSIG(rc),Cmd)
564  SafeExit(32);
565  }
566  if (WIFEXITED(rc)) rc = WEXITSTATUS(rc);
567  else rc=-1;
568  if (rc != 0) LOG_ERROR("Unable to run command '%s'",Cmd)
569  /* add it to the list of files */
570  RecurseOk = DisplayContainerInfo(&CImeta,PI->Cmd);
571  if (UnlinkAll) unlink(CImeta.Source);
572  }
573 
574  /* see if I need to spawn (if not, then save time by not!) */
575  if ((Queue[Index].ChildEnd == 1) && IsFile(Queue[Index].ChildRecurse,0))
576  {
577  goto TraverseEnd;
578  }
579 
580  /* spawn unpacker */
581  fflush(stdout); /* if no flush, then child may duplicate output! */
582  if (ListOutFile) fflush(ListOutFile);
583  if (RecurseOk)
584  {
585  Pid = fork();
586  if (Pid == 0) TraverseChild(Index,&CI,NewDir);
587  else
588  {
589  /* Parent: Save child info */
590  if (Pid == -1)
591  {
592  LOG_FATAL("Unable to fork child.")
593  SafeExit(33);
594  }
595  Queue[Index].ChildPid = Pid;
596 
597  // add by larry, start
598  Queue[Index].PI.uploadtree_pk = CI.uploadtree_pk;
599  // add by larry, end
600 
601  Thread++;
602  /* Parent: Continue testing files */
603  if (Thread >= MaxThread)
604  {
605  /* Too many children. Wait for one to end */
606  Index=ParentWait();
607  if (Index < 0) goto TraverseEnd; /* no more children (shouldn't happen here!) */
608  Thread--;
609  /* the value for ChildRecurse can/will be overwitten quickly, but
610  it will be overwritten AFTER it is used */
611  /* Only recurse if the name is different */
612  if (strcmp(Queue[Index].ChildRecurse,CI.Source) && !Queue[Index].ChildEnd)
613  {
614  /* copy over data */
615  CI.Corrupt = Queue[Index].ChildCorrupt;
616  CI.PI.StartTime = Queue[Index].PI.StartTime;
617  CI.PI.EndTime = Queue[Index].PI.EndTime;
618  CI.PI.uploadtree_pk = Queue[Index].PI.uploadtree_pk;
619  CI.HasChild = Queue[Index].ChildHasChild;
620  CI.Stat = Queue[Index].ChildStat;
621 #if 0
622  Queue[Index].PI.uploadtree_pk = CI.uploadtree_pk;
623 #endif
624  if (Recurse > 0)
625  Traverse(Queue[Index].ChildRecurse,NULL,"Called by dir/wait",NULL,Recurse-1,&Queue[Index].PI, ExcludePatterns);
626  else if (Recurse < 0)
627  Traverse(Queue[Index].ChildRecurse,NULL,"Called by dir/wait",NULL,Recurse,&Queue[Index].PI, ExcludePatterns);
628  if (ListOutFile)
629  {
630  fputs("</item>\n",ListOutFile);
631  TotalContainers++;
632  }
633  }
634  } /* if waiting for a child */
635  } /* if parent */
636  } /* if RecurseOk */
637  } /* if S_ISREG() */
638 
639  /***********************************************/
640  else
641  {
642  /* Not a file and not a directory */
643  if (PI->Cmd)
644  {
645  CI.HasChild = 0;
646  DisplayContainerInfo(&CI,PI->Cmd);
647  }
648  LOG_DEBUG("Skipping (not a file or directory): %s",CI.Source)
649  }
650 
651  TraverseEnd:
652  if (UnlinkAll && MaxThread <=1)
653  {
654 #if 0
655  printf("===\n");
656  printf("Source: '%s'\n",CI.Source);
657  printf("NewDir: '%s'\n",NewDir ? NewDir : "");
658  printf("Name: '%s' '%s'\n",CI.Partdir,CI.Partname);
659 #endif
660  if (!NewDir)
661  {
662  if (IsDir(CI.Source)) RemoveDir(CI.Source);
663  // else unlink(CI.Source);
664  }
665  else RemoveDir(NewDir);
666  }
667  return(IsContainer);
668 } /* 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:118
int IsCompressed
Definition: ununpack.h:131
int TopContainer
Definition: ununpack.h:123
ParentInfo PI
Definition: ununpack.h:128
char Partname[FILENAME_MAX]
Definition: ununpack.h:121
long uploadtree_pk
Definition: ununpack.h:132
struct stat Stat
Definition: ununpack.h:127
char PartnameNew[FILENAME_MAX]
Definition: ununpack.h:122
char Partdir[FILENAME_MAX]
Definition: ununpack.h:120
time_t StartTime
Definition: ununpack.h:80
long uploadtree_pk
Definition: ununpack.h:83
int ChildRecurseArtifact
Definition: ununpack.h:82
time_t EndTime
Definition: ununpack.h:81
cmdtype Type
Definition: ununpack.h:151
int Status
Definition: ununpack.h:152
char * MetaCmd
Definition: ununpack.h:150
char * Cmd
Definition: ununpack.h:147
char * CmdPost
Definition: ununpack.h:149
char * CmdPre
Definition: ununpack.h:148
Directory linked list.
Definition: ununpack.h:107
struct dirlist * Next
Definition: ununpack.h:109
Queue for files to be unpacked.
Definition: ununpack.h:91
ParentInfo PI
Definition: ununpack.h:99
struct stat ChildStat
Definition: ununpack.h:98
int ChildEnd
Definition: ununpack.h:96
char ChildRecurse[FILENAME_MAX+1]
Definition: ununpack.h:93
int ChildCorrupt
Definition: ununpack.h:95
int ChildHasChild
Definition: ununpack.h:97
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, char *ExcludePatterns)
Find all files (assuming a directory) and process (unpack) all of them.
Definition: traverse.c:24
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:242
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, char *ExcludePatterns)
Find all files, traverse all directories. This is a depth-first search, in inode order!
Definition: traverse.c:279
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 ExtractLzip(char *Source, const char *OrigName, char *Destination)
Given an lzip file, extract the contents to the directory.
Definition: ununpack-lzip.c:23
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:623
int DisplayContainerInfo(ContainerInfo *CI, int Cmd)
Print what can be printed in XML.
Definition: utils.c:1459
int RemoveDir(char *dirpath)
Remove all files under dirpath (rm -rf)
Definition: utils.c:1643
int Prune(char *Fname, struct stat Stat)
Given a filename and its stat, prune it.
Definition: utils.c:218
int MkDir(char *Fname)
Smart mkdir.
Definition: utils.c:304
void SetDir(char *Dest, int DestLen, char *Smain, char *Sfile)
Set a destination directory name.
Definition: utils.c:1049
int ParentWait()
Wait for a child. Sets child status.
Definition: utils.c:510
void RemovePostfix(char *Name)
get rid of the postfix
Definition: utils.c:91
void FreeDirList(dirlist *DL)
Free a list of files in a directory list.
Definition: utils.c:953
void SafeExit(int rc)
Close scheduler and database connections, then exit.
Definition: utils.c:78
int FindCmd(char *Filename)
Given a file name, determine the type of extraction command. This uses Magic.
Definition: utils.c:852
int ShouldExclude(char *Filename, const char *ExcludePatterns)
Determines if a file or folder should be excluded.
Definition: utils.c:1789
int IsInflatedFile(char *FileName, int InflateSize)
Test if the file is a compression bomb.
Definition: utils.c:41
dirlist * MakeDirList(char *Fullname)
Create a list of files in a directory.
Definition: utils.c:972
int IsDir(char *Fname)
Given a filename, is it a directory?
Definition: utils.c:320
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