Line data Source code
1 : /*
2 : * Copyright (c) 2016 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 : /*
16 : * pci.c: Linux user space PCI bus management.
17 : *
18 : * Copyright (c) 2008 Eliot Dresselhaus
19 : *
20 : * Permission is hereby granted, free of charge, to any person obtaining
21 : * a copy of this software and associated documentation files (the
22 : * "Software"), to deal in the Software without restriction, including
23 : * without limitation the rights to use, copy, modify, merge, publish,
24 : * distribute, sublicense, and/or sell copies of the Software, and to
25 : * permit persons to whom the Software is furnished to do so, subject to
26 : * the following conditions:
27 : *
28 : * The above copyright notice and this permission notice shall be
29 : * included in all copies or substantial portions of the Software.
30 : *
31 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 : * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 : * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 : * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 : */
39 :
40 : #include <vlib/vlib.h>
41 : #include <vlib/unix/unix.h>
42 :
43 : #include <sys/types.h>
44 : #include <sys/stat.h>
45 : #include <fcntl.h>
46 : #include <dirent.h>
47 :
48 : clib_error_t *
49 575 : foreach_directory_file (char *dir_name,
50 : clib_error_t * (*f) (void *arg, u8 * path_name,
51 : u8 * file_name), void *arg,
52 : int scan_dirs)
53 : {
54 : DIR *d;
55 : struct dirent *e;
56 575 : clib_error_t *error = 0;
57 : u8 *s, *t;
58 :
59 575 : d = opendir (dir_name);
60 575 : if (!d)
61 : {
62 0 : if (errno == ENOENT)
63 0 : return 0;
64 0 : return clib_error_return_unix (0, "open `%s'", dir_name);
65 : }
66 :
67 575 : s = t = 0;
68 : while (1)
69 : {
70 172500 : e = readdir (d);
71 172500 : if (!e)
72 575 : break;
73 171925 : if (scan_dirs)
74 : {
75 0 : if (e->d_type == DT_DIR
76 0 : && (!strncmp (e->d_name, ".", 1) ||
77 0 : !strncmp (e->d_name, "..", 2)))
78 0 : continue;
79 : }
80 : else
81 : {
82 171925 : if (e->d_type == DT_DIR)
83 1150 : continue;
84 : }
85 :
86 170775 : s = format (s, "%s/%s", dir_name, e->d_name);
87 170775 : t = format (t, "%s", e->d_name);
88 170775 : error = f (arg, s, t);
89 170775 : vec_set_len (s, 0);
90 170775 : vec_set_len (t, 0);
91 :
92 170775 : if (error)
93 0 : break;
94 : }
95 :
96 575 : vec_free (s);
97 575 : closedir (d);
98 :
99 575 : return error;
100 : }
101 :
102 : clib_error_t *
103 1189 : vlib_unix_recursive_mkdir (char *path)
104 : {
105 1189 : clib_error_t *error = 0;
106 1189 : char *c = 0;
107 1189 : int i = 0;
108 :
109 53120 : while (path[i] != 0)
110 : {
111 51931 : if (c && path[i] == '/')
112 : {
113 1838 : vec_add1 (c, 0);
114 1838 : if ((mkdir (c, 0755)) && (errno != EEXIST))
115 : {
116 0 : error = clib_error_return_unix (0, "mkdir '%s'", c);
117 0 : goto done;
118 : }
119 1838 : vec_dec_len (c, 1);
120 : }
121 51931 : vec_add1 (c, path[i]);
122 51931 : i++;
123 : }
124 :
125 1189 : if ((mkdir (path, 0755)) && (errno != EEXIST))
126 : {
127 0 : error = clib_error_return_unix (0, "mkdir '%s'", path);
128 0 : goto done;
129 : }
130 :
131 1189 : done:
132 1189 : vec_free (c);
133 :
134 1189 : return error;
135 : }
136 :
137 : clib_error_t *
138 0 : vlib_unix_validate_runtime_file (unix_main_t * um,
139 : const char *path, u8 ** full_path)
140 : {
141 0 : u8 *fp = 0;
142 0 : char *last_slash = 0;
143 :
144 0 : if (path[0] == '\0')
145 : {
146 0 : return clib_error_return (0, "path is an empty string");
147 : }
148 0 : else if (strncmp (path, "../", 3) == 0 || strstr (path, "/../"))
149 : {
150 0 : return clib_error_return (0, "'..' not allowed in runtime path");
151 : }
152 0 : else if (path[0] == '/')
153 : {
154 : /* Absolute path. Has to start with runtime directory */
155 0 : if (strncmp ((char *) um->runtime_dir, path,
156 0 : strlen ((char *) um->runtime_dir)))
157 : {
158 0 : return clib_error_return (0,
159 : "file %s is not in runtime directory %s",
160 : path, um->runtime_dir);
161 : }
162 0 : fp = format (0, "%s%c", path, '\0');
163 : }
164 : else
165 : {
166 : /* Relative path, just append to runtime */
167 0 : fp = format (0, "%s/%s%c", um->runtime_dir, path, '\0');
168 : }
169 :
170 : /* We don't want to create a directory out of the last file */
171 0 : if ((last_slash = strrchr ((char *) fp, '/')) != NULL)
172 0 : *last_slash = '\0';
173 :
174 0 : clib_error_t *error = vlib_unix_recursive_mkdir ((char *) fp);
175 :
176 0 : if (last_slash != NULL)
177 0 : *last_slash = '/';
178 :
179 0 : if (error)
180 0 : vec_free (fp);
181 :
182 0 : *full_path = fp;
183 0 : return error;
184 : }
185 :
186 : /*
187 : * fd.io coding-style-patch-verification: ON
188 : *
189 : * Local Variables:
190 : * eval: (c-set-style "gnu")
191 : * End:
192 : */
|