xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

builder.c
Go to the documentation of this file.
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 
34 {
35  ++builder->refcount;
36 }
37 
39 {
40  if (--builder->refcount == 0) {
41  /* free private data */
42  builder->free(builder);
43  free(builder);
44  }
45 }
46 
47 static
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 */
74 
75  name = iso_file_source_get_name(src);
76  if ((int) strlen(name) > image->truncate_length) {
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
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  }
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 */
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
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 
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;
304  b->free = default_free;
305 
306  *builder = b;
307  return ISO_SUCCESS;
308 }
int aaip_cleanout_st_mode(char *acl_text, mode_t *in_st_mode, int flag)
Definition: aaip_0_2.c:720
void iso_node_builder_ref(IsoNodeBuilder *builder)
Definition: builder.c:33
static int default_create_file(IsoNodeBuilder *builder, IsoImage *image, IsoFileSource *src, IsoFile **file)
Definition: builder.c:48
static int default_create_node(IsoNodeBuilder *builder, IsoImage *image, IsoFileSource *src, char *in_name, IsoNode **node)
Definition: builder.c:106
int iso_node_basic_builder_new(IsoNodeBuilder **builder)
Definition: builder.c:286
void iso_node_builder_unref(IsoNodeBuilder *builder)
Definition: builder.c:38
static void default_free(IsoNodeBuilder *builder)
Definition: builder.c:278
int iso_file_source_lstat(IsoFileSource *src, struct stat *info)
Definition: fsource.c:65
int iso_file_source_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
Definition: fsource.c:126
char * iso_file_source_get_name(IsoFileSource *src)
Definition: fsource.c:59
int iso_file_source_stat(IsoFileSource *src, struct stat *info)
Definition: fsource.c:77
void iso_file_source_ref(IsoFileSource *src)
Definition: fsource.c:22
IsoFilesystem * iso_file_source_get_filesystem(IsoFileSource *src)
Definition: fsource.c:119
int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
Definition: fsource.c:113
int iso_truncate_rr_name(int truncate_mode, int truncate_length, char *name, int flag)
Definition: util.c:2425
#define LIBISO_FREE_MEM(pt)
Definition: util.h:627
#define LIBISO_ALLOC_MEM(pt, typ, count)
Definition: util.h:615
void iso_node_set_permissions(IsoNode *node, mode_t mode)
Definition: node.c:453
#define ISO_SUCCESS
Definition: libisofs.h:8719
int iso_tree_get_follow_symlinks(IsoImage *image)
Definition: tree.c:410
#define ISO_BAD_FSRC_FILETYPE
Definition: libisofs.h:9221
#define ISO_OUT_OF_MEM
Definition: libisofs.h:8745
void iso_node_set_gid(IsoNode *node, gid_t gid)
Definition: node.c:497
void iso_node_set_ctime(IsoNode *node, time_t time)
Definition: node.c:545
void iso_node_set_mtime(IsoNode *node, time_t time)
Definition: node.c:513
int aaip_xinfo_func(void *data, int flag)
Definition: rockridge.c:1118
int iso_node_add_xinfo(IsoNode *node, iso_node_xinfo_func proc, void *data)
Definition: node.c:136
#define ISO_NULL_POINTER
Definition: libisofs.h:8742
void iso_stream_unref(IsoStream *stream)
Definition: stream.c:789
void iso_node_set_atime(IsoNode *node, time_t time)
Definition: node.c:529
void iso_node_set_uid(IsoNode *node, uid_t uid)
Definition: node.c:480
int iso_node_new_dir(char *name, IsoDir **dir)
Definition: node.c:1481
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
Definition: node.c:1507
int iso_node_new_special(char *name, mode_t mode, dev_t dev, IsoSpecial **special)
Definition: node.c:1573
int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
Definition: node.c:1538
int iso_node_set_perms_internal(IsoNode *node, mode_t mode, int flag)
Definition: node.c:430
int iso_aa_get_acl_text(unsigned char *aa_string, mode_t st_mode, char **access_text, char **default_text, int flag)
Definition: node.c:2180
#define LIBISOFS_NODE_PATH_MAX
Definition: node.h:53
int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
Definition: stream.c:225
Definition: node.h:140
Definition: node.h:149
int truncate_length
Definition: image.h:176
int truncate_mode
Definition: image.h:175
int blind_on_local_get_attrs
Definition: image.h:253
unsigned int builder_take_all_ea
Definition: image.h:152
unsigned int builder_ignore_acl
Definition: image.h:139
unsigned int builder_ignore_ea
Definition: image.h:146
void(* free)(IsoNodeBuilder *builder)
Definition: builder.h:65
int(* create_node)(IsoNodeBuilder *builder, IsoImage *image, IsoFileSource *src, char *name, IsoNode **node)
Definition: builder.h:58
void * create_node_data
Definition: builder.h:69
void * create_file_data
Definition: builder.h:68
int(* create_file)(IsoNodeBuilder *builder, IsoImage *image, IsoFileSource *src, IsoFile **file)
Definition: builder.h:44
Definition: node.h:100
ino_t st_ino
Definition: node.h:195
dev_t st_dev
Definition: node.h:194
unsigned int fs_id
Definition: node.h:193
unsigned int(* get_id)(IsoFilesystem *fs)
Definition: libisofs.h:593