FOSSology  4.4.0
Open Source License Compliance by Open Source Software
ununpack-zstd.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2023 Siemens AG
3  SPDX-FileContributor: Gaurav Mishra <mishra.gaurav@siemens.com>
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 #include "ununpack.h"
9 #include "externs.h"
10 
23 int ExtractZstd(char *Source, const char *OrigName, char *Destination)
24 {
25  char Cmd[FILENAME_MAX * 4]; /* command to run */
26  int rc;
27  char TempSource[FILENAME_MAX];
28  char CWD[FILENAME_MAX];
29  char OutputName[FILENAME_MAX] = {'\0'};
30  char format[6] = {'\0'};
31  char formatCmd[17] = {'\0'};
32  int i;
33 
34  /* judge if the parameters are empty */
35  if ((NULL == Source) || (!strcmp(Source, "")) || (NULL == Destination) ||
36  (!strcmp(Destination, ""))) {
37  return 1;
38  }
39 
40  if (getcwd(CWD, sizeof(CWD)) == NULL) {
41  fprintf(stderr, "ERROR: directory name longer than %d characters\n",
42  (int) sizeof(CWD));
43  return (-1);
44  }
45 
46  i = 0;
47  while (OrigName[i] != '\0') {
48  if (OrigName[i] == '.') {
49  const char *ext = &OrigName[i + 1];
50  if (strncasecmp(ext, "zst", 3) == 0) {
51  strcpy(format, "zstd");
52  break;
53  }
54  else if (strncasecmp(ext, "tzst", 4) == 0) {
55  strcpy(format, "zstd");
56  break;
57  }
58  else if (strncasecmp(ext, "lzma", 4) == 0) {
59  strcpy(format, "lzma");
60  break;
61  }
62  else if (strncasecmp(ext, "xz", 2) == 0) {
63  strcpy(format, "xz");
64  break;
65  }
66  else if (strncasecmp(ext, "txz", 3) == 0) {
67  strcpy(format, "xz");
68  break;
69  }
70  else if (strncasecmp(ext, "lz4", 3) == 0) {
71  strcpy(format, "lz4");
72  break;
73  }
74  else if (strncasecmp(ext, "tlz4", 4) == 0) {
75  strcpy(format, "lz4");
76  break;
77  }
78  }
79  OutputName[i] = OrigName[i];
80  i++;
81  }
82 
83  if (strlen(format) > 1) {
84  snprintf(formatCmd, sizeof(formatCmd), " --format=%s", format);
85  }
86 
87  if (Verbose > 1) {
88  printf("CWD: %s\n", CWD);
89  if (!Quiet) { fprintf(stderr, "Extracting zstd: %s\n", Source); }
90  }
91 
92  if (chdir(Destination) != 0) {
93  fprintf(stderr, "ERROR %s.%d: Unable to change directory to %s\n",
94  __FILE__, __LINE__, Destination);
95  fprintf(stderr, "ERROR: errno is: %s\n", strerror(errno));
96  }
97 
98  if (TaintString(TempSource, FILENAME_MAX, Source, 1, NULL)) {
99  return (-1);
100  }
101  memset(Cmd, '\0', sizeof(Cmd));
102 
103  if (Verbose > 1) {
104  printf("Extracting zstd with output name: %s and format: %s\n", OutputName,
105  formatCmd);
106  }
107 
108  /* Let's extract file */
109  if (TempSource[0] != '/') {
110  snprintf(Cmd, sizeof(Cmd),
111  " (zstd --decompress --output-dir-flat '%s' -o '%s/%s'%s "
112  "'%s/%s') 2>/dev/null", Destination, Destination, OutputName, formatCmd,
113  CWD, TempSource);
114  }
115  else {
116  snprintf(Cmd, sizeof(Cmd),
117  " (zstd --decompress --output-dir-flat '%s' -o '%s/%s'%s "
118  "'%s') 2>/dev/null", Destination, Destination, OutputName, formatCmd,
119  TempSource);
120  }
121  rc = WEXITSTATUS(system(Cmd));
122  if (rc) {
123  fprintf(stderr, "ERROR: Command failed (rc=%d): %s\n", rc, Cmd);
124  }
125 
126  /* All done */
127  if (chdir(CWD) != 0) {
128  fprintf(stderr, "ERROR %s.%d: Unable to change directory to %s\n", __FILE__, __LINE__, CWD);
129  fprintf(stderr, "ERROR: errno is: %s\n", strerror(errno));
130  }
131  return (rc);
132 } /* ExtractZstd() */
int Verbose
Verbose level.
Definition: util.c:19
Stores all extern variables used by the agent.
int Quiet
Run in quiet mode?
char * TaintString(char *S)
Create a string with taint quoting.
Definition: finder.c:35
int ExtractZstd(char *Source, const char *OrigName, char *Destination)
Given a ZSTd file, extract the contents to the directory.
Definition: ununpack-zstd.c:23