ReactOS 0.4.15-dev-7834-g00c4b3d
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
4static 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
65LOCAL void rstrncpy __PR((char *t, char *f, size_t tlen,
66 siconvt_t *inls,
67 siconvt_t *onls));
68LOCAL void add_CE_entry __PR((char *field, int line));
70LOCAL void gen_xa __PR((struct stat *lstatbuf));
72 char *name,
73 struct directory_entry *s_entry,
74 struct stat *statbuf,
75 struct stat *lstatbuf,
76 int deep_opt));
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 */
96LOCAL int ipnt = 0; /* Current "write" offset in Rock[] */
97LOCAL int recstart = 0; /* Start offset in Rock[] for this area */
98LOCAL int currlen = 0; /* # of non RR bytes used in this area */
99LOCAL int mainrec = 0; /* # of RR bytes use in main dir area */
100LOCAL int reclimit; /* Max. # of bytes usable in this area */
101
102/* if we are using converted filenames, we don't want the '/' character */
103LOCAL void
104rstrncpy(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
126LOCAL 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"),
135 field, line);
136 errmsgno(EX_BAD, _("currlen: %d ipnt: %d, recstart: %d\n"),
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
162LOCAL int
164#else
165LOCAL 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
195LOCAL void
196gen_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
228EXPORT int
229generate_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
235EXPORT 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] +
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,
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 */
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 */
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) {
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
891xa_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 */
902EXPORT 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}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define PATH_MAX
Definition: types.h:280
#define S_ISDIR(mode)
Definition: various.h:18
#define S_ISREG(mode)
Definition: various.h:17
#define SECTOR_SIZE
Definition: fs.h:22
#define UConst
Definition: ccomdefs.h:72
EXPORT void comerrno(int err, char *msg, va_alist)
Definition: comerr.c:137
EXPORT int errmsgno(int err, char *msg, va_alist)
Definition: comerr.c:219
EXPORT int errmsg(char *msg, va_alist)
Definition: comerr.c:192
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
__kernel_dev_t dev_t
Definition: linux.h:197
__kernel_mode_t mode_t
Definition: linux.h:199
#define S_ISBLK(m)
Definition: ext2fs.h:375
#define S_ISCHR(m)
Definition: ext2fs.h:377
#define S_ISLNK(m)
Definition: ext2fs.h:373
unsigned int BOOL
Definition: ntddk_ex.h:94
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLfloat f
Definition: glext.h:7540
GLuint id
Definition: glext.h:5910
#define _(X)
Definition: i386-dis.c:35
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_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)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define XA_G_EXEC
Definition: iso9660.h:342
#define XA_O_EXEC
Definition: iso9660.h:338
#define XA_W_READ
Definition: iso9660.h:344
#define MAX_ISODIR
Definition: iso9660.h:243
#define XA_DIR
Definition: iso9660.h:352
#define XA_G_READ
Definition: iso9660.h:340
#define XA_O_READ
Definition: iso9660.h:336
#define XA_W_EXEC
Definition: iso9660.h:346
#define XA_FORM1
Definition: iso9660.h:348
EXPORT void set_722(void *vp, UInt32_t i)
Definition: isonum.c:61
EXPORT UInt32_t get_731(void *vp)
Definition: isonum.c:187
EXPORT void set_733(void *vp, UInt32_t i)
Definition: isonum.c:125
#define LOCAL(type)
Definition: jmorecfg.h:289
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 f
Definition: ke_i.h:83
EXPORT int iso9660_date(char *result, time_t crtime)
Definition: mkisofs.c:1868
int transparent_compression
Definition: mkisofs.c:235
int use_RockRidge
Definition: mkisofs.c:110
int split_SL_component
Definition: mkisofs.c:257
EXPORT void * e_malloc(size_t size)
Definition: mkisofs.c:3921
BOOL long_rr_time
Definition: mkisofs.c:326
int split_SL_field
Definition: mkisofs.c:258
EXPORT int iso9660_ldate(char *result, time_t crtime, int nsec, int gmtoff)
Definition: mkisofs.c:1907
siconvt_t * in_nls
Definition: mkisofs.c:332
siconvt_t * out_nls
Definition: mkisofs.c:333
int use_XA
Definition: mkisofs.c:111
BOOL rrip112
Definition: mkisofs.c:325
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
siconvt_t * hfs_inls
#define INHIBIT_ISO9660_ENTRY
Definition: mkisofs.h:802
int readlink(const char *path, char *buf, size_t size)
#define minor(rdev)
Definition: propsheet.cpp:929
#define major(rdev)
Definition: propsheet.cpp:928
#define S_IXGRP
Definition: propsheet.h:49
#define S_IROTH
Definition: propsheet.h:53
#define S_IXOTH
Definition: propsheet.h:61
#define S_IRGRP
Definition: propsheet.h:41
#define S_IRUSR
Definition: propsheet.h:29
#define S_IXUSR
Definition: propsheet.h:37
#define __PR(a)
Definition: prototyp.h:106
static unsigned int file_size
Definition: regtests2xml.c:47
LOCAL int mainrec
Definition: rock.c:99
#define SL_CONTINUE
Definition: rock.c:40
#define RE_SIZE
Definition: rock.c:50
LOCAL void add_CE_entry(char *field, int line)
Definition: rock.c:127
#define MAYBE_ADD_CE_ENTRY(BYTES)
Definition: rock.c:88
#define SL_ROOT
Definition: rock.c:37
LOCAL int recstart
Definition: rock.c:97
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
#define SU_VERSION
Definition: rock.c:35
LOCAL Uchar symlink_buff[PATH_MAX+1]
Definition: rock.c:95
LOCAL void gen_xa(struct stat *lstatbuf)
Definition: rock.c:196
LOCAL void rstrncpy(char *t, char *f, size_t tlen, siconvt_t *inls, siconvt_t *onls)
Definition: rock.c:104
#define CE_SIZE
Definition: rock.c:42
static UConst char sccsid[]
Definition: rock.c:4
#define PX_SIZE
Definition: rock.c:49
LOCAL int reclimit
Definition: rock.c:100
#define PX_OLD_SIZE
Definition: rock.c:48
#define TF_SIZE
Definition: rock.c:61
#define NM_SIZE
Definition: rock.c:45
#define TF_SIZE_LONG
Definition: rock.c:62
#define CL_SIZE
Definition: rock.c:43
#define SL_SIZE
Definition: rock.c:52
#define RR_SIZE
Definition: rock.c:51
#define RR_CUR_USE
Definition: rock.c:86
EXPORT char * generate_rr_extension_record(char *id, char *descriptor, char *source, int *size)
Definition: rock.c:903
#define SL_PARENT
Definition: rock.c:38
#define SL_CURRENT
Definition: rock.c:39
#define ZF_SIZE
Definition: rock.c:53
#define ER_SIZE
Definition: rock.c:44
#define PN_SIZE
Definition: rock.c:47
LOCAL Uchar Rock[16384]
Definition: rock.c:94
LOCAL int gen_xa_attr(mode_t attr)
Definition: rock.c:166
#define PL_SIZE
Definition: rock.c:46
LOCAL int currlen
Definition: rock.c:98
LOCAL int ipnt
Definition: rock.c:96
#define NEED_CL
Definition: rock.h:51
#define NEED_SP
Definition: rock.h:53
#define DID_CHDIR
Definition: rock.h:54
#define NEED_CE
Definition: rock.h:52
#define NEED_RE
Definition: rock.h:49
#define NEED_PL
Definition: rock.h:50
#define offsetof(TYPE, MEMBER)
descriptor
Definition: scsi.h:3951
#define memset(x, y, z)
Definition: compat.h:39
#define EX_BAD
Definition: standard.h:62
Definition: cookie.c:202
Definition: mkisofs.h:107
unsigned int rr_attr_size
Definition: mkisofs.h:135
unsigned char * rr_attributes
Definition: mkisofs.h:134
char * name
Definition: mkisofs.h:116
unsigned int de_flags
Definition: mkisofs.h:122
struct iso_directory_record isorec
Definition: mkisofs.h:110
unsigned int total_rr_attr_size
Definition: mkisofs.h:136
Definition: parser.c:44
Definition: parser.c:49
Definition: name.c:39
Definition: stat.h:55
time_t st_ctime
Definition: stat.h:66
short st_gid
Definition: stat.h:61
unsigned short st_mode
Definition: stat.h:58
time_t st_mtime
Definition: stat.h:65
short st_uid
Definition: stat.h:60
_dev_t st_rdev
Definition: stat.h:62
time_t st_atime
Definition: stat.h:64
short st_nlink
Definition: stat.h:59
#define stat_cnsecs(s)
Definition: stat.h:395
#define stat_mnsecs(s)
Definition: stat.h:394
#define stat_ansecs(s)
Definition: stat.h:393
unsigned char Uchar
Definition: utypes.h:45
int ret