ReactOS  0.4.13-dev-551-gf37fb1f
rock.c
Go to the documentation of this file.
1 /* @(#)rock.c 1.66 12/12/02 joerg */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5  "@(#)rock.c 1.66 12/12/02 joerg";
6 #endif
7 /*
8  * File rock.c - generate RRIP records for iso9660 filesystems.
9  *
10  * Written by Eric Youngdale (1993).
11  *
12  * Copyright 1993 Yggdrasil Computing, Incorporated
13  * Copyright (c) 1999,2000-2012 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 #include "mkisofs.h"
31 #include "rock.h"
32 #include <schily/device.h>
33 #include <schily/schily.h>
34 
35 #define SU_VERSION 1
36 
37 #define SL_ROOT 8
38 #define SL_PARENT 4
39 #define SL_CURRENT 2
40 #define SL_CONTINUE 1
41 
42 #define CE_SIZE 28 /* SUSP Continuation aerea */
43 #define CL_SIZE 12 /* RR Child Link for deep dir relocation */
44 #define ER_SIZE 8 /* RR Extension record for RR signature */
45 #define NM_SIZE 5 /* RR Real name */
46 #define PL_SIZE 12 /* RR Paren Link for deep dir relocation */
47 #define PN_SIZE 20 /* RR POSIX device modes (Major/Minor) */
48 #define PX_OLD_SIZE 36 /* RR POSIX Extensions (mode/nlink/uid/gid) */
49 #define PX_SIZE 44 /* RR POSIX Extensions (mode/nlink/uid/gid/ino) */
50 #define RE_SIZE 4 /* RR Relocated directory */
51 #define RR_SIZE 5 /* RR RR Signature in every file */
52 #define SL_SIZE 20 /* RR Symlink */
53 #define ZF_SIZE 16 /* RR* Linux compression extension */
54 #ifdef APPLE_HYB
55 #define AA_SIZE 14 /* size of Apple extension */
56 #endif /* APPLE_HYB */
57 #if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */
58 #define TF_SIZE (5 + 4 * 7) /* RR Time field */
59 #define TF_SIZE_LONG (5 + 4 * 17) /* RR Time field */
60 #else
61 #define TF_SIZE (5 + 3 * 7)
62 #define TF_SIZE_LONG (5 + 3 * 17)
63 #endif
64 
65 LOCAL void rstrncpy __PR((char *t, char *f, size_t tlen,
66  siconvt_t *inls,
67  siconvt_t *onls));
68 LOCAL void add_CE_entry __PR((char *field, int line));
70 LOCAL void gen_xa __PR((struct stat *lstatbuf));
71 EXPORT int generate_xa_rr_attributes __PR((char *whole_name,
72  char *name,
73  struct directory_entry *s_entry,
74  struct stat *statbuf,
75  struct stat *lstatbuf,
76  int deep_opt));
77  char *generate_rr_extension_record __PR((char *id,
78  char *descriptor,
79  char *source,
80  int *size));
81 /*
82  * If we need to store this number of bytes, make sure we
83  * do not box ourselves in so that we do not have room for
84  * a CE entry for the continuation record
85  */
86 #define RR_CUR_USE (CE_SIZE + currlen + (ipnt - recstart))
87 
88 #define MAYBE_ADD_CE_ENTRY(BYTES) \
89  (((int)(BYTES)) + CE_SIZE + currlen + (ipnt - recstart) > reclimit ? 1 : 0)
90 
91 /*
92  * Buffer to build RR attributes
93  */
94 LOCAL Uchar Rock[16384];
96 LOCAL int ipnt = 0; /* Current "write" offset in Rock[] */
97 LOCAL int recstart = 0; /* Start offset in Rock[] for this area */
98 LOCAL int currlen = 0; /* # of non RR bytes used in this area */
99 LOCAL int mainrec = 0; /* # of RR bytes use in main dir area */
100 LOCAL int reclimit; /* Max. # of bytes usable in this area */
101 
102 /* if we are using converted filenames, we don't want the '/' character */
103 LOCAL void
104 rstrncpy(t, f, tlen, inls, onls)
105  char *t;
106  char *f;
107  size_t tlen; /* The to-length */
108  siconvt_t *inls;
109  siconvt_t *onls;
110 {
111  size_t flen = strlen(f);
112 
113  while (tlen > 0 && *f) {
114  size_t ofl = flen;
115  size_t otl = tlen;
116 
117  conv_charset((Uchar *)t, &tlen, (Uchar *)f, &flen, inls, onls);
118  if (*t == '/') {
119  *t = '_';
120  }
121  t += otl - tlen;
122  f += ofl - flen;
123  }
124 }
125 
126 LOCAL void
128  char *field;
129  int line;
130 {
131  if (MAYBE_ADD_CE_ENTRY(0)) {
133  _("Panic: no space, cannot add RR CE entry (%d bytes mising) for %s line %d.\n"),
134  (CE_SIZE + currlen + (ipnt - recstart) - reclimit),
135  field, line);
136  errmsgno(EX_BAD, _("currlen: %d ipnt: %d, recstart: %d\n"),
137  currlen, ipnt, recstart);
138  errmsgno(EX_BAD, _("Send bug report to the maintainer.\n"));
139  comerrno(EX_BAD, _("Aborting.\n"));
140  }
141 
142  if (recstart)
143  set_733((char *)Rock + recstart - 8, ipnt + 28 - recstart);
144  Rock[ipnt++] = 'C';
145  Rock[ipnt++] = 'E';
146  Rock[ipnt++] = CE_SIZE;
147  Rock[ipnt++] = SU_VERSION;
148  set_733((char *)Rock + ipnt, 0);
149  ipnt += 8;
150  set_733((char *)Rock + ipnt, 0);
151  ipnt += 8;
152  set_733((char *)Rock + ipnt, 0);
153  ipnt += 8;
154  recstart = ipnt;
155  currlen = 0;
156  if (!mainrec)
157  mainrec = ipnt;
158  reclimit = SECTOR_SIZE - 8; /* Limit to one sector */
159 }
160 
161 #ifdef PROTOTYPES
162 LOCAL int
164 #else
165 LOCAL int
167  mode_t attr;
168 #endif
169 {
170  int ret = 0;
171 
172  if (attr & S_IRUSR)
173  ret |= XA_O_READ;
174  if (attr & S_IXUSR)
175  ret |= XA_O_EXEC;
176 
177  if (attr & S_IRGRP)
178  ret |= XA_G_READ;
179  if (attr & S_IXGRP)
180  ret |= XA_G_EXEC;
181 
182  if (attr & S_IROTH)
183  ret |= XA_W_READ;
184  if (attr & S_IXOTH)
185  ret |= XA_W_EXEC;
186 
187  ret |= XA_FORM1;
188 
189  if (S_ISDIR(attr))
190  ret |= XA_DIR;
191 
192  return (ret);
193 }
194 
195 LOCAL void
196 gen_xa(lstatbuf)
197  struct stat *lstatbuf;
198 {
199  /*
200  * Group ID
201  */
202  set_722((char *)Rock + ipnt, lstatbuf->st_gid);
203  ipnt += 2;
204  /*
205  * User ID
206  */
207  set_722((char *)Rock + ipnt, lstatbuf->st_uid);
208  ipnt += 2;
209  /*
210  * Attributes
211  */
212  set_722((char *)Rock + ipnt, gen_xa_attr(lstatbuf->st_mode));
213  ipnt += 2;
214 
215  Rock[ipnt++] = 'X'; /* XA Signature */
216  Rock[ipnt++] = 'A';
217  Rock[ipnt++] = 0; /* File number (we always use '0' */
218 
219  Rock[ipnt++] = 0; /* Reserved (5 Byte) */
220  Rock[ipnt++] = 0;
221  Rock[ipnt++] = 0;
222  Rock[ipnt++] = 0;
223  Rock[ipnt++] = 0;
224 
225 }
226 
227 #ifdef PROTOTYPES
228 EXPORT int
229 generate_xa_rr_attributes(char *whole_name, char *name,
230  struct directory_entry *s_entry,
231  struct stat *statbuf,
232  struct stat *lstatbuf,
233  int deep_opt)
234 #else
235 EXPORT int
237  s_entry,
238  statbuf,
239  lstatbuf,
240  deep_opt)
241  char *whole_name;
242  char *name;
243  struct directory_entry *s_entry;
244  struct stat *statbuf,
245  *lstatbuf;
246  int deep_opt;
247 #endif
248 {
249  int flagpos;
250  int flagval;
251  int need_ce;
252 
253  statbuf = statbuf; /* this shuts up unreferenced compiler */
254  /* warnings */
255  mainrec = recstart = ipnt = 0;
256 
257  if (use_XA) {
258  gen_xa(lstatbuf);
259  }
260 
261 /* reclimit = 0xf8; XXX we now use 254 == 0xfe */
263 
264  /* no need to fill in the RR stuff if we won't see the file */
265  if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
266  return (0);
267 
268  /*
269  * Obtain the amount of space that is currently used for the directory
270  * record. We may safely use the current name length; because if name
271  * confilcts force us to change the ISO-9660 name later, the name will
272  * never become longer than now.
273  */
274  if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
275  s_entry->isorec.name_len[0] = 1;
276  } else {
277  s_entry->isorec.name_len[0] = strlen(s_entry->isorec.name);
278  }
279  currlen = s_entry->isorec.length[0] = s_entry->isorec.name_len[0] +
280  offsetof(struct iso_directory_record, name[0]);
281  if (currlen & 1)
282  s_entry->isorec.length[0] = ++currlen;
283 
284  if (currlen < 33+37) {
285  /*
286  * If the ISO-9660 name length is less than 37, we may use
287  * ISO-9660:1988 name rules and for this reason, the name len
288  * may later increase from adding e.g. ".;1"; in this case
289  * just use the upper limit.
290  */
291  currlen = 33+37;
292  }
293 
294 #ifdef APPLE_HYB
295  /* if we have regular file, then add Apple extensions */
296  if (S_ISREG(lstatbuf->st_mode) && apple_ext && s_entry->hfs_ent) {
297  if (MAYBE_ADD_CE_ENTRY(AA_SIZE))
298  add_CE_entry("AA", __LINE__);
299  Rock[ipnt++] = 'A'; /* AppleSignature */
300  Rock[ipnt++] = 'A';
301  Rock[ipnt++] = AA_SIZE; /* includes AppleSignature bytes */
302  Rock[ipnt++] = 0x02; /* SystemUseID */
303  Rock[ipnt++] = s_entry->hfs_ent->u.file.type[0];
304  Rock[ipnt++] = s_entry->hfs_ent->u.file.type[1];
305  Rock[ipnt++] = s_entry->hfs_ent->u.file.type[2];
306  Rock[ipnt++] = s_entry->hfs_ent->u.file.type[3];
307  Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[0];
308  Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[1];
309  Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[2];
310  Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[3];
311  Rock[ipnt++] = (s_entry->hfs_ent->fdflags >> 8) & 0xff;
312  Rock[ipnt++] = s_entry->hfs_ent->fdflags & 0xff;
313  }
314 #endif /* APPLE_HYB */
315 
316  if (!use_RockRidge)
317  goto xa_only;
318 
319  /* Identify that we are using the SUSP protocol */
320  if (deep_opt & NEED_SP) {
321  /*
322  * We may not use a CE record here but we never will need to
323  * do so, as this SP record is only used for the "." entry
324  * of the root directory.
325  */
326  Rock[ipnt++] = 'S';
327  Rock[ipnt++] = 'P';
328  Rock[ipnt++] = 7;
329  Rock[ipnt++] = SU_VERSION;
330  Rock[ipnt++] = 0xbe;
331  Rock[ipnt++] = 0xef;
332  if (use_XA)
333  Rock[ipnt++] = sizeof (struct iso_xa_dir_record);
334  else
335  Rock[ipnt++] = 0;
336  }
337 
338  /* First build the posix name field */
340  add_CE_entry("RR", __LINE__);
341  Rock[ipnt++] = 'R';
342  Rock[ipnt++] = 'R';
343  Rock[ipnt++] = 5;
344  Rock[ipnt++] = SU_VERSION;
345  flagpos = ipnt;
346  flagval = 0;
347  Rock[ipnt++] = 0; /* We go back and fix this later */
348 
349  if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0) {
350  char *npnt;
351  int remain; /* Remaining name length */
352  int use; /* Current name part used */
353 
354 #ifdef APPLE_HYB
355  /* use the HFS name if it exists */
356  if (USE_MAC_NAME(s_entry)) {
357  remain = strlen(s_entry->hfs_ent->name);
358  npnt = s_entry->hfs_ent->name;
359  } else {
360 #endif /* APPLE_HYB */
361 
362  remain = strlen(name);
363  npnt = name;
364 #ifdef APPLE_HYB
365  }
366 #endif /* APPLE_HYB */
367 
369  add_CE_entry("NM", __LINE__);
370  while (remain) {
371  use = remain;
372  need_ce = 0;
373  /* Can we fit this SUSP and a CE entry? */
374  if (MAYBE_ADD_CE_ENTRY(NM_SIZE+use)) {
375  use = reclimit - NM_SIZE - RR_CUR_USE;
376  need_ce++;
377  }
378  /* Only room for 256 per SUSP field */
379  if (use > 0xf8) {
380  use = 0xf8;
381  need_ce++;
382  }
383  if (use < 0) {
385  _("Negative RR name length residual: %d\n"),
386  use);
387  }
388 
389  /* First build the posix name field */
390  Rock[ipnt++] = 'N';
391  Rock[ipnt++] = 'M';
392  Rock[ipnt++] = NM_SIZE + use;
393  Rock[ipnt++] = SU_VERSION;
394  Rock[ipnt++] = (remain != use ? 1 : 0);
395  flagval |= (1 << 3);
396 
397  /*
398  * Convert charsets as required
399  * XXX If we are using iconv() based locales and in/out
400  * XXX locale differ, then strlen(&Rock[ipnt]) may
401  * XXX increase. We would need to compute the length
402  * XXX early enough.
403  */
404 #ifdef APPLE_HYB
405  if (USE_MAC_NAME(s_entry))
406  rstrncpy((char *)&Rock[ipnt], npnt, use,
407  hfs_inls, out_nls);
408  else
409 #endif /* APPLE_HYB */
410  rstrncpy((char *)&Rock[ipnt], npnt, use,
411  in_nls, out_nls);
412  npnt += use;
413  ipnt += use;
414  remain -= use;
415  if (remain && need_ce)
416  add_CE_entry("NM", __LINE__);
417  }
418  }
419 
420  /* Add the posix modes */
422  add_CE_entry("PX", __LINE__);
423  Rock[ipnt++] = 'P';
424  Rock[ipnt++] = 'X';
425  if (rrip112) {
426  Rock[ipnt++] = PX_SIZE;
427  } else {
428  Rock[ipnt++] = PX_OLD_SIZE;
429  }
430  Rock[ipnt++] = SU_VERSION;
431  flagval |= (1 << 0);
432  set_733((char *)Rock + ipnt, lstatbuf->st_mode);
433  ipnt += 8;
434  set_733((char *)Rock + ipnt, lstatbuf->st_nlink);
435  ipnt += 8;
436  set_733((char *)Rock + ipnt, lstatbuf->st_uid);
437  ipnt += 8;
438  set_733((char *)Rock + ipnt, lstatbuf->st_gid);
439  ipnt += 8;
440  if (rrip112) {
441  /*
442  * We will set up correct inode numbers later
443  * after we did assign them.
444  */
445  set_733((char *)Rock + ipnt, 0);
446  ipnt += 8;
447  }
448 
449  /* Check for special devices */
450 #if defined(S_IFCHR) || defined(S_IFBLK)
451  /*
452  * The code in this if statement used to be #ifdef'd with NON_UNIXFS.
453  * But as schily/stat.h always provides the macros S_ISCHR() & S_ISBLK()
454  * and schily/device.h always provides major()/minor() it is not needed
455  * anymore.
456  */
457  if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) {
459  add_CE_entry("PN", __LINE__);
460  Rock[ipnt++] = 'P';
461  Rock[ipnt++] = 'N';
462  Rock[ipnt++] = PN_SIZE;
463  Rock[ipnt++] = SU_VERSION;
464  flagval |= (1 << 1);
465 #if 1
466  /* This is the new and only code which uses <schily/device.h> */
467  set_733((char *)Rock + ipnt, major(lstatbuf->st_rdev));
468  ipnt += 8;
469  set_733((char *)Rock + ipnt, minor(lstatbuf->st_rdev));
470  ipnt += 8;
471 #else
472  /*
473  * If we don't have sysmacros.h, then we have to guess as to
474  * how best to pick apart the device number for major/minor.
475  * Note: this may very well be wrong for many systems, so it
476  * is always best to use the major/minor macros if the system
477  * supports it.
478  */
479  if (sizeof (dev_t) <= 2) {
480  set_733((char *)Rock + ipnt, (lstatbuf->st_rdev >> 8));
481  ipnt += 8;
482  set_733((char *)Rock + ipnt, lstatbuf->st_rdev & 0xff);
483  ipnt += 8;
484  } else if (sizeof (dev_t) <= 4) {
485  set_733((char *)Rock + ipnt,
486  (lstatbuf->st_rdev >> 8) >> 8);
487  ipnt += 8;
488  set_733((char *)Rock + ipnt,
489  lstatbuf->st_rdev & 0xffff);
490  ipnt += 8;
491  } else {
492  set_733((char *)Rock + ipnt,
493  (lstatbuf->st_rdev >> 16)>>16);
494  ipnt += 8;
495  set_733((char *)Rock + ipnt, lstatbuf->st_rdev);
496  ipnt += 8;
497  }
498 #endif
499  }
500 #endif /* defined(S_IFCHR) || defined(S_IFBLK) */
501 
502  /* Check for and symbolic links. VMS does not have these. */
503 #ifdef S_IFLNK
504  if (S_ISLNK(lstatbuf->st_mode)) {
505  int lenpos;
506  int lenval;
507  int j0;
508  int j1;
509  int nchar;
510  Uchar *cpnt;
511  Uchar *cpnt1;
512  BOOL last_sl = FALSE; /* Don't suppress last '/' */
513 
514 #ifdef HAVE_READLINK
515  nchar = readlink(deep_opt&DID_CHDIR?name:whole_name,
516  (char *)symlink_buff,
517  sizeof (symlink_buff)-1);
518  if (nchar < 0)
519  errmsg(_("Cannot read link '%s'.\n"), whole_name);
520 #else
521  nchar = -1;
522 #endif /* HAVE_READLINK */
523  symlink_buff[nchar < 0 ? 0 : nchar] = 0;
524  nchar = strlen((char *)symlink_buff);
525  set_733(s_entry->isorec.size, 0);
526  cpnt = &symlink_buff[0];
527  flagval |= (1 << 2);
528 
529  if (!split_SL_field) {
530  int sl_bytes = 0;
531 
532  for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) {
533  if (*cpnt1 == '/') {
534  sl_bytes += 4;
535  } else {
536  sl_bytes += 1;
537  }
538  }
539  if (sl_bytes > 250) {
540  /*
541  * the symbolic link won't fit into one
542  * SL System Use Field print an error message
543  * and continue with splited one
544  */
545  fprintf(stderr,
546  _("symbolic link ``%s'' to long for one SL System Use Field, splitting"),
547  cpnt);
548  }
549  if (MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes))
550  add_CE_entry("SL+", __LINE__);
551  }
552  while (nchar) {
554  add_CE_entry("SL", __LINE__);
555  Rock[ipnt++] = 'S';
556  Rock[ipnt++] = 'L';
557  lenpos = ipnt;
558  Rock[ipnt++] = SL_SIZE;
559  Rock[ipnt++] = SU_VERSION;
560  Rock[ipnt++] = 0; /* Flags */
561  lenval = 5;
562  while (*cpnt || last_sl) {
563  cpnt1 = (Uchar *)
564  strchr((char *)cpnt, '/');
565  if (cpnt1) {
566  nchar--;
567  *cpnt1 = 0;
568  }
569 
570  /*
571  * We treat certain components in a special
572  * way.
573  */
574  if (cpnt[0] == '.' && cpnt[1] == '.' &&
575  cpnt[2] == 0) {
576  if (MAYBE_ADD_CE_ENTRY(2)) {
577  add_CE_entry("SL-parent", __LINE__);
578  if (cpnt1) {
579  *cpnt1 = '/';
580  nchar++;
581  /*
582  * A kluge so that we
583  * can restart properly
584  */
585  cpnt1 = NULL;
586  }
587  break;
588  }
589  Rock[ipnt++] = SL_PARENT;
590  Rock[ipnt++] = 0; /* length is zero */
591  lenval += 2;
592  nchar -= 2;
593  } else if (cpnt[0] == '.' && cpnt[1] == 0) {
594  if (MAYBE_ADD_CE_ENTRY(2)) {
595  add_CE_entry("SL-current", __LINE__);
596  if (cpnt1) {
597  *cpnt1 = '/';
598  nchar++;
599  /*
600  * A kluge so that we
601  * can restart properly
602  */
603  cpnt1 = NULL;
604  }
605  break;
606  }
607  Rock[ipnt++] = SL_CURRENT;
608  Rock[ipnt++] = 0; /* length is zero */
609  lenval += 2;
610  nchar -= 1;
611  } else if (cpnt[0] == 0) {
612  if (MAYBE_ADD_CE_ENTRY(2)) {
613  add_CE_entry("SL-root", __LINE__);
614  if (cpnt1) {
615  *cpnt1 = '/';
616  nchar++;
617  /*
618  * A kluge so that we
619  * can restart properly
620  */
621  cpnt1 = NULL;
622  }
623  break;
624  }
625  if (cpnt == &symlink_buff[0])
626  Rock[ipnt++] = SL_ROOT;
627  else
628  Rock[ipnt++] = 0;
629  Rock[ipnt++] = 0; /* length is zero */
630  lenval += 2;
631  } else {
632  /*
633  * If we do not have enough room for a
634  * component, start a new continuations
635  * segment now
636  */
637  if (split_SL_component ?
638  MAYBE_ADD_CE_ENTRY(6) :
639  MAYBE_ADD_CE_ENTRY(6 + strlen((char *)cpnt))) {
640  add_CE_entry("SL++", __LINE__);
641  if (cpnt1) {
642  *cpnt1 = '/';
643  nchar++;
644  /*
645  * A kluge so that we
646  * can restart properly
647  */
648  cpnt1 = NULL;
649  }
650  break;
651  }
652  j0 = strlen((char *)cpnt);
653  while (j0) {
654  j1 = j0;
655  if (j1 > 0xf8)
656  j1 = 0xf8;
657  need_ce = 0;
658  if (j1 + currlen + 2 + CE_SIZE +
659  (ipnt - recstart) >
660  reclimit) {
661 
662  j1 = reclimit -
663  (currlen + 2) -
664  CE_SIZE -
665  (ipnt - recstart);
666  need_ce++;
667  }
668  Rock[ipnt++] =
669  (j1 != j0 ?
670  SL_CONTINUE : 0);
671  Rock[ipnt++] = j1;
672  strncpy((char *)Rock + ipnt,
673  (char *)cpnt, j1);
674  ipnt += j1;
675  lenval += j1 + 2;
676  cpnt += j1;
677  /*
678  * Number we processed
679  * this time
680  */
681  nchar -= j1;
682  j0 -= j1;
683  if (need_ce) {
684  add_CE_entry(
685  "SL-path-split",
686  __LINE__);
687  if (cpnt1) {
688  *cpnt1 = '/';
689  nchar++;
690  /*
691  * A kluge so
692  * that we can
693  * restart
694  * properly
695  */
696  cpnt1 = NULL;
697  }
698  break;
699  }
700  }
701  }
702  if (cpnt1) {
703  *cpnt1 = '/';
704  if (cpnt1 > symlink_buff && !last_sl &&
705  cpnt1[1] == '\0') {
706  last_sl = TRUE;
707  }
708  cpnt = cpnt1 + 1;
709  } else
710  break;
711  }
712  Rock[lenpos] = lenval;
713  if (nchar) {
714  /* We need another SL entry */
715  Rock[lenpos + 2] = SL_CONTINUE;
716  }
717  } /* while nchar */
718  } /* Is a symbolic link */
719 #endif /* S_IFLNK */
720 
721  /* Add in the Rock Ridge TF time field */
723  add_CE_entry("TF", __LINE__);
724  Rock[ipnt++] = 'T';
725  Rock[ipnt++] = 'F';
727  Rock[ipnt++] = SU_VERSION;
728 #if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */
729  Rock[ipnt++] = long_rr_time ? 0x8f:0x0f;
730 #else
731  Rock[ipnt++] = long_rr_time ? 0x8e:0x0e;
732 #endif
733  flagval |= (1 << 7);
734 
735 #if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */
736  if (long_rr_time) {
737  iso9660_date((char *)&Rock[ipnt], lstatbuf->st_ftime);
738  ipnt += 7;
739  } else {
740  /*
741  * XXX Do we have nanoseconds on QNX?
742  */
743  iso9660_ldate((char *)&Rock[ipnt], lstatbuf->st_ftime, 0, -100);
744  ipnt += 17;
745  }
746 #endif
747  if (long_rr_time) {
748  iso9660_ldate((char *)&Rock[ipnt],
749  lstatbuf->st_mtime, stat_mnsecs(lstatbuf), -100);
750  ipnt += 17;
751  iso9660_ldate((char *)&Rock[ipnt],
752  lstatbuf->st_atime, stat_ansecs(lstatbuf), -100);
753  ipnt += 17;
754  iso9660_ldate((char *)&Rock[ipnt],
755  lstatbuf->st_ctime, stat_cnsecs(lstatbuf), -100);
756  ipnt += 17;
757  } else {
758  iso9660_date((char *)&Rock[ipnt], lstatbuf->st_mtime);
759  ipnt += 7;
760  iso9660_date((char *)&Rock[ipnt], lstatbuf->st_atime);
761  ipnt += 7;
762  iso9660_date((char *)&Rock[ipnt], lstatbuf->st_ctime);
763  ipnt += 7;
764  }
765 
766  /* Add in the Rock Ridge RE (relocated dir) field */
767  if (deep_opt & NEED_RE) {
769  add_CE_entry("RE", __LINE__);
770  Rock[ipnt++] = 'R';
771  Rock[ipnt++] = 'E';
772  Rock[ipnt++] = RE_SIZE;
773  Rock[ipnt++] = SU_VERSION;
774  flagval |= (1 << 6);
775  }
776  /* Add in the Rock Ridge PL record, if required. */
777  if (deep_opt & NEED_PL) {
779  add_CE_entry("PL", __LINE__);
780  Rock[ipnt++] = 'P';
781  Rock[ipnt++] = 'L';
782  Rock[ipnt++] = PL_SIZE;
783  Rock[ipnt++] = SU_VERSION;
784  set_733((char *)Rock + ipnt, 0);
785  ipnt += 8;
786  flagval |= (1 << 5);
787  }
788 
789  /* Add in the Rock Ridge CL field, if required. */
790  if (deep_opt & NEED_CL) {
792  add_CE_entry("CL", __LINE__);
793  Rock[ipnt++] = 'C';
794  Rock[ipnt++] = 'L';
795  Rock[ipnt++] = CL_SIZE;
796  Rock[ipnt++] = SU_VERSION;
797  set_733((char *)Rock + ipnt, 0);
798  ipnt += 8;
799  flagval |= (1 << 4);
800  }
801 
802 #ifndef VMS
803  /*
804  * If transparent compression was requested, fill in the correct field
805  * for this file, if (and only if) it is actually a compressed file!
806  * This relies only on magic number, but it should in general not
807  * be an issue since if you're using -z odds are most of your
808  * files are already compressed.
809  *
810  * In the future it would be nice if mkisofs actually did the
811  * compression.
812  */
813  if (transparent_compression && S_ISREG(lstatbuf->st_mode)) {
814  static const Uchar zisofs_magic[8] =
815  { 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 };
816  FILE *zffile;
817  unsigned int file_size;
818  Uchar header[16];
819  int OK_flag;
820  int blocksize;
821  int headersize;
822 
823  /*
824  * First open file and verify that the correct algorithm was
825  * used
826  */
827  file_size = 0;
828  OK_flag = 1;
829 
830  memset(header, 0, sizeof (header));
831 
832  zffile = fopen(whole_name, "rb");
833  if (zffile != NULL) {
834  if (fread(header, 1, sizeof (header), zffile) != sizeof (header))
835  OK_flag = 0;
836 
837  /* Check magic number */
838  if (memcmp(header, zisofs_magic, sizeof (zisofs_magic)))
839  OK_flag = 0;
840 
841  /* Get the real size of the file */
842  file_size = get_731((char *)header+8);
843 
844  /* Get the header size (>> 2) */
845  headersize = header[12];
846 
847  /* Get the block size (log2) */
848  blocksize = header[13];
849 
850  fclose(zffile);
851  } else {
852  OK_flag = 0;
853  blocksize = headersize = 0; /* Make silly GCC quiet */
854  }
855 
856  if (OK_flag) {
858  add_CE_entry("ZF", __LINE__);
859  Rock[ipnt++] = 'Z';
860  Rock[ipnt++] = 'F';
861  Rock[ipnt++] = ZF_SIZE;
862  Rock[ipnt++] = SU_VERSION;
863  Rock[ipnt++] = 'p'; /* Algorithm: "paged zlib" */
864  Rock[ipnt++] = 'z';
865  /* 2 bytes for algorithm-specific information */
866  Rock[ipnt++] = headersize;
867  Rock[ipnt++] = blocksize;
868  set_733((char *)Rock + ipnt, file_size); /* Real file size */
869  ipnt += 8;
870  }
871  }
872 #endif
873  /*
874  * Add in the Rock Ridge CE field, if required. We use this for the
875  * extension record that is stored in the root directory.
876  */
877  if (deep_opt & NEED_CE)
878  add_CE_entry("ER", __LINE__);
879 
880  /*
881  * Done filling in all of the fields. Now copy it back to a buffer
882  * for the file in question.
883  */
884  /* Now copy this back to the buffer for the file */
885  Rock[flagpos] = flagval;
886 
887  /* If there was a CE, fill in the size field */
888  if (recstart)
889  set_733((char *)Rock + recstart - 8, ipnt - recstart);
890 
891 xa_only:
892  s_entry->rr_attributes = (Uchar *) e_malloc(ipnt);
893  s_entry->total_rr_attr_size = ipnt;
894  s_entry->rr_attr_size = (mainrec ? mainrec : ipnt);
895  memcpy(s_entry->rr_attributes, Rock, ipnt);
896  return (ipnt);
897 }
898 
899 /*
900  * Guaranteed to return a single sector with the relevant info
901  */
902 EXPORT char *
904  char *id;
905  char *descriptor;
906  char *source;
907  int *size;
908 {
909  int lipnt = 0;
910  char *pnt;
911  int len_id;
912  int len_des;
913  int len_src;
914 
915  len_id = strlen(id);
916  len_des = strlen(descriptor);
917  len_src = strlen(source);
918  Rock[lipnt++] = 'E';
919  Rock[lipnt++] = 'R';
920  Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src;
921  Rock[lipnt++] = 1;
922  Rock[lipnt++] = len_id;
923  Rock[lipnt++] = len_des;
924  Rock[lipnt++] = len_src;
925  Rock[lipnt++] = 1;
926 
927  memcpy(Rock + lipnt, id, len_id);
928  lipnt += len_id;
929 
930  memcpy(Rock + lipnt, descriptor, len_des);
931  lipnt += len_des;
932 
933  memcpy(Rock + lipnt, source, len_src);
934  lipnt += len_src;
935 
936  if (lipnt > SECTOR_SIZE) {
937  comerrno(EX_BAD, _("Extension record too long\n"));
938  }
939  pnt = (char *)e_malloc(SECTOR_SIZE);
940  memset(pnt, 0, SECTOR_SIZE);
941  memcpy(pnt, Rock, lipnt);
942  *size = lipnt;
943  return (pnt);
944 }
LOCAL void rstrncpy __PR((char *t, char *f, size_t tlen, siconvt_t *inls, siconvt_t *onls))
short st_nlink
Definition: stat.h:59
unsigned int de_flags
Definition: mkisofs.h:122
#define PX_SIZE
Definition: rock.c:49
#define TF_SIZE
Definition: rock.c:61
#define TRUE
Definition: types.h:120
EXPORT UInt32_t get_731(void *vp)
Definition: isonum.c:187
LOCAL Uchar Rock[16384]
Definition: rock.c:94
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define NEED_RE
Definition: rock.h:49
BOOL rrip112
Definition: mkisofs.c:325
unsigned char Uchar
Definition: utypes.h:45
Definition: mkisofs.h:107
time_t st_ctime
Definition: stat.h:66
#define NEED_CL
Definition: rock.h:51
#define S_ISBLK(m)
Definition: ext2fs.h:370
#define MAX_ISODIR
Definition: iso9660.h:243
#define PN_SIZE
Definition: rock.c:47
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define NEED_SP
Definition: rock.h:53
#define PX_OLD_SIZE
Definition: rock.c:48
LOCAL void gen_xa(struct stat *lstatbuf)
Definition: rock.c:196
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define UConst
Definition: ccomdefs.h:72
LOCAL void add_CE_entry(char *field, int line)
Definition: rock.c:127
GLdouble GLdouble t
Definition: gl.h:2047
EXPORT void set_722(void *vp, UInt32_t i)
Definition: isonum.c:61
int split_SL_field
Definition: mkisofs.c:258
LOCAL int recstart
Definition: rock.c:97
siconvt_t * hfs_inls
#define CE_SIZE
Definition: rock.c:42
LOCAL int gen_xa_attr(mode_t attr)
Definition: rock.c:166
#define ZF_SIZE
Definition: rock.c:53
#define XA_W_EXEC
Definition: iso9660.h:346
BOOL long_rr_time
Definition: mkisofs.c:326
#define SL_CURRENT
Definition: rock.c:39
char * name
Definition: mkisofs.h:116
#define XA_FORM1
Definition: iso9660.h:348
#define S_ISLNK(m)
Definition: ext2fs.h:368
short st_uid
Definition: stat.h:60
#define DID_CHDIR
Definition: rock.h:54
LOCAL void rstrncpy(char *t, char *f, size_t tlen, siconvt_t *inls, siconvt_t *onls)
Definition: rock.c:104
#define PL_SIZE
Definition: rock.c:46
#define TF_SIZE_LONG
Definition: rock.c:62
_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 NEED_CE
Definition: rock.h:52
#define _(X)
Definition: i386-dis.c:36
#define SECTOR_SIZE
Definition: winldr.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
#define RR_SIZE
Definition: rock.c:51
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define S_IRGRP
Definition: propsheet.h:41
#define S_IXOTH
Definition: propsheet.h:61
struct iso_directory_record isorec
Definition: mkisofs.h:110
#define SU_VERSION
Definition: rock.c:35
#define SL_CONTINUE
Definition: rock.c:40
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
short st_gid
Definition: stat.h:61
EXPORT int errmsg(char *msg, va_alist)
Definition: comerr.c:192
Definition: parser.c:48
EXPORT int iso9660_date(char *result, time_t crtime)
Definition: mkisofs.c:1868
#define INHIBIT_ISO9660_ENTRY
Definition: mkisofs.h:802
#define S_ISCHR(m)
Definition: ext2fs.h:372
#define LOCAL(type)
Definition: jmorecfg.h:289
unsigned int total_rr_attr_size
Definition: mkisofs.h:136
static UConst char sccsid[]
Definition: rock.c:4
#define S_IXGRP
Definition: propsheet.h:49
GLfloat f
Definition: glext.h:7540
GLsizeiptr size
Definition: glext.h:5919
int transparent_compression
Definition: mkisofs.c:235
Definition: parser.c:43
int use_RockRidge
Definition: mkisofs.c:110
#define S_ISDIR(mode)
Definition: various.h:18
#define RE_SIZE
Definition: rock.c:50
#define SL_PARENT
Definition: rock.c:38
#define MAYBE_ADD_CE_ENTRY(BYTES)
Definition: rock.c:88
#define stat_mnsecs(s)
Definition: stat.h:394
#define XA_O_READ
Definition: iso9660.h:336
EXPORT int iso9660_ldate(char *result, time_t crtime, int nsec, int gmtoff)
Definition: mkisofs.c:1907
#define PATH_MAX
Definition: types.h:280
siconvt_t * in_nls
Definition: mkisofs.c:332
Definition: cookie.c:170
#define SL_ROOT
Definition: rock.c:37
int ret
char line[200]
Definition: main.c:97
#define S_IXUSR
Definition: propsheet.h:37
__u8 attr
Definition: mkdosfs.c:359
#define S_IROTH
Definition: propsheet.h:53
unsigned short st_mode
Definition: stat.h:58
Definition: stat.h:55
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_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)
_dev_t st_rdev
Definition: stat.h:62
#define RR_CUR_USE
Definition: rock.c:86
#define XA_G_EXEC
Definition: iso9660.h:342
#define XA_W_READ
Definition: iso9660.h:344
#define stat_cnsecs(s)
Definition: stat.h:395
EXPORT int generate_xa_rr_attributes(char *whole_name, char *name, struct directory_entry *s_entry, struct stat *statbuf, struct stat *lstatbuf, int deep_opt)
Definition: rock.c:236
__kernel_dev_t dev_t
Definition: linux.h:197
__kernel_mode_t mode_t
Definition: linux.h:199
time_t st_atime
Definition: stat.h:64
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
#define major(rdev)
Definition: propsheet.cpp:879
#define XA_G_READ
Definition: iso9660.h:340
#define f
Definition: ke_i.h:83
#define XA_DIR
Definition: iso9660.h:352
unsigned int rr_attr_size
Definition: mkisofs.h:135
#define S_IRUSR
Definition: propsheet.h:29
EXPORT void comerrno(int err, char *msg, va_alist)
Definition: comerr.c:137
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define SL_SIZE
Definition: rock.c:52
#define CL_SIZE
Definition: rock.c:43
EXPORT void * e_malloc(size_t size)
Definition: mkisofs.c:3921
EXPORT char * generate_rr_extension_record(char *id, char *descriptor, char *source, int *size)
Definition: rock.c:903
Definition: name.c:36
LOCAL Uchar symlink_buff[PATH_MAX+1]
Definition: rock.c:95
GLenum GLuint id
Definition: glext.h:5579
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define minor(rdev)
Definition: propsheet.cpp:880
unsigned char * rr_attributes
Definition: mkisofs.h:134
LOCAL int reclimit
Definition: rock.c:100
int readlink(const char *path, char *buf, size_t size)
LOCAL int currlen
Definition: rock.c:98
siconvt_t * out_nls
Definition: mkisofs.c:333
int use_XA
Definition: mkisofs.c:111
#define ER_SIZE
Definition: rock.c:44
#define stat_ansecs(s)
Definition: stat.h:393
int split_SL_component
Definition: mkisofs.c:257
#define XA_O_EXEC
Definition: iso9660.h:338
time_t st_mtime
Definition: stat.h:65
#define NEED_PL
Definition: rock.h:50
EXPORT void conv_charset(unsigned char *to, size_t *tosizep, unsigned char *from, size_t *fromsizep, siconvt_t *inls, siconvt_t *onls)
Definition: joliet.c:148
#define memset(x, y, z)
Definition: compat.h:39
LOCAL int ipnt
Definition: rock.c:96
#define S_ISREG(mode)
Definition: various.h:17
LOCAL int mainrec
Definition: rock.c:99
struct CFHEADER header
Definition: fdi.c:109
#define NM_SIZE
Definition: rock.c:45
#define file_size(inode)
Definition: reiserfs_fs.h:1869
EXPORT void set_733(void *vp, UInt32_t i)
Definition: isonum.c:125
EXPORT int errmsgno(int err, char *msg, va_alist)
Definition: comerr.c:219
#define EX_BAD
Definition: standard.h:62
GLuint const GLchar * name
Definition: glext.h:6031