xref: /third_party/eudev/src/shared/strxcpyx.c (revision 99ca880a)
1/***
2  This file is part of eudev from systemd
3
4  Copyright 2013 Kay Sievers
5
6  systemd is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Lesser General Public License as published by
8  the Free Software Foundation; either version 2.1 of the License, or
9  (at your option) any later version.
10
11  systemd is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15
16  You should have received a copy of the GNU Lesser General Public License
17  along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
20/*
21 * Concatenates/copies strings. In any case, terminates in all cases
22 * with '\0' * and moves the @dest pointer forward to the added '\0'.
23 * Returns the * remaining size, and 0 if the string was truncated.
24 */
25
26#include <stdio.h>
27#include <string.h>
28#include "strxcpyx.h"
29
30size_t strpcpy(char **dest, size_t size, const char *src) {
31        size_t len;
32
33        len = strlen(src);
34        if (len >= size) {
35                if (size > 1)
36                        *dest = mempcpy(*dest, src, size-1);
37                size = 0;
38        } else {
39                if (len > 0) {
40                        *dest = mempcpy(*dest, src, len);
41                        size -= len;
42                }
43        }
44        *dest[0] = '\0';
45        return size;
46}
47
48size_t strpcpyf(char **dest, size_t size, const char *src, ...) {
49        va_list va;
50        int i;
51
52        va_start(va, src);
53        i = vsnprintf(*dest, size, src, va);
54        if (i < (int)size) {
55                *dest += i;
56                size -= i;
57        } else {
58                *dest += size;
59                size = 0;
60        }
61        va_end(va);
62        *dest[0] = '\0';
63        return size;
64}
65
66size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
67        va_list va;
68
69        va_start(va, src);
70        do {
71                size = strpcpy(dest, size, src);
72                src = va_arg(va, char *);
73        } while (src != NULL);
74        va_end(va);
75        return size;
76}
77
78size_t strscpy(char *dest, size_t size, const char *src) {
79        char *s;
80
81        s = dest;
82        return strpcpy(&s, size, src);
83}
84
85size_t strscpyl(char *dest, size_t size, const char *src, ...) {
86        va_list va;
87        char *s;
88
89        va_start(va, src);
90        s = dest;
91        do {
92                size = strpcpy(&s, size, src);
93                src = va_arg(va, char *);
94        } while (src != NULL);
95        va_end(va);
96
97        return size;
98}
99