"Fossies" - the Fresh Open Source Software Archive 
Member "libisofs-1.5.4/libisofs/builder.c" (8 Jul 2020, 8455 Bytes) of package /linux/misc/libisofs-1.5.4.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "builder.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.4.8_vs_1.5.0.
1 /*
2 * Copyright (c) 2007 Vreixo Formoso
3 * Copyright (c) 2009 - 2015 Thomas Schmitt
4 *
5 * This file is part of the libisofs project; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * or later as published by the Free Software Foundation.
8 * See COPYING file for details.
9 */
10
11 #ifdef HAVE_CONFIG_H
12 #include "../config.h"
13 #endif
14
15 /* libisofs.h defines aaip_xinfo_func */
16 #include "libisofs.h"
17
18 #include "builder.h"
19 #include "node.h"
20 #include "fsource.h"
21 #include "image.h"
22 #include "aaip_0_2.h"
23 #include "util.h"
24 #include "messages.h"
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <limits.h>
29 #include <stdio.h>
30
31
32
33 void iso_node_builder_ref(IsoNodeBuilder *builder)
34 {
35 ++builder->refcount;
36 }
37
38 void iso_node_builder_unref(IsoNodeBuilder *builder)
39 {
40 if (--builder->refcount == 0) {
41 /* free private data */
42 builder->free(builder);
43 free(builder);
44 }
45 }
46
47 static
48 int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
49 IsoFileSource *src, IsoFile **file)
50 {
51 int ret;
52 struct stat info;
53 IsoStream *stream;
54 IsoFile *node;
55 char *name;
56
57 if (builder == NULL || src == NULL || file == NULL) {
58 return ISO_NULL_POINTER;
59 }
60
61 ret = iso_file_source_stat(src, &info);
62 if (ret < 0) {
63 return ret;
64 }
65
66 /* this will fail if src is a dir, is not accessible... */
67 ret = iso_file_source_stream_new(src, &stream);
68 if (ret < 0) {
69 return ret;
70 }
71
72 /* take a ref to the src, as stream has taken our ref */
73 iso_file_source_ref(src);
74
75 name = iso_file_source_get_name(src);
76 if ((int) strlen(name) > image->truncate_length) {
77 ret = iso_truncate_rr_name(image->truncate_mode,
78 image->truncate_length, name, 0);
79 if (ret < 0) {
80 iso_stream_unref(stream);
81 free(name);
82 return ret;
83 }
84 }
85 ret = iso_node_new_file(name, stream, &node);
86 if (ret < 0) {
87 iso_stream_unref(stream);
88 free(name);
89 return ret;
90 }
91
92 /* fill node fields */
93 iso_node_set_permissions((IsoNode*)node, info.st_mode);
94 iso_node_set_uid((IsoNode*)node, info.st_uid);
95 iso_node_set_gid((IsoNode*)node, info.st_gid);
96 iso_node_set_atime((IsoNode*)node, info.st_atime);
97 iso_node_set_mtime((IsoNode*)node, info.st_mtime);
98 iso_node_set_ctime((IsoNode*)node, info.st_ctime);
99 iso_node_set_uid((IsoNode*)node, info.st_uid);
100
101 *file = node;
102 return ISO_SUCCESS;
103 }
104
105 static
106 int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
107 IsoFileSource *src, char *in_name, IsoNode **node)
108 {
109 int ret, name_is_attached = 0;
110 struct stat info;
111 IsoNode *new;
112 IsoFilesystem *fs;
113 char *name = NULL;
114 unsigned char *aa_string = NULL;
115 char *a_text = NULL, *d_text = NULL;
116 char *dest = NULL;
117 IsoSymlink *link;
118
119 if (builder == NULL || src == NULL || node == NULL) {
120 {ret = ISO_NULL_POINTER; goto ex;}
121 }
122
123 /* get info about source */
124 if (iso_tree_get_follow_symlinks(image)) {
125 ret = iso_file_source_stat(src, &info);
126 } else {
127 ret = iso_file_source_lstat(src, &info);
128 }
129 if (ret < 0) {
130 goto ex;
131 }
132
133 if (in_name == NULL) {
134 name = iso_file_source_get_name(src);
135 } else {
136 name = strdup(in_name);
137 if (name == NULL) {
138 ret = ISO_OUT_OF_MEM; goto ex;
139 }
140 }
141
142 if ((int) strlen(name) > image->truncate_length) {
143 ret = iso_truncate_rr_name(image->truncate_mode,
144 image->truncate_length, name, 0);
145 if (ret < 0)
146 goto ex;
147 }
148 fs = iso_file_source_get_filesystem(src);
149 new = NULL;
150
151 switch (info.st_mode & S_IFMT) {
152 case S_IFREG:
153 {
154 /* source is a regular file */
155 IsoStream *stream;
156 IsoFile *file;
157 ret = iso_file_source_stream_new(src, &stream);
158 if (ret < 0) {
159 break;
160 }
161 /* take a ref to the src, as stream has taken our ref */
162 iso_file_source_ref(src);
163
164 /* create the file */
165 ret = iso_node_new_file(name, stream, &file);
166 if (ret < 0) {
167 iso_stream_unref(stream);
168 }
169 new = (IsoNode*) file;
170 }
171 break;
172 case S_IFDIR:
173 {
174 /* source is a directory */
175 IsoDir *dir;
176 ret = iso_node_new_dir(name, &dir);
177 new = (IsoNode*)dir;
178 }
179 break;
180 case S_IFLNK:
181 {
182 /* source is a symbolic link */
183 LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
184 ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
185 if (ret < 0) {
186 break;
187 }
188 ret = iso_node_new_symlink(name, strdup(dest), &link);
189 new = (IsoNode*) link;
190 if (fs != NULL) {
191 link->fs_id = fs->get_id(fs);
192 if (link->fs_id != 0) {
193 link->st_ino = info.st_ino;
194 link->st_dev = info.st_dev;
195 }
196 }
197 }
198 break;
199 case S_IFSOCK:
200 case S_IFBLK:
201 case S_IFCHR:
202 case S_IFIFO:
203 {
204 /* source is an special file */
205 IsoSpecial *special;
206 ret = iso_node_new_special(name, info.st_mode, info.st_rdev,
207 &special);
208 new = (IsoNode*) special;
209 if (fs != NULL) {
210 special->fs_id = fs->get_id(fs);
211 if (special->fs_id != 0) {
212 special->st_ino = info.st_ino;
213 special->st_dev = info.st_dev;
214 }
215 }
216 }
217 break;
218 default:
219 ret = ISO_BAD_FSRC_FILETYPE;
220 goto ex;
221 }
222
223 if (ret < 0)
224 goto ex;
225 name_is_attached = 1;
226
227 /* fill fields */
228 iso_node_set_perms_internal(new, info.st_mode, 1);
229 iso_node_set_uid(new, info.st_uid);
230 iso_node_set_gid(new, info.st_gid);
231 iso_node_set_atime(new, info.st_atime);
232 iso_node_set_mtime(new, info.st_mtime);
233 iso_node_set_ctime(new, info.st_ctime);
234 iso_node_set_uid(new, info.st_uid);
235
236 /* Eventually set S_IRWXG from ACL */
237 if (image->builder_ignore_acl) {
238 ret = iso_file_source_get_aa_string(src, &aa_string, 4);
239 if (ret >= 0 && aa_string != NULL)
240 iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text, 16);
241 if (ret >= 0 && a_text != NULL) {
242 aaip_cleanout_st_mode(a_text, &(info.st_mode), 4 | 16);
243 iso_node_set_perms_internal(new, info.st_mode, 1);
244 }
245 iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text,
246 1 << 15); /* free ACL texts */
247 if(aa_string != NULL)
248 free(aa_string);
249 aa_string = NULL;
250 }
251
252 /* Obtain ownership of eventual AAIP string */
253 ret = iso_file_source_get_aa_string(src, &aa_string,
254 1 | (image->builder_ignore_acl << 1) |
255 (image->builder_ignore_ea << 2) |
256 (image->builder_take_all_ea << 3));
257 if(ret == 2)
258 image->blind_on_local_get_attrs = 1;
259 if (ret > 0 && aa_string != NULL) {
260 ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
261 if (ret < 0)
262 goto ex;
263 } else if(aa_string != NULL) {
264 free(aa_string);
265 }
266
267 *node = new;
268
269 ret = ISO_SUCCESS;
270 ex:;
271 if (name != NULL && !name_is_attached)
272 free(name);
273 LIBISO_FREE_MEM(dest);
274 return ret;
275 }
276
277 static
278 void default_free(IsoNodeBuilder *builder)
279 {
280 /* The .free() method of IsoNodeBuilder shall free private data but not
281 the builder itself. The latter is done in iso_node_builder_unref().
282 */
283 return;
284 }
285
286 int iso_node_basic_builder_new(IsoNodeBuilder **builder)
287 {
288 IsoNodeBuilder *b;
289
290 if (builder == NULL) {
291 return ISO_NULL_POINTER;
292 }
293
294 b = malloc(sizeof(IsoNodeBuilder));
295 if (b == NULL) {
296 return ISO_OUT_OF_MEM;
297 }
298
299 b->refcount = 1;
300 b->create_file_data = NULL;
301 b->create_node_data = NULL;
302 b->create_file = default_create_file;
303 b->create_node = default_create_node;
304 b->free = default_free;
305
306 *builder = b;
307 return ISO_SUCCESS;
308 }