/** * mnt_optstr_deduplicate_option: * @optstr: string with a comma separated list of options * @name: requested option name * * Removes all instances of @name except the last one. * * Returns: 0 on success, 1 when not found the @name or negative number in case * of error. */ int mnt_optstr_deduplicate_option(char **optstr, const char *name) { int rc; char *begin = NULL, *end = NULL, *opt; assert(optstr); assert(name); opt = *optstr; do { struct libmnt_optloc ol; mnt_init_optloc(&ol); rc = mnt_optstr_locate_option(opt, name, &ol); if (!rc) { if (begin) { /* remove the previous instance */ size_t shift = strlen(*optstr); mnt_optstr_remove_option_at(optstr, begin, end); /* now all the offsets are not valid anymore - recount */ shift -= strlen(*optstr); ol.begin -= shift; ol.end -= shift; } begin = ol.begin; end = ol.end; opt = end && *end ? end + 1 : NULL; } } while (rc == 0 && opt && *opt); return rc < 0 ? rc : begin ? 0 : 1; }
/** * mnt_optstr_remove_option: * @optstr: string with comma separated list of options * @name: requested option name * * Returns: 0 on success, 1 when not found the @name or negative number in case * of error. */ int mnt_optstr_remove_option(char **optstr, const char *name) { struct libmnt_optloc ol; int rc; mnt_init_optloc(&ol); rc = mnt_optstr_locate_option(*optstr, name, &ol); if (rc != 0) return rc; mnt_optstr_remove_option_at(optstr, ol.begin, ol.end); return 0; }
/** * mnt_optstr_get_option: * @optstr: string with comma separated list of options * @name: requested option name * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL * @valsz: returns size of the value or 0 * * Returns: 0 on success, 1 when not found the @name or negative number in case * of error. */ int mnt_optstr_get_option(const char *optstr, const char *name, char **value, size_t *valsz) { struct libmnt_optloc ol; int rc; mnt_init_optloc(&ol); rc = mnt_optstr_locate_option((char *) optstr, name, &ol); if (!rc) { if (value) *value = ol.value; if (valsz) *valsz = ol.valsz; } return rc; }
/** * mnt_optstr_set_option: * @optstr: string with a comma separated list of options * @name: requested option * @value: new value or NULL * * Set or unset the option @value. * * Returns: 0 on success, 1 when not found the @name or negative number in case * of error. */ int mnt_optstr_set_option(char **optstr, const char *name, const char *value) { struct libmnt_optloc ol; char *nameend; int rc = 1; assert(optstr); assert(name); if (!optstr) return -EINVAL; mnt_init_optloc(&ol); if (*optstr) rc = mnt_optstr_locate_option(*optstr, name, &ol); if (rc < 0) return rc; /* parse error */ if (rc == 1) return mnt_optstr_append_option(optstr, name, value); /* not found */ nameend = ol.begin + ol.namesz; if (value == NULL && ol.value && ol.valsz) /* remove unwanted "=value" */ mnt_optstr_remove_option_at(optstr, nameend, ol.end); else if (value && ol.value == NULL) /* insert "=value" */ rc = insert_value(optstr, nameend, value, NULL); else if (value && ol.value && strlen(value) == ol.valsz) /* simply replace =value */ memcpy(ol.value, value, ol.valsz); else if (value && ol.value) { mnt_optstr_remove_option_at(optstr, nameend, ol.end); rc = insert_value(optstr, nameend, value, NULL); } return rc; }