libisofs  1.5.4
About: libisofs is a library to create an ISO 9660 filesystem, supports extensions like RockRidge or Joliet, makes bootable ISO 9660, and records file attributes which are of interest for data backups.
  Fossies Dox: libisofs-1.5.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

filesrc.c File Reference
#include "libisofs.h"
#include "filesrc.h"
#include "node.h"
#include "util.h"
#include "writer.h"
#include "messages.h"
#include "image.h"
#include "stream.h"
#include "md5.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
Include dependency graph for filesrc.c:

Go to the source code of this file.

Macros

#define PATH_MAX   Libisofs_default_path_maX
 

Functions

int iso_file_src_cmp (const void *n1, const void *n2)
 
int iso_file_src_create (Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
 Create a new IsoFileSrc to get data from a specific IsoFile. More...
 
int iso_file_src_add (Ecma119Image *img, IsoFileSrc *new, IsoFileSrc **src)
 Add a given IsoFileSrc to the given image target. More...
 
void iso_file_src_free (void *node)
 Free the IsoFileSrc especific data. More...
 
off_t iso_file_src_get_size (IsoFileSrc *file)
 Get the size of the file this IsoFileSrc represents. More...
 
static int cmp_by_weight (const void *f1, const void *f2)
 
static int shall_be_written (void *arg)
 
static int shall_be_written_if_not_taken (void *arg)
 
int filesrc_writer_pre_compute (IsoImageWriter *writer)
 Determine number of filesrc blocks in the image and compute extent addresses relative to start of the file source writer area. More...
 
static int filesrc_writer_compute_data_blocks (IsoImageWriter *writer)
 
static int filesrc_writer_write_vol_desc (IsoImageWriter *writer)
 
static int filesrc_open (IsoFileSrc *file)
 
static int filesrc_close (IsoFileSrc *file)
 
static int filesrc_read (IsoFileSrc *file, char *buf, size_t count)
 
static int filesrc_make_md5 (Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
 
int iso_filesrc_write_data (Ecma119Image *t, IsoFileSrc *file, char *name, char *buffer, int flag)
 Write the content of file into the output stream of t. More...
 
static int filesrc_writer_write_data (IsoImageWriter *writer)
 
static int filesrc_writer_free_data (IsoImageWriter *writer)
 
int iso_file_src_writer_create (Ecma119Image *target)
 Create a Writer for file contents. More...
 

Macro Definition Documentation

◆ PATH_MAX

#define PATH_MAX   Libisofs_default_path_maX

Definition at line 48 of file filesrc.c.

Function Documentation

◆ cmp_by_weight()

static int cmp_by_weight ( const void *  f1,
const void *  f2 
)
static

Definition at line 217 of file filesrc.c.

218 {
219  IsoFileSrc *f = *((IsoFileSrc**)f1);
220  IsoFileSrc *g = *((IsoFileSrc**)f2);
221  /* higher weighted first */
222  return g->sort_weight - f->sort_weight;
223 }
int sort_weight
Definition: filesrc.h:59

References Iso_File_Src::sort_weight.

Referenced by filesrc_writer_pre_compute().

◆ filesrc_close()

static int filesrc_close ( IsoFileSrc file)
inlinestatic

Definition at line 400 of file filesrc.c.

401 {
402  return iso_stream_close(file->stream);
403 }
int iso_stream_close(IsoStream *stream)
Close a previously opened IsoStream.
Definition: stream.c:804
IsoStream * stream
Definition: filesrc.h:60

References iso_stream_close(), and Iso_File_Src::stream.

Referenced by iso_filesrc_write_data().

◆ filesrc_make_md5()

static int filesrc_make_md5 ( Ecma119Image t,
IsoFileSrc file,
char  md5[16],
int  flag 
)
static

Definition at line 422 of file filesrc.c.

423 {
424  return iso_stream_make_md5(file->stream, md5, 0);
425 }
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
Definition: stream.c:1227

References iso_stream_make_md5(), and Iso_File_Src::stream.

Referenced by iso_filesrc_write_data().

◆ filesrc_open()

static int filesrc_open ( IsoFileSrc file)
inlinestatic

Definition at line 394 of file filesrc.c.

395 {
396  return iso_stream_open(file->stream);
397 }
int iso_stream_open(IsoStream *stream)
Opens the given stream.
Definition: stream.c:798

References iso_stream_open(), and Iso_File_Src::stream.

Referenced by iso_filesrc_write_data().

◆ filesrc_read()

static int filesrc_read ( IsoFileSrc file,
char *  buf,
size_t  count 
)
static
Returns
1 ok, 0 EOF, < 0 error

Definition at line 410 of file filesrc.c.

411 {
412  size_t got;
413 
414  return iso_stream_read_buffer(file->stream, buf, count, &got);
415 }
int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count, size_t *got)
Read the full required amount of data unless error or EOF occurs.
Definition: stream.c:1197

References iso_stream_read_buffer(), and Iso_File_Src::stream.

Referenced by iso_filesrc_write_data().

◆ filesrc_writer_compute_data_blocks()

static int filesrc_writer_compute_data_blocks ( IsoImageWriter writer)
static

Definition at line 346 of file filesrc.c.

347 {
348  Ecma119Image *t;
349  int extent = 0;
350  size_t i;
351  IsoFileSrc *file;
352  IsoFileSrc **filelist;
353 
354  if (writer == NULL) {
355  return ISO_ASSERT_FAILURE;
356  }
357  t = writer->target;
358  filelist = (IsoFileSrc **) writer->data;
359 
360  /* >>> HFS: need to align to allocation block size */;
361  /* >>> HFS: ??? how to handle multi-extent files ? */;
362 
363  t->filesrc_start = t->curblock;
364 
365  /* Give all extent addresses their final absolute value */
366  i = 0;
367  while ((file = filelist[i++]) != NULL) {
368 
369  /* Skip external partitions */
370  if (file->no_write)
371  continue;
372 
373  for (extent = 0; extent < file->nsections; ++extent) {
374  if (file->sections[extent].block == 0xffffffff)
375  file->sections[extent].block = t->empty_file_block;
376  else
377  file->sections[extent].block += t->curblock;
378  }
379  }
380 
381  t->curblock += t->filesrc_blocks;
382  return ISO_SUCCESS;
383 }
#define ISO_SUCCESS
successfully execution
Definition: libisofs.h:8719
#define ISO_ASSERT_FAILURE
Internal programming error.
Definition: libisofs.h:8737
struct iso_file_section * sections
File Sections of the file in the image.
Definition: filesrc.h:56
int nsections
Definition: filesrc.h:57
unsigned int no_write
Definition: filesrc.h:33
Ecma119Image * target
Definition: writer.h:28
void * data
Definition: writer.h:27
uint32_t empty_file_block
Definition: ecma119.h:623
uint32_t filesrc_blocks
Definition: ecma119.h:914
uint32_t curblock
Definition: ecma119.h:618
uint32_t filesrc_start
Definition: ecma119.h:913
uint32_t block
Definition: libisofs.h:258

References iso_file_section::block, ecma119_image::curblock, Iso_Image_Writer::data, ecma119_image::empty_file_block, ecma119_image::filesrc_blocks, ecma119_image::filesrc_start, ISO_ASSERT_FAILURE, ISO_SUCCESS, Iso_File_Src::no_write, Iso_File_Src::nsections, Iso_File_Src::sections, and Iso_Image_Writer::target.

Referenced by iso_file_src_writer_create().

◆ filesrc_writer_free_data()

static int filesrc_writer_free_data ( IsoImageWriter writer)
static

Definition at line 714 of file filesrc.c.

715 {
716  /* free the list of files (contents are free together with the tree) */
717  free(writer->data);
718  return ISO_SUCCESS;
719 }

References Iso_Image_Writer::data, and ISO_SUCCESS.

Referenced by iso_file_src_writer_create().

◆ filesrc_writer_pre_compute()

int filesrc_writer_pre_compute ( IsoImageWriter writer)

Determine number of filesrc blocks in the image and compute extent addresses relative to start of the file source writer area.

filesrc_writer_compute_data_blocks() later makes them absolute.

Definition at line 239 of file filesrc.c.

240 {
241  size_t i, size, is_external;
242  Ecma119Image *t;
243  IsoFileSrc **filelist;
244  int (*inc_item)(void *);
245  size_t omitted_count;
247  int (*include_item)(void *),
248  size_t *size);
249 
250  if (writer == NULL) {
251  return ISO_ASSERT_FAILURE;
252  }
253 
254  t = writer->target;
255  t->filesrc_blocks = 0;
256 
257  /* Normally reserve a single zeroed block for all files which have
258  no block address: symbolic links, device files, empty data files.
259  */
260  if (! t->opts->old_empty)
261  t->filesrc_blocks++;
262 
263  /* on appendable images, ms files shouldn't be included */
264  if (t->opts->appendable) {
265  inc_item = shall_be_written;
266  } else {
267  inc_item = NULL;
268  }
269 
270  /* store the filesrcs in a array */
271  filelist = (IsoFileSrc**) iso_ecma119_to_filesrc_array(t, inc_item, &size);
272  omitted_count = iso_rbtree_count_array(t->files, (size_t) 0,
274  if (omitted_count > 0) {
276  "Cannot arrange content of data files in surely reproducible way");
277  LIBISO_FREE_MEM(filelist);
278  filelist = (IsoFileSrc**)iso_rbtree_to_array(
279  t->files, inc_item, &size);
280  }
281  if (filelist == NULL) {
282  return ISO_OUT_OF_MEM;
283  }
284 
285  /* sort files by weight, if needed */
286  if (t->opts->sort_files) {
287  qsort(filelist, size, sizeof(void*), cmp_by_weight);
288  }
289 
290  /* fill block value */
291  for (i = 0; i < size; ++i) {
292  int extent = 0;
293  IsoFileSrc *file = filelist[i];
294  off_t section_size;
295 
296  /* 0xfffffffe in emerging image means that this is an external
297  partition. Only assess extent sizes but do not count as part
298  of filesrc_writer output.
299  */
300  is_external = (file->no_write == 0 &&
301  file->sections[0].block == 0xfffffffe);
302 
303  section_size = iso_stream_get_size(file->stream);
304  for (extent = 0; extent < file->nsections - 1; ++extent) {
305  file->sections[extent].block = t->filesrc_blocks + extent *
307  file->sections[extent].size = ISO_EXTENT_SIZE;
308  section_size -= (off_t) ISO_EXTENT_SIZE;
309  }
310 
311  /*
312  * final section
313  */
314  if (section_size <= 0) {
315  /* Will become t->empty_file_block
316  in filesrc_writer_compute_data_blocks()
317  Special use of 0xffffffe0 to 0xffffffff is covered by
318  mspad_writer which enforces a minimum start of filesrc at
319  block 0x00000020.
320  */
321  file->sections[extent].block = 0xffffffff;
322  } else {
323  file->sections[extent].block =
324  t->filesrc_blocks + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
325  }
326  file->sections[extent].size = (uint32_t)section_size;
327 
328  /* 0xfffffffe in emerging image means that this is an external
329  partition. Others will take care of the content data.
330  */
331  if (is_external) {
332  file->sections[0].block = 0xfffffffe;
333  file->no_write = 1; /* Ban for filesrc_writer */
334  continue;
335  }
336 
338  }
339 
340  /* the list is only needed by this writer, store locally */
341  writer->data = filelist;
342  return ISO_SUCCESS;
343 }
#define BLOCK_SIZE
Definition: buffer.h:23
IsoFileSrc ** iso_ecma119_to_filesrc_array(Ecma119Image *t, int(*include_item)(void *), size_t *size)
Definition: ecma119.c:4608
#define ISO_EXTENT_SIZE
Definition: ecma119.h:40
static int shall_be_written_if_not_taken(void *arg)
Definition: filesrc.c:233
static int cmp_by_weight(const void *f1, const void *f2)
Definition: filesrc.c:217
static int shall_be_written(void *arg)
Definition: filesrc.c:226
off_t iso_file_src_get_size(IsoFileSrc *file)
Get the size of the file this IsoFileSrc represents.
Definition: filesrc.c:212
#define ISO_OUT_OF_MEM
Memory allocation error (FATAL,HIGH, -6)
Definition: libisofs.h:8745
off_t iso_stream_get_size(IsoStream *stream)
Get the size of a given stream.
Definition: stream.c:810
#define ISO_NOT_REPRODUCIBLE
Cannot arrange content of data files in surely reproducible way (NOTE, HIGH, -409)
Definition: libisofs.h:9200
int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt,...)
Definition: messages.c:579
int id
Definition: image.h:97
IsoImage * image
Definition: ecma119.h:560
IsoWriteOpts * opts
Definition: ecma119.h:563
IsoRBTree * files
Definition: ecma119.h:756
uint32_t size
Definition: libisofs.h:259
unsigned int sort_files
If files should be sorted based on their weight.
Definition: ecma119.h:285
unsigned int old_empty
gid to use when replace_gid == 2.
Definition: ecma119.h:311
unsigned int appendable
This flags control the type of the image to create.
Definition: ecma119.h:364
size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count, int(*include_item)(void *))
Predict the size of the array which gets returned by iso_rbtree_to_array().
Definition: util_rbtree.c:337
#define LIBISO_FREE_MEM(pt)
Definition: util.h:627
#define DIV_UP(n, div)
Definition: util.h:38
void ** iso_rbtree_to_array(IsoRBTree *tree, int(*include_item)(void *), size_t *size)
Get an array view of the elements of the tree.
Definition: util_rbtree.c:284

