Commit d5a89d7d authored by Kay Sievers's avatar Kay Sievers
Browse files

udev: move string copy functions to shared/

parent 0908dd2f
......@@ -769,6 +769,8 @@ libsystemd_shared_la_SOURCES = \
src/shared/strv.h \
src/shared/strbuf.c \
src/shared/strbuf.h \
src/shared/strxcpyx.c \
src/shared/strxcpyx.h \
src/shared/conf-parser.c \
src/shared/conf-parser.h \
src/shared/log.c \
......
......@@ -381,7 +381,6 @@ Features:
* udev: move to LGPL
* udev systemd unify:
- strpcpy(), strpcpyl(), strscpy(), strscpyl()
- utf8 validator code
* udev: scsi_id -> sg3_utils -> kill scsi_id
......
......@@ -38,7 +38,7 @@ static void udev_device_tag(struct udev_device *dev, const char *tag, bool add)
id = udev_device_get_id_filename(dev);
if (id == NULL)
return;
util_strscpyl(filename, sizeof(filename), "/run/udev/tags/", tag, "/", id, NULL);
strscpyl(filename, sizeof(filename), "/run/udev/tags/", tag, "/", id, NULL);
if (add) {
int fd;
......@@ -116,7 +116,7 @@ int udev_device_update_db(struct udev_device *udev_device)
return -1;
has_info = device_has_info(udev_device);
util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
/* do not store anything for otherwise empty devices */
if (!has_info &&
......@@ -127,7 +127,7 @@ int udev_device_update_db(struct udev_device *udev_device)
}
/* write a database file */
util_strscpyl(filename_tmp, sizeof(filename_tmp), filename, ".tmp", NULL);
strscpyl(filename_tmp, sizeof(filename_tmp), filename, ".tmp", NULL);
mkdir_parents(filename_tmp, 0755);
f = fopen(filename_tmp, "we");
if (f == NULL) {
......@@ -186,7 +186,7 @@ int udev_device_delete_db(struct udev_device *udev_device)
id = udev_device_get_id_filename(udev_device);
if (id == NULL)
return -1;
util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
unlink(filename);
return 0;
}
......@@ -379,7 +379,7 @@ static struct udev_list_entry *udev_device_add_property_from_string(struct udev_
char name[UTIL_LINE_SIZE];
char *val;
util_strscpy(name, sizeof(name), property);
strscpy(name, sizeof(name), property);
val = strchr(name, '=');
if (val == NULL)
return NULL;
......@@ -404,7 +404,7 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
if (startswith(property, "DEVPATH=")) {
char path[UTIL_PATH_SIZE];
util_strscpyl(path, sizeof(path), "/sys", &property[8], NULL);
strscpyl(path, sizeof(path), "/sys", &property[8], NULL);
udev_device_set_syspath(udev_device, path);
} else if (startswith(property, "SUBSYSTEM=")) {
udev_device_set_subsystem(udev_device, &property[10]);
......@@ -417,7 +417,7 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
char *slink;
char *next;
util_strscpy(devlinks, sizeof(devlinks), &property[9]);
strscpy(devlinks, sizeof(devlinks), &property[9]);
slink = devlinks;
next = strchr(slink, ' ');
while (next != NULL) {
......@@ -432,7 +432,7 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
char tags[UTIL_PATH_SIZE];
char *next;
util_strscpy(tags, sizeof(tags), &property[5]);
strscpy(tags, sizeof(tags), &property[5]);
next = strchr(tags, ':');
if (next != NULL) {
next++;
......@@ -527,7 +527,7 @@ int udev_device_read_db(struct udev_device *udev_device, const char *dbfile)
id = udev_device_get_id_filename(udev_device);
if (id == NULL)
return -1;
util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
dbfile = filename;
}
......@@ -550,7 +550,7 @@ int udev_device_read_db(struct udev_device *udev_device, const char *dbfile)
val = &line[2];
switch(line[0]) {
case 'S':
util_strscpyl(filename, sizeof(filename), "/dev/", val, NULL);
strscpyl(filename, sizeof(filename), "/dev/", val, NULL);
udev_device_add_devlink(udev_device, filename);
break;
case 'L':
......@@ -588,7 +588,7 @@ int udev_device_read_uevent_file(struct udev_device *udev_device)
if (udev_device->uevent_loaded)
return 0;
util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL);
strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL);
f = fopen(filename, "re");
if (f == NULL)
return -1;
......@@ -702,14 +702,14 @@ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, con
return NULL;
/* resolve possible symlink to real path */
util_strscpy(path, sizeof(path), syspath);
strscpy(path, sizeof(path), syspath);
util_resolve_sys_link(udev, path, sizeof(path));
if (startswith(path + strlen("/sys"), "/devices/")) {
char file[UTIL_PATH_SIZE];
/* all "devices" require a "uevent" file */
util_strscpyl(file, sizeof(file), path, "/uevent", NULL);
strscpyl(file, sizeof(file), path, "/uevent", NULL);
if (stat(file, &statbuf) != 0)
return NULL;
} else {
......@@ -823,7 +823,7 @@ _public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, c
return NULL;
}
case '+':
util_strscpy(subsys, sizeof(subsys), &id[1]);
strscpy(subsys, sizeof(subsys), &id[1]);
sysname = strchr(subsys, ':');
if (sysname == NULL)
return NULL;
......@@ -856,22 +856,22 @@ _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev
struct stat statbuf;
if (streq(subsystem, "subsystem")) {
util_strscpyl(path, sizeof(path), "/sys/subsystem/", sysname, NULL);
strscpyl(path, sizeof(path), "/sys/subsystem/", sysname, NULL);
if (stat(path, &statbuf) == 0)
goto found;
util_strscpyl(path, sizeof(path), "/sys/bus/", sysname, NULL);
strscpyl(path, sizeof(path), "/sys/bus/", sysname, NULL);
if (stat(path, &statbuf) == 0)
goto found;
util_strscpyl(path, sizeof(path), "/sys/class/", sysname, NULL);
strscpyl(path, sizeof(path), "/sys/class/", sysname, NULL);
if (stat(path, &statbuf) == 0)
goto found;
goto out;
}
if (streq(subsystem, "module")) {
util_strscpyl(path, sizeof(path), "/sys/module/", sysname, NULL);
strscpyl(path, sizeof(path), "/sys/module/", sysname, NULL);
if (stat(path, &statbuf) == 0)
goto found;
goto out;
......@@ -881,32 +881,32 @@ _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev
char subsys[UTIL_NAME_SIZE];
char *driver;
util_strscpy(subsys, sizeof(subsys), sysname);
strscpy(subsys, sizeof(subsys), sysname);
driver = strchr(subsys, ':');
if (driver != NULL) {
driver[0] = '\0';
driver = &driver[1];
util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsys, "/drivers/", driver, NULL);
strscpyl(path, sizeof(path), "/sys/subsystem/", subsys, "/drivers/", driver, NULL);
if (stat(path, &statbuf) == 0)
goto found;
util_strscpyl(path, sizeof(path), "/sys/bus/", subsys, "/drivers/", driver, NULL);
strscpyl(path, sizeof(path), "/sys/bus/", subsys, "/drivers/", driver, NULL);
if (stat(path, &statbuf) == 0)
goto found;
}
goto out;
}
util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsystem, "/devices/", sysname, NULL);
strscpyl(path, sizeof(path), "/sys/subsystem/", subsystem, "/devices/", sysname, NULL);
if (stat(path, &statbuf) == 0)
goto found;
util_strscpyl(path, sizeof(path), "/sys/bus/", subsystem, "/devices/", sysname, NULL);
strscpyl(path, sizeof(path), "/sys/bus/", subsystem, "/devices/", sysname, NULL);
if (stat(path, &statbuf) == 0)
goto found;
util_strscpyl(path, sizeof(path), "/sys/class/", subsystem, "/", sysname, NULL);
strscpyl(path, sizeof(path), "/sys/class/", subsystem, "/", sysname, NULL);
if (stat(path, &statbuf) == 0)
goto found;
out:
......@@ -957,7 +957,7 @@ static struct udev_device *device_new_from_parent(struct udev_device *udev_devic
char path[UTIL_PATH_SIZE];
const char *subdir;
util_strscpy(path, sizeof(path), udev_device->syspath);
strscpy(path, sizeof(path), udev_device->syspath);
subdir = path + strlen("/sys/");
for (;;) {
char *pos;
......@@ -1260,9 +1260,9 @@ _public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct ud
size_t l;
s = symlinks;
l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
l = strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
udev_device_add_property(udev_device, "DEVLINKS", symlinks);
}
}
......@@ -1275,9 +1275,9 @@ _public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct ud
size_t l;
s = tags;
l = util_strpcpyl(&s, sizeof(tags), ":", NULL);
l = strpcpyl(&s, sizeof(tags), ":", NULL);
udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
l = strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
udev_device_add_property(udev_device, "TAGS", tags);
}
}
......@@ -1374,7 +1374,7 @@ _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_devi
if (list_entry != NULL)
return udev_list_entry_get_value(list_entry);
util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
if (lstat(path, &statbuf) != 0) {
udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL);
goto out;
......@@ -1400,7 +1400,7 @@ _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_devi
/* resolve custom link to a device and return its syspath */
if (!streq(sysattr, "device")) {
util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
dev = udev_device_new_from_syspath(udev_device->udev, path);
if (dev != NULL) {
list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
......@@ -1463,7 +1463,7 @@ static int udev_device_sysattr_list_read(struct udev_device *udev_device)
if (dent->d_type != DT_LNK && dent->d_type != DT_REG)
continue;
util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL);
strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL);
if (lstat(path, &statbuf) != 0)
continue;
if ((statbuf.st_mode & S_IRUSR) == 0)
......@@ -1722,10 +1722,10 @@ static int update_envp_monitor_buf(struct udev_device *udev_device)
return -EINVAL;
/* add property string to monitor buffer */
l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL);
l = strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL);
if (l == 0)
return -EINVAL;
/* advance past the trailing '\0' that util_strpcpyl() guarantees */
/* advance past the trailing '\0' that strpcpyl() guarantees */
s++;
l--;
}
......
......@@ -659,11 +659,11 @@ static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate,
struct dirent *dent;
s = path;
l = util_strpcpyl(&s, sizeof(path), "/sys/", basedir, NULL);
l = strpcpyl(&s, sizeof(path), "/sys/", basedir, NULL);
if (subdir1 != NULL)
l = util_strpcpyl(&s, l, "/", subdir1, NULL);
l = strpcpyl(&s, l, "/", subdir1, NULL);
if (subdir2 != NULL)
util_strpcpyl(&s, l, "/", subdir2, NULL);
strpcpyl(&s, l, "/", subdir2, NULL);
dir = opendir(path);
if (dir == NULL)
return -ENOENT;
......@@ -677,7 +677,7 @@ static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate,
if (!match_sysname(udev_enumerate, dent->d_name))
continue;
util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL);
strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL);
dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
if (dev == NULL)
continue;
......@@ -738,7 +738,7 @@ static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir,
DIR *dir;
struct dirent *dent;
util_strscpyl(path, sizeof(path), "/sys/", basedir, NULL);
strscpyl(path, sizeof(path), "/sys/", basedir, NULL);
dir = opendir(path);
if (dir == NULL)
return -1;
......@@ -789,7 +789,7 @@ static int scan_devices_tags(struct udev_enumerate *udev_enumerate)
struct dirent *dent;
char path[UTIL_PATH_SIZE];
util_strscpyl(path, sizeof(path), "/run/udev/tags/", udev_list_entry_get_name(list_entry), NULL);
strscpyl(path, sizeof(path), "/run/udev/tags/", udev_list_entry_get_name(list_entry), NULL);
dir = opendir(path);
if (dir == NULL)
continue;
......
......@@ -29,6 +29,7 @@
#include "macro.h"
#include "util.h"
#include "mkdir.h"
#include "strxcpyx.h"
#define READ_END 0
#define WRITE_END 1
......@@ -164,11 +165,6 @@ int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size);
int util_log_priority(const char *priority);
size_t util_path_encode(const char *src, char *dest, size_t size);
void util_remove_trailing_chars(char *path, char c);
size_t util_strpcpy(char **dest, size_t size, const char *src);
size_t util_strpcpyf(char **dest, size_t size, const char *src, ...) __attribute__((format(printf, 3, 4)));
size_t util_strpcpyl(char **dest, size_t size, const char *src, ...) __attribute__((sentinel));
size_t util_strscpy(char *dest, size_t size, const char *src);
size_t util_strscpyl(char *dest, size_t size, const char *src, ...) __attribute__((sentinel));
int util_replace_whitespace(const char *str, char *to, size_t len);
int util_replace_chars(char *str, const char *white);
unsigned int util_string_hash32(const char *key);
......
......@@ -458,7 +458,7 @@ _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_qu
snprintf(seqnum_str, sizeof(seqnum_str), "%llu", seqnum);
s = syspath;
l = util_strpcpy(&s, sizeof(syspath), "/sys");
l = strpcpy(&s, sizeof(syspath), "/sys");
len = udev_queue_read_devpath(queue_file, s, l);
if (len < 0)
break;
......
......@@ -51,7 +51,7 @@ int util_delete_path(struct udev *udev, const char *path)
if (path[0] == '/')
while(path[1] == '/')
path++;
util_strscpy(p, sizeof(p), path);
strscpy(p, sizeof(p), path);
pos = strrchr(p, '/');
if (pos == p || pos == NULL)
return 0;
......@@ -151,7 +151,7 @@ int util_resolve_subsys_kernel(struct udev *udev, const char *string,
if (string[0] != '[')
return -1;
util_strscpy(temp, sizeof(temp), string);
strscpy(temp, sizeof(temp), string);
subsys = &temp[1];
......@@ -183,7 +183,7 @@ int util_resolve_subsys_kernel(struct udev *udev, const char *string,
val = udev_device_get_sysattr_value(dev, attr);
if (val != NULL)
util_strscpy(result, maxsize, val);
strscpy(result, maxsize, val);
else
result[0] = '\0';
udev_dbg(udev, "value '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result);
......@@ -192,9 +192,9 @@ int util_resolve_subsys_kernel(struct udev *udev, const char *string,
char *s;
s = result;
l = util_strpcpyl(&s, maxsize, udev_device_get_syspath(dev), NULL);
l = strpcpyl(&s, maxsize, udev_device_get_syspath(dev), NULL);
if (attr != NULL)
util_strpcpyl(&s, l, "/", attr, NULL);
strpcpyl(&s, l, "/", attr, NULL);
udev_dbg(udev, "path '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result);
}
udev_device_unref(dev);
......@@ -207,7 +207,7 @@ ssize_t util_get_sys_core_link_value(struct udev *udev, const char *slink, const
ssize_t len;
const char *pos;
util_strscpyl(path, sizeof(path), syspath, "/", slink, NULL);
strscpyl(path, sizeof(path), syspath, "/", slink, NULL);
len = readlink(path, target, sizeof(target));
if (len <= 0 || len == (ssize_t)sizeof(target))
return -1;
......@@ -216,7 +216,7 @@ ssize_t util_get_sys_core_link_value(struct udev *udev, const char *slink, const
if (pos == NULL)
return -1;
pos = &pos[1];
return util_strscpy(value, size, pos);
return strscpy(value, size, pos);
}
int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size)
......@@ -243,7 +243,7 @@ int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size)
}
if (base == NULL)
return -EINVAL;
util_strscpyl(base, size - (base - syspath), "/", &link_target[back * 3], NULL);
strscpyl(base, size - (base - syspath), "/", &link_target[back * 3], NULL);
return 0;
}
......@@ -307,89 +307,6 @@ void util_remove_trailing_chars(char *path, char c)
path[--len] = '\0';
}
/*
* Concatenates strings. In any case, terminates in _all_ cases with '\0'
* and moves the @dest pointer forward to the added '\0'. Returns the
* remaining size, and 0 if the string was truncated.
*/
size_t util_strpcpy(char **dest, size_t size, const char *src)
{
size_t len;
len = strlen(src);
if (len >= size) {
if (size > 1)
*dest = mempcpy(*dest, src, size-1);
size = 0;
} else {
if (len > 0) {
*dest = mempcpy(*dest, src, len);
size -= len;
}
}
*dest[0] = '\0';
return size;
}
size_t util_strpcpyf(char **dest, size_t size, const char *src, ...)
{
va_list va;
int i;
va_start(va, src);
i = vsnprintf(*dest, size, src, va);
if (i < (int)size) {
*dest += i;
size -= i;
} else {
*dest += size;
size = 0;
}
va_end(va);
*dest[0] = '\0';
return size;
}
/* concatenates list of strings, moves dest forward */
size_t util_strpcpyl(char **dest, size_t size, const char *src, ...)
{
va_list va;
va_start(va, src);
do {
size = util_strpcpy(dest, size, src);
src = va_arg(va, char *);
} while (src != NULL);
va_end(va);
return size;
}
/* copies string */
size_t util_strscpy(char *dest, size_t size, const char *src)
{
char *s;
s = dest;
return util_strpcpy(&s, size, src);
}
/* concatenates list of strings */
size_t util_strscpyl(char *dest, size_t size, const char *src, ...)
{
va_list va;
char *s;
va_start(va, src);
s = dest;
do {
size = util_strpcpy(&s, size, src);
src = va_arg(va, char *);
} while (src != NULL);
va_end(va);
return size;
}
/* count of characters used to encode one unicode char */
static int utf8_encoded_expected_len(const char *str)
{
......
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2013 Kay Sievers
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
/*
* Concatenates/copies strings. In any case, terminates in all cases
* with '\0' * and moves the @dest pointer forward to the added '\0'.
* Returns the * remaining size, and 0 if the string was truncated.
*/
#include <stdio.h>
#include <string.h>
#include "strxcpyx.h"
size_t strpcpy(char **dest, size_t size, const char *src)
{
size_t len;
len = strlen(src);
if (len >= size) {
if (size > 1)
*dest = mempcpy(*dest, src, size-1);
size = 0;
} else {
if (len > 0) {
*dest = mempcpy(*dest, src, len);
size -= len;
}
}
*dest[0] = '\0';
return size;
}
size_t strpcpyf(char **dest, size_t size, const char *src, ...)
{
va_list va;
int i;
va_start(va, src);
i = vsnprintf(*dest, size, src, va);
if (i < (int)size) {
*dest += i;
size -= i;
} else {
*dest += size;
size = 0;
}
va_end(va);
*dest[0] = '\0';
return size;
}
size_t strpcpyl(char **dest, size_t size, const char *src, ...)
{
va_list va;
va_start(va, src);
do {
size = strpcpy(dest, size, src);
src = va_arg(va, char *);
} while (src != NULL);
va_end(va);
return size;
}
size_t strscpy(char *dest, size_t size, const char *src)
{
char *s;
s = dest;
return strpcpy(&s, size, src);
}
size_t strscpyl(char *dest, size_t size, const char *src, ...) {
va_list va;
char *s;
va_start(va, src);
s = dest;
do {
size = strpcpy(&s, size, src);