Skip to content

Commit

Permalink
maint: Refactor trashinfo; cleanup (#492)
Browse files Browse the repository at this point in the history
* maint: Cleanup trashinfo

* more cleanup, obliterate union

* Add error-checking to fprintf when writing trashinfo file

* combine enums

* Move some vars into globals.c

* rename function

* narrow scope of LEN_DELETION_DATE_KEY_WITH_VALUE
  • Loading branch information
andy5995 authored Nov 20, 2024
1 parent 487357a commit 70afe64
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 152 deletions.
3 changes: 1 addition & 2 deletions src/config_rmw.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// #include <sys/sysmacros.h> // for major() and minor()

static const int DEFAULT_EXPIRE_AGE = 0;
static const char *lit_files = "files";

const char *expire_age_str = "expire_age";

Expand Down Expand Up @@ -243,7 +242,7 @@ parse_line_waste(st_waste *waste_curr, struct Canfigger *node,
}

/* and the files... */
waste_curr->files = join_paths(waste_curr->parent, lit_files);
waste_curr->files = join_paths(waste_curr->parent, "files");
waste_curr->len_files = strlen(waste_curr->files);

int p_state = check_pathname_state(waste_curr->files);
Expand Down
3 changes: 3 additions & 0 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "globals.h"

int verbose = 0;
const char *lit_info = "info";
const char trashinfo_ext[] = ".trashinfo";
const int len_trashinfo_ext = sizeof trashinfo_ext - 1; /* Subtract 1 for the terminating NULL */
17 changes: 12 additions & 5 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VERSION "unversioned"
#endif

#ifndef PATH_MAX
#define PATH_MAX 4096
#endif

#define LEN_MAX_ESCAPED_PATH (((PATH_MAX - 1) * 3) + 1)
#define LEN_MAX_ESCAPED_PATH (PATH_MAX * 3)

#define EBUF 11

typedef enum
{
TI_HEADER,
PATH_KEY,
DELETIONDATE_KEY,
TI_LINE_MAX
} ti_key;

extern int verbose;
extern const char *lit_info;
extern const char trashinfo_ext[];
extern const int len_trashinfo_ext;
2 changes: 1 addition & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ main(const int argc, char *const argv[])
parse_cli_options(argc, argv, &cli_user_options);

if (verbose > 1)
printf("PATH_MAX = %d\n", PATH_MAX - 1);
printf("PATH_MAX = %d\n", PATH_MAX);

if (verbose > 0)
#ifdef HAVE_LINUX_BTRFS
Expand Down
3 changes: 1 addition & 2 deletions src/messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ display_dot_trashinfo_error(const char *dti)
* "format" refers to the layout of the file
* contents
*/
printf(_("format of .trashinfo `file %s` is incorrect"), dti);
putchar('\n');
printf(_("format of .trashinfo file '%s' is incorrect\n"), dti);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/purging.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static time_t
get_then_time(const char *tinfo_file)
{
char *raw_deletion_date =
parse_trashinfo_file(tinfo_file, deletion_date_key);
validate_and_get_value(tinfo_file, DELETIONDATE_KEY);
if (raw_deletion_date != NULL)
{
struct tm tm_then;
Expand Down
2 changes: 1 addition & 1 deletion src/restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ restore(const char *src, st_time *st_time_var,
tmp_str = NULL;
sn_check(r, PATH_MAX);

char *_dest = parse_trashinfo_file(src_tinfo, path_key);
char *_dest = validate_and_get_value(src_tinfo, PATH_KEY);
if (_dest == NULL)
return -1;

Expand Down
199 changes: 93 additions & 106 deletions src/trashinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,17 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdint.h>

#include "trashinfo.h"
#include "utils.h"
#include "messages.h"

#define TI_LINE_COUNT 3

enum
{
TI_HEADER,
TI_PATH_LINE,
TI_DATE_LINE
};

static const char ti_header[] = "[Trash Info]";
static const char ti_path[] = "Path=";
static const char ti_date[] = "DeletionDate=";
const size_t LEN_MAX_TRASHINFO_PATH_LINE =
sizeof "Path=" + LEN_MAX_ESCAPED_PATH - 1;

static const struct st__trashinfo st_trashinfo_template[] = {
{ti_header, sizeof ti_header - 1},
{ti_path, sizeof ti_path - 1},
{ti_date, sizeof ti_date - 1},
};

const char trashinfo_ext[] = ".trashinfo";
const int len_trashinfo_ext = sizeof trashinfo_ext - 1; /* Subtract 1 for the terminating NULL */
const int LEN_MAX_TRASHINFO_PATH_LINE =
(sizeof ti_path - 1) + LEN_MAX_ESCAPED_PATH;

const char *lit_info = "info";
const char *path_key = "Path";
const char *deletion_date_key = "DeletionDate";
const struct trashinfo_template trashinfo_template =
{ "[Trash Info]", "Path=", "DeletionDate=" };


int
Expand Down Expand Up @@ -105,13 +85,32 @@ create_trashinfo(rmw_target *st_f_props, st_waste *waste_curr,
}
}

fprintf(fp, "%s\n", st_trashinfo_template[TI_HEADER].str);
fprintf(fp, "%s%s\n", st_trashinfo_template[TI_PATH_LINE].str,
escaped_path_ptr);
ssize_t want_size = strlen(trashinfo_template.header) + 1 +
strlen(trashinfo_template.path_key) +
strlen(escaped_path_ptr) + 1 +
strlen(trashinfo_template.deletion_date_key) +
strlen(st_time_var->deletion_date) + 1;

int n = fprintf(fp, "%s\n%s%s\n%s%s\n", trashinfo_template.header,
trashinfo_template.path_key, escaped_path_ptr,
trashinfo_template.deletion_date_key,
st_time_var->deletion_date);

free(escaped_path);
fprintf(fp, "%s%s\n", st_trashinfo_template[TI_DATE_LINE].str,
st_time_var->deletion_date);

if (n < 0)
{
print_msg_error();
fprintf(stderr, "fprintf() failed due to an error writing to %s\n",
final_info_dest);
}
else if (n != want_size)
{
print_msg_error();
fprintf(stderr,
"Expected to write %zu bytes, but wrote %d bytes to %s\n",
want_size, n, final_info_dest);
}
return close_file(&fp, final_info_dest, __func__);
}
else
Expand All @@ -122,108 +121,96 @@ create_trashinfo(rmw_target *st_f_props, st_waste *waste_curr,
}


/*
* name: parse_trashinfo_file
*
* Checks the integrity of a trashinfo file and returns req_value for
* either the Path or DeletionDate key
*
*/
char *
parse_trashinfo_file(const char *file, const char *req_value)
validate_and_get_value(const char *file, ti_key key)
{
struct trashinfo_field trashinfo_field;
if (strcmp(req_value, path_key) != 0
&& strcmp(req_value, deletion_date_key) != 0)
const uint8_t LEN_DELETION_DATE_KEY_WITH_VALUE = 32;
struct
{
print_msg_error();
fprintf(stderr, "Required arg for %s can be either \"%s\" or \"%s\".",
__func__, path_key, deletion_date_key);
return NULL;
}
bool header_ok;
bool path_ok;
bool date_ok;
} ti_status = { false, false, false };

int line_no = 0;
FILE *fp = fopen(file, "r");
if (fp != NULL)
{
trashinfo_field.value = NULL;
bool res = true;
char *key_value = NULL;
uint8_t line_n = 0;

char fp_line[LEN_MAX_TRASHINFO_PATH_LINE];
while (fgets(fp_line, LEN_MAX_TRASHINFO_PATH_LINE, fp) != NULL
&& res == true)
&& line_n < TI_LINE_MAX)
{
trim_whitespace(fp_line);

switch (line_no)
char *val_ptr;
switch (line_n)
{
case TI_HEADER:
res =
strncmp(fp_line, st_trashinfo_template[TI_HEADER].str,
st_trashinfo_template[TI_HEADER].len) == 0;
ti_status.header_ok =
(strcmp(fp_line, trashinfo_template.header) == 0);
break;
case TI_PATH_LINE:
res =
strncmp(fp_line, st_trashinfo_template[TI_PATH_LINE].str,
st_trashinfo_template[TI_PATH_LINE].len) == 0;
if (res && strcmp(req_value, path_key) == 0)
case PATH_KEY:
ti_status.path_ok =
(strncmp
(fp_line, trashinfo_template.path_key,
strlen(trashinfo_template.path_key)) == 0);
if (ti_status.path_ok && key == PATH_KEY)
{
trashinfo_field.f.path_ptr = strchr(fp_line, '=');
trashinfo_field.f.path_ptr++; /* move past the '=' sign */
char *unescaped_path = unescape_url(trashinfo_field.f.path_ptr);
trashinfo_field.value = unescaped_path;
val_ptr = strchr(fp_line, '=');
if (val_ptr)
{
val_ptr++; /* move past the '=' sign */
char *unescaped_path = unescape_url(val_ptr);
if (!unescaped_path)
fatal_malloc();
key_value = unescaped_path;
}
}
break;
case TI_DATE_LINE:
res =
strncmp(fp_line, st_trashinfo_template[TI_DATE_LINE].str,
st_trashinfo_template[TI_DATE_LINE].len) == 0
&& strlen(fp_line) == 32;

if (res && strcmp(req_value, deletion_date_key) == 0)
case DELETIONDATE_KEY:
ti_status.date_ok =
(strncmp(fp_line, trashinfo_template.deletion_date_key,
strlen(trashinfo_template.deletion_date_key)) == 0)
&& strlen(fp_line) == LEN_DELETION_DATE_KEY_WITH_VALUE;
if (ti_status.date_ok && key == DELETIONDATE_KEY)
{
trashinfo_field.f.date_str_ptr = strchr(fp_line, '=');
trashinfo_field.f.date_str_ptr++;
trashinfo_field.value = strdup(trashinfo_field.f.date_str_ptr);
if (!trashinfo_field.value)
fatal_malloc();
val_ptr = strchr(fp_line, '=');
if (val_ptr)
{
val_ptr++;
key_value = strdup(val_ptr);
if (!key_value)
fatal_malloc();
}
}
break;
default:
res = false;
break;
}
line_no++;
line_n++;
}
close_file(&fp, file, __func__);

if (res && line_no == TI_LINE_COUNT)
return trashinfo_field.value;
if (ti_status.header_ok && ti_status.path_ok && ti_status.date_ok
&& key_value)
return key_value;

if (trashinfo_field.value != NULL)
free(trashinfo_field.value);
if (key_value != NULL)
free(key_value);
display_dot_trashinfo_error(file);
return NULL;
}
else
{
open_err(file, __func__);
return NULL;
}
open_err(file, __func__);
return NULL;
}