References iso_write_opts::appendable, iso_file_section::block, BLOCK_SIZE, cmp_by_weight(), Iso_Image_Writer::data, DIV_UP, ecma119_image::files, ecma119_image::filesrc_blocks, Iso_Image::id, ecma119_image::image, ISO_ASSERT_FAILURE, iso_ecma119_to_filesrc_array(), ISO_EXTENT_SIZE, iso_file_src_get_size(), iso_msg_submit(), ISO_NOT_REPRODUCIBLE, ISO_OUT_OF_MEM, iso_rbtree_count_array(), iso_rbtree_to_array(), iso_stream_get_size(), ISO_SUCCESS, LIBISO_FREE_MEM, Iso_File_Src::no_write, Iso_File_Src::nsections, iso_write_opts::old_empty, ecma119_image::opts, Iso_File_Src::sections, shall_be_written(), shall_be_written_if_not_taken(), iso_file_section::size, iso_write_opts::sort_files, Iso_File_Src::stream, and Iso_Image_Writer::target.

Referenced by ecma119_image_new().

◆ filesrc_writer_write_data()

static int filesrc_writer_write_data ( IsoImageWriter writer)
static

Definition at line 658 of file filesrc.c.

659 {
660  int ret;
661  size_t i;
662  Ecma119Image *t = NULL;
663  IsoFileSrc *file;
664  IsoFileSrc **filelist;
665  char *name = NULL;
666  char *buffer = NULL;
667 
668  if (writer == NULL) {
669  ret = ISO_ASSERT_FAILURE; goto ex;
670  }
671 
672  LIBISO_ALLOC_MEM(name, char, PATH_MAX);
673  LIBISO_ALLOC_MEM(buffer, char, BLOCK_SIZE);
674  t = writer->target;
675  filelist = writer->data;
676 
677  iso_msg_debug(t->image->id, "Writing Files...");
678 
679  /* Normally write a single zeroed block as block address target for all
680  files which have no block address:
681  symbolic links, device files, empty data files.
682  */
683  if (! t->opts->old_empty) {
684  ret = iso_write(t, buffer, BLOCK_SIZE);
685  if (ret < 0)
686  goto ex;
687  }
688 
689  i = 0;
690  while ((file = filelist[i++]) != NULL) {
691  if (file->no_write) {
692  /* Do not write external partitions */
693  iso_msg_debug(t->image->id,
694  "filesrc_writer: Skipping no_write-src [%.f , %.f]",
695  (double) file->sections[0].block,
696  (double) (file->sections[0].block - 1 +
697  (file->sections[0].size + 2047) / BLOCK_SIZE));
698  continue;
699  }
700  ret = iso_filesrc_write_data(t, file, name, buffer, 0);
701  if (ret < 0)
702  goto ex;
703  }
704 
705  ret = ISO_SUCCESS;
706 ex:;
707  LIBISO_FREE_MEM(buffer);
708  LIBISO_FREE_MEM(name);
709  return ret;
710 }
int iso_write(Ecma119Image *target, void *buf, size_t count)
This is the function all Writers should call to write data to image.
Definition: ecma119.c:3471
int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file, char *name, char *buffer, int flag)
Write the content of file into the output stream of t.
Definition: filesrc.c:430
#define PATH_MAX
Definition: filesrc.c:48
void iso_msg_debug(int imgid, const char *fmt,...)
Submit a debug message.
Definition: messages.c:253
#define LIBISO_ALLOC_MEM(pt, typ, count)
Definition: util.h:615

