Skip to content

Commit 15e26bb

Browse files
a3fsaschahauer
authored andcommitted
param: introduce file-list parameter type
DFU, fastboot and incoming mass storage support all use file lists as input, but individually check syntax correctness only on use. A dedicated file list parameter would improve the user experience and makes the code using it easier to handle: the struct file_list can be passed around directly instead of having to parse it first on use. Signed-off-by: Ahmad Fatoum <[email protected]> Link: https://lore.barebox.org/[email protected] Signed-off-by: Sascha Hauer <[email protected]>
1 parent fab1f40 commit 15e26bb

File tree

6 files changed

+184
-0
lines changed

6 files changed

+184
-0
lines changed

common/file-list.c

+47
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <malloc.h>
77
#include <fs.h>
88
#include <file-list.h>
9+
#include <stringlist.h>
910
#include <linux/err.h>
1011

1112
#define PARSE_DEVICE 0
@@ -109,6 +110,25 @@ static int file_list_parse_one(struct file_list *files, const char *partstr, con
109110
return file_list_add_entry(files, name, filename, flags);
110111
}
111112

113+
static const char *flags_to_str(int flags)
114+
{
115+
static char str[sizeof "srcu"];
116+
char *s = str;;
117+
118+
if (flags & FILE_LIST_FLAG_SAFE)
119+
*s++ = 's';
120+
if (flags & FILE_LIST_FLAG_READBACK)
121+
*s++ = 'r';
122+
if (flags & FILE_LIST_FLAG_CREATE)
123+
*s++ = 'c';
124+
if (flags & FILE_LIST_FLAG_UBI)
125+
*s++ = 'u';
126+
127+
*s = '\0';
128+
129+
return str;
130+
}
131+
112132
struct file_list *file_list_parse(const char *str)
113133
{
114134
struct file_list *files;
@@ -149,3 +169,30 @@ void file_list_free(struct file_list *files)
149169

150170
free(files);
151171
}
172+
173+
char *file_list_to_str(const struct file_list *files)
174+
{
175+
struct file_list_entry *entry;
176+
struct string_list sl;
177+
char *str;
178+
179+
if (!files)
180+
return strdup("");
181+
182+
string_list_init(&sl);
183+
184+
list_for_each_entry(entry, &files->list, list) {
185+
int ret = string_list_add_asprintf(&sl, "%s(%s)%s", entry->filename, entry->name,
186+
flags_to_str(entry->flags));
187+
if (ret) {
188+
str = ERR_PTR(ret);
189+
goto out;
190+
}
191+
}
192+
193+
str = string_list_join(&sl, ",");
194+
out:
195+
string_list_free(&sl);
196+
197+
return str;
198+
}

include/file-list.h

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#ifndef __FILE_LIST
33
#define __FILE_LIST
44

5+
#include <linux/list.h>
6+
57
#define FILE_LIST_FLAG_SAFE (1 << 0)
68
#define FILE_LIST_FLAG_READBACK (1 << 1)
79
#define FILE_LIST_FLAG_CREATE (1 << 2)
@@ -20,6 +22,7 @@ struct file_list {
2022
};
2123

2224
struct file_list *file_list_parse(const char *str);
25+
char *file_list_to_str(const struct file_list *files);
2326
void file_list_free(struct file_list *);
2427

