FOSSology  4.4.0
Open Source License Compliance by Open Source Software
ununpack-ar.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2007-2011 Hewlett-Packard Development Company, L.P.
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
7 #include "ununpack.h"
8 #include "externs.h"
9 
26 int ExtractAR (char *Source, char *Destination)
27 {
28  char Cmd[FILENAME_MAX*4]; /* command to run */
29  char Line[FILENAME_MAX];
30  char *s; /* generic string pointer */
31  FILE *Fin;
32  int rc;
33  char TempSource[FILENAME_MAX];
34  char CWD[FILENAME_MAX];
35 
36  /* judge if the parameters are empty */
37  if ((NULL == Source) || (!strcmp(Source, "")) || (NULL == Destination) || (!strcmp(Destination, "")))
38  return 1;
39 
40  if (getcwd(CWD,sizeof(CWD)) == NULL)
41  {
42  fprintf(stderr,"ERROR: directory name longer than %d characters\n",(int)sizeof(CWD));
43  return(-1);
44  }
45  if (Verbose > 1)
46  {
47  printf("CWD: %s\n",CWD);
48  if (!Quiet) fprintf(stderr,"Extracting ar: %s\n",Source);
49  }
50 
51  if(chdir(Destination) != 0)
52  {
53  fprintf(stderr, "ERROR %s.%d: Unable to change directory to %s\n",
54  __FILE__, __LINE__, Destination);
55  fprintf(stderr, "ERROR: errno is: %s\n", strerror(errno));
56  }
57 
58  if (TaintString(TempSource,FILENAME_MAX,Source,1,NULL))
59  return(-1);
60  memset(Cmd,'\0',sizeof(Cmd));
61 
62  /* get list of directories and make the directories */
63  /* Cmd: ar t %s 2>/dev/null | grep '^Directory' */
64  if (TempSource[0] != '/')
65  snprintf(Cmd,sizeof(Cmd)," (ar t '%s/%s') 2>/dev/null",CWD,TempSource);
66  else
67  snprintf(Cmd,sizeof(Cmd)," (ar t '%s') 2>/dev/null",TempSource);
68 
69  Fin = popen(Cmd,"r");
70  if (!Fin)
71  {
72  fprintf(stderr,"ERROR: ar failed: %s\n",Cmd);
73  if(chdir(CWD) != 0)
74  {
75  fprintf(stderr, "ERROR %s.%d: Unable to change directory to %s\n",
76  __FILE__, __LINE__, CWD);
77  fprintf(stderr, "ERROR: errno is: %s\n", strerror(errno));
78  }
79  return(-1);
80  }
81  while(ReadLine(Fin,Line,sizeof(Line)-1) >= 0)
82  {
83  /* each line is a file. Check for directories. */
84  if (Line[0]=='/') { pclose(Fin); return(1); } /* NO ABSOLUTE PATHS! */
85  s=strrchr(Line,'/'); /* find the last slash */
86  if (s == NULL) continue;
87  s[0]='\0';
88  if (MkDir(Line))
89  {
90  fprintf(stderr,"ERROR: Unable to mkdir(%s) in ExtractAR\n",Line);
91  if (!ForceContinue) exit(-1);
92  }
93  }
94  pclose(Fin);
95 
96  /* Now let's extract each file */
97  if (TempSource[0] != '/')
98  snprintf(Cmd,sizeof(Cmd)," (ar x '%s/%s') 2>/dev/null",CWD,TempSource);
99  else
100  snprintf(Cmd,sizeof(Cmd)," (ar x '%s') 2>/dev/null",TempSource);
101  rc = WEXITSTATUS(system(Cmd));
102  if (rc)
103  {
104  fprintf(stderr,"ERROR: Command failed (rc=%d): %s\n",rc,Cmd);
105  }
106 
107  /* All done */
108  if(chdir(CWD) != 0)
109  {
110  fprintf(stderr, "ERROR %s.%d: Unable to change directory to %s\n",
111  __FILE__, __LINE__, CWD);
112  fprintf(stderr, "ERROR: errno is: %s\n", strerror(errno));
113  }
114  return(rc);
115 } /* ExtractAR() */
int Verbose
Verbose level.
Definition: util.c:19
Stores all extern variables used by the agent.
int Quiet
Run in quiet mode?
int ForceContinue
Force continue when unpack tool fails?
char * TaintString(char *S)
Create a string with taint quoting.
Definition: finder.c:35
int s
The socket that the CLI will use to communicate.
Definition: fo_cli.c:37
int ReadLine(FILE *Fin, char *Line, int MaxLine)
Definition: repcopyin.c:64
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 MkDir(char *Fname)
Smart mkdir.
Definition: utils.c:303