References iso_file_section::block, BLOCK_SIZE, Iso_Image_Writer::data, Iso_Image::id, ecma119_image::image, ISO_ASSERT_FAILURE, iso_filesrc_write_data(), iso_msg_debug(), ISO_SUCCESS, iso_write(), LIBISO_ALLOC_MEM, LIBISO_FREE_MEM, Iso_File_Src::no_write, iso_write_opts::old_empty, ecma119_image::opts, PATH_MAX, Iso_File_Src::sections, iso_file_section::size, and Iso_Image_Writer::target.

Referenced by iso_file_src_writer_create().

◆ filesrc_writer_write_vol_desc()

static int filesrc_writer_write_vol_desc ( IsoImageWriter writer)
static

Definition at line 386 of file filesrc.c.

387 {
388  /* nothing needed */
389  return ISO_SUCCESS;
390 }

References ISO_SUCCESS.

Referenced by iso_file_src_writer_create().

◆ iso_file_src_add()

int iso_file_src_add ( Ecma119Image img,
IsoFileSrc new,
IsoFileSrc **  src 
)

Add a given IsoFileSrc to the given image target.

The IsoFileSrc will be cached in a tree to prevent the same file for being written several times to image. If you call again this function with a node that refers to the same source file, the previously created one will be returned.

