ReactOS  0.4.13-dev-99-g7e18b6d
write.c
Go to the documentation of this file.
1 /* @(#)write.c 1.146 16/12/13 joerg */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5  "@(#)write.c 1.146 16/12/13 joerg";
6 #endif
7 /*
8  * Program write.c - dump memory structures to file for iso9660 filesystem.
9  *
10  * Written by Eric Youngdale (1993).
11  *
12  * Copyright 1993 Yggdrasil Computing, Incorporated
13  * Copyright (c) 1999-2016 J. Schilling
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2, or (at your option)
18  * any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28  */
29 
30 /* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */
31 
32 /* DUPLICATES_ONCE Alex Kopylov cdrtools@bootcd.ru 19.06.2004 */
33 
34 #include "mkisofs.h"
35 #include <schily/time.h>
36 #include <schily/fcntl.h>
37 #ifdef SORTING
38 #include "match.h"
39 #endif /* SORTING */
40 #include <schily/errno.h>
41 #include <schily/schily.h>
42 #include <schily/checkerr.h>
43 #ifdef DVD_AUD_VID
44 #include "dvd_reader.h"
45 #include "dvd_file.h"
46 #include "ifo_read.h"
47 #endif
48 #ifdef APPLE_HYB
49 #include <schily/ctype.h>
50 #endif
51 
52 #ifdef VMS
53 #include "vms.h"
54 #endif
55 
56 #define SIZEOF_UDF_EXT_ATTRIBUTE_COMMON 50
57 
58 /* Max number of sectors we will write at one time */
59 #define NSECT 32
60 
61 #define INSERTMACRESFORK 1
62 
63 /* Counters for statistics */
64 
65 LOCAL int table_size = 0;
71 
72 LOCAL int is_rr_dir = 0;
73 
76 
79 
80 #ifndef APPLE_HFS_HYB
81  char *hfs_error = __("no error");
82 #endif
83 
84 LOCAL int xawrite __PR((void *buffer, int size, int count,
85  FILE *file, int submode, BOOL islast));
86 EXPORT void xfwrite __PR((void *buffer, int size, int count,
87  FILE *file, int submode, BOOL islast));
89 #if defined(APPLE_HYB) || defined(USE_LARGEFILES)
92  int isrfile, unsigned rba));
93 #else
95  FILE *outfile));
96 #endif
97 #ifdef UDF
98 LOCAL void write_udf_symlink __PR((char *filename, off_t size,
99  FILE *outfile));
100 #endif
102 #if 0
103 LOCAL void dump_filelist __PR((void));
104 #endif
105 LOCAL int compare_dirs __PR((const void *rr, const void *ll));
106 EXPORT int sort_directory __PR((struct directory_entry **sort_dir,
107  int rr));
108 LOCAL int root_gen __PR((void));
109 LOCAL BOOL assign_file_addresses __PR((struct directory *dpnt, BOOL isnest));
110 LOCAL void free_one_directory __PR((struct directory *dpnt));
111 LOCAL void free_directories __PR((struct directory *dpnt));
112 EXPORT void generate_one_directory __PR((struct directory *dpnt,
113  FILE *outfile));
114 LOCAL void build_pathlist __PR((struct directory *node));
115 LOCAL int compare_paths __PR((void const *r, void const *l));
116 LOCAL int generate_path_tables __PR((void));
117 EXPORT void memcpy_max __PR((char *to, char *from, int max));
118 EXPORT void outputlist_insert __PR((struct output_fragment *frag));
124 LOCAL int graftcp __PR((char *to, char *from, char *ep));
125 LOCAL int pathcp __PR((char *to, char *from, char *ep));
128 EXPORT int oneblock_size __PR((UInt32_t starting_extent));
129 LOCAL int pathtab_size __PR((UInt32_t starting_extent));
130 LOCAL int startpad_size __PR((UInt32_t starting_extent));
131 LOCAL int interpad_size __PR((UInt32_t starting_extent));
132 LOCAL int endpad_size __PR((UInt32_t starting_extent));
133 LOCAL int file_gen __PR((void));
134 LOCAL int dirtree_dump __PR((void));
135 LOCAL int dirtree_fixup __PR((UInt32_t starting_extent));
136 LOCAL int dirtree_size __PR((UInt32_t starting_extent));
137 LOCAL int ext_size __PR((UInt32_t starting_extent));
143 #ifdef APPLE_HYB
144 LOCAL int hfs_pad;
145 LOCAL int hfs_get_parms __PR((char *key));
146 LOCAL void hfs_file_gen __PR((UInt32_t start_extent));
147 LOCAL void gen_prepboot __PR((void));
148 EXPORT Ulong get_adj_size __PR((int Csize));
149 EXPORT int adj_size __PR((int Csize, UInt32_t start_extent, int extra));
150 EXPORT void adj_size_other __PR((struct directory *dpnt));
151 LOCAL int hfs_hce_write __PR((FILE *outfile));
152 EXPORT int insert_padding_file __PR((int size));
153 #endif /* APPLE_HYB */
154 
155 #ifdef SORTING
156 LOCAL int compare_sort __PR((const void *rr, const void *ll));
157 LOCAL void reassign_link_addresses __PR((struct directory *dpnt));
158 LOCAL int sort_file_addresses __PR((void));
159 #endif /* SORTING */
160 
161 /*
162  * Routines to actually write the disc. We write sequentially so that
163  * we could write a tape, or write the disc directly
164  */
165 #define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof (vol_desc.X))
166 
167 EXPORT void
168 xfwrite(buffer, size, count, file, submode, islast)
169  void *buffer;
170  int size;
171  int count;
172  FILE *file;
173  int submode;
174  BOOL islast;
175 {
176  /*
177  * This is a hack that could be made better.
178  * XXXIs this the only place?
179  * It is definitely needed on Operating Systems that do not allow to
180  * write files that are > 2GB. If the system is fast enough to be able
181  * to feed 1400 KB/s writing speed of a DVD-R drive, use stdout.
182  * If the system cannot do this reliable, you need to use this hacky
183  * option.
184  */
185  static int idx = 0;
186 
187 #ifdef XFWRITE_DEBUG
188  if (count != 1 || (size % 2048) != 0)
189  error(_("Count: %d, size: %d\n"), count, size);
190 #endif
191  if (count == 0 || size == 0) {
193  _("Implementation botch, write 0 bytes (size %d count %d).\n"),
194  size, count);
195  abort();
196  }
197 
198  if (split_output != 0 &&
199  (idx == 0 || ftell(file) >= ((off_t)1024 * 1024 * 1024))) {
200  char nbuf[512];
201  extern char *outfile;
202 
203  if (idx == 0)
204  unlink(outfile);
205  sprintf(nbuf, "%s_%02d", outfile, idx++);
206  file = freopen(nbuf, "wb", file);
207  if (file == NULL) {
208  comerr(_("Cannot open '%s'.\n"), nbuf);
209  }
210  }
211  while (count) {
212  int got;
213 
214  seterrno(0);
215  if (osecsize != 0)
216  got = xawrite(buffer, size, count, file, submode, islast);
217  else
218  got = fwrite(buffer, size, count, file);
219 
220  if (got <= 0) {
221  comerr(_("cannot fwrite %d*%d\n"), size, count);
222  }
223  /*
224  * This comment is in hope to prevent silly people from
225  * e.g. SuSE (who did not yet learn C but believe that
226  * they need to patch other peoples code) from changing the
227  * next cast into an illegal lhs cast expression.
228  * The cast below is the correct way to handle the problem.
229  * The (void *) cast is to avoid a GCC warning like:
230  * "warning: dereferencing type-punned pointer will break \
231  * strict-aliasing rules"
232  * which is wrong this code. (void *) introduces a compatible
233  * intermediate type in the cast list.
234  */
235  count -= got, *(char **)(void *)&buffer += size * got;
236  }
237 }
238 
239 LOCAL int
240 xawrite(buffer, size, count, file, submode, islast)
241  void *buffer;
242  int size;
243  int count;
244  FILE *file;
245  int submode;
246  BOOL islast;
247 {
248  register char *p = buffer;
249  register int amt = size * count;
250  register int n;
251  struct xa_subhdr subhdr[2];
252 
253  if (osecsize == 2048)
254  return (fwrite(buffer, size, count, file));
255 
256  if (amt % 2048)
258  _("Trying to write %d bytes (not a multiple of 2048).\n"),
259  amt);
260 
261  subhdr[0].file_number = subhdr[1].file_number = 0;
262  subhdr[0].channel_number = subhdr[1].channel_number = 0;
263  subhdr[0].coding = subhdr[1].coding = 0;
264 
265  while (amt > 0) {
266 #ifdef LATER
267  if (submode < 0)
268  subhdr[0].sub_mode = subhdr[1].sub_mode = XA_SUBH_DATA;
269  else
270  subhdr[0].sub_mode = subhdr[1].sub_mode = submode;
271 #else
272  subhdr[0].sub_mode = subhdr[1].sub_mode = XA_SUBH_DATA;
273 #endif
274 
275  if ((amt <= 2048) && islast) {
276  subhdr[0].sub_mode = subhdr[1].sub_mode
278  }
279  n = fwrite(subhdr, sizeof (subhdr), 1, file);
280  if (n <= 0)
281  return (n);
282 
283  n = fwrite(p, 2048, 1, file);
284  if (n <= 0)
285  return (n);
286 
287  p += 2048;
288  amt -= 2048;
289  }
290  return (1);
291 }
292 
293 #ifdef APPLE_HYB
294 /*
295  * use the deferred_write struct to store info about the hfs_boot_file
296  */
297 LOCAL struct deferred_write mac_boot;
298 
299 #endif /* APPLE_HYB */
302 
303 UInt32_t last_extent_written = 0;
307 
308 /*
309  * We recursively walk through all of the directories and assign extent
310  * numbers to them. We have already assigned extent numbers to everything that
311  * goes in front of them
312  */
313 LOCAL int
315  struct directory *node;
316 {
317  int dir_size;
318  struct directory *dpnt;
319 
320  dpnt = node;
321 
322  while (dpnt) {
323  /* skip if it's hidden */
324  if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) {
325  dpnt = dpnt->next;
326  continue;
327  }
328  /*
329  * If we already have an extent for this (i.e. it came from a
330  * multisession disc), then don't reassign a new extent.
331  */
332  dpnt->path_index = next_path_index++;
333  if (dpnt->extent == 0) {
334  dpnt->extent = last_extent;
335  dir_size = ISO_BLOCKS(dpnt->size);
336 
337  last_extent += dir_size;
338 
339  /*
340  * Leave room for the CE entries for this directory.
341  * Keep them close to the reference directory so that
342  * access will be quick.
343  */
344  if (dpnt->ce_bytes) {
345  last_extent += ISO_BLOCKS(dpnt->ce_bytes);
346  }
347  }
348  if (dpnt->subdir) {
350  }
351  dpnt = dpnt->next;
352  }
353  return (0);
354 }
355 
356 #if defined(APPLE_HYB) || defined(USE_LARGEFILES)
357 LOCAL void
358 write_one_file(filename, size, outfile, off, isrfile, rba)
359  char *filename;
360  off_t size;
361  FILE *outfile;
362  off_t off;
363  int isrfile;
364  unsigned rba;
365 #else
366 LOCAL void
368  char *filename;
369  off_t size;
370  FILE *outfile;
371 #endif /* APPLE_HYB || USE_LARGEFILES */
372 {
373  /*
374  * It seems that there are still stone age C-compilers
375  * around.
376  * The Metrowerks C found on BeOS/PPC does not allow
377  * more than 32kB of local vars.
378  * As we do not need to call write_one_file() recursively
379  * we make buffer static.
380  */
381 #ifdef __BEOS__
382 static char buffer[SECTOR_SIZE * NSECT];
383 #else
384  char buffer[SECTOR_SIZE * NSECT];
385 #endif
386  FILE *infile;
387  off_t remain;
388  int use;
389  int unroundeduse;
390  int bytestowrite = 0; /* Dummy init. to serve GCC bug */
391  int correctedsize = 0;
392 
393 
394  if ((infile = fopen(filename, "rb")) == NULL) {
395  if (!errhidden(E_OPEN, filename)) {
396  if (!errwarnonly(E_OPEN, filename))
397  ;
398  errmsg(_("Cannot open '%s'.\n"), filename);
400  }
401  }
402 #if defined(APPLE_HYB) || defined(USE_LARGEFILES)
403  if (infile)
405 #if defined(INSERTMACRESFORK) && defined(UDF)
406  if (isrfile && use_udf) {
407  memset(buffer, 0, sizeof (buffer));
408  udf_set_extattr_freespace((Uchar *)buffer, size, rba);
411 
412  memset(buffer, 0, sizeof (buffer));
413  udf_set_extattr_macresfork((Uchar *)buffer, size, rba);
415  correctedsize = SIZEOF_UDF_EXT_ATTRIBUTE_COMMON;
416  }
417 #endif
418 #endif /* APPLE_HYB || USE_LARGEFILES */
419  remain = size;
420 
421  while (remain > 0) {
422  int amt;
423 
424  unroundeduse = use = (remain > SECTOR_SIZE * NSECT - 1 ?
425  NSECT * SECTOR_SIZE : remain);
426  use = ISO_ROUND_UP(use); /* Round up to nearest sector */
427  /* boundary */
428  memset(buffer, 0, use);
429  seterrno(0);
430  if (infile) {
431 #ifdef VMS
432  amt = fread(buffer, 1, use, infile);
433 #else
434  amt = ffileread(infile, buffer, use);
435 #endif
436  } else {
437  amt = use;
438  }
439  if (amt < use && amt != remain) {
440  /*
441  * Note that mkisofs is not star and no 100% archiver.
442  * We only detect file growth if the new size does not
443  * match 'use' at the last read.
444  */
445  if (geterrno() == 0) {
446  if (!errhidden(amt > remain ? E_GROW:E_SHRINK, filename)) {
447  if (!errwarnonly(amt < remain ? E_SHRINK:E_GROW, filename)) {
449  _("Try to use the option -data-change-warn\n"));
451  _("Files should not change while mkisofs is running.\n"));
452  }
454  _("File '%s' did %s.\n"),
455  filename,
456  amt < remain ?
457  _("shrink"):_("grow"));
458  (void) errabort(amt < remain ?
460  filename, TRUE);
461  }
462  } else if (!errhidden(E_READ, filename)) {
463  if (!errwarnonly(E_READ, filename))
464  ;
465  errmsg(_("Cannot read from '%s'\n"), filename);
467  }
468  amt = remain; /* Fake success */
469  if (infile) {
470  fclose(infile); /* Prevent furthe failure */
471  infile = NULL;
472  }
473  }
474 #if defined(APPLE_HYB) && defined(INSERTMACRESFORK) && defined(UDF)
475  if (unroundeduse == remain && isrfile && use_udf && correctedsize) {
476  /* adjust the last block to write according to correctedsize */
477  if (use - unroundeduse == correctedsize) {
478  bytestowrite = use;
479  correctedsize = 0;
480  } else if (use - unroundeduse > correctedsize) {
481  bytestowrite = use - correctedsize;
482  correctedsize = 0;
483  } else if (use - unroundeduse < correctedsize) {
484  bytestowrite = unroundeduse;
485  correctedsize -= use - unroundeduse;
486  }
487  } else {
488  bytestowrite = use;
489  }
490 #else
491  bytestowrite = use;
492 #endif
493 
494  xfwrite(buffer, bytestowrite, 1, outfile,
495  XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT));
497 #if 0
498  if ((last_extent_written % 1000) < use / SECTOR_SIZE) {
500  }
501 #else
502  if (verbose > 0 &&
503  (int)(last_extent_written % (gui ? 500 : 5000)) <
504  use / SECTOR_SIZE) {
505  time_t now;
506  time_t the_end;
507  double frac;
508 
509  time(&now);
511  the_end = begun + (now - begun) / frac;
512 #ifndef NO_FLOATINGPOINT
513  fprintf(stderr, _("%6.2f%% done, estimate finish %s"),
514  frac * 100., ctime(&the_end));
515 #else
516  fprintf(stderr, _("%3d.%-02d%% done, estimate finish %s"),
517  (int)(frac * 100.),
518  (int)((frac+.00005) * 10000.)%100,
519  ctime(&the_end));
520 #endif
521  fflush(stderr);
522  }
523 #endif
524  remain -= use;
525  }
526 #ifdef APPLE_HYB
527 #if defined(INSERTMACRESFORK) && defined(UDF)
528  if (isrfile && use_udf && correctedsize) {
530  memset(buffer, 0, sizeof (buffer));
531  xfwrite(buffer, SECTOR_SIZE - correctedsize, 1, outfile, XA_SUBH_DATA, 1);
533  }
534  }
535 #endif
536 #endif
537  if (infile)
538  fclose(infile);
539 } /* write_one_file(... */
540 
541 #ifdef UDF
542 LOCAL void
543 write_udf_symlink(filename, size, outfile)
544  char *filename;
545  off_t size;
546  FILE *outfile;
547 {
548  static char buffer[SECTOR_SIZE * NSECT];
549  off_t remain = sizeof (buffer);
550  int use;
551 
552  if (udf_get_symlinkcontents(filename, buffer, &remain) < 0) {
553  comerr(_("Cannot open smylink '%s'\n"), filename);
554  }
555  if (remain != size) {
556  comerrno(EX_BAD, _("Symlink '%s' did %s.\n"),
557  filename,
558  size > remain ?
559  _("shrink"):_("grow"));
560  }
561  use = (remain > SECTOR_SIZE * NSECT - 1 ?
562  NSECT * SECTOR_SIZE : remain);
563  use = ISO_ROUND_UP(use);
564  xfwrite(buffer, use, 1, outfile,
565  XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT));
567 
568 } /* write_udf_symlink(... */
569 #endif
570 
571 LOCAL void
573  FILE *outfile;
574 {
575  struct deferred_write *dwpnt,
576  *dwnext;
577  unsigned rba = 0;
578 
579  dwpnt = dw_head;
580  while (dwpnt) {
581 /*#define DEBUG*/
582 #ifdef DEBUG
583  fprintf(stderr,
584  _("The file name is %s and pad is %d, size is %lld and extent is %d\n"),
585  dwpnt->name, dwpnt->pad,
586  (Llong)dwpnt->size, dwpnt->extent);
587 #endif
588  if (dwpnt->table) {
589  xfwrite(dwpnt->table, ISO_ROUND_UP(dwpnt->size), 1,
590  outfile,
591  XA_SUBH_DATA, TRUE);
593  table_size += dwpnt->size;
594 /* fprintf(stderr, _("Size %lld "), (Llong)dwpnt->size); */
595  free(dwpnt->table);
596  dwpnt->table = NULL;
597  } else {
598 
599 #ifdef VMS
600  vms_write_one_file(dwpnt->name, dwpnt->size, outfile);
601 #else
602 #ifdef UDF
603  if ((dwpnt->dw_flags & IS_SYMLINK) && use_udf && create_udfsymlinks) {
604  write_udf_symlink(dwpnt->name, dwpnt->size, outfile);
605  } else {
606 #endif /* UDF */
607 #ifdef APPLE_HYB
608 #if defined(INSERTMACRESFORK) && defined(UDF)
609  if (file_is_resource(dwpnt->name, dwpnt->hfstype) && (dwpnt->size > 0) && use_udf) {
610  rba = dwpnt->extent;
611  } else {
612  rba = 0;
613  }
614 #endif /* INSERTMACRESFORK && UDF */
615  write_one_file(dwpnt->name, dwpnt->size, outfile, dwpnt->off,
616  file_is_resource(dwpnt->name, dwpnt->hfstype) && (dwpnt->size > 0), rba);
617 #else
618 #ifdef USE_LARGEFILES
619  write_one_file(dwpnt->name, dwpnt->size, outfile, dwpnt->off, 0, 0);
620 #else
621  write_one_file(dwpnt->name, dwpnt->size, outfile);
622 #endif
623 #endif /* APPLE_HYB */
624 #ifdef UDF
625  }
626 #endif
627 #endif /* VMS */
628  free(dwpnt->name);
629  dwpnt->name = NULL;
630  }
631 
632 
633 #ifndef DVD_AUD_VID
634 #define dvd_aud_vid_flag 0
635 #endif
636 
637 #ifndef APPLE_HYB
638 #define apple_hyb 0
639 #endif
640 
641 #if defined(APPLE_HYB) || defined(DVD_AUD_VID)
642 
643  if ((apple_hyb && !donotwrite_macpart) || (dvd_aud_vid_flag & DVD_SPEC_VIDEO)) {
644  /*
645  * we may have to pad out ISO files to work with HFS
646  * clump sizes
647  */
648  char blk[SECTOR_SIZE];
649  Uint i;
650 
651  for (i = 0; i < dwpnt->pad; i++)
652  xfwrite(blk, SECTOR_SIZE, 1, outfile, 0, FALSE);
653 
654  last_extent_written += dwpnt->pad;
655  }
656 #endif /* APPLE_HYB || DVD_AUD_VID */
657 
658 
659  dwnext = dwpnt;
660  dwpnt = dwpnt->next;
661  free(dwnext);
662  dwnext = NULL;
663  }
664 } /* write_files(... */
665 
666 #if 0
667 LOCAL void
668 dump_filelist()
669 {
670  struct deferred_write *dwpnt;
671 
672  dwpnt = dw_head;
673  while (dwpnt) {
674  fprintf(stderr, _("File %s\n"), dwpnt->name);
675  dwpnt = dwpnt->next;
676  }
677  fprintf(stderr, "\n");
678 }
679 
680 #endif
681 
682 LOCAL int
684  const void *rr;
685  const void *ll;
686 {
687  char *rpnt,
688  *lpnt;
689  struct directory_entry **r,
690  **l;
691 
692  r = (struct directory_entry **)rr;
693  l = (struct directory_entry **)ll;
694  rpnt = (*r)->isorec.name;
695  lpnt = (*l)->isorec.name;
696 
697 #ifdef APPLE_HYB
698  /*
699  * resource fork MUST (not sure if this is true for HFS volumes) be
700  * before the data fork - so force it here
701  */
702  if ((*r)->assoc && (*r)->assoc == (*l))
703  return (1);
704  if ((*l)->assoc && (*l)->assoc == (*r))
705  return (-1);
706 #endif /* APPLE_HYB */
707 
708  /*
709  * If the names are the same, multiple extent sections of the same file
710  * are sorted by part number. If the part numbers do not differ, this
711  * is an error.
712  */
713  if (strcmp(rpnt, lpnt) == 0) {
714 #ifdef USE_LARGEFILES
715  if ((*r)->mxpart < (*l)->mxpart)
716  return (-1);
717  else if ((*r)->mxpart > (*l)->mxpart)
718  return (1);
719 #endif
721  _("Error: '%s' and '%s' have the same ISO9660 name '%s'.\n"),
722  (*r)->whole_name, (*l)->whole_name,
723  rpnt);
724  sort_goof++;
725  }
726  /* Check we don't have the same RR name */
727  if (use_RockRidge && !is_rr_dir) {
728  /*
729  * entries *can* have the same RR name in the "rr_moved"
730  * directory so skip checks if we're in reloc_dir
731  */
732  if (strcmp((*r)->name, (*l)->name) == 0) {
734  _("Error: '%s' and '%s' have the same Rock Ridge name '%s'.\n"),
735  (*r)->whole_name, (*l)->whole_name,
736  (*r)->name);
737  sort_goof++;
738  }
739  }
740  /*
741  * Put the '.' and '..' entries on the head of the sorted list. For
742  * normal ASCII, this always happens to be the case, but out of band
743  * characters cause this not to be the case sometimes.
744  * FIXME(eric) - these tests seem redundant, in that the name is never
745  * assigned these values. It will instead be \000 or \001, and thus
746  * should always be sorted correctly. I need to figure out why I
747  * thought I needed this in the first place.
748  */
749 #if 0
750  if (strcmp(rpnt, ".") == 0)
751  return (-1);
752  if (strcmp(lpnt, ".") == 0)
753  return (1);
754 
755  if (strcmp(rpnt, "..") == 0)
756  return (-1);
757  if (strcmp(lpnt, "..") == 0)
758  return (1);
759 #else
760  /*
761  * The code above is wrong (as explained in Eric's comment), leading to
762  * incorrect sort order iff the -L option ("allow leading dots") is in
763  * effect and a directory contains entries that start with a dot.
764  * (TF, Tue Dec 29 13:49:24 CET 1998)
765  */
766  if ((*r)->isorec.name_len[0] == 1 && *rpnt == 0)
767  return (-1); /* '.' */
768  if ((*l)->isorec.name_len[0] == 1 && *lpnt == 0)
769  return (1);
770 
771  if ((*r)->isorec.name_len[0] == 1 && *rpnt == 1)
772  return (-1); /* '..' */
773  if ((*l)->isorec.name_len[0] == 1 && *lpnt == 1)
774  return (1);
775 #endif
776 
777  while (*rpnt && *lpnt) {
778  if (*rpnt == ';' && *lpnt != ';')
779  return (-1);
780  if (*rpnt != ';' && *lpnt == ';')
781  return (1);
782 
783  if (*rpnt == ';' && *lpnt == ';')
784  return (0);
785 
786  if (*rpnt == '.' && *lpnt != '.')
787  return (-1);
788  if (*rpnt != '.' && *lpnt == '.')
789  return (1);
790 
791  if ((unsigned char) *rpnt < (unsigned char) *lpnt)
792  return (-1);
793  if ((unsigned char) *rpnt > (unsigned char) *lpnt)
794  return (1);
795  rpnt++;
796  lpnt++;
797  }
798  if (*rpnt)
799  return (1);
800  if (*lpnt)
801  return (-1);
802  return (0);
803 }
804 
805 /*
806  * Function: sort_directory
807  *
808  * Purpose: Sort the directory in the appropriate ISO9660
809  * order.
810  *
811  * Notes: Returns 0 if OK, returns > 0 if an error occurred.
812  */
813 EXPORT int
814 sort_directory(sort_dir, rr)
815  struct directory_entry **sort_dir;
816  int rr;
817 {
818  int dcount = 0;
819  int xcount = 0;
820  int j;
821  int i,
822  len;
823  struct directory_entry *s_entry;
824  struct directory_entry **sortlist;
825 
826  /* need to keep a count of how many entries are hidden */
827  s_entry = *sort_dir;
828  while (s_entry) {
829  if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
830  xcount++;
831  dcount++;
832  s_entry = s_entry->next;
833  }
834 
835  if (dcount == 0) {
836  return (0);
837  }
838  /* OK, now we know how many there are. Build a vector for sorting. */
839  sortlist = (struct directory_entry **)
840  e_malloc(sizeof (struct directory_entry *) * dcount);
841 
842  j = dcount - xcount;
843  dcount = 0;
844  s_entry = *sort_dir;
845  while (s_entry) {
846  if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {
847  /* put any hidden entries at the end of the vector */
848  sortlist[j++] = s_entry;
849  } else {
850  sortlist[dcount] = s_entry;
851  dcount++;
852  }
853  len = s_entry->isorec.name_len[0];
854  s_entry->isorec.name[len] = 0;
855  s_entry = s_entry->next;
856  }
857 
858  /* Each directory is required to contain at least . and .. */
859  if (dcount < 2) {
861  _("Directory size too small (. or .. may be missing)\n"));
862  sort_goof = 1;
863 
864  } else {
865  /* only sort the non-hidden entries */
866  sort_goof = 0;
867  is_rr_dir = rr;
868 #ifdef PROTOTYPES
869  qsort(sortlist, dcount, sizeof (struct directory_entry *),
870  (int (*) (const void *, const void *)) compare_dirs);
871 #else
872  qsort(sortlist, dcount, sizeof (struct directory_entry *),
873  compare_dirs);
874 #endif
875 
876  /*
877  * Now reassemble the linked list in the proper sorted order
878  * We still need the hidden entries, as they may be used in
879  * the Joliet tree.
880  */
881  for (i = 0; i < dcount + xcount - 1; i++) {
882  sortlist[i]->next = sortlist[i + 1];
883  }
884 
885  sortlist[dcount + xcount - 1]->next = NULL;
886  *sort_dir = sortlist[0];
887  }
888 
889  free(sortlist);
890  sortlist = NULL;
891  return (sort_goof);
892 }
893 
894 LOCAL int
896 {
897  init_fstatbuf();
898 
899  root_record.length[0] = 1 +
900  offsetof(struct iso_directory_record, name[0]);
901  root_record.ext_attr_length[0] = 0;
902  set_733((char *)root_record.extent, root->extent);
903  set_733((char *)root_record.size, ISO_ROUND_UP(root->size));
904  iso9660_date(root_record.date, root_statbuf.st_mtime);
905  root_record.flags[0] = ISO_DIRECTORY;
906  root_record.file_unit_size[0] = 0;
907  root_record.interleave[0] = 0;
908  set_723(root_record.volume_sequence_number, volume_sequence_number);
909  root_record.name_len[0] = 1;
910  return (0);
911 }
912 
913 #ifdef SORTING
914 /*
915  * sorts deferred_write entries based on the sort weight
916  */
917 LOCAL int
918 compare_sort(rr, ll)
919  const void *rr;
920  const void *ll;
921 {
922  struct deferred_write **r;
923  struct deferred_write **l;
924  int r_sort;
925  int l_sort;
926 
927  r = (struct deferred_write **)rr;
928  l = (struct deferred_write **)ll;
929  r_sort = (*r)->s_entry->sort;
930  l_sort = (*l)->s_entry->sort;
931 
932  if (r_sort != l_sort)
933  return (r_sort < l_sort ? 1 : -1);
934  else
935  return ((*r)->extent - (*l)->extent);
936 }
937 
938 /*
939  * reassign start extents to files that are "hard links" to
940  * files that may have been sorted
941  */
942 LOCAL void
943 reassign_link_addresses(dpnt)
944  struct directory *dpnt;
945 {
946  struct directory_entry *s_entry;
947  struct file_hash *s_hash;
948 
949  while (dpnt) {
950  s_entry = dpnt->contents;
951  for (s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) {
952  /* link files have already been given the weight NOT_SORTED */
953  if (s_entry->sort != NOT_SORTED)
954  continue;
955 
956  /* update the start extent */
957  s_hash = find_hash(s_entry);
958  if (s_hash) {
959  set_733((char *)s_entry->isorec.extent, s_hash->starting_block);
960  s_entry->starting_block = s_hash->starting_block;
961  }
962  }
963  if (dpnt->subdir) {
964  reassign_link_addresses(dpnt->subdir);
965  }
966 
967  dpnt = dpnt->next;
968  }
969 }
970 
971 /*
972  * sort files in order of the given sort weight
973  */
974 LOCAL int
975 sort_file_addresses()
976 {
977  struct deferred_write *dwpnt;
978  struct deferred_write **sortlist;
979  struct directory_entry *s_entry;
980  UInt32_t start_extent;
981  int num = 0;
982  int i;
983 
984  /* need to store start extents for linked files */
985  flush_hash();
986 
987  /* find out how many files we have */
988  dwpnt = dw_head;
989  while (dwpnt) {
990  num++;
991  dwpnt = dwpnt->next;
992  }
993 
994  /* return if we have none */
995  if (num == 0) {
996  return (1);
997  }
998 
999  /* save the start extent of the first file */
1000  start_extent = dw_head->extent;
1001 
1002  /* set up vector to store entries */
1003  sortlist = (struct deferred_write **)
1004  e_malloc(sizeof (struct deferred_write *) * num);
1005 
1006  for (i = 0, dwpnt = dw_head; i < num; i++, dwpnt = dwpnt->next)
1007  sortlist[i] = dwpnt;
1008 
1009  /* sort the list */
1010 #ifdef PROTOTYPES
1011  qsort(sortlist, num, sizeof (struct deferred_write *),
1012  (int (*)(const void *, const void *))compare_sort);
1013 #else
1014  qsort(sortlist, num, sizeof (struct deferred_write *), compare_sort);
1015 #endif
1016 
1017  /* reconstruct the linked list */
1018  for (i = 0; i < num-1; i++) {
1019  sortlist[i]->next = sortlist[i+1];
1020  }
1021 
1022  sortlist[num-1]->next = NULL;
1023  dw_head = sortlist[0];
1024 
1025  free(sortlist);
1026 
1027  /* set the new start extents for the sorted list */
1028  for (i = 0, dwpnt = dw_head; i < num; i++, dwpnt = dwpnt->next) {
1029  s_entry = dwpnt->s_entry;
1030  dwpnt->extent = s_entry->starting_block = start_extent;
1031 
1032  if (s_entry->de_flags & MULTI_EXTENT) {
1033  struct directory_entry *s_e;
1034  UInt32_t ext = start_extent;
1035 
1036  /*
1037  * For unknown reason, we sometimes get mxroot as
1038  * part of the chain and sometime it's missing.
1039  * Be careful to distinct between the mxroot entry and
1040  * others to select both corectly in a conservative way.
1041  */
1042  s_entry->mxroot->starting_block = start_extent;
1043  set_733((char *)s_entry->mxroot->isorec.extent,
1044  start_extent);
1045  start_extent += ISO_BLOCKS(s_entry->mxroot->size);
1046 
1047  for (s_e = s_entry;
1048  s_e && s_e->mxroot == s_entry->mxroot;
1049  s_e = s_e->next) {
1050  if (s_e == s_entry->mxroot)
1051  continue;
1052 
1053  set_733((char *)s_e->isorec.extent, ext);
1054  s_entry->starting_block = ext;
1055  ext += ISO_BLOCKS(s_e->size);
1056  }
1057  } else {
1058  set_733((char *)s_entry->isorec.extent, start_extent);
1059  start_extent += ISO_BLOCKS(s_entry->size);
1060  }
1061 #ifdef DVD_AUD_VID
1062  /*
1063  * Shouldn't this be done for every type of sort? Otherwise
1064  * we will loose every pad info we add if we sort the files
1065  */
1066  if (dvd_aud_vid_flag & DVD_SPEC_VIDEO) {
1067  start_extent += dwpnt->pad;
1068  }
1069 #endif /* DVD_AUD_VID */
1070 
1071  /* cache start extents for any linked files */
1072  add_hash(s_entry);
1073  }
1074 
1075  return (0);
1076 }
1077 #endif /* SORTING */
1078 
1079 
1080 
1081 LOCAL BOOL
1083  struct directory *dpnt;
1084  BOOL isnest;
1085 {
1086  struct directory *finddir;
1087  struct directory_entry *s_entry;
1088  struct file_hash *s_hash;
1089  struct deferred_write *dwpnt;
1090  char whole_path[PATH_MAX];
1091 #ifdef DVD_AUD_VID
1092  char dvd_path[PATH_MAX];
1093  title_set_info_t *title_set_info = NULL;
1094  char *p;
1095 #endif
1096  BOOL ret = FALSE;
1097 
1098  while (dpnt) {
1099 #ifdef DVD_AUD_VID
1100  if ((dvd_aud_vid_flag & DVD_SPEC_VIDEO) && root == dpnt->parent &&
1101  ((p = strstr(dpnt->whole_name, "VIDEO_TS")) != 0)&&
1102  strcmp(p, "VIDEO_TS") == 0) {
1103  int maxlen = strlen(dpnt->whole_name)-8+1;
1104 
1105  if (maxlen > sizeof (dvd_path))
1106  maxlen = sizeof (dvd_path);
1107  strlcpy(dvd_path, dpnt->whole_name, maxlen);
1108 #ifdef DEBUG
1109  fprintf(stderr, _("Found 'VIDEO_TS', the path is %s \n"), dvd_path);
1110 #endif
1111  title_set_info = DVDGetFileSet(dvd_path);
1112  if (title_set_info == 0) {
1113  /*
1114  * Do not switch off -dvd-video but let is fail later.
1115  */
1116 /* dvd_aud_vid_flag &= ~DVD_SPEC_VIDEO;*/
1117  errmsgno(EX_BAD, _("Unable to parse DVD-Video structures.\n"));
1118  } else {
1119  ret = TRUE;
1120  }
1121  }
1122 #endif /* DVD_AUD_VID */
1123 
1124  for (s_entry = dpnt->contents; s_entry;
1125  s_entry = s_entry->next) {
1126  /*
1127  * If we already have an extent for this entry, then
1128  * don't assign a new one. It must have come from a
1129  * previous session on the disc. Note that we don't
1130  * end up scheduling the thing for writing either.
1131  */
1132  if (get_733(s_entry->isorec.extent) != 0) {
1133  continue;
1134  }
1135  /*
1136  * This saves some space if there are symlinks present.
1137  * If this is a multi-extent file, we get mxpart == 1
1138  * from find_hash().
1139  */
1140  s_hash = find_hash(s_entry);
1141  if (s_hash) {
1142  if (verbose > 2) {
1143  fprintf(stderr, _("Cache hit for '%s%s%s'\n"),
1144  s_entry->filedir->de_name,
1146  s_entry->name);
1147  }
1148  s_entry->starting_block = s_hash->starting_block;
1149  set_733((char *)s_entry->isorec.extent,
1150  s_hash->starting_block);
1151  set_733((char *)s_entry->isorec.size,
1152  s_hash->size);
1153 #ifdef USE_LARGEFILES
1154  if (s_entry->de_flags & MULTI_EXTENT) {
1155  struct directory_entry *s_e;
1156  unsigned int ext = s_hash->starting_block;
1157 
1158  /*
1159  * Skip the multi extent root entry.
1160  */
1161  if (s_entry->mxpart == 0)
1162  continue;
1163  /*
1164  * The directory is sorted, so we should
1165  * see s_entry->mxpart == 1 first.
1166  */
1167  if (s_entry->mxpart != 1) {
1168  comerrno(EX_BAD,
1169  _("Panic: Multi extent parts for %s not sorted.\n"),
1170  s_entry->whole_name);
1171  }
1172  s_entry->mxroot->starting_block = ext;
1173  for (s_e = s_entry;
1174  s_e && s_e->mxroot == s_entry->mxroot;
1175  s_e = s_e->next) {
1176  set_733((char *)s_e->isorec.extent,
1177  ext);
1178  ext += ISO_BLOCKS(s_e->size);
1179  }
1180  }
1181 #endif
1182 
1183 #ifdef SORTING
1184  /* check for non-directory files */
1185  if (do_sort && ((s_entry->isorec.flags[0] & ISO_DIRECTORY) == 0)) {
1186  /* make sure the real file has the highest weighting */
1187  s_hash->de->sort = MAX(s_entry->sort, s_hash->de->sort);
1188  /* flag this as a potential non-sorted file */
1189  s_entry->sort = NOT_SORTED;
1190  }
1191 #endif /* SORTING */
1192  continue;
1193  }
1194  /*
1195  * If this is for a directory that is not a . or
1196  * a .. entry, then look up the information for the
1197  * entry. We have already assigned extents for
1198  * directories, so we just need to fill in the blanks
1199  * here.
1200  */
1201  if (strcmp(s_entry->name, ".") != 0 &&
1202  strcmp(s_entry->name, "..") != 0 &&
1203  s_entry->isorec.flags[0] & ISO_DIRECTORY) {
1204  finddir = dpnt->subdir;
1205  while (finddir && finddir->self != s_entry) {
1206  finddir = finddir->next;
1207  }
1208  if (!finddir) {
1209 #ifdef DVD_AUD_VID
1210  if (title_set_info != 0) {
1211  DVDFreeFileSet(title_set_info);
1212  }
1213 #endif
1214  comerrno(EX_BAD,
1215  _("Fatal goof - could not find dir entry for '%s'\n"),
1216  s_entry->name);
1217  }
1218  set_733((char *)s_entry->isorec.extent,
1219  finddir->extent);
1220  s_entry->starting_block = finddir->extent;
1221  s_entry->size = ISO_ROUND_UP(finddir->size);
1222  total_dir_size += s_entry->size;
1223  add_hash(s_entry);
1224  set_733((char *)s_entry->isorec.size,
1225  ISO_ROUND_UP(finddir->size));
1226  continue;
1227  }
1228  /*
1229  * If this is . or .., then look up the relevant info
1230  * from the tables.
1231  */
1232  if (strcmp(s_entry->name, ".") == 0) {
1233  set_733((char *)s_entry->isorec.extent,
1234  dpnt->extent);
1235 
1236  /*
1237  * Set these so that the hash table has the
1238  * correct information
1239  */
1240  s_entry->starting_block = dpnt->extent;
1241  s_entry->size = ISO_ROUND_UP(dpnt->size);
1242 
1243  add_hash(s_entry);
1244  s_entry->starting_block = dpnt->extent;
1245  set_733((char *)s_entry->isorec.size,
1246  ISO_ROUND_UP(dpnt->size));
1247  continue;
1248  }
1249  if (strcmp(s_entry->name, "..") == 0) {
1250  if (dpnt == root) {
1251  total_dir_size += root->size;
1252  }
1253  set_733((char *)s_entry->isorec.extent,
1254  dpnt->parent->extent);
1255 
1256  /*
1257  * Set these so that the hash table has the
1258  * correct information
1259  */
1260  s_entry->starting_block = dpnt->parent->extent;
1261  s_entry->size =
1262  ISO_ROUND_UP(dpnt->parent->size);
1263 
1264  add_hash(s_entry);
1265  s_entry->starting_block = dpnt->parent->extent;
1266  set_733((char *)s_entry->isorec.size,
1267  ISO_ROUND_UP(dpnt->parent->size));
1268  continue;
1269  }
1270  /*
1271  * Some ordinary non-directory file. Just schedule
1272  * the file to be written. This is all quite
1273  * straightforward, just make a list and assign
1274  * extents as we go. Once we get through writing all
1275  * of the directories, we should be ready write out
1276  * these files
1277  */
1278  if (s_entry->size) {
1279  dwpnt = (struct deferred_write *)
1280  e_malloc(sizeof (struct deferred_write));
1281  /* save this directory entry for later use */
1282  dwpnt->s_entry = s_entry;
1283  /* set the initial padding to zero */
1284  dwpnt->pad = 0;
1285  dwpnt->dw_flags = 0;
1286 #ifdef DVD_AUD_VID
1287  if ((dvd_aud_vid_flag & DVD_SPEC_VIDEO) && (title_set_info != 0)) {
1288  int pad;
1289 
1290  pad = DVDGetFilePad(title_set_info, s_entry->name);
1291  if (pad < 0) {
1292  errmsgno(EX_BAD,
1293  _("Implementation botch. Video pad for file %s is %d\n"),
1294  s_entry->name, pad),
1295  comerrno(EX_BAD,
1296  _("Either the *.IFO file is bad or you found a mkisofs bug.\n"));
1297  }
1298  dwpnt->pad = pad;
1299  if (verbose > 0 && pad != 0) {
1300  fprintf(stderr,
1301  _("The pad was %d for file %s\n"),
1302  dwpnt->pad, s_entry->name);
1303  }
1304  }
1305 #endif /* DVD_AUD_VID */
1306 #ifdef APPLE_HYB
1307  /*
1308  * maybe an offset to start of the real
1309  * file/fork
1310  */
1311  dwpnt->off = s_entry->hfs_off;
1312  dwpnt->hfstype = s_entry->hfs_type;
1313 #else
1314  dwpnt->off = (off_t)0;
1315 #endif /* APPLE_HYB */
1316  if (s_entry->inode == TABLE_INODE) {
1317  dwpnt->table = s_entry->table;
1318  dwpnt->name = NULL;
1319  sprintf(whole_path, "%s%s%s",
1320  s_entry->filedir->whole_name,
1322  } else {
1323  dwpnt->table = NULL;
1324  strlcpy(whole_path,
1325  s_entry->whole_name,
1326  sizeof (whole_path));
1327  dwpnt->name = e_strdup(whole_path);
1328  }
1329  dwpnt->next = NULL;
1330  dwpnt->size = s_entry->size;
1331  dwpnt->extent = last_extent;
1332  set_733((char *)s_entry->isorec.extent,
1333  last_extent);
1334  s_entry->starting_block = last_extent;
1335 #ifdef USE_LARGEFILES
1336  /*
1337  * Update the entries for multi-section files
1338  * as we now know the starting extent numbers.
1339  */
1340  if (s_entry->de_flags & MULTI_EXTENT) {
1341  struct directory_entry *s_e;
1342  unsigned int ext = last_extent;
1343 
1344  /*
1345  * Skip the multi extent root entry.
1346  */
1347  if (s_entry->mxpart == 0) {
1348  if (dwpnt->name)
1349  free(dwpnt->name);
1350  free(dwpnt);
1351  continue;
1352  }
1353  /*
1354  * The directory is sorted, so we should
1355  * see s_entry->mxpart == 1 first.
1356  */
1357  if (s_entry->mxpart != 1) {
1358  comerrno(EX_BAD,
1359  _("Panic: Multi extent parts for %s not sorted.\n"),
1360  s_entry->whole_name);
1361  }
1362  dwpnt->size = s_entry->mxroot->size;
1363  s_entry->mxroot->starting_block = ext;
1364  /*
1365  * Set the mxroot (mxpart == 0) to allow
1366  * the UDF code to fetch the starting
1367  * extent number.
1368  */
1369  set_733((char *)s_entry->mxroot->isorec.extent, ext);
1370  for (s_e = s_entry;
1371  s_e && s_e->mxroot == s_entry->mxroot;
1372  s_e = s_e->next) {
1373  if (s_e->mxpart == 0)
1374  continue;
1375  set_733((char *)s_e->isorec.extent,
1376  ext);
1377  ext += ISO_BLOCKS(s_e->size);
1378  }
1379  add_hash(s_entry);
1380  }
1381 #endif
1382  if (dw_tail) {
1383  dw_tail->next = dwpnt;
1384  dw_tail = dwpnt;
1385  } else {
1386  dw_head = dwpnt;
1387  dw_tail = dwpnt;
1388  }
1389  add_hash(s_entry);
1390  /*
1391  * The cache holds the full size of the file
1392  */
1393  last_extent += ISO_BLOCKS(dwpnt->size);
1394  dwpnt->dw_flags = s_entry->de_flags;
1395 #ifdef APPLE_HYB
1396 #if defined(INSERTMACRESFORK) && defined(UDF)
1397  if (file_is_resource(dwpnt->name, dwpnt->s_entry->hfs_type) && (dwpnt->size > 0) && use_udf) {
1398  last_extent++;
1399  if (ISO_ROUND_UP(dwpnt->size) <
1401  last_extent++;
1402  }
1403  }
1404 #endif
1405 #endif /* APPLE_HYB */
1406 #ifdef DVD_AUD_VID
1407  /* Shouldn't we always add the pad info? */
1408  if (dvd_aud_vid_flag & DVD_SPEC_VIDEO) {
1409  last_extent += dwpnt->pad;
1410  }
1411 #endif /* DVD_AUD_VID */
1412  if (verbose > 2) {
1413  fprintf(stderr, "%u %d %s\n",
1414  s_entry->starting_block,
1415  last_extent - 1, whole_path);
1416  }
1417 #ifdef DBG_ISO
1418  if (ISO_BLOCKS(s_entry->size) > 500) {
1419  fprintf(stderr,
1420  _("Warning: large file '%s'\n"),
1421  whole_path);
1422  fprintf(stderr,
1423  _("Starting block is %d\n"),
1424  s_entry->starting_block);
1425  fprintf(stderr,
1426  _("Reported file size is %lld\n"),
1427  (Llong)s_entry->size);
1428 
1429  }
1430 #endif
1431 #ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */
1432 
1433  if (last_extent > (800000000 >> 11)) {
1434  /* More than 800Mb? Punt */
1435  fprintf(stderr,
1436  _("Extent overflow processing file '%s'\n"),
1437  whole_path);
1438  fprintf(stderr,
1439  _("Starting block is %d\n"),
1440  s_entry->starting_block);
1441  fprintf(stderr,
1442  _("Reported file size is %lld\n"),
1443  (Llong)s_entry->size);
1444  exit(1);
1445  }
1446 #endif
1447  continue;
1448  }
1449  /*
1450  * This is for zero-length files. If we leave the
1451  * extent 0, then we get screwed, because many readers
1452  * simply drop files that have an extent of zero.
1453  * Thus we leave the size 0, and just assign the
1454  * extent number.
1455  */
1456  set_733((char *)s_entry->isorec.extent, last_extent);
1457  }
1458  if (dpnt->subdir) {
1459  if (assign_file_addresses(dpnt->subdir, TRUE))
1460  ret = TRUE;
1461  }
1462  dpnt = dpnt->next;
1463  }
1464 #ifdef DVD_AUD_VID
1465  if (title_set_info != NULL) {
1466  DVDFreeFileSet(title_set_info);
1467  }
1468  if ((dvd_aud_vid_flag & DVD_SPEC_VIDEO)&& !ret && !isnest) {
1469  errmsgno(EX_BAD,
1470  _("Could not find correct 'VIDEO_TS' directory.\n"));
1471  }
1472 #endif /* DVD_AUD_VID */
1473  return (ret);
1474 } /* assign_file_addresses(... */
1475 
1476 LOCAL void
1478  struct directory *dpnt;
1479 {
1480  struct directory_entry *s_entry;
1481  struct directory_entry *s_entry_d;
1482 
1483  s_entry = dpnt->contents;
1484  while (s_entry) {
1485  s_entry_d = s_entry;
1486  s_entry = s_entry->next;
1487 
1488  if (s_entry_d->rr_attributes) {
1489  free(s_entry_d->rr_attributes);
1490  s_entry_d->rr_attributes = NULL;
1491  }
1492  if (s_entry_d->name != NULL) {
1493  free(s_entry_d->name);
1494  s_entry_d->name = NULL;
1495  }
1496  if (s_entry_d->whole_name != NULL) {
1497  free(s_entry_d->whole_name);
1498  s_entry_d->whole_name = NULL;
1499  }
1500 #ifdef APPLE_HYB
1501  if (apple_both && s_entry_d->hfs_ent && !s_entry_d->assoc &&
1502  (s_entry_d->isorec.flags[0] & ISO_MULTIEXTENT) == 0) {
1503  free(s_entry_d->hfs_ent);
1504  }
1505 #endif /* APPLE_HYB */
1506 
1507 #ifdef DUPLICATES_ONCE
1508  if (s_entry_d->digest_fast) {
1509 
1510  if (s_entry_d->digest_full &&
1511  (s_entry_d->digest_full != s_entry_d->digest_fast))
1512  free(s_entry_d->digest_full);
1513 
1514  free(s_entry_d->digest_fast);
1515 
1516  s_entry_d->digest_fast = NULL;
1517  s_entry_d->digest_full = NULL;
1518  }
1519 #endif
1520  free(s_entry_d);
1521  s_entry_d = NULL;
1522  }
1523  dpnt->contents = NULL;
1524 } /* free_one_directory(... */
1525 
1526 LOCAL void
1528  struct directory *dpnt;
1529 {
1530  while (dpnt) {
1531  free_one_directory(dpnt);
1532  if (dpnt->subdir)
1533  free_directories(dpnt->subdir);
1534  dpnt = dpnt->next;
1535  }
1536 }
1537 
1538 EXPORT void
1540  struct directory *dpnt;
1541  FILE *outfile;
1542 {
1543  unsigned int ce_address = 0;
1544  char *ce_buffer;
1545  unsigned int ce_index = 0;
1546  unsigned int ce_size;
1547  unsigned int dir_index;
1548  char *directory_buffer;
1549  int new_reclen;
1550  struct directory_entry *s_entry;
1551  struct directory_entry *s_entry_d;
1552  unsigned int total_size;
1553 
1554  total_size = ISO_ROUND_UP(dpnt->size);
1555  directory_buffer = (char *)e_malloc(total_size);
1556  memset(directory_buffer, 0, total_size);
1557  dir_index = 0;
1558 
1559  ce_size = ISO_ROUND_UP(dpnt->ce_bytes);
1560  ce_buffer = NULL;
1561 
1562  if (ce_size > 0) {
1563  ce_buffer = (char *)e_malloc(ce_size);
1564  memset(ce_buffer, 0, ce_size);
1565 
1566  ce_index = 0;
1567 
1568  /* Absolute sector address of CE entries for this directory */
1569  ce_address = last_extent_written + (total_size >> 11);
1570  }
1571  s_entry = dpnt->contents;
1572  while (s_entry) {
1573  /* skip if it's hidden */
1574  if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {
1575  s_entry = s_entry->next;
1576  continue;
1577  }
1578  /*
1579  * We do not allow directory entries to cross sector
1580  * boundaries. Simply pad, and then start the next entry at
1581  * the next sector
1582  */
1583  new_reclen = s_entry->isorec.length[0];
1584  if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >=
1585  SECTOR_SIZE) {
1586  dir_index = ISO_ROUND_UP(dir_index);
1587  }
1588  memcpy(directory_buffer + dir_index, &s_entry->isorec,
1589  offsetof(struct iso_directory_record, name[0]) +
1590  s_entry->isorec.name_len[0]);
1591  dir_index += offsetof(struct iso_directory_record, name[0]) +
1592  s_entry->isorec.name_len[0];
1593 
1594  /* Add the Rock Ridge attributes, if present */
1595  if (s_entry->rr_attr_size) {
1596  if (dir_index & 1) {
1597  directory_buffer[dir_index++] = 0;
1598  }
1599  /*
1600  * If the RR attributes were too long, then write the
1601  * CE records, as required.
1602  */
1603  if (s_entry->rr_attr_size != s_entry->total_rr_attr_size) {
1604  struct iso_xa_dir_record *xadp;
1605  unsigned char *pnt;
1606  int len,
1607  nbytes;
1608 
1609  /*
1610  * Go through the entire record, first skip
1611  * the XA record and then fix up the
1612  * CE entries so that the extent and offset
1613  * are correct
1614  */
1615  pnt = s_entry->rr_attributes;
1616  len = s_entry->total_rr_attr_size;
1617 
1618  if (len >= 14) {
1619  xadp = (struct iso_xa_dir_record *)pnt;
1620 
1621  if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' &&
1622  xadp->reserved[0] == '\0') {
1623  len -= 14;
1624  pnt += 14;
1625  }
1626  }
1627 
1628  while (len > 3) {
1629 #ifdef DEBUG
1630  if (ce_size <= 0) {
1631  fprintf(stderr,
1632  _("Warning: ce_index(%d) && ce_address(%d) not initialized\n"),
1633  ce_index, ce_address);
1634  }
1635 #endif
1636 
1637  if (pnt[0] == 'C' && pnt[1] == 'E') {
1638  nbytes = get_733((char *)pnt + 20);
1639 
1640  if ((ce_index & (SECTOR_SIZE - 1)) + nbytes >=
1641  SECTOR_SIZE) {
1642  ce_index = ISO_ROUND_UP(ce_index);
1643  }
1644  set_733((char *)pnt + 4,
1645  ce_address + (ce_index >> 11));
1646  set_733((char *)pnt + 12,
1647  ce_index & (SECTOR_SIZE - 1));
1648 
1649 
1650 
1651  /*
1652  * Now store the block in the
1653  * ce buffer
1654  */
1655  memcpy(ce_buffer + ce_index,
1656  pnt + pnt[2], nbytes);
1657  ce_index += nbytes;
1658  if (ce_index & 1) {
1659  ce_index++;
1660  }
1661  }
1662  len -= pnt[2];
1663  pnt += pnt[2];
1664  }
1665 
1666  }
1667  rockridge_size += s_entry->total_rr_attr_size;
1668  memcpy(directory_buffer + dir_index,
1669  s_entry->rr_attributes,
1670  s_entry->rr_attr_size);
1671  dir_index += s_entry->rr_attr_size;
1672  }
1673  if (dir_index & 1) {
1674  directory_buffer[dir_index++] = 0;
1675  }
1676  s_entry_d = s_entry;
1677  s_entry = s_entry->next;
1678 
1679  /*
1680  * Joliet doesn't use the Rock Ridge attributes, so we free
1681  * it here.
1682  */
1683  if (s_entry_d->rr_attributes) {
1684  free(s_entry_d->rr_attributes);
1685  s_entry_d->rr_attributes = NULL;
1686  }
1687  }
1688 
1689  if (dpnt->size != dir_index) {
1690  errmsgno(EX_BAD,
1691  _("Unexpected directory length %lld expected: %d '%s'\n"),
1692  (Llong)dpnt->size,
1693  dir_index, dpnt->de_name);
1694  }
1695  xfwrite(directory_buffer, total_size, 1, outfile, 0, FALSE);
1696  last_extent_written += total_size >> 11;
1697  free(directory_buffer);
1698  directory_buffer = NULL;
1699 
1700  if (ce_size > 0) {
1701  if (ce_index != dpnt->ce_bytes) {
1702  errmsgno(EX_BAD,
1703  _("Continuation entry record length mismatch %d expected: %d.\n"),
1704  ce_index, dpnt->ce_bytes);
1705  }
1706  xfwrite(ce_buffer, ce_size, 1, outfile, 0, FALSE);
1707  last_extent_written += ce_size >> 11;
1708  free(ce_buffer);
1709  ce_buffer = NULL;
1710  }
1711 } /* generate_one_directory(... */
1712 
1713 LOCAL void
1715  struct directory *node;
1716 {
1717  struct directory *dpnt;
1718 
1719  dpnt = node;
1720 
1721  while (dpnt) {
1722  /* skip if it's hidden */
1723  if ((dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0)
1724  pathlist[dpnt->path_index] = dpnt;
1725 
1726  if (dpnt->subdir)
1727  build_pathlist(dpnt->subdir);
1728  dpnt = dpnt->next;
1729  }
1730 } /* build_pathlist(... */
1731 
1732 LOCAL int
1734  void const *r;
1735  void const *l;
1736 {
1737  struct directory const *ll = *(struct directory * const *) l;
1738  struct directory const *rr = *(struct directory * const *) r;
1739 
1740  if (rr->parent->path_index < ll->parent->path_index) {
1741  return (-1);
1742  }
1743  if (rr->parent->path_index > ll->parent->path_index) {
1744  return (1);
1745  }
1746  return (strcmp(rr->self->isorec.name, ll->self->isorec.name));
1747 
1748 } /* compare_paths(... */
1749 
1750 LOCAL int
1752 {
1753  struct directory_entry *de = NULL;
1754  struct directory *dpnt;
1755  int fix;
1756  int i;
1757  int j;
1758  int namelen;
1759  char *npnt;
1760  char *npnt1;
1761  int tablesize;
1762 
1763  /* First allocate memory for the tables and initialize the memory */
1764  tablesize = path_blocks << 11;
1765  path_table_m = (char *)e_malloc(tablesize);
1766  path_table_l = (char *)e_malloc(tablesize);
1767  memset(path_table_l, 0, tablesize);
1768  memset(path_table_m, 0, tablesize);
1769 
1770  /*
1771  * Now start filling in the path tables. Start with root directory
1772  */
1773 
1774  path_table_index = 0;
1775  pathlist = (struct directory **)e_malloc(sizeof (struct directory *)
1776  *next_path_index);
1777  memset(pathlist, 0, sizeof (struct directory *) * next_path_index);
1779 
1780  do {
1781  fix = 0;
1782 #ifdef PROTOTYPES
1783  qsort(&pathlist[1], next_path_index - 1,
1784  sizeof (struct directory *),
1785  (int (*) (const void *, const void *)) compare_paths);
1786 #else
1787  qsort(&pathlist[1], next_path_index - 1,
1788  sizeof (struct directory *),
1789  compare_paths);
1790 #endif
1791 
1792  for (j = 1; j < next_path_index; j++) {
1793  if (pathlist[j]->path_index != j) {
1794  pathlist[j]->path_index = j;
1795  fix++;
1796  }
1797  }
1798  } while (fix);
1799 
1800  for (j = 1; j < next_path_index; j++) {
1801  dpnt = pathlist[j];
1802  if (!dpnt) {
1803  comerrno(EX_BAD, _("Entry %d not in path tables\n"), j);
1804  }
1805  npnt = dpnt->de_name;
1806 
1807  /* So the root comes out OK */
1808  if ((*npnt == 0) || (dpnt == root)) {
1809  npnt = ".";
1810  }
1811  npnt1 = strrchr(npnt, PATH_SEPARATOR);
1812  if (npnt1) {
1813  npnt = npnt1 + 1;
1814  }
1815  de = dpnt->self;
1816  if (!de) {
1817  comerrno(EX_BAD,
1818  _("Fatal ISO9660 goof - directory has amnesia\n"));
1819  }
1820  namelen = de->isorec.name_len[0];
1821 
1824  path_table_index += 2;
1825 
1828  path_table_index += 4;
1829 
1831  dpnt->parent->path_index);
1833  dpnt->parent->path_index);
1834 
1835  if (dpnt->parent->path_index > 0xffff) {
1836  static int warned = 0;
1837 
1838  if (!warned) {
1839  warned++;
1840  errmsgno(EX_BAD,
1841  _("Unable to generate sane path tables - too many directories (%u)\n"),
1842  dpnt->parent->path_index);
1843  if (!nolimitpathtables)
1844  errmsgno(EX_BAD,
1845  _("Try to use the option -no-limit-pathtables\n"));
1846  }
1847  if (!nolimitpathtables)
1848  exit(EX_BAD);
1849  /*
1850  * Let it point to the root directory instead.
1851  */
1854  }
1855 
1856  path_table_index += 2;
1857 
1858  for (i = 0; i < namelen; i++) {
1859  path_table_l[path_table_index] = de->isorec.name[i];
1860  path_table_m[path_table_index] = de->isorec.name[i];
1861  path_table_index++;
1862  }
1863  if (path_table_index & 1) {
1864  path_table_index++; /* For odd lengths we pad */
1865  }
1866  }
1867 
1868  free(pathlist);
1869  pathlist = NULL;
1871  errmsgno(EX_BAD,
1872  _("Path table lengths do not match %d expected: %d\n"),
1874  path_table_size);
1875  }
1876  return (0);
1877 } /* generate_path_tables(... */
1878 
1879 EXPORT void
1881  char *to;
1882  char *from;
1883  int max;
1884 {
1885  int n = strlen(from);
1886 
1887  if (n > max) {
1888  n = max;
1889  }
1890  memcpy(to, from, n);
1891 
1892 } /* memcpy_max(... */
1893 
1894 EXPORT void
1896  struct output_fragment *frag;
1897 {
1898  struct output_fragment *nfrag;
1899 
1900  nfrag = e_malloc(sizeof (*frag));
1901  movebytes(frag, nfrag, sizeof (*frag));
1902  nfrag->of_start_extent = 0;
1903 
1904  if (out_tail == NULL) {
1905  out_list = out_tail = nfrag;
1906  } else {
1907  out_tail->of_next = nfrag;
1908  out_tail = nfrag;
1909  }
1910 }
1911 
1912 LOCAL int
1914  FILE *outfile;
1915 {
1916  Uint should_write;
1917 
1918 #ifdef APPLE_HYB
1919  char buffer[SECTOR_SIZE];
1920 
1921  memset(buffer, 0, sizeof (buffer));
1922 
1923  if (apple_hyb && !donotwrite_macpart) {
1924 
1925  int i;
1926 
1927  /*
1928  * write out padding to round up to HFS allocation block
1929  */
1930  for (i = 0; i < hfs_pad; i++)
1931  xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
1932 
1933  last_extent_written += hfs_pad;
1934  }
1935 #endif /* APPLE_HYB */
1936 
1937  /*
1938  * OK, all done with that crap. Now write out the directories. This is
1939  * where the fur starts to fly, because we need to keep track of each
1940  * file as we find it and keep track of where we put it.
1941  */
1942  should_write = last_extent - session_start;
1943 
1944  if (verbose > 2) {
1945 #ifdef DBG_ISO
1946  fprintf(stderr,
1947  _("Total directory extents being written = %u\n"),
1948  last_extent);
1949 #endif
1950 
1951 #ifdef APPLE_HYB
1952  if (apple_hyb && !donotwrite_macpart)
1953  fprintf(stderr,
1954  _("Total extents scheduled to be written (inc HFS) = %u\n"),
1956  else
1957 #endif /* APPLE_HYB */
1958 
1959  fprintf(stderr,
1960  _("Total extents scheduled to be written = %u\n"),
1962  }
1963  /* Now write all of the files that we need. */
1965 
1966 #ifdef APPLE_HYB
1967  /* write out extents/catalog/dt file */
1968  if (apple_hyb && !donotwrite_macpart) {
1969 
1970  xfwrite(hce->hfs_ce, HFS_BLOCKSZ, hce->hfs_tot_size, outfile, 0, FALSE);
1971 
1972  /* round up to a whole CD block */
1973  if (HFS_ROUND_UP(hce->hfs_tot_size) -
1974  hce->hfs_tot_size * HFS_BLOCKSZ) {
1975  xfwrite(buffer,
1976  HFS_ROUND_UP(hce->hfs_tot_size) -
1977  hce->hfs_tot_size * HFS_BLOCKSZ, 1, outfile, 0, FALSE);
1978  }
1979  last_extent_written += ISO_ROUND_UP(hce->hfs_tot_size *
1980  HFS_BLOCKSZ) / SECTOR_SIZE;
1981 
1982  /* write out HFS boot block */
1983  if (mac_boot.name)
1984  write_one_file(mac_boot.name, mac_boot.size, outfile,
1985  mac_boot.off, 0, 0);
1986  }
1987 #endif /* APPLE_HYB */
1988 
1989  /* The rest is just fluff. */
1990  if (verbose == 0) {
1991  return (0);
1992  }
1993 #ifdef APPLE_HYB
1994  if (apple_hyb && !donotwrite_macpart) {
1995  fprintf(stderr,
1996  _("Total extents actually written (inc HFS) = %u\n"),
1998  fprintf(stderr, _("(Size of ISO volume = %d, HFS extra = %d)\n"),
1999  last_extent_written - session_start - hfs_extra,
2000  hfs_extra);
2001  } else
2002 #else
2003  fprintf(stderr, _("Total extents actually written = %d\n"),
2005 #endif /* APPLE_HYB */
2006 
2007  /* Hard links throw us off here */
2008  if (should_write != (last_extent - session_start)) {
2009  fprintf(stderr,
2010  _("Number of extents written not what was predicted. Please fix.\n"));
2011  fprintf(stderr, _("Predicted = %d, written = %d\n"),
2012  should_write, last_extent);
2013  }
2014  fprintf(stderr, _("Total translation table size: %d\n"), table_size);
2015  fprintf(stderr, _("Total rockridge attributes bytes: %d\n"),
2016  rockridge_size);
2017  fprintf(stderr, _("Total directory bytes: %d\n"), total_dir_size);
2018  fprintf(stderr, _("Path table size(bytes): %d\n"), path_table_size);
2019 
2020 #ifdef DEBUG
2021  fprintf(stderr,
2022  "next extent, last_extent, last_extent_written %d %d %d\n",
2024 #endif
2025 
2026  return (0);
2027 
2028 } /* iso_write(... */
2029 
2030 /*
2031  * Function to write the PVD for the disc.
2032  */
2033 LOCAL int
2035  FILE *outfile;
2036 {
2037  char iso_time[17];
2038  int should_write;
2039  int i;
2040  int s;
2041  Uchar *cp;
2042 extern ldate modification_date;
2043 
2044 
2045  iso9660_ldate(iso_time, tv_begun.tv_sec, tv_begun.tv_usec * 1000, -100);
2046 
2047  /* Next we write out the primary descriptor for the disc */
2048  memset(&vol_desc, 0, sizeof (vol_desc));
2049  vol_desc.type[0] = ISO_VD_PRIMARY;
2051  vol_desc.version[0] = 1;
2052 
2053  memset(vol_desc.system_id, ' ', sizeof (vol_desc.system_id));
2055 
2056  memset(vol_desc.volume_id, ' ', sizeof (vol_desc.volume_id));
2058 
2059  should_write = last_extent - session_start;
2060  set_733((char *)vol_desc.volume_space_size, should_write);
2061  set_723(vol_desc.volume_set_size, volume_set_size);
2062  set_723(vol_desc.volume_sequence_number, volume_sequence_number);
2063  set_723(vol_desc.logical_block_size, SECTOR_SIZE);
2064 
2065  /*
2066  * The path tables are used by DOS based machines to cache directory
2067  * locations
2068  */
2069  set_733((char *)vol_desc.path_table_size, path_table_size);
2070  set_731(vol_desc.type_l_path_table, path_table[0]);
2071  set_731(vol_desc.opt_type_l_path_table, path_table[1]);
2072  set_732(vol_desc.type_m_path_table, path_table[2]);
2073  set_732(vol_desc.opt_type_m_path_table, path_table[3]);
2074 
2075  /* Now we copy the actual root directory record */
2076  memcpy(vol_desc.root_directory_record, &root_record,
2077  offsetof(struct iso_directory_record, name[0]) + 1);
2078 
2079  /*
2080  * The rest is just fluff. It looks nice to fill in many of these
2081  * fields, though.
2082  */
2083  FILL_SPACE(volume_set_id);
2084  if (volset_id)
2085  memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id));
2086 
2087  FILL_SPACE(publisher_id);
2088  if (publisher)
2089  memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher));
2090 
2091  FILL_SPACE(preparer_id);
2092  if (preparer)
2093  memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer));
2094 
2095  FILL_SPACE(application_id);
2096  if (appid)
2097  memcpy_max(vol_desc.application_id, appid, strlen(appid));
2098 
2099  FILL_SPACE(copyright_file_id);
2100  if (copyright)
2101  memcpy_max(vol_desc.copyright_file_id, copyright,
2102  strlen(copyright));
2103 
2104  FILL_SPACE(abstract_file_id);
2105  if (abstract)
2106  memcpy_max(vol_desc.abstract_file_id, abstract,
2107  strlen(abstract));
2108 
2109  FILL_SPACE(bibliographic_file_id);
2110  if (biblio)
2111  memcpy_max(vol_desc.bibliographic_file_id, biblio,
2112  strlen(biblio));
2113 
2114  FILL_SPACE(creation_date);
2116  FILL_SPACE(expiration_date);
2117  FILL_SPACE(effective_date);
2118  vol_desc.file_structure_version[0] = 1;
2119  FILL_SPACE(application_data);
2120 
2121  iso9660_ldate(vol_desc.modification_date,
2123  modification_date.l_usec * 1000,
2125 
2126  memcpy(vol_desc.creation_date, iso_time, 17);
2127  memcpy(vol_desc.expiration_date, "0000000000000000", 17);
2128  memcpy(vol_desc.effective_date, iso_time, 17);
2129 
2130  if (use_XA) {
2131  char *xap = &((char *)&vol_desc)[1024];
2132 
2133  memcpy(&xap[0], "CD-XA001", 8); /* XA Sign. */
2134  memcpy(&xap[8], "\0\0", 2); /* XA flags */
2135  memcpy(&xap[10], "\0\0\0\0\0\0\0\0", 8); /* Start dir */
2136  memcpy(&xap[18], "\0\0\0\0\0\0\0\0", 8); /* Reserved */
2137  }
2138 
2139  /*
2140  * Compute a checksum to be used as a fingerprint in case we
2141  * include correct inode/link-count information in the current image.
2142  */
2143  for (i = 0, s = 0, cp = (Uchar *)&vol_desc; i < SECTOR_SIZE; i++) {
2144  s += cp[i] & 0xFF;
2145  }
2146  vol_desc_sum = s;
2147 
2148  /* if not a bootable cd do it the old way */
2151  return (0);
2152 }
2153 
2154 /*
2155  * Function to write the Extended PVD for the disc.
2156  */
2157 LOCAL int
2159  FILE *outfile;
2160 {
2161  vol_desc.type[0] = ISO_VD_SUPPLEMENTARY;
2162  vol_desc.version[0] = 2;
2163  vol_desc.file_structure_version[0] = 2;
2164 
2165  /* if not a bootable cd do it the old way */
2168  return (0);
2169 }
2170 
2171 /*
2172  * Function to write the EVD for the disc.
2173  */
2174 LOCAL int
2176  FILE *outfile;
2177 {
2178  struct iso_primary_descriptor evol_desc;
2179 
2180  /*
2181  * Now write the end volume descriptor. Much simpler than the other
2182  * one
2183  */
2184  memset(&evol_desc, 0, sizeof (evol_desc));
2185  evol_desc.type[0] = (unsigned char) ISO_VD_END;
2186  strncpy(evol_desc.id, ISO_STANDARD_ID, sizeof (evol_desc.id));
2187  evol_desc.version[0] = 1;
2188  xfwrite(&evol_desc, SECTOR_SIZE, 1, outfile, 0, TRUE);
2189  last_extent_written += 1;
2190  return (0);
2191 }
2192 
2193 /*
2194  * Function to write the version information for the disc.
2195  * Warning: Do not disable or change this function. The data created by this
2196  * function is used to tell the filesystem driver in the OS kernel that this
2197  * mkisofs version includes correct inode information.
2198  */
2199 LOCAL int
2201  FILE *outfile;
2202 {
2203  char vers[SECTOR_SIZE+1];
2204  int X_ac;
2205  char **X_av;
2206  char *cp;
2207  int i;
2208  int idx = 4;
2209  int len;
2210  extern char version_string[];
2211  extern int path_ind;
2212 
2213  /* Now write the version descriptor. */
2214  memset(vers, 0, sizeof (vers));
2215  strcpy(vers, "MKI "); /* strcpy() OK here */
2216 
2217  cp = vers;
2218  X_ac = saved_ac();
2219  X_av = saved_av();
2220  strlcpy(&cp[idx], ctime(&begun), 26);
2221  idx += 25;
2224  for (i = 1; i < X_ac; i++) {
2225  len = strlen(X_av[i]);
2226  if ((idx + len + 2) >= SECTOR_SIZE)
2227  break;
2228  cp[idx++] = ' ';
2229  /*
2230  * Do not give away secret information when not in debug mode.
2231  */
2232  if (debug)
2233  strlcpy(&cp[idx], X_av[i], SECTOR_SIZE - idx);
2234  else if (i >= path_ind)
2235  len = graftcp(&cp[idx], X_av[i], &vers[SECTOR_SIZE-1]);
2236  else if (X_av[i][0] == '/')
2237  len = pathcp(&cp[idx], X_av[i], &vers[SECTOR_SIZE-1]);
2238  else
2239  strlcpy(&cp[idx], X_av[i], SECTOR_SIZE - idx);
2240  idx += len;
2241  }
2242 
2243  cp[SECTOR_SIZE - 1] = '\0';
2244  len = 0;
2245  if (correct_inodes) {
2246  /*
2247  * Only add this fingerprint in case we include correct
2248  * inode/link-count information in the current image.
2249  */
2250  len = vol_desc_sum;
2251  }
2252  cp = &vers[SECTOR_SIZE - 1];
2253  *(Uchar *)cp = len % 256;
2254  len /= 256;
2255  *(Uchar *)--cp = len % 256;
2256  len /= 256;
2257  *(Uchar *)--cp = len % 256;
2258 
2259  xfwrite(vers, SECTOR_SIZE, 1, outfile, 0, TRUE);
2260  last_extent_written += 1;
2261  return (0);
2262 }
2263 
2264 /*
2265  * Avoid to write unwanted information into the version info string.
2266  */
2267 LOCAL int
2268 graftcp(to, from, ep)
2269  char *to;
2270  char *from;
2271  char *ep;
2272 {
2273  int len = strlen(from);
2274  char *node = NULL;
2275 
2276  if (use_graft_ptrs)
2277  node = findgequal(from);
2278 
2279  if (node == NULL) {
2280  len = 0;
2281  node = from;
2282  } else {
2283  len = node - from;
2284  *node = '\0';
2285  strncpy(to, from, ep - to);
2286  *node++ = '=';
2287  to += len++;
2288  *to++ = '=';
2289  }
2290  return (len + pathcp(to, node, ep));
2291 }
2292 
2293 LOCAL int
2294 pathcp(to, from, ep)
2295  char *to;
2296  char *from;
2297  char *ep;
2298 {
2299  int len = strlen(from);
2300  char *p;
2301 
2302  p = strrchr(from, '/');
2303  if (p == NULL) {
2304  strncpy(to, from, ep - to);
2305  } else {
2306  if (p[1] == '\0') {
2307  --p;
2308  while (p > from && *p != '/')
2309  --p;
2310  }
2311  len = 0;
2312  if (*p == '/') {
2313  strncpy(to, "...", ep - to);
2314  to += 3;
2315  len = 3;
2316  }
2317  if (to < ep) {
2318  strncpy(to, p, ep - to);
2319  len += strlen(to);
2320  }
2321  }
2322  return (len);
2323 }
2324 
2325 
2326 /*
2327  * Function to write the path table for the disc.
2328  */
2329 LOCAL int
2331  FILE *outfile;
2332 {
2333  /* Next we write the path tables */
2334  xfwrite(path_table_l, path_blocks << 11, 1, outfile, 0, FALSE);
2335  xfwrite(path_table_m, path_blocks << 11, 1, outfile, 0, FALSE);
2337  free(path_table_l);
2338  free(path_table_m);
2339  path_table_l = NULL;
2340  path_table_m = NULL;
2341  return (0);
2342 }
2343 
2344 LOCAL int
2346  FILE *outfile;
2347 {
2350  return (0);
2351 }
2352 
2353 /*
2354  * Functions to describe padding block at the start of the disc.
2355  */
2356 EXPORT int
2357 oneblock_size(starting_extent)
2358  UInt32_t starting_extent;
2359 {
2360  last_extent++;
2361  return (0);
2362 }
2363 
2364 /*
2365  * Functions to describe path table size.
2366  */
2367 LOCAL int
2368 pathtab_size(starting_extent)
2369  UInt32_t starting_extent;
2370 {
2371  path_table[0] = starting_extent;
2372 
2373  path_table[1] = 0;
2374  path_table[2] = path_table[0] + path_blocks;
2375  path_table[3] = 0;
2376  last_extent += 2 * path_blocks;
2377  return (0);
2378 }
2379 
2380 /*
2381  * Functions to describe padding blocks before PVD.
2382  */
2383 LOCAL int
2384 startpad_size(starting_extent)
2385  UInt32_t starting_extent;
2386 {
2387  last_extent = session_start + 16;
2388  return (0);
2389 }
2390 
2391 /*
2392  * Functions to describe padding blocks between sections.
2393  */
2394 LOCAL int
2395 interpad_size(starting_extent)
2396  UInt32_t starting_extent;
2397 {
2398  int emod = 0;
2399 
2400 #ifdef needed
2401  starting_extent += 16; /* First add 16 pad blocks */
2402 #endif
2403  if ((emod = starting_extent % 16) != 0) {
2404  starting_extent += 16 - emod; /* Now pad to mod 16 # */
2405  }
2406  last_extent = starting_extent;
2407  return (0);
2408 }
2409 
2410 /*
2411  * Functions to describe padding blocks at end of disk.
2412  */
2413 LOCAL int
2414 endpad_size(starting_extent)
2415  UInt32_t starting_extent;
2416 {
2417  starting_extent += 150; /* 150 pad blocks (post gap) */
2418  last_extent = starting_extent;
2419  return (0);
2420 }
2421 
2422 LOCAL int
2424 {
2425 #ifdef APPLE_HYB
2426  UInt32_t start_extent = last_extent; /* orig ISO files start */
2427 
2428 #endif /* APPLE_HYB */
2429 
2430  if (!assign_file_addresses(root, FALSE)) {
2431 #ifdef DVD_AUD_VID
2432  if (dvd_aud_vid_flag & DVD_SPEC_VIDEO) {
2433  comerrno(EX_BAD, _("Unable to make a DVD-Video image.\n"));
2434  }
2435 #else
2436  ;
2437  /* EMPTY */
2438 #endif
2439  }
2440 
2441 
2442 #ifdef SORTING
2443  if (do_sort) {
2444  if (sort_file_addresses() == 0)
2445  reassign_link_addresses(root);
2446  }
2447 #endif /* SORTING */
2448 
2449 #ifdef APPLE_HYB
2450  /*
2451  * put this here for the time being - may when I've worked out how to
2452  * use Eric's new system for creating/writing parts of the image it
2453  * may move to it's own routine
2454  */
2455  if (apple_hyb && !donotwrite_macpart)
2456  hfs_file_gen(start_extent);
2457 #ifdef PREP_BOOT
2458  else if (use_prep_boot || use_chrp_boot)
2459  gen_prepboot();
2460 #endif /* PREP_BOOT */
2461 #endif /* APPLE_HYB */
2462 
2463  /*
2464  * Do inode/hard link related stuff for non-directory type files.
2465  */
2466  do_inode(root);
2467  return (0);
2468 }
2469 
2470 LOCAL int
2472 {
2473  if (verbose > 2) {
2474  dump_tree(root);
2475  }
2476  return (0);
2477 }
2478 
2479 LOCAL int
2480 dirtree_fixup(starting_extent)
2481  UInt32_t starting_extent;
2482 {
2483  if (use_RockRidge && reloc_dir)
2485 
2486  /*
2487  * Set the link count for directories to 2 + number of sub-directories.
2488  */
2489  if (use_RockRidge)
2490  do_dir_nlink(root);
2491  return (0);
2492 }
2493 
2494 LOCAL int
2495 dirtree_size(starting_extent)
2496  UInt32_t starting_extent;
2497 {
2499  return (0);
2500 }
2501 
2502 LOCAL int
2503 ext_size(starting_extent)
2504  UInt32_t starting_extent;
2505 {
2506  extern int extension_record_size;
2507  struct directory_entry *s_entry;
2508 
2509  extension_record_extent = starting_extent;
2510  s_entry = root->contents;
2511  set_733((char *)s_entry->rr_attributes + s_entry->rr_attr_size - 24,
2513  set_733((char *)s_entry->rr_attributes + s_entry->rr_attr_size - 8,
2515  last_extent++;
2516  return (0);
2517 }
2518 
2519 LOCAL int
2521  FILE *outfile;
2522 {
2524  return (0);
2525 }
2526 
2527 LOCAL int
2529  FILE *outfile;
2530 {
2532  return (0);
2533 }
2534 
2535 LOCAL int
2537  FILE *outfile;
2538 {
2539  char buffer[SECTOR_SIZE];
2540  int i;
2541  int npad;
2542 
2543  memset(buffer, 0, sizeof (buffer));
2544 
2545  npad = session_start + 16 - last_extent_written;
2546 
2547  for (i = 0; i < npad; i++) {
2548  xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
2549  }
2550 
2551  last_extent_written += npad;
2552  return (0);
2553 }
2554 
2555 LOCAL int
2557  FILE *outfile;
2558 {
2559  char buffer[SECTOR_SIZE];
2560  int i;
2561  int npad = 0;
2562 
2563  memset(buffer, 0, sizeof (buffer));
2564 
2565 #ifdef needed
2566  npad = 16;
2567 #endif
2568  if ((i = last_extent_written % 16) != 0)
2569  npad += 16 - i;
2570 
2571  for (i = 0; i < npad; i++) {
2572  xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
2573  }
2574 
2575  last_extent_written += npad;
2576  return (0);
2577 }
2578 
2579 LOCAL int
2581  FILE *outfile;
2582 {
2583  char buffer[SECTOR_SIZE];
2584  int i;
2585 
2586  memset(buffer, 0, sizeof (buffer));
2587 
2588  for (i = 0; i < 150; i++) {
2589  xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE);
2590  }
2591 
2592  last_extent_written += 150;
2593  return (0);
2594 }
2595 
2596 #ifdef APPLE_HYB
2597 
2598 /*
2599  * hfs_get_parms: get HFS parameters from the command line
2600  */
2601 
2602 LOCAL int
2603 hfs_get_parms(key)
2604  char *key;
2605 {
2606  int ret = 0;
2607  char *p;
2608 
2609  if (hfs_parms == NULL)
2610  return (ret);
2611 
2612  if ((p = strstr(hfs_parms, key)) != NULL) {
2613  p += strlen(key) + 1;
2614  sscanf(p, "%d", &ret);
2615  }
2616 
2617  return (ret);
2618 }
2619 
2620 /*
2621  * hfs_file_gen: set up "fake" HFS volume using the ISO9660 tree
2622  */
2623 LOCAL void
2624 hfs_file_gen(start_extent)
2625  UInt32_t start_extent;
2626 {
2627  int Csize; /* clump size for HFS vol */
2628  int loop;
2629  UInt32_t last_extent_save = last_extent;
2630  char *p;
2631 
2632  /* allocate memory for the libhfs/mkisofs extra info */
2633  hce = (hce_mem *) e_malloc(sizeof (hce_mem));
2634 
2635  hce->error = (char *)e_malloc(1024);
2636 
2637  /* mark as unallocated for use later */
2638  hce->hfs_ce = hce->hfs_hdr = hce->hfs_map = 0;
2639 
2640  /* reserve space for the label partition - if it is needed */
2641 #ifdef PREP_BOOT
2642  /* a PReP bootable partition needs the map.. */
2643  if (gen_pt || use_prep_boot || use_chrp_boot)
2644 #else
2645  if (gen_pt)
2646 #endif /* PREP_BOOT */
2647  hce->hfs_map_size = HFS_MAP_SIZE;
2648  else
2649  hce->hfs_map_size = 0;
2650 
2651  /* set the HFS parameter string to upper case */
2652  if (hfs_parms) {
2653  for (p = hfs_parms; *p; p++)
2654  *p = toupper((*p & 0xFF));
2655  }
2656 
2657  /* set the initial factor to increase Catalog file size */
2658  if ((hce->ctc_size = hfs_get_parms("CTC")) == 0)
2659  hce->ctc_size = CTC;
2660 
2661  /* set the max size of the Catalog file */
2662  if ((hce->max_XTCsize = hfs_get_parms("MAX_XTCSIZE")) == 0)
2663  hce->max_XTCsize = MAX_XTCSIZE;
2664 
2665  /* set the number of time to try to make an HFS volume */
2666  if ((loop = hfs_get_parms("CTC_LOOP")) == 0)
2667  loop = CTC_LOOP;
2668 
2669  /*
2670  * "create" the HFS volume (just the header, catalog/extents files) if
2671  * there's a problem with the Catalog file being too small, we keep on
2672  * increasing the size (up to CTC_LOOP) times and try again.
2673  * Unfortunately I don't know enough about the inner workings of HFS,
2674  * so I can't workout the size of the Catalog file in advance (and I
2675  * don't want to "grow" as is is normally allowed to), therefore, this
2676  * approach is a bit over the top as it involves throwing away the
2677  * "volume" we have created and trying again ...
2678  */
2679  do {
2680  hce->error[0] = '\0';
2681 
2682  /* attempt to create the Mac volume */
2683 #ifdef APPLE_HFS_HYB
2684  Csize = make_mac_volume(root, start_extent);
2685 #else
2686  Csize = -1;
2687 #endif
2688 
2689  /* if we have a problem ... */
2690  if (Csize < 0) {
2691  /*
2692  * we've made too many attempts, or got some other
2693  * error
2694  */
2695  if (loop == 0 || errno != HCE_ERROR) {
2696  /* HCE_ERROR is not a valid errno value */
2697  if (errno == HCE_ERROR)
2698  errno = 0;
2699 
2700  /* exit with the error */
2701  if (*hce->error)
2702  fprintf(stderr, "%s\n", hce->error);
2703  perr(hfs_error);
2704  } else {
2705  /* increase Catalog file size factor */
2706  hce->ctc_size *= CTC;
2707 
2708  /*
2709  * reset the initial "last_extent" and try
2710  * again
2711  */
2712  last_extent = last_extent_save;
2713  }
2714  } else {
2715  /* everything OK - just carry on ... */
2716  loop = 0;
2717  }
2718  }
2719  while (loop--);
2720 
2721  hfs_extra = HFS_ROUND_UP(hce->hfs_tot_size) / SECTOR_SIZE;
2722 
2723  last_extent += hfs_extra;
2724 
2725  /* generate the Mac label and HFS partition maps */
2726  mac_boot.name = hfs_boot_file;
2727 
2728  /*
2729  * only generate the partition tables etc. if we are making a bootable
2730  * CD - or if the -part option is given
2731  */
2732  if (gen_pt) {
2733  if (gen_mac_label(&mac_boot)) {
2734  if (*hce->error)
2735  fprintf(stderr, "%s\n", hce->error);
2736  perr(hfs_error);
2737  }
2738  }
2739  /* set Autostart filename if required */
2740  if (autoname) {
2741  if (autostart())
2742  perr("Autostart filename must less than 12 characters");
2743  }
2744  /* finished with any HFS type errors */
2745  free(hce->error);
2746  hce->error = 0;
2747 
2748  /*
2749  * the ISO files need to start on a multiple of the HFS allocation
2750  * blocks, so find out how much padding we need
2751  */
2752 
2753  /*
2754  * take in accout alignment of files wrt HFS volume start - remove any
2755  * previous session as well
2756  */
2757  start_extent -= session_start;
2758  hfs_pad = ROUND_UP(start_extent*SECTOR_SIZE +
2759  (hce->hfs_hdr_size + hce->hfs_map_size) * HFS_BLOCKSZ,
2760  Csize) / SECTOR_SIZE;
2761 
2762  hfs_pad -= (start_extent + (hce->hfs_hdr_size + hce->hfs_map_size) /
2763  HFS_BLK_CONV);
2764 
2765 #ifdef PREP_BOOT
2766  gen_prepboot_label(hce->hfs_map);
2767 #endif /* PREP_BOOT */
2768 
2769 }
2770 
2771 #ifdef PREP_BOOT
2772 LOCAL void
2773 gen_prepboot()
2774 {
2775  /*
2776  * we need to allocate the hce struct since hce->hfs_map is used to
2777  * generate the fdisk partition map required for PReP booting
2778  */
2779  hce = (hce_mem *) e_malloc(sizeof (hce_mem));
2780 
2781  /* mark as unallocated for use later */
2782  hce->hfs_ce = hce->hfs_hdr = hce->hfs_map = 0;
2783 
2784  /* reserve space for the label partition - if it is needed */
2785  hce->hfs_map_size = HFS_MAP_SIZE;
2786 
2787  hce->hfs_map = (unsigned char *) e_malloc(hce->hfs_map_size * HFS_BLOCKSZ);
2788  gen_prepboot_label(hce->hfs_map);
2789 }
2790 
2791 #endif /* PREP_BOOT */
2792 
2793 /*
2794  * get_adj_size: get the ajusted size of the volume with the HFS
2795  * allocation block size for each file
2796  */
2797 EXPORT Ulong
2798 get_adj_size(Csize)
2799  int Csize;
2800 {
2801  struct deferred_write *dw;
2802  Ulong size = 0;
2803  int count = 0;
2804 
2805  /* loop through all the files finding the new total size */
2806  for (dw = dw_head; dw; dw = dw->next) {
2807  size += (ROUND_UP(dw->size, Csize)/HFS_BLOCKSZ);
2808  count++;
2809  }
2810 
2811  /*
2812  * crude attempt to prevent overflows - HFS can only cope with a
2813  * maximum of about 65536 forks (actually less) - this will trap cases
2814  * when we have far too many files
2815  */
2816 
2817  if (count >= 65536)
2818  return (-1);
2819  else
2820  return (size);
2821 }
2822 
2823 /*
2824  * adj_size: adjust the ISO record entries for all files
2825  * based on the HFS allocation block size
2826  */
2827 EXPORT int
2828 adj_size(Csize, start_extent, extra)
2829  int Csize;
2830  UInt32_t start_extent;
2831  int extra;
2832 {
2833  struct deferred_write *dw;
2834  struct directory_entry *s_entry;
2835  int size;
2836 
2837  /* get the adjusted start_extent (with padding) */
2838  /* take in accout alignment of files wrt HFS volume start */
2839 
2840  start_extent -= session_start;
2841 
2842  start_extent = ROUND_UP(start_extent*SECTOR_SIZE + extra*HFS_BLOCKSZ,
2843  Csize) / SECTOR_SIZE;
2844 
2845  start_extent -= (extra / HFS_BLK_CONV);
2846 
2847  start_extent += session_start;
2848 
2849  /* initialise file hash */
2850  flush_hash();
2851 
2852  /*
2853  * loop through all files changing their starting blocks and finding
2854  * any padding needed to written out latter
2855  */
2856  for (dw = dw_head; dw; dw = dw->next) {
2857  s_entry = dw->s_entry;
2858  s_entry->starting_block = dw->extent = start_extent;
2859  set_733((char *)s_entry->isorec.extent, start_extent);
2860  size = ROUND_UP(dw->size, Csize) / SECTOR_SIZE;
2861  dw->pad = size - ISO_ROUND_UP(dw->size) / SECTOR_SIZE;
2862 
2863  /*
2864  * cache non-HFS files - as there may be multiple links to
2865  * these files (HFS files can't have multiple links). We will
2866  * need to change the starting extent of the other links later
2867  */
2868  if (!s_entry->hfs_ent)
2869  add_hash(s_entry);
2870 
2871  start_extent += size;
2872  }
2873 
2874  return (start_extent);
2875 }
2876 
2877 /*
2878  * adj_size_other: adjust any non-HFS files that may be linked
2879  * to an existing file (i.e. not have a deferred_write
2880  * entry of it's own
2881  */
2882 EXPORT void
2883 adj_size_other(dpnt)
2884  struct directory *dpnt;
2885 {
2886  struct directory_entry *s_entry;
2887  struct file_hash *s_hash;
2888 
2889  while (dpnt) {
2890  s_entry = dpnt->contents;
2891  for (s_entry = dpnt->contents; s_entry;
2892  s_entry = s_entry->next) {
2893  /*
2894  * if it's an HFS file or a directory - then ignore
2895  * (we're after non-HFS files)
2896  */
2897  if (s_entry->hfs_ent ||
2898  (s_entry->isorec.flags[0] & ISO_DIRECTORY))
2899  continue;
2900 
2901  /*
2902  * find any cached entry and assign new starting
2903  * extent
2904  */
2905  s_hash = find_hash(s_entry);
2906  if (s_hash) {
2907  set_733((char *)s_entry->isorec.extent,
2908  s_hash->starting_block);
2909  /* not vital - but tidy */
2910  s_entry->starting_block =
2911  s_hash->starting_block;
2912  }
2913  }
2914  if (dpnt->subdir) {
2915  adj_size_other(dpnt->subdir);
2916  }
2917  dpnt = dpnt->next;
2918  }
2919 
2920  /* clear file hash */
2921  flush_hash();
2922 }
2923 
2924 /*
2925  * hfs_hce_write: write out the HFS header stuff
2926  */
2927 LOCAL int
2928 hfs_hce_write(outfile)
2929  FILE *outfile;
2930 {
2931  char buffer[SECTOR_SIZE];
2932  int n = 0;
2933  int r; /* HFS hdr output */
2934  int tot_size = hce->hfs_map_size + hce->hfs_hdr_size;
2935 
2936  memset(buffer, 0, sizeof (buffer));
2937 
2938  /*
2939  * hack time ... if the tot_size is greater than 32Kb then
2940  * it won't fit in the first 16 blank SECTORS (64 512 byte
2941  * blocks, as most of this is padding, we just truncate this
2942  * data to 64x4xHFS_BLOCKSZ ... hope this is OK ...
2943  */
2944 
2945  if (tot_size > 64) tot_size = 64;
2946 
2947  /* get size in CD blocks == 4xHFS_BLOCKSZ == 2048 */
2948  n = tot_size / HFS_BLK_CONV;
2949  r = tot_size % HFS_BLK_CONV;
2950 
2951  /* write out HFS volume header info */
2952  xfwrite(hce->hfs_map, HFS_BLOCKSZ, tot_size, outfile, 0, FALSE);
2953 
2954  /* fill up to a complete CD block */
2955  if (r) {
2956  xfwrite(buffer, HFS_BLOCKSZ, HFS_BLK_CONV - r, outfile, 0, FALSE);
2957  n++;
2958  }
2960  return (0);
2961 }
2962 
2963 /*
2964  * insert_padding_file : insert a dumy file to make volume at least
2965  * 800k
2966  *
2967  * XXX If we ever need to write more then 2 GB, make size off_t
2968  */
2969 EXPORT int
2970 insert_padding_file(size)
2971  int size;
2972 {
2973  struct deferred_write *dwpnt;
2974 
2975  /* get the size in bytes */
2976  size *= HFS_BLOCKSZ;
2977 
2978  dwpnt = (struct deferred_write *)
2979  e_malloc(sizeof (struct deferred_write));
2980  dwpnt->s_entry = 0;
2981  /* set the padding to zero */
2982  dwpnt->pad = 0;
2983  /* set offset to zero */
2984  dwpnt->off = (off_t)0;
2985  dwpnt->dw_flags = 0;
2986 #ifdef APPLE_HYB
2987  dwpnt->hfstype = TYPE_NONE;
2988 #endif
2989 
2990  /*
2991  * don't need to wory about the s_entry stuff as it won't be touched#
2992  * at this point onwards
2993  */
2994 
2995  /* insert the entry in the list */
2996  if (dw_tail) {
2997  dw_tail->next = dwpnt;
2998  dw_tail = dwpnt;
2999  } else {
3000  dw_head = dwpnt;
3001  dw_tail = dwpnt;
3002  }
3003 
3004  /* aloocate memory as a "Table" file */
3005  dwpnt->table = e_malloc(size);
3006  dwpnt->name = NULL;
3007 
3008  dwpnt->next = NULL;
3009  dwpnt->size = size;
3010  dwpnt->extent = last_extent;
3012 
3013  /* retune the size in HFS blocks */
3014  return (ISO_ROUND_UP(size) / HFS_BLOCKSZ);
3015 }
3016 
3017 struct output_fragment hfs_desc = {NULL, NULL, NULL, hfs_hce_write, "HFS volume header"};
3018 
3019 #endif /* APPLE_HYB */
3020 
3022 struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write, "Primary Volume Descriptor"};
3023 struct output_fragment xvoldesc_desc = {NULL, oneblock_size, NULL, xpvd_write, "Enhanced Volume Descriptor"};
3024 struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write, "End Volume Descriptor" };
3029 struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write, "Extension record" };
3031 struct output_fragment interpad_desc = {NULL, interpad_size, NULL, interpad_write, "Intermediate Padblock"};
return TRUE
Definition: write.c:2909
unsigned int extent
Definition: mkisofs.h:299
char version[ISODCL(7, 7)]
Definition: iso9660.h:67
unsigned int path_blocks
Definition: mkisofs.c:80
char * name
Definition: wpp.c:36
Uchar sub_mode
Definition: iso9660.h:360
unsigned int de_flags
Definition: mkisofs.h:122
unsigned int starting_block
Definition: mkisofs.h:161
EXPORT void set_732(void *vp, UInt32_t i)
Definition: isonum.c:108
char * whole_name
Definition: mkisofs.h:273
struct deferred_write * next
Definition: mkisofs.h:297
char * name
Definition: mkisofs.h:301
#define max(a, b)
Definition: svc.c:63
#define frac(x)
Definition: texture.c:364
int split_output
Definition: mkisofs.c:156
EXPORT int saved_ac()
Definition: saveargs.c:96
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
LOCAL int pvd_write(FILE *outfile)
Definition: write.c:2034
EXPORT void comerr(char *msg, va_alist)
Definition: comerr.c:84
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
LOCAL int exten_write(FILE *outfile)
Definition: write.c:2345
EXPORT void outputlist_insert(struct output_fragment *frag)
Definition: write.c:1895
struct output_fragment extension_desc
Definition: write.c:3029
#define error(str)
Definition: mkdosfs.c:1605
unsigned char Uchar
Definition: utypes.h:45
_In_ fcb _In_ chunk _In_ UINT64 _In_ UINT64 _In_ BOOL _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ UINT8 _In_ UINT64 _In_ BOOL file_write
Definition: write.c:2822
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
Definition: mkisofs.h:107
LOCAL int interpad_size(UInt32_t starting_extent)
Definition: write.c:2395
long Llong
Definition: stdint.h:152
#define MULTI_EXTENT
Definition: mkisofs.h:808
char copyright[]
Definition: main.c:27
EXPORT int oneblock_size(UInt32_t starting_extent)
Definition: write.c:2357
char * extension_record
Definition: mkisofs.c:90
#define FILL_SPACE(X)
Definition: write.c:165
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DWORD path_table_size
Definition: cdmake.c:202
#define ISO_VD_SUPPLEMENTARY
Definition: iso9660.h:44
EXPORT char ** saved_av()
Definition: saveargs.c:105
unsigned int size
Definition: mkisofs.h:279
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
EXPORT void xfwrite(void *buffer, int size, int count, FILE *file, int submode, BOOL islast)
Definition: write.c:168
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
EXPORT void do_dir_nlink(struct directory *dpnt)
Definition: inode.c:85
EXPORT void set_721(void *vp, UInt32_t i)
Definition: isonum.c:46
unsigned int starting_block
Definition: mkisofs.h:111
GLuint GLuint GLsizei count
Definition: gl.h:1545
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
EXPORT struct timeval tv_begun
Definition: write.c:306
#define SPATH_SEPARATOR
Definition: mkisofs.h:787
#define free
Definition: debug_ros.c:5
char * path_table_m
Definition: mkisofs.c:1632
__kernel_off_t off_t
Definition: linux.h:201
size_t strlcpy(char *d, const char *s, size_t bufsize)
Definition: compat.c:3
#define E_GROW
Definition: checkerr.h:51
#define UConst
Definition: ccomdefs.h:72
GLdouble n
Definition: glext.h:7729
LOCAL int evd_write(FILE *outfile)
Definition: write.c:2175
#define unlink
Definition: syshdrs.h:54
EXPORT void set_722(void *vp, UInt32_t i)
Definition: isonum.c:61
#define PATH_SEPARATOR
Definition: xmllint.c:210
static FILE * infile
Definition: rdjpgcom.c:65
char id[ISODCL(2, 6)]
Definition: iso9660.h:66
GLuint buffer
Definition: glext.h:5915
char * biblio
Definition: mkisofs.c:163
LOCAL struct directory ** pathlist
Definition: write.c:68
LOCAL int generate_path_tables()
Definition: write.c:1751
int donotwrite_macpart
Definition: mkisofs.c:298
LOCAL Uint path_table_index
Definition: write.c:304
LOCAL void write_one_file(char *filename, off_t size, FILE *outfile)
Definition: write.c:367
LOCAL int file_gen()
Definition: write.c:2423
LOCAL int total_dir_size
Definition: write.c:66
static FILE * outfile
Definition: wrjpgcom.c:81
int errno
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
__u16 time
Definition: mkdosfs.c:366
EXPORT char * e_strdup(char *s) const
Definition: mkisofs.c:3941
EXPORT void set_731(void *vp, UInt32_t i)
Definition: isonum.c:91
char *abstract char * volset_id
Definition: mkisofs.c:165
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
LOCAL void write_files(FILE *outfile)
Definition: write.c:572
#define XA_SUBH_DATA
Definition: iso9660.h:370
const char * filename
Definition: ioapi.h:135
GLint namelen
Definition: glext.h:7232
#define ISO_STANDARD_ID
Definition: iso9660.h:47
#define TABLE_INODE
Definition: mkisofs.h:763
unsigned int ce_bytes
Definition: mkisofs.h:276
char * publisher
Definition: mkisofs.c:160
LOCAL int endpad_size(UInt32_t starting_extent)
Definition: write.c:2414
unsigned int Uint
Definition: utypes.h:43
struct output_fragment * out_tail
Definition: write.c:74
LOCAL int startpad_write(FILE *outfile)
Definition: write.c:2536
char * name
Definition: mkisofs.h:116
ed2 size
Definition: write.c:2852
struct directory * subdir
Definition: mkisofs.h:268
int mxpart
Definition: mkisofs.h:113
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define verbose
Definition: rosglue.h:36
unsigned int extent
Definition: mkisofs.h:280
struct node node
char type[ISODCL(1, 1)]
Definition: iso9660.h:65
UInt32_t extension_record_extent
Definition: mkisofs.c:91
struct directory * parent
Definition: mkisofs.h:269
EXPORT struct file_hash * find_hash(struct directory_entry *spnt)
Definition: hash.c:192
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
#define dvd_aud_vid_flag
int extension_record_size
Definition: mkisofs.c:92
LOCAL int dirtree_cleanup(FILE *outfile)
Definition: write.c:2528
#define _(X)
Definition: i386-dis.c:36
#define SECTOR_SIZE
Definition: winldr.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
time_t now
Definition: finger.c:65
char * table
Definition: mkisofs.h:298
LOCAL BOOL assign_file_addresses(struct directory *dpnt, BOOL isnest)
Definition: write.c:1082
struct iso_directory_record isorec
Definition: mkisofs.h:110
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
__u8 volume_id[4]
Definition: mkdosfs.c:361
unsigned int idx
Definition: utils.c:41
#define IS_SYMLINK
Definition: mkisofs.h:807
UInt32_t last_extent
Definition: mkisofs.c:76
char * appid
Definition: mkisofs.c:161
struct output_fragment version_desc
Definition: write.c:3025
LOCAL int is_rr_dir
Definition: write.c:72
struct output_fragment voldesc_desc
Definition: write.c:3022
EXPORT UInt32_t get_733(void *vp)
Definition: isonum.c:219
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
char ext[3]
Definition: mkdosfs.c:358
unsigned char
Definition: typeof.h:29
EXPORT int errmsg(char *msg, va_alist)
Definition: comerr.c:192
unsigned int of_start_extent
Definition: mkisofs.h:196
char * whole_name
Definition: mkisofs.h:118
struct output_fragment dirtree_desc
Definition: write.c:3027
EXPORT int iso9660_date(char *result, time_t crtime)
Definition: mkisofs.c:1868
struct output_fragment xvoldesc_desc
Definition: write.c:3023
#define ISO_BLOCKS(X)
Definition: mkisofs.h:743
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define XA_SUBH_EOR
Definition: iso9660.h:367
#define INHIBIT_ISO9660_ENTRY
Definition: mkisofs.h:802
#define off_t
Definition: dosfsck.h:5
LOCAL int pathtab_size(UInt32_t starting_extent)
Definition: write.c:2368
char reserved[ISODCL(10, 14)]
Definition: iso9660.h:330
struct directory_entry * contents
Definition: mkisofs.h:270
#define LOCAL(type)
Definition: jmorecfg.h:289
char * de_name
Definition: mkisofs.h:275
LOCAL int dirtree_dump()
Definition: write.c:2471
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
unsigned int total_rr_attr_size
Definition: mkisofs.h:136
r l[0]
Definition: byte_order.h:167
#define SEEK_SET
Definition: jmemansi.c:26
LOCAL int interpad_write(FILE *outfile)
Definition: write.c:2556
__u16 ctime
Definition: mkdosfs.c:362
static void pad(Char *s)
Definition: bzip2.c:908
int toupper(int c)
Definition: utclib.c:881
EXPORT int seterrno(int err)
Definition: seterrno.c:34
GLsizeiptr size
Definition: glext.h:5919
Definition: id3.c:18
LOCAL int endpad_write(FILE *outfile)
Definition: write.c:2580
struct stat root_statbuf
Definition: tree.c:110
#define XA_SUBH_EOF
Definition: iso9660.h:374
struct directory * reloc_dir
Definition: tree.c:111
int use_RockRidge
Definition: mkisofs.c:110
LOCAL void free_directories(struct directory *dpnt)
Definition: write.c:1527
EXPORT int geterrno()
Definition: geterrno.c:34
struct output_fragment startpad_desc
Definition: write.c:3021
Definition: mkisofs.h:331
int create_udfsymlinks
#define ISO_VD_END
Definition: iso9660.h:45
const char file[]
Definition: icontest.c:11
UInt32_t session_start
Definition: mkisofs.c:77
LOCAL int ext_size(UInt32_t starting_extent)
Definition: write.c:2503
GLuint GLuint num
Definition: glext.h:9618
EXPORT int iso9660_ldate(char *result, time_t crtime, int nsec, int gmtoff)
Definition: mkisofs.c:1907
#define PATH_MAX
Definition: types.h:280
REFIID LPVOID DWORD dw
Definition: atlbase.h:40
LOCAL struct deferred_write * dw_head
Definition: write.c:300
LOCAL int root_gen()
Definition: write.c:895
int volume_sequence_number
Definition: mkisofs.c:173
#define E_SHRINK
Definition: checkerr.h:52
LOCAL int vers_write(FILE *outfile)
Definition: write.c:2200
EXPORT ssize_t ffileread(FILE *f, void *buf, size_t len)
Definition: ffileread.c:20
LOCAL int compare_dirs(void *rr, const void *ll) const
Definition: write.c:683
char * trans_tbl
Definition: mkisofs.c:259
Uchar file_number
Definition: iso9660.h:358
ldate modification_date
Definition: mkisofs.c:197
int ret
#define ISO_DIRECTORY
Definition: iso9660.h:265
int path_ind
Definition: mkisofs.c:69
struct directory_entry * s_entry
Definition: mkisofs.h:302
off_t size
Definition: mkisofs.h:162
EXPORT BOOL errabort(int etype, const char *fname, BOOL doexit)
Definition: checkerr.c:300
EXPORT void dump_tree(struct directory *node)
Definition: tree.c:2863
#define E_OPEN
Definition: checkerr.h:48
HKEY key
Definition: reg.c:42
struct output_fragment end_vol
Definition: write.c:3024
struct output_fragment pathtable_desc
Definition: write.c:3026
#define blk
Definition: linetest.c:70
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define NSECT
Definition: write.c:59
GLdouble s
Definition: gl.h:2039
struct directory_entry * next
Definition: mkisofs.h:108
struct directory_entry * self
Definition: mkisofs.h:272
LOCAL int dirtree_write(FILE *outfile)
Definition: write.c:2520
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
off_t size
Definition: mkisofs.h:112
LOCAL int vol_desc_sum
Definition: write.c:78
LOCAL int startpad_size(UInt32_t starting_extent)
Definition: write.c:2384
off_t size
Definition: mkisofs.h:300
LOCAL int dirtree_size(UInt32_t starting_extent)
Definition: write.c:2495
int volume_set_size
Definition: mkisofs.c:172
EXPORT void finish_cl_pl_entries()
Definition: tree.c:1036
T MAX(T a, T b)
Definition: polytest.cpp:85
EXPORT BOOL errhidden(int etype, const char *fname)
Definition: checkerr.c:264
int nolimitpathtables
Definition: mkisofs.c:245
UInt32_t last_extent_written
Definition: write.c:303
EXPORT void init_fstatbuf()
Definition: tree.c:2974
LOCAL int graftcp(char *to, char *from, char *ep)
Definition: write.c:2268
LOCAL int compare_paths(void const *r, void const *l)
Definition: write.c:1733
LOCAL void free_one_directory(struct directory *dpnt)
Definition: write.c:1477
char * hfs_error
Definition: write.c:81
#define ISO_VD_PRIMARY
Definition: iso9660.h:43
#define __(s)
Definition: nlsdefs.h:101
Uchar channel_number
Definition: iso9660.h:359
#define ISO_ROUND_UP(X)
Definition: mkisofs.h:742
struct output_fragment * out_list
Definition: write.c:75
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
__kernel_time_t time_t
Definition: linux.h:252
LOCAL void build_pathlist(struct directory *node)
Definition: write.c:1714
struct output_fragment endpad_desc
Definition: write.c:3032
EXPORT BOOL errwarnonly(int etype, const char *fname)
Definition: checkerr.c:282
void add_hash(struct hash_table *table, unsigned char *name, int len, unsigned char *pointer)
Definition: hash.c:82
EXPORT char * findgequal(char *s)
Definition: mkisofs.c:3642
int osecsize
Definition: mkisofs.c:112
unsigned int rr_attr_size
Definition: mkisofs.h:135
int gui
Definition: mkisofs.c:130
#define abort()
Definition: i386-dis.c:35
LOCAL int xawrite __PR((void *buffer, int size, int count, FILE *file, int submode, BOOL islast))
EXPORT void memcpy_max(char *to, char *from, int max)
Definition: write.c:1880
w ll
Definition: byte_order.h:166
EXPORT void do_inode(struct directory *dpnt)
Definition: inode.c:55
struct directory_entry * mxroot
Definition: mkisofs.h:121
LOCAL int dirtree_fixup(UInt32_t starting_extent)
Definition: write.c:2480
#define SIZEOF_UDF_EXT_ATTRIBUTE_COMMON
Definition: write.c:56
struct output_fragment interpad_desc
Definition: write.c:3031
#define ISO_MULTIEXTENT
Definition: iso9660.h:271
LOCAL int pathtab_write(FILE *outfile)
Definition: write.c:2330
#define E_READ
Definition: checkerr.h:49
char * path_table_l
Definition: mkisofs.c:1631
EXPORT void generate_iso9660_directories(struct directory *node, FILE *outfile)
Definition: tree.c:2458
time_t l_sec
Definition: mkisofs.h:332
EXPORT void comerrno(int err, char *msg, va_alist)
Definition: comerr.c:137
EXPORT void * e_malloc(size_t size)
Definition: mkisofs.c:3921
Uchar coding
Definition: iso9660.h:361
EXPORT struct iso_primary_descriptor vol_desc
Definition: write.c:77
LOCAL int assign_directory_addresses(struct directory *node)
Definition: write.c:314
POINT cp
Definition: magnifier.c:60
Definition: name.c:36
struct iso_directory_record root_record
Definition: mkisofs.c:87
LOCAL int xawrite(void *buffer, int size, int count, FILE *file, int submode, BOOL islast)
Definition: write.c:240
EXPORT void flush_hash()
Definition: hash.c:240
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
EXPORT char * movebytes(void *fromv, void *tov, ssize_t cnt) const
Definition: movebytes.c:30
LOCAL int rockridge_size
Definition: write.c:67
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
FILE * stderr
#define const
Definition: zconf.h:230
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
_Check_return_ _CRTIMP FILE *__cdecl freopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode, _Inout_ FILE *_File)
unsigned char * rr_attributes
Definition: mkisofs.h:134
char version_string[]
Definition: mkisofs.c:71
static UConst char sccsid[]
Definition: write.c:4
#define debug(msg)
Definition: key_call.c:71
int use_XA
Definition: mkisofs.c:111
char * preparer
Definition: mkisofs.c:159
unsigned int path_index
Definition: mkisofs.h:283
EXPORT int sort_directory(struct directory_entry **sort_dir, int rr)
Definition: write.c:814
struct output_fragment dirtree_clean
Definition: write.c:3028
LOCAL int xpvd_write(FILE *outfile)
Definition: write.c:2158
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
CardRegion * from
Definition: spigame.cpp:19
unsigned long Ulong
Definition: utypes.h:42
LOCAL struct deferred_write * dw_tail
Definition: write.c:301
unsigned int pad
Definition: mkisofs.h:303
#define memset(x, y, z)
Definition: compat.h:39
#define apple_hyb
LOCAL int sort_goof
Definition: write.c:70
int use_graft_ptrs
Definition: mkisofs.c:230
UInt32_t next_extent
Definition: mkisofs.c:75
EXPORT time_t begun
Definition: write.c:305
EXPORT void set_723(void *vp, UInt32_t i)
Definition: isonum.c:76
unsigned short dir_flags
Definition: mkisofs.h:285
int l_gmtoff
Definition: mkisofs.h:334
unsigned int path_table[4]
Definition: mkisofs.c:79
struct output_fragment files_desc
Definition: write.c:3030
EXPORT void generate_one_directory(struct directory *dpnt, FILE *outfile)
Definition: write.c:1539
__u8 system_id[8]
Definition: mkdosfs.c:359
unsigned int dw_flags
Definition: mkisofs.h:305
BOOL correct_inodes
Definition: mkisofs.c:324
EXPORT void set_733(void *vp, UInt32_t i)
Definition: isonum.c:125
char signature[ISODCL(7, 8)]
Definition: iso9660.h:328
struct directory * next
Definition: mkisofs.h:267
Definition: path.c:42
LOCAL int table_size
Definition: write.c:65
EXPORT int errmsgno(int err, char *msg, va_alist)
Definition: comerr.c:219
Definition: dlist.c:348
int l_usec
Definition: mkisofs.h:333
LOCAL int pathcp(char *to, char *from, char *ep)
Definition: write.c:2294
off
Definition: i386-dis.c:3909
Definition: fci.c:126
LOCAL int next_path_index
Definition: write.c:69
#define EX_BAD
Definition: standard.h:62