]>
git.proxmox.com Git - pve-cluster.git/blob - data/src/cfs-utils.c
2 Copyright (C) 2010 Proxmox Server Solutions GmbH
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Affero General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Affero General Public License for more details.
14 You should have received a copy of the GNU Affero General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Author: Dietmar Maurer <dietmar@proxmox.com>
23 #endif /* HAVE_CONFIG_H */
30 #include <sys/types.h>
36 #include "cfs-utils.h"
38 static const char * hexchar
= "0123456789abcdef";
40 /* convert utf8 to json and syslog compatible ascii */
48 g_return_if_fail(buf
!= NULL
);
52 g_return_if_fail(bufsize
> 10);
56 char *end
= buf
+ bufsize
- 7;
58 if (!g_utf8_validate(msg
, -1, NULL
)) {
59 while (*p
&& d
< end
) {
61 if (c
== 34 && quotequote
) {
64 } else if (c
>= 0 && c
< 32) {
67 *(d
+1) = hexchar
[c
% 10]; c
= c
/ 10;
70 } else if (c
>= 32 && c
< 127) {
80 while (*p
&& d
< end
) {
81 gunichar u
= g_utf8_get_char(p
);
82 if (u
== 34 && quotequote
) {
85 } else if (u
< 32 || u
== 127) {
87 *(d
+2) = hexchar
[u
% 10]; u
= u
/ 10;
88 *(d
+1) = hexchar
[u
% 10]; u
= u
/ 10;
93 } else if (u
< 65536) {
96 *(d
+3) = hexchar
[u
&0xf]; u
= u
>> 4;
97 *(d
+2) = hexchar
[u
&0xf]; u
= u
>> 4;
98 *(d
+1) = hexchar
[u
&0xf]; u
= u
>> 4;
102 /* we simply ignore this */
104 p
= g_utf8_next_char(p
);
111 const gchar
*log_domain
,
112 GLogLevelFlags log_level
,
121 switch (log_level
& G_LOG_LEVEL_MASK
) {
122 case G_LOG_LEVEL_ERROR
:
125 case G_LOG_LEVEL_CRITICAL
:
128 case G_LOG_LEVEL_WARNING
:
131 case G_LOG_LEVEL_MESSAGE
:
134 case G_LOG_LEVEL_INFO
:
137 case G_LOG_LEVEL_DEBUG
:
148 va_start (args
, format
);
149 char *orgmsg
= g_strdup_vprintf (format
, args
);
153 utf8_to_ascii(msg
, sizeof(msg
), orgmsg
, FALSE
);
155 uint32_t tag
= g_quark_from_string(log_domain
);
157 qb_log_from_external_source(func
, file
, "%s", level
, line
, tag
, msg
);
163 cluster_config_version(
164 const gpointer config_data
,
168 GMatchInfo
*match_info
;
171 regex
= g_regex_new ("config_version\\s*:\\s*(\\d+)", 0, 0, NULL
);
172 g_regex_match (regex
, config_data
, 0, &match_info
);
173 if (g_match_info_matches (match_info
)) {
174 gchar
*word
= g_match_info_fetch (match_info
, 1);
176 version
= strtoull(word
, NULL
, 10);
180 g_match_info_free (match_info
);
181 g_regex_unref (regex
);
195 n
= read(fd
, buf
, count
);
196 } while (n
< 0 && errno
== EINTR
);
214 n
= write(fd
, buf
, len
);
215 } while (n
< 0 && errno
== EINTR
);
230 const char *filename
,
236 g_return_val_if_fail(filename
!= NULL
, FALSE
);
237 g_return_val_if_fail(len
== 0 || data
!= NULL
, FALSE
);
241 char *tmp_name
= g_strdup_printf ("%s.XXXXXX", filename
);
242 int fd
= mkstemp(tmp_name
);
244 cfs_critical("Failed to create file '%s': %s", tmp_name
, g_strerror(errno
));
249 if (fchown(fd
, 0, gid
) == -1) {
250 cfs_critical("Failed to change group of file '%s': %s", tmp_name
, g_strerror(errno
));
255 if (fchmod(fd
, mode
) == -1) {
256 cfs_critical("Failed to change mode of file '%s': %s", tmp_name
, g_strerror(errno
));
261 if (len
&& !full_write(fd
, data
, len
)) {
262 cfs_critical("Failed to write file '%s': %s", tmp_name
, g_strerror(errno
));
267 if (close(fd
) == -1) {
268 cfs_critical("Failed to close file '%s': %s", tmp_name
, g_strerror(errno
));
272 if (rename(tmp_name
, filename
) == -1) {
273 cfs_critical("Failed to rename file from '%s' to '%s': %s",
274 tmp_name
, filename
, g_strerror(errno
));
291 path_is_private(const char *path
)
293 while (*path
== '/') path
++;
295 if ((strncmp(path
, "priv", 4) == 0) && (path
[4] == 0 || path
[4] == '/')) {
298 if (strncmp(path
, "nodes/", 6) == 0) {
299 const char *tmp
= path
+ 6;
300 while(*tmp
&& *tmp
!= '/') tmp
++;
302 (strncmp(tmp
, "/priv", 5) == 0) &&
303 (tmp
[5] == 0 || tmp
[5] == '/')) {
312 path_is_lxc_conf(const char *path
)
314 while (*path
== '/') path
++;
316 if (strncmp(path
, "nodes/", 6) == 0) {
317 const char *tmp
= path
+ 6;
318 while(*tmp
&& *tmp
!= '/') tmp
++;
320 (strncmp(tmp
, "/lxc", 4) == 0) &&
321 (tmp
[4] == 0 || tmp
[4] == '/')) {
331 path_is_lockdir(const char *path
)
333 while (*path
== '/') path
++;
335 return (strncmp(path
, "priv/lock/", 10) == 0) && path
[10];