///////////////////////////////////////////////////////////////////////
#ifdef TEST_LIB

#include "test.h"

int
main()
{
assert(strcmp(st_trashinfo_template[TI_HEADER].str, "[Trash Info]") == 0);
assert(strcmp(st_trashinfo_template[TI_PATH_LINE].str, "Path=") == 0);
assert(strcmp(st_trashinfo_template[TI_DATE_LINE].str, "DeletionDate=") ==
0);

return 0;
}
#endif
//const char *ti_key_to_string(ti_key key)
//{
//switch (key)
//{
//case TI_HEADER: return "TI_HEADER";
//case PATH_KEY: return "PATH_KEY";
//case DELETIONDATE_KEY: return "DELETIONDATE_KEY";
//case TI_LINE_MAX: return "TI_LINE_MAX";
//default: return "UNKNOWN_KEY";
//}
//}
33 changes: 6 additions & 27 deletions src/trashinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "time_rmw.h"

extern const char trashinfo_ext[];
extern const int len_trashinfo_ext;

extern const int TI_LINE_COUNT;

extern const int LEN_MAX_TRASHINFO_PATH_LINE;

/** Each waste directory is added to a linked list and has the data
* from this structure associated with it.
*/
Expand Down Expand Up @@ -103,30 +96,16 @@ typedef struct
bool is_duplicate;
} rmw_target;


extern const char *lit_info;
extern const char *path_key;
extern const char *deletion_date_key;

struct st__trashinfo
extern const struct trashinfo_template
{
const char *str;
const unsigned short int len;
};

const char *header;
const char *path_key;
const char *deletion_date_key;
} trashinfo_template;

struct trashinfo_field
{
char *value;
union
{
char *path_ptr;
char *date_str_ptr;
} f;
};

int
create_trashinfo(rmw_target * st_f_props, st_waste * waste_curr,
st_time * st_time_var);

char *parse_trashinfo_file(const char *file, const char *req_value);
char *validate_and_get_value(const char *file, ti_key key);
Loading

0 comments on commit 70afe64

Please sign in to comment.