2528
int file_list_add_entry(struct file_list *files, const char *name, const char *filename,

include/param.h

+15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define PARAM_GLOBALVAR_UNQUALIFIED (1 << 1)
1111

1212
struct device_d;
13+
struct file_list;
1314
typedef uint32_t IPaddr_t;
1415

1516
enum param_type {
@@ -23,6 +24,7 @@ enum param_type {
2324
PARAM_TYPE_BITMASK,
2425
PARAM_TYPE_IPV4,
2526
PARAM_TYPE_MAC,
27+
PARAM_TYPE_FILE_LIST,
2628
};
2729

2830
struct param_d {
@@ -89,6 +91,11 @@ struct param_d *dev_add_param_mac(struct device_d *dev, const char *name,
8991
int (*get)(struct param_d *p, void *priv),
9092
u8 *mac, void *priv);
9193

94+
struct param_d *dev_add_param_file_list(struct device_d *dev, const char *name,
95+
int (*set)(struct param_d *p, void *priv),
96+
int (*get)(struct param_d *p, void *priv),
97+
struct file_list **file_list, void *priv);
98+
9299
struct param_d *dev_add_param_fixed(struct device_d *dev, const char *name, const char *value);
93100

94101
void dev_remove_param(struct param_d *p);
@@ -185,6 +192,14 @@ static inline struct param_d *dev_add_param_mac(struct device_d *dev, const char
185192
return NULL;
186193
}
187194

195+
static inline struct param_d *dev_add_param_file_list(struct device_d *dev, const char *name,
196+
int (*set)(struct param_d *p, void *priv),
197+
int (*get)(struct param_d *p, void *priv),
198+
struct file_list **file_list, void *priv)
199+
{
200+
return NULL;
201+
}
202+
188203
static inline struct param_d *dev_add_param_fixed(struct device_d *dev, const char *name,
189204
const char *value)
190205
{

include/stringlist.h

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ int string_list_add_asprintf(struct string_list *sl, const char *fmt, ...);
1414
int string_list_add_sorted(struct string_list *sl, const char *str);
1515
int string_list_add_sort_uniq(struct string_list *sl, const char *str);
1616
int string_list_contains(struct string_list *sl, const char *str);
17+
char *string_list_join(const struct string_list *sl, const char *joinstr);
1718
void string_list_print_by_column(struct string_list *sl);
1819

1920
static inline void string_list_init(struct string_list *sl)

lib/parameter.c

+88
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include <string.h>
2828
#include <globalvar.h>
2929
#include <linux/err.h>
30+
#include <file-list.h>
31+
#include <stringlist.h>
3032

3133
static const char *param_type_string[] = {
3234
[PARAM_TYPE_STRING] = "string",
@@ -39,6 +41,7 @@ static const char *param_type_string[] = {
3941
[PARAM_TYPE_BITMASK] = "bitmask",
4042
[PARAM_TYPE_IPV4] = "ipv4",
4143
[PARAM_TYPE_MAC] = "MAC",
44+
[PARAM_TYPE_FILE_LIST] = "file-list",
4245
};
4346

4447
const char *get_param_type(struct param_d *param)
@@ -907,6 +910,91 @@ struct param_d *dev_add_param_mac(struct device_d *dev, const char *name,
907910
return &pm->param;
908911
}
909912

913+
struct param_file_list {
914+
struct param_d param;
915+
struct file_list **file_list;
916+
char *file_list_str;
917+
int (*set)(struct param_d *p, void *priv);
918+
int (*get)(struct param_d *p, void *priv);
919+
};
920+
921+
static inline struct param_file_list *to_param_file_list(struct param_d *p)
922+
{
923+
return container_of(p, struct param_file_list, param);
924+
}
925+
926+
static int param_file_list_set(struct device_d *dev, struct param_d *p, const char *val)
927+
{
928+
struct param_file_list *pfl = to_param_file_list(p);
929+
struct file_list *file_list_save = *pfl->file_list;
930+
int ret;
931+
932+
if (!val)
933+
val = "";
934+
935+
*pfl->file_list = file_list_parse(val);
936+
if (IS_ERR(*pfl->file_list)) {
937+
ret = PTR_ERR(*pfl->file_list);
938+
goto out;
939+
}
940+
941+
if (pfl->set) {
942+
ret = pfl->set(p, p->driver_priv);
943+
if (ret) {
944+
file_list_free(*pfl->file_list);
945+
goto out;
946+
}
947+
}
948+
949+
return 0;
950+
out:
951+
*pfl->file_list = file_list_save;
952+
953+
return ret;
954+
}
955+
956+
static const char *param_file_list_get(struct device_d *dev, struct param_d *p)
957+
{
958+
struct param_file_list *pfl = to_param_file_list(p);
959+
int ret;
960+
961+
if (pfl->get) {
962+
ret = pfl->get(p, p->driver_priv);
963+
if (ret)
964+
return NULL;
965+
}
966+
967+
free(p->value);
968+
p->value = file_list_to_str(*pfl->file_list);
969+
return p->value;
970+
}
971+
972+
struct param_d *dev_add_param_file_list(struct device_d *dev, const char *name,
973+
int (*set)(struct param_d *p, void *priv),
974+
int (*get)(struct param_d *p, void *priv),
975+
struct file_list **file_list, void *priv)
976+
{
977+
struct param_file_list *pfl;
978+
int ret;
979+
980+
pfl = xzalloc(sizeof(*pfl));
981+
pfl->file_list = file_list;
982+
pfl->set = set;
983+
pfl->get = get;
984+
pfl->param.driver_priv = priv;
985+
pfl->param.type = PARAM_TYPE_FILE_LIST;
986+
987+
ret = __dev_add_param(&pfl->param, dev, name,
988+
param_file_list_set, param_file_list_get, 0);
989+
if (ret) {
990+
free(pfl);
991+
return ERR_PTR(ret);
992+
}
993+
994+
return &pfl->param;
995+
}
996+
997+
910998
/**
911999
* dev_remove_param - remove a parameter from a device and free its
9121000
* memory

lib/stringlist.c

+30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <xfuncs.h>
33
#include <malloc.h>
44
#include <errno.h>
5+
#include <string.h>
56
#include <stringlist.h>
67

78
static int string_list_compare(struct list_head *a, struct list_head *b)
@@ -95,6 +96,35 @@ int string_list_contains(struct string_list *sl, const char *str)
9596
return 0;
9697
}
9798

99+
char *string_list_join(const struct string_list *sl, const char *joinstr)
100+
{
101+
struct string_list *entry;
102+
size_t len = 0;
103+
size_t joinstr_len = strlen(joinstr);
104+
char *str, *next;
105+
106+
string_list_for_each_entry(entry, sl)
107+
len += strlen(entry->str) + joinstr_len;
108+
109+
if (len == 0)
110+
return strdup("");
111+
112+
str = malloc(len + 1);
113+
if (!str)
114+
return NULL;
115+
116+
next = str;
117+
118+
string_list_for_each_entry(entry, sl) {
119+
next = stpcpy(next, entry->str);
120+
next = stpcpy(next, joinstr);
121+
}
122+
123+
next[-joinstr_len] = '\0';
124+
125+
return str;
126+
}
127+
98128
void string_list_print_by_column(struct string_list *sl)
99129
{
100130
int len = 0, num, i;

0 commit comments

Comments
 (0)