TAILQ_HEAD(bhead, usbg_binding) bindings;
usbg_gadget *parent;
- char name[USBG_MAX_NAME_LENGTH];
- char path[USBG_MAX_PATH_LENGTH];
+ char *name;
+ char *path;
};
struct usbg_function
case USBG_ERROR_NOT_SUPPORTED:
ret = "USBG_ERROR_NOT_SUPPORTED";
break;
+ case USBG_ERROR_PATH_TOO_LONG:
+ ret = "USBG_ERROR_PATH_TOO_LONG";
+ break;
case USBG_ERROR_OTHER_ERROR:
ret = "USBG_ERROR_OTHER_ERROR";
break;
case USBG_ERROR_NOT_SUPPORTED:
ret = "Function not supported";
break;
+ case USBG_ERROR_PATH_TOO_LONG:
+ ret = "Created path was too long to process it.";
+ break;
case USBG_ERROR_OTHER_ERROR:
ret = "Other error";
break;
TAILQ_REMOVE(&c->bindings, b, bnode);
usbg_free_binding(b);
}
+ free(c->path);
+ free(c->name);
free(c);
}
return g;
}
+static usbg_config *usbg_allocate_config(char *path, char *name,
+ usbg_gadget *parent)
+{
+ usbg_config *c;
+
+ c = malloc(sizeof(usbg_config));
+ if (c) {
+ TAILQ_INIT(&c->bindings);
+ c->name = strdup(name);
+ c->path = strdup(path);
+ c->parent = parent;
+
+ if (!(c->name) || !(c->path)) {
+ free(c->name);
+ free(c->path);
+ free(c);
+ c = NULL;
+ }
+ }
+
+ return c;
+}
+
static int usbg_parse_function_net_attrs(usbg_function *f,
usbg_function_attrs *f_attrs)
{
struct dirent **dent;
char cpath[USBG_MAX_PATH_LENGTH];
- sprintf(cpath, "%s/%s/%s", path, g->name, CONFIGS_DIR);
+ n = snprintf(cpath, sizeof(cpath), "%s/%s/%s", path, g->name,
+ CONFIGS_DIR);
+ if (n >= sizeof(cpath)) {
+ ret = USBG_ERROR_PATH_TOO_LONG;
+ goto out;
+ }
n = scandir(cpath, &dent, file_select, alphasort);
if (n >= 0) {
for (i = 0; i < n; i++) {
if (ret == USBG_SUCCESS) {
- c = malloc(sizeof(usbg_config));
+ c = usbg_allocate_config(cpath, dent[i]->d_name, g);
if (c) {
- c->parent = g;
- strcpy(c->name, dent[i]->d_name);
- strcpy(c->path, cpath);
- TAILQ_INIT(&c->bindings);
ret = usbg_parse_config_bindings(c);
if (ret == USBG_SUCCESS)
TAILQ_INSERT_TAIL(&g->configs, c, cnode);
ret = usbg_translate_error(errno);
}
+out:
return ret;
}
char cpath[USBG_MAX_PATH_LENGTH];
usbg_config *conf;
int ret = USBG_ERROR_INVALID_PARAM;
+ int n, free_space;
if (!g || !c)
- return ret;
+ goto out;
/**
* @todo Check for legal configuration name
conf = usbg_get_config(g, name);
if (conf) {
ERROR("duplicate configuration name\n");
- return USBG_ERROR_EXIST;
+ ret = USBG_ERROR_EXIST;
+ goto out;
}
- sprintf(cpath, "%s/%s/%s/%s", g->path, g->name, CONFIGS_DIR, name);
+ n = snprintf(cpath, sizeof(cpath), "%s/%s/%s", g->path, g->name,
+ CONFIGS_DIR);
+ if (n >= sizeof(cpath)) {
+ ret = USBG_ERROR_PATH_TOO_LONG;
+ goto out;
+ }
- *c = malloc(sizeof(usbg_config));
+ *c = usbg_allocate_config(cpath, name, g);
conf = *c;
- if (conf) {
- TAILQ_INIT(&conf->bindings);
- strcpy(conf->name, name);
- sprintf(conf->path, "%s/%s/%s", g->path, g->name, CONFIGS_DIR);
+ if (!conf) {
+ ERRORNO("allocating configuration\n");
+ ret = USBG_ERROR_NO_MEM;
+ goto out;
+ }
- ret = mkdir(cpath, S_IRWXU|S_IRWXG|S_IRWXO);
+ free_space = sizeof(cpath) - n;
+ /* Append string at the end of previous one */
+ n = snprintf(&(cpath[n]), free_space, "/%s", name);
+ if (n < free_space) {
+ ret = mkdir(cpath, S_IRWXU | S_IRWXG | S_IRWXO);
if (!ret) {
ret = USBG_SUCCESS;
if (c_attrs)
if (ret == USBG_SUCCESS && c_strs)
ret = usbg_set_config_string(conf, LANG_US_ENG,
c_strs->configuration);
-
} else {
ret = usbg_translate_error(errno);
}
-
- if (ret == USBG_SUCCESS)
- INSERT_TAILQ_STRING_ORDER(&g->configs, chead, name, conf, cnode);
- else
- usbg_free_config(conf);
} else {
- ERRORNO("allocating configuration\n");
- ret = USBG_ERROR_NO_MEM;
+ ret = USBG_ERROR_PATH_TOO_LONG;
}
+ if (ret == USBG_SUCCESS)
+ INSERT_TAILQ_STRING_ORDER(&g->configs, chead, name,
+ conf, cnode);
+ else
+ usbg_free_config(conf);
+
+out:
return ret;
}