fileutils.c
Go to the documentation of this file.
/* SPDX-FileCopyrightText: 2009-2023 Greenbone AG
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/* time.h in glibc2 needs this for strptime. */
#define _GNU_SOURCE
#include "fileutils.h"
#include <errno.h> /* for errno */
#include <gio/gio.h> /* for g_file_new_for_path, GFile */
#include <glib/gstdio.h> /* for g_lstat, g_remove */
#include <glib/gtypes.h> /* for gsize */
#include <string.h> /* for strlen, memset, strcmp */
#include <sys/stat.h> /* for stat, S_ISDIR */
#include <time.h> /* for tm, strptime, localtime, time, time_t */
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "libgvm util"
int
gvm_file_check_is_dir (const char *name)
{
struct stat sb;
if (g_lstat (name, &sb))
{
g_warning ("g_lstat(%s) failed - %s\n", name, g_strerror (errno));
return -1;
}
return S_ISDIR (sb.st_mode);
}
int
gvm_file_exists (const char *name)
{
return eaccess (name, F_OK) == 0;
}
int
gvm_file_is_executable (const char *name)
{
return eaccess (name, X_OK) == 0;
}
int
gvm_file_is_readable (const char *name)
{
return eaccess (name, R_OK) == 0;
}
int
gvm_file_remove_recurse (const gchar *pathname)
{
if (gvm_file_check_is_dir (pathname) == 1)
{
GError *error = NULL;
GDir *directory = g_dir_open (pathname, 0, &error);
if (directory == NULL)
{
g_warning ("g_dir_open(%s) failed - %s\n", pathname, error->message);
g_error_free (error);
return -1;
}
else
{
int ret = 0;
const gchar *entry = NULL;
while ((entry = g_dir_read_name (directory)) && (ret == 0))
{
gchar *entry_path = g_build_filename (pathname, entry, NULL);
ret = gvm_file_remove_recurse (entry_path);
g_free (entry_path);
if (ret != 0)
{
g_warning ("Failed to remove %s from %s!", entry, pathname);
g_dir_close (directory);
return ret;
}
}
g_dir_close (directory);
}
}
return g_remove (pathname);
}
gboolean
gvm_file_copy (const gchar *source_file, const gchar *dest_file)
{
gboolean rc;
GFile *sfile, *dfile;
GError *error;
sfile = g_file_new_for_path (source_file);
dfile = g_file_new_for_path (dest_file);
error = NULL;
rc =
g_file_copy (sfile, dfile, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
if (!rc)
{
g_warning ("%s: g_file_copy(%s, %s) failed - %s\n", __func__, source_file,
dest_file, error->message);
g_error_free (error);
}
g_object_unref (sfile);
g_object_unref (dfile);
return rc;
}
gboolean
gvm_file_move (const gchar *source_file, const gchar *dest_file)
{
gboolean rc;
GFile *sfile, *dfile;
GError *error;
sfile = g_file_new_for_path (source_file);
dfile = g_file_new_for_path (dest_file);
error = NULL;
rc =
g_file_move (sfile, dfile, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
if (!rc)
{
g_warning ("%s: g_file_move(%s, %s) failed - %s\n", __func__, source_file,
dest_file, error->message);
g_error_free (error);
}
g_object_unref (sfile);
g_object_unref (dfile);
return rc;
}
char *
gvm_file_as_base64 (const char *path)
{
GError *error = NULL;
char *content, *encoded;
gsize len;
if (!g_file_get_contents (path, &content, &len, &error))
{
g_error_free (error);
return NULL;
}
encoded = g_base64_encode ((guchar *) content, len);
g_free (content);
return encoded;
}
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)
{
time_t now;
struct tm now_broken;
gchar *now_date_str, *creation_date_str, *modification_date_str;
gchar *now_time_str, *creation_time_str, *modification_time_str;
struct tm creation_time, modification_time;
gchar *creation_date_short, *modification_date_short;
gchar *fname_point;
GString *file_name_buf;
int format_state = 0;
char *ret;
creation_date_str = NULL;
modification_date_str = NULL;
creation_time_str = NULL;
modification_time_str = NULL;
now = time (NULL);
if (localtime_r (&now, &now_broken) == NULL)
{
g_warning ("%s: localtime failed", __func__);
}
now_date_str = g_strdup_printf ("%04d%02d%02d", (now_broken.tm_year + 1900),
(now_broken.tm_mon + 1), now_broken.tm_mday);
now_time_str = g_strdup_printf ("%02d%02d%02d", now_broken.tm_hour,
now_broken.tm_min, now_broken.tm_sec);
memset (&creation_time, 0, sizeof (struct tm));
memset (&modification_time, 0, sizeof (struct tm));
creation_date_short = NULL;
modification_date_short = NULL;
if (creation_iso_time && (strlen (creation_iso_time) >= 19))
creation_date_short = g_strndup (creation_iso_time, 19);
if (creation_date_short
&& (((ret = strptime (creation_date_short, "%Y-%m-%dT%H:%M:%S",
&creation_time))
== NULL)
|| (strlen (ret) == 0)))
{
creation_date_str =
g_strdup_printf ("%04d%02d%02d", (creation_time.tm_year + 1900),
(creation_time.tm_mon + 1), creation_time.tm_mday);
creation_time_str =
g_strdup_printf ("%02d%02d%02d", creation_time.tm_hour,
creation_time.tm_min, creation_time.tm_sec);
}
g_free (creation_date_short);
if (modification_iso_time && (strlen (modification_iso_time) >= 19))
modification_date_short = g_strndup (modification_iso_time, 19);
if (modification_date_short
&& (((ret = strptime (modification_date_short, "%Y-%m-%dT%H:%M:%S",
&modification_time))
== NULL)
|| (strlen (ret) == 0)))
{
modification_date_str = g_strdup_printf (
"%04d%02d%02d", (modification_time.tm_year + 1900),
(modification_time.tm_mon + 1), modification_time.tm_mday);
modification_time_str =
g_strdup_printf ("%02d%02d%02d", modification_time.tm_hour,
modification_time.tm_min, modification_time.tm_sec);
}
g_free (modification_date_short);
if (creation_date_str == NULL)
creation_date_str = g_strdup (now_date_str);
if (modification_date_str == NULL)
modification_date_str = g_strdup (creation_date_str);
if (creation_time_str == NULL)
creation_time_str = g_strdup (now_time_str);
if (modification_time_str == NULL)
modification_time_str = g_strdup (creation_time_str);
file_name_buf = g_string_new ("");
fname_point = (char *) fname_format;
while (format_state >= 0 && *fname_point != '\0')
{
if (format_state == 0)
{
if (*fname_point == '%')
format_state = 1;
else if (*fname_point == '"')
g_string_append (file_name_buf, "\\\"");
else if (*fname_point <= ' ')
g_string_append_c (file_name_buf, '_');
else
g_string_append_c (file_name_buf, *fname_point);
}
else if (format_state == 1)
{
format_state = 0;
switch (*fname_point)
{
case 'C':
g_string_append (file_name_buf, creation_date_str);
break;
case 'c':
g_string_append (file_name_buf, creation_time_str);
break;
case 'd':
g_string_append_printf (file_name_buf, "%02d",
modification_time.tm_mday);
break;
case 'D':
g_string_append (file_name_buf, now_date_str);
break;
case 'F':
g_string_append (file_name_buf,
format_name ? format_name : "XML");
break;
case 'M':
g_string_append (file_name_buf, modification_date_str);
break;
case 'm':
g_string_append (file_name_buf, modification_time_str);
break;
case 'N':
g_string_append (file_name_buf,
name ? name : (type ? type : "unnamed"));
break;
case 'o':
g_string_append_printf (file_name_buf, "%02d",
modification_time.tm_mon + 1);
break;
case 'T':
g_string_append (file_name_buf, type ? type : "resource");
break;
case 't':
g_string_append (file_name_buf, now_time_str);
break;
case 'U':
g_string_append (file_name_buf, uuid ? uuid : "list");
break;
case 'u':
g_string_append (file_name_buf, username ? username : "");
break;
case 'Y':
g_string_append_printf (file_name_buf, "%04d",
modification_time.tm_year + 1900);
break;
case '%':
g_string_append_c (file_name_buf, '%');
break;
default:
g_warning ("%s : Unknown file name format placeholder: %%%c.",
__func__, *fname_point);
format_state = -1;
}
}
fname_point += sizeof (char);
}
if (format_state || strcmp (file_name_buf->str, "") == 0)
{
g_warning ("%s : Invalid file name format", __func__);
g_string_free (file_name_buf, TRUE);
return NULL;
}
fname_point = file_name_buf->str;
while (*fname_point != '\0')
{
if (*fname_point <= ' ')
*fname_point = '_';
fname_point++;
}
g_free (now_date_str);
g_free (now_time_str);
g_free (creation_date_str);
g_free (creation_time_str);
g_free (modification_date_str);
g_free (modification_time_str);
return g_string_free (file_name_buf, FALSE);
}
gvm_file_remove_recurse
int gvm_file_remove_recurse(const gchar *pathname)
Recursively removes files and directories.
Definition fileutils.c:123
gvm_file_exists
int gvm_file_exists(const char *name)
Checks whether a file or directory exists.
Definition fileutils.c:71
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
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
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_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_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_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
fileutils.h
Protos for file utility functions.