Parameters
imgThe image where this file is to be written
newThe IsoFileSrc to add
srcWill be filled with a pointer to the IsoFileSrc really present in the tree. It could be different than new if the same file already exists in the tree.
Returns
1 on success, 0 if file already exists on tree, < 0 error

Definition at line 192 of file filesrc.c.

193 {
194  int ret;
195 
196  if (img == NULL || new == NULL || src == NULL) {
197  return ISO_NULL_POINTER;
198  }
199 
200  /* insert the filesrc in the tree */
201  ret = iso_rbtree_insert(img->files, new, (void**)src);
202  return ret;
203 }
#define ISO_NULL_POINTER
NULL pointer as value for an arg.
Definition: libisofs.h:8742
int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item)
Inserts a given element in a Red-Black tree.
Definition: util_rbtree.c:149

References ecma119_image::files, ISO_NULL_POINTER, and iso_rbtree_insert().

Referenced by el_torito_catalog_file_src_create().

◆ iso_file_src_cmp()

int iso_file_src_cmp ( const void *  n1,
const void *  n2 
)

Definition at line 52 of file filesrc.c.

53 {
54  int ret;
55  const IsoFileSrc *f1, *f2;
56 
57  if (n1 == n2) {
58  return 0; /* Normally just a shortcut.
59  But important if Libisofs_file_src_cmp_non_zerO */
60  }
61 
62  f1 = (const IsoFileSrc *)n1;
63  f2 = (const IsoFileSrc *)n2;
64 
65  ret = iso_stream_cmp_ino(f1->stream, f2->stream, 0);
66  return ret;
67 }
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
Compare two streams whether they are based on the same input and will produce the same output.
Definition: stream.c:1042

References iso_stream_cmp_ino(), and Iso_File_Src::stream.

Referenced by ecma119_image_new().

◆ iso_file_src_create()

int iso_file_src_create ( Ecma119Image img,
IsoFile file,
IsoFileSrc **  src 
)

Create a new IsoFileSrc to get data from a specific IsoFile.

The IsoFileSrc will be cached in a tree to prevent the same file for being written several times to image. If you call again this function with a node that refers to the same source file, the previously created one will be returned. No new IsoFileSrc is created in that case.

