"Fossies" - the Fresh Open Source Software Archive 
Member "libisoburn-1.5.4/xorriso/cmp_update.c" (8 Jul 2020, 33762 Bytes) of package /linux/misc/libisoburn-1.5.4.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "cmp_update.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.5.0_vs_1.5.2.
1
2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
3
4 Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
5
6 Provided under GPL version 2 or later.
7
8 This file contains the implementation of actions which compare or update
9 files between disk filesystem and ISO filesystem.
10 */
11
12 #ifdef HAVE_CONFIG_H
13 #include "../config.h"
14 #endif
15
16 #include <ctype.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/time.h>
24 #include <time.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <pwd.h>
28 #include <grp.h>
29
30 /* O_BINARY is needed for Cygwin but undefined elsewhere */
31 #ifndef O_BINARY
32 #define O_BINARY 0
33 #endif
34
35 #include "xorriso.h"
36 #include "xorriso_private.h"
37 #include "xorrisoburn.h"
38
39
40 /*
41 @param result Bitfield indicationg type of mismatch
42 bit11= cannot open regular disk file
43 bit12= cannot open iso file
44 bit13= early eof of disk file
45 bit14= early eof of iso file
46 bit15= content bytes differ
47 @param flag bit0= mtimes of both file objects are equal
48 bit29= do not issue pacifier messages
49 bit31= do not issue result messages
50 @return >0 ok , <=0 error
51 */
52 int Xorriso_compare_2_contents(struct XorrisO *xorriso, char *common_adr,
53 char *disk_adr, off_t disk_size,
54 off_t offset, off_t bytes,
55 char *iso_adr, off_t iso_size,
56 int *result, int flag)
57 {
58 int fd1= -1, ret, r1, r2, done, wanted, i, was_error= 0, use_md5= 0;
59 void *stream2= NULL;
60 off_t r1count= 0, r2count= 0, diffcount= 0, first_diff= -1;
61 char *respt, *buf1= NULL, *buf2= NULL, offset_text[80];
62 char disk_md5[16], iso_md5[16];
63 void *ctx= NULL;
64 int buf_size= 32 * 1024;
65 double dcount;
66
67 Xorriso_alloc_meM(buf1, char, buf_size);
68 Xorriso_alloc_meM(buf2, char, buf_size);
69
70 respt= xorriso->result_line;
71
72 fd1= open(disk_adr, O_RDONLY | O_BINARY);
73 if(fd1==-1) {
74 sprintf(respt, "- %s (DISK) : cannot open() : %s\n",
75 disk_adr, strerror(errno));
76 cannot_address:;
77 if(!(flag&(1u<<31)))
78 Xorriso_result(xorriso,0);
79 (*result)|= 2048;
80 {ret= 0; goto ex;}
81 }
82 if(offset>0)
83 if(lseek(fd1, offset, SEEK_SET)==-1) {
84 sprintf(respt, "- %s (DISK) : cannot lseek(%.f) : %s\n",
85 disk_adr, (double) offset, strerror(errno));
86 close(fd1);
87 goto cannot_address;
88 }
89
90 if(xorriso->do_md5 & 16) {
91 use_md5= 1;
92 ret= Xorriso_is_plain_image_file(xorriso, NULL, iso_adr, 0);
93 if(ret <= 0)
94 ret= 0; /* (reverse) filtered files are likely not to match their MD5 */
95 else
96 ret= Xorriso_get_md5(xorriso, NULL, iso_adr, iso_md5, 1);
97 if(ret <= 0)
98 use_md5= 0;
99 else {
100 ret= Xorriso_md5_start(xorriso, &ctx, 0);
101 if(ret <= 0)
102 use_md5= 0;
103 }
104 }
105 if (! use_md5) {
106 ret= Xorriso_iso_file_open(xorriso, iso_adr, NULL, &stream2, 0);
107 if(ret<=0) {
108 sprintf(respt, "- %s (ISO) : cannot open() file in ISO image\n",iso_adr);
109 if(!(flag&(1u<<31)))
110 Xorriso_result(xorriso,0);
111 close(fd1);
112 (*result)|= 4096;
113 {ret= 0; goto ex;}
114 }
115 }
116
117 done= 0;
118 while(!done) {
119
120 wanted= buf_size;
121 if(r1count+offset+wanted>disk_size)
122 wanted= disk_size-r1count-offset;
123 if(r1count+wanted>bytes)
124 wanted= bytes-r1count;
125 r1= 0;
126 while(wanted>0) {
127 ret= read(fd1, buf1, wanted);
128 if(ret<=0)
129 break;
130 wanted-= ret;
131 r1+= ret;
132 }
133
134 wanted= buf_size;
135 if(r2count+wanted>iso_size)
136 wanted= iso_size-r2count;
137 /*
138 if(r2count+wanted>bytes)
139 wanted= bytes-r2count;
140 */
141 if(use_md5)
142 r2= r1;
143 else if(wanted>0)
144 r2= Xorriso_iso_file_read(xorriso, stream2, buf2, wanted, 0);
145 else
146 r2= 0;
147
148 if(r1<0 || r2<0)
149 was_error= 1;
150
151 if(r1<=0 && r2<=0)
152 break;
153 if(r1<=0) {
154 if(r1<0)
155 r1= 0;
156 if(disk_size > r1count + r1 + offset) {
157 sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n",
158 disk_adr, (double) r1count);
159 if(!(flag&(1u<<31)))
160 Xorriso_result(xorriso,0);
161 (*result)|= 8196;
162 }
163 (*result)|= (1<<15);
164 }
165 r1count+= r1;
166 if(r2<=0 || r2<r1) {
167 if(r2<0)
168 r2= 0;
169 if(iso_size > r2count + r2) {
170 sprintf(respt, "- %s (ISO) : early EOF after %.f bytes\n",
171 iso_adr, (double) r2count);
172 if(!(flag&(1u<<31)))
173 Xorriso_result(xorriso,0);
174 (*result)|= (1<<14);
175 }
176 (*result)|= (1<<15);
177 done= 1;
178 }
179 if(r2>r1) {
180 if(disk_size > r1count + r1 + offset) {
181 sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n",
182 disk_adr, (double) r1count);
183 if(!(flag&(1u<<31)))
184 Xorriso_result(xorriso,0);
185 (*result)|= 8196;
186 }
187 (*result)|= (1<<15);
188 done= 1;
189 }
190 r2count+= r2;
191 if(r1>r2)
192 r1= r2;
193
194 if(use_md5) {
195 Xorriso_md5_compute(xorriso, ctx, buf1, r1, 0);
196 } else {
197 for(i= 0; i<r1; i++) {
198 if(buf1[i]!=buf2[i]) {
199 if(first_diff<0)
200 first_diff= r1count - r1 + i;
201 diffcount++;
202 }
203 }
204 }
205 if(!(flag&(1<<29))) {
206 xorriso->pacifier_count+= r1;
207 xorriso->pacifier_byte_count+= r1;
208 if(flag&(1u<<31))
209 Xorriso_pacifier_callback(xorriso, "content bytes read",
210 xorriso->pacifier_count, 0, "", 8);
211 else
212 Xorriso_pacifier_callback(xorriso, "bytes", xorriso->pacifier_count, 0,
213 "", 8 | 1<<6);
214 }
215 }
216
217 if(use_md5) {
218 ret= Xorriso_md5_end(xorriso, &ctx, disk_md5, 0);
219 if(ret <= 0) {
220 *result |= (1 << 15);
221 ret= -1; goto ex;
222 }
223 for(i= 0; i < 16; i++)
224 if(iso_md5[i] != disk_md5[i])
225 break;
226 if(i < 16 ) {
227 offset_text[0]= 0;
228 if(offset>0)
229 sprintf(offset_text, "%.f+", (double) offset);
230 sprintf(respt, "%s %s : differs by MD5 sums.\n",
231 common_adr, (flag&1 ? "CONTENT": "content"));
232 if(!(flag&(1u<<31)))
233 Xorriso_result(xorriso,0);
234 (*result)|= (1<<15);
235 }
236 } else if(diffcount>0 || r1count!=r2count) {
237 if(first_diff<0)
238 first_diff= (r1count>r2count ? r2count : r1count);
239 offset_text[0]= 0;
240 if(offset>0)
241 sprintf(offset_text, "%.f+", (double) offset);
242 if(r1count > r2count)
243 dcount= diffcount + (r1count - r2count);
244 else
245 dcount= diffcount + (r2count - r1count);
246 sprintf(respt, "%s %s : differs by at least %.f bytes. First at %s%.f\n",
247 common_adr, (flag&1 ? "CONTENT": "content"),
248 dcount, offset_text, (double) first_diff);
249 if(!(flag&(1u<<31)))
250 Xorriso_result(xorriso,0);
251 (*result)|= (1<<15);
252 }
253 if(fd1!=-1)
254 close(fd1);
255 if(! use_md5)
256 Xorriso_iso_file_close(xorriso, &stream2, 0);
257 if(was_error)
258 {ret= -1; goto ex;}
259 ret= 1;
260 ex:;
261 if(ctx != NULL)
262 Xorriso_md5_end(xorriso, &ctx, disk_md5, 0);
263 Xorriso_free_meM(buf1);
264 Xorriso_free_meM(buf2);
265 return(ret);
266 }
267
268
269 /*
270 @param result Bitfield indicationg type of mismatch
271 bit0= disk_adr not existing
272 bit1= iso_adr not existing
273 bit2= access permissions
274 bit3= file type
275 bit4= user id
276 bit5= group id
277 bit6= minor, major with device file
278 bit7= size
279 bit8= mtime
280 bit9= atime
281 bit10= ctime
282 bit11= cannot open regular disk file
283 bit12= cannot open iso file
284 bit13= early eof of disk file
285 bit14= early eof of iso file
286 bit15= content bytes differ
287 bit16= symbolic link on disk pointing to dir, dir in iso
288 bit17= file chunks detected and compared
289 bit18= incomplete chunk collection encountered
290 bit19= ACL differs (this condition sets also bit2)
291 bit20= xattr differ
292 bit21= mismatch of recorded dev,inode
293 bit22= no recorded dev,inode found in node
294 bit23= timestamps younger than xorriso->isofs_st_in
295 bit24= hardlink split
296 bit25= hardlink fusion
297 @param flag bit0= compare atime
298 bit1= compare ctime
299 bit2= check only existence of both file objects
300 count one or both missing as "difference"
301 bit26= do not issue message about missing disk file
302 bit27= for Xorriso_path_is_excluded(): bit0
303 bit28= examine eventual disk_path link target rather than link
304 bit29= do not issue pacifier messages
305 bit30= omit adr_common_tail in report messages
306 bit31= do not issue result messages
307 @return 1=files match properly , 0=difference detected , -1=error
308 */
309 int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
310 char *iso_adr, char *adr_common_tail,
311 int *result, int flag)
312 {
313 struct stat s1, s2, stbuf;
314 int ret, missing= 0, is_split= 0, i, was_error= 0, diff_count= 0;
315 int content_shortcut= 0, mask;
316 char *respt;
317 char *a= NULL;
318 char ttx1[40], ttx2[40];
319 char *a1_acl= NULL, *a2_acl= NULL, *d1_acl= NULL, *d2_acl= NULL;
320 char *attrlist1= NULL, *attrlist2= NULL;
321 struct SplitparT *split_parts= NULL;
322 int split_count= 0;
323 time_t stamp;
324
325 char *part_path= NULL, *part_name;
326 int partno, total_parts= 0;
327 off_t offset, bytes, total_bytes;
328
329 Xorriso_alloc_meM(a, char, 5*SfileadrL);
330 Xorriso_alloc_meM(part_path, char, SfileadrL);
331
332 *result= 0;
333 respt= xorriso->result_line;
334
335 if(!(xorriso->disk_excl_mode&8)) {
336 ret= Xorriso_path_is_excluded(xorriso, disk_adr, 2 | !!(flag&(1<<27)));
337 if(ret>0) {
338 strcpy(respt, "? ");
339 Text_shellsafe(disk_adr, respt, 1);
340 sprintf(respt + strlen(respt), " (DISK) : excluded by %s\n",
341 (ret==1 ? "-not_paths" : "-not_leaf"));
342 if(! (flag & ((1u << 31) | (1 << 26))))
343 Xorriso_result(xorriso,0);
344 missing= 1;
345 (*result)|= 1;
346 }
347 }
348 if(!missing) {
349 if(flag&(1<<28))
350 ret= stat(disk_adr, &s1);
351 else
352 ret= lstat(disk_adr, &s1);
353 if(ret==-1) {
354 strcpy(respt, "? ");
355 Text_shellsafe(disk_adr, respt, 1);
356 sprintf(respt + strlen(respt),
357 " (DISK) : cannot lstat() : %s\n", strerror(errno));
358 if(! (flag & ((1u << 31) | (1 << 26))))
359 Xorriso_result(xorriso,0);
360 missing= 1;
361 (*result)|= 1;
362 }
363 }
364 if(missing)
365 strcpy(a, "?");
366 else
367 strcpy(a, Ftypetxt(s1.st_mode, 1));
368 strcat(a, " ");
369 if(adr_common_tail[0])
370 Text_shellsafe(adr_common_tail, a, 1);
371 else {
372 Text_shellsafe(disk_adr, a+strlen(a), 0);
373 strcat(a, " (DISK)");
374 /*
375 strcat(a, "'.'");
376 */
377 }
378 strcat(a, " :");
379 if(flag&(1<<30))
380 a[0]= 0;
381
382 ret= Xorriso_iso_lstat(xorriso, iso_adr, &s2, 0);
383 if(ret<0) {
384 strcpy(respt, "? ");
385 Text_shellsafe(iso_adr, respt, 1);
386 strcat(respt, " (ISO) : cannot find this file in ISO image\n");
387 if(!(flag&(1u<<31)))
388 Xorriso_result(xorriso,0);
389 missing= 1;
390 (*result)|= 2;
391 }
392
393 if((flag&4)||missing)
394 {ret= !missing; goto ex;}
395
396
397 /* Splitfile parts */
398 if((S_ISREG(s1.st_mode) || S_ISBLK(s1.st_mode)) && S_ISDIR(s2.st_mode)) {
399 is_split= Xorriso_identify_split(xorriso, iso_adr, NULL, &split_parts,
400 &split_count, &s2, 0);
401 if(is_split>0)
402 (*result)|= (1<<17);
403 else
404 is_split= 0;
405 }
406
407 /* Attributes */
408 if(s1.st_mode != s2.st_mode) {
409 if((s1.st_mode&~S_IFMT)!=(s2.st_mode&~S_IFMT)) {
410 sprintf(respt, "%s st_mode : %7.7o <> %7.7o\n",
411 a, (unsigned int) (s1.st_mode & ~S_IFMT),
412 (unsigned int) (s2.st_mode & ~S_IFMT));
413 if(!(flag&(1u<<31)))
414 Xorriso_result(xorriso,0);
415 (*result)|= 4;
416 }
417
418 if((s1.st_mode&S_IFMT)!=(s2.st_mode&S_IFMT)) {
419 sprintf(respt, "%s type : %s <> %s\n",
420 a, Ftypetxt(s1.st_mode, 0), Ftypetxt(s2.st_mode, 0));
421 if(!(flag&(1u<<31)))
422 Xorriso_result(xorriso,0);
423 (*result)|= 8;
424 if((s1.st_mode&S_IFMT) == S_IFLNK) {
425 /* check whether link target type matches */
426 ret= stat(disk_adr, &stbuf);
427 if(ret!=-1)
428 if(S_ISDIR(stbuf.st_mode) && S_ISDIR(s2.st_mode))
429 (*result)|= (1<<16);
430 }
431 }
432 }
433
434 /* ACL */
435 if(xorriso->do_aaip & 3) {
436 Xorriso_local_getfacl(xorriso, disk_adr, &a1_acl,
437 16 | ((flag & (1 << 28)) >> 23));
438 if(S_ISDIR(s1.st_mode))
439 Xorriso_local_getfacl(xorriso, disk_adr, &d1_acl, 1);
440 ret= Xorriso_getfacl(xorriso, NULL, iso_adr, &a2_acl, 1 | 4 | 16);
441 if(ret < 0)
442 goto ex;
443 if(S_ISDIR(s1.st_mode)) {
444 ret= Xorriso_getfacl(xorriso, NULL, iso_adr, &d2_acl, 1 | 8);
445 if(ret < 0)
446 goto ex;
447 }
448 ret= Compare_text_lines(a1_acl, a2_acl, &diff_count, 0);
449 if(ret < 0)
450 goto ex;
451 if(ret == 0)
452 (*result)|= 4 | (1 << 19);
453 ret= Compare_text_lines(d1_acl, d2_acl, &diff_count, 1);
454 if(ret < 0)
455 goto ex;
456 if(ret == 0)
457 (*result)|= 4 | (1 << 19);
458 if((*result) & (1 << 19)) {
459 sprintf(respt, "%s ACL : %d difference%s\n",
460 a, diff_count, diff_count == 1 ? "" : "s");
461 if(!(flag&(1u<<31)))
462 Xorriso_result(xorriso,0);
463 }
464 }
465
466 /* xattr */
467 if(xorriso->do_aaip & 12) {
468 ret= Xorriso_getfattr(xorriso, NULL, disk_adr, &attrlist1,
469 1 | 2 | ((flag & (1 << 28)) >> 23));
470 if(ret < 0)
471 goto ex;
472 ret= Xorriso_getfattr(xorriso, NULL, iso_adr, &attrlist2, 1);
473 if(ret < 0)
474 goto ex;
475 ret= Compare_text_lines(attrlist1, attrlist2, &diff_count, 0);
476 if(ret < 0)
477 goto ex;
478 if(ret == 0) {
479 (*result)|= (1 << 20);
480 sprintf(respt, "%s xattr : %d difference%s\n",
481 a, diff_count, diff_count == 1 ? "" : "s");
482 if(!(flag&(1u<<31)))
483 Xorriso_result(xorriso,0);
484 }
485 }
486
487 if(s1.st_uid != s2.st_uid) {
488 sprintf(respt, "%s st_uid : %lu <> %lu\n", a,
489 (unsigned long) s1.st_uid, (unsigned long) s2.st_uid);
490 if(!(flag&(1u<<31)))
491 Xorriso_result(xorriso,0);
492 (*result)|= 16;
493 }
494 if(s1.st_gid != s2.st_gid) {
495 sprintf(respt, "%s st_gid : %lu <> %lu\n", a,
496 (unsigned long) s1.st_gid, (unsigned long) s2.st_gid);
497 if(!(flag&(1u<<31)))
498 Xorriso_result(xorriso,0);
499 (*result)|= 32;
500 }
501 if((S_ISCHR(s1.st_mode) && S_ISCHR(s2.st_mode)) ||
502 (S_ISBLK(s1.st_mode) && S_ISBLK(s2.st_mode))) {
503 if(s1.st_rdev != s2.st_rdev) {
504 sprintf(respt, "%s %s st_rdev : %lu <> %lu\n", a,
505 (S_ISCHR(s1.st_mode) ? "S_IFCHR" : "S_IFBLK"),
506 (unsigned long) s1.st_rdev, (unsigned long) s1.st_rdev);
507 if(!(flag&(1u<<31)))
508 Xorriso_result(xorriso,0);
509 (*result)|= 64;
510 }
511 }
512 if((!(xorriso->do_aaip & 32)) &&
513 S_ISREG(s2.st_mode) && s1.st_size != s2.st_size) {
514 sprintf(respt, "%s st_size : %.f <> %.f diff= %.f\n",
515 a, (double) s1.st_size, (double) s2.st_size,
516 ((double) s1.st_size) - (double) s2.st_size);
517 if(!(flag&(1u<<31)))
518 Xorriso_result(xorriso,0);
519 (*result)|= 128;
520 }
521 if(s1.st_mtime != s2.st_mtime) {
522 sprintf(respt, "%s st_mtime : %s <> %s diff= %.f s\n",
523 a, Ftimetxt(s1.st_mtime, ttx1, 0),
524 Ftimetxt(s2.st_mtime, ttx2, 0),
525 ((double) s1.st_mtime) - (double) s2.st_mtime);
526 if(!(flag&(1u<<31)))
527 Xorriso_result(xorriso,0);
528 (*result)|= 256;
529 }
530 if(flag&1) {
531 if(s1.st_atime != s2.st_atime) {
532 sprintf(respt, "%s st_atime : %s <> %s diff= %.f s\n",
533 a, Ftimetxt(s1.st_atime, ttx1, 0),
534 Ftimetxt(s2.st_atime, ttx2, 0),
535 ((double) s1.st_atime) - (double) s2.st_atime);
536 if(!(flag&(1u<<31)))
537 Xorriso_result(xorriso,0);
538 (*result)|= 512;
539 }
540 }
541 if(flag&2) {
542 if(s1.st_ctime != s2.st_ctime) {
543 sprintf(respt, "%s st_ctime : %s <> %s diff= %.f s\n",
544 a, Ftimetxt(s1.st_ctime, ttx1, 0),
545 Ftimetxt(s2.st_ctime, ttx2, 0),
546 ((double) s1.st_ctime) - (double) s2.st_ctime);
547 if(!(flag&(1u<<31)))
548 Xorriso_result(xorriso,0);
549 (*result)|= 1024;
550 }
551 }
552 if(xorriso->isofs_st_in > 0 &&
553 (xorriso->isofs_st_in <= s2.st_mtime ||
554 ((flag & 1) && xorriso->isofs_st_in <= s2.st_atime) ||
555 ((flag & 2) && xorriso->isofs_st_in <= s2.st_ctime)))
556 (*result)|= 1 << 23;
557
558 if((xorriso->do_aaip & 32) || !(xorriso->ino_behavior & 2)) {
559 /* dev,inode comparison.
560 For skipping content comparison or for hardlink detection.
561 */
562 ret= Xorriso_record_dev_inode(xorriso, "", s1.st_dev, s1.st_ino, NULL,
563 iso_adr, 1 | 2 | ((flag & (1 << 28)) >> 23) | (xorriso->do_aaip & 128));
564 if(ret < 0) {
565 ret= -1; goto ex;
566 } else if(ret == 0) { /* match */
567 if((xorriso->do_aaip & 64) && S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)){
568 if(xorriso->do_aaip & 32)
569 content_shortcut= 1;
570 if((*result) & (8 | 128 | 256 | 512 | 1024 | (1 << 23))) {
571 (*result)|= (1 << 15); /* content bytes differ */
572 if(((*result) & (1 << 23)) &&
573 !((*result) & (8 | 128 | 256 | 512 | 1024))) {
574 sprintf(respt,
575 "%s content : node timestamp younger than image timestamp\n", a);
576 if((xorriso->do_aaip & 32) && !(flag&(1u<<31)))
577 Xorriso_result(xorriso,0);
578 stamp= s2.st_mtime;
579 if((flag & 1) && s2.st_atime >= stamp)
580 stamp= s2.st_atime;
581 if((flag & 2) && s2.st_ctime >= stamp)
582 stamp= s2.st_ctime;
583 sprintf(respt, "%s content : %s > %s diff= %.f s\n",
584 a, Ftimetxt(stamp, ttx1, 3 << 1),
585 Ftimetxt(xorriso->isofs_st_in, ttx2, 3 << 1),
586 ((double) stamp) - (double) xorriso->isofs_st_in);
587 if((xorriso->do_aaip & 32) && !(flag&(1u<<31)))
588 Xorriso_result(xorriso,0);
589 }
590 sprintf(respt,
591 "%s content : assuming inequality due to size or timestamps\n", a);
592 if((xorriso->do_aaip & 32) && !(flag&(1u<<31)))
593 Xorriso_result(xorriso,0);
594 }
595 }
596 } else if(ret == 1) { /* mismatch */
597 (*result)|= (1 << 21);
598 sprintf(respt, "%s dev_ino : differing\n", a);
599 if((xorriso->do_aaip & 32) && !(flag&(1u<<31)))
600 Xorriso_result(xorriso,0);
601
602 if((xorriso->do_aaip & 64) && S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)){
603 if(xorriso->do_aaip & 32)
604 content_shortcut= 1;
605 (*result)|= (1 << 15); /* content bytes differ */
606 sprintf(respt,
607 "%s content : assuming inequality after dev_ino mismatch\n", a);
608 if((xorriso->do_aaip & 32) && !(flag&(1u<<31)))
609 Xorriso_result(xorriso,0);
610 }
611 } else {
612 sprintf(respt, "%s dev_ino : no dev_ino stored with image node\n", a);
613 if((xorriso->do_aaip & 32) && !(flag&(1u<<31)))
614 Xorriso_result(xorriso,0);
615 (*result)|= (1 << 22);
616 }
617 }
618
619 if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode) && !content_shortcut) {
620 /* Content */
621 if(is_split) {
622 for(i= 0; i<split_count; i++) {
623 Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
624 &offset, &bytes, &total_bytes, 0);
625 strcpy(part_path, iso_adr);
626 if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
627 Xorriso_much_too_long(xorriso, strlen(iso_adr)+strlen(part_name)+1,
628 2);
629 {ret= -1; goto ex;}
630 }
631 ret= Xorriso_iso_lstat(xorriso, part_path, &stbuf, 0);
632 if(ret<0)
633 continue;
634 ret= Xorriso_compare_2_contents(xorriso, a, disk_adr, s1.st_size,
635 offset, bytes,
636 part_path, stbuf.st_size, result,
637 (s1.st_mtime==s2.st_mtime) | (flag&((1<<29)|(1u<<31))));
638 if(ret<0)
639 was_error= 1;
640 }
641 if(total_parts>0 && split_count!=total_parts) {
642 sprintf(xorriso->info_text,
643 "- %s/* (ISO) : Not all split parts present (%d of %d)\n",
644 iso_adr, split_count, total_parts);
645 if(!(flag&(1u<<31)))
646 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 1);
647 (*result)|= 1<<18;
648 }
649 } else {
650 ret= Xorriso_compare_2_contents(xorriso, a, disk_adr, s1.st_size,
651 (off_t) 0, s1.st_size,
652 iso_adr, s2.st_size, result,
653 (s1.st_mtime==s2.st_mtime) | (flag&((1<<29)|(1u<<31))));
654 if(ret<0)
655 was_error= 1;
656 }
657
658 }
659 if(was_error)
660 ret= -1;
661 else {
662 mask= ~((1 << 17) | (1 << 18) | (1 << 22) | (1 << 23));
663 if(xorriso->do_aaip & 32)
664 mask|= 1 << 22;
665 ret= (((*result) & mask)==0);
666 }
667 ex:;
668 if(split_parts!=NULL)
669 Splitparts_destroy(&split_parts, split_count, 0);
670 Xorriso_local_getfacl(xorriso, disk_adr, &a1_acl, 1 << 15);
671 Xorriso_local_getfacl(xorriso, disk_adr, &d1_acl, 1 << 15);
672 if(a2_acl != NULL)
673 free(a2_acl);
674 if(d2_acl != NULL)
675 free(d2_acl);
676 if(attrlist1 != NULL)
677 free(attrlist1);
678 if(attrlist2 != NULL)
679 free(attrlist2);
680 Xorriso_free_meM(part_path);
681 Xorriso_free_meM(a);
682 return(ret);
683 }
684
685
686 int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path,
687 char *iso_prefix, char *disk_prefix,
688 char disk_path[SfileadrL], int flag)
689 {
690 int ret;
691 char *adrc= NULL;
692
693 Xorriso_alloc_meM(adrc, char, SfileadrL);
694
695 if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0)
696 {ret= -1; goto ex;}
697 if(strlen(disk_prefix) + strlen(iso_path) - strlen(iso_prefix)+1 >= SfileadrL)
698 {ret= -1; goto ex;}
699 if(iso_path[strlen(iso_prefix)] == '/')
700 strcpy(adrc, iso_path + strlen(iso_prefix) + 1);
701 else
702 strcpy(adrc, iso_path + strlen(iso_prefix));
703 ret= Xorriso_make_abs_adr(xorriso, disk_prefix, adrc, disk_path, 4 | 8);
704 if(ret <= 0)
705 goto ex;
706 ret= 1;
707 ex:;
708 Xorriso_free_meM(adrc);
709 return(ret);
710 }
711
712
713 /* @param boss_iter Opaque handle to be forwarded to actions in ISO image
714 Set to NULL if calling this function from outside ISO world
715 @param flag bit0= update rather than compare
716 bit1= find[ix] is in recursion
717 bit2= update_merge : do not delete but mark visited and found
718 @return <=0 error, 1= ok , 2= iso_path was deleted
719 3=ok, do not dive into directory (e.g. because it is a split file)
720 */
721 int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter, void *node,
722 char *iso_path, char *iso_prefix, char *disk_prefix,
723 int flag)
724 {
725 int ret, result, uret, follow_links, deleted= 0;
726 char *disk_path= NULL;
727
728 Xorriso_alloc_meM(disk_path, char, SfileadrL);
729
730 ret= Xorriso_pfx_disk_path(xorriso, iso_path, iso_prefix, disk_prefix,
731 disk_path, 0);
732 if(ret <= 0)
733 goto ex;
734
735 /* compare exclusions against disk_path resp. leaf name */
736 if(xorriso->disk_excl_mode&8)
737 ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&2));
738 else
739 ret= 0;
740 if(ret<0)
741 goto ex;
742 if(ret>0)
743 {ret= 3; goto ex;}
744
745 follow_links= (xorriso->do_follow_links ||
746 (xorriso->do_follow_param && !(flag&2))) <<28;
747 ret= Xorriso_compare_2_files(xorriso, disk_path, iso_path, "", &result,
748 2 | follow_links | ((!!(flag & 4)) << 26)
749 | ((!(flag&2))<<27) | (((unsigned)(flag&1))<<31));
750 /* was once: | ((!(flag&1))<<29) */
751 if(ret<xorriso->find_compare_result)
752 xorriso->find_compare_result= ret;
753 if(flag&1) {
754 if(ret<0)
755 if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
756 goto ex;
757 if(ret > 0)
758 result= 0;
759 uret= Xorriso_update_interpreter(xorriso, boss_iter, node, result,
760 disk_path, iso_path,
761 ((flag & 2) << 1) | ((flag & 4) >> 1));
762 if(uret<=0)
763 ret= 0;
764 if(uret==2)
765 deleted= 1;
766 }
767 if(ret<0)
768 goto ex;
769 if(deleted)
770 {ret= 2; goto ex;}
771 if(result&(1<<17))
772 {ret= 3; goto ex;}
773 ex:;
774 Xorriso_free_meM(disk_path);
775 return(ret);
776 }
777
778
779 /* @param boss_iter Opaque handle to be forwarded to actions in ISO image
780 Set to NULL if calling this function from outside ISO world
781 @param flag bit0= widen hardlink sibling:
782 Do not call Xorriso_hardlink_update()
783 Overwrite exactly if normal mode would not,
784 else do nothing
785 bit1= do not delete files which are not found under
786 disk_path, but rather mark visited files and mark
787 files which were found.
788 bit2= -follow: this is not a command parameter
789 @return <=0 error, 1= ok , 2= iso_rr_path node object has been deleted ,
790 3= no action taken
791 */
792 int Xorriso_update_interpreter(struct XorrisO *xorriso,
793 void *boss_iter, void *node,
794 int compare_result, char *disk_path,
795 char *iso_rr_path, int flag)
796 {
797 int ret= 1, deleted= 0, is_split= 0, i, loop_count, late_hardlink_update= 0;
798 struct stat stbuf;
799 struct SplitparT *split_parts= NULL;
800 int split_count= 0;
801 char *part_path= NULL, *part_name;
802 int partno, total_parts, new_total_parts, added_overwrote= 0;
803 off_t offset, bytes, total_bytes, disk_size, first_bytes, du_size;
804
805 if((compare_result&3)==3) {
806 sprintf(xorriso->info_text, "Missing on disk and in ISO: disk_path ");
807 Text_shellsafe(disk_path, xorriso->info_text, 1);
808 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1);
809 xorriso->find_compare_result= -1;
810 ret= 3; goto ex;
811 }
812
813 Xorriso_alloc_meM(part_path, char, SfileadrL);
814
815 if((flag & 2) && !(compare_result & 2)) {
816 ret= Xorriso_mark_update_merge(xorriso, iso_rr_path, node,
817 !(compare_result & 1));
818 if(ret <= 0)
819 goto ex;
820 }
821 if(compare_result == 0)
822 {ret= 1; goto ex;}
823
824 if(compare_result&((1<<11)|(1<<13))) {
825 if(flag & 1)
826 {ret= 3; goto ex;}
827 /* cannot open regular disk file, early eof of disk file */
828 sprintf(xorriso->info_text, "Problems with reading disk file ");
829 Text_shellsafe(disk_path, xorriso->info_text, 1);
830 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1);
831 xorriso->find_compare_result= -1;
832 ret= 1; goto ex;
833 }
834 xorriso->info_text[0]= 0;
835 is_split= !!(compare_result & (1<<17));
836
837 if((!(xorriso->ino_behavior & 2)) && (compare_result & (2 | (3 << 21))) &&
838 !(flag & 1)) {
839 if(compare_result & 2) {
840 /* File is not yet in image */
841 late_hardlink_update= 1;
842 } else {
843 /* Hard link relation has changed resp. was not recorded. */
844 ret= Xorriso_hardlink_update(xorriso, &compare_result,
845 disk_path, iso_rr_path,
846 (flag & 4) | ((compare_result >> 21) & 2));
847 if(ret < 0)
848 goto ex;
849 if(ret == 2)
850 {ret= 1; goto ex;}
851 }
852 }
853
854 if(compare_result&(8|64)) {
855 /* file type, minor+major with device file */
856 if(flag & 1)
857 {ret= 3; goto ex;}
858 ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); /* rm_r */
859 if(ret>0) {
860 deleted= 1;
861 ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path,
862 (off_t) 0, (off_t) 0, 2|(flag&4));
863 if(ret <= 0)
864 goto ex;
865 if(flag & 2) {
866 ret= Xorriso_mark_update_merge(xorriso, iso_rr_path, NULL, 1);
867 if(ret <= 0)
868 goto ex;
869 }
870 }
871 sprintf(xorriso->info_text, "Deleted and re-added ");
872
873 } else if(compare_result&(1)) {
874 delete:;
875 /* disk_adr not existing */
876 if(!(flag & 2)) {
877 ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1);
878 deleted= 1;
879 sprintf(xorriso->info_text, "Deleted ");
880 }
881
882 } else if(compare_result&(2|128|(1<<12)|(1<<14)|(1<<15))) {
883 /* iso_adr not existing, size, cannot open iso file, early eof of iso file
884 content bytes differ */
885
886 if(flag & 1)
887 {ret= 3; goto ex;}
888 overwrite:;
889 if(is_split) {
890 ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
891 &split_parts, &split_count, &stbuf, 0);
892 if(ret<=0)
893 {ret= -1; goto ex;} /* (should not happen) */
894 ret= lstat(disk_path, &stbuf);
895 if(ret==-1)
896 goto delete;
897 disk_size= stbuf.st_size;
898 Splitparts_get(split_parts, 0, &part_name, &partno, &total_parts,
899 &offset, &first_bytes, &total_bytes, 0);
900 new_total_parts= disk_size/first_bytes;
901 if(disk_size % first_bytes)
902 new_total_parts++;
903
904 loop_count= split_count;
905 /* If disk file grew over part limit and all parts are present:
906 add new parts */
907 if(new_total_parts > total_parts && split_count == total_parts)
908 loop_count= new_total_parts;
909
910 for(i= 0; i<loop_count; i++) {
911 if(i<split_count) {
912 /* Delete old part */
913 Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
914 &offset, &bytes, &total_bytes, 0);
915 strcpy(part_path, iso_rr_path);
916 if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
917 Xorriso_much_too_long(xorriso,
918 strlen(iso_rr_path)+strlen(part_path)+1, 2);
919 {ret= -1; goto ex;}
920 }
921 ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, part_path, 1);
922 if(ret<=0)
923 goto ex;
924 deleted= 1;
925 } else {
926 partno= i+1;
927 offset= i*first_bytes;
928 bytes= first_bytes;
929 }
930 if(disk_size<=offset)
931 continue;
932 /* Insert new part */
933 if(strlen(part_path)+160>SfileadrL) {
934 Xorriso_much_too_long(xorriso, strlen(part_path)+160, 2);
935 ret= 0; goto ex;
936 }
937 Splitpart__compose(part_path+strlen(iso_rr_path)+1, partno,
938 new_total_parts, offset, first_bytes, disk_size, 0);
939 ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, part_path,
940 offset, bytes, 2|(flag&4)|8|128);
941 if(ret<=0)
942 goto ex;
943 }
944 /* Copy file attributes to iso_rr_path, augment r-perms by x-perms */
945 ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 2 | 4);
946 if(ret<=0)
947 goto ex;
948 } else {
949 ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path,
950 (off_t) 0, (off_t) 0, 2|(flag&4));
951 if(ret>0 && !(compare_result&2))
952 deleted= 1;
953 }
954 if(late_hardlink_update) {
955 /* Handle eventual hardlink siblings of newly created file */
956 ret= Xorriso_hardlink_update(xorriso, &compare_result,
957 disk_path, iso_rr_path, 1 | (flag & 4));
958 if(ret < 0)
959 goto ex;
960 }
961 if(flag & 2) {
962 ret= Xorriso_mark_update_merge(xorriso, iso_rr_path, NULL, 1);
963 if(ret <= 0)
964 goto ex;
965 }
966 if(flag & 1) {
967 sprintf(xorriso->info_text, "Widened hard link ");
968 } else {
969 sprintf(xorriso->info_text, "Added/overwrote ");
970 added_overwrote= 1;
971 }
972
973 } else if(compare_result&(4|16|32|256|512|1024|(1<<19)|(1<<20)|(1<<22))) {
974 /* access permissions, user id, group id, mtime, atime, ctime, ACL, xattr,
975 dev_ino missing */
976
977 if(flag & 1)
978 goto overwrite;
979
980 if(is_split) {
981 ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
982 &split_parts, &split_count, &stbuf, 0);
983 if(ret<=0)
984 {ret= -1; goto ex;} /* (should not happen) */
985 for(i= 0; i<split_count; i++) {
986 Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
987 &offset, &bytes, &total_bytes, 0);
988 strcpy(part_path, iso_rr_path);
989 if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
990 Xorriso_much_too_long(xorriso,
991 strlen(iso_rr_path)+strlen(part_path)+1, 2);
992 {ret= -1; goto ex;}
993 }
994 ret= Xorriso_copy_properties(xorriso, disk_path, part_path,
995 4 * !(compare_result & (1<<21)));
996 /* do not update eventually mismatching dev_ino */
997 if(ret<=0)
998 goto ex;
999 }
1000 /* Copy file attributes to iso_rr_path, augment r-perms by x-perms */
1001 ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 2 | 4);
1002 if(ret<=0)
1003 goto ex;
1004 } else
1005 ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 4);
1006 sprintf(xorriso->info_text, "Adjusted attributes of ");
1007
1008 } else if(flag & 1) {
1009 goto overwrite;
1010 } else
1011 ret= 1;
1012 if(ret>0 && xorriso->info_text[0]) {
1013 Text_shellsafe(iso_rr_path, xorriso->info_text, 1);
1014 if(added_overwrote) {
1015 ret= Xorriso_iso_lstat(xorriso, iso_rr_path, &stbuf, 0);
1016 if(ret == 0 && S_ISREG(stbuf.st_mode)) {
1017 strcat(xorriso->info_text, " (");
1018 Sfile_scale((double) stbuf.st_size,
1019 xorriso->info_text + strlen(xorriso->info_text), 5, 1e4,
1020 1 | 2);
1021 strcat(xorriso->info_text, ")");
1022 } else if (ret == 0 && S_ISDIR(stbuf.st_mode)) {
1023 ret= Xorriso_get_dus(xorriso, iso_rr_path, &du_size, (off_t) 0, 0);
1024 if(ret > 0 && du_size > 0) {
1025 strcat(xorriso->info_text, " (");
1026 Sfile_scale((double) du_size,
1027 xorriso->info_text + strlen(xorriso->info_text), 5, 1e4,
1028 1 | 2);
1029 strcat(xorriso->info_text, ")");
1030 }
1031 }
1032 }
1033 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1034 }
1035 ret= 1;
1036 ex:;
1037 if(split_parts!=NULL)
1038 Splitparts_destroy(&split_parts, split_count, 0);
1039 Xorriso_free_meM(part_path);
1040 if(ret<=0)
1041 return(ret);
1042 if(deleted)
1043 return(2);
1044 return(ret);
1045 }
1046