362
* Write /set keyword. It means set global datas.
363
* [directory-only mode]
364
* - It is only once to write /set keyword. It is using values of the
367
* - Write /set keyword. It is using values of the first entry whose
368
* filetype is a regular file.
369
* - When a parent directory of the entry whose filetype is the regular
370
* file is changed, check the global datas and write it again if its
371
* values are different from the entry's.
438
* Write /set keyword.
439
* Set most used value of uid,gid,mode and fflags, which are
440
* collected by collect_set_values() function.
374
set_global(struct mtree_writer *mtree, struct archive_entry *entry)
443
write_global(struct mtree_writer *mtree)
376
445
struct archive_string setstr;
377
446
struct archive_string unsetstr;
378
447
const char *name;
379
448
int keys, oldkeys, effkeys;
382
switch (archive_entry_filetype(entry)) {
383
case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
384
case AE_IFBLK: case AE_IFIFO:
391
default: /* Handle unknown file types as regular files. */
398
if (mtree->set.processed &&
399
!parent_dir_changed(&mtree->set.parent, entry))
401
/* At first, save a parent directory of the entry for following
403
if (!mtree->set.processed && set_type == AE_IFREG)
404
parent_dir_changed(&mtree->set.parent, entry);
449
struct attr_counter *ac;
406
451
archive_string_init(&setstr);
407
452
archive_string_init(&unsetstr);
408
keys = mtree->keys & (F_FLAGS | F_GID | F_GNAME | F_NLINK | F_MODE
409
| F_TYPE | F_UID | F_UNAME);
453
keys = mtree->keys & SET_KEYS;
410
454
oldkeys = mtree->set.keys;
412
456
if (mtree->set.processed) {
414
* Check the global datas for whether it needs updating.
458
* Check if the global data needs updating.
416
460
effkeys &= ~F_TYPE;
417
if ((oldkeys & (F_UNAME | F_UID)) != 0 &&
418
mtree->set.uid == archive_entry_uid(entry))
419
effkeys &= ~(F_UNAME | F_UID);
420
if ((oldkeys & (F_GNAME | F_GID)) != 0 &&
421
mtree->set.gid == archive_entry_gid(entry))
422
effkeys &= ~(F_GNAME | F_GID);
423
if ((oldkeys & F_MODE) != 0 &&
424
mtree->set.mode == (archive_entry_mode(entry) & 07777))
461
if (oldkeys & (F_UNAME | F_UID)) {
462
ac = mtree->set.uid_list;
464
if (mtree->set.uid == ac->m_entry->uid) {
465
effkeys &= ~(F_UNAME | F_UID);
468
if (ac->next != NULL &&
469
ac->next->count == ac->count)
473
if (oldkeys & (F_GNAME | F_GID)) {
474
ac = mtree->set.gid_list;
476
if (mtree->set.gid == ac->m_entry->gid) {
477
effkeys &= ~(F_GNAME | F_GID);
480
if (ac->next != NULL &&
481
ac->next->count == ac->count)
485
if (oldkeys & F_MODE) {
486
ac = mtree->set.mode_list;
488
if (mtree->set.mode == ac->m_entry->mode) {
492
if (ac->next != NULL &&
493
ac->next->count == ac->count)
426
497
if ((oldkeys & F_FLAGS) != 0) {
427
unsigned long fflags_set;
428
unsigned long fflags_clear;
430
archive_entry_fflags(entry, &fflags_set, &fflags_clear);
431
if (fflags_set == mtree->set.fflags_set &&
432
fflags_clear == mtree->set.fflags_clear)
498
ac = mtree->set.flags_list;
500
if (ac->m_entry->fflags_set ==
501
mtree->set.fflags_set &&
502
ac->m_entry->fflags_clear ==
503
mtree->set.fflags_clear) {
507
if (ac->next != NULL &&
508
ac->next->count == ac->count)
436
513
if ((keys & effkeys & F_TYPE) != 0) {
437
mtree->set.type = set_type;
438
if (set_type == AE_IFDIR)
514
if (mtree->dironly) {
439
515
archive_strcat(&setstr, " type=dir");
516
mtree->set.type = AE_IFDIR;
441
518
archive_strcat(&setstr, " type=file");
519
mtree->set.type = AE_IFREG;
443
522
if ((keys & effkeys & F_UNAME) != 0) {
444
if ((name = archive_entry_uname(entry)) != NULL) {
523
name = mtree->set.uid_list->m_entry->uname;
445
525
archive_strcat(&setstr, " uname=");
446
526
mtree_quote(&setstr, name);
447
} else if ((oldkeys & F_UNAME) != 0)
448
archive_strcat(&unsetstr, " uname");
450
528
keys &= ~F_UNAME;
529
if ((oldkeys & F_UNAME) != 0)
530
archive_strcat(&unsetstr, " uname");
452
533
if ((keys & effkeys & F_UID) != 0) {
453
mtree->set.uid = archive_entry_uid(entry);
534
mtree->set.uid = mtree->set.uid_list->m_entry->uid;
454
535
archive_string_sprintf(&setstr, " uid=%jd",
455
536
(intmax_t)mtree->set.uid);
457
538
if ((keys & effkeys & F_GNAME) != 0) {
458
if ((name = archive_entry_gname(entry)) != NULL) {
539
name = mtree->set.gid_list->m_entry->gname;
459
541
archive_strcat(&setstr, " gname=");
460
542
mtree_quote(&setstr, name);
461
} else if ((oldkeys & F_GNAME) != 0)
462
archive_strcat(&unsetstr, " gname");
464
544
keys &= ~F_GNAME;
545
if ((oldkeys & F_GNAME) != 0)
546
archive_strcat(&unsetstr, " gname");
466
549
if ((keys & effkeys & F_GID) != 0) {
467
mtree->set.gid = archive_entry_gid(entry);
550
mtree->set.gid = mtree->set.gid_list->m_entry->gid;
468
551
archive_string_sprintf(&setstr, " gid=%jd",
469
552
(intmax_t)mtree->set.gid);
471
554
if ((keys & effkeys & F_MODE) != 0) {
472
mtree->set.mode = archive_entry_mode(entry) & 07777;
473
archive_string_sprintf(&setstr, " mode=%o", mtree->set.mode);
555
mtree->set.mode = mtree->set.mode_list->m_entry->mode;
556
archive_string_sprintf(&setstr, " mode=%o",
557
(unsigned int)mtree->set.mode);
475
559
if ((keys & effkeys & F_FLAGS) != 0) {
476
if ((name = archive_entry_fflags_text(entry)) != NULL) {
560
name = mtree->set.flags_list->m_entry->fflags_text;
477
562
archive_strcat(&setstr, " flags=");
478
563
mtree_quote(&setstr, name);
479
archive_entry_fflags(entry, &mtree->set.fflags_set,
480
&mtree->set.fflags_clear);
481
} else if ((oldkeys & F_FLAGS) != 0)
482
archive_strcat(&unsetstr, " flags");
564
mtree->set.fflags_set =
565
mtree->set.flags_list->m_entry->fflags_set;
566
mtree->set.fflags_clear =
567
mtree->set.flags_list->m_entry->fflags_clear;
484
569
keys &= ~F_FLAGS;
570
if ((oldkeys & F_FLAGS) != 0)
571
archive_strcat(&unsetstr, " flags");
486
574
if (unsetstr.length > 0)
487
575
archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
491
579
archive_string_free(&setstr);
492
580
mtree->set.keys = keys;
493
581
mtree->set.processed = 1;
494
/* On directory-only mode, it is only once to write /set keyword. */
496
mtree->set.output = 0;
500
get_keys(struct mtree_writer *mtree, struct archive_entry *entry)
583
free_attr_count(&mtree->set.uid_list);
584
free_attr_count(&mtree->set.gid_list);
585
free_attr_count(&mtree->set.mode_list);
586
free_attr_count(&mtree->set.flags_list);
589
static struct attr_counter *
590
new_attr_count(struct mtree_entry *me, struct attr_counter *prev)
592
struct attr_counter *ac;
594
ac = malloc(sizeof(*ac));
605
free_attr_count(struct attr_counter **top)
607
struct attr_counter *ac, *tac;
621
inc_attr_count(struct attr_counter **top, struct attr_counter *ac,
622
struct attr_counter *last, struct mtree_entry *me)
624
struct attr_counter *pac;
628
if (*top == ac || ac->prev->count >= ac->count)
630
for (pac = ac->prev; pac; pac = pac->prev) {
631
if (pac->count >= ac->count)
634
ac->prev->next = ac->next;
635
if (ac->next != NULL)
636
ac->next->prev = ac->prev;
639
ac->next = pac->next;
641
if (ac->next != NULL)
650
ac = new_attr_count(me, last);
659
collect_set_values(struct mtree_writer *mtree, struct mtree_entry *me)
661
int keys = mtree->keys;
662
struct attr_counter *ac, *last;
664
if (keys & (F_UNAME | F_UID)) {
665
if (mtree->set.uid_list == NULL) {
666
mtree->set.uid_list = new_attr_count(me, NULL);
667
if (mtree->set.uid_list == NULL)
671
for (ac = mtree->set.uid_list; ac; ac = ac->next) {
672
if (ac->m_entry->uid == me->uid)
677
&mtree->set.uid_list, ac, last, me) < 0)
681
if (keys & (F_GNAME | F_GID)) {
682
if (mtree->set.gid_list == NULL) {
683
mtree->set.gid_list = new_attr_count(me, NULL);
684
if (mtree->set.gid_list == NULL)
688
for (ac = mtree->set.gid_list; ac; ac = ac->next) {
689
if (ac->m_entry->gid == me->gid)
694
&mtree->set.gid_list, ac, last, me) < 0)
699
if (mtree->set.mode_list == NULL) {
700
mtree->set.mode_list = new_attr_count(me, NULL);
701
if (mtree->set.mode_list == NULL)
705
for (ac = mtree->set.mode_list; ac; ac = ac->next) {
706
if (ac->m_entry->mode == me->mode)
711
&mtree->set.mode_list, ac, last, me) < 0)
715
if (keys & F_FLAGS) {
716
if (mtree->set.flags_list == NULL) {
717
mtree->set.flags_list = new_attr_count(me, NULL);
718
if (mtree->set.flags_list == NULL)
722
for (ac = mtree->set.flags_list; ac; ac = ac->next) {
723
if (ac->m_entry->fflags_set == me->fflags_set &&
724
ac->m_entry->fflags_clear == me->fflags_clear)
729
&mtree->set.flags_list, ac, last, me) < 0)
738
*mtree->set.me_last = me;
739
mtree->set.me_last = &me->next;
744
get_keys(struct mtree_writer *mtree, struct mtree_entry *me)
504
748
keys = mtree->keys;
751
* If a keyword has been set by /set, we do not need to
505
754
if (mtree->set.keys == 0)
755
return (keys);/* /set is not used. */
507
757
if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
508
mtree->set.gid == archive_entry_gid(entry))
758
mtree->set.gid == me->gid)
509
759
keys &= ~(F_GNAME | F_GID);
510
760
if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
511
mtree->set.uid == archive_entry_uid(entry))
761
mtree->set.uid == me->uid)
512
762
keys &= ~(F_UNAME | F_UID);
513
763
if (mtree->set.keys & F_FLAGS) {
514
unsigned long set, clear;
516
archive_entry_fflags(entry, &set, &clear);
517
if (mtree->set.fflags_set == set &&
518
mtree->set.fflags_clear == clear)
764
if (mtree->set.fflags_set == me->fflags_set &&
765
mtree->set.fflags_clear == me->fflags_clear)
519
766
keys &= ~F_FLAGS;
521
if ((mtree->set.keys & F_MODE) != 0 &&
522
mtree->set.mode == (archive_entry_mode(entry) & 07777))
768
if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode)
525
switch (archive_entry_filetype(entry)) {
771
switch (me->filetype) {
526
772
case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
527
773
case AE_IFBLK: case AE_IFIFO:
791
static struct mtree_entry *
792
new_mtree_entry(struct archive_entry *entry)
794
struct mtree_entry *me;
797
me = calloc(1, sizeof(*me));
800
me->pathname = strdup(archive_entry_pathname(entry));
801
if ((s = archive_entry_symlink(entry)) != NULL)
802
me->symlink = strdup(s);
805
me->nlink = archive_entry_nlink(entry);
806
me->filetype = archive_entry_filetype(entry);
807
me->mode = archive_entry_mode(entry) & 07777;
808
me->uid = archive_entry_uid(entry);
809
me->gid = archive_entry_gid(entry);
810
if ((s = archive_entry_uname(entry)) != NULL)
811
me->uname = strdup(s);
814
if ((s = archive_entry_gname(entry)) != NULL)
815
me->gname = strdup(s);
818
if ((s = archive_entry_fflags_text(entry)) != NULL)
819
me->fflags_text = strdup(s);
821
me->fflags_text = NULL;
822
archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
823
me->mtime = archive_entry_mtime(entry);
824
me->mtime_nsec = archive_entry_mtime_nsec(entry);
825
me->rdevmajor = archive_entry_rdevmajor(entry);
826
me->rdevminor = archive_entry_rdevminor(entry);
827
me->size = archive_entry_size(entry);
834
free_mtree_entry(struct mtree_entry *me)
840
free(me->fflags_text);
546
845
archive_write_mtree_header(struct archive_write *a,
547
846
struct archive_entry *entry)
549
848
struct mtree_writer *mtree= a->format_data;
550
struct archive_string *str;
553
mtree->entry = archive_entry_clone(entry);
554
path = archive_entry_pathname(mtree->entry);
556
850
if (mtree->first) {
557
851
mtree->first = 0;
558
852
archive_strcat(&mtree->buf, "#mtree\n");
853
if ((mtree->keys & SET_KEYS) == 0)
854
mtree->set.output = 0;/* Disalbed. */
560
if (mtree->set.output)
561
set_global(mtree, entry);
563
archive_string_empty(&mtree->ebuf);
564
str = (mtree->indent)? &mtree->ebuf : &mtree->buf;
565
if (!mtree->dironly || archive_entry_filetype(entry) == AE_IFDIR)
566
mtree_quote(str, path);
568
857
mtree->entry_bytes_remaining = archive_entry_size(entry);
569
if ((mtree->keys & F_CKSUM) != 0 &&
570
archive_entry_filetype(entry) == AE_IFREG) {
571
mtree->compute_sum |= F_CKSUM;
575
mtree->compute_sum &= ~F_CKSUM;
576
#ifdef ARCHIVE_HAS_MD5
577
if ((mtree->keys & F_MD5) != 0 &&
578
archive_entry_filetype(entry) == AE_IFREG) {
579
mtree->compute_sum |= F_MD5;
580
archive_md5_init(&mtree->md5ctx);
582
mtree->compute_sum &= ~F_MD5;
584
#ifdef ARCHIVE_HAS_RMD160
585
if ((mtree->keys & F_RMD160) != 0 &&
586
archive_entry_filetype(entry) == AE_IFREG) {
587
mtree->compute_sum |= F_RMD160;
588
archive_rmd160_init(&mtree->rmd160ctx);
590
mtree->compute_sum &= ~F_RMD160;
592
#ifdef ARCHIVE_HAS_SHA1
593
if ((mtree->keys & F_SHA1) != 0 &&
594
archive_entry_filetype(entry) == AE_IFREG) {
595
mtree->compute_sum |= F_SHA1;
596
archive_sha1_init(&mtree->sha1ctx);
598
mtree->compute_sum &= ~F_SHA1;
600
#ifdef ARCHIVE_HAS_SHA256
601
if ((mtree->keys & F_SHA256) != 0 &&
602
archive_entry_filetype(entry) == AE_IFREG) {
603
mtree->compute_sum |= F_SHA256;
604
archive_sha256_init(&mtree->sha256ctx);
606
mtree->compute_sum &= ~F_SHA256;
608
#ifdef ARCHIVE_HAS_SHA384
609
if ((mtree->keys & F_SHA384) != 0 &&
610
archive_entry_filetype(entry) == AE_IFREG) {
611
mtree->compute_sum |= F_SHA384;
612
archive_sha384_init(&mtree->sha384ctx);
614
mtree->compute_sum &= ~F_SHA384;
616
#ifdef ARCHIVE_HAS_SHA512
617
if ((mtree->keys & F_SHA512) != 0 &&
618
archive_entry_filetype(entry) == AE_IFREG) {
619
mtree->compute_sum |= F_SHA512;
620
archive_sha512_init(&mtree->sha512ctx);
622
mtree->compute_sum &= ~F_SHA512;
858
if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR)
861
mtree->mtree_entry = new_mtree_entry(entry);
862
if (mtree->mtree_entry == NULL) {
863
archive_set_error(&a->archive, ENOMEM,
864
"Can't allocate mtree entry");
865
return (ARCHIVE_FATAL);
868
mtree->compute_sum = 0;
870
/* If current file is not a regular file, we do not have to
871
* compute the sum of its content. */
872
if (archive_entry_filetype(entry) != AE_IFREG)
875
/* Initialize a bunch of sum check context. */
625
878
return (ARCHIVE_OK);
628
#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
629
defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
630
defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
632
strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
634
static const char hex[] = "0123456789abcdef";
637
for (i = 0; i < n; i++) {
638
archive_strappend_char(s, hex[bin[i] >> 4]);
639
archive_strappend_char(s, hex[bin[i] & 0x0f]);
645
archive_write_mtree_finish_entry(struct archive_write *a)
882
write_entry(struct archive_write *a, struct mtree_entry *me)
647
884
struct mtree_writer *mtree = a->format_data;
648
struct archive_entry *entry;
649
885
struct archive_string *str;
653
entry = mtree->entry;
655
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
656
"Finished entry without being open first.");
657
return (ARCHIVE_FATAL);
661
if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR) {
662
archive_entry_free(entry);
888
archive_string_empty(&mtree->ebuf);
666
889
str = (mtree->indent)? &mtree->ebuf : &mtree->buf;
667
keys = get_keys(mtree, entry);
890
mtree_quote(str, me->pathname);
891
keys = get_keys(mtree, me);
668
892
if ((keys & F_NLINK) != 0 &&
669
archive_entry_nlink(entry) != 1 &&
670
archive_entry_filetype(entry) != AE_IFDIR)
671
archive_string_sprintf(str,
672
" nlink=%u", archive_entry_nlink(entry));
893
me->nlink != 1 && me->filetype != AE_IFDIR)
894
archive_string_sprintf(str, " nlink=%u", me->nlink);
674
if ((keys & F_GNAME) != 0 &&
675
(name = archive_entry_gname(entry)) != NULL) {
896
if ((keys & F_GNAME) != 0 && me->gname != NULL) {
676
897
archive_strcat(str, " gname=");
677
mtree_quote(str, name);
898
mtree_quote(str, me->gname);
679
if ((keys & F_UNAME) != 0 &&
680
(name = archive_entry_uname(entry)) != NULL) {
900
if ((keys & F_UNAME) != 0 && me->uname != NULL) {
681
901
archive_strcat(str, " uname=");
682
mtree_quote(str, name);
902
mtree_quote(str, me->uname);
684
if ((keys & F_FLAGS) != 0 &&
685
(name = archive_entry_fflags_text(entry)) != NULL) {
686
archive_strcat(str, " flags=");
687
mtree_quote(str, name);
904
if ((keys & F_FLAGS) != 0) {
905
if (me->fflags_text != NULL) {
906
archive_strcat(str, " flags=");
907
mtree_quote(str, me->fflags_text);
908
} else if (mtree->set.processed &&
909
(mtree->set.keys & F_FLAGS) != 0)
910
/* Overwrite the global parameter. */
911
archive_strcat(str, " flags=none");
689
913
if ((keys & F_TIME) != 0)
690
914
archive_string_sprintf(str, " time=%jd.%jd",
691
(intmax_t)archive_entry_mtime(entry),
692
(intmax_t)archive_entry_mtime_nsec(entry));
915
(intmax_t)me->mtime, (intmax_t)me->mtime_nsec);
693
916
if ((keys & F_MODE) != 0)
694
archive_string_sprintf(str, " mode=%o",
695
archive_entry_mode(entry) & 07777);
917
archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode);
696
918
if ((keys & F_GID) != 0)
697
archive_string_sprintf(str, " gid=%jd",
698
(intmax_t)archive_entry_gid(entry));
919
archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid);
699
920
if ((keys & F_UID) != 0)
700
archive_string_sprintf(str, " uid=%jd",
701
(intmax_t)archive_entry_uid(entry));
921
archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
703
switch (archive_entry_filetype(entry)) {
923
switch (me->filetype) {
705
925
if ((keys & F_TYPE) != 0)
706
926
archive_strcat(str, " type=link");
707
927
if ((keys & F_SLINK) != 0) {
708
928
archive_strcat(str, " link=");
709
mtree_quote(str, archive_entry_symlink(entry));
929
mtree_quote(str, me->symlink);
747
967
archive_strcat(str, " type=file");
748
968
if ((keys & F_SIZE) != 0)
749
969
archive_string_sprintf(str, " size=%jd",
750
(intmax_t)archive_entry_size(entry));
754
if (mtree->compute_sum & F_CKSUM) {
756
/* Include the length of the file. */
757
for (len = mtree->crc_len; len != 0; len >>= 8)
758
COMPUTE_CRC(mtree->crc, len & 0xff);
759
mtree->crc = ~mtree->crc;
760
archive_string_sprintf(str, " cksum=%ju",
761
(uintmax_t)mtree->crc);
763
#ifdef ARCHIVE_HAS_MD5
764
if (mtree->compute_sum & F_MD5) {
765
unsigned char buf[16];
767
archive_md5_final(&mtree->md5ctx, buf);
768
archive_strcat(str, " md5digest=");
769
strappend_bin(str, buf, sizeof(buf));
772
#ifdef ARCHIVE_HAS_RMD160
773
if (mtree->compute_sum & F_RMD160) {
774
unsigned char buf[20];
776
archive_rmd160_final(&mtree->rmd160ctx, buf);
777
archive_strcat(str, " rmd160digest=");
778
strappend_bin(str, buf, sizeof(buf));
781
#ifdef ARCHIVE_HAS_SHA1
782
if (mtree->compute_sum & F_SHA1) {
783
unsigned char buf[20];
785
archive_sha1_final(&mtree->sha1ctx, buf);
786
archive_strcat(str, " sha1digest=");
787
strappend_bin(str, buf, sizeof(buf));
790
#ifdef ARCHIVE_HAS_SHA256
791
if (mtree->compute_sum & F_SHA256) {
792
unsigned char buf[32];
794
archive_sha256_final(&mtree->sha256ctx, buf);
795
archive_strcat(str, " sha256digest=");
796
strappend_bin(str, buf, sizeof(buf));
799
#ifdef ARCHIVE_HAS_SHA384
800
if (mtree->compute_sum & F_SHA384) {
801
unsigned char buf[48];
803
archive_sha384_final(&mtree->sha384ctx, buf);
804
archive_strcat(str, " sha384digest=");
805
strappend_bin(str, buf, sizeof(buf));
808
#ifdef ARCHIVE_HAS_SHA512
809
if (mtree->compute_sum & F_SHA512) {
810
unsigned char buf[64];
812
archive_sha512_final(&mtree->sha512ctx, buf);
813
archive_strcat(str, " sha512digest=");
814
strappend_bin(str, buf, sizeof(buf));
974
/* Write a bunch of sum. */
975
if (me->filetype == AE_IFREG)
817
978
archive_strcat(str, "\n");
818
979
if (mtree->indent)
819
980
mtree_indent(mtree);
821
archive_entry_free(entry);
823
982
if (mtree->buf.length > 32768) {
824
ret = (a->compressor.write)(a, mtree->buf.s, mtree->buf.length);
983
ret = __archive_write_output(a, mtree->buf.s, mtree->buf.length);
825
984
archive_string_empty(&mtree->buf);
827
986
ret = ARCHIVE_OK;
991
* Write mtree entries saved at collect_set_values() function.
994
write_mtree_entries(struct archive_write *a)
996
struct mtree_writer *mtree = a->format_data;
997
struct mtree_entry *me, *tme;
1000
for (me = mtree->set.me_first; me; me = me->next) {
1001
ret = write_entry(a, me);
1002
if (ret != ARCHIVE_OK)
1003
return (ARCHIVE_FATAL);
1006
me = mtree->set.me_first;
1007
while (me != NULL) {
1009
free_mtree_entry(me);
1012
mtree->set.me_first = NULL;
1013
mtree->set.me_last = &mtree->set.me_first;
1014
return (ARCHIVE_OK);
1018
archive_write_mtree_finish_entry(struct archive_write *a)
1020
struct mtree_writer *mtree = a->format_data;
1021
struct mtree_entry *me;
1024
if ((me = mtree->mtree_entry) == NULL)
1025
return (ARCHIVE_OK);
1026
mtree->mtree_entry = NULL;
1028
if (me->filetype == AE_IFREG)
1029
sum_final(mtree, me);
1031
if (mtree->set.output) {
1032
if (!mtree->dironly) {
1033
if (archive_strlen(&mtree->set.parent) == 0)
1034
parent_dir_changed(&mtree->set.parent, me);
1035
if (parent_dir_changed(&mtree->set.parent, me)) {
1036
/* Write /set keyword */
1037
write_global(mtree);
1038
/* Write entries saved by
1039
* collect_set_values() function. */
1040
ret = write_mtree_entries(a);
1041
if (ret != ARCHIVE_OK)
1042
return (ARCHIVE_FATAL);
1045
/* Tabulate uid,gid,mode and fflags of a entry
1046
* in order to be used for /set. and, at this time
1047
* we do not write a entry. */
1048
collect_set_values(mtree, me);
1049
return (ARCHIVE_OK);
1051
/* Write the current entry and free it. */
1052
ret = write_entry(a, me);
1053
free_mtree_entry(me);
829
1055
return (ret == ARCHIVE_OK ? ret : ARCHIVE_FATAL);
833
archive_write_mtree_finish(struct archive_write *a)
1059
archive_write_mtree_close(struct archive_write *a)
835
1061
struct mtree_writer *mtree= a->format_data;
1064
if (mtree->set.output && mtree->set.me_first != NULL) {
1065
write_global(mtree);
1066
ret = write_mtree_entries(a);
1067
if (ret != ARCHIVE_OK)
1068
return (ARCHIVE_FATAL);
837
1071
archive_write_set_bytes_in_last_block(&a->archive, 1);
839
return (a->compressor.write)(a, mtree->buf.s, mtree->buf.length);
1073
return __archive_write_output(a, mtree->buf.s, mtree->buf.length);
847
1081
if (n > mtree->entry_bytes_remaining)
848
1082
n = mtree->entry_bytes_remaining;
850
/* We don't need compute a regular file sum */
1083
mtree->entry_bytes_remaining -= n;
1085
/* We don't need to compute a regular file sum */
1086
if (mtree->mtree_entry == NULL)
852
if (mtree->compute_sum & F_CKSUM) {
854
* Compute a POSIX 1003.2 checksum
856
const unsigned char *p;
859
for (nn = n, p = buff; nn--; ++p)
860
COMPUTE_CRC(mtree->crc, *p);
863
#ifdef ARCHIVE_HAS_MD5
864
if (mtree->compute_sum & F_MD5)
865
archive_md5_update(&mtree->md5ctx, buff, n);
867
#ifdef ARCHIVE_HAS_RMD160
868
if (mtree->compute_sum & F_RMD160)
869
archive_rmd160_update(&mtree->rmd160ctx, buff, n);
871
#ifdef ARCHIVE_HAS_SHA1
872
if (mtree->compute_sum & F_SHA1)
873
archive_sha1_update(&mtree->sha1ctx, buff, n);
875
#ifdef ARCHIVE_HAS_SHA256
876
if (mtree->compute_sum & F_SHA256)
877
archive_sha256_update(&mtree->sha256ctx, buff, n);
879
#ifdef ARCHIVE_HAS_SHA384
880
if (mtree->compute_sum & F_SHA384)
881
archive_sha384_update(&mtree->sha384ctx, buff, n);
883
#ifdef ARCHIVE_HAS_SHA512
884
if (mtree->compute_sum & F_SHA512)
885
archive_sha512_update(&mtree->sha512ctx, buff, n);
1089
if (mtree->mtree_entry->filetype == AE_IFREG)
1090
sum_update(mtree, buff, n);
891
archive_write_mtree_destroy(struct archive_write *a)
1096
archive_write_mtree_free(struct archive_write *a)
893
1098
struct mtree_writer *mtree= a->format_data;
1099
struct mtree_entry *me, *tme;
895
1101
if (mtree == NULL)
896
1102
return (ARCHIVE_OK);
898
archive_entry_free(mtree->entry);
1104
/* Make sure we dot not leave any entries. */
1105
me = mtree->set.me_first;
1106
while (me != NULL) {
1108
free_mtree_entry(me);
899
1111
archive_string_free(&mtree->ebuf);
900
1112
archive_string_free(&mtree->buf);
901
1113
archive_string_free(&mtree->set.parent);
1114
free_attr_count(&mtree->set.uid_list);
1115
free_attr_count(&mtree->set.gid_list);
1116
free_attr_count(&mtree->set.mode_list);
1117
free_attr_count(&mtree->set.flags_list);
903
1119
a->format_data = NULL;
904
1120
return (ARCHIVE_OK);
1049
1268
return (ARCHIVE_OK);
1272
sum_init(struct mtree_writer *mtree)
1274
if (mtree->keys & F_CKSUM) {
1275
mtree->compute_sum |= F_CKSUM;
1279
#ifdef ARCHIVE_HAS_MD5
1280
if (mtree->keys & F_MD5) {
1281
if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK)
1282
mtree->compute_sum |= F_MD5;
1284
mtree->keys &= ~F_MD5;/* Not supported. */
1287
#ifdef ARCHIVE_HAS_RMD160
1288
if (mtree->keys & F_RMD160) {
1289
if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK)
1290
mtree->compute_sum |= F_RMD160;
1292
mtree->keys &= ~F_RMD160;/* Not supported. */
1295
#ifdef ARCHIVE_HAS_SHA1
1296
if (mtree->keys & F_SHA1) {
1297
if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK)
1298
mtree->compute_sum |= F_SHA1;
1300
mtree->keys &= ~F_SHA1;/* Not supported. */
1303
#ifdef ARCHIVE_HAS_SHA256
1304
if (mtree->keys & F_SHA256) {
1305
if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK)
1306
mtree->compute_sum |= F_SHA256;
1308
mtree->keys &= ~F_SHA256;/* Not supported. */
1311
#ifdef ARCHIVE_HAS_SHA384
1312
if (mtree->keys & F_SHA384) {
1313
if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK)
1314
mtree->compute_sum |= F_SHA384;
1316
mtree->keys &= ~F_SHA384;/* Not supported. */
1319
#ifdef ARCHIVE_HAS_SHA512
1320
if (mtree->keys & F_SHA512) {
1321
if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK)
1322
mtree->compute_sum |= F_SHA512;
1324
mtree->keys &= ~F_SHA512;/* Not supported. */
1330
sum_update(struct mtree_writer *mtree, const void *buff, size_t n)
1332
if (mtree->compute_sum & F_CKSUM) {
1334
* Compute a POSIX 1003.2 checksum
1336
const unsigned char *p;
1339
for (nn = n, p = buff; nn--; ++p)
1340
COMPUTE_CRC(mtree->crc, *p);
1341
mtree->crc_len += n;
1343
#ifdef ARCHIVE_HAS_MD5
1344
if (mtree->compute_sum & F_MD5)
1345
archive_md5_update(&mtree->md5ctx, buff, n);
1347
#ifdef ARCHIVE_HAS_RMD160
1348
if (mtree->compute_sum & F_RMD160)
1349
archive_rmd160_update(&mtree->rmd160ctx, buff, n);
1351
#ifdef ARCHIVE_HAS_SHA1
1352
if (mtree->compute_sum & F_SHA1)
1353
archive_sha1_update(&mtree->sha1ctx, buff, n);
1355
#ifdef ARCHIVE_HAS_SHA256
1356
if (mtree->compute_sum & F_SHA256)
1357
archive_sha256_update(&mtree->sha256ctx, buff, n);
1359
#ifdef ARCHIVE_HAS_SHA384
1360
if (mtree->compute_sum & F_SHA384)
1361
archive_sha384_update(&mtree->sha384ctx, buff, n);
1363
#ifdef ARCHIVE_HAS_SHA512
1364
if (mtree->compute_sum & F_SHA512)
1365
archive_sha512_update(&mtree->sha512ctx, buff, n);
1370
sum_final(struct mtree_writer *mtree, struct mtree_entry *me)
1373
if (mtree->compute_sum & F_CKSUM) {
1375
/* Include the length of the file. */
1376
for (len = mtree->crc_len; len != 0; len >>= 8)
1377
COMPUTE_CRC(mtree->crc, len & 0xff);
1378
me->crc = ~mtree->crc;
1380
#ifdef ARCHIVE_HAS_MD5
1381
if (mtree->compute_sum & F_MD5)
1382
archive_md5_final(&mtree->md5ctx, me->buf_md5);
1384
#ifdef ARCHIVE_HAS_RMD160
1385
if (mtree->compute_sum & F_RMD160)
1386
archive_rmd160_final(&mtree->rmd160ctx, me->buf_rmd160);
1388
#ifdef ARCHIVE_HAS_SHA1
1389
if (mtree->compute_sum & F_SHA1)
1390
archive_sha1_final(&mtree->sha1ctx, me->buf_sha1);
1392
#ifdef ARCHIVE_HAS_SHA256
1393
if (mtree->compute_sum & F_SHA256)
1394
archive_sha256_final(&mtree->sha256ctx, me->buf_sha256);
1396
#ifdef ARCHIVE_HAS_SHA384
1397
if (mtree->compute_sum & F_SHA384)
1398
archive_sha384_final(&mtree->sha384ctx, me->buf_sha384);
1400
#ifdef ARCHIVE_HAS_SHA512
1401
if (mtree->compute_sum & F_SHA512)
1402
archive_sha512_final(&mtree->sha512ctx, me->buf_sha512);
1404
/* Save what types of sum are computed. */
1405
me->compute_sum = mtree->compute_sum;
1408
#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
1409
defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
1410
defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
1412
strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
1414
static const char hex[] = "0123456789abcdef";
1417
for (i = 0; i < n; i++) {
1418
archive_strappend_char(s, hex[bin[i] >> 4]);
1419
archive_strappend_char(s, hex[bin[i] & 0x0f]);
1425
sum_write(struct archive_string *str, struct mtree_entry *me)
1428
if (me->compute_sum & F_CKSUM) {
1429
archive_string_sprintf(str, " cksum=%ju",
1430
(uintmax_t)me->crc);
1432
#ifdef ARCHIVE_HAS_MD5
1433
if (me->compute_sum & F_MD5) {
1434
archive_strcat(str, " md5digest=");
1435
strappend_bin(str, me->buf_md5, sizeof(me->buf_md5));
1438
#ifdef ARCHIVE_HAS_RMD160
1439
if (me->compute_sum & F_RMD160) {
1440
archive_strcat(str, " rmd160digest=");
1441
strappend_bin(str, me->buf_rmd160, sizeof(me->buf_rmd160));
1444
#ifdef ARCHIVE_HAS_SHA1
1445
if (me->compute_sum & F_SHA1) {
1446
archive_strcat(str, " sha1digest=");
1447
strappend_bin(str, me->buf_sha1, sizeof(me->buf_sha1));
1450
#ifdef ARCHIVE_HAS_SHA256
1451
if (me->compute_sum & F_SHA256) {
1452
archive_strcat(str, " sha256digest=");
1453
strappend_bin(str, me->buf_sha256, sizeof(me->buf_sha256));
1456
#ifdef ARCHIVE_HAS_SHA384
1457
if (me->compute_sum & F_SHA384) {
1458
archive_strcat(str, " sha384digest=");
1459
strappend_bin(str, me->buf_sha384, sizeof(me->buf_sha384));
1462
#ifdef ARCHIVE_HAS_SHA512
1463
if (me->compute_sum & F_SHA512) {
1464
archive_strcat(str, " sha512digest=");
1465
strappend_bin(str, me->buf_sha512, sizeof(me->buf_sha512));