]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/parse.c
make lxc_af_unix_open() safely return error on long pathnames
[mirror_lxc.git] / src / lxc / parse.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23 #define _GNU_SOURCE
24 #include <stdio.h>
25 #undef _GNU_SOURCE
26 #include <string.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <dirent.h>
30
31 #include "parse.h"
32 #include "config.h"
33 #include <lxc/log.h>
34
35 /* Define getline() if missing from the C library */
36 #ifndef HAVE_GETLINE
37 #ifdef HAVE_FGETLN
38 #include <../include/getline.h>
39 #endif
40 #endif
41
42 /* Workaround for the broken signature of alphasort() in bionic.
43 This was fixed upstream in 40e467ec668b59be25491bd44bf348a884d6a68d so the
44 workaround can probably be dropped with the next version of the Android NDK.
45 */
46 #ifdef IS_BIONIC
47 int bionic_alphasort(const struct dirent** a, const struct dirent** b) {
48 return strcoll((*a)->d_name, (*b)->d_name);
49 }
50 #endif
51
52
53 lxc_log_define(lxc_parse, lxc);
54
55 static int dir_filter(const struct dirent *dirent)
56 {
57 if (!strcmp(dirent->d_name, ".") ||
58 !strcmp(dirent->d_name, ".."))
59 return 0;
60 return 1;
61 }
62
63 int lxc_dir_for_each(const char *name, const char *directory,
64 lxc_dir_cb callback, void *data)
65 {
66 struct dirent **namelist;
67 int n, ret = 0;
68
69 #ifdef IS_BIONIC
70 n = scandir(directory, &namelist, dir_filter, bionic_alphasort);
71 #else
72 n = scandir(directory, &namelist, dir_filter, alphasort);
73 #endif
74 if (n < 0) {
75 SYSERROR("failed to scan %s directory", directory);
76 return -1;
77 }
78
79 while (n--) {
80 if (!ret &&
81 callback(name, directory, namelist[n]->d_name, data)) {
82 ERROR("callback failed");
83 ret = -1;
84 }
85 free(namelist[n]);
86 }
87 free(namelist);
88
89 return ret;
90 }
91
92 int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
93 {
94 FILE *f;
95 int err = 0;
96 char *line = NULL;
97 size_t len = 0;
98
99 f = fopen(file, "r");
100 if (!f) {
101 SYSERROR("failed to open %s", file);
102 return -1;
103 }
104
105 while (getline(&line, &len, f) != -1) {
106 err = callback(line, data);
107 if (err)
108 break;
109 }
110
111 if (line)
112 free(line);
113 fclose(f);
114 return err;
115 }
116
117 int lxc_char_left_gc(char *buffer, size_t len)
118 {
119 int i;
120 for (i = 0; i < len; i++) {
121 if (buffer[i] == ' ' ||
122 buffer[i] == '\t')
123 continue;
124 return i;
125 }
126 return 0;
127 }
128
129 int lxc_char_right_gc(char *buffer, size_t len)
130 {
131 int i;
132 for (i = len - 1; i >= 0; i--) {
133 if (buffer[i] == ' ' ||
134 buffer[i] == '\t' ||
135 buffer[i] == '\n' ||
136 buffer[i] == '\0')
137 continue;
138 return i + 1;
139 }
140 return 0;
141 }
142
143 int lxc_is_line_empty(char *line)
144 {
145 int i;
146 size_t len = strlen(line);
147
148 for (i = 0; i < len; i++)
149 if (line[i] != ' ' && line[i] != '\t' &&
150 line[i] != '\n' && line[i] != '\r' &&
151 line[i] != '\f' && line[i] != '\0')
152 return 0;
153 return 1;
154 }