Parameters
imgThe image where this file is to be written
fileThe IsoNode we want to write
srcWill be filled with a pointer to the IsoFileSrc
Returns
1 if new object was created, 0 if object existed, < 0 on error

Definition at line 69 of file filesrc.c.

70 {
71  int ret, i;
72  IsoFileSrc *fsrc;
73  unsigned int fs_id;
74  dev_t dev_id;
75  ino_t ino_id;
76  int cret, no_md5= 0;
77  void *xipt = NULL;
78 
79  if (img == NULL || file == NULL || src == NULL) {
80  return ISO_NULL_POINTER;
81  }
82 
83  iso_stream_get_id(file->stream, &fs_id, &dev_id, &ino_id);
84 
85  fsrc = calloc(1, sizeof(IsoFileSrc));
86  if (fsrc == NULL) {
87  return ISO_OUT_OF_MEM;
88  }
89 
90  /* fill key and other atts */
91  fsrc->no_write = (file->from_old_session && img->opts->appendable);
92  if (file->from_old_session && img->opts->appendable) {
93  /*
94  * On multisession discs we keep file sections from old image.
95  */
96  int ret = iso_file_get_old_image_sections(file, &(fsrc->nsections),
97  &(fsrc->sections), 0);
98  if (ret < 0) {
99  free(fsrc);
100  return ISO_OUT_OF_MEM;
101  }
102  } else {
103 
104  /*
105  * For new files, or for image copy, we compute our own file sections.
106  * Block and size of each section will be filled later.
107  */
108  off_t section_size = iso_stream_get_size(file->stream);
109  if (section_size > (off_t) MAX_ISO_FILE_SECTION_SIZE) {
110  fsrc->nsections = DIV_UP(section_size - (off_t) MAX_ISO_FILE_SECTION_SIZE,
111  (off_t)ISO_EXTENT_SIZE) + 1;
112  } else {
113  fsrc->nsections = 1;
114  }
115  fsrc->sections = calloc(fsrc->nsections,
116  sizeof(struct iso_file_section));
117  if (fsrc->sections == NULL) {
118  free(fsrc);
119  return ISO_OUT_OF_MEM;
120  }
121  for (i = 0; i < fsrc->nsections; i++)
122  fsrc->sections[i].block = 0;
123  }
124  fsrc->sort_weight = file->sort_weight;
125  fsrc->stream = file->stream;
126 
127  /* insert the filesrc in the tree */
128  ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
129  if (ret <= 0) {
130  if (ret == 0 && (*src)->checksum_index > 0 &&
131  !img->opts->will_cancel) {
132  /* Duplicate file source was mapped to previously registered source
133  */
134  cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
135  if (cret < 0)
136  ret = cret;
137  }
138  free(fsrc->sections);
139  free(fsrc);
140  return ret;
141  }
142  iso_stream_ref(fsrc->stream);
143 
144  if ((img->opts->md5_file_checksums & 1) &&
145  file->from_old_session && img->opts->appendable) {
147  &xipt);
148  if (ret <= 0)
150  &xipt);
151  if (ret <= 0)
152  /* Omit MD5 indexing with old image nodes which have no MD5 */
153  no_md5 = 1;
154  }
155 
156  if ((img->opts->md5_file_checksums & 1) &&
157  !(no_md5 || img->opts->will_cancel)) {
158  img->checksum_idx_counter++;
159  if (img->checksum_idx_counter < 0x7fffffff) {
161  } else {
162  fsrc->checksum_index= 0;
163  img->checksum_idx_counter= 0x7ffffffe; /* keep from rolling over */
164  }
165  cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
166  if (cret < 0)
167  return cret;
168  }
169 
170  return ISO_SUCCESS;
171 }
#define MAX_ISO_FILE_SECTION_SIZE
Definition: ecma119.h:33
int iso_file_get_old_image_sections(IsoFile *file, int *section_count, struct iso_file_section **sections, int flag)
Get the start addresses and the sizes of the data extents of a file node if it was imported from an o...
Definition: fs_image.c:6565
int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
Get the given extended info (defined by the proc function) from the given node.
Definition: node.c:213
void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, ino_t *ino_id)
Get an unique identifier for a given IsoStream.
Definition: stream.c:835
void iso_stream_ref(IsoStream *stream)
Increment reference count of an IsoStream.
Definition: stream.c:784
int checksum_cx_xinfo_func(void *data, int flag)
Definition: md5.c:421
int checksum_md5_xinfo_func(void *data, int flag)
Definition: md5.c:447
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index, int flag)
Set the checksum index (typically coming from IsoFileSrc.checksum_index) of a regular file node.
Definition: node.c:2887
unsigned int checksum_index
Definition: filesrc.h:39
IsoStream * stream
Definition: node.h:166
int sort_weight
It sorts the order in which the file data is written to the CD image.
Definition: node.h:165
unsigned int from_old_session
Definition: node.h:155
Definition: node.h:100
unsigned int checksum_idx_counter
Definition: ecma119.h:760
File section in an old image.
Definition: libisofs.h:257
int will_cancel
Definition: ecma119.h:101
unsigned int md5_file_checksums
Compute MD5 checksums for IsoFile objects and write them to blocks after the data area of the session...
Definition: ecma119.h:282

