Greenbone Vulnerability Management Libraries  22.8.0
fileutils.c
Go to the documentation of this file.
1 /* SPDX-FileCopyrightText: 2009-2023 Greenbone AG
2  *
3  * SPDX-License-Identifier: GPL-2.0-or-later
4  */
5 
11 /* time.h in glibc2 needs this for strptime. */
12 #define _GNU_SOURCE
13 
14 #include "fileutils.h"
15 
16 #include <errno.h> /* for errno */
17 #include <gio/gio.h> /* for g_file_new_for_path, GFile */
18 #include <glib/gstdio.h> /* for g_lstat, g_remove */
19 #include <glib/gtypes.h> /* for gsize */
20 #include <string.h> /* for strlen, memset, strcmp */
21 #include <sys/stat.h> /* for stat, S_ISDIR */
22 #include <time.h> /* for tm, strptime, localtime, time, time_t */
23 
24 #undef G_LOG_DOMAIN
25 
28 #define G_LOG_DOMAIN "libgvm util"
29 
44 int
46 {
47  struct stat sb;
48 
49  if (g_lstat (name, &sb))
50  {
51  g_warning ("g_lstat(%s) failed - %s\n", name, g_strerror (errno));
52  return -1;
53  }
54 
55  return S_ISDIR (sb.st_mode);
56 }
57 
70 int
71 gvm_file_exists (const char *name)
72 {
73  return eaccess (name, F_OK) == 0;
74 }
75 
88 int
89 gvm_file_is_executable (const char *name)
90 {
91  return eaccess (name, X_OK) == 0;
92 }
93 
106 int
107 gvm_file_is_readable (const char *name)
108 {
109  return eaccess (name, R_OK) == 0;
110 }
111 
122 int
123 gvm_file_remove_recurse (const gchar *pathname)
124 {
125  if (gvm_file_check_is_dir (pathname) == 1)
126  {
127  GError *error = NULL;
128  GDir *directory = g_dir_open (pathname, 0, &error);
129 
130  if (directory == NULL)
131  {
132  g_warning ("g_dir_open(%s) failed - %s\n", pathname, error->message);
133  g_error_free (error);
134  return -1;
135  }
136  else
137  {
138  int ret = 0;
139  const gchar *entry = NULL;
140 
141  while ((entry = g_dir_read_name (directory)) && (ret == 0))
142  {
143  gchar *entry_path = g_build_filename (pathname, entry, NULL);
144  ret = gvm_file_remove_recurse (entry_path);
145  g_free (entry_path);
146  if (ret != 0)
147  {
148  g_warning ("Failed to remove %s from %s!", entry, pathname);
149  g_dir_close (directory);
150  return ret;
151  }
152  }
153  g_dir_close (directory);
154  }
155  }
156 
157  return g_remove (pathname);
158 }
159 
170 gboolean
171 gvm_file_copy (const gchar *source_file, const gchar *dest_file)
172 {
173  gboolean rc;
174  GFile *sfile, *dfile;
175  GError *error;
176 
177  sfile = g_file_new_for_path (source_file);
178  dfile = g_file_new_for_path (dest_file);
179  error = NULL;
180 
181  rc =
182  g_file_copy (sfile, dfile, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
183  if (!rc)
184  {
185  g_warning ("%s: g_file_copy(%s, %s) failed - %s\n", __func__, source_file,
186  dest_file, error->message);
187  g_error_free (error);
188  }
189 
190  g_object_unref (sfile);
191  g_object_unref (dfile);
192  return rc;
193 }
194 
205 gboolean
206 gvm_file_move (const gchar *source_file, const gchar *dest_file)
207 {
208  gboolean rc;
209  GFile *sfile, *dfile;
210  GError *error;
211 
212  sfile = g_file_new_for_path (source_file);
213  dfile = g_file_new_for_path (dest_file);
214  error = NULL;
215 
216  rc =
217  g_file_move (sfile, dfile, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
218  if (!rc)
219  {
220  g_warning ("%s: g_file_move(%s, %s) failed - %s\n", __func__, source_file,
221  dest_file, error->message);
222  g_error_free (error);
223  }
224 
225  g_object_unref (sfile);
226  g_object_unref (dfile);
227  return rc;
228 }
229 
237 char *
238 gvm_file_as_base64 (const char *path)
239 {
240  GError *error = NULL;
241  char *content, *encoded;
242  gsize len;
243 
244  if (!g_file_get_contents (path, &content, &len, &error))
245  {
246  g_error_free (error);
247  return NULL;
248  }
249  encoded = g_base64_encode ((guchar *) content, len);
250  g_free (content);
251  return encoded;
252 }
253 
268 gchar *
269 gvm_export_file_name (const char *fname_format, const char *username,
270  const char *type, const char *uuid,
271  const char *creation_iso_time,
272  const char *modification_iso_time, const char *name,
273  const char *format_name)
274 {
275  time_t now;
276  struct tm now_broken;
277  gchar *now_date_str, *creation_date_str, *modification_date_str;
278  gchar *now_time_str, *creation_time_str, *modification_time_str;
279  struct tm creation_time, modification_time;
280  gchar *creation_date_short, *modification_date_short;
281  gchar *fname_point;
282  GString *file_name_buf;
283  int format_state = 0;
284  char *ret;
285 
286  creation_date_str = NULL;
287  modification_date_str = NULL;
288  creation_time_str = NULL;
289  modification_time_str = NULL;
290 
291  now = time (NULL);
292  if (localtime_r (&now, &now_broken) == NULL)
293  {
294  g_warning ("%s: localtime failed", __func__);
295  }
296  now_date_str = g_strdup_printf ("%04d%02d%02d", (now_broken.tm_year + 1900),
297  (now_broken.tm_mon + 1), now_broken.tm_mday);
298  now_time_str = g_strdup_printf ("%02d%02d%02d", now_broken.tm_hour,
299  now_broken.tm_min, now_broken.tm_sec);
300 
301  memset (&creation_time, 0, sizeof (struct tm));
302  memset (&modification_time, 0, sizeof (struct tm));
303  creation_date_short = NULL;
304  modification_date_short = NULL;
305 
306  if (creation_iso_time && (strlen (creation_iso_time) >= 19))
307  creation_date_short = g_strndup (creation_iso_time, 19);
308 
309  if (creation_date_short
310  && (((ret = strptime (creation_date_short, "%Y-%m-%dT%H:%M:%S",
311  &creation_time))
312  == NULL)
313  || (strlen (ret) == 0)))
314  {
315  creation_date_str =
316  g_strdup_printf ("%04d%02d%02d", (creation_time.tm_year + 1900),
317  (creation_time.tm_mon + 1), creation_time.tm_mday);
318  creation_time_str =
319  g_strdup_printf ("%02d%02d%02d", creation_time.tm_hour,
320  creation_time.tm_min, creation_time.tm_sec);
321  }
322 
323  if (modification_iso_time && (strlen (modification_iso_time) >= 19))
324  modification_date_short = g_strndup (modification_iso_time, 19);
325 
326  if (modification_date_short
327  && (((ret = strptime (modification_date_short, "%Y-%m-%dT%H:%M:%S",
328  &modification_time))
329  == NULL)
330  || (strlen (ret) == 0)))
331  {
332  modification_date_str = g_strdup_printf (
333  "%04d%02d%02d", (modification_time.tm_year + 1900),
334  (modification_time.tm_mon + 1), modification_time.tm_mday);
335 
336  modification_time_str =
337  g_strdup_printf ("%02d%02d%02d", modification_time.tm_hour,
338  modification_time.tm_min, modification_time.tm_sec);
339  }
340 
341  if (creation_date_str == NULL)
342  creation_date_str = g_strdup (now_date_str);
343  if (modification_date_str == NULL)
344  modification_date_str = g_strdup (creation_date_str);
345  if (creation_time_str == NULL)
346  creation_time_str = g_strdup (now_time_str);
347  if (modification_time_str == NULL)
348  modification_time_str = g_strdup (creation_time_str);
349 
350  file_name_buf = g_string_new ("");
351 
352  fname_point = (char *) fname_format;
353 
354  while (format_state >= 0 && *fname_point != '\0')
355  {
356  if (format_state == 0)
357  {
358  if (*fname_point == '%')
359  format_state = 1;
360  else if (*fname_point == '"')
361  g_string_append (file_name_buf, "\\\"");
362  else if (*fname_point <= ' ')
363  g_string_append_c (file_name_buf, '_');
364  else
365  g_string_append_c (file_name_buf, *fname_point);
366  }
367  else if (format_state == 1)
368  {
369  format_state = 0;
370  switch (*fname_point)
371  {
372  case 'C':
373  g_string_append (file_name_buf, creation_date_str);
374  break;
375  case 'c':
376  g_string_append (file_name_buf, creation_time_str);
377  break;
378  case 'd':
379  g_string_append_printf (file_name_buf, "%02d",
380  modification_time.tm_mday);
381  break;
382  case 'D':
383  g_string_append (file_name_buf, now_date_str);
384  break;
385  case 'F':
386  g_string_append (file_name_buf,
387  format_name ? format_name : "XML");
388  break;
389  case 'M':
390  g_string_append (file_name_buf, modification_date_str);
391  break;
392  case 'm':
393  g_string_append (file_name_buf, modification_time_str);
394  break;
395  case 'N':
396  g_string_append (file_name_buf,
397  name ? name : (type ? type : "unnamed"));
398  break;
399  case 'o':
400  g_string_append_printf (file_name_buf, "%02d",
401  modification_time.tm_mon + 1);
402  break;
403  case 'T':
404  g_string_append (file_name_buf, type ? type : "resource");
405  break;
406  case 't':
407  g_string_append (file_name_buf, now_time_str);
408  break;
409  case 'U':
410  g_string_append (file_name_buf, uuid ? uuid : "list");
411  break;
412  case 'u':
413  g_string_append (file_name_buf, username ? username : "");
414  break;
415  case 'Y':
416  g_string_append_printf (file_name_buf, "%04d",
417  modification_time.tm_year + 1900);
418  break;
419  case '%':
420  g_string_append_c (file_name_buf, '%');
421  break;
422  default:
423  g_warning ("%s : Unknown file name format placeholder: %%%c.",
424  __func__, *fname_point);
425  format_state = -1;
426  }
427  }
428  fname_point += sizeof (char);
429  }
430 
431  if (format_state || strcmp (file_name_buf->str, "") == 0)
432  {
433  g_warning ("%s : Invalid file name format", __func__);
434  g_string_free (file_name_buf, TRUE);
435  return NULL;
436  }
437 
438  fname_point = file_name_buf->str;
439  while (*fname_point != '\0')
440  {
441  if (*fname_point <= ' ')
442  *fname_point = '_';
443  fname_point++;
444  }
445 
446  g_free (now_date_str);
447  g_free (creation_date_str);
448  g_free (creation_time_str);
449  g_free (modification_date_str);
450  return g_string_free (file_name_buf, FALSE);
451 }
gvm_file_remove_recurse
int gvm_file_remove_recurse(const gchar *pathname)
Recursively removes files and directories.
Definition: fileutils.c:123
gvm_file_check_is_dir
int gvm_file_check_is_dir(const char *name)
Checks whether a file is a directory or not.
Definition: fileutils.c:45
fileutils.h
Protos for file utility functions.
gvm_file_is_executable
int gvm_file_is_executable(const char *name)
Checks whether a file or directory exists and is executable.
Definition: fileutils.c:89
gvm_file_as_base64
char * gvm_file_as_base64(const char *path)
Get the content of a file in base64 format.
Definition: fileutils.c:238
gvm_file_move
gboolean gvm_file_move(const gchar *source_file, const gchar *dest_file)
Moves a source file into a destination file.
Definition: fileutils.c:206
gvm_file_exists
int gvm_file_exists(const char *name)
Checks whether a file or directory exists.
Definition: fileutils.c:71
osp_param::name
char * name
Definition: osp.c:49
gvm_file_is_readable
int gvm_file_is_readable(const char *name)
Checks whether a file or directory exists and is readable.
Definition: fileutils.c:107
gvm_file_copy
gboolean gvm_file_copy(const gchar *source_file, const gchar *dest_file)
Copies a source file into a destination file.
Definition: fileutils.c:171
gvm_export_file_name
gchar * gvm_export_file_name(const char *fname_format, const char *username, const char *type, const char *uuid, const char *creation_iso_time, const char *modification_iso_time, const char *name, const char *format_name)
Generates a file name for exporting.
Definition: fileutils.c:269