]>
Commit | Line | Data |
---|---|---|
4b4c4f64 RM |
1 | /* |
2 | * File rock.c - generate RRIP records for iso9660 filesystems. | |
3 | ||
4 | Written by Eric Youngdale (1993). | |
5 | ||
6 | Copyright 1993 Yggdrasil Computing, Incorporated | |
7 | ||
dc83dd64 RM |
8 | Copyright (C) 2009 Free Software Foundation, Inc. |
9 | ||
4b4c4f64 RM |
10 | This program is free software; you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License as published by | |
dc83dd64 | 12 | the Free Software Foundation; either version 3, or (at your option) |
4b4c4f64 RM |
13 | any later version. |
14 | ||
15 | This program is distributed in the hope that it will be useful, | |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | GNU General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU General Public License | |
dc83dd64 | 21 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
4b4c4f64 RM |
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
23 | ||
11e9a115 | 24 | static char rcsid[] ="$Id: rock.c,v 1.8 1999/03/02 03:41:26 eric Exp $"; |
4b4c4f64 RM |
25 | |
26 | #include <stdlib.h> | |
27 | ||
28 | #include "config.h" | |
29 | ||
30 | #ifndef VMS | |
31 | #if defined(MAJOR_IN_SYSMACROS) | |
32 | #include <sys/sysmacros.h> | |
33 | #endif | |
34 | ||
35 | #ifdef HAVE_UNISTD_H | |
36 | #include <unistd.h> | |
37 | #endif | |
38 | ||
39 | #endif | |
40 | #if defined(MAJOR_IN_MKDEV) | |
41 | #include <sys/types.h> | |
42 | #include <sys/mkdev.h> | |
43 | #endif | |
44 | ||
45 | #include "mkisofs.h" | |
46 | #include "iso9660.h" | |
47 | #include <string.h> | |
6e1e0d89 | 48 | #include <errno.h> |
4b4c4f64 | 49 | |
11e9a115 RM |
50 | #ifdef DOESNT_WORK |
51 | ||
4b4c4f64 RM |
52 | #ifdef NON_UNIXFS |
53 | #define S_ISLNK(m) (0) | |
54 | #else | |
55 | #ifndef S_ISLNK | |
56 | #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) | |
57 | #endif | |
58 | #endif | |
59 | ||
11e9a115 RM |
60 | #else |
61 | #include <statdefs.h> | |
62 | #endif | |
63 | ||
4b4c4f64 RM |
64 | #define SU_VERSION 1 |
65 | ||
66 | #define SL_ROOT 8 | |
67 | #define SL_PARENT 4 | |
68 | #define SL_CURRENT 2 | |
69 | #define SL_CONTINUE 1 | |
70 | ||
71 | #define CE_SIZE 28 | |
72 | #define CL_SIZE 12 | |
73 | #define ER_SIZE 8 | |
74 | #define NM_SIZE 5 | |
75 | #define PL_SIZE 12 | |
76 | #define PN_SIZE 20 | |
77 | #define PX_SIZE 36 | |
78 | #define RE_SIZE 4 | |
79 | #define SL_SIZE 20 | |
80 | #define ZZ_SIZE 15 | |
81 | #ifdef __QNX__ | |
82 | #define TF_SIZE (5 + 4 * 7) | |
83 | #else | |
84 | #define TF_SIZE (5 + 3 * 7) | |
85 | #endif | |
86 | ||
87 | /* If we need to store this number of bytes, make sure we | |
88 | do not box ourselves in so that we do not have room for | |
89 | a CE entry for the continuation record */ | |
90 | ||
91 | #define MAYBE_ADD_CE_ENTRY(BYTES) \ | |
dc83dd64 | 92 | ((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0) |
4b4c4f64 RM |
93 | |
94 | /* | |
95 | * Buffer to build RR attributes | |
96 | */ | |
97 | ||
98 | static unsigned char Rock[16384]; | |
99 | static unsigned char symlink_buff[256]; | |
100 | static int ipnt = 0; | |
101 | static int recstart = 0; | |
102 | static int currlen = 0; | |
103 | static int mainrec = 0; | |
104 | static int reclimit; | |
105 | ||
11e9a115 RM |
106 | static void add_CE_entry __PR((void)); |
107 | ||
4b4c4f64 RM |
108 | static void add_CE_entry(){ |
109 | if(recstart) | |
110 | set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart); | |
111 | Rock[ipnt++] ='C'; | |
112 | Rock[ipnt++] ='E'; | |
113 | Rock[ipnt++] = CE_SIZE; | |
114 | Rock[ipnt++] = SU_VERSION; | |
115 | set_733((char*)Rock + ipnt, 0); | |
116 | ipnt += 8; | |
117 | set_733((char*)Rock + ipnt, 0); | |
118 | ipnt += 8; | |
119 | set_733((char*)Rock + ipnt, 0); | |
120 | ipnt += 8; | |
121 | recstart = ipnt; | |
122 | currlen = 0; | |
123 | if(!mainrec) mainrec = ipnt; | |
124 | reclimit = SECTOR_SIZE - 8; /* Limit to one sector */ | |
125 | } | |
126 | ||
127 | #ifdef __STDC__ | |
128 | int generate_rock_ridge_attributes (char * whole_name, char * name, | |
129 | struct directory_entry * s_entry, | |
130 | struct stat * statbuf, | |
131 | struct stat * lstatbuf, | |
132 | int deep_opt) | |
133 | #else | |
134 | int generate_rock_ridge_attributes (whole_name, name, | |
135 | s_entry, | |
136 | statbuf, | |
137 | lstatbuf, | |
138 | deep_opt) | |
139 | char * whole_name; char * name; struct directory_entry * s_entry; | |
140 | struct stat * statbuf, *lstatbuf; | |
141 | int deep_opt; | |
142 | #endif | |
143 | { | |
144 | int flagpos, flagval; | |
145 | int need_ce; | |
146 | ||
147 | statbuf = statbuf; /* this shuts up unreferenced compiler warnings */ | |
148 | mainrec = recstart = ipnt = 0; | |
149 | reclimit = 0xf8; | |
150 | ||
11e9a115 RM |
151 | /* no need to fill in the RR stuff if we won't see the file */ |
152 | if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) | |
153 | return 0; | |
154 | ||
4b4c4f64 RM |
155 | /* Obtain the amount of space that is currently used for the directory |
156 | record. Assume max for name, since name conflicts may cause us | |
157 | to rename the file later on */ | |
158 | currlen = sizeof(s_entry->isorec); | |
159 | ||
160 | /* Identify that we are using the SUSP protocol */ | |
161 | if(deep_opt & NEED_SP){ | |
162 | Rock[ipnt++] ='S'; | |
163 | Rock[ipnt++] ='P'; | |
164 | Rock[ipnt++] = 7; | |
165 | Rock[ipnt++] = SU_VERSION; | |
166 | Rock[ipnt++] = 0xbe; | |
167 | Rock[ipnt++] = 0xef; | |
168 | Rock[ipnt++] = 0; | |
169 | }; | |
170 | ||
171 | /* First build the posix name field */ | |
172 | Rock[ipnt++] ='R'; | |
173 | Rock[ipnt++] ='R'; | |
174 | Rock[ipnt++] = 5; | |
175 | Rock[ipnt++] = SU_VERSION; | |
176 | flagpos = ipnt; | |
177 | flagval = 0; | |
178 | Rock[ipnt++] = 0; /* We go back and fix this later */ | |
179 | ||
180 | if(strcmp(name,".") && strcmp(name,"..")){ | |
181 | char * npnt; | |
182 | int remain, use; | |
183 | ||
184 | remain = strlen(name); | |
185 | npnt = name; | |
186 | ||
187 | while(remain){ | |
188 | use = remain; | |
189 | need_ce = 0; | |
190 | /* Can we fit this SUSP and a CE entry? */ | |
191 | if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { | |
192 | use = reclimit - currlen - CE_SIZE - (ipnt - recstart); | |
193 | need_ce++; | |
194 | } | |
195 | ||
196 | /* Only room for 256 per SUSP field */ | |
197 | if(use > 0xf8) use = 0xf8; | |
198 | ||
199 | /* First build the posix name field */ | |
200 | Rock[ipnt++] ='N'; | |
201 | Rock[ipnt++] ='M'; | |
202 | Rock[ipnt++] = NM_SIZE + use; | |
203 | Rock[ipnt++] = SU_VERSION; | |
204 | Rock[ipnt++] = (remain != use ? 1 : 0); | |
205 | flagval |= (1<<3); | |
206 | strncpy((char *)&Rock[ipnt], npnt, use); | |
207 | npnt += use; | |
208 | ipnt += use; | |
209 | remain -= use; | |
210 | if(remain && need_ce) add_CE_entry(); | |
211 | }; | |
212 | }; | |
213 | ||
214 | /* | |
215 | * Add the posix modes | |
216 | */ | |
217 | if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry(); | |
218 | Rock[ipnt++] ='P'; | |
219 | Rock[ipnt++] ='X'; | |
220 | Rock[ipnt++] = PX_SIZE; | |
221 | Rock[ipnt++] = SU_VERSION; | |
222 | flagval |= (1<<0); | |
223 | set_733((char*)Rock + ipnt, lstatbuf->st_mode); | |
224 | ipnt += 8; | |
225 | set_733((char*)Rock + ipnt, lstatbuf->st_nlink); | |
226 | ipnt += 8; | |
227 | set_733((char*)Rock + ipnt, lstatbuf->st_uid); | |
228 | ipnt += 8; | |
229 | set_733((char*)Rock + ipnt, lstatbuf->st_gid); | |
230 | ipnt += 8; | |
231 | ||
232 | /* | |
233 | * Check for special devices | |
234 | */ | |
235 | #ifndef NON_UNIXFS | |
236 | if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) { | |
237 | if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry(); | |
238 | Rock[ipnt++] ='P'; | |
239 | Rock[ipnt++] ='N'; | |
240 | Rock[ipnt++] = PN_SIZE; | |
241 | Rock[ipnt++] = SU_VERSION; | |
242 | flagval |= (1<<1); | |
63eb2d63 | 243 | #if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV) |
4b4c4f64 RM |
244 | set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev )); |
245 | ipnt += 8; | |
246 | set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev)); | |
247 | ipnt += 8; | |
248 | #else | |
249 | /* | |
250 | * If we don't have sysmacros.h, then we have to guess as to how | |
251 | * best to pick apart the device number for major/minor. | |
252 | * Note: this may very well be wrong for many systems, so | |
253 | * it is always best to use the major/minor macros if the | |
254 | * system supports it. | |
255 | */ | |
256 | if(sizeof(dev_t) <= 2) { | |
257 | set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8)); | |
258 | ipnt += 8; | |
259 | set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff); | |
260 | ipnt += 8; | |
261 | } | |
262 | else if(sizeof(dev_t) <= 4) { | |
263 | set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8); | |
264 | ipnt += 8; | |
265 | set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff); | |
266 | ipnt += 8; | |
267 | } | |
268 | else { | |
269 | set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16); | |
270 | ipnt += 8; | |
271 | set_733((char*)Rock + ipnt, lstatbuf->st_rdev); | |
272 | ipnt += 8; | |
273 | } | |
274 | #endif | |
275 | }; | |
276 | #endif | |
277 | /* | |
278 | * Check for and symbolic links. VMS does not have these. | |
279 | */ | |
280 | if (S_ISLNK(lstatbuf->st_mode)){ | |
281 | int lenpos, lenval, j0, j1; | |
282 | int nchar; | |
283 | unsigned char * cpnt, *cpnt1; | |
11e9a115 | 284 | nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff)); |
4b4c4f64 | 285 | symlink_buff[nchar < 0 ? 0 : nchar] = 0; |
63eb2d63 | 286 | nchar = strlen((char *) symlink_buff); |
4b4c4f64 RM |
287 | set_733(s_entry->isorec.size, 0); |
288 | cpnt = &symlink_buff[0]; | |
289 | flagval |= (1<<2); | |
290 | ||
63eb2d63 RM |
291 | if (! split_SL_field) |
292 | { | |
293 | int sl_bytes = 0; | |
294 | for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) | |
295 | { | |
296 | if (*cpnt1 == '/') | |
297 | { | |
298 | sl_bytes += 4; | |
299 | } | |
300 | else | |
301 | { | |
302 | sl_bytes += 1; | |
303 | } | |
304 | } | |
305 | if (sl_bytes > 250) | |
306 | { | |
307 | /* | |
308 | * the symbolic link won't fit into one SL System Use Field | |
309 | * print an error message and continue with splited one | |
310 | */ | |
311 | fprintf(stderr,"symbolic link ``%s'' to long for one SL System Use Field, splitting", cpnt); | |
312 | } | |
313 | if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry(); | |
314 | } | |
315 | ||
4b4c4f64 RM |
316 | while(nchar){ |
317 | if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry(); | |
318 | Rock[ipnt++] ='S'; | |
319 | Rock[ipnt++] ='L'; | |
320 | lenpos = ipnt; | |
321 | Rock[ipnt++] = SL_SIZE; | |
322 | Rock[ipnt++] = SU_VERSION; | |
323 | Rock[ipnt++] = 0; /* Flags */ | |
324 | lenval = 5; | |
325 | while(*cpnt){ | |
326 | cpnt1 = (unsigned char *) strchr((char *) cpnt, '/'); | |
327 | if(cpnt1) { | |
328 | nchar--; | |
329 | *cpnt1 = 0; | |
330 | }; | |
331 | ||
332 | /* We treat certain components in a special way. */ | |
333 | if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){ | |
334 | if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); | |
335 | Rock[ipnt++] = SL_PARENT; | |
336 | Rock[ipnt++] = 0; /* length is zero */ | |
337 | lenval += 2; | |
338 | nchar -= 2; | |
339 | } else if(cpnt[0] == '.' && cpnt[1] == 0){ | |
340 | if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); | |
341 | Rock[ipnt++] = SL_CURRENT; | |
342 | Rock[ipnt++] = 0; /* length is zero */ | |
343 | lenval += 2; | |
344 | nchar -= 1; | |
345 | } else if(cpnt[0] == 0){ | |
346 | if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); | |
347 | Rock[ipnt++] = SL_ROOT; | |
348 | Rock[ipnt++] = 0; /* length is zero */ | |
349 | lenval += 2; | |
350 | } else { | |
351 | /* If we do not have enough room for a component, start | |
352 | a new continuations segment now */ | |
63eb2d63 RM |
353 | if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) : |
354 | MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt))) | |
355 | { | |
356 | add_CE_entry(); | |
357 | if(cpnt1) | |
358 | { | |
359 | *cpnt1 = '/'; | |
360 | nchar++; | |
361 | cpnt1 = NULL; /* A kluge so that we can restart properly */ | |
362 | } | |
363 | break; | |
364 | } | |
4b4c4f64 RM |
365 | j0 = strlen((char *) cpnt); |
366 | while(j0) { | |
367 | j1 = j0; | |
368 | if(j1 > 0xf8) j1 = 0xf8; | |
369 | need_ce = 0; | |
370 | if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { | |
371 | j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart); | |
372 | need_ce++; | |
373 | } | |
374 | Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0); | |
375 | Rock[ipnt++] = j1; | |
376 | strncpy((char *) Rock + ipnt, (char *) cpnt, j1); | |
377 | ipnt += j1; | |
378 | lenval += j1 + 2; | |
379 | cpnt += j1; | |
380 | nchar -= j1; /* Number we processed this time */ | |
381 | j0 -= j1; | |
382 | if(need_ce) { | |
383 | add_CE_entry(); | |
384 | if(cpnt1) { | |
385 | *cpnt1 = '/'; | |
386 | nchar++; | |
387 | cpnt1 = NULL; /* A kluge so that we can restart properly */ | |
388 | } | |
389 | break; | |
390 | } | |
391 | } | |
392 | }; | |
393 | if(cpnt1) { | |
394 | cpnt = cpnt1 + 1; | |
395 | } else | |
396 | break; | |
397 | } | |
398 | Rock[lenpos] = lenval; | |
399 | if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */ | |
400 | } /* while nchar */ | |
401 | } /* Is a symbolic link */ | |
402 | /* | |
403 | * Add in the Rock Ridge TF time field | |
404 | */ | |
405 | if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry(); | |
406 | Rock[ipnt++] ='T'; | |
407 | Rock[ipnt++] ='F'; | |
408 | Rock[ipnt++] = TF_SIZE; | |
409 | Rock[ipnt++] = SU_VERSION; | |
410 | #ifdef __QNX__ | |
411 | Rock[ipnt++] = 0x0f; | |
412 | #else | |
413 | Rock[ipnt++] = 0x0e; | |
414 | #endif | |
415 | flagval |= (1<<7); | |
416 | #ifdef __QNX__ | |
417 | iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime); | |
418 | ipnt += 7; | |
419 | #endif | |
420 | iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime); | |
421 | ipnt += 7; | |
422 | iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime); | |
423 | ipnt += 7; | |
424 | iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime); | |
425 | ipnt += 7; | |
426 | ||
427 | /* | |
428 | * Add in the Rock Ridge RE time field | |
429 | */ | |
430 | if(deep_opt & NEED_RE){ | |
431 | if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry(); | |
432 | Rock[ipnt++] ='R'; | |
433 | Rock[ipnt++] ='E'; | |
434 | Rock[ipnt++] = RE_SIZE; | |
435 | Rock[ipnt++] = SU_VERSION; | |
436 | flagval |= (1<<6); | |
437 | }; | |
438 | /* | |
439 | * Add in the Rock Ridge PL record, if required. | |
440 | */ | |
441 | if(deep_opt & NEED_PL){ | |
442 | if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry(); | |
443 | Rock[ipnt++] ='P'; | |
444 | Rock[ipnt++] ='L'; | |
445 | Rock[ipnt++] = PL_SIZE; | |
446 | Rock[ipnt++] = SU_VERSION; | |
447 | set_733((char*)Rock + ipnt, 0); | |
448 | ipnt += 8; | |
449 | flagval |= (1<<5); | |
450 | }; | |
451 | ||
452 | /* | |
453 | * Add in the Rock Ridge CL field, if required. | |
454 | */ | |
455 | if(deep_opt & NEED_CL){ | |
456 | if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry(); | |
457 | Rock[ipnt++] ='C'; | |
458 | Rock[ipnt++] ='L'; | |
459 | Rock[ipnt++] = CL_SIZE; | |
460 | Rock[ipnt++] = SU_VERSION; | |
461 | set_733((char*)Rock + ipnt, 0); | |
462 | ipnt += 8; | |
463 | flagval |= (1<<4); | |
464 | }; | |
465 | ||
466 | #ifndef VMS | |
467 | /* If transparent compression was requested, fill in the correct | |
468 | field for this file */ | |
469 | if(transparent_compression && | |
470 | S_ISREG(lstatbuf->st_mode) && | |
471 | strlen(name) > 3 && | |
472 | strcmp(name + strlen(name) - 3,".gZ") == 0){ | |
473 | FILE * zipfile; | |
474 | char * checkname; | |
475 | unsigned int file_size; | |
476 | unsigned char header[8]; | |
477 | int OK_flag; | |
478 | ||
479 | /* First open file and verify that the correct algorithm was used */ | |
480 | file_size = 0; | |
481 | OK_flag = 1; | |
482 | ||
11e9a115 | 483 | zipfile = fopen(whole_name, "rb"); |
6e1e0d89 RM |
484 | if (fread (header, 1, sizeof (header), zipfile) != sizeof(header)) |
485 | error (1, errno, "fread"); | |
4b4c4f64 RM |
486 | |
487 | /* Check some magic numbers from gzip. */ | |
488 | if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0; | |
489 | /* Make sure file was blocksized. */ | |
490 | if(((header[3] & 0x40) == 0)) OK_flag = 0; | |
491 | /* OK, now go to the end of the file and get some more info */ | |
492 | if(OK_flag){ | |
493 | int status; | |
494 | status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END); | |
495 | if(status == -1) OK_flag = 0; | |
496 | } | |
497 | if(OK_flag){ | |
498 | if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header)) | |
499 | OK_flag = 0; | |
500 | else { | |
501 | int blocksize; | |
502 | blocksize = (header[3] << 8) | header[2]; | |
503 | file_size = ((unsigned int)header[7] << 24) | | |
504 | ((unsigned int)header[6] << 16) | | |
505 | ((unsigned int)header[5] << 8) | header[4]; | |
506 | #if 0 | |
507 | fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size); | |
508 | #endif | |
509 | if(blocksize != SECTOR_SIZE) OK_flag = 0; | |
510 | } | |
511 | } | |
512 | fclose(zipfile); | |
513 | ||
514 | checkname = strdup(whole_name); | |
515 | checkname[strlen(whole_name)-3] = 0; | |
11e9a115 | 516 | zipfile = fopen(checkname, "rb"); |
4b4c4f64 RM |
517 | if(zipfile) { |
518 | OK_flag = 0; | |
519 | fprintf(stderr,"Unable to insert transparent compressed file - name conflict\n"); | |
520 | fclose(zipfile); | |
521 | } | |
522 | ||
523 | free(checkname); | |
524 | ||
525 | if(OK_flag){ | |
526 | if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry(); | |
527 | Rock[ipnt++] ='Z'; | |
528 | Rock[ipnt++] ='Z'; | |
529 | Rock[ipnt++] = ZZ_SIZE; | |
530 | Rock[ipnt++] = SU_VERSION; | |
531 | Rock[ipnt++] = 'g'; /* Identify compression technique used */ | |
532 | Rock[ipnt++] = 'z'; | |
533 | Rock[ipnt++] = 3; | |
534 | set_733((char*)Rock + ipnt, file_size); /* Real file size */ | |
535 | ipnt += 8; | |
536 | }; | |
537 | } | |
538 | #endif | |
539 | /* | |
540 | * Add in the Rock Ridge CE field, if required. We use this for the | |
541 | * extension record that is stored in the root directory. | |
542 | */ | |
543 | if(deep_opt & NEED_CE) add_CE_entry(); | |
544 | /* | |
545 | * Done filling in all of the fields. Now copy it back to a buffer for the | |
546 | * file in question. | |
547 | */ | |
548 | ||
549 | /* Now copy this back to the buffer for the file */ | |
550 | Rock[flagpos] = flagval; | |
551 | ||
552 | /* If there was a CE, fill in the size field */ | |
553 | if(recstart) | |
554 | set_733((char*)Rock + recstart - 8, ipnt - recstart); | |
555 | ||
556 | s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt); | |
557 | s_entry->total_rr_attr_size = ipnt; | |
558 | s_entry->rr_attr_size = (mainrec ? mainrec : ipnt); | |
559 | memcpy(s_entry->rr_attributes, Rock, ipnt); | |
560 | return ipnt; | |
561 | } | |
562 | ||
563 | /* Guaranteed to return a single sector with the relevant info */ | |
564 | ||
565 | char * FDECL4(generate_rr_extension_record, char *, id, char *, descriptor, | |
566 | char *, source, int *, size){ | |
11e9a115 | 567 | int lipnt = 0; |
4b4c4f64 RM |
568 | char * pnt; |
569 | int len_id, len_des, len_src; | |
570 | ||
571 | len_id = strlen(id); | |
572 | len_des = strlen(descriptor); | |
573 | len_src = strlen(source); | |
11e9a115 RM |
574 | Rock[lipnt++] ='E'; |
575 | Rock[lipnt++] ='R'; | |
576 | Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src; | |
577 | Rock[lipnt++] = 1; | |
578 | Rock[lipnt++] = len_id; | |
579 | Rock[lipnt++] = len_des; | |
580 | Rock[lipnt++] = len_src; | |
581 | Rock[lipnt++] = 1; | |
4b4c4f64 | 582 | |
11e9a115 RM |
583 | memcpy(Rock + lipnt, id, len_id); |
584 | lipnt += len_id; | |
4b4c4f64 | 585 | |
11e9a115 RM |
586 | memcpy(Rock + lipnt, descriptor, len_des); |
587 | lipnt += len_des; | |
4b4c4f64 | 588 | |
11e9a115 RM |
589 | memcpy(Rock + lipnt, source, len_src); |
590 | lipnt += len_src; | |
4b4c4f64 | 591 | |
11e9a115 | 592 | if(lipnt > SECTOR_SIZE) { |
4b4c4f64 RM |
593 | fprintf(stderr,"Extension record too long\n"); |
594 | exit(1); | |
595 | }; | |
596 | pnt = (char *) e_malloc(SECTOR_SIZE); | |
597 | memset(pnt, 0, SECTOR_SIZE); | |
11e9a115 RM |
598 | memcpy(pnt, Rock, lipnt); |
599 | *size = lipnt; | |
4b4c4f64 RM |
600 | return pnt; |
601 | } |