chiark / gitweb /
json: fix a mem leak
[elogind.git] / src / shared / import-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2015 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "util.h"
23 #include "import-util.h"
24
25 int import_url_last_component(const char *url, char **ret) {
26         const char *e, *p;
27         char *s;
28
29         e = strchrnul(url, '?');
30
31         while (e > url && e[-1] == '/')
32                 e--;
33
34         p = e;
35         while (p > url && p[-1] != '/')
36                 p--;
37
38         if (e <= p)
39                 return -EINVAL;
40
41         s = strndup(p, e - p);
42         if (!s)
43                 return -ENOMEM;
44
45         *ret = s;
46         return 0;
47 }
48
49
50 int import_url_change_last_component(const char *url, const char *suffix, char **ret) {
51         const char *e;
52         char *s;
53
54         assert(url);
55         assert(ret);
56
57         e = strchrnul(url, '?');
58
59         while (e > url && e[-1] == '/')
60                 e--;
61
62         while (e > url && e[-1] != '/')
63                 e--;
64
65         if (e <= url)
66                 return -EINVAL;
67
68         s = new(char, (e - url) + strlen(suffix) + 1);
69         if (!s)
70                 return -ENOMEM;
71
72         strcpy(mempcpy(s, url, e - url), suffix);
73         *ret = s;
74         return 0;
75 }
76
77 static const char* const import_verify_table[_IMPORT_VERIFY_MAX] = {
78         [IMPORT_VERIFY_NO] = "no",
79         [IMPORT_VERIFY_CHECKSUM] = "checksum",
80         [IMPORT_VERIFY_SIGNATURE] = "signature",
81 };
82
83 DEFINE_STRING_TABLE_LOOKUP(import_verify, ImportVerify);
84
85 int tar_strip_suffixes(const char *name, char **ret) {
86         const char *e;
87         char *s;
88
89         e = endswith(name, ".tar");
90         if (!e)
91                 e = endswith(name, ".tar.xz");
92         if (!e)
93                 e = endswith(name, ".tar.gz");
94         if (!e)
95                 e = endswith(name, ".tar.bz2");
96         if (!e)
97                 e = endswith(name, ".tgz");
98         if (!e)
99                 e = strchr(name, 0);
100
101         if (e <= name)
102                 return -EINVAL;
103
104         s = strndup(name, e - name);
105         if (!s)
106                 return -ENOMEM;
107
108         *ret = s;
109         return 0;
110 }
111
112 int raw_strip_suffixes(const char *p, char **ret) {
113
114         static const char suffixes[] =
115                 ".xz\0"
116                 ".gz\0"
117                 ".bz2\0"
118                 ".raw\0"
119                 ".qcow2\0"
120                 ".img\0"
121                 ".bin\0";
122
123         _cleanup_free_ char *q = NULL;
124
125         q = strdup(p);
126         if (!q)
127                 return -ENOMEM;
128
129         for (;;) {
130                 const char *sfx;
131                 bool changed = false;
132
133                 NULSTR_FOREACH(sfx, suffixes) {
134                         char *e;
135
136                         e = endswith(q, sfx);
137                         if (e) {
138                                 *e = 0;
139                                 changed = true;
140                         }
141                 }
142
143                 if (!changed)
144                         break;
145         }
146
147         *ret = q;
148         q = NULL;
149
150         return 0;
151 }
152
153 bool dkr_digest_is_valid(const char *digest) {
154         /* 7 chars for prefix, 64 chars for the digest itself */
155         if (strlen(digest) != 71)
156                 return false;
157
158         return startswith(digest, "sha256:") && in_charset(digest + 7, "0123456789abcdef");
159 }
160
161 bool dkr_ref_is_valid(const char *ref) {
162         const char *colon;
163
164         if (isempty(ref))
165                 return false;
166
167         colon = strchr(ref, ':');
168         if (!colon)
169                 return filename_is_valid(ref);
170
171         return dkr_digest_is_valid(ref);
172 }
173
174 bool dkr_name_is_valid(const char *name) {
175         const char *slash, *p;
176
177         if (isempty(name))
178                 return false;
179
180         slash = strchr(name, '/');
181         if (!slash)
182                 return false;
183
184         if (!filename_is_valid(slash + 1))
185                 return false;
186
187         p = strndupa(name, slash - name);
188         if (!filename_is_valid(p))
189                 return false;
190
191         return true;
192 }
193
194 bool dkr_id_is_valid(const char *id) {
195
196         if (!filename_is_valid(id))
197                 return false;
198
199         if (!in_charset(id, "0123456789abcdef"))
200                 return false;
201
202         return true;
203 }