1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2018 Jan Stancek <jstancek@redhat.com>
4 */
5
6 #include <limits.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <string.h>
10
11 #define TST_NO_DEFAULT_MAIN
12 #include "tst_test.h"
13 #include "tst_sys_conf.h"
14
15 static struct tst_sys_conf *save_restore_data;
16
tst_sys_conf_dump(void)17 void tst_sys_conf_dump(void)
18 {
19 struct tst_sys_conf *i;
20
21 for (i = save_restore_data; i; i = i->next)
22 tst_res(TINFO, "%s = %s", i->path, i->value);
23 }
24
tst_sys_conf_save_str(const char * path,const char * value)25 int tst_sys_conf_save_str(const char *path, const char *value)
26 {
27 struct tst_sys_conf *n = SAFE_MALLOC(sizeof(*n));
28
29 strncpy(n->path, path, sizeof(n->path)-1);
30 strncpy(n->value, value, sizeof(n->value)-1);
31
32 n->path[sizeof(n->path) - 1] = 0;
33 n->value[sizeof(n->value) - 1] = 0;
34
35 n->next = save_restore_data;
36 save_restore_data = n;
37
38 return 0;
39 }
40
tst_sys_conf_save(const char * path)41 int tst_sys_conf_save(const char *path)
42 {
43 char line[PATH_MAX];
44 FILE *fp;
45 void *ret;
46 char flag;
47
48 if (!path)
49 tst_brk(TBROK, "path is empty");
50
51 flag = path[0];
52 if (flag == '?' || flag == '!')
53 path++;
54
55 if (access(path, F_OK) != 0) {
56 switch (flag) {
57 case '?':
58 tst_res(TINFO, "Path not found: '%s'", path);
59 break;
60 case '!':
61 tst_brk(TBROK|TERRNO, "Path not found: '%s'", path);
62 break;
63 default:
64 tst_brk(TCONF|TERRNO, "Path not found: '%s'", path);
65 }
66 return 1;
67 }
68
69 fp = fopen(path, "r");
70 if (fp == NULL) {
71 if (flag == '?')
72 return 1;
73
74 tst_brk(TBROK | TERRNO, "Failed to open FILE '%s' for reading",
75 path);
76 return 1;
77 }
78
79 ret = fgets(line, sizeof(line), fp);
80 fclose(fp);
81
82 if (ret == NULL) {
83 if (flag == '?')
84 return 1;
85
86 tst_brk(TBROK | TERRNO, "Failed to read anything from '%s'",
87 path);
88 }
89
90 return tst_sys_conf_save_str(path, line);
91 }
92
tst_sys_conf_restore(int verbose)93 void tst_sys_conf_restore(int verbose)
94 {
95 struct tst_sys_conf *i;
96
97 for (i = save_restore_data; i; i = i->next) {
98 if (verbose) {
99 tst_res(TINFO, "Restoring conf.: %s -> %s\n",
100 i->path, i->value);
101 }
102 FILE_PRINTF(i->path, "%s", i->value);
103 }
104 }
105
106