References iso_write_opts::appendable, iso_file_section::block, checksum_cx_xinfo_func(), ecma119_image::checksum_idx_counter, Iso_File_Src::checksum_index, checksum_md5_xinfo_func(), DIV_UP, ecma119_image::files, Iso_File::from_old_session, ISO_EXTENT_SIZE, iso_file_get_old_image_sections(), iso_file_set_isofscx(), iso_node_get_xinfo(), ISO_NULL_POINTER, ISO_OUT_OF_MEM, iso_rbtree_insert(), iso_stream_get_id(), iso_stream_get_size(), iso_stream_ref(), ISO_SUCCESS, MAX_ISO_FILE_SECTION_SIZE, iso_write_opts::md5_file_checksums, Iso_File_Src::no_write, Iso_File_Src::nsections, ecma119_image::opts, Iso_File_Src::sections, Iso_File_Src::sort_weight, Iso_File::sort_weight, Iso_File_Src::stream, Iso_File::stream, and iso_write_opts::will_cancel.

Referenced by create_file_src(), create_node(), create_tree(), ecma119_writer_create(), and eltorito_writer_create().

◆ iso_file_src_free()

void iso_file_src_free ( void *  node)

Free the IsoFileSrc especific data.

Definition at line 205 of file filesrc.c.

206 {
207  iso_stream_unref(((IsoFileSrc*)node)->stream);
208  free(((IsoFileSrc*)node)->sections);
209  free(node);
210 }
void iso_stream_unref(IsoStream *stream)
Decrement reference count of an IsoStream, and eventually free it if refcount reach 0.
Definition: stream.c:789

References iso_stream_unref().

Referenced by ecma119_image_free().

◆ iso_file_src_get_size()

off_t iso_file_src_get_size ( IsoFileSrc file)

Get the size of the file this IsoFileSrc represents.

Definition at line 212 of file filesrc.c.

213 {
214  return iso_stream_get_size(file->stream);
215 }

References iso_stream_get_size(), and Iso_File_Src::stream.

Referenced by filesrc_writer_pre_compute(), and iso_filesrc_write_data().

◆ iso_file_src_writer_create()

int iso_file_src_writer_create ( Ecma119Image target)

Create a Writer for file contents.

It takes care of written the files in the correct order.

Definition at line 721 of file filesrc.c.

722 {
723  IsoImageWriter *writer;
724 
725  writer = calloc(1, sizeof(IsoImageWriter));
726  if (writer == NULL) {
727  return ISO_OUT_OF_MEM;
728  }
729 
734  writer->data = NULL;
735  writer->target = target;
736 
737  /* add this writer to image */
738  target->writers[target->nwriters++] = writer;
739 
740  return ISO_SUCCESS;
741 }
static int filesrc_writer_free_data(IsoImageWriter *writer)
Definition: filesrc.c:714
static int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
Definition: filesrc.c:346
static int filesrc_writer_write_vol_desc(IsoImageWriter *writer)
Definition: filesrc.c:386
static int filesrc_writer_write_data(IsoImageWriter *writer)
Definition: filesrc.c:658
int(* write_data)(IsoImageWriter *writer)
Definition: writer.h:23
int(* compute_data_blocks)(IsoImageWriter *writer)
Definition: writer.h:19
int(* write_vol_desc)(IsoImageWriter *writer)
Definition: writer.h:21
int(* free_data)(IsoImageWriter *writer)
Definition: writer.h:25
IsoImageWriter ** writers
Definition: ecma119.h:753
size_t nwriters
Definition: ecma119.h:752

References Iso_Image_Writer::compute_data_blocks, Iso_Image_Writer::data, filesrc_writer_compute_data_blocks(), filesrc_writer_free_data(), filesrc_writer_write_data(), filesrc_writer_write_vol_desc(), Iso_Image_Writer::free_data, ISO_OUT_OF_MEM, ISO_SUCCESS, ecma119_image::nwriters, Iso_Image_Writer::target, Iso_Image_Writer::write_data, Iso_Image_Writer::write_vol_desc, and ecma119_image::writers.

Referenced by ecma119_image_new().

◆ iso_filesrc_write_data()

int iso_filesrc_write_data ( Ecma119Image t,
IsoFileSrc file,
char *  name,
char *  buffer,
int  flag 
)

Write the content of file into the output stream of t.

name must be NULL or offer at least PATH_MAX characters of storage. buffer must be NULL or offer at least BLOCK_SIZE characters of storage. flag is not used yet, submit 0.

Definition at line 430 of file filesrc.c.

