FOSSology  4.5.1
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_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, char *ExcludePatterns)
277 {
278  if (ShouldExclude(Filename, ExcludePatterns)) {
279  if (Verbose) LOG_DEBUG("Skipping excluded file or folder: %s", Filename);
280  return 0;
281  }
282  int rc;
283  PGresult *result;
284  int i;
285  ContainerInfo CI,CImeta;
286  int IsContainer=0;
287  int RecurseOk=1; /* should it recurse? (only on unique inserts) */
288  int MaxRepeatingName = 3;
289 
290  if (!Filename || (Filename[0]=='\0')) return(IsContainer);
291  if (Verbose > 0) LOG_DEBUG("Traverse(%s) -- %s",Filename,Label)
292 
293  /* to prevent infinitely recursive test archives, count how many times the basename
294  occurs in Filename. If over MaxRepeatingName, then return 0
295  */
296  if (CountFilename(Filename, basename(Filename)) >= MaxRepeatingName)
297  {
298  LOG_NOTICE("Traverse() recursion terminating due to max directory repetition: %s", Filename);
299  return 0;
300  }
301 
302  /* clear the container */
303  memset(&CI,0,sizeof(ContainerInfo));
304 
305  /* check for top containers */
306  CI.TopContainer = (NewDir!=NULL);
307 
308  /***********************************************/
309  /* Populate CI and CI.PI structure */
310  /***********************************************/
311  CI.PI.Cmd=PI->Cmd; /* inherit */
312  CI.PI.StartTime = PI->StartTime;
313  CI.PI.EndTime = PI->EndTime;
314  CI.PI.uploadtree_pk = PI->uploadtree_pk;
316  /* the item is processed; log all children */
317  if (CI.Artifact > 0) PI->ChildRecurseArtifact=CI.Artifact-1;
318  else PI->ChildRecurseArtifact=0;
319 
320  rc = lstat(Filename,&CI.Stat);
321 
322  /* Source filename may be from another Queue element.
323  Copy the name over so it does not accidentally change. */
324  strcpy(CI.Source,Filename);
325 
326  /* split directory and filename */
327  if (Basename) SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,Basename);
328  else SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,CI.Source);
329 
330  /* count length of filename */
331  for(i=strlen(CI.Source)-1; (i>=0) && (CI.Source[i] != '/'); i--)
332  ;
333  strcpy(CI.Partname,CI.Source+i+1);
334  strcpy(CI.PartnameNew,CI.Partname);
335 
336  /***********************************************/
337  /* ignore anything that is not a directory or a file */
338  /***********************************************/
339  if (CI.Stat.st_mode & S_IFMT & ~(S_IFREG | S_IFDIR))
340  {
341  if (PI->Cmd) DisplayContainerInfo(&CI,PI->Cmd);
342  goto TraverseEnd;
343  }
344 
345  if (rc != 0)
346  {
347  /* this should never happen... */
348  LOG_ERROR("pfile %s \"%s\" DOES NOT EXIST!!!",Pfile_Pk,Filename)
349  /* goto TraverseEnd; */
350  return(0);
351  }
352 
353  /***********************************************/
354  /* handle pruning (on recursion only -- never delete originals) */
355  /***********************************************/
356  if (PruneFiles && !NewDir && Prune(Filename,CI.Stat))
357  {
358  /* pruned! */
359  if (PI->Cmd)
360  {
361  CI.Pruned=1;
362  DisplayContainerInfo(&CI,PI->Cmd);
363  }
364  goto TraverseEnd;
365  }
366 
367  /***********************************************/
368  /* check the type of file in filename: file or directory */
369  /***********************************************/
370  if (S_ISDIR(CI.Stat.st_mode))
371  {
372  /***********************************************/
373  /* if it's a directory, then recurse! */
374  /***********************************************/
375  dirlist *DLhead, *DLentry;
376  long TmpPk;
377 
378  /* record stats */
379  CI.IsDir=1;
380  CI.HasChild=1;
381  IsContainer=1;
382 
383  /* make sure it is accessible */
384  if (!NewDir && ((CI.Stat.st_mode & 0700) != 0700))
385  {
386  chmod(Filename,(CI.Stat.st_mode | 0700));
387  }
388 
389  if (CI.Source[strlen(CI.Source)-1] != '/') strcat(CI.Source,"/");
390  DLhead = MakeDirList(CI.Source);
391  /* process inode in the directory (only if unique) */
392  if (DisplayContainerInfo(&CI,PI->Cmd))
393  {
394  for(DLentry=DLhead; DLentry; DLentry=DLentry->Next)
395  {
396  SetDir(CI.Partdir,sizeof(CI.Partdir),NewDir,CI.Source);
397  strcat(CI.Partdir,DLentry->Name);
398  TmpPk = CI.PI.uploadtree_pk;
400  /* don't decrement just because it is a directory */
401  Traverse(CI.Partdir,NULL,"Called by dir",NULL,Recurse,&(CI.PI), ExcludePatterns);
402  CI.PI.uploadtree_pk = TmpPk;
403  }
404  }
405  if (PI->Cmd && ListOutFile)
406  {
407  fputs("</item>\n",ListOutFile);
408  }
409  FreeDirList(DLhead);
410  } /* if S_ISDIR() */
411 
412 #if 0
413  else if (S_ISLNK(CI.Stat.st_mode) || S_ISCHR(CI.Stat.st_mode) ||
414  S_ISBLK(CI.Stat.st_mode) || S_ISFIFO(CI.Stat.st_mode) ||
415  S_ISSOCK(CI.Stat.st_mode))
416  {
417  /* skip symbolic links, blocks, and special devices */
420  }
421 #endif
422 
423  /***********************************************/
424  else if (S_ISREG(CI.Stat.st_mode))
425  {
426  if(IsInflatedFile(CI.Source, 1000)) return 0; // if the file is one compression bombs, do not unpack this file
427 
428  /***********************************************/
429  /* if it's a regular file, then process it! */
430  /***********************************************/
431  int Pid;
432  int Index; /* child index into queue table */
433 
434  CI.PI.Cmd = FindCmd(CI.Source);
435  if (CI.PI.Cmd < 0) goto TraverseEnd;
436 
437  /* make sure it is accessible */
438  if (!NewDir && ((CI.Stat.st_mode & 0600) != 0600))
439  {
440  chmod(Filename,(CI.Stat.st_mode | 0600));
441  }
442 
443  /* if it made it this far, then it's spawning time! */
444  /* Determine where to put the output */
445  Index=0;
446  while((Index < MAXCHILD) && (Queue[Index].ChildPid != 0))
447  Index++;
448 
449  /* determine output location */
450  memset(Queue+Index,0,sizeof(unpackqueue)); /* clear memory */
451  strcpy(Queue[Index].ChildRecurse,CI.Partdir);
452  strcat(Queue[Index].ChildRecurse,CI.Partname);
453  Queue[Index].PI.StartTime = CI.PI.StartTime;
454  Queue[Index].ChildEnd=0;
455  Queue[Index].PI.Cmd = CI.PI.Cmd;
456  Queue[Index].PI.uploadtree_pk = CI.PI.uploadtree_pk;
457  Queue[Index].ChildStat = CI.Stat;
458  switch(CMD[CI.PI.Cmd].Type)
459  {
460  case CMD_ARC:
461  case CMD_AR:
462  case CMD_ISO:
463  case CMD_DISK:
464  case CMD_PARTITION:
465  case CMD_PACK:
466  case CMD_ZSTD:
467  CI.HasChild=1;
468  IsContainer=1;
469  strcat(Queue[Index].ChildRecurse,".dir");
470  strcat(CI.PartnameNew,".dir");
471  Queue[Index].PI.ChildRecurseArtifact=1;
472  /* make the directory */
473  if (MkDir(Queue[Index].ChildRecurse))
474  {
475  LOG_FATAL("Unable to mkdir(%s) in Traverse", Queue[Index].ChildRecurse)
476  if (!ForceContinue)
477  {
478  SafeExit(30);
479  }
480  }
481  if (CMD[CI.PI.Cmd].Type == CMD_PARTITION)
482  Queue[Index].PI.ChildRecurseArtifact=2;
483 
484  /* get the upload file name */
485  /* if the type of the upload file is CMD_PACK, and is top container,
486  * and using repository, then get the upload file name from DB
487  */
488  if (CMD_PACK == CMD[CI.PI.Cmd].Type && CI.TopContainer && UseRepository)
489  {
490  char *UFileName;
491  char SQL[MAXSQL];
492  snprintf(SQL, MAXSQL,"SELECT upload_filename FROM upload WHERE upload_pk = %s;",Upload_Pk);
493  result = PQexec(pgConn, SQL); // get name of the upload file
494  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
495  {
496  SafeExit(31);
497  }
498  UFileName = PQgetvalue(result,0,0);
499  PQclear(result);
500  if (strchr(UFileName, '/')) UFileName = strrchr(UFileName, '/') + 1;
501  memset(UploadFileName, '\0', FILENAME_MAX);
502  strncpy(UploadFileName, UFileName, FILENAME_MAX - 1);
503  }
504 
505  break;
506  case CMD_DEB:
507  case CMD_RPM:
508  CI.HasChild=1;
509  IsContainer=1;
510  strcat(Queue[Index].ChildRecurse,".unpacked");
511  strcat(CI.PartnameNew,".unpacked");
512  Queue[Index].PI.ChildRecurseArtifact=1;
513  if (CMD[CI.PI.Cmd].Type == CMD_PACK)
514  {
515  CI.IsCompressed = 1;
516  }
517  break;
518  case CMD_DEFAULT:
519  default:
520  /* use the original name */
521  CI.HasChild=0;
522  Queue[Index].ChildEnd=1;
523  break;
524  }
525  Queue[Index].ChildHasChild = CI.HasChild;
526 
527  /* save the file's data */
528  RecurseOk = DisplayContainerInfo(&CI,PI->Cmd);
529 
530  /* extract meta info if we added it */
531  if (RecurseOk && CMD[CI.PI.Cmd].MetaCmd && CMD[CI.PI.Cmd].MetaCmd[0])
532  {
533  /* extract meta info */
534  /* This needs to call AddToRepository() or DisplayContainerInfo() */
535  char Cmd[2*FILENAME_MAX];
536  char Fname[FILENAME_MAX];
537  memcpy(&CImeta,&CI,sizeof(CI));
538  CImeta.Artifact=1;
539  CImeta.HasChild=0;
540  CImeta.TopContainer = 0;
541  CImeta.PI.uploadtree_pk = CI.uploadtree_pk;
542  CImeta.PI.Cmd = 0; /* no meta type */
543  memset(Cmd,0,sizeof(Cmd));
544  memset(Fname,0,sizeof(Fname));
545  strcpy(Fname,CImeta.Source);
546  strcat(CImeta.Source,".meta");
547  strcat(CImeta.Partname,".meta");
548 
549  /* remove the destination file if it exists */
550  /* this gets past any permission problems with read-only files */
551  unlink(CImeta.Source);
552 
553  /* build the command and run it */
554  sprintf(Cmd,CMD[CI.PI.Cmd].MetaCmd,Fname,CImeta.Source);
555  rc = system(Cmd);
556  if (WIFSIGNALED(rc))
557  {
558  LOG_ERROR("Process killed by signal (%d): %s",WTERMSIG(rc),Cmd)
559  SafeExit(32);
560  }
561  if (WIFEXITED(rc)) rc = WEXITSTATUS(rc);
562  else rc=-1;
563  if (rc != 0) LOG_ERROR("Unable to run command '%s'",Cmd)
564  /* add it to the list of files */
565  RecurseOk = DisplayContainerInfo(&CImeta,PI->Cmd);
566  if (UnlinkAll) unlink(CImeta.Source);
567  }
568 
569  /* see if I need to spawn (if not, then save time by not!) */
570  if ((Queue[Index].ChildEnd == 1) && IsFile(Queue[Index].ChildRecurse,0))
571  {
572  goto TraverseEnd;
573  }
574 
575  /* spawn unpacker */
576  fflush(stdout); /* if no flush, then child may duplicate output! */
577  if (ListOutFile) fflush(ListOutFile);
578  if (RecurseOk)
579  {
580  Pid = fork();
581  if (Pid == 0) TraverseChild(Index,&CI,NewDir);
582  else
583  {
584  /* Parent: Save child info */
585  if (Pid == -1)
586  {
587  LOG_FATAL("Unable to fork child.")
588  SafeExit(33);
589  }
590  Queue[Index].ChildPid = Pid;
591 
592  // add by larry, start
593  Queue[Index].PI.uploadtree_pk = CI.uploadtree_pk;
594  // add by larry, end
595 
596  Thread++;
597  /* Parent: Continue testing files */
598  if (Thread >= MaxThread)
599  {
600  /* Too many children. Wait for one to end */
601  Index=ParentWait();
602  if (Index < 0) goto TraverseEnd; /* no more children (shouldn't happen here!) */
603  Thread--;
604  /* the value for ChildRecurse can/will be overwitten quickly, but
605  it will be overwritten AFTER it is used */
606  /* Only recurse if the name is different */
607  if (strcmp(Queue[Index].ChildRecurse,CI.Source) && !Queue[Index].ChildEnd)
608  {
609  /* copy over data */
610  CI.Corrupt = Queue[Index].ChildCorrupt;
611  CI.PI.StartTime = Queue[Index].PI.StartTime;
612  CI.PI.EndTime = Queue[Index].PI.EndTime;
613  CI.PI.uploadtree_pk = Queue[Index].PI.uploadtree_pk;
614  CI.HasChild = Queue[Index].ChildHasChild;
615  CI.Stat = Queue[Index].ChildStat;
616 #if 0
617  Queue[Index].PI.uploadtree_pk = CI.uploadtree_pk;
618 #endif
619  if (Recurse > 0)
620  Traverse(Queue[Index].ChildRecurse,NULL,"Called by dir/wait",NULL,Recurse-1,&Queue[Index].PI, ExcludePatterns);
621  else if (Recurse < 0)
622  Traverse(Queue[Index].ChildRecurse,NULL,"Called by dir/wait",NULL,Recurse,&Queue[Index].PI, ExcludePatterns);
623  if (ListOutFile)
624  {
625  fputs("</item>\n",ListOutFile);
626  TotalContainers++;
627  }
628  }
629  } /* if waiting for a child */
630  } /* if parent */
631  } /* if RecurseOk */
632  } /* if S_ISREG() */
633 
634  /***********************************************/
635  else
636  {
637  /* Not a file and not a directory */
638  if (PI->Cmd)
639  {
640  CI.HasChild = 0;
641  DisplayContainerInfo(&CI,PI->Cmd);
642  }
643  LOG_DEBUG("Skipping (not a file or directory): %s",CI.Source)
644  }
645 
646  TraverseEnd:
647  if (UnlinkAll && MaxThread <=1)
648  {
649 #if 0
650  printf("===\n");
651  printf("Source: '%s'\n",CI.Source);
652  printf("NewDir: '%s'\n",NewDir ? NewDir : "");
653  printf("Name: '%s' '%s'\n",CI.Partdir,CI.Partname);
654 #endif
655  if (!NewDir)
656  {
657  if (IsDir(CI.Source)) RemoveDir(CI.Source);
658  // else unlink(CI.Source);
659  }
660  else RemoveDir(NewDir);
661  }
662  return(IsContainer);
663 } /* 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, 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: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, char *ExcludePatterns)
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:622
int DisplayContainerInfo(ContainerInfo *CI, int Cmd)
Print what can be printed in XML.
Definition: utils.c:1458
int RemoveDir(char *dirpath)
Remove all files under dirpath (rm -rf)
Definition: utils.c:1642
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:1048
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:952
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:851
int ShouldExclude(char *Filename, const char *ExcludePatterns)
Determines if a file or folder should be excluded.
Definition: utils.c:1788
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:971
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