432 {
433  int res, ret, was_error;
434  char *name_data = NULL;
435  char *buffer_data = NULL;
436  size_t b;
437  off_t file_size;
438  uint32_t nblocks;
439  void *ctx= NULL;
440  char md5[16], pre_md5[16];
441  int pre_md5_valid = 0;
442  IsoStream *stream, *inp;
443 
444 #ifdef Libisofs_with_libjtE
445  int jte_begun = 0;
446 #endif
447 
448  if (name == NULL) {
449  LIBISO_ALLOC_MEM(name_data, char, PATH_MAX);
450  name = name_data;
451  }
452  if (buffer == NULL) {
453  LIBISO_ALLOC_MEM(buffer_data, char, BLOCK_SIZE);
454  buffer = buffer_data;
455  }
456 
457  was_error = 0;
458  file_size = iso_file_src_get_size(file);
459  nblocks = DIV_UP(file_size, BLOCK_SIZE);
460  pre_md5_valid = 0;
461  if (file->checksum_index > 0 && (t->opts->md5_file_checksums & 2)) {
462  /* Obtain an MD5 of content by a first read pass */
463  pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
464  }
465  res = filesrc_open(file);
466 
467  /* Get file name from end of filter chain */
468  for (stream = file->stream; ; stream = inp) {
469  inp = iso_stream_get_input_stream(stream, 0);
470  if (inp == NULL)
471  break;
472  }
473  iso_stream_get_file_name(stream, name);
474  if (res < 0) {
475  /*
476  * UPS, very ugly error, the best we can do is just to write
477  * 0's to image
478  */
480  was_error = 1;
481  res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
482  "File \"%s\" can't be opened. Filling with 0s.", name);
483  if (res < 0) {
484  ret = res; /* aborted due to error severity */
485  goto ex;
486  }
487  memset(buffer, 0, BLOCK_SIZE);
488  for (b = 0; b < nblocks; ++b) {
489  res = iso_write(t, buffer, BLOCK_SIZE);
490  if (res < 0) {
491  /* ko, writer error, we need to go out! */
492  ret = res;
493  goto ex;
494  }
495  }
496  ret = ISO_SUCCESS;
497  goto ex;
498  } else if (res > 1) {
500  was_error = 1;
502  "Size of file \"%s\" has changed. It will be %s", name,
503  (res == 2 ? "truncated" : "padded with 0's"));
504  if (res < 0) {
505  filesrc_close(file);
506  ret = res; /* aborted due to error severity */
507  goto ex;
508  }
509  }
510 #ifdef LIBISOFS_VERBOSE_DEBUG
511  else {
512  iso_msg_debug(t->image->id, "Writing file %s", name);
513  }
514 #endif
515 
516  /* >>> HFS: need to align to allocation block size */;
517 
518 #ifdef Libisofs_with_libjtE
519  if (t->opts->libjte_handle != NULL) {
520  res = libjte_begin_data_file(t->opts->libjte_handle, name,
521  BLOCK_SIZE, file_size);
522  if (res <= 0) {
523  res = iso_libjte_forward_msgs(t->opts->libjte_handle, t->image->id,
525  if (res < 0) {
526  filesrc_close(file);
528  goto ex;
529  }
530  }
531  jte_begun = 1;
532  }
533 #endif /* Libisofs_with_libjtE */
534 
535  if (file->checksum_index > 0) {
536  /* initialize file checksum */
537  res = iso_md5_start(&ctx);
538  if (res <= 0)
539  file->checksum_index = 0;
540  }
541  /* write file contents to image */
542  for (b = 0; b < nblocks; ++b) {
543  int wres;
544  res = filesrc_read(file, buffer, BLOCK_SIZE);
545  if (res < 0) {
546  /* read error */
547  break;
548  }
549  wres = iso_write(t, buffer, BLOCK_SIZE);
550  if (wres < 0) {
551  /* ko, writer error, we need to go out! */
552  filesrc_close(file);
553  ret = wres;
554  goto ex;
555  }
556  if (file->checksum_index > 0) {
557  /* Add to file checksum */
558  if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
559  res = BLOCK_SIZE;
560  else
561  res = file_size - b * BLOCK_SIZE;
562  res = iso_md5_compute(ctx, buffer, res);
563  if (res <= 0)
564  file->checksum_index = 0;
565  }
566  }
567 
568  filesrc_close(file);
569 
570  if (b < nblocks) {
571  /* premature end of file, due to error or eof */
573  was_error = 1;
574  if (res < 0) {
575  /* error */
576  res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
577  "Read error in file %s.", name);
578  } else {
579  /* eof */
581  "Premature end of file %s.", name);
582  }
583 
584  if (res < 0) {
585  ret = res; /* aborted due error severity */
586  goto ex;
587  }
588 
589  /* fill with 0s */
591  "Filling with 0");
592  memset(buffer, 0, BLOCK_SIZE);
593  while (b++ < nblocks) {
594  res = iso_write(t, buffer, BLOCK_SIZE);
595  if (res < 0) {
596  /* ko, writer error, we need to go out! */
597  ret = res;
598  goto ex;
599  }
600  if (file->checksum_index > 0) {
601  /* Add to file checksum */
602  if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
603  res = BLOCK_SIZE;
604  else
605  res = file_size - b * BLOCK_SIZE;
606  res = iso_md5_compute(ctx, buffer, res);
607  if (res <= 0)
608  file->checksum_index = 0;
609  }
610  }
611  }
612  if (file->checksum_index > 0 &&
613  file->checksum_index <= t->checksum_idx_counter) {
614  /* Obtain checksum and dispose checksum context */
615  res = iso_md5_end(&ctx, md5);
616  if (res <= 0)
617  file->checksum_index = 0;
618  if ((t->opts->md5_file_checksums & 2) && pre_md5_valid > 0 &&
619  !was_error) {
620  if (! iso_md5_match(md5, pre_md5)) {
621  /* Issue MISHAP event */
623  was_error = 1;
625  "Content of file '%s' changed while it was written into the image.",
626  name);
627  if (res < 0) {
628  ret = res; /* aborted due to error severity */
629  goto ex;
630  }
631  }
632  }
633  /* Write md5 into checksum buffer at file->checksum_index */
634  memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
635  }
636 
637  ret = ISO_SUCCESS;
638 ex:;
639  if (ctx != NULL) /* avoid any memory leak */
640  iso_md5_end(&ctx, md5);
641 
642 #ifdef Libisofs_with_libjtE
643  if (jte_begun) {
644  res = libjte_end_data_file(t->opts->libjte_handle);
645  iso_libjte_forward_msgs(t->opts->libjte_handle, t->image->id,
647  if (res <= 0 && ret >= 0)
649  }
650 #endif /* Libisofs_with_libjtE */
651 
652  LIBISO_FREE_MEM(buffer_data);
653  LIBISO_FREE_MEM(name_data);
654  return ret;
655 }
static int filesrc_close(IsoFileSrc *file)
Definition: filesrc.c:400
static int filesrc_make_md5(Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
Definition: filesrc.c:422
static int filesrc_read(IsoFileSrc *file, char *buf, size_t count)
Definition: filesrc.c:410
static int filesrc_open(IsoFileSrc *file)
Definition: filesrc.c:394
#define ISO_FILE_CANT_WRITE
Definition: libisofs.h:8838
int iso_md5_end(void **md5_context, char result[16])
Obtain the MD5 checksum from a MD5 computation context and dispose this context.
Definition: md5.c:391
#define ISO_MD5_STREAM_CHANGE
Detected file content changes while it was written into the image.
Definition: libisofs.h:9021
IsoStream * iso_stream_get_input_stream(IsoStream *stream, int flag)
Obtain the eventual input stream of a filter stream.
Definition: stream.c:867
#define ISO_LIBJTE_END_FAILED
Failed to finish Jigdo Template Extraction (FAILURE, HIGH, -365)
Definition: libisofs.h:9058
int iso_md5_match(char first_md5[16], char second_md5[16])
Inquire whether two MD5 checksums match.
Definition: md5.c:403
#define ISO_LIBJTE_FILE_FAILED
Failed to process file for Jigdo Template Extraction (MISHAP, HIGH, -366)
Definition: libisofs.h:9062
int iso_md5_start(void **md5_context)
Create a MD5 computation context and hand out an opaque handle.
Definition: md5.c:353
int iso_md5_compute(void *md5_context, char *data, int datalen)
Advance the computation of a MD5 checksum by a chunk of data bytes.
Definition: md5.c:365
int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
Definition: messages.c:783
int iso_libjte_forward_msgs(void *libjte_handle, int imgid, int errcode, int flag)
Definition: messages.c:792
void iso_stream_get_file_name(IsoStream *stream, char *name)
Get an identifier for the file of the source, for debug purposes.
Definition: stream.c:841
char * checksum_buffer
Definition: ecma119.h:768
Representation of file contents as a stream of bytes.
Definition: libisofs.h:1184

References BLOCK_SIZE, ecma119_image::checksum_buffer, ecma119_image::checksum_idx_counter, Iso_File_Src::checksum_index, DIV_UP, filesrc_close(), filesrc_make_md5(), filesrc_open(), filesrc_read(), Iso_Image::id, ecma119_image::image, ISO_FILE_CANT_WRITE, iso_file_src_get_size(), ISO_LIBJTE_END_FAILED, ISO_LIBJTE_FILE_FAILED, iso_libjte_forward_msgs(), iso_md5_compute(), iso_md5_end(), iso_md5_match(), iso_md5_start(), ISO_MD5_STREAM_CHANGE, iso_msg_debug(), iso_msg_submit(), iso_report_errfile(), iso_stream_get_file_name(), iso_stream_get_input_stream(), ISO_SUCCESS, iso_write(), LIBISO_ALLOC_MEM, LIBISO_FREE_MEM, iso_write_opts::md5_file_checksums, ecma119_image::opts, PATH_MAX, and Iso_File_Src::stream.

Referenced by filesrc_writer_write_data(), and partprepend_writer_write_data().

◆ shall_be_written()

static int shall_be_written ( void *  arg)
static

Definition at line 226 of file filesrc.c.

227 {
228  IsoFileSrc *f = (IsoFileSrc *)arg;
229  return f->no_write ? 0 : 1;
230 }

References Iso_File_Src::no_write.

Referenced by filesrc_writer_pre_compute().

◆ shall_be_written_if_not_taken()

static int shall_be_written_if_not_taken ( void *  arg)
static

Definition at line 233 of file filesrc.c.

234 {
235  IsoFileSrc *f = (IsoFileSrc *)arg;
236  return f->no_write || f->taken ? 0 : 1;
237 }
unsigned int taken
Definition: filesrc.h:37

References Iso_File_Src::no_write, and Iso_File_Src::taken.

Referenced by filesrc_writer_pre_compute().