From 5af59472024985419bb11bf9c3d1242e2dc5523a Mon Sep 17 00:00:00 2001 From: Chang Yang Date: Wed, 6 Dec 2023 10:33:47 +0800 Subject: [PATCH] feat: upgrade package --- Makefile-boot.am | 2 + Makefile-libostree.am | 33 +- Makefile-man.am | 16 +- Makefile-ostree.am | 18 +- Makefile-otcore.am | 25 + Makefile-otutil.am | 4 +- Makefile-switchroot.am | 40 +- Makefile-tests.am | 43 +- Makefile.am | 26 +- Makefile.in | 1222 ++++-- README.md | 20 +- apidoc/Makefile.in | 3 + apidoc/html/index.html | 2 +- ...Core-repository-independent-functions.html | 97 +- ...ee-GPG-signature-verification-results.html | 3 +- ...-In-memory-modifiable-filesystem-tree.html | 16 +- apidoc/html/ostree-OstreeRepo.html | 422 ++- ...on-system-for-asynchronous-operations.html | 67 +- .../ostree-Root-partition-mount-point.html | 111 +- .../ostree-SELinux-policy-management.html | 10 +- apidoc/html/ostree-Signature-management.html | 6 +- apidoc/html/ostree-Simple-upgrade-class.html | 11 +- .../html/ostree-ostree-bootconfig-parser.html | 60 + apidoc/html/ostree-ostree-deployment.html | 6 +- apidoc/html/ostree-ostree-diff.html | 2 +- apidoc/html/ostree-ostree-kernel-args.html | 156 +- apidoc/html/ostree-ostree-ref.html | 14 +- apidoc/html/ostree-ostree-remote.html | 14 +- apidoc/html/ostree-ostree-repo-file.html | 157 +- apidoc/html/ostree-ostree-repo-finder.html | 10 +- .../ostree-ostree-repo-remote-finder.html | 4 +- apidoc/html/ostree-ostree-version.html | 8 +- apidoc/html/ostree.devhelp2 | 14 +- apidoc/html/reference.html | 64 +- apidoc/ostree-sections.txt | 7 + apidoc/version.xml | 2 +- autogen.sh | 1 + bash/ostree | 21 +- build-aux/config.guess | 1636 ++++---- build-aux/config.sub | 2657 ++++++------- build-aux/ltmain.sh | 855 +++-- buildutil/glibtests.m4 | 2 +- buildutil/libtool.m4 | 227 +- buildutil/ltoptions.m4 | 4 +- buildutil/ltsugar.m4 | 2 +- buildutil/ltversion.m4 | 13 +- buildutil/lt~obsolete.m4 | 4 +- composefs/libcomposefs/Makefile-lib.am | 22 + composefs/libcomposefs/Makefile-lib.am.inc | 22 + composefs/libcomposefs/bitrotate.h | 135 + composefs/libcomposefs/erofs_fs.h | 461 +++ composefs/libcomposefs/erofs_fs_wrapper.h | 150 + composefs/libcomposefs/hash.c | 1106 ++++++ composefs/libcomposefs/hash.h | 277 ++ composefs/libcomposefs/lcfs-erofs-internal.h | 134 + composefs/libcomposefs/lcfs-erofs.h | 36 + composefs/libcomposefs/lcfs-fsverity.c | 457 +++ composefs/libcomposefs/lcfs-fsverity.h | 27 + composefs/libcomposefs/lcfs-internal.h | 205 + composefs/libcomposefs/lcfs-mount.c | 616 ++++ composefs/libcomposefs/lcfs-mount.h | 63 + composefs/libcomposefs/lcfs-utils.h | 111 + composefs/libcomposefs/lcfs-writer-erofs.c | 1880 ++++++++++ composefs/libcomposefs/lcfs-writer.c | 1338 +++++++ composefs/libcomposefs/lcfs-writer.h | 143 + composefs/libcomposefs/xalloc-oversized.h | 65 + config.h.in | 21 +- configure | 773 +++- configure.ac | 135 +- debian/.gitignore | 8 + debian/changelog | 1299 ++++++- debian/control | 41 +- debian/copyright | 52 +- debian/libostree-1-1.symbols | 11 + debian/libostree-doc.lintian-overrides | 2 - debian/ostree-boot.install | 14 +- debian/ostree-boot.lintian-overrides | 4 + debian/ostree-tests.install | 1 - debian/ostree-tests.lintian-overrides | 12 +- debian/ostree.maintscript | 2 - debian/patches/add-sunway-support.patch | 19 - ...loader-zipl-No-op-if-run-as-non-root.patch | 29 + ...-test-admin-deploy-uboot.sh-on-s390x.patch | 29 + .../Skip-test-pull-repeated-during-CI.patch | 2 +- ...est-sysroot-Skip-on-s390x-by-default.patch | 30 + ...ib-Fix-symbol-versioning-inheritance.patch | 46 - debian/patches/series | 6 +- ...sert-that-extended-attributes-are-av.patch | 36 - debian/rules | 15 +- debian/tests/build | 4 +- debian/tests/control | 9 +- debian/tests/{flaky => flaky-concurrency} | 0 debian/tests/flaky-sysroot | 12 + debian/tests/gnome-desktop-testing | 17 +- debian/watch | 9 +- libglnx/Makefile-libglnx.am | 2 + libglnx/Makefile-libglnx.am.inc | 2 + libglnx/glnx-backport-testutils.c | 162 + libglnx/glnx-backport-testutils.h | 209 ++ libglnx/glnx-backports.c | 22 + libglnx/glnx-backports.h | 95 +- libglnx/glnx-dirfd.c | 4 +- libglnx/glnx-fdio.c | 21 +- libglnx/glnx-local-alloc.h | 15 +- libglnx/glnx-lockfile.c | 2 +- libglnx/libglnx.h | 1 + libglnx/tests/libglnx-testlib.c | 3 +- libglnx/tests/test-libglnx-macros.c | 8 + man/index.xml | 2 +- man/ostree-admin-deploy.xml | 18 +- man/ostree-admin-os-init.xml | 16 +- man/ostree-admin-set-default.xml | 83 + man/ostree-admin-stateroot-init.xml | 75 + man/ostree-checkout.xml | 11 + man/ostree-commit.xml | 22 +- man/ostree-find-remotes.xml | 8 + man/ostree-prepare-root.xml | 160 + man/ostree-pull.xml | 44 + man/ostree-refs.xml | 9 + man/ostree-remote.xml | 33 + man/ostree-rev-parse.xml | 13 + man/ostree-show.xml | 16 + man/ostree-trivial-httpd.xml | 116 - man/ostree.repo-config.xml | 23 +- man/ostree.xml | 8 - src/boot/dracut/module-setup.sh | 12 + src/boot/ostree-finalize-staged-hold.service | 35 + src/boot/ostree-finalize-staged.service | 5 + src/libostree/bupsplit.c | 120 +- src/libostree/bupsplit.h | 23 +- src/libostree/libostree-devel.sym | 1 - src/libostree/libostree-released.sym | 25 +- src/libostree/ostree-async-progress.c | 102 +- src/libostree/ostree-async-progress.h | 63 +- src/libostree/ostree-autocleanups.h | 3 +- src/libostree/ostree-bloom-private.h | 22 +- src/libostree/ostree-bloom.c | 288 +- src/libostree/ostree-bootconfig-parser.c | 103 +- src/libostree/ostree-bootconfig-parser.h | 49 +- src/libostree/ostree-bootloader-aboot.c | 224 ++ src/libostree/ostree-bootloader-aboot.h | 35 + src/libostree/ostree-bootloader-grub2.c | 146 +- src/libostree/ostree-bootloader-grub2.h | 12 +- src/libostree/ostree-bootloader-syslinux.c | 76 +- src/libostree/ostree-bootloader-syslinux.h | 8 +- src/libostree/ostree-bootloader-uboot.c | 62 +- src/libostree/ostree-bootloader-uboot.h | 8 +- src/libostree/ostree-bootloader-zipl.c | 314 +- src/libostree/ostree-bootloader-zipl.h | 8 +- src/libostree/ostree-bootloader.c | 41 +- src/libostree/ostree-bootloader.h | 58 +- src/libostree/ostree-chain-input-stream.c | 96 +- src/libostree/ostree-chain-input-stream.h | 29 +- src/libostree/ostree-checksum-input-stream.c | 90 +- src/libostree/ostree-checksum-input-stream.h | 30 +- src/libostree/ostree-cmd-private.c | 24 +- src/libostree/ostree-cmd-private.h | 34 +- src/libostree/ostree-content-writer.c | 61 +- src/libostree/ostree-content-writer.h | 9 +- src/libostree/ostree-core-private.h | 150 +- src/libostree/ostree-core.c | 881 ++--- src/libostree/ostree-core.h | 305 +- src/libostree/ostree-date-utils-private.h | 3 +- src/libostree/ostree-date-utils.c | 60 +- src/libostree/ostree-deployment-private.h | 8 +- src/libostree/ostree-deployment.c | 64 +- src/libostree/ostree-deployment.h | 14 +- src/libostree/ostree-diff.c | 184 +- src/libostree/ostree-diff.h | 44 +- src/libostree/ostree-dummy-enumtypes.c | 2 +- src/libostree/ostree-dummy-enumtypes.h | 3 +- src/libostree/ostree-fetcher-curl.c | 396 +- src/libostree/ostree-fetcher-soup.c | 651 ++-- src/libostree/ostree-fetcher-soup3.c | 878 +++++ src/libostree/ostree-fetcher-uri.c | 88 +- src/libostree/ostree-fetcher-util.c | 171 +- src/libostree/ostree-fetcher-util.h | 57 +- src/libostree/ostree-fetcher.h | 174 +- src/libostree/ostree-gpg-verifier.c | 201 +- src/libostree/ostree-gpg-verifier.h | 85 +- .../ostree-gpg-verify-result-dummy.c | 43 +- .../ostree-gpg-verify-result-private.h | 3 +- src/libostree/ostree-gpg-verify-result.c | 421 +-- src/libostree/ostree-gpg-verify-result.h | 36 +- src/libostree/ostree-impl-system-generator.c | 128 +- src/libostree/ostree-kernel-args-private.h | 44 + src/libostree/ostree-kernel-args.c | 185 +- src/libostree/ostree-kernel-args.h | 88 +- .../ostree-libarchive-input-stream.c | 86 +- .../ostree-libarchive-input-stream.h | 32 +- src/libostree/ostree-libarchive-private.h | 20 +- src/libostree/ostree-linuxfsutil.c | 32 +- src/libostree/ostree-linuxfsutil.h | 10 +- src/libostree/ostree-lzma-common.c | 29 +- src/libostree/ostree-lzma-compressor.c | 64 +- src/libostree/ostree-lzma-compressor.h | 24 +- src/libostree/ostree-lzma-decompressor.c | 31 +- src/libostree/ostree-lzma-decompressor.h | 25 +- src/libostree/ostree-metalink.c | 210 +- src/libostree/ostree-metalink.h | 38 +- src/libostree/ostree-mutable-tree.c | 211 +- src/libostree/ostree-mutable-tree.h | 105 +- src/libostree/ostree-ref.c | 40 +- src/libostree/ostree-ref.h | 18 +- src/libostree/ostree-remote-private.h | 23 +- src/libostree/ostree-remote.c | 21 +- src/libostree/ostree-remote.h | 2 +- src/libostree/ostree-repo-checkout.c | 723 ++-- src/libostree/ostree-repo-commit.c | 1944 +++++----- src/libostree/ostree-repo-composefs.c | 616 ++++ src/libostree/ostree-repo-deprecated.h | 18 +- src/libostree/ostree-repo-file-enumerator.c | 47 +- src/libostree/ostree-repo-file-enumerator.h | 33 +- src/libostree/ostree-repo-file.c | 380 +- src/libostree/ostree-repo-file.h | 61 +- .../ostree-repo-finder-avahi-parser.c | 26 +- .../ostree-repo-finder-avahi-private.h | 2 +- src/libostree/ostree-repo-finder-avahi.c | 503 ++- src/libostree/ostree-repo-finder-avahi.h | 28 +- src/libostree/ostree-repo-finder-config.c | 108 +- src/libostree/ostree-repo-finder-config.h | 23 +- src/libostree/ostree-repo-finder-mount.c | 291 +- src/libostree/ostree-repo-finder-mount.h | 23 +- src/libostree/ostree-repo-finder-override.c | 128 +- src/libostree/ostree-repo-finder-override.h | 26 +- src/libostree/ostree-repo-finder.c | 145 +- src/libostree/ostree-repo-finder.h | 75 +- src/libostree/ostree-repo-libarchive.c | 573 ++- src/libostree/ostree-repo-os.c | 30 +- src/libostree/ostree-repo-os.h | 10 +- src/libostree/ostree-repo-private.h | 516 ++- src/libostree/ostree-repo-prune.c | 250 +- src/libostree/ostree-repo-pull-private.h | 239 +- src/libostree/ostree-repo-pull-verify.c | 188 +- src/libostree/ostree-repo-pull.c | 3281 ++++++++--------- src/libostree/ostree-repo-refs.c | 505 ++- ...e-repo-static-delta-compilation-analysis.c | 142 +- .../ostree-repo-static-delta-compilation.c | 801 ++-- src/libostree/ostree-repo-static-delta-core.c | 622 ++-- .../ostree-repo-static-delta-private.h | 160 +- .../ostree-repo-static-delta-processing.c | 373 +- src/libostree/ostree-repo-traverse.c | 299 +- src/libostree/ostree-repo-verity.c | 134 +- src/libostree/ostree-repo.c | 2889 +++++++-------- src/libostree/ostree-repo.h | 1417 +++---- src/libostree/ostree-rollsum.c | 53 +- src/libostree/ostree-rollsum.h | 11 +- src/libostree/ostree-sepolicy-private.h | 12 +- src/libostree/ostree-sepolicy.c | 218 +- src/libostree/ostree-sepolicy.h | 55 +- src/libostree/ostree-sign-dummy.c | 66 +- src/libostree/ostree-sign-dummy.h | 40 +- src/libostree/ostree-sign-ed25519.c | 373 +- src/libostree/ostree-sign-ed25519.h | 59 +- src/libostree/ostree-sign-private.h | 35 + src/libostree/ostree-sign.c | 325 +- src/libostree/ostree-sign.h | 127 +- src/libostree/ostree-sysroot-cleanup.c | 335 +- src/libostree/ostree-sysroot-deploy.c | 2250 ++++++----- src/libostree/ostree-sysroot-private.h | 173 +- src/libostree/ostree-sysroot-upgrader.c | 308 +- src/libostree/ostree-sysroot-upgrader.h | 67 +- src/libostree/ostree-sysroot.c | 796 ++-- src/libostree/ostree-sysroot.h | 253 +- .../ostree-tls-cert-interaction-private.h | 35 +- src/libostree/ostree-tls-cert-interaction.c | 12 +- src/libostree/ostree-varint.c | 147 +- src/libostree/ostree-varint.h | 6 +- src/libostree/ostree-version.h | 10 +- src/libostree/ostree.h | 24 +- src/libostree/s390x-se-luks-gencpio | 22 - src/libotcore/otcore-ed25519-verify.c | 115 + src/libotcore/otcore-prepare-root.c | 139 + src/libotcore/otcore.h | 76 + src/libotutil/ot-checksum-instream.c | 52 +- src/libotutil/ot-checksum-instream.h | 33 +- src/libotutil/ot-checksum-utils.c | 97 +- src/libotutil/ot-checksum-utils.h | 54 +- src/libotutil/ot-fs-utils.c | 130 +- src/libotutil/ot-fs-utils.h | 71 +- src/libotutil/ot-gio-utils.c | 46 +- src/libotutil/ot-gio-utils.h | 42 +- src/libotutil/ot-gpg-utils.c | 373 +- src/libotutil/ot-gpg-utils.h | 31 +- src/libotutil/ot-keyfile-utils.c | 136 +- src/libotutil/ot-keyfile-utils.h | 69 +- src/libotutil/ot-tool-util.c | 35 +- src/libotutil/ot-tool-util.h | 18 +- src/libotutil/ot-unix-utils.c | 52 +- src/libotutil/ot-unix-utils.h | 10 +- src/libotutil/ot-variant-builder.c | 290 +- src/libotutil/ot-variant-builder.h | 39 +- src/libotutil/ot-variant-utils.c | 57 +- src/libotutil/ot-variant-utils.h | 21 +- src/libotutil/otutil.h | 60 +- src/libotutil/zbase32.c | 165 +- src/libotutil/zbase32.h | 8 +- src/ostree/main.c | 104 +- src/ostree/ostree-trivial-httpd.c | 473 ++- src/ostree/ot-admin-builtin-boot-complete.c | 21 +- src/ostree/ot-admin-builtin-cleanup.c | 19 +- src/ostree/ot-admin-builtin-deploy.c | 123 +- src/ostree/ot-admin-builtin-diff.c | 49 +- src/ostree/ot-admin-builtin-finalize-staged.c | 71 +- src/ostree/ot-admin-builtin-init-fs.c | 36 +- src/ostree/ot-admin-builtin-instutil.c | 32 +- src/ostree/ot-admin-builtin-kargs.c | 134 + src/ostree/ot-admin-builtin-os-init.c | 39 +- src/ostree/ot-admin-builtin-pin.c | 39 +- src/ostree/ot-admin-builtin-set-default.c | 68 + src/ostree/ot-admin-builtin-set-origin.c | 107 +- src/ostree/ot-admin-builtin-status.c | 110 +- src/ostree/ot-admin-builtin-switch.c | 62 +- src/ostree/ot-admin-builtin-undeploy.c | 37 +- src/ostree/ot-admin-builtin-unlock.c | 58 +- src/ostree/ot-admin-builtin-upgrade.c | 60 +- src/ostree/ot-admin-builtins.h | 44 +- src/ostree/ot-admin-functions.c | 43 +- src/ostree/ot-admin-functions.h | 32 +- ...ot-admin-instutil-builtin-grub2-generate.c | 46 +- ...-instutil-builtin-selinux-ensure-labeled.c | 117 +- .../ot-admin-instutil-builtin-set-kargs.c | 54 +- src/ostree/ot-admin-instutil-builtins.h | 15 +- .../ot-admin-kargs-builtin-edit-in-place.c | 79 + ...vial-httpd.c => ot-admin-kargs-builtins.h} | 32 +- src/ostree/ot-builtin-admin.c | 97 +- src/ostree/ot-builtin-cat.c | 32 +- src/ostree/ot-builtin-checkout.c | 201 +- src/ostree/ot-builtin-checksum.c | 49 +- src/ostree/ot-builtin-commit.c | 495 +-- src/ostree/ot-builtin-config.c | 88 +- src/ostree/ot-builtin-create-usb.c | 95 +- src/ostree/ot-builtin-diff.c | 133 +- src/ostree/ot-builtin-export.c | 119 +- src/ostree/ot-builtin-find-remotes.c | 164 +- src/ostree/ot-builtin-fsck.c | 349 +- src/ostree/ot-builtin-gpg-sign.c | 113 +- src/ostree/ot-builtin-init.c | 45 +- src/ostree/ot-builtin-log.c | 76 +- src/ostree/ot-builtin-ls.c | 122 +- src/ostree/ot-builtin-prune.c | 172 +- src/ostree/ot-builtin-pull-local.c | 132 +- src/ostree/ot-builtin-pull.c | 257 +- src/ostree/ot-builtin-refs.c | 145 +- src/ostree/ot-builtin-remote.c | 53 +- src/ostree/ot-builtin-reset.c | 26 +- src/ostree/ot-builtin-rev-parse.c | 79 +- src/ostree/ot-builtin-show.c | 246 +- src/ostree/ot-builtin-sign.c | 87 +- src/ostree/ot-builtin-static-delta.c | 325 +- src/ostree/ot-builtin-summary.c | 272 +- src/ostree/ot-builtins.h | 60 +- src/ostree/ot-dump.c | 189 +- src/ostree/ot-dump.h | 21 +- src/ostree/ot-editor.c | 26 +- src/ostree/ot-editor.h | 4 +- src/ostree/ot-main.c | 290 +- src/ostree/ot-main.h | 69 +- src/ostree/ot-remote-builtin-add-cookie.c | 23 +- src/ostree/ot-remote-builtin-add.c | 180 +- src/ostree/ot-remote-builtin-delete-cookie.c | 20 +- src/ostree/ot-remote-builtin-delete.c | 37 +- src/ostree/ot-remote-builtin-gpg-import.c | 53 +- src/ostree/ot-remote-builtin-gpg-list-keys.c | 26 +- src/ostree/ot-remote-builtin-list-cookies.c | 17 +- src/ostree/ot-remote-builtin-list.c | 41 +- src/ostree/ot-remote-builtin-refs.c | 58 +- src/ostree/ot-remote-builtin-show-url.c | 39 +- src/ostree/ot-remote-builtin-summary.c | 110 +- src/ostree/ot-remote-builtins.h | 28 +- src/ostree/ot-remote-cookie-util.c | 91 +- src/ostree/ot-remote-cookie-util.h | 17 +- src/rofiles-fuse/main.c | 171 +- src/switchroot/ostree-mount-util.h | 65 +- src/switchroot/ostree-prepare-root-static.c | 393 ++ src/switchroot/ostree-prepare-root.c | 726 ++-- src/switchroot/ostree-remount.c | 188 +- src/switchroot/ostree-system-generator.c | 40 +- tests/admin-test.sh | 21 +- tests/archive-test.sh | 7 +- tests/basic-test.sh | 54 +- tests/libostreetest.c | 40 +- tests/libostreetest.h | 12 +- tests/libtest-core.sh | 7 + tests/libtest.sh | 104 +- tests/readdir-rand.c | 208 -- tests/repo-finder-mount.c | 50 +- tests/test-admin-deploy-bootprefix.sh | 35 + tests/test-admin-deploy-emptyetc.sh | 33 + tests/test-admin-deploy-karg.sh | 4 +- tests/test-admin-deploy-whiteouts.sh | 42 + tests/test-admin-gpg.sh | 5 + tests/test-admin-kargs.sh | 44 + tests/test-basic-bare-split-xattrs.sh | 2 + tests/test-basic-c.c | 297 +- tests/test-bloom.c | 37 +- tests/test-bsdiff.c | 34 +- tests/test-checksum.c | 25 +- tests/test-commit-sign-sh-ext.c | 39 +- tests/test-commit-sign.sh | 5 + tests/test-commit-timestamp.sh | 8 +- tests/test-composefs.sh | 44 + tests/test-concurrency.py | 4 - tests/test-delta-ed25519.sh | 2 - tests/test-delta.sh | 20 +- tests/test-export.sh | 10 +- tests/test-gpg-verify-result.c | 354 +- tests/test-include-ostree-h.c | 5 +- tests/test-kargs.c | 73 +- tests/test-keyfile-utils.c | 155 +- tests/test-libarchive-import.c | 184 +- tests/test-lzma.c | 65 +- tests/test-mock-gio.c | 38 +- tests/test-mock-gio.h | 92 +- tests/test-mutable-tree.c | 52 +- tests/test-ot-opt-utils.c | 15 +- tests/test-ot-tool-util.c | 29 +- tests/test-ot-unix-utils.c | 15 +- tests/test-otcore.c | 141 + tests/test-prune.sh | 12 + tests/test-pull-c.c | 58 +- tests/test-pull-contenturl.sh | 5 + tests/test-pull-large-metadata.sh | 5 +- tests/test-pull-localcache.sh | 2 +- tests/test-pull-metalink.sh | 5 + tests/test-pull-mirrorlist.sh | 5 + tests/test-pull-override-url.sh | 5 + tests/test-pull-repeated.sh | 44 +- tests/test-pull-summary-sigs.sh | 10 + tests/test-refs.sh | 12 + tests/test-remote-refs.sh | 49 + tests/test-repo-finder-avahi.c | 117 +- tests/test-repo-finder-config.c | 210 +- tests/test-repo-finder-mount-integration.sh | 1 + tests/test-repo-finder-mount.c | 329 +- tests/test-repo.c | 279 +- tests/test-rfc2616-dates.c | 97 +- tests/test-rollsum-cli.c | 10 +- tests/test-rollsum.c | 90 +- tests/test-signed-commit.sh | 2 - tests/test-signed-pull-summary.sh | 10 + tests/test-signed-pull.sh | 6 +- tests/test-summary-update.sh | 4 + tests/test-symbols.sh | 2 +- tests/test-sysroot-c.c | 29 +- tests/test-varint.c | 23 +- 446 files changed, 39689 insertions(+), 26691 deletions(-) create mode 100644 Makefile-otcore.am create mode 100644 composefs/libcomposefs/Makefile-lib.am create mode 100644 composefs/libcomposefs/Makefile-lib.am.inc create mode 100644 composefs/libcomposefs/bitrotate.h create mode 100644 composefs/libcomposefs/erofs_fs.h create mode 100644 composefs/libcomposefs/erofs_fs_wrapper.h create mode 100644 composefs/libcomposefs/hash.c create mode 100644 composefs/libcomposefs/hash.h create mode 100644 composefs/libcomposefs/lcfs-erofs-internal.h create mode 100644 composefs/libcomposefs/lcfs-erofs.h create mode 100644 composefs/libcomposefs/lcfs-fsverity.c create mode 100644 composefs/libcomposefs/lcfs-fsverity.h create mode 100644 composefs/libcomposefs/lcfs-internal.h create mode 100644 composefs/libcomposefs/lcfs-mount.c create mode 100644 composefs/libcomposefs/lcfs-mount.h create mode 100644 composefs/libcomposefs/lcfs-utils.h create mode 100644 composefs/libcomposefs/lcfs-writer-erofs.c create mode 100644 composefs/libcomposefs/lcfs-writer.c create mode 100644 composefs/libcomposefs/lcfs-writer.h create mode 100644 composefs/libcomposefs/xalloc-oversized.h create mode 100644 debian/.gitignore delete mode 100644 debian/libostree-doc.lintian-overrides delete mode 100644 debian/ostree.maintscript delete mode 100644 debian/patches/add-sunway-support.patch create mode 100644 debian/patches/bootloader-zipl-No-op-if-run-as-non-root.patch create mode 100644 debian/patches/debian/Skip-test-admin-deploy-uboot.sh-on-s390x.patch create mode 100644 debian/patches/debian/test-sysroot-Skip-on-s390x-by-default.patch delete mode 100644 debian/patches/lib-Fix-symbol-versioning-inheritance.patch delete mode 100644 debian/patches/test-basic-c-Don-t-assert-that-extended-attributes-are-av.patch rename debian/tests/{flaky => flaky-concurrency} (100%) mode change 100644 => 100755 create mode 100644 debian/tests/flaky-sysroot create mode 100644 libglnx/glnx-backport-testutils.c create mode 100644 libglnx/glnx-backport-testutils.h create mode 100644 man/ostree-admin-set-default.xml create mode 100644 man/ostree-admin-stateroot-init.xml create mode 100644 man/ostree-prepare-root.xml delete mode 100644 man/ostree-trivial-httpd.xml create mode 100644 src/boot/ostree-finalize-staged-hold.service create mode 100644 src/libostree/ostree-bootloader-aboot.c create mode 100644 src/libostree/ostree-bootloader-aboot.h create mode 100644 src/libostree/ostree-fetcher-soup3.c create mode 100644 src/libostree/ostree-kernel-args-private.h create mode 100644 src/libostree/ostree-repo-composefs.c create mode 100644 src/libostree/ostree-sign-private.h delete mode 100755 src/libostree/s390x-se-luks-gencpio create mode 100644 src/libotcore/otcore-ed25519-verify.c create mode 100644 src/libotcore/otcore-prepare-root.c create mode 100644 src/libotcore/otcore.h create mode 100644 src/ostree/ot-admin-builtin-kargs.c create mode 100644 src/ostree/ot-admin-builtin-set-default.c create mode 100644 src/ostree/ot-admin-kargs-builtin-edit-in-place.c rename src/ostree/{ot-builtin-trivial-httpd.c => ot-admin-kargs-builtins.h} (52%) create mode 100644 src/switchroot/ostree-prepare-root-static.c delete mode 100644 tests/readdir-rand.c create mode 100755 tests/test-admin-deploy-bootprefix.sh create mode 100755 tests/test-admin-deploy-emptyetc.sh create mode 100755 tests/test-admin-deploy-whiteouts.sh create mode 100755 tests/test-admin-kargs.sh create mode 100755 tests/test-composefs.sh create mode 100644 tests/test-otcore.c create mode 100755 tests/test-remote-refs.sh diff --git a/Makefile-boot.am b/Makefile-boot.am index e42e518..90f9804 100644 --- a/Makefile-boot.am +++ b/Makefile-boot.am @@ -41,6 +41,7 @@ systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \ src/boot/ostree-boot-complete.service \ src/boot/ostree-finalize-staged.service \ src/boot/ostree-finalize-staged.path \ + src/boot/ostree-finalize-staged-hold.service \ $(NULL) systemdtmpfilesdir = $(prefix)/lib/tmpfiles.d dist_systemdtmpfiles_DATA = src/boot/ostree-tmpfiles.conf @@ -70,6 +71,7 @@ EXTRA_DIST += src/boot/dracut/module-setup.sh \ src/boot/ostree-finalize-staged.path \ src/boot/ostree-remount.service \ src/boot/ostree-finalize-staged.service \ + src/boot/ostree-finalize-staged-hold.service \ src/boot/grub2/grub2-15_ostree \ src/boot/grub2/ostree-grub-generator \ $(NULL) diff --git a/Makefile-libostree.am b/Makefile-libostree.am index f93f712..9611473 100644 --- a/Makefile-libostree.am +++ b/Makefile-libostree.am @@ -87,6 +87,7 @@ libostree_1_la_SOURCES = \ src/libostree/ostree-repo.c \ src/libostree/ostree-repo-checkout.c \ src/libostree/ostree-repo-commit.c \ + src/libostree/ostree-repo-composefs.c \ src/libostree/ostree-repo-pull.c \ src/libostree/ostree-repo-pull-private.h \ src/libostree/ostree-repo-pull-verify.c \ @@ -111,6 +112,8 @@ libostree_1_la_SOURCES = \ src/libostree/ostree-deployment.c \ src/libostree/ostree-bootloader.h \ src/libostree/ostree-bootloader.c \ + src/libostree/ostree-bootloader-aboot.h \ + src/libostree/ostree-bootloader-aboot.c \ src/libostree/ostree-bootloader-grub2.h \ src/libostree/ostree-bootloader-grub2.c \ src/libostree/ostree-bootloader-zipl.h \ @@ -133,6 +136,7 @@ libostree_1_la_SOURCES = \ src/libostree/ostree-repo-finder-mount.c \ src/libostree/ostree-repo-finder-override.c \ src/libostree/ostree-kernel-args.h \ + src/libostree/ostree-kernel-args-private.h \ src/libostree/ostree-kernel-args.c \ $(NULL) if USE_LIBARCHIVE @@ -182,12 +186,13 @@ EXTRA_DIST += \ $(top_srcdir)/src/libostree/libostree-released.sym \ $(NULL) -libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(builddir)/src/libostree \ +libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff -I$(srcdir)/libglnx -I$(srcdir)/composefs -I$(srcdir)/src/libotutil -I$(srcdir)/src/libotcore -I$(srcdir)/src/libostree -I$(builddir)/src/libostree \ + -I$(srcdir)/src/switchroot \ $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) $(OT_DEP_CRYPTO_CFLAGS) \ -fvisibility=hidden '-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) extern' \ -DPKGLIBEXECDIR=\"$(pkglibexecdir)\" libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions $(addprefix $(wl_versionscript_arg),$(symbol_files)) -libostree_1_la_LIBADD = libotutil.la libglnx.la libbsdiff.la $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) \ +libostree_1_la_LIBADD = libotutil.la libotcore.la libglnx.la libbsdiff.la $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) \ $(OT_DEP_LZMA_LIBS) $(OT_DEP_ZLIB_LIBS) $(OT_DEP_CRYPTO_LIBS) # Some change between rust-1.21.0-1.fc27 and rust-1.22.1-1.fc27.x86_64 libostree_1_la_LIBADD += $(bupsplitpath) @@ -219,18 +224,25 @@ libostree_1_la_SOURCES += \ $(NULL) endif +# Only enable one fetcher backend. if USE_CURL libostree_1_la_SOURCES += src/libostree/ostree-fetcher-curl.c \ $(NULL) libostree_1_la_CFLAGS += $(OT_DEP_CURL_CFLAGS) libostree_1_la_LIBADD += $(OT_DEP_CURL_LIBS) else +if USE_LIBSOUP3 +libostree_1_la_SOURCES += src/libostree/ostree-fetcher-soup3.c +libostree_1_la_CFLAGS += $(OT_INTERNAL_SOUP_CFLAGS) +libostree_1_la_LIBADD += $(OT_INTERNAL_SOUP_LIBS) +else if USE_LIBSOUP libostree_1_la_SOURCES += src/libostree/ostree-fetcher-soup.c libostree_1_la_CFLAGS += $(OT_INTERNAL_SOUP_CFLAGS) libostree_1_la_LIBADD += $(OT_INTERNAL_SOUP_LIBS) endif endif +endif if USE_LIBMOUNT libostree_1_la_CFLAGS += $(OT_DEP_LIBMOUNT_CFLAGS) @@ -249,12 +261,12 @@ libostree_1_la_SOURCES += \ src/libostree/ostree-sign-dummy.h \ src/libostree/ostree-sign-ed25519.c \ src/libostree/ostree-sign-ed25519.h \ + src/libostree/ostree-sign-private.h \ $(NULL) -if USE_LIBSODIUM -libostree_1_la_CFLAGS += $(OT_DEP_LIBSODIUM_CFLAGS) -libostree_1_la_LIBADD += $(OT_DEP_LIBSODIUM_LIBS) -endif # USE_LIBSODIUM +if USE_COMPOSEFS +libostree_1_la_LIBADD += libcomposefs.la +endif # USE_COMPOSEFS # XXX: work around clang being passed -fstack-clash-protection which it doesn't understand # See: https://bugzilla.redhat.com/show_bug.cgi?id=1672012 @@ -264,10 +276,11 @@ if BUILDOPT_INTROSPECTION OSTree-1.0.gir: libostree-1.la Makefile OSTree_1_0_gir_EXPORT_PACKAGES = ostree-1 OSTree_1_0_gir_INCLUDES = Gio-2.0 +OSTree_1_0_gir_C_INCLUDES = ostree.h OSTree_1_0_gir_CFLAGS = $(libostree_1_la_CFLAGS) OSTree_1_0_gir_LIBS = libostree-1.la OSTree_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=Ostree --symbol-prefix=ostree $(GI_SCANNERFLAGS) -OSTree_1_0_gir_FILES = $(libostreeinclude_HEADERS) $(filter-out %-private.h %/ostree-soup-uri.h,$(libostree_1_la_SOURCES)) +OSTree_1_0_gir_FILES = $(libostreeinclude_HEADERS) $(filter-out %.h,$(libostree_1_la_SOURCES)) INTROSPECTION_GIRS += OSTree-1.0.gir gir_DATA += OSTree-1.0.gir typelib_DATA += OSTree-1.0.typelib @@ -284,12 +297,8 @@ EXTRA_DIST += src/libostree/README-gpg src/libostree/bupsplit.h \ src/libostree/ostree-enumtypes.c.template \ src/libostree/ostree-deployment-private.h \ src/libostree/ostree-repo-deprecated.h \ - src/libostree/ostree-version.h \ - src/libostree/s390x-se-luks-gencpio + src/libostree/ostree-version.h install-mkdir-remotes-d-hook: mkdir -p $(DESTDIR)$(sysconfdir)/ostree/remotes.d INSTALL_DATA_HOOKS += install-mkdir-remotes-d-hook - -# Secure Execution: script for creating new initramdisk with LUKS key and config -pkglibexec_SCRIPTS += src/libostree/s390x-se-luks-gencpio diff --git a/Makefile-man.am b/Makefile-man.am index 5c7f241..da229bc 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -17,29 +17,26 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see . +# This needs to be outside the conditional to avoid a warning +.PHONY: manhtml + if ENABLE_MAN # If you add a new man page here, add a reference to it in index.xml and # ostree.xml. man1_files = ostree.1 ostree-admin-cleanup.1 \ ostree-admin-config-diff.1 ostree-admin-deploy.1 \ -ostree-admin-init-fs.1 ostree-admin-instutil.1 ostree-admin-os-init.1 \ +ostree-admin-init-fs.1 ostree-admin-instutil.1 ostree-admin-stateroot-init.1 ostree-admin-os-init.1 \ ostree-admin-status.1 ostree-admin-set-origin.1 ostree-admin-switch.1 \ ostree-admin-undeploy.1 ostree-admin-upgrade.1 ostree-admin-unlock.1 \ -ostree-admin-pin.1 \ +ostree-admin-pin.1 ostree-admin-set-default.1 \ ostree-admin.1 ostree-cat.1 ostree-checkout.1 ostree-checksum.1 \ ostree-commit.1 ostree-create-usb.1 ostree-export.1 \ ostree-config.1 ostree-diff.1 ostree-find-remotes.1 ostree-fsck.1 \ ostree-init.1 ostree-log.1 ostree-ls.1 ostree-prune.1 ostree-pull-local.1 \ ostree-pull.1 ostree-refs.1 ostree-remote.1 ostree-reset.1 \ ostree-rev-parse.1 ostree-show.1 ostree-sign.1 ostree-summary.1 \ -ostree-static-delta.1 -if USE_LIBSOUP -man1_files += ostree-trivial-httpd.1 -else -# We still want to distribute the source, even if we are not building it -EXTRA_DIST += man/ostree-trivial-httpd.xml -endif +ostree-static-delta.1 ostree-prepare-root.1 if BUILDOPT_FUSE man1_files += rofiles-fuse.1 @@ -65,7 +62,6 @@ noinst_DATA += $(manhtml_files) # Convenience target for building the just the HTML man pages manhtml: $(manhtml_files) -.PHONY: manhtml endif EXTRA_DIST += man/index.xml $(man1_MANS:.1=.xml) $(man5_MANS:.5=.xml) diff --git a/Makefile-ostree.am b/Makefile-ostree.am index 0fe2c5f..16bb04d 100644 --- a/Makefile-ostree.am +++ b/Makefile-ostree.am @@ -72,7 +72,9 @@ ostree_SOURCES += \ src/ostree/ot-admin-builtin-finalize-staged.c \ src/ostree/ot-admin-builtin-boot-complete.c \ src/ostree/ot-admin-builtin-undeploy.c \ + src/ostree/ot-admin-builtin-set-default.c \ src/ostree/ot-admin-builtin-instutil.c \ + src/ostree/ot-admin-builtin-kargs.c \ src/ostree/ot-admin-builtin-cleanup.c \ src/ostree/ot-admin-builtin-os-init.c \ src/ostree/ot-admin-builtin-set-origin.c \ @@ -88,6 +90,8 @@ ostree_SOURCES += \ src/ostree/ot-admin-instutil-builtins.h \ src/ostree/ot-admin-functions.h \ src/ostree/ot-admin-functions.c \ + src/ostree/ot-admin-kargs-builtins.h \ + src/ostree/ot-admin-kargs-builtin-edit-in-place.c \ $(NULL) # Remote subcommand @@ -138,14 +142,7 @@ if USE_CURL_OR_SOUP ostree_SOURCES += src/ostree/ot-builtin-pull.c endif -if USE_LIBSOUP -# Eventually once we stop things from using this, we should support disabling this -ostree_SOURCES += src/ostree/ot-builtin-trivial-httpd.c -pkglibexec_PROGRAMS += ostree-trivial-httpd -ostree_trivial_httpd_SOURCES = src/ostree/ostree-trivial-httpd.c -ostree_trivial_httpd_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_SOUP_CFLAGS) -ostree_trivial_httpd_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_SOUP_LIBS) - +if USE_LIBSOUP_OR_LIBSOUP3 if !USE_CURL # This is necessary for the cookie jar bits ostree_CFLAGS += $(OT_INTERNAL_SOUP_CFLAGS) @@ -157,8 +154,3 @@ if USE_LIBARCHIVE ostree_CFLAGS += $(OT_DEP_LIBARCHIVE_CFLAGS) ostree_LDADD += $(OT_DEP_LIBARCHIVE_LIBS) endif - -if USE_LIBSODIUM -ostree_CFLAGS += $(OT_DEP_LIBSODIUM_CFLAGS) -ostree_LDADD += $(OT_DEP_LIBSODIUM_LIBS) -endif # USE_LIBSODIUM diff --git a/Makefile-otcore.am b/Makefile-otcore.am new file mode 100644 index 0000000..8252ead --- /dev/null +++ b/Makefile-otcore.am @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + +noinst_LTLIBRARIES += libotcore.la + +libotcore_la_SOURCES = \ + src/libotcore/otcore.h \ + src/libotcore/otcore-ed25519-verify.c \ + src/libotcore/otcore-prepare-root.c \ + $(NULL) + +libotcore_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_CRYPTO_LIBS) $(LIBSYSTEMD_CFLAGS) +libotcore_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS) $(OT_DEP_CRYPTO_LIBS) diff --git a/Makefile-otutil.am b/Makefile-otutil.am index 79a9d3d..291a2e8 100644 --- a/Makefile-otutil.am +++ b/Makefile-otutil.am @@ -52,5 +52,5 @@ libotutil_la_SOURCES += \ $(NULL) endif -libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(LIBSYSTEMD_CFLAGS) -libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS) +libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_CRYPTO_LIBS) $(LIBSYSTEMD_CFLAGS) +libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS) $(OT_DEP_CRYPTO_LIBS) diff --git a/Makefile-switchroot.am b/Makefile-switchroot.am index 104ec0c..1e458e0 100644 --- a/Makefile-switchroot.am +++ b/Makefile-switchroot.am @@ -15,6 +15,12 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see . +ostree_prepare_root_SOURCES = \ + src/switchroot/ostree-mount-util.h +ostree_prepare_root_CFLAGS = +ostree_prepare_root_CPPFLAGS = $(AM_CPPFLAGS) +ostree_prepare_root_LDADD = + if BUILDOPT_SYSTEMD ostree_boot_PROGRAMS += ostree-remount else @@ -23,13 +29,9 @@ else check_PROGRAMS += ostree-remount endif -ostree_prepare_root_SOURCES = \ - src/switchroot/ostree-mount-util.h \ - src/switchroot/ostree-prepare-root.c \ - $(NULL) -ostree_prepare_root_CPPFLAGS = $(AM_CPPFLAGS) - if BUILDOPT_USE_STATIC_COMPILER +ostree_prepare_root_SOURCES += src/switchroot/ostree-prepare-root-static.c + # ostree-prepare-root can be used as init in a system without a populated /lib. # To support this use case we need to link statically as we will be unable to # locate libc.so at run time if it's not installed in /lib. @@ -43,22 +45,36 @@ if BUILDOPT_USE_STATIC_COMPILER ostree_boot_SCRIPTS += ostree-prepare-root ostree-prepare-root : $(ostree_prepare_root_SOURCES) - $(STATIC_COMPILER) -o $@ -static $(top_srcdir)/src/switchroot/ostree-prepare-root.c $(ostree_prepare_root_CPPFLAGS) $(AM_CFLAGS) $(DEFAULT_INCLUDES) -DOSTREE_PREPARE_ROOT_STATIC=1 + $(STATIC_COMPILER) -o $@ -static $(top_srcdir)/src/switchroot/ostree-prepare-root-static.c $(ostree_prepare_root_CPPFLAGS) $(AM_CFLAGS) $(DEFAULT_INCLUDES) -DOSTREE_PREPARE_ROOT_STATIC=1 +CLEANFILES += ostree-prepare-root else ostree_boot_PROGRAMS += ostree-prepare-root -ostree_prepare_root_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot -endif +ostree_prepare_root_CFLAGS += $(AM_CFLAGS) -Isrc/switchroot -I$(srcdir)/composefs -I$(srcdir)/src/libostree -I$(srcdir)/src/libotcore -I$(srcdir)/src/libotutil +ostree_prepare_root_SOURCES += src/switchroot/ostree-prepare-root.c +ostree_prepare_root_CPPFLAGS += $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_DEP_CRYPTO_CFLAGS) -I $(srcdir)/libglnx +ostree_prepare_root_LDADD += $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_DEP_CRYPTO_LIBS) libotcore.la libotutil.la libglnx.la +endif # BUILDOPT_USE_STATIC_COMPILER + ostree_remount_SOURCES = \ src/switchroot/ostree-mount-util.h \ src/switchroot/ostree-remount.c \ $(NULL) -ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -Isrc/switchroot -I$(srcdir)/libglnx -ostree_remount_LDADD = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) libglnx.la +ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -Isrc/switchroot -I$(srcdir)/src/libotcore -I$(srcdir)/src/libotutil -I$(srcdir)/libglnx +ostree_remount_LDADD = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) libotcore.la libotutil.la libglnx.la + +if USE_SELINUX +ostree_remount_CPPFLAGS += $(OT_DEP_SELINUX_CFLAGS) +ostree_remount_LDADD += $(OT_DEP_SELINUX_LIBS) +endif + +if USE_COMPOSEFS +ostree_prepare_root_LDADD += libcomposefs.la +endif if BUILDOPT_SYSTEMD ostree_prepare_root_CPPFLAGS += -DHAVE_SYSTEMD=1 -ostree_prepare_root_LDADD = $(AM_LDFLAGS) $(LIBSYSTEMD_LIBS) +ostree_prepare_root_LDADD += $(LIBSYSTEMD_LIBS) endif # This is the "new mode" of using a generator for /var; see diff --git a/Makefile-tests.am b/Makefile-tests.am index 29de6c7..e1cea7f 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -36,6 +36,9 @@ AM_TESTS_ENVIRONMENT += OT_TESTS_DEBUG=1 \ PATH=$$(cd $(top_builddir)/tests && pwd):$${PATH} \ OSTREE_FEATURES="$(OSTREE_FEATURES)" \ PYTHONUNBUFFERED=1 \ + GSETTINGS_BACKEND=memory \ + GIO_USE_PROXY_RESOLVER=dummy \ + GIO_USE_VFS=local \ $(NULL) if BUILDOPT_ASAN AM_TESTS_ENVIRONMENT += OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc @@ -68,6 +71,8 @@ _installed_or_uninstalled_test_scripts = \ tests/test-archivez.sh \ tests/test-remote-add.sh \ tests/test-remote-headers.sh \ + tests/test-remote-refs.sh \ + tests/test-composefs.sh \ tests/test-commit-sign.sh \ tests/test-commit-timestamp.sh \ tests/test-export.sh \ @@ -98,6 +103,7 @@ _installed_or_uninstalled_test_scripts = \ tests/test-admin-upgrade-endoflife.sh \ tests/test-admin-upgrade-systemd-update.sh \ tests/test-admin-deploy-syslinux.sh \ + tests/test-admin-deploy-bootprefix.sh \ tests/test-admin-deploy-2.sh \ tests/test-admin-deploy-karg.sh \ tests/test-admin-deploy-switch.sh \ @@ -107,6 +113,8 @@ _installed_or_uninstalled_test_scripts = \ tests/test-admin-deploy-nomerge.sh \ tests/test-admin-deploy-none.sh \ tests/test-admin-deploy-bootid-gc.sh \ + tests/test-admin-deploy-whiteouts.sh \ + tests/test-admin-deploy-emptyetc.sh \ tests/test-osupdate-dtb.sh \ tests/test-admin-instutil-set-kargs.sh \ tests/test-admin-upgrade-not-backwards.sh \ @@ -114,6 +122,7 @@ _installed_or_uninstalled_test_scripts = \ tests/test-admin-pull-deploy-split.sh \ tests/test-admin-locking.sh \ tests/test-admin-deploy-clean.sh \ + tests/test-admin-kargs.sh \ tests/test-reset-nonlinear.sh \ tests/test-oldstyle-partial.sh \ tests/test-delta.sh \ @@ -178,7 +187,7 @@ else EXTRA_DIST += tests/test-rofiles-fuse.sh endif -if USE_LIBSOUP +if USE_LIBSOUP_OR_LIBSOUP3 _installed_or_uninstalled_test_scripts += tests/test-remote-cookies.sh endif @@ -253,19 +262,7 @@ else EXTRA_DIST += $(js_installed_tests) endif -test_ltlibraries = libreaddir-rand.la -libreaddir_rand_la_SOURCES = tests/readdir-rand.c -libreaddir_rand_la_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -libreaddir_rand_la_LIBADD = \ - -ldl \ - $(OT_INTERNAL_GIO_UNIX_LIBS) \ - $(NULL) -libreaddir_rand_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version -if !ENABLE_INSTALLED_TESTS -libreaddir_rand_la_LDFLAGS += -rpath $(abs_builddir) -endif - -_installed_or_uninstalled_test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tests/test-mutable-tree \ +_installed_or_uninstalled_test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tests/test-otcore tests/test-mutable-tree \ tests/test-keyfile-utils tests/test-ot-opt-utils tests/test-ot-tool-util \ tests/test-checksum tests/test-lzma tests/test-rollsum \ tests/test-basic-c tests/test-sysroot-c tests/test-pull-c tests/test-repo tests/test-include-ostree-h tests/test-kargs \ @@ -277,6 +274,13 @@ _installed_or_uninstalled_test_programs += \ $(NULL) endif +if USE_LIBSOUP_OR_LIBSOUP3 +test_extra_programs += ostree-trivial-httpd +ostree_trivial_httpd_SOURCES = src/ostree/ostree-trivial-httpd.c +ostree_trivial_httpd_CFLAGS = $(common_tests_cflags) $(OT_INTERNAL_SOUP_CFLAGS) +ostree_trivial_httpd_LDADD = $(common_tests_ldadd) $(OT_INTERNAL_SOUP_LIBS) +endif + if USE_AVAHI test_programs += tests/test-repo-finder-avahi endif @@ -361,6 +365,9 @@ tests_test_varint_LDADD = $(TESTS_LDADD) tests_test_bsdiff_CFLAGS = $(TESTS_CFLAGS) tests_test_bsdiff_LDADD = libbsdiff.la $(TESTS_LDADD) +tests_test_otcore_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libotcore -I$(srcdir)/libglnx +tests_test_otcore_LDADD = $(OT_INTERNAL_GIO_UNIX_LIBS) libotcore.la libglnx.la libotutil.la + tests_test_checksum_SOURCES = \ src/libostree/ostree-core.c \ src/libostree/ostree-varint.c \ @@ -413,11 +420,7 @@ EXTRA_DIST += \ tests/libtest.sh \ $(NULL) -tests/libreaddir-rand.so: Makefile - mkdir -p tests/ - $(AM_V_GEN) ln -fns ../.libs/libreaddir-rand.so tests/ -ALL_LOCAL_RULES += tests/libreaddir-rand.so -CLEANFILES += tests/libreaddir-rand.so tests/ostree-symlink-stamp \ +CLEANFILES += tests/ostree-symlink-stamp \ tests/ostree-prepare-root-symlink-stamp tests/ostree-remount-symlink-stamp \ tests/rofiles-fuse-symlink-stamp tests/ostree CLEANFILES += tests/ostree-prepare-root tests/ostree-remount tests/rofiles-fuse @@ -447,7 +450,7 @@ dist_test_scripts += $(_installed_or_uninstalled_test_scripts) test_programs += $(_installed_or_uninstalled_test_programs) endif -if !USE_LIBSOUP +if !USE_LIBSOUP_OR_LIBSOUP3 no-soup-for-you-warning: @echo "WARNING: $(PACKAGE) was built without libsoup, which is currently" 1>&2 @echo "WARNING: required for many unit tests." 1>&2 diff --git a/Makefile.am b/Makefile.am index 4e66916..19abc0c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,8 +29,7 @@ AM_CPPFLAGS += -DDATADIR='"$(datadir)"' -DLIBEXECDIR='"$(libexecdir)"' \ -DOSTREE_COMPILATION \ -DG_LOG_DOMAIN=\"OSTree\" \ -DOSTREE_GITREV='"$(OSTREE_GITREV)"' \ - -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_66 '-DGLIB_VERSION_MAX_ALLOWED=G_ENCODE_VERSION(2,70)' \ - -DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_40 '-DSOUP_VERSION_MAX_ALLOWED=G_ENCODE_VERSION(2,48)' + -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_66 '-DGLIB_VERSION_MAX_ALLOWED=G_ENCODE_VERSION(2,70)' # For strict aliasing, see https://bugzilla.gnome.org/show_bug.cgi?id=791622 AM_CFLAGS += -std=gnu99 -fno-strict-aliasing $(WARN_CFLAGS) AM_DISTCHECK_CONFIGURE_FLAGS += \ @@ -39,6 +38,10 @@ AM_DISTCHECK_CONFIGURE_FLAGS += \ --disable-maintainer-mode \ $(NULL) +if USE_LIBSOUP +AM_CPPFLAGS += -DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_40 '-DSOUP_VERSION_MAX_ALLOWED=G_ENCODE_VERSION(2,48)' +endif + GITIGNOREFILES = aclocal.m4 build-aux/ buildutil/*.m4 config.h.in gtk-doc.make # Generated by ci/gh-build.sh @@ -69,8 +72,13 @@ EXTRA_DIST += autogen.sh COPYING README.md OT_INTERNAL_GIO_UNIX_CFLAGS = $(OT_DEP_GIO_UNIX_CFLAGS) OT_INTERNAL_GIO_UNIX_LIBS = $(OT_DEP_GIO_UNIX_LIBS) +if USE_LIBSOUP3 +OT_INTERNAL_SOUP_CFLAGS = $(OT_DEP_SOUP3_CFLAGS) +OT_INTERNAL_SOUP_LIBS = $(OT_DEP_SOUP3_LIBS) +else OT_INTERNAL_SOUP_CFLAGS = $(OT_DEP_SOUP_CFLAGS) OT_INTERNAL_SOUP_LIBS = $(OT_DEP_SOUP_LIBS) +endif # This canonicalizes the PKG_CHECK_MODULES or AM_PATH_GPGME results if USE_GPGME @@ -109,7 +117,17 @@ include bsdiff/Makefile-bsdiff.am.inc EXTRA_DIST += bsdiff/Makefile-bsdiff.am noinst_LTLIBRARIES += libbsdiff.la +COMPOSEFSDIR=$(srcdir)/composefs/libcomposefs +LCFS_DEP_CRYPTO_CFLAGS=$(OT_DEP_CRYPTO_CFLAGS) +LCFS_DEP_CRYPTO_LIBS=$(OT_DEP_CRYPTO_LIBS) +include composefs/libcomposefs/Makefile-lib.am.inc +EXTRA_DIST += composefs/libcomposefs/Makefile-lib.am +if USE_COMPOSEFS +noinst_LTLIBRARIES += libcomposefs.la +endif + include Makefile-otutil.am +include Makefile-otcore.am include Makefile-libostree.am include Makefile-ostree.am include Makefile-switchroot.am @@ -124,6 +142,10 @@ include Makefile-bash.am release-tag: cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION) +.PHONY: clang-format +clang-format: + git ls-files '**.c' '**.cxx' '**.h' '**.hpp' | xargs clang-format -i + embed_dependency=tar -C $(srcdir) --append --exclude='.git/*' --transform="s,^embedded-dependencies/,ostree-embeddeps-$${GITVERSION}/embedded-dependencies/," --file=$${TARFILE_TMP} git_version_rpm = $$(cd $(srcdir) && git describe | sed -e 's,-,\.,g' -e 's,^v,,') diff --git a/Makefile.in b/Makefile.in index 6312f3e..68c4e4a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -111,6 +111,21 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see . +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + # Makefile for C source code # # Copyright (C) 2011,2014 Colin Walters @@ -359,14 +374,14 @@ host_triplet = @host@ bin_PROGRAMS = ostree$(EXEEXT) $(am__EXEEXT_1) sbin_PROGRAMS = libexec_PROGRAMS = -pkglibexec_PROGRAMS = $(am__EXEEXT_19) -noinst_PROGRAMS = $(am__EXEEXT_16) tests/test-rollsum-cli$(EXEEXT) \ +pkglibexec_PROGRAMS = +noinst_PROGRAMS = $(am__EXEEXT_17) tests/test-rollsum-cli$(EXEEXT) \ tests/test-commit-sign-sh-ext$(EXEEXT) -ostree_boot_PROGRAMS = $(am__EXEEXT_17) $(am__EXEEXT_18) +ostree_boot_PROGRAMS = $(am__EXEEXT_18) $(am__EXEEXT_19) TESTS = $(am__EXEEXT_8) $(am__EXEEXT_25) \ - $(dist_uninstalled_test_scripts) $(am__EXEEXT_13) -installed_test_PROGRAMS = $(am__EXEEXT_15) -check_PROGRAMS = $(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14) + $(dist_uninstalled_test_scripts) $(am__EXEEXT_14) +installed_test_PROGRAMS = $(am__EXEEXT_16) +check_PROGRAMS = $(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) @ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_1 = $(all_test_ltlibs) @ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_2 = $(all_test_programs) @ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_3 = $(all_test_scripts) @@ -392,47 +407,49 @@ check_PROGRAMS = $(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14) @ENABLE_INSTALLED_TESTS_TRUE@ $(dist_installed_test_data) @ENABLE_INSTALLED_TESTS_TRUE@am__append_12 = $(test_ltlibraries) $(installed_test_ltlibraries) @ENABLE_INSTALLED_TESTS_TRUE@am__append_13 = $(installed_test_meta_DATA) -@ENABLE_GTK_DOC_TRUE@am__append_14 = apidoc -@USE_GPGME_TRUE@am__append_15 = \ +@USE_LIBSOUP_TRUE@am__append_14 = -DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_40 '-DSOUP_VERSION_MAX_ALLOWED=G_ENCODE_VERSION(2,48)' +@ENABLE_GTK_DOC_TRUE@am__append_15 = apidoc +@USE_COMPOSEFS_TRUE@am__append_16 = libcomposefs.la +@USE_GPGME_TRUE@am__append_17 = \ @USE_GPGME_TRUE@ src/libotutil/ot-gpg-utils.c \ @USE_GPGME_TRUE@ src/libotutil/ot-gpg-utils.h \ @USE_GPGME_TRUE@ src/libotutil/zbase32.c \ @USE_GPGME_TRUE@ src/libotutil/zbase32.h \ @USE_GPGME_TRUE@ $(NULL) -@USE_LIBARCHIVE_TRUE@am__append_16 = src/libostree/ostree-libarchive-input-stream.h \ +@USE_LIBARCHIVE_TRUE@am__append_18 = src/libostree/ostree-libarchive-input-stream.h \ @USE_LIBARCHIVE_TRUE@ src/libostree/ostree-libarchive-input-stream.c \ @USE_LIBARCHIVE_TRUE@ src/libostree/ostree-libarchive-private.h \ @USE_LIBARCHIVE_TRUE@ $(NULL) -@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@am__append_17 = \ +@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@am__append_19 = \ @HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ src/libostree/ostree-tls-cert-interaction.c \ @HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ src/libostree/ostree-tls-cert-interaction-private.h \ @HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ $(NULL) -@USE_AVAHI_TRUE@am__append_18 = \ +@USE_AVAHI_TRUE@am__append_20 = \ @USE_AVAHI_TRUE@ src/libostree/ostree-repo-finder-avahi-parser.c \ @USE_AVAHI_TRUE@ src/libostree/ostree-repo-finder-avahi-private.h \ @USE_AVAHI_TRUE@ $(NULL) -@USE_GPGME_TRUE@am__append_19 = \ +@USE_GPGME_TRUE@am__append_21 = \ @USE_GPGME_TRUE@ src/libostree/ostree-gpg-verifier.c \ @USE_GPGME_TRUE@ src/libostree/ostree-gpg-verifier.h \ @USE_GPGME_TRUE@ src/libostree/ostree-gpg-verify-result.c \ @USE_GPGME_TRUE@ src/libostree/ostree-gpg-verify-result-private.h \ @USE_GPGME_TRUE@ $(NULL) -@USE_GPGME_FALSE@am__append_20 = \ +@USE_GPGME_FALSE@am__append_22 = \ @USE_GPGME_FALSE@ src/libostree/ostree-gpg-verify-result-dummy.c \ @USE_GPGME_FALSE@ $(NULL) -@USE_LIBARCHIVE_TRUE@am__append_21 = $(OT_DEP_LIBARCHIVE_CFLAGS) -@USE_LIBARCHIVE_TRUE@am__append_22 = $(OT_DEP_LIBARCHIVE_LIBS) -@USE_AVAHI_TRUE@am__append_23 = $(OT_DEP_AVAHI_CFLAGS) -@USE_AVAHI_TRUE@am__append_24 = $(OT_DEP_AVAHI_LIBS) -@BUILDOPT_SYSTEMD_TRUE@am__append_25 = $(LIBSYSTEMD_CFLAGS) -@BUILDOPT_SYSTEMD_TRUE@am__append_26 = $(LIBSYSTEMD_LIBS) -@USE_CURL_OR_SOUP_TRUE@am__append_27 = \ +@USE_LIBARCHIVE_TRUE@am__append_23 = $(OT_DEP_LIBARCHIVE_CFLAGS) +@USE_LIBARCHIVE_TRUE@am__append_24 = $(OT_DEP_LIBARCHIVE_LIBS) +@USE_AVAHI_TRUE@am__append_25 = $(OT_DEP_AVAHI_CFLAGS) +@USE_AVAHI_TRUE@am__append_26 = $(OT_DEP_AVAHI_LIBS) +@BUILDOPT_SYSTEMD_TRUE@am__append_27 = $(LIBSYSTEMD_CFLAGS) +@BUILDOPT_SYSTEMD_TRUE@am__append_28 = $(LIBSYSTEMD_LIBS) +@USE_CURL_OR_SOUP_TRUE@am__append_29 = \ @USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher.h \ @USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher-util.h \ @USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher-util.c \ @@ -441,55 +458,54 @@ check_PROGRAMS = $(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14) @USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-metalink.c \ @USE_CURL_OR_SOUP_TRUE@ $(NULL) -@USE_CURL_TRUE@am__append_28 = src/libostree/ostree-fetcher-curl.c \ + +# Only enable one fetcher backend. +@USE_CURL_TRUE@am__append_30 = src/libostree/ostree-fetcher-curl.c \ @USE_CURL_TRUE@ $(NULL) -@USE_CURL_TRUE@am__append_29 = $(OT_DEP_CURL_CFLAGS) -@USE_CURL_TRUE@am__append_30 = $(OT_DEP_CURL_LIBS) -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_31 = src/libostree/ostree-fetcher-soup.c -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_32 = $(OT_INTERNAL_SOUP_CFLAGS) -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_33 = $(OT_INTERNAL_SOUP_LIBS) -@USE_LIBMOUNT_TRUE@am__append_34 = $(OT_DEP_LIBMOUNT_CFLAGS) -@USE_LIBMOUNT_TRUE@am__append_35 = $(OT_DEP_LIBMOUNT_LIBS) -@USE_SELINUX_TRUE@am__append_36 = $(OT_DEP_SELINUX_CFLAGS) -@USE_SELINUX_TRUE@am__append_37 = $(OT_DEP_SELINUX_LIBS) -@USE_LIBSODIUM_TRUE@am__append_38 = $(OT_DEP_LIBSODIUM_CFLAGS) -@USE_LIBSODIUM_TRUE@am__append_39 = $(OT_DEP_LIBSODIUM_LIBS) -@BUILDOPT_INTROSPECTION_TRUE@am__append_40 = OSTree-1.0.gir -@BUILDOPT_INTROSPECTION_TRUE@am__append_41 = OSTree-1.0.gir -@BUILDOPT_INTROSPECTION_TRUE@am__append_42 = OSTree-1.0.typelib -@BUILDOPT_INTROSPECTION_TRUE@am__append_43 = $(gir_DATA) $(typelib_DATA) -@USE_GPGME_TRUE@am__append_44 = \ +@USE_CURL_TRUE@am__append_31 = $(OT_DEP_CURL_CFLAGS) +@USE_CURL_TRUE@am__append_32 = $(OT_DEP_CURL_LIBS) +@USE_CURL_FALSE@@USE_LIBSOUP3_TRUE@am__append_33 = src/libostree/ostree-fetcher-soup3.c +@USE_CURL_FALSE@@USE_LIBSOUP3_TRUE@am__append_34 = $(OT_INTERNAL_SOUP_CFLAGS) +@USE_CURL_FALSE@@USE_LIBSOUP3_TRUE@am__append_35 = $(OT_INTERNAL_SOUP_LIBS) +@USE_CURL_FALSE@@USE_LIBSOUP3_FALSE@@USE_LIBSOUP_TRUE@am__append_36 = src/libostree/ostree-fetcher-soup.c +@USE_CURL_FALSE@@USE_LIBSOUP3_FALSE@@USE_LIBSOUP_TRUE@am__append_37 = $(OT_INTERNAL_SOUP_CFLAGS) +@USE_CURL_FALSE@@USE_LIBSOUP3_FALSE@@USE_LIBSOUP_TRUE@am__append_38 = $(OT_INTERNAL_SOUP_LIBS) +@USE_LIBMOUNT_TRUE@am__append_39 = $(OT_DEP_LIBMOUNT_CFLAGS) +@USE_LIBMOUNT_TRUE@am__append_40 = $(OT_DEP_LIBMOUNT_LIBS) +@USE_SELINUX_TRUE@am__append_41 = $(OT_DEP_SELINUX_CFLAGS) +@USE_SELINUX_TRUE@am__append_42 = $(OT_DEP_SELINUX_LIBS) +@USE_COMPOSEFS_TRUE@am__append_43 = libcomposefs.la +@BUILDOPT_INTROSPECTION_TRUE@am__append_44 = OSTree-1.0.gir +@BUILDOPT_INTROSPECTION_TRUE@am__append_45 = OSTree-1.0.gir +@BUILDOPT_INTROSPECTION_TRUE@am__append_46 = OSTree-1.0.typelib +@BUILDOPT_INTROSPECTION_TRUE@am__append_47 = $(gir_DATA) $(typelib_DATA) +@USE_GPGME_TRUE@am__append_48 = \ @USE_GPGME_TRUE@ src/ostree/ot-builtin-gpg-sign.c \ @USE_GPGME_TRUE@ $(NULL) -@USE_GPGME_TRUE@am__append_45 = \ +@USE_GPGME_TRUE@am__append_49 = \ @USE_GPGME_TRUE@ src/ostree/ot-remote-builtin-gpg-import.c \ @USE_GPGME_TRUE@ src/ostree/ot-remote-builtin-gpg-list-keys.c \ @USE_GPGME_TRUE@ $(NULL) -@USE_CURL_OR_SOUP_TRUE@am__append_46 = src/ostree/ot-remote-builtin-add-cookie.c \ +@USE_CURL_OR_SOUP_TRUE@am__append_50 = src/ostree/ot-remote-builtin-add-cookie.c \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ot-remote-builtin-delete-cookie.c \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ot-remote-builtin-list-cookies.c \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ot-remote-cookie-util.h \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ot-remote-cookie-util.c \ @USE_CURL_OR_SOUP_TRUE@ $(NULL) src/ostree/ot-builtin-pull.c -# Eventually once we stop things from using this, we should support disabling this -@USE_LIBSOUP_TRUE@am__append_47 = src/ostree/ot-builtin-trivial-httpd.c -@USE_LIBSOUP_TRUE@am__append_48 = ostree-trivial-httpd - # This is necessary for the cookie jar bits -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_49 = $(OT_INTERNAL_SOUP_CFLAGS) -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_50 = $(OT_INTERNAL_SOUP_LIBS) -@USE_LIBARCHIVE_TRUE@am__append_51 = $(OT_DEP_LIBARCHIVE_CFLAGS) -@USE_LIBARCHIVE_TRUE@am__append_52 = $(OT_DEP_LIBARCHIVE_LIBS) -@USE_LIBSODIUM_TRUE@am__append_53 = $(OT_DEP_LIBSODIUM_CFLAGS) -@USE_LIBSODIUM_TRUE@am__append_54 = $(OT_DEP_LIBSODIUM_LIBS) +@USE_CURL_FALSE@@USE_LIBSOUP_OR_LIBSOUP3_TRUE@am__append_51 = $(OT_INTERNAL_SOUP_CFLAGS) +@USE_CURL_FALSE@@USE_LIBSOUP_OR_LIBSOUP3_TRUE@am__append_52 = $(OT_INTERNAL_SOUP_LIBS) +@USE_LIBARCHIVE_TRUE@am__append_53 = $(OT_DEP_LIBARCHIVE_CFLAGS) +@USE_LIBARCHIVE_TRUE@am__append_54 = $(OT_DEP_LIBARCHIVE_LIBS) @BUILDOPT_SYSTEMD_TRUE@am__append_55 = ostree-remount # It is built anyway as a side-effect of having the symlink in tests/, # and if we declare it here, it gets cleaned up properly @BUILDOPT_SYSTEMD_FALSE@am__append_56 = ostree-remount +@BUILDOPT_USE_STATIC_COMPILER_TRUE@am__append_57 = src/switchroot/ostree-prepare-root-static.c # ostree-prepare-root can be used as init in a system without a populated /lib. # To support this use case we need to link statically as we will be unable to @@ -501,67 +517,73 @@ check_PROGRAMS = $(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14) # to get autotools to install this as an executable but without generating rules # to make it itself which we have specified manually. See # https://lists.gnu.org/archive/html/help-gnu-utils/2007-01/msg00007.html -@BUILDOPT_USE_STATIC_COMPILER_TRUE@am__append_57 = ostree-prepare-root -@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_58 = ostree-prepare-root -@BUILDOPT_SYSTEMD_TRUE@am__append_59 = -DHAVE_SYSTEMD=1 +@BUILDOPT_USE_STATIC_COMPILER_TRUE@am__append_58 = ostree-prepare-root +@BUILDOPT_USE_STATIC_COMPILER_TRUE@am__append_59 = ostree-prepare-root +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_60 = ostree-prepare-root +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_61 = $(AM_CFLAGS) -Isrc/switchroot -I$(srcdir)/composefs -I$(srcdir)/src/libostree -I$(srcdir)/src/libotcore -I$(srcdir)/src/libotutil +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_62 = src/switchroot/ostree-prepare-root.c +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_63 = $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_DEP_CRYPTO_CFLAGS) -I $(srcdir)/libglnx +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_64 = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_DEP_CRYPTO_LIBS) libotcore.la libotutil.la libglnx.la +@USE_SELINUX_TRUE@am__append_65 = $(OT_DEP_SELINUX_CFLAGS) +@USE_SELINUX_TRUE@am__append_66 = $(OT_DEP_SELINUX_LIBS) +@USE_COMPOSEFS_TRUE@am__append_67 = libcomposefs.la +@BUILDOPT_SYSTEMD_TRUE@am__append_68 = -DHAVE_SYSTEMD=1 +@BUILDOPT_SYSTEMD_TRUE@am__append_69 = $(LIBSYSTEMD_LIBS) # This is the "new mode" of using a generator for /var; see # https://github.com/ostreedev/ostree/issues/855 -@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_60 = -DHAVE_SYSTEMD_AND_LIBMOUNT=1 -@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_61 = -DHAVE_SYSTEMD_AND_LIBMOUNT=1 +@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_70 = -DHAVE_SYSTEMD_AND_LIBMOUNT=1 +@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_71 = -DHAVE_SYSTEMD_AND_LIBMOUNT=1 @BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@systemdsystemgenerator_PROGRAMS = ostree-system-generator$(EXEEXT) -@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_62 = $(systemdsystemgenerator_PROGRAMS) +@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_72 = $(systemdsystemgenerator_PROGRAMS) # Allow the distcheck install under $prefix test to pass -@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_63 = --with-systemdsystemgeneratordir='$${libdir}/systemd/system-generators' -@BUILDOPT_FUSE_TRUE@am__append_64 = rofiles-fuse -@BUILDOPT_ASAN_TRUE@am__append_65 = OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc -@USE_GPGME_TRUE@am__append_66 = \ +@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_73 = --with-systemdsystemgeneratordir='$${libdir}/systemd/system-generators' +@BUILDOPT_FUSE_TRUE@am__append_74 = rofiles-fuse +@BUILDOPT_ASAN_TRUE@am__append_75 = OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc +@USE_GPGME_TRUE@am__append_76 = \ @USE_GPGME_TRUE@ tests/test-remote-gpg-import.sh \ @USE_GPGME_TRUE@ tests/test-remote-gpg-list-keys.sh \ @USE_GPGME_TRUE@ tests/test-gpg-signed-commit.sh \ @USE_GPGME_TRUE@ tests/test-admin-gpg.sh \ @USE_GPGME_TRUE@ $(NULL) -@BUILDOPT_FUSE_TRUE@am__append_67 = tests/test-rofiles-fuse.sh -@BUILDOPT_FUSE_TRUE@am__append_68 = tests/rofiles-fuse-symlink-stamp -@BUILDOPT_FUSE_FALSE@am__append_69 = tests/test-rofiles-fuse.sh -@USE_LIBSOUP_TRUE@am__append_70 = tests/test-remote-cookies.sh -@BUILDOPT_GJS_TRUE@am__append_71 = $(js_tests) $(js_installed_tests) -@BUILDOPT_GJS_FALSE@am__append_72 = $(js_tests) -@BUILDOPT_GJS_FALSE@am__append_73 = $(js_installed_tests) -@ENABLE_INSTALLED_TESTS_FALSE@am__append_74 = -rpath $(abs_builddir) -@USE_GPGME_TRUE@am__append_75 = \ +@BUILDOPT_FUSE_TRUE@am__append_77 = tests/test-rofiles-fuse.sh +@BUILDOPT_FUSE_TRUE@am__append_78 = tests/rofiles-fuse-symlink-stamp +@BUILDOPT_FUSE_FALSE@am__append_79 = tests/test-rofiles-fuse.sh +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@am__append_80 = tests/test-remote-cookies.sh +@BUILDOPT_GJS_TRUE@am__append_81 = $(js_tests) $(js_installed_tests) +@BUILDOPT_GJS_FALSE@am__append_82 = $(js_tests) +@BUILDOPT_GJS_FALSE@am__append_83 = $(js_installed_tests) +@USE_GPGME_TRUE@am__append_84 = \ @USE_GPGME_TRUE@ tests/test-gpg-verify-result \ @USE_GPGME_TRUE@ $(NULL) -@USE_AVAHI_TRUE@am__append_76 = tests/test-repo-finder-avahi -@USE_LIBARCHIVE_TRUE@am__append_77 = tests/test-libarchive-import -@USE_GPGME_TRUE@am__append_78 = \ +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@am__append_85 = ostree-trivial-httpd +@USE_AVAHI_TRUE@am__append_86 = tests/test-repo-finder-avahi +@USE_LIBARCHIVE_TRUE@am__append_87 = tests/test-libarchive-import +@USE_GPGME_TRUE@am__append_88 = \ @USE_GPGME_TRUE@ tests/gpg-verify-data/README.md \ @USE_GPGME_TRUE@ $(NULL) -@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__append_79 = $(_installed_or_uninstalled_test_scripts) -@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__append_80 = $(_installed_or_uninstalled_test_programs) -@ENABLE_INSTALLED_TESTS_TRUE@am__append_81 = install-installed-tests-extra +@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__append_89 = $(_installed_or_uninstalled_test_scripts) +@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__append_90 = $(_installed_or_uninstalled_test_programs) +@ENABLE_INSTALLED_TESTS_TRUE@am__append_91 = install-installed-tests-extra # Allow the distcheck install under $prefix test to pass -@BUILDOPT_SYSTEMD_TRUE@am__append_82 = --with-systemdsystemunitdir='$${libdir}/systemd/system' +@BUILDOPT_SYSTEMD_TRUE@am__append_92 = --with-systemdsystemunitdir='$${libdir}/systemd/system' # We're using the system grub2-mkconfig generator -@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_83 = src/boot/grub2/grub2-15_ostree -@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_84 = install-grub2-config-hook +@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_93 = src/boot/grub2/grub2-15_ostree +@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_94 = install-grub2-config-hook # We're using our internal generator -@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_TRUE@am__append_85 = src/boot/grub2/ostree-grub-generator -@ENABLE_MAN_TRUE@@USE_LIBSOUP_TRUE@am__append_86 = ostree-trivial-httpd.1 -# We still want to distribute the source, even if we are not building it -@ENABLE_MAN_TRUE@@USE_LIBSOUP_FALSE@am__append_87 = man/ostree-trivial-httpd.xml -@BUILDOPT_FUSE_TRUE@@ENABLE_MAN_TRUE@am__append_88 = rofiles-fuse.1 -@ENABLE_MAN_TRUE@@USE_GPGME_TRUE@am__append_89 = ostree-gpg-sign.1 -@ENABLE_MAN_HTML_TRUE@@ENABLE_MAN_TRUE@am__append_90 = $(manhtml_files) -@ENABLE_MAN_TRUE@am__append_91 = man/index.xml $(man1_MANS:.1=.xml) \ +@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_TRUE@am__append_95 = src/boot/grub2/ostree-grub-generator +@BUILDOPT_FUSE_TRUE@@ENABLE_MAN_TRUE@am__append_96 = rofiles-fuse.1 +@ENABLE_MAN_TRUE@@USE_GPGME_TRUE@am__append_97 = ostree-gpg-sign.1 +@ENABLE_MAN_HTML_TRUE@@ENABLE_MAN_TRUE@am__append_98 = $(manhtml_files) +@ENABLE_MAN_TRUE@am__append_99 = man/index.xml $(man1_MANS:.1=.xml) \ @ENABLE_MAN_TRUE@ $(man5_MANS:.5=.xml) $(XSLT_HTML_STYLESHEET) -@ENABLE_MAN_TRUE@am__append_92 = \ +@ENABLE_MAN_TRUE@am__append_100 = \ @ENABLE_MAN_TRUE@ $(man1_MANS) \ @ENABLE_MAN_TRUE@ $(man5_MANS) \ @ENABLE_MAN_TRUE@ $(manhtml_files) \ @@ -628,7 +650,7 @@ am__EXEEXT_2 = @USE_LIBARCHIVE_TRUE@ tests/test-libarchive-import$(EXEEXT) am__EXEEXT_6 = tests/test-varint$(EXEEXT) \ tests/test-ot-unix-utils$(EXEEXT) tests/test-bsdiff$(EXEEXT) \ - tests/test-mutable-tree$(EXEEXT) \ + tests/test-otcore$(EXEEXT) tests/test-mutable-tree$(EXEEXT) \ tests/test-keyfile-utils$(EXEEXT) \ tests/test-ot-opt-utils$(EXEEXT) \ tests/test-ot-tool-util$(EXEEXT) tests/test-checksum$(EXEEXT) \ @@ -645,20 +667,22 @@ am__EXEEXT_8 = tests/test-bloom$(EXEEXT) \ tests/test-repo-finder-mount$(EXEEXT) $(am__EXEEXT_2) \ $(am__EXEEXT_3) $(am__EXEEXT_7) @ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE@am__EXEEXT_9 = $(am__EXEEXT_6) -am__EXEEXT_10 = tests/get-byte-order$(EXEEXT) \ - tests/repo-finder-mount$(EXEEXT) $(am__EXEEXT_2) -am__EXEEXT_11 = $(am__EXEEXT_8) $(am__EXEEXT_9) $(am__EXEEXT_10) -@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__EXEEXT_12 = $(am__EXEEXT_11) -am__EXEEXT_13 = test-libglnx-xattrs$(EXEEXT) \ +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@am__EXEEXT_10 = \ +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@ ostree-trivial-httpd$(EXEEXT) +am__EXEEXT_11 = tests/get-byte-order$(EXEEXT) \ + tests/repo-finder-mount$(EXEEXT) $(am__EXEEXT_2) \ + $(am__EXEEXT_10) +am__EXEEXT_12 = $(am__EXEEXT_8) $(am__EXEEXT_9) $(am__EXEEXT_11) +@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__EXEEXT_13 = $(am__EXEEXT_12) +am__EXEEXT_14 = test-libglnx-xattrs$(EXEEXT) \ test-libglnx-fdio$(EXEEXT) test-libglnx-errors$(EXEEXT) \ test-libglnx-macros$(EXEEXT) test-libglnx-shutil$(EXEEXT) -@BUILDOPT_SYSTEMD_FALSE@am__EXEEXT_14 = ostree-remount$(EXEEXT) -@ENABLE_INSTALLED_TESTS_TRUE@am__EXEEXT_15 = $(am__EXEEXT_8) \ -@ENABLE_INSTALLED_TESTS_TRUE@ $(am__EXEEXT_9) $(am__EXEEXT_10) -@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_16 = $(am__EXEEXT_11) -@BUILDOPT_SYSTEMD_TRUE@am__EXEEXT_17 = ostree-remount$(EXEEXT) -@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__EXEEXT_18 = ostree-prepare-root$(EXEEXT) -@USE_LIBSOUP_TRUE@am__EXEEXT_19 = ostree-trivial-httpd$(EXEEXT) +@BUILDOPT_SYSTEMD_FALSE@am__EXEEXT_15 = ostree-remount$(EXEEXT) +@ENABLE_INSTALLED_TESTS_TRUE@am__EXEEXT_16 = $(am__EXEEXT_8) \ +@ENABLE_INSTALLED_TESTS_TRUE@ $(am__EXEEXT_9) $(am__EXEEXT_11) +@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_17 = $(am__EXEEXT_12) +@BUILDOPT_SYSTEMD_TRUE@am__EXEEXT_18 = ostree-remount$(EXEEXT) +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__EXEEXT_19 = ostree-prepare-root$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(installed_test_PROGRAMS) \ $(libexec_PROGRAMS) $(noinst_PROGRAMS) $(ostree_boot_PROGRAMS) \ $(pkglibexec_PROGRAMS) $(sbin_PROGRAMS) \ @@ -710,13 +734,26 @@ am_libbupsplit_la_OBJECTS = src/libostree/bupsplit.lo libbupsplit_la_OBJECTS = $(am_libbupsplit_la_OBJECTS) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +libcomposefs_la_DEPENDENCIES = $(am__DEPENDENCIES_2) +am_libcomposefs_la_OBJECTS = \ + composefs/libcomposefs/libcomposefs_la-hash.lo \ + composefs/libcomposefs/libcomposefs_la-lcfs-fsverity.lo \ + composefs/libcomposefs/libcomposefs_la-lcfs-writer-erofs.lo \ + composefs/libcomposefs/libcomposefs_la-lcfs-writer.lo \ + composefs/libcomposefs/libcomposefs_la-lcfs-mount.lo +libcomposefs_la_OBJECTS = $(am_libcomposefs_la_OBJECTS) +libcomposefs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libcomposefs_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +@USE_COMPOSEFS_TRUE@am_libcomposefs_la_rpath = libglnx_la_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_libglnx_la_OBJECTS = libglnx/la-glnx-backports.lo \ - libglnx/la-glnx-local-alloc.lo libglnx/la-glnx-errors.lo \ - libglnx/la-glnx-console.lo libglnx/la-glnx-dirfd.lo \ - libglnx/la-glnx-fdio.lo libglnx/la-glnx-lockfile.lo \ - libglnx/la-glnx-xattrs.lo libglnx/la-glnx-shutil.lo \ - $(am__objects_1) +am_libglnx_la_OBJECTS = libglnx/la-glnx-backport-testutils.lo \ + libglnx/la-glnx-backports.lo libglnx/la-glnx-local-alloc.lo \ + libglnx/la-glnx-errors.lo libglnx/la-glnx-console.lo \ + libglnx/la-glnx-dirfd.lo libglnx/la-glnx-fdio.lo \ + libglnx/la-glnx-lockfile.lo libglnx/la-glnx-xattrs.lo \ + libglnx/la-glnx-shutil.lo $(am__objects_1) libglnx_la_OBJECTS = $(am_libglnx_la_OBJECTS) libglnx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libglnx_la_CFLAGS) \ @@ -727,19 +764,21 @@ libglnx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ @USE_AVAHI_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) @BUILDOPT_SYSTEMD_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) @USE_CURL_TRUE@am__DEPENDENCIES_7 = $(am__DEPENDENCIES_1) -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__DEPENDENCIES_8 = \ -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@ $(am__DEPENDENCIES_2) -@USE_LIBMOUNT_TRUE@am__DEPENDENCIES_9 = $(am__DEPENDENCIES_1) -@USE_SELINUX_TRUE@am__DEPENDENCIES_10 = $(am__DEPENDENCIES_1) -@USE_LIBSODIUM_TRUE@am__DEPENDENCIES_11 = $(am__DEPENDENCIES_1) -libostree_1_la_DEPENDENCIES = libotutil.la libglnx.la libbsdiff.la \ - $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \ +@USE_LIBSOUP3_FALSE@am__DEPENDENCIES_8 = $(am__DEPENDENCIES_1) +@USE_LIBSOUP3_TRUE@am__DEPENDENCIES_8 = $(am__DEPENDENCIES_1) +@USE_CURL_FALSE@@USE_LIBSOUP3_TRUE@am__DEPENDENCIES_9 = \ +@USE_CURL_FALSE@@USE_LIBSOUP3_TRUE@ $(am__DEPENDENCIES_8) +@USE_CURL_FALSE@@USE_LIBSOUP3_FALSE@@USE_LIBSOUP_TRUE@am__DEPENDENCIES_10 = $(am__DEPENDENCIES_8) +@USE_LIBMOUNT_TRUE@am__DEPENDENCIES_11 = $(am__DEPENDENCIES_1) +@USE_SELINUX_TRUE@am__DEPENDENCIES_12 = $(am__DEPENDENCIES_1) +libostree_1_la_DEPENDENCIES = libotutil.la libotcore.la libglnx.la \ + libbsdiff.la $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(bupsplitpath) $(am__DEPENDENCIES_4) \ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_6) \ - $(am__DEPENDENCIES_7) $(am__DEPENDENCIES_8) \ - $(am__DEPENDENCIES_9) $(am__DEPENDENCIES_10) \ - $(am__DEPENDENCIES_11) + $(am__DEPENDENCIES_7) $(am__DEPENDENCIES_9) \ + $(am__DEPENDENCIES_10) $(am__DEPENDENCIES_11) \ + $(am__DEPENDENCIES_12) $(am__append_43) am__libostree_1_la_SOURCES_DIST = \ src/libostree/ostree-async-progress.c \ src/libostree/ostree-cmd-private.h \ @@ -770,6 +809,7 @@ am__libostree_1_la_SOURCES_DIST = \ src/libostree/ostree-repo-os.c src/libostree/ostree-repo.c \ src/libostree/ostree-repo-checkout.c \ src/libostree/ostree-repo-commit.c \ + src/libostree/ostree-repo-composefs.c \ src/libostree/ostree-repo-pull.c \ src/libostree/ostree-repo-pull-private.h \ src/libostree/ostree-repo-pull-verify.c \ @@ -794,6 +834,8 @@ am__libostree_1_la_SOURCES_DIST = \ src/libostree/ostree-deployment.c \ src/libostree/ostree-bootloader.h \ src/libostree/ostree-bootloader.c \ + src/libostree/ostree-bootloader-aboot.h \ + src/libostree/ostree-bootloader-aboot.c \ src/libostree/ostree-bootloader-grub2.h \ src/libostree/ostree-bootloader-grub2.c \ src/libostree/ostree-bootloader-zipl.h \ @@ -816,6 +858,7 @@ am__libostree_1_la_SOURCES_DIST = \ src/libostree/ostree-repo-finder-mount.c \ src/libostree/ostree-repo-finder-override.c \ src/libostree/ostree-kernel-args.h \ + src/libostree/ostree-kernel-args-private.h \ src/libostree/ostree-kernel-args.c \ src/libostree/ostree-libarchive-input-stream.h \ src/libostree/ostree-libarchive-input-stream.c \ @@ -836,12 +879,14 @@ am__libostree_1_la_SOURCES_DIST = \ src/libostree/ostree-metalink.h \ src/libostree/ostree-metalink.c \ src/libostree/ostree-fetcher-curl.c \ + src/libostree/ostree-fetcher-soup3.c \ src/libostree/ostree-fetcher-soup.c \ src/libostree/ostree-sign.c src/libostree/ostree-sign.h \ src/libostree/ostree-sign-dummy.c \ src/libostree/ostree-sign-dummy.h \ src/libostree/ostree-sign-ed25519.c \ - src/libostree/ostree-sign-ed25519.h + src/libostree/ostree-sign-ed25519.h \ + src/libostree/ostree-sign-private.h @USE_LIBARCHIVE_TRUE@am__objects_2 = src/libostree/libostree_1_la-ostree-libarchive-input-stream.lo \ @USE_LIBARCHIVE_TRUE@ $(am__objects_1) @HAVE_LIBSOUP_CLIENT_CERTS_TRUE@am__objects_3 = src/libostree/libostree_1_la-ostree-tls-cert-interaction.lo \ @@ -859,7 +904,8 @@ am__libostree_1_la_SOURCES_DIST = \ @USE_CURL_OR_SOUP_TRUE@ $(am__objects_1) @USE_CURL_TRUE@am__objects_8 = src/libostree/libostree_1_la-ostree-fetcher-curl.lo \ @USE_CURL_TRUE@ $(am__objects_1) -@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__objects_9 = src/libostree/libostree_1_la-ostree-fetcher-soup.lo +@USE_CURL_FALSE@@USE_LIBSOUP3_TRUE@am__objects_9 = src/libostree/libostree_1_la-ostree-fetcher-soup3.lo +@USE_CURL_FALSE@@USE_LIBSOUP3_FALSE@@USE_LIBSOUP_TRUE@am__objects_10 = src/libostree/libostree_1_la-ostree-fetcher-soup.lo am_libostree_1_la_OBJECTS = \ src/libostree/libostree_1_la-ostree-async-progress.lo \ src/libostree/libostree_1_la-ostree-cmd-private.lo \ @@ -883,6 +929,7 @@ am_libostree_1_la_OBJECTS = \ src/libostree/libostree_1_la-ostree-repo.lo \ src/libostree/libostree_1_la-ostree-repo-checkout.lo \ src/libostree/libostree_1_la-ostree-repo-commit.lo \ + src/libostree/libostree_1_la-ostree-repo-composefs.lo \ src/libostree/libostree_1_la-ostree-repo-pull.lo \ src/libostree/libostree_1_la-ostree-repo-pull-verify.lo \ src/libostree/libostree_1_la-ostree-repo-libarchive.lo \ @@ -901,6 +948,7 @@ am_libostree_1_la_OBJECTS = \ src/libostree/libostree_1_la-ostree-bootconfig-parser.lo \ src/libostree/libostree_1_la-ostree-deployment.lo \ src/libostree/libostree_1_la-ostree-bootloader.lo \ + src/libostree/libostree_1_la-ostree-bootloader-aboot.lo \ src/libostree/libostree_1_la-ostree-bootloader-grub2.lo \ src/libostree/libostree_1_la-ostree-bootloader-zipl.lo \ src/libostree/libostree_1_la-ostree-bootloader-syslinux.lo \ @@ -919,7 +967,7 @@ am_libostree_1_la_OBJECTS = \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - src/libostree/libostree_1_la-ostree-sign.lo \ + $(am__objects_10) src/libostree/libostree_1_la-ostree-sign.lo \ src/libostree/libostree_1_la-ostree-sign-dummy.lo \ src/libostree/libostree_1_la-ostree-sign-ed25519.lo \ $(am__objects_1) @@ -932,10 +980,10 @@ libostree_1_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libostree_1_la_CFLAGS) $(CFLAGS) $(libostree_1_la_LDFLAGS) \ $(LDFLAGS) -o $@ -am__DEPENDENCIES_12 = libglnx.la libotutil.la libostree-1.la \ +am__DEPENDENCIES_13 = libglnx.la libotutil.la libostree-1.la \ $(am__DEPENDENCIES_2) -am__DEPENDENCIES_13 = $(am__DEPENDENCIES_12) $(am__DEPENDENCIES_2) -libostreetest_la_DEPENDENCIES = $(am__DEPENDENCIES_13) +am__DEPENDENCIES_14 = $(am__DEPENDENCIES_13) $(am__DEPENDENCIES_2) +libostreetest_la_DEPENDENCIES = $(am__DEPENDENCIES_14) am_libostreetest_la_OBJECTS = tests/libostreetest_la-libostreetest.lo \ tests/libostreetest_la-test-mock-gio.lo libostreetest_la_OBJECTS = $(am_libostreetest_la_OBJECTS) @@ -943,8 +991,20 @@ libostreetest_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libostreetest_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ +libotcore_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libotcore_la_OBJECTS = \ + src/libotcore/libotcore_la-otcore-ed25519-verify.lo \ + src/libotcore/libotcore_la-otcore-prepare-root.lo \ + $(am__objects_1) +libotcore_la_OBJECTS = $(am_libotcore_la_OBJECTS) +libotcore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libotcore_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ libotutil_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am__libotutil_la_SOURCES_DIST = src/libotutil/ot-checksum-utils.c \ src/libotutil/ot-checksum-utils.h \ src/libotutil/ot-checksum-instream.c \ @@ -962,7 +1022,7 @@ am__libotutil_la_SOURCES_DIST = src/libotutil/ot-checksum-utils.c \ src/libotutil/ot-tool-util.h src/libotutil/ot-gpg-utils.c \ src/libotutil/ot-gpg-utils.h src/libotutil/zbase32.c \ src/libotutil/zbase32.h -@USE_GPGME_TRUE@am__objects_10 = \ +@USE_GPGME_TRUE@am__objects_11 = \ @USE_GPGME_TRUE@ src/libotutil/libotutil_la-ot-gpg-utils.lo \ @USE_GPGME_TRUE@ src/libotutil/libotutil_la-zbase32.lo \ @USE_GPGME_TRUE@ $(am__objects_1) @@ -977,24 +1037,11 @@ am_libotutil_la_OBJECTS = \ src/libotutil/libotutil_la-ot-variant-builder.lo \ src/libotutil/libotutil_la-ot-gio-utils.lo \ src/libotutil/libotutil_la-ot-tool-util.lo $(am__objects_1) \ - $(am__objects_10) + $(am__objects_11) libotutil_la_OBJECTS = $(am_libotutil_la_OBJECTS) libotutil_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libotutil_la_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -libreaddir_rand_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_1) -am_libreaddir_rand_la_OBJECTS = \ - tests/libreaddir_rand_la-readdir-rand.lo -libreaddir_rand_la_OBJECTS = $(am_libreaddir_rand_la_OBJECTS) -libreaddir_rand_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libreaddir_rand_la_CFLAGS) $(CFLAGS) \ - $(libreaddir_rand_la_LDFLAGS) $(LDFLAGS) -o $@ -@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am_libreaddir_rand_la_rpath = -@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am_libreaddir_rand_la_rpath = -@ENABLE_INSTALLED_TESTS_TRUE@am_libreaddir_rand_la_rpath = -rpath \ -@ENABLE_INSTALLED_TESTS_TRUE@ $(installed_testdir) am__ostree_SOURCES_DIST = src/ostree/main.c \ src/ostree/ot-builtin-admin.c src/ostree/ot-builtins.h \ src/ostree/ot-builtin-cat.c src/ostree/ot-builtin-config.c \ @@ -1021,7 +1068,9 @@ am__ostree_SOURCES_DIST = src/ostree/main.c \ src/ostree/ot-admin-builtin-finalize-staged.c \ src/ostree/ot-admin-builtin-boot-complete.c \ src/ostree/ot-admin-builtin-undeploy.c \ + src/ostree/ot-admin-builtin-set-default.c \ src/ostree/ot-admin-builtin-instutil.c \ + src/ostree/ot-admin-builtin-kargs.c \ src/ostree/ot-admin-builtin-cleanup.c \ src/ostree/ot-admin-builtin-os-init.c \ src/ostree/ot-admin-builtin-set-origin.c \ @@ -1037,6 +1086,8 @@ am__ostree_SOURCES_DIST = src/ostree/main.c \ src/ostree/ot-admin-instutil-builtins.h \ src/ostree/ot-admin-functions.h \ src/ostree/ot-admin-functions.c \ + src/ostree/ot-admin-kargs-builtins.h \ + src/ostree/ot-admin-kargs-builtin-edit-in-place.c \ src/ostree/ot-remote-builtins.h \ src/ostree/ot-remote-builtin-add.c \ src/ostree/ot-remote-builtin-delete.c \ @@ -1051,20 +1102,18 @@ am__ostree_SOURCES_DIST = src/ostree/main.c \ src/ostree/ot-remote-builtin-list-cookies.c \ src/ostree/ot-remote-cookie-util.h \ src/ostree/ot-remote-cookie-util.c \ - src/ostree/ot-builtin-pull.c \ - src/ostree/ot-builtin-trivial-httpd.c -@USE_GPGME_TRUE@am__objects_11 = src/ostree/ostree-ot-builtin-gpg-sign.$(OBJEXT) \ + src/ostree/ot-builtin-pull.c +@USE_GPGME_TRUE@am__objects_12 = src/ostree/ostree-ot-builtin-gpg-sign.$(OBJEXT) \ @USE_GPGME_TRUE@ $(am__objects_1) -@USE_GPGME_TRUE@am__objects_12 = src/ostree/ostree-ot-remote-builtin-gpg-import.$(OBJEXT) \ +@USE_GPGME_TRUE@am__objects_13 = src/ostree/ostree-ot-remote-builtin-gpg-import.$(OBJEXT) \ @USE_GPGME_TRUE@ src/ostree/ostree-ot-remote-builtin-gpg-list-keys.$(OBJEXT) \ @USE_GPGME_TRUE@ $(am__objects_1) -@USE_CURL_OR_SOUP_TRUE@am__objects_13 = src/ostree/ostree-ot-remote-builtin-add-cookie.$(OBJEXT) \ +@USE_CURL_OR_SOUP_TRUE@am__objects_14 = src/ostree/ostree-ot-remote-builtin-add-cookie.$(OBJEXT) \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-remote-builtin-delete-cookie.$(OBJEXT) \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-remote-builtin-list-cookies.$(OBJEXT) \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-remote-cookie-util.$(OBJEXT) \ @USE_CURL_OR_SOUP_TRUE@ $(am__objects_1) \ @USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-builtin-pull.$(OBJEXT) -@USE_LIBSOUP_TRUE@am__objects_14 = src/ostree/ostree-ot-builtin-trivial-httpd.$(OBJEXT) am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \ src/ostree/ostree-ot-builtin-admin.$(OBJEXT) \ src/ostree/ostree-ot-builtin-cat.$(OBJEXT) \ @@ -1093,14 +1142,16 @@ am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \ src/ostree/ostree-ot-main.$(OBJEXT) \ src/ostree/ostree-ot-dump.$(OBJEXT) \ src/ostree/ostree-ot-editor.$(OBJEXT) $(am__objects_1) \ - $(am__objects_11) \ + $(am__objects_12) \ src/ostree/ostree-ot-admin-builtin-init-fs.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-diff.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-deploy.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-finalize-staged.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-boot-complete.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-undeploy.$(OBJEXT) \ + src/ostree/ostree-ot-admin-builtin-set-default.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-instutil.$(OBJEXT) \ + src/ostree/ostree-ot-admin-builtin-kargs.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-cleanup.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-os-init.$(OBJEXT) \ src/ostree/ostree-ot-admin-builtin-set-origin.$(OBJEXT) \ @@ -1113,6 +1164,7 @@ am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \ src/ostree/ostree-ot-admin-instutil-builtin-set-kargs.$(OBJEXT) \ src/ostree/ostree-ot-admin-instutil-builtin-grub2-generate.$(OBJEXT) \ src/ostree/ostree-ot-admin-functions.$(OBJEXT) \ + src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.$(OBJEXT) \ $(am__objects_1) \ src/ostree/ostree-ot-remote-builtin-add.$(OBJEXT) \ src/ostree/ostree-ot-remote-builtin-delete.$(OBJEXT) \ @@ -1120,22 +1172,32 @@ am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \ src/ostree/ostree-ot-remote-builtin-show-url.$(OBJEXT) \ src/ostree/ostree-ot-remote-builtin-refs.$(OBJEXT) \ src/ostree/ostree-ot-remote-builtin-summary.$(OBJEXT) \ - $(am__objects_1) $(am__objects_12) $(am__objects_13) \ - $(am__objects_14) + $(am__objects_1) $(am__objects_13) $(am__objects_14) nodist_ostree_OBJECTS = src/ostree/ostree-parse-datetime.$(OBJEXT) \ $(am__objects_1) ostree_OBJECTS = $(am_ostree_OBJECTS) $(nodist_ostree_OBJECTS) -ostree_DEPENDENCIES = $(am__DEPENDENCIES_12) libbsdiff.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_8) \ - $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_11) +@USE_CURL_FALSE@@USE_LIBSOUP_OR_LIBSOUP3_TRUE@am__DEPENDENCIES_15 = $(am__DEPENDENCIES_8) +ostree_DEPENDENCIES = $(am__DEPENDENCIES_13) libbsdiff.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_15) \ + $(am__DEPENDENCIES_4) ostree_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ostree_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am_ostree_prepare_root_OBJECTS = src/switchroot/ostree_prepare_root-ostree-prepare-root.$(OBJEXT) \ - $(am__objects_1) +am__ostree_prepare_root_SOURCES_DIST = \ + src/switchroot/ostree-mount-util.h \ + src/switchroot/ostree-prepare-root-static.c \ + src/switchroot/ostree-prepare-root.c +@BUILDOPT_USE_STATIC_COMPILER_TRUE@am__objects_15 = src/switchroot/ostree_prepare_root-ostree-prepare-root-static.$(OBJEXT) +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__objects_16 = src/switchroot/ostree_prepare_root-ostree-prepare-root.$(OBJEXT) +am_ostree_prepare_root_OBJECTS = $(am__objects_15) $(am__objects_16) ostree_prepare_root_OBJECTS = $(am_ostree_prepare_root_OBJECTS) -@BUILDOPT_SYSTEMD_TRUE@ostree_prepare_root_DEPENDENCIES = \ -@BUILDOPT_SYSTEMD_TRUE@ $(am__DEPENDENCIES_1) +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__DEPENDENCIES_16 = \ +@BUILDOPT_USE_STATIC_COMPILER_FALSE@ $(am__DEPENDENCIES_2) \ +@BUILDOPT_USE_STATIC_COMPILER_FALSE@ $(am__DEPENDENCIES_1) \ +@BUILDOPT_USE_STATIC_COMPILER_FALSE@ libotcore.la libotutil.la \ +@BUILDOPT_USE_STATIC_COMPILER_FALSE@ libglnx.la +ostree_prepare_root_DEPENDENCIES = $(am__DEPENDENCIES_16) \ + $(am__append_67) $(am__DEPENDENCIES_6) ostree_prepare_root_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(ostree_prepare_root_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1144,7 +1206,8 @@ am_ostree_remount_OBJECTS = \ src/switchroot/ostree_remount-ostree-remount.$(OBJEXT) \ $(am__objects_1) ostree_remount_OBJECTS = $(am_ostree_remount_OBJECTS) -ostree_remount_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la +ostree_remount_DEPENDENCIES = $(am__DEPENDENCIES_2) libotcore.la \ + libotutil.la libglnx.la $(am__DEPENDENCIES_12) am__ostree_system_generator_SOURCES_DIST = \ src/switchroot/ostree-mount-util.h \ src/switchroot/ostree-system-generator.c @@ -1160,10 +1223,11 @@ ostree_system_generator_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(LDFLAGS) -o $@ am__ostree_trivial_httpd_SOURCES_DIST = \ src/ostree/ostree-trivial-httpd.c -@USE_LIBSOUP_TRUE@am_ostree_trivial_httpd_OBJECTS = src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.$(OBJEXT) +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@am_ostree_trivial_httpd_OBJECTS = src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.$(OBJEXT) ostree_trivial_httpd_OBJECTS = $(am_ostree_trivial_httpd_OBJECTS) -@USE_LIBSOUP_TRUE@ostree_trivial_httpd_DEPENDENCIES = \ -@USE_LIBSOUP_TRUE@ $(am__DEPENDENCIES_12) $(am__DEPENDENCIES_2) +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@ostree_trivial_httpd_DEPENDENCIES = \ +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@ $(am__DEPENDENCIES_14) \ +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@ $(am__DEPENDENCIES_8) ostree_trivial_httpd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(ostree_trivial_httpd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1177,9 +1241,9 @@ rofiles_fuse_OBJECTS = $(am_rofiles_fuse_OBJECTS) rofiles_fuse_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rofiles_fuse_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_15 = \ +am__objects_17 = \ libglnx/tests/test_libglnx_errors-libglnx-testlib.$(OBJEXT) -am_test_libglnx_errors_OBJECTS = $(am__objects_15) \ +am_test_libglnx_errors_OBJECTS = $(am__objects_17) \ libglnx/tests/test_libglnx_errors-test-libglnx-errors.$(OBJEXT) test_libglnx_errors_OBJECTS = $(am_test_libglnx_errors_OBJECTS) test_libglnx_errors_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la @@ -1187,9 +1251,9 @@ test_libglnx_errors_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_libglnx_errors_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -am__objects_16 = \ +am__objects_18 = \ libglnx/tests/test_libglnx_fdio-libglnx-testlib.$(OBJEXT) -am_test_libglnx_fdio_OBJECTS = $(am__objects_16) \ +am_test_libglnx_fdio_OBJECTS = $(am__objects_18) \ libglnx/tests/test_libglnx_fdio-test-libglnx-fdio.$(OBJEXT) test_libglnx_fdio_OBJECTS = $(am_test_libglnx_fdio_OBJECTS) test_libglnx_fdio_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la @@ -1197,9 +1261,9 @@ test_libglnx_fdio_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_libglnx_fdio_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ -am__objects_17 = \ +am__objects_19 = \ libglnx/tests/test_libglnx_macros-libglnx-testlib.$(OBJEXT) -am_test_libglnx_macros_OBJECTS = $(am__objects_17) \ +am_test_libglnx_macros_OBJECTS = $(am__objects_19) \ libglnx/tests/test_libglnx_macros-test-libglnx-macros.$(OBJEXT) test_libglnx_macros_OBJECTS = $(am_test_libglnx_macros_OBJECTS) test_libglnx_macros_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la @@ -1207,9 +1271,9 @@ test_libglnx_macros_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_libglnx_macros_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -am__objects_18 = \ +am__objects_20 = \ libglnx/tests/test_libglnx_shutil-libglnx-testlib.$(OBJEXT) -am_test_libglnx_shutil_OBJECTS = $(am__objects_18) \ +am_test_libglnx_shutil_OBJECTS = $(am__objects_20) \ libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.$(OBJEXT) test_libglnx_shutil_OBJECTS = $(am_test_libglnx_shutil_OBJECTS) test_libglnx_shutil_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la @@ -1217,9 +1281,9 @@ test_libglnx_shutil_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_libglnx_shutil_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -am__objects_19 = \ +am__objects_21 = \ libglnx/tests/test_libglnx_xattrs-libglnx-testlib.$(OBJEXT) -am_test_libglnx_xattrs_OBJECTS = $(am__objects_19) \ +am_test_libglnx_xattrs_OBJECTS = $(am__objects_21) \ libglnx/tests/test_libglnx_xattrs-test-libglnx-xattrs.$(OBJEXT) test_libglnx_xattrs_OBJECTS = $(am_test_libglnx_xattrs_OBJECTS) test_libglnx_xattrs_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la @@ -1239,7 +1303,7 @@ am_tests_repo_finder_mount_OBJECTS = \ tests/repo_finder_mount-repo-finder-mount.$(OBJEXT) tests_repo_finder_mount_OBJECTS = \ $(am_tests_repo_finder_mount_OBJECTS) -tests_repo_finder_mount_DEPENDENCIES = $(am__DEPENDENCIES_13) \ +tests_repo_finder_mount_DEPENDENCIES = $(am__DEPENDENCIES_14) \ libostreetest.la tests_repo_finder_mount_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -1248,8 +1312,8 @@ tests_repo_finder_mount_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_basic_c_SOURCES = tests/test-basic-c.c tests_test_basic_c_OBJECTS = \ tests/test_basic_c-test-basic-c.$(OBJEXT) -am__DEPENDENCIES_14 = $(am__DEPENDENCIES_13) libostreetest.la -tests_test_basic_c_DEPENDENCIES = $(am__DEPENDENCIES_14) +am__DEPENDENCIES_17 = $(am__DEPENDENCIES_14) libostreetest.la +tests_test_basic_c_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_basic_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_basic_c_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1258,14 +1322,14 @@ am_tests_test_bloom_OBJECTS = \ src/libostree/tests_test_bloom-ostree-bloom.$(OBJEXT) \ tests/test_bloom-test-bloom.$(OBJEXT) tests_test_bloom_OBJECTS = $(am_tests_test_bloom_OBJECTS) -tests_test_bloom_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_bloom_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_bloom_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_bloom_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ tests_test_bsdiff_SOURCES = tests/test-bsdiff.c tests_test_bsdiff_OBJECTS = tests/test_bsdiff-test-bsdiff.$(OBJEXT) -tests_test_bsdiff_DEPENDENCIES = libbsdiff.la $(am__DEPENDENCIES_14) +tests_test_bsdiff_DEPENDENCIES = libbsdiff.la $(am__DEPENDENCIES_17) tests_test_bsdiff_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_bsdiff_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -1275,7 +1339,7 @@ am_tests_test_checksum_OBJECTS = \ src/libostree/tests_test_checksum-ostree-varint.$(OBJEXT) \ tests/test_checksum-test-checksum.$(OBJEXT) tests_test_checksum_OBJECTS = $(am_tests_test_checksum_OBJECTS) -tests_test_checksum_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_checksum_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_checksum_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_checksum_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1283,7 +1347,7 @@ tests_test_checksum_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_commit_sign_sh_ext_SOURCES = \ tests/test-commit-sign-sh-ext.c tests_test_commit_sign_sh_ext_OBJECTS = tests/test_commit_sign_sh_ext-test-commit-sign-sh-ext.$(OBJEXT) -tests_test_commit_sign_sh_ext_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_commit_sign_sh_ext_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_commit_sign_sh_ext_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_commit_sign_sh_ext_CFLAGS) $(CFLAGS) \ @@ -1295,7 +1359,7 @@ am__tests_test_gpg_verify_result_SOURCES_DIST = \ tests_test_gpg_verify_result_OBJECTS = \ $(am_tests_test_gpg_verify_result_OBJECTS) @USE_GPGME_TRUE@tests_test_gpg_verify_result_DEPENDENCIES = \ -@USE_GPGME_TRUE@ $(am__DEPENDENCIES_14) $(am__DEPENDENCIES_3) +@USE_GPGME_TRUE@ $(am__DEPENDENCIES_17) $(am__DEPENDENCIES_3) tests_test_gpg_verify_result_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_gpg_verify_result_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1304,7 +1368,7 @@ am_tests_test_include_ostree_h_OBJECTS = \ tests/test_include_ostree_h-test-include-ostree-h.$(OBJEXT) tests_test_include_ostree_h_OBJECTS = \ $(am_tests_test_include_ostree_h_OBJECTS) -tests_test_include_ostree_h_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_include_ostree_h_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_include_ostree_h_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_include_ostree_h_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1313,7 +1377,7 @@ am_tests_test_kargs_OBJECTS = \ src/libostree/tests_test_kargs-ostree-kernel-args.$(OBJEXT) \ tests/test_kargs-test-kargs.$(OBJEXT) tests_test_kargs_OBJECTS = $(am_tests_test_kargs_OBJECTS) -tests_test_kargs_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_kargs_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_kargs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_kargs_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -1321,7 +1385,7 @@ tests_test_kargs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_keyfile_utils_SOURCES = tests/test-keyfile-utils.c tests_test_keyfile_utils_OBJECTS = \ tests/test_keyfile_utils-test-keyfile-utils.$(OBJEXT) -tests_test_keyfile_utils_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_keyfile_utils_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_keyfile_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_keyfile_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1330,7 +1394,7 @@ am_tests_test_libarchive_import_OBJECTS = \ tests/test_libarchive_import-test-libarchive-import.$(OBJEXT) tests_test_libarchive_import_OBJECTS = \ $(am_tests_test_libarchive_import_OBJECTS) -tests_test_libarchive_import_DEPENDENCIES = $(am__DEPENDENCIES_14) \ +tests_test_libarchive_import_DEPENDENCIES = $(am__DEPENDENCIES_17) \ $(am__DEPENDENCIES_1) tests_test_libarchive_import_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -1342,7 +1406,7 @@ am_tests_test_lzma_OBJECTS = \ src/libostree/tests_test_lzma-ostree-lzma-decompressor.$(OBJEXT) \ tests/test_lzma-test-lzma.$(OBJEXT) tests_test_lzma_OBJECTS = $(am_tests_test_lzma_OBJECTS) -tests_test_lzma_DEPENDENCIES = $(am__DEPENDENCIES_14) \ +tests_test_lzma_DEPENDENCIES = $(am__DEPENDENCIES_17) \ $(am__DEPENDENCIES_1) tests_test_lzma_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -1351,7 +1415,7 @@ tests_test_lzma_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_mutable_tree_SOURCES = tests/test-mutable-tree.c tests_test_mutable_tree_OBJECTS = \ tests/test_mutable_tree-test-mutable-tree.$(OBJEXT) -tests_test_mutable_tree_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_mutable_tree_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_mutable_tree_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_mutable_tree_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1359,7 +1423,7 @@ tests_test_mutable_tree_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_ot_opt_utils_SOURCES = tests/test-ot-opt-utils.c tests_test_ot_opt_utils_OBJECTS = \ tests/test_ot_opt_utils-test-ot-opt-utils.$(OBJEXT) -tests_test_ot_opt_utils_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_ot_opt_utils_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_ot_opt_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_ot_opt_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1367,7 +1431,7 @@ tests_test_ot_opt_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_ot_tool_util_SOURCES = tests/test-ot-tool-util.c tests_test_ot_tool_util_OBJECTS = \ tests/test_ot_tool_util-test-ot-tool-util.$(OBJEXT) -tests_test_ot_tool_util_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_ot_tool_util_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_ot_tool_util_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_ot_tool_util_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1375,21 +1439,29 @@ tests_test_ot_tool_util_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_ot_unix_utils_SOURCES = tests/test-ot-unix-utils.c tests_test_ot_unix_utils_OBJECTS = \ tests/test_ot_unix_utils-test-ot-unix-utils.$(OBJEXT) -tests_test_ot_unix_utils_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_ot_unix_utils_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_ot_unix_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_ot_unix_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ +tests_test_otcore_SOURCES = tests/test-otcore.c +tests_test_otcore_OBJECTS = tests/test_otcore-test-otcore.$(OBJEXT) +tests_test_otcore_DEPENDENCIES = $(am__DEPENDENCIES_2) libotcore.la \ + libglnx.la libotutil.la +tests_test_otcore_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(tests_test_otcore_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ tests_test_pull_c_SOURCES = tests/test-pull-c.c tests_test_pull_c_OBJECTS = tests/test_pull_c-test-pull-c.$(OBJEXT) -tests_test_pull_c_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_pull_c_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_pull_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_pull_c_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ tests_test_repo_SOURCES = tests/test-repo.c tests_test_repo_OBJECTS = tests/test_repo-test-repo.$(OBJEXT) -tests_test_repo_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_repo_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_repo_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_repo_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -1402,7 +1474,7 @@ am__tests_test_repo_finder_avahi_SOURCES_DIST = \ tests_test_repo_finder_avahi_OBJECTS = \ $(am_tests_test_repo_finder_avahi_OBJECTS) @USE_AVAHI_TRUE@tests_test_repo_finder_avahi_DEPENDENCIES = \ -@USE_AVAHI_TRUE@ $(am__DEPENDENCIES_14) +@USE_AVAHI_TRUE@ $(am__DEPENDENCIES_17) tests_test_repo_finder_avahi_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_repo_finder_avahi_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1410,7 +1482,7 @@ tests_test_repo_finder_avahi_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ am_tests_test_repo_finder_config_OBJECTS = tests/test_repo_finder_config-test-repo-finder-config.$(OBJEXT) tests_test_repo_finder_config_OBJECTS = \ $(am_tests_test_repo_finder_config_OBJECTS) -tests_test_repo_finder_config_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_repo_finder_config_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_repo_finder_config_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_repo_finder_config_CFLAGS) $(CFLAGS) \ @@ -1419,7 +1491,7 @@ am_tests_test_repo_finder_mount_OBJECTS = \ tests/test_repo_finder_mount-test-repo-finder-mount.$(OBJEXT) tests_test_repo_finder_mount_OBJECTS = \ $(am_tests_test_repo_finder_mount_OBJECTS) -tests_test_repo_finder_mount_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_repo_finder_mount_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_repo_finder_mount_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_repo_finder_mount_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1428,7 +1500,7 @@ am_tests_test_rfc2616_dates_OBJECTS = src/libostree/tests_test_rfc2616_dates-ost tests/test_rfc2616_dates-test-rfc2616-dates.$(OBJEXT) tests_test_rfc2616_dates_OBJECTS = \ $(am_tests_test_rfc2616_dates_OBJECTS) -tests_test_rfc2616_dates_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_rfc2616_dates_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_rfc2616_dates_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_rfc2616_dates_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1438,7 +1510,7 @@ am_tests_test_rollsum_OBJECTS = \ tests/test_rollsum-test-rollsum.$(OBJEXT) tests_test_rollsum_OBJECTS = $(am_tests_test_rollsum_OBJECTS) tests_test_rollsum_DEPENDENCIES = $(bupsplitpath) \ - $(am__DEPENDENCIES_14) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_17) $(am__DEPENDENCIES_1) tests_test_rollsum_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_rollsum_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1448,7 +1520,7 @@ am_tests_test_rollsum_cli_OBJECTS = \ tests/test_rollsum_cli-test-rollsum-cli.$(OBJEXT) tests_test_rollsum_cli_OBJECTS = $(am_tests_test_rollsum_cli_OBJECTS) tests_test_rollsum_cli_DEPENDENCIES = $(bupsplitpath) \ - $(am__DEPENDENCIES_14) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_17) $(am__DEPENDENCIES_1) tests_test_rollsum_cli_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_rollsum_cli_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1456,7 +1528,7 @@ tests_test_rollsum_cli_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_sysroot_c_SOURCES = tests/test-sysroot-c.c tests_test_sysroot_c_OBJECTS = \ tests/test_sysroot_c-test-sysroot-c.$(OBJEXT) -tests_test_sysroot_c_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_sysroot_c_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_sysroot_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_sysroot_c_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1465,7 +1537,7 @@ am_tests_test_varint_OBJECTS = \ src/libostree/tests_test_varint-ostree-varint.$(OBJEXT) \ tests/test_varint-test-varint.$(OBJEXT) tests_test_varint_OBJECTS = $(am_tests_test_varint_OBJECTS) -tests_test_varint_DEPENDENCIES = $(am__DEPENDENCIES_14) +tests_test_varint_DEPENDENCIES = $(am__DEPENDENCIES_17) tests_test_varint_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_varint_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -1490,6 +1562,12 @@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ bsdiff/$(DEPDIR)/libbsdiff_la-bspatch.Plo \ + composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-hash.Plo \ + composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-fsverity.Plo \ + composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-mount.Plo \ + composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer-erofs.Plo \ + composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer.Plo \ + libglnx/$(DEPDIR)/la-glnx-backport-testutils.Plo \ libglnx/$(DEPDIR)/la-glnx-backports.Plo \ libglnx/$(DEPDIR)/la-glnx-console.Plo \ libglnx/$(DEPDIR)/la-glnx-dirfd.Plo \ @@ -1513,6 +1591,7 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-async-progress.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-bloom.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootconfig-parser.Plo \ + src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-aboot.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-grub2.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-syslinux.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-uboot.Plo \ @@ -1530,6 +1609,7 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-enumtypes.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-curl.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup.Plo \ + src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup3.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-uri.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verifier.Plo \ @@ -1548,6 +1628,7 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-checkout.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-commit.Plo \ + src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-composefs.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file-enumerator.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-finder-avahi-parser.Plo \ @@ -1592,6 +1673,8 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/libostree/$(DEPDIR)/tests_test_rollsum-ostree-rollsum.Po \ src/libostree/$(DEPDIR)/tests_test_rollsum_cli-ostree-rollsum.Po \ src/libostree/$(DEPDIR)/tests_test_varint-ostree-varint.Po \ + src/libotcore/$(DEPDIR)/libotcore_la-otcore-ed25519-verify.Plo \ + src/libotcore/$(DEPDIR)/libotcore_la-otcore-prepare-root.Plo \ src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-instream.Plo \ src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-utils.Plo \ src/libotutil/$(DEPDIR)/libotutil_la-ot-fs-utils.Plo \ @@ -1612,8 +1695,10 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-finalize-staged.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-init-fs.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-instutil.Po \ + src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-os-init.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-pin.Po \ + src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-origin.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-status.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-switch.Po \ @@ -1624,6 +1709,7 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-grub2-generate.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-selinux-ensure-labeled.Po \ src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-set-kargs.Po \ + src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Po \ src/ostree/$(DEPDIR)/ostree-ot-builtin-admin.Po \ src/ostree/$(DEPDIR)/ostree-ot-builtin-cat.Po \ src/ostree/$(DEPDIR)/ostree-ot-builtin-checkout.Po \ @@ -1650,7 +1736,6 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/ostree/$(DEPDIR)/ostree-ot-builtin-sign.Po \ src/ostree/$(DEPDIR)/ostree-ot-builtin-static-delta.Po \ src/ostree/$(DEPDIR)/ostree-ot-builtin-summary.Po \ - src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Po \ src/ostree/$(DEPDIR)/ostree-ot-dump.Po \ src/ostree/$(DEPDIR)/ostree-ot-editor.Po \ src/ostree/$(DEPDIR)/ostree-ot-main.Po \ @@ -1669,13 +1754,13 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ src/ostree/$(DEPDIR)/ostree-parse-datetime.Po \ src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Po \ src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Po \ + src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Po \ src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po \ src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po \ src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Po \ tests/$(DEPDIR)/get_byte_order-get-byte-order.Po \ tests/$(DEPDIR)/libostreetest_la-libostreetest.Plo \ tests/$(DEPDIR)/libostreetest_la-test-mock-gio.Plo \ - tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Plo \ tests/$(DEPDIR)/repo_finder_mount-repo-finder-mount.Po \ tests/$(DEPDIR)/test_basic_c-test-basic-c.Po \ tests/$(DEPDIR)/test_bloom-test-bloom.Po \ @@ -1692,6 +1777,7 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \ tests/$(DEPDIR)/test_ot_opt_utils-test-ot-opt-utils.Po \ tests/$(DEPDIR)/test_ot_tool_util-test-ot-tool-util.Po \ tests/$(DEPDIR)/test_ot_unix_utils-test-ot-unix-utils.Po \ + tests/$(DEPDIR)/test_otcore-test-otcore.Po \ tests/$(DEPDIR)/test_pull_c-test-pull-c.Po \ tests/$(DEPDIR)/test_repo-test-repo.Po \ tests/$(DEPDIR)/test_repo_finder_avahi-test-repo-finder-avahi.Po \ @@ -1722,12 +1808,12 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \ - $(libglnx_la_SOURCES) $(libostree_1_la_SOURCES) \ - $(nodist_libostree_1_la_SOURCES) $(libostreetest_la_SOURCES) \ - $(libotutil_la_SOURCES) $(libreaddir_rand_la_SOURCES) \ - $(ostree_SOURCES) $(nodist_ostree_SOURCES) \ - $(ostree_prepare_root_SOURCES) $(ostree_remount_SOURCES) \ - $(ostree_system_generator_SOURCES) \ + $(libcomposefs_la_SOURCES) $(libglnx_la_SOURCES) \ + $(libostree_1_la_SOURCES) $(nodist_libostree_1_la_SOURCES) \ + $(libostreetest_la_SOURCES) $(libotcore_la_SOURCES) \ + $(libotutil_la_SOURCES) $(ostree_SOURCES) \ + $(nodist_ostree_SOURCES) $(ostree_prepare_root_SOURCES) \ + $(ostree_remount_SOURCES) $(ostree_system_generator_SOURCES) \ $(ostree_trivial_httpd_SOURCES) $(rofiles_fuse_SOURCES) \ $(test_libglnx_errors_SOURCES) $(test_libglnx_fdio_SOURCES) \ $(test_libglnx_macros_SOURCES) $(test_libglnx_shutil_SOURCES) \ @@ -1741,8 +1827,9 @@ SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \ $(tests_test_libarchive_import_SOURCES) \ $(tests_test_lzma_SOURCES) tests/test-mutable-tree.c \ tests/test-ot-opt-utils.c tests/test-ot-tool-util.c \ - tests/test-ot-unix-utils.c tests/test-pull-c.c \ - tests/test-repo.c $(tests_test_repo_finder_avahi_SOURCES) \ + tests/test-ot-unix-utils.c tests/test-otcore.c \ + tests/test-pull-c.c tests/test-repo.c \ + $(tests_test_repo_finder_avahi_SOURCES) \ $(tests_test_repo_finder_config_SOURCES) \ $(tests_test_repo_finder_mount_SOURCES) \ $(tests_test_rfc2616_dates_SOURCES) \ @@ -1750,10 +1837,12 @@ SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \ $(tests_test_rollsum_cli_SOURCES) tests/test-sysroot-c.c \ $(tests_test_varint_SOURCES) DIST_SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \ - $(libglnx_la_SOURCES) $(am__libostree_1_la_SOURCES_DIST) \ - $(libostreetest_la_SOURCES) $(am__libotutil_la_SOURCES_DIST) \ - $(libreaddir_rand_la_SOURCES) $(am__ostree_SOURCES_DIST) \ - $(ostree_prepare_root_SOURCES) $(ostree_remount_SOURCES) \ + $(libcomposefs_la_SOURCES) $(libglnx_la_SOURCES) \ + $(am__libostree_1_la_SOURCES_DIST) $(libostreetest_la_SOURCES) \ + $(libotcore_la_SOURCES) $(am__libotutil_la_SOURCES_DIST) \ + $(am__ostree_SOURCES_DIST) \ + $(am__ostree_prepare_root_SOURCES_DIST) \ + $(ostree_remount_SOURCES) \ $(am__ostree_system_generator_SOURCES_DIST) \ $(am__ostree_trivial_httpd_SOURCES_DIST) \ $(am__rofiles_fuse_SOURCES_DIST) \ @@ -1769,8 +1858,8 @@ DIST_SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \ $(tests_test_libarchive_import_SOURCES) \ $(tests_test_lzma_SOURCES) tests/test-mutable-tree.c \ tests/test-ot-opt-utils.c tests/test-ot-tool-util.c \ - tests/test-ot-unix-utils.c tests/test-pull-c.c \ - tests/test-repo.c \ + tests/test-ot-unix-utils.c tests/test-otcore.c \ + tests/test-pull-c.c tests/test-repo.c \ $(am__tests_test_repo_finder_avahi_SOURCES_DIST) \ $(tests_test_repo_finder_config_SOURCES) \ $(tests_test_repo_finder_mount_SOURCES) \ @@ -2014,7 +2103,8 @@ am__EXEEXT_23 = tests/test-basic.sh \ tests/test-basic-user-only.sh tests/test-basic-root.sh \ tests/test-cli-extensions.sh tests/test-pull-subpath.sh \ tests/test-archivez.sh tests/test-remote-add.sh \ - tests/test-remote-headers.sh tests/test-commit-sign.sh \ + tests/test-remote-headers.sh tests/test-remote-refs.sh \ + tests/test-composefs.sh tests/test-commit-sign.sh \ tests/test-commit-timestamp.sh tests/test-export.sh \ tests/test-help.sh tests/test-libarchive.sh \ tests/test-parent.sh tests/test-pull-bare.sh \ @@ -2033,6 +2123,7 @@ am__EXEEXT_23 = tests/test-basic.sh \ tests/test-admin-upgrade-endoflife.sh \ tests/test-admin-upgrade-systemd-update.sh \ tests/test-admin-deploy-syslinux.sh \ + tests/test-admin-deploy-bootprefix.sh \ tests/test-admin-deploy-2.sh tests/test-admin-deploy-karg.sh \ tests/test-admin-deploy-switch.sh \ tests/test-admin-deploy-etcmerge-cornercases.sh \ @@ -2041,24 +2132,26 @@ am__EXEEXT_23 = tests/test-basic.sh \ tests/test-admin-deploy-nomerge.sh \ tests/test-admin-deploy-none.sh \ tests/test-admin-deploy-bootid-gc.sh \ - tests/test-osupdate-dtb.sh \ + tests/test-admin-deploy-whiteouts.sh \ + tests/test-admin-deploy-emptyetc.sh tests/test-osupdate-dtb.sh \ tests/test-admin-instutil-set-kargs.sh \ tests/test-admin-upgrade-not-backwards.sh \ tests/test-admin-pull-deploy-commit.sh \ tests/test-admin-pull-deploy-split.sh \ tests/test-admin-locking.sh tests/test-admin-deploy-clean.sh \ - tests/test-reset-nonlinear.sh tests/test-oldstyle-partial.sh \ - tests/test-delta.sh tests/test-delta-sign.sh \ - tests/test-delta-ed25519.sh tests/test-xattrs.sh \ - tests/test-auto-summary.sh tests/test-prune.sh \ - tests/test-concurrency.py tests/test-refs.sh \ - tests/test-demo-buildsystem.sh tests/test-switchroot.sh \ - tests/test-pull-contenturl.sh tests/test-pull-mirrorlist.sh \ - tests/test-summary-update.sh tests/test-summary-view.sh \ - tests/test-no-initramfs.sh tests/test-create-usb.sh \ - tests/test-find-remotes.sh tests/test-fsck-collections.sh \ - tests/test-fsck-delete.sh tests/test-init-collections.sh \ - tests/test-prune-collections.sh tests/test-refs-collections.sh \ + tests/test-admin-kargs.sh tests/test-reset-nonlinear.sh \ + tests/test-oldstyle-partial.sh tests/test-delta.sh \ + tests/test-delta-sign.sh tests/test-delta-ed25519.sh \ + tests/test-xattrs.sh tests/test-auto-summary.sh \ + tests/test-prune.sh tests/test-concurrency.py \ + tests/test-refs.sh tests/test-demo-buildsystem.sh \ + tests/test-switchroot.sh tests/test-pull-contenturl.sh \ + tests/test-pull-mirrorlist.sh tests/test-summary-update.sh \ + tests/test-summary-view.sh tests/test-no-initramfs.sh \ + tests/test-create-usb.sh tests/test-find-remotes.sh \ + tests/test-fsck-collections.sh tests/test-fsck-delete.sh \ + tests/test-init-collections.sh tests/test-prune-collections.sh \ + tests/test-refs-collections.sh \ tests/test-remote-add-collections.sh \ tests/test-repo-finder-mount-integration.sh \ tests/test-summary-collections.sh \ @@ -2066,7 +2159,7 @@ am__EXEEXT_23 = tests/test-basic.sh \ tests/test-signed-commit.sh tests/test-signed-pull.sh \ tests/test-pre-signed-pull.sh \ tests/test-signed-pull-summary.sh $(am__EXEEXT_2) \ - $(am__EXEEXT_20) $(am__append_67) $(am__append_70) \ + $(am__EXEEXT_20) $(am__append_77) $(am__append_80) \ $(am__EXEEXT_22) @ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__EXEEXT_24 = \ @ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@ $(am__EXEEXT_23) @@ -2095,9 +2188,11 @@ am__DIST_COMMON = $(srcdir)/Makefile-bash.am \ $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-decls.am \ $(srcdir)/Makefile-libostree-defines.am \ $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-man.am \ - $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-otutil.am \ - $(srcdir)/Makefile-switchroot.am $(srcdir)/Makefile-tests.am \ - $(srcdir)/Makefile.in $(srcdir)/bsdiff/Makefile-bsdiff.am.inc \ + $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-otcore.am \ + $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-switchroot.am \ + $(srcdir)/Makefile-tests.am $(srcdir)/Makefile.in \ + $(srcdir)/bsdiff/Makefile-bsdiff.am.inc \ + $(srcdir)/composefs/libcomposefs/Makefile-lib.am.inc \ $(srcdir)/config.h.in \ $(srcdir)/libglnx/Makefile-libglnx.am.inc \ $(srcdir)/src/rofiles-fuse/Makefile-inc.am \ @@ -2190,6 +2285,7 @@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ FUSE3_CFLAGS = @FUSE3_CFLAGS@ FUSE3_LIBS = @FUSE3_LIBS@ FUSE_CFLAGS = @FUSE_CFLAGS@ @@ -2273,6 +2369,8 @@ OT_DEP_LZMA_CFLAGS = @OT_DEP_LZMA_CFLAGS@ OT_DEP_LZMA_LIBS = @OT_DEP_LZMA_LIBS@ OT_DEP_SELINUX_CFLAGS = @OT_DEP_SELINUX_CFLAGS@ OT_DEP_SELINUX_LIBS = @OT_DEP_SELINUX_LIBS@ +OT_DEP_SOUP3_CFLAGS = @OT_DEP_SOUP3_CFLAGS@ +OT_DEP_SOUP3_LIBS = @OT_DEP_SOUP3_LIBS@ OT_DEP_SOUP_CFLAGS = @OT_DEP_SOUP_CFLAGS@ OT_DEP_SOUP_LIBS = @OT_DEP_SOUP_LIBS@ OT_DEP_ZLIB_CFLAGS = @OT_DEP_ZLIB_CFLAGS@ @@ -2370,29 +2468,28 @@ AM_CPPFLAGS = -DDATADIR='"$(datadir)"' -DLIBEXECDIR='"$(libexecdir)"' \ -DG_LOG_DOMAIN=\"OSTree\" -DOSTREE_GITREV='"$(OSTREE_GITREV)"' \ -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_66 \ '-DGLIB_VERSION_MAX_ALLOWED=G_ENCODE_VERSION(2,70)' \ - -DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_40 \ - '-DSOUP_VERSION_MAX_ALLOWED=G_ENCODE_VERSION(2,48)' + $(am__append_14) # For strict aliasing, see https://bugzilla.gnome.org/show_bug.cgi?id=791622 AM_CFLAGS = -std=gnu99 -fno-strict-aliasing $(WARN_CFLAGS) # Allow the distcheck install under $prefix test to pass AM_DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-man \ - --disable-maintainer-mode $(NULL) $(am__append_63) \ - $(am__append_82) \ + --disable-maintainer-mode $(NULL) $(am__append_73) \ + $(am__append_92) \ BASH_COMPLETIONSDIR='$${datadir}/bash-completion/completions' -SUBDIRS = . $(am__append_14) +SUBDIRS = . $(am__append_15) NULL = BUILT_SOURCES = $(top_builddir)/libglnx-config.h \ $(nodist_libostree_1_la_SOURCES) MANPAGES = CLEANFILES = $(am__append_13) $(top_builddir)/libglnx-config.h \ - $(BUILT_SOURCES) $(am__append_43) src/ostree/parse-datetime.c \ - tests/libreaddir-rand.so tests/ostree-symlink-stamp \ + $(BUILT_SOURCES) $(am__append_47) src/ostree/parse-datetime.c \ + $(am__append_59) tests/ostree-symlink-stamp \ tests/ostree-prepare-root-symlink-stamp \ tests/ostree-remount-symlink-stamp \ tests/rofiles-fuse-symlink-stamp tests/ostree \ tests/ostree-prepare-root tests/ostree-remount \ - tests/rofiles-fuse $(am__append_92) + tests/rofiles-fuse $(am__append_100) EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \ COPYING README.md libglnx/README.md libglnx/COPYING \ libglnx/LICENSES/LGPL-2.0-or-later.txt \ @@ -2400,6 +2497,7 @@ EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \ $(NULL) libglnx/Makefile-libglnx.am bsdiff/bsdiff.h \ bsdiff/bspatch.h bsdiff/LICENSE bsdiff/README.md \ bsdiff/Makefile-bsdiff.am \ + composefs/libcomposefs/Makefile-lib.am \ $(top_srcdir)/src/libostree/libostree-devel.sym \ $(top_srcdir)/src/libostree/libostree-released.sym $(NULL) \ src/libostree/README-gpg src/libostree/bupsplit.h \ @@ -2407,42 +2505,38 @@ EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \ src/libostree/ostree-enumtypes.c.template \ src/libostree/ostree-deployment-private.h \ src/libostree/ostree-repo-deprecated.h \ - src/libostree/ostree-version.h \ - src/libostree/s390x-se-luks-gencpio \ - src/ostree/parse-datetime.y buildutil/tap-driver.sh \ - buildutil/tap-test tests/glib.supp tests/ostree.supp $(NULL) \ - $(am__append_69) $(am__append_72) tests/libtest.sh \ - $(am__append_73) $(am__append_78) tests/libostreetest.h \ - tests/libtest.sh $(NULL) src/boot/dracut/module-setup.sh \ - src/boot/dracut/ostree.conf src/boot/mkinitcpio \ - src/boot/ostree-boot-complete.service \ + src/libostree/ostree-version.h src/ostree/parse-datetime.y \ + buildutil/tap-driver.sh buildutil/tap-test tests/glib.supp \ + tests/ostree.supp $(NULL) $(am__append_79) $(am__append_82) \ + tests/libtest.sh $(am__append_83) $(am__append_88) \ + tests/libostreetest.h tests/libtest.sh $(NULL) \ + src/boot/dracut/module-setup.sh src/boot/dracut/ostree.conf \ + src/boot/mkinitcpio src/boot/ostree-boot-complete.service \ src/boot/ostree-prepare-root.service \ src/boot/ostree-finalize-staged.path \ src/boot/ostree-remount.service \ src/boot/ostree-finalize-staged.service \ + src/boot/ostree-finalize-staged-hold.service \ src/boot/grub2/grub2-15_ostree \ - src/boot/grub2/ostree-grub-generator $(NULL) $(am__append_87) \ - $(am__append_91) + src/boot/grub2/ostree-grub-generator $(NULL) $(am__append_99) bin_SCRIPTS = lib_LTLIBRARIES = libostree-1.la - -# Secure Execution: script for creating new initramdisk with LUKS key and config -pkglibexec_SCRIPTS = src/libostree/s390x-se-luks-gencpio \ - $(am__append_83) +pkglibexec_SCRIPTS = $(am__append_93) noinst_LTLIBRARIES = $(am__append_1) libglnx.la libbsdiff.la \ - libotutil.la libbupsplit.la libostreetest.la + $(am__append_16) libotutil.la libotcore.la libbupsplit.la \ + libostreetest.la privlibdir = $(pkglibdir) privlib_LTLIBRARIES = pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = src/libostree/ostree-1.pc -INTROSPECTION_GIRS = $(am__append_40) +INTROSPECTION_GIRS = $(am__append_44) girdir = $(datadir)/gir-1.0 -gir_DATA = $(am__append_41) +gir_DATA = $(am__append_45) typelibdir = $(libdir)/girepository-1.0 -typelib_DATA = $(am__append_42) +typelib_DATA = $(am__append_46) gsettings_SCHEMAS = ostree_bootdir = $(prefix)/lib/ostree -ostree_boot_SCRIPTS = $(am__append_57) $(am__append_85) +ostree_boot_SCRIPTS = $(am__append_58) $(am__append_95) # We should probably consider flipping the default for DEBUG. Also, # include the builddir in $PATH so we find our just-built ostree @@ -2459,7 +2553,8 @@ AM_TESTS_ENVIRONMENT = G_TEST_SRCDIR="$(abs_srcdir)" \ pwd)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}} PATH=$$(cd \ $(top_builddir)/tests && pwd):$${PATH} \ OSTREE_FEATURES="$(OSTREE_FEATURES)" PYTHONUNBUFFERED=1 \ - $(NULL) $(am__append_65) + GSETTINGS_BACKEND=memory GIO_USE_PROXY_RESOLVER=dummy \ + GIO_USE_VFS=local $(NULL) $(am__append_75) LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/buildutil/tap-driver.sh LOG_COMPILER = $(top_srcdir)/buildutil/tap-test installed_test_LTLIBRARIES = $(am__append_12) @@ -2467,7 +2562,7 @@ installed_test_SCRIPTS = $(am__append_10) installed_test_DATA = $(am__append_11) nobase_installed_test_DATA = noinst_SCRIPTS = $(am__append_3) -noinst_DATA = $(am__append_4) $(am__append_90) +noinst_DATA = $(am__append_4) $(am__append_98) check_LTLIBRARIES = $(am__append_5) check_SCRIPTS = $(am__append_7) check_DATA = $(am__append_8) @@ -2499,9 +2594,9 @@ all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installe # This initializes some more variables # This is a special facility to chain together hooks easily -INSTALL_DATA_HOOKS = install-mkdir-remotes-d-hook $(am__append_81) \ - $(am__append_84) -ALL_LOCAL_RULES = tests/libreaddir-rand.so +INSTALL_DATA_HOOKS = install-mkdir-remotes-d-hook $(am__append_91) \ + $(am__append_94) +ALL_LOCAL_RULES = shortened_sysconfdir = $$(echo "$(sysconfdir)" | sed -e 's|^$(prefix)||' -e 's|^/||') OSTREE_GITREV = $(shell cd $(srcdir) && if command -v git >/dev/null 2>&1 && test -d .git; then git describe --abbrev=42 --tags --always HEAD; fi) ACLOCAL_AMFLAGS = -I buildutil -I libglnx ${ACLOCAL_FLAGS} @@ -2516,11 +2611,13 @@ ACLOCAL_AMFLAGS = -I buildutil -I libglnx ${ACLOCAL_FLAGS} GITIGNOREFILES = aclocal.m4 build-aux/ buildutil/*.m4 config.h.in \ gtk-doc.make ci-build/ fastbuild-*.qcow2 _kola_temp/ target/ \ Cargo.lock docs/.bundle/ docs/Gemfile.lock docs/_site/ \ - docs/reference/ docs/vendor/ $(NULL) $(am__append_62) + docs/reference/ docs/vendor/ $(NULL) $(am__append_72) OT_INTERNAL_GIO_UNIX_CFLAGS = $(OT_DEP_GIO_UNIX_CFLAGS) OT_INTERNAL_GIO_UNIX_LIBS = $(OT_DEP_GIO_UNIX_LIBS) -OT_INTERNAL_SOUP_CFLAGS = $(OT_DEP_SOUP_CFLAGS) -OT_INTERNAL_SOUP_LIBS = $(OT_DEP_SOUP_LIBS) +@USE_LIBSOUP3_FALSE@OT_INTERNAL_SOUP_CFLAGS = $(OT_DEP_SOUP_CFLAGS) +@USE_LIBSOUP3_TRUE@OT_INTERNAL_SOUP_CFLAGS = $(OT_DEP_SOUP3_CFLAGS) +@USE_LIBSOUP3_FALSE@OT_INTERNAL_SOUP_LIBS = $(OT_DEP_SOUP_LIBS) +@USE_LIBSOUP3_TRUE@OT_INTERNAL_SOUP_LIBS = $(OT_DEP_SOUP3_LIBS) # This canonicalizes the PKG_CHECK_MODULES or AM_PATH_GPGME results @USE_GPGME_TRUE@OT_INTERNAL_GPGME_CFLAGS = $(OT_DEP_GPGME_CFLAGS) $(GPGME_PTHREAD_CFLAGS) @@ -2534,6 +2631,8 @@ libglnx_la_SOURCES = \ libglnx/glnx-macros.h \ libglnx/glnx-backport-autocleanups.h \ libglnx/glnx-backport-autoptr.h \ + libglnx/glnx-backport-testutils.h \ + libglnx/glnx-backport-testutils.c \ libglnx/glnx-backports.h \ libglnx/glnx-backports.c \ libglnx/glnx-local-alloc.h \ @@ -2587,6 +2686,31 @@ libbsdiff_la_SOURCES = \ $(NULL) libbsdiff_la_CFLAGS = $(AM_CFLAGS) +COMPOSEFSDIR = $(srcdir)/composefs/libcomposefs +LCFS_DEP_CRYPTO_CFLAGS = $(OT_DEP_CRYPTO_CFLAGS) +LCFS_DEP_CRYPTO_LIBS = $(OT_DEP_CRYPTO_LIBS) +COMPOSEFS_HASH_CFLAGS = -DUSE_OBSTACK=0 -DTESTING=0 -DUSE_DIFF_HASH=0 +libcomposefs_la_SOURCES = \ + composefs/libcomposefs/bitrotate.h \ + composefs/libcomposefs/erofs_fs.h \ + composefs/libcomposefs/erofs_fs_wrapper.h \ + composefs/libcomposefs/hash.c \ + composefs/libcomposefs/hash.h \ + composefs/libcomposefs/lcfs-internal.h \ + composefs/libcomposefs/lcfs-erofs.h \ + composefs/libcomposefs/lcfs-erofs-internal.h \ + composefs/libcomposefs/lcfs-fsverity.c \ + composefs/libcomposefs/lcfs-fsverity.h \ + composefs/libcomposefs/lcfs-writer-erofs.c \ + composefs/libcomposefs/lcfs-writer.c \ + composefs/libcomposefs/lcfs-writer.h \ + composefs/libcomposefs/lcfs-utils.h \ + composefs/libcomposefs/lcfs-mount.c \ + composefs/libcomposefs/lcfs-mount.h \ + composefs/libcomposefs/xalloc-oversized.h + +libcomposefs_la_CFLAGS = $(WARN_CFLAGS) $(COMPOSEFS_HASH_CFLAGS) $(LCFS_DEP_CRYPTO_CFLAGS) $(HIDDEN_VISIBILITY_CFLAGS) +libcomposefs_la_LIBADD = $(LCFS_DEP_CRYPTO_LIBS) libotutil_la_SOURCES = src/libotutil/ot-checksum-utils.c \ src/libotutil/ot-checksum-utils.h \ src/libotutil/ot-checksum-instream.c \ @@ -2601,9 +2725,17 @@ libotutil_la_SOURCES = src/libotutil/ot-checksum-utils.c \ src/libotutil/ot-variant-builder.h \ src/libotutil/ot-gio-utils.c src/libotutil/ot-gio-utils.h \ src/libotutil/otutil.h src/libotutil/ot-tool-util.c \ - src/libotutil/ot-tool-util.h $(NULL) $(am__append_15) -libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(LIBSYSTEMD_CFLAGS) -libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS) + src/libotutil/ot-tool-util.h $(NULL) $(am__append_17) +libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_CRYPTO_LIBS) $(LIBSYSTEMD_CFLAGS) +libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS) $(OT_DEP_CRYPTO_LIBS) +libotcore_la_SOURCES = \ + src/libotcore/otcore.h \ + src/libotcore/otcore-ed25519-verify.c \ + src/libotcore/otcore-prepare-root.c \ + $(NULL) + +libotcore_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_CRYPTO_LIBS) $(LIBSYSTEMD_CFLAGS) +libotcore_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS) $(OT_DEP_CRYPTO_LIBS) libostree_public_headers = \ src/libostree/ostree.h \ src/libostree/ostree-async-progress.h \ @@ -2679,6 +2811,7 @@ libostree_1_la_SOURCES = src/libostree/ostree-async-progress.c \ src/libostree/ostree-repo-os.c src/libostree/ostree-repo.c \ src/libostree/ostree-repo-checkout.c \ src/libostree/ostree-repo-commit.c \ + src/libostree/ostree-repo-composefs.c \ src/libostree/ostree-repo-pull.c \ src/libostree/ostree-repo-pull-private.h \ src/libostree/ostree-repo-pull-verify.c \ @@ -2703,6 +2836,8 @@ libostree_1_la_SOURCES = src/libostree/ostree-async-progress.c \ src/libostree/ostree-deployment.c \ src/libostree/ostree-bootloader.h \ src/libostree/ostree-bootloader.c \ + src/libostree/ostree-bootloader-aboot.h \ + src/libostree/ostree-bootloader-aboot.c \ src/libostree/ostree-bootloader-grub2.h \ src/libostree/ostree-bootloader-grub2.c \ src/libostree/ostree-bootloader-zipl.h \ @@ -2725,14 +2860,16 @@ libostree_1_la_SOURCES = src/libostree/ostree-async-progress.c \ src/libostree/ostree-repo-finder-mount.c \ src/libostree/ostree-repo-finder-override.c \ src/libostree/ostree-kernel-args.h \ - src/libostree/ostree-kernel-args.c $(NULL) $(am__append_16) \ - $(am__append_17) $(am__append_18) $(am__append_19) \ - $(am__append_20) $(am__append_27) $(am__append_28) \ - $(am__append_31) src/libostree/ostree-sign.c \ + src/libostree/ostree-kernel-args-private.h \ + src/libostree/ostree-kernel-args.c $(NULL) $(am__append_18) \ + $(am__append_19) $(am__append_20) $(am__append_21) \ + $(am__append_22) $(am__append_29) $(am__append_30) \ + $(am__append_33) $(am__append_36) src/libostree/ostree-sign.c \ src/libostree/ostree-sign.h src/libostree/ostree-sign-dummy.c \ src/libostree/ostree-sign-dummy.h \ src/libostree/ostree-sign-ed25519.c \ - src/libostree/ostree-sign-ed25519.h $(NULL) + src/libostree/ostree-sign-ed25519.h \ + src/libostree/ostree-sign-private.h $(NULL) symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym # Uncomment this include when adding new development symbols. @@ -2743,24 +2880,27 @@ symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym # http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html wl_versionscript_arg = -Wl,--version-script= libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff \ - -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil \ + -I$(srcdir)/libglnx -I$(srcdir)/composefs \ + -I$(srcdir)/src/libotutil -I$(srcdir)/src/libotcore \ -I$(srcdir)/src/libostree -I$(builddir)/src/libostree \ - $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) \ - $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) \ - $(OT_DEP_CRYPTO_CFLAGS) -fvisibility=hidden \ + -I$(srcdir)/src/switchroot $(OT_INTERNAL_GIO_UNIX_CFLAGS) \ + $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) \ + $(OT_DEP_ZLIB_CFLAGS) $(OT_DEP_CRYPTO_CFLAGS) \ + -fvisibility=hidden \ '-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) \ - extern' -DPKGLIBEXECDIR=\"$(pkglibexecdir)\" $(am__append_21) \ - $(am__append_23) $(am__append_25) $(am__append_29) \ - $(am__append_32) $(am__append_34) $(am__append_36) \ - $(am__append_38) + extern' -DPKGLIBEXECDIR=\"$(pkglibexecdir)\" $(am__append_23) \ + $(am__append_25) $(am__append_27) $(am__append_31) \ + $(am__append_34) $(am__append_37) $(am__append_39) \ + $(am__append_41) libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions $(addprefix $(wl_versionscript_arg),$(symbol_files)) # Some change between rust-1.21.0-1.fc27 and rust-1.22.1-1.fc27.x86_64 -libostree_1_la_LIBADD = libotutil.la libglnx.la libbsdiff.la \ - $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) \ - $(OT_DEP_LZMA_LIBS) $(OT_DEP_ZLIB_LIBS) $(OT_DEP_CRYPTO_LIBS) \ - $(bupsplitpath) $(am__append_22) $(am__append_24) \ - $(am__append_26) $(am__append_30) $(am__append_33) \ - $(am__append_35) $(am__append_37) $(am__append_39) +libostree_1_la_LIBADD = libotutil.la libotcore.la libglnx.la \ + libbsdiff.la $(OT_INTERNAL_GIO_UNIX_LIBS) \ + $(OT_INTERNAL_GPGME_LIBS) $(OT_DEP_LZMA_LIBS) \ + $(OT_DEP_ZLIB_LIBS) $(OT_DEP_CRYPTO_LIBS) $(bupsplitpath) \ + $(am__append_24) $(am__append_26) $(am__append_28) \ + $(am__append_32) $(am__append_35) $(am__append_38) \ + $(am__append_40) $(am__append_42) $(am__append_43) EXTRA_libostree_1_la_DEPENDENCIES = $(symbol_files) # XXX: work around clang being passed -fstack-clash-protection which it doesn't understand @@ -2768,10 +2908,11 @@ EXTRA_libostree_1_la_DEPENDENCIES = $(symbol_files) INTROSPECTION_SCANNER_ENV = CC=gcc @BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_EXPORT_PACKAGES = ostree-1 @BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_INCLUDES = Gio-2.0 +@BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_C_INCLUDES = ostree.h @BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_CFLAGS = $(libostree_1_la_CFLAGS) @BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_LIBS = libostree-1.la @BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=Ostree --symbol-prefix=ostree $(GI_SCANNERFLAGS) -@BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_FILES = $(libostreeinclude_HEADERS) $(filter-out %-private.h %/ostree-soup-uri.h,$(libostree_1_la_SOURCES)) +@BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_FILES = $(libostreeinclude_HEADERS) $(filter-out %.h,$(libostree_1_la_SOURCES)) gpgreadme_DATA = src/libostree/README-gpg gpgreadmedir = $(datadir)/ostree/trusted.gpg.d @@ -2797,14 +2938,16 @@ ostree_SOURCES = src/ostree/main.c src/ostree/ot-builtin-admin.c \ src/ostree/ot-builtin-static-delta.c src/ostree/ot-main.h \ src/ostree/ot-main.c src/ostree/ot-dump.h src/ostree/ot-dump.c \ src/ostree/ot-editor.c src/ostree/ot-editor.h \ - src/ostree/parse-datetime.h $(NULL) $(am__append_44) \ + src/ostree/parse-datetime.h $(NULL) $(am__append_48) \ src/ostree/ot-admin-builtin-init-fs.c \ src/ostree/ot-admin-builtin-diff.c \ src/ostree/ot-admin-builtin-deploy.c \ src/ostree/ot-admin-builtin-finalize-staged.c \ src/ostree/ot-admin-builtin-boot-complete.c \ src/ostree/ot-admin-builtin-undeploy.c \ + src/ostree/ot-admin-builtin-set-default.c \ src/ostree/ot-admin-builtin-instutil.c \ + src/ostree/ot-admin-builtin-kargs.c \ src/ostree/ot-admin-builtin-cleanup.c \ src/ostree/ot-admin-builtin-os-init.c \ src/ostree/ot-admin-builtin-set-origin.c \ @@ -2819,7 +2962,9 @@ ostree_SOURCES = src/ostree/main.c src/ostree/ot-builtin-admin.c \ src/ostree/ot-admin-instutil-builtin-grub2-generate.c \ src/ostree/ot-admin-instutil-builtins.h \ src/ostree/ot-admin-functions.h \ - src/ostree/ot-admin-functions.c $(NULL) \ + src/ostree/ot-admin-functions.c \ + src/ostree/ot-admin-kargs-builtins.h \ + src/ostree/ot-admin-kargs-builtin-edit-in-place.c $(NULL) \ src/ostree/ot-remote-builtins.h \ src/ostree/ot-remote-builtin-add.c \ src/ostree/ot-remote-builtin-delete.c \ @@ -2827,7 +2972,7 @@ ostree_SOURCES = src/ostree/main.c src/ostree/ot-builtin-admin.c \ src/ostree/ot-remote-builtin-show-url.c \ src/ostree/ot-remote-builtin-refs.c \ src/ostree/ot-remote-builtin-summary.c $(NULL) \ - $(am__append_45) $(am__append_46) $(am__append_47) + $(am__append_49) $(am__append_50) nodist_ostree_SOURCES = \ src/ostree/parse-datetime.c \ $(NULL) @@ -2839,22 +2984,17 @@ ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/sr ostree_bin_shared_ldadd = $(AM_LDFLAGS) libglnx.la libotutil.la libostree-1.la \ $(OT_INTERNAL_GIO_UNIX_LIBS) -ostree_CFLAGS = $(ostree_bin_shared_cflags) $(am__append_49) \ - $(am__append_51) $(am__append_53) +ostree_CFLAGS = $(ostree_bin_shared_cflags) $(am__append_51) \ + $(am__append_53) ostree_LDADD = $(ostree_bin_shared_ldadd) libbsdiff.la \ - $(LIBSYSTEMD_LIBS) $(am__append_50) $(am__append_52) \ - $(am__append_54) -@USE_LIBSOUP_TRUE@ostree_trivial_httpd_SOURCES = src/ostree/ostree-trivial-httpd.c -@USE_LIBSOUP_TRUE@ostree_trivial_httpd_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_SOUP_CFLAGS) -@USE_LIBSOUP_TRUE@ostree_trivial_httpd_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_SOUP_LIBS) -ostree_prepare_root_SOURCES = \ - src/switchroot/ostree-mount-util.h \ - src/switchroot/ostree-prepare-root.c \ - $(NULL) - -ostree_prepare_root_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_59) \ - $(am__append_60) -@BUILDOPT_USE_STATIC_COMPILER_FALSE@ostree_prepare_root_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot + $(LIBSYSTEMD_LIBS) $(am__append_52) $(am__append_54) +ostree_prepare_root_SOURCES = src/switchroot/ostree-mount-util.h \ + $(am__append_57) $(am__append_62) +ostree_prepare_root_CFLAGS = $(am__append_61) +ostree_prepare_root_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_63) \ + $(am__append_68) $(am__append_70) +ostree_prepare_root_LDADD = $(am__append_64) $(am__append_67) \ + $(am__append_69) ostree_remount_SOURCES = \ src/switchroot/ostree-mount-util.h \ src/switchroot/ostree-remount.c \ @@ -2862,9 +3002,10 @@ ostree_remount_SOURCES = \ ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) \ $(OT_INTERNAL_GIO_UNIX_CFLAGS) -Isrc/switchroot \ - -I$(srcdir)/libglnx $(am__append_61) -ostree_remount_LDADD = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) libglnx.la -@BUILDOPT_SYSTEMD_TRUE@ostree_prepare_root_LDADD = $(AM_LDFLAGS) $(LIBSYSTEMD_LIBS) + -I$(srcdir)/src/libotcore -I$(srcdir)/src/libotutil \ + -I$(srcdir)/libglnx $(am__append_65) $(am__append_71) +ostree_remount_LDADD = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) \ + libotcore.la libotutil.la libglnx.la $(am__append_66) @BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_SOURCES = src/switchroot/ostree-mount-util.h \ @BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ src/switchroot/ostree-system-generator.c @@ -2879,7 +3020,7 @@ ostree_remount_LDADD = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) libglnx.la @BUILDOPT_FUSE_TRUE@rofiles_fuse_LDADD = libglnx.la $(BUILDOPT_FUSE_LIBS) $(OT_INTERNAL_GIO_UNIX_LIBS) libostree-1.la uninstalled_test_data = tests/ostree-symlink-stamp \ tests/ostree-prepare-root-symlink-stamp \ - tests/ostree-remount-symlink-stamp $(am__append_68) + tests/ostree-remount-symlink-stamp $(am__append_78) dist_uninstalled_test_scripts = tests/test-symbols.sh tests/coccinelle.sh # This logic implements ENABLE_INSTALLED_TESTS_EXCLUSIVE; see below. @@ -2887,16 +3028,17 @@ dist_uninstalled_test_scripts = tests/test-symbols.sh tests/coccinelle.sh # tests *only* run installed, to avoid having to run them twice in CI. # This overrides the glib-tap.mk emphasis on doing both, if we'd # used e.g. `dist_test_scripts`. -dist_test_scripts = $(NULL) $(am__append_79) +dist_test_scripts = $(NULL) $(am__append_89) test_programs = tests/test-bloom tests/test-repo-finder-config \ - tests/test-repo-finder-mount $(NULL) $(am__append_76) \ - $(am__append_80) + tests/test-repo-finder-mount $(NULL) $(am__append_86) \ + $(am__append_90) _installed_or_uninstalled_test_scripts = tests/test-basic.sh \ tests/test-basic-bare-split-xattrs.sh tests/test-basic-user.sh \ tests/test-basic-user-only.sh tests/test-basic-root.sh \ tests/test-cli-extensions.sh tests/test-pull-subpath.sh \ tests/test-archivez.sh tests/test-remote-add.sh \ - tests/test-remote-headers.sh tests/test-commit-sign.sh \ + tests/test-remote-headers.sh tests/test-remote-refs.sh \ + tests/test-composefs.sh tests/test-commit-sign.sh \ tests/test-commit-timestamp.sh tests/test-export.sh \ tests/test-help.sh tests/test-libarchive.sh \ tests/test-parent.sh tests/test-pull-bare.sh \ @@ -2915,6 +3057,7 @@ _installed_or_uninstalled_test_scripts = tests/test-basic.sh \ tests/test-admin-upgrade-endoflife.sh \ tests/test-admin-upgrade-systemd-update.sh \ tests/test-admin-deploy-syslinux.sh \ + tests/test-admin-deploy-bootprefix.sh \ tests/test-admin-deploy-2.sh tests/test-admin-deploy-karg.sh \ tests/test-admin-deploy-switch.sh \ tests/test-admin-deploy-etcmerge-cornercases.sh \ @@ -2923,37 +3066,36 @@ _installed_or_uninstalled_test_scripts = tests/test-basic.sh \ tests/test-admin-deploy-nomerge.sh \ tests/test-admin-deploy-none.sh \ tests/test-admin-deploy-bootid-gc.sh \ - tests/test-osupdate-dtb.sh \ + tests/test-admin-deploy-whiteouts.sh \ + tests/test-admin-deploy-emptyetc.sh tests/test-osupdate-dtb.sh \ tests/test-admin-instutil-set-kargs.sh \ tests/test-admin-upgrade-not-backwards.sh \ tests/test-admin-pull-deploy-commit.sh \ tests/test-admin-pull-deploy-split.sh \ tests/test-admin-locking.sh tests/test-admin-deploy-clean.sh \ - tests/test-reset-nonlinear.sh tests/test-oldstyle-partial.sh \ - tests/test-delta.sh tests/test-delta-sign.sh \ - tests/test-delta-ed25519.sh tests/test-xattrs.sh \ - tests/test-auto-summary.sh tests/test-prune.sh \ - tests/test-concurrency.py tests/test-refs.sh \ - tests/test-demo-buildsystem.sh tests/test-switchroot.sh \ - tests/test-pull-contenturl.sh tests/test-pull-mirrorlist.sh \ - tests/test-summary-update.sh tests/test-summary-view.sh \ - tests/test-no-initramfs.sh tests/test-create-usb.sh \ - tests/test-find-remotes.sh tests/test-fsck-collections.sh \ - tests/test-fsck-delete.sh tests/test-init-collections.sh \ - tests/test-prune-collections.sh tests/test-refs-collections.sh \ + tests/test-admin-kargs.sh tests/test-reset-nonlinear.sh \ + tests/test-oldstyle-partial.sh tests/test-delta.sh \ + tests/test-delta-sign.sh tests/test-delta-ed25519.sh \ + tests/test-xattrs.sh tests/test-auto-summary.sh \ + tests/test-prune.sh tests/test-concurrency.py \ + tests/test-refs.sh tests/test-demo-buildsystem.sh \ + tests/test-switchroot.sh tests/test-pull-contenturl.sh \ + tests/test-pull-mirrorlist.sh tests/test-summary-update.sh \ + tests/test-summary-view.sh tests/test-no-initramfs.sh \ + tests/test-create-usb.sh tests/test-find-remotes.sh \ + tests/test-fsck-collections.sh tests/test-fsck-delete.sh \ + tests/test-init-collections.sh tests/test-prune-collections.sh \ + tests/test-refs-collections.sh \ tests/test-remote-add-collections.sh \ tests/test-repo-finder-mount-integration.sh \ tests/test-summary-collections.sh \ tests/test-pull-collections.sh tests/test-config.sh \ tests/test-signed-commit.sh tests/test-signed-pull.sh \ tests/test-pre-signed-pull.sh \ - tests/test-signed-pull-summary.sh $(NULL) $(am__append_66) \ - $(am__append_67) $(am__append_70) $(am__append_71) -test_extra_programs = \ - tests/get-byte-order \ - tests/repo-finder-mount \ - $(NULL) - + tests/test-signed-pull-summary.sh $(NULL) $(am__append_76) \ + $(am__append_77) $(am__append_80) $(am__append_81) +test_extra_programs = tests/get-byte-order tests/repo-finder-mount \ + $(NULL) $(am__append_85) tests_get_byte_order_SOURCES = tests/get-byte-order.c tests_get_byte_order_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) tests_get_byte_order_LDADD = $(GLIB_LIBS) @@ -3016,24 +3158,17 @@ js_installed_tests = \ tests/test-sysroot.js \ $(NULL) -test_ltlibraries = libreaddir-rand.la -libreaddir_rand_la_SOURCES = tests/readdir-rand.c -libreaddir_rand_la_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -libreaddir_rand_la_LIBADD = \ - -ldl \ - $(OT_INTERNAL_GIO_UNIX_LIBS) \ - $(NULL) - -libreaddir_rand_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version \ - $(am__append_74) _installed_or_uninstalled_test_programs = tests/test-varint \ - tests/test-ot-unix-utils tests/test-bsdiff \ + tests/test-ot-unix-utils tests/test-bsdiff tests/test-otcore \ tests/test-mutable-tree tests/test-keyfile-utils \ tests/test-ot-opt-utils tests/test-ot-tool-util \ tests/test-checksum tests/test-lzma tests/test-rollsum \ tests/test-basic-c tests/test-sysroot-c tests/test-pull-c \ tests/test-repo tests/test-include-ostree-h tests/test-kargs \ - tests/test-rfc2616-dates $(am__append_75) $(am__append_77) + tests/test-rfc2616-dates $(am__append_84) $(am__append_87) +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@ostree_trivial_httpd_SOURCES = src/ostree/ostree-trivial-httpd.c +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@ostree_trivial_httpd_CFLAGS = $(common_tests_cflags) $(OT_INTERNAL_SOUP_CFLAGS) +@USE_LIBSOUP_OR_LIBSOUP3_TRUE@ostree_trivial_httpd_LDADD = $(common_tests_ldadd) $(OT_INTERNAL_SOUP_LIBS) common_tests_cflags = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx common_tests_ldadd = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) libostreetest_la_SOURCES = tests/libostreetest.c tests/test-mock-gio.c tests/test-mock-gio.h @@ -3085,6 +3220,8 @@ tests_test_varint_CFLAGS = $(TESTS_CFLAGS) tests_test_varint_LDADD = $(TESTS_LDADD) tests_test_bsdiff_CFLAGS = $(TESTS_CFLAGS) tests_test_bsdiff_LDADD = libbsdiff.la $(TESTS_LDADD) +tests_test_otcore_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libotcore -I$(srcdir)/libglnx +tests_test_otcore_LDADD = $(OT_INTERNAL_GIO_UNIX_LIBS) libotcore.la libglnx.la libotutil.la tests_test_checksum_SOURCES = \ src/libostree/ostree-core.c \ src/libostree/ostree-varint.c \ @@ -3139,6 +3276,7 @@ tests_test_commit_sign_sh_ext_LDADD = $(TESTS_LDADD) @BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-boot-complete.service \ @BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-finalize-staged.service \ @BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-finalize-staged.path \ +@BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-finalize-staged-hold.service \ @BUILDOPT_SYSTEMD_TRUE@ $(NULL) @BUILDOPT_SYSTEMD_TRUE@systemdtmpfilesdir = $(prefix)/lib/tmpfiles.d @@ -3151,12 +3289,13 @@ tests_test_commit_sign_sh_ext_LDADD = $(TESTS_LDADD) @ENABLE_MAN_TRUE@ ostree-admin-config-diff.1 \ @ENABLE_MAN_TRUE@ ostree-admin-deploy.1 ostree-admin-init-fs.1 \ @ENABLE_MAN_TRUE@ ostree-admin-instutil.1 \ +@ENABLE_MAN_TRUE@ ostree-admin-stateroot-init.1 \ @ENABLE_MAN_TRUE@ ostree-admin-os-init.1 ostree-admin-status.1 \ @ENABLE_MAN_TRUE@ ostree-admin-set-origin.1 \ @ENABLE_MAN_TRUE@ ostree-admin-switch.1 ostree-admin-undeploy.1 \ @ENABLE_MAN_TRUE@ ostree-admin-upgrade.1 ostree-admin-unlock.1 \ -@ENABLE_MAN_TRUE@ ostree-admin-pin.1 ostree-admin.1 \ -@ENABLE_MAN_TRUE@ ostree-cat.1 ostree-checkout.1 \ +@ENABLE_MAN_TRUE@ ostree-admin-pin.1 ostree-admin-set-default.1 \ +@ENABLE_MAN_TRUE@ ostree-admin.1 ostree-cat.1 ostree-checkout.1 \ @ENABLE_MAN_TRUE@ ostree-checksum.1 ostree-commit.1 \ @ENABLE_MAN_TRUE@ ostree-create-usb.1 ostree-export.1 \ @ENABLE_MAN_TRUE@ ostree-config.1 ostree-diff.1 \ @@ -3166,8 +3305,8 @@ tests_test_commit_sign_sh_ext_LDADD = $(TESTS_LDADD) @ENABLE_MAN_TRUE@ ostree-pull.1 ostree-refs.1 ostree-remote.1 \ @ENABLE_MAN_TRUE@ ostree-reset.1 ostree-rev-parse.1 \ @ENABLE_MAN_TRUE@ ostree-show.1 ostree-sign.1 ostree-summary.1 \ -@ENABLE_MAN_TRUE@ ostree-static-delta.1 $(am__append_86) \ -@ENABLE_MAN_TRUE@ $(am__append_88) $(am__append_89) +@ENABLE_MAN_TRUE@ ostree-static-delta.1 ostree-prepare-root.1 \ +@ENABLE_MAN_TRUE@ $(am__append_96) $(am__append_97) @ENABLE_MAN_TRUE@man5_files = ostree.repo.5 ostree.repo-config.5 @ENABLE_MAN_TRUE@man1_MANS = $(addprefix man/,$(man1_files)) @ENABLE_MAN_TRUE@man5_MANS = $(addprefix man/,$(man5_files)) @@ -3199,7 +3338,7 @@ all: $(BUILT_SOURCES) config.h .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs am--refresh: Makefile @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(srcdir)/Makefile-bash.am $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/composefs/libcomposefs/Makefile-lib.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-otcore.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(srcdir)/Makefile-bash.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -3221,7 +3360,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; -$(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(srcdir)/Makefile-bash.am $(am__empty): +$(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/composefs/libcomposefs/Makefile-lib.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-otcore.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(srcdir)/Makefile-bash.am $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck @@ -3762,12 +3901,38 @@ src/libostree/bupsplit.lo: src/libostree/$(am__dirstamp) \ libbupsplit.la: $(libbupsplit_la_OBJECTS) $(libbupsplit_la_DEPENDENCIES) $(EXTRA_libbupsplit_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libbupsplit_la_OBJECTS) $(libbupsplit_la_LIBADD) $(LIBS) +composefs/libcomposefs/$(am__dirstamp): + @$(MKDIR_P) composefs/libcomposefs + @: > composefs/libcomposefs/$(am__dirstamp) +composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) composefs/libcomposefs/$(DEPDIR) + @: > composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp) +composefs/libcomposefs/libcomposefs_la-hash.lo: \ + composefs/libcomposefs/$(am__dirstamp) \ + composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp) +composefs/libcomposefs/libcomposefs_la-lcfs-fsverity.lo: \ + composefs/libcomposefs/$(am__dirstamp) \ + composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp) +composefs/libcomposefs/libcomposefs_la-lcfs-writer-erofs.lo: \ + composefs/libcomposefs/$(am__dirstamp) \ + composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp) +composefs/libcomposefs/libcomposefs_la-lcfs-writer.lo: \ + composefs/libcomposefs/$(am__dirstamp) \ + composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp) +composefs/libcomposefs/libcomposefs_la-lcfs-mount.lo: \ + composefs/libcomposefs/$(am__dirstamp) \ + composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp) + +libcomposefs.la: $(libcomposefs_la_OBJECTS) $(libcomposefs_la_DEPENDENCIES) $(EXTRA_libcomposefs_la_DEPENDENCIES) + $(AM_V_CCLD)$(libcomposefs_la_LINK) $(am_libcomposefs_la_rpath) $(libcomposefs_la_OBJECTS) $(libcomposefs_la_LIBADD) $(LIBS) libglnx/$(am__dirstamp): @$(MKDIR_P) libglnx @: > libglnx/$(am__dirstamp) libglnx/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) libglnx/$(DEPDIR) @: > libglnx/$(DEPDIR)/$(am__dirstamp) +libglnx/la-glnx-backport-testutils.lo: libglnx/$(am__dirstamp) \ + libglnx/$(DEPDIR)/$(am__dirstamp) libglnx/la-glnx-backports.lo: libglnx/$(am__dirstamp) \ libglnx/$(DEPDIR)/$(am__dirstamp) libglnx/la-glnx-local-alloc.lo: libglnx/$(am__dirstamp) \ @@ -3855,6 +4020,9 @@ src/libostree/libostree_1_la-ostree-repo-checkout.lo: \ src/libostree/libostree_1_la-ostree-repo-commit.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) +src/libostree/libostree_1_la-ostree-repo-composefs.lo: \ + src/libostree/$(am__dirstamp) \ + src/libostree/$(DEPDIR)/$(am__dirstamp) src/libostree/libostree_1_la-ostree-repo-pull.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) @@ -3909,6 +4077,9 @@ src/libostree/libostree_1_la-ostree-deployment.lo: \ src/libostree/libostree_1_la-ostree-bootloader.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) +src/libostree/libostree_1_la-ostree-bootloader-aboot.lo: \ + src/libostree/$(am__dirstamp) \ + src/libostree/$(DEPDIR)/$(am__dirstamp) src/libostree/libostree_1_la-ostree-bootloader-grub2.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) @@ -3984,6 +4155,9 @@ src/libostree/libostree_1_la-ostree-metalink.lo: \ src/libostree/libostree_1_la-ostree-fetcher-curl.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) +src/libostree/libostree_1_la-ostree-fetcher-soup3.lo: \ + src/libostree/$(am__dirstamp) \ + src/libostree/$(DEPDIR)/$(am__dirstamp) src/libostree/libostree_1_la-ostree-fetcher-soup.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) @@ -4015,6 +4189,21 @@ tests/libostreetest_la-test-mock-gio.lo: tests/$(am__dirstamp) \ libostreetest.la: $(libostreetest_la_OBJECTS) $(libostreetest_la_DEPENDENCIES) $(EXTRA_libostreetest_la_DEPENDENCIES) $(AM_V_CCLD)$(libostreetest_la_LINK) $(libostreetest_la_OBJECTS) $(libostreetest_la_LIBADD) $(LIBS) +src/libotcore/$(am__dirstamp): + @$(MKDIR_P) src/libotcore + @: > src/libotcore/$(am__dirstamp) +src/libotcore/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libotcore/$(DEPDIR) + @: > src/libotcore/$(DEPDIR)/$(am__dirstamp) +src/libotcore/libotcore_la-otcore-ed25519-verify.lo: \ + src/libotcore/$(am__dirstamp) \ + src/libotcore/$(DEPDIR)/$(am__dirstamp) +src/libotcore/libotcore_la-otcore-prepare-root.lo: \ + src/libotcore/$(am__dirstamp) \ + src/libotcore/$(DEPDIR)/$(am__dirstamp) + +libotcore.la: $(libotcore_la_OBJECTS) $(libotcore_la_DEPENDENCIES) $(EXTRA_libotcore_la_DEPENDENCIES) + $(AM_V_CCLD)$(libotcore_la_LINK) $(libotcore_la_OBJECTS) $(libotcore_la_LIBADD) $(LIBS) src/libotutil/$(am__dirstamp): @$(MKDIR_P) src/libotutil @: > src/libotutil/$(am__dirstamp) @@ -4059,11 +4248,6 @@ src/libotutil/libotutil_la-zbase32.lo: src/libotutil/$(am__dirstamp) \ libotutil.la: $(libotutil_la_OBJECTS) $(libotutil_la_DEPENDENCIES) $(EXTRA_libotutil_la_DEPENDENCIES) $(AM_V_CCLD)$(libotutil_la_LINK) $(libotutil_la_OBJECTS) $(libotutil_la_LIBADD) $(LIBS) -tests/libreaddir_rand_la-readdir-rand.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) - -libreaddir-rand.la: $(libreaddir_rand_la_OBJECTS) $(libreaddir_rand_la_DEPENDENCIES) $(EXTRA_libreaddir_rand_la_DEPENDENCIES) - $(AM_V_CCLD)$(libreaddir_rand_la_LINK) $(am_libreaddir_rand_la_rpath) $(libreaddir_rand_la_OBJECTS) $(libreaddir_rand_la_LIBADD) $(LIBS) src/ostree/$(am__dirstamp): @$(MKDIR_P) src/ostree @: > src/ostree/$(am__dirstamp) @@ -4170,9 +4354,15 @@ src/ostree/ostree-ot-admin-builtin-boot-complete.$(OBJEXT): \ src/ostree/ostree-ot-admin-builtin-undeploy.$(OBJEXT): \ src/ostree/$(am__dirstamp) \ src/ostree/$(DEPDIR)/$(am__dirstamp) +src/ostree/ostree-ot-admin-builtin-set-default.$(OBJEXT): \ + src/ostree/$(am__dirstamp) \ + src/ostree/$(DEPDIR)/$(am__dirstamp) src/ostree/ostree-ot-admin-builtin-instutil.$(OBJEXT): \ src/ostree/$(am__dirstamp) \ src/ostree/$(DEPDIR)/$(am__dirstamp) +src/ostree/ostree-ot-admin-builtin-kargs.$(OBJEXT): \ + src/ostree/$(am__dirstamp) \ + src/ostree/$(DEPDIR)/$(am__dirstamp) src/ostree/ostree-ot-admin-builtin-cleanup.$(OBJEXT): \ src/ostree/$(am__dirstamp) \ src/ostree/$(DEPDIR)/$(am__dirstamp) @@ -4209,6 +4399,9 @@ src/ostree/ostree-ot-admin-instutil-builtin-grub2-generate.$(OBJEXT): \ src/ostree/ostree-ot-admin-functions.$(OBJEXT): \ src/ostree/$(am__dirstamp) \ src/ostree/$(DEPDIR)/$(am__dirstamp) +src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.$(OBJEXT): \ + src/ostree/$(am__dirstamp) \ + src/ostree/$(DEPDIR)/$(am__dirstamp) src/ostree/ostree-ot-remote-builtin-add.$(OBJEXT): \ src/ostree/$(am__dirstamp) \ src/ostree/$(DEPDIR)/$(am__dirstamp) @@ -4248,9 +4441,6 @@ src/ostree/ostree-ot-remote-cookie-util.$(OBJEXT): \ src/ostree/ostree-ot-builtin-pull.$(OBJEXT): \ src/ostree/$(am__dirstamp) \ src/ostree/$(DEPDIR)/$(am__dirstamp) -src/ostree/ostree-ot-builtin-trivial-httpd.$(OBJEXT): \ - src/ostree/$(am__dirstamp) \ - src/ostree/$(DEPDIR)/$(am__dirstamp) src/ostree/ostree-parse-datetime.$(OBJEXT): \ src/ostree/$(am__dirstamp) \ src/ostree/$(DEPDIR)/$(am__dirstamp) @@ -4264,6 +4454,9 @@ src/switchroot/$(am__dirstamp): src/switchroot/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/switchroot/$(DEPDIR) @: > src/switchroot/$(DEPDIR)/$(am__dirstamp) +src/switchroot/ostree_prepare_root-ostree-prepare-root-static.$(OBJEXT): \ + src/switchroot/$(am__dirstamp) \ + src/switchroot/$(DEPDIR)/$(am__dirstamp) src/switchroot/ostree_prepare_root-ostree-prepare-root.$(OBJEXT): \ src/switchroot/$(am__dirstamp) \ src/switchroot/$(DEPDIR)/$(am__dirstamp) @@ -4484,6 +4677,12 @@ tests/test_ot_unix_utils-test-ot-unix-utils.$(OBJEXT): \ tests/test-ot-unix-utils$(EXEEXT): $(tests_test_ot_unix_utils_OBJECTS) $(tests_test_ot_unix_utils_DEPENDENCIES) $(EXTRA_tests_test_ot_unix_utils_DEPENDENCIES) tests/$(am__dirstamp) @rm -f tests/test-ot-unix-utils$(EXEEXT) $(AM_V_CCLD)$(tests_test_ot_unix_utils_LINK) $(tests_test_ot_unix_utils_OBJECTS) $(tests_test_ot_unix_utils_LDADD) $(LIBS) +tests/test_otcore-test-otcore.$(OBJEXT): tests/$(am__dirstamp) \ + tests/$(DEPDIR)/$(am__dirstamp) + +tests/test-otcore$(EXEEXT): $(tests_test_otcore_OBJECTS) $(tests_test_otcore_DEPENDENCIES) $(EXTRA_tests_test_otcore_DEPENDENCIES) tests/$(am__dirstamp) + @rm -f tests/test-otcore$(EXEEXT) + $(AM_V_CCLD)$(tests_test_otcore_LINK) $(tests_test_otcore_OBJECTS) $(tests_test_otcore_LDADD) $(LIBS) tests/test_pull_c-test-pull-c.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) @@ -4774,11 +4973,15 @@ mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f bsdiff/*.$(OBJEXT) -rm -f bsdiff/*.lo + -rm -f composefs/libcomposefs/*.$(OBJEXT) + -rm -f composefs/libcomposefs/*.lo -rm -f libglnx/*.$(OBJEXT) -rm -f libglnx/*.lo -rm -f libglnx/tests/*.$(OBJEXT) -rm -f src/libostree/*.$(OBJEXT) -rm -f src/libostree/*.lo + -rm -f src/libotcore/*.$(OBJEXT) + -rm -f src/libotcore/*.lo -rm -f src/libotutil/*.$(OBJEXT) -rm -f src/libotutil/*.lo -rm -f src/ostree/*.$(OBJEXT) @@ -4792,6 +4995,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@bsdiff/$(DEPDIR)/libbsdiff_la-bspatch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-hash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-fsverity.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-mount.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer-erofs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libglnx/$(DEPDIR)/la-glnx-backport-testutils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@libglnx/$(DEPDIR)/la-glnx-backports.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@libglnx/$(DEPDIR)/la-glnx-console.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@libglnx/$(DEPDIR)/la-glnx-dirfd.Plo@am__quote@ # am--include-marker @@ -4815,6 +5024,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-async-progress.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-bloom.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootconfig-parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-aboot.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-grub2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-syslinux.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-uboot.Plo@am__quote@ # am--include-marker @@ -4832,6 +5042,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-enumtypes.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-curl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup3.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-uri.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verifier.Plo@am__quote@ # am--include-marker @@ -4850,6 +5061,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-checkout.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-commit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-composefs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file-enumerator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-finder-avahi-parser.Plo@am__quote@ # am--include-marker @@ -4894,6 +5106,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_rollsum-ostree-rollsum.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_rollsum_cli-ostree-rollsum.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_varint-ostree-varint.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libotcore/$(DEPDIR)/libotcore_la-otcore-ed25519-verify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libotcore/$(DEPDIR)/libotcore_la-otcore-prepare-root.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-instream.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-fs-utils.Plo@am__quote@ # am--include-marker @@ -4914,8 +5128,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-finalize-staged.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-init-fs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-instutil.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-os-init.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-pin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-origin.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-status.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-switch.Po@am__quote@ # am--include-marker @@ -4926,6 +5142,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-grub2-generate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-selinux-ensure-labeled.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-set-kargs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-builtin-admin.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-builtin-cat.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-builtin-checkout.Po@am__quote@ # am--include-marker @@ -4952,7 +5169,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-builtin-sign.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-builtin-static-delta.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-builtin-summary.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-dump.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-editor.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-main.Po@am__quote@ # am--include-marker @@ -4971,13 +5187,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-parse-datetime.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/get_byte_order-get-byte-order.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/libostreetest_la-libostreetest.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/libostreetest_la-test-mock-gio.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/repo_finder_mount-repo-finder-mount.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_basic_c-test-basic-c.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_bloom-test-bloom.Po@am__quote@ # am--include-marker @@ -4994,6 +5210,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_ot_opt_utils-test-ot-opt-utils.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_ot_tool_util-test-ot-tool-util.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_ot_unix_utils-test-ot-unix-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_otcore-test-otcore.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_pull_c-test-pull-c.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_repo-test-repo.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_repo_finder_avahi-test-repo-finder-avahi.Po@am__quote@ # am--include-marker @@ -5049,6 +5266,48 @@ bsdiff/libbsdiff_la-bspatch.lo: bsdiff/bspatch.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbsdiff_la_CFLAGS) $(CFLAGS) -c -o bsdiff/libbsdiff_la-bspatch.lo `test -f 'bsdiff/bspatch.c' || echo '$(srcdir)/'`bsdiff/bspatch.c +composefs/libcomposefs/libcomposefs_la-hash.lo: composefs/libcomposefs/hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -MT composefs/libcomposefs/libcomposefs_la-hash.lo -MD -MP -MF composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-hash.Tpo -c -o composefs/libcomposefs/libcomposefs_la-hash.lo `test -f 'composefs/libcomposefs/hash.c' || echo '$(srcdir)/'`composefs/libcomposefs/hash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-hash.Tpo composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-hash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composefs/libcomposefs/hash.c' object='composefs/libcomposefs/libcomposefs_la-hash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -c -o composefs/libcomposefs/libcomposefs_la-hash.lo `test -f 'composefs/libcomposefs/hash.c' || echo '$(srcdir)/'`composefs/libcomposefs/hash.c + +composefs/libcomposefs/libcomposefs_la-lcfs-fsverity.lo: composefs/libcomposefs/lcfs-fsverity.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -MT composefs/libcomposefs/libcomposefs_la-lcfs-fsverity.lo -MD -MP -MF composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-fsverity.Tpo -c -o composefs/libcomposefs/libcomposefs_la-lcfs-fsverity.lo `test -f 'composefs/libcomposefs/lcfs-fsverity.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-fsverity.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-fsverity.Tpo composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-fsverity.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composefs/libcomposefs/lcfs-fsverity.c' object='composefs/libcomposefs/libcomposefs_la-lcfs-fsverity.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -c -o composefs/libcomposefs/libcomposefs_la-lcfs-fsverity.lo `test -f 'composefs/libcomposefs/lcfs-fsverity.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-fsverity.c + +composefs/libcomposefs/libcomposefs_la-lcfs-writer-erofs.lo: composefs/libcomposefs/lcfs-writer-erofs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -MT composefs/libcomposefs/libcomposefs_la-lcfs-writer-erofs.lo -MD -MP -MF composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer-erofs.Tpo -c -o composefs/libcomposefs/libcomposefs_la-lcfs-writer-erofs.lo `test -f 'composefs/libcomposefs/lcfs-writer-erofs.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-writer-erofs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer-erofs.Tpo composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer-erofs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composefs/libcomposefs/lcfs-writer-erofs.c' object='composefs/libcomposefs/libcomposefs_la-lcfs-writer-erofs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -c -o composefs/libcomposefs/libcomposefs_la-lcfs-writer-erofs.lo `test -f 'composefs/libcomposefs/lcfs-writer-erofs.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-writer-erofs.c + +composefs/libcomposefs/libcomposefs_la-lcfs-writer.lo: composefs/libcomposefs/lcfs-writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -MT composefs/libcomposefs/libcomposefs_la-lcfs-writer.lo -MD -MP -MF composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer.Tpo -c -o composefs/libcomposefs/libcomposefs_la-lcfs-writer.lo `test -f 'composefs/libcomposefs/lcfs-writer.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer.Tpo composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composefs/libcomposefs/lcfs-writer.c' object='composefs/libcomposefs/libcomposefs_la-lcfs-writer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -c -o composefs/libcomposefs/libcomposefs_la-lcfs-writer.lo `test -f 'composefs/libcomposefs/lcfs-writer.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-writer.c + +composefs/libcomposefs/libcomposefs_la-lcfs-mount.lo: composefs/libcomposefs/lcfs-mount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -MT composefs/libcomposefs/libcomposefs_la-lcfs-mount.lo -MD -MP -MF composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-mount.Tpo -c -o composefs/libcomposefs/libcomposefs_la-lcfs-mount.lo `test -f 'composefs/libcomposefs/lcfs-mount.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-mount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-mount.Tpo composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-mount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='composefs/libcomposefs/lcfs-mount.c' object='composefs/libcomposefs/libcomposefs_la-lcfs-mount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcomposefs_la_CFLAGS) $(CFLAGS) -c -o composefs/libcomposefs/libcomposefs_la-lcfs-mount.lo `test -f 'composefs/libcomposefs/lcfs-mount.c' || echo '$(srcdir)/'`composefs/libcomposefs/lcfs-mount.c + +libglnx/la-glnx-backport-testutils.lo: libglnx/glnx-backport-testutils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglnx_la_CFLAGS) $(CFLAGS) -MT libglnx/la-glnx-backport-testutils.lo -MD -MP -MF libglnx/$(DEPDIR)/la-glnx-backport-testutils.Tpo -c -o libglnx/la-glnx-backport-testutils.lo `test -f 'libglnx/glnx-backport-testutils.c' || echo '$(srcdir)/'`libglnx/glnx-backport-testutils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libglnx/$(DEPDIR)/la-glnx-backport-testutils.Tpo libglnx/$(DEPDIR)/la-glnx-backport-testutils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libglnx/glnx-backport-testutils.c' object='libglnx/la-glnx-backport-testutils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglnx_la_CFLAGS) $(CFLAGS) -c -o libglnx/la-glnx-backport-testutils.lo `test -f 'libglnx/glnx-backport-testutils.c' || echo '$(srcdir)/'`libglnx/glnx-backport-testutils.c + libglnx/la-glnx-backports.lo: libglnx/glnx-backports.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglnx_la_CFLAGS) $(CFLAGS) -MT libglnx/la-glnx-backports.lo -MD -MP -MF libglnx/$(DEPDIR)/la-glnx-backports.Tpo -c -o libglnx/la-glnx-backports.lo `test -f 'libglnx/glnx-backports.c' || echo '$(srcdir)/'`libglnx/glnx-backports.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libglnx/$(DEPDIR)/la-glnx-backports.Tpo libglnx/$(DEPDIR)/la-glnx-backports.Plo @@ -5266,6 +5525,13 @@ src/libostree/libostree_1_la-ostree-repo-commit.lo: src/libostree/ostree-repo-co @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-repo-commit.lo `test -f 'src/libostree/ostree-repo-commit.c' || echo '$(srcdir)/'`src/libostree/ostree-repo-commit.c +src/libostree/libostree_1_la-ostree-repo-composefs.lo: src/libostree/ostree-repo-composefs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-repo-composefs.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-composefs.Tpo -c -o src/libostree/libostree_1_la-ostree-repo-composefs.lo `test -f 'src/libostree/ostree-repo-composefs.c' || echo '$(srcdir)/'`src/libostree/ostree-repo-composefs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-composefs.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-composefs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-repo-composefs.c' object='src/libostree/libostree_1_la-ostree-repo-composefs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-repo-composefs.lo `test -f 'src/libostree/ostree-repo-composefs.c' || echo '$(srcdir)/'`src/libostree/ostree-repo-composefs.c + src/libostree/libostree_1_la-ostree-repo-pull.lo: src/libostree/ostree-repo-pull.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-repo-pull.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-pull.Tpo -c -o src/libostree/libostree_1_la-ostree-repo-pull.lo `test -f 'src/libostree/ostree-repo-pull.c' || echo '$(srcdir)/'`src/libostree/ostree-repo-pull.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-pull.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-pull.Plo @@ -5392,6 +5658,13 @@ src/libostree/libostree_1_la-ostree-bootloader.lo: src/libostree/ostree-bootload @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-bootloader.lo `test -f 'src/libostree/ostree-bootloader.c' || echo '$(srcdir)/'`src/libostree/ostree-bootloader.c +src/libostree/libostree_1_la-ostree-bootloader-aboot.lo: src/libostree/ostree-bootloader-aboot.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-bootloader-aboot.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-aboot.Tpo -c -o src/libostree/libostree_1_la-ostree-bootloader-aboot.lo `test -f 'src/libostree/ostree-bootloader-aboot.c' || echo '$(srcdir)/'`src/libostree/ostree-bootloader-aboot.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-aboot.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-aboot.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-bootloader-aboot.c' object='src/libostree/libostree_1_la-ostree-bootloader-aboot.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-bootloader-aboot.lo `test -f 'src/libostree/ostree-bootloader-aboot.c' || echo '$(srcdir)/'`src/libostree/ostree-bootloader-aboot.c + src/libostree/libostree_1_la-ostree-bootloader-grub2.lo: src/libostree/ostree-bootloader-grub2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-bootloader-grub2.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-grub2.Tpo -c -o src/libostree/libostree_1_la-ostree-bootloader-grub2.lo `test -f 'src/libostree/ostree-bootloader-grub2.c' || echo '$(srcdir)/'`src/libostree/ostree-bootloader-grub2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-grub2.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-grub2.Plo @@ -5567,6 +5840,13 @@ src/libostree/libostree_1_la-ostree-fetcher-curl.lo: src/libostree/ostree-fetche @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-fetcher-curl.lo `test -f 'src/libostree/ostree-fetcher-curl.c' || echo '$(srcdir)/'`src/libostree/ostree-fetcher-curl.c +src/libostree/libostree_1_la-ostree-fetcher-soup3.lo: src/libostree/ostree-fetcher-soup3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-fetcher-soup3.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup3.Tpo -c -o src/libostree/libostree_1_la-ostree-fetcher-soup3.lo `test -f 'src/libostree/ostree-fetcher-soup3.c' || echo '$(srcdir)/'`src/libostree/ostree-fetcher-soup3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup3.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup3.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-fetcher-soup3.c' object='src/libostree/libostree_1_la-ostree-fetcher-soup3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-fetcher-soup3.lo `test -f 'src/libostree/ostree-fetcher-soup3.c' || echo '$(srcdir)/'`src/libostree/ostree-fetcher-soup3.c + src/libostree/libostree_1_la-ostree-fetcher-soup.lo: src/libostree/ostree-fetcher-soup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-fetcher-soup.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup.Tpo -c -o src/libostree/libostree_1_la-ostree-fetcher-soup.lo `test -f 'src/libostree/ostree-fetcher-soup.c' || echo '$(srcdir)/'`src/libostree/ostree-fetcher-soup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup.Plo @@ -5616,6 +5896,20 @@ tests/libostreetest_la-test-mock-gio.lo: tests/test-mock-gio.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostreetest_la_CFLAGS) $(CFLAGS) -c -o tests/libostreetest_la-test-mock-gio.lo `test -f 'tests/test-mock-gio.c' || echo '$(srcdir)/'`tests/test-mock-gio.c +src/libotcore/libotcore_la-otcore-ed25519-verify.lo: src/libotcore/otcore-ed25519-verify.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotcore_la_CFLAGS) $(CFLAGS) -MT src/libotcore/libotcore_la-otcore-ed25519-verify.lo -MD -MP -MF src/libotcore/$(DEPDIR)/libotcore_la-otcore-ed25519-verify.Tpo -c -o src/libotcore/libotcore_la-otcore-ed25519-verify.lo `test -f 'src/libotcore/otcore-ed25519-verify.c' || echo '$(srcdir)/'`src/libotcore/otcore-ed25519-verify.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libotcore/$(DEPDIR)/libotcore_la-otcore-ed25519-verify.Tpo src/libotcore/$(DEPDIR)/libotcore_la-otcore-ed25519-verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libotcore/otcore-ed25519-verify.c' object='src/libotcore/libotcore_la-otcore-ed25519-verify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotcore_la_CFLAGS) $(CFLAGS) -c -o src/libotcore/libotcore_la-otcore-ed25519-verify.lo `test -f 'src/libotcore/otcore-ed25519-verify.c' || echo '$(srcdir)/'`src/libotcore/otcore-ed25519-verify.c + +src/libotcore/libotcore_la-otcore-prepare-root.lo: src/libotcore/otcore-prepare-root.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotcore_la_CFLAGS) $(CFLAGS) -MT src/libotcore/libotcore_la-otcore-prepare-root.lo -MD -MP -MF src/libotcore/$(DEPDIR)/libotcore_la-otcore-prepare-root.Tpo -c -o src/libotcore/libotcore_la-otcore-prepare-root.lo `test -f 'src/libotcore/otcore-prepare-root.c' || echo '$(srcdir)/'`src/libotcore/otcore-prepare-root.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libotcore/$(DEPDIR)/libotcore_la-otcore-prepare-root.Tpo src/libotcore/$(DEPDIR)/libotcore_la-otcore-prepare-root.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libotcore/otcore-prepare-root.c' object='src/libotcore/libotcore_la-otcore-prepare-root.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotcore_la_CFLAGS) $(CFLAGS) -c -o src/libotcore/libotcore_la-otcore-prepare-root.lo `test -f 'src/libotcore/otcore-prepare-root.c' || echo '$(srcdir)/'`src/libotcore/otcore-prepare-root.c + src/libotutil/libotutil_la-ot-checksum-utils.lo: src/libotutil/ot-checksum-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -MT src/libotutil/libotutil_la-ot-checksum-utils.lo -MD -MP -MF src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-utils.Tpo -c -o src/libotutil/libotutil_la-ot-checksum-utils.lo `test -f 'src/libotutil/ot-checksum-utils.c' || echo '$(srcdir)/'`src/libotutil/ot-checksum-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-utils.Tpo src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-utils.Plo @@ -5700,13 +5994,6 @@ src/libotutil/libotutil_la-zbase32.lo: src/libotutil/zbase32.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -c -o src/libotutil/libotutil_la-zbase32.lo `test -f 'src/libotutil/zbase32.c' || echo '$(srcdir)/'`src/libotutil/zbase32.c -tests/libreaddir_rand_la-readdir-rand.lo: tests/readdir-rand.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libreaddir_rand_la_CFLAGS) $(CFLAGS) -MT tests/libreaddir_rand_la-readdir-rand.lo -MD -MP -MF tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Tpo -c -o tests/libreaddir_rand_la-readdir-rand.lo `test -f 'tests/readdir-rand.c' || echo '$(srcdir)/'`tests/readdir-rand.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Tpo tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/readdir-rand.c' object='tests/libreaddir_rand_la-readdir-rand.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libreaddir_rand_la_CFLAGS) $(CFLAGS) -c -o tests/libreaddir_rand_la-readdir-rand.lo `test -f 'tests/readdir-rand.c' || echo '$(srcdir)/'`tests/readdir-rand.c - src/ostree/ostree-main.o: src/ostree/main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-main.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-main.Tpo -c -o src/ostree/ostree-main.o `test -f 'src/ostree/main.c' || echo '$(srcdir)/'`src/ostree/main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-main.Tpo src/ostree/$(DEPDIR)/ostree-main.Po @@ -6197,6 +6484,20 @@ src/ostree/ostree-ot-admin-builtin-undeploy.obj: src/ostree/ot-admin-builtin-und @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-builtin-undeploy.obj `if test -f 'src/ostree/ot-admin-builtin-undeploy.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-builtin-undeploy.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-builtin-undeploy.c'; fi` +src/ostree/ostree-ot-admin-builtin-set-default.o: src/ostree/ot-admin-builtin-set-default.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-builtin-set-default.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Tpo -c -o src/ostree/ostree-ot-admin-builtin-set-default.o `test -f 'src/ostree/ot-admin-builtin-set-default.c' || echo '$(srcdir)/'`src/ostree/ot-admin-builtin-set-default.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-admin-builtin-set-default.c' object='src/ostree/ostree-ot-admin-builtin-set-default.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-builtin-set-default.o `test -f 'src/ostree/ot-admin-builtin-set-default.c' || echo '$(srcdir)/'`src/ostree/ot-admin-builtin-set-default.c + +src/ostree/ostree-ot-admin-builtin-set-default.obj: src/ostree/ot-admin-builtin-set-default.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-builtin-set-default.obj -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Tpo -c -o src/ostree/ostree-ot-admin-builtin-set-default.obj `if test -f 'src/ostree/ot-admin-builtin-set-default.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-builtin-set-default.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-builtin-set-default.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-admin-builtin-set-default.c' object='src/ostree/ostree-ot-admin-builtin-set-default.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-builtin-set-default.obj `if test -f 'src/ostree/ot-admin-builtin-set-default.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-builtin-set-default.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-builtin-set-default.c'; fi` + src/ostree/ostree-ot-admin-builtin-instutil.o: src/ostree/ot-admin-builtin-instutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-builtin-instutil.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-instutil.Tpo -c -o src/ostree/ostree-ot-admin-builtin-instutil.o `test -f 'src/ostree/ot-admin-builtin-instutil.c' || echo '$(srcdir)/'`src/ostree/ot-admin-builtin-instutil.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-instutil.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-instutil.Po @@ -6211,6 +6512,20 @@ src/ostree/ostree-ot-admin-builtin-instutil.obj: src/ostree/ot-admin-builtin-ins @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-builtin-instutil.obj `if test -f 'src/ostree/ot-admin-builtin-instutil.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-builtin-instutil.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-builtin-instutil.c'; fi` +src/ostree/ostree-ot-admin-builtin-kargs.o: src/ostree/ot-admin-builtin-kargs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-builtin-kargs.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Tpo -c -o src/ostree/ostree-ot-admin-builtin-kargs.o `test -f 'src/ostree/ot-admin-builtin-kargs.c' || echo '$(srcdir)/'`src/ostree/ot-admin-builtin-kargs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-admin-builtin-kargs.c' object='src/ostree/ostree-ot-admin-builtin-kargs.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-builtin-kargs.o `test -f 'src/ostree/ot-admin-builtin-kargs.c' || echo '$(srcdir)/'`src/ostree/ot-admin-builtin-kargs.c + +src/ostree/ostree-ot-admin-builtin-kargs.obj: src/ostree/ot-admin-builtin-kargs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-builtin-kargs.obj -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Tpo -c -o src/ostree/ostree-ot-admin-builtin-kargs.obj `if test -f 'src/ostree/ot-admin-builtin-kargs.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-builtin-kargs.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-builtin-kargs.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-admin-builtin-kargs.c' object='src/ostree/ostree-ot-admin-builtin-kargs.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-builtin-kargs.obj `if test -f 'src/ostree/ot-admin-builtin-kargs.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-builtin-kargs.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-builtin-kargs.c'; fi` + src/ostree/ostree-ot-admin-builtin-cleanup.o: src/ostree/ot-admin-builtin-cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-builtin-cleanup.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-cleanup.Tpo -c -o src/ostree/ostree-ot-admin-builtin-cleanup.o `test -f 'src/ostree/ot-admin-builtin-cleanup.c' || echo '$(srcdir)/'`src/ostree/ot-admin-builtin-cleanup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-cleanup.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-cleanup.Po @@ -6379,6 +6694,20 @@ src/ostree/ostree-ot-admin-functions.obj: src/ostree/ot-admin-functions.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-functions.obj `if test -f 'src/ostree/ot-admin-functions.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-functions.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-functions.c'; fi` +src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.o: src/ostree/ot-admin-kargs-builtin-edit-in-place.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Tpo -c -o src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.o `test -f 'src/ostree/ot-admin-kargs-builtin-edit-in-place.c' || echo '$(srcdir)/'`src/ostree/ot-admin-kargs-builtin-edit-in-place.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-admin-kargs-builtin-edit-in-place.c' object='src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.o `test -f 'src/ostree/ot-admin-kargs-builtin-edit-in-place.c' || echo '$(srcdir)/'`src/ostree/ot-admin-kargs-builtin-edit-in-place.c + +src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.obj: src/ostree/ot-admin-kargs-builtin-edit-in-place.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.obj -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Tpo -c -o src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.obj `if test -f 'src/ostree/ot-admin-kargs-builtin-edit-in-place.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-kargs-builtin-edit-in-place.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-kargs-builtin-edit-in-place.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Tpo src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-admin-kargs-builtin-edit-in-place.c' object='src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-admin-kargs-builtin-edit-in-place.obj `if test -f 'src/ostree/ot-admin-kargs-builtin-edit-in-place.c'; then $(CYGPATH_W) 'src/ostree/ot-admin-kargs-builtin-edit-in-place.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-admin-kargs-builtin-edit-in-place.c'; fi` + src/ostree/ostree-ot-remote-builtin-add.o: src/ostree/ot-remote-builtin-add.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-remote-builtin-add.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-remote-builtin-add.Tpo -c -o src/ostree/ostree-ot-remote-builtin-add.o `test -f 'src/ostree/ot-remote-builtin-add.c' || echo '$(srcdir)/'`src/ostree/ot-remote-builtin-add.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-remote-builtin-add.Tpo src/ostree/$(DEPDIR)/ostree-ot-remote-builtin-add.Po @@ -6561,20 +6890,6 @@ src/ostree/ostree-ot-builtin-pull.obj: src/ostree/ot-builtin-pull.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-builtin-pull.obj `if test -f 'src/ostree/ot-builtin-pull.c'; then $(CYGPATH_W) 'src/ostree/ot-builtin-pull.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-builtin-pull.c'; fi` -src/ostree/ostree-ot-builtin-trivial-httpd.o: src/ostree/ot-builtin-trivial-httpd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-builtin-trivial-httpd.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Tpo -c -o src/ostree/ostree-ot-builtin-trivial-httpd.o `test -f 'src/ostree/ot-builtin-trivial-httpd.c' || echo '$(srcdir)/'`src/ostree/ot-builtin-trivial-httpd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Tpo src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-builtin-trivial-httpd.c' object='src/ostree/ostree-ot-builtin-trivial-httpd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-builtin-trivial-httpd.o `test -f 'src/ostree/ot-builtin-trivial-httpd.c' || echo '$(srcdir)/'`src/ostree/ot-builtin-trivial-httpd.c - -src/ostree/ostree-ot-builtin-trivial-httpd.obj: src/ostree/ot-builtin-trivial-httpd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-ot-builtin-trivial-httpd.obj -MD -MP -MF src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Tpo -c -o src/ostree/ostree-ot-builtin-trivial-httpd.obj `if test -f 'src/ostree/ot-builtin-trivial-httpd.c'; then $(CYGPATH_W) 'src/ostree/ot-builtin-trivial-httpd.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-builtin-trivial-httpd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Tpo src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ot-builtin-trivial-httpd.c' object='src/ostree/ostree-ot-builtin-trivial-httpd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-builtin-trivial-httpd.obj `if test -f 'src/ostree/ot-builtin-trivial-httpd.c'; then $(CYGPATH_W) 'src/ostree/ot-builtin-trivial-httpd.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-builtin-trivial-httpd.c'; fi` - src/ostree/ostree-parse-datetime.o: src/ostree/parse-datetime.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -MT src/ostree/ostree-parse-datetime.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree-parse-datetime.Tpo -c -o src/ostree/ostree-parse-datetime.o `test -f 'src/ostree/parse-datetime.c' || echo '$(srcdir)/'`src/ostree/parse-datetime.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree-parse-datetime.Tpo src/ostree/$(DEPDIR)/ostree-parse-datetime.Po @@ -6589,6 +6904,20 @@ src/ostree/ostree-parse-datetime.obj: src/ostree/parse-datetime.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-parse-datetime.obj `if test -f 'src/ostree/parse-datetime.c'; then $(CYGPATH_W) 'src/ostree/parse-datetime.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/parse-datetime.c'; fi` +src/switchroot/ostree_prepare_root-ostree-prepare-root-static.o: src/switchroot/ostree-prepare-root-static.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_prepare_root-ostree-prepare-root-static.o -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Tpo -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root-static.o `test -f 'src/switchroot/ostree-prepare-root-static.c' || echo '$(srcdir)/'`src/switchroot/ostree-prepare-root-static.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Tpo src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-prepare-root-static.c' object='src/switchroot/ostree_prepare_root-ostree-prepare-root-static.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root-static.o `test -f 'src/switchroot/ostree-prepare-root-static.c' || echo '$(srcdir)/'`src/switchroot/ostree-prepare-root-static.c + +src/switchroot/ostree_prepare_root-ostree-prepare-root-static.obj: src/switchroot/ostree-prepare-root-static.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_prepare_root-ostree-prepare-root-static.obj -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Tpo -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root-static.obj `if test -f 'src/switchroot/ostree-prepare-root-static.c'; then $(CYGPATH_W) 'src/switchroot/ostree-prepare-root-static.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-prepare-root-static.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Tpo src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-prepare-root-static.c' object='src/switchroot/ostree_prepare_root-ostree-prepare-root-static.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root-static.obj `if test -f 'src/switchroot/ostree-prepare-root-static.c'; then $(CYGPATH_W) 'src/switchroot/ostree-prepare-root-static.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-prepare-root-static.c'; fi` + src/switchroot/ostree_prepare_root-ostree-prepare-root.o: src/switchroot/ostree-prepare-root.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_prepare_root-ostree-prepare-root.o -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.o `test -f 'src/switchroot/ostree-prepare-root.c' || echo '$(srcdir)/'`src/switchroot/ostree-prepare-root.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po @@ -7135,6 +7464,20 @@ tests/test_ot_unix_utils-test-ot-unix-utils.obj: tests/test-ot-unix-utils.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_ot_unix_utils_CFLAGS) $(CFLAGS) -c -o tests/test_ot_unix_utils-test-ot-unix-utils.obj `if test -f 'tests/test-ot-unix-utils.c'; then $(CYGPATH_W) 'tests/test-ot-unix-utils.c'; else $(CYGPATH_W) '$(srcdir)/tests/test-ot-unix-utils.c'; fi` +tests/test_otcore-test-otcore.o: tests/test-otcore.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_otcore_CFLAGS) $(CFLAGS) -MT tests/test_otcore-test-otcore.o -MD -MP -MF tests/$(DEPDIR)/test_otcore-test-otcore.Tpo -c -o tests/test_otcore-test-otcore.o `test -f 'tests/test-otcore.c' || echo '$(srcdir)/'`tests/test-otcore.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/test_otcore-test-otcore.Tpo tests/$(DEPDIR)/test_otcore-test-otcore.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/test-otcore.c' object='tests/test_otcore-test-otcore.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_otcore_CFLAGS) $(CFLAGS) -c -o tests/test_otcore-test-otcore.o `test -f 'tests/test-otcore.c' || echo '$(srcdir)/'`tests/test-otcore.c + +tests/test_otcore-test-otcore.obj: tests/test-otcore.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_otcore_CFLAGS) $(CFLAGS) -MT tests/test_otcore-test-otcore.obj -MD -MP -MF tests/$(DEPDIR)/test_otcore-test-otcore.Tpo -c -o tests/test_otcore-test-otcore.obj `if test -f 'tests/test-otcore.c'; then $(CYGPATH_W) 'tests/test-otcore.c'; else $(CYGPATH_W) '$(srcdir)/tests/test-otcore.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/test_otcore-test-otcore.Tpo tests/$(DEPDIR)/test_otcore-test-otcore.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/test-otcore.c' object='tests/test_otcore-test-otcore.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_otcore_CFLAGS) $(CFLAGS) -c -o tests/test_otcore-test-otcore.obj `if test -f 'tests/test-otcore.c'; then $(CYGPATH_W) 'tests/test-otcore.c'; else $(CYGPATH_W) '$(srcdir)/tests/test-otcore.c'; fi` + tests/test_pull_c-test-pull-c.o: tests/test-pull-c.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_pull_c_CFLAGS) $(CFLAGS) -MT tests/test_pull_c-test-pull-c.o -MD -MP -MF tests/$(DEPDIR)/test_pull_c-test-pull-c.Tpo -c -o tests/test_pull_c-test-pull-c.o `test -f 'tests/test-pull-c.c' || echo '$(srcdir)/'`tests/test-pull-c.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/test_pull_c-test-pull-c.Tpo tests/$(DEPDIR)/test_pull_c-test-pull-c.Po @@ -7351,8 +7694,10 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -rm -rf bsdiff/.libs bsdiff/_libs + -rm -rf composefs/libcomposefs/.libs composefs/libcomposefs/_libs -rm -rf libglnx/.libs libglnx/_libs -rm -rf src/libostree/.libs src/libostree/_libs + -rm -rf src/libotcore/.libs src/libotcore/_libs -rm -rf src/libotutil/.libs src/libotutil/_libs -rm -rf tests/.libs tests/_libs @@ -8097,6 +8442,13 @@ tests/test-bsdiff.log: tests/test-bsdiff$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-otcore.log: tests/test-otcore$(EXEEXT) + @p='tests/test-otcore$(EXEEXT)'; \ + b='tests/test-otcore'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test-mutable-tree.log: tests/test-mutable-tree$(EXEEXT) @p='tests/test-mutable-tree$(EXEEXT)'; \ b='tests/test-mutable-tree'; \ @@ -8279,6 +8631,20 @@ tests/test-remote-headers.sh.log: tests/test-remote-headers.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-remote-refs.sh.log: tests/test-remote-refs.sh + @p='tests/test-remote-refs.sh'; \ + b='tests/test-remote-refs.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-composefs.sh.log: tests/test-composefs.sh + @p='tests/test-composefs.sh'; \ + b='tests/test-composefs.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test-commit-sign.sh.log: tests/test-commit-sign.sh @p='tests/test-commit-sign.sh'; \ b='tests/test-commit-sign.sh'; \ @@ -8489,6 +8855,13 @@ tests/test-admin-deploy-syslinux.sh.log: tests/test-admin-deploy-syslinux.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-admin-deploy-bootprefix.sh.log: tests/test-admin-deploy-bootprefix.sh + @p='tests/test-admin-deploy-bootprefix.sh'; \ + b='tests/test-admin-deploy-bootprefix.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test-admin-deploy-2.sh.log: tests/test-admin-deploy-2.sh @p='tests/test-admin-deploy-2.sh'; \ b='tests/test-admin-deploy-2.sh'; \ @@ -8552,6 +8925,20 @@ tests/test-admin-deploy-bootid-gc.sh.log: tests/test-admin-deploy-bootid-gc.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-admin-deploy-whiteouts.sh.log: tests/test-admin-deploy-whiteouts.sh + @p='tests/test-admin-deploy-whiteouts.sh'; \ + b='tests/test-admin-deploy-whiteouts.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-admin-deploy-emptyetc.sh.log: tests/test-admin-deploy-emptyetc.sh + @p='tests/test-admin-deploy-emptyetc.sh'; \ + b='tests/test-admin-deploy-emptyetc.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test-osupdate-dtb.sh.log: tests/test-osupdate-dtb.sh @p='tests/test-osupdate-dtb.sh'; \ b='tests/test-osupdate-dtb.sh'; \ @@ -8601,6 +8988,13 @@ tests/test-admin-deploy-clean.sh.log: tests/test-admin-deploy-clean.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-admin-kargs.sh.log: tests/test-admin-kargs.sh + @p='tests/test-admin-kargs.sh'; \ + b='tests/test-admin-kargs.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test-reset-nonlinear.sh.log: tests/test-reset-nonlinear.sh @p='tests/test-reset-nonlinear.sh'; \ b='tests/test-reset-nonlinear.sh'; \ @@ -9244,12 +9638,16 @@ distclean-generic: -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f bsdiff/$(DEPDIR)/$(am__dirstamp) -rm -f bsdiff/$(am__dirstamp) + -rm -f composefs/libcomposefs/$(DEPDIR)/$(am__dirstamp) + -rm -f composefs/libcomposefs/$(am__dirstamp) -rm -f libglnx/$(DEPDIR)/$(am__dirstamp) -rm -f libglnx/$(am__dirstamp) -rm -f libglnx/tests/$(DEPDIR)/$(am__dirstamp) -rm -f libglnx/tests/$(am__dirstamp) -rm -f src/libostree/$(DEPDIR)/$(am__dirstamp) -rm -f src/libostree/$(am__dirstamp) + -rm -f src/libotcore/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libotcore/$(am__dirstamp) -rm -f src/libotutil/$(DEPDIR)/$(am__dirstamp) -rm -f src/libotutil/$(am__dirstamp) -rm -f src/ostree/$(DEPDIR)/$(am__dirstamp) @@ -9280,6 +9678,12 @@ distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo -rm -f bsdiff/$(DEPDIR)/libbsdiff_la-bspatch.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-hash.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-fsverity.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-mount.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer-erofs.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer.Plo + -rm -f libglnx/$(DEPDIR)/la-glnx-backport-testutils.Plo -rm -f libglnx/$(DEPDIR)/la-glnx-backports.Plo -rm -f libglnx/$(DEPDIR)/la-glnx-console.Plo -rm -f libglnx/$(DEPDIR)/la-glnx-dirfd.Plo @@ -9303,6 +9707,7 @@ distclean: distclean-recursive -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-async-progress.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bloom.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootconfig-parser.Plo + -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-aboot.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-grub2.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-syslinux.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-uboot.Plo @@ -9320,6 +9725,7 @@ distclean: distclean-recursive -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-enumtypes.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-curl.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup.Plo + -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup3.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-uri.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verifier.Plo @@ -9338,6 +9744,7 @@ distclean: distclean-recursive -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-checkout.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-commit.Plo + -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-composefs.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file-enumerator.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-finder-avahi-parser.Plo @@ -9382,6 +9789,8 @@ distclean: distclean-recursive -rm -f src/libostree/$(DEPDIR)/tests_test_rollsum-ostree-rollsum.Po -rm -f src/libostree/$(DEPDIR)/tests_test_rollsum_cli-ostree-rollsum.Po -rm -f src/libostree/$(DEPDIR)/tests_test_varint-ostree-varint.Po + -rm -f src/libotcore/$(DEPDIR)/libotcore_la-otcore-ed25519-verify.Plo + -rm -f src/libotcore/$(DEPDIR)/libotcore_la-otcore-prepare-root.Plo -rm -f src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-instream.Plo -rm -f src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-utils.Plo -rm -f src/libotutil/$(DEPDIR)/libotutil_la-ot-fs-utils.Plo @@ -9402,8 +9811,10 @@ distclean: distclean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-finalize-staged.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-init-fs.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-instutil.Po + -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-os-init.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-pin.Po + -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-origin.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-status.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-switch.Po @@ -9414,6 +9825,7 @@ distclean: distclean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-grub2-generate.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-selinux-ensure-labeled.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-set-kargs.Po + -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-admin.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-cat.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-checkout.Po @@ -9440,7 +9852,6 @@ distclean: distclean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-sign.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-static-delta.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-summary.Po - -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-dump.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-editor.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-main.Po @@ -9459,13 +9870,13 @@ distclean: distclean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-parse-datetime.Po -rm -f src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Po -rm -f src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Po + -rm -f src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Po -rm -f src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po -rm -f src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po -rm -f src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Po -rm -f tests/$(DEPDIR)/get_byte_order-get-byte-order.Po -rm -f tests/$(DEPDIR)/libostreetest_la-libostreetest.Plo -rm -f tests/$(DEPDIR)/libostreetest_la-test-mock-gio.Plo - -rm -f tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Plo -rm -f tests/$(DEPDIR)/repo_finder_mount-repo-finder-mount.Po -rm -f tests/$(DEPDIR)/test_basic_c-test-basic-c.Po -rm -f tests/$(DEPDIR)/test_bloom-test-bloom.Po @@ -9482,6 +9893,7 @@ distclean: distclean-recursive -rm -f tests/$(DEPDIR)/test_ot_opt_utils-test-ot-opt-utils.Po -rm -f tests/$(DEPDIR)/test_ot_tool_util-test-ot-tool-util.Po -rm -f tests/$(DEPDIR)/test_ot_unix_utils-test-ot-unix-utils.Po + -rm -f tests/$(DEPDIR)/test_otcore-test-otcore.Po -rm -f tests/$(DEPDIR)/test_pull_c-test-pull-c.Po -rm -f tests/$(DEPDIR)/test_repo-test-repo.Po -rm -f tests/$(DEPDIR)/test_repo_finder_avahi-test-repo-finder-avahi.Po @@ -9561,6 +9973,12 @@ maintainer-clean: maintainer-clean-recursive -rm -rf $(top_srcdir)/autom4te.cache -rm -f bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo -rm -f bsdiff/$(DEPDIR)/libbsdiff_la-bspatch.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-hash.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-fsverity.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-mount.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer-erofs.Plo + -rm -f composefs/libcomposefs/$(DEPDIR)/libcomposefs_la-lcfs-writer.Plo + -rm -f libglnx/$(DEPDIR)/la-glnx-backport-testutils.Plo -rm -f libglnx/$(DEPDIR)/la-glnx-backports.Plo -rm -f libglnx/$(DEPDIR)/la-glnx-console.Plo -rm -f libglnx/$(DEPDIR)/la-glnx-dirfd.Plo @@ -9584,6 +10002,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-async-progress.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bloom.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootconfig-parser.Plo + -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-aboot.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-grub2.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-syslinux.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootloader-uboot.Plo @@ -9601,6 +10020,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-enumtypes.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-curl.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup.Plo + -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-soup3.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-uri.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verifier.Plo @@ -9619,6 +10039,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-checkout.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-commit.Plo + -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-composefs.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file-enumerator.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-finder-avahi-parser.Plo @@ -9663,6 +10084,8 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/libostree/$(DEPDIR)/tests_test_rollsum-ostree-rollsum.Po -rm -f src/libostree/$(DEPDIR)/tests_test_rollsum_cli-ostree-rollsum.Po -rm -f src/libostree/$(DEPDIR)/tests_test_varint-ostree-varint.Po + -rm -f src/libotcore/$(DEPDIR)/libotcore_la-otcore-ed25519-verify.Plo + -rm -f src/libotcore/$(DEPDIR)/libotcore_la-otcore-prepare-root.Plo -rm -f src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-instream.Plo -rm -f src/libotutil/$(DEPDIR)/libotutil_la-ot-checksum-utils.Plo -rm -f src/libotutil/$(DEPDIR)/libotutil_la-ot-fs-utils.Plo @@ -9683,8 +10106,10 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-finalize-staged.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-init-fs.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-instutil.Po + -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-kargs.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-os-init.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-pin.Po + -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-default.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-set-origin.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-status.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-builtin-switch.Po @@ -9695,6 +10120,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-grub2-generate.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-selinux-ensure-labeled.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-instutil-builtin-set-kargs.Po + -rm -f src/ostree/$(DEPDIR)/ostree-ot-admin-kargs-builtin-edit-in-place.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-admin.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-cat.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-checkout.Po @@ -9721,7 +10147,6 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-sign.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-static-delta.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-summary.Po - -rm -f src/ostree/$(DEPDIR)/ostree-ot-builtin-trivial-httpd.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-dump.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-editor.Po -rm -f src/ostree/$(DEPDIR)/ostree-ot-main.Po @@ -9740,13 +10165,13 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/ostree/$(DEPDIR)/ostree-parse-datetime.Po -rm -f src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Po -rm -f src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Po + -rm -f src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root-static.Po -rm -f src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po -rm -f src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po -rm -f src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Po -rm -f tests/$(DEPDIR)/get_byte_order-get-byte-order.Po -rm -f tests/$(DEPDIR)/libostreetest_la-libostreetest.Plo -rm -f tests/$(DEPDIR)/libostreetest_la-test-mock-gio.Plo - -rm -f tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Plo -rm -f tests/$(DEPDIR)/repo_finder_mount-repo-finder-mount.Po -rm -f tests/$(DEPDIR)/test_basic_c-test-basic-c.Po -rm -f tests/$(DEPDIR)/test_bloom-test-bloom.Po @@ -9763,6 +10188,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f tests/$(DEPDIR)/test_ot_opt_utils-test-ot-opt-utils.Po -rm -f tests/$(DEPDIR)/test_ot_tool_util-test-ot-tool-util.Po -rm -f tests/$(DEPDIR)/test_ot_unix_utils-test-ot-unix-utils.Po + -rm -f tests/$(DEPDIR)/test_otcore-test-otcore.Po -rm -f tests/$(DEPDIR)/test_pull_c-test-pull-c.Po -rm -f tests/$(DEPDIR)/test_repo-test-repo.Po -rm -f tests/$(DEPDIR)/test_repo_finder_avahi-test-repo-finder-avahi.Po @@ -9930,11 +10356,7 @@ src/ostree/parse-datetime.c: src/ostree/parse-datetime.y Makefile $(AM_V_GEN) $(YACC) $< -o $@ @BUILDOPT_USE_STATIC_COMPILER_TRUE@ostree-prepare-root : $(ostree_prepare_root_SOURCES) -@BUILDOPT_USE_STATIC_COMPILER_TRUE@ $(STATIC_COMPILER) -o $@ -static $(top_srcdir)/src/switchroot/ostree-prepare-root.c $(ostree_prepare_root_CPPFLAGS) $(AM_CFLAGS) $(DEFAULT_INCLUDES) -DOSTREE_PREPARE_ROOT_STATIC=1 - -tests/libreaddir-rand.so: Makefile - mkdir -p tests/ - $(AM_V_GEN) ln -fns ../.libs/libreaddir-rand.so tests/ +@BUILDOPT_USE_STATIC_COMPILER_TRUE@ $(STATIC_COMPILER) -o $@ -static $(top_srcdir)/src/switchroot/ostree-prepare-root-static.c $(ostree_prepare_root_CPPFLAGS) $(AM_CFLAGS) $(DEFAULT_INCLUDES) -DOSTREE_PREPARE_ROOT_STATIC=1 tests/%-symlink-stamp: % Makefile $(AM_V_GEN) set -e; \ @@ -9952,11 +10374,11 @@ tests/%-symlink-stamp: % Makefile @ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@check-local: @ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@ echo "NOTE: Run the Rust installed tests (uninstalled) with ./tests/run-installed" -@USE_LIBSOUP_FALSE@no-soup-for-you-warning: -@USE_LIBSOUP_FALSE@ @echo "WARNING: $(PACKAGE) was built without libsoup, which is currently" 1>&2 -@USE_LIBSOUP_FALSE@ @echo "WARNING: required for many unit tests." 1>&2 -@USE_LIBSOUP_FALSE@ sleep 10 -@USE_LIBSOUP_FALSE@check: no-soup-for-you-warning +@USE_LIBSOUP_OR_LIBSOUP3_FALSE@no-soup-for-you-warning: +@USE_LIBSOUP_OR_LIBSOUP3_FALSE@ @echo "WARNING: $(PACKAGE) was built without libsoup, which is currently" 1>&2 +@USE_LIBSOUP_OR_LIBSOUP3_FALSE@ @echo "WARNING: required for many unit tests." 1>&2 +@USE_LIBSOUP_OR_LIBSOUP3_FALSE@ sleep 10 +@USE_LIBSOUP_OR_LIBSOUP3_FALSE@check: no-soup-for-you-warning # Unfortunately the glib test data APIs don't actually handle # non-recursive Automake, so we change our code to canonically look @@ -9979,9 +10401,11 @@ install-kola-tests: @BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@ mkdir -p $(DESTDIR)$(grub2configdir) @BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@ ln -sf $(pkglibexecdir)/grub2-15_ostree $(DESTDIR)$(grub2configdir)/15_ostree +# This needs to be outside the conditional to avoid a warning +.PHONY: manhtml + # Convenience target for building the just the HTML man pages @ENABLE_MAN_HTML_TRUE@@ENABLE_MAN_TRUE@manhtml: $(manhtml_files) -@ENABLE_MAN_HTML_TRUE@@ENABLE_MAN_TRUE@.PHONY: manhtml @ENABLE_MAN_TRUE@%.1: %.xml @ENABLE_MAN_TRUE@ $(AM_V_GEN) $(XSLTPROC_MAN) --output $@ $(XSLT_MAN_STYLESHEET) $< @@ -9996,6 +10420,10 @@ install-kola-tests: release-tag: cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION) +.PHONY: clang-format +clang-format: + git ls-files '**.c' '**.cxx' '**.h' '**.hpp' | xargs clang-format -i + release-tarball-embedded: set -x; \ GITVERSION=$(git_version_rpm); export GITVERSION; \ diff --git a/README.md b/README.md index 0896b24..a5e97f7 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ their host system as well as Flatpak. [Liri OS](https://liri.io/download/silverblue/) has the option to install their distribution using ostree. +[TorizonCore](https://developer.toradex.com/torizon/working-with-torizon/torizoncore-technical-overview/) is a Linux distribution for embedded systems that updates via OSTree images delivered via [Uptane](https://uptane.github.io/) and [aktualizr](https://github.com/uptane/aktualizr/). + ## Distribution build tools [meta-updater](https://github.com/advancedtelematic/meta-updater) is @@ -85,9 +87,16 @@ which uses libostree. The [BuildStream](https://gitlab.com/BuildStream/buildstream) build and integration tool supports importing and exporting from libostree repos. +[fedora-iot/otto](https://github.com/fedora-iot/otto) is a tool that helps +ship ostree commits inside Docker/OCI containers and run a webserver +to serve the commits. + Fedora [coreos-assembler](https://github.com/coreos/coreos-assembler) is the build tool used to generate Fedora CoreOS derivatives. +[debos](https://github.com/go-debos/debos) is a tool-chain for simplifying the +process of building a Debian-based OS image. + ## Projects linking to libostree [rpm-ostree](https://github.com/projectatomic/rpm-ostree) is used by the @@ -106,6 +115,8 @@ use the "libostree host system" aspects (e.g. bootloader management), just the "git-like hardlink dedup". For example, Flatpak supports a per-user OSTree repository. +[aktualizr](https://github.com/uptane/aktualizr/) is an [Uptane](https://uptane.github.io/)-conformant software update client library intended for use in automotive and other security-sensitive embedded devices. It uses OSTree to manage the OS of the host device by default. + ## Language bindings libostree is accessible via [GObject Introspection](https://gi.readthedocs.io/en/latest/); @@ -119,7 +130,7 @@ write higher level manual bindings on top; this is more common for statically compiled languages. Here's a list of such bindings: - [ostree-go](https://github.com/ostreedev/ostree-go/) - - [ostree-rs](https://github.com/ostreedev/ostree-rs/) + - [ostree-rs](./rust-bindings) ## Building @@ -131,7 +142,7 @@ However, in order to build from a git clone, you must update the submodules. If you're packaging OSTree and want a tarball, I recommend using a "recursive git archive" script. There are several available online; -[this code](https://github.com/ostreedev/ostree/blob/main/packaging/Makefile.dist-packaging#L11) +[this code](https://github.com/ostreedev/ostree/blob/main/ci/Makefile.dist-packaging#L18) in OSTree is an example. Once you have a git clone or recursive archive, building is the @@ -147,9 +158,8 @@ make install DESTDIR=/path/to/dest ## Contact and discussion forums -OSTree has a [mailing list](https://mail.gnome.org/archives/ostree-list/) and -there is also an `#ostree` channel on [Libera.Chat](ircs://irc.libera.chat/ostree). However, asynchronous+logged -communication is preferred for nontrivial questions. +There is also an `#ostree` channel on [Libera.Chat](ircs://irc.libera.chat/ostree) as +well as [enabled Github discussions](https://github.com/ostreedev/ostree/discussions/). ## Contributing diff --git a/apidoc/Makefile.in b/apidoc/Makefile.in index 591328d..4abac48 100644 --- a/apidoc/Makefile.in +++ b/apidoc/Makefile.in @@ -220,6 +220,7 @@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ FUSE3_CFLAGS = @FUSE3_CFLAGS@ FUSE3_LIBS = @FUSE3_LIBS@ FUSE_CFLAGS = @FUSE_CFLAGS@ @@ -303,6 +304,8 @@ OT_DEP_LZMA_CFLAGS = @OT_DEP_LZMA_CFLAGS@ OT_DEP_LZMA_LIBS = @OT_DEP_LZMA_LIBS@ OT_DEP_SELINUX_CFLAGS = @OT_DEP_SELINUX_CFLAGS@ OT_DEP_SELINUX_LIBS = @OT_DEP_SELINUX_LIBS@ +OT_DEP_SOUP3_CFLAGS = @OT_DEP_SOUP3_CFLAGS@ +OT_DEP_SOUP3_LIBS = @OT_DEP_SOUP3_LIBS@ OT_DEP_SOUP_CFLAGS = @OT_DEP_SOUP_CFLAGS@ OT_DEP_SOUP_LIBS = @OT_DEP_SOUP_LIBS@ OT_DEP_ZLIB_CFLAGS = @OT_DEP_ZLIB_CFLAGS@ diff --git a/apidoc/html/index.html b/apidoc/html/index.html index 22666f1..b651901 100644 --- a/apidoc/html/index.html +++ b/apidoc/html/index.html @@ -14,7 +14,7 @@
-

for OSTree 2022.4

+

for OSTree 2023.6


diff --git a/apidoc/html/ostree-Core-repository-independent-functions.html b/apidoc/html/ostree-Core-repository-independent-functions.html index 52089ce..ec7684f 100644 --- a/apidoc/html/ostree-Core-repository-independent-functions.html +++ b/apidoc/html/ostree-Core-repository-independent-functions.html @@ -467,7 +467,7 @@

-OstreeCommitSizesEntry * +OstreeCommitSizesEntry * ostree_commit_sizes_entry_new () @@ -475,7 +475,7 @@

-OstreeCommitSizesEntry * +OstreeCommitSizesEntry * ostree_commit_sizes_entry_copy () @@ -564,10 +564,6 @@

#define OSTREE_SUMMARY_GVARIANT_FORMAT - -  -OstreeCommitSizesEntry - @@ -725,7 +721,8 @@

Returns

Binary checksum from checksum -of length 32; free with g_free().

+of length 32; +free with g_free().

[transfer full][array fixed-size=32]

@@ -896,7 +893,8 @@

Returns

-

Binary checksum data in bytes +

Binary checksum data in +bytes ; do not free. If bytes does not have the correct length, return NULL.

[transfer none][array fixed-size=32][element-type guint8]

@@ -2548,9 +2546,10 @@

Returns

-

Checksum of the parent commit of commit_variant +

Checksum of the parent commit of commit_variant , or NULL -if none

+if none.

+

[nullable]


@@ -2624,9 +2623,9 @@

SHA256(root dirtree_checksum || root_dirmeta_checksum), -i.e. the SHA-256 of the root "dirtree" object's checksum concatenated with the -root "dirmeta" checksum (both in binary form, not hexadecimal).

+

The content checksums is simply defined as SHA256(root dirtree_checksum || +root_dirmeta_checksum), i.e. the SHA-256 of the root "dirtree" object's checksum concatenated +with the root "dirmeta" checksum (both in binary form, not hexadecimal).

Parameters

@@ -2658,7 +2657,7 @@

GPtrArray **out_sizes_entries, GError **error);

Reads a commit's "ostree.sizes" metadata and returns an array of -OstreeCommitSizesEntry in out_sizes_entries +OstreeCommitSizesEntry in out_sizes_entries . Each element represents an object in the commit. If the commit does not contain the "ostree.sizes" metadata, a G_IO_ERROR_NOT_FOUND error will be @@ -2695,12 +2694,12 @@

ostree_commit_sizes_entry_new ()

-
OstreeCommitSizesEntry *
+
OstreeCommitSizesEntry *
 ostree_commit_sizes_entry_new (const gchar *checksum,
                                OstreeObjectType objtype,
                                guint64 unpacked,
                                guint64 archived);
-

Create a new OstreeCommitSizesEntry for representing an object in a +

Create a new OstreeCommitSizesEntry for representing an object in a commit's "ostree.sizes" metadata.

Parameters

@@ -2736,7 +2735,7 @@

Returns

-

a new OstreeCommitSizesEntry.

+

a new OstreeCommitSizesEntry.

[transfer full][nullable]

Since: 2020.1

@@ -2744,8 +2743,8 @@

ostree_commit_sizes_entry_copy ()

-
OstreeCommitSizesEntry *
-ostree_commit_sizes_entry_copy (const OstreeCommitSizesEntry *entry);
+
OstreeCommitSizesEntry *
+ostree_commit_sizes_entry_copy (const OstreeCommitSizesEntry *entry);

Create a copy of the given entry .

@@ -2758,7 +2757,7 @@

entry

-

+

an OstreeCommitSizesEntry.

an OstreeCommitSizesEntry.

[not nullable]
@@ -2775,7 +2774,7 @@

ostree_commit_sizes_entry_free ()

void
-ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry);
+ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry);

Free given entry .

@@ -2788,7 +2787,7 @@

entry

-

an OstreeCommitSizesEntry.

+

an OstreeCommitSizesEntry.

[transfer full]

@@ -2834,7 +2833,7 @@

Types and Values

OSTREE_MAX_METADATA_SIZE

-
#define OSTREE_MAX_METADATA_SIZE (10 * 1024 * 1024)
+
#define OSTREE_MAX_METADATA_SIZE (128 * 1024 * 1024)
 

Default limit for maximum permitted size in bytes of metadata objects fetched over HTTP (including repo/config files, refs, and commit/dirtree/dirmeta @@ -2921,7 +2920,8 @@

OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK

-

Hardlink to a .file-xattrs given the checksum of its .file object.

+

Hardlink to a .file-xattrs given the checksum of its .file +object.

  @@ -3026,7 +3026,8 @@

#define OSTREE_SUMMARY_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_SUMMARY_GVARIANT_STRING)

+

+
+
+

ostree_repo_commit_add_composefs_metadata ()

+
gboolean
+ostree_repo_commit_add_composefs_metadata
+                               (OstreeRepo *self,
+                                guint format_version,
+                                GVariantDict *dict,
+                                OstreeRepoFile *repo_root,
+                                GCancellable *cancellable,
+                                GError **error);
+

Compute the composefs digest for a filesystem tree +and insert it into metadata for a commit object. The composefs +digest covers the entire filesystem tree and can be verified by +the composefs mount tooling.

+
+

Parameters

+
+++++ + + + + + + + + + + + + + + + + + + + + @@ -7052,7 +7130,7 @@

Ostr

ostree_repo_checkout_at_options_set_devino ()

void
 ostree_repo_checkout_at_options_set_devino
-                               (OstreeRepoCheckoutAtOptions *opts,
+                               (OstreeRepoCheckoutAtOptions *opts,
                                 OstreeRepoDevInoCache *cache);

This function simply assigns cache to the devino_to_csum_cache member of @@ -7234,7 +7312,7 @@

Ostr

ostree_repo_checkout_at ()

gboolean
 ostree_repo_checkout_at (OstreeRepo *self,
-                         OstreeRepoCheckoutAtOptions *options,
+                         OstreeRepoCheckoutAtOptions *options,
                          int destination_dfd,
                          const char *destination_path,
                          const char *commit,
@@ -7371,12 +7449,12 @@ 

Ostr

- + - + @@ -7464,6 +7542,8 @@

Ostr with start , returning data in out_commits .

+

To list all commit objects, provide the empty string "" for start +.

Parameters

self

Repo

 

format_version

Must be zero

 

dict

A GVariant builder of type a{sv}

 

repo_root

the target filesystem tree

 

cancellable

out_root

An OstreeRepoFile corresponding to the root.

[out][out][optional]

out_commit

The resolved commit checksum.

[out][out][optional]

cancellable

@@ -7480,7 +7560,7 @@

Ostr

- + @@ -7534,7 +7614,8 @@

Ostr

- + @@ -7578,7 +7659,8 @@

Ostr

- + @@ -7611,7 +7693,8 @@

Ostr is non-NULL), or for all commits that are reachable by an existing delta (if opt_to_commit is NULL).

-

This is normally called automatically when the summary is updated in ostree_repo_regenerate_summary().

+

This is normally called automatically when the summary is updated in +ostree_repo_regenerate_summary().

Locking: shared

Parameters

@@ -7674,7 +7757,8 @@

Ostr argument should be an a{sv}. The following attributes are known:

    -
  • min-fallback-size: u: Minimum uncompressed size in megabytes to use fallback, 0 to disable fallbacks

  • +
  • min-fallback-size: u: Minimum uncompressed size in megabytes to use fallback, 0 to disable +fallbacks

  • max-chunk-size: u: Maximum size in megabytes of a delta part

  • max-bsdiff-size: u: Maximum size in megabytes to consider bsdiff compression for input files

  • @@ -7682,10 +7766,12 @@

    Ostr
  • bsdiff-enabled: b: Enable bsdiff compression. Default TRUE.

  • inline-parts: b: Put part data in header, to get a single file delta. Default FALSE.

  • verbose: b: Print diagnostic messages. Default FALSE.

  • -
  • endianness: b: Deltas use host byte order by default; this option allows choosing (G_BIG_ENDIAN or G_LITTLE_ENDIAN)

  • -
  • filename: ay: Save delta superblock to this filename, and parts in the same directory. Default saves to repository.

  • -
  • sign-name: ay: Signature type to use.

  • -
  • sign-key-ids: as: Array of keys used to sign delta superblock.

  • +
  • endianness: b: Deltas use host byte order by default; this option allows choosing +(G_BIG_ENDIAN or G_LITTLE_ENDIAN)

  • +
  • filename: ^ay: Save delta superblock to this filename (bytestring), and parts in the same +directory. Default saves to repository.

  • +
  • sign-name: ^ay: Signature type to use (bytestring).

  • +
  • sign-key-ids: ^as: NULL-terminated array of keys used to sign delta superblock.

Parameters

@@ -7996,7 +8082,8 @@

Ostr

- + @@ -8757,7 +8844,8 @@

Ostr

- + @@ -8824,7 +8912,8 @@

Ostr

- + @@ -8881,19 +8970,32 @@

Ostr
  • disable-static-deltas (b): Do not use static deltas

  • require-static-deltas (b): Require static deltas

  • override-commit-ids (as): Array of specific commit IDs to fetch for refs

  • -
  • timestamp-check (b): Verify commit timestamps are newer than current (when pulling via ref); Since: 2017.11

  • -
  • timestamp-check-from-rev (s): Verify that all fetched commit timestamps are newer than timestamp of given rev; Since: 2020.4

  • -
  • metadata-size-restriction (t): Restrict metadata objects to a maximum number of bytes; 0 to disable. Since: 2018.9

  • +
  • timestamp-check (b): Verify commit timestamps are newer than current (when pulling via +ref); Since: 2017.11

  • +
  • timestamp-check-from-rev (s): Verify that all fetched commit timestamps are newer than +timestamp of given rev; Since: 2020.4

  • +
  • max-metadata-size (t): Restrict metadata objects to a maximum number of bytes; 0 to +disable. Since: 2018.9

  • dry-run (b): Only print information on what will be downloaded (requires static deltas)

  • override-url (s): Fetch objects from this URL if remote specifies no metalink in options

  • -
  • inherit-transaction (b): Don't initiate, finish or abort a transaction, useful to do multiple pulls in one transaction.

  • +
  • inherit-transaction (b): Don't initiate, finish or abort a transaction, useful to do +multiple pulls in one transaction.

  • http-headers (a(ss)): Additional headers to add to all HTTP requests

  • -
  • update-frequency (u): Frequency to call the async progress callback in milliseconds, if any; only values higher than 0 are valid

  • -
  • localcache-repos (as): File paths for local repos to use as caches when doing remote fetches

  • +
  • update-frequency (u): Frequency to call the async progress callback in milliseconds, if +any; only values higher than 0 are valid

  • +
  • localcache-repos (as): File paths for local repos to use as caches when doing remote +fetches

  • append-user-agent (s): Additional string to append to the user agent

  • n-network-retries (u): Number of times to retry each download on receiving a transient network error, such as a socket timeout; default is 5, 0 means return errors without retrying. Since: 2018.6

  • +
  • low-speed-limit-bytes (u): The average transfer speed per second of a transfer + during the time set via "low-speed-time-seconds" for libcurl to abort.

  • +
  • low-speed-time-seconds (u): The time in number seconds that the transfer + speed should be below the "low-speed-limit-bytes" setting for libcurl to abort.

  • +
  • retry-all-network-errors (b): Retry when network issues happen, instead of + failing automatically. Currently only affects libcurl. (Default set to true)

  • +
  • max-outstanding-fetcher-requests (u): The max amount of concurrent connections allowed.

  • ref-keyring-map (a(sss)): Array of (collection ID, ref name, keyring remote name) tuples specifying which remote's keyring should be used when doing GPG verification of each collection-ref. This is useful to prevent a @@ -9177,8 +9279,8 @@

    Ostr

  • - - + + @@ -9188,7 +9290,7 @@

    Ostr

    - + @@ -9210,11 +9312,9 @@

    Ostr

    Returns

    -

    TRUE -if data +

    TRUE if data has been signed successfully, -FALSE -in case of error (error +FALSE in case of error (error will contain the reason).

    Since: 2020.8

    @@ -9350,7 +9450,7 @@

    Ostr

    - + @@ -9605,6 +9705,72 @@

    Ostr
    +

    ostree_repo_regenerate_metadata ()

    +
    gboolean
    +ostree_repo_regenerate_metadata (OstreeRepo *self,
    +                                 GVariant *additional_metadata,
    +                                 GVariant *options,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Regenerate the OSTree repository metadata used by clients to describe +available branches and other metadata.

    +

    The repository metadata currently consists of the summary file. See +ostree_repo_regenerate_summary() and OSTREE_SUMMARY_GVARIANT_FORMAT for +additional details on its contents.

    +

    Additionally, if the core/collection-id key is set in the configuration, a +OSTREE_REPO_METADATA_REF commit will be created.

    +

    The following options + are currently defined:

    +
      +
    • gpg-key-ids (as): Array of GPG key IDs to sign the metadata with.

    • +
    • gpg-homedir (s): GPG home directory.

    • +
    • sign-keys (av): Array of keys to sign the metadata with. The key +type is specific to the sign engine used.

    • +
    • sign-type (s): Sign engine type to use. If not specified, +OSTREE_SIGN_NAME_ED25519 is used.

    • +
    +

    Locking: shared

    +
    +

    Parameters

    +

    start

    List commits starting with this checksum

    List commits starting with this checksum (empty string for all)

     

    out_deltas

    String name of deltas (checksum-checksum.delta).

    String name of deltas +(checksum-checksum.delta).

    [out][element-type utf8][transfer container]

    out_indexes

    String name of delta indexes (checksum).

    String name of delta indexes +(checksum).

    [out][element-type utf8][transfer container]

    out_reachable

    Set of reachable objects.

    Set of reachable +objects.

    [out][transfer container][element-type GVariant GVariant]

    refs_to_fetch

    Optional list of refs; if NULL, fetch all configured refs.

    Optional list of +refs; if NULL, fetch all configured refs.

    [array zero-terminated=1][element-type utf8][allow-none]

    refs_to_fetch

    Optional list of refs; if NULL, fetch all configured refs.

    Optional list of +refs; if NULL, fetch all configured refs.

    [array zero-terminated=1][element-type utf8][allow-none]

    old_signatures

    Existing signatures to append to (or NULL)

     

    Existing signatures to append to (or NULL).

    [nullable]

    key_id

    homedir

    GPG home directory, or NULL.

    [allow-none][nullable]

    out_signatures

    out_results

    Textual description of results.

    [nullable][out][transfer full][optional][out][transfer full]

    error

    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    additional_metadata

    A GVariant a{sv}, or NULL.

    [nullable]

    options

    A GVariant a{sv} with an extensible set of flags.

    [nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2023.1

    +
    +
    +

    ostree_repo_regenerate_summary ()

    gboolean
     ostree_repo_regenerate_summary (OstreeRepo *self,
    @@ -9685,14 +9851,16 @@ 

    Ostr

    OSTREE_REPO_MODE_BARE

    -

    Files are stored as themselves; checkouts are hardlinks; can only be written as root

    +

    Files are stored as themselves; checkouts are hardlinks; can only be +written as root

     

    OSTREE_REPO_MODE_ARCHIVE

    -

    Files are compressed, should be owned by non-root. Can be served via HTTP. Since: 2017.12

    +

    Files are compressed, should be owned by non-root. Can be served via +HTTP. Since: 2017.12

      @@ -9706,21 +9874,24 @@

    Ostr

    OSTREE_REPO_MODE_BARE_USER

    -

    Files are stored as themselves, except ownership; can be written by user. Hardlinks work only in user checkouts.

    +

    Files are stored as themselves, except ownership; can be written by +user. Hardlinks work only in user checkouts.

     

    OSTREE_REPO_MODE_BARE_USER_ONLY

    -

    Same as BARE_USER, but all metadata is not stored, so it can only be used for user checkouts. Does not need xattrs.

    +

    Same as BARE_USER, but all metadata is not stored, so it can +only be used for user checkouts. Does not need xattrs.

     

    OSTREE_REPO_MODE_BARE_SPLIT_XATTRS

    -

    Same as BARE_USER, but xattrs are stored separately from file content, with dedicated object types.

    +

    Same as BARE_USER, but xattrs are stored separately from +file content, with dedicated object types.

      @@ -9804,7 +9975,8 @@

    Ostr

    OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS

    -

    Delete a remote, do nothing if the remote does not exist

    +

    Delete a remote, do nothing if the remote does not +exist

      @@ -9830,7 +10002,7 @@

    Ostr guint64 content_bytes_written; guint devino_cache_hits; - guint padding1; + guint padding1; guint64 padding2; guint64 padding3; guint64 padding4; @@ -10063,9 +10235,10 @@

    Ostr

    enum OstreeRepoCommitModifierFlags

    -

    Flags modifying commit behavior. In bare-user-only mode, OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS - -and OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS +

    Flags modifying commit behavior. In bare-user-only mode, +OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS + and +OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS are automatically enabled.

    Members

    @@ -10107,21 +10280,32 @@

    Ostr

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_ERROR_ON_UNLABELED

    -

    Emit an error if configured SELinux policy does not provide a label

    +

    Emit an error if configured SELinux +policy does not provide a label

     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME

    -

    Delete added files/directories after commit; Since: 2017.13

    +

    Delete added files/directories after commit; Since: +2017.13

     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL

    -

    If a devino cache hit is found, skip modifier filters (non-directories only); Since: 2017.14

    +

    If a devino cache hit is found, skip +modifier filters (non-directories only); Since: 2017.14

    + +  + + +

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SELINUX_LABEL_V1

    + +

    For SELinux and other systems, label +/usr/etc as if it was /etc.

      @@ -10131,41 +10315,6 @@

    Ostr


    -

    OstreeRepoCheckoutAtOptions

    -
    typedef struct {
    -  OstreeRepoCheckoutMode mode;
    -  OstreeRepoCheckoutOverwriteMode overwrite_mode;
    -
    -  gboolean enable_uncompressed_cache;  /* Deprecated */
    -  gboolean enable_fsync;  /* Deprecated */
    -  gboolean process_whiteouts;
    -  gboolean no_copy_fallback;
    -  gboolean force_copy; /* Since: 2017.6 */
    -  gboolean bareuseronly_dirs; /* Since: 2017.7 */
    -  gboolean force_copy_zerosized; /* Since: 2018.9 */
    -  gboolean unused_bools[4];
    -  /* 4 byte hole on 64 bit */
    -
    -  const char *subpath;
    -
    -  OstreeRepoDevInoCache *devino_to_csum_cache;
    -
    -  int unused_ints[6];
    -  gpointer unused_ptrs[3];
    -  OstreeRepoCheckoutFilter filter; /* Since: 2018.2 */
    -  gpointer filter_user_data; /* Since: 2018.2 */
    -  OstreeSePolicy *sepolicy; /* Since: 2017.6 */
    -  const char *sepolicy_prefix;
    -} OstreeRepoCheckoutAtOptions;
    -
    -

    An extensible options structure controlling checkout. Ensure that -you have entirely zeroed the structure, then set just the desired -options. This is used by ostree_repo_checkout_at() which -supercedes previous separate enumeration usage in -ostree_repo_checkout_tree() and ostree_repo_checkout_tree_at().

    -
    -
    -

    enum OstreeRepoCheckoutMode

    Members

    @@ -10216,7 +10365,9 @@

    Ostr

    OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES

    -

    When layering checkouts, unlink() and replace existing files, but do not modify existing directories (unless whiteouts are enabled, then directories are replaced)

    +

    When layering checkouts, unlink() and replace +existing files, but do not modify existing directories (unless whiteouts are enabled, then +directories are replaced)

      @@ -10230,7 +10381,8 @@

    Ostr

    OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL

    -

    Like UNION_FILES, but error if files are not identical (requires hardlink checkouts)

    +

    Like UNION_FILES, but error if files are not +identical (requires hardlink checkouts)

      @@ -10343,7 +10495,8 @@

    Ostr

    OSTREE_REPO_COMMIT_TRAVERSE_FLAG_COMMIT_ONLY

    -

    Traverse and retrieve only commit objects. (Since: 2022.2)

    +

    Traverse and retrieve only commit objects. +(Since: 2022.2)

      @@ -10416,7 +10569,8 @@

    Ostr

    OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY

    -

    Do not traverse individual commit objects, only follow refs

    +

    Do not traverse individual commit objects, only follow refs +for reachability calculations

      @@ -10453,7 +10607,8 @@

    Ostr

    OSTREE_REPO_PULL_FLAGS_MIRROR

    -

    Write out refs suitable for mirrors and fetch all refs if none requested

    +

    Write out refs suitable for mirrors and fetch all refs if none +requested

      @@ -10467,21 +10622,24 @@

    Ostr

    OSTREE_REPO_PULL_FLAGS_UNTRUSTED

    -

    Do verify checksums of local (filesystem-accessible) repositories (defaults on for HTTP)

    +

    Do verify checksums of local (filesystem-accessible) +repositories (defaults on for HTTP)

     

    OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES

    -

    Since 2017.7. Reject writes of content objects with modes outside of 0775.

    +

    Since 2017.7. Reject writes of content objects with +modes outside of 0775.

     

    OSTREE_REPO_PULL_FLAGS_TRUSTED_HTTP

    -

    Don't verify checksums of objects HTTP repositories (Since: 2017.12)

    +

    Don't verify checksums of objects HTTP repositories +(Since: 2017.12)

      diff --git a/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html b/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html index 6dce720..b0229a4 100644 --- a/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html +++ b/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html @@ -201,6 +201,35 @@

    OstreeAsyncProgress * ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, gpointer user_data), gpointer user_data);

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    changed

    a notification callback

     

    user_data

    data to pass to changed +

     
    +
    +
    +

    Returns

    +

    A new progress object.

    +

    [transfer full]

    +

    diff --git a/apidoc/html/ostree-Root-partition-mount-point.html b/apidoc/html/ostree-Root-partition-mount-point.html index 9b44c0c..8461c18 100644 --- a/apidoc/html/ostree-Root-partition-mount-point.html +++ b/apidoc/html/ostree-Root-partition-mount-point.html @@ -65,6 +65,14 @@

    +gboolean + + +ostree_sysroot_initialize_with_mount_namespace () + + + + GFile * @@ -300,6 +308,14 @@

    gboolean +ostree_sysroot_deployment_set_kargs_in_place () + + + + +gboolean + + ostree_sysroot_deployment_set_mutable () @@ -521,6 +537,25 @@

    +

    ostree_sysroot_initialize_with_mount_namespace ()

    +
    gboolean
    +ostree_sysroot_initialize_with_mount_namespace
    +                               (OstreeSysroot *self,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Prepare the current process for modifying a booted sysroot, if applicable. +This function subsumes the functionality of ostree_sysroot_initialize +and may be invoked wherever that function is.

    +

    If the sysroot does not appear to be booted, or where the current process is not uid 0, +this function returns successfully.

    +

    Otherwise, if the process is in the same mount namespace as pid 1, create +a new namespace.

    +

    If you invoke this function, it must be before ostree_sysroot_load(); it may +be invoked before or after ostree_sysroot_initialize().

    +

    Since: 2022.7

    + +
    +

    ostree_sysroot_get_path ()

    GFile *
     ostree_sysroot_get_path (OstreeSysroot *self);
    @@ -1486,6 +1521,58 @@

    +

    ostree_sysroot_deployment_set_kargs_in_place ()

    +
    gboolean
    +ostree_sysroot_deployment_set_kargs_in_place
    +                               (OstreeSysroot *self,
    +                                OstreeDeployment *deployment,
    +                                char *kargs_str,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Replace the kernel arguments of deployment + with the values in kargs_str +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    A deployment

     

    kargs_str

    Replace deployment +'s kernel arguments.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    +
    +

    ostree_sysroot_deployment_set_mutable ()

    gboolean
     ostree_sysroot_deployment_set_mutable (OstreeSysroot *self,
    @@ -1843,7 +1930,8 @@ 

    override_kernel_argv

    -

    Use these as kernel arguments; if NULL, inherit options from provided_merge_deployment.

    +

    Use these as +kernel arguments; if NULL, inherit options from provided_merge_deployment.

    [
    allow-none][array zero-terminated=1][element-type utf8]
    @@ -2023,7 +2111,7 @@

    osname

    osname to use for merge deployment.

    -[
    allow-none]
    +[nullable]

    revision

    @@ -2033,17 +2121,18 @@

    origin

    Origin to use for upgrades.

    -[
    allow-none]
    +[nullable]

    provided_merge_deployment

    Use this deployment for merge path.

    -[allow-none] +[nullable]

    override_kernel_argv

    -

    Use these as kernel arguments; if NULL, inherit options from provided_merge_deployment.

    -[allow-none][array zero-terminated=1][element-type utf8] +

    Use these as +kernel arguments; if NULL, inherit options from provided_merge_deployment.

    +[nullable][array zero-terminated=1][element-type utf8]

    out_new_deployment

    @@ -2102,7 +2191,7 @@

    osname

    osname to use for merge deployment.

    -[
    allow-none]
    +[nullable]

    revision

    @@ -2112,22 +2201,22 @@

    origin

    Origin to use for upgrades.

    -[
    allow-none]
    +[nullable]

    provided_merge_deployment

    Use this deployment for merge path.

    -[allow-none] +[nullable]

    opts

    Options.

    -[allow-none] +[nullable]

    out_new_deployment

    The new deployment path.

    -[out] +[out][transfer full]

    cancellable

    diff --git a/apidoc/html/ostree-SELinux-policy-management.html b/apidoc/html/ostree-SELinux-policy-management.html index d3cd48b..116c2ac 100644 --- a/apidoc/html/ostree-SELinux-policy-management.html +++ b/apidoc/html/ostree-SELinux-policy-management.html @@ -303,7 +303,7 @@

    Returns

    Path to rootfs.

    -

    [transfer none]

    +

    [transfer none][nullable]


    @@ -360,7 +360,7 @@

    out_label

    Return location for security context.

    -[
    allow-none][out][transfer full]
    +[nullable][out][transfer full]

    cancellable

    @@ -384,7 +384,7 @@

    Returns

    Checksum of current policy.

    -

    [transfer none]

    +

    [transfer none][nullable]

    Since: 2016.5

    @@ -424,7 +424,7 @@

    info

    File attributes.

    -[
    allow-none]
    +[nullable]

    target

    @@ -439,7 +439,7 @@

    out_new_label

    New label, or NULL if unchanged.

    -[
    allow-none][out]
    +[nullable][optional][out]

    cancellable

    diff --git a/apidoc/html/ostree-Signature-management.html b/apidoc/html/ostree-Signature-management.html index 39be5e7..3ac4fce 100644 --- a/apidoc/html/ostree-Signature-management.html +++ b/apidoc/html/ostree-Signature-management.html @@ -291,7 +291,8 @@

    out_success_message

    -

    success message returned by the signing engine.

    +

    success message returned by the signing +engine.

    [
    out][nullable][optional]
    @@ -417,7 +418,8 @@

    out_success_message

    -

    success message returned by the signing engine.

    +

    success message returned by the signing +engine.

    [
    out][nullable][optional]
    diff --git a/apidoc/html/ostree-Simple-upgrade-class.html b/apidoc/html/ostree-Simple-upgrade-class.html index da3eee9..346ffd4 100644 --- a/apidoc/html/ostree-Simple-upgrade-class.html +++ b/apidoc/html/ostree-Simple-upgrade-class.html @@ -321,7 +321,7 @@

    Returns

    The origin file, or NULL if unknown.

    -

    [transfer none]

    +

    [transfer none][nullable]


    @@ -347,7 +347,7 @@

    Returns

    A copy of the origin file, or NULL if unknown.

    -

    [transfer full]

    +

    [transfer full][nullable]


    @@ -416,7 +416,9 @@

    Returns

    -

    A one-line descriptive summary of the origin, or NULL if unknown

    +

    A one-line descriptive summary of the origin, or NULL if +unknown.

    +

    [transfer full][nullable]


    @@ -668,7 +670,8 @@

    OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED

    -

    Do not error if the origin has an unconfigured-state key

    +

    Do not error if the origin has an +unconfigured-state key

      diff --git a/apidoc/html/ostree-ostree-bootconfig-parser.html b/apidoc/html/ostree-ostree-bootconfig-parser.html index d6c2e2b..9cda254 100644 --- a/apidoc/html/ostree-ostree-bootconfig-parser.html +++ b/apidoc/html/ostree-ostree-bootconfig-parser.html @@ -254,6 +254,36 @@

    OstreeBootconfigParser *self, const char *key, const char *value); +

    Set the key +/value + pair to the boot configuration dictionary.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Parser

     

    key

    the key

     

    value

    the key

     
    +

    @@ -261,6 +291,36 @@

    const char * ostree_bootconfig_parser_get (OstreeBootconfigParser *self, const char *key); +

    Get the value corresponding to key + from the boot configuration dictionary.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Parser

     

    key

    the key name to retrieve

     
    +
    +
    +

    Returns

    +

    The corresponding value, or NULL if the key hasn't been +found.

    +

    [nullable]

    +


    diff --git a/apidoc/html/ostree-ostree-deployment.html b/apidoc/html/ostree-ostree-deployment.html index 41cc9be..b77de84 100644 --- a/apidoc/html/ostree-ostree-deployment.html +++ b/apidoc/html/ostree-ostree-deployment.html @@ -425,7 +425,7 @@

    <

    Returns

    Boot configuration.

    -

    [transfer none]

    +

    [transfer none][nullable]


    @@ -451,7 +451,7 @@

    <

    Returns

    Origin.

    -

    [transfer none]

    +

    [transfer none][nullable]


    @@ -745,7 +745,7 @@

    <

    OstreeDeployment

    typedef struct {
    -  GObject       parent_instance;
    +  GObject parent_instance;
     
       int index;
       char *osname;
    diff --git a/apidoc/html/ostree-ostree-diff.html b/apidoc/html/ostree-ostree-diff.html
    index 627dff2..a6b3187 100644
    --- a/apidoc/html/ostree-ostree-diff.html
    +++ b/apidoc/html/ostree-ostree-diff.html
    @@ -348,7 +348,7 @@ 

    ost

    struct OstreeDiffItem

    struct OstreeDiffItem {
    -  gint refcount;  /* atomic */
    +  gint refcount; /* atomic */
     
       GFile *src;
       GFile *target;
    diff --git a/apidoc/html/ostree-ostree-kernel-args.html b/apidoc/html/ostree-ostree-kernel-args.html
    index f1e9322..1708a69 100644
    --- a/apidoc/html/ostree-ostree-kernel-args.html
    +++ b/apidoc/html/ostree-ostree-kernel-args.html
    @@ -113,6 +113,14 @@ 

    +void + + +ostree_kernel_args_append_if_missing () + + + + gboolean @@ -182,6 +190,22 @@

    ostree_kernel_args_to_string () + + +gboolean + + +ostree_kernel_args_contains () + + + + +gboolean + + +ostree_kernel_args_delete_if_present () + +

    @@ -425,8 +449,8 @@

    argv

    -

    an array of key=value argument pairs

    -  +

    an array of key=value argument pairs.

    +[
    array zero-terminated=1]
    @@ -460,13 +484,13 @@

    argv

    -

    an array of key=value argument pairs

    -  +

    an array of key=value argument pairs.

    +[
    array zero-terminated=1]

    prefixes

    -

    an array of prefix strings

    -  +

    an array of prefix strings.

    +[array zero-terminated=1] @@ -475,6 +499,40 @@


    +

    ostree_kernel_args_append_if_missing ()

    +
    void
    +ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs,
    +                                      const char *arg);
    +

    Appends arg + which is in the form of key=value pair to the hash table kargs->table +(appends to the value list if key is not in the hash table) +and appends key to kargs->order if it is not in the hash table.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair to be added

     
    +
    +

    Since: 2022.5

    +
    +
    +

    ostree_kernel_args_new_replace ()

    gboolean
     ostree_kernel_args_new_replace (OstreeKernelArgs *kargs,
    @@ -743,11 +801,12 @@ 

    Returns

    -

    NULL if key +

    NULL if key is not found in the kargs hash table, otherwise returns last element of value array corresponding to key -

    +.

    +

    [nullable]

    Since: 2019.3

    @@ -850,6 +909,87 @@

    Since: 2019.3

    +
    +
    +

    ostree_kernel_args_contains ()

    +
    gboolean
    +ostree_kernel_args_contains (OstreeKernelArgs *kargs,
    +                             const char *arg);
    +

    Search for arg + which is in the form of key=value pair at the hash table kargs->table +and returns true if finds it.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair to check

     
    +
    +
    +

    Returns

    +

    TRUE if arg +is contained in kargs +, FALSE otherwise.

    +
    +

    Since: 2022.7

    +
    +
    +
    +

    ostree_kernel_args_delete_if_present ()

    +
    gboolean
    +ostree_kernel_args_delete_if_present (OstreeKernelArgs *kargs,
    +                                      const char *arg,
    +                                      GError **error);
    +

    Deletes arg + which is in the form of key=value pair from the hash table kargs->table.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair to be deleted

     

    error

    an GError instance

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +

    Since: 2022.7

    +

    Types and Values

    diff --git a/apidoc/html/ostree-ostree-ref.html b/apidoc/html/ostree-ostree-ref.html index 4c15cdf..9000327 100644 --- a/apidoc/html/ostree-ostree-ref.html +++ b/apidoc/html/ostree-ostree-ref.html @@ -153,7 +153,7 @@

    ostr

    Returns

    a new OstreeCollectionRef.

    -

    [transfer full][nullable]

    +

    [transfer full]

    Since: 2018.6

    @@ -231,7 +231,7 @@

    ostr

    ref

    an OstreeCollectionRef.

    -[not nullable] +[not nullable][type OstreeCollectionRef] @@ -266,12 +266,12 @@

    ostr

    ref1

    an OstreeCollectionRef.

    -[not nullable] +[not nullable][type OstreeCollectionRef]

    ref2

    another OstreeCollectionRef.

    -[not nullable] +[not nullable][type OstreeCollectionRef] @@ -288,7 +288,7 @@

    ostr

    ostree_collection_ref_dupv ()

    OstreeCollectionRef **
    -ostree_collection_ref_dupv (const OstreeCollectionRef * const *refs);
    +ostree_collection_ref_dupv (const OstreeCollectionRef *const *refs);

    Copy an array of OstreeCollectionRefs, including deep copies of all its elements. refs must be NULL-terminated; it may be empty, but must not be @@ -347,7 +347,7 @@

    ostr

    Types and Values

    OstreeCollectionRefv

    -
    typedef OstreeCollectionRef** OstreeCollectionRefv;
    +
    typedef OstreeCollectionRef **OstreeCollectionRefv;
     

    A NULL-terminated array of OstreeCollectionRef instances, designed to be used with g_auto():

    @@ -356,7 +356,7 @@

    ostr
    1
    -
    g_auto(OstreeCollectionRefv) refs = NULL;
    +
    g_auto(OstreeCollectionRefv) refs = NULL;
    diff --git a/apidoc/html/ostree-ostree-remote.html b/apidoc/html/ostree-ostree-remote.html index 01e83fb..5cfd768 100644 --- a/apidoc/html/ostree-ostree-remote.html +++ b/apidoc/html/ostree-ostree-remote.html @@ -198,7 +198,7 @@

    o

    Returns

    the remote's URL.

    -

    [transfer full]

    +

    [transfer full][nullable]

    Since: 2018.6

    @@ -208,12 +208,12 @@

    o

    struct OstreeRemote

    struct OstreeRemote {
    -  int ref_count;  /* atomic */
    -  char *name;  /* (not nullable) */
    -  char *refspec_name;  /* (nullable) */
    -  char *group;   /* group name in options (not nullable) */
    -  char *keyring; /* keyring name ($refspec_name.trustedkeys.gpg) (not nullable) */
    -  GFile *file;   /* NULL if remote defined in repo/config */
    +  int ref_count;      /* atomic */
    +  char *name;         /* (not nullable) */
    +  char *refspec_name; /* (nullable) */
    +  char *group;        /* group name in options (not nullable) */
    +  char *keyring;      /* keyring name ($refspec_name.trustedkeys.gpg) (not nullable) */
    +  GFile *file;        /* NULL if remote defined in repo/config */
       GKeyFile *options;
     };
     
    diff --git a/apidoc/html/ostree-ostree-repo-file.html b/apidoc/html/ostree-ostree-repo-file.html index ff2bcf3..365900f 100644 --- a/apidoc/html/ostree-ostree-repo-file.html +++ b/apidoc/html/ostree-ostree-repo-file.html @@ -158,6 +158,33 @@

    gboolean ostree_repo_file_ensure_resolved (OstreeRepoFile *self, GError **error); +

    Ensure that the backing metadata is loaded.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    A repo file

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    FALSE if the operation failed, TRUE otherwise

    +


    @@ -229,6 +256,22 @@

    OstreeRepoFile *self, const char *checksum, GVariant *metadata); +

    Replace the metadata checksum and metadata object.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +


    @@ -236,6 +279,27 @@

    const char * ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile *self); +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The SHA256 digest of the content object, or NULL if this is not a +directory.

    +

    [nullable]

    +


    @@ -243,18 +307,83 @@

    const char * ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self); +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The SHA256 digest of the metadata object, or NULL if this is not a +directory.

    +

    [nullable]

    +


    ostree_repo_file_tree_get_contents ()

    GVariant *
     ostree_repo_file_tree_get_contents (OstreeRepoFile *self);
    +

    This API will return NULL if the file is not "resolved" i.e. in a loaded +state. It will also return NULL if this path is not a directory tree.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The GVariant representing the children of this directory.

    +

    [nullable]

    +

    ostree_repo_file_tree_get_metadata ()

    GVariant *
     ostree_repo_file_tree_get_metadata (OstreeRepoFile *self);
    +

    This API will return NULL if the file is not "resolved" i.e. in a loaded +state. It will also return NULL if this path is not a directory tree.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The GVariant representing the metadata for this directory.

    +

    [nullable]

    +

    @@ -329,23 +458,43 @@

      +

    n

    +

    the child number

    +  + + +

    attributes

    +

    an attribute string to match, see g_file_attribute_matcher_new()

    +  + + +

    flags

    +

    a GFileQueryInfoFlags

    +  + +

    out_info

    -

    .

    -[
    out]
    +

    the GFileInfo of the child.

    +[out][transfer full][optional]

    cancellable

    -

    Cancellable

    +

    a GCancellable or NULL

     

    error

    -

    Error

    +

    a GError or NULL

     

    +
    +

    Returns

    +

    TRUE on success and the out_info +is set, FALSE otherwise.

    +
    diff --git a/apidoc/html/ostree-ostree-repo-finder.html b/apidoc/html/ostree-ostree-repo-finder.html index 53c12d6..337e70b 100644 --- a/apidoc/html/ostree-ostree-repo-finder.html +++ b/apidoc/html/ostree-ostree-repo-finder.html @@ -142,7 +142,7 @@

    ostree_repo_finder_resolve_async ()

    void
     ostree_repo_finder_resolve_async (OstreeRepoFinder *self,
    -                                  const OstreeCollectionRef * const *refs,
    +                                  const OstreeCollectionRef *const *refs,
                                       OstreeRepo *parent_repo,
                                       GCancellable *cancellable,
                                       GAsyncReadyCallback callback,
    @@ -264,8 +264,8 @@ 

    ostree_repo_finder_resolve_all_async ()

    void
    -ostree_repo_finder_resolve_all_async (OstreeRepoFinder * const *finders,
    -                                      const OstreeCollectionRef * const *refs,
    +ostree_repo_finder_resolve_all_async (OstreeRepoFinder *const *finders,
    +                                      const OstreeCollectionRef *const *refs,
                                           OstreeRepo *parent_repo,
                                           GCancellable *cancellable,
                                           GAsyncReadyCallback callback,
    @@ -551,7 +551,7 @@ 


    OstreeRepoFinderResultv

    -
    typedef OstreeRepoFinderResult** OstreeRepoFinderResultv;
    +
    typedef OstreeRepoFinderResult **OstreeRepoFinderResultv;
     

    A NULL-terminated array of OstreeRepoFinderResult instances, designed to be used with g_auto():

    @@ -560,7 +560,7 @@

    1
    -
    g_auto(OstreeRepoFinderResultv) results = NULL;
    +
    g_auto(OstreeRepoFinderResultv) results = NULL;
    diff --git a/apidoc/html/ostree-ostree-repo-remote-finder.html b/apidoc/html/ostree-ostree-repo-remote-finder.html index 006ba4d..74533e4 100644 --- a/apidoc/html/ostree-ostree-repo-remote-finder.html +++ b/apidoc/html/ostree-ostree-repo-remote-finder.html @@ -110,7 +110,7 @@

    ostree_repo_find_remotes_async ()

    void
     ostree_repo_find_remotes_async (OstreeRepo *self,
    -                                const OstreeCollectionRef * const *refs,
    +                                const OstreeCollectionRef *const *refs,
                                     GVariant *options,
                                     OstreeRepoFinder **finders,
                                     OstreeAsyncProgress *progress,
    @@ -266,7 +266,7 @@ 

    ostree_repo_pull_from_remotes_async ()

    void
     ostree_repo_pull_from_remotes_async (OstreeRepo *self,
    -                                     const OstreeRepoFinderResult * const *results,
    +                                     const OstreeRepoFinderResult *const *results,
                                          GVariant *options,
                                          OstreeAsyncProgress *progress,
                                          GCancellable *cancellable,
    diff --git a/apidoc/html/ostree-ostree-version.html b/apidoc/html/ostree-ostree-version.html
    index 4eb3e34..e5d04d1 100644
    --- a/apidoc/html/ostree-ostree-version.html
    +++ b/apidoc/html/ostree-ostree-version.html
    @@ -117,7 +117,7 @@ 

    Types and Values

    OSTREE_YEAR_VERSION

    -
    #define OSTREE_YEAR_VERSION (2022)
    +
    #define OSTREE_YEAR_VERSION (2023)
     

    ostree year version component (e.g. 2017 if OSTREE_VERSION is 2017.2)

    Since: 2017.4

    @@ -125,7 +125,7 @@


    OSTREE_RELEASE_VERSION

    -
    #define OSTREE_RELEASE_VERSION (4)
    +
    #define OSTREE_RELEASE_VERSION (7)
     

    ostree release version component (e.g. 2 if OSTREE_VERSION is 2017.2)

    Since: 2017.4

    @@ -133,7 +133,7 @@


    OSTREE_VERSION

    -
    #define OSTREE_VERSION (2022.4)
    +
    #define OSTREE_VERSION (2023.7)
     

    ostree version.

    Since: 2017.4

    @@ -141,7 +141,7 @@


    OSTREE_VERSION_S

    -
    #define OSTREE_VERSION_S "2022.4"
    +
    #define OSTREE_VERSION_S "2023.7"
     

    ostree version, encoded as a string, useful for printing and concatenation.

    diff --git a/apidoc/html/ostree.devhelp2 b/apidoc/html/ostree.devhelp2 index 6e4d705..d905114 100644 --- a/apidoc/html/ostree.devhelp2 +++ b/apidoc/html/ostree.devhelp2 @@ -100,7 +100,6 @@ - @@ -215,6 +214,7 @@ + @@ -262,6 +262,7 @@ + @@ -275,7 +276,6 @@ - @@ -306,6 +306,7 @@ + @@ -335,6 +336,7 @@ + @@ -476,6 +478,7 @@ + @@ -485,6 +488,8 @@ + + @@ -576,6 +581,7 @@ + @@ -643,10 +649,6 @@ - - - - diff --git a/apidoc/html/reference.html b/apidoc/html/reference.html index 35684ee..27b6865 100644 --- a/apidoc/html/reference.html +++ b/apidoc/html/reference.html @@ -334,10 +334,6 @@
    -OstreeCommitSizesEntry, struct in Core repository-independent functions -
    -
    -
    ostree_commit_get_content_checksum, function in Core repository-independent functions
    @@ -615,6 +611,10 @@
    +ostree_kernel_args_append_if_missing, function in ostree-kernel-args +
    +
    +
    ostree_kernel_args_append_proc_cmdline, function in ostree-kernel-args
    @@ -623,10 +623,18 @@
    +ostree_kernel_args_contains, function in ostree-kernel-args +
    +
    +
    ostree_kernel_args_delete, function in ostree-kernel-args
    +ostree_kernel_args_delete_if_present, function in ostree-kernel-args +
    +
    +
    ostree_kernel_args_delete_key_entry, function in ostree-kernel-args
    @@ -851,10 +859,6 @@
    -OstreeRepoCheckoutAtOptions, struct in OstreeRepo -
    -
    -
    OstreeRepoCheckoutMode, enum in OstreeRepo
    @@ -999,6 +1003,10 @@
    +ostree_repo_commit_add_composefs_metadata, function in OstreeRepo +
    +
    +
    ostree_repo_commit_modifier_new, function in OstreeRepo
    @@ -1147,6 +1155,34 @@
    +ostree_repo_finder_avahi_new, function in OstreeRepoFinderAvahi +
    +
    +
    +ostree_repo_finder_avahi_start, function in OstreeRepoFinderAvahi +
    +
    +
    +ostree_repo_finder_avahi_stop, function in OstreeRepoFinderAvahi +
    +
    +
    +ostree_repo_finder_config_new, function in OstreeRepoFinderConfig +
    +
    +
    +ostree_repo_finder_mount_new, function in OstreeRepoFinderMount +
    +
    +
    +ostree_repo_finder_override_add_uri, function in OstreeRepoFinderOverride +
    +
    +
    +ostree_repo_finder_override_new, function in OstreeRepoFinderOverride +
    +
    +
    ostree_repo_finder_resolve_all_async, function in ostree-repo-finder
    @@ -1431,6 +1467,10 @@
    +ostree_repo_regenerate_metadata, function in OstreeRepo +
    +
    +
    ostree_repo_regenerate_summary, function in OstreeRepo
    @@ -1868,6 +1908,10 @@
    +ostree_sysroot_deployment_set_kargs_in_place, function in Root partition mount point +
    +
    +
    ostree_sysroot_deployment_set_mutable, function in Root partition mount point
    @@ -1944,6 +1988,10 @@
    +ostree_sysroot_initialize_with_mount_namespace, function in Root partition mount point +
    +
    +
    ostree_sysroot_init_osname, function in Root partition mount point
    diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index adf5255..af57d7c 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -426,6 +426,7 @@ ostree_repo_write_commit ostree_repo_write_commit_with_time ostree_repo_read_commit_detached_metadata ostree_repo_write_commit_detached_metadata +ostree_repo_commit_add_composefs_metadata OstreeRepoCheckoutAtOptions ostree_repo_checkout_at_options_set_devino OstreeRepoCheckoutMode @@ -483,6 +484,7 @@ ostree_repo_verify_commit ostree_repo_verify_commit_ext ostree_repo_verify_commit_for_remote ostree_repo_verify_summary +ostree_repo_regenerate_metadata ostree_repo_regenerate_summary OSTREE_REPO @@ -548,6 +550,7 @@ OstreeSysroot ostree_sysroot_new ostree_sysroot_new_default ostree_sysroot_initialize +ostree_sysroot_initialize_with_mount_namespace ostree_sysroot_get_path ostree_sysroot_load ostree_sysroot_load_if_changed @@ -577,6 +580,7 @@ ostree_sysroot_get_repo ostree_sysroot_get_staged_deployment ostree_sysroot_init_osname ostree_sysroot_deployment_set_kargs +ostree_sysroot_deployment_set_kargs_in_place ostree_sysroot_deployment_set_mutable ostree_sysroot_deployment_unlock ostree_sysroot_deployment_set_pinned @@ -727,6 +731,7 @@ ostree_kernel_args_replace_argv ostree_kernel_args_append ostree_kernel_args_append_argv ostree_kernel_args_append_argv_filtered +ostree_kernel_args_append_if_missing ostree_kernel_args_new_replace ostree_kernel_args_delete ostree_kernel_args_delete_key_entry @@ -736,6 +741,8 @@ ostree_kernel_args_get_last_value ostree_kernel_args_from_string ostree_kernel_args_to_strv ostree_kernel_args_to_string +ostree_kernel_args_contains +ostree_kernel_args_delete_if_present
    diff --git a/apidoc/version.xml b/apidoc/version.xml index 9ea7918..e7b67ba 100644 --- a/apidoc/version.xml +++ b/apidoc/version.xml @@ -1 +1 @@ -2022.4 \ No newline at end of file +2023.6 \ No newline at end of file diff --git a/autogen.sh b/autogen.sh index 689bba8..ea2412c 100755 --- a/autogen.sh +++ b/autogen.sh @@ -35,6 +35,7 @@ fi # changing this, please also change Makefile.am. sed -e 's,$(libglnx_srcpath),libglnx,g' < libglnx/Makefile-libglnx.am >libglnx/Makefile-libglnx.am.inc sed -e 's,$(libbsdiff_srcpath),bsdiff,g' < bsdiff/Makefile-bsdiff.am >bsdiff/Makefile-bsdiff.am.inc +sed -e 's,$(COMPOSEFSDIR),composefs/libcomposefs,g' < composefs/libcomposefs/Makefile-lib.am >composefs/libcomposefs/Makefile-lib.am.inc # FIXME - figure out how to get aclocal to find this by default ln -sf ../libglnx/libglnx.m4 buildutil/libglnx.m4 diff --git a/bash/ostree b/bash/ostree index 4636331..875b34f 100644 --- a/bash/ostree +++ b/bash/ostree @@ -249,6 +249,7 @@ _ostree_checkout() { --union-identical --user-mode -U --whiteouts + --process-passthrough-whiteouts " local options_with_args=" @@ -899,7 +900,6 @@ _ostree_pull() { local boolean_options=" $main_boolean_options --commit-metadata-only - --cache-dir --disable-fsync --disable-static-deltas --require-static-deltas @@ -911,6 +911,7 @@ _ostree_pull() { " local options_with_args=" + --cache-dir --depth --http-header --localcache-repo -L @@ -924,7 +925,7 @@ _ostree_pull() { local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) case "$prev" in - --localcache-repo|-L|--repo|--subpath) + --cache-dir|--localcache-repo|-L|--repo|--subpath) __ostree_compreply_dirs_only return 0 ;; @@ -952,6 +953,7 @@ _ostree_pull() { _ostree_refs() { local boolean_options=" $main_boolean_options + --revision -r --alias -A --collections -c --delete @@ -1273,17 +1275,18 @@ _ostree_remote_list_gpg_keys() { _ostree_remote_refs() { local boolean_options=" $main_boolean_options - --cache-dir + --revision -r " local options_with_args=" + --cache-dir --repo " local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) case "$prev" in - --repo) + --cache-dir|--repo) __ostree_compreply_dirs_only return 0 ;; @@ -1342,18 +1345,20 @@ _ostree_remote_show_url() { _ostree_remote_summary() { local boolean_options=" $main_boolean_options - --cache-dir + --list-metadata-keys --raw " local options_with_args=" + --cache-dir + --print-metadata-key --repo " local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) case "$prev" in - --repo) + --cache-dir|--repo) __ostree_compreply_dirs_only return 0 ;; @@ -1483,6 +1488,8 @@ _ostree_rev_parse() { _ostree_show() { local boolean_options=" $main_boolean_options + --list-detached-metadata-keys + --list-metadata-keys --print-related --print-sizes --raw @@ -1811,6 +1818,7 @@ _ostree_static_delta() { _ostree_summary() { local boolean_options=" $main_boolean_options + --list-metadata-keys --raw --update -u --view -v @@ -1820,6 +1828,7 @@ _ostree_summary() { --add-metadata -m --gpg-homedir --gpg-sign + --print-metadata-key --repo " diff --git a/build-aux/config.guess b/build-aux/config.guess index 7ea49fa..c7f17e8 100755 --- a/build-aux/config.guess +++ b/build-aux/config.guess @@ -1,12 +1,14 @@ #!/usr/bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2022 Free Software Foundation, Inc. -timestamp='2016-10-02' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-05-25' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -15,7 +17,7 @@ timestamp='2016-10-02' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,11 +29,19 @@ timestamp='2016-10-02' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + me=`echo "$0" | sed -e 's,.*/,,'` usage="\ @@ -39,7 +49,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +60,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,7 +94,8 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 +# Just in case it came from the environment. +GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires @@ -96,66 +107,90 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case $UNAME_SYSTEM in Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu + LIBC=unknown - eval $set_cc_for_build - cat <<-EOF > $dummy.c + set_cc_for_build + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc - #else + #elif defined(__GLIBC__) LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -167,32 +202,32 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "${UNAME_MACHINE_ARCH}" in + case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -208,10 +243,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -219,47 +254,68 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case $UNAME_VERSION in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" - exit ;; + GUESS=$machine-${os}${release}${abi-} + ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-unknown-sortix - exit ;; + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` @@ -273,7 +329,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in + case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") @@ -310,126 +366,121 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; + GUESS=m68k-unknown-sysv4 + ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; + GUESS=$UNAME_MACHINE-unknown-morphos + ;; *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; + GUESS=i370-ibm-openedition + ;; *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; + GUESS=s390-ibm-zvmoe + ;; *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; + GUESS=powerpc-ibm-os400 + ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; + GUESS=arm-unknown-riscos + ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; + GUESS=hppa1.1-hitachi-hiuxmpp + ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; + GUESS=pyramid-pyramid-svr4 + ;; DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; + GUESS=sparc-icl-nx6 + ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 - case "`/bin/arch`" in + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac - exit ;; + ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -439,44 +490,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; + GUESS=mips-dec-mach_bsd4.3 + ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -485,95 +536,96 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; + GUESS=powerpc-motorola-powermax + ;; Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; + GUESS=powerpc-harris-powerunix + ;; m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; + GUESS=m88k-harris-cxux7 + ;; m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; + GUESS=m88k-motorola-sysv4 + ;; m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then - echo m88k-dg-dgux${UNAME_RELEASE} + GUESS=m88k-dg-dgux$UNAME_RELEASE else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else - echo i586-dg-dgux${UNAME_RELEASE} + GUESS=i586-dg-dgux$UNAME_RELEASE fi - exit ;; + ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; + GUESS=m88k-dolphin-sysv3 + ;; M88*:*:R3*:*) # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; + GUESS=m88k-tektronix-sysv3 + ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; + GUESS=m68k-tektronix-bsd + ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; + GUESS=i386-ibm-aix + ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then + if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -584,77 +636,77 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then - echo "$SYSTEM_NAME" + GUESS=$SYSTEM_NAME else - echo rs6000-ibm-aix3.2.5 + GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 + GUESS=rs6000-ibm-aix3.2.4 else - echo rs6000-ibm-aix3.2 + GUESS=rs6000-ibm-aix3.2 fi - exit ;; + ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; + GUESS=rs6000-bull-bosx + ;; DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; + GUESS=m68k-bull-sysv3 + ;; 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; + GUESS=m68k-hp-bsd + ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; + GUESS=m68k-hp-bsd4.4 + ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then + if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in + case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in + case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -687,13 +739,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = hppa2.0w ] + if test "$HP_ARCH" = hppa2.0w then - eval $set_cc_for_build + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -712,15 +764,15 @@ EOF HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -745,38 +797,38 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; + GUESS=hppa1.0-hp-bsd + ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; + GUESS=hppa1.0-hp-osf + ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + GUESS=$UNAME_MACHINE-unknown-osf1 fi - exit ;; + ;; parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; + GUESS=hppa1.1-hp-lites + ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; + GUESS=c1-convex-bsd + ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd @@ -784,139 +836,148 @@ EOF fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; + GUESS=c34-convex-bsd + ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; + GUESS=c38-convex-bsd + ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; + GUESS=c4-convex-bsd + ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case $UNAME_PROCESSOR in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac - exit ;; + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; + GUESS=$UNAME_MACHINE-pc-cygwin + ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-msys + ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case $UNAME_MACHINE in x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; + GUESS=i586-pc-interix$UNAME_RELEASE + ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; + GUESS=$UNAME_MACHINE-pc-uwin + ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; + GUESS=x86_64-pc-cygwin + ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -927,183 +988,236 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; arm*:Linux:*:*) - eval $set_cc_for_build + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi - exit ;; + ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; k1om:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} - exit ;; + GUESS=or1k-unknown-linux-$LIBC + ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} - exit ;; + GUESS=sparc-unknown-linux-$LIBC + ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} - exit ;; + GUESS=hppa64-unknown-linux-$LIBC + ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; esac - exit ;; + ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc64-unknown-linux-$LIBC + ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc-unknown-linux-$LIBC + ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc64le-unknown-linux-$LIBC + ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} - exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac + fi + GUESS=$CPU-pc-linux-$LIBCABI + ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; + GUESS=i386-sequent-sysv4 + ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; + GUESS=$UNAME_MACHINE-unknown-stop + ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; + GUESS=$UNAME_MACHINE-unknown-atheos + ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; + GUESS=$UNAME_MACHINE-pc-syllable + ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi - exit ;; + ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in @@ -1111,12 +1225,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1126,11 +1240,11 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else - echo ${UNAME_MACHINE}-pc-sysv32 + GUESS=$UNAME_MACHINE-pc-sysv32 fi - exit ;; + ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about @@ -1138,31 +1252,31 @@ EOF # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; + GUESS=i586-pc-msdosdjgpp + ;; Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; + GUESS=i386-pc-mach3 + ;; paragon:*:*:*) - echo i860-intel-osf1 - exit ;; + GUESS=i860-intel-osf1 + ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi - exit ;; + ;; mini*:CTIX:SYS*5:*) # "miniframe" - echo m68010-convergent-sysv - exit ;; + GUESS=m68010-convergent-sysv + ;; mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; + GUESS=m68k-convergent-sysv + ;; M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; + GUESS=m68k-diab-dnix + ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) @@ -1170,9 +1284,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1181,249 +1295,440 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; + GUESS=m68k-atari-sysv4 + ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + GUESS=$UNAME_MACHINE-sni-sysv4 else - echo ns32k-sni-sysv + GUESS=ns32k-sni-sysv fi - exit ;; + ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says - echo i586-unisys-sysv4 - exit ;; + GUESS=i586-unisys-sysv4 + ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; + GUESS=hppa1.1-stratus-sysv4 + ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; + GUESS=i860-stratus-sysv4 + ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; + GUESS=$UNAME_MACHINE-stratus-vos + ;; *:VOS:*:*) # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; + GUESS=hppa1.1-stratus-vos + ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; + GUESS=mips-sony-newsos6 + ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE else - echo mips-unknown-sysv${UNAME_RELEASE} + GUESS=mips-unknown-sysv$UNAME_RELEASE fi - exit ;; + ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; + GUESS=powerpc-be-beos + ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; + GUESS=powerpc-apple-beos + ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; + GUESS=i586-pc-beos + ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; + GUESS=i586-pc-haiku + ;; + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku + ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; + GUESS=mips-compaq-nonstopux + ;; BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; + GUESS=bs2000-siemens-sysv + ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = 386; then + if test "${cputype-}" = 386; then UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; + GUESS=pdp10-unknown-tops10 + ;; *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; + GUESS=pdp10-unknown-tenex + ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; + GUESS=pdp10-dec-tops20 + ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; + GUESS=pdp10-xkl-tops20 + ;; *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; + GUESS=pdp10-unknown-tops20 + ;; *:ITS:*:*) - echo pdp10-unknown-its - exit ;; + GUESS=pdp10-unknown-its + ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; + GUESS=i386-pc-xenix + ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` - exit ;; + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; + GUESS=$UNAME_MACHINE-unknown-esx + ;; amd64:Isilon\ OneFS:*:*) - echo x86_64-unknown-onefs - exit ;; + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/build-aux/config.sub b/build-aux/config.sub index ba15a57..b41da55 100755 --- a/build-aux/config.sub +++ b/build-aux/config.sub @@ -1,12 +1,14 @@ #!/usr/bin/sh # Configuration validation subroutine script. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2022 Free Software Foundation, Inc. -timestamp='2016-09-05' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -15,7 +17,7 @@ timestamp='2016-09-05' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +35,7 @@ timestamp='2016-09-05' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -50,6 +52,13 @@ timestamp='2016-09-05' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + me=`echo "$0" | sed -e 's,.*/,,'` usage="\ @@ -57,7 +66,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +76,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -89,12 +98,12 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -110,1242 +119,1186 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | cloudabi*-eabi* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -psos*) - os=-psos + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | ba \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - leon|leon[3-9]) - basic_machine=sparc-$basic_machine - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + op50n) + cpu=hppa1.1 + vendor=oki ;; - ms1) - basic_machine=mt-unknown + op60c) + cpu=hppa1.1 + vendor=oki ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown + ibm*) + cpu=i370 + vendor=ibm ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none + orion105) + cpu=clipper + vendor=highlevel ;; - xscaleeb) - basic_machine=armeb-unknown + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; - - xscaleel) - basic_machine=armel-unknown + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | ba-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | e2k-* | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | riscv32-* | riscv64-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - asmjs) - basic_machine=asmjs-unknown - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=we32k + vendor=att ;; bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + cpu=powerpc + vendor=ibm + basic_os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + basic_os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos + cpu=m68k + vendor=motorola ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - e500v[12]) - basic_machine=powerpc-unknown - os=$os"spe" - ;; - e500v[12]-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - os=$os"spe" - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k3[2-9][0-9]) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm + cpu=hppa1.0 + vendor=hp ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) + cpu=mips + vendor=sgi + case $basic_os in + irix*) ;; *) - os=-irix4 + basic_os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl + cpu=m68000 + vendor=convergent ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + basic_os=nextstep2 ;; *) - os=-nextstep3 + basic_os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + basic_os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc + cpu=m68k + vendor=tti ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown + cpu=pn + vendor=gould ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + power) + cpu=power + vendor=ibm ;; ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + cpu=i386 + vendor=ibm ;; rm[46]00) - basic_machine=mips-siemens + cpu=mips + vendor=siemens ;; rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm + cpu=romp + vendor=ibm ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} ;; - sb1) - basic_machine=mipsisa64sb1-unknown + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown + tower | tower-32) + cpu=m68k + vendor=ncr ;; - sde) - basic_machine=mipsisa32-sde - os=-elf + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - sei) - basic_machine=mips-sei - os=-seiux + w65) + cpu=w65 + vendor=wdc ;; - sequent) - basic_machine=i386-sequent + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf ;; - sh) - basic_machine=sh-hitachi - os=-hms + none) + cpu=none + vendor=none ;; - sh5el) - basic_machine=sh5le-unknown + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine ;; - sh64) - basic_machine=sh64-unknown + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb | arc32 | arc64 \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r3 | mipsisa32r3el \ + | mipsisa32r5 | mipsisa32r5el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r3 | mipsisa64r3el \ + | mipsisa64r5 | mipsisa64r5el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | thumbv7* \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1353,203 +1306,215 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if test x$basic_os != x then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1562,261 +1527,363 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; - *-be) - os=-beos + pru-*) + os=elf ;; - *-haiku) - os=-haiku + *-be) + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; - *-next ) - os=-nextstep + *-next) + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + musl* | newlib* | relibc* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ + | fiwix* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ + | linux-musl* | linux-relibc* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - -beos*) + *-beos*) vendor=be ;; - -hpux*) + *-hpux*) vendor=hp ;; - -mpeix*) + *-mpeix*) vendor=hp ;; - -hiux*) + *-hiux*) vendor=hitachi ;; - -unos*) + *-unos*) vendor=crds ;; - -dgux*) + *-dgux*) vendor=dg ;; - -luna*) + *-luna*) vendor=omron ;; - -genix*) + *-genix*) vendor=ns ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - -os400*) + s390-* | s390x-*) vendor=ibm ;; - -ptx*) + *-ptx*) vendor=sequent ;; - -tpf*) + *-tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - -aux*) + *-aux*) vendor=apple ;; - -hms*) + *-hms*) vendor=hitachi ;; - -mpw* | -macos*) + *-mpw* | *-macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - -vos*) + *-vos*) vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh index 8dab662..49fcad1 100644 --- a/build-aux/ltmain.sh +++ b/build-aux/ltmain.sh @@ -1,12 +1,12 @@ -#! /bin/sh +#! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in -## by inline-source v2014-01-03.01 +## by inline-source v2019-02-19.15 -# libtool (GNU libtool) 2.4.6 +# libtool (GNU libtool) 2.4.7 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -31,8 +31,8 @@ PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.6 -package_revision=2.4.6 +VERSION=2.4.7 +package_revision=2.4.7 ## ------ ## @@ -64,34 +64,25 @@ package_revision=2.4.6 # libraries, which are installed to $pkgauxdir. # Set a version string for this script. -scriptversion=2015-01-20.17; # UTC +scriptversion=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 -# Copyright (C) 2004-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. - -# As a special exception to the GNU General Public License, if you distribute -# this file as part of a program or library that is built using GNU Libtool, -# you may include this file under the same distribution terms that you use -# for the rest of that program. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2004-2019, 2021 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# Please report bugs or propose patches to gary@gnu.org. +# Please report bugs or propose patches to: +# ## ------ ## @@ -139,9 +130,12 @@ do _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# These NLS vars are set unconditionally (bootstrap issue #24). Unset those +# in case the environment reset is needed later and the $save_* variant is not +# defined (see the code above). +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' @@ -159,6 +153,26 @@ if test "${PATH_SEPARATOR+set}" != set; then fi +# func_unset VAR +# -------------- +# Portably unset VAR. +# In some shells, an 'unset VAR' statement leaves a non-zero return +# status if VAR is already unset, which might be problematic if the +# statement is used at the end of a function (thus poisoning its return +# value) or when 'set -e' is active (causing even a spurious abort of +# the script in this case). +func_unset () +{ + { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } +} + + +# Make sure CDPATH doesn't cause `cd` commands to output the target dir. +func_unset CDPATH + +# Make sure ${,E,F}GREP behave sanely. +func_unset GREP_OPTIONS + ## ------------------------- ## ## Locate command utilities. ## @@ -259,7 +273,7 @@ test -z "$SED" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } @@ -295,7 +309,7 @@ test -z "$GREP" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } @@ -360,6 +374,35 @@ sed_double_backslash="\ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" +# require_check_ifs_backslash +# --------------------------- +# Check if we can use backslash as IFS='\' separator, and set +# $check_ifs_backshlash_broken to ':' or 'false'. +require_check_ifs_backslash=func_require_check_ifs_backslash +func_require_check_ifs_backslash () +{ + _G_save_IFS=$IFS + IFS='\' + _G_check_ifs_backshlash='a\\b' + for _G_i in $_G_check_ifs_backshlash + do + case $_G_i in + a) + check_ifs_backshlash_broken=false + ;; + '') + break + ;; + *) + check_ifs_backshlash_broken=: + break + ;; + esac + done + IFS=$_G_save_IFS + require_check_ifs_backslash=: +} + ## ----------------- ## ## Global variables. ## @@ -580,16 +623,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then { $debug_cmd - func_quote_for_eval "$2" - eval "$1+=\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd - func_quote_for_eval "$2" - eval "$1=\$$1\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1=\$$1\\ \$func_quote_arg_result" } fi @@ -1091,85 +1134,203 @@ func_relative_path () } -# func_quote_for_eval ARG... -# -------------------------- -# Aesthetically quote ARGs to be evaled later. -# This function returns two values: -# i) func_quote_for_eval_result -# double-quoted, suitable for a subsequent eval -# ii) func_quote_for_eval_unquoted_result -# has all characters that are still active within double -# quotes backslashified. -func_quote_for_eval () +# func_quote_portable EVAL ARG +# ---------------------------- +# Internal function to portably implement func_quote_arg. Note that we still +# keep attention to performance here so we as much as possible try to avoid +# calling sed binary (so far O(N) complexity as long as func_append is O(1)). +func_quote_portable () { $debug_cmd - func_quote_for_eval_unquoted_result= - func_quote_for_eval_result= - while test 0 -lt $#; do - case $1 in - *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; - *) - _G_unquoted_arg=$1 ;; - esac - if test -n "$func_quote_for_eval_unquoted_result"; then - func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" - else - func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + $require_check_ifs_backslash + + func_quote_portable_result=$2 + + # one-time-loop (easy break) + while true + do + if $1; then + func_quote_portable_result=`$ECHO "$2" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` + break fi - case $_G_unquoted_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and variable expansion - # for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_quoted_arg=\"$_G_unquoted_arg\" + # Quote for eval. + case $func_quote_portable_result in + *[\\\`\"\$]*) + # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string + # contains the shell wildcard characters. + case $check_ifs_backshlash_broken$func_quote_portable_result in + :*|*[\[\*\?]*) + func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ + | $SED "$sed_quote_subst"` + break + ;; + esac + + func_quote_portable_old_IFS=$IFS + for _G_char in '\' '`' '"' '$' + do + # STATE($1) PREV($2) SEPARATOR($3) + set start "" "" + func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy + IFS=$_G_char + for _G_part in $func_quote_portable_result + do + case $1 in + quote) + func_append func_quote_portable_result "$3$2" + set quote "$_G_part" "\\$_G_char" + ;; + start) + set first "" "" + func_quote_portable_result= + ;; + first) + set quote "$_G_part" "" + ;; + esac + done + done + IFS=$func_quote_portable_old_IFS ;; - *) - _G_quoted_arg=$_G_unquoted_arg - ;; + *) ;; esac - - if test -n "$func_quote_for_eval_result"; then - func_append func_quote_for_eval_result " $_G_quoted_arg" - else - func_append func_quote_for_eval_result "$_G_quoted_arg" - fi - shift + break done + + func_quote_portable_unquoted_result=$func_quote_portable_result + case $func_quote_portable_result in + # double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # many bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_portable_result=\"$func_quote_portable_result\" + ;; + esac } -# func_quote_for_expand ARG -# ------------------------- -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - $debug_cmd +# func_quotefast_eval ARG +# ----------------------- +# Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', +# but optimized for speed. Result is stored in $func_quotefast_eval. +if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then + printf -v _GL_test_printf_tilde %q '~' + if test '\~' = "$_GL_test_printf_tilde"; then + func_quotefast_eval () + { + printf -v func_quotefast_eval_result %q "$1" + } + else + # Broken older Bash implementations. Make those faster too if possible. + func_quotefast_eval () + { + case $1 in + '~'*) + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + ;; + *) + printf -v func_quotefast_eval_result %q "$1" + ;; + esac + } + fi +else + func_quotefast_eval () + { + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + } +fi - case $1 in - *[\\\`\"]*) - _G_arg=`$ECHO "$1" | $SED \ - -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; - *) - _G_arg=$1 ;; + +# func_quote_arg MODEs ARG +# ------------------------ +# Quote one ARG to be evaled later. MODEs argument may contain zero or more +# specifiers listed below separated by ',' character. This function returns two +# values: +# i) func_quote_arg_result +# double-quoted (when needed), suitable for a subsequent eval +# ii) func_quote_arg_unquoted_result +# has all characters that are still active within double +# quotes backslashified. Available only if 'unquoted' is specified. +# +# Available modes: +# ---------------- +# 'eval' (default) +# - escape shell special characters +# 'expand' +# - the same as 'eval'; but do not quote variable references +# 'pretty' +# - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might +# be used later in func_quote to get output like: 'echo "a b"' instead +# of 'echo a\ b'. This is slower than default on some shells. +# 'unquoted' +# - produce also $func_quote_arg_unquoted_result which does not contain +# wrapping double-quotes. +# +# Examples for 'func_quote_arg pretty,unquoted string': +# +# string | *_result | *_unquoted_result +# ------------+-----------------------+------------------- +# " | \" | \" +# a b | "a b" | a b +# "a b" | "\"a b\"" | \"a b\" +# * | "*" | * +# z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" +# +# Examples for 'func_quote_arg pretty,unquoted,expand string': +# +# string | *_result | *_unquoted_result +# --------------+---------------------+-------------------- +# z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" +func_quote_arg () +{ + _G_quote_expand=false + case ,$1, in + *,expand,*) + _G_quote_expand=: + ;; esac - case $_G_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_arg=\"$_G_arg\" + case ,$1, in + *,pretty,*|*,expand,*|*,unquoted,*) + func_quote_portable $_G_quote_expand "$2" + func_quote_arg_result=$func_quote_portable_result + func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result + ;; + *) + # Faster quote-for-eval for some shells. + func_quotefast_eval "$2" + func_quote_arg_result=$func_quotefast_eval_result ;; esac +} + - func_quote_for_expand_result=$_G_arg +# func_quote MODEs ARGs... +# ------------------------ +# Quote all ARGs to be evaled later and join them into single command. See +# func_quote_arg's description for more info. +func_quote () +{ + $debug_cmd + _G_func_quote_mode=$1 ; shift + func_quote_result= + while test 0 -lt $#; do + func_quote_arg "$_G_func_quote_mode" "$1" + if test -n "$func_quote_result"; then + func_append func_quote_result " $func_quote_arg_result" + else + func_append func_quote_result "$func_quote_arg_result" + fi + shift + done } @@ -1215,8 +1376,8 @@ func_show_eval () _G_cmd=$1 _G_fail_exp=${2-':'} - func_quote_for_expand "$_G_cmd" - eval "func_notquiet $func_quote_for_expand_result" + func_quote_arg pretty,expand "$_G_cmd" + eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" @@ -1241,8 +1402,8 @@ func_show_eval_locale () _G_fail_exp=${2-':'} $opt_quiet || { - func_quote_for_expand "$_G_cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$_G_cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || { @@ -1369,30 +1530,26 @@ func_lt_ver () # End: #! /bin/sh -# Set a version string for this script. -scriptversion=2014-01-07.03; # UTC - # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 -# Copyright (C) 2010-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2010-2019, 2021 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Please report bugs or propose patches to: +# -# Please report bugs or propose patches to gary@gnu.org. +# Set a version string for this script. +scriptversion=2019-02-19.15; # UTC ## ------ ## @@ -1415,7 +1572,7 @@ scriptversion=2014-01-07.03; # UTC # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file -# starting with '# Written by ' and ending with '# warranty; '. +# starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the @@ -1427,7 +1584,7 @@ scriptversion=2014-01-07.03; # UTC # to display verbose messages only when your user has specified # '--verbose'. # -# After sourcing this file, you can plug processing for additional +# After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. @@ -1476,8 +1633,8 @@ fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## # This section contains functions for adding, removing, and running hooks -# to the main code. A hook is just a named list of of function, that can -# be run in order later on. +# in the main code. A hook is just a list of function names that can be +# run in order later on. # func_hookable FUNC_NAME # ----------------------- @@ -1510,7 +1667,8 @@ func_add_hook () # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ -# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +# Remove HOOK_FUNC from the list of hook functions to be called by +# FUNC_NAME. func_remove_hook () { $debug_cmd @@ -1519,10 +1677,28 @@ func_remove_hook () } +# func_propagate_result FUNC_NAME_A FUNC_NAME_B +# --------------------------------------------- +# If the *_result variable of FUNC_NAME_A _is set_, assign its value to +# *_result variable of FUNC_NAME_B. +func_propagate_result () +{ + $debug_cmd + + func_propagate_result_result=: + if eval "test \"\${${1}_result+set}\" = set" + then + eval "${2}_result=\$${1}_result" + else + func_propagate_result_result=false + fi +} + + # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. -# It is assumed that the list of hook functions contains nothing more +# It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. @@ -1532,22 +1708,19 @@ func_run_hooks () case " $hookable_fns " in *" $1 "*) ;; - *) func_fatal_error "'$1' does not support hook funcions.n" ;; + *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' - - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift + func_unset "${_G_hook}_result" + eval $_G_hook '${1+"$@"}' + func_propagate_result $_G_hook func_run_hooks + if $func_propagate_result_result; then + eval set dummy "$func_run_hooks_result"; shift + fi done - - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result } @@ -1557,10 +1730,18 @@ func_run_hooks () ## --------------- ## # In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, remove any -# options that you action, and then pass back the remaining unprocessed -# options in '_result', escaped suitably for -# 'eval'. Like this: +# full positional parameter list from your hook function. You may remove +# or edit any options that you action, and then pass back the remaining +# unprocessed options in '_result', escaped +# suitably for 'eval'. +# +# The '_result' variable is automatically unset +# before your hook gets called; for best performance, only set the +# *_result variable when necessary (i.e. don't call the 'func_quote' +# function unnecessarily because it can be an expensive operation on some +# machines). +# +# Like this: # # my_options_prep () # { @@ -1570,9 +1751,8 @@ func_run_hooks () # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' -# -# func_quote_for_eval ${1+"$@"} -# my_options_prep_result=$func_quote_for_eval_result +# # No change in '$@' (ignored completely by this hook). Leave +# # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # @@ -1581,25 +1761,36 @@ func_run_hooks () # { # $debug_cmd # -# # Note that for efficiency, we parse as many options as we can +# args_changed=false +# +# # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in -# --silent|-s) opt_silent=: ;; +# --silent|-s) opt_silent=: +# args_changed=: +# ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift +# args_changed=: # ;; -# *) set dummy "$_G_opt" "$*"; shift; break ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@" in case we need it later, +# # if $args_changed was set to 'true'. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result +# # Only call 'func_quote' here if we processed at least one argument. +# if $args_changed; then +# func_quote eval ${1+"$@"} +# my_silent_option_result=$func_quote_result +# fi # } # func_add_hook func_parse_options my_silent_option # @@ -1610,17 +1801,26 @@ func_run_hooks () # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." -# -# func_quote_for_eval ${1+"$@"} -# my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # -# You'll alse need to manually amend $usage_message to reflect the extra +# You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + func_run_hooks func_options ${1+"$@"} + func_propagate_result func_run_hooks func_options_finish +} + + # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the @@ -1630,17 +1830,27 @@ func_options () { $debug_cmd - func_options_prep ${1+"$@"} - eval func_parse_options \ - ${func_options_prep_result+"$func_options_prep_result"} - eval func_validate_options \ - ${func_parse_options_result+"$func_parse_options_result"} + _G_options_quoted=false - eval func_run_hooks func_options \ - ${func_validate_options_result+"$func_validate_options_result"} + for my_func in options_prep parse_options validate_options options_finish + do + func_unset func_${my_func}_result + func_unset func_run_hooks_result + eval func_$my_func '${1+"$@"}' + func_propagate_result func_$my_func func_options + if $func_propagate_result_result; then + eval set dummy "$func_options_result"; shift + _G_options_quoted=: + fi + done - # save modified positional parameters for caller - func_options_result=$func_run_hooks_result + $_G_options_quoted || { + # As we (func_options) are top-level options-parser function and + # nobody quoted "$@" for us yet, we need to do it explicitly for + # caller. + func_quote eval ${1+"$@"} + func_options_result=$func_quote_result + } } @@ -1649,9 +1859,8 @@ func_options () # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and -# needs to propogate that back to rest of this script, then the complete -# modified list must be put in 'func_run_hooks_result' before -# returning. +# needs to propagate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { @@ -1662,9 +1871,7 @@ func_options_prep () opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} - - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result + func_propagate_result func_run_hooks func_options_prep } @@ -1676,25 +1883,32 @@ func_parse_options () { $debug_cmd - func_parse_options_result= - + _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} - - # Adjust func_parse_options positional parameters to match - eval set dummy "$func_run_hooks_result"; shift + func_propagate_result func_run_hooks func_parse_options + if $func_propagate_result_result; then + eval set dummy "$func_parse_options_result"; shift + # Even though we may have changed "$@", we passed the "$@" array + # down into the hook and it quoted it for us (because we are in + # this if-branch). No need to quote it again. + _G_parse_options_requote=false + fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break + # We expect that one of the options parsed in this function matches + # and thus we remove _G_opt from "$@" and need to re-quote. + _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' - func_echo "enabling shell trace mode" + func_echo "enabling shell trace mode" >&2 $debug_cmd ;; @@ -1704,7 +1918,10 @@ func_parse_options () ;; --warnings|--warning|-W) - test $# = 0 && func_missing_arg $_G_opt && break + if test $# = 0 && func_missing_arg $_G_opt; then + _G_parse_options_requote=: + break + fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above @@ -1757,15 +1974,24 @@ func_parse_options () shift ;; - --) break ;; + --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; esac + + if $_G_match_parse_options; then + _G_parse_options_requote=: + fi done - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result + if $_G_parse_options_requote; then + # save modified positional parameters for caller + func_quote eval ${1+"$@"} + func_parse_options_result=$func_quote_result + fi } @@ -1782,12 +2008,10 @@ func_validate_options () test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} + func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE - - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result } @@ -1843,8 +2067,8 @@ func_missing_arg () # func_split_equals STRING # ------------------------ -# Set func_split_equals_lhs and func_split_equals_rhs shell variables after -# splitting STRING at the '=' sign. +# Set func_split_equals_lhs and func_split_equals_rhs shell variables +# after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ @@ -1859,8 +2083,9 @@ then func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} - test "x$func_split_equals_lhs" = "x$1" \ - && func_split_equals_rhs= + if test "x$func_split_equals_lhs" = "x$1"; then + func_split_equals_rhs= + fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. @@ -1870,7 +2095,7 @@ else func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= - test "x$func_split_equals_lhs" = "x$1" \ + test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals @@ -1896,7 +2121,7 @@ else { $debug_cmd - func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt @@ -1938,31 +2163,44 @@ func_usage_message () # func_version # ------------ # Echo version message to standard output and exit. +# The version message is extracted from the calling file's header +# comments, with leading '# ' stripped: +# 1. First display the progname and version +# 2. Followed by the header comment line matching /^# Written by / +# 3. Then a blank line followed by the first following line matching +# /^# Copyright / +# 4. Immediately followed by any lines between the previous matches, +# except lines preceding the intervening completely blank line. +# For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' - /(C)/!b go - :more - /\./!{ - N - s|\n# | | - b more - } - :go - /^# Written by /,/# warranty; / { - s|^# || - s|^# *$|| - s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| - p + /^# Written by /!b + s|^# ||; p; n + + :fwd2blnk + /./ { + n + b fwd2blnk } - /^# Written by / { - s|^# || - p + p; n + + :holdwrnt + s|^# || + s|^# *$|| + /^Copyright /!{ + /./H + n + b holdwrnt } - /^warranty; /q' < "$progpath" + + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + G + s|\(\n\)\n*|\1|g + p; q' < "$progpath" exit $? } @@ -1972,12 +2210,12 @@ func_version () # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. -scriptversion='(GNU libtool) 2.4.6' +scriptversion='(GNU libtool) 2.4.7' # func_echo ARG... @@ -2068,7 +2306,7 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6 + version: $progname (GNU libtool) 2.4.7 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` @@ -2124,7 +2362,7 @@ fi # a configuration failure hint, and exit. func_fatal_configuration () { - func__fatal_error ${1+"$@"} \ + func_fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } @@ -2270,6 +2508,8 @@ libtool_options_prep () nonopt= preserve_args= + _G_rc_lt_options_prep=: + # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) @@ -2293,11 +2533,16 @@ libtool_options_prep () uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; + *) + _G_rc_lt_options_prep=false + ;; esac - # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote eval ${1+"$@"} + libtool_options_prep_result=$func_quote_result + fi } func_add_hook func_options_prep libtool_options_prep @@ -2309,9 +2554,12 @@ libtool_parse_options () { $debug_cmd + _G_rc_lt_parse_options=false + # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do + _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in @@ -2386,15 +2634,20 @@ libtool_parse_options () func_append preserve_args " $_G_opt" ;; - # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote eval ${1+"$@"} + libtool_parse_options_result=$func_quote_result + fi } func_add_hook func_parse_options libtool_parse_options @@ -2444,8 +2697,8 @@ libtool_validate_options () } # Pass back the unparsed argument list - func_quote_for_eval ${1+"$@"} - libtool_validate_options_result=$func_quote_for_eval_result + func_quote eval ${1+"$@"} + libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options @@ -3411,8 +3664,8 @@ func_mode_compile () esac done - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ + func_quote_arg pretty "$libobj" + test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" @@ -3485,8 +3738,8 @@ compiler." func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result + func_quote_arg pretty "$srcfile" + qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then @@ -3641,7 +3894,8 @@ This mode accepts the following additional options: -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler + -Wc,FLAG + -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. @@ -3747,6 +4001,8 @@ The following components of LINK-COMMAND are treated specially: -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wa,FLAG + -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) @@ -4089,8 +4345,8 @@ func_mode_install () case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " + func_quote_arg pretty "$nonopt" + install_prog="$func_quote_arg_result " arg=$1 shift else @@ -4100,8 +4356,8 @@ func_mode_install () # The real first argument should be the name of the installation program. # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; @@ -4158,12 +4414,12 @@ func_mode_install () esac # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then - func_quote_for_eval "$arg2" + func_quote_arg pretty "$arg2" fi - func_append install_shared_prog " $func_quote_for_eval_result" + func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ @@ -4174,8 +4430,8 @@ func_mode_install () if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" + func_quote_arg pretty "$install_override_mode" + func_append install_shared_prog " -m $func_quote_arg_result" fi fi @@ -4471,8 +4727,8 @@ func_mode_install () relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$relink_command" + eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else @@ -5251,7 +5507,8 @@ else if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + func_quote_arg pretty "$ECHO" + qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. @@ -5261,7 +5518,7 @@ func_fallback_echo () \$1 _LTECHO_EOF' } - ECHO=\"$qECHO\" + ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to @@ -6604,9 +6861,9 @@ func_mode_link () while test "$#" -gt 0; do arg=$1 shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" + func_quote_arg pretty,unquoted "$arg" + qarg=$func_quote_arg_unquoted_result + func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then @@ -6842,6 +7099,13 @@ func_mode_link () prev= continue ;; + xassembler) + func_append compiler_flags " -Xassembler $qarg" + prev= + func_append compile_command " -Xassembler $qarg" + func_append finalize_command " -Xassembler $qarg" + continue + ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" @@ -7012,7 +7276,7 @@ func_mode_link () # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; @@ -7032,7 +7296,7 @@ func_mode_link () esac elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -7062,8 +7326,20 @@ func_mode_link () prev=xcompiler continue ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. + -pthread) + case $host in + *solaris2*) ;; + *) + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + ;; + esac + continue + ;; + -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" @@ -7204,9 +7480,9 @@ func_mode_link () save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" + func_quote_arg pretty "$flag" + func_append arg " $func_quote_arg_result" + func_append compiler_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" @@ -7220,16 +7496,21 @@ func_mode_link () save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" + func_quote_arg pretty "$flag" + func_append arg " $wl$func_quote_arg_result" + func_append compiler_flags " $wl$func_quote_arg_result" + func_append linker_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; + -Xassembler) + prev=xassembler + continue + ;; + -Xcompiler) prev=xcompiler continue @@ -7247,8 +7528,8 @@ func_mode_link () # -msg_* for osf cc -msg_*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; # Flags to be passed through unchanged, with rationale: @@ -7265,12 +7546,17 @@ func_mode_link () # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + # -fuse-ld=* Linker select flags for GCC + # -Wa,* Pass flags directly to the assembler -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*|-fuse-ld=*|-Wa,*) + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" @@ -7291,15 +7577,15 @@ func_mode_link () continue else # Otherwise treat like 'Some other compiler flag' below - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result fi ;; # Some other compiler flag. -* | +*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; *.$objext) @@ -7419,8 +7705,8 @@ func_mode_link () *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; esac # arg @@ -8625,7 +8911,7 @@ func_mode_link () test CXX = "$tagname" && { case $host_os in linux*) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi @@ -8798,7 +9084,7 @@ func_mode_link () # case $version_type in # correct linux to gnu/linux during the next big refactor - darwin|freebsd-elf|linux|osf|windows|none) + darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor @@ -8889,7 +9175,7 @@ func_mode_link () versuffix=.$current.$revision ;; - freebsd-elf) + freebsd-elf | midnightbsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision @@ -9115,7 +9401,7 @@ func_mode_link () *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) @@ -9926,8 +10212,8 @@ EOF for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? @@ -10020,8 +10306,8 @@ EOF eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? @@ -10495,12 +10781,13 @@ EOF elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + func_quote_arg pretty "$var_value" + relink_command="$var=$func_quote_arg_result; export $var; $relink_command" fi done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + func_quote eval cd "`pwd`" + func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)" + relink_command=$func_quote_arg_unquoted_result fi # Only actually do things if not in dry run mode. @@ -10740,13 +11027,15 @@ EOF elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + func_quote_arg pretty,unquoted "$var_value" + relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command" fi done # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + func_quote eval cd "`pwd`" + relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + func_quote_arg pretty,unquoted "$relink_command" + relink_command=$func_quote_arg_unquoted_result if test yes = "$hardcode_automatic"; then relink_command= fi diff --git a/buildutil/glibtests.m4 b/buildutil/glibtests.m4 index 108c847..34dfcf6 100644 --- a/buildutil/glibtests.m4 +++ b/buildutil/glibtests.m4 @@ -25,7 +25,7 @@ AC_DEFUN([GLIB_TESTS], *) AC_MSG_ERROR([bad value ${enableval} for --enable-always-build-tests]) ;; esac]) AM_CONDITIONAL([ENABLE_ALWAYS_BUILD_TESTS], test "$ENABLE_ALWAYS_BUILD_TESTS" = "1") - if test "$ENABLE_INSTALLED_TESTS" == "1"; then + if test "$ENABLE_INSTALLED_TESTS" = "1"; then AC_SUBST(installed_test_metadir, [${datadir}/installed-tests/]AC_PACKAGE_NAME) AC_SUBST(installed_testdir, [${libexecdir}/installed-tests/]AC_PACKAGE_NAME) fi diff --git a/buildutil/libtool.m4 b/buildutil/libtool.m4 index a644432..e3adeda 100644 --- a/buildutil/libtool.m4 +++ b/buildutil/libtool.m4 @@ -1,6 +1,7 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -31,7 +32,7 @@ m4_define([_LT_COPYING], [dnl # along with this program. If not, see . ]) -# serial 58 LT_INIT +# serial 59 LT_INIT # LT_PREREQ(VERSION) @@ -181,6 +182,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl @@ -219,8 +221,8 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -778,7 +780,7 @@ _LT_EOF # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || @@ -1042,8 +1044,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF @@ -1067,17 +1069,12 @@ _LT_EOF _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac @@ -1126,12 +1123,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1245,7 +1242,8 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) +[m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot @@ -1262,7 +1260,7 @@ case $with_sysroot in #( fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -1292,7 +1290,7 @@ ia64-*-hpux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -1309,7 +1307,7 @@ ia64-*-hpux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -1321,7 +1319,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -1343,7 +1341,7 @@ mips64*-*linux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -1351,7 +1349,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -1359,7 +1357,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -1379,14 +1377,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -1454,7 +1452,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -1493,9 +1491,22 @@ need_locks=$enable_libtool_lock m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} -: ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because thats what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS +_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. +_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], + [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no @@ -1714,7 +1725,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1757,7 +1768,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -2207,26 +2218,35 @@ m4_defun([_LT_CMD_STRIPLIB], striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) +if test -z "$STRIP"; then + AC_MSG_RESULT([no]) else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) - else + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac + ;; + esac + fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) @@ -2549,7 +2569,7 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; @@ -2559,14 +2579,14 @@ m4_if([$1], [],[ ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -2585,7 +2605,7 @@ m4_if([$1], [],[ done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -2622,7 +2642,7 @@ m4_if([$1], [],[ ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -2655,7 +2675,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -3457,7 +3477,7 @@ beos*) bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -3491,14 +3511,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -3512,7 +3532,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' @@ -3559,7 +3579,7 @@ netbsd*) newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -3686,13 +3706,13 @@ else mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -3718,7 +3738,7 @@ else # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -3958,7 +3978,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -3976,20 +3996,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -4013,7 +4033,7 @@ for ac_symprfx in "" "_"; do if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ @@ -4031,9 +4051,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -4320,7 +4340,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) @@ -4403,7 +4423,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4739,7 +4759,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4922,7 +4942,7 @@ m4_if([$1], [CXX], [ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) @@ -4930,7 +4950,7 @@ m4_if([$1], [CXX], [ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -4987,15 +5007,15 @@ dnl Note also adjust exclude_expsyms for C++ above. case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) @@ -5047,7 +5067,7 @@ dnl Note also adjust exclude_expsyms for C++ above. _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -5159,6 +5179,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) @@ -5173,7 +5194,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -5216,7 +5237,7 @@ _LT_EOF _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes @@ -5228,7 +5249,7 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi @@ -5244,7 +5265,7 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -5376,7 +5397,7 @@ _LT_EOF if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no @@ -5559,12 +5580,12 @@ _LT_EOF cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes @@ -5605,7 +5626,7 @@ _LT_EOF fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. @@ -5653,7 +5674,7 @@ _LT_EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes @@ -5864,6 +5885,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) @@ -6634,8 +6656,8 @@ if test yes != "$_lt_caught_CXX_error"; then cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' @@ -6733,6 +6755,7 @@ if test yes != "$_lt_caught_CXX_error"; then emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) @@ -6763,7 +6786,7 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes @@ -6900,7 +6923,7 @@ if test yes != "$_lt_caught_CXX_error"; then # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in @@ -7040,13 +7063,13 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' @@ -8192,6 +8215,14 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) +# _LT_DECL_FILECMD +# ---------------- +# Check for a file(cmd) program that can be used to detect file type and magic +m4_defun([_LT_DECL_FILECMD], +[AC_CHECK_TOOL([FILECMD], [file], [:]) +_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) +])# _LD_DECL_FILECMD + # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates diff --git a/buildutil/ltoptions.m4 b/buildutil/ltoptions.m4 index 94b0829..b0b5e9c 100644 --- a/buildutil/ltoptions.m4 +++ b/buildutil/ltoptions.m4 @@ -1,7 +1,7 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software -# Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free +# Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives diff --git a/buildutil/ltsugar.m4 b/buildutil/ltsugar.m4 index 48bc934..902508b 100644 --- a/buildutil/ltsugar.m4 +++ b/buildutil/ltsugar.m4 @@ -1,6 +1,6 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # diff --git a/buildutil/ltversion.m4 b/buildutil/ltversion.m4 index fa04b52..b155d0a 100644 --- a/buildutil/ltversion.m4 +++ b/buildutil/ltversion.m4 @@ -1,6 +1,7 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, +# Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +10,15 @@ # @configure_input@ -# serial 4179 ltversion.m4 +# serial 4245 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.6]) -m4_define([LT_PACKAGE_REVISION], [2.4.6]) +m4_define([LT_PACKAGE_VERSION], [2.4.7]) +m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6' -macro_revision='2.4.6' +[macro_version='2.4.7' +macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/buildutil/lt~obsolete.m4 b/buildutil/lt~obsolete.m4 index c6b26f8..0f7a875 100644 --- a/buildutil/lt~obsolete.m4 +++ b/buildutil/lt~obsolete.m4 @@ -1,7 +1,7 @@ # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software -# Foundation, Inc. +# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free +# Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives diff --git a/composefs/libcomposefs/Makefile-lib.am b/composefs/libcomposefs/Makefile-lib.am new file mode 100644 index 0000000..4b4d401 --- /dev/null +++ b/composefs/libcomposefs/Makefile-lib.am @@ -0,0 +1,22 @@ +COMPOSEFS_HASH_CFLAGS = -DUSE_OBSTACK=0 -DTESTING=0 -DUSE_DIFF_HASH=0 + +libcomposefs_la_SOURCES = \ + $(COMPOSEFSDIR)/bitrotate.h \ + $(COMPOSEFSDIR)/erofs_fs.h \ + $(COMPOSEFSDIR)/erofs_fs_wrapper.h \ + $(COMPOSEFSDIR)/hash.c \ + $(COMPOSEFSDIR)/hash.h \ + $(COMPOSEFSDIR)/lcfs-internal.h \ + $(COMPOSEFSDIR)/lcfs-erofs.h \ + $(COMPOSEFSDIR)/lcfs-erofs-internal.h \ + $(COMPOSEFSDIR)/lcfs-fsverity.c \ + $(COMPOSEFSDIR)/lcfs-fsverity.h \ + $(COMPOSEFSDIR)/lcfs-writer-erofs.c \ + $(COMPOSEFSDIR)/lcfs-writer.c \ + $(COMPOSEFSDIR)/lcfs-writer.h \ + $(COMPOSEFSDIR)/lcfs-utils.h \ + $(COMPOSEFSDIR)/lcfs-mount.c \ + $(COMPOSEFSDIR)/lcfs-mount.h \ + $(COMPOSEFSDIR)/xalloc-oversized.h +libcomposefs_la_CFLAGS = $(WARN_CFLAGS) $(COMPOSEFS_HASH_CFLAGS) $(LCFS_DEP_CRYPTO_CFLAGS) $(HIDDEN_VISIBILITY_CFLAGS) +libcomposefs_la_LIBADD = $(LCFS_DEP_CRYPTO_LIBS) diff --git a/composefs/libcomposefs/Makefile-lib.am.inc b/composefs/libcomposefs/Makefile-lib.am.inc new file mode 100644 index 0000000..4d1012a --- /dev/null +++ b/composefs/libcomposefs/Makefile-lib.am.inc @@ -0,0 +1,22 @@ +COMPOSEFS_HASH_CFLAGS = -DUSE_OBSTACK=0 -DTESTING=0 -DUSE_DIFF_HASH=0 + +libcomposefs_la_SOURCES = \ + composefs/libcomposefs/bitrotate.h \ + composefs/libcomposefs/erofs_fs.h \ + composefs/libcomposefs/erofs_fs_wrapper.h \ + composefs/libcomposefs/hash.c \ + composefs/libcomposefs/hash.h \ + composefs/libcomposefs/lcfs-internal.h \ + composefs/libcomposefs/lcfs-erofs.h \ + composefs/libcomposefs/lcfs-erofs-internal.h \ + composefs/libcomposefs/lcfs-fsverity.c \ + composefs/libcomposefs/lcfs-fsverity.h \ + composefs/libcomposefs/lcfs-writer-erofs.c \ + composefs/libcomposefs/lcfs-writer.c \ + composefs/libcomposefs/lcfs-writer.h \ + composefs/libcomposefs/lcfs-utils.h \ + composefs/libcomposefs/lcfs-mount.c \ + composefs/libcomposefs/lcfs-mount.h \ + composefs/libcomposefs/xalloc-oversized.h +libcomposefs_la_CFLAGS = $(WARN_CFLAGS) $(COMPOSEFS_HASH_CFLAGS) $(LCFS_DEP_CRYPTO_CFLAGS) $(HIDDEN_VISIBILITY_CFLAGS) +libcomposefs_la_LIBADD = $(LCFS_DEP_CRYPTO_LIBS) diff --git a/composefs/libcomposefs/bitrotate.h b/composefs/libcomposefs/bitrotate.h new file mode 100644 index 0000000..8e8016c --- /dev/null +++ b/composefs/libcomposefs/bitrotate.h @@ -0,0 +1,135 @@ +/* bitrotate.h - Rotate bits in integers + Copyright (C) 2008-2021 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Simon Josefsson , 2008. */ + +#ifndef _GL_BITROTATE_H +#define _GL_BITROTATE_H + +#include +#include +#include + +#define _GL_INLINE static inline +#define _GL_ATTRIBUTE_CONST const + +#ifndef BITROTATE_INLINE +# define BITROTATE_INLINE _GL_INLINE +#endif + +#ifdef UINT64_MAX +/* Given an unsigned 64-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 and + 63 inclusive. */ +BITROTATE_INLINE uint64_t +rotl64 (uint64_t x, int n) +{ + return ((x << n) | (x >> (64 - n))) & UINT64_MAX; +} + +/* Given an unsigned 64-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be between 1 to + 63 inclusive.*/ +BITROTATE_INLINE uint64_t +rotr64 (uint64_t x, int n) +{ + return ((x >> n) | (x << (64 - n))) & UINT64_MAX; +} +#endif + +/* Given an unsigned 32-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 and + 31 inclusive. */ +BITROTATE_INLINE uint32_t +rotl32 (uint32_t x, int n) +{ + return ((x << n) | (x >> (32 - n))) & UINT32_MAX; +} + +/* Given an unsigned 32-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be between 1 to + 31 inclusive.*/ +BITROTATE_INLINE uint32_t +rotr32 (uint32_t x, int n) +{ + return ((x >> n) | (x << (32 - n))) & UINT32_MAX; +} + +/* Given a size_t argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 and + (CHAR_BIT * sizeof (size_t) - 1) inclusive. */ +BITROTATE_INLINE size_t +rotl_sz (size_t x, int n) +{ + return ((x << n) | (x >> ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX; +} + +/* Given a size_t argument X, return the value corresponding + to rotating the bits N steps to the right. N must be between 1 to + (CHAR_BIT * sizeof (size_t) - 1) inclusive. */ +BITROTATE_INLINE size_t +rotr_sz (size_t x, int n) +{ + return ((x >> n) | (x << ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX; +} + +/* Given an unsigned 16-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 to + 15 inclusive, but on most relevant targets N can also be 0 and 16 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint16_t +rotl16 (uint16_t x, int n) +{ + return (((unsigned int) x << n) | ((unsigned int) x >> (16 - n))) + & UINT16_MAX; +} + +/* Given an unsigned 16-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be in 1 to 15 + inclusive, but on most relevant targets N can also be 0 and 16 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint16_t +rotr16 (uint16_t x, int n) +{ + return (((unsigned int) x >> n) | ((unsigned int) x << (16 - n))) + & UINT16_MAX; +} + +/* Given an unsigned 8-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 to 7 + inclusive, but on most relevant targets N can also be 0 and 8 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint8_t +rotl8 (uint8_t x, int n) +{ + return (((unsigned int) x << n) | ((unsigned int) x >> (8 - n))) & UINT8_MAX; +} + +/* Given an unsigned 8-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be in 1 to 7 + inclusive, but on most relevant targets N can also be 0 and 8 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint8_t +rotr8 (uint8_t x, int n) +{ + return (((unsigned int) x >> n) | ((unsigned int) x << (8 - n))) & UINT8_MAX; +} + +#endif /* _GL_BITROTATE_H */ diff --git a/composefs/libcomposefs/erofs_fs.h b/composefs/libcomposefs/erofs_fs.h new file mode 100644 index 0000000..a03ec70 --- /dev/null +++ b/composefs/libcomposefs/erofs_fs.h @@ -0,0 +1,461 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR Apache-2.0 */ +/* + * EROFS (Enhanced ROM File System) on-disk format definition + * + * Copyright (C) 2017-2018 HUAWEI, Inc. + * https://www.huawei.com/ + * Copyright (C) 2021, Alibaba Cloud + */ +#ifndef __EROFS_FS_H +#define __EROFS_FS_H + +#define EROFS_SUPER_OFFSET 1024 + +#define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001 +#define EROFS_FEATURE_COMPAT_MTIME 0x00000002 +#define EROFS_FEATURE_COMPAT_XATTR_FILTER 0x00000004 + +/* + * Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should + * be incompatible with this kernel version. + */ +#define EROFS_FEATURE_INCOMPAT_ZERO_PADDING 0x00000001 +#define EROFS_FEATURE_INCOMPAT_COMPR_CFGS 0x00000002 +#define EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER 0x00000002 +#define EROFS_FEATURE_INCOMPAT_CHUNKED_FILE 0x00000004 +#define EROFS_FEATURE_INCOMPAT_DEVICE_TABLE 0x00000008 +#define EROFS_FEATURE_INCOMPAT_COMPR_HEAD2 0x00000008 +#define EROFS_FEATURE_INCOMPAT_ZTAILPACKING 0x00000010 +#define EROFS_FEATURE_INCOMPAT_FRAGMENTS 0x00000020 +#define EROFS_FEATURE_INCOMPAT_DEDUPE 0x00000020 +#define EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES 0x00000040 +#define EROFS_ALL_FEATURE_INCOMPAT \ + (EROFS_FEATURE_INCOMPAT_ZERO_PADDING | \ + EROFS_FEATURE_INCOMPAT_COMPR_CFGS | \ + EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER | \ + EROFS_FEATURE_INCOMPAT_CHUNKED_FILE | \ + EROFS_FEATURE_INCOMPAT_DEVICE_TABLE | \ + EROFS_FEATURE_INCOMPAT_COMPR_HEAD2 | \ + EROFS_FEATURE_INCOMPAT_ZTAILPACKING | \ + EROFS_FEATURE_INCOMPAT_FRAGMENTS | \ + EROFS_FEATURE_INCOMPAT_DEDUPE | \ + EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES) + +#define EROFS_SB_EXTSLOT_SIZE 16 + +struct erofs_deviceslot { + u8 tag[64]; /* digest(sha256), etc. */ + __le32 blocks; /* total fs blocks of this device */ + __le32 mapped_blkaddr; /* map starting at mapped_blkaddr */ + u8 reserved[56]; +}; +#define EROFS_DEVT_SLOT_SIZE sizeof(struct erofs_deviceslot) + +/* erofs on-disk super block (currently 128 bytes) */ +struct erofs_super_block { + __le32 magic; /* file system magic number */ + __le32 checksum; /* crc32c(super_block) */ + __le32 feature_compat; + __u8 blkszbits; /* filesystem block size in bit shift */ + __u8 sb_extslots; /* superblock size = 128 + sb_extslots * 16 */ + + __le16 root_nid; /* nid of root directory */ + __le64 inos; /* total valid ino # (== f_files - f_favail) */ + + __le64 build_time; /* compact inode time derivation */ + __le32 build_time_nsec; /* compact inode time derivation in ns scale */ + __le32 blocks; /* used for statfs */ + __le32 meta_blkaddr; /* start block address of metadata area */ + __le32 xattr_blkaddr; /* start block address of shared xattr area */ + __u8 uuid[16]; /* 128-bit uuid for volume */ + __u8 volume_name[16]; /* volume name */ + __le32 feature_incompat; + union { + /* bitmap for available compression algorithms */ + __le16 available_compr_algs; + /* customized sliding window size instead of 64k by default */ + __le16 lz4_max_distance; + } __packed u1; + __le16 extra_devices; /* # of devices besides the primary device */ + __le16 devt_slotoff; /* startoff = devt_slotoff * devt_slotsize */ + __u8 dirblkbits; /* directory block size in bit shift */ + __u8 xattr_prefix_count; /* # of long xattr name prefixes */ + __le32 xattr_prefix_start; /* start of long xattr prefixes */ + __le64 packed_nid; /* nid of the special packed inode */ + __u8 xattr_filter_reserved; /* reserved for xattr name filter */ + __u8 reserved2[23]; +}; + +/* + * EROFS inode datalayout (i_format in on-disk inode): + * 0 - uncompressed flat inode without tail-packing inline data: + * 1 - compressed inode with non-compact indexes: + * 2 - uncompressed flat inode with tail-packing inline data: + * 3 - compressed inode with compact indexes: + * 4 - chunk-based inode with (optional) multi-device support: + * 5~7 - reserved + */ +enum { + EROFS_INODE_FLAT_PLAIN = 0, + EROFS_INODE_COMPRESSED_FULL = 1, + EROFS_INODE_FLAT_INLINE = 2, + EROFS_INODE_COMPRESSED_COMPACT = 3, + EROFS_INODE_CHUNK_BASED = 4, + EROFS_INODE_DATALAYOUT_MAX +}; + +static inline bool erofs_inode_is_data_compressed(unsigned int datamode) +{ + return datamode == EROFS_INODE_COMPRESSED_COMPACT || + datamode == EROFS_INODE_COMPRESSED_FULL; +} + +/* bit definitions of inode i_format */ +#define EROFS_I_VERSION_MASK 0x01 +#define EROFS_I_DATALAYOUT_MASK 0x07 + +#define EROFS_I_VERSION_BIT 0 +#define EROFS_I_DATALAYOUT_BIT 1 +#define EROFS_I_ALL_BIT 4 + +#define EROFS_I_ALL ((1 << EROFS_I_ALL_BIT) - 1) + +/* indicate chunk blkbits, thus 'chunksize = blocksize << chunk blkbits' */ +#define EROFS_CHUNK_FORMAT_BLKBITS_MASK 0x001F +/* with chunk indexes or just a 4-byte blkaddr array */ +#define EROFS_CHUNK_FORMAT_INDEXES 0x0020 + +#define EROFS_CHUNK_FORMAT_ALL \ + (EROFS_CHUNK_FORMAT_BLKBITS_MASK | EROFS_CHUNK_FORMAT_INDEXES) + +/* 32-byte on-disk inode */ +#define EROFS_INODE_LAYOUT_COMPACT 0 +/* 64-byte on-disk inode */ +#define EROFS_INODE_LAYOUT_EXTENDED 1 + +struct erofs_inode_chunk_info { + __le16 format; /* chunk blkbits, etc. */ + __le16 reserved; +}; + +union erofs_inode_i_u { + /* total compressed blocks for compressed inodes */ + __le32 compressed_blocks; + + /* block address for uncompressed flat inodes */ + __le32 raw_blkaddr; + + /* for device files, used to indicate old/new device # */ + __le32 rdev; + + /* for chunk-based files, it contains the summary info */ + struct erofs_inode_chunk_info c; +}; + +/* 32-byte reduced form of an ondisk inode */ +struct erofs_inode_compact { + __le16 i_format; /* inode format hints */ + +/* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ + __le16 i_xattr_icount; + __le16 i_mode; + __le16 i_nlink; + __le32 i_size; + __le32 i_reserved; + union erofs_inode_i_u i_u; + + __le32 i_ino; /* only used for 32-bit stat compatibility */ + __le16 i_uid; + __le16 i_gid; + __le32 i_reserved2; +}; + +/* 64-byte complete form of an ondisk inode */ +struct erofs_inode_extended { + __le16 i_format; /* inode format hints */ + +/* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ + __le16 i_xattr_icount; + __le16 i_mode; + __le16 i_reserved; + __le64 i_size; + union erofs_inode_i_u i_u; + + __le32 i_ino; /* only used for 32-bit stat compatibility */ + __le32 i_uid; + __le32 i_gid; + __le64 i_mtime; + __le32 i_mtime_nsec; + __le32 i_nlink; + __u8 i_reserved2[16]; +}; + +/* + * inline xattrs (n == i_xattr_icount): + * erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes + * 12 bytes / \ + * / \ + * /-----------------------\ + * | erofs_xattr_entries+ | + * +-----------------------+ + * inline xattrs must starts in erofs_xattr_ibody_header, + * for read-only fs, no need to introduce h_refcount + */ +struct erofs_xattr_ibody_header { + __le32 h_name_filter; /* bit value 1 indicates not-present */ + __u8 h_shared_count; + __u8 h_reserved2[7]; + __le32 h_shared_xattrs[]; /* shared xattr id array */ +}; + +/* Name indexes */ +#define EROFS_XATTR_INDEX_USER 1 +#define EROFS_XATTR_INDEX_POSIX_ACL_ACCESS 2 +#define EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 +#define EROFS_XATTR_INDEX_TRUSTED 4 +#define EROFS_XATTR_INDEX_LUSTRE 5 +#define EROFS_XATTR_INDEX_SECURITY 6 + +/* + * bit 7 of e_name_index is set when it refers to a long xattr name prefix, + * while the remained lower bits represent the index of the prefix. + */ +#define EROFS_XATTR_LONG_PREFIX 0x80 +#define EROFS_XATTR_LONG_PREFIX_MASK 0x7f + +#define EROFS_XATTR_FILTER_BITS 32 +#define EROFS_XATTR_FILTER_DEFAULT UINT32_MAX +#define EROFS_XATTR_FILTER_SEED 0x25BBE08F + +/* xattr entry (for both inline & shared xattrs) */ +struct erofs_xattr_entry { + __u8 e_name_len; /* length of name */ + __u8 e_name_index; /* attribute name index */ + __le16 e_value_size; /* size of attribute value */ + /* followed by e_name and e_value */ + char e_name[]; /* attribute name */ +}; + +/* long xattr name prefix */ +struct erofs_xattr_long_prefix { + __u8 base_index; /* short xattr name prefix index */ + char infix[]; /* infix apart from short prefix */ +}; + +static inline unsigned int erofs_xattr_ibody_size(__le16 i_xattr_icount) +{ + if (!i_xattr_icount) + return 0; + + return sizeof(struct erofs_xattr_ibody_header) + + sizeof(__u32) * (le16_to_cpu(i_xattr_icount) - 1); +} + +#define EROFS_XATTR_ALIGN(size) round_up(size, sizeof(struct erofs_xattr_entry)) + +static inline unsigned int erofs_xattr_entry_size(struct erofs_xattr_entry *e) +{ + return EROFS_XATTR_ALIGN(sizeof(struct erofs_xattr_entry) + + e->e_name_len + le16_to_cpu(e->e_value_size)); +} + +/* represent a zeroed chunk (hole) */ +#define EROFS_NULL_ADDR -1 + +/* 4-byte block address array */ +#define EROFS_BLOCK_MAP_ENTRY_SIZE sizeof(__le32) + +/* 8-byte inode chunk indexes */ +struct erofs_inode_chunk_index { + __le16 advise; /* always 0, don't care for now */ + __le16 device_id; /* back-end storage id (with bits masked) */ + __le32 blkaddr; /* start block address of this inode chunk */ +}; + +/* dirent sorts in alphabet order, thus we can do binary search */ +struct erofs_dirent { + __le64 nid; /* node number */ + __le16 nameoff; /* start offset of file name */ + __u8 file_type; /* file type */ + __u8 reserved; /* reserved */ +} __packed; + +/* + * EROFS file types should match generic FT_* types and + * it seems no need to add BUILD_BUG_ONs since potential + * unmatchness will break other fses as well... + */ + +#define EROFS_NAME_LEN 255 + +/* maximum supported size of a physical compression cluster */ +#define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024) + +/* available compression algorithm types (for h_algorithmtype) */ +enum { + Z_EROFS_COMPRESSION_LZ4 = 0, + Z_EROFS_COMPRESSION_LZMA = 1, + Z_EROFS_COMPRESSION_DEFLATE = 2, + Z_EROFS_COMPRESSION_MAX +}; +#define Z_EROFS_ALL_COMPR_ALGS ((1 << Z_EROFS_COMPRESSION_MAX) - 1) + +/* 14 bytes (+ length field = 16 bytes) */ +struct z_erofs_lz4_cfgs { + __le16 max_distance; + __le16 max_pclusterblks; + u8 reserved[10]; +} __packed; + +/* 14 bytes (+ length field = 16 bytes) */ +struct z_erofs_lzma_cfgs { + __le32 dict_size; + __le16 format; + u8 reserved[8]; +} __packed; + +#define Z_EROFS_LZMA_MAX_DICT_SIZE (8 * Z_EROFS_PCLUSTER_MAX_SIZE) + +/* 6 bytes (+ length field = 8 bytes) */ +struct z_erofs_deflate_cfgs { + u8 windowbits; /* 8..15 for DEFLATE */ + u8 reserved[5]; +} __packed; + +/* + * bit 0 : COMPACTED_2B indexes (0 - off; 1 - on) + * e.g. for 4k logical cluster size, 4B if compacted 2B is off; + * (4B) + 2B + (4B) if compacted 2B is on. + * bit 1 : HEAD1 big pcluster (0 - off; 1 - on) + * bit 2 : HEAD2 big pcluster (0 - off; 1 - on) + * bit 3 : tailpacking inline pcluster (0 - off; 1 - on) + * bit 4 : interlaced plain pcluster (0 - off; 1 - on) + * bit 5 : fragment pcluster (0 - off; 1 - on) + */ +#define Z_EROFS_ADVISE_COMPACTED_2B 0x0001 +#define Z_EROFS_ADVISE_BIG_PCLUSTER_1 0x0002 +#define Z_EROFS_ADVISE_BIG_PCLUSTER_2 0x0004 +#define Z_EROFS_ADVISE_INLINE_PCLUSTER 0x0008 +#define Z_EROFS_ADVISE_INTERLACED_PCLUSTER 0x0010 +#define Z_EROFS_ADVISE_FRAGMENT_PCLUSTER 0x0020 + +#define Z_EROFS_FRAGMENT_INODE_BIT 7 +struct z_erofs_map_header { + union { + /* fragment data offset in the packed inode */ + __le32 h_fragmentoff; + struct { + __le16 h_reserved1; + /* indicates the encoded size of tailpacking data */ + __le16 h_idata_size; + }; + }; + __le16 h_advise; + /* + * bit 0-3 : algorithm type of head 1 (logical cluster type 01); + * bit 4-7 : algorithm type of head 2 (logical cluster type 11). + */ + __u8 h_algorithmtype; + /* + * bit 0-2 : logical cluster bits - 12, e.g. 0 for 4096; + * bit 3-6 : reserved; + * bit 7 : move the whole file into packed inode or not. + */ + __u8 h_clusterbits; +}; + +/* + * On-disk logical cluster type: + * 0 - literal (uncompressed) lcluster + * 1,3 - compressed lcluster (for HEAD lclusters) + * 2 - compressed lcluster (for NONHEAD lclusters) + * + * In detail, + * 0 - literal (uncompressed) lcluster, + * di_advise = 0 + * di_clusterofs = the literal data offset of the lcluster + * di_blkaddr = the blkaddr of the literal pcluster + * + * 1,3 - compressed lcluster (for HEAD lclusters) + * di_advise = 1 or 3 + * di_clusterofs = the decompressed data offset of the lcluster + * di_blkaddr = the blkaddr of the compressed pcluster + * + * 2 - compressed lcluster (for NONHEAD lclusters) + * di_advise = 2 + * di_clusterofs = + * the decompressed data offset in its own HEAD lcluster + * di_u.delta[0] = distance to this HEAD lcluster + * di_u.delta[1] = distance to the next HEAD lcluster + */ +enum { + Z_EROFS_LCLUSTER_TYPE_PLAIN = 0, + Z_EROFS_LCLUSTER_TYPE_HEAD1 = 1, + Z_EROFS_LCLUSTER_TYPE_NONHEAD = 2, + Z_EROFS_LCLUSTER_TYPE_HEAD2 = 3, + Z_EROFS_LCLUSTER_TYPE_MAX +}; + +#define Z_EROFS_LI_LCLUSTER_TYPE_BITS 2 +#define Z_EROFS_LI_LCLUSTER_TYPE_BIT 0 + +/* (noncompact only, HEAD) This pcluster refers to partial decompressed data */ +#define Z_EROFS_LI_PARTIAL_REF (1 << 15) + +/* + * D0_CBLKCNT will be marked _only_ at the 1st non-head lcluster to store the + * compressed block count of a compressed extent (in logical clusters, aka. + * block count of a pcluster). + */ +#define Z_EROFS_LI_D0_CBLKCNT (1 << 11) + +struct z_erofs_lcluster_index { + __le16 di_advise; + /* where to decompress in the head lcluster */ + __le16 di_clusterofs; + + union { + /* for the HEAD lclusters */ + __le32 blkaddr; + /* + * for the NONHEAD lclusters + * [0] - distance to its HEAD lcluster + * [1] - distance to the next HEAD lcluster + */ + __le16 delta[2]; + } di_u; +}; + +#define Z_EROFS_FULL_INDEX_ALIGN(end) \ + (ALIGN(end, 8) + sizeof(struct z_erofs_map_header) + 8) + +/* check the EROFS on-disk layout strictly at compile time */ +static inline void erofs_check_ondisk_layout_definitions(void) +{ + const __le64 fmh = *(__le64 *)&(struct z_erofs_map_header) { + .h_clusterbits = 1 << Z_EROFS_FRAGMENT_INODE_BIT + }; + + BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128); + BUILD_BUG_ON(sizeof(struct erofs_inode_compact) != 32); + BUILD_BUG_ON(sizeof(struct erofs_inode_extended) != 64); + BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12); + BUILD_BUG_ON(sizeof(struct erofs_xattr_entry) != 4); + BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_info) != 4); + BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != 8); + BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8); + BUILD_BUG_ON(sizeof(struct z_erofs_lcluster_index) != 8); + BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12); + /* keep in sync between 2 index structures for better extendibility */ + BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != + sizeof(struct z_erofs_lcluster_index)); + BUILD_BUG_ON(sizeof(struct erofs_deviceslot) != 128); + + BUILD_BUG_ON(BIT(Z_EROFS_LI_LCLUSTER_TYPE_BITS) < + Z_EROFS_LCLUSTER_TYPE_MAX - 1); + /* exclude old compiler versions like gcc 7.5.0 */ + BUILD_BUG_ON(__builtin_constant_p(fmh) ? + fmh != cpu_to_le64(1ULL << 63) : 0); +} + +#endif diff --git a/composefs/libcomposefs/erofs_fs_wrapper.h b/composefs/libcomposefs/erofs_fs_wrapper.h new file mode 100644 index 0000000..b7ed2aa --- /dev/null +++ b/composefs/libcomposefs/erofs_fs_wrapper.h @@ -0,0 +1,150 @@ +#include +#include + +#define __packed __attribute__((__packed__)) +typedef __u8 u8; + +static inline __u16 cpu_to_le16(__u16 val) +{ + return htole16(val); +} + +static inline __u32 cpu_to_le32(__u32 val) +{ + return htole32(val); +} + +static inline __u64 cpu_to_le64(__u64 val) +{ + return htole64(val); +} + +static inline __u16 le16_to_cpu(__u16 val) +{ + return le16toh(val); +} + +static inline __u32 le32_to_cpu(__u32 val) +{ + return le32toh(val); +} + +static inline __u64 le64_to_cpu(__u64 val) +{ + return le64toh(val); +} + +/* Note: These only do power of 2 */ +#define __round_mask(x, y) ((__typeof__(x))((y)-1)) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) +#define round_down(x, y) ((x) & ~__round_mask(x, y)) + +#define ALIGN_TO(_offset, _align_size) \ + (((_offset) + _align_size - 1) & ~(_align_size - 1)) + +#define BIT(nr) (((uint64_t) 1) << (nr)) +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)])) +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + +/* We use a fixed block size for all arches of 4k */ +#define EROFS_BLKSIZ 4096 +#define EROFS_BLKSIZ_BITS 12 + +#define EROFS_ISLOTBITS 5 +#define EROFS_SLOTSIZE (1U << EROFS_ISLOTBITS) + +#define EROFS_SUPER_MAGIC_V1 0xE0F5E1E2 + +#define CRC32C_POLY_LE 0x82F63B78 +static inline uint32_t erofs_crc32c(uint32_t crc, const uint8_t *in, size_t len) +{ + int i; + + while (len--) { + crc ^= *in++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0); + } + return crc; +} + +enum { + EROFS_FT_UNKNOWN, + EROFS_FT_REG_FILE, + EROFS_FT_DIR, + EROFS_FT_CHRDEV, + EROFS_FT_BLKDEV, + EROFS_FT_FIFO, + EROFS_FT_SOCK, + EROFS_FT_SYMLINK, + EROFS_FT_MAX +}; + +#define ilog2(n) \ +( \ + (n) & (1ULL << 63) ? 63 : \ + (n) & (1ULL << 62) ? 62 : \ + (n) & (1ULL << 61) ? 61 : \ + (n) & (1ULL << 60) ? 60 : \ + (n) & (1ULL << 59) ? 59 : \ + (n) & (1ULL << 58) ? 58 : \ + (n) & (1ULL << 57) ? 57 : \ + (n) & (1ULL << 56) ? 56 : \ + (n) & (1ULL << 55) ? 55 : \ + (n) & (1ULL << 54) ? 54 : \ + (n) & (1ULL << 53) ? 53 : \ + (n) & (1ULL << 52) ? 52 : \ + (n) & (1ULL << 51) ? 51 : \ + (n) & (1ULL << 50) ? 50 : \ + (n) & (1ULL << 49) ? 49 : \ + (n) & (1ULL << 48) ? 48 : \ + (n) & (1ULL << 47) ? 47 : \ + (n) & (1ULL << 46) ? 46 : \ + (n) & (1ULL << 45) ? 45 : \ + (n) & (1ULL << 44) ? 44 : \ + (n) & (1ULL << 43) ? 43 : \ + (n) & (1ULL << 42) ? 42 : \ + (n) & (1ULL << 41) ? 41 : \ + (n) & (1ULL << 40) ? 40 : \ + (n) & (1ULL << 39) ? 39 : \ + (n) & (1ULL << 38) ? 38 : \ + (n) & (1ULL << 37) ? 37 : \ + (n) & (1ULL << 36) ? 36 : \ + (n) & (1ULL << 35) ? 35 : \ + (n) & (1ULL << 34) ? 34 : \ + (n) & (1ULL << 33) ? 33 : \ + (n) & (1ULL << 32) ? 32 : \ + (n) & (1ULL << 31) ? 31 : \ + (n) & (1ULL << 30) ? 30 : \ + (n) & (1ULL << 29) ? 29 : \ + (n) & (1ULL << 28) ? 28 : \ + (n) & (1ULL << 27) ? 27 : \ + (n) & (1ULL << 26) ? 26 : \ + (n) & (1ULL << 25) ? 25 : \ + (n) & (1ULL << 24) ? 24 : \ + (n) & (1ULL << 23) ? 23 : \ + (n) & (1ULL << 22) ? 22 : \ + (n) & (1ULL << 21) ? 21 : \ + (n) & (1ULL << 20) ? 20 : \ + (n) & (1ULL << 19) ? 19 : \ + (n) & (1ULL << 18) ? 18 : \ + (n) & (1ULL << 17) ? 17 : \ + (n) & (1ULL << 16) ? 16 : \ + (n) & (1ULL << 15) ? 15 : \ + (n) & (1ULL << 14) ? 14 : \ + (n) & (1ULL << 13) ? 13 : \ + (n) & (1ULL << 12) ? 12 : \ + (n) & (1ULL << 11) ? 11 : \ + (n) & (1ULL << 10) ? 10 : \ + (n) & (1ULL << 9) ? 9 : \ + (n) & (1ULL << 8) ? 8 : \ + (n) & (1ULL << 7) ? 7 : \ + (n) & (1ULL << 6) ? 6 : \ + (n) & (1ULL << 5) ? 5 : \ + (n) & (1ULL << 4) ? 4 : \ + (n) & (1ULL << 3) ? 3 : \ + (n) & (1ULL << 2) ? 2 : \ + (n) & (1ULL << 1) ? 1 : 0 \ +) + +#include "erofs_fs.h" diff --git a/composefs/libcomposefs/hash.c b/composefs/libcomposefs/hash.c new file mode 100644 index 0000000..918aa0d --- /dev/null +++ b/composefs/libcomposefs/hash.c @@ -0,0 +1,1106 @@ +/* hash - hashing table processing. + + Copyright (C) 1998-2004, 2006-2007, 2009-2023 Free Software Foundation, Inc. + + Written by Jim Meyering, 1992. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* A generic hash table package. */ + +/* Define USE_OBSTACK to 1 if you want the allocator to use obstacks instead + of malloc. If you change USE_OBSTACK, you have to recompile! */ + +#include + +#include "hash.h" + +#include "bitrotate.h" +#include "xalloc-oversized.h" + +#include +#include +#include + +#if USE_OBSTACK +# include "obstack.h" +# ifndef obstack_chunk_alloc +# define obstack_chunk_alloc malloc +# endif +# ifndef obstack_chunk_free +# define obstack_chunk_free free +# endif +#endif + +struct hash_entry + { + void *data; + struct hash_entry *next; + }; + +struct hash_table + { + /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1, + for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets + are not empty, there are N_ENTRIES active entries in the table. */ + struct hash_entry *bucket; + struct hash_entry const *bucket_limit; + size_t n_buckets; + size_t n_buckets_used; + size_t n_entries; + + /* Tuning arguments, kept in a physically separate structure. */ + const Hash_tuning *tuning; + + /* Three functions are given to 'hash_initialize', see the documentation + block for this function. In a word, HASHER randomizes a user entry + into a number up from 0 up to some maximum minus 1; COMPARATOR returns + true if two user entries compare equally; and DATA_FREER is the cleanup + function for a user entry. */ + Hash_hasher hasher; + Hash_comparator comparator; + Hash_data_freer data_freer; + + /* A linked list of freed struct hash_entry structs. */ + struct hash_entry *free_entry_list; + +#if USE_OBSTACK + /* Whenever obstacks are used, it is possible to allocate all overflowed + entries into a single stack, so they all can be freed in a single + operation. It is not clear if the speedup is worth the trouble. */ + struct obstack entry_stack; +#endif + }; + +/* A hash table contains many internal entries, each holding a pointer to + some user-provided data (also called a user entry). An entry indistinctly + refers to both the internal entry and its associated user entry. A user + entry contents may be hashed by a randomization function (the hashing + function, or just "hasher" for short) into a number (or "slot") between 0 + and the current table size. At each slot position in the hash table, + starts a linked chain of entries for which the user data all hash to this + slot. A bucket is the collection of all entries hashing to the same slot. + + A good "hasher" function will distribute entries rather evenly in buckets. + In the ideal case, the length of each bucket is roughly the number of + entries divided by the table size. Finding the slot for a data is usually + done in constant time by the "hasher", and the later finding of a precise + entry is linear in time with the size of the bucket. Consequently, a + larger hash table size (that is, a larger number of buckets) is prone to + yielding shorter chains, *given* the "hasher" function behaves properly. + + Long buckets slow down the lookup algorithm. One might use big hash table + sizes in hope to reduce the average length of buckets, but this might + become inordinate, as unused slots in the hash table take some space. The + best bet is to make sure you are using a good "hasher" function (beware + that those are not that easy to write! :-), and to use a table size + larger than the actual number of entries. */ + +/* If an insertion makes the ratio of nonempty buckets to table size larger + than the growth threshold (a number between 0.0 and 1.0), then increase + the table size by multiplying by the growth factor (a number greater than + 1.0). The growth threshold defaults to 0.8, and the growth factor + defaults to 1.414, meaning that the table will have doubled its size + every second time 80% of the buckets get used. */ +#define DEFAULT_GROWTH_THRESHOLD 0.8f +#define DEFAULT_GROWTH_FACTOR 1.414f + +/* If a deletion empties a bucket and causes the ratio of used buckets to + table size to become smaller than the shrink threshold (a number between + 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a + number greater than the shrink threshold but smaller than 1.0). The shrink + threshold and factor default to 0.0 and 1.0, meaning that the table never + shrinks. */ +#define DEFAULT_SHRINK_THRESHOLD 0.0f +#define DEFAULT_SHRINK_FACTOR 1.0f + +/* Use this to initialize or reset a TUNING structure to + some sensible values. */ +static const Hash_tuning default_tuning = + { + DEFAULT_SHRINK_THRESHOLD, + DEFAULT_SHRINK_FACTOR, + DEFAULT_GROWTH_THRESHOLD, + DEFAULT_GROWTH_FACTOR, + false + }; + +/* Information and lookup. */ + +size_t +hash_get_n_buckets (const Hash_table *table) +{ + return table->n_buckets; +} + +size_t +hash_get_n_buckets_used (const Hash_table *table) +{ + return table->n_buckets_used; +} + +size_t +hash_get_n_entries (const Hash_table *table) +{ + return table->n_entries; +} + +size_t +hash_get_max_bucket_length (const Hash_table *table) +{ + struct hash_entry const *bucket; + size_t max_bucket_length = 0; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + struct hash_entry const *cursor = bucket; + size_t bucket_length = 1; + + while (cursor = cursor->next, cursor) + bucket_length++; + + if (bucket_length > max_bucket_length) + max_bucket_length = bucket_length; + } + } + + return max_bucket_length; +} + +bool +hash_table_ok (const Hash_table *table) +{ + struct hash_entry const *bucket; + size_t n_buckets_used = 0; + size_t n_entries = 0; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + struct hash_entry const *cursor = bucket; + + /* Count bucket head. */ + n_buckets_used++; + n_entries++; + + /* Count bucket overflow. */ + while (cursor = cursor->next, cursor) + n_entries++; + } + } + + if (n_buckets_used == table->n_buckets_used && n_entries == table->n_entries) + return true; + + return false; +} + +void +hash_print_statistics (const Hash_table *table, FILE *stream) +{ + size_t n_entries = hash_get_n_entries (table); + size_t n_buckets = hash_get_n_buckets (table); + size_t n_buckets_used = hash_get_n_buckets_used (table); + size_t max_bucket_length = hash_get_max_bucket_length (table); + + fprintf (stream, "# entries: %lu\n", (unsigned long int) n_entries); + fprintf (stream, "# buckets: %lu\n", (unsigned long int) n_buckets); + fprintf (stream, "# buckets used: %lu (%.2f%%)\n", + (unsigned long int) n_buckets_used, + (100.0 * n_buckets_used) / n_buckets); + fprintf (stream, "max bucket length: %lu\n", + (unsigned long int) max_bucket_length); +} + +/* Hash KEY and return a pointer to the selected bucket. + If TABLE->hasher misbehaves, abort. */ +static struct hash_entry * +safe_hasher (const Hash_table *table, const void *key) +{ + size_t n = table->hasher (key, table->n_buckets); + if (! (n < table->n_buckets)) + abort (); + return table->bucket + n; +} + +void * +hash_lookup (const Hash_table *table, const void *entry) +{ + struct hash_entry const *bucket = safe_hasher (table, entry); + struct hash_entry const *cursor; + + if (bucket->data == NULL) + return NULL; + + for (cursor = bucket; cursor; cursor = cursor->next) + if (entry == cursor->data || table->comparator (entry, cursor->data)) + return cursor->data; + + return NULL; +} + +/* Walking. */ + +void * +hash_get_first (const Hash_table *table) +{ + struct hash_entry const *bucket; + + if (table->n_entries == 0) + return NULL; + + for (bucket = table->bucket; ; bucket++) + if (! (bucket < table->bucket_limit)) + abort (); + else if (bucket->data) + return bucket->data; +} + +void * +hash_get_next (const Hash_table *table, const void *entry) +{ + struct hash_entry const *bucket = safe_hasher (table, entry); + struct hash_entry const *cursor; + + /* Find next entry in the same bucket. */ + cursor = bucket; + do + { + if (cursor->data == entry && cursor->next) + return cursor->next->data; + cursor = cursor->next; + } + while (cursor != NULL); + + /* Find first entry in any subsequent bucket. */ + while (++bucket < table->bucket_limit) + if (bucket->data) + return bucket->data; + + /* None found. */ + return NULL; +} + +size_t +hash_get_entries (const Hash_table *table, void **buffer, + size_t buffer_size) +{ + size_t counter = 0; + struct hash_entry const *bucket; + struct hash_entry const *cursor; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + for (cursor = bucket; cursor; cursor = cursor->next) + { + if (counter >= buffer_size) + return counter; + buffer[counter++] = cursor->data; + } + } + } + + return counter; +} + +size_t +hash_do_for_each (const Hash_table *table, Hash_processor processor, + void *processor_data) +{ + size_t counter = 0; + struct hash_entry const *bucket; + struct hash_entry const *cursor; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + for (cursor = bucket; cursor; cursor = cursor->next) + { + if (! processor (cursor->data, processor_data)) + return counter; + counter++; + } + } + } + + return counter; +} + +/* Allocation and clean-up. */ + +#if USE_DIFF_HASH + +/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see + B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm, + Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash + algorithms tend to be domain-specific, so what's good for [diffutils'] io.c + may not be good for your application." */ + +size_t +hash_string (const char *string, size_t n_buckets) +{ +# define HASH_ONE_CHAR(Value, Byte) \ + ((Byte) + rotl_sz (Value, 7)) + + size_t value = 0; + unsigned char ch; + + for (; (ch = *string); string++) + value = HASH_ONE_CHAR (value, ch); + return value % n_buckets; + +# undef HASH_ONE_CHAR +} + +#else /* not USE_DIFF_HASH */ + +/* This one comes from 'recode', and performs a bit better than the above as + per a few experiments. It is inspired from a hashing routine found in the + very old Cyber 'snoop', itself written in typical Greg Mansfield style. + (By the way, what happened to this excellent man? Is he still alive?) */ + +size_t +hash_string (const char *string, size_t n_buckets) +{ + size_t value = 0; + unsigned char ch; + + for (; (ch = *string); string++) + value = (value * 31 + ch) % n_buckets; + return value; +} + +#endif /* not USE_DIFF_HASH */ + +/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd + number at least equal to 11. */ + +static bool _GL_ATTRIBUTE_CONST +is_prime (size_t candidate) +{ + size_t divisor = 3; + size_t square = divisor * divisor; + + while (square < candidate && (candidate % divisor)) + { + divisor++; + square += 4 * divisor; + divisor++; + } + + return (candidate % divisor ? true : false); +} + +/* Round a given CANDIDATE number up to the nearest prime, and return that + prime. Primes lower than 10 are merely skipped. */ + +static size_t _GL_ATTRIBUTE_CONST +next_prime (size_t candidate) +{ + /* Skip small primes. */ + if (candidate < 10) + candidate = 10; + + /* Make it definitely odd. */ + candidate |= 1; + + while (SIZE_MAX != candidate && !is_prime (candidate)) + candidate += 2; + + return candidate; +} + +void +hash_reset_tuning (Hash_tuning *tuning) +{ + *tuning = default_tuning; +} + +/* If the user passes a NULL hasher, we hash the raw pointer. */ +static size_t +raw_hasher (const void *data, size_t n) +{ + /* When hashing unique pointers, it is often the case that they were + generated by malloc and thus have the property that the low-order + bits are 0. As this tends to give poorer performance with small + tables, we rotate the pointer value before performing division, + in an attempt to improve hash quality. */ + size_t val = rotr_sz ((size_t) data, 3); + return val % n; +} + +/* If the user passes a NULL comparator, we use pointer comparison. */ +static bool +raw_comparator (const void *a, const void *b) +{ + return a == b; +} + + +/* For the given hash TABLE, check the user supplied tuning structure for + reasonable values, and return true if there is no gross error with it. + Otherwise, definitively reset the TUNING field to some acceptable default + in the hash table (that is, the user loses the right of further modifying + tuning arguments), and return false. */ + +static bool +check_tuning (Hash_table *table) +{ + const Hash_tuning *tuning = table->tuning; + float epsilon; + if (tuning == &default_tuning) + return true; + + /* Be a bit stricter than mathematics would require, so that + rounding errors in size calculations do not cause allocations to + fail to grow or shrink as they should. The smallest allocation + is 11 (due to next_prime's algorithm), so an epsilon of 0.1 + should be good enough. */ + epsilon = 0.1f; + + if (epsilon < tuning->growth_threshold + && tuning->growth_threshold < 1 - epsilon + && 1 + epsilon < tuning->growth_factor + && 0 <= tuning->shrink_threshold + && tuning->shrink_threshold + epsilon < tuning->shrink_factor + && tuning->shrink_factor <= 1 + && tuning->shrink_threshold + epsilon < tuning->growth_threshold) + return true; + + table->tuning = &default_tuning; + return false; +} + +/* Compute the size of the bucket array for the given CANDIDATE and + TUNING, or return 0 if there is no possible way to allocate that + many entries. */ + +static size_t _GL_ATTRIBUTE_PURE +compute_bucket_size (size_t candidate, const Hash_tuning *tuning) +{ + if (!tuning->is_n_buckets) + { + float new_candidate = candidate / tuning->growth_threshold; + if ((float) SIZE_MAX <= new_candidate) + return 0; + candidate = new_candidate; + } + candidate = next_prime (candidate); + if (xalloc_oversized (candidate, sizeof (struct hash_entry *))) + return 0; + return candidate; +} + +Hash_table * +hash_initialize (size_t candidate, const Hash_tuning *tuning, + Hash_hasher hasher, Hash_comparator comparator, + Hash_data_freer data_freer) +{ + Hash_table *table; + + if (hasher == NULL) + hasher = raw_hasher; + if (comparator == NULL) + comparator = raw_comparator; + + table = malloc (sizeof *table); + if (table == NULL) + return NULL; + + if (!tuning) + tuning = &default_tuning; + table->tuning = tuning; + if (!check_tuning (table)) + { + /* Fail if the tuning options are invalid. This is the only occasion + when the user gets some feedback about it. Once the table is created, + if the user provides invalid tuning options, we silently revert to + using the defaults, and ignore further request to change the tuning + options. */ + goto fail; + } + + table->n_buckets = compute_bucket_size (candidate, tuning); + if (!table->n_buckets) + goto fail; + + table->bucket = calloc (table->n_buckets, sizeof *table->bucket); + if (table->bucket == NULL) + goto fail; + table->bucket_limit = table->bucket + table->n_buckets; + table->n_buckets_used = 0; + table->n_entries = 0; + + table->hasher = hasher; + table->comparator = comparator; + table->data_freer = data_freer; + + table->free_entry_list = NULL; +#if USE_OBSTACK + obstack_init (&table->entry_stack); +#endif + return table; + + fail: + free (table); + return NULL; +} + +void +hash_clear (Hash_table *table) +{ + struct hash_entry *bucket; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + struct hash_entry *cursor; + struct hash_entry *next; + + /* Free the bucket overflow. */ + for (cursor = bucket->next; cursor; cursor = next) + { + if (table->data_freer) + table->data_freer (cursor->data); + cursor->data = NULL; + + next = cursor->next; + /* Relinking is done one entry at a time, as it is to be expected + that overflows are either rare or short. */ + cursor->next = table->free_entry_list; + table->free_entry_list = cursor; + } + + /* Free the bucket head. */ + if (table->data_freer) + table->data_freer (bucket->data); + bucket->data = NULL; + bucket->next = NULL; + } + } + + table->n_buckets_used = 0; + table->n_entries = 0; +} + +void +hash_free (Hash_table *table) +{ + struct hash_entry *bucket; + struct hash_entry *cursor; + struct hash_entry *next; + + /* Call the user data_freer function. */ + if (table->data_freer && table->n_entries) + { + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + for (cursor = bucket; cursor; cursor = cursor->next) + table->data_freer (cursor->data); + } + } + } + +#if USE_OBSTACK + + obstack_free (&table->entry_stack, NULL); + +#else + + /* Free all bucket overflowed entries. */ + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + for (cursor = bucket->next; cursor; cursor = next) + { + next = cursor->next; + free (cursor); + } + } + + /* Also reclaim the internal list of previously freed entries. */ + for (cursor = table->free_entry_list; cursor; cursor = next) + { + next = cursor->next; + free (cursor); + } + +#endif + + /* Free the remainder of the hash table structure. */ + free (table->bucket); + free (table); +} + +/* Insertion and deletion. */ + +/* Get a new hash entry for a bucket overflow, possibly by recycling a + previously freed one. If this is not possible, allocate a new one. */ + +static struct hash_entry * +allocate_entry (Hash_table *table) +{ + struct hash_entry *new; + + if (table->free_entry_list) + { + new = table->free_entry_list; + table->free_entry_list = new->next; + } + else + { +#if USE_OBSTACK + new = obstack_alloc (&table->entry_stack, sizeof *new); +#else + new = malloc (sizeof *new); +#endif + } + + return new; +} + +/* Free a hash entry which was part of some bucket overflow, + saving it for later recycling. */ + +static void +free_entry (Hash_table *table, struct hash_entry *entry) +{ + entry->data = NULL; + entry->next = table->free_entry_list; + table->free_entry_list = entry; +} + +/* This private function is used to help with insertion and deletion. When + ENTRY matches an entry in the table, return a pointer to the corresponding + user data and set *BUCKET_HEAD to the head of the selected bucket. + Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in + the table, unlink the matching entry. */ + +static void * +hash_find_entry (Hash_table *table, const void *entry, + struct hash_entry **bucket_head, bool delete) +{ + struct hash_entry *bucket = safe_hasher (table, entry); + struct hash_entry *cursor; + + *bucket_head = bucket; + + /* Test for empty bucket. */ + if (bucket->data == NULL) + return NULL; + + /* See if the entry is the first in the bucket. */ + if (entry == bucket->data || table->comparator (entry, bucket->data)) + { + void *data = bucket->data; + + if (delete) + { + if (bucket->next) + { + struct hash_entry *next = bucket->next; + + /* Bump the first overflow entry into the bucket head, then save + the previous first overflow entry for later recycling. */ + *bucket = *next; + free_entry (table, next); + } + else + { + bucket->data = NULL; + } + } + + return data; + } + + /* Scan the bucket overflow. */ + for (cursor = bucket; cursor->next; cursor = cursor->next) + { + if (entry == cursor->next->data + || table->comparator (entry, cursor->next->data)) + { + void *data = cursor->next->data; + + if (delete) + { + struct hash_entry *next = cursor->next; + + /* Unlink the entry to delete, then save the freed entry for later + recycling. */ + cursor->next = next->next; + free_entry (table, next); + } + + return data; + } + } + + /* No entry found. */ + return NULL; +} + +/* Internal helper, to move entries from SRC to DST. Both tables must + share the same free entry list. If SAFE, only move overflow + entries, saving bucket heads for later, so that no allocations will + occur. Return false if the free entry list is exhausted and an + allocation fails. */ + +static bool +transfer_entries (Hash_table *dst, Hash_table *src, bool safe) +{ + struct hash_entry *bucket; + struct hash_entry *cursor; + struct hash_entry *next; + for (bucket = src->bucket; bucket < src->bucket_limit; bucket++) + if (bucket->data) + { + void *data; + struct hash_entry *new_bucket; + + /* Within each bucket, transfer overflow entries first and + then the bucket head, to minimize memory pressure. After + all, the only time we might allocate is when moving the + bucket head, but moving overflow entries first may create + free entries that can be recycled by the time we finally + get to the bucket head. */ + for (cursor = bucket->next; cursor; cursor = next) + { + data = cursor->data; + new_bucket = safe_hasher (dst, data); + + next = cursor->next; + + if (new_bucket->data) + { + /* Merely relink an existing entry, when moving from a + bucket overflow into a bucket overflow. */ + cursor->next = new_bucket->next; + new_bucket->next = cursor; + } + else + { + /* Free an existing entry, when moving from a bucket + overflow into a bucket header. */ + new_bucket->data = data; + dst->n_buckets_used++; + free_entry (dst, cursor); + } + } + /* Now move the bucket head. Be sure that if we fail due to + allocation failure that the src table is in a consistent + state. */ + data = bucket->data; + bucket->next = NULL; + if (safe) + continue; + new_bucket = safe_hasher (dst, data); + + if (new_bucket->data) + { + /* Allocate or recycle an entry, when moving from a bucket + header into a bucket overflow. */ + struct hash_entry *new_entry = allocate_entry (dst); + + if (new_entry == NULL) + return false; + + new_entry->data = data; + new_entry->next = new_bucket->next; + new_bucket->next = new_entry; + } + else + { + /* Move from one bucket header to another. */ + new_bucket->data = data; + dst->n_buckets_used++; + } + bucket->data = NULL; + src->n_buckets_used--; + } + return true; +} + +bool +hash_rehash (Hash_table *table, size_t candidate) +{ + Hash_table storage; + Hash_table *new_table; + size_t new_size = compute_bucket_size (candidate, table->tuning); + + if (!new_size) + return false; + if (new_size == table->n_buckets) + return true; + new_table = &storage; + new_table->bucket = calloc (new_size, sizeof *new_table->bucket); + if (new_table->bucket == NULL) + return false; + new_table->n_buckets = new_size; + new_table->bucket_limit = new_table->bucket + new_size; + new_table->n_buckets_used = 0; + new_table->n_entries = 0; + new_table->tuning = table->tuning; + new_table->hasher = table->hasher; + new_table->comparator = table->comparator; + new_table->data_freer = table->data_freer; + + /* In order for the transfer to successfully complete, we need + additional overflow entries when distinct buckets in the old + table collide into a common bucket in the new table. The worst + case possible is a hasher that gives a good spread with the old + size, but returns a constant with the new size; if we were to + guarantee table->n_buckets_used-1 free entries in advance, then + the transfer would be guaranteed to not allocate memory. + However, for large tables, a guarantee of no further allocation + introduces a lot of extra memory pressure, all for an unlikely + corner case (most rehashes reduce, rather than increase, the + number of overflow entries needed). So, we instead ensure that + the transfer process can be reversed if we hit a memory + allocation failure mid-transfer. */ + + /* Merely reuse the extra old space into the new table. */ +#if USE_OBSTACK + new_table->entry_stack = table->entry_stack; +#endif + new_table->free_entry_list = table->free_entry_list; + + if (transfer_entries (new_table, table, false)) + { + /* Entries transferred successfully; tie up the loose ends. */ + free (table->bucket); + table->bucket = new_table->bucket; + table->bucket_limit = new_table->bucket_limit; + table->n_buckets = new_table->n_buckets; + table->n_buckets_used = new_table->n_buckets_used; + table->free_entry_list = new_table->free_entry_list; + /* table->n_entries and table->entry_stack already hold their value. */ + return true; + } + + /* We've allocated new_table->bucket (and possibly some entries), + exhausted the free list, and moved some but not all entries into + new_table. We must undo the partial move before returning + failure. The only way to get into this situation is if new_table + uses fewer buckets than the old table, so we will reclaim some + free entries as overflows in the new table are put back into + distinct buckets in the old table. + + There are some pathological cases where a single pass through the + table requires more intermediate overflow entries than using two + passes. Two passes give worse cache performance and takes + longer, but at this point, we're already out of memory, so slow + and safe is better than failure. */ + table->free_entry_list = new_table->free_entry_list; + if (! (transfer_entries (table, new_table, true) + && transfer_entries (table, new_table, false))) + abort (); + /* table->n_entries already holds its value. */ + free (new_table->bucket); + return false; +} + +int +hash_insert_if_absent (Hash_table *table, void const *entry, + void const **matched_ent) +{ + void *data; + struct hash_entry *bucket; + + /* The caller cannot insert a NULL entry, since hash_lookup returns NULL + to indicate "not found", and hash_find_entry uses "bucket->data == NULL" + to indicate an empty bucket. */ + if (! entry) + abort (); + + /* If there's a matching entry already in the table, return that. */ + if ((data = hash_find_entry (table, entry, &bucket, false)) != NULL) + { + if (matched_ent) + *matched_ent = data; + return 0; + } + + /* If the growth threshold of the buckets in use has been reached, increase + the table size and rehash. There's no point in checking the number of + entries: if the hashing function is ill-conditioned, rehashing is not + likely to improve it. */ + + if (table->n_buckets_used + > table->tuning->growth_threshold * table->n_buckets) + { + /* Check more fully, before starting real work. If tuning arguments + became invalid, the second check will rely on proper defaults. */ + check_tuning (table); + if (table->n_buckets_used + > table->tuning->growth_threshold * table->n_buckets) + { + const Hash_tuning *tuning = table->tuning; + float candidate = + (tuning->is_n_buckets + ? (table->n_buckets * tuning->growth_factor) + : (table->n_buckets * tuning->growth_factor + * tuning->growth_threshold)); + + if ((float) SIZE_MAX <= candidate) + return -1; + + /* If the rehash fails, arrange to return NULL. */ + if (!hash_rehash (table, candidate)) + return -1; + + /* Update the bucket we are interested in. */ + if (hash_find_entry (table, entry, &bucket, false) != NULL) + abort (); + } + } + + /* ENTRY is not matched, it should be inserted. */ + + if (bucket->data) + { + struct hash_entry *new_entry = allocate_entry (table); + + if (new_entry == NULL) + return -1; + + /* Add ENTRY in the overflow of the bucket. */ + + new_entry->data = (void *) entry; + new_entry->next = bucket->next; + bucket->next = new_entry; + table->n_entries++; + return 1; + } + + /* Add ENTRY right in the bucket head. */ + + bucket->data = (void *) entry; + table->n_entries++; + table->n_buckets_used++; + + return 1; +} + +void * +hash_insert (Hash_table *table, void const *entry) +{ + void const *matched_ent; + int err = hash_insert_if_absent (table, entry, &matched_ent); + return (err == -1 + ? NULL + : (void *) (err == 0 ? matched_ent : entry)); +} + +void * +hash_remove (Hash_table *table, const void *entry) +{ + void *data; + struct hash_entry *bucket; + + data = hash_find_entry (table, entry, &bucket, true); + if (!data) + return NULL; + + table->n_entries--; + if (!bucket->data) + { + table->n_buckets_used--; + + /* If the shrink threshold of the buckets in use has been reached, + rehash into a smaller table. */ + + if (table->n_buckets_used + < table->tuning->shrink_threshold * table->n_buckets) + { + /* Check more fully, before starting real work. If tuning arguments + became invalid, the second check will rely on proper defaults. */ + check_tuning (table); + if (table->n_buckets_used + < table->tuning->shrink_threshold * table->n_buckets) + { + const Hash_tuning *tuning = table->tuning; + size_t candidate = + (tuning->is_n_buckets + ? table->n_buckets * tuning->shrink_factor + : (table->n_buckets * tuning->shrink_factor + * tuning->growth_threshold)); + + if (!hash_rehash (table, candidate)) + { + /* Failure to allocate memory in an attempt to + shrink the table is not fatal. But since memory + is low, we can at least be kind and free any + spare entries, rather than keeping them tied up + in the free entry list. */ +#if ! USE_OBSTACK + struct hash_entry *cursor = table->free_entry_list; + struct hash_entry *next; + while (cursor) + { + next = cursor->next; + free (cursor); + cursor = next; + } + table->free_entry_list = NULL; +#endif + } + } + } + } + + return data; +} + +void * +hash_delete (Hash_table *table, const void *entry) +{ + return hash_remove (table, entry); +} + +/* Testing. */ + +#if TESTING + +void +hash_print (const Hash_table *table) +{ + struct hash_entry *bucket = (struct hash_entry *) table->bucket; + + for ( ; bucket < table->bucket_limit; bucket++) + { + struct hash_entry *cursor; + + if (bucket) + printf ("%lu:\n", (unsigned long int) (bucket - table->bucket)); + + for (cursor = bucket; cursor; cursor = cursor->next) + { + char const *s = cursor->data; + /* FIXME */ + if (s) + printf (" %s\n", s); + } + } +} + +#endif /* TESTING */ diff --git a/composefs/libcomposefs/hash.h b/composefs/libcomposefs/hash.h new file mode 100644 index 0000000..7b80859 --- /dev/null +++ b/composefs/libcomposefs/hash.h @@ -0,0 +1,277 @@ +/* hash - hashing table processing. + Copyright (C) 1998-1999, 2001, 2003, 2009-2023 Free Software Foundation, + Inc. + Written by Jim Meyering , 1998. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* A generic hash table package. */ + +/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use + obstacks instead of malloc, and recompile 'hash.c' with same setting. */ + +#ifndef HASH_H_ +# define HASH_H_ + +# include + +# include +# include + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The attribute __pure__ was added in gcc 2.96. */ +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated)) +# define _GL_ATTRIBUTE_NODISCARD +# define _GL_ATTRIBUTE_RETURNS_NONNULL +# define _GL_ATTRIBUTE_MALLOC +# define _GL_ATTRIBUTE_DEALLOC(_a,_b) + +# include + +# ifdef __cplusplus +extern "C" { +# endif + +struct hash_tuning + { + /* This structure is mainly used for 'hash_initialize', see the block + documentation of 'hash_reset_tuning' for more complete comments. */ + + float shrink_threshold; /* ratio of used buckets to trigger a shrink */ + float shrink_factor; /* ratio of new smaller size to original size */ + float growth_threshold; /* ratio of used buckets to trigger a growth */ + float growth_factor; /* ratio of new bigger size to original size */ + bool is_n_buckets; /* if CANDIDATE really means table size */ + }; + +typedef struct hash_tuning Hash_tuning; + +struct hash_table; + +typedef struct hash_table Hash_table; + +/* + * Information and lookup. + */ + +/* The following few functions provide information about the overall hash + table organization: the number of entries, number of buckets and maximum + length of buckets. */ + +/* Return the number of buckets in the hash table. The table size, the total + number of buckets (used plus unused), or the maximum number of slots, are + the same quantity. */ +extern size_t hash_get_n_buckets (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the number of slots in use (non-empty buckets). */ +extern size_t hash_get_n_buckets_used (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the number of active entries. */ +extern size_t hash_get_n_entries (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the length of the longest chain (bucket). */ +extern size_t hash_get_max_bucket_length (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Do a mild validation of a hash table, by traversing it and checking two + statistics. */ +extern bool hash_table_ok (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +extern void hash_print_statistics (const Hash_table *table, FILE *stream); + +/* If ENTRY matches an entry already in the hash table, return the + entry from the table. Otherwise, return NULL. */ +extern void *hash_lookup (const Hash_table *table, const void *entry); + +/* + * Walking. + */ + +/* The functions in this page traverse the hash table and process the + contained entries. For the traversal to work properly, the hash table + should not be resized nor modified while any particular entry is being + processed. In particular, entries should not be added, and an entry + may be removed only if there is no shrink threshold and the entry being + removed has already been passed to hash_get_next. */ + +/* Return the first data in the table, or NULL if the table is empty. */ +extern void *hash_get_first (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the user data for the entry following ENTRY, where ENTRY has been + returned by a previous call to either 'hash_get_first' or 'hash_get_next'. + Return NULL if there are no more entries. */ +extern void *hash_get_next (const Hash_table *table, const void *entry); + +/* Fill BUFFER with pointers to active user entries in the hash table, then + return the number of pointers copied. Do not copy more than BUFFER_SIZE + pointers. */ +extern size_t hash_get_entries (const Hash_table *table, void **buffer, + size_t buffer_size); + +typedef bool (*Hash_processor) (void *entry, void *processor_data); + +/* Call a PROCESSOR function for each entry of a hash table, and return the + number of entries for which the processor function returned success. A + pointer to some PROCESSOR_DATA which will be made available to each call to + the processor function. The PROCESSOR accepts two arguments: the first is + the user entry being walked into, the second is the value of PROCESSOR_DATA + as received. The walking continue for as long as the PROCESSOR function + returns nonzero. When it returns zero, the walking is interrupted. */ +extern size_t hash_do_for_each (const Hash_table *table, + Hash_processor processor, void *processor_data); + +/* + * Allocation and clean-up. + */ + +/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1. + This is a convenience routine for constructing other hashing functions. */ +extern size_t hash_string (const char *string, size_t n_buckets) + _GL_ATTRIBUTE_PURE; + +extern void hash_reset_tuning (Hash_tuning *tuning); + +typedef size_t (*Hash_hasher) (const void *entry, size_t table_size); +typedef bool (*Hash_comparator) (const void *entry1, const void *entry2); +typedef void (*Hash_data_freer) (void *entry); + +/* Reclaim all storage associated with a hash table. If a data_freer + function has been supplied by the user when the hash table was created, + this function applies it to the data of each entry before freeing that + entry. */ +extern void hash_free (Hash_table *table); + +/* Allocate and return a new hash table, or NULL upon failure. The initial + number of buckets is automatically selected so as to _guarantee_ that you + may insert at least CANDIDATE different user entries before any growth of + the hash table size occurs. So, if have a reasonably tight a-priori upper + bound on the number of entries you intend to insert in the hash table, you + may save some table memory and insertion time, by specifying it here. If + the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE + argument has its meaning changed to the wanted number of buckets. + + TUNING points to a structure of user-supplied values, in case some fine + tuning is wanted over the default behavior of the hasher. If TUNING is + NULL, the default tuning parameters are used instead. If TUNING is + provided but the values requested are out of bounds or might cause + rounding errors, return NULL. + + The user-supplied HASHER function, when not NULL, accepts two + arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a + slot number for that entry which should be in the range 0..TABLE_SIZE-1. + This slot number is then returned. + + The user-supplied COMPARATOR function, when not NULL, accepts two + arguments pointing to user data, it then returns true for a pair of entries + that compare equal, or false otherwise. This function is internally called + on entries which are already known to hash to the same bucket index, + but which are distinct pointers. + + The user-supplied DATA_FREER function, when not NULL, may be later called + with the user data as an argument, just before the entry containing the + data gets freed. This happens from within 'hash_free' or 'hash_clear'. + You should specify this function only if you want these functions to free + all of your 'data' data. This is typically the case when your data is + simply an auxiliary struct that you have malloc'd to aggregate several + values. */ +_GL_ATTRIBUTE_NODISCARD +extern Hash_table *hash_initialize (size_t candidate, + const Hash_tuning *tuning, + Hash_hasher hasher, + Hash_comparator comparator, + Hash_data_freer data_freer) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (hash_free, 1); + +/* Same as hash_initialize, but invokes xalloc_die on memory exhaustion. */ +/* This function is defined by module 'xhash'. */ +_GL_ATTRIBUTE_NODISCARD +extern Hash_table *hash_xinitialize (size_t candidate, + const Hash_tuning *tuning, + Hash_hasher hasher, + Hash_comparator comparator, + Hash_data_freer data_freer) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (hash_free, 1) + _GL_ATTRIBUTE_RETURNS_NONNULL; + +/* Make all buckets empty, placing any chained entries on the free list. + Apply the user-specified function data_freer (if any) to the datas of any + affected entries. */ +extern void hash_clear (Hash_table *table); + +/* + * Insertion and deletion. + */ + +/* For an already existing hash table, change the number of buckets through + specifying CANDIDATE. The contents of the hash table are preserved. The + new number of buckets is automatically selected so as to _guarantee_ that + the table may receive at least CANDIDATE different user entries, including + those already in the table, before any other growth of the hash table size + occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the + exact number of buckets desired. Return true iff the rehash succeeded. */ +_GL_ATTRIBUTE_NODISCARD +extern bool hash_rehash (Hash_table *table, size_t candidate); + +/* If ENTRY matches an entry already in the hash table, return the pointer + to the entry from the table. Otherwise, insert ENTRY and return ENTRY. + Return NULL if the storage required for insertion cannot be allocated. + This implementation does not support duplicate entries or insertion of + NULL. */ +_GL_ATTRIBUTE_NODISCARD +extern void *hash_insert (Hash_table *table, const void *entry); + +/* Same as hash_insert, but invokes xalloc_die on memory exhaustion. */ +/* This function is defined by module 'xhash'. */ +extern void *hash_xinsert (Hash_table *table, const void *entry); + +/* Insert ENTRY into hash TABLE if there is not already a matching entry. + + Return -1 upon memory allocation failure. + Return 1 if insertion succeeded. + Return 0 if there is already a matching entry in the table, + and in that case, if MATCHED_ENT is non-NULL, set *MATCHED_ENT + to that entry. + + This interface is easier to use than hash_insert when you must + distinguish between the latter two cases. More importantly, + hash_insert is unusable for some types of ENTRY values. When using + hash_insert, the only way to distinguish those cases is to compare + the return value and ENTRY. That works only when you can have two + different ENTRY values that point to data that compares "equal". Thus, + when the ENTRY value is a simple scalar, you must use + hash_insert_if_absent. ENTRY must not be NULL. */ +extern int hash_insert_if_absent (Hash_table *table, const void *entry, + const void **matched_ent); + +/* If ENTRY is already in the table, remove it and return the just-deleted + data (the user may want to deallocate its storage). If ENTRY is not in the + table, don't modify the table and return NULL. */ +extern void *hash_remove (Hash_table *table, const void *entry); + +/* Same as hash_remove. This interface is deprecated. + FIXME: Remove in 2022. */ +_GL_ATTRIBUTE_DEPRECATED +extern void *hash_delete (Hash_table *table, const void *entry); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/composefs/libcomposefs/lcfs-erofs-internal.h b/composefs/libcomposefs/lcfs-erofs-internal.h new file mode 100644 index 0000000..f6f7a97 --- /dev/null +++ b/composefs/libcomposefs/lcfs-erofs-internal.h @@ -0,0 +1,134 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _LCFS_EROFS_INTERNAL_H +#define _LCFS_EROFS_INTERNAL_H + +#include + +#include "lcfs-internal.h" +#include "lcfs-erofs.h" +#include "erofs_fs_wrapper.h" + +typedef union { + __le16 i_format; + struct erofs_inode_compact compact; + struct erofs_inode_extended extended; +} erofs_inode; + +static const char *erofs_xattr_prefixes[] = { + "", + "user.", + "system.posix_acl_access", + "system.posix_acl_default", + "trusted.", + "lustre.", + "security.", +}; + +static inline uint16_t erofs_inode_version(const erofs_inode *cino) +{ + uint16_t i_format = lcfs_u16_from_file(cino->i_format); + return (i_format >> EROFS_I_VERSION_BIT) & EROFS_I_VERSION_MASK; +} + +static inline bool erofs_inode_is_compact(const erofs_inode *cino) +{ + return erofs_inode_version(cino) == 0; +} + +static inline uint16_t erofs_inode_datalayout(const erofs_inode *cino) +{ + uint16_t i_format = lcfs_u16_from_file(cino->i_format); + return (i_format >> EROFS_I_DATALAYOUT_BIT) & EROFS_I_DATALAYOUT_MASK; +} + +static inline bool erofs_inode_is_tailpacked(const erofs_inode *cino) +{ + return erofs_inode_datalayout(cino) == EROFS_INODE_FLAT_INLINE; +} + +static inline bool erofs_inode_is_flat(const erofs_inode *cino) +{ + return erofs_inode_datalayout(cino) == EROFS_INODE_FLAT_INLINE || + erofs_inode_datalayout(cino) == EROFS_INODE_FLAT_PLAIN; +} + +static inline size_t erofs_xattr_inode_size(uint16_t xattr_icount) +{ + size_t xattr_size = 0; + if (xattr_icount > 0) + xattr_size = sizeof(struct erofs_xattr_ibody_header) + + (xattr_icount - 1) * 4; + return xattr_size; +} + +#define EROFS_N_XATTR_PREFIXES (sizeof(erofs_xattr_prefixes) / sizeof(char *)) + +static inline bool erofs_is_acl_xattr(int prefix, const char *name, size_t name_len) +{ + const char *const nfs_acl = "system.nfs4_acl"; + + if ((prefix == EROFS_XATTR_INDEX_POSIX_ACL_ACCESS || + prefix == EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT) && + name_len == 0) + return true; + if (prefix == 0 && name_len == strlen(nfs_acl) && + memcmp(name, nfs_acl, strlen(nfs_acl)) == 0) + return true; + return false; +} + +static inline int erofs_get_xattr_prefix(const char *str) +{ + for (int i = 1; i < EROFS_N_XATTR_PREFIXES; i++) { + const char *prefix = erofs_xattr_prefixes[i]; + if (strlen(str) >= strlen(prefix) && + memcmp(str, prefix, strlen(prefix)) == 0) { + return i; + } + } + return 0; +} + +static inline char *erofs_get_xattr_name(uint8_t index, const char *name, + size_t name_len) +{ + char *res; + const char *prefix; + size_t prefix_len; + + if (index >= EROFS_N_XATTR_PREFIXES) { + errno = EINVAL; + return NULL; + } + + prefix = erofs_xattr_prefixes[index]; + prefix_len = strlen(prefix); + + res = malloc(prefix_len + name_len + 1); + if (res == NULL) { + errno = ENOMEM; + return NULL; + } + memcpy(res, prefix, prefix_len); + memcpy(res + prefix_len, name, name_len); + res[prefix_len + name_len] = 0; + + return res; +} + +#endif diff --git a/composefs/libcomposefs/lcfs-erofs.h b/composefs/libcomposefs/lcfs-erofs.h new file mode 100644 index 0000000..0e607f8 --- /dev/null +++ b/composefs/libcomposefs/lcfs-erofs.h @@ -0,0 +1,36 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _LCFS_EROFS_H +#define _LCFS_EROFS_H + +#include + +#define LCFS_EROFS_VERSION 1 +#define LCFS_EROFS_MAGIC 0xd078629aU + +typedef enum { + LCFS_EROFS_FLAGS_HAS_ACL = (1 << 0), +} lcfs_erofs_flag_t; + +struct lcfs_erofs_header_s { + uint32_t magic; + uint32_t version; + uint32_t flags; + uint32_t unused[5]; +} __attribute__((__packed__)); + +#endif diff --git a/composefs/libcomposefs/lcfs-fsverity.c b/composefs/libcomposefs/lcfs-fsverity.c new file mode 100644 index 0000000..4949dd9 --- /dev/null +++ b/composefs/libcomposefs/lcfs-fsverity.c @@ -0,0 +1,457 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SHA256_DATASIZE 64 + +#ifdef HAVE_OPENSSL +/* For sha256 computation */ +#include + +#else /* SHA256 fallback implementation */ + +typedef struct { + uint32_t buf[8]; + uint32_t bits[2]; + + uint8_t data[SHA256_DATASIZE]; +} Sha256sum; + +/* + * SHA-256 Checksum + */ + +/* adapted from the SHA256 implementation in glib, which is originally: + * + * Copyright (C) 2006 Dave Benson + * Released under the terms of the GNU Lesser General Public License + */ + +static void sha256_sum_init(Sha256sum *sha256) +{ + sha256->buf[0] = 0x6a09e667; + sha256->buf[1] = 0xbb67ae85; + sha256->buf[2] = 0x3c6ef372; + sha256->buf[3] = 0xa54ff53a; + sha256->buf[4] = 0x510e527f; + sha256->buf[5] = 0x9b05688c; + sha256->buf[6] = 0x1f83d9ab; + sha256->buf[7] = 0x5be0cd19; + + sha256->bits[0] = sha256->bits[1] = 0; +} + +#define GET_UINT32(n, b, i) \ + do { \ + (n) = ((uint32_t)(b)[(i)] << 24) | \ + ((uint32_t)(b)[(i) + 1] << 16) | \ + ((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]); \ + } while (0) + +#define PUT_UINT32(n, b, i) \ + do { \ + (b)[(i)] = (uint8_t)((n) >> 24); \ + (b)[(i) + 1] = (uint8_t)((n) >> 16); \ + (b)[(i) + 2] = (uint8_t)((n) >> 8); \ + (b)[(i) + 3] = (uint8_t)((n)); \ + } while (0) + +static void sha256_transform(uint32_t buf[8], uint8_t const data[64]) +{ + uint32_t temp1, temp2, W[64]; + uint32_t A, B, C, D, E, F, G, H; + + GET_UINT32(W[0], data, 0); + GET_UINT32(W[1], data, 4); + GET_UINT32(W[2], data, 8); + GET_UINT32(W[3], data, 12); + GET_UINT32(W[4], data, 16); + GET_UINT32(W[5], data, 20); + GET_UINT32(W[6], data, 24); + GET_UINT32(W[7], data, 28); + GET_UINT32(W[8], data, 32); + GET_UINT32(W[9], data, 36); + GET_UINT32(W[10], data, 40); + GET_UINT32(W[11], data, 44); + GET_UINT32(W[12], data, 48); + GET_UINT32(W[13], data, 52); + GET_UINT32(W[14], data, 56); + GET_UINT32(W[15], data, 60); + +#define SHR(x, n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x, n) (SHR(x, n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) +#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) + +#define F0(x, y, z) ((x & y) | (z & (x | y))) +#define F1(x, y, z) (z ^ (x & (y ^ z))) + +#define R(t) (W[t] = S1(W[t - 2]) + W[t - 7] + S0(W[t - 15]) + W[t - 16]) + +#define P(a, b, c, d, e, f, g, h, x, K) \ + do { \ + temp1 = h + S3(e) + F1(e, f, g) + K + x; \ + temp2 = S2(a) + F0(a, b, c); \ + d += temp1; \ + h = temp1 + temp2; \ + } while (0) + + A = buf[0]; + B = buf[1]; + C = buf[2]; + D = buf[3]; + E = buf[4]; + F = buf[5]; + G = buf[6]; + H = buf[7]; + + P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98); + P(H, A, B, C, D, E, F, G, W[1], 0x71374491); + P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF); + P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5); + P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B); + P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1); + P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4); + P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5); + P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98); + P(H, A, B, C, D, E, F, G, W[9], 0x12835B01); + P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); + P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); + P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); + P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); + P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); + P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); + P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); + P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); + P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); + P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); + P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); + P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); + P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); + P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); + P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); + P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); + P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); + P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); + P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); + P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); + P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); + P(B, C, D, E, F, G, H, A, R(31), 0x14292967); + P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); + P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); + P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); + P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); + P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); + P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); + P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); + P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); + P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); + P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); + P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); + P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); + P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); + P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); + P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); + P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); + P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); + P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); + P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); + P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); + P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); + P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); + P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); + P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); + P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); + P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); + P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); + P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); + P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); + P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); + P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); + P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); + +#undef SHR +#undef ROTR +#undef S0 +#undef S1 +#undef S2 +#undef S3 +#undef F0 +#undef F1 +#undef R +#undef P + + buf[0] += A; + buf[1] += B; + buf[2] += C; + buf[3] += D; + buf[4] += E; + buf[5] += F; + buf[6] += G; + buf[7] += H; +} + +static void sha256_sum_update(Sha256sum *sha256, const uint8_t *buffer, size_t length) +{ + uint32_t left, fill; + const uint8_t *input = buffer; + + if (length == 0) + return; + + left = sha256->bits[0] & 0x3F; + fill = 64 - left; + + sha256->bits[0] += length; + sha256->bits[0] &= 0xFFFFFFFF; + + if (sha256->bits[0] < length) + sha256->bits[1]++; + + if (left > 0 && length >= fill) { + memcpy((sha256->data + left), input, fill); + + sha256_transform(sha256->buf, sha256->data); + length -= fill; + input += fill; + + left = 0; + } + + while (length >= SHA256_DATASIZE) { + sha256_transform(sha256->buf, input); + + length -= 64; + input += 64; + } + + if (length) + memcpy(sha256->data + left, input, length); +} + +static uint8_t sha256_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static void sha256_sum_close(Sha256sum *sha256, uint8_t *digest) +{ + uint32_t last, padn; + uint32_t high, low; + uint8_t msglen[8]; + + high = (sha256->bits[0] >> 29) | (sha256->bits[1] << 3); + low = (sha256->bits[0] << 3); + + PUT_UINT32(high, msglen, 0); + PUT_UINT32(low, msglen, 4); + + last = sha256->bits[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + sha256_sum_update(sha256, sha256_padding, padn); + sha256_sum_update(sha256, msglen, 8); + + PUT_UINT32(sha256->buf[0], digest, 0); + PUT_UINT32(sha256->buf[1], digest, 4); + PUT_UINT32(sha256->buf[2], digest, 8); + PUT_UINT32(sha256->buf[3], digest, 12); + PUT_UINT32(sha256->buf[4], digest, 16); + PUT_UINT32(sha256->buf[5], digest, 20); + PUT_UINT32(sha256->buf[6], digest, 24); + PUT_UINT32(sha256->buf[7], digest, 28); +} + +#undef PUT_UINT32 +#undef GET_UINT32 + +#endif /* SHA256 fallback implementation */ + +#include "lcfs-fsverity.h" + +struct fsverity_descriptor { + uint8_t version; + uint8_t hash_algorithm; + uint8_t log_blocksize; + uint8_t salt_size; + uint32_t reserved1; + uint64_t data_size_be; + uint8_t root_hash[64]; + uint8_t salt[32]; + uint8_t reserved2[144]; +}; + +#define FSVERITY_BLOCK_SIZE 4096 +#define FSVERITY_MAX_LEVELS 8 /* enough for 64bit file size */ + +struct FsVerityContext { + uint8_t buffer[FSVERITY_MAX_LEVELS][FSVERITY_BLOCK_SIZE]; + uint32_t buffer_pos[FSVERITY_MAX_LEVELS]; + uint32_t max_level; + uint64_t file_size; +#ifdef HAVE_OPENSSL + EVP_MD_CTX *md_ctx; +#endif +}; + +FsVerityContext *lcfs_fsverity_context_new(void) +{ + FsVerityContext *ctx; + + ctx = calloc(1, sizeof(FsVerityContext)); + if (ctx == NULL) + return NULL; + +#ifdef HAVE_OPENSSL + ctx->md_ctx = EVP_MD_CTX_create(); + if (ctx->md_ctx == NULL) { + free(ctx); + return NULL; + } +#endif + + return ctx; +} + +void lcfs_fsverity_context_free(FsVerityContext *ctx) +{ +#ifdef HAVE_OPENSSL + EVP_MD_CTX_destroy(ctx->md_ctx); +#endif + free(ctx); +} + +static void do_sha256(FsVerityContext *ctx, const uint8_t *data, + size_t data_len, uint8_t *digest) +{ +#ifdef HAVE_OPENSSL + const EVP_MD *md = EVP_sha256(); + int ret; + + assert(md != NULL); + + ret = EVP_DigestInit_ex(ctx->md_ctx, md, NULL); + assert(ret == 1); + + ret = EVP_DigestUpdate(ctx->md_ctx, data, data_len); + assert(ret == 1); + + ret = EVP_DigestFinal_ex(ctx->md_ctx, digest, NULL); + assert(ret == 1); +#else + Sha256sum sha256; + + sha256_sum_init(&sha256); + sha256_sum_update(&sha256, data, data_len); + sha256_sum_close(&sha256, digest); +#endif +} + +static void lcfs_fsverity_context_update_level(FsVerityContext *ctx, uint8_t *data, + size_t data_len, uint32_t level) +{ + assert(level < FSVERITY_MAX_LEVELS); + + if (level > ctx->max_level) + ctx->max_level = level; + + while (data_len > 0) { + /* First check if block is already full, we want to do this lazyly + so we only flush to the next level if there is more data after + the block is full */ + if (ctx->buffer_pos[level] == FSVERITY_BLOCK_SIZE) { + uint8_t digest[LCFS_SHA256_DIGEST_LEN]; + do_sha256(ctx, ctx->buffer[level], FSVERITY_BLOCK_SIZE, + digest); + lcfs_fsverity_context_update_level(ctx, digest, 32, + level + 1); + ctx->buffer_pos[level] = 0; + } + + size_t to_copy = + MIN(FSVERITY_BLOCK_SIZE - ctx->buffer_pos[level], data_len); + + memcpy(ctx->buffer[level] + ctx->buffer_pos[level], data, to_copy); + ctx->buffer_pos[level] += to_copy; + + data += to_copy; + data_len -= to_copy; + } +} + +void lcfs_fsverity_context_update(FsVerityContext *ctx, void *data, size_t data_len) +{ + lcfs_fsverity_context_update_level(ctx, data, data_len, 0); + ctx->file_size += data_len; +} + +static void lcfs_fsverity_context_flush_level(FsVerityContext *ctx, uint32_t level) +{ + uint8_t digest[LCFS_SHA256_DIGEST_LEN]; + + if (ctx->buffer_pos[level] < FSVERITY_BLOCK_SIZE) { + memset(ctx->buffer[level] + ctx->buffer_pos[level], 0, + FSVERITY_BLOCK_SIZE - ctx->buffer_pos[level]); + ctx->buffer_pos[level] = FSVERITY_BLOCK_SIZE; + } + + if (level == ctx->max_level) + return; + + do_sha256(ctx, ctx->buffer[level], FSVERITY_BLOCK_SIZE, digest); + lcfs_fsverity_context_update_level(ctx, digest, LCFS_SHA256_DIGEST_LEN, + level + 1); + + lcfs_fsverity_context_flush_level(ctx, level + 1); +} + +void lcfs_fsverity_context_get_digest(FsVerityContext *ctx, + uint8_t digest[LCFS_SHA256_DIGEST_LEN]) +{ + struct fsverity_descriptor descriptor; + + lcfs_fsverity_context_flush_level(ctx, 0); + + memset(&descriptor, 0, sizeof(descriptor)); + descriptor.version = 1; + descriptor.hash_algorithm = 1; + descriptor.log_blocksize = 12; + descriptor.salt_size = 0; + descriptor.data_size_be = htole64(ctx->file_size); + + do_sha256(ctx, ctx->buffer[ctx->max_level], FSVERITY_BLOCK_SIZE, + descriptor.root_hash); + + do_sha256(ctx, (uint8_t *)&descriptor, sizeof(descriptor), digest); +} diff --git a/composefs/libcomposefs/lcfs-fsverity.h b/composefs/libcomposefs/lcfs-fsverity.h new file mode 100644 index 0000000..cd38045 --- /dev/null +++ b/composefs/libcomposefs/lcfs-fsverity.h @@ -0,0 +1,27 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +typedef struct FsVerityContext FsVerityContext; + +#define LCFS_SHA256_DIGEST_LEN 32 + +FsVerityContext *lcfs_fsverity_context_new(void); +void lcfs_fsverity_context_free(FsVerityContext *ctx); +void lcfs_fsverity_context_update(FsVerityContext *ctx, void *data, size_t data_len); +void lcfs_fsverity_context_get_digest(FsVerityContext *ctx, + uint8_t digest[LCFS_SHA256_DIGEST_LEN]); diff --git a/composefs/libcomposefs/lcfs-internal.h b/composefs/libcomposefs/lcfs-internal.h new file mode 100644 index 0000000..f9cab47 --- /dev/null +++ b/composefs/libcomposefs/lcfs-internal.h @@ -0,0 +1,205 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _LCFS_INTERNAL_H +#define _LCFS_INTERNAL_H + +#include + +#include "lcfs-writer.h" +#include "lcfs-fsverity.h" +#include "hash.h" + +/* When using LCFS_BUILD_INLINE_SMALL in lcfs_load_node_from_file() inline files below this size + * We pick 64 which is the size of a sha256 digest that would otherwise be used as a redirect + * xattr, so the inlined file is smaller. + */ +#define LCFS_BUILD_INLINE_FILE_SIZE_LIMIT 64 + +#define OVERLAY_XATTR_USER_PREFIX "user." +#define OVERLAY_XATTR_TRUSTED_PREFIX "trusted." +#define OVERLAY_XATTR_PARTIAL_PREFIX "overlay." +#define OVERLAY_XATTR_PREFIX \ + OVERLAY_XATTR_TRUSTED_PREFIX OVERLAY_XATTR_PARTIAL_PREFIX +#define OVERLAY_XATTR_USERXATTR_PREFIX \ + OVERLAY_XATTR_USER_PREFIX OVERLAY_XATTR_PARTIAL_PREFIX +#define OVERLAY_XATTR_ESCAPE_PREFIX OVERLAY_XATTR_PREFIX "overlay." +#define OVERLAY_XATTR_METACOPY OVERLAY_XATTR_PREFIX "metacopy" +#define OVERLAY_XATTR_REDIRECT OVERLAY_XATTR_PREFIX "redirect" +#define OVERLAY_XATTR_WHITEOUT OVERLAY_XATTR_PREFIX "whiteout" +#define OVERLAY_XATTR_WHITEOUTS OVERLAY_XATTR_PREFIX "whiteouts" +#define OVERLAY_XATTR_OPAQUE OVERLAY_XATTR_PREFIX "opaque" + +#define OVERLAY_XATTR_ESCAPED_WHITEOUT OVERLAY_XATTR_ESCAPE_PREFIX "whiteout" +#define OVERLAY_XATTR_ESCAPED_WHITEOUTS OVERLAY_XATTR_ESCAPE_PREFIX "whiteouts" + +#define OVERLAY_XATTR_USERXATTR_WHITEOUT \ + OVERLAY_XATTR_USERXATTR_PREFIX "whiteout" +#define OVERLAY_XATTR_USERXATTR_WHITEOUTS \ + OVERLAY_XATTR_USERXATTR_PREFIX "whiteouts" + +#define ALIGN_TO(_offset, _align_size) \ + (((_offset) + _align_size - 1) & ~(_align_size - 1)) + +#define __round_mask(x, y) ((__typeof__(x))((y)-1)) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) +#define round_down(x, y) ((x) & ~__round_mask(x, y)) + +#define LCFS_MAX_NAME_LENGTH 255 /* max len of file name excluding NULL */ + +static inline uint16_t lcfs_u16_to_file(uint16_t val) +{ + return htole16(val); +} + +static inline uint32_t lcfs_u32_to_file(uint32_t val) +{ + return htole32(val); +} + +static inline uint64_t lcfs_u64_to_file(uint64_t val) +{ + return htole64(val); +} + +static inline uint16_t lcfs_u16_from_file(uint16_t val) +{ + return le16toh(val); +} + +static inline uint32_t lcfs_u32_from_file(uint32_t val) +{ + return le32toh(val); +} + +static inline uint64_t lcfs_u64_from_file(uint64_t val) +{ + return le64toh(val); +} + +/* In memory representation used to build the file. */ + +struct lcfs_xattr_s { + char *key; + char *value; + size_t value_len; + + /* Used during writing */ + int64_t erofs_shared_xattr_offset; /* shared offset, or -1 if not shared */ +}; + +struct lcfs_inode_s { + uint32_t st_mode; /* File type and mode. */ + uint32_t st_nlink; /* Number of hard links, only for regular files. */ + uint32_t st_uid; /* User ID of owner. */ + uint32_t st_gid; /* Group ID of owner. */ + uint32_t st_rdev; /* Device ID (if special file). */ + uint64_t st_size; /* Size of file, only used for regular files */ + int64_t st_mtim_sec; + uint32_t st_mtim_nsec; +}; + +struct lcfs_node_s { + int ref_count; + + struct lcfs_node_s *parent; + + struct lcfs_node_s **children; /* Owns refs */ + size_t children_size; + + /* Used to create hard links. */ + struct lcfs_node_s *link_to; /* Owns refs */ + + char *name; + char *payload; /* backing file or symlink target */ + + uint8_t *content; + + struct lcfs_xattr_s *xattrs; + size_t n_xattrs; + + bool digest_set; + uint8_t digest[LCFS_DIGEST_SIZE]; /* sha256 fs-verity digest */ + + struct lcfs_inode_s inode; + + /* Used during compute_tree */ + struct lcfs_node_s *next; /* Use for the queue in compute_tree */ + bool in_tree; + uint32_t inode_num; + + bool erofs_compact; + uint32_t erofs_ipad; /* padding before inode data */ + uint32_t erofs_isize; + uint32_t erofs_nid; + uint32_t erofs_n_blocks; + uint32_t erofs_tailsize; +}; + +struct lcfs_ctx_s { + struct lcfs_write_options_s *options; + struct lcfs_node_s *root; + bool destroy_root; + + /* Used by compute_tree. */ + struct lcfs_node_s *queue_end; + uint32_t num_inodes; + int64_t min_mtim_sec; + uint32_t min_mtim_nsec; + bool has_acl; + + void *file; + lcfs_write_cb write_cb; + off_t bytes_written; + FsVerityContext *fsverity_ctx; + + void (*finalize)(struct lcfs_ctx_s *ctx); +}; + +static inline void lcfs_node_unrefp(struct lcfs_node_s **nodep) +{ + if (*nodep != NULL) { + lcfs_node_unref(*nodep); + *nodep = NULL; + } +} +#define cleanup_node __attribute__((cleanup(lcfs_node_unrefp))) + +/* lcfs-writer.c */ +size_t hash_memory(const char *string, size_t len, size_t n_buckets); +int lcfs_write(struct lcfs_ctx_s *ctx, void *_data, size_t data_len); +int lcfs_write_align(struct lcfs_ctx_s *ctx, size_t align_size); +int lcfs_write_pad(struct lcfs_ctx_s *ctx, size_t data_len); +int lcfs_compute_tree(struct lcfs_ctx_s *ctx, struct lcfs_node_s *root); +int lcfs_clone_root(struct lcfs_ctx_s *ctx); +char *maybe_join_path(const char *a, const char *b); +struct lcfs_node_s *follow_links(struct lcfs_node_s *node); +int node_get_dtype(struct lcfs_node_s *node); + +int lcfs_node_rename_xattr(struct lcfs_node_s *node, size_t index, + const char *new_name); + +/* lcfs-writer-erofs.c */ + +int lcfs_write_erofs_to(struct lcfs_ctx_s *ctx); +struct lcfs_ctx_s *lcfs_ctx_erofs_new(void); + +/* lcfs-writer-cfs.c */ + +int lcfs_write_cfs_to(struct lcfs_ctx_s *ctx); +struct lcfs_ctx_s *lcfs_ctx_cfs_new(void); + +#endif diff --git a/composefs/libcomposefs/lcfs-mount.c b/composefs/libcomposefs/lcfs-mount.c new file mode 100644 index 0000000..0a4b08f --- /dev/null +++ b/composefs/libcomposefs/lcfs-mount.c @@ -0,0 +1,616 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#define _GNU_SOURCE + +#include "config.h" + +#include "lcfs-writer.h" +#include "lcfs-mount.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef HAVE_FSCONFIG_CMD_CREATE_LINUX_MOUNT_H +#include +#endif +#if defined HAVE_FSCONFIG_CMD_CREATE_LINUX_MOUNT_H || \ + defined HAVE_FSCONFIG_CMD_CREATE_SYS_MOUNT_H +#define HAVE_NEW_MOUNT_API +#endif + +#include "lcfs-erofs.h" +#include "lcfs-utils.h" +#include "lcfs-internal.h" + +static int syscall_fsopen(const char *fs_name, unsigned int flags) +{ +#if defined __NR_fsopen + return (int)syscall(__NR_fsopen, fs_name, flags); +#else + (void)fs_name; + (void)flags; + errno = ENOSYS; + return -1; +#endif +} + +static int syscall_fsmount(int fsfd, unsigned int flags, unsigned int attr_flags) +{ +#if defined __NR_fsmount + return (int)syscall(__NR_fsmount, fsfd, flags, attr_flags); +#else + (void)fsfd; + (void)flags; + (void)attr_flags; + errno = ENOSYS; + return -1; +#endif +} + +static int syscall_fsconfig(int fsfd, unsigned int cmd, const char *key, + const void *val, int aux) +{ +#if defined __NR_fsconfig + return (int)syscall(__NR_fsconfig, fsfd, cmd, key, val, aux); +#else + (void)fsfd; + (void)cmd; + (void)key; + (void)val; + (void)aux; + errno = ENOSYS; + return -1; +#endif +} + +static int syscall_move_mount(int from_dfd, const char *from_pathname, int to_dfd, + const char *to_pathname, unsigned int flags) + +{ +#if defined __NR_move_mount + return (int)syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, + to_pathname, flags); +#else + (void)from_dfd; + (void)from_pathname; + (void)to_dfd; + (void)to_pathname; + (void)flags; + errno = ENOSYS; + return -1; +#endif +} + +static int syscall_mount_setattr(int dfd, const char *path, unsigned int flags, + struct mount_attr *attr, size_t usize) +{ +#ifdef __NR_mount_setattr + return (int)syscall(__NR_mount_setattr, dfd, path, flags, attr, usize); +#else + (void)dfd; + (void)path; + (void)flags; + (void)attr; + errno = ENOSYS; + return -1; +#endif +} + +#define MAX_DIGEST_SIZE 64 + +struct lcfs_mount_state_s { + const char *image_path; + const char *mountpoint; + struct lcfs_mount_options_s *options; + int fd; + uint8_t expected_digest[MAX_DIGEST_SIZE]; + int expected_digest_len; +}; + +static void escape_mount_option_to(const char *str, char *dest) +{ + const char *s; + char *d; + + d = dest + strlen(dest); + for (s = str; *s != 0; s++) { + if (*s == ',') + *d++ = '\\'; + *d++ = *s; + } + *d++ = 0; +} + +static char *escape_mount_option(const char *str) +{ + const char *s; + char *res; + int n_escapes = 0; + + for (s = str; *s != 0; s++) { + if (*s == ',') + n_escapes++; + } + + res = malloc(strlen(str) + n_escapes + 1); + if (res == NULL) + return NULL; + + *res = 0; + + escape_mount_option_to(str, res); + + return res; +} + +static int hexdigit(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return 10 + (c - 'a'); + if (c >= 'A' && c <= 'F') + return 10 + (c - 'A'); + return -1; +} + +static int digest_to_raw(const char *digest, uint8_t *raw, int max_size) +{ + int size = 0; + + while (*digest) { + char c1, c2; + int n1, n2; + + if (size >= max_size) + return -1; + + c1 = *digest++; + n1 = hexdigit(c1); + if (n1 < 0) + return -1; + + c2 = *digest++; + n2 = hexdigit(c2); + if (n2 < 0) + return -1; + + raw[size++] = (n1 & 0xf) << 4 | (n2 & 0xf); + } + + return size; +} + +static int lcfs_validate_mount_options(struct lcfs_mount_state_s *state) +{ + struct lcfs_mount_options_s *options = state->options; + + if ((options->flags & ~LCFS_MOUNT_FLAGS_MASK) != 0) { + return -EINVAL; + } + + if ((options->flags & LCFS_MOUNT_FLAGS_REQUIRE_VERITY) && + (options->flags & LCFS_MOUNT_FLAGS_DISABLE_VERITY)) { + return -EINVAL; /* Can't have both */ + } + + if (options->n_objdirs == 0) + return -EINVAL; + + if ((options->upperdir && !options->workdir) || + (!options->upperdir && options->workdir)) + return -EINVAL; + + if (options->expected_fsverity_digest) { + int raw_len = digest_to_raw(options->expected_fsverity_digest, + state->expected_digest, MAX_DIGEST_SIZE); + if (raw_len < 0) + return -EINVAL; + state->expected_digest_len = raw_len; + } + + if ((options->flags & LCFS_MOUNT_FLAGS_IDMAP) != 0 && options->idmap_fd < 0) { + return -EINVAL; + } + + return 0; +} + +static int lcfs_validate_verity_fd(struct lcfs_mount_state_s *state) +{ + struct { + struct fsverity_digest fsv; + char buf[MAX_DIGEST_SIZE]; + } buf; + int res; + + if (state->expected_digest_len != 0) { + buf.fsv.digest_size = MAX_DIGEST_SIZE; + res = ioctl(state->fd, FS_IOC_MEASURE_VERITY, &buf.fsv); + if (res == -1) { + if (errno == ENODATA || errno == EOPNOTSUPP || errno == ENOTTY) + return -ENOVERITY; + return -errno; + } + if (buf.fsv.digest_size != state->expected_digest_len || + memcmp(state->expected_digest, buf.fsv.digest, + buf.fsv.digest_size) != 0) + return -EWRONGVERITY; + } + + return 0; +} + +static int setup_loopback(int fd, const char *image_path, char *loopname) +{ + struct loop_config loopconfig = { 0 }; + int loopctlfd, loopfd; + long devnr; + int errsv; + + loopctlfd = open("/dev/loop-control", O_RDWR | O_CLOEXEC); + if (loopctlfd < 0) + return -errno; + + devnr = ioctl(loopctlfd, LOOP_CTL_GET_FREE); + errsv = errno; + close(loopctlfd); + if (devnr == -1) { + return -errsv; + } + + sprintf(loopname, "/dev/loop%ld", devnr); + loopfd = open(loopname, O_RDWR | O_CLOEXEC); + if (loopfd < 0) + return -errno; + + loopconfig.fd = fd; + loopconfig.block_size = + 4096; /* This is what we use for the erofs block size, so probably good */ + loopconfig.info.lo_flags = + LO_FLAGS_READ_ONLY | LO_FLAGS_DIRECT_IO | LO_FLAGS_AUTOCLEAR; + if (image_path) + strncat((char *)loopconfig.info.lo_file_name, image_path, + LO_NAME_SIZE - 1); + + if (ioctl(loopfd, LOOP_CONFIGURE, &loopconfig) < 0) { + errsv = errno; + close(loopfd); + return -errsv; + } + + return loopfd; +} + +static char *compute_lower(const char *imagemount, + struct lcfs_mount_state_s *state, bool with_datalower) +{ + size_t size; + char *lower; + size_t i; + + /* Compute the total max size (including escapes) */ + size = 2 * strlen(imagemount); + for (i = 0; i < state->options->n_objdirs; i++) + size += 2 + 2 * strlen(state->options->objdirs[i]); + + lower = malloc(size + 1); + if (lower == NULL) + return NULL; + *lower = 0; + + escape_mount_option_to(imagemount, lower); + + for (i = 0; i < state->options->n_objdirs; i++) { + if (with_datalower) + strcat(lower, "::"); + else + strcat(lower, ":"); + escape_mount_option_to(state->options->objdirs[i], lower); + } + + return lower; +} + +static int lcfs_mount_erofs(const char *source, const char *target, + uint32_t image_flags, struct lcfs_mount_state_s *state) +{ + bool image_has_acls = (image_flags & LCFS_EROFS_FLAGS_HAS_ACL) != 0; + bool use_idmap = (state->options->flags & LCFS_MOUNT_FLAGS_IDMAP) != 0; + int res; + +#ifdef HAVE_NEW_MOUNT_API + /* We have new mount API is in header */ + cleanup_fd int fd_fs = -1; + cleanup_fd int fd_mnt = -1; + + fd_fs = syscall_fsopen("erofs", FSOPEN_CLOEXEC); + if (fd_fs < 0) { + if (errno == ENOSYS) + goto fallback; + return -errno; + } + + res = syscall_fsconfig(fd_fs, FSCONFIG_SET_STRING, "source", source, 0); + if (res < 0) + return -errno; + + res = syscall_fsconfig(fd_fs, FSCONFIG_SET_FLAG, "ro", NULL, 0); + if (res < 0) + return -errno; + + if (!image_has_acls) { + res = syscall_fsconfig(fd_fs, FSCONFIG_SET_FLAG, "noacl", NULL, 0); + if (res < 0) + return -errno; + } + + res = syscall_fsconfig(fd_fs, FSCONFIG_CMD_CREATE, NULL, NULL, 0); + if (res < 0) + return -errno; + + fd_mnt = syscall_fsmount(fd_fs, FSMOUNT_CLOEXEC, MS_RDONLY); + if (fd_mnt < 0) + return -errno; + + if (use_idmap) { + struct mount_attr attr = { + .attr_set = MOUNT_ATTR_IDMAP, + .userns_fd = state->options->idmap_fd, + }; + + res = syscall_mount_setattr(fd_mnt, "", AT_EMPTY_PATH, &attr, + sizeof(struct mount_attr)); + if (res < 0) + return -errno; + } + + res = syscall_move_mount(fd_mnt, "", AT_FDCWD, target, + MOVE_MOUNT_F_EMPTY_PATH); + if (res < 0) + return -errno; + + return 0; + +fallback: +#endif + + /* We need new mount api for idmapped mounts */ + if (use_idmap) + return -ENOTSUP; + + res = mount(source, target, "erofs", MS_RDONLY, + image_has_acls ? "ro" : "ro,noacl"); + if (res < 0) + return -errno; + + return 0; +} + +#define HEADER_SIZE sizeof(struct lcfs_erofs_header_s) + +static int lcfs_mount_erofs_ovl(struct lcfs_mount_state_s *state, + struct lcfs_erofs_header_s *header) +{ + struct lcfs_mount_options_s *options = state->options; + uint32_t image_flags; + char imagemountbuf[] = "/tmp/.composefs.XXXXXX"; + char *imagemount; + bool created_tmpdir = false; + char loopname[PATH_MAX]; + int res, errsv; + cleanup_free char *lowerdir_1 = NULL; + cleanup_free char *lowerdir_2 = NULL; + cleanup_free char *upperdir = NULL; + cleanup_free char *workdir = NULL; + cleanup_free char *overlay_options = NULL; + /* Can point to lowerdir_1 or _2 */ + const char *lowerdir_target = NULL; + int loopfd; + bool require_verity; + bool disable_verity; + bool readonly; + int mount_flags; + + image_flags = lcfs_u32_from_file(header->flags); + + require_verity = (options->flags & LCFS_MOUNT_FLAGS_REQUIRE_VERITY) != 0; + disable_verity = (options->flags & LCFS_MOUNT_FLAGS_DISABLE_VERITY) != 0; + readonly = (options->flags & LCFS_MOUNT_FLAGS_READONLY) != 0; + + loopfd = setup_loopback(state->fd, state->image_path, loopname); + if (loopfd < 0) + return loopfd; + + if (options->image_mountdir) { + imagemount = (char *)options->image_mountdir; + } else { + imagemount = mkdtemp(imagemountbuf); + if (imagemount == NULL) { + errsv = errno; + close(loopfd); + return -errsv; + } + created_tmpdir = true; + } + + res = lcfs_mount_erofs(loopname, imagemount, image_flags, state); + close(loopfd); + if (res < 0) { + rmdir(imagemount); + return res; + } + + /* We use the legacy API to mount overlayfs, because the new API doesn't allow use + * to pass in escaped directory names + */ + + /* First try new version with :: separating datadirs. */ + lowerdir_1 = compute_lower(imagemount, state, true); + if (lowerdir_1 == NULL) { + res = -ENOMEM; + goto fail; + } + lowerdir_target = lowerdir_1; + + /* Then fall back. */ + lowerdir_2 = compute_lower(imagemount, state, false); + if (lowerdir_2 == NULL) { + res = -ENOMEM; + goto fail; + } + + if (options->upperdir) { + upperdir = escape_mount_option(options->upperdir); + if (upperdir == NULL) { + res = -ENOMEM; + goto fail; + } + } + if (options->workdir) { + workdir = escape_mount_option(options->workdir); + if (workdir == NULL) { + res = -ENOMEM; + goto fail; + } + } + +retry: + free(steal_pointer(&overlay_options)); + res = asprintf(&overlay_options, + "metacopy=on,redirect_dir=on,lowerdir=%s%s%s%s%s%s", + lowerdir_target, upperdir ? ",upperdir=" : "", + upperdir ? upperdir : "", workdir ? ",workdir=" : "", + workdir ? workdir : "", + require_verity ? ",verity=require" : + (disable_verity ? ",verity=off" : "")); + if (res < 0) { + res = -ENOMEM; + goto fail; + } + + mount_flags = 0; + if (readonly) + mount_flags |= MS_RDONLY; + if (lowerdir_target == lowerdir_1) + mount_flags |= MS_SILENT; + + res = mount("overlay", state->mountpoint, "overlay", mount_flags, + overlay_options); + if (res != 0) { + res = -errno; + } + + if (res == -EINVAL && lowerdir_target == lowerdir_1) { + lowerdir_target = lowerdir_2; + goto retry; + } + +fail: + umount2(imagemount, MNT_DETACH); + if (created_tmpdir) { + rmdir(imagemount); + } + + return res; +} + +static int lcfs_mount(struct lcfs_mount_state_s *state) +{ + uint8_t header_data[HEADER_SIZE]; + struct lcfs_erofs_header_s *erofs_header; + int res; + + res = lcfs_validate_verity_fd(state); + if (res < 0) + return res; + + res = pread(state->fd, &header_data, HEADER_SIZE, 0); + if (res < 0) + return -errno; + + erofs_header = (struct lcfs_erofs_header_s *)header_data; + if (lcfs_u32_from_file(erofs_header->magic) == LCFS_EROFS_MAGIC) + return lcfs_mount_erofs_ovl(state, erofs_header); + + return -EINVAL; +} + +int lcfs_mount_fd(int fd, const char *mountpoint, struct lcfs_mount_options_s *options) +{ + struct lcfs_mount_state_s state = { .mountpoint = mountpoint, + .options = options, + .fd = fd }; + int res; + + res = lcfs_validate_mount_options(&state); + if (res < 0) { + errno = -res; + return -1; + } + + res = lcfs_mount(&state); + if (res < 0) { + errno = -res; + return -1; + } + return 0; +} + +int lcfs_mount_image(const char *path, const char *mountpoint, + struct lcfs_mount_options_s *options) +{ + struct lcfs_mount_state_s state = { .image_path = path, + .mountpoint = mountpoint, + .options = options, + .fd = -1 }; + int fd, res; + + res = lcfs_validate_mount_options(&state); + if (res < 0) { + errno = -res; + return -1; + } + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + return -1; + } + state.fd = fd; + + res = lcfs_mount(&state); + close(fd); + if (res < 0) { + errno = -res; + return -1; + } + + return 0; +} diff --git a/composefs/libcomposefs/lcfs-mount.h b/composefs/libcomposefs/lcfs-mount.h new file mode 100644 index 0000000..d8e837b --- /dev/null +++ b/composefs/libcomposefs/lcfs-mount.h @@ -0,0 +1,63 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _LCFS_MOUNT_H +#define _LCFS_MOUNT_H + +#include +#include +#include +#include +#include + +#ifndef LCFS_EXTERN +#define LCFS_EXTERN extern +#endif + +#define ENOVERITY ENOTTY +#define EWRONGVERITY EILSEQ +#define ENOSIGNATURE EBADMSG + +enum lcfs_mount_flags_t { + LCFS_MOUNT_FLAGS_NONE = 0, + LCFS_MOUNT_FLAGS_REQUIRE_VERITY = (1 << 0), + LCFS_MOUNT_FLAGS_READONLY = (1 << 1), + LCFS_MOUNT_FLAGS_IDMAP = (1 << 3), + LCFS_MOUNT_FLAGS_DISABLE_VERITY = (1 << 4), + + LCFS_MOUNT_FLAGS_MASK = (1 << 5) - 1, +}; + +struct lcfs_mount_options_s { + const char **objdirs; + size_t n_objdirs; + const char *workdir; + const char *upperdir; + const char *expected_fsverity_digest; + uint32_t flags; + int idmap_fd; /* userns fd */ + const char *image_mountdir; /* Temporary location to mount images if needed */ + + uint32_t reserved[4]; + void *reserved2[4]; +}; + +LCFS_EXTERN int lcfs_mount_image(const char *path, const char *mountpoint, + struct lcfs_mount_options_s *options); +LCFS_EXTERN int lcfs_mount_fd(int fd, const char *mountpoint, + struct lcfs_mount_options_s *options); + +#endif diff --git a/composefs/libcomposefs/lcfs-utils.h b/composefs/libcomposefs/lcfs-utils.h new file mode 100644 index 0000000..e493d6d --- /dev/null +++ b/composefs/libcomposefs/lcfs-utils.h @@ -0,0 +1,111 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _LCFS_UTILS_H +#define _LCFS_UTILS_H + +#include +#include +#include +#include +#include + +#define max(a, b) ((a > b) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +static inline bool str_has_prefix(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)) == 0; +} + +static inline char *memdup(const char *s, size_t len) +{ + char *s2 = malloc(len); + if (s2 == NULL) { + errno = ENOMEM; + return NULL; + } + memcpy(s2, s, len); + return s2; +} + +static inline char *str_join(const char *a, const char *b) +{ + size_t a_len = strlen(a); + size_t b_len = strlen(b); + char *res = malloc(a_len + b_len + 1); + if (res) { + memcpy(res, a, a_len); + memcpy(res + a_len, b, b_len + 1); + } + return res; +} + +static inline void _lcfs_reset_errno_(int *saved_errno) +{ + if (*saved_errno < 0) + return; + errno = *saved_errno; +} + +// This helper was taken from systemd; it ensures that the value of errno +// is reset. +#define PROTECT_ERRNO \ + __attribute__((cleanup(_lcfs_reset_errno_))) \ + __attribute__((unused)) int _saved_errno_ = errno + +static inline void cleanup_freep(void *p) +{ + void **pp = (void **)p; + + if (*pp) + free(*pp); +} + +// A wrapper around close() that takes a pointer to a file descriptor (integer): +// - Never returns an error (and preserves errno) +// - Sets the value to -1 after closing to make cleanup idempotent +static inline void cleanup_fdp(int *fdp) +{ + PROTECT_ERRNO; + int fd; + + assert(fdp); + + fd = *fdp; + if (fd != -1) + (void)close(fd); + *fdp = -1; +} + +#define cleanup_free __attribute__((cleanup(cleanup_freep))) +#define cleanup_fd __attribute__((cleanup(cleanup_fdp))) + +static inline void *steal_pointer(void *pp) +{ + void **ptr = (void **)pp; + void *ref; + + ref = *ptr; + *ptr = NULL; + + return ref; +} + +/* type safety */ +#define steal_pointer(pp) (0 ? (*(pp)) : (steal_pointer)(pp)) + +#endif diff --git a/composefs/libcomposefs/lcfs-writer-erofs.c b/composefs/libcomposefs/lcfs-writer-erofs.c new file mode 100644 index 0000000..c061703 --- /dev/null +++ b/composefs/libcomposefs/lcfs-writer-erofs.c @@ -0,0 +1,1880 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#define _GNU_SOURCE + +#include "config.h" + +#include "lcfs-internal.h" +#include "lcfs-utils.h" +#include "lcfs-writer.h" +#include "lcfs-fsverity.h" +#include "lcfs-erofs-internal.h" +#include "lcfs-utils.h" +#include "hash.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The xxh32 hash function is copied from the linux kernel at: + * https://github.com/torvalds/linux/blob/d89775fc929c5a1d91ed518a71b456da0865e5ff/lib/xxhash.c + * + * The original copyright is: + * + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at: + * - xxHash homepage: https://cyan4973.github.io/xxHash/ + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ + +static const uint32_t PRIME32_1 = 2654435761U; +static const uint32_t PRIME32_2 = 2246822519U; +static const uint32_t PRIME32_3 = 3266489917U; +static const uint32_t PRIME32_4 = 668265263U; +static const uint32_t PRIME32_5 = 374761393U; + +static inline uint32_t get_unaligned_le32(const uint8_t *p) +{ + return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; +} + +#define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r))) + +static uint32_t xxh32_round(uint32_t seed, const uint32_t input) +{ + seed += input * PRIME32_2; + seed = xxh_rotl32(seed, 13); + seed *= PRIME32_1; + return seed; +} + +static uint32_t xxh32(const void *input, const size_t len, const uint32_t seed) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *b_end = p + len; + uint32_t h32; + + if (len >= 16) { + const uint8_t *const limit = b_end - 16; + uint32_t v1 = seed + PRIME32_1 + PRIME32_2; + uint32_t v2 = seed + PRIME32_2; + uint32_t v3 = seed + 0; + uint32_t v4 = seed - PRIME32_1; + + do { + v1 = xxh32_round(v1, get_unaligned_le32(p)); + p += 4; + v2 = xxh32_round(v2, get_unaligned_le32(p)); + p += 4; + v3 = xxh32_round(v3, get_unaligned_le32(p)); + p += 4; + v4 = xxh32_round(v4, get_unaligned_le32(p)); + p += 4; + } while (p <= limit); + + h32 = xxh_rotl32(v1, 1) + xxh_rotl32(v2, 7) + + xxh_rotl32(v3, 12) + xxh_rotl32(v4, 18); + } else { + h32 = seed + PRIME32_5; + } + + h32 += (uint32_t)len; + + while (p + 4 <= b_end) { + h32 += get_unaligned_le32(p) * PRIME32_3; + h32 = xxh_rotl32(h32, 17) * PRIME32_4; + p += 4; + } + + while (p < b_end) { + h32 += (*p) * PRIME32_5; + h32 = xxh_rotl32(h32, 11) * PRIME32_1; + p++; + } + + h32 ^= h32 >> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + +struct lcfs_ctx_erofs_s { + struct lcfs_ctx_s base; + + uint64_t inodes_end; /* start of xattrs */ + uint64_t shared_xattr_size; + uint64_t n_data_blocks; + uint64_t current_end; + struct lcfs_xattr_s **shared_xattrs; + size_t n_shared_xattrs; +}; + +static void lcfs_ctx_erofs_finalize(struct lcfs_ctx_s *ctx) +{ + struct lcfs_ctx_erofs_s *ctx_erofs = (struct lcfs_ctx_erofs_s *)ctx; + + free(ctx_erofs->shared_xattrs); +} + +struct lcfs_ctx_s *lcfs_ctx_erofs_new(void) +{ + struct lcfs_ctx_erofs_s *ret = calloc(1, sizeof(struct lcfs_ctx_erofs_s)); + if (ret == NULL) { + return NULL; + } + + ret->base.finalize = lcfs_ctx_erofs_finalize; + + return &ret->base; +} + +static int erofs_make_file_type(int regular) +{ + switch (regular) { + case DT_LNK: + return EROFS_FT_SYMLINK; + case DT_DIR: + return EROFS_FT_DIR; + case DT_REG: + return EROFS_FT_REG_FILE; + case DT_BLK: + return EROFS_FT_BLKDEV; + case DT_CHR: + return EROFS_FT_CHRDEV; + case DT_SOCK: + return EROFS_FT_SOCK; + case DT_FIFO: + return EROFS_FT_FIFO; + default: + return EROFS_FT_UNKNOWN; + } +} + +struct hasher_xattr_s { + struct lcfs_xattr_s *xattr; + uint32_t count; + + bool shared; + uint64_t shared_offset; /* offset in bytes from start of shared xattrs */ +}; + +static size_t xattrs_ht_hasher(const void *d, size_t n) +{ + const struct hasher_xattr_s *v = d; + return (hash_string(v->xattr->key, n) ^ + hash_memory(v->xattr->value, v->xattr->value_len, n)) % + n; +} + +static bool xattrs_ht_comparator(const void *d1, const void *d2) +{ + const struct hasher_xattr_s *v1 = d1; + const struct hasher_xattr_s *v2 = d2; + + if (strcmp(v1->xattr->key, v2->xattr->key) != 0) + return false; + + if (v1->xattr->value_len != v2->xattr->value_len) + return false; + + return memcmp(v1->xattr->value, v2->xattr->value, v1->xattr->value_len) == 0; +} + +/* Sort alphabetically by key and value to get some canonical order */ +static int xattrs_ht_sort(const void *d1, const void *d2) +{ + const struct hasher_xattr_s *v1 = *(const struct hasher_xattr_s **)d1; + const struct hasher_xattr_s *v2 = *(const struct hasher_xattr_s **)d2; + int r; + + r = strcmp(v2->xattr->key, v1->xattr->key); + if (r != 0) + return r; + + if (v1->xattr->value_len != v2->xattr->value_len) + return (int)v2->xattr->value_len - (int)v1->xattr->value_len; + + return memcmp(v2->xattr->value, v1->xattr->value, v1->xattr->value_len); +} + +static uint8_t xattr_erofs_entry_index(struct lcfs_xattr_s *xattr, char **rest) +{ + char *key = xattr->key; + struct { + const char *prefix; + uint8_t index; + } keys[] = { { "user.", EROFS_XATTR_INDEX_USER }, + { "system.posix_acl_access", EROFS_XATTR_INDEX_POSIX_ACL_ACCESS }, + { "system.posix_acl_default", EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT }, + { "trusted.", EROFS_XATTR_INDEX_TRUSTED }, + { "security.", EROFS_XATTR_INDEX_SECURITY }, + { NULL } }; + for (size_t i = 0; keys[i].prefix != NULL; i++) { + if (str_has_prefix(key, keys[i].prefix)) { + *rest = key + strlen(keys[i].prefix); + return keys[i].index; + } + } + + *rest = key; + return 0; +} + +static size_t xattr_erofs_entry_size(struct lcfs_xattr_s *xattr) +{ + char *key_suffix; + xattr_erofs_entry_index(xattr, &key_suffix); + + return round_up(sizeof(struct erofs_xattr_entry) + strlen(key_suffix) + + xattr->value_len, + sizeof(uint32_t)); +} + +static size_t xattr_erofs_icount(size_t xattr_size) +{ + if (xattr_size == 0) + return 0; + return (xattr_size - sizeof(struct erofs_xattr_ibody_header)) / + sizeof(uint32_t) + + 1; +} + +static size_t xattr_erofs_inode_size(size_t n_shared_xattrs, size_t unshared_xattrs_size) +{ + if (n_shared_xattrs == 0 && unshared_xattrs_size == 0) { + return 0; + } + + return round_up(sizeof(struct erofs_xattr_ibody_header) + + n_shared_xattrs * sizeof(uint32_t) + + unshared_xattrs_size, + sizeof(uint32_t)); +} + +static bool erofs_xattr_should_be_shared(struct hasher_xattr_s *ent) +{ + /* Share multi-use xattrs */ + if (ent->count > 1) + return true; + + return false; +} + +static int compute_erofs_shared_xattrs(struct lcfs_ctx_s *ctx) +{ + struct lcfs_ctx_erofs_s *ctx_erofs = (struct lcfs_ctx_erofs_s *)ctx; + struct lcfs_node_s *node; + Hash_table *xattr_hash; + struct hasher_xattr_s **sorted = NULL; + size_t n_xattrs; + uint64_t xattr_offset; + + /* Find the use count for each xattr key/value in use */ + + xattr_hash = hash_initialize(0, NULL, xattrs_ht_hasher, + xattrs_ht_comparator, free); + if (xattr_hash == NULL) { + return -1; + } + + for (node = ctx->root; node != NULL; node = node->next) { + for (size_t i = 0; i < node->n_xattrs; i++) { + struct hasher_xattr_s hkey = { .xattr = &node->xattrs[i] }; + struct hasher_xattr_s *ent; + + ent = hash_lookup(xattr_hash, &hkey); + if (ent == NULL) { + struct hasher_xattr_s *new_ent = + calloc(1, sizeof(struct hasher_xattr_s)); + if (new_ent == NULL) { + goto fail; + } + new_ent->xattr = &node->xattrs[i]; + ent = hash_insert(xattr_hash, new_ent); + if (ent == NULL) { + goto fail; + } + } + ent->count++; + } + } + + /* Compute the xattr list in canonical order */ + + n_xattrs = hash_get_n_entries(xattr_hash); + sorted = calloc(n_xattrs, sizeof(struct hasher_xattr_s *)); + if (sorted == NULL) + goto fail; + n_xattrs = hash_get_entries(xattr_hash, (void **)sorted, n_xattrs); + qsort(sorted, n_xattrs, sizeof(struct hasher_xattr_s *), xattrs_ht_sort); + + /* Compute the list of shared (multi-use) xattrs and their offsets */ + ctx_erofs->shared_xattrs = calloc(n_xattrs, sizeof(struct lcfs_xattr_s *)); + if (ctx_erofs->shared_xattrs == NULL) + goto fail; + ctx_erofs->n_shared_xattrs = 0; + + xattr_offset = 0; + for (size_t i = 0; i < n_xattrs; i++) { + struct hasher_xattr_s *ent = sorted[i]; + if (erofs_xattr_should_be_shared(ent)) { + ent->shared = true; + ent->shared_offset = xattr_offset; + + ctx_erofs->shared_xattrs[ctx_erofs->n_shared_xattrs] = + ent->xattr; + ctx_erofs->n_shared_xattrs++; + + xattr_offset += xattr_erofs_entry_size(ent->xattr); + } + } + + ctx_erofs->shared_xattr_size = xattr_offset; + + /* Assign shared xattr offsets for all inodes */ + + for (node = ctx->root; node != NULL; node = node->next) { + int n_shared = 0; + for (size_t i = 0; i < node->n_xattrs; i++) { + struct lcfs_xattr_s *xattr = &node->xattrs[i]; + struct hasher_xattr_s hkey = { .xattr = xattr }; + struct hasher_xattr_s *ent; + + ent = hash_lookup(xattr_hash, &hkey); + assert(ent != NULL); + if (ent->shared && n_shared < EROFS_XATTR_LONG_PREFIX) { + xattr->erofs_shared_xattr_offset = ent->shared_offset; + n_shared++; + } else { + xattr->erofs_shared_xattr_offset = -1; + } + } + } + + free(sorted); + hash_free(xattr_hash); + return 0; + +fail: + errno = ENOMEM; + free(sorted); + hash_free(xattr_hash); + return -1; +} + +static bool lcfs_fits_in_erofs_compact(struct lcfs_ctx_s *ctx, + struct lcfs_node_s *node) +{ + int type = node->inode.st_mode & S_IFMT; + uint64_t size; + + if (node->inode.st_mtim_sec != ctx->min_mtim_sec || + node->inode.st_mtim_nsec != ctx->min_mtim_nsec) { + return false; + } + + if (node->inode.st_nlink > UINT16_MAX || + node->inode.st_uid > UINT16_MAX || node->inode.st_gid > UINT16_MAX) { + return false; + } + + if (type == S_IFDIR) { + size = (uint64_t)node->erofs_n_blocks * EROFS_BLKSIZ + + node->erofs_tailsize; + } else { + size = node->inode.st_size; + } + if (size > UINT32_MAX) { + return false; + } + + return true; +} + +static void compute_erofs_dir_size(struct lcfs_node_s *node) +{ + uint32_t n_blocks = 0; + size_t block_size = 0; + + for (size_t i = 0; i < node->children_size; i++) { + struct lcfs_node_s *child = node->children[i]; + size_t len = sizeof(struct erofs_dirent) + strlen(child->name); + if (block_size + len > EROFS_BLKSIZ) { + n_blocks++; + block_size = 0; + } + block_size += len; + } + + /* As a heuristic, we never inline more than half a block */ + if (block_size > EROFS_BLKSIZ / 2) { + n_blocks++; + block_size = 0; + } + + node->erofs_n_blocks = n_blocks; + node->erofs_tailsize = block_size; +} + +static uint32_t compute_erofs_chunk_bitsize(struct lcfs_node_s *node) +{ + uint64_t file_size = node->inode.st_size; + + // Compute the chunksize to use for the file size + // We want as few chunks as possible, but not an + // unnecessary large chunk. + uint32_t chunkbits = ilog2(file_size - 1) + 1; + + // At least one logical block + if (chunkbits < EROFS_BLKSIZ_BITS) + chunkbits = EROFS_BLKSIZ_BITS; + + // Not larger chunks than max possible + if (chunkbits - EROFS_BLKSIZ_BITS > EROFS_CHUNK_FORMAT_BLKBITS_MASK) + chunkbits = EROFS_CHUNK_FORMAT_BLKBITS_MASK + EROFS_BLKSIZ_BITS; + + return chunkbits; +} + +static void compute_erofs_inode_size(struct lcfs_node_s *node) +{ + int type = node->inode.st_mode & S_IFMT; + uint64_t file_size = node->inode.st_size; + + if (type == S_IFDIR) { + compute_erofs_dir_size(node); + } else if (type == S_IFLNK) { + node->erofs_n_blocks = 0; + node->erofs_tailsize = strlen(node->payload); + } else if (type == S_IFREG && file_size > 0) { + if (node->content != NULL) { + node->erofs_n_blocks = file_size / EROFS_BLKSIZ; + node->erofs_tailsize = file_size % EROFS_BLKSIZ; + if (node->erofs_tailsize > EROFS_BLKSIZ / 2) { + node->erofs_n_blocks++; + node->erofs_tailsize = 0; + } + } else { + uint32_t chunkbits = compute_erofs_chunk_bitsize(node); + uint64_t chunksize = 1ULL << chunkbits; + uint32_t chunk_count = DIV_ROUND_UP(file_size, chunksize); + + node->erofs_n_blocks = 0; + node->erofs_tailsize = chunk_count * sizeof(uint32_t); + } + } else { + node->erofs_n_blocks = 0; + node->erofs_tailsize = 0; + } +} + +static void compute_erofs_xattr_counts(struct lcfs_node_s *node, + size_t *n_shared_xattrs_out, + size_t *unshared_xattrs_size_out) +{ + size_t n_shared_xattrs = 0; + size_t unshared_xattrs_size = 0; + + for (size_t i = 0; i < node->n_xattrs; i++) { + struct lcfs_xattr_s *xattr = &node->xattrs[i]; + if (xattr->erofs_shared_xattr_offset >= 0) { + n_shared_xattrs++; + } else { + unshared_xattrs_size += xattr_erofs_entry_size(xattr); + } + } + + *n_shared_xattrs_out = n_shared_xattrs; + *unshared_xattrs_size_out = unshared_xattrs_size; +} + +static uint32_t compute_erofs_xattr_filter(struct lcfs_node_s *node) +{ + uint32_t name_filter = 0; + + for (size_t i = 0; i < node->n_xattrs; i++) { + struct lcfs_xattr_s *xattr = &node->xattrs[i]; + uint32_t name_filter_bit; + uint8_t index; + char *key; + + index = xattr_erofs_entry_index(xattr, &key); + name_filter_bit = + xxh32(key, strlen(key), EROFS_XATTR_FILTER_SEED + index) & + (EROFS_XATTR_FILTER_BITS - 1); + name_filter |= 1UL << name_filter_bit; + } + + return EROFS_XATTR_FILTER_DEFAULT & ~name_filter; +} + +static uint64_t compute_erofs_inode_padding_for_tail(struct lcfs_node_s *node, + uint64_t pos, size_t inode_size, + size_t xattr_size) +{ + int type = node->inode.st_mode & S_IFMT; + uint64_t block_remainder; + size_t non_tail_size = inode_size + xattr_size; + size_t total_size = inode_size + xattr_size + node->erofs_tailsize; + + /* This adds extra padding in front of an inode to ensure that + * the tail data doesn't cross a block boundary. + */ + + if (type == S_IFLNK) { + /* Due to how erofs_fill_symlink is implemented, we + * need *both* the inode data and the symlink tail + * data in the same block, wheras normally just the + * tail data itself need to be inside a block. + */ + if (pos / EROFS_BLKSIZ != (pos + total_size - 1) / EROFS_BLKSIZ) { + return round_up(pos, EROFS_BLKSIZ) - pos; + } + return 0; + } + + block_remainder = EROFS_BLKSIZ - ((pos + non_tail_size) % EROFS_BLKSIZ); + if (block_remainder < node->erofs_tailsize) { + /* Add (aligned) padding so that tail starts in new block */ + uint64_t extra_pad = round_up(block_remainder, EROFS_SLOTSIZE); + + /* Due to the extra_pad round up it is possible the tail does not fit anyway */ + block_remainder = EROFS_BLKSIZ - + ((pos + non_tail_size + extra_pad) % EROFS_BLKSIZ); + if (node->erofs_tailsize <= block_remainder) { + /* It fit! */ + return extra_pad; + } + /* Didn't fit, don't inline the tail. */ + node->erofs_n_blocks++; + node->erofs_tailsize = 0; + } + + return 0; +} + +static int compute_erofs_inodes(struct lcfs_ctx_s *ctx) +{ + struct lcfs_ctx_erofs_s *ctx_erofs = (struct lcfs_ctx_erofs_s *)ctx; + struct lcfs_node_s *node; + uint64_t pos, ppos; + uint64_t meta_start, extra_pad; + + // Start inode data directly after superblock + pos = EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block); + + // But inode offsets (nids) are relative to start of block + meta_start = round_down(pos, EROFS_BLKSIZ); + + for (node = ctx->root; node != NULL; node = node->next) { + size_t n_shared_xattrs, unshared_xattrs_size; + size_t inode_size, xattr_size; + + compute_erofs_inode_size(node); + node->erofs_compact = lcfs_fits_in_erofs_compact(ctx, node); + inode_size = node->erofs_compact ? + sizeof(struct erofs_inode_compact) : + sizeof(struct erofs_inode_extended); + + compute_erofs_xattr_counts(node, &n_shared_xattrs, + &unshared_xattrs_size); + xattr_size = xattr_erofs_inode_size(n_shared_xattrs, + unshared_xattrs_size); + + /* Align inode start to next slot */ + ppos = pos; + pos = round_up(pos, EROFS_SLOTSIZE); + node->erofs_ipad = pos - ppos; + + /* Ensure tail does not straddle block boundaries */ + extra_pad = compute_erofs_inode_padding_for_tail( + node, pos, inode_size, xattr_size); + node->erofs_ipad += extra_pad; + pos += extra_pad; + + node->erofs_isize = inode_size + xattr_size + node->erofs_tailsize; + ctx_erofs->n_data_blocks += node->erofs_n_blocks; + node->erofs_nid = (pos - meta_start) / EROFS_SLOTSIZE; + + /* Assert that tails never span multiple blocks */ + assert(node->erofs_tailsize == 0 || + ((pos + inode_size + xattr_size) / EROFS_BLKSIZ) == + ((pos + node->erofs_isize - 1) / EROFS_BLKSIZ)); + + pos += node->erofs_isize; + } + + ctx_erofs->inodes_end = round_up(pos, EROFS_SLOTSIZE); + + return 0; +} + +static int write_erofs_xattr(struct lcfs_ctx_s *ctx, struct lcfs_xattr_s *xattr) +{ + struct erofs_xattr_entry e = { 0 }; + int ret; + char *key_suffix; + uint8_t index = xattr_erofs_entry_index(xattr, &key_suffix); + + e.e_name_len = strlen(key_suffix); + e.e_name_index = index; + e.e_value_size = lcfs_u16_to_file(xattr->value_len); + + ret = lcfs_write(ctx, &e, sizeof(e)); + if (ret < 0) + return ret; + + ret = lcfs_write(ctx, key_suffix, strlen(key_suffix)); + if (ret < 0) + return ret; + + ret = lcfs_write(ctx, xattr->value, xattr->value_len); + if (ret < 0) + return ret; + + return lcfs_write_align(ctx, sizeof(uint32_t)); +} + +static int write_erofs_dentries_chunk(struct lcfs_ctx_s *ctx, + struct lcfs_node_s *node, int first_child, + int n_children, int alignment) +{ + uint16_t nameoff = n_children * sizeof(struct erofs_dirent); + int ret; + + for (int i = first_child; i < first_child + n_children; i++) { + struct lcfs_node_s *dirent_child = node->children[i]; + struct lcfs_node_s *target_child = follow_links(dirent_child); + + struct erofs_dirent dirent = { 0 }; + dirent.nid = lcfs_u64_to_file(target_child->erofs_nid); + dirent.nameoff = lcfs_u16_to_file(nameoff); + dirent.file_type = + erofs_make_file_type(node_get_dtype(target_child)); + + nameoff += strlen(dirent_child->name); + + ret = lcfs_write(ctx, &dirent, sizeof(dirent)); + if (ret < 0) + return ret; + } + + for (int i = first_child; i < first_child + n_children; i++) { + struct lcfs_node_s *dirent_child = node->children[i]; + + ret = lcfs_write(ctx, dirent_child->name, strlen(dirent_child->name)); + if (ret < 0) + return ret; + } + + return lcfs_write_align(ctx, alignment); +} + +static int write_erofs_dentries(struct lcfs_ctx_s *ctx, struct lcfs_node_s *node, + bool write_blocks, bool write_tail) +{ + size_t block_size = 0; + size_t block_written = 0; + size_t first = 0; + int ret; + + for (size_t i = 0; i < node->children_size; i++) { + struct lcfs_node_s *child = node->children[i]; + size_t len = sizeof(struct erofs_dirent) + strlen(child->name); + if (block_size + len > EROFS_BLKSIZ) { + if (write_blocks) { + ret = write_erofs_dentries_chunk( + ctx, node, first, i - first, EROFS_BLKSIZ); + if (ret < 0) + return ret; + } + + block_written++; + block_size = 0; + first = i; + } + block_size += len; + } + + /* Handle the remaining block which is either tailpacked or block as decided before */ + + if (block_written < node->erofs_n_blocks) { + if (write_blocks) { + ret = write_erofs_dentries_chunk(ctx, node, first, + node->children_size - first, + EROFS_BLKSIZ); + if (ret < 0) + return ret; + } + + block_written++; + block_size = 0; + first = node->children_size; + } + + if (write_tail && block_size > 0) { + ret = write_erofs_dentries_chunk(ctx, node, first, + node->children_size - first, 1); + if (ret < 0) + return ret; + } + + return 0; +} + +static int write_erofs_inode_data(struct lcfs_ctx_s *ctx, struct lcfs_node_s *node) +{ + struct lcfs_ctx_erofs_s *ctx_erofs = (struct lcfs_ctx_erofs_s *)ctx; + int type = node->inode.st_mode & S_IFMT; + size_t xattr_icount; + uint64_t size; + int ret; + uint16_t format; + uint16_t version; + uint16_t datalayout; + off_t orig_bytes_written = ctx->bytes_written; + size_t n_shared_xattrs; + size_t unshared_xattrs_size; + size_t xattr_size; + uint32_t chunk_count = 0; + uint16_t chunk_format = 0; + + ret = lcfs_write_pad(ctx, node->erofs_ipad); + if (ret < 0) + return ret; + + /* All inodes start on slot boundary */ + assert(ctx->bytes_written % EROFS_SLOTSIZE == 0); + + /* compute xattr details */ + + compute_erofs_xattr_counts(node, &n_shared_xattrs, &unshared_xattrs_size); + xattr_size = xattr_erofs_inode_size(n_shared_xattrs, unshared_xattrs_size); + xattr_icount = xattr_erofs_icount(xattr_size); + + version = node->erofs_compact ? 0 : 1; + datalayout = (node->erofs_tailsize > 0) ? EROFS_INODE_FLAT_INLINE : + EROFS_INODE_FLAT_PLAIN; + + if (type == S_IFDIR || type == S_IFLNK) { + size = (uint64_t)node->erofs_n_blocks * EROFS_BLKSIZ + + node->erofs_tailsize; + } else if (type == S_IFREG) { + size = node->inode.st_size; + + if (size > 0 && node->content == NULL) { + uint32_t chunkbits = compute_erofs_chunk_bitsize(node); + uint64_t chunksize = 1ULL << chunkbits; + + datalayout = EROFS_INODE_CHUNK_BASED; + chunk_count = DIV_ROUND_UP(size, chunksize); + chunk_format = chunkbits - EROFS_BLKSIZ_BITS; + } + } else { + size = 0; + } + + format = datalayout << EROFS_I_DATALAYOUT_BIT | version << EROFS_I_VERSION_BIT; + + if (node->erofs_compact) { + struct erofs_inode_compact i = { 0 }; + i.i_format = lcfs_u16_to_file(format); + i.i_xattr_icount = lcfs_u16_to_file(xattr_icount); + i.i_mode = lcfs_u16_to_file(node->inode.st_mode); + i.i_nlink = lcfs_u16_to_file(node->inode.st_nlink); + i.i_size = lcfs_u32_to_file(size); + i.i_ino = lcfs_u32_to_file(node->inode_num); + i.i_uid = lcfs_u16_to_file(node->inode.st_uid); + i.i_gid = lcfs_u16_to_file(node->inode.st_gid); + + if (type == S_IFDIR) { + if (node->erofs_n_blocks > 0) { + i.i_u.raw_blkaddr = lcfs_u32_to_file( + ctx_erofs->current_end / EROFS_BLKSIZ); + ctx_erofs->current_end += + EROFS_BLKSIZ * node->erofs_n_blocks; + } + } else if (type == S_IFCHR || type == S_IFBLK) { + i.i_u.rdev = lcfs_u32_to_file(node->inode.st_rdev); + } else if (type == S_IFREG) { + if (node->erofs_n_blocks > 0) { + i.i_u.raw_blkaddr = lcfs_u32_to_file( + ctx_erofs->current_end / EROFS_BLKSIZ); + ctx_erofs->current_end += + EROFS_BLKSIZ * node->erofs_n_blocks; + } + if (datalayout == EROFS_INODE_CHUNK_BASED) { + i.i_u.c.format = lcfs_u16_to_file(chunk_format); + } + } + + ret = lcfs_write(ctx, &i, sizeof(i)); + if (ret < 0) + return ret; + } else { + struct erofs_inode_extended i = { 0 }; + i.i_format = lcfs_u16_to_file(format); + i.i_xattr_icount = lcfs_u16_to_file(xattr_icount); + i.i_mode = lcfs_u16_to_file(node->inode.st_mode); + i.i_nlink = lcfs_u32_to_file(node->inode.st_nlink); + i.i_size = lcfs_u64_to_file(size); + i.i_ino = lcfs_u32_to_file(node->inode_num); + i.i_uid = lcfs_u32_to_file(node->inode.st_uid); + i.i_gid = lcfs_u32_to_file(node->inode.st_gid); + i.i_mtime = lcfs_u64_to_file(node->inode.st_mtim_sec); + i.i_mtime_nsec = lcfs_u64_to_file(node->inode.st_mtim_nsec); + + if (type == S_IFDIR) { + if (node->erofs_n_blocks > 0) { + i.i_u.raw_blkaddr = lcfs_u32_to_file( + ctx_erofs->current_end / EROFS_BLKSIZ); + ctx_erofs->current_end += + EROFS_BLKSIZ * node->erofs_n_blocks; + } + } else if (type == S_IFCHR || type == S_IFBLK) { + i.i_u.rdev = lcfs_u32_to_file(node->inode.st_rdev); + } else if (type == S_IFREG) { + if (node->erofs_n_blocks > 0) { + i.i_u.raw_blkaddr = lcfs_u32_to_file( + ctx_erofs->current_end / EROFS_BLKSIZ); + ctx_erofs->current_end += + EROFS_BLKSIZ * node->erofs_n_blocks; + } + if (datalayout == EROFS_INODE_CHUNK_BASED) { + i.i_u.c.format = lcfs_u16_to_file(chunk_format); + } + } + + ret = lcfs_write(ctx, &i, sizeof(i)); + if (ret < 0) + return ret; + } + + /* write xattrs */ + if (xattr_size) { + struct erofs_xattr_ibody_header xattr_header = { 0 }; + xattr_header.h_shared_count = n_shared_xattrs; + xattr_header.h_name_filter = + lcfs_u32_to_file(compute_erofs_xattr_filter(node)); + + ret = lcfs_write(ctx, &xattr_header, sizeof(xattr_header)); + if (ret < 0) + return ret; + + /* shared */ + for (size_t i = 0; i < node->n_xattrs; i++) { + struct lcfs_xattr_s *xattr = &node->xattrs[i]; + if (xattr->erofs_shared_xattr_offset >= 0) { + uint64_t offset = + ctx_erofs->inodes_end % EROFS_BLKSIZ + + xattr->erofs_shared_xattr_offset; + uint32_t v = + lcfs_u32_to_file(offset / sizeof(uint32_t)); + ret = lcfs_write(ctx, &v, sizeof(v)); + if (ret < 0) + return ret; + } + } + /* unshared */ + for (size_t i = 0; i < node->n_xattrs; i++) { + struct lcfs_xattr_s *xattr = &node->xattrs[i]; + if (xattr->erofs_shared_xattr_offset < 0) { + ret = write_erofs_xattr(ctx, xattr); + if (ret < 0) + return ret; + } + } + } + + if (type == S_IFDIR) { + ret = write_erofs_dentries(ctx, node, false, true); + if (ret < 0) + return ret; + } else if (type == S_IFLNK) { + ret = lcfs_write(ctx, node->payload, strlen(node->payload)); + if (ret < 0) + return ret; + } else if (type == S_IFREG) { + if (node->content != NULL) { + if (node->erofs_tailsize) { + uint64_t file_size = node->inode.st_size; + ret = lcfs_write(ctx, + node->content + file_size - + node->erofs_tailsize, + node->erofs_tailsize); + if (ret < 0) + return ret; + } + } else { + for (size_t i = 0; i < chunk_count; i++) { + uint32_t empty_chunk = 0xFFFFFFFF; + ret = lcfs_write(ctx, &empty_chunk, + sizeof(empty_chunk)); + if (ret < 0) + return ret; + } + } + } + + assert(ctx->bytes_written - orig_bytes_written == + node->erofs_isize + node->erofs_ipad); + + return 0; +} + +static int write_erofs_inodes(struct lcfs_ctx_s *ctx) +{ + struct lcfs_node_s *node; + int ret; + + for (node = ctx->root; node != NULL; node = node->next) { + ret = write_erofs_inode_data(ctx, node); + if (ret < 0) + return ret; + } + + ret = lcfs_write_align(ctx, EROFS_SLOTSIZE); + if (ret < 0) + return ret; + + return 0; +} + +/* Writes the non-tailpacked file data, if any */ +static int write_erofs_file_content(struct lcfs_ctx_s *ctx, struct lcfs_node_s *node) +{ + int type = node->inode.st_mode & S_IFMT; + off_t size = node->inode.st_size; + + if (type != S_IFREG || node->erofs_n_blocks == 0) + return 0; + + assert(node->content != NULL); + + for (size_t i = 0; i < node->erofs_n_blocks; i++) { + off_t offset = i * EROFS_BLKSIZ; + off_t len = min(size - offset, EROFS_BLKSIZ); + int ret; + + ret = lcfs_write(ctx, node->content + offset, len); + if (ret < 0) + return ret; + } + + return lcfs_write_align(ctx, EROFS_BLKSIZ); +} + +static int write_erofs_data_blocks(struct lcfs_ctx_s *ctx) +{ + struct lcfs_node_s *node; + int ret; + + for (node = ctx->root; node != NULL; node = node->next) { + ret = write_erofs_dentries(ctx, node, true, false); + if (ret < 0) + return ret; + ret = write_erofs_file_content(ctx, node); + if (ret < 0) + return ret; + } + + return 0; +} + +static int write_erofs_shared_xattrs(struct lcfs_ctx_s *ctx) +{ + struct lcfs_ctx_erofs_s *ctx_erofs = (struct lcfs_ctx_erofs_s *)ctx; + int ret; + + for (size_t i = 0; i < ctx_erofs->n_shared_xattrs; i++) { + struct lcfs_xattr_s *xattr = ctx_erofs->shared_xattrs[i]; + ret = write_erofs_xattr(ctx, xattr); + if (ret < 0) + return ret; + } + + return 0; +} + +static int add_overlayfs_xattrs(struct lcfs_node_s *node) +{ + int type = node->inode.st_mode & S_IFMT; + int ret; + + /* First escape all existing "trusted.overlay.*" xattrs */ + for (size_t i = 0; i < lcfs_node_get_n_xattr(node); i++) { + const char *name = lcfs_node_get_xattr_name(node, i); + + if (str_has_prefix(name, OVERLAY_XATTR_PREFIX)) { + cleanup_free char *renamed = + str_join(OVERLAY_XATTR_ESCAPE_PREFIX, + name + strlen(OVERLAY_XATTR_PREFIX)); + if (renamed == NULL) { + errno = ENOMEM; + return -1; + } + /* We rename in-place, this is safe from + collisions because we also rename any + colliding xattr */ + if (lcfs_node_rename_xattr(node, i, renamed) < 0) + return -1; + } + } + + if (type == S_IFREG && node->inode.st_size > 0 && node->content == NULL) { + uint8_t xattr_data[4 + LCFS_DIGEST_SIZE]; + size_t xattr_len = 0; + + if (node->digest_set) { + xattr_len = sizeof(xattr_data); + xattr_data[0] = 0; /* version */ + xattr_data[1] = xattr_len; + xattr_data[2] = 0; /* flags */ + xattr_data[3] = FS_VERITY_HASH_ALG_SHA256; + memcpy(xattr_data + 4, node->digest, LCFS_DIGEST_SIZE); + } + + ret = lcfs_node_set_xattr(node, OVERLAY_XATTR_METACOPY, + (const char *)xattr_data, xattr_len); + if (ret < 0) + return ret; + + if (node->payload && strlen(node->payload) > 0) { + char *path = maybe_join_path("/", node->payload); + if (path == NULL) { + errno = ENOMEM; + return -1; + } + ret = lcfs_node_set_xattr(node, OVERLAY_XATTR_REDIRECT, + path, strlen(path)); + free(path); + if (ret < 0) + return ret; + } + } + + /* escape whiteouts */ + if (type == S_IFCHR && node->inode.st_rdev == makedev(0, 0)) { + struct lcfs_node_s *parent = lcfs_node_get_parent(node); + + lcfs_node_set_mode(node, + S_IFREG | (lcfs_node_get_mode(node) & ~S_IFMT)); + ret = lcfs_node_set_xattr(node, OVERLAY_XATTR_ESCAPED_WHITEOUT, + "", 0); + if (ret < 0) + return ret; + ret = lcfs_node_set_xattr(node, OVERLAY_XATTR_USERXATTR_WHITEOUT, + "", 0); + if (ret < 0) + return ret; + + /* Mark parent dir containing whiteouts */ + ret = lcfs_node_set_xattr(parent, + OVERLAY_XATTR_ESCAPED_WHITEOUTS, "", 0); + if (ret < 0) + return ret; + ret = lcfs_node_set_xattr(parent, OVERLAY_XATTR_USERXATTR_WHITEOUTS, + "", 0); + if (ret < 0) + return ret; + } + + return 0; +} + +static int add_overlay_whiteouts(struct lcfs_node_s *root) +{ + static const char hexchars[] = "0123456789abcdef"; + const char *selinux; + size_t selinux_len; + int res; + + selinux = lcfs_node_get_xattr(root, "security.selinux", &selinux_len); + + for (int i = 0; i <= 255; i++) { + struct lcfs_node_s *child; + char name[3]; + + name[0] = hexchars[(i >> 4) % 16]; + name[1] = hexchars[i % 16]; + name[2] = 0; + + child = lcfs_node_lookup_child(root, name); + if (child != NULL) + continue; + + child = lcfs_node_new(); + if (child == NULL) { + errno = ENOMEM; + return -1; + } + + lcfs_node_set_mode(child, S_IFCHR | 0644); + lcfs_node_set_rdev(child, 0); + + child->inode.st_uid = root->inode.st_uid; + child->inode.st_gid = root->inode.st_gid; + child->inode.st_mtim_sec = root->inode.st_mtim_sec; + child->inode.st_mtim_nsec = root->inode.st_mtim_nsec; + + /* Inherit selinux context from root dir */ + if (selinux != NULL) { + res = lcfs_node_set_xattr(child, "security.selinux", + selinux, selinux_len); + if (res < 0) { + lcfs_node_unref(child); + return res; + } + } + + res = lcfs_node_add_child(root, child, name); + if (res < 0) + return res; + } + + return 0; +} + +static int rewrite_tree_node_for_erofs(struct lcfs_node_s *node, + struct lcfs_node_s *parent) +{ + int ret; + + ret = add_overlayfs_xattrs(node); + if (ret < 0) + return ret; + + if (lcfs_node_dirp(node)) { + struct lcfs_node_s *existing; + + /* Ensure we have . and .. */ + existing = lcfs_node_lookup_child(node, "."); + if (existing == NULL) { + struct lcfs_node_s *link = lcfs_node_new(); + if (link == NULL) { + errno = ENOMEM; + return -1; + } + lcfs_node_make_hardlink(link, node); + ret = lcfs_node_add_child(node, link, "."); + if (ret < 0) { + lcfs_node_unref(link); + return -1; + } + } + + existing = lcfs_node_lookup_child(node, ".."); + if (existing == NULL) { + struct lcfs_node_s *link = lcfs_node_new(); + if (link == NULL) { + errno = ENOMEM; + return -1; + } + lcfs_node_make_hardlink(link, parent); + ret = lcfs_node_add_child(node, link, ".."); + if (ret < 0) { + lcfs_node_unref(link); + return -1; + } + } + + for (size_t i = 0; i < node->children_size; ++i) { + struct lcfs_node_s *child = node->children[i]; + + if (child->link_to != NULL) { + continue; + } + + ret = rewrite_tree_node_for_erofs(child, node); + if (ret < 0) { + return -1; + } + } + } + + return 0; +} + +static int set_overlay_opaque(struct lcfs_node_s *node) +{ + int ret; + + ret = lcfs_node_set_xattr(node, OVERLAY_XATTR_OPAQUE, "y", 1); + if (ret < 0) + return ret; + + return 0; +} + +static int rewrite_tree_for_erofs(struct lcfs_node_s *root) +{ + int res; + + res = rewrite_tree_node_for_erofs(root, root); + if (res < 0) + return res; + + res = set_overlay_opaque(root); + if (res < 0) + return res; + + res = add_overlay_whiteouts(root); + if (res < 0) + return res; + + return 0; +} + +int lcfs_write_erofs_to(struct lcfs_ctx_s *ctx) +{ + struct lcfs_ctx_erofs_s *ctx_erofs = (struct lcfs_ctx_erofs_s *)ctx; + struct lcfs_node_s *root; + struct lcfs_erofs_header_s header = { + .magic = lcfs_u32_to_file(LCFS_EROFS_MAGIC), + .version = lcfs_u32_to_file(LCFS_EROFS_VERSION), + }; + uint32_t header_flags; + struct erofs_super_block superblock = { + .magic = lcfs_u32_to_file(EROFS_SUPER_MAGIC_V1), + .blkszbits = EROFS_BLKSIZ_BITS, + }; + int ret = 0; + uint64_t data_block_start; + + if (ctx->options->version != 0) { + errno = -EINVAL; + return -1; + } + + /* Clone root so we can make required modifications to it */ + ret = lcfs_clone_root(ctx); + if (ret < 0) + return ret; + + root = ctx->root; /* After we cloned it */ + + /* Rewrite cloned tree as needed for erofs */ + ret = rewrite_tree_for_erofs(root); + if (ret < 0) + return ret; + + ret = lcfs_compute_tree(ctx, root); + if (ret < 0) + return ret; + + ret = compute_erofs_shared_xattrs(ctx); + if (ret < 0) + return ret; + + ret = compute_erofs_inodes(ctx); + if (ret < 0) + return ret; + + header_flags = 0; + if (ctx->has_acl) + header_flags |= LCFS_EROFS_FLAGS_HAS_ACL; + header.flags = lcfs_u32_to_file(header_flags); + + ret = lcfs_write(ctx, &header, sizeof(header)); + if (ret < 0) + return ret; + + ret = lcfs_write_pad(ctx, EROFS_SUPER_OFFSET - sizeof(header)); + if (ret < 0) + return ret; + + superblock.feature_compat = lcfs_u32_to_file( + EROFS_FEATURE_COMPAT_MTIME | EROFS_FEATURE_COMPAT_XATTR_FILTER); + superblock.inos = lcfs_u64_to_file(ctx->num_inodes); + + superblock.build_time = lcfs_u64_to_file(ctx->min_mtim_sec); + superblock.build_time_nsec = lcfs_u32_to_file(ctx->min_mtim_nsec); + + /* metadata is stored directly after superblock */ + superblock.meta_blkaddr = lcfs_u32_to_file( + (EROFS_SUPER_OFFSET + sizeof(superblock)) / EROFS_BLKSIZ); + assert(root->erofs_nid < UINT16_MAX); + superblock.root_nid = lcfs_u16_to_file(root->erofs_nid); + + /* shared xattrs is directly after metadata */ + superblock.xattr_blkaddr = + lcfs_u32_to_file(ctx_erofs->inodes_end / EROFS_BLKSIZ); + + data_block_start = + round_up(ctx_erofs->inodes_end + ctx_erofs->shared_xattr_size, + EROFS_BLKSIZ); + + superblock.blocks = lcfs_u32_to_file(data_block_start / EROFS_BLKSIZ + + ctx_erofs->n_data_blocks); + + /* TODO: More superblock fields: + * uuid? + * volume_name? + */ + + ret = lcfs_write(ctx, &superblock, sizeof(superblock)); + if (ret < 0) + return ret; + + ctx_erofs->current_end = data_block_start; + + ret = write_erofs_inodes(ctx); + if (ret < 0) + return ret; + + assert(ctx_erofs->inodes_end == (uint64_t)ctx->bytes_written); + + ret = write_erofs_shared_xattrs(ctx); + if (ret < 0) + return ret; + + assert(ctx_erofs->inodes_end + ctx_erofs->shared_xattr_size == + (uint64_t)ctx->bytes_written); + + /* Following are full blocks and must be block-aligned */ + ret = lcfs_write_align(ctx, EROFS_BLKSIZ); + if (ret < 0) + return ret; + + assert(data_block_start == (uint64_t)ctx->bytes_written); + + ret = write_erofs_data_blocks(ctx); + if (ret < 0) + return ret; + + assert(ctx_erofs->current_end == (uint64_t)ctx->bytes_written); + assert(data_block_start + ctx_erofs->n_data_blocks * EROFS_BLKSIZ == + (uint64_t)ctx->bytes_written); + + return 0; +} + +struct hasher_node_s { + uint64_t nid; + struct lcfs_node_s *node; +}; + +struct lcfs_image_data { + const uint8_t *erofs_data; + size_t erofs_data_size; + const uint8_t *erofs_metadata; + const uint8_t *erofs_metadata_end; + const uint8_t *erofs_xattrdata; + const uint8_t *erofs_xattrdata_end; + uint64_t erofs_build_time; + uint32_t erofs_build_time_nsec; + Hash_table *node_hash; +}; + +static const erofs_inode *lcfs_image_get_erofs_inode(struct lcfs_image_data *data, + uint64_t nid) +{ + const uint8_t *inode_data = data->erofs_metadata + (nid << EROFS_ISLOTBITS); + + if (inode_data >= data->erofs_metadata_end) + return NULL; + + return (const erofs_inode *)inode_data; +} + +static struct lcfs_node_s *lcfs_build_node_from_image(struct lcfs_image_data *data, + uint64_t nid); + +static int erofs_readdir_block(struct lcfs_image_data *data, + struct lcfs_node_s *parent, const uint8_t *block, + size_t block_size) +{ + const struct erofs_dirent *dirents = (struct erofs_dirent *)block; + size_t dirents_size = lcfs_u16_from_file(dirents[0].nameoff); + size_t n_dirents, i; + + if (dirents_size % sizeof(struct erofs_dirent) != 0) { + /* This should not happen for valid filesystems */ + errno = EINVAL; + return -1; + } + + n_dirents = dirents_size / sizeof(struct erofs_dirent); + + for (i = 0; i < n_dirents; i++) { + char name_buf[PATH_MAX]; + uint64_t nid = lcfs_u64_from_file(dirents[i].nid); + uint16_t nameoff = lcfs_u16_from_file(dirents[i].nameoff); + const char *child_name; + uint16_t child_name_len; + cleanup_node struct lcfs_node_s *child = NULL; + + /* Compute length of the name, which is a bit weird for the last dirent */ + child_name = (char *)(block + nameoff); + if (i + 1 < n_dirents) + child_name_len = + lcfs_u16_from_file(dirents[i + 1].nameoff) - nameoff; + else + child_name_len = strnlen(child_name, block_size - nameoff); + + if ((child_name_len == 1 && child_name[0] == '.') || + (child_name_len == 2 && child_name[0] == '.' && + child_name[1] == '.')) + continue; + + /* Copy to null terminate */ + child_name_len = min(child_name_len, PATH_MAX - 1); + memcpy(name_buf, child_name, child_name_len); + name_buf[child_name_len] = 0; + + child = lcfs_build_node_from_image(data, nid); + if (child == NULL) { + if (errno == ENOTSUP) + continue; /* Skip real whiteouts (00-ff) */ + } + + if (lcfs_node_add_child(parent, child, /* Takes ownership on success */ + name_buf) < 0) + return -1; + steal_pointer(&child); + } + + return 0; +} + +static int lcfs_build_node_erofs_xattr(struct lcfs_node_s *node, uint8_t name_index, + const char *entry_name, uint8_t name_len, + const char *value, uint16_t value_size) +{ + cleanup_free char *name = + erofs_get_xattr_name(name_index, entry_name, name_len); + if (name == NULL) + return -1; + + if (strcmp(name, OVERLAY_XATTR_REDIRECT) == 0) { + if ((node->inode.st_mode & S_IFMT) == S_IFREG) { + if (value_size > 1 && value[0] == '/') { + value_size++; + value++; + } + node->payload = strndup(value, value_size); + if (node->payload == NULL) { + errno = EINVAL; + return -1; + } + } + return 0; + } + + if (strcmp(name, OVERLAY_XATTR_METACOPY) == 0) { + if ((node->inode.st_mode & S_IFMT) == S_IFREG && + value_size == 4 + LCFS_DIGEST_SIZE) + lcfs_node_set_fsverity_digest(node, (uint8_t *)value + 4); + return 0; + } + + if (strcmp(name, OVERLAY_XATTR_ESCAPED_WHITEOUT) == 0 && + (node->inode.st_mode & S_IFMT) == S_IFREG) { + /* Rewrite to regular whiteout */ + node->inode.st_mode = (node->inode.st_mode & ~S_IFMT) | S_IFCHR; + node->inode.st_rdev = makedev(0, 0); + node->inode.st_size = 0; + return 0; + } + if (strcmp(name, OVERLAY_XATTR_ESCAPED_WHITEOUTS) == 0 || + strcmp(name, OVERLAY_XATTR_USERXATTR_WHITEOUT) == 0 || + strcmp(name, OVERLAY_XATTR_USERXATTR_WHITEOUTS) == 0) { + /* skip */ + return 0; + } + + if (str_has_prefix(name, OVERLAY_XATTR_PREFIX)) { + if (str_has_prefix(name, OVERLAY_XATTR_ESCAPE_PREFIX)) { + /* Unescape */ + memmove(name + strlen(OVERLAY_XATTR_TRUSTED_PREFIX), + name + strlen(OVERLAY_XATTR_PREFIX), + strlen(name) - strlen(OVERLAY_XATTR_PREFIX) + 1); + } else { + /* skip */ + return 0; + } + } + + if (lcfs_node_set_xattr(node, name, value, value_size) < 0) + return -1; + + return 0; +} + +static struct lcfs_node_s *lcfs_build_node_from_image(struct lcfs_image_data *data, + uint64_t nid) +{ + const erofs_inode *cino; + cleanup_node struct lcfs_node_s *node = NULL; + uint64_t file_size; + uint16_t xattr_icount; + uint32_t raw_blkaddr; + int type; + size_t isize; + bool tailpacked; + size_t xattr_size; + struct hasher_node_s ht_entry = { nid }; + struct hasher_node_s *new_ht_entry; + struct hasher_node_s *existing; + uint64_t n_blocks; + uint64_t last_oob_block; + size_t tail_size; + const uint8_t *tail_data; + const uint8_t *oob_data; + + cino = lcfs_image_get_erofs_inode(data, nid); + if (cino == NULL) + return NULL; + + node = lcfs_node_new(); + if (node == NULL) { + errno = ENOMEM; + return NULL; + } + + existing = hash_lookup(data->node_hash, &ht_entry); + if (existing) { + node->link_to = lcfs_node_ref(existing->node); + return steal_pointer(&node); + } + + new_ht_entry = malloc(sizeof(struct hasher_node_s)); + if (new_ht_entry == NULL) { + errno = ENOMEM; + return NULL; + } + new_ht_entry->nid = nid; + new_ht_entry->node = node; + if (hash_insert(data->node_hash, new_ht_entry) == NULL) { + errno = ENOMEM; + return NULL; + } + + if (erofs_inode_is_compact(cino)) { + const struct erofs_inode_compact *c = &cino->compact; + + node->inode.st_mode = lcfs_u16_from_file(c->i_mode); + node->inode.st_nlink = lcfs_u16_from_file(c->i_nlink); + node->inode.st_size = lcfs_u32_from_file(c->i_size); + node->inode.st_uid = lcfs_u16_from_file(c->i_uid); + node->inode.st_gid = lcfs_u16_from_file(c->i_gid); + + node->inode.st_mtim_sec = data->erofs_build_time; + node->inode.st_mtim_nsec = data->erofs_build_time_nsec; + + type = node->inode.st_mode & S_IFMT; + + if (type == S_IFCHR || type == S_IFBLK) + node->inode.st_rdev = lcfs_u32_from_file(c->i_u.rdev); + + file_size = lcfs_u32_from_file(c->i_size); + xattr_icount = lcfs_u16_from_file(c->i_xattr_icount); + raw_blkaddr = lcfs_u32_from_file(c->i_u.raw_blkaddr); + isize = sizeof(struct erofs_inode_compact); + + } else { + const struct erofs_inode_extended *e = &cino->extended; + + node->inode.st_mode = lcfs_u16_from_file(e->i_mode); + node->inode.st_size = lcfs_u64_from_file(e->i_size); + node->inode.st_uid = lcfs_u32_from_file(e->i_uid); + node->inode.st_gid = lcfs_u32_from_file(e->i_gid); + node->inode.st_mtim_sec = lcfs_u64_from_file(e->i_mtime); + node->inode.st_mtim_nsec = lcfs_u32_from_file(e->i_mtime_nsec); + node->inode.st_nlink = lcfs_u32_from_file(e->i_nlink); + + type = node->inode.st_mode & S_IFMT; + + if (type == S_IFCHR || type == S_IFBLK) + node->inode.st_rdev = lcfs_u32_from_file(e->i_u.rdev); + + file_size = lcfs_u64_from_file(e->i_size); + xattr_icount = lcfs_u16_from_file(e->i_xattr_icount); + raw_blkaddr = lcfs_u32_from_file(e->i_u.raw_blkaddr); + isize = sizeof(struct erofs_inode_extended); + } + + if (type == S_IFCHR && node->inode.st_rdev == 0) { + errno = ENOTSUP; /* Use this to signal that we found a whiteout */ + return NULL; + } + + xattr_size = erofs_xattr_inode_size(xattr_icount); + + tailpacked = erofs_inode_is_tailpacked(cino); + tail_size = tailpacked ? file_size % EROFS_BLKSIZ : 0; + tail_data = ((uint8_t *)cino) + isize + xattr_size; + oob_data = data->erofs_data + raw_blkaddr * EROFS_BLKSIZ; + + n_blocks = round_up(file_size, EROFS_BLKSIZ) / EROFS_BLKSIZ; + last_oob_block = tailpacked ? n_blocks - 1 : n_blocks; + + if (type == S_IFDIR) { + /* First read the out-of-band blocks */ + for (uint64_t block = 0; block < last_oob_block; block++) { + const uint8_t *block_data = oob_data + block * EROFS_BLKSIZ; + size_t block_size = EROFS_BLKSIZ; + + if (!tailpacked && block + 1 == last_oob_block) { + block_size = file_size % EROFS_BLKSIZ; + if (block_size == 0) { + block_size = EROFS_BLKSIZ; + } + } + + if (erofs_readdir_block(data, node, block_data, block_size) < 0) + return NULL; + } + + /* Then inline */ + if (tailpacked) { + if (erofs_readdir_block(data, node, tail_data, tail_size) < 0) + return NULL; + } + + } else if (type == S_IFLNK) { + char name_buf[PATH_MAX]; + + if (file_size >= PATH_MAX || !tailpacked) { + errno = -EINVAL; + return NULL; + } + + memcpy(name_buf, tail_data, file_size); + name_buf[file_size] = 0; + if (lcfs_node_set_payload(node, name_buf) < 0) + return NULL; + + } else if (type == S_IFREG && file_size != 0 && erofs_inode_is_flat(cino)) { + cleanup_free uint8_t *content = NULL; + size_t oob_size; + + content = malloc(file_size); + if (content == NULL) { + errno = ENOMEM; + return NULL; + } + + oob_size = tailpacked ? last_oob_block * EROFS_BLKSIZ : file_size; + memcpy(content, data->erofs_data + raw_blkaddr * EROFS_BLKSIZ, + oob_size); + if (tailpacked) + memcpy(content + oob_size, tail_data, tail_size); + + lcfs_node_set_content(node, content, file_size); + } + + if (xattr_icount > 0) { + const struct erofs_xattr_ibody_header *xattr_header; + const uint8_t *xattrs_inline; + const uint8_t *xattrs_start; + const uint8_t *xattrs_end; + uint8_t shared_count; + + xattrs_start = ((uint8_t *)cino) + isize; + xattrs_end = ((uint8_t *)cino) + isize + xattr_size; + xattr_header = (struct erofs_xattr_ibody_header *)xattrs_start; + shared_count = xattr_header->h_shared_count; + + xattrs_inline = xattrs_start + + sizeof(struct erofs_xattr_ibody_header) + + shared_count * 4; + + /* Inline xattrs */ + while (xattrs_inline + sizeof(struct erofs_xattr_entry) < xattrs_end) { + const struct erofs_xattr_entry *entry = + (const struct erofs_xattr_entry *)xattrs_inline; + const char *entry_data = (const char *)entry + + sizeof(struct erofs_xattr_entry); + const char *entry_name = entry_data; + uint8_t name_len = entry->e_name_len; + uint8_t name_index = entry->e_name_index; + const char *value = entry_data + name_len; + uint16_t value_size = + lcfs_u16_from_file(entry->e_value_size); + size_t el_size = round_up(sizeof(struct erofs_xattr_entry) + + name_len + value_size, + 4); + + if (lcfs_build_node_erofs_xattr(node, name_index, + entry_name, name_len, + value, value_size) < 0) + return NULL; + + xattrs_inline += el_size; + } + + /* Shared xattrs */ + for (int i = 0; i < shared_count; i++) { + uint32_t idx = lcfs_u32_from_file( + xattr_header->h_shared_xattrs[i]); + const struct erofs_xattr_entry *entry = + (const struct erofs_xattr_entry *)(data->erofs_xattrdata + + idx * 4); + const char *entry_data = (const char *)entry + + sizeof(struct erofs_xattr_entry); + const char *entry_name = entry_data; + uint8_t name_len = entry->e_name_len; + uint8_t name_index = entry->e_name_index; + const char *value = entry_data + name_len; + uint16_t value_size = + lcfs_u16_from_file(entry->e_value_size); + + if (lcfs_build_node_erofs_xattr(node, name_index, + entry_name, name_len, + value, value_size) < 0) + return NULL; + } + } + + return steal_pointer(&node); +} + +static size_t node_ht_hasher(const void *d, size_t n) +{ + const struct hasher_node_s *v = d; + return v->nid % n; +} + +static bool node_ht_comparator(const void *d1, const void *d2) +{ + const struct hasher_node_s *v1 = d1; + const struct hasher_node_s *v2 = d2; + + return v1->nid == v2->nid; +} + +struct lcfs_node_s *lcfs_load_node_from_image(const uint8_t *image_data, + size_t image_data_size) +{ + const uint8_t *image_data_end; + struct lcfs_image_data data = { image_data, image_data_size }; + const struct lcfs_erofs_header_s *cfs_header; + const struct erofs_super_block *erofs_super; + uint64_t erofs_root_nid; + struct lcfs_node_s *root; + + if (image_data_size < EROFS_BLKSIZ) { + errno = EINVAL; + return NULL; + } + + /* Avoid wrapping */ + image_data_end = image_data + image_data_size; + if (image_data_end < image_data) { + errno = EINVAL; + return NULL; + } + + cfs_header = (struct lcfs_erofs_header_s *)(image_data); + if (lcfs_u32_from_file(cfs_header->magic) != LCFS_EROFS_MAGIC) { + errno = EINVAL; /* Wrong cfs magic */ + return NULL; + } + + if (lcfs_u32_from_file(cfs_header->version) != LCFS_EROFS_VERSION) { + errno = ENOTSUP; /* Wrong cfs version */ + return NULL; + } + + erofs_super = (struct erofs_super_block *)(image_data + EROFS_SUPER_OFFSET); + + if (lcfs_u32_from_file(erofs_super->magic) != EROFS_SUPER_MAGIC_V1) { + errno = EINVAL; /* Wrong erofs magic */ + return NULL; + } + + data.erofs_metadata = + image_data + + lcfs_u32_from_file(erofs_super->meta_blkaddr) * EROFS_BLKSIZ; + data.erofs_xattrdata = + image_data + + lcfs_u32_from_file(erofs_super->xattr_blkaddr) * EROFS_BLKSIZ; + + if (data.erofs_metadata >= image_data_end || + data.erofs_xattrdata >= image_data_end) { + errno = EINVAL; + return NULL; + } + + data.erofs_metadata_end = image_data_end; + data.erofs_xattrdata_end = image_data_end; + + data.erofs_build_time = lcfs_u64_from_file(erofs_super->build_time); + data.erofs_build_time_nsec = + lcfs_u32_from_file(erofs_super->build_time_nsec); + + erofs_root_nid = lcfs_u16_from_file(erofs_super->root_nid); + + data.node_hash = + hash_initialize(0, NULL, node_ht_hasher, node_ht_comparator, free); + if (data.node_hash == NULL) { + errno = ENOMEM; + return NULL; + } + + root = lcfs_build_node_from_image(&data, erofs_root_nid); + + hash_free(data.node_hash); + + return root; +} diff --git a/composefs/libcomposefs/lcfs-writer.c b/composefs/libcomposefs/lcfs-writer.c new file mode 100644 index 0000000..13a8e06 --- /dev/null +++ b/composefs/libcomposefs/lcfs-writer.c @@ -0,0 +1,1338 @@ +/* lcfs + Copyright (C) 2021 Giuseppe Scrivano + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#define _GNU_SOURCE + +#include "config.h" + +#include "lcfs-internal.h" +#include "lcfs-writer.h" +#include "lcfs-utils.h" +#include "lcfs-fsverity.h" +#include "hash.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void lcfs_node_remove_all_children(struct lcfs_node_s *node); +static void lcfs_node_destroy(struct lcfs_node_s *node); + +static int lcfs_close(struct lcfs_ctx_s *ctx); + +char *maybe_join_path(const char *a, const char *b) +{ + size_t a_len = strlen(a); + size_t b_len = 0; + + if (b != NULL) + b_len = 1 + strlen(b); + + char *res = malloc(a_len + b_len + 1); + if (res) { + strcpy(res, a); + if (b != NULL) { + if (a_len > 0 && res[a_len - 1] != '/') { + strcat(res, "/"); + } + strcat(res, b); + } + } + return res; +} + +size_t hash_memory(const char *string, size_t len, size_t n_buckets) +{ + size_t i, value = 0; + + for (i = 0; i < len; i++) { + value = (value * 31 + string[i]) % n_buckets; + } + return value; +} + +static struct lcfs_ctx_s *lcfs_new_ctx(struct lcfs_node_s *root, + struct lcfs_write_options_s *options) +{ + struct lcfs_ctx_s *ret; + + switch (options->format) { + case LCFS_FORMAT_EROFS: + ret = lcfs_ctx_erofs_new(); + break; + + default: + ret = NULL; + } + + if (ret == NULL) { + return ret; + } + + ret->options = options; + ret->root = lcfs_node_ref(root); + + ret->file = options->file; + ret->write_cb = options->file_write_cb; + if (options->digest_out) { + ret->fsverity_ctx = lcfs_fsverity_context_new(); + if (ret->fsverity_ctx == NULL) { + lcfs_close(ret); + return NULL; + } + } + + return ret; +} + +int lcfs_clone_root(struct lcfs_ctx_s *ctx) +{ + struct lcfs_node_s *clone; + + clone = lcfs_node_clone_deep(ctx->root); + if (clone == NULL) { + errno = -EINVAL; + return -1; + } + + lcfs_node_unref(ctx->root); + ctx->root = clone; + ctx->destroy_root = true; + + return 0; +} + +int node_get_dtype(struct lcfs_node_s *node) +{ + switch ((node->inode.st_mode & S_IFMT)) { + case S_IFLNK: + return DT_LNK; + case S_IFDIR: + return DT_DIR; + case S_IFREG: + return DT_REG; + case S_IFBLK: + return DT_BLK; + case S_IFCHR: + return DT_CHR; + case S_IFSOCK: + return DT_SOCK; + case S_IFIFO: + return DT_FIFO; + default: + return DT_UNKNOWN; + } +} + +static int cmp_nodes(const void *a, const void *b) +{ + const struct lcfs_node_s *na = *((const struct lcfs_node_s **)a); + const struct lcfs_node_s *nb = *((const struct lcfs_node_s **)b); + + return strcmp(na->name, nb->name); +} + +static int cmp_xattr(const void *a, const void *b) +{ + const struct lcfs_xattr_s *na = a; + const struct lcfs_xattr_s *nb = b; + + return strcmp(na->key, nb->key); +} + +/* This ensures that the tree is in a well defined order, with + children sorted by name, and the nodes visited in breadth-first + order. It also updates the inode offset. */ +int lcfs_compute_tree(struct lcfs_ctx_s *ctx, struct lcfs_node_s *root) +{ + uint32_t index; + struct lcfs_node_s *node; + + /* Start with the root node. */ + + ctx->queue_end = root; + root->in_tree = true; + + ctx->min_mtim_sec = root->inode.st_mtim_sec; + ctx->min_mtim_nsec = root->inode.st_mtim_nsec; + ctx->has_acl = false; + + for (node = root, index = 0; node != NULL; node = node->next, index++) { + if ((node->inode.st_mode & S_IFMT) != S_IFDIR && + node->children_size != 0) { + /* Only dirs can have children */ + errno = EINVAL; + return -1; + } + + /* Fix up directory n_links counts, they are 2 + nr of subdirs */ + if ((node->inode.st_mode & S_IFMT) == S_IFDIR) { + size_t n_link = 2; + for (size_t i = 0; i < node->children_size; i++) { + struct lcfs_node_s *child = node->children[i]; + if ((child->inode.st_mode & S_IFMT) == S_IFDIR) { + n_link++; + } + } + node->inode.st_nlink = n_link; + } + + /* Canonical order */ + if (node->children) + qsort(node->children, node->children_size, + sizeof(node->children[0]), cmp_nodes); + if (node->xattrs) + qsort(node->xattrs, node->n_xattrs, + sizeof(node->xattrs[0]), cmp_xattr); + + if (node->inode.st_mtim_sec < ctx->min_mtim_sec || + (node->inode.st_mtim_sec == ctx->min_mtim_sec && + node->inode.st_mtim_nsec < ctx->min_mtim_nsec)) { + ctx->min_mtim_sec = node->inode.st_mtim_sec; + ctx->min_mtim_nsec = node->inode.st_mtim_nsec; + } + + /* Assign inode index */ + node->inode_num = index; + + /* Compute has_acl */ + if (lcfs_node_get_xattr(node, "system.posix_acl_access", NULL) != NULL || + lcfs_node_get_xattr(node, "system.posix_acl_default", NULL) != NULL) + ctx->has_acl = true; + + node->in_tree = true; + /* Append to queue for more work */ + for (size_t i = 0; i < node->children_size; i++) { + struct lcfs_node_s *child = node->children[i]; + + /* Skip hardlinks, they will not be serialized separately */ + if (child->link_to != NULL) { + continue; + } + + /* Avoid recursion */ + assert(!child->in_tree); + + ctx->queue_end->next = child; + ctx->queue_end = child; + } + } + + /* Ensure all hardlinks are in tree */ + for (node = root; node != NULL; node = node->next) { + for (size_t i = 0; i < node->children_size; i++) { + struct lcfs_node_s *child = node->children[i]; + if (child->link_to != NULL && !child->link_to->in_tree) { + /* Link to inode outside tree */ + errno = EINVAL; + return -1; + } + } + } + + /* Reset in_tree back to false for multiple uses */ + for (node = ctx->root; node != NULL; node = node->next) { + node->in_tree = false; + } + + ctx->num_inodes = index; + + return 0; +} + +struct lcfs_node_s *follow_links(struct lcfs_node_s *node) +{ + if (node->link_to) + return follow_links(node->link_to); + return node; +} + +int lcfs_write(struct lcfs_ctx_s *ctx, void *_data, size_t data_len) +{ + uint8_t *data = _data; + if (ctx->fsverity_ctx) + lcfs_fsverity_context_update(ctx->fsverity_ctx, data, data_len); + + ctx->bytes_written += data_len; + + if (ctx->write_cb) { + while (data_len > 0) { + ssize_t r = ctx->write_cb(ctx->file, data, data_len); + if (r <= 0) { + errno = EIO; + return -1; + } + data_len -= r; + data += r; + } + } + + return 0; +} + +int lcfs_write_pad(struct lcfs_ctx_s *ctx, size_t data_len) +{ + char buf[256] = { 0 }; + + for (size_t i = 0; i < data_len; i += sizeof(buf)) { + size_t to_write = MIN(sizeof(buf), data_len - i); + int r = lcfs_write(ctx, buf, to_write); + if (r < 0) { + return r; + } + } + + return 0; +} + +int lcfs_write_align(struct lcfs_ctx_s *ctx, size_t align_size) +{ + off_t end = round_up(ctx->bytes_written, align_size); + if (end > ctx->bytes_written) { + return lcfs_write_pad(ctx, end - ctx->bytes_written); + } + return 0; +} + +static int lcfs_close(struct lcfs_ctx_s *ctx) +{ + if (ctx == NULL) + return 0; + + if (ctx->finalize) + ctx->finalize(ctx); + + if (ctx->fsverity_ctx) + lcfs_fsverity_context_free(ctx->fsverity_ctx); + if (ctx->root) { + if (ctx->destroy_root) { + lcfs_node_destroy(ctx->root); + } else { + lcfs_node_unref(ctx->root); + } + } + free(ctx); + + return 0; +} + +int lcfs_write_to(struct lcfs_node_s *root, struct lcfs_write_options_s *options) +{ + enum lcfs_format_t format = options->format; + struct lcfs_ctx_s *ctx; + int res; + + /* Check for unknown flags */ + if ((options->flags & ~LCFS_FLAGS_MASK) != 0) { + errno = -EINVAL; + return -1; + } + + ctx = lcfs_new_ctx(root, options); + if (ctx == NULL) { + errno = ENOMEM; + return -1; + } + + if (format == LCFS_FORMAT_EROFS) + res = lcfs_write_erofs_to(ctx); + else { + errno = -EINVAL; + res = -1; + } + + if (res < 0) { + lcfs_close(ctx); + return res; + } + + if (options->digest_out) { + lcfs_fsverity_context_get_digest(ctx->fsverity_ctx, + options->digest_out); + } + + lcfs_close(ctx); + return 0; +} + +static int read_xattrs(struct lcfs_node_s *ret, int dirfd, const char *fname) +{ + char path[PATH_MAX]; + ssize_t list_size; + cleanup_free char *list = NULL; + ssize_t r = 0; + cleanup_fd int fd = -1; + + fd = openat(dirfd, fname, O_PATH | O_NOFOLLOW | O_CLOEXEC, 0); + if (fd < 0) + return -1; + + sprintf(path, "/proc/self/fd/%d", fd); + + list_size = listxattr(path, NULL, 0); + if (list_size < 0) { + return list_size; + } + + list = malloc(list_size); + if (list == NULL) { + return -1; + } + + list_size = listxattr(path, list, list_size); + if (list_size < 0) { + return list_size; + } + + for (const char *it = list; it < list + list_size; it += strlen(it) + 1) { + ssize_t value_size; + cleanup_free char *value = NULL; + + value_size = getxattr(path, it, NULL, 0); + if (value_size < 0) { + return value_size; + } + + value = malloc(value_size); + if (value == NULL) { + return -1; + } + + r = getxattr(path, it, value, value_size); + if (r < 0) { + return r; + } + + r = lcfs_node_set_xattr(ret, it, value, value_size); + if (r < 0) { + return r; + } + } + return r; +} + +struct lcfs_node_s *lcfs_node_new(void) +{ + struct lcfs_node_s *node = calloc(1, sizeof(struct lcfs_node_s)); + if (node == NULL) + return NULL; + + node->ref_count = 1; + node->inode.st_nlink = 1; + return node; +} + +static ssize_t fsverity_read_cb(void *_fd, void *buf, size_t count) +{ + int fd = *(int *)_fd; + ssize_t res; + + do + res = read(fd, buf, count); + while (res < 0 && errno == EINTR); + + return res; +} + +int lcfs_compute_fsverity_from_content(uint8_t *digest, void *file, lcfs_read_cb read_cb) +{ + uint8_t buffer[4096]; + ssize_t n_read; + FsVerityContext *ctx; + + ctx = lcfs_fsverity_context_new(); + if (ctx == NULL) { + errno = ENOMEM; + return -1; + } + + while (true) { + n_read = read_cb(file, buffer, sizeof(buffer)); + if (n_read < 0) { + lcfs_fsverity_context_free(ctx); + errno = ENODATA; + return -1; + } + if (n_read == 0) + break; + lcfs_fsverity_context_update(ctx, buffer, n_read); + } + + lcfs_fsverity_context_get_digest(ctx, digest); + + lcfs_fsverity_context_free(ctx); + + return 0; +} + +int lcfs_compute_fsverity_from_fd(uint8_t *digest, int fd) +{ + int _fd = fd; + return lcfs_compute_fsverity_from_content(digest, &_fd, fsverity_read_cb); +} + +int lcfs_compute_fsverity_from_data(uint8_t *digest, uint8_t *data, size_t data_len) +{ + FsVerityContext *ctx; + + ctx = lcfs_fsverity_context_new(); + if (ctx == NULL) { + errno = ENOMEM; + return -1; + } + + lcfs_fsverity_context_update(ctx, data, data_len); + + lcfs_fsverity_context_get_digest(ctx, digest); + + lcfs_fsverity_context_free(ctx); + + return 0; +} + +int lcfs_node_set_fsverity_from_content(struct lcfs_node_s *node, void *file, + lcfs_read_cb read_cb) +{ + uint8_t digest[LCFS_DIGEST_SIZE]; + + if (lcfs_compute_fsverity_from_content(digest, file, read_cb) < 0) + return -1; + + lcfs_node_set_fsverity_digest(node, digest); + + return 0; +} + +int lcfs_node_set_fsverity_from_fd(struct lcfs_node_s *node, int fd) +{ + int _fd = fd; + return lcfs_node_set_fsverity_from_content(node, &_fd, fsverity_read_cb); +} + +static int read_content(int fd, size_t size, uint8_t *buf) +{ + int bytes_read; + + while (size > 0) { + do + bytes_read = read(fd, buf, size); + while (bytes_read < 0 && errno == EINTR); + + if (bytes_read == 0) + break; + + size -= bytes_read; + buf += bytes_read; + } + + if (size > 0) { + errno = ENODATA; + return -1; + } + + return 0; +} + +struct lcfs_node_s *lcfs_load_node_from_file(int dirfd, const char *fname, + int buildflags) +{ + cleanup_node struct lcfs_node_s *ret = NULL; + struct stat sb; + int r; + + if (buildflags & ~(LCFS_BUILD_SKIP_XATTRS | LCFS_BUILD_USE_EPOCH | + LCFS_BUILD_SKIP_DEVICES | LCFS_BUILD_COMPUTE_DIGEST | + LCFS_BUILD_NO_INLINE)) { + errno = EINVAL; + return NULL; + } + + r = fstatat(dirfd, fname, &sb, AT_SYMLINK_NOFOLLOW); + if (r < 0) + return NULL; + + ret = lcfs_node_new(); + if (ret == NULL) + return NULL; + + ret->inode.st_mode = sb.st_mode; + ret->inode.st_uid = sb.st_uid; + ret->inode.st_gid = sb.st_gid; + ret->inode.st_rdev = sb.st_rdev; + ret->inode.st_size = sb.st_size; + + if ((sb.st_mode & S_IFMT) == S_IFREG) { + bool compute_digest = (buildflags & LCFS_BUILD_COMPUTE_DIGEST) != 0; + bool no_inline = (buildflags & LCFS_BUILD_NO_INLINE) != 0; + bool is_zerosized = sb.st_size == 0; + bool do_digest = !is_zerosized && compute_digest; + bool do_inline = !is_zerosized && !no_inline && + sb.st_size <= LCFS_BUILD_INLINE_FILE_SIZE_LIMIT; + + if (do_digest || do_inline) { + cleanup_fd int fd = + openat(dirfd, fname, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return NULL; + if (do_digest) { + r = lcfs_node_set_fsverity_from_fd(ret, fd); + if (r < 0) + return NULL; + /* In case we re-read below */ + lseek(fd, 0, SEEK_SET); + } + if (do_inline) { + uint8_t buf[LCFS_BUILD_INLINE_FILE_SIZE_LIMIT]; + + r = read_content(fd, sb.st_size, buf); + if (r < 0) + return NULL; + r = lcfs_node_set_content(ret, buf, sb.st_size); + if (r < 0) + return NULL; + } + } + } + + if ((buildflags & LCFS_BUILD_USE_EPOCH) == 0) { + ret->inode.st_mtim_sec = sb.st_mtim.tv_sec; + ret->inode.st_mtim_nsec = sb.st_mtim.tv_nsec; + } + + if ((buildflags & LCFS_BUILD_SKIP_XATTRS) == 0) { + r = read_xattrs(ret, dirfd, fname); + if (r < 0) + return NULL; + } + + return steal_pointer(&ret); +} + +struct lcfs_node_s *lcfs_load_node_from_fd(int fd) +{ + struct lcfs_node_s *node; + uint8_t *image_data; + size_t image_data_size; + struct stat s; + int errsv; + int r; + + r = fstat(fd, &s); + if (r < 0) { + return NULL; + } + + image_data_size = s.st_size; + + image_data = mmap(0, image_data_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (image_data == MAP_FAILED) { + return NULL; + } + + node = lcfs_load_node_from_image(image_data, image_data_size); + if (node == NULL) { + errsv = errno; + munmap(image_data, image_data_size); + errno = errsv; + return NULL; + } + + munmap(image_data, image_data_size); + + return node; +} + +int lcfs_node_set_payload(struct lcfs_node_s *node, const char *payload) +{ + char *dup = strdup(payload); + if (dup == NULL) { + errno = ENOMEM; + return -1; + } + free(node->payload); + node->payload = dup; + + return 0; +} + +const char *lcfs_node_get_payload(struct lcfs_node_s *node) +{ + return node->payload; +} + +const uint8_t *lcfs_node_get_fsverity_digest(struct lcfs_node_s *node) +{ + if (node->digest_set) + return node->digest; + return NULL; +} + +/* This is the sha256 fs-verity digest of the file contents */ +void lcfs_node_set_fsverity_digest(struct lcfs_node_s *node, + uint8_t digest[LCFS_DIGEST_SIZE]) +{ + node->digest_set = true; + memcpy(node->digest, digest, LCFS_DIGEST_SIZE); +} + +int lcfs_node_set_content(struct lcfs_node_s *node, const uint8_t *data, + size_t data_size) +{ + uint8_t *dup = NULL; + + if (data && data_size != 0) { + dup = malloc(data_size); + if (dup == NULL) { + errno = ENOMEM; + return -1; + } + memcpy(dup, data, data_size); + } + free(node->content); + node->content = dup; + node->inode.st_size = data_size; + + return 0; +} + +const uint8_t *lcfs_node_get_content(struct lcfs_node_s *node) +{ + return node->content; +} + +const char *lcfs_node_get_name(struct lcfs_node_s *node) +{ + return node->name; +} + +size_t lcfs_node_get_n_children(struct lcfs_node_s *node) +{ + return node->children_size; +} + +struct lcfs_node_s *lcfs_node_get_child(struct lcfs_node_s *node, size_t i) +{ + if (i < node->children_size) + return node->children[i]; + return NULL; +} + +uint32_t lcfs_node_get_mode(struct lcfs_node_s *node) +{ + return node->inode.st_mode; +} + +void lcfs_node_set_mode(struct lcfs_node_s *node, uint32_t mode) +{ + node->inode.st_mode = mode; +} + +uint32_t lcfs_node_get_uid(struct lcfs_node_s *node) +{ + return node->inode.st_uid; +} + +void lcfs_node_set_uid(struct lcfs_node_s *node, uint32_t uid) +{ + node->inode.st_uid = uid; +} + +uint32_t lcfs_node_get_gid(struct lcfs_node_s *node) +{ + return node->inode.st_gid; +} + +void lcfs_node_set_gid(struct lcfs_node_s *node, uint32_t gid) +{ + node->inode.st_gid = gid; +} + +uint32_t lcfs_node_get_rdev(struct lcfs_node_s *node) +{ + return node->inode.st_rdev; +} + +void lcfs_node_set_rdev(struct lcfs_node_s *node, uint32_t rdev) +{ + node->inode.st_rdev = rdev; +} + +uint32_t lcfs_node_get_nlink(struct lcfs_node_s *node) +{ + return node->inode.st_nlink; +} + +void lcfs_node_set_nlink(struct lcfs_node_s *node, uint32_t nlink) +{ + node->inode.st_nlink = nlink; +} + +uint64_t lcfs_node_get_size(struct lcfs_node_s *node) +{ + return node->inode.st_size; +} + +/* Clears content if size changes */ +void lcfs_node_set_size(struct lcfs_node_s *node, uint64_t size) +{ + if (size == node->inode.st_size) + return; + + free(node->content); + node->content = NULL; + node->inode.st_size = size; +} + +void lcfs_node_set_mtime(struct lcfs_node_s *node, struct timespec *time) +{ + node->inode.st_mtim_sec = time->tv_sec; + node->inode.st_mtim_nsec = time->tv_nsec; +} + +void lcfs_node_get_mtime(struct lcfs_node_s *node, struct timespec *time) +{ + time->tv_sec = node->inode.st_mtim_sec; + time->tv_nsec = node->inode.st_mtim_nsec; +} + +struct lcfs_node_s *lcfs_node_lookup_child(struct lcfs_node_s *node, const char *name) +{ + size_t i; + + for (i = 0; i < node->children_size; ++i) { + struct lcfs_node_s *child = node->children[i]; + + if (child->name && strcmp(child->name, name) == 0) + return child; + } + + return NULL; +} + +struct lcfs_node_s *lcfs_node_get_parent(struct lcfs_node_s *node) +{ + return node->parent; +} + +void lcfs_node_make_hardlink(struct lcfs_node_s *node, struct lcfs_node_s *target) +{ + target = follow_links(target); + node->link_to = lcfs_node_ref(target); + target->inode.st_nlink++; +} + +struct lcfs_node_s *lcfs_node_get_hardlink_target(struct lcfs_node_s *node) +{ + return node->link_to; +} + +int lcfs_node_add_child(struct lcfs_node_s *parent, struct lcfs_node_s *child, + const char *name) +{ + struct lcfs_node_s **new_children; + size_t new_size; + char *name_copy; + + if ((parent->inode.st_mode & S_IFMT) != S_IFDIR) { + errno = ENOTDIR; + return -1; + } + + if (strlen(name) > LCFS_MAX_NAME_LENGTH) { + errno = ENAMETOOLONG; + return -1; + } + + /* Each node can only be added once */ + if (child->name != NULL) { + errno = EMLINK; + return -1; + } + + if (lcfs_node_lookup_child(parent, name) != NULL) { + errno = EEXIST; + return -1; + } + + name_copy = strdup(name); + if (name_copy == NULL) { + errno = ENOMEM; + return -1; + } + + new_size = parent->children_size + 1; + + new_children = reallocarray(parent->children, sizeof(*parent->children), + new_size); + if (new_children == NULL) { + errno = ENOMEM; + free(name_copy); + return -1; + } + + parent->children = new_children; + + parent->children[parent->children_size] = child; + parent->children_size = new_size; + child->parent = parent; + child->name = name_copy; + + return 0; +} + +struct lcfs_node_s *lcfs_node_ref(struct lcfs_node_s *node) +{ + node->ref_count++; + return node; +} + +void lcfs_node_unref(struct lcfs_node_s *node) +{ + size_t i; + + node->ref_count--; + + if (node->ref_count > 0) + return; + + /* finalizing */ + + /* if we have a parent, that should have a real ref to us */ + assert(node->parent == NULL); + + lcfs_node_remove_all_children(node); + free(node->children); + + if (node->link_to) + lcfs_node_unref(node->link_to); + + free(node->name); + free(node->payload); + free(node->content); + + for (i = 0; i < node->n_xattrs; i++) { + free(node->xattrs[i].key); + free(node->xattrs[i].value); + } + free(node->xattrs); + + free(node); +} + +static void lcfs_node_remove_all_children(struct lcfs_node_s *node) +{ + for (size_t i = 0; i < node->children_size; i++) { + struct lcfs_node_s *child = node->children[i]; + assert(child->parent == node); + /* Unlink correctly as it may live on outside the tree and be reinserted */ + free(child->name); + child->name = NULL; + child->parent = NULL; + lcfs_node_destroy(child); + } + node->children_size = 0; +} + +/* Unlink all children (recursively) and then unref. Useful to handle refcount loops like dot and dotdot. */ +static void lcfs_node_destroy(struct lcfs_node_s *node) +{ + lcfs_node_remove_all_children(node); + lcfs_node_unref(node); +}; + +struct lcfs_node_s *lcfs_node_clone(struct lcfs_node_s *node) +{ + cleanup_node struct lcfs_node_s *new = lcfs_node_new(); + if (new == NULL) + return NULL; + + /* Note: This copies only data, not structure like name or children */ + + /* We copy the link_to, but clone_deep may rewrite this */ + if (node->link_to) { + new->link_to = lcfs_node_ref(node->link_to); + } + + if (node->payload) { + new->payload = strdup(node->payload); + if (new->payload == NULL) + return NULL; + ; + } + + if (node->content) { + new->content = malloc(node->inode.st_size); + if (new->content == NULL) + return NULL; + ; + memcpy(new->content, node->content, node->inode.st_size); + } + + if (node->n_xattrs > 0) { + new->xattrs = malloc(sizeof(struct lcfs_xattr_s) * node->n_xattrs); + if (new->xattrs == NULL) + return NULL; + for (size_t i = 0; i < node->n_xattrs; i++) { + char *key = strdup(node->xattrs[i].key); + char *value = memdup(node->xattrs[i].value, + node->xattrs[i].value_len); + if (key == NULL || value == NULL) { + free(key); + free(value); + return NULL; + } + new->xattrs[i].key = key; + new->xattrs[i].value = value; + new->xattrs[i].value_len = node->xattrs[i].value_len; + new->n_xattrs++; + } + } + + new->digest_set = node->digest_set; + memcpy(new->digest, node->digest, LCFS_DIGEST_SIZE); + new->inode = node->inode; + + return steal_pointer(&new); +} + +struct lcfs_node_mapping_s { + struct lcfs_node_s *old; + struct lcfs_node_s *new; +}; + +struct lcfs_clone_data { + struct lcfs_node_mapping_s *mapping; + size_t n_mappings; + size_t allocated_mappings; +}; + +static struct lcfs_node_s *_lcfs_node_clone_deep(struct lcfs_node_s *node, + struct lcfs_clone_data *data) +{ + cleanup_node struct lcfs_node_s *new = lcfs_node_clone(node); + if (new == NULL) + return NULL; + + if (data->n_mappings >= data->allocated_mappings) { + struct lcfs_node_mapping_s *new_mapping; + data->allocated_mappings = (data->allocated_mappings == 0) ? + 32 : + data->allocated_mappings * 2; + new_mapping = reallocarray(data->mapping, + sizeof(struct lcfs_node_mapping_s), + data->allocated_mappings); + if (new_mapping == NULL) + return NULL; + data->mapping = new_mapping; + } + + data->mapping[data->n_mappings].old = node; + data->mapping[data->n_mappings].new = new; + data->n_mappings++; + + for (size_t i = 0; i < node->children_size; ++i) { + struct lcfs_node_s *child = node->children[i]; + struct lcfs_node_s *new_child = _lcfs_node_clone_deep(child, data); + if (new_child == NULL) + return NULL; + + if (lcfs_node_add_child(new, new_child, child->name) < 0) + return NULL; + } + + return steal_pointer(&new); +} + +/* Rewrite all hardlinks according to mapping */ +static void _lcfs_node_clone_rewrite_links(struct lcfs_node_s *new, + struct lcfs_clone_data *data) +{ + for (size_t i = 0; i < new->children_size; ++i) { + struct lcfs_node_s *new_child = new->children[i]; + _lcfs_node_clone_rewrite_links(new_child, data); + } + + if (new->link_to != NULL) { + for (size_t i = 0; i < data->n_mappings; ++i) { + if (data->mapping[i].old == new->link_to) { + lcfs_node_unref(new->link_to); + new->link_to = lcfs_node_ref(data->mapping[i].new); + break; + } + } + } +} + +struct lcfs_node_s *lcfs_node_clone_deep(struct lcfs_node_s *node) +{ + struct lcfs_clone_data data = { NULL }; + struct lcfs_node_s *new; + + new = _lcfs_node_clone_deep(node, &data); + if (new) + _lcfs_node_clone_rewrite_links(new, &data); + + free(data.mapping); + + return new; +} + +bool lcfs_node_dirp(struct lcfs_node_s *node) +{ + return (node->inode.st_mode & S_IFMT) == S_IFDIR; +} + +struct lcfs_node_s *lcfs_build(int dirfd, const char *fname, int buildflags, + char **failed_path_out) +{ + struct lcfs_node_s *node = NULL; + struct dirent *de; + DIR *dir = NULL; + int dfd; + char *free_failed_subpath = NULL; + const char *failed_subpath = NULL; + int errsv; + + node = lcfs_load_node_from_file(dirfd, fname, buildflags); + if (node == NULL) { + errsv = errno; + goto fail; + } + + if (!lcfs_node_dirp(node)) { + return node; + } + + dfd = openat(dirfd, fname, O_RDONLY | O_NOFOLLOW | O_CLOEXEC, 0); + if (dfd < 0) { + errsv = errno; + goto fail; + } + + dir = fdopendir(dfd); + if (dir == NULL) { + errsv = errno; + close(dfd); + goto fail; + } + + for (;;) { + struct lcfs_node_s *n; + int r; + + errno = 0; + de = readdir(dir); + if (de == NULL) { + if (errno) { + errsv = errno; + goto fail; + } + + break; + } + + if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) + continue; + + if (de->d_type == DT_UNKNOWN) { + struct stat statbuf; + + if (fstatat(dfd, de->d_name, &statbuf, + AT_SYMLINK_NOFOLLOW) < 0) { + errsv = errno; + failed_subpath = de->d_name; + goto fail; + } + + if (S_ISDIR(statbuf.st_mode)) + de->d_type = DT_DIR; + } + + if (de->d_type == DT_DIR) { + n = lcfs_build(dfd, de->d_name, buildflags, + &free_failed_subpath); + if (n == NULL) { + failed_subpath = free_failed_subpath; + errsv = errno; + goto fail; + } + } else { + if (buildflags & LCFS_BUILD_SKIP_DEVICES) { + if (de->d_type == DT_BLK || de->d_type == DT_CHR) + continue; + } + + n = lcfs_load_node_from_file(dfd, de->d_name, buildflags); + if (n == NULL) { + errsv = errno; + failed_subpath = de->d_name; + goto fail; + } + } + + r = lcfs_node_add_child(node, n, de->d_name); + if (r < 0) { + errsv = errno; + goto fail; + } + } + + closedir(dir); + return node; + +fail: + if (failed_path_out) + *failed_path_out = maybe_join_path(fname, failed_subpath); + if (free_failed_subpath) + free(free_failed_subpath); + if (node) + lcfs_node_unref(node); + if (dir) + closedir(dir); + errno = errsv; + return NULL; +} + +size_t lcfs_node_get_n_xattr(struct lcfs_node_s *node) +{ + return node->n_xattrs; +} + +const char *lcfs_node_get_xattr_name(struct lcfs_node_s *node, size_t index) +{ + if (index >= node->n_xattrs) + return NULL; + + return node->xattrs[index].key; +} + +static ssize_t find_xattr(struct lcfs_node_s *node, const char *name) +{ + ssize_t i; + for (i = 0; i < (ssize_t)node->n_xattrs; i++) { + struct lcfs_xattr_s *xattr = &node->xattrs[i]; + if (strcmp(name, xattr->key) == 0) + return i; + } + return -1; +} + +const char *lcfs_node_get_xattr(struct lcfs_node_s *node, const char *name, + size_t *length) +{ + ssize_t index = find_xattr(node, name); + + if (index >= 0) { + struct lcfs_xattr_s *xattr = &node->xattrs[index]; + if (length) + *length = xattr->value_len; + return xattr->value; + } + + return NULL; +} + +int lcfs_node_unset_xattr(struct lcfs_node_s *node, const char *name) +{ + ssize_t index = find_xattr(node, name); + + if (index >= 0) { + if (index != (ssize_t)node->n_xattrs - 1) + node->xattrs[index] = node->xattrs[node->n_xattrs - 1]; + node->n_xattrs--; + } + + return -1; +} + +int lcfs_node_set_xattr(struct lcfs_node_s *node, const char *name, + const char *value, size_t value_len) +{ + struct lcfs_xattr_s *xattrs; + char *k, *v; + ssize_t index = find_xattr(node, name); + + if (index >= 0) { + /* Already set, replace */ + struct lcfs_xattr_s *xattr = &node->xattrs[index]; + v = memdup(value, value_len); + if (v == NULL) { + errno = ENOMEM; + return -1; + } + free(xattr->value); + xattr->value = v; + xattr->value_len = value_len; + + return 0; + } + + xattrs = realloc(node->xattrs, + (node->n_xattrs + 1) * sizeof(struct lcfs_xattr_s)); + if (xattrs == NULL) { + errno = ENOMEM; + return -1; + } + node->xattrs = xattrs; + + k = strdup(name); + v = memdup(value, value_len); + if (k == NULL || v == NULL) { + free(k); + free(v); + errno = ENOMEM; + return -1; + } + + xattrs[node->n_xattrs].key = k; + xattrs[node->n_xattrs].value = v; + xattrs[node->n_xattrs].value_len = value_len; + node->n_xattrs++; + + return 0; +} + +/* This is an internal function. + * Be careful to not cause duplicates if new_name already exist */ +int lcfs_node_rename_xattr(struct lcfs_node_s *node, size_t index, const char *new_name) +{ + struct lcfs_xattr_s *xattr; + cleanup_free char *dup = NULL; + + dup = strdup(new_name); + if (dup == NULL) { + errno = ENOMEM; + return -1; + } + + if (index >= node->n_xattrs) { + errno = EINVAL; + return -1; + } + + xattr = &node->xattrs[index]; + free(xattr->key); + xattr->key = steal_pointer(&dup); + return 0; +} diff --git a/composefs/libcomposefs/lcfs-writer.h b/composefs/libcomposefs/lcfs-writer.h new file mode 100644 index 0000000..136de48 --- /dev/null +++ b/composefs/libcomposefs/lcfs-writer.h @@ -0,0 +1,143 @@ +/* lcfs + Copyright (C) 2021 Giuseppe Scrivano + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _LCFS_OPS_H +#define _LCFS_OPS_H + +#include +#include +#include +#include +#include + +#ifndef LCFS_EXTERN +#define LCFS_EXTERN extern +#endif + +#define LCFS_DIGEST_SIZE 32 + +enum { + LCFS_BUILD_SKIP_XATTRS = (1 << 0), + LCFS_BUILD_USE_EPOCH = (1 << 1), + LCFS_BUILD_SKIP_DEVICES = (1 << 2), + LCFS_BUILD_COMPUTE_DIGEST = (1 << 3), + LCFS_BUILD_NO_INLINE = (1 << 4), +}; + +enum lcfs_format_t { + LCFS_FORMAT_EROFS, +}; + +enum lcfs_flags_t { + LCFS_FLAGS_NONE = 0, + LCFS_FLAGS_MASK = 0, +}; + +typedef ssize_t (*lcfs_read_cb)(void *file, void *buf, size_t count); +typedef ssize_t (*lcfs_write_cb)(void *file, void *buf, size_t count); + +struct lcfs_write_options_s { + uint32_t format; + uint32_t version; + uint32_t flags; + uint8_t *digest_out; + void *file; + lcfs_write_cb file_write_cb; + uint32_t reserved[4]; + void *reserved2[4]; +}; + +LCFS_EXTERN struct lcfs_node_s *lcfs_node_new(void); +LCFS_EXTERN struct lcfs_node_s *lcfs_node_ref(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_unref(struct lcfs_node_s *node); +LCFS_EXTERN struct lcfs_node_s *lcfs_node_clone(struct lcfs_node_s *node); +LCFS_EXTERN struct lcfs_node_s *lcfs_node_clone_deep(struct lcfs_node_s *node); +LCFS_EXTERN struct lcfs_node_s *lcfs_load_node_from_file(int dirfd, const char *fname, + int buildflags); +LCFS_EXTERN struct lcfs_node_s *lcfs_load_node_from_image(const uint8_t *image_data, + size_t image_data_size); +LCFS_EXTERN struct lcfs_node_s *lcfs_load_node_from_fd(int fd); + +LCFS_EXTERN const char *lcfs_node_get_xattr(struct lcfs_node_s *node, + const char *name, size_t *length); +LCFS_EXTERN int lcfs_node_set_xattr(struct lcfs_node_s *node, const char *name, + const char *value, size_t value_len); +LCFS_EXTERN int lcfs_node_unset_xattr(struct lcfs_node_s *node, const char *name); +LCFS_EXTERN size_t lcfs_node_get_n_xattr(struct lcfs_node_s *node); +LCFS_EXTERN const char *lcfs_node_get_xattr_name(struct lcfs_node_s *node, + size_t index); + +LCFS_EXTERN int lcfs_node_set_payload(struct lcfs_node_s *node, const char *payload); +LCFS_EXTERN const char *lcfs_node_get_payload(struct lcfs_node_s *node); + +LCFS_EXTERN int lcfs_node_set_content(struct lcfs_node_s *node, + const uint8_t *data, size_t data_size); +LCFS_EXTERN const uint8_t *lcfs_node_get_content(struct lcfs_node_s *node); + +LCFS_EXTERN struct lcfs_node_s *lcfs_node_lookup_child(struct lcfs_node_s *node, + const char *name); +LCFS_EXTERN struct lcfs_node_s *lcfs_node_get_parent(struct lcfs_node_s *node); +LCFS_EXTERN int lcfs_node_add_child(struct lcfs_node_s *parent, + struct lcfs_node_s *child, /* Takes ownership on success */ + const char *name); +LCFS_EXTERN const char *lcfs_node_get_name(struct lcfs_node_s *node); +LCFS_EXTERN size_t lcfs_node_get_n_children(struct lcfs_node_s *node); +LCFS_EXTERN struct lcfs_node_s *lcfs_node_get_child(struct lcfs_node_s *node, + size_t i); +LCFS_EXTERN void lcfs_node_make_hardlink(struct lcfs_node_s *node, + struct lcfs_node_s *target); +LCFS_EXTERN struct lcfs_node_s *lcfs_node_get_hardlink_target(struct lcfs_node_s *node); + +LCFS_EXTERN bool lcfs_node_dirp(struct lcfs_node_s *node); +LCFS_EXTERN uint32_t lcfs_node_get_mode(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_set_mode(struct lcfs_node_s *node, uint32_t mode); +LCFS_EXTERN uint32_t lcfs_node_get_uid(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_set_uid(struct lcfs_node_s *node, uint32_t uid); +LCFS_EXTERN uint32_t lcfs_node_get_gid(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_set_gid(struct lcfs_node_s *node, uint32_t gid); +LCFS_EXTERN uint32_t lcfs_node_get_rdev(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_set_rdev(struct lcfs_node_s *node, uint32_t rdev); +LCFS_EXTERN uint32_t lcfs_node_get_nlink(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_set_nlink(struct lcfs_node_s *node, uint32_t nlink); +LCFS_EXTERN uint64_t lcfs_node_get_size(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_set_size(struct lcfs_node_s *node, uint64_t size); +LCFS_EXTERN void lcfs_node_set_mtime(struct lcfs_node_s *node, struct timespec *time); +LCFS_EXTERN void lcfs_node_get_mtime(struct lcfs_node_s *node, struct timespec *time); + +LCFS_EXTERN const uint8_t *lcfs_node_get_fsverity_digest(struct lcfs_node_s *node); +LCFS_EXTERN void lcfs_node_set_fsverity_digest(struct lcfs_node_s *node, + uint8_t digest[LCFS_DIGEST_SIZE]); + +LCFS_EXTERN int lcfs_node_set_fsverity_from_content(struct lcfs_node_s *node, + void *file, + lcfs_read_cb read_cb); + +LCFS_EXTERN int lcfs_node_set_fsverity_from_fd(struct lcfs_node_s *node, int fd); + +LCFS_EXTERN struct lcfs_node_s *lcfs_build(int dirfd, const char *fname, + int buildflags, char **failed_path_out); + +LCFS_EXTERN int lcfs_write_to(struct lcfs_node_s *root, + struct lcfs_write_options_s *options); + +/* fsverity helpers */ +LCFS_EXTERN int lcfs_compute_fsverity_from_content(uint8_t *digest, void *file, + lcfs_read_cb read_cb); +LCFS_EXTERN int lcfs_compute_fsverity_from_fd(uint8_t *digest, int fd); +LCFS_EXTERN int lcfs_compute_fsverity_from_data(uint8_t *digest, uint8_t *data, + size_t data_len); + +#endif diff --git a/composefs/libcomposefs/xalloc-oversized.h b/composefs/libcomposefs/xalloc-oversized.h new file mode 100644 index 0000000..4184f33 --- /dev/null +++ b/composefs/libcomposefs/xalloc-oversized.h @@ -0,0 +1,65 @@ +/* xalloc-oversized.h -- memory allocation size checking + + Copyright (C) 1990-2000, 2003-2004, 2006-2021 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef XALLOC_OVERSIZED_H_ +#define XALLOC_OVERSIZED_H_ + +#include +#include + +/* True if N * S does not fit into both ptrdiff_t and size_t. + N and S should be nonnegative and free of side effects. + This expands to a constant expression if N and S are both constants. + By gnulib convention, SIZE_MAX represents overflow in size_t + calculations, so the conservative size_t-based dividend to use here + is SIZE_MAX - 1. */ +#define __xalloc_oversized(n, s) \ + ((s) != 0 \ + && ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) \ + < (n))) + +/* Return 1 if and only if an array of N objects, each of size S, + cannot exist reliably because its total size in bytes would exceed + MIN (PTRDIFF_MAX, SIZE_MAX - 1). + + N and S should be nonnegative and free of side effects. + + Warning: (xalloc_oversized (N, S) ? NULL : malloc (N * S)) can + misbehave if N and S are both narrower than ptrdiff_t and size_t, + and can be rewritten as (xalloc_oversized (N, S) ? NULL + : malloc (N * (size_t) S)). + + This is a macro, not a function, so that it works even if an + argument exceeds MAX (PTRDIFF_MAX, SIZE_MAX). */ +#if 7 <= __GNUC__ && !defined __clang__ && PTRDIFF_MAX < SIZE_MAX +# define xalloc_oversized(n, s) \ + __builtin_mul_overflow_p (n, s, (ptrdiff_t) 1) +#elif (5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__ \ + && PTRDIFF_MAX < SIZE_MAX) +# define xalloc_oversized(n, s) \ + (__builtin_constant_p (n) && __builtin_constant_p (s) \ + ? __xalloc_oversized (n, s) \ + : ({ ptrdiff_t __xalloc_count; \ + __builtin_mul_overflow (n, s, &__xalloc_count); })) + +/* Other compilers use integer division; this may be slower but is + more portable. */ +#else +# define xalloc_oversized(n, s) __xalloc_oversized (n, s) +#endif + +#endif /* !XALLOC_OVERSIZED_H_ */ diff --git a/config.h.in b/config.h.in index 132745f..a1c6243 100644 --- a/config.h.in +++ b/config.h.in @@ -3,9 +3,6 @@ /* Define if we are building with asan and ubsan */ #undef BUILDOPT_ASAN -/* Define if we are enabling ostree trivial-httpd entrypoint */ -#undef BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE - /* Define if we enable http2 by default */ #undef BUILDOPT_HTTP2 @@ -39,6 +36,9 @@ /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME +/* Define if we have libcomposefs */ +#undef HAVE_COMPOSEFS + /* Define to 1 if you have the declaration of `copy_file_range', and to 0 if you don't. */ #undef HAVE_DECL_COPY_FILE_RANGE @@ -58,6 +58,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define if ed25519 is supported */ +#undef HAVE_ED25519 + +/* Define if FSCONFIG_CMD_CREATE is available in linux/mount.h */ +#undef HAVE_FSCONFIG_CMD_CREATE_LINUX_MOUNT_H + +/* Define if FSCONFIG_CMD_CREATE is available in sys/mount.h */ +#undef HAVE_FSCONFIG_CMD_CREATE_SYS_MOUNT_H + /* Define if we have gnutls */ #undef HAVE_GNUTLS @@ -82,9 +91,15 @@ /* Define if we have libsoup.pc */ #undef HAVE_LIBSOUP +/* Define if we have libsoup3 */ +#undef HAVE_LIBSOUP3 + /* Define if we have libsoup client certs */ #undef HAVE_LIBSOUP_CLIENT_CERTS +/* Define if we have libsoup.pc or libsoup3.pc */ +#undef HAVE_LIBSOUP_OR_LIBSOUP3 + /* Define if we have libsystemd.pc */ #undef HAVE_LIBSYSTEMD diff --git a/configure b/configure index 37d458a..9f70777 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for libostree 2022.4. +# Generated by GNU Autoconf 2.71 for libostree 2023.7. # # Report bugs to . # @@ -621,8 +621,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libostree' PACKAGE_TARNAME='libostree' -PACKAGE_VERSION='2022.4' -PACKAGE_STRING='libostree 2022.4' +PACKAGE_VERSION='2023.7' +PACKAGE_STRING='libostree 2023.7' PACKAGE_BUGREPORT='walters@verbum.org' PACKAGE_URL='' @@ -747,6 +747,8 @@ USE_LIBSODIUM_FALSE USE_LIBSODIUM_TRUE OT_DEP_LIBSODIUM_LIBS OT_DEP_LIBSODIUM_CFLAGS +USE_COMPOSEFS_FALSE +USE_COMPOSEFS_TRUE USE_GPGME_FALSE USE_GPGME_TRUE GPG_ERROR_CONFIG @@ -773,12 +775,18 @@ _GI_EXP_LIBDIR _GI_EXP_DATADIR USE_CURL_OR_SOUP_FALSE USE_CURL_OR_SOUP_TRUE +USE_LIBSOUP_OR_LIBSOUP3_FALSE +USE_LIBSOUP_OR_LIBSOUP3_TRUE HAVE_LIBSOUP_CLIENT_CERTS_FALSE HAVE_LIBSOUP_CLIENT_CERTS_TRUE USE_LIBSOUP_FALSE USE_LIBSOUP_TRUE OT_DEP_SOUP_LIBS OT_DEP_SOUP_CFLAGS +USE_LIBSOUP3_FALSE +USE_LIBSOUP3_TRUE +OT_DEP_SOUP3_LIBS +OT_DEP_SOUP3_CFLAGS USE_CURL_FALSE USE_CURL_TRUE OT_DEP_CURL_LIBS @@ -822,6 +830,7 @@ ac_ct_AR AR DLLTOOL OBJDUMP +FILECMD LN_S NM ac_ct_DUMPBIN @@ -962,12 +971,13 @@ enable_wrpseudo_compat enable_glibtest with_curl enable_http2 +with_soup3 with_soup enable_libsoup_client_certs -enable_trivial_httpd_cmdline enable_introspection with_gpgme with_gpgme_prefix +with_composefs with_ed25519_libsodium with_html_dir enable_gtk_doc @@ -1024,6 +1034,8 @@ OT_DEP_E2P_CFLAGS OT_DEP_E2P_LIBS OT_DEP_CURL_CFLAGS OT_DEP_CURL_LIBS +OT_DEP_SOUP3_CFLAGS +OT_DEP_SOUP3_LIBS OT_DEP_SOUP_CFLAGS OT_DEP_SOUP_LIBS OT_DEP_GPGME_CFLAGS @@ -1598,7 +1610,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libostree 2022.4 to adapt to many kinds of systems. +\`configure' configures libostree 2023.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1669,7 +1681,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libostree 2022.4:";; + short | recursive ) echo "Configuration of libostree 2023.7:";; esac cat <<\_ACEOF @@ -1706,9 +1718,6 @@ Optional Features: --enable-libsoup-client-certs Require availability of new enough libsoup TLS client cert API (default: auto) - --enable-trivial-httpd-cmdline - Continue to support "ostree trivial-httpd" - [default=no] --enable-introspection=[no/auto/yes] Enable introspection for this build --enable-gtk-doc use gtk-doc to build documentation [[default=no]] @@ -1730,9 +1739,11 @@ Optional Packages: --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-curl Use libcurl [default=no] + --with-soup3 Use libsoup3 [default=no] --with-soup Use libsoup [default=yes] --with-gpgme Use gpgme [default=yes] --with-gpgme-prefix=PFX prefix where GPGME is installed (optional) + --with-composefs Support composefs --with-ed25519-libsodium Use libsodium for ed25519 [default=no] --with-html-dir=PATH path to installed docs @@ -1816,6 +1827,10 @@ Some influential environment variables: C compiler flags for OT_DEP_CURL, overriding pkg-config OT_DEP_CURL_LIBS linker flags for OT_DEP_CURL, overriding pkg-config + OT_DEP_SOUP3_CFLAGS + C compiler flags for OT_DEP_SOUP3, overriding pkg-config + OT_DEP_SOUP3_LIBS + linker flags for OT_DEP_SOUP3, overriding pkg-config OT_DEP_SOUP_CFLAGS C compiler flags for OT_DEP_SOUP, overriding pkg-config OT_DEP_SOUP_LIBS @@ -1933,7 +1948,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libostree configure 2022.4 +libostree configure 2023.7 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2306,7 +2321,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libostree $as_me 2022.4, which was +It was created by libostree $as_me 2023.7, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3583,7 +3598,7 @@ fi # Define the identity of the package. PACKAGE='libostree' - VERSION='2022.4' + VERSION='2023.7' # Some tools Automake needs. @@ -6459,11 +6474,11 @@ done test -n "$YACC" || YACC="yacc" -YEAR_VERSION=2022 +YEAR_VERSION=2023 -RELEASE_VERSION=4 +RELEASE_VERSION=7 -PACKAGE_VERSION=2022.4 +PACKAGE_VERSION=2023.7 pkglibexecdir=$libexecdir/$PACKAGE @@ -6596,8 +6611,8 @@ esac -macro_version='2.4.6' -macro_revision='2.4.6' +macro_version='2.4.7' +macro_revision='2.4.7' @@ -7225,13 +7240,13 @@ else mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -7369,7 +7384,7 @@ esac fi fi - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -7473,7 +7488,7 @@ else $as_nop lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -7516,7 +7531,7 @@ else $as_nop sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -7721,6 +7736,114 @@ esac +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. +set dummy ${ac_tool_prefix}file; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_FILECMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$FILECMD"; then + ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_FILECMD="${ac_tool_prefix}file" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +FILECMD=$ac_cv_prog_FILECMD +if test -n "$FILECMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 +printf "%s\n" "$FILECMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_FILECMD"; then + ac_ct_FILECMD=$FILECMD + # Extract the first word of "file", so it can be a program name with args. +set dummy file; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_FILECMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_FILECMD"; then + ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_FILECMD="file" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD +if test -n "$ac_ct_FILECMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 +printf "%s\n" "$ac_ct_FILECMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_FILECMD" = x; then + FILECMD=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + FILECMD=$ac_ct_FILECMD + fi +else + FILECMD="$ac_cv_prog_FILECMD" +fi + + + + + + + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 @@ -7864,7 +7987,7 @@ beos*) bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -7898,14 +8021,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -7919,7 +8042,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' @@ -7966,7 +8089,7 @@ netbsd*) newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -8339,13 +8462,29 @@ esac fi : ${AR=ar} -: ${AR_FLAGS=cru} +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because thats what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS + + + + + + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. + @@ -8762,7 +8901,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -8780,20 +8919,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -8817,7 +8956,7 @@ for ac_symprfx in "" "_"; do if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ @@ -8835,9 +8974,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -9040,7 +9179,7 @@ case $with_sysroot in #( fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -9165,7 +9304,7 @@ ia64-*-hpux*) ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -9186,7 +9325,7 @@ ia64-*-hpux*) printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -9198,7 +9337,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -9224,7 +9363,7 @@ mips64*-*linux*) printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -9232,7 +9371,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -9240,7 +9379,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -9264,14 +9403,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -9379,7 +9518,7 @@ printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -10162,8 +10301,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 + echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 + $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF @@ -10190,17 +10329,12 @@ printf "%s\n" "$lt_cv_ld_force_load" >&6; } _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[012],*|,*powerpc*-darwin[5-8]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac @@ -10558,8 +10692,8 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -11071,7 +11205,7 @@ lt_prog_compiler_static= lt_prog_compiler_static='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' @@ -11494,15 +11628,15 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) @@ -11554,7 +11688,7 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries whole_archive_flag_spec= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -11666,6 +11800,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes + file_list_spec='@' ;; interix[3-9]*) @@ -11680,7 +11815,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -11723,7 +11858,7 @@ _LT_EOF compiler_needs_object=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes @@ -11735,7 +11870,7 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi @@ -11751,7 +11886,7 @@ _LT_EOF archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -11883,7 +12018,7 @@ _LT_EOF if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no @@ -12154,12 +12289,12 @@ fi cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes @@ -12200,7 +12335,7 @@ fi fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. @@ -12241,8 +12376,8 @@ fi output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no @@ -12276,7 +12411,7 @@ fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes @@ -12527,6 +12662,7 @@ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes + file_list_spec='@' ;; osf3*) @@ -13219,7 +13355,7 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; @@ -13229,14 +13365,14 @@ cygwin* | mingw* | pw32* | cegcc*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -13255,7 +13391,7 @@ cygwin* | mingw* | pw32* | cegcc*) done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -13292,7 +13428,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -13325,7 +13461,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -14481,30 +14617,41 @@ striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } +if test -z "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - fi - ;; - *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ;; - esac + ;; + esac + fi fi @@ -14594,7 +14741,7 @@ CC=$lt_save_CC -OSTREE_FEATURES="" +OSTREE_FEATURES="inode64" @@ -14644,7 +14791,7 @@ else ENABLE_ALWAYS_BUILD_TESTS_FALSE= fi - if test "$ENABLE_INSTALLED_TESTS" == "1"; then + if test "$ENABLE_INSTALLED_TESTS" = "1"; then installed_test_metadir=${datadir}/installed-tests/libostree installed_testdir=${libexecdir}/installed-tests/libostree @@ -16158,6 +16305,130 @@ else $as_nop fi +SOUP3_DEPENDENCY="libsoup-3.0 >= 3.0.0" + +# Check whether --with-soup3 was given. +if test ${with_soup3+y} +then : + withval=$with_soup3; +else $as_nop + with_soup3=no +fi + +if test x$with_soup3 != xno +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OT_DEP_SOUP3" >&5 +printf %s "checking for OT_DEP_SOUP3... " >&6; } + +if test -n "$OT_DEP_SOUP3_CFLAGS"; then + pkg_cv_OT_DEP_SOUP3_CFLAGS="$OT_DEP_SOUP3_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SOUP3_DEPENDENCY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$SOUP3_DEPENDENCY") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_OT_DEP_SOUP3_CFLAGS=`$PKG_CONFIG --cflags "$SOUP3_DEPENDENCY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$OT_DEP_SOUP3_LIBS"; then + pkg_cv_OT_DEP_SOUP3_LIBS="$OT_DEP_SOUP3_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SOUP3_DEPENDENCY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$SOUP3_DEPENDENCY") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_OT_DEP_SOUP3_LIBS=`$PKG_CONFIG --libs "$SOUP3_DEPENDENCY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + OT_DEP_SOUP3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SOUP3_DEPENDENCY" 2>&1` + else + OT_DEP_SOUP3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SOUP3_DEPENDENCY" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$OT_DEP_SOUP3_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements ($SOUP3_DEPENDENCY) were not met: + +$OT_DEP_SOUP3_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables OT_DEP_SOUP3_CFLAGS +and OT_DEP_SOUP3_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables OT_DEP_SOUP3_CFLAGS +and OT_DEP_SOUP3_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + OT_DEP_SOUP3_CFLAGS=$pkg_cv_OT_DEP_SOUP3_CFLAGS + OT_DEP_SOUP3_LIBS=$pkg_cv_OT_DEP_SOUP3_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +fi + with_soup3=yes + +printf "%s\n" "#define HAVE_LIBSOUP3 1" >>confdefs.h + + OSTREE_FEATURES="$OSTREE_FEATURES libsoup3" + with_soup_default=no + have_libsoup_client_certs=yes + +else $as_nop + with_soup_default=check +fi + if test x$with_soup3 != xno; then + USE_LIBSOUP3_TRUE= + USE_LIBSOUP3_FALSE='#' +else + USE_LIBSOUP3_TRUE='#' + USE_LIBSOUP3_FALSE= +fi + + SOUP_DEPENDENCY="libsoup-2.4 >= 2.39.1" # Check whether --with-soup was given. @@ -16346,30 +16617,31 @@ else fi -# Check whether --enable-trivial-httpd-cmdline was given. -if test ${enable_trivial_httpd_cmdline+y} -then : - enableval=$enable_trivial_httpd_cmdline; -else $as_nop - enable_trivial_httpd_cmdline=no + if test x$with_soup = xyes || test x$with_soup3 = xyes; then + USE_LIBSOUP_OR_LIBSOUP3_TRUE= + USE_LIBSOUP_OR_LIBSOUP3_FALSE='#' +else + USE_LIBSOUP_OR_LIBSOUP3_TRUE='#' + USE_LIBSOUP_OR_LIBSOUP3_FALSE= fi -if test x$enable_trivial_httpd_cmdline = xyes +if test x$with_soup = xyes || test x$with_soup3 = xyes then : -printf "%s\n" "#define BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE 1" >>confdefs.h + +printf "%s\n" "#define HAVE_LIBSOUP_OR_LIBSOUP3 1" >>confdefs.h fi -if test x$with_curl = xyes && test x$with_soup = xno +if test x$with_curl = xyes && test x$with_soup = xno && test x$with_soup3 = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Curl enabled, but libsoup is not; libsoup is needed for tests (make check, etc.)" >&5 printf "%s\n" "$as_me: WARNING: Curl enabled, but libsoup is not; libsoup is needed for tests (make check, etc.)" >&2;} fi - if test x$with_curl != xno || test x$with_soup != xno; then + if test x$with_curl != xno || test x$with_soup != xno || test x$with_soup3 != xno; then USE_CURL_OR_SOUP_TRUE= USE_CURL_OR_SOUP_FALSE='#' else @@ -16377,7 +16649,7 @@ else USE_CURL_OR_SOUP_FALSE= fi -if test x$with_curl != xno || test x$with_soup != xno +if test x$with_curl != xno || test x$with_soup != xno || test x$with_soup3 != xno then : printf "%s\n" "#define HAVE_LIBCURL_OR_LIBSOUP 1" >>confdefs.h @@ -16389,6 +16661,9 @@ then : elif test x$with_soup = xyes then : fetcher_backend=libsoup +elif test x$with_soup3 = xyes +then : + fetcher_backend=libsoup3 else $as_nop fetcher_backend=none fi @@ -16425,20 +16700,20 @@ else as_fn_error $? "gobject-introspection-1.0 is not installed" "$LINENO" 5 fi if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 1.34.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 1.34.0") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 1.51.5\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 1.51.5") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then found_introspection=yes else - as_fn_error $? "You need to have gobject-introspection >= 1.34.0 installed to build libostree" "$LINENO" 5 + as_fn_error $? "You need to have gobject-introspection >= 1.51.5 installed to build libostree" "$LINENO" 5 fi ;; #( auto) : if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 1.34.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 1.34.0") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 1.51.5\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 1.51.5") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then @@ -16556,7 +16831,8 @@ else fi -LIBGPGME_DEPENDENCY="1.1.8" +LIBGPGME_DEPENDENCY="1.8.0" +LIBGPGME_PTHREAD_DEPENDENCY="1.1.8" # Check whether --with-gpgme was given. if test ${with_gpgme+y} @@ -16566,6 +16842,84 @@ else $as_nop with_gpgme=yes fi +if test x$with_gpgme != xno +then : + + have_gpgme=yes + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OT_DEP_GPGME" >&5 +printf %s "checking for OT_DEP_GPGME... " >&6; } + +if test -n "$OT_DEP_GPGME_CFLAGS"; then + pkg_cv_OT_DEP_GPGME_CFLAGS="$OT_DEP_GPGME_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gpgme >= \$LIBGPGME_DEPENDENCY gpg-error\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gpgme >= $LIBGPGME_DEPENDENCY gpg-error") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_OT_DEP_GPGME_CFLAGS=`$PKG_CONFIG --cflags "gpgme >= $LIBGPGME_DEPENDENCY gpg-error" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$OT_DEP_GPGME_LIBS"; then + pkg_cv_OT_DEP_GPGME_LIBS="$OT_DEP_GPGME_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gpgme >= \$LIBGPGME_DEPENDENCY gpg-error\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gpgme >= $LIBGPGME_DEPENDENCY gpg-error") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_OT_DEP_GPGME_LIBS=`$PKG_CONFIG --libs "gpgme >= $LIBGPGME_DEPENDENCY gpg-error" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + OT_DEP_GPGME_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gpgme >= $LIBGPGME_DEPENDENCY gpg-error" 2>&1` + else + OT_DEP_GPGME_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gpgme >= $LIBGPGME_DEPENDENCY gpg-error" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$OT_DEP_GPGME_PKG_ERRORS" >&5 + + have_gpgme=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_gpgme=no +else + OT_DEP_GPGME_CFLAGS=$pkg_cv_OT_DEP_GPGME_CFLAGS + OT_DEP_GPGME_LIBS=$pkg_cv_OT_DEP_GPGME_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_gpgme=yes +fi + + +fi # Check whether --with-gpgme-prefix was given. if test ${with_gpgme_prefix+y} @@ -16667,7 +17021,7 @@ fi gpgme_version_micro=`echo $gpgme_version | \ sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\3/'` -if test x$with_gpgme != xno +if test x$with_gpgme != xno && test x$have_gpgme != xyes then : @@ -16679,12 +17033,12 @@ if test -n "$OT_DEP_GPGME_CFLAGS"; then pkg_cv_OT_DEP_GPGME_CFLAGS="$OT_DEP_GPGME_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gpgme-pthread >= \$LIBGPGME_DEPENDENCY\""; } >&5 - ($PKG_CONFIG --exists --print-errors "gpgme-pthread >= $LIBGPGME_DEPENDENCY") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gpgme-pthread >= \$LIBGPGME_PTHREAD_DEPENDENCY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gpgme-pthread >= $LIBGPGME_PTHREAD_DEPENDENCY") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_OT_DEP_GPGME_CFLAGS=`$PKG_CONFIG --cflags "gpgme-pthread >= $LIBGPGME_DEPENDENCY" 2>/dev/null` + pkg_cv_OT_DEP_GPGME_CFLAGS=`$PKG_CONFIG --cflags "gpgme-pthread >= $LIBGPGME_PTHREAD_DEPENDENCY" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -16696,12 +17050,12 @@ if test -n "$OT_DEP_GPGME_LIBS"; then pkg_cv_OT_DEP_GPGME_LIBS="$OT_DEP_GPGME_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gpgme-pthread >= \$LIBGPGME_DEPENDENCY\""; } >&5 - ($PKG_CONFIG --exists --print-errors "gpgme-pthread >= $LIBGPGME_DEPENDENCY") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gpgme-pthread >= \$LIBGPGME_PTHREAD_DEPENDENCY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gpgme-pthread >= $LIBGPGME_PTHREAD_DEPENDENCY") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_OT_DEP_GPGME_LIBS=`$PKG_CONFIG --libs "gpgme-pthread >= $LIBGPGME_DEPENDENCY" 2>/dev/null` + pkg_cv_OT_DEP_GPGME_LIBS=`$PKG_CONFIG --libs "gpgme-pthread >= $LIBGPGME_PTHREAD_DEPENDENCY" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -16722,16 +17076,16 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - OT_DEP_GPGME_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gpgme-pthread >= $LIBGPGME_DEPENDENCY" 2>&1` + OT_DEP_GPGME_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gpgme-pthread >= $LIBGPGME_PTHREAD_DEPENDENCY" 2>&1` else - OT_DEP_GPGME_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gpgme-pthread >= $LIBGPGME_DEPENDENCY" 2>&1` + OT_DEP_GPGME_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gpgme-pthread >= $LIBGPGME_PTHREAD_DEPENDENCY" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$OT_DEP_GPGME_PKG_ERRORS" >&5 - tmp=$LIBGPGME_DEPENDENCY + tmp=$LIBGPGME_PTHREAD_DEPENDENCY if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then req_gpgme_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` min_gpgme_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` @@ -16831,7 +17185,7 @@ elif test $pkg_failed = untried; then printf "%s\n" "no" >&6; } - tmp=$LIBGPGME_DEPENDENCY + tmp=$LIBGPGME_PTHREAD_DEPENDENCY if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then req_gpgme_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` min_gpgme_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` @@ -16936,7 +17290,7 @@ fi if test x$have_gpgme = xno then : - as_fn_error $? "Need GPGME_PTHREAD version $LIBGPGME_DEPENDENCY or later" "$LINENO" 5 + as_fn_error $? "Need GPGME_PTHREAD version $LIBGPGME_PTHREAD_DEPENDENCY or later" "$LINENO" 5 fi OSTREE_FEATURES="$OSTREE_FEATURES gpgme" @@ -17112,12 +17466,22 @@ fi OT_DEP_GPGME_CFLAGS="${OT_DEP_GPGME_CFLAGS} ${OT_DEP_GPG_ERROR_CFLAGS}" OT_DEP_GPGME_LIBS="${OT_DEP_GPGME_LIBS} ${OT_DEP_GPG_ERROR_LIBS}" + +fi +if test x$with_gpgme != xno && test x$have_gpgme != xyes +then : + as_fn_error $? "Need GPGME_PTHREAD and GPG_ERROR" "$LINENO" 5 + +fi +if test x$have_gpgme = xyes +then : + OSTREE_FEATURES="$OSTREE_FEATURES gpgme" else $as_nop printf "%s\n" "#define OSTREE_DISABLE_GPGME 1" >>confdefs.h - with_gpgme=no + have_gpgme=no fi @@ -17130,6 +17494,103 @@ else fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MOUNT_ATTR_IDMAP" >&5 +printf %s "checking for MOUNT_ATTR_IDMAP... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main (void) +{ +int foo = MOUNT_ATTR_IDMAP; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_mount_attr_idmap=yes +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for new mount API (fsconfig)" >&5 +printf %s "checking for new mount API (fsconfig)... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int cmd = FSCONFIG_CMD_CREATE; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_FSCONFIG_CMD_CREATE_SYS_MOUNT_H 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* also make sure it doesn't conflict with since it is always used. */ + #include + #include + int cmd = FSCONFIG_CMD_CREATE; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_FSCONFIG_CMD_CREATE_LINUX_MOUNT_H 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +composefs_default=yes +if test x"$have_mount_attr_idmap" != xyes; then + composefs_default=no +fi + +# Check whether --with-composefs was given. +if test ${with_composefs+y} +then : + withval=$with_composefs; : +else $as_nop + with_composefs=$composefs_default +fi + + +if test x$with_composefs != xno; then OSTREE_FEATURES="$OSTREE_FEATURES composefs"; + +printf "%s\n" "#define HAVE_COMPOSEFS 1" >>confdefs.h + +fi + if test $with_composefs != no; then + USE_COMPOSEFS_TRUE= + USE_COMPOSEFS_FALSE='#' +else + USE_COMPOSEFS_TRUE='#' + USE_COMPOSEFS_FALSE= +fi + LIBSODIUM_DEPENDENCY="1.0.14" @@ -17224,7 +17685,6 @@ then : as_fn_error $? "Need LIBSODIUM version $LIBSODIUM_DEPENDENCY or later" "$LINENO" 5 fi - OSTREE_FEATURES="$OSTREE_FEATURES sign-ed25519" else $as_nop with_ed25519_libsodium=no @@ -18250,6 +18710,13 @@ else fi +if test x$with_openssl != xno || test x$with_ed25519_libsodium != xno; then + +printf "%s\n" "#define HAVE_ED25519 1" >>confdefs.h + + OSTREE_FEATURES="$OSTREE_FEATURES sign-ed25519" +fi + GNUTLS_DEPENDENCY="gnutls >= 3.5.0" if test $with_crypto = gnutls then : @@ -18360,6 +18827,9 @@ else fi +OT_DEP_CRYPTO_CFLAGS="${OT_DEP_CRYPTO_CFLAGS} ${OT_DEP_LIBSODIUM_CFLAGS}" +OT_DEP_CRYPTO_LIBS="${OT_DEP_CRYPTO_LIBS} ${OT_DEP_LIBSODIUM_LIBS}" + AVAHI_DEPENDENCY="avahi-client >= 0.6.31 avahi-glib >= 0.6.31" @@ -19607,6 +20077,10 @@ if test -z "${USE_CURL_TRUE}" && test -z "${USE_CURL_FALSE}"; then as_fn_error $? "conditional \"USE_CURL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_LIBSOUP3_TRUE}" && test -z "${USE_LIBSOUP3_FALSE}"; then + as_fn_error $? "conditional \"USE_LIBSOUP3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_LIBSOUP_TRUE}" && test -z "${USE_LIBSOUP_FALSE}"; then as_fn_error $? "conditional \"USE_LIBSOUP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -19615,6 +20089,10 @@ if test -z "${HAVE_LIBSOUP_CLIENT_CERTS_TRUE}" && test -z "${HAVE_LIBSOUP_CLIENT as_fn_error $? "conditional \"HAVE_LIBSOUP_CLIENT_CERTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_LIBSOUP_OR_LIBSOUP3_TRUE}" && test -z "${USE_LIBSOUP_OR_LIBSOUP3_FALSE}"; then + as_fn_error $? "conditional \"USE_LIBSOUP_OR_LIBSOUP3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_CURL_OR_SOUP_TRUE}" && test -z "${USE_CURL_OR_SOUP_FALSE}"; then as_fn_error $? "conditional \"USE_CURL_OR_SOUP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -19631,6 +20109,10 @@ if test -z "${USE_GPGME_TRUE}" && test -z "${USE_GPGME_FALSE}"; then as_fn_error $? "conditional \"USE_GPGME\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_COMPOSEFS_TRUE}" && test -z "${USE_COMPOSEFS_FALSE}"; then + as_fn_error $? "conditional \"USE_COMPOSEFS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_LIBSODIUM_TRUE}" && test -z "${USE_LIBSODIUM_FALSE}"; then as_fn_error $? "conditional \"USE_LIBSODIUM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -20125,7 +20607,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libostree $as_me 2022.4, which was +This file was extended by libostree $as_me 2023.7, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20193,7 +20675,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -libostree config.status 2022.4 +libostree config.status 2023.7 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" @@ -20356,6 +20838,7 @@ lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_q lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' @@ -20364,6 +20847,7 @@ want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' @@ -20484,6 +20968,7 @@ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ +FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ @@ -20492,7 +20977,6 @@ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ -AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ @@ -21438,6 +21922,9 @@ to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd +# A file(cmd) program that detects file types. +FILECMD=$lt_FILECMD + # An object symbol dumper. OBJDUMP=$lt_OBJDUMP @@ -21462,8 +21949,11 @@ sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR +# Flags to create an archive (by configure). +lt_ar_flags=$lt_ar_flags + # Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS +AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec @@ -21839,7 +22329,7 @@ ltmain=$ac_aux_dir/ltmain.sh # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || @@ -21895,13 +22385,13 @@ echo " introspection: $found_introspection rofiles-fuse: $enable_rofiles_fuse HTTP backend: $fetcher_backend - \"ostree trivial-httpd\": $enable_trivial_httpd_cmdline SELinux: $with_selinux fs-verity: $ac_cv_header_linux_fsverity_h cryptographic checksums: $with_crypto systemd: $with_libsystemd libmount: $with_libmount libsodium (ed25519 signatures): $with_ed25519_libsodium + openssl (ed25519 signatures): $with_openssl libarchive (parse tar files directly): $with_libarchive static deltas: yes (always enabled now) O_TMPFILE: $enable_otmpfile @@ -21912,7 +22402,8 @@ echo " gjs-based tests: $have_gjs dracut: $with_dracut mkinitcpio: $with_mkinitcpio - Static compiler for ostree-prepare-root: $with_static_compiler" + Static compiler for ostree-prepare-root: $with_static_compiler + Composefs: $with_composefs" if test x$with_builtin_grub2_mkconfig = xyes then : diff --git a/configure.ac b/configure.ac index 615580a..a65d879 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.63]) dnl To perform a release, follow the instructions in `docs/CONTRIBUTING.md`. -m4_define([year_version], [2022]) -m4_define([release_version], [4]) +m4_define([year_version], [2023]) +m4_define([release_version], [7]) m4_define([package_version], [year_version.release_version]) AC_INIT([libostree], [package_version], [walters@verbum.org]) is_release_build=yes @@ -82,7 +82,10 @@ AM_COND_IF([BUILDOPT_TSAN], LT_PREREQ([2.2.4]) LT_INIT([disable-static]) -OSTREE_FEATURES="" +dnl We have an always-on feature now to signify the fix for +dnl https://github.com/ostreedev/ostree/pull/2874/commits/de6fddc6adee09a93901243dc7074090828a1912 +dnl "commit: fix ostree deployment on 64-bit inode fs" +OSTREE_FEATURES="inode64" AC_SUBST([OSTREE_FEATURES]) GLIB_TESTS @@ -149,6 +152,21 @@ AS_IF([test x$enable_http2 != xno ], [ OSTREE_FEATURES="$OSTREE_FEATURES no-http2" ]) +SOUP3_DEPENDENCY="libsoup-3.0 >= 3.0.0" +AC_ARG_WITH(soup3, + AS_HELP_STRING([--with-soup3], [Use libsoup3 @<:@default=no@:>@]), + [], [with_soup3=no]) +AS_IF([test x$with_soup3 != xno], [ + PKG_CHECK_MODULES(OT_DEP_SOUP3, $SOUP3_DEPENDENCY) + with_soup3=yes + AC_DEFINE([HAVE_LIBSOUP3], 1, [Define if we have libsoup3]) + OSTREE_FEATURES="$OSTREE_FEATURES libsoup3" + with_soup_default=no + dnl soup3 always supports client certs + have_libsoup_client_certs=yes +], [with_soup_default=check]) +AM_CONDITIONAL(USE_LIBSOUP3, test x$with_soup3 != xno) + dnl When bumping the libsoup-2.4 dependency, remember to bump dnl SOUP_VERSION_MIN_REQUIRED and SOUP_VERSION_MAX_ALLOWED in dnl Makefile.am @@ -180,7 +198,7 @@ AS_IF([test x$with_soup != xno], [ ], [], [#include ]) AS_IF([test x$enable_libsoup_client_certs = xyes && test x$have_libsoup_client_certs != xyes], [ AC_MSG_ERROR([libsoup client certs explicitly requested but not found]) - ]) + ]) CFLAGS=$save_CFLAGS ], [ with_soup=no @@ -190,39 +208,47 @@ if test x$with_soup != xno; then OSTREE_FEATURES="$OSTREE_FEATURES libsoup"; fi AM_CONDITIONAL(USE_LIBSOUP, test x$with_soup != xno) AM_CONDITIONAL(HAVE_LIBSOUP_CLIENT_CERTS, test x$have_libsoup_client_certs = xyes) -AC_ARG_ENABLE(trivial-httpd-cmdline, - [AS_HELP_STRING([--enable-trivial-httpd-cmdline], - [Continue to support "ostree trivial-httpd" [default=no]])],, - enable_trivial_httpd_cmdline=no) -AS_IF([test x$enable_trivial_httpd_cmdline = xyes], - [AC_DEFINE([BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE], 1, [Define if we are enabling ostree trivial-httpd entrypoint])] -) +dnl Some components use either soup2 or soup3. +AM_CONDITIONAL([USE_LIBSOUP_OR_LIBSOUP3], + [test x$with_soup = xyes || test x$with_soup3 = xyes]) +AS_IF([test x$with_soup = xyes || test x$with_soup3 = xyes], [ + AC_DEFINE([HAVE_LIBSOUP_OR_LIBSOUP3], 1, [Define if we have libsoup.pc or libsoup3.pc]) +]) -AS_IF([test x$with_curl = xyes && test x$with_soup = xno], [ +AS_IF([test x$with_curl = xyes && test x$with_soup = xno && test x$with_soup3 = xno], [ AC_MSG_WARN([Curl enabled, but libsoup is not; libsoup is needed for tests (make check, etc.)]) ]) -AM_CONDITIONAL(USE_CURL_OR_SOUP, test x$with_curl != xno || test x$with_soup != xno) -AS_IF([test x$with_curl != xno || test x$with_soup != xno], +AM_CONDITIONAL(USE_CURL_OR_SOUP, test x$with_curl != xno || test x$with_soup != xno || test x$with_soup3 != xno) +AS_IF([test x$with_curl != xno || test x$with_soup != xno || test x$with_soup3 != xno], [AC_DEFINE([HAVE_LIBCURL_OR_LIBSOUP], 1, [Define if we have soup or curl])]) -AS_IF([test x$with_curl = xyes], [fetcher_backend=curl], [test x$with_soup = xyes], [fetcher_backend=libsoup], [fetcher_backend=none]) +AS_IF([test x$with_curl = xyes], [fetcher_backend=curl], + [test x$with_soup = xyes], [fetcher_backend=libsoup], + [test x$with_soup3 = xyes], [fetcher_backend=libsoup3], + [fetcher_backend=none]) m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [ - GOBJECT_INTROSPECTION_CHECK([1.34.0]) + GOBJECT_INTROSPECTION_CHECK([1.51.5]) ]) AM_CONDITIONAL(BUILDOPT_INTROSPECTION, test "x$found_introspection" = xyes) -LIBGPGME_DEPENDENCY="1.1.8" +LIBGPGME_DEPENDENCY="1.8.0" +LIBGPGME_PTHREAD_DEPENDENCY="1.1.8" AC_ARG_WITH(gpgme, AS_HELP_STRING([--with-gpgme], [Use gpgme @<:@default=yes@:>@]), [], [with_gpgme=yes]) AS_IF([test x$with_gpgme != xno], [ - PKG_CHECK_MODULES(OT_DEP_GPGME, gpgme-pthread >= $LIBGPGME_DEPENDENCY, have_gpgme=yes, [ + have_gpgme=yes + PKG_CHECK_MODULES([OT_DEP_GPGME], [gpgme >= $LIBGPGME_DEPENDENCY gpg-error], [have_gpgme=yes], [have_gpgme=no]) + ] +) +AS_IF([test x$with_gpgme != xno && test x$have_gpgme != xyes], [ + PKG_CHECK_MODULES(OT_DEP_GPGME, gpgme-pthread >= $LIBGPGME_PTHREAD_DEPENDENCY, have_gpgme=yes, [ m4_ifdef([AM_PATH_GPGME_PTHREAD], [ - AM_PATH_GPGME_PTHREAD($LIBGPGME_DEPENDENCY, have_gpgme=yes, have_gpgme=no) + AM_PATH_GPGME_PTHREAD($LIBGPGME_PTHREAD_DEPENDENCY, have_gpgme=yes, have_gpgme=no) ],[ have_gpgme=no ]) ]) AS_IF([ test x$have_gpgme = xno ], [ - AC_MSG_ERROR([Need GPGME_PTHREAD version $LIBGPGME_DEPENDENCY or later]) + AC_MSG_ERROR([Need GPGME_PTHREAD version $LIBGPGME_PTHREAD_DEPENDENCY or later]) ]) OSTREE_FEATURES="$OSTREE_FEATURES gpgme" PKG_CHECK_MODULES(OT_DEP_GPG_ERROR, [gpg-error], [], [ @@ -234,14 +260,64 @@ dnl to link to it directly. ]) OT_DEP_GPGME_CFLAGS="${OT_DEP_GPGME_CFLAGS} ${OT_DEP_GPG_ERROR_CFLAGS}" OT_DEP_GPGME_LIBS="${OT_DEP_GPGME_LIBS} ${OT_DEP_GPG_ERROR_LIBS}" - ], + ] +) +AS_IF([test x$with_gpgme != xno && test x$have_gpgme != xyes], + [AC_MSG_ERROR([Need GPGME_PTHREAD and GPG_ERROR])] +) +AS_IF([test x$have_gpgme = xyes], + [ OSTREE_FEATURES="$OSTREE_FEATURES gpgme" ], [ AC_DEFINE([OSTREE_DISABLE_GPGME], 1, [Define to disable internal GPGME support]) - with_gpgme=no + have_gpgme=no ] ) AM_CONDITIONAL(USE_GPGME, test "x$have_gpgme" = xyes) +dnl composefs won't work at all without this +AC_MSG_CHECKING([for MOUNT_ATTR_IDMAP]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ + #include + #include + ],[int foo = MOUNT_ATTR_IDMAP;] + )], + [AC_MSG_RESULT(yes) + have_mount_attr_idmap=yes], + [AC_MSG_RESULT(no)]) +dnl These are needed by libcomposefs to use the new mount API optionally +AC_MSG_CHECKING([for new mount API (fsconfig)]) +AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ + #include + int cmd = FSCONFIG_CMD_CREATE; + ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_FSCONFIG_CMD_CREATE_SYS_MOUNT_H], 1, [Define if FSCONFIG_CMD_CREATE is available in sys/mount.h])], + [AC_MSG_RESULT(no)]) +AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ + /* also make sure it doesn't conflict with since it is always used. */ + #include + #include + int cmd = FSCONFIG_CMD_CREATE; + ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_FSCONFIG_CMD_CREATE_LINUX_MOUNT_H], 1, [Define if FSCONFIG_CMD_CREATE is available in linux/mount.h])], + [AC_MSG_RESULT(no)]) + +composefs_default=yes +if test x"$have_mount_attr_idmap" != xyes; then + composefs_default=no +fi +AC_ARG_WITH(composefs, + AS_HELP_STRING([--with-composefs], [Support composefs]), + :, with_composefs=$composefs_default) + +if test x$with_composefs != xno; then OSTREE_FEATURES="$OSTREE_FEATURES composefs"; + AC_DEFINE([HAVE_COMPOSEFS], 1, [Define if we have libcomposefs]) +fi +AM_CONDITIONAL(USE_COMPOSEFS, test $with_composefs != no) LIBSODIUM_DEPENDENCY="1.0.14" AC_ARG_WITH(ed25519_libsodium, @@ -253,7 +329,6 @@ AS_IF([test x$with_ed25519_libsodium != xno], [ AS_IF([ test x$have_libsodium = xno ], [ AC_MSG_ERROR([Need LIBSODIUM version $LIBSODIUM_DEPENDENCY or later]) ]) - OSTREE_FEATURES="$OSTREE_FEATURES sign-ed25519" ], with_ed25519_libsodium=no ) AM_CONDITIONAL(USE_LIBSODIUM, test "x$have_libsodium" = xyes) @@ -392,6 +467,11 @@ if test x$with_openssl != xno; then OSTREE_FEATURES="$OSTREE_FEATURES openssl"; AM_CONDITIONAL(USE_OPENSSL, test $with_openssl != no) dnl end openssl +if test x$with_openssl != xno || test x$with_ed25519_libsodium != xno; then + AC_DEFINE([HAVE_ED25519], 1, [Define if ed25519 is supported ]) + OSTREE_FEATURES="$OSTREE_FEATURES sign-ed25519" +fi + dnl begin gnutls; in contrast to openssl this one only dnl supports --with-crypto=gnutls GNUTLS_DEPENDENCY="gnutls >= 3.5.0" @@ -403,6 +483,10 @@ AS_IF([ test $with_crypto = gnutls ], [ AM_CONDITIONAL(USE_GNUTLS, test $with_crypto = gnutls) dnl end gnutls +dnl we always inject libsodium into our crypto deps in addition to openssl/gnutls +OT_DEP_CRYPTO_CFLAGS="${OT_DEP_CRYPTO_CFLAGS} ${OT_DEP_LIBSODIUM_CFLAGS}" +OT_DEP_CRYPTO_LIBS="${OT_DEP_CRYPTO_LIBS} ${OT_DEP_LIBSODIUM_LIBS}" + dnl Avahi dependency for finding repos AVAHI_DEPENDENCY="avahi-client >= 0.6.31 avahi-glib >= 0.6.31" @@ -620,13 +704,13 @@ echo " introspection: $found_introspection rofiles-fuse: $enable_rofiles_fuse HTTP backend: $fetcher_backend - \"ostree trivial-httpd\": $enable_trivial_httpd_cmdline SELinux: $with_selinux fs-verity: $ac_cv_header_linux_fsverity_h cryptographic checksums: $with_crypto systemd: $with_libsystemd libmount: $with_libmount libsodium (ed25519 signatures): $with_ed25519_libsodium + openssl (ed25519 signatures): $with_openssl libarchive (parse tar files directly): $with_libarchive static deltas: yes (always enabled now) O_TMPFILE: $enable_otmpfile @@ -637,7 +721,8 @@ echo " gjs-based tests: $have_gjs dracut: $with_dracut mkinitcpio: $with_mkinitcpio - Static compiler for ostree-prepare-root: $with_static_compiler" + Static compiler for ostree-prepare-root: $with_static_compiler + Composefs: $with_composefs" AS_IF([test x$with_builtin_grub2_mkconfig = xyes], [ echo " builtin grub2-mkconfig (instead of system): $with_builtin_grub2_mkconfig" ], [ diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 0000000..910c5bd --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,8 @@ +/*.debhelper +/*.substvars +/gir1.2-ostree-1.0/ +/libostree-1-1/ +/libostree-dev/ +/libostree-doc/ +/ostree-grub2/ +/ostree/ diff --git a/debian/changelog b/debian/changelog index 257245b..c9bd88a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,1298 @@ -ostree (2022.4.1-deepin) stable; urgency=medium +ostree (2023.7-3) unstable; urgency=medium - * ['Rebuild against by current gcc 11.2'] + * Remove version constraints unnecessary since bullseye + * Remove maintscript entries unnecessary since bullseye + * d/p/debian/Skip-test-admin-deploy-uboot.sh-on-s390x.patch: + Really skip test-admin-deploy-uboot.sh on s390x - -- Deepin Packages Builder Wed, 10 Aug 2022 21:25:28 +0800 + -- Simon McVittie Mon, 06 Nov 2023 09:45:08 +0000 + +ostree (2023.7-2) unstable; urgency=medium + + * d/p/bootloader-zipl-No-op-if-run-as-non-root.patch: + Add patch from upstream to avoid build-time test failure on s390x + * d/p/debian/Skip-test-admin-deploy-uboot.sh-on-s390x.patch: + Add patch to avoid another test failure on s390x + * libostree-1-dev Provides gir1.2-ostree-1.0-dev. + This is likely to be useful in the migration path to being able to turn + off GObject-Introspection bindings when bootstrapping or cross-compiling. + + -- Simon McVittie Thu, 26 Oct 2023 11:33:28 +0100 + +ostree (2023.7-1) unstable; urgency=medium + + * New upstream release + * Install systemd system units into /usr/lib/systemd/system. + This was allowed by TC resolution #1053901. Build-depend on debhelper + 13.11.6~ to ensure that the units are still picked up by + dh_installsystemd. + * Depend on pkgconf in preference to pkg-config + + -- Simon McVittie Mon, 23 Oct 2023 10:36:48 +0100 + +ostree (2023.6-2) unstable; urgency=medium + + * d/rules: Disable composefs for now. + Official buildds don't seem to support fsetxattr on the filesystem used + for /var/tmp, which is required for the composefs tests. + + -- Simon McVittie Sun, 03 Sep 2023 12:06:27 +0100 + +ostree (2023.6-1) unstable; urgency=medium + + * New upstream release + * d/rules: Enable composefs support. + This is now on by default when compiled with sufficiently new kernel + headers. + * d/ostree-tests.install: Adjust for move of trivial-httpd to + installed-tests directory + + -- Simon McVittie Sat, 02 Sep 2023 18:52:19 +0100 + +ostree (2023.5-1) unstable; urgency=medium + + * Team upload + * New upstream release + * deiban/libostree-1-1.symbols: Add new symbols + + -- Jeremy Bícha Wed, 16 Aug 2023 10:01:24 -0400 + +ostree (2023.3-2) unstable; urgency=medium + + * Release to unstable + + -- Simon McVittie Mon, 12 Jun 2023 20:48:45 +0100 + +ostree (2023.3-1) experimental; urgency=medium + + * New upstream release + * d/patches: Drop patch that was applied upstream + * d/control: Update GObject-Introspection build-dependency + * d/control, d/rules: Use libsoup 3 for test code + + -- Simon McVittie Sat, 27 May 2023 17:34:25 +0100 + +ostree (2023.1-2) experimental; urgency=medium + + * d/control: Drop compatibility with bsdmainutils older than Debian 11 + * Standards-Version: 4.6.2 (no changes required) + * Add patch to ensure capsh is found in tests' PATH (Closes: #1031353) + + -- Simon McVittie Mon, 27 Feb 2023 12:42:45 +0000 + +ostree (2023.1-1) experimental; urgency=medium + + * New upstream release + * d/copyright: Update + * d/libostree-1-1.symbols: Update + * d/p/configure-use-pkg-config-with-newer-gpgme-and-gpg-error.patch: + Drop patch that was applied upstream + + -- Simon McVittie Tue, 21 Feb 2023 11:17:55 +0000 + +ostree (2022.7-2) unstable; urgency=medium + + * Skip test-sysroot.js on s390x (Mitigates: #1025532) + + -- Simon McVittie Tue, 06 Dec 2022 11:11:05 +0000 + +ostree (2022.7-1) unstable; urgency=medium + + * New upstream release + * d/copyright: Update + * d/libostree-1-1.symbols: Update + * Update Lintian overrides + * d/p/configure-use-pkg-config-with-newer-gpgme-and-gpg-error.patch: + Add patch from Luca Bruno to fix FTBFS with current gpgme Debian packages + * d/rules: Update for removal of libreaddir-rand.so LD_PRELOAD module + + -- Simon McVittie Fri, 25 Nov 2022 10:54:28 +0000 + +ostree (2022.6-1) unstable; urgency=medium + + * New upstream release + * Build-depend on libext2fs-dev instead of transitional e2fslibs-dev + * Don't install s390x-se-luks-gencpio script. + It was reimplemented in C as part of ostree(1). + * Install another early-boot service in ostree-boot + + -- Simon McVittie Sat, 15 Oct 2022 10:48:34 +0100 + +ostree (2022.5-4) unstable; urgency=medium + + * Re-enable gjs-based tests on armel. + Adrian Bunk and Mike Hommey were able to fix mozjs102 on armel, so we + can continue to have gjs on that architecture for Debian 12. + * d/watch: Adapt to Github website changes + + -- Simon McVittie Mon, 03 Oct 2022 10:19:36 +0100 + +ostree (2022.5-3) unstable; urgency=medium + + * d/control, d/rules: Disable gjs-based tests on armel. + It's looking as though mozjs102, and therefore the next gjs release, + will not support armel due to its lack of atomic instructions. + * d/control, d/rules: Re-enable gjs tests on s390x + + -- Simon McVittie Wed, 31 Aug 2022 09:47:41 +0100 + +ostree (2022.5-2) unstable; urgency=medium + + * Build with libcurl http backend instead of libsoup2.4. + This avoids library conflicts during the transition to GNOME 43, in + which core apps and libraries have switched to libsoup3, which conflicts + with libsoup2.4. + We still build-depend on libsoup2.4, because it's used in the test suite + and installed-tests. (Closes: #1016589) + + -- Simon McVittie Fri, 05 Aug 2022 10:00:02 +0100 + +ostree (2022.5-1) unstable; urgency=medium + + * New upstream release + * debian/libostree-1-1.symbols: Update + * d/copyright: Update + * Drop patches that were applied upstream + * Update Lintian overrides + * Standards-Version: 4.6.1 (no changes required) + + -- Simon McVittie Tue, 26 Jul 2022 19:00:58 +0100 + +ostree (2022.4-2) unstable; urgency=medium + + [ Dan Nicholson ] + * Backport patch to fix 2022.4 symbol version parent + + -- Simon McVittie Sun, 19 Jun 2022 20:58:51 +0100 + +ostree (2022.4-1) unstable; urgency=medium + + [ Dan Nicholson ] + * New upstream release + - Drop patches that were applied upstream + * d/control: Bump libglib2.0-dev dependency to 2.66.0 + * Add new ostree-boot-complete.service unit to ostree-boot + + [ Simon McVittie ] + * d/copyright: Update + * New upstream release + * d/libostree-1-1.symbols: Update + * d/p/test-basic-c-Don-t-assert-that-extended-attributes-are-av.patch: + Add patch to skip a test-case if /var/tmp doesn't support xattrs + + -- Simon McVittie Fri, 17 Jun 2022 16:35:46 +0100 + +ostree (2022.2-3) unstable; urgency=medium + + * d/rules: Correct argument used to disable gjs on s390x + + -- Simon McVittie Tue, 08 Mar 2022 16:16:43 +0000 + +ostree (2022.2-2) unstable; urgency=medium + + * d/control: Disable JavaScript-based tests on s390x. + Mitigates: ostreedev/ostree#2527 + * d/rules: Explicitly disable JS-based tests on architectures where + they're unreliable, or where an up-to-date gjs is unavailable. + Otherwise we'd build and install these tests if gjs (maybe an + old version) happens to be installed, despite it not being in + Build-Depends. + + -- Simon McVittie Tue, 08 Mar 2022 09:55:53 +0000 + +ostree (2022.2-1) unstable; urgency=medium + + * New upstream release + - Updated libglnx submodule fixes an incompatibility with eCryptFS + (Closes: #1004467) + * Install new script /usr/libexec/libostree/s390x-se-luks-gencpio + into ostree-boot + * d/p/s390x-se-luks-gencpio-Fix-shebang-syntax.patch, + d/p/s390x-se-luks-gencpio-Use-interoperable-path-for-bash.patch: + Add patches to retain compatibility with non-/usr-merged systems + * d/libostree-1-1.symbols: Update + * d/p/test-prune-Read-to-the-end-of-cut-1-output.patch: + Add patch to fix an intermittent test failure involving SIGPIPE + * Revert Lintian overrides to latest released version of Lintian + + -- Simon McVittie Mon, 07 Mar 2022 21:12:45 +0000 + +ostree (2022.1-3) unstable; urgency=medium + + * Use debhelper 11 features instead of dh-exec + * Move README.md from gir1.2-ostree-1.0 to libostree-doc + * Release to unstable + + -- Simon McVittie Mon, 24 Jan 2022 10:43:09 +0000 + +ostree (2022.1-2) experimental; urgency=medium + + * ostree Breaks flatpak-builder (<< 1.2.1-2~). + Previous versions relied on being able to use FUSE 2 options that are + no longer supported by FUSE 3, so prepare a lockstep transition. + + -- Simon McVittie Mon, 10 Jan 2022 12:42:08 +0000 + +ostree (2022.1-1) experimental; urgency=medium + + * New upstream release + * Build using FUSE 3 + * Update syntax of Lintian overrides for newer Lintian + + -- Simon McVittie Fri, 07 Jan 2022 10:44:49 +0000 + +ostree (2021.6-1) unstable; urgency=medium + + * New upstream release + - Drop patch that was applied upstream + + -- Simon McVittie Mon, 13 Dec 2021 11:39:48 +0000 + +ostree (2021.5-1) unstable; urgency=medium + + * New upstream release + - Update symbols file + * d/p/test-commit-sign.sh-Skip-a-unit-test-when-running-as-an-i.patch: + Mark as applied upstream + + -- Simon McVittie Sun, 10 Oct 2021 17:51:27 +0100 + +ostree (2021.4-1) unstable; urgency=medium + + * New upstream release + - Update symbols file + - d/copyright: Update + - Drop patch that was applied upstream + * Standards-Version: 4.6.0 (no further changes) + * d/control: Canonicalize field name case Multi-arch => Multi-Arch + * Bump debhelper compat level from 12 to 13 + - debian/rules: Drop --fail-missing argument to dh_missing, which is + now the default. + * Remove Lintian override for #947258, fixed in lintian 2.105.0 + * d/p/test-commit-sign.sh-Skip-a-unit-test-when-running-as-an-i.patch: + Add patch to fix installed-tests + + -- Simon McVittie Tue, 05 Oct 2021 23:53:20 +0100 + +ostree (2021.3-2) unstable; urgency=medium + + * d/gbp.conf: Switch branch back to debian/master + * d/p/tests-Unset-SOURCE_DATE_EPOCH.patch: + Apply patch from upstream to fix tests with SOURCE_DATE_EPOCH + - Revert "d/test.sh, d/tests: Unset SOURCE_DATE_EPOCH", + no longer needed + * d/rules: Normalize permissions of installed-tests + * Adjust Lintian overrides. + Recent debhelper installs units into /usr/lib/systemd, so adjust our + override to match either way. + + -- Simon McVittie Mon, 23 Aug 2021 19:30:23 +0100 + +ostree (2021.3-1) experimental; urgency=medium + + * New upstream release + - Increase build-dependency to GLib 2.44 + - d/libostree-1-1.symbols: Update + - Drop patches that were applied upstream + * Re-enable gjs tests on architectures where it is available + * d/libostree-1-1.symbols: Remove a duplicate symbol + * d/test.sh, d/tests: Unset SOURCE_DATE_EPOCH. + Otherwise, some tests will think we're downgrading, and fail. + + -- Simon McVittie Sun, 25 Jul 2021 19:18:51 +0100 + +ostree (2021.2-2) experimental; urgency=medium + + * d/p/libtest-On-failure-make-it-clearer-what-has-happened.patch: + Mark patch as applied upstream + * d/p/tests-Test-without-a-cache-directory-by-default.patch: + Add patch from upstream to fix intermittent FTBFS on some filesystems + + -- Simon McVittie Mon, 26 Apr 2021 10:15:06 +0100 + +ostree (2021.2-1) experimental; urgency=medium + + * New upstream release + - Update symbols file + - d/copyright: Update + * d/test.sh: Line-buffer stdout. + Otherwise, lines from stdout appear with an arbitrary delay, making it + hard to tell what the order of events was. + * d/p/libtest-On-failure-make-it-clearer-what-has-happened.patch: + Add proposed patch to make test failures easier to debug + + -- Simon McVittie Sun, 18 Apr 2021 12:20:49 +0100 + +ostree (2021.1-1) experimental; urgency=medium + + * d/gbp.conf: Branch for experimental + * New upstream release + - Update symbols file + - Drop a patch that was applied upstream + * d/rules: Declare that we have grub >= 2.02. + Debian's grub packaging runs grub-install in postinst, so we should + be able to rely on grub actually getting updated. + * Standards-Version: 4.5.1 (no changes required) + + -- Simon McVittie Wed, 14 Apr 2021 13:53:50 +0100 + +ostree (2020.8-2) unstable; urgency=medium + + * d/p/test-pull-summary-sigs-Set-timestamps-to-serve-expected-f.patch: + Add proposed patch to fix test failures when run on tmpfs + (Closes: #975418) + + -- Simon McVittie Sun, 22 Nov 2020 13:24:35 +0000 + +ostree (2020.8-1) unstable; urgency=medium + + * New upstream release + * Update symbols file + + -- Simon McVittie Thu, 19 Nov 2020 14:47:09 +0000 + +ostree (2020.7-1) unstable; urgency=medium + + * New upstream release + * Update symbols file + * Remove an unused lintian override + * Override Lintian warning for gtk-doc outside /usr/share/doc + (see #970275) + + -- Simon McVittie Wed, 14 Oct 2020 15:54:19 +0100 + +ostree (2020.6-1) unstable; urgency=medium + + * New upstream release + * ostree-boot-examples: Update for ostree-boot being in Debian 10 + * Update documentation: separate /boot should no longer be required + + -- Simon McVittie Tue, 08 Sep 2020 11:00:40 +0100 + +ostree (2020.5-1) unstable; urgency=medium + + * New upstream release + * ostree-tests: Depend on gjs on s390x again. + mozjs and gjs are believed to work fine on s390x now. + + -- Simon McVittie Fri, 21 Aug 2020 08:41:27 +0100 + +ostree (2020.4-2) unstable; urgency=medium + + * Depend on bsdextrautils, for hexdump (used during testing) + - Add to Build-Depends + - Add to ostree-tests Depends + - Allow bsdmainutils (<< 12) as an alternative, for backports + + -- Simon McVittie Mon, 10 Aug 2020 12:33:14 +0100 + +ostree (2020.4-1) unstable; urgency=medium + + * New upstream release + * d/copyright: Update + * d/libostree-1-1.symbols: Update + * Update Lintian overrides for some minor false-positives + + -- Simon McVittie Mon, 27 Jul 2020 23:43:11 +0100 + +ostree (2020.3-1) unstable; urgency=medium + + * New upstream release + + -- Simon McVittie Wed, 25 Mar 2020 12:29:32 +0000 + +ostree (2020.2-1) unstable; urgency=medium + + * New upstream release + - d/libostree-1-1.symbols: Update + * Set upstream metadata fields: Repository. + * Remove obsolete field Name from debian/upstream/metadata (already + present in machine-readable debian/copyright). + * Standards-Version: 4.5.0 (no changes required) + + -- Simon McVittie Wed, 26 Feb 2020 21:00:11 +0000 + +ostree (2019.6-1) unstable; urgency=medium + + * New upstream release + - d/libostree-1-1.symbols: Update + * d/tests/build: Use correct compiler for proposed autopkgtest + cross-architecture testing support + * d/tests: Make tests shellcheck-clean + + -- Simon McVittie Sat, 14 Dec 2019 11:30:10 +0000 + +ostree (2019.5-1) unstable; urgency=medium + + * New upstream release + - d/copyright: Update + + -- Simon McVittie Sat, 02 Nov 2019 10:32:49 +0000 + +ostree (2019.4-1) unstable; urgency=medium + + * New upstream release + - d/libostree-1-1.symbols: Update + - d/copyright: Update + * d/control: Set Vcs-Git to point to default branch again + * Standards-Version: 4.4.1 (no changes required) + * d/p/debian/Revert-lib-Kill-GPG-agent-when-cleaning-up-tmp-homedirs.patch: + Drop patch, fixed differently upstream in 2019.4 + + -- Simon McVittie Tue, 01 Oct 2019 09:30:23 +0100 + +ostree (2019.3-3) unstable; urgency=medium + + * Upload to unstable + - d/gbp.conf: Reset packaging branch to debian/master + + -- Simon McVittie Thu, 19 Sep 2019 17:49:53 +0100 + +ostree (2019.3-2) experimental; urgency=medium + + [ Felix Krull ] + * Enable ostree-boot package (Closes: #824650) + * ostree-boot: Weaken dracut Depends to Recommends. + The systemd parts of the package could also be used for integration + with e.g. initramfs-tools. + + [ Simon McVittie ] + * Switch packaging branch to debian/experimental + * d/ostree-boot.postinst: Trigger an update of the initramfs. + Otherwise the dracut initramfs won't be rebuilt to include ostree-boot. + * Add instructions for testing ostree-boot. + Thanks to Felix Krull for providing the original version of these. + * d/copyright: Update + * d/ostree-boot.lintian-overrides: + Do not warn about ostree-remount.service being in local-fs.target. + This part of the boot integration is genuinely part of an earlier + phase of boot than sysinit.target. + + -- Simon McVittie Sat, 31 Aug 2019 19:06:38 +0100 + +ostree (2019.3-1) unstable; urgency=medium + + * New upstream release + - Refresh patch series + * d/p/debian/Revert-lib-Kill-GPG-agent-when-cleaning-up-tmp-homedirs.patch: + Skip `gpg-connect-agent` when cleaning up temporary GPG home + directories. It appears this is sometimes done when it wasn't + needed, causing gpg-connect-agent to wait for an agent to start so + that it can tell it to stop, which results in a lot of noise on stderr + when running `flatpak update`. Debian 10 has GPG 2.2, and according to + the commit message of the commit I'm reverting here, this cleanup + should be unnecessary with GPG >= 2.2. + + -- Simon McVittie Fri, 23 Aug 2019 11:28:27 +0100 + +ostree (2019.2-2) unstable; urgency=medium + + * Upload to unstable + * d/gbp.conf: Return to debian/master branch + * d/salsa-ci.yml: Request standard CI on salsa.debian.org + - Disable build-time tests with DEB_BUILD_OPTIONS=nocheck for now. + They don't currently work in the salsa-ci infrastructure, but I + can't reproduce and debug the failure in a local Docker container. + - Similarly, disable the autopkgtest for now. + * Standards-Version: 4.4.0 (no changes required) + * Use debhelper-compat 12 + - Override dh_installsystemd instead of dh_systemd_start + - Stop overriding libexecdir + + -- Simon McVittie Tue, 09 Jul 2019 20:13:57 +0100 + +ostree (2019.2-1) experimental; urgency=medium + + * New upstream release + * d/upstream/metadata: Add DEP-12 metadata + * d/copyright: Update + * d/libostree-1-1.symbols: Update + * Use debian/experimental branch for new upstream release during freeze + + -- Simon McVittie Mon, 29 Apr 2019 09:11:58 +0100 + +ostree (2019.1-1) unstable; urgency=medium + + * New upstream release + * d/copyright: Update + * Standards-Version: 4.3.0 (no changes required) + + -- Simon McVittie Mon, 14 Jan 2019 08:23:44 +0000 + +ostree (2018.9.1-1) unstable; urgency=medium + + * d/tests/build: Mark as superficial (see #904979) + * New upstream release + - d/libostree-1-1.symbols: Update + * Skip installation of new ostree-finalize-staged.path unit, which + should be in ostree-boot when added (see #824650) + * Override lintian warning for /usr/share/ostree/trusted.gpg.d/README-gpg + not being in /usr/share/doc: it documents the directory in which it is + located + + -- Simon McVittie Tue, 30 Oct 2018 16:04:19 +0000 + +ostree (2018.8-2) unstable; urgency=medium + + [ Simon McVittie ] + * ostree-tests: Remove gjs dependency on s390x. + mozjs60 doesn't work on s390x, so gjs is in danger of being removed + from that architecture (see #909536). The test that uses JS is + automatically skipped if the interpreter is missing. + (Closes: #910286) + * Standards-Version: 4.2.1 (no changes required) + + [ Ondřej Nový ] + * d/tests: Use AUTOPKGTEST_TMP instead of ADTTMP + * d/changelog: Remove trailing whitespaces + + -- Simon McVittie Thu, 04 Oct 2018 14:54:29 +0100 + +ostree (2018.8-1) unstable; urgency=medium + + * New upstream release + - d/p/debian/Skip-test-pull-repeated-during-CI.patch: + Drop, applied upstream + - d/copyright: Update + * Standards-Version: 4.2.0 (no changes required) + + -- Simon McVittie Thu, 23 Aug 2018 13:19:00 +0100 + +ostree (2018.7-2) unstable; urgency=medium + + * d/p/debian/Skip-test-pull-repeated-during-CI.patch: + Skip a test that is non-deterministic and can spuriously fail, + which is not suitable for build-time testing or gating migration in + autopkgtest. + + -- Simon McVittie Mon, 30 Jul 2018 16:52:35 +0100 + +ostree (2018.7-1) unstable; urgency=medium + + * New upstream release + - d/libostree-1-1.symbols: Update + - Drop all patches, applied upstream + - d/copyright: Remove details of Rust files not included in this + release + * d/p/lib-pull-Fix-minor-memleak-in-error-path.patch: + Apply a memory leak fix from upstream + * Use upstream default ${libexecdir} now that Debian Policy allows + /usr/libexec (via FHS 3.0) + * Standards-Version: 4.1.5 (no changes required) + + -- Simon McVittie Wed, 25 Jul 2018 23:46:29 +0100 + +ostree (2018.6-3) unstable; urgency=medium + + * d/p/avahi-Fail-immediately-if-we-can-t-talk-to-D-Bus-or-Avahi.patch: + Mark as applied upstream + * d/p/OstreeRepoFinderConfig-Fix-guint-gsize-confusion.patch: + Add patch to fix incorrect type aliasing that caused assertion + failures on 64-bit big-endian platforms (Closes: #902209) + + -- Simon McVittie Sun, 24 Jun 2018 13:04:09 +0100 + +ostree (2018.6-2) unstable; urgency=medium + + * d/p/lib-repo-Fix-32-bit-format-string-error.patch: + Apply patch from upstream to fix FTBFS on 32-bit architectures + (Closes: #902194) + + -- Simon McVittie Sat, 23 Jun 2018 12:37:27 +0100 + +ostree (2018.6-1) unstable; urgency=medium + + * New upstream release with support for peer-to-peer software + collections, required by Flatpak's peer-to-peer app sharing feature + - d/copyright: Update + - d/libostree-1-1.symbols: Update + - Build-depend on Avahi libraries + * d/rules: Explicitly enable various desired libraries + * d/p/avahi-Fail-immediately-if-we-can-t-talk-to-D-Bus-or-Avahi.patch: + Add patch to avoid Flatpak test failures with this ostree if Avahi + (or dbus-daemon --system) is not available on the build/test system + + -- Simon McVittie Fri, 22 Jun 2018 21:05:29 +0100 + +ostree (2018.5-2) unstable; urgency=medium + + * d/tests/gnome-desktop-testing: Skip libostree/test-concurrency.py.test + during autopkgtest. It does not appear to be completely reliable. + (See #901170) + + -- Simon McVittie Sun, 10 Jun 2018 13:57:19 +0100 + +ostree (2018.5-1) unstable; urgency=medium + + * New upstream release + - d/copyright: Upstream clarified that only doc/ is CC-BY-SA-3.0 or + GFDL-1.3-or-later, and doc/ isn't included in dist tarballs, so + remove those licenses + - d/libostree-1-1.symbols: Update (and sort) + - d/p/Don-t-write-to-parent-repo.patch: Drop, applied upstream + - d/ostree-boot.install: Add new systemd service + lib/systemd/system/ostree-finalize-staged.service + - d/rules: Remove lib/systemd/system/ostree-finalize-staged.service + until we build ostree-boot + * ostree-tests: Add Lintian override for library-not-linked-against-libc. + libreaddir-rand.so genuinely doesn't use any libc ABIs directly, only + via GLib. + * Standards-Version: 4.1.4 (no changes required) + + -- Simon McVittie Tue, 15 May 2018 11:30:03 +0100 + +ostree (2018.4-2) unstable; urgency=medium + + * d/p/Don-t-write-to-parent-repo.patch: + Add patch from upstream to prevent trying to write to a parent + repository, fixing installation of Flatpak apps and runtimes into + the system-wide repository (Closes: #895883) + + -- Simon McVittie Tue, 17 Apr 2018 09:06:42 +0100 + +ostree (2018.4-1) unstable; urgency=medium + + * New upstream release + * Update symbols file + * Drop all patches, including one that was previously considered to + be Debian-specific (moving to Python 3 for tests) + * d/copyright: Update + + -- Simon McVittie Sat, 24 Mar 2018 19:20:08 +0000 + +ostree (2018.2-1) unstable; urgency=medium + + * New upstream release + - d/copyright: Update + - d/libostree-1-1.symbols: Update + * Mark patches as forwarded + * Add gnupg to build-time test dependencies (and ostree-tests + dependencies) as it is no longer transitively build-essential + + -- Simon McVittie Mon, 19 Feb 2018 09:01:47 +0000 + +ostree (2018.1-1) unstable; urgency=medium + + * New upstream release + - d/copyright: Update + - d/patches: Remove, applied upstream + - d/libostree-1-1.symbols: Update + * Move Vcs-* to salsa.debian.org + d/p/test-concurrency-Explicitly-use-floor-division.patch, + d/p/tests-bootloader-entries-crosscheck-Use-Python-3-friendly.patch: + Make tests compatible with Python 3 + * d/control, d/p/debian/Use-Python-3-for-tests.patch: + Switch build-time tests and autopkgtests to Python 3 + + -- Simon McVittie Wed, 17 Jan 2018 15:34:46 +0000 + +ostree (2017.15-2) unstable; urgency=medium + + * d/p/2018.1/tests-Don-t-assume-uid-primary-gid.patch: Mark as applied + upstream in 2018.1 + * d/p/2018.1/tests-Assert-that-byte-order-[etc.].patch: + Add patch to fix test failures on big-endian machines + (Closes: #886218) + * Temporarily disable gjs tests. gjs is not currently installable on + buildds due to the glibc transition and a long dependency chain + involving systemd-shim being preferred over systemd-sysv, which + ends with libnih1 Depends: libc6 (<< 2.26). + + -- Simon McVittie Thu, 04 Jan 2018 19:26:16 +0000 + +ostree (2017.15-1) unstable; urgency=medium + + * New upstream release + - d/libostree-1-1.symbols: Update + * d/rules: Stop forcing C.UTF-8 locale: the tests now do this internally + * Standards-Version: 4.1.3 (no changes required) + * d/p/tests-Don-t-assume-uid-primary-gid.patch: Mark as forwarded + + -- Simon McVittie Tue, 02 Jan 2018 14:13:08 +0000 + +ostree (2017.14-1) unstable; urgency=medium + + * New upstream release + - d/libostree-1-1.symbols: Update + * Standards-Version: 4.1.2 (no changes required) + * d/p/tests-Don-t-assume-uid-primary-gid.patch: + Add patch to fix automated test failure when uid != primary gid + + -- Simon McVittie Sun, 10 Dec 2017 19:42:36 +0000 + +ostree (2017.13-1) unstable; urgency=medium + + * New upstream release + - d/patches: Drop all patches + - d/copyright: Update + - Update symbols file + * d/control: Require dh-exec 0.23~, for build-profile support. + Strictly speaking we might only need 0.15, but I'm not going to + test versions older than the jessie backport. + * Set Rules-Requires-Root to no + * Standards-Version: 4.1.1 (no changes required) + + -- Simon McVittie Sat, 04 Nov 2017 14:05:06 +0000 + +ostree (2017.12-2) unstable; urgency=medium + + * Disable gtk-doc if we are not going to build libostree-doc, + in particular for architecture-specific builds. Note that it remains + in Build-Depends (not Build-Depends-Indep) because it is also needed + for gtkdocize during dh_autoreconf. + - In particular this might fix FTBFS on sparc64, where highlight(1) + fails. + * d/p/2017.13/lib-core-Init-struct-stat-buffer.patch, + d/p/2017.13/lib-sysroot-Fix-pointer-going-out-of-scope-in-unlock-code.patch, + d/p/2017.13/lib-deploy-Ignore-FIFREEZE-FITHAW-errors-when-already-in-.patch, + d/p/2017.13/lib-deploy-Use-_exit-for-FIFREEZE-watchdog.patch, + d/p/2017.13/lib-deltas-Check-cancellable-during-processing.patch, + d/p/2017.13/lib-utils-Check-for-invalid-UTF-8-in-filenames.patch, + d/p/2017.13/Cope-with-xattr-syscalls-raising-EOPNOTSUPP.patch, + d/p/2017.13/lib-sysroot-Fix-error-handling-when-mounting-overlayfs-fa.patch, + d/p/2017.13/lib-repo-Properly-handle-NULL-homedir-when-signing-commit.patch, + d/p/2017.13/fdio-allow-NULL-for-fstatat_allow_noent-stbuf.patch, + d/p/2017.13/lib-repo-Fix-loading-commitstate-with-parent-repos.patch: + Add various bugfix patches from upstream + - In particular, dealing with the possibility that EOPNOTSUPP != ENOTSUP + should fix test failures on hppa. + * d/p/2017.13/tests-Add-test-pull-bareuseronly.patch: + Add more test coverage from upstream + - d/rules: Make the new test executable + * d/test.sh: Clean up ostree-trivial-httpd processes + * d/test.sh: Don't repeat build-time tests if they fail once. They seem + to be somewhat reliable now. + + -- Simon McVittie Fri, 27 Oct 2017 00:19:45 +0100 + +ostree (2017.12-1) unstable; urgency=medium + + * New upstream release + - Drop all current patches, applied upstream + - Update symbols file + * Add some post-release bug fix patches + * Simplify autopkgtest now that test-local-pull seems to be stable + * Unexport HTTP proxy variables in autopkgtest to work around lack of + support for no_proxy, which breaks the tests on Ubuntu autopkgtest. + We don't actually need Internet access, so this is OK. + * debian/test.sh: Unexport HTTP proxy variables for build-time tests + too + * Make build-time test failures fatal if they fail at least twice + out of 5 tries (previously they had to fail at least 3 times) + * Add patch to reinstate test-libglnx-shutil.c, which was missed out + of the upstream tarball + + -- Simon McVittie Tue, 03 Oct 2017 22:47:48 +0100 + +ostree (2017.11-2) unstable; urgency=medium + + * Replace patch with the version applied upstream in 2017.12 + * Standards-Version: 4.1.0 (no changes) + * Add a patch to fix FTBFS in non-English locales + * Add a patch to fix FTBFS if building as root with umask != 022, + which for some reason debomatic does (Closes: #876138) + * Add a patch from upstream to fix undefined behaviour with + O_RDONLY|O_CREAT in rofiles-fuse + + -- Simon McVittie Fri, 22 Sep 2017 15:48:24 +0100 + +ostree (2017.11-1) unstable; urgency=medium + + * New upstream release + - Drop all current patches, applied upstream + - Update symbols file + * Adjust Description and Upstream-Name to emphasize libostree + * Classify new ostree-tmpfiles.conf as part of ostree-boot, and so + don't install it yet + * Stop copying an old ostree-trivial-httpd.xml from debian/dist/ + into source tree. Upstream distributes it again, and has since + 2017.8. + * Add a patch to fix JavaScript tests with gjs 1.50.0, which is + more strict about 'let' + * Stop providing "ostree trivial-httpd" CLI, following upstream + default behaviour. flatpak used to use it in its tests, but + the version in stable no longer does. + + -- Simon McVittie Fri, 15 Sep 2017 16:58:15 +0100 + +ostree (2017.10-1) unstable; urgency=medium + + * New upstream release + - Update symbols file + - Install new bash completions + * Use dh_missing --fail-missing instead of dh_install --fail-missing + * Only run tests when building architecture-dependent packages. + The tests aren't so interesting that we want to run them again + when splitting -arch/-indep builds. + * Add patches to make the tests pass again when /var/tmp is on tmpfs, + which does not support user xattrs + * Add patch to remove useless #! from bash completions + * Make build-time test failures fatal again, but only if they are + reproducible (at least 3 times out of 5) for now + + -- Simon McVittie Tue, 29 Aug 2017 18:18:49 +0100 + +ostree (2017.9-1) unstable; urgency=medium + + * New upstream release + - Drop backported patch + - Update symbols file + * debian/rules: Adjust a comment to avoid Lintian thinking this is a + dh_make template + + -- Simon McVittie Fri, 28 Jul 2017 14:43:30 +0100 + +ostree (2017.8-1) unstable; urgency=medium + + * New upstream release + - Update symbols file + - Remove patches that are no longer needed + - Add patch from upstream PR #1016 to fix a regression + * Add a Breaks on flatpak (<< 0.8.7-2~), which rely on libostree to + download the summary and its signature when mirroring. + libostree >= 2017.7 no longer does this. On affected flatpak versions, + this breaks installation of new apps and runtimes system-wide. + * Add Build-Depends-Indep: libglib2.0-doc so gtk-doc can set up + cross-references + + -- Simon McVittie Wed, 19 Jul 2017 22:18:20 +0100 + +ostree (2017.7-1) unstable; urgency=medium + + * New upstream release + - Update symbols file + - Add post-release patches so test-symbols.sh passes again + - debian/dist/: Add ostree-trivial-httpd.xml, which was incorrectly + excluded from the upstream release + * Standards-Version: 4.0.0 + - Use https URL for copyright-format + * Implement build profile + * Upload to unstable + + -- Simon McVittie Wed, 21 Jun 2017 13:06:54 +0100 + +ostree (2017.6-1) experimental; urgency=medium + + * New upstream release + - Update debian/copyright + - Update disabled ostree-boot packaging for new systemd generator + - Add new ABI to symbols file + * Skip build-time tests when nocheck is in DEB_BUILD_OPTIONS + (Closes: #862803). Thanks to Krzesimir Nowak + + -- Simon McVittie Thu, 25 May 2017 10:01:12 +0100 + +ostree (2017.5-1) experimental; urgency=high + + * New upstream release + - This release fixes a regression in 2017.4 that caused symlinks + in Flatpak apps and runtimes to be checked out as regular files. + Any apps or runtimes that were installed or updated with 2017.4 + will need to be removed and reinstalled. + + -- Simon McVittie Wed, 19 Apr 2017 14:18:16 +0100 + +ostree (2017.4-1) experimental; urgency=medium + + * New upstream release + - d/rules: Explicitly enable trivial-httpd: the tests still need it + - Update symbols file for new ABI + + -- Simon McVittie Mon, 17 Apr 2017 17:19:58 +0100 + +ostree (2017.3-2) experimental; urgency=medium + + * d/ostree.maintscript: Clean up obsolete conffiles from before we + started removing what will eventually become ostree-boot + (see #824650) + * libostree-dev: Add missing dependency on libostree-1-1 + (Closes: #860047) + + -- Simon McVittie Mon, 10 Apr 2017 18:52:26 +0100 + +ostree (2017.3-1) experimental; urgency=medium + + * d/watch, d/copyright: upstream project is now named libostree + * New upstream release + - d/copyright: update + - symbols file: update + - tests, ostree-tests.install: update for new location of tests + - d/control: ostree-tests now needs python-yaml + - build-depend on python, python-yaml for tests + + -- Simon McVittie Thu, 16 Mar 2017 06:58:46 +0000 + +ostree (2017.1-1) experimental; urgency=medium + + * Branch to experimental to avoid interfering with the Debian 9 freeze + * Remove an unintended line in the previous changelog + * New upstream release + - trivial-httpd is now a separate binary. Move it to ostree-tests, + so that it doesn't continue to pull in libsoup if the ostree + downloader is ported to libcurl. + - d/copyright: update + - d/patches: drop all patches, applied upstream + * Explicitly depend on autoconf, automake, libtool. This avoids + builds for experimental non-deterministically pulling in an older + version of automake, in my case automake1.11 which is far too old. + + -- Simon McVittie Fri, 27 Jan 2017 10:23:47 +0000 + +ostree (2016.15-3) unstable; urgency=medium + + * debian/control: Don't run gjs tests on sparc64. gjs doesn't seem + to work there at all (#827815) + - d/ostree-tests.lintian-overrides: silence + missing-dep-for-interpreter error on sparc64, where we install + the script but do not attempt to run it + * debian/tests/gnome-desktop-testing: Skip test-local-pull.sh.test + which suffers from a known bug (#842606) + - debian/tests/test-local-pull: Run the unreliable test separately, + repeated 3 times to assess how often it fails + * d/p/Sourced-test-snippets-remove-shebang-and-make-non-executa.patch, + d/p/Make-corrupt-repo-ref.js-executable.patch: + Fix permissions and #! lines for some tests in the upstream build + system + * d/rules: remove workarounds for script permissions. + The upstream build system now uses the intended permissions throughout. + - Retain explicit chmod for *.js, which dh_fixperms assumes should + not be executable. + * d/p/Fix-TAP-syntax-in-test-basic-user.sh-and-run-it.patch: + Run an additional test, which was previously installed but not run + + -- Simon McVittie Thu, 19 Jan 2017 13:23:32 +0000 + +ostree (2016.15-2) unstable; urgency=medium + + * Make all test failures non-fatal at build time, so that intermittent + test failures do not interfere with possible security updates during + Debian stretch-as-stable. + + -- Simon McVittie Tue, 20 Dec 2016 11:28:41 +0000 + +ostree (2016.15-1) unstable; urgency=medium + + * New upstream release + - d/patches: drop all patches, applied upstream + + -- Simon McVittie Tue, 13 Dec 2016 13:13:44 +0000 + +ostree (2016.14-2) unstable; urgency=medium + + * Make build-time test failures non-fatal, as long as at least + 3 out of 5 attempts succeed. + + There are several upstream bugs that cause intermittent test + failures, and can intermittently be reproduced in real use. + However, these are not regressions, so we should not FTBFS just + because we happen to have been unlucky during build. + + * d/p/Terminate-individual-tests-after-10-minutes.patch: + replace d/p/debian/Terminate-individual-tests-after-half-an-hour.patch + with the version that I sent upstream, which uses SIGABRT and + terminates the tests sooner + * d/p/*.patch: import more memory leak fixes from upstream + + -- Simon McVittie Thu, 01 Dec 2016 12:38:54 +0000 + +ostree (2016.14-1) unstable; urgency=medium + + * Switch the build-dependency on libgpgme11-dev (which no longer exists + as a real package) to libgpgme-dev + * Drop the version from versioned build-dependencies where the required + version was already present in oldstable + * New upstream release + - update symbols file for new ABI + * Import various post-release fixes from upstream + + -- Simon McVittie Tue, 29 Nov 2016 11:05:44 +0000 + +ostree (2016.13-1) unstable; urgency=medium + + * New upstream release + - d/p/dist/Retrieve-some-missing-test-files-from-upstream-git.patch: + remove, 2016.13 was released with a fixed "make dist" + - d/p/Filter-bootloader-supplied-kernel-cmdline-options.patch: + remove, merged upstream + * d/copyright: drop copyright and license stanzas for files that are + in upstream git but not in tarballs + + -- Simon McVittie Sun, 20 Nov 2016 21:58:11 +0000 + +ostree (2016.12-2) unstable; urgency=medium + + * d/p/Filter-bootloader-supplied-kernel-cmdline-options.patch: + - Filter out kernel command line parameters set by the bootloading when + deriving the configuration from /proc/cmdline. + * Add myself to uploaders + + -- Sjoerd Simons Thu, 03 Nov 2016 15:48:01 -0600 + +ostree (2016.12-1) unstable; urgency=medium + + * Force LC_ALL=C.UTF-8 during build, so that builds in non-English + locales can pass their build-time tests + * New upstream release + * Build-depend on ca-certificates. glib-networking now generates + warnings if those are missing, causing the build-time tests to fail. + + -- Simon McVittie Wed, 26 Oct 2016 19:11:14 +0100 + +ostree (2016.11-1) unstable; urgency=medium + + * New upstream release + * Relicense debian/ from GPL-2+ to LGPL-2+, with permission from + David King + * Install GObject-Introspection typelibs to multiarch path, + and mark gir1.2-ostree-1.0 as Multi-Arch: same + * libostree-dev: stop depending on ostree. It isn't necessary to + use the library, and would break multiarch installability + * Move to debhelper compat level 10 + - stop using dh --parallel, it's the default now + - don't use autoreconf and systemd addons explicitly, they are + the default now + * d/p/dist/Retrieve-some-missing-test-files-from-upstream-git.patch: + fetch missing test files from upstream git + - debian/rules: make the missing scripts executable + + -- Simon McVittie Fri, 07 Oct 2016 23:39:06 +0100 + +ostree (2016.10-1) unstable; urgency=medium + + * New upstream release + * Make libostree-dev Multi-Arch: same + * Make libostree-doc Multi-Arch: foreign + + -- Simon McVittie Thu, 15 Sep 2016 08:26:51 +0100 + +ostree (2016.9-2) unstable; urgency=medium + + * debian/patches/Terminate-individual-tests-after-half-an-hour.patch: + terminate individual tests after 30 minutes, in an attempt to debug + what happened on the ppc64el buildd + + -- Simon McVittie Fri, 09 Sep 2016 08:23:44 +0100 + +ostree (2016.9-1) unstable; urgency=medium + + * New upstream version + - update symbols file for new ABI + - update copyright file + - update ostree-boot packaging: the utilities in /usr/sbin moved to + /usr/lib/ostree + - drop libgsystem build-dependency + - d/p/Makefile-tests.am-make-check-uses-the-built-binaries.patch: + drop, applied upstream + * Explicitly build-depend on xsltproc, which is directly used + + -- Simon McVittie Tue, 06 Sep 2016 09:59:00 +0100 + +ostree (2016.7-1) unstable; urgency=medium + + * New upstream version + - drop all patches, applied upstream + - build-depend on libsystemd (unconditionally, because this package is + Linux-specific already) + - update symbols file for new ABI + * d/p/Makefile-tests.am-make-check-uses-the-built-binaries.patch: + add patch from upstream to make sure we use the built binaries for + build-time testing + * d/control: mention Flatpak, not its former name xdg-app + + -- Simon McVittie Thu, 28 Jul 2016 07:40:27 +0100 + +ostree (2016.6-4) unstable; urgency=medium + + * Switch sense of check in debian/test.sh so we really ignore test + failures on mipsel, and not on !mipsel. + + -- Simon McVittie Wed, 06 Jul 2016 15:23:31 +0100 + +ostree (2016.6-3) unstable; urgency=medium + + * Ignore build-time test failures on mipsel. "ostree pull" + intermittently fails with a bus error on at least some mipsel CPUs, + and applying gdb to the resulting core dump does not produce any + useful information. Debugging help would be appreciated. + (Mitigates: #827473) + + -- Simon McVittie Wed, 06 Jul 2016 10:17:43 +0100 + +ostree (2016.6-2) unstable; urgency=medium + + * d/p/tests-Improve-check-for-proc-cmdline-kargs.patch: add patch from + upstream fixing FTBFS on host machines without root= in /proc/cmdline, + such as the reproducible builds armhf workers + * d/control, d/copyright: use the GitHub repository as the Homepage + and Source: the GNOME wiki page is less frequently updated + + -- Simon McVittie Tue, 28 Jun 2016 09:29:53 +0100 + +ostree (2016.6-1) unstable; urgency=medium + + [ Jeremy Bicha ] + * Fix debian/watch (Closes: #827440) + + [ Simon McVittie ] + * New upstream release + - drop all patches, included upstream + - update symbols file + - this version is more careful about thread-safety, which appears + to fix the test failures that caused FTBFS on mipsel + (Closes: #827473) + * d/watch: fetch releases from GitHub instead of GNOME + * d/gbp.conf: configure to use upstream/latest for upstream imports + * d/gbp.conf: configure to merge upstream tags into upstream/latest + (add https://github.com/ostreedev/ostree as a remote) + * d/p/libostree.sym-Fix-test-symbols.patch: apply patch from upstream + to fix a build-time test + * d/p/pull-Correctly-handle-repo-parent_repo-when-applying-stat.patch: + apply patch from upstream to fix a bug that flatpak currently works + around + * d/p/tests-fail-the-build-if-symlinking-tests-ostree-fails.patch, + d/p/tests-use-our-own-generated-libtool-not-the-one-in-PATH.patch: + add patches to ensure that the build-time tests act on the copy + of ostree that we just built + * d/p/entry_pathname_test_helper-these-tests-need-extended-attr.patch: + skip more tests if /var/tmp doesn't support extended attributes + * d/control: ostree no longer needs its Suggests on dracut. A stronger + dependency on dracut will be needed in the ostree-boot package when + the boot integration is reinstated (see #824650). + + -- Simon McVittie Sun, 26 Jun 2016 19:51:31 +0100 + +ostree (2016.5-4) unstable; urgency=medium + + * d/p/test-sysroot.js-set-strict-mode-when-sourcing-libtest.sh.patch, + d/p/tests-Use-strict-mode-by-default-for-C-tests.patch: add patches + to make sure the tests fail as soon as something goes wrong + * Build-depend on procps, used to check for leaked processes + * debian/test.sh: factor out our dh_auto_test wrapper, and clean + up any stray processes even if the test fails + * If build-time tests fail, try 4 more times to get an idea of + whether the failure is reproducible (hoping to diagnose #826858) + * Add a patch to link libreaddir-rand to libdl, which should fix + test failures on Ubuntu (Closes: #826857) + + -- Simon McVittie Tue, 14 Jun 2016 15:35:18 -0400 + +ostree (2016.5-3) unstable; urgency=medium + + * Remove ostree-grub2 and the boot-related parts of ostree, leaving + the library and the command-line tool, which are also used by + Flatpak. + When we have documentation for how to use and test OSTree + deployments with a Debian derivative (see #824649), they should be + reinstated in an ostree-boot package (see #824650). + * Upload to unstable. + + -- Simon McVittie Wed, 08 Jun 2016 11:58:01 +0100 + +ostree (2016.5-2) experimental; urgency=medium + + * Add a patch to skip the test-parent test if /var/tmp doesn't support + user xattrs, hopefully fixing FTBFS on x86-csail-02 buildd + + -- Simon McVittie Mon, 25 Apr 2016 12:51:33 +0100 + +ostree (2016.5-1) experimental; urgency=medium + + * New upstream release + - Remove all patches, applied upstream + - debian/libostree-1-1.symbols: update for new versioned symbols + - Build-depend on libmount-dev + - debian/copyright: update + - debian/rules, debian/ostree-tests.install: adjust for new installation + directory for installed-tests + - debian/rules: use Debian's grub2-mkconfig path + * debian/gbp.conf: use DEP-14 branch names; disable numbered patches + * Fix ITP bug number in changelog (was #813308, should have been #697477) + * debian/control: build-depend on attr, for the tests (only required if + /var/tmp supports extended attributes) + * debian/rules: clean up stale gpg-agent processes after testing + * debian/rules: warn if there are leftover daemon processes after testing + * debian/ostree-tests.lintian-overrides: override a couple of false + positives + * Run dh_auto_test with VERBOSE=1, to get logs with older debhelper + * Build-depend on elfutils, for test-abi.sh + * Work around #821235 to avoid undefined macro 'AQ' in some man pages + * Add a patch to put more information in the log if tests fail, + in an attempt to debug a failure in test/pull-resume.sh which + I can no longer reproduce + * Standards-version: 3.9.8 (no changes needed) + + -- Simon McVittie Mon, 25 Apr 2016 07:46:16 +0100 + +ostree (2016.3-1) experimental; urgency=medium + + * Prepare package for Debian (Closes: #697477) + * New upstream release + * Remove -dbg package, rely on automatic dbgsym packages instead + * Extend package descriptions a bit + * debian/.gitignore: add + * debian/copyright: fill in all copyright holders and licenses + * debian/control: set Maintainer to the pkg-utopia team, with packaging + in collab-maint git, and myself and Matthias Klumpp as uploaders + * Normalize packaging via `wrap-and-sort -abst` + * debian/control: move shared library to Section: libs + * debian/control: remove redundant Section + * debian/control: change Section to admin + * Remove unnecessary uses of dh-exec + * debian/patches: remove all patches, no longer needed or applied + * Use dh_install --fail-missing to catch mistakes + * Add a symbols file + * Add missing dependency on libglib2.0-dev + * Add an ostree-tests package, and use it for autopkgtest + * Enable systemd helpers, but do not start the early-boot systemd services + on installation + * Don't override dh_auto_clean to nothing + * ostree-grub2: recommend concrete GRUB packages instead of hard-depending + on a transitional package. This is only a Recommends because you + could be using some other architecture's grub packages. + * Redirect libexecdir to /usr/lib (not /usr/lib/${multiarch}) since we don't + need multiarch for anything that's installed there, fixing a broken + symlink in ostree-grub2 + * Document the limited situations in which ostree-grub2 will work in + practice + * Only build on Linux architectures; this package is specifically + not portable + * Add patch to fix underlinking of test-archive + * Add patch to skip one build-time test if /var/tmp cannot support xattrs, + for example if it is on tmpfs + * Stop dh_makeshlibs thinking that the LD_PRELOAD module libreaddir-rand.so + (part of the tests) is meant to be a shared library + * Add a missing #!/bin/sh to one test + + -- Simon McVittie Sat, 19 Mar 2016 17:56:21 +0000 + +ostree (2016.1-alexlarsson1~wily1) wily; urgency=medium + + * New upstream release + + -- Alexander Larsson Thu, 01 Oct 2015 11:28:39 +0200 + +ostree (2015.11-alexlarsson1~vivid1) vivid; urgency=medium + + * New upstream release + + -- Alexander Larsson Thu, 01 Oct 2015 11:28:39 +0200 + +ostree (2015.9-alexlarsson1) vivid; urgency=medium + + * New upstream release + + -- Alexander Larsson Thu, 01 Oct 2015 11:28:39 +0200 + +ostree (2015.4-0amigadave2) trusty; urgency=low + + [ David King ] + * Add build dependency on libattr1-dev. + + -- David King Wed, 08 Apr 2015 13:10:39 +0100 + +ostree (2015.4-0amigadave1) trusty; urgency=low + + [ David King ] + * Initial packaging. + + -- David King Thu, 02 Apr 2015 15:40:52 +0000 diff --git a/debian/control b/debian/control index 534c88c..86523a9 100644 --- a/debian/control +++ b/debian/control @@ -1,8 +1,8 @@ Source: ostree Section: admin Priority: optional -Maintainer: Deepin Developer -Uploaders: Deepin Packages Builder +Maintainer: Utopia Maintenance Team +Uploaders: Matthias Klumpp , Simon McVittie , Sjoerd Simons @@ -11,34 +11,37 @@ Build-Depends: autoconf, automake, bison, - bsdextrautils | bsdmainutils (<< 12) , + bsdextrautils , ca-certificates, cpio, + debhelper (>= 13.11.6~), debhelper-compat (= 13), docbook-xml , docbook-xsl , - e2fslibs-dev, + libext2fs-dev, elfutils, fuse3, - gjs [!alpha !hppa !ia64 !m68k !s390x !sh4 !sparc64 !x32 !sw64], + gjs [!alpha !hppa !ia64 !m68k !sh4 !sparc64 !x32], gnupg , gobject-introspection, gtk-doc-tools , libarchive-dev, libattr1-dev, - libavahi-client-dev (>= 0.6.31), - libavahi-glib-dev (>= 0.6.31), + libavahi-client-dev, + libavahi-glib-dev, libcap-dev, + libcurl4-gnutls-dev | libcurl-dev, libfuse3-dev, libgirepository1.0-dev, - libglib2.0-dev (>= 2.66.0), + libglib2.0-dev, libgpgme-dev, liblzma-dev, - libmount-dev (>= 2.23), + libmount-dev, libselinux1-dev, - libsoup2.4-dev (>= 2.39.1), + libsoup-3.0-dev (>= 3.0.0), libsystemd-dev, libtool, + pkgconf, procps, python3 , python3-yaml , @@ -47,10 +50,10 @@ Build-Depends: Build-Depends-Indep: libglib2.0-doc, Rules-Requires-Root: no -Standards-Version: 4.6.0 +Standards-Version: 4.6.2 Homepage: https://github.com/ostreedev/ostree/ -#Vcs-Git -#Vcs-Browser +Vcs-Git: https://salsa.debian.org/debian/ostree.git +Vcs-Browser: https://salsa.debian.org/debian/ostree Package: gir1.2-ostree-1.0 Architecture: linux-any @@ -75,8 +78,6 @@ Depends: ${shlibs:Depends}, Pre-Depends: ${misc:Pre-Depends}, -Breaks: - flatpak (<< 0.8.7-2~), Multi-Arch: same Description: content-addressed filesystem for operating system binaries (library) libostree is a library for managing bootable, immutable, versioned @@ -96,12 +97,14 @@ Multi-Arch: same Section: libdevel Depends: gir1.2-ostree-1.0 (= ${binary:Version}), - libglib2.0-dev (>= 2.66.0), + libglib2.0-dev, libostree-1-1 (= ${binary:Version}), - pkg-config, + pkgconf, ${misc:Depends}, Suggests: libostree-doc, +Provides: + gir1.2-ostree-1.0-dev (= ${binary:Version}), Description: Development files for the libostree library libostree is a library for managing bootable, immutable, versioned filesystem trees. It is like git in that it checksums individual files @@ -185,12 +188,12 @@ Package: ostree-tests Architecture: linux-any Depends: attr, - bsdextrautils | bsdmainutils (<< 12), + bsdextrautils, ca-certificates, cpio, fuse3, gir1.2-ostree-1.0, - gjs [!alpha !hppa !ia64 !m68k !sh4 !sparc64 !x32 !sw64], + gjs [!alpha !hppa !ia64 !m68k !sh4 !sparc64 !x32], gnupg, ostree, python3, diff --git a/debian/copyright b/debian/copyright index 3b04bc1..452d7b2 100644 --- a/debian/copyright +++ b/debian/copyright @@ -6,22 +6,26 @@ Files: * Copyright: © 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - © 1995-2015 Free Software Foundation, Inc. + © 1995-2023 Free Software Foundation, Inc. + © 1998 Manish Singh + © 1998 Tim Janik © 1999-2003 Ximian, Inc. + © 2006 Dave Benson © 2007-2008 Ryan Lortie - © 2008-2022 Red Hat, Inc + © 2008-2023 Red Hat, Inc © 2010-2011 Lennart Poettering © 2010 Codethink Ltd. © 2011-2019 Colin Walters © 2011 Avery Pennarun - © 2013-2020 Collabora Ltd. + © 2013-2022 Collabora Ltd. © 2013 Stef Walter © 2013 Javier Martinez © 2013 Jeremy Whiting © 2013-2016 Sjoerd Simons - © 2014-2017 Alexander Larsson + © 2014-2023 Alexander Larsson © 2014 Anne LoVerso © 2014 Owen Taylor + © 2014 Dan Winship © 2015 Dan Nicholson © 2015 Canonical Ltd. © 2015 Matthew Barnes @@ -29,14 +33,19 @@ Copyright: © 2016 Kinvolk GmbH © 2016 Zbigniew Jędrzejewski-Szmek © 2017 Georges Basile Stavracas Neto + © 2017 Emmanuele Bassi © 2018 Matthew Leeds © 2018 Sinny Kumari © 2019 Rafael Fonseca © 2019 Robert Fairley © 2019 Wind River Systems, Inc. © 2019 Denis Pynkin - © 2021 Endless OS Foundation LLC + © 2018-2023 Endless OS Foundation LLC + © 2020-2022 Niels De Graef + © 2021 Giuseppe Scrivano © 2022 Igalia S.L. + © 2022 Huijing Hei + © 2022 Eric Curtin License: LGPL-2+ and LGPL-2.1+ Files: @@ -54,6 +63,13 @@ Copyright: 2012 Lucas De Marchi License: GPL-2+ with Autoconf exception +Files: + composefs/libcomposefs/erofs_fs.h +Copyright: + 2017-2018 HUAWEI, Inc. + 2021 Alibaba Cloud +License: GPL-2+ or Apache-2.0 + Files: gtk-doc.make Copyright: @@ -90,6 +106,32 @@ Copyright: © 2017-2021 Simon McVittie License: LGPL-2+ +License: Apache-2.0 + (Apache license referenced a via SPDX license header, no license grant) +Comment: + On Debian systems, the full text of the Apache License version 2 + can be found in the file '/usr/share/common-licenses/Apache-2.0'. + +License: GPL-2+ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +Comment: + On Debian systems, the full text of the GNU General Public + License version 2 can be found in the file + '/usr/share/common-licenses/GPL-2'. + License: GPL-2+ with Autoconf exception This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/debian/libostree-1-1.symbols b/debian/libostree-1-1.symbols index d39f14f..8a81cf3 100644 --- a/debian/libostree-1-1.symbols +++ b/debian/libostree-1-1.symbols @@ -43,6 +43,10 @@ libostree-1.so.1 libostree-1-1 #MINVER# LIBOSTREE_2021.5@LIBOSTREE_2021.5 2021.5 LIBOSTREE_2022.2@LIBOSTREE_2022.2 2022.2 LIBOSTREE_2022.4@LIBOSTREE_2022.4 2022.4 + LIBOSTREE_2022.5@LIBOSTREE_2022.5 2022.5 + LIBOSTREE_2022.7@LIBOSTREE_2022.7 2022.7 + LIBOSTREE_2023.1@LIBOSTREE_2023.1 2023.1 + LIBOSTREE_2023.4@LIBOSTREE_2023.4 2023.5 ostree_async_progress_copy_state@LIBOSTREE_2019.6 2019.6 ostree_async_progress_finish@LIBOSTREE_2016.3 2016.4 ostree_async_progress_get@LIBOSTREE_2017.6 2017.6 @@ -163,9 +167,12 @@ libostree-1.so.1 libostree-1-1 #MINVER# ostree_kernel_args_append@LIBOSTREE_2019.3 2019.3 ostree_kernel_args_append_argv@LIBOSTREE_2019.3 2019.3 ostree_kernel_args_append_argv_filtered@LIBOSTREE_2019.3 2019.3 + ostree_kernel_args_append_if_missing@LIBOSTREE_2022.5 2022.5 ostree_kernel_args_append_proc_cmdline@LIBOSTREE_2019.3 2019.3 ostree_kernel_args_cleanup@LIBOSTREE_2019.3 2019.3 + ostree_kernel_args_contains@LIBOSTREE_2022.7 2022.7 ostree_kernel_args_delete@LIBOSTREE_2019.3 2019.3 + ostree_kernel_args_delete_if_present@LIBOSTREE_2022.7 2022.7 ostree_kernel_args_delete_key_entry@LIBOSTREE_2019.3 2019.3 ostree_kernel_args_free@LIBOSTREE_2019.3 2019.3 ostree_kernel_args_from_string@LIBOSTREE_2019.3 2019.3 @@ -222,6 +229,7 @@ libostree-1.so.1 libostree-1-1 #MINVER# ostree_repo_checkout_gc@LIBOSTREE_2016.3 2016.4 ostree_repo_checkout_tree@LIBOSTREE_2016.3 2016.4 ostree_repo_checkout_tree_at@LIBOSTREE_2016.3 2016.4 + ostree_repo_commit_add_composefs_metadata@LIBOSTREE_2023.4 2023.5 ostree_repo_commit_modifier_get_type@LIBOSTREE_2016.3 2016.4 ostree_repo_commit_modifier_new@LIBOSTREE_2016.3 2016.4 ostree_repo_commit_modifier_ref@LIBOSTREE_2016.3 2016.4 @@ -344,6 +352,7 @@ libostree-1.so.1 libostree-1-1 #MINVER# ostree_repo_query_object_storage_size@LIBOSTREE_2016.3 2016.4 ostree_repo_read_commit@LIBOSTREE_2016.3 2016.4 ostree_repo_read_commit_detached_metadata@LIBOSTREE_2016.3 2016.4 + ostree_repo_regenerate_metadata@LIBOSTREE_2023.1 2023.1 ostree_repo_regenerate_summary@LIBOSTREE_2016.3 2016.4 ostree_repo_reload_config@LIBOSTREE_2017.2 2017.2 ostree_repo_remote_add@LIBOSTREE_2016.3 2016.4 @@ -447,6 +456,7 @@ libostree-1.so.1 libostree-1-1 #MINVER# ostree_sysroot_deploy_tree@LIBOSTREE_2016.3 2016.4 ostree_sysroot_deploy_tree_with_options@LIBOSTREE_2020.7 2020.7 ostree_sysroot_deployment_set_kargs@LIBOSTREE_2016.3 2016.4 + ostree_sysroot_deployment_set_kargs_in_place@LIBOSTREE_2022.5 2022.5 ostree_sysroot_deployment_set_mutable@LIBOSTREE_2016.3 2016.4 ostree_sysroot_deployment_set_pinned@LIBOSTREE_2018.3 2018.3 ostree_sysroot_deployment_unlock@LIBOSTREE_2016.4 2016.4 @@ -466,6 +476,7 @@ libostree-1.so.1 libostree-1-1 #MINVER# ostree_sysroot_get_type@LIBOSTREE_2016.3 2016.4 ostree_sysroot_init_osname@LIBOSTREE_2016.4 2016.4 ostree_sysroot_initialize@LIBOSTREE_2020.1 2020.1 + ostree_sysroot_initialize_with_mount_namespace@LIBOSTREE_2022.7 2022.7 ostree_sysroot_is_booted@LIBOSTREE_2020.1 2020.1 ostree_sysroot_load@LIBOSTREE_2016.3 2016.4 ostree_sysroot_load_if_changed@LIBOSTREE_2016.4 2016.4 diff --git a/debian/libostree-doc.lintian-overrides b/debian/libostree-doc.lintian-overrides deleted file mode 100644 index 0e0a046..0000000 --- a/debian/libostree-doc.lintian-overrides +++ /dev/null @@ -1,2 +0,0 @@ -# https://bugs.debian.org/970275 -libostree-doc: package-contains-documentation-outside-usr-share-doc usr/share/gtk-doc/html/ostree/* diff --git a/debian/ostree-boot.install b/debian/ostree-boot.install index 3367d17..3dcc5ba 100644 --- a/debian/ostree-boot.install +++ b/debian/ostree-boot.install @@ -1,14 +1,14 @@ etc/dracut.conf.d/ostree.conf etc/grub.d/15_ostree -lib/systemd/system-generators/ostree-system-generator -lib/systemd/system/ostree-boot-complete.service -lib/systemd/system/ostree-finalize-staged.path -lib/systemd/system/ostree-finalize-staged.service -lib/systemd/system/ostree-prepare-root.service -lib/systemd/system/ostree-remount.service usr/lib/dracut/modules.d/98ostree usr/lib/ostree/ostree-prepare-root usr/lib/ostree/ostree-remount +usr/lib/systemd/system-generators/ostree-system-generator +usr/lib/systemd/system/ostree-boot-complete.service +usr/lib/systemd/system/ostree-finalize-staged-hold.service +usr/lib/systemd/system/ostree-finalize-staged.path +usr/lib/systemd/system/ostree-finalize-staged.service +usr/lib/systemd/system/ostree-prepare-root.service +usr/lib/systemd/system/ostree-remount.service usr/lib/tmpfiles.d/ostree-tmpfiles.conf usr/libexec/libostree/grub2-15_ostree -usr/libexec/libostree/s390x-se-luks-gencpio diff --git a/debian/ostree-boot.lintian-overrides b/debian/ostree-boot.lintian-overrides index b599c96..f3bbc9f 100644 --- a/debian/ostree-boot.lintian-overrides +++ b/debian/ostree-boot.lintian-overrides @@ -1,2 +1,6 @@ +# specific boot ordering requirements unlikely to be satisfiable in sysv-rc +ostree-boot: package-supports-alternative-init-but-no-init.d-script * +# statically Wanted by another unit +ostree-boot: systemd-service-file-missing-install-key [*/systemd/system/ostree-finalize-staged-hold.service] # ostree-remount genuinely does need to be run that early ostree-boot: systemd-service-file-refers-to-unusual-wantedby-target local-fs.target [*/systemd/system/ostree-remount.service] diff --git a/debian/ostree-tests.install b/debian/ostree-tests.install index 5ccecb3..f6ec82d 100644 --- a/debian/ostree-tests.install +++ b/debian/ostree-tests.install @@ -1,3 +1,2 @@ usr/libexec/installed-tests/libostree -usr/libexec/libostree/ostree-trivial-httpd usr/share/installed-tests/libostree diff --git a/debian/ostree-tests.lintian-overrides b/debian/ostree-tests.lintian-overrides index 94bb2c3..9d04f32 100644 --- a/debian/ostree-tests.lintian-overrides +++ b/debian/ostree-tests.lintian-overrides @@ -1,17 +1,13 @@ # This is deliberate: it's just some random signed file to be verified, and # upstream happens to have used the text of the LGPL as the signed file -ostree-tests: extra-license-file usr/libexec/installed-tests/libostree/gpg-verify-data/lgpl2 -ostree-tests: extra-license-file usr/libexec/installed-tests/libostree/gpg-verify-data/lgpl2.sig* +ostree-tests: extra-license-file [usr/libexec/installed-tests/libostree/gpg-verify-data/lgpl2] +ostree-tests: extra-license-file [usr/libexec/installed-tests/libostree/gpg-verify-data/lgpl2.sig*] # This is deliberate, working around the assumption of recursive make -ostree-tests: symlink-is-self-recursive usr/libexec/installed-tests/libostree/tests . +ostree-tests: symlink-is-self-recursive . [usr/libexec/installed-tests/libostree/tests] # gjs has been broken on sparc64 for a while, and is missing on the # other architectures mentioned here. # The test that runs this script is automatically skipped if gjs isn't # present. -[alpha hppa ia64 m68k s390x sh4 sparc64 x32]: missing-dep-for-interpreter gjs => gjs (usr/libexec/installed-tests/libostree/corrupt-repo-ref.js) - -# This shared object genuinely doesn't use any libc ABIs directly, -# only via GLib -library-not-linked-against-libc usr/libexec/installed-tests/libostree/libreaddir-rand.so +[alpha hppa ia64 m68k sh4 sparc64 x32]: missing-dep-for-interpreter gjs => gjs (usr/libexec/installed-tests/libostree/corrupt-repo-ref.js) diff --git a/debian/ostree.maintscript b/debian/ostree.maintscript deleted file mode 100644 index 5b1850b..0000000 --- a/debian/ostree.maintscript +++ /dev/null @@ -1,2 +0,0 @@ -rm_conffile /etc/dracut.conf.d/ostree.conf 2017.3-2~ ostree -rm_conffile /etc/grub.d/15_ostree 2017.3-2~ ostree diff --git a/debian/patches/add-sunway-support.patch b/debian/patches/add-sunway-support.patch deleted file mode 100644 index b9e353c..0000000 --- a/debian/patches/add-sunway-support.patch +++ /dev/null @@ -1,19 +0,0 @@ -Description: add sunway support -Author: Miao Changwei - ---- -Last-Update: 2022-05-23 - ---- ostree-2021.5.orig/libglnx/glnx-missing.h -+++ ostree-2021.5/libglnx/glnx-missing.h -@@ -46,8 +46,8 @@ - */ - - #ifndef __O_TMPFILE --#if defined(__alpha__) --#define __O_TMPFILE 0100000000 -+#if defined(__alpha__) || defined(__sw_64__) -+#define __O_TMPFILE 0100100000 - #elif defined(__parisc__) || defined(__hppa__) - #define __O_TMPFILE 0400000000 - #elif defined(__sparc__) || defined(__sparc64__) diff --git a/debian/patches/bootloader-zipl-No-op-if-run-as-non-root.patch b/debian/patches/bootloader-zipl-No-op-if-run-as-non-root.patch new file mode 100644 index 0000000..d2dd935 --- /dev/null +++ b/debian/patches/bootloader-zipl-No-op-if-run-as-non-root.patch @@ -0,0 +1,29 @@ +From: Colin Walters +Date: Tue, 24 Oct 2023 10:40:51 -0400 +Subject: bootloader/zipl: No-op if run as non-root + +Not the most elegant fix but should get the job done. + +Bug: https://github.com/ostreedev/ostree/issues/3084 +Origin: upstream, 2023.8, commit:75c7e51a8bedb5edeadb9f54e84ccfff2adcc755 +--- + src/libostree/ostree-bootloader-zipl.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c +index c0a2a14..4579a89 100644 +--- a/src/libostree/ostree-bootloader-zipl.c ++++ b/src/libostree/ostree-bootloader-zipl.c +@@ -381,6 +381,12 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, int bootver + { + OstreeBootloaderZipl *self = OSTREE_BOOTLOADER_ZIPL (bootloader); + ++ // This can happen in a unit testing environment; at some point what we want to do here ++ // is move all of the zipl logic to a systemd unit instead that's keyed of ++ // ostree-finalize-staged.service. ++ if (getuid () != 0) ++ return TRUE; ++ + /* Note that unlike the grub2-mkconfig backend, we make no attempt to + * chroot(). + */ diff --git a/debian/patches/debian/Skip-test-admin-deploy-uboot.sh-on-s390x.patch b/debian/patches/debian/Skip-test-admin-deploy-uboot.sh-on-s390x.patch new file mode 100644 index 0000000..f147aa5 --- /dev/null +++ b/debian/patches/debian/Skip-test-admin-deploy-uboot.sh-on-s390x.patch @@ -0,0 +1,29 @@ +From: Simon McVittie +Date: Thu, 26 Oct 2023 11:26:04 +0100 +Subject: Skip test-admin-deploy-uboot.sh on s390x + +It fails on a porterbox. ostree hard-codes zipl to be used on s390x, +so it's reasonable that tests for other bootloaders might not work. + +Bug: https://github.com/ostreedev/ostree/issues/3086 +Forwarded: no +--- + tests/test-admin-deploy-uboot.sh | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/test-admin-deploy-uboot.sh b/tests/test-admin-deploy-uboot.sh +index 9a4d773..772e51d 100755 +--- a/tests/test-admin-deploy-uboot.sh ++++ b/tests/test-admin-deploy-uboot.sh +@@ -20,6 +20,11 @@ + + set -euo pipefail + ++if [ "${DEB_HOST_ARCH-$(dpkg --print-architecture)}" = s390x ]; then ++ echo "1..0 # SKIP uBoot not supported on s390x" ++ exit 0 ++fi ++ + . $(dirname $0)/libtest.sh + + # Exports OSTREE_SYSROOT so --sysroot not needed. diff --git a/debian/patches/debian/Skip-test-pull-repeated-during-CI.patch b/debian/patches/debian/Skip-test-pull-repeated-during-CI.patch index fd2b3e7..82a65aa 100644 --- a/debian/patches/debian/Skip-test-pull-repeated-during-CI.patch +++ b/debian/patches/debian/Skip-test-pull-repeated-during-CI.patch @@ -18,7 +18,7 @@ Signed-off-by: Simon McVittie 1 file changed, 4 insertions(+) diff --git a/tests/test-pull-repeated.sh b/tests/test-pull-repeated.sh -index 4c32161..3b7d10b 100755 +index 7f724c9..d10799b 100755 --- a/tests/test-pull-repeated.sh +++ b/tests/test-pull-repeated.sh @@ -21,6 +21,10 @@ set -euo pipefail diff --git a/debian/patches/debian/test-sysroot-Skip-on-s390x-by-default.patch b/debian/patches/debian/test-sysroot-Skip-on-s390x-by-default.patch new file mode 100644 index 0000000..6dcef39 --- /dev/null +++ b/debian/patches/debian/test-sysroot-Skip-on-s390x-by-default.patch @@ -0,0 +1,30 @@ +From: Simon McVittie +Date: Tue, 6 Dec 2022 10:59:33 +0000 +Subject: test-sysroot: Skip on s390x by default + +This test regularly fails on the buildds, but I cannot reproduce the +failure on a porterbox. + +Bug: https://github.com/ostreedev/ostree/issues/2527 +Bug-Debian: https://bugs.debian.org/1025532 +Forwarded: not-needed +--- + tests/test-sysroot.js | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/test-sysroot.js b/tests/test-sysroot.js +index d4f67ef..0855b3d 100755 +--- a/tests/test-sysroot.js ++++ b/tests/test-sysroot.js +@@ -38,6 +38,11 @@ function libtestExec(shellCode) { + proc.wait_check(null); + } + ++if (GLib.getenv('DEB_HOST_ARCH') === 's390x' && !GLib.getenv('DEB_ALLOW_FLAKY_TESTS')) { ++ print('1..0 # SKIP https://bugs.debian.org/1025532'); ++ imports.system.exit(0); ++} ++ + print('1..1') + + libtestExec('setup_os_repository archive syslinux'); diff --git a/debian/patches/lib-Fix-symbol-versioning-inheritance.patch b/debian/patches/lib-Fix-symbol-versioning-inheritance.patch deleted file mode 100644 index b0b4889..0000000 --- a/debian/patches/lib-Fix-symbol-versioning-inheritance.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Colin Walters -Date: Wed, 8 Jun 2022 16:27:30 -0400 -Subject: [PATCH] lib: Fix symbol versioning inheritance - -I messed this up; the last release should inherit from the previous -release (N-1) and not the previous to that (N-2). - -I think (hope) this isn't an ABI break... - -Just noticed this when I was going to add a new symbol. - -Applied-upstream: 2022.4, commit:145d91d1c96755bc61a468b5da1061547909121e ---- - src/libostree/libostree-released.sym | 2 +- - tests/test-symbols.sh | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/libostree/libostree-released.sym b/src/libostree/libostree-released.sym -index 8b8a722d8..5afdfd3e2 100644 ---- a/src/libostree/libostree-released.sym -+++ b/src/libostree/libostree-released.sym -@@ -681,7 +681,7 @@ LIBOSTREE_2022.4 { - global: - ostree_fs_get_all_xattrs; - ostree_fs_get_all_xattrs_at; --} LIBOSTREE_2021.5; -+} LIBOSTREE_2022.2; - - /* NOTE: Only add more content here in release commits! See the - * comments at the top of this file. -diff --git a/tests/test-symbols.sh b/tests/test-symbols.sh -index a888ef358..a14849d56 100755 ---- a/tests/test-symbols.sh -+++ b/tests/test-symbols.sh -@@ -54,7 +54,7 @@ echo 'ok documented symbols' - - # ONLY update this checksum in release commits! - cat > released-sha256.txt < -Date: Fri, 17 Jun 2022 14:15:35 +0100 -Subject: test-basic-c: Don't assert that extended attributes are available - -Not all filesystems support extended attributes. This test uses -/var/tmp to try to get an extended-attributes-capable filesystem, -but that might not succeed. - -Signed-off-by: Simon McVittie -Forwarded: https://github.com/ostreedev/ostree/pull/2652 ---- - tests/test-basic-c.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/tests/test-basic-c.c b/tests/test-basic-c.c -index 1886feb..fc99529 100644 ---- a/tests/test-basic-c.c -+++ b/tests/test-basic-c.c -@@ -514,8 +514,15 @@ test_read_xattrs (void) - g_assert_no_error (local_error); - - int r = fsetxattr (tmpd.fd, "user.ostreetesting", value, sizeof (value), 0); -- g_assert_cmpint (r, ==, 0); -- -+ -+ if (r != 0) -+ { -+ g_autofree gchar *message = g_strdup_printf ("Unable to set extended attributes in /var/tmp: %s", -+ g_strerror (errno)); -+ g_test_skip (message); -+ return; -+ } -+ - g_autoptr(GVariant) new_xattrs = ostree_fs_get_all_xattrs (tmpd.fd, NULL, error); - g_assert_no_error (local_error); - diff --git a/debian/rules b/debian/rules index 6d6abf4..1b79603 100755 --- a/debian/rules +++ b/debian/rules @@ -13,6 +13,7 @@ override_dh_autoreconf: configure_options = \ --enable-installed-tests \ --with-avahi \ + --with-curl \ --with-dracut \ --with-grub2 \ --with-grub2-mkconfig-path=/usr/sbin/grub-mkconfig \ @@ -20,14 +21,15 @@ configure_options = \ --with-libsystemd \ --with-libmount \ --with-modern-grub \ - --with-soup \ + --with-soup3 \ --with-selinux \ - --with-systemdsystemgeneratordir=/lib/systemd/system-generators \ - --with-systemdsystemunitdir=/lib/systemd/system \ + --with-systemdsystemgeneratordir=/usr/lib/systemd/system-generators \ + --with-systemdsystemunitdir=/usr/lib/systemd/system \ + --without-composefs \ --without-smack \ $(NULL) -ifneq ($(filter alpha hppa ia64 m68k s390x sh4 sparc64 x32,$(DEB_HOST_ARCH)),) +ifneq ($(filter alpha hppa ia64 m68k sh4 sparc64 x32,$(DEB_HOST_ARCH)),) configure_options += ac_cv_path_GJS= endif @@ -72,16 +74,11 @@ override_dh_install: : dh_install -override_dh_makeshlibs: - # this is an LD_PRELOAD, not a real shared library - dh_makeshlibs -Xinstalled-tests/ostree/libreaddir-rand.so - override_dh_fixperms: dh_fixperms -Xusr/libexec/installed-tests ifneq ($(filter %-tests,$(binaries)),) # debhelper >= 13.4 makes all of /usr/libexec executable, which is not # quite right for installed-tests - chmod --changes u=rw,og=r debian/*-tests/usr/libexec/installed-tests/*/*.so chmod --recursive --changes a+rX,u+w,og-w debian/*-tests/usr/libexec/installed-tests endif diff --git a/debian/tests/build b/debian/tests/build index 1a40303..f34c7c7 100755 --- a/debian/tests/build +++ b/debian/tests/build @@ -22,9 +22,9 @@ int main (void) } EOF -# Deliberately word-splitting, that's how pkg-config works: +# Deliberately word-splitting, that's how pkgconf works: # shellcheck disable=SC2046 -"${CROSS_COMPILE}gcc" -o trivial trivial.c $("${CROSS_COMPILE}pkg-config" --cflags --libs ostree-1 gobject-2.0) +"${CROSS_COMPILE}gcc" -o trivial trivial.c $("${CROSS_COMPILE}pkgconf" --cflags --libs ostree-1 gobject-2.0) test -x trivial ./trivial echo "OK" diff --git a/debian/tests/control b/debian/tests/control index 28691e7..b428613 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -1,4 +1,9 @@ -Tests: flaky +Tests: flaky-concurrency +Restrictions: flaky +Depends: gnome-desktop-testing, ostree-tests + +Tests: flaky-sysroot +Architecture: s390x Restrictions: flaky Depends: gnome-desktop-testing, ostree-tests @@ -7,4 +12,4 @@ Depends: gnome-desktop-testing, ostree-tests Tests: build Restrictions: superficial -Depends: build-essential, libostree-dev, pkg-config +Depends: build-essential, libostree-dev, pkgconf diff --git a/debian/tests/flaky b/debian/tests/flaky-concurrency old mode 100644 new mode 100755 similarity index 100% rename from debian/tests/flaky rename to debian/tests/flaky-concurrency diff --git a/debian/tests/flaky-sysroot b/debian/tests/flaky-sysroot new file mode 100644 index 0000000..8865f9e --- /dev/null +++ b/debian/tests/flaky-sysroot @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e +exec 2>&1 + +unset ftp_proxy +unset http_proxy +unset https_proxy +unset no_proxy +export DEB_ALLOW_FLAKY_TESTS=1 + +exec gnome-desktop-testing-runner libostree/test-sysroot.js.test diff --git a/debian/tests/gnome-desktop-testing b/debian/tests/gnome-desktop-testing index e4346ca..b041ae0 100755 --- a/debian/tests/gnome-desktop-testing +++ b/debian/tests/gnome-desktop-testing @@ -11,7 +11,9 @@ unset http_proxy unset https_proxy unset no_proxy -tests="$(gnome-desktop-testing-runner -l libostree | while read -r t; do +namespace=libostree/ + +tests="$(gnome-desktop-testing-runner -l "$namespace" | while read -r t; do t="${t%% *}" case "$t" in @@ -20,11 +22,24 @@ tests="$(gnome-desktop-testing-runner -l libostree | while read -r t; do # https://github.com/ostreedev/ostree/issues/1620 continue ;; + + (libostree/test-sysroot.js.test) + # https://bugs.debian.org/1025532 + # https://github.com/ostreedev/ostree/issues/2527 + if [ "${DEB_HOST_ARCH-}" = s390x ] || [ "$(uname -m)" = s390x ]; then + continue + fi + ;; esac echo "$t" done)" +if [ -z "$tests" ]; then + echo "Error: no installed-tests found matching $namespace" >&2 + exit 1 +fi + # Deliberately word-splitting # shellcheck disable=SC2046 exec gnome-desktop-testing-runner $tests diff --git a/debian/watch b/debian/watch index 048ca2a..9bc35d3 100644 --- a/debian/watch +++ b/debian/watch @@ -1,2 +1,9 @@ version=4 -https://github.com/ostreedev/ostree/releases .*/libostree-(\d\S*)\.tar\.xz +# Upstream releases official Autotools 'make dist' tarballs, so we use +# those in preference to git tags +opts="\ + compression=xz, \ + dversionmangle=s/\+(?:git)?[0-9]*(?:\+g[0-9a-f]*)//, \ + downloadurlmangle=s#/tag/#/download/#;s#(v?@ANY_VERSION@)$#$1/libostree-$2.tar.xz#, \ + filenamemangle=s#v?@ANY_VERSION@#@PACKAGE@-$1.tar.xz#" \ +https://github.com/ostreedev/@PACKAGE@/tags .*/releases/tag/v?@ANY_VERSION@ diff --git a/libglnx/Makefile-libglnx.am b/libglnx/Makefile-libglnx.am index bea7b13..5934a2b 100644 --- a/libglnx/Makefile-libglnx.am +++ b/libglnx/Makefile-libglnx.am @@ -33,6 +33,8 @@ libglnx_la_SOURCES = \ $(libglnx_srcpath)/glnx-macros.h \ $(libglnx_srcpath)/glnx-backport-autocleanups.h \ $(libglnx_srcpath)/glnx-backport-autoptr.h \ + $(libglnx_srcpath)/glnx-backport-testutils.h \ + $(libglnx_srcpath)/glnx-backport-testutils.c \ $(libglnx_srcpath)/glnx-backports.h \ $(libglnx_srcpath)/glnx-backports.c \ $(libglnx_srcpath)/glnx-local-alloc.h \ diff --git a/libglnx/Makefile-libglnx.am.inc b/libglnx/Makefile-libglnx.am.inc index f08724c..c8a8c15 100644 --- a/libglnx/Makefile-libglnx.am.inc +++ b/libglnx/Makefile-libglnx.am.inc @@ -33,6 +33,8 @@ libglnx_la_SOURCES = \ libglnx/glnx-macros.h \ libglnx/glnx-backport-autocleanups.h \ libglnx/glnx-backport-autoptr.h \ + libglnx/glnx-backport-testutils.h \ + libglnx/glnx-backport-testutils.c \ libglnx/glnx-backports.h \ libglnx/glnx-backports.c \ libglnx/glnx-local-alloc.h \ diff --git a/libglnx/glnx-backport-testutils.c b/libglnx/glnx-backport-testutils.c new file mode 100644 index 0000000..3440872 --- /dev/null +++ b/libglnx/glnx-backport-testutils.c @@ -0,0 +1,162 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright 2015 Colin Walters + * Copyright 2020 Niels De Graef + * Copyright 2021-2022 Collabora Ltd. + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the licence or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "libglnx-config.h" + +#include +#include + +#include + +#include "glnx-backport-autocleanups.h" +#include "glnx-backport-autoptr.h" +#include "glnx-backport-testutils.h" +#include "glnx-backports.h" + +#include +#include + +#if !GLIB_CHECK_VERSION (2, 68, 0) +/* Backport of g_assertion_message_cmpstrv() */ +void +_glnx_assertion_message_cmpstrv (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + const char * const *arg1, + const char * const *arg2, + gsize first_wrong_idx) +{ + const char *s1 = arg1[first_wrong_idx], *s2 = arg2[first_wrong_idx]; + char *a1, *a2, *s, *t1 = NULL, *t2 = NULL; + + a1 = g_strconcat ("\"", t1 = g_strescape (s1, NULL), "\"", NULL); + a2 = g_strconcat ("\"", t2 = g_strescape (s2, NULL), "\"", NULL); + g_free (t1); + g_free (t2); + s = g_strdup_printf ("assertion failed (%s): first differing element at index %" G_GSIZE_FORMAT ": %s does not equal %s", + expr, first_wrong_idx, a1, a2); + g_free (a1); + g_free (a2); + g_assertion_message (domain, file, line, func, s); + g_free (s); +} +#endif + +#if !GLIB_CHECK_VERSION(2, 70, 0) +/* + * Same as g_test_message(), but split messages with newlines into + * multiple separate messages to avoid corrupting stdout, even in older + * GLib versions that didn't do this + */ +void +_glnx_test_message_safe (const char *format, + ...) +{ + g_autofree char *message = NULL; + va_list ap; + char *line; + char *saveptr = NULL; + + va_start (ap, format); + g_vasprintf (&message, format, ap); + va_end (ap); + + for (line = strtok_r (message, "\n", &saveptr); + line != NULL; + line = strtok_r (NULL, "\n", &saveptr)) + (g_test_message) ("%s", line); +} + +/* Backport of g_test_fail_printf() */ +void +_glnx_test_fail_printf (const char *format, + ...) +{ + g_autofree char *message = NULL; + va_list ap; + + va_start (ap, format); + g_vasprintf (&message, format, ap); + va_end (ap); + + /* This is the closest we can do in older GLib */ + g_test_message ("Bail out! %s", message); + g_test_fail (); +} + +/* Backport of g_test_skip_printf() */ +void +_glnx_test_skip_printf (const char *format, + ...) +{ + g_autofree char *message = NULL; + va_list ap; + + va_start (ap, format); + g_vasprintf (&message, format, ap); + va_end (ap); + + g_test_skip (message); +} + +/* Backport of g_test_incomplete_printf() */ +void +_glnx_test_incomplete_printf (const char *format, + ...) +{ + g_autofree char *message = NULL; + va_list ap; + + va_start (ap, format); + g_vasprintf (&message, format, ap); + va_end (ap); + +#if GLIB_CHECK_VERSION(2, 58, 0) + /* Since 2.58, g_test_incomplete() sets the exit status correctly. */ + g_test_incomplete (message); +#elif GLIB_CHECK_VERSION (2, 38, 0) + /* Before 2.58, g_test_incomplete() was treated like a failure for the + * purposes of setting the exit status, so prefer to use (our wrapper + * around) g_test_skip(). */ + g_test_skip_printf ("TODO: %s", message); +#else + g_test_message ("TODO: %s", message); +#endif +} +#endif + +#if !GLIB_CHECK_VERSION (2, 78, 0) +void +_glnx_test_disable_crash_reporting (void) +{ + struct rlimit limit = { 0, 0 }; + + (void) setrlimit (RLIMIT_CORE, &limit); + + /* On Linux, RLIMIT_CORE = 0 is ignored if core dumps are + * configured to be written to a pipe, but PR_SET_DUMPABLE is not. */ + (void) prctl (PR_SET_DUMPABLE, 0, 0, 0, 0); +} +#endif diff --git a/libglnx/glnx-backport-testutils.h b/libglnx/glnx-backport-testutils.h new file mode 100644 index 0000000..f579c0e --- /dev/null +++ b/libglnx/glnx-backport-testutils.h @@ -0,0 +1,209 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * Copyright 2015 Colin Walters + * Copyright 2014 Dan Winship + * Copyright 2015 Colin Walters + * Copyright 2017 Emmanuele Bassi + * Copyright 2018-2019 Endless OS Foundation LLC + * Copyright 2020 Niels De Graef + * Copyright 2021-2022 Collabora Ltd. + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#pragma once + +#include + +#include "glnx-backports.h" + +G_BEGIN_DECLS + +#ifndef g_assert_true /* added in 2.38 */ +#define g_assert_true(x) g_assert ((x)) +#endif + +#ifndef g_assert_false /* added in 2.38 */ +#define g_assert_false(x) g_assert (!(x)) +#endif + +#ifndef g_assert_nonnull /* added in 2.40 */ +#define g_assert_nonnull(x) g_assert (x != NULL) +#endif + +#ifndef g_assert_null /* added in 2.40 */ +#define g_assert_null(x) g_assert (x == NULL) +#endif + +#if !GLIB_CHECK_VERSION (2, 38, 0) +/* Not exactly equivalent, but close enough */ +#define g_test_skip(s) g_test_message ("SKIP: %s", s) +#endif + +#if !GLIB_CHECK_VERSION (2, 58, 0) +/* Before 2.58, g_test_incomplete() didn't set the exit status correctly */ +#define g_test_incomplete(s) _glnx_test_incomplete_printf ("%s", s) +#endif + +#if !GLIB_CHECK_VERSION (2, 46, 0) +#define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\ + gconstpointer __m1 = m1, __m2 = m2; \ + int __l1 = l1, __l2 = l2; \ + if (__l1 != 0 && __m1 == NULL) \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "assertion failed (" #l1 " == 0 || " #m1 " != NULL)"); \ + else if (__l2 != 0 && __m2 == NULL) \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "assertion failed (" #l2 " == 0 || " #m2 " != NULL)"); \ + else if (__l1 != __l2) \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", \ + (long double) __l1, "==", (long double) __l2, 'i'); \ + else if (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "assertion failed (" #m1 " == " #m2 ")"); \ + } G_STMT_END +#endif + +#if !GLIB_CHECK_VERSION (2, 58, 0) +#define g_assert_cmpfloat_with_epsilon(n1,n2,epsilon) \ + G_STMT_START { \ + double __n1 = (n1), __n2 = (n2), __epsilon = (epsilon); \ + if (G_APPROX_VALUE (__n1, __n2, __epsilon)) ; else \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " == " #n2 " (+/- " #epsilon ")", __n1, "==", __n2, 'f'); \ + } G_STMT_END +#endif + +#if !GLIB_CHECK_VERSION (2, 60, 0) +#define g_assert_cmpvariant(v1, v2) \ + G_STMT_START \ + { \ + GVariant *__v1 = (v1), *__v2 = (v2); \ + if (!g_variant_equal (__v1, __v2)) \ + { \ + gchar *__s1, *__s2, *__msg; \ + __s1 = g_variant_print (__v1, TRUE); \ + __s2 = g_variant_print (__v2, TRUE); \ + __msg = g_strdup_printf ("assertion failed (" #v1 " == " #v2 "): %s does not equal %s", __s1, __s2); \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \ + g_free (__s1); \ + g_free (__s2); \ + g_free (__msg); \ + } \ + } \ + G_STMT_END +#endif + +#if !GLIB_CHECK_VERSION (2, 62, 0) +/* Not exactly equivalent, but close enough */ +#define g_test_summary(s) g_test_message ("SUMMARY: %s", s) +#endif + +#if !GLIB_CHECK_VERSION (2, 66, 0) +#define g_assert_no_errno(expr) G_STMT_START { \ + int __ret, __errsv; \ + errno = 0; \ + __ret = expr; \ + __errsv = errno; \ + if (__ret < 0) \ + { \ + gchar *__msg; \ + __msg = g_strdup_printf ("assertion failed (" #expr " >= 0): errno %i: %s", __errsv, g_strerror (__errsv)); \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \ + g_free (__msg); \ + } \ + } G_STMT_END +#endif + +#if !GLIB_CHECK_VERSION (2, 68, 0) +#define g_assertion_message_cmpstrv _glnx_assertion_message_cmpstrv +void _glnx_assertion_message_cmpstrv (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + const char * const *arg1, + const char * const *arg2, + gsize first_wrong_idx); +#define g_assert_cmpstrv(strv1, strv2) \ + G_STMT_START \ + { \ + const char * const *__strv1 = (const char * const *) (strv1); \ + const char * const *__strv2 = (const char * const *) (strv2); \ + if (!__strv1 || !__strv2) \ + { \ + if (__strv1) \ + { \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "assertion failed (" #strv1 " == " #strv2 "): " #strv2 " is NULL, but " #strv1 " is not"); \ + } \ + else if (__strv2) \ + { \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "assertion failed (" #strv1 " == " #strv2 "): " #strv1 " is NULL, but " #strv2 " is not"); \ + } \ + } \ + else \ + { \ + guint __l1 = g_strv_length ((char **) __strv1); \ + guint __l2 = g_strv_length ((char **) __strv2); \ + if (__l1 != __l2) \ + { \ + char *__msg; \ + __msg = g_strdup_printf ("assertion failed (" #strv1 " == " #strv2 "): length %u does not equal length %u", __l1, __l2); \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \ + g_free (__msg); \ + } \ + else \ + { \ + guint __i; \ + for (__i = 0; __i < __l1; __i++) \ + { \ + if (g_strcmp0 (__strv1[__i], __strv2[__i]) != 0) \ + { \ + g_assertion_message_cmpstrv (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #strv1 " == " #strv2, \ + __strv1, __strv2, __i); \ + } \ + } \ + } \ + } \ + } \ + G_STMT_END +#endif + +#if !GLIB_CHECK_VERSION (2, 70, 0) +/* Before 2.70, diagnostic messages containing newlines were problematic */ +#define g_test_message(...) _glnx_test_message_safe (__VA_ARGS__) +void _glnx_test_message_safe (const char *format, ...) G_GNUC_PRINTF (1, 2); + +#define g_test_fail_printf _glnx_test_fail_printf +void _glnx_test_fail_printf (const char *format, ...) G_GNUC_PRINTF (1, 2); +#define g_test_skip_printf _glnx_test_skip_printf +void _glnx_test_skip_printf (const char *format, ...) G_GNUC_PRINTF (1, 2); +#define g_test_incomplete_printf _glnx_test_incomplete_printf +void _glnx_test_incomplete_printf (const char *format, ...) G_GNUC_PRINTF (1, 2); +#endif + +#if !GLIB_CHECK_VERSION (2, 78, 0) +#define g_test_disable_crash_reporting _glnx_test_disable_crash_reporting +void _glnx_test_disable_crash_reporting (void); +#endif + +G_END_DECLS diff --git a/libglnx/glnx-backports.c b/libglnx/glnx-backports.c index f9aa7ce..391c154 100644 --- a/libglnx/glnx-backports.c +++ b/libglnx/glnx-backports.c @@ -1,6 +1,7 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Copyright (C) 2015 Colin Walters + * Copyright (C) 2018 Endless OS Foundation, LLC * SPDX-License-Identifier: LGPL-2.0-or-later * * This program is free software: you can redistribute it and/or modify @@ -60,3 +61,24 @@ glnx_set_object (GObject **object_ptr, return TRUE; } #endif + +#if !GLIB_CHECK_VERSION(2, 60, 0) +gboolean +_glnx_strv_equal (const gchar * const *strv1, + const gchar * const *strv2) +{ + g_return_val_if_fail (strv1 != NULL, FALSE); + g_return_val_if_fail (strv2 != NULL, FALSE); + + if (strv1 == strv2) + return TRUE; + + for (; *strv1 != NULL && *strv2 != NULL; strv1++, strv2++) + { + if (!g_str_equal (*strv1, *strv2)) + return FALSE; + } + + return (*strv1 == NULL && *strv2 == NULL); +} +#endif diff --git a/libglnx/glnx-backports.h b/libglnx/glnx-backports.h index 0c5fabe..121e073 100644 --- a/libglnx/glnx-backports.h +++ b/libglnx/glnx-backports.h @@ -1,7 +1,11 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * + * Copyright 1998 Manish Singh + * Copyright 1998 Tim Janik * Copyright (C) 2015 Colin Walters - * SPDX-License-Identifier: LGPL-2.0-or-later + * Copyright (C) 2018 Endless OS Foundation, LLC + * Copyright 2017 Emmanuele Bassi + * SPDX-License-Identifier: LGPL-2.1-or-later * * GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald @@ -9,7 +13,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,13 +21,13 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ #pragma once +#include + #include G_BEGIN_DECLS @@ -48,6 +52,10 @@ G_BEGIN_DECLS } G_STMT_END #endif +#if !GLIB_CHECK_VERSION(2, 40, 0) +#define g_info(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__) +#endif + #if !GLIB_CHECK_VERSION(2, 44, 0) #define g_strv_contains glnx_strv_contains @@ -64,16 +72,81 @@ gboolean glnx_set_object (GObject **object_ptr, #endif /* !GLIB_CHECK_VERSION(2, 44, 0) */ -#ifndef g_assert_nonnull -#define g_assert_nonnull(x) g_assert (x != NULL) +#if !GLIB_CHECK_VERSION(2, 38, 0) +#define G_SPAWN_DEFAULT ((GSpawnFlags) 0) +#endif + +#if !GLIB_CHECK_VERSION(2, 42, 0) +#define G_OPTION_FLAG_NONE ((GOptionFlags) 0) +#endif + +#if !GLIB_CHECK_VERSION(2, 60, 0) +#define g_strv_equal _glnx_strv_equal +gboolean _glnx_strv_equal (const gchar * const *strv1, + const gchar * const *strv2); +#endif + +#ifndef G_DBUS_METHOD_INVOCATION_HANDLED /* added in 2.68 */ +#define G_DBUS_METHOD_INVOCATION_HANDLED TRUE +#endif + +#ifndef G_DBUS_METHOD_INVOCATION_UNHANDLED /* added in 2.68 */ +#define G_DBUS_METHOD_INVOCATION_UNHANDLED FALSE +#endif + +#if !GLIB_CHECK_VERSION(2, 68, 0) +static inline gpointer _glnx_memdup2 (gconstpointer mem, + gsize byte_size) G_GNUC_ALLOC_SIZE(2); +static inline gpointer +_glnx_memdup2 (gconstpointer mem, + gsize byte_size) +{ + gpointer new_mem; + + if (mem && byte_size != 0) + { + new_mem = g_malloc (byte_size); + memcpy (new_mem, mem, byte_size); + } + else + new_mem = NULL; + + return new_mem; +} +#define g_memdup2 _glnx_memdup2 +#endif + +#ifndef G_OPTION_ENTRY_NULL /* added in 2.70 */ +#define G_OPTION_ENTRY_NULL { NULL, 0, 0, 0, NULL, NULL, NULL } +#endif + +#ifndef G_APPROX_VALUE /* added in 2.58 */ +#define G_APPROX_VALUE(a, b, epsilon) \ + (((a) > (b) ? (a) - (b) : (b) - (a)) < (epsilon)) #endif -#ifndef g_assert_null -#define g_assert_null(x) g_assert (x == NULL) +#if !GLIB_CHECK_VERSION(2, 70, 0) +#define g_steal_fd _glnx_steal_fd +static inline int +_glnx_steal_fd (int *fdp) +{ + int fd = *fdp; + *fdp = -1; + return fd; +} #endif -#if !GLIB_CHECK_VERSION (2, 38, 0) -#define g_test_skip(s) g_test_message ("SKIP: %s", s) +#if !GLIB_CHECK_VERSION(2, 74, 0) +#define G_APPLICATION_DEFAULT_FLAGS ((GApplicationFlags) 0) +#define G_CONNECT_DEFAULT ((GConnectFlags) 0) +#define G_IO_FLAG_NONE ((GIOFlags) 0) +#define G_MARKUP_DEFAULT_FLAGS ((GMarkupParseFlags) 0) +#define G_REGEX_DEFAULT ((GRegexCompileFlags) 0) +#define G_REGEX_MATCH_DEFAULT ((GRegexMatchFlags) 0) +#define G_TEST_SUBPROCESS_DEFAULT ((GTestSubprocessFlags) 0) +#define G_TEST_TRAP_DEFAULT ((GTestTrapFlags) 0) +#define G_TLS_CERTIFICATE_NO_FLAGS ((GTlsCertificateFlags) 0) +#define G_TYPE_FLAG_NONE ((GTypeFlags) 0) #endif G_END_DECLS diff --git a/libglnx/glnx-dirfd.c b/libglnx/glnx-dirfd.c index b039c41..b78e2df 100644 --- a/libglnx/glnx-dirfd.c +++ b/libglnx/glnx-dirfd.c @@ -129,7 +129,7 @@ glnx_dirfd_iterator_init_take_fd (int *dfd, if (!d) return glnx_throw_errno_prefix (error, "fdopendir"); - real_dfd_iter->fd = glnx_steal_fd (dfd); + real_dfd_iter->fd = g_steal_fd (dfd); real_dfd_iter->d = d; real_dfd_iter->initialized = TRUE; @@ -349,7 +349,7 @@ glnx_mkdtempat (int dfd, const char *tmpl, int mode, /* Return the initialized directory struct */ out_tmpdir->initialized = TRUE; out_tmpdir->src_dfd = dfd; /* referenced; see above docs */ - out_tmpdir->fd = glnx_steal_fd (&ret_dfd); + out_tmpdir->fd = g_steal_fd (&ret_dfd); out_tmpdir->path = g_steal_pointer (&path); return TRUE; } diff --git a/libglnx/glnx-fdio.c b/libglnx/glnx-fdio.c index ee69aa1..9873205 100644 --- a/libglnx/glnx-fdio.c +++ b/libglnx/glnx-fdio.c @@ -218,7 +218,7 @@ open_tmpfile_core (int dfd, const char *subpath, return glnx_throw_errno_prefix (error, "fchmod"); out_tmpf->initialized = TRUE; out_tmpf->src_dfd = dfd; /* Copied; caller must keep open */ - out_tmpf->fd = glnx_steal_fd (&fd); + out_tmpf->fd = g_steal_fd (&fd); out_tmpf->path = NULL; return TRUE; } @@ -245,7 +245,7 @@ open_tmpfile_core (int dfd, const char *subpath, { out_tmpf->initialized = TRUE; out_tmpf->src_dfd = dfd; /* Copied; caller must keep open */ - out_tmpf->fd = glnx_steal_fd (&fd); + out_tmpf->fd = g_steal_fd (&fd); out_tmpf->path = g_steal_pointer (&tmp); return TRUE; } @@ -463,7 +463,7 @@ glnx_tmpfile_reopen_rdonly (GLnxTmpfile *tmpf, } glnx_close_fd (&tmpf->fd); - tmpf->fd = glnx_steal_fd (&rdonly_fd); + tmpf->fd = g_steal_fd (&rdonly_fd); return TRUE; } @@ -794,10 +794,21 @@ glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes) /* If we've requested to copy the whole range, try a full-file clone first. */ - if (max_bytes == (off_t) -1) + if (max_bytes == (off_t) -1 && + lseek (fdf, 0, SEEK_CUR) == 0 && + lseek (fdt, 0, SEEK_CUR) == 0) { if (ioctl (fdt, FICLONE, fdf) == 0) - return 0; + { + /* All the other methods advance the fds. Do it here too for consistency. */ + if (lseek (fdf, 0, SEEK_END) < 0) + return -1; + if (lseek (fdt, 0, SEEK_END) < 0) + return -1; + + return 0; + } + /* Fall through */ struct stat stbuf; diff --git a/libglnx/glnx-local-alloc.h b/libglnx/glnx-local-alloc.h index 615b954..65ae747 100644 --- a/libglnx/glnx-local-alloc.h +++ b/libglnx/glnx-local-alloc.h @@ -24,6 +24,8 @@ #include #include +#include "glnx-backports.h" + G_BEGIN_DECLS /** @@ -43,19 +45,14 @@ glnx_local_obj_unref (void *v) } #define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref))) -static inline int -glnx_steal_fd (int *fdp) -{ - int fd = *fdp; - *fdp = -1; - return fd; -} +/* Backwards-compat with older libglnx */ +#define glnx_steal_fd g_steal_fd /** * glnx_close_fd: * @fdp: Pointer to fd * - * Effectively `close (glnx_steal_fd (&fd))`. Also + * Effectively `close (g_steal_fd (&fd))`. Also * asserts that `close()` did not raise `EBADF` - encountering * that error is usually a critical bug in the program. */ @@ -66,7 +63,7 @@ glnx_close_fd (int *fdp) g_assert (fdp); - int fd = glnx_steal_fd (fdp); + int fd = g_steal_fd (fdp); if (fd >= 0) { errsv = errno; diff --git a/libglnx/glnx-lockfile.c b/libglnx/glnx-lockfile.c index 65a1558..fcda84c 100644 --- a/libglnx/glnx-lockfile.c +++ b/libglnx/glnx-lockfile.c @@ -129,7 +129,7 @@ glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_loc out_lock->initialized = TRUE; out_lock->dfd = dfd; out_lock->path = g_steal_pointer (&t); - out_lock->fd = glnx_steal_fd (&fd); + out_lock->fd = g_steal_fd (&fd); out_lock->operation = operation; return TRUE; } diff --git a/libglnx/libglnx.h b/libglnx/libglnx.h index ca82ba5..63d73ad 100644 --- a/libglnx/libglnx.h +++ b/libglnx/libglnx.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS #include #include #include +#include #include #include #include diff --git a/libglnx/tests/libglnx-testlib.c b/libglnx/tests/libglnx-testlib.c index 37b3ece..3eb2ba1 100644 --- a/libglnx/tests/libglnx-testlib.c +++ b/libglnx/tests/libglnx-testlib.c @@ -67,8 +67,7 @@ _glnx_test_auto_temp_dir_leave (_GLnxTestAutoTempDir *dir) glnx_tmpdir_delete (&dir->temp_dir, NULL, &error); g_assert_no_error (error); - g_close (dir->old_cwd_fd, &error); - g_assert_no_error (error); + glnx_close_fd (&dir->old_cwd_fd); g_free (dir->old_cwd); g_free (dir); diff --git a/libglnx/tests/test-libglnx-macros.c b/libglnx/tests/test-libglnx-macros.c index 5f41e5b..ec669d3 100644 --- a/libglnx/tests/test-libglnx-macros.c +++ b/libglnx/tests/test-libglnx-macros.c @@ -26,6 +26,13 @@ #include #include +static void +test_info (void) +{ + g_info ("hello, world"); + g_info ("answer=%d", 42); +} + static void test_inset (void) { @@ -104,6 +111,7 @@ test_hash_table_foreach (void) int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); + g_test_add_func ("/info", test_info); g_test_add_func ("/inset", test_inset); g_test_add_func ("/hash_table_foreach", test_hash_table_foreach); return g_test_run(); diff --git a/man/index.xml b/man/index.xml index e20ae87..9f52cf7 100644 --- a/man/index.xml +++ b/man/index.xml @@ -193,7 +193,7 @@ License along with this library. If not, see . - ostree-trivial-httpd1 + ostree-prepare-root1 diff --git a/man/ostree-admin-deploy.xml b/man/ostree-admin-deploy.xml index 0d73b8e..8be3390 100644 --- a/man/ostree-admin-deploy.xml +++ b/man/ostree-admin-deploy.xml @@ -65,11 +65,19 @@ License along with this library. If not, see . Options + + ="STATEROOT" + + + Use a different operating system stateroot than the current one. + + + ="STATEROOT" - Use a different operating system root than the current one. + Alias for --stateroot. @@ -136,6 +144,14 @@ License along with this library. If not, see . Append kernel argument; useful with e.g. console= that can be used multiple times. + + + ="NAME=VALUE" + + + Delete kernel argument if exists, can be used multiple times. + + diff --git a/man/ostree-admin-os-init.xml b/man/ostree-admin-os-init.xml index fbe1ec7..ea141ab 100644 --- a/man/ostree-admin-os-init.xml +++ b/man/ostree-admin-os-init.xml @@ -44,7 +44,7 @@ License along with this library. If not, see . ostree-admin-os-init - Initialize empty state for a given operating system + Soft-deprecated alias for stateroot-init @@ -57,19 +57,7 @@ License along with this library. If not, see . Description - Initializes an new stateroot (AKA "osname") for an operating system. - Ensures that the core subdirectories of /var (/tmp, /lib, /run, and - /lock) exist and initialize the given STATEROOT as OSTree stateroot. - Each deployment location is comprised of a single shared - var and a set of deployments (chroots). + This is a soft-deprecated alias for stateroot-init. Please see the documentation for that. - - - Example - $ ostree admin os-init exampleos - - ostree/deploy/exampleos initialized as OSTree root - - diff --git a/man/ostree-admin-set-default.xml b/man/ostree-admin-set-default.xml new file mode 100644 index 0000000..7d362fe --- /dev/null +++ b/man/ostree-admin-set-default.xml @@ -0,0 +1,83 @@ + + + + + + + + + ostree admin set-default + OSTree + + + + Developer + Colin + Walters + walters@verbum.org + + + + + + ostree admin set-default + 1 + + + + ostree-admin-set-default + Make deployment at a given index the default for the next boot + + + + + ostree admin set-default INDEX + + + + + Description + + + Make the deployment at INDEX the default for the next boot. + + + + + Example + $ ostree admin status + + * exampleos 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0 + origin refspec: exampleos/buildmain/x86_64-runtime + exampleos ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0 + origin refspec: exampleos/buildmain/x86_64-runtime + +$ ostree admin set-default 1 + + Transaction complete; bootconfig swap: deployment count change: 0 + +$ ostree admin status + exampleos ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0 + origin refspec: exampleos/buildmain/x86_64-runtime + * exampleos 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0 + origin refspec: exampleos/buildmain/x86_64-runtime + + + + diff --git a/man/ostree-admin-stateroot-init.xml b/man/ostree-admin-stateroot-init.xml new file mode 100644 index 0000000..c9e50ed --- /dev/null +++ b/man/ostree-admin-stateroot-init.xml @@ -0,0 +1,75 @@ + + + + + + + + + ostree admin stateroot-init + OSTree + + + + Developer + Colin + Walters + walters@verbum.org + + + + + + ostree admin stateroot-init + 1 + + + + ostree-admin-stateroot-init + Initialize empty state for a given operating system + + + + + ostree admin stateroot-init STATEROOT + + + + + Description + + + Initializes an new stateroot (AKA "osname") for an operating system. + Ensures that the core subdirectories of /var (/tmp, /lib, /run, and + /lock) exist and initialize the given STATEROOT as OSTree stateroot. + Each deployment location is comprised of a single shared + var and a set of deployments (chroots). + + + + + Example + $ ostree admin stateroot-init exampleos + + ostree/deploy/exampleos initialized as OSTree stateroot + + + diff --git a/man/ostree-checkout.xml b/man/ostree-checkout.xml index 4ed53a9..8f7d4f9 100644 --- a/man/ostree-checkout.xml +++ b/man/ostree-checkout.xml @@ -114,6 +114,17 @@ License along with this library. If not, see . + + + + + Enable overlayfs whiteout extraction into 0:0 character devices. + Overlayfs whiteouts are encoded inside ostree as .ostree-wh.filename + and extracted as 0:0 character devices. This is useful to carry + container storage embedded into ostree. + + + diff --git a/man/ostree-commit.xml b/man/ostree-commit.xml index e964064..12f4fd1 100644 --- a/man/ostree-commit.xml +++ b/man/ostree-commit.xml @@ -184,6 +184,14 @@ License along with this library. If not, see . + + 0 | 1 + + + When SELinux labeling is enabled, epoch 1 ensures that /usr/etc is labeled as if it was /etc. + + + @@ -311,10 +319,22 @@ License along with this library. If not, see . + + + ="PATH" + + This will read a key (corresponding to the provided --sign-type from the provided path. The key should be base64 encoded. + + + ="KEY-ID" - There KEY-ID is: + In new code, avoid using this because passing private keys via command line arguments + are prone to leakage in logs and process listings. + + + The KEY-ID is: diff --git a/man/ostree-find-remotes.xml b/man/ostree-find-remotes.xml index 5c5b241..eee0d12 100644 --- a/man/ostree-find-remotes.xml +++ b/man/ostree-find-remotes.xml @@ -86,6 +86,14 @@ License along with this library. If not, see . Options + + =DIR + + + Use an alternate cache directory in DIR. + + + diff --git a/man/ostree-prepare-root.xml b/man/ostree-prepare-root.xml new file mode 100644 index 0000000..03bf022 --- /dev/null +++ b/man/ostree-prepare-root.xml @@ -0,0 +1,160 @@ + + + + + + + + + ostree prepare-root + OSTree + + + + Developer + Colin + Walters + walters@verbum.org + + + + + + ostree prepare-root + 1 + + + + ostree-prepare-root + Change the view of a mounted root filesystem to an ostree deployment + + + + + ostree prepare-root TARGET + + + + + Description + + + At its core, ostree operates on an existing mounted filesystem. Tooling such + as ostree admin deploy will create a new directory that can be + used as a bootable target. This tool is designed to run in an initramfs and + set up "remapping" mounts as a view into that filesystem. + + + + As of more recently, this tool also has optional support for composefs, which + creates a distinct mount point layered on top of the underlying filesystem. + + + + The most common pattern today is to use systemd in an initramfs. The systemd + unit shipped upstream is ordered in this way: + + After=sysroot.mount and Before=initrd-root-fs.target + + + + When it runs, the mounted filesystem at the provided TARGET (usually /sysroot) + will be changed such that what appears at /sysroot is actually the + "deployment root" - i.e. a particular versioned subdirectory. What was formerly the + "physical root" i.e. the real root of the filesystem will appear as /sysroot/sysroot. + + + + For /var, by default a bind mount is created from the deployment root to /sysroot/var. + + + + A read-only bind mount is created over /sysroot/usr. The immutable bit is set on the deployment + root, so this provides basic protection for filesystem mutation. If the sysroot.readonly + option is enabled, instead a writable bind mount for /sysroot/etc, and everything else + is mounted read-only. + + + + Finally, when higher level tooling such as systemd performs a switch-root operation, what + was /sysroot becomes / and after the transition into + the real root, the system will be booted into the "deployment", which is a versioned immutable + filesystem tree. The ostree tooling running in the real root thereafter performs further changes + by operating on /sysroot which is now the "physical root". + + + + + Configuration + + + The /usr/lib/ostree/prepare-root.conf (or /etc/ostree/prepare-root.conf) config file is parsed by ostree-prepare-root. This file must + be present in the initramfs. The default dracut module will copy it from the real root if present. + + + + + sysroot.readonly + A boolean value; the default is false. If this is set to true, then the /sysroot mount point is mounted read-only. + + + etc.transient + A boolean value; the default is false. If this is set to true, then the /etc mount point is mounted transiently i.e. a non-persistent location. + + + composefs.enabled + This can be yes, no. maybe or + signed. The default is maybe. If set to yes or + signed, then composefs is always used, and the boot fails if it is not + available. Additionally if set to signed, boot will fail if the image cannot be + validated by a public key. If set to maybe, then composefs is used if supported. + + + + composefs.keypath + Path to a file with Ed25519 public keys in the initramfs, used if + composefs.enabled is set to signed. The default value for this is + /etc/ostree/initramfs-root-binding.key. For a valid signed boot the target OSTree + commit must be signed by at least one public key in this file, and the commitfs digest listed in the + commit must match the target composefs image. + + + + + + + systemd + + + As mentioned above, this tool comes with a systemd unit file ostree-prepare-root.service + and it is primarily expected to be invoked this way. + + + + + Composefs + + + The default for ostree is to create a plain hardlinked filesystem tree. + composefs support is currently experimental; see the upstream doc/composefs.md + for more information on using it. + + + + diff --git a/man/ostree-pull.xml b/man/ostree-pull.xml index 0915dd2..29181f4 100644 --- a/man/ostree-pull.xml +++ b/man/ostree-pull.xml @@ -65,6 +65,14 @@ License along with this library. If not, see . + + =DIR + + + Use an alternate cache directory in DIR. + + + @@ -136,6 +144,42 @@ License along with this library. If not, see . + + + + + Do not retry when network issues happen, instead fail automatically. (Currently only affects libcurl) + + + + + =N + + + The average transfer speed per second of a transfer during the + time set via 'low-speed-time-seconds' for libcurl to abort + (default: 1000) + + + + + =N + + + The time in number seconds that the transfer speed should be + below the 'low-speed-limit-bytes' setting for libcurl to abort + (default: 30) + + + + + =N + + + The max amount of concurrent connections allowed. (default: 8) + + + diff --git a/man/ostree-refs.xml b/man/ostree-refs.xml index 97d69fd..b54039a 100644 --- a/man/ostree-refs.xml +++ b/man/ostree-refs.xml @@ -98,6 +98,15 @@ License along with this library. If not, see . + + , + + + When listing refs, also print their revisions. The revisions + will be separated by a tab character. + + + , diff --git a/man/ostree-remote.xml b/man/ostree-remote.xml index b14fc6d..d107ce9 100644 --- a/man/ostree-remote.xml +++ b/man/ostree-remote.xml @@ -194,6 +194,31 @@ License along with this library. If not, see . + + 'Refs' Options + + + + , + + + Also print the revisions for each ref. The revisions will + be separated by a tab character. + + + + + + + =DIR + + + Use an alternate cache directory in DIR. + + + + + 'GPG-Import' Options @@ -226,6 +251,14 @@ License along with this library. If not, see . 'Summary' Options + + =DIR + + + Use an alternate cache directory in DIR. + + + diff --git a/man/ostree-rev-parse.xml b/man/ostree-rev-parse.xml index 74c585f..f39868a 100644 --- a/man/ostree-rev-parse.xml +++ b/man/ostree-rev-parse.xml @@ -54,6 +54,19 @@ License along with this library. If not, see . + + Options + + + , + + + If the repository has exactly one commit, then print it; any other case will result in an error. + + + + + Description diff --git a/man/ostree-show.xml b/man/ostree-show.xml index 4495b1e..8d134cc 100644 --- a/man/ostree-show.xml +++ b/man/ostree-show.xml @@ -81,6 +81,14 @@ License along with this library. If not, see . + + + + + List the available metadata keys. + + + ="KEY" @@ -89,6 +97,14 @@ License along with this library. If not, see . + + + + + List the available detached metadata keys. + + + ="KEY" diff --git a/man/ostree-trivial-httpd.xml b/man/ostree-trivial-httpd.xml deleted file mode 100644 index 7ba1dae..0000000 --- a/man/ostree-trivial-httpd.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - ostree trivial-httpd - OSTree - - - - Developer - Colin - Walters - walters@verbum.org - - - - - - ostree trivial-httpd - 1 - - - - ostree-trivial-httpd - Simple webserver - - - - - ostree trivial-httpd OPTIONS DIR - - - - - - Description - - - This runs a simple webserver and keeps it running until killed. If DIR is not specified, it defaults to the current directory. - - - - - Options - - - - , - - - Fork into background when ready. - - - - - - - - Automatically exit when directory is deleted. - - - - - ,="PATH" - - - Write port number to PATH (- for standard output). - - - - - , - - - Use the specified TCP port to listen on. - - - - - - - - Force range requests by only serving half of files. - - - - - - - - Example - $ ostree trivial-httpd - - diff --git a/man/ostree.repo-config.xml b/man/ostree.repo-config.xml index 5afeac8..c2a9a8c 100644 --- a/man/ostree.repo-config.xml +++ b/man/ostree.repo-config.xml @@ -229,7 +229,10 @@ License along with this library. If not, see . lock-timeout-secs Integer value controlling the number of seconds to block while attempting to acquire a lock (see above). A value - of -1 means block indefinitely. The default value is 30. + of -1 means block indefinitely. The default value is 300. This timeout + is now regarded as a mistake; because it's likely to cause flakes. + It's recommended to set it to -1, and have timeouts at a higher application + level if desired. @@ -415,8 +418,26 @@ License along with this library. If not, see . + + bootprefix + A boolean value; defaults to false. If set to true, the bootloader entries + generated will include /boot as a prefix. This will likely be turned + on by default in the future. + + + + + + + + [ex-integrity] Section Options + + The "ex-" prefix here signifies experimental options. The ex-integrity section + contains options related to system integrity. Information about experimental + options is canonically found in upstream tracking issues. + diff --git a/man/ostree.xml b/man/ostree.xml index 39f7884..779024b 100644 --- a/man/ostree.xml +++ b/man/ostree.xml @@ -426,14 +426,6 @@ License along with this library. If not, see . Regenerate the repository summary metadata. - - - ostree-trivial-httpd1 - - - Simple webserver. - - diff --git a/src/boot/dracut/module-setup.sh b/src/boot/dracut/module-setup.sh index bedf584..06d7460 100755 --- a/src/boot/dracut/module-setup.sh +++ b/src/boot/dracut/module-setup.sh @@ -19,6 +19,10 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see . +installkernel() { + instmods erofs overlay +} + check() { if [[ -x $systemdutildir/systemd ]] && [[ -x /usr/lib/ostree/ostree-prepare-root ]]; then return 255 @@ -33,6 +37,14 @@ depends() { install() { dracut_install /usr/lib/ostree/ostree-prepare-root + for r in /usr/lib /etc; do + if test -f "$r/ostree/prepare-root.conf"; then + inst_simple "$r/ostree/prepare-root.conf" + fi + done + if test -f "/etc/ostree/initramfs-root-binding.key"; then + inst_simple "/etc/ostree/initramfs-root-binding.key" + fi inst_simple "${systemdsystemunitdir}/ostree-prepare-root.service" mkdir -p "${initdir}${systemdsystemconfdir}/initrd-root-fs.target.wants" ln_r "${systemdsystemunitdir}/ostree-prepare-root.service" \ diff --git a/src/boot/ostree-finalize-staged-hold.service b/src/boot/ostree-finalize-staged-hold.service new file mode 100644 index 0000000..85b5d54 --- /dev/null +++ b/src/boot/ostree-finalize-staged-hold.service @@ -0,0 +1,35 @@ +# Copyright (C) 2018 Red Hat, Inc. +# Copyright (C) 2022 Endless OS Foundation LLC +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + +# See https://github.com/ostreedev/ostree/pull/2543 for background. +[Unit] +Description=Hold /boot Open for OSTree Finalize Staged Deployment +Documentation=man:ostree(1) +ConditionPathExists=/run/ostree-booted +DefaultDependencies=no + +RequiresMountsFor=/sysroot /boot +After=local-fs.target +Before=basic.target final.target + +[Service] +Type=exec + +# This is explicitly run in the root namespace to ensure an automounted +# /boot doesn't time out since autofs doesn't handle mount namespaces. +# +# https://bugzilla.redhat.com/show_bug.cgi?id=2056090 +ExecStart=+/usr/bin/ostree admin finalize-staged --hold diff --git a/src/boot/ostree-finalize-staged.service b/src/boot/ostree-finalize-staged.service index 2f28bbb..63621ce 100644 --- a/src/boot/ostree-finalize-staged.service +++ b/src/boot/ostree-finalize-staged.service @@ -29,6 +29,11 @@ Before=basic.target final.target After=systemd-journal-flush.service Conflicts=final.target +# Start the hold unit and ensure it stays active throughout this +# service. +Wants=ostree-finalize-staged-hold.service +After=ostree-finalize-staged-hold.service + [Service] Type=oneshot RemainAfterExit=yes diff --git a/src/libostree/bupsplit.c b/src/libostree/bupsplit.c index 79207a6..7e5f3ab 100644 --- a/src/libostree/bupsplit.c +++ b/src/libostree/bupsplit.c @@ -1,20 +1,20 @@ /* * Copyright 2011 Avery Pennarun. All rights reserved. - * + * * (This license applies to bupsplit.c and bupsplit.h only.) - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AVERY PENNARUN ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -28,10 +28,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "bupsplit.h" -#include #include -#include +#include #include +#include // According to librsync/rollsum.h: // "We should make this something other than zero to improve the @@ -40,79 +40,81 @@ // slightly worse than the librsync value of 31 for my arbitrary test data. #define ROLLSUM_CHAR_OFFSET 31 -typedef struct { - unsigned s1, s2; - uint8_t window[BUP_WINDOWSIZE]; - int wofs; +typedef struct +{ + unsigned s1, s2; + uint8_t window[BUP_WINDOWSIZE]; + int wofs; } Rollsum; - // These formulas are based on rollsum.h in the librsync project. -static void rollsum_add(Rollsum *r, uint8_t drop, uint8_t add) +static void +rollsum_add (Rollsum *r, uint8_t drop, uint8_t add) { - r->s1 += add - drop; - r->s2 += r->s1 - (BUP_WINDOWSIZE * (drop + ROLLSUM_CHAR_OFFSET)); + r->s1 += add - drop; + r->s2 += r->s1 - (BUP_WINDOWSIZE * (drop + ROLLSUM_CHAR_OFFSET)); } - -static void rollsum_init(Rollsum *r) +static void +rollsum_init (Rollsum *r) { - r->s1 = BUP_WINDOWSIZE * ROLLSUM_CHAR_OFFSET; - r->s2 = BUP_WINDOWSIZE * (BUP_WINDOWSIZE-1) * ROLLSUM_CHAR_OFFSET; - r->wofs = 0; - memset(r->window, 0, BUP_WINDOWSIZE); + r->s1 = BUP_WINDOWSIZE * ROLLSUM_CHAR_OFFSET; + r->s2 = BUP_WINDOWSIZE * (BUP_WINDOWSIZE - 1) * ROLLSUM_CHAR_OFFSET; + r->wofs = 0; + memset (r->window, 0, BUP_WINDOWSIZE); } - // For some reason, gcc 4.3 (at least) optimizes badly if find_ofs() // is static and rollsum_roll is an inline function. Let's use a macro // here instead to help out the optimizer. -#define rollsum_roll(r, ch) do { \ - rollsum_add((r), (r)->window[(r)->wofs], (ch)); \ - (r)->window[(r)->wofs] = (ch); \ - (r)->wofs = ((r)->wofs + 1) % BUP_WINDOWSIZE; \ -} while (0) - +#define rollsum_roll(r, ch) \ + do \ + { \ + rollsum_add ((r), (r)->window[(r)->wofs], (ch)); \ + (r)->window[(r)->wofs] = (ch); \ + (r)->wofs = ((r)->wofs + 1) % BUP_WINDOWSIZE; \ + } \ + while (0) -static uint32_t rollsum_digest(Rollsum *r) +static uint32_t +rollsum_digest (Rollsum *r) { - return (r->s1 << 16) | (r->s2 & 0xffff); + return (r->s1 << 16) | (r->s2 & 0xffff); } - uint32_t -bupsplit_sum(uint8_t *buf, size_t ofs, size_t len) +bupsplit_sum (uint8_t *buf, size_t ofs, size_t len) { - size_t count; - Rollsum r; - rollsum_init(&r); - for (count = ofs; count < len; count++) - rollsum_roll(&r, buf[count]); - return rollsum_digest(&r); + size_t count; + Rollsum r; + rollsum_init (&r); + for (count = ofs; count < len; count++) + rollsum_roll (&r, buf[count]); + return rollsum_digest (&r); } - -int bupsplit_find_ofs(const unsigned char *buf, int len, int *bits) +int +bupsplit_find_ofs (const unsigned char *buf, int len, int *bits) { - Rollsum r; - int count; - - rollsum_init(&r); - for (count = 0; count < len; count++) + Rollsum r; + int count; + + rollsum_init (&r); + for (count = 0; count < len; count++) { - rollsum_roll(&r, buf[count]); - if ((r.s2 & (BUP_BLOBSIZE-1)) == ((~0) & (BUP_BLOBSIZE-1))) - { - if (bits) - { - unsigned rsum = rollsum_digest(&r); - *bits = BUP_BLOBBITS; - rsum >>= BUP_BLOBBITS; - for (*bits = BUP_BLOBBITS; (rsum >>= 1) & 1; (*bits)++) - ; - } - return count+1; - } + rollsum_roll (&r, buf[count]); + if ((r.s2 & (BUP_BLOBSIZE - 1)) == ((~0) & (BUP_BLOBSIZE - 1))) + { + if (bits) + { + unsigned rsum = rollsum_digest (&r); + *bits = BUP_BLOBBITS; + rsum >>= BUP_BLOBBITS; + for (*bits = BUP_BLOBBITS; (rsum >>= 1) & 1; (*bits)++) + ; + } + return count + 1; + } } - return 0; + return 0; } diff --git a/src/libostree/bupsplit.h b/src/libostree/bupsplit.h index f770ee5..1db9e25 100644 --- a/src/libostree/bupsplit.h +++ b/src/libostree/bupsplit.h @@ -1,20 +1,20 @@ /* * Copyright 2011 Avery Pennarun. All rights reserved. - * + * * (This license applies to bupsplit.c and bupsplit.h only.) - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AVERY PENNARUN ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -34,19 +34,20 @@ #include #define BUP_BLOBBITS (13) -#define BUP_BLOBSIZE (1<lock); self->maincontext = g_main_context_ref_thread_default (); - self->values = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_variant_unref); + self->values = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_variant_unref); } /** @@ -125,13 +121,14 @@ ostree_async_progress_init (OstreeAsyncProgress *self) * Since: 2017.6 */ GVariant * -ostree_async_progress_get_variant (OstreeAsyncProgress *self, - const char *key) +ostree_async_progress_get_variant (OstreeAsyncProgress *self, const char *key) { + g_assert (OSTREE_IS_ASYNC_PROGRESS (self)); + GVariant *rval; - g_return_val_if_fail (OSTREE_IS_ASYNC_PROGRESS (self), NULL); - g_return_val_if_fail (key != NULL, NULL); + if (key == NULL) + return NULL; /* Early return */ g_mutex_lock (&self->lock); rval = g_hash_table_lookup (self->values, GUINT_TO_POINTER (g_quark_from_string (key))); @@ -143,18 +140,16 @@ ostree_async_progress_get_variant (OstreeAsyncProgress *self, } guint -ostree_async_progress_get_uint (OstreeAsyncProgress *self, - const char *key) +ostree_async_progress_get_uint (OstreeAsyncProgress *self, const char *key) { - g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, key); + g_autoptr (GVariant) rval = ostree_async_progress_get_variant (self, key); return (rval != NULL) ? g_variant_get_uint32 (rval) : 0; } guint64 -ostree_async_progress_get_uint64 (OstreeAsyncProgress *self, - const char *key) +ostree_async_progress_get_uint64 (OstreeAsyncProgress *self, const char *key) { - g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, key); + g_autoptr (GVariant) rval = ostree_async_progress_get_variant (self, key); return (rval != NULL) ? g_variant_get_uint64 (rval) : 0; } @@ -192,8 +187,7 @@ ostree_async_progress_get_uint64 (OstreeAsyncProgress *self, * Since: 2017.6 */ void -ostree_async_progress_get (OstreeAsyncProgress *self, - ...) +ostree_async_progress_get (OstreeAsyncProgress *self, ...) { va_list ap; const char *key, *format_string; @@ -201,8 +195,7 @@ ostree_async_progress_get (OstreeAsyncProgress *self, g_mutex_lock (&self->lock); va_start (ap, self); - for (key = va_arg (ap, const char *), format_string = va_arg (ap, const char *); - key != NULL; + for (key = va_arg (ap, const char *), format_string = va_arg (ap, const char *); key != NULL; key = va_arg (ap, const char *), format_string = va_arg (ap, const char *)) { GVariant *variant; @@ -257,8 +250,7 @@ ensure_callback_locked (OstreeAsyncProgress *self) * Since: 2017.6 */ void -ostree_async_progress_set_status (OstreeAsyncProgress *self, - const char *status) +ostree_async_progress_set_status (OstreeAsyncProgress *self, const char *status) { ostree_async_progress_set_variant (self, "status", g_variant_new_string ((status != NULL) ? status : "")); @@ -278,9 +270,9 @@ ostree_async_progress_set_status (OstreeAsyncProgress *self, * Since: 2017.6 */ char * -ostree_async_progress_get_status (OstreeAsyncProgress *self) +ostree_async_progress_get_status (OstreeAsyncProgress *self) { - g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, "status"); + g_autoptr (GVariant) rval = ostree_async_progress_get_variant (self, "status"); const gchar *status = (rval != NULL) ? g_variant_get_string (rval, NULL) : NULL; if (status != NULL && *status == '\0') status = NULL; @@ -318,8 +310,7 @@ ostree_async_progress_get_status (OstreeAsyncProgress *self) * Since: 2017.6 */ void -ostree_async_progress_set (OstreeAsyncProgress *self, - ...) +ostree_async_progress_set (OstreeAsyncProgress *self, ...) { va_list ap; const char *key, *format_string; @@ -334,18 +325,17 @@ ostree_async_progress_set (OstreeAsyncProgress *self, va_start (ap, self); - for (key = va_arg (ap, const char *), format_string = va_arg (ap, const char *); - key != NULL; + for (key = va_arg (ap, const char *), format_string = va_arg (ap, const char *); key != NULL; key = va_arg (ap, const char *), format_string = va_arg (ap, const char *)) { GVariant *orig_value; - g_autoptr(GVariant) new_value = NULL; + g_autoptr (GVariant) new_value = NULL; gpointer qkey = GUINT_TO_POINTER (g_quark_from_string (key)); new_value = g_variant_ref_sink (g_variant_new_va (format_string, NULL, &ap)); - if (g_hash_table_lookup_extended (self->values, qkey, NULL, (gpointer *) &orig_value) && - g_variant_equal (orig_value, new_value)) + if (g_hash_table_lookup_extended (self->values, qkey, NULL, (gpointer *)&orig_value) + && g_variant_equal (orig_value, new_value)) continue; g_hash_table_replace (self->values, qkey, g_steal_pointer (&new_value)); @@ -377,12 +367,10 @@ ostree_async_progress_set (OstreeAsyncProgress *self, * Since: 2017.6 */ void -ostree_async_progress_set_variant (OstreeAsyncProgress *self, - const char *key, - GVariant *value) +ostree_async_progress_set_variant (OstreeAsyncProgress *self, const char *key, GVariant *value) { GVariant *orig_value; - g_autoptr(GVariant) new_value = g_variant_ref_sink (value); + g_autoptr (GVariant) new_value = g_variant_ref_sink (value); gpointer qkey = GUINT_TO_POINTER (g_quark_from_string (key)); g_return_if_fail (OSTREE_IS_ASYNC_PROGRESS (self)); @@ -394,7 +382,7 @@ ostree_async_progress_set_variant (OstreeAsyncProgress *self, if (self->dead) goto out; - if (g_hash_table_lookup_extended (self->values, qkey, NULL, (gpointer *) &orig_value)) + if (g_hash_table_lookup_extended (self->values, qkey, NULL, (gpointer *)&orig_value)) { if (g_variant_equal (orig_value, new_value)) goto out; @@ -402,22 +390,18 @@ ostree_async_progress_set_variant (OstreeAsyncProgress *self, g_hash_table_replace (self->values, qkey, g_steal_pointer (&new_value)); ensure_callback_locked (self); - out: +out: g_mutex_unlock (&self->lock); } void -ostree_async_progress_set_uint (OstreeAsyncProgress *self, - const char *key, - guint value) +ostree_async_progress_set_uint (OstreeAsyncProgress *self, const char *key, guint value) { ostree_async_progress_set_variant (self, key, g_variant_new_uint32 (value)); } void -ostree_async_progress_set_uint64 (OstreeAsyncProgress *self, - const char *key, - guint64 value) +ostree_async_progress_set_uint64 (OstreeAsyncProgress *self, const char *key, guint64 value) { ostree_async_progress_set_variant (self, key, g_variant_new_uint64 (value)); } @@ -434,11 +418,10 @@ ostree_async_progress_set_uint64 (OstreeAsyncProgress *self, * Since: 2019.6 */ void -ostree_async_progress_copy_state (OstreeAsyncProgress *self, - OstreeAsyncProgress *dest) +ostree_async_progress_copy_state (OstreeAsyncProgress *self, OstreeAsyncProgress *dest) { - g_return_if_fail (OSTREE_IS_ASYNC_PROGRESS (self)); - g_return_if_fail (OSTREE_IS_ASYNC_PROGRESS (dest)); + g_assert (OSTREE_IS_ASYNC_PROGRESS (self)); + g_assert (OSTREE_IS_ASYNC_PROGRESS (dest)); g_mutex_lock (&self->lock); @@ -452,7 +435,7 @@ ostree_async_progress_copy_state (OstreeAsyncProgress *self, g_hash_table_replace (dest->values, key, value); } - out: +out: g_mutex_unlock (&self->lock); } @@ -464,12 +447,19 @@ ostree_async_progress_copy_state (OstreeAsyncProgress *self, OstreeAsyncProgress * ostree_async_progress_new (void) { - return (OstreeAsyncProgress*)g_object_new (OSTREE_TYPE_ASYNC_PROGRESS, NULL); + return (OstreeAsyncProgress *)g_object_new (OSTREE_TYPE_ASYNC_PROGRESS, NULL); } - +/** + * ostree_async_progress_new_and_connect: (skip) + * @changed: a notification callback + * @user_data: data to pass to @changed + * + * Returns: (transfer full): A new progress object + */ OstreeAsyncProgress * -ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, gpointer user_data), +ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, + gpointer user_data), gpointer user_data) { OstreeAsyncProgress *ret = ostree_async_progress_new (); diff --git a/src/libostree/ostree-async-progress.h b/src/libostree/ostree-async-progress.h index afd45f1..3006892 100644 --- a/src/libostree/ostree-async-progress.h +++ b/src/libostree/ostree-async-progress.h @@ -23,15 +23,19 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_ASYNC_PROGRESS (ostree_async_progress_get_type ()) -#define OSTREE_ASYNC_PROGRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgress)) -#define OSTREE_ASYNC_PROGRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgressClass)) -#define OSTREE_IS_ASYNC_PROGRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_ASYNC_PROGRESS)) -#define OSTREE_IS_ASYNC_PROGRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_ASYNC_PROGRESS)) -#define OSTREE_ASYNC_PROGRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgressClass)) - -typedef struct OstreeAsyncProgress OstreeAsyncProgress; -typedef struct OstreeAsyncProgressClass OstreeAsyncProgressClass; +#define OSTREE_TYPE_ASYNC_PROGRESS (ostree_async_progress_get_type ()) +#define OSTREE_ASYNC_PROGRESS(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgress)) +#define OSTREE_ASYNC_PROGRESS_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgressClass)) +#define OSTREE_IS_ASYNC_PROGRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_ASYNC_PROGRESS)) +#define OSTREE_IS_ASYNC_PROGRESS_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_ASYNC_PROGRESS)) +#define OSTREE_ASYNC_PROGRESS_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgressClass)) + +typedef struct OstreeAsyncProgress OstreeAsyncProgress; +typedef struct OstreeAsyncProgressClass OstreeAsyncProgressClass; struct OstreeAsyncProgressClass { @@ -41,57 +45,46 @@ struct OstreeAsyncProgressClass }; _OSTREE_PUBLIC -GType ostree_async_progress_get_type (void) G_GNUC_CONST; +GType ostree_async_progress_get_type (void) G_GNUC_CONST; _OSTREE_PUBLIC OstreeAsyncProgress *ostree_async_progress_new (void); _OSTREE_PUBLIC -OstreeAsyncProgress *ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, gpointer user_data), gpointer user_data); +OstreeAsyncProgress *ostree_async_progress_new_and_connect ( + void (*changed) (OstreeAsyncProgress *self, gpointer user_data), gpointer user_data); _OSTREE_PUBLIC -char *ostree_async_progress_get_status (OstreeAsyncProgress *self); +char *ostree_async_progress_get_status (OstreeAsyncProgress *self); _OSTREE_PUBLIC -void ostree_async_progress_get (OstreeAsyncProgress *self, - ...) G_GNUC_NULL_TERMINATED; +void ostree_async_progress_get (OstreeAsyncProgress *self, ...) G_GNUC_NULL_TERMINATED; _OSTREE_PUBLIC -guint ostree_async_progress_get_uint (OstreeAsyncProgress *self, - const char *key); +guint ostree_async_progress_get_uint (OstreeAsyncProgress *self, const char *key); _OSTREE_PUBLIC -guint64 ostree_async_progress_get_uint64 (OstreeAsyncProgress *self, - const char *key); +guint64 ostree_async_progress_get_uint64 (OstreeAsyncProgress *self, const char *key); _OSTREE_PUBLIC -GVariant *ostree_async_progress_get_variant (OstreeAsyncProgress *self, - const char *key); +GVariant *ostree_async_progress_get_variant (OstreeAsyncProgress *self, const char *key); _OSTREE_PUBLIC -void ostree_async_progress_set_status (OstreeAsyncProgress *self, - const char *status); +void ostree_async_progress_set_status (OstreeAsyncProgress *self, const char *status); _OSTREE_PUBLIC -void ostree_async_progress_set (OstreeAsyncProgress *self, - ...) G_GNUC_NULL_TERMINATED; +void ostree_async_progress_set (OstreeAsyncProgress *self, ...) G_GNUC_NULL_TERMINATED; _OSTREE_PUBLIC -void ostree_async_progress_set_uint (OstreeAsyncProgress *self, - const char *key, - guint value); +void ostree_async_progress_set_uint (OstreeAsyncProgress *self, const char *key, guint value); _OSTREE_PUBLIC -void ostree_async_progress_set_uint64 (OstreeAsyncProgress *self, - const char *key, - guint64 value); +void ostree_async_progress_set_uint64 (OstreeAsyncProgress *self, const char *key, guint64 value); _OSTREE_PUBLIC -void ostree_async_progress_set_variant (OstreeAsyncProgress *self, - const char *key, - GVariant *value); +void ostree_async_progress_set_variant (OstreeAsyncProgress *self, const char *key, + GVariant *value); _OSTREE_PUBLIC void ostree_async_progress_finish (OstreeAsyncProgress *self); _OSTREE_PUBLIC -void ostree_async_progress_copy_state (OstreeAsyncProgress *self, - OstreeAsyncProgress *dest); +void ostree_async_progress_copy_state (OstreeAsyncProgress *self, OstreeAsyncProgress *dest); G_END_DECLS diff --git a/src/libostree/ostree-autocleanups.h b/src/libostree/ostree-autocleanups.h index 5627494..d087e6a 100644 --- a/src/libostree/ostree-autocleanups.h +++ b/src/libostree/ostree-autocleanups.h @@ -58,7 +58,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSePolicy, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSysroot, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSysrootUpgrader, g_object_unref) -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeRepoCommitTraverseIter, ostree_repo_commit_traverse_iter_clear) +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeRepoCommitTraverseIter, + ostree_repo_commit_traverse_iter_clear) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeCollectionRef, ostree_collection_ref_free) G_DEFINE_AUTO_CLEANUP_FREE_FUNC (OstreeCollectionRefv, ostree_collection_ref_freev, NULL) diff --git a/src/libostree/ostree-bloom-private.h b/src/libostree/ostree-bloom-private.h index e9ec2ba..3a608af 100644 --- a/src/libostree/ostree-bloom-private.h +++ b/src/libostree/ostree-bloom-private.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include "libglnx.h" @@ -55,8 +55,7 @@ typedef struct _OstreeBloom OstreeBloom; * * Since: 2017.8 */ -typedef guint64 (*OstreeBloomHashFunc) (gconstpointer element, - guint8 k); +typedef guint64 (*OstreeBloomHashFunc) (gconstpointer element, guint8 k); #define OSTREE_TYPE_BLOOM (ostree_bloom_get_type ()) @@ -64,14 +63,10 @@ G_GNUC_INTERNAL GType ostree_bloom_get_type (void); G_GNUC_INTERNAL -OstreeBloom *ostree_bloom_new (gsize n_bytes, - guint8 k, - OstreeBloomHashFunc hash_func); +OstreeBloom *ostree_bloom_new (gsize n_bytes, guint8 k, OstreeBloomHashFunc hash_func); G_GNUC_INTERNAL -OstreeBloom *ostree_bloom_new_from_bytes (GBytes *bytes, - guint8 k, - OstreeBloomHashFunc hash_func); +OstreeBloom *ostree_bloom_new_from_bytes (GBytes *bytes, guint8 k, OstreeBloomHashFunc hash_func); G_GNUC_INTERNAL OstreeBloom *ostree_bloom_ref (OstreeBloom *bloom); @@ -81,15 +76,13 @@ void ostree_bloom_unref (OstreeBloom *bloom); G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeBloom, ostree_bloom_unref) G_GNUC_INTERNAL -gboolean ostree_bloom_maybe_contains (OstreeBloom *bloom, - gconstpointer element); +gboolean ostree_bloom_maybe_contains (OstreeBloom *bloom, gconstpointer element); G_GNUC_INTERNAL GBytes *ostree_bloom_seal (OstreeBloom *bloom); G_GNUC_INTERNAL -void ostree_bloom_add_element (OstreeBloom *bloom, - gconstpointer element); +void ostree_bloom_add_element (OstreeBloom *bloom, gconstpointer element); G_GNUC_INTERNAL gsize ostree_bloom_get_size (OstreeBloom *bloom); @@ -99,7 +92,6 @@ G_GNUC_INTERNAL OstreeBloomHashFunc ostree_bloom_get_hash_func (OstreeBloom *bloom); G_GNUC_INTERNAL -guint64 ostree_str_bloom_hash (gconstpointer element, - guint8 k); +guint64 ostree_str_bloom_hash (gconstpointer element, guint8 k); G_END_DECLS diff --git a/src/libostree/ostree-bloom.c b/src/libostree/ostree-bloom.c index 8c1017d..6c1d1f1 100644 --- a/src/libostree/ostree-bloom.c +++ b/src/libostree/ostree-bloom.c @@ -24,8 +24,8 @@ #include #include -#include #include +#include #include #include @@ -76,13 +76,13 @@ struct _OstreeBloom { guint ref_count; - gsize n_bytes; /* 0 < n_bytes <= G_MAXSIZE / 8 */ - gboolean is_mutable; /* determines which of [im]mutable_bytes is accessed */ + gsize n_bytes; /* 0 < n_bytes <= G_MAXSIZE / 8 */ + gboolean is_mutable; /* determines which of [im]mutable_bytes is accessed */ union - { - guint8 *mutable_bytes; /* owned; mutually exclusive */ - GBytes *immutable_bytes; /* owned; mutually exclusive */ - }; + { + guint8 *mutable_bytes; /* owned; mutually exclusive */ + GBytes *immutable_bytes; /* owned; mutually exclusive */ + }; guint8 k; OstreeBloomHashFunc hash_func; }; @@ -110,11 +110,9 @@ G_DEFINE_BOXED_TYPE (OstreeBloom, ostree_bloom, ostree_bloom_ref, ostree_bloom_u * Since: 2017.8 */ OstreeBloom * -ostree_bloom_new (gsize n_bytes, - guint8 k, - OstreeBloomHashFunc hash_func) +ostree_bloom_new (gsize n_bytes, guint8 k, OstreeBloomHashFunc hash_func) { - g_autoptr(OstreeBloom) bloom = NULL; + g_autoptr (OstreeBloom) bloom = NULL; g_return_val_if_fail (n_bytes > 0, NULL); g_return_val_if_fail (n_bytes <= G_MAXSIZE / 8, NULL); @@ -152,11 +150,9 @@ ostree_bloom_new (gsize n_bytes, * Since: 2017.8 */ OstreeBloom * -ostree_bloom_new_from_bytes (GBytes *bytes, - guint8 k, - OstreeBloomHashFunc hash_func) +ostree_bloom_new_from_bytes (GBytes *bytes, guint8 k, OstreeBloomHashFunc hash_func) { - g_autoptr(OstreeBloom) bloom = NULL; + g_autoptr (OstreeBloom) bloom = NULL; g_return_val_if_fail (bytes != NULL, NULL); g_return_val_if_fail (g_bytes_get_size (bytes) > 0, NULL); @@ -227,8 +223,7 @@ ostree_bloom_unref (OstreeBloom *bloom) /* @idx is in bits, not bytes. */ static inline gboolean -ostree_bloom_get_bit (OstreeBloom *bloom, - gsize idx) +ostree_bloom_get_bit (OstreeBloom *bloom, gsize idx) { const guint8 *bytes; @@ -243,12 +238,11 @@ ostree_bloom_get_bit (OstreeBloom *bloom, /* @idx is in bits, not bytes. */ static inline void -ostree_bloom_set_bit (OstreeBloom *bloom, - gsize idx) +ostree_bloom_set_bit (OstreeBloom *bloom, gsize idx) { g_assert (bloom->is_mutable); g_assert (idx / 8 < bloom->n_bytes); - bloom->mutable_bytes[idx / 8] |= (guint8) (1 << (idx % 8)); + bloom->mutable_bytes[idx / 8] |= (guint8)(1 << (idx % 8)); } /** @@ -265,8 +259,7 @@ ostree_bloom_set_bit (OstreeBloom *bloom, * Since: 2017.8 */ gboolean -ostree_bloom_maybe_contains (OstreeBloom *bloom, - gconstpointer element) +ostree_bloom_maybe_contains (OstreeBloom *bloom, gconstpointer element) { guint8 i; @@ -279,11 +272,11 @@ ostree_bloom_maybe_contains (OstreeBloom *bloom, idx = bloom->hash_func (element, i); - if (!ostree_bloom_get_bit (bloom, (gsize) (idx % (bloom->n_bytes * 8)))) - return FALSE; /* definitely not in the set */ + if (!ostree_bloom_get_bit (bloom, (gsize)(idx % (bloom->n_bytes * 8)))) + return FALSE; /* definitely not in the set */ } - return TRUE; /* possibly in the set */ + return TRUE; /* possibly in the set */ } /** @@ -310,7 +303,8 @@ ostree_bloom_seal (OstreeBloom *bloom) if (bloom->is_mutable) { bloom->is_mutable = FALSE; - bloom->immutable_bytes = g_bytes_new_take (g_steal_pointer (&bloom->mutable_bytes), bloom->n_bytes); + bloom->immutable_bytes + = g_bytes_new_take (g_steal_pointer (&bloom->mutable_bytes), bloom->n_bytes); } return g_bytes_ref (bloom->immutable_bytes); @@ -328,8 +322,7 @@ ostree_bloom_seal (OstreeBloom *bloom) * Since: 2017.8 */ void -ostree_bloom_add_element (OstreeBloom *bloom, - gconstpointer element) +ostree_bloom_add_element (OstreeBloom *bloom, gconstpointer element) { guint8 i; @@ -340,7 +333,7 @@ ostree_bloom_add_element (OstreeBloom *bloom, for (i = 0; i < bloom->k; i++) { guint64 idx = bloom->hash_func (element, i); - ostree_bloom_set_bit (bloom, (gsize) (idx % (bloom->n_bytes * 8))); + ostree_bloom_set_bit (bloom, (gsize)(idx % (bloom->n_bytes * 8))); } } @@ -418,145 +411,147 @@ ostree_bloom_get_hash_func (OstreeBloom *bloom) #define cROUNDS 2 #define dROUNDS 4 -#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) - -#define U32TO8_LE(p, v) \ - (p)[0] = (uint8_t)((v)); \ - (p)[1] = (uint8_t)((v) >> 8); \ - (p)[2] = (uint8_t)((v) >> 16); \ - (p)[3] = (uint8_t)((v) >> 24); - -#define U64TO8_LE(p, v) \ - U32TO8_LE((p), (uint32_t)((v))); \ - U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); - -#define U8TO64_LE(p) \ - (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ - ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ - ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ - ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) - -#define SIPROUND \ - do { \ - v0 += v1; \ - v1 = ROTL(v1, 13); \ - v1 ^= v0; \ - v0 = ROTL(v0, 32); \ - v2 += v3; \ - v3 = ROTL(v3, 16); \ - v3 ^= v2; \ - v0 += v3; \ - v3 = ROTL(v3, 21); \ - v3 ^= v0; \ - v2 += v1; \ - v1 = ROTL(v1, 17); \ - v1 ^= v2; \ - v2 = ROTL(v2, 32); \ - } while (0) +#define ROTL(x, b) (uint64_t) (((x) << (b)) | ((x) >> (64 - (b)))) + +#define U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); + +#define U64TO8_LE(p, v) \ + U32TO8_LE ((p), (uint32_t)((v))); \ + U32TO8_LE ((p) + 4, (uint32_t)((v) >> 32)); + +#define U8TO64_LE(p) \ + (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | ((uint64_t)((p)[2]) << 16) \ + | ((uint64_t)((p)[3]) << 24) | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \ + | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) + +#define SIPROUND \ + do \ + { \ + v0 += v1; \ + v1 = ROTL (v1, 13); \ + v1 ^= v0; \ + v0 = ROTL (v0, 32); \ + v2 += v3; \ + v3 = ROTL (v3, 16); \ + v3 ^= v2; \ + v0 += v3; \ + v3 = ROTL (v3, 21); \ + v3 ^= v0; \ + v2 += v1; \ + v1 = ROTL (v1, 17); \ + v1 ^= v2; \ + v2 = ROTL (v2, 32); \ + } \ + while (0) #ifdef DEBUG -#define TRACE \ - do { \ - printf("(%3d) v0 %08x %08x\n", (int)inlen, (uint32_t)(v0 >> 32), \ - (uint32_t)v0); \ - printf("(%3d) v1 %08x %08x\n", (int)inlen, (uint32_t)(v1 >> 32), \ - (uint32_t)v1); \ - printf("(%3d) v2 %08x %08x\n", (int)inlen, (uint32_t)(v2 >> 32), \ - (uint32_t)v2); \ - printf("(%3d) v3 %08x %08x\n", (int)inlen, (uint32_t)(v3 >> 32), \ - (uint32_t)v3); \ - } while (0) +#define TRACE \ + do \ + { \ + printf ("(%3d) v0 %08x %08x\n", (int)inlen, (uint32_t)(v0 >> 32), (uint32_t)v0); \ + printf ("(%3d) v1 %08x %08x\n", (int)inlen, (uint32_t)(v1 >> 32), (uint32_t)v1); \ + printf ("(%3d) v2 %08x %08x\n", (int)inlen, (uint32_t)(v2 >> 32), (uint32_t)v2); \ + printf ("(%3d) v3 %08x %08x\n", (int)inlen, (uint32_t)(v3 >> 32), (uint32_t)v3); \ + } \ + while (0) #else #define TRACE #endif -static int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k, - uint8_t *out, const size_t outlen) { - - assert((outlen == 8) || (outlen == 16)); - uint64_t v0 = 0x736f6d6570736575ULL; - uint64_t v1 = 0x646f72616e646f6dULL; - uint64_t v2 = 0x6c7967656e657261ULL; - uint64_t v3 = 0x7465646279746573ULL; - uint64_t k0 = U8TO64_LE(k); - uint64_t k1 = U8TO64_LE(k + 8); - uint64_t m; - int i; - const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); - const int left = inlen & 7; - uint64_t b = ((uint64_t)inlen) << 56; - v3 ^= k1; - v2 ^= k0; - v1 ^= k1; - v0 ^= k0; - - if (outlen == 16) - v1 ^= 0xee; - - for (; in != end; in += 8) { - m = U8TO64_LE(in); - v3 ^= m; - - TRACE; - for (i = 0; i < cROUNDS; ++i) - SIPROUND; - - v0 ^= m; +static int +siphash (const uint8_t *in, const size_t inlen, const uint8_t *k, uint8_t *out, const size_t outlen) +{ + + assert ((outlen == 8) || (outlen == 16)); + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f6dULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + uint64_t k0 = U8TO64_LE (k); + uint64_t k1 = U8TO64_LE (k + 8); + uint64_t m; + int i; + const uint8_t *end = in + inlen - (inlen % sizeof (uint64_t)); + const int left = inlen & 7; + uint64_t b = ((uint64_t)inlen) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + + if (outlen == 16) + v1 ^= 0xee; + + for (; in != end; in += 8) + { + m = U8TO64_LE (in); + v3 ^= m; + + TRACE; + for (i = 0; i < cROUNDS; ++i) + SIPROUND; + + v0 ^= m; } - switch (left) { + switch (left) + { case 7: - b |= ((uint64_t)in[6]) << 48; + b |= ((uint64_t)in[6]) << 48; case 6: - b |= ((uint64_t)in[5]) << 40; + b |= ((uint64_t)in[5]) << 40; case 5: - b |= ((uint64_t)in[4]) << 32; + b |= ((uint64_t)in[4]) << 32; case 4: - b |= ((uint64_t)in[3]) << 24; + b |= ((uint64_t)in[3]) << 24; case 3: - b |= ((uint64_t)in[2]) << 16; + b |= ((uint64_t)in[2]) << 16; case 2: - b |= ((uint64_t)in[1]) << 8; + b |= ((uint64_t)in[1]) << 8; case 1: - b |= ((uint64_t)in[0]); - break; + b |= ((uint64_t)in[0]); + break; case 0: - break; + break; } - v3 ^= b; + v3 ^= b; - TRACE; - for (i = 0; i < cROUNDS; ++i) - SIPROUND; + TRACE; + for (i = 0; i < cROUNDS; ++i) + SIPROUND; - v0 ^= b; + v0 ^= b; - if (outlen == 16) - v2 ^= 0xee; - else - v2 ^= 0xff; + if (outlen == 16) + v2 ^= 0xee; + else + v2 ^= 0xff; - TRACE; - for (i = 0; i < dROUNDS; ++i) - SIPROUND; + TRACE; + for (i = 0; i < dROUNDS; ++i) + SIPROUND; - b = v0 ^ v1 ^ v2 ^ v3; - U64TO8_LE(out, b); + b = v0 ^ v1 ^ v2 ^ v3; + U64TO8_LE (out, b); - if (outlen == 8) - return 0; + if (outlen == 8) + return 0; - v1 ^= 0xdd; + v1 ^= 0xdd; - TRACE; - for (i = 0; i < dROUNDS; ++i) - SIPROUND; + TRACE; + for (i = 0; i < dROUNDS; ++i) + SIPROUND; - b = v0 ^ v1 ^ v2 ^ v3; - U64TO8_LE(out + 8, b); + b = v0 ^ v1 ^ v2 ^ v3; + U64TO8_LE (out + 8, b); - return 0; + return 0; } /* End SipHash copied code. */ @@ -581,16 +576,15 @@ static int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k, * Since: 2017.8 */ guint64 -ostree_str_bloom_hash (gconstpointer element, - guint8 k) +ostree_str_bloom_hash (gconstpointer element, guint8 k) { const gchar *str = element; gsize str_len; union - { - guint64 u64; - guint8 u8[8]; - } out_le; + { + guint64 u64; + guint8 u8[8]; + } out_le; guint8 k_array[16]; gsize i; @@ -598,7 +592,7 @@ ostree_str_bloom_hash (gconstpointer element, for (i = 0; i < G_N_ELEMENTS (k_array); i++) k_array[i] = k; - siphash ((const guint8 *) str, str_len, k_array, out_le.u8, sizeof (out_le)); + siphash ((const guint8 *)str, str_len, k_array, out_le.u8, sizeof (out_le)); return le64toh (out_le.u64); } diff --git a/src/libostree/ostree-bootconfig-parser.c b/src/libostree/ostree-bootconfig-parser.c index e005fab..4c3e80d 100644 --- a/src/libostree/ostree-bootconfig-parser.c +++ b/src/libostree/ostree-bootconfig-parser.c @@ -22,15 +22,15 @@ struct _OstreeBootconfigParser { - GObject parent_instance; + GObject parent_instance; - gboolean parsed; - const char *separators; + gboolean parsed; + const char *separators; - GHashTable *options; + GHashTable *options; /* Additional initrds; the primary initrd is in options. */ - char **overlay_initrds; + char **overlay_initrds; }; typedef GObjectClass OstreeBootconfigParserClass; @@ -40,7 +40,7 @@ G_DEFINE_TYPE (OstreeBootconfigParser, ostree_bootconfig_parser, G_TYPE_OBJECT) /** * ostree_bootconfig_parser_clone: * @self: Bootconfig to clone - * + * * Returns: (transfer full): Copy of @self */ OstreeBootconfigParser * @@ -48,7 +48,7 @@ ostree_bootconfig_parser_clone (OstreeBootconfigParser *self) { OstreeBootconfigParser *parser = ostree_bootconfig_parser_new (); - GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v) + GLNX_HASH_TABLE_FOREACH_KV (self->options, const char *, k, const char *, v) g_hash_table_replace (parser->options, g_strdup (k), g_strdup (v)); parser->overlay_initrds = g_strdupv (self->overlay_initrds); @@ -67,21 +67,18 @@ ostree_bootconfig_parser_clone (OstreeBootconfigParser *self) * Initialize a bootconfig from the given file. */ gboolean -ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, int dfd, const char *path, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (!self->parsed, FALSE); + g_assert (!self->parsed); g_autofree char *contents = glnx_file_get_contents_utf8_at (dfd, path, NULL, cancellable, error); if (!contents) return FALSE; - g_autoptr(GPtrArray) overlay_initrds = NULL; + g_autoptr (GPtrArray) overlay_initrds = NULL; - g_auto(GStrv) lines = g_strsplit (contents, "\n", -1); + g_auto (GStrv) lines = g_strsplit (contents, "\n", -1); for (char **iter = lines; *iter; iter++) { const char *line = *iter; @@ -92,8 +89,8 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, items = g_strsplit_set (line, self->separators, 2); if (g_strv_length (items) == 2 && items[0][0] != '\0') { - if (g_str_equal (items[0], "initrd") && - g_hash_table_contains (self->options, "initrd")) + if (g_str_equal (items[0], "initrd") + && g_hash_table_contains (self->options, "initrd")) { if (!overlay_initrds) overlay_initrds = g_ptr_array_new_with_free_func (g_free); @@ -116,7 +113,7 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, if (overlay_initrds) { g_ptr_array_add (overlay_initrds, NULL); - self->overlay_initrds = (char**)g_ptr_array_free (g_steal_pointer (&overlay_initrds), FALSE); + self->overlay_initrds = (char **)g_ptr_array_free (g_steal_pointer (&overlay_initrds), FALSE); } self->parsed = TRUE; @@ -125,26 +122,39 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, } gboolean -ostree_bootconfig_parser_parse (OstreeBootconfigParser *self, - GFile *path, - GCancellable *cancellable, - GError **error) +ostree_bootconfig_parser_parse (OstreeBootconfigParser *self, GFile *path, + GCancellable *cancellable, GError **error) { return ostree_bootconfig_parser_parse_at (self, AT_FDCWD, gs_file_get_path_cached (path), cancellable, error); } +/** + * ostree_bootconfig_parser_set: + * @self: Parser + * @key: the key + * @value: the key + * + * Set the @key/@value pair to the boot configuration dictionary. + */ void -ostree_bootconfig_parser_set (OstreeBootconfigParser *self, - const char *key, - const char *value) +ostree_bootconfig_parser_set (OstreeBootconfigParser *self, const char *key, const char *value) { g_hash_table_replace (self->options, g_strdup (key), g_strdup (value)); } +/** + * ostree_bootconfig_parser_get: + * @self: Parser + * @key: the key name to retrieve + * + * Get the value corresponding to @key from the boot configuration dictionary. + * + * Returns: (nullable): The corresponding value, or %NULL if the key hasn't been + * found. + */ const char * -ostree_bootconfig_parser_get (OstreeBootconfigParser *self, - const char *key) +ostree_bootconfig_parser_get (OstreeBootconfigParser *self, const char *key) { return g_hash_table_lookup (self->options, key); } @@ -161,8 +171,7 @@ ostree_bootconfig_parser_get (OstreeBootconfigParser *self, * Since: 2020.7 */ void -ostree_bootconfig_parser_set_overlay_initrds (OstreeBootconfigParser *self, - char **initrds) +ostree_bootconfig_parser_set_overlay_initrds (OstreeBootconfigParser *self, char **initrds) { g_assert (g_hash_table_contains (self->options, "initrd")); g_strfreev (self->overlay_initrds); @@ -178,17 +187,14 @@ ostree_bootconfig_parser_set_overlay_initrds (OstreeBootconfigParser *self, * * Since: 2020.7 */ -char** -ostree_bootconfig_parser_get_overlay_initrds (OstreeBootconfigParser *self) +char ** +ostree_bootconfig_parser_get_overlay_initrds (OstreeBootconfigParser *self) { return self->overlay_initrds; } static void -write_key (OstreeBootconfigParser *self, - GString *buf, - const char *key, - const char *value) +write_key (OstreeBootconfigParser *self, GString *buf, const char *key, const char *value) { g_string_append (buf, key); g_string_append_c (buf, self->separators[0]); @@ -197,19 +203,16 @@ write_key (OstreeBootconfigParser *self, } gboolean -ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self, int dfd, const char *path, + GCancellable *cancellable, GError **error) { /* Write the fields in a deterministic order, following what is used * in the bootconfig example of the BootLoaderspec document: * https://systemd.io/BOOT_LOADER_SPECIFICATION */ const char *fields[] = { "title", "version", "options", "devicetree", "linux", "initrd" }; - g_autoptr(GHashTable) keys_written = g_hash_table_new (g_str_hash, g_str_equal); - g_autoptr(GString) buf = g_string_new (""); + g_autoptr (GHashTable) keys_written = g_hash_table_new (g_str_hash, g_str_equal); + g_autoptr (GString) buf = g_string_new (""); for (guint i = 0; i < G_N_ELEMENTS (fields); i++) { @@ -232,29 +235,25 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self, } /* Write unknown fields */ - GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v) + GLNX_HASH_TABLE_FOREACH_KV (self->options, const char *, k, const char *, v) { if (g_hash_table_lookup (keys_written, k)) continue; write_key (self, buf, k, v); } - if (!glnx_file_replace_contents_at (dfd, path, (guint8*)buf->str, buf->len, - GLNX_FILE_REPLACE_NODATASYNC, - cancellable, error)) + if (!glnx_file_replace_contents_at (dfd, path, (guint8 *)buf->str, buf->len, + GLNX_FILE_REPLACE_NODATASYNC, cancellable, error)) return FALSE; return TRUE; } gboolean -ostree_bootconfig_parser_write (OstreeBootconfigParser *self, - GFile *output, - GCancellable *cancellable, - GError **error) +ostree_bootconfig_parser_write (OstreeBootconfigParser *self, GFile *output, + GCancellable *cancellable, GError **error) { - return ostree_bootconfig_parser_write_at (self, - AT_FDCWD, gs_file_get_path_cached (output), + return ostree_bootconfig_parser_write_at (self, AT_FDCWD, gs_file_get_path_cached (output), cancellable, error); } diff --git a/src/libostree/ostree-bootconfig-parser.h b/src/libostree/ostree-bootconfig-parser.h index 6d8359d..5fdad72 100644 --- a/src/libostree/ostree-bootconfig-parser.h +++ b/src/libostree/ostree-bootconfig-parser.h @@ -22,8 +22,10 @@ G_BEGIN_DECLS #define OSTREE_TYPE_BOOTCONFIG_PARSER (ostree_bootconfig_parser_get_type ()) -#define OSTREE_BOOTCONFIG_PARSER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTCONFIG_PARSER, OstreeBootconfigParser)) -#define OSTREE_IS_BOOTCONFIG_PARSER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTCONFIG_PARSER)) +#define OSTREE_BOOTCONFIG_PARSER(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTCONFIG_PARSER, OstreeBootconfigParser)) +#define OSTREE_IS_BOOTCONFIG_PARSER(inst) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTCONFIG_PARSER)) typedef struct _OstreeBootconfigParser OstreeBootconfigParser; @@ -31,51 +33,38 @@ _OSTREE_PUBLIC GType ostree_bootconfig_parser_get_type (void) G_GNUC_CONST; _OSTREE_PUBLIC -OstreeBootconfigParser * ostree_bootconfig_parser_new (void); +OstreeBootconfigParser *ostree_bootconfig_parser_new (void); _OSTREE_PUBLIC -OstreeBootconfigParser * ostree_bootconfig_parser_clone (OstreeBootconfigParser *self); +OstreeBootconfigParser *ostree_bootconfig_parser_clone (OstreeBootconfigParser *self); _OSTREE_PUBLIC -gboolean ostree_bootconfig_parser_parse (OstreeBootconfigParser *self, - GFile *path, - GCancellable *cancellable, - GError **error); +gboolean ostree_bootconfig_parser_parse (OstreeBootconfigParser *self, GFile *path, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error); +gboolean ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, int dfd, const char *path, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_bootconfig_parser_write (OstreeBootconfigParser *self, - GFile *output, - GCancellable *cancellable, - GError **error); +gboolean ostree_bootconfig_parser_write (OstreeBootconfigParser *self, GFile *output, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error); +gboolean ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self, int dfd, const char *path, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -void ostree_bootconfig_parser_set (OstreeBootconfigParser *self, - const char *key, - const char *value); +void ostree_bootconfig_parser_set (OstreeBootconfigParser *self, const char *key, + const char *value); _OSTREE_PUBLIC -const char *ostree_bootconfig_parser_get (OstreeBootconfigParser *self, - const char *key); +const char *ostree_bootconfig_parser_get (OstreeBootconfigParser *self, const char *key); _OSTREE_PUBLIC -void ostree_bootconfig_parser_set_overlay_initrds (OstreeBootconfigParser *self, - char **initrds); +void ostree_bootconfig_parser_set_overlay_initrds (OstreeBootconfigParser *self, char **initrds); _OSTREE_PUBLIC -char** ostree_bootconfig_parser_get_overlay_initrds (OstreeBootconfigParser *self); +char **ostree_bootconfig_parser_get_overlay_initrds (OstreeBootconfigParser *self); G_END_DECLS diff --git a/src/libostree/ostree-bootloader-aboot.c b/src/libostree/ostree-bootloader-aboot.c new file mode 100644 index 0000000..c125ca5 --- /dev/null +++ b/src/libostree/ostree-bootloader-aboot.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2022 Eric Curtin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the licence or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library. If not, see . + */ + +#include "config.h" + +#include "ostree-bootloader-aboot.h" +#include "ostree-deployment-private.h" +#include "ostree-libarchive-private.h" +#include "ostree-sysroot-private.h" +#include "otutil.h" +#include + +#include + +/* This is specific to aboot and zipl today, but in the future we could also + * use it for the grub2-mkconfig case. + */ +static const char aboot_requires_execute_path[] = "boot/ostree-bootloader-update.stamp"; + +struct _OstreeBootloaderAboot +{ + GObject parent_instance; + + OstreeSysroot *sysroot; +}; + +typedef GObjectClass OstreeBootloaderAbootClass; +static void _ostree_bootloader_aboot_bootloader_iface_init (OstreeBootloaderInterface *iface); +G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderAboot, _ostree_bootloader_aboot, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, + _ostree_bootloader_aboot_bootloader_iface_init)); + +static gboolean +_ostree_bootloader_aboot_query (OstreeBootloader *bootloader, gboolean *out_is_active, + GCancellable *cancellable, GError **error) +{ + /* We don't auto-detect this one; should be explicitly chosen right now. + * see also https://github.com/coreos/coreos-assembler/pull/849 + */ + *out_is_active = FALSE; + return TRUE; +} + +static const char * +_ostree_bootloader_aboot_get_name (OstreeBootloader *bootloader) +{ + return "aboot"; +} + +static gboolean +_ostree_bootloader_aboot_write_config (OstreeBootloader *bootloader, int bootversion, + GPtrArray *new_deployments, GCancellable *cancellable, + GError **error) +{ + OstreeBootloaderAboot *self = OSTREE_BOOTLOADER_ABOOT (bootloader); + + /* Write our stamp file */ + if (!glnx_file_replace_contents_at (self->sysroot->sysroot_fd, aboot_requires_execute_path, + (guint8 *)"", 0, GLNX_FILE_REPLACE_NODATASYNC, cancellable, + error)) + return FALSE; + + return TRUE; +} + +static gboolean +_ostree_aboot_get_bls_config (OstreeBootloaderAboot *self, int bootversion, gchar **aboot, + gchar **abootcfg, gchar **version, gchar **vmlinuz, gchar **initramfs, + gchar **options, GCancellable *cancellable, GError **error) +{ + g_autoptr (GPtrArray) configs = NULL; + if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &configs, cancellable, + error)) + return glnx_prefix_error (error, "aboot: loading bls configs"); + + if (!configs || configs->len == 0) + return glnx_throw (error, "aboot: no bls config"); + + OstreeBootconfigParser *parser = (OstreeBootconfigParser *)g_ptr_array_index (configs, 0); + const gchar *val = NULL; + + val = ostree_bootconfig_parser_get (parser, "aboot"); + if (!val) + { + return glnx_throw (error, "aboot: no \"aboot\" key in bootloader config"); + } + *aboot = g_strdup (val); + + val = ostree_bootconfig_parser_get (parser, "abootcfg"); + if (!val) + { + return glnx_throw (error, "aboot: no \"abootcfg\" key in bootloader config"); + } + *abootcfg = g_strdup (val); + + val = ostree_bootconfig_parser_get (parser, "version"); + if (!val) + return glnx_throw (error, "aboot: no \"version\" key in bootloader config"); + *version = g_strdup (val); + + val = ostree_bootconfig_parser_get (parser, "linux"); + if (!val) + return glnx_throw (error, "aboot: no \"linux\" key in bootloader config"); + *vmlinuz = g_build_filename ("/boot", val, NULL); + + val = ostree_bootconfig_parser_get (parser, "initrd"); + if (!val) + return glnx_throw (error, "aboot: no \"initrd\" key in bootloader config"); + *initramfs = g_build_filename ("/boot", val, NULL); + + val = ostree_bootconfig_parser_get (parser, "options"); + if (!val) + return glnx_throw (error, "aboot: no \"options\" key in bootloader config"); + *options = g_strdup (val); + + return TRUE; +} + +static gboolean +_ostree_bootloader_aboot_post_bls_sync (OstreeBootloader *bootloader, int bootversion, + GCancellable *cancellable, GError **error) +{ + OstreeBootloaderAboot *self = OSTREE_BOOTLOADER_ABOOT (bootloader); + + /* Note that unlike the grub2-mkconfig backend, we make no attempt to + * chroot(). + */ + // g_assert (self->sysroot->booted_deployment); + + if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, aboot_requires_execute_path, NULL, 0, + error)) + return FALSE; + + /* If there's no stamp file, nothing to do */ + if (errno == ENOENT) + return TRUE; + + g_autofree gchar *aboot = NULL; + g_autofree gchar *abootcfg = NULL; + g_autofree gchar *version = NULL; + g_autofree gchar *vmlinuz = NULL; + g_autofree gchar *initramfs = NULL; + g_autofree gchar *options = NULL; + if (!_ostree_aboot_get_bls_config (self, bootversion, &aboot, &abootcfg, &version, &vmlinuz, + &initramfs, &options, cancellable, error)) + return FALSE; + + g_autofree char *path_str = g_file_get_path (self->sysroot->path); + + const char *const aboot_argv[] + = { "aboot-deploy", "-r", path_str, "-c", abootcfg, "-o", options, aboot, NULL }; + int estatus; + if (!g_spawn_sync (NULL, (char **)aboot_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, + &estatus, error)) + { + return FALSE; + } + + if (!g_spawn_check_exit_status (estatus, error)) + { + return FALSE; + } + + if (!glnx_unlinkat (self->sysroot->sysroot_fd, aboot_requires_execute_path, 0, error)) + { + return FALSE; + } + + return TRUE; +} + +static void +_ostree_bootloader_aboot_finalize (GObject *object) +{ + OstreeBootloaderAboot *self = OSTREE_BOOTLOADER_ABOOT (object); + + g_clear_object (&self->sysroot); + + G_OBJECT_CLASS (_ostree_bootloader_aboot_parent_class)->finalize (object); +} + +void +_ostree_bootloader_aboot_init (OstreeBootloaderAboot *self) +{ +} + +static void +_ostree_bootloader_aboot_bootloader_iface_init (OstreeBootloaderInterface *iface) +{ + iface->query = _ostree_bootloader_aboot_query; + iface->get_name = _ostree_bootloader_aboot_get_name; + iface->write_config = _ostree_bootloader_aboot_write_config; + iface->post_bls_sync = _ostree_bootloader_aboot_post_bls_sync; +} + +void +_ostree_bootloader_aboot_class_init (OstreeBootloaderAbootClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = _ostree_bootloader_aboot_finalize; +} + +OstreeBootloaderAboot * +_ostree_bootloader_aboot_new (OstreeSysroot *sysroot) +{ + OstreeBootloaderAboot *self = g_object_new (OSTREE_TYPE_BOOTLOADER_ABOOT, NULL); + self->sysroot = g_object_ref (sysroot); + return self; +} diff --git a/src/libostree/ostree-bootloader-aboot.h b/src/libostree/ostree-bootloader-aboot.h new file mode 100644 index 0000000..690220a --- /dev/null +++ b/src/libostree/ostree-bootloader-aboot.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022 Eric Curtin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the licence or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library. If not, see . + */ + +#pragma once + +#include "ostree-bootloader.h" + +G_BEGIN_DECLS + +#define OSTREE_TYPE_BOOTLOADER_ABOOT (_ostree_bootloader_aboot_get_type ()) +#define OSTREE_BOOTLOADER_ABOOT(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_ABOOT, OstreeBootloaderAboot)) +#define OSTREE_IS_BOOTLOADER_ABOOT(inst) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_ABOOT)) + +typedef struct _OstreeBootloaderAboot OstreeBootloaderAboot; + +GType _ostree_bootloader_aboot_get_type (void) G_GNUC_CONST; + +OstreeBootloaderAboot *_ostree_bootloader_aboot_new (OstreeSysroot *sysroot); +G_END_DECLS diff --git a/src/libostree/ostree-bootloader-grub2.c b/src/libostree/ostree-bootloader-grub2.c index fff3b95..e1ee786 100644 --- a/src/libostree/ostree-bootloader-grub2.c +++ b/src/libostree/ostree-bootloader-grub2.c @@ -17,8 +17,8 @@ #include "config.h" -#include "ostree-sysroot-private.h" #include "ostree-bootloader-grub2.h" +#include "ostree-sysroot-private.h" #include "otutil.h" #include #include @@ -32,7 +32,7 @@ * Allow us to override this at build time if we're * using a modern GRUB installation. */ -#if !defined(WITH_MODERN_GRUB) && ( defined(__i386__) || defined(__x86_64__) ) +#if !defined(WITH_MODERN_GRUB) && (defined(__i386__) || defined(__x86_64__)) #define GRUB2_SUFFIX "16" #else #define GRUB2_SUFFIX "" @@ -53,49 +53,48 @@ struct _OstreeBootloaderGrub2 { - GObject parent_instance; + GObject parent_instance; - OstreeSysroot *sysroot; - GFile *config_path_bios_1; - GFile *config_path_bios_2; - GFile *config_path_efi; - gboolean is_efi; + OstreeSysroot *sysroot; + GFile *config_path_bios_1; + GFile *config_path_bios_2; + GFile *config_path_efi; + gboolean is_efi; }; typedef GObjectClass OstreeBootloaderGrub2Class; static void _ostree_bootloader_grub2_bootloader_iface_init (OstreeBootloaderInterface *iface); G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderGrub2, _ostree_bootloader_grub2, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, _ostree_bootloader_grub2_bootloader_iface_init)); + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, + _ostree_bootloader_grub2_bootloader_iface_init)); static gboolean -_ostree_bootloader_grub2_query (OstreeBootloader *bootloader, - gboolean *out_is_active, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_grub2_query (OstreeBootloader *bootloader, gboolean *out_is_active, + GCancellable *cancellable, GError **error) { OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader); /* Look for the BIOS path first */ - if (g_file_query_exists (self->config_path_bios_1, NULL) || - g_file_query_exists (self->config_path_bios_2, NULL)) + if (g_file_query_exists (self->config_path_bios_1, NULL) + || g_file_query_exists (self->config_path_bios_2, NULL)) { /* If we found it, we're done */ *out_is_active = TRUE; return TRUE; } - g_autoptr(GFile) efi_basedir = g_file_resolve_relative_path (self->sysroot->path, "boot/efi/EFI"); + g_autoptr (GFile) efi_basedir + = g_file_resolve_relative_path (self->sysroot->path, "boot/efi/EFI"); g_clear_object (&self->config_path_efi); if (g_file_query_exists (efi_basedir, NULL)) { - g_autoptr(GFileEnumerator) direnum = NULL; + g_autoptr (GFileEnumerator) direnum = NULL; direnum = g_file_enumerate_children (efi_basedir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!direnum) return FALSE; @@ -104,8 +103,7 @@ _ostree_bootloader_grub2_query (OstreeBootloader *bootloader, GFileInfo *file_info; const char *fname; - if (!g_file_enumerator_iterate (direnum, &file_info, NULL, - cancellable, error)) + if (!g_file_enumerator_iterate (direnum, &file_info, NULL, cancellable, error)) return FALSE; if (file_info == NULL) break; @@ -117,8 +115,8 @@ _ostree_bootloader_grub2_query (OstreeBootloader *bootloader, if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY) continue; - g_autofree char *subdir_grub_cfg = - g_build_filename (gs_file_get_path_cached (efi_basedir), fname, "grub.cfg", NULL); + g_autofree char *subdir_grub_cfg + = g_build_filename (gs_file_get_path_cached (efi_basedir), fname, "grub.cfg", NULL); if (g_file_test (subdir_grub_cfg, G_FILE_TEST_EXISTS)) { @@ -152,20 +150,15 @@ _ostree_bootloader_grub2_get_name (OstreeBootloader *bootloader) * https://github.com/ostreedev/ostree/issues/717 */ gboolean -_ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot, - int bootversion, - int target_fd, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot, int bootversion, int target_fd, + GCancellable *cancellable, GError **error) { /* So... yeah. Just going to hardcode these. */ static const char hardcoded_video[] = "load_video\n" - "set gfxpayload=keep\n"; + "set gfxpayload=keep\n"; static const char hardcoded_insmods[] = "insmod gzio\n"; - const char *grub2_boot_device_id = - g_getenv ("GRUB2_BOOT_DEVICE_ID"); - const char *grub2_prepare_root_cache = - g_getenv ("GRUB2_PREPARE_ROOT_CACHE"); + const char *grub2_boot_device_id = g_getenv ("GRUB2_BOOT_DEVICE_ID"); + const char *grub2_prepare_root_cache = g_getenv ("GRUB2_PREPARE_ROOT_CACHE"); /* We must have been called via the wrapper script */ g_assert (grub2_boot_device_id != NULL); @@ -174,15 +167,14 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot /* Passed from the parent */ gboolean is_efi = g_getenv ("_OSTREE_GRUB2_IS_EFI") != NULL; - g_autoptr(GOutputStream) out_stream = g_unix_output_stream_new (target_fd, FALSE); + g_autoptr (GOutputStream) out_stream = g_unix_output_stream_new (target_fd, FALSE); - g_autoptr(GPtrArray) loader_configs = NULL; - if (!_ostree_sysroot_read_boot_loader_configs (sysroot, bootversion, - &loader_configs, - cancellable, error)) + g_autoptr (GPtrArray) loader_configs = NULL; + if (!_ostree_sysroot_read_boot_loader_configs (sysroot, bootversion, &loader_configs, cancellable, + error)) return FALSE; - g_autoptr(GString) output = g_string_new (""); + g_autoptr (GString) output = g_string_new (""); for (guint i = 0; i < loader_configs->len; i++) { OstreeBootconfigParser *config = loader_configs->pdata[i]; @@ -204,7 +196,9 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot quoted_title = g_shell_quote (title); uuid = g_strdup_printf ("ostree-%u-%s", (guint)i, grub2_boot_device_id); quoted_uuid = g_shell_quote (uuid); - g_string_append_printf (output, "menuentry %s --class gnu-linux --class gnu --class os --unrestricted %s {\n", quoted_title, quoted_uuid); + g_string_append_printf ( + output, "menuentry %s --class gnu-linux --class gnu --class os --unrestricted %s {\n", + quoted_title, quoted_uuid); g_free (uuid); g_free (quoted_title); g_free (quoted_uuid); @@ -259,14 +253,15 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot } gsize bytes_written; - if (!g_output_stream_write_all (out_stream, output->str, output->len, - &bytes_written, cancellable, error)) + if (!g_output_stream_write_all (out_stream, output->str, output->len, &bytes_written, cancellable, + error)) return FALSE; return TRUE; } -typedef struct { +typedef struct +{ const char *root; const char *bootversion_str; gboolean is_efi; @@ -302,7 +297,7 @@ grub2_child_setup (gpointer user_data) _exit (1); } - if (mount (NULL, "/", "none", MS_REC|MS_PRIVATE, NULL) < 0) + if (mount (NULL, "/", "none", MS_REC | MS_PRIVATE, NULL) < 0) { perror ("Failed to make / a private mount"); _exit (1); @@ -329,15 +324,14 @@ grub2_child_setup (gpointer user_data) /* Main entrypoint for writing GRUB configuration. */ static gboolean -_ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, int bootversion, + GPtrArray *new_deployments, GCancellable *cancellable, + GError **error) { OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader); - /* Autotests can set this envvar to select which code path to test, useful for OS installers as well */ + /* Autotests can set this envvar to select which code path to test, useful for OS installers as + * well */ gboolean use_system_grub2_mkconfig = TRUE; #ifdef USE_BUILTIN_GRUB2_MKCONFIG use_system_grub2_mkconfig = FALSE; @@ -351,14 +345,15 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, use_system_grub2_mkconfig = FALSE; } else - grub_exec = use_system_grub2_mkconfig ? GRUB2_MKCONFIG_PATH : TARGET_PREFIX "/lib/ostree/ostree-grub-generator"; + grub_exec = use_system_grub2_mkconfig ? GRUB2_MKCONFIG_PATH + : TARGET_PREFIX "/lib/ostree/ostree-grub-generator"; g_autofree char *grub2_mkconfig_chroot = NULL; if (use_system_grub2_mkconfig && ostree_sysroot_get_booted_deployment (self->sysroot) == NULL && g_file_has_parent (self->sysroot->path, NULL)) { OstreeDeployment *tool_deployment; - g_autoptr(GFile) tool_deployment_root = NULL; + g_autoptr (GFile) tool_deployment_root = NULL; g_assert_cmpint (new_deployments->len, >, 0); tool_deployment = new_deployments->pdata[0]; @@ -372,14 +367,15 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, * This all only applies if we're not using the builtin * generator, which handles being run outside of the root. */ - tool_deployment_root = ostree_sysroot_get_deployment_directory (self->sysroot, tool_deployment); + tool_deployment_root + = ostree_sysroot_get_deployment_directory (self->sysroot, tool_deployment); grub2_mkconfig_chroot = g_file_get_path (tool_deployment_root); } g_debug ("Using grub2-mkconfig chroot: %s\n", grub2_mkconfig_chroot); - g_autoptr(GFile) new_config_path = NULL; - g_autoptr(GFile) config_path_efi_dir = NULL; + g_autoptr (GFile) new_config_path = NULL; + g_autoptr (GFile) config_path_efi_dir = NULL; if (self->is_efi) { config_path_efi_dir = g_file_get_parent (self->config_path_efi); @@ -390,12 +386,14 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, } else { - new_config_path = ot_gfile_resolve_path_printf (self->sysroot->path, "boot/loader.%d/grub.cfg", - bootversion); + new_config_path = ot_gfile_resolve_path_printf (self->sysroot->path, + "boot/loader.%d/grub.cfg", bootversion); } - const char *grub_argv[4] = { NULL, "-o", NULL, NULL}; - Grub2ChildSetupData cdata = { NULL, }; + const char *grub_argv[4] = { NULL, "-o", NULL, NULL }; + Grub2ChildSetupData cdata = { + NULL, + }; grub_argv[0] = grub_exec; grub_argv[2] = gs_file_get_path_cached (new_config_path); @@ -415,9 +413,8 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, Upstream is fixed though. */ int grub2_estatus; - if (!g_spawn_sync (NULL, (char**)grub_argv, NULL, grub_spawnflags, - grub2_child_setup, &cdata, NULL, NULL, - &grub2_estatus, error)) + if (!g_spawn_sync (NULL, (char **)grub_argv, NULL, grub_spawnflags, grub2_child_setup, &cdata, + NULL, NULL, &grub2_estatus, error)) return FALSE; if (!g_spawn_check_exit_status (grub2_estatus, error)) { @@ -426,8 +423,10 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, } /* Now let's fdatasync() for the new file */ - { glnx_autofd int new_config_fd = -1; - if (!glnx_openat_rdonly (AT_FDCWD, gs_file_get_path_cached (new_config_path), TRUE, &new_config_fd, error)) + { + glnx_autofd int new_config_fd = -1; + if (!glnx_openat_rdonly (AT_FDCWD, gs_file_get_path_cached (new_config_path), TRUE, + &new_config_fd, error)) return FALSE; if (fdatasync (new_config_fd) < 0) @@ -436,13 +435,14 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, if (self->is_efi) { - g_autoptr(GFile) config_path_efi_old = g_file_get_child (config_path_efi_dir, "grub.cfg.old"); + g_autoptr (GFile) config_path_efi_old + = g_file_get_child (config_path_efi_dir, "grub.cfg.old"); /* copy current to old */ if (!ot_gfile_ensure_unlinked (config_path_efi_old, cancellable, error)) return FALSE; - if (!g_file_copy (self->config_path_efi, config_path_efi_old, - G_FILE_COPY_OVERWRITE, cancellable, NULL, NULL, error)) + if (!g_file_copy (self->config_path_efi, config_path_efi_old, G_FILE_COPY_OVERWRITE, + cancellable, NULL, NULL, error)) return FALSE; /* NOTE: NON-ATOMIC REPLACEMENT; WE can't do anything else on FAT; @@ -450,7 +450,9 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, */ if (!ot_gfile_ensure_unlinked (self->config_path_efi, cancellable, error)) return FALSE; - if (rename (gs_file_get_path_cached (new_config_path), gs_file_get_path_cached (self->config_path_efi)) < 0) + if (rename (gs_file_get_path_cached (new_config_path), + gs_file_get_path_cached (self->config_path_efi)) + < 0) return glnx_throw_errno_prefix (error, "rename"); } @@ -458,7 +460,7 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, } static gboolean -_ostree_bootloader_grub2_is_atomic (OstreeBootloader *bootloader) +_ostree_bootloader_grub2_is_atomic (OstreeBootloader *bootloader) { OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader); return !self->is_efi; @@ -505,8 +507,10 @@ _ostree_bootloader_grub2_new (OstreeSysroot *sysroot) OstreeBootloaderGrub2 *self = g_object_new (OSTREE_TYPE_BOOTLOADER_GRUB2, NULL); self->sysroot = g_object_ref (sysroot); /* Used by (at least) Debian */ - self->config_path_bios_1 = g_file_resolve_relative_path (self->sysroot->path, "boot/grub/grub.cfg"); + self->config_path_bios_1 + = g_file_resolve_relative_path (self->sysroot->path, "boot/grub/grub.cfg"); /* Used by (at least) Fedora */ - self->config_path_bios_2 = g_file_resolve_relative_path (self->sysroot->path, "boot/grub2/grub.cfg"); + self->config_path_bios_2 + = g_file_resolve_relative_path (self->sysroot->path, "boot/grub2/grub.cfg"); return self; } diff --git a/src/libostree/ostree-bootloader-grub2.h b/src/libostree/ostree-bootloader-grub2.h index 2b0d99c..8f6c3de 100644 --- a/src/libostree/ostree-bootloader-grub2.h +++ b/src/libostree/ostree-bootloader-grub2.h @@ -22,15 +22,19 @@ G_BEGIN_DECLS #define OSTREE_TYPE_BOOTLOADER_GRUB2 (_ostree_bootloader_grub2_get_type ()) -#define OSTREE_BOOTLOADER_GRUB2(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_GRUB2, OstreeBootloaderGrub2)) -#define OSTREE_IS_BOOTLOADER_GRUB2(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_GRUB2)) +#define OSTREE_BOOTLOADER_GRUB2(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_GRUB2, OstreeBootloaderGrub2)) +#define OSTREE_IS_BOOTLOADER_GRUB2(inst) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_GRUB2)) typedef struct _OstreeBootloaderGrub2 OstreeBootloaderGrub2; GType _ostree_bootloader_grub2_get_type (void) G_GNUC_CONST; -OstreeBootloaderGrub2 * _ostree_bootloader_grub2_new (OstreeSysroot *sysroot); +OstreeBootloaderGrub2 *_ostree_bootloader_grub2_new (OstreeSysroot *sysroot); -gboolean _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error); +gboolean _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot, int bootversion, + int target_fd, GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/src/libostree/ostree-bootloader-syslinux.c b/src/libostree/ostree-bootloader-syslinux.c index 8add0f1..1e71ef2 100644 --- a/src/libostree/ostree-bootloader-syslinux.c +++ b/src/libostree/ostree-bootloader-syslinux.c @@ -17,8 +17,8 @@ #include "config.h" -#include "ostree-sysroot-private.h" #include "ostree-bootloader-syslinux.h" +#include "ostree-sysroot-private.h" #include "otutil.h" #include @@ -27,27 +27,27 @@ static const char syslinux_config_path[] = "boot/syslinux/syslinux.cfg"; struct _OstreeBootloaderSyslinux { - GObject parent_instance; + GObject parent_instance; - OstreeSysroot *sysroot; + OstreeSysroot *sysroot; }; typedef GObjectClass OstreeBootloaderSyslinuxClass; static void _ostree_bootloader_syslinux_bootloader_iface_init (OstreeBootloaderInterface *iface); G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderSyslinux, _ostree_bootloader_syslinux, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, _ostree_bootloader_syslinux_bootloader_iface_init)); + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, + _ostree_bootloader_syslinux_bootloader_iface_init)); static gboolean -_ostree_bootloader_syslinux_query (OstreeBootloader *bootloader, - gboolean *out_is_active, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_syslinux_query (OstreeBootloader *bootloader, gboolean *out_is_active, + GCancellable *cancellable, GError **error) { OstreeBootloaderSyslinux *self = OSTREE_BOOTLOADER_SYSLINUX (bootloader); struct stat stbuf; - if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, syslinux_config_path, &stbuf, AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, syslinux_config_path, &stbuf, + AT_SYMLINK_NOFOLLOW, error)) return FALSE; *out_is_active = (errno == 0); return TRUE; @@ -60,14 +60,11 @@ _ostree_bootloader_syslinux_get_name (OstreeBootloader *bootloader) } static gboolean -append_config_from_loader_entries (OstreeBootloaderSyslinux *self, - gboolean regenerate_default, - int bootversion, - GPtrArray *new_lines, - GCancellable *cancellable, - GError **error) +append_config_from_loader_entries (OstreeBootloaderSyslinux *self, gboolean regenerate_default, + int bootversion, GPtrArray *new_lines, GCancellable *cancellable, + GError **error) { - g_autoptr(GPtrArray) loader_configs = NULL; + g_autoptr (GPtrArray) loader_configs = NULL; if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &loader_configs, cancellable, error)) return FALSE; @@ -106,27 +103,23 @@ append_config_from_loader_entries (OstreeBootloaderSyslinux *self, } static gboolean -_ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, int bootversion, + GPtrArray *new_deployments, GCancellable *cancellable, + GError **error) { OstreeBootloaderSyslinux *self = OSTREE_BOOTLOADER_SYSLINUX (bootloader); - g_autofree char *new_config_path = - g_strdup_printf ("boot/loader.%d/syslinux.cfg", bootversion); + g_autofree char *new_config_path = g_strdup_printf ("boot/loader.%d/syslinux.cfg", bootversion); /* This should follow the symbolic link to the current bootversion. */ - g_autofree char *config_contents = - glnx_file_get_contents_utf8_at (self->sysroot->sysroot_fd, syslinux_config_path, NULL, - cancellable, error); + g_autofree char *config_contents = glnx_file_get_contents_utf8_at ( + self->sysroot->sysroot_fd, syslinux_config_path, NULL, cancellable, error); if (!config_contents) return FALSE; - g_auto(GStrv) lines = g_strsplit (config_contents, "\n", -1); - g_autoptr(GPtrArray) new_lines = g_ptr_array_new_with_free_func (g_free); - g_autoptr(GPtrArray) tmp_lines = g_ptr_array_new_with_free_func (g_free); + g_auto (GStrv) lines = g_strsplit (config_contents, "\n", -1); + g_autoptr (GPtrArray) new_lines = g_ptr_array_new_with_free_func (g_free); + g_autoptr (GPtrArray) tmp_lines = g_ptr_array_new_with_free_func (g_free); g_autofree char *kernel_arg = NULL; gboolean saw_default = FALSE; @@ -141,8 +134,7 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, const char *line = *iter; gboolean skip = FALSE; - if (parsing_label && - (line == NULL || !g_str_has_prefix (line, "\t"))) + if (parsing_label && (line == NULL || !g_str_has_prefix (line, "\t"))) { parsing_label = FALSE; if (kernel_arg == NULL) @@ -153,8 +145,8 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, * We check for /ostree (without /boot prefix) as well to support * upgrading ostree from len; i++) { @@ -174,8 +166,7 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, if (line == NULL) break; - if (!parsing_label && - (g_str_has_prefix (line, "LABEL "))) + if (!parsing_label && (g_str_has_prefix (line, "LABEL "))) { parsing_label = TRUE; g_ptr_array_set_size (tmp_lines, 0); @@ -185,15 +176,14 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, g_free (kernel_arg); kernel_arg = g_strdup (line + strlen ("\tKERNEL ")); } - else if (!parsing_label && - (g_str_has_prefix (line, "DEFAULT "))) + else if (!parsing_label && (g_str_has_prefix (line, "DEFAULT "))) { saw_default = TRUE; /* XXX Searching for patterns in the title is rather brittle, * but this hack is at least noted in the code that builds * the title to hopefully avoid regressions. */ - if (g_str_has_prefix (line, "DEFAULT ostree:") || /* old format */ - strstr (line, "(ostree") != NULL) /* new format */ + if (g_str_has_prefix (line, "DEFAULT ostree:") || /* old format */ + strstr (line, "(ostree") != NULL) /* new format */ regenerate_default = TRUE; skip = TRUE; } @@ -210,16 +200,14 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader, if (!saw_default) regenerate_default = TRUE; - if (!append_config_from_loader_entries (self, regenerate_default, - bootversion, new_lines, + if (!append_config_from_loader_entries (self, regenerate_default, bootversion, new_lines, cancellable, error)) return FALSE; g_autofree char *new_config_contents = _ostree_sysroot_join_lines (new_lines); if (!glnx_file_replace_contents_at (self->sysroot->sysroot_fd, new_config_path, - (guint8*)new_config_contents, strlen (new_config_contents), - GLNX_FILE_REPLACE_DATASYNC_NEW, - cancellable, error)) + (guint8 *)new_config_contents, strlen (new_config_contents), + GLNX_FILE_REPLACE_DATASYNC_NEW, cancellable, error)) return FALSE; return TRUE; diff --git a/src/libostree/ostree-bootloader-syslinux.h b/src/libostree/ostree-bootloader-syslinux.h index bed9a6c..311e962 100644 --- a/src/libostree/ostree-bootloader-syslinux.h +++ b/src/libostree/ostree-bootloader-syslinux.h @@ -22,13 +22,15 @@ G_BEGIN_DECLS #define OSTREE_TYPE_BOOTLOADER_SYSLINUX (_ostree_bootloader_syslinux_get_type ()) -#define OSTREE_BOOTLOADER_SYSLINUX(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_SYSLINUX, OstreeBootloaderSyslinux)) -#define OSTREE_IS_BOOTLOADER_SYSLINUX(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_SYSLINUX)) +#define OSTREE_BOOTLOADER_SYSLINUX(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_SYSLINUX, OstreeBootloaderSyslinux)) +#define OSTREE_IS_BOOTLOADER_SYSLINUX(inst) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_SYSLINUX)) typedef struct _OstreeBootloaderSyslinux OstreeBootloaderSyslinux; GType _ostree_bootloader_syslinux_get_type (void) G_GNUC_CONST; -OstreeBootloaderSyslinux * _ostree_bootloader_syslinux_new (OstreeSysroot *sysroot); +OstreeBootloaderSyslinux *_ostree_bootloader_syslinux_new (OstreeSysroot *sysroot); G_END_DECLS diff --git a/src/libostree/ostree-bootloader-uboot.c b/src/libostree/ostree-bootloader-uboot.c index fb2c2fc..41280cf 100644 --- a/src/libostree/ostree-bootloader-uboot.c +++ b/src/libostree/ostree-bootloader-uboot.c @@ -21,8 +21,8 @@ #include "config.h" -#include "ostree-sysroot-private.h" #include "ostree-bootloader-uboot.h" +#include "ostree-sysroot-private.h" #include "otutil.h" #include @@ -31,27 +31,27 @@ static const char uboot_config_path[] = "boot/loader/uEnv.txt"; struct _OstreeBootloaderUboot { - GObject parent_instance; + GObject parent_instance; - OstreeSysroot *sysroot; + OstreeSysroot *sysroot; }; typedef GObjectClass OstreeBootloaderUbootClass; static void _ostree_bootloader_uboot_bootloader_iface_init (OstreeBootloaderInterface *iface); G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderUboot, _ostree_bootloader_uboot, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, _ostree_bootloader_uboot_bootloader_iface_init)); + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, + _ostree_bootloader_uboot_bootloader_iface_init)); static gboolean -_ostree_bootloader_uboot_query (OstreeBootloader *bootloader, - gboolean *out_is_active, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_uboot_query (OstreeBootloader *bootloader, gboolean *out_is_active, + GCancellable *cancellable, GError **error) { OstreeBootloaderUboot *self = OSTREE_BOOTLOADER_UBOOT (bootloader); struct stat stbuf; - if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, uboot_config_path, &stbuf, AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, uboot_config_path, &stbuf, + AT_SYMLINK_NOFOLLOW, error)) return FALSE; *out_is_active = (errno == 0); return TRUE; @@ -65,14 +65,11 @@ _ostree_bootloader_uboot_get_name (OstreeBootloader *bootloader) /* Append system's uEnv.txt, if it exists in $deployment/usr/lib/ostree-boot/ */ static gboolean -append_system_uenv (OstreeBootloaderUboot *self, - const char *bootargs, - GPtrArray *new_lines, - GCancellable *cancellable, - GError **error) +append_system_uenv (OstreeBootloaderUboot *self, const char *bootargs, GPtrArray *new_lines, + GCancellable *cancellable, GError **error) { glnx_autofd int uenv_fd = -1; - g_autoptr(OstreeKernelArgs) kargs = NULL; + g_autoptr (OstreeKernelArgs) kargs = NULL; const char *uenv_path = NULL; const char *ostree_arg = NULL; @@ -102,13 +99,11 @@ append_system_uenv (OstreeBootloaderUboot *self, } static gboolean -create_config_from_boot_loader_entries (OstreeBootloaderUboot *self, - int bootversion, - GPtrArray *new_lines, - GCancellable *cancellable, - GError **error) +create_config_from_boot_loader_entries (OstreeBootloaderUboot *self, int bootversion, + GPtrArray *new_lines, GCancellable *cancellable, + GError **error) { - g_autoptr(GPtrArray) boot_loader_configs = NULL; + g_autoptr (GPtrArray) boot_loader_configs = NULL; OstreeBootconfigParser *config; const char *val; @@ -122,7 +117,7 @@ create_config_from_boot_loader_entries (OstreeBootloaderUboot *self, if (i == 0) index_suffix = g_strdup (""); else - index_suffix = g_strdup_printf ("%d", i+1); + index_suffix = g_strdup_printf ("%d", i + 1); config = boot_loader_configs->pdata[i]; val = ostree_bootconfig_parser_get (config, "linux"); @@ -160,32 +155,27 @@ create_config_from_boot_loader_entries (OstreeBootloaderUboot *self, } static gboolean -_ostree_bootloader_uboot_write_config (OstreeBootloader *bootloader, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_uboot_write_config (OstreeBootloader *bootloader, int bootversion, + GPtrArray *new_deployments, GCancellable *cancellable, + GError **error) { OstreeBootloaderUboot *self = OSTREE_BOOTLOADER_UBOOT (bootloader); /* This should follow the symbolic link to the current bootversion. */ - g_autofree char *config_contents = - glnx_file_get_contents_utf8_at (self->sysroot->sysroot_fd, uboot_config_path, NULL, - cancellable, error); + g_autofree char *config_contents = glnx_file_get_contents_utf8_at ( + self->sysroot->sysroot_fd, uboot_config_path, NULL, cancellable, error); if (!config_contents) return FALSE; - g_autoptr(GPtrArray) new_lines = g_ptr_array_new_with_free_func (g_free); - if (!create_config_from_boot_loader_entries (self, bootversion, new_lines, - cancellable, error)) + g_autoptr (GPtrArray) new_lines = g_ptr_array_new_with_free_func (g_free); + if (!create_config_from_boot_loader_entries (self, bootversion, new_lines, cancellable, error)) return FALSE; g_autofree char *new_config_path = g_strdup_printf ("boot/loader.%d/uEnv.txt", bootversion); g_autofree char *new_config_contents = _ostree_sysroot_join_lines (new_lines); if (!glnx_file_replace_contents_at (self->sysroot->sysroot_fd, new_config_path, - (guint8*)new_config_contents, strlen (new_config_contents), - GLNX_FILE_REPLACE_DATASYNC_NEW, - cancellable, error)) + (guint8 *)new_config_contents, strlen (new_config_contents), + GLNX_FILE_REPLACE_DATASYNC_NEW, cancellable, error)) return FALSE; return TRUE; diff --git a/src/libostree/ostree-bootloader-uboot.h b/src/libostree/ostree-bootloader-uboot.h index ac777fa..8e2ed24 100644 --- a/src/libostree/ostree-bootloader-uboot.h +++ b/src/libostree/ostree-bootloader-uboot.h @@ -26,13 +26,15 @@ G_BEGIN_DECLS #define OSTREE_TYPE_BOOTLOADER_UBOOT (_ostree_bootloader_uboot_get_type ()) -#define OSTREE_BOOTLOADER_UBOOT(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_UBOOT, OstreeBootloaderUboot)) -#define OSTREE_IS_BOOTLOADER_UBOOT(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_UBOOT)) +#define OSTREE_BOOTLOADER_UBOOT(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_UBOOT, OstreeBootloaderUboot)) +#define OSTREE_IS_BOOTLOADER_UBOOT(inst) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_UBOOT)) typedef struct _OstreeBootloaderUboot OstreeBootloaderUboot; GType _ostree_bootloader_uboot_get_type (void) G_GNUC_CONST; -OstreeBootloaderUboot * _ostree_bootloader_uboot_new (OstreeSysroot *sysroot); +OstreeBootloaderUboot *_ostree_bootloader_uboot_new (OstreeSysroot *sysroot); G_END_DECLS diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c index 87b9b67..c0a2a14 100644 --- a/src/libostree/ostree-bootloader-zipl.c +++ b/src/libostree/ostree-bootloader-zipl.c @@ -17,24 +17,28 @@ #include "config.h" -#include "ostree-sysroot-private.h" #include "ostree-bootloader-zipl.h" #include "ostree-deployment-private.h" +#include "ostree-libarchive-private.h" +#include "ostree-sysroot-private.h" #include "otutil.h" +#include #include #include -#include -#define SECURE_EXECUTION_SYSFS_FLAG "/sys/firmware/uv/prot_virt_guest" -#define SECURE_EXECUTION_PARTITION "/dev/disk/by-label/se" -#define SECURE_EXECUTION_MOUNTPOINT "/sysroot/se" -#define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sd-boot" -#define SECURE_EXECUTION_HOSTKEY_PATH "/etc/se-hostkeys/" +#define SECURE_EXECUTION_SYSFS_FLAG "/sys/firmware/uv/prot_virt_guest" +#define SECURE_EXECUTION_PARTITION "/dev/disk/by-label/se" +#define SECURE_EXECUTION_MOUNTPOINT "/sysroot/se" +#define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sdboot" +#define SECURE_EXECUTION_HOSTKEY_PATH "/etc/se-hostkeys/" #define SECURE_EXECUTION_HOSTKEY_PREFIX "ibm-z-hostkey" -#define SECURE_EXECUTION_LUKS_ROOT_KEY "/etc/luks/root" -#define SECURE_EXECUTION_LUKS_BOOT_KEY "/etc/luks/boot" -#define SECURE_EXECUTION_LUKS_CONFIG "/etc/crypttab" -#define SECURE_EXECUTION_RAMDISK_TOOL PKGLIBEXECDIR "/s390x-se-luks-gencpio" +#define SECURE_EXECUTION_LUKS_ROOT_KEY "/etc/luks/root" +#define SECURE_EXECUTION_LUKS_BOOT_KEY "/etc/luks/boot" +#define SECURE_EXECUTION_LUKS_CONFIG "/etc/crypttab" + +#if !(defined HAVE_LIBARCHIVE) && defined(__s390x__) +#error libarchive is required for s390x +#endif /* This is specific to zipl today, but in the future we could also * use it for the grub2-mkconfig case. @@ -43,27 +47,27 @@ static const char zipl_requires_execute_path[] = "boot/ostree-bootloader-update. struct _OstreeBootloaderZipl { - GObject parent_instance; + GObject parent_instance; - OstreeSysroot *sysroot; + OstreeSysroot *sysroot; }; typedef GObjectClass OstreeBootloaderZiplClass; static void _ostree_bootloader_zipl_bootloader_iface_init (OstreeBootloaderInterface *iface); G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderZipl, _ostree_bootloader_zipl, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, _ostree_bootloader_zipl_bootloader_iface_init)); + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER, + _ostree_bootloader_zipl_bootloader_iface_init)); static gboolean -_ostree_bootloader_zipl_query (OstreeBootloader *bootloader, - gboolean *out_is_active, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_zipl_query (OstreeBootloader *bootloader, gboolean *out_is_active, + GCancellable *cancellable, GError **error) { - /* We don't auto-detect this one; should be explicitly chosen right now. - * see also https://github.com/coreos/coreos-assembler/pull/849 - */ +#if defined(__s390x__) + *out_is_active = TRUE; +#else *out_is_active = FALSE; +#endif return TRUE; } @@ -74,18 +78,18 @@ _ostree_bootloader_zipl_get_name (OstreeBootloader *bootloader) } static gboolean -_ostree_secure_execution_mount(GError **error) +_ostree_secure_execution_mount (GError **error) { const char *device = realpath (SECURE_EXECUTION_PARTITION, NULL); if (device == NULL) - return glnx_throw_errno_prefix(error, "s390x SE: resolving %s", SECURE_EXECUTION_PARTITION); + return glnx_throw_errno_prefix (error, "s390x SE: resolving %s", SECURE_EXECUTION_PARTITION); if (mount (device, SECURE_EXECUTION_MOUNTPOINT, "ext4", 0, NULL) < 0) return glnx_throw_errno_prefix (error, "s390x SE: Mounting %s", device); return TRUE; } static gboolean -_ostree_secure_execution_umount(GError **error) +_ostree_secure_execution_umount (GError **error) { if (umount (SECURE_EXECUTION_MOUNTPOINT) < 0) return glnx_throw_errno_prefix (error, "s390x SE: Unmounting %s", SECURE_EXECUTION_MOUNTPOINT); @@ -93,33 +97,31 @@ _ostree_secure_execution_umount(GError **error) } static gboolean -_ostree_bootloader_zipl_write_config (OstreeBootloader *bootloader, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_zipl_write_config (OstreeBootloader *bootloader, int bootversion, + GPtrArray *new_deployments, GCancellable *cancellable, + GError **error) { OstreeBootloaderZipl *self = OSTREE_BOOTLOADER_ZIPL (bootloader); /* Write our stamp file */ if (!glnx_file_replace_contents_at (self->sysroot->sysroot_fd, zipl_requires_execute_path, - (guint8*)"", 0, GLNX_FILE_REPLACE_NODATASYNC, - cancellable, error)) + (guint8 *)"", 0, GLNX_FILE_REPLACE_NODATASYNC, cancellable, + error)) return FALSE; return TRUE; } -static gboolean _ostree_secure_execution_is_enabled (gboolean *out_enabled, - GCancellable *cancellable, - GError **error) +static gboolean +_ostree_secure_execution_is_enabled (gboolean *out_enabled, GCancellable *cancellable, + GError **error) { *out_enabled = FALSE; glnx_autofd int fd = -1; if (!ot_openat_ignore_enoent (AT_FDCWD, SECURE_EXECUTION_SYSFS_FLAG, &fd, error)) return FALSE; if (fd == -1) - return TRUE; //ENOENT --> SecureExecution is disabled + return TRUE; // ENOENT --> SecureExecution is disabled g_autofree char *data = glnx_fd_readall_utf8 (fd, NULL, cancellable, error); if (!data) return FALSE; @@ -128,15 +130,15 @@ static gboolean _ostree_secure_execution_is_enabled (gboolean *out_enabled, } static gboolean -_ostree_secure_execution_get_keys (GPtrArray **keys, - GCancellable *cancellable, - GError **error) +_ostree_secure_execution_get_keys (GPtrArray **keys, GCancellable *cancellable, GError **error) { - g_auto (GLnxDirFdIterator) it = { 0,}; - if ( !glnx_dirfd_iterator_init_at (-1, SECURE_EXECUTION_HOSTKEY_PATH, TRUE, &it, error)) + g_auto (GLnxDirFdIterator) it = { + 0, + }; + if (!glnx_dirfd_iterator_init_at (-1, SECURE_EXECUTION_HOSTKEY_PATH, TRUE, &it, error)) return glnx_prefix_error (error, "s390x SE: looking for SE keys"); - g_autoptr(GPtrArray) ret_keys = g_ptr_array_new_with_free_func (g_free); + g_autoptr (GPtrArray) ret_keys = g_ptr_array_new_with_free_func (g_free); while (TRUE) { struct dirent *dent = NULL; @@ -147,7 +149,8 @@ _ostree_secure_execution_get_keys (GPtrArray **keys, break; if (g_str_has_prefix (dent->d_name, SECURE_EXECUTION_HOSTKEY_PREFIX)) - g_ptr_array_add (ret_keys, g_build_filename (SECURE_EXECUTION_HOSTKEY_PATH, dent->d_name, NULL)); + g_ptr_array_add (ret_keys, + g_build_filename (SECURE_EXECUTION_HOSTKEY_PATH, dent->d_name, NULL)); } *keys = g_steal_pointer (&ret_keys); @@ -155,22 +158,19 @@ _ostree_secure_execution_get_keys (GPtrArray **keys, } static gboolean -_ostree_secure_execution_get_bls_config (OstreeBootloaderZipl *self, - int bootversion, - gchar **vmlinuz, - gchar **initramfs, - gchar **options, - GCancellable *cancellable, - GError **error) +_ostree_secure_execution_get_bls_config (OstreeBootloaderZipl *self, int bootversion, + gchar **vmlinuz, gchar **initramfs, gchar **options, + GCancellable *cancellable, GError **error) { g_autoptr (GPtrArray) configs = NULL; - if ( !_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &configs, cancellable, error)) + if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &configs, cancellable, + error)) return glnx_prefix_error (error, "s390x SE: loading bls configs"); if (!configs || configs->len == 0) return glnx_throw (error, "s390x SE: no bls config"); - OstreeBootconfigParser *parser = (OstreeBootconfigParser *) g_ptr_array_index (configs, 0); + OstreeBootconfigParser *parser = (OstreeBootconfigParser *)g_ptr_array_index (configs, 0); const gchar *val = NULL; val = ostree_bootconfig_parser_get (parser, "linux"); @@ -186,7 +186,7 @@ _ostree_secure_execution_get_bls_config (OstreeBootloaderZipl *self, val = ostree_bootconfig_parser_get (parser, "options"); if (!val) return glnx_throw (error, "s390x SE: no \"options\" key in bootloader config"); - *options = g_strdup(val); + *options = g_strdup (val); return TRUE; } @@ -194,74 +194,124 @@ _ostree_secure_execution_get_bls_config (OstreeBootloaderZipl *self, static gboolean _ostree_secure_execution_luks_key_exists (void) { - return (access(SECURE_EXECUTION_LUKS_CONFIG, F_OK) == 0 && - (access(SECURE_EXECUTION_LUKS_ROOT_KEY, F_OK) == 0 || access(SECURE_EXECUTION_LUKS_BOOT_KEY, F_OK) == 0)); + return (access (SECURE_EXECUTION_LUKS_CONFIG, F_OK) == 0 + && access (SECURE_EXECUTION_LUKS_ROOT_KEY, F_OK) == 0 + && access (SECURE_EXECUTION_LUKS_BOOT_KEY, F_OK) == 0); } static gboolean -_ostree_secure_execution_enable_luks(const gchar *oldramfs, - const gchar *newramfs, - GError **error) +_ostree_secure_execution_append_luks_keys (int initrd_fd, GCancellable *cancellable, GError **error) { - const char *const argv[] = {SECURE_EXECUTION_RAMDISK_TOOL, oldramfs, newramfs, NULL}; - g_autofree gchar *out = NULL; - g_autofree gchar *err = NULL; - int status = 0; - if (!g_spawn_sync (NULL, (char**)argv, NULL, G_SPAWN_SEARCH_PATH, - NULL, NULL, &out, &err, &status, error)) - return glnx_prefix_error(error, "s390x SE: spawning %s", SECURE_EXECUTION_RAMDISK_TOOL); - - if (!g_spawn_check_exit_status (status, error)) +#ifdef HAVE_LIBARCHIVE + // appending cpio gzip archive with LUKS keys + g_autoptr (OtAutoArchiveWrite) a = archive_write_new (); + g_assert (a != NULL); + + if (archive_write_set_format_cpio_newc (a) != 0 || archive_write_add_filter_gzip (a) != 0 + || archive_write_open_fd (a, initrd_fd) != 0) + return glnx_prefix_error (error, "s390x SE: initing cpio: %s", archive_error_string (a)); + + const char *files[] = { "/etc", "/etc/luks", SECURE_EXECUTION_LUKS_CONFIG, + SECURE_EXECUTION_LUKS_BOOT_KEY, SECURE_EXECUTION_LUKS_ROOT_KEY }; + for (uint i = 0; i != G_N_ELEMENTS (files); ++i) { - g_printerr("s390x SE: `%s` stdout: %s\n", SECURE_EXECUTION_RAMDISK_TOOL, out); - g_printerr("s390x SE: `%s` stderr: %s\n", SECURE_EXECUTION_RAMDISK_TOOL, err); - return glnx_prefix_error(error, "s390x SE: `%s` failed", SECURE_EXECUTION_RAMDISK_TOOL); + const char *path = files[i]; + struct stat st; + if (stat (path, &st) != 0) + glnx_throw_errno_prefix (error, "s390x SE: stat(%s) failed", path); + + g_autoptr (OtArchiveEntry) ae = archive_entry_new (); + g_assert (ae != NULL); + + archive_entry_copy_stat (ae, &st); + archive_entry_set_pathname (ae, path); + if (archive_write_header (a, ae) != 0) + glnx_prefix_error (error, "s390x SE: writing cpio header: %s", archive_error_string (a)); + + if (S_ISREG (st.st_mode)) + { + ot_journal_print (LOG_INFO, "s390x SE: appending %s to initrd", path); + glnx_autofd int fd = -1; + if (!glnx_openat_rdonly (AT_FDCWD, path, TRUE, &fd, error)) + return glnx_prefix_error (error, "s390x SE: opening %s", path); + g_autoptr (GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error); + if (!data) + return glnx_prefix_error (error, "s390x SE: reading %s", path); + + gsize size = 0; + const char *ptr = (const char *)g_bytes_get_data (data, &size); + ssize_t written = archive_write_data (a, ptr, size); + if (written == -1) + return glnx_prefix_error (error, "s390x SE: writing cpio entry: %s", + archive_error_string (a)); + if (written != size) + return glnx_prefix_error (error, "s390x SE: writing cpio entry %zd != %zu", written, + size); + } } - - ot_journal_print(LOG_INFO, "s390x SE: luks key added to initrd"); + ot_journal_print (LOG_INFO, "s390x SE: luks keys added to initrd"); return TRUE; +#else + return glnx_throw (error, "'libarchive' is required for s390x"); +#endif +} + +static gboolean +_ostree_secure_execution_generate_initrd (const gchar *initrd, GLnxTmpfile *out_initrd, + GCancellable *cancellable, GError **error) +{ + if (!_ostree_secure_execution_luks_key_exists ()) + return glnx_throw (error, "s390x SE: missing luks keys and config"); + + if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, out_initrd, error)) + return glnx_prefix_error (error, "s390x SE: opening new ramdisk"); + { + glnx_autofd int fd = -1; + if (!glnx_openat_rdonly (AT_FDCWD, initrd, TRUE, &fd, error)) + return glnx_prefix_error (error, "s390x SE: opening initrd"); + if (glnx_regfile_copy_bytes (fd, out_initrd->fd, (off_t)-1) < 0) + return glnx_throw_errno_prefix (error, "s390x SE: copying ramdisk"); + } + + return _ostree_secure_execution_append_luks_keys (out_initrd->fd, cancellable, error); } static gboolean -_ostree_secure_execution_generate_sdboot (gchar *vmlinuz, - gchar *initramfs, - gchar *options, - GPtrArray *keys, +_ostree_secure_execution_generate_sdboot (gchar *vmlinuz, gchar *initramfs, gchar *options, + GPtrArray *keys, GCancellable *cancellable, GError **error) { g_assert (vmlinuz && initramfs && options && keys && keys->len); - ot_journal_print(LOG_INFO, "s390x SE: kernel: %s", vmlinuz); - ot_journal_print(LOG_INFO, "s390x SE: initrd: %s", initramfs); - ot_journal_print(LOG_INFO, "s390x SE: kargs: %s", options); + ot_journal_print (LOG_INFO, "s390x SE: kernel: %s", vmlinuz); + ot_journal_print (LOG_INFO, "s390x SE: initrd: %s", initramfs); + ot_journal_print (LOG_INFO, "s390x SE: kargs: %s", options); - pid_t self = getpid(); + pid_t self = getpid (); // Store kernel options to temp file, so `genprotimg` can later embed it - g_auto(GLnxTmpfile) cmdline = { 0, }; + g_auto (GLnxTmpfile) cmdline = { + 0, + }; if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &cmdline, error)) - return glnx_prefix_error(error, "s390x SE: opening cmdline file"); + return glnx_prefix_error (error, "s390x SE: opening cmdline file"); if (glnx_loop_write (cmdline.fd, options, strlen (options)) < 0) - return glnx_throw_errno_prefix (error, "s390x SE: writting cmdline file"); + return glnx_throw_errno_prefix (error, "s390x SE: writing cmdline file"); g_autofree gchar *cmdline_filename = g_strdup_printf ("/proc/%d/fd/%d", self, cmdline.fd); - // Copy initramfs to temp file and embed LUKS key and config into it - g_auto(GLnxTmpfile) ramdisk = { 0, }; - g_autofree gchar *ramdisk_filename = NULL; - if (_ostree_secure_execution_luks_key_exists ()) - { - if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &ramdisk, error)) - return glnx_prefix_error(error, "s390x SE: creating new ramdisk"); - ramdisk_filename = g_strdup_printf ("/proc/%d/fd/%d", self, ramdisk.fd); - if (!_ostree_secure_execution_enable_luks (initramfs, ramdisk_filename, error)) - return FALSE; - } + // Copy initramfs to temp file and embed LUKS keys & config into it + g_auto (GLnxTmpfile) ramdisk = { + 0, + }; + if (!_ostree_secure_execution_generate_initrd (initramfs, &ramdisk, cancellable, error)) + return FALSE; + g_autofree gchar *ramdisk_filename = g_strdup_printf ("/proc/%d/fd/%d", self, ramdisk.fd); - g_autoptr(GPtrArray) argv = g_ptr_array_new (); + g_autoptr (GPtrArray) argv = g_ptr_array_new (); g_ptr_array_add (argv, "genprotimg"); g_ptr_array_add (argv, "-i"); g_ptr_array_add (argv, vmlinuz); g_ptr_array_add (argv, "-r"); - g_ptr_array_add (argv, (ramdisk_filename == NULL) ? initramfs: ramdisk_filename); + g_ptr_array_add (argv, ramdisk_filename); g_ptr_array_add (argv, "-p"); g_ptr_array_add (argv, cmdline_filename); for (guint i = 0; i < keys->len; ++i) @@ -269,7 +319,7 @@ _ostree_secure_execution_generate_sdboot (gchar *vmlinuz, gchar *key = g_ptr_array_index (keys, i); g_ptr_array_add (argv, "-k"); g_ptr_array_add (argv, key); - ot_journal_print(LOG_INFO, "s390x SE: key[%d]: %s", i + 1, key); + ot_journal_print (LOG_INFO, "s390x SE: key[%d]: %s", i + 1, key); } g_ptr_array_add (argv, "--no-verify"); g_ptr_array_add (argv, "-o"); @@ -277,14 +327,14 @@ _ostree_secure_execution_generate_sdboot (gchar *vmlinuz, g_ptr_array_add (argv, NULL); gint status = 0; - if (!g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_SEARCH_PATH, - NULL, NULL, NULL, NULL, &status, error)) - return glnx_prefix_error(error, "s390x SE: spawning genprotimg"); + if (!g_spawn_sync (NULL, (char **)argv->pdata, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, + &status, error)) + return glnx_prefix_error (error, "s390x SE: spawning genprotimg"); if (!g_spawn_check_exit_status (status, error)) - return glnx_prefix_error(error, "s390x SE: `genprotimg` failed"); + return glnx_prefix_error (error, "s390x SE: `genprotimg` failed"); - ot_journal_print(LOG_INFO, "s390x SE: `%s` generated", SECURE_EXECUTION_BOOT_IMAGE); + ot_journal_print (LOG_INFO, "s390x SE: `%s` generated", SECURE_EXECUTION_BOOT_IMAGE); return TRUE; } @@ -292,45 +342,42 @@ static gboolean _ostree_secure_execution_call_zipl (GError **error) { int status = 0; - const char *const zipl_argv[] = {"zipl", "-V", "-t", SECURE_EXECUTION_MOUNTPOINT, "-i", SECURE_EXECUTION_BOOT_IMAGE, NULL}; - if (!g_spawn_sync (NULL, (char**)zipl_argv, NULL, G_SPAWN_SEARCH_PATH, - NULL, NULL, NULL, NULL, &status, error)) - return glnx_prefix_error(error, "s390x SE: spawning zipl"); + const char *const zipl_argv[] = { + "zipl", "-V", "-t", SECURE_EXECUTION_MOUNTPOINT, "-i", SECURE_EXECUTION_BOOT_IMAGE, NULL + }; + if (!g_spawn_sync (NULL, (char **)zipl_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, + &status, error)) + return glnx_prefix_error (error, "s390x SE: spawning zipl"); if (!g_spawn_check_exit_status (status, error)) - return glnx_prefix_error(error, "s390x SE: `zipl` failed"); + return glnx_prefix_error (error, "s390x SE: `zipl` failed"); - ot_journal_print(LOG_INFO, "s390x SE: `sd-boot` zipled"); + ot_journal_print (LOG_INFO, "s390x SE: `sdboot` zipled"); return TRUE; } static gboolean -_ostree_secure_execution_enable (OstreeBootloaderZipl *self, - int bootversion, - GPtrArray *keys, - GCancellable *cancellable, - GError **error) +_ostree_secure_execution_enable (OstreeBootloaderZipl *self, int bootversion, GPtrArray *keys, + GCancellable *cancellable, GError **error) { - g_autofree gchar* vmlinuz = NULL; - g_autofree gchar* initramfs = NULL; - g_autofree gchar* options = NULL; - - gboolean rc = - _ostree_secure_execution_mount (error) && - _ostree_secure_execution_get_bls_config (self, bootversion, &vmlinuz, &initramfs, &options, cancellable, error) && - _ostree_secure_execution_generate_sdboot (vmlinuz, initramfs, options, keys, error) && - _ostree_secure_execution_call_zipl (error) && - _ostree_secure_execution_umount (error); + g_autofree gchar *vmlinuz = NULL; + g_autofree gchar *initramfs = NULL; + g_autofree gchar *options = NULL; + + gboolean rc = _ostree_secure_execution_mount (error) + && _ostree_secure_execution_get_bls_config (self, bootversion, &vmlinuz, &initramfs, + &options, cancellable, error) + && _ostree_secure_execution_generate_sdboot (vmlinuz, initramfs, options, keys, + cancellable, error) + && _ostree_secure_execution_call_zipl (error) + && _ostree_secure_execution_umount (error); return rc; } - static gboolean -_ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, - int bootversion, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, int bootversion, + GCancellable *cancellable, GError **error) { OstreeBootloaderZipl *self = OSTREE_BOOTLOADER_ZIPL (bootloader); @@ -339,7 +386,8 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, */ g_assert (self->sysroot->booted_deployment); - if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, zipl_requires_execute_path, NULL, 0, error)) + if (!glnx_fstatat_allow_noent (self->sysroot->sysroot_fd, zipl_requires_execute_path, NULL, 0, + error)) return FALSE; /* If there's no stamp file, nothing to do */ @@ -348,11 +396,11 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, /* Try with Secure Execution */ gboolean se_enabled = FALSE; - if ( !_ostree_secure_execution_is_enabled (&se_enabled, cancellable, error)) + if (!_ostree_secure_execution_is_enabled (&se_enabled, cancellable, error)) return FALSE; if (se_enabled) { - g_autoptr(GPtrArray) keys = NULL; + g_autoptr (GPtrArray) keys = NULL; if (!_ostree_secure_execution_get_keys (&keys, cancellable, error)) return FALSE; if (!keys || keys->len == 0) @@ -360,10 +408,10 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, return _ostree_secure_execution_enable (self, bootversion, keys, cancellable, error); } /* Fallback to non-SE setup */ - const char *const zipl_argv[] = {"zipl", NULL}; + const char *const zipl_argv[] = { "zipl", NULL }; int estatus; - if (!g_spawn_sync (NULL, (char**)zipl_argv, NULL, G_SPAWN_SEARCH_PATH, - NULL, NULL, NULL, NULL, &estatus, error)) + if (!g_spawn_sync (NULL, (char **)zipl_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, + &estatus, error)) return FALSE; if (!g_spawn_check_exit_status (estatus, error)) return FALSE; diff --git a/src/libostree/ostree-bootloader-zipl.h b/src/libostree/ostree-bootloader-zipl.h index e3f0b2b..97ba7dd 100644 --- a/src/libostree/ostree-bootloader-zipl.h +++ b/src/libostree/ostree-bootloader-zipl.h @@ -22,12 +22,14 @@ G_BEGIN_DECLS #define OSTREE_TYPE_BOOTLOADER_ZIPL (_ostree_bootloader_zipl_get_type ()) -#define OSTREE_BOOTLOADER_ZIPL(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_ZIPL, OstreeBootloaderZipl)) -#define OSTREE_IS_BOOTLOADER_ZIPL(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_ZIPL)) +#define OSTREE_BOOTLOADER_ZIPL(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_ZIPL, OstreeBootloaderZipl)) +#define OSTREE_IS_BOOTLOADER_ZIPL(inst) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_ZIPL)) typedef struct _OstreeBootloaderZipl OstreeBootloaderZipl; GType _ostree_bootloader_zipl_get_type (void) G_GNUC_CONST; -OstreeBootloaderZipl * _ostree_bootloader_zipl_new (OstreeSysroot *sysroot); +OstreeBootloaderZipl *_ostree_bootloader_zipl_new (OstreeSysroot *sysroot); G_END_DECLS diff --git a/src/libostree/ostree-bootloader.c b/src/libostree/ostree-bootloader.c index 785fd23..4fd8c4c 100644 --- a/src/libostree/ostree-bootloader.c +++ b/src/libostree/ostree-bootloader.c @@ -16,6 +16,7 @@ */ #include "config.h" + #include "ostree-bootloader.h" G_DEFINE_INTERFACE (OstreeBootloader, _ostree_bootloader, G_TYPE_OBJECT) @@ -26,12 +27,10 @@ _ostree_bootloader_default_init (OstreeBootloaderInterface *iface) } gboolean -_ostree_bootloader_query (OstreeBootloader *self, - gboolean *out_is_active, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_query (OstreeBootloader *self, gboolean *out_is_active, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE); + g_assert (OSTREE_IS_BOOTLOADER (self)); return OSTREE_BOOTLOADER_GET_IFACE (self)->query (self, out_is_active, cancellable, error); } @@ -42,45 +41,41 @@ _ostree_bootloader_query (OstreeBootloader *self, * Returns: (transfer none): Name of this bootloader */ const char * -_ostree_bootloader_get_name (OstreeBootloader *self) +_ostree_bootloader_get_name (OstreeBootloader *self) { - g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), NULL); + g_assert (OSTREE_IS_BOOTLOADER (self)); return OSTREE_BOOTLOADER_GET_IFACE (self)->get_name (self); } gboolean -_ostree_bootloader_write_config (OstreeBootloader *self, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_write_config (OstreeBootloader *self, int bootversion, + GPtrArray *new_deployments, GCancellable *cancellable, + GError **error) { - g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE); + g_assert (OSTREE_IS_BOOTLOADER (self)); - return OSTREE_BOOTLOADER_GET_IFACE (self)->write_config (self, bootversion, - new_deployments, + return OSTREE_BOOTLOADER_GET_IFACE (self)->write_config (self, bootversion, new_deployments, cancellable, error); } gboolean -_ostree_bootloader_post_bls_sync (OstreeBootloader *self, - int bootversion, - GCancellable *cancellable, - GError **error) +_ostree_bootloader_post_bls_sync (OstreeBootloader *self, int bootversion, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE); + g_assert (OSTREE_IS_BOOTLOADER (self)); if (OSTREE_BOOTLOADER_GET_IFACE (self)->post_bls_sync) - return OSTREE_BOOTLOADER_GET_IFACE (self)->post_bls_sync (self, bootversion, cancellable, error); + return OSTREE_BOOTLOADER_GET_IFACE (self)->post_bls_sync (self, bootversion, cancellable, + error); return TRUE; } gboolean -_ostree_bootloader_is_atomic (OstreeBootloader *self) +_ostree_bootloader_is_atomic (OstreeBootloader *self) { - g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE); + g_assert (OSTREE_IS_BOOTLOADER (self)); if (OSTREE_BOOTLOADER_GET_IFACE (self)->is_atomic) return OSTREE_BOOTLOADER_GET_IFACE (self)->is_atomic (self); diff --git a/src/libostree/ostree-bootloader.h b/src/libostree/ostree-bootloader.h index ca1b453..bb326f5 100644 --- a/src/libostree/ostree-bootloader.h +++ b/src/libostree/ostree-bootloader.h @@ -17,62 +17,52 @@ #pragma once -#include +#include + #include "otutil.h" G_BEGIN_DECLS #define OSTREE_TYPE_BOOTLOADER (_ostree_bootloader_get_type ()) -#define OSTREE_BOOTLOADER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER, OstreeBootloader)) +#define OSTREE_BOOTLOADER(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER, OstreeBootloader)) #define OSTREE_IS_BOOTLOADER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER)) -#define OSTREE_BOOTLOADER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), OSTREE_TYPE_BOOTLOADER, OstreeBootloaderInterface)) +#define OSTREE_BOOTLOADER_GET_IFACE(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), OSTREE_TYPE_BOOTLOADER, OstreeBootloaderInterface)) typedef struct _OstreeBootloader OstreeBootloader; -typedef struct _OstreeBootloaderInterface OstreeBootloaderInterface; +typedef struct _OstreeBootloaderInterface OstreeBootloaderInterface; struct _OstreeBootloaderInterface { GTypeInterface g_iface; /* virtual functions */ - gboolean (* query) (OstreeBootloader *bootloader, - gboolean *out_is_active, - GCancellable *cancellable, - GError **error); - const char * (* get_name) (OstreeBootloader *self); - gboolean (* write_config) (OstreeBootloader *self, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error); - gboolean (* post_bls_sync) (OstreeBootloader *self, - int bootversion, - GCancellable *cancellable, - GError **error); - gboolean (* is_atomic) (OstreeBootloader *self); + gboolean (*query) (OstreeBootloader *bootloader, gboolean *out_is_active, + GCancellable *cancellable, GError **error); + const char *(*get_name) (OstreeBootloader *self); + gboolean (*write_config) (OstreeBootloader *self, int bootversion, GPtrArray *new_deployments, + GCancellable *cancellable, GError **error); + gboolean (*post_bls_sync) (OstreeBootloader *self, int bootversion, GCancellable *cancellable, + GError **error); + gboolean (*is_atomic) (OstreeBootloader *self); }; G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeBootloader, g_object_unref) GType _ostree_bootloader_get_type (void) G_GNUC_CONST; -gboolean _ostree_bootloader_query (OstreeBootloader *bootloader, - gboolean *out_is_active, - GCancellable *cancellable, - GError **error); +gboolean _ostree_bootloader_query (OstreeBootloader *bootloader, gboolean *out_is_active, + GCancellable *cancellable, GError **error); -const char *_ostree_bootloader_get_name (OstreeBootloader *self); +const char *_ostree_bootloader_get_name (OstreeBootloader *self); -gboolean _ostree_bootloader_write_config (OstreeBootloader *self, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error); +gboolean _ostree_bootloader_write_config (OstreeBootloader *self, int bootversion, + GPtrArray *new_deployments, GCancellable *cancellable, + GError **error); -gboolean _ostree_bootloader_post_bls_sync (OstreeBootloader *self, - int bootversion, - GCancellable *cancellable, - GError **error); +gboolean _ostree_bootloader_post_bls_sync (OstreeBootloader *self, int bootversion, + GCancellable *cancellable, GError **error); -gboolean _ostree_bootloader_is_atomic (OstreeBootloader *self); +gboolean _ostree_bootloader_is_atomic (OstreeBootloader *self); G_END_DECLS diff --git a/src/libostree/ostree-chain-input-stream.c b/src/libostree/ostree-chain-input-stream.c index 5ff4392..63f5c1d 100644 --- a/src/libostree/ostree-chain-input-stream.c +++ b/src/libostree/ostree-chain-input-stream.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2011 Colin Walters * Copyright (C) 2022 Igalia S.L. * @@ -22,35 +22,29 @@ #include "ostree-chain-input-stream.h" -enum { +enum +{ PROP_0, PROP_STREAMS }; -struct _OstreeChainInputStreamPrivate { +struct _OstreeChainInputStreamPrivate +{ GPtrArray *streams; guint index; }; G_DEFINE_TYPE_WITH_PRIVATE (OstreeChainInputStream, ostree_chain_input_stream, G_TYPE_INPUT_STREAM) -static void ostree_chain_input_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void ostree_chain_input_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void ostree_chain_input_stream_finalize (GObject *object); -static gssize ostree_chain_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error); -static gboolean ostree_chain_input_stream_close (GInputStream *stream, - GCancellable *cancellable, - GError **error); +static void ostree_chain_input_stream_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void ostree_chain_input_stream_get_property (GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec); +static void ostree_chain_input_stream_finalize (GObject *object); +static gssize ostree_chain_input_stream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error); +static gboolean ostree_chain_input_stream_close (GInputStream *stream, GCancellable *cancellable, + GError **error); static void ostree_chain_input_stream_class_init (OstreeChainInputStreamClass *klass) @@ -60,7 +54,7 @@ ostree_chain_input_stream_class_init (OstreeChainInputStreamClass *klass) gobject_class->get_property = ostree_chain_input_stream_get_property; gobject_class->set_property = ostree_chain_input_stream_set_property; - gobject_class->finalize = ostree_chain_input_stream_finalize; + gobject_class->finalize = ostree_chain_input_stream_finalize; stream_class->read_fn = ostree_chain_input_stream_read; stream_class->close_fn = ostree_chain_input_stream_close; @@ -70,24 +64,18 @@ ostree_chain_input_stream_class_init (OstreeChainInputStreamClass *klass) * * Chain of input streams read in order. */ - g_object_class_install_property (gobject_class, - PROP_STREAMS, - g_param_spec_pointer ("streams", - "", "", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - + g_object_class_install_property ( + gobject_class, PROP_STREAMS, + g_param_spec_pointer ("streams", "", "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } static void -ostree_chain_input_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +ostree_chain_input_stream_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeChainInputStream *self; - + self = OSTREE_CHAIN_INPUT_STREAM (object); switch (prop_id) @@ -102,10 +90,8 @@ ostree_chain_input_stream_set_property (GObject *object, } static void -ostree_chain_input_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +ostree_chain_input_stream_get_property (GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec) { OstreeChainInputStream *self; @@ -126,7 +112,7 @@ ostree_chain_input_stream_finalize (GObject *object) { OstreeChainInputStream *stream; - stream = (OstreeChainInputStream*)(object); + stream = (OstreeChainInputStream *)(object); g_ptr_array_unref (stream->priv->streams); @@ -137,35 +123,29 @@ static void ostree_chain_input_stream_init (OstreeChainInputStream *self) { self->priv = ostree_chain_input_stream_get_instance_private (self); - } OstreeChainInputStream * -ostree_chain_input_stream_new (GPtrArray *streams) +ostree_chain_input_stream_new (GPtrArray *streams) { OstreeChainInputStream *stream; - stream = g_object_new (OSTREE_TYPE_CHAIN_INPUT_STREAM, - "streams", streams, - NULL); + stream = g_object_new (OSTREE_TYPE_CHAIN_INPUT_STREAM, "streams", streams, NULL); - return (OstreeChainInputStream*) (stream); + return (OstreeChainInputStream *)(stream); } static gssize -ostree_chain_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error) +ostree_chain_input_stream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error) { - OstreeChainInputStream *self = (OstreeChainInputStream*) stream; + OstreeChainInputStream *self = (OstreeChainInputStream *)stream; GInputStream *child; gssize res = -1; if (g_cancellable_set_error_if_cancelled (cancellable, error)) return -1; - + if (self->priv->index >= self->priv->streams->len) return 0; @@ -173,11 +153,7 @@ ostree_chain_input_stream_read (GInputStream *stream, while (res == 0 && self->priv->index < self->priv->streams->len) { child = self->priv->streams->pdata[self->priv->index]; - res = g_input_stream_read (child, - buffer, - count, - cancellable, - error); + res = g_input_stream_read (child, buffer, count, cancellable, error); if (res == 0) self->priv->index++; } @@ -186,9 +162,7 @@ ostree_chain_input_stream_read (GInputStream *stream, } static gboolean -ostree_chain_input_stream_close (GInputStream *stream, - GCancellable *cancellable, - GError **error) +ostree_chain_input_stream_close (GInputStream *stream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; OstreeChainInputStream *self = (gpointer)stream; @@ -202,6 +176,6 @@ ostree_chain_input_stream_close (GInputStream *stream, } ret = TRUE; - out: +out: return ret; } diff --git a/src/libostree/ostree-chain-input-stream.h b/src/libostree/ostree-chain-input-stream.h index 539f0eb..d639677 100644 --- a/src/libostree/ostree-chain-input-stream.h +++ b/src/libostree/ostree-chain-input-stream.h @@ -22,20 +22,25 @@ #ifndef __GI_SCANNER__ -#include +#include G_BEGIN_DECLS -#define OSTREE_TYPE_CHAIN_INPUT_STREAM (ostree_chain_input_stream_get_type ()) -#define OSTREE_CHAIN_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStream)) -#define OSTREE_CHAIN_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStreamClass)) -#define OSTREE_IS_CHAIN_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM)) -#define OSTREE_IS_CHAIN_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_CHAIN_INPUT_STREAM)) -#define OSTREE_CHAIN_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStreamClass)) +#define OSTREE_TYPE_CHAIN_INPUT_STREAM (ostree_chain_input_stream_get_type ()) +#define OSTREE_CHAIN_INPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStream)) +#define OSTREE_CHAIN_INPUT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStreamClass)) +#define OSTREE_IS_CHAIN_INPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM)) +#define OSTREE_IS_CHAIN_INPUT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_CHAIN_INPUT_STREAM)) +#define OSTREE_CHAIN_INPUT_STREAM_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStreamClass)) -typedef struct _OstreeChainInputStream OstreeChainInputStream; -typedef struct _OstreeChainInputStreamClass OstreeChainInputStreamClass; -typedef struct _OstreeChainInputStreamPrivate OstreeChainInputStreamPrivate; +typedef struct _OstreeChainInputStream OstreeChainInputStream; +typedef struct _OstreeChainInputStreamClass OstreeChainInputStreamClass; +typedef struct _OstreeChainInputStreamPrivate OstreeChainInputStreamPrivate; struct _OstreeChainInputStream { @@ -59,10 +64,10 @@ struct _OstreeChainInputStreamClass }; _OSTREE_PUBLIC -GType ostree_chain_input_stream_get_type (void) G_GNUC_CONST; +GType ostree_chain_input_stream_get_type (void) G_GNUC_CONST; _OSTREE_PUBLIC -OstreeChainInputStream * ostree_chain_input_stream_new (GPtrArray *streams); +OstreeChainInputStream *ostree_chain_input_stream_new (GPtrArray *streams); G_END_DECLS diff --git a/src/libostree/ostree-checksum-input-stream.c b/src/libostree/ostree-checksum-input-stream.c index 7cdf204..f06a95d 100644 --- a/src/libostree/ostree-checksum-input-stream.c +++ b/src/libostree/ostree-checksum-input-stream.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2011 Colin Walters * Copyright (C) 2022 Igalia S.L. * @@ -22,30 +22,26 @@ #include "ostree-checksum-input-stream.h" -enum { +enum +{ PROP_0, PROP_CHECKSUM }; -struct _OstreeChecksumInputStreamPrivate { +struct _OstreeChecksumInputStreamPrivate +{ GChecksum *checksum; }; -G_DEFINE_TYPE_WITH_PRIVATE (OstreeChecksumInputStream, ostree_checksum_input_stream, G_TYPE_FILTER_INPUT_STREAM) - -static void ostree_checksum_input_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void ostree_checksum_input_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static gssize ostree_checksum_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error); +G_DEFINE_TYPE_WITH_PRIVATE (OstreeChecksumInputStream, ostree_checksum_input_stream, + G_TYPE_FILTER_INPUT_STREAM) + +static void ostree_checksum_input_stream_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void ostree_checksum_input_stream_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); +static gssize ostree_checksum_input_stream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error); static void ostree_checksum_input_stream_class_init (OstreeChecksumInputStreamClass *klass) @@ -63,24 +59,18 @@ ostree_checksum_input_stream_class_init (OstreeChecksumInputStreamClass *klass) * * The checksum that the stream updates. */ - g_object_class_install_property (gobject_class, - PROP_CHECKSUM, - g_param_spec_pointer ("checksum", - "", "", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - + g_object_class_install_property ( + gobject_class, PROP_CHECKSUM, + g_param_spec_pointer ("checksum", "", "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } static void -ostree_checksum_input_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +ostree_checksum_input_stream_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeChecksumInputStream *self; - + self = OSTREE_CHECKSUM_INPUT_STREAM (object); switch (prop_id) @@ -95,10 +85,8 @@ ostree_checksum_input_stream_set_property (GObject *object, } static void -ostree_checksum_input_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +ostree_checksum_input_stream_get_property (GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec) { OstreeChecksumInputStream *self; @@ -121,40 +109,28 @@ ostree_checksum_input_stream_init (OstreeChecksumInputStream *self) } OstreeChecksumInputStream * -ostree_checksum_input_stream_new (GInputStream *base, - GChecksum *checksum) +ostree_checksum_input_stream_new (GInputStream *base, GChecksum *checksum) { - OstreeChecksumInputStream *stream; - - g_return_val_if_fail (G_IS_INPUT_STREAM (base), NULL); + g_assert (G_IS_INPUT_STREAM (base)); - stream = g_object_new (OSTREE_TYPE_CHECKSUM_INPUT_STREAM, - "base-stream", base, - "checksum", checksum, - NULL); + OstreeChecksumInputStream *stream = g_object_new ( + OSTREE_TYPE_CHECKSUM_INPUT_STREAM, "base-stream", base, "checksum", checksum, NULL); - return (OstreeChecksumInputStream*) (stream); + return stream; } static gssize -ostree_checksum_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error) +ostree_checksum_input_stream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error) { - OstreeChecksumInputStream *self = (OstreeChecksumInputStream*) stream; - GFilterInputStream *fself = (GFilterInputStream*) self; + OstreeChecksumInputStream *self = (OstreeChecksumInputStream *)stream; + GFilterInputStream *fself = (GFilterInputStream *)self; gssize res = -1; if (g_cancellable_set_error_if_cancelled (cancellable, error)) return -1; - res = g_input_stream_read (fself->base_stream, - buffer, - count, - cancellable, - error); + res = g_input_stream_read (fself->base_stream, buffer, count, cancellable, error); if (res > 0) g_checksum_update (self->priv->checksum, buffer, res); diff --git a/src/libostree/ostree-checksum-input-stream.h b/src/libostree/ostree-checksum-input-stream.h index 4138cd7..1c5cc37 100644 --- a/src/libostree/ostree-checksum-input-stream.h +++ b/src/libostree/ostree-checksum-input-stream.h @@ -24,16 +24,22 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_CHECKSUM_INPUT_STREAM (ostree_checksum_input_stream_get_type ()) -#define OSTREE_CHECKSUM_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStream)) -#define OSTREE_CHECKSUM_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStreamClass)) -#define OSTREE_IS_CHECKSUM_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM)) -#define OSTREE_IS_CHECKSUM_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_CHECKSUM_INPUT_STREAM)) -#define OSTREE_CHECKSUM_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStreamClass)) +#define OSTREE_TYPE_CHECKSUM_INPUT_STREAM (ostree_checksum_input_stream_get_type ()) +#define OSTREE_CHECKSUM_INPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStream)) +#define OSTREE_CHECKSUM_INPUT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStreamClass)) +#define OSTREE_IS_CHECKSUM_INPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM)) +#define OSTREE_IS_CHECKSUM_INPUT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_CHECKSUM_INPUT_STREAM)) +#define OSTREE_CHECKSUM_INPUT_STREAM_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, \ + OstreeChecksumInputStreamClass)) -typedef struct _OstreeChecksumInputStream OstreeChecksumInputStream; -typedef struct _OstreeChecksumInputStreamClass OstreeChecksumInputStreamClass; -typedef struct _OstreeChecksumInputStreamPrivate OstreeChecksumInputStreamPrivate; +typedef struct _OstreeChecksumInputStream OstreeChecksumInputStream; +typedef struct _OstreeChecksumInputStreamClass OstreeChecksumInputStreamClass; +typedef struct _OstreeChecksumInputStreamPrivate OstreeChecksumInputStreamPrivate; struct _OstreeChecksumInputStream { @@ -57,10 +63,10 @@ struct _OstreeChecksumInputStreamClass }; _OSTREE_PUBLIC -GType ostree_checksum_input_stream_get_type (void) G_GNUC_CONST; +GType ostree_checksum_input_stream_get_type (void) G_GNUC_CONST; _OSTREE_PUBLIC -OstreeChecksumInputStream * ostree_checksum_input_stream_new (GInputStream *stream, - GChecksum *checksum); +OstreeChecksumInputStream *ostree_checksum_input_stream_new (GInputStream *stream, + GChecksum *checksum); G_END_DECLS diff --git a/src/libostree/ostree-cmd-private.c b/src/libostree/ostree-cmd-private.c index ad820fd..239d3cd 100644 --- a/src/libostree/ostree-cmd-private.c +++ b/src/libostree/ostree-cmd-private.c @@ -19,19 +19,21 @@ #include "config.h" +#include "ostree-bootloader-grub2.h" #include "ostree-cmd-private.h" -#include "ostree-repo-private.h" #include "ostree-core-private.h" +#include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" #include "ostree-sysroot-private.h" -#include "ostree-bootloader-grub2.h" #include "otutil.h" -static gboolean -impl_ostree_generate_grub2_config (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error) +static gboolean +impl_ostree_generate_grub2_config (OstreeSysroot *sysroot, int bootversion, int target_fd, + GCancellable *cancellable, GError **error) { - return _ostree_bootloader_grub2_generate_config (sysroot, bootversion, target_fd, cancellable, error); + return _ostree_bootloader_grub2_generate_config (sysroot, bootversion, target_fd, cancellable, + error); } /** @@ -44,14 +46,10 @@ const OstreeCmdPrivateVTable * ostree_cmd__private__ (void) { static OstreeCmdPrivateVTable table = { - _ostree_impl_system_generator, - impl_ostree_generate_grub2_config, - _ostree_repo_static_delta_dump, - _ostree_repo_static_delta_query_exists, - _ostree_repo_static_delta_delete, - _ostree_repo_verify_bindings, - _ostree_sysroot_finalize_staged, - _ostree_sysroot_boot_complete, + _ostree_impl_system_generator, impl_ostree_generate_grub2_config, + _ostree_repo_static_delta_dump, _ostree_repo_static_delta_query_exists, + _ostree_repo_static_delta_delete, _ostree_repo_verify_bindings, + _ostree_sysroot_finalize_staged, _ostree_sysroot_boot_complete, }; return &table; diff --git a/src/libostree/ostree-cmd-private.h b/src/libostree/ostree-cmd-private.h index 17f943c..3b48e6e 100644 --- a/src/libostree/ostree-cmd-private.h +++ b/src/libostree/ostree-cmd-private.h @@ -23,21 +23,31 @@ G_BEGIN_DECLS -gboolean _ostree_impl_system_generator (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, const char *late_dir, GError **error); +gboolean _ostree_impl_system_generator (const char *normal_dir, const char *early_dir, + const char *late_dir, GError **error); -typedef struct { - gboolean (* ostree_system_generator) (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, const char *late_dir, GError **error); - gboolean (* ostree_generate_grub2_config) (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error); - gboolean (* ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error); - gboolean (* ostree_static_delta_query_exists) (OstreeRepo *repo, const char *delta_id, gboolean *out_exists, GCancellable *cancellable, GError **error); - gboolean (* ostree_static_delta_delete) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error); - gboolean (* ostree_repo_verify_bindings) (const char *collection_id, const char *ref_name, GVariant *commit, GError **error); - gboolean (* ostree_finalize_staged) (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); - gboolean (* ostree_boot_complete) (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); +typedef struct +{ + gboolean (*ostree_system_generator) (const char *normal_dir, const char *early_dir, + const char *late_dir, GError **error); + gboolean (*ostree_generate_grub2_config) (OstreeSysroot *sysroot, int bootversion, int target_fd, + GCancellable *cancellable, GError **error); + gboolean (*ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, + GCancellable *cancellable, GError **error); + gboolean (*ostree_static_delta_query_exists) (OstreeRepo *repo, const char *delta_id, + gboolean *out_exists, GCancellable *cancellable, + GError **error); + gboolean (*ostree_static_delta_delete) (OstreeRepo *repo, const char *delta_id, + GCancellable *cancellable, GError **error); + gboolean (*ostree_repo_verify_bindings) (const char *collection_id, const char *ref_name, + GVariant *commit, GError **error); + gboolean (*ostree_finalize_staged) (OstreeSysroot *sysroot, GCancellable *cancellable, + GError **error); + gboolean (*ostree_boot_complete) (OstreeSysroot *sysroot, GCancellable *cancellable, + GError **error); } OstreeCmdPrivateVTable; /* Note this not really "public", we just export the symbol, but not the header */ -_OSTREE_PUBLIC const OstreeCmdPrivateVTable * -ostree_cmd__private__ (void); +_OSTREE_PUBLIC const OstreeCmdPrivateVTable *ostree_cmd__private__ (void); G_END_DECLS diff --git a/src/libostree/ostree-content-writer.c b/src/libostree/ostree-content-writer.c index fa4180a..bbca287 100644 --- a/src/libostree/ostree-content-writer.c +++ b/src/libostree/ostree-content-writer.c @@ -1,4 +1,4 @@ -/* +/* * SPDX-License-Identifier: LGPL-2.0+ * * This library is free software; you can redistribute it and/or @@ -17,9 +17,9 @@ #include "config.h" +#include "ostree-autocleanups.h" #include "ostree-content-writer.h" #include "ostree-repo-private.h" -#include "ostree-autocleanups.h" struct _OstreeContentWriter { @@ -31,23 +31,19 @@ struct _OstreeContentWriter G_DEFINE_TYPE (OstreeContentWriter, ostree_content_writer, G_TYPE_OUTPUT_STREAM) -static void ostree_content_writer_finalize (GObject *object); -static gssize ostree_content_writer_write (GOutputStream *stream, - const void *buffer, - gsize count, - GCancellable *cancellable, - GError **error); -static gboolean ostree_content_writer_close (GOutputStream *stream, - GCancellable *cancellable, - GError **error); +static void ostree_content_writer_finalize (GObject *object); +static gssize ostree_content_writer_write (GOutputStream *stream, const void *buffer, gsize count, + GCancellable *cancellable, GError **error); +static gboolean ostree_content_writer_close (GOutputStream *stream, GCancellable *cancellable, + GError **error); static void ostree_content_writer_class_init (OstreeContentWriterClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); - - gobject_class->finalize = ostree_content_writer_finalize; + + gobject_class->finalize = ostree_content_writer_finalize; stream_class->write_fn = ostree_content_writer_write; stream_class->close_fn = ostree_content_writer_close; @@ -58,7 +54,7 @@ ostree_content_writer_finalize (GObject *object) { OstreeContentWriter *stream; - stream = (OstreeContentWriter*)(object); + stream = (OstreeContentWriter *)(object); g_clear_object (&stream->repo); _ostree_repo_bare_content_cleanup (&stream->output); @@ -70,19 +66,13 @@ static void ostree_content_writer_init (OstreeContentWriter *self) { self->output.initialized = FALSE; - } +} OstreeContentWriter * -_ostree_content_writer_new (OstreeRepo *repo, - const char *checksum, - guint uid, - guint gid, - guint mode, - guint64 content_len, - GVariant *xattrs, - GError **error) +_ostree_content_writer_new (OstreeRepo *repo, const char *checksum, guint uid, guint gid, + guint mode, guint64 content_len, GVariant *xattrs, GError **error) { - g_autoptr(OstreeContentWriter) stream = g_object_new (OSTREE_TYPE_CONTENT_WRITER, NULL); + g_autoptr (OstreeContentWriter) stream = g_object_new (OSTREE_TYPE_CONTENT_WRITER, NULL); stream->repo = g_object_ref (repo); if (!_ostree_repo_bare_content_open (stream->repo, checksum, content_len, uid, gid, mode, xattrs, &stream->output, NULL, error)) @@ -91,27 +81,22 @@ _ostree_content_writer_new (OstreeRepo *repo, } static gssize -ostree_content_writer_write (GOutputStream *stream, - const void *buffer, - gsize count, - GCancellable *cancellable, - GError **error) +ostree_content_writer_write (GOutputStream *stream, const void *buffer, gsize count, + GCancellable *cancellable, GError **error) { - OstreeContentWriter *self = (OstreeContentWriter*) stream; + OstreeContentWriter *self = (OstreeContentWriter *)stream; if (g_cancellable_set_error_if_cancelled (cancellable, error)) return -1; - if (!_ostree_repo_bare_content_write (self->repo, &self->output, - buffer, count, cancellable, error)) + if (!_ostree_repo_bare_content_write (self->repo, &self->output, buffer, count, cancellable, + error)) return -1; return count; } static gboolean -ostree_content_writer_close (GOutputStream *stream, - GCancellable *cancellable, - GError **error) +ostree_content_writer_close (GOutputStream *stream, GCancellable *cancellable, GError **error) { /* We don't expect people to invoke close() - they need to call finish() * to get the checksum. We'll clean up in finalize anyways if need be. @@ -129,11 +114,9 @@ ostree_content_writer_close (GOutputStream *stream, * Returns: (transfer full): Checksum, or %NULL on error */ char * -ostree_content_writer_finish (OstreeContentWriter *self, - GCancellable *cancellable, - GError **error) +ostree_content_writer_finish (OstreeContentWriter *self, GCancellable *cancellable, GError **error) { - char actual_checksum[OSTREE_SHA256_STRING_LEN+1]; + char actual_checksum[OSTREE_SHA256_STRING_LEN + 1]; if (!_ostree_repo_bare_content_commit (self->repo, &self->output, actual_checksum, sizeof (actual_checksum), cancellable, error)) return NULL; diff --git a/src/libostree/ostree-content-writer.h b/src/libostree/ostree-content-writer.h index 219860d..26a17b7 100644 --- a/src/libostree/ostree-content-writer.h +++ b/src/libostree/ostree-content-writer.h @@ -24,11 +24,12 @@ G_BEGIN_DECLS #define OSTREE_TYPE_CONTENT_WRITER (ostree_content_writer_get_type ()) -_OSTREE_PUBLIC G_DECLARE_FINAL_TYPE (OstreeContentWriter, ostree_content_writer, OSTREE, CONTENT_WRITER, GOutputStream) +_OSTREE_PUBLIC +G_DECLARE_FINAL_TYPE (OstreeContentWriter, ostree_content_writer, OSTREE, CONTENT_WRITER, + GOutputStream) _OSTREE_PUBLIC -char * ostree_content_writer_finish (OstreeContentWriter *self, - GCancellable *cancellable, - GError **error); +char *ostree_content_writer_finish (OstreeContentWriter *self, GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/src/libostree/ostree-core-private.h b/src/libostree/ostree-core-private.h index 2bd2f98..3c4b391 100644 --- a/src/libostree/ostree-core-private.h +++ b/src/libostree/ostree-core-private.h @@ -34,6 +34,11 @@ G_BEGIN_DECLS #define DEFAULT_DIRECTORY_MODE 0775 #define DEFAULT_REGFILE_MODE 0660 +/* This exists in glibc's sys/stat.h, but not on musl */ +#ifndef ALLPERMS +#define ALLPERMS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) +#endif + /* This file contains private implementation data format definitions * read by multiple implementation .c files. */ @@ -41,7 +46,7 @@ G_BEGIN_DECLS /* * File objects are stored as a stream, with one #GVariant header, * followed by content. - * + * * The file header is of the following form: * * <BE guint32 containing variant length> @@ -49,7 +54,7 @@ G_BEGIN_DECLS * u - gid * u - mode * u - rdev (must be 0) - * s - symlink target + * s - symlink target * a(ayay) - xattrs * * Then the rest of the stream is data. @@ -66,37 +71,30 @@ G_BEGIN_DECLS * u - gid * u - mode * u - rdev (must be 0) - * s - symlink target + * s - symlink target * a(ayay) - xattrs * --- * zlib-compressed data */ #define _OSTREE_ZLIB_FILE_HEADER_GVARIANT_FORMAT G_VARIANT_TYPE ("(tuuuusa(ayay))") +GBytes *_ostree_file_header_new (GFileInfo *file_info, GVariant *xattrs); -GBytes *_ostree_file_header_new (GFileInfo *file_info, - GVariant *xattrs); - -GBytes *_ostree_zlib_file_header_new (GFileInfo *file_info, - GVariant *xattrs); +GBytes *_ostree_zlib_file_header_new (GFileInfo *file_info, GVariant *xattrs); -gboolean -_ostree_make_temporary_symlink_at (int tmp_dirfd, - const char *target, - char **out_name, - GCancellable *cancellable, - GError **error); +gboolean _ostree_make_temporary_symlink_at (int tmp_dirfd, const char *target, char **out_name, + GCancellable *cancellable, GError **error); -GFileInfo * _ostree_stbuf_to_gfileinfo (const struct stat *stbuf); -void _ostree_gfileinfo_to_stbuf (GFileInfo *file_info, struct stat *out_stbuf); +GFileInfo *_ostree_stbuf_to_gfileinfo (const struct stat *stbuf); +void _ostree_gfileinfo_to_stbuf (GFileInfo *file_info, struct stat *out_stbuf); gboolean _ostree_gfileinfo_equal (GFileInfo *a, GFileInfo *b); gboolean _ostree_stbuf_equal (struct stat *stbuf_a, struct stat *stbuf_b); -GFileInfo * _ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid); +GFileInfo *_ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid); static inline void _ostree_checksum_inplace_from_bytes_v (GVariant *csum_v, char *buf) { - const guint8*csum = ostree_checksum_bytes_peek (csum_v); + const guint8 *csum = ostree_checksum_bytes_peek (csum_v); g_assert (csum); ostree_checksum_inplace_from_bytes (csum, buf); } @@ -109,84 +107,49 @@ _ostree_checksum_inplace_from_bytes_v (GVariant *csum_v, char *buf) /* GVariant format for ostree.sizes metadata entries. */ #define _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE "ay" -char * -_ostree_get_relative_object_path (const char *checksum, - OstreeObjectType type, - gboolean compressed); +char *_ostree_get_relative_object_path (const char *checksum, OstreeObjectType type, + gboolean compressed); +char *_ostree_get_relative_static_delta_path (const char *from, const char *to, const char *target); -char * -_ostree_get_relative_static_delta_path (const char *from, - const char *to, - const char *target); +char *_ostree_get_relative_static_delta_superblock_path (const char *from, const char *to); -char * -_ostree_get_relative_static_delta_superblock_path (const char *from, - const char *to); +char *_ostree_get_relative_static_delta_detachedmeta_path (const char *from, const char *to); -char * -_ostree_get_relative_static_delta_detachedmeta_path (const char *from, - const char *to); +char *_ostree_get_relative_static_delta_part_path (const char *from, const char *to, guint i); -char * -_ostree_get_relative_static_delta_part_path (const char *from, - const char *to, - guint i); +char *_ostree_get_relative_static_delta_index_path (const char *to); -char * -_ostree_get_relative_static_delta_index_path (const char *to); - -static inline char * _ostree_get_commitpartial_path (const char *checksum) +static inline char * +_ostree_get_commitpartial_path (const char *checksum) { return g_strconcat ("state/", checksum, ".commitpartial", NULL); } -gboolean -_ostree_validate_ref_fragment (const char *fragment, - GError **error); - +gboolean _ostree_validate_ref_fragment (const char *fragment, GError **error); -gboolean -_ostree_validate_bareuseronly_mode (guint32 mode, - const char *checksum, - GError **error); +gboolean _ostree_validate_bareuseronly_mode (guint32 mode, const char *checksum, GError **error); static inline gboolean -_ostree_validate_bareuseronly_mode_finfo (GFileInfo *finfo, - const char *checksum, - GError **error) +_ostree_validate_bareuseronly_mode_finfo (GFileInfo *finfo, const char *checksum, GError **error) { const guint32 content_mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode"); return _ostree_validate_bareuseronly_mode (content_mode, checksum, error); } -gboolean -_ostree_compare_object_checksum (OstreeObjectType objtype, - const char *expected, - const char *actual, - GError **error); +gboolean _ostree_compare_object_checksum (OstreeObjectType objtype, const char *expected, + const char *actual, GError **error); -gboolean -_ostree_parse_delta_name (const char *delta_name, - char **out_from, - char **out_to, - GError **error); +gboolean _ostree_parse_delta_name (const char *delta_name, char **out_from, char **out_to, + GError **error); -void -_ostree_loose_path (char *buf, - const char *checksum, - OstreeObjectType objtype, - OstreeRepoMode repo_mode); +void _ostree_loose_path (char *buf, const char *checksum, OstreeObjectType objtype, + OstreeRepoMode repo_mode); -gboolean _ostree_validate_structureof_metadata (OstreeObjectType objtype, - GVariant *commit, - GError **error); - -gboolean -_ostree_verify_metadata_object (OstreeObjectType objtype, - const char *expected_checksum, - GVariant *metadata, - GError **error); +gboolean _ostree_validate_structureof_metadata (OstreeObjectType objtype, GVariant *commit, + GError **error); +gboolean _ostree_verify_metadata_object (OstreeObjectType objtype, const char *expected_checksum, + GVariant *metadata, GError **error); #define _OSTREE_METADATA_GPGSIGS_NAME "ostree.gpgsigs" #define _OSTREE_METADATA_GPGSIGS_TYPE G_VARIANT_TYPE ("aay") @@ -194,37 +157,24 @@ _ostree_verify_metadata_object (OstreeObjectType objtype, static inline gboolean _ostree_repo_mode_is_bare (OstreeRepoMode mode) { - return - mode == OSTREE_REPO_MODE_BARE || - mode == OSTREE_REPO_MODE_BARE_USER || - mode == OSTREE_REPO_MODE_BARE_USER_ONLY || - mode == OSTREE_REPO_MODE_BARE_SPLIT_XATTRS; + return mode == OSTREE_REPO_MODE_BARE || mode == OSTREE_REPO_MODE_BARE_USER + || mode == OSTREE_REPO_MODE_BARE_USER_ONLY || mode == OSTREE_REPO_MODE_BARE_SPLIT_XATTRS; } #ifndef OSTREE_DISABLE_GPGME -GVariant * -_ostree_detached_metadata_append_gpg_sig (GVariant *existing_metadata, - GBytes *signature_bytes); +GVariant *_ostree_detached_metadata_append_gpg_sig (GVariant *existing_metadata, + GBytes *signature_bytes); #endif -GFile * -_ostree_get_default_sysroot_path (void); +GFile *_ostree_get_default_sysroot_path (void); _OSTREE_PUBLIC -gboolean -_ostree_raw_file_to_archive_stream (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - guint compression_level, - GInputStream **out_input, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_compare_timestamps (const char *current_rev, - guint64 current_ts, - const char *new_rev, - guint64 new_ts, - GError **error); +gboolean _ostree_raw_file_to_archive_stream (GInputStream *input, GFileInfo *file_info, + GVariant *xattrs, guint compression_level, + GInputStream **out_input, GCancellable *cancellable, + GError **error); + +gboolean _ostree_compare_timestamps (const char *current_rev, guint64 current_ts, + const char *new_rev, guint64 new_ts, GError **error); G_END_DECLS diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 56b381d..b6d2134 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -22,39 +22,38 @@ #include "config.h" -#include -#include -#include -#include -#include #include "libglnx.h" -#include "ostree.h" -#include "ostree-core-private.h" #include "ostree-chain-input-stream.h" +#include "ostree-core-private.h" #include "ostree-varint.h" +#include "ostree.h" #include "otutil.h" +#include +#include +#include +#include +#include /* Generic ABI checks */ -G_STATIC_ASSERT(OSTREE_REPO_MODE_BARE == 0); -G_STATIC_ASSERT(OSTREE_REPO_MODE_ARCHIVE_Z2 == 1); -G_STATIC_ASSERT(OSTREE_REPO_MODE_ARCHIVE == OSTREE_REPO_MODE_ARCHIVE_Z2); -G_STATIC_ASSERT(OSTREE_REPO_MODE_BARE_USER == 2); -G_STATIC_ASSERT(OSTREE_REPO_MODE_BARE_USER_ONLY == 3); -G_STATIC_ASSERT(OSTREE_REPO_MODE_BARE_SPLIT_XATTRS == 4); +G_STATIC_ASSERT (OSTREE_REPO_MODE_BARE == 0); +G_STATIC_ASSERT (OSTREE_REPO_MODE_ARCHIVE_Z2 == 1); +G_STATIC_ASSERT (OSTREE_REPO_MODE_ARCHIVE == OSTREE_REPO_MODE_ARCHIVE_Z2); +G_STATIC_ASSERT (OSTREE_REPO_MODE_BARE_USER == 2); +G_STATIC_ASSERT (OSTREE_REPO_MODE_BARE_USER_ONLY == 3); +G_STATIC_ASSERT (OSTREE_REPO_MODE_BARE_SPLIT_XATTRS == 4); static GBytes *variant_to_lenprefixed_buffer (GVariant *variant); #define ALIGN_VALUE(this, boundary) \ - (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + ((((unsigned long)(this)) + (((unsigned long)(boundary)) - 1)) \ + & (~(((unsigned long)(boundary)) - 1))) /* Return a copy of @input suitable for addition to * a GError message; newlines are quashed, the value * is forced to be UTF-8, is truncated to @maxlen (if maxlen != -1). */ static char * -quash_string_for_error_message (const char *input, - ssize_t len, - ssize_t maxlen) +quash_string_for_error_message (const char *input, ssize_t len, ssize_t maxlen) { if (len == -1) len = strlen (input); @@ -81,16 +80,10 @@ quash_string_for_error_message (const char *input, return buf; } -static gboolean -file_header_parse (GVariant *metadata, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GError **error); -static gboolean -zlib_file_header_parse (GVariant *metadata, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GError **error); +static gboolean file_header_parse (GVariant *metadata, GFileInfo **out_file_info, + GVariant **out_xattrs, GError **error); +static gboolean zlib_file_header_parse (GVariant *metadata, GFileInfo **out_file_info, + GVariant **out_xattrs, GError **error); /** * SECTION:ostree-core @@ -139,8 +132,7 @@ ostree_metadata_variant_type (OstreeObjectType objtype) * Returns: %TRUE if @sha256 is a valid checksum string, %FALSE otherwise */ gboolean -ostree_validate_checksum_string (const char *sha256, - GError **error) +ostree_validate_checksum_string (const char *sha256, GError **error) { return ostree_validate_structureof_checksum_string (sha256, error); } @@ -169,21 +161,19 @@ ostree_validate_checksum_string (const char *sha256, * Returns: %TRUE on successful parsing, %FALSE otherwise */ gboolean -ostree_parse_refspec (const char *refspec, - char **out_remote, - char **out_ref, - GError **error) +ostree_parse_refspec (const char *refspec, char **out_remote, char **out_ref, GError **error) { static GRegex *regex; static gsize regex_initialized; if (g_once_init_enter (®ex_initialized)) { - regex = g_regex_new ("^(" OSTREE_REMOTE_NAME_REGEXP ":)?(" OSTREE_REF_REGEXP ")$", 0, 0, NULL); + regex + = g_regex_new ("^(" OSTREE_REMOTE_NAME_REGEXP ":)?(" OSTREE_REF_REGEXP ")$", 0, 0, NULL); g_assert (regex); g_once_init_leave (®ex_initialized, 1); } - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; if (!g_regex_match (regex, refspec, 0, &match)) return glnx_throw (error, "Invalid refspec %s", refspec); @@ -195,7 +185,7 @@ ostree_parse_refspec (const char *refspec, else { /* Trim the : */ - remote[strlen(remote)-1] = '\0'; + remote[strlen (remote) - 1] = '\0'; } if (out_remote) @@ -206,8 +196,7 @@ ostree_parse_refspec (const char *refspec, } gboolean -_ostree_validate_ref_fragment (const char *fragment, - GError **error) +_ostree_validate_ref_fragment (const char *fragment, GError **error) { static GRegex *regex; static gsize regex_initialized; @@ -218,7 +207,7 @@ _ostree_validate_ref_fragment (const char *fragment, g_once_init_leave (®ex_initialized, 1); } - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; if (!g_regex_match (regex, fragment, 0, &match)) return glnx_throw (error, "Invalid ref fragment '%s'", fragment); @@ -233,10 +222,9 @@ _ostree_validate_ref_fragment (const char *fragment, * Returns: %TRUE if @rev is a valid ref string */ gboolean -ostree_validate_rev (const char *rev, - GError **error) +ostree_validate_rev (const char *rev, GError **error) { - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; static gsize regex_initialized; static GRegex *regex; @@ -262,10 +250,9 @@ ostree_validate_rev (const char *rev, * Since: 2017.8 */ gboolean -ostree_validate_remote_name (const char *remote_name, - GError **error) +ostree_validate_remote_name (const char *remote_name, GError **error) { - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; static gsize regex_initialized; static GRegex *regex; @@ -321,8 +308,7 @@ ostree_validate_collection_id (const char *collection_id, GError **error) * as @xattrs (which if NULL, is taken to be the empty set). */ GBytes * -_ostree_file_header_new (GFileInfo *file_info, - GVariant *xattrs) +_ostree_file_header_new (GFileInfo *file_info, GVariant *xattrs) { guint32 uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid"); @@ -335,13 +321,13 @@ _ostree_file_header_new (GFileInfo *file_info, else symlink_target = ""; - g_autoptr(GVariant) tmp_xattrs = NULL; + g_autoptr (GVariant) tmp_xattrs = NULL; if (xattrs == NULL) tmp_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); - g_autoptr(GVariant) ret = g_variant_new ("(uuuus@a(ayay))", GUINT32_TO_BE (uid), - GUINT32_TO_BE (gid), GUINT32_TO_BE (mode), 0, - symlink_target, xattrs ?: tmp_xattrs); + g_autoptr (GVariant) ret + = g_variant_new ("(uuuus@a(ayay))", GUINT32_TO_BE (uid), GUINT32_TO_BE (gid), + GUINT32_TO_BE (mode), 0, symlink_target, xattrs ?: tmp_xattrs); return variant_to_lenprefixed_buffer (g_variant_ref_sink (ret)); } @@ -352,10 +338,9 @@ _ostree_file_header_new (GFileInfo *file_info, * user.ostreemeta xattr. */ GBytes * -_ostree_zlib_file_header_new (GFileInfo *file_info, - GVariant *xattrs) +_ostree_zlib_file_header_new (GFileInfo *file_info, GVariant *xattrs) { - guint64 size = g_file_info_get_size (file_info); + guint64 size = 0; guint32 uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid"); guint32 gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid"); guint32 mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); @@ -366,14 +351,16 @@ _ostree_zlib_file_header_new (GFileInfo *file_info, else symlink_target = ""; - g_autoptr(GVariant) tmp_xattrs = NULL; + if (g_file_info_has_attribute (file_info, "standard::size")) + size = g_file_info_get_size (file_info); + + g_autoptr (GVariant) tmp_xattrs = NULL; if (xattrs == NULL) tmp_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); - g_autoptr(GVariant) ret = g_variant_new ("(tuuuus@a(ayay))", - GUINT64_TO_BE (size), GUINT32_TO_BE (uid), - GUINT32_TO_BE (gid), GUINT32_TO_BE (mode), 0, - symlink_target, xattrs ?: tmp_xattrs); + g_autoptr (GVariant) ret = g_variant_new ( + "(tuuuus@a(ayay))", GUINT64_TO_BE (size), GUINT32_TO_BE (uid), GUINT32_TO_BE (gid), + GUINT32_TO_BE (mode), 0, symlink_target, xattrs ?: tmp_xattrs); return variant_to_lenprefixed_buffer (g_variant_ref_sink (ret)); } @@ -384,27 +371,27 @@ static GBytes * variant_to_lenprefixed_buffer (GVariant *variant) { /* This string is really a binary memory buffer */ - g_autoptr(GString) buf = g_string_new (NULL); + g_autoptr (GString) buf = g_string_new (NULL); /* Write variant size */ const guint64 variant_size = g_variant_get_size (variant); g_assert (variant_size < G_MAXUINT32); - const guint32 variant_size_u32_be = GUINT32_TO_BE((guint32) variant_size); + const guint32 variant_size_u32_be = GUINT32_TO_BE ((guint32)variant_size); - g_string_append_len (buf, (char*)&variant_size_u32_be, sizeof (variant_size_u32_be)); + g_string_append_len (buf, (char *)&variant_size_u32_be, sizeof (variant_size_u32_be)); - /* Write NULs for alignment. At the moment this is a constant 4 bytes (i.e. - * align to 8, since the length is 4 bytes). If we ever change this, the - * logic is here: - */ - // const gsize alignment_offset = sizeof (variant_size_u32_be); - // const guint bits = alignment_offset & 7; /* mod 8 */ - // const guint padding_len = alignment - bits; - #define padding_len sizeof(guint32) - const guchar padding_nuls[padding_len] = {0, 0, 0, 0}; - g_string_append_len (buf, (char*)padding_nuls, padding_len); - #undef padding_len - - g_string_append_len (buf, (char*)g_variant_get_data (variant), g_variant_get_size (variant)); +/* Write NULs for alignment. At the moment this is a constant 4 bytes (i.e. + * align to 8, since the length is 4 bytes). If we ever change this, the + * logic is here: + */ +// const gsize alignment_offset = sizeof (variant_size_u32_be); +// const guint bits = alignment_offset & 7; /* mod 8 */ +// const guint padding_len = alignment - bits; +#define padding_len sizeof (guint32) + const guchar padding_nuls[padding_len] = { 0, 0, 0, 0 }; + g_string_append_len (buf, (char *)padding_nuls, padding_len); +#undef padding_len + + g_string_append_len (buf, (char *)g_variant_get_data (variant), g_variant_get_size (variant)); return g_string_free_to_bytes (g_steal_pointer (&buf)); } @@ -416,14 +403,13 @@ variant_to_lenprefixed_buffer (GVariant *variant) * Combines @file_header and @input into a single stream. */ static GInputStream * -header_and_input_to_stream (GBytes *file_header, - GInputStream *input) +header_and_input_to_stream (GBytes *file_header, GInputStream *input) { /* Our result stream chain */ - g_autoptr(GPtrArray) streams = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); + g_autoptr (GPtrArray) streams = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); /* Append the header to the chain */ - g_autoptr(GInputStream) header_in_stream = g_memory_input_stream_new_from_bytes (file_header); + g_autoptr (GInputStream) header_in_stream = g_memory_input_stream_new_from_bytes (file_header); g_ptr_array_add (streams, g_object_ref (header_in_stream)); @@ -432,27 +418,23 @@ header_and_input_to_stream (GBytes *file_header, g_ptr_array_add (streams, g_object_ref (input)); /* Return the result stream */ - return (GInputStream*)ostree_chain_input_stream_new (streams); + return (GInputStream *)ostree_chain_input_stream_new (streams); } /* Convert file metadata + file content into an archive-format stream. */ gboolean -_ostree_raw_file_to_archive_stream (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - guint compression_level, - GInputStream **out_input, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GInputStream) zlib_input = NULL; +_ostree_raw_file_to_archive_stream (GInputStream *input, GFileInfo *file_info, GVariant *xattrs, + guint compression_level, GInputStream **out_input, + GCancellable *cancellable, GError **error) +{ + g_autoptr (GInputStream) zlib_input = NULL; if (input != NULL) { - g_autoptr(GConverter) zlib_compressor = - G_CONVERTER (g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW, compression_level)); + g_autoptr (GConverter) zlib_compressor + = G_CONVERTER (g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW, compression_level)); zlib_input = g_converter_input_stream_new (input, zlib_compressor); } - g_autoptr(GBytes) file_header = _ostree_zlib_file_header_new (file_info, xattrs); + g_autoptr (GBytes) file_header = _ostree_zlib_file_header_new (file_info, xattrs); *out_input = header_and_input_to_stream (file_header, zlib_input); return TRUE; } @@ -472,16 +454,13 @@ _ostree_raw_file_to_archive_stream (GInputStream *input, * Since: 2016.6 */ gboolean -ostree_raw_file_to_archive_z2_stream (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - GInputStream **out_input, - GCancellable *cancellable, - GError **error) +ostree_raw_file_to_archive_z2_stream (GInputStream *input, GFileInfo *file_info, GVariant *xattrs, + GInputStream **out_input, GCancellable *cancellable, + GError **error) { return _ostree_raw_file_to_archive_stream (input, file_info, xattrs, - OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL, - out_input, cancellable, error); + OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL, out_input, + cancellable, error); } /** @@ -503,25 +482,21 @@ ostree_raw_file_to_archive_z2_stream (GInputStream *input, * Since: 2017.3 */ gboolean -ostree_raw_file_to_archive_z2_stream_with_options (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - GVariant *options, - GInputStream **out_input, - GCancellable *cancellable, - GError **error) +ostree_raw_file_to_archive_z2_stream_with_options (GInputStream *input, GFileInfo *file_info, + GVariant *xattrs, GVariant *options, + GInputStream **out_input, + GCancellable *cancellable, GError **error) { gint compression_level = -1; if (options) - (void) g_variant_lookup (options, "compression-level", "i", &compression_level); + (void)g_variant_lookup (options, "compression-level", "i", &compression_level); if (compression_level < 0) compression_level = OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL; - return _ostree_raw_file_to_archive_stream (input, file_info, xattrs, - compression_level, - out_input, cancellable, error); + return _ostree_raw_file_to_archive_stream (input, file_info, xattrs, compression_level, out_input, + cancellable, error); } /** @@ -539,18 +514,16 @@ ostree_raw_file_to_archive_z2_stream_with_options (GInputStream *input, * for writing data to an #OstreeRepo. */ gboolean -ostree_raw_file_to_content_stream (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - GInputStream **out_input, - guint64 *out_length, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GBytes) file_header = _ostree_file_header_new (file_info, xattrs); +ostree_raw_file_to_content_stream (GInputStream *input, GFileInfo *file_info, GVariant *xattrs, + GInputStream **out_input, guint64 *out_length, + GCancellable *cancellable, GError **error) +{ + g_autoptr (GBytes) file_header = _ostree_file_header_new (file_info, xattrs); *out_input = header_and_input_to_stream (file_header, input); if (out_length) - *out_length = g_bytes_get_size (file_header) + g_file_info_get_size (file_info); + *out_length = g_bytes_get_size (file_header); + if (out_length && g_file_info_has_attribute (file_info, "standard::size")) + *out_length += g_file_info_get_size (file_info); return TRUE; } @@ -570,69 +543,51 @@ ostree_raw_file_to_content_stream (GInputStream *input, * converts an object content stream back into components. */ gboolean -ostree_content_stream_parse (gboolean compressed, - GInputStream *input, - guint64 input_length, - gboolean trusted, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) +ostree_content_stream_parse (gboolean compressed, GInputStream *input, guint64 input_length, + gboolean trusted, GInputStream **out_input, GFileInfo **out_file_info, + GVariant **out_xattrs, GCancellable *cancellable, GError **error) { guint32 archive_header_size; guchar dummy[4]; gsize bytes_read; - if (!g_input_stream_read_all (input, - &archive_header_size, 4, &bytes_read, - cancellable, error)) + if (!g_input_stream_read_all (input, &archive_header_size, 4, &bytes_read, cancellable, error)) return FALSE; archive_header_size = GUINT32_FROM_BE (archive_header_size); if (archive_header_size > input_length) - return glnx_throw (error, "File header size %u exceeds size %" G_GUINT64_FORMAT, - (guint)archive_header_size, input_length); + return glnx_throw (error, "File header size %u exceeds size %" G_GUINT64_FORMAT, + (guint)archive_header_size, input_length); else if (archive_header_size == 0) return glnx_throw (error, "File header size is zero"); /* Skip over padding */ - if (!g_input_stream_read_all (input, - dummy, 4, &bytes_read, - cancellable, error)) + if (!g_input_stream_read_all (input, dummy, 4, &bytes_read, cancellable, error)) return FALSE; g_autofree guchar *buf = g_malloc (archive_header_size); - if (!g_input_stream_read_all (input, buf, archive_header_size, &bytes_read, - cancellable, error)) + if (!g_input_stream_read_all (input, buf, archive_header_size, &bytes_read, cancellable, error)) return FALSE; - g_autoptr(GVariant) file_header = - g_variant_ref_sink(g_variant_new_from_data (compressed ? _OSTREE_ZLIB_FILE_HEADER_GVARIANT_FORMAT : _OSTREE_FILE_HEADER_GVARIANT_FORMAT, - buf, archive_header_size, trusted, - g_free, buf)); + g_autoptr (GVariant) file_header = g_variant_ref_sink (g_variant_new_from_data ( + compressed ? _OSTREE_ZLIB_FILE_HEADER_GVARIANT_FORMAT : _OSTREE_FILE_HEADER_GVARIANT_FORMAT, + buf, archive_header_size, trusted, g_free, buf)); buf = NULL; - g_autoptr(GFileInfo) ret_file_info = NULL; - g_autoptr(GVariant) ret_xattrs = NULL; + g_autoptr (GFileInfo) ret_file_info = NULL; + g_autoptr (GVariant) ret_xattrs = NULL; if (compressed) { - if (!zlib_file_header_parse (file_header, - &ret_file_info, - out_xattrs ? &ret_xattrs : NULL, + if (!zlib_file_header_parse (file_header, &ret_file_info, out_xattrs ? &ret_xattrs : NULL, error)) return FALSE; } else { - if (!file_header_parse (file_header, - &ret_file_info, - out_xattrs ? &ret_xattrs : NULL, - error)) + if (!file_header_parse (file_header, &ret_file_info, out_xattrs ? &ret_xattrs : NULL, error)) return FALSE; g_file_info_set_size (ret_file_info, input_length - archive_header_size - 8); } - g_autoptr(GInputStream) ret_input = NULL; - if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR - && out_input) + g_autoptr (GInputStream) ret_input = NULL; + if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR && out_input) { /* Give the input stream at its current position as return value; * assuming the caller doesn't seek, this should be fine. We might @@ -640,7 +595,8 @@ ostree_content_stream_parse (gboolean compressed, **/ if (compressed) { - g_autoptr(GConverter) zlib_decomp = (GConverter*)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); + g_autoptr (GConverter) zlib_decomp + = (GConverter *)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW); ret_input = g_converter_input_stream_new (input, zlib_decomp); } else @@ -669,15 +625,9 @@ ostree_content_stream_parse (gboolean compressed, * converts an object content stream back into components. */ gboolean -ostree_content_file_parse_at (gboolean compressed, - int parent_dfd, - const char *path, - gboolean trusted, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) +ostree_content_file_parse_at (gboolean compressed, int parent_dfd, const char *path, + gboolean trusted, GInputStream **out_input, GFileInfo **out_file_info, + GVariant **out_xattrs, GCancellable *cancellable, GError **error) { glnx_autofd int fd = -1; if (!glnx_openat_rdonly (parent_dfd, path, TRUE, &fd, error)) @@ -687,14 +637,13 @@ ostree_content_file_parse_at (gboolean compressed, if (!glnx_fstat (fd, &stbuf, error)) return FALSE; - g_autoptr(GInputStream) file_input = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE); + g_autoptr (GInputStream) file_input = g_unix_input_stream_new (g_steal_fd (&fd), TRUE); - g_autoptr(GFileInfo) ret_file_info = NULL; - g_autoptr(GVariant) ret_xattrs = NULL; - g_autoptr(GInputStream) ret_input = NULL; + g_autoptr (GFileInfo) ret_file_info = NULL; + g_autoptr (GVariant) ret_xattrs = NULL; + g_autoptr (GInputStream) ret_input = NULL; if (!ostree_content_stream_parse (compressed, file_input, stbuf.st_size, trusted, - out_input ? &ret_input : NULL, - &ret_file_info, &ret_xattrs, + out_input ? &ret_input : NULL, &ret_file_info, &ret_xattrs, cancellable, error)) return FALSE; @@ -719,29 +668,18 @@ ostree_content_file_parse_at (gboolean compressed, * converts an object content stream back into components. */ gboolean -ostree_content_file_parse (gboolean compressed, - GFile *content_path, - gboolean trusted, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) -{ - return ostree_content_file_parse_at (compressed, AT_FDCWD, - gs_file_get_path_cached (content_path), - trusted, - out_input, out_file_info, out_xattrs, - cancellable, error); +ostree_content_file_parse (gboolean compressed, GFile *content_path, gboolean trusted, + GInputStream **out_input, GFileInfo **out_file_info, + GVariant **out_xattrs, GCancellable *cancellable, GError **error) +{ + return ostree_content_file_parse_at (compressed, AT_FDCWD, gs_file_get_path_cached (content_path), + trusted, out_input, out_file_info, out_xattrs, cancellable, + error); } static gboolean -break_symhardlink (int dfd, - const char *path, - struct stat *stbuf, - GLnxFileCopyFlags copyflags, - GCancellable *cancellable, - GError **error) +break_symhardlink (int dfd, const char *path, struct stat *stbuf, GLnxFileCopyFlags copyflags, + GCancellable *cancellable, GError **error) { guint count; gboolean copy_success = FALSE; @@ -749,12 +687,11 @@ break_symhardlink (int dfd, for (count = 0; count < 100; count++) { - g_autoptr(GError) tmp_error = NULL; + g_autoptr (GError) tmp_error = NULL; glnx_gen_temp_name (path_tmp); - if (!glnx_file_copy_at (dfd, path, stbuf, dfd, path_tmp, copyflags, - cancellable, &tmp_error)) + if (!glnx_file_copy_at (dfd, path, stbuf, dfd, path_tmp, copyflags, cancellable, &tmp_error)) { if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) continue; @@ -803,11 +740,9 @@ break_symhardlink (int dfd, * * Since: 2017.15 */ -gboolean ostree_break_hardlink (int dfd, - const char *path, - gboolean skip_xattrs, - GCancellable *cancellable, - GError **error) +gboolean +ostree_break_hardlink (int dfd, const char *path, gboolean skip_xattrs, GCancellable *cancellable, + GError **error) { struct stat stbuf; @@ -815,7 +750,7 @@ gboolean ostree_break_hardlink (int dfd, return FALSE; if (stbuf.st_nlink <= 1) - return TRUE; /* Note early return */ + return TRUE; /* Note early return */ const GLnxFileCopyFlags copyflags = skip_xattrs ? GLNX_FILE_COPY_NOXATTRS : 0; @@ -824,12 +759,10 @@ gboolean ostree_break_hardlink (int dfd, * as glnx_file_copy_at() is documented to do an O_TMPFILE + rename() * with GLNX_FILE_COPY_OVERWRITE. */ - return glnx_file_copy_at (dfd, path, &stbuf, dfd, path, - copyflags | GLNX_FILE_COPY_OVERWRITE, + return glnx_file_copy_at (dfd, path, &stbuf, dfd, path, copyflags | GLNX_FILE_COPY_OVERWRITE, cancellable, error); else if (S_ISLNK (stbuf.st_mode)) - return break_symhardlink (dfd, path, &stbuf, copyflags, - cancellable, error); + return break_symhardlink (dfd, path, &stbuf, copyflags, cancellable, error); else return glnx_throw (error, "Unsupported type for entry '%s'", path); @@ -894,16 +827,14 @@ ostree_fs_get_all_xattrs_at (int dfd, const char *path, GCancellable *cancellabl * Compute the OSTree checksum for a given input. */ gboolean -ostree_checksum_file_from_input (GFileInfo *file_info, - GVariant *xattrs, - GInputStream *in, - OstreeObjectType objtype, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +ostree_checksum_file_from_input (GFileInfo *file_info, GVariant *xattrs, GInputStream *in, + OstreeObjectType objtype, guchar **out_csum, + GCancellable *cancellable, GError **error) { - g_auto(OtChecksum) checksum = { 0, }; + g_auto (OtChecksum) checksum = { + 0, + }; ot_checksum_init (&checksum); if (OSTREE_OBJECT_TYPE_IS_META (objtype)) @@ -913,13 +844,12 @@ ostree_checksum_file_from_input (GFileInfo *file_info, } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) { - g_autoptr(GVariant) dirmeta = ostree_create_directory_metadata (file_info, xattrs); - ot_checksum_update (&checksum, g_variant_get_data (dirmeta), - g_variant_get_size (dirmeta)); + g_autoptr (GVariant) dirmeta = ostree_create_directory_metadata (file_info, xattrs); + ot_checksum_update (&checksum, g_variant_get_data (dirmeta), g_variant_get_size (dirmeta)); } else { - g_autoptr(GBytes) file_header = _ostree_file_header_new (file_info, xattrs); + g_autoptr (GBytes) file_header = _ostree_file_header_new (file_info, xattrs); ot_checksum_update_bytes (&checksum, file_header); @@ -946,44 +876,40 @@ ostree_checksum_file_from_input (GFileInfo *file_info, * Compute the OSTree checksum for a given file. */ gboolean -ostree_checksum_file (GFile *f, - OstreeObjectType objtype, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +ostree_checksum_file (GFile *f, OstreeObjectType objtype, guchar **out_csum, + GCancellable *cancellable, GError **error) { if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - g_autoptr(GFileInfo) file_info = - g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + g_autoptr (GFileInfo) file_info = g_file_query_info ( + f, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!file_info) return FALSE; - g_autoptr(GInputStream) in = NULL; + g_autoptr (GInputStream) in = NULL; if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { - in = (GInputStream*)g_file_read (f, cancellable, error); + in = (GInputStream *)g_file_read (f, cancellable, error); if (!in) return FALSE; } - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; if (objtype == OSTREE_OBJECT_TYPE_FILE) { - xattrs = ostree_fs_get_all_xattrs_at (AT_FDCWD, gs_file_get_path_cached (f), cancellable, error); + xattrs + = ostree_fs_get_all_xattrs_at (AT_FDCWD, gs_file_get_path_cached (f), cancellable, error); if (!xattrs) return FALSE; } g_autofree guchar *ret_csum = NULL; - if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype, - &ret_csum, cancellable, error)) + if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype, &ret_csum, cancellable, + error)) return FALSE; - ot_transfer_out_value(out_csum, &ret_csum); + ot_transfer_out_value (out_csum, &ret_csum); return TRUE; } @@ -1005,14 +931,9 @@ ostree_checksum_file (GFile *f, * Since: 2017.13 */ gboolean -ostree_checksum_file_at (int dfd, - const char *path, - struct stat *stbuf, - OstreeObjectType objtype, - OstreeChecksumFlags flags, - char **out_checksum, - GCancellable *cancellable, - GError **error) +ostree_checksum_file_at (int dfd, const char *path, struct stat *stbuf, OstreeObjectType objtype, + OstreeChecksumFlags flags, char **out_checksum, GCancellable *cancellable, + GError **error) { g_return_val_if_fail (out_checksum != NULL, FALSE); @@ -1027,18 +948,17 @@ ostree_checksum_file_at (int dfd, return FALSE; } - g_autoptr(GFileInfo) file_info = _ostree_stbuf_to_gfileinfo (stbuf); + g_autoptr (GFileInfo) file_info = _ostree_stbuf_to_gfileinfo (stbuf); - const gboolean canonicalize_perms = - ((flags & OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS) != 0); + const gboolean canonicalize_perms = ((flags & OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS) != 0); - g_autoptr(GInputStream) in = NULL; + g_autoptr (GInputStream) in = NULL; if (S_ISREG (stbuf->st_mode)) { glnx_autofd int fd = -1; if (!glnx_openat_rdonly (dfd, path, FALSE, &fd, error)) return FALSE; - in = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE); + in = g_unix_input_stream_new (g_steal_fd (&fd), TRUE); if (canonicalize_perms) { g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0); @@ -1051,10 +971,9 @@ ostree_checksum_file_at (int dfd, return FALSE; } - const gboolean ignore_xattrs = - ((flags & OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS) > 0); + const gboolean ignore_xattrs = ((flags & OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS) > 0); - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; if (!ignore_xattrs && objtype == OSTREE_OBJECT_TYPE_FILE) { if (!glnx_dfd_name_get_all_xattrs (dfd, path, &xattrs, cancellable, error)) @@ -1062,25 +981,23 @@ ostree_checksum_file_at (int dfd, } g_autofree guchar *csum_bytes = NULL; - if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype, - &csum_bytes, cancellable, error)) + if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype, &csum_bytes, cancellable, + error)) return FALSE; *out_checksum = ostree_checksum_from_bytes (csum_bytes); return TRUE; } -typedef struct { - GFile *f; +typedef struct +{ + GFile *f; OstreeObjectType objtype; guchar *csum; } ChecksumFileAsyncData; static void -checksum_file_async_thread (GTask *task, - GObject *object, - gpointer datap, - GCancellable *cancellable) +checksum_file_async_thread (GTask *task, GObject *object, gpointer datap, GCancellable *cancellable) { GError *error = NULL; ChecksumFileAsyncData *data = datap; @@ -1118,14 +1035,11 @@ checksum_file_async_data_free (gpointer datap) * complete with ostree_checksum_file_async_finish(). */ void -ostree_checksum_file_async (GFile *f, - OstreeObjectType objtype, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - g_autoptr(GTask) task = NULL; +ostree_checksum_file_async (GFile *f, OstreeObjectType objtype, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + g_autoptr (GTask) task = NULL; ChecksumFileAsyncData *data; data = g_new0 (ChecksumFileAsyncData, 1); @@ -1150,10 +1064,8 @@ ostree_checksum_file_async (GFile *f, * ostree_checksum_file_async(). */ gboolean -ostree_checksum_file_async_finish (GFile *f, - GAsyncResult *result, - guchar **out_csum, - GError **error) +ostree_checksum_file_async_finish (GFile *f, GAsyncResult *result, guchar **out_csum, + GError **error) { ChecksumFileAsyncData *data; @@ -1178,15 +1090,12 @@ ostree_checksum_file_async_finish (GFile *f, * error message. */ gboolean -_ostree_compare_object_checksum (OstreeObjectType objtype, - const char *expected, - const char *actual, - GError **error) +_ostree_compare_object_checksum (OstreeObjectType objtype, const char *expected, const char *actual, + GError **error) { if (!g_str_equal (expected, actual)) return glnx_throw (error, "Corrupted %s object; checksum expected='%s' actual='%s'", - ostree_object_type_to_string (objtype), - expected, actual); + ostree_object_type_to_string (objtype), expected, actual); return TRUE; } @@ -1198,16 +1107,15 @@ _ostree_compare_object_checksum (OstreeObjectType objtype, * Returns: (transfer full) (not nullable): A new #GVariant containing %OSTREE_OBJECT_TYPE_DIR_META */ GVariant * -ostree_create_directory_metadata (GFileInfo *dir_info, - GVariant *xattrs) +ostree_create_directory_metadata (GFileInfo *dir_info, GVariant *xattrs) { GVariant *ret_metadata = NULL; - ret_metadata = g_variant_new ("(uuu@a(ayay))", - GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::uid")), - GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::gid")), - GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::mode")), - xattrs ? xattrs : g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); + ret_metadata = g_variant_new ( + "(uuu@a(ayay))", GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::uid")), + GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::gid")), + GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::mode")), + xattrs ? xattrs : g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); g_variant_ref_sink (ret_metadata); return ret_metadata; @@ -1225,11 +1133,8 @@ ostree_create_directory_metadata (GFileInfo *dir_info, * where we override existing files via tempfile+rename(). */ gboolean -_ostree_make_temporary_symlink_at (int tmp_dirfd, - const char *target, - char **out_name, - GCancellable *cancellable, - GError **error) +_ostree_make_temporary_symlink_at (int tmp_dirfd, const char *target, char **out_name, + GCancellable *cancellable, GError **error) { g_autofree char *tmpname = g_strdup ("tmplink.XXXXXX"); const int max_attempts = 128; @@ -1256,7 +1161,6 @@ _ostree_make_temporary_symlink_at (int tmp_dirfd, return TRUE; } - /** * ostree_object_type_to_string: * @objtype: an #OstreeObjectType @@ -1331,8 +1235,7 @@ ostree_object_type_from_string (const char *str) * Returns: A string containing both @checksum and a stringifed version of @objtype */ char * -ostree_object_to_string (const char *checksum, - OstreeObjectType objtype) +ostree_object_to_string (const char *checksum, OstreeObjectType objtype) { return g_strconcat (checksum, ".", ostree_object_type_to_string (objtype), NULL); } @@ -1346,9 +1249,7 @@ ostree_object_to_string (const char *checksum, * Reverse ostree_object_to_string(). */ void -ostree_object_from_string (const char *str, - gchar **out_checksum, - OstreeObjectType *out_objtype) +ostree_object_from_string (const char *str, gchar **out_checksum, OstreeObjectType *out_objtype) { const char *dot; @@ -1373,7 +1274,7 @@ ostree_hash_object_name (gconstpointer a) gint objtype_int; ostree_object_name_deserialize (variant, &checksum, &objtype); - objtype_int = (gint) objtype; + objtype_int = (gint)objtype; return g_str_hash (checksum) + g_int_hash (&objtype_int); } @@ -1385,8 +1286,7 @@ ostree_hash_object_name (gconstpointer a) * Compare two binary checksums, using memcmp(). */ int -ostree_cmp_checksum_bytes (const guchar *a, - const guchar *b) +ostree_cmp_checksum_bytes (const guchar *a, const guchar *b) { return memcmp (a, b, OSTREE_SHA256_DIGEST_LEN); } @@ -1399,11 +1299,9 @@ ostree_cmp_checksum_bytes (const guchar *a, * Returns: (transfer floating): A new floating #GVariant containing checksum string and objtype */ GVariant * -ostree_object_name_serialize (const char *checksum, - OstreeObjectType objtype) +ostree_object_name_serialize (const char *checksum, OstreeObjectType objtype) { - g_assert (objtype >= OSTREE_OBJECT_TYPE_FILE - && objtype <= OSTREE_OBJECT_TYPE_LAST); + g_assert (objtype >= OSTREE_OBJECT_TYPE_FILE && objtype <= OSTREE_OBJECT_TYPE_LAST); return g_variant_new ("(su)", checksum, (guint32)objtype); } @@ -1417,8 +1315,7 @@ ostree_object_name_serialize (const char *checksum, * only valid for the lifetime of @variant, and must not be freed. */ void -ostree_object_name_deserialize (GVariant *variant, - const char **out_checksum, +ostree_object_name_deserialize (GVariant *variant, const char **out_checksum, OstreeObjectType *out_objtype) { guint32 objtype_u32; @@ -1434,8 +1331,7 @@ ostree_object_name_deserialize (GVariant *variant, * Overwrite the contents of @buf with stringified version of @csum. */ void -ostree_checksum_b64_inplace_to_bytes (const char *checksum, - guchar *buf) +ostree_checksum_b64_inplace_to_bytes (const char *checksum, guchar *buf) { int state = 0; guint save = 0; @@ -1452,7 +1348,7 @@ ostree_checksum_b64_inplace_to_bytes (const char *checksum, } tmpbuf[43] = '='; - g_base64_decode_step (tmpbuf, sizeof (tmpbuf), (guchar *) buf, &state, &save); + g_base64_decode_step (tmpbuf, sizeof (tmpbuf), (guchar *)buf, &state, &save); } /** @@ -1464,8 +1360,7 @@ ostree_checksum_b64_inplace_to_bytes (const char *checksum, * allocating memory. Use this function in hot code paths. */ void -ostree_checksum_inplace_to_bytes (const char *checksum, - guchar *buf) +ostree_checksum_inplace_to_bytes (const char *checksum, guchar *buf) { guint i; guint j; @@ -1475,10 +1370,10 @@ ostree_checksum_inplace_to_bytes (const char *checksum, gint big, little; g_assert (checksum[j]); - g_assert (checksum[j+1]); + g_assert (checksum[j + 1]); big = g_ascii_xdigit_value (checksum[j]); - little = g_ascii_xdigit_value (checksum[j+1]); + little = g_ascii_xdigit_value (checksum[j + 1]); g_assert (big != -1); g_assert (little != -1); @@ -1491,7 +1386,8 @@ ostree_checksum_inplace_to_bytes (const char *checksum, * ostree_checksum_to_bytes: * @checksum: An ASCII checksum * - * Returns: (transfer full) (array fixed-size=32): Binary checksum from @checksum of length 32; free with g_free(). + * Returns: (transfer full) (array fixed-size=32): Binary checksum from @checksum of length 32; + * free with g_free(). */ guchar * ostree_checksum_to_bytes (const char *checksum) @@ -1512,7 +1408,7 @@ ostree_checksum_to_bytes_v (const char *checksum) { guchar result[OSTREE_SHA256_DIGEST_LEN]; ostree_checksum_inplace_to_bytes (checksum, result); - return ot_gvariant_new_bytearray ((guchar*)result, OSTREE_SHA256_DIGEST_LEN); + return ot_gvariant_new_bytearray ((guchar *)result, OSTREE_SHA256_DIGEST_LEN); } /** @@ -1539,8 +1435,7 @@ ostree_checksum_b64_to_bytes (const char *checksum) * Overwrite the contents of @buf with stringified version of @csum. */ void -ostree_checksum_inplace_from_bytes (const guchar *csum, - char *buf) +ostree_checksum_inplace_from_bytes (const guchar *csum, char *buf) { ot_bin2hex (buf, csum, OSTREE_SHA256_DIGEST_LEN); } @@ -1555,8 +1450,7 @@ ostree_checksum_inplace_from_bytes (const guchar *csum, * character is used. */ void -ostree_checksum_b64_inplace_from_bytes (const guchar *csum, - char *buf) +ostree_checksum_b64_inplace_from_bytes (const guchar *csum, char *buf) { char tmpbuf[44]; int save = 0; @@ -1569,7 +1463,7 @@ ostree_checksum_b64_inplace_from_bytes (const guchar *csum, * to replace the '/' with '_'. */ outlen = g_base64_encode_step (csum, OSTREE_SHA256_DIGEST_LEN, FALSE, tmpbuf, &state, &save); - outlen += g_base64_encode_close (FALSE, tmpbuf+outlen, &state, &save); + outlen += g_base64_encode_close (FALSE, tmpbuf + outlen, &state, &save); g_assert (outlen == 44); for (i = 0; i < sizeof (tmpbuf); i++) @@ -1596,7 +1490,7 @@ ostree_checksum_b64_inplace_from_bytes (const guchar *csum, char * ostree_checksum_from_bytes (const guchar *csum) { - char *ret = g_malloc (OSTREE_SHA256_STRING_LEN+1); + char *ret = g_malloc (OSTREE_SHA256_STRING_LEN + 1); ostree_checksum_inplace_from_bytes (csum, ret); return ret; } @@ -1636,7 +1530,8 @@ ostree_checksum_b64_from_bytes (const guchar *csum) * ostree_checksum_bytes_peek: * @bytes: #GVariant of type ay * - * Returns: (transfer none) (array fixed-size=32) (element-type guint8): Binary checksum data in @bytes; do not free. If @bytes does not have the correct length, return %NULL. + * Returns: (transfer none) (array fixed-size=32) (element-type guint8): Binary checksum data in + * @bytes; do not free. If @bytes does not have the correct length, return %NULL. */ const guchar * ostree_checksum_bytes_peek (GVariant *bytes) @@ -1659,15 +1554,14 @@ ostree_checksum_bytes_peek (GVariant *bytes) * Returns: (transfer none) (array fixed-size=32) (element-type guint8): Binary checksum data */ const guchar * -ostree_checksum_bytes_peek_validate (GVariant *bytes, - GError **error) +ostree_checksum_bytes_peek_validate (GVariant *bytes, GError **error) { const guchar *ret = ostree_checksum_bytes_peek (bytes); if (G_UNLIKELY (!ret)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid checksum of length %" G_GUINT64_FORMAT - " expected 32", (guint64) g_variant_n_children (bytes)); + "Invalid checksum of length %" G_GUINT64_FORMAT " expected 32", + (guint64)g_variant_n_children (bytes)); return NULL; } return ret; @@ -1684,17 +1578,14 @@ ostree_checksum_bytes_peek_validate (GVariant *bytes, * object. */ void -_ostree_loose_path (char *buf, - const char *checksum, - OstreeObjectType objtype, - OstreeRepoMode mode) +_ostree_loose_path (char *buf, const char *checksum, OstreeObjectType objtype, OstreeRepoMode mode) { *buf = checksum[0]; buf++; *buf = checksum[1]; buf++; - snprintf (buf, _OSTREE_LOOSE_PATH_MAX - 2, "/%s.%s%s", - checksum + 2, ostree_object_type_to_string (objtype), + snprintf (buf, _OSTREE_LOOSE_PATH_MAX - 2, "/%s.%s%s", checksum + 2, + ostree_object_type_to_string (objtype), (!OSTREE_OBJECT_TYPE_IS_META (objtype) && mode == OSTREE_REPO_MODE_ARCHIVE) ? "z" : ""); } @@ -1723,7 +1614,7 @@ _ostree_stbuf_to_gfileinfo (const struct stat *stbuf) ftype = G_FILE_TYPE_REGULAR; else if (S_ISLNK (mode)) ftype = G_FILE_TYPE_SYMBOLIC_LINK; - else if (S_ISBLK (mode) || S_ISCHR(mode) || S_ISFIFO(mode)) + else if (S_ISBLK (mode) || S_ISCHR (mode) || S_ISFIFO (mode)) ftype = G_FILE_TYPE_SPECIAL; else ftype = G_FILE_TYPE_UNKNOWN; @@ -1739,6 +1630,8 @@ _ostree_stbuf_to_gfileinfo (const struct stat *stbuf) if (S_ISREG (mode)) g_file_info_set_attribute_uint64 (ret, "standard::size", stbuf->st_size); + else + g_file_info_set_attribute_uint64 (ret, "standard::size", 0); return ret; } @@ -1751,10 +1644,11 @@ _ostree_stbuf_to_gfileinfo (const struct stat *stbuf) * Map GFileInfo data from @file_info onto @out_stbuf. */ void -_ostree_gfileinfo_to_stbuf (GFileInfo *file_info, - struct stat *out_stbuf) +_ostree_gfileinfo_to_stbuf (GFileInfo *file_info, struct stat *out_stbuf) { - struct stat stbuf = {0,}; + struct stat stbuf = { + 0, + }; stbuf.st_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); stbuf.st_uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid"); stbuf.st_gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid"); @@ -1782,10 +1676,13 @@ _ostree_gfileinfo_equal (GFileInfo *a, GFileInfo *b) return TRUE; #define CHECK_ONE_ATTR(type, attr, a, b) \ - do { if (g_file_info_get_attribute_##type(a, attr) != \ - g_file_info_get_attribute_##type(b, attr)) \ - return FALSE; \ - } while (0) + do \ + { \ + if (g_file_info_get_attribute_##type (a, attr) \ + != g_file_info_get_attribute_##type (b, attr)) \ + return FALSE; \ + } \ + while (0) CHECK_ONE_ATTR (uint32, "unix::uid", a, b); CHECK_ONE_ATTR (uint32, "unix::gid", a, b); @@ -1822,7 +1719,9 @@ _ostree_stbuf_equal (struct stat *stbuf_a, struct stat *stbuf_b) GFileInfo * _ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid) { - struct stat stbuf = { 0, }; + struct stat stbuf = { + 0, + }; stbuf.st_mode = mode; stbuf.st_uid = uid; stbuf.st_gid = gid; @@ -1838,9 +1737,7 @@ _ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid) * Returns: (transfer full): Relative path for a loose object */ char * -_ostree_get_relative_object_path (const char *checksum, - OstreeObjectType type, - gboolean compressed) +_ostree_get_relative_object_path (const char *checksum, OstreeObjectType type, gboolean compressed) { GString *path; @@ -1860,9 +1757,7 @@ _ostree_get_relative_object_path (const char *checksum, } static GString * -static_delta_path_base (const char *dir, - const char *from, - const char *to) +static_delta_path_base (const char *dir, const char *from, const char *to) { guint8 csum_to[OSTREE_SHA256_DIGEST_LEN]; char to_b64[44]; @@ -1900,9 +1795,7 @@ static_delta_path_base (const char *dir, } char * -_ostree_get_relative_static_delta_path (const char *from, - const char *to, - const char *target) +_ostree_get_relative_static_delta_path (const char *from, const char *to, const char *target) { GString *ret = static_delta_path_base ("deltas/", from, to); @@ -1916,23 +1809,19 @@ _ostree_get_relative_static_delta_path (const char *from, } char * -_ostree_get_relative_static_delta_superblock_path (const char *from, - const char *to) +_ostree_get_relative_static_delta_superblock_path (const char *from, const char *to) { return _ostree_get_relative_static_delta_path (from, to, "superblock"); } char * -_ostree_get_relative_static_delta_detachedmeta_path (const char *from, - const char *to) +_ostree_get_relative_static_delta_detachedmeta_path (const char *from, const char *to) { return _ostree_get_relative_static_delta_path (from, to, "meta"); } char * -_ostree_get_relative_static_delta_part_path (const char *from, - const char *to, - guint i) +_ostree_get_relative_static_delta_part_path (const char *from, const char *to, guint i) { g_autofree char *partstr = g_strdup_printf ("%u", i); return _ostree_get_relative_static_delta_path (from, to, partstr); @@ -1949,12 +1838,9 @@ _ostree_get_relative_static_delta_index_path (const char *to) } gboolean -_ostree_parse_delta_name (const char *delta_name, - char **out_from, - char **out_to, - GError **error) +_ostree_parse_delta_name (const char *delta_name, char **out_from, char **out_to, GError **error) { - g_auto(GStrv) parts = NULL; + g_auto (GStrv) parts = NULL; g_return_val_if_fail (delta_name != NULL, FALSE); parts = g_strsplit (delta_name, "-", 2); @@ -1965,8 +1851,7 @@ _ostree_parse_delta_name (const char *delta_name, if (!ostree_validate_checksum_string (parts[0] ?: "", error)) return FALSE; - if (parts[0] && parts[1] && - !ostree_validate_checksum_string (parts[1], error)) + if (parts[0] && parts[1] && !ostree_validate_checksum_string (parts[1], error)) return FALSE; *out_from = *out_to = NULL; @@ -1994,25 +1879,22 @@ _ostree_parse_delta_name (const char *delta_name, * along with extended attributes tored in @out_xattrs. */ static gboolean -file_header_parse (GVariant *metadata, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GError **error) +file_header_parse (GVariant *metadata, GFileInfo **out_file_info, GVariant **out_xattrs, + GError **error) { guint32 uid, gid, mode, rdev; const char *symlink_target; - g_autoptr(GVariant) ret_xattrs = NULL; + g_autoptr (GVariant) ret_xattrs = NULL; - g_variant_get (metadata, "(uuuu&s@a(ayay))", - &uid, &gid, &mode, &rdev, - &symlink_target, &ret_xattrs); + g_variant_get (metadata, "(uuuu&s@a(ayay))", &uid, &gid, &mode, &rdev, &symlink_target, + &ret_xattrs); if (rdev != 0) return glnx_throw (error, "Corrupted archive file; invalid rdev %u", GUINT32_FROM_BE (rdev)); uid = GUINT32_FROM_BE (uid); gid = GUINT32_FROM_BE (gid); mode = GUINT32_FROM_BE (mode); - g_autoptr(GFileInfo) ret_file_info = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); + g_autoptr (GFileInfo) ret_file_info = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); if (S_ISREG (mode)) { @@ -2020,15 +1902,16 @@ file_header_parse (GVariant *metadata, } else if (S_ISLNK (mode)) { - g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", symlink_target); + g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", + symlink_target); } else { return glnx_throw (error, "Corrupted archive file; invalid mode %u", mode); } - ot_transfer_out_value(out_file_info, &ret_file_info); - ot_transfer_out_value(out_xattrs, &ret_xattrs); + ot_transfer_out_value (out_file_info, &ret_file_info); + ot_transfer_out_value (out_xattrs, &ret_xattrs); return TRUE; } @@ -2043,26 +1926,23 @@ file_header_parse (GVariant *metadata, * content. */ static gboolean -zlib_file_header_parse (GVariant *metadata, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GError **error) +zlib_file_header_parse (GVariant *metadata, GFileInfo **out_file_info, GVariant **out_xattrs, + GError **error) { guint64 size; guint32 uid, gid, mode, rdev; const char *symlink_target; - g_autoptr(GVariant) ret_xattrs = NULL; + g_autoptr (GVariant) ret_xattrs = NULL; - g_variant_get (metadata, "(tuuuu&s@a(ayay))", &size, - &uid, &gid, &mode, &rdev, - &symlink_target, &ret_xattrs); + g_variant_get (metadata, "(tuuuu&s@a(ayay))", &size, &uid, &gid, &mode, &rdev, &symlink_target, + &ret_xattrs); if (rdev != 0) return glnx_throw (error, "Corrupted archive file; invalid rdev %u", GUINT32_FROM_BE (rdev)); uid = GUINT32_FROM_BE (uid); gid = GUINT32_FROM_BE (gid); mode = GUINT32_FROM_BE (mode); - g_autoptr(GFileInfo) ret_file_info = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); + g_autoptr (GFileInfo) ret_file_info = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); g_file_info_set_size (ret_file_info, GUINT64_FROM_BE (size)); if (S_ISREG (mode)) @@ -2071,15 +1951,16 @@ zlib_file_header_parse (GVariant *metadata, } else if (S_ISLNK (mode)) { - g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", symlink_target); + g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", + symlink_target); } else { return glnx_throw (error, "Corrupted archive file; invalid mode %u", mode); } - ot_transfer_out_value(out_file_info, &ret_file_info); - ot_transfer_out_value(out_xattrs, &ret_xattrs); + ot_transfer_out_value (out_file_info, &ret_file_info); + ot_transfer_out_value (out_xattrs, &ret_xattrs); return TRUE; } @@ -2091,12 +1972,10 @@ zlib_file_header_parse (GVariant *metadata, * Returns: %TRUE if @objtype represents a valid object type */ gboolean -ostree_validate_structureof_objtype (guchar objtype, - GError **error) +ostree_validate_structureof_objtype (guchar objtype, GError **error) { - OstreeObjectType objtype_v = (OstreeObjectType) objtype; - if (objtype_v < OSTREE_OBJECT_TYPE_FILE - || objtype_v > OSTREE_OBJECT_TYPE_COMMIT) + OstreeObjectType objtype_v = (OstreeObjectType)objtype; + if (objtype_v < OSTREE_OBJECT_TYPE_FILE || objtype_v > OSTREE_OBJECT_TYPE_COMMIT) return glnx_throw (error, "Invalid object type '%u'", objtype); return TRUE; } @@ -2109,8 +1988,7 @@ ostree_validate_structureof_objtype (guchar objtype, * Returns: %TRUE if @checksum is a valid binary SHA256 checksum */ gboolean -ostree_validate_structureof_csum_v (GVariant *checksum, - GError **error) +ostree_validate_structureof_csum_v (GVariant *checksum, GError **error) { return ostree_checksum_bytes_peek_validate (checksum, error) != NULL; } @@ -2123,8 +2001,7 @@ ostree_validate_structureof_csum_v (GVariant *checksum, * Returns: %TRUE if @checksum is a valid ASCII SHA256 checksum */ gboolean -ostree_validate_structureof_checksum_string (const char *checksum, - GError **error) +ostree_validate_structureof_checksum_string (const char *checksum, GError **error) { int i = 0; size_t len = strlen (checksum); @@ -2135,20 +2012,18 @@ ostree_validate_structureof_checksum_string (const char *checksum, * dump it all to the error. * https://github.com/projectatomic/rpm-ostree/issues/885 */ - g_autofree char *sanitized = quash_string_for_error_message (checksum, len, - OSTREE_SHA256_STRING_LEN); + g_autofree char *sanitized + = quash_string_for_error_message (checksum, len, OSTREE_SHA256_STRING_LEN); return glnx_throw (error, "Invalid rev %s", sanitized); } for (i = 0; i < len; i++) { - guint8 c = ((guint8*) checksum)[i]; + guint8 c = ((guint8 *)checksum)[i]; - if (!((c >= 48 && c <= 57) - || (c >= 97 && c <= 102))) + if (!((c >= 48 && c <= 57) || (c >= 97 && c <= 102))) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid character '%d' in rev '%s'", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid character '%d' in rev '%s'", c, checksum); return FALSE; } @@ -2157,9 +2032,7 @@ ostree_validate_structureof_checksum_string (const char *checksum, } static gboolean -validate_variant (GVariant *variant, - const GVariantType *variant_type, - GError **error) +validate_variant (GVariant *variant, const GVariantType *variant_type, GError **error) { if (!g_variant_is_normal_form (variant)) { @@ -2167,8 +2040,7 @@ validate_variant (GVariant *variant, } if (!g_variant_is_of_type (variant, variant_type)) { - return glnx_throw (error, "Doesn't match variant type '%s'", - (char *)variant_type); + return glnx_throw (error, "Doesn't match variant type '%s'", (char *)variant_type); } return TRUE; } @@ -2177,9 +2049,7 @@ validate_variant (GVariant *variant, * commit/dirtree/dirmeta verifiers. */ gboolean -_ostree_validate_structureof_metadata (OstreeObjectType objtype, - GVariant *metadata, - GError **error) +_ostree_validate_structureof_metadata (OstreeObjectType objtype, GVariant *metadata, GError **error) { g_assert (OSTREE_OBJECT_TYPE_IS_META (objtype)); @@ -2218,25 +2088,31 @@ _ostree_validate_structureof_metadata (OstreeObjectType objtype, * one is checking for path traversal in dirtree objects. */ gboolean -_ostree_verify_metadata_object (OstreeObjectType objtype, - const char *expected_checksum, - GVariant *metadata, - GError **error) +_ostree_verify_metadata_object (OstreeObjectType objtype, const char *expected_checksum, + GVariant *metadata, GError **error) { g_assert (expected_checksum); - g_auto(OtChecksum) hasher = { 0, }; + const guint8 *data = ot_variant_get_data (metadata, error); + if (!data) + return FALSE; + + g_auto (OtChecksum) hasher = { + 0, + }; ot_checksum_init (&hasher); - ot_checksum_update (&hasher, g_variant_get_data (metadata), g_variant_get_size (metadata)); + ot_checksum_update (&hasher, data, g_variant_get_size (metadata)); - char actual_checksum[OSTREE_SHA256_STRING_LEN+1]; + char actual_checksum[OSTREE_SHA256_STRING_LEN + 1]; ot_checksum_get_hexdigest (&hasher, actual_checksum, sizeof (actual_checksum)); if (!_ostree_compare_object_checksum (objtype, expected_checksum, actual_checksum, error)) return FALSE; /* Add the checksum + objtype prefix here */ - { const char *error_prefix = glnx_strjoina (expected_checksum, ".", ostree_object_type_to_string (objtype)); - GLNX_AUTO_PREFIX_ERROR(error_prefix, error); + { + const char *error_prefix + = glnx_strjoina (expected_checksum, ".", ostree_object_type_to_string (objtype)); + GLNX_AUTO_PREFIX_ERROR (error_prefix, error); if (!_ostree_validate_structureof_metadata (objtype, metadata, error)) return FALSE; } @@ -2255,18 +2131,17 @@ _ostree_verify_metadata_object (OstreeObjectType objtype, * Returns: %TRUE if @commit is structurally valid */ gboolean -ostree_validate_structureof_commit (GVariant *commit, - GError **error) +ostree_validate_structureof_commit (GVariant *commit, GError **error) { if (!validate_variant (commit, OSTREE_COMMIT_GVARIANT_FORMAT, error)) return FALSE; - g_autoptr(GVariant) metadata = NULL; + g_autoptr (GVariant) metadata = NULL; g_variant_get_child (commit, 0, "@a{sv}", &metadata); g_assert (metadata != NULL); - g_autoptr(GVariantIter) metadata_iter = g_variant_iter_new (metadata); + g_autoptr (GVariantIter) metadata_iter = g_variant_iter_new (metadata); g_assert (metadata_iter != NULL); - g_autoptr(GVariant) metadata_entry = NULL; + g_autoptr (GVariant) metadata_entry = NULL; const gchar *metadata_key = NULL; while (g_variant_iter_loop (metadata_iter, "{sv}", &metadata_key, NULL)) { @@ -2274,25 +2149,25 @@ ostree_validate_structureof_commit (GVariant *commit, return glnx_throw (error, "Empty metadata key"); } - g_autoptr(GVariant) parent_csum_v = NULL; + g_autoptr (GVariant) parent_csum_v = NULL; g_variant_get_child (commit, 1, "@ay", &parent_csum_v); gsize n_elts; - (void) g_variant_get_fixed_array (parent_csum_v, &n_elts, 1); + (void)g_variant_get_fixed_array (parent_csum_v, &n_elts, 1); if (n_elts > 0) { if (!ostree_validate_structureof_csum_v (parent_csum_v, error)) - return FALSE; + return glnx_prefix_error (error, "Invalid commit parent"); } - g_autoptr(GVariant) content_csum_v = NULL; + g_autoptr (GVariant) content_csum_v = NULL; g_variant_get_child (commit, 6, "@ay", &content_csum_v); if (!ostree_validate_structureof_csum_v (content_csum_v, error)) - return FALSE; + return glnx_prefix_error (error, "Invalid commit tree content checksum"); - g_autoptr(GVariant) metadata_csum_v = NULL; + g_autoptr (GVariant) metadata_csum_v = NULL; g_variant_get_child (commit, 7, "@ay", &metadata_csum_v); if (!ostree_validate_structureof_csum_v (metadata_csum_v, error)) - return FALSE; + return glnx_prefix_error (error, "Invalid commit tree metadata checksum"); return TRUE; } @@ -2308,21 +2183,19 @@ ostree_validate_structureof_commit (GVariant *commit, * Returns: %TRUE if @dirtree is structurally valid */ gboolean -ostree_validate_structureof_dirtree (GVariant *dirtree, - GError **error) +ostree_validate_structureof_dirtree (GVariant *dirtree, GError **error) { const char *filename; - g_autoptr(GVariant) content_csum_v = NULL; - g_autoptr(GVariant) meta_csum_v = NULL; - g_autoptr(GVariantIter) contents_iter = NULL; + g_autoptr (GVariant) content_csum_v = NULL; + g_autoptr (GVariant) meta_csum_v = NULL; + g_autoptr (GVariantIter) contents_iter = NULL; if (!validate_variant (dirtree, OSTREE_TREE_GVARIANT_FORMAT, error)) return FALSE; g_variant_get_child (dirtree, 0, "a(say)", &contents_iter); - while (g_variant_iter_loop (contents_iter, "(&s@ay)", - &filename, &content_csum_v)) + while (g_variant_iter_loop (contents_iter, "(&s@ay)", &filename, &content_csum_v)) { if (!ot_util_filename_validate (filename, error)) return FALSE; @@ -2337,8 +2210,8 @@ ostree_validate_structureof_dirtree (GVariant *dirtree, g_variant_iter_free (contents_iter); g_variant_get_child (dirtree, 1, "a(sayay)", &contents_iter); - while (g_variant_iter_loop (contents_iter, "(&s@ay@ay)", - &filename, &content_csum_v, &meta_csum_v)) + while ( + g_variant_iter_loop (contents_iter, "(&s@ay@ay)", &filename, &content_csum_v, &meta_csum_v)) { if (!ot_util_filename_validate (filename, error)) return FALSE; @@ -2357,16 +2230,14 @@ ostree_validate_structureof_dirtree (GVariant *dirtree, * bare-user-only mode. It's opt-in though for all pulls. */ gboolean -_ostree_validate_bareuseronly_mode (guint32 content_mode, - const char *checksum, - GError **error) +_ostree_validate_bareuseronly_mode (guint32 content_mode, const char *checksum, GError **error) { if (S_ISREG (content_mode)) { const guint32 invalid_modebits = ((content_mode & ~S_IFMT) & ~0775); if (invalid_modebits > 0) - return glnx_throw (error, "Content object %s: invalid mode 0%04o with bits 0%04o", - checksum, content_mode, invalid_modebits); + return glnx_throw (error, "Content object %s: invalid mode 0%04o with bits 0%04o", checksum, + content_mode, invalid_modebits); } else if (S_ISLNK (content_mode)) ; /* Nothing */ @@ -2377,11 +2248,9 @@ _ostree_validate_bareuseronly_mode (guint32 content_mode, } static gboolean -validate_stat_mode_perms (guint32 mode, - GError **error) +validate_stat_mode_perms (guint32 mode, GError **error) { - guint32 otherbits = (~S_IFMT & ~S_IRWXU & ~S_IRWXG & ~S_IRWXO & - ~S_ISUID & ~S_ISGID & ~S_ISVTX); + guint32 otherbits = (~S_IFMT & ~S_IRWXU & ~S_IRWXG & ~S_IRWXO & ~S_ISUID & ~S_ISGID & ~S_ISVTX); if (mode & otherbits) return glnx_throw (error, "Invalid mode %u; invalid bits in mode", mode); @@ -2397,8 +2266,7 @@ validate_stat_mode_perms (guint32 mode, * Returns: %TRUE if @mode represents a valid file type and permissions */ gboolean -ostree_validate_structureof_file_mode (guint32 mode, - GError **error) +ostree_validate_structureof_file_mode (guint32 mode, GError **error) { if (!(S_ISREG (mode) || S_ISLNK (mode))) return glnx_throw (error, "Invalid file metadata mode %u; not a valid file type", mode); @@ -2419,8 +2287,7 @@ ostree_validate_structureof_file_mode (guint32 mode, * Returns: %TRUE if @dirmeta is structurally valid */ gboolean -ostree_validate_structureof_dirmeta (GVariant *dirmeta, - GError **error) +ostree_validate_structureof_dirmeta (GVariant *dirmeta, GError **error) { guint32 mode; @@ -2443,13 +2310,13 @@ ostree_validate_structureof_dirmeta (GVariant *dirmeta, * ostree_commit_get_parent: * @commit_variant: Variant of type %OSTREE_OBJECT_TYPE_COMMIT * - * Returns: Checksum of the parent commit of @commit_variant, or %NULL + * Returns: (nullable): Checksum of the parent commit of @commit_variant, or %NULL * if none */ gchar * -ostree_commit_get_parent (GVariant *commit_variant) +ostree_commit_get_parent (GVariant *commit_variant) { - g_autoptr(GVariant) bytes = NULL; + g_autoptr (GVariant) bytes = NULL; bytes = g_variant_get_child_value (commit_variant, 1); if (g_variant_n_children (bytes) == 0) return NULL; @@ -2464,14 +2331,13 @@ ostree_commit_get_parent (GVariant *commit_variant) * Since: 2016.3 */ guint64 -ostree_commit_get_timestamp (GVariant *commit_variant) +ostree_commit_get_timestamp (GVariant *commit_variant) { guint64 ret; g_variant_get_child (commit_variant, 5, "t", &ret); return GUINT64_FROM_BE (ret); } - /** * ostree_commit_get_content_checksum: * @commit_variant: A commit object @@ -2484,9 +2350,9 @@ ostree_commit_get_timestamp (GVariant *commit_variant) * By comparing checksums of content, it's possible to easily distinguish * cases where nothing actually changed. * - * The content checksums is simply defined as `SHA256(root dirtree_checksum || root_dirmeta_checksum)`, - * i.e. the SHA-256 of the root "dirtree" object's checksum concatenated with the - * root "dirmeta" checksum (both in binary form, not hexadecimal). + * The content checksums is simply defined as `SHA256(root dirtree_checksum || + * root_dirmeta_checksum)`, i.e. the SHA-256 of the root "dirtree" object's checksum concatenated + * with the root "dirmeta" checksum (both in binary form, not hexadecimal). * * Returns: (nullable): A SHA-256 hex string, or %NULL if @commit_variant is not well-formed * @@ -2495,11 +2361,13 @@ ostree_commit_get_timestamp (GVariant *commit_variant) gchar * ostree_commit_get_content_checksum (GVariant *commit_variant) { - g_auto(OtChecksum) checksum = { 0, }; + g_auto (OtChecksum) checksum = { + 0, + }; ot_checksum_init (&checksum); - g_autoptr(GVariant) tree_contents_csum = NULL; - g_autoptr(GVariant) tree_meta_csum = NULL; + g_autoptr (GVariant) tree_contents_csum = NULL; + g_autoptr (GVariant) tree_meta_csum = NULL; g_variant_get_child (commit_variant, 6, "@ay", &tree_contents_csum); g_variant_get_child (commit_variant, 7, "@ay", &tree_meta_csum); @@ -2513,7 +2381,7 @@ ostree_commit_get_content_checksum (GVariant *commit_variant) if (!bytes) return NULL; ot_checksum_update (&checksum, bytes, OSTREE_SHA256_DIGEST_LEN); - char hexdigest[OSTREE_SHA256_STRING_LEN+1]; + char hexdigest[OSTREE_SHA256_STRING_LEN + 1]; ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest)); return g_strdup (hexdigest); } @@ -2535,14 +2403,12 @@ G_DEFINE_BOXED_TYPE (OstreeCommitSizesEntry, ostree_commit_sizes_entry, * Since: 2020.1 */ OstreeCommitSizesEntry * -ostree_commit_sizes_entry_new (const gchar *checksum, - OstreeObjectType objtype, - guint64 unpacked, - guint64 archived) +ostree_commit_sizes_entry_new (const gchar *checksum, OstreeObjectType objtype, guint64 unpacked, + guint64 archived) { g_return_val_if_fail (checksum == NULL || ostree_validate_checksum_string (checksum, NULL), NULL); - g_autoptr(OstreeCommitSizesEntry) entry = g_new0 (OstreeCommitSizesEntry, 1); + g_autoptr (OstreeCommitSizesEntry) entry = g_new0 (OstreeCommitSizesEntry, 1); entry->checksum = g_strdup (checksum); entry->objtype = objtype; entry->unpacked = unpacked; @@ -2565,9 +2431,7 @@ ostree_commit_sizes_entry_copy (const OstreeCommitSizesEntry *entry) { g_return_val_if_fail (entry != NULL, NULL); - return ostree_commit_sizes_entry_new (entry->checksum, - entry->objtype, - entry->unpacked, + return ostree_commit_sizes_entry_new (entry->checksum, entry->objtype, entry->unpacked, entry->archived); } @@ -2589,9 +2453,7 @@ ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry) } static gboolean -read_sizes_entry (GVariant *entry, - OstreeCommitSizesEntry **out_sizes, - GError **error) +read_sizes_entry (GVariant *entry, OstreeCommitSizesEntry **out_sizes, GError **error) { gsize entry_size = g_variant_get_size (entry); g_return_val_if_fail (entry_size >= OSTREE_SHA256_DIGEST_LEN + 2, FALSE); @@ -2624,8 +2486,7 @@ read_sizes_entry (GVariant *entry, { objtype = *buffer; if (objtype < OSTREE_OBJECT_TYPE_FILE || objtype > OSTREE_OBJECT_TYPE_LAST) - return glnx_throw (error, "Unexpected ostree.sizes object type %u", - objtype); + return glnx_throw (error, "Unexpected ostree.sizes object type %u", objtype); buffer++; entry_size--; } @@ -2635,10 +2496,8 @@ read_sizes_entry (GVariant *entry, objtype = OSTREE_OBJECT_TYPE_FILE; } - g_autoptr(OstreeCommitSizesEntry) sizes = ostree_commit_sizes_entry_new (checksum, - objtype, - unpacked, - archived); + g_autoptr (OstreeCommitSizesEntry) sizes + = ostree_commit_sizes_entry_new (checksum, objtype, unpacked, archived); if (out_sizes != NULL) *out_sizes = g_steal_pointer (&sizes); @@ -2662,16 +2521,14 @@ read_sizes_entry (GVariant *entry, * Since: 2020.1 */ gboolean -ostree_commit_get_object_sizes (GVariant *commit_variant, - GPtrArray **out_sizes_entries, - GError **error) +ostree_commit_get_object_sizes (GVariant *commit_variant, GPtrArray **out_sizes_entries, + GError **error) { g_return_val_if_fail (commit_variant != NULL, FALSE); - g_autoptr(GVariant) metadata = g_variant_get_child_value (commit_variant, 0); - g_autoptr(GVariant) sizes_variant = - g_variant_lookup_value (metadata, "ostree.sizes", - G_VARIANT_TYPE ("a" _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE)); + g_autoptr (GVariant) metadata = g_variant_get_child_value (commit_variant, 0); + g_autoptr (GVariant) sizes_variant = g_variant_lookup_value ( + metadata, "ostree.sizes", G_VARIANT_TYPE ("a" _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE)); if (sizes_variant == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, @@ -2679,9 +2536,9 @@ ostree_commit_get_object_sizes (GVariant *commit_variant, return FALSE; } - g_autoptr(GPtrArray) sizes_entries = - g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_commit_sizes_entry_free); - g_autoptr(GVariant) entry = NULL; + g_autoptr (GPtrArray) sizes_entries + = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_commit_sizes_entry_free); + g_autoptr (GVariant) entry = NULL; GVariantIter entry_iter; g_variant_iter_init (&entry_iter, sizes_variant); while ((entry = g_variant_iter_next_value (&entry_iter))) @@ -2701,11 +2558,8 @@ ostree_commit_get_object_sizes (GVariant *commit_variant, /* Used in pull/deploy to validate we're not being downgraded */ gboolean -_ostree_compare_timestamps (const char *current_rev, - guint64 current_ts, - const char *new_rev, - guint64 new_ts, - GError **error) +_ostree_compare_timestamps (const char *current_rev, guint64 current_ts, const char *new_rev, + guint64 new_ts, GError **error) { /* Newer timestamp is OK */ if (new_ts > current_ts) @@ -2715,44 +2569,45 @@ _ostree_compare_timestamps (const char *current_rev, return TRUE; /* Looks like a downgrade, format an error message */ - g_autoptr(GDateTime) current_dt = g_date_time_new_from_unix_utc (current_ts); - g_autoptr(GDateTime) new_dt = g_date_time_new_from_unix_utc (new_ts); + g_autoptr (GDateTime) current_dt = g_date_time_new_from_unix_utc (current_ts); + g_autoptr (GDateTime) new_dt = g_date_time_new_from_unix_utc (new_ts); if (current_dt == NULL || new_dt == NULL) - return glnx_throw (error, "Upgrade target revision '%s' timestamp (%" G_GINT64_FORMAT ") or current revision '%s' timestamp (%" G_GINT64_FORMAT ") is invalid", - new_rev, new_ts, - current_rev, current_ts); + return glnx_throw (error, + "Upgrade target revision '%s' timestamp (%" G_GINT64_FORMAT + ") or current revision '%s' timestamp (%" G_GINT64_FORMAT ") is invalid", + new_rev, new_ts, current_rev, current_ts); g_autofree char *current_ts_str = g_date_time_format (current_dt, "%c"); g_autofree char *new_ts_str = g_date_time_format (new_dt, "%c"); - return glnx_throw (error, "Upgrade target revision '%s' with timestamp '%s' is chronologically older than current revision '%s' with timestamp '%s'; use --allow-downgrade to permit", - new_rev, new_ts_str, current_rev, current_ts_str); + return glnx_throw ( + error, + "Upgrade target revision '%s' with timestamp '%s' is chronologically older than current " + "revision '%s' with timestamp '%s'; use --allow-downgrade to permit", + new_rev, new_ts_str, current_rev, current_ts_str); } - #ifndef OSTREE_DISABLE_GPGME GVariant * -_ostree_detached_metadata_append_gpg_sig (GVariant *existing_metadata, - GBytes *signature_bytes) +_ostree_detached_metadata_append_gpg_sig (GVariant *existing_metadata, GBytes *signature_bytes) { GVariantDict metadata_dict; - g_autoptr(GVariant) signature_data = NULL; - g_autoptr(GVariantBuilder) signature_builder = NULL; + g_autoptr (GVariant) signature_data = NULL; + g_autoptr (GVariantBuilder) signature_builder = NULL; g_variant_dict_init (&metadata_dict, existing_metadata); - signature_data = g_variant_dict_lookup_value (&metadata_dict, - _OSTREE_METADATA_GPGSIGS_NAME, + signature_data = g_variant_dict_lookup_value (&metadata_dict, _OSTREE_METADATA_GPGSIGS_NAME, _OSTREE_METADATA_GPGSIGS_TYPE); /* signature_data may be NULL */ - signature_builder = ot_util_variant_builder_from_variant (signature_data, _OSTREE_METADATA_GPGSIGS_TYPE); + signature_builder + = ot_util_variant_builder_from_variant (signature_data, _OSTREE_METADATA_GPGSIGS_TYPE); g_variant_builder_add (signature_builder, "@ay", ot_gvariant_new_ay_bytes (signature_bytes)); - g_variant_dict_insert_value (&metadata_dict, - _OSTREE_METADATA_GPGSIGS_NAME, + g_variant_dict_insert_value (&metadata_dict, _OSTREE_METADATA_GPGSIGS_NAME, g_variant_builder_end (signature_builder)); return g_variant_ref_sink (g_variant_dict_end (&metadata_dict)); @@ -2798,5 +2653,5 @@ _ostree_get_default_sysroot_path (void) gboolean ostree_check_version (guint required_year, guint required_release) { - return OSTREE_CHECK_VERSION(required_year, required_release); + return OSTREE_CHECK_VERSION (required_year, required_release); } diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h index 0d4dca8..12a1e48 100644 --- a/src/libostree/ostree-core.h +++ b/src/libostree/ostree-core.h @@ -21,9 +21,9 @@ #pragma once -#include #include #include +#include G_BEGIN_DECLS @@ -35,7 +35,7 @@ G_BEGIN_DECLS * objects). This is an arbitrary number intended to mitigate disk space * exhaustion attacks. */ -#define OSTREE_MAX_METADATA_SIZE (10 * 1024 * 1024) +#define OSTREE_MAX_METADATA_SIZE (128 * 1024 * 1024) /** * OSTREE_MAX_METADATA_WARN_SIZE: @@ -68,21 +68,23 @@ G_BEGIN_DECLS * @OSTREE_OBJECT_TYPE_COMMIT_META: Detached metadata for a commit * @OSTREE_OBJECT_TYPE_PAYLOAD_LINK: Symlink to a .file given its checksum on the payload only. * @OSTREE_OBJECT_TYPE_FILE_XATTRS: Detached xattrs content, for 'bare-split-xattrs' mode. - * @OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK: Hardlink to a .file-xattrs given the checksum of its .file object. + * @OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK: Hardlink to a .file-xattrs given the checksum of its .file + * object. * * Enumeration for core object types; %OSTREE_OBJECT_TYPE_FILE is for * content, the other types are metadata. */ -typedef enum { - OSTREE_OBJECT_TYPE_FILE = 1, /* .file */ - OSTREE_OBJECT_TYPE_DIR_TREE = 2, /* .dirtree */ - OSTREE_OBJECT_TYPE_DIR_META = 3, /* .dirmeta */ - OSTREE_OBJECT_TYPE_COMMIT = 4, /* .commit */ - OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT = 5, /* .commit-tombstone */ - OSTREE_OBJECT_TYPE_COMMIT_META = 6, /* .commitmeta */ - OSTREE_OBJECT_TYPE_PAYLOAD_LINK = 7, /* .payload-link */ - OSTREE_OBJECT_TYPE_FILE_XATTRS = 8, /* .file-xattrs */ - OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK = 9, /* .file-xattrs-link */ +typedef enum +{ + OSTREE_OBJECT_TYPE_FILE = 1, /* .file */ + OSTREE_OBJECT_TYPE_DIR_TREE = 2, /* .dirtree */ + OSTREE_OBJECT_TYPE_DIR_META = 3, /* .dirmeta */ + OSTREE_OBJECT_TYPE_COMMIT = 4, /* .commit */ + OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT = 5, /* .commit-tombstone */ + OSTREE_OBJECT_TYPE_COMMIT_META = 6, /* .commitmeta */ + OSTREE_OBJECT_TYPE_PAYLOAD_LINK = 7, /* .payload-link */ + OSTREE_OBJECT_TYPE_FILE_XATTRS = 8, /* .file-xattrs */ + OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK = 9, /* .file-xattrs-link */ } OstreeObjectType; /** @@ -154,7 +156,8 @@ typedef enum { /** * OSTREE_SUMMARY_GVARIANT_FORMAT: * - * - a(s(taya{sv})) - Map of ref name -> (latest commit size, latest commit checksum, additional metadata), sorted by ref name + * - a(s(taya{sv})) - Map of ref name -> (latest commit size, latest commit checksum, additional + * metadata), sorted by ref name * - a{sv} - Additional metadata, at the current time the following are defined: * - key: "ostree.static-deltas", value: a{sv}, static delta name -> 32 bytes of checksum * - key: "ostree.summary.last-modified", value: t, timestamp (seconds since @@ -188,17 +191,23 @@ typedef enum { /** * OstreeRepoMode: - * @OSTREE_REPO_MODE_BARE: Files are stored as themselves; checkouts are hardlinks; can only be written as root - * @OSTREE_REPO_MODE_ARCHIVE: Files are compressed, should be owned by non-root. Can be served via HTTP. Since: 2017.12 + * @OSTREE_REPO_MODE_BARE: Files are stored as themselves; checkouts are hardlinks; can only be + * written as root + * @OSTREE_REPO_MODE_ARCHIVE: Files are compressed, should be owned by non-root. Can be served via + * HTTP. Since: 2017.12 * @OSTREE_REPO_MODE_ARCHIVE_Z2: Legacy alias for `OSTREE_REPO_MODE_ARCHIVE` - * @OSTREE_REPO_MODE_BARE_USER: Files are stored as themselves, except ownership; can be written by user. Hardlinks work only in user checkouts. - * @OSTREE_REPO_MODE_BARE_USER_ONLY: Same as BARE_USER, but all metadata is not stored, so it can only be used for user checkouts. Does not need xattrs. - * @OSTREE_REPO_MODE_BARE_SPLIT_XATTRS: Same as BARE_USER, but xattrs are stored separately from file content, with dedicated object types. + * @OSTREE_REPO_MODE_BARE_USER: Files are stored as themselves, except ownership; can be written by + * user. Hardlinks work only in user checkouts. + * @OSTREE_REPO_MODE_BARE_USER_ONLY: Same as BARE_USER, but all metadata is not stored, so it can + * only be used for user checkouts. Does not need xattrs. + * @OSTREE_REPO_MODE_BARE_SPLIT_XATTRS: Same as BARE_USER, but xattrs are stored separately from + * file content, with dedicated object types. * * See the documentation of #OstreeRepo for more information about the * possible modes. */ -typedef enum { +typedef enum +{ OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_ARCHIVE, OSTREE_REPO_MODE_ARCHIVE_Z2 = OSTREE_REPO_MODE_ARCHIVE, @@ -222,10 +231,10 @@ typedef enum { /** * OSTREE_COMMIT_META_KEY_ARCHITECTURE: * - * GVariant type `s`. Intended to describe the CPU architecture. This is a freeform string, and some distributions - * which have existing package managers might want to match that schema. If you - * don't have a prior schema, it's recommended to use `uname -m` by default (i.e. the Linux kernel schema). In the future - * ostree might include a builtin function to compare architectures. + * GVariant type `s`. Intended to describe the CPU architecture. This is a freeform string, and + * some distributions which have existing package managers might want to match that schema. If you + * don't have a prior schema, it's recommended to use `uname -m` by default (i.e. the Linux kernel + * schema). In the future ostree might include a builtin function to compare architectures. * * Since: 2020.4 */ @@ -298,8 +307,7 @@ _OSTREE_PUBLIC const GVariantType *ostree_metadata_variant_type (OstreeObjectType objtype); _OSTREE_PUBLIC -gboolean ostree_validate_checksum_string (const char *sha256, - GError **error); +gboolean ostree_validate_checksum_string (const char *sha256, GError **error); _OSTREE_PUBLIC guchar *ostree_checksum_to_bytes (const char *checksum); @@ -308,26 +316,22 @@ GVariant *ostree_checksum_to_bytes_v (const char *checksum); _OSTREE_PUBLIC guchar *ostree_checksum_b64_to_bytes (const char *checksum); _OSTREE_PUBLIC -void ostree_checksum_b64_inplace_to_bytes (const char *checksum, - guint8 *buf); +void ostree_checksum_b64_inplace_to_bytes (const char *checksum, guint8 *buf); _OSTREE_PUBLIC -char * ostree_checksum_from_bytes (const guchar *csum); +char *ostree_checksum_from_bytes (const guchar *csum); _OSTREE_PUBLIC -char * ostree_checksum_from_bytes_v (GVariant *csum_v); +char *ostree_checksum_from_bytes_v (GVariant *csum_v); _OSTREE_PUBLIC -char * ostree_checksum_b64_from_bytes (const guchar *csum); +char *ostree_checksum_b64_from_bytes (const guchar *csum); _OSTREE_PUBLIC -void ostree_checksum_inplace_from_bytes (const guchar *csum, - char *buf); +void ostree_checksum_inplace_from_bytes (const guchar *csum, char *buf); _OSTREE_PUBLIC -void ostree_checksum_b64_inplace_from_bytes (const guchar *csum, - char *buf); +void ostree_checksum_b64_inplace_from_bytes (const guchar *csum, char *buf); _OSTREE_PUBLIC -void ostree_checksum_inplace_to_bytes (const char *checksum, - guchar *buf); +void ostree_checksum_inplace_to_bytes (const char *checksum, guchar *buf); _OSTREE_PUBLIC const guchar *ostree_checksum_bytes_peek (GVariant *bytes); @@ -348,13 +352,11 @@ _OSTREE_PUBLIC gboolean ostree_validate_remote_name (const char *remote_name, GError **error); _OSTREE_PUBLIC -gboolean ostree_parse_refspec (const char *refspec, - char **out_remote, - char **out_ref, - GError **error); +gboolean ostree_parse_refspec (const char *refspec, char **out_remote, char **out_ref, + GError **error); _OSTREE_PUBLIC -const char * ostree_object_type_to_string (OstreeObjectType objtype); +const char *ostree_object_type_to_string (OstreeObjectType objtype); _OSTREE_PUBLIC OstreeObjectType ostree_object_type_from_string (const char *str); @@ -363,112 +365,73 @@ _OSTREE_PUBLIC guint ostree_hash_object_name (gconstpointer a); _OSTREE_PUBLIC -GVariant *ostree_object_name_serialize (const char *checksum, - OstreeObjectType objtype); +GVariant *ostree_object_name_serialize (const char *checksum, OstreeObjectType objtype); _OSTREE_PUBLIC -void ostree_object_name_deserialize (GVariant *variant, - const char **out_checksum, +void ostree_object_name_deserialize (GVariant *variant, const char **out_checksum, OstreeObjectType *out_objtype); _OSTREE_PUBLIC -char * ostree_object_to_string (const char *checksum, - OstreeObjectType objtype); +char *ostree_object_to_string (const char *checksum, OstreeObjectType objtype); _OSTREE_PUBLIC -void ostree_object_from_string (const char *str, - gchar **out_checksum, +void ostree_object_from_string (const char *str, gchar **out_checksum, OstreeObjectType *out_objtype); _OSTREE_PUBLIC -gboolean -ostree_content_stream_parse (gboolean compressed, - GInputStream *input, - guint64 input_length, - gboolean trusted, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_content_file_parse (gboolean compressed, - GFile *content_path, - gboolean trusted, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_content_file_parse_at (gboolean compressed, - int parent_dfd, - const char *path, - gboolean trusted, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean -ostree_raw_file_to_archive_z2_stream (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - GInputStream **out_input, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean -ostree_raw_file_to_archive_z2_stream_with_options (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - GVariant *options, - GInputStream **out_input, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_raw_file_to_content_stream (GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - GInputStream **out_input, - guint64 *out_length, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_checksum_file_from_input (GFileInfo *file_info, - GVariant *xattrs, - GInputStream *in, - OstreeObjectType objtype, - guchar **out_csum, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_checksum_file (GFile *f, - OstreeObjectType objtype, - guchar **out_csum, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_break_hardlink (int dfd, - const char *path, - gboolean skip_xattrs, - GCancellable *cancellable, - GError **error); +gboolean ostree_content_stream_parse (gboolean compressed, GInputStream *input, + guint64 input_length, gboolean trusted, + GInputStream **out_input, GFileInfo **out_file_info, + GVariant **out_xattrs, GCancellable *cancellable, + GError **error); + +_OSTREE_PUBLIC +gboolean ostree_content_file_parse (gboolean compressed, GFile *content_path, gboolean trusted, + GInputStream **out_input, GFileInfo **out_file_info, + GVariant **out_xattrs, GCancellable *cancellable, + GError **error); + +_OSTREE_PUBLIC +gboolean ostree_content_file_parse_at (gboolean compressed, int parent_dfd, const char *path, + gboolean trusted, GInputStream **out_input, + GFileInfo **out_file_info, GVariant **out_xattrs, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_raw_file_to_archive_z2_stream (GInputStream *input, GFileInfo *file_info, + GVariant *xattrs, GInputStream **out_input, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_raw_file_to_archive_z2_stream_with_options ( + GInputStream *input, GFileInfo *file_info, GVariant *xattrs, GVariant *options, + GInputStream **out_input, GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_raw_file_to_content_stream (GInputStream *input, GFileInfo *file_info, + GVariant *xattrs, GInputStream **out_input, + guint64 *out_length, GCancellable *cancellable, + GError **error); + +_OSTREE_PUBLIC +gboolean ostree_checksum_file_from_input (GFileInfo *file_info, GVariant *xattrs, GInputStream *in, + OstreeObjectType objtype, guchar **out_csum, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_checksum_file (GFile *f, OstreeObjectType objtype, guchar **out_csum, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_break_hardlink (int dfd, const char *path, gboolean skip_xattrs, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC GVariant *ostree_fs_get_all_xattrs (int fd, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -GVariant *ostree_fs_get_all_xattrs_at (int dfd, const char *path, GCancellable *cancellable, GError **error); +GVariant *ostree_fs_get_all_xattrs_at (int dfd, const char *path, GCancellable *cancellable, + GError **error); /** * OstreeChecksumFlags: @@ -483,77 +446,60 @@ GVariant *ostree_fs_get_all_xattrs_at (int dfd, const char *path, GCancellable * * * Since: 2017.13 */ -typedef enum { +typedef enum +{ OSTREE_CHECKSUM_FLAGS_NONE = 0, OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS = (1 << 0), OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS = (1 << 1), } OstreeChecksumFlags; _OSTREE_PUBLIC -gboolean ostree_checksum_file_at (int dfd, - const char *path, - struct stat *stbuf, - OstreeObjectType objtype, - OstreeChecksumFlags flags, - char **out_checksum, - GCancellable *cancellable, - GError **error); +gboolean ostree_checksum_file_at (int dfd, const char *path, struct stat *stbuf, + OstreeObjectType objtype, OstreeChecksumFlags flags, + char **out_checksum, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -void ostree_checksum_file_async (GFile *f, - OstreeObjectType objtype, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +void ostree_checksum_file_async (GFile *f, OstreeObjectType objtype, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data); _OSTREE_PUBLIC -gboolean ostree_checksum_file_async_finish (GFile *f, - GAsyncResult *result, - guchar **out_csum, - GError **error); +gboolean ostree_checksum_file_async_finish (GFile *f, GAsyncResult *result, guchar **out_csum, + GError **error); _OSTREE_PUBLIC -GVariant *ostree_create_directory_metadata (GFileInfo *dir_info, - GVariant *xattrs); +GVariant *ostree_create_directory_metadata (GFileInfo *dir_info, GVariant *xattrs); /* VALIDATION */ _OSTREE_PUBLIC -gboolean ostree_validate_structureof_objtype (guchar objtype, - GError **error); +gboolean ostree_validate_structureof_objtype (guchar objtype, GError **error); _OSTREE_PUBLIC -gboolean ostree_validate_structureof_csum_v (GVariant *checksum, - GError **error); +gboolean ostree_validate_structureof_csum_v (GVariant *checksum, GError **error); _OSTREE_PUBLIC -gboolean ostree_validate_structureof_checksum_string (const char *checksum, - GError **error); +gboolean ostree_validate_structureof_checksum_string (const char *checksum, GError **error); _OSTREE_PUBLIC -gboolean ostree_validate_structureof_file_mode (guint32 mode, - GError **error); +gboolean ostree_validate_structureof_file_mode (guint32 mode, GError **error); _OSTREE_PUBLIC -gboolean ostree_validate_structureof_commit (GVariant *commit, - GError **error); +gboolean ostree_validate_structureof_commit (GVariant *commit, GError **error); _OSTREE_PUBLIC -gboolean ostree_validate_structureof_dirtree (GVariant *dirtree, - GError **error); +gboolean ostree_validate_structureof_dirtree (GVariant *dirtree, GError **error); _OSTREE_PUBLIC -gboolean ostree_validate_structureof_dirmeta (GVariant *dirmeta, - GError **error); +gboolean ostree_validate_structureof_dirmeta (GVariant *dirmeta, GError **error); _OSTREE_PUBLIC -gchar * ostree_commit_get_parent (GVariant *commit_variant); +gchar *ostree_commit_get_parent (GVariant *commit_variant); _OSTREE_PUBLIC -guint64 ostree_commit_get_timestamp (GVariant *commit_variant); +guint64 ostree_commit_get_timestamp (GVariant *commit_variant); _OSTREE_PUBLIC -gchar * ostree_commit_get_content_checksum (GVariant *commit_variant); +gchar *ostree_commit_get_content_checksum (GVariant *commit_variant); /** * OstreeCommitSizesEntry: @@ -567,7 +513,8 @@ gchar * ostree_commit_get_content_checksum (GVariant *commit_variant); * * Since: 2020.1 */ -typedef struct { +typedef struct +{ gchar *checksum; OstreeObjectType objtype; guint64 unpacked; @@ -578,19 +525,17 @@ _OSTREE_PUBLIC GType ostree_commit_sizes_entry_get_type (void); _OSTREE_PUBLIC -OstreeCommitSizesEntry *ostree_commit_sizes_entry_new (const gchar *checksum, - OstreeObjectType objtype, - guint64 unpacked, - guint64 archived); +OstreeCommitSizesEntry *ostree_commit_sizes_entry_new (const gchar *checksum, + OstreeObjectType objtype, guint64 unpacked, + guint64 archived); _OSTREE_PUBLIC OstreeCommitSizesEntry *ostree_commit_sizes_entry_copy (const OstreeCommitSizesEntry *entry); _OSTREE_PUBLIC -void ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry); +void ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry); _OSTREE_PUBLIC -gboolean ostree_commit_get_object_sizes (GVariant *commit_variant, - GPtrArray **out_sizes_entries, - GError **error); +gboolean ostree_commit_get_object_sizes (GVariant *commit_variant, GPtrArray **out_sizes_entries, + GError **error); _OSTREE_PUBLIC gboolean ostree_check_version (guint required_year, guint required_release); diff --git a/src/libostree/ostree-date-utils-private.h b/src/libostree/ostree-date-utils-private.h index f48a696..f0e2432 100644 --- a/src/libostree/ostree-date-utils-private.h +++ b/src/libostree/ostree-date-utils-private.h @@ -28,8 +28,7 @@ G_BEGIN_DECLS -GDateTime *_ostree_parse_rfc2616_date_time (const char *buf, - size_t len); +GDateTime *_ostree_parse_rfc2616_date_time (const char *buf, size_t len); G_END_DECLS diff --git a/src/libostree/ostree-date-utils.c b/src/libostree/ostree-date-utils.c index a715691..07aecd3 100644 --- a/src/libostree/ostree-date-utils.c +++ b/src/libostree/ostree-date-utils.c @@ -30,29 +30,23 @@ /* @buf must already be known to be long enough */ static gboolean -parse_uint (const char *buf, - guint n_digits, - guint min, - guint max, - guint *out) +parse_uint (const char *buf, guint n_digits, guint min, guint max, guint *out) { guint64 number; const char *end_ptr = NULL; gint saved_errno = 0; - g_return_val_if_fail (n_digits == 2 || n_digits == 4, FALSE); - g_return_val_if_fail (out != NULL, FALSE); + g_assert (out != NULL); + + if (!(n_digits == 2 || n_digits == 4)) + return FALSE; errno = 0; number = g_ascii_strtoull (buf, (gchar **)&end_ptr, 10); saved_errno = errno; - if (!g_ascii_isdigit (buf[0]) || - saved_errno != 0 || - end_ptr == NULL || - end_ptr != buf + n_digits || - number < min || - number > max) + if (!g_ascii_isdigit (buf[0]) || saved_errno != 0 || end_ptr == NULL || end_ptr != buf + n_digits + || number < min || number > max) return FALSE; *out = number; @@ -73,36 +67,16 @@ parse_uint (const char *buf, * Wed, 21 Oct 2015 07:28:00 GMT */ GDateTime * -_ostree_parse_rfc2616_date_time (const char *buf, - size_t len) +_ostree_parse_rfc2616_date_time (const char *buf, size_t len) { guint day_int, year_int, hour_int, minute_int, second_int; - const char *day_names[] = - { - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat", - "Sun", - }; + const char *day_names[] = { + "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", + }; size_t day_name_index; - const char *month_names[] = - { - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec", - }; + const char *month_names[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; size_t month_name_index; if (len != 29) @@ -152,13 +126,13 @@ _ostree_parse_rfc2616_date_time (const char *buf, return NULL; if (*(minute + 2) != ':') return NULL; - if (!parse_uint (second, 2, 0, 60, &second_int)) /* allow leap seconds */ + if (!parse_uint (second, 2, 0, 60, &second_int)) /* allow leap seconds */ return NULL; if (*(second + 2) != ' ') return NULL; if (strncmp (tz, "GMT", 3) != 0) return NULL; - return g_date_time_new_utc (year_int, month_name_index + 1, day_int, - hour_int, minute_int, second_int); + return g_date_time_new_utc (year_int, month_name_index + 1, day_int, hour_int, minute_int, + second_int); } diff --git a/src/libostree/ostree-deployment-private.h b/src/libostree/ostree-deployment-private.h index 5d16798..2a28bff 100644 --- a/src/libostree/ostree-deployment-private.h +++ b/src/libostree/ostree-deployment-private.h @@ -21,7 +21,6 @@ G_BEGIN_DECLS - /** * OstreeDeployment: * @parent_instance: @@ -40,7 +39,7 @@ G_BEGIN_DECLS */ struct _OstreeDeployment { - GObject parent_instance; + GObject parent_instance; int index; char *osname; @@ -58,9 +57,8 @@ struct _OstreeDeployment void _ostree_deployment_set_bootcsum (OstreeDeployment *self, const char *bootcsum); -void _ostree_deployment_set_overlay_initrds (OstreeDeployment *self, - char **overlay_initrds); +void _ostree_deployment_set_overlay_initrds (OstreeDeployment *self, char **overlay_initrds); -char** _ostree_deployment_get_overlay_initrds (OstreeDeployment *self); +char **_ostree_deployment_get_overlay_initrds (OstreeDeployment *self); G_END_DECLS diff --git a/src/libostree/ostree-deployment.c b/src/libostree/ostree-deployment.c index 30e82a6..1480d74 100644 --- a/src/libostree/ostree-deployment.c +++ b/src/libostree/ostree-deployment.c @@ -17,9 +17,9 @@ #include "config.h" -#include "otutil.h" -#include "ostree.h" #include "ostree-deployment-private.h" +#include "ostree.h" +#include "otutil.h" typedef GObjectClass OstreeDeploymentClass; @@ -89,7 +89,7 @@ ostree_deployment_get_bootserial (OstreeDeployment *self) * ostree_deployment_get_bootconfig: * @self: Deployment * - * Returns: (transfer none): Boot configuration + * Returns: (transfer none) (nullable): Boot configuration */ OstreeBootconfigParser * ostree_deployment_get_bootconfig (OstreeDeployment *self) @@ -101,7 +101,7 @@ ostree_deployment_get_bootconfig (OstreeDeployment *self) * ostree_deployment_get_origin: * @self: Deployment * - * Returns: (transfer none): Origin + * Returns: (transfer none) (nullable): Origin */ GKeyFile * ostree_deployment_get_origin (OstreeDeployment *self) @@ -157,9 +157,7 @@ ostree_deployment_set_bootserial (OstreeDeployment *self, int index) void ostree_deployment_set_bootconfig (OstreeDeployment *self, OstreeBootconfigParser *bootconfig) { - g_clear_object (&self->bootconfig); - if (bootconfig) - self->bootconfig = g_object_ref (bootconfig); + g_set_object (&self->bootconfig, bootconfig); } /** @@ -173,6 +171,9 @@ ostree_deployment_set_bootconfig (OstreeDeployment *self, OstreeBootconfigParser void ostree_deployment_set_origin (OstreeDeployment *self, GKeyFile *origin) { + if (self->origin == origin) + return; + g_clear_pointer (&self->origin, g_key_file_unref); if (origin) self->origin = g_key_file_ref (origin); @@ -208,16 +209,14 @@ ostree_deployment_origin_remove_transient_state (GKeyFile *origin) } void -_ostree_deployment_set_bootcsum (OstreeDeployment *self, - const char *bootcsum) +_ostree_deployment_set_bootcsum (OstreeDeployment *self, const char *bootcsum) { g_free (self->bootcsum); self->bootcsum = g_strdup (bootcsum); } void -_ostree_deployment_set_overlay_initrds (OstreeDeployment *self, - char **overlay_initrds) +_ostree_deployment_set_overlay_initrds (OstreeDeployment *self, char **overlay_initrds) { g_clear_pointer (&self->overlay_initrds, g_strfreev); g_clear_pointer (&self->overlay_initrds_id, g_free); @@ -229,7 +228,7 @@ _ostree_deployment_set_overlay_initrds (OstreeDeployment *self, * ostree_sysroot_write_deployments_with_options() can easily compare initrds when * comparing deployments for whether a bootswap is necessary. We could be fancier here but * meh... this works. */ - g_autoptr(GString) id = g_string_new (NULL); + g_autoptr (GString) id = g_string_new (NULL); for (char **it = overlay_initrds; it && *it; it++) g_string_append (id, *it); @@ -237,7 +236,7 @@ _ostree_deployment_set_overlay_initrds (OstreeDeployment *self, self->overlay_initrds_id = g_string_free (g_steal_pointer (&id), FALSE); } -char** +char ** _ostree_deployment_get_overlay_initrds (OstreeDeployment *self) { return self->overlay_initrds; @@ -252,10 +251,9 @@ _ostree_deployment_get_overlay_initrds (OstreeDeployment *self) OstreeDeployment * ostree_deployment_clone (OstreeDeployment *self) { - g_autoptr(OstreeBootconfigParser) new_bootconfig = NULL; - OstreeDeployment *ret = ostree_deployment_new (self->index, self->osname, self->csum, - self->deployserial, - self->bootcsum, self->bootserial); + g_autoptr (OstreeBootconfigParser) new_bootconfig = NULL; + OstreeDeployment *ret = ostree_deployment_new ( + self->index, self->osname, self->csum, self->deployserial, self->bootcsum, self->bootserial); new_bootconfig = ostree_bootconfig_parser_clone (self->bootconfig); ostree_deployment_set_bootconfig (ret, new_bootconfig); @@ -264,7 +262,7 @@ ostree_deployment_clone (OstreeDeployment *self) if (self->origin) { - g_autoptr(GKeyFile) new_origin = NULL; + g_autoptr (GKeyFile) new_origin = NULL; g_autofree char *data = NULL; gsize len; gboolean success; @@ -290,10 +288,9 @@ ostree_deployment_clone (OstreeDeployment *self) guint ostree_deployment_hash (gconstpointer v) { - OstreeDeployment *d = (OstreeDeployment*)v; - return g_str_hash (ostree_deployment_get_osname (d)) + - g_str_hash (ostree_deployment_get_csum (d)) + - ostree_deployment_get_deployserial (d); + OstreeDeployment *d = (OstreeDeployment *)v; + return g_str_hash (ostree_deployment_get_osname (d)) + g_str_hash (ostree_deployment_get_csum (d)) + + ostree_deployment_get_deployserial (d); } /** @@ -306,17 +303,15 @@ ostree_deployment_hash (gconstpointer v) gboolean ostree_deployment_equal (gconstpointer ap, gconstpointer bp) { - OstreeDeployment *a = (OstreeDeployment*)ap; - OstreeDeployment *b = (OstreeDeployment*)bp; + OstreeDeployment *a = (OstreeDeployment *)ap; + OstreeDeployment *b = (OstreeDeployment *)bp; if (a == b) return TRUE; else if (a != NULL && b != NULL) - return g_str_equal (ostree_deployment_get_osname (a), - ostree_deployment_get_osname (b)) && - g_str_equal (ostree_deployment_get_csum (a), - ostree_deployment_get_csum (b)) && - ostree_deployment_get_deployserial (a) == ostree_deployment_get_deployserial (b); + return g_str_equal (ostree_deployment_get_osname (a), ostree_deployment_get_osname (b)) + && g_str_equal (ostree_deployment_get_csum (a), ostree_deployment_get_csum (b)) + && ostree_deployment_get_deployserial (a) == ostree_deployment_get_deployserial (b); else return FALSE; } @@ -362,12 +357,8 @@ ostree_deployment_class_init (OstreeDeploymentClass *class) * Returns: (transfer full) (not nullable): New deployment */ OstreeDeployment * -ostree_deployment_new (int index, - const char *osname, - const char *csum, - int deployserial, - const char *bootcsum, - int bootserial) +ostree_deployment_new (int index, const char *osname, const char *csum, int deployserial, + const char *bootcsum, int bootserial) { OstreeDeployment *self; @@ -403,8 +394,7 @@ char * ostree_deployment_get_origin_relpath (OstreeDeployment *self) { return g_strdup_printf ("ostree/deploy/%s/deploy/%s.%d.origin", - ostree_deployment_get_osname (self), - ostree_deployment_get_csum (self), + ostree_deployment_get_osname (self), ostree_deployment_get_csum (self), ostree_deployment_get_deployserial (self)); } diff --git a/src/libostree/ostree-deployment.h b/src/libostree/ostree-deployment.h index 68a0ff7..0d4a5d7 100644 --- a/src/libostree/ostree-deployment.h +++ b/src/libostree/ostree-deployment.h @@ -22,7 +22,8 @@ G_BEGIN_DECLS #define OSTREE_TYPE_DEPLOYMENT (ostree_deployment_get_type ()) -#define OSTREE_DEPLOYMENT(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_DEPLOYMENT, OstreeDeployment)) +#define OSTREE_DEPLOYMENT(inst) \ + (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_DEPLOYMENT, OstreeDeployment)) #define OSTREE_IS_DEPLOYMENT(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_DEPLOYMENT)) /** @@ -47,12 +48,8 @@ _OSTREE_PUBLIC gboolean ostree_deployment_equal (gconstpointer ap, gconstpointer bp); _OSTREE_PUBLIC -OstreeDeployment * ostree_deployment_new (int index, - const char *osname, - const char *csum, - int deployserial, - const char *bootcsum, - int bootserial); +OstreeDeployment *ostree_deployment_new (int index, const char *osname, const char *csum, + int deployserial, const char *bootcsum, int bootserial); _OSTREE_PUBLIC int ostree_deployment_get_index (OstreeDeployment *self); @@ -94,7 +91,8 @@ OstreeDeployment *ostree_deployment_clone (OstreeDeployment *self); _OSTREE_PUBLIC char *ostree_deployment_get_origin_relpath (OstreeDeployment *self); -typedef enum { +typedef enum +{ OSTREE_DEPLOYMENT_UNLOCKED_NONE, OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT, OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX, diff --git a/src/libostree/ostree-diff.c b/src/libostree/ostree-diff.c index d6d8e98..9d6a719 100644 --- a/src/libostree/ostree-diff.c +++ b/src/libostree/ostree-diff.c @@ -22,62 +22,55 @@ #include "config.h" #include "libglnx.h" -#include "ostree.h" #include "ostree-repo-private.h" +#include "ostree.h" #include "otutil.h" /* See ostree-repo.c for a bit more info about these ABI checks */ #if __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 8 && __SIZEOF_INT__ == 4 -G_STATIC_ASSERT(sizeof(OstreeDiffDirsOptions) == - sizeof(int) * 2 + - sizeof(gpointer) + - sizeof(int) * (7+6) + - sizeof(int) + /* hole */ - sizeof(gpointer) * 7); +G_STATIC_ASSERT (sizeof (OstreeDiffDirsOptions) + == sizeof (int) * 2 + sizeof (gpointer) + sizeof (int) * (7 + 6) + sizeof (int) + + /* hole */ + sizeof (gpointer) * 7); #endif static gboolean -get_file_checksum (OstreeDiffFlags flags, - GFile *f, - GFileInfo *f_info, - char **out_checksum, - GCancellable *cancellable, - GError **error) +get_file_checksum (OstreeDiffFlags flags, GFile *f, GFileInfo *f_info, char **out_checksum, + GCancellable *cancellable, GError **error) { g_autofree char *ret_checksum = NULL; if (OSTREE_IS_REPO_FILE (f)) { - ret_checksum = g_strdup (ostree_repo_file_get_checksum ((OstreeRepoFile*)f)); + ret_checksum = g_strdup (ostree_repo_file_get_checksum ((OstreeRepoFile *)f)); } else { - g_autoptr(GVariant) xattrs = NULL; - g_autoptr(GInputStream) in = NULL; + g_autoptr (GVariant) xattrs = NULL; + g_autoptr (GInputStream) in = NULL; if (!(flags & OSTREE_DIFF_FLAGS_IGNORE_XATTRS)) { - if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (f), - &xattrs, cancellable, error)) + if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (f), &xattrs, + cancellable, error)) return FALSE; } if (g_file_info_get_file_type (f_info) == G_FILE_TYPE_REGULAR) { - in = (GInputStream*)g_file_read (f, cancellable, error); + in = (GInputStream *)g_file_read (f, cancellable, error); if (!in) return FALSE; } g_autofree guchar *csum = NULL; - if (!ostree_checksum_file_from_input (f_info, xattrs, in, - OSTREE_OBJECT_TYPE_FILE, - &csum, cancellable, error)) + if (!ostree_checksum_file_from_input (f_info, xattrs, in, OSTREE_OBJECT_TYPE_FILE, &csum, + cancellable, error)) return FALSE; ret_checksum = ostree_checksum_from_bytes (csum); } - ot_transfer_out_value(out_checksum, &ret_checksum); + ot_transfer_out_value (out_checksum, &ret_checksum); return TRUE; } @@ -103,17 +96,12 @@ ostree_diff_item_unref (OstreeDiffItem *diffitem) g_free (diffitem); } -G_DEFINE_BOXED_TYPE(OstreeDiffItem, ostree_diff_item, - ostree_diff_item_ref, - ostree_diff_item_unref); +G_DEFINE_BOXED_TYPE (OstreeDiffItem, ostree_diff_item, ostree_diff_item_ref, + ostree_diff_item_unref); static OstreeDiffItem * -diff_item_new (GFile *a, - GFileInfo *a_info, - GFile *b, - GFileInfo *b_info, - char *checksum_a, - char *checksum_b) +diff_item_new (GFile *a, GFileInfo *a_info, GFile *b, GFileInfo *b_info, char *checksum_a, + char *checksum_b) { OstreeDiffItem *ret = g_new0 (OstreeDiffItem, 1); ret->refcount = 1; @@ -127,14 +115,8 @@ diff_item_new (GFile *a, } static gboolean -diff_files (OstreeDiffFlags flags, - GFile *a, - GFileInfo *a_info, - GFile *b, - GFileInfo *b_info, - OstreeDiffItem **out_item, - GCancellable *cancellable, - GError **error) +diff_files (OstreeDiffFlags flags, GFile *a, GFileInfo *a_info, GFile *b, GFileInfo *b_info, + OstreeDiffItem **out_item, GCancellable *cancellable, GError **error) { g_autofree char *checksum_a = NULL; g_autofree char *checksum_b = NULL; @@ -143,28 +125,21 @@ diff_files (OstreeDiffFlags flags, if (!get_file_checksum (flags, b, b_info, &checksum_b, cancellable, error)) return FALSE; - g_autoptr(OstreeDiffItem) ret_item = NULL; + g_autoptr (OstreeDiffItem) ret_item = NULL; if (strcmp (checksum_a, checksum_b) != 0) { - ret_item = diff_item_new (a, a_info, b, b_info, - checksum_a, checksum_b); + ret_item = diff_item_new (a, a_info, b, b_info, checksum_a, checksum_b); } - ot_transfer_out_value(out_item, &ret_item); + ot_transfer_out_value (out_item, &ret_item); return TRUE; } static gboolean -diff_add_dir_recurse (GFile *d, - GPtrArray *added, - GCancellable *cancellable, - GError **error) +diff_add_dir_recurse (GFile *d, GPtrArray *added, GCancellable *cancellable, GError **error) { - g_autoptr(GFileEnumerator) dir_enum = - g_file_enumerate_children (d, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, - error); + g_autoptr (GFileEnumerator) dir_enum = g_file_enumerate_children ( + d, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_enum) return FALSE; @@ -173,15 +148,14 @@ diff_add_dir_recurse (GFile *d, GFileInfo *child_info; const char *name; - if (!g_file_enumerator_iterate (dir_enum, &child_info, NULL, - cancellable, error)) + if (!g_file_enumerator_iterate (dir_enum, &child_info, NULL, cancellable, error)) return FALSE; if (child_info == NULL) break; name = g_file_info_get_name (child_info); - g_autoptr(GFile) child = g_file_get_child (d, name); + g_autoptr (GFile) child = g_file_get_child (d, name); g_ptr_array_add (added, g_object_ref (child)); if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY) @@ -209,18 +183,11 @@ diff_add_dir_recurse (GFile *d, * sets of #OstreeDiffItem in @modified, @removed, and @added. */ gboolean -ostree_diff_dirs (OstreeDiffFlags flags, - GFile *a, - GFile *b, - GPtrArray *modified, - GPtrArray *removed, - GPtrArray *added, - GCancellable *cancellable, - GError **error) +ostree_diff_dirs (OstreeDiffFlags flags, GFile *a, GFile *b, GPtrArray *modified, + GPtrArray *removed, GPtrArray *added, GCancellable *cancellable, GError **error) { - return ostree_diff_dirs_with_options (flags, a, b, modified, - removed, added, NULL, - cancellable, error); + return ostree_diff_dirs_with_options (flags, a, b, modified, removed, added, NULL, cancellable, + error); } /** @@ -241,23 +208,17 @@ ostree_diff_dirs (OstreeDiffFlags flags, * Since: 2017.4 */ gboolean -ostree_diff_dirs_with_options (OstreeDiffFlags flags, - GFile *a, - GFile *b, - GPtrArray *modified, - GPtrArray *removed, - GPtrArray *added, - OstreeDiffDirsOptions *options, - GCancellable *cancellable, - GError **error) +ostree_diff_dirs_with_options (OstreeDiffFlags flags, GFile *a, GFile *b, GPtrArray *modified, + GPtrArray *removed, GPtrArray *added, OstreeDiffDirsOptions *options, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GError *temp_error = NULL; - g_autoptr(GFileEnumerator) dir_enum = NULL; - g_autoptr(GFile) child_a = NULL; - g_autoptr(GFile) child_b = NULL; - g_autoptr(GFileInfo) child_a_info = NULL; - g_autoptr(GFileInfo) child_b_info = NULL; + g_autoptr (GFileEnumerator) dir_enum = NULL; + g_autoptr (GFile) child_a = NULL; + g_autoptr (GFile) child_b = NULL; + g_autoptr (GFileInfo) child_a_info = NULL; + g_autoptr (GFileInfo) child_b_info = NULL; OstreeDiffDirsOptions default_opts = OSTREE_DIFF_DIRS_OPTIONS_INIT; if (!options) @@ -268,13 +229,13 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, */ if (OSTREE_IS_REPO_FILE (a)) { - OstreeRepo *repo = ostree_repo_file_get_repo ((OstreeRepoFile*)a); + OstreeRepo *repo = ostree_repo_file_get_repo ((OstreeRepoFile *)a); if (repo->disable_xattrs || repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY) flags |= OSTREE_DIFF_FLAGS_IGNORE_XATTRS; } if (OSTREE_IS_REPO_FILE (b)) { - OstreeRepo *repo = ostree_repo_file_get_repo ((OstreeRepoFile*)b); + OstreeRepo *repo = ostree_repo_file_get_repo ((OstreeRepoFile *)b); if (repo->disable_xattrs || repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY) flags |= OSTREE_DIFF_FLAGS_IGNORE_XATTRS; } @@ -289,28 +250,26 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, } child_a_info = g_file_query_info (a, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!child_a_info) goto out; child_b_info = g_file_query_info (b, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!child_b_info) goto out; /* Fast path test for unmodified directories */ if (g_file_info_get_file_type (child_a_info) == G_FILE_TYPE_DIRECTORY && g_file_info_get_file_type (child_b_info) == G_FILE_TYPE_DIRECTORY - && OSTREE_IS_REPO_FILE (a) - && OSTREE_IS_REPO_FILE (b)) + && OSTREE_IS_REPO_FILE (a) && OSTREE_IS_REPO_FILE (b)) { - OstreeRepoFile *a_repof = (OstreeRepoFile*) a; - OstreeRepoFile *b_repof = (OstreeRepoFile*) b; + OstreeRepoFile *a_repof = (OstreeRepoFile *)a; + OstreeRepoFile *b_repof = (OstreeRepoFile *)b; if (strcmp (ostree_repo_file_tree_get_contents_checksum (a_repof), - ostree_repo_file_tree_get_contents_checksum (b_repof)) == 0) + ostree_repo_file_tree_get_contents_checksum (b_repof)) + == 0) { ret = TRUE; goto out; @@ -321,8 +280,7 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, g_clear_object (&child_b_info); dir_enum = g_file_enumerate_children (a, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_enum) goto out; @@ -342,10 +300,9 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, child_b = g_file_get_child (b, name); g_clear_object (&child_b_info); - child_b_info = g_file_query_info (child_b, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, - &temp_error); + child_b_info + = g_file_query_info (child_b, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, &temp_error); if (!child_b_info) { if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) @@ -369,8 +326,8 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, child_b_type = g_file_info_get_file_type (child_b_info); if (child_a_type != child_b_type) { - OstreeDiffItem *diff_item = diff_item_new (child_a, child_a_info, - child_b, child_b_info, NULL, NULL); + OstreeDiffItem *diff_item + = diff_item_new (child_a, child_a_info, child_b, child_b_info, NULL, NULL); g_ptr_array_add (modified, diff_item); } @@ -387,9 +344,8 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, if (child_a_type == G_FILE_TYPE_DIRECTORY) { - if (!ostree_diff_dirs_with_options (flags, child_a, child_b, modified, - removed, added, options, - cancellable, error)) + if (!ostree_diff_dirs_with_options (flags, child_a, child_b, modified, removed, + added, options, cancellable, error)) goto out; } } @@ -405,8 +361,7 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, g_clear_object (&dir_enum); dir_enum = g_file_enumerate_children (b, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_enum) goto out; @@ -424,10 +379,9 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, child_b = g_file_get_child (b, name); g_clear_object (&child_a_info); - child_a_info = g_file_query_info (child_a, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, - &temp_error); + child_a_info + = g_file_query_info (child_a, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, &temp_error); if (!child_a_info) { if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) @@ -455,14 +409,12 @@ ostree_diff_dirs_with_options (OstreeDiffFlags flags, } ret = TRUE; - out: +out: return ret; } static void -print_diff_item (char prefix, - GFile *base, - GFile *file) +print_diff_item (char prefix, GFile *base, GFile *file) { if (g_file_is_native (file)) { @@ -486,11 +438,7 @@ print_diff_item (char prefix, * Print the contents of a diff to stdout. */ void -ostree_diff_print (GFile *a, - GFile *b, - GPtrArray *modified, - GPtrArray *removed, - GPtrArray *added) +ostree_diff_print (GFile *a, GFile *b, GPtrArray *modified, GPtrArray *removed, GPtrArray *added) { guint i; diff --git a/src/libostree/ostree-diff.h b/src/libostree/ostree-diff.h index be50c63..ba77ae6 100644 --- a/src/libostree/ostree-diff.h +++ b/src/libostree/ostree-diff.h @@ -29,7 +29,8 @@ G_BEGIN_DECLS /** * OstreeDiffFlags: */ -typedef enum { +typedef enum +{ OSTREE_DIFF_FLAGS_NONE = 0, OSTREE_DIFF_FLAGS_IGNORE_XATTRS = (1 << 0) } OstreeDiffFlags; @@ -40,7 +41,7 @@ typedef enum { typedef struct _OstreeDiffItem OstreeDiffItem; struct _OstreeDiffItem { - gint refcount; /* atomic */ + gint refcount; /* atomic */ GFile *src; GFile *target; @@ -61,14 +62,9 @@ _OSTREE_PUBLIC GType ostree_diff_item_get_type (void); _OSTREE_PUBLIC -gboolean ostree_diff_dirs (OstreeDiffFlags flags, - GFile *a, - GFile *b, - GPtrArray *modified, - GPtrArray *removed, - GPtrArray *added, - GCancellable *cancellable, - GError **error); +gboolean ostree_diff_dirs (OstreeDiffFlags flags, GFile *a, GFile *b, GPtrArray *modified, + GPtrArray *removed, GPtrArray *added, GCancellable *cancellable, + GError **error); /** * OstreeDiffDirsOptions: @@ -77,7 +73,8 @@ gboolean ostree_diff_dirs (OstreeDiffFlags flags, * that owner_uid/gid is set to -1 when not used. This is used by * ostree_diff_dirs_with_options(). */ -typedef struct { +typedef struct +{ gint owner_uid; gint owner_gid; @@ -94,24 +91,19 @@ typedef struct { * * Use this to initialize an `OstreeDiffDirsOptions` structure. */ -#define OSTREE_DIFF_DIRS_OPTIONS_INIT { .owner_uid = -1, .owner_gid = -1, } +#define OSTREE_DIFF_DIRS_OPTIONS_INIT \ + { \ + .owner_uid = -1, .owner_gid = -1, \ + } _OSTREE_PUBLIC -gboolean ostree_diff_dirs_with_options (OstreeDiffFlags flags, - GFile *a, - GFile *b, - GPtrArray *modified, - GPtrArray *removed, - GPtrArray *added, - OstreeDiffDirsOptions *options, - GCancellable *cancellable, - GError **error); +gboolean ostree_diff_dirs_with_options (OstreeDiffFlags flags, GFile *a, GFile *b, + GPtrArray *modified, GPtrArray *removed, GPtrArray *added, + OstreeDiffDirsOptions *options, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -void ostree_diff_print (GFile *a, - GFile *b, - GPtrArray *modified, - GPtrArray *removed, - GPtrArray *added); +void ostree_diff_print (GFile *a, GFile *b, GPtrArray *modified, GPtrArray *removed, + GPtrArray *added); G_END_DECLS diff --git a/src/libostree/ostree-dummy-enumtypes.c b/src/libostree/ostree-dummy-enumtypes.c index b03d61c..1967b48 100644 --- a/src/libostree/ostree-dummy-enumtypes.c +++ b/src/libostree/ostree-dummy-enumtypes.c @@ -21,7 +21,7 @@ #include "ostree-dummy-enumtypes.h" -/* Exported for backwards compat - see +/* Exported for backwards compat - see * https://bugzilla.gnome.org/show_bug.cgi?id=764131 */ GType diff --git a/src/libostree/ostree-dummy-enumtypes.h b/src/libostree/ostree-dummy-enumtypes.h index 6284644..a27ea6b 100644 --- a/src/libostree/ostree-dummy-enumtypes.h +++ b/src/libostree/ostree-dummy-enumtypes.h @@ -24,6 +24,5 @@ #include #ifndef __GI_SCANNER__ -_OSTREE_PUBLIC GType -ostree_fetcher_config_flags_get_type (void); +_OSTREE_PUBLIC GType ostree_fetcher_config_flags_get_type (void); #endif diff --git a/src/libostree/ostree-fetcher-curl.c b/src/libostree/ostree-fetcher-curl.c index 75038ec..e9b9672 100644 --- a/src/libostree/ostree-fetcher-curl.c +++ b/src/libostree/ostree-fetcher-curl.c @@ -20,23 +20,25 @@ #include "config.h" +#include #include #include #include -#include +#include /* These macros came from 7.43.0, but we want to check * for versions a bit earlier than that (to work on CentOS 7), * so define them here if we're using an older version. */ #ifndef CURL_VERSION_BITS -#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_VERSION_BITS(x, y, z) ((x) << 16 | (y) << 8 | z) #endif #ifndef CURL_AT_LEAST_VERSION -#define CURL_AT_LEAST_VERSION(x,y,z) (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) +#define CURL_AT_LEAST_VERSION(x, y, z) (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS (x, y, z)) #endif -/* Cargo culted from https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c */ +/* Cargo culted from https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c + */ #ifndef CURLPIPE_MULTIPLEX /* This little trick will just make sure that we don't enable pipelining for libcurls old enough to not have this symbol. It is _not_ defined to zero in @@ -45,9 +47,9 @@ #endif #include "ostree-date-utils-private.h" -#include "ostree-fetcher.h" -#include "ostree-fetcher-util.h" #include "ostree-enumtypes.h" +#include "ostree-fetcher-util.h" +#include "ostree-fetcher.h" #include "ostree-repo-private.h" #include "otutil.h" @@ -75,20 +77,26 @@ struct OstreeFetcher char *proxy; struct curl_slist *extra_headers; int tmpdir_dfd; + bool force_anonymous; char *custom_user_agent; + guint32 opt_low_speed_limit; + guint32 opt_low_speed_time; + gboolean opt_retry_all; + guint32 opt_max_outstanding_fetcher_requests; GMainContext *mainctx; CURLM *multi; GSource *timer_event; int curl_running; GHashTable *outstanding_requests; /* Set */ - GHashTable *sockets; /* Set */ + GHashTable *sockets; /* Set */ guint64 bytes_transferred; }; /* Information associated with a request */ -struct FetcherRequest { +struct FetcherRequest +{ guint refcount; GPtrArray *mirrorlist; guint idx; @@ -98,15 +106,16 @@ struct FetcherRequest { guint64 max_size; OstreeFetcherRequestFlags flags; struct curl_slist *req_headers; - char *if_none_match; /* request ETag */ - guint64 if_modified_since; /* seconds since the epoch */ + char *if_none_match; /* request ETag */ + guint64 if_modified_since; /* seconds since the epoch */ gboolean is_membuf; GError *caught_write_error; GLnxTmpfile tmpf; GString *output_buf; - gboolean out_not_modified; /* TRUE if the server gave a HTTP 304 Not Modified response, which we don’t propagate as an error */ - char *out_etag; /* response ETag */ - guint64 out_last_modified; /* response Last-Modified, seconds since the epoch */ + gboolean out_not_modified; /* TRUE if the server gave a HTTP 304 Not Modified response, which we + don’t propagate as an error */ + char *out_etag; /* response ETag */ + guint64 out_last_modified; /* response Last-Modified, seconds since the epoch */ CURL *easy; char error[CURL_ERROR_SIZE]; @@ -115,7 +124,8 @@ struct FetcherRequest { }; /* Information associated with a specific socket */ -struct SockInfo { +struct SockInfo +{ guint refcount; curl_socket_t sockfd; int action; @@ -124,7 +134,8 @@ struct SockInfo { OstreeFetcher *fetcher; }; -enum { +enum +{ PROP_0, PROP_CONFIG_FLAGS }; @@ -132,40 +143,35 @@ enum { G_DEFINE_TYPE (OstreeFetcher, _ostree_fetcher, G_TYPE_OBJECT) static void -_ostree_fetcher_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +_ostree_fetcher_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeFetcher *self = OSTREE_FETCHER (object); switch (prop_id) { - case PROP_CONFIG_FLAGS: - self->config_flags = g_value_get_flags (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + case PROP_CONFIG_FLAGS: + self->config_flags = g_value_get_flags (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } static void -_ostree_fetcher_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +_ostree_fetcher_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { OstreeFetcher *self = OSTREE_FETCHER (object); switch (prop_id) { - case PROP_CONFIG_FLAGS: - g_value_set_flags (value, self->config_flags); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + case PROP_CONFIG_FLAGS: + g_value_set_flags (value, self->config_flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } @@ -211,23 +217,19 @@ _ostree_fetcher_class_init (OstreeFetcherClass *klass) gobject_class->finalize = _ostree_fetcher_finalize; gobject_class->constructed = _ostree_fetcher_constructed; - g_object_class_install_property (gobject_class, - PROP_CONFIG_FLAGS, - g_param_spec_flags ("config-flags", - "", - "", - OSTREE_TYPE_FETCHER_CONFIG_FLAGS, - OSTREE_FETCHER_FLAGS_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property ( + gobject_class, PROP_CONFIG_FLAGS, + g_param_spec_flags ("config-flags", "", "", OSTREE_TYPE_FETCHER_CONFIG_FLAGS, + OSTREE_FETCHER_FLAGS_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } static void _ostree_fetcher_init (OstreeFetcher *self) { - self->multi = curl_multi_init(); - self->outstanding_requests = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)g_object_unref, NULL); + self->multi = curl_multi_init (); + self->outstanding_requests + = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)g_object_unref, NULL); self->sockets = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)sock_unref, NULL); curl_multi_setopt (self->multi, CURLMOPT_SOCKETFUNCTION, sock_cb); curl_multi_setopt (self->multi, CURLMOPT_SOCKETDATA, self); @@ -245,11 +247,8 @@ _ostree_fetcher_init (OstreeFetcher *self) #endif } - OstreeFetcher * -_ostree_fetcher_new (int tmpdir_dfd, - const char *remote_name, - OstreeFetcherConfigFlags flags) +_ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfigFlags flags) { OstreeFetcher *fetcher = g_object_new (OSTREE_TYPE_FETCHER, "config-flags", flags, NULL); fetcher->remote_name = g_strdup (remote_name); @@ -257,6 +256,12 @@ _ostree_fetcher_new (int tmpdir_dfd, return fetcher; } +void +_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self) +{ + self->force_anonymous = true; +} + static void destroy_and_unref_source (GSource *source) { @@ -269,7 +274,8 @@ request_get_uri (FetcherRequest *req, GUri *baseuri) { if (!req->filename) return g_uri_to_string_partial (baseuri, G_URI_HIDE_PASSWORD); - { g_autofree char *uristr = g_uri_to_string_partial (baseuri, G_URI_HIDE_PASSWORD); + { + g_autofree char *uristr = g_uri_to_string_partial (baseuri, G_URI_HIDE_PASSWORD); return g_build_filename (uristr, req->filename, NULL); } } @@ -277,13 +283,12 @@ request_get_uri (FetcherRequest *req, GUri *baseuri) static gboolean ensure_tmpfile (FetcherRequest *req, GError **error) { - if (!req->tmpf.initialized) - { - if (!_ostree_fetcher_tmpf_from_flags (req->flags, req->fetcher->tmpdir_dfd, - &req->tmpf, error)) - return FALSE; - } - return TRUE; + if (req->tmpf.initialized) + return TRUE; + if (req->fetcher->force_anonymous) + return glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &req->tmpf, error); + else + return _ostree_fetcher_tmpf (req->fetcher->tmpdir_dfd, &req->tmpf, error); } /* Check for completed transfers, and remove their easy handles */ @@ -324,24 +329,30 @@ check_multi_info (OstreeFetcher *fetcher) if (is_file && curlres == CURLE_FILE_COULDNT_READ_FILE) { /* Handle file not found */ - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "%s", curl_easy_strerror (curlres)); + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "%s", + curl_easy_strerror (curlres)); } else { - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, + /* When it is not a file, we want to retry the request. + * We accomplish that by using G_IO_ERROR_TIMED_OUT. + */ + gboolean opt_retry_all = req->fetcher->opt_retry_all; + int g_io_error_code + = (is_file || !opt_retry_all) ? G_IO_ERROR_FAILED : G_IO_ERROR_TIMED_OUT; + g_task_return_new_error (task, G_IO_ERROR, g_io_error_code, "While fetching %s: [%u] %s", eff_url, curlres, curl_easy_strerror (curlres)); - _ostree_fetcher_journal_failure (req->fetcher->remote_name, - eff_url, curl_easy_strerror (curlres)); + _ostree_fetcher_journal_failure (req->fetcher->remote_name, eff_url, + curl_easy_strerror (curlres)); } } else { curl_easy_getinfo (easy, CURLINFO_RESPONSE_CODE, &response); - if (!is_file && response == 304 && - (req->if_none_match != NULL || req->if_modified_since > 0)) + if (!is_file && response == 304 + && (req->if_none_match != NULL || req->if_modified_since > 0)) { /* Version on the server is unchanged from the version we have * cached locally; report this as an out-argument, a zero-length @@ -355,15 +366,14 @@ check_multi_info (OstreeFetcher *fetcher) if (req->idx + 1 == req->mirrorlist->len) { - g_autofree char *response_msg = g_strdup_printf ("Server returned HTTP %lu", response); - g_task_return_new_error (task, G_IO_ERROR, giocode, - "%s", response_msg); - if (req->fetcher->remote_name && - !((req->flags & OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT) > 0 && - giocode == G_IO_ERROR_NOT_FOUND)) - _ostree_fetcher_journal_failure (req->fetcher->remote_name, - eff_url, response_msg); - + g_autofree char *response_msg + = g_strdup_printf ("Server returned HTTP %lu", response); + g_task_return_new_error (task, G_IO_ERROR, giocode, "%s", response_msg); + if (req->fetcher->remote_name + && !((req->flags & OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT) > 0 + && giocode == G_IO_ERROR_NOT_FOUND)) + _ostree_fetcher_journal_failure (req->fetcher->remote_name, eff_url, + response_msg); } else { @@ -381,7 +391,7 @@ check_multi_info (OstreeFetcher *fetcher) } else { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; if (!ensure_tmpfile (req, error)) @@ -454,9 +464,8 @@ event_cb (int fd, GIOCondition condition, gpointer data) { OstreeFetcher *fetcher = data; - int action = - (condition & G_IO_IN ? CURL_CSELECT_IN : 0) | - (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0); + int action + = (condition & G_IO_IN ? CURL_CSELECT_IN : 0) | (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0); (void)curl_multi_socket_action (fetcher->multi, fd, action, &fetcher->curl_running); check_multi_info (fetcher); @@ -484,10 +493,9 @@ sock_unref (SockInfo *f) /* Assign information to a SockInfo structure */ static void -setsock (SockInfo*f, curl_socket_t s, int act, OstreeFetcher *fetcher) +setsock (SockInfo *f, curl_socket_t s, int act, OstreeFetcher *fetcher) { - GIOCondition kind = - (act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0); + GIOCondition kind = (act & CURL_POLL_IN ? G_IO_IN : 0) | (act & CURL_POLL_OUT ? G_IO_OUT : 0); f->sockfd = s; f->action = act; @@ -496,7 +504,7 @@ setsock (SockInfo*f, curl_socket_t s, int act, OstreeFetcher *fetcher) * flags involves less allocation. */ f->ch = g_unix_fd_source_new (f->sockfd, kind); - g_source_set_callback (f->ch, (GSourceFunc) event_cb, fetcher, NULL); + g_source_set_callback (f->ch, (GSourceFunc)event_cb, fetcher, NULL); g_source_attach (f->ch, fetcher->mainctx); } @@ -518,7 +526,7 @@ static int sock_cb (CURL *easy, curl_socket_t s, int what, void *cbp, void *sockp) { OstreeFetcher *fetcher = cbp; - SockInfo *fdp = (SockInfo*) sockp; + SockInfo *fdp = (SockInfo *)sockp; if (what == CURL_POLL_REMOVE) { @@ -554,14 +562,14 @@ write_cb (void *ptr, size_t size, size_t nmemb, void *data) if (req->max_size > 0) { - if (realsize > req->max_size || - (realsize + req->current_size) > req->max_size) + if (realsize > req->max_size || (realsize + req->current_size) > req->max_size) { const char *eff_url; curl_easy_getinfo (req->easy, CURLINFO_EFFECTIVE_URL, &eff_url); - req->caught_write_error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, - "URI %s exceeded maximum size of %" G_GUINT64_FORMAT " bytes", - eff_url, req->max_size); + req->caught_write_error + = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, + "URI %s exceeded maximum size of %" G_GUINT64_FORMAT " bytes", eff_url, + req->max_size); return -1; } } @@ -603,17 +611,17 @@ response_header_cb (const char *buffer, size_t size, size_t n_items, void *user_ const char *etag_header = "ETag: "; const char *last_modified_header = "Last-Modified: "; - if (real_size > strlen (etag_header) && - strncasecmp (buffer, etag_header, strlen (etag_header)) == 0) + if (real_size > strlen (etag_header) + && strncasecmp (buffer, etag_header, strlen (etag_header)) == 0) { g_clear_pointer (&req->out_etag, g_free); req->out_etag = g_strstrip (g_strdup (buffer + strlen (etag_header))); } - else if (real_size > strlen (last_modified_header) && - strncasecmp (buffer, last_modified_header, strlen (last_modified_header)) == 0) + else if (real_size > strlen (last_modified_header) + && strncasecmp (buffer, last_modified_header, strlen (last_modified_header)) == 0) { g_autofree char *lm_buf = g_strstrip (g_strdup (buffer + strlen (last_modified_header))); - g_autoptr(GDateTime) dt = _ostree_parse_rfc2616_date_time (lm_buf, strlen (lm_buf)); + g_autoptr (GDateTime) dt = _ostree_parse_rfc2616_date_time (lm_buf, strlen (lm_buf)); req->out_last_modified = (dt != NULL) ? g_date_time_to_unix (dt) : 0; } @@ -660,28 +668,48 @@ _ostree_fetcher_get_dfd (OstreeFetcher *fetcher) } void -_ostree_fetcher_set_proxy (OstreeFetcher *self, - const char *http_proxy) +_ostree_fetcher_set_proxy (OstreeFetcher *self, const char *http_proxy) { g_free (self->proxy); self->proxy = g_strdup (http_proxy); } void -_ostree_fetcher_set_cookie_jar (OstreeFetcher *self, - const char *jar_path) +_ostree_fetcher_set_low_speed_time (OstreeFetcher *self, guint32 opt_low_speed_time) +{ + self->opt_low_speed_time = opt_low_speed_time; +} + +void +_ostree_fetcher_set_low_speed_limit (OstreeFetcher *self, guint32 opt_low_speed_limit) +{ + self->opt_low_speed_limit = opt_low_speed_limit; +} + +void +_ostree_fetcher_set_retry_all (OstreeFetcher *self, gboolean opt_retry_all) +{ + self->opt_retry_all = opt_retry_all; +} + +void +_ostree_fetcher_set_max_outstanding_fetcher_requests (OstreeFetcher *self, + guint32 opt_max_outstanding_fetcher_requests) +{ + self->opt_max_outstanding_fetcher_requests = opt_max_outstanding_fetcher_requests; +} + +void +_ostree_fetcher_set_cookie_jar (OstreeFetcher *self, const char *jar_path) { g_free (self->cookie_jar_path); self->cookie_jar_path = g_strdup (jar_path); } void -_ostree_fetcher_set_client_cert (OstreeFetcher *self, - const char *cert_path, - const char *key_path) +_ostree_fetcher_set_client_cert (OstreeFetcher *self, const char *cert_path, const char *key_path) { - g_assert ((cert_path == NULL && key_path == NULL) - || (cert_path != NULL && key_path != NULL)); + g_assert ((cert_path == NULL && key_path == NULL) || (cert_path != NULL && key_path != NULL)); g_free (self->tls_client_cert_path); self->tls_client_cert_path = g_strdup (cert_path); g_free (self->tls_client_key_path); @@ -689,16 +717,14 @@ _ostree_fetcher_set_client_cert (OstreeFetcher *self, } void -_ostree_fetcher_set_tls_database (OstreeFetcher *self, - const char *dbpath) +_ostree_fetcher_set_tls_database (OstreeFetcher *self, const char *dbpath) { g_free (self->tls_ca_db_path); self->tls_ca_db_path = g_strdup (dbpath); } void -_ostree_fetcher_set_extra_headers (OstreeFetcher *self, - GVariant *extra_headers) +_ostree_fetcher_set_extra_headers (OstreeFetcher *self, GVariant *extra_headers) { GVariantIter viter; const char *key; @@ -715,21 +741,19 @@ _ostree_fetcher_set_extra_headers (OstreeFetcher *self, } void -_ostree_fetcher_set_extra_user_agent (OstreeFetcher *self, - const char *extra_user_agent) +_ostree_fetcher_set_extra_user_agent (OstreeFetcher *self, const char *extra_user_agent) { g_clear_pointer (&self->custom_user_agent, g_free); if (extra_user_agent) { - self->custom_user_agent = - g_strdup_printf ("%s %s", OSTREE_FETCHER_USERAGENT_STRING, extra_user_agent); + self->custom_user_agent + = g_strdup_printf ("%s %s", OSTREE_FETCHER_USERAGENT_STRING, extra_user_agent); } } /* Re-bind all of the outstanding curl items to our new main context */ static void -adopt_steal_mainctx (OstreeFetcher *self, - GMainContext *mainctx) +adopt_steal_mainctx (OstreeFetcher *self, GMainContext *mainctx) { g_assert (self->mainctx == NULL); self->mainctx = mainctx; /* Transfer */ @@ -744,13 +768,12 @@ adopt_steal_mainctx (OstreeFetcher *self, update_timeout_cb (self->multi, timeout_micros / 1000, self); } - GLNX_HASH_TABLE_FOREACH (self->sockets, SockInfo*, fdp) + GLNX_HASH_TABLE_FOREACH (self->sockets, SockInfo *, fdp) setsock (fdp, fdp->sockfd, fdp->action, self); } static void -initiate_next_curl_request (FetcherRequest *req, - GTask *task) +initiate_next_curl_request (FetcherRequest *req, GTask *task) { CURLcode rc; OstreeFetcher *self = req->fetcher; @@ -763,13 +786,14 @@ initiate_next_curl_request (FetcherRequest *req, g_assert_cmpint (req->idx, <, req->mirrorlist->len); GUri *baseuri = req->mirrorlist->pdata[req->idx]; - { g_autofree char *uri = request_get_uri (req, baseuri); + { + g_autofree char *uri = request_get_uri (req, baseuri); rc = curl_easy_setopt (req->easy, CURLOPT_URL, uri); g_assert_cmpint (rc, ==, CURLM_OK); } rc = curl_easy_setopt (req->easy, CURLOPT_USERAGENT, - self->custom_user_agent ?: OSTREE_FETCHER_USERAGENT_STRING); + self->custom_user_agent ?: OSTREE_FETCHER_USERAGENT_STRING); g_assert_cmpint (rc, ==, CURLM_OK); /* Set caching request headers */ @@ -781,8 +805,9 @@ initiate_next_curl_request (FetcherRequest *req, if (req->if_modified_since > 0) { - g_autoptr(GDateTime) date_time = g_date_time_new_from_unix_utc (req->if_modified_since); - g_autofree char *mod_date = g_date_time_format (date_time, "If-Modified-Since: %a, %d %b %Y %H:%M:%S %Z"); + g_autoptr (GDateTime) date_time = g_date_time_new_from_unix_utc (req->if_modified_since); + g_autofree char *mod_date + = g_date_time_format (date_time, "If-Modified-Since: %a, %d %b %Y %H:%M:%S %Z"); req->req_headers = curl_slist_append (req->req_headers, mod_date); } @@ -818,7 +843,6 @@ initiate_next_curl_request (FetcherRequest *req, g_assert_cmpint (rc, ==, CURLM_OK); } - if ((self->config_flags & OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE) > 0) { rc = curl_easy_setopt (req->easy, CURLOPT_SSL_VERIFYPEER, 0L); @@ -873,7 +897,8 @@ initiate_next_curl_request (FetcherRequest *req, g_assert_cmpint (rc, ==, CURLM_OK); /* We should only speak HTTP; TODO: only enable file if specified */ - rc = curl_easy_setopt (req->easy, CURLOPT_PROTOCOLS, (long)(CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FILE)); + rc = curl_easy_setopt (req->easy, CURLOPT_PROTOCOLS, + (long)(CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FILE)); g_assert_cmpint (rc, ==, CURLM_OK); /* Picked the current version in F25 as of 20170127, since * there are numerous HTTP/2 fixes since the original version in @@ -882,10 +907,13 @@ initiate_next_curl_request (FetcherRequest *req, if (!(self->config_flags & OSTREE_FETCHER_FLAGS_DISABLE_HTTP2)) { #if CURL_AT_LEAST_VERSION(7, 51, 0) - rc = curl_easy_setopt (req->easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); - g_assert_cmpint (rc, ==, CURLM_OK); + if ((curl_version_info (CURLVERSION_NOW))->features & CURL_VERSION_HTTP2) + { + rc = curl_easy_setopt (req->easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); + g_assert_cmpint (rc, ==, CURLM_OK); + } #endif - /* https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c */ + /* https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c */ #if (CURLPIPE_MULTIPLEX > 0) /* wait for pipe connection to confirm */ rc = curl_easy_setopt (req->easy, CURLOPT_PIPEWAIT, 1L); @@ -893,6 +921,12 @@ initiate_next_curl_request (FetcherRequest *req, #endif } + if (self->config_flags & OSTREE_FETCHER_FLAGS_DISABLE_HTTP2) + { + rc = curl_easy_setopt (req->easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + g_assert_cmpint (rc, ==, CURLM_OK); + } + rc = curl_easy_setopt (req->easy, CURLOPT_WRITEFUNCTION, write_cb); g_assert_cmpint (rc, ==, CURLM_OK); rc = curl_easy_setopt (req->easy, CURLOPT_HEADERFUNCTION, response_header_cb); @@ -913,14 +947,10 @@ initiate_next_curl_request (FetcherRequest *req, g_assert_cmpint (rc, ==, CURLM_OK); rc = curl_easy_setopt (req->easy, CURLOPT_CONNECTTIMEOUT, 30L); g_assert_cmpint (rc, ==, CURLM_OK); - /* We used to set CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME - * here, but see https://github.com/ostreedev/ostree/issues/878#issuecomment-347228854 - * basically those options don't play well with HTTP2 at the moment - * where we can have lots of outstanding requests. Further, - * we could implement that functionality at a higher level - * more consistently too. - */ - + rc = curl_easy_setopt (req->easy, CURLOPT_LOW_SPEED_LIMIT, req->fetcher->opt_low_speed_limit); + g_assert_cmpint (rc, ==, CURLM_OK); + rc = curl_easy_setopt (req->easy, CURLOPT_LOW_SPEED_TIME, req->fetcher->opt_low_speed_time); + g_assert_cmpint (rc, ==, CURLM_OK); /* closure bindings -> task */ rc = curl_easy_setopt (req->easy, CURLOPT_PRIVATE, task); g_assert_cmpint (rc, ==, CURLM_OK); @@ -936,29 +966,21 @@ initiate_next_curl_request (FetcherRequest *req, } static void -_ostree_fetcher_request_async (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - gboolean is_membuf, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_fetcher_request_async (OstreeFetcher *self, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, + guint64 if_modified_since, gboolean is_membuf, guint64 max_size, + int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = NULL; + g_autoptr (GTask) task = NULL; FetcherRequest *req; - g_autoptr(GMainContext) mainctx = g_main_context_ref_thread_default (); + g_autoptr (GMainContext) mainctx = g_main_context_ref_thread_default (); /* We don't support multiple concurrent main contexts; take * a ref to the first one, and require that later invocations * share it. */ - if (g_hash_table_size (self->outstanding_requests) == 0 - && mainctx != self->mainctx) + if (g_hash_table_size (self->outstanding_requests) == 0 && mainctx != self->mainctx) { adopt_steal_mainctx (self, g_steal_pointer (&mainctx)); } @@ -969,7 +991,7 @@ _ostree_fetcher_request_async (OstreeFetcher *self, req = g_new0 (FetcherRequest, 1); req->refcount = 1; - req->error[0]='\0'; + req->error[0] = '\0'; req->fetcher = self; req->mirrorlist = g_ptr_array_ref (mirrorlist); req->filename = g_strdup (filename); @@ -988,7 +1010,7 @@ _ostree_fetcher_request_async (OstreeFetcher *self, /* We'll use the GTask priority for our own priority queue. */ g_task_set_priority (task, priority); g_task_set_source_tag (task, _ostree_fetcher_request_async); - g_task_set_task_data (task, req, (GDestroyNotify) request_unref); + g_task_set_task_data (task, req, (GDestroyNotify)request_unref); initiate_next_curl_request (req, task); @@ -996,37 +1018,27 @@ _ostree_fetcher_request_async (OstreeFetcher *self, } void -_ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, GPtrArray *mirrorlist, + const char *filename, OstreeFetcherRequestFlags flags, + const char *if_none_match, guint64 if_modified_since, + guint64 max_size, int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - _ostree_fetcher_request_async (self, mirrorlist, filename, flags, - if_none_match, if_modified_since, FALSE, - max_size, priority, cancellable, + _ostree_fetcher_request_async (self, mirrorlist, filename, flags, if_none_match, + if_modified_since, FALSE, max_size, priority, cancellable, callback, user_data); } gboolean -_ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, - GAsyncResult *result, - GLnxTmpfile *out_tmpf, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - GError **error) +_ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, GAsyncResult *result, + GLnxTmpfile *out_tmpf, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), FALSE); g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); - GTask *task = (GTask*)result; + GTask *task = (GTask *)result; FetcherRequest *req = g_task_get_task_data (task); if (!g_task_propagate_boolean (task, error)) @@ -1047,32 +1059,22 @@ _ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, } void -_ostree_fetcher_request_to_membuf (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_fetcher_request_to_membuf (OstreeFetcher *self, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, + guint64 if_modified_since, guint64 max_size, int priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { - _ostree_fetcher_request_async (self, mirrorlist, filename, flags, - if_none_match, if_modified_since, TRUE, - max_size, priority, cancellable, - callback, user_data); + _ostree_fetcher_request_async (self, mirrorlist, filename, flags, if_none_match, + if_modified_since, TRUE, max_size, priority, cancellable, callback, + user_data); } gboolean -_ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, - GAsyncResult *result, - GBytes **out_buf, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - GError **error) +_ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, GAsyncResult *result, + GBytes **out_buf, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + GError **error) { GTask *task; FetcherRequest *req; @@ -1081,7 +1083,7 @@ _ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, g_return_val_if_fail (g_task_is_valid (result, self), FALSE); g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); - task = (GTask*)result; + task = (GTask *)result; req = g_task_get_task_data (task); ret = g_task_propagate_pointer (task, error); @@ -1103,7 +1105,7 @@ _ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, } guint64 -_ostree_fetcher_bytes_transferred (OstreeFetcher *self) +_ostree_fetcher_bytes_transferred (OstreeFetcher *self) { return self->bytes_transferred; } diff --git a/src/libostree/ostree-fetcher-soup.c b/src/libostree/ostree-fetcher-soup.c index ec1d8e0..e75e72b 100644 --- a/src/libostree/ostree-fetcher-soup.c +++ b/src/libostree/ostree-fetcher-soup.c @@ -22,41 +22,45 @@ #include "config.h" -#include #include +#include #include +#include #define LIBSOUP_USE_UNSTABLE_REQUEST_API -#include -#include #include +#include +#include #include "libglnx.h" -#include "ostree-fetcher.h" #include "ostree-fetcher-util.h" +#include "ostree-fetcher.h" #ifdef HAVE_LIBSOUP_CLIENT_CERTS #include "ostree-tls-cert-interaction-private.h" #endif #include "ostree-enumtypes.h" -#include "ostree.h" #include "ostree-repo-private.h" +#include "ostree.h" #include "otutil.h" -typedef enum { +typedef enum +{ OSTREE_FETCHER_STATE_PENDING, OSTREE_FETCHER_STATE_DOWNLOADING, OSTREE_FETCHER_STATE_COMPLETE } OstreeFetcherState; -typedef struct { - int ref_count; /* atomic */ +typedef struct +{ + int ref_count; /* atomic */ - SoupSession *session; /* not referenced */ + SoupSession *session; /* not referenced */ GMainContext *main_context; volatile gint running; GError *initialization_error; /* Any failure to load the db */ char *remote_name; int base_tmpdir_dfd; + bool force_anonymous; GVariant *extra_headers; gboolean transfer_gzip; @@ -65,22 +69,25 @@ typedef struct { GHashTable *outstanding; /* Shared across threads; be sure to lock. */ - GHashTable *output_stream_set; /* set */ + GHashTable *output_stream_set; /* set */ GMutex output_stream_set_lock; /* Also protected by output_stream_set_lock. */ guint64 total_downloaded; + guint32 opt_max_outstanding_fetcher_requests; + GError *oob_error; } ThreadClosure; -typedef struct { - int ref_count; /* atomic */ +typedef struct +{ + int ref_count; /* atomic */ ThreadClosure *thread_closure; GPtrArray *mirrorlist; /* list of base URIs */ - char *filename; /* relative name to fetch or NULL */ + char *filename; /* relative name to fetch or NULL */ guint mirrorlist_idx; OstreeFetcherState state; @@ -89,14 +96,15 @@ typedef struct { gboolean is_membuf; OstreeFetcherRequestFlags flags; - char *if_none_match; /* request ETag */ - guint64 if_modified_since; /* seconds since the epoch */ + char *if_none_match; /* request ETag */ + guint64 if_modified_since; /* seconds since the epoch */ GInputStream *request_body; GLnxTmpfile tmpf; GOutputStream *out_stream; - gboolean out_not_modified; /* TRUE if the server gave a HTTP 304 Not Modified response, which we don’t propagate as an error */ - char *out_etag; /* response ETag */ - guint64 out_last_modified; /* response Last-Modified, seconds since the epoch */ + gboolean out_not_modified; /* TRUE if the server gave a HTTP 304 Not Modified response, which we + don’t propagate as an error */ + char *out_etag; /* response ETag */ + guint64 out_last_modified; /* response Last-Modified, seconds since the epoch */ guint64 max_size; guint64 current_size; @@ -104,11 +112,11 @@ typedef struct { } OstreeFetcherPendingURI; /* Used by session_thread_idle_add() */ -typedef void (*SessionThreadFunc) (ThreadClosure *thread_closure, - gpointer data); +typedef void (*SessionThreadFunc) (ThreadClosure *thread_closure, gpointer data); /* Used by session_thread_idle_add() */ -typedef struct { +typedef struct +{ ThreadClosure *thread_closure; SessionThreadFunc function; gpointer data; @@ -125,7 +133,8 @@ struct OstreeFetcher ThreadClosure *thread_closure; }; -enum { +enum +{ PROP_0, PROP_CONFIG_FLAGS }; @@ -212,16 +221,13 @@ session_thread_idle_dispatch (gpointer data) { IdleClosure *idle_closure = data; - idle_closure->function (idle_closure->thread_closure, - idle_closure->data); + idle_closure->function (idle_closure->thread_closure, idle_closure->data); return G_SOURCE_REMOVE; } static void -session_thread_idle_add (ThreadClosure *thread_closure, - SessionThreadFunc function, - gpointer data, +session_thread_idle_add (ThreadClosure *thread_closure, SessionThreadFunc function, gpointer data, GDestroyNotify notify) { IdleClosure *idle_closure; @@ -235,27 +241,22 @@ session_thread_idle_add (ThreadClosure *thread_closure, idle_closure->data = data; idle_closure->notify = notify; - g_main_context_invoke_full (thread_closure->main_context, - G_PRIORITY_DEFAULT, - session_thread_idle_dispatch, - idle_closure, /* takes ownership */ - (GDestroyNotify) idle_closure_free); + g_main_context_invoke_full (thread_closure->main_context, G_PRIORITY_DEFAULT, + session_thread_idle_dispatch, idle_closure, /* takes ownership */ + (GDestroyNotify)idle_closure_free); } static void -session_thread_add_logger (ThreadClosure *thread_closure, - gpointer data) +session_thread_add_logger (ThreadClosure *thread_closure, gpointer data) { glnx_unref_object SoupLogger *logger = NULL; logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, 500); - soup_session_add_feature (thread_closure->session, - SOUP_SESSION_FEATURE (logger)); + soup_session_add_feature (thread_closure->session, SOUP_SESSION_FEATURE (logger)); } static void -session_thread_config_flags (ThreadClosure *thread_closure, - gpointer data) +session_thread_config_flags (ThreadClosure *thread_closure, gpointer data) { OstreeFetcherConfigFlags config_flags; @@ -263,15 +264,13 @@ session_thread_config_flags (ThreadClosure *thread_closure, if ((config_flags & OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE) > 0) { - g_object_set (thread_closure->session, - SOUP_SESSION_SSL_STRICT, - FALSE, NULL); + g_object_set (thread_closure->session, SOUP_SESSION_SSL_STRICT, FALSE, NULL); } } static void -on_authenticate (SoupSession *session, SoupMessage *msg, SoupAuth *auth, - gboolean retrying, gpointer user_data) +on_authenticate (SoupSession *session, SoupMessage *msg, SoupAuth *auth, gboolean retrying, + gpointer user_data) { ThreadClosure *thread_closure = user_data; @@ -282,51 +281,42 @@ on_authenticate (SoupSession *session, SoupMessage *msg, SoupAuth *auth, if (retrying) { g_autofree char *s = soup_uri_to_string (uri, FALSE); - g_set_error (&thread_closure->oob_error, - G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED, + g_set_error (&thread_closure->oob_error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED, "Invalid username or password for proxy '%s'", s); } else - soup_auth_authenticate (auth, soup_uri_get_user (uri), - soup_uri_get_password (uri)); + soup_auth_authenticate (auth, soup_uri_get_user (uri), soup_uri_get_password (uri)); } } static void -session_thread_set_proxy_cb (ThreadClosure *thread_closure, - gpointer data) +session_thread_set_proxy_cb (ThreadClosure *thread_closure, gpointer data) { SoupURI *proxy_uri = data; - g_object_set (thread_closure->session, - SOUP_SESSION_PROXY_URI, - proxy_uri, NULL); + g_object_set (thread_closure->session, SOUP_SESSION_PROXY_URI, proxy_uri, NULL); /* libsoup won't necessarily pass any embedded username and password to proxy * requests, so we have to be ready to handle 407 and handle them ourselves. * See also: https://bugzilla.gnome.org/show_bug.cgi?id=772932 * */ - if (soup_uri_get_user (proxy_uri) && - soup_uri_get_password (proxy_uri)) + if (soup_uri_get_user (proxy_uri) && soup_uri_get_password (proxy_uri)) { - g_signal_connect (thread_closure->session, "authenticate", - G_CALLBACK (on_authenticate), thread_closure); + g_signal_connect (thread_closure->session, "authenticate", G_CALLBACK (on_authenticate), + thread_closure); } } static void -session_thread_set_cookie_jar_cb (ThreadClosure *thread_closure, - gpointer data) +session_thread_set_cookie_jar_cb (ThreadClosure *thread_closure, gpointer data) { SoupCookieJar *jar = data; - soup_session_add_feature (thread_closure->session, - SOUP_SESSION_FEATURE (jar)); + soup_session_add_feature (thread_closure->session, SOUP_SESSION_FEATURE (jar)); } static void -session_thread_set_headers_cb (ThreadClosure *thread_closure, - gpointer data) +session_thread_set_headers_cb (ThreadClosure *thread_closure, gpointer data) { GVariant *headers = data; @@ -336,27 +326,23 @@ session_thread_set_headers_cb (ThreadClosure *thread_closure, #ifdef HAVE_LIBSOUP_CLIENT_CERTS static void -session_thread_set_tls_interaction_cb (ThreadClosure *thread_closure, - gpointer data) +session_thread_set_tls_interaction_cb (ThreadClosure *thread_closure, gpointer data) { const char *cert_and_key_path = data; /* str\0str\0 in one malloc buf */ const char *cert_path = cert_and_key_path; const char *key_path = cert_and_key_path + strlen (cert_and_key_path) + 1; - g_autoptr(OstreeTlsCertInteraction) interaction = NULL; + g_autoptr (OstreeTlsCertInteraction) interaction = NULL; /* The GTlsInteraction instance must be created in the * session thread so it uses the correct GMainContext. */ interaction = _ostree_tls_cert_interaction_new (cert_path, key_path); - g_object_set (thread_closure->session, - SOUP_SESSION_TLS_INTERACTION, - interaction, NULL); + g_object_set (thread_closure->session, SOUP_SESSION_TLS_INTERACTION, interaction, NULL); } #endif static void -session_thread_set_tls_database_cb (ThreadClosure *thread_closure, - gpointer data) +session_thread_set_tls_database_cb (ThreadClosure *thread_closure, gpointer data) { const char *db_path = data; @@ -368,27 +354,28 @@ session_thread_set_tls_database_cb (ThreadClosure *thread_closure, tlsdb = g_tls_file_database_new (db_path, &thread_closure->initialization_error); if (tlsdb) - g_object_set (thread_closure->session, - SOUP_SESSION_TLS_DATABASE, - tlsdb, NULL); + g_object_set (thread_closure->session, SOUP_SESSION_TLS_DATABASE, tlsdb, NULL); } else { - g_object_set (thread_closure->session, - SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, - TRUE, NULL); + g_object_set (thread_closure->session, SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE, NULL); } } static void -session_thread_set_extra_user_agent_cb (ThreadClosure *thread_closure, - gpointer data) +session_thread_set_max_outstanding_fetcher_requests (ThreadClosure *thread_closure, gpointer data) +{ + thread_closure->opt_max_outstanding_fetcher_requests = GPOINTER_TO_UINT (data); +} + +static void +session_thread_set_extra_user_agent_cb (ThreadClosure *thread_closure, gpointer data) { const char *extra_user_agent = data; if (extra_user_agent != NULL) { - g_autofree char *ua = - g_strdup_printf ("%s %s", OSTREE_FETCHER_USERAGENT_STRING, extra_user_agent); + g_autofree char *ua + = g_strdup_printf ("%s %s", OSTREE_FETCHER_USERAGENT_STRING, extra_user_agent); g_object_set (thread_closure->session, SOUP_SESSION_USER_AGENT, ua, NULL); } else @@ -398,12 +385,37 @@ session_thread_set_extra_user_agent_cb (ThreadClosure *thread_closure, } } -static void -on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data); +void +_ostree_fetcher_set_low_speed_time (OstreeFetcher *self, guint32 opt_low_speed_time) +{ + // TODO +} + +void +_ostree_fetcher_set_low_speed_limit (OstreeFetcher *self, guint32 opt_low_speed_limit) +{ + // TODO +} + +void +_ostree_fetcher_set_retry_all (OstreeFetcher *self, gboolean opt_retry_all) +{ + // TODO +} + +void +_ostree_fetcher_set_max_outstanding_fetcher_requests (OstreeFetcher *self, + guint32 opt_max_outstanding_fetcher_requests) +{ + session_thread_idle_add (self->thread_closure, + session_thread_set_max_outstanding_fetcher_requests, + GUINT_TO_POINTER (opt_max_outstanding_fetcher_requests), NULL); +} + +static void on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data); static void -start_pending_request (ThreadClosure *thread_closure, - GTask *task) +start_pending_request (ThreadClosure *thread_closure, GTask *task) { OstreeFetcherPendingURI *pending; @@ -413,18 +425,14 @@ start_pending_request (ThreadClosure *thread_closure, cancellable = g_task_get_cancellable (task); g_hash_table_add (thread_closure->outstanding, pending_uri_ref (pending)); - soup_request_send_async (pending->request, - cancellable, - on_request_sent, - g_object_ref (task)); + soup_request_send_async (pending->request, cancellable, on_request_sent, g_object_ref (task)); } static void -create_pending_soup_request (OstreeFetcherPendingURI *pending, - GError **error) +create_pending_soup_request (OstreeFetcherPendingURI *pending, GError **error) { OstreeFetcherURI *next_mirror = NULL; - g_autoptr(OstreeFetcherURI) uri = NULL; + g_autoptr (OstreeFetcherURI) uri = NULL; g_assert (pending->mirrorlist); g_assert (pending->mirrorlist_idx < pending->mirrorlist->len); @@ -433,35 +441,36 @@ create_pending_soup_request (OstreeFetcherPendingURI *pending, if (pending->filename) uri = _ostree_fetcher_uri_new_subpath (next_mirror, pending->filename); if (!uri) - uri = (OstreeFetcherURI*)g_uri_ref ((GUri*)next_mirror); + uri = (OstreeFetcherURI *)g_uri_ref ((GUri *)next_mirror); g_clear_object (&pending->request); { - g_autofree gchar *uri_str = g_uri_to_string ((GUri*)uri); + g_autofree gchar *uri_str = g_uri_to_string ((GUri *)uri); pending->request = soup_session_request (pending->thread_closure->session, uri_str, error); } /* Add caching headers. */ if (SOUP_IS_REQUEST_HTTP (pending->request) && pending->if_none_match != NULL) { - glnx_unref_object SoupMessage *msg = soup_request_http_get_message ((SoupRequestHTTP*) pending->request); + glnx_unref_object SoupMessage *msg + = soup_request_http_get_message ((SoupRequestHTTP *)pending->request); soup_message_headers_append (msg->request_headers, "If-None-Match", pending->if_none_match); } if (SOUP_IS_REQUEST_HTTP (pending->request) && pending->if_modified_since > 0) { - glnx_unref_object SoupMessage *msg = soup_request_http_get_message ((SoupRequestHTTP*) pending->request); + glnx_unref_object SoupMessage *msg + = soup_request_http_get_message ((SoupRequestHTTP *)pending->request); - g_autoptr(GDateTime) date_time = g_date_time_new_from_unix_utc (pending->if_modified_since); + g_autoptr (GDateTime) date_time = g_date_time_new_from_unix_utc (pending->if_modified_since); g_autofree char *mod_date = g_date_time_format (date_time, "%a, %d %b %Y %H:%M:%S %Z"); soup_message_headers_append (msg->request_headers, "If-Modified-Since", mod_date); } } static void -session_thread_request_uri (ThreadClosure *thread_closure, - gpointer data) +session_thread_request_uri (ThreadClosure *thread_closure, gpointer data) { GTask *task = G_TASK (data); OstreeFetcherPendingURI *pending; @@ -485,10 +494,17 @@ session_thread_request_uri (ThreadClosure *thread_closure, return; } + { + g_autofree gchar *uri_str = soup_uri_to_string (soup_request_get_uri (pending->request), FALSE); + g_debug ("%s: starting request %p for URI %s, using GTask %p", G_STRFUNC, pending->request, + uri_str, task); + } + if (SOUP_IS_REQUEST_HTTP (pending->request) && thread_closure->extra_headers) { - glnx_unref_object SoupMessage *msg = soup_request_http_get_message ((SoupRequestHTTP*) pending->request); - g_autoptr(GVariantIter) viter = g_variant_iter_new (thread_closure->extra_headers); + glnx_unref_object SoupMessage *msg + = soup_request_http_get_message ((SoupRequestHTTP *)pending->request); + g_autoptr (GVariantIter) viter = g_variant_iter_new (thread_closure->extra_headers); const char *key; const char *value; @@ -498,14 +514,11 @@ session_thread_request_uri (ThreadClosure *thread_closure, if (pending->is_membuf) { - soup_request_send_async (pending->request, - cancellable, - on_request_sent, - g_object_ref (task)); + soup_request_send_async (pending->request, cancellable, on_request_sent, g_object_ref (task)); } else { - start_pending_request (thread_closure, task); + start_pending_request (thread_closure, task); } } @@ -513,7 +526,7 @@ static gpointer ostree_fetcher_session_thread (gpointer data) { ThreadClosure *closure = data; - g_autoptr(GMainContext) mainctx = g_main_context_ref (closure->main_context); + g_autoptr (GMainContext) mainctx = g_main_context_ref (closure->main_context); /* This becomes the GMainContext that SoupSession schedules async * callbacks and emits signals from. Make it the thread-default @@ -521,13 +534,10 @@ ostree_fetcher_session_thread (gpointer data) g_main_context_push_thread_default (mainctx); /* We retain ownership of the SoupSession reference. */ - closure->session = soup_session_async_new_with_options (SOUP_SESSION_USER_AGENT, OSTREE_FETCHER_USERAGENT_STRING, - SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE, - SOUP_SESSION_USE_THREAD_CONTEXT, TRUE, - SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER, - SOUP_SESSION_TIMEOUT, 60, - SOUP_SESSION_IDLE_TIMEOUT, 60, - NULL); + closure->session = soup_session_async_new_with_options ( + SOUP_SESSION_USER_AGENT, OSTREE_FETCHER_USERAGENT_STRING, SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, + TRUE, SOUP_SESSION_USE_THREAD_CONTEXT, TRUE, SOUP_SESSION_ADD_FEATURE_BY_TYPE, + SOUP_TYPE_REQUESTER, SOUP_SESSION_TIMEOUT, 60, SOUP_SESSION_IDLE_TIMEOUT, 60, NULL); if (closure->transfer_gzip) soup_session_add_feature_by_type (closure->session, SOUP_TYPE_CONTENT_DECODER); @@ -536,20 +546,19 @@ ostree_fetcher_session_thread (gpointer data) * by spreading requests across mirrors. */ gint max_conns; g_object_get (closure->session, "max-conns-per-host", &max_conns, NULL); - if (max_conns < _OSTREE_MAX_OUTSTANDING_FETCHER_REQUESTS) + if (max_conns < closure->opt_max_outstanding_fetcher_requests) { /* We download a lot of small objects in ostree, so this * helps a lot. Also matches what most modern browsers do. * - * Note since https://github.com/ostreedev/ostree/commit/f4d1334e19ce3ab2f8872b1e28da52044f559401 - * we don't do queuing in this libsoup backend, but we still - * want to override libsoup's currently conservative - * #define SOUP_SESSION_MAX_CONNS_PER_HOST_DEFAULT 2 (as of 2018-02-14). + * Note since + * https://github.com/ostreedev/ostree/commit/f4d1334e19ce3ab2f8872b1e28da52044f559401 we + * don't do queuing in this libsoup backend, but we still want to override libsoup's + * currently conservative #define SOUP_SESSION_MAX_CONNS_PER_HOST_DEFAULT 2 (as of + * 2018-02-14). */ - max_conns = _OSTREE_MAX_OUTSTANDING_FETCHER_REQUESTS; - g_object_set (closure->session, - "max-conns-per-host", - max_conns, NULL); + max_conns = closure->opt_max_outstanding_fetcher_requests; + g_object_set (closure->session, "max-conns-per-host", max_conns, NULL); } /* This model ensures we don't hit a race using g_main_loop_quit(); @@ -576,40 +585,35 @@ ostree_fetcher_session_thread (gpointer data) } static void -_ostree_fetcher_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +_ostree_fetcher_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeFetcher *self = OSTREE_FETCHER (object); switch (prop_id) { - case PROP_CONFIG_FLAGS: - self->config_flags = g_value_get_flags (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + case PROP_CONFIG_FLAGS: + self->config_flags = g_value_get_flags (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } static void -_ostree_fetcher_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +_ostree_fetcher_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { OstreeFetcher *self = OSTREE_FETCHER (object); switch (prop_id) { - case PROP_CONFIG_FLAGS: - g_value_set_flags (value, self->config_flags); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + case PROP_CONFIG_FLAGS: + g_value_set_flags (value, self->config_flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } @@ -638,7 +642,7 @@ static void _ostree_fetcher_constructed (GObject *object) { OstreeFetcher *self = OSTREE_FETCHER (object); - g_autoptr(GMainContext) main_context = NULL; + g_autoptr (GMainContext) main_context = NULL; const char *http_proxy; main_context = g_main_context_new (); @@ -647,27 +651,25 @@ _ostree_fetcher_constructed (GObject *object) self->thread_closure->ref_count = 1; self->thread_closure->main_context = g_main_context_ref (main_context); self->thread_closure->running = 1; - self->thread_closure->transfer_gzip = (self->config_flags & OSTREE_FETCHER_FLAGS_TRANSFER_GZIP) != 0; + self->thread_closure->transfer_gzip + = (self->config_flags & OSTREE_FETCHER_FLAGS_TRANSFER_GZIP) != 0; - self->thread_closure->outstanding = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)pending_uri_unref); - self->thread_closure->output_stream_set = g_hash_table_new_full (NULL, NULL, - (GDestroyNotify) NULL, - (GDestroyNotify) g_object_unref); + self->thread_closure->outstanding + = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)pending_uri_unref); + self->thread_closure->output_stream_set + = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)NULL, (GDestroyNotify)g_object_unref); g_mutex_init (&self->thread_closure->output_stream_set_lock); if (g_getenv ("OSTREE_DEBUG_HTTP")) { - session_thread_idle_add (self->thread_closure, - session_thread_add_logger, - NULL, (GDestroyNotify) NULL); + session_thread_idle_add (self->thread_closure, session_thread_add_logger, NULL, + (GDestroyNotify)NULL); } if (self->config_flags != 0) { - session_thread_idle_add (self->thread_closure, - session_thread_config_flags, - GUINT_TO_POINTER (self->config_flags), - (GDestroyNotify) NULL); + session_thread_idle_add (self->thread_closure, session_thread_config_flags, + GUINT_TO_POINTER (self->config_flags), (GDestroyNotify)NULL); } http_proxy = g_getenv ("http_proxy"); @@ -676,8 +678,7 @@ _ostree_fetcher_constructed (GObject *object) /* FIXME Maybe implement GInitableIface and use g_thread_try_new() * so we can try to handle thread creation errors gracefully? */ - self->session_thread = g_thread_new ("fetcher-session-thread", - ostree_fetcher_session_thread, + self->session_thread = g_thread_new ("fetcher-session-thread", ostree_fetcher_session_thread, thread_closure_ref (self->thread_closure)); G_OBJECT_CLASS (_ostree_fetcher_parent_class)->constructed (object); @@ -693,16 +694,11 @@ _ostree_fetcher_class_init (OstreeFetcherClass *klass) gobject_class->finalize = _ostree_fetcher_finalize; gobject_class->constructed = _ostree_fetcher_constructed; - g_object_class_install_property (gobject_class, - PROP_CONFIG_FLAGS, - g_param_spec_flags ("config-flags", - "", - "", - OSTREE_TYPE_FETCHER_CONFIG_FLAGS, - OSTREE_FETCHER_FLAGS_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property ( + gobject_class, PROP_CONFIG_FLAGS, + g_param_spec_flags ("config-flags", "", "", OSTREE_TYPE_FETCHER_CONFIG_FLAGS, + OSTREE_FETCHER_FLAGS_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } static void @@ -711,9 +707,7 @@ _ostree_fetcher_init (OstreeFetcher *self) } OstreeFetcher * -_ostree_fetcher_new (int tmpdir_dfd, - const char *remote_name, - OstreeFetcherConfigFlags flags) +_ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfigFlags flags) { OstreeFetcher *self; @@ -724,6 +718,12 @@ _ostree_fetcher_new (int tmpdir_dfd, return self; } +void +_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self) +{ + self->thread_closure->force_anonymous = true; +} + int _ostree_fetcher_get_dfd (OstreeFetcher *fetcher) { @@ -731,8 +731,7 @@ _ostree_fetcher_get_dfd (OstreeFetcher *fetcher) } void -_ostree_fetcher_set_proxy (OstreeFetcher *self, - const char *http_proxy) +_ostree_fetcher_set_proxy (OstreeFetcher *self, const char *http_proxy) { SoupURI *proxy_uri; @@ -747,16 +746,14 @@ _ostree_fetcher_set_proxy (OstreeFetcher *self, } else { - session_thread_idle_add (self->thread_closure, - session_thread_set_proxy_cb, - proxy_uri, /* takes ownership */ - (GDestroyNotify) soup_uri_free); + session_thread_idle_add (self->thread_closure, session_thread_set_proxy_cb, + proxy_uri, /* takes ownership */ + (GDestroyNotify)soup_uri_free); } } void -_ostree_fetcher_set_cookie_jar (OstreeFetcher *self, - const char *jar_path) +_ostree_fetcher_set_cookie_jar (OstreeFetcher *self, const char *jar_path) { SoupCookieJar *jar; @@ -765,18 +762,15 @@ _ostree_fetcher_set_cookie_jar (OstreeFetcher *self, jar = soup_cookie_jar_text_new (jar_path, TRUE); - session_thread_idle_add (self->thread_closure, - session_thread_set_cookie_jar_cb, - jar, /* takes ownership */ - (GDestroyNotify) g_object_unref); + session_thread_idle_add (self->thread_closure, session_thread_set_cookie_jar_cb, + jar, /* takes ownership */ + (GDestroyNotify)g_object_unref); } void -_ostree_fetcher_set_client_cert (OstreeFetcher *self, - const char *cert_path, - const char *key_path) +_ostree_fetcher_set_client_cert (OstreeFetcher *self, const char *cert_path, const char *key_path) { - g_autoptr(GString) buf = NULL; + g_autoptr (GString) buf = NULL; g_return_if_fail (OSTREE_IS_FETCHER (self)); if (cert_path) @@ -787,51 +781,38 @@ _ostree_fetcher_set_client_cert (OstreeFetcher *self, } #ifdef HAVE_LIBSOUP_CLIENT_CERTS - session_thread_idle_add (self->thread_closure, - session_thread_set_tls_interaction_cb, - g_string_free (g_steal_pointer (&buf), FALSE), - (GDestroyNotify) g_free); + session_thread_idle_add (self->thread_closure, session_thread_set_tls_interaction_cb, + g_string_free (g_steal_pointer (&buf), FALSE), (GDestroyNotify)g_free); #else g_warning ("This version of OSTree is compiled without client side certificate support"); #endif } void -_ostree_fetcher_set_tls_database (OstreeFetcher *self, - const char *tlsdb_path) +_ostree_fetcher_set_tls_database (OstreeFetcher *self, const char *tlsdb_path) { g_return_if_fail (OSTREE_IS_FETCHER (self)); - session_thread_idle_add (self->thread_closure, - session_thread_set_tls_database_cb, - g_strdup (tlsdb_path), - (GDestroyNotify) g_free); + session_thread_idle_add (self->thread_closure, session_thread_set_tls_database_cb, + g_strdup (tlsdb_path), (GDestroyNotify)g_free); } void -_ostree_fetcher_set_extra_headers (OstreeFetcher *self, - GVariant *extra_headers) +_ostree_fetcher_set_extra_headers (OstreeFetcher *self, GVariant *extra_headers) { - session_thread_idle_add (self->thread_closure, - session_thread_set_headers_cb, - g_variant_ref (extra_headers), - (GDestroyNotify) g_variant_unref); + session_thread_idle_add (self->thread_closure, session_thread_set_headers_cb, + g_variant_ref (extra_headers), (GDestroyNotify)g_variant_unref); } void -_ostree_fetcher_set_extra_user_agent (OstreeFetcher *self, - const char *extra_user_agent) +_ostree_fetcher_set_extra_user_agent (OstreeFetcher *self, const char *extra_user_agent) { - session_thread_idle_add (self->thread_closure, - session_thread_set_extra_user_agent_cb, - g_strdup (extra_user_agent), - (GDestroyNotify) g_free); + session_thread_idle_add (self->thread_closure, session_thread_set_extra_user_agent_cb, + g_strdup (extra_user_agent), (GDestroyNotify)g_free); } static gboolean -finish_stream (OstreeFetcherPendingURI *pending, - GCancellable *cancellable, - GError **error) +finish_stream (OstreeFetcherPendingURI *pending, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; struct stat stbuf; @@ -855,8 +836,7 @@ finish_stream (OstreeFetcherPendingURI *pending, goto out; g_mutex_lock (&pending->thread_closure->output_stream_set_lock); - g_hash_table_remove (pending->thread_closure->output_stream_set, - pending->out_stream); + g_hash_table_remove (pending->thread_closure->output_stream_set, pending->out_stream); g_mutex_unlock (&pending->thread_closure->output_stream_set_lock); } @@ -884,15 +864,12 @@ finish_stream (OstreeFetcherPendingURI *pending, } ret = TRUE; - out: - (void) g_input_stream_close (pending->request_body, NULL, NULL); +out: + (void)g_input_stream_close (pending->request_body, NULL, NULL); return ret; } -static void -on_stream_read (GObject *object, - GAsyncResult *result, - gpointer user_data); +static void on_stream_read (GObject *object, GAsyncResult *result, gpointer user_data); static void remove_pending (OstreeFetcherPendingURI *pending) @@ -906,9 +883,7 @@ remove_pending (OstreeFetcherPendingURI *pending) } static void -on_out_splice_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) +on_out_splice_complete (GObject *object, GAsyncResult *result, gpointer user_data) { GTask *task = G_TASK (user_data); OstreeFetcherPendingURI *pending; @@ -919,19 +894,14 @@ on_out_splice_complete (GObject *object, pending = g_task_get_task_data (task); cancellable = g_task_get_cancellable (task); - bytes_written = g_output_stream_splice_finish ((GOutputStream *)object, - result, - &local_error); + bytes_written = g_output_stream_splice_finish ((GOutputStream *)object, result, &local_error); if (bytes_written < 0) goto out; - g_input_stream_read_bytes_async (pending->request_body, - 8192, G_PRIORITY_DEFAULT, - cancellable, - on_stream_read, - g_object_ref (task)); + g_input_stream_read_bytes_async (pending->request_body, 8192, G_PRIORITY_DEFAULT, cancellable, + on_stream_read, g_object_ref (task)); - out: +out: if (local_error) { g_task_return_error (task, local_error); @@ -942,14 +912,12 @@ on_out_splice_complete (GObject *object, } static void -on_stream_read (GObject *object, - GAsyncResult *result, - gpointer user_data) +on_stream_read (GObject *object, GAsyncResult *result, gpointer user_data) { GTask *task = G_TASK (user_data); OstreeFetcherPendingURI *pending; GCancellable *cancellable; - g_autoptr(GBytes) bytes = NULL; + g_autoptr (GBytes) bytes = NULL; gsize bytes_read; GError *local_error = NULL; @@ -963,8 +931,13 @@ on_stream_read (GObject *object, { if (!pending->is_membuf) { - if (!_ostree_fetcher_tmpf_from_flags (pending->flags, pending->thread_closure->base_tmpdir_dfd, - &pending->tmpf, &local_error)) + if (pending->thread_closure->force_anonymous) + { + if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &pending->tmpf, &local_error)) + goto out; + } + else if (!_ostree_fetcher_tmpf (pending->thread_closure->base_tmpdir_dfd, &pending->tmpf, + &local_error)) goto out; pending->out_stream = g_unix_output_stream_new (pending->tmpf.fd, FALSE); } @@ -980,7 +953,7 @@ on_stream_read (GObject *object, } /* Get a GBytes buffer */ - bytes = g_input_stream_read_bytes_finish ((GInputStream*)object, result, &local_error); + bytes = g_input_stream_read_bytes_finish ((GInputStream *)object, result, &local_error); if (!bytes) goto out; bytes_read = g_bytes_get_size (bytes); @@ -992,9 +965,10 @@ on_stream_read (GObject *object, goto out; if (pending->is_membuf) { - g_task_return_pointer (task, - g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)pending->out_stream), - (GDestroyNotify) g_bytes_unref); + g_task_return_pointer ( + task, + g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream *)pending->out_stream), + (GDestroyNotify)g_bytes_unref); } else { @@ -1013,14 +987,15 @@ on_stream_read (GObject *object, /* Verify max size */ if (pending->max_size > 0) { - if (bytes_read > pending->max_size || - (bytes_read + pending->current_size) > pending->max_size) + if (bytes_read > pending->max_size + || (bytes_read + pending->current_size) > pending->max_size) { - g_autofree char *uristr = - soup_uri_to_string (soup_request_get_uri (pending->request), FALSE); - local_error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, - "URI %s exceeded maximum size of %" G_GUINT64_FORMAT " bytes", - uristr, pending->max_size); + g_autofree char *uristr + = soup_uri_to_string (soup_request_get_uri (pending->request), FALSE); + local_error + = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, + "URI %s exceeded maximum size of %" G_GUINT64_FORMAT " bytes", + uristr, pending->max_size); goto out; } } @@ -1031,18 +1006,14 @@ on_stream_read (GObject *object, * guaranteed to do a complete write. */ { - g_autoptr(GInputStream) membuf = - g_memory_input_stream_new_from_bytes (bytes); + g_autoptr (GInputStream) membuf = g_memory_input_stream_new_from_bytes (bytes); g_output_stream_splice_async (pending->out_stream, membuf, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - G_PRIORITY_DEFAULT, - cancellable, - on_out_splice_complete, - g_object_ref (task)); + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, G_PRIORITY_DEFAULT, + cancellable, on_out_splice_complete, g_object_ref (task)); } } - out: +out: if (local_error) { g_task_return_error (task, local_error); @@ -1053,9 +1024,7 @@ on_stream_read (GObject *object, } static void -on_request_sent (GObject *object, - GAsyncResult *result, - gpointer user_data) +on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data) { GTask *task = G_TASK (user_data); /* Hold a ref to the pending across this function, since we remove @@ -1066,8 +1035,11 @@ on_request_sent (GObject *object, glnx_unref_object SoupMessage *msg = NULL; pending->state = OSTREE_FETCHER_STATE_COMPLETE; - pending->request_body = soup_request_send_finish ((SoupRequest*) object, - result, &local_error); + pending->request_body = soup_request_send_finish ((SoupRequest *)object, result, &local_error); + + g_debug ("%s: request %p (GTask %p) finished with request_body %p and error %s", G_STRFUNC, + object, task, pending->request_body, + (local_error != NULL) ? local_error->message : "none"); if (!pending->request_body) goto out; @@ -1075,9 +1047,9 @@ on_request_sent (GObject *object, if (SOUP_IS_REQUEST_HTTP (object)) { - msg = soup_request_http_get_message ((SoupRequestHTTP*) object); - if (msg->status_code == SOUP_STATUS_NOT_MODIFIED && - (pending->if_none_match != NULL || pending->if_modified_since > 0)) + msg = soup_request_http_get_message ((SoupRequestHTTP *)object); + if (msg->status_code == SOUP_STATUS_NOT_MODIFIED + && (pending->if_none_match != NULL || pending->if_modified_since > 0)) { /* Version on the server is unchanged from the version we have cached locally; * report this as an out-argument, a zero-length response buffer, and no error */ @@ -1093,14 +1065,14 @@ on_request_sent (GObject *object, if (local_error != NULL) goto out; - (void) g_input_stream_close (pending->request_body, NULL, NULL); + (void)g_input_stream_close (pending->request_body, NULL, NULL); start_pending_request (pending->thread_closure, task); } else { - g_autofree char *uristring = - soup_uri_to_string (soup_request_get_uri (pending->request), FALSE); + g_autofree char *uristring + = soup_uri_to_string (soup_request_get_uri (pending->request), FALSE); GIOErrorEnum code; @@ -1127,17 +1099,15 @@ on_request_sent (GObject *object, } { - g_autofree char *errmsg = - g_strdup_printf ("Server returned status %u: %s", - msg->status_code, - soup_status_get_phrase (msg->status_code)); + g_autofree char *errmsg + = g_strdup_printf ("Server returned status %u: %s", msg->status_code, + soup_status_get_phrase (msg->status_code)); /* Let's make OOB errors be the final one since they're probably * the cause for the error here. */ if (pending->thread_closure->oob_error) { - local_error = - g_error_copy (pending->thread_closure->oob_error); + local_error = g_error_copy (pending->thread_closure->oob_error); g_prefix_error (&local_error, "%s: ", errmsg); } else @@ -1145,15 +1115,13 @@ on_request_sent (GObject *object, } if (pending->mirrorlist->len > 1) - g_prefix_error (&local_error, - "All %u mirrors failed. Last error was: ", + g_prefix_error (&local_error, "All %u mirrors failed. Last error was: ", pending->mirrorlist->len); - if (pending->thread_closure->remote_name && - !((pending->flags & OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT) > 0 && - code == G_IO_ERROR_NOT_FOUND)) - _ostree_fetcher_journal_failure (pending->thread_closure->remote_name, - uristring, local_error->message); - + if (pending->thread_closure->remote_name + && !((pending->flags & OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT) > 0 + && code == G_IO_ERROR_NOT_FOUND)) + _ostree_fetcher_journal_failure (pending->thread_closure->remote_name, uristring, + local_error->message); } goto out; } @@ -1162,7 +1130,8 @@ on_request_sent (GObject *object, pending->out_etag = g_strdup (soup_message_headers_get_one (msg->response_headers, "ETag")); pending->out_last_modified = 0; - const char *last_modified_str = soup_message_headers_get_one (msg->response_headers, "Last-Modified"); + const char *last_modified_str + = soup_message_headers_get_one (msg->response_headers, "Last-Modified"); if (last_modified_str != NULL) { SoupDate *soup_date = soup_date_new_from_string (last_modified_str); @@ -1175,20 +1144,17 @@ on_request_sent (GObject *object, } pending->state = OSTREE_FETCHER_STATE_DOWNLOADING; - + pending->content_length = soup_request_get_content_length (pending->request); - g_input_stream_read_bytes_async (pending->request_body, - 8192, G_PRIORITY_DEFAULT, - cancellable, - on_stream_read, - g_object_ref (task)); + g_input_stream_read_bytes_async (pending->request_body, 8192, G_PRIORITY_DEFAULT, cancellable, + on_stream_read, g_object_ref (task)); - out: +out: if (local_error) { if (pending->request_body) - (void) g_input_stream_close (pending->request_body, NULL, NULL); + (void)g_input_stream_close (pending->request_body, NULL, NULL); g_task_return_error (task, local_error); remove_pending (pending); } @@ -1198,20 +1164,13 @@ on_request_sent (GObject *object, } static void -_ostree_fetcher_request_async (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - gboolean is_membuf, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_fetcher_request_async (OstreeFetcher *self, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, + guint64 if_modified_since, gboolean is_membuf, guint64 max_size, + int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = NULL; + g_autoptr (GTask) task = NULL; OstreeFetcherPendingURI *pending; g_return_if_fail (OSTREE_IS_FETCHER (self)); @@ -1232,44 +1191,32 @@ _ostree_fetcher_request_async (OstreeFetcher *self, task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, _ostree_fetcher_request_async); - g_task_set_task_data (task, pending, (GDestroyNotify) pending_uri_unref); + g_task_set_task_data (task, pending, (GDestroyNotify)pending_uri_unref); /* We'll use the GTask priority for our own priority queue. */ g_task_set_priority (task, priority); - session_thread_idle_add (self->thread_closure, - session_thread_request_uri, - g_object_ref (task), - (GDestroyNotify) g_object_unref); + session_thread_idle_add (self->thread_closure, session_thread_request_uri, g_object_ref (task), + (GDestroyNotify)g_object_unref); } void -_ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, GPtrArray *mirrorlist, + const char *filename, OstreeFetcherRequestFlags flags, + const char *if_none_match, guint64 if_modified_since, + guint64 max_size, int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - _ostree_fetcher_request_async (self, mirrorlist, filename, flags, - if_none_match, if_modified_since, FALSE, - max_size, priority, cancellable, + _ostree_fetcher_request_async (self, mirrorlist, filename, flags, if_none_match, + if_modified_since, FALSE, max_size, priority, cancellable, callback, user_data); } gboolean -_ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, - GAsyncResult *result, - GLnxTmpfile *out_tmpf, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - GError **error) +_ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, GAsyncResult *result, + GLnxTmpfile *out_tmpf, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + GError **error) { GTask *task; OstreeFetcherPendingURI *pending; @@ -1278,7 +1225,7 @@ _ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, g_return_val_if_fail (g_task_is_valid (result, self), FALSE); g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); - task = (GTask*)result; + task = (GTask *)result; pending = g_task_get_task_data (task); ret = g_task_propagate_pointer (task, error); @@ -1300,32 +1247,22 @@ _ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, } void -_ostree_fetcher_request_to_membuf (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_fetcher_request_to_membuf (OstreeFetcher *self, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, + guint64 if_modified_since, guint64 max_size, int priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { - _ostree_fetcher_request_async (self, mirrorlist, filename, flags, - if_none_match, if_modified_since, TRUE, - max_size, priority, cancellable, - callback, user_data); + _ostree_fetcher_request_async (self, mirrorlist, filename, flags, if_none_match, + if_modified_since, TRUE, max_size, priority, cancellable, callback, + user_data); } gboolean -_ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, - GAsyncResult *result, - GBytes **out_buf, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - GError **error) +_ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, GAsyncResult *result, + GBytes **out_buf, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + GError **error) { GTask *task; OstreeFetcherPendingURI *pending; @@ -1334,7 +1271,7 @@ _ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, g_return_val_if_fail (g_task_is_valid (result, self), FALSE); g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); - task = (GTask*)result; + task = (GTask *)result; pending = g_task_get_task_data (task); ret = g_task_propagate_pointer (task, error); @@ -1355,9 +1292,8 @@ _ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, return TRUE; } - guint64 -_ostree_fetcher_bytes_transferred (OstreeFetcher *self) +_ostree_fetcher_bytes_transferred (OstreeFetcher *self) { g_return_val_if_fail (OSTREE_IS_FETCHER (self), 0); @@ -1365,12 +1301,11 @@ _ostree_fetcher_bytes_transferred (OstreeFetcher *self) guint64 ret = self->thread_closure->total_downloaded; - GLNX_HASH_TABLE_FOREACH (self->thread_closure->output_stream_set, - GFileOutputStream*, stream) + GLNX_HASH_TABLE_FOREACH (self->thread_closure->output_stream_set, GFileOutputStream *, stream) { if (G_IS_FILE_DESCRIPTOR_BASED (stream)) { - int fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)stream); + int fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased *)stream); struct stat stbuf; if (glnx_fstat (fd, &stbuf, NULL)) diff --git a/src/libostree/ostree-fetcher-soup3.c b/src/libostree/ostree-fetcher-soup3.c new file mode 100644 index 0000000..6de5c1e --- /dev/null +++ b/src/libostree/ostree-fetcher-soup3.c @@ -0,0 +1,878 @@ +/* + * Copyright (C) 2011 Colin Walters + * Copyright (C) 2022 Igalia S.L. + * Copyright (C) 2023 Endless OS Foundation, LLC + * + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Colin Walters + * Author: Daniel Kolesa + * Author: Dan Nicholson + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "libglnx.h" +#include "ostree-enumtypes.h" +#include "ostree-fetcher-util.h" +#include "ostree-fetcher.h" +#include "ostree-repo-private.h" +#include "ostree-tls-cert-interaction-private.h" + +typedef struct +{ + GPtrArray *mirrorlist; /* list of base URIs */ + char *filename; /* relative name to fetch or NULL */ + guint mirrorlist_idx; + + SoupMessage *message; + struct OstreeFetcher *fetcher; + GMainContext *mainctx; + SoupSession *session; + GFile *file; + + gboolean is_membuf; + OstreeFetcherRequestFlags flags; + char *if_none_match; /* request ETag */ + guint64 if_modified_since; /* seconds since the epoch */ + GInputStream *response_body; + GLnxTmpfile tmpf; + GOutputStream *out_stream; + gboolean out_not_modified; /* TRUE if the server gave a HTTP 304 Not Modified response, which we + don’t propagate as an error */ + char *out_etag; /* response ETag */ + guint64 out_last_modified; /* response Last-Modified, seconds since the epoch */ + + guint64 max_size; + guint64 current_size; + goffset content_length; +} FetcherRequest; + +struct OstreeFetcher +{ + GObject parent_instance; + + OstreeFetcherConfigFlags config_flags; + char *remote_name; + int tmpdir_dfd; + bool force_anonymous; + + GHashTable *sessions; /* (element-type GMainContext SoupSession ) */ + GProxyResolver *proxy_resolver; + SoupCookieJar *cookie_jar; + OstreeTlsCertInteraction *client_cert; + GTlsDatabase *tls_database; + GVariant *extra_headers; + char *user_agent; + + guint64 bytes_transferred; + guint32 opt_max_outstanding_fetcher_requests; +}; + +enum +{ + PROP_0, + PROP_CONFIG_FLAGS +}; + +G_DEFINE_TYPE (OstreeFetcher, _ostree_fetcher, G_TYPE_OBJECT) + +static void +fetcher_request_free (FetcherRequest *request) +{ + g_debug ("Freeing request for %s", request->filename); + g_clear_pointer (&request->mirrorlist, g_ptr_array_unref); + g_clear_pointer (&request->filename, g_free); + g_clear_object (&request->message); + g_clear_pointer (&request->mainctx, g_main_context_unref); + g_clear_object (&request->session); + g_clear_object (&request->file); + g_clear_pointer (&request->if_none_match, g_free); + g_clear_object (&request->response_body); + glnx_tmpfile_clear (&request->tmpf); + g_clear_object (&request->out_stream); + g_clear_pointer (&request->out_etag, g_free); + g_free (request); +} + +static void on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data); + +static gboolean +_message_accept_cert_loose (SoupMessage *msg, GTlsCertificate *tls_peer_certificate, + GTlsCertificateFlags tls_peer_errors, gpointer data) +{ + return TRUE; +} + +static void +create_request_message (FetcherRequest *request) +{ + g_assert (request->mirrorlist); + g_assert (request->mirrorlist_idx < request->mirrorlist->len); + + OstreeFetcherURI *next_mirror = g_ptr_array_index (request->mirrorlist, request->mirrorlist_idx); + g_autoptr (OstreeFetcherURI) uri = NULL; + if (request->filename) + uri = _ostree_fetcher_uri_new_subpath (next_mirror, request->filename); + if (!uri) + uri = (OstreeFetcherURI *)g_uri_ref ((GUri *)next_mirror); + + g_clear_object (&request->message); + g_clear_object (&request->file); + g_clear_object (&request->response_body); + + GUri *guri = (GUri *)uri; + + /* file:// URI is handle via GFile */ + if (!strcmp (g_uri_get_scheme (guri), "file")) + { + g_autofree char *str = g_uri_to_string (guri); + request->file = g_file_new_for_uri (str); + return; + } + + request->message = soup_message_new_from_uri ("GET", guri); + + if (request->if_none_match != NULL) + soup_message_headers_append (soup_message_get_request_headers (request->message), + "If-None-Match", request->if_none_match); + + if (request->if_modified_since > 0) + { + g_autoptr (GDateTime) date_time = g_date_time_new_from_unix_utc (request->if_modified_since); + g_autofree char *mod_date = g_date_time_format (date_time, "%a, %d %b %Y %H:%M:%S %Z"); + soup_message_headers_append (soup_message_get_request_headers (request->message), + "If-Modified-Since", mod_date); + } + + if ((request->fetcher->config_flags & OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE) != 0) + g_signal_connect (request->message, "accept-certificate", + G_CALLBACK (_message_accept_cert_loose), NULL); + + if (request->fetcher->extra_headers) + { + g_autoptr (GVariantIter) viter = g_variant_iter_new (request->fetcher->extra_headers); + const char *key; + const char *value; + + while (g_variant_iter_next (viter, "(&s&s)", &key, &value)) + soup_message_headers_append (soup_message_get_request_headers (request->message), key, + value); + } +} + +static void +initiate_task_request (GTask *task) +{ + FetcherRequest *request = g_task_get_task_data (task); + create_request_message (request); + + GCancellable *cancellable = g_task_get_cancellable (task); + int priority = g_task_get_priority (task); + if (request->file) + g_file_read_async (request->file, priority, cancellable, on_request_sent, task); + else + { + g_autofree char *uri = g_uri_to_string (soup_message_get_uri (request->message)); + const char *dest = request->is_membuf ? "memory" : "tmpfile"; + g_debug ("Requesting %s to %s for session %p in main context %p", uri, dest, request->session, + request->mainctx); + soup_session_send_async (request->session, request->message, priority, cancellable, + on_request_sent, task); + } +} + +static void +_ostree_fetcher_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) +{ + OstreeFetcher *self = OSTREE_FETCHER (object); + + switch (prop_id) + { + case PROP_CONFIG_FLAGS: + self->config_flags = g_value_get_flags (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +_ostree_fetcher_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + OstreeFetcher *self = OSTREE_FETCHER (object); + + switch (prop_id) + { + case PROP_CONFIG_FLAGS: + g_value_set_flags (value, self->config_flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +_ostree_fetcher_finalize (GObject *object) +{ + OstreeFetcher *self = OSTREE_FETCHER (object); + + g_clear_pointer (&self->remote_name, g_free); + g_clear_pointer (&self->sessions, g_hash_table_unref); + g_clear_object (&self->proxy_resolver); + g_clear_object (&self->cookie_jar); + g_clear_object (&self->client_cert); + g_clear_object (&self->tls_database); + g_clear_pointer (&self->extra_headers, g_variant_unref); + g_clear_pointer (&self->user_agent, g_free); + + G_OBJECT_CLASS (_ostree_fetcher_parent_class)->finalize (object); +} + +static void +_ostree_fetcher_constructed (GObject *object) +{ + OstreeFetcher *self = OSTREE_FETCHER (object); + + const char *http_proxy = g_getenv ("http_proxy"); + if (http_proxy != NULL && http_proxy[0] != '\0') + _ostree_fetcher_set_proxy (self, http_proxy); + + G_OBJECT_CLASS (_ostree_fetcher_parent_class)->constructed (object); +} + +static void +_ostree_fetcher_class_init (OstreeFetcherClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = _ostree_fetcher_set_property; + gobject_class->get_property = _ostree_fetcher_get_property; + gobject_class->finalize = _ostree_fetcher_finalize; + gobject_class->constructed = _ostree_fetcher_constructed; + + g_object_class_install_property ( + gobject_class, PROP_CONFIG_FLAGS, + g_param_spec_flags ("config-flags", "", "", OSTREE_TYPE_FETCHER_CONFIG_FLAGS, + OSTREE_FETCHER_FLAGS_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); +} + +static void +_ostree_fetcher_init (OstreeFetcher *self) +{ + self->sessions = g_hash_table_new (g_direct_hash, g_direct_equal); +} + +OstreeFetcher * +_ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfigFlags flags) +{ + OstreeFetcher *self = g_object_new (OSTREE_TYPE_FETCHER, "config-flags", flags, NULL); + self->remote_name = g_strdup (remote_name); + self->tmpdir_dfd = tmpdir_dfd; + + return self; +} + +void +_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self) +{ + self->force_anonymous = true; +} + +int +_ostree_fetcher_get_dfd (OstreeFetcher *self) +{ + return self->tmpdir_dfd; +} + +void +_ostree_fetcher_set_proxy (OstreeFetcher *self, const char *http_proxy) +{ + g_return_if_fail (OSTREE_IS_FETCHER (self)); + g_return_if_fail (http_proxy != NULL && http_proxy[0] != '\0'); + + /* validate first */ + g_autoptr (GError) local_error = NULL; + g_autoptr (GUri) guri = g_uri_parse (http_proxy, G_URI_FLAGS_NONE, &local_error); + if (guri == NULL) + { + g_warning ("Invalid proxy URI '%s': %s", http_proxy, local_error->message); + return; + } + + g_clear_object (&self->proxy_resolver); + self->proxy_resolver = g_simple_proxy_resolver_new (http_proxy, NULL); +} + +void +_ostree_fetcher_set_cookie_jar (OstreeFetcher *self, const char *jar_path) +{ + g_return_if_fail (OSTREE_IS_FETCHER (self)); + g_return_if_fail (jar_path != NULL); + + g_clear_object (&self->cookie_jar); + self->cookie_jar = soup_cookie_jar_text_new (jar_path, TRUE); +} + +void +_ostree_fetcher_set_client_cert (OstreeFetcher *self, const char *cert_path, const char *key_path) +{ + g_return_if_fail (OSTREE_IS_FETCHER (self)); + + g_clear_object (&self->client_cert); + self->client_cert = _ostree_tls_cert_interaction_new (cert_path, key_path); +} + +void +_ostree_fetcher_set_tls_database (OstreeFetcher *self, const char *tlsdb_path) +{ + g_return_if_fail (OSTREE_IS_FETCHER (self)); + + g_autoptr (GError) local_error = NULL; + GTlsDatabase *tlsdb = g_tls_file_database_new (tlsdb_path, &local_error); + if (tlsdb == NULL) + { + g_warning ("Invalid TLS database '%s': %s", tlsdb_path, local_error->message); + return; + } + + g_clear_object (&self->tls_database); + self->tls_database = tlsdb; +} + +void +_ostree_fetcher_set_extra_headers (OstreeFetcher *self, GVariant *extra_headers) +{ + g_return_if_fail (OSTREE_IS_FETCHER (self)); + + g_clear_pointer (&self->extra_headers, g_variant_unref); + self->extra_headers = g_variant_ref (extra_headers); +} + +void +_ostree_fetcher_set_extra_user_agent (OstreeFetcher *self, const char *extra_user_agent) +{ + g_return_if_fail (OSTREE_IS_FETCHER (self)); + + g_clear_pointer (&self->user_agent, g_free); + if (extra_user_agent != NULL) + self->user_agent = g_strdup_printf ("%s %s", OSTREE_FETCHER_USERAGENT_STRING, extra_user_agent); +} + +void +_ostree_fetcher_set_low_speed_time (OstreeFetcher *self, guint32 opt_low_speed_time) +{ + // TODO +} + +void +_ostree_fetcher_set_low_speed_limit (OstreeFetcher *self, guint32 opt_low_speed_limit) +{ + // TODO +} + +void +_ostree_fetcher_set_retry_all (OstreeFetcher *self, gboolean opt_retry_all) +{ + // TODO +} + +void +_ostree_fetcher_set_max_outstanding_fetcher_requests (OstreeFetcher *self, + guint32 opt_max_outstanding_fetcher_requests) +{ + self->opt_max_outstanding_fetcher_requests = opt_max_outstanding_fetcher_requests; +} + +static gboolean +finish_stream (FetcherRequest *request, GCancellable *cancellable, GError **error) +{ + /* Close it here since we do an async fstat(), where we don't want + * to hit a bad fd. + */ + if (request->out_stream) + { + if ((request->flags & OSTREE_FETCHER_REQUEST_NUL_TERMINATION) > 0) + { + const guint8 nulchar = 0; + + if (!g_output_stream_write_all (request->out_stream, &nulchar, 1, NULL, cancellable, + error)) + return FALSE; + } + + if (!g_output_stream_close (request->out_stream, cancellable, error)) + return FALSE; + } + + if (!request->is_membuf) + { + struct stat stbuf; + + if (!glnx_fstat (request->tmpf.fd, &stbuf, error)) + return FALSE; + + if (request->content_length >= 0 && stbuf.st_size < request->content_length) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Download incomplete"); + return FALSE; + } + } + + return TRUE; +} + +static void on_stream_read (GObject *object, GAsyncResult *result, gpointer user_data); + +static void +on_out_splice_complete (GObject *object, GAsyncResult *result, gpointer user_data) +{ + g_autoptr (GTask) task = G_TASK (user_data); + GError *local_error = NULL; + + gssize bytes_written + = g_output_stream_splice_finish ((GOutputStream *)object, result, &local_error); + if (bytes_written < 0) + { + g_task_return_error (task, local_error); + return; + } + + FetcherRequest *request = g_task_get_task_data (task); + request->fetcher->bytes_transferred += bytes_written; + + GCancellable *cancellable = g_task_get_cancellable (task); + g_input_stream_read_bytes_async (request->response_body, 8192, G_PRIORITY_DEFAULT, cancellable, + on_stream_read, g_object_ref (task)); +} + +static void +on_stream_read (GObject *object, GAsyncResult *result, gpointer user_data) +{ + g_autoptr (GTask) task = G_TASK (user_data); + FetcherRequest *request = g_task_get_task_data (task); + GError *local_error = NULL; + + /* Only open the output stream on demand to ensure we use as + * few file descriptors as possible. + */ + if (!request->out_stream) + { + if (!request->is_membuf) + { + if (request->fetcher->force_anonymous) + { + if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &request->tmpf, &local_error)) + { + g_task_return_error (task, local_error); + return; + } + } + else if (!_ostree_fetcher_tmpf (request->fetcher->tmpdir_dfd, &request->tmpf, + &local_error)) + { + g_task_return_error (task, local_error); + return; + } + request->out_stream = g_unix_output_stream_new (request->tmpf.fd, FALSE); + } + else + { + request->out_stream = g_memory_output_stream_new_resizable (); + } + } + + /* Get a GBytes buffer */ + g_autoptr (GBytes) bytes + = g_input_stream_read_bytes_finish ((GInputStream *)object, result, &local_error); + if (!bytes) + { + g_task_return_error (task, local_error); + return; + } + + /* Was this the end of the stream? */ + GCancellable *cancellable = g_task_get_cancellable (task); + gsize bytes_read = g_bytes_get_size (bytes); + if (bytes_read == 0) + { + if (!finish_stream (request, cancellable, &local_error)) + { + g_task_return_error (task, local_error); + return; + } + if (request->is_membuf) + { + GBytes *mem_bytes + = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream *)request->out_stream); + g_task_return_pointer (task, mem_bytes, (GDestroyNotify)g_bytes_unref); + } + else + { + if (lseek (request->tmpf.fd, 0, SEEK_SET) < 0) + { + glnx_set_error_from_errno (&local_error); + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + g_task_return_boolean (task, TRUE); + } + } + else + { + /* Verify max size */ + if (request->max_size > 0) + { + if (bytes_read > request->max_size + || (bytes_read + request->current_size) > request->max_size) + { + g_autofree char *uristr = NULL; + + if (request->file) + uristr = g_file_get_uri (request->file); + else + uristr = g_uri_to_string (soup_message_get_uri (request->message)); + + local_error + = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, + "URI %s exceeded maximum size of %" G_GUINT64_FORMAT " bytes", + uristr, request->max_size); + g_task_return_error (task, local_error); + return; + } + } + + request->current_size += bytes_read; + + /* We do this instead of _write_bytes_async() as that's not + * guaranteed to do a complete write. + */ + { + g_autoptr (GInputStream) membuf = g_memory_input_stream_new_from_bytes (bytes); + g_output_stream_splice_async (request->out_stream, membuf, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, G_PRIORITY_DEFAULT, + cancellable, on_out_splice_complete, g_object_ref (task)); + } + } +} + +static void +on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data) +{ + g_autoptr (GTask) task = G_TASK (user_data); + FetcherRequest *request = g_task_get_task_data (task); + GError *local_error = NULL; + + if (request->file) + request->response_body + = (GInputStream *)g_file_read_finish ((GFile *)object, result, &local_error); + else + request->response_body = soup_session_send_finish ((SoupSession *)object, result, &local_error); + + if (!request->response_body) + { + g_task_return_error (task, local_error); + return; + } + + if (request->message) + { + SoupStatus status = soup_message_get_status (request->message); + if (status == SOUP_STATUS_NOT_MODIFIED + && (request->if_none_match != NULL || request->if_modified_since > 0)) + { + /* Version on the server is unchanged from the version we have cached locally; + * report this as an out-argument, a zero-length response buffer, and no error */ + request->out_not_modified = TRUE; + } + else if (!SOUP_STATUS_IS_SUCCESSFUL (status)) + { + /* is there another mirror we can try? */ + if (request->mirrorlist_idx + 1 < request->mirrorlist->len) + { + request->mirrorlist_idx++; + initiate_task_request (g_object_ref (task)); + return; + } + else + { + g_autofree char *uristring + = g_uri_to_string (soup_message_get_uri (request->message)); + GIOErrorEnum code = _ostree_fetcher_http_status_code_to_io_error (status); + { + g_autofree char *errmsg = g_strdup_printf ("Server returned status %u: %s", status, + soup_status_get_phrase (status)); + local_error = g_error_new_literal (G_IO_ERROR, code, errmsg); + } + + if (request->mirrorlist->len > 1) + g_prefix_error (&local_error, "All %u mirrors failed. Last error was: ", + request->mirrorlist->len); + if (request->fetcher->remote_name + && !((request->flags & OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT) > 0 + && code == G_IO_ERROR_NOT_FOUND)) + _ostree_fetcher_journal_failure (request->fetcher->remote_name, uristring, + local_error->message); + + g_task_return_error (task, local_error); + return; + } + } + + /* Grab cache properties from the response */ + request->out_etag = g_strdup (soup_message_headers_get_one ( + soup_message_get_response_headers (request->message), "ETag")); + request->out_last_modified = 0; + + const char *last_modified_str = soup_message_headers_get_one ( + soup_message_get_response_headers (request->message), "Last-Modified"); + if (last_modified_str != NULL) + { + GDateTime *soup_date = soup_date_time_new_from_http_string (last_modified_str); + if (soup_date != NULL) + { + request->out_last_modified = g_date_time_to_unix (soup_date); + g_date_time_unref (soup_date); + } + } + } + + if (request->file) + { + GFileInfo *info = g_file_query_info ( + request->file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SIZE, + 0, NULL, NULL); + if (info) + { + request->content_length = g_file_info_get_size (info); + g_object_unref (info); + } + else + request->content_length = -1; + } + else + { + SoupMessageHeaders *headers = soup_message_get_response_headers (request->message); + if (soup_message_headers_get_list (headers, "Content-Encoding") == NULL) + request->content_length = soup_message_headers_get_content_length (headers); + else + request->content_length = -1; + } + + GCancellable *cancellable = g_task_get_cancellable (task); + g_input_stream_read_bytes_async (request->response_body, 8192, G_PRIORITY_DEFAULT, cancellable, + on_stream_read, g_object_ref (task)); +} + +static SoupSession * +create_soup_session (OstreeFetcher *self) +{ + const char *user_agent = self->user_agent ?: OSTREE_FETCHER_USERAGENT_STRING; + SoupSession *session = soup_session_new_with_options ( + "user-agent", user_agent, "timeout", 60, "idle-timeout", 60, "max-conns-per-host", + self->opt_max_outstanding_fetcher_requests, NULL); + + /* SoupContentDecoder is included in the session by default. Remove it + * if gzip compression isn't in use. + */ + if ((self->config_flags & OSTREE_FETCHER_FLAGS_TRANSFER_GZIP) == 0) + soup_session_remove_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER); + + if (g_getenv ("OSTREE_DEBUG_HTTP")) + { + glnx_unref_object SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_BODY); + soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger)); + } + + if (self->proxy_resolver != NULL) + soup_session_set_proxy_resolver (session, self->proxy_resolver); + if (self->cookie_jar != NULL) + soup_session_add_feature (session, SOUP_SESSION_FEATURE (self->cookie_jar)); + if (self->client_cert != NULL) + soup_session_set_tls_interaction (session, (GTlsInteraction *)self->client_cert); + if (self->tls_database != NULL) + soup_session_set_tls_database (session, self->tls_database); + + return session; +} + +static gboolean +match_value (gpointer key, gpointer value, gpointer user_data) +{ + return value == user_data; +} + +static void +on_session_finalized (gpointer data, GObject *object) +{ + GHashTable *sessions = data; + g_debug ("Removing session %p from sessions hash table", object); + (void)g_hash_table_foreach_remove (sessions, match_value, object); +} + +static void +_ostree_fetcher_request_async (OstreeFetcher *self, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, + guint64 if_modified_since, gboolean is_membuf, guint64 max_size, + int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) +{ + g_return_if_fail (OSTREE_IS_FETCHER (self)); + g_return_if_fail (mirrorlist != NULL); + g_return_if_fail (mirrorlist->len > 0); + + FetcherRequest *request = g_new0 (FetcherRequest, 1); + request->mirrorlist = g_ptr_array_ref (mirrorlist); + request->filename = g_strdup (filename); + request->flags = flags; + request->if_none_match = g_strdup (if_none_match); + request->if_modified_since = if_modified_since; + request->max_size = max_size; + request->is_membuf = is_membuf; + request->fetcher = self; + request->mainctx = g_main_context_ref_thread_default (); + + /* Ideally each fetcher would have a single soup session. However, each + * session needs to be used from a single main context and the fetcher + * doesn't have that limitation. Instead, a mapping from main context to + * session is kept in the fetcher. + */ + g_debug ("Looking up session for main context %p", request->mainctx); + request->session = (SoupSession *)g_hash_table_lookup (self->sessions, request->mainctx); + if (request->session != NULL) + { + g_debug ("Using existing session %p", request->session); + g_object_ref (request->session); + } + else + { + request->session = create_soup_session (self); + g_debug ("Created new session %p", request->session); + g_hash_table_insert (self->sessions, request->mainctx, request->session); + + /* Add a weak ref to the session so that when it's finalized it can be + * removed from the hash table. + */ + g_object_weak_ref (G_OBJECT (request->session), on_session_finalized, self->sessions); + } + + g_autoptr (GTask) task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, _ostree_fetcher_request_async); + g_task_set_task_data (task, request, (GDestroyNotify)fetcher_request_free); + + /* We'll use the GTask priority for our own priority queue. */ + g_task_set_priority (task, priority); + + initiate_task_request (g_object_ref (task)); +} + +void +_ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, GPtrArray *mirrorlist, + const char *filename, OstreeFetcherRequestFlags flags, + const char *if_none_match, guint64 if_modified_since, + guint64 max_size, int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) +{ + _ostree_fetcher_request_async (self, mirrorlist, filename, flags, if_none_match, + if_modified_since, FALSE, max_size, priority, cancellable, + callback, user_data); +} + +gboolean +_ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, GAsyncResult *result, + GLnxTmpfile *out_tmpf, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, self), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); + + GTask *task = (GTask *)result; + gpointer ret = g_task_propagate_pointer (task, error); + if (!ret) + return FALSE; + + FetcherRequest *request = g_task_get_task_data (task); + g_assert (!request->is_membuf); + *out_tmpf = request->tmpf; + request->tmpf.initialized = FALSE; /* Transfer ownership */ + + if (out_not_modified != NULL) + *out_not_modified = request->out_not_modified; + if (out_etag != NULL) + *out_etag = g_steal_pointer (&request->out_etag); + if (out_last_modified != NULL) + *out_last_modified = request->out_last_modified; + + return TRUE; +} + +void +_ostree_fetcher_request_to_membuf (OstreeFetcher *self, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, + guint64 if_modified_since, guint64 max_size, int priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + _ostree_fetcher_request_async (self, mirrorlist, filename, flags, if_none_match, + if_modified_since, TRUE, max_size, priority, cancellable, callback, + user_data); +} + +gboolean +_ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, GAsyncResult *result, + GBytes **out_buf, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, self), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); + + GTask *task = (GTask *)result; + gpointer ret = g_task_propagate_pointer (task, error); + if (!ret) + return FALSE; + + FetcherRequest *request = g_task_get_task_data (task); + g_assert (request->is_membuf); + g_assert (out_buf); + *out_buf = ret; + + if (out_not_modified != NULL) + *out_not_modified = request->out_not_modified; + if (out_etag != NULL) + *out_etag = g_steal_pointer (&request->out_etag); + if (out_last_modified != NULL) + *out_last_modified = request->out_last_modified; + + return TRUE; +} + +guint64 +_ostree_fetcher_bytes_transferred (OstreeFetcher *self) +{ + return self->bytes_transferred; +} diff --git a/src/libostree/ostree-fetcher-uri.c b/src/libostree/ostree-fetcher-uri.c index d5ed576..af30012 100644 --- a/src/libostree/ostree-fetcher-uri.c +++ b/src/libostree/ostree-fetcher-uri.c @@ -32,16 +32,16 @@ void _ostree_fetcher_uri_free (OstreeFetcherURI *uri) { if (uri) - g_uri_unref ((GUri*)uri); + g_uri_unref ((GUri *)uri); } OstreeFetcherURI * -_ostree_fetcher_uri_parse (const char *str, - GError **error) +_ostree_fetcher_uri_parse (const char *str, GError **error) { GUri *uri = NULL; #if GLIB_CHECK_VERSION(2, 68, 0) - uri = g_uri_parse (str, G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_ENCODED | G_URI_FLAGS_SCHEME_NORMALIZE, error); + uri = g_uri_parse ( + str, G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_ENCODED | G_URI_FLAGS_SCHEME_NORMALIZE, error); #else /* perform manual scheme normalization for older glib */ uri = g_uri_parse (str, G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_ENCODED, error); @@ -50,42 +50,36 @@ _ostree_fetcher_uri_parse (const char *str, GUri *nuri = NULL; switch (g_uri_get_port (uri)) { - case 21: - if (!strcmp (g_uri_get_scheme (uri), "ftp")) - break; - return (OstreeFetcherURI*)uri; - case 80: - if (!strcmp (g_uri_get_scheme (uri), "http")) - break; - return (OstreeFetcherURI*)uri; - case 443: - if (!strcmp (g_uri_get_scheme (uri), "https")) - break; - return (OstreeFetcherURI*)uri; - default: - return (OstreeFetcherURI*)uri; + case 21: + if (!strcmp (g_uri_get_scheme (uri), "ftp")) + break; + return (OstreeFetcherURI *)uri; + case 80: + if (!strcmp (g_uri_get_scheme (uri), "http")) + break; + return (OstreeFetcherURI *)uri; + case 443: + if (!strcmp (g_uri_get_scheme (uri), "https")) + break; + return (OstreeFetcherURI *)uri; + default: + return (OstreeFetcherURI *)uri; } - nuri = g_uri_build_with_user (g_uri_get_flags (uri), "http", - g_uri_get_user (uri), - g_uri_get_password (uri), - NULL, - g_uri_get_host (uri), -1, - g_uri_get_path (uri), - g_uri_get_query (uri), + nuri = g_uri_build_with_user (g_uri_get_flags (uri), "http", g_uri_get_user (uri), + g_uri_get_password (uri), NULL, g_uri_get_host (uri), -1, + g_uri_get_path (uri), g_uri_get_query (uri), g_uri_get_fragment (uri)); g_uri_unref (uri); uri = nuri; } #endif - return (OstreeFetcherURI*)uri; + return (OstreeFetcherURI *)uri; } static OstreeFetcherURI * -_ostree_fetcher_uri_new_path_internal (OstreeFetcherURI *uri, - gboolean extend, - const char *path) +_ostree_fetcher_uri_new_path_internal (OstreeFetcherURI *uri, gboolean extend, const char *path) { - GUri *guri = (GUri*)uri; + GUri *guri = (GUri *)uri; const char *opath = g_uri_get_path (guri); g_autofree char *newpath = NULL; if (path) @@ -100,28 +94,20 @@ _ostree_fetcher_uri_new_path_internal (OstreeFetcherURI *uri, opath = path; } } - return (OstreeFetcherURI*)g_uri_build_with_user (g_uri_get_flags (guri), - g_uri_get_scheme (guri), - g_uri_get_user (guri), - g_uri_get_password (guri), - NULL, - g_uri_get_host (guri), - g_uri_get_port (guri), - opath, - g_uri_get_query (guri), - g_uri_get_fragment (guri)); + return (OstreeFetcherURI *)g_uri_build_with_user ( + g_uri_get_flags (guri), g_uri_get_scheme (guri), g_uri_get_user (guri), + g_uri_get_password (guri), NULL, g_uri_get_host (guri), g_uri_get_port (guri), opath, + g_uri_get_query (guri), g_uri_get_fragment (guri)); } OstreeFetcherURI * -_ostree_fetcher_uri_new_path (OstreeFetcherURI *uri, - const char *path) +_ostree_fetcher_uri_new_path (OstreeFetcherURI *uri, const char *path) { return _ostree_fetcher_uri_new_path_internal (uri, FALSE, path); } OstreeFetcherURI * -_ostree_fetcher_uri_new_subpath (OstreeFetcherURI *uri, - const char *subpath) +_ostree_fetcher_uri_new_subpath (OstreeFetcherURI *uri, const char *subpath) { return _ostree_fetcher_uri_new_path_internal (uri, TRUE, subpath); } @@ -135,32 +121,32 @@ _ostree_fetcher_uri_clone (OstreeFetcherURI *uri) char * _ostree_fetcher_uri_get_scheme (OstreeFetcherURI *uri) { - return g_strdup (g_uri_get_scheme ((GUri*)uri)); + return g_strdup (g_uri_get_scheme ((GUri *)uri)); } char * _ostree_fetcher_uri_get_path (OstreeFetcherURI *uri) { - return g_strdup (g_uri_get_path ((GUri*)uri)); + return g_strdup (g_uri_get_path ((GUri *)uri)); } char * _ostree_fetcher_uri_to_string (OstreeFetcherURI *uri) { - return g_uri_to_string_partial ((GUri*)uri, G_URI_HIDE_PASSWORD); + return g_uri_to_string_partial ((GUri *)uri, G_URI_HIDE_PASSWORD); } - /* Only accept http, https, and file; particularly curl has a ton of other * backends like sftp that we don't want, and this also gracefully filters * out invalid input. */ gboolean -_ostree_fetcher_uri_validate (OstreeFetcherURI *uri, GError **error) +_ostree_fetcher_uri_validate (OstreeFetcherURI *uri, GError **error) { - const char *scheme = g_uri_get_scheme ((GUri*)uri); + const char *scheme = g_uri_get_scheme ((GUri *)uri); // TODO only allow file if explicitly requested by a higher level - if (!(g_str_equal (scheme, "http") || g_str_equal (scheme, "https") || g_str_equal (scheme, "file"))) + if (!(g_str_equal (scheme, "http") || g_str_equal (scheme, "https") + || g_str_equal (scheme, "file"))) { g_autofree char *s = _ostree_fetcher_uri_to_string (uri); return glnx_throw (error, "Invalid URI scheme in %s", s); diff --git a/src/libostree/ostree-fetcher-util.c b/src/libostree/ostree-fetcher-util.c index 450a3ab..b797bee 100644 --- a/src/libostree/ostree-fetcher-util.c +++ b/src/libostree/ostree-fetcher-util.c @@ -32,47 +32,36 @@ typedef struct { - GBytes *result_buf; - gboolean result_not_modified; - char *result_etag; - guint64 result_last_modified; /* second since the epoch */ - gboolean done; - GError **error; -} - FetchUriSyncData; + GBytes *result_buf; + gboolean result_not_modified; + char *result_etag; + guint64 result_last_modified; /* second since the epoch */ + gboolean done; + GMainContext *main_context; /* (owned) */ + GError **error; +} FetchUriSyncData; static void -fetch_uri_sync_on_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) +fetch_uri_sync_on_complete (GObject *object, GAsyncResult *result, gpointer user_data) { FetchUriSyncData *data = user_data; - (void)_ostree_fetcher_request_to_membuf_finish ((OstreeFetcher*)object, - result, &data->result_buf, - &data->result_not_modified, - &data->result_etag, &data->result_last_modified, - data->error); + (void)_ostree_fetcher_request_to_membuf_finish ( + (OstreeFetcher *)object, result, &data->result_buf, &data->result_not_modified, + &data->result_etag, &data->result_last_modified, data->error); data->done = TRUE; + g_main_context_wakeup (data->main_context); } static gboolean -_ostree_fetcher_mirrored_request_to_membuf_once (OstreeFetcher *fetcher, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - GBytes **out_contents, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - guint64 max_size, - GCancellable *cancellable, - GError **error) +_ostree_fetcher_mirrored_request_to_membuf_once ( + OstreeFetcher *fetcher, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, guint64 if_modified_since, + GBytes **out_contents, gboolean *out_not_modified, char **out_etag, guint64 *out_last_modified, + guint64 max_size, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GMainContext) mainctx = NULL; + g_autoptr (GMainContext) mainctx = NULL; FetchUriSyncData data; g_assert (error != NULL); @@ -84,12 +73,12 @@ _ostree_fetcher_mirrored_request_to_membuf_once (OstreeFetcher *fe mainctx = g_main_context_new (); g_main_context_push_thread_default (mainctx); + data.main_context = g_main_context_ref (mainctx); data.done = FALSE; data.error = error; - _ostree_fetcher_request_to_membuf (fetcher, mirrorlist, filename, - flags, if_none_match, if_modified_since, - max_size, OSTREE_FETCHER_DEFAULT_PRIORITY, + _ostree_fetcher_request_to_membuf (fetcher, mirrorlist, filename, flags, if_none_match, + if_modified_since, max_size, OSTREE_FETCHER_DEFAULT_PRIORITY, cancellable, fetch_uri_sync_on_complete, &data); while (!data.done) g_main_context_iteration (mainctx, TRUE); @@ -122,42 +111,33 @@ _ostree_fetcher_mirrored_request_to_membuf_once (OstreeFetcher *fe *out_etag = g_steal_pointer (&data.result_etag); if (out_last_modified != NULL) *out_last_modified = data.result_last_modified; - out: +out: if (mainctx) g_main_context_pop_thread_default (mainctx); g_clear_pointer (&data.result_buf, g_bytes_unref); g_clear_pointer (&data.result_etag, g_free); + g_clear_pointer (&data.main_context, g_main_context_unref); return ret; } gboolean -_ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint n_network_retries, - GBytes **out_contents, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - guint64 max_size, - GCancellable *cancellable, - GError **error) +_ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher, GPtrArray *mirrorlist, + const char *filename, OstreeFetcherRequestFlags flags, + const char *if_none_match, guint64 if_modified_since, + guint n_network_retries, GBytes **out_contents, + gboolean *out_not_modified, char **out_etag, + guint64 *out_last_modified, guint64 max_size, + GCancellable *cancellable, GError **error) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; guint n_retries_remaining = n_network_retries; do { g_clear_error (&local_error); - if (_ostree_fetcher_mirrored_request_to_membuf_once (fetcher, mirrorlist, - filename, flags, - if_none_match, if_modified_since, - out_contents, out_not_modified, out_etag, - out_last_modified, max_size, - cancellable, &local_error)) + if (_ostree_fetcher_mirrored_request_to_membuf_once ( + fetcher, mirrorlist, filename, flags, if_none_match, if_modified_since, out_contents, + out_not_modified, out_etag, out_last_modified, max_size, cancellable, &local_error)) return TRUE; } while (_ostree_fetcher_should_retry_request (local_error, n_retries_remaining--)); @@ -169,46 +149,33 @@ _ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher /* Helper for callers who just want to fetch single one-off URIs */ gboolean -_ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher, - OstreeFetcherURI *uri, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint n_network_retries, - GBytes **out_contents, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - guint64 max_size, - GCancellable *cancellable, - GError **error) +_ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher, OstreeFetcherURI *uri, + OstreeFetcherRequestFlags flags, const char *if_none_match, + guint64 if_modified_since, guint n_network_retries, + GBytes **out_contents, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + guint64 max_size, GCancellable *cancellable, GError **error) { - g_autoptr(GPtrArray) mirrorlist = g_ptr_array_new (); + g_autoptr (GPtrArray) mirrorlist = g_ptr_array_new (); g_ptr_array_add (mirrorlist, uri); /* no transfer */ - return _ostree_fetcher_mirrored_request_to_membuf (fetcher, mirrorlist, NULL, flags, - if_none_match, if_modified_since, - n_network_retries, out_contents, - out_not_modified, out_etag, out_last_modified, max_size, - cancellable, error); + return _ostree_fetcher_mirrored_request_to_membuf ( + fetcher, mirrorlist, NULL, flags, if_none_match, if_modified_since, n_network_retries, + out_contents, out_not_modified, out_etag, out_last_modified, max_size, cancellable, error); } -#define OSTREE_HTTP_FAILURE_ID SD_ID128_MAKE(f0,2b,ce,89,a5,4e,4e,fa,b3,a9,4a,79,7d,26,20,4a) +#define OSTREE_HTTP_FAILURE_ID \ + SD_ID128_MAKE (f0, 2b, ce, 89, a5, 4e, 4e, fa, b3, a9, 4a, 79, 7d, 26, 20, 4a) void -_ostree_fetcher_journal_failure (const char *remote_name, - const char *url, - const char *msg) +_ostree_fetcher_journal_failure (const char *remote_name, const char *url, const char *msg) { /* Sanity - we don't want to log this when doing local/file pulls */ if (!remote_name) return; - ot_journal_send ("MESSAGE=libostree HTTP error from remote %s for <%s>: %s", - remote_name, url, msg, - "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_HTTP_FAILURE_ID), - "OSTREE_REMOTE=%s", remote_name, - "OSTREE_URL=%s", url, - "PRIORITY=%i", LOG_ERR, - NULL); + ot_journal_send ("MESSAGE=libostree HTTP error from remote %s for <%s>: %s", remote_name, url, + msg, "MESSAGE_ID=" SD_ID128_FORMAT_STR, + SD_ID128_FORMAT_VAL (OSTREE_HTTP_FAILURE_ID), "OSTREE_REMOTE=%s", remote_name, + "OSTREE_URL=%s", url, "PRIORITY=%i", LOG_ERR, NULL); } /* Check whether a particular operation should be retried. This is entirely @@ -220,32 +187,30 @@ _ostree_fetcher_journal_failure (const char *remote_name, * FIXME: In future, we may decide to use transient failures like this as a hint * to prioritise other mirrors for a particular pull operation (for example). */ gboolean -_ostree_fetcher_should_retry_request (const GError *error, - guint n_retries_remaining) +_ostree_fetcher_should_retry_request (const GError *error, guint n_retries_remaining) { if (error == NULL) - g_debug ("%s: error: unset, n_retries_remaining: %u", - G_STRFUNC, n_retries_remaining); + g_debug ("%s: error: unset, n_retries_remaining: %u", G_STRFUNC, n_retries_remaining); else - g_debug ("%s: error: %u:%u %s, n_retries_remaining: %u", - G_STRFUNC, error->domain, error->code, error->message, - n_retries_remaining); + g_debug ("%s: error: %u:%u %s, n_retries_remaining: %u", G_STRFUNC, error->domain, error->code, + error->message, n_retries_remaining); if (error == NULL || n_retries_remaining == 0) return FALSE; /* Return TRUE for transient errors. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT) || + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) + || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND) + || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE) + || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT) + || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_BUSY) || #if !GLIB_CHECK_VERSION(2, 44, 0) g_error_matches (error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) || #else g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED) || #endif - g_error_matches (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND) || - g_error_matches (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_TEMPORARY_FAILURE)) + g_error_matches (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND) + || g_error_matches (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_TEMPORARY_FAILURE)) { g_debug ("Should retry request (remaining: %u retries), due to transient error: %s", n_retries_remaining, error->message); @@ -263,12 +228,14 @@ _ostree_fetcher_http_status_code_to_io_error (guint status_code) { switch (status_code) { - case 403: /* SOUP_STATUS_FORBIDDEN */ - case 404: /* SOUP_STATUS_NOT_FOUND */ - case 410: /* SOUP_STATUS_GONE */ + case 403: /* SOUP_STATUS_FORBIDDEN */ + case 404: /* SOUP_STATUS_NOT_FOUND */ + case 410: /* SOUP_STATUS_GONE */ return G_IO_ERROR_NOT_FOUND; - case 408: /* SOUP_STATUS_REQUEST_TIMEOUT */ + case 408: /* SOUP_STATUS_REQUEST_TIMEOUT */ return G_IO_ERROR_TIMED_OUT; + case 500: /* SOUP_STATUS_INTERNAL_SERVER_ERROR */ + return G_IO_ERROR_BUSY; default: return G_IO_ERROR_FAILED; } diff --git a/src/libostree/ostree-fetcher-util.h b/src/libostree/ostree-fetcher-util.h index edbcd32..97233e1 100644 --- a/src/libostree/ostree-fetcher-util.h +++ b/src/libostree/ostree-fetcher-util.h @@ -32,59 +32,30 @@ G_BEGIN_DECLS #define OSTREE_FETCHER_USERAGENT_STRING (PACKAGE_NAME "/" PACKAGE_VERSION) static inline gboolean -_ostree_fetcher_tmpf_from_flags (OstreeFetcherRequestFlags flags, - int dfd, - GLnxTmpfile *tmpf, - GError **error) +_ostree_fetcher_tmpf (int dfd, GLnxTmpfile *tmpf, GError **error) { - if ((flags & OSTREE_FETCHER_REQUEST_LINKABLE) > 0) - { - if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_RDWR | O_CLOEXEC, tmpf, error)) - return FALSE; - } - else if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_RDWR | O_CLOEXEC, tmpf, error)) return FALSE; - if (!glnx_fchmod (tmpf->fd, 0644, error)) return FALSE; return TRUE; } -gboolean _ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint n_network_retries, - GBytes **out_contents, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - guint64 max_size, - GCancellable *cancellable, - GError **error); +gboolean _ostree_fetcher_mirrored_request_to_membuf ( + OstreeFetcher *fetcher, GPtrArray *mirrorlist, const char *filename, + OstreeFetcherRequestFlags flags, const char *if_none_match, guint64 if_modified_since, + guint n_network_retries, GBytes **out_contents, gboolean *out_not_modified, char **out_etag, + guint64 *out_last_modified, guint64 max_size, GCancellable *cancellable, GError **error); -gboolean _ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher, - OstreeFetcherURI *uri, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint n_network_retries, - GBytes **out_contents, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - guint64 max_size, - GCancellable *cancellable, - GError **error); +gboolean _ostree_fetcher_request_uri_to_membuf ( + OstreeFetcher *fetcher, OstreeFetcherURI *uri, OstreeFetcherRequestFlags flags, + const char *if_none_match, guint64 if_modified_since, guint n_network_retries, + GBytes **out_contents, gboolean *out_not_modified, char **out_etag, guint64 *out_last_modified, + guint64 max_size, GCancellable *cancellable, GError **error); -void _ostree_fetcher_journal_failure (const char *remote_name, - const char *url, - const char *msg); +void _ostree_fetcher_journal_failure (const char *remote_name, const char *url, const char *msg); -gboolean _ostree_fetcher_should_retry_request (const GError *error, - guint n_retries_remaining); +gboolean _ostree_fetcher_should_retry_request (const GError *error, guint n_retries_remaining); GIOErrorEnum _ostree_fetcher_http_status_code_to_io_error (guint status_code); diff --git a/src/libostree/ostree-fetcher.h b/src/libostree/ostree-fetcher.h index 3c91762..59ae633 100644 --- a/src/libostree/ostree-fetcher.h +++ b/src/libostree/ostree-fetcher.h @@ -25,141 +25,119 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_FETCHER (_ostree_fetcher_get_type ()) -#define OSTREE_FETCHER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_FETCHER, OstreeFetcher)) -#define OSTREE_FETCHER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_FETCHER, OstreeFetcherClass)) -#define OSTREE_IS_FETCHER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_FETCHER)) -#define OSTREE_IS_FETCHER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_FETCHER)) -#define OSTREE_FETCHER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_FETCHER, OstreeFetcherClass)) +#define OSTREE_TYPE_FETCHER (_ostree_fetcher_get_type ()) +#define OSTREE_FETCHER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_FETCHER, OstreeFetcher)) +#define OSTREE_FETCHER_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_FETCHER, OstreeFetcherClass)) +#define OSTREE_IS_FETCHER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_FETCHER)) +#define OSTREE_IS_FETCHER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_FETCHER)) +#define OSTREE_FETCHER_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_FETCHER, OstreeFetcherClass)) /* Lower values have higher priority */ #define OSTREE_FETCHER_DEFAULT_PRIORITY 0 typedef struct OstreeFetcherURI OstreeFetcherURI; -typedef struct OstreeFetcherClass OstreeFetcherClass; -typedef struct OstreeFetcher OstreeFetcher; +typedef struct OstreeFetcherClass OstreeFetcherClass; +typedef struct OstreeFetcher OstreeFetcher; struct OstreeFetcherClass { GObjectClass parent_class; }; -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeFetcher, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeFetcher, g_object_unref) -typedef enum { +typedef enum +{ OSTREE_FETCHER_FLAGS_NONE = 0, OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE = (1 << 0), OSTREE_FETCHER_FLAGS_TRANSFER_GZIP = (1 << 1), OSTREE_FETCHER_FLAGS_DISABLE_HTTP2 = (1 << 2), } OstreeFetcherConfigFlags; -typedef enum { +typedef enum +{ OSTREE_FETCHER_REQUEST_NUL_TERMINATION = (1 << 0), OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT = (1 << 1), OSTREE_FETCHER_REQUEST_LINKABLE = (1 << 2), } OstreeFetcherRequestFlags; -void -_ostree_fetcher_uri_free (OstreeFetcherURI *uri); -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeFetcherURI, _ostree_fetcher_uri_free) +void _ostree_fetcher_uri_free (OstreeFetcherURI *uri); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeFetcherURI, _ostree_fetcher_uri_free) -OstreeFetcherURI * -_ostree_fetcher_uri_parse (const char *str, - GError **error); +OstreeFetcherURI *_ostree_fetcher_uri_parse (const char *str, GError **error); -OstreeFetcherURI * -_ostree_fetcher_uri_clone (OstreeFetcherURI *uri); +OstreeFetcherURI *_ostree_fetcher_uri_clone (OstreeFetcherURI *uri); -OstreeFetcherURI * -_ostree_fetcher_uri_new_path (OstreeFetcherURI *uri, - const char *subpath); +OstreeFetcherURI *_ostree_fetcher_uri_new_path (OstreeFetcherURI *uri, const char *subpath); -OstreeFetcherURI * -_ostree_fetcher_uri_new_subpath (OstreeFetcherURI *uri, - const char *subpath); +OstreeFetcherURI *_ostree_fetcher_uri_new_subpath (OstreeFetcherURI *uri, const char *subpath); -char * -_ostree_fetcher_uri_get_scheme (OstreeFetcherURI *uri); +char *_ostree_fetcher_uri_get_scheme (OstreeFetcherURI *uri); -char * -_ostree_fetcher_uri_get_path (OstreeFetcherURI *uri); +char *_ostree_fetcher_uri_get_path (OstreeFetcherURI *uri); -char * -_ostree_fetcher_uri_to_string (OstreeFetcherURI *uri); +char *_ostree_fetcher_uri_to_string (OstreeFetcherURI *uri); -gboolean -_ostree_fetcher_uri_validate (OstreeFetcherURI *uri, GError **error); +gboolean _ostree_fetcher_uri_validate (OstreeFetcherURI *uri, GError **error); -GType _ostree_fetcher_get_type (void) G_GNUC_CONST; +GType _ostree_fetcher_get_type (void) G_GNUC_CONST; -OstreeFetcher *_ostree_fetcher_new (int tmpdir_dfd, - const char *remote_name, +OstreeFetcher *_ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfigFlags flags); -int _ostree_fetcher_get_dfd (OstreeFetcher *fetcher); - -void _ostree_fetcher_set_cookie_jar (OstreeFetcher *self, - const char *jar_path); - -void _ostree_fetcher_set_proxy (OstreeFetcher *fetcher, - const char *proxy); - -void _ostree_fetcher_set_client_cert (OstreeFetcher *fetcher, - const char *cert_path, - const char *key_path); - -void _ostree_fetcher_set_tls_database (OstreeFetcher *self, - const char *tlsdb_path); - -void _ostree_fetcher_set_extra_headers (OstreeFetcher *self, - GVariant *extra_headers); - -void _ostree_fetcher_set_extra_user_agent (OstreeFetcher *self, - const char *extra_user_agent); - -guint64 _ostree_fetcher_bytes_transferred (OstreeFetcher *self); - -void _ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean _ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, - GAsyncResult *result, - GLnxTmpfile *out_tmpf, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - GError **error); - -void _ostree_fetcher_request_to_membuf (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - OstreeFetcherRequestFlags flags, - const char *if_none_match, - guint64 if_modified_since, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean _ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, - GAsyncResult *result, - GBytes **out_buf, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - GError **error); +void _ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *fetcher); + +int _ostree_fetcher_get_dfd (OstreeFetcher *fetcher); + +void _ostree_fetcher_set_cookie_jar (OstreeFetcher *self, const char *jar_path); + +void _ostree_fetcher_set_proxy (OstreeFetcher *fetcher, const char *proxy); + +void _ostree_fetcher_set_client_cert (OstreeFetcher *fetcher, const char *cert_path, + const char *key_path); + +void _ostree_fetcher_set_low_speed_limit (OstreeFetcher *self, guint32 opt_low_speed_limit); + +void _ostree_fetcher_set_low_speed_time (OstreeFetcher *self, guint32 opt_low_speed_time); + +void _ostree_fetcher_set_retry_all (OstreeFetcher *self, gboolean opt_retry_all); + +void +_ostree_fetcher_set_max_outstanding_fetcher_requests (OstreeFetcher *self, + guint32 opt_max_outstanding_fetcher_requests); + +void _ostree_fetcher_set_tls_database (OstreeFetcher *self, const char *tlsdb_path); + +void _ostree_fetcher_set_extra_headers (OstreeFetcher *self, GVariant *extra_headers); + +void _ostree_fetcher_set_extra_user_agent (OstreeFetcher *self, const char *extra_user_agent); + +guint64 _ostree_fetcher_bytes_transferred (OstreeFetcher *self); + +void _ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, GPtrArray *mirrorlist, + const char *filename, OstreeFetcherRequestFlags flags, + const char *if_none_match, guint64 if_modified_since, + guint64 max_size, int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +gboolean _ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, GAsyncResult *result, + GLnxTmpfile *out_tmpf, + gboolean *out_not_modified, char **out_etag, + guint64 *out_last_modified, GError **error); + +void _ostree_fetcher_request_to_membuf (OstreeFetcher *self, GPtrArray *mirrorlist, + const char *filename, OstreeFetcherRequestFlags flags, + const char *if_none_match, guint64 if_modified_since, + guint64 max_size, int priority, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); +gboolean _ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, GAsyncResult *result, + GBytes **out_buf, gboolean *out_not_modified, + char **out_etag, guint64 *out_last_modified, + GError **error); G_END_DECLS diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c index 1c8d946..90aa481 100644 --- a/src/libostree/ostree-gpg-verifier.c +++ b/src/libostree/ostree-gpg-verifier.c @@ -25,18 +25,20 @@ #include "libglnx.h" #include "ostree-gpg-verifier.h" -#include "ot-gpg-utils.h" #include "ostree-gpg-verify-result-private.h" +#include "ot-gpg-utils.h" #include "otutil.h" -#include #include +#include -typedef struct { +typedef struct +{ GObjectClass parent_class; } OstreeGpgVerifierClass; -struct OstreeGpgVerifier { +struct OstreeGpgVerifier +{ GObject parent; GList *keyrings; @@ -77,31 +79,28 @@ _ostree_gpg_verifier_init (OstreeGpgVerifier *self) } static void -verify_result_finalized_cb (gpointer data, - GObject *finalized_verify_result) +verify_result_finalized_cb (gpointer data, GObject *finalized_verify_result) { - g_autofree gchar *tmp_dir = data; /* assume ownership */ + g_autofree gchar *tmp_dir = data; /* assume ownership */ /* XXX OstreeGpgVerifyResult could do this cleanup in its own * finalize() method, but I didn't want this keyring hack * bleeding into multiple classes. */ ot_gpgme_kill_agent (tmp_dir); - (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL); + (void)glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL); } static gboolean -_ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self, - gpgme_ctx_t gpgme_ctx, - GOutputStream *pubring_stream, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self, gpgme_ctx_t gpgme_ctx, + GOutputStream *pubring_stream, GCancellable *cancellable, + GError **error) { - GLNX_AUTO_PREFIX_ERROR("GPG", error); + GLNX_AUTO_PREFIX_ERROR ("GPG", error); for (GList *link = self->keyrings; link != NULL; link = link->next) { - g_autoptr(GFileInputStream) source_stream = NULL; + g_autoptr (GFileInputStream) source_stream = NULL; GFile *keyring_file = link->data; gssize bytes_written; GError *local_error = NULL; @@ -120,10 +119,9 @@ _ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self, return FALSE; } - bytes_written = g_output_stream_splice (pubring_stream, - G_INPUT_STREAM (source_stream), - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - cancellable, error); + bytes_written + = g_output_stream_splice (pubring_stream, G_INPUT_STREAM (source_stream), + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, cancellable, error); if (bytes_written < 0) return FALSE; } @@ -134,8 +132,7 @@ _ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self, gsize len; gsize bytes_written; const guint8 *buf = g_bytes_get_data (keyringd, &len); - if (!g_output_stream_write_all (pubring_stream, buf, len, &bytes_written, - cancellable, error)) + if (!g_output_stream_write_all (pubring_stream, buf, len, &bytes_written, cancellable, error)) return FALSE; } @@ -155,7 +152,7 @@ _ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self, gpgme_error_t gpg_error; const char *path = self->key_ascii_files->pdata[i]; glnx_autofd int fd = -1; - g_auto(gpgme_data_t) kdata = NULL; + g_auto (gpgme_data_t) kdata = NULL; if (!glnx_openat_rdonly (AT_FDCWD, path, TRUE, &fd, error)) goto out; @@ -178,24 +175,21 @@ _ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self, ret = TRUE; - out: +out: gpgme_set_armor (gpgme_ctx, armor); return ret; } gboolean -_ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self, - const char * const *key_ids, - GPtrArray **out_keys, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self, const char *const *key_ids, + GPtrArray **out_keys, GCancellable *cancellable, GError **error) { - GLNX_AUTO_PREFIX_ERROR("GPG", error); - g_auto(gpgme_ctx_t) context = NULL; - g_autoptr(GOutputStream) pubring_stream = NULL; + GLNX_AUTO_PREFIX_ERROR ("GPG", error); + g_auto (gpgme_ctx_t) context = NULL; + g_autoptr (GOutputStream) pubring_stream = NULL; g_autofree char *tmp_dir = NULL; - g_autoptr(GPtrArray) keys = NULL; + g_autoptr (GPtrArray) keys = NULL; gpgme_error_t gpg_error = 0; gboolean ret = FALSE; @@ -206,15 +200,13 @@ _ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self, if (context == NULL) goto out; - if (!ot_gpgme_ctx_tmp_home_dir (context, &tmp_dir, &pubring_stream, - cancellable, error)) + if (!ot_gpgme_ctx_tmp_home_dir (context, &tmp_dir, &pubring_stream, cancellable, error)) goto out; - if (!_ostree_gpg_verifier_import_keys (self, context, pubring_stream, - cancellable, error)) + if (!_ostree_gpg_verifier_import_keys (self, context, pubring_stream, cancellable, error)) goto out; - keys = g_ptr_array_new_with_free_func ((GDestroyNotify) gpgme_key_unref); + keys = g_ptr_array_new_with_free_func ((GDestroyNotify)gpgme_key_unref); if (key_ids != NULL) { for (guint i = 0; key_ids[i] != NULL; i++) @@ -224,8 +216,7 @@ _ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self, gpg_error = gpgme_get_key (context, key_ids[i], &key, 0); if (gpg_error != GPG_ERR_NO_ERROR) { - ot_gpgme_throw (gpg_error, error, "Unable to find key \"%s\"", - key_ids[i]); + ot_gpgme_throw (gpg_error, error, "Unable to find key \"%s\"", key_ids[i]); goto out; } @@ -260,28 +251,26 @@ _ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self, ret = TRUE; - out: - if (tmp_dir != NULL) { - ot_gpgme_kill_agent (tmp_dir); - (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL); - } +out: + if (tmp_dir != NULL) + { + ot_gpgme_kill_agent (tmp_dir); + (void)glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL); + } return ret; } OstreeGpgVerifyResult * -_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, - GBytes *signed_data, - GBytes *signatures, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, GBytes *signed_data, + GBytes *signatures, GCancellable *cancellable, GError **error) { - GLNX_AUTO_PREFIX_ERROR("GPG", error); + GLNX_AUTO_PREFIX_ERROR ("GPG", error); gpgme_error_t gpg_error = 0; - g_auto(gpgme_data_t) data_buffer = NULL; - g_auto(gpgme_data_t) signature_buffer = NULL; + g_auto (gpgme_data_t) data_buffer = NULL; + g_auto (gpgme_data_t) signature_buffer = NULL; g_autofree char *tmp_dir = NULL; - g_autoptr(GOutputStream) target_stream = NULL; + g_autoptr (GOutputStream) target_stream = NULL; OstreeGpgVerifyResult *result = NULL; gboolean success = FALSE; @@ -293,38 +282,30 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, if (g_cancellable_set_error_if_cancelled (cancellable, error)) goto out; - result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT, - cancellable, error, NULL); + result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT, cancellable, error, NULL); if (result == NULL) goto out; - if (!ot_gpgme_ctx_tmp_home_dir (result->context, - &tmp_dir, &target_stream, - cancellable, error)) + if (!ot_gpgme_ctx_tmp_home_dir (result->context, &tmp_dir, &target_stream, cancellable, error)) goto out; - if (!_ostree_gpg_verifier_import_keys (self, result->context, target_stream, - cancellable, error)) + if (!_ostree_gpg_verifier_import_keys (self, result->context, target_stream, cancellable, error)) goto out; /* Both the signed data and signature GBytes instances will outlive the * gpgme_data_t structs, so we can safely reuse the GBytes memory buffer * directly and avoid a copy. */ - gpg_error = gpgme_data_new_from_mem (&data_buffer, - g_bytes_get_data (signed_data, NULL), - g_bytes_get_size (signed_data), - 0 /* do not copy */); + gpg_error = gpgme_data_new_from_mem (&data_buffer, g_bytes_get_data (signed_data, NULL), + g_bytes_get_size (signed_data), 0 /* do not copy */); if (gpg_error != GPG_ERR_NO_ERROR) { ot_gpgme_throw (gpg_error, error, "Unable to read signed data"); goto out; } - gpg_error = gpgme_data_new_from_mem (&signature_buffer, - g_bytes_get_data (signatures, NULL), - g_bytes_get_size (signatures), - 0 /* do not copy */); + gpg_error = gpgme_data_new_from_mem (&signature_buffer, g_bytes_get_data (signatures, NULL), + g_bytes_get_size (signatures), 0 /* do not copy */); if (gpg_error != GPG_ERR_NO_ERROR) { ot_gpgme_throw (gpg_error, error, "Unable to read signature"); @@ -352,9 +333,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, * object so its GPGME context remains valid. It may yet have to * extract user details from signing keys and will need to access * the fabricated pubring.gpg keyring. */ - g_object_weak_ref (G_OBJECT (result), - verify_result_finalized_cb, - g_strdup (tmp_dir)); + g_object_weak_ref (G_OBJECT (result), verify_result_finalized_cb, g_strdup (tmp_dir)); } else { @@ -363,7 +342,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, /* Try to clean up the temporary directory. */ if (tmp_dir != NULL) - (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL); + (void)glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL); } return result; @@ -373,8 +352,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, * to the list of trusted keys. */ void -_ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self, - GFile *path) +_ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self, GFile *path) { g_return_if_fail (G_IS_FILE (path)); @@ -388,9 +366,8 @@ _ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self, * the list of trusted keys. */ void -_ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self, - GBytes *keyring, - const char *data_source) +_ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self, GBytes *keyring, + const char *data_source) { g_debug ("Adding GPG keyring data from %s to verifier", data_source); @@ -398,8 +375,7 @@ _ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self, } void -_ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, - const char *path) +_ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, const char *path) { g_debug ("Adding GPG key ASCII file %s to verifier", path); @@ -409,14 +385,11 @@ _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, } gboolean -_ostree_gpg_verifier_add_keyfile_path (OstreeGpgVerifier *self, - const char *path, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_add_keyfile_path (OstreeGpgVerifier *self, const char *path, + GCancellable *cancellable, GError **error) { - g_autoptr(GError) temp_error = NULL; - if (!_ostree_gpg_verifier_add_keyfile_dir_at (self, AT_FDCWD, path, - cancellable, &temp_error)) + g_autoptr (GError) temp_error = NULL; + if (!_ostree_gpg_verifier_add_keyfile_dir_at (self, AT_FDCWD, path, cancellable, &temp_error)) { g_assert (temp_error); @@ -442,16 +415,14 @@ _ostree_gpg_verifier_add_keyfile_path (OstreeGpgVerifier *self, * an error is returned. */ gboolean -_ostree_gpg_verifier_add_keyfile_dir_at (OstreeGpgVerifier *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_add_keyfile_dir_at (OstreeGpgVerifier *self, int dfd, const char *path, + GCancellable *cancellable, GError **error) { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; - if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, - &dfd_iter, error)) + if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error)) return FALSE; g_debug ("Adding GPG keyfile dir %s to verifier", path); @@ -460,8 +431,7 @@ _ostree_gpg_verifier_add_keyfile_dir_at (OstreeGpgVerifier *self, { struct dirent *dent; - if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, - cancellable, error)) + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) return FALSE; if (dent == NULL) break; @@ -480,26 +450,21 @@ _ostree_gpg_verifier_add_keyfile_dir_at (OstreeGpgVerifier *self, } gboolean -_ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self, - GFile *path, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self, GFile *path, + GCancellable *cancellable, GError **error) { - return _ostree_gpg_verifier_add_keyring_dir_at (self, AT_FDCWD, - gs_file_get_path_cached (path), + return _ostree_gpg_verifier_add_keyring_dir_at (self, AT_FDCWD, gs_file_get_path_cached (path), cancellable, error); } gboolean -_ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, int dfd, const char *path, + GCancellable *cancellable, GError **error) { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, - &dfd_iter, error)) + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error)) return FALSE; g_debug ("Adding GPG keyring dir %s to verifier", path); @@ -534,7 +499,7 @@ _ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, if (!glnx_openat_rdonly (dfd_iter.fd, dent->d_name, TRUE, &fd, error)) return FALSE; - g_autoptr(GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error); + g_autoptr (GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error); if (!data) return FALSE; @@ -545,11 +510,10 @@ _ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, } gboolean -_ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, - GCancellable *cancellable, - GError **error) +_ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, GCancellable *cancellable, + GError **error) { - g_return_val_if_fail (OSTREE_IS_GPG_VERIFIER (self), FALSE); + g_assert (OSTREE_IS_GPG_VERIFIER (self)); const char *global_keyring_path = g_getenv ("OSTREE_GPG_HOME"); if (global_keyring_path == NULL) @@ -557,9 +521,8 @@ _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, if (g_file_test (global_keyring_path, G_FILE_TEST_IS_DIR)) { - g_autoptr(GFile) global_keyring_dir = g_file_new_for_path (global_keyring_path); - if (!_ostree_gpg_verifier_add_keyring_dir (self, global_keyring_dir, - cancellable, error)) + g_autoptr (GFile) global_keyring_dir = g_file_new_for_path (global_keyring_path); + if (!_ostree_gpg_verifier_add_keyring_dir (self, global_keyring_dir, cancellable, error)) return glnx_prefix_error (error, "Reading keyring directory '%s'", gs_file_get_path_cached (global_keyring_dir)); } @@ -567,7 +530,7 @@ _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, return TRUE; } -OstreeGpgVerifier* +OstreeGpgVerifier * _ostree_gpg_verifier_new (void) { return g_object_new (OSTREE_TYPE_GPG_VERIFIER, NULL); diff --git a/src/libostree/ostree-gpg-verifier.h b/src/libostree/ostree-gpg-verifier.h index 34329bb..b9e54b7 100644 --- a/src/libostree/ostree-gpg-verifier.h +++ b/src/libostree/ostree-gpg-verifier.h @@ -20,17 +20,16 @@ * Author: Sjoerd Simons */ -//#pragma once +// #pragma once #include "ostree-gpg-verify-result.h" G_BEGIN_DECLS -#define OSTREE_TYPE_GPG_VERIFIER _ostree_gpg_verifier_get_type() +#define OSTREE_TYPE_GPG_VERIFIER _ostree_gpg_verifier_get_type () #define OSTREE_GPG_VERIFIER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_GPG_VERIFIER, OstreeGpgVerifier)) -#define OSTREE_IS_GPG_VERIFIER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_GPG_VERIFIER)) +#define OSTREE_IS_GPG_VERIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_GPG_VERIFIER)) typedef struct OstreeGpgVerifier OstreeGpgVerifier; @@ -44,52 +43,36 @@ GType _ostree_gpg_verifier_get_type (void); OstreeGpgVerifier *_ostree_gpg_verifier_new (void); OstreeGpgVerifyResult *_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, - GBytes *signed_data, - GBytes *signatures, - GCancellable *cancellable, - GError **error); - -gboolean _ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self, - const char * const *key_ids, - GPtrArray **out_keys, - GCancellable *cancellable, - GError **error); - -gboolean _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self, - GFile *path, - GCancellable *cancellable, - GError **error); - -gboolean _ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error); - -gboolean _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, - GCancellable *cancellable, - GError **error); - -void _ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self, - GBytes *data, - const char *data_source); -void _ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self, - GFile *path); - -void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, - const char *path); - -gboolean -_ostree_gpg_verifier_add_keyfile_path (OstreeGpgVerifier *self, - const char *path, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_gpg_verifier_add_keyfile_dir_at (OstreeGpgVerifier *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error); + GBytes *signed_data, + GBytes *signatures, + GCancellable *cancellable, + GError **error); + +gboolean _ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self, const char *const *key_ids, + GPtrArray **out_keys, GCancellable *cancellable, + GError **error); + +gboolean _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self, GFile *path, + GCancellable *cancellable, GError **error); + +gboolean _ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, int dfd, + const char *path, GCancellable *cancellable, + GError **error); + +gboolean _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, + GCancellable *cancellable, GError **error); + +void _ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self, GBytes *data, + const char *data_source); +void _ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self, GFile *path); + +void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, const char *path); + +gboolean _ostree_gpg_verifier_add_keyfile_path (OstreeGpgVerifier *self, const char *path, + GCancellable *cancellable, GError **error); + +gboolean _ostree_gpg_verifier_add_keyfile_dir_at (OstreeGpgVerifier *self, int dfd, + const char *path, GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/src/libostree/ostree-gpg-verify-result-dummy.c b/src/libostree/ostree-gpg-verify-result-dummy.c index 382b7b9..e1ff846 100644 --- a/src/libostree/ostree-gpg-verify-result-dummy.c +++ b/src/libostree/ostree-gpg-verify-result-dummy.c @@ -42,20 +42,19 @@ * * Private instance structure. */ -struct OstreeGpgVerifyResult { +struct OstreeGpgVerifyResult +{ GObject parent; }; - -typedef struct { +typedef struct +{ GObjectClass parent_class; } OstreeGpgVerifyResultClass; static void ostree_gpg_verify_result_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (OstreeGpgVerifyResult, - ostree_gpg_verify_result, - G_TYPE_OBJECT, +G_DEFINE_TYPE_WITH_CODE (OstreeGpgVerifyResult, ostree_gpg_verify_result, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, ostree_gpg_verify_result_initable_iface_init)) @@ -120,8 +119,7 @@ ostree_gpg_verify_result_count_valid (OstreeGpgVerifyResult *result) * Returns: %TRUE on success, %FALSE on failure **/ gboolean -ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, - const gchar *key_id, +ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, const gchar *key_id, guint *out_signature_index) { g_critical ("%s: GPG feature is disabled in a build time", __FUNCTION__); @@ -146,10 +144,8 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, * Returns: (transfer floating): a new, floating, #GVariant tuple **/ GVariant * -ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, - guint signature_index, - OstreeGpgSignatureAttr *attrs, - guint n_attrs) +ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, guint signature_index, + OstreeGpgSignatureAttr *attrs, guint n_attrs) { g_critical ("%s: GPG feature is disabled in a build time", __FUNCTION__); return NULL; @@ -187,8 +183,7 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, * Returns: (transfer floating): a new, floating, #GVariant tuple **/ GVariant * -ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, - guint signature_index) +ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, guint signature_index) { g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), NULL); @@ -217,13 +212,11 @@ ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, * @result. */ void -ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, - guint signature_index, - GString *output_buffer, - const gchar *line_prefix, +ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, guint signature_index, + GString *output_buffer, const gchar *line_prefix, OstreeGpgSignatureFormatFlags flags) { - g_autoptr(GVariant) variant = NULL; + g_autoptr (GVariant) variant = NULL; g_return_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result)); @@ -249,8 +242,7 @@ ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, * ostree_gpg_verify_result_get_all(). */ void -ostree_gpg_verify_result_describe_variant (GVariant *variant, - GString *output_buffer, +ostree_gpg_verify_result_describe_variant (GVariant *variant, GString *output_buffer, const gchar *line_prefix, OstreeGpgSignatureFormatFlags flags) { @@ -264,8 +256,7 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, type_string = g_variant_get_type_string (variant); g_return_if_fail (strcmp (type_string, "(bbbbbsxxsssssxx)") == 0); - g_string_append (output_buffer, - "GPG feature is disabled in a build time\n"); + g_string_append (output_buffer, "GPG feature is disabled in a build time\n"); g_critical ("%s: GPG feature is disabled in a build time", __FUNCTION__); } @@ -286,15 +277,13 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, * Since: 2016.6 */ gboolean -ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, - GError **error) +ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, GError **error) { if (result == NULL) return FALSE; g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "'%s': GPG feature is disabled in a build time", - __FUNCTION__); + "'%s': GPG feature is disabled in a build time", __FUNCTION__); return FALSE; } diff --git a/src/libostree/ostree-gpg-verify-result-private.h b/src/libostree/ostree-gpg-verify-result-private.h index 7182dac..a6b2208 100644 --- a/src/libostree/ostree-gpg-verify-result-private.h +++ b/src/libostree/ostree-gpg-verify-result-private.h @@ -28,7 +28,8 @@ * * Private instance structure. */ -struct OstreeGpgVerifyResult { +struct OstreeGpgVerifyResult +{ GObject parent; gpgme_ctx_t context; diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c index 3b6a7da..4b7bd47 100644 --- a/src/libostree/ostree-gpg-verify-result.c +++ b/src/libostree/ostree-gpg-verify-result.c @@ -45,7 +45,8 @@ * or get all signature details with ostree_gpg_verify_result_get_all(). */ -typedef struct { +typedef struct +{ GObjectClass parent_class; } OstreeGpgVerifyResultClass; @@ -70,9 +71,7 @@ static OstreeGpgSignatureAttr all_signature_attrs[] = { static void ostree_gpg_verify_result_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (OstreeGpgVerifyResult, - ostree_gpg_verify_result, - G_TYPE_OBJECT, +G_DEFINE_TYPE_WITH_CODE (OstreeGpgVerifyResult, ostree_gpg_verify_result, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, ostree_gpg_verify_result_initable_iface_init)) @@ -87,9 +86,8 @@ signature_is_valid (gpgme_signature_t signature) * - No summary but also no error means the signature is valid but * the signing key is not certified with a trusted signature. */ - return (signature->summary & GPGME_SIGSUM_VALID) || - (signature->summary & GPGME_SIGSUM_GREEN) || - (signature->summary == 0 && signature->status == GPG_ERR_NO_ERROR); + return (signature->summary & GPGME_SIGSUM_VALID) || (signature->summary & GPGME_SIGSUM_GREEN) + || (signature->summary == 0 && signature->status == GPG_ERR_NO_ERROR); } static gboolean @@ -104,9 +102,9 @@ signing_key_is_revoked (gpgme_signature_t signature) * Reported to GPGME: https://bugs.g10code.com/gnupg/issue1929 */ - return (signature->summary & GPGME_SIGSUM_KEY_REVOKED) || - ((signature->summary & GPGME_SIGSUM_SYS_ERROR) && - gpgme_err_code (signature->status) == GPG_ERR_CERT_REVOKED); + return (signature->summary & GPGME_SIGSUM_KEY_REVOKED) + || ((signature->summary & GPGME_SIGSUM_SYS_ERROR) + && gpgme_err_code (signature->status) == GPG_ERR_CERT_REVOKED); } static void @@ -124,9 +122,8 @@ ostree_gpg_verify_result_finalize (GObject *object) } static gboolean -ostree_gpg_verify_result_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) +ostree_gpg_verify_result_initable_init (GInitable *initable, GCancellable *cancellable, + GError **error) { OstreeGpgVerifyResult *result = OSTREE_GPG_VERIFY_RESULT (initable); gpgme_error_t gpg_error; @@ -181,9 +178,7 @@ ostree_gpg_verify_result_count_all (OstreeGpgVerifyResult *result) g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), 0); - for (signature = result->details->signatures; - signature != NULL; - signature = signature->next) + for (signature = result->details->signatures; signature != NULL; signature = signature->next) { count++; } @@ -207,9 +202,7 @@ ostree_gpg_verify_result_count_valid (OstreeGpgVerifyResult *result) g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), 0); - for (signature = result->details->signatures; - signature != NULL; - signature = signature->next) + for (signature = result->details->signatures; signature != NULL; signature = signature->next) { if (signature_is_valid (signature)) count++; @@ -234,11 +227,10 @@ ostree_gpg_verify_result_count_valid (OstreeGpgVerifyResult *result) * Returns: %TRUE on success, %FALSE on failure **/ gboolean -ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, - const gchar *key_id, +ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, const gchar *key_id, guint *out_signature_index) { - g_auto(gpgme_key_t) lookup_key = NULL; + g_auto (gpgme_key_t) lookup_key = NULL; gpgme_signature_t signature; guint signature_index; @@ -246,7 +238,7 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, g_return_val_if_fail (key_id != NULL, FALSE); /* fetch requested key_id from keyring to canonicalise ID */ - (void) gpgme_get_key (result->context, key_id, &lookup_key, 0); + (void)gpgme_get_key (result->context, key_id, &lookup_key, 0); if (lookup_key == NULL) { @@ -254,13 +246,12 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, return FALSE; } - for (signature = result->details->signatures, signature_index = 0; - signature != NULL; + for (signature = result->details->signatures, signature_index = 0; signature != NULL; signature = signature->next, signature_index++) { - g_auto(gpgme_key_t) signature_key = NULL; + g_auto (gpgme_key_t) signature_key = NULL; - (void) gpgme_get_key (result->context, signature->fpr, &signature_key, 0); + (void)gpgme_get_key (result->context, signature->fpr, &signature_key, 0); if (signature_key == NULL) { @@ -269,15 +260,13 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, } /* the first subkey in the list is the primary key */ - if (!g_strcmp0 (lookup_key->subkeys->fpr, - signature_key->subkeys->fpr)) + if (!g_strcmp0 (lookup_key->subkeys->fpr, signature_key->subkeys->fpr)) { if (out_signature_index != NULL) *out_signature_index = signature_index; /* Note early return */ return TRUE; } - } return FALSE; @@ -301,13 +290,11 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, * Returns: (transfer floating): a new, floating, #GVariant tuple **/ GVariant * -ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, - guint signature_index, - OstreeGpgSignatureAttr *attrs, - guint n_attrs) +ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, guint signature_index, + OstreeGpgSignatureAttr *attrs, guint n_attrs) { GVariantBuilder builder; - g_auto(gpgme_key_t) key = NULL; + g_auto (gpgme_key_t) key = NULL; gpgme_signature_t signature; guint ii; @@ -329,13 +316,13 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, * (OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING). */ for (ii = 0; ii < n_attrs; ii++) { - if (attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_NAME || - attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL || - attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY || - attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP || - attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY) + if (attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_NAME + || attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL + || attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY + || attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP + || attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY) { - (void) gpgme_get_key (result->context, signature->fpr, &key, 0); + (void)gpgme_get_key (result->context, signature->fpr, &key, 0); break; } } @@ -351,108 +338,108 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, switch (attrs[ii]) { - case OSTREE_GPG_SIGNATURE_ATTR_VALID: - v_boolean = signature_is_valid (signature); - child = g_variant_new_boolean (v_boolean); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED: - v_boolean = ((signature->summary & GPGME_SIGSUM_SIG_EXPIRED) != 0); - child = g_variant_new_boolean (v_boolean); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED: - v_boolean = ((signature->summary & GPGME_SIGSUM_KEY_EXPIRED) != 0); - child = g_variant_new_boolean (v_boolean); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED: - v_boolean = signing_key_is_revoked (signature); - child = g_variant_new_boolean (v_boolean); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING: - v_boolean = ((signature->summary & GPGME_SIGSUM_KEY_MISSING) != 0); - child = g_variant_new_boolean (v_boolean); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT: - child = g_variant_new_string (signature->fpr); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP: - child = g_variant_new_int64 ((gint64) signature->timestamp); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_EXP_TIMESTAMP: - child = g_variant_new_int64 ((gint64) signature->exp_timestamp); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME: - v_string = gpgme_pubkey_algo_name (signature->pubkey_algo); - if (v_string == NULL) - v_string = "[unknown name]"; - child = g_variant_new_string (v_string); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_HASH_ALGO_NAME: - v_string = gpgme_hash_algo_name (signature->hash_algo); - if (v_string == NULL) - v_string = "[unknown name]"; - child = g_variant_new_string (v_string); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_USER_NAME: - if (key != NULL && key->uids != NULL) - v_string = key->uids->name; - if (v_string == NULL) - v_string = "[unknown name]"; - child = g_variant_new_string (v_string); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL: - if (key != NULL && key->uids != NULL) - v_string = key->uids->email; - if (v_string == NULL) - v_string = "[unknown email]"; - child = g_variant_new_string (v_string); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY: - if (key != NULL && key->subkeys != NULL) - v_string = key->subkeys->fpr; - if (v_string == NULL) - v_string = ""; - child = g_variant_new_string (v_string); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP: + case OSTREE_GPG_SIGNATURE_ATTR_VALID: + v_boolean = signature_is_valid (signature); + child = g_variant_new_boolean (v_boolean); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED: + v_boolean = ((signature->summary & GPGME_SIGSUM_SIG_EXPIRED) != 0); + child = g_variant_new_boolean (v_boolean); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED: + v_boolean = ((signature->summary & GPGME_SIGSUM_KEY_EXPIRED) != 0); + child = g_variant_new_boolean (v_boolean); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED: + v_boolean = signing_key_is_revoked (signature); + child = g_variant_new_boolean (v_boolean); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING: + v_boolean = ((signature->summary & GPGME_SIGSUM_KEY_MISSING) != 0); + child = g_variant_new_boolean (v_boolean); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT: + child = g_variant_new_string (signature->fpr); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP: + child = g_variant_new_int64 ((gint64)signature->timestamp); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_EXP_TIMESTAMP: + child = g_variant_new_int64 ((gint64)signature->exp_timestamp); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME: + v_string = gpgme_pubkey_algo_name (signature->pubkey_algo); + if (v_string == NULL) + v_string = "[unknown name]"; + child = g_variant_new_string (v_string); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_HASH_ALGO_NAME: + v_string = gpgme_hash_algo_name (signature->hash_algo); + if (v_string == NULL) + v_string = "[unknown name]"; + child = g_variant_new_string (v_string); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_USER_NAME: + if (key != NULL && key->uids != NULL) + v_string = key->uids->name; + if (v_string == NULL) + v_string = "[unknown name]"; + child = g_variant_new_string (v_string); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL: + if (key != NULL && key->uids != NULL) + v_string = key->uids->email; + if (v_string == NULL) + v_string = "[unknown email]"; + child = g_variant_new_string (v_string); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY: + if (key != NULL && key->subkeys != NULL) + v_string = key->subkeys->fpr; + if (v_string == NULL) + v_string = ""; + child = g_variant_new_string (v_string); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP: + v_int64 = 0; + if (key != NULL) + { + gpgme_subkey_t subkey = key->subkeys; + + while (subkey != NULL && (g_strcmp0 (subkey->fpr, signature->fpr) != 0)) + subkey = subkey->next; + + if (subkey != NULL) + v_int64 = subkey->expires; + } + child = g_variant_new_int64 (v_int64); + break; + + case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY: + if (key != NULL && key->subkeys != NULL) + v_int64 = key->subkeys->expires; + else v_int64 = 0; - if (key != NULL) - { - gpgme_subkey_t subkey = key->subkeys; - - while (subkey != NULL && (g_strcmp0 (subkey->fpr, signature->fpr) != 0)) - subkey = subkey->next; - - if (subkey != NULL) - v_int64 = subkey->expires; - } - child = g_variant_new_int64 (v_int64); - break; - - case OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY: - if (key != NULL && key->subkeys != NULL) - v_int64 = key->subkeys->expires; - else - v_int64 = 0; - child = g_variant_new_int64 (v_int64); - break; - - default: - g_critical ("Invalid signature attribute (%d)", attrs[ii]); - g_variant_builder_clear (&builder); - return NULL; + child = g_variant_new_int64 (v_int64); + break; + + default: + g_critical ("Invalid signature attribute (%d)", attrs[ii]); + g_variant_builder_clear (&builder); + return NULL; } g_variant_builder_add_value (&builder, child); @@ -493,13 +480,11 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, * Returns: (transfer floating): a new, floating, #GVariant tuple **/ GVariant * -ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, - guint signature_index) +ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, guint signature_index) { g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), NULL); - return ostree_gpg_verify_result_get (result, signature_index, - all_signature_attrs, + return ostree_gpg_verify_result_get (result, signature_index, all_signature_attrs, G_N_ELEMENTS (all_signature_attrs)); } @@ -524,13 +509,11 @@ ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, * @result. */ void -ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, - guint signature_index, - GString *output_buffer, - const gchar *line_prefix, +ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, guint signature_index, + GString *output_buffer, const gchar *line_prefix, OstreeGpgSignatureFormatFlags flags) { - g_autoptr(GVariant) variant = NULL; + g_autoptr (GVariant) variant = NULL; g_return_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result)); @@ -540,41 +523,31 @@ ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, } static void -append_expire_info (GString *output_buffer, - const gchar *line_prefix, - const gchar *exp_type, - gint64 exp_timestamp, - gboolean expired) +append_expire_info (GString *output_buffer, const gchar *line_prefix, const gchar *exp_type, + gint64 exp_timestamp, gboolean expired) { if (line_prefix != NULL) g_string_append (output_buffer, line_prefix); - g_autoptr(GDateTime) date_time_utc = g_date_time_new_from_unix_utc (exp_timestamp); + g_autoptr (GDateTime) date_time_utc = g_date_time_new_from_unix_utc (exp_timestamp); if (date_time_utc == NULL) { g_string_append_printf (output_buffer, - "%s expiry timestamp (%" G_GINT64_FORMAT ") is invalid\n", - exp_type, + "%s expiry timestamp (%" G_GINT64_FORMAT ") is invalid\n", exp_type, exp_timestamp); return; } - g_autoptr(GDateTime) date_time_local = g_date_time_to_local (date_time_utc); + g_autoptr (GDateTime) date_time_local = g_date_time_to_local (date_time_utc); g_autofree char *formatted_date_time = g_date_time_format (date_time_local, "%c"); if (expired) { - g_string_append_printf (output_buffer, - "%s expired %s\n", - exp_type, - formatted_date_time); + g_string_append_printf (output_buffer, "%s expired %s\n", exp_type, formatted_date_time); } else { - g_string_append_printf (output_buffer, - "%s expires %s\n", - exp_type, - formatted_date_time); + g_string_append_printf (output_buffer, "%s expires %s\n", exp_type, formatted_date_time); } } @@ -593,13 +566,12 @@ append_expire_info (GString *output_buffer, * ostree_gpg_verify_result_get_all(). */ void -ostree_gpg_verify_result_describe_variant (GVariant *variant, - GString *output_buffer, +ostree_gpg_verify_result_describe_variant (GVariant *variant, GString *output_buffer, const gchar *line_prefix, OstreeGpgSignatureFormatFlags flags) { - g_autoptr(GDateTime) date_time_utc = NULL; - g_autoptr(GDateTime) date_time_local = NULL; + g_autoptr (GDateTime) date_time_utc = NULL; + g_autoptr (GDateTime) date_time_local = NULL; g_autofree char *formatted_date_time = NULL; gint64 timestamp; gint64 exp_timestamp; @@ -631,34 +603,23 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, * check_sig_and_print() in gnupg/g10/mainproc.c, though obviously * greatly simplified. */ - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_VALID, - "b", &valid); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, - "b", &sig_expired); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, - "b", &key_expired); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED, - "b", &key_revoked); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, - "b", &key_missing); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT, - "&s", &fingerprint); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY, - "&s", &fingerprint_primary); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP, - "x", ×tamp); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_EXP_TIMESTAMP, - "x", &exp_timestamp); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME, - "&s", &pubkey_algo); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_USER_NAME, - "&s", &user_name); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL, - "&s", &user_email); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, - "x", &key_exp_timestamp); - g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY, - "x", &key_exp_timestamp_primary); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_VALID, "b", &valid); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, "b", &sig_expired); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, "b", &key_expired); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED, "b", &key_revoked); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, "b", &key_missing); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT, "&s", &fingerprint); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY, "&s", + &fingerprint_primary); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP, "x", ×tamp); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_EXP_TIMESTAMP, "x", &exp_timestamp); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME, "&s", &pubkey_algo); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_USER_NAME, "&s", &user_name); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL, "&s", &user_email); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, "x", + &key_exp_timestamp); + g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY, "x", + &key_exp_timestamp_primary); len = strlen (fingerprint); key_id = (len > 16) ? fingerprint + len - 16 : fingerprint; @@ -678,8 +639,7 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, if (line_prefix != NULL) g_string_append (output_buffer, line_prefix); - g_string_append_printf (output_buffer, - "Signature made %s using %s key ID %s\n", + g_string_append_printf (output_buffer, "Signature made %s using %s key ID %s\n", formatted_date_time, pubkey_algo, key_id); g_clear_pointer (&date_time_utc, g_date_time_unref); @@ -691,14 +651,12 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, if (key_missing) { - g_string_append (output_buffer, - "Can't check signature: public key not found\n"); + g_string_append (output_buffer, "Can't check signature: public key not found\n"); } else if (valid) { - g_string_append_printf (output_buffer, - "Good signature from \"%s <%s>\"\n", - user_name, user_email); + g_string_append_printf (output_buffer, "Good signature from \"%s <%s>\"\n", user_name, + user_email); } else if (key_revoked) { @@ -706,15 +664,13 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, } else if (sig_expired) { - g_string_append_printf (output_buffer, - "Expired signature from \"%s <%s>\"\n", - user_name, user_email); + g_string_append_printf (output_buffer, "Expired signature from \"%s <%s>\"\n", user_name, + user_email); } else { - g_string_append_printf (output_buffer, - "BAD signature from \"%s <%s>\"\n", - user_name, user_email); + g_string_append_printf (output_buffer, "BAD signature from \"%s <%s>\"\n", user_name, + user_email); } if (!key_missing && (g_strcmp0 (fingerprint, fingerprint_primary) != 0)) @@ -722,25 +678,21 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, const char *key_id_primary; len = strlen (fingerprint_primary); - key_id_primary = (len > 16) ? fingerprint_primary + len - 16 : - fingerprint_primary; + key_id_primary = (len > 16) ? fingerprint_primary + len - 16 : fingerprint_primary; if (line_prefix != NULL) g_string_append (output_buffer, line_prefix); - g_string_append_printf (output_buffer, - "Primary key ID %s\n", key_id_primary); + g_string_append_printf (output_buffer, "Primary key ID %s\n", key_id_primary); } if (exp_timestamp > 0) - append_expire_info (output_buffer, line_prefix, "Signature", exp_timestamp, - sig_expired); + append_expire_info (output_buffer, line_prefix, "Signature", exp_timestamp, sig_expired); if (key_exp_timestamp > 0) - append_expire_info (output_buffer, line_prefix, "Key", key_exp_timestamp, - key_expired); + append_expire_info (output_buffer, line_prefix, "Key", key_exp_timestamp, key_expired); if (key_exp_timestamp_primary > 0 && (g_strcmp0 (fingerprint, fingerprint_primary) != 0)) - append_expire_info (output_buffer, line_prefix, "Primary key", - key_exp_timestamp_primary, key_expired); + append_expire_info (output_buffer, line_prefix, "Primary key", key_exp_timestamp_primary, + key_expired); } /** @@ -759,8 +711,7 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant, * Since: 2016.6 */ gboolean -ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, - GError **error) +ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, GError **error) { if (result == NULL) return FALSE; @@ -775,7 +726,7 @@ ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, * valid key. */ gint code = OSTREE_GPG_ERROR_NO_SIGNATURE; - g_autoptr(GString) buffer = g_string_sized_new (256); + g_autoptr (GString) buffer = g_string_sized_new (256); guint nsigs = ostree_gpg_verify_result_count_all (result); if (nsigs == 0) @@ -785,21 +736,21 @@ ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, { for (int i = nsigs - 1; i >= 0; i--) { - g_autoptr(GVariant) info = ostree_gpg_verify_result_get_all (result, i); + g_autoptr (GVariant) info = ostree_gpg_verify_result_get_all (result, i); ostree_gpg_verify_result_describe_variant (info, buffer, "", OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT); if (i == nsigs - 1) { gboolean key_missing, key_revoked, key_expired, sig_expired; - g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, - "b", &key_missing); - g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED, - "b", &key_revoked); - g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, - "b", &key_expired); - g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, - "b", &sig_expired); + g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, "b", + &key_missing); + g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED, "b", + &key_revoked); + g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, "b", + &key_expired); + g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, "b", + &sig_expired); if (key_missing) code = OSTREE_GPG_ERROR_MISSING_KEY; diff --git a/src/libostree/ostree-gpg-verify-result.h b/src/libostree/ostree-gpg-verify-result.h index 05e4403..666dc6f 100644 --- a/src/libostree/ostree-gpg-verify-result.h +++ b/src/libostree/ostree-gpg-verify-result.h @@ -24,8 +24,7 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_GPG_VERIFY_RESULT \ - (ostree_gpg_verify_result_get_type ()) +#define OSTREE_TYPE_GPG_VERIFY_RESULT (ostree_gpg_verify_result_get_type ()) #define OSTREE_GPG_VERIFY_RESULT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_GPG_VERIFY_RESULT, OstreeGpgVerifyResult)) #define OSTREE_IS_GPG_VERIFY_RESULT(obj) \ @@ -80,7 +79,8 @@ typedef struct OstreeGpgVerifyResult OstreeGpgVerifyResult; * Signature attributes available from an #OstreeGpgVerifyResult. * The attribute's #GVariantType is shown in brackets. **/ -typedef enum { +typedef enum +{ OSTREE_GPG_SIGNATURE_ATTR_VALID, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, @@ -108,19 +108,15 @@ _OSTREE_PUBLIC guint ostree_gpg_verify_result_count_valid (OstreeGpgVerifyResult *result); _OSTREE_PUBLIC -gboolean ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, - const gchar *key_id, +gboolean ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, const gchar *key_id, guint *out_signature_index); _OSTREE_PUBLIC -GVariant * ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, - guint signature_index, - OstreeGpgSignatureAttr *attrs, - guint n_attrs); +GVariant *ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, guint signature_index, + OstreeGpgSignatureAttr *attrs, guint n_attrs); _OSTREE_PUBLIC -GVariant * ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, - guint signature_index); +GVariant *ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, guint signature_index); /** * OstreeGpgSignatureFormatFlags: @@ -131,20 +127,18 @@ GVariant * ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result, * there's only one possible output format, but this enumeration allows * for future variations. **/ -typedef enum { +typedef enum +{ OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT = (0 << 0), } OstreeGpgSignatureFormatFlags; _OSTREE_PUBLIC -void ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, - guint signature_index, - GString *output_buffer, - const gchar *line_prefix, +void ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result, guint signature_index, + GString *output_buffer, const gchar *line_prefix, OstreeGpgSignatureFormatFlags flags); _OSTREE_PUBLIC -void ostree_gpg_verify_result_describe_variant (GVariant *variant, - GString *output_buffer, +void ostree_gpg_verify_result_describe_variant (GVariant *variant, GString *output_buffer, const gchar *line_prefix, OstreeGpgSignatureFormatFlags flags); @@ -156,7 +150,8 @@ gboolean ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult * OstreeGpgError: * @OSTREE_GPG_ERROR_NO_SIGNATURE: A signature was expected, but not found. * @OSTREE_GPG_ERROR_INVALID_SIGNATURE: A signature was malformed. - * @OSTREE_GPG_ERROR_MISSING_KEY: A signature was found, but was created with a key not in the configured keyrings. + * @OSTREE_GPG_ERROR_MISSING_KEY: A signature was found, but was created with a key not in the + * configured keyrings. * @OSTREE_GPG_ERROR_EXPIRED_SIGNATURE: A signature was expired. Since: 2020.1. * @OSTREE_GPG_ERROR_EXPIRED_KEY: A signature was found, but the key used to * sign it has expired. Since: 2020.1. @@ -168,7 +163,8 @@ gboolean ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult * * Since: 2017.10 */ -typedef enum { +typedef enum +{ OSTREE_GPG_ERROR_NO_SIGNATURE = 0, OSTREE_GPG_ERROR_INVALID_SIGNATURE, OSTREE_GPG_ERROR_MISSING_KEY, diff --git a/src/libostree/ostree-impl-system-generator.c b/src/libostree/ostree-impl-system-generator.c index da4654b..ad785eb 100644 --- a/src/libostree/ostree-impl-system-generator.c +++ b/src/libostree/ostree-impl-system-generator.c @@ -19,24 +19,26 @@ #include "config.h" -#include -#include #include +#include +#include #include #ifdef HAVE_LIBMOUNT #include #endif -#include -#include #include "otutil.h" +#include +#include -#include "ostree.h" -#include "ostree-core-private.h" #include "ostree-cmd-private.h" +#include "ostree-core-private.h" +#include "ostree-mount-util.h" +#include "ostree-sysroot-private.h" +#include "otcore.h" #ifdef HAVE_LIBMOUNT typedef FILE OtLibMountFile; -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtLibMountFile, endmntent) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OtLibMountFile, endmntent) /* Taken from systemd path-util.c */ static bool @@ -46,7 +48,7 @@ is_path (const char *p) } /* Taken from systemd path-util.c */ -static char* +static char * path_kill_slashes (char *path) { char *f, *t; @@ -85,38 +87,12 @@ path_kill_slashes (char *path) return path; } -/* Written by ostree-sysroot-deploy.c. We parse out the stateroot here since we - * need to know it to mount /var. Unfortunately we can't easily use the - * libostree API to find the booted deployment since /boot might not have been - * mounted yet. - */ -static char * -stateroot_from_ostree_cmdline (const char *ostree_cmdline, - GError **error) -{ - static GRegex *regex; - static gsize regex_initialized; - if (g_once_init_enter (®ex_initialized)) - { - regex = g_regex_new ("^/ostree/boot.[01]/([^/]+)/", 0, 0, NULL); - g_assert (regex); - g_once_init_leave (®ex_initialized, 1); - } - - g_autoptr(GMatchInfo) match = NULL; - if (!g_regex_match (regex, ostree_cmdline, 0, &match)) - return glnx_null_throw (error, "Failed to parse %s", ostree_cmdline); - - return g_match_info_fetch (match, 1); -} #endif /* Forcibly enable our internal units, since we detected ostree= on the kernel cmdline */ static gboolean -require_internal_units (const char *normal_dir, - const char *early_dir, - const char *late_dir, - GError **error) +require_internal_units (const char *normal_dir, const char *early_dir, const char *late_dir, + GError **error) { #ifdef SYSTEM_DATA_UNIT_PATH GCancellable *cancellable = NULL; @@ -125,16 +101,23 @@ require_internal_units (const char *normal_dir, if (!glnx_opendirat (AT_FDCWD, normal_dir, TRUE, &normal_dir_dfd, error)) return FALSE; - if (!glnx_shutil_mkdir_p_at (normal_dir_dfd, "local-fs.target.requires", 0755, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (normal_dir_dfd, "local-fs.target.requires", 0755, cancellable, + error)) return FALSE; - if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-remount.service", normal_dir_dfd, "local-fs.target.requires/ostree-remount.service") < 0) + if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-remount.service", normal_dir_dfd, + "local-fs.target.requires/ostree-remount.service") + < 0) return glnx_throw_errno_prefix (error, "symlinkat"); if (!glnx_shutil_mkdir_p_at (normal_dir_dfd, "multi-user.target.wants", 0755, cancellable, error)) return FALSE; - if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-finalize-staged.path", normal_dir_dfd, "multi-user.target.wants/ostree-finalize-staged.path") < 0) + if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-finalize-staged.path", normal_dir_dfd, + "multi-user.target.wants/ostree-finalize-staged.path") + < 0) return glnx_throw_errno_prefix (error, "symlinkat"); - if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-boot-complete.service", normal_dir_dfd, "multi-user.target.wants/ostree-boot-complete.service") < 0) + if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-boot-complete.service", normal_dir_dfd, + "multi-user.target.wants/ostree-boot-complete.service") + < 0) return glnx_throw_errno_prefix (error, "symlinkat"); return TRUE; @@ -145,11 +128,8 @@ require_internal_units (const char *normal_dir, /* Generate var.mount */ static gboolean -fstab_generator (const char *ostree_cmdline, - const char *normal_dir, - const char *early_dir, - const char *late_dir, - GError **error) +fstab_generator (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, + const char *late_dir, GError **error) { #ifdef HAVE_LIBMOUNT /* Not currently cancellable, but define a var in case we care later */ @@ -158,13 +138,17 @@ fstab_generator (const char *ostree_cmdline, static const char fstab_path[] = "/etc/fstab"; static const char var_path[] = "/var"; - /* ostree-prepare-root was patched to write the stateroot to this file */ - g_autofree char *stateroot = stateroot_from_ostree_cmdline (ostree_cmdline, error); - if (!stateroot) - return FALSE; + /* Written by ostree-sysroot-deploy.c. We parse out the stateroot here since we + * need to know it to mount /var. Unfortunately we can't easily use the + * libostree API to find the booted deployment since /boot might not have been + * mounted yet. + */ + g_autofree char *stateroot = NULL; + if (!_ostree_sysroot_parse_bootlink (ostree_cmdline, NULL, &stateroot, NULL, NULL, error)) + return glnx_prefix_error (error, "Parsing stateroot"); /* Load /etc/fstab if it exists, and look for a /var mount */ - g_autoptr(OtLibMountFile) fstab = setmntent (fstab_path, "re"); + g_autoptr (OtLibMountFile) fstab = setmntent (fstab_path, "re"); gboolean found_var_mnt = FALSE; if (!fstab) { @@ -204,11 +188,12 @@ fstab_generator (const char *ostree_cmdline, /* Generate our bind mount unit */ const char *stateroot_var_path = glnx_strjoina ("/sysroot/ostree/deploy/", stateroot, "/var"); - g_auto(GLnxTmpfile) tmpf = { 0, }; - if (!glnx_open_tmpfile_linkable_at (normal_dir_dfd, ".", O_WRONLY | O_CLOEXEC, - &tmpf, error)) + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (normal_dir_dfd, ".", O_WRONLY | O_CLOEXEC, &tmpf, error)) return FALSE; - g_autoptr(GOutputStream) outstream = g_unix_output_stream_new (tmpf.fd, FALSE); + g_autoptr (GOutputStream) outstream = g_unix_output_stream_new (tmpf.fd, FALSE); gsize bytes_written; /* This code is inspired by systemd's fstab-generator.c. * @@ -226,8 +211,7 @@ fstab_generator (const char *ostree_cmdline, "Where=%s\n" "What=%s\n" "Options=bind\n", - var_path, - stateroot_var_path)) + var_path, stateroot_var_path)) return FALSE; if (!g_output_stream_flush (outstream, cancellable, error)) return FALSE; @@ -236,8 +220,8 @@ fstab_generator (const char *ostree_cmdline, if (!glnx_fchmod (tmpf.fd, 0644, error)) return FALSE; /* Error out if somehow it already exists, that'll help us debug conflicts */ - if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_NOREPLACE, - normal_dir_dfd, "var.mount", error)) + if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_NOREPLACE, normal_dir_dfd, "var.mount", + error)) return FALSE; /* And ensure it's required; newer systemd will auto-inject fs dependencies @@ -245,7 +229,8 @@ fstab_generator (const char *ostree_cmdline, * need this. It's what the fstab generator does. And my mother always said, * listen to the fstab generator. */ - if (!glnx_shutil_mkdir_p_at (normal_dir_dfd, "local-fs.target.requires", 0755, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (normal_dir_dfd, "local-fs.target.requires", 0755, cancellable, + error)) return FALSE; if (symlinkat ("../var.mount", normal_dir_dfd, "local-fs.target.requires/var.mount") < 0) return glnx_throw_errno_prefix (error, "symlinkat"); @@ -258,12 +243,27 @@ fstab_generator (const char *ostree_cmdline, /* Implementation of ostree-system-generator */ gboolean -_ostree_impl_system_generator (const char *ostree_cmdline, - const char *normal_dir, - const char *early_dir, - const char *late_dir, - GError **error) +_ostree_impl_system_generator (const char *normal_dir, const char *early_dir, const char *late_dir, + GError **error) { + /* We conflict with the magic ostree-mount-deployment-var file for ostree-prepare-root. + * If this file is present, we have nothing to do! */ + if (unlinkat (AT_FDCWD, INITRAMFS_MOUNT_VAR, 0) == 0) + return TRUE; + + g_autofree char *cmdline = read_proc_cmdline (); + if (!cmdline) + return glnx_throw (error, "Failed to read /proc/cmdline"); + + /* If we're installed on a system which isn't using OSTree for boot (e.g. + * package installed as a dependency for flatpak or whatever), silently + * exit so that we don't error, but at the same time work where switchroot + * is PID 1 (and so hasn't created /run/ostree-booted). + */ + g_autofree char *ostree_cmdline = otcore_find_proc_cmdline_key (cmdline, "ostree"); + if (!ostree_cmdline) + return TRUE; + if (!require_internal_units (normal_dir, early_dir, late_dir, error)) return FALSE; if (!fstab_generator (ostree_cmdline, normal_dir, early_dir, late_dir, error)) diff --git a/src/libostree/ostree-kernel-args-private.h b/src/libostree/ostree-kernel-args-private.h new file mode 100644 index 0000000..967676b --- /dev/null +++ b/src/libostree/ostree-kernel-args-private.h @@ -0,0 +1,44 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the licence or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library. If not, see . + */ + +#pragma once + +#include "ostree-kernel-args.h" + +G_BEGIN_DECLS + +typedef struct _OstreeKernelArgsEntry OstreeKernelArgsEntry; + +GHashTable *_ostree_kernel_arg_get_kargs_table (OstreeKernelArgs *kargs); + +GPtrArray *_ostree_kernel_arg_get_key_array (OstreeKernelArgs *kargs); + +char *_ostree_kernel_args_entry_get_key (const OstreeKernelArgsEntry *e); + +char *_ostree_kernel_args_entry_get_value (const OstreeKernelArgsEntry *e); + +void _ostree_kernel_args_entry_set_key (OstreeKernelArgsEntry *e, char *key); + +void _ostree_kernel_args_entry_set_value (OstreeKernelArgsEntry *e, char *value); + +char *_ostree_kernel_args_get_key_index (const OstreeKernelArgs *kargs, int i); + +char *_ostree_kernel_args_get_value_index (const OstreeKernelArgs *kargs, int i); + +OstreeKernelArgsEntry *_ostree_kernel_args_entry_new (void); + +void _ostree_kernel_args_entry_value_free (OstreeKernelArgsEntry *e); + +G_END_DECLS diff --git a/src/libostree/ostree-kernel-args.c b/src/libostree/ostree-kernel-args.c index 40f11e9..9a9e0be 100644 --- a/src/libostree/ostree-kernel-args.c +++ b/src/libostree/ostree-kernel-args.c @@ -17,18 +17,20 @@ #include "config.h" -#include "ostree-kernel-args.h" #include "libglnx.h" +#include "ostree-kernel-args-private.h" #include "otutil.h" #include -struct _OstreeKernelArgs { - GPtrArray *order; +struct _OstreeKernelArgs +{ + GPtrArray *order; GHashTable *table; }; -struct _OstreeKernelArgsEntry { +struct _OstreeKernelArgsEntry +{ char *key; char *value; }; @@ -46,30 +48,26 @@ _ostree_kernel_args_entry_get_value (const OstreeKernelArgsEntry *e) } void -_ostree_kernel_args_entry_set_key (OstreeKernelArgsEntry *e, - char *key) +_ostree_kernel_args_entry_set_key (OstreeKernelArgsEntry *e, char *key) { e->key = key; } void -_ostree_kernel_args_entry_set_value (OstreeKernelArgsEntry *e, - char *value) +_ostree_kernel_args_entry_set_value (OstreeKernelArgsEntry *e, char *value) { e->value = value; } char * -_ostree_kernel_args_get_key_index (const OstreeKernelArgs *kargs, - int i) +_ostree_kernel_args_get_key_index (const OstreeKernelArgs *kargs, int i) { OstreeKernelArgsEntry *e = kargs->order->pdata[i]; return e->key; } char * -_ostree_kernel_args_get_value_index (const OstreeKernelArgs *kargs, - int i) +_ostree_kernel_args_get_value_index (const OstreeKernelArgs *kargs, int i) { OstreeKernelArgsEntry *e = kargs->order->pdata[i]; return e->value; @@ -100,24 +98,21 @@ kernel_args_entry_free_from_table (gpointer data) } static gboolean -kernel_args_entry_value_equal (gconstpointer data, - gconstpointer value) +kernel_args_entry_value_equal (gconstpointer data, gconstpointer value) { const OstreeKernelArgsEntry *e = data; return g_strcmp0 (_ostree_kernel_args_entry_get_value (e), value) == 0; } static gboolean -kernel_args_entry_key_equal (gconstpointer data, - gconstpointer key) +kernel_args_entry_key_equal (gconstpointer data, gconstpointer key) { const OstreeKernelArgsEntry *e = data; return g_strcmp0 (_ostree_kernel_args_entry_get_key (e), key) == 0; } static void -kernel_args_entry_replace_value (OstreeKernelArgsEntry *e, - const char *value) +kernel_args_entry_replace_value (OstreeKernelArgsEntry *e, const char *value) { g_assert (e); _ostree_kernel_args_entry_value_free (e); @@ -125,8 +120,7 @@ kernel_args_entry_replace_value (OstreeKernelArgsEntry *e, } static void -kernel_args_remove_entries_from_order (GPtrArray *order, - GPtrArray *entries) +kernel_args_remove_entries_from_order (GPtrArray *order, GPtrArray *entries) { g_assert (entries); for (int i = 0; i < entries->len; i++) @@ -144,12 +138,11 @@ split_keyeq (char *arg) // Note: key/val are in a single allocation block, so we don't free val. *eq = '\0'; - return eq+1; + return eq + 1; } static gboolean -_arg_has_prefix (const char *arg, - char **prefixes) +_arg_has_prefix (const char *arg, char **prefixes) { char **strviter; @@ -165,8 +158,7 @@ _arg_has_prefix (const char *arg, } static gboolean -strcmp0_equal (gconstpointer v1, - gconstpointer v2) +strcmp0_equal (gconstpointer v1, gconstpointer v2) { return g_strcmp0 (v1, v2) == 0; } @@ -187,8 +179,8 @@ ostree_kernel_args_new (void) ret = g_new0 (OstreeKernelArgs, 1); /* Hash table owns the kernel args entries, since it uses keys to index, * and its values are used to locate entries in the order array. */ - ret->table = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify)g_ptr_array_unref); + ret->table + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_ptr_array_unref); ret->order = g_ptr_array_new_with_free_func (NULL); return ret; } @@ -222,7 +214,7 @@ ostree_kernel_args_free (OstreeKernelArgs *kargs) void ostree_kernel_args_cleanup (void *loc) { - ostree_kernel_args_free (*((OstreeKernelArgs**)loc)); + ostree_kernel_args_free (*((OstreeKernelArgs **)loc)); } /** @@ -235,7 +227,7 @@ ostree_kernel_args_cleanup (void *loc) * * Since: 2019.3 **/ -GHashTable* +GHashTable * _ostree_kernel_arg_get_kargs_table (OstreeKernelArgs *kargs) { if (kargs != NULL) @@ -253,7 +245,7 @@ _ostree_kernel_arg_get_kargs_table (OstreeKernelArgs *kargs) * * Since: 2019.3 **/ -GPtrArray* +GPtrArray * _ostree_kernel_arg_get_key_array (OstreeKernelArgs *kargs) { if (kargs != NULL) @@ -291,9 +283,7 @@ _ostree_kernel_arg_get_key_array (OstreeKernelArgs *kargs) * Since: 2019.3 **/ gboolean -ostree_kernel_args_new_replace (OstreeKernelArgs *kargs, - const char *arg, - GError **error) +ostree_kernel_args_new_replace (OstreeKernelArgs *kargs, const char *arg, GError **error) { g_autofree char *arg_owned = g_strdup (arg); const char *key = arg_owned; @@ -345,9 +335,7 @@ ostree_kernel_args_new_replace (OstreeKernelArgs *kargs, * Since: 2019.3 **/ gboolean -ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs, - const char *key, - GError **error) +ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs, const char *key, GError **error) { GPtrArray *entries = g_hash_table_lookup (kargs->table, key); if (!entries) @@ -358,8 +346,7 @@ ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs, if (!g_hash_table_remove (kargs->table, key)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to find kernel argument '%s'", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to find kernel argument '%s'", key); return FALSE; } @@ -392,9 +379,7 @@ ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs, * Since: 2019.3 **/ gboolean -ostree_kernel_args_delete (OstreeKernelArgs *kargs, - const char *arg, - GError **error) +ostree_kernel_args_delete (OstreeKernelArgs *kargs, const char *arg, GError **error) { g_autofree char *arg_owned = g_strdup (arg); const char *key = arg_owned; @@ -444,8 +429,7 @@ ostree_kernel_args_delete (OstreeKernelArgs *kargs, * Since: 2019.3 **/ void -ostree_kernel_args_replace_take (OstreeKernelArgs *kargs, - char *arg) +ostree_kernel_args_replace_take (OstreeKernelArgs *kargs, char *arg) { gboolean existed; GPtrArray *entries = g_ptr_array_new_with_free_func (kernel_args_entry_free_from_table); @@ -466,7 +450,8 @@ ostree_kernel_args_replace_take (OstreeKernelArgs *kargs, g_assert_cmpuint (old_entries->len, >, 0); guint old_order_index = 0; - g_assert (ot_ptr_array_find_with_equal_func (kargs->order, old_key, kernel_args_entry_key_equal, &old_order_index)); + g_assert (ot_ptr_array_find_with_equal_func (kargs->order, old_key, + kernel_args_entry_key_equal, &old_order_index)); kernel_args_remove_entries_from_order (kargs->order, old_entries); g_assert_cmpstr (old_key, ==, arg); @@ -495,8 +480,7 @@ ostree_kernel_args_replace_take (OstreeKernelArgs *kargs, * Since: 2019.3 **/ void -ostree_kernel_args_replace (OstreeKernelArgs *kargs, - const char *arg) +ostree_kernel_args_replace (OstreeKernelArgs *kargs, const char *arg) { ostree_kernel_args_replace_take (kargs, g_strdup (arg)); } @@ -513,8 +497,7 @@ ostree_kernel_args_replace (OstreeKernelArgs *kargs, * Since: 2019.3 **/ void -ostree_kernel_args_append (OstreeKernelArgs *kargs, - const char *arg) +ostree_kernel_args_append (OstreeKernelArgs *kargs, const char *arg) { gboolean existed = TRUE; GPtrArray *entries = NULL; @@ -551,8 +534,7 @@ ostree_kernel_args_append (OstreeKernelArgs *kargs, * Since: 2019.3 **/ void -ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs, - char **argv) +ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs, char **argv) { char **strviter; @@ -566,17 +548,15 @@ ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs, /** * ostree_kernel_args_append_argv_filtered: * @kargs: a OstreeKernelArgs instance - * @argv: an array of key=value argument pairs - * @prefixes: an array of prefix strings + * @argv: (array zero-terminated=1): an array of key=value argument pairs + * @prefixes: (array zero-terminated=1): an array of prefix strings * * Appends each argument that does not have one of the @prefixes as prefix to the @kargs * * Since: 2019.3 **/ void -ostree_kernel_args_append_argv_filtered (OstreeKernelArgs *kargs, - char **argv, - char **prefixes) +ostree_kernel_args_append_argv_filtered (OstreeKernelArgs *kargs, char **argv, char **prefixes) { char **strviter; @@ -592,7 +572,7 @@ ostree_kernel_args_append_argv_filtered (OstreeKernelArgs *kargs, /** * ostree_kernel_args_append_argv: * @kargs: a OstreeKernelArgs instance - * @argv: an array of key=value argument pairs + * @argv: (array zero-terminated=1): an array of key=value argument pairs * * Appends each value in @argv to the corresponding value array and * appends key to kargs->order if it is not in the hash table already. @@ -600,8 +580,7 @@ ostree_kernel_args_append_argv_filtered (OstreeKernelArgs *kargs, * Since: 2019.3 **/ void -ostree_kernel_args_append_argv (OstreeKernelArgs *kargs, - char **argv) +ostree_kernel_args_append_argv (OstreeKernelArgs *kargs, char **argv) { ostree_kernel_args_append_argv_filtered (kargs, argv, NULL); } @@ -620,32 +599,29 @@ ostree_kernel_args_append_argv (OstreeKernelArgs *kargs, * Since: 2019.3 **/ gboolean -ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs, - GCancellable *cancellable, - GError **error) +ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs, GCancellable *cancellable, + GError **error) { - g_autoptr(GFile) proc_cmdline_path = g_file_new_for_path ("/proc/cmdline"); + g_autoptr (GFile) proc_cmdline_path = g_file_new_for_path ("/proc/cmdline"); g_autofree char *proc_cmdline = NULL; gsize proc_cmdline_len = 0; - g_auto(GStrv) proc_cmdline_args = NULL; + g_auto (GStrv) proc_cmdline_args = NULL; /* When updating the filter list don't forget to update the list in the tests * e.g. tests/test-admin-deploy-karg.sh and * tests/test-admin-instutil-set-kargs.sh */ char *filtered_prefixes[] = { "BOOT_IMAGE=", /* GRUB 2 */ - "initrd=", /* sd-boot */ + "initrd=", /* sd-boot */ NULL }; - if (!g_file_load_contents (proc_cmdline_path, cancellable, - &proc_cmdline, &proc_cmdline_len, - NULL, error)) + if (!g_file_load_contents (proc_cmdline_path, cancellable, &proc_cmdline, &proc_cmdline_len, NULL, + error)) return FALSE; g_strchomp (proc_cmdline); proc_cmdline_args = g_strsplit (proc_cmdline, " ", -1); - ostree_kernel_args_append_argv_filtered (kargs, proc_cmdline_args, - filtered_prefixes); + ostree_kernel_args_append_argv_filtered (kargs, proc_cmdline_args, filtered_prefixes); return TRUE; } @@ -660,8 +636,7 @@ ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs, * Since: 2019.3 **/ void -ostree_kernel_args_parse_append (OstreeKernelArgs *kargs, - const char *options) +ostree_kernel_args_parse_append (OstreeKernelArgs *kargs, const char *options) { char **args = NULL; char **iter; @@ -730,7 +705,7 @@ ostree_kernel_args_to_strv (OstreeKernelArgs *kargs) } g_ptr_array_add (strv, NULL); - return (char**)g_ptr_array_free (strv, FALSE); + return (char **)g_ptr_array_free (strv, FALSE); } /** @@ -787,7 +762,7 @@ ostree_kernel_args_to_string (OstreeKernelArgs *kargs) * corresponding to the @key in @kargs hash table. Note that the application * will be terminated if the @key is found but the value array is empty * - * Returns: NULL if @key is not found in the @kargs hash table, + * Returns: (nullable): %NULL if @key is not found in the @kargs hash table, * otherwise returns last element of value array corresponding to @key * * Since: 2019.3 @@ -801,6 +776,68 @@ ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key) return NULL; g_assert (entries->len > 0); - const OstreeKernelArgsEntry *e = entries->pdata[entries->len-1]; + const OstreeKernelArgsEntry *e = entries->pdata[entries->len - 1]; return _ostree_kernel_args_entry_get_value (e); } + +/** + * ostree_kernel_args_append_if_missing: + * @kargs: a OstreeKernelArgs instance + * @arg: key or key/value pair to be added + * + * Appends @arg which is in the form of key=value pair to the hash table kargs->table + * (appends to the value list if key is not in the hash table) + * and appends key to kargs->order if it is not in the hash table. + * + * Since: 2022.5 + **/ +void +ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs, const char *arg) +{ + // Don't insert a duplicate key. + if (ostree_kernel_args_contains (kargs, arg)) + return; + + ostree_kernel_args_append (kargs, arg); +} + +/** + * ostree_kernel_args_contains: + * @kargs: a OstreeKernelArgs instance + * @arg: key or key/value pair to check + * + * Search for @arg which is in the form of key=value pair at the hash table kargs->table + * and returns true if finds it. + * + *Returns: %TRUE if @arg is contained in @kargs, %FALSE otherwise. + * + * Since: 2022.7 + **/ +gboolean +ostree_kernel_args_contains (OstreeKernelArgs *kargs, const char *arg) +{ + g_autofree char *key = g_strdup (arg); + split_keyeq (key); + + return g_hash_table_contains (kargs->table, key); +} + +/** + * ostree_kernel_args_delete_if_present: + * @kargs: a OstreeKernelArgs instance + * @arg: key or key/value pair to be deleted + * @error: an GError instance + * + * Deletes @arg which is in the form of key=value pair from the hash table kargs->table. + * + * Returns: %TRUE on success, %FALSE on failure + * + * Since: 2022.7 + **/ +gboolean +ostree_kernel_args_delete_if_present (OstreeKernelArgs *kargs, const char *arg, GError **error) +{ + if (ostree_kernel_args_contains (kargs, arg)) + return ostree_kernel_args_delete (kargs, arg, error); + return TRUE; +} diff --git a/src/libostree/ostree-kernel-args.h b/src/libostree/ostree-kernel-args.h index dde0312..b39dafd 100644 --- a/src/libostree/ostree-kernel-args.h +++ b/src/libostree/ostree-kernel-args.h @@ -17,47 +17,14 @@ #pragma once +#include "ostree-types.h" #include -#include #include -#include "ostree-types.h" +#include G_BEGIN_DECLS typedef struct _OstreeKernelArgs OstreeKernelArgs; -typedef struct _OstreeKernelArgsEntry OstreeKernelArgsEntry; - -GHashTable *_ostree_kernel_arg_get_kargs_table (OstreeKernelArgs *kargs); - -GPtrArray *_ostree_kernel_arg_get_key_array (OstreeKernelArgs *kargs); - -char * -_ostree_kernel_args_entry_get_key (const OstreeKernelArgsEntry *e); - -char * -_ostree_kernel_args_entry_get_value (const OstreeKernelArgsEntry *e); - -void -_ostree_kernel_args_entry_set_key (OstreeKernelArgsEntry *e, - char *key); - -void -_ostree_kernel_args_entry_set_value (OstreeKernelArgsEntry *e, - char *value); - -char * -_ostree_kernel_args_get_key_index (const OstreeKernelArgs *kargs, - int i); - -char * -_ostree_kernel_args_get_value_index (const OstreeKernelArgs *kargs, - int i); - -OstreeKernelArgsEntry * -_ostree_kernel_args_entry_new (void); - -void -_ostree_kernel_args_entry_value_free (OstreeKernelArgsEntry *e); _OSTREE_PUBLIC void ostree_kernel_args_free (OstreeKernelArgs *kargs); @@ -69,57 +36,43 @@ _OSTREE_PUBLIC void ostree_kernel_args_cleanup (void *loc); _OSTREE_PUBLIC -void ostree_kernel_args_replace_take (OstreeKernelArgs *kargs, - char *arg); +void ostree_kernel_args_replace_take (OstreeKernelArgs *kargs, char *arg); _OSTREE_PUBLIC -void ostree_kernel_args_replace (OstreeKernelArgs *kargs, - const char *arg); +void ostree_kernel_args_replace (OstreeKernelArgs *kargs, const char *arg); _OSTREE_PUBLIC -void ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs, - char **argv); +void ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs, char **argv); _OSTREE_PUBLIC -void ostree_kernel_args_append (OstreeKernelArgs *kargs, - const char *arg); +void ostree_kernel_args_append (OstreeKernelArgs *kargs, const char *arg); _OSTREE_PUBLIC -void ostree_kernel_args_append_argv (OstreeKernelArgs *kargs, - char **argv); +void ostree_kernel_args_append_argv (OstreeKernelArgs *kargs, char **argv); _OSTREE_PUBLIC -void ostree_kernel_args_append_argv_filtered (OstreeKernelArgs *kargs, - char **argv, +void ostree_kernel_args_append_argv_filtered (OstreeKernelArgs *kargs, char **argv, char **prefixes); _OSTREE_PUBLIC -gboolean ostree_kernel_args_new_replace (OstreeKernelArgs *kargs, - const char *arg, - GError **error); +gboolean ostree_kernel_args_new_replace (OstreeKernelArgs *kargs, const char *arg, GError **error); _OSTREE_PUBLIC -gboolean ostree_kernel_args_delete (OstreeKernelArgs *kargs, - const char *arg, - GError **error); +gboolean ostree_kernel_args_delete (OstreeKernelArgs *kargs, const char *arg, GError **error); _OSTREE_PUBLIC -gboolean ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs, - const char *key, - GError **error); +gboolean ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs, const char *key, + GError **error); _OSTREE_PUBLIC -gboolean ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs, - GCancellable *cancellable, - GError **error); +gboolean ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -void ostree_kernel_args_parse_append (OstreeKernelArgs *kargs, - const char *options); +void ostree_kernel_args_parse_append (OstreeKernelArgs *kargs, const char *options); _OSTREE_PUBLIC -const char *ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, - const char *key); +const char *ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key); _OSTREE_PUBLIC OstreeKernelArgs *ostree_kernel_args_from_string (const char *options); @@ -130,4 +83,13 @@ char **ostree_kernel_args_to_strv (OstreeKernelArgs *kargs); _OSTREE_PUBLIC char *ostree_kernel_args_to_string (OstreeKernelArgs *kargs); +_OSTREE_PUBLIC +void ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs, const char *arg); + +_OSTREE_PUBLIC +gboolean ostree_kernel_args_contains (OstreeKernelArgs *kargs, const char *arg); + +_OSTREE_PUBLIC +gboolean ostree_kernel_args_delete_if_present (OstreeKernelArgs *kargs, const char *arg, + GError **error); G_END_DECLS diff --git a/src/libostree/ostree-libarchive-input-stream.c b/src/libostree/ostree-libarchive-input-stream.c index 3c313c1..b1c9042 100644 --- a/src/libostree/ostree-libarchive-input-stream.c +++ b/src/libostree/ostree-libarchive-input-stream.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2011 Colin Walters * Copyright (C) 2022 Igalia S.L. * @@ -20,38 +20,32 @@ #include "config.h" - +#include "ostree-libarchive-input-stream.h" #include #include -#include "ostree-libarchive-input-stream.h" -enum { +enum +{ PROP_0, PROP_ARCHIVE }; -struct _OstreeLibarchiveInputStreamPrivate { +struct _OstreeLibarchiveInputStreamPrivate +{ struct archive *archive; }; -G_DEFINE_TYPE_WITH_PRIVATE (OstreeLibarchiveInputStream, _ostree_libarchive_input_stream, G_TYPE_INPUT_STREAM) - -static void ostree_libarchive_input_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void ostree_libarchive_input_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static gssize ostree_libarchive_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error); -static gboolean ostree_libarchive_input_stream_close (GInputStream *stream, - GCancellable *cancellable, - GError **error); +G_DEFINE_TYPE_WITH_PRIVATE (OstreeLibarchiveInputStream, _ostree_libarchive_input_stream, + G_TYPE_INPUT_STREAM) + +static void ostree_libarchive_input_stream_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void ostree_libarchive_input_stream_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); +static gssize ostree_libarchive_input_stream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error); +static gboolean ostree_libarchive_input_stream_close (GInputStream *stream, + GCancellable *cancellable, GError **error); static void ostree_libarchive_input_stream_finalize (GObject *object) @@ -77,24 +71,18 @@ _ostree_libarchive_input_stream_class_init (OstreeLibarchiveInputStreamClass *kl * * The archive that the stream reads from. */ - g_object_class_install_property (gobject_class, - PROP_ARCHIVE, - g_param_spec_pointer ("archive", - "", "", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - + g_object_class_install_property ( + gobject_class, PROP_ARCHIVE, + g_param_spec_pointer ("archive", "", "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } static void -ostree_libarchive_input_stream_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +ostree_libarchive_input_stream_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeLibarchiveInputStream *self; - + self = OSTREE_LIBARCHIVE_INPUT_STREAM (object); switch (prop_id) @@ -109,10 +97,8 @@ ostree_libarchive_input_stream_set_property (GObject *object, } static void -ostree_libarchive_input_stream_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +ostree_libarchive_input_stream_get_property (GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec) { OstreeLibarchiveInputStream *self; @@ -139,19 +125,14 @@ _ostree_libarchive_input_stream_new (struct archive *a) { OstreeLibarchiveInputStream *stream; - stream = g_object_new (OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, - "archive", a, - NULL); + stream = g_object_new (OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, "archive", a, NULL); return G_INPUT_STREAM (stream); } static gssize -ostree_libarchive_input_stream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error) +ostree_libarchive_input_stream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error) { OstreeLibarchiveInputStream *self; gssize res = -1; @@ -164,17 +145,16 @@ ostree_libarchive_input_stream_read (GInputStream *stream, res = archive_read_data (self->priv->archive, buffer, count); if (res < 0) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "%s", archive_error_string (self->priv->archive)); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", + archive_error_string (self->priv->archive)); } return res; } static gboolean -ostree_libarchive_input_stream_close (GInputStream *stream, - GCancellable *cancellable, - GError **error) +ostree_libarchive_input_stream_close (GInputStream *stream, GCancellable *cancellable, + GError **error) { return TRUE; } diff --git a/src/libostree/ostree-libarchive-input-stream.h b/src/libostree/ostree-libarchive-input-stream.h index a71a6d5..8ab2203 100644 --- a/src/libostree/ostree-libarchive-input-stream.h +++ b/src/libostree/ostree-libarchive-input-stream.h @@ -21,21 +21,29 @@ #pragma once -#include #include "ostree-libarchive-private.h" +#include G_BEGIN_DECLS -#define OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM (_ostree_libarchive_input_stream_get_type ()) -#define OSTREE_LIBARCHIVE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, OstreeLibarchiveInputStream)) -#define OSTREE_LIBARCHIVE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, OstreeLibarchiveInputStreamClass)) -#define OSTREE_IS_LIBARCHIVE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM)) -#define OSTREE_IS_LIBARCHIVE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM)) -#define OSTREE_LIBARCHIVE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, OstreeLibarchiveInputStreamClass)) +#define OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM (_ostree_libarchive_input_stream_get_type ()) +#define OSTREE_LIBARCHIVE_INPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, \ + OstreeLibarchiveInputStream)) +#define OSTREE_LIBARCHIVE_INPUT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, \ + OstreeLibarchiveInputStreamClass)) +#define OSTREE_IS_LIBARCHIVE_INPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM)) +#define OSTREE_IS_LIBARCHIVE_INPUT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM)) +#define OSTREE_LIBARCHIVE_INPUT_STREAM_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_LIBARCHIVE_INPUT_STREAM, \ + OstreeLibarchiveInputStreamClass)) -typedef struct _OstreeLibarchiveInputStream OstreeLibarchiveInputStream; -typedef struct _OstreeLibarchiveInputStreamClass OstreeLibarchiveInputStreamClass; -typedef struct _OstreeLibarchiveInputStreamPrivate OstreeLibarchiveInputStreamPrivate; +typedef struct _OstreeLibarchiveInputStream OstreeLibarchiveInputStream; +typedef struct _OstreeLibarchiveInputStreamClass OstreeLibarchiveInputStreamClass; +typedef struct _OstreeLibarchiveInputStreamPrivate OstreeLibarchiveInputStreamPrivate; struct _OstreeLibarchiveInputStream { @@ -58,8 +66,8 @@ struct _OstreeLibarchiveInputStreamClass void (*_g_reserved5) (void); }; -GType _ostree_libarchive_input_stream_get_type (void) G_GNUC_CONST; +GType _ostree_libarchive_input_stream_get_type (void) G_GNUC_CONST; -GInputStream * _ostree_libarchive_input_stream_new (struct archive *a); +GInputStream *_ostree_libarchive_input_stream_new (struct archive *a); G_END_DECLS diff --git a/src/libostree/ostree-libarchive-private.h b/src/libostree/ostree-libarchive-private.h index 6e6dadd..02cf6d5 100644 --- a/src/libostree/ostree-libarchive-private.h +++ b/src/libostree/ostree-libarchive-private.h @@ -26,8 +26,8 @@ #include "config.h" -#include #include "otutil.h" +#include #ifdef HAVE_LIBARCHIVE #include #include @@ -37,9 +37,11 @@ G_BEGIN_DECLS #ifdef HAVE_LIBARCHIVE typedef struct archive OtAutoArchiveWrite; -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveWrite, archive_write_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OtAutoArchiveWrite, archive_write_free) +typedef struct archive_entry OtArchiveEntry; +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OtArchiveEntry, archive_entry_free) typedef struct archive OtAutoArchiveRead; -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveRead, archive_read_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OtAutoArchiveRead, archive_read_free) static inline OtAutoArchiveRead * ot_archive_read_new (void) @@ -59,12 +61,12 @@ ot_archive_read_new (void) static inline OtAutoArchiveRead * ot_open_archive_read (const char *path, GError **error) { - g_autoptr(OtAutoArchiveRead) a = ot_archive_read_new (); + g_autoptr (OtAutoArchiveRead) a = ot_archive_read_new (); if (archive_read_open_filename (a, path, 8192) != ARCHIVE_OK) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "archive_read_open_filename: %s", archive_error_string (a)); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "archive_read_open_filename: %s", + archive_error_string (a)); return NULL; } @@ -74,12 +76,12 @@ ot_open_archive_read (const char *path, GError **error) static inline OtAutoArchiveRead * ot_open_archive_read_fd (int fd, GError **error) { - g_autoptr(OtAutoArchiveRead) a = ot_archive_read_new (); + g_autoptr (OtAutoArchiveRead) a = ot_archive_read_new (); if (archive_read_open_fd (a, fd, 8192) != ARCHIVE_OK) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "archive_read_open_fd: %s", archive_error_string (a)); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "archive_read_open_fd: %s", + archive_error_string (a)); return NULL; } diff --git a/src/libostree/ostree-linuxfsutil.c b/src/libostree/ostree-linuxfsutil.c index 97f9360..bebd524 100644 --- a/src/libostree/ostree-linuxfsutil.c +++ b/src/libostree/ostree-linuxfsutil.c @@ -24,9 +24,11 @@ #include #include +// This should be the only file including linux/fs.h; see +// https://sourceware.org/glibc/wiki/Release/2.36#Usage_of_.3Clinux.2Fmount.h.3E_and_.3Csys.2Fmount.h.3E +// https://github.com/ostreedev/ostree/issues/2685 #include - -#include "otutil.h" +#include /** * _ostree_linuxfs_fd_alter_immutable_flag: @@ -43,10 +45,8 @@ * silently do nothing. */ gboolean -_ostree_linuxfs_fd_alter_immutable_flag (int fd, - gboolean new_immutable_state, - GCancellable *cancellable, - GError **error) +_ostree_linuxfs_fd_alter_immutable_flag (int fd, gboolean new_immutable_state, + GCancellable *cancellable, GError **error) { static gint no_alter_immutable = 0; @@ -68,7 +68,7 @@ _ostree_linuxfs_fd_alter_immutable_flag (int fd, { gboolean prev_immutable_state = (flags & EXT2_IMMUTABLE_FL) > 0; if (prev_immutable_state == new_immutable_state) - return TRUE; /* Nothing to do */ + return TRUE; /* Nothing to do */ if (new_immutable_state) flags |= EXT2_IMMUTABLE_FL; @@ -88,3 +88,21 @@ _ostree_linuxfs_fd_alter_immutable_flag (int fd, return TRUE; } + +/* Wrapper for FIFREEZE ioctl. + * This is split into a separate wrapped API for + * reasons around conflicts between glibc and linux/fs.h + * includes; see above. + */ +int +_ostree_linuxfs_filesystem_freeze (int fd) +{ + return TEMP_FAILURE_RETRY (ioctl (fd, FIFREEZE, 0)); +} + +/* Wrapper for FITHAW ioctl. See above. */ +int +_ostree_linuxfs_filesystem_thaw (int fd) +{ + return TEMP_FAILURE_RETRY (ioctl (fd, FITHAW, 0)); +} diff --git a/src/libostree/ostree-linuxfsutil.h b/src/libostree/ostree-linuxfsutil.h index 0654b6f..e0e07bc 100644 --- a/src/libostree/ostree-linuxfsutil.h +++ b/src/libostree/ostree-linuxfsutil.h @@ -23,10 +23,10 @@ G_BEGIN_DECLS -gboolean -_ostree_linuxfs_fd_alter_immutable_flag (int fd, - gboolean new_immutable_state, - GCancellable *cancellable, - GError **error); +gboolean _ostree_linuxfs_fd_alter_immutable_flag (int fd, gboolean new_immutable_state, + GCancellable *cancellable, GError **error); + +int _ostree_linuxfs_filesystem_freeze (int fd); +int _ostree_linuxfs_filesystem_thaw (int fd); G_END_DECLS diff --git a/src/libostree/ostree-lzma-common.c b/src/libostree/ostree-lzma-common.c index d4bc71b..40f6424 100644 --- a/src/libostree/ostree-lzma-common.c +++ b/src/libostree/ostree-lzma-common.c @@ -26,8 +26,7 @@ #include GConverterResult -_ostree_lzma_return (lzma_ret res, - GError **error) +_ostree_lzma_return (lzma_ret res, GError **error) { switch (res) { @@ -36,40 +35,32 @@ _ostree_lzma_return (lzma_ret res, case LZMA_STREAM_END: return G_CONVERTER_FINISHED; case LZMA_NO_CHECK: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Stream is corrupt"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Stream is corrupt"); return G_CONVERTER_ERROR; case LZMA_UNSUPPORTED_CHECK: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Cannot calculate integrity check"); + "Cannot calculate integrity check"); return G_CONVERTER_ERROR; case LZMA_MEM_ERROR: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Out of memory"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Out of memory"); return G_CONVERTER_ERROR; case LZMA_MEMLIMIT_ERROR: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Exceeded memory limit"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Exceeded memory limit"); return G_CONVERTER_ERROR; case LZMA_FORMAT_ERROR: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "File format not recognized"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "File format not recognized"); return G_CONVERTER_ERROR; case LZMA_OPTIONS_ERROR: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid or unsupported options"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid or unsupported options"); return G_CONVERTER_ERROR; case LZMA_DATA_ERROR: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Data is corrupt"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Data is corrupt"); return G_CONVERTER_ERROR; case LZMA_BUF_ERROR: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, - "Input buffer too small"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, "Input buffer too small"); return G_CONVERTER_ERROR; default: - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unrecognized LZMA error"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unrecognized LZMA error"); return G_CONVERTER_ERROR; } } diff --git a/src/libostree/ostree-lzma-compressor.c b/src/libostree/ostree-lzma-compressor.c index c60e6b7..1f95cd8 100644 --- a/src/libostree/ostree-lzma-compressor.c +++ b/src/libostree/ostree-lzma-compressor.c @@ -20,14 +20,15 @@ #include "config.h" -#include "ostree-lzma-compressor.h" #include "ostree-lzma-common.h" +#include "ostree-lzma-compressor.h" #include #include #include -enum { +enum +{ PROP_0, PROP_PARAMS }; @@ -40,7 +41,7 @@ enum { * LZMA. */ -static void _ostree_lzma_compressor_iface_init (GConverterIface *iface); +static void _ostree_lzma_compressor_iface_init (GConverterIface *iface); /** * OstreeLzmaCompressor: @@ -56,10 +57,9 @@ struct _OstreeLzmaCompressor gboolean initialized; }; -G_DEFINE_TYPE_WITH_CODE (OstreeLzmaCompressor, _ostree_lzma_compressor, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, - _ostree_lzma_compressor_iface_init)) +G_DEFINE_TYPE_WITH_CODE (OstreeLzmaCompressor, _ostree_lzma_compressor, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + _ostree_lzma_compressor_iface_init)) static void _ostree_lzma_compressor_finalize (GObject *object) @@ -73,10 +73,8 @@ _ostree_lzma_compressor_finalize (GObject *object) } static void -_ostree_lzma_compressor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +_ostree_lzma_compressor_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeLzmaCompressor *self = OSTREE_LZMA_COMPRESSOR (object); @@ -90,14 +88,11 @@ _ostree_lzma_compressor_set_property (GObject *object, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } - } static void -_ostree_lzma_compressor_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +_ostree_lzma_compressor_get_property (GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec) { OstreeLzmaCompressor *self = OSTREE_LZMA_COMPRESSOR (object); @@ -129,21 +124,16 @@ _ostree_lzma_compressor_class_init (OstreeLzmaCompressorClass *klass) gobject_class->get_property = _ostree_lzma_compressor_get_property; gobject_class->set_property = _ostree_lzma_compressor_set_property; - g_object_class_install_property (gobject_class, - PROP_PARAMS, - g_param_spec_variant ("params", "", "", - G_VARIANT_TYPE ("a{sv}"), - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property ( + gobject_class, PROP_PARAMS, + g_param_spec_variant ("params", "", "", G_VARIANT_TYPE ("a{sv}"), NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } OstreeLzmaCompressor * _ostree_lzma_compressor_new (GVariant *params) { - return g_object_new (OSTREE_TYPE_LZMA_COMPRESSOR, - "params", params, - NULL); + return g_object_new (OSTREE_TYPE_LZMA_COMPRESSOR, "params", params, NULL); } static void @@ -161,24 +151,17 @@ _ostree_lzma_compressor_reset (GConverter *converter) } static GConverterResult -_ostree_lzma_compressor_convert (GConverter *converter, - const void *inbuf, - gsize inbuf_size, - void *outbuf, - gsize outbuf_size, - GConverterFlags flags, - gsize *bytes_read, - gsize *bytes_written, - GError **error) +_ostree_lzma_compressor_convert (GConverter *converter, const void *inbuf, gsize inbuf_size, + void *outbuf, gsize outbuf_size, GConverterFlags flags, + gsize *bytes_read, gsize *bytes_written, GError **error) { OstreeLzmaCompressor *self = OSTREE_LZMA_COMPRESSOR (converter); int res; - lzma_action action; + lzma_action action; if (inbuf_size != 0 && outbuf_size == 0) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, - "Output buffer too small"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, "Output buffer too small"); return G_CONVERTER_ERROR; } @@ -186,7 +169,7 @@ _ostree_lzma_compressor_convert (GConverter *converter, { res = lzma_easy_encoder (&self->lstream, 8, LZMA_CHECK_CRC64); if (res != LZMA_OK) - goto out; + return _ostree_lzma_return (res, error); self->initialized = TRUE; } @@ -204,12 +187,11 @@ _ostree_lzma_compressor_convert (GConverter *converter, res = lzma_code (&self->lstream, action); if (res != LZMA_OK && res != LZMA_STREAM_END) - goto out; + return _ostree_lzma_return (res, error); *bytes_read = inbuf_size - self->lstream.avail_in; *bytes_written = outbuf_size - self->lstream.avail_out; - out: return _ostree_lzma_return (res, error); } diff --git a/src/libostree/ostree-lzma-compressor.h b/src/libostree/ostree-lzma-compressor.h index 5f3da18..570bc33 100644 --- a/src/libostree/ostree-lzma-compressor.h +++ b/src/libostree/ostree-lzma-compressor.h @@ -23,22 +23,26 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_LZMA_COMPRESSOR (_ostree_lzma_compressor_get_type ()) -#define OSTREE_LZMA_COMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_LZMA_COMPRESSOR, OstreeLzmaCompressor)) -#define OSTREE_LZMA_COMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_LZMA_COMPRESSOR, OstreeLzmaCompressorClass)) -#define OSTREE_IS_LZMA_COMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_LZMA_COMPRESSOR)) -#define OSTREE_IS_LZMA_COMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_LZMA_COMPRESSOR)) -#define OSTREE_LZMA_COMPRESSOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_LZMA_COMPRESSOR, OstreeLzmaCompressorClass)) - -typedef struct _OstreeLzmaCompressorClass OstreeLzmaCompressorClass; -typedef struct _OstreeLzmaCompressor OstreeLzmaCompressor; +#define OSTREE_TYPE_LZMA_COMPRESSOR (_ostree_lzma_compressor_get_type ()) +#define OSTREE_LZMA_COMPRESSOR(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_LZMA_COMPRESSOR, OstreeLzmaCompressor)) +#define OSTREE_LZMA_COMPRESSOR_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_LZMA_COMPRESSOR, OstreeLzmaCompressorClass)) +#define OSTREE_IS_LZMA_COMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_LZMA_COMPRESSOR)) +#define OSTREE_IS_LZMA_COMPRESSOR_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_LZMA_COMPRESSOR)) +#define OSTREE_LZMA_COMPRESSOR_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_LZMA_COMPRESSOR, OstreeLzmaCompressorClass)) + +typedef struct _OstreeLzmaCompressorClass OstreeLzmaCompressorClass; +typedef struct _OstreeLzmaCompressor OstreeLzmaCompressor; struct _OstreeLzmaCompressorClass { GObjectClass parent_class; }; -GType _ostree_lzma_compressor_get_type (void) G_GNUC_CONST; +GType _ostree_lzma_compressor_get_type (void) G_GNUC_CONST; OstreeLzmaCompressor *_ostree_lzma_compressor_new (GVariant *params); diff --git a/src/libostree/ostree-lzma-decompressor.c b/src/libostree/ostree-lzma-decompressor.c index 029159e..2ac48a3 100644 --- a/src/libostree/ostree-lzma-decompressor.c +++ b/src/libostree/ostree-lzma-decompressor.c @@ -19,14 +19,15 @@ #include "config.h" -#include "ostree-lzma-decompressor.h" #include "ostree-lzma-common.h" +#include "ostree-lzma-decompressor.h" #include #include #include -enum { +enum +{ PROP_0, }; @@ -38,7 +39,7 @@ enum { * LZMA. */ -static void _ostree_lzma_decompressor_iface_init (GConverterIface *iface); +static void _ostree_lzma_decompressor_iface_init (GConverterIface *iface); struct _OstreeLzmaDecompressor { @@ -48,10 +49,9 @@ struct _OstreeLzmaDecompressor gboolean initialized; }; -G_DEFINE_TYPE_WITH_CODE (OstreeLzmaDecompressor, _ostree_lzma_decompressor, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, - _ostree_lzma_decompressor_iface_init)) +G_DEFINE_TYPE_WITH_CODE (OstreeLzmaDecompressor, _ostree_lzma_decompressor, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + _ostree_lzma_decompressor_iface_init)) static void _ostree_lzma_decompressor_finalize (GObject *object) @@ -100,23 +100,16 @@ _ostree_lzma_decompressor_reset (GConverter *converter) } static GConverterResult -_ostree_lzma_decompressor_convert (GConverter *converter, - const void *inbuf, - gsize inbuf_size, - void *outbuf, - gsize outbuf_size, - GConverterFlags flags, - gsize *bytes_read, - gsize *bytes_written, - GError **error) +_ostree_lzma_decompressor_convert (GConverter *converter, const void *inbuf, gsize inbuf_size, + void *outbuf, gsize outbuf_size, GConverterFlags flags, + gsize *bytes_read, gsize *bytes_written, GError **error) { OstreeLzmaDecompressor *self = OSTREE_LZMA_DECOMPRESSOR (converter); int res; if (inbuf_size != 0 && outbuf_size == 0) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, - "Output buffer too small"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, "Output buffer too small"); return G_CONVERTER_ERROR; } @@ -141,7 +134,7 @@ _ostree_lzma_decompressor_convert (GConverter *converter, *bytes_read = inbuf_size - self->lstream.avail_in; *bytes_written = outbuf_size - self->lstream.avail_out; - out: +out: return _ostree_lzma_return (res, error); } diff --git a/src/libostree/ostree-lzma-decompressor.h b/src/libostree/ostree-lzma-decompressor.h index 231f214..a60745f 100644 --- a/src/libostree/ostree-lzma-decompressor.h +++ b/src/libostree/ostree-lzma-decompressor.h @@ -23,15 +23,20 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_LZMA_DECOMPRESSOR (_ostree_lzma_decompressor_get_type ()) -#define OSTREE_LZMA_DECOMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_LZMA_DECOMPRESSOR, OstreeLzmaDecompressor)) -#define OSTREE_LZMA_DECOMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_LZMA_DECOMPRESSOR, OstreeLzmaDecompressorClass)) -#define OSTREE_IS_LZMA_DECOMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_LZMA_DECOMPRESSOR)) -#define OSTREE_IS_LZMA_DECOMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_LZMA_DECOMPRESSOR)) -#define OSTREE_LZMA_DECOMPRESSOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_LZMA_DECOMPRESSOR, OstreeLzmaDecompressorClass)) - -typedef struct _OstreeLzmaDecompressorClass OstreeLzmaDecompressorClass; -typedef struct _OstreeLzmaDecompressor OstreeLzmaDecompressor; +#define OSTREE_TYPE_LZMA_DECOMPRESSOR (_ostree_lzma_decompressor_get_type ()) +#define OSTREE_LZMA_DECOMPRESSOR(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_LZMA_DECOMPRESSOR, OstreeLzmaDecompressor)) +#define OSTREE_LZMA_DECOMPRESSOR_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_LZMA_DECOMPRESSOR, OstreeLzmaDecompressorClass)) +#define OSTREE_IS_LZMA_DECOMPRESSOR(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_LZMA_DECOMPRESSOR)) +#define OSTREE_IS_LZMA_DECOMPRESSOR_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_LZMA_DECOMPRESSOR)) +#define OSTREE_LZMA_DECOMPRESSOR_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_LZMA_DECOMPRESSOR, OstreeLzmaDecompressorClass)) + +typedef struct _OstreeLzmaDecompressorClass OstreeLzmaDecompressorClass; +typedef struct _OstreeLzmaDecompressor OstreeLzmaDecompressor; struct _OstreeLzmaDecompressorClass { @@ -39,7 +44,7 @@ struct _OstreeLzmaDecompressorClass }; GLIB_AVAILABLE_IN_ALL -GType _ostree_lzma_decompressor_get_type (void) G_GNUC_CONST; +GType _ostree_lzma_decompressor_get_type (void) G_GNUC_CONST; GLIB_AVAILABLE_IN_ALL OstreeLzmaDecompressor *_ostree_lzma_decompressor_new (void); diff --git a/src/libostree/ostree-metalink.c b/src/libostree/ostree-metalink.c index 7178f34..449018e 100644 --- a/src/libostree/ostree-metalink.c +++ b/src/libostree/ostree-metalink.c @@ -19,13 +19,14 @@ #include "config.h" -#include "ostree-metalink.h" #include "ostree-fetcher-util.h" +#include "ostree-metalink.h" #include #include "otutil.h" -typedef enum { +typedef enum +{ OSTREE_METALINK_STATE_INITIAL, OSTREE_METALINK_STATE_METALINK, OSTREE_METALINK_STATE_FILES, @@ -62,7 +63,7 @@ typedef struct guint passthrough_depth; OstreeMetalinkState passthrough_previous; - + guint found_a_file_element : 1; guint found_our_file_element : 1; guint verification_known : 1; @@ -83,8 +84,7 @@ typedef struct } OstreeMetalinkRequest; static void -state_transition (OstreeMetalinkRequest *self, - OstreeMetalinkState new_state) +state_transition (OstreeMetalinkRequest *self, OstreeMetalinkState new_state) { g_assert (self->state != new_state); @@ -95,21 +95,16 @@ state_transition (OstreeMetalinkRequest *self, } static void -unknown_element (OstreeMetalinkRequest *self, - const char *element_name, - GError **error) +unknown_element (OstreeMetalinkRequest *self, const char *element_name, GError **error) { state_transition (self, OSTREE_METALINK_STATE_PASSTHROUGH); g_assert (self->passthrough_depth == 0); } static void -metalink_parser_start (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) +metalink_parser_start (GMarkupParseContext *context, const gchar *element_name, + const gchar **attribute_names, const gchar **attribute_values, + gpointer user_data, GError **error) { OstreeMetalinkRequest *self = user_data; @@ -139,13 +134,8 @@ metalink_parser_start (GMarkupParseContext *context, { const char *file_name; - if (!g_markup_collect_attributes (element_name, - attribute_names, - attribute_values, - error, - G_MARKUP_COLLECT_STRING, - "name", - &file_name, + if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error, + G_MARKUP_COLLECT_STRING, "name", &file_name, G_MARKUP_COLLECT_INVALID)) goto out; @@ -181,16 +171,11 @@ metalink_parser_start (GMarkupParseContext *context, case OSTREE_METALINK_STATE_VERIFICATION: if (strcmp (element_name, "hash") == 0) { - char *verification_type_str = NULL; + char *verification_type_str = NULL; state_transition (self, OSTREE_METALINK_STATE_HASH); - if (!g_markup_collect_attributes (element_name, - attribute_names, - attribute_values, - error, - G_MARKUP_COLLECT_STRING, - "type", - &verification_type_str, + if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error, + G_MARKUP_COLLECT_STRING, "type", &verification_type_str, G_MARKUP_COLLECT_INVALID)) goto out; @@ -227,23 +212,11 @@ metalink_parser_start (GMarkupParseContext *context, { const char *protocol; - if (!g_markup_collect_attributes (element_name, - attribute_names, - attribute_values, - error, - G_MARKUP_COLLECT_STRING, - "protocol", - &protocol, - G_MARKUP_COLLECT_STRING, - "type", - NULL, - G_MARKUP_COLLECT_STRING, - "location", - NULL, - G_MARKUP_COLLECT_STRING, - "preference", - NULL, - G_MARKUP_COLLECT_INVALID)) + if (!g_markup_collect_attributes ( + element_name, attribute_names, attribute_values, error, G_MARKUP_COLLECT_STRING, + "protocol", &protocol, G_MARKUP_COLLECT_STRING, "type", NULL, + G_MARKUP_COLLECT_STRING, "location", NULL, G_MARKUP_COLLECT_STRING, "preference", + NULL, G_MARKUP_COLLECT_INVALID)) goto out; /* Ignore non-HTTP resources */ @@ -263,15 +236,13 @@ metalink_parser_start (GMarkupParseContext *context, break; } - out: +out: return; } static void -metalink_parser_end (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) +metalink_parser_end (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, + GError **error) { OstreeMetalinkRequest *self = user_data; @@ -309,11 +280,8 @@ metalink_parser_end (GMarkupParseContext *context, } static void -metalink_parser_text (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) +metalink_parser_text (GMarkupParseContext *context, const gchar *text, gsize text_len, + gpointer user_data, GError **error) { OstreeMetalinkRequest *self = user_data; @@ -366,7 +334,6 @@ metalink_parser_text (GMarkupParseContext *context, case OSTREE_METALINK_STATE_PASSTHROUGH: break; } - } static void @@ -397,13 +364,10 @@ _ostree_metalink_init (OstreeMetalink *self) } OstreeMetalink * -_ostree_metalink_new (OstreeFetcher *fetcher, - const char *requested_file, - guint64 max_size, - OstreeFetcherURI *uri, - guint n_network_retries) +_ostree_metalink_new (OstreeFetcher *fetcher, const char *requested_file, guint64 max_size, + OstreeFetcherURI *uri, guint n_network_retries) { - OstreeMetalink *self = (OstreeMetalink*)g_object_new (OSTREE_TYPE_METALINK, NULL); + OstreeMetalink *self = (OstreeMetalink *)g_object_new (OSTREE_TYPE_METALINK, NULL); self->fetcher = g_object_ref (fetcher); self->requested_file = g_strdup (requested_file); @@ -423,31 +387,23 @@ valid_hex_checksum (const char *s, gsize expected_len) } static gboolean -try_one_url (OstreeMetalinkRequest *self, - OstreeFetcherURI *uri, - GBytes **out_data, - GError **error) +try_one_url (OstreeMetalinkRequest *self, OstreeFetcherURI *uri, GBytes **out_data, GError **error) { gboolean ret = FALSE; - g_autoptr(GBytes) bytes = NULL; + g_autoptr (GBytes) bytes = NULL; gssize n_bytes; - if (!_ostree_fetcher_request_uri_to_membuf (self->metalink->fetcher, - uri, 0, - NULL, 0, - self->metalink->n_network_retries, - &bytes, - NULL, NULL, NULL, - self->metalink->max_size, - self->cancellable, - error)) + if (!_ostree_fetcher_request_uri_to_membuf ( + self->metalink->fetcher, uri, 0, NULL, 0, self->metalink->n_network_retries, &bytes, NULL, + NULL, NULL, self->metalink->max_size, self->cancellable, error)) goto out; n_bytes = g_bytes_get_size (bytes); if (n_bytes != self->size) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Expected size is %" G_GUINT64_FORMAT " bytes but content is %" G_GSSIZE_FORMAT " bytes", + "Expected size is %" G_GUINT64_FORMAT " bytes but content is %" G_GSSIZE_FORMAT + " bytes", self->size, n_bytes); goto out; } @@ -461,8 +417,8 @@ try_one_url (OstreeMetalinkRequest *self, if (strcmp (self->verification_sha512, actual) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Expected checksum is %s but actual is %s", - self->verification_sha512, actual); + "Expected checksum is %s but actual is %s", self->verification_sha512, + actual); goto out; } } @@ -475,8 +431,8 @@ try_one_url (OstreeMetalinkRequest *self, if (strcmp (self->verification_sha256, actual) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Expected checksum is %s but actual is %s", - self->verification_sha256, actual); + "Expected checksum is %s but actual is %s", self->verification_sha256, + actual); goto out; } } @@ -484,24 +440,21 @@ try_one_url (OstreeMetalinkRequest *self, ret = TRUE; if (out_data) *out_data = g_steal_pointer (&bytes); - out: +out: return ret; } static gboolean -try_metalink_targets (OstreeMetalinkRequest *self, - OstreeFetcherURI **out_target_uri, - GBytes **out_data, - GError **error) +try_metalink_targets (OstreeMetalinkRequest *self, OstreeFetcherURI **out_target_uri, + GBytes **out_data, GError **error) { gboolean ret = FALSE; OstreeFetcherURI *target_uri = NULL; - g_autoptr(GBytes) ret_data = NULL; + g_autoptr (GBytes) ret_data = NULL; if (!self->found_a_file_element) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No element found"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No element found"); goto out; } @@ -510,8 +463,8 @@ try_metalink_targets (OstreeMetalinkRequest *self, /* XXX Use NOT_FOUND here so we can distinguish not finding the * requested file from other errors. This is a bit of a hack * through; metalinks should have their own error enum. */ - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No found", self->metalink->requested_file); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No found", + self->metalink->requested_file); goto out; } @@ -524,33 +477,29 @@ try_metalink_targets (OstreeMetalinkRequest *self, if (self->verification_sha256 && !valid_hex_checksum (self->verification_sha256, 64)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid hash digest for sha256"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid hash digest for sha256"); goto out; } if (self->verification_sha512 && !valid_hex_checksum (self->verification_sha512, 128)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid hash digest for sha512"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid hash digest for sha512"); goto out; } if (self->urls->len == 0) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No elements found"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No elements found"); goto out; } - for (self->current_url_index = 0; - self->current_url_index < self->urls->len; + for (self->current_url_index = 0; self->current_url_index < self->urls->len; self->current_url_index++) { GError *temp_error = NULL; target_uri = self->urls->pdata[self->current_url_index]; - + if (try_one_url (self, target_uri, &ret_data, &temp_error)) break; else @@ -565,8 +514,8 @@ try_metalink_targets (OstreeMetalinkRequest *self, { g_assert (self->last_metalink_error != NULL); g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Exhausted %u metalink targets, last error: %s", - self->urls->len, self->last_metalink_error); + "Exhausted %u metalink targets, last error: %s", self->urls->len, + self->last_metalink_error); goto out; } @@ -575,38 +524,32 @@ try_metalink_targets (OstreeMetalinkRequest *self, *out_target_uri = _ostree_fetcher_uri_clone (target_uri); if (out_data) *out_data = g_steal_pointer (&ret_data); - out: +out: return ret; } -static const GMarkupParser metalink_parser = { - metalink_parser_start, - metalink_parser_end, - metalink_parser_text, - NULL, - NULL -}; +static const GMarkupParser metalink_parser + = { metalink_parser_start, metalink_parser_end, metalink_parser_text, NULL, NULL }; typedef struct { - OstreeFetcherURI **out_target_uri; - GBytes **out_data; - gboolean success; - GError **error; - GMainLoop *loop; + OstreeFetcherURI **out_target_uri; + GBytes **out_data; + gboolean success; + GError **error; + GMainLoop *loop; } FetchMetalinkSyncData; gboolean -_ostree_metalink_request_sync (OstreeMetalink *self, - OstreeFetcherURI **out_target_uri, - GBytes **out_data, - GCancellable *cancellable, - GError **error) +_ostree_metalink_request_sync (OstreeMetalink *self, OstreeFetcherURI **out_target_uri, + GBytes **out_data, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - OstreeMetalinkRequest request = { 0, }; - g_autoptr(GMainContext) mainctx = NULL; - g_autoptr(GBytes) contents = NULL; + OstreeMetalinkRequest request = { + 0, + }; + g_autoptr (GMainContext) mainctx = NULL; + g_autoptr (GBytes) contents = NULL; gsize len; const guint8 *data; @@ -614,25 +557,24 @@ _ostree_metalink_request_sync (OstreeMetalink *self, g_main_context_push_thread_default (mainctx); request.metalink = g_object_ref (self); - request.urls = g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); - request.parser = g_markup_parse_context_new (&metalink_parser, G_MARKUP_PREFIX_ERROR_POSITION, &request, NULL); - - if (!_ostree_fetcher_request_uri_to_membuf (self->fetcher, self->uri, 0, - NULL, 0, - self->n_network_retries, - &contents, NULL, NULL, NULL, self->max_size, - cancellable, error)) + request.urls = g_ptr_array_new_with_free_func ((GDestroyNotify)_ostree_fetcher_uri_free); + request.parser = g_markup_parse_context_new (&metalink_parser, G_MARKUP_PREFIX_ERROR_POSITION, + &request, NULL); + + if (!_ostree_fetcher_request_uri_to_membuf (self->fetcher, self->uri, 0, NULL, 0, + self->n_network_retries, &contents, NULL, NULL, NULL, + self->max_size, cancellable, error)) goto out; data = g_bytes_get_data (contents, &len); - if (!g_markup_parse_context_parse (request.parser, (const char*)data, len, error)) + if (!g_markup_parse_context_parse (request.parser, (const char *)data, len, error)) goto out; if (!try_metalink_targets (&request, out_target_uri, out_data, error)) goto out; ret = TRUE; - out: +out: if (mainctx) g_main_context_pop_thread_default (mainctx); g_clear_object (&request.metalink); diff --git a/src/libostree/ostree-metalink.h b/src/libostree/ostree-metalink.h index 68400cd..a457515 100644 --- a/src/libostree/ostree-metalink.h +++ b/src/libostree/ostree-metalink.h @@ -25,15 +25,17 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_METALINK (_ostree_metalink_get_type ()) -#define OSTREE_METALINK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_METALINK, OstreeMetalink)) -#define OSTREE_METALINK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_METALINK, OstreeMetalinkClass)) -#define OSTREE_IS_METALINK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_METALINK)) -#define OSTREE_IS_METALINK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_METALINK)) -#define OSTREE_METALINK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_METALINK, OstreeMetalinkClass)) - -typedef struct OstreeMetalinkClass OstreeMetalinkClass; -typedef struct OstreeMetalink OstreeMetalink; +#define OSTREE_TYPE_METALINK (_ostree_metalink_get_type ()) +#define OSTREE_METALINK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_METALINK, OstreeMetalink)) +#define OSTREE_METALINK_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_METALINK, OstreeMetalinkClass)) +#define OSTREE_IS_METALINK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_METALINK)) +#define OSTREE_IS_METALINK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_METALINK)) +#define OSTREE_METALINK_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_METALINK, OstreeMetalinkClass)) + +typedef struct OstreeMetalinkClass OstreeMetalinkClass; +typedef struct OstreeMetalink OstreeMetalink; struct OstreeMetalinkClass { @@ -41,19 +43,15 @@ struct OstreeMetalinkClass }; G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMetalink, g_object_unref) -GType _ostree_metalink_get_type (void) G_GNUC_CONST; +GType _ostree_metalink_get_type (void) G_GNUC_CONST; -OstreeMetalink *_ostree_metalink_new (OstreeFetcher *fetcher, - const char *requested_file, - guint64 max_size, - OstreeFetcherURI *uri, - guint n_network_retries); +OstreeMetalink *_ostree_metalink_new (OstreeFetcher *fetcher, const char *requested_file, + guint64 max_size, OstreeFetcherURI *uri, + guint n_network_retries); -gboolean _ostree_metalink_request_sync (OstreeMetalink *self, - OstreeFetcherURI **out_target_uri, - GBytes **out_data, - GCancellable *cancellable, - GError **error); +gboolean _ostree_metalink_request_sync (OstreeMetalink *self, OstreeFetcherURI **out_target_uri, + GBytes **out_data, GCancellable *cancellable, + GError **error); G_END_DECLS #endif diff --git a/src/libostree/ostree-mutable-tree.c b/src/libostree/ostree-mutable-tree.c index 58dd3c4..3a47de6 100644 --- a/src/libostree/ostree-mutable-tree.c +++ b/src/libostree/ostree-mutable-tree.c @@ -21,8 +21,8 @@ #include "config.h" -#include "otutil.h" #include "ostree.h" +#include "otutil.h" #include "ostree-core-private.h" @@ -38,13 +38,14 @@ * programmatically. */ -typedef enum { - MTREE_STATE_WHOLE, +typedef enum +{ + MTREE_STATE_WHOLE, - /* MTREE_STATE_LAZY allows us to not read files and subdirs from the objects - * on disk until they're actually needed - often they won't be needed at - * all. */ - MTREE_STATE_LAZY + /* MTREE_STATE_LAZY allows us to not read files and subdirs from the objects + * on disk until they're actually needed - often they won't be needed at + * all. */ + MTREE_STATE_LAZY } OstreeMutableTreeState; /** @@ -132,8 +133,7 @@ ostree_mutable_tree_class_init (OstreeMutableTreeClass *klass) * * Ownership of @child is transferred from the caller to @self */ static void -insert_child_mtree (OstreeMutableTree *self, const gchar* name, - OstreeMutableTree *child) +insert_child_mtree (OstreeMutableTree *self, const gchar *name, OstreeMutableTree *child) { g_assert_null (child->parent); g_hash_table_insert (self->subdirs, g_strdup (name), child); @@ -147,7 +147,7 @@ remove_child_mtree (gpointer data) * non-owning reference back to parent. If the parent goes out of scope the * children may still be alive because they're reference counted. This * removes the reference to the parent before it goes stale. */ - OstreeMutableTree *child = (OstreeMutableTree*) data; + OstreeMutableTree *child = (OstreeMutableTree *)data; child->parent = NULL; g_object_unref (child); } @@ -155,30 +155,27 @@ remove_child_mtree (gpointer data) static void ostree_mutable_tree_init (OstreeMutableTree *self) { - self->files = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - self->subdirs = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, remove_child_mtree); + self->files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + self->subdirs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, remove_child_mtree); self->state = MTREE_STATE_WHOLE; } static void invalidate_contents_checksum (OstreeMutableTree *self) { - while (self) { - if (!self->contents_checksum) - break; + while (self) + { + if (!self->contents_checksum) + break; - g_clear_pointer (&self->contents_checksum, g_free); - self = self->parent; - } + g_clear_pointer (&self->contents_checksum, g_free); + self = self->parent; + } } /* Go from state LAZY to state WHOLE by reading the tree from disk */ static gboolean -_ostree_mutable_tree_make_whole (OstreeMutableTree *self, - GCancellable *cancellable, - GError **error) +_ostree_mutable_tree_make_whole (OstreeMutableTree *self, GCancellable *cancellable, GError **error) { if (self->state == MTREE_STATE_WHOLE) return TRUE; @@ -190,13 +187,13 @@ _ostree_mutable_tree_make_whole (OstreeMutableTree *self, g_assert_cmpuint (g_hash_table_size (self->files), ==, 0); g_assert_cmpuint (g_hash_table_size (self->subdirs), ==, 0); - g_autoptr(GVariant) dirtree = NULL; - if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE, - self->contents_checksum, &dirtree, error)) + g_autoptr (GVariant) dirtree = NULL; + if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE, self->contents_checksum, + &dirtree, error)) return FALSE; { - g_autoptr(GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0); + g_autoptr (GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0); GVariantIter viter; g_variant_iter_init (&viter, dir_file_contents); const char *fname; @@ -205,28 +202,28 @@ _ostree_mutable_tree_make_whole (OstreeMutableTree *self, { char tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; _ostree_checksum_inplace_from_bytes_v (contents_csum_v, tmp_checksum); - g_hash_table_insert (self->files, g_strdup (fname), - g_strdup (tmp_checksum)); + g_hash_table_insert (self->files, g_strdup (fname), g_strdup (tmp_checksum)); } } /* Process subdirectories */ { - g_autoptr(GVariant) dir_subdirs = g_variant_get_child_value (dirtree, 1); + g_autoptr (GVariant) dir_subdirs = g_variant_get_child_value (dirtree, 1); const char *dname; GVariant *subdirtree_csum_v = NULL; GVariant *subdirmeta_csum_v = NULL; GVariantIter viter; g_variant_iter_init (&viter, dir_subdirs); - while (g_variant_iter_loop (&viter, "(&s@ay@ay)", &dname, - &subdirtree_csum_v, &subdirmeta_csum_v)) + while ( + g_variant_iter_loop (&viter, "(&s@ay@ay)", &dname, &subdirtree_csum_v, &subdirmeta_csum_v)) { - char subdirtree_checksum[OSTREE_SHA256_STRING_LEN+1]; + char subdirtree_checksum[OSTREE_SHA256_STRING_LEN + 1]; _ostree_checksum_inplace_from_bytes_v (subdirtree_csum_v, subdirtree_checksum); - char subdirmeta_checksum[OSTREE_SHA256_STRING_LEN+1]; + char subdirmeta_checksum[OSTREE_SHA256_STRING_LEN + 1]; _ostree_checksum_inplace_from_bytes_v (subdirmeta_csum_v, subdirmeta_checksum); - insert_child_mtree (self, dname, ostree_mutable_tree_new_from_checksum ( - self->repo, subdirtree_checksum, subdirmeta_checksum)); + insert_child_mtree (self, dname, + ostree_mutable_tree_new_from_checksum (self->repo, subdirtree_checksum, + subdirmeta_checksum)); } } @@ -247,8 +244,7 @@ _assert_ostree_mutable_tree_make_whole (OstreeMutableTree *self) } void -ostree_mutable_tree_set_metadata_checksum (OstreeMutableTree *self, - const char *checksum) +ostree_mutable_tree_set_metadata_checksum (OstreeMutableTree *self, const char *checksum) { if (g_strcmp0 (checksum, self->metadata_checksum) == 0) return; @@ -265,16 +261,15 @@ ostree_mutable_tree_get_metadata_checksum (OstreeMutableTree *self) } void -ostree_mutable_tree_set_contents_checksum (OstreeMutableTree *self, - const char *checksum) +ostree_mutable_tree_set_contents_checksum (OstreeMutableTree *self, const char *checksum) { if (g_strcmp0 (checksum, self->contents_checksum) == 0) return; if (checksum && self->contents_checksum) g_warning ("Setting a contents checksum on an OstreeMutableTree that " - "already has a checksum set. Old checksum %s, new checksum %s", - self->contents_checksum, checksum); + "already has a checksum set. Old checksum %s, new checksum %s", + self->contents_checksum, checksum); _assert_ostree_mutable_tree_make_whole (self); @@ -291,20 +286,14 @@ ostree_mutable_tree_get_contents_checksum (OstreeMutableTree *self) static gboolean set_error_noent (GError **error, const char *path) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No such file or directory: %s", - path); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No such file or directory: %s", path); return FALSE; } gboolean -ostree_mutable_tree_replace_file (OstreeMutableTree *self, - const char *name, - const char *checksum, - GError **error) +ostree_mutable_tree_replace_file (OstreeMutableTree *self, const char *name, const char *checksum, + GError **error) { - g_return_val_if_fail (name != NULL, FALSE); - if (!ot_util_filename_validate (name, error)) return FALSE; @@ -315,9 +304,7 @@ ostree_mutable_tree_replace_file (OstreeMutableTree *self, return glnx_throw (error, "Can't replace directory with file: %s", name); invalidate_contents_checksum (self); - g_hash_table_replace (self->files, - g_strdup (name), - g_strdup (checksum)); + g_hash_table_replace (self->files, g_strdup (name), g_strdup (checksum)); return TRUE; } @@ -333,21 +320,16 @@ ostree_mutable_tree_replace_file (OstreeMutableTree *self, * Since: 2018.9 */ gboolean -ostree_mutable_tree_remove (OstreeMutableTree *self, - const char *name, - gboolean allow_noent, - GError **error) +ostree_mutable_tree_remove (OstreeMutableTree *self, const char *name, gboolean allow_noent, + GError **error) { - g_return_val_if_fail (name != NULL, FALSE); - if (!ot_util_filename_validate (name, error)) return FALSE; if (!_ostree_mutable_tree_make_whole (self, NULL, error)) return FALSE; - if (!g_hash_table_remove (self->files, name) && - !g_hash_table_remove (self->subdirs, name)) + if (!g_hash_table_remove (self->files, name) && !g_hash_table_remove (self->subdirs, name)) { if (allow_noent) return TRUE; /* NB: early return */ @@ -362,20 +344,16 @@ ostree_mutable_tree_remove (OstreeMutableTree *self, * ostree_mutable_tree_ensure_dir: * @self: Tree * @name: Name of subdirectory of self to retrieve/creates - * @out_subdir: (out) (transfer full): the subdirectory + * @out_subdir: (out) (transfer full) (optional): the subdirectory * @error: a #GError * * Returns the subdirectory of self with filename @name, creating an empty one * it if it doesn't exist. */ gboolean -ostree_mutable_tree_ensure_dir (OstreeMutableTree *self, - const char *name, - OstreeMutableTree **out_subdir, - GError **error) +ostree_mutable_tree_ensure_dir (OstreeMutableTree *self, const char *name, + OstreeMutableTree **out_subdir, GError **error) { - g_return_val_if_fail (name != NULL, FALSE); - if (!ot_util_filename_validate (name, error)) return FALSE; @@ -385,8 +363,8 @@ ostree_mutable_tree_ensure_dir (OstreeMutableTree *self, if (g_hash_table_lookup (self->files, name)) return glnx_throw (error, "Can't replace file with directory: %s", name); - g_autoptr(OstreeMutableTree) ret_dir = - ot_gobject_refz (g_hash_table_lookup (self->subdirs, name)); + g_autoptr (OstreeMutableTree) ret_dir + = ot_gobject_refz (g_hash_table_lookup (self->subdirs, name)); if (!ret_dir) { ret_dir = ostree_mutable_tree_new (); @@ -406,20 +384,23 @@ ostree_mutable_tree_ensure_dir (OstreeMutableTree *self, * @out_file_checksum: (out) (transfer full) (nullable) (optional): checksum * @out_subdir: (out) (transfer full) (nullable) (optional): subdirectory * @error: a #GError + * + * Lookup @name and returns @out_file_checksum or @out_subdir depending on its + * file type. + * + * Returns: %TRUE on success and either @out_file_checksum or @out_subdir are + * filled, %FALSE otherwise. */ gboolean -ostree_mutable_tree_lookup (OstreeMutableTree *self, - const char *name, - char **out_file_checksum, - OstreeMutableTree **out_subdir, - GError **error) +ostree_mutable_tree_lookup (OstreeMutableTree *self, const char *name, char **out_file_checksum, + OstreeMutableTree **out_subdir, GError **error) { if (!_ostree_mutable_tree_make_whole (self, NULL, error)) return FALSE; g_autofree char *ret_file_checksum = NULL; - g_autoptr(OstreeMutableTree) ret_subdir = - ot_gobject_refz (g_hash_table_lookup (self->subdirs, name)); + g_autoptr (OstreeMutableTree) ret_subdir + = ot_gobject_refz (g_hash_table_lookup (self->subdirs, name)); if (!ret_subdir) { ret_file_checksum = g_strdup (g_hash_table_lookup (self->files, name)); @@ -439,18 +420,16 @@ ostree_mutable_tree_lookup (OstreeMutableTree *self, * @self: Tree * @split_path: (element-type utf8): File path components * @metadata_checksum: SHA256 checksum for metadata - * @out_parent: (out) (transfer full): The parent tree + * @out_parent: (out) (transfer full) (optional): The parent tree * @error: a #GError * * Create all parent trees necessary for the given @split_path to * exist. */ gboolean -ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self, - GPtrArray *split_path, - const char *metadata_checksum, - OstreeMutableTree **out_parent, - GError **error) +ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self, GPtrArray *split_path, + const char *metadata_checksum, + OstreeMutableTree **out_parent, GError **error) { g_assert (metadata_checksum != NULL); @@ -461,7 +440,7 @@ ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self, ostree_mutable_tree_set_metadata_checksum (self, metadata_checksum); OstreeMutableTree *subdir = self; /* nofree */ - for (guint i = 0; i+1 < split_path->len; i++) + for (guint i = 0; i + 1 < split_path->len; i++) { const char *name = split_path->pdata[i]; if (g_hash_table_lookup (subdir->files, name)) @@ -507,35 +486,34 @@ const char empty_tree_csum[] = "6e340b9cffb37a989ca544e6bb780a2c78901d3fb3373876 * Since: 2018.7 */ gboolean -ostree_mutable_tree_fill_empty_from_dirtree (OstreeMutableTree *self, - OstreeRepo *repo, - const char *contents_checksum, - const char *metadata_checksum) +ostree_mutable_tree_fill_empty_from_dirtree (OstreeMutableTree *self, OstreeRepo *repo, + const char *contents_checksum, + const char *metadata_checksum) { - g_return_val_if_fail (repo, FALSE); - g_return_val_if_fail (contents_checksum, FALSE); - g_return_val_if_fail (metadata_checksum, FALSE); + g_assert (repo); + g_assert (contents_checksum); + g_assert (metadata_checksum); switch (self->state) { case MTREE_STATE_LAZY: { - if (g_strcmp0 (contents_checksum, self->contents_checksum) == 0 || - g_strcmp0 (empty_tree_csum, self->contents_checksum) == 0) + if (g_strcmp0 (contents_checksum, self->contents_checksum) == 0 + || g_strcmp0 (empty_tree_csum, self->contents_checksum) == 0) break; if (g_strcmp0 (empty_tree_csum, contents_checksum) == 0) { /* Adding an empty tree to a full one - stick with the old contents */ - contents_checksum = self->contents_checksum; - break; + g_set_object (&self->repo, repo); + ostree_mutable_tree_set_metadata_checksum (self, metadata_checksum); + return TRUE; } else return FALSE; } case MTREE_STATE_WHOLE: - if (g_hash_table_size (self->files) == 0 && - g_hash_table_size (self->subdirs) == 0) + if (g_hash_table_size (self->files) == 0 && g_hash_table_size (self->subdirs) == 0) break; /* We're not empty - can't convert to a LAZY tree */ return FALSE; @@ -566,13 +544,10 @@ ostree_mutable_tree_fill_empty_from_dirtree (OstreeMutableTree *self, * child will be returned in @out_subdir. */ gboolean -ostree_mutable_tree_walk (OstreeMutableTree *self, - GPtrArray *split_path, - guint start, - OstreeMutableTree **out_subdir, - GError **error) +ostree_mutable_tree_walk (OstreeMutableTree *self, GPtrArray *split_path, guint start, + OstreeMutableTree **out_subdir, GError **error) { - g_return_val_if_fail (start < split_path->len, FALSE); + g_assert_cmpuint (start, <, split_path->len); if (start == split_path->len - 1) { @@ -585,7 +560,7 @@ ostree_mutable_tree_walk (OstreeMutableTree *self, return FALSE; OstreeMutableTree *subdir = g_hash_table_lookup (self->subdirs, split_path->pdata[start]); if (!subdir) - return set_error_noent (error, (char*)split_path->pdata[start]); + return set_error_noent (error, (char *)split_path->pdata[start]); return ostree_mutable_tree_walk (subdir, split_path, start + 1, out_subdir, error); } @@ -630,8 +605,7 @@ ostree_mutable_tree_get_files (OstreeMutableTree *self) * Returns: `TRUE` on success */ gboolean -ostree_mutable_tree_check_error (OstreeMutableTree *self, - GError **error) +ostree_mutable_tree_check_error (OstreeMutableTree *self, GError **error) { if (self->cached_error) { @@ -650,7 +624,7 @@ ostree_mutable_tree_check_error (OstreeMutableTree *self, OstreeMutableTree * ostree_mutable_tree_new (void) { - return (OstreeMutableTree*)g_object_new (OSTREE_TYPE_MUTABLE_TREE, NULL); + return (OstreeMutableTree *)g_object_new (OSTREE_TYPE_MUTABLE_TREE, NULL); } /** @@ -667,11 +641,10 @@ ostree_mutable_tree_new (void) * Since: 2018.7 */ OstreeMutableTree * -ostree_mutable_tree_new_from_checksum (OstreeRepo *repo, - const char *contents_checksum, +ostree_mutable_tree_new_from_checksum (OstreeRepo *repo, const char *contents_checksum, const char *metadata_checksum) { - OstreeMutableTree* out = (OstreeMutableTree*)g_object_new (OSTREE_TYPE_MUTABLE_TREE, NULL); + OstreeMutableTree *out = (OstreeMutableTree *)g_object_new (OSTREE_TYPE_MUTABLE_TREE, NULL); out->state = MTREE_STATE_LAZY; out->repo = g_object_ref (repo); out->contents_checksum = g_strdup (contents_checksum); @@ -691,26 +664,22 @@ ostree_mutable_tree_new_from_checksum (OstreeRepo *repo, * Since: 2021.5 */ OstreeMutableTree * -ostree_mutable_tree_new_from_commit (OstreeRepo *repo, - const char *rev, - GError **error) +ostree_mutable_tree_new_from_commit (OstreeRepo *repo, const char *rev, GError **error) { g_autofree char *commit = NULL; if (!ostree_repo_resolve_rev (repo, rev, FALSE, &commit, error)) return NULL; - g_autoptr(GVariant) commit_v = NULL; + g_autoptr (GVariant) commit_v = NULL; if (!ostree_repo_load_commit (repo, commit, &commit_v, NULL, error)) return NULL; - g_autoptr(GVariant) contents_checksum_v = NULL; - g_autoptr(GVariant) metadata_checksum_v = NULL; + g_autoptr (GVariant) contents_checksum_v = NULL; + g_autoptr (GVariant) metadata_checksum_v = NULL; char contents_checksum[OSTREE_SHA256_STRING_LEN + 1]; char metadata_checksum[OSTREE_SHA256_STRING_LEN + 1]; g_variant_get_child (commit_v, 6, "@ay", &contents_checksum_v); - ostree_checksum_inplace_from_bytes (g_variant_get_data (contents_checksum_v), - contents_checksum); + ostree_checksum_inplace_from_bytes (g_variant_get_data (contents_checksum_v), contents_checksum); g_variant_get_child (commit_v, 7, "@ay", &metadata_checksum_v); - ostree_checksum_inplace_from_bytes (g_variant_get_data (metadata_checksum_v), - metadata_checksum); + ostree_checksum_inplace_from_bytes (g_variant_get_data (metadata_checksum_v), metadata_checksum); return ostree_mutable_tree_new_from_checksum (repo, contents_checksum, metadata_checksum); } diff --git a/src/libostree/ostree-mutable-tree.h b/src/libostree/ostree-mutable-tree.h index 384ff25..923b2cd 100644 --- a/src/libostree/ostree-mutable-tree.h +++ b/src/libostree/ostree-mutable-tree.h @@ -25,18 +25,22 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_MUTABLE_TREE (ostree_mutable_tree_get_type ()) -#define OSTREE_MUTABLE_TREE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_MUTABLE_TREE, OstreeMutableTree)) -#define OSTREE_MUTABLE_TREE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_MUTABLE_TREE, OstreeMutableTreeClass)) -#define OSTREE_IS_MUTABLE_TREE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_MUTABLE_TREE)) -#define OSTREE_IS_MUTABLE_TREE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_MUTABLE_TREE)) -#define OSTREE_MUTABLE_TREE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_MUTABLE_TREE, OstreeMutableTreeClass)) - -typedef struct OstreeMutableTreeClass OstreeMutableTreeClass; - -typedef struct { - gboolean in_files; - GHashTableIter iter; +#define OSTREE_TYPE_MUTABLE_TREE (ostree_mutable_tree_get_type ()) +#define OSTREE_MUTABLE_TREE(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_MUTABLE_TREE, OstreeMutableTree)) +#define OSTREE_MUTABLE_TREE_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_MUTABLE_TREE, OstreeMutableTreeClass)) +#define OSTREE_IS_MUTABLE_TREE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_MUTABLE_TREE)) +#define OSTREE_IS_MUTABLE_TREE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_MUTABLE_TREE)) +#define OSTREE_MUTABLE_TREE_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_MUTABLE_TREE, OstreeMutableTreeClass)) + +typedef struct OstreeMutableTreeClass OstreeMutableTreeClass; + +typedef struct +{ + gboolean in_files; + GHashTableIter iter; } OstreeMutableTreeIter; struct OstreeMutableTreeClass @@ -45,90 +49,69 @@ struct OstreeMutableTreeClass }; _OSTREE_PUBLIC -GType ostree_mutable_tree_get_type (void) G_GNUC_CONST; +GType ostree_mutable_tree_get_type (void) G_GNUC_CONST; _OSTREE_PUBLIC OstreeMutableTree *ostree_mutable_tree_new (void); _OSTREE_PUBLIC -OstreeMutableTree * -ostree_mutable_tree_new_from_commit (OstreeRepo *repo, - const char *rev, - GError **error); +OstreeMutableTree *ostree_mutable_tree_new_from_commit (OstreeRepo *repo, const char *rev, + GError **error); _OSTREE_PUBLIC -OstreeMutableTree * ostree_mutable_tree_new_from_checksum (OstreeRepo *repo, - const char *contents_checksum, - const char *metadata_checksum); +OstreeMutableTree *ostree_mutable_tree_new_from_checksum (OstreeRepo *repo, + const char *contents_checksum, + const char *metadata_checksum); _OSTREE_PUBLIC -void ostree_mutable_tree_set_metadata_checksum (OstreeMutableTree *self, - const char *checksum); +void ostree_mutable_tree_set_metadata_checksum (OstreeMutableTree *self, const char *checksum); _OSTREE_PUBLIC const char *ostree_mutable_tree_get_metadata_checksum (OstreeMutableTree *self); _OSTREE_PUBLIC -void ostree_mutable_tree_set_contents_checksum (OstreeMutableTree *self, - const char *checksum); +void ostree_mutable_tree_set_contents_checksum (OstreeMutableTree *self, const char *checksum); _OSTREE_PUBLIC const char *ostree_mutable_tree_get_contents_checksum (OstreeMutableTree *self); _OSTREE_PUBLIC -gboolean ostree_mutable_tree_replace_file (OstreeMutableTree *self, - const char *name, - const char *checksum, - GError **error); +gboolean ostree_mutable_tree_replace_file (OstreeMutableTree *self, const char *name, + const char *checksum, GError **error); _OSTREE_PUBLIC -gboolean ostree_mutable_tree_remove (OstreeMutableTree *self, - const char *name, - gboolean allow_noent, - GError **error); +gboolean ostree_mutable_tree_remove (OstreeMutableTree *self, const char *name, + gboolean allow_noent, GError **error); _OSTREE_PUBLIC -gboolean ostree_mutable_tree_ensure_dir (OstreeMutableTree *self, - const char *name, - OstreeMutableTree **out_subdir, - GError **error); +gboolean ostree_mutable_tree_ensure_dir (OstreeMutableTree *self, const char *name, + OstreeMutableTree **out_subdir, GError **error); _OSTREE_PUBLIC -gboolean ostree_mutable_tree_lookup (OstreeMutableTree *self, - const char *name, - char **out_file_checksum, - OstreeMutableTree **out_subdir, - GError **error); +gboolean ostree_mutable_tree_lookup (OstreeMutableTree *self, const char *name, + char **out_file_checksum, OstreeMutableTree **out_subdir, + GError **error); _OSTREE_PUBLIC -gboolean -ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self, - GPtrArray *split_path, - const char *metadata_checksum, - OstreeMutableTree **out_parent, - GError **error); +gboolean ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self, GPtrArray *split_path, + const char *metadata_checksum, + OstreeMutableTree **out_parent, GError **error); _OSTREE_PUBLIC -gboolean ostree_mutable_tree_walk (OstreeMutableTree *self, - GPtrArray *split_path, - guint start, - OstreeMutableTree **out_subdir, - GError **error); +gboolean ostree_mutable_tree_walk (OstreeMutableTree *self, GPtrArray *split_path, guint start, + OstreeMutableTree **out_subdir, GError **error); _OSTREE_PUBLIC -gboolean ostree_mutable_tree_fill_empty_from_dirtree (OstreeMutableTree *self, - OstreeRepo *repo, - const char *contents_checksum, - const char *metadata_checksum); +gboolean ostree_mutable_tree_fill_empty_from_dirtree (OstreeMutableTree *self, OstreeRepo *repo, + const char *contents_checksum, + const char *metadata_checksum); _OSTREE_PUBLIC -gboolean -ostree_mutable_tree_check_error (OstreeMutableTree *self, - GError **error); +gboolean ostree_mutable_tree_check_error (OstreeMutableTree *self, GError **error); _OSTREE_PUBLIC -GHashTable * ostree_mutable_tree_get_subdirs (OstreeMutableTree *self); +GHashTable *ostree_mutable_tree_get_subdirs (OstreeMutableTree *self); _OSTREE_PUBLIC -GHashTable * ostree_mutable_tree_get_files (OstreeMutableTree *self); +GHashTable *ostree_mutable_tree_get_files (OstreeMutableTree *self); G_END_DECLS diff --git a/src/libostree/ostree-ref.c b/src/libostree/ostree-ref.c index eb77d97..149c291 100644 --- a/src/libostree/ostree-ref.c +++ b/src/libostree/ostree-ref.c @@ -23,17 +23,17 @@ #include "config.h" #include -#include #include +#include #include #include "ostree-autocleanups.h" -#include "ostree-core.h" #include "ostree-core-private.h" +#include "ostree-core.h" #include "ostree-ref.h" -G_DEFINE_BOXED_TYPE (OstreeCollectionRef, ostree_collection_ref, - ostree_collection_ref_dup, ostree_collection_ref_free) +G_DEFINE_BOXED_TYPE (OstreeCollectionRef, ostree_collection_ref, ostree_collection_ref_dup, + ostree_collection_ref_free) /** * ostree_collection_ref_new: @@ -45,17 +45,16 @@ G_DEFINE_BOXED_TYPE (OstreeCollectionRef, ostree_collection_ref, * refspec; no remote name is included), which can be used for non-P2P * operations. * - * Returns: (transfer full) (nullable): a new #OstreeCollectionRef + * Returns: (transfer full): a new #OstreeCollectionRef * Since: 2018.6 */ OstreeCollectionRef * -ostree_collection_ref_new (const gchar *collection_id, - const gchar *ref_name) +ostree_collection_ref_new (const gchar *collection_id, const gchar *ref_name) { - g_autoptr(OstreeCollectionRef) collection_ref = NULL; + g_autoptr (OstreeCollectionRef) collection_ref = NULL; - g_return_val_if_fail (collection_id == NULL || - ostree_validate_collection_id (collection_id, NULL), NULL); + g_return_val_if_fail ( + collection_id == NULL || ostree_validate_collection_id (collection_id, NULL), NULL); g_return_val_if_fail (ostree_validate_rev (ref_name, NULL), NULL); collection_ref = g_new0 (OstreeCollectionRef, 1); @@ -102,7 +101,7 @@ ostree_collection_ref_free (OstreeCollectionRef *ref) /** * ostree_collection_ref_hash: - * @ref: (not nullable): an #OstreeCollectionRef + * @ref: (not nullable) (type OstreeCollectionRef): an #OstreeCollectionRef * * Hash the given @ref. This function is suitable for use with #GHashTable. * @ref must be non-%NULL. @@ -123,8 +122,8 @@ ostree_collection_ref_hash (gconstpointer ref) /** * ostree_collection_ref_equal: - * @ref1: (not nullable): an #OstreeCollectionRef - * @ref2 : (not nullable): another #OstreeCollectionRef + * @ref1: (not nullable) (type OstreeCollectionRef): an #OstreeCollectionRef + * @ref2 : (not nullable) (type OstreeCollectionRef): another #OstreeCollectionRef * * Compare @ref1 and @ref2 and return %TRUE if they have the same collection ID and * ref name, and %FALSE otherwise. Both @ref1 and @ref2 must be non-%NULL. @@ -133,13 +132,12 @@ ostree_collection_ref_hash (gconstpointer ref) * Since: 2018.6 */ gboolean -ostree_collection_ref_equal (gconstpointer ref1, - gconstpointer ref2) +ostree_collection_ref_equal (gconstpointer ref1, gconstpointer ref2) { const OstreeCollectionRef *_ref1 = ref1, *_ref2 = ref2; - return (g_strcmp0 (_ref1->collection_id, _ref2->collection_id) == 0 && - g_strcmp0 (_ref1->ref_name, _ref2->ref_name) == 0); + return (g_strcmp0 (_ref1->collection_id, _ref2->collection_id) == 0 + && g_strcmp0 (_ref1->ref_name, _ref2->ref_name) == 0); } /** @@ -154,14 +152,14 @@ ostree_collection_ref_equal (gconstpointer ref1, * Since: 2018.6 */ OstreeCollectionRef ** -ostree_collection_ref_dupv (const OstreeCollectionRef * const *refs) +ostree_collection_ref_dupv (const OstreeCollectionRef *const *refs) { - gsize i, n_refs = g_strv_length ((gchar **) refs); /* hack */ - g_auto(OstreeCollectionRefv) new_refs = NULL; + gsize i, n_refs = g_strv_length ((gchar **)refs); /* hack */ + g_auto (OstreeCollectionRefv) new_refs = NULL; g_return_val_if_fail (refs != NULL, NULL); - new_refs = g_new0 (OstreeCollectionRef*, n_refs + 1); + new_refs = g_new0 (OstreeCollectionRef *, n_refs + 1); for (i = 0; i < n_refs; i++) new_refs[i] = ostree_collection_ref_dup (refs[i]); diff --git a/src/libostree/ostree-ref.h b/src/libostree/ostree-ref.h index 384b848..30f3fd3 100644 --- a/src/libostree/ostree-ref.h +++ b/src/libostree/ostree-ref.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include "ostree-types.h" @@ -44,16 +44,15 @@ G_BEGIN_DECLS */ typedef struct { - gchar *collection_id; /* (nullable) */ - gchar *ref_name; /* (not nullable) */ + gchar *collection_id; /* (nullable) */ + gchar *ref_name; /* (not nullable) */ } OstreeCollectionRef; _OSTREE_PUBLIC GType ostree_collection_ref_get_type (void); _OSTREE_PUBLIC -OstreeCollectionRef *ostree_collection_ref_new (const gchar *collection_id, - const gchar *ref_name); +OstreeCollectionRef *ostree_collection_ref_new (const gchar *collection_id, const gchar *ref_name); _OSTREE_PUBLIC OstreeCollectionRef *ostree_collection_ref_dup (const OstreeCollectionRef *ref); _OSTREE_PUBLIC @@ -62,16 +61,15 @@ void ostree_collection_ref_free (OstreeCollectionRef *ref); _OSTREE_PUBLIC guint ostree_collection_ref_hash (gconstpointer ref); _OSTREE_PUBLIC -gboolean ostree_collection_ref_equal (gconstpointer ref1, - gconstpointer ref2); +gboolean ostree_collection_ref_equal (gconstpointer ref1, gconstpointer ref2); _OSTREE_PUBLIC -OstreeCollectionRef **ostree_collection_ref_dupv (const OstreeCollectionRef * const *refs); +OstreeCollectionRef **ostree_collection_ref_dupv (const OstreeCollectionRef *const *refs); _OSTREE_PUBLIC void ostree_collection_ref_freev (OstreeCollectionRef **refs); /** - * OstreeCollectionRefv: + * OstreeCollectionRefv: (skip) * * A %NULL-terminated array of #OstreeCollectionRef instances, designed to * be used with g_auto(): @@ -82,6 +80,6 @@ void ostree_collection_ref_freev (OstreeCollectionRef **refs); * * Since: 2018.6 */ -typedef OstreeCollectionRef** OstreeCollectionRefv; +typedef OstreeCollectionRef **OstreeCollectionRefv; G_END_DECLS diff --git a/src/libostree/ostree-remote-private.h b/src/libostree/ostree-remote-private.h index eba7430..24ada6c 100644 --- a/src/libostree/ostree-remote-private.h +++ b/src/libostree/ostree-remote-private.h @@ -26,8 +26,8 @@ #pragma once #include -#include #include +#include #include "libglnx.h" #include "ostree-remote.h" @@ -38,24 +38,23 @@ G_BEGIN_DECLS /* @refspec_name is set if this is a dynamic remote. It’s the name of the static * remote which this one inherits from, and is what should be used in refspecs * for pulls from this remote. If it’s %NULL, @name should be used instead. */ -struct OstreeRemote { - int ref_count; /* atomic */ - char *name; /* (not nullable) */ - char *refspec_name; /* (nullable) */ - char *group; /* group name in options (not nullable) */ - char *keyring; /* keyring name ($refspec_name.trustedkeys.gpg) (not nullable) */ - GFile *file; /* NULL if remote defined in repo/config */ +struct OstreeRemote +{ + int ref_count; /* atomic */ + char *name; /* (not nullable) */ + char *refspec_name; /* (nullable) */ + char *group; /* group name in options (not nullable) */ + char *keyring; /* keyring name ($refspec_name.trustedkeys.gpg) (not nullable) */ + GFile *file; /* NULL if remote defined in repo/config */ GKeyFile *options; }; G_GNUC_INTERNAL OstreeRemote *ostree_remote_new (const gchar *name); G_GNUC_INTERNAL -OstreeRemote *ostree_remote_new_dynamic (const gchar *name, - const gchar *refspec_name); +OstreeRemote *ostree_remote_new_dynamic (const gchar *name, const gchar *refspec_name); G_GNUC_INTERNAL -OstreeRemote *ostree_remote_new_from_keyfile (GKeyFile *keyfile, - const gchar *group); +OstreeRemote *ostree_remote_new_from_keyfile (GKeyFile *keyfile, const gchar *group); G_END_DECLS diff --git a/src/libostree/ostree-remote.c b/src/libostree/ostree-remote.c index 04f0835..73d836a 100644 --- a/src/libostree/ostree-remote.c +++ b/src/libostree/ostree-remote.c @@ -26,13 +26,13 @@ #include "config.h" #include -#include #include +#include #include #include -#include "ostree-remote.h" #include "ostree-remote-private.h" +#include "ostree-remote.h" #include "ot-keyfile-utils.h" /** @@ -58,8 +58,7 @@ ostree_remote_new (const gchar *name) } OstreeRemote * -ostree_remote_new_dynamic (const gchar *name, - const gchar *refspec_name) +ostree_remote_new_dynamic (const gchar *name, const gchar *refspec_name) { OstreeRemote *remote; @@ -71,17 +70,17 @@ ostree_remote_new_dynamic (const gchar *name, remote->name = g_strdup (name); remote->refspec_name = g_strdup (refspec_name); remote->group = g_strdup_printf ("remote \"%s\"", (refspec_name != NULL) ? refspec_name : name); - remote->keyring = g_strdup_printf ("%s.trustedkeys.gpg", (refspec_name != NULL) ? refspec_name : name); + remote->keyring + = g_strdup_printf ("%s.trustedkeys.gpg", (refspec_name != NULL) ? refspec_name : name); remote->options = g_key_file_new (); return remote; } OstreeRemote * -ostree_remote_new_from_keyfile (GKeyFile *keyfile, - const gchar *group) +ostree_remote_new_from_keyfile (GKeyFile *keyfile, const gchar *group) { - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; OstreeRemote *remote; g_autofree gchar *name = NULL; @@ -156,9 +155,7 @@ ostree_remote_unref (OstreeRemote *remote) } } -G_DEFINE_BOXED_TYPE(OstreeRemote, ostree_remote, - ostree_remote_ref, - ostree_remote_unref); +G_DEFINE_BOXED_TYPE (OstreeRemote, ostree_remote, ostree_remote_ref, ostree_remote_unref); /** * ostree_remote_get_name: @@ -186,7 +183,7 @@ ostree_remote_get_name (OstreeRemote *remote) * * Get the URL from the remote. * - * Returns: (transfer full): the remote's URL + * Returns: (transfer full) (nullable): the remote's URL * Since: 2018.6 */ gchar * diff --git a/src/libostree/ostree-remote.h b/src/libostree/ostree-remote.h index 3230ff8..066322f 100644 --- a/src/libostree/ostree-remote.h +++ b/src/libostree/ostree-remote.h @@ -26,8 +26,8 @@ #pragma once #include -#include #include +#include #include "ostree-types.h" diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c index 663292a..0516ef4 100644 --- a/src/libostree/ostree-repo-checkout.c +++ b/src/libostree/ostree-repo-checkout.c @@ -21,23 +21,26 @@ #include "config.h" -#include -#include +#include "otutil.h" #include #include -#include "otutil.h" +#include +#include -#include "ostree-repo-file.h" -#include "ostree-sepolicy-private.h" #include "ostree-core-private.h" +#include "ostree-repo-file.h" #include "ostree-repo-private.h" +#include "ostree-sepolicy-private.h" #define WHITEOUT_PREFIX ".wh." #define OPAQUE_WHITEOUT_NAME ".wh..wh..opq" +#define OVERLAYFS_WHITEOUT_PREFIX ".ostree-wh." + /* Per-checkout call state/caching */ -typedef struct { - GString *path_buf; /* buffer for real path if filtering enabled */ +typedef struct +{ + GString *path_buf; /* buffer for real path if filtering enabled */ GString *selabel_path_buf; /* buffer for selinux path if labeling enabled; this may be the same buffer as path_buf */ } CheckoutState; @@ -50,25 +53,23 @@ checkout_state_clear (CheckoutState *state) if (state->selabel_path_buf && (state->selabel_path_buf != state->path_buf)) g_string_free (state->selabel_path_buf, TRUE); } -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear) +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (CheckoutState, checkout_state_clear) static gboolean -checkout_object_for_uncompressed_cache (OstreeRepo *self, - const char *loose_path, - GFileInfo *src_info, - GInputStream *content, - GCancellable *cancellable, - GError **error) +checkout_object_for_uncompressed_cache (OstreeRepo *self, const char *loose_path, + GFileInfo *src_info, GInputStream *content, + GCancellable *cancellable, GError **error) { /* Don't make setuid files in uncompressed cache */ guint32 file_mode = g_file_info_get_attribute_uint32 (src_info, "unix::mode"); - file_mode &= ~(S_ISUID|S_ISGID); + file_mode &= ~(S_ISUID | S_ISGID); - g_auto(GLnxTmpfile) tmpf = { 0, }; - if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY | O_CLOEXEC, - &tmpf, error)) + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY | O_CLOEXEC, &tmpf, error)) return FALSE; - g_autoptr(GOutputStream) temp_out = g_unix_output_stream_new (tmpf.fd, FALSE); + g_autoptr (GOutputStream) temp_out = g_unix_output_stream_new (tmpf.fd, FALSE); if (g_output_stream_splice (temp_out, content, 0, cancellable, error) < 0) return FALSE; @@ -94,47 +95,38 @@ checkout_object_for_uncompressed_cache (OstreeRepo *self, DEFAULT_DIRECTORY_MODE, cancellable, error)) return FALSE; if (!glnx_opendirat (self->repo_dir_fd, "uncompressed-objects-cache", TRUE, - &self->uncompressed_objects_dir_fd, - error)) + &self->uncompressed_objects_dir_fd, error)) return FALSE; } - if (!_ostree_repo_ensure_loose_objdir_at (self->uncompressed_objects_dir_fd, - loose_path, + if (!_ostree_repo_ensure_loose_objdir_at (self->uncompressed_objects_dir_fd, loose_path, cancellable, error)) return FALSE; if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST, - self->uncompressed_objects_dir_fd, loose_path, - error)) + self->uncompressed_objects_dir_fd, loose_path, error)) return FALSE; return TRUE; } static gboolean -fsync_is_enabled (OstreeRepo *self, - OstreeRepoCheckoutAtOptions *options) +fsync_is_enabled (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options) { return options->enable_fsync; } static gboolean -write_regular_file_content (OstreeRepo *self, - OstreeRepoCheckoutAtOptions *options, - int outfd, - GFileInfo *file_info, - GVariant *xattrs, - GInputStream *input, - GCancellable *cancellable, - GError **error) +write_regular_file_content (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options, int outfd, + GFileInfo *file_info, GVariant *xattrs, GInputStream *input, + GCancellable *cancellable, GError **error) { const OstreeRepoCheckoutMode mode = options->mode; - g_autoptr(GOutputStream) outstream = NULL; + g_autoptr (GOutputStream) outstream = NULL; if (G_IS_FILE_DESCRIPTOR_BASED (input)) { - int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input); + int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased *)input); guint64 len = g_file_info_get_size (file_info); if (glnx_regfile_copy_bytes (infd, outfd, (off_t)len) < 0) @@ -143,8 +135,7 @@ write_regular_file_content (OstreeRepo *self, else { outstream = g_unix_output_stream_new (outfd, FALSE); - if (g_output_stream_splice (outstream, input, 0, - cancellable, error) < 0) + if (g_output_stream_splice (outstream, input, 0, cancellable, error) < 0) return FALSE; if (!g_output_stream_flush (outstream, cancellable, error)) @@ -153,8 +144,10 @@ write_regular_file_content (OstreeRepo *self, if (mode != OSTREE_REPO_CHECKOUT_MODE_USER) { - if (TEMP_FAILURE_RETRY (fchown (outfd, g_file_info_get_attribute_uint32 (file_info, "unix::uid"), - g_file_info_get_attribute_uint32 (file_info, "unix::gid"))) < 0) + if (TEMP_FAILURE_RETRY (fchown (outfd, + g_file_info_get_attribute_uint32 (file_info, "unix::uid"), + g_file_info_get_attribute_uint32 (file_info, "unix::gid"))) + < 0) return glnx_throw_errno_prefix (error, "fchown"); if (xattrs) @@ -168,7 +161,7 @@ write_regular_file_content (OstreeRepo *self, /* Don't make setuid files on checkout when we're doing --user */ if (mode == OSTREE_REPO_CHECKOUT_MODE_USER) - file_mode &= ~(S_ISUID|S_ISGID); + file_mode &= ~(S_ISUID | S_ISGID); if (TEMP_FAILURE_RETRY (fchmod (outfd, file_mode)) < 0) return glnx_throw_errno_prefix (error, "fchmod"); @@ -192,20 +185,14 @@ write_regular_file_content (OstreeRepo *self, * Create a copy of a file, supporting optional union/add behavior. */ static gboolean -create_file_copy_from_input_at (OstreeRepo *repo, - OstreeRepoCheckoutAtOptions *options, - CheckoutState *state, - const char *checksum, - GFileInfo *file_info, - GVariant *xattrs, - GInputStream *input, - int destination_dfd, - const char *destination_name, - GCancellable *cancellable, - GError **error) +create_file_copy_from_input_at (OstreeRepo *repo, OstreeRepoCheckoutAtOptions *options, + CheckoutState *state, const char *checksum, GFileInfo *file_info, + GVariant *xattrs, GInputStream *input, int destination_dfd, + const char *destination_name, GCancellable *cancellable, + GError **error) { const gboolean sepolicy_enabled = options->sepolicy && !repo->disable_xattrs; - g_autoptr(GVariant) modified_xattrs = NULL; + g_autoptr (GVariant) modified_xattrs = NULL; /* If we're doing SELinux labeling, prepare it */ if (sepolicy_enabled) @@ -220,15 +207,16 @@ create_file_copy_from_input_at (OstreeRepo *repo, if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK) { - g_auto(OstreeSepolicyFsCreatecon) fscreatecon = { 0, }; + g_auto (OstreeSepolicyFsCreatecon) fscreatecon = { + 0, + }; if (sepolicy_enabled) { /* For symlinks, since we don't have O_TMPFILE, we use setfscreatecon() */ - if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, options->sepolicy, - state->selabel_path_buf->str, - g_file_info_get_attribute_uint32 (file_info, "unix::mode"), - error)) + if (!_ostree_sepolicy_preparefscreatecon ( + &fscreatecon, options->sepolicy, state->selabel_path_buf->str, + g_file_info_get_attribute_uint32 (file_info, "unix::mode"), error)) return FALSE; } @@ -280,9 +268,8 @@ create_file_copy_from_input_at (OstreeRepo *repo, return FALSE; if (S_ISLNK (dest_stbuf.st_mode)) { - g_autofree char *dest_target = - glnx_readlinkat_malloc (destination_dfd, destination_name, - cancellable, error); + g_autofree char *dest_target = glnx_readlinkat_malloc ( + destination_dfd, destination_name, cancellable, error); if (!dest_target) return FALSE; /* In theory we could also compare xattrs...but eh */ @@ -298,32 +285,35 @@ create_file_copy_from_input_at (OstreeRepo *repo, /* Process ownership and xattrs now that we made the link */ if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) { - if (TEMP_FAILURE_RETRY (fchownat (destination_dfd, destination_name, - g_file_info_get_attribute_uint32 (file_info, "unix::uid"), - g_file_info_get_attribute_uint32 (file_info, "unix::gid"), - AT_SYMLINK_NOFOLLOW)) == -1) + if (TEMP_FAILURE_RETRY (fchownat ( + destination_dfd, destination_name, + g_file_info_get_attribute_uint32 (file_info, "unix::uid"), + g_file_info_get_attribute_uint32 (file_info, "unix::gid"), AT_SYMLINK_NOFOLLOW)) + == -1) return glnx_throw_errno_prefix (error, "fchownat"); - if (xattrs != NULL && - !glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name, - xattrs, cancellable, error)) + if (xattrs != NULL + && !glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name, xattrs, + cancellable, error)) return FALSE; } } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { - g_auto(GLnxTmpfile) tmpf = { 0, }; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; - if (!glnx_open_tmpfile_linkable_at (destination_dfd, ".", O_WRONLY | O_CLOEXEC, - &tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (destination_dfd, ".", O_WRONLY | O_CLOEXEC, &tmpf, error)) return FALSE; if (sepolicy_enabled && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) { g_autofree char *label = NULL; - if (!ostree_sepolicy_get_label (options->sepolicy, state->selabel_path_buf->str, - g_file_info_get_attribute_uint32 (file_info, "unix::mode"), - &label, cancellable, error)) + if (!ostree_sepolicy_get_label ( + options->sepolicy, state->selabel_path_buf->str, + g_file_info_get_attribute_uint32 (file_info, "unix::mode"), &label, cancellable, + error)) return FALSE; if (fsetxattr (tmpf.fd, "security.selinux", label, strlen (label), 0) < 0) @@ -377,9 +367,9 @@ create_file_copy_from_input_at (OstreeRepo *repo, flags |= OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS; g_autofree char *actual_checksum = NULL; - if (!ostree_checksum_file_at (destination_dfd, destination_name, - &dest_stbuf, OSTREE_OBJECT_TYPE_FILE, - flags, &actual_checksum, cancellable, error)) + if (!ostree_checksum_file_at (destination_dfd, destination_name, &dest_stbuf, + OSTREE_OBJECT_TYPE_FILE, flags, &actual_checksum, + cancellable, error)) return FALSE; if (g_str_equal (checksum, actual_checksum)) @@ -393,9 +383,7 @@ create_file_copy_from_input_at (OstreeRepo *repo, break; } - if (!glnx_link_tmpfile_at (&tmpf, replace_mode, - destination_dfd, destination_name, - error)) + if (!glnx_link_tmpfile_at (&tmpf, replace_mode, destination_dfd, destination_name, error)) return FALSE; } else @@ -404,7 +392,8 @@ create_file_copy_from_input_at (OstreeRepo *repo, return TRUE; } -typedef enum { +typedef enum +{ HARDLINK_RESULT_NOT_SUPPORTED, HARDLINK_RESULT_SKIP_EXISTED, HARDLINK_RESULT_LINKED @@ -416,12 +405,8 @@ typedef enum { * buffer @tmpname. */ static gboolean -hardlink_add_tmp_name (OstreeRepo *self, - int srcfd, - const char *loose_path, - char *tmpname, - GCancellable *cancellable, - GError **error) +hardlink_add_tmp_name (OstreeRepo *self, int srcfd, const char *loose_path, char *tmpname, + GCancellable *cancellable, GError **error) { const int max_attempts = 128; guint i; @@ -446,20 +431,14 @@ hardlink_add_tmp_name (OstreeRepo *self, } static gboolean -checkout_file_hardlink (OstreeRepo *self, - const char *checksum, - OstreeRepoCheckoutAtOptions *options, - const char *loose_path, - int destination_dfd, - const char *destination_name, - gboolean allow_noent, - HardlinkResult *out_result, - GCancellable *cancellable, - GError **error) +checkout_file_hardlink (OstreeRepo *self, const char *checksum, + OstreeRepoCheckoutAtOptions *options, const char *loose_path, + int destination_dfd, const char *destination_name, gboolean allow_noent, + HardlinkResult *out_result, GCancellable *cancellable, GError **error) { HardlinkResult ret_result = HARDLINK_RESULT_NOT_SUPPORTED; - int srcfd = _ostree_repo_mode_is_bare (self->mode) ? - self->objects_dir_fd : self->uncompressed_objects_dir_fd; + int srcfd = _ostree_repo_mode_is_bare (self->mode) ? self->objects_dir_fd + : self->uncompressed_objects_dir_fd; if (srcfd == -1) { @@ -485,7 +464,8 @@ checkout_file_hardlink (OstreeRepo *self, { case OSTREE_REPO_CHECKOUT_OVERWRITE_NONE: /* Just throw */ - return glnx_throw_errno_prefix (error, "Hardlinking %s to %s", loose_path, destination_name); + return glnx_throw_errno_prefix (error, "Hardlinking %s to %s", loose_path, + destination_name); case OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES: /* In this mode, we keep existing content. Distinguish this case though to * avoid inserting into the devino cache. @@ -509,16 +489,14 @@ checkout_file_hardlink (OstreeRepo *self, * into place. */ struct stat src_stbuf; - if (!glnx_fstatat (srcfd, loose_path, &src_stbuf, - AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat (srcfd, loose_path, &src_stbuf, AT_SYMLINK_NOFOLLOW, error)) return FALSE; struct stat dest_stbuf; - if (!glnx_fstatat (destination_dfd, destination_name, &dest_stbuf, - AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat (destination_dfd, destination_name, &dest_stbuf, AT_SYMLINK_NOFOLLOW, + error)) return FALSE; - gboolean is_identical = - (src_stbuf.st_dev == dest_stbuf.st_dev && - src_stbuf.st_ino == dest_stbuf.st_ino); + gboolean is_identical + = (src_stbuf.st_dev == dest_stbuf.st_dev && src_stbuf.st_ino == dest_stbuf.st_ino); if (!is_identical && (_ostree_stbuf_equal (&src_stbuf, &dest_stbuf))) { /* As a last resort, do a checksum comparison. This is the case currently @@ -534,9 +512,9 @@ checkout_file_hardlink (OstreeRepo *self, flags |= OSTREE_CHECKSUM_FLAGS_CANONICAL_PERMISSIONS; g_autofree char *actual_checksum = NULL; - if (!ostree_checksum_file_at (destination_dfd, destination_name, - &dest_stbuf, OSTREE_OBJECT_TYPE_FILE, - flags, &actual_checksum, cancellable, error)) + if (!ostree_checksum_file_at (destination_dfd, destination_name, &dest_stbuf, + OSTREE_OBJECT_TYPE_FILE, flags, &actual_checksum, + cancellable, error)) return FALSE; is_identical = g_str_equal (checksum, actual_checksum); @@ -557,16 +535,20 @@ checkout_file_hardlink (OstreeRepo *self, if (!glnx_shutil_rm_rf_at (destination_dfd, destination_name, NULL, error)) return FALSE; } - /* Rename it into place - for non-OCI this will overwrite files but not directories */ - if (!glnx_renameat (self->tmp_dir_fd, tmpname, destination_dfd, destination_name, error)) + /* Rename it into place - for non-OCI this will overwrite files but not directories + */ + if (!glnx_renameat (self->tmp_dir_fd, tmpname, destination_dfd, destination_name, + error)) return FALSE; ret_result = HARDLINK_RESULT_LINKED; } else { - g_assert_cmpint (options->overwrite_mode, ==, OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL); + g_assert_cmpint (options->overwrite_mode, ==, + OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL); errno = saved_errno; - return glnx_throw_errno_prefix (error, "Hardlinking %s to %s", loose_path, destination_name); + return glnx_throw_errno_prefix (error, "Hardlinking %s to %s", loose_path, + destination_name); } break; } @@ -583,14 +565,116 @@ checkout_file_hardlink (OstreeRepo *self, } static gboolean -checkout_one_file_at (OstreeRepo *repo, - OstreeRepoCheckoutAtOptions *options, - CheckoutState *state, - const char *checksum, - int destination_dfd, - const char *destination_name, - GCancellable *cancellable, - GError **error) +_checkout_overlayfs_whiteout_at_no_overwrite (OstreeRepoCheckoutAtOptions *options, + int destination_dfd, const char *destination_name, + GFileInfo *file_info, GVariant *xattrs, + gboolean *found_exant_file, GCancellable *cancellable, + GError **error) +{ + if (found_exant_file != NULL) + *found_exant_file = FALSE; + guint32 file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); + if (mknodat (destination_dfd, destination_name, (file_mode & ~S_IFMT) | S_IFCHR, (dev_t)0) < 0) + { + if (errno == EEXIST && found_exant_file != NULL) + { + *found_exant_file = TRUE; + return TRUE; + } + return glnx_throw_errno_prefix (error, "Creating whiteout char device"); + } + if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) + { + if (xattrs != NULL + && !glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name, xattrs, cancellable, + error)) + return glnx_throw_errno_prefix (error, "Setting xattrs for whiteout char device"); + + if (TEMP_FAILURE_RETRY (fchownat (destination_dfd, destination_name, + g_file_info_get_attribute_uint32 (file_info, "unix::uid"), + g_file_info_get_attribute_uint32 (file_info, "unix::gid"), + AT_SYMLINK_NOFOLLOW) + < 0)) + return glnx_throw_errno_prefix (error, "fchownat"); + if (TEMP_FAILURE_RETRY (fchmodat (destination_dfd, destination_name, file_mode & ~S_IFMT, 0)) + < 0) + return glnx_throw_errno_prefix (error, "fchmodat %s to 0%o", destination_name, + file_mode & ~S_IFMT); + } + + return TRUE; +} + +static gboolean +_checkout_overlayfs_whiteout_at (OstreeRepo *repo, OstreeRepoCheckoutAtOptions *options, + int destination_dfd, const char *destination_name, + GFileInfo *file_info, GVariant *xattrs, GCancellable *cancellable, + GError **error) +{ + gboolean found_exant_file = FALSE; + if (!_checkout_overlayfs_whiteout_at_no_overwrite (options, destination_dfd, destination_name, + file_info, xattrs, &found_exant_file, + cancellable, error)) + return FALSE; + + if (!found_exant_file) + return TRUE; + + guint32 uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid"); + guint32 gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid"); + guint32 file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); + + struct stat dest_stbuf; + + switch (options->overwrite_mode) + { + case OSTREE_REPO_CHECKOUT_OVERWRITE_NONE: + return FALSE; + case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES: + if (!ot_ensure_unlinked_at (destination_dfd, destination_name, error)) + return FALSE; + return _checkout_overlayfs_whiteout_at_no_overwrite ( + options, destination_dfd, destination_name, file_info, xattrs, NULL, cancellable, error); + case OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES: + return TRUE; + + case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL: + if (!glnx_fstatat (destination_dfd, destination_name, &dest_stbuf, AT_SYMLINK_NOFOLLOW, + error)) + return FALSE; + if (!(repo->disable_xattrs || repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY)) + { + g_autoptr (GVariant) fs_xattrs; + if (!glnx_dfd_name_get_all_xattrs (destination_dfd, destination_name, &fs_xattrs, + cancellable, error)) + return FALSE; + if (!g_variant_equal (fs_xattrs, xattrs)) + return glnx_throw (error, "existing destination file %s xattrs don't match", + destination_name); + } + if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) + { + if (gid != dest_stbuf.st_gid) + return glnx_throw (error, "existing destination file %s does not match gid %d", + destination_name, gid); + + if (uid != dest_stbuf.st_uid) + return glnx_throw (error, "existing destination file %s does not match uid %d", + destination_name, uid); + + if ((file_mode & ALLPERMS) != (dest_stbuf.st_mode & ALLPERMS)) + return glnx_throw (error, "existing destination file %s does not match mode %o", + destination_name, file_mode); + } + break; + } + return TRUE; +} + +static gboolean +checkout_one_file_at (OstreeRepo *repo, OstreeRepoCheckoutAtOptions *options, CheckoutState *state, + const char *checksum, int destination_dfd, const char *destination_name, + GCancellable *cancellable, GError **error) { /* Validate this up front to prevent path traversal attacks */ if (!ot_util_filename_validate (destination_name, error)) @@ -600,31 +684,37 @@ checkout_one_file_at (OstreeRepo *repo, gboolean is_bare_user_symlink = FALSE; char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; - /* FIXME - avoid the GFileInfo here */ - g_autoptr(GFileInfo) source_info = NULL; - if (!ostree_repo_load_file (repo, checksum, NULL, &source_info, NULL, - cancellable, error)) + g_autoptr (GFileInfo) source_info = NULL; + g_autoptr (GVariant) source_xattrs = NULL; + if (!ostree_repo_load_file (repo, checksum, NULL, &source_info, &source_xattrs, cancellable, + error)) return FALSE; if (options->filter) { /* use struct stat for when we can get rid of GFileInfo; though for now, we end up * packing and unpacking in the non-archive case; blehh */ - struct stat stbuf = {0,}; + struct stat stbuf = { + 0, + }; _ostree_gfileinfo_to_stbuf (source_info, &stbuf); - if (options->filter (repo, state->path_buf->str, &stbuf, options->filter_user_data) == - OSTREE_REPO_CHECKOUT_FILTER_SKIP) + if (options->filter (repo, state->path_buf->str, &stbuf, options->filter_user_data) + == OSTREE_REPO_CHECKOUT_FILTER_SKIP) return TRUE; /* Note early return */ } - const gboolean is_symlink = (g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK); + const gboolean is_symlink + = (g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK); const guint32 source_mode = g_file_info_get_attribute_uint32 (source_info, "unix::mode"); const gboolean is_unreadable = (!is_symlink && (source_mode & S_IRUSR) == 0); - const gboolean is_whiteout = (!is_symlink && options->process_whiteouts && - g_str_has_prefix (destination_name, WHITEOUT_PREFIX)); + const gboolean is_whiteout = (!is_symlink && options->process_whiteouts + && g_str_has_prefix (destination_name, WHITEOUT_PREFIX)); + const gboolean is_overlayfs_whiteout + = (!is_symlink && g_str_has_prefix (destination_name, OVERLAYFS_WHITEOUT_PREFIX)); const gboolean is_reg_zerosized = (!is_symlink && g_file_info_get_size (source_info) == 0); - const gboolean override_user_unreadable = (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER && is_unreadable); + const gboolean override_user_unreadable + = (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER && is_unreadable); /* First, see if it's a Docker whiteout, * https://github.com/docker/docker/blob/1a714e76a2cb9008cd19609059e9988ff1660b78/pkg/archive/whiteouts.go @@ -643,6 +733,18 @@ checkout_one_file_at (OstreeRepo *repo, need_copy = FALSE; } + else if (is_overlayfs_whiteout && options->process_passthrough_whiteouts) + { + const char *name = destination_name + (sizeof (OVERLAYFS_WHITEOUT_PREFIX) - 1); + + if (!name[0]) + return glnx_throw (error, "Invalid empty overlayfs whiteout '%s'", name); + + g_assert (name[0] != '/'); /* Sanity */ + + return _checkout_overlayfs_whiteout_at (repo, options, destination_dfd, name, source_info, + source_xattrs, cancellable, error); + } else if (is_reg_zerosized || override_user_unreadable) { /* In https://github.com/ostreedev/ostree/commit/673cacd633f9d6b653cdea530657d3e780a41bbd we @@ -664,19 +766,18 @@ checkout_one_file_at (OstreeRepo *repo, /* TODO - Hoist this up to the toplevel at least for checking out from * !parent; don't need to compute it for each file. */ - gboolean repo_is_usermode = - current_repo->mode == OSTREE_REPO_MODE_BARE_USER || - current_repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY; + gboolean repo_is_usermode = current_repo->mode == OSTREE_REPO_MODE_BARE_USER + || current_repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY; /* We're hardlinkable if the checkout mode matches the repo mode */ - gboolean is_hardlinkable = - (current_repo->mode == OSTREE_REPO_MODE_BARE - && options->mode == OSTREE_REPO_CHECKOUT_MODE_NONE) || - (repo_is_usermode && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER); - gboolean current_can_cache = (options->enable_uncompressed_cache - && current_repo->enable_uncompressed_cache); - gboolean is_archive_z2_with_cache = (current_repo->mode == OSTREE_REPO_MODE_ARCHIVE - && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER - && current_can_cache); + gboolean is_hardlinkable + = (current_repo->mode == OSTREE_REPO_MODE_BARE + && options->mode == OSTREE_REPO_CHECKOUT_MODE_NONE) + || (repo_is_usermode && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER); + gboolean current_can_cache + = (options->enable_uncompressed_cache && current_repo->enable_uncompressed_cache); + gboolean is_archive_z2_with_cache + = (current_repo->mode == OSTREE_REPO_MODE_ARCHIVE + && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER && current_can_cache); /* NOTE: bare-user symlinks are not stored as symlinks; see * https://github.com/ostreedev/ostree/commit/47c612e5a0688c3452a125655a245e8f4f01b2b0 @@ -690,22 +791,19 @@ checkout_one_file_at (OstreeRepo *repo, */ if (options->no_copy_fallback && !is_hardlinkable && !is_bare_user_symlink) return glnx_throw (error, - repo_is_usermode ? - "User repository mode requires user checkout mode to hardlink" : - "Bare repository mode cannot hardlink in user checkout mode"); + repo_is_usermode + ? "User repository mode requires user checkout mode to hardlink" + : "Bare repository mode cannot hardlink in user checkout mode"); /* But only under these conditions */ if (is_bare || is_archive_z2_with_cache) { /* Override repo mode; for archive we're looking in the cache, which is in "bare" form */ - _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE); - if (!checkout_file_hardlink (current_repo, - checksum, - options, - loose_path_buf, - destination_dfd, destination_name, - TRUE, &hardlink_res, + _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, + OSTREE_REPO_MODE_BARE); + if (!checkout_file_hardlink (current_repo, checksum, options, loose_path_buf, + destination_dfd, destination_name, TRUE, &hardlink_res, cancellable, error)) return FALSE; @@ -714,15 +812,17 @@ checkout_one_file_at (OstreeRepo *repo, struct stat stbuf; OstreeDevIno *key; - if (TEMP_FAILURE_RETRY (fstatat (destination_dfd, destination_name, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0) + if (TEMP_FAILURE_RETRY ( + fstatat (destination_dfd, destination_name, &stbuf, AT_SYMLINK_NOFOLLOW)) + != 0) return glnx_throw_errno (error); key = g_new (OstreeDevIno, 1); key->dev = stbuf.st_dev; key->ino = stbuf.st_ino; - memcpy (key->checksum, checksum, OSTREE_SHA256_STRING_LEN+1); + memcpy (key->checksum, checksum, OSTREE_SHA256_STRING_LEN + 1); - g_hash_table_add ((GHashTable*)options->devino_to_csum_cache, key); + g_hash_table_add ((GHashTable *)options->devino_to_csum_cache, key); } if (hardlink_res != HARDLINK_RESULT_NOT_SUPPORTED) @@ -736,34 +836,28 @@ checkout_one_file_at (OstreeRepo *repo, need_copy = (hardlink_res == HARDLINK_RESULT_NOT_SUPPORTED); } - const gboolean can_cache = (options->enable_uncompressed_cache - && repo->enable_uncompressed_cache); + const gboolean can_cache + = (options->enable_uncompressed_cache && repo->enable_uncompressed_cache); - g_autoptr(GInputStream) input = NULL; - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GInputStream) input = NULL; + g_autoptr (GVariant) xattrs = NULL; /* Ok, if we're archive and we didn't find an object, uncompress * it now, stick it in the cache, and then hardlink to that. */ - if (can_cache - && !is_whiteout - && !is_symlink - && !(is_reg_zerosized || override_user_unreadable) - && need_copy - && repo->mode == OSTREE_REPO_MODE_ARCHIVE + if (can_cache && !is_whiteout && !is_symlink && !(is_reg_zerosized || override_user_unreadable) + && need_copy && repo->mode == OSTREE_REPO_MODE_ARCHIVE && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER) { HardlinkResult hardlink_res = HARDLINK_RESULT_NOT_SUPPORTED; - if (!ostree_repo_load_file (repo, checksum, &input, NULL, NULL, - cancellable, error)) + if (!ostree_repo_load_file (repo, checksum, &input, NULL, NULL, cancellable, error)) return FALSE; /* Overwrite any parent repo from earlier */ _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE); - if (!checkout_object_for_uncompressed_cache (repo, loose_path_buf, - source_info, input, + if (!checkout_object_for_uncompressed_cache (repo, loose_path_buf, source_info, input, cancellable, error)) return glnx_prefix_error (error, "Unpacking loose object %s", checksum); @@ -786,19 +880,18 @@ checkout_one_file_at (OstreeRepo *repo, */ g_mutex_lock (&repo->cache_lock); { - gpointer key = GUINT_TO_POINTER ((g_ascii_xdigit_value (checksum[0]) << 4) + - g_ascii_xdigit_value (checksum[1])); + gpointer key = GUINT_TO_POINTER ((g_ascii_xdigit_value (checksum[0]) << 4) + + g_ascii_xdigit_value (checksum[1])); if (repo->updated_uncompressed_dirs == NULL) repo->updated_uncompressed_dirs = g_hash_table_new (NULL, NULL); g_hash_table_add (repo->updated_uncompressed_dirs, key); } g_mutex_unlock (&repo->cache_lock); - if (!checkout_file_hardlink (repo, checksum, options, loose_path_buf, - destination_dfd, destination_name, - FALSE, &hardlink_res, - cancellable, error)) - return glnx_prefix_error (error, "Using new cached uncompressed hardlink of %s to %s", checksum, destination_name); + if (!checkout_file_hardlink (repo, checksum, options, loose_path_buf, destination_dfd, + destination_name, FALSE, &hardlink_res, cancellable, error)) + return glnx_prefix_error (error, "Using new cached uncompressed hardlink of %s to %s", + checksum, destination_name); need_copy = (hardlink_res == HARDLINK_RESULT_NOT_SUPPORTED); } @@ -813,12 +906,11 @@ checkout_one_file_at (OstreeRepo *repo, */ if (options->no_copy_fallback) g_assert (is_bare_user_symlink || is_reg_zerosized || override_user_unreadable); - if (!ostree_repo_load_file (repo, checksum, &input, NULL, &xattrs, - cancellable, error)) + if (!ostree_repo_load_file (repo, checksum, &input, NULL, &xattrs, cancellable, error)) return FALSE; GFileInfo *copy_source_info = source_info; - g_autoptr(GFileInfo) modified_info = NULL; + g_autoptr (GFileInfo) modified_info = NULL; if (override_user_unreadable) { modified_info = g_file_info_dup (source_info); @@ -826,9 +918,9 @@ checkout_one_file_at (OstreeRepo *repo, copy_source_info = modified_info; } - if (!create_file_copy_from_input_at (repo, options, state, checksum, copy_source_info, xattrs, input, - destination_dfd, destination_name, - cancellable, error)) + if (!create_file_copy_from_input_at (repo, options, state, checksum, copy_source_info, xattrs, + input, destination_dfd, destination_name, cancellable, + error)) return glnx_prefix_error (error, "Copy checkout of %s to %s", checksum, destination_name); if (input) @@ -842,9 +934,7 @@ checkout_one_file_at (OstreeRepo *repo, } static inline void -push_path_element_once (GString *buf, - const char *name, - gboolean is_dir) +push_path_element_once (GString *buf, const char *name, gboolean is_dir) { g_string_append (buf, name); if (is_dir) @@ -852,10 +942,8 @@ push_path_element_once (GString *buf, } static inline void -push_path_element (OstreeRepoCheckoutAtOptions *options, - CheckoutState *state, - const char *name, - gboolean is_dir) +push_path_element (OstreeRepoCheckoutAtOptions *options, CheckoutState *state, const char *name, + gboolean is_dir) { if (state->path_buf) push_path_element_once (state->path_buf, name, is_dir); @@ -864,10 +952,8 @@ push_path_element (OstreeRepoCheckoutAtOptions *options, } static inline void -pop_path_element (OstreeRepoCheckoutAtOptions *options, - CheckoutState *state, - const char *name, - gboolean is_dir) +pop_path_element (OstreeRepoCheckoutAtOptions *options, CheckoutState *state, const char *name, + gboolean is_dir) { const size_t n = strlen (name) + (is_dir ? 1 : 0); if (state->path_buf) @@ -893,35 +979,29 @@ pop_path_element (OstreeRepoCheckoutAtOptions *options, * relative @destination_name, located by @destination_parent_fd. */ static gboolean -checkout_tree_at_recurse (OstreeRepo *self, - OstreeRepoCheckoutAtOptions *options, - CheckoutState *state, - int destination_parent_fd, - const char *destination_name, - const char *dirtree_checksum, - const char *dirmeta_checksum, - GCancellable *cancellable, - GError **error) +checkout_tree_at_recurse (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options, + CheckoutState *state, int destination_parent_fd, + const char *destination_name, const char *dirtree_checksum, + const char *dirmeta_checksum, GCancellable *cancellable, GError **error) { gboolean did_exist = FALSE; gboolean is_opaque_whiteout = FALSE; const gboolean sepolicy_enabled = options->sepolicy && !self->disable_xattrs; - g_autoptr(GVariant) dirtree = NULL; - g_autoptr(GVariant) dirmeta = NULL; - g_autoptr(GVariant) xattrs = NULL; - g_autoptr(GVariant) modified_xattrs = NULL; + g_autoptr (GVariant) dirtree = NULL; + g_autoptr (GVariant) dirmeta = NULL; + g_autoptr (GVariant) xattrs = NULL; + g_autoptr (GVariant) modified_xattrs = NULL; - if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_TREE, - dirtree_checksum, &dirtree, error)) + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_TREE, dirtree_checksum, &dirtree, + error)) return FALSE; - if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_META, - dirmeta_checksum, &dirmeta, error)) + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_META, dirmeta_checksum, &dirmeta, + error)) return FALSE; /* Parse OSTREE_OBJECT_TYPE_DIR_META */ guint32 uid, gid, mode; - g_variant_get (dirmeta, "(uuu@a(ayay))", - &uid, &gid, &mode, + g_variant_get (dirmeta, "(uuu@a(ayay))", &uid, &gid, &mode, options->mode != OSTREE_REPO_CHECKOUT_MODE_USER ? &xattrs : NULL); uid = GUINT32_FROM_BE (uid); gid = GUINT32_FROM_BE (gid); @@ -929,7 +1009,9 @@ checkout_tree_at_recurse (OstreeRepo *self, if (options->filter) { - struct stat stbuf = { 0, }; + struct stat stbuf = { + 0, + }; stbuf.st_mode = mode; stbuf.st_uid = uid; stbuf.st_gid = gid; @@ -940,10 +1022,10 @@ checkout_tree_at_recurse (OstreeRepo *self, if (options->process_whiteouts) { - g_autoptr(GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0); + g_autoptr (GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0); GVariantIter viter; const char *fname; - g_autoptr(GVariant) contents_csum_v = NULL; + g_autoptr (GVariant) contents_csum_v = NULL; g_variant_iter_init (&viter, dir_file_contents); while (g_variant_iter_loop (&viter, "(&s@ay)", &fname, &contents_csum_v)) { @@ -958,7 +1040,9 @@ checkout_tree_at_recurse (OstreeRepo *self, * setfscreatecon(). */ { - g_auto(OstreeSepolicyFsCreatecon) fscreatecon = { 0, }; + g_auto (OstreeSepolicyFsCreatecon) fscreatecon = { + 0, + }; /* If we're doing SELinux labeling, prepare it */ if (sepolicy_enabled) @@ -968,8 +1052,7 @@ checkout_tree_at_recurse (OstreeRepo *self, xattrs = modified_xattrs; if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, options->sepolicy, - state->selabel_path_buf->str, - mode, error)) + state->selabel_path_buf->str, mode, error)) return FALSE; } @@ -1004,8 +1087,7 @@ checkout_tree_at_recurse (OstreeRepo *self, } glnx_autofd int destination_dfd = -1; - if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE, - &destination_dfd, error)) + if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE, &destination_dfd, error)) return FALSE; struct stat repo_dfd_stat; @@ -1016,7 +1098,9 @@ checkout_tree_at_recurse (OstreeRepo *self, return glnx_throw_errno (error); if (options->no_copy_fallback && repo_dfd_stat.st_dev != destination_stat.st_dev) - return glnx_throw (error, "Unable to do hardlink checkout across devices (src=%"G_GUINT64_FORMAT" destination=%"G_GUINT64_FORMAT")", + return glnx_throw (error, + "Unable to do hardlink checkout across devices (src=%" G_GUINT64_FORMAT + " destination=%" G_GUINT64_FORMAT ")", (guint64)repo_dfd_stat.st_dev, (guint64)destination_stat.st_dev); /* Set the xattrs if we created the dir */ @@ -1027,21 +1111,20 @@ checkout_tree_at_recurse (OstreeRepo *self, } /* Process files in this subdir */ - { g_autoptr(GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0); + { + g_autoptr (GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0); GVariantIter viter; g_variant_iter_init (&viter, dir_file_contents); const char *fname; - g_autoptr(GVariant) contents_csum_v = NULL; + g_autoptr (GVariant) contents_csum_v = NULL; while (g_variant_iter_loop (&viter, "(&s@ay)", &fname, &contents_csum_v)) { push_path_element (options, state, fname, FALSE); - char tmp_checksum[OSTREE_SHA256_STRING_LEN+1]; + char tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; _ostree_checksum_inplace_from_bytes_v (contents_csum_v, tmp_checksum); - if (!checkout_one_file_at (self, options, state, - tmp_checksum, - destination_dfd, fname, + if (!checkout_one_file_at (self, options, state, tmp_checksum, destination_dfd, fname, cancellable, error)) return FALSE; @@ -1051,14 +1134,15 @@ checkout_tree_at_recurse (OstreeRepo *self, } /* Process subdirectories */ - { g_autoptr(GVariant) dir_subdirs = g_variant_get_child_value (dirtree, 1); + { + g_autoptr (GVariant) dir_subdirs = g_variant_get_child_value (dirtree, 1); const char *dname; - g_autoptr(GVariant) subdirtree_csum_v = NULL; - g_autoptr(GVariant) subdirmeta_csum_v = NULL; + g_autoptr (GVariant) subdirtree_csum_v = NULL; + g_autoptr (GVariant) subdirmeta_csum_v = NULL; GVariantIter viter; g_variant_iter_init (&viter, dir_subdirs); - while (g_variant_iter_loop (&viter, "(&s@ay@ay)", &dname, - &subdirtree_csum_v, &subdirmeta_csum_v)) + while ( + g_variant_iter_loop (&viter, "(&s@ay@ay)", &dname, &subdirtree_csum_v, &subdirmeta_csum_v)) { /* Validate this up front to prevent path traversal attacks. Note that * we don't validate at the top of this function like we do for @@ -1071,14 +1155,13 @@ checkout_tree_at_recurse (OstreeRepo *self, push_path_element (options, state, dname, TRUE); - char subdirtree_checksum[OSTREE_SHA256_STRING_LEN+1]; + char subdirtree_checksum[OSTREE_SHA256_STRING_LEN + 1]; _ostree_checksum_inplace_from_bytes_v (subdirtree_csum_v, subdirtree_checksum); - char subdirmeta_checksum[OSTREE_SHA256_STRING_LEN+1]; + char subdirmeta_checksum[OSTREE_SHA256_STRING_LEN + 1]; _ostree_checksum_inplace_from_bytes_v (subdirmeta_csum_v, subdirmeta_checksum); - if (!checkout_tree_at_recurse (self, options, state, - destination_dfd, dname, - subdirtree_checksum, subdirmeta_checksum, - cancellable, error)) + if (!checkout_tree_at_recurse (self, options, state, destination_dfd, dname, + subdirtree_checksum, subdirmeta_checksum, cancellable, + error)) return FALSE; pop_path_element (options, state, dname, TRUE); @@ -1094,7 +1177,8 @@ checkout_tree_at_recurse (OstreeRepo *self, /* Silently ignore world-writable directories (plus sticky, suid bits, * etc.) when doing a checkout for bare-user-only repos, or if requested explicitly. * This is related to the logic in ostree-repo-commit.c for files. - * See also: https://github.com/ostreedev/ostree/pull/909 i.e. 0c4b3a2b6da950fd78e63f9afec602f6188f1ab0 + * See also: https://github.com/ostreedev/ostree/pull/909 i.e. + * 0c4b3a2b6da950fd78e63f9afec602f6188f1ab0 */ if (self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY || options->bareuseronly_dirs) canonical_mode = (mode & 0775) | S_IFDIR; @@ -1117,7 +1201,8 @@ checkout_tree_at_recurse (OstreeRepo *self, */ if (!did_exist && !options->force_copy) { - const struct timespec times[2] = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0} }; + const struct timespec times[2] + = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0 } }; if (TEMP_FAILURE_RETRY (futimens (destination_dfd, times)) < 0) return glnx_throw_errno (error); } @@ -1133,16 +1218,13 @@ checkout_tree_at_recurse (OstreeRepo *self, /* Begin a checkout process */ static gboolean -checkout_tree_at (OstreeRepo *self, - OstreeRepoCheckoutAtOptions *options, - int destination_parent_fd, - const char *destination_name, - OstreeRepoFile *source, - GFileInfo *source_info, - GCancellable *cancellable, - GError **error) +checkout_tree_at (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options, int destination_parent_fd, + const char *destination_name, OstreeRepoFile *source, GFileInfo *source_info, + GCancellable *cancellable, GError **error) { - g_auto(CheckoutState) state = { 0, }; + g_auto (CheckoutState) state = { + 0, + }; if (options->filter) state.path_buf = g_string_new ("/"); @@ -1164,21 +1246,19 @@ checkout_tree_at (OstreeRepo *self, GString *buf = g_string_new (prefix); g_assert_cmpint (buf->len, >, 0); /* Ensure it ends with / */ - if (buf->str[buf->len-1] != '/') + if (buf->str[buf->len - 1] != '/') g_string_append_c (buf, '/'); state.selabel_path_buf = buf; } } /* Uncompressed archive caches; should be considered deprecated */ - const gboolean can_cache = (options->enable_uncompressed_cache - && self->enable_uncompressed_cache); - if (can_cache - && !_ostree_repo_mode_is_bare (self->mode) - && self->uncompressed_objects_dir_fd < 0) + const gboolean can_cache + = (options->enable_uncompressed_cache && self->enable_uncompressed_cache); + if (can_cache && !_ostree_repo_mode_is_bare (self->mode) && self->uncompressed_objects_dir_fd < 0) { - self->uncompressed_objects_dir_fd = - glnx_opendirat_with_errno (self->repo_dir_fd, "uncompressed-objects-cache", TRUE); + self->uncompressed_objects_dir_fd + = glnx_opendirat_with_errno (self->repo_dir_fd, "uncompressed-objects-cache", TRUE); if (self->uncompressed_objects_dir_fd < 0 && errno != ENOENT) return glnx_throw_errno_prefix (error, "opendir(uncompressed-objects-cache)"); } @@ -1196,8 +1276,7 @@ checkout_tree_at (OstreeRepo *self, glnx_autofd int destination_dfd_owned = -1; if (!g_str_equal (destination_name, ".")) { - if (mkdirat (destination_parent_fd, destination_name, 0700) < 0 - && errno != EEXIST) + if (mkdirat (destination_parent_fd, destination_name, 0700) < 0 && errno != EEXIST) return glnx_throw_errno_prefix (error, "mkdirat"); if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE, &destination_dfd_owned, error)) @@ -1207,31 +1286,26 @@ checkout_tree_at (OstreeRepo *self, /* let's just ignore filter here; I can't think of a useful case for filtering when * only checking out one path */ options->filter = NULL; - return checkout_one_file_at (self, options, &state, - ostree_repo_file_get_checksum (source), - destination_dfd, - g_file_info_get_name (source_info), - cancellable, error); + return checkout_one_file_at (self, options, &state, ostree_repo_file_get_checksum (source), + destination_dfd, g_file_info_get_name (source_info), cancellable, + error); } /* Cache any directory metadata we read during this operation; * see commit b7afe91e21143d7abb0adde440683a52712aa246 */ - g_auto(OstreeRepoMemoryCacheRef) memcache_ref; + g_auto (OstreeRepoMemoryCacheRef) memcache_ref; _ostree_repo_memory_cache_ref_init (&memcache_ref, self); g_assert_cmpint (g_file_info_get_file_type (source_info), ==, G_FILE_TYPE_DIRECTORY); const char *dirtree_checksum = ostree_repo_file_tree_get_contents_checksum (source); const char *dirmeta_checksum = ostree_repo_file_tree_get_metadata_checksum (source); - return checkout_tree_at_recurse (self, options, &state, destination_parent_fd, - destination_name, - dirtree_checksum, dirmeta_checksum, - cancellable, error); + return checkout_tree_at_recurse (self, options, &state, destination_parent_fd, destination_name, + dirtree_checksum, dirmeta_checksum, cancellable, error); } static void -canonicalize_options (OstreeRepo *self, - OstreeRepoCheckoutAtOptions *options) +canonicalize_options (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options) { /* Canonicalize subpath to / */ if (!options->subpath) @@ -1259,26 +1333,22 @@ canonicalize_options (OstreeRepo *self, * files are checked out. */ gboolean -ostree_repo_checkout_tree (OstreeRepo *self, - OstreeRepoCheckoutMode mode, - OstreeRepoCheckoutOverwriteMode overwrite_mode, - GFile *destination, - OstreeRepoFile *source, - GFileInfo *source_info, - GCancellable *cancellable, - GError **error) +ostree_repo_checkout_tree (OstreeRepo *self, OstreeRepoCheckoutMode mode, + OstreeRepoCheckoutOverwriteMode overwrite_mode, GFile *destination, + OstreeRepoFile *source, GFileInfo *source_info, + GCancellable *cancellable, GError **error) { - OstreeRepoCheckoutAtOptions options = { 0, }; + OstreeRepoCheckoutAtOptions options = { + 0, + }; options.mode = mode; options.overwrite_mode = overwrite_mode; /* Backwards compatibility */ options.enable_uncompressed_cache = TRUE; canonicalize_options (self, &options); - return checkout_tree_at (self, &options, - AT_FDCWD, gs_file_get_path_cached (destination), - source, source_info, - cancellable, error); + return checkout_tree_at (self, &options, AT_FDCWD, gs_file_get_path_cached (destination), source, + source_info, cancellable, error); } /** @@ -1303,15 +1373,13 @@ ostree_repo_checkout_tree (OstreeRepo *self, * This function is deprecated. Use ostree_repo_checkout_at() instead. */ gboolean -ostree_repo_checkout_tree_at (OstreeRepo *self, - OstreeRepoCheckoutOptions *options, - int destination_dfd, - const char *destination_path, - const char *commit, - GCancellable *cancellable, - GError **error) +ostree_repo_checkout_tree_at (OstreeRepo *self, OstreeRepoCheckoutOptions *options, + int destination_dfd, const char *destination_path, const char *commit, + GCancellable *cancellable, GError **error) { - OstreeRepoCheckoutAtOptions new_opts = {0, }; + OstreeRepoCheckoutAtOptions new_opts = { + 0, + }; new_opts.mode = options->mode; new_opts.overwrite_mode = options->overwrite_mode; new_opts.enable_uncompressed_cache = options->enable_uncompressed_cache; @@ -1320,8 +1388,8 @@ ostree_repo_checkout_tree_at (OstreeRepo *self, new_opts.no_copy_fallback = options->no_copy_fallback; new_opts.subpath = options->subpath; new_opts.devino_to_csum_cache = options->devino_to_csum_cache; - return ostree_repo_checkout_at (self, &new_opts, destination_dfd, - destination_path, commit, cancellable, error); + return ostree_repo_checkout_at (self, &new_opts, destination_dfd, destination_path, commit, + cancellable, error); } /** @@ -1349,15 +1417,13 @@ ostree_repo_checkout_tree_at (OstreeRepo *self, * Since: 2016.8 */ gboolean -ostree_repo_checkout_at (OstreeRepo *self, - OstreeRepoCheckoutAtOptions *options, - int destination_dfd, - const char *destination_path, - const char *commit, - GCancellable *cancellable, - GError **error) +ostree_repo_checkout_at (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options, + int destination_dfd, const char *destination_path, const char *commit, + GCancellable *cancellable, GError **error) { - OstreeRepoCheckoutAtOptions default_options = { 0, }; + OstreeRepoCheckoutAtOptions default_options = { + 0, + }; OstreeRepoCheckoutAtOptions real_options; if (!options) @@ -1374,34 +1440,31 @@ ostree_repo_checkout_at (OstreeRepo *self, g_return_val_if_fail (!(options->force_copy && options->no_copy_fallback), FALSE); g_return_val_if_fail (!options->sepolicy || options->force_copy, FALSE); /* union identical requires hardlink mode */ - g_return_val_if_fail (!(options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL && - !options->no_copy_fallback), FALSE); + g_return_val_if_fail (!(options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL + && !options->no_copy_fallback), + FALSE); - g_autoptr(GFile) commit_root = (GFile*) _ostree_repo_file_new_for_commit (self, commit, error); + g_autoptr (GFile) commit_root = (GFile *)_ostree_repo_file_new_for_commit (self, commit, error); if (!commit_root) return FALSE; - if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile*)commit_root, error)) + if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *)commit_root, error)) return FALSE; - g_autoptr(GFile) target_dir = NULL; + g_autoptr (GFile) target_dir = NULL; if (strcmp (options->subpath, "/") != 0) target_dir = g_file_resolve_relative_path (commit_root, options->subpath); else target_dir = g_object_ref (commit_root); - g_autoptr(GFileInfo) target_info = - g_file_query_info (target_dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + g_autoptr (GFileInfo) target_info + = g_file_query_info (target_dir, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!target_info) return FALSE; - if (!checkout_tree_at (self, options, - destination_dfd, - destination_path, - (OstreeRepoFile*)target_dir, target_info, - cancellable, error)) + if (!checkout_tree_at (self, options, destination_dfd, destination_path, + (OstreeRepoFile *)target_dir, target_info, cancellable, error)) return FALSE; return TRUE; @@ -1431,17 +1494,15 @@ static guint devino_hash (gconstpointer a) { OstreeDevIno *a_i = (gpointer)a; - return (guint) (a_i->dev + a_i->ino); + return (guint)(a_i->dev + a_i->ino); } static int -devino_equal (gconstpointer a, - gconstpointer b) +devino_equal (gconstpointer a, gconstpointer b) { OstreeDevIno *a_i = (gpointer)a; OstreeDevIno *b_i = (gpointer)b; - return a_i->dev == b_i->dev - && a_i->ino == b_i->ino; + return a_i->dev == b_i->dev && a_i->ino == b_i->ino; } /** @@ -1460,7 +1521,7 @@ devino_equal (gconstpointer a, OstreeRepoDevInoCache * ostree_repo_devino_cache_new (void) { - return (OstreeRepoDevInoCache*) g_hash_table_new_full (devino_hash, devino_equal, g_free, NULL); + return (OstreeRepoDevInoCache *)g_hash_table_new_full (devino_hash, devino_equal, g_free, NULL); } /** @@ -1474,11 +1535,9 @@ ostree_repo_devino_cache_new (void) * cache. */ gboolean -ostree_repo_checkout_gc (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +ostree_repo_checkout_gc (OstreeRepo *self, GCancellable *cancellable, GError **error) { - g_autoptr(GHashTable) to_clean_dirs = NULL; + g_autoptr (GHashTable) to_clean_dirs = NULL; g_mutex_lock (&self->cache_lock); to_clean_dirs = self->updated_uncompressed_dirs; @@ -1491,7 +1550,9 @@ ostree_repo_checkout_gc (OstreeRepo *self, GLNX_HASH_TABLE_FOREACH (to_clean_dirs, gpointer, prefix) { g_autofree char *objdir_name = g_strdup_printf ("%02x", GPOINTER_TO_UINT (prefix)); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (self->uncompressed_objects_dir_fd, objdir_name, FALSE, &dfd_iter, error)) diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index afab3fd..d9fbb25 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -22,33 +22,33 @@ #include "config.h" -#include -#include +#include #include #include #include -#include +#include #include +#include #include -#include -#include +#include +#include -#include "otutil.h" -#include "ostree.h" +#include "ostree-checksum-input-stream.h" #include "ostree-core-private.h" +#include "ostree-repo-file-enumerator.h" #include "ostree-repo-private.h" #include "ostree-sepolicy-private.h" -#include "ostree-repo-file-enumerator.h" -#include "ostree-checksum-input-stream.h" #include "ostree-varint.h" +#include "ostree.h" +#include "otutil.h" /* The standardized version of BTRFS_IOC_CLONE */ #ifndef FICLONE -#define FICLONE _IOW(0x94, 9, int) +#define FICLONE _IOW (0x94, 9, int) #endif /* Understanding ostree's fsync strategy - * + * * A long time ago, ostree used to invoke fsync() on each object, * then move it into the objects directory. However, it turned * out to be a *lot* faster to write the objects into a separate "staging" @@ -98,10 +98,8 @@ commit_tmp_dfd (OstreeRepo *self) * is quite old, but Git also uses it for example. */ gboolean -_ostree_repo_ensure_loose_objdir_at (int dfd, - const char *loose_path, - GCancellable *cancellable, - GError **error) +_ostree_repo_ensure_loose_objdir_at (int dfd, const char *loose_path, GCancellable *cancellable, + GError **error) { char loose_prefix[3]; @@ -121,22 +119,16 @@ _ostree_repo_ensure_loose_objdir_at (int dfd, /* This GVariant is the header for content objects (regfiles and symlinks) */ static GVariant * -create_file_metadata (guint32 uid, - guint32 gid, - guint32 mode, - GVariant *xattrs) +create_file_metadata (guint32 uid, guint32 gid, guint32 mode, GVariant *xattrs) { GVariant *ret_metadata = NULL; - g_autoptr(GVariant) tmp_xattrs = NULL; + g_autoptr (GVariant) tmp_xattrs = NULL; if (xattrs == NULL) tmp_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); - ret_metadata = g_variant_new ("(uuu@a(ayay))", - GUINT32_TO_BE (uid), - GUINT32_TO_BE (gid), - GUINT32_TO_BE (mode), - xattrs ? xattrs : tmp_xattrs); + ret_metadata = g_variant_new ("(uuu@a(ayay))", GUINT32_TO_BE (uid), GUINT32_TO_BE (gid), + GUINT32_TO_BE (mode), xattrs ? xattrs : tmp_xattrs); g_variant_ref_sink (ret_metadata); return ret_metadata; @@ -144,19 +136,14 @@ create_file_metadata (guint32 uid, /* bare-user repositories store file metadata as a user xattr */ gboolean -_ostree_write_bareuser_metadata (int fd, - guint32 uid, - guint32 gid, - guint32 mode, - GVariant *xattrs, - GError **error) +_ostree_write_bareuser_metadata (int fd, guint32 uid, guint32 gid, guint32 mode, GVariant *xattrs, + GError **error) { - g_autoptr(GVariant) filemeta = create_file_metadata (uid, gid, mode, xattrs); + g_autoptr (GVariant) filemeta = create_file_metadata (uid, gid, mode, xattrs); - if (TEMP_FAILURE_RETRY (fsetxattr (fd, "user.ostreemeta", - (char*)g_variant_get_data (filemeta), - g_variant_get_size (filemeta), - 0)) != 0) + if (TEMP_FAILURE_RETRY (fsetxattr (fd, "user.ostreemeta", (char *)g_variant_get_data (filemeta), + g_variant_get_size (filemeta), 0)) + != 0) return glnx_throw_errno_prefix (error, "fsetxattr(user.ostreemeta)"); return TRUE; @@ -174,7 +161,7 @@ ot_security_smack_reset_dfd_name (int dfd, const char *name) char buf[PATH_MAX]; /* See glnx-xattrs.c */ snprintf (buf, sizeof (buf), "/proc/self/fd/%d/%s", dfd, name); - (void) lremovexattr (buf, XATTR_NAME_SMACK); + (void)lremovexattr (buf, XATTR_NAME_SMACK); #endif } @@ -182,32 +169,27 @@ static void ot_security_smack_reset_fd (int fd) { #ifdef WITH_SMACK - (void) fremovexattr (fd, XATTR_NAME_SMACK); + (void)fremovexattr (fd, XATTR_NAME_SMACK); #endif } /* Given an O_TMPFILE regular file, link it into place. */ gboolean -_ostree_repo_commit_tmpf_final (OstreeRepo *self, - const char *checksum, - OstreeObjectType objtype, - GLnxTmpfile *tmpf, - GCancellable *cancellable, - GError **error) +_ostree_repo_commit_tmpf_final (OstreeRepo *self, const char *checksum, OstreeObjectType objtype, + GLnxTmpfile *tmpf, GCancellable *cancellable, GError **error) { char tmpbuf[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (tmpbuf, checksum, objtype, self->mode); int dest_dfd = commit_dest_dfd (self); - if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, tmpbuf, - cancellable, error)) + if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, tmpbuf, cancellable, error)) return FALSE; - if (!_ostree_tmpf_fsverity (self, tmpf, error)) + if (!_ostree_tmpf_fsverity (self, tmpf, NULL, error)) return FALSE; - if (!glnx_link_tmpfile_at (tmpf, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST, - dest_dfd, tmpbuf, error)) + if (!glnx_link_tmpfile_at (tmpf, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST, dest_dfd, tmpbuf, + error)) return FALSE; /* We're done with the fd */ glnx_tmpfile_clear (tmpf); @@ -218,24 +200,18 @@ _ostree_repo_commit_tmpf_final (OstreeRepo *self, * rename it into place. */ static gboolean -commit_path_final (OstreeRepo *self, - const char *checksum, - OstreeObjectType objtype, - OtCleanupUnlinkat *tmp_path, - GCancellable *cancellable, - GError **error) +commit_path_final (OstreeRepo *self, const char *checksum, OstreeObjectType objtype, + OtCleanupUnlinkat *tmp_path, GCancellable *cancellable, GError **error) { /* The final renameat() */ char tmpbuf[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (tmpbuf, checksum, objtype, self->mode); int dest_dfd = commit_dest_dfd (self); - if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, tmpbuf, - cancellable, error)) + if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, tmpbuf, cancellable, error)) return FALSE; - if (renameat (tmp_path->dfd, tmp_path->path, - dest_dfd, tmpbuf) == -1) + if (renameat (tmp_path->dfd, tmp_path->path, dest_dfd, tmpbuf) == -1) { if (errno != EEXIST) return glnx_throw_errno_prefix (error, "Storing file '%s'", tmp_path->path); @@ -250,21 +226,14 @@ commit_path_final (OstreeRepo *self, return TRUE; } - /* Given either a file or symlink, apply the final metadata to it depending on * the repository mode. Note that @checksum is assumed to have been validated by * the caller. */ static gboolean -commit_loose_regfile_object (OstreeRepo *self, - const char *checksum, - GLnxTmpfile *tmpf, - guint32 uid, - guint32 gid, - guint32 mode, - GVariant *xattrs, - GCancellable *cancellable, - GError **error) +commit_loose_regfile_object (OstreeRepo *self, const char *checksum, GLnxTmpfile *tmpf, guint32 uid, + guint32 gid, guint32 mode, GVariant *xattrs, GCancellable *cancellable, + GError **error) { if (self->mode == OSTREE_REPO_MODE_BARE) { @@ -319,7 +288,8 @@ commit_loose_regfile_object (OstreeRepo *self, * to determine whether or not source files need to be compiled, * set the modification time to OSTREE_TIMESTAMP. */ - const struct timespec times[2] = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0} }; + const struct timespec times[2] + = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0 } }; if (TEMP_FAILURE_RETRY (futimens (tmpf->fd, times)) < 0) return glnx_throw_errno_prefix (error, "futimens"); } @@ -333,8 +303,8 @@ commit_loose_regfile_object (OstreeRepo *self, return glnx_throw_errno_prefix (error, "fsync"); } - if (!_ostree_repo_commit_tmpf_final (self, checksum, OSTREE_OBJECT_TYPE_FILE, - tmpf, cancellable, error)) + if (!_ostree_repo_commit_tmpf_final (self, checksum, OSTREE_OBJECT_TYPE_FILE, tmpf, cancellable, + error)) return FALSE; return TRUE; @@ -349,9 +319,7 @@ typedef struct } OstreeContentSizeCacheEntry; static OstreeContentSizeCacheEntry * -content_size_cache_entry_new (OstreeObjectType objtype, - goffset unpacked, - goffset archived) +content_size_cache_entry_new (OstreeObjectType objtype, goffset unpacked, goffset archived) { OstreeContentSizeCacheEntry *entry = g_slice_new0 (OstreeContentSizeCacheEntry); @@ -370,8 +338,7 @@ content_size_cache_entry_free (gpointer entry) } void -_ostree_repo_setup_generate_sizes (OstreeRepo *self, - OstreeRepoCommitModifier *modifier) +_ostree_repo_setup_generate_sizes (OstreeRepo *self, OstreeRepoCommitModifier *modifier) { if (modifier && modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES) { @@ -392,14 +359,12 @@ static void repo_ensure_size_entries (OstreeRepo *self) { if (G_UNLIKELY (self->object_sizes == NULL)) - self->object_sizes = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, content_size_cache_entry_free); + self->object_sizes + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, content_size_cache_entry_free); } static gboolean -repo_has_size_entry (OstreeRepo *self, - OstreeObjectType objtype, - const gchar *checksum) +repo_has_size_entry (OstreeRepo *self, OstreeObjectType objtype, const gchar *checksum) { /* Only file, dirtree and dirmeta objects appropriate for size metadata */ if (objtype > OSTREE_OBJECT_TYPE_DIR_META) @@ -410,28 +375,23 @@ repo_has_size_entry (OstreeRepo *self, } static void -repo_store_size_entry (OstreeRepo *self, - OstreeObjectType objtype, - const gchar *checksum, - goffset unpacked, - goffset archived) +repo_store_size_entry (OstreeRepo *self, OstreeObjectType objtype, const gchar *checksum, + goffset unpacked, goffset archived) { /* Only file, dirtree and dirmeta objects appropriate for size metadata */ if (objtype > OSTREE_OBJECT_TYPE_DIR_META) return; repo_ensure_size_entries (self); - g_hash_table_replace (self->object_sizes, - g_strdup (checksum), + g_hash_table_replace (self->object_sizes, g_strdup (checksum), content_size_cache_entry_new (objtype, unpacked, archived)); } static int -compare_ascii_checksums_for_sorting (gconstpointer a_pp, - gconstpointer b_pp) +compare_ascii_checksums_for_sorting (gconstpointer a_pp, gconstpointer b_pp) { - char *a = *((char**)a_pp); - char *b = *((char**)b_pp); + char *a = *((char **)a_pp); + char *b = *((char **)b_pp); return strcmp (a, b); } @@ -439,25 +399,18 @@ compare_ascii_checksums_for_sorting (gconstpointer a_pp, /* * Create sizes metadata GVariant and add it to the metadata variant given. */ -static GVariant * -add_size_index_to_metadata (OstreeRepo *self, - GVariant *original_metadata) +static void +add_size_index_to_metadata (OstreeRepo *self, GVariantBuilder *builder) { - g_autoptr(GVariantBuilder) builder = NULL; - - /* original_metadata may be NULL */ - builder = ot_util_variant_builder_from_variant (original_metadata, G_VARIANT_TYPE ("a{sv}")); - - if (self->object_sizes && - g_hash_table_size (self->object_sizes) > 0) + if (self->object_sizes && g_hash_table_size (self->object_sizes) > 0) { GVariantBuilder index_builder; g_variant_builder_init (&index_builder, G_VARIANT_TYPE ("a" _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE)); /* Sort the checksums so we can bsearch if desired */ - g_autoptr(GPtrArray) sorted_keys = g_ptr_array_new (); - GLNX_HASH_TABLE_FOREACH (self->object_sizes, const char*, e_checksum) + g_autoptr (GPtrArray) sorted_keys = g_ptr_array_new (); + GLNX_HASH_TABLE_FOREACH (self->object_sizes, const char *, e_checksum) g_ptr_array_add (sorted_keys, (gpointer)e_checksum); g_ptr_array_sort (sorted_keys, compare_ascii_checksums_for_sorting); @@ -465,19 +418,19 @@ add_size_index_to_metadata (OstreeRepo *self, { guint8 csum[OSTREE_SHA256_DIGEST_LEN]; const char *e_checksum = sorted_keys->pdata[i]; - g_autoptr(GString) buffer = g_string_new (NULL); + g_autoptr (GString) buffer = g_string_new (NULL); ostree_checksum_inplace_to_bytes (e_checksum, csum); - g_string_append_len (buffer, (char*)csum, sizeof (csum)); + g_string_append_len (buffer, (char *)csum, sizeof (csum)); - OstreeContentSizeCacheEntry *e_size = - g_hash_table_lookup (self->object_sizes, e_checksum); + OstreeContentSizeCacheEntry *e_size + = g_hash_table_lookup (self->object_sizes, e_checksum); _ostree_write_varuint64 (buffer, e_size->archived); _ostree_write_varuint64 (buffer, e_size->unpacked); - g_string_append_c (buffer, (gchar) e_size->objtype); + g_string_append_c (buffer, (gchar)e_size->objtype); g_variant_builder_add (&index_builder, "@ay", - ot_gvariant_new_bytearray ((guint8*)buffer->str, buffer->len)); + ot_gvariant_new_bytearray ((guint8 *)buffer->str, buffer->len)); } g_variant_builder_add (builder, "{sv}", "ostree.sizes", @@ -486,14 +439,10 @@ add_size_index_to_metadata (OstreeRepo *self, /* Clear the object sizes hash table for a subsequent commit. */ g_hash_table_remove_all (self->object_sizes); } - - return g_variant_ref_sink (g_variant_builder_end (builder)); } static gboolean -throw_min_free_space_error (OstreeRepo *self, - guint64 bytes_required, - GError **error) +throw_min_free_space_error (OstreeRepo *self, guint64 bytes_required, GError **error) { const char *err_msg = NULL; g_autofree char *err_msg_owned = NULL; @@ -501,18 +450,23 @@ throw_min_free_space_error (OstreeRepo *self, if (bytes_required > 0) { g_autofree char *formatted_required = g_format_size (bytes_required); - err_msg = err_msg_owned = g_strdup_printf ("would be exceeded, at least %s requested", formatted_required); + err_msg = err_msg_owned + = g_strdup_printf ("would be exceeded, at least %s requested", formatted_required); } else - err_msg = "would be exceeded"; + err_msg = "would be exceeded"; + (void)err_msg_owned; // Conditional ownership if (self->min_free_space_mb > 0) - return glnx_throw (error, "min-free-space-size %" G_GUINT64_FORMAT "MB %s", self->min_free_space_mb, err_msg); + return glnx_throw (error, "min-free-space-size %" G_GUINT64_FORMAT "MB %s", + self->min_free_space_mb, err_msg); else - return glnx_throw (error, "min-free-space-percent '%u%%' %s", self->min_free_space_percent, err_msg); + return glnx_throw (error, "min-free-space-percent '%u%%' %s", self->min_free_space_percent, + err_msg); } -typedef struct { +typedef struct +{ gboolean initialized; GLnxTmpfile tmpf; char *expected_checksum; @@ -531,23 +485,17 @@ G_STATIC_ASSERT (sizeof (OstreeRepoBareContent) >= sizeof (OstreeRealRepoBareCon * to be used also by the dfd_iter commit path. */ gboolean -_ostree_repo_bare_content_open (OstreeRepo *self, - const char *expected_checksum, - guint64 content_len, - guint uid, - guint gid, - guint mode, - GVariant *xattrs, - OstreeRepoBareContent *out_regwrite, - GCancellable *cancellable, - GError **error) +_ostree_repo_bare_content_open (OstreeRepo *self, const char *expected_checksum, + guint64 content_len, guint uid, guint gid, guint mode, + GVariant *xattrs, OstreeRepoBareContent *out_regwrite, + GCancellable *cancellable, GError **error) { - OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent*) out_regwrite; + OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent *)out_regwrite; g_assert (!real->initialized); real->initialized = TRUE; g_assert (S_ISREG (mode)); - if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC, - &real->tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY | O_CLOEXEC, &real->tmpf, + error)) return FALSE; ot_checksum_init (&real->checksum); real->expected_checksum = g_strdup (expected_checksum); @@ -559,22 +507,19 @@ _ostree_repo_bare_content_open (OstreeRepo *self, real->xattrs = xattrs ? g_variant_ref (xattrs) : NULL; /* Initialize the checksum with the header info */ - g_autoptr(GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); - g_autoptr(GBytes) header = _ostree_file_header_new (finfo, xattrs); + g_autoptr (GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); + g_autoptr (GBytes) header = _ostree_file_header_new (finfo, xattrs); ot_checksum_update_bytes (&real->checksum, header); return TRUE; } gboolean -_ostree_repo_bare_content_write (OstreeRepo *repo, - OstreeRepoBareContent *barewrite, - const guint8 *buf, - size_t len, - GCancellable *cancellable, - GError **error) +_ostree_repo_bare_content_write (OstreeRepo *repo, OstreeRepoBareContent *barewrite, + const guint8 *buf, size_t len, GCancellable *cancellable, + GError **error) { - OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent*) barewrite; + OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent *)barewrite; g_assert (real->initialized); ot_checksum_update (&real->checksum, buf, len); if (glnx_loop_write (real->tmpf.fd, buf, len) < 0) @@ -583,14 +528,11 @@ _ostree_repo_bare_content_write (OstreeRepo *repo, } gboolean -_ostree_repo_bare_content_commit (OstreeRepo *self, - OstreeRepoBareContent *barewrite, - char *checksum_buf, - size_t buflen, - GCancellable *cancellable, - GError **error) +_ostree_repo_bare_content_commit (OstreeRepo *self, OstreeRepoBareContent *barewrite, + char *checksum_buf, size_t buflen, GCancellable *cancellable, + GError **error) { - OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent*) barewrite; + OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent *)barewrite; g_assert (real->initialized); if ((self->min_free_space_percent > 0 || self->min_free_space_mb > 0) && self->in_transaction) @@ -616,16 +558,13 @@ _ostree_repo_bare_content_commit (OstreeRepo *self, ot_checksum_get_hexdigest (&real->checksum, checksum_buf, buflen); - if (real->expected_checksum && - !_ostree_compare_object_checksum (OSTREE_OBJECT_TYPE_FILE, - real->expected_checksum, checksum_buf, - error)) + if (real->expected_checksum + && !_ostree_compare_object_checksum (OSTREE_OBJECT_TYPE_FILE, real->expected_checksum, + checksum_buf, error)) return FALSE; - if (!commit_loose_regfile_object (self, checksum_buf, - &real->tmpf, real->uid, real->gid, - real->mode, real->xattrs, - cancellable, error)) + if (!commit_loose_regfile_object (self, checksum_buf, &real->tmpf, real->uid, real->gid, + real->mode, real->xattrs, cancellable, error)) return FALSE; /* Let's have a guarantee that after commit the object is cleaned up */ @@ -636,7 +575,7 @@ _ostree_repo_bare_content_commit (OstreeRepo *self, void _ostree_repo_bare_content_cleanup (OstreeRepoBareContent *regwrite) { - OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent*) regwrite; + OstreeRealRepoBareContent *real = (OstreeRealRepoBareContent *)regwrite; if (!real->initialized) return; glnx_tmpfile_clear (&real->tmpf); @@ -651,16 +590,15 @@ _ostree_repo_bare_content_cleanup (OstreeRepoBareContent *regwrite) * and content objects in all bare-type repos. */ static gboolean -create_regular_tmpfile_linkable_with_content (OstreeRepo *self, - guint64 length, - GInputStream *input, - GLnxTmpfile *out_tmpf, - GCancellable *cancellable, +create_regular_tmpfile_linkable_with_content (OstreeRepo *self, guint64 length, GInputStream *input, + GLnxTmpfile *out_tmpf, GCancellable *cancellable, GError **error) { - g_auto(GLnxTmpfile) tmpf = { 0, }; - if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC, - &tmpf, error)) + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY | O_CLOEXEC, &tmpf, + error)) return FALSE; if (!glnx_try_fallocate (tmpf.fd, 0, length, error)) @@ -668,7 +606,7 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self, if (G_IS_FILE_DESCRIPTOR_BASED (input)) { - int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input); + int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased *)input); if (glnx_regfile_copy_bytes (infd, tmpf.fd, (off_t)length) < 0) return glnx_throw_errno_prefix (error, "regfile copy"); } @@ -679,16 +617,20 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self, * e.g. 10 bytes but is actually gigabytes. * - Due to GLib bugs that pointlessly calls `poll()` on the output fd for every write */ - char buf[8192]; + gsize buf_size = MIN (length, 1048576); + g_autofree gchar *buf = g_malloc (buf_size); guint64 remaining = length; while (remaining > 0) { - const gssize bytes_read = - g_input_stream_read (input, buf, MIN (remaining, sizeof (buf)), cancellable, error); + const gssize bytes_read + = g_input_stream_read (input, buf, MIN (remaining, buf_size), cancellable, error); if (bytes_read < 0) return FALSE; else if (bytes_read == 0) - return glnx_throw (error, "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " bytes remaining", remaining, length); + return glnx_throw (error, + "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT + " bytes remaining", + remaining, length); if (glnx_loop_write (tmpf.fd, buf, bytes_read) < 0) return glnx_throw_errno_prefix (error, "write"); remaining -= bytes_read; @@ -698,7 +640,8 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self, if (!glnx_fchmod (tmpf.fd, 0644, error)) return FALSE; - *out_tmpf = tmpf; tmpf.initialized = FALSE; + *out_tmpf = tmpf; + tmpf.initialized = FALSE; return TRUE; } @@ -709,17 +652,20 @@ _check_support_reflink (OstreeRepo *dest, gboolean *supported, GError **error) if (g_atomic_int_get (&dest->fs_support_reflink) == 0) { glnx_autofd int src_fd = -1; - g_auto(GLnxTmpfile) dest_tmpf = { 0, }; + g_auto (GLnxTmpfile) dest_tmpf = { + 0, + }; if (!glnx_openat_rdonly (dest->repo_dir_fd, "config", TRUE, &src_fd, error)) return FALSE; - if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (dest), ".", O_WRONLY|O_CLOEXEC, + if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (dest), ".", O_WRONLY | O_CLOEXEC, &dest_tmpf, error)) return FALSE; if (ioctl (dest_tmpf.fd, FICLONE, src_fd) == 0) g_atomic_int_set (&dest->fs_support_reflink, 1); - else if (errno == EOPNOTSUPP) /* Ignore other kind of errors as they might be temporary failures */ + else if (errno + == EOPNOTSUPP) /* Ignore other kind of errors as they might be temporary failures */ g_atomic_int_set (&dest->fs_support_reflink, -1); } *supported = g_atomic_int_get (&dest->fs_support_reflink) >= 0; @@ -727,12 +673,8 @@ _check_support_reflink (OstreeRepo *dest, gboolean *supported, GError **error) } static gboolean -_create_payload_link (OstreeRepo *self, - const char *checksum, - const char *payload_checksum, - GFileInfo *file_info, - GCancellable *cancellable, - GError **error) +_create_payload_link (OstreeRepo *self, const char *checksum, const char *payload_checksum, + GFileInfo *file_info, GCancellable *cancellable, GError **error) { gboolean reflinks_supported = FALSE; @@ -743,7 +685,8 @@ _create_payload_link (OstreeRepo *self, return TRUE; if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR - || !G_IN_SET(self->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER, OSTREE_REPO_MODE_BARE_USER_ONLY)) + || !G_IN_SET (self->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER, + OSTREE_REPO_MODE_BARE_USER_ONLY)) return TRUE; if (payload_checksum == NULL || g_file_info_get_size (file_info) < self->payload_link_threshold) @@ -751,7 +694,8 @@ _create_payload_link (OstreeRepo *self, char target_buf[_OSTREE_LOOSE_PATH_MAX + _OSTREE_PAYLOAD_LINK_PREFIX_LEN]; strcpy (target_buf, _OSTREE_PAYLOAD_LINK_PREFIX); - _ostree_loose_path (target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN, checksum, OSTREE_OBJECT_TYPE_FILE, self->mode); + _ostree_loose_path (target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN, checksum, + OSTREE_OBJECT_TYPE_FILE, self->mode); if (symlinkat (target_buf, commit_tmp_dfd (self), payload_checksum) < 0) { @@ -760,8 +704,10 @@ _create_payload_link (OstreeRepo *self, } else { - g_auto(OtCleanupUnlinkat) tmp_unlinker = { commit_tmp_dfd (self), g_strdup (payload_checksum) }; - if (!commit_path_final (self, payload_checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, &tmp_unlinker, cancellable, error)) + g_auto (OtCleanupUnlinkat) tmp_unlinker + = { commit_tmp_dfd (self), g_strdup (payload_checksum) }; + if (!commit_path_final (self, payload_checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, + &tmp_unlinker, cancellable, error)) return FALSE; } @@ -769,17 +715,14 @@ _create_payload_link (OstreeRepo *self, } static gboolean -_import_payload_link (OstreeRepo *dest_repo, - OstreeRepo *src_repo, - const char *checksum, - GCancellable *cancellable, - GError **error) +_import_payload_link (OstreeRepo *dest_repo, OstreeRepo *src_repo, const char *checksum, + GCancellable *cancellable, GError **error) { gboolean reflinks_supported = FALSE; g_autofree char *payload_checksum = NULL; - g_autoptr(GInputStream) is = NULL; + g_autoptr (GInputStream) is = NULL; glnx_unref_object OtChecksumInstream *checksum_payload = NULL; - g_autoptr(GFileInfo) file_info = NULL; + g_autoptr (GFileInfo) file_info = NULL; /* The two repositories are on different devices */ if (src_repo->device != dest_repo->device) @@ -791,7 +734,8 @@ _import_payload_link (OstreeRepo *dest_repo, if (!reflinks_supported) return TRUE; - if (!G_IN_SET(dest_repo->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER, OSTREE_REPO_MODE_BARE_USER_ONLY)) + if (!G_IN_SET (dest_repo->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER, + OSTREE_REPO_MODE_BARE_USER_ONLY)) return TRUE; if (!ostree_repo_load_file (src_repo, checksum, &is, &file_info, NULL, cancellable, error)) @@ -807,7 +751,7 @@ _import_payload_link (OstreeRepo *dest_repo, while (remaining) { char buf[8192]; - gssize ret = g_input_stream_read ((GInputStream *) checksum_payload, buf, + gssize ret = g_input_stream_read ((GInputStream *)checksum_payload, buf, MIN (sizeof (buf), remaining), cancellable, error); if (ret < 0) return FALSE; @@ -815,17 +759,14 @@ _import_payload_link (OstreeRepo *dest_repo, } payload_checksum = ot_checksum_instream_get_string (checksum_payload); - return _create_payload_link (dest_repo, checksum, payload_checksum, file_info, cancellable, error); + return _create_payload_link (dest_repo, checksum, payload_checksum, file_info, cancellable, + error); } static gboolean -_try_clone_from_payload_link (OstreeRepo *self, - OstreeRepo *dest_repo, - const char *payload_checksum, - GFileInfo *file_info, - GLnxTmpfile *tmpf, - GCancellable *cancellable, - GError **error) +_try_clone_from_payload_link (OstreeRepo *self, OstreeRepo *dest_repo, const char *payload_checksum, + GFileInfo *file_info, GLnxTmpfile *tmpf, GCancellable *cancellable, + GError **error) { gboolean reflinks_supported = FALSE; int dfd_searches[] = { -1, self->objects_dir_fd }; @@ -848,13 +789,14 @@ _try_clone_from_payload_link (OstreeRepo *self, char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; char loose_path_target_buf[_OSTREE_LOOSE_PATH_MAX]; char target_buf[_OSTREE_LOOSE_PATH_MAX + _OSTREE_PAYLOAD_LINK_PREFIX_LEN]; - char target_checksum[OSTREE_SHA256_STRING_LEN+1]; + char target_checksum[OSTREE_SHA256_STRING_LEN + 1]; int dfd = dfd_searches[i]; ssize_t size; if (dfd == -1) continue; - _ostree_loose_path (loose_path_buf, payload_checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, self->mode); + _ostree_loose_path (loose_path_buf, payload_checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, + self->mode); size = TEMP_FAILURE_RETRY (readlinkat (dfd, loose_path_buf, target_buf, sizeof (target_buf))); if (size < 0) @@ -867,32 +809,33 @@ _try_clone_from_payload_link (OstreeRepo *self, if (size < OSTREE_SHA256_STRING_LEN + _OSTREE_PAYLOAD_LINK_PREFIX_LEN) return glnx_throw (error, "invalid data size for %s", loose_path_buf); - sprintf (target_checksum, "%.2s%.62s", target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN, target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN + 3); + sprintf (target_checksum, "%.2s%.62s", target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN, + target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN + 3); - _ostree_loose_path (loose_path_target_buf, target_checksum, OSTREE_OBJECT_TYPE_FILE, self->mode); + _ostree_loose_path (loose_path_target_buf, target_checksum, OSTREE_OBJECT_TYPE_FILE, + self->mode); if (!ot_openat_ignore_enoent (dfd, loose_path_target_buf, &fdf, error)) return FALSE; if (fdf < 0) { - /* If the link is referring to an object that doesn't exist anymore in the repository, just unlink it. */ + /* If the link is referring to an object that doesn't exist anymore in the repository, + * just unlink it. */ if (!glnx_unlinkat (dfd, loose_path_buf, 0, error)) return FALSE; } else { /* This undoes all of the previous writes; we want to generate reflinked data. */ - if (ftruncate (tmpf->fd, 0) < 0) - return glnx_throw_errno_prefix (error, "ftruncate"); - - if (glnx_regfile_copy_bytes (fdf, tmpf->fd, -1) < 0) - return glnx_throw_errno_prefix (error, "regfile copy"); + if (ioctl (tmpf->fd, FICLONE, fdf) < 0) + return glnx_throw_errno_prefix (error, "FICLONE"); return TRUE; } } if (self->parent_repo) - return _try_clone_from_payload_link (self->parent_repo, dest_repo, payload_checksum, file_info, tmpf, cancellable, error); + return _try_clone_from_payload_link (self->parent_repo, dest_repo, payload_checksum, file_info, + tmpf, cancellable, error); return TRUE; } @@ -904,14 +847,9 @@ _try_clone_from_payload_link (OstreeRepo *self, * knows the checksum. */ static gboolean -write_content_object (OstreeRepo *self, - const char *expected_checksum, - GInputStream *input, - GFileInfo *file_info, - GVariant *xattrs, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +write_content_object (OstreeRepo *self, const char *expected_checksum, GInputStream *input, + GFileInfo *file_info, GVariant *xattrs, guchar **out_csum, + GCancellable *cancellable, GError **error) { g_assert (expected_checksum != NULL || out_csum != NULL); @@ -921,12 +859,12 @@ write_content_object (OstreeRepo *self, return FALSE; OstreeRepoMode repo_mode = ostree_repo_get_mode (self); - if (repo_mode == OSTREE_REPO_MODE_BARE_SPLIT_XATTRS && - g_getenv ("OSTREE_EXP_WRITE_BARE_SPLIT_XATTRS") == NULL) + if (repo_mode == OSTREE_REPO_MODE_BARE_SPLIT_XATTRS + && g_getenv ("OSTREE_EXP_WRITE_BARE_SPLIT_XATTRS") == NULL) return glnx_throw (error, "Not allowed due to repo mode"); - GInputStream *file_input; /* Unowned alias */ - g_autoptr(GInputStream) file_input_owned = NULL; /* We need a temporary for bare-user symlinks */ + GInputStream *file_input; /* Unowned alias */ + g_autoptr (GInputStream) file_input_owned = NULL; /* We need a temporary for bare-user symlinks */ glnx_unref_object OtChecksumInstream *checksum_input = NULL; glnx_unref_object OtChecksumInstream *checksum_payload_input = NULL; const GFileType object_file_type = g_file_info_get_file_type (file_info); @@ -939,37 +877,41 @@ write_content_object (OstreeRepo *self, * checksum over the data we actually use. */ gboolean reflinks_supported = FALSE; - g_autoptr(GBytes) header = _ostree_file_header_new (file_info, xattrs); + g_autoptr (GBytes) header = _ostree_file_header_new (file_info, xattrs); size_t len; const guint8 *buf = g_bytes_get_data (header, &len); /* Give a null input if there's no content */ - g_autoptr(GInputStream) null_input = NULL; + g_autoptr (GInputStream) null_input = NULL; if (!input) { null_input = input = g_memory_input_stream_new_from_data ("", 0, NULL); - (void) null_input; /* quiet static analysis */ + (void)null_input; /* quiet static analysis */ } - checksum_input = ot_checksum_instream_new_with_start (input, G_CHECKSUM_SHA256, - buf, len); + checksum_input = ot_checksum_instream_new_with_start (input, G_CHECKSUM_SHA256, buf, len); if (!_check_support_reflink (self, &reflinks_supported, error)) return FALSE; - if (xattrs == NULL || !G_IN_SET(self->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER, OSTREE_REPO_MODE_BARE_USER_ONLY) || object_file_type != G_FILE_TYPE_REGULAR || - !reflinks_supported) - file_input = (GInputStream*)checksum_input; + if (xattrs == NULL + || !G_IN_SET (self->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER, + OSTREE_REPO_MODE_BARE_USER_ONLY) + || object_file_type != G_FILE_TYPE_REGULAR || !reflinks_supported) + file_input = (GInputStream *)checksum_input; else { /* The payload checksum-input reads from the full object checksum-input; this * means it skips the header. */ - checksum_payload_input = ot_checksum_instream_new ((GInputStream*)checksum_input, G_CHECKSUM_SHA256); - file_input = (GInputStream*)checksum_payload_input; + checksum_payload_input + = ot_checksum_instream_new ((GInputStream *)checksum_input, G_CHECKSUM_SHA256); + file_input = (GInputStream *)checksum_payload_input; } } else file_input = input; + (void)file_input_owned; // Conditionally owned + gboolean phys_object_is_symlink = FALSE; switch (object_file_type) { @@ -989,7 +931,7 @@ write_content_object (OstreeRepo *self, if (repo_mode == OSTREE_REPO_MODE_BARE_USER && object_file_type == G_FILE_TYPE_SYMBOLIC_LINK) { const char *target_str = g_file_info_get_symlink_target (file_info); - g_autoptr(GBytes) target = g_bytes_new (target_str, strlen (target_str) + 1); + g_autoptr (GBytes) target = g_bytes_new (target_str, strlen (target_str) + 1); /* Include the terminating zero so we can e.g. mmap this file */ file_input = file_input_owned = g_memory_input_stream_new_from_bytes (target); @@ -1000,6 +942,8 @@ write_content_object (OstreeRepo *self, else size = 0; + (void)file_input_owned; // Conditionally owned + /* Free space check; only applies during transactions */ if ((self->min_free_space_percent > 0 || self->min_free_space_mb > 0) && self->in_transaction) { @@ -1027,44 +971,47 @@ write_content_object (OstreeRepo *self, * * We use GLnxTmpfile for regular files, and OtCleanupUnlinkat for symlinks. */ - g_auto(OtCleanupUnlinkat) tmp_unlinker = { commit_tmp_dfd (self), NULL }; - g_auto(GLnxTmpfile) tmpf = { 0, }; + g_auto (OtCleanupUnlinkat) tmp_unlinker = { commit_tmp_dfd (self), NULL }; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; goffset unpacked_size = 0; /* Is it a symlink physically? */ if (phys_object_is_symlink) { /* This will not be hit for bare-user or archive */ - g_assert (self->mode == OSTREE_REPO_MODE_BARE || self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY); + g_assert (self->mode == OSTREE_REPO_MODE_BARE + || self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY); if (!_ostree_make_temporary_symlink_at (commit_tmp_dfd (self), g_file_info_get_symlink_target (file_info), - &tmp_unlinker.path, - cancellable, error)) + &tmp_unlinker.path, cancellable, error)) return FALSE; } else if (repo_mode != OSTREE_REPO_MODE_ARCHIVE) { - if (!create_regular_tmpfile_linkable_with_content (self, size, file_input, - &tmpf, cancellable, error)) + if (!create_regular_tmpfile_linkable_with_content (self, size, file_input, &tmpf, cancellable, + error)) return FALSE; } else { - g_autoptr(GConverter) zlib_compressor = NULL; - g_autoptr(GOutputStream) compressed_out_stream = NULL; - g_autoptr(GOutputStream) temp_out = NULL; + g_autoptr (GConverter) zlib_compressor = NULL; + g_autoptr (GOutputStream) compressed_out_stream = NULL; + g_autoptr (GOutputStream) temp_out = NULL; g_assert (repo_mode == OSTREE_REPO_MODE_ARCHIVE); - if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC, - &tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY | O_CLOEXEC, &tmpf, + error)) return FALSE; temp_out = g_unix_output_stream_new (tmpf.fd, FALSE); - g_autoptr(GBytes) file_meta_header = _ostree_zlib_file_header_new (file_info, xattrs); + g_autoptr (GBytes) file_meta_header = _ostree_zlib_file_header_new (file_info, xattrs); gsize file_meta_len; - const guint8* file_meta_buf = g_bytes_get_data (file_meta_header, &file_meta_len); + const guint8 *file_meta_buf = g_bytes_get_data (file_meta_header, &file_meta_len); - { gsize bytes_written; + { + gsize bytes_written; if (!g_output_stream_write_all (temp_out, file_meta_buf, file_meta_len, &bytes_written, cancellable, error)) return FALSE; @@ -1072,13 +1019,14 @@ write_content_object (OstreeRepo *self, if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { - zlib_compressor = (GConverter*)g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW, self->zlib_compression_level); + zlib_compressor = (GConverter *)g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW, + self->zlib_compression_level); compressed_out_stream = g_converter_output_stream_new (temp_out, zlib_compressor); /* Don't close the base; we'll do that later */ - g_filter_output_stream_set_close_base_stream ((GFilterOutputStream*)compressed_out_stream, FALSE); + g_filter_output_stream_set_close_base_stream ( + (GFilterOutputStream *)compressed_out_stream, FALSE); - if (g_output_stream_splice (compressed_out_stream, file_input, - 0, cancellable, error) < 0) + if (g_output_stream_splice (compressed_out_stream, file_input, 0, cancellable, error) < 0) return FALSE; unpacked_size = g_file_info_get_size (file_info); @@ -1106,10 +1054,11 @@ write_content_object (OstreeRepo *self, actual_checksum = actual_checksum_owned = ot_checksum_instream_get_string (checksum_input); if (expected_checksum) { - if (!_ostree_compare_object_checksum (OSTREE_OBJECT_TYPE_FILE, expected_checksum, actual_checksum, - error)) + if (!_ostree_compare_object_checksum (OSTREE_OBJECT_TYPE_FILE, expected_checksum, + actual_checksum, error)) return FALSE; } + (void)actual_checksum_owned; // Just used to autofree if (checksum_payload_input) actual_payload_checksum = ot_checksum_instream_get_string (checksum_payload_input); @@ -1118,24 +1067,23 @@ write_content_object (OstreeRepo *self, g_assert (actual_checksum != NULL); /* Pacify static analysis */ /* Update size metadata if configured and entry missing */ - if (self->generate_sizes && - !repo_has_size_entry (self, OSTREE_OBJECT_TYPE_FILE, actual_checksum)) + if (self->generate_sizes && !repo_has_size_entry (self, OSTREE_OBJECT_TYPE_FILE, actual_checksum)) { struct stat stbuf; if (!glnx_fstat (tmpf.fd, &stbuf, error)) return FALSE; - repo_store_size_entry (self, OSTREE_OBJECT_TYPE_FILE, actual_checksum, - unpacked_size, stbuf.st_size); + repo_store_size_entry (self, OSTREE_OBJECT_TYPE_FILE, actual_checksum, unpacked_size, + stbuf.st_size); } /* See whether or not we have the object, now that we know the * checksum. */ gboolean have_obj; - if (!_ostree_repo_has_loose_object (self, actual_checksum, OSTREE_OBJECT_TYPE_FILE, - &have_obj, cancellable, error)) + if (!_ostree_repo_has_loose_object (self, actual_checksum, OSTREE_OBJECT_TYPE_FILE, &have_obj, + cancellable, error)) return FALSE; /* If we already have it, just update the stats. */ if (have_obj) @@ -1144,7 +1092,8 @@ write_content_object (OstreeRepo *self, self->txn.stats.content_objects_total++; g_mutex_unlock (&self->txn_lock); - if (!_create_payload_link (self, actual_checksum, actual_payload_checksum, file_info, cancellable, error)) + if (!_create_payload_link (self, actual_checksum, actual_payload_checksum, file_info, + cancellable, error)) return FALSE; if (out_csum) @@ -1171,15 +1120,16 @@ write_content_object (OstreeRepo *self, * Note, this does not apply for bare-user repos, as they store symlinks * as regular files. */ - if (G_UNLIKELY (fchownat (tmp_unlinker.dfd, tmp_unlinker.path, - uid, gid, AT_SYMLINK_NOFOLLOW) == -1)) + if (G_UNLIKELY ( + fchownat (tmp_unlinker.dfd, tmp_unlinker.path, uid, gid, AT_SYMLINK_NOFOLLOW) + == -1)) return glnx_throw_errno_prefix (error, "fchownat"); if (xattrs != NULL) { ot_security_smack_reset_dfd_name (tmp_unlinker.dfd, tmp_unlinker.path); - if (!glnx_dfd_name_set_all_xattrs (tmp_unlinker.dfd, tmp_unlinker.path, - xattrs, cancellable, error)) + if (!glnx_dfd_name_set_all_xattrs (tmp_unlinker.dfd, tmp_unlinker.path, xattrs, + cancellable, error)) return FALSE; } } @@ -1189,32 +1139,34 @@ write_content_object (OstreeRepo *self, g_assert_not_reached (); } - if (!commit_path_final (self, actual_checksum, OSTREE_OBJECT_TYPE_FILE, - &tmp_unlinker, cancellable, error)) + if (!commit_path_final (self, actual_checksum, OSTREE_OBJECT_TYPE_FILE, &tmp_unlinker, + cancellable, error)) return FALSE; } else { /* Check if a file with the same payload is present in the repository, and in case try to reflink it */ - if (actual_payload_checksum && !_try_clone_from_payload_link (self, self, actual_payload_checksum, file_info, &tmpf, cancellable, error)) + if (actual_payload_checksum + && !_try_clone_from_payload_link (self, self, actual_payload_checksum, file_info, &tmpf, + cancellable, error)) return FALSE; /* This path is for regular files */ - if (!commit_loose_regfile_object (self, actual_checksum, &tmpf, - uid, gid, mode, - xattrs, + if (!commit_loose_regfile_object (self, actual_checksum, &tmpf, uid, gid, mode, xattrs, cancellable, error)) return FALSE; - if (!_create_payload_link (self, actual_checksum, actual_payload_checksum, file_info, cancellable, error)) + if (!_create_payload_link (self, actual_checksum, actual_payload_checksum, file_info, + cancellable, error)) return FALSE; } /* Update statistics */ g_mutex_lock (&self->txn_lock); self->txn.stats.content_objects_written++; - self->txn.stats.content_bytes_written += g_file_info_get_size (file_info); + if (g_file_info_has_attribute (file_info, "standard::size")) + self->txn.stats.content_bytes_written += g_file_info_get_size (file_info); self->txn.stats.content_objects_total++; g_mutex_unlock (&self->txn_lock); @@ -1240,22 +1192,19 @@ write_content_object (OstreeRepo *self, * security.selinux xattr on setuid binaries and the like to live on). */ static gboolean -adopt_and_commit_regfile (OstreeRepo *self, - int dfd, - const char *name, - GFileInfo *finfo, - GVariant *xattrs, - char *out_checksum_buf, - GCancellable *cancellable, - GError **error) +adopt_and_commit_regfile (OstreeRepo *self, int dfd, const char *name, GFileInfo *finfo, + GVariant *xattrs, char *out_checksum_buf, GCancellable *cancellable, + GError **error) { g_assert (G_IN_SET (self->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER_ONLY)); GLNX_AUTO_PREFIX_ERROR ("Commit regfile (adopt)", error); - g_autoptr(GBytes) header = _ostree_file_header_new (finfo, xattrs); + g_autoptr (GBytes) header = _ostree_file_header_new (finfo, xattrs); - g_auto(OtChecksum) hasher = { 0, }; + g_auto (OtChecksum) hasher = { + 0, + }; ot_checksum_init (&hasher); ot_checksum_update_bytes (&hasher, header); @@ -1270,7 +1219,7 @@ adopt_and_commit_regfile (OstreeRepo *self, * Turns out bigger block size is better; down the line we should use their * same heuristics. */ - char buf[16*1024]; + char buf[16 * 1024]; while (TRUE) { ssize_t bytes_read = read (fd, buf, sizeof (buf)); @@ -1279,10 +1228,10 @@ adopt_and_commit_regfile (OstreeRepo *self, if (bytes_read == 0) break; - ot_checksum_update (&hasher, (guint8*)buf, bytes_read); + ot_checksum_update (&hasher, (guint8 *)buf, bytes_read); } - ot_checksum_get_hexdigest (&hasher, out_checksum_buf, OSTREE_SHA256_STRING_LEN+1); + ot_checksum_get_hexdigest (&hasher, out_checksum_buf, OSTREE_SHA256_STRING_LEN + 1); const char *checksum = out_checksum_buf; /* TODO: dedup this with commit_path_final() */ @@ -1293,8 +1242,7 @@ adopt_and_commit_regfile (OstreeRepo *self, const guint64 src_inode = g_file_info_get_attribute_uint64 (finfo, "unix::inode"); int dest_dfd = commit_dest_dfd (self); - if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, loose_path, - cancellable, error)) + if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, loose_path, cancellable, error)) return FALSE; struct stat dest_stbuf; @@ -1307,9 +1255,7 @@ adopt_and_commit_regfile (OstreeRepo *self, * "If oldpath and newpath are existing hard links referring to the same file, * then rename() does nothing, and returns a success status." */ - if (errno != ENOENT - && src_dev == dest_stbuf.st_dev - && src_inode == dest_stbuf.st_ino) + if (errno != ENOENT && src_dev == dest_stbuf.st_dev && src_inode == dest_stbuf.st_ino) { if (!glnx_unlinkat (dfd, name, 0, error)) return FALSE; @@ -1339,13 +1285,8 @@ adopt_and_commit_regfile (OstreeRepo *self, /* Main driver for writing a metadata (non-content) object. */ static gboolean -write_metadata_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *expected_checksum, - GBytes *buf, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +write_metadata_object (OstreeRepo *self, OstreeObjectType objtype, const char *expected_checksum, + GBytes *buf, guchar **out_csum, GCancellable *cancellable, GError **error) { g_assert (expected_checksum != NULL || out_csum != NULL); @@ -1364,7 +1305,7 @@ write_metadata_object (OstreeRepo *self, * *original* sha256 to say what commit was being killed. */ const gboolean is_tombstone = (objtype == OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT); - char actual_checksum[OSTREE_SHA256_STRING_LEN+1]; + char actual_checksum[OSTREE_SHA256_STRING_LEN + 1]; if (is_tombstone) { g_assert (expected_checksum != NULL); @@ -1372,15 +1313,17 @@ write_metadata_object (OstreeRepo *self, } else { - g_auto(OtChecksum) checksum = { 0, }; + g_auto (OtChecksum) checksum = { + 0, + }; ot_checksum_init (&checksum); gsize len; - const guint8*bufdata = g_bytes_get_data (buf, &len); + const guint8 *bufdata = g_bytes_get_data (buf, &len); ot_checksum_update (&checksum, bufdata, len); ot_checksum_get_hexdigest (&checksum, actual_checksum, sizeof (actual_checksum)); gboolean have_obj; - if (!_ostree_repo_has_loose_object (self, actual_checksum, objtype, &have_obj, - cancellable, error)) + if (!_ostree_repo_has_loose_object (self, actual_checksum, objtype, &have_obj, cancellable, + error)) return FALSE; /* If we already have the object, we just need to update the tried-to-commit * stat for metadata and be done here. @@ -1388,8 +1331,7 @@ write_metadata_object (OstreeRepo *self, if (have_obj) { /* Update size metadata if needed */ - if (self->generate_sizes && - !repo_has_size_entry (self, objtype, actual_checksum)) + if (self->generate_sizes && !repo_has_size_entry (self, objtype, actual_checksum)) repo_store_size_entry (self, objtype, actual_checksum, len, len); g_mutex_lock (&self->txn_lock); @@ -1414,14 +1356,15 @@ write_metadata_object (OstreeRepo *self, const guint8 *bufp = g_bytes_get_data (buf, &len); /* Update size metadata if needed */ - if (self->generate_sizes && - !repo_has_size_entry (self, objtype, actual_checksum)) + if (self->generate_sizes && !repo_has_size_entry (self, objtype, actual_checksum)) repo_store_size_entry (self, objtype, actual_checksum, len, len); /* Write the metadata to a temporary file */ - g_auto(GLnxTmpfile) tmpf = { 0, }; - if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC, - &tmpf, error)) + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY | O_CLOEXEC, &tmpf, + error)) return FALSE; if (!glnx_try_fallocate (tmpf.fd, 0, len, error)) return FALSE; @@ -1431,8 +1374,7 @@ write_metadata_object (OstreeRepo *self, return FALSE; /* And commit it into place */ - if (!_ostree_repo_commit_tmpf_final (self, actual_checksum, objtype, - &tmpf, cancellable, error)) + if (!_ostree_repo_commit_tmpf_final (self, actual_checksum, objtype, &tmpf, cancellable, error)) return FALSE; if (objtype == OSTREE_OBJECT_TYPE_COMMIT) @@ -1440,11 +1382,8 @@ write_metadata_object (OstreeRepo *self, GError *local_error = NULL; /* If we are writing a commit, be sure there is no tombstone for it. We may have deleted the commit and now we are trying to pull it again. */ - if (!ostree_repo_delete_object (self, - OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, - actual_checksum, - cancellable, - &local_error)) + if (!ostree_repo_delete_object (self, OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, actual_checksum, + cancellable, &local_error)) { if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) g_clear_error (&local_error); @@ -1471,21 +1410,21 @@ write_metadata_object (OstreeRepo *self, * (device,inode) → checksum map. */ static gboolean -scan_one_loose_devino (OstreeRepo *self, - int object_dir_fd, - GHashTable *devino_cache, - GCancellable *cancellable, - GError **error) +scan_one_loose_devino (OstreeRepo *self, int object_dir_fd, GHashTable *devino_cache, + GCancellable *cancellable, GError **error) { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - if (!glnx_dirfd_iterator_init_at (object_dir_fd, ".", FALSE, - &dfd_iter, error)) + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + if (!glnx_dirfd_iterator_init_at (object_dir_fd, ".", FALSE, &dfd_iter, error)) return FALSE; while (TRUE) { struct dirent *dent; - g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) child_dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error)) return FALSE; @@ -1496,8 +1435,7 @@ scan_one_loose_devino (OstreeRepo *self, if (strlen (dent->d_name) != 2) continue; - if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, - &child_dfd_iter, error)) + if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, &child_dfd_iter, error)) return FALSE; while (TRUE) @@ -1534,8 +1472,8 @@ scan_one_loose_devino (OstreeRepo *self, continue; struct stat stbuf; - if (!glnx_fstatat (child_dfd_iter.fd, child_dent->d_name, - &stbuf, AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat (child_dfd_iter.fd, child_dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, + error)) return FALSE; OstreeDevIno *key = g_new (OstreeDevIno, 1); @@ -1543,7 +1481,7 @@ scan_one_loose_devino (OstreeRepo *self, key->ino = stbuf.st_ino; memcpy (key->checksum, dent->d_name, 2); memcpy (key->checksum + 2, name, 62); - key->checksum[sizeof(key->checksum)-1] = '\0'; + key->checksum[sizeof (key->checksum) - 1] = '\0'; g_hash_table_add (devino_cache, key); } } @@ -1553,10 +1491,8 @@ scan_one_loose_devino (OstreeRepo *self, /* Used by ostree_repo_scan_hardlinks(); see that function for more information. */ static gboolean -scan_loose_devino (OstreeRepo *self, - GHashTable *devino_cache, - GCancellable *cancellable, - GError **error) +scan_loose_devino (OstreeRepo *self, GHashTable *devino_cache, GCancellable *cancellable, + GError **error) { if (self->parent_repo) { @@ -1564,16 +1500,14 @@ scan_loose_devino (OstreeRepo *self, return FALSE; } - if (self->mode == OSTREE_REPO_MODE_ARCHIVE && - self->uncompressed_objects_dir_fd != -1) + if (self->mode == OSTREE_REPO_MODE_ARCHIVE && self->uncompressed_objects_dir_fd != -1) { if (!scan_one_loose_devino (self, self->uncompressed_objects_dir_fd, devino_cache, cancellable, error)) return FALSE; } - if (!scan_one_loose_devino (self, self->objects_dir_fd, - devino_cache, cancellable, error)) + if (!scan_one_loose_devino (self, self->objects_dir_fd, devino_cache, cancellable, error)) return FALSE; return TRUE; @@ -1582,10 +1516,8 @@ scan_loose_devino (OstreeRepo *self, /* Loook up a (device,inode) pair in our cache, and see if it maps to a known * checksum. */ static const char * -devino_cache_lookup (OstreeRepo *self, - OstreeRepoCommitModifier *modifier, - guint32 device, - guint32 inode) +devino_cache_lookup (OstreeRepo *self, OstreeRepoCommitModifier *modifier, guint32 device, + guint64 inode) { OstreeDevIno dev_ino_key; OstreeDevIno *dev_ino_val; @@ -1631,9 +1563,7 @@ devino_cache_lookup (OstreeRepo *self, * Multithreading: This function is *not* MT safe. */ gboolean -ostree_repo_scan_hardlinks (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +ostree_repo_scan_hardlinks (OstreeRepo *self, GCancellable *cancellable, GError **error) { g_assert (self != NULL); g_assert (OSTREE_IS_REPO (self)); @@ -1642,7 +1572,7 @@ ostree_repo_scan_hardlinks (OstreeRepo *self, return glnx_throw (error, "Failed to scan hardlinks, not in a transaction"); if (!self->loose_object_devino_hash) - self->loose_object_devino_hash = (GHashTable*)ostree_repo_devino_cache_new (); + self->loose_object_devino_hash = (GHashTable *)ostree_repo_devino_cache_new (); g_hash_table_remove_all (self->loose_object_devino_hash); return scan_loose_devino (self, self->loose_object_devino_hash, cancellable, error); } @@ -1675,10 +1605,8 @@ ostree_repo_scan_hardlinks (OstreeRepo *self, * active at a time. */ gboolean -ostree_repo_prepare_transaction (OstreeRepo *self, - gboolean *out_transaction_resume, - GCancellable *cancellable, - GError **error) +ostree_repo_prepare_transaction (OstreeRepo *self, gboolean *out_transaction_resume, + GCancellable *cancellable, GError **error) { g_assert (self != NULL); g_assert (OSTREE_IS_REPO (self)); @@ -1691,13 +1619,12 @@ ostree_repo_prepare_transaction (OstreeRepo *self, /* Set up to abort the transaction if we return early from this function. * We can't call _ostree_repo_auto_transaction_start() here, because that * would be a circular dependency; use the lower-level version instead. */ - g_autoptr(OstreeRepoAutoTransaction) txn = _ostree_repo_auto_transaction_new (self); + g_autoptr (OstreeRepoAutoTransaction) txn = _ostree_repo_auto_transaction_new (self); g_assert (txn != NULL); memset (&self->txn.stats, 0, sizeof (OstreeRepoTransactionStats)); - self->txn_locked = ostree_repo_lock_push (self, OSTREE_REPO_LOCK_SHARED, - cancellable, error); + self->txn_locked = ostree_repo_lock_push (self, OSTREE_REPO_LOCK_SHARED, cancellable, error); if (!self->txn_locked) return FALSE; @@ -1740,16 +1667,14 @@ ostree_repo_prepare_transaction (OstreeRepo *self, g_mutex_unlock (&self->txn_lock); gboolean ret_transaction_resume = FALSE; - if (!_ostree_repo_allocate_tmpdir (self->tmp_dir_fd, - self->stagedir_prefix, - &self->commit_stagedir, - &self->commit_stagedir_lock, - &ret_transaction_resume, - cancellable, error)) + if (!_ostree_repo_allocate_tmpdir (self->tmp_dir_fd, self->stagedir_prefix, + &self->commit_stagedir, &self->commit_stagedir_lock, + &ret_transaction_resume, cancellable, error)) return FALSE; /* Success: do not abort the transaction when returning. */ - txn->repo = NULL; (void) txn; + g_clear_object (&txn->repo); + (void)txn; if (out_transaction_resume) *out_transaction_resume = ret_transaction_resume; @@ -1758,15 +1683,15 @@ ostree_repo_prepare_transaction (OstreeRepo *self, /* Synchronize the directories holding the objects */ static gboolean -fsync_object_dirs (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +fsync_object_dirs (OstreeRepo *self, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("fsync objdirs", error); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (self->disable_fsync) - return TRUE; /* No fsync? Nothing to do then. */ + return TRUE; /* No fsync? Nothing to do then. */ if (!glnx_dirfd_iterator_init_at (self->objects_dir_fd, ".", FALSE, &dfd_iter, error)) return FALSE; @@ -1784,8 +1709,7 @@ fsync_object_dirs (OstreeRepo *self, continue; glnx_autofd int target_dir_fd = -1; - if (!glnx_opendirat (self->objects_dir_fd, dent->d_name, FALSE, - &target_dir_fd, error)) + if (!glnx_opendirat (self->objects_dir_fd, dent->d_name, FALSE, &target_dir_fd, error)) return FALSE; /* This synchronizes the directory to ensure all the objects we wrote * are there. We need to do this before removing the .commitpartial @@ -1809,12 +1733,12 @@ fsync_object_dirs (OstreeRepo *self, * https://github.com/ostreedev/ostree/issues/1184 */ static gboolean -rename_pending_loose_objects (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +rename_pending_loose_objects (OstreeRepo *self, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("rename pending", error); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (self->commit_stagedir.fd, ".", FALSE, &dfd_iter, error)) return FALSE; @@ -1835,9 +1759,10 @@ rename_pending_loose_objects (OstreeRepo *self, if (strlen (dent->d_name) != 2) continue; - g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, }; - if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, - &child_dfd_iter, error)) + g_auto (GLnxDirFdIterator) child_dfd_iter = { + 0, + }; + if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, &child_dfd_iter, error)) return FALSE; char loose_objpath[_OSTREE_LOOSE_PATH_MAX]; @@ -1855,14 +1780,14 @@ rename_pending_loose_objects (OstreeRepo *self, if (child_dent == NULL) break; - g_strlcpy (loose_objpath + 3, child_dent->d_name, sizeof (loose_objpath)-3); + g_strlcpy (loose_objpath + 3, child_dent->d_name, sizeof (loose_objpath) - 3); if (!_ostree_repo_ensure_loose_objdir_at (self->objects_dir_fd, loose_objpath, cancellable, error)) return FALSE; - if (!glnx_renameat (child_dfd_iter.fd, loose_objpath + 3, - self->objects_dir_fd, loose_objpath, error)) + if (!glnx_renameat (child_dfd_iter.fd, loose_objpath + 3, self->objects_dir_fd, + loose_objpath, error)) return FALSE; } } @@ -1874,16 +1799,15 @@ rename_pending_loose_objects (OstreeRepo *self, * ostree_repo_prepare_transaction(). */ static gboolean -cleanup_txn_dir (OstreeRepo *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +cleanup_txn_dir (OstreeRepo *self, int dfd, const char *path, GCancellable *cancellable, + GError **error) { const char *errprefix = glnx_strjoina ("Cleaning up txn dir ", path); GLNX_AUTO_PREFIX_ERROR (errprefix, error); - g_auto(GLnxLockFile) lockfile = { 0, }; + g_auto (GLnxLockFile) lockfile = { + 0, + }; gboolean did_lock; /* Try to lock, but if we don't get it, move on */ @@ -1916,14 +1840,14 @@ cleanup_txn_dir (OstreeRepo *self, * https://github.com/ostreedev/ostree/issues/713 */ static gboolean -cleanup_tmpdir (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +cleanup_tmpdir (OstreeRepo *self, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("tmpdir cleanup", error); const guint64 curtime_secs = g_get_real_time () / 1000000; - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (self->tmp_dir_fd, ".", TRUE, &dfd_iter, error)) return FALSE; @@ -1986,10 +1910,9 @@ ensure_txn_refs (OstreeRepo *self) if (self->txn.refs == NULL) self->txn.refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); if (self->txn.collection_refs == NULL) - self->txn.collection_refs = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - (GDestroyNotify) ostree_collection_ref_free, - g_free); + self->txn.collection_refs + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, g_free); } /** @@ -2011,11 +1934,8 @@ ensure_txn_refs (OstreeRepo *self) * Since: 2019.4 */ gboolean -ostree_repo_mark_commit_partial_reason (OstreeRepo *self, - const char *checksum, - gboolean is_partial, - OstreeRepoCommitState in_state, - GError **error) +ostree_repo_mark_commit_partial_reason (OstreeRepo *self, const char *checksum, gboolean is_partial, + OstreeRepoCommitState in_state, GError **error) { g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum); if (is_partial) @@ -2061,14 +1981,11 @@ ostree_repo_mark_commit_partial_reason (OstreeRepo *self, * Since: 2017.15 */ gboolean -ostree_repo_mark_commit_partial (OstreeRepo *self, - const char *checksum, - gboolean is_partial, - GError **error) +ostree_repo_mark_commit_partial (OstreeRepo *self, const char *checksum, gboolean is_partial, + GError **error) { return ostree_repo_mark_commit_partial_reason (self, checksum, is_partial, - OSTREE_REPO_COMMIT_STATE_NORMAL, - error); + OSTREE_REPO_COMMIT_STATE_NORMAL, error); } /** @@ -2084,9 +2001,7 @@ ostree_repo_mark_commit_partial (OstreeRepo *self, * Multithreading: Since v2017.15 this function is MT safe. */ void -ostree_repo_transaction_set_refspec (OstreeRepo *self, - const char *refspec, - const char *checksum) +ostree_repo_transaction_set_refspec (OstreeRepo *self, const char *refspec, const char *checksum) { g_assert (self != NULL); g_assert (OSTREE_IS_REPO (self)); @@ -2128,9 +2043,7 @@ ostree_repo_transaction_set_refspec (OstreeRepo *self, * Multithreading: Since v2017.15 this function is MT safe. */ void -ostree_repo_transaction_set_ref (OstreeRepo *self, - const char *remote, - const char *ref, +ostree_repo_transaction_set_ref (OstreeRepo *self, const char *remote, const char *ref, const char *checksum) { g_assert (self != NULL); @@ -2171,9 +2084,8 @@ ostree_repo_transaction_set_ref (OstreeRepo *self, * Since: 2018.6 */ void -ostree_repo_transaction_set_collection_ref (OstreeRepo *self, - const OstreeCollectionRef *ref, - const char *checksum) +ostree_repo_transaction_set_collection_ref (OstreeRepo *self, const OstreeCollectionRef *ref, + const char *checksum) { g_assert (self != NULL); g_assert (OSTREE_IS_REPO (self)); @@ -2186,8 +2098,8 @@ ostree_repo_transaction_set_collection_ref (OstreeRepo *self, g_mutex_lock (&self->txn_lock); ensure_txn_refs (self); - g_hash_table_replace (self->txn.collection_refs, - ostree_collection_ref_dup (ref), g_strdup (checksum)); + g_hash_table_replace (self->txn.collection_refs, ostree_collection_ref_dup (ref), + g_strdup (checksum)); g_mutex_unlock (&self->txn_lock); } @@ -2207,16 +2119,11 @@ ostree_repo_transaction_set_collection_ref (OstreeRepo *self, * Multithreading: This function is MT safe. */ gboolean -ostree_repo_set_ref_immediate (OstreeRepo *self, - const char *remote, - const char *ref, - const char *checksum, - GCancellable *cancellable, - GError **error) +ostree_repo_set_ref_immediate (OstreeRepo *self, const char *remote, const char *ref, + const char *checksum, GCancellable *cancellable, GError **error) { - const OstreeCollectionRef _ref = { NULL, (gchar *) ref }; - return _ostree_repo_write_ref (self, remote, &_ref, checksum, NULL, - cancellable, error); + const OstreeCollectionRef _ref = { NULL, (gchar *)ref }; + return _ostree_repo_write_ref (self, remote, &_ref, checksum, NULL, cancellable, error); } /** @@ -2233,16 +2140,11 @@ ostree_repo_set_ref_immediate (OstreeRepo *self, * Since: 2017.10 */ gboolean -ostree_repo_set_alias_ref_immediate (OstreeRepo *self, - const char *remote, - const char *ref, - const char *target, - GCancellable *cancellable, - GError **error) +ostree_repo_set_alias_ref_immediate (OstreeRepo *self, const char *remote, const char *ref, + const char *target, GCancellable *cancellable, GError **error) { - const OstreeCollectionRef _ref = { NULL, (gchar *) ref }; - return _ostree_repo_write_ref (self, remote, &_ref, NULL, target, - cancellable, error); + const OstreeCollectionRef _ref = { NULL, (gchar *)ref }; + return _ostree_repo_write_ref (self, remote, &_ref, NULL, target, cancellable, error); } /** @@ -2261,11 +2163,9 @@ ostree_repo_set_alias_ref_immediate (OstreeRepo *self, * Since: 2018.6 */ gboolean -ostree_repo_set_collection_ref_immediate (OstreeRepo *self, - const OstreeCollectionRef *ref, - const char *checksum, - GCancellable *cancellable, - GError **error) +ostree_repo_set_collection_ref_immediate (OstreeRepo *self, const OstreeCollectionRef *ref, + const char *checksum, GCancellable *cancellable, + GError **error) { g_assert (self != NULL); g_assert (OSTREE_IS_REPO (self)); @@ -2275,8 +2175,7 @@ ostree_repo_set_collection_ref_immediate (OstreeRepo *self, if (checksum != NULL && !ostree_validate_checksum_string (checksum, error)) return FALSE; - return _ostree_repo_write_ref (self, NULL, ref, checksum, NULL, - cancellable, error); + return _ostree_repo_write_ref (self, NULL, ref, checksum, NULL, cancellable, error); } /** @@ -2299,10 +2198,8 @@ ostree_repo_set_collection_ref_immediate (OstreeRepo *self, * active at a time. */ gboolean -ostree_repo_commit_transaction (OstreeRepo *self, - OstreeRepoTransactionStats *out_stats, - GCancellable *cancellable, - GError **error) +ostree_repo_commit_transaction (OstreeRepo *self, OstreeRepoTransactionStats *out_stats, + GCancellable *cancellable, GError **error) { g_assert (self != NULL); g_assert (OSTREE_IS_REPO (self)); @@ -2318,8 +2215,7 @@ ostree_repo_commit_transaction (OstreeRepo *self, /* FIXME: Added OSTREE_SUPPRESS_SYNCFS since valgrind in el7 doesn't know * about `syncfs`...we should delete this later. */ - if (!self->disable_fsync && - g_getenv ("OSTREE_SUPPRESS_SYNCFS") == NULL) + if (!self->disable_fsync && g_getenv ("OSTREE_SUPPRESS_SYNCFS") == NULL) { if (syncfs (self->tmp_dir_fd) < 0) return glnx_throw_errno_prefix (error, "syncfs"); @@ -2354,8 +2250,8 @@ ostree_repo_commit_transaction (OstreeRepo *self, /* Update the summary if auto-update-summary is set, because doing so was * delayed for each ref change during the transaction. */ - if ((self->txn.refs || self->txn.collection_refs) && - !_ostree_repo_maybe_regenerate_summary (self, cancellable, error)) + if (!self->txn.disable_auto_summary && (self->txn.refs || self->txn.collection_refs) + && !_ostree_repo_maybe_regenerate_summary (self, cancellable, error)) return FALSE; g_clear_pointer (&self->txn.refs, g_hash_table_destroy); @@ -2391,14 +2287,12 @@ ostree_repo_commit_transaction (OstreeRepo *self, * transaction will do nothing and return successfully. */ gboolean -ostree_repo_abort_transaction (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +ostree_repo_abort_transaction (OstreeRepo *self, GCancellable *cancellable, GError **error) { g_assert (self != NULL); g_assert (OSTREE_IS_REPO (self)); - g_autoptr(GError) cleanup_error = NULL; + g_autoptr (GError) cleanup_error = NULL; /* Always ignore the cancellable to avoid the chance that, if it gets * canceled, the transaction may not be fully cleaned up. @@ -2448,9 +2342,9 @@ ostree_repo_abort_transaction (OstreeRepo *self, * ostree_repo_write_metadata: * @self: Repo * @objtype: Object type - * @expected_checksum: (allow-none): If provided, validate content against this checksum + * @expected_checksum: (nullable): If provided, validate content against this checksum * @object: Metadata - * @out_csum: (out) (array fixed-size=32) (allow-none): Binary checksum + * @out_csum: (out) (array fixed-size=32) (optional): Binary checksum * @cancellable: Cancellable * @error: Error * @@ -2461,32 +2355,27 @@ ostree_repo_abort_transaction (OstreeRepo *self, * computed checksum. */ gboolean -ostree_repo_write_metadata (OstreeRepo *self, - OstreeObjectType objtype, - const char *expected_checksum, - GVariant *object, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +ostree_repo_write_metadata (OstreeRepo *self, OstreeObjectType objtype, + const char *expected_checksum, GVariant *object, guchar **out_csum, + GCancellable *cancellable, GError **error) { - g_autoptr(GVariant) normalized = NULL; + g_autoptr (GVariant) normalized = NULL; /* First, if we have an expected checksum, see if we already have this * object. This mirrors the same logic in ostree_repo_write_content(). */ if (expected_checksum) { gboolean have_obj; - if (!_ostree_repo_has_loose_object (self, expected_checksum, objtype, &have_obj, - cancellable, error)) + if (!_ostree_repo_has_loose_object (self, expected_checksum, objtype, &have_obj, cancellable, + error)) return FALSE; if (have_obj) { /* Update size metadata if needed */ - if (self->generate_sizes && - !repo_has_size_entry (self, objtype, expected_checksum)) + if (self->generate_sizes && !repo_has_size_entry (self, objtype, expected_checksum)) { /* Make sure we have a fully serialized object */ - g_autoptr(GVariant) trusted = g_variant_get_normal_form (object); + g_autoptr (GVariant) trusted = g_variant_get_normal_form (object); gsize size = g_variant_get_size (trusted); repo_store_size_entry (self, objtype, expected_checksum, size, size); } @@ -2509,9 +2398,9 @@ ostree_repo_write_metadata (OstreeRepo *self, if (!_ostree_validate_structureof_metadata (objtype, object, error)) return FALSE; - g_autoptr(GBytes) vdata = g_variant_get_data_as_bytes (normalized); - if (!write_metadata_object (self, objtype, expected_checksum, - vdata, out_csum, cancellable, error)) + g_autoptr (GBytes) vdata = g_variant_get_data_as_bytes (normalized); + if (!write_metadata_object (self, objtype, expected_checksum, vdata, out_csum, cancellable, + error)) return FALSE; return TRUE; @@ -2531,27 +2420,25 @@ ostree_repo_write_metadata (OstreeRepo *self, * trusted. */ gboolean -ostree_repo_write_metadata_stream_trusted (OstreeRepo *self, - OstreeObjectType objtype, - const char *checksum, - GInputStream *object_input, - guint64 length, - GCancellable *cancellable, - GError **error) +ostree_repo_write_metadata_stream_trusted (OstreeRepo *self, OstreeObjectType objtype, + const char *checksum, GInputStream *object_input, + guint64 length, GCancellable *cancellable, + GError **error) { /* This is all pretty ridiculous, but we're keeping this API for backwards * compatibility, it doesn't really need to be fast. */ - g_autoptr(GMemoryOutputStream) tmpbuf = (GMemoryOutputStream*)g_memory_output_stream_new_resizable (); - if (g_output_stream_splice ((GOutputStream*)tmpbuf, object_input, - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0) + g_autoptr (GMemoryOutputStream) tmpbuf + = (GMemoryOutputStream *)g_memory_output_stream_new_resizable (); + if (g_output_stream_splice ((GOutputStream *)tmpbuf, object_input, + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) + < 0) return FALSE; - g_autoptr(GBytes) tmpb = g_memory_output_stream_steal_as_bytes (tmpbuf); + g_autoptr (GBytes) tmpb = g_memory_output_stream_steal_as_bytes (tmpbuf); - g_autoptr(GVariant) tmpv = g_variant_new_from_bytes (ostree_metadata_variant_type (objtype), - tmpb, TRUE); - return ostree_repo_write_metadata_trusted (self, objtype, checksum, tmpv, - cancellable, error); + g_autoptr (GVariant) tmpv + = g_variant_new_from_bytes (ostree_metadata_variant_type (objtype), tmpb, TRUE); + return ostree_repo_write_metadata_trusted (self, objtype, checksum, tmpv, cancellable, error); } /** @@ -2567,19 +2454,14 @@ ostree_repo_write_metadata_stream_trusted (OstreeRepo *self, * trusted. */ gboolean -ostree_repo_write_metadata_trusted (OstreeRepo *self, - OstreeObjectType type, - const char *checksum, - GVariant *variant, - GCancellable *cancellable, - GError **error) +ostree_repo_write_metadata_trusted (OstreeRepo *self, OstreeObjectType type, const char *checksum, + GVariant *variant, GCancellable *cancellable, GError **error) { - return ostree_repo_write_metadata (self, type, - checksum, variant, NULL, - cancellable, error); + return ostree_repo_write_metadata (self, type, checksum, variant, NULL, cancellable, error); } -typedef struct { +typedef struct +{ OstreeRepo *repo; OstreeObjectType objtype; char *expected_checksum; @@ -2602,18 +2484,13 @@ write_metadata_async_data_free (gpointer user_data) } static void -write_metadata_thread (GTask *task, - GObject *object, - gpointer datap, - GCancellable *cancellable) +write_metadata_thread (GTask *task, GObject *object, gpointer datap, GCancellable *cancellable) { GError *error = NULL; WriteMetadataAsyncData *data = datap; - if (!ostree_repo_write_metadata (data->repo, data->objtype, data->expected_checksum, - data->object, - &data->result_csum, - cancellable, &error)) + if (!ostree_repo_write_metadata (data->repo, data->objtype, data->expected_checksum, data->object, + &data->result_csum, cancellable, &error)) g_task_return_error (task, error); else g_task_return_pointer (task, data, NULL); @@ -2623,7 +2500,7 @@ write_metadata_thread (GTask *task, * ostree_repo_write_metadata_async: * @self: Repo * @objtype: Object type - * @expected_checksum: (allow-none): If provided, validate content against this checksum + * @expected_checksum: (nullable): If provided, validate content against this checksum * @object: Metadata * @cancellable: Cancellable * @callback: Invoked when metadata is writed @@ -2633,15 +2510,12 @@ write_metadata_thread (GTask *task, * the checksum @expected_checksum will be verified. */ void -ostree_repo_write_metadata_async (OstreeRepo *self, - OstreeObjectType objtype, - const char *expected_checksum, - GVariant *object, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_write_metadata_async (OstreeRepo *self, OstreeObjectType objtype, + const char *expected_checksum, GVariant *object, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { - g_autoptr(GTask) task = NULL; + g_autoptr (GTask) task = NULL; WriteMetadataAsyncData *asyncdata; asyncdata = g_new0 (WriteMetadataAsyncData, 1); @@ -2667,10 +2541,8 @@ ostree_repo_write_metadata_async (OstreeRepo *self, * Complete a call to ostree_repo_write_metadata_async(). */ gboolean -ostree_repo_write_metadata_finish (OstreeRepo *self, - GAsyncResult *result, - guchar **out_csum, - GError **error) +ostree_repo_write_metadata_finish (OstreeRepo *self, GAsyncResult *result, guchar **out_csum, + GError **error) { WriteMetadataAsyncData *data; @@ -2694,20 +2566,16 @@ ostree_repo_write_metadata_finish (OstreeRepo *self, * Return its (binary) checksum in @out_csum. */ gboolean -_ostree_repo_write_directory_meta (OstreeRepo *self, - GFileInfo *file_info, - GVariant *xattrs, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +_ostree_repo_write_directory_meta (OstreeRepo *self, GFileInfo *file_info, GVariant *xattrs, + guchar **out_csum, GCancellable *cancellable, GError **error) { if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - g_autoptr(GVariant) dirmeta = ostree_create_directory_metadata (file_info, xattrs); - return ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_DIR_META, NULL, - dirmeta, out_csum, cancellable, error); + g_autoptr (GVariant) dirmeta = ostree_create_directory_metadata (file_info, xattrs); + return ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_DIR_META, NULL, dirmeta, out_csum, + cancellable, error); } /** @@ -2726,15 +2594,11 @@ _ostree_repo_write_directory_meta (OstreeRepo *self, * disk, for example. */ gboolean -ostree_repo_write_content_trusted (OstreeRepo *self, - const char *checksum, - GInputStream *object_input, - guint64 length, - GCancellable *cancellable, - GError **error) +ostree_repo_write_content_trusted (OstreeRepo *self, const char *checksum, + GInputStream *object_input, guint64 length, + GCancellable *cancellable, GError **error) { - return ostree_repo_write_content (self, checksum, object_input, length, - NULL, cancellable, error); + return ostree_repo_write_content (self, checksum, object_input, length, NULL, cancellable, error); } /** @@ -2743,7 +2607,7 @@ ostree_repo_write_content_trusted (OstreeRepo *self, * @expected_checksum: (allow-none): If provided, validate content against this checksum * @object_input: Content object stream * @length: Length of @object_input - * @out_csum: (out) (array fixed-size=32) (allow-none): Binary checksum + * @out_csum: (out) (array fixed-size=32) (optional) (nullable): Binary checksum * @cancellable: Cancellable * @error: Error * @@ -2752,13 +2616,9 @@ ostree_repo_write_content_trusted (OstreeRepo *self, * be returned as @out_csum. */ gboolean -ostree_repo_write_content (OstreeRepo *self, - const char *expected_checksum, - GInputStream *object_input, - guint64 length, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +ostree_repo_write_content (OstreeRepo *self, const char *expected_checksum, + GInputStream *object_input, guint64 length, guchar **out_csum, + GCancellable *cancellable, GError **error) { /* First, if we have an expected checksum, see if we already have this * object. This mirrors the same logic in ostree_repo_write_metadata(). @@ -2769,9 +2629,8 @@ ostree_repo_write_content (OstreeRepo *self, if (expected_checksum && !self->generate_sizes) { gboolean have_obj; - if (!_ostree_repo_has_loose_object (self, expected_checksum, - OSTREE_OBJECT_TYPE_FILE, &have_obj, - cancellable, error)) + if (!_ostree_repo_has_loose_object (self, expected_checksum, OSTREE_OBJECT_TYPE_FILE, + &have_obj, cancellable, error)) return FALSE; if (have_obj) { @@ -2782,16 +2641,14 @@ ostree_repo_write_content (OstreeRepo *self, } /* Parse the stream */ - g_autoptr(GInputStream) file_input = NULL; - g_autoptr(GVariant) xattrs = NULL; - g_autoptr(GFileInfo) file_info = NULL; - if (!ostree_content_stream_parse (FALSE, object_input, length, FALSE, - &file_input, &file_info, &xattrs, - cancellable, error)) + g_autoptr (GInputStream) file_input = NULL; + g_autoptr (GVariant) xattrs = NULL; + g_autoptr (GFileInfo) file_info = NULL; + if (!ostree_content_stream_parse (FALSE, object_input, length, FALSE, &file_input, &file_info, + &xattrs, cancellable, error)) return FALSE; - return write_content_object (self, expected_checksum, - file_input, file_info, xattrs, out_csum, + return write_content_object (self, expected_checksum, file_input, file_info, xattrs, out_csum, cancellable, error); } @@ -2819,24 +2676,16 @@ ostree_repo_write_content (OstreeRepo *self, */ _OSTREE_PUBLIC char * -ostree_repo_write_regfile_inline (OstreeRepo *self, - const char *expected_checksum, - guint32 uid, - guint32 gid, - guint32 mode, - GVariant *xattrs, - const guint8* buf, - gsize len, - GCancellable *cancellable, - GError **error) +ostree_repo_write_regfile_inline (OstreeRepo *self, const char *expected_checksum, guint32 uid, + guint32 gid, guint32 mode, GVariant *xattrs, const guint8 *buf, + gsize len, GCancellable *cancellable, GError **error) { - g_autoptr(GInputStream) memin = g_memory_input_stream_new_from_data (buf, len, NULL); - g_autoptr(GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); + g_autoptr (GInputStream) memin = g_memory_input_stream_new_from_data (buf, len, NULL); + g_autoptr (GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid); g_file_info_set_size (finfo, len); - g_autofree guint8* csum = NULL; - if (!write_content_object (self, expected_checksum, - memin, finfo, xattrs, &csum, - cancellable, error)) + g_autofree guint8 *csum = NULL; + if (!write_content_object (self, expected_checksum, memin, finfo, xattrs, &csum, cancellable, + error)) return NULL; return ostree_checksum_from_bytes (csum); } @@ -2860,24 +2709,18 @@ ostree_repo_write_regfile_inline (OstreeRepo *self, * Returns: (transfer full): Checksum (as a hex string) of the committed file * Since: 2021.2 */ -char * -ostree_repo_write_symlink (OstreeRepo *self, - const char *expected_checksum, - guint32 uid, - guint32 gid, - GVariant *xattrs, - const char *symlink_target, - GCancellable *cancellable, - GError **error) +char * +ostree_repo_write_symlink (OstreeRepo *self, const char *expected_checksum, guint32 uid, + guint32 gid, GVariant *xattrs, const char *symlink_target, + GCancellable *cancellable, GError **error) { g_assert (symlink_target != NULL); - g_autoptr(GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (S_IFLNK | 0777, uid, gid); + g_autoptr (GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (S_IFLNK | 0777, uid, gid); g_file_info_set_attribute_byte_string (finfo, "standard::symlink-target", symlink_target); - g_autofree guint8* csum = NULL; - if (!write_content_object (self, expected_checksum, - NULL, finfo, xattrs, &csum, - cancellable, error)) + g_autofree guint8 *csum = NULL; + if (!write_content_object (self, expected_checksum, NULL, finfo, xattrs, &csum, cancellable, + error)) return NULL; return ostree_checksum_from_bytes (csum); } @@ -2892,30 +2735,28 @@ ostree_repo_write_symlink (OstreeRepo *self, * @content_len: Expected content length * @xattrs: (allow-none): Extended attributes (GVariant type `(ayay)`) * @error: Error - * + * * Create an `OstreeContentWriter` that allows streaming output into * the repository. * * Returns: (transfer full): A new writer, or %NULL on error * Since: 2021.2 */ -OstreeContentWriter * -ostree_repo_write_regfile (OstreeRepo *self, - const char *expected_checksum, - guint32 uid, - guint32 gid, - guint32 mode, - guint64 content_len, - GVariant *xattrs, - GError **error) +OstreeContentWriter * +ostree_repo_write_regfile (OstreeRepo *self, const char *expected_checksum, guint32 uid, + guint32 gid, guint32 mode, guint64 content_len, GVariant *xattrs, + GError **error) { if (self->mode == OSTREE_REPO_MODE_ARCHIVE) - return glnx_null_throw (error, "Cannot currently use ostree_repo_write_regfile() on an archive mode repository"); + return glnx_null_throw ( + error, "Cannot currently use ostree_repo_write_regfile() on an archive mode repository"); - return _ostree_content_writer_new (self, expected_checksum, uid, gid, mode, content_len, xattrs, error); + return _ostree_content_writer_new (self, expected_checksum, uid, gid, mode, content_len, xattrs, + error); } -typedef struct { +typedef struct +{ OstreeRepo *repo; char *expected_checksum; GInputStream *object; @@ -2939,18 +2780,14 @@ write_content_async_data_free (gpointer user_data) } static void -write_content_thread (GTask *task, - GObject *object, - gpointer datap, - GCancellable *cancellable) +write_content_thread (GTask *task, GObject *object, gpointer datap, GCancellable *cancellable) { GError *error = NULL; WriteContentAsyncData *data = datap; - if (!ostree_repo_write_content (data->repo, data->expected_checksum, - data->object, data->file_object_length, - &data->result_csum, - cancellable, &error)) + if (!ostree_repo_write_content (data->repo, data->expected_checksum, data->object, + data->file_object_length, &data->result_csum, cancellable, + &error)) g_task_return_error (task, error); else g_task_return_pointer (task, data, NULL); @@ -2970,15 +2807,11 @@ write_content_thread (GTask *task, * checksum @expected_checksum will be verified. */ void -ostree_repo_write_content_async (OstreeRepo *self, - const char *expected_checksum, - GInputStream *object, - guint64 length, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_write_content_async (OstreeRepo *self, const char *expected_checksum, + GInputStream *object, guint64 length, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = NULL; + g_autoptr (GTask) task = NULL; WriteContentAsyncData *asyncdata; asyncdata = g_new0 (WriteContentAsyncData, 1); @@ -2998,16 +2831,15 @@ ostree_repo_write_content_async (OstreeRepo *self, * ostree_repo_write_content_finish: * @self: a #OstreeRepo * @result: a #GAsyncResult - * @out_csum: (out) (transfer full): A binary SHA256 checksum of the content object + * @out_csum: (out) (transfer full) (optional): A binary SHA256 + * checksum of the content object * @error: a #GError * * Completes an invocation of ostree_repo_write_content_async(). */ gboolean -ostree_repo_write_content_finish (OstreeRepo *self, - GAsyncResult *result, - guchar **out_csum, - GError **error) +ostree_repo_write_content_finish (OstreeRepo *self, GAsyncResult *result, guchar **out_csum, + GError **error) { WriteContentAsyncData *data; @@ -3025,23 +2857,16 @@ ostree_repo_write_content_finish (OstreeRepo *self, return TRUE; } -static GVariant * -create_empty_gvariant_dict (void) -{ - GVariantBuilder builder; - g_variant_builder_init (&builder, G_VARIANT_TYPE("a{sv}")); - return g_variant_builder_end (&builder); -} - /** * ostree_repo_write_commit: * @self: Repo - * @parent: (allow-none): ASCII SHA256 checksum for parent, or %NULL for none - * @subject: (allow-none): Subject - * @body: (allow-none): Body - * @metadata: (allow-none): GVariant of type a{sv}, or %NULL for none + * @parent: (nullable): ASCII SHA256 checksum for parent, or %NULL for none + * @subject: (nullable): Subject + * @body: (nullable): Body + * @metadata: (nullable): GVariant of type a{sv}, or %NULL for none * @root: The tree to point the commit to - * @out_commit: (out): Resulting ASCII SHA256 checksum for commit + * @out_commit: (out) (optional): Resulting ASCII SHA256 checksum for + * commit * @cancellable: Cancellable * @error: Error * @@ -3053,21 +2878,15 @@ create_empty_gvariant_dict (void) * `SOURCE_DATE_EPOCH` environment flag. */ gboolean -ostree_repo_write_commit (OstreeRepo *self, - const char *parent, - const char *subject, - const char *body, - GVariant *metadata, - OstreeRepoFile *root, - char **out_commit, - GCancellable *cancellable, - GError **error) +ostree_repo_write_commit (OstreeRepo *self, const char *parent, const char *subject, + const char *body, GVariant *metadata, OstreeRepoFile *root, + char **out_commit, GCancellable *cancellable, GError **error) { gint64 timestamp = 0; const gchar *env_timestamp = g_getenv ("SOURCE_DATE_EPOCH"); if (env_timestamp == NULL) { - g_autoptr(GDateTime) now = g_date_time_new_now_utc (); + g_autoptr (GDateTime) now = g_date_time_new_now_utc (); timestamp = g_date_time_to_unix (now); } else @@ -3081,21 +2900,35 @@ ostree_repo_write_commit (OstreeRepo *self, return glnx_throw (error, "Failed to convert SOURCE_DATE_EPOCH"); } - return ostree_repo_write_commit_with_time (self, parent, subject, body, - metadata, root, timestamp, + return ostree_repo_write_commit_with_time (self, parent, subject, body, metadata, root, timestamp, out_commit, cancellable, error); } +static GVariant * +add_auto_metadata (OstreeRepo *self, GVariant *original_metadata, OstreeRepoFile *repo_root, + GCancellable *cancellable, GError **error) +{ + g_autoptr (GVariantBuilder) builder = NULL; + + /* original_metadata may be NULL */ + builder = ot_util_variant_builder_from_variant (original_metadata, G_VARIANT_TYPE ("a{sv}")); + + add_size_index_to_metadata (self, builder); + + return g_variant_ref_sink (g_variant_builder_end (builder)); +} + /** * ostree_repo_write_commit_with_time: * @self: Repo - * @parent: (allow-none): ASCII SHA256 checksum for parent, or %NULL for none - * @subject: (allow-none): Subject - * @body: (allow-none): Body - * @metadata: (allow-none): GVariant of type a{sv}, or %NULL for none + * @parent: (nullable): ASCII SHA256 checksum for parent, or %NULL for none + * @subject: (nullable): Subject + * @body: (nullable): Body + * @metadata: (nullable): GVariant of type a{sv}, or %NULL for none * @root: The tree to point the commit to * @time: The time to use to stamp the commit - * @out_commit: (out): Resulting ASCII SHA256 checksum for commit + * @out_commit: (out) (optional): Resulting ASCII SHA256 checksum for + * commit * @cancellable: Cancellable * @error: Error * @@ -3103,40 +2936,34 @@ ostree_repo_write_commit (OstreeRepo *self, * and @root_metadata_checksum. */ gboolean -ostree_repo_write_commit_with_time (OstreeRepo *self, - const char *parent, - const char *subject, - const char *body, - GVariant *metadata, - OstreeRepoFile *root, - guint64 time, - char **out_commit, - GCancellable *cancellable, - GError **error) +ostree_repo_write_commit_with_time (OstreeRepo *self, const char *parent, const char *subject, + const char *body, GVariant *metadata, OstreeRepoFile *root, + guint64 time, char **out_commit, GCancellable *cancellable, + GError **error) { OstreeRepoFile *repo_root = OSTREE_REPO_FILE (root); /* Add sizes information to our metadata object */ - g_autoptr(GVariant) new_metadata = add_size_index_to_metadata (self, metadata); - - g_autoptr(GVariant) commit = - g_variant_new ("(@a{sv}@ay@a(say)sst@ay@ay)", - new_metadata ? new_metadata : create_empty_gvariant_dict (), - parent ? ostree_checksum_to_bytes_v (parent) : ot_gvariant_new_bytearray (NULL, 0), - g_variant_new_array (G_VARIANT_TYPE ("(say)"), NULL, 0), - subject ? subject : "", body ? body : "", - GUINT64_TO_BE (time), - ostree_checksum_to_bytes_v (ostree_repo_file_tree_get_contents_checksum (repo_root)), - ostree_checksum_to_bytes_v (ostree_repo_file_tree_get_metadata_checksum (repo_root))); + g_autoptr (GVariant) new_metadata + = add_auto_metadata (self, metadata, repo_root, cancellable, error); + if (new_metadata == NULL) + return FALSE; + + g_autoptr (GVariant) commit = g_variant_new ( + "(@a{sv}@ay@a(say)sst@ay@ay)", new_metadata, + parent ? ostree_checksum_to_bytes_v (parent) : ot_gvariant_new_bytearray (NULL, 0), + g_variant_new_array (G_VARIANT_TYPE ("(say)"), NULL, 0), subject ? subject : "", + body ? body : "", GUINT64_TO_BE (time), + ostree_checksum_to_bytes_v (ostree_repo_file_tree_get_contents_checksum (repo_root)), + ostree_checksum_to_bytes_v (ostree_repo_file_tree_get_metadata_checksum (repo_root))); g_variant_ref_sink (commit); g_autofree guchar *commit_csum = NULL; - if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_COMMIT, NULL, - commit, &commit_csum, + if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_COMMIT, NULL, commit, &commit_csum, cancellable, error)) return FALSE; g_autofree char *ret_commit = ostree_checksum_from_bytes (commit_csum); - ot_transfer_out_value(out_commit, &ret_commit); + ot_transfer_out_value (out_commit, &ret_commit); return TRUE; } @@ -3144,7 +2971,8 @@ ostree_repo_write_commit_with_time (OstreeRepo *self, * ostree_repo_read_commit_detached_metadata: * @self: Repo * @checksum: ASCII SHA256 commit checksum - * @out_metadata: (out) (nullable) (transfer full): Metadata associated with commit in with format "a{sv}", or %NULL if none exists + * @out_metadata: (out) (nullable) (transfer full): Metadata associated with commit in with format + * "a{sv}", or %NULL if none exists * @cancellable: Cancellable * @error: Error * @@ -3153,11 +2981,9 @@ ostree_repo_write_commit_with_time (OstreeRepo *self, * to %NULL. */ gboolean -ostree_repo_read_commit_detached_metadata (OstreeRepo *self, - const char *checksum, - GVariant **out_metadata, - GCancellable *cancellable, - GError **error) +ostree_repo_read_commit_detached_metadata (OstreeRepo *self, const char *checksum, + GVariant **out_metadata, GCancellable *cancellable, + GError **error) { g_assert (out_metadata != NULL); @@ -3170,20 +2996,17 @@ ostree_repo_read_commit_detached_metadata (OstreeRepo *self, if (!ot_openat_ignore_enoent (self->commit_stagedir.fd, buf, &fd, error)) return FALSE; if (fd != -1) - return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE, - out_metadata, error); + return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE, out_metadata, error); } glnx_autofd int fd = -1; if (!ot_openat_ignore_enoent (self->objects_dir_fd, buf, &fd, error)) return FALSE; if (fd != -1) - return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE, - out_metadata, error); + return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE, out_metadata, error); if (self->parent_repo) - return ostree_repo_read_commit_detached_metadata (self->parent_repo, - checksum, out_metadata, + return ostree_repo_read_commit_detached_metadata (self->parent_repo, checksum, out_metadata, cancellable, error); /* Nothing found */ *out_metadata = NULL; @@ -3194,7 +3017,8 @@ ostree_repo_read_commit_detached_metadata (OstreeRepo *self, * ostree_repo_write_commit_detached_metadata: * @self: Repo * @checksum: ASCII SHA256 commit checksum - * @metadata: (allow-none): Metadata to associate with commit in with format "a{sv}", or %NULL to delete + * @metadata: (nullable): Metadata to associate with commit in with format "a{sv}", or %NULL to + * delete * @cancellable: Cancellable * @error: Error * @@ -3203,11 +3027,9 @@ ostree_repo_read_commit_detached_metadata (OstreeRepo *self, * data will be deleted. */ gboolean -ostree_repo_write_commit_detached_metadata (OstreeRepo *self, - const char *checksum, - GVariant *metadata, - GCancellable *cancellable, - GError **error) +ostree_repo_write_commit_detached_metadata (OstreeRepo *self, const char *checksum, + GVariant *metadata, GCancellable *cancellable, + GError **error) { int dest_dfd; if (self->in_transaction) @@ -3215,11 +3037,10 @@ ostree_repo_write_commit_detached_metadata (OstreeRepo *self, else dest_dfd = self->objects_dir_fd; - if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, checksum, - cancellable, error)) + if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, checksum, cancellable, error)) return FALSE; - g_autoptr(GVariant) normalized = NULL; + g_autoptr (GVariant) normalized = NULL; gsize normalized_size = 0; const guint8 *data = NULL; if (metadata != NULL) @@ -3230,13 +3051,12 @@ ostree_repo_write_commit_detached_metadata (OstreeRepo *self, } if (data == NULL) - data = (guint8*)""; + data = (guint8 *)""; char pathbuf[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (pathbuf, checksum, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode); - if (!glnx_file_replace_contents_at (dest_dfd, pathbuf, - data, normalized_size, - 0, cancellable, error)) + if (!glnx_file_replace_contents_at (dest_dfd, pathbuf, data, normalized_size, 0, cancellable, + error)) { g_prefix_error (error, "Unable to write detached metadata: "); return FALSE; @@ -3249,9 +3069,8 @@ ostree_repo_write_commit_detached_metadata (OstreeRepo *self, * content objects and subdirectories. The input hashes will be sorted */ static GVariant * -create_tree_variant_from_hashes (GHashTable *file_checksums, - GHashTable *dir_contents_checksums, - GHashTable *dir_metadata_checksums) +create_tree_variant_from_hashes (GHashTable *file_checksums, GHashTable *dir_contents_checksums, + GHashTable *dir_metadata_checksums) { GVariantBuilder files_builder; g_variant_builder_init (&files_builder, G_VARIANT_TYPE ("a(say)")); @@ -3259,12 +3078,12 @@ create_tree_variant_from_hashes (GHashTable *file_checksums, g_variant_builder_init (&dirs_builder, G_VARIANT_TYPE ("a(sayay)")); GSList *sorted_filenames = NULL; - GLNX_HASH_TABLE_FOREACH (file_checksums, const char*, name) + GLNX_HASH_TABLE_FOREACH (file_checksums, const char *, name) { /* Should have been validated earlier, but be paranoid */ g_assert (ot_util_filename_validate (name, NULL)); - sorted_filenames = g_slist_prepend (sorted_filenames, (char*)name); + sorted_filenames = g_slist_prepend (sorted_filenames, (char *)name); } sorted_filenames = g_slist_sort (sorted_filenames, (GCompareFunc)strcmp); for (GSList *iter = sorted_filenames; iter; iter = iter->next) @@ -3273,14 +3092,13 @@ create_tree_variant_from_hashes (GHashTable *file_checksums, const char *value; value = g_hash_table_lookup (file_checksums, name); - g_variant_builder_add (&files_builder, "(s@ay)", name, - ostree_checksum_to_bytes_v (value)); + g_variant_builder_add (&files_builder, "(s@ay)", name, ostree_checksum_to_bytes_v (value)); } g_slist_free (sorted_filenames); sorted_filenames = NULL; - GLNX_HASH_TABLE_FOREACH (dir_metadata_checksums, const char*, name) - sorted_filenames = g_slist_prepend (sorted_filenames, (char*)name); + GLNX_HASH_TABLE_FOREACH (dir_metadata_checksums, const char *, name) + sorted_filenames = g_slist_prepend (sorted_filenames, (char *)name); sorted_filenames = g_slist_sort (sorted_filenames, (GCompareFunc)strcmp); for (GSList *iter = sorted_filenames; iter; iter = iter->next) @@ -3297,10 +3115,9 @@ create_tree_variant_from_hashes (GHashTable *file_checksums, g_slist_free (sorted_filenames); sorted_filenames = NULL; - GVariant *serialized_tree = - g_variant_new ("(@a(say)@a(sayay))", - g_variant_builder_end (&files_builder), - g_variant_builder_end (&dirs_builder)); + GVariant *serialized_tree + = g_variant_new ("(@a(say)@a(sayay))", g_variant_builder_end (&files_builder), + g_variant_builder_end (&dirs_builder)); return g_variant_ref_sink (serialized_tree); } @@ -3309,11 +3126,9 @@ create_tree_variant_from_hashes (GHashTable *file_checksums, * will simply be another reference (with incremented refcount) to @file_info. */ OstreeRepoCommitFilterResult -_ostree_repo_commit_modifier_apply (OstreeRepo *self, - OstreeRepoCommitModifier *modifier, - const char *path, - GFileInfo *file_info, - GFileInfo **out_modified_info) +_ostree_repo_commit_modifier_apply (OstreeRepo *self, OstreeRepoCommitModifier *modifier, + const char *path, GFileInfo *file_info, + GFileInfo **out_modified_info) { gboolean canonicalize_perms = FALSE; gboolean has_filter = FALSE; @@ -3374,7 +3189,7 @@ _ostree_repo_commit_modifier_apply (OstreeRepo *self, /* Convert @path into a string */ static char * -ptrarray_path_join (GPtrArray *path) +ptrarray_path_join (GPtrArray *path) { GString *path_buf = g_string_new (""); @@ -3395,36 +3210,30 @@ ptrarray_path_join (GPtrArray *path) } static gboolean -get_final_xattrs (OstreeRepo *self, - OstreeRepoCommitModifier *modifier, - const char *relpath, - GFileInfo *file_info, - GFile *path, - int dfd, - const char *dfd_subpath, - GVariant *source_xattrs, - GVariant **out_xattrs, - gboolean *out_modified, - GCancellable *cancellable, - GError **error) +get_final_xattrs (OstreeRepo *self, OstreeRepoCommitModifier *modifier, const char *relpath, + GFileInfo *file_info, GFile *path, int dfd, const char *dfd_subpath, + GVariant *source_xattrs, GVariant **out_xattrs, gboolean *out_modified, + GCancellable *cancellable, GError **error) { /* track whether the returned xattrs differ from the file on disk */ gboolean modified = TRUE; - const gboolean skip_xattrs = (modifier && - (modifier->flags & (OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS | - OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS)) > 0) || - self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY; + const gboolean skip_xattrs = (modifier + && (modifier->flags + & (OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS + | OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS)) + > 0) + || self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY; /* fetch on-disk xattrs if needed & not disabled */ - g_autoptr(GVariant) original_xattrs = NULL; + g_autoptr (GVariant) original_xattrs = NULL; if (!skip_xattrs && !self->disable_xattrs) { if (source_xattrs) original_xattrs = g_variant_ref (source_xattrs); else if (path && OSTREE_IS_REPO_FILE (path)) { - if (!ostree_repo_file_get_xattrs (OSTREE_REPO_FILE (path), &original_xattrs, - cancellable, error)) + if (!ostree_repo_file_get_xattrs (OSTREE_REPO_FILE (path), &original_xattrs, cancellable, + error)) return FALSE; } else if (path) @@ -3451,11 +3260,10 @@ get_final_xattrs (OstreeRepo *self, g_assert (original_xattrs); } - g_autoptr(GVariant) ret_xattrs = NULL; + g_autoptr (GVariant) ret_xattrs = NULL; if (modifier && modifier->xattr_callback) { - ret_xattrs = modifier->xattr_callback (self, relpath, file_info, - modifier->xattr_user_data); + ret_xattrs = modifier->xattr_callback (self, relpath, file_info, modifier->xattr_user_data); } /* if callback returned NULL or didn't exist, default to on-disk state */ @@ -3465,8 +3273,14 @@ get_final_xattrs (OstreeRepo *self, if (modifier && modifier->sepolicy) { g_autofree char *label = NULL; + const char *path_for_labeling = relpath; + + bool using_v1 = (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SELINUX_LABEL_V1) > 0; + bool is_usretc = g_str_equal (relpath, "/usr/etc") || g_str_has_prefix (relpath, "/usr/etc/"); + if (using_v1 && is_usretc) + path_for_labeling += strlen ("/usr"); - if (!ostree_sepolicy_get_label (modifier->sepolicy, relpath, + if (!ostree_sepolicy_get_label (modifier->sepolicy, path_for_labeling, g_file_info_get_attribute_uint32 (file_info, "unix::mode"), &label, cancellable, error)) return FALSE; @@ -3477,25 +3291,23 @@ get_final_xattrs (OstreeRepo *self, } else if (label) { - g_autoptr(GVariantBuilder) builder = NULL; + g_autoptr (GVariantBuilder) builder = NULL; if (ret_xattrs) { /* drop out any existing SELinux policy from the set, so we don't end up * counting it twice in the checksum */ - GVariant* new_ret_xattrs = _ostree_filter_selinux_xattr (ret_xattrs); + GVariant *new_ret_xattrs = _ostree_filter_selinux_xattr (ret_xattrs); g_variant_unref (ret_xattrs); ret_xattrs = new_ret_xattrs; } /* ret_xattrs may be NULL */ - builder = ot_util_variant_builder_from_variant (ret_xattrs, - G_VARIANT_TYPE ("a(ayay)")); + builder = ot_util_variant_builder_from_variant (ret_xattrs, G_VARIANT_TYPE ("a(ayay)")); - g_variant_builder_add_value (builder, - g_variant_new ("(@ay@ay)", - g_variant_new_bytestring ("security.selinux"), - g_variant_new_bytestring (label))); + g_variant_builder_add_value ( + builder, g_variant_new ("(@ay@ay)", g_variant_new_bytestring ("security.selinux"), + g_variant_new_bytestring (label))); if (ret_xattrs) g_variant_unref (ret_xattrs); @@ -3514,24 +3326,19 @@ get_final_xattrs (OstreeRepo *self, return TRUE; } -static gboolean -write_directory_to_mtree_internal (OstreeRepo *self, - GFile *dir, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GPtrArray *path, - GCancellable *cancellable, - GError **error); -static gboolean -write_dfd_iter_to_mtree_internal (OstreeRepo *self, - GLnxDirFdIterator *src_dfd_iter, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GPtrArray *path, - GCancellable *cancellable, - GError **error); - -typedef enum { +static gboolean write_directory_to_mtree_internal (OstreeRepo *self, GFile *dir, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + GPtrArray *path, GCancellable *cancellable, + GError **error); +static gboolean write_dfd_iter_to_mtree_internal (OstreeRepo *self, GLnxDirFdIterator *src_dfd_iter, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + GPtrArray *path, GCancellable *cancellable, + GError **error); + +typedef enum +{ WRITE_DIR_CONTENT_FLAGS_NONE = 0, WRITE_DIR_CONTENT_FLAGS_CAN_ADOPT = 1, } WriteDirContentFlags; @@ -3542,17 +3349,11 @@ typedef enum { * write_directory_to_mtree_internal (dir_enum case) which will do the actual * dirmeta + dirent iteration. */ static gboolean -write_dir_entry_to_mtree_internal (OstreeRepo *self, - OstreeRepoFile *repo_dir, - GFileEnumerator *dir_enum, - GLnxDirFdIterator *dfd_iter, - WriteDirContentFlags writeflags, - GFileInfo *child_info, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GPtrArray *path, - GCancellable *cancellable, - GError **error) +write_dir_entry_to_mtree_internal (OstreeRepo *self, OstreeRepoFile *repo_dir, + GFileEnumerator *dir_enum, GLnxDirFdIterator *dfd_iter, + WriteDirContentFlags writeflags, GFileInfo *child_info, + OstreeMutableTree *mtree, OstreeRepoCommitModifier *modifier, + GPtrArray *path, GCancellable *cancellable, GError **error) { g_assert (dir_enum != NULL || dfd_iter != NULL); g_assert (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY); @@ -3563,17 +3364,17 @@ write_dir_entry_to_mtree_internal (OstreeRepo *self, * more complexity in this function, and it'd mostly only be useful when * operating on local filesystems anyways. */ - const gboolean delete_after_commit = dfd_iter && modifier && - (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME); + const gboolean delete_after_commit + = dfd_iter && modifier && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME); /* Build the full path which we need for callbacks */ - g_ptr_array_add (path, (char*)name); + g_ptr_array_add (path, (char *)name); g_autofree char *child_relpath = ptrarray_path_join (path); /* Call the filter */ - g_autoptr(GFileInfo) modified_info = NULL; - OstreeRepoCommitFilterResult filter_result = - _ostree_repo_commit_modifier_apply (self, modifier, child_relpath, child_info, &modified_info); + g_autoptr (GFileInfo) modified_info = NULL; + OstreeRepoCommitFilterResult filter_result = _ostree_repo_commit_modifier_apply ( + self, modifier, child_relpath, child_info, &modified_info); if (filter_result != OSTREE_REPO_COMMIT_FILTER_ALLOW) { @@ -3588,41 +3389,40 @@ write_dir_entry_to_mtree_internal (OstreeRepo *self, return TRUE; } - g_autoptr(GFile) child = NULL; + g_autoptr (GFile) child = NULL; if (dir_enum != NULL) child = g_file_enumerator_get_child (dir_enum, child_info); - g_autoptr(OstreeMutableTree) child_mtree = NULL; + g_autoptr (OstreeMutableTree) child_mtree = NULL; if (!ostree_mutable_tree_ensure_dir (mtree, name, &child_mtree, error)) return FALSE; /* Finally, recurse on the dir */ if (dir_enum != NULL) { - if (!write_directory_to_mtree_internal (self, child, child_mtree, - modifier, path, - cancellable, error)) + if (!write_directory_to_mtree_internal (self, child, child_mtree, modifier, path, cancellable, + error)) return FALSE; } else if (repo_dir) { g_assert (dir_enum != NULL); g_debug ("Adding: %s", gs_file_get_path_cached (child)); - if (!ostree_mutable_tree_replace_file (mtree, name, - ostree_repo_file_get_checksum ((OstreeRepoFile*) child), - error)) + if (!ostree_mutable_tree_replace_file ( + mtree, name, ostree_repo_file_get_checksum ((OstreeRepoFile *)child), error)) return FALSE; } else { g_assert (dfd_iter != NULL); - g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) child_dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (dfd_iter->fd, name, FALSE, &child_dfd_iter, error)) return FALSE; - if (!write_dfd_iter_to_mtree_internal (self, &child_dfd_iter, child_mtree, - modifier, path, + if (!write_dfd_iter_to_mtree_internal (self, &child_dfd_iter, child_mtree, modifier, path, cancellable, error)) return FALSE; @@ -3642,17 +3442,11 @@ write_dir_entry_to_mtree_internal (OstreeRepo *self, * the mtree. */ static gboolean -write_content_to_mtree_internal (OstreeRepo *self, - OstreeRepoFile *repo_dir, - GFileEnumerator *dir_enum, - GLnxDirFdIterator *dfd_iter, - WriteDirContentFlags writeflags, - GFileInfo *child_info, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GPtrArray *path, - GCancellable *cancellable, - GError **error) +write_content_to_mtree_internal (OstreeRepo *self, OstreeRepoFile *repo_dir, + GFileEnumerator *dir_enum, GLnxDirFdIterator *dfd_iter, + WriteDirContentFlags writeflags, GFileInfo *child_info, + OstreeMutableTree *mtree, OstreeRepoCommitModifier *modifier, + GPtrArray *path, GCancellable *cancellable, GError **error) { g_assert (dir_enum != NULL || dfd_iter != NULL); @@ -3662,16 +3456,18 @@ write_content_to_mtree_internal (OstreeRepo *self, /* Load flags into boolean constants for ease of readability (we also need to * NULL-check modifier) */ - const gboolean canonical_permissions = self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY || - (modifier && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS)); - const gboolean devino_canonical = modifier && - (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL); + const gboolean canonical_permissions + = self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY + || (modifier + && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS)); + const gboolean devino_canonical + = modifier && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL); /* We currently only honor the CONSUME flag in the dfd_iter case to avoid even * more complexity in this function, and it'd mostly only be useful when * operating on local filesystems anyways. */ - const gboolean delete_after_commit = dfd_iter && modifier && - (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME); + const gboolean delete_after_commit + = dfd_iter && modifier && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME); /* See if we have a devino hit; this is used below in a few places. */ const char *loose_checksum = NULL; @@ -3701,7 +3497,7 @@ write_content_to_mtree_internal (OstreeRepo *self, } /* Build the full path which we need for callbacks */ - g_ptr_array_add (path, (char*)name); + g_ptr_array_add (path, (char *)name); g_autofree char *child_relpath = ptrarray_path_join (path); /* For bare-user repos we'll reload our file info from the object @@ -3710,8 +3506,8 @@ write_content_to_mtree_internal (OstreeRepo *self, * Basically we're making sure that we pick up "real" uid/gid and any xattrs * there. */ - g_autoptr(GVariant) source_xattrs = NULL; - g_autoptr(GFileInfo) source_child_info = NULL; + g_autoptr (GVariant) source_xattrs = NULL; + g_autoptr (GFileInfo) source_child_info = NULL; if (loose_checksum && self->mode == OSTREE_REPO_MODE_BARE_USER) { if (!ostree_repo_load_file (self, loose_checksum, NULL, &source_child_info, &source_xattrs, @@ -3721,9 +3517,9 @@ write_content_to_mtree_internal (OstreeRepo *self, } /* Call the filter */ - g_autoptr(GFileInfo) modified_info = NULL; - OstreeRepoCommitFilterResult filter_result = - _ostree_repo_commit_modifier_apply (self, modifier, child_relpath, child_info, &modified_info); + g_autoptr (GFileInfo) modified_info = NULL; + OstreeRepoCommitFilterResult filter_result = _ostree_repo_commit_modifier_apply ( + self, modifier, child_relpath, child_info, &modified_info); const gboolean child_info_was_modified = !_ostree_gfileinfo_equal (child_info, modified_info); if (filter_result != OSTREE_REPO_COMMIT_FILTER_ALLOW) @@ -3748,7 +3544,7 @@ write_content_to_mtree_internal (OstreeRepo *self, return glnx_throw (error, "Unsupported file type for file: '%s'", child_relpath); } - g_autoptr(GFile) child = NULL; + g_autoptr (GFile) child = NULL; if (dir_enum != NULL) child = g_file_enumerator_get_child (dir_enum, child_info); @@ -3768,13 +3564,12 @@ write_content_to_mtree_internal (OstreeRepo *self, return FALSE; } - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; gboolean xattrs_were_modified; if (dir_enum != NULL) { - if (!get_final_xattrs (self, modifier, child_relpath, child_info, child, - -1, name, source_xattrs, &xattrs, &xattrs_were_modified, - cancellable, error)) + if (!get_final_xattrs (self, modifier, child_relpath, child_info, child, -1, name, + source_xattrs, &xattrs, &xattrs_were_modified, cancellable, error)) return FALSE; } else @@ -3784,9 +3579,8 @@ write_content_to_mtree_internal (OstreeRepo *self, */ int xattr_fd_arg = (file_input_fd != -1) ? file_input_fd : dfd_iter->fd; const char *xattr_path_arg = (file_input_fd != -1) ? NULL : name; - if (!get_final_xattrs (self, modifier, child_relpath, child_info, child, - xattr_fd_arg, xattr_path_arg, source_xattrs, - &xattrs, &xattrs_were_modified, + if (!get_final_xattrs (self, modifier, child_relpath, child_info, child, xattr_fd_arg, + xattr_path_arg, source_xattrs, &xattrs, &xattrs_were_modified, cancellable, error)) return FALSE; } @@ -3797,11 +3591,9 @@ write_content_to_mtree_internal (OstreeRepo *self, /* A big prerequisite list of conditions for whether or not we can * "adopt", i.e. just checksum and rename() into place */ - const gboolean can_adopt_basic = - file_type == G_FILE_TYPE_REGULAR - && dfd_iter != NULL - && delete_after_commit - && ((writeflags & WRITE_DIR_CONTENT_FLAGS_CAN_ADOPT) > 0); + const gboolean can_adopt_basic = file_type == G_FILE_TYPE_REGULAR && dfd_iter != NULL + && delete_after_commit + && ((writeflags & WRITE_DIR_CONTENT_FLAGS_CAN_ADOPT) > 0); gboolean can_adopt = can_adopt_basic; /* If basic prerquisites are met, check repo mode specific ones */ if (can_adopt) @@ -3824,8 +3616,7 @@ write_content_to_mtree_internal (OstreeRepo *self, /* The very fast path - we have a devino cache hit, nothing to write */ if (loose_checksum && !modified_file_meta) { - if (!ostree_mutable_tree_replace_file (mtree, name, loose_checksum, - error)) + if (!ostree_mutable_tree_replace_file (mtree, name, loose_checksum, error)) return FALSE; g_mutex_lock (&self->txn_lock); @@ -3835,9 +3626,9 @@ write_content_to_mtree_internal (OstreeRepo *self, /* Next fast path - we can "adopt" the file */ else if (can_adopt) { - char checksum[OSTREE_SHA256_STRING_LEN+1]; - if (!adopt_and_commit_regfile (self, dfd_iter->fd, name, modified_info, xattrs, - checksum, cancellable, error)) + char checksum[OSTREE_SHA256_STRING_LEN + 1]; + if (!adopt_and_commit_regfile (self, dfd_iter->fd, name, modified_info, xattrs, checksum, + cancellable, error)) return FALSE; if (!ostree_mutable_tree_replace_file (mtree, name, checksum, error)) return FALSE; @@ -3845,14 +3636,14 @@ write_content_to_mtree_internal (OstreeRepo *self, } else { - g_autoptr(GInputStream) file_input = NULL; + g_autoptr (GInputStream) file_input = NULL; if (file_type == G_FILE_TYPE_REGULAR) { if (dir_enum != NULL) { g_assert (child != NULL); - file_input = (GInputStream*)g_file_read (child, cancellable, error); + file_input = (GInputStream *)g_file_read (child, cancellable, error); if (!file_input) return FALSE; } @@ -3864,14 +3655,13 @@ write_content_to_mtree_internal (OstreeRepo *self, } g_autofree guchar *child_file_csum = NULL; - if (!write_content_object (self, NULL, file_input, modified_info, xattrs, - &child_file_csum, cancellable, error)) + if (!write_content_object (self, NULL, file_input, modified_info, xattrs, &child_file_csum, + cancellable, error)) return FALSE; - char tmp_checksum[OSTREE_SHA256_STRING_LEN+1]; + char tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; ostree_checksum_inplace_from_bytes (child_file_csum, tmp_checksum); - if (!ostree_mutable_tree_replace_file (mtree, name, tmp_checksum, - error)) + if (!ostree_mutable_tree_replace_file (mtree, name, tmp_checksum, error)) return FALSE; } @@ -3892,13 +3682,9 @@ write_content_to_mtree_internal (OstreeRepo *self, /* Handles the dirmeta for the given GFile dir and then calls * write_{dir_entry,content}_to_mtree_internal() for each directory entry. */ static gboolean -write_directory_to_mtree_internal (OstreeRepo *self, - GFile *dir, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GPtrArray *path, - GCancellable *cancellable, - GError **error) +write_directory_to_mtree_internal (OstreeRepo *self, GFile *dir, OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, GPtrArray *path, + GCancellable *cancellable, GError **error) { OstreeRepoCommitFilterResult filter_result; OstreeRepoFile *repo_dir = NULL; @@ -3909,7 +3695,7 @@ write_directory_to_mtree_internal (OstreeRepo *self, /* If the directory is already in the repository, we can try to * reuse checksums to skip checksumming. */ if (dir && OSTREE_IS_REPO_FILE (dir) && modifier == NULL) - repo_dir = (OstreeRepoFile *) dir; + repo_dir = (OstreeRepoFile *)dir; if (repo_dir) { @@ -3918,24 +3704,23 @@ write_directory_to_mtree_internal (OstreeRepo *self, /* ostree_mutable_tree_fill_from_dirtree returns FALSE if mtree isn't * empty: in which case we're responsible for merging the trees. */ - if (ostree_mutable_tree_fill_empty_from_dirtree (mtree, - ostree_repo_file_get_repo (repo_dir), - ostree_repo_file_tree_get_contents_checksum (repo_dir), - ostree_repo_file_get_checksum (repo_dir))) + if (ostree_mutable_tree_fill_empty_from_dirtree ( + mtree, ostree_repo_file_get_repo (repo_dir), + ostree_repo_file_tree_get_contents_checksum (repo_dir), + ostree_repo_file_get_checksum (repo_dir))) return TRUE; - ostree_mutable_tree_set_metadata_checksum (mtree, ostree_repo_file_tree_get_metadata_checksum (repo_dir)); + ostree_mutable_tree_set_metadata_checksum ( + mtree, ostree_repo_file_tree_get_metadata_checksum (repo_dir)); filter_result = OSTREE_REPO_COMMIT_FILTER_ALLOW; } else { - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; - g_autoptr(GFileInfo) child_info = - g_file_query_info (dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + g_autoptr (GFileInfo) child_info = g_file_query_info ( + dir, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!child_info) return FALSE; @@ -3943,13 +3728,14 @@ write_directory_to_mtree_internal (OstreeRepo *self, if (modifier != NULL) relpath = ptrarray_path_join (path); - g_autoptr(GFileInfo) modified_info = NULL; - filter_result = _ostree_repo_commit_modifier_apply (self, modifier, relpath, child_info, &modified_info); + g_autoptr (GFileInfo) modified_info = NULL; + filter_result = _ostree_repo_commit_modifier_apply (self, modifier, relpath, child_info, + &modified_info); if (filter_result == OSTREE_REPO_COMMIT_FILTER_ALLOW) { - if (!get_final_xattrs (self, modifier, relpath, child_info, dir, -1, NULL, - NULL, &xattrs, NULL, cancellable, error)) + if (!get_final_xattrs (self, modifier, relpath, child_info, dir, -1, NULL, NULL, &xattrs, + NULL, cancellable, error)) return FALSE; g_autofree guchar *child_file_csum = NULL; @@ -3964,12 +3750,11 @@ write_directory_to_mtree_internal (OstreeRepo *self, if (filter_result == OSTREE_REPO_COMMIT_FILTER_ALLOW) { - g_autoptr(GFileEnumerator) dir_enum = NULL; + g_autoptr (GFileEnumerator) dir_enum = NULL; - dir_enum = g_file_enumerate_children ((GFile*)dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, - error); + dir_enum + = g_file_enumerate_children ((GFile *)dir, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_enum) return FALSE; @@ -3977,8 +3762,7 @@ write_directory_to_mtree_internal (OstreeRepo *self, { GFileInfo *child_info; - if (!g_file_enumerator_iterate (dir_enum, &child_info, NULL, - cancellable, error)) + if (!g_file_enumerator_iterate (dir_enum, &child_info, NULL, cancellable, error)) return FALSE; if (child_info == NULL) break; @@ -3986,19 +3770,15 @@ write_directory_to_mtree_internal (OstreeRepo *self, if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY) { if (!write_dir_entry_to_mtree_internal (self, repo_dir, dir_enum, NULL, - WRITE_DIR_CONTENT_FLAGS_NONE, - child_info, - mtree, modifier, path, - cancellable, error)) + WRITE_DIR_CONTENT_FLAGS_NONE, child_info, + mtree, modifier, path, cancellable, error)) return FALSE; } else { if (!write_content_to_mtree_internal (self, repo_dir, dir_enum, NULL, - WRITE_DIR_CONTENT_FLAGS_NONE, - child_info, - mtree, modifier, path, - cancellable, error)) + WRITE_DIR_CONTENT_FLAGS_NONE, child_info, mtree, + modifier, path, cancellable, error)) return FALSE; } } @@ -4010,16 +3790,12 @@ write_directory_to_mtree_internal (OstreeRepo *self, /* Handles the dirmeta for the dir described by src_dfd_iter and then calls * write_{dir_entry,content}_to_mtree_internal() for each directory entry. */ static gboolean -write_dfd_iter_to_mtree_internal (OstreeRepo *self, - GLnxDirFdIterator *src_dfd_iter, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GPtrArray *path, - GCancellable *cancellable, - GError **error) +write_dfd_iter_to_mtree_internal (OstreeRepo *self, GLnxDirFdIterator *src_dfd_iter, + OstreeMutableTree *mtree, OstreeRepoCommitModifier *modifier, + GPtrArray *path, GCancellable *cancellable, GError **error) { - g_autoptr(GFileInfo) modified_info = NULL; - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GFileInfo) modified_info = NULL; + g_autoptr (GVariant) xattrs = NULL; g_autofree guchar *child_file_csum = NULL; g_autofree char *relpath = NULL; OstreeRepoCommitFilterResult filter_result; @@ -4029,11 +3805,12 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self, return FALSE; { - g_autoptr(GFileInfo) child_info = _ostree_stbuf_to_gfileinfo (&dir_stbuf); + g_autoptr (GFileInfo) child_info = _ostree_stbuf_to_gfileinfo (&dir_stbuf); if (modifier != NULL) { relpath = ptrarray_path_join (path); - filter_result = _ostree_repo_commit_modifier_apply (self, modifier, relpath, child_info, &modified_info); + filter_result = _ostree_repo_commit_modifier_apply (self, modifier, relpath, child_info, + &modified_info); } else { @@ -4044,8 +3821,8 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self, if (filter_result == OSTREE_REPO_COMMIT_FILTER_ALLOW) { - if (!get_final_xattrs (self, modifier, relpath, modified_info, NULL, src_dfd_iter->fd, - NULL, NULL, &xattrs, NULL, cancellable, error)) + if (!get_final_xattrs (self, modifier, relpath, modified_info, NULL, src_dfd_iter->fd, NULL, + NULL, &xattrs, NULL, cancellable, error)) return FALSE; if (!_ostree_repo_write_directory_meta (self, modified_info, xattrs, &child_file_csum, @@ -4079,15 +3856,13 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self, if (!glnx_fstatat (src_dfd_iter->fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, error)) return FALSE; - g_autoptr(GFileInfo) child_info = _ostree_stbuf_to_gfileinfo (&stbuf); + g_autoptr (GFileInfo) child_info = _ostree_stbuf_to_gfileinfo (&stbuf); g_file_info_set_name (child_info, dent->d_name); if (S_ISDIR (stbuf.st_mode)) { - if (!write_dir_entry_to_mtree_internal (self, NULL, NULL, src_dfd_iter, - flags, child_info, - mtree, modifier, path, - cancellable, error)) + if (!write_dir_entry_to_mtree_internal (self, NULL, NULL, src_dfd_iter, flags, child_info, + mtree, modifier, path, cancellable, error)) return FALSE; /* We handled the dir, move onto the next */ @@ -4098,21 +3873,18 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self, ; else if (S_ISLNK (stbuf.st_mode)) { - if (!ot_readlinkat_gfile_info (src_dfd_iter->fd, dent->d_name, - child_info, cancellable, error)) + if (!ot_readlinkat_gfile_info (src_dfd_iter->fd, dent->d_name, child_info, cancellable, + error)) return FALSE; } else { - return glnx_throw (error, "Not a regular file or symlink: %s", - dent->d_name); + return glnx_throw (error, "Not a regular file or symlink: %s", dent->d_name); } /* Write a content object, we handled directories above */ - if (!write_content_to_mtree_internal (self, NULL, NULL, src_dfd_iter, - flags, child_info, - mtree, modifier, path, - cancellable, error)) + if (!write_content_to_mtree_internal (self, NULL, NULL, src_dfd_iter, flags, child_info, + mtree, modifier, path, cancellable, error)) return FALSE; } @@ -4132,28 +3904,24 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self, * overlaying the resulting filesystem hierarchy into @mtree. */ gboolean -ostree_repo_write_directory_to_mtree (OstreeRepo *self, - GFile *dir, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GCancellable *cancellable, - GError **error) +ostree_repo_write_directory_to_mtree (OstreeRepo *self, GFile *dir, OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, GCancellable *cancellable, + GError **error) { /* Short cut local files */ if (g_file_is_native (dir)) { - if (!ostree_repo_write_dfd_to_mtree (self, AT_FDCWD, gs_file_get_path_cached (dir), - mtree, modifier, cancellable, error)) + if (!ostree_repo_write_dfd_to_mtree (self, AT_FDCWD, gs_file_get_path_cached (dir), mtree, + modifier, cancellable, error)) return FALSE; } else { _ostree_repo_setup_generate_sizes (self, modifier); - g_autoptr(GPtrArray) path = g_ptr_array_new (); - if (!write_directory_to_mtree_internal (self, dir, mtree, modifier, path, - cancellable, error)) + g_autoptr (GPtrArray) path = g_ptr_array_new (); + if (!write_directory_to_mtree_internal (self, dir, mtree, modifier, path, cancellable, error)) return FALSE; } @@ -4175,23 +3943,21 @@ ostree_repo_write_directory_to_mtree (OstreeRepo *self, * resulting filesystem hierarchy into @mtree. */ gboolean -ostree_repo_write_dfd_to_mtree (OstreeRepo *self, - int dfd, - const char *path, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GCancellable *cancellable, - GError **error) +ostree_repo_write_dfd_to_mtree (OstreeRepo *self, int dfd, const char *path, + OstreeMutableTree *mtree, OstreeRepoCommitModifier *modifier, + GCancellable *cancellable, GError **error) { _ostree_repo_setup_generate_sizes (self, modifier); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error)) return FALSE; - g_autoptr(GPtrArray) pathbuilder = g_ptr_array_new (); - if (!write_dfd_iter_to_mtree_internal (self, &dfd_iter, mtree, modifier, pathbuilder, - cancellable, error)) + g_autoptr (GPtrArray) pathbuilder = g_ptr_array_new (); + if (!write_dfd_iter_to_mtree_internal (self, &dfd_iter, mtree, modifier, pathbuilder, cancellable, + error)) return FALSE; /* And now finally remove the toplevel; see also the handling for this flag in @@ -4199,8 +3965,8 @@ ostree_repo_write_dfd_to_mtree (OstreeRepo *self, * try to remove `.` (since we'd get EINVAL); that's what's used in * rpm-ostree. */ - const gboolean delete_after_commit = modifier && - (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME); + const gboolean delete_after_commit + = modifier && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME); if (delete_after_commit && !g_str_equal (path, ".")) { if (!glnx_unlinkat (dfd, path, AT_REMOVEDIR, error)) @@ -4223,14 +3989,11 @@ ostree_repo_write_dfd_to_mtree (OstreeRepo *self, * the @mtree represented. */ gboolean -ostree_repo_write_mtree (OstreeRepo *self, - OstreeMutableTree *mtree, - GFile **out_file, - GCancellable *cancellable, - GError **error) +ostree_repo_write_mtree (OstreeRepo *self, OstreeMutableTree *mtree, GFile **out_file, + GCancellable *cancellable, GError **error) { const char *contents_checksum, *metadata_checksum; - g_autoptr(GFile) ret_file = NULL; + g_autoptr (GFile) ret_file = NULL; if (!ostree_mutable_tree_check_error (mtree, error)) return glnx_prefix_error (error, "mtree"); @@ -4246,44 +4009,44 @@ ostree_repo_write_mtree (OstreeRepo *self, } else { - g_autoptr(GHashTable) dir_metadata_checksums = NULL; - g_autoptr(GHashTable) dir_contents_checksums = NULL; - g_autoptr(GVariant) serialized_tree = NULL; + g_autoptr (GHashTable) dir_metadata_checksums = NULL; + g_autoptr (GHashTable) dir_contents_checksums = NULL; + g_autoptr (GVariant) serialized_tree = NULL; g_autofree guchar *contents_csum = NULL; - char contents_checksum_buf[OSTREE_SHA256_STRING_LEN+1]; + char contents_checksum_buf[OSTREE_SHA256_STRING_LEN + 1]; - dir_contents_checksums = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, (GDestroyNotify)g_free); - dir_metadata_checksums = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, (GDestroyNotify)g_free); + dir_contents_checksums = g_hash_table_new_full ( + g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); + dir_metadata_checksums = g_hash_table_new_full ( + g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); - GLNX_HASH_TABLE_FOREACH_KV (ostree_mutable_tree_get_subdirs (mtree), - const char*, name, OstreeMutableTree*, child_dir) + GLNX_HASH_TABLE_FOREACH_KV (ostree_mutable_tree_get_subdirs (mtree), const char *, name, + OstreeMutableTree *, child_dir) { - g_autoptr(GFile) child_file = NULL; - if (!ostree_repo_write_mtree (self, child_dir, &child_file, - cancellable, error)) + g_autoptr (GFile) child_file = NULL; + if (!ostree_repo_write_mtree (self, child_dir, &child_file, cancellable, error)) return FALSE; g_hash_table_replace (dir_contents_checksums, g_strdup (name), - g_strdup (ostree_repo_file_tree_get_contents_checksum (OSTREE_REPO_FILE (child_file)))); + g_strdup (ostree_repo_file_tree_get_contents_checksum ( + OSTREE_REPO_FILE (child_file)))); g_hash_table_replace (dir_metadata_checksums, g_strdup (name), - g_strdup (ostree_repo_file_tree_get_metadata_checksum (OSTREE_REPO_FILE (child_file)))); + g_strdup (ostree_repo_file_tree_get_metadata_checksum ( + OSTREE_REPO_FILE (child_file)))); } - serialized_tree = create_tree_variant_from_hashes (ostree_mutable_tree_get_files (mtree), - dir_contents_checksums, - dir_metadata_checksums); + serialized_tree = create_tree_variant_from_hashes ( + ostree_mutable_tree_get_files (mtree), dir_contents_checksums, dir_metadata_checksums); - if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_DIR_TREE, NULL, - serialized_tree, &contents_csum, - cancellable, error)) + if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_DIR_TREE, NULL, serialized_tree, + &contents_csum, cancellable, error)) return FALSE; ostree_checksum_inplace_from_bytes (contents_csum, contents_checksum_buf); ostree_mutable_tree_set_contents_checksum (mtree, contents_checksum_buf); - ret_file = G_FILE (_ostree_repo_file_new_root (self, contents_checksum_buf, metadata_checksum)); + ret_file + = G_FILE (_ostree_repo_file_new_root (self, contents_checksum_buf, metadata_checksum)); } if (out_file) @@ -4301,10 +4064,9 @@ ostree_repo_write_mtree (OstreeRepo *self, * Returns: (transfer full): A new commit modifier. */ OstreeRepoCommitModifier * -ostree_repo_commit_modifier_new (OstreeRepoCommitModifierFlags flags, - OstreeRepoCommitFilter commit_filter, - gpointer user_data, - GDestroyNotify destroy_notify) +ostree_repo_commit_modifier_new (OstreeRepoCommitModifierFlags flags, + OstreeRepoCommitFilter commit_filter, gpointer user_data, + GDestroyNotify destroy_notify) { OstreeRepoCommitModifier *modifier = g_new0 (OstreeRepoCommitModifier, 1); @@ -4360,10 +4122,9 @@ ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier) * repository. */ void -ostree_repo_commit_modifier_set_xattr_callback (OstreeRepoCommitModifier *modifier, - OstreeRepoCommitModifierXattrCallback callback, - GDestroyNotify destroy, - gpointer user_data) +ostree_repo_commit_modifier_set_xattr_callback (OstreeRepoCommitModifier *modifier, + OstreeRepoCommitModifierXattrCallback callback, + GDestroyNotify destroy, gpointer user_data) { modifier->xattr_callback = callback; modifier->xattr_destroy = destroy; @@ -4385,8 +4146,8 @@ ostree_repo_commit_modifier_set_xattr_callback (OstreeRepoCommitModifier *modif * policy wins. */ void -ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier *modifier, - OstreeSePolicy *sepolicy) +ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier *modifier, + OstreeSePolicy *sepolicy) { g_clear_object (&modifier->sepolicy); modifier->sepolicy = sepolicy ? g_object_ref (sepolicy) : NULL; @@ -4406,14 +4167,13 @@ ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier * * Since: 2020.4 */ -gboolean -ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier *modifier, - OstreeRepo *repo, - const char *rev, - GCancellable *cancellable, - GError **error) +gboolean +ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier *modifier, + OstreeRepo *repo, const char *rev, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeSePolicy) policy = ostree_sepolicy_new_from_commit (repo, rev, cancellable, error); + g_autoptr (OstreeSePolicy) policy + = ostree_sepolicy_new_from_commit (repo, rev, cancellable, error); if (!policy) return FALSE; ostree_repo_commit_modifier_set_sepolicy (modifier, policy); @@ -4439,55 +4199,50 @@ ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier * Since: 2017.13 */ void -ostree_repo_commit_modifier_set_devino_cache (OstreeRepoCommitModifier *modifier, - OstreeRepoDevInoCache *cache) +ostree_repo_commit_modifier_set_devino_cache (OstreeRepoCommitModifier *modifier, + OstreeRepoDevInoCache *cache) { - modifier->devino_cache = g_hash_table_ref ((GHashTable*)cache); + modifier->devino_cache = g_hash_table_ref ((GHashTable *)cache); } OstreeRepoDevInoCache * ostree_repo_devino_cache_ref (OstreeRepoDevInoCache *cache) { - g_hash_table_ref ((GHashTable*)cache); + g_hash_table_ref ((GHashTable *)cache); return cache; } void ostree_repo_devino_cache_unref (OstreeRepoDevInoCache *cache) { - g_hash_table_unref ((GHashTable*)cache); + g_hash_table_unref ((GHashTable *)cache); } -G_DEFINE_BOXED_TYPE(OstreeRepoDevInoCache, ostree_repo_devino_cache, - ostree_repo_devino_cache_ref, - ostree_repo_devino_cache_unref); +G_DEFINE_BOXED_TYPE (OstreeRepoDevInoCache, ostree_repo_devino_cache, ostree_repo_devino_cache_ref, + ostree_repo_devino_cache_unref); -G_DEFINE_BOXED_TYPE(OstreeRepoCommitModifier, ostree_repo_commit_modifier, - ostree_repo_commit_modifier_ref, - ostree_repo_commit_modifier_unref); +G_DEFINE_BOXED_TYPE (OstreeRepoCommitModifier, ostree_repo_commit_modifier, + ostree_repo_commit_modifier_ref, ostree_repo_commit_modifier_unref); /* Special case between bare-user and bare-user-only, * mostly for https://github.com/flatpak/flatpak/issues/845 * see below for any more comments. */ static gboolean -import_is_bareuser_only_conversion (OstreeRepo *src_repo, - OstreeRepo *dest_repo, +import_is_bareuser_only_conversion (OstreeRepo *src_repo, OstreeRepo *dest_repo, OstreeObjectType objtype) { return src_repo->mode == OSTREE_REPO_MODE_BARE_USER - && dest_repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY - && objtype == OSTREE_OBJECT_TYPE_FILE; + && dest_repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY + && objtype == OSTREE_OBJECT_TYPE_FILE; } /* Returns TRUE if we can potentially just call link() to copy an object; * if untrusted the repos must be owned by the same uid. */ static gboolean -import_via_reflink_is_possible (OstreeRepo *src_repo, - OstreeRepo *dest_repo, - OstreeObjectType objtype, - gboolean trusted) +import_via_reflink_is_possible (OstreeRepo *src_repo, OstreeRepo *dest_repo, + OstreeObjectType objtype, gboolean trusted) { /* Untrusted pulls require matching ownership */ if (!trusted && (src_repo->owner_uid != dest_repo->owner_uid)) @@ -4495,8 +4250,7 @@ import_via_reflink_is_possible (OstreeRepo *src_repo, /* Equal modes are always compatible, and metadata * is identical between all modes. */ - if (src_repo->mode == dest_repo->mode || - OSTREE_OBJECT_TYPE_IS_META (objtype)) + if (src_repo->mode == dest_repo->mode || OSTREE_OBJECT_TYPE_IS_META (objtype)) return TRUE; /* And now a special case between bare-user and bare-user-only, * mostly for https://github.com/flatpak/flatpak/issues/845 @@ -4510,23 +4264,18 @@ import_via_reflink_is_possible (OstreeRepo *src_repo, * to @self. */ static gboolean -copy_detached_metadata (OstreeRepo *self, - OstreeRepo *source, - const char *checksum, - GCancellable *cancellable, - GError **error) +copy_detached_metadata (OstreeRepo *self, OstreeRepo *source, const char *checksum, + GCancellable *cancellable, GError **error) { - g_autoptr(GVariant) detached_meta = NULL; - if (!ostree_repo_read_commit_detached_metadata (source, - checksum, &detached_meta, - cancellable, error)) + g_autoptr (GVariant) detached_meta = NULL; + if (!ostree_repo_read_commit_detached_metadata (source, checksum, &detached_meta, cancellable, + error)) return FALSE; if (detached_meta) { - if (!ostree_repo_write_commit_detached_metadata (self, - checksum, detached_meta, - cancellable, error)) + if (!ostree_repo_write_commit_detached_metadata (self, checksum, detached_meta, cancellable, + error)) return FALSE; } @@ -4538,24 +4287,19 @@ copy_detached_metadata (OstreeRepo *self, * we're not verifying the checksum. */ static gboolean -import_one_object_direct (OstreeRepo *dest_repo, - OstreeRepo *src_repo, - const char *checksum, - OstreeObjectType objtype, - gboolean *out_was_supported, - GCancellable *cancellable, - GError **error) +import_one_object_direct (OstreeRepo *dest_repo, OstreeRepo *src_repo, const char *checksum, + OstreeObjectType objtype, gboolean *out_was_supported, + GCancellable *cancellable, GError **error) { - const char *errprefix = glnx_strjoina ("Importing ", checksum, ".", - ostree_object_type_to_string (objtype)); + const char *errprefix + = glnx_strjoina ("Importing ", checksum, ".", ostree_object_type_to_string (objtype)); GLNX_AUTO_PREFIX_ERROR (errprefix, error); char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (loose_path_buf, checksum, objtype, dest_repo->mode); /* hardlinks require the owner to match and to be on the same device */ - const gboolean can_hardlink = - src_repo->owner_uid == dest_repo->owner_uid && - src_repo->device == dest_repo->device; + const gboolean can_hardlink + = src_repo->owner_uid == dest_repo->owner_uid && src_repo->device == dest_repo->device; /* Find our target dfd */ int dest_dfd; @@ -4595,8 +4339,8 @@ import_one_object_direct (OstreeRepo *dest_repo, { struct stat stbuf; - if (!glnx_fstatat (src_repo->objects_dir_fd, loose_path_buf, - &stbuf, AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat (src_repo->objects_dir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW, + error)) return FALSE; /* Let's punt for symlinks right now, it's more complicated */ @@ -4611,17 +4355,17 @@ import_one_object_direct (OstreeRepo *dest_repo, * in the future we should add flags for those things? */ glnx_autofd int src_fd = -1; - if (!glnx_openat_rdonly (src_repo->objects_dir_fd, loose_path_buf, - FALSE, &src_fd, error)) + if (!glnx_openat_rdonly (src_repo->objects_dir_fd, loose_path_buf, FALSE, &src_fd, error)) return FALSE; /* Open a tmpfile for dest */ - g_auto(GLnxTmpfile) tmp_dest = { 0, }; - if (!glnx_open_tmpfile_linkable_at (dest_dfd, ".", O_WRONLY | O_CLOEXEC, - &tmp_dest, error)) + g_auto (GLnxTmpfile) tmp_dest = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (dest_dfd, ".", O_WRONLY | O_CLOEXEC, &tmp_dest, error)) return FALSE; - if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t) -1) < 0) + if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t)-1) < 0) return glnx_throw_errno_prefix (error, "regfile copy"); /* Only chown for true bare repos */ @@ -4635,18 +4379,17 @@ import_one_object_direct (OstreeRepo *dest_repo, * bare-user-only. We also only do this for content * objects. */ - const gboolean src_is_bare_or_bare_user = - G_IN_SET (src_repo->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER); - if (src_is_bare_or_bare_user && !OSTREE_OBJECT_TYPE_IS_META(objtype)) + const gboolean src_is_bare_or_bare_user + = G_IN_SET (src_repo->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER); + if (src_is_bare_or_bare_user && !OSTREE_OBJECT_TYPE_IS_META (objtype)) { if (src_repo->mode == OSTREE_REPO_MODE_BARE) { - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; xattrs = ostree_fs_get_all_xattrs (src_fd, cancellable, error); if (!xattrs) return FALSE; - if (!glnx_fd_set_all_xattrs (tmp_dest.fd, xattrs, - cancellable, error)) + if (!glnx_fd_set_all_xattrs (tmp_dest.fd, xattrs, cancellable, error)) return FALSE; } else if (dest_repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY) @@ -4662,14 +4405,14 @@ import_one_object_direct (OstreeRepo *dest_repo, g_assert (src_repo->mode == dest_repo->mode); /* bare-user; we just want ostree.usermeta */ - g_autoptr(GBytes) bytes = - glnx_fgetxattr_bytes (src_fd, "user.ostreemeta", error); + g_autoptr (GBytes) bytes = glnx_fgetxattr_bytes (src_fd, "user.ostreemeta", error); if (bytes == NULL) return FALSE; if (TEMP_FAILURE_RETRY (fsetxattr (tmp_dest.fd, "user.ostreemeta", - (char*)g_bytes_get_data (bytes, NULL), - g_bytes_get_size (bytes), 0)) != 0) + (char *)g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), 0)) + != 0) return glnx_throw_errno_prefix (error, "fsetxattr"); } } @@ -4685,11 +4428,11 @@ import_one_object_direct (OstreeRepo *dest_repo, struct timespec ts[2]; ts[0] = stbuf.st_atim; ts[1] = stbuf.st_mtim; - (void) futimens (tmp_dest.fd, ts); + (void)futimens (tmp_dest.fd, ts); } - if (!_ostree_repo_commit_tmpf_final (dest_repo, checksum, objtype, - &tmp_dest, cancellable, error)) + if (!_ostree_repo_commit_tmpf_final (dest_repo, checksum, objtype, &tmp_dest, cancellable, + error)) return FALSE; } @@ -4711,13 +4454,9 @@ import_one_object_direct (OstreeRepo *dest_repo, * with flags; may make this public API later. */ gboolean -_ostree_repo_import_object (OstreeRepo *self, - OstreeRepo *source, - OstreeObjectType objtype, - const char *checksum, - OstreeRepoImportFlags flags, - GCancellable *cancellable, - GError **error) +_ostree_repo_import_object (OstreeRepo *self, OstreeRepo *source, OstreeObjectType objtype, + const char *checksum, OstreeRepoImportFlags flags, + GCancellable *cancellable, GError **error) { const gboolean trusted = (flags & _OSTREE_REPO_IMPORT_FLAGS_TRUSTED) > 0; /* Implements OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES which was designed for flatpak */ @@ -4725,8 +4464,8 @@ _ostree_repo_import_object (OstreeRepo *self, /* A special case between bare-user and bare-user-only, * mostly for https://github.com/flatpak/flatpak/issues/845 */ - const gboolean is_bareuseronly_conversion = - import_is_bareuser_only_conversion (source, self, objtype); + const gboolean is_bareuseronly_conversion + = import_is_bareuser_only_conversion (source, self, objtype); gboolean try_direct = TRUE; /* If we need to do bareuseronly verification, or we're potentially doing a @@ -4735,10 +4474,8 @@ _ostree_repo_import_object (OstreeRepo *self, */ if ((verify_bareuseronly || is_bareuseronly_conversion) && !OSTREE_OBJECT_TYPE_IS_META (objtype)) { - g_autoptr(GFileInfo) src_finfo = NULL; - if (!ostree_repo_load_file (source, checksum, - NULL, &src_finfo, NULL, - cancellable, error)) + g_autoptr (GFileInfo) src_finfo = NULL; + if (!ostree_repo_load_file (source, checksum, NULL, &src_finfo, NULL, cancellable, error)) return FALSE; if (verify_bareuseronly) @@ -4776,14 +4513,12 @@ _ostree_repo_import_object (OstreeRepo *self, */ if (!trusted) { - if (!ostree_repo_fsck_object (source, objtype, checksum, - cancellable, error)) + if (!ostree_repo_fsck_object (source, objtype, checksum, cancellable, error)) return FALSE; } gboolean direct_was_supported = FALSE; - if (!import_one_object_direct (self, source, checksum, objtype, - &direct_was_supported, + if (!import_one_object_direct (self, source, checksum, objtype, &direct_was_supported, cancellable, error)) return FALSE; @@ -4799,8 +4534,7 @@ _ostree_repo_import_object (OstreeRepo *self, /* First, do we have the object already? */ gboolean has_object; - if (!ostree_repo_has_object (self, objtype, checksum, &has_object, - cancellable, error)) + if (!ostree_repo_has_object (self, objtype, checksum, &has_object, cancellable, error)) return FALSE; /* If we have it, we're done */ if (has_object) @@ -4816,7 +4550,7 @@ _ostree_repo_import_object (OstreeRepo *self, if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { /* Metadata object */ - g_autoptr(GVariant) variant = NULL; + g_autoptr (GVariant) variant = NULL; if (objtype == OSTREE_OBJECT_TYPE_COMMIT) { @@ -4825,34 +4559,28 @@ _ostree_repo_import_object (OstreeRepo *self, return FALSE; } - if (!ostree_repo_load_variant (source, objtype, checksum, - &variant, error)) + if (!ostree_repo_load_variant (source, objtype, checksum, &variant, error)) return FALSE; /* Note this one also now verifies structure in the !trusted case */ g_autofree guchar *real_csum = NULL; - if (!ostree_repo_write_metadata (self, objtype, - checksum, variant, - trusted ? NULL : &real_csum, - cancellable, error)) + if (!ostree_repo_write_metadata (self, objtype, checksum, variant, + trusted ? NULL : &real_csum, cancellable, error)) return FALSE; } else { /* Content object */ guint64 length; - g_autoptr(GInputStream) object_stream = NULL; + g_autoptr (GInputStream) object_stream = NULL; - if (!ostree_repo_load_object_stream (source, objtype, checksum, - &object_stream, &length, + if (!ostree_repo_load_object_stream (source, objtype, checksum, &object_stream, &length, cancellable, error)) return FALSE; g_autofree guchar *real_csum = NULL; - if (!ostree_repo_write_content (self, checksum, - object_stream, length, - trusted ? NULL : &real_csum, - cancellable, error)) + if (!ostree_repo_write_content (self, checksum, object_stream, length, + trusted ? NULL : &real_csum, cancellable, error)) return FALSE; } @@ -4862,7 +4590,7 @@ _ostree_repo_import_object (OstreeRepo *self, static OstreeRepoTransactionStats * ostree_repo_transaction_stats_copy (OstreeRepoTransactionStats *stats) { - return g_memdup (stats, sizeof (OstreeRepoTransactionStats)); + return g_memdup2 (stats, sizeof (OstreeRepoTransactionStats)); } static void @@ -4871,6 +4599,68 @@ ostree_repo_transaction_stats_free (OstreeRepoTransactionStats *stats) return g_free (stats); } -G_DEFINE_BOXED_TYPE(OstreeRepoTransactionStats, ostree_repo_transaction_stats, - ostree_repo_transaction_stats_copy, - ostree_repo_transaction_stats_free); +G_DEFINE_BOXED_TYPE (OstreeRepoTransactionStats, ostree_repo_transaction_stats, + ostree_repo_transaction_stats_copy, ostree_repo_transaction_stats_free); + +gboolean +_ostree_repo_transaction_write_repo_metadata (OstreeRepo *self, GVariant *additional_metadata, + char **out_checksum, GCancellable *cancellable, + GError **error) +{ + g_assert (self != NULL); + g_assert (OSTREE_IS_REPO (self)); + g_assert (self->in_transaction == TRUE); + + const char *collection_id = ostree_repo_get_collection_id (self); + if (collection_id == NULL) + return glnx_throw (error, "Repository must have collection ID to write repo metadata"); + + OstreeCollectionRef collection_ref + = { (gchar *)collection_id, (gchar *)OSTREE_REPO_METADATA_REF }; + g_autofree char *old_checksum = NULL; + if (!ostree_repo_resolve_rev (self, OSTREE_REPO_METADATA_REF, TRUE, &old_checksum, error)) + return FALSE; + + /* Add bindings to the commit metadata. */ + g_autoptr (GVariantDict) metadata_dict = g_variant_dict_new (additional_metadata); + g_variant_dict_insert (metadata_dict, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "s", + collection_ref.collection_id); + g_variant_dict_insert_value ( + metadata_dict, OSTREE_COMMIT_META_KEY_REF_BINDING, + g_variant_new_strv ((const gchar *const *)&collection_ref.ref_name, 1)); + g_autoptr (GVariant) metadata = g_variant_dict_end (metadata_dict); + + /* Set up an empty mtree. */ + g_autoptr (OstreeMutableTree) mtree = ostree_mutable_tree_new (); + + glnx_unref_object GFileInfo *fi = g_file_info_new (); + g_file_info_set_attribute_uint32 (fi, "unix::uid", 0); + g_file_info_set_attribute_uint32 (fi, "unix::gid", 0); + g_file_info_set_attribute_uint32 (fi, "unix::mode", (0755 | S_IFDIR)); + + g_autoptr (GVariant) dirmeta = ostree_create_directory_metadata (fi, NULL /* xattrs */); + + g_autofree guchar *csum_raw = NULL; + if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_DIR_META, NULL, dirmeta, &csum_raw, + cancellable, error)) + return FALSE; + + g_autofree char *csum = ostree_checksum_from_bytes (csum_raw); + ostree_mutable_tree_set_metadata_checksum (mtree, csum); + + g_autoptr (OstreeRepoFile) repo_file = NULL; + if (!ostree_repo_write_mtree (self, mtree, (GFile **)&repo_file, cancellable, error)) + return FALSE; + + g_autofree gchar *new_checksum = NULL; + if (!ostree_repo_write_commit (self, old_checksum, NULL /* subject */, NULL /* body */, metadata, + repo_file, &new_checksum, cancellable, error)) + return FALSE; + + ostree_repo_transaction_set_collection_ref (self, &collection_ref, new_checksum); + + if (out_checksum != NULL) + *out_checksum = g_steal_pointer (&new_checksum); + + return TRUE; +} diff --git a/src/libostree/ostree-repo-composefs.c b/src/libostree/ostree-repo-composefs.c new file mode 100644 index 0000000..cc5e5fd --- /dev/null +++ b/src/libostree/ostree-repo-composefs.c @@ -0,0 +1,616 @@ +/* + * Copyright (C) Red Hat, Inc. + * + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include +#include +#include + +#include "ostree-core-private.h" +#include "ostree-repo-file.h" +#include "ostree-repo-private.h" + +#ifdef HAVE_COMPOSEFS +#include +#endif + +#ifdef HAVE_LINUX_FSVERITY_H +#include +#endif + +gboolean +_ostree_repo_parse_composefs_config (OstreeRepo *self, GError **error) +{ + /* Currently experimental */ + OtTristate use_composefs; + + if (!ot_keyfile_get_tristate_with_default (self->config, _OSTREE_INTEGRITY_SECTION, "composefs", + OT_TRISTATE_NO, &use_composefs, error)) + return FALSE; + + self->composefs_wanted = use_composefs; +#ifdef HAVE_COMPOSEFS + self->composefs_supported = TRUE; +#else + self->composefs_supported = FALSE; +#endif + + if (use_composefs == OT_TRISTATE_YES && !self->composefs_supported) + return glnx_throw (error, "composefs required, but libostree compiled without support"); + + return TRUE; +} + +struct OstreeComposefsTarget +{ +#ifdef HAVE_COMPOSEFS + struct lcfs_node_s *dest; +#endif + int ref_count; +}; + +/** + * ostree_composefs_target_new: + * + * Creates a #OstreeComposefsTarget which can be used with + * ostree_repo_checkout_composefs() to create a composefs image based + * on a set of checkouts. + * + * Returns: (transfer full): a new of #OstreeComposefsTarget + */ +OstreeComposefsTarget * +ostree_composefs_target_new (void) +{ + OstreeComposefsTarget *target; + + target = g_slice_new0 (OstreeComposefsTarget); + +#ifdef HAVE_COMPOSEFS + target->dest = lcfs_node_new (); + lcfs_node_set_mode (target->dest, 0755 | S_IFDIR); +#endif + + target->ref_count = 1; + + return target; +} + +/** + * ostree_composefs_target_ref: + * @target: an #OstreeComposefsTarget + * + * Increase the reference count on the given @target. + * + * Returns: (transfer full): a copy of @target, for convenience + */ +OstreeComposefsTarget * +ostree_composefs_target_ref (OstreeComposefsTarget *target) +{ + gint refcount; + g_return_val_if_fail (target != NULL, NULL); + refcount = g_atomic_int_add (&target->ref_count, 1); + g_assert (refcount > 0); + return target; +} + +/** + * ostree_composefs_target_unref: + * @target: (transfer full): an #OstreeComposefsTarget + * + * Decrease the reference count on the given @target and free it if the + * reference count reaches 0. + */ +void +ostree_composefs_target_unref (OstreeComposefsTarget *target) +{ + g_return_if_fail (target != NULL); + g_return_if_fail (target->ref_count > 0); + + if (g_atomic_int_dec_and_test (&target->ref_count)) + { +#ifdef HAVE_COMPOSEFS + g_clear_pointer (&target->dest, lcfs_node_unref); +#endif + g_slice_free (OstreeComposefsTarget, target); + } +} + +G_DEFINE_BOXED_TYPE (OstreeComposefsTarget, ostree_composefs_target, ostree_composefs_target_ref, + ostree_composefs_target_unref); + +#ifdef HAVE_COMPOSEFS + +static ssize_t +_composefs_read_cb (void *_file, void *buf, size_t count) +{ + GInputStream *in = _file; + gsize bytes_read; + + if (!g_input_stream_read_all (in, buf, count, &bytes_read, NULL, NULL)) + { + errno = EIO; + return -1; + } + + return bytes_read; +} + +static ssize_t +_composefs_write_cb (void *file, void *buf, size_t len) +{ + int fd = GPOINTER_TO_INT (file); + const char *content = buf; + ssize_t res = 0; + + while (len > 0) + { + res = write (fd, content, len); + if (res < 0 && errno == EINTR) + continue; + + if (res <= 0) + { + if (res == 0) /* Unexpected short write, should not happen when writing to a file */ + errno = ENOSPC; + return -1; + } + + break; + } + + return res; +} + +#else /* HAVE_COMPOSEFS */ + +static gboolean +composefs_not_supported (GError **error) +{ + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "composefs is not supported in this ostree build"); + return FALSE; +} + +#endif + +/** + * ostree_composefs_target_write: + * @target: an #OstreeComposefsTarget + * @fd: Write image here (or -1 to not write) + * @out_fsverity_digest: (out) (array fixed-size=32) (nullable): Return location for the fsverity + * binary digest, or %NULL to not compute it + * @cancellable: Cancellable + * @error: Error + * + * Writes a composefs image file to the filesystem at the + * path specified by @destination_dfd and destination_path (if not %NULL) + * and (optionally) computes the fsverity digest of the image. + * + * Returns: %TRUE on success, %FALSE on failure + */ +gboolean +ostree_composefs_target_write (OstreeComposefsTarget *target, int fd, guchar **out_fsverity_digest, + GCancellable *cancellable, GError **error) +{ +#ifdef HAVE_COMPOSEFS + GLNX_AUTO_PREFIX_ERROR ("Writing composefs", error); + g_autoptr (GOutputStream) tmp_out = NULL; + g_autoptr (GOutputStream) out = NULL; + struct lcfs_node_s *root; + g_autofree guchar *fsverity_digest = NULL; + struct lcfs_write_options_s options = { + LCFS_FORMAT_EROFS, + }; + + root = lcfs_node_lookup_child (target->dest, "root"); + if (root == NULL) + root = target->dest; /* Nothing was checked out, use an empty dir */ + + if (out_fsverity_digest) + { + fsverity_digest = g_malloc (OSTREE_SHA256_DIGEST_LEN); + options.digest_out = fsverity_digest; + } + + if (fd != -1) + { + options.file = GINT_TO_POINTER (fd); + options.file_write_cb = _composefs_write_cb; + } + + if (lcfs_write_to (root, &options) != 0) + return glnx_throw_errno_prefix (error, "lcfs_write_to"); + + if (out_fsverity_digest) + *out_fsverity_digest = g_steal_pointer (&fsverity_digest); + + return TRUE; +#else + return composefs_not_supported (error); +#endif +} + +#ifdef HAVE_COMPOSEFS +static gboolean +_ostree_composefs_set_xattrs (struct lcfs_node_s *node, GVariant *xattrs, GCancellable *cancellable, + GError **error) +{ + const guint n = g_variant_n_children (xattrs); + for (guint i = 0; i < n; i++) + { + const guint8 *name; + g_autoptr (GVariant) value = NULL; + g_variant_get_child (xattrs, i, "(^&ay@ay)", &name, &value); + + gsize value_len; + const guint8 *value_data = g_variant_get_fixed_array (value, &value_len, 1); + + if (lcfs_node_set_xattr (node, (char *)name, (char *)value_data, value_len) != 0) + return glnx_throw_errno_prefix (error, "Setting composefs xattrs for %s", name); + } + + return TRUE; +} + +static gboolean +checkout_one_composefs_file_at (OstreeRepo *repo, const char *checksum, struct lcfs_node_s *parent, + const char *destination_name, GCancellable *cancellable, + GError **error) +{ + g_autoptr (GInputStream) input = NULL; + g_autoptr (GVariant) xattrs = NULL; + struct lcfs_node_s *existing; + + /* Validate this up front to prevent path traversal attacks */ + if (!ot_util_filename_validate (destination_name, error)) + return FALSE; + + existing = lcfs_node_lookup_child (parent, destination_name); + if (existing != NULL) + return glnx_throw (error, "Target checkout file already exist"); + + g_autoptr (GFileInfo) source_info = NULL; + if (!ostree_repo_load_file (repo, checksum, &input, &source_info, &xattrs, cancellable, error)) + return FALSE; + + const guint32 source_mode = g_file_info_get_attribute_uint32 (source_info, "unix::mode"); + const guint32 source_uid = g_file_info_get_attribute_uint32 (source_info, "unix::uid"); + const guint32 source_gid = g_file_info_get_attribute_uint32 (source_info, "unix::gid"); + const guint64 source_size = g_file_info_get_size (source_info); + const gboolean is_symlink + = (g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK); + + struct lcfs_node_s *node = lcfs_node_new (); + if (node == NULL) + return glnx_throw (error, "Out of memory"); + + /* Takes ownership on success */ + if (lcfs_node_add_child (parent, node, destination_name) != 0) + { + lcfs_node_unref (node); + return glnx_throw_errno (error); + } + + lcfs_node_set_mode (node, source_mode); + lcfs_node_set_uid (node, source_uid); + lcfs_node_set_gid (node, source_gid); + lcfs_node_set_size (node, source_size); + if (is_symlink) + { + const char *source_symlink_target = g_file_info_get_symlink_target (source_info); + if (lcfs_node_set_payload (node, source_symlink_target) != 0) + return glnx_throw_errno (error); + } + else if (source_size != 0) + { + char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; + _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE); + if (lcfs_node_set_payload (node, loose_path_buf) != 0) + return glnx_throw_errno (error); + + guchar *known_digest = NULL; + +#ifdef HAVE_LINUX_FSVERITY_H + /* First try to get the digest directly from the bare repo file. + * This is the typical case when we're pulled into the target + * system repo with verity on and are recreating the composefs + * image during deploy. */ + char buf[sizeof (struct fsverity_digest) + OSTREE_SHA256_DIGEST_LEN]; + + if (G_IS_UNIX_INPUT_STREAM (input)) + { + int content_fd = g_unix_input_stream_get_fd (G_UNIX_INPUT_STREAM (input)); + struct fsverity_digest *d = (struct fsverity_digest *)&buf; + d->digest_size = OSTREE_SHA256_DIGEST_LEN; + + if (ioctl (content_fd, FS_IOC_MEASURE_VERITY, d) == 0 + && d->digest_size == OSTREE_SHA256_DIGEST_LEN + && d->digest_algorithm == FS_VERITY_HASH_ALG_SHA256) + known_digest = d->digest; + } +#endif + + if (known_digest) + lcfs_node_set_fsverity_digest (node, known_digest); + else if (lcfs_node_set_fsverity_from_content (node, input, _composefs_read_cb) != 0) + return glnx_throw_errno (error); + } + + if (xattrs) + { + if (!_ostree_composefs_set_xattrs (node, xattrs, cancellable, error)) + return FALSE; + } + + g_clear_object (&input); + + return TRUE; +} + +static gboolean +checkout_composefs_recurse (OstreeRepo *self, const char *dirtree_checksum, + const char *dirmeta_checksum, struct lcfs_node_s *parent, + const char *name, GCancellable *cancellable, GError **error) +{ + g_autoptr (GVariant) dirtree = NULL; + g_autoptr (GVariant) dirmeta = NULL; + g_autoptr (GVariant) xattrs = NULL; + struct lcfs_node_s *directory; + + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_TREE, dirtree_checksum, &dirtree, + error)) + return FALSE; + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_META, dirmeta_checksum, &dirmeta, + error)) + return FALSE; + + /* Parse OSTREE_OBJECT_TYPE_DIR_META */ + guint32 uid, gid, mode; + g_variant_get (dirmeta, "(uuu@a(ayay))", &uid, &gid, &mode, &xattrs); + uid = GUINT32_FROM_BE (uid); + gid = GUINT32_FROM_BE (gid); + mode = GUINT32_FROM_BE (mode); + + directory = lcfs_node_lookup_child (parent, name); + if (directory != NULL && lcfs_node_get_mode (directory) != 0) + { + return glnx_throw (error, "Target checkout directory already exist"); + } + else + { + directory = lcfs_node_new (); + if (directory == NULL) + return glnx_throw (error, "Out of memory"); + + /* Takes ownership on success */ + if (lcfs_node_add_child (parent, directory, name) != 0) + { + lcfs_node_unref (directory); + return glnx_throw_errno_prefix (error, "lcfs_node_add_child"); + } + } + + lcfs_node_set_mode (directory, mode); + lcfs_node_set_uid (directory, uid); + lcfs_node_set_gid (directory, gid); + + /* Set the xattrs if we created the dir */ + if (xattrs && !_ostree_composefs_set_xattrs (directory, xattrs, cancellable, error)) + return FALSE; + + /* Process files in this subdir */ + { + g_autoptr (GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0); + GVariantIter viter; + g_variant_iter_init (&viter, dir_file_contents); + const char *fname; + g_autoptr (GVariant) contents_csum_v = NULL; + while (g_variant_iter_loop (&viter, "(&s@ay)", &fname, &contents_csum_v)) + { + char tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; + _ostree_checksum_inplace_from_bytes_v (contents_csum_v, tmp_checksum); + + if (!checkout_one_composefs_file_at (self, tmp_checksum, directory, fname, cancellable, + error)) + return glnx_prefix_error (error, "Processing %s", tmp_checksum); + } + contents_csum_v = NULL; /* iter_loop freed it */ + } + + /* Process subdirectories */ + { + g_autoptr (GVariant) dir_subdirs = g_variant_get_child_value (dirtree, 1); + const char *dname; + g_autoptr (GVariant) subdirtree_csum_v = NULL; + g_autoptr (GVariant) subdirmeta_csum_v = NULL; + GVariantIter viter; + g_variant_iter_init (&viter, dir_subdirs); + while ( + g_variant_iter_loop (&viter, "(&s@ay@ay)", &dname, &subdirtree_csum_v, &subdirmeta_csum_v)) + { + /* Validate this up front to prevent path traversal attacks. Note that + * we don't validate at the top of this function like we do for + * checkout_one_file_at() becuase I believe in some cases this function + * can be called *initially* with user-specified paths for the root + * directory. + */ + if (!ot_util_filename_validate (dname, error)) + return FALSE; + + char subdirtree_checksum[OSTREE_SHA256_STRING_LEN + 1]; + _ostree_checksum_inplace_from_bytes_v (subdirtree_csum_v, subdirtree_checksum); + char subdirmeta_checksum[OSTREE_SHA256_STRING_LEN + 1]; + _ostree_checksum_inplace_from_bytes_v (subdirmeta_csum_v, subdirmeta_checksum); + if (!checkout_composefs_recurse (self, subdirtree_checksum, subdirmeta_checksum, directory, + dname, cancellable, error)) + return FALSE; + } + /* Freed by iter-loop */ + subdirtree_csum_v = NULL; + subdirmeta_csum_v = NULL; + } + + return TRUE; +} + +/* Begin a checkout process */ +static gboolean +checkout_composefs_tree (OstreeRepo *self, OstreeComposefsTarget *target, OstreeRepoFile *source, + GFileInfo *source_info, GCancellable *cancellable, GError **error) +{ + if (g_file_info_get_file_type (source_info) != G_FILE_TYPE_DIRECTORY) + return glnx_throw (error, "Root checkout of composefs must be directory"); + + /* Cache any directory metadata we read during this operation; + * see commit b7afe91e21143d7abb0adde440683a52712aa246 + */ + g_auto (OstreeRepoMemoryCacheRef) memcache_ref; + _ostree_repo_memory_cache_ref_init (&memcache_ref, self); + + g_assert_cmpint (g_file_info_get_file_type (source_info), ==, G_FILE_TYPE_DIRECTORY); + + const char *dirtree_checksum = ostree_repo_file_tree_get_contents_checksum (source); + const char *dirmeta_checksum = ostree_repo_file_tree_get_metadata_checksum (source); + return checkout_composefs_recurse (self, dirtree_checksum, dirmeta_checksum, target->dest, "root", + cancellable, error); +} + +static struct lcfs_node_s * +ensure_lcfs_dir (struct lcfs_node_s *parent, const char *name, GError **error) +{ + GLNX_AUTO_PREFIX_ERROR ("Ensuring dir", error); + struct lcfs_node_s *node; + + node = lcfs_node_lookup_child (parent, name); + if (node != NULL) + return node; + + node = lcfs_node_new (); + lcfs_node_set_mode (node, 0755 | S_IFDIR); + if (lcfs_node_add_child (parent, node, name) != 0) + { + lcfs_node_unref (node); + glnx_throw_errno_prefix (error, "lcfs_node_add_child"); + return NULL; + } + + return node; +} + +#endif /* HAVE_COMPOSEFS */ + +/** + * ostree_repo_checkout_composefs: + * @self: Repo + * @target: A target for the checkout + * @source: Source tree + * @cancellable: Cancellable + * @error: Error + * + * Check out @source into @target, which is an in-memory + * representation of a composefs image. The @target can be reused + * multiple times to layer multiple checkouts before writing out the + * image to disk using ostree_composefs_target_write(). + * + * There are various options specified by @options that affect + * how the image is created. + * + * Returns: %TRUE on success, %FALSE on failure + */ +gboolean +ostree_repo_checkout_composefs (OstreeRepo *self, OstreeComposefsTarget *target, + OstreeRepoFile *source, GCancellable *cancellable, GError **error) +{ +#ifdef HAVE_COMPOSEFS + GLNX_AUTO_PREFIX_ERROR ("Checking out composefs", error); + char *root_dirs[] = { "usr", "etc", "boot", "var", "sysroot" }; + int i; + struct lcfs_node_s *root, *dir; + + g_autoptr (GFileInfo) target_info + = g_file_query_info (G_FILE (source), OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); + if (!target_info) + return glnx_prefix_error (error, "Failed to query"); + + if (!checkout_composefs_tree (self, target, source, target_info, cancellable, error)) + return FALSE; + + /* We need a root dir */ + root = ensure_lcfs_dir (target->dest, "root", error); + if (root == NULL) + return FALSE; + + /* To work as a rootfs we need some root directories to use as bind-mounts */ + for (i = 0; i < G_N_ELEMENTS (root_dirs); i++) + { + dir = ensure_lcfs_dir (root, root_dirs[i], error); + if (dir == NULL) + return FALSE; + } + + return TRUE; +#else + return composefs_not_supported (error); +#endif +} + +/** + * ostree_repo_commit_add_composefs_metadata: + * @self: Repo + * @format_version: Must be zero + * @dict: A GVariant builder of type a{sv} + * @repo_root: the target filesystem tree + * @cancellable: Cancellable + * @error: Error + * + * Compute the composefs digest for a filesystem tree + * and insert it into metadata for a commit object. The composefs + * digest covers the entire filesystem tree and can be verified by + * the composefs mount tooling. + */ +_OSTREE_PUBLIC +gboolean +ostree_repo_commit_add_composefs_metadata (OstreeRepo *self, guint format_version, + GVariantDict *dict, OstreeRepoFile *repo_root, + GCancellable *cancellable, GError **error) +{ +#ifdef HAVE_COMPOSEFS + /* For now */ + g_assert (format_version == 0); + + g_autoptr (OstreeComposefsTarget) target = ostree_composefs_target_new (); + + if (!ostree_repo_checkout_composefs (self, target, repo_root, cancellable, error)) + return FALSE; + + g_autofree guchar *fsverity_digest = NULL; + if (!ostree_composefs_target_write (target, -1, &fsverity_digest, cancellable, error)) + return FALSE; + + g_variant_dict_insert_value ( + dict, OSTREE_COMPOSEFS_DIGEST_KEY_V0, + ot_gvariant_new_bytearray (fsverity_digest, OSTREE_SHA256_DIGEST_LEN)); + + return TRUE; +#else + return composefs_not_supported (error); +#endif +} diff --git a/src/libostree/ostree-repo-deprecated.h b/src/libostree/ostree-repo-deprecated.h index 780c764..8704410 100644 --- a/src/libostree/ostree-repo-deprecated.h +++ b/src/libostree/ostree-repo-deprecated.h @@ -24,7 +24,7 @@ #ifndef __GI_SCANNER__ #ifndef G_GNUC_DEPRECATED_FOR -# define G_GNUC_DEPRECATED_FOR(x) +#define G_GNUC_DEPRECATED_FOR(x) #endif #endif @@ -39,7 +39,8 @@ G_BEGIN_DECLS * supercedes previous separate enumeration usage in * ostree_repo_checkout_tree(). */ -typedef struct { +typedef struct +{ OstreeRepoCheckoutMode mode; OstreeRepoCheckoutOverwriteMode overwrite_mode; @@ -58,13 +59,10 @@ typedef struct { } OstreeRepoCheckoutOptions; _OSTREE_PUBLIC -gboolean ostree_repo_checkout_tree_at (OstreeRepo *self, - OstreeRepoCheckoutOptions *options, - int destination_dfd, - const char *destination_path, - const char *commit, - GCancellable *cancellable, - GError **error) -G_GNUC_DEPRECATED_FOR(ostree_repo_checkout_at); +gboolean ostree_repo_checkout_tree_at (OstreeRepo *self, OstreeRepoCheckoutOptions *options, + int destination_dfd, const char *destination_path, + const char *commit, GCancellable *cancellable, + GError **error) + G_GNUC_DEPRECATED_FOR (ostree_repo_checkout_at); G_END_DECLS diff --git a/src/libostree/ostree-repo-file-enumerator.c b/src/libostree/ostree-repo-file-enumerator.c index a9ff547..35dd763 100644 --- a/src/libostree/ostree-repo-file-enumerator.c +++ b/src/libostree/ostree-repo-file-enumerator.c @@ -38,13 +38,10 @@ struct _OstreeRepoFileEnumerator #define ostree_repo_file_enumerator_get_type _ostree_repo_file_enumerator_get_type G_DEFINE_TYPE (OstreeRepoFileEnumerator, ostree_repo_file_enumerator, G_TYPE_FILE_ENUMERATOR); -static GFileInfo *ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator, - GCancellable *cancellable, - GError **error); -static gboolean ostree_repo_file_enumerator_close (GFileEnumerator *enumerator, - GCancellable *cancellable, - GError **error); - +static GFileInfo *ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator, + GCancellable *cancellable, GError **error); +static gboolean ostree_repo_file_enumerator_close (GFileEnumerator *enumerator, + GCancellable *cancellable, GError **error); static void ostree_repo_file_enumerator_dispose (GObject *object) @@ -55,7 +52,7 @@ ostree_repo_file_enumerator_dispose (GObject *object) g_clear_object (&self->dir); g_free (self->attributes); - + if (G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->dispose) G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->dispose (object); } @@ -71,13 +68,12 @@ ostree_repo_file_enumerator_finalize (GObject *object) G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->finalize (object); } - static void ostree_repo_file_enumerator_class_init (OstreeRepoFileEnumeratorClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass); - + gobject_class->finalize = ostree_repo_file_enumerator_finalize; gobject_class->dispose = ostree_repo_file_enumerator_dispose; @@ -91,52 +87,45 @@ ostree_repo_file_enumerator_init (OstreeRepoFileEnumerator *self) } GFileEnumerator * -_ostree_repo_file_enumerator_new (OstreeRepoFile *dir, - const char *attributes, - GFileQueryInfoFlags flags, - GCancellable *cancellable, - GError **error) +_ostree_repo_file_enumerator_new (OstreeRepoFile *dir, const char *attributes, + GFileQueryInfoFlags flags, GCancellable *cancellable, + GError **error) { OstreeRepoFileEnumerator *self; - - self = g_object_new (OSTREE_TYPE_REPO_FILE_ENUMERATOR, - "container", dir, - NULL); + + self = g_object_new (OSTREE_TYPE_REPO_FILE_ENUMERATOR, "container", dir, NULL); self->dir = g_object_ref (dir); self->attributes = g_strdup (attributes); self->flags = flags; - + return G_FILE_ENUMERATOR (self); } static GFileInfo * -ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator, - GCancellable *cancellable, - GError **error) +ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator, GCancellable *cancellable, + GError **error) { OstreeRepoFileEnumerator *self = OSTREE_REPO_FILE_ENUMERATOR (enumerator); gboolean ret = FALSE; GFileInfo *info = NULL; - if (!ostree_repo_file_tree_query_child (self->dir, self->index, - self->attributes, self->flags, + if (!ostree_repo_file_tree_query_child (self->dir, self->index, self->attributes, self->flags, &info, cancellable, error)) goto out; self->index++; ret = TRUE; - out: +out: if (!ret) g_clear_object (&info); return info; } static gboolean -ostree_repo_file_enumerator_close (GFileEnumerator *enumerator, - GCancellable *cancellable, - GError **error) +ostree_repo_file_enumerator_close (GFileEnumerator *enumerator, GCancellable *cancellable, + GError **error) { return TRUE; } diff --git a/src/libostree/ostree-repo-file-enumerator.h b/src/libostree/ostree-repo-file-enumerator.h index 8404d24..a67ac9d 100644 --- a/src/libostree/ostree-repo-file-enumerator.h +++ b/src/libostree/ostree-repo-file-enumerator.h @@ -25,15 +25,20 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_REPO_FILE_ENUMERATOR (_ostree_repo_file_enumerator_get_type ()) -#define OSTREE_REPO_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumerator)) -#define OSTREE_REPO_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass)) -#define OSTREE_IS_REPO_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR)) -#define OSTREE_IS_REPO_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR)) -#define OSTREE_REPO_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass)) - -typedef struct _OstreeRepoFileEnumerator OstreeRepoFileEnumerator; -typedef struct _OstreeRepoFileEnumeratorClass OstreeRepoFileEnumeratorClass; +#define OSTREE_TYPE_REPO_FILE_ENUMERATOR (_ostree_repo_file_enumerator_get_type ()) +#define OSTREE_REPO_FILE_ENUMERATOR(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumerator)) +#define OSTREE_REPO_FILE_ENUMERATOR_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass)) +#define OSTREE_IS_REPO_FILE_ENUMERATOR(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR)) +#define OSTREE_IS_REPO_FILE_ENUMERATOR_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR)) +#define OSTREE_REPO_FILE_ENUMERATOR_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass)) + +typedef struct _OstreeRepoFileEnumerator OstreeRepoFileEnumerator; +typedef struct _OstreeRepoFileEnumeratorClass OstreeRepoFileEnumeratorClass; struct _OstreeRepoFileEnumeratorClass { @@ -41,13 +46,11 @@ struct _OstreeRepoFileEnumeratorClass }; G_GNUC_INTERNAL -GType _ostree_repo_file_enumerator_get_type (void) G_GNUC_CONST; +GType _ostree_repo_file_enumerator_get_type (void) G_GNUC_CONST; G_GNUC_INTERNAL -GFileEnumerator * _ostree_repo_file_enumerator_new (OstreeRepoFile *dir, - const char *attributes, - GFileQueryInfoFlags flags, - GCancellable *cancellable, - GError **error); +GFileEnumerator *_ostree_repo_file_enumerator_new (OstreeRepoFile *dir, const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/src/libostree/ostree-repo-file.c b/src/libostree/ostree-repo-file.c index 3d396ce..f33bc6b 100644 --- a/src/libostree/ostree-repo-file.c +++ b/src/libostree/ostree-repo-file.c @@ -22,9 +22,9 @@ #include "config.h" -#include "otutil.h" #include "ostree-repo-file-enumerator.h" #include "ostree-repo-private.h" +#include "otutil.h" static void ostree_repo_file_file_iface_init (GFileIface *iface); @@ -46,8 +46,7 @@ struct OstreeRepoFile }; G_DEFINE_TYPE_WITH_CODE (OstreeRepoFile, ostree_repo_file, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_FILE, - ostree_repo_file_file_iface_init)) + G_IMPLEMENT_INTERFACE (G_TYPE_FILE, ostree_repo_file_file_iface_init)) static void ostree_repo_file_finalize (GObject *object) @@ -98,15 +97,13 @@ ostree_repo_file_init (OstreeRepoFile *self) static gboolean set_error_noent (GFile *self, GError **error) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No such file or directory: %s", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No such file or directory: %s", gs_file_get_path_cached (self)); return FALSE; } OstreeRepoFile * -_ostree_repo_file_new_root (OstreeRepo *repo, - const char *contents_checksum, +_ostree_repo_file_new_root (OstreeRepo *repo, const char *contents_checksum, const char *metadata_checksum) { OstreeRepoFile *self; @@ -126,31 +123,28 @@ _ostree_repo_file_new_root (OstreeRepo *repo, } static OstreeRepoFile * -ostree_repo_file_new_child (OstreeRepoFile *parent, - const char *name) +ostree_repo_file_new_child (OstreeRepoFile *parent, const char *name) { OstreeRepoFile *self; size_t len; - + self = g_object_new (OSTREE_TYPE_REPO_FILE, NULL); self->repo = g_object_ref (parent->repo); self->parent = g_object_ref (parent); self->name = g_strdup (name); - len = strlen(self->name); - if (self->name[len-1] == '/') - self->name[len-1] = '\0'; + len = strlen (self->name); + if (self->name[len - 1] == '/') + self->name[len - 1] = '\0'; return self; } OstreeRepoFile * -_ostree_repo_file_new_for_commit (OstreeRepo *repo, - const char *commit, - GError **error) +_ostree_repo_file_new_for_commit (OstreeRepo *repo, const char *commit, GError **error) { - g_autoptr(GVariant) commit_v = NULL; - g_autoptr(GVariant) tree_contents_csum_v = NULL; - g_autoptr(GVariant) tree_metadata_csum_v = NULL; + g_autoptr (GVariant) commit_v = NULL; + g_autoptr (GVariant) tree_contents_csum_v = NULL; + g_autoptr (GVariant) tree_metadata_csum_v = NULL; char tree_contents_csum[OSTREE_SHA256_STRING_LEN + 1]; char tree_metadata_csum[OSTREE_SHA256_STRING_LEN + 1]; @@ -158,8 +152,7 @@ _ostree_repo_file_new_for_commit (OstreeRepo *repo, g_return_val_if_fail (commit != NULL, NULL); g_return_val_if_fail (strlen (commit) == OSTREE_SHA256_STRING_LEN, NULL); - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, - commit, &commit_v, error)) + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit, &commit_v, error)) return NULL; /* PARSE OSTREE_OBJECT_TYPE_COMMIT */ @@ -175,11 +168,10 @@ _ostree_repo_file_new_for_commit (OstreeRepo *repo, } static gboolean -do_resolve (OstreeRepoFile *self, - GError **error) +do_resolve (OstreeRepoFile *self, GError **error) { - g_autoptr(GVariant) root_contents = NULL; - g_autoptr(GVariant) root_metadata = NULL; + g_autoptr (GVariant) root_contents = NULL; + g_autoptr (GVariant) root_metadata = NULL; g_assert (self->parent == NULL); @@ -200,16 +192,15 @@ do_resolve (OstreeRepoFile *self, } static gboolean -do_resolve_nonroot (OstreeRepoFile *self, - GError **error) +do_resolve_nonroot (OstreeRepoFile *self, GError **error) { gboolean is_dir; int i; - g_autoptr(GVariant) container = NULL; - g_autoptr(GVariant) tree_contents = NULL; - g_autoptr(GVariant) tree_metadata = NULL; - g_autoptr(GVariant) contents_csum_v = NULL; - g_autoptr(GVariant) metadata_csum_v = NULL; + g_autoptr (GVariant) container = NULL; + g_autoptr (GVariant) tree_contents = NULL; + g_autoptr (GVariant) tree_metadata = NULL; + g_autoptr (GVariant) contents_csum_v = NULL; + g_autoptr (GVariant) metadata_csum_v = NULL; g_autofree char *tmp_checksum = NULL; if (!ostree_repo_file_ensure_resolved (self->parent, error)) @@ -217,8 +208,7 @@ do_resolve_nonroot (OstreeRepoFile *self, if (!self->parent->tree_contents) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, - "Not a directory"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, "Not a directory"); return FALSE; } @@ -226,7 +216,7 @@ do_resolve_nonroot (OstreeRepoFile *self, if (i < 0) { - set_error_noent ((GFile*)self, error); + set_error_noent ((GFile *)self, error); return FALSE; } @@ -239,21 +229,18 @@ do_resolve_nonroot (OstreeRepoFile *self, self->index = g_variant_n_children (files_variant) + i; g_clear_pointer (&files_variant, g_variant_unref); - g_variant_get_child (container, i, "(&s@ay@ay)", - &name, &contents_csum_v, &metadata_csum_v); + g_variant_get_child (container, i, "(&s@ay@ay)", &name, &contents_csum_v, &metadata_csum_v); g_free (tmp_checksum); tmp_checksum = ostree_checksum_from_bytes_v (contents_csum_v); - if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE, - tmp_checksum, &tree_contents, - error)) + if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE, tmp_checksum, + &tree_contents, error)) return FALSE; g_free (tmp_checksum); tmp_checksum = ostree_checksum_from_bytes_v (metadata_csum_v); - if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META, - tmp_checksum, &tree_metadata, - error)) + if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META, tmp_checksum, + &tree_metadata, error)) return FALSE; self->tree_contents = tree_contents; @@ -269,9 +256,17 @@ do_resolve_nonroot (OstreeRepoFile *self, return TRUE; } +/** + * ostree_repo_file_ensure_resolved: + * @self: A repo file + * @error: Error + * + * Ensure that the backing metadata is loaded. + * + * Returns: %FALSE if the operation failed, %TRUE otherwise + */ gboolean -ostree_repo_file_ensure_resolved (OstreeRepoFile *self, - GError **error) +ostree_repo_file_ensure_resolved (OstreeRepoFile *self, GError **error) { if (self->parent == NULL) { @@ -299,44 +294,64 @@ ostree_repo_file_ensure_resolved (OstreeRepoFile *self, * @error: Error */ gboolean -ostree_repo_file_get_xattrs (OstreeRepoFile *self, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) +ostree_repo_file_get_xattrs (OstreeRepoFile *self, GVariant **out_xattrs, GCancellable *cancellable, + GError **error) { if (!ostree_repo_file_ensure_resolved (self, error)) return FALSE; - g_autoptr(GVariant) ret_xattrs = NULL; + g_autoptr (GVariant) ret_xattrs = NULL; if (self->tree_metadata) ret_xattrs = g_variant_get_child_value (self->tree_metadata, 3); else { - if (!ostree_repo_load_file (self->repo, ostree_repo_file_get_checksum (self), - NULL, NULL, &ret_xattrs, cancellable, error)) + if (!ostree_repo_load_file (self->repo, ostree_repo_file_get_checksum (self), NULL, NULL, + &ret_xattrs, cancellable, error)) return FALSE; } - ot_transfer_out_value(out_xattrs, &ret_xattrs); + ot_transfer_out_value (out_xattrs, &ret_xattrs); return TRUE; } +/** + * ostree_repo_file_tree_get_contents: + * @self: A repo file + * + * This API will return %NULL if the file is not "resolved" i.e. in a loaded + * state. It will also return %NULL if this path is not a directory tree. + * + * Returns: (nullable): The GVariant representing the children of this directory. + */ GVariant * -ostree_repo_file_tree_get_contents (OstreeRepoFile *self) +ostree_repo_file_tree_get_contents (OstreeRepoFile *self) { return self->tree_contents; } +/** + * ostree_repo_file_tree_get_metadata: + * @self: A repo file + * + * This API will return %NULL if the file is not "resolved" i.e. in a loaded + * state. It will also return %NULL if this path is not a directory tree. + * + * Returns: (nullable): The GVariant representing the metadata for this directory. + */ GVariant * -ostree_repo_file_tree_get_metadata (OstreeRepoFile *self) +ostree_repo_file_tree_get_metadata (OstreeRepoFile *self) { return self->tree_metadata; } +/** + * ostree_repo_file_tree_set_metadata: + * @self: A repo file + * + * Replace the metadata checksum and metadata object. + */ void -ostree_repo_file_tree_set_metadata (OstreeRepoFile *self, - const char *checksum, - GVariant *metadata) +ostree_repo_file_tree_set_metadata (OstreeRepoFile *self, const char *checksum, GVariant *metadata) { g_clear_pointer (&self->tree_metadata, g_variant_unref); self->tree_metadata = g_variant_ref (metadata); @@ -344,14 +359,28 @@ ostree_repo_file_tree_set_metadata (OstreeRepoFile *self, self->tree_metadata_checksum = g_strdup (checksum); } +/** + * ostree_repo_file_tree_get_contents_checksum: + * @self: A repo file + * + * Returns: (nullable): The SHA256 digest of the content object, or %NULL if this is not a + * directory. + */ const char * -ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile *self) +ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile *self) { return self->tree_contents_checksum; } +/** + * ostree_repo_file_tree_get_metadata_checksum: + * @self: A repo file + * + * Returns: (nullable): The SHA256 digest of the metadata object, or %NULL if this is not a + * directory. + */ const char * -ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self) +ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self) { return self->tree_metadata_checksum; } @@ -363,7 +392,7 @@ ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self) * Returns: (transfer none): Repository */ OstreeRepo * -ostree_repo_file_get_repo (OstreeRepoFile *self) +ostree_repo_file_get_repo (OstreeRepoFile *self) { return self->repo; } @@ -375,7 +404,7 @@ ostree_repo_file_get_repo (OstreeRepoFile *self) * Returns: (transfer none): The root directory for the commit referenced by this file */ OstreeRepoFile * -ostree_repo_file_get_root (OstreeRepoFile *self) +ostree_repo_file_get_root (OstreeRepoFile *self) { OstreeRepoFile *parent = self; @@ -384,8 +413,15 @@ ostree_repo_file_get_root (OstreeRepoFile *self) return parent; } +/** + * ostree_repo_file_tree_get_checksum: + * @self: A repo file + * + * Returns: For non-directories, the SHA-256 digest of the object. For directories, the metadata + * digest will be returned. + */ const char * -ostree_repo_file_get_checksum (OstreeRepoFile *self) +ostree_repo_file_get_checksum (OstreeRepoFile *self) { int n; gboolean is_dir; @@ -407,13 +443,11 @@ ostree_repo_file_get_checksum (OstreeRepoFile *self) if (is_dir) { - g_variant_get_child (dirs_variant, n, - "(@s@ay@ay)", NULL, NULL, &csum_bytes); + g_variant_get_child (dirs_variant, n, "(@s@ay@ay)", NULL, NULL, &csum_bytes); } else { - g_variant_get_child (files_variant, n, - "(@s@ay)", NULL, &csum_bytes); + g_variant_get_child (files_variant, n, "(@s@ay)", NULL, &csum_bytes); } g_clear_pointer (&files_variant, g_variant_unref); g_clear_pointer (&dirs_variant, g_variant_unref); @@ -432,8 +466,7 @@ ostree_repo_file_is_native (GFile *file) } static gboolean -ostree_repo_file_has_uri_scheme (GFile *file, - const char *uri_scheme) +ostree_repo_file_has_uri_scheme (GFile *file, const char *uri_scheme) { return g_ascii_strcasecmp (uri_scheme, "ostree") == 0; } @@ -496,10 +529,8 @@ ostree_repo_file_get_uri (GFile *file) path = gs_file_get_path_cached (file); uri_path = g_filename_to_uri (path, NULL, NULL); g_assert (g_str_has_prefix (uri_path, "file://")); - ret = g_strconcat ("ostree://", - root->tree_contents_checksum, "/", root->tree_metadata_checksum, - uri_path+strlen("file://"), - NULL); + ret = g_strconcat ("ostree://", root->tree_contents_checksum, "/", root->tree_metadata_checksum, + uri_path + strlen ("file://"), NULL); g_free (uri_path); return ret; @@ -516,7 +547,7 @@ ostree_repo_file_get_parent (GFile *file) { OstreeRepoFile *self = OSTREE_REPO_FILE (file); - return (GFile*)g_object_ref (self->parent); + return (GFile *)g_object_ref (self->parent); } static GFile * @@ -527,14 +558,15 @@ ostree_repo_file_dup (GFile *file) if (self->parent) return G_FILE (ostree_repo_file_new_child (self->parent, self->name)); else - return G_FILE (_ostree_repo_file_new_root (self->repo, self->tree_contents_checksum, self->tree_metadata_checksum)); + return G_FILE (_ostree_repo_file_new_root (self->repo, self->tree_contents_checksum, + self->tree_metadata_checksum)); } static guint ostree_repo_file_hash (GFile *file) { OstreeRepoFile *self = OSTREE_REPO_FILE (file); - + if (self->parent) return g_file_hash (self->parent) + g_str_hash (self->name); else @@ -542,48 +574,44 @@ ostree_repo_file_hash (GFile *file) } static gboolean -ostree_repo_file_equal (GFile *file1, - GFile *file2) +ostree_repo_file_equal (GFile *file1, GFile *file2) { OstreeRepoFile *self1 = OSTREE_REPO_FILE (file1); OstreeRepoFile *self2 = OSTREE_REPO_FILE (file2); if (self1->parent && self2->parent) { - return (g_str_equal (self1->name, self2->name) && - g_file_equal ((GFile*)self1->parent, (GFile*)self2->parent)); + return (g_str_equal (self1->name, self2->name) + && g_file_equal ((GFile *)self1->parent, (GFile *)self2->parent)); } else if (!self1->parent && !self2->parent) { - return (g_str_equal (self1->tree_contents_checksum, self2->tree_contents_checksum) && - g_str_equal (self1->tree_metadata_checksum, self2->tree_metadata_checksum)); + return (g_str_equal (self1->tree_contents_checksum, self2->tree_contents_checksum) + && g_str_equal (self1->tree_metadata_checksum, self2->tree_metadata_checksum)); } else return FALSE; } static const char * -match_prefix (const char *path, - const char *prefix) +match_prefix (const char *path, const char *prefix) { int prefix_len; prefix_len = strlen (prefix); if (strncmp (path, prefix, prefix_len) != 0) return NULL; - + /* Handle the case where prefix is the root, so that * the IS_DIR_SEPRARATOR check below works */ - if (prefix_len > 0 && - G_IS_DIR_SEPARATOR (prefix[prefix_len-1])) + if (prefix_len > 0 && G_IS_DIR_SEPARATOR (prefix[prefix_len - 1])) prefix_len--; - + return path + prefix_len; } static gboolean -ostree_repo_file_prefix_matches (GFile *parent, - GFile *descendant) +ostree_repo_file_prefix_matches (GFile *parent, GFile *descendant) { const char *remainder; const char *parent_path; @@ -598,8 +626,7 @@ ostree_repo_file_prefix_matches (GFile *parent, } static char * -ostree_repo_file_get_relative_path (GFile *parent, - GFile *descendant) +ostree_repo_file_get_relative_path (GFile *parent, GFile *descendant) { const char *remainder; const char *parent_path; @@ -608,15 +635,14 @@ ostree_repo_file_get_relative_path (GFile *parent, parent_path = gs_file_get_path_cached (parent); descendant_path = gs_file_get_path_cached (descendant); remainder = match_prefix (descendant_path, parent_path); - + if (remainder != NULL && G_IS_DIR_SEPARATOR (*remainder)) return g_strdup (remainder + 1); return NULL; } static GFile * -ostree_repo_file_resolve_relative_path (GFile *file, - const char *relative_path) +ostree_repo_file_resolve_relative_path (GFile *file, const char *relative_path) { OstreeRepoFile *self = OSTREE_REPO_FILE (file); OstreeRepoFile *parent; @@ -629,13 +655,13 @@ ostree_repo_file_resolve_relative_path (GFile *file, g_assert (*relative_path == '/'); if (strcmp (relative_path, "/") == 0) - return (GFile*)g_object_ref (ostree_repo_file_get_root (self)); + return (GFile *)g_object_ref (ostree_repo_file_get_root (self)); if (self->parent) - return ostree_repo_file_resolve_relative_path ((GFile*)ostree_repo_file_get_root (self), - relative_path+1); + return ostree_repo_file_resolve_relative_path ((GFile *)ostree_repo_file_get_root (self), + relative_path + 1); else - relative_path = relative_path+1; + relative_path = relative_path + 1; } rest = strchr (relative_path, '/'); @@ -649,49 +675,40 @@ ostree_repo_file_resolve_relative_path (GFile *file, parent = ostree_repo_file_new_child (self, filename); g_free (filename); - + if (!rest) - ret = (GFile*)parent; + ret = (GFile *)parent; else { - ret = ostree_repo_file_resolve_relative_path ((GFile*)parent, rest); + ret = ostree_repo_file_resolve_relative_path ((GFile *)parent, rest); g_clear_object (&parent); } return ret; } static GFileEnumerator * -ostree_repo_file_enumerate_children (GFile *file, - const char *attributes, - GFileQueryInfoFlags flags, - GCancellable *cancellable, - GError **error) +ostree_repo_file_enumerate_children (GFile *file, const char *attributes, GFileQueryInfoFlags flags, + GCancellable *cancellable, GError **error) { OstreeRepoFile *self = OSTREE_REPO_FILE (file); - return _ostree_repo_file_enumerator_new (self, - attributes, flags, - cancellable, error); + return _ostree_repo_file_enumerator_new (self, attributes, flags, cancellable, error); } static GFile * -ostree_repo_file_get_child_for_display_name (GFile *file, - const char *display_name, - GError **error) +ostree_repo_file_get_child_for_display_name (GFile *file, const char *display_name, GError **error) { return g_file_get_child (file, display_name); } static void -set_info_from_dirmeta (GFileInfo *info, - GVariant *metadata) +set_info_from_dirmeta (GFileInfo *info, GVariant *metadata) { guint32 uid, gid, mode; g_file_info_set_attribute_uint32 (info, "standard::type", G_FILE_TYPE_DIRECTORY); /* PARSE OSTREE_OBJECT_TYPE_DIR_META */ - g_variant_get (metadata, "(uuu@a(ayay))", - &uid, &gid, &mode, NULL); + g_variant_get (metadata, "(uuu@a(ayay))", &uid, &gid, &mode, NULL); uid = GUINT32_FROM_BE (uid); gid = GUINT32_FROM_BE (gid); mode = GUINT32_FROM_BE (mode); @@ -702,31 +719,26 @@ set_info_from_dirmeta (GFileInfo *info, } static gboolean -query_child_info_dir (OstreeRepo *repo, - const char *metadata_checksum, - GFileAttributeMatcher *matcher, - GFileQueryInfoFlags flags, - GFileInfo **out_info, - GCancellable *cancellable, - GError **error) +query_child_info_dir (OstreeRepo *repo, const char *metadata_checksum, + GFileAttributeMatcher *matcher, GFileQueryInfoFlags flags, + GFileInfo **out_info, GCancellable *cancellable, GError **error) { - g_autoptr(GFileInfo) ret_info = g_file_info_new (); + g_autoptr (GFileInfo) ret_info = g_file_info_new (); - g_file_info_set_attribute_uint32 (ret_info, "standard::type", - G_FILE_TYPE_DIRECTORY); + g_file_info_set_attribute_uint32 (ret_info, "standard::type", G_FILE_TYPE_DIRECTORY); if (g_file_attribute_matcher_matches (matcher, "unix::mode")) { - g_autoptr(GVariant) metadata = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_META, - metadata_checksum, &metadata, error)) + g_autoptr (GVariant) metadata = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_META, metadata_checksum, + &metadata, error)) return FALSE; set_info_from_dirmeta (ret_info, metadata); } - ot_transfer_out_value(out_info, &ret_info); + ot_transfer_out_value (out_info, &ret_info); return TRUE; } @@ -738,10 +750,8 @@ query_child_info_dir (OstreeRepo *repo, * @out_container: (out): */ int -ostree_repo_file_tree_find_child (OstreeRepoFile *self, - const char *name, - gboolean *is_dir, - GVariant **out_container) +ostree_repo_file_tree_find_child (OstreeRepoFile *self, const char *name, gboolean *is_dir, + GVariant **out_container) { int i; GVariant *files_variant = NULL; @@ -785,31 +795,29 @@ ostree_repo_file_tree_find_child (OstreeRepoFile *self, /** * ostree_repo_file_tree_query_child: * @self: #OstreeRepoFile - * @n: - * @attributes: - * @flags: - * @out_info: (out): - * @cancellable: Cancellable - * @error: Error + * @n: the child number + * @attributes: an attribute string to match, see g_file_attribute_matcher_new() + * @flags: a #GFileQueryInfoFlags + * @out_info: (out) (transfer full) (optional): the #GFileInfo of the child. + * @cancellable: a #GCancellable or %NULL + * @error: a #GError or %NULL + * + * Returns: %TRUE on success and the @out_info is set, %FALSE otherwise. */ gboolean -ostree_repo_file_tree_query_child (OstreeRepoFile *self, - int n, - const char *attributes, - GFileQueryInfoFlags flags, - GFileInfo **out_info, - GCancellable *cancellable, - GError **error) +ostree_repo_file_tree_query_child (OstreeRepoFile *self, int n, const char *attributes, + GFileQueryInfoFlags flags, GFileInfo **out_info, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const char *name = NULL; int c; - g_autoptr(GFileInfo) ret_info = NULL; - g_autoptr(GVariant) files_variant = NULL; - g_autoptr(GVariant) dirs_variant = NULL; - g_autoptr(GVariant) content_csum_v = NULL; - g_autoptr(GVariant) meta_csum_v = NULL; - char tmp_checksum[OSTREE_SHA256_STRING_LEN+1]; + g_autoptr (GFileInfo) ret_info = NULL; + g_autoptr (GVariant) files_variant = NULL; + g_autoptr (GVariant) dirs_variant = NULL; + g_autoptr (GVariant) content_csum_v = NULL; + g_autoptr (GVariant) meta_csum_v = NULL; + char tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; GFileAttributeMatcher *matcher = NULL; if (!ostree_repo_file_ensure_resolved (self, error)) @@ -834,8 +842,8 @@ ostree_repo_file_tree_query_child (OstreeRepoFile *self, ostree_checksum_inplace_from_bytes (csum_bytes, tmp_checksum); - if (!ostree_repo_load_file (self->repo, tmp_checksum, NULL, &ret_info, NULL, - cancellable, error)) + if (!ostree_repo_load_file (self->repo, tmp_checksum, NULL, &ret_info, NULL, cancellable, + error)) goto out; } else @@ -848,16 +856,14 @@ ostree_repo_file_tree_query_child (OstreeRepoFile *self, { const guchar *csum_bytes; - g_variant_get_child (dirs_variant, n, "(&s@ay@ay)", - &name, NULL, &meta_csum_v); + g_variant_get_child (dirs_variant, n, "(&s@ay@ay)", &name, NULL, &meta_csum_v); csum_bytes = ostree_checksum_bytes_peek_validate (meta_csum_v, error); if (csum_bytes == NULL) goto out; ostree_checksum_inplace_from_bytes (csum_bytes, tmp_checksum); - if (!query_child_info_dir (self->repo, tmp_checksum, - matcher, flags, &ret_info, + if (!query_child_info_dir (self->repo, tmp_checksum, matcher, flags, &ret_info, cancellable, error)) goto out; } @@ -865,10 +871,8 @@ ostree_repo_file_tree_query_child (OstreeRepoFile *self, if (name) { - g_file_info_set_attribute_byte_string (ret_info, "standard::name", - name); - g_file_info_set_attribute_string (ret_info, "standard::display-name", - name); + g_file_info_set_attribute_byte_string (ret_info, "standard::name", name); + g_file_info_set_attribute_string (ret_info, "standard::display-name", name); if (*name == '.') g_file_info_set_is_hidden (ret_info, TRUE); } @@ -878,22 +882,19 @@ ostree_repo_file_tree_query_child (OstreeRepoFile *self, } ret = TRUE; - ot_transfer_out_value(out_info, &ret_info); - out: + ot_transfer_out_value (out_info, &ret_info); +out: if (matcher) g_file_attribute_matcher_unref (matcher); return ret; } static GFileInfo * -ostree_repo_file_query_info (GFile *file, - const char *attributes, - GFileQueryInfoFlags flags, - GCancellable *cancellable, - GError **error) +ostree_repo_file_query_info (GFile *file, const char *attributes, GFileQueryInfoFlags flags, + GCancellable *cancellable, GError **error) { OstreeRepoFile *self = OSTREE_REPO_FILE (file); - g_autoptr(GFileInfo) info = NULL; + g_autoptr (GFileInfo) info = NULL; if (!ostree_repo_file_ensure_resolved (self, error)) return NULL; @@ -905,9 +906,8 @@ ostree_repo_file_query_info (GFile *file, } else { - if (!ostree_repo_file_tree_query_child (self->parent, self->index, - attributes, flags, - &info, cancellable, error)) + if (!ostree_repo_file_tree_query_child (self->parent, self->index, attributes, flags, &info, + cancellable, error)) return NULL; g_assert (info != NULL); } @@ -916,57 +916,49 @@ ostree_repo_file_query_info (GFile *file, } static GFileAttributeInfoList * -ostree_repo_file_query_settable_attributes (GFile *file, - GCancellable *cancellable, - GError **error) +ostree_repo_file_query_settable_attributes (GFile *file, GCancellable *cancellable, GError **error) { return g_file_attribute_info_list_new (); } static GFileAttributeInfoList * -ostree_repo_file_query_writable_namespaces (GFile *file, - GCancellable *cancellable, - GError **error) +ostree_repo_file_query_writable_namespaces (GFile *file, GCancellable *cancellable, GError **error) { return g_file_attribute_info_list_new (); } static GFileInputStream * -ostree_repo_file_read (GFile *file, - GCancellable *cancellable, - GError **error) +ostree_repo_file_read (GFile *file, GCancellable *cancellable, GError **error) { OstreeRepoFile *self = OSTREE_REPO_FILE (file); const char *checksum; - g_autoptr(GInputStream) ret_stream = NULL; + g_autoptr (GInputStream) ret_stream = NULL; if (!ostree_repo_file_ensure_resolved (self, error)) return FALSE; if (self->tree_contents) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, - "Can't open directory"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, "Can't open directory"); return NULL; } checksum = ostree_repo_file_get_checksum (self); - g_autoptr(GFileInfo) finfo = NULL; - if (!ostree_repo_load_file (self->repo, checksum, NULL, - &finfo, NULL, cancellable, error)) + g_autoptr (GFileInfo) finfo = NULL; + if (!ostree_repo_load_file (self->repo, checksum, NULL, &finfo, NULL, cancellable, error)) return NULL; if (g_file_info_get_file_type (finfo) == G_FILE_TYPE_REGULAR) { - if (!ostree_repo_load_file (self->repo, checksum, &ret_stream, - NULL, NULL, cancellable, error)) + if (!ostree_repo_load_file (self->repo, checksum, &ret_stream, NULL, NULL, cancellable, + error)) return NULL; } else { - g_autoptr(GFile) parent = g_file_get_parent (file); + g_autoptr (GFile) parent = g_file_get_parent (file); const char *target = g_file_info_get_symlink_target (finfo); - g_autoptr(GFile) dest = g_file_resolve_relative_path (parent, target); + g_autoptr (GFile) dest = g_file_resolve_relative_path (parent, target); return g_file_read (dest, cancellable, error); } diff --git a/src/libostree/ostree-repo-file.h b/src/libostree/ostree-repo-file.h index bfe2ab0..309e296 100644 --- a/src/libostree/ostree-repo-file.h +++ b/src/libostree/ostree-repo-file.h @@ -25,14 +25,17 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_REPO_FILE (ostree_repo_file_get_type ()) -#define OSTREE_REPO_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFile)) -#define OSTREE_REPO_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass)) -#define OSTREE_IS_REPO_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE)) -#define OSTREE_IS_REPO_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE)) -#define OSTREE_REPO_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass)) - -typedef struct _OstreeRepoFileClass OstreeRepoFileClass; +#define OSTREE_TYPE_REPO_FILE (ostree_repo_file_get_type ()) +#define OSTREE_REPO_FILE(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFile)) +#define OSTREE_REPO_FILE_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass)) +#define OSTREE_IS_REPO_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE)) +#define OSTREE_IS_REPO_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE)) +#define OSTREE_REPO_FILE_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass)) + +typedef struct _OstreeRepoFileClass OstreeRepoFileClass; struct _OstreeRepoFileClass { @@ -40,32 +43,28 @@ struct _OstreeRepoFileClass }; _OSTREE_PUBLIC -GType ostree_repo_file_get_type (void) G_GNUC_CONST; +GType ostree_repo_file_get_type (void) G_GNUC_CONST; _OSTREE_PUBLIC -gboolean ostree_repo_file_ensure_resolved (OstreeRepoFile *self, - GError **error); +gboolean ostree_repo_file_ensure_resolved (OstreeRepoFile *self, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_file_get_xattrs (OstreeRepoFile *self, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_file_get_xattrs (OstreeRepoFile *self, GVariant **out_xattrs, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeRepo * ostree_repo_file_get_repo (OstreeRepoFile *self); +OstreeRepo *ostree_repo_file_get_repo (OstreeRepoFile *self); _OSTREE_PUBLIC -OstreeRepoFile * ostree_repo_file_get_root (OstreeRepoFile *self); +OstreeRepoFile *ostree_repo_file_get_root (OstreeRepoFile *self); _OSTREE_PUBLIC -void ostree_repo_file_tree_set_metadata (OstreeRepoFile *self, - const char *checksum, - GVariant *metadata); +void ostree_repo_file_tree_set_metadata (OstreeRepoFile *self, const char *checksum, + GVariant *metadata); _OSTREE_PUBLIC -const char *ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile *self); +const char *ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile *self); _OSTREE_PUBLIC -const char *ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self); +const char *ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self); _OSTREE_PUBLIC GVariant *ostree_repo_file_tree_get_contents (OstreeRepoFile *self); @@ -73,21 +72,15 @@ _OSTREE_PUBLIC GVariant *ostree_repo_file_tree_get_metadata (OstreeRepoFile *self); _OSTREE_PUBLIC -const char * ostree_repo_file_get_checksum (OstreeRepoFile *self); +const char *ostree_repo_file_get_checksum (OstreeRepoFile *self); _OSTREE_PUBLIC -int ostree_repo_file_tree_find_child (OstreeRepoFile *self, - const char *name, - gboolean *is_dir, - GVariant **out_container); +int ostree_repo_file_tree_find_child (OstreeRepoFile *self, const char *name, gboolean *is_dir, + GVariant **out_container); _OSTREE_PUBLIC -gboolean ostree_repo_file_tree_query_child (OstreeRepoFile *self, - int n, - const char *attributes, - GFileQueryInfoFlags flags, - GFileInfo **out_info, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_file_tree_query_child (OstreeRepoFile *self, int n, const char *attributes, + GFileQueryInfoFlags flags, GFileInfo **out_info, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/src/libostree/ostree-repo-finder-avahi-parser.c b/src/libostree/ostree-repo-finder-avahi-parser.c index 8eb1ce4..dfa8d17 100644 --- a/src/libostree/ostree-repo-finder-avahi-parser.c +++ b/src/libostree/ostree-repo-finder-avahi-parser.c @@ -25,23 +25,19 @@ #include "config.h" #include -#include #include +#include #include #include #include "ostree-autocleanups.h" -#include "ostree-repo-finder-avahi.h" #include "ostree-repo-finder-avahi-private.h" +#include "ostree-repo-finder-avahi.h" /* Reference: RFC 6763, §6. */ static gboolean -parse_txt_record (const guint8 *txt, - gsize txt_len, - const gchar **key, - gsize *key_len, - const guint8 **value, - gsize *value_len) +parse_txt_record (const guint8 *txt, gsize txt_len, const gchar **key, gsize *key_len, + const guint8 **value, gsize *value_len) { gsize i; @@ -54,7 +50,7 @@ parse_txt_record (const guint8 *txt, if (txt_len > 8900) return FALSE; - *key = (const gchar *) txt; + *key = (const gchar *)txt; *key_len = 0; *value = NULL; *value_len = 0; @@ -92,9 +88,9 @@ GHashTable * _ostree_txt_records_parse (AvahiStringList *txt_list) { AvahiStringList *l; - g_autoptr(GHashTable) out = NULL; + g_autoptr (GHashTable) out = NULL; - out = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_bytes_unref); + out = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_bytes_unref); for (l = txt_list; l != NULL; l = avahi_string_list_get_next (l)) { @@ -104,15 +100,14 @@ _ostree_txt_records_parse (AvahiStringList *txt_list) const guint8 *value; gsize key_len, value_len; g_autofree gchar *key_allocated = NULL; - g_autoptr(GBytes) value_allocated = NULL; + g_autoptr (GBytes) value_allocated = NULL; txt = avahi_string_list_get_text (l); txt_len = avahi_string_list_get_size (l); if (!parse_txt_record (txt, txt_len, &key, &key_len, &value, &value_len)) { - g_debug ("Ignoring invalid TXT record of length %" G_GSIZE_FORMAT, - txt_len); + g_debug ("Ignoring invalid TXT record of length %" G_GSIZE_FORMAT, txt_len); continue; } @@ -130,7 +125,8 @@ _ostree_txt_records_parse (AvahiStringList *txt_list) if (value != NULL) value_allocated = g_bytes_new_static (value, value_len); - g_hash_table_insert (out, g_steal_pointer (&key_allocated), g_steal_pointer (&value_allocated)); + g_hash_table_insert (out, g_steal_pointer (&key_allocated), + g_steal_pointer (&value_allocated)); } return g_steal_pointer (&out); diff --git a/src/libostree/ostree-repo-finder-avahi-private.h b/src/libostree/ostree-repo-finder-avahi-private.h index f44677e..47d3a87 100644 --- a/src/libostree/ostree-repo-finder-avahi-private.h +++ b/src/libostree/ostree-repo-finder-avahi-private.h @@ -24,8 +24,8 @@ #include #include -#include #include +#include G_BEGIN_DECLS diff --git a/src/libostree/ostree-repo-finder-avahi.c b/src/libostree/ostree-repo-finder-avahi.c index 7555df6..680ac0b 100644 --- a/src/libostree/ostree-repo-finder-avahi.c +++ b/src/libostree/ostree-repo-finder-avahi.c @@ -37,25 +37,25 @@ #include #include #include -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ #include -#include #include +#include #include #include "ostree-autocleanups.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-avahi.h" +#include "ostree-repo-finder.h" #ifdef HAVE_AVAHI #include "ostree-bloom-private.h" #include "ostree-remote-private.h" +#include "ostree-repo-finder-avahi-private.h" #include "ostree-repo-private.h" #include "ostree-repo.h" -#include "ostree-repo-finder-avahi-private.h" #include "otutil.h" -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ /** * SECTION:ostree-repo-finder-avahi @@ -107,7 +107,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (AvahiServiceBrowser, avahi_service_browser_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (AvahiServiceResolver, avahi_service_resolver_free) /* FIXME: Register this with IANA? https://tools.ietf.org/html/rfc6335#section-5.2 */ -const gchar * const OSTREE_AVAHI_SERVICE_TYPE = "_ostree_repo._tcp"; +const gchar *const OSTREE_AVAHI_SERVICE_TYPE = "_ostree_repo._tcp"; static const gchar * ostree_avahi_client_state_to_string (AvahiClientState state) @@ -166,7 +166,7 @@ ostree_avahi_browser_event_to_string (AvahiBrowserEvent event) typedef struct { gchar *uri; - OstreeRemote *keyring_remote; /* (owned) */ + OstreeRemote *keyring_remote; /* (owned) */ } UriAndKeyring; static void @@ -180,10 +180,9 @@ uri_and_keyring_free (UriAndKeyring *data) G_DEFINE_AUTOPTR_CLEANUP_FUNC (UriAndKeyring, uri_and_keyring_free) static UriAndKeyring * -uri_and_keyring_new (const gchar *uri, - OstreeRemote *keyring_remote) +uri_and_keyring_new (const gchar *uri, OstreeRemote *keyring_remote) { - g_autoptr(UriAndKeyring) data = NULL; + g_autoptr (UriAndKeyring) data = NULL; data = g_new0 (UriAndKeyring, 1); data->uri = g_strdup (uri); @@ -201,13 +200,12 @@ uri_and_keyring_hash (gconstpointer key) } static gboolean -uri_and_keyring_equal (gconstpointer a, - gconstpointer b) +uri_and_keyring_equal (gconstpointer a, gconstpointer b) { const UriAndKeyring *_a = a, *_b = b; - return (g_str_equal (_a->uri, _b->uri) && - g_str_equal (_a->keyring_remote->keyring, _b->keyring_remote->keyring)); + return (g_str_equal (_a->uri, _b->uri) + && g_str_equal (_a->keyring_remote->keyring, _b->keyring_remote->keyring)); } /* This must return a valid remote name (suitable for use in a refspec). */ @@ -215,7 +213,8 @@ static gchar * uri_and_keyring_to_name (UriAndKeyring *data) { g_autofree gchar *escaped_uri = g_uri_escape_string (data->uri, NULL, FALSE); - g_autofree gchar *escaped_keyring = g_uri_escape_string (data->keyring_remote->keyring, NULL, FALSE); + g_autofree gchar *escaped_keyring + = g_uri_escape_string (data->keyring_remote->keyring, NULL, FALSE); /* FIXME: Need a better separator than `_`, since it’s not escaped in the input. */ g_autofree gchar *out = g_strdup_printf ("%s_%s", escaped_uri, escaped_keyring); @@ -261,8 +260,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAvahiService, ostree_avahi_service_free) * (See https://en.wikipedia.org/wiki/IPv6_address#Link-local_addresses_and_zone_indices and * https://github.com/lathiat/avahi/issues/110.) */ static gchar * -address_to_string (const AvahiAddress *address, - AvahiIfIndex interface) +address_to_string (const AvahiAddress *address, AvahiIfIndex interface) { char address_string[AVAHI_ADDRESS_STR_MAX]; @@ -271,8 +269,7 @@ address_to_string (const AvahiAddress *address, switch (address->proto) { case AVAHI_PROTO_INET6: - if (IN6_IS_ADDR_LINKLOCAL (address->data.data) || - IN6_IS_ADDR_LOOPBACK (address->data.data)) + if (IN6_IS_ADDR_LINKLOCAL (address->data.data) || IN6_IS_ADDR_LOOPBACK (address->data.data)) return g_strdup_printf ("%s%%%d", address_string, interface); /* else fall through */ case AVAHI_PROTO_INET: @@ -283,14 +280,10 @@ address_to_string (const AvahiAddress *address, } static OstreeAvahiService * -ostree_avahi_service_new (const gchar *name, - const gchar *domain, - const AvahiAddress *address, - AvahiIfIndex interface, - guint16 port, - AvahiStringList *txt) +ostree_avahi_service_new (const gchar *name, const gchar *domain, const AvahiAddress *address, + AvahiIfIndex interface, guint16 port, AvahiStringList *txt) { - g_autoptr(OstreeAvahiService) service = NULL; + g_autoptr (OstreeAvahiService) service = NULL; g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (domain != NULL, NULL); @@ -328,12 +321,11 @@ str_is_lowercase (const gchar *str) * is of the wrong type or is not in normal form, %NULL is returned. @key must * be lowercase in order to match reliably. */ static GVariant * -_ostree_txt_records_lookup_variant (GHashTable *attributes, - const gchar *key, +_ostree_txt_records_lookup_variant (GHashTable *attributes, const gchar *key, const GVariantType *value_type) { GBytes *value; - g_autoptr(GVariant) variant = NULL; + g_autoptr (GVariant) variant = NULL; g_return_val_if_fail (attributes != NULL, NULL); g_return_val_if_fail (str_is_lowercase (key), NULL); @@ -360,8 +352,7 @@ _ostree_txt_records_lookup_variant (GHashTable *attributes, /* Bloom hash function family for #OstreeCollectionRef, parameterised by @k. */ static guint64 -ostree_collection_ref_bloom_hash (gconstpointer element, - guint8 k) +ostree_collection_ref_bloom_hash (gconstpointer element, guint8 k) { const OstreeCollectionRef *ref = element; @@ -373,18 +364,17 @@ ostree_collection_ref_bloom_hash (gconstpointer element, * %NULL-terminated. If there is an error decoding the bloom filter (invalid * type, zero length, unknown hash function), %NULL will be returned. */ static GPtrArray * -bloom_refs_intersection (GVariant *bloom_encoded, - const OstreeCollectionRef * const *refs) +bloom_refs_intersection (GVariant *bloom_encoded, const OstreeCollectionRef *const *refs) { - g_autoptr(OstreeBloom) bloom = NULL; - g_autoptr(GVariant) bloom_variant = NULL; + g_autoptr (OstreeBloom) bloom = NULL; + g_autoptr (GVariant) bloom_variant = NULL; guint8 k, hash_id; OstreeBloomHashFunc hash_func; const guint8 *bloom_bytes; gsize n_bloom_bytes; - g_autoptr(GBytes) bytes = NULL; + g_autoptr (GBytes) bytes = NULL; gsize i; - g_autoptr(GPtrArray) possible_refs = NULL; /* (element-type OstreeCollectionRef) */ + g_autoptr (GPtrArray) possible_refs = NULL; /* (element-type OstreeCollectionRef) */ g_variant_get (bloom_encoded, "(yy@ay)", &k, &hash_id, &bloom_variant); @@ -409,7 +399,7 @@ bloom_refs_intersection (GVariant *bloom_encoded, for (i = 0; refs[i] != NULL; i++) { if (ostree_bloom_maybe_contains (bloom, refs[i])) - g_ptr_array_add (possible_refs, (gpointer) refs[i]); + g_ptr_array_add (possible_refs, (gpointer)refs[i]); } return g_steal_pointer (&possible_refs); @@ -422,19 +412,17 @@ bloom_refs_intersection (GVariant *bloom_encoded, * The @summary_map is validated as it’s iterated over; on error, @error will be * set and @refs_and_checksums will be left in an undefined state. */ static gboolean -fill_refs_and_checksums_from_summary_map (GVariantIter *summary_map, - const gchar *collection_id, - GHashTable *refs_and_checksums /* (element-type OstreeCollectionRef utf8) */, - GError **error) +fill_refs_and_checksums_from_summary_map ( + GVariantIter *summary_map, const gchar *collection_id, + GHashTable *refs_and_checksums /* (element-type OstreeCollectionRef utf8) */, GError **error) { g_autofree gchar *ref_name = NULL; - g_autoptr(GVariant) checksum_variant = NULL; + g_autoptr (GVariant) checksum_variant = NULL; - while (g_variant_iter_loop (summary_map, "(s(t@aya{sv}))", - (gpointer *) &ref_name, NULL, - (gpointer *) &checksum_variant, NULL)) + while (g_variant_iter_loop (summary_map, "(s(t@aya{sv}))", (gpointer *)&ref_name, NULL, + (gpointer *)&checksum_variant, NULL)) { - const OstreeCollectionRef ref = { (gchar *) collection_id, ref_name }; + const OstreeCollectionRef ref = { (gchar *)collection_id, ref_name }; if (!ostree_validate_rev (ref_name, error)) return FALSE; @@ -445,8 +433,7 @@ fill_refs_and_checksums_from_summary_map (GVariantIter *summary_map, { g_autofree gchar *checksum_string = ostree_checksum_from_bytes_v (checksum_variant); - g_hash_table_replace (refs_and_checksums, - ostree_collection_ref_dup (&ref), + g_hash_table_replace (refs_and_checksums, ostree_collection_ref_dup (&ref), g_steal_pointer (&checksum_string)); } } @@ -461,16 +448,16 @@ fill_refs_and_checksums_from_summary_map (GVariantIter *summary_map, * The @summary is validated as it’s explored; on error, @error will be * set and @refs_and_checksums will be left in an undefined state. */ static gboolean -fill_refs_and_checksums_from_summary (GVariant *summary, - GHashTable *refs_and_checksums /* (element-type OstreeCollectionRef utf8) */, - GError **error) +fill_refs_and_checksums_from_summary ( + GVariant *summary, GHashTable *refs_and_checksums /* (element-type OstreeCollectionRef utf8) */, + GError **error) { - g_autoptr(GVariant) ref_map_v = NULL; - g_autoptr(GVariant) additional_metadata_v = NULL; - g_autoptr(GVariantIter) ref_map = NULL; - g_auto(GVariantDict) additional_metadata = OT_VARIANT_BUILDER_INITIALIZER; + g_autoptr (GVariant) ref_map_v = NULL; + g_autoptr (GVariant) additional_metadata_v = NULL; + g_autoptr (GVariantIter) ref_map = NULL; + g_auto (GVariantDict) additional_metadata = OT_VARIANT_BUILDER_INITIALIZER; const gchar *collection_id; - g_autoptr(GVariantIter) collection_map = NULL; + g_autoptr (GVariantIter) collection_map = NULL; ref_map_v = g_variant_get_child_value (summary, 0); additional_metadata_v = g_variant_get_child_value (summary, 1); @@ -482,24 +469,28 @@ fill_refs_and_checksums_from_summary (GVariant *summary, * ref map), use that to start matching against the queried refs. Otherwise, * it might specify all its refs in a collection-map; or the summary format is * old and unsuitable for P2P redistribution and we should bail. */ - if (g_variant_dict_lookup (&additional_metadata, OSTREE_SUMMARY_COLLECTION_ID, "&s", &collection_id)) + if (g_variant_dict_lookup (&additional_metadata, OSTREE_SUMMARY_COLLECTION_ID, "&s", + &collection_id)) { if (!ostree_validate_collection_id (collection_id, error)) return FALSE; - if (!fill_refs_and_checksums_from_summary_map (ref_map, collection_id, refs_and_checksums, error)) + if (!fill_refs_and_checksums_from_summary_map (ref_map, collection_id, refs_and_checksums, + error)) return FALSE; } g_clear_pointer (&ref_map, g_variant_iter_free); /* Repeat for the other collections listed in the summary. */ - if (g_variant_dict_lookup (&additional_metadata, OSTREE_SUMMARY_COLLECTION_MAP, "a{sa(s(taya{sv}))}", &collection_map)) + if (g_variant_dict_lookup (&additional_metadata, OSTREE_SUMMARY_COLLECTION_MAP, + "a{sa(s(taya{sv}))}", &collection_map)) { while (g_variant_iter_loop (collection_map, "{sa(s(taya{sv}))}", &collection_id, &ref_map)) { if (!ostree_validate_collection_id (collection_id, error)) return FALSE; - if (!fill_refs_and_checksums_from_summary_map (ref_map, collection_id, refs_and_checksums, error)) + if (!fill_refs_and_checksums_from_summary_map (ref_map, collection_id, refs_and_checksums, + error)) return FALSE; } } @@ -508,9 +499,7 @@ fill_refs_and_checksums_from_summary (GVariant *summary, } static gboolean -remove_null_checksum_refs_cb (gpointer key, - gpointer value, - gpointer user_data) +remove_null_checksum_refs_cb (gpointer key, gpointer value, gpointer user_data) { const char *checksum = value; @@ -526,24 +515,23 @@ remove_null_checksum_refs_cb (gpointer key, * set and %FALSE will be returned. If the intersection of the summary file refs * and the keys in @supported_ref_to_checksum is empty, an error is set. */ static gboolean -get_refs_and_checksums_from_summary (GBytes *summary_bytes, - GHashTable *supported_ref_to_checksum /* (element-type OstreeCollectionRef utf8) */, - OstreeRemote *remote, - GError **error) +get_refs_and_checksums_from_summary ( + GBytes *summary_bytes, + GHashTable *supported_ref_to_checksum /* (element-type OstreeCollectionRef utf8) */, + OstreeRemote *remote, GError **error) { - g_autoptr(GVariant) summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE)); + g_autoptr (GVariant) summary = g_variant_ref_sink ( + g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE)); guint removed_refs; if (!g_variant_is_normal_form (summary)) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Not normal form"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not normal form"); return FALSE; } if (!g_variant_is_of_type (summary, OSTREE_SUMMARY_GVARIANT_FORMAT)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Doesn't match variant type '%s'", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Doesn't match variant type '%s'", (char *)OSTREE_SUMMARY_GVARIANT_FORMAT); return FALSE; } @@ -551,10 +539,12 @@ get_refs_and_checksums_from_summary (GBytes *summary_bytes, if (!fill_refs_and_checksums_from_summary (summary, supported_ref_to_checksum, error)) return FALSE; - removed_refs = g_hash_table_foreach_remove (supported_ref_to_checksum, remove_null_checksum_refs_cb, NULL); + removed_refs + = g_hash_table_foreach_remove (supported_ref_to_checksum, remove_null_checksum_refs_cb, NULL); if (removed_refs > 0) - g_debug ("Removed %d refs from the list resolved from ‘%s’ (possibly bloom filter false positives)", - removed_refs, remote->name); + g_debug ( + "Removed %d refs from the list resolved from ‘%s’ (possibly bloom filter false positives)", + removed_refs, remote->name); /* If none of the refs had a non-%NULL checksum set, we can discard this peer. */ if (g_hash_table_size (supported_ref_to_checksum) == 0) @@ -571,21 +561,14 @@ get_refs_and_checksums_from_summary (GBytes *summary_bytes, * @out_summary_bytes. This will return %TRUE and set @out_summary_bytes to %NULL * if the summary file does not exist. */ static gboolean -fetch_summary_from_remote (OstreeRepo *repo, - OstreeRemote *remote, - GBytes **out_summary_bytes, - GCancellable *cancellable, - GError **error) +fetch_summary_from_remote (OstreeRepo *repo, OstreeRemote *remote, GBytes **out_summary_bytes, + GCancellable *cancellable, GError **error) { - g_autoptr(GBytes) summary_bytes = NULL; + g_autoptr (GBytes) summary_bytes = NULL; gboolean remote_already_existed = _ostree_repo_add_remote (repo, remote); - gboolean success = ostree_repo_remote_fetch_summary_with_options (repo, - remote->name, - NULL /* options */, - &summary_bytes, - NULL /* signature */, - cancellable, - error); + gboolean success = ostree_repo_remote_fetch_summary_with_options ( + repo, remote->name, NULL /* options */, &summary_bytes, NULL /* signature */, cancellable, + error); if (!remote_already_existed) _ostree_repo_remove_remote (repo, remote); @@ -597,7 +580,7 @@ fetch_summary_from_remote (OstreeRepo *repo, *out_summary_bytes = g_steal_pointer (&summary_bytes); return TRUE; } -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ struct _OstreeRepoFinderAvahi { @@ -609,7 +592,7 @@ struct _OstreeRepoFinderAvahi /* Note: There is a ref-count loop here: each #GTask has a reference to the * #OstreeRepoFinderAvahi, and we have to keep a reference to the #GTask. */ - GPtrArray *resolve_tasks; /* (element-type (owned) GTask) */ + GPtrArray *resolve_tasks; /* (element-type (owned) GTask) */ AvahiGLibPoll *poll; AvahiClient *client; @@ -627,18 +610,20 @@ struct _OstreeRepoFinderAvahi * could end up with more than one resolver if the same name is advertised to * us over multiple interfaces or protocols (for example, IPv4 and IPv6). * Resolve all of them just in case one doesn’t work. */ - GHashTable *resolvers; /* (element-type (owned) utf8 (owned) GPtrArray (element-type (owned) AvahiServiceResolver)) */ + GHashTable *resolvers; /* (element-type (owned) utf8 (owned) GPtrArray (element-type (owned) + AvahiServiceResolver)) */ /* Array of #OstreeAvahiService instances representing all the services which * we currently think are valid. */ - GPtrArray *found_services; /* (element-type (owned OstreeAvahiService) */ -#endif /* HAVE_AVAHI */ + GPtrArray *found_services; /* (element-type (owned OstreeAvahiService) */ +#endif /* HAVE_AVAHI */ }; static void ostree_repo_finder_avahi_iface_init (OstreeRepoFinderInterface *iface); G_DEFINE_TYPE_WITH_CODE (OstreeRepoFinderAvahi, ostree_repo_finder_avahi, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, ostree_repo_finder_avahi_iface_init)) + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, + ostree_repo_finder_avahi_iface_init)) #ifdef HAVE_AVAHI @@ -646,29 +631,23 @@ G_DEFINE_TYPE_WITH_CODE (OstreeRepoFinderAvahi, ostree_repo_finder_avahi, G_TYPE * @supported_ref_to_checksum hash table, given the existing refs in it as keys. * See get_refs_and_checksums_from_summary() for more details. */ static gboolean -get_checksums (OstreeRepoFinderAvahi *finder, - OstreeRepo *repo, - OstreeRemote *remote, - GHashTable *supported_ref_to_checksum /* (element-type OstreeCollectionRef utf8) */, - GError **error) +get_checksums (OstreeRepoFinderAvahi *finder, OstreeRepo *repo, OstreeRemote *remote, + GHashTable *supported_ref_to_checksum /* (element-type OstreeCollectionRef utf8) */, + GError **error) { - g_autoptr(GBytes) summary_bytes = NULL; + g_autoptr (GBytes) summary_bytes = NULL; - if (!fetch_summary_from_remote (repo, - remote, - &summary_bytes, - finder->avahi_cancellable, - error)) + if (!fetch_summary_from_remote (repo, remote, &summary_bytes, finder->avahi_cancellable, error)) return FALSE; if (summary_bytes == NULL) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No summary file found on server"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No summary file found on server"); return FALSE; } - return get_refs_and_checksums_from_summary (summary_bytes, supported_ref_to_checksum, remote, error); + return get_refs_and_checksums_from_summary (summary_bytes, supported_ref_to_checksum, remote, + error); } /* Build some #OstreeRepoFinderResults out of the given #OstreeAvahiService by @@ -690,27 +669,25 @@ get_checksums (OstreeRepoFinderAvahi *finder, * hosted on the peer this is. Big endian. */ static void -ostree_avahi_service_build_repo_finder_result (OstreeAvahiService *service, - OstreeRepoFinderAvahi *finder, - OstreeRepo *parent_repo, - gint priority, - const OstreeCollectionRef * const *refs, - GPtrArray *results, - GCancellable *cancellable) +ostree_avahi_service_build_repo_finder_result (OstreeAvahiService *service, + OstreeRepoFinderAvahi *finder, + OstreeRepo *parent_repo, gint priority, + const OstreeCollectionRef *const *refs, + GPtrArray *results, GCancellable *cancellable) { - g_autoptr(GHashTable) attributes = NULL; - g_autoptr(GVariant) version = NULL; - g_autoptr(GVariant) bloom = NULL; - g_autoptr(GVariant) summary_timestamp = NULL; - g_autoptr(GVariant) repo_index = NULL; + g_autoptr (GHashTable) attributes = NULL; + g_autoptr (GVariant) version = NULL; + g_autoptr (GVariant) bloom = NULL; + g_autoptr (GVariant) summary_timestamp = NULL; + g_autoptr (GVariant) repo_index = NULL; g_autofree gchar *repo_path = NULL; - g_autoptr(GPtrArray) possible_refs = NULL; /* (element-type OstreeCollectionRef) */ + g_autoptr (GPtrArray) possible_refs = NULL; /* (element-type OstreeCollectionRef) */ GUri *_uri = NULL; g_autofree gchar *uri = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; gsize i; - g_autoptr(GHashTable) repo_to_refs = NULL; /* (element-type UriAndKeyring GHashTable) */ - GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) repo_to_refs = NULL; /* (element-type UriAndKeyring GHashTable) */ + GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ GHashTableIter iter; UriAndKeyring *repo; @@ -741,7 +718,8 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService possible_refs = bloom_refs_intersection (bloom, refs); if (possible_refs == NULL) { - g_debug ("Wrong k parameter or hash id in rb (refs bloom) attribute in TXT record. Ignoring."); + g_debug ( + "Wrong k parameter or hash id in rb (refs bloom) attribute in TXT record. Ignoring."); return; } if (possible_refs->len == 0) @@ -770,28 +748,28 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService /* Create a new result for each keyring needed by @possible_refs. Typically, * there will be a separate keyring per collection, but some might be shared. */ repo_to_refs = g_hash_table_new_full (uri_and_keyring_hash, uri_and_keyring_equal, - (GDestroyNotify) uri_and_keyring_free, (GDestroyNotify) g_hash_table_unref); + (GDestroyNotify)uri_and_keyring_free, + (GDestroyNotify)g_hash_table_unref); - _uri = g_uri_build (G_URI_FLAGS_ENCODED, "http", NULL, service->address, service->port, repo_path, NULL, NULL); + _uri = g_uri_build (G_URI_FLAGS_ENCODED, "http", NULL, service->address, service->port, repo_path, + NULL, NULL); uri = g_uri_to_string (_uri); g_uri_unref (_uri); for (i = 0; i < possible_refs->len; i++) { const OstreeCollectionRef *ref = g_ptr_array_index (possible_refs, i); - g_autoptr(UriAndKeyring) resolved_repo = NULL; - g_autoptr(OstreeRemote) keyring_remote = NULL; + g_autoptr (UriAndKeyring) resolved_repo = NULL; + g_autoptr (OstreeRemote) keyring_remote = NULL; /* Look up the GPG keyring for this ref. */ - keyring_remote = ostree_repo_resolve_keyring_for_collection (parent_repo, - ref->collection_id, + keyring_remote = ostree_repo_resolve_keyring_for_collection (parent_repo, ref->collection_id, cancellable, &error); if (keyring_remote == NULL) { g_debug ("Ignoring ref (%s, %s) on host ‘%s’ due to missing keyring: %s", - ref->collection_id, refs[i]->ref_name, service->address, - error->message); + ref->collection_id, refs[i]->ref_name, service->address, error->message); g_clear_error (&error); continue; } @@ -808,23 +786,23 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService if (supported_ref_to_checksum == NULL) { - supported_ref_to_checksum = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - NULL, g_free); - g_hash_table_insert (repo_to_refs, g_steal_pointer (&resolved_repo), supported_ref_to_checksum /* transfer */); + supported_ref_to_checksum = g_hash_table_new_full ( + ostree_collection_ref_hash, ostree_collection_ref_equal, NULL, g_free); + g_hash_table_insert (repo_to_refs, g_steal_pointer (&resolved_repo), + supported_ref_to_checksum /* transfer */); } /* Add a placeholder to @supported_ref_to_checksum for this ref. It will * be filled out by the get_checksums() call below. */ - g_hash_table_insert (supported_ref_to_checksum, (gpointer) ref, NULL); + g_hash_table_insert (supported_ref_to_checksum, (gpointer)ref, NULL); } /* Aggregate the results. */ g_hash_table_iter_init (&iter, repo_to_refs); - while (g_hash_table_iter_next (&iter, (gpointer *) &repo, (gpointer *) &supported_ref_to_checksum)) + while (g_hash_table_iter_next (&iter, (gpointer *)&repo, (gpointer *)&supported_ref_to_checksum)) { - g_autoptr(OstreeRemote) remote = NULL; + g_autoptr (OstreeRemote) remote = NULL; /* Build an #OstreeRemote. Use the escaped URI, since remote->name * is used in file paths, so needs to not contain special characters. */ @@ -847,16 +825,17 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService continue; } - g_ptr_array_add (results, ostree_repo_finder_result_new (remote, OSTREE_REPO_FINDER (finder), - priority, supported_ref_to_checksum, NULL, - GUINT64_FROM_BE (g_variant_get_uint64 (summary_timestamp)))); + g_ptr_array_add (results, + ostree_repo_finder_result_new ( + remote, OSTREE_REPO_FINDER (finder), priority, supported_ref_to_checksum, + NULL, GUINT64_FROM_BE (g_variant_get_uint64 (summary_timestamp)))); } } typedef struct { - OstreeCollectionRef **refs; /* (owned) (array zero-terminated=1) */ - OstreeRepo *parent_repo; /* (owned) */ + OstreeCollectionRef **refs; /* (owned) (array zero-terminated=1) */ + OstreeRepo *parent_repo; /* (owned) */ } ResolveData; static void @@ -870,10 +849,9 @@ resolve_data_free (ResolveData *data) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ResolveData, resolve_data_free) static ResolveData * -resolve_data_new (const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo) +resolve_data_new (const OstreeCollectionRef *const *refs, OstreeRepo *parent_repo) { - g_autoptr(ResolveData) data = NULL; + g_autoptr (ResolveData) data = NULL; data = g_new0 (ResolveData, 1); data->refs = ostree_collection_ref_dupv (refs); @@ -882,27 +860,20 @@ resolve_data_new (const OstreeCollectionRef * const *refs, return g_steal_pointer (&data); } -static void -fail_all_pending_tasks (OstreeRepoFinderAvahi *self, - GQuark domain, - gint code, - const gchar *format, - ...) G_GNUC_PRINTF(4, 5); +static void fail_all_pending_tasks (OstreeRepoFinderAvahi *self, GQuark domain, gint code, + const gchar *format, ...) G_GNUC_PRINTF (4, 5); /* Executed in @self->avahi_context. * * Return the given error from all the pending resolve tasks in * self->resolve_tasks. */ static void -fail_all_pending_tasks (OstreeRepoFinderAvahi *self, - GQuark domain, - gint code, - const gchar *format, +fail_all_pending_tasks (OstreeRepoFinderAvahi *self, GQuark domain, gint code, const gchar *format, ...) { gsize i; va_list args; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; g_assert (g_main_context_is_owner (self->avahi_context)); @@ -920,11 +891,10 @@ fail_all_pending_tasks (OstreeRepoFinderAvahi *self, } static gint -results_compare_cb (gconstpointer a, - gconstpointer b) +results_compare_cb (gconstpointer a, gconstpointer b) { - const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **) a); - const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **) b); + const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **)a); + const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **)b); return ostree_repo_finder_result_compare (result_a, result_b); } @@ -938,8 +908,9 @@ static void complete_all_pending_tasks (OstreeRepoFinderAvahi *self) { gsize i; - const gint priority = 60; /* arbitrarily chosen */ - g_autoptr(GPtrArray) results_for_tasks = g_ptr_array_new_full (self->resolve_tasks->len, (GDestroyNotify)g_ptr_array_unref); + const gint priority = 60; /* arbitrarily chosen */ + g_autoptr (GPtrArray) results_for_tasks + = g_ptr_array_new_full (self->resolve_tasks->len, (GDestroyNotify)g_ptr_array_unref); gboolean cancelled = FALSE; g_assert (g_main_context_is_owner (self->avahi_context)); @@ -947,24 +918,23 @@ complete_all_pending_tasks (OstreeRepoFinderAvahi *self) for (i = 0; i < self->resolve_tasks->len; i++) { - g_autoptr(GPtrArray) results = NULL; + g_autoptr (GPtrArray) results = NULL; GTask *task; ResolveData *data; - const OstreeCollectionRef * const *refs; + const OstreeCollectionRef *const *refs; gsize j; task = G_TASK (g_ptr_array_index (self->resolve_tasks, i)); data = g_task_get_task_data (task); - refs = (const OstreeCollectionRef * const *) data->refs; - results = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_repo_finder_result_free); + refs = (const OstreeCollectionRef *const *)data->refs; + results = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_repo_finder_result_free); for (j = 0; j < self->found_services->len; j++) { OstreeAvahiService *service = g_ptr_array_index (self->found_services, j); - ostree_avahi_service_build_repo_finder_result (service, self, data->parent_repo, - priority, refs, results, - self->avahi_cancellable); + ostree_avahi_service_build_repo_finder_result (service, self, data->parent_repo, priority, + refs, results, self->avahi_cancellable); if (g_cancellable_is_cancelled (self->avahi_cancellable)) { cancelled = TRUE; @@ -986,9 +956,8 @@ complete_all_pending_tasks (OstreeRepoFinderAvahi *self) g_ptr_array_sort (results, results_compare_cb); - g_task_return_pointer (task, - g_ptr_array_ref (results), - (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_ptr_array_ref (results), + (GDestroyNotify)g_ptr_array_unref); } g_ptr_array_set_size (self->resolve_tasks, 0); @@ -1008,41 +977,34 @@ maybe_complete_all_pending_tasks (OstreeRepoFinderAvahi *self) g_debug ("%s: client_state: %s, browser_failed: %u, cancelled: %u, " "browser_all_for_now: %u, n_resolvers: %u", G_STRFUNC, ostree_avahi_client_state_to_string (self->client_state), - self->browser_failed, - g_cancellable_is_cancelled (self->avahi_cancellable), + self->browser_failed, g_cancellable_is_cancelled (self->avahi_cancellable), self->browser_all_for_now, g_hash_table_size (self->resolvers)); if (self->client_state == AVAHI_CLIENT_FAILURE) - fail_all_pending_tasks (self, G_IO_ERROR, G_IO_ERROR_FAILED, - "Avahi client error: %s", + fail_all_pending_tasks (self, G_IO_ERROR, G_IO_ERROR_FAILED, "Avahi client error: %s", avahi_strerror (avahi_client_errno (self->client))); else if (self->browser_failed) - fail_all_pending_tasks (self, G_IO_ERROR, G_IO_ERROR_FAILED, - "Avahi browser error: %s", + fail_all_pending_tasks (self, G_IO_ERROR, G_IO_ERROR_FAILED, "Avahi browser error: %s", avahi_strerror (avahi_client_errno (self->client))); else if (g_cancellable_is_cancelled (self->avahi_cancellable)) fail_all_pending_tasks (self, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Avahi service resolution cancelled."); - else if (self->browser_all_for_now && - g_hash_table_size (self->resolvers) == 0) + else if (self->browser_all_for_now && g_hash_table_size (self->resolvers) == 0) complete_all_pending_tasks (self); } /* Executed in @self->avahi_context. */ static void -client_cb (AvahiClient *client, - AvahiClientState state, - void *finder_ptr) +client_cb (AvahiClient *client, AvahiClientState state, void *finder_ptr) { /* Completing the pending tasks might drop the final reference to @self. */ - g_autoptr(OstreeRepoFinderAvahi) self = g_object_ref (finder_ptr); + g_autoptr (OstreeRepoFinderAvahi) self = g_object_ref (finder_ptr); /* self->client will be NULL if client_cb() is called from * ostree_repo_finder_avahi_start(). */ g_assert (self->client == NULL || g_main_context_is_owner (self->avahi_context)); - g_debug ("%s: Entered state ‘%s’.", - G_STRFUNC, ostree_avahi_client_state_to_string (state)); + g_debug ("%s: Entered state ‘%s’.", G_STRFUNC, ostree_avahi_client_state_to_string (state)); /* We only care about entering and leaving %AVAHI_CLIENT_FAILURE. */ self->client_state = state; @@ -1052,29 +1014,20 @@ client_cb (AvahiClient *client, /* Executed in @self->avahi_context. */ static void -resolve_cb (AvahiServiceResolver *resolver, - AvahiIfIndex interface, - AvahiProtocol protocol, - AvahiResolverEvent event, - const char *name, - const char *type, - const char *domain, - const char *host_name, - const AvahiAddress *address, - uint16_t port, - AvahiStringList *txt, - AvahiLookupResultFlags flags, - void *finder_ptr) +resolve_cb (AvahiServiceResolver *resolver, AvahiIfIndex interface, AvahiProtocol protocol, + AvahiResolverEvent event, const char *name, const char *type, const char *domain, + const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, + AvahiLookupResultFlags flags, void *finder_ptr) { /* Completing the pending tasks might drop the final reference to @self. */ - g_autoptr(OstreeRepoFinderAvahi) self = g_object_ref (finder_ptr); - g_autoptr(OstreeAvahiService) service = NULL; + g_autoptr (OstreeRepoFinderAvahi) self = g_object_ref (finder_ptr); + g_autoptr (OstreeAvahiService) service = NULL; GPtrArray *resolvers; g_assert (g_main_context_is_owner (self->avahi_context)); - g_debug ("%s: Resolve event ‘%s’ for name ‘%s’.", - G_STRFUNC, ostree_avahi_resolver_event_to_string (event), name); + g_debug ("%s: Resolve event ‘%s’ for name ‘%s’.", G_STRFUNC, + ostree_avahi_resolver_event_to_string (event), name); /* Track the resolvers active for this @name. There may be several, * as @name might appear to us over several interfaces or protocols. Most @@ -1100,8 +1053,7 @@ resolve_cb (AvahiServiceResolver *resolver, switch (event) { case AVAHI_RESOLVER_FOUND: - service = ostree_avahi_service_new (name, domain, address, interface, - port, txt); + service = ostree_avahi_service_new (name, domain, address, interface, port, txt); g_ptr_array_add (self->found_services, g_steal_pointer (&service)); break; case AVAHI_RESOLVER_FAILURE: @@ -1116,28 +1068,16 @@ resolve_cb (AvahiServiceResolver *resolver, /* Executed in @self->avahi_context. */ static void -browse_new (OstreeRepoFinderAvahi *self, - AvahiIfIndex interface, - AvahiProtocol protocol, - const gchar *name, - const gchar *type, - const gchar *domain) +browse_new (OstreeRepoFinderAvahi *self, AvahiIfIndex interface, AvahiProtocol protocol, + const gchar *name, const gchar *type, const gchar *domain) { - g_autoptr(AvahiServiceResolver) resolver = NULL; - GPtrArray *resolvers; /* (element-type AvahiServiceResolver) */ + g_autoptr (AvahiServiceResolver) resolver = NULL; + GPtrArray *resolvers; /* (element-type AvahiServiceResolver) */ g_assert (g_main_context_is_owner (self->avahi_context)); - resolver = avahi_service_resolver_new (self->client, - interface, - protocol, - name, - type, - domain, - AVAHI_PROTO_UNSPEC, - 0, - resolve_cb, - self); + resolver = avahi_service_resolver_new (self->client, interface, protocol, name, type, domain, + AVAHI_PROTO_UNSPEC, 0, resolve_cb, self); if (resolver == NULL) { g_warning ("Failed to resolve service ‘%s’: %s", name, @@ -1146,15 +1086,15 @@ browse_new (OstreeRepoFinderAvahi *self, } g_debug ("Found name service %s on the network; type: %s, domain: %s, " - "protocol: %u, interface: %u", name, type, domain, protocol, - interface); + "protocol: %u, interface: %u", + name, type, domain, protocol, interface); /* Start a resolver for this (interface, protocol, name, type, domain) * combination. */ resolvers = g_hash_table_lookup (self->resolvers, name); if (resolvers == NULL) { - resolvers = g_ptr_array_new_with_free_func ((GDestroyNotify) avahi_service_resolver_free); + resolvers = g_ptr_array_new_with_free_func ((GDestroyNotify)avahi_service_resolver_free); g_hash_table_insert (self->resolvers, g_strdup (name), resolvers); } @@ -1163,8 +1103,7 @@ browse_new (OstreeRepoFinderAvahi *self, /* Executed in @self->avahi_context. Caller must call maybe_complete_all_pending_tasks(). */ static void -browse_remove (OstreeRepoFinderAvahi *self, - const char *name) +browse_remove (OstreeRepoFinderAvahi *self, const char *name) { gsize i; gboolean removed = FALSE; @@ -1190,23 +1129,17 @@ browse_remove (OstreeRepoFinderAvahi *self, /* Executed in @self->avahi_context. */ static void -browse_cb (AvahiServiceBrowser *browser, - AvahiIfIndex interface, - AvahiProtocol protocol, - AvahiBrowserEvent event, - const char *name, - const char *type, - const char *domain, - AvahiLookupResultFlags flags, - void *finder_ptr) +browse_cb (AvahiServiceBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, + AvahiBrowserEvent event, const char *name, const char *type, const char *domain, + AvahiLookupResultFlags flags, void *finder_ptr) { /* Completing the pending tasks might drop the final reference to @self. */ - g_autoptr(OstreeRepoFinderAvahi) self = g_object_ref (finder_ptr); + g_autoptr (OstreeRepoFinderAvahi) self = g_object_ref (finder_ptr); g_assert (g_main_context_is_owner (self->avahi_context)); - g_debug ("%s: Browse event ‘%s’ for name ‘%s’.", - G_STRFUNC, ostree_avahi_browser_event_to_string (event), name); + g_debug ("%s: Browse event ‘%s’ for name ‘%s’.", G_STRFUNC, + ostree_avahi_browser_event_to_string (event), name); self->browser_failed = FALSE; @@ -1242,18 +1175,16 @@ browse_cb (AvahiServiceBrowser *browser, } static gboolean add_resolve_task_cb (gpointer user_data); -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ static void -ostree_repo_finder_avahi_resolve_async (OstreeRepoFinder *finder, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_finder_avahi_resolve_async (OstreeRepoFinder *finder, + const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { OstreeRepoFinderAvahi *self = OSTREE_REPO_FINDER_AVAHI (finder); - g_autoptr(GTask) task = NULL; + g_autoptr (GTask) task = NULL; g_debug ("%s: Starting resolving", G_STRFUNC); @@ -1261,14 +1192,15 @@ ostree_repo_finder_avahi_resolve_async (OstreeRepoFinder *finde g_task_set_source_tag (task, ostree_repo_finder_avahi_resolve_async); #ifdef HAVE_AVAHI - g_task_set_task_data (task, resolve_data_new (refs, parent_repo), (GDestroyNotify) resolve_data_free); + g_task_set_task_data (task, resolve_data_new (refs, parent_repo), + (GDestroyNotify)resolve_data_free); /* Move @task to the @avahi_context where it can be processed. */ g_main_context_invoke (self->avahi_context, add_resolve_task_cb, g_steal_pointer (&task)); #else /* if !HAVE_AVAHI */ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Avahi support was not compiled in to libostree"); -#endif /* !HAVE_AVAHI */ +#endif /* !HAVE_AVAHI */ } #ifdef HAVE_AVAHI @@ -1276,7 +1208,7 @@ ostree_repo_finder_avahi_resolve_async (OstreeRepoFinder *finde static gboolean add_resolve_task_cb (gpointer user_data) { - g_autoptr(GTask) task = G_TASK (user_data); + g_autoptr (GTask) task = G_TASK (user_data); OstreeRepoFinderAvahi *self = g_task_get_source_object (task); g_assert (g_main_context_is_owner (self->avahi_context)); @@ -1289,12 +1221,11 @@ add_resolve_task_cb (gpointer user_data) return G_SOURCE_REMOVE; } -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ static GPtrArray * -ostree_repo_finder_avahi_resolve_finish (OstreeRepoFinder *finder, - GAsyncResult *result, - GError **error) +ostree_repo_finder_avahi_resolve_finish (OstreeRepoFinder *finder, GAsyncResult *result, + GError **error) { g_return_val_if_fail (g_task_is_valid (result, finder), NULL); return g_task_propagate_pointer (G_TASK (result), error); @@ -1318,7 +1249,7 @@ ostree_repo_finder_avahi_dispose (GObject *obj) g_clear_pointer (&self->found_services, g_ptr_array_unref); g_clear_pointer (&self->resolvers, g_hash_table_unref); g_clear_object (&self->avahi_cancellable); -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ /* Chain up. */ G_OBJECT_CLASS (ostree_repo_finder_avahi_parent_class)->dispose (obj); @@ -1343,12 +1274,13 @@ static void ostree_repo_finder_avahi_init (OstreeRepoFinderAvahi *self) { #ifdef HAVE_AVAHI - self->resolve_tasks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + self->resolve_tasks = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); self->avahi_cancellable = g_cancellable_new (); self->client_state = AVAHI_CLIENT_S_REGISTERING; - self->resolvers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); - self->found_services = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_avahi_service_free); -#endif /* HAVE_AVAHI */ + self->resolvers + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_ptr_array_unref); + self->found_services = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_avahi_service_free); +#endif /* HAVE_AVAHI */ } /** @@ -1372,7 +1304,7 @@ ostree_repo_finder_avahi_init (OstreeRepoFinderAvahi *self) OstreeRepoFinderAvahi * ostree_repo_finder_avahi_new (GMainContext *context) { - g_autoptr(OstreeRepoFinderAvahi) finder = NULL; + g_autoptr (OstreeRepoFinderAvahi) finder = NULL; finder = g_object_new (OSTREE_TYPE_REPO_FINDER_AVAHI, NULL); @@ -1389,7 +1321,7 @@ ostree_repo_finder_avahi_new (GMainContext *context) * *also* use Avahi API itself. */ avahi_set_allocator (avahi_glib_allocator ()); finder->poll = avahi_glib_poll_new (finder->avahi_context, G_PRIORITY_DEFAULT); -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ return g_steal_pointer (&finder); } @@ -1419,15 +1351,14 @@ ostree_repo_finder_avahi_new (GMainContext *context) * Since: 2018.6 */ void -ostree_repo_finder_avahi_start (OstreeRepoFinderAvahi *self, - GError **error) +ostree_repo_finder_avahi_start (OstreeRepoFinderAvahi *self, GError **error) { g_return_if_fail (OSTREE_IS_REPO_FINDER_AVAHI (self)); g_return_if_fail (error == NULL || *error == NULL); #ifdef HAVE_AVAHI - g_autoptr(AvahiClient) client = NULL; - g_autoptr(AvahiServiceBrowser) browser = NULL; + g_autoptr (AvahiClient) client = NULL; + g_autoptr (AvahiServiceBrowser) browser = NULL; int failure = 0; if (g_cancellable_set_error_if_cancelled (self->avahi_cancellable, error)) @@ -1435,37 +1366,27 @@ ostree_repo_finder_avahi_start (OstreeRepoFinderAvahi *self, g_assert (self->client == NULL); - client = avahi_client_new (avahi_glib_poll_get (self->poll), 0, - client_cb, self, &failure); + client = avahi_client_new (avahi_glib_poll_get (self->poll), 0, client_cb, self, &failure); if (client == NULL) { if (failure == AVAHI_ERR_NO_DAEMON) - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Avahi daemon is not running: %s", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Avahi daemon is not running: %s", avahi_strerror (failure)); else - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to create finder client: %s", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create finder client: %s", avahi_strerror (failure)); return; } /* Query for the OSTree DNS-SD service on the local network. */ - browser = avahi_service_browser_new (client, - AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, - OSTREE_AVAHI_SERVICE_TYPE, - NULL, - 0, - browse_cb, - self); + browser = avahi_service_browser_new (client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + OSTREE_AVAHI_SERVICE_TYPE, NULL, 0, browse_cb, self); if (browser == NULL) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to create service browser: %s", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create service browser: %s", avahi_strerror (avahi_client_errno (client))); return; } @@ -1476,12 +1397,12 @@ ostree_repo_finder_avahi_start (OstreeRepoFinderAvahi *self, #else /* if !HAVE_AVAHI */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Avahi support was not compiled in to libostree"); -#endif /* !HAVE_AVAHI */ +#endif /* !HAVE_AVAHI */ } #ifdef HAVE_AVAHI static gboolean stop_cb (gpointer user_data); -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ /** * ostree_repo_finder_avahi_stop: @@ -1509,14 +1430,14 @@ ostree_repo_finder_avahi_stop (OstreeRepoFinderAvahi *self) return; g_main_context_invoke (self->avahi_context, stop_cb, g_object_ref (self)); -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ } #ifdef HAVE_AVAHI static gboolean stop_cb (gpointer user_data) { - g_autoptr(OstreeRepoFinderAvahi) self = OSTREE_REPO_FINDER_AVAHI (user_data); + g_autoptr (OstreeRepoFinderAvahi) self = OSTREE_REPO_FINDER_AVAHI (user_data); g_cancellable_cancel (self->avahi_cancellable); maybe_complete_all_pending_tasks (self); @@ -1527,4 +1448,4 @@ stop_cb (gpointer user_data) return G_SOURCE_REMOVE; } -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ diff --git a/src/libostree/ostree-repo-finder-avahi.h b/src/libostree/ostree-repo-finder-avahi.h index 92b15f2..3885df6 100644 --- a/src/libostree/ostree-repo-finder-avahi.h +++ b/src/libostree/ostree-repo-finder-avahi.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include "ostree-repo-finder.h" #include "ostree-types.h" @@ -35,27 +35,39 @@ G_BEGIN_DECLS /* Manually expanded version of the following, omitting autoptr support (for GLib < 2.44): _OSTREE_PUBLIC -G_DECLARE_FINAL_TYPE (OstreeRepoFinderAvahi, ostree_repo_finder_avahi, OSTREE, REPO_FINDER_AVAHI, GObject) */ +G_DECLARE_FINAL_TYPE (OstreeRepoFinderAvahi, ostree_repo_finder_avahi, OSTREE, REPO_FINDER_AVAHI, +GObject) */ _OSTREE_PUBLIC GType ostree_repo_finder_avahi_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeRepoFinderAvahi OstreeRepoFinderAvahi; -typedef struct { GObjectClass parent_class; } OstreeRepoFinderAvahiClass; +typedef struct +{ + GObjectClass parent_class; +} OstreeRepoFinderAvahiClass; -static inline OstreeRepoFinderAvahi *OSTREE_REPO_FINDER_AVAHI (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_avahi_get_type (), OstreeRepoFinderAvahi); } -static inline gboolean OSTREE_IS_REPO_FINDER_AVAHI (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_avahi_get_type ()); } +static inline OstreeRepoFinderAvahi * +OSTREE_REPO_FINDER_AVAHI (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_avahi_get_type (), + OstreeRepoFinderAvahi); +} +static inline gboolean +OSTREE_IS_REPO_FINDER_AVAHI (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_avahi_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS _OSTREE_PUBLIC OstreeRepoFinderAvahi *ostree_repo_finder_avahi_new (GMainContext *context); _OSTREE_PUBLIC -void ostree_repo_finder_avahi_start (OstreeRepoFinderAvahi *self, - GError **error); +void ostree_repo_finder_avahi_start (OstreeRepoFinderAvahi *self, GError **error); _OSTREE_PUBLIC -void ostree_repo_finder_avahi_stop (OstreeRepoFinderAvahi *self); +void ostree_repo_finder_avahi_stop (OstreeRepoFinderAvahi *self); G_END_DECLS diff --git a/src/libostree/ostree-repo-finder-config.c b/src/libostree/ostree-repo-finder-config.c index 9cee8a9..a907dc3 100644 --- a/src/libostree/ostree-repo-finder-config.c +++ b/src/libostree/ostree-repo-finder-config.c @@ -24,16 +24,16 @@ #include #include -#include #include +#include #include #include "ostree-autocleanups.h" #include "ostree-remote-private.h" -#include "ostree-repo.h" -#include "ostree-repo-private.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-config.h" +#include "ostree-repo-finder.h" +#include "ostree-repo-private.h" +#include "ostree-repo.h" /** * SECTION:ostree-repo-finder-config @@ -65,42 +65,40 @@ struct _OstreeRepoFinderConfig }; G_DEFINE_TYPE_WITH_CODE (OstreeRepoFinderConfig, ostree_repo_finder_config, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, ostree_repo_finder_config_iface_init)) + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, + ostree_repo_finder_config_iface_init)) static gint -results_compare_cb (gconstpointer a, - gconstpointer b) +results_compare_cb (gconstpointer a, gconstpointer b) { - const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **) a); - const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **) b); + const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **)a); + const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **)b); return ostree_repo_finder_result_compare (result_a, result_b); } static void -ostree_repo_finder_config_resolve_async (OstreeRepoFinder *finder, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_finder_config_resolve_async (OstreeRepoFinder *finder, + const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = NULL; - g_autoptr(GPtrArray) results = NULL; - const gint priority = 100; /* arbitrarily chosen; lower than the others */ + g_autoptr (GTask) task = NULL; + g_autoptr (GPtrArray) results = NULL; + const gint priority = 100; /* arbitrarily chosen; lower than the others */ gsize i, j; - g_autoptr(GHashTable) repo_name_to_refs = NULL; /* (element-type utf8 GHashTable) */ - GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) repo_name_to_refs = NULL; /* (element-type utf8 GHashTable) */ + GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ GHashTableIter iter; const gchar *remote_name; - g_auto(GStrv) remotes = NULL; + g_auto (GStrv) remotes = NULL; guint n_remotes = 0; task = g_task_new (finder, cancellable, callback, user_data); g_task_set_source_tag (task, ostree_repo_finder_config_resolve_async); - results = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_repo_finder_result_free); - repo_name_to_refs = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, - (GDestroyNotify) g_hash_table_unref); + results = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_repo_finder_result_free); + repo_name_to_refs + = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_hash_table_unref); /* List all remotes in this #OstreeRepo and see which of their ref lists * intersect with @refs. */ @@ -110,17 +108,17 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find for (i = 0; i < n_remotes; i++) { - g_autoptr(GError) local_error = NULL; - g_autoptr(GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GError) local_error = NULL; + g_autoptr (GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ const gchar *checksum; g_autofree gchar *remote_collection_id = NULL; gboolean resolved_a_ref = FALSE; remote_name = remotes[i]; - if (!ostree_repo_get_remote_option (parent_repo, remote_name, "collection-id", - NULL, &remote_collection_id, &local_error) || - !ostree_validate_collection_id (remote_collection_id, &local_error)) + if (!ostree_repo_get_remote_option (parent_repo, remote_name, "collection-id", NULL, + &remote_collection_id, &local_error) + || !ostree_validate_collection_id (remote_collection_id, &local_error)) { g_debug ("Ignoring remote ‘%s’ due to no valid collection ID being configured for it: %s", remote_name, local_error->message); @@ -128,54 +126,55 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find continue; } - if (!ostree_repo_remote_list_collection_refs (parent_repo, remote_name, - &remote_refs, cancellable, - &local_error)) + if (!ostree_repo_remote_list_collection_refs (parent_repo, remote_name, &remote_refs, + cancellable, &local_error)) { - g_debug ("Ignoring remote ‘%s’ due to error loading its refs: %s", - remote_name, local_error->message); + g_debug ("Ignoring remote ‘%s’ due to error loading its refs: %s", remote_name, + local_error->message); g_clear_error (&local_error); continue; } for (j = 0; refs[j] != NULL; j++) { - if (g_strcmp0 (refs[j]->collection_id, remote_collection_id) == 0 && - g_hash_table_lookup_extended (remote_refs, refs[j], NULL, (gpointer *) &checksum)) + if (g_strcmp0 (refs[j]->collection_id, remote_collection_id) == 0 + && g_hash_table_lookup_extended (remote_refs, refs[j], NULL, (gpointer *)&checksum)) { /* The requested ref is listed in the refs for this remote. Add * the remote to the results, and the ref to its * @supported_ref_to_checksum. */ - g_debug ("Resolved ref (%s, %s) to remote ‘%s’.", - refs[j]->collection_id, refs[j]->ref_name, remote_name); + g_debug ("Resolved ref (%s, %s) to remote ‘%s’.", refs[j]->collection_id, + refs[j]->ref_name, remote_name); resolved_a_ref = TRUE; supported_ref_to_checksum = g_hash_table_lookup (repo_name_to_refs, remote_name); if (supported_ref_to_checksum == NULL) { - supported_ref_to_checksum = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - NULL, g_free); - g_hash_table_insert (repo_name_to_refs, (gpointer) remote_name, supported_ref_to_checksum /* transfer */); + supported_ref_to_checksum = g_hash_table_new_full ( + ostree_collection_ref_hash, ostree_collection_ref_equal, NULL, g_free); + g_hash_table_insert (repo_name_to_refs, (gpointer)remote_name, + supported_ref_to_checksum /* transfer */); } - g_hash_table_insert (supported_ref_to_checksum, - (gpointer) refs[j], g_strdup (checksum)); + g_hash_table_insert (supported_ref_to_checksum, (gpointer)refs[j], + g_strdup (checksum)); } } if (!resolved_a_ref) - g_debug ("Ignoring remote ‘%s’ due to it not advertising any of the requested refs.", remote_name); + g_debug ("Ignoring remote ‘%s’ due to it not advertising any of the requested refs.", + remote_name); } /* Aggregate the results. */ g_hash_table_iter_init (&iter, repo_name_to_refs); - while (g_hash_table_iter_next (&iter, (gpointer *) &remote_name, (gpointer *) &supported_ref_to_checksum)) + while (g_hash_table_iter_next (&iter, (gpointer *)&remote_name, + (gpointer *)&supported_ref_to_checksum)) { - g_autoptr(GError) local_error = NULL; - g_autoptr(OstreeRemote) remote = NULL; + g_autoptr (GError) local_error = NULL; + g_autoptr (OstreeRemote) remote = NULL; /* We don’t know what last-modified timestamp the remote has without * making expensive HTTP queries, so leave that information blank. We @@ -185,23 +184,22 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find remote = _ostree_repo_get_remote_inherited (parent_repo, remote_name, &local_error); if (remote == NULL) { - g_debug ("Configuration for remote ‘%s’ could not be found. Ignoring.", - remote_name); + g_debug ("Configuration for remote ‘%s’ could not be found. Ignoring.", remote_name); continue; } - g_ptr_array_add (results, ostree_repo_finder_result_new (remote, finder, priority, supported_ref_to_checksum, NULL, 0)); + g_ptr_array_add (results, ostree_repo_finder_result_new (remote, finder, priority, + supported_ref_to_checksum, NULL, 0)); } g_ptr_array_sort (results, results_compare_cb); - g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify)g_ptr_array_unref); } static GPtrArray * -ostree_repo_finder_config_resolve_finish (OstreeRepoFinder *finder, - GAsyncResult *result, - GError **error) +ostree_repo_finder_config_resolve_finish (OstreeRepoFinder *finder, GAsyncResult *result, + GError **error) { g_return_val_if_fail (g_task_is_valid (result, finder), NULL); return g_task_propagate_pointer (G_TASK (result), error); diff --git a/src/libostree/ostree-repo-finder-config.h b/src/libostree/ostree-repo-finder-config.h index 2ba1041..4570e5f 100644 --- a/src/libostree/ostree-repo-finder-config.h +++ b/src/libostree/ostree-repo-finder-config.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include "ostree-repo-finder.h" #include "ostree-types.h" @@ -35,17 +35,30 @@ G_BEGIN_DECLS /* Manually expanded version of the following, omitting autoptr support (for GLib < 2.44): _OSTREE_PUBLIC -G_DECLARE_FINAL_TYPE (OstreeRepoFinderConfig, ostree_repo_finder_config, OSTREE, REPO_FINDER_CONFIG, GObject) */ +G_DECLARE_FINAL_TYPE (OstreeRepoFinderConfig, ostree_repo_finder_config, OSTREE, +REPO_FINDER_CONFIG, GObject) */ _OSTREE_PUBLIC GType ostree_repo_finder_config_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeRepoFinderConfig OstreeRepoFinderConfig; -typedef struct { GObjectClass parent_class; } OstreeRepoFinderConfigClass; +typedef struct +{ + GObjectClass parent_class; +} OstreeRepoFinderConfigClass; -static inline OstreeRepoFinderConfig *OSTREE_REPO_FINDER_CONFIG (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_config_get_type (), OstreeRepoFinderConfig); } -static inline gboolean OSTREE_IS_REPO_FINDER_CONFIG (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_config_get_type ()); } +static inline OstreeRepoFinderConfig * +OSTREE_REPO_FINDER_CONFIG (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_config_get_type (), + OstreeRepoFinderConfig); +} +static inline gboolean +OSTREE_IS_REPO_FINDER_CONFIG (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_config_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS _OSTREE_PUBLIC diff --git a/src/libostree/ostree-repo-finder-mount.c b/src/libostree/ostree-repo-finder-mount.c index 628c53c..3f92b27 100644 --- a/src/libostree/ostree-repo-finder-mount.c +++ b/src/libostree/ostree-repo-finder-mount.c @@ -24,16 +24,16 @@ #include #include -#include #include +#include #include #include #include "ostree-autocleanups.h" #include "ostree-remote-private.h" -#include "ostree-repo-private.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-mount.h" +#include "ostree-repo-finder.h" +#include "ostree-repo-private.h" /** * SECTION:ostree-repo-finder-mount @@ -69,7 +69,7 @@ * Since: 2018.6 */ -typedef GList/**/ ObjectList; +typedef GList /**/ ObjectList; static void object_list_free (ObjectList *list) @@ -85,16 +85,17 @@ struct _OstreeRepoFinderMount { GObject parent_instance; - GVolumeMonitor *monitor; /* owned */ + GVolumeMonitor *monitor; /* owned */ }; G_DEFINE_TYPE_WITH_CODE (OstreeRepoFinderMount, ostree_repo_finder_mount, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, ostree_repo_finder_mount_iface_init)) + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, + ostree_repo_finder_mount_iface_init)) typedef struct { gchar *uri; - OstreeRemote *keyring_remote; /* (owned) */ + OstreeRemote *keyring_remote; /* (owned) */ } UriAndKeyring; static void @@ -108,10 +109,9 @@ uri_and_keyring_free (UriAndKeyring *data) G_DEFINE_AUTOPTR_CLEANUP_FUNC (UriAndKeyring, uri_and_keyring_free) static UriAndKeyring * -uri_and_keyring_new (const gchar *uri, - OstreeRemote *keyring_remote) +uri_and_keyring_new (const gchar *uri, OstreeRemote *keyring_remote) { - g_autoptr(UriAndKeyring) data = NULL; + g_autoptr (UriAndKeyring) data = NULL; data = g_new0 (UriAndKeyring, 1); data->uri = g_strdup (uri); @@ -129,13 +129,12 @@ uri_and_keyring_hash (gconstpointer key) } static gboolean -uri_and_keyring_equal (gconstpointer a, - gconstpointer b) +uri_and_keyring_equal (gconstpointer a, gconstpointer b) { const UriAndKeyring *_a = a, *_b = b; - return (g_str_equal (_a->uri, _b->uri) && - g_str_equal (_a->keyring_remote->keyring, _b->keyring_remote->keyring)); + return (g_str_equal (_a->uri, _b->uri) + && g_str_equal (_a->keyring_remote->keyring, _b->keyring_remote->keyring)); } /* This must return a valid remote name (suitable for use in a refspec). */ @@ -143,7 +142,8 @@ static gchar * uri_and_keyring_to_name (UriAndKeyring *data) { g_autofree gchar *escaped_uri = g_uri_escape_string (data->uri, NULL, FALSE); - g_autofree gchar *escaped_keyring = g_uri_escape_string (data->keyring_remote->keyring, NULL, FALSE); + g_autofree gchar *escaped_keyring + = g_uri_escape_string (data->keyring_remote->keyring, NULL, FALSE); /* FIXME: Need a better separator than `_`, since it’s not escaped in the input. */ g_autofree gchar *out = g_strdup_printf ("%s_%s", escaped_uri, escaped_keyring); @@ -160,20 +160,19 @@ uri_and_keyring_to_name (UriAndKeyring *data) } static gint -results_compare_cb (gconstpointer a, - gconstpointer b) +results_compare_cb (gconstpointer a, gconstpointer b) { - const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **) a); - const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **) b); + const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **)a); + const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **)b); return ostree_repo_finder_result_compare (result_a, result_b); } typedef struct { - char *ordering_name; /* (owned) */ - OstreeRepo *repo; /* (owned) */ - GHashTable *refs; /* (owned) (element-type OstreeCollectionRef utf8) */ + char *ordering_name; /* (owned) */ + OstreeRepo *repo; /* (owned) */ + GHashTable *refs; /* (owned) (element-type OstreeCollectionRef utf8) */ } RepoAndRefs; static void @@ -185,8 +184,7 @@ repo_and_refs_clear (RepoAndRefs *data) } static gint -repo_and_refs_compare (gconstpointer a, - gconstpointer b) +repo_and_refs_compare (gconstpointer a, gconstpointer b) { const RepoAndRefs *_a = a; const RepoAndRefs *_b = b; @@ -198,23 +196,17 @@ repo_and_refs_compare (gconstpointer a, * to the @parent_repo, and can be opened. If so, return it as @out_repo and * all its collection–refs as @out_refs, to be added into the results. */ static gboolean -scan_repo (int dfd, - const char *path, - const char *mount_name, - const struct stat *mount_root_stbuf, - OstreeRepo *parent_repo, - OstreeRepo **out_repo, - GHashTable **out_refs, - GCancellable *cancellable, - GError **error) +scan_repo (int dfd, const char *path, const char *mount_name, const struct stat *mount_root_stbuf, + OstreeRepo *parent_repo, OstreeRepo **out_repo, GHashTable **out_refs, + GCancellable *cancellable, GError **error) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_open_at (dfd, path, cancellable, &local_error); + g_autoptr (OstreeRepo) repo = ostree_repo_open_at (dfd, path, cancellable, &local_error); if (repo == NULL) { - g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as it could not be opened: %s", - path, mount_name, local_error->message); + g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as it could not be opened: %s", path, + mount_name, local_error->message); g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; } @@ -224,8 +216,8 @@ scan_repo (int dfd, if (!glnx_fstat (repo_dfd, &stbuf, &local_error)) { - g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as querying its info failed: %s", - path, mount_name, local_error->message); + g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as querying its info failed: %s", path, + mount_name, local_error->message); g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; } @@ -234,29 +226,30 @@ scan_repo (int dfd, * allow ref symlinks to point somewhere outside of the mounted volume. */ if (stbuf.st_dev != mount_root_stbuf->st_dev) { - g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as it’s on a different file system from the mount", + g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as it’s on a different file system from " + "the mount", path, mount_name); return glnx_throw (error, "Repository is on a different file system from the mount"); } /* Exclude repositories which resolve to @parent_repo. */ - if (stbuf.st_dev == parent_repo->device && - stbuf.st_ino == parent_repo->inode) + if (stbuf.st_dev == parent_repo->device && stbuf.st_ino == parent_repo->inode) { - g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as it is the same as the one we are resolving", - path, mount_name); + g_debug ( + "Ignoring repository ‘%s’ on mount ‘%s’ as it is the same as the one we are resolving", + path, mount_name); return glnx_throw (error, "Repository is the same as the one we are resolving"); } /* List the repo’s refs and return them. */ - g_autoptr(GHashTable) repo_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) repo_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ if (!ostree_repo_list_collection_refs (repo, NULL, &repo_refs, - OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, - cancellable, &local_error)) + OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, cancellable, + &local_error)) { - g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as its refs could not be listed: %s", - path, mount_name, local_error->message); + g_debug ("Ignoring repository ‘%s’ on mount ‘%s’ as its refs could not be listed: %s", path, + mount_name, local_error->message); g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; } @@ -270,54 +263,43 @@ scan_repo (int dfd, } static void -scan_and_add_repo (int dfd, - const char *path, - gboolean sortable, - const char *mount_name, - const struct stat *mount_root_stbuf, - OstreeRepo *parent_repo, - GArray *inout_repos_refs, - GCancellable *cancellable) +scan_and_add_repo (int dfd, const char *path, gboolean sortable, const char *mount_name, + const struct stat *mount_root_stbuf, OstreeRepo *parent_repo, + GArray *inout_repos_refs, GCancellable *cancellable) { - g_autoptr(GHashTable) repo_refs = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GHashTable) repo_refs = NULL; + g_autoptr (OstreeRepo) repo = NULL; - if (scan_repo (dfd, path, - mount_name, mount_root_stbuf, - parent_repo, &repo, &repo_refs, cancellable, NULL)) + if (scan_repo (dfd, path, mount_name, mount_root_stbuf, parent_repo, &repo, &repo_refs, + cancellable, NULL)) { - RepoAndRefs val = { - sortable ? g_strdup (path) : NULL, - g_steal_pointer (&repo), - g_steal_pointer (&repo_refs) - }; + RepoAndRefs val = { sortable ? g_strdup (path) : NULL, g_steal_pointer (&repo), + g_steal_pointer (&repo_refs) }; g_array_append_val (inout_repos_refs, val); - g_debug ("%s: Adding repo ‘%s’ on mount ‘%s’ (%ssortable)", - G_STRFUNC, path, mount_name, sortable ? "" : "not "); + g_debug ("%s: Adding repo ‘%s’ on mount ‘%s’ (%ssortable)", G_STRFUNC, path, mount_name, + sortable ? "" : "not "); } } static void -ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finder, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finder, + const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { OstreeRepoFinderMount *self = OSTREE_REPO_FINDER_MOUNT (finder); - g_autoptr(GTask) task = NULL; - g_autoptr(ObjectList) mounts = NULL; - g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GTask) task = NULL; + g_autoptr (ObjectList) mounts = NULL; + g_autoptr (GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ GList *l; - const gint priority = 50; /* arbitrarily chosen */ + const gint priority = 50; /* arbitrarily chosen */ task = g_task_new (finder, cancellable, callback, user_data); g_task_set_source_tag (task, ostree_repo_finder_mount_resolve_async); mounts = g_volume_monitor_get_mounts (self->monitor); - results = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_repo_finder_result_free); + results = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_repo_finder_result_free); g_debug ("%s: Found %u mounts", G_STRFUNC, g_list_length (mounts)); @@ -325,16 +307,16 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde { GMount *mount = G_MOUNT (l->data); g_autofree gchar *mount_name = NULL; - g_autoptr(GFile) mount_root = NULL; + g_autoptr (GFile) mount_root = NULL; g_autofree gchar *mount_root_path = NULL; glnx_autofd int mount_root_dfd = -1; struct stat mount_root_stbuf; glnx_autofd int repos_dfd = -1; gsize i; - g_autoptr(GHashTable) repo_to_refs = NULL; /* (element-type UriAndKeyring GHashTable) */ - GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) repo_to_refs = NULL; /* (element-type UriAndKeyring GHashTable) */ + GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ GHashTableIter iter; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; mount_name = g_mount_get_name (mount); @@ -350,18 +332,19 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde if (!glnx_opendirat (AT_FDCWD, mount_root_path, TRUE, &mount_root_dfd, &local_error)) { - g_debug ("Ignoring mount ‘%s’ as ‘%s’ directory can’t be opened: %s", - mount_name, mount_root_path, local_error->message); + g_debug ("Ignoring mount ‘%s’ as ‘%s’ directory can’t be opened: %s", mount_name, + mount_root_path, local_error->message); continue; } #if GLIB_CHECK_VERSION(2, 55, 0) -G_GNUC_BEGIN_IGNORE_DEPRECATIONS /* remove once GLIB_VERSION_MAX_ALLOWED ≥ 2.56 */ - g_autoptr(GUnixMountEntry) mount_entry = g_unix_mount_at (mount_root_path, NULL); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS /* remove once GLIB_VERSION_MAX_ALLOWED ≥ 2.56 */ + g_autoptr (GUnixMountEntry) mount_entry + = g_unix_mount_at (mount_root_path, NULL); - if (mount_entry != NULL && - (g_unix_is_system_fs_type (g_unix_mount_get_fs_type (mount_entry)) || - g_unix_is_system_device_path (g_unix_mount_get_device_path (mount_entry)))) + if (mount_entry != NULL + && (g_unix_is_system_fs_type (g_unix_mount_get_fs_type (mount_entry)) + || g_unix_is_system_device_path (g_unix_mount_get_device_path (mount_entry)))) { g_debug ("Ignoring mount ‘%s’ as its file system type (%s) or device " "path (%s) indicate it’s a system mount.", @@ -369,16 +352,16 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS /* remove once GLIB_VERSION_MAX_ALLOWED ≥ 2. g_unix_mount_get_device_path (mount_entry)); continue; } -G_GNUC_END_IGNORE_DEPRECATIONS -#endif /* GLib 2.56.0 */ + G_GNUC_END_IGNORE_DEPRECATIONS +#endif /* GLib 2.56.0 */ /* stat() the mount root so we can later check whether the resolved * repositories for individual refs are on the same device (to avoid the * symlinks for them pointing outside the mount root). */ if (!glnx_fstat (mount_root_dfd, &mount_root_stbuf, &local_error)) { - g_debug ("Ignoring mount ‘%s’ as querying info of ‘%s’ failed: %s", - mount_name, mount_root_path, local_error->message); + g_debug ("Ignoring mount ‘%s’ as querying info of ‘%s’ failed: %s", mount_name, + mount_root_path, local_error->message); continue; } @@ -389,13 +372,13 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* List all the repositories in the repos.d directory. */ /* (element-type GHashTable (element-type OstreeCollectionRef utf8)) */ - g_autoptr(GArray) repos_refs = g_array_new (FALSE, TRUE, sizeof (RepoAndRefs)); - g_array_set_clear_func (repos_refs, (GDestroyNotify) repo_and_refs_clear); + g_autoptr (GArray) repos_refs = g_array_new (FALSE, TRUE, sizeof (RepoAndRefs)); + g_array_set_clear_func (repos_refs, (GDestroyNotify)repo_and_refs_clear); GLnxDirFdIterator repos_iter; - if (repos_dfd >= 0 && - !glnx_dirfd_iterator_init_at (repos_dfd, ".", TRUE, &repos_iter, &local_error)) + if (repos_dfd >= 0 + && !glnx_dirfd_iterator_init_at (repos_dfd, ".", TRUE, &repos_iter, &local_error)) { g_debug ("Error iterating over ‘%s/.ostree/repos.d’ directory in mount ‘%s’: %s", mount_root_path, mount_name, local_error->message); @@ -408,7 +391,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS { struct dirent *repo_dent; - if (!glnx_dirfd_iterator_next_dent (&repos_iter, &repo_dent, cancellable, &local_error)) + if (!glnx_dirfd_iterator_next_dent (&repos_iter, &repo_dent, cancellable, + &local_error)) { g_debug ("Error iterating over ‘%s/.ostree/repos.d’ directory in mount ‘%s’: %s", mount_root_path, mount_name, local_error->message); @@ -421,8 +405,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS break; /* Grab the set of collection–refs from the repo if we can open it. */ - scan_and_add_repo (repos_dfd, repo_dent->d_name, TRUE, - mount_name, &mount_root_stbuf, + scan_and_add_repo (repos_dfd, repo_dent->d_name, TRUE, mount_name, &mount_root_stbuf, parent_repo, repos_refs, cancellable); } } @@ -433,30 +416,28 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* Also check the well-known special-case directories in the mount. * Add them after sorting, so they’re always last. * NOTE: If you change these, update the man page. */ - const gchar * const well_known_repos[] = - { - ".ostree/repo", - "ostree/repo", - "var/lib/flatpak/repo", - }; + const gchar *const well_known_repos[] = { + ".ostree/repo", + "ostree/repo", + "var/lib/flatpak/repo", + }; for (i = 0; i < G_N_ELEMENTS (well_known_repos); i++) - scan_and_add_repo (mount_root_dfd, well_known_repos[i], FALSE, - mount_name, &mount_root_stbuf, - parent_repo, repos_refs, cancellable); + scan_and_add_repo (mount_root_dfd, well_known_repos[i], FALSE, mount_name, + &mount_root_stbuf, parent_repo, repos_refs, cancellable); /* Check whether a subdirectory exists for any of the @refs we’re looking * for. If so, and it’s a symbolic link, dereference it so multiple links * to the same repository (containing multiple refs) are coalesced. * Otherwise, include it as a result by itself. */ repo_to_refs = g_hash_table_new_full (uri_and_keyring_hash, uri_and_keyring_equal, - (GDestroyNotify) uri_and_keyring_free, (GDestroyNotify) g_hash_table_unref); + (GDestroyNotify)uri_and_keyring_free, + (GDestroyNotify)g_hash_table_unref); for (i = 0; refs[i] != NULL; i++) { const OstreeCollectionRef *ref = refs[i]; g_autofree gchar *resolved_repo_uri = NULL; - g_autoptr(UriAndKeyring) resolved_repo = NULL; for (gsize j = 0; j < repos_refs->len; j++) { @@ -464,27 +445,29 @@ G_GNUC_END_IGNORE_DEPRECATIONS OstreeRepo *repo = repo_and_refs->repo; GHashTable *repo_refs = repo_and_refs->refs; g_autofree char *repo_path = g_file_get_path (ostree_repo_get_path (repo)); - g_autoptr(OstreeRemote) keyring_remote = NULL; + g_autoptr (OstreeRemote) keyring_remote = NULL; const gchar *checksum = g_hash_table_lookup (repo_refs, ref); if (checksum == NULL) { - g_debug ("Ignoring repository ‘%s’ when looking for ref (%s, %s) on mount ‘%s’ as it doesn’t contain the ref.", + g_debug ("Ignoring repository ‘%s’ when looking for ref (%s, %s) on mount ‘%s’ " + "as it doesn’t contain the ref.", repo_path, ref->collection_id, ref->ref_name, mount_name); g_clear_error (&local_error); continue; } /* Finally, look up the GPG keyring for this ref. */ - keyring_remote = ostree_repo_resolve_keyring_for_collection (parent_repo, - ref->collection_id, - cancellable, &local_error); + keyring_remote = ostree_repo_resolve_keyring_for_collection ( + parent_repo, ref->collection_id, cancellable, &local_error); if (keyring_remote == NULL) { - g_debug ("Ignoring repository ‘%s’ when looking for ref (%s, %s) on mount ‘%s’ due to missing keyring: %s", - repo_path, ref->collection_id, ref->ref_name, mount_name, local_error->message); + g_debug ("Ignoring repository ‘%s’ when looking for ref (%s, %s) on mount ‘%s’ " + "due to missing keyring: %s", + repo_path, ref->collection_id, ref->ref_name, mount_name, + local_error->message); g_clear_error (&local_error); continue; } @@ -495,23 +478,25 @@ G_GNUC_END_IGNORE_DEPRECATIONS * to deduplicate the results. */ g_autofree char *canonical_repo_path = realpath (repo_path, NULL); resolved_repo_uri = g_strconcat ("file://", canonical_repo_path, NULL); - g_debug ("Resolved ref (%s, %s) on mount ‘%s’ to repo URI ‘%s’ with keyring ‘%s’ from remote ‘%s’.", + g_debug ("Resolved ref (%s, %s) on mount ‘%s’ to repo URI ‘%s’ with keyring ‘%s’ " + "from remote ‘%s’.", ref->collection_id, ref->ref_name, mount_name, resolved_repo_uri, keyring_remote->keyring, keyring_remote->name); - resolved_repo = uri_and_keyring_new (resolved_repo_uri, keyring_remote); + g_autoptr (UriAndKeyring) resolved_repo + = uri_and_keyring_new (resolved_repo_uri, keyring_remote); supported_ref_to_checksum = g_hash_table_lookup (repo_to_refs, resolved_repo); if (supported_ref_to_checksum == NULL) { - supported_ref_to_checksum = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - NULL, g_free); - g_hash_table_insert (repo_to_refs, g_steal_pointer (&resolved_repo), supported_ref_to_checksum /* transfer */); + supported_ref_to_checksum = g_hash_table_new_full ( + ostree_collection_ref_hash, ostree_collection_ref_equal, NULL, g_free); + g_hash_table_insert (repo_to_refs, g_steal_pointer (&resolved_repo), + supported_ref_to_checksum /* transfer */); } - g_hash_table_insert (supported_ref_to_checksum, (gpointer) ref, g_strdup (checksum)); + g_hash_table_insert (supported_ref_to_checksum, (gpointer)ref, g_strdup (checksum)); /* We’ve found a result for this collection–ref. No point in checking * the other repos on the mount, since pulling in parallel from them won’t help. */ @@ -523,9 +508,10 @@ G_GNUC_END_IGNORE_DEPRECATIONS g_hash_table_iter_init (&iter, repo_to_refs); UriAndKeyring *repo; - while (g_hash_table_iter_next (&iter, (gpointer *) &repo, (gpointer *) &supported_ref_to_checksum)) + while ( + g_hash_table_iter_next (&iter, (gpointer *)&repo, (gpointer *)&supported_ref_to_checksum)) { - g_autoptr(OstreeRemote) remote = NULL; + g_autoptr (OstreeRemote) remote = NULL; /* Build an #OstreeRemote. Use the escaped URI, since remote->name * is used in file paths, so needs to not contain special characters. */ @@ -544,19 +530,20 @@ G_GNUC_END_IGNORE_DEPRECATIONS * the code in ostree_repo_pull_from_remotes_async() will be able to * check it just as quickly as we can here; so don’t duplicate the * code. */ - g_ptr_array_add (results, ostree_repo_finder_result_new (remote, finder, priority, supported_ref_to_checksum, NULL, 0)); + g_ptr_array_add (results, + ostree_repo_finder_result_new (remote, finder, priority, + supported_ref_to_checksum, NULL, 0)); } } g_ptr_array_sort (results, results_compare_cb); - g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify)g_ptr_array_unref); } static GPtrArray * -ostree_repo_finder_mount_resolve_finish (OstreeRepoFinder *self, - GAsyncResult *result, - GError **error) +ostree_repo_finder_mount_resolve_finish (OstreeRepoFinder *self, GAsyncResult *result, + GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), NULL); return g_task_propagate_pointer (G_TASK (result), error); @@ -585,14 +572,12 @@ typedef enum } OstreeRepoFinderMountProperty; static void -ostree_repo_finder_mount_get_property (GObject *object, - guint property_id, - GValue *value, +ostree_repo_finder_mount_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { OstreeRepoFinderMount *self = OSTREE_REPO_FINDER_MOUNT (object); - switch ((OstreeRepoFinderMountProperty) property_id) + switch ((OstreeRepoFinderMountProperty)property_id) { case PROP_MONITOR: g_value_set_object (value, self->monitor); @@ -603,14 +588,12 @@ ostree_repo_finder_mount_get_property (GObject *object, } static void -ostree_repo_finder_mount_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) +ostree_repo_finder_mount_set_property (GObject *object, guint property_id, const GValue *value, + GParamSpec *pspec) { OstreeRepoFinderMount *self = OSTREE_REPO_FINDER_MOUNT (object); - switch ((OstreeRepoFinderMountProperty) property_id) + switch ((OstreeRepoFinderMountProperty)property_id) { case PROP_MONITOR: /* Construct-only. */ @@ -649,16 +632,14 @@ ostree_repo_finder_mount_class_init (OstreeRepoFinderMountClass *klass) * * Since: 2018.6 */ - g_object_class_install_property (object_class, PROP_MONITOR, - g_param_spec_object ("monitor", - "Volume Monitor", - "Volume monitor to use " - "to look up mounted " - "volumes when queried.", - G_TYPE_VOLUME_MONITOR, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); + g_object_class_install_property ( + object_class, PROP_MONITOR, + g_param_spec_object ("monitor", "Volume Monitor", + "Volume monitor to use " + "to look up mounted " + "volumes when queried.", + G_TYPE_VOLUME_MONITOR, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -685,7 +666,5 @@ ostree_repo_finder_mount_new (GVolumeMonitor *monitor) { g_return_val_if_fail (monitor == NULL || G_IS_VOLUME_MONITOR (monitor), NULL); - return g_object_new (OSTREE_TYPE_REPO_FINDER_MOUNT, - "monitor", monitor, - NULL); + return g_object_new (OSTREE_TYPE_REPO_FINDER_MOUNT, "monitor", monitor, NULL); } diff --git a/src/libostree/ostree-repo-finder-mount.h b/src/libostree/ostree-repo-finder-mount.h index d040338..1ba7851 100644 --- a/src/libostree/ostree-repo-finder-mount.h +++ b/src/libostree/ostree-repo-finder-mount.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include "ostree-repo-finder.h" #include "ostree-types.h" @@ -35,17 +35,30 @@ G_BEGIN_DECLS /* Manually expanded version of the following, omitting autoptr support (for GLib < 2.44): _OSTREE_PUBLIC -G_DECLARE_FINAL_TYPE (OstreeRepoFinderMount, ostree_repo_finder_mount, OSTREE, REPO_FINDER_MOUNT, GObject) */ +G_DECLARE_FINAL_TYPE (OstreeRepoFinderMount, ostree_repo_finder_mount, OSTREE, REPO_FINDER_MOUNT, +GObject) */ _OSTREE_PUBLIC GType ostree_repo_finder_mount_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeRepoFinderMount OstreeRepoFinderMount; -typedef struct { GObjectClass parent_class; } OstreeRepoFinderMountClass; +typedef struct +{ + GObjectClass parent_class; +} OstreeRepoFinderMountClass; -static inline OstreeRepoFinderMount *OSTREE_REPO_FINDER_MOUNT (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_mount_get_type (), OstreeRepoFinderMount); } -static inline gboolean OSTREE_IS_REPO_FINDER_MOUNT (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_mount_get_type ()); } +static inline OstreeRepoFinderMount * +OSTREE_REPO_FINDER_MOUNT (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_mount_get_type (), + OstreeRepoFinderMount); +} +static inline gboolean +OSTREE_IS_REPO_FINDER_MOUNT (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_mount_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS _OSTREE_PUBLIC diff --git a/src/libostree/ostree-repo-finder-override.c b/src/libostree/ostree-repo-finder-override.c index c2af9fc..29308a9 100644 --- a/src/libostree/ostree-repo-finder-override.c +++ b/src/libostree/ostree-repo-finder-override.c @@ -24,16 +24,16 @@ #include #include -#include #include +#include #include #include "ostree-autocleanups.h" #include "ostree-remote-private.h" -#include "ostree-repo.h" -#include "ostree-repo-private.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-override.h" +#include "ostree-repo-finder.h" +#include "ostree-repo-private.h" +#include "ostree-repo.h" /** * SECTION:ostree-repo-finder-override @@ -68,26 +68,25 @@ struct _OstreeRepoFinderOverride { GObject parent_instance; - GPtrArray *override_uris; /* (owned) (element-type utf8) */ + GPtrArray *override_uris; /* (owned) (element-type utf8) */ }; G_DEFINE_TYPE_WITH_CODE (OstreeRepoFinderOverride, ostree_repo_finder_override, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, ostree_repo_finder_override_iface_init)) + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_REPO_FINDER, + ostree_repo_finder_override_iface_init)) static gint -results_compare_cb (gconstpointer a, - gconstpointer b) +results_compare_cb (gconstpointer a, gconstpointer b) { - const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **) a); - const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **) b); + const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **)a); + const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **)b); return ostree_repo_finder_result_compare (result_a, result_b); } /* This must return a valid remote name (suitable for use in a refspec). */ static gchar * -uri_and_keyring_to_name (const gchar *uri, - const gchar *keyring) +uri_and_keyring_to_name (const gchar *uri, const gchar *keyring) { g_autofree gchar *escaped_uri = g_uri_escape_string (uri, NULL, FALSE); g_autofree gchar *escaped_keyring = g_uri_escape_string (keyring, NULL, FALSE); @@ -109,22 +108,17 @@ uri_and_keyring_to_name (const gchar *uri, /* Version of ostree_repo_remote_list_collection_refs() which takes an * #OstreeRemote. */ static gboolean -repo_remote_list_collection_refs (OstreeRepo *repo, - const gchar *remote_uri, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error) +repo_remote_list_collection_refs (OstreeRepo *repo, const gchar *remote_uri, + GHashTable **out_all_refs, GCancellable *cancellable, + GError **error) { g_autofree gchar *name = uri_and_keyring_to_name (remote_uri, ""); - g_autoptr(OstreeRemote) remote = ostree_remote_new (name); + g_autoptr (OstreeRemote) remote = ostree_remote_new (name); g_key_file_set_string (remote->options, remote->group, "url", remote_uri); gboolean remote_already_existed = _ostree_repo_add_remote (repo, remote); - gboolean success = ostree_repo_remote_list_collection_refs (repo, - remote->name, - out_all_refs, - cancellable, - error); + gboolean success = ostree_repo_remote_list_collection_refs (repo, remote->name, out_all_refs, + cancellable, error); if (!remote_already_existed) _ostree_repo_remove_remote (repo, remote); @@ -133,77 +127,73 @@ repo_remote_list_collection_refs (OstreeRepo *repo, } static void -ostree_repo_finder_override_resolve_async (OstreeRepoFinder *finder, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_finder_override_resolve_async (OstreeRepoFinder *finder, + const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { OstreeRepoFinderOverride *self = OSTREE_REPO_FINDER_OVERRIDE (finder); - g_autoptr(GTask) task = NULL; - g_autoptr(GPtrArray) results = NULL; - const gint priority = 20; /* arbitrarily chosen; higher priority than the others */ + g_autoptr (GTask) task = NULL; + g_autoptr (GPtrArray) results = NULL; + const gint priority = 20; /* arbitrarily chosen; higher priority than the others */ gsize i, j; - g_autoptr(GHashTable) repo_remote_to_refs = NULL; /* (element-type OstreeRemote GHashTable) */ - GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) repo_remote_to_refs = NULL; /* (element-type OstreeRemote GHashTable) */ + GHashTable *supported_ref_to_checksum; /* (element-type OstreeCollectionRef utf8) */ GHashTableIter iter; const gchar *remote_uri; task = g_task_new (finder, cancellable, callback, user_data); g_task_set_source_tag (task, ostree_repo_finder_override_resolve_async); - results = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_repo_finder_result_free); - repo_remote_to_refs = g_hash_table_new_full (g_direct_hash, g_direct_equal, - (GDestroyNotify) ostree_remote_unref, - (GDestroyNotify) g_hash_table_unref); + results = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_repo_finder_result_free); + repo_remote_to_refs + = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify)ostree_remote_unref, + (GDestroyNotify)g_hash_table_unref); g_debug ("%s: Checking %u overrides", G_STRFUNC, self->override_uris->len); for (i = 0; i < self->override_uris->len; i++) { - g_autoptr(GError) local_error = NULL; - g_autoptr(GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GError) local_error = NULL; + g_autoptr (GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ const gchar *checksum; gboolean resolved_a_ref = FALSE; remote_uri = self->override_uris->pdata[i]; - if (!repo_remote_list_collection_refs (parent_repo, remote_uri, - &remote_refs, cancellable, + if (!repo_remote_list_collection_refs (parent_repo, remote_uri, &remote_refs, cancellable, &local_error)) { - g_debug ("Ignoring remote ‘%s’ due to error loading its refs: %s", - remote_uri, local_error->message); + g_debug ("Ignoring remote ‘%s’ due to error loading its refs: %s", remote_uri, + local_error->message); g_clear_error (&local_error); continue; } for (j = 0; refs[j] != NULL; j++) { - g_autoptr(OstreeRemote) keyring_remote = NULL; + g_autoptr (OstreeRemote) keyring_remote = NULL; /* Look up the GPG keyring for this ref. */ - keyring_remote = ostree_repo_resolve_keyring_for_collection (parent_repo, - refs[j]->collection_id, - cancellable, &local_error); + keyring_remote = ostree_repo_resolve_keyring_for_collection ( + parent_repo, refs[j]->collection_id, cancellable, &local_error); if (keyring_remote == NULL) { - g_debug ("Ignoring ref (%s, %s) due to missing keyring: %s", - refs[j]->collection_id, refs[j]->ref_name, local_error->message); + g_debug ("Ignoring ref (%s, %s) due to missing keyring: %s", refs[j]->collection_id, + refs[j]->ref_name, local_error->message); g_clear_error (&local_error); continue; } - if (g_hash_table_lookup_extended (remote_refs, refs[j], NULL, (gpointer *) &checksum)) + if (g_hash_table_lookup_extended (remote_refs, refs[j], NULL, (gpointer *)&checksum)) { - g_autoptr(OstreeRemote) remote = NULL; + g_autoptr (OstreeRemote) remote = NULL; /* The requested ref is listed in the refs for this remote. Add * the remote to the results, and the ref to its * @supported_ref_to_checksum. */ - g_debug ("Resolved ref (%s, %s) to remote ‘%s’.", - refs[j]->collection_id, refs[j]->ref_name, remote_uri); + g_debug ("Resolved ref (%s, %s) to remote ‘%s’.", refs[j]->collection_id, + refs[j]->ref_name, remote_uri); resolved_a_ref = TRUE; /* Build an #OstreeRemote. Use the escaped URI, since remote->name @@ -220,14 +210,14 @@ ostree_repo_finder_override_resolve_async (OstreeRepoFinder *fi if (supported_ref_to_checksum == NULL) { - supported_ref_to_checksum = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - NULL, g_free); - g_hash_table_insert (repo_remote_to_refs, ostree_remote_ref (remote), supported_ref_to_checksum /* transfer */); + supported_ref_to_checksum = g_hash_table_new_full ( + ostree_collection_ref_hash, ostree_collection_ref_equal, NULL, g_free); + g_hash_table_insert (repo_remote_to_refs, ostree_remote_ref (remote), + supported_ref_to_checksum /* transfer */); } - g_hash_table_insert (supported_ref_to_checksum, - (gpointer) refs[j], g_strdup (checksum)); + g_hash_table_insert (supported_ref_to_checksum, (gpointer)refs[j], + g_strdup (checksum)); } } @@ -240,18 +230,19 @@ ostree_repo_finder_override_resolve_async (OstreeRepoFinder *fi g_hash_table_iter_init (&iter, repo_remote_to_refs); OstreeRemote *remote; - while (g_hash_table_iter_next (&iter, (gpointer *) &remote, (gpointer *) &supported_ref_to_checksum)) - g_ptr_array_add (results, ostree_repo_finder_result_new (remote, finder, priority, supported_ref_to_checksum, NULL, 0)); + while ( + g_hash_table_iter_next (&iter, (gpointer *)&remote, (gpointer *)&supported_ref_to_checksum)) + g_ptr_array_add (results, ostree_repo_finder_result_new (remote, finder, priority, + supported_ref_to_checksum, NULL, 0)); g_ptr_array_sort (results, results_compare_cb); - g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify)g_ptr_array_unref); } static GPtrArray * -ostree_repo_finder_override_resolve_finish (OstreeRepoFinder *finder, - GAsyncResult *result, - GError **error) +ostree_repo_finder_override_resolve_finish (OstreeRepoFinder *finder, GAsyncResult *result, + GError **error) { g_return_val_if_fail (g_task_is_valid (result, finder), NULL); return g_task_propagate_pointer (G_TASK (result), error); @@ -260,7 +251,7 @@ ostree_repo_finder_override_resolve_finish (OstreeRepoFinder *finder, static void ostree_repo_finder_override_init (OstreeRepoFinderOverride *self) { - self->override_uris = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); + self->override_uris = g_ptr_array_new_with_free_func ((GDestroyNotify)g_free); } static void @@ -312,8 +303,7 @@ ostree_repo_finder_override_new (void) * Since: 2018.6 */ void -ostree_repo_finder_override_add_uri (OstreeRepoFinderOverride *self, - const gchar *uri) +ostree_repo_finder_override_add_uri (OstreeRepoFinderOverride *self, const gchar *uri) { g_return_if_fail (OSTREE_IS_REPO_FINDER_OVERRIDE (self)); g_return_if_fail (uri != NULL); diff --git a/src/libostree/ostree-repo-finder-override.h b/src/libostree/ostree-repo-finder-override.h index 1e18a8f..978dc50 100644 --- a/src/libostree/ostree-repo-finder-override.h +++ b/src/libostree/ostree-repo-finder-override.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include "ostree-repo-finder.h" #include "ostree-types.h" @@ -35,24 +35,36 @@ G_BEGIN_DECLS /* Manually expanded version of the following, omitting autoptr support (for GLib < 2.44): _OSTREE_PUBLIC -G_DECLARE_FINAL_TYPE (OstreeRepoFinderOverride, ostree_repo_finder_override, OSTREE, REPO_FINDER_OVERRIDE, GObject) */ +G_DECLARE_FINAL_TYPE (OstreeRepoFinderOverride, ostree_repo_finder_override, OSTREE, +REPO_FINDER_OVERRIDE, GObject) */ _OSTREE_PUBLIC GType ostree_repo_finder_override_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeRepoFinderOverride OstreeRepoFinderOverride; -typedef struct { GObjectClass parent_class; } OstreeRepoFinderOverrideClass; +typedef struct +{ + GObjectClass parent_class; +} OstreeRepoFinderOverrideClass; -static inline OstreeRepoFinderOverride *OSTREE_REPO_FINDER_OVERRIDE (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_override_get_type (), OstreeRepoFinderOverride); } -static inline gboolean OSTREE_IS_REPO_FINDER_OVERRIDE (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_override_get_type ()); } +static inline OstreeRepoFinderOverride * +OSTREE_REPO_FINDER_OVERRIDE (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_override_get_type (), + OstreeRepoFinderOverride); +} +static inline gboolean +OSTREE_IS_REPO_FINDER_OVERRIDE (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_override_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS _OSTREE_PUBLIC OstreeRepoFinderOverride *ostree_repo_finder_override_new (void); _OSTREE_PUBLIC -void ostree_repo_finder_override_add_uri (OstreeRepoFinderOverride *self, - const gchar *uri); +void ostree_repo_finder_override_add_uri (OstreeRepoFinderOverride *self, const gchar *uri); G_END_DECLS diff --git a/src/libostree/ostree-repo-finder.c b/src/libostree/ostree-repo-finder.c index aff6d6c..2f1af1c 100644 --- a/src/libostree/ostree-repo-finder.c +++ b/src/libostree/ostree-repo-finder.c @@ -23,8 +23,8 @@ #include "config.h" #include -#include #include +#include #include #include "ostree-autocleanups.h" @@ -48,15 +48,14 @@ ostree_repo_finder_default_init (OstreeRepoFinderInterface *iface) static gboolean is_valid_collection_ref (const OstreeCollectionRef *ref) { - return (ref != NULL && - ostree_validate_rev (ref->ref_name, NULL) && - ostree_validate_collection_id (ref->collection_id, NULL)); + return (ref != NULL && ostree_validate_rev (ref->ref_name, NULL) + && ostree_validate_collection_id (ref->collection_id, NULL)); } /* Validate @refs is non-%NULL, non-empty, and contains only valid collection * and ref names. */ static gboolean -is_valid_collection_ref_array (const OstreeCollectionRef * const *refs) +is_valid_collection_ref_array (const OstreeCollectionRef *const *refs) { gsize i; @@ -86,7 +85,7 @@ is_valid_collection_ref_map (GHashTable *ref_to_checksum) g_hash_table_iter_init (&iter, ref_to_checksum); - while (g_hash_table_iter_next (&iter, (gpointer *) &ref, (gpointer *) &checksum)) + while (g_hash_table_iter_next (&iter, (gpointer *)&ref, (gpointer *)&checksum)) { g_assert (ref != NULL); g_assert (checksum != NULL); @@ -100,9 +99,7 @@ is_valid_collection_ref_map (GHashTable *ref_to_checksum) return TRUE; } -static void resolve_cb (GObject *obj, - GAsyncResult *result, - gpointer user_data); +static void resolve_cb (GObject *obj, GAsyncResult *result, gpointer user_data); /** * ostree_repo_finder_resolve_async: @@ -140,15 +137,14 @@ static void resolve_cb (GObject *obj, * Since: 2018.6 */ void -ostree_repo_finder_resolve_async (OstreeRepoFinder *self, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_finder_resolve_async (OstreeRepoFinder *self, const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = NULL; - OstreeRepoFinder *finders[2] = { NULL, }; + g_autoptr (GTask) task = NULL; + OstreeRepoFinder *finders[2] = { + NULL, + }; g_return_if_fail (OSTREE_IS_REPO_FINDER (self)); g_return_if_fail (is_valid_collection_ref_array (refs)); @@ -160,18 +156,16 @@ ostree_repo_finder_resolve_async (OstreeRepoFinder *self, finders[0] = self; - ostree_repo_finder_resolve_all_async (finders, refs, parent_repo, cancellable, - resolve_cb, g_steal_pointer (&task)); + ostree_repo_finder_resolve_all_async (finders, refs, parent_repo, cancellable, resolve_cb, + g_steal_pointer (&task)); } static void -resolve_cb (GObject *obj, - GAsyncResult *result, - gpointer user_data) +resolve_cb (GObject *obj, GAsyncResult *result, gpointer user_data) { - g_autoptr(GTask) task = NULL; - g_autoptr(GPtrArray) results = NULL; - g_autoptr(GError) local_error = NULL; + g_autoptr (GTask) task = NULL; + g_autoptr (GPtrArray) results = NULL; + g_autoptr (GError) local_error = NULL; task = G_TASK (user_data); @@ -182,7 +176,7 @@ resolve_cb (GObject *obj, if (local_error != NULL) g_task_return_error (task, g_steal_pointer (&local_error)); else - g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify)g_ptr_array_unref); } /** @@ -198,9 +192,7 @@ resolve_cb (GObject *obj, * Since: 2018.6 */ GPtrArray * -ostree_repo_finder_resolve_finish (OstreeRepoFinder *self, - GAsyncResult *result, - GError **error) +ostree_repo_finder_resolve_finish (OstreeRepoFinder *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (OSTREE_IS_REPO_FINDER (self), NULL); g_return_val_if_fail (g_task_is_valid (result, self), NULL); @@ -210,11 +202,10 @@ ostree_repo_finder_resolve_finish (OstreeRepoFinder *self, } static gint -sort_results_cb (gconstpointer a, - gconstpointer b) +sort_results_cb (gconstpointer a, gconstpointer b) { - const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **) a); - const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **) b); + const OstreeRepoFinderResult *result_a = *((const OstreeRepoFinderResult **)a); + const OstreeRepoFinderResult *result_b = *((const OstreeRepoFinderResult **)b); return ostree_repo_finder_result_compare (result_a, result_b); } @@ -235,9 +226,7 @@ resolve_all_data_free (ResolveAllData *data) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ResolveAllData, resolve_all_data_free) -static void resolve_all_cb (GObject *obj, - GAsyncResult *result, - gpointer user_data); +static void resolve_all_cb (GObject *obj, GAsyncResult *result, gpointer user_data); static void resolve_all_finished_one (GTask *task); /** @@ -256,18 +245,16 @@ static void resolve_all_finished_one (GTask *task); * Since: 2018.6 */ void -ostree_repo_finder_resolve_all_async (OstreeRepoFinder * const *finders, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_finder_resolve_all_async (OstreeRepoFinder *const *finders, + const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = NULL; - g_autoptr(ResolveAllData) data = NULL; + g_autoptr (GTask) task = NULL; + g_autoptr (ResolveAllData) data = NULL; gsize i; - g_autoptr(GString) refs_str = NULL; - g_autoptr(GString) finders_str = NULL; + g_autoptr (GString) refs_str = NULL; + g_autoptr (GString) finders_str = NULL; g_return_if_fail (finders != NULL && finders[0] != NULL); g_return_if_fail (is_valid_collection_ref_array (refs)); @@ -279,8 +266,7 @@ ostree_repo_finder_resolve_all_async (OstreeRepoFinder * const *finders { if (i != 0) g_string_append (refs_str, ", "); - g_string_append_printf (refs_str, "(%s, %s)", - refs[i]->collection_id, refs[i]->ref_name); + g_string_append_printf (refs_str, "(%s, %s)", refs[i]->collection_id, refs[i]->ref_name); } finders_str = g_string_new (""); @@ -291,16 +277,15 @@ ostree_repo_finder_resolve_all_async (OstreeRepoFinder * const *finders g_string_append (finders_str, g_type_name (G_TYPE_FROM_INSTANCE (finders[i]))); } - g_debug ("%s: Resolving refs [%s] with finders [%s]", G_STRFUNC, - refs_str->str, finders_str->str); + g_debug ("%s: Resolving refs [%s] with finders [%s]", G_STRFUNC, refs_str->str, finders_str->str); task = g_task_new (NULL, cancellable, callback, user_data); g_task_set_source_tag (task, ostree_repo_finder_resolve_all_async); data = g_new0 (ResolveAllData, 1); - data->n_finders_pending = 1; /* while setting up the loop */ - data->results = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_repo_finder_result_free); - g_task_set_task_data (task, data, (GDestroyNotify) resolve_all_data_free); + data->n_finders_pending = 1; /* while setting up the loop */ + data->results = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_repo_finder_result_free); + g_task_set_task_data (task, data, (GDestroyNotify)resolve_all_data_free); /* Start all the asynchronous queries in parallel. */ for (i = 0; finders[i] != NULL; i++) @@ -310,20 +295,20 @@ ostree_repo_finder_resolve_all_async (OstreeRepoFinder * const *finders iface = OSTREE_REPO_FINDER_GET_IFACE (finder); g_assert (iface->resolve_async != NULL); - iface->resolve_async (finder, refs, parent_repo, cancellable, resolve_all_cb, g_object_ref (task)); + iface->resolve_async (finder, refs, parent_repo, cancellable, resolve_all_cb, + g_object_ref (task)); data->n_finders_pending++; } resolve_all_finished_one (task); - data = NULL; /* passed to the GTask above */ + data = NULL; /* passed to the GTask above */ } /* Modifies both arrays in place. */ static void -array_concatenate_steal (GPtrArray *array, - GPtrArray *to_concatenate) /* (transfer full) */ +array_concatenate_steal (GPtrArray *array, GPtrArray *to_concatenate) /* (transfer full) */ { - g_autoptr(GPtrArray) array_to_concatenate = to_concatenate; + g_autoptr (GPtrArray) array_to_concatenate = to_concatenate; gsize i; for (i = 0; i < array_to_concatenate->len; i++) @@ -339,15 +324,13 @@ array_concatenate_steal (GPtrArray *array, } static void -resolve_all_cb (GObject *obj, - GAsyncResult *result, - gpointer user_data) +resolve_all_cb (GObject *obj, GAsyncResult *result, gpointer user_data) { OstreeRepoFinder *finder; OstreeRepoFinderInterface *iface; - g_autoptr(GTask) task = NULL; - g_autoptr(GPtrArray) results = NULL; - g_autoptr(GError) local_error = NULL; + g_autoptr (GTask) task = NULL; + g_autoptr (GPtrArray) results = NULL; + g_autoptr (GError) local_error = NULL; ResolveAllData *data; finder = OSTREE_REPO_FINDER (obj); @@ -379,7 +362,7 @@ resolve_all_finished_one (GTask *task) if (data->n_finders_pending == 0) { gsize i; - g_autoptr(GString) results_str = NULL; + g_autoptr (GString) results_str = NULL; g_ptr_array_sort (data->results, sort_results_cb); @@ -397,7 +380,8 @@ resolve_all_finished_one (GTask *task) g_debug ("%s: Finished, results: %s", G_STRFUNC, results_str->str); - g_task_return_pointer (task, g_steal_pointer (&data->results), (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_steal_pointer (&data->results), + (GDestroyNotify)g_ptr_array_unref); } } @@ -413,8 +397,7 @@ resolve_all_finished_one (GTask *task) * Since: 2018.6 */ GPtrArray * -ostree_repo_finder_resolve_all_finish (GAsyncResult *result, - GError **error) +ostree_repo_finder_resolve_all_finish (GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, NULL), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); @@ -448,14 +431,11 @@ G_DEFINE_BOXED_TYPE (OstreeRepoFinderResult, ostree_repo_finder_result, * Since: 2018.6 */ OstreeRepoFinderResult * -ostree_repo_finder_result_new (OstreeRemote *remote, - OstreeRepoFinder *finder, - gint priority, - GHashTable *ref_to_checksum, - GHashTable *ref_to_timestamp, - guint64 summary_last_modified) +ostree_repo_finder_result_new (OstreeRemote *remote, OstreeRepoFinder *finder, gint priority, + GHashTable *ref_to_checksum, GHashTable *ref_to_timestamp, + guint64 summary_last_modified) { - g_autoptr(OstreeRepoFinderResult) result = NULL; + g_autoptr (OstreeRepoFinderResult) result = NULL; g_return_val_if_fail (remote != NULL, NULL); g_return_val_if_fail (OSTREE_IS_REPO_FINDER (finder), NULL); @@ -486,9 +466,9 @@ ostree_repo_finder_result_dup (OstreeRepoFinderResult *result) { g_return_val_if_fail (result != NULL, NULL); - return ostree_repo_finder_result_new (result->remote, result->finder, - result->priority, result->ref_to_checksum, - result->ref_to_timestamp, result->summary_last_modified); + return ostree_repo_finder_result_new (result->remote, result->finder, result->priority, + result->ref_to_checksum, result->ref_to_timestamp, + result->summary_last_modified); } /** @@ -504,8 +484,7 @@ ostree_repo_finder_result_dup (OstreeRepoFinderResult *result) * Since: 2018.6 */ gint -ostree_repo_finder_result_compare (const OstreeRepoFinderResult *a, - const OstreeRepoFinderResult *b) +ostree_repo_finder_result_compare (const OstreeRepoFinderResult *a, const OstreeRepoFinderResult *b) { guint a_n_refs, b_n_refs; @@ -518,8 +497,8 @@ ostree_repo_finder_result_compare (const OstreeRepoFinderResult *a, if (a->priority != b->priority) return a->priority - b->priority; - if (a->summary_last_modified != 0 && b->summary_last_modified != 0 && - a->summary_last_modified != b->summary_last_modified) + if (a->summary_last_modified != 0 && b->summary_last_modified != 0 + && a->summary_last_modified != b->summary_last_modified) return a->summary_last_modified - b->summary_last_modified; gpointer value; @@ -537,7 +516,7 @@ ostree_repo_finder_result_compare (const OstreeRepoFinderResult *a, b_n_refs++; if (a_n_refs != b_n_refs) - return (gint) a_n_refs - (gint) b_n_refs; + return (gint)a_n_refs - (gint)b_n_refs; return g_strcmp0 (a->remote->name, b->remote->name); } diff --git a/src/libostree/ostree-repo-finder.h b/src/libostree/ostree-repo-finder.h index 0737b85..f587848 100644 --- a/src/libostree/ostree-repo-finder.h +++ b/src/libostree/ostree-repo-finder.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include "ostree-ref.h" #include "ostree-remote.h" @@ -44,48 +44,50 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeRepoFinder OstreeRepoFinder; typedef struct _OstreeRepoFinderInterface OstreeRepoFinderInterface; -static inline OstreeRepoFinder *OSTREE_REPO_FINDER (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_get_type (), OstreeRepoFinder); } -static inline gboolean OSTREE_IS_REPO_FINDER (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_get_type ()); } -static inline OstreeRepoFinderInterface *OSTREE_REPO_FINDER_GET_IFACE (gpointer ptr) { return G_TYPE_INSTANCE_GET_INTERFACE (ptr, ostree_repo_finder_get_type (), OstreeRepoFinderInterface); } +static inline OstreeRepoFinder * +OSTREE_REPO_FINDER (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_repo_finder_get_type (), OstreeRepoFinder); +} +static inline gboolean +OSTREE_IS_REPO_FINDER (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_repo_finder_get_type ()); +} +static inline OstreeRepoFinderInterface * +OSTREE_REPO_FINDER_GET_IFACE (gpointer ptr) +{ + return G_TYPE_INSTANCE_GET_INTERFACE (ptr, ostree_repo_finder_get_type (), + OstreeRepoFinderInterface); +} G_GNUC_END_IGNORE_DEPRECATIONS struct _OstreeRepoFinderInterface { GTypeInterface g_iface; - void (*resolve_async) (OstreeRepoFinder *self, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - GPtrArray *(*resolve_finish) (OstreeRepoFinder *self, - GAsyncResult *result, - GError **error); + void (*resolve_async) (OstreeRepoFinder *self, const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); + GPtrArray *(*resolve_finish) (OstreeRepoFinder *self, GAsyncResult *result, GError **error); }; _OSTREE_PUBLIC -void ostree_repo_finder_resolve_async (OstreeRepoFinder *self, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +void ostree_repo_finder_resolve_async (OstreeRepoFinder *self, + const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); _OSTREE_PUBLIC -GPtrArray *ostree_repo_finder_resolve_finish (OstreeRepoFinder *self, - GAsyncResult *result, - GError **error); +GPtrArray *ostree_repo_finder_resolve_finish (OstreeRepoFinder *self, GAsyncResult *result, + GError **error); _OSTREE_PUBLIC -void ostree_repo_finder_resolve_all_async (OstreeRepoFinder * const *finders, - const OstreeCollectionRef * const *refs, - OstreeRepo *parent_repo, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +void ostree_repo_finder_resolve_all_async (OstreeRepoFinder *const *finders, + const OstreeCollectionRef *const *refs, + OstreeRepo *parent_repo, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); _OSTREE_PUBLIC -GPtrArray *ostree_repo_finder_resolve_all_finish (GAsyncResult *result, - GError **error); +GPtrArray *ostree_repo_finder_resolve_all_finish (GAsyncResult *result, GError **error); /** * OstreeRepoFinderResult: @@ -152,12 +154,11 @@ _OSTREE_PUBLIC GType ostree_repo_finder_result_get_type (void); _OSTREE_PUBLIC -OstreeRepoFinderResult *ostree_repo_finder_result_new (OstreeRemote *remote, - OstreeRepoFinder *finder, - gint priority, - GHashTable *ref_to_checksum, - GHashTable *ref_to_timestamp, - guint64 summary_last_modified); +OstreeRepoFinderResult *ostree_repo_finder_result_new (OstreeRemote *remote, + OstreeRepoFinder *finder, gint priority, + GHashTable *ref_to_checksum, + GHashTable *ref_to_timestamp, + guint64 summary_last_modified); _OSTREE_PUBLIC OstreeRepoFinderResult *ostree_repo_finder_result_dup (OstreeRepoFinderResult *result); _OSTREE_PUBLIC @@ -178,7 +179,7 @@ void ostree_repo_finder_result_free (OstreeRepoFinderResult *result); * * Since: 2018.6 */ -typedef OstreeRepoFinderResult** OstreeRepoFinderResultv; +typedef OstreeRepoFinderResult **OstreeRepoFinderResultv; _OSTREE_PUBLIC void ostree_repo_finder_result_freev (OstreeRepoFinderResult **results); diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c index 631c6d4..65a3093 100644 --- a/src/libostree/ostree-repo-libarchive.c +++ b/src/libostree/ostree-repo-libarchive.c @@ -21,15 +21,15 @@ #include "config.h" -#include "otutil.h" -#include "ostree.h" #include "ostree-core-private.h" #include "ostree-repo-private.h" +#include "ostree.h" +#include "otutil.h" #ifdef HAVE_LIBARCHIVE +#include "ostree-libarchive-input-stream.h" #include #include -#include "ostree-libarchive-input-stream.h" #endif #include "otutil.h" @@ -39,16 +39,13 @@ #define DEFAULT_DIRMODE (0755 | S_IFDIR) static void -propagate_libarchive_error (GError **error, - struct archive *a) +propagate_libarchive_error (GError **error, struct archive *a) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "%s", archive_error_string (a)); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", archive_error_string (a)); } static const char * -path_relative (const char *src, - GError **error) +path_relative (const char *src, GError **error) { /* One issue here is that some archives almost record the pathname as just a * string and don't need to actually encode parent/child relationships in the @@ -92,8 +89,7 @@ path_relative (const char *src, } static char * -path_relative_ostree (const char *path, - GError **error) +path_relative_ostree (const char *path, GError **error) { path = path_relative (path, error); if (path == NULL) @@ -106,8 +102,7 @@ path_relative_ostree (const char *path, } static void -append_path_component (char **path_builder, - const char *component) +append_path_component (char **path_builder, const char *component) { g_autofree char *s = g_steal_pointer (path_builder); *path_builder = g_build_filename (s ?: "/", component, NULL); @@ -127,8 +122,7 @@ squash_trailing_slashes (char *path) * Yes, this hack will work even if it's a hardlink to a symlink. */ static void -read_archive_entry_stat (struct archive_entry *entry, - struct stat *stbuf) +read_archive_entry_stat (struct archive_entry *entry, struct stat *stbuf) { const struct stat *st = archive_entry_stat (entry); @@ -144,57 +138,44 @@ file_info_from_archive_entry (struct archive_entry *entry) struct stat stbuf; read_archive_entry_stat (entry, &stbuf); - g_autoptr(GFileInfo) info = _ostree_stbuf_to_gfileinfo (&stbuf); + g_autoptr (GFileInfo) info = _ostree_stbuf_to_gfileinfo (&stbuf); if (S_ISLNK (stbuf.st_mode)) { const char *target = archive_entry_symlink (entry); if (target != NULL) - g_file_info_set_attribute_byte_string (info, "standard::symlink-target", - target); + g_file_info_set_attribute_byte_string (info, "standard::symlink-target", target); } return g_steal_pointer (&info); } static gboolean -builder_add_label (GVariantBuilder *builder, - OstreeSePolicy *sepolicy, - const char *path, - mode_t mode, - GCancellable *cancellable, - GError **error) +builder_add_label (GVariantBuilder *builder, OstreeSePolicy *sepolicy, const char *path, + mode_t mode, GCancellable *cancellable, GError **error) { g_autofree char *label = NULL; if (!sepolicy) return TRUE; - if (!ostree_sepolicy_get_label (sepolicy, path, mode, &label, - cancellable, error)) + if (!ostree_sepolicy_get_label (sepolicy, path, mode, &label, cancellable, error)) return FALSE; if (label) - g_variant_builder_add (builder, "(@ay@ay)", - g_variant_new_bytestring ("security.selinux"), + g_variant_builder_add (builder, "(@ay@ay)", g_variant_new_bytestring ("security.selinux"), g_variant_new_bytestring (label)); return TRUE; } - /* Like ostree_mutable_tree_ensure_dir(), but also creates and sets dirmeta if * the dir has to be created. */ static gboolean -mtree_ensure_dir_with_meta (OstreeRepo *repo, - OstreeMutableTree *parent, - const char *name, - GFileInfo *file_info, - GVariant *xattrs, - gboolean error_if_exist, /* XXX: remove if not needed */ - OstreeMutableTree **out_dir, - GCancellable *cancellable, - GError **error) +mtree_ensure_dir_with_meta (OstreeRepo *repo, OstreeMutableTree *parent, const char *name, + GFileInfo *file_info, GVariant *xattrs, + gboolean error_if_exist, /* XXX: remove if not needed */ + OstreeMutableTree **out_dir, GCancellable *cancellable, GError **error) { - g_autoptr(OstreeMutableTree) dir = NULL; + g_autoptr (OstreeMutableTree) dir = NULL; g_autofree guchar *csum_raw = NULL; g_autofree char *csum = NULL; @@ -204,8 +185,8 @@ mtree_ensure_dir_with_meta (OstreeRepo *repo, { if (error_if_exist) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Directory \"%s\" already exists", name); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Directory \"%s\" already exists", + name); return FALSE; } } @@ -221,8 +202,7 @@ mtree_ensure_dir_with_meta (OstreeRepo *repo, return FALSE; } - if (!_ostree_repo_write_directory_meta (repo, file_info, xattrs, - &csum_raw, cancellable, error)) + if (!_ostree_repo_write_directory_meta (repo, file_info, xattrs, &csum_raw, cancellable, error)) return FALSE; csum = ostree_checksum_from_bytes (csum_raw); @@ -235,26 +215,26 @@ mtree_ensure_dir_with_meta (OstreeRepo *repo, return TRUE; } -typedef struct { - OstreeRepo *repo; +typedef struct +{ + OstreeRepo *repo; OstreeRepoImportArchiveOptions *opts; - OstreeMutableTree *root; - struct archive *archive; - struct archive_entry *entry; - GHashTable *deferred_hardlinks; - OstreeRepoCommitModifier *modifier; + OstreeMutableTree *root; + struct archive *archive; + struct archive_entry *entry; + GHashTable *deferred_hardlinks; + OstreeRepoCommitModifier *modifier; } OstreeRepoArchiveImportContext; -typedef struct { - OstreeMutableTree *parent; - char *path; - guint64 size; +typedef struct +{ + OstreeMutableTree *parent; + char *path; + guint64 size; } DeferredHardlink; -static inline char* -aic_get_final_path (OstreeRepoArchiveImportContext *ctx, - const char *path, - GError **error) +static inline char * +aic_get_final_path (OstreeRepoArchiveImportContext *ctx, const char *path, GError **error) { if (ctx->opts->translate_pathname) { @@ -272,9 +252,8 @@ aic_get_final_path (OstreeRepoArchiveImportContext *ctx, return g_strdup (path_relative (path, error)); } -static inline char* -aic_get_final_entry_pathname (OstreeRepoArchiveImportContext *ctx, - GError **error) +static inline char * +aic_get_final_entry_pathname (OstreeRepoArchiveImportContext *ctx, GError **error) { const char *pathname = archive_entry_pathname (ctx->entry); g_autofree char *final = aic_get_final_path (ctx, pathname, error); @@ -286,7 +265,7 @@ aic_get_final_entry_pathname (OstreeRepoArchiveImportContext *ctx, return g_steal_pointer (&final); } -static inline char* +static inline char * aic_get_final_entry_hardlink (OstreeRepoArchiveImportContext *ctx) { GError *local_error = NULL; @@ -306,11 +285,10 @@ aic_get_final_entry_hardlink (OstreeRepoArchiveImportContext *ctx) } static OstreeRepoCommitFilterResult -aic_apply_modifier_filter (OstreeRepoArchiveImportContext *ctx, - const char *relpath, - GFileInfo **out_file_info) +aic_apply_modifier_filter (OstreeRepoArchiveImportContext *ctx, const char *relpath, + GFileInfo **out_file_info) { - g_autoptr(GFileInfo) file_info = NULL; + g_autoptr (GFileInfo) file_info = NULL; g_autofree char *abspath = NULL; const char *cb_path = NULL; @@ -325,48 +303,40 @@ aic_apply_modifier_filter (OstreeRepoArchiveImportContext *ctx, file_info = file_info_from_archive_entry (ctx->entry); - return _ostree_repo_commit_modifier_apply (ctx->repo, ctx->modifier, cb_path, - file_info, out_file_info); + return _ostree_repo_commit_modifier_apply (ctx->repo, ctx->modifier, cb_path, file_info, + out_file_info); } static gboolean aic_ensure_parent_dir_with_file_info (OstreeRepoArchiveImportContext *ctx, - OstreeMutableTree *parent, - const char *fullpath, - GFileInfo *file_info, - OstreeMutableTree **out_dir, - GCancellable *cancellable, - GError **error) + OstreeMutableTree *parent, const char *fullpath, + GFileInfo *file_info, OstreeMutableTree **out_dir, + GCancellable *cancellable, GError **error) { const char *name = glnx_basename (fullpath); - g_auto(GVariantBuilder) xattrs_builder; - g_autoptr(GVariant) xattrs = NULL; + g_auto (GVariantBuilder) xattrs_builder; + g_autoptr (GVariant) xattrs = NULL; /* is this the root directory itself? transform into empty string */ if (name[0] == '/' && name[1] == '\0') name++; - g_variant_builder_init (&xattrs_builder, (GVariantType*)"a(ayay)"); + g_variant_builder_init (&xattrs_builder, (GVariantType *)"a(ayay)"); if (ctx->modifier && ctx->modifier->sepolicy) - if (!builder_add_label (&xattrs_builder, ctx->modifier->sepolicy, fullpath, - DEFAULT_DIRMODE, cancellable, error)) + if (!builder_add_label (&xattrs_builder, ctx->modifier->sepolicy, fullpath, DEFAULT_DIRMODE, + cancellable, error)) return FALSE; xattrs = g_variant_ref_sink (g_variant_builder_end (&xattrs_builder)); - return mtree_ensure_dir_with_meta (ctx->repo, parent, name, file_info, - xattrs, - FALSE /* error_if_exist */, out_dir, - cancellable, error); + return mtree_ensure_dir_with_meta (ctx->repo, parent, name, file_info, xattrs, + FALSE /* error_if_exist */, out_dir, cancellable, error); } static gboolean -aic_ensure_parent_dir (OstreeRepoArchiveImportContext *ctx, - OstreeMutableTree *parent, - const char *fullpath, - OstreeMutableTree **out_dir, - GCancellable *cancellable, - GError **error) +aic_ensure_parent_dir (OstreeRepoArchiveImportContext *ctx, OstreeMutableTree *parent, + const char *fullpath, OstreeMutableTree **out_dir, GCancellable *cancellable, + GError **error) { GLNX_AUTO_PREFIX_ERROR ("ostree-tar: Failed to create parent", error); /* Who should own the parent dir? Since it's not in the archive, it's up to @@ -382,31 +352,27 @@ aic_ensure_parent_dir (OstreeRepoArchiveImportContext *ctx, g_file_info_set_attribute_uint32 (file_info, "unix::gid", gid); g_file_info_set_attribute_uint32 (file_info, "unix::mode", DEFAULT_DIRMODE); - return aic_ensure_parent_dir_with_file_info (ctx, parent, fullpath, file_info, - out_dir, cancellable, error); + return aic_ensure_parent_dir_with_file_info (ctx, parent, fullpath, file_info, out_dir, + cancellable, error); } static gboolean -aic_create_parent_dirs (OstreeRepoArchiveImportContext *ctx, - GPtrArray *components, - OstreeMutableTree **out_subdir, - GCancellable *cancellable, - GError **error) +aic_create_parent_dirs (OstreeRepoArchiveImportContext *ctx, GPtrArray *components, + OstreeMutableTree **out_subdir, GCancellable *cancellable, GError **error) { g_autofree char *fullpath = NULL; - g_autoptr(OstreeMutableTree) dir = NULL; + g_autoptr (OstreeMutableTree) dir = NULL; /* start with the root itself */ if (!aic_ensure_parent_dir (ctx, ctx->root, "/", &dir, cancellable, error)) return FALSE; - for (guint i = 0; i < components->len-1; i++) + for (guint i = 0; i < components->len - 1; i++) { - glnx_unref_object OstreeMutableTree *subdir = NULL; + glnx_unref_object OstreeMutableTree *subdir = NULL; append_path_component (&fullpath, components->pdata[i]); - if (!aic_ensure_parent_dir (ctx, dir, fullpath, &subdir, - cancellable, error)) + if (!aic_ensure_parent_dir (ctx, dir, fullpath, &subdir, cancellable, error)) return FALSE; g_set_object (&dir, subdir); @@ -417,13 +383,10 @@ aic_create_parent_dirs (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_get_parent_dir (OstreeRepoArchiveImportContext *ctx, - const char *path, - OstreeMutableTree **out_dir, - GCancellable *cancellable, - GError **error) +aic_get_parent_dir (OstreeRepoArchiveImportContext *ctx, const char *path, + OstreeMutableTree **out_dir, GCancellable *cancellable, GError **error) { - g_autoptr(GPtrArray) components = NULL; + g_autoptr (GPtrArray) components = NULL; if (!ot_util_path_split_validate (path, &components, error)) return FALSE; @@ -442,28 +405,23 @@ aic_get_parent_dir (OstreeRepoArchiveImportContext *ctx, if (ctx->opts->autocreate_parents) { g_clear_error (error); - return aic_create_parent_dirs (ctx, components, out_dir, - cancellable, error); + return aic_create_parent_dirs (ctx, components, out_dir, cancellable, error); } return FALSE; } static gboolean -aic_get_xattrs (OstreeRepoArchiveImportContext *ctx, - const char *path, - GFileInfo *file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) +aic_get_xattrs (OstreeRepoArchiveImportContext *ctx, const char *path, GFileInfo *file_info, + GVariant **out_xattrs, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("ostree-tar: Failed to get xattrs", error); g_autofree char *abspath = g_build_filename ("/", path, NULL); - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; const char *cb_path = abspath; - gboolean no_xattrs = ctx->modifier && - ctx->modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS; + gboolean no_xattrs + = ctx->modifier && ctx->modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS; if (!no_xattrs && archive_entry_xattr_count (ctx->entry) > 0) { @@ -471,18 +429,14 @@ aic_get_xattrs (OstreeRepoArchiveImportContext *ctx, const void *value; size_t size; - g_autoptr(GVariantBuilder) builder = - ot_util_variant_builder_from_variant (xattrs, - G_VARIANT_TYPE ("a(ayay)")); + g_autoptr (GVariantBuilder) builder + = ot_util_variant_builder_from_variant (xattrs, G_VARIANT_TYPE ("a(ayay)")); archive_entry_xattr_reset (ctx->entry); - while (archive_entry_xattr_next ( - ctx->entry, &name, &value, &size) == ARCHIVE_OK) + while (archive_entry_xattr_next (ctx->entry, &name, &value, &size) == ARCHIVE_OK) { - g_variant_builder_add (builder, "(@ay@ay)", - g_variant_new_bytestring (name), - g_variant_new_fixed_array (G_VARIANT_TYPE("y"), - value, size, 1)); + g_variant_builder_add (builder, "(@ay@ay)", g_variant_new_bytestring (name), + g_variant_new_fixed_array (G_VARIANT_TYPE ("y"), value, size, 1)); } xattrs = g_variant_builder_end (builder); @@ -503,12 +457,10 @@ aic_get_xattrs (OstreeRepoArchiveImportContext *ctx, if (ctx->modifier && ctx->modifier->sepolicy) { mode_t mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); - g_autoptr(GVariantBuilder) builder = - ot_util_variant_builder_from_variant (xattrs, G_VARIANT_TYPE - ("a(ayay)")); + g_autoptr (GVariantBuilder) builder + = ot_util_variant_builder_from_variant (xattrs, G_VARIANT_TYPE ("a(ayay)")); - if (!builder_add_label (builder, ctx->modifier->sepolicy, abspath, mode, - cancellable, error)) + if (!builder_add_label (builder, ctx->modifier->sepolicy, abspath, mode, cancellable, error)) return FALSE; if (xattrs) @@ -525,35 +477,26 @@ aic_get_xattrs (OstreeRepoArchiveImportContext *ctx, /* XXX: add option in ctx->opts to disallow already existing dirs? see * error_if_exist */ static gboolean -aic_handle_dir (OstreeRepoArchiveImportContext *ctx, - OstreeMutableTree *parent, - const char *path, - GFileInfo *fi, - GCancellable *cancellable, - GError **error) +aic_handle_dir (OstreeRepoArchiveImportContext *ctx, OstreeMutableTree *parent, const char *path, + GFileInfo *fi, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("ostree-tar: Failed to handle directory", error); const char *name = glnx_basename (path); - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; if (!aic_get_xattrs (ctx, path, fi, &xattrs, cancellable, error)) return FALSE; return mtree_ensure_dir_with_meta (ctx->repo, parent, name, fi, xattrs, - FALSE /* error_if_exist */, NULL, - cancellable, error); + FALSE /* error_if_exist */, NULL, cancellable, error); } static gboolean -aic_write_file (OstreeRepoArchiveImportContext *ctx, - GFileInfo *fi, - GVariant *xattrs, - char **out_csum, - GCancellable *cancellable, - GError **error) +aic_write_file (OstreeRepoArchiveImportContext *ctx, GFileInfo *fi, GVariant *xattrs, + char **out_csum, GCancellable *cancellable, GError **error) { - g_autoptr(GInputStream) archive_stream = NULL; - g_autoptr(GInputStream) file_object_input = NULL; + g_autoptr (GInputStream) archive_stream = NULL; + g_autoptr (GInputStream) file_object_input = NULL; guint64 length; g_autofree guchar *csum_raw = NULL; @@ -561,13 +504,12 @@ aic_write_file (OstreeRepoArchiveImportContext *ctx, if (g_file_info_get_file_type (fi) == G_FILE_TYPE_REGULAR) archive_stream = _ostree_libarchive_input_stream_new (ctx->archive); - if (!ostree_raw_file_to_content_stream (archive_stream, fi, xattrs, - &file_object_input, &length, + if (!ostree_raw_file_to_content_stream (archive_stream, fi, xattrs, &file_object_input, &length, cancellable, error)) return FALSE; - if (!ostree_repo_write_content (ctx->repo, NULL, file_object_input, length, - &csum_raw, cancellable, error)) + if (!ostree_repo_write_content (ctx->repo, NULL, file_object_input, length, &csum_raw, + cancellable, error)) return FALSE; *out_csum = ostree_checksum_from_bytes (csum_raw); @@ -575,16 +517,12 @@ aic_write_file (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_import_file (OstreeRepoArchiveImportContext *ctx, - OstreeMutableTree *parent, - const char *path, - GFileInfo *fi, - GCancellable *cancellable, - GError **error) +aic_import_file (OstreeRepoArchiveImportContext *ctx, OstreeMutableTree *parent, const char *path, + GFileInfo *fi, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("ostree-tar: Failed to import file", error); const char *name = glnx_basename (path); - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; g_autofree char *csum = NULL; if (!aic_get_xattrs (ctx, path, fi, &xattrs, cancellable, error)) @@ -600,9 +538,8 @@ aic_import_file (OstreeRepoArchiveImportContext *ctx, } static void -aic_add_deferred_hardlink (OstreeRepoArchiveImportContext *ctx, - const char *hardlink, - DeferredHardlink *dh) +aic_add_deferred_hardlink (OstreeRepoArchiveImportContext *ctx, const char *hardlink, + DeferredHardlink *dh) { gboolean new_slist; GSList *slist; @@ -617,11 +554,8 @@ aic_add_deferred_hardlink (OstreeRepoArchiveImportContext *ctx, } static void -aic_defer_hardlink (OstreeRepoArchiveImportContext *ctx, - OstreeMutableTree *parent, - const char *path, - guint64 size, - const char *hardlink) +aic_defer_hardlink (OstreeRepoArchiveImportContext *ctx, OstreeMutableTree *parent, + const char *path, guint64 size, const char *hardlink) { DeferredHardlink *dh = g_slice_new (DeferredHardlink); dh->parent = g_object_ref (parent); @@ -632,12 +566,8 @@ aic_defer_hardlink (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_handle_file (OstreeRepoArchiveImportContext *ctx, - OstreeMutableTree *parent, - const char *path, - GFileInfo *fi, - GCancellable *cancellable, - GError **error) +aic_handle_file (OstreeRepoArchiveImportContext *ctx, OstreeMutableTree *parent, const char *path, + GFileInfo *fi, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("ostree-tar: Failed to handle file", error); /* The wonderful world of hardlinks and archives. We have to be very careful @@ -667,12 +597,8 @@ aic_handle_file (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_handle_entry (OstreeRepoArchiveImportContext *ctx, - OstreeMutableTree *parent, - const char *path, - GFileInfo *fi, - GCancellable *cancellable, - GError **error) +aic_handle_entry (OstreeRepoArchiveImportContext *ctx, OstreeMutableTree *parent, const char *path, + GFileInfo *fi, GCancellable *cancellable, GError **error) { switch (g_file_info_get_file_type (fi)) { @@ -686,28 +612,24 @@ aic_handle_entry (OstreeRepoArchiveImportContext *ctx, return TRUE; else { - return glnx_throw (error, "Unsupported file type for path \"%s\"", - path); + return glnx_throw (error, "Unsupported file type for path \"%s\"", path); } } } static gboolean -aic_import_entry (OstreeRepoArchiveImportContext *ctx, - GCancellable *cancellable, - GError **error) +aic_import_entry (OstreeRepoArchiveImportContext *ctx, GCancellable *cancellable, GError **error) { g_autofree char *path = aic_get_final_entry_pathname (ctx, error); if (path == NULL) return FALSE; - g_autoptr(GFileInfo) fi = NULL; - if (aic_apply_modifier_filter (ctx, path, &fi) - == OSTREE_REPO_COMMIT_FILTER_SKIP) + g_autoptr (GFileInfo) fi = NULL; + if (aic_apply_modifier_filter (ctx, path, &fi) == OSTREE_REPO_COMMIT_FILTER_SKIP) return TRUE; - g_autoptr(OstreeMutableTree) parent = NULL; + g_autoptr (OstreeMutableTree) parent = NULL; if (!aic_get_parent_dir (ctx, path, &parent, cancellable, error)) return FALSE; @@ -715,16 +637,14 @@ aic_import_entry (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_import_from_hardlink (OstreeRepoArchiveImportContext *ctx, - const char *target, - DeferredHardlink *dh, - GError **error) +aic_import_from_hardlink (OstreeRepoArchiveImportContext *ctx, const char *target, + DeferredHardlink *dh, GError **error) { g_autofree char *csum = NULL; const char *name = glnx_basename (target); const char *name_dh = glnx_basename (dh->path); - g_autoptr(GPtrArray) components = NULL; - g_autoptr(OstreeMutableTree) parent = NULL; + g_autoptr (GPtrArray) components = NULL; + g_autoptr (OstreeMutableTree) parent = NULL; if (!ostree_mutable_tree_lookup (dh->parent, name_dh, &csum, NULL, error)) return FALSE; @@ -744,16 +664,14 @@ aic_import_from_hardlink (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_lookup_file_csum (OstreeRepoArchiveImportContext *ctx, - const char *target, - char **out_csum, - GError **error) +aic_lookup_file_csum (OstreeRepoArchiveImportContext *ctx, const char *target, char **out_csum, + GError **error) { g_autofree char *csum = NULL; const char *name = glnx_basename (target); - g_autoptr(OstreeMutableTree) parent = NULL; - g_autoptr(OstreeMutableTree) subdir = NULL; - g_autoptr(GPtrArray) components = NULL; + g_autoptr (OstreeMutableTree) parent = NULL; + g_autoptr (OstreeMutableTree) subdir = NULL; + g_autoptr (GPtrArray) components = NULL; if (!ot_util_path_split_validate (target, &components, error)) return FALSE; @@ -768,7 +686,8 @@ aic_lookup_file_csum (OstreeRepoArchiveImportContext *ctx, { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Expected hardlink file target at \"%s\" but found a " - "directory", target); + "directory", + target); return FALSE; } @@ -777,17 +696,15 @@ aic_lookup_file_csum (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_import_deferred_hardlinks_for (OstreeRepoArchiveImportContext *ctx, - const char *target, - GSList *hardlinks, - GError **error) +aic_import_deferred_hardlinks_for (OstreeRepoArchiveImportContext *ctx, const char *target, + GSList *hardlinks, GError **error) { GSList *payload = hardlinks; g_autofree char *csum = NULL; /* find node with the payload, if any (if none, then they're all hardlinks to * a zero sized target, and there's no rewrite required) */ - while (payload && ((DeferredHardlink*)payload->data)->size == 0) + while (payload && ((DeferredHardlink *)payload->data)->size == 0) payload = g_slist_next (payload); /* rewrite the target so it points to the csum of the payload hardlink */ @@ -815,11 +732,10 @@ aic_import_deferred_hardlinks_for (OstreeRepoArchiveImportContext *ctx, } static gboolean -aic_import_deferred_hardlinks (OstreeRepoArchiveImportContext *ctx, - GCancellable *cancellable, - GError **error) +aic_import_deferred_hardlinks (OstreeRepoArchiveImportContext *ctx, GCancellable *cancellable, + GError **error) { - GLNX_HASH_TABLE_FOREACH_KV (ctx->deferred_hardlinks, const char*, target, GSList*, links) + GLNX_HASH_TABLE_FOREACH_KV (ctx->deferred_hardlinks, const char *, target, GSList *, links) { if (!aic_import_deferred_hardlinks_for (ctx, target, links, error)) return glnx_prefix_error (error, "ostree-tar: Processing deferred hardlink %s", target); @@ -858,29 +774,23 @@ deferred_hardlinks_list_free (void *data) * file structure to @mtree. */ gboolean -ostree_repo_import_archive_to_mtree (OstreeRepo *self, - OstreeRepoImportArchiveOptions *opts, - void *archive, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GCancellable *cancellable, - GError **error) +ostree_repo_import_archive_to_mtree (OstreeRepo *self, OstreeRepoImportArchiveOptions *opts, + void *archive, OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, GCancellable *cancellable, + GError **error) { #ifdef HAVE_LIBARCHIVE gboolean ret = FALSE; struct archive *a = archive; - g_autoptr(GHashTable) deferred_hardlinks = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, - deferred_hardlinks_list_free); - - OstreeRepoArchiveImportContext aictx = { - .repo = self, - .opts = opts, - .root = mtree, - .archive = archive, - .deferred_hardlinks = deferred_hardlinks, - .modifier = modifier - }; + g_autoptr (GHashTable) deferred_hardlinks + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, deferred_hardlinks_list_free); + + OstreeRepoArchiveImportContext aictx = { .repo = self, + .opts = opts, + .root = mtree, + .archive = archive, + .deferred_hardlinks = deferred_hardlinks, + .modifier = modifier }; _ostree_repo_setup_generate_sizes (self, modifier); @@ -910,29 +820,24 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self, * useful primarily when importing Docker image layers, which can * just be metadata. */ - if (opts->autocreate_parents && - ostree_mutable_tree_get_metadata_checksum (mtree) == NULL) + if (opts->autocreate_parents && ostree_mutable_tree_get_metadata_checksum (mtree) == NULL) { /* _ostree_stbuf_to_gfileinfo() only looks at these fields, * but we use it to ensure it sets all of the relevant GFileInfo * properties. */ - struct stat stbuf = { .st_mode = DEFAULT_DIRMODE, - .st_uid = 0, - .st_gid = 0 }; - g_autoptr(GFileInfo) fi = _ostree_stbuf_to_gfileinfo (&stbuf); + struct stat stbuf = { .st_mode = DEFAULT_DIRMODE, .st_uid = 0, .st_gid = 0 }; + g_autoptr (GFileInfo) fi = _ostree_stbuf_to_gfileinfo (&stbuf); - g_autoptr(GFileInfo) mfi = NULL; - (void)_ostree_repo_commit_modifier_apply (self, modifier, "/", - fi, &mfi); + g_autoptr (GFileInfo) mfi = NULL; + (void)_ostree_repo_commit_modifier_apply (self, modifier, "/", fi, &mfi); - if (!aic_ensure_parent_dir_with_file_info (&aictx, mtree, "/", mfi, NULL, - cancellable, error)) + if (!aic_ensure_parent_dir_with_file_info (&aictx, mtree, "/", mfi, NULL, cancellable, error)) goto out; } ret = TRUE; - out: +out: return ret; #else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, @@ -943,20 +848,19 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self, #ifdef HAVE_LIBARCHIVE static gboolean -write_archive_to_mtree (OstreeRepo *self, - OtAutoArchiveRead *archive, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - gboolean autocreate_parents, - GCancellable *cancellable, - GError **error) +write_archive_to_mtree (OstreeRepo *self, OtAutoArchiveRead *archive, OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, gboolean autocreate_parents, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - OstreeRepoImportArchiveOptions opts = { 0, }; + OstreeRepoImportArchiveOptions opts = { + 0, + }; opts.autocreate_parents = !!autocreate_parents; - if (!ostree_repo_import_archive_to_mtree (self, &opts, archive, mtree, modifier, cancellable, error)) + if (!ostree_repo_import_archive_to_mtree (self, &opts, archive, mtree, modifier, cancellable, + error)) goto out; if (archive_read_close (archive) != ARCHIVE_OK) @@ -966,7 +870,7 @@ write_archive_to_mtree (OstreeRepo *self, } ret = TRUE; - out: +out: (void)archive_read_close (archive); return ret; } @@ -986,18 +890,15 @@ write_archive_to_mtree (OstreeRepo *self, * file structure to @mtree. */ gboolean -ostree_repo_write_archive_to_mtree (OstreeRepo *self, - GFile *archive, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - gboolean autocreate_parents, - GCancellable *cancellable, - GError **error) +ostree_repo_write_archive_to_mtree (OstreeRepo *self, GFile *archive, OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, gboolean autocreate_parents, + GCancellable *cancellable, GError **error) { #ifdef HAVE_LIBARCHIVE - g_autoptr(OtAutoArchiveRead) a = ot_open_archive_read (gs_file_get_path_cached (archive), error); + g_autoptr (OtAutoArchiveRead) a = ot_open_archive_read (gs_file_get_path_cached (archive), error); if (a) - return write_archive_to_mtree (self, a, mtree, modifier, autocreate_parents, cancellable, error); + return write_archive_to_mtree (self, a, mtree, modifier, autocreate_parents, cancellable, + error); return FALSE; #else @@ -1021,18 +922,16 @@ ostree_repo_write_archive_to_mtree (OstreeRepo *self, * its file structure to @mtree. */ gboolean -ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo *self, - int fd, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - gboolean autocreate_parents, - GCancellable *cancellable, - GError **error) +ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo *self, int fd, OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + gboolean autocreate_parents, GCancellable *cancellable, + GError **error) { #ifdef HAVE_LIBARCHIVE - g_autoptr(OtAutoArchiveRead) a = ot_open_archive_read_fd (fd, error); + g_autoptr (OtAutoArchiveRead) a = ot_open_archive_read_fd (fd, error); if (a) - return write_archive_to_mtree (self, a, mtree, modifier, autocreate_parents, cancellable, error); + return write_archive_to_mtree (self, a, mtree, modifier, autocreate_parents, cancellable, + error); return FALSE; #else @@ -1044,19 +943,10 @@ ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo *self, #ifdef HAVE_LIBARCHIVE -static gboolean -file_to_archive_entry_common (GFile *root, - OstreeRepoExportArchiveOptions *opts, - GFile *path, - GFileInfo *file_info, - struct archive_entry *entry, - GError **error) +static char * +file_to_pathstr (GFile *root, OstreeRepoExportArchiveOptions *opts, GFile *path) { - gboolean ret = FALSE; g_autofree char *pathstr = g_file_get_relative_path (root, path); - g_autoptr(GVariant) xattrs = NULL; - time_t ts = (time_t) opts->timestamp_secs; - if (opts->path_prefix && opts->path_prefix[0]) { g_autofree char *old_pathstr = pathstr; @@ -1069,6 +959,18 @@ file_to_archive_entry_common (GFile *root, pathstr = g_strdup ("."); } + return g_steal_pointer (&pathstr); +} + +static gboolean +file_to_archive_entry_common (GFile *root, OstreeRepoExportArchiveOptions *opts, GFile *path, + GFileInfo *file_info, struct archive_entry *entry, GError **error) +{ + gboolean ret = FALSE; + g_autofree char *pathstr = file_to_pathstr (root, opts, path); + g_autoptr (GVariant) xattrs = NULL; + time_t ts = (time_t)opts->timestamp_secs; + archive_entry_update_pathname_utf8 (entry, pathstr); archive_entry_set_ctime (entry, ts, OSTREE_TIMESTAMP); archive_entry_set_mtime (entry, ts, OSTREE_TIMESTAMP); @@ -1077,38 +979,35 @@ file_to_archive_entry_common (GFile *root, archive_entry_set_gid (entry, g_file_info_get_attribute_uint32 (file_info, "unix::gid")); archive_entry_set_mode (entry, g_file_info_get_attribute_uint32 (file_info, "unix::mode")); - if (!ostree_repo_file_get_xattrs ((OstreeRepoFile*)path, &xattrs, NULL, error)) + if (!ostree_repo_file_get_xattrs ((OstreeRepoFile *)path, &xattrs, NULL, error)) goto out; if (!opts->disable_xattrs) { int i, n; - + n = g_variant_n_children (xattrs); for (i = 0; i < n; i++) { - const guint8* name; - g_autoptr(GVariant) value = NULL; - const guint8* value_data; + const guint8 *name; + g_autoptr (GVariant) value = NULL; + const guint8 *value_data; gsize value_len; g_variant_get_child (xattrs, i, "(^&ay@ay)", &name, &value); value_data = g_variant_get_fixed_array (value, &value_len, 1); - archive_entry_xattr_add_entry (entry, (char*)name, - (char*) value_data, value_len); + archive_entry_xattr_add_entry (entry, (char *)name, (char *)value_data, value_len); } } ret = TRUE; - out: +out: return ret; } static gboolean -write_header_free_entry (struct archive *a, - struct archive_entry **entryp, - GError **error) +write_header_free_entry (struct archive *a, struct archive_entry **entryp, GError **error) { struct archive_entry *entry = *entryp; gboolean ret = FALSE; @@ -1120,28 +1019,24 @@ write_header_free_entry (struct archive *a, } ret = TRUE; - out: +out: archive_entry_free (entry); *entryp = NULL; return ret; } static gboolean -write_directory_to_libarchive_recurse (OstreeRepo *self, - OstreeRepoExportArchiveOptions *opts, - GFile *root, - GFile *dir, - struct archive *a, - GCancellable *cancellable, - GError **error) +write_directory_to_libarchive_recurse (OstreeRepo *self, OstreeRepoExportArchiveOptions *opts, + GFile *root, GFile *dir, struct archive *a, + GHashTable *seen_checksums, GCancellable *cancellable, + GError **error) { gboolean ret = FALSE; - g_autoptr(GFileInfo) dir_info = NULL; - g_autoptr(GFileEnumerator) dir_enum = NULL; + g_autoptr (GFileInfo) dir_info = NULL; + g_autoptr (GFileEnumerator) dir_enum = NULL; struct archive_entry *entry = NULL; - dir_info = g_file_query_info (dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + dir_info = g_file_query_info (dir, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_info) goto out; @@ -1152,9 +1047,8 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, if (!write_header_free_entry (a, &entry, error)) goto out; - dir_enum = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + dir_enum = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_enum) goto out; @@ -1163,8 +1057,7 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, GFileInfo *file_info; GFile *path; - if (!g_file_enumerator_iterate (dir_enum, &file_info, &path, - cancellable, error)) + if (!g_file_enumerator_iterate (dir_enum, &file_info, &path, cancellable, error)) goto out; if (file_info == NULL) break; @@ -1172,7 +1065,7 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, /* First, handle directories recursively */ if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) { - if (!write_directory_to_libarchive_recurse (self, opts, root, path, a, + if (!write_directory_to_libarchive_recurse (self, opts, root, path, a, seen_checksums, cancellable, error)) goto out; @@ -1198,11 +1091,29 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, case G_FILE_TYPE_REGULAR: { guint8 buf[8192]; - g_autoptr(GInputStream) file_in = NULL; - g_autoptr(GFileInfo) regular_file_info = NULL; + g_autoptr (GInputStream) file_in = NULL; + g_autoptr (GFileInfo) regular_file_info = NULL; const char *checksum; + GFile *old_path; - checksum = ostree_repo_file_get_checksum ((OstreeRepoFile*)path); + checksum = ostree_repo_file_get_checksum ((OstreeRepoFile *)path); + + old_path = g_hash_table_lookup (seen_checksums, checksum); + if (old_path) + { + g_autofree char *old_pathstr = file_to_pathstr (root, opts, old_path); + + archive_entry_set_hardlink (entry, old_pathstr); + if (!write_header_free_entry (a, &entry, error)) + goto out; + + break; + } + else + { + /* The checksum is owned by path (an OstreeRepoFile) */ + g_hash_table_insert (seen_checksums, (char *)checksum, g_object_ref (path)); + } if (!ostree_repo_load_file (self, checksum, &file_in, ®ular_file_info, NULL, cancellable, error)) @@ -1218,18 +1129,22 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, while (TRUE) { - gssize bytes_read = g_input_stream_read (file_in, buf, sizeof (buf), - cancellable, error); + gssize bytes_read + = g_input_stream_read (file_in, buf, sizeof (buf), cancellable, error); if (bytes_read < 0) goto out; if (bytes_read == 0) break; - { ssize_t r = archive_write_data (a, buf, bytes_read); + { + ssize_t r = archive_write_data (a, buf, bytes_read); if (r != bytes_read) { propagate_libarchive_error (error, a); - g_prefix_error (error, "Failed to write %" G_GUINT64_FORMAT " bytes (code %" G_GUINT64_FORMAT"): ", (guint64)bytes_read, (guint64)r); + g_prefix_error (error, + "Failed to write %" G_GUINT64_FORMAT + " bytes (code %" G_GUINT64_FORMAT "): ", + (guint64)bytes_read, (guint64)r); goto out; } } @@ -1251,7 +1166,7 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, } ret = TRUE; - out: +out: if (entry) archive_entry_free (entry); return ret; @@ -1263,7 +1178,8 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, * @self: An #OstreeRepo * @opts: Options controlling conversion * @root: An #OstreeRepoFile for the base directory - * @archive: A `struct archive`, but specified as void to avoid a dependency on the libarchive headers + * @archive: A `struct archive`, but specified as void to avoid a dependency on the libarchive + * headers * @cancellable: Cancellable * @error: Error * @@ -1271,23 +1187,22 @@ write_directory_to_libarchive_recurse (OstreeRepo *self, * file structure to @mtree. */ gboolean -ostree_repo_export_tree_to_archive (OstreeRepo *self, - OstreeRepoExportArchiveOptions *opts, - OstreeRepoFile *root, - void *archive, - GCancellable *cancellable, - GError **error) +ostree_repo_export_tree_to_archive (OstreeRepo *self, OstreeRepoExportArchiveOptions *opts, + OstreeRepoFile *root, void *archive, GCancellable *cancellable, + GError **error) { #ifdef HAVE_LIBARCHIVE gboolean ret = FALSE; struct archive *a = archive; + g_autoptr (GHashTable) seen_checksums + = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); - if (!write_directory_to_libarchive_recurse (self, opts, (GFile*)root, (GFile*)root, - a, cancellable, error)) + if (!write_directory_to_libarchive_recurse (self, opts, (GFile *)root, (GFile *)root, a, + seen_checksums, cancellable, error)) goto out; ret = TRUE; - out: +out: return ret; #else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, diff --git a/src/libostree/ostree-repo-os.c b/src/libostree/ostree-repo-os.c index 784e033..ef150c2 100644 --- a/src/libostree/ostree-repo-os.c +++ b/src/libostree/ostree-repo-os.c @@ -17,16 +17,16 @@ #include "config.h" -#include -#include -#include -#include -#include #include "libglnx.h" -#include "ostree.h" #include "ostree-core-private.h" #include "ostree-repo-os.h" +#include "ostree.h" #include "otutil.h" +#include +#include +#include +#include +#include /** * ostree_commit_metadata_for_bootable: @@ -38,13 +38,12 @@ */ _OSTREE_PUBLIC gboolean -ostree_commit_metadata_for_bootable (GFile *root, GVariantDict *dict, GCancellable *cancellable, GError **error) +ostree_commit_metadata_for_bootable (GFile *root, GVariantDict *dict, GCancellable *cancellable, + GError **error) { - g_autoptr(GFile) modules = g_file_resolve_relative_path (root, "usr/lib/modules"); - g_autoptr(GFileEnumerator) dir_enum - = g_file_enumerate_children (modules, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + g_autoptr (GFile) modules = g_file_resolve_relative_path (root, "usr/lib/modules"); + g_autoptr (GFileEnumerator) dir_enum = g_file_enumerate_children ( + modules, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_enum) return glnx_prefix_error (error, "Opening usr/lib/modules"); @@ -53,15 +52,14 @@ ostree_commit_metadata_for_bootable (GFile *root, GVariantDict *dict, GCancellab { GFileInfo *child_info; GFile *child_path; - if (!g_file_enumerator_iterate (dir_enum, &child_info, &child_path, - cancellable, error)) + if (!g_file_enumerator_iterate (dir_enum, &child_info, &child_path, cancellable, error)) return FALSE; if (child_info == NULL) break; if (g_file_info_get_file_type (child_info) != G_FILE_TYPE_DIRECTORY) continue; - - g_autoptr(GFile) kernel_path = g_file_resolve_relative_path (child_path, "vmlinuz"); + + g_autoptr (GFile) kernel_path = g_file_resolve_relative_path (child_path, "vmlinuz"); if (!g_file_query_exists (kernel_path, NULL)) continue; diff --git a/src/libostree/ostree-repo-os.h b/src/libostree/ostree-repo-os.h index 9019ea5..28963ee 100644 --- a/src/libostree/ostree-repo-os.h +++ b/src/libostree/ostree-repo-os.h @@ -17,20 +17,20 @@ #pragma once -#include #include #include +#include G_BEGIN_DECLS -/** +/** * OSTREE_METADATA_KEY_BOOTABLE: * * GVariant type `b`: Set if this commit is intended to be bootable * Since: 2021.1 */ #define OSTREE_METADATA_KEY_BOOTABLE "ostree.bootable" -/** +/** * OSTREE_METADATA_KEY_LINUX: * * GVariant type `s`: Contains the Linux kernel release (i.e. `uname -r`) @@ -39,7 +39,7 @@ G_BEGIN_DECLS #define OSTREE_METADATA_KEY_LINUX "ostree.linux" _OSTREE_PUBLIC -gboolean -ostree_commit_metadata_for_bootable (GFile *root, GVariantDict *dict, GCancellable *cancellable, GError **error); +gboolean ostree_commit_metadata_for_bootable (GFile *root, GVariantDict *dict, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 96253e7..ad6457e 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -19,12 +19,12 @@ #pragma once -#include #include "config.h" -#include "otutil.h" #include "ostree-ref.h" -#include "ostree-repo.h" #include "ostree-remote-private.h" +#include "ostree-repo.h" +#include "otutil.h" +#include G_BEGIN_DECLS @@ -33,7 +33,6 @@ G_BEGIN_DECLS #define _OSTREE_SUMMARY_CACHE_DIR "summaries" #define _OSTREE_CACHE_DIR "cache" -#define _OSTREE_MAX_OUTSTANDING_FETCHER_REQUESTS 8 #define _OSTREE_MAX_OUTSTANDING_DELTAPART_REQUESTS 2 /* We want some parallelism with disk writes, but we also @@ -65,13 +64,22 @@ G_BEGIN_DECLS #define OSTREE_COMMIT_TIMESTAMP "ostree.commit.timestamp" #define OSTREE_COMMIT_VERSION "ostree.commit.version" -typedef enum { +// The metadata key for composefs +#define OSTREE_COMPOSEFS_META_PREFIX "ostree.composefs" +// The fs-verity digest of the composefs, version 0 +#define OSTREE_COMPOSEFS_DIGEST_KEY_V0 OSTREE_COMPOSEFS_META_PREFIX ".digest.v0" + +#define _OSTREE_INTEGRITY_SECTION "ex-integrity" + +typedef enum +{ OSTREE_REPO_TEST_ERROR_PRE_COMMIT = (1 << 0), OSTREE_REPO_TEST_ERROR_INVALID_CACHE = (1 << 1), } OstreeRepoTestErrorFlags; -struct OstreeRepoCommitModifier { - gint refcount; /* atomic */ +struct OstreeRepoCommitModifier +{ + gint refcount; /* atomic */ OstreeRepoCommitModifierFlags flags; OstreeRepoCommitFilter filter; @@ -87,55 +95,63 @@ struct OstreeRepoCommitModifier { GHashTable *devino_cache; }; -typedef enum { +typedef enum +{ OSTREE_REPO_SYSROOT_KIND_UNKNOWN, - OSTREE_REPO_SYSROOT_KIND_NO, /* Not a system repo */ - OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT, /* Constructed via ostree_sysroot_get_repo() */ + OSTREE_REPO_SYSROOT_KIND_NO, /* Not a system repo */ + OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT, /* Constructed via ostree_sysroot_get_repo() */ OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE, /* We match /ostree/repo */ } OstreeRepoSysrootKind; -typedef struct { - GHashTable *refs; /* (element-type utf8 utf8) */ - GHashTable *collection_refs; /* (element-type OstreeCollectionRef utf8) */ +typedef struct +{ + GHashTable *refs; /* (element-type utf8 utf8) */ + GHashTable *collection_refs; /* (element-type OstreeCollectionRef utf8) */ OstreeRepoTransactionStats stats; /* Implementation of min-free-space-percent */ gulong blocksize; fsblkcnt_t max_blocks; + gboolean disable_auto_summary; } OstreeRepoTxn; -typedef struct { - GMutex mutex; /* All other members should only be accessed with this held */ - int fd; /* The open file or flock file descriptor */ - guint shared; /* Number of shared locks curently held */ - guint exclusive; /* Number of exclusive locks currently held */ +typedef struct +{ + GMutex mutex; /* All other members should only be accessed with this held */ + int fd; /* The open file or flock file descriptor */ + guint shared; /* Number of shared locks curently held */ + guint exclusive; /* Number of exclusive locks currently held */ } OstreeRepoLock; -typedef enum { +typedef enum +{ _OSTREE_FEATURE_NO, _OSTREE_FEATURE_MAYBE, _OSTREE_FEATURE_YES, } _OstreeFeatureSupport; /* Possible values for the sysroot.bootloader configuration variable */ -typedef enum { +typedef enum +{ CFG_SYSROOT_BOOTLOADER_OPT_AUTO = 0, CFG_SYSROOT_BOOTLOADER_OPT_NONE, CFG_SYSROOT_BOOTLOADER_OPT_GRUB2, CFG_SYSROOT_BOOTLOADER_OPT_SYSLINUX, CFG_SYSROOT_BOOTLOADER_OPT_UBOOT, CFG_SYSROOT_BOOTLOADER_OPT_ZIPL, + CFG_SYSROOT_BOOTLOADER_OPT_ABOOT, /* Non-exhaustive */ } OstreeCfgSysrootBootloaderOpt; -static const char* const CFG_SYSROOT_BOOTLOADER_OPTS_STR[] = { +#if !defined(__s390x__) +#define CFG_SYSROOT_BOOTLOADER_DEFAULT_STR "auto" +#else +// There's nothing else on s390x. +#define CFG_SYSROOT_BOOTLOADER_DEFAULT_STR "zipl" +#endif + +static const char *const CFG_SYSROOT_BOOTLOADER_OPTS_STR[] = { /* This must be kept in the same order as the enum */ - "auto", - "none", - "grub2", - "syslinux", - "uboot", - "zipl", - NULL, + "auto", "none", "grub2", "syslinux", "uboot", "zipl", "aboot", NULL, }; /** @@ -143,7 +159,8 @@ static const char* const CFG_SYSROOT_BOOTLOADER_OPTS_STR[] = { * * Private instance structure. */ -struct OstreeRepo { +struct OstreeRepo +{ GObject parent; char *stagedir_prefix; @@ -155,10 +172,10 @@ struct OstreeRepo { */ GFile *repodir_fdrel; GFile *repodir; /* May be %NULL if we were opened via ostree_repo_open_at() */ - int repo_dir_fd; - int tmp_dir_fd; - int cache_dir_fd; - char *cache_dir; + int repo_dir_fd; + int tmp_dir_fd; + int cache_dir_fd; + char *cache_dir; int objects_dir_fd; int uncompressed_objects_dir_fd; GFile *sysroot_dir; @@ -172,6 +189,8 @@ struct OstreeRepo { gboolean txn_locked; _OstreeFeatureSupport fs_verity_wanted; _OstreeFeatureSupport fs_verity_supported; + OtTristate composefs_wanted; + gboolean composefs_supported; GMutex cache_lock; guint dirmeta_cache_refcount; @@ -180,6 +199,7 @@ struct OstreeRepo { gboolean inited; gboolean writable; + gboolean is_on_fuse; /* TRUE if the repository is on a FUSE filesystem */ OstreeRepoSysrootKind sysroot_kind; GError *writable_error; gboolean in_transaction; @@ -202,9 +222,9 @@ struct OstreeRepo { /* Cache the repo's device/inode to use for comparisons elsewhere */ dev_t device; ino_t inode; - uid_t owner_uid; /* Cache of repo's owner uid */ + uid_t owner_uid; /* Cache of repo's owner uid */ guint min_free_space_percent; /* See the min-free-space-percent config option */ - guint64 min_free_space_mb; /* See the min-free-space-size config option */ + guint64 min_free_space_mb; /* See the min-free-space-size config option */ guint64 reserved_blocks; gboolean cleanup_stagedir; @@ -224,14 +244,18 @@ struct OstreeRepo { gint fs_support_reflink; /* The underlying filesystem has support for ioctl (FICLONE..) */ gchar **repo_finders; OstreeCfgSysrootBootloaderOpt bootloader; /* Configure which bootloader to use. */ + GHashTable + *bls_append_values; /* Parsed key-values from bls-append-except-default key in config. */ + gboolean enable_bootprefix; /* If true, prepend bootloader entries with /boot */ OstreeRepo *parent_repo; }; -typedef struct { +typedef struct +{ dev_t dev; ino_t ino; - char checksum[OSTREE_SHA256_STRING_LEN+1]; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; } OstreeDevIno; /* A MemoryCacheRef is an in-memory cache of objects (currently just DIRMETA). This can @@ -239,279 +263,165 @@ typedef struct { * the primary use case is ostree_repo_checkout_at() avoiding lots of duplicate dirmeta * lookups. */ -typedef struct { +typedef struct +{ OstreeRepo *repo; } OstreeRepoMemoryCacheRef; +void _ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state, OstreeRepo *repo); -void -_ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state, - OstreeRepo *repo); - -void -_ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state); -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeRepoMemoryCacheRef, _ostree_repo_memory_cache_ref_destroy) +void _ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state); +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeRepoMemoryCacheRef, _ostree_repo_memory_cache_ref_destroy) #define OSTREE_REPO_TMPDIR_STAGING "staging-" -gboolean -_ostree_repo_allocate_tmpdir (int tmpdir_dfd, - const char *tmpdir_prefix, - GLnxTmpDir *tmpdir_out, - GLnxLockFile *file_lock_out, - gboolean * reusing_dir_out, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_has_staging_prefix (const char *filename); - -gboolean -_ostree_repo_try_lock_tmpdir (int tmpdir_dfd, - const char *tmpdir_name, - GLnxLockFile *file_lock_out, - gboolean *out_did_lock, - GError **error); - -gboolean -_ostree_repo_ensure_loose_objdir_at (int dfd, - const char *loose_path, - GCancellable *cancellable, - GError **error); - -GFile * -_ostree_repo_get_commit_metadata_loose_path (OstreeRepo *self, - const char *checksum); - -gboolean -_ostree_repo_has_loose_object (OstreeRepo *self, - const char *checksum, - OstreeObjectType objtype, - gboolean *out_is_stored, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_write_bareuser_metadata (int fd, - guint32 uid, - guint32 gid, - guint32 mode, - GVariant *xattrs, - GError **error); - -gboolean -_ostree_repo_write_directory_meta (OstreeRepo *self, - GFileInfo *file_info, - GVariant *xattrs, - guchar **out_csum, - GCancellable *cancellable, - GError **error); -gboolean -_ostree_repo_update_refs (OstreeRepo *self, - GHashTable *refs, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_update_collection_refs (OstreeRepo *self, - GHashTable *refs, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_file_replace_contents (OstreeRepo *self, - int dfd, - const char *path, - const guint8 *buf, - gsize len, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_write_ref (OstreeRepo *self, - const char *remote, - const OstreeCollectionRef *ref, - const char *rev, - const char *alias, - GCancellable *cancellable, - GError **error); - -OstreeRepoFile * -_ostree_repo_file_new_for_commit (OstreeRepo *repo, - const char *commit, - GError **error); - -OstreeRepoFile * -_ostree_repo_file_new_root (OstreeRepo *repo, - const char *contents_checksum, - const char *metadata_checksum); - -gboolean -_ostree_repo_traverse_dirtree_internal (OstreeRepo *repo, - const char *dirtree_checksum, - int recursion_depth, - GHashTable *inout_reachable, - GHashTable *inout_content_names, - GCancellable *cancellable, - GError **error); - -OstreeRepoCommitFilterResult -_ostree_repo_commit_modifier_apply (OstreeRepo *self, - OstreeRepoCommitModifier *modifier, - const char *path, - GFileInfo *file_info, - GFileInfo **out_modified_info); - -void -_ostree_repo_setup_generate_sizes (OstreeRepo *self, - OstreeRepoCommitModifier *modifier); - -gboolean -_ostree_repo_remote_name_is_file (const char *remote_name); +gboolean _ostree_repo_allocate_tmpdir (int tmpdir_dfd, const char *tmpdir_prefix, + GLnxTmpDir *tmpdir_out, GLnxLockFile *file_lock_out, + gboolean *reusing_dir_out, GCancellable *cancellable, + GError **error); + +gboolean _ostree_repo_has_staging_prefix (const char *filename); + +gboolean _ostree_repo_try_lock_tmpdir (int tmpdir_dfd, const char *tmpdir_name, + GLnxLockFile *file_lock_out, gboolean *out_did_lock, + GError **error); + +gboolean _ostree_repo_ensure_loose_objdir_at (int dfd, const char *loose_path, + GCancellable *cancellable, GError **error); + +GFile *_ostree_repo_get_commit_metadata_loose_path (OstreeRepo *self, const char *checksum); + +gboolean _ostree_repo_has_loose_object (OstreeRepo *self, const char *checksum, + OstreeObjectType objtype, gboolean *out_is_stored, + GCancellable *cancellable, GError **error); + +gboolean _ostree_write_bareuser_metadata (int fd, guint32 uid, guint32 gid, guint32 mode, + GVariant *xattrs, GError **error); + +gboolean _ostree_repo_write_directory_meta (OstreeRepo *self, GFileInfo *file_info, + GVariant *xattrs, guchar **out_csum, + GCancellable *cancellable, GError **error); +gboolean _ostree_repo_update_refs (OstreeRepo *self, GHashTable *refs, GCancellable *cancellable, + GError **error); + +gboolean _ostree_repo_update_collection_refs (OstreeRepo *self, GHashTable *refs, + GCancellable *cancellable, GError **error); + +gboolean _ostree_repo_file_replace_contents (OstreeRepo *self, int dfd, const char *path, + const guint8 *buf, gsize len, + GCancellable *cancellable, GError **error); + +gboolean _ostree_repo_write_ref (OstreeRepo *self, const char *remote, + const OstreeCollectionRef *ref, const char *rev, const char *alias, + GCancellable *cancellable, GError **error); + +OstreeRepoFile *_ostree_repo_file_new_for_commit (OstreeRepo *repo, const char *commit, + GError **error); + +OstreeRepoFile *_ostree_repo_file_new_root (OstreeRepo *repo, const char *contents_checksum, + const char *metadata_checksum); + +gboolean _ostree_repo_traverse_dirtree_internal (OstreeRepo *repo, const char *dirtree_checksum, + int recursion_depth, GHashTable *inout_reachable, + GHashTable *inout_content_names, + GCancellable *cancellable, GError **error); + +OstreeRepoCommitFilterResult _ostree_repo_commit_modifier_apply (OstreeRepo *self, + OstreeRepoCommitModifier *modifier, + const char *path, + GFileInfo *file_info, + GFileInfo **out_modified_info); + +void _ostree_repo_setup_generate_sizes (OstreeRepo *self, OstreeRepoCommitModifier *modifier); + +gboolean _ostree_repo_remote_name_is_file (const char *remote_name); #ifndef OSTREE_DISABLE_GPGME -OstreeGpgVerifyResult * -_ostree_repo_gpg_verify_with_metadata (OstreeRepo *self, - GBytes *signed_data, - GVariant *metadata, - const char *remote_name, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error); - -OstreeGpgVerifyResult * -_ostree_repo_verify_commit_internal (OstreeRepo *self, - const char *commit_checksum, - const char *remote_name, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error); +OstreeGpgVerifyResult *_ostree_repo_gpg_verify_with_metadata ( + OstreeRepo *self, GBytes *signed_data, GVariant *metadata, const char *remote_name, + GFile *keyringdir, GFile *extra_keyring, GCancellable *cancellable, GError **error); + +OstreeGpgVerifyResult *_ostree_repo_verify_commit_internal ( + OstreeRepo *self, const char *commit_checksum, const char *remote_name, GFile *keyringdir, + GFile *extra_keyring, GCancellable *cancellable, GError **error); #endif /* OSTREE_DISABLE_GPGME */ -typedef enum { +typedef enum +{ _OSTREE_REPO_IMPORT_FLAGS_NONE = 0, _OSTREE_REPO_IMPORT_FLAGS_TRUSTED = (1 << 0), _OSTREE_REPO_IMPORT_FLAGS_VERIFY_BAREUSERONLY = (1 << 1), } OstreeRepoImportFlags; -gboolean -_ostree_repo_import_object (OstreeRepo *self, - OstreeRepo *source, - OstreeObjectType objtype, - const char *checksum, - OstreeRepoImportFlags flags, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_commit_tmpf_final (OstreeRepo *self, - const char *checksum, - OstreeObjectType objtype, - GLnxTmpfile *tmpf, - GCancellable *cancellable, - GError **error); - -typedef struct { +gboolean _ostree_repo_import_object (OstreeRepo *self, OstreeRepo *source, OstreeObjectType objtype, + const char *checksum, OstreeRepoImportFlags flags, + GCancellable *cancellable, GError **error); + +gboolean _ostree_repo_commit_tmpf_final (OstreeRepo *self, const char *checksum, + OstreeObjectType objtype, GLnxTmpfile *tmpf, + GCancellable *cancellable, GError **error); + +typedef struct +{ gboolean initialized; gpointer opaque0[10]; guint opaque1[10]; } OstreeRepoBareContent; void _ostree_repo_bare_content_cleanup (OstreeRepoBareContent *regwrite); -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeRepoBareContent, _ostree_repo_bare_content_cleanup) - -gboolean -_ostree_repo_bare_content_open (OstreeRepo *self, - const char *checksum, - guint64 content_len, - guint uid, - guint gid, - guint mode, - GVariant *xattrs, - OstreeRepoBareContent *out_regwrite, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_bare_content_write (OstreeRepo *repo, - OstreeRepoBareContent *barewrite, - const guint8 *buf, - size_t len, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_bare_content_commit (OstreeRepo *self, - OstreeRepoBareContent *barewrite, - char *checksum_buf, - size_t buflen, - GCancellable *cancellable, - GError **error); - -OstreeContentWriter * -_ostree_content_writer_new (OstreeRepo *repo, - const char *checksum, - guint uid, - guint gid, - guint mode, - guint64 content_len, - GVariant *xattrs, - GError **error); - -gboolean -_ostree_repo_load_file_bare (OstreeRepo *self, - const char *checksum, - int *out_fd, - struct stat *out_stbuf, - char **out_symlink, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_update_mtime (OstreeRepo *self, - GError **error); - -gboolean -_ostree_repo_add_remote (OstreeRepo *self, - OstreeRemote *remote); -gboolean -_ostree_repo_remove_remote (OstreeRepo *self, - OstreeRemote *remote); -OstreeRemote * -_ostree_repo_get_remote (OstreeRepo *self, - const char *name, - GError **error); -OstreeRemote * -_ostree_repo_get_remote_inherited (OstreeRepo *self, - const char *name, - GError **error); - -gboolean -_ostree_repo_maybe_regenerate_summary (OstreeRepo *self, - GCancellable *cancellable, - GError **error); +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeRepoBareContent, _ostree_repo_bare_content_cleanup) + +gboolean _ostree_repo_bare_content_open (OstreeRepo *self, const char *checksum, + guint64 content_len, guint uid, guint gid, guint mode, + GVariant *xattrs, OstreeRepoBareContent *out_regwrite, + GCancellable *cancellable, GError **error); + +gboolean _ostree_repo_bare_content_write (OstreeRepo *repo, OstreeRepoBareContent *barewrite, + const guint8 *buf, size_t len, GCancellable *cancellable, + GError **error); + +gboolean _ostree_repo_bare_content_commit (OstreeRepo *self, OstreeRepoBareContent *barewrite, + char *checksum_buf, size_t buflen, + GCancellable *cancellable, GError **error); + +OstreeContentWriter *_ostree_content_writer_new (OstreeRepo *repo, const char *checksum, guint uid, + guint gid, guint mode, guint64 content_len, + GVariant *xattrs, GError **error); + +gboolean _ostree_repo_load_file_bare (OstreeRepo *self, const char *checksum, int *out_fd, + struct stat *out_stbuf, char **out_symlink, + GVariant **out_xattrs, GCancellable *cancellable, + GError **error); + +gboolean _ostree_repo_update_mtime (OstreeRepo *self, GError **error); + +gboolean _ostree_repo_add_remote (OstreeRepo *self, OstreeRemote *remote); +gboolean _ostree_repo_remove_remote (OstreeRepo *self, OstreeRemote *remote); +OstreeRemote *_ostree_repo_get_remote (OstreeRepo *self, const char *name, GError **error); +OstreeRemote *_ostree_repo_get_remote_inherited (OstreeRepo *self, const char *name, + GError **error); +gboolean _ostree_repo_maybe_regenerate_summary (OstreeRepo *self, GCancellable *cancellable, + GError **error); gboolean _ostree_repo_parse_fsverity_config (OstreeRepo *self, GError **error); +gboolean _ostree_repo_parse_composefs_config (OstreeRepo *self, GError **error); -gboolean -_ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf, - _OstreeFeatureSupport fsverity_requested, - gboolean *supported, - GError **error); +gboolean _ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf, _OstreeFeatureSupport fsverity_requested, + GBytes *signature, gboolean *supported, GError **error); -gboolean -_ostree_tmpf_fsverity (OstreeRepo *self, - GLnxTmpfile *tmpf, - GError **error); +gboolean _ostree_tmpf_fsverity (OstreeRepo *self, GLnxTmpfile *tmpf, GBytes *signature, + GError **error); -gboolean -_ostree_repo_verify_bindings (const char *collection_id, - const char *ref_name, - GVariant *commit, - GError **error); +gboolean _ostree_repo_verify_bindings (const char *collection_id, const char *ref_name, + GVariant *commit, GError **error); + +GHashTable *ostree_repo_list_objects_set (OstreeRepo *self, OstreeRepoListObjectsFlags flags, + GCancellable *cancellable, GError **error); + +gboolean _ostree_repo_transaction_write_repo_metadata (OstreeRepo *self, + GVariant *additional_metadata, + char **out_checksum, + GCancellable *cancellable, GError **error); /** * OstreeRepoAutoTransaction: @@ -529,26 +439,18 @@ typedef struct } OstreeRepoAutoTransaction; OstreeRepoAutoTransaction * -_ostree_repo_auto_transaction_start (OstreeRepo *repo, - GCancellable *cancellable, - GError **error); +_ostree_repo_auto_transaction_start (OstreeRepo *repo, GCancellable *cancellable, GError **error); -gboolean -_ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction *txn, - GCancellable *cancellable, - GError **error); +gboolean _ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction *txn, + GCancellable *cancellable, GError **error); -gboolean -_ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction *txn, - OstreeRepoTransactionStats *out_stats, - GCancellable *cancellable, - GError **error); +gboolean _ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction *txn, + OstreeRepoTransactionStats *out_stats, + GCancellable *cancellable, GError **error); -OstreeRepoAutoTransaction * -_ostree_repo_auto_transaction_ref (OstreeRepoAutoTransaction *txn); +OstreeRepoAutoTransaction *_ostree_repo_auto_transaction_ref (OstreeRepoAutoTransaction *txn); -void -_ostree_repo_auto_transaction_unref (OstreeRepoAutoTransaction *txn); +void _ostree_repo_auto_transaction_unref (OstreeRepoAutoTransaction *txn); GType _ostree_repo_auto_transaction_get_type (void); @@ -558,4 +460,20 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoTransaction, _ostree_repo_auto_tran * should not be made into public API, even if the rest is */ OstreeRepoAutoTransaction *_ostree_repo_auto_transaction_new (OstreeRepo *repo); +typedef struct OstreeComposefsTarget OstreeComposefsTarget; + +GType ostree_composefs_target_get_type (void) G_GNUC_CONST; +OstreeComposefsTarget *ostree_composefs_target_new (void); +OstreeComposefsTarget *ostree_composefs_target_ref (OstreeComposefsTarget *target); +void ostree_composefs_target_unref (OstreeComposefsTarget *target); +gboolean ostree_composefs_target_write (OstreeComposefsTarget *target, int fd, + guchar **out_fsverity_digest, GCancellable *cancellable, + GError **error); + +gboolean ostree_repo_checkout_composefs (OstreeRepo *self, OstreeComposefsTarget *target, + OstreeRepoFile *source, GCancellable *cancellable, + GError **error); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeComposefsTarget, ostree_composefs_target_unref) + G_END_DECLS diff --git a/src/libostree/ostree-repo-prune.c b/src/libostree/ostree-repo-prune.c index 0c702dc..5817859 100644 --- a/src/libostree/ostree-repo-prune.c +++ b/src/libostree/ostree-repo-prune.c @@ -21,12 +21,13 @@ #include "config.h" +#include "ostree-autocleanups.h" #include "ostree-core-private.h" #include "ostree-repo-private.h" -#include "ostree-autocleanups.h" #include "otutil.h" -typedef struct { +typedef struct +{ OstreeRepo *repo; GHashTable *reachable; guint n_reachable_meta; @@ -37,11 +38,8 @@ typedef struct { } OtPruneData; static gboolean -maybe_prune_loose_object (OtPruneData *data, - OstreeRepoPruneFlags flags, - GVariant *key, - GCancellable *cancellable, - GError **error) +maybe_prune_loose_object (OtPruneData *data, OstreeRepoPruneFlags flags, GVariant *key, + GCancellable *cancellable, GError **error) { gboolean reachable = FALSE; const char *checksum; @@ -59,11 +57,10 @@ maybe_prune_loose_object (OtPruneData *data, { guint64 storage_size = 0; - g_debug ("Pruning unneeded object %s.%s", checksum, - ostree_object_type_to_string (objtype)); + g_debug ("Pruning unneeded object %s.%s", checksum, ostree_object_type_to_string (objtype)); - if (!ostree_repo_query_object_storage_size (data->repo, objtype, checksum, - &storage_size, cancellable, error)) + if (!ostree_repo_query_object_storage_size (data->repo, objtype, checksum, &storage_size, + cancellable, error)) return FALSE; data->freed_bytes += storage_size; @@ -74,26 +71,31 @@ maybe_prune_loose_object (OtPruneData *data, { ssize_t size; char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; - char target_checksum[OSTREE_SHA256_STRING_LEN+1]; + char target_checksum[OSTREE_SHA256_STRING_LEN + 1]; char target_buf[_OSTREE_LOOSE_PATH_MAX + _OSTREE_PAYLOAD_LINK_PREFIX_LEN]; - _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, data->repo->mode); - size = readlinkat (data->repo->objects_dir_fd, loose_path_buf, target_buf, sizeof (target_buf)); + _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, + data->repo->mode); + size = readlinkat (data->repo->objects_dir_fd, loose_path_buf, target_buf, + sizeof (target_buf)); if (size < 0) return glnx_throw_errno_prefix (error, "readlinkat"); if (size < OSTREE_SHA256_STRING_LEN + _OSTREE_PAYLOAD_LINK_PREFIX_LEN) return glnx_throw (error, "invalid data size for %s", loose_path_buf); - sprintf (target_checksum, "%.2s%.62s", target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN, target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN + 3); + sprintf (target_checksum, "%.2s%.62s", target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN, + target_buf + _OSTREE_PAYLOAD_LINK_PREFIX_LEN + 3); - g_autoptr(GVariant) target_key = ostree_object_name_serialize (target_checksum, OSTREE_OBJECT_TYPE_FILE); + g_autoptr (GVariant) target_key + = ostree_object_name_serialize (target_checksum, OSTREE_OBJECT_TYPE_FILE); if (g_hash_table_lookup_extended (data->reachable, target_key, NULL, NULL)) { guint64 target_storage_size = 0; - if (!ostree_repo_query_object_storage_size (data->repo, OSTREE_OBJECT_TYPE_FILE, target_checksum, - &target_storage_size, cancellable, error)) + if (!ostree_repo_query_object_storage_size (data->repo, OSTREE_OBJECT_TYPE_FILE, + target_checksum, &target_storage_size, + cancellable, error)) return FALSE; reachable = target_storage_size >= data->repo->payload_link_threshold; @@ -107,10 +109,8 @@ maybe_prune_loose_object (OtPruneData *data, return FALSE; } - if (!ostree_repo_delete_object (data->repo, objtype, checksum, - cancellable, error)) + if (!ostree_repo_delete_object (data->repo, objtype, checksum, cancellable, error)) return FALSE; - } if (OSTREE_OBJECT_TYPE_IS_META (objtype)) @@ -119,17 +119,16 @@ maybe_prune_loose_object (OtPruneData *data, data->n_unreachable_content++; } - exit: +exit: if (reachable) { - g_debug ("Keeping needed object %s.%s", checksum, - ostree_object_type_to_string (objtype)); + g_debug ("Keeping needed object %s.%s", checksum, ostree_object_type_to_string (objtype)); if (OSTREE_OBJECT_TYPE_IS_META (objtype)) data->n_reachable_meta++; else data->n_reachable_content++; } - if (commit_only && (objtype != OSTREE_OBJECT_TYPE_COMMIT)) + if (commit_only && (objtype != OSTREE_OBJECT_TYPE_COMMIT)) { g_debug ("Keeping object (not commit) %s.%s", checksum, ostree_object_type_to_string (objtype)); @@ -138,17 +137,17 @@ maybe_prune_loose_object (OtPruneData *data, } static gboolean -_ostree_repo_prune_tmp (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +_ostree_repo_prune_tmp (OstreeRepo *self, GCancellable *cancellable, GError **error) { if (self->cache_dir_fd == -1) return TRUE; - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; gboolean exists; - if (!ot_dfd_iter_init_allow_noent (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, - &dfd_iter, &exists, error)) + if (!ot_dfd_iter_init_allow_noent (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, &dfd_iter, + &exists, error)) return FALSE; /* Note early return */ if (!exists) @@ -189,7 +188,6 @@ _ostree_repo_prune_tmp (OstreeRepo *self, return TRUE; } - /** * ostree_repo_prune_static_deltas: * @self: Repo @@ -205,18 +203,16 @@ _ostree_repo_prune_tmp (OstreeRepo *self, * Locking: exclusive */ gboolean -ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, - GCancellable *cancellable, - GError **error) +ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, GCancellable *cancellable, + GError **error) { - g_autoptr(OstreeRepoAutoLock) lock = - ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; - g_autoptr(GPtrArray) deltas = NULL; - if (!ostree_repo_list_static_delta_names (self, &deltas, - cancellable, error)) + g_autoptr (GPtrArray) deltas = NULL; + if (!ostree_repo_list_static_delta_names (self, &deltas, cancellable, error)) return FALSE; for (guint i = 0; i < deltas->len; i++) @@ -244,8 +240,7 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, else { gboolean have_commit; - if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, - to, &have_commit, + if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, to, &have_commit, cancellable, error)) return FALSE; @@ -255,8 +250,7 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, g_debug ("Trying to prune static delta %s", deltaname); g_autofree char *deltadir = _ostree_get_relative_static_delta_path (from, to, NULL); - if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir, - cancellable, error)) + if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir, cancellable, error)) return FALSE; } @@ -264,33 +258,23 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, } static gboolean -repo_prune_internal (OstreeRepo *self, - GHashTable *objects, - OstreeRepoPruneOptions *options, - gint *out_objects_total, - gint *out_objects_pruned, - guint64 *out_pruned_object_size_total, - GCancellable *cancellable, - GError **error) +repo_prune_internal (OstreeRepo *self, GHashTable *objects, OstreeRepoPruneOptions *options, + gint *out_objects_total, gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, GCancellable *cancellable, + GError **error) { - OtPruneData data = { 0, }; + OtPruneData data = { + 0, + }; data.repo = self; /* We unref this when we're done */ - g_autoptr(GHashTable) reachable_owned = g_hash_table_ref (options->reachable); + g_autoptr (GHashTable) reachable_owned = g_hash_table_ref (options->reachable); data.reachable = reachable_owned; - GLNX_HASH_TABLE_FOREACH_KV (objects, GVariant*, serialized_key, GVariant*, objdata) + GLNX_HASH_TABLE_FOREACH (objects, GVariant *, serialized_key) { - gboolean is_loose; - - g_variant_get_child (objdata, 0, "b", &is_loose); - - if (!is_loose) - continue; - - if (!maybe_prune_loose_object (&data, options->flags, serialized_key, - cancellable, error)) + if (!maybe_prune_loose_object (&data, options->flags, serialized_key, cancellable, error)) return FALSE; } @@ -300,53 +284,49 @@ repo_prune_internal (OstreeRepo *self, if (!_ostree_repo_prune_tmp (self, cancellable, error)) return FALSE; - *out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta + - data.n_reachable_content + data.n_unreachable_content); + *out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta + data.n_reachable_content + + data.n_unreachable_content); *out_objects_pruned = (data.n_unreachable_meta + data.n_unreachable_content); *out_pruned_object_size_total = data.freed_bytes; return TRUE; } static gboolean -traverse_reachable_internal (OstreeRepo *self, - OstreeRepoCommitTraverseFlags flags, - guint depth, - GHashTable *reachable, - GCancellable *cancellable, - GError **error) +traverse_reachable_internal (OstreeRepo *self, OstreeRepoCommitTraverseFlags flags, guint depth, + GHashTable *reachable, GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepoAutoLock) lock = - ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_SHARED, cancellable, error); + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_SHARED, cancellable, error); if (!lock) return FALSE; /* Ignoring collections. */ - g_autoptr(GHashTable) all_refs = NULL; /* (element-type utf8 utf8) */ + g_autoptr (GHashTable) all_refs = NULL; /* (element-type utf8 utf8) */ - if (!ostree_repo_list_refs (self, NULL, &all_refs, - cancellable, error)) + if (!ostree_repo_list_refs (self, NULL, &all_refs, cancellable, error)) return FALSE; - GLNX_HASH_TABLE_FOREACH_V (all_refs, const char*, checksum) + GLNX_HASH_TABLE_FOREACH_V (all_refs, const char *, checksum) { g_debug ("Finding objects to keep for commit %s", checksum); - if (!ostree_repo_traverse_commit_with_flags (self, flags, checksum, depth, reachable, - NULL, cancellable, error)) + if (!ostree_repo_traverse_commit_with_flags (self, flags, checksum, depth, reachable, NULL, + cancellable, error)) return FALSE; } /* Using collections. */ - g_autoptr(GHashTable) all_collection_refs = NULL; /* (element-type OstreeChecksumRef utf8) */ + g_autoptr (GHashTable) all_collection_refs = NULL; /* (element-type OstreeChecksumRef utf8) */ if (!ostree_repo_list_collection_refs (self, NULL, &all_collection_refs, - OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, cancellable, error)) + OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, cancellable, + error)) return FALSE; - GLNX_HASH_TABLE_FOREACH_V (all_collection_refs, const char*, checksum) + GLNX_HASH_TABLE_FOREACH_V (all_collection_refs, const char *, checksum) { g_debug ("Finding objects to keep for commit %s", checksum); - if (!ostree_repo_traverse_commit_with_flags (self, flags, checksum, depth, reachable, - NULL, cancellable, error)) + if (!ostree_repo_traverse_commit_with_flags (self, flags, checksum, depth, reachable, NULL, + cancellable, error)) return FALSE; } @@ -367,15 +347,10 @@ traverse_reachable_internal (OstreeRepo *self, * Since: 2018.6 */ gboolean -ostree_repo_traverse_reachable_refs (OstreeRepo *self, - guint depth, - GHashTable *reachable, - GCancellable *cancellable, - GError **error) +ostree_repo_traverse_reachable_refs (OstreeRepo *self, guint depth, GHashTable *reachable, + GCancellable *cancellable, GError **error) { - return traverse_reachable_internal (self, - OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, - depth, reachable, + return traverse_reachable_internal (self, OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, depth, reachable, cancellable, error); } @@ -407,25 +382,20 @@ ostree_repo_traverse_reachable_refs (OstreeRepo *self, * Locking: exclusive */ gboolean -ostree_repo_prune (OstreeRepo *self, - OstreeRepoPruneFlags flags, - gint depth, - gint *out_objects_total, - gint *out_objects_pruned, - guint64 *out_pruned_object_size_total, - GCancellable *cancellable, - GError **error) +ostree_repo_prune (OstreeRepo *self, OstreeRepoPruneFlags flags, gint depth, + gint *out_objects_total, gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepoAutoLock) lock = - ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; - g_autoptr(GHashTable) objects = NULL; + g_autoptr (GHashTable) objects = NULL; gboolean refs_only = flags & OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY; gboolean commit_only = flags & OSTREE_REPO_PRUNE_FLAGS_COMMIT_ONLY; - g_autoptr(GHashTable) reachable = ostree_repo_traverse_new_reachable (); + g_autoptr (GHashTable) reachable = ostree_repo_traverse_new_reachable (); /* This original prune API has fixed logic for traversing refs or all commits * combined with actually deleting content. The newer backend API just does @@ -438,19 +408,28 @@ ostree_repo_prune (OstreeRepo *self, if (refs_only) { - if (!traverse_reachable_internal (self, traverse_flags, - depth, reachable, - cancellable, error)) + if (!traverse_reachable_internal (self, traverse_flags, depth, reachable, cancellable, error)) return FALSE; } - if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, - &objects, cancellable, error)) + if (commit_only) + { + if (!ostree_repo_list_commit_objects_starting_with (self, "", &objects, cancellable, error)) + return FALSE; + } + else + { + objects = ostree_repo_list_objects_set ( + self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, cancellable, + error); + } + + if (!objects) return FALSE; if (!refs_only) { - GLNX_HASH_TABLE_FOREACH (objects, GVariant*, serialized_key) + GLNX_HASH_TABLE_FOREACH (objects, GVariant *, serialized_key) { const char *checksum; OstreeObjectType objtype; @@ -461,15 +440,15 @@ ostree_repo_prune (OstreeRepo *self, continue; g_debug ("Finding objects to keep for commit %s", checksum); - if (!ostree_repo_traverse_commit_with_flags (self, traverse_flags, checksum, depth, reachable, - NULL, cancellable, error)) + if (!ostree_repo_traverse_commit_with_flags (self, traverse_flags, checksum, depth, + reachable, NULL, cancellable, error)) return FALSE; } } - { OstreeRepoPruneOptions opts = { flags, reachable }; - return repo_prune_internal (self, objects, &opts, - out_objects_total, out_objects_pruned, + { + OstreeRepoPruneOptions opts = { flags, reachable }; + return repo_prune_internal (self, objects, &opts, out_objects_total, out_objects_pruned, out_pruned_object_size_total, cancellable, error); } } @@ -501,26 +480,33 @@ ostree_repo_prune (OstreeRepo *self, * Since: 2017.1 */ gboolean -ostree_repo_prune_from_reachable (OstreeRepo *self, - OstreeRepoPruneOptions *options, - gint *out_objects_total, - gint *out_objects_pruned, - guint64 *out_pruned_object_size_total, - GCancellable *cancellable, - GError **error) +ostree_repo_prune_from_reachable (OstreeRepo *self, OstreeRepoPruneOptions *options, + gint *out_objects_total, gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, GCancellable *cancellable, + GError **error) { - g_autoptr(OstreeRepoAutoLock) lock = - ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; - g_autoptr(GHashTable) objects = NULL; - - if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, - &objects, cancellable, error)) + g_autoptr (GHashTable) objects = NULL; + OstreeRepoPruneFlags flags = options->flags; + gboolean commit_only = (flags & OSTREE_REPO_PRUNE_FLAGS_COMMIT_ONLY) > 0; + if (commit_only) + { + if (!ostree_repo_list_commit_objects_starting_with (self, "", &objects, cancellable, error)) + return FALSE; + } + else + { + objects = ostree_repo_list_objects_set ( + self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, cancellable, + error); + } + if (!objects) return FALSE; - return repo_prune_internal (self, objects, options, out_objects_total, - out_objects_pruned, out_pruned_object_size_total, - cancellable, error); + return repo_prune_internal (self, objects, options, out_objects_total, out_objects_pruned, + out_pruned_object_size_total, cancellable, error); } diff --git a/src/libostree/ostree-repo-pull-private.h b/src/libostree/ostree-repo-pull-private.h index 6ee7ba0..a4781bf 100644 --- a/src/libostree/ostree-repo-pull-private.h +++ b/src/libostree/ostree-repo-pull-private.h @@ -19,159 +19,154 @@ #pragma once -#include "ostree-repo-private.h" #include "ostree-fetcher-util.h" #include "ostree-remote-private.h" +#include "ostree-repo-private.h" G_BEGIN_DECLS -typedef enum { +typedef enum +{ OSTREE_FETCHER_SECURITY_STATE_CA_PINNED, OSTREE_FETCHER_SECURITY_STATE_TLS, OSTREE_FETCHER_SECURITY_STATE_INSECURE, } OstreeFetcherSecurityState; -typedef struct { - OstreeRepo *repo; - int tmpdir_dfd; +typedef struct +{ + OstreeRepo *repo; + int tmpdir_dfd; OstreeRepoPullFlags flags; - char *remote_name; - char *remote_refspec_name; + char *remote_name; + char *remote_refspec_name; OstreeRepoMode remote_mode; OstreeFetcher *fetcher; OstreeFetcherSecurityState fetcher_security_state; - GPtrArray *meta_mirrorlist; /* List of base URIs for fetching metadata */ - GPtrArray *content_mirrorlist; /* List of base URIs for fetching content */ - OstreeRepo *remote_repo_local; - GPtrArray *localcache_repos; /* Array */ + GPtrArray *meta_mirrorlist; /* List of base URIs for fetching metadata */ + GPtrArray *content_mirrorlist; /* List of base URIs for fetching content */ + OstreeRepo *remote_repo_local; + GPtrArray *localcache_repos; /* Array */ - GMainContext *main_context; + GMainContext *main_context; GCancellable *cancellable; OstreeAsyncProgress *progress; - GVariant *extra_headers; - char *append_user_agent; - - gboolean dry_run; - gboolean dry_run_emitted_progress; - gboolean legacy_transaction_resuming; - guint n_network_retries; - enum { + GVariant *extra_headers; + char *append_user_agent; + guint32 low_speed_limit; + guint32 low_speed_time; + gboolean retry_all; + guint32 max_outstanding_fetcher_requests; + + gboolean dry_run; + gboolean dry_run_emitted_progress; + gboolean legacy_transaction_resuming; + guint n_network_retries; + enum + { OSTREE_PULL_PHASE_FETCHING_REFS, OSTREE_PULL_PHASE_FETCHING_OBJECTS - } phase; - gint n_scanned_metadata; - - gboolean gpg_verify; - gboolean gpg_verify_summary; - gboolean require_static_deltas; - gboolean disable_static_deltas; - gboolean has_tombstone_commits; - gboolean disable_verify_bindings; - - GBytes *summary_data; - char *summary_etag; - guint64 summary_last_modified; /* seconds since the epoch */ - GBytes *summary_data_sig; - char *summary_sig_etag; - guint64 summary_sig_last_modified; /* seconds since the epoch */ - GVariant *summary; - GHashTable *summary_deltas_checksums; /* Filled from summary and delta indexes */ - gboolean summary_has_deltas; /* True if the summary existed and had a delta index */ - gboolean has_indexed_deltas; - GHashTable *ref_original_commits; /* Maps checksum to commit, used by timestamp checks */ - GHashTable *verified_commits; /* Set of commits that have been verified */ - GHashTable *signapi_verified_commits; /* Map of commits that have been signapi verified */ - GHashTable *ref_keyring_map; /* Maps OstreeCollectionRef to keyring remote name */ - GPtrArray *static_delta_superblocks; - GHashTable *expected_commit_sizes; /* Maps commit checksum to known size */ - GHashTable *commit_to_depth; /* Maps parent commit checksum maximum depth */ - GHashTable *scanned_metadata; /* Maps object name to itself */ - GHashTable *fetched_detached_metadata; /* Map */ - GHashTable *requested_metadata; /* Maps object name to itself */ - GHashTable *requested_content; /* Maps checksum to itself */ - GHashTable *requested_fallback_content; /* Maps checksum to itself */ - GHashTable *pending_fetch_metadata; /* Map */ - GHashTable *pending_fetch_content; /* Map */ - GHashTable *pending_fetch_delta_indexes; /* Set */ - GHashTable *pending_fetch_delta_superblocks; /* Set */ - GHashTable *pending_fetch_deltaparts; /* Set */ - guint n_outstanding_metadata_fetches; - guint n_outstanding_metadata_write_requests; - guint n_outstanding_content_fetches; - guint n_outstanding_content_write_requests; - guint n_outstanding_deltapart_fetches; - guint n_outstanding_deltapart_write_requests; - guint n_total_deltaparts; - guint n_total_delta_fallbacks; - guint64 fetched_deltapart_size; /* How much of the delta we have now */ - guint64 total_deltapart_size; - guint64 total_deltapart_usize; - gint n_requested_metadata; - gint n_requested_content; - guint n_fetched_deltaparts; - guint n_fetched_deltapart_fallbacks; - guint n_fetched_metadata; - guint n_fetched_content; + } phase; + gint n_scanned_metadata; + + gboolean gpg_verify; + gboolean gpg_verify_summary; + gboolean require_static_deltas; + gboolean disable_static_deltas; + gboolean has_tombstone_commits; + gboolean disable_verify_bindings; + + GBytes *summary_data; + char *summary_etag; + guint64 summary_last_modified; /* seconds since the epoch */ + GBytes *summary_data_sig; + char *summary_sig_etag; + guint64 summary_sig_last_modified; /* seconds since the epoch */ + GVariant *summary; + GHashTable *summary_deltas_checksums; /* Filled from summary and delta indexes */ + gboolean summary_has_deltas; /* True if the summary existed and had a delta index */ + gboolean has_indexed_deltas; + GHashTable *ref_original_commits; /* Maps checksum to commit, used by timestamp checks */ + GHashTable *verified_commits; /* Set of commits that have been verified */ + GHashTable *signapi_verified_commits; /* Map of commits that have been + signapi verified */ + GHashTable *ref_keyring_map; /* Maps OstreeCollectionRef to keyring remote name */ + + GHashTable *static_delta_targets; /* Set of commits fetched via static delta */ + + GHashTable *expected_commit_sizes; /* Maps commit checksum to known size */ + GHashTable *commit_to_depth; /* Maps parent commit checksum maximum depth */ + GHashTable *scanned_metadata; /* Maps object name to itself */ + GHashTable *fetched_detached_metadata; /* Map */ + GHashTable *requested_metadata; /* Maps object name to itself */ + GHashTable *requested_content; /* Maps checksum to itself */ + GHashTable *requested_fallback_content; /* Maps checksum to itself */ + GHashTable *pending_fetch_metadata; /* Map */ + GHashTable *pending_fetch_content; /* Map */ + GHashTable *pending_fetch_delta_indexes; /* Set */ + GHashTable *pending_fetch_delta_superblocks; /* Set */ + GHashTable *pending_fetch_deltaparts; /* Set */ + guint n_outstanding_metadata_fetches; + guint n_outstanding_metadata_write_requests; + guint n_outstanding_content_fetches; + guint n_outstanding_content_write_requests; + guint n_outstanding_deltapart_fetches; + guint n_outstanding_deltapart_write_requests; + guint n_total_deltaparts; + guint n_total_delta_fallbacks; + guint64 fetched_deltapart_size; /* How much of the delta we have now */ + guint64 total_deltapart_size; + guint64 total_deltapart_usize; + gint n_requested_metadata; + gint n_requested_content; + guint n_fetched_deltaparts; + guint n_fetched_deltapart_fallbacks; + guint n_fetched_metadata; + guint n_fetched_content; /* Objects imported via hardlink/reflink/copying or --localcache-repo*/ - guint n_imported_metadata; - guint n_imported_content; - - gboolean timestamp_check; /* Verify commit timestamps */ - char *timestamp_check_from_rev; - int maxdepth; - guint64 max_metadata_size; - guint64 start_time; - - gboolean is_mirror; - gboolean trusted_http_direct; - gboolean is_commit_only; + guint n_imported_metadata; + guint n_imported_content; + + gboolean timestamp_check; /* Verify commit timestamps */ + char *timestamp_check_from_rev; + int maxdepth; + guint64 max_metadata_size; + guint64 start_time; + + gboolean is_mirror; + gboolean trusted_http_direct; + gboolean is_commit_only; OstreeRepoImportFlags importflags; - GPtrArray *signapi_commit_verifiers; - GPtrArray *signapi_summary_verifiers; + GPtrArray *signapi_commit_verifiers; + GPtrArray *signapi_summary_verifiers; - GPtrArray *dirs; + GPtrArray *dirs; - gboolean have_previous_bytes; - guint64 previous_bytes_sec; - guint64 previous_total_downloaded; + gboolean have_previous_bytes; + guint64 previous_bytes_sec; + guint64 previous_total_downloaded; - GError *cached_async_error; - GError **async_error; - gboolean caught_error; + GError *cached_async_error; + GError **async_error; + gboolean caught_error; GQueue scan_object_queue; GSource *idle_src; } OtPullData; -gboolean -_signapi_init_for_remote (OstreeRepo *repo, - const char *remote_name, - GPtrArray **out_commit_verifiers, - GPtrArray **out_summary_verifiers, - GError **error); -gboolean -_sign_verify_for_remote (GPtrArray *signers, - GBytes *signed_data, - GVariant *metadata, - char **out_success_message, - GError **error); - -gboolean -_verify_unwritten_commit (OtPullData *pull_data, - const char *checksum, - GVariant *commit, - GVariant *detached_metadata, - const OstreeCollectionRef *ref, - GCancellable *cancellable, - GError **error); - -gboolean -_process_gpg_verify_result (OtPullData *pull_data, - const char *checksum, - OstreeGpgVerifyResult *result, - GError **error); +gboolean _signapi_init_for_remote (OstreeRepo *repo, const char *remote_name, + GPtrArray **out_commit_verifiers, + GPtrArray **out_summary_verifiers, GError **error); +gboolean _sign_verify_for_remote (GPtrArray *signers, GBytes *signed_data, GVariant *metadata, + char **out_success_message, GError **error); + +gboolean _verify_unwritten_commit (OtPullData *pull_data, const char *checksum, GVariant *commit, + GVariant *detached_metadata, const OstreeCollectionRef *ref, + GCancellable *cancellable, GError **error); + +gboolean _process_gpg_verify_result (OtPullData *pull_data, const char *checksum, + OstreeGpgVerifyResult *result, GError **error); G_END_DECLS diff --git a/src/libostree/ostree-repo-pull-verify.c b/src/libostree/ostree-repo-pull-verify.c index 8989d66..9f4d214 100644 --- a/src/libostree/ostree-repo-pull-verify.c +++ b/src/libostree/ostree-repo-pull-verify.c @@ -21,16 +21,16 @@ #include "config.h" #include "libglnx.h" +#include "ostree-repo-private.h" +#include "ostree-repo-pull-private.h" #include "ostree.h" #include "otutil.h" -#include "ostree-repo-pull-private.h" -#include "ostree-repo-private.h" #include "ostree-core-private.h" -#include "ostree-repo-static-delta-private.h" -#include "ostree-metalink.h" #include "ostree-fetcher-util.h" +#include "ostree-metalink.h" #include "ostree-remote-private.h" +#include "ostree-repo-static-delta-private.h" #include "ot-fs-utils.h" #include @@ -42,14 +42,11 @@ #include "ostree-sign.h" static gboolean -get_signapi_remote_option (OstreeRepo *repo, - OstreeSign *sign, - const char *remote_name, - const char *keysuffix, - char **out_value, - GError **error) +get_signapi_remote_option (OstreeRepo *repo, OstreeSign *sign, const char *remote_name, + const char *keysuffix, char **out_value, GError **error) { - g_autofree char *key = g_strdup_printf ("verification-%s-%s", ostree_sign_get_name (sign), keysuffix); + g_autofree char *key + = g_strdup_printf ("verification-%s-%s", ostree_sign_get_name (sign), keysuffix); return ostree_repo_get_remote_option (repo, remote_name, key, NULL, out_value, error); } @@ -66,11 +63,8 @@ get_signapi_remote_option (OstreeRepo *repo, * Returns: %TRUE if no configuration or any key loaded. * */ static gboolean -_signapi_load_public_keys (OstreeSign *sign, - OstreeRepo *repo, - const gchar *remote_name, - gboolean required, - GError **error) +_signapi_load_public_keys (OstreeSign *sign, OstreeRepo *repo, const gchar *remote_name, + gboolean required, GError **error) { g_autofree gchar *pk_ascii = NULL; g_autofree gchar *pk_file = NULL; @@ -83,7 +77,7 @@ _signapi_load_public_keys (OstreeSign *sign, return FALSE; /* return TRUE if there is no configuration for remote */ - if ((pk_file == NULL) &&(pk_ascii == NULL)) + if ((pk_file == NULL) && (pk_ascii == NULL)) { /* It is expected what remote may have verification file as * a part of configuration. Hence there is not a lot of sense @@ -95,7 +89,8 @@ _signapi_load_public_keys (OstreeSign *sign, * specific for signature type. */ if (required) - return glnx_throw (error, "No keys found for required signapi type %s", ostree_sign_get_name (sign)); + return glnx_throw (error, "No keys found for required signapi type %s", + ostree_sign_get_name (sign)); return TRUE; } @@ -121,7 +116,7 @@ _signapi_load_public_keys (OstreeSign *sign, if (pk_ascii != NULL) { g_autoptr (GError) local_error = NULL; - g_autoptr (GVariant) pk = g_variant_new_string(pk_ascii); + g_autoptr (GVariant) pk = g_variant_new_string (pk_ascii); /* Add inlined public key */ if (loaded_from_file) @@ -144,10 +139,11 @@ _signapi_load_public_keys (OstreeSign *sign, } static gboolean -string_is_gkeyfile_truthy (const char *value, - gboolean *out_truth) +string_is_gkeyfile_truthy (const char *value, gboolean *out_truth) { - /* See https://gitlab.gnome.org/GNOME/glib/-/blob/20fb5bf868added5aec53c013ae85ec78ba2eedc/glib/gkeyfile.c#L4528 */ + /* See + * https://gitlab.gnome.org/GNOME/glib/-/blob/20fb5bf868added5aec53c013ae85ec78ba2eedc/glib/gkeyfile.c#L4528 + */ if (g_str_equal (value, "true") || g_str_equal (value, "1")) { *out_truth = TRUE; @@ -162,18 +158,13 @@ string_is_gkeyfile_truthy (const char *value, } static gboolean -verifiers_from_config (OstreeRepo *repo, - const char *remote_name, - const char *key, - GPtrArray **out_verifiers, - GError **error) +verifiers_from_config (OstreeRepo *repo, const char *remote_name, const char *key, + GPtrArray **out_verifiers, GError **error) { - g_autoptr(GPtrArray) verifiers = NULL; + g_autoptr (GPtrArray) verifiers = NULL; g_autofree char *raw_value = NULL; - if (!ostree_repo_get_remote_option (repo, remote_name, - key, NULL, - &raw_value, error)) + if (!ostree_repo_get_remote_option (repo, remote_name, key, NULL, &raw_value, error)) return FALSE; if (raw_value == NULL || g_str_equal (raw_value, "")) { @@ -204,12 +195,10 @@ verifiers_from_config (OstreeRepo *repo, else { /* If the value isn't "truthy", then it must be an explicit list */ - g_auto(GStrv) sign_types = NULL; - if (!ostree_repo_get_remote_list_option (repo, remote_name, - key, &sign_types, - error)) + g_auto (GStrv) sign_types = NULL; + if (!ostree_repo_get_remote_list_option (repo, remote_name, key, &sign_types, error)) return FALSE; - verifiers = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + verifiers = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); for (char **iter = sign_types; iter && *iter; iter++) { const char *sign_type = *iter; @@ -233,14 +222,12 @@ verifiers_from_config (OstreeRepo *repo, * the resulting verifier list will be NULL. */ gboolean -_signapi_init_for_remote (OstreeRepo *repo, - const char *remote_name, - GPtrArray **out_commit_verifiers, - GPtrArray **out_summary_verifiers, - GError **error) +_signapi_init_for_remote (OstreeRepo *repo, const char *remote_name, + GPtrArray **out_commit_verifiers, GPtrArray **out_summary_verifiers, + GError **error) { - g_autoptr(GPtrArray) commit_verifiers = NULL; - g_autoptr(GPtrArray) summary_verifiers = NULL; + g_autoptr (GPtrArray) commit_verifiers = NULL; + g_autoptr (GPtrArray) summary_verifiers = NULL; if (!verifiers_from_config (repo, remote_name, "sign-verify", &commit_verifiers, error)) return FALSE; @@ -256,11 +243,8 @@ _signapi_init_for_remote (OstreeRepo *repo, * by at least one. */ gboolean -_sign_verify_for_remote (GPtrArray *verifiers, - GBytes *signed_data, - GVariant *metadata, - char **out_success_message, - GError **error) +_sign_verify_for_remote (GPtrArray *verifiers, GBytes *signed_data, GVariant *metadata, + char **out_success_message, GError **error) { guint n_invalid_signatures = 0; g_autoptr (GError) last_sig_error = NULL; @@ -274,9 +258,9 @@ _sign_verify_for_remote (GPtrArray *verifiers, { OstreeSign *sign = verifiers->pdata[i]; const gchar *signature_key = ostree_sign_metadata_key (sign); - GVariantType *signature_format = (GVariantType *) ostree_sign_metadata_format (sign); - g_autoptr (GVariant) signatures = - g_variant_lookup_value (metadata, signature_key, signature_format); + GVariantType *signature_format = (GVariantType *)ostree_sign_metadata_format (sign); + g_autoptr (GVariant) signatures + = g_variant_lookup_value (metadata, signature_key, signature_format); /* If not found signatures for requested signature subsystem */ if (!signatures) @@ -285,12 +269,9 @@ _sign_verify_for_remote (GPtrArray *verifiers, found_sig = TRUE; g_autofree char *success_message = NULL; - /* Return true if any signature fit to pre-loaded public keys. - * If no keys configured -- then system configuration will be used */ - if (!ostree_sign_data_verify (sign, - signed_data, - signatures, - &success_message, + /* Return true if any signature fit to pre-loaded public keys. + * If no keys configured -- then system configuration will be used */ + if (!ostree_sign_data_verify (sign, signed_data, signatures, &success_message, last_sig_error ? NULL : &last_sig_error)) { n_invalid_signatures++; @@ -308,32 +289,26 @@ _sign_verify_for_remote (GPtrArray *verifiers, g_assert (last_sig_error); g_propagate_error (error, g_steal_pointer (&last_sig_error)); if (n_invalid_signatures > 1) - glnx_prefix_error (error, "(%d other invalid signatures)", n_invalid_signatures-1); + glnx_prefix_error (error, "(%d other invalid signatures)", n_invalid_signatures - 1); return FALSE; } - #ifndef OSTREE_DISABLE_GPGME gboolean -_process_gpg_verify_result (OtPullData *pull_data, - const char *checksum, - OstreeGpgVerifyResult *result, - GError **error) +_process_gpg_verify_result (OtPullData *pull_data, const char *checksum, + OstreeGpgVerifyResult *result, GError **error) { const char *error_prefix = glnx_strjoina ("Commit ", checksum); - GLNX_AUTO_PREFIX_ERROR(error_prefix, error); + GLNX_AUTO_PREFIX_ERROR (error_prefix, error); if (result == NULL) return FALSE; /* Allow callers to output the results immediately. */ - g_signal_emit_by_name (pull_data->repo, - "gpg-verify-result", - checksum, result); + g_signal_emit_by_name (pull_data->repo, "gpg-verify-result", checksum, result); if (!ostree_gpg_verify_result_require_valid_signature (result, error)) return FALSE; - /* We now check both *before* writing the commit, and after. Because the * behavior used to be only verifiying after writing, we need to handle * the case of "written but not verified". But we also don't want to check @@ -350,7 +325,9 @@ validate_metadata_size (const char *prefix, GBytes *buf, GError **error) { gsize len = g_bytes_get_size (buf); if (len > OSTREE_MAX_METADATA_SIZE) - return glnx_throw (error, "%s is %" G_GUINT64_FORMAT " bytes, exceeding maximum %" G_GUINT64_FORMAT, prefix, (guint64)len, (guint64)OSTREE_MAX_METADATA_SIZE); + return glnx_throw (error, + "%s is %" G_GUINT64_FORMAT " bytes, exceeding maximum %" G_GUINT64_FORMAT, + prefix, (guint64)len, (guint64)OSTREE_MAX_METADATA_SIZE); return TRUE; } @@ -361,21 +338,18 @@ validate_metadata_size (const char *prefix, GBytes *buf, GError **error) * @commit_data: Commit object data (GVariant) * @commit_metadata: Commit metadata (GVariant `a{sv}`), must contain at least one valid signature * @flags: Optionally disable GPG or signapi - * @out_results: (nullable) (out) (transfer full): Textual description of results + * @out_results: (optional) (out) (transfer full): Textual description of results * @error: Error * * Validate the commit data using the commit metadata which must * contain at least one valid signature. If GPG and signapi are * both enabled, then both must find at least one valid signature. */ -gboolean -ostree_repo_signature_verify_commit_data (OstreeRepo *self, - const char *remote_name, - GBytes *commit_data, - GBytes *commit_metadata, - OstreeRepoVerifyFlags flags, - char **out_results, - GError **error) +gboolean +ostree_repo_signature_verify_commit_data (OstreeRepo *self, const char *remote_name, + GBytes *commit_data, GBytes *commit_metadata, + OstreeRepoVerifyFlags flags, char **out_results, + GError **error) { g_assert (self); g_assert (remote_name); @@ -394,20 +368,20 @@ ostree_repo_signature_verify_commit_data (OstreeRepo *self, return glnx_throw (error, "Can't verify commit without detached metadata"); if (!validate_metadata_size ("Commit metadata", commit_metadata, error)) return FALSE; - g_autoptr(GVariant) commit_metadata_v = g_variant_new_from_bytes (G_VARIANT_TYPE_VARDICT, commit_metadata, FALSE); + g_autoptr (GVariant) commit_metadata_v + = g_variant_new_from_bytes (G_VARIANT_TYPE_VARDICT, commit_metadata, FALSE); - g_autoptr(GString) results_buf = g_string_new (""); + g_autoptr (GString) results_buf = g_string_new (""); gboolean verified = FALSE; if (gpg) { - if (!ostree_repo_remote_get_gpg_verify (self, remote_name, - &gpg, error)) + if (!ostree_repo_remote_get_gpg_verify (self, remote_name, &gpg, error)) return FALSE; } /* TODO - we could cache this in the repo */ - g_autoptr(GPtrArray) signapi_verifiers = NULL; + g_autoptr (GPtrArray) signapi_verifiers = NULL; if (signapi) { if (!_signapi_init_for_remote (self, remote_name, &signapi_verifiers, NULL, error)) @@ -415,16 +389,16 @@ ostree_repo_signature_verify_commit_data (OstreeRepo *self, } if (!(gpg || signapi_verifiers)) - return glnx_throw (error, "Cannot verify commit for remote %s; GPG verification disabled, and no signapi verifiers configured", remote_name); + return glnx_throw (error, + "Cannot verify commit for remote %s; GPG verification disabled, and no " + "signapi verifiers configured", + remote_name); #ifndef OSTREE_DISABLE_GPGME if (gpg) { - g_autoptr(OstreeGpgVerifyResult) result = - _ostree_repo_gpg_verify_with_metadata (self, commit_data, - commit_metadata_v, - remote_name, - NULL, NULL, NULL, error); + g_autoptr (OstreeGpgVerifyResult) result = _ostree_repo_gpg_verify_with_metadata ( + self, commit_data, commit_metadata_v, remote_name, NULL, NULL, NULL, error); if (!result) return FALSE; if (!ostree_gpg_verify_result_require_valid_signature (result, error)) @@ -434,8 +408,8 @@ ostree_repo_signature_verify_commit_data (OstreeRepo *self, g_assert_cmpuint (n_signatures, >, 0); for (guint jj = 0; jj < n_signatures; jj++) { - ostree_gpg_verify_result_describe (result, jj, results_buf, "GPG: ", - OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT); + ostree_gpg_verify_result_describe (result, jj, results_buf, + "GPG: ", OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT); } verified = TRUE; } @@ -444,7 +418,8 @@ ostree_repo_signature_verify_commit_data (OstreeRepo *self, if (signapi_verifiers) { g_autofree char *success_message = NULL; - if (!_sign_verify_for_remote (signapi_verifiers, commit_data, commit_metadata_v, &success_message, error)) + if (!_sign_verify_for_remote (signapi_verifiers, commit_data, commit_metadata_v, + &success_message, error)) return glnx_prefix_error (error, "Can't verify commit"); if (verified) g_string_append_c (results_buf, '\n'); @@ -460,20 +435,17 @@ ostree_repo_signature_verify_commit_data (OstreeRepo *self, } gboolean -_verify_unwritten_commit (OtPullData *pull_data, - const char *checksum, - GVariant *commit, - GVariant *detached_metadata, - const OstreeCollectionRef *ref, - GCancellable *cancellable, - GError **error) +_verify_unwritten_commit (OtPullData *pull_data, const char *checksum, GVariant *commit, + GVariant *detached_metadata, const OstreeCollectionRef *ref, + GCancellable *cancellable, GError **error) { /* Shouldn't happen, but see comment in process_gpg_verify_result() */ if ((!pull_data->gpg_verify || g_hash_table_contains (pull_data->verified_commits, checksum)) - && (!pull_data->signapi_commit_verifiers || g_hash_table_contains (pull_data->signapi_verified_commits, checksum))) + && (!pull_data->signapi_commit_verifiers + || g_hash_table_contains (pull_data->signapi_verified_commits, checksum))) return TRUE; - g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit); + g_autoptr (GBytes) signed_data = g_variant_get_data_as_bytes (commit); #ifndef OSTREE_DISABLE_GPGME if (pull_data->gpg_verify) @@ -485,11 +457,9 @@ _verify_unwritten_commit (OtPullData *pull_data, if (keyring_remote == NULL) keyring_remote = pull_data->remote_name; - g_autoptr(OstreeGpgVerifyResult) result = - _ostree_repo_gpg_verify_with_metadata (pull_data->repo, signed_data, - detached_metadata, - keyring_remote, - NULL, NULL, cancellable, error); + g_autoptr (OstreeGpgVerifyResult) result + = _ostree_repo_gpg_verify_with_metadata (pull_data->repo, signed_data, detached_metadata, + keyring_remote, NULL, NULL, cancellable, error); if (!_process_gpg_verify_result (pull_data, checksum, result, error)) return FALSE; } @@ -502,12 +472,14 @@ _verify_unwritten_commit (OtPullData *pull_data, return glnx_throw (error, "Can't verify commit without detached metadata"); g_autofree char *success_message = NULL; - if (!_sign_verify_for_remote (pull_data->signapi_commit_verifiers, signed_data, detached_metadata, &success_message, error)) + if (!_sign_verify_for_remote (pull_data->signapi_commit_verifiers, signed_data, + detached_metadata, &success_message, error)) return glnx_prefix_error (error, "Can't verify commit"); /* Mark the commit as verified to avoid double verification * see process_verify_result () for rationale */ - g_hash_table_insert (pull_data->signapi_verified_commits, g_strdup (checksum), g_steal_pointer (&success_message)); + g_hash_table_insert (pull_data->signapi_verified_commits, g_strdup (checksum), + g_steal_pointer (&success_message)); } return TRUE; diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 4819a40..9989415 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -26,22 +26,22 @@ #include "config.h" #include "libglnx.h" +#include "ostree-repo-pull-private.h" #include "ostree.h" #include "otutil.h" -#include "ostree-repo-pull-private.h" #ifdef HAVE_LIBCURL_OR_LIBSOUP #include "ostree-core-private.h" -#include "ostree-repo-static-delta-private.h" #include "ostree-metalink.h" +#include "ostree-repo-static-delta-private.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-config.h" #include "ostree-repo-finder-mount.h" +#include "ostree-repo-finder.h" #ifdef HAVE_AVAHI #include "ostree-repo-finder-avahi.h" -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ #include #include @@ -50,9 +50,10 @@ #include #endif -#define OSTREE_MESSAGE_FETCH_COMPLETE_ID SD_ID128_MAKE(75,ba,3d,eb,0a,f0,41,a9,a4,62,72,ff,85,d9,e7,3e) +#define OSTREE_MESSAGE_FETCH_COMPLETE_ID \ + SD_ID128_MAKE (75, ba, 3d, eb, 0a, f0, 41, a9, a4, 62, 72, ff, 85, d9, e7, 3e) -#define OSTREE_REPO_PULL_CONTENT_PRIORITY (OSTREE_FETCHER_DEFAULT_PRIORITY) +#define OSTREE_REPO_PULL_CONTENT_PRIORITY (OSTREE_FETCHER_DEFAULT_PRIORITY) #define OSTREE_REPO_PULL_METADATA_PRIORITY (OSTREE_REPO_PULL_CONTENT_PRIORITY - 100) /* Arbitrarily chosen number of retries for all download operations when they @@ -60,24 +61,30 @@ * _ostree_fetcher_should_retry_request(). This is the default value for the * `n-network-retries` pull option. */ #define DEFAULT_N_NETWORK_RETRIES 5 +#define OPT_LOWSPEEDLIMIT_DEFAULT 1000 +#define OPT_LOWSPEEDTIME_DEFAULT 30 +#define OPT_RETRYALL_DEFAULT TRUE +#define OPT_OSTREE_MAX_OUTSTANDING_FETCHER_REQUESTS_DEFAULT 8 -typedef struct { - OtPullData *pull_data; - GVariant *object; - char *path; - gboolean is_detached_meta; +typedef struct +{ + OtPullData *pull_data; + GVariant *object; + char *path; + gboolean is_detached_meta; /* Only relevant when is_detached_meta is TRUE. Controls * whether to fetch the primary object after fetching its * detached metadata (no need if it's already stored). */ - gboolean object_is_stored; + gboolean object_is_stored; - OstreeCollectionRef *requested_ref; /* (nullable) */ + OstreeCollectionRef *requested_ref; /* (nullable) */ guint n_retries_remaining; } FetchObjectData; -typedef struct { - OtPullData *pull_data; +typedef struct +{ + OtPullData *pull_data; GVariant *objects; char *expected_checksum; char *from_revision; @@ -87,27 +94,30 @@ typedef struct { guint n_retries_remaining; } FetchStaticDeltaData; -typedef struct { +typedef struct +{ guchar csum[OSTREE_SHA256_DIGEST_LEN]; char *path; OstreeObjectType objtype; - guint recursion_depth; /* NB: not used anymore, though might be nice to print */ - OstreeCollectionRef *requested_ref; /* (nullable) */ + guint recursion_depth; /* NB: not used anymore, though might be nice to print */ + OstreeCollectionRef *requested_ref; /* (nullable) */ } ScanObjectQueueData; -typedef struct { +typedef struct +{ OtPullData *pull_data; char *from_revision; char *to_revision; - OstreeCollectionRef *requested_ref; /* (nullable) */ + OstreeCollectionRef *requested_ref; /* (nullable) */ guint n_retries_remaining; } FetchDeltaSuperData; -typedef struct { +typedef struct +{ OtPullData *pull_data; char *from_revision; char *to_revision; - OstreeCollectionRef *requested_ref; /* (nullable) */ + OstreeCollectionRef *requested_ref; /* (nullable) */ guint n_retries_remaining; } FetchDeltaIndexData; @@ -119,52 +129,38 @@ variant_or_null_unref (gpointer data) } static void start_fetch (OtPullData *pull_data, FetchObjectData *fetch); -static void start_fetch_deltapart (OtPullData *pull_data, - FetchStaticDeltaData *fetch); -static void start_fetch_delta_superblock (OtPullData *pull_data, - FetchDeltaSuperData *fetch_data); -static void start_fetch_delta_index (OtPullData *pull_data, - FetchDeltaIndexData *fetch_data); +static void start_fetch_deltapart (OtPullData *pull_data, FetchStaticDeltaData *fetch); +static void start_fetch_delta_superblock (OtPullData *pull_data, FetchDeltaSuperData *fetch_data); +static void start_fetch_delta_index (OtPullData *pull_data, FetchDeltaIndexData *fetch_data); static gboolean fetcher_queue_is_full (OtPullData *pull_data); -static void queue_scan_one_metadata_object (OtPullData *pull_data, - const char *csum, - OstreeObjectType objtype, - const char *path, - guint recursion_depth, - const OstreeCollectionRef *ref); - -static void queue_scan_one_metadata_object_s (OtPullData *pull_data, - ScanObjectQueueData *scan_data); -static void queue_scan_one_metadata_object_c (OtPullData *pull_data, - const guchar *csum, - OstreeObjectType objtype, - const char *path, - guint recursion_depth, +static void queue_scan_one_metadata_object (OtPullData *pull_data, const char *csum, + OstreeObjectType objtype, const char *path, + guint recursion_depth, const OstreeCollectionRef *ref); + +static void queue_scan_one_metadata_object_s (OtPullData *pull_data, + ScanObjectQueueData *scan_data); +static void queue_scan_one_metadata_object_c (OtPullData *pull_data, const guchar *csum, + OstreeObjectType objtype, const char *path, + guint recursion_depth, const OstreeCollectionRef *ref); -static void enqueue_one_object_request_s (OtPullData *pull_data, - FetchObjectData *fetch_data); -static void enqueue_one_static_delta_index_request_s (OtPullData *pull_data, +static void enqueue_one_object_request_s (OtPullData *pull_data, FetchObjectData *fetch_data); +static void enqueue_one_static_delta_index_request_s (OtPullData *pull_data, FetchDeltaIndexData *fetch_data); -static void enqueue_one_static_delta_superblock_request_s (OtPullData *pull_data, +static void enqueue_one_static_delta_superblock_request_s (OtPullData *pull_data, FetchDeltaSuperData *fetch_data); -static void enqueue_one_static_delta_part_request_s (OtPullData *pull_data, +static void enqueue_one_static_delta_part_request_s (OtPullData *pull_data, FetchStaticDeltaData *fetch_data); +static void ensure_idle_queued (OtPullData *pull_data); -static gboolean scan_one_metadata_object (OtPullData *pull_data, - const char *checksum, - OstreeObjectType objtype, - const char *path, - guint recursion_depth, - const OstreeCollectionRef *ref, - GCancellable *cancellable, - GError **error); +static gboolean scan_one_metadata_object (OtPullData *pull_data, const char *checksum, + OstreeObjectType objtype, const char *path, + guint recursion_depth, const OstreeCollectionRef *ref, + GCancellable *cancellable, GError **error); static void scan_object_queue_data_free (ScanObjectQueueData *scan_data); -static gboolean initiate_delta_request (OtPullData *pull_data, - const OstreeCollectionRef *ref, - const char *to_revision, - const char *delta_from_revision, - GError **error); +static gboolean initiate_delta_request (OtPullData *pull_data, const OstreeCollectionRef *ref, + const char *to_revision, const char *delta_from_revision, + GError **error); static gboolean update_progress (gpointer user_data) @@ -180,63 +176,51 @@ update_progress (gpointer user_data) pull_data = user_data; - if (! pull_data->progress) + if (!pull_data->progress) return FALSE; /* In dry run, we only emit progress once metadata is done */ if (pull_data->dry_run && pull_data->n_outstanding_metadata_fetches > 0) return TRUE; - outstanding_writes = pull_data->n_outstanding_content_write_requests + - pull_data->n_outstanding_metadata_write_requests + - pull_data->n_outstanding_deltapart_write_requests; - outstanding_fetches = pull_data->n_outstanding_content_fetches + - pull_data->n_outstanding_metadata_fetches + - pull_data->n_outstanding_deltapart_fetches; + outstanding_writes = pull_data->n_outstanding_content_write_requests + + pull_data->n_outstanding_metadata_write_requests + + pull_data->n_outstanding_deltapart_write_requests; + outstanding_fetches = pull_data->n_outstanding_content_fetches + + pull_data->n_outstanding_metadata_fetches + + pull_data->n_outstanding_deltapart_fetches; bytes_transferred = _ostree_fetcher_bytes_transferred (pull_data->fetcher); fetched = pull_data->n_fetched_metadata + pull_data->n_fetched_content; requested = pull_data->n_requested_metadata + pull_data->n_requested_content; n_scanned_metadata = pull_data->n_scanned_metadata; start_time = pull_data->start_time; - ostree_async_progress_set (pull_data->progress, - "outstanding-fetches", "u", outstanding_fetches, - "outstanding-writes", "u", outstanding_writes, - "fetched", "u", fetched, - "requested", "u", requested, - "scanning", "u", g_queue_is_empty (&pull_data->scan_object_queue) ? 0 : 1, - "caught-error", "b", pull_data->caught_error, - "scanned-metadata", "u", n_scanned_metadata, - "bytes-transferred", "t", bytes_transferred, - "start-time", "t", start_time, - /* We use these status keys even though we now also - * use these values for filesystem-local pulls. - */ - "metadata-fetched-localcache", "u", pull_data->n_imported_metadata, - "content-fetched-localcache", "u", pull_data->n_imported_content, - /* Deltas */ - "fetched-delta-parts", - "u", pull_data->n_fetched_deltaparts, - "total-delta-parts", - "u", pull_data->n_total_deltaparts, - "fetched-delta-fallbacks", - "u", pull_data->n_fetched_deltapart_fallbacks, - "total-delta-fallbacks", - "u", pull_data->n_total_delta_fallbacks, - "fetched-delta-part-size", - "t", pull_data->fetched_deltapart_size, - "total-delta-part-size", - "t", pull_data->total_deltapart_size, - "total-delta-part-usize", - "t", pull_data->total_deltapart_usize, - "total-delta-superblocks", - "u", pull_data->static_delta_superblocks->len, - /* We fetch metadata before content. These allow us to report metadata fetch progress specifically. */ - "outstanding-metadata-fetches", "u", pull_data->n_outstanding_metadata_fetches, - "metadata-fetched", "u", pull_data->n_fetched_metadata, - /* Overall status. */ - "status", "s", "", - NULL); + ostree_async_progress_set ( + pull_data->progress, "outstanding-fetches", "u", outstanding_fetches, "outstanding-writes", + "u", outstanding_writes, "fetched", "u", fetched, "requested", "u", requested, "scanning", + "u", g_queue_is_empty (&pull_data->scan_object_queue) ? 0 : 1, "caught-error", "b", + pull_data->caught_error, "scanned-metadata", "u", n_scanned_metadata, "bytes-transferred", + "t", bytes_transferred, "start-time", "t", start_time, + /* We use these status keys even though we now also + * use these values for filesystem-local pulls. + */ + "metadata-fetched-localcache", "u", pull_data->n_imported_metadata, + "content-fetched-localcache", "u", pull_data->n_imported_content, + /* Deltas */ + "fetched-delta-parts", "u", pull_data->n_fetched_deltaparts, "total-delta-parts", "u", + pull_data->n_total_deltaparts, "fetched-delta-fallbacks", "u", + pull_data->n_fetched_deltapart_fallbacks, "total-delta-fallbacks", "u", + pull_data->n_total_delta_fallbacks, "fetched-delta-part-size", "t", + pull_data->fetched_deltapart_size, "total-delta-part-size", "t", + pull_data->total_deltapart_size, "total-delta-part-usize", "t", + pull_data->total_deltapart_usize, "total-delta-superblocks", "u", + g_hash_table_size (pull_data->static_delta_targets), + /* We fetch metadata before content. These allow us to report metadata fetch progress + specifically. */ + "outstanding-metadata-fetches", "u", pull_data->n_outstanding_metadata_fetches, + "metadata-fetched", "u", pull_data->n_fetched_metadata, + /* Overall status. */ + "status", "s", "", NULL); if (pull_data->dry_run) pull_data->dry_run_emitted_progress = TRUE; @@ -246,14 +230,14 @@ update_progress (gpointer user_data) /* The core logic function for whether we should continue the main loop */ static gboolean -pull_termination_condition (OtPullData *pull_data) +pull_termination_condition (OtPullData *pull_data) { - gboolean current_fetch_idle = (pull_data->n_outstanding_metadata_fetches == 0 && - pull_data->n_outstanding_content_fetches == 0 && - pull_data->n_outstanding_deltapart_fetches == 0); - gboolean current_write_idle = (pull_data->n_outstanding_metadata_write_requests == 0 && - pull_data->n_outstanding_content_write_requests == 0 && - pull_data->n_outstanding_deltapart_write_requests == 0 ); + gboolean current_fetch_idle = (pull_data->n_outstanding_metadata_fetches == 0 + && pull_data->n_outstanding_content_fetches == 0 + && pull_data->n_outstanding_deltapart_fetches == 0); + gboolean current_write_idle = (pull_data->n_outstanding_metadata_write_requests == 0 + && pull_data->n_outstanding_content_write_requests == 0 + && pull_data->n_outstanding_deltapart_write_requests == 0); gboolean current_scan_idle = g_queue_is_empty (&pull_data->scan_object_queue); gboolean current_idle = current_fetch_idle && current_write_idle && current_scan_idle; @@ -274,8 +258,7 @@ pull_termination_condition (OtPullData *pull_data) * requests as appropriate. */ static void -check_outstanding_requests_handle_error (OtPullData *pull_data, - GError **errorp) +check_outstanding_requests_handle_error (OtPullData *pull_data, GError **errorp) { g_assert (errorp); @@ -300,7 +283,7 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, */ if (pull_data->caught_error) { - g_queue_foreach (&pull_data->scan_object_queue, (GFunc) scan_object_queue_data_free, NULL); + g_queue_foreach (&pull_data->scan_object_queue, (GFunc)scan_object_queue_data_free, NULL); g_queue_clear (&pull_data->scan_object_queue); g_hash_table_remove_all (pull_data->pending_fetch_metadata); g_hash_table_remove_all (pull_data->pending_fetch_delta_indexes); @@ -322,8 +305,7 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, /* Try filling the queue with metadata we need to fetch */ g_hash_table_iter_init (&hiter, pull_data->pending_fetch_metadata); - while (!fetcher_queue_is_full (pull_data) && - g_hash_table_iter_next (&hiter, &key, &value)) + while (!fetcher_queue_is_full (pull_data) && g_hash_table_iter_next (&hiter, &key, &value)) { GVariant *objname = key; FetchObjectData *fetch = value; @@ -339,8 +321,7 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, /* Next, process delta index requests */ g_hash_table_iter_init (&hiter, pull_data->pending_fetch_delta_indexes); - while (!fetcher_queue_is_full (pull_data) && - g_hash_table_iter_next (&hiter, &key, &value)) + while (!fetcher_queue_is_full (pull_data) && g_hash_table_iter_next (&hiter, &key, &value)) { FetchDeltaIndexData *fetch = key; g_hash_table_iter_steal (&hiter); @@ -349,8 +330,7 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, /* Next, process delta superblock requests */ g_hash_table_iter_init (&hiter, pull_data->pending_fetch_delta_superblocks); - while (!fetcher_queue_is_full (pull_data) && - g_hash_table_iter_next (&hiter, &key, &value)) + while (!fetcher_queue_is_full (pull_data) && g_hash_table_iter_next (&hiter, &key, &value)) { FetchDeltaSuperData *fetch = key; g_hash_table_iter_steal (&hiter); @@ -359,8 +339,7 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, /* Now, process deltapart requests */ g_hash_table_iter_init (&hiter, pull_data->pending_fetch_deltaparts); - while (!fetcher_queue_is_full (pull_data) && - g_hash_table_iter_next (&hiter, &key, &value)) + while (!fetcher_queue_is_full (pull_data) && g_hash_table_iter_next (&hiter, &key, &value)) { FetchStaticDeltaData *fetch = key; g_hash_table_iter_steal (&hiter); @@ -370,8 +349,7 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, /* Next, fill the queue with content */ g_hash_table_iter_init (&hiter, pull_data->pending_fetch_content); - while (!fetcher_queue_is_full (pull_data) && - g_hash_table_iter_next (&hiter, &key, &value)) + while (!fetcher_queue_is_full (pull_data) && g_hash_table_iter_next (&hiter, &key, &value)) { char *checksum = key; FetchObjectData *fetch = value; @@ -385,6 +363,9 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, g_free (checksum); } + /* Finally, if we still have capacity, scan more metadata objects */ + if (!g_queue_is_empty (&pull_data->scan_object_queue)) + ensure_idle_queued (pull_data); } } @@ -396,19 +377,16 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, static gboolean fetcher_queue_is_full (OtPullData *pull_data) { - const gboolean fetch_full = - ((pull_data->n_outstanding_metadata_fetches + - pull_data->n_outstanding_content_fetches + - pull_data->n_outstanding_deltapart_fetches) == - _OSTREE_MAX_OUTSTANDING_FETCHER_REQUESTS); - const gboolean deltas_full = - (pull_data->n_outstanding_deltapart_fetches == - _OSTREE_MAX_OUTSTANDING_DELTAPART_REQUESTS); - const gboolean writes_full = - ((pull_data->n_outstanding_metadata_write_requests + - pull_data->n_outstanding_content_write_requests + - pull_data->n_outstanding_deltapart_write_requests) >= - _OSTREE_MAX_OUTSTANDING_WRITE_REQUESTS); + const gboolean fetch_full + = ((pull_data->n_outstanding_metadata_fetches + pull_data->n_outstanding_content_fetches + + pull_data->n_outstanding_deltapart_fetches) + == pull_data->max_outstanding_fetcher_requests); + const gboolean deltas_full + = (pull_data->n_outstanding_deltapart_fetches == _OSTREE_MAX_OUTSTANDING_DELTAPART_REQUESTS); + const gboolean writes_full = ((pull_data->n_outstanding_metadata_write_requests + + pull_data->n_outstanding_content_write_requests + + pull_data->n_outstanding_deltapart_write_requests) + >= _OSTREE_MAX_OUTSTANDING_WRITE_REQUESTS); return fetch_full || deltas_full || writes_full; } @@ -431,7 +409,7 @@ idle_worker (gpointer user_data) { OtPullData *pull_data = user_data; ScanObjectQueueData *scan_data; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; scan_data = g_queue_pop_head (&pull_data->scan_object_queue); if (!scan_data) @@ -440,11 +418,11 @@ idle_worker (gpointer user_data) return G_SOURCE_REMOVE; } - char checksum[OSTREE_SHA256_STRING_LEN+1]; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; ostree_checksum_inplace_from_bytes (scan_data->csum, checksum); - scan_one_metadata_object (pull_data, checksum, scan_data->objtype, - scan_data->path, scan_data->recursion_depth, - scan_data->requested_ref, pull_data->cancellable, &error); + scan_one_metadata_object (pull_data, checksum, scan_data->objtype, scan_data->path, + scan_data->recursion_depth, scan_data->requested_ref, + pull_data->cancellable, &error); /* No need to retry scan tasks, since they’re local. */ check_outstanding_requests_handle_error (pull_data, &error); @@ -461,6 +439,10 @@ ensure_idle_queued (OtPullData *pull_data) if (pull_data->idle_src) return; + /* If the operation queue is full, there's no point in blocking further. */ + if (fetcher_queue_is_full (pull_data)) + return; + idle_src = g_idle_source_new (); g_source_set_callback (idle_src, idle_worker, pull_data, NULL); g_source_attach (idle_src, pull_data->main_context); @@ -469,28 +451,23 @@ ensure_idle_queued (OtPullData *pull_data) g_source_unref (idle_src); } -typedef struct { - OtPullData *pull_data; - GInputStream *result_stream; +typedef struct +{ + OtPullData *pull_data; + GInputStream *result_stream; } OstreeFetchUriSyncData; static gboolean -fetch_mirrored_uri_contents_utf8_sync (OstreeFetcher *fetcher, - GPtrArray *mirrorlist, - const char *filename, - guint n_network_retries, - char **out_contents, - GCancellable *cancellable, - GError **error) +fetch_mirrored_uri_contents_utf8_sync (OstreeFetcher *fetcher, GPtrArray *mirrorlist, + const char *filename, guint n_network_retries, + char **out_contents, GCancellable *cancellable, + GError **error) { - g_autoptr(GBytes) bytes = NULL; - if (!_ostree_fetcher_mirrored_request_to_membuf (fetcher, mirrorlist, - filename, OSTREE_FETCHER_REQUEST_NUL_TERMINATION, - NULL, 0, - n_network_retries, - &bytes, NULL, NULL, NULL, - OSTREE_MAX_METADATA_SIZE, - cancellable, error)) + g_autoptr (GBytes) bytes = NULL; + if (!_ostree_fetcher_mirrored_request_to_membuf (fetcher, mirrorlist, filename, + OSTREE_FETCHER_REQUEST_NUL_TERMINATION, NULL, 0, + n_network_retries, &bytes, NULL, NULL, NULL, + OSTREE_MAX_METADATA_SIZE, cancellable, error)) return FALSE; gsize len; @@ -504,34 +481,23 @@ fetch_mirrored_uri_contents_utf8_sync (OstreeFetcher *fetcher, } static gboolean -fetch_uri_contents_utf8_sync (OstreeFetcher *fetcher, - OstreeFetcherURI *uri, - guint n_network_retries, - char **out_contents, - GCancellable *cancellable, - GError **error) +fetch_uri_contents_utf8_sync (OstreeFetcher *fetcher, OstreeFetcherURI *uri, + guint n_network_retries, char **out_contents, + GCancellable *cancellable, GError **error) { - g_autoptr(GPtrArray) mirrorlist = g_ptr_array_new (); + g_autoptr (GPtrArray) mirrorlist = g_ptr_array_new (); g_ptr_array_add (mirrorlist, uri); /* no transfer */ - return fetch_mirrored_uri_contents_utf8_sync (fetcher, mirrorlist, - NULL, n_network_retries, - out_contents, - cancellable, error); + return fetch_mirrored_uri_contents_utf8_sync (fetcher, mirrorlist, NULL, n_network_retries, + out_contents, cancellable, error); } -static void -enqueue_one_object_request (OtPullData *pull_data, - const char *checksum, - OstreeObjectType objtype, - const char *path, - gboolean is_detached_meta, - gboolean object_is_stored, - const OstreeCollectionRef *ref); +static void enqueue_one_object_request (OtPullData *pull_data, const char *checksum, + OstreeObjectType objtype, const char *path, + gboolean is_detached_meta, gboolean object_is_stored, + const OstreeCollectionRef *ref); static gboolean -matches_pull_dir (const char *current_file, - const char *pull_dir, - gboolean current_file_is_dir) +matches_pull_dir (const char *current_file, const char *pull_dir, gboolean current_file_is_dir) { const char *rest; @@ -569,11 +535,8 @@ matches_pull_dir (const char *current_file, return FALSE; } - static gboolean -pull_matches_subdir (OtPullData *pull_data, - const char *path, - const char *basename, +pull_matches_subdir (OtPullData *pull_data, const char *path, const char *basename, gboolean basename_is_dir) { if (pull_data->dirs == NULL) @@ -591,28 +554,26 @@ pull_matches_subdir (OtPullData *pull_data, return FALSE; } -typedef struct { +typedef struct +{ OtPullData *pull_data; OstreeRepo *src_repo; - char checksum[OSTREE_SHA256_STRING_LEN+1]; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; } ImportLocalAsyncData; /* Asynchronously import a single content object. @src_repo is either * pull_data->remote_repo_local or one of pull_data->localcache_repos. */ static void -async_import_in_thread (GTask *task, - gpointer source, - gpointer task_data, - GCancellable *cancellable) +async_import_in_thread (GTask *task, gpointer source, gpointer task_data, GCancellable *cancellable) { ImportLocalAsyncData *iataskdata = task_data; OtPullData *pull_data = iataskdata->pull_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; /* pull_data->importflags was set up in the pull option processing */ - if (!_ostree_repo_import_object (pull_data->repo, iataskdata->src_repo, - OSTREE_OBJECT_TYPE_FILE, iataskdata->checksum, - pull_data->importflags, cancellable, &local_error)) + if (!_ostree_repo_import_object (pull_data->repo, iataskdata->src_repo, OSTREE_OBJECT_TYPE_FILE, + iataskdata->checksum, pull_data->importflags, cancellable, + &local_error)) g_task_return_error (task, g_steal_pointer (&local_error)); else g_task_return_boolean (task, TRUE); @@ -626,18 +587,15 @@ async_import_in_thread (GTask *task, * OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES flag. */ static void -async_import_one_local_content_object (OtPullData *pull_data, - OstreeRepo *src_repo, - const char *checksum, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +async_import_one_local_content_object (OtPullData *pull_data, OstreeRepo *src_repo, + const char *checksum, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { ImportLocalAsyncData *iataskdata = g_new0 (ImportLocalAsyncData, 1); iataskdata->pull_data = pull_data; iataskdata->src_repo = src_repo; memcpy (iataskdata->checksum, checksum, OSTREE_SHA256_STRING_LEN); - g_autoptr(GTask) task = g_task_new (pull_data->repo, cancellable, callback, user_data); + g_autoptr (GTask) task = g_task_new (pull_data->repo, cancellable, callback, user_data); g_task_set_source_tag (task, async_import_one_local_content_object); g_task_set_task_data (task, iataskdata, g_free); pull_data->n_outstanding_content_write_requests++; @@ -645,27 +603,24 @@ async_import_one_local_content_object (OtPullData *pull_data, } static gboolean -async_import_one_local_content_object_finish (OtPullData *pull_data, - GAsyncResult *result, +async_import_one_local_content_object_finish (OtPullData *pull_data, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, pull_data->repo), FALSE); - return g_task_propagate_boolean ((GTask*)result, error); + return g_task_propagate_boolean ((GTask *)result, error); } static void -on_local_object_imported (GObject *object, - GAsyncResult *result, - gpointer user_data) +on_local_object_imported (GObject *object, GAsyncResult *result, gpointer user_data) { OtPullData *pull_data = user_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; if (!async_import_one_local_content_object_finish (pull_data, result, error)) goto out; - out: +out: pull_data->n_imported_content++; g_assert_cmpint (pull_data->n_outstanding_content_write_requests, >, 0); pull_data->n_outstanding_content_write_requests--; @@ -674,26 +629,22 @@ on_local_object_imported (GObject *object, } static gboolean -scan_dirtree_object (OtPullData *pull_data, - const char *checksum, - const char *path, - int recursion_depth, - GCancellable *cancellable, - GError **error) +scan_dirtree_object (OtPullData *pull_data, const char *checksum, const char *path, + int recursion_depth, GCancellable *cancellable, GError **error) { - g_autoptr(GVariant) tree = NULL; - if (!ostree_repo_load_variant (pull_data->repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum, - &tree, error)) + g_autoptr (GVariant) tree = NULL; + if (!ostree_repo_load_variant (pull_data->repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum, &tree, + error)) return FALSE; /* PARSE OSTREE_SERIALIZED_TREE_VARIANT */ - g_autoptr(GVariant) files_variant = g_variant_get_child_value (tree, 0); + g_autoptr (GVariant) files_variant = g_variant_get_child_value (tree, 0); const guint n = g_variant_n_children (files_variant); for (guint i = 0; i < n; i++) { const char *filename; gboolean file_is_stored; - g_autoptr(GVariant) csum = NULL; + g_autoptr (GVariant) csum = NULL; g_autofree char *file_checksum = NULL; g_variant_get_child (files_variant, i, "(&s@ay)", &filename, &csum); @@ -731,8 +682,7 @@ scan_dirtree_object (OtPullData *pull_data, { async_import_one_local_content_object (pull_data, pull_data->remote_repo_local, file_checksum, cancellable, - on_local_object_imported, - pull_data); + on_local_object_imported, pull_data); g_hash_table_add (pull_data->requested_content, g_steal_pointer (&file_checksum)); /* Note early loop continue */ continue; @@ -752,8 +702,9 @@ scan_dirtree_object (OtPullData *pull_data, return FALSE; if (!localcache_repo_has_obj) continue; - async_import_one_local_content_object (pull_data, localcache_repo, file_checksum, cancellable, - on_local_object_imported, pull_data); + async_import_one_local_content_object (pull_data, localcache_repo, file_checksum, + cancellable, on_local_object_imported, + pull_data); g_hash_table_add (pull_data->requested_content, g_steal_pointer (&file_checksum)); did_import_from_cache_repo = TRUE; break; @@ -764,19 +715,19 @@ scan_dirtree_object (OtPullData *pull_data, /* Not available locally, queue a HTTP request */ g_hash_table_add (pull_data->requested_content, file_checksum); - enqueue_one_object_request (pull_data, file_checksum, OSTREE_OBJECT_TYPE_FILE, path, FALSE, FALSE, NULL); - file_checksum = NULL; /* Transfer ownership */ + enqueue_one_object_request (pull_data, file_checksum, OSTREE_OBJECT_TYPE_FILE, path, FALSE, + FALSE, NULL); + file_checksum = NULL; /* Transfer ownership */ } - g_autoptr(GVariant) dirs_variant = g_variant_get_child_value (tree, 1); + g_autoptr (GVariant) dirs_variant = g_variant_get_child_value (tree, 1); const guint m = g_variant_n_children (dirs_variant); for (guint i = 0; i < m; i++) { const char *dirname = NULL; - g_autoptr(GVariant) tree_csum = NULL; - g_autoptr(GVariant) meta_csum = NULL; - g_variant_get_child (dirs_variant, i, "(&s@ay@ay)", - &dirname, &tree_csum, &meta_csum); + g_autoptr (GVariant) tree_csum = NULL; + g_autoptr (GVariant) meta_csum = NULL; + g_variant_get_child (dirs_variant, i, "(&s@ay@ay)", &dirname, &tree_csum, &meta_csum); /* See comment above for files */ if (!ot_util_filename_validate (dirname, error)) @@ -787,17 +738,17 @@ scan_dirtree_object (OtPullData *pull_data, const guchar *tree_csum_bytes = ostree_checksum_bytes_peek_validate (tree_csum, error); if (tree_csum_bytes == NULL) - return FALSE; + return glnx_prefix_error (error, "Parsing dirtree %s tree child %s", checksum, dirname); const guchar *meta_csum_bytes = ostree_checksum_bytes_peek_validate (meta_csum, error); if (meta_csum_bytes == NULL) - return FALSE; + return glnx_prefix_error (error, "Parsing dirtree %s meta child %s", checksum, dirname); g_autofree char *subpath = g_strconcat (path, dirname, "/", NULL); - queue_scan_one_metadata_object_c (pull_data, tree_csum_bytes, - OSTREE_OBJECT_TYPE_DIR_TREE, subpath, recursion_depth + 1, NULL); - queue_scan_one_metadata_object_c (pull_data, meta_csum_bytes, - OSTREE_OBJECT_TYPE_DIR_META, subpath, recursion_depth + 1, NULL); + queue_scan_one_metadata_object_c (pull_data, tree_csum_bytes, OSTREE_OBJECT_TYPE_DIR_TREE, + subpath, recursion_depth + 1, NULL); + queue_scan_one_metadata_object_c (pull_data, meta_csum_bytes, OSTREE_OBJECT_TYPE_DIR_META, + subpath, recursion_depth + 1, NULL); } return TRUE; @@ -805,29 +756,23 @@ scan_dirtree_object (OtPullData *pull_data, /* Given a @ref, fetch its contents (should be a SHA256 ASCII string) */ static gboolean -fetch_ref_contents (OtPullData *pull_data, - const char *main_collection_id, - const OstreeCollectionRef *ref, - char **out_contents, - GCancellable *cancellable, - GError **error) +fetch_ref_contents (OtPullData *pull_data, const char *main_collection_id, + const OstreeCollectionRef *ref, char **out_contents, GCancellable *cancellable, + GError **error) { g_autofree char *ret_contents = NULL; if (pull_data->remote_repo_local != NULL && ref->collection_id != NULL) { - if (!ostree_repo_resolve_collection_ref (pull_data->remote_repo_local, - ref, FALSE, - OSTREE_REPO_RESOLVE_REV_EXT_NONE, - &ret_contents, cancellable, error)) + if (!ostree_repo_resolve_collection_ref (pull_data->remote_repo_local, ref, FALSE, + OSTREE_REPO_RESOLVE_REV_EXT_NONE, &ret_contents, + cancellable, error)) return FALSE; } else if (pull_data->remote_repo_local != NULL) { - if (!ostree_repo_resolve_rev_ext (pull_data->remote_repo_local, - ref->ref_name, FALSE, - OSTREE_REPO_RESOLVE_REV_EXT_NONE, - &ret_contents, error)) + if (!ostree_repo_resolve_rev_ext (pull_data->remote_repo_local, ref->ref_name, FALSE, + OSTREE_REPO_RESOLVE_REV_EXT_NONE, &ret_contents, error)) return FALSE; } else @@ -839,13 +784,11 @@ fetch_ref_contents (OtPullData *pull_data, else filename = g_build_filename ("refs", "mirrors", ref->collection_id, ref->ref_name, NULL); - if (!fetch_mirrored_uri_contents_utf8_sync (pull_data->fetcher, - pull_data->meta_mirrorlist, + if (!fetch_mirrored_uri_contents_utf8_sync (pull_data->fetcher, pull_data->meta_mirrorlist, filename, pull_data->n_network_retries, - &ret_contents, - cancellable, error)) + &ret_contents, cancellable, error)) return FALSE; - + g_assert (ret_contents); g_strchomp (ret_contents); } @@ -853,28 +796,26 @@ fetch_ref_contents (OtPullData *pull_data, if (!ostree_validate_checksum_string (ret_contents, error)) return glnx_prefix_error (error, "Fetching checksum for ref (%s, %s)", - ref->collection_id ?: "(empty)", - ref->ref_name); + ref->collection_id ?: "(empty)", ref->ref_name); ot_transfer_out_value (out_contents, &ret_contents); return TRUE; } static gboolean -lookup_commit_checksum_and_collection_from_summary (OtPullData *pull_data, - const OstreeCollectionRef *ref, - char **out_checksum, - gsize *out_size, - char **out_collection_id, - GError **error) +lookup_commit_checksum_and_collection_from_summary (OtPullData *pull_data, + const OstreeCollectionRef *ref, + char **out_checksum, gsize *out_size, + char **out_collection_id, GError **error) { - g_autoptr(GVariant) additional_metadata = g_variant_get_child_value (pull_data->summary, 1); + g_autoptr (GVariant) additional_metadata = g_variant_get_child_value (pull_data->summary, 1); const gchar *main_collection_id; - if (!g_variant_lookup (additional_metadata, OSTREE_SUMMARY_COLLECTION_ID, "&s", &main_collection_id)) + if (!g_variant_lookup (additional_metadata, OSTREE_SUMMARY_COLLECTION_ID, "&s", + &main_collection_id)) main_collection_id = NULL; - g_autoptr(GVariant) refs = NULL; + g_autoptr (GVariant) refs = NULL; const gchar *resolved_collection_id = NULL; if (ref->collection_id == NULL || g_strcmp0 (ref->collection_id, main_collection_id) == 0) @@ -884,12 +825,13 @@ lookup_commit_checksum_and_collection_from_summary (OtPullData * } else if (ref->collection_id != NULL) { - g_autoptr(GVariant) collection_map = NULL; + g_autoptr (GVariant) collection_map = NULL; collection_map = g_variant_lookup_value (additional_metadata, OSTREE_SUMMARY_COLLECTION_MAP, G_VARIANT_TYPE ("a{sa(s(taya{sv}))}")); if (collection_map != NULL) - refs = g_variant_lookup_value (collection_map, ref->collection_id, G_VARIANT_TYPE ("a(s(taya{sv}))")); + refs = g_variant_lookup_value (collection_map, ref->collection_id, + G_VARIANT_TYPE ("a(s(taya{sv}))")); resolved_collection_id = ref->collection_id; } @@ -897,19 +839,20 @@ lookup_commit_checksum_and_collection_from_summary (OtPullData * if (refs == NULL || !ot_variant_bsearch_str (refs, ref->ref_name, &i)) { if (ref->collection_id != NULL) - return glnx_throw (error, "No such branch (%s, %s) in repository summary", ref->collection_id, ref->ref_name); + return glnx_throw (error, "No such branch (%s, %s) in repository summary", + ref->collection_id, ref->ref_name); else return glnx_throw (error, "No such branch '%s' in repository summary", ref->ref_name); } - g_autoptr(GVariant) refdata = g_variant_get_child_value (refs, i); - g_autoptr(GVariant) reftargetdata = g_variant_get_child_value (refdata, 1); + g_autoptr (GVariant) refdata = g_variant_get_child_value (refs, i); + g_autoptr (GVariant) reftargetdata = g_variant_get_child_value (refdata, 1); guint64 commit_size; - g_autoptr(GVariant) commit_csum_v = NULL; + g_autoptr (GVariant) commit_csum_v = NULL; g_variant_get (reftargetdata, "(t@ay@a{sv})", &commit_size, &commit_csum_v, NULL); - if (resolved_collection_id != NULL && - !ostree_validate_collection_id (resolved_collection_id, error)) + if (resolved_collection_id != NULL + && !ostree_validate_collection_id (resolved_collection_id, error)) return FALSE; if (!ostree_validate_structureof_csum_v (commit_csum_v, error)) return FALSE; @@ -931,13 +874,11 @@ fetch_object_data_free (FetchObjectData *fetch_data) } static void -content_fetch_on_write_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) +content_fetch_on_write_complete (GObject *object, GAsyncResult *result, gpointer user_data) { FetchObjectData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; OstreeObjectType objtype; const char *expected_checksum; @@ -945,8 +886,7 @@ content_fetch_on_write_complete (GObject *object, g_autofree char *checksum = NULL; g_autofree char *checksum_obj = NULL; - if (!ostree_repo_write_content_finish ((OstreeRepo*)object, result, - &csum, error)) + if (!ostree_repo_write_content_finish ((OstreeRepo *)object, result, &csum, error)) goto out; checksum = ostree_checksum_from_bytes (csum); @@ -964,7 +904,7 @@ content_fetch_on_write_complete (GObject *object, /* Was this a delta fallback? */ if (g_hash_table_remove (pull_data->requested_fallback_content, expected_checksum)) pull_data->n_fetched_deltapart_fallbacks++; - out: +out: pull_data->n_outstanding_content_write_requests--; /* No retries for local writes. */ check_outstanding_requests_handle_error (pull_data, &local_error); @@ -972,23 +912,23 @@ content_fetch_on_write_complete (GObject *object, } static void -content_fetch_on_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) +content_fetch_on_complete (GObject *object, GAsyncResult *result, gpointer user_data) { OstreeFetcher *fetcher = (OstreeFetcher *)object; FetchObjectData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; GCancellable *cancellable = NULL; guint64 length; - g_auto(GLnxTmpfile) tmpf = { 0, }; - g_autoptr(GInputStream) tmpf_input = NULL; - g_autoptr(GFileInfo) file_info = NULL; - g_autoptr(GVariant) xattrs = NULL; - g_autoptr(GInputStream) file_in = NULL; - g_autoptr(GInputStream) object_input = NULL; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + g_autoptr (GInputStream) tmpf_input = NULL; + g_autoptr (GFileInfo) file_info = NULL; + g_autoptr (GVariant) xattrs = NULL; + g_autoptr (GInputStream) file_in = NULL; + g_autoptr (GInputStream) object_input = NULL; const char *checksum; g_autofree char *checksum_obj = NULL; OstreeObjectType objtype; @@ -1003,8 +943,8 @@ content_fetch_on_complete (GObject *object, checksum_obj = ostree_object_to_string (checksum, objtype); g_debug ("fetch of %s complete", checksum_obj); - const gboolean verifying_bareuseronly = - (pull_data->importflags & _OSTREE_REPO_IMPORT_FLAGS_VERIFY_BAREUSERONLY) > 0; + const gboolean verifying_bareuseronly + = (pull_data->importflags & _OSTREE_REPO_IMPORT_FLAGS_VERIFY_BAREUSERONLY) > 0; /* See comments where we set this variable; this is implementing * the --trusted-http/OSTREE_REPO_PULL_FLAGS_TRUSTED_HTTP flags. @@ -1012,8 +952,8 @@ content_fetch_on_complete (GObject *object, if (pull_data->trusted_http_direct) { g_assert (!verifying_bareuseronly); - if (!_ostree_repo_commit_tmpf_final (pull_data->repo, checksum, objtype, - &tmpf, cancellable, error)) + if (!_ostree_repo_commit_tmpf_final (pull_data->repo, checksum, objtype, &tmpf, cancellable, + error)) goto out; pull_data->n_fetched_content++; } @@ -1023,12 +963,11 @@ content_fetch_on_complete (GObject *object, if (!glnx_fstat (tmpf.fd, &stbuf, error)) goto out; /* Non-mirroring path */ - tmpf_input = g_unix_input_stream_new (glnx_steal_fd (&tmpf.fd), TRUE); + tmpf_input = g_unix_input_stream_new (g_steal_fd (&tmpf.fd), TRUE); /* If it appears corrupted, we'll delete it below */ - if (!ostree_content_stream_parse (TRUE, tmpf_input, stbuf.st_size, FALSE, - &file_in, &file_info, &xattrs, - cancellable, error)) + if (!ostree_content_stream_parse (TRUE, tmpf_input, stbuf.st_size, FALSE, &file_in, + &file_info, &xattrs, cancellable, error)) { g_prefix_error (error, "Parsing %s: ", checksum_obj); goto out; @@ -1040,20 +979,17 @@ content_fetch_on_complete (GObject *object, goto out; } - if (!ostree_raw_file_to_content_stream (file_in, file_info, xattrs, - &object_input, &length, + if (!ostree_raw_file_to_content_stream (file_in, file_info, xattrs, &object_input, &length, cancellable, error)) goto out; pull_data->n_outstanding_content_write_requests++; - ostree_repo_write_content_async (pull_data->repo, checksum, - object_input, length, - cancellable, + ostree_repo_write_content_async (pull_data->repo, checksum, object_input, length, cancellable, content_fetch_on_write_complete, fetch_data); free_fetch_data = FALSE; } - out: +out: g_assert (pull_data->n_outstanding_content_fetches > 0); pull_data->n_outstanding_content_fetches--; @@ -1067,13 +1003,11 @@ content_fetch_on_complete (GObject *object, } static void -on_metadata_written (GObject *object, - GAsyncResult *result, - gpointer user_data) +on_metadata_written (GObject *object, GAsyncResult *result, gpointer user_data) { FetchObjectData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; const char *expected_checksum; OstreeObjectType objtype; @@ -1081,8 +1015,7 @@ on_metadata_written (GObject *object, g_autofree guchar *csum = NULL; g_autofree char *stringified_object = NULL; - if (!ostree_repo_write_metadata_finish ((OstreeRepo*)object, result, - &csum, error)) + if (!ostree_repo_write_metadata_finish ((OstreeRepo *)object, result, &csum, error)) goto out; checksum = ostree_checksum_from_bytes (csum); @@ -1101,9 +1034,10 @@ on_metadata_written (GObject *object, goto out; } - queue_scan_one_metadata_object_c (pull_data, csum, objtype, fetch_data->path, 0, fetch_data->requested_ref); + queue_scan_one_metadata_object_c (pull_data, csum, objtype, fetch_data->path, 0, + fetch_data->requested_ref); - out: +out: g_assert (pull_data->n_outstanding_metadata_write_requests > 0); pull_data->n_outstanding_metadata_write_requests--; fetch_object_data_free (fetch_data); @@ -1113,8 +1047,7 @@ on_metadata_written (GObject *object, } static gboolean -is_parent_commit (OtPullData *pull_data, - const char *checksum) +is_parent_commit (OtPullData *pull_data, const char *checksum) { /* FIXME: Only parent commits are added to the commit_to_depth table, * so if the checksum isn't in the table then a new commit chain is @@ -1125,21 +1058,22 @@ is_parent_commit (OtPullData *pull_data, } static void -meta_fetch_on_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) +meta_fetch_on_complete (GObject *object, GAsyncResult *result, gpointer user_data) { OstreeFetcher *fetcher = (OstreeFetcher *)object; FetchObjectData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; - g_autoptr(GVariant) metadata = NULL; - g_auto(GLnxTmpfile) tmpf = { 0, }; + g_autoptr (GVariant) metadata = NULL; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; const char *checksum; g_autofree char *checksum_obj = NULL; OstreeObjectType objtype; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; gboolean free_fetch_data = TRUE; + gboolean was_enoent = FALSE; ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype); checksum_obj = ostree_object_to_string (checksum, objtype); @@ -1150,6 +1084,7 @@ meta_fetch_on_complete (GObject *object, { if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { + was_enoent = TRUE; if (fetch_data->is_detached_meta) { /* There isn't any detached metadata, just fetch the commit */ @@ -1160,9 +1095,11 @@ meta_fetch_on_complete (GObject *object, g_hash_table_insert (pull_data->fetched_detached_metadata, g_strdup (checksum), NULL); if (!fetch_data->object_is_stored) - enqueue_one_object_request (pull_data, checksum, objtype, fetch_data->path, FALSE, FALSE, fetch_data->requested_ref); + enqueue_one_object_request (pull_data, checksum, objtype, fetch_data->path, FALSE, + FALSE, fetch_data->requested_ref); else - queue_scan_one_metadata_object (pull_data, checksum, objtype, fetch_data->path, 0, fetch_data->requested_ref); + queue_scan_one_metadata_object (pull_data, checksum, objtype, fetch_data->path, 0, + fetch_data->requested_ref); } /* When traversing parents, do not fail on a missing commit. @@ -1170,17 +1107,17 @@ meta_fetch_on_complete (GObject *object, * dangling parent reference. This logic should match the * local case in scan_one_metadata_object. */ - else if (objtype == OSTREE_OBJECT_TYPE_COMMIT && - pull_data->maxdepth != 0 && - is_parent_commit (pull_data, checksum)) + else if (objtype == OSTREE_OBJECT_TYPE_COMMIT && pull_data->maxdepth != 0 + && is_parent_commit (pull_data, checksum)) { g_clear_error (&local_error); - /* If the remote repo supports tombstone commits, check if the commit was intentionally - deleted. */ + /* If the remote repo supports tombstone commits, check if the commit was + intentionally deleted. */ if (pull_data->has_tombstone_commits) { - enqueue_one_object_request (pull_data, checksum, OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, - fetch_data->path, FALSE, FALSE, NULL); + enqueue_one_object_request (pull_data, checksum, + OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, fetch_data->path, + FALSE, FALSE, NULL); } } } @@ -1194,25 +1131,27 @@ meta_fetch_on_complete (GObject *object, if (fetch_data->is_detached_meta) { - if (!ot_variant_read_fd (tmpf.fd, 0, G_VARIANT_TYPE ("a{sv}"), - FALSE, &metadata, error)) + if (!ot_variant_read_fd (tmpf.fd, 0, G_VARIANT_TYPE ("a{sv}"), FALSE, &metadata, error)) goto out; if (!ostree_repo_write_commit_detached_metadata (pull_data->repo, checksum, metadata, pull_data->cancellable, error)) goto out; - g_hash_table_insert (pull_data->fetched_detached_metadata, g_strdup (checksum), g_steal_pointer (&metadata)); + g_hash_table_insert (pull_data->fetched_detached_metadata, g_strdup (checksum), + g_steal_pointer (&metadata)); if (!fetch_data->object_is_stored) - enqueue_one_object_request (pull_data, checksum, objtype, fetch_data->path, FALSE, FALSE, fetch_data->requested_ref); + enqueue_one_object_request (pull_data, checksum, objtype, fetch_data->path, FALSE, FALSE, + fetch_data->requested_ref); else - queue_scan_one_metadata_object (pull_data, checksum, objtype, fetch_data->path, 0, fetch_data->requested_ref); + queue_scan_one_metadata_object (pull_data, checksum, objtype, fetch_data->path, 0, + fetch_data->requested_ref); } else { - if (!ot_variant_read_fd (tmpf.fd, 0, ostree_metadata_variant_type (objtype), - FALSE, &metadata, error)) + if (!ot_variant_read_fd (tmpf.fd, 0, ostree_metadata_variant_type (objtype), FALSE, &metadata, + error)) goto out; /* Compute checksum and verify structure now. Note this is a recent change @@ -1236,7 +1175,8 @@ meta_fetch_on_complete (GObject *object, * to look up from the disk state as well, or insert the on-disk * metadata into this hash. */ - GVariant *detached_data = g_hash_table_lookup (pull_data->fetched_detached_metadata, checksum); + GVariant *detached_data + = g_hash_table_lookup (pull_data->fetched_detached_metadata, checksum); if (!_verify_unwritten_commit (pull_data, checksum, metadata, detached_data, fetch_data->requested_ref, pull_data->cancellable, error)) goto out; @@ -1252,17 +1192,16 @@ meta_fetch_on_complete (GObject *object, * fetch path does for trusted commits. */ ostree_repo_write_metadata_async (pull_data->repo, objtype, NULL, metadata, - pull_data->cancellable, - on_metadata_written, fetch_data); + pull_data->cancellable, on_metadata_written, fetch_data); pull_data->n_outstanding_metadata_write_requests++; free_fetch_data = FALSE; } - out: +out: g_assert (pull_data->n_outstanding_metadata_fetches > 0); pull_data->n_outstanding_metadata_fetches--; - if (local_error == NULL) + if (local_error == NULL && !was_enoent) pull_data->n_fetched_metadata++; if (_ostree_fetcher_should_retry_request (local_error, fetch_data->n_retries_remaining--)) @@ -1275,7 +1214,7 @@ meta_fetch_on_complete (GObject *object, } static void -fetch_static_delta_data_free (gpointer data) +fetch_static_delta_data_free (gpointer data) { FetchStaticDeltaData *fetch_data = data; g_free (fetch_data->expected_checksum); @@ -1286,13 +1225,11 @@ fetch_static_delta_data_free (gpointer data) } static void -on_static_delta_written (GObject *object, - GAsyncResult *result, - gpointer user_data) +on_static_delta_written (GObject *object, GAsyncResult *result, gpointer user_data) { FetchStaticDeltaData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; g_debug ("execute static delta part %s complete", fetch_data->expected_checksum); @@ -1300,7 +1237,7 @@ on_static_delta_written (GObject *object, if (!_ostree_static_delta_part_execute_finish (pull_data->repo, result, error)) goto out; - out: +out: g_assert (pull_data->n_outstanding_deltapart_write_requests > 0); pull_data->n_outstanding_deltapart_write_requests--; /* No need to retry on failure to write locally. */ @@ -1310,17 +1247,17 @@ on_static_delta_written (GObject *object, } static void -static_deltapart_fetch_on_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) +static_deltapart_fetch_on_complete (GObject *object, GAsyncResult *result, gpointer user_data) { OstreeFetcher *fetcher = (OstreeFetcher *)object; FetchStaticDeltaData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; - g_auto(GLnxTmpfile) tmpf = { 0, }; - g_autoptr(GInputStream) in = NULL; - g_autoptr(GVariant) part = NULL; - g_autoptr(GError) local_error = NULL; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + g_autoptr (GInputStream) in = NULL; + g_autoptr (GVariant) part = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; gboolean free_fetch_data = TRUE; @@ -1330,23 +1267,20 @@ static_deltapart_fetch_on_complete (GObject *object, goto out; /* Transfer ownership of the fd */ - in = g_unix_input_stream_new (glnx_steal_fd (&tmpf.fd), TRUE); + in = g_unix_input_stream_new (g_steal_fd (&tmpf.fd), TRUE); /* TODO - make async */ - if (!_ostree_static_delta_part_open (in, NULL, 0, fetch_data->expected_checksum, - &part, pull_data->cancellable, error)) + if (!_ostree_static_delta_part_open (in, NULL, 0, fetch_data->expected_checksum, &part, + pull_data->cancellable, error)) goto out; - _ostree_static_delta_part_execute_async (pull_data->repo, - fetch_data->objects, - part, - pull_data->cancellable, - on_static_delta_written, + _ostree_static_delta_part_execute_async (pull_data->repo, fetch_data->objects, part, + pull_data->cancellable, on_static_delta_written, fetch_data); pull_data->n_outstanding_deltapart_write_requests++; free_fetch_data = FALSE; - out: +out: g_assert (pull_data->n_outstanding_deltapart_fetches > 0); pull_data->n_outstanding_deltapart_fetches--; @@ -1363,21 +1297,19 @@ static_deltapart_fetch_on_complete (GObject *object, } static gboolean -commitstate_is_partial (OtPullData *pull_data, - OstreeRepoCommitState commitstate) +commitstate_is_partial (OtPullData *pull_data, OstreeRepoCommitState commitstate) { return pull_data->legacy_transaction_resuming - || (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0; + || (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0; } -#endif /* HAVE_LIBCURL_OR_LIBSOUP */ +#endif /* HAVE_LIBCURL_OR_LIBSOUP */ /* Reads the collection-id of a given remote from the repo * configuration. */ static char * -get_real_remote_repo_collection_id (OstreeRepo *repo, - const gchar *remote_name) +get_real_remote_repo_collection_id (OstreeRepo *repo, const gchar *remote_name) { /* remote_name == NULL can happen for pull-local */ if (!remote_name) @@ -1385,9 +1317,8 @@ get_real_remote_repo_collection_id (OstreeRepo *repo, g_autofree gchar *remote_collection_id = NULL; if (!ostree_repo_get_remote_option (repo, remote_name, "collection-id", NULL, - &remote_collection_id, NULL) || - (remote_collection_id == NULL) || - (remote_collection_id[0] == '\0')) + &remote_collection_id, NULL) + || (remote_collection_id == NULL) || (remote_collection_id[0] == '\0')) return NULL; return g_steal_pointer (&remote_collection_id); @@ -1405,25 +1336,22 @@ get_remote_repo_collection_id (OtPullData *pull_data) { if (pull_data->remote_repo_local != NULL) { - const char *remote_collection_id = - ostree_repo_get_collection_id (pull_data->remote_repo_local); - if ((remote_collection_id == NULL) || - (remote_collection_id[0] == '\0')) + const char *remote_collection_id + = ostree_repo_get_collection_id (pull_data->remote_repo_local); + if ((remote_collection_id == NULL) || (remote_collection_id[0] == '\0')) return NULL; return g_strdup (remote_collection_id); } - return get_real_remote_repo_collection_id (pull_data->repo, - pull_data->remote_name); + return get_real_remote_repo_collection_id (pull_data->repo, pull_data->remote_name); } -#endif /* HAVE_LIBCURL_OR_LIBSOUP */ +#endif /* HAVE_LIBCURL_OR_LIBSOUP */ /* Check whether the given remote exists, has a `collection-id` key set, and it * equals @collection_id. If so, return %TRUE. Otherwise, %FALSE. */ static gboolean -check_remote_matches_collection_id (OstreeRepo *repo, - const gchar *remote_name, +check_remote_matches_collection_id (OstreeRepo *repo, const gchar *remote_name, const gchar *collection_id) { g_autofree gchar *remote_collection_id = NULL; @@ -1458,15 +1386,13 @@ check_remote_matches_collection_id (OstreeRepo *repo, * Since: 2018.6 */ OstreeRemote * -ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, - const gchar *collection_id, - GCancellable *cancellable, - GError **error) +ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, const gchar *collection_id, + GCancellable *cancellable, GError **error) { #ifndef OSTREE_DISABLE_GPGME gsize i; - g_auto(GStrv) remotes = NULL; - g_autoptr(OstreeRemote) keyring_remote = NULL; + g_auto (GStrv) remotes = NULL; + g_autoptr (OstreeRemote) keyring_remote = NULL; g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); g_return_val_if_fail (ostree_validate_collection_id (collection_id, NULL), NULL); @@ -1478,29 +1404,29 @@ ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, for (i = 0; remotes != NULL && remotes[i] != NULL; i++) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; if (!check_remote_matches_collection_id (self, remotes[i], collection_id)) continue; if (keyring_remote == NULL) { - g_debug ("%s: Found match for collection ‘%s’ in remote ‘%s’.", - G_STRFUNC, collection_id, remotes[i]); + g_debug ("%s: Found match for collection ‘%s’ in remote ‘%s’.", G_STRFUNC, collection_id, + remotes[i]); keyring_remote = _ostree_repo_get_remote_inherited (self, remotes[i], &local_error); if (keyring_remote == NULL) { - g_debug ("%s: Error loading remote ‘%s’: %s", - G_STRFUNC, remotes[i], local_error->message); + g_debug ("%s: Error loading remote ‘%s’: %s", G_STRFUNC, remotes[i], + local_error->message); continue; } - if (g_strcmp0 (keyring_remote->keyring, "") == 0 || - g_strcmp0 (keyring_remote->keyring, "/dev/null") == 0) + if (g_strcmp0 (keyring_remote->keyring, "") == 0 + || g_strcmp0 (keyring_remote->keyring, "/dev/null") == 0) { - g_debug ("%s: Ignoring remote ‘%s’ as it has no keyring configured.", - G_STRFUNC, remotes[i]); + g_debug ("%s: Ignoring remote ‘%s’ as it has no keyring configured.", G_STRFUNC, + remotes[i]); g_clear_object (&keyring_remote); continue; } @@ -1511,8 +1437,7 @@ ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, { g_debug ("%s: Duplicate keyring for collection ‘%s’ in remote ‘%s’." "Keyring will be loaded from remote ‘%s’.", - G_STRFUNC, collection_id, remotes[i], - keyring_remote->name); + G_STRFUNC, collection_id, remotes[i], keyring_remote->name); } } @@ -1521,14 +1446,12 @@ ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No keyring found configured locally for collection ‘%s’", - collection_id); + "No keyring found configured locally for collection ‘%s’", collection_id); return NULL; } #else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "'%s': GPG feature is disabled in a build time", - __FUNCTION__); + "'%s': GPG feature is disabled in a build time", __FUNCTION__); return NULL; #endif /* OSTREE_DISABLE_GPGME */ } @@ -1539,17 +1462,12 @@ ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, * more things to fetch. */ static gboolean -scan_commit_object (OtPullData *pull_data, - const char *checksum, - guint recursion_depth, - const OstreeCollectionRef *ref, - GCancellable *cancellable, - GError **error) +scan_commit_object (OtPullData *pull_data, const char *checksum, guint recursion_depth, + const OstreeCollectionRef *ref, GCancellable *cancellable, GError **error) { gpointer depthp; gint depth; - if (g_hash_table_lookup_extended (pull_data->commit_to_depth, checksum, - NULL, &depthp)) + if (g_hash_table_lookup_extended (pull_data->commit_to_depth, checksum, NULL, &depthp)) { depth = GPOINTER_TO_INT (depthp); } @@ -1562,10 +1480,9 @@ scan_commit_object (OtPullData *pull_data, /* See comment in process_verify_result() - we now gpg check before writing, * but also ensure we've done it here if not already. */ - if (pull_data->gpg_verify && - !g_hash_table_contains (pull_data->verified_commits, checksum)) + if (pull_data->gpg_verify && !g_hash_table_contains (pull_data->verified_commits, checksum)) { - g_autoptr(OstreeGpgVerifyResult) result = NULL; + g_autoptr (OstreeGpgVerifyResult) result = NULL; const char *keyring_remote = NULL; if (ref != NULL) @@ -1573,20 +1490,17 @@ scan_commit_object (OtPullData *pull_data, if (keyring_remote == NULL) keyring_remote = pull_data->remote_name; - result = ostree_repo_verify_commit_for_remote (pull_data->repo, - checksum, - keyring_remote, - cancellable, - error); + result = ostree_repo_verify_commit_for_remote (pull_data->repo, checksum, keyring_remote, + cancellable, error); if (!_process_gpg_verify_result (pull_data, checksum, result, error)) return FALSE; } #endif /* OSTREE_DISABLE_GPGME */ - if (pull_data->signapi_commit_verifiers && - !g_hash_table_contains (pull_data->signapi_verified_commits, checksum)) + if (pull_data->signapi_commit_verifiers + && !g_hash_table_contains (pull_data->signapi_verified_commits, checksum)) { - g_autoptr(GError) last_verification_error = NULL; + g_autoptr (GError) last_verification_error = NULL; gboolean found_any_signature = FALSE; gboolean found_valid_signature = FALSE; g_autofree char *success_message = NULL; @@ -1598,17 +1512,14 @@ scan_commit_object (OtPullData *pull_data, found_any_signature = TRUE; /* Set return to true if any sign fit */ - if (ostree_sign_commit_verify (sign, - pull_data->repo, - checksum, - &success_message, - cancellable, - last_verification_error ? NULL : &last_verification_error)) + if (ostree_sign_commit_verify (sign, pull_data->repo, checksum, &success_message, + cancellable, + last_verification_error ? NULL : &last_verification_error)) { found_valid_signature = TRUE; break; } - } + } if (!found_any_signature) return glnx_throw (error, "No signatures found for commit %s", checksum); @@ -1620,7 +1531,8 @@ scan_commit_object (OtPullData *pull_data, return glnx_prefix_error (error, "Can't verify commit %s", checksum); } g_assert (success_message); - g_hash_table_insert (pull_data->signapi_verified_commits, g_strdup (checksum), g_steal_pointer (&success_message)); + g_hash_table_insert (pull_data->signapi_verified_commits, g_strdup (checksum), + g_steal_pointer (&success_message)); } /* If we found a legacy transaction flag, assume we have to scan. @@ -1628,10 +1540,14 @@ scan_commit_object (OtPullData *pull_data, * https://github.com/ostreedev/ostree/issues/543 */ OstreeRepoCommitState commitstate; - g_autoptr(GVariant) commit = NULL; + g_autoptr (GVariant) commit = NULL; if (!ostree_repo_load_commit (pull_data->repo, checksum, &commit, &commitstate, error)) return FALSE; + /* Do this early because if it's corrupt, something else is going wrong */ + if (!ostree_validate_structureof_commit (commit, error)) + return glnx_prefix_error (error, "Validating commit %s", checksum); + if (!pull_data->disable_verify_bindings) { /* If ref is non-NULL then the commit we fetched was requested through @@ -1640,8 +1556,7 @@ scan_commit_object (OtPullData *pull_data, */ g_autofree char *remote_collection_id = NULL; remote_collection_id = get_remote_repo_collection_id (pull_data); - if (!_ostree_repo_verify_bindings (remote_collection_id, - (ref != NULL) ? ref->ref_name : NULL, + if (!_ostree_repo_verify_bindings (remote_collection_id, (ref != NULL) ? ref->ref_name : NULL, commit, error)) return glnx_prefix_error (error, "Commit %s", checksum); } @@ -1653,15 +1568,14 @@ scan_commit_object (OtPullData *pull_data, g_assert (ref); g_assert_cmpint (recursion_depth, ==, 0); const char *orig_rev = NULL; - if (!g_hash_table_lookup_extended (pull_data->ref_original_commits, - ref, NULL, (void**)&orig_rev)) + if (!g_hash_table_lookup_extended (pull_data->ref_original_commits, ref, NULL, + (void **)&orig_rev)) g_assert_not_reached (); - g_autoptr(GVariant) orig_commit = NULL; + g_autoptr (GVariant) orig_commit = NULL; if (orig_rev) { - if (!ostree_repo_load_commit (pull_data->repo, orig_rev, - &orig_commit, NULL, error)) + if (!ostree_repo_load_commit (pull_data->repo, orig_rev, &orig_commit, NULL, error)) return glnx_prefix_error (error, "Reading %s for timestamp-check", ref->ref_name); guint64 orig_ts = ostree_commit_get_timestamp (orig_commit); @@ -1671,54 +1585,43 @@ scan_commit_object (OtPullData *pull_data, } if (pull_data->timestamp_check_from_rev) { - g_autoptr(GVariant) timestamp_commit = NULL; + g_autoptr (GVariant) timestamp_commit = NULL; if (!ostree_repo_load_commit (pull_data->repo, pull_data->timestamp_check_from_rev, ×tamp_commit, NULL, error)) return glnx_prefix_error (error, "Reading %s for timestamp-check-from-rev", pull_data->timestamp_check_from_rev); guint64 ts = ostree_commit_get_timestamp (timestamp_commit); - if (!_ostree_compare_timestamps (pull_data->timestamp_check_from_rev, ts, checksum, new_ts, error)) + if (!_ostree_compare_timestamps (pull_data->timestamp_check_from_rev, ts, checksum, new_ts, + error)) return FALSE; } /* If we found a legacy transaction flag, assume all commits are partial */ gboolean is_partial = commitstate_is_partial (pull_data, commitstate); - /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */ - g_autoptr(GVariant) parent_csum = NULL; - const guchar *parent_csum_bytes = NULL; - g_variant_get_child (commit, 1, "@ay", &parent_csum); - if (g_variant_n_children (parent_csum) > 0) - { - parent_csum_bytes = ostree_checksum_bytes_peek_validate (parent_csum, error); - if (parent_csum_bytes == NULL) - return FALSE; - } - - if (parent_csum_bytes != NULL && (pull_data->maxdepth == -1 || depth > 0)) + if (pull_data->maxdepth == -1 || depth > 0) { - char parent_checksum[OSTREE_SHA256_STRING_LEN+1]; - ostree_checksum_inplace_from_bytes (parent_csum_bytes, parent_checksum); - - int parent_depth = (depth > 0) ? depth - 1 : -1; - g_hash_table_insert (pull_data->commit_to_depth, g_strdup (parent_checksum), - GINT_TO_POINTER (parent_depth)); - queue_scan_one_metadata_object_c (pull_data, parent_csum_bytes, - OSTREE_OBJECT_TYPE_COMMIT, - NULL, - recursion_depth + 1, - NULL); + g_autofree char *parent_checksum = ostree_commit_get_parent (commit); + if (parent_checksum) + { + int parent_depth = (depth > 0) ? depth - 1 : -1; + g_hash_table_insert (pull_data->commit_to_depth, g_strdup (parent_checksum), + GINT_TO_POINTER (parent_depth)); + queue_scan_one_metadata_object (pull_data, parent_checksum, OSTREE_OBJECT_TYPE_COMMIT, + NULL, recursion_depth + 1, NULL); + } } /* We only recurse to looking whether we need dirtree/dirmeta * objects if the commit is partial, and we're not doing a - * commit-only fetch. + * commit-only fetch nor is it the target of a static delta. */ - if (is_partial && !pull_data->is_commit_only) + if (is_partial && !pull_data->is_commit_only + && !g_hash_table_contains (pull_data->static_delta_targets, checksum)) { - g_autoptr(GVariant) tree_contents_csum = NULL; - g_autoptr(GVariant) tree_meta_csum = NULL; + g_autoptr (GVariant) tree_contents_csum = NULL; + g_autoptr (GVariant) tree_meta_csum = NULL; const guchar *tree_contents_csum_bytes; const guchar *tree_meta_csum_bytes; @@ -1734,21 +1637,20 @@ scan_commit_object (OtPullData *pull_data, return FALSE; queue_scan_one_metadata_object_c (pull_data, tree_contents_csum_bytes, - OSTREE_OBJECT_TYPE_DIR_TREE, "/", recursion_depth + 1, NULL); + OSTREE_OBJECT_TYPE_DIR_TREE, "/", recursion_depth + 1, + NULL); queue_scan_one_metadata_object_c (pull_data, tree_meta_csum_bytes, - OSTREE_OBJECT_TYPE_DIR_META, NULL, recursion_depth + 1, NULL); + OSTREE_OBJECT_TYPE_DIR_META, NULL, recursion_depth + 1, + NULL); } return TRUE; } static void -queue_scan_one_metadata_object (OtPullData *pull_data, - const char *csum, - OstreeObjectType objtype, - const char *path, - guint recursion_depth, +queue_scan_one_metadata_object (OtPullData *pull_data, const char *csum, OstreeObjectType objtype, + const char *path, guint recursion_depth, const OstreeCollectionRef *ref) { guchar buf[OSTREE_SHA256_DIGEST_LEN]; @@ -1757,19 +1659,15 @@ queue_scan_one_metadata_object (OtPullData *pull_data, } static void -queue_scan_one_metadata_object_s (OtPullData *pull_data, - ScanObjectQueueData *scan_data) +queue_scan_one_metadata_object_s (OtPullData *pull_data, ScanObjectQueueData *scan_data) { g_queue_push_tail (&pull_data->scan_object_queue, scan_data); ensure_idle_queued (pull_data); } static void -queue_scan_one_metadata_object_c (OtPullData *pull_data, - const guchar *csum, - OstreeObjectType objtype, - const char *path, - guint recursion_depth, +queue_scan_one_metadata_object_c (OtPullData *pull_data, const guchar *csum, + OstreeObjectType objtype, const char *path, guint recursion_depth, const OstreeCollectionRef *ref) { ScanObjectQueueData *scan_data = g_new0 (ScanObjectQueueData, 1); @@ -1788,16 +1686,11 @@ queue_scan_one_metadata_object_c (OtPullData *pull_data, * execution of this function. */ static gboolean -scan_one_metadata_object (OtPullData *pull_data, - const char *checksum, - OstreeObjectType objtype, - const char *path, - guint recursion_depth, - const OstreeCollectionRef *ref, - GCancellable *cancellable, - GError **error) +scan_one_metadata_object (OtPullData *pull_data, const char *checksum, OstreeObjectType objtype, + const char *path, guint recursion_depth, const OstreeCollectionRef *ref, + GCancellable *cancellable, GError **error) { - g_autoptr(GVariant) object = ostree_object_name_serialize (checksum, objtype); + g_autoptr (GVariant) object = ostree_object_name_serialize (checksum, objtype); /* It may happen that we've already looked at this object (think shared * dirtree subtrees), if that's the case, we're done */ @@ -1807,8 +1700,7 @@ scan_one_metadata_object (OtPullData *pull_data, gboolean is_requested = g_hash_table_lookup (pull_data->requested_metadata, object) != NULL; /* Determine if we already have the object */ gboolean is_stored; - if (!ostree_repo_has_object (pull_data->repo, objtype, checksum, &is_stored, - cancellable, error)) + if (!ostree_repo_has_object (pull_data->repo, objtype, checksum, &is_stored, cancellable, error)) return FALSE; /* Are we pulling an object we don't have from a local repo? */ @@ -1821,10 +1713,9 @@ scan_one_metadata_object (OtPullData *pull_data, return FALSE; } - g_autoptr(GError) local_error = NULL; - if (!_ostree_repo_import_object (pull_data->repo, pull_data->remote_repo_local, - objtype, checksum, pull_data->importflags, - cancellable, &local_error)) + g_autoptr (GError) local_error = NULL; + if (!_ostree_repo_import_object (pull_data->repo, pull_data->remote_repo_local, objtype, + checksum, pull_data->importflags, cancellable, &local_error)) { /* When traversing parents, do not fail on a missing commit. * We may be pulling from a partial repository that ends in a @@ -1833,10 +1724,9 @@ scan_one_metadata_object (OtPullData *pull_data, * * Note early return. */ - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) && - objtype == OSTREE_OBJECT_TYPE_COMMIT && - pull_data->maxdepth != 0 && - is_parent_commit (pull_data, checksum)) + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) + && objtype == OSTREE_OBJECT_TYPE_COMMIT && pull_data->maxdepth != 0 + && is_parent_commit (pull_data, checksum)) { g_clear_error (&local_error); @@ -1846,9 +1736,8 @@ scan_one_metadata_object (OtPullData *pull_data, if (pull_data->has_tombstone_commits) { if (!_ostree_repo_import_object (pull_data->repo, pull_data->remote_repo_local, - OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, - checksum, pull_data->importflags, - cancellable, error)) + OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, checksum, + pull_data->importflags, cancellable, error)) return FALSE; } @@ -1878,8 +1767,8 @@ scan_one_metadata_object (OtPullData *pull_data, OstreeRepo *refd_repo = pull_data->localcache_repos->pdata[i]; gboolean localcache_repo_has_obj; - if (!ostree_repo_has_object (refd_repo, objtype, checksum, - &localcache_repo_has_obj, cancellable, error)) + if (!ostree_repo_has_object (refd_repo, objtype, checksum, &localcache_repo_has_obj, + cancellable, error)) return FALSE; if (!localcache_repo_has_obj) continue; @@ -1889,9 +1778,8 @@ scan_one_metadata_object (OtPullData *pull_data, if (!ostree_repo_mark_commit_partial (pull_data->repo, checksum, TRUE, error)) return FALSE; } - if (!_ostree_repo_import_object (pull_data->repo, refd_repo, - objtype, checksum, pull_data->importflags, - cancellable, error)) + if (!_ostree_repo_import_object (pull_data->repo, refd_repo, objtype, checksum, + pull_data->importflags, cancellable, error)) return FALSE; /* See comment above */ if (objtype == OSTREE_OBJECT_TYPE_COMMIT) @@ -1910,7 +1798,8 @@ scan_one_metadata_object (OtPullData *pull_data, g_hash_table_add (pull_data->requested_metadata, g_variant_ref (object)); do_fetch_detached = (objtype == OSTREE_OBJECT_TYPE_COMMIT); - enqueue_one_object_request (pull_data, checksum, objtype, path, do_fetch_detached, FALSE, ref); + enqueue_one_object_request (pull_data, checksum, objtype, path, do_fetch_detached, FALSE, + ref); } else if (is_stored && objtype == OSTREE_OBJECT_TYPE_COMMIT) { @@ -1931,8 +1820,8 @@ scan_one_metadata_object (OtPullData *pull_data, } else if (is_stored && objtype == OSTREE_OBJECT_TYPE_DIR_TREE) { - if (!scan_dirtree_object (pull_data, checksum, path, recursion_depth, - pull_data->cancellable, error)) + if (!scan_dirtree_object (pull_data, checksum, path, recursion_depth, pull_data->cancellable, + error)) return glnx_prefix_error (error, "Validating dirtree %s (%s)", checksum, path); g_hash_table_add (pull_data->scanned_metadata, g_variant_ref (object)); @@ -1943,8 +1832,7 @@ scan_one_metadata_object (OtPullData *pull_data, } static void -enqueue_one_object_request_s (OtPullData *pull_data, - FetchObjectData *fetch_data) +enqueue_one_object_request_s (OtPullData *pull_data, FetchObjectData *fetch_data) { const char *checksum; OstreeObjectType objtype; @@ -1955,13 +1843,13 @@ enqueue_one_object_request_s (OtPullData *pull_data, /* Are too many requests are in flight? */ if (fetcher_queue_is_full (pull_data)) { - g_debug ("queuing fetch of %s.%s%s", checksum, - ostree_object_type_to_string (objtype), + g_debug ("queuing fetch of %s.%s%s", checksum, ostree_object_type_to_string (objtype), fetch_data->is_detached_meta ? " (detached)" : ""); if (is_meta) { - g_hash_table_insert (pull_data->pending_fetch_metadata, g_variant_ref (fetch_data->object), fetch_data); + g_hash_table_insert (pull_data->pending_fetch_metadata, + g_variant_ref (fetch_data->object), fetch_data); } else { @@ -1975,12 +1863,8 @@ enqueue_one_object_request_s (OtPullData *pull_data, } static void -enqueue_one_object_request (OtPullData *pull_data, - const char *checksum, - OstreeObjectType objtype, - const char *path, - gboolean is_detached_meta, - gboolean object_is_stored, +enqueue_one_object_request (OtPullData *pull_data, const char *checksum, OstreeObjectType objtype, + const char *path, gboolean is_detached_meta, gboolean object_is_stored, const OstreeCollectionRef *ref) { FetchObjectData *fetch_data; @@ -2003,8 +1887,7 @@ enqueue_one_object_request (OtPullData *pull_data, } static void -start_fetch (OtPullData *pull_data, - FetchObjectData *fetch) +start_fetch (OtPullData *pull_data, FetchObjectData *fetch) { g_autofree char *obj_subpath = NULL; guint64 *expected_max_size_p; @@ -2015,8 +1898,7 @@ start_fetch (OtPullData *pull_data, ostree_object_name_deserialize (fetch->object, &expected_checksum, &objtype); - g_debug ("starting fetch of %s.%s%s", expected_checksum, - ostree_object_type_to_string (objtype), + g_debug ("starting fetch of %s.%s%s", expected_checksum, ostree_object_type_to_string (objtype), fetch->is_detached_meta ? " (detached)" : ""); gboolean is_meta = OSTREE_OBJECT_TYPE_IS_META (objtype); @@ -2030,7 +1912,8 @@ start_fetch (OtPullData *pull_data, if (fetch->is_detached_meta) { char buf[_OSTREE_LOOSE_PATH_MAX]; - _ostree_loose_path (buf, expected_checksum, OSTREE_OBJECT_TYPE_COMMIT_META, pull_data->remote_mode); + _ostree_loose_path (buf, expected_checksum, OSTREE_OBJECT_TYPE_COMMIT_META, + pull_data->remote_mode); obj_subpath = g_build_filename ("objects", buf, NULL); mirrorlist = pull_data->meta_mirrorlist; flags |= OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT; @@ -2044,7 +1927,10 @@ start_fetch (OtPullData *pull_data, /* We may have determined maximum sizes from the summary file content; if so, * honor it. Otherwise, metadata has a baseline max size. */ - expected_max_size_p = fetch->is_detached_meta ? NULL : g_hash_table_lookup (pull_data->expected_commit_sizes, expected_checksum); + expected_max_size_p + = fetch->is_detached_meta + ? NULL + : g_hash_table_lookup (pull_data->expected_commit_sizes, expected_checksum); if (expected_max_size_p) expected_max_size = *expected_max_size_p; else if (OSTREE_OBJECT_TYPE_IS_META (objtype)) @@ -2054,33 +1940,28 @@ start_fetch (OtPullData *pull_data, if (!is_meta && pull_data->trusted_http_direct) flags |= OSTREE_FETCHER_REQUEST_LINKABLE; - _ostree_fetcher_request_to_tmpfile (pull_data->fetcher, mirrorlist, - obj_subpath, flags, NULL, 0, expected_max_size, - is_meta ? OSTREE_REPO_PULL_METADATA_PRIORITY - : OSTREE_REPO_PULL_CONTENT_PRIORITY, - pull_data->cancellable, - is_meta ? meta_fetch_on_complete : content_fetch_on_complete, fetch); + _ostree_fetcher_request_to_tmpfile ( + pull_data->fetcher, mirrorlist, obj_subpath, flags, NULL, 0, expected_max_size, + is_meta ? OSTREE_REPO_PULL_METADATA_PRIORITY : OSTREE_REPO_PULL_CONTENT_PRIORITY, + pull_data->cancellable, is_meta ? meta_fetch_on_complete : content_fetch_on_complete, fetch); } /* Deprecated: code should load options from the `summary` file rather than * downloading the remote’s `config` file, to save on network round trips. */ static gboolean -load_remote_repo_config (OtPullData *pull_data, - GKeyFile **out_keyfile, - GCancellable *cancellable, - GError **error) +load_remote_repo_config (OtPullData *pull_data, GKeyFile **out_keyfile, GCancellable *cancellable, + GError **error) { g_autofree char *contents = NULL; - if (!fetch_mirrored_uri_contents_utf8_sync (pull_data->fetcher, - pull_data->meta_mirrorlist, - "config", pull_data->n_network_retries, - &contents, cancellable, error)) + if (!fetch_mirrored_uri_contents_utf8_sync (pull_data->fetcher, pull_data->meta_mirrorlist, + "config", pull_data->n_network_retries, &contents, + cancellable, error)) return FALSE; + g_assert (contents); - g_autoptr(GKeyFile) ret_keyfile = g_key_file_new (); - if (!g_key_file_load_from_data (ret_keyfile, contents, strlen (contents), - 0, error)) + g_autoptr (GKeyFile) ret_keyfile = g_key_file_new (); + if (!g_key_file_load_from_data (ret_keyfile, contents, strlen (contents), 0, error)) return glnx_prefix_error (error, "Parsing config"); ot_transfer_out_value (out_keyfile, &ret_keyfile); @@ -2088,18 +1969,16 @@ load_remote_repo_config (OtPullData *pull_data, } static gboolean -process_one_static_delta_fallback (OtPullData *pull_data, - gboolean delta_byteswap, - GVariant *fallback_object, - GCancellable *cancellable, - GError **error) +process_one_static_delta_fallback (OtPullData *pull_data, gboolean delta_byteswap, + GVariant *fallback_object, GCancellable *cancellable, + GError **error) { guint8 objtype_y; - g_autoptr(GVariant) csum_v = NULL; + g_autoptr (GVariant) csum_v = NULL; guint64 compressed_size, uncompressed_size; - g_variant_get (fallback_object, "(y@aytt)", - &objtype_y, &csum_v, &compressed_size, &uncompressed_size); + g_variant_get (fallback_object, "(y@aytt)", &objtype_y, &csum_v, &compressed_size, + &uncompressed_size); if (!ostree_validate_structureof_objtype (objtype_y, error)) return FALSE; @@ -2117,9 +1996,7 @@ process_one_static_delta_fallback (OtPullData *pull_data, g_autofree char *checksum = ostree_checksum_from_bytes_v (csum_v); gboolean is_stored; - if (!ostree_repo_has_object (pull_data->repo, objtype, checksum, - &is_stored, - cancellable, error)) + if (!ostree_repo_has_object (pull_data->repo, objtype, checksum, &is_stored, cancellable, error)) return FALSE; if (is_stored) @@ -2144,8 +2021,9 @@ process_one_static_delta_fallback (OtPullData *pull_data, * for it as logically part of the delta fetch. */ g_hash_table_add (pull_data->requested_fallback_content, g_strdup (checksum)); - enqueue_one_object_request (pull_data, checksum, OSTREE_OBJECT_TYPE_FILE, NULL, FALSE, FALSE, NULL); - checksum = NULL; /* We transferred ownership to the requested_content hash */ + enqueue_one_object_request (pull_data, checksum, OSTREE_OBJECT_TYPE_FILE, NULL, FALSE, + FALSE, NULL); + checksum = NULL; /* We transferred ownership to the requested_content hash */ } } } @@ -2154,13 +2032,11 @@ process_one_static_delta_fallback (OtPullData *pull_data, } static void -enqueue_one_static_delta_part_request_s (OtPullData *pull_data, - FetchStaticDeltaData *fetch_data) +enqueue_one_static_delta_part_request_s (OtPullData *pull_data, FetchStaticDeltaData *fetch_data) { if (fetcher_queue_is_full (pull_data)) { - g_debug ("queuing fetch of static delta %s-%s part %u", - fetch_data->from_revision ?: "empty", + g_debug ("queuing fetch of static delta %s-%s part %u", fetch_data->from_revision ?: "empty", fetch_data->to_revision, fetch_data->i); g_hash_table_add (pull_data->pending_fetch_deltaparts, fetch_data); @@ -2172,37 +2048,31 @@ enqueue_one_static_delta_part_request_s (OtPullData *pull_data, } static void -start_fetch_deltapart (OtPullData *pull_data, - FetchStaticDeltaData *fetch) +start_fetch_deltapart (OtPullData *pull_data, FetchStaticDeltaData *fetch) { - g_autofree char *deltapart_path = _ostree_get_relative_static_delta_part_path (fetch->from_revision, fetch->to_revision, fetch->i); + g_autofree char *deltapart_path = _ostree_get_relative_static_delta_part_path ( + fetch->from_revision, fetch->to_revision, fetch->i); g_debug ("starting fetch of deltapart %s", deltapart_path); pull_data->n_outstanding_deltapart_fetches++; - g_assert_cmpint (pull_data->n_outstanding_deltapart_fetches, <=, _OSTREE_MAX_OUTSTANDING_DELTAPART_REQUESTS); - _ostree_fetcher_request_to_tmpfile (pull_data->fetcher, - pull_data->content_mirrorlist, + g_assert_cmpint (pull_data->n_outstanding_deltapart_fetches, <=, + _OSTREE_MAX_OUTSTANDING_DELTAPART_REQUESTS); + _ostree_fetcher_request_to_tmpfile (pull_data->fetcher, pull_data->content_mirrorlist, deltapart_path, 0, NULL, 0, fetch->size, - OSTREE_FETCHER_DEFAULT_PRIORITY, - pull_data->cancellable, - static_deltapart_fetch_on_complete, - fetch); + OSTREE_FETCHER_DEFAULT_PRIORITY, pull_data->cancellable, + static_deltapart_fetch_on_complete, fetch); } static gboolean -process_one_static_delta (OtPullData *pull_data, - const char *from_revision, - const char *to_revision, - GVariant *delta_superblock, - const OstreeCollectionRef *ref, - GCancellable *cancellable, - GError **error) +process_one_static_delta (OtPullData *pull_data, const char *from_revision, const char *to_revision, + GVariant *delta_superblock, const OstreeCollectionRef *ref, + GCancellable *cancellable, GError **error) { gboolean delta_byteswap = _ostree_delta_needs_byteswap (delta_superblock); /* Parsing OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */ - g_autoptr(GVariant) metadata = g_variant_get_child_value (delta_superblock, 0); - g_autoptr(GVariant) headers = g_variant_get_child_value (delta_superblock, 6); - g_autoptr(GVariant) fallback_objects = g_variant_get_child_value (delta_superblock, 7); + g_autoptr (GVariant) metadata = g_variant_get_child_value (delta_superblock, 0); + g_autoptr (GVariant) headers = g_variant_get_child_value (delta_superblock, 6); + g_autoptr (GVariant) fallback_objects = g_variant_get_child_value (delta_superblock, 7); /* Gather free space so we can do a check below */ struct statvfs stvfsbuf; @@ -2213,11 +2083,9 @@ process_one_static_delta (OtPullData *pull_data, guint n = g_variant_n_children (fallback_objects); for (guint i = 0; i < n; i++) { - g_autoptr(GVariant) fallback_object = - g_variant_get_child_value (fallback_objects, i); + g_autoptr (GVariant) fallback_object = g_variant_get_child_value (fallback_objects, i); - if (!process_one_static_delta_fallback (pull_data, delta_byteswap, - fallback_object, + if (!process_one_static_delta_fallback (pull_data, delta_byteswap, fallback_object, cancellable, error)) return FALSE; } @@ -2225,7 +2093,7 @@ process_one_static_delta (OtPullData *pull_data, /* Write the to-commit object */ if (!pull_data->dry_run) { - g_autoptr(GVariant) to_csum_v = g_variant_get_child_value (delta_superblock, 3); + g_autoptr (GVariant) to_csum_v = g_variant_get_child_value (delta_superblock, 3); if (!ostree_validate_structureof_csum_v (to_csum_v, error)) return FALSE; g_autofree char *to_checksum = ostree_checksum_from_bytes_v (to_csum_v); @@ -2237,36 +2105,36 @@ process_one_static_delta (OtPullData *pull_data, if (!have_to_commit) { - g_autoptr(GVariant) to_commit = g_variant_get_child_value (delta_superblock, 4); - g_autofree char *detached_path = _ostree_get_relative_static_delta_path (from_revision, to_revision, "commitmeta"); - g_autoptr(GVariant) detached_data = g_variant_lookup_value (metadata, detached_path, G_VARIANT_TYPE("a{sv}")); + g_autoptr (GVariant) to_commit = g_variant_get_child_value (delta_superblock, 4); + g_autofree char *detached_path + = _ostree_get_relative_static_delta_path (from_revision, to_revision, "commitmeta"); + g_autoptr (GVariant) detached_data + = g_variant_lookup_value (metadata, detached_path, G_VARIANT_TYPE ("a{sv}")); - if (!_verify_unwritten_commit (pull_data, to_revision, to_commit, detached_data, - ref, cancellable, error)) + if (!_verify_unwritten_commit (pull_data, to_revision, to_commit, detached_data, ref, + cancellable, error)) return FALSE; if (!ostree_repo_mark_commit_partial (pull_data->repo, to_revision, TRUE, error)) return FALSE; - if (detached_data && !ostree_repo_write_commit_detached_metadata (pull_data->repo, - to_revision, - detached_data, - cancellable, - error)) + if (detached_data + && !ostree_repo_write_commit_detached_metadata (pull_data->repo, to_revision, + detached_data, cancellable, error)) return FALSE; FetchObjectData *fetch_data = g_new0 (FetchObjectData, 1); fetch_data->pull_data = pull_data; - fetch_data->object = ostree_object_name_serialize (to_checksum, OSTREE_OBJECT_TYPE_COMMIT); + fetch_data->object + = ostree_object_name_serialize (to_checksum, OSTREE_OBJECT_TYPE_COMMIT); fetch_data->is_detached_meta = FALSE; fetch_data->object_is_stored = FALSE; fetch_data->requested_ref = (ref != NULL) ? ostree_collection_ref_dup (ref) : NULL; fetch_data->n_retries_remaining = pull_data->n_network_retries; ostree_repo_write_metadata_async (pull_data->repo, OSTREE_OBJECT_TYPE_COMMIT, to_checksum, - to_commit, - pull_data->cancellable, - on_metadata_written, fetch_data); + to_commit, pull_data->cancellable, on_metadata_written, + fetch_data); pull_data->n_outstanding_metadata_write_requests++; } } @@ -2278,10 +2146,10 @@ process_one_static_delta (OtPullData *pull_data, { gboolean have_all = FALSE; - g_autoptr(GVariant) header = g_variant_get_child_value (headers, i); - g_autoptr(GVariant) csum_v = NULL; - g_autoptr(GVariant) objects = NULL; - g_autoptr(GBytes) inline_part_bytes = NULL; + g_autoptr (GVariant) header = g_variant_get_child_value (headers, i); + g_autoptr (GVariant) csum_v = NULL; + g_autoptr (GVariant) objects = NULL; + g_autoptr (GBytes) inline_part_bytes = NULL; guint32 version; guint64 size, usize; g_variant_get (header, "(u@aytt@ay)", &version, &csum_v, &size, &usize, &objects); @@ -2296,9 +2164,7 @@ process_one_static_delta (OtPullData *pull_data, if (!csum) return FALSE; - if (!_ostree_repo_static_delta_part_have_all_objects (pull_data->repo, - objects, - &have_all, + if (!_ostree_repo_static_delta_part_have_all_objects (pull_data->repo, objects, &have_all, cancellable, error)) return FALSE; @@ -2307,18 +2173,19 @@ process_one_static_delta (OtPullData *pull_data, if (have_all) { - g_debug ("Have all objects from static delta %s-%s part %u", - from_revision ?: "empty", to_revision, - i); + g_debug ("Have all objects from static delta %s-%s part %u", from_revision ?: "empty", + to_revision, i); pull_data->fetched_deltapart_size += size; pull_data->n_fetched_deltaparts++; continue; } - g_autofree char *deltapart_path = _ostree_get_relative_static_delta_part_path (from_revision, to_revision, i); + g_autofree char *deltapart_path + = _ostree_get_relative_static_delta_part_path (from_revision, to_revision, i); - { g_autoptr(GVariant) part_datav = - g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE ("(yay)")); + { + g_autoptr (GVariant) part_datav + = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE ("(yay)")); if (part_datav) inline_part_bytes = g_variant_get_data_as_bytes (part_datav); @@ -2339,25 +2206,21 @@ process_one_static_delta (OtPullData *pull_data, if (inline_part_bytes != NULL) { - g_autoptr(GInputStream) memin = g_memory_input_stream_new_from_bytes (inline_part_bytes); - g_autoptr(GVariant) inline_delta_part = NULL; + g_autoptr (GInputStream) memin = g_memory_input_stream_new_from_bytes (inline_part_bytes); + g_autoptr (GVariant) inline_delta_part = NULL; /* For inline parts we are relying on per-commit GPG, so don't bother checksumming. */ if (!_ostree_static_delta_part_open (memin, inline_part_bytes, - OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM, - NULL, &inline_delta_part, - cancellable, error)) + OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM, NULL, + &inline_delta_part, cancellable, error)) { fetch_static_delta_data_free (fetch_data); return FALSE; } - _ostree_static_delta_part_execute_async (pull_data->repo, - fetch_data->objects, - inline_delta_part, - pull_data->cancellable, - on_static_delta_written, - fetch_data); + _ostree_static_delta_part_execute_async (pull_data->repo, fetch_data->objects, + inline_delta_part, pull_data->cancellable, + on_static_delta_written, fetch_data); pull_data->n_outstanding_deltapart_write_requests++; } else @@ -2375,7 +2238,8 @@ process_one_static_delta (OtPullData *pull_data, if (delta_required_blocks > stvfsbuf.f_bfree) { g_autofree char *formatted_required = g_format_size (pull_data->total_deltapart_usize); - g_autofree char *formatted_avail = g_format_size (((guint64)stvfsbuf.f_bsize) * stvfsbuf.f_bfree); + g_autofree char *formatted_avail + = g_format_size (((guint64)stvfsbuf.f_bsize) * stvfsbuf.f_bfree); return glnx_throw (error, "Delta requires %s free space, but only %s available", formatted_required, formatted_avail); } @@ -2398,14 +2262,16 @@ process_one_static_delta (OtPullData *pull_data, * There is a %NULL → @to_revision delta, also known as * a "from scratch" delta. */ -typedef struct { - enum { +typedef struct +{ + enum + { DELTA_SEARCH_RESULT_UNCHANGED, DELTA_SEARCH_RESULT_NO_MATCH, DELTA_SEARCH_RESULT_FROM, DELTA_SEARCH_RESULT_SCRATCH, } result; - char from_revision[OSTREE_SHA256_STRING_LEN+1]; + char from_revision[OSTREE_SHA256_STRING_LEN + 1]; } DeltaSearchResult; /* Loop over the static delta data we got from the summary, @@ -2413,14 +2279,12 @@ typedef struct { * See the enum in `DeltaSearchResult` for available result types. */ static gboolean -get_best_static_delta_start_for (OtPullData *pull_data, - const char *to_revision, - DeltaSearchResult *out_result, - GCancellable *cancellable, - GError **error) +get_best_static_delta_start_for (OtPullData *pull_data, const char *to_revision, + DeltaSearchResult *out_result, GCancellable *cancellable, + GError **error) { /* Array of possible from checksums */ - g_autoptr(GPtrArray) candidates = g_ptr_array_new_with_free_func (g_free); + g_autoptr (GPtrArray) candidates = g_ptr_array_new_with_free_func (g_free); const char *newest_candidate = NULL; guint64 newest_candidate_timestamp = 0; @@ -2431,27 +2295,25 @@ get_best_static_delta_start_for (OtPullData *pull_data, /* First, do we already have this commit completely downloaded? */ gboolean have_to_rev; - if (!ostree_repo_has_object (pull_data->repo, OSTREE_OBJECT_TYPE_COMMIT, - to_revision, &have_to_rev, - cancellable, error)) + if (!ostree_repo_has_object (pull_data->repo, OSTREE_OBJECT_TYPE_COMMIT, to_revision, + &have_to_rev, cancellable, error)) return FALSE; if (have_to_rev) { OstreeRepoCommitState to_rev_state; - if (!ostree_repo_load_commit (pull_data->repo, to_revision, - NULL, &to_rev_state, error)) + if (!ostree_repo_load_commit (pull_data->repo, to_revision, NULL, &to_rev_state, error)) return FALSE; - if (!(commitstate_is_partial(pull_data, to_rev_state))) + if (!(commitstate_is_partial (pull_data, to_rev_state))) { /* We already have this commit, we're done! */ out_result->result = DELTA_SEARCH_RESULT_UNCHANGED; - return TRUE; /* Early return */ + return TRUE; /* Early return */ } } /* Loop over all deltas known from the summary file, * finding ones which go to to_revision */ - GLNX_HASH_TABLE_FOREACH (pull_data->summary_deltas_checksums, const char*, delta_name) + GLNX_HASH_TABLE_FOREACH (pull_data->summary_deltas_checksums, const char *, delta_name) { g_autofree char *cur_from_rev = NULL; g_autofree char *cur_to_rev = NULL; @@ -2483,21 +2345,19 @@ get_best_static_delta_start_for (OtPullData *pull_data, { const char *candidate = candidates->pdata[i]; guint64 candidate_ts = 0; - g_autoptr(GVariant) commit = NULL; + g_autoptr (GVariant) commit = NULL; OstreeRepoCommitState state; gboolean have_candidate; /* Do we have this commit at all? If not, skip it */ - if (!ostree_repo_has_object (pull_data->repo, OSTREE_OBJECT_TYPE_COMMIT, - candidate, &have_candidate, - NULL, error)) + if (!ostree_repo_has_object (pull_data->repo, OSTREE_OBJECT_TYPE_COMMIT, candidate, + &have_candidate, NULL, error)) return FALSE; if (!have_candidate) continue; /* Load it */ - if (!ostree_repo_load_commit (pull_data->repo, candidate, - &commit, &state, error)) + if (!ostree_repo_load_commit (pull_data->repo, candidate, &commit, &state, error)) return FALSE; /* Ignore partial commits, we can't use them */ @@ -2506,8 +2366,7 @@ get_best_static_delta_start_for (OtPullData *pull_data, /* Is it newer? */ candidate_ts = ostree_commit_get_timestamp (commit); - if (newest_candidate == NULL || - candidate_ts > newest_candidate_timestamp) + if (newest_candidate == NULL || candidate_ts > newest_candidate_timestamp) { newest_candidate = candidate; newest_candidate_timestamp = candidate_ts; @@ -2517,7 +2376,7 @@ get_best_static_delta_start_for (OtPullData *pull_data, if (newest_candidate) { out_result->result = DELTA_SEARCH_RESULT_FROM; - memcpy (out_result->from_revision, newest_candidate, OSTREE_SHA256_STRING_LEN+1); + memcpy (out_result->from_revision, newest_candidate, OSTREE_SHA256_STRING_LEN + 1); } return TRUE; } @@ -2543,34 +2402,26 @@ fetch_delta_index_data_free (FetchDeltaIndexData *fetch_data) } static void -set_required_deltas_error (GError **error, - const char *from_revision, - const char *to_revision) +set_required_deltas_error (GError **error, const char *from_revision, const char *to_revision) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Static deltas required, but none found for %s to %s", - from_revision, to_revision); + "Static deltas required, but none found for %s to %s", from_revision, to_revision); } static void -on_superblock_fetched (GObject *src, - GAsyncResult *res, - gpointer data) +on_superblock_fetched (GObject *src, GAsyncResult *res, gpointer data) { FetchDeltaSuperData *fetch_data = data; OtPullData *pull_data = fetch_data->pull_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; - g_autoptr(GBytes) delta_superblock_data = NULL; + g_autoptr (GBytes) delta_superblock_data = NULL; const char *from_revision = fetch_data->from_revision; const char *to_revision = fetch_data->to_revision; - if (!_ostree_fetcher_request_to_membuf_finish ((OstreeFetcher*)src, - res, - &delta_superblock_data, - NULL, NULL, NULL, - error)) + if (!_ostree_fetcher_request_to_membuf_finish ((OstreeFetcher *)src, res, &delta_superblock_data, + NULL, NULL, NULL, error)) { if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) goto out; @@ -2582,13 +2433,16 @@ on_superblock_fetched (GObject *src, goto out; } - queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, fetch_data->requested_ref); + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, + fetch_data->requested_ref); } else { - g_autoptr(GVariant) delta_superblock = NULL; - g_autofree gchar *delta = g_strconcat (from_revision ?: "", from_revision ? "-" : "", to_revision, NULL); - const guchar *expected_summary_digest = g_hash_table_lookup (pull_data->summary_deltas_checksums, delta); + g_autoptr (GVariant) delta_superblock = NULL; + g_autofree gchar *delta + = g_strconcat (from_revision ?: "", from_revision ? "-" : "", to_revision, NULL); + const guchar *expected_summary_digest + = g_hash_table_lookup (pull_data->summary_deltas_checksums, delta); guint8 actual_summary_digest[OSTREE_SHA256_DIGEST_LEN]; ot_checksum_bytes (delta_superblock_data, actual_summary_digest); @@ -2601,27 +2455,31 @@ on_superblock_fetched (GObject *src, if (pull_data->gpg_verify_summary && !expected_summary_digest) { g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, - "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); + "GPG verification enabled, but no summary signatures found (use " + "gpg-verify-summary=false in remote config to disable)"); goto out; } #endif /* OSTREE_DISABLE_GPGME */ - if (expected_summary_digest && memcmp (expected_summary_digest, actual_summary_digest, sizeof (actual_summary_digest))) + if (expected_summary_digest + && memcmp (expected_summary_digest, actual_summary_digest, + sizeof (actual_summary_digest))) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid checksum for static delta %s", delta); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid checksum for static delta %s", + delta); goto out; } - delta_superblock = g_variant_ref_sink (g_variant_new_from_bytes ((GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, - delta_superblock_data, FALSE)); + delta_superblock = g_variant_ref_sink (g_variant_new_from_bytes ( + (GVariantType *)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, delta_superblock_data, FALSE)); - g_ptr_array_add (pull_data->static_delta_superblocks, g_variant_ref (delta_superblock)); - if (!process_one_static_delta (pull_data, from_revision, to_revision, delta_superblock, fetch_data->requested_ref, - pull_data->cancellable, error)) + g_hash_table_add (pull_data->static_delta_targets, g_strdup (to_revision)); + if (!process_one_static_delta (pull_data, from_revision, to_revision, delta_superblock, + fetch_data->requested_ref, pull_data->cancellable, error)) goto out; } - out: +out: g_assert (pull_data->n_outstanding_metadata_fetches > 0); pull_data->n_outstanding_metadata_fetches--; @@ -2637,37 +2495,29 @@ on_superblock_fetched (GObject *src, } static void -start_fetch_delta_superblock (OtPullData *pull_data, - FetchDeltaSuperData *fetch_data) +start_fetch_delta_superblock (OtPullData *pull_data, FetchDeltaSuperData *fetch_data) { - g_autofree char *delta_name = - _ostree_get_relative_static_delta_superblock_path (fetch_data->from_revision, - fetch_data->to_revision); + g_autofree char *delta_name = _ostree_get_relative_static_delta_superblock_path ( + fetch_data->from_revision, fetch_data->to_revision); g_debug ("starting fetch of delta superblock %s", delta_name); - _ostree_fetcher_request_to_membuf (pull_data->fetcher, - pull_data->content_mirrorlist, - delta_name, OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - NULL, 0, - OSTREE_MAX_METADATA_SIZE, - 0, pull_data->cancellable, - on_superblock_fetched, - g_steal_pointer (&fetch_data)); + _ostree_fetcher_request_to_membuf (pull_data->fetcher, pull_data->content_mirrorlist, delta_name, + OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, NULL, 0, + OSTREE_MAX_METADATA_SIZE, 0, pull_data->cancellable, + on_superblock_fetched, g_steal_pointer (&fetch_data)); pull_data->n_outstanding_metadata_fetches++; pull_data->n_requested_metadata++; } static void -enqueue_one_static_delta_superblock_request_s (OtPullData *pull_data, +enqueue_one_static_delta_superblock_request_s (OtPullData *pull_data, FetchDeltaSuperData *fetch_data) { if (fetcher_queue_is_full (pull_data)) { g_debug ("queuing fetch of static delta superblock %s-%s", - fetch_data->from_revision ?: "empty", - fetch_data->to_revision); + fetch_data->from_revision ?: "empty", fetch_data->to_revision); - g_hash_table_add (pull_data->pending_fetch_delta_superblocks, - g_steal_pointer (&fetch_data)); + g_hash_table_add (pull_data->pending_fetch_delta_superblocks, g_steal_pointer (&fetch_data)); } else { @@ -2677,12 +2527,11 @@ enqueue_one_static_delta_superblock_request_s (OtPullData *pull_data, /* Start a request for a static delta */ static void -enqueue_one_static_delta_superblock_request (OtPullData *pull_data, - const char *from_revision, - const char *to_revision, +enqueue_one_static_delta_superblock_request (OtPullData *pull_data, const char *from_revision, + const char *to_revision, const OstreeCollectionRef *ref) { - FetchDeltaSuperData *fdata = g_new0(FetchDeltaSuperData, 1); + FetchDeltaSuperData *fdata = g_new0 (FetchDeltaSuperData, 1); fdata->pull_data = pull_data; fdata->from_revision = g_strdup (from_revision); fdata->to_revision = g_strdup (to_revision); @@ -2693,8 +2542,7 @@ enqueue_one_static_delta_superblock_request (OtPullData *pull_dat } static gboolean -validate_variant_is_csum (GVariant *csum, - GError **error) +validate_variant_is_csum (GVariant *csum, GError **error) { if (!g_variant_is_of_type (csum, G_VARIANT_TYPE ("ay"))) return glnx_throw (error, "Invalid checksum variant of type '%s', expected 'ay'", @@ -2704,9 +2552,7 @@ validate_variant_is_csum (GVariant *csum, } static gboolean -collect_available_deltas_for_pull (OtPullData *pull_data, - GVariant *deltas, - GError **error) +collect_available_deltas_for_pull (OtPullData *pull_data, GVariant *deltas, GError **error) { gsize n; @@ -2714,8 +2560,8 @@ collect_available_deltas_for_pull (OtPullData *pull_data, for (gsize i = 0; i < n; i++) { const char *delta; - g_autoptr(GVariant) csum_v = NULL; - g_autoptr(GVariant) ref = g_variant_get_child_value (deltas, i); + g_autoptr (GVariant) csum_v = NULL; + g_autoptr (GVariant) ref = g_variant_get_child_value (deltas, i); g_variant_get_child (ref, 0, "&s", &delta); g_variant_get_child (ref, 1, "v", &csum_v); @@ -2725,57 +2571,50 @@ collect_available_deltas_for_pull (OtPullData *pull_data, guchar *csum_data = g_malloc (OSTREE_SHA256_DIGEST_LEN); memcpy (csum_data, ostree_checksum_bytes_peek (csum_v), 32); - g_hash_table_insert (pull_data->summary_deltas_checksums, - g_strdup (delta), - csum_data); + g_hash_table_insert (pull_data->summary_deltas_checksums, g_strdup (delta), csum_data); } return TRUE; } static void -on_delta_index_fetched (GObject *src, - GAsyncResult *res, - gpointer data) +on_delta_index_fetched (GObject *src, GAsyncResult *res, gpointer data) { FetchDeltaIndexData *fetch_data = data; OtPullData *pull_data = fetch_data->pull_data; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; - g_autoptr(GBytes) delta_index_data = NULL; + g_autoptr (GBytes) delta_index_data = NULL; const char *from_revision = fetch_data->from_revision; const char *to_revision = fetch_data->to_revision; - if (!_ostree_fetcher_request_to_membuf_finish ((OstreeFetcher*)src, - res, - &delta_index_data, - NULL, NULL, NULL, - error)) + if (!_ostree_fetcher_request_to_membuf_finish ((OstreeFetcher *)src, res, &delta_index_data, NULL, + NULL, NULL, error)) { if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) goto out; g_clear_error (&local_error); - /* below call to initiate_delta_request() will fail finding the delta and fall back to commit */ + /* below call to initiate_delta_request() will fail finding the delta and fall back to commit + */ } else { - g_autoptr(GVariant) delta_index = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE_VARDICT, delta_index_data, FALSE)); - g_autoptr(GVariant) deltas = g_variant_lookup_value (delta_index, OSTREE_SUMMARY_STATIC_DELTAS, G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariant) delta_index = g_variant_ref_sink ( + g_variant_new_from_bytes (G_VARIANT_TYPE_VARDICT, delta_index_data, FALSE)); + g_autoptr (GVariant) deltas = g_variant_lookup_value ( + delta_index, OSTREE_SUMMARY_STATIC_DELTAS, G_VARIANT_TYPE ("a{sv}")); if (!collect_available_deltas_for_pull (pull_data, deltas, error)) goto out; } - if (!initiate_delta_request (pull_data, - fetch_data->requested_ref, - to_revision, - from_revision, + if (!initiate_delta_request (pull_data, fetch_data->requested_ref, to_revision, from_revision, &local_error)) goto out; - out: +out: g_assert (pull_data->n_outstanding_metadata_fetches > 0); pull_data->n_outstanding_metadata_fetches--; @@ -2791,35 +2630,27 @@ on_delta_index_fetched (GObject *src, } static void -start_fetch_delta_index (OtPullData *pull_data, - FetchDeltaIndexData *fetch_data) +start_fetch_delta_index (OtPullData *pull_data, FetchDeltaIndexData *fetch_data) { - g_autofree char *delta_name = - _ostree_get_relative_static_delta_index_path (fetch_data->to_revision); + g_autofree char *delta_name + = _ostree_get_relative_static_delta_index_path (fetch_data->to_revision); g_debug ("starting fetch of delta index %s", delta_name); - _ostree_fetcher_request_to_membuf (pull_data->fetcher, - pull_data->content_mirrorlist, - delta_name, OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - NULL, 0, - OSTREE_MAX_METADATA_SIZE, - 0, pull_data->cancellable, - on_delta_index_fetched, - g_steal_pointer (&fetch_data)); + _ostree_fetcher_request_to_membuf (pull_data->fetcher, pull_data->content_mirrorlist, delta_name, + OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, NULL, 0, + OSTREE_MAX_METADATA_SIZE, 0, pull_data->cancellable, + on_delta_index_fetched, g_steal_pointer (&fetch_data)); pull_data->n_outstanding_metadata_fetches++; pull_data->n_requested_metadata++; } static void -enqueue_one_static_delta_index_request_s (OtPullData *pull_data, - FetchDeltaIndexData *fetch_data) +enqueue_one_static_delta_index_request_s (OtPullData *pull_data, FetchDeltaIndexData *fetch_data) { if (fetcher_queue_is_full (pull_data)) { - g_debug ("queuing fetch of static delta index to %s", - fetch_data->to_revision); + g_debug ("queuing fetch of static delta index to %s", fetch_data->to_revision); - g_hash_table_add (pull_data->pending_fetch_delta_indexes, - g_steal_pointer (&fetch_data)); + g_hash_table_add (pull_data->pending_fetch_delta_indexes, g_steal_pointer (&fetch_data)); } else { @@ -2829,12 +2660,10 @@ enqueue_one_static_delta_index_request_s (OtPullData *pull_data, /* Start a request for a static delta index */ static void -enqueue_one_static_delta_index_request (OtPullData *pull_data, - const char *to_revision, - const char *from_revision, - const OstreeCollectionRef *ref) +enqueue_one_static_delta_index_request (OtPullData *pull_data, const char *to_revision, + const char *from_revision, const OstreeCollectionRef *ref) { - FetchDeltaIndexData *fdata = g_new0(FetchDeltaIndexData, 1); + FetchDeltaIndexData *fdata = g_new0 (FetchDeltaIndexData, 1); fdata->pull_data = pull_data; fdata->from_revision = g_strdup (from_revision); fdata->to_revision = g_strdup (to_revision); @@ -2845,42 +2674,34 @@ enqueue_one_static_delta_index_request (OtPullData *pull_data, } static gboolean -_ostree_repo_verify_summary (OstreeRepo *self, - const char *name, - gboolean gpg_verify_summary, - GPtrArray *signapi_summary_verifiers, - GBytes *summary, - GBytes *signatures, - GCancellable *cancellable, - GError **error) +_ostree_repo_verify_summary (OstreeRepo *self, const char *name, gboolean gpg_verify_summary, + GPtrArray *signapi_summary_verifiers, GBytes *summary, + GBytes *signatures, GCancellable *cancellable, GError **error) { if (gpg_verify_summary) { if (summary == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "GPG verification enabled, but no summary found (check that the configured URL in remote config is correct)"); + "GPG verification enabled, but no summary found (check that the configured " + "URL in remote config is correct)"); return FALSE; } if (signatures == NULL) { g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, - "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); + "GPG verification enabled, but no summary signatures found (use " + "gpg-verify-summary=false in remote config to disable)"); return FALSE; } /* Verify any summary signatures. */ if (summary != NULL && signatures != NULL) { - g_autoptr(OstreeGpgVerifyResult) result = NULL; - - result = ostree_repo_verify_summary (self, - name, - summary, - signatures, - cancellable, - error); + g_autoptr (OstreeGpgVerifyResult) result = NULL; + + result = ostree_repo_verify_summary (self, name, summary, signatures, cancellable, error); if (!ostree_gpg_verify_result_require_valid_signature (result, error)) return FALSE; } @@ -2891,26 +2712,29 @@ _ostree_repo_verify_summary (OstreeRepo *self, if (summary == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Signature verification enabled, but no summary found (check that the configured URL in remote config is correct)"); + "Signature verification enabled, but no summary found (check that the " + "configured URL in remote config is correct)"); return FALSE; } if (signatures == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Signature verification enabled, but no summary signatures found (use sign-verify-summary=false in remote config to disable)"); + "Signature verification enabled, but no summary signatures found (use " + "sign-verify-summary=false in remote config to disable)"); return FALSE; } /* Verify any summary signatures. */ if (summary != NULL && signatures != NULL) { - g_autoptr(GVariant) sig_variant = NULL; + g_autoptr (GVariant) sig_variant = NULL; - sig_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, - signatures, FALSE); + sig_variant + = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, signatures, FALSE); - if (!_sign_verify_for_remote (signapi_summary_verifiers, summary, sig_variant, NULL, error)) + if (!_sign_verify_for_remote (signapi_summary_verifiers, summary, sig_variant, NULL, + error)) return FALSE; } } @@ -2919,11 +2743,9 @@ _ostree_repo_verify_summary (OstreeRepo *self, } static void -_ostree_repo_load_cache_summary_properties (OstreeRepo *self, - const char *filename, - const char *extension, - char **out_etag, - guint64 *out_last_modified) +_ostree_repo_load_cache_summary_properties (OstreeRepo *self, const char *filename, + const char *extension, char **out_etag, + guint64 *out_last_modified) { const char *file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", filename, extension); glnx_autofd int fd = -1; @@ -2936,7 +2758,7 @@ _ostree_repo_load_cache_summary_properties (OstreeRepo *self, if (out_etag != NULL) { - g_autoptr(GBytes) etag_bytes = glnx_fgetxattr_bytes (fd, "user.etag", NULL); + g_autoptr (GBytes) etag_bytes = glnx_fgetxattr_bytes (fd, "user.etag", NULL); if (etag_bytes != NULL) { const guint8 *buf; @@ -2957,7 +2779,7 @@ _ostree_repo_load_cache_summary_properties (OstreeRepo *self, /* Nul-terminate and return */ if (buf_len > 0) - *out_etag = g_strndup ((const char *) buf, buf_len); + *out_etag = g_strndup ((const char *)buf, buf_len); else *out_etag = NULL; } @@ -2977,16 +2799,12 @@ _ostree_repo_load_cache_summary_properties (OstreeRepo *self, } static gboolean -_ostree_repo_load_cache_summary_file (OstreeRepo *self, - const char *filename, - const char *extension, - GBytes **out_data, - GCancellable *cancellable, - GError **error) +_ostree_repo_load_cache_summary_file (OstreeRepo *self, const char *filename, const char *extension, + GBytes **out_data, GCancellable *cancellable, GError **error) { const char *file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", filename, extension); glnx_autofd int fd = -1; - g_autoptr(GBytes) data = NULL; + g_autoptr (GBytes) data = NULL; *out_data = NULL; @@ -3005,44 +2823,39 @@ _ostree_repo_load_cache_summary_file (OstreeRepo *self, if (!data) return FALSE; - *out_data =g_steal_pointer (&data); + *out_data = g_steal_pointer (&data); return TRUE; } /* Load the summary from the cache if the provided .sig file is the same as the cached version. */ static gboolean -_ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self, - const char *remote, - GBytes *summary_sig, - GBytes **out_summary, - GCancellable *cancellable, - GError **error) +_ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self, const char *remote, + GBytes *summary_sig, GBytes **out_summary, + GCancellable *cancellable, GError **error) { - g_autoptr(GBytes) old_sig_contents = NULL; + g_autoptr (GBytes) old_sig_contents = NULL; *out_summary = NULL; - if (!_ostree_repo_load_cache_summary_file (self, remote, ".sig", - &old_sig_contents, - cancellable, error)) + if (!_ostree_repo_load_cache_summary_file (self, remote, ".sig", &old_sig_contents, cancellable, + error)) return FALSE; - if (old_sig_contents != NULL && - g_bytes_compare (old_sig_contents, summary_sig) == 0) + if (old_sig_contents != NULL && g_bytes_compare (old_sig_contents, summary_sig) == 0) { - g_autoptr(GBytes) summary_data = NULL; + g_autoptr (GBytes) summary_data = NULL; - if (!_ostree_repo_load_cache_summary_file (self, remote, NULL, - &summary_data, - cancellable, error)) + if (!_ostree_repo_load_cache_summary_file (self, remote, NULL, &summary_data, cancellable, + error)) return FALSE; if (summary_data == NULL) { /* Cached signature without cached summary, remove the signature */ - const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig"); - (void) unlinkat (self->cache_dir_fd, summary_cache_sig_file, 0); + const char *summary_cache_sig_file + = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig"); + (void)unlinkat (self->cache_dir_fd, summary_cache_sig_file, 0); } else *out_summary = g_steal_pointer (&summary_data); @@ -3052,17 +2865,14 @@ _ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self, } static void -store_file_cache_properties (int dir_fd, - const char *filename, - const char *etag, - guint64 last_modified) +store_file_cache_properties (int dir_fd, const char *filename, const char *etag, + guint64 last_modified) { glnx_autofd int fd = -1; - struct timespec time_vals[] = - { - { .tv_sec = last_modified, .tv_nsec = UTIME_OMIT }, /* access, leave unchanged */ - { .tv_sec = last_modified, .tv_nsec = 0 }, /* modification */ - }; + struct timespec time_vals[] = { + { .tv_sec = last_modified, .tv_nsec = UTIME_OMIT }, /* access, leave unchanged */ + { .tv_sec = last_modified, .tv_nsec = 0 }, /* modification */ + }; if (!glnx_openat_rdonly (dir_fd, filename, TRUE, &fd, NULL)) return; @@ -3077,14 +2887,9 @@ store_file_cache_properties (int dir_fd, } static gboolean -_ostree_repo_save_cache_summary_file (OstreeRepo *self, - const char *filename, - const char *extension, - GBytes *data, - const char *etag, - guint64 last_modified, - GCancellable *cancellable, - GError **error) +_ostree_repo_save_cache_summary_file (OstreeRepo *self, const char *filename, const char *extension, + GBytes *data, const char *etag, guint64 last_modified, + GCancellable *cancellable, GError **error) { const char *file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", filename, extension); glnx_autofd int fd = -1; @@ -3092,15 +2897,14 @@ _ostree_repo_save_cache_summary_file (OstreeRepo *self, if (self->cache_dir_fd == -1) return TRUE; - if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, DEFAULT_DIRECTORY_MODE, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, + DEFAULT_DIRECTORY_MODE, cancellable, error)) return FALSE; - if (!glnx_file_replace_contents_at (self->cache_dir_fd, - file, - g_bytes_get_data (data, NULL), - g_bytes_get_size (data), - self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW, - cancellable, error)) + if (!glnx_file_replace_contents_at ( + self->cache_dir_fd, file, g_bytes_get_data (data, NULL), g_bytes_get_size (data), + self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW, + cancellable, error)) return FALSE; /* Store the caching properties. This is non-fatal on failure. */ @@ -3111,40 +2915,29 @@ _ostree_repo_save_cache_summary_file (OstreeRepo *self, /* Replace the current summary+signature with new versions */ static gboolean -_ostree_repo_cache_summary (OstreeRepo *self, - const char *remote, - GBytes *summary, - const char *summary_etag, - guint64 summary_last_modified, - GBytes *summary_sig, - const char *summary_sig_etag, - guint64 summary_sig_last_modified, - GCancellable *cancellable, - GError **error) +_ostree_repo_cache_summary (OstreeRepo *self, const char *remote, GBytes *summary, + const char *summary_etag, guint64 summary_last_modified, + GBytes *summary_sig, const char *summary_sig_etag, + guint64 summary_sig_last_modified, GCancellable *cancellable, + GError **error) { - if (!_ostree_repo_save_cache_summary_file (self, remote, NULL, - summary, - summary_etag, summary_last_modified, - cancellable, error)) + if (!_ostree_repo_save_cache_summary_file (self, remote, NULL, summary, summary_etag, + summary_last_modified, cancellable, error)) return FALSE; - if (!_ostree_repo_save_cache_summary_file (self, remote, ".sig", - summary_sig, - summary_sig_etag, summary_sig_last_modified, - cancellable, error)) + if (!_ostree_repo_save_cache_summary_file (self, remote, ".sig", summary_sig, summary_sig_etag, + summary_sig_last_modified, cancellable, error)) return FALSE; return TRUE; } static OstreeFetcher * -_ostree_repo_remote_new_fetcher (OstreeRepo *self, - const char *remote_name, - gboolean gzip, - GVariant *extra_headers, - const char *append_user_agent, - OstreeFetcherSecurityState *out_state, - GError **error) +_ostree_repo_remote_new_fetcher (OstreeRepo *self, const char *remote_name, gboolean gzip, + GVariant *extra_headers, const char *append_user_agent, + guint32 low_speed_limit, guint32 low_speed_time, + gboolean retry_all, guint32 max_outstanding_fetcher_requests, + OstreeFetcherSecurityState *out_state, GError **error) { OstreeFetcher *fetcher = NULL; OstreeFetcherConfigFlags fetcher_flags = 0; @@ -3155,8 +2948,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); g_return_val_if_fail (remote_name != NULL, NULL); - if (!ostree_repo_get_remote_boolean_option (self, remote_name, - "tls-permissive", FALSE, + if (!ostree_repo_get_remote_boolean_option (self, remote_name, "tls-permissive", FALSE, &tls_permissive, error)) goto out; @@ -3169,32 +2961,32 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, if (gzip) fetcher_flags |= OSTREE_FETCHER_FLAGS_TRANSFER_GZIP; - { gboolean http2_default = TRUE; + { + gboolean http2_default = TRUE; #ifndef BUILDOPT_HTTP2 http2_default = FALSE; #endif gboolean http2; - if (!ostree_repo_get_remote_boolean_option (self, remote_name, - "http2", http2_default, - &http2, error)) + if (!ostree_repo_get_remote_boolean_option (self, remote_name, "http2", http2_default, &http2, + error)) goto out; if (!http2) fetcher_flags |= OSTREE_FETCHER_FLAGS_DISABLE_HTTP2; } fetcher = _ostree_fetcher_new (self->tmp_dir_fd, remote_name, fetcher_flags); + if (self->is_on_fuse) + _ostree_fetcher_set_force_anonymous_tmpfiles (fetcher); { g_autofree char *tls_client_cert_path = NULL; g_autofree char *tls_client_key_path = NULL; - if (!ostree_repo_get_remote_option (self, remote_name, - "tls-client-cert-path", NULL, + if (!ostree_repo_get_remote_option (self, remote_name, "tls-client-cert-path", NULL, &tls_client_cert_path, error)) goto out; - if (!ostree_repo_get_remote_option (self, remote_name, - "tls-client-key-path", NULL, + if (!ostree_repo_get_remote_option (self, remote_name, "tls-client-key-path", NULL, &tls_client_key_path, error)) goto out; @@ -3212,12 +3004,16 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, } } + _ostree_fetcher_set_low_speed_limit (fetcher, low_speed_limit); + _ostree_fetcher_set_low_speed_time (fetcher, low_speed_time); + _ostree_fetcher_set_retry_all (fetcher, retry_all); + _ostree_fetcher_set_max_outstanding_fetcher_requests (fetcher, max_outstanding_fetcher_requests); + { g_autofree char *tls_ca_path = NULL; - if (!ostree_repo_get_remote_option (self, remote_name, - "tls-ca-path", NULL, - &tls_ca_path, error)) + if (!ostree_repo_get_remote_option (self, remote_name, "tls-ca-path", NULL, &tls_ca_path, + error)) goto out; if (tls_ca_path != NULL) @@ -3233,9 +3029,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, { g_autofree char *http_proxy = NULL; - if (!ostree_repo_get_remote_option (self, remote_name, - "proxy", NULL, - &http_proxy, error)) + if (!ostree_repo_get_remote_option (self, remote_name, "proxy", NULL, &http_proxy, error)) goto out; if (http_proxy != NULL && http_proxy[0] != '\0') @@ -3248,9 +3042,9 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, /* TODO; port away from this; a bit hard since both libsoup and libcurl * expect a file. Doing ot_fdrel_to_gfile() works for now though. */ - GFile*repo_path = ostree_repo_get_path (self); - g_autofree char *jar_path = - g_build_filename (gs_file_get_path_cached (repo_path), cookie_file, NULL); + GFile *repo_path = ostree_repo_get_path (self); + g_autofree char *jar_path + = g_build_filename (gs_file_get_path_cached (repo_path), cookie_file, NULL); if (g_file_test (jar_path, G_FILE_TEST_IS_REGULAR)) _ostree_fetcher_set_cookie_jar (fetcher, jar_path); @@ -3274,20 +3068,13 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, } static gboolean -_ostree_preload_metadata_file (OstreeRepo *self, - OstreeFetcher *fetcher, - GPtrArray *mirrorlist, - const char *filename, - gboolean is_metalink, - const char *if_none_match, - guint64 if_modified_since, - guint n_network_retries, - GBytes **out_bytes, - gboolean *out_not_modified, - char **out_etag, - guint64 *out_last_modified, - GCancellable *cancellable, - GError **error) +_ostree_preload_metadata_file (OstreeRepo *self, OstreeFetcher *fetcher, GPtrArray *mirrorlist, + const char *filename, gboolean is_metalink, + const char *if_none_match, guint64 if_modified_since, + guint n_network_retries, GBytes **out_bytes, + gboolean *out_not_modified, char **out_etag, + guint64 *out_last_modified, GCancellable *cancellable, + GError **error) { if (is_metalink) { @@ -3295,13 +3082,10 @@ _ostree_preload_metadata_file (OstreeRepo *self, /* the metalink uri is buried in the mirrorlist as the first (and only) * element */ - g_autoptr(OstreeMetalink) metalink = - _ostree_metalink_new (fetcher, filename, - OSTREE_MAX_METADATA_SIZE, - mirrorlist->pdata[0], n_network_retries); + g_autoptr (OstreeMetalink) metalink = _ostree_metalink_new ( + fetcher, filename, OSTREE_MAX_METADATA_SIZE, mirrorlist->pdata[0], n_network_retries); - _ostree_metalink_request_sync (metalink, NULL, out_bytes, - cancellable, &local_error); + _ostree_metalink_request_sync (metalink, NULL, out_bytes, cancellable, &local_error); if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { @@ -3318,46 +3102,38 @@ _ostree_preload_metadata_file (OstreeRepo *self, } else { - return _ostree_fetcher_mirrored_request_to_membuf (fetcher, mirrorlist, filename, - OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - if_none_match, if_modified_since, - n_network_retries, - out_bytes, out_not_modified, out_etag, out_last_modified, - OSTREE_MAX_METADATA_SIZE, - cancellable, error); + return _ostree_fetcher_mirrored_request_to_membuf ( + fetcher, mirrorlist, filename, OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, if_none_match, + if_modified_since, n_network_retries, out_bytes, out_not_modified, out_etag, + out_last_modified, OSTREE_MAX_METADATA_SIZE, cancellable, error); } } static gboolean -fetch_mirrorlist (OstreeFetcher *fetcher, - const char *mirrorlist_url, - guint n_network_retries, - GPtrArray **out_mirrorlist, - GCancellable *cancellable, - GError **error) +fetch_mirrorlist (OstreeFetcher *fetcher, const char *mirrorlist_url, guint n_network_retries, + GPtrArray **out_mirrorlist, GCancellable *cancellable, GError **error) { - g_autoptr(GPtrArray) ret_mirrorlist = - g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); + g_autoptr (GPtrArray) ret_mirrorlist + = g_ptr_array_new_with_free_func ((GDestroyNotify)_ostree_fetcher_uri_free); - g_autoptr(OstreeFetcherURI) mirrorlist = _ostree_fetcher_uri_parse (mirrorlist_url, error); + g_autoptr (OstreeFetcherURI) mirrorlist = _ostree_fetcher_uri_parse (mirrorlist_url, error); if (!mirrorlist) return FALSE; g_autofree char *contents = NULL; - if (!fetch_uri_contents_utf8_sync (fetcher, mirrorlist, n_network_retries, - &contents, cancellable, error)) - return glnx_prefix_error (error, "While fetching mirrorlist '%s'", - mirrorlist_url); + if (!fetch_uri_contents_utf8_sync (fetcher, mirrorlist, n_network_retries, &contents, cancellable, + error)) + return glnx_prefix_error (error, "While fetching mirrorlist '%s'", mirrorlist_url); /* go through each mirror in mirrorlist and do a quick sanity check that it * works so that we don't waste the fetcher's time when it goes through them * */ - g_auto(GStrv) lines = g_strsplit (contents, "\n", -1); + g_auto (GStrv) lines = g_strsplit (contents, "\n", -1); g_debug ("Scanning mirrorlist from '%s'", mirrorlist_url); for (char **iter = lines; iter && *iter; iter++) { const char *mirror_uri_str = *iter; - g_autoptr(OstreeFetcherURI) mirror_uri = NULL; + g_autoptr (OstreeFetcherURI) mirror_uri = NULL; g_autofree char *scheme = NULL; /* let's be nice and support empty lines and comments */ @@ -3389,15 +3165,16 @@ fetch_mirrorlist (OstreeFetcher *fetcher, if (ret_mirrorlist->len == 0) { GError *local_error = NULL; - g_autoptr(OstreeFetcherURI) config_uri = _ostree_fetcher_uri_new_subpath (mirror_uri, "config"); + g_autoptr (OstreeFetcherURI) config_uri + = _ostree_fetcher_uri_new_subpath (mirror_uri, "config"); - if (fetch_uri_contents_utf8_sync (fetcher, config_uri, n_network_retries, - NULL, cancellable, &local_error)) + if (fetch_uri_contents_utf8_sync (fetcher, config_uri, n_network_retries, NULL, + cancellable, &local_error)) g_ptr_array_add (ret_mirrorlist, g_steal_pointer (&mirror_uri)); else { - g_debug ("Failed to fetch config from mirror '%s': %s", - mirror_uri_str, local_error->message); + g_debug ("Failed to fetch config from mirror '%s': %s", mirror_uri_str, + local_error->message); g_clear_error (&local_error); } } @@ -3408,22 +3185,17 @@ fetch_mirrorlist (OstreeFetcher *fetcher, } if (ret_mirrorlist->len == 0) - return glnx_throw (error, "No valid mirrors were found in mirrorlist '%s'", - mirrorlist_url); + return glnx_throw (error, "No valid mirrors were found in mirrorlist '%s'", mirrorlist_url); *out_mirrorlist = g_steal_pointer (&ret_mirrorlist); return TRUE; } static gboolean -compute_effective_mirrorlist (OstreeRepo *self, - const char *remote_name_or_baseurl, - const char *url_override, - OstreeFetcher *fetcher, - guint n_network_retries, - GPtrArray **out_mirrorlist, - GCancellable *cancellable, - GError **error) +compute_effective_mirrorlist (OstreeRepo *self, const char *remote_name_or_baseurl, + const char *url_override, OstreeFetcher *fetcher, + guint n_network_retries, GPtrArray **out_mirrorlist, + GCancellable *cancellable, GError **error) { g_autofree char *baseurl = NULL; @@ -3434,16 +3206,13 @@ compute_effective_mirrorlist (OstreeRepo *self, if (g_str_has_prefix (baseurl, "mirrorlist=")) { - if (!fetch_mirrorlist (fetcher, - baseurl + strlen ("mirrorlist="), - n_network_retries, - out_mirrorlist, - cancellable, error)) + if (!fetch_mirrorlist (fetcher, baseurl + strlen ("mirrorlist="), n_network_retries, + out_mirrorlist, cancellable, error)) return FALSE; } else { - g_autoptr(OstreeFetcherURI) baseuri = _ostree_fetcher_uri_parse (baseurl, error); + g_autoptr (OstreeFetcherURI) baseuri = _ostree_fetcher_uri_parse (baseurl, error); if (!baseuri) return FALSE; @@ -3451,8 +3220,7 @@ compute_effective_mirrorlist (OstreeRepo *self, if (!_ostree_fetcher_uri_validate (baseuri, error)) return FALSE; - *out_mirrorlist = - g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); + *out_mirrorlist = g_ptr_array_new_with_free_func ((GDestroyNotify)_ostree_fetcher_uri_free); g_ptr_array_add (*out_mirrorlist, g_steal_pointer (&baseuri)); } return TRUE; @@ -3462,15 +3230,13 @@ compute_effective_mirrorlist (OstreeRepo *self, * any options specific to this pull (such as extra headers). */ static gboolean -reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, - GError **error) +reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, GError **error) { g_clear_object (&pull_data->fetcher); - pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE, - pull_data->extra_headers, - pull_data->append_user_agent, - &pull_data->fetcher_security_state, - error); + pull_data->fetcher = _ostree_repo_remote_new_fetcher ( + pull_data->repo, remote_name, FALSE, pull_data->extra_headers, pull_data->append_user_agent, + pull_data->low_speed_limit, pull_data->low_speed_time, pull_data->retry_all, + pull_data->max_outstanding_fetcher_requests, &pull_data->fetcher_security_state, error); if (pull_data->fetcher == NULL) return FALSE; @@ -3478,17 +3244,14 @@ reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, } static gboolean -initiate_delta_request (OtPullData *pull_data, - const OstreeCollectionRef *ref, - const char *to_revision, - const char *delta_from_revision, - GError **error) +initiate_delta_request (OtPullData *pull_data, const OstreeCollectionRef *ref, + const char *to_revision, const char *delta_from_revision, GError **error) { DeltaSearchResult deltares; /* Look for a delta to @to_revision in the summary data */ - if (!get_best_static_delta_start_for (pull_data, to_revision, &deltares, - pull_data->cancellable, error)) + if (!get_best_static_delta_start_for (pull_data, to_revision, &deltares, pull_data->cancellable, + error)) return FALSE; switch (deltares.result) @@ -3501,11 +3264,13 @@ initiate_delta_request (OtPullData *pull_data, return FALSE; } else /* No deltas, fall back to object fetches. */ - queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, ref); + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, + 0, ref); } break; case DELTA_SEARCH_RESULT_FROM: - enqueue_one_static_delta_superblock_request (pull_data, deltares.from_revision, to_revision, ref); + enqueue_one_static_delta_superblock_request (pull_data, deltares.from_revision, to_revision, + ref); break; case DELTA_SEARCH_RESULT_SCRATCH: { @@ -3514,7 +3279,8 @@ initiate_delta_request (OtPullData *pull_data, * commits out of date; so doing an object pull is likely more * bandwidth efficient. */ if (delta_from_revision != NULL) - queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, ref); + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, + 0, ref); else enqueue_one_static_delta_superblock_request (pull_data, NULL, to_revision, ref); } @@ -3529,7 +3295,8 @@ initiate_delta_request (OtPullData *pull_data, if (pull_data->require_static_deltas) break; else - queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, ref); + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, + 0, ref); } } @@ -3548,17 +3315,16 @@ initiate_delta_request (OtPullData *pull_data, * `disable_static_deltas` and `require_static_deltas`. */ static gboolean -initiate_request (OtPullData *pull_data, - const OstreeCollectionRef *ref, - const char *to_revision, - GError **error) +initiate_request (OtPullData *pull_data, const OstreeCollectionRef *ref, const char *to_revision, + GError **error) { g_autofree char *delta_from_revision = NULL; /* Are deltas disabled? OK, just start an object fetch and be done */ if (pull_data->disable_static_deltas) { - queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, ref); + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, + ref); return TRUE; } @@ -3569,8 +3335,7 @@ initiate_request (OtPullData *pull_data, g_autofree char *refspec = NULL; if (pull_data->remote_name != NULL) refspec = g_strdup_printf ("%s:%s", pull_data->remote_name, ref->ref_name); - if (!ostree_repo_resolve_rev (pull_data->repo, - refspec ?: ref->ref_name, TRUE, + if (!ostree_repo_resolve_rev (pull_data->repo, refspec ?: ref->ref_name, TRUE, &delta_from_revision, error)) return FALSE; } @@ -3614,9 +3379,11 @@ initiate_request (OtPullData *pull_data, * delta. */ if (delta_from_revision && g_str_equal (delta_from_revision, to_revision)) - queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, ref); + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0, + ref); else - enqueue_one_static_delta_superblock_request (pull_data, delta_from_revision ?: NULL, to_revision, ref); + enqueue_one_static_delta_superblock_request (pull_data, delta_from_revision ?: NULL, + to_revision, ref); } else { @@ -3630,10 +3397,11 @@ initiate_request (OtPullData *pull_data, } static gboolean -all_requested_refs_have_commit (GHashTable *requested_refs /* (element-type OstreeCollectionRef utf8) */) +all_requested_refs_have_commit ( + GHashTable *requested_refs /* (element-type OstreeCollectionRef utf8) */) { - GLNX_HASH_TABLE_FOREACH_KV (requested_refs, const OstreeCollectionRef*, ref, - const char*, override_commitid) + GLNX_HASH_TABLE_FOREACH_KV (requested_refs, const OstreeCollectionRef *, ref, const char *, + override_commitid) { /* Note: "" override means whatever is latest */ if (override_commitid == NULL || *override_commitid == 0) @@ -3678,19 +3446,32 @@ all_requested_refs_have_commit (GHashTable *requested_refs /* (element-type Ostr * * `disable-static-deltas` (`b`): Do not use static deltas * * `require-static-deltas` (`b`): Require static deltas * * `override-commit-ids` (`as`): Array of specific commit IDs to fetch for refs - * * `timestamp-check` (`b`): Verify commit timestamps are newer than current (when pulling via ref); Since: 2017.11 - * * `timestamp-check-from-rev` (`s`): Verify that all fetched commit timestamps are newer than timestamp of given rev; Since: 2020.4 - * * `metadata-size-restriction` (`t`): Restrict metadata objects to a maximum number of bytes; 0 to disable. Since: 2018.9 + * * `timestamp-check` (`b`): Verify commit timestamps are newer than current (when pulling via + * ref); Since: 2017.11 + * * `timestamp-check-from-rev` (`s`): Verify that all fetched commit timestamps are newer than + * timestamp of given rev; Since: 2020.4 + * * `max-metadata-size` (`t`): Restrict metadata objects to a maximum number of bytes; 0 to + * disable. Since: 2018.9 * * `dry-run` (`b`): Only print information on what will be downloaded (requires static deltas) * * `override-url` (`s`): Fetch objects from this URL if remote specifies no metalink in options - * * `inherit-transaction` (`b`): Don't initiate, finish or abort a transaction, useful to do multiple pulls in one transaction. + * * `inherit-transaction` (`b`): Don't initiate, finish or abort a transaction, useful to do + * multiple pulls in one transaction. * * `http-headers` (`a(ss)`): Additional headers to add to all HTTP requests - * * `update-frequency` (`u`): Frequency to call the async progress callback in milliseconds, if any; only values higher than 0 are valid - * * `localcache-repos` (`as`): File paths for local repos to use as caches when doing remote fetches + * * `update-frequency` (`u`): Frequency to call the async progress callback in milliseconds, if + * any; only values higher than 0 are valid + * * `localcache-repos` (`as`): File paths for local repos to use as caches when doing remote + * fetches * * `append-user-agent` (`s`): Additional string to append to the user agent * * `n-network-retries` (`u`): Number of times to retry each download on receiving * a transient network error, such as a socket timeout; default is 5, 0 * means return errors without retrying. Since: 2018.6 + * * `low-speed-limit-bytes` (`u`): The average transfer speed per second of a transfer + * during the time set via "low-speed-time-seconds" for libcurl to abort. + * * `low-speed-time-seconds` (`u`): The time in number seconds that the transfer + * speed should be below the "low-speed-limit-bytes" setting for libcurl to abort. + * * `retry-all-network-errors` (`b`): Retry when network issues happen, instead of + * failing automatically. Currently only affects libcurl. (Default set to true) + * * `max-outstanding-fetcher-requests` (`u`): The max amount of concurrent connections allowed. * * `ref-keyring-map` (`a(sss)`): Array of (collection ID, ref name, keyring * remote name) tuples specifying which remote's keyring should be used when * doing GPG verification of each collection-ref. This is useful to prevent a @@ -3711,24 +3492,24 @@ all_requested_refs_have_commit (GHashTable *requested_refs /* (element-type Ostr * Since: 2020.9 */ gboolean -ostree_repo_pull_with_options (OstreeRepo *self, - const char *remote_name_or_baseurl, - GVariant *options, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GError **error) +ostree_repo_pull_with_options (OstreeRepo *self, const char *remote_name_or_baseurl, + GVariant *options, OstreeAsyncProgress *progress, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GBytes) bytes_summary = NULL; + g_autoptr (GBytes) bytes_summary = NULL; gboolean summary_not_modified = FALSE; g_autofree char *summary_etag = NULL; guint64 summary_last_modified = 0; g_autofree char *metalink_url_str = NULL; - g_autoptr(GHashTable) requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */ - g_autoptr(GHashTable) commits_to_fetch = NULL; + g_autoptr (GHashTable) requested_refs_to_fetch + = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) commits_to_fetch = NULL; g_autofree char *remote_mode_str = NULL; - g_autoptr(OstreeMetalink) metalink = NULL; - OtPullData pull_data_real = { 0, }; + g_autoptr (OstreeMetalink) metalink = NULL; + OtPullData pull_data_real = { + 0, + }; OtPullData *pull_data = &pull_data_real; GKeyFile *remote_config = NULL; char **configured_branches = NULL; @@ -3739,14 +3520,18 @@ ostree_repo_pull_with_options (OstreeRepo *self, const char *dir_to_pull = NULL; g_autofree char **dirs_to_pull = NULL; g_autofree char **refs_to_fetch = NULL; - g_autoptr(GVariantIter) collection_refs_iter = NULL; + g_autoptr (GVariantIter) collection_refs_iter = NULL; g_autofree char **override_commit_ids = NULL; - g_autoptr(GSource) update_timeout = NULL; + g_autoptr (GSource) update_timeout = NULL; gboolean opt_per_object_fsync = FALSE; gboolean opt_gpg_verify_set = FALSE; gboolean opt_gpg_verify_summary_set = FALSE; gboolean opt_collection_refs_set = FALSE; gboolean opt_n_network_retries_set = FALSE; + gboolean opt_low_speed_limit_set = FALSE; + gboolean opt_low_speed_time_set = FALSE; + gboolean opt_retry_all_set = FALSE; + gboolean opt_max_outstanding_fetcher_requests_set = FALSE; gboolean opt_ref_keyring_map_set = FALSE; gboolean disable_sign_verify = FALSE; gboolean disable_sign_verify_summary = FALSE; @@ -3755,17 +3540,20 @@ ostree_repo_pull_with_options (OstreeRepo *self, const char *url_override = NULL; gboolean inherit_transaction = FALSE; gboolean require_summary_for_mirror = FALSE; - g_autoptr(GHashTable) updated_requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) updated_requested_refs_to_fetch + = NULL; /* (element-type OstreeCollectionRef utf8) */ gsize i; g_autofree char **opt_localcache_repos = NULL; - g_autoptr(GVariantIter) ref_keyring_map_iter = NULL; - g_autoptr(GVariant) summary_bytes_v = NULL; - g_autoptr(GVariant) summary_sig_bytes_v = NULL; + g_autoptr (GVariantIter) ref_keyring_map_iter = NULL; + g_autoptr (GVariant) summary_bytes_v = NULL; + g_autoptr (GVariant) summary_sig_bytes_v = NULL; /* If refs or collection-refs has exactly one value, this will point to that * value, otherwise NULL. Used for logging. */ const char *the_ref_to_fetch = NULL; - OstreeRepoTransactionStats tstats = { 0, }; + OstreeRepoTransactionStats tstats = { + 0, + }; gboolean remote_mode_loaded = FALSE; /* Default */ @@ -3774,43 +3562,57 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (options) { int flags_i = OSTREE_REPO_PULL_FLAGS_NONE; - (void) g_variant_lookup (options, "refs", "^a&s", &refs_to_fetch); - opt_collection_refs_set = - g_variant_lookup (options, "collection-refs", "a(sss)", &collection_refs_iter); - (void) g_variant_lookup (options, "flags", "i", &flags_i); + (void)g_variant_lookup (options, "refs", "^a&s", &refs_to_fetch); + opt_collection_refs_set + = g_variant_lookup (options, "collection-refs", "a(sss)", &collection_refs_iter); + (void)g_variant_lookup (options, "flags", "i", &flags_i); /* Reduce risk of issues if enum happens to be 64 bit for some reason */ flags = flags_i; - (void) g_variant_lookup (options, "subdir", "&s", &dir_to_pull); - (void) g_variant_lookup (options, "subdirs", "^a&s", &dirs_to_pull); - (void) g_variant_lookup (options, "override-remote-name", "s", &pull_data->remote_refspec_name); - opt_gpg_verify_set = - g_variant_lookup (options, "gpg-verify", "b", &pull_data->gpg_verify); - opt_gpg_verify_summary_set = - g_variant_lookup (options, "gpg-verify-summary", "b", &pull_data->gpg_verify_summary); - g_variant_lookup (options, "disable-sign-verify", "b", &disable_sign_verify); - g_variant_lookup (options, "disable-sign-verify-summary", "b", &disable_sign_verify_summary); - (void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth); - (void) g_variant_lookup (options, "disable-static-deltas", "b", &pull_data->disable_static_deltas); - (void) g_variant_lookup (options, "require-static-deltas", "b", &pull_data->require_static_deltas); - (void) g_variant_lookup (options, "override-commit-ids", "^a&s", &override_commit_ids); - (void) g_variant_lookup (options, "dry-run", "b", &pull_data->dry_run); - (void) g_variant_lookup (options, "per-object-fsync", "b", &opt_per_object_fsync); - (void) g_variant_lookup (options, "override-url", "&s", &url_override); - (void) g_variant_lookup (options, "inherit-transaction", "b", &inherit_transaction); - (void) g_variant_lookup (options, "http-headers", "@a(ss)", &pull_data->extra_headers); - (void) g_variant_lookup (options, "update-frequency", "u", &update_frequency); - (void) g_variant_lookup (options, "localcache-repos", "^a&s", &opt_localcache_repos); - (void) g_variant_lookup (options, "timestamp-check", "b", &pull_data->timestamp_check); - (void) g_variant_lookup (options, "timestamp-check-from-rev", "s", &pull_data->timestamp_check_from_rev); - (void) g_variant_lookup (options, "max-metadata-size", "t", &pull_data->max_metadata_size); - (void) g_variant_lookup (options, "append-user-agent", "s", &pull_data->append_user_agent); - opt_n_network_retries_set = - g_variant_lookup (options, "n-network-retries", "u", &pull_data->n_network_retries); - opt_ref_keyring_map_set = - g_variant_lookup (options, "ref-keyring-map", "a(sss)", &ref_keyring_map_iter); - (void) g_variant_lookup (options, "summary-bytes", "@ay", &summary_bytes_v); - (void) g_variant_lookup (options, "summary-sig-bytes", "@ay", &summary_sig_bytes_v); - (void) g_variant_lookup (options, "disable-verify-bindings", "b", &pull_data->disable_verify_bindings); + (void)g_variant_lookup (options, "subdir", "&s", &dir_to_pull); + (void)g_variant_lookup (options, "subdirs", "^a&s", &dirs_to_pull); + (void)g_variant_lookup (options, "override-remote-name", "s", + &pull_data->remote_refspec_name); + opt_gpg_verify_set = g_variant_lookup (options, "gpg-verify", "b", &pull_data->gpg_verify); + opt_gpg_verify_summary_set + = g_variant_lookup (options, "gpg-verify-summary", "b", &pull_data->gpg_verify_summary); + (void)g_variant_lookup (options, "disable-sign-verify", "b", &disable_sign_verify); + (void)g_variant_lookup (options, "disable-sign-verify-summary", "b", + &disable_sign_verify_summary); + (void)g_variant_lookup (options, "depth", "i", &pull_data->maxdepth); + (void)g_variant_lookup (options, "disable-static-deltas", "b", + &pull_data->disable_static_deltas); + (void)g_variant_lookup (options, "require-static-deltas", "b", + &pull_data->require_static_deltas); + (void)g_variant_lookup (options, "override-commit-ids", "^a&s", &override_commit_ids); + (void)g_variant_lookup (options, "dry-run", "b", &pull_data->dry_run); + (void)g_variant_lookup (options, "per-object-fsync", "b", &opt_per_object_fsync); + (void)g_variant_lookup (options, "override-url", "&s", &url_override); + (void)g_variant_lookup (options, "inherit-transaction", "b", &inherit_transaction); + (void)g_variant_lookup (options, "http-headers", "@a(ss)", &pull_data->extra_headers); + (void)g_variant_lookup (options, "update-frequency", "u", &update_frequency); + (void)g_variant_lookup (options, "localcache-repos", "^a&s", &opt_localcache_repos); + (void)g_variant_lookup (options, "timestamp-check", "b", &pull_data->timestamp_check); + (void)g_variant_lookup (options, "timestamp-check-from-rev", "s", + &pull_data->timestamp_check_from_rev); + (void)g_variant_lookup (options, "max-metadata-size", "t", &pull_data->max_metadata_size); + (void)g_variant_lookup (options, "append-user-agent", "s", &pull_data->append_user_agent); + opt_low_speed_limit_set + = g_variant_lookup (options, "low-speed-limit-bytes", "u", &pull_data->low_speed_limit); + opt_low_speed_time_set + = g_variant_lookup (options, "low-speed-time-seconds", "u", &pull_data->low_speed_time); + opt_retry_all_set + = g_variant_lookup (options, "retry-all-network-errors", "b", &pull_data->retry_all); + opt_max_outstanding_fetcher_requests_set + = g_variant_lookup (options, "max-outstanding-fetcher-requests", "b", + &pull_data->max_outstanding_fetcher_requests); + opt_n_network_retries_set + = g_variant_lookup (options, "n-network-retries", "u", &pull_data->n_network_retries); + opt_ref_keyring_map_set + = g_variant_lookup (options, "ref-keyring-map", "a(sss)", &ref_keyring_map_iter); + (void)g_variant_lookup (options, "summary-bytes", "@ay", &summary_bytes_v); + (void)g_variant_lookup (options, "summary-sig-bytes", "@ay", &summary_sig_bytes_v); + (void)g_variant_lookup (options, "disable-verify-bindings", "b", + &pull_data->disable_verify_bindings); if (pull_data->remote_refspec_name != NULL) pull_data->remote_name = g_strdup (pull_data->remote_refspec_name); @@ -3819,21 +3621,21 @@ ostree_repo_pull_with_options (OstreeRepo *self, #ifdef OSTREE_DISABLE_GPGME /* Explicitly fail here if gpg verification is requested and we have no GPG support */ if (pull_data->gpg_verify || pull_data->gpg_verify_summary) - { + { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "'%s': GPG feature is disabled at build time", - __FUNCTION__); + "'%s': GPG feature is disabled at build time", __FUNCTION__); goto out; - } + } #endif g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); g_return_val_if_fail (pull_data->maxdepth >= -1, FALSE); g_return_val_if_fail (!pull_data->timestamp_check || pull_data->maxdepth == 0, FALSE); - g_return_val_if_fail (!opt_collection_refs_set || - (refs_to_fetch == NULL && override_commit_ids == NULL), FALSE); + g_return_val_if_fail ( + !opt_collection_refs_set || (refs_to_fetch == NULL && override_commit_ids == NULL), FALSE); if (refs_to_fetch && override_commit_ids) - g_return_val_if_fail (g_strv_length (refs_to_fetch) == g_strv_length (override_commit_ids), FALSE); + g_return_val_if_fail (g_strv_length (refs_to_fetch) == g_strv_length (override_commit_ids), + FALSE); if (dir_to_pull) g_return_val_if_fail (dir_to_pull[0] == '/', FALSE); @@ -3841,7 +3643,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, for (i = 0; dirs_to_pull != NULL && dirs_to_pull[i] != NULL; i++) g_return_val_if_fail (dirs_to_pull[i][0] == '/', FALSE); - g_return_val_if_fail (!(pull_data->disable_static_deltas && pull_data->require_static_deltas), FALSE); + g_return_val_if_fail (!(pull_data->disable_static_deltas && pull_data->require_static_deltas), + FALSE); /* We only do dry runs with static deltas, because we don't really have any * in-advance information for bare fetches. @@ -3876,47 +3679,56 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!opt_n_network_retries_set) pull_data->n_network_retries = DEFAULT_N_NETWORK_RETRIES; + if (!opt_low_speed_limit_set) + pull_data->low_speed_limit = OPT_LOWSPEEDLIMIT_DEFAULT; + if (!opt_low_speed_time_set) + pull_data->low_speed_time = OPT_LOWSPEEDTIME_DEFAULT; + if (!opt_retry_all_set) + pull_data->retry_all = OPT_RETRYALL_DEFAULT; + if (!opt_max_outstanding_fetcher_requests_set) + pull_data->max_outstanding_fetcher_requests + = OPT_OSTREE_MAX_OUTSTANDING_FETCHER_REQUESTS_DEFAULT; pull_data->repo = self; pull_data->progress = progress; - pull_data->expected_commit_sizes = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)g_free); - pull_data->commit_to_depth = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, - NULL); - pull_data->summary_deltas_checksums = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)g_free); - pull_data->ref_original_commits = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, - (GDestroyNotify)NULL, - (GDestroyNotify)g_free); - pull_data->verified_commits = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, NULL); - pull_data->signapi_verified_commits = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, NULL); - pull_data->ref_keyring_map = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, - (GDestroyNotify)ostree_collection_ref_free, (GDestroyNotify)g_free); + pull_data->expected_commit_sizes = g_hash_table_new_full ( + g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); + pull_data->commit_to_depth + = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); + pull_data->summary_deltas_checksums = g_hash_table_new_full ( + g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); + pull_data->ref_original_commits + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)NULL, (GDestroyNotify)g_free); + pull_data->verified_commits + = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); + pull_data->signapi_verified_commits + = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); + pull_data->ref_keyring_map + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, (GDestroyNotify)g_free); pull_data->scanned_metadata = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, (GDestroyNotify)g_variant_unref, NULL); - pull_data->fetched_detached_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, (GDestroyNotify)variant_or_null_unref); - pull_data->requested_content = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, NULL); - pull_data->requested_fallback_content = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, NULL); + pull_data->fetched_detached_metadata = g_hash_table_new_full ( + g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)variant_or_null_unref); + pull_data->requested_content + = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); + pull_data->requested_fallback_content + = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); pull_data->requested_metadata = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, (GDestroyNotify)g_variant_unref, NULL); - pull_data->pending_fetch_content = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)fetch_object_data_free); - pull_data->pending_fetch_metadata = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, - (GDestroyNotify)g_variant_unref, - (GDestroyNotify)fetch_object_data_free); - pull_data->pending_fetch_delta_indexes = g_hash_table_new_full (NULL, NULL, (GDestroyNotify) fetch_delta_index_data_free, NULL); - pull_data->pending_fetch_delta_superblocks = g_hash_table_new_full (NULL, NULL, (GDestroyNotify) fetch_delta_super_data_free, NULL); - pull_data->pending_fetch_deltaparts = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)fetch_static_delta_data_free, NULL); + pull_data->pending_fetch_content = g_hash_table_new_full ( + g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)fetch_object_data_free); + pull_data->pending_fetch_metadata = g_hash_table_new_full ( + ostree_hash_object_name, g_variant_equal, (GDestroyNotify)g_variant_unref, + (GDestroyNotify)fetch_object_data_free); + pull_data->pending_fetch_delta_indexes + = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)fetch_delta_index_data_free, NULL); + pull_data->pending_fetch_delta_superblocks + = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)fetch_delta_super_data_free, NULL); + pull_data->pending_fetch_deltaparts + = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)fetch_static_delta_data_free, NULL); if (opt_localcache_repos && *opt_localcache_repos) { @@ -3924,8 +3736,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, for (char **it = opt_localcache_repos; it && *it; it++) { const char *localcache_path = *it; - g_autoptr(GFile) localcache_file = g_file_new_for_path (localcache_path); - g_autoptr(OstreeRepo) cacherepo = ostree_repo_new (localcache_file); + g_autoptr (GFile) localcache_file = g_file_new_for_path (localcache_path); + g_autoptr (OstreeRepo) cacherepo = ostree_repo_new (localcache_file); if (!ostree_repo_open (cacherepo, cancellable, error)) goto out; g_ptr_array_add (pull_data->localcache_repos, g_steal_pointer (&cacherepo)); @@ -3954,10 +3766,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, /* For compatibility with pull-local, don't gpg verify local * pulls by default. */ - if ((pull_data->gpg_verify || - pull_data->gpg_verify_summary - ) && - pull_data->remote_name == NULL) + if ((pull_data->gpg_verify || pull_data->gpg_verify_summary) + && pull_data->remote_name == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Must specify remote name to enable gpg verification"); @@ -3987,29 +3797,25 @@ ostree_repo_pull_with_options (OstreeRepo *self, /* NOTE: If changing this, see the matching implementation in * ostree-sysroot-upgrader.c */ - if (!ostree_repo_get_remote_option (self, pull_data->remote_name, - "unconfigured-state", NULL, - &unconfigured_state, - error)) + if (!ostree_repo_get_remote_option (self, pull_data->remote_name, "unconfigured-state", NULL, + &unconfigured_state, error)) goto out; if (unconfigured_state) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "remote unconfigured-state: %s", unconfigured_state); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "remote unconfigured-state: %s", + unconfigured_state); goto out; } - if (!ostree_repo_get_remote_option (self, pull_data->remote_name, - "custom-backend", NULL, - &custom_backend, - error)) + if (!ostree_repo_get_remote_option (self, pull_data->remote_name, "custom-backend", NULL, + &custom_backend, error)) goto out; if (custom_backend) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Cannot fetch via libostree - remote '%s' uses custom backend '%s'", + "Cannot fetch via libostree - remote '%s' uses custom backend '%s'", pull_data->remote_name, custom_backend); goto out; } @@ -4019,8 +3825,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, { if (!_signapi_init_for_remote (pull_data->repo, pull_data->remote_name, &pull_data->signapi_commit_verifiers, - &pull_data->signapi_summary_verifiers, - error)) + &pull_data->signapi_summary_verifiers, error)) goto out; } @@ -4030,32 +3835,28 @@ ostree_repo_pull_with_options (OstreeRepo *self, goto out; pull_data->tmpdir_dfd = pull_data->repo->tmp_dir_fd; - requested_refs_to_fetch = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - (GDestroyNotify) ostree_collection_ref_free, - g_free); + requested_refs_to_fetch + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, g_free); commits_to_fetch = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - if (!ostree_repo_get_remote_option (self, - remote_name_or_baseurl, "metalink", - NULL, &metalink_url_str, error)) + if (!ostree_repo_get_remote_option (self, remote_name_or_baseurl, "metalink", NULL, + &metalink_url_str, error)) goto out; if (!metalink_url_str) { - if (!compute_effective_mirrorlist (self, remote_name_or_baseurl, - url_override, - pull_data->fetcher, - pull_data->n_network_retries, - &pull_data->meta_mirrorlist, - cancellable, error)) + if (!compute_effective_mirrorlist (self, remote_name_or_baseurl, url_override, + pull_data->fetcher, pull_data->n_network_retries, + &pull_data->meta_mirrorlist, cancellable, error)) goto out; } else { - g_autoptr(GBytes) summary_bytes = NULL; - g_autoptr(OstreeFetcherURI) metalink_uri = _ostree_fetcher_uri_parse (metalink_url_str, error); - g_autoptr(OstreeFetcherURI) target_uri = NULL; + g_autoptr (GBytes) summary_bytes = NULL; + g_autoptr (OstreeFetcherURI) metalink_uri + = _ostree_fetcher_uri_parse (metalink_url_str, error); + g_autoptr (OstreeFetcherURI) target_uri = NULL; if (!metalink_uri) goto out; @@ -4064,15 +3865,11 @@ ostree_repo_pull_with_options (OstreeRepo *self, * re-downloads here. Would require additional support for caching the * metalink file or mirror list. */ - metalink = _ostree_metalink_new (pull_data->fetcher, "summary", - OSTREE_MAX_METADATA_SIZE, metalink_uri, - pull_data->n_network_retries); + metalink = _ostree_metalink_new (pull_data->fetcher, "summary", OSTREE_MAX_METADATA_SIZE, + metalink_uri, pull_data->n_network_retries); - if (! _ostree_metalink_request_sync (metalink, - &target_uri, - &summary_bytes, - cancellable, - error)) + if (!_ostree_metalink_request_sync (metalink, &target_uri, &summary_bytes, cancellable, + error)) goto out; /* XXX: would be interesting to implement metalink as another source of @@ -4081,14 +3878,15 @@ ostree_repo_pull_with_options (OstreeRepo *self, { g_autofree char *path = _ostree_fetcher_uri_get_path (target_uri); g_autofree char *basepath = g_path_get_dirname (path); - g_autoptr(OstreeFetcherURI) new_target_uri = _ostree_fetcher_uri_new_path (target_uri, basepath); - pull_data->meta_mirrorlist = - g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); + g_autoptr (OstreeFetcherURI) new_target_uri + = _ostree_fetcher_uri_new_path (target_uri, basepath); + pull_data->meta_mirrorlist + = g_ptr_array_new_with_free_func ((GDestroyNotify)_ostree_fetcher_uri_free); g_ptr_array_add (pull_data->meta_mirrorlist, g_steal_pointer (&new_target_uri)); } - pull_data->summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, - summary_bytes, FALSE); + pull_data->summary + = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE); } { @@ -4096,31 +3894,25 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (metalink_url_str == NULL && url_override != NULL) contenturl = g_strdup (url_override); - else if (!ostree_repo_get_remote_option (self, remote_name_or_baseurl, - "contenturl", NULL, + else if (!ostree_repo_get_remote_option (self, remote_name_or_baseurl, "contenturl", NULL, &contenturl, error)) goto out; if (contenturl == NULL) { - pull_data->content_mirrorlist = - g_ptr_array_ref (pull_data->meta_mirrorlist); + pull_data->content_mirrorlist = g_ptr_array_ref (pull_data->meta_mirrorlist); } else { - if (!compute_effective_mirrorlist (self, remote_name_or_baseurl, - contenturl, - pull_data->fetcher, - pull_data->n_network_retries, - &pull_data->content_mirrorlist, - cancellable, error)) + if (!compute_effective_mirrorlist (self, remote_name_or_baseurl, contenturl, + pull_data->fetcher, pull_data->n_network_retries, + &pull_data->content_mirrorlist, cancellable, error)) goto out; } } /* FIXME: Do we want an analogue of this which supports collection IDs? */ - if (!ostree_repo_get_remote_list_option (self, - remote_name_or_baseurl, "branches", + if (!ostree_repo_get_remote_list_option (self, remote_name_or_baseurl, "branches", &configured_branches, error)) goto out; @@ -4138,7 +3930,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (g_str_equal (first_scheme, "file") && !pull_data->require_static_deltas) { g_autofree char *uri = _ostree_fetcher_uri_to_string (first_uri); - g_autoptr(GFile) remote_repo_path = g_file_new_for_uri (uri); + g_autoptr (GFile) remote_repo_path = g_file_new_for_uri (uri); pull_data->remote_repo_local = ostree_repo_new (remote_repo_path); if (!ostree_repo_open (pull_data->remote_repo_local, cancellable, error)) goto out; @@ -4177,16 +3969,17 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (flags & OSTREE_REPO_PULL_FLAGS_TRUSTED_HTTP) pull_data->importflags |= _OSTREE_REPO_IMPORT_FLAGS_TRUSTED; - const gboolean verifying_bareuseronly = - (pull_data->importflags & _OSTREE_REPO_IMPORT_FLAGS_VERIFY_BAREUSERONLY) > 0; + const gboolean verifying_bareuseronly + = (pull_data->importflags & _OSTREE_REPO_IMPORT_FLAGS_VERIFY_BAREUSERONLY) > 0; /* If we're mirroring and writing into an archive repo, and both checksum and * bareuseronly are turned off, we can directly copy the content rather than * paying the cost of exploding it, checksumming, and re-gzip. */ - const gboolean mirroring_into_archive = - pull_data->is_mirror && pull_data->repo->mode == OSTREE_REPO_MODE_ARCHIVE; - const gboolean import_trusted = !verifying_bareuseronly && - (pull_data->importflags & _OSTREE_REPO_IMPORT_FLAGS_TRUSTED) > 0; + const gboolean mirroring_into_archive + = pull_data->is_mirror && pull_data->repo->mode == OSTREE_REPO_MODE_ARCHIVE; + const gboolean import_trusted + = !verifying_bareuseronly + && (pull_data->importflags & _OSTREE_REPO_IMPORT_FLAGS_TRUSTED) > 0; pull_data->trusted_http_direct = mirroring_into_archive && import_trusted; } @@ -4217,7 +4010,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, { const gchar *collection_id, *ref_name, *checksum; - while (g_variant_iter_loop (collection_refs_iter, "(&s&s&s)", &collection_id, &ref_name, &checksum)) + while (g_variant_iter_loop (collection_refs_iter, "(&s&s&s)", &collection_id, &ref_name, + &checksum)) { if (!ostree_validate_rev (ref_name, error)) goto out; @@ -4262,22 +4056,24 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!(branches_iter && *branches_iter)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No configured branches for remote %s", remote_name_or_baseurl); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No configured branches for remote %s", + remote_name_or_baseurl); goto out; } - for (;branches_iter && *branches_iter; branches_iter++) + for (; branches_iter && *branches_iter; branches_iter++) { const char *branch = *branches_iter; - g_hash_table_insert (requested_refs_to_fetch, - ostree_collection_ref_new (NULL, branch), NULL); + g_hash_table_insert (requested_refs_to_fetch, ostree_collection_ref_new (NULL, branch), + NULL); } } /* Deltas are necessary when mirroring or resolving a requested ref to a commit. * We try to avoid loading the potentially large summary if it is not needed. */ - need_summary = require_summary_for_mirror || !all_requested_refs_have_commit (requested_refs_to_fetch) || summary_sig_bytes_v != NULL; + need_summary = require_summary_for_mirror + || !all_requested_refs_have_commit (requested_refs_to_fetch) + || summary_sig_bytes_v != NULL; /* If we don't have indexed deltas, we need the summary for deltas, so check * the config file for support. @@ -4294,20 +4090,21 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!pull_data->has_indexed_deltas) need_summary = TRUE; - } + } - pull_data->static_delta_superblocks = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); + pull_data->static_delta_targets + = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); if (need_summary) { - g_autoptr(GBytes) bytes_sig = NULL; + g_autoptr (GBytes) bytes_sig = NULL; gboolean summary_sig_not_modified = FALSE; g_autofree char *summary_sig_etag = NULL; guint64 summary_sig_last_modified = 0; gsize n; - g_autoptr(GVariant) refs = NULL; - g_autoptr(GVariant) deltas = NULL; - g_autoptr(GVariant) additional_metadata = NULL; + g_autoptr (GVariant) refs = NULL; + g_autoptr (GVariant) deltas = NULL; + g_autoptr (GVariant) additional_metadata = NULL; gboolean summary_from_cache = FALSE; gboolean tombstone_commits = FALSE; @@ -4338,19 +4135,17 @@ ostree_repo_pull_with_options (OstreeRepo *self, * Last-Modified from the on-disk cache (if it exists) to reduce the * download size if nothing’s changed. */ _ostree_repo_load_cache_summary_properties (self, remote_name_or_baseurl, ".sig", - &summary_sig_if_none_match, &summary_sig_if_modified_since); + &summary_sig_if_none_match, + &summary_sig_if_modified_since); g_clear_pointer (&summary_sig_etag, g_free); summary_sig_last_modified = 0; - if (!_ostree_fetcher_mirrored_request_to_membuf (pull_data->fetcher, - pull_data->meta_mirrorlist, - "summary.sig", OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - summary_sig_if_none_match, summary_sig_if_modified_since, - pull_data->n_network_retries, - &bytes_sig, - &summary_sig_not_modified, &summary_sig_etag, &summary_sig_last_modified, - OSTREE_MAX_METADATA_SIZE, - cancellable, error)) + if (!_ostree_fetcher_mirrored_request_to_membuf ( + pull_data->fetcher, pull_data->meta_mirrorlist, "summary.sig", + OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, summary_sig_if_none_match, + summary_sig_if_modified_since, pull_data->n_network_retries, &bytes_sig, + &summary_sig_not_modified, &summary_sig_etag, &summary_sig_last_modified, + OSTREE_MAX_METADATA_SIZE, cancellable, error)) goto out; /* The server returned HTTP status 304 Not Modified, so we’re clear to @@ -4361,28 +4156,19 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_clear_pointer (&bytes_sig, g_bytes_unref); g_clear_pointer (&bytes_summary, g_bytes_unref); if (!_ostree_repo_load_cache_summary_file (self, remote_name_or_baseurl, ".sig", - &bytes_sig, - cancellable, error)) + &bytes_sig, cancellable, error)) goto out; - if (!bytes_summary && - !pull_data->remote_repo_local && - !_ostree_repo_load_cache_summary_file (self, remote_name_or_baseurl, NULL, - &bytes_summary, - cancellable, error)) + if (!bytes_summary && !pull_data->remote_repo_local + && !_ostree_repo_load_cache_summary_file (self, remote_name_or_baseurl, NULL, + &bytes_summary, cancellable, error)) goto out; } } - if (bytes_sig && - !bytes_summary && - !pull_data->remote_repo_local && - !_ostree_repo_load_cache_summary_if_same_sig (self, - remote_name_or_baseurl, - bytes_sig, - &bytes_summary, - cancellable, - error)) + if (bytes_sig && !bytes_summary && !pull_data->remote_repo_local + && !_ostree_repo_load_cache_summary_if_same_sig (self, remote_name_or_baseurl, bytes_sig, + &bytes_summary, cancellable, error)) goto out; if (bytes_summary && !summary_bytes_v) @@ -4397,20 +4183,18 @@ ostree_repo_pull_with_options (OstreeRepo *self, guint64 summary_if_modified_since = 0; _ostree_repo_load_cache_summary_properties (self, remote_name_or_baseurl, NULL, - &summary_if_none_match, &summary_if_modified_since); + &summary_if_none_match, + &summary_if_modified_since); g_clear_pointer (&summary_etag, g_free); summary_last_modified = 0; - if (!_ostree_fetcher_mirrored_request_to_membuf (pull_data->fetcher, - pull_data->meta_mirrorlist, - "summary", OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - summary_if_none_match, summary_if_modified_since, - pull_data->n_network_retries, - &bytes_summary, - &summary_not_modified, &summary_etag, &summary_last_modified, - OSTREE_MAX_METADATA_SIZE, - cancellable, error)) + if (!_ostree_fetcher_mirrored_request_to_membuf ( + pull_data->fetcher, pull_data->meta_mirrorlist, "summary", + OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, summary_if_none_match, + summary_if_modified_since, pull_data->n_network_retries, &bytes_summary, + &summary_not_modified, &summary_etag, &summary_last_modified, + OSTREE_MAX_METADATA_SIZE, cancellable, error)) goto out; /* The server returned HTTP status 304 Not Modified, so we’re clear to @@ -4419,8 +4203,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, { g_clear_pointer (&bytes_summary, g_bytes_unref); if (!_ostree_repo_load_cache_summary_file (self, remote_name_or_baseurl, NULL, - &bytes_summary, - cancellable, error)) + &bytes_summary, cancellable, error)) goto out; } } @@ -4429,7 +4212,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!bytes_summary && pull_data->gpg_verify_summary) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "GPG verification enabled, but no summary found (use gpg-verify-summary=false in remote config to disable)"); + "GPG verification enabled, but no summary found (use " + "gpg-verify-summary=false in remote config to disable)"); goto out; } #endif /* OSTREE_DISABLE_GPGME */ @@ -4437,7 +4221,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!bytes_summary && require_summary_for_mirror) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Fetching all refs was requested in mirror mode, but remote repository does not have a summary"); + "Fetching all refs was requested in mirror mode, but remote repository " + "does not have a summary"); goto out; } @@ -4445,18 +4230,18 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!bytes_sig && pull_data->gpg_verify_summary) { g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, - "GPG verification enabled, but no summary.sig found (use gpg-verify-summary=false in remote config to disable)"); + "GPG verification enabled, but no summary.sig found (use " + "gpg-verify-summary=false in remote config to disable)"); goto out; } if (pull_data->gpg_verify_summary && bytes_summary && bytes_sig) { - g_autoptr(OstreeGpgVerifyResult) result = NULL; - g_autoptr(GError) temp_error = NULL; + g_autoptr (OstreeGpgVerifyResult) result = NULL; + g_autoptr (GError) temp_error = NULL; - result = ostree_repo_verify_summary (self, pull_data->remote_name, - bytes_summary, bytes_sig, - cancellable, &temp_error); + result = ostree_repo_verify_summary (self, pull_data->remote_name, bytes_summary, + bytes_sig, cancellable, &temp_error); if (!ostree_gpg_verify_result_require_valid_signature (result, &temp_error)) { if (summary_from_cache) @@ -4480,22 +4265,16 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_clear_pointer (&bytes_summary, g_bytes_unref); g_clear_pointer (&summary_etag, g_free); summary_last_modified = 0; - if (!_ostree_fetcher_mirrored_request_to_membuf (pull_data->fetcher, - pull_data->meta_mirrorlist, - "summary", - OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - NULL, 0, /* no cache headers */ - pull_data->n_network_retries, - &bytes_summary, - &summary_not_modified, &summary_etag, &summary_last_modified, - OSTREE_MAX_METADATA_SIZE, - cancellable, error)) + if (!_ostree_fetcher_mirrored_request_to_membuf ( + pull_data->fetcher, pull_data->meta_mirrorlist, "summary", + OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, NULL, 0, /* no cache headers */ + pull_data->n_network_retries, &bytes_summary, &summary_not_modified, + &summary_etag, &summary_last_modified, OSTREE_MAX_METADATA_SIZE, + cancellable, error)) goto out; - g_autoptr(OstreeGpgVerifyResult) retry = - ostree_repo_verify_summary (self, pull_data->remote_name, - bytes_summary, bytes_sig, - cancellable, error); + g_autoptr (OstreeGpgVerifyResult) retry = ostree_repo_verify_summary ( + self, pull_data->remote_name, bytes_summary, bytes_sig, cancellable, error); if (!ostree_gpg_verify_result_require_valid_signature (retry, error)) goto out; } @@ -4513,19 +4292,21 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!bytes_sig && pull_data->signapi_summary_verifiers) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Signatures verification enabled, but no summary.sig found (use sign-verify-summary=false in remote config to disable)"); + "Signatures verification enabled, but no summary.sig found (use " + "sign-verify-summary=false in remote config to disable)"); goto out; } if (bytes_summary && bytes_sig) { - g_autoptr(GVariant) signatures = NULL; - g_autoptr(GError) temp_error = NULL; + g_autoptr (GVariant) signatures = NULL; + g_autoptr (GError) temp_error = NULL; - signatures = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, - bytes_sig, FALSE); + signatures + = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, bytes_sig, FALSE); g_assert (pull_data->signapi_summary_verifiers); - if (!_sign_verify_for_remote (pull_data->signapi_summary_verifiers, bytes_summary, signatures, NULL, &temp_error)) + if (!_sign_verify_for_remote (pull_data->signapi_summary_verifiers, bytes_summary, + signatures, NULL, &temp_error)) { if (summary_from_cache) { @@ -4548,19 +4329,17 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_clear_pointer (&bytes_summary, g_bytes_unref); g_clear_pointer (&summary_etag, g_free); summary_last_modified = 0; - if (!_ostree_fetcher_mirrored_request_to_membuf (pull_data->fetcher, - pull_data->meta_mirrorlist, - "summary", - OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - NULL, 0, /* no cache headers */ - pull_data->n_network_retries, - &bytes_summary, - &summary_not_modified, &summary_etag, &summary_last_modified, - OSTREE_MAX_METADATA_SIZE, - cancellable, error)) + if (!_ostree_fetcher_mirrored_request_to_membuf ( + pull_data->fetcher, pull_data->meta_mirrorlist, "summary", + OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, NULL, + 0, /* no cache headers */ + pull_data->n_network_retries, &bytes_summary, &summary_not_modified, + &summary_etag, &summary_last_modified, OSTREE_MAX_METADATA_SIZE, + cancellable, error)) goto out; - if (!_sign_verify_for_remote (pull_data->signapi_summary_verifiers, bytes_summary, signatures, NULL, error)) + if (!_sign_verify_for_remote (pull_data->signapi_summary_verifiers, + bytes_summary, signatures, NULL, error)) goto out; } else @@ -4577,18 +4356,17 @@ ostree_repo_pull_with_options (OstreeRepo *self, pull_data->summary_data = g_bytes_ref (bytes_summary); pull_data->summary_etag = g_strdup (summary_etag); pull_data->summary_last_modified = summary_last_modified; - pull_data->summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes_summary, FALSE); + pull_data->summary + = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes_summary, FALSE); if (!g_variant_is_normal_form (pull_data->summary)) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Not normal form"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not normal form"); goto out; } if (!g_variant_is_of_type (pull_data->summary, OSTREE_SUMMARY_GVARIANT_FORMAT)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Doesn't match variant type '%s'", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Doesn't match variant type '%s'", (char *)OSTREE_SUMMARY_GVARIANT_FORMAT); goto out; } @@ -4603,15 +4381,10 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!summary_from_cache && bytes_summary && bytes_sig && summary_sig_bytes_v == NULL) { - if (!pull_data->remote_repo_local && - !_ostree_repo_cache_summary (self, - remote_name_or_baseurl, - bytes_summary, - summary_etag, summary_last_modified, - bytes_sig, - summary_sig_etag, summary_sig_last_modified, - cancellable, - error)) + if (!pull_data->remote_repo_local + && !_ostree_repo_cache_summary ( + self, remote_name_or_baseurl, bytes_summary, summary_etag, summary_last_modified, + bytes_sig, summary_sig_etag, summary_sig_last_modified, cancellable, error)) goto out; } @@ -4619,7 +4392,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, { additional_metadata = g_variant_get_child_value (pull_data->summary, 1); - if (!g_variant_lookup (additional_metadata, OSTREE_SUMMARY_COLLECTION_ID, "&s", &main_collection_id)) + if (!g_variant_lookup (additional_metadata, OSTREE_SUMMARY_COLLECTION_ID, "&s", + &main_collection_id)) main_collection_id = NULL; else if (!ostree_validate_collection_id (main_collection_id, error)) goto out; @@ -4628,7 +4402,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, for (i = 0, n = g_variant_n_children (refs); i < n; i++) { const char *refname; - g_autoptr(GVariant) ref = g_variant_get_child_value (refs, i); + g_autoptr (GVariant) ref = g_variant_get_child_value (refs, i); g_variant_get_child (ref, 0, "&s", &refname); @@ -4638,21 +4412,25 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (pull_data->is_mirror && !refs_to_fetch && !opt_collection_refs_set) { g_hash_table_insert (requested_refs_to_fetch, - ostree_collection_ref_new (main_collection_id, refname), NULL); + ostree_collection_ref_new (main_collection_id, refname), + NULL); } } - g_autoptr(GVariant) collection_map = NULL; - collection_map = g_variant_lookup_value (additional_metadata, OSTREE_SUMMARY_COLLECTION_MAP, G_VARIANT_TYPE ("a{sa(s(taya{sv}))}")); + g_autoptr (GVariant) collection_map = NULL; + collection_map + = g_variant_lookup_value (additional_metadata, OSTREE_SUMMARY_COLLECTION_MAP, + G_VARIANT_TYPE ("a{sa(s(taya{sv}))}")); if (collection_map != NULL) { GVariantIter collection_map_iter; const char *collection_id; - g_autoptr(GVariant) collection_refs = NULL; + g_autoptr (GVariant) collection_refs = NULL; g_variant_iter_init (&collection_map_iter, collection_map); - while (g_variant_iter_loop (&collection_map_iter, "{&s@a(s(taya{sv}))}", &collection_id, &collection_refs)) + while (g_variant_iter_loop (&collection_map_iter, "{&s@a(s(taya{sv}))}", + &collection_id, &collection_refs)) { if (!ostree_validate_collection_id (collection_id, error)) goto out; @@ -4660,7 +4438,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, for (i = 0, n = g_variant_n_children (collection_refs); i < n; i++) { const char *refname; - g_autoptr(GVariant) ref = g_variant_get_child_value (collection_refs, i); + g_autoptr (GVariant) ref = g_variant_get_child_value (collection_refs, i); g_variant_get_child (ref, 0, "&s", &refname); @@ -4670,23 +4448,27 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (pull_data->is_mirror && !refs_to_fetch && !opt_collection_refs_set) { g_hash_table_insert (requested_refs_to_fetch, - ostree_collection_ref_new (collection_id, refname), NULL); + ostree_collection_ref_new (collection_id, refname), + NULL); } } } } - deltas = g_variant_lookup_value (additional_metadata, OSTREE_SUMMARY_STATIC_DELTAS, G_VARIANT_TYPE ("a{sv}")); + deltas = g_variant_lookup_value (additional_metadata, OSTREE_SUMMARY_STATIC_DELTAS, + G_VARIANT_TYPE ("a{sv}")); pull_data->summary_has_deltas = deltas != NULL && g_variant_n_children (deltas) > 0; if (!collect_available_deltas_for_pull (pull_data, deltas, error)) goto out; - g_variant_lookup (additional_metadata, OSTREE_SUMMARY_INDEXED_DELTAS, "b", &pull_data->has_indexed_deltas); + (void)g_variant_lookup (additional_metadata, OSTREE_SUMMARY_INDEXED_DELTAS, "b", + &pull_data->has_indexed_deltas); } - if (pull_data->summary && - g_variant_lookup (additional_metadata, OSTREE_SUMMARY_MODE, "s", &remote_mode_str) && - g_variant_lookup (additional_metadata, OSTREE_SUMMARY_TOMBSTONE_COMMITS, "b", &tombstone_commits)) + if (pull_data->summary + && g_variant_lookup (additional_metadata, OSTREE_SUMMARY_MODE, "s", &remote_mode_str) + && g_variant_lookup (additional_metadata, OSTREE_SUMMARY_TOMBSTONE_COMMITS, "b", + &tombstone_commits)) { if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error)) goto out; @@ -4695,57 +4477,59 @@ ostree_repo_pull_with_options (OstreeRepo *self, } } - if (pull_data->require_static_deltas && !pull_data->has_indexed_deltas && !pull_data->summary_has_deltas) + if (pull_data->require_static_deltas && !pull_data->has_indexed_deltas + && !pull_data->summary_has_deltas) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Fetch configured to require static deltas, but no summary deltas or delta index found"); + g_set_error ( + error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "Fetch configured to require static deltas, but no summary deltas or delta index found"); goto out; } if (remote_mode_loaded && pull_data->remote_repo_local == NULL) - { - /* Fall-back path which loads the necessary config from the remote’s - * `config` file (unless we already read it above). Doing so is deprecated since it means an - * additional round trip to the remote for each pull. No need to do - * it for local pulls. */ - if (remote_config == NULL && - !load_remote_repo_config (pull_data, &remote_config, cancellable, error)) - goto out; + { + /* Fall-back path which loads the necessary config from the remote’s + * `config` file (unless we already read it above). Doing so is deprecated since it means an + * additional round trip to the remote for each pull. No need to do + * it for local pulls. */ + if (remote_config == NULL + && !load_remote_repo_config (pull_data, &remote_config, cancellable, error)) + goto out; - if (!ot_keyfile_get_value_with_default (remote_config, "core", "mode", "bare", - &remote_mode_str, error)) - goto out; + g_clear_pointer (&remote_mode_str, g_free); + if (!ot_keyfile_get_value_with_default (remote_config, "core", "mode", "bare", + &remote_mode_str, error)) + goto out; - if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error)) - goto out; + if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error)) + goto out; - if (!ot_keyfile_get_boolean_with_default (remote_config, "core", "tombstone-commits", FALSE, - &pull_data->has_tombstone_commits, error)) - goto out; + if (!ot_keyfile_get_boolean_with_default (remote_config, "core", "tombstone-commits", FALSE, + &pull_data->has_tombstone_commits, error)) + goto out; - remote_mode_loaded = TRUE; - } + remote_mode_loaded = TRUE; + } - if (remote_mode_loaded && pull_data->remote_repo_local == NULL && pull_data->remote_mode != OSTREE_REPO_MODE_ARCHIVE) + if (remote_mode_loaded && pull_data->remote_repo_local == NULL + && pull_data->remote_mode != OSTREE_REPO_MODE_ARCHIVE) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Can't pull from archives with mode \"%s\"", - remote_mode_str); + "Can't pull from archives with mode \"%s\"", remote_mode_str); goto out; } /* Resolve the checksum for each ref. This has to be done into a new hash table, * since we can’t modify the keys of @requested_refs_to_fetch while iterating * over it, and we need to ensure the collection IDs are resolved too. */ - updated_requested_refs_to_fetch = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - (GDestroyNotify) ostree_collection_ref_free, - g_free); - GLNX_HASH_TABLE_FOREACH_KV (requested_refs_to_fetch, const OstreeCollectionRef*, ref, - const char*, override_commitid) + updated_requested_refs_to_fetch + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, g_free); + GLNX_HASH_TABLE_FOREACH_KV (requested_refs_to_fetch, const OstreeCollectionRef *, ref, + const char *, override_commitid) { g_autofree char *checksum = NULL; - g_autoptr(OstreeCollectionRef) ref_with_collection = NULL; + g_autoptr (OstreeCollectionRef) ref_with_collection = NULL; /* Support specifying "" for an override commitid */ if (override_commitid && *override_commitid) @@ -4761,18 +4545,21 @@ ostree_repo_pull_with_options (OstreeRepo *self, guint64 *malloced_size; g_autofree gchar *collection_id = NULL; - if (!lookup_commit_checksum_and_collection_from_summary (pull_data, ref, &checksum, &commit_size, &collection_id, error)) + if (!lookup_commit_checksum_and_collection_from_summary ( + pull_data, ref, &checksum, &commit_size, &collection_id, error)) goto out; ref_with_collection = ostree_collection_ref_new (collection_id, ref->ref_name); malloced_size = g_new0 (guint64, 1); *malloced_size = commit_size; - g_hash_table_insert (pull_data->expected_commit_sizes, g_strdup (checksum), malloced_size); + g_hash_table_insert (pull_data->expected_commit_sizes, g_strdup (checksum), + malloced_size); } else { - if (!fetch_ref_contents (pull_data, main_collection_id, ref, &checksum, cancellable, error)) + if (!fetch_ref_contents (pull_data, main_collection_id, ref, &checksum, cancellable, + error)) goto out; ref_with_collection = ostree_collection_ref_dup (ref); @@ -4797,14 +4584,13 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_steal_pointer (&from_rev)); } - g_hash_table_replace (updated_requested_refs_to_fetch, - g_steal_pointer (&ref_with_collection), + g_hash_table_replace (updated_requested_refs_to_fetch, g_steal_pointer (&ref_with_collection), g_steal_pointer (&checksum)); } /* Resolve refs to a checksum if necessary */ - if (pull_data->timestamp_check_from_rev && - !ostree_validate_checksum_string (pull_data->timestamp_check_from_rev, NULL)) + if (pull_data->timestamp_check_from_rev + && !ostree_validate_checksum_string (pull_data->timestamp_check_from_rev, NULL)) { g_autofree char *from_rev = NULL; if (!ostree_repo_resolve_rev (pull_data->repo, pull_data->timestamp_check_from_rev, FALSE, @@ -4818,8 +4604,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, requested_refs_to_fetch = g_steal_pointer (&updated_requested_refs_to_fetch); if (g_hash_table_size (requested_refs_to_fetch) == 1) { - GLNX_HASH_TABLE_FOREACH (requested_refs_to_fetch, - const OstreeCollectionRef *, ref) + GLNX_HASH_TABLE_FOREACH (requested_refs_to_fetch, const OstreeCollectionRef *, ref) { the_ref_to_fetch = ref->ref_name; break; @@ -4830,9 +4615,10 @@ ostree_repo_pull_with_options (OstreeRepo *self, { const gchar *collection_id, *ref_name, *keyring_remote_name; - while (g_variant_iter_loop (ref_keyring_map_iter, "(&s&s&s)", &collection_id, &ref_name, &keyring_remote_name)) + while (g_variant_iter_loop (ref_keyring_map_iter, "(&s&s&s)", &collection_id, &ref_name, + &keyring_remote_name)) { - g_autoptr(OstreeCollectionRef) c_r = NULL; + g_autoptr (OstreeCollectionRef) c_r = NULL; if (!ostree_validate_collection_id (collection_id, error)) goto out; @@ -4844,8 +4630,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, c_r = ostree_collection_ref_new (collection_id, ref_name); if (!g_hash_table_contains (requested_refs_to_fetch, c_r)) continue; - g_hash_table_insert (pull_data->ref_keyring_map, - g_steal_pointer (&c_r), + g_hash_table_insert (pull_data->ref_keyring_map, g_steal_pointer (&c_r), g_strdup (keyring_remote_name)); } } @@ -4871,24 +4656,24 @@ ostree_repo_pull_with_options (OstreeRepo *self, goto out; pull_data->legacy_transaction_resuming = FALSE; - if (!inherit_transaction && - !ostree_repo_prepare_transaction (pull_data->repo, &pull_data->legacy_transaction_resuming, - cancellable, error)) + if (!inherit_transaction + && !ostree_repo_prepare_transaction (pull_data->repo, &pull_data->legacy_transaction_resuming, + cancellable, error)) goto out; if (pull_data->legacy_transaction_resuming) g_debug ("resuming legacy transaction"); /* Initiate requests for explicit commit revisions */ - GLNX_HASH_TABLE_FOREACH_V (commits_to_fetch, const char*, commit) + GLNX_HASH_TABLE_FOREACH_V (commits_to_fetch, const char *, commit) { if (!initiate_request (pull_data, NULL, commit, error)) goto out; } /* Initiate requests for refs */ - GLNX_HASH_TABLE_FOREACH_KV (requested_refs_to_fetch, const OstreeCollectionRef*, ref, - const char*, to_revision) + GLNX_HASH_TABLE_FOREACH_KV (requested_refs_to_fetch, const OstreeCollectionRef *, ref, + const char *, to_revision) { if (!initiate_request (pull_data, ref, to_revision, error)) goto out; @@ -4925,8 +4710,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_assert_cmpint (pull_data->n_outstanding_content_fetches, ==, 0); g_assert_cmpint (pull_data->n_outstanding_content_write_requests, ==, 0); - GLNX_HASH_TABLE_FOREACH_KV (requested_refs_to_fetch, const OstreeCollectionRef*, ref, - const char*, checksum) + GLNX_HASH_TABLE_FOREACH_KV (requested_refs_to_fetch, const OstreeCollectionRef *, ref, + const char *, checksum) { g_autofree char *remote_ref = NULL; g_autofree char *original_rev = NULL; @@ -4945,46 +4730,44 @@ ostree_repo_pull_with_options (OstreeRepo *self, else { if (pull_data->is_mirror) - ostree_repo_transaction_set_collection_ref (pull_data->repo, - ref, checksum); + ostree_repo_transaction_set_collection_ref (pull_data->repo, ref, checksum); else - ostree_repo_transaction_set_ref (pull_data->repo, - pull_data->remote_refspec_name ?: pull_data->remote_name, - ref->ref_name, checksum); + ostree_repo_transaction_set_ref ( + pull_data->repo, pull_data->remote_refspec_name ?: pull_data->remote_name, + ref->ref_name, checksum); } } - if (pull_data->is_mirror && pull_data->summary_data && - !refs_to_fetch && !opt_collection_refs_set && !configured_branches) + if (pull_data->is_mirror && pull_data->summary_data && !refs_to_fetch && !opt_collection_refs_set + && !configured_branches) { - GLnxFileReplaceFlags replaceflag = - pull_data->repo->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : 0; + GLnxFileReplaceFlags replaceflag + = pull_data->repo->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : 0; gsize len; const guint8 *buf = g_bytes_get_data (pull_data->summary_data, &len); - if (!glnx_file_replace_contents_at (pull_data->repo->repo_dir_fd, "summary", - buf, len, replaceflag, - cancellable, error)) + if (!glnx_file_replace_contents_at (pull_data->repo->repo_dir_fd, "summary", buf, len, + replaceflag, cancellable, error)) goto out; - store_file_cache_properties (pull_data->repo->repo_dir_fd, "summary", - pull_data->summary_etag, pull_data->summary_last_modified); + store_file_cache_properties (pull_data->repo->repo_dir_fd, "summary", pull_data->summary_etag, + pull_data->summary_last_modified); if (pull_data->summary_data_sig) { buf = g_bytes_get_data (pull_data->summary_data_sig, &len); - if (!glnx_file_replace_contents_at (pull_data->repo->repo_dir_fd, "summary.sig", - buf, len, replaceflag, - cancellable, error)) + if (!glnx_file_replace_contents_at (pull_data->repo->repo_dir_fd, "summary.sig", buf, len, + replaceflag, cancellable, error)) goto out; store_file_cache_properties (pull_data->repo->repo_dir_fd, "summary.sig", - pull_data->summary_sig_etag, pull_data->summary_sig_last_modified); + pull_data->summary_sig_etag, + pull_data->summary_sig_last_modified); } } - if (!inherit_transaction && - !ostree_repo_commit_transaction (pull_data->repo, &tstats, cancellable, error)) + if (!inherit_transaction + && !ostree_repo_commit_transaction (pull_data->repo, &tstats, cancellable, error)) goto out; end_time = g_get_monotonic_time (); @@ -4992,7 +4775,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, bytes_transferred = _ostree_fetcher_bytes_transferred (pull_data->fetcher); if (pull_data->progress) { - g_autoptr(GString) buf = g_string_new (""); + g_autoptr (GString) buf = g_string_new (""); /* Ensure the rest of the progress keys are set appropriately. */ update_progress (pull_data); @@ -5008,10 +4791,9 @@ ostree_repo_pull_with_options (OstreeRepo *self, else g_string_append_printf (buf, "%u metadata, %u content objects fetched", pull_data->n_fetched_metadata, pull_data->n_fetched_content); - if (!pull_data->remote_repo_local && - (pull_data->n_imported_metadata || pull_data->n_imported_content)) - g_string_append_printf (buf, " (%u meta, %u content local)", - pull_data->n_imported_metadata, + if (!pull_data->remote_repo_local + && (pull_data->n_imported_metadata || pull_data->n_imported_content)) + g_string_append_printf (buf, " (%u meta, %u content local)", pull_data->n_imported_metadata, pull_data->n_imported_content); if (bytes_transferred > 0) @@ -5022,9 +4804,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, else shift = 1024; g_string_append_printf (buf, "; %" G_GUINT64_FORMAT " %s transferred in %u seconds", - (guint64)(bytes_transferred / shift), - shift == 1 ? "B" : "KiB", - (guint) ((end_time - pull_data->start_time) / G_USEC_PER_SEC)); + (guint64)(bytes_transferred / shift), shift == 1 ? "B" : "KiB", + (guint)((end_time - pull_data->start_time) / G_USEC_PER_SEC)); } if (!inherit_transaction) { @@ -5038,13 +4819,14 @@ ostree_repo_pull_with_options (OstreeRepo *self, #ifdef HAVE_LIBSYSTEMD if (bytes_transferred > 0 && pull_data->remote_name) { - g_autoptr(GString) msg = g_string_new (""); + g_autoptr (GString) msg = g_string_new (""); if (the_ref_to_fetch) g_string_append_printf (msg, "libostree pull from '%s' for %s complete", pull_data->remote_name, the_ref_to_fetch); else g_string_append_printf (msg, "libostree pull from '%s' for %u refs complete", - pull_data->remote_name, g_hash_table_size (requested_refs_to_fetch)); + pull_data->remote_name, + g_hash_table_size (requested_refs_to_fetch)); const char *gpg_verify_state; #ifndef OSTREE_DISABLE_GPGME @@ -5088,13 +4870,12 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_string_append (msg, "\n"); if (pull_data->n_fetched_deltaparts > 0) - g_string_append_printf (msg, "delta: parts: %u loose: %u", - pull_data->n_fetched_deltaparts, + g_string_append_printf (msg, "delta: parts: %u loose: %u", pull_data->n_fetched_deltaparts, pull_data->n_fetched_metadata + pull_data->n_fetched_content); else g_string_append_printf (msg, "non-delta: meta: %u content: %u", pull_data->n_fetched_metadata, pull_data->n_fetched_content); - const guint n_seconds = (guint) ((end_time - pull_data->start_time) / G_USEC_PER_SEC); + const guint n_seconds = (guint)((end_time - pull_data->start_time) / G_USEC_PER_SEC); g_autofree char *formatted_xferred = g_format_size (bytes_transferred); g_string_append_printf (msg, "\ntransfer: secs: %u size: %s", n_seconds, formatted_xferred); if (pull_data->signapi_commit_verifiers) @@ -5102,34 +4883,31 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_assert_cmpuint (g_hash_table_size (pull_data->signapi_verified_commits), >, 0); } - ot_journal_send ("MESSAGE=%s", msg->str, - "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_MESSAGE_FETCH_COMPLETE_ID), - "OSTREE_REMOTE=%s", pull_data->remote_name, - "OSTREE_SIGN=%s", sign_verify_state, - "OSTREE_GPG=%s", gpg_verify_state, - "OSTREE_SECONDS=%u", n_seconds, - "OSTREE_XFER_SIZE=%s", formatted_xferred, - NULL); + ot_journal_send ("MESSAGE=%s", msg->str, "MESSAGE_ID=" SD_ID128_FORMAT_STR, + SD_ID128_FORMAT_VAL (OSTREE_MESSAGE_FETCH_COMPLETE_ID), "OSTREE_REMOTE=%s", + pull_data->remote_name, "OSTREE_SIGN=%s", sign_verify_state, "OSTREE_GPG=%s", + gpg_verify_state, "OSTREE_SECONDS=%u", n_seconds, "OSTREE_XFER_SIZE=%s", + formatted_xferred, NULL); } #endif /* iterate over commits fetched and delete any commitpartial files */ if (pull_data->dirs == NULL && !pull_data->is_commit_only) { - GLNX_HASH_TABLE_FOREACH_V (requested_refs_to_fetch, const char*, checksum) + GLNX_HASH_TABLE_FOREACH_V (requested_refs_to_fetch, const char *, checksum) { if (!ostree_repo_mark_commit_partial (pull_data->repo, checksum, FALSE, error)) goto out; } - GLNX_HASH_TABLE_FOREACH_V (commits_to_fetch, const char*, commit) + GLNX_HASH_TABLE_FOREACH_V (commits_to_fetch, const char *, commit) { if (!ostree_repo_mark_commit_partial (pull_data->repo, commit, FALSE, error)) goto out; } /* and finally any parent commits we might also have pulled because of depth>0 */ - GLNX_HASH_TABLE_FOREACH (pull_data->commit_to_depth, const char*, commit) + GLNX_HASH_TABLE_FOREACH (pull_data->commit_to_depth, const char *, commit) { if (!ostree_repo_mark_commit_partial (pull_data->repo, commit, FALSE, error)) goto out; @@ -5137,7 +4915,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, } ret = TRUE; - out: +out: /* This is pretty ugly - we have two error locations, because we * have a mix of synchronous and async code. Mixing them gets messy * as we need to avoid overwriting errors. @@ -5170,7 +4948,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_clear_pointer (&pull_data->summary_data_sig, g_bytes_unref); g_clear_pointer (&pull_data->summary_sig_etag, g_free); g_clear_pointer (&pull_data->summary, g_variant_unref); - g_clear_pointer (&pull_data->static_delta_superblocks, g_ptr_array_unref); + g_clear_pointer (&pull_data->static_delta_targets, g_hash_table_unref); g_clear_pointer (&pull_data->commit_to_depth, g_hash_table_unref); g_clear_pointer (&pull_data->expected_commit_sizes, g_hash_table_unref); g_clear_pointer (&pull_data->scanned_metadata, g_hash_table_unref); @@ -5189,7 +4967,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_clear_pointer (&pull_data->pending_fetch_delta_indexes, g_hash_table_unref); g_clear_pointer (&pull_data->pending_fetch_delta_superblocks, g_hash_table_unref); g_clear_pointer (&pull_data->pending_fetch_deltaparts, g_hash_table_unref); - g_queue_foreach (&pull_data->scan_object_queue, (GFunc) scan_object_queue_data_free, NULL); + g_queue_foreach (&pull_data->scan_object_queue, (GFunc)scan_object_queue_data_free, NULL); g_queue_clear (&pull_data->scan_object_queue); g_clear_pointer (&pull_data->idle_src, g_source_destroy); g_clear_pointer (&pull_data->dirs, g_ptr_array_unref); @@ -5203,11 +4981,12 @@ ostree_repo_pull_with_options (OstreeRepo *self, * have refs pointing to this commit. */ typedef struct { - gchar *checksum; /* always set */ - guint64 commit_size; /* always set */ - guint64 timestamp; /* 0 for unknown */ + gchar *checksum; /* always set */ + guint64 commit_size; /* always set */ + guint64 timestamp; /* 0 for unknown */ GVariant *additional_metadata; - GArray *refs; /* (element-type gsize), indexes to refs which point to this commit on at least one remote */ + GArray *refs; /* (element-type gsize), indexes to refs which point to this commit on at least one + remote */ } CommitMetadata; static void @@ -5222,18 +5001,17 @@ commit_metadata_free (CommitMetadata *info) G_DEFINE_AUTOPTR_CLEANUP_FUNC (CommitMetadata, commit_metadata_free) static CommitMetadata * -commit_metadata_new (const gchar *checksum, - guint64 commit_size, - guint64 timestamp, - GVariant *additional_metadata) +commit_metadata_new (const gchar *checksum, guint64 commit_size, guint64 timestamp, + GVariant *additional_metadata) { - g_autoptr(CommitMetadata) info = NULL; + g_autoptr (CommitMetadata) info = NULL; info = g_new0 (CommitMetadata, 1); info->checksum = g_strdup (checksum); info->commit_size = commit_size; info->timestamp = timestamp; - info->additional_metadata = (additional_metadata != NULL) ? g_variant_ref (additional_metadata) : NULL; + info->additional_metadata + = (additional_metadata != NULL) ? g_variant_ref (additional_metadata) : NULL; info->refs = g_array_new (FALSE, FALSE, sizeof (gsize)); return g_steal_pointer (&info); @@ -5245,9 +5023,9 @@ commit_metadata_new (const gchar *checksum, * there. */ typedef struct { - gsize width; /* pointers */ - gsize height; /* pointers */ - gconstpointer pointers[]; /* n_pointers = width * height */ + gsize width; /* pointers */ + gsize height; /* pointers */ + gconstpointer pointers[]; /* n_pointers = width * height */ } PointerTable; static void @@ -5260,14 +5038,14 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (PointerTable, pointer_table_free) /* Both dimensions are in numbers of pointers. */ static PointerTable * -pointer_table_new (gsize width, - gsize height) +pointer_table_new (gsize width, gsize height) { - g_autoptr(PointerTable) table = NULL; + g_autoptr (PointerTable) table = NULL; g_return_val_if_fail (width > 0, NULL); g_return_val_if_fail (height > 0, NULL); - g_return_val_if_fail (width <= (G_MAXSIZE - sizeof (PointerTable)) / sizeof (gconstpointer) / height, NULL); + g_return_val_if_fail ( + width <= (G_MAXSIZE - sizeof (PointerTable)) / sizeof (gconstpointer) / height, NULL); table = g_malloc0 (sizeof (PointerTable) + sizeof (gconstpointer) * width * height); table->width = width; @@ -5277,9 +5055,7 @@ pointer_table_new (gsize width, } static gconstpointer -pointer_table_get (const PointerTable *table, - gsize x, - gsize y) +pointer_table_get (const PointerTable *table, gsize x, gsize y) { g_return_val_if_fail (table != NULL, FALSE); g_return_val_if_fail (x < table->width, FALSE); @@ -5289,10 +5065,7 @@ pointer_table_get (const PointerTable *table, } static void -pointer_table_set (PointerTable *table, - gsize x, - gsize y, - gconstpointer value) +pointer_table_set (PointerTable *table, gsize x, gsize y, gconstpointer value) { g_return_if_fail (table != NULL); g_return_if_fail (x < table->width); @@ -5305,15 +5078,14 @@ pointer_table_set (PointerTable *table, static gboolean is_valid_collection_ref (const OstreeCollectionRef *ref) { - return (ref != NULL && - ostree_validate_rev (ref->ref_name, NULL) && - ostree_validate_collection_id (ref->collection_id, NULL)); + return (ref != NULL && ostree_validate_rev (ref->ref_name, NULL) + && ostree_validate_collection_id (ref->collection_id, NULL)); } /* Validate @refs is non-%NULL, non-empty, and contains only valid collection * and ref names. */ static gboolean -is_valid_collection_ref_array (const OstreeCollectionRef * const *refs) +is_valid_collection_ref_array (const OstreeCollectionRef *const *refs) { gsize i; @@ -5373,19 +5145,18 @@ find_remotes_data_free (FindRemotesData *data) G_DEFINE_AUTOPTR_CLEANUP_FUNC (FindRemotesData, find_remotes_data_free) static FindRemotesData * -find_remotes_data_new (const OstreeCollectionRef * const *refs, - GVariant *options, - OstreeAsyncProgress *progress, - OstreeRepoFinder *default_finder_avahi, - guint n_network_retries) +find_remotes_data_new (const OstreeCollectionRef *const *refs, GVariant *options, + OstreeAsyncProgress *progress, OstreeRepoFinder *default_finder_avahi, + guint n_network_retries) { - g_autoptr(FindRemotesData) data = NULL; + g_autoptr (FindRemotesData) data = NULL; data = g_new0 (FindRemotesData, 1); data->refs = ostree_collection_ref_dupv (refs); data->options = (options != NULL) ? g_variant_ref (options) : NULL; data->progress = (progress != NULL) ? g_object_ref (progress) : NULL; - data->default_finder_avahi = (default_finder_avahi != NULL) ? g_object_ref (default_finder_avahi) : NULL; + data->default_finder_avahi + = (default_finder_avahi != NULL) ? g_object_ref (default_finder_avahi) : NULL; data->n_network_retries = n_network_retries; return g_steal_pointer (&data); @@ -5394,7 +5165,7 @@ find_remotes_data_new (const OstreeCollectionRef * const *refs, static gchar * uint64_secs_to_iso8601 (guint64 secs) { - g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc (secs); + g_autoptr (GDateTime) dt = g_date_time_new_from_unix_utc (secs); if (dt != NULL) return g_date_time_format (dt, "%FT%TZ"); @@ -5403,11 +5174,10 @@ uint64_secs_to_iso8601 (guint64 secs) } static gint -sort_results_cb (gconstpointer a, - gconstpointer b) +sort_results_cb (gconstpointer a, gconstpointer b) { - const OstreeRepoFinderResult **result_a = (const OstreeRepoFinderResult **) a; - const OstreeRepoFinderResult **result_b = (const OstreeRepoFinderResult **) b; + const OstreeRepoFinderResult **result_a = (const OstreeRepoFinderResult **)a; + const OstreeRepoFinderResult **result_b = (const OstreeRepoFinderResult **)b; return ostree_repo_finder_result_compare (*result_a, *result_b); } @@ -5421,9 +5191,7 @@ repo_finder_result_free0 (OstreeRepoFinderResult *result) ostree_repo_finder_result_free (result); } -static void find_remotes_cb (GObject *obj, - GAsyncResult *result, - gpointer user_data); +static void find_remotes_cb (GObject *obj, GAsyncResult *result, gpointer user_data); /** * ostree_repo_find_remotes_async: @@ -5482,38 +5250,36 @@ static void find_remotes_cb (GObject *obj, * Since: 2018.6 */ void -ostree_repo_find_remotes_async (OstreeRepo *self, - const OstreeCollectionRef * const *refs, - GVariant *options, - OstreeRepoFinder **finders, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_find_remotes_async (OstreeRepo *self, const OstreeCollectionRef *const *refs, + GVariant *options, OstreeRepoFinder **finders, + OstreeAsyncProgress *progress, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = NULL; - g_autoptr(FindRemotesData) data = NULL; - OstreeRepoFinder *default_finders[4] = { NULL, }; - g_autoptr(OstreeRepoFinder) finder_config = NULL; - g_autoptr(OstreeRepoFinder) finder_mount = NULL; - g_autoptr(OstreeRepoFinder) finder_avahi = NULL; + g_autoptr (GTask) task = NULL; + g_autoptr (FindRemotesData) data = NULL; + OstreeRepoFinder *default_finders[4] = { + NULL, + }; + g_autoptr (OstreeRepoFinder) finder_config = NULL; + g_autoptr (OstreeRepoFinder) finder_mount = NULL; + g_autoptr (OstreeRepoFinder) finder_avahi = NULL; g_autofree char **override_commit_ids = NULL; guint n_network_retries = DEFAULT_N_NETWORK_RETRIES; g_return_if_fail (OSTREE_IS_REPO (self)); g_return_if_fail (is_valid_collection_ref_array (refs)); - g_return_if_fail (options == NULL || - g_variant_is_of_type (options, G_VARIANT_TYPE_VARDICT)); + g_return_if_fail (options == NULL || g_variant_is_of_type (options, G_VARIANT_TYPE_VARDICT)); g_return_if_fail (finders == NULL || is_valid_finder_array (finders)); g_return_if_fail (progress == NULL || OSTREE_IS_ASYNC_PROGRESS (progress)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); if (options) { - (void) g_variant_lookup (options, "override-commit-ids", "^a&s", &override_commit_ids); - g_return_if_fail (override_commit_ids == NULL || g_strv_length ((gchar **) refs) == g_strv_length (override_commit_ids)); + (void)g_variant_lookup (options, "override-commit-ids", "^a&s", &override_commit_ids); + g_return_if_fail (override_commit_ids == NULL + || g_strv_length ((gchar **)refs) == g_strv_length (override_commit_ids)); - (void) g_variant_lookup (options, "n-network-retries", "u", &n_network_retries); + (void)g_variant_lookup (options, "n-network-retries", "u", &n_network_retries); } /* Set up a task for the whole operation. */ @@ -5527,22 +5293,25 @@ ostree_repo_find_remotes_async (OstreeRepo *self, #ifdef HAVE_AVAHI guint avahi_index; GMainContext *context = g_main_context_get_thread_default (); - g_autoptr(GError) local_error = NULL; -#endif /* HAVE_AVAHI */ + g_autoptr (GError) local_error = NULL; +#endif /* HAVE_AVAHI */ - if (g_strv_contains ((const char * const *)self->repo_finders, "config")) - default_finders[finder_index++] = finder_config = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ()); + if (g_strv_contains ((const char *const *)self->repo_finders, "config")) + default_finders[finder_index++] = finder_config + = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ()); - if (g_strv_contains ((const char * const *)self->repo_finders, "mount")) - default_finders[finder_index++] = finder_mount = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL)); + if (g_strv_contains ((const char *const *)self->repo_finders, "mount")) + default_finders[finder_index++] = finder_mount + = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL)); #ifdef HAVE_AVAHI - if (g_strv_contains ((const char * const *)self->repo_finders, "lan")) + if (g_strv_contains ((const char *const *)self->repo_finders, "lan")) { avahi_index = finder_index; - default_finders[finder_index++] = finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (context)); + default_finders[finder_index++] = finder_avahi + = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (context)); } -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ /* self->repo_finders is guaranteed to be non-empty */ g_assert (default_finders != NULL); @@ -5551,8 +5320,7 @@ ostree_repo_find_remotes_async (OstreeRepo *self, #ifdef HAVE_AVAHI if (finder_avahi != NULL) { - ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), - &local_error); + ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), &local_error); if (local_error != NULL) { @@ -5566,7 +5334,8 @@ ostree_repo_find_remotes_async (OstreeRepo *self, * would cause client code to abort if a warning were emitted. */ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - g_debug ("Avahi finder failed under normal operation; removing it: %s", local_error->message); + g_debug ("Avahi finder failed under normal operation; removing it: %s", + local_error->message); else g_warning ("Avahi finder failed abnormally; removing it: %s", local_error->message); @@ -5574,34 +5343,32 @@ ostree_repo_find_remotes_async (OstreeRepo *self, g_clear_object (&finder_avahi); } } -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ } /* We need to keep a pointer to the default Avahi finder so we can stop it * again after the operation, which happens implicitly by dropping the final * ref. */ data = find_remotes_data_new (refs, options, progress, finder_avahi, n_network_retries); - g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) find_remotes_data_free); + g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify)find_remotes_data_free); /* Asynchronously resolve all possible remotes for the given refs. */ - ostree_repo_finder_resolve_all_async (finders, refs, self, cancellable, - find_remotes_cb, g_steal_pointer (&task)); + ostree_repo_finder_resolve_all_async (finders, refs, self, cancellable, find_remotes_cb, + g_steal_pointer (&task)); } /* Find the first instance of (@collection_id, @ref_name) in @refs and return * its index; or return %FALSE if nothing’s found. */ static gboolean -collection_refv_contains (const OstreeCollectionRef * const *refs, - const gchar *collection_id, - const gchar *ref_name, - gsize *out_index) +collection_refv_contains (const OstreeCollectionRef *const *refs, const gchar *collection_id, + const gchar *ref_name, gsize *out_index) { gsize i; for (i = 0; refs[i] != NULL; i++) { - if (g_str_equal (refs[i]->collection_id, collection_id) && - g_str_equal (refs[i]->ref_name, ref_name)) + if (g_str_equal (refs[i]->collection_id, collection_id) + && g_str_equal (refs[i]->ref_name, ref_name)) { *out_index = i; return TRUE; @@ -5616,26 +5383,23 @@ collection_refv_contains (const OstreeCollectionRef * const *refs, * points to into @refs_and_remotes_table at (@ref_index, @result_index). * @ref_index is the ref’s index in @refs. */ static gboolean -find_remotes_process_refs (OstreeRepo *self, - const OstreeCollectionRef * const *refs, - OstreeRepoFinderResult *result, - gsize result_index, - const gchar *summary_collection_id, - GVariant *summary_refs, - GHashTable *commit_metadatas, - PointerTable *refs_and_remotes_table) +find_remotes_process_refs (OstreeRepo *self, const OstreeCollectionRef *const *refs, + OstreeRepoFinderResult *result, gsize result_index, + const gchar *summary_collection_id, GVariant *summary_refs, + GHashTable *commit_metadatas, PointerTable *refs_and_remotes_table) { gsize j, n; for (j = 0, n = g_variant_n_children (summary_refs); j < n; j++) { const guchar *csum_bytes; - g_autoptr(GVariant) ref_v = NULL, csum_v = NULL, commit_metadata_v = NULL, stored_commit_v = NULL; + g_autoptr (GVariant) ref_v = NULL, csum_v = NULL, commit_metadata_v = NULL, + stored_commit_v = NULL; guint64 commit_size, commit_timestamp; gchar tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; gsize ref_index; - g_autoptr(GDateTime) dt = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GDateTime) dt = NULL; + g_autoptr (GError) error = NULL; const gchar *ref_name; CommitMetadata *commit_metadata; @@ -5645,8 +5409,8 @@ find_remotes_process_refs (OstreeRepo *self, if (!ostree_validate_rev (ref_name, &error)) { - g_debug ("%s: Summary for result ‘%s’ contained invalid ref name ‘%s’: %s", - G_STRFUNC, result->remote->name, ref_name, error->message); + g_debug ("%s: Summary for result ‘%s’ contained invalid ref name ‘%s’: %s", G_STRFUNC, + result->remote->name, ref_name, error->message); return FALSE; } @@ -5656,8 +5420,8 @@ find_remotes_process_refs (OstreeRepo *self, csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, &error); if (csum_bytes == NULL) { - g_debug ("%s: Summary for result ‘%s’ contained invalid ref checksum: %s", - G_STRFUNC, result->remote->name, error->message); + g_debug ("%s: Summary for result ‘%s’ contained invalid ref checksum: %s", G_STRFUNC, + result->remote->name, error->message); return FALSE; } @@ -5673,7 +5437,7 @@ find_remotes_process_refs (OstreeRepo *self, /* Check the additional metadata. */ if (!g_variant_lookup (commit_metadata_v, OSTREE_COMMIT_TIMESTAMP, "t", &commit_timestamp)) - commit_timestamp = 0; /* unknown */ + commit_timestamp = 0; /* unknown */ else commit_timestamp = GUINT64_FROM_BE (commit_timestamp); @@ -5681,7 +5445,8 @@ find_remotes_process_refs (OstreeRepo *self, if (dt == NULL) { - g_debug ("%s: Summary for result ‘%s’ contained commit timestamp %" G_GUINT64_FORMAT " which is too far in the future. Resetting to 0.", + g_debug ("%s: Summary for result ‘%s’ contained commit timestamp %" G_GUINT64_FORMAT + " which is too far in the future. Resetting to 0.", G_STRFUNC, result->remote->name, commit_timestamp); commit_timestamp = 0; } @@ -5691,11 +5456,11 @@ find_remotes_process_refs (OstreeRepo *self, if (commit_metadata == NULL) { - commit_metadata = commit_metadata_new (tmp_checksum, commit_size, - (stored_commit_v != NULL) ? ostree_commit_get_timestamp (stored_commit_v) : 0, - NULL); + commit_metadata = commit_metadata_new ( + tmp_checksum, commit_size, + (stored_commit_v != NULL) ? ostree_commit_get_timestamp (stored_commit_v) : 0, NULL); g_hash_table_insert (commit_metadatas, commit_metadata->checksum, - commit_metadata /* transfer */); + commit_metadata /* transfer */); } /* Update the metadata if possible. */ @@ -5705,59 +5470,63 @@ find_remotes_process_refs (OstreeRepo *self, } else if (commit_timestamp != 0 && commit_metadata->timestamp != commit_timestamp) { - g_debug ("%s: Summary for result ‘%s’ contained commit timestamp %" G_GUINT64_FORMAT " which did not match existing timestamp %" G_GUINT64_FORMAT ". Ignoring.", + g_debug ("%s: Summary for result ‘%s’ contained commit timestamp %" G_GUINT64_FORMAT + " which did not match existing timestamp %" G_GUINT64_FORMAT ". Ignoring.", G_STRFUNC, result->remote->name, commit_timestamp, commit_metadata->timestamp); return FALSE; } if (commit_size != commit_metadata->commit_size) { - g_debug ("%s: Summary for result ‘%s’ contained commit size %" G_GUINT64_FORMAT "B which did not match existing size %" G_GUINT64_FORMAT "B. Ignoring.", + g_debug ("%s: Summary for result ‘%s’ contained commit size %" G_GUINT64_FORMAT + "B which did not match existing size %" G_GUINT64_FORMAT "B. Ignoring.", G_STRFUNC, result->remote->name, commit_size, commit_metadata->commit_size); return FALSE; } - pointer_table_set (refs_and_remotes_table, ref_index, result_index, commit_metadata->checksum); + pointer_table_set (refs_and_remotes_table, ref_index, result_index, + commit_metadata->checksum); g_array_append_val (commit_metadata->refs, ref_index); - g_debug ("%s: Remote ‘%s’ lists ref ‘%s’ mapping to commit ‘%s’.", - G_STRFUNC, result->remote->name, ref_name, commit_metadata->checksum); + g_debug ("%s: Remote ‘%s’ lists ref ‘%s’ mapping to commit ‘%s’.", G_STRFUNC, + result->remote->name, ref_name, commit_metadata->checksum); } return TRUE; } static void -find_remotes_cb (GObject *obj, - GAsyncResult *async_result, - gpointer user_data) +find_remotes_cb (GObject *obj, GAsyncResult *async_result, gpointer user_data) { OstreeRepo *self; - g_autoptr(GTask) task = NULL; + g_autoptr (GTask) task = NULL; GCancellable *cancellable; const FindRemotesData *data; - const OstreeCollectionRef * const *refs; + const OstreeCollectionRef *const *refs; /* FIXME: We currently do nothing with @progress. Comment out to assuage -Wunused-variable */ /* OstreeAsyncProgress *progress; */ - g_autoptr(GError) error = NULL; - g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GError) error = NULL; + g_autoptr (GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ gsize i; - g_autoptr(PointerTable) refs_and_remotes_table = NULL; /* (element-type commit-checksum) */ - g_autoptr(GHashTable) commit_metadatas = NULL; /* (element-type commit-checksum CommitMetadata) */ - g_autoptr(OstreeFetcher) fetcher = NULL; - g_autofree const gchar **ref_to_latest_commit = NULL; /* indexed as @refs; (element-type commit-checksum) */ - g_autofree guint64 *ref_to_latest_timestamp = NULL; /* indexed as @refs; (element-type commit-timestamp) */ + g_autoptr (PointerTable) refs_and_remotes_table = NULL; /* (element-type commit-checksum) */ + g_autoptr (GHashTable) commit_metadatas + = NULL; /* (element-type commit-checksum CommitMetadata) */ + g_autoptr (OstreeFetcher) fetcher = NULL; + g_autofree const gchar **ref_to_latest_commit + = NULL; /* indexed as @refs; (element-type commit-checksum) */ + g_autofree guint64 *ref_to_latest_timestamp + = NULL; /* indexed as @refs; (element-type commit-timestamp) */ gsize n_refs; g_autofree char **override_commit_ids = NULL; - g_autoptr(GPtrArray) remotes_to_remove = NULL; /* (element-type OstreeRemote) */ - g_autoptr(GPtrArray) final_results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GPtrArray) remotes_to_remove = NULL; /* (element-type OstreeRemote) */ + g_autoptr (GPtrArray) final_results = NULL; /* (element-type OstreeRepoFinderResult) */ task = G_TASK (user_data); self = OSTREE_REPO (g_task_get_source_object (task)); cancellable = g_task_get_cancellable (task); data = g_task_get_task_data (task); - refs = (const OstreeCollectionRef * const *) data->refs; + refs = (const OstreeCollectionRef *const *)data->refs; /* progress = data->progress; */ /* Finish finding the remotes. */ @@ -5771,7 +5540,7 @@ find_remotes_cb (GObject *obj, if (results->len == 0) { - g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify)g_ptr_array_unref); return; } @@ -5779,11 +5548,11 @@ find_remotes_cb (GObject *obj, * clearing them to %NULL. We cannot remove them from the array, as that messes * up iteration and stored array indices. Accordingly, we need the free function * to be %NULL-safe. */ - g_ptr_array_set_free_func (results, (GDestroyNotify) repo_finder_result_free0); + g_ptr_array_set_free_func (results, (GDestroyNotify)repo_finder_result_free0); if (data->options) { - (void) g_variant_lookup (data->options, "override-commit-ids", "^a&s", &override_commit_ids); + (void)g_variant_lookup (data->options, "override-commit-ids", "^a&s", &override_commit_ids); } /* FIXME: In future, we also want to pull static delta superblocks in this @@ -5792,14 +5561,15 @@ find_remotes_cb (GObject *obj, * disable-static-deltas option first. */ /* Each key must be a pointer to the #CommitMetadata.checksum field of its value. */ - commit_metadatas = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) commit_metadata_free); + commit_metadatas + = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)commit_metadata_free); /* X dimension is an index into @refs. Y dimension is an index into @results. * Each cell stores the commit checksum which that ref resolves to on that * remote, or %NULL if the remote doesn’t have that ref. */ - n_refs = g_strv_length ((gchar **) refs); /* it’s not a GStrv, but this works */ + n_refs = g_strv_length ((gchar **)refs); /* it’s not a GStrv, but this works */ refs_and_remotes_table = pointer_table_new (n_refs, results->len); - remotes_to_remove = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_remote_unref); + remotes_to_remove = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_remote_unref); /* Fetch and validate the summary file for each result. */ /* FIXME: All these downloads could be parallelised; that requires the @@ -5807,13 +5577,13 @@ find_remotes_cb (GObject *obj, for (i = 0; i < results->len; i++) { OstreeRepoFinderResult *result = g_ptr_array_index (results, i); - g_autoptr(GBytes) summary_bytes = NULL; - g_autoptr(GVariant) summary_v = NULL; + g_autoptr (GBytes) summary_bytes = NULL; + g_autoptr (GVariant) summary_v = NULL; guint64 summary_last_modified; - g_autoptr(GVariant) summary_refs = NULL; - g_autoptr(GVariant) additional_metadata_v = NULL; + g_autoptr (GVariant) summary_refs = NULL; + g_autoptr (GVariant) additional_metadata_v = NULL; g_autofree gchar *summary_collection_id = NULL; - g_autoptr(GVariantIter) summary_collection_map = NULL; + g_autoptr (GVariantIter) summary_collection_map = NULL; gboolean invalid_result = FALSE; /* Add the remote to our internal list of remotes, so other libostree @@ -5821,41 +5591,36 @@ find_remotes_cb (GObject *obj, if (!_ostree_repo_add_remote (self, result->remote)) g_ptr_array_add (remotes_to_remove, ostree_remote_ref (result->remote)); - g_debug ("%s: Fetching summary for remote ‘%s’ with keyring ‘%s’.", - G_STRFUNC, result->remote->name, result->remote->keyring); + g_debug ("%s: Fetching summary for remote ‘%s’ with keyring ‘%s’.", G_STRFUNC, + result->remote->name, result->remote->keyring); /* Download the summary. This will load from the cache if possible. */ - ostree_repo_remote_fetch_summary_with_options (self, - result->remote->name, - NULL, /* no options */ - &summary_bytes, - NULL, - cancellable, - &error); + ostree_repo_remote_fetch_summary_with_options (self, result->remote->name, + NULL, /* no options */ + &summary_bytes, NULL, cancellable, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto error; else if (error != NULL) { - g_debug ("%s: Failed to download summary for result ‘%s’. Ignoring. %s", - G_STRFUNC, result->remote->name, error->message); + g_debug ("%s: Failed to download summary for result ‘%s’. Ignoring. %s", G_STRFUNC, + result->remote->name, error->message); g_clear_pointer (&g_ptr_array_index (results, i), ostree_repo_finder_result_free); g_clear_error (&error); continue; } else if (summary_bytes == NULL) { - g_debug ("%s: Failed to download summary for result ‘%s’. Ignoring. %s", - G_STRFUNC, result->remote->name, - "No summary file exists on server"); + g_debug ("%s: Failed to download summary for result ‘%s’. Ignoring. %s", G_STRFUNC, + result->remote->name, "No summary file exists on server"); g_clear_pointer (&g_ptr_array_index (results, i), ostree_repo_finder_result_free); continue; } /* Check the metadata in the summary file, especially whether it contains * all the @refs we are interested in. */ - summary_v = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, - summary_bytes, FALSE)); + summary_v = g_variant_ref_sink ( + g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE)); /* Check the summary’s additional metadata and set up @commit_metadata * and @refs_and_remotes_table with the refs listed in the summary file, @@ -5863,33 +5628,37 @@ find_remotes_cb (GObject *obj, * intersection with @refs. */ additional_metadata_v = g_variant_get_child_value (summary_v, 1); - if (g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_ID, "s", &summary_collection_id)) + if (g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_ID, "s", + &summary_collection_id)) { summary_refs = g_variant_get_child_value (summary_v, 0); - if (!find_remotes_process_refs (self, refs, result, i, summary_collection_id, summary_refs, - commit_metadatas, refs_and_remotes_table)) + if (!find_remotes_process_refs (self, refs, result, i, summary_collection_id, + summary_refs, commit_metadatas, refs_and_remotes_table)) { g_clear_pointer (&g_ptr_array_index (results, i), ostree_repo_finder_result_free); continue; } } - if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_MAP, "a{sa(s(taya{sv}))}", &summary_collection_map)) + if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_MAP, + "a{sa(s(taya{sv}))}", &summary_collection_map)) summary_collection_map = NULL; - while (summary_collection_map != NULL && - g_variant_iter_loop (summary_collection_map, "{s@a(s(taya{sv}))}", &summary_collection_id, &summary_refs)) + while (summary_collection_map != NULL + && g_variant_iter_loop (summary_collection_map, "{s@a(s(taya{sv}))}", + &summary_collection_id, &summary_refs)) { /* Exclude refs that don't use the associated keyring if this is a * dynamic remote, by comparing against the collection ID of the * remote this one inherits from */ - if (result->remote->refspec_name != NULL && - !check_remote_matches_collection_id (self, result->remote->refspec_name, summary_collection_id)) + if (result->remote->refspec_name != NULL + && !check_remote_matches_collection_id (self, result->remote->refspec_name, + summary_collection_id)) continue; - if (!find_remotes_process_refs (self, refs, result, i, summary_collection_id, summary_refs, - commit_metadatas, refs_and_remotes_table)) + if (!find_remotes_process_refs (self, refs, result, i, summary_collection_id, + summary_refs, commit_metadatas, refs_and_remotes_table)) { g_clear_pointer (&g_ptr_array_index (results, i), ostree_repo_finder_result_free); invalid_result = TRUE; @@ -5901,7 +5670,8 @@ find_remotes_cb (GObject *obj, continue; /* Check the summary timestamp. */ - if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_LAST_MODIFIED, "t", &summary_last_modified)) + if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_LAST_MODIFIED, "t", + &summary_last_modified)) summary_last_modified = 0; else summary_last_modified = GUINT64_FROM_BE (summary_last_modified); @@ -5918,21 +5688,22 @@ find_remotes_cb (GObject *obj, * the commit metadata from the remotes. The ‘most recent commits’ are the * set of head commits pointed to by the refs we just resolved from the * summary files. */ - GLNX_HASH_TABLE_FOREACH_V (commit_metadatas, CommitMetadata*, commit_metadata) + GLNX_HASH_TABLE_FOREACH_V (commit_metadatas, CommitMetadata *, commit_metadata) { char buf[_OSTREE_LOOSE_PATH_MAX]; g_autofree gchar *commit_filename = NULL; - g_autoptr(GPtrArray) mirrorlist = NULL; /* (element-type OstreeFetcherURI) */ - g_autoptr(GBytes) commit_bytes = NULL; - g_autoptr(GVariant) commit_v = NULL; + g_autoptr (GPtrArray) mirrorlist = NULL; /* (element-type OstreeFetcherURI) */ + g_autoptr (GBytes) commit_bytes = NULL; + g_autoptr (GVariant) commit_v = NULL; guint64 commit_timestamp; - g_autoptr(GDateTime) dt = NULL; + g_autoptr (GDateTime) dt = NULL; /* Already complete? */ if (commit_metadata->timestamp != 0) continue; - _ostree_loose_path (buf, commit_metadata->checksum, OSTREE_OBJECT_TYPE_COMMIT, OSTREE_REPO_MODE_ARCHIVE); + _ostree_loose_path (buf, commit_metadata->checksum, OSTREE_OBJECT_TYPE_COMMIT, + OSTREE_REPO_MODE_ARCHIVE); commit_filename = g_build_filename ("objects", buf, NULL); /* For each of the remotes whose summary files contain this ref, try @@ -5951,52 +5722,44 @@ find_remotes_cb (GObject *obj, if (result == NULL) continue; - if (pointer_table_get (refs_and_remotes_table, ref_index, j) != commit_metadata->checksum) + if (pointer_table_get (refs_and_remotes_table, ref_index, j) + != commit_metadata->checksum) continue; g_autofree gchar *uri = NULL; - g_autoptr(OstreeFetcherURI) fetcher_uri = NULL; + g_autoptr (OstreeFetcherURI) fetcher_uri = NULL; - if (!ostree_repo_remote_get_url (self, result->remote->name, - &uri, &error)) + if (!ostree_repo_remote_get_url (self, result->remote->name, &uri, &error)) goto error; fetcher_uri = _ostree_fetcher_uri_parse (uri, &error); if (fetcher_uri == NULL) goto error; - fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name, - TRUE, NULL, NULL, NULL, &error); + fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name, TRUE, NULL, + NULL, 0, 0, TRUE, 0, NULL, &error); if (fetcher == NULL) goto error; - g_debug ("%s: Fetching metadata for commit ‘%s’ from remote ‘%s’.", - G_STRFUNC, commit_metadata->checksum, result->remote->name); + g_debug ("%s: Fetching metadata for commit ‘%s’ from remote ‘%s’.", G_STRFUNC, + commit_metadata->checksum, result->remote->name); /* FIXME: Support remotes which have contenturl, mirrorlist, etc. */ - mirrorlist = g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); + mirrorlist + = g_ptr_array_new_with_free_func ((GDestroyNotify)_ostree_fetcher_uri_free); g_ptr_array_add (mirrorlist, g_steal_pointer (&fetcher_uri)); - if (!_ostree_fetcher_mirrored_request_to_membuf (fetcher, - mirrorlist, - commit_filename, - OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, - NULL, 0, - data->n_network_retries, - &commit_bytes, - NULL, NULL, NULL, - 0, /* no maximum size */ - cancellable, - &error)) + if (!_ostree_fetcher_mirrored_request_to_membuf ( + fetcher, mirrorlist, commit_filename, OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT, + NULL, 0, data->n_network_retries, &commit_bytes, NULL, NULL, NULL, + 0, /* no maximum size */ + cancellable, &error)) goto error; - g_autoptr(OstreeGpgVerifyResult) verify_result = NULL; + g_autoptr (OstreeGpgVerifyResult) verify_result = NULL; - verify_result = ostree_repo_verify_commit_for_remote (self, - commit_metadata->checksum, - result->remote->name, - cancellable, - &error); + verify_result = ostree_repo_verify_commit_for_remote ( + self, commit_metadata->checksum, result->remote->name, cancellable, &error); if (verify_result == NULL) { g_prefix_error (&error, "Commit %s: ", commit_metadata->checksum); @@ -6019,21 +5782,21 @@ find_remotes_cb (GObject *obj, if (commit_bytes == NULL) { - g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Metadata not found for commit ‘%s’", commit_metadata->checksum); + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Metadata not found for commit ‘%s’", + commit_metadata->checksum); goto error; } /* Parse the commit metadata. */ - commit_v = g_variant_new_from_bytes (OSTREE_COMMIT_GVARIANT_FORMAT, - commit_bytes, FALSE); + commit_v = g_variant_new_from_bytes (OSTREE_COMMIT_GVARIANT_FORMAT, commit_bytes, FALSE); g_variant_get_child (commit_v, 5, "t", &commit_timestamp); commit_timestamp = GUINT64_FROM_BE (commit_timestamp); dt = g_date_time_new_from_unix_utc (commit_timestamp); if (dt == NULL) { - g_debug ("%s: Commit ‘%s’ metadata contained timestamp %" G_GUINT64_FORMAT " which is too far in the future. Resetting to 0.", + g_debug ("%s: Commit ‘%s’ metadata contained timestamp %" G_GUINT64_FORMAT + " which is too far in the future. Resetting to 0.", G_STRFUNC, commit_metadata->checksum, commit_timestamp); commit_timestamp = 0; } @@ -6066,8 +5829,8 @@ find_remotes_cb (GObject *obj, if (override_commit_ids) { - g_debug ("%s: Using specified commit ‘%s’ for ref (%s, %s).", - G_STRFUNC, override_commit_ids[i], refs[i]->collection_id, refs[i]->ref_name); + g_debug ("%s: Using specified commit ‘%s’ for ref (%s, %s).", G_STRFUNC, + override_commit_ids[i], refs[i]->collection_id, refs[i]->ref_name); continue; } @@ -6084,8 +5847,8 @@ find_remotes_cb (GObject *obj, candidate_commit_metadata = g_hash_table_lookup (commit_metadatas, candidate_checksum); g_assert (candidate_commit_metadata != NULL); - if (latest_commit_metadata == NULL || - candidate_commit_metadata->timestamp > latest_commit_metadata->timestamp) + if (latest_commit_metadata == NULL + || candidate_commit_metadata->timestamp > latest_commit_metadata->timestamp) { latest_checksum = candidate_checksum; latest_commit_metadata = candidate_commit_metadata; @@ -6104,27 +5867,31 @@ find_remotes_cb (GObject *obj, if (latest_commit_metadata != NULL) { latest_commit_timestamp_str = uint64_secs_to_iso8601 (latest_commit_metadata->timestamp); - g_debug ("%s: Latest commit for ref (%s, %s) across all remotes is ‘%s’ with timestamp %s.", - G_STRFUNC, refs[i]->collection_id, refs[i]->ref_name, - latest_checksum, latest_commit_timestamp_str); + g_debug ( + "%s: Latest commit for ref (%s, %s) across all remotes is ‘%s’ with timestamp %s.", + G_STRFUNC, refs[i]->collection_id, refs[i]->ref_name, latest_checksum, + latest_commit_timestamp_str); } else { - g_debug ("%s: Latest commit for ref (%s, %s) is unknown due to failure to download metadata.", - G_STRFUNC, refs[i]->collection_id, refs[i]->ref_name); + g_debug ( + "%s: Latest commit for ref (%s, %s) is unknown due to failure to download metadata.", + G_STRFUNC, refs[i]->collection_id, refs[i]->ref_name); } } /* Recombine @commit_metadatas and @results so that each * #OstreeRepoFinderResult.refs lists the refs for which that remote has the * latest commits (i.e. it’s not out of date compared to some other remote). */ - final_results = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_repo_finder_result_free); + final_results = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_repo_finder_result_free); for (i = 0; i < results->len; i++) { OstreeRepoFinderResult *result = g_ptr_array_index (results, i); - g_autoptr(GHashTable) validated_ref_to_checksum = NULL; /* (element-type OstreeCollectionRef utf8) */ - g_autoptr(GHashTable) validated_ref_to_timestamp = NULL; /* (element-type OstreeCollectionRef guint64) */ + g_autoptr (GHashTable) validated_ref_to_checksum + = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) validated_ref_to_timestamp + = NULL; /* (element-type OstreeCollectionRef guint64) */ gsize j, n_latest_refs; /* Previous error processing this result? */ @@ -6133,15 +5900,13 @@ find_remotes_cb (GObject *obj, /* Map of refs to checksums provided by this result. The checksums should * be %NULL for each ref unless this result provides the latest checksum. */ - validated_ref_to_checksum = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - (GDestroyNotify) ostree_collection_ref_free, - g_free); - - validated_ref_to_timestamp = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - (GDestroyNotify) ostree_collection_ref_free, - g_free); + validated_ref_to_checksum + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, g_free); + + validated_ref_to_timestamp + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, g_free); if (override_commit_ids) { for (j = 0; refs[j] != NULL; j++) @@ -6209,7 +5974,7 @@ find_remotes_cb (GObject *obj, _ostree_repo_remove_remote (self, remote); } - g_task_return_pointer (task, g_steal_pointer (&final_results), (GDestroyNotify) g_ptr_array_unref); + g_task_return_pointer (task, g_steal_pointer (&final_results), (GDestroyNotify)g_ptr_array_unref); return; @@ -6239,11 +6004,9 @@ find_remotes_cb (GObject *obj, * Since: 2018.6 */ OstreeRepoFinderResult ** -ostree_repo_find_remotes_finish (OstreeRepo *self, - GAsyncResult *result, - GError **error) +ostree_repo_find_remotes_finish (OstreeRepo *self, GAsyncResult *result, GError **error) { - g_autoptr(GPtrArray) results = NULL; + g_autoptr (GPtrArray) results = NULL; g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); g_return_val_if_fail (g_task_is_valid (result, self), NULL); @@ -6254,20 +6017,18 @@ ostree_repo_find_remotes_finish (OstreeRepo *self, if (results != NULL) { - g_ptr_array_add (results, NULL); /* NULL terminator */ - return (OstreeRepoFinderResult **) g_ptr_array_free (g_steal_pointer (&results), FALSE); + g_ptr_array_add (results, NULL); /* NULL terminator */ + return (OstreeRepoFinderResult **)g_ptr_array_free (g_steal_pointer (&results), FALSE); } else return NULL; } static void -copy_option (GVariantDict *master_options, - GVariantDict *slave_options, - const gchar *key, +copy_option (GVariantDict *master_options, GVariantDict *slave_options, const gchar *key, const GVariantType *expected_type) { - g_autoptr(GVariant) option_v = g_variant_dict_lookup_value (master_options, key, expected_type); + g_autoptr (GVariant) option_v = g_variant_dict_lookup_value (master_options, key, expected_type); if (option_v != NULL) g_variant_dict_insert_value (slave_options, key, option_v); } @@ -6330,13 +6091,10 @@ copy_option (GVariantDict *master_options, * Since: 2018.6 */ void -ostree_repo_pull_from_remotes_async (OstreeRepo *self, - const OstreeRepoFinderResult * const *results, - GVariant *options, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_pull_from_remotes_async (OstreeRepo *self, const OstreeRepoFinderResult *const *results, + GVariant *options, OstreeAsyncProgress *progress, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { g_return_if_fail (OSTREE_IS_REPO (self)); g_return_if_fail (results != NULL && results[0] != NULL); @@ -6344,12 +6102,12 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, g_return_if_fail (progress == NULL || OSTREE_IS_ASYNC_PROGRESS (progress)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); - g_autoptr(GTask) task = NULL; - g_autoptr(GHashTable) refs_pulled = NULL; /* (element-type OstreeCollectionRef gboolean) */ + g_autoptr (GTask) task = NULL; + g_autoptr (GHashTable) refs_pulled = NULL; /* (element-type OstreeCollectionRef gboolean) */ gsize i, j; - g_autoptr(GString) refs_unpulled_string = NULL; - g_autoptr(GError) local_error = NULL; - g_auto(GVariantDict) options_dict = OT_VARIANT_BUILDER_INITIALIZER; + g_autoptr (GString) refs_unpulled_string = NULL; + g_autoptr (GError) local_error = NULL; + g_auto (GVariantDict) options_dict = OT_VARIANT_BUILDER_INITIALIZER; OstreeRepoPullFlags flags; gboolean inherit_transaction; @@ -6359,8 +6117,8 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, /* Keep track of the set of refs we’ve pulled already. Value is %TRUE if the * ref has been pulled; %FALSE if it has not. */ - refs_pulled = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, NULL, NULL); + refs_pulled + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, NULL, NULL); g_variant_dict_init (&options_dict, options); @@ -6370,8 +6128,8 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, inherit_transaction = FALSE; /* Run all the local pull operations in a single overall transaction. */ - if (!inherit_transaction && - !ostree_repo_prepare_transaction (self, NULL, cancellable, &local_error)) + if (!inherit_transaction + && !ostree_repo_prepare_transaction (self, NULL, cancellable, &local_error)) { g_task_return_error (task, g_steal_pointer (&local_error)); return; @@ -6387,31 +6145,30 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, { const OstreeRepoFinderResult *result = results[i]; - g_autoptr(GString) refs_to_pull_str = NULL; - g_autoptr(GPtrArray) refs_to_pull = NULL; /* (element-type OstreeCollectionRef) */ - g_auto(GVariantBuilder) refs_to_pull_builder = OT_VARIANT_BUILDER_INITIALIZER; - g_auto(GVariantDict) local_options_dict = OT_VARIANT_BUILDER_INITIALIZER; - g_autoptr(GVariant) local_options = NULL; + g_autoptr (GString) refs_to_pull_str = NULL; + g_autoptr (GPtrArray) refs_to_pull = NULL; /* (element-type OstreeCollectionRef) */ + g_auto (GVariantBuilder) refs_to_pull_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantDict) local_options_dict = OT_VARIANT_BUILDER_INITIALIZER; + g_autoptr (GVariant) local_options = NULL; gboolean remove_remote; refs_to_pull = g_ptr_array_new_with_free_func (NULL); refs_to_pull_str = g_string_new (""); g_variant_builder_init (&refs_to_pull_builder, G_VARIANT_TYPE ("a(sss)")); - GLNX_HASH_TABLE_FOREACH_KV (result->ref_to_checksum, const OstreeCollectionRef*, ref, - const char*, checksum) + GLNX_HASH_TABLE_FOREACH_KV (result->ref_to_checksum, const OstreeCollectionRef *, ref, + const char *, checksum) { - if (checksum != NULL && - !GPOINTER_TO_INT (g_hash_table_lookup (refs_pulled, ref))) + if (checksum != NULL && !GPOINTER_TO_INT (g_hash_table_lookup (refs_pulled, ref))) { - g_ptr_array_add (refs_to_pull, (gpointer) ref); - g_variant_builder_add (&refs_to_pull_builder, "(sss)", - ref->collection_id, ref->ref_name, checksum); + g_ptr_array_add (refs_to_pull, (gpointer)ref); + g_variant_builder_add (&refs_to_pull_builder, "(sss)", ref->collection_id, + ref->ref_name, checksum); if (refs_to_pull_str->len > 0) g_string_append (refs_to_pull_str, ", "); - g_string_append_printf (refs_to_pull_str, "(%s, %s)", - ref->collection_id, ref->ref_name); + g_string_append_printf (refs_to_pull_str, "(%s, %s)", ref->collection_id, + ref->ref_name); } } @@ -6426,14 +6183,15 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, /* NULL terminators. */ g_ptr_array_add (refs_to_pull, NULL); - g_debug ("Pulling from remote ‘%s’: %s", - result->remote->name, refs_to_pull_str->str); + g_debug ("Pulling from remote ‘%s’: %s", result->remote->name, refs_to_pull_str->str); /* Set up the pull options. */ g_variant_dict_init (&local_options_dict, NULL); - g_variant_dict_insert (&local_options_dict, "flags", "i", OSTREE_REPO_PULL_FLAGS_UNTRUSTED | flags); - g_variant_dict_insert_value (&local_options_dict, "collection-refs", g_variant_builder_end (&refs_to_pull_builder)); + g_variant_dict_insert (&local_options_dict, "flags", "i", + OSTREE_REPO_PULL_FLAGS_UNTRUSTED | flags); + g_variant_dict_insert_value (&local_options_dict, "collection-refs", + g_variant_builder_end (&refs_to_pull_builder)); #ifndef OSTREE_DISABLE_GPGME g_variant_dict_insert (&local_options_dict, "gpg-verify", "b", TRUE); #else @@ -6444,22 +6202,25 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, g_variant_dict_insert (&local_options_dict, "sign-verify-summary", "b", FALSE); g_variant_dict_insert (&local_options_dict, "inherit-transaction", "b", TRUE); if (result->remote->refspec_name != NULL) - g_variant_dict_insert (&local_options_dict, "override-remote-name", "s", result->remote->refspec_name); + g_variant_dict_insert (&local_options_dict, "override-remote-name", "s", + result->remote->refspec_name); copy_option (&options_dict, &local_options_dict, "depth", G_VARIANT_TYPE ("i")); - copy_option (&options_dict, &local_options_dict, "disable-static-deltas", G_VARIANT_TYPE ("b")); + copy_option (&options_dict, &local_options_dict, "disable-static-deltas", + G_VARIANT_TYPE ("b")); copy_option (&options_dict, &local_options_dict, "http-headers", G_VARIANT_TYPE ("a(ss)")); copy_option (&options_dict, &local_options_dict, "subdirs", G_VARIANT_TYPE ("as")); copy_option (&options_dict, &local_options_dict, "update-frequency", G_VARIANT_TYPE ("u")); copy_option (&options_dict, &local_options_dict, "append-user-agent", G_VARIANT_TYPE ("s")); copy_option (&options_dict, &local_options_dict, "n-network-retries", G_VARIANT_TYPE ("u")); - copy_option (&options_dict, &local_options_dict, "ref-keyring-map", G_VARIANT_TYPE ("a(sss)")); + copy_option (&options_dict, &local_options_dict, "ref-keyring-map", + G_VARIANT_TYPE ("a(sss)")); local_options = g_variant_dict_end (&local_options_dict); /* FIXME: We do nothing useful with @progress at the moment. */ remove_remote = !_ostree_repo_add_remote (self, result->remote); - ostree_repo_pull_with_options (self, result->remote->name, local_options, - progress, cancellable, &local_error); + ostree_repo_pull_with_options (self, result->remote->name, local_options, progress, + cancellable, &local_error); if (remove_remote) _ostree_repo_remove_remote (self, result->remote); @@ -6477,8 +6238,7 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, if (local_error != NULL) { - g_debug ("Failed to pull refs from ‘%s’: %s", - result->remote->name, local_error->message); + g_debug ("Failed to pull refs from ‘%s’: %s", result->remote->name, local_error->message); g_clear_error (&local_error); continue; } @@ -6489,16 +6249,16 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, } /* Commit the transaction. */ - if (!inherit_transaction && - !ostree_repo_commit_transaction (self, NULL, cancellable, &local_error)) + if (!inherit_transaction + && !ostree_repo_commit_transaction (self, NULL, cancellable, &local_error)) { g_task_return_error (task, g_steal_pointer (&local_error)); return; } /* Any refs left un-downloaded? If so, we’ve failed. */ - GLNX_HASH_TABLE_FOREACH_KV (refs_pulled, const OstreeCollectionRef*, ref, - gpointer, is_pulled_pointer) + GLNX_HASH_TABLE_FOREACH_KV (refs_pulled, const OstreeCollectionRef *, ref, gpointer, + is_pulled_pointer) { gboolean is_pulled = GPOINTER_TO_INT (is_pulled_pointer); @@ -6510,8 +6270,7 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, else g_string_append (refs_unpulled_string, ", "); - g_string_append_printf (refs_unpulled_string, "(%s, %s)", - ref->collection_id, ref->ref_name); + g_string_append_printf (refs_unpulled_string, "(%s, %s)", ref->collection_id, ref->ref_name); } if (refs_unpulled_string != NULL) @@ -6538,13 +6297,12 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, * Since: 2018.6 */ gboolean -ostree_repo_pull_from_remotes_finish (OstreeRepo *self, - GAsyncResult *result, - GError **error) +ostree_repo_pull_from_remotes_finish (OstreeRepo *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); g_return_val_if_fail (g_task_is_valid (result, self), FALSE); - g_return_val_if_fail (g_async_result_is_tagged (result, ostree_repo_pull_from_remotes_async), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, ostree_repo_pull_from_remotes_async), + FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); return g_task_propagate_boolean (G_TASK (result), error); @@ -6555,10 +6313,9 @@ ostree_repo_pull_from_remotes_finish (OstreeRepo *self, * @self: Self * @name: name of a remote * @options: (nullable): A GVariant a{sv} with an extensible set of flags - * @out_summary: (out) (optional): return location for raw summary data, or - * %NULL - * @out_signatures: (out) (optional): return location for raw summary - * signature data, or %NULL + * @out_summary: (out) (optional): return location for raw summary data, or %NULL + * @out_signatures: (out) (optional): return location for raw summary signature + * data, or %NULL * @cancellable: a #GCancellable * @error: a #GError * @@ -6577,26 +6334,27 @@ ostree_repo_pull_from_remotes_finish (OstreeRepo *self, * Since: 2016.6 */ gboolean -ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, - const char *name, - GVariant *options, - GBytes **out_summary, - GBytes **out_signatures, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, const char *name, + GVariant *options, GBytes **out_summary, + GBytes **out_signatures, GCancellable *cancellable, + GError **error) { g_autofree char *metalink_url_string = NULL; - g_autoptr(GBytes) summary = NULL; - g_autoptr(GBytes) signatures = NULL; + g_autoptr (GBytes) summary = NULL; + g_autoptr (GBytes) signatures = NULL; gboolean gpg_verify_summary; - g_autoptr(GPtrArray) signapi_summary_verifiers = NULL; + g_autoptr (GPtrArray) signapi_summary_verifiers = NULL; gboolean summary_is_from_cache = FALSE; - g_autoptr(OstreeFetcher) fetcher = NULL; - g_autoptr(GMainContextPopDefault) mainctx = NULL; + g_autoptr (OstreeFetcher) fetcher = NULL; + g_autoptr (GMainContextPopDefault) mainctx = NULL; const char *url_override = NULL; - g_autoptr(GVariant) extra_headers = NULL; - g_autoptr(GPtrArray) mirrorlist = NULL; + g_autoptr (GVariant) extra_headers = NULL; + g_autoptr (GPtrArray) mirrorlist = NULL; const char *append_user_agent = NULL; + guint32 low_speed_limit = OPT_LOWSPEEDLIMIT_DEFAULT; + guint32 low_speed_time = OPT_LOWSPEEDTIME_DEFAULT; + gboolean retry_all = OPT_RETRYALL_DEFAULT; + guint32 max_outstanding_fetcher_requests = OPT_OSTREE_MAX_OUTSTANDING_FETCHER_REQUESTS_DEFAULT; guint n_network_retries = DEFAULT_N_NETWORK_RETRIES; gboolean summary_sig_not_modified = FALSE; g_autofree char *summary_sig_if_none_match = NULL; @@ -6612,44 +6370,47 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, g_return_val_if_fail (OSTREE_REPO (self), FALSE); g_return_val_if_fail (name != NULL, FALSE); - if (!ostree_repo_get_remote_option (self, name, "metalink", NULL, - &metalink_url_string, error)) + if (!ostree_repo_get_remote_option (self, name, "metalink", NULL, &metalink_url_string, error)) return FALSE; if (options) { - (void) g_variant_lookup (options, "override-url", "&s", &url_override); - (void) g_variant_lookup (options, "http-headers", "@a(ss)", &extra_headers); - (void) g_variant_lookup (options, "append-user-agent", "&s", &append_user_agent); - (void) g_variant_lookup (options, "n-network-retries", "u", &n_network_retries); + (void)g_variant_lookup (options, "override-url", "&s", &url_override); + (void)g_variant_lookup (options, "http-headers", "@a(ss)", &extra_headers); + (void)g_variant_lookup (options, "append-user-agent", "&s", &append_user_agent); + (void)g_variant_lookup (options, "n-network-retries", "u", &n_network_retries); + (void)g_variant_lookup (options, "low-speed-limit-bytes", "u", &low_speed_limit); + (void)g_variant_lookup (options, "low-speed-time-seconds", "u", &low_speed_time); + (void)g_variant_lookup (options, "retry-all-network-errors", "b", &retry_all); + (void)g_variant_lookup (options, "max-outstanding-fetcher-requests", "b", + &max_outstanding_fetcher_requests); } if (!ostree_repo_remote_get_gpg_verify_summary (self, name, &gpg_verify_summary, error)) return FALSE; - if (!_signapi_init_for_remote (self, name, NULL, - &signapi_summary_verifiers, - error)) + if (!_signapi_init_for_remote (self, name, NULL, &signapi_summary_verifiers, error)) return FALSE; mainctx = _ostree_main_context_new_default (); + (void)mainctx; // Used for autocleanup - fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, extra_headers, append_user_agent, NULL, error); + fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, extra_headers, append_user_agent, + low_speed_limit, low_speed_time, retry_all, + max_outstanding_fetcher_requests, NULL, error); if (fetcher == NULL) return FALSE; if (metalink_url_string) { - g_autoptr(OstreeFetcherURI) uri = _ostree_fetcher_uri_parse (metalink_url_string, error); + g_autoptr (OstreeFetcherURI) uri = _ostree_fetcher_uri_parse (metalink_url_string, error); if (!uri) return FALSE; - mirrorlist = - g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); + mirrorlist = g_ptr_array_new_with_free_func ((GDestroyNotify)_ostree_fetcher_uri_free); g_ptr_array_add (mirrorlist, g_steal_pointer (&uri)); } - else if (!compute_effective_mirrorlist (self, name, url_override, - fetcher, n_network_retries, + else if (!compute_effective_mirrorlist (self, name, url_override, fetcher, n_network_retries, &mirrorlist, cancellable, error)) return FALSE; @@ -6658,22 +6419,16 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, * much benefit since summary.sig is typically 590B in size (vs a 0B HTTP 304 * response). But if a repository has multiple keys, the signature file will * grow and this optimisation may be useful. */ - _ostree_repo_load_cache_summary_properties (self, name, ".sig", - &summary_sig_if_none_match, &summary_sig_if_modified_since); - _ostree_repo_load_cache_summary_properties (self, name, NULL, - &summary_if_none_match, &summary_if_modified_since); - - if (!_ostree_preload_metadata_file (self, - fetcher, - mirrorlist, - "summary.sig", - metalink_url_string ? TRUE : FALSE, - summary_sig_if_none_match, summary_sig_if_modified_since, - n_network_retries, - &signatures, - &summary_sig_not_modified, &summary_sig_etag, &summary_sig_last_modified, - cancellable, - error)) + _ostree_repo_load_cache_summary_properties (self, name, ".sig", &summary_sig_if_none_match, + &summary_sig_if_modified_since); + _ostree_repo_load_cache_summary_properties (self, name, NULL, &summary_if_none_match, + &summary_if_modified_since); + + if (!_ostree_preload_metadata_file (self, fetcher, mirrorlist, "summary.sig", + metalink_url_string ? TRUE : FALSE, summary_sig_if_none_match, + summary_sig_if_modified_since, n_network_retries, &signatures, + &summary_sig_not_modified, &summary_sig_etag, + &summary_sig_last_modified, cancellable, error)) return FALSE; /* The server returned HTTP status 304 Not Modified, so we’re clear to @@ -6683,26 +6438,19 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, { g_clear_pointer (&signatures, g_bytes_unref); g_clear_pointer (&summary, g_bytes_unref); - if (!_ostree_repo_load_cache_summary_file (self, name, ".sig", - &signatures, - cancellable, error)) + if (!_ostree_repo_load_cache_summary_file (self, name, ".sig", &signatures, cancellable, + error)) return FALSE; - if (!summary && - !_ostree_repo_load_cache_summary_file (self, name, NULL, - &summary, - cancellable, error)) + if (!summary + && !_ostree_repo_load_cache_summary_file (self, name, NULL, &summary, cancellable, error)) return FALSE; } if (signatures && !summary) { - if (!_ostree_repo_load_cache_summary_if_same_sig (self, - name, - signatures, - &summary, - cancellable, - error)) + if (!_ostree_repo_load_cache_summary_if_same_sig (self, name, signatures, &summary, + cancellable, error)) return FALSE; } @@ -6710,17 +6458,10 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, summary_is_from_cache = TRUE; else { - if (!_ostree_preload_metadata_file (self, - fetcher, - mirrorlist, - "summary", - metalink_url_string ? TRUE : FALSE, - summary_if_none_match, summary_if_modified_since, - n_network_retries, - &summary, - &summary_not_modified, &summary_etag, &summary_last_modified, - cancellable, - error)) + if (!_ostree_preload_metadata_file ( + self, fetcher, mirrorlist, "summary", metalink_url_string ? TRUE : FALSE, + summary_if_none_match, summary_if_modified_since, n_network_retries, &summary, + &summary_not_modified, &summary_etag, &summary_last_modified, cancellable, error)) return FALSE; /* The server returned HTTP status 304 Not Modified, so we’re clear to @@ -6729,31 +6470,23 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, if (summary_not_modified) { g_clear_pointer (&summary, g_bytes_unref); - if (!_ostree_repo_load_cache_summary_file (self, name, NULL, - &summary, - cancellable, error)) + if (!_ostree_repo_load_cache_summary_file (self, name, NULL, &summary, cancellable, + error)) return FALSE; } } - if (!_ostree_repo_verify_summary (self, name, - gpg_verify_summary, signapi_summary_verifiers, - summary, signatures, - cancellable, error)) - return FALSE; + if (!_ostree_repo_verify_summary (self, name, gpg_verify_summary, signapi_summary_verifiers, + summary, signatures, cancellable, error)) + return FALSE; if (!summary_is_from_cache && summary && signatures) { - g_autoptr(GError) temp_error = NULL; + g_autoptr (GError) temp_error = NULL; - if (!_ostree_repo_cache_summary (self, - name, - summary, - summary_etag, summary_last_modified, - signatures, - summary_sig_etag, summary_sig_last_modified, - cancellable, - &temp_error)) + if (!_ostree_repo_cache_summary (self, name, summary, summary_etag, summary_last_modified, + signatures, summary_sig_etag, summary_sig_last_modified, + cancellable, &temp_error)) { if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) g_debug ("No permissions to save summary cache"); @@ -6777,55 +6510,46 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, #else /* HAVE_LIBCURL_OR_LIBSOUP */ gboolean -ostree_repo_pull_with_options (OstreeRepo *self, - const char *remote_name_or_baseurl, - GVariant *options, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GError **error) +ostree_repo_pull_with_options (OstreeRepo *self, const char *remote_name_or_baseurl, + GVariant *options, OstreeAsyncProgress *progress, + GCancellable *cancellable, GError **error) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); + g_set_error_literal ( + error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); return FALSE; } gboolean -ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, - const char *name, - GVariant *options, - GBytes **out_summary, - GBytes **out_signatures, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, const char *name, + GVariant *options, GBytes **out_summary, + GBytes **out_signatures, GCancellable *cancellable, + GError **error) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); + g_set_error_literal ( + error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); return FALSE; } void -ostree_repo_find_remotes_async (OstreeRepo *self, - const OstreeCollectionRef * const *refs, - GVariant *options, - OstreeRepoFinder **finders, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_find_remotes_async (OstreeRepo *self, const OstreeCollectionRef *const *refs, + GVariant *options, OstreeRepoFinder **finders, + OstreeAsyncProgress *progress, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (OSTREE_IS_REPO (self)); - g_task_report_new_error (self, callback, user_data, ostree_repo_find_remotes_async, - G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); + g_task_report_new_error ( + self, callback, user_data, ostree_repo_find_remotes_async, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); } OstreeRepoFinderResult ** -ostree_repo_find_remotes_finish (OstreeRepo *self, - GAsyncResult *result, - GError **error) +ostree_repo_find_remotes_finish (OstreeRepo *self, GAsyncResult *result, GError **error) { - g_autoptr(GPtrArray) results = NULL; + g_autoptr (GPtrArray) results = NULL; g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); g_return_val_if_fail (g_task_is_valid (result, self), NULL); @@ -6838,31 +6562,28 @@ ostree_repo_find_remotes_finish (OstreeRepo *self, } void -ostree_repo_pull_from_remotes_async (OstreeRepo *self, - const OstreeRepoFinderResult * const *results, - GVariant *options, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_repo_pull_from_remotes_async (OstreeRepo *self, const OstreeRepoFinderResult *const *results, + GVariant *options, OstreeAsyncProgress *progress, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { g_return_if_fail (OSTREE_IS_REPO (self)); - g_task_report_new_error (self, callback, user_data, ostree_repo_find_remotes_async, - G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); + g_task_report_new_error ( + self, callback, user_data, ostree_repo_find_remotes_async, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); } gboolean -ostree_repo_pull_from_remotes_finish (OstreeRepo *self, - GAsyncResult *result, - GError **error) +ostree_repo_pull_from_remotes_finish (OstreeRepo *self, GAsyncResult *result, GError **error) { gboolean success; g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); g_return_val_if_fail (g_task_is_valid (result, self), FALSE); - g_return_val_if_fail (g_async_result_is_tagged (result, ostree_repo_pull_from_remotes_async), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, ostree_repo_pull_from_remotes_async), + FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); success = g_task_propagate_boolean (G_TASK (result), error); diff --git a/src/libostree/ostree-repo-refs.c b/src/libostree/ostree-repo-refs.c index 86bd27c..548a1fc 100644 --- a/src/libostree/ostree-repo-refs.c +++ b/src/libostree/ostree-repo-refs.c @@ -21,22 +21,18 @@ #include "ostree-core-private.h" #include "ostree-repo-private.h" -#include "otutil.h" #include "ot-fs-utils.h" +#include "otutil.h" /* This is polymorphic in @collection_id: if non-%NULL, @refs will be treated as of * type OstreeCollectionRef ↦ checksum. Otherwise, it will be treated as of type * refspec ↦ checksum. */ static gboolean -add_ref_to_set (const char *remote, - const char *collection_id, - int base_fd, - const char *path, - GHashTable *refs, - GCancellable *cancellable, - GError **error) +add_ref_to_set (const char *remote, const char *collection_id, int base_fd, const char *path, + GHashTable *refs, GCancellable *cancellable, GError **error) { - g_return_val_if_fail (remote == NULL || collection_id == NULL, FALSE); + if (remote != NULL && collection_id != NULL) + return glnx_throw (error, "Cannot process both a remote and a collection ID"); gsize len; char *contents = glnx_file_get_contents_utf8_at (base_fd, path, &len, cancellable, error); @@ -47,7 +43,7 @@ add_ref_to_set (const char *remote, if (collection_id == NULL) { - g_autoptr(GString) refname = g_string_new (""); + g_autoptr (GString) refname = g_string_new (""); if (remote) { g_string_append (refname, remote); @@ -65,12 +61,8 @@ add_ref_to_set (const char *remote, } static gboolean -write_checksum_file_at (OstreeRepo *self, - int dfd, - const char *name, - const char *sha256, - GCancellable *cancellable, - GError **error) +write_checksum_file_at (OstreeRepo *self, int dfd, const char *name, const char *sha256, + GCancellable *cancellable, GError **error) { if (!ostree_validate_checksum_string (sha256, error)) return FALSE; @@ -95,18 +87,18 @@ write_checksum_file_at (OstreeRepo *self, { size_t l = strlen (sha256); char *bufnl = alloca (l + 2); - g_autoptr(GError) temp_error = NULL; + g_autoptr (GError) temp_error = NULL; memcpy (bufnl, sha256, l); bufnl[l] = '\n'; - bufnl[l+1] = '\0'; + bufnl[l + 1] = '\0'; - if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8*)bufnl, l + 1, - cancellable, &temp_error)) + if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8 *)bufnl, l + 1, cancellable, + &temp_error)) { if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) { - g_autoptr(GHashTable) refs = NULL; + g_autoptr (GHashTable) refs = NULL; GHashTableIter hashiter; gpointer hashkey, hashvalue; @@ -122,13 +114,14 @@ write_checksum_file_at (OstreeRepo *self, while ((g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))) { if (strcmp (name, (char *)hashkey) != 0) - return glnx_throw (error, "Conflict: %s exists under %s when attempting write", (char*)hashkey, name); + return glnx_throw (error, "Conflict: %s exists under %s when attempting write", + (char *)hashkey, name); } if (!glnx_shutil_rm_rf_at (dfd, name, cancellable, error)) return FALSE; - if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8*)bufnl, l + 1, + if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8 *)bufnl, l + 1, cancellable, error)) return FALSE; } @@ -144,12 +137,11 @@ write_checksum_file_at (OstreeRepo *self, } static gboolean -find_ref_in_remotes (OstreeRepo *self, - const char *rev, - int *out_fd, - GError **error) +find_ref_in_remotes (OstreeRepo *self, const char *rev, int *out_fd, GError **error) { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; glnx_autofd int ret_fd = -1; if (!glnx_dirfd_iterator_init_at (self->repo_dir_fd, "refs/remotes", TRUE, &dfd_iter, error)) @@ -178,44 +170,32 @@ find_ref_in_remotes (OstreeRepo *self, break; } - *out_fd = ret_fd; ret_fd = -1; + *out_fd = ret_fd; + ret_fd = -1; return TRUE; } -static gboolean -resolve_refspec (OstreeRepo *self, - const char *remote, - const char *ref, - gboolean allow_noent, - gboolean fallback_remote, - char **out_rev, - GError **error); +static gboolean resolve_refspec (OstreeRepo *self, const char *remote, const char *ref, + gboolean allow_noent, gboolean fallback_remote, char **out_rev, + GError **error); static gboolean -resolve_refspec_fallback (OstreeRepo *self, - const char *remote, - const char *ref, - gboolean allow_noent, - gboolean fallback_remote, - char **out_rev, - GCancellable *cancellable, - GError **error) +resolve_refspec_fallback (OstreeRepo *self, const char *remote, const char *ref, + gboolean allow_noent, gboolean fallback_remote, char **out_rev, + GCancellable *cancellable, GError **error) { g_autofree char *ret_rev = NULL; if (self->parent_repo) { - if (!resolve_refspec (self->parent_repo, remote, ref, allow_noent, - fallback_remote, &ret_rev, error)) + if (!resolve_refspec (self->parent_repo, remote, ref, allow_noent, fallback_remote, &ret_rev, + error)) return FALSE; } else if (!allow_noent) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Refspec '%s%s%s' not found", - remote ? remote : "", - remote ? ":" : "", - ref); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Refspec '%s%s%s' not found", + remote ? remote : "", remote ? ":" : "", ref); return FALSE; } @@ -224,15 +204,10 @@ resolve_refspec_fallback (OstreeRepo *self, } static gboolean -resolve_refspec (OstreeRepo *self, - const char *remote, - const char *ref, - gboolean allow_noent, - gboolean fallback_remote, - char **out_rev, - GError **error) +resolve_refspec (OstreeRepo *self, const char *remote, const char *ref, gboolean allow_noent, + gboolean fallback_remote, char **out_rev, GError **error) { - __attribute__((unused)) GCancellable *cancellable = NULL; + __attribute__ ((unused)) GCancellable *cancellable = NULL; g_autofree char *ret_rev = NULL; glnx_autofd int target_fd = -1; @@ -308,8 +283,8 @@ resolve_refspec (OstreeRepo *self, } else { - if (!resolve_refspec_fallback (self, remote, ref, allow_noent, fallback_remote, - &ret_rev, cancellable, error)) + if (!resolve_refspec_fallback (self, remote, ref, allow_noent, fallback_remote, &ret_rev, + cancellable, error)) return FALSE; } @@ -328,10 +303,8 @@ resolve_refspec (OstreeRepo *self, * of a valid checksum it will return that checksum in the parameter @full_checksum */ static gboolean -ostree_repo_resolve_partial_checksum (OstreeRepo *self, - const char *refspec, - char **full_checksum, - GError **error) +ostree_repo_resolve_partial_checksum (OstreeRepo *self, const char *refspec, char **full_checksum, + GError **error) { static const char hexchars[] = "0123456789abcdef"; g_autofree char *ret_rev = NULL; @@ -347,7 +320,7 @@ ostree_repo_resolve_partial_checksum (OstreeRepo *self, /* this looks through all objects and adds them to the ref_list if: a) they are a commit object AND b) the obj checksum starts with the partual checksum defined by "refspec" */ - g_autoptr(GHashTable) ref_list = NULL; + g_autoptr (GHashTable) ref_list = NULL; if (!ostree_repo_list_commit_objects_starting_with (self, refspec, &ref_list, NULL, error)) return FALSE; @@ -358,7 +331,7 @@ ostree_repo_resolve_partial_checksum (OstreeRepo *self, GVariant *first_commit = NULL; g_hash_table_iter_init (&hashiter, ref_list); if (g_hash_table_iter_next (&hashiter, &key, &value)) - first_commit = (GVariant*) key; + first_commit = (GVariant *)key; OstreeObjectType objtype; const char *checksum = NULL; @@ -381,12 +354,8 @@ ostree_repo_resolve_partial_checksum (OstreeRepo *self, } static gboolean -_ostree_repo_resolve_rev_internal (OstreeRepo *self, - const char *refspec, - gboolean allow_noent, - gboolean fallback_remote, - char **out_rev, - GError **error) +_ostree_repo_resolve_rev_internal (OstreeRepo *self, const char *refspec, gboolean allow_noent, + gboolean fallback_remote, char **out_rev, GError **error) { g_autofree char *ret_rev = NULL; @@ -408,16 +377,16 @@ _ostree_repo_resolve_rev_internal (OstreeRepo *self, { g_autofree char *parent_refspec = NULL; g_autofree char *parent_rev = NULL; - g_autoptr(GVariant) commit = NULL; + g_autoptr (GVariant) commit = NULL; parent_refspec = g_strdup (refspec); - parent_refspec[strlen(parent_refspec) - 1] = '\0'; + parent_refspec[strlen (parent_refspec) - 1] = '\0'; if (!ostree_repo_resolve_rev (self, parent_refspec, allow_noent, &parent_rev, error)) return FALSE; - if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, parent_rev, - &commit, error)) + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, parent_rev, &commit, + error)) return FALSE; if (!(ret_rev = ostree_commit_get_parent (commit))) @@ -431,8 +400,7 @@ _ostree_repo_resolve_rev_internal (OstreeRepo *self, if (!ostree_parse_refspec (refspec, &remote, &ref, error)) return FALSE; - if (!resolve_refspec (self, remote, ref, allow_noent, - fallback_remote, &ret_rev, error)) + if (!resolve_refspec (self, remote, ref, allow_noent, fallback_remote, &ret_rev, error)) return FALSE; } } @@ -446,7 +414,8 @@ _ostree_repo_resolve_rev_internal (OstreeRepo *self, * @self: Repo * @refspec: A refspec * @allow_noent: Do not throw an error if refspec does not exist - * @out_rev: (out) (nullable) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist + * @out_rev: (out) (nullable) (transfer full): A checksum,or %NULL if @allow_noent is true and it + * does not exist * @error: Error * * Look up the given refspec, returning the checksum it references in @@ -454,11 +423,8 @@ _ostree_repo_resolve_rev_internal (OstreeRepo *self, * find the given refspec in local. */ gboolean -ostree_repo_resolve_rev (OstreeRepo *self, - const char *refspec, - gboolean allow_noent, - char **out_rev, - GError **error) +ostree_repo_resolve_rev (OstreeRepo *self, const char *refspec, gboolean allow_noent, + char **out_rev, GError **error) { return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, TRUE, out_rev, error); } @@ -469,7 +435,8 @@ ostree_repo_resolve_rev (OstreeRepo *self, * @refspec: A refspec * @allow_noent: Do not throw an error if refspec does not exist * @flags: Options controlling behavior - * @out_rev: (out) (nullable) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist + * @out_rev: (out) (nullable) (transfer full): A checksum,or %NULL if @allow_noent is true and it + * does not exist * @error: Error * * Look up the given refspec, returning the checksum it references in @@ -483,12 +450,8 @@ ostree_repo_resolve_rev (OstreeRepo *self, * Since: 2016.7 */ gboolean -ostree_repo_resolve_rev_ext (OstreeRepo *self, - const char *refspec, - gboolean allow_noent, - OstreeRepoResolveRevExtFlags flags, - char **out_rev, - GError **error) +ostree_repo_resolve_rev_ext (OstreeRepo *self, const char *refspec, gboolean allow_noent, + OstreeRepoResolveRevExtFlags flags, char **out_rev, GError **error) { return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, FALSE, out_rev, error); } @@ -521,13 +484,9 @@ ostree_repo_resolve_rev_ext (OstreeRepo *self, * Since: 2018.6 */ gboolean -ostree_repo_resolve_collection_ref (OstreeRepo *self, - const OstreeCollectionRef *ref, - gboolean allow_noent, - OstreeRepoResolveRevExtFlags flags, - char **out_rev, - GCancellable *cancellable, - GError **error) +ostree_repo_resolve_collection_ref (OstreeRepo *self, const OstreeCollectionRef *ref, + gboolean allow_noent, OstreeRepoResolveRevExtFlags flags, + char **out_rev, GCancellable *cancellable, GError **error) { g_autofree char *ret_contents = NULL; @@ -546,29 +505,29 @@ ostree_repo_resolve_collection_ref (OstreeRepo *self, { const char *repo_collection_id = ostree_repo_get_collection_id (self); /* If the collection ID doesn't match it's a remote ref */ - if (!(flags & OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY) || - repo_collection_id == NULL || - g_strcmp0 (repo_collection_id, ref->collection_id) == 0) + if (!(flags & OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY) || repo_collection_id == NULL + || g_strcmp0 (repo_collection_id, ref->collection_id) == 0) { ret_contents = g_strdup (g_hash_table_lookup (self->txn.collection_refs, ref)); } - } + } g_mutex_unlock (&self->txn_lock); } /* Check for the ref on disk in the repo */ if (ret_contents == NULL) { - g_autoptr(GHashTable) refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) refs = NULL; /* (element-type OstreeCollectionRef utf8) */ OstreeRepoListRefsExtFlags list_refs_flags; if (flags & OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY) - list_refs_flags = OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES | OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS; + list_refs_flags + = OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES | OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS; else list_refs_flags = OSTREE_REPO_LIST_REFS_EXT_NONE; - if (!ostree_repo_list_collection_refs (self, ref->collection_id, &refs, - list_refs_flags, cancellable, error)) + if (!ostree_repo_list_collection_refs (self, ref->collection_id, &refs, list_refs_flags, + cancellable, error)) return FALSE; ret_contents = g_strdup (g_hash_table_lookup (refs, ref)); @@ -577,20 +536,14 @@ ostree_repo_resolve_collection_ref (OstreeRepo *self, /* Check for the ref in the parent repo */ if (ret_contents == NULL && self->parent_repo != NULL) { - if (!ostree_repo_resolve_collection_ref (self->parent_repo, - ref, - TRUE, - flags, - &ret_contents, - cancellable, - error)) + if (!ostree_repo_resolve_collection_ref (self->parent_repo, ref, TRUE, flags, &ret_contents, + cancellable, error)) return FALSE; } if (ret_contents == NULL && !allow_noent) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Collection–ref (%s, %s) not found", + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Collection–ref (%s, %s) not found", ref->collection_id, ref->ref_name); return FALSE; } @@ -601,19 +554,14 @@ ostree_repo_resolve_collection_ref (OstreeRepo *self, } static gboolean -enumerate_refs_recurse (OstreeRepo *repo, - const char *remote, - OstreeRepoListRefsExtFlags flags, - const char *collection_id, - int base_dfd, - GString *base_path, - int child_dfd, - const char *path, - GHashTable *refs, - GCancellable *cancellable, - GError **error) +enumerate_refs_recurse (OstreeRepo *repo, const char *remote, OstreeRepoListRefsExtFlags flags, + const char *collection_id, int base_dfd, GString *base_path, int child_dfd, + const char *path, GHashTable *refs, GCancellable *cancellable, + GError **error) { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; const gboolean aliases_only = (flags & OSTREE_REPO_LIST_REFS_EXT_ALIASES) > 0; if (!glnx_dirfd_iterator_init_at (child_dfd, path, FALSE, &dfd_iter, error)) @@ -644,16 +592,15 @@ enumerate_refs_recurse (OstreeRepo *repo, g_string_append_c (base_path, '/'); if (!enumerate_refs_recurse (repo, remote, flags, collection_id, base_dfd, base_path, - dfd_iter.fd, dent->d_name, - refs, cancellable, error)) + dfd_iter.fd, dent->d_name, refs, cancellable, error)) return FALSE; } else { if (aliases_only && dent->d_type == DT_LNK) { - g_autofree char *target = glnx_readlinkat_malloc (base_dfd, base_path->str, - cancellable, error); + g_autofree char *target + = glnx_readlinkat_malloc (base_dfd, base_path->str, cancellable, error); const char *resolved_target = target; if (!target) return FALSE; @@ -676,20 +623,18 @@ enumerate_refs_recurse (OstreeRepo *repo, } static gboolean -_ostree_repo_list_refs_internal (OstreeRepo *self, - gboolean cut_prefix, - OstreeRepoListRefsExtFlags flags, - const char *refspec_prefix, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error) +_ostree_repo_list_refs_internal (OstreeRepo *self, gboolean cut_prefix, + OstreeRepoListRefsExtFlags flags, const char *refspec_prefix, + GHashTable **out_all_refs, GCancellable *cancellable, + GError **error) { GLNX_AUTO_PREFIX_ERROR ("Listing refs", error); g_autofree char *remote = NULL; g_autofree char *ref_prefix = NULL; - g_autoptr(GHashTable) ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + g_autoptr (GHashTable) ret_all_refs + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); if (refspec_prefix) { struct stat stbuf; @@ -697,8 +642,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, const char *path; /* special-case ":" and ":.", which ostree_parse_refspec won't like */ - if (g_str_has_suffix (refspec_prefix, ":") || - g_str_has_suffix (refspec_prefix, ":.")) + if (g_str_has_suffix (refspec_prefix, ":") || g_str_has_suffix (refspec_prefix, ":.")) { const char *colon = strrchr (refspec_prefix, ':'); g_autofree char *r = g_strndup (refspec_prefix, colon - refspec_prefix); @@ -733,16 +677,17 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, if (S_ISDIR (stbuf.st_mode)) { glnx_autofd int base_fd = -1; - g_autoptr(GString) base_path = g_string_new (""); + g_autoptr (GString) base_path = g_string_new (""); if (!cut_prefix) g_string_printf (base_path, "%s/", ref_prefix); - if (!glnx_opendirat (self->repo_dir_fd, cut_prefix ? path : prefix_path, TRUE, &base_fd, error)) + if (!glnx_opendirat (self->repo_dir_fd, cut_prefix ? path : prefix_path, TRUE, + &base_fd, error)) return FALSE; - if (!enumerate_refs_recurse (self, remote, flags, NULL, base_fd, base_path, - base_fd, cut_prefix ? "." : ref_prefix, - ret_all_refs, cancellable, error)) + if (!enumerate_refs_recurse (self, remote, flags, NULL, base_fd, base_path, base_fd, + cut_prefix ? "." : ref_prefix, ret_all_refs, cancellable, + error)) return FALSE; } else @@ -752,31 +697,33 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, if (!glnx_opendirat (self->repo_dir_fd, prefix_path, TRUE, &prefix_dfd, error)) return FALSE; - if (!add_ref_to_set (remote, NULL, prefix_dfd, ref_prefix, ret_all_refs, - cancellable, error)) + if (!add_ref_to_set (remote, NULL, prefix_dfd, ref_prefix, ret_all_refs, cancellable, + error)) return FALSE; } } } else { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - g_autoptr(GString) base_path = g_string_new (""); + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + g_autoptr (GString) base_path = g_string_new (""); glnx_autofd int refs_heads_dfd = -1; if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error)) return FALSE; if (!enumerate_refs_recurse (self, NULL, flags, NULL, refs_heads_dfd, base_path, - refs_heads_dfd, ".", - ret_all_refs, cancellable, error)) + refs_heads_dfd, ".", ret_all_refs, cancellable, error)) return FALSE; if (!(flags & OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES)) { g_string_truncate (base_path, 0); - if (!glnx_dirfd_iterator_init_at (self->repo_dir_fd, "refs/remotes", TRUE, &dfd_iter, error)) + if (!glnx_dirfd_iterator_init_at (self->repo_dir_fd, "refs/remotes", TRUE, &dfd_iter, + error)) return FALSE; while (TRUE) @@ -784,7 +731,8 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, struct dirent *dent; glnx_autofd int remote_dfd = -1; - if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, + error)) return FALSE; if (!dent) break; @@ -796,9 +744,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, return FALSE; if (!enumerate_refs_recurse (self, dent->d_name, flags, NULL, remote_dfd, base_path, - remote_dfd, ".", - ret_all_refs, - cancellable, error)) + remote_dfd, ".", ret_all_refs, cancellable, error)) return FALSE; } } @@ -826,16 +772,11 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, * removed as a prefix from the hash table keys. */ gboolean -ostree_repo_list_refs (OstreeRepo *self, - const char *refspec_prefix, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error) +ostree_repo_list_refs (OstreeRepo *self, const char *refspec_prefix, GHashTable **out_all_refs, + GCancellable *cancellable, GError **error) { - return _ostree_repo_list_refs_internal (self, TRUE, - OSTREE_REPO_LIST_REFS_EXT_NONE, - refspec_prefix, out_all_refs, - cancellable, error); + return _ostree_repo_list_refs_internal (self, TRUE, OSTREE_REPO_LIST_REFS_EXT_NONE, + refspec_prefix, out_all_refs, cancellable, error); } /** @@ -859,15 +800,11 @@ ostree_repo_list_refs (OstreeRepo *self, * Since: 2016.4 */ gboolean -ostree_repo_list_refs_ext (OstreeRepo *self, - const char *refspec_prefix, - GHashTable **out_all_refs, - OstreeRepoListRefsExtFlags flags, - GCancellable *cancellable, - GError **error) +ostree_repo_list_refs_ext (OstreeRepo *self, const char *refspec_prefix, GHashTable **out_all_refs, + OstreeRepoListRefsExtFlags flags, GCancellable *cancellable, + GError **error) { - return _ostree_repo_list_refs_internal (self, FALSE, flags, - refspec_prefix, out_all_refs, + return _ostree_repo_list_refs_internal (self, FALSE, flags, refspec_prefix, out_all_refs, cancellable, error); } @@ -882,18 +819,14 @@ ostree_repo_list_refs_ext (OstreeRepo *self, * */ gboolean -ostree_repo_remote_list_refs (OstreeRepo *self, - const char *remote_name, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_list_refs (OstreeRepo *self, const char *remote_name, GHashTable **out_all_refs, + GCancellable *cancellable, GError **error) { - g_autoptr(GBytes) summary_bytes = NULL; - g_autoptr(GHashTable) ret_all_refs = NULL; + g_autoptr (GBytes) summary_bytes = NULL; + g_autoptr (GHashTable) ret_all_refs = NULL; - if (!ostree_repo_remote_fetch_summary (self, remote_name, - &summary_bytes, NULL, - cancellable, error)) + if (!ostree_repo_remote_fetch_summary (self, remote_name, &summary_bytes, NULL, cancellable, + error)) return FALSE; if (summary_bytes == NULL) @@ -902,14 +835,13 @@ ostree_repo_remote_list_refs (OstreeRepo *self, } else { - g_autoptr(GVariant) summary = NULL; - g_autoptr(GVariant) ref_map = NULL; + g_autoptr (GVariant) summary = NULL; + g_autoptr (GVariant) ref_map = NULL; GVariantIter iter; GVariant *child; ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, - summary_bytes, FALSE); + summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE); ref_map = g_variant_get_child_value (summary, 0); @@ -917,8 +849,8 @@ ostree_repo_remote_list_refs (OstreeRepo *self, while ((child = g_variant_iter_next_value (&iter)) != NULL) { const char *ref_name = NULL; - g_autoptr(GVariant) csum_v = NULL; - char tmp_checksum[OSTREE_SHA256_STRING_LEN+1]; + g_autoptr (GVariant) csum_v = NULL; + char tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; g_variant_get_child (child, 0, "&s", &ref_name); @@ -932,9 +864,7 @@ ostree_repo_remote_list_refs (OstreeRepo *self, ostree_checksum_inplace_from_bytes (csum_bytes, tmp_checksum); - g_hash_table_insert (ret_all_refs, - g_strdup (ref_name), - g_strdup (tmp_checksum)); + g_hash_table_insert (ret_all_refs, g_strdup (ref_name), g_strdup (tmp_checksum)); } g_variant_unref (child); @@ -946,19 +876,17 @@ ostree_repo_remote_list_refs (OstreeRepo *self, } static gboolean -remote_list_collection_refs_process_refs (OstreeRepo *self, - const gchar *remote_name, - const gchar *summary_collection_id, - GVariant *summary_refs, - GHashTable *ret_all_refs, - GError **error) +remote_list_collection_refs_process_refs (OstreeRepo *self, const gchar *remote_name, + const gchar *summary_collection_id, + GVariant *summary_refs, GHashTable *ret_all_refs, + GError **error) { gsize j, n; for (j = 0, n = g_variant_n_children (summary_refs); j < n; j++) { const guchar *csum_bytes; - g_autoptr(GVariant) ref_v = NULL, csum_v = NULL; + g_autoptr (GVariant) ref_v = NULL, csum_v = NULL; gchar tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; const gchar *ref_name; @@ -1005,58 +933,53 @@ remote_list_collection_refs_process_refs (OstreeRepo *self, * Since: 2018.6 */ gboolean -ostree_repo_remote_list_collection_refs (OstreeRepo *self, - const char *remote_name, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_list_collection_refs (OstreeRepo *self, const char *remote_name, + GHashTable **out_all_refs, GCancellable *cancellable, + GError **error) { - g_autoptr(GBytes) summary_bytes = NULL; - g_autoptr(GHashTable) ret_all_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ - g_autoptr(GVariant) summary_v = NULL; - g_autoptr(GVariant) additional_metadata_v = NULL; - g_autoptr(GVariant) summary_refs = NULL; + g_autoptr (GBytes) summary_bytes = NULL; + g_autoptr (GHashTable) ret_all_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GVariant) summary_v = NULL; + g_autoptr (GVariant) additional_metadata_v = NULL; + g_autoptr (GVariant) summary_refs = NULL; const char *summary_collection_id; - g_autoptr(GVariantIter) summary_collection_map = NULL; + g_autoptr (GVariantIter) summary_collection_map = NULL; - if (!ostree_repo_remote_fetch_summary (self, remote_name, - &summary_bytes, NULL, - cancellable, error)) + if (!ostree_repo_remote_fetch_summary (self, remote_name, &summary_bytes, NULL, cancellable, + error)) return FALSE; if (summary_bytes == NULL) return glnx_throw (error, "Remote refs not available; server has no summary file"); - ret_all_refs = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - (GDestroyNotify) ostree_collection_ref_free, - g_free); + ret_all_refs = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, g_free); - summary_v = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, - summary_bytes, FALSE); + summary_v = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE); additional_metadata_v = g_variant_get_child_value (summary_v, 1); /* List the refs in the main map. */ - if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_ID, "&s", &summary_collection_id)) + if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_ID, "&s", + &summary_collection_id)) summary_collection_id = NULL; summary_refs = g_variant_get_child_value (summary_v, 0); - if (!remote_list_collection_refs_process_refs (self, remote_name, - summary_collection_id, summary_refs, - ret_all_refs, error)) + if (!remote_list_collection_refs_process_refs (self, remote_name, summary_collection_id, + summary_refs, ret_all_refs, error)) return FALSE; /* List the refs in the collection map. */ - if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_MAP, "a{sa(s(taya{sv}))}", &summary_collection_map)) + if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_MAP, "a{sa(s(taya{sv}))}", + &summary_collection_map)) summary_collection_map = NULL; - while (summary_collection_map != NULL && - g_variant_iter_loop (summary_collection_map, "{&s@a(s(taya{sv}))}", &summary_collection_id, &summary_refs)) + while (summary_collection_map != NULL + && g_variant_iter_loop (summary_collection_map, "{&s@a(s(taya{sv}))}", + &summary_collection_id, &summary_refs)) { - if (!remote_list_collection_refs_process_refs (self, remote_name, - summary_collection_id, summary_refs, - ret_all_refs, error)) + if (!remote_list_collection_refs_process_refs (self, remote_name, summary_collection_id, + summary_refs, ret_all_refs, error)) return FALSE; } @@ -1065,13 +988,12 @@ ostree_repo_remote_list_collection_refs (OstreeRepo *self, } static char * -relative_symlink_to (const char *relpath, - const char *target) +relative_symlink_to (const char *relpath, const char *target) { g_assert (*relpath); g_assert (*target && *target != '/'); - g_autoptr(GString) buf = g_string_new (""); + g_autoptr (GString) buf = g_string_new (""); while (TRUE) { @@ -1089,13 +1011,9 @@ relative_symlink_to (const char *relpath, /* May specify @rev or @alias */ gboolean -_ostree_repo_write_ref (OstreeRepo *self, - const char *remote, - const OstreeCollectionRef *ref, - const char *rev, - const char *alias, - GCancellable *cancellable, - GError **error) +_ostree_repo_write_ref (OstreeRepo *self, const char *remote, const OstreeCollectionRef *ref, + const char *rev, const char *alias, GCancellable *cancellable, + GError **error) { glnx_autofd int dfd = -1; @@ -1109,11 +1027,11 @@ _ostree_repo_write_ref (OstreeRepo *self, if (!ostree_validate_rev (ref->ref_name, error)) return FALSE; - if (remote == NULL && - (ref->collection_id == NULL || g_strcmp0 (ref->collection_id, ostree_repo_get_collection_id (self)) == 0)) + if (remote == NULL + && (ref->collection_id == NULL + || g_strcmp0 (ref->collection_id, ostree_repo_get_collection_id (self)) == 0)) { - if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, - &dfd, error)) + if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &dfd, error)) return FALSE; } else if (remote == NULL && ref->collection_id != NULL) @@ -1121,14 +1039,15 @@ _ostree_repo_write_ref (OstreeRepo *self, glnx_autofd int refs_mirrors_dfd = -1; /* refs/mirrors might not exist in older repositories, so create it. */ - if (!glnx_shutil_mkdir_p_at_open (self->repo_dir_fd, "refs/mirrors", 0777, - &refs_mirrors_dfd, cancellable, error)) + if (!glnx_shutil_mkdir_p_at_open (self->repo_dir_fd, "refs/mirrors", 0777, &refs_mirrors_dfd, + cancellable, error)) return FALSE; if (rev != NULL) { /* Ensure we have a dir for the collection */ - if (!glnx_shutil_mkdir_p_at (refs_mirrors_dfd, ref->collection_id, 0777, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (refs_mirrors_dfd, ref->collection_id, 0777, cancellable, + error)) return FALSE; } @@ -1140,8 +1059,7 @@ _ostree_repo_write_ref (OstreeRepo *self, { glnx_autofd int refs_remotes_dfd = -1; - if (!glnx_opendirat (self->repo_dir_fd, "refs/remotes", TRUE, - &refs_remotes_dfd, error)) + if (!glnx_opendirat (self->repo_dir_fd, "refs/remotes", TRUE, &refs_remotes_dfd, error)) return FALSE; if (rev != NULL) @@ -1184,8 +1102,8 @@ _ostree_repo_write_ref (OstreeRepo *self, g_autofree char *reltarget = relative_symlink_to (ref->ref_name, alias); g_autofree char *tmplink = NULL; - if (!_ostree_make_temporary_symlink_at (self->tmp_dir_fd, reltarget, - &tmplink, cancellable, error)) + if (!_ostree_make_temporary_symlink_at (self->tmp_dir_fd, reltarget, &tmplink, cancellable, + error)) return FALSE; if (!glnx_renameat (self->tmp_dir_fd, tmplink, dfd, ref->ref_name, error)) return FALSE; @@ -1203,12 +1121,10 @@ _ostree_repo_write_ref (OstreeRepo *self, } gboolean -_ostree_repo_update_refs (OstreeRepo *self, - GHashTable *refs, /* (element-type utf8 utf8) */ - GCancellable *cancellable, - GError **error) +_ostree_repo_update_refs (OstreeRepo *self, GHashTable *refs, /* (element-type utf8 utf8) */ + GCancellable *cancellable, GError **error) { - GLNX_HASH_TABLE_FOREACH_KV (refs, const char*, refspec, const char*, rev) + GLNX_HASH_TABLE_FOREACH_KV (refs, const char *, refspec, const char *, rev) { g_autofree char *remote = NULL; g_autofree char *ref_name = NULL; @@ -1216,8 +1132,7 @@ _ostree_repo_update_refs (OstreeRepo *self, return FALSE; const OstreeCollectionRef ref = { NULL, ref_name }; - if (!_ostree_repo_write_ref (self, remote, &ref, rev, NULL, - cancellable, error)) + if (!_ostree_repo_write_ref (self, remote, &ref, rev, NULL, cancellable, error)) return FALSE; } @@ -1225,10 +1140,9 @@ _ostree_repo_update_refs (OstreeRepo *self, } gboolean -_ostree_repo_update_collection_refs (OstreeRepo *self, - GHashTable *refs, /* (element-type OstreeCollectionRef utf8) */ - GCancellable *cancellable, - GError **error) +_ostree_repo_update_collection_refs (OstreeRepo *self, + GHashTable *refs, /* (element-type OstreeCollectionRef utf8) */ + GCancellable *cancellable, GError **error) { GHashTableIter hash_iter; gpointer key, value; @@ -1239,8 +1153,7 @@ _ostree_repo_update_collection_refs (OstreeRepo *self, const OstreeCollectionRef *ref = key; const char *rev = value; - if (!_ostree_repo_write_ref (self, NULL, ref, rev, NULL, - cancellable, error)) + if (!_ostree_repo_write_ref (self, NULL, ref, rev, NULL, cancellable, error)) return FALSE; } @@ -1276,12 +1189,9 @@ _ostree_repo_update_collection_refs (OstreeRepo *self, * Since: 2018.6 */ gboolean -ostree_repo_list_collection_refs (OstreeRepo *self, - const char *match_collection_id, - GHashTable **out_all_refs, - OstreeRepoListRefsExtFlags flags, - GCancellable *cancellable, - GError **error) +ostree_repo_list_collection_refs (OstreeRepo *self, const char *match_collection_id, + GHashTable **out_all_refs, OstreeRepoListRefsExtFlags flags, + GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Listing refs", error); @@ -1292,36 +1202,32 @@ ostree_repo_list_collection_refs (OstreeRepo *self, if (match_collection_id != NULL && !ostree_validate_collection_id (match_collection_id, error)) return FALSE; - g_autoptr(GPtrArray) refs_dirs = g_ptr_array_new (); + g_autoptr (GPtrArray) refs_dirs = g_ptr_array_new (); if (!(flags & OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS)) g_ptr_array_add (refs_dirs, "refs/mirrors"); if (!(flags & OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES)) g_ptr_array_add (refs_dirs, "refs/remotes"); g_ptr_array_add (refs_dirs, NULL); - g_autoptr(GHashTable) ret_all_refs = NULL; + g_autoptr (GHashTable) ret_all_refs = NULL; - ret_all_refs = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, - (GDestroyNotify) ostree_collection_ref_free, - g_free); + ret_all_refs = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, + (GDestroyNotify)ostree_collection_ref_free, g_free); - g_autoptr(GString) base_path = g_string_new (""); + g_autoptr (GString) base_path = g_string_new (""); const gchar *main_collection_id = ostree_repo_get_collection_id (self); - if (main_collection_id != NULL && - (match_collection_id == NULL || g_strcmp0 (match_collection_id, main_collection_id) == 0)) + if (main_collection_id != NULL + && (match_collection_id == NULL || g_strcmp0 (match_collection_id, main_collection_id) == 0)) { glnx_autofd int refs_heads_dfd = -1; if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error)) return FALSE; - if (!enumerate_refs_recurse (self, NULL, flags, - main_collection_id, refs_heads_dfd, base_path, - refs_heads_dfd, ".", - ret_all_refs, cancellable, error)) + if (!enumerate_refs_recurse (self, NULL, flags, main_collection_id, refs_heads_dfd, base_path, + refs_heads_dfd, ".", ret_all_refs, cancellable, error)) return FALSE; } @@ -1331,10 +1237,12 @@ ostree_repo_list_collection_refs (OstreeRepo *self, { const char *refs_dir = *iter; gboolean refs_dir_exists = FALSE; - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; - if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, refs_dir, - &dfd_iter, &refs_dir_exists, error)) + if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, refs_dir, &dfd_iter, &refs_dir_exists, + error)) return FALSE; while (refs_dir_exists) @@ -1361,18 +1269,20 @@ ostree_repo_list_collection_refs (OstreeRepo *self, } else /* refs_dir = "refs/remotes" */ { - g_autoptr(GError) local_error = NULL; - if (!ostree_repo_get_remote_option (self, dent->d_name, "collection-id", - NULL, &remote_collection_id, &local_error) || - !ostree_validate_collection_id (remote_collection_id, &local_error)) + g_autoptr (GError) local_error = NULL; + if (!ostree_repo_get_remote_option (self, dent->d_name, "collection-id", NULL, + &remote_collection_id, &local_error) + || !ostree_validate_collection_id (remote_collection_id, &local_error)) { - g_debug ("Ignoring remote ‘%s’ due to no valid collection ID being configured for it: %s", + g_debug ("Ignoring remote ‘%s’ due to no valid collection ID being configured " + "for it: %s", dent->d_name, local_error->message); g_clear_error (&local_error); continue; } - if (match_collection_id != NULL && g_strcmp0 (match_collection_id, remote_collection_id) != 0) + if (match_collection_id != NULL + && g_strcmp0 (match_collection_id, remote_collection_id) != 0) continue; else current_collection_id = remote_collection_id; @@ -1381,11 +1291,8 @@ ostree_repo_list_collection_refs (OstreeRepo *self, if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &subdir_fd, error)) return FALSE; - if (!enumerate_refs_recurse (self, NULL, flags, - current_collection_id, subdir_fd, base_path, - subdir_fd, ".", - ret_all_refs, - cancellable, error)) + if (!enumerate_refs_recurse (self, NULL, flags, current_collection_id, subdir_fd, + base_path, subdir_fd, ".", ret_all_refs, cancellable, error)) return FALSE; } } diff --git a/src/libostree/ostree-repo-static-delta-compilation-analysis.c b/src/libostree/ostree-repo-static-delta-compilation-analysis.c index f92951e..a98181c 100644 --- a/src/libostree/ostree-repo-static-delta-compilation-analysis.c +++ b/src/libostree/ostree-repo-static-delta-compilation-analysis.c @@ -19,17 +19,17 @@ #include "config.h" -#include #include +#include #include "ostree-core-private.h" -#include "ostree-repo-private.h" +#include "ostree-diff.h" #include "ostree-lzma-compressor.h" +#include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" -#include "ostree-diff.h" #include "ostree-rollsum.h" -#include "otutil.h" #include "ostree-varint.h" +#include "otutil.h" void _ostree_delta_content_sizenames_free (gpointer v) @@ -41,20 +41,17 @@ _ostree_delta_content_sizenames_free (gpointer v) } static gboolean -build_content_sizenames_recurse (OstreeRepo *repo, - OstreeRepoCommitTraverseIter *iter, - GHashTable *sizenames_map, - GHashTable *include_only_objects, - GCancellable *cancellable, - GError **error) +build_content_sizenames_recurse (OstreeRepo *repo, OstreeRepoCommitTraverseIter *iter, + GHashTable *sizenames_map, GHashTable *include_only_objects, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; while (TRUE) { - OstreeRepoCommitIterResult iterres = - ostree_repo_commit_traverse_iter_next (iter, cancellable, error); - + OstreeRepoCommitIterResult iterres + = ostree_repo_commit_traverse_iter_next (iter, cancellable, error); + if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_ERROR) goto out; else if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_END) @@ -64,7 +61,7 @@ build_content_sizenames_recurse (OstreeRepo *repo, char *name; char *checksum; OstreeDeltaContentSizeNames *csizenames; - + ostree_repo_commit_traverse_iter_get_file (iter, &name, &checksum); if (include_only_objects && !g_hash_table_contains (include_only_objects, checksum)) @@ -73,11 +70,9 @@ build_content_sizenames_recurse (OstreeRepo *repo, csizenames = g_hash_table_lookup (sizenames_map, checksum); if (!csizenames) { - g_autoptr(GFileInfo) finfo = NULL; + g_autoptr (GFileInfo) finfo = NULL; - if (!ostree_repo_load_file (repo, checksum, - NULL, &finfo, NULL, - cancellable, error)) + if (!ostree_repo_load_file (repo, checksum, NULL, &finfo, NULL, cancellable, error)) goto out; if (g_file_info_get_file_type (finfo) != G_FILE_TYPE_REGULAR) @@ -98,24 +93,22 @@ build_content_sizenames_recurse (OstreeRepo *repo, char *name; char *content_checksum; char *meta_checksum; - g_autoptr(GVariant) dirtree = NULL; - ostree_cleanup_repo_commit_traverse_iter - OstreeRepoCommitTraverseIter subiter = { 0, }; + g_autoptr (GVariant) dirtree = NULL; + ostree_cleanup_repo_commit_traverse_iter OstreeRepoCommitTraverseIter subiter = { + 0, + }; ostree_repo_commit_traverse_iter_get_dir (iter, &name, &content_checksum, &meta_checksum); - - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, - content_checksum, &dirtree, - error)) + + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, content_checksum, + &dirtree, error)) goto out; - if (!ostree_repo_commit_traverse_iter_init_dirtree (&subiter, repo, dirtree, - OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, - error)) + if (!ostree_repo_commit_traverse_iter_init_dirtree ( + &subiter, repo, dirtree, OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, error)) goto out; - if (!build_content_sizenames_recurse (repo, &subiter, - sizenames_map, include_only_objects, + if (!build_content_sizenames_recurse (repo, &subiter, sizenames_map, include_only_objects, cancellable, error)) goto out; } @@ -123,16 +116,15 @@ build_content_sizenames_recurse (OstreeRepo *repo, g_assert_not_reached (); } ret = TRUE; - out: +out: return ret; } static int -compare_sizenames (const void *a, - const void *b) +compare_sizenames (const void *a, const void *b) { - OstreeDeltaContentSizeNames *sn_a = *(OstreeDeltaContentSizeNames**)(void*)a; - OstreeDeltaContentSizeNames *sn_b = *(OstreeDeltaContentSizeNames**)(void*)b; + OstreeDeltaContentSizeNames *sn_a = *(OstreeDeltaContentSizeNames **)(void *)a; + OstreeDeltaContentSizeNames *sn_b = *(OstreeDeltaContentSizeNames **)(void *)b; return sn_a->size - sn_b->size; } @@ -142,31 +134,29 @@ compare_sizenames (const void *a, * for regular file content. */ static gboolean -build_content_sizenames_filtered (OstreeRepo *repo, - GVariant *commit, - GHashTable *include_only_objects, - GPtrArray **out_sizenames, - GCancellable *cancellable, - GError **error) +build_content_sizenames_filtered (OstreeRepo *repo, GVariant *commit, + GHashTable *include_only_objects, GPtrArray **out_sizenames, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GPtrArray) ret_sizenames = - g_ptr_array_new_with_free_func (_ostree_delta_content_sizenames_free); - g_autoptr(GHashTable) sizenames_map = - g_hash_table_new_full (g_str_hash, g_str_equal, NULL, _ostree_delta_content_sizenames_free); - ostree_cleanup_repo_commit_traverse_iter - OstreeRepoCommitTraverseIter iter = { 0, }; + g_autoptr (GPtrArray) ret_sizenames + = g_ptr_array_new_with_free_func (_ostree_delta_content_sizenames_free); + g_autoptr (GHashTable) sizenames_map + = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, _ostree_delta_content_sizenames_free); + ostree_cleanup_repo_commit_traverse_iter OstreeRepoCommitTraverseIter iter = { + 0, + }; if (!ostree_repo_commit_traverse_iter_init_commit (&iter, repo, commit, - OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, - error)) + OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, error)) goto out; if (!build_content_sizenames_recurse (repo, &iter, sizenames_map, include_only_objects, cancellable, error)) goto out; - { GHashTableIter hashiter; + { + GHashTableIter hashiter; gpointer hkey, hvalue; g_hash_table_iter_init (&hashiter, sizenames_map); @@ -182,14 +172,12 @@ build_content_sizenames_filtered (OstreeRepo *repo, ret = TRUE; if (out_sizenames) *out_sizenames = g_steal_pointer (&ret_sizenames); - out: +out: return ret; } static gboolean -string_array_nonempty_intersection (GPtrArray *a, - GPtrArray *b, - gboolean fuzzy) +string_array_nonempty_intersection (GPtrArray *a, GPtrArray *b, gboolean fuzzy) { guint i; for (i = 0; i < a->len; i++) @@ -238,7 +226,7 @@ sizename_is_delta_candidate (OstreeDeltaContentSizeNames *sizename) const char *dot = strrchr (name, '.'); if (!dot) continue; - const char *extension = dot+1; + const char *extension = dot + 1; /* Don't add .gz here, see above */ if (g_str_equal (extension, "xz") || g_str_equal (extension, "bz2")) return FALSE; @@ -262,31 +250,25 @@ sizename_is_delta_candidate (OstreeDeltaContentSizeNames *sizename) * a cost for each one, then pick the best. */ gboolean -_ostree_delta_compute_similar_objects (OstreeRepo *repo, - GVariant *from_commit, - GVariant *to_commit, - GHashTable *new_reachable_regfile_content, - guint similarity_percent_threshold, - GHashTable **out_modified_regfile_content, - GCancellable *cancellable, - GError **error) +_ostree_delta_compute_similar_objects (OstreeRepo *repo, GVariant *from_commit, GVariant *to_commit, + GHashTable *new_reachable_regfile_content, + guint similarity_percent_threshold, + GHashTable **out_modified_regfile_content, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GHashTable) ret_modified_regfile_content = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - g_autoptr(GPtrArray) from_sizes = NULL; - g_autoptr(GPtrArray) to_sizes = NULL; + g_autoptr (GHashTable) ret_modified_regfile_content + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + g_autoptr (GPtrArray) from_sizes = NULL; + g_autoptr (GPtrArray) to_sizes = NULL; guint i, j; guint lower; guint upper; - if (!build_content_sizenames_filtered (repo, from_commit, NULL, - &from_sizes, - cancellable, error)) + if (!build_content_sizenames_filtered (repo, from_commit, NULL, &from_sizes, cancellable, error)) goto out; - if (!build_content_sizenames_filtered (repo, to_commit, new_reachable_regfile_content, - &to_sizes, + if (!build_content_sizenames_filtered (repo, to_commit, new_reachable_regfile_content, &to_sizes, cancellable, error)) goto out; @@ -303,10 +285,10 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo, int fuzzy; gboolean found = FALSE; OstreeDeltaContentSizeNames *to_sizenames = to_sizes->pdata[i]; - const guint64 min_threshold = to_sizenames->size * - (1.0-similarity_percent_threshold/100.0); - const guint64 max_threshold = to_sizenames->size * - (1.0+similarity_percent_threshold/100.0); + const guint64 min_threshold + = to_sizenames->size * (1.0 - similarity_percent_threshold / 100.0); + const guint64 max_threshold + = to_sizenames->size * (1.0 + similarity_percent_threshold / 100.0); if (!sizename_is_delta_candidate (to_sizenames)) continue; @@ -329,15 +311,13 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo, break; if (!string_array_nonempty_intersection (from_sizenames->basenames, - to_sizenames->basenames, - fuzzy == 1)) + to_sizenames->basenames, fuzzy == 1)) { continue; } /* Only one candidate right now */ - g_hash_table_insert (ret_modified_regfile_content, - g_strdup (to_sizenames->checksum), + g_hash_table_insert (ret_modified_regfile_content, g_strdup (to_sizenames->checksum), g_strdup (from_sizenames->checksum)); found = TRUE; break; @@ -348,6 +328,6 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo, ret = TRUE; if (out_modified_regfile_content) *out_modified_regfile_content = g_steal_pointer (&ret_modified_regfile_content); - out: +out: return ret; } diff --git a/src/libostree/ostree-repo-static-delta-compilation.c b/src/libostree/ostree-repo-static-delta-compilation.c index cf232c1..54e4801 100644 --- a/src/libostree/ostree-repo-static-delta-compilation.c +++ b/src/libostree/ostree-repo-static-delta-compilation.c @@ -19,33 +19,34 @@ #include "config.h" -#include -#include #include -#include +#include +#include +#include "bsdiff/bsdiff.h" +#include "libglnx.h" +#include "ostree-autocleanups.h" #include "ostree-core-private.h" -#include "ostree-repo-private.h" +#include "ostree-diff.h" #include "ostree-lzma-compressor.h" +#include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" -#include "ostree-diff.h" #include "ostree-rollsum.h" -#include "otutil.h" -#include "libglnx.h" -#include "ostree-varint.h" -#include "bsdiff/bsdiff.h" -#include "ostree-autocleanups.h" #include "ostree-sign.h" +#include "ostree-varint.h" +#include "otutil.h" #define CONTENT_SIZE_SIMILARITY_THRESHOLD_PERCENT (30) -typedef enum { +typedef enum +{ DELTAOPT_FLAG_NONE = (1 << 0), DELTAOPT_FLAG_DISABLE_BSDIFF = (1 << 1), DELTAOPT_FLAG_VERBOSE = (1 << 2) } DeltaOpts; -typedef struct { +typedef struct +{ guint64 compressed_size; guint64 uncompressed_size; GPtrArray *objects; @@ -59,7 +60,8 @@ typedef struct { GVariant *header; } OstreeStaticDeltaPartBuilder; -typedef struct { +typedef struct +{ GPtrArray *parts; GPtrArray *fallback_objects; guint64 loose_compressed_size; @@ -77,15 +79,13 @@ typedef struct { /* Get an input stream for a GVariant */ static GInputStream * -variant_to_inputstream (GVariant *variant) +variant_to_inputstream (GVariant *variant) { - GMemoryInputStream *ret = (GMemoryInputStream*) - g_memory_input_stream_new_from_data (g_variant_get_data (variant), - g_variant_get_size (variant), - NULL); - g_object_set_data_full ((GObject*)ret, "ot-variant-data", - g_variant_ref (variant), (GDestroyNotify) g_variant_unref); - return (GInputStream*)ret; + GMemoryInputStream *ret = (GMemoryInputStream *)g_memory_input_stream_new_from_data ( + g_variant_get_data (variant), g_variant_get_size (variant), NULL); + g_object_set_data_full ((GObject *)ret, "ot-variant-data", g_variant_ref (variant), + (GDestroyNotify)g_variant_unref); + return (GInputStream *)ret; } static GBytes * @@ -103,7 +103,7 @@ objtype_checksum_array_new (GPtrArray *objects) guint8 objtype_v; ostree_object_name_deserialize (serialized_key, &checksum, &objtype); - objtype_v = (guint8) objtype; + objtype_v = (guint8)objtype; ostree_checksum_inplace_to_bytes (checksum, csum); @@ -135,7 +135,7 @@ ostree_static_delta_part_builder_unref (OstreeStaticDeltaPartBuilder *part_build static guint mode_chunk_hash (const void *vp) { - GVariant *v = (GVariant*)vp; + GVariant *v = (GVariant *)vp; guint uid, gid, mode; g_variant_get (v, "(uuu)", &uid, &gid, &mode); return uid + gid + mode; @@ -144,8 +144,8 @@ mode_chunk_hash (const void *vp) static gboolean mode_chunk_equals (const void *one, const void *two) { - GVariant *v1 = (GVariant*)one; - GVariant *v2 = (GVariant*)two; + GVariant *v1 = (GVariant *)one; + GVariant *v2 = (GVariant *)two; guint uid1, gid1, mode1; guint uid2, gid2, mode2; @@ -170,20 +170,19 @@ bufhash (const void *b, gsize len) static guint xattr_chunk_hash (const void *vp) { - GVariant *v = (GVariant*)vp; + GVariant *v = (GVariant *)vp; gsize n = g_variant_n_children (v); guint i; guint32 h = 5381; for (i = 0; i < n; i++) { - const guint8* name; - const guint8* value_data; - g_autoptr(GVariant) value = NULL; + const guint8 *name; + const guint8 *value_data; + g_autoptr (GVariant) value = NULL; gsize value_len; - g_variant_get_child (v, i, "(^&ay@ay)", - &name, &value); + g_variant_get_child (v, i, "(^&ay@ay)", &name, &value); value_data = g_variant_get_fixed_array (value, &value_len, 1); h += g_str_hash (name); @@ -196,8 +195,8 @@ xattr_chunk_hash (const void *vp) static gboolean xattr_chunk_equals (const void *one, const void *two) { - GVariant *v1 = (GVariant*)one; - GVariant *v2 = (GVariant*)two; + GVariant *v1 = (GVariant *)one; + GVariant *v2 = (GVariant *)two; gsize l1 = g_variant_get_size (v1); gsize l2 = g_variant_get_size (v2); @@ -215,19 +214,19 @@ finish_part (OstreeStaticDeltaBuilder *builder, GError **error) { OstreeStaticDeltaPartBuilder *part_builder = builder->parts->pdata[builder->parts->len - 1]; g_autofree guchar *part_checksum = NULL; - g_autoptr(GBytes) objtype_checksum_array = NULL; - g_autoptr(GBytes) checksum_bytes = NULL; - g_autoptr(GOutputStream) part_temp_outstream = NULL; - g_autoptr(GInputStream) part_in = NULL; - g_autoptr(GInputStream) part_payload_in = NULL; - g_autoptr(GMemoryOutputStream) part_payload_out = NULL; - g_autoptr(GConverterOutputStream) part_payload_compressor = NULL; - g_autoptr(GConverter) compressor = NULL; - g_autoptr(GVariant) delta_part_content = NULL; - g_autoptr(GVariant) delta_part = NULL; - g_autoptr(GVariant) delta_part_header = NULL; - g_auto(GVariantBuilder) mode_builder = OT_VARIANT_BUILDER_INITIALIZER; - g_auto(GVariantBuilder) xattr_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_autoptr (GBytes) objtype_checksum_array = NULL; + g_autoptr (GBytes) checksum_bytes = NULL; + g_autoptr (GOutputStream) part_temp_outstream = NULL; + g_autoptr (GInputStream) part_in = NULL; + g_autoptr (GInputStream) part_payload_in = NULL; + g_autoptr (GMemoryOutputStream) part_payload_out = NULL; + g_autoptr (GConverterOutputStream) part_payload_compressor = NULL; + g_autoptr (GConverter) compressor = NULL; + g_autoptr (GVariant) delta_part_content = NULL; + g_autoptr (GVariant) delta_part = NULL; + g_autoptr (GVariant) delta_part_header = NULL; + g_auto (GVariantBuilder) mode_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantBuilder) xattr_builder = OT_VARIANT_BUILDER_INITIALIZER; guint8 compression_type_char; g_variant_builder_init (&mode_builder, G_VARIANT_TYPE ("a(uuu)")); @@ -241,37 +240,39 @@ finish_part (OstreeStaticDeltaBuilder *builder, GError **error) g_variant_builder_add_value (&xattr_builder, part_builder->xattrs->pdata[j]); { - g_autoptr(GBytes) payload_b = g_string_free_to_bytes (g_steal_pointer (&part_builder->payload)); - g_autoptr(GBytes) operations_b = g_string_free_to_bytes (g_steal_pointer (&part_builder->operations)); + g_autoptr (GBytes) payload_b + = g_string_free_to_bytes (g_steal_pointer (&part_builder->payload)); + g_autoptr (GBytes) operations_b + = g_string_free_to_bytes (g_steal_pointer (&part_builder->operations)); - delta_part_content = g_variant_new ("(a(uuu)aa(ayay)@ay@ay)", - &mode_builder, &xattr_builder, + delta_part_content = g_variant_new ("(a(uuu)aa(ayay)@ay@ay)", &mode_builder, &xattr_builder, ot_gvariant_new_ay_bytes (payload_b), ot_gvariant_new_ay_bytes (operations_b)); g_variant_ref_sink (delta_part_content); } /* Hardcode xz for now */ - compressor = (GConverter*)_ostree_lzma_compressor_new (NULL); + compressor = (GConverter *)_ostree_lzma_compressor_new (NULL); compression_type_char = 'x'; part_payload_in = variant_to_inputstream (delta_part_content); - part_payload_out = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); - part_payload_compressor = (GConverterOutputStream*)g_converter_output_stream_new ((GOutputStream*)part_payload_out, compressor); + part_payload_out = (GMemoryOutputStream *)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + part_payload_compressor = (GConverterOutputStream *)g_converter_output_stream_new ( + (GOutputStream *)part_payload_out, compressor); { - gssize n_bytes_written = g_output_stream_splice ((GOutputStream*)part_payload_compressor, part_payload_in, - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - NULL, error); + gssize n_bytes_written = g_output_stream_splice ( + (GOutputStream *)part_payload_compressor, part_payload_in, + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, NULL, error); if (n_bytes_written < 0) return FALSE; } g_clear_pointer (&delta_part_content, g_variant_unref); - { g_autoptr(GBytes) payload = g_memory_output_stream_steal_as_bytes (part_payload_out); - delta_part = g_variant_ref_sink (g_variant_new ("(y@ay)", - compression_type_char, - ot_gvariant_new_ay_bytes (payload))); + { + g_autoptr (GBytes) payload = g_memory_output_stream_steal_as_bytes (part_payload_out); + delta_part = g_variant_ref_sink ( + g_variant_new ("(y@ay)", compression_type_char, ot_gvariant_new_ay_bytes (payload))); } if (!glnx_open_tmpfile_linkable_at (builder->parts_dfd, ".", O_RDWR | O_CLOEXEC, @@ -281,19 +282,17 @@ finish_part (OstreeStaticDeltaBuilder *builder, GError **error) part_temp_outstream = g_unix_output_stream_new (part_builder->part_tmpf.fd, FALSE); part_in = variant_to_inputstream (delta_part); - if (!ot_gio_splice_get_checksum (part_temp_outstream, part_in, - &part_checksum, - NULL, error)) + if (!ot_gio_splice_get_checksum (part_temp_outstream, part_in, &part_checksum, NULL, error)) return FALSE; checksum_bytes = g_bytes_new (part_checksum, OSTREE_SHA256_DIGEST_LEN); objtype_checksum_array = objtype_checksum_array_new (part_builder->objects); - delta_part_header = g_variant_new ("(u@aytt@ay)", - maybe_swap_endian_u32 (builder->swap_endian, OSTREE_DELTAPART_VERSION), - ot_gvariant_new_ay_bytes (checksum_bytes), - maybe_swap_endian_u64 (builder->swap_endian, (guint64) g_variant_get_size (delta_part)), - maybe_swap_endian_u64 (builder->swap_endian, part_builder->uncompressed_size), - ot_gvariant_new_ay_bytes (objtype_checksum_array)); + delta_part_header = g_variant_new ( + "(u@aytt@ay)", maybe_swap_endian_u32 (builder->swap_endian, OSTREE_DELTAPART_VERSION), + ot_gvariant_new_ay_bytes (checksum_bytes), + maybe_swap_endian_u64 (builder->swap_endian, (guint64)g_variant_get_size (delta_part)), + maybe_swap_endian_u64 (builder->swap_endian, part_builder->uncompressed_size), + ot_gvariant_new_ay_bytes (objtype_checksum_array)); g_variant_ref_sink (delta_part_header); part_builder->header = g_variant_ref (delta_part_header); @@ -301,9 +300,9 @@ finish_part (OstreeStaticDeltaBuilder *builder, GError **error) if (builder->delta_opts & DELTAOPT_FLAG_VERBOSE) { - g_printerr ("part %u n:%u compressed:%" G_GUINT64_FORMAT " uncompressed:%" G_GUINT64_FORMAT "\n", - builder->parts->len, part_builder->objects->len, - part_builder->compressed_size, + g_printerr ("part %u n:%u compressed:%" G_GUINT64_FORMAT " uncompressed:%" G_GUINT64_FORMAT + "\n", + builder->parts->len, part_builder->objects->len, part_builder->compressed_size, part_builder->uncompressed_size); } @@ -335,8 +334,7 @@ allocate_part (OstreeStaticDeltaBuilder *builder, GError **error) } static gsize -allocate_part_buffer_space (OstreeStaticDeltaPartBuilder *current_part, - guint len) +allocate_part_buffer_space (OstreeStaticDeltaPartBuilder *current_part, guint len) { gsize empty_space; gsize old_len; @@ -348,7 +346,8 @@ allocate_part_buffer_space (OstreeStaticDeltaPartBuilder *current_part, { gsize origlen; origlen = current_part->payload->len; - g_string_set_size (current_part->payload, current_part->payload->allocated_len + (len - empty_space)); + g_string_set_size (current_part->payload, + current_part->payload->allocated_len + (len - empty_space)); current_part->payload->len = origlen; } @@ -356,10 +355,8 @@ allocate_part_buffer_space (OstreeStaticDeltaPartBuilder *current_part, } static gsize -write_unique_variant_chunk (OstreeStaticDeltaPartBuilder *current_part, - GHashTable *hash, - GPtrArray *ordered, - GVariant *key) +write_unique_variant_chunk (OstreeStaticDeltaPartBuilder *current_part, GHashTable *hash, + GPtrArray *ordered, GVariant *key) { gpointer target_offsetp; gsize offset; @@ -376,10 +373,8 @@ write_unique_variant_chunk (OstreeStaticDeltaPartBuilder *current_part, } static gboolean -splice_stream_to_payload (OstreeStaticDeltaPartBuilder *current_part, - GInputStream *istream, - GCancellable *cancellable, - GError **error) +splice_stream_to_payload (OstreeStaticDeltaPartBuilder *current_part, GInputStream *istream, + GCancellable *cancellable, GError **error) { while (TRUE) { @@ -389,9 +384,7 @@ splice_stream_to_payload (OstreeStaticDeltaPartBuilder *current_part, gsize bytes_read; if (!g_input_stream_read_all (istream, current_part->payload->str + current_part->payload->len, - readlen, - &bytes_read, - cancellable, error)) + readlen, &bytes_read, cancellable, error)) return FALSE; if (bytes_read == 0) break; @@ -403,69 +396,50 @@ splice_stream_to_payload (OstreeStaticDeltaPartBuilder *current_part, } static void -write_content_mode_xattrs (OstreeRepo *repo, - OstreeStaticDeltaPartBuilder *current_part, - GFileInfo *content_finfo, - GVariant *content_xattrs, - gsize *out_mode_offset, - gsize *out_xattr_offset) +write_content_mode_xattrs (OstreeRepo *repo, OstreeStaticDeltaPartBuilder *current_part, + GFileInfo *content_finfo, GVariant *content_xattrs, + gsize *out_mode_offset, gsize *out_xattr_offset) { - guint32 uid = - g_file_info_get_attribute_uint32 (content_finfo, "unix::uid"); - guint32 gid = - g_file_info_get_attribute_uint32 (content_finfo, "unix::gid"); - guint32 mode = - g_file_info_get_attribute_uint32 (content_finfo, "unix::mode"); - g_autoptr(GVariant) modev - = g_variant_ref_sink (g_variant_new ("(uuu)", - GUINT32_TO_BE (uid), - GUINT32_TO_BE (gid), - GUINT32_TO_BE (mode))); - - *out_mode_offset = write_unique_variant_chunk (current_part, - current_part->mode_set, - current_part->modes, - modev); - *out_xattr_offset = write_unique_variant_chunk (current_part, - current_part->xattr_set, - current_part->xattrs, - content_xattrs); + guint32 uid = g_file_info_get_attribute_uint32 (content_finfo, "unix::uid"); + guint32 gid = g_file_info_get_attribute_uint32 (content_finfo, "unix::gid"); + guint32 mode = g_file_info_get_attribute_uint32 (content_finfo, "unix::mode"); + g_autoptr (GVariant) modev = g_variant_ref_sink ( + g_variant_new ("(uuu)", GUINT32_TO_BE (uid), GUINT32_TO_BE (gid), GUINT32_TO_BE (mode))); + + *out_mode_offset = write_unique_variant_chunk (current_part, current_part->mode_set, + current_part->modes, modev); + *out_xattr_offset = write_unique_variant_chunk (current_part, current_part->xattr_set, + current_part->xattrs, content_xattrs); } static gboolean -process_one_object (OstreeRepo *repo, - OstreeStaticDeltaBuilder *builder, - OstreeStaticDeltaPartBuilder **current_part_val, - const char *checksum, - OstreeObjectType objtype, - GCancellable *cancellable, - GError **error) +process_one_object (OstreeRepo *repo, OstreeStaticDeltaBuilder *builder, + OstreeStaticDeltaPartBuilder **current_part_val, const char *checksum, + OstreeObjectType objtype, GCancellable *cancellable, GError **error) { OstreeStaticDeltaPartBuilder *current_part = *current_part_val; - g_autoptr(GFileInfo) content_finfo = NULL; - g_autoptr(GVariant) content_xattrs = NULL; + g_autoptr (GFileInfo) content_finfo = NULL; + g_autoptr (GVariant) content_xattrs = NULL; guint64 content_size; - g_autoptr(GInputStream) content_stream = NULL; + g_autoptr (GInputStream) content_stream = NULL; if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { - if (!ostree_repo_load_object_stream (repo, objtype, checksum, - &content_stream, &content_size, + if (!ostree_repo_load_object_stream (repo, objtype, checksum, &content_stream, &content_size, cancellable, error)) return FALSE; } else { - if (!ostree_repo_load_file (repo, checksum, &content_stream, - &content_finfo, &content_xattrs, + if (!ostree_repo_load_file (repo, checksum, &content_stream, &content_finfo, &content_xattrs, cancellable, error)) return FALSE; content_size = g_file_info_get_size (content_finfo); } /* Check to see if this delta is maximum size */ - if (current_part->objects->len > 0 && - current_part->payload->len + content_size > builder->max_chunk_size_bytes) + if (current_part->objects->len > 0 + && current_part->payload->len + content_size > builder->max_chunk_size_bytes) { current_part = allocate_part (builder, error); if (current_part == NULL) @@ -474,8 +448,7 @@ process_one_object (OstreeRepo *repo, } guint64 compressed_size; - if (!ostree_repo_query_object_storage_size (repo, objtype, checksum, - &compressed_size, + if (!ostree_repo_query_object_storage_size (repo, objtype, checksum, &compressed_size, cancellable, error)) return FALSE; builder->loose_compressed_size += compressed_size; @@ -490,11 +463,11 @@ process_one_object (OstreeRepo *repo, object_payload_start = current_part->payload->len; - if (!splice_stream_to_payload (current_part, content_stream, - cancellable, error)) + if (!splice_stream_to_payload (current_part, content_stream, cancellable, error)) return FALSE; - g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_OPEN_SPLICE_AND_CLOSE); + g_string_append_c (current_part->operations, + (gchar)OSTREE_STATIC_DELTA_OP_OPEN_SPLICE_AND_CLOSE); _ostree_write_varuint64 (current_part->operations, content_size); _ostree_write_varuint64 (current_part->operations, object_payload_start); } @@ -503,15 +476,14 @@ process_one_object (OstreeRepo *repo, gsize mode_offset, xattr_offset, content_offset; guint32 mode = g_file_info_get_attribute_uint32 (content_finfo, "unix::mode"); - write_content_mode_xattrs (repo, current_part, content_finfo, content_xattrs, - &mode_offset, &xattr_offset); + write_content_mode_xattrs (repo, current_part, content_finfo, content_xattrs, &mode_offset, + &xattr_offset); if (S_ISLNK (mode)) { g_assert (content_stream == NULL); const char *target = g_file_info_get_symlink_target (content_finfo); - content_stream = - g_memory_input_stream_new_from_data (target, strlen (target), NULL); + content_stream = g_memory_input_stream_new_from_data (target, strlen (target), NULL); content_size = strlen (target); } else @@ -520,11 +492,11 @@ process_one_object (OstreeRepo *repo, } content_offset = current_part->payload->len; - if (!splice_stream_to_payload (current_part, content_stream, - cancellable, error)) + if (!splice_stream_to_payload (current_part, content_stream, cancellable, error)) return FALSE; - g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_OPEN_SPLICE_AND_CLOSE); + g_string_append_c (current_part->operations, + (gchar)OSTREE_STATIC_DELTA_OP_OPEN_SPLICE_AND_CLOSE); _ostree_write_varuint64 (current_part->operations, mode_offset); _ostree_write_varuint64 (current_part->operations, xattr_offset); _ostree_write_varuint64 (current_part->operations, content_size); @@ -534,17 +506,19 @@ process_one_object (OstreeRepo *repo, return TRUE; } -typedef struct { +typedef struct +{ char *from_checksum; } ContentBsdiff; -typedef struct { +typedef struct +{ char *from_checksum; OstreeRollsumMatches *matches; } ContentRollsum; static void -content_rollsums_free (ContentRollsum *rollsum) +content_rollsums_free (ContentRollsum *rollsum) { g_free (rollsum->from_checksum); _ostree_rollsum_matches_free (rollsum->matches); @@ -552,7 +526,7 @@ content_rollsums_free (ContentRollsum *rollsum) } static void -content_bsdiffs_free (ContentBsdiff *bsdiff) +content_bsdiffs_free (ContentBsdiff *bsdiff) { g_free (bsdiff->from_checksum); g_free (bsdiff); @@ -562,16 +536,12 @@ content_bsdiffs_free (ContentBsdiff *bsdiff) that's mmap()'d and suitable for seeking. */ static gboolean -get_unpacked_unlinked_content (OstreeRepo *repo, - const char *checksum, - GBytes **out_content, - GCancellable *cancellable, - GError **error) +get_unpacked_unlinked_content (OstreeRepo *repo, const char *checksum, GBytes **out_content, + GCancellable *cancellable, GError **error) { - g_autoptr(GInputStream) istream = NULL; + g_autoptr (GInputStream) istream = NULL; - if (!ostree_repo_load_file (repo, checksum, &istream, NULL, NULL, - cancellable, error)) + if (!ostree_repo_load_file (repo, checksum, &istream, NULL, NULL, cancellable, error)) return FALSE; *out_content = ot_map_anonymous_tmpfile_from_content (istream, cancellable, error); @@ -581,23 +551,15 @@ get_unpacked_unlinked_content (OstreeRepo *repo, } static gboolean -try_content_bsdiff (OstreeRepo *repo, - const char *from, - const char *to, - ContentBsdiff **out_bsdiff, - guint64 max_bsdiff_size_bytes, - GCancellable *cancellable, - GError **error) +try_content_bsdiff (OstreeRepo *repo, const char *from, const char *to, ContentBsdiff **out_bsdiff, + guint64 max_bsdiff_size_bytes, GCancellable *cancellable, GError **error) { - - g_autoptr(GFileInfo) from_finfo = NULL; - if (!ostree_repo_load_file (repo, from, NULL, &from_finfo, NULL, - cancellable, error)) + g_autoptr (GFileInfo) from_finfo = NULL; + if (!ostree_repo_load_file (repo, from, NULL, &from_finfo, NULL, cancellable, error)) return FALSE; - g_autoptr(GFileInfo) to_finfo = NULL; - if (!ostree_repo_load_file (repo, to, NULL, &to_finfo, NULL, - cancellable, error)) + g_autoptr (GFileInfo) to_finfo = NULL; + if (!ostree_repo_load_file (repo, to, NULL, &to_finfo, NULL, cancellable, error)) return FALSE; *out_bsdiff = NULL; @@ -614,29 +576,24 @@ try_content_bsdiff (OstreeRepo *repo, } static gboolean -try_content_rollsum (OstreeRepo *repo, - DeltaOpts opts, - const char *from, - const char *to, - ContentRollsum **out_rollsum, - GCancellable *cancellable, - GError **error) +try_content_rollsum (OstreeRepo *repo, DeltaOpts opts, const char *from, const char *to, + ContentRollsum **out_rollsum, GCancellable *cancellable, GError **error) { *out_rollsum = NULL; /* Load the content objects, splice them to uncompressed temporary files that * we can just mmap() and seek around in conveniently. */ - g_autoptr(GBytes) tmp_from = NULL; + g_autoptr (GBytes) tmp_from = NULL; if (!get_unpacked_unlinked_content (repo, from, &tmp_from, cancellable, error)) return FALSE; - g_autoptr(GBytes) tmp_to = NULL; + g_autoptr (GBytes) tmp_to = NULL; if (!get_unpacked_unlinked_content (repo, to, &tmp_to, cancellable, error)) return FALSE; - g_autoptr(OstreeRollsumMatches) matches = _ostree_compute_rollsum_matches (tmp_from, tmp_to); + g_autoptr (OstreeRollsumMatches) matches = _ostree_compute_rollsum_matches (tmp_from, tmp_to); - const guint match_ratio = (matches->bufmatches*100)/matches->total; + const guint match_ratio = (matches->bufmatches * 100) / matches->total; /* Only proceed if the file contains (arbitrary) more than 50% of * the previous chunks. @@ -646,10 +603,9 @@ try_content_rollsum (OstreeRepo *repo, if (opts & DELTAOPT_FLAG_VERBOSE) { - g_printerr ("rollsum for %s -> %s; crcs=%u bufs=%u total=%u matchsize=%llu\n", - from, to, matches->crcmatches, - matches->bufmatches, - matches->total, (unsigned long long)matches->match_size); + g_printerr ("rollsum for %s -> %s; crcs=%u bufs=%u total=%u matchsize=%llu\n", from, to, + matches->crcmatches, matches->bufmatches, matches->total, + (unsigned long long)matches->match_size); } ContentRollsum *ret_rollsum = g_new0 (ContentRollsum, 1); @@ -667,47 +623,37 @@ struct bzdiff_opaque_s }; static int -bzdiff_write (struct bsdiff_stream* stream, const void* buffer, int size) +bzdiff_write (struct bsdiff_stream *stream, const void *buffer, int size) { struct bzdiff_opaque_s *op = stream->opaque; - if (!g_output_stream_write (op->out, - buffer, - size, - op->cancellable, - op->error)) + if (!g_output_stream_write (op->out, buffer, size, op->cancellable, op->error)) return -1; return 0; } static void -append_payload_chunk_and_write (OstreeStaticDeltaPartBuilder *current_part, - const guint8 *buf, - guint64 offset) +append_payload_chunk_and_write (OstreeStaticDeltaPartBuilder *current_part, const guint8 *buf, + guint64 offset) { guint64 payload_start; payload_start = current_part->payload->len; - g_string_append_len (current_part->payload, (char*)buf, offset); + g_string_append_len (current_part->payload, (char *)buf, offset); g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_WRITE); _ostree_write_varuint64 (current_part->operations, offset); _ostree_write_varuint64 (current_part->operations, payload_start); } static gboolean -process_one_rollsum (OstreeRepo *repo, - OstreeStaticDeltaBuilder *builder, - OstreeStaticDeltaPartBuilder **current_part_val, - const char *to_checksum, - ContentRollsum *rollsum, - GCancellable *cancellable, - GError **error) +process_one_rollsum (OstreeRepo *repo, OstreeStaticDeltaBuilder *builder, + OstreeStaticDeltaPartBuilder **current_part_val, const char *to_checksum, + ContentRollsum *rollsum, GCancellable *cancellable, GError **error) { OstreeStaticDeltaPartBuilder *current_part = *current_part_val; /* Check to see if this delta has gone over maximum size */ - if (current_part->objects->len > 0 && - current_part->payload->len > builder->max_chunk_size_bytes) + if (current_part->objects->len > 0 && current_part->payload->len > builder->max_chunk_size_bytes) { current_part = allocate_part (builder, error); if (current_part == NULL) @@ -715,46 +661,47 @@ process_one_rollsum (OstreeRepo *repo, *current_part_val = current_part; } - g_autoptr(GBytes) tmp_to = NULL; - if (!get_unpacked_unlinked_content (repo, to_checksum, &tmp_to, - cancellable, error)) + g_autoptr (GBytes) tmp_to = NULL; + if (!get_unpacked_unlinked_content (repo, to_checksum, &tmp_to, cancellable, error)) return FALSE; gsize tmp_to_len; const guint8 *tmp_to_buf = g_bytes_get_data (tmp_to, &tmp_to_len); - g_autoptr(GFileInfo) content_finfo = NULL; - g_autoptr(GVariant) content_xattrs = NULL; - if (!ostree_repo_load_file (repo, to_checksum, NULL, - &content_finfo, &content_xattrs, - cancellable, error)) + g_autoptr (GFileInfo) content_finfo = NULL; + g_autoptr (GVariant) content_xattrs = NULL; + if (!ostree_repo_load_file (repo, to_checksum, NULL, &content_finfo, &content_xattrs, cancellable, + error)) return FALSE; guint64 content_size = g_file_info_get_size (content_finfo); g_assert_cmpint (tmp_to_len, ==, content_size); current_part->uncompressed_size += content_size; - g_ptr_array_add (current_part->objects, ostree_object_name_serialize (to_checksum, OSTREE_OBJECT_TYPE_FILE)); + g_ptr_array_add (current_part->objects, + ostree_object_name_serialize (to_checksum, OSTREE_OBJECT_TYPE_FILE)); - { gsize mode_offset, xattr_offset, from_csum_offset; + { + gsize mode_offset, xattr_offset, from_csum_offset; gboolean reading_payload = TRUE; guchar source_csum[OSTREE_SHA256_DIGEST_LEN]; guint i; - write_content_mode_xattrs (repo, current_part, content_finfo, content_xattrs, - &mode_offset, &xattr_offset); + write_content_mode_xattrs (repo, current_part, content_finfo, content_xattrs, &mode_offset, + &xattr_offset); /* Write the origin checksum */ ostree_checksum_inplace_to_bytes (rollsum->from_checksum, source_csum); from_csum_offset = current_part->payload->len; - g_string_append_len (current_part->payload, (char*)source_csum, sizeof (source_csum)); + g_string_append_len (current_part->payload, (char *)source_csum, sizeof (source_csum)); g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_OPEN); _ostree_write_varuint64 (current_part->operations, mode_offset); _ostree_write_varuint64 (current_part->operations, xattr_offset); _ostree_write_varuint64 (current_part->operations, content_size); - { guint64 writing_offset = 0; + { + guint64 writing_offset = 0; guint64 offset = 0, to_start = 0, from_start = 0; GPtrArray *matchlist = rollsum->matches->matches; @@ -772,7 +719,8 @@ process_one_rollsum (OstreeRepo *repo, { if (!reading_payload) { - g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_UNSET_READ_SOURCE); + g_string_append_c (current_part->operations, + (gchar)OSTREE_STATIC_DELTA_OP_UNSET_READ_SOURCE); reading_payload = TRUE; } @@ -783,7 +731,8 @@ process_one_rollsum (OstreeRepo *repo, if (reading_payload) { - g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_SET_READ_SOURCE); + g_string_append_c (current_part->operations, + (gchar)OSTREE_STATIC_DELTA_OP_SET_READ_SOURCE); _ostree_write_varuint64 (current_part->operations, from_csum_offset); reading_payload = FALSE; } @@ -795,7 +744,8 @@ process_one_rollsum (OstreeRepo *repo, } if (!reading_payload) - g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_UNSET_READ_SOURCE); + g_string_append_c (current_part->operations, + (gchar)OSTREE_STATIC_DELTA_OP_UNSET_READ_SOURCE); const guint64 remainder = tmp_to_len - writing_offset; if (remainder > 0) @@ -805,7 +755,6 @@ process_one_rollsum (OstreeRepo *repo, g_assert_cmpint (writing_offset, ==, content_size); } - g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_CLOSE); } @@ -813,19 +762,14 @@ process_one_rollsum (OstreeRepo *repo, } static gboolean -process_one_bsdiff (OstreeRepo *repo, - OstreeStaticDeltaBuilder *builder, - OstreeStaticDeltaPartBuilder **current_part_val, - const char *to_checksum, - ContentBsdiff *bsdiff_content, - GCancellable *cancellable, - GError **error) +process_one_bsdiff (OstreeRepo *repo, OstreeStaticDeltaBuilder *builder, + OstreeStaticDeltaPartBuilder **current_part_val, const char *to_checksum, + ContentBsdiff *bsdiff_content, GCancellable *cancellable, GError **error) { OstreeStaticDeltaPartBuilder *current_part = *current_part_val; /* Check to see if this delta has gone over maximum size */ - if (current_part->objects->len > 0 && - current_part->payload->len > builder->max_chunk_size_bytes) + if (current_part->objects->len > 0 && current_part->payload->len > builder->max_chunk_size_bytes) { current_part = allocate_part (builder, error); if (current_part == NULL) @@ -833,13 +777,12 @@ process_one_bsdiff (OstreeRepo *repo, *current_part_val = current_part; } - g_autoptr(GBytes) tmp_from = NULL; - if (!get_unpacked_unlinked_content (repo, bsdiff_content->from_checksum, &tmp_from, - cancellable, error)) + g_autoptr (GBytes) tmp_from = NULL; + if (!get_unpacked_unlinked_content (repo, bsdiff_content->from_checksum, &tmp_from, cancellable, + error)) return FALSE; - g_autoptr(GBytes) tmp_to = NULL; - if (!get_unpacked_unlinked_content (repo, to_checksum, &tmp_to, - cancellable, error)) + g_autoptr (GBytes) tmp_to = NULL; + if (!get_unpacked_unlinked_content (repo, to_checksum, &tmp_to, cancellable, error)) return FALSE; gsize tmp_to_len; @@ -847,31 +790,32 @@ process_one_bsdiff (OstreeRepo *repo, gsize tmp_from_len; const guint8 *tmp_from_buf = g_bytes_get_data (tmp_from, &tmp_from_len); - g_autoptr(GFileInfo) content_finfo = NULL; - g_autoptr(GVariant) content_xattrs = NULL; - if (!ostree_repo_load_file (repo, to_checksum, NULL, - &content_finfo, &content_xattrs, - cancellable, error)) + g_autoptr (GFileInfo) content_finfo = NULL; + g_autoptr (GVariant) content_xattrs = NULL; + if (!ostree_repo_load_file (repo, to_checksum, NULL, &content_finfo, &content_xattrs, cancellable, + error)) return FALSE; const guint64 content_size = g_file_info_get_size (content_finfo); g_assert_cmpint (tmp_to_len, ==, content_size); current_part->uncompressed_size += content_size; - g_ptr_array_add (current_part->objects, ostree_object_name_serialize (to_checksum, OSTREE_OBJECT_TYPE_FILE)); + g_ptr_array_add (current_part->objects, + ostree_object_name_serialize (to_checksum, OSTREE_OBJECT_TYPE_FILE)); - { gsize mode_offset, xattr_offset; + { + gsize mode_offset, xattr_offset; guchar source_csum[OSTREE_SHA256_DIGEST_LEN]; - write_content_mode_xattrs (repo, current_part, content_finfo, content_xattrs, - &mode_offset, &xattr_offset); + write_content_mode_xattrs (repo, current_part, content_finfo, content_xattrs, &mode_offset, + &xattr_offset); /* Write the origin checksum */ ostree_checksum_inplace_to_bytes (bsdiff_content->from_checksum, source_csum); g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_SET_READ_SOURCE); _ostree_write_varuint64 (current_part->operations, current_part->payload->len); - g_string_append_len (current_part->payload, (char*)source_csum, sizeof (source_csum)); + g_string_append_len (current_part->payload, (char *)source_csum, sizeof (source_csum)); g_string_append_c (current_part->operations, (gchar)OSTREE_STATIC_DELTA_OP_OPEN); _ostree_write_varuint64 (current_part->operations, mode_offset); @@ -883,7 +827,7 @@ process_one_bsdiff (OstreeRepo *repo, struct bzdiff_opaque_s op; const gchar *payload; gssize payload_size; - g_autoptr(GOutputStream) out = g_memory_output_stream_new_resizable (); + g_autoptr (GOutputStream) out = g_memory_output_stream_new_resizable (); stream.malloc = malloc; stream.free = free; stream.write = bzdiff_write; @@ -926,17 +870,13 @@ process_one_bsdiff (OstreeRepo *repo, } static gboolean -check_object_world_readable (OstreeRepo *repo, - const char *checksum, - gboolean *out_readable, - GCancellable *cancellable, - GError **error) +check_object_world_readable (OstreeRepo *repo, const char *checksum, gboolean *out_readable, + GCancellable *cancellable, GError **error) { - g_autoptr(GFileInfo) finfo = NULL; + g_autoptr (GFileInfo) finfo = NULL; guint32 mode; - if (!ostree_repo_load_file (repo, checksum, NULL, &finfo, NULL, - cancellable, error)) + if (!ostree_repo_load_file (repo, checksum, NULL, &finfo, NULL, cancellable, error)) return FALSE; mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode"); @@ -945,54 +885,44 @@ check_object_world_readable (OstreeRepo *repo, } static gboolean -generate_delta_lowlatency (OstreeRepo *repo, - const char *from, - const char *to, - DeltaOpts opts, - OstreeStaticDeltaBuilder *builder, - GCancellable *cancellable, - GError **error) +generate_delta_lowlatency (OstreeRepo *repo, const char *from, const char *to, DeltaOpts opts, + OstreeStaticDeltaBuilder *builder, GCancellable *cancellable, + GError **error) { GHashTableIter hashiter; gpointer key, value; OstreeStaticDeltaPartBuilder *current_part = NULL; - g_autoptr(GFile) root_from = NULL; - g_autoptr(GVariant) from_commit = NULL; - g_autoptr(GFile) root_to = NULL; - g_autoptr(GVariant) to_commit = NULL; - g_autoptr(GHashTable) to_reachable_objects = NULL; - g_autoptr(GHashTable) from_reachable_objects = NULL; - g_autoptr(GHashTable) new_reachable_metadata = NULL; - g_autoptr(GHashTable) new_reachable_regfile_content = NULL; - g_autoptr(GHashTable) new_reachable_symlink_content = NULL; - g_autoptr(GHashTable) modified_regfile_content = NULL; - g_autoptr(GHashTable) rollsum_optimized_content_objects = NULL; - g_autoptr(GHashTable) bsdiff_optimized_content_objects = NULL; + g_autoptr (GFile) root_from = NULL; + g_autoptr (GVariant) from_commit = NULL; + g_autoptr (GFile) root_to = NULL; + g_autoptr (GVariant) to_commit = NULL; + g_autoptr (GHashTable) to_reachable_objects = NULL; + g_autoptr (GHashTable) from_reachable_objects = NULL; + g_autoptr (GHashTable) new_reachable_metadata = NULL; + g_autoptr (GHashTable) new_reachable_regfile_content = NULL; + g_autoptr (GHashTable) new_reachable_symlink_content = NULL; + g_autoptr (GHashTable) modified_regfile_content = NULL; + g_autoptr (GHashTable) rollsum_optimized_content_objects = NULL; + g_autoptr (GHashTable) bsdiff_optimized_content_objects = NULL; if (from != NULL) { - if (!ostree_repo_read_commit (repo, from, &root_from, NULL, - cancellable, error)) + if (!ostree_repo_read_commit (repo, from, &root_from, NULL, cancellable, error)) return FALSE; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, from, - &from_commit, error)) + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, from, &from_commit, error)) return FALSE; - if (!ostree_repo_traverse_commit (repo, from, 0, &from_reachable_objects, - cancellable, error)) + if (!ostree_repo_traverse_commit (repo, from, 0, &from_reachable_objects, cancellable, error)) return FALSE; } - if (!ostree_repo_read_commit (repo, to, &root_to, NULL, - cancellable, error)) + if (!ostree_repo_read_commit (repo, to, &root_to, NULL, cancellable, error)) return FALSE; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, to, - &to_commit, error)) + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, to, &to_commit, error)) return FALSE; - if (!ostree_repo_traverse_commit (repo, to, 0, &to_reachable_objects, - cancellable, error)) + if (!ostree_repo_traverse_commit (repo, to, 0, &to_reachable_objects, cancellable, error)) return FALSE; new_reachable_metadata = ostree_repo_traverse_new_reachable (); @@ -1015,11 +945,10 @@ generate_delta_lowlatency (OstreeRepo *repo, g_hash_table_add (new_reachable_metadata, g_variant_ref (serialized_key)); else { - g_autoptr(GFileInfo) finfo = NULL; + g_autoptr (GFileInfo) finfo = NULL; GFileType ftype; - if (!ostree_repo_load_file (repo, checksum, NULL, &finfo, NULL, - cancellable, error)) + if (!ostree_repo_load_file (repo, checksum, NULL, &finfo, NULL, cancellable, error)) return FALSE; ftype = g_file_info_get_file_type (finfo); @@ -1037,8 +966,7 @@ generate_delta_lowlatency (OstreeRepo *repo, if (!_ostree_delta_compute_similar_objects (repo, from_commit, to_commit, new_reachable_regfile_content, CONTENT_SIZE_SIMILARITY_THRESHOLD_PERCENT, - &modified_regfile_content, - cancellable, error)) + &modified_regfile_content, cancellable, error)) return FALSE; } else @@ -1054,17 +982,16 @@ generate_delta_lowlatency (OstreeRepo *repo, } /* We already ship the to commit in the superblock, don't ship it twice */ - { g_autoptr(GVariant) commit = ostree_object_name_serialize (to, OSTREE_OBJECT_TYPE_COMMIT); + { + g_autoptr (GVariant) commit = ostree_object_name_serialize (to, OSTREE_OBJECT_TYPE_COMMIT); g_hash_table_remove (new_reachable_metadata, commit); } - rollsum_optimized_content_objects = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, - (GDestroyNotify) content_rollsums_free); + rollsum_optimized_content_objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify)content_rollsums_free); - bsdiff_optimized_content_objects = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, - (GDestroyNotify) content_bsdiffs_free); + bsdiff_optimized_content_objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify)content_bsdiffs_free); g_hash_table_iter_init (&hashiter, modified_regfile_content); while (g_hash_table_iter_next (&hashiter, &key, &value)) @@ -1081,13 +1008,14 @@ generate_delta_lowlatency (OstreeRepo *repo, * when the client is trying to update a bare-user repository with a * bare repository defined as its parent. */ - if (!check_object_world_readable (repo, from_checksum, &from_world_readable, cancellable, error)) + if (!check_object_world_readable (repo, from_checksum, &from_world_readable, cancellable, + error)) return FALSE; if (!from_world_readable) continue; - if (!try_content_rollsum (repo, opts, from_checksum, to_checksum, - &rollsum, cancellable, error)) + if (!try_content_rollsum (repo, opts, from_checksum, to_checksum, &rollsum, cancellable, + error)) return FALSE; if (rollsum) @@ -1099,9 +1027,8 @@ generate_delta_lowlatency (OstreeRepo *repo, if (!(opts & DELTAOPT_FLAG_DISABLE_BSDIFF)) { - if (!try_content_bsdiff (repo, from_checksum, to_checksum, - &bsdiff, builder->max_bsdiff_size_bytes, - cancellable, error)) + if (!try_content_bsdiff (repo, from_checksum, to_checksum, &bsdiff, + builder->max_bsdiff_size_bytes, cancellable, error)) return FALSE; if (bsdiff) @@ -1130,9 +1057,7 @@ generate_delta_lowlatency (OstreeRepo *repo, ostree_object_name_deserialize (serialized_key, &checksum, &objtype); - if (!process_one_object (repo, builder, ¤t_part, - checksum, objtype, - cancellable, error)) + if (!process_one_object (repo, builder, ¤t_part, checksum, objtype, cancellable, error)) return FALSE; } @@ -1144,9 +1069,8 @@ generate_delta_lowlatency (OstreeRepo *repo, const char *checksum = key; ContentRollsum *rollsum = value; - if (!process_one_rollsum (repo, builder, ¤t_part, - checksum, rollsum, - cancellable, error)) + if (!process_one_rollsum (repo, builder, ¤t_part, checksum, rollsum, cancellable, + error)) return FALSE; builder->n_rollsum++; @@ -1164,13 +1088,11 @@ generate_delta_lowlatency (OstreeRepo *repo, const char *checksum = key; ContentBsdiff *bsdiff = value; - if (opts & DELTAOPT_FLAG_VERBOSE && - (mod == 0 || builder->n_bsdiff % mod == 0)) + if (opts & DELTAOPT_FLAG_VERBOSE && (mod == 0 || builder->n_bsdiff % mod == 0)) g_printerr ("processing bsdiff: [%u/%u]\n", builder->n_bsdiff, n_bsdiff); - if (!process_one_bsdiff (repo, builder, ¤t_part, - checksum, bsdiff, - cancellable, error)) + if (!process_one_bsdiff (repo, builder, ¤t_part, checksum, bsdiff, cancellable, + error)) return FALSE; builder->n_bsdiff++; @@ -1188,16 +1110,15 @@ generate_delta_lowlatency (OstreeRepo *repo, gboolean fallback = FALSE; /* Skip content objects we rollsum'd or bsdiff'ed */ - if (g_hash_table_contains (rollsum_optimized_content_objects, checksum) || - g_hash_table_contains (bsdiff_optimized_content_objects, checksum)) + if (g_hash_table_contains (rollsum_optimized_content_objects, checksum) + || g_hash_table_contains (bsdiff_optimized_content_objects, checksum)) continue; - if (!ostree_repo_load_object_stream (repo, OSTREE_OBJECT_TYPE_FILE, checksum, - NULL, &uncompressed_size, - cancellable, error)) + if (!ostree_repo_load_object_stream (repo, OSTREE_OBJECT_TYPE_FILE, checksum, NULL, + &uncompressed_size, cancellable, error)) return FALSE; - if (builder->min_fallback_size_bytes > 0 && - uncompressed_size > builder->min_fallback_size_bytes) + if (builder->min_fallback_size_bytes > 0 + && uncompressed_size > builder->min_fallback_size_bytes) fallback = TRUE; if (fallback) @@ -1221,12 +1142,11 @@ generate_delta_lowlatency (OstreeRepo *repo, const char *checksum = key; /* Skip content objects we rollsum'd */ - if (g_hash_table_contains (rollsum_optimized_content_objects, checksum) || - g_hash_table_contains (bsdiff_optimized_content_objects, checksum)) + if (g_hash_table_contains (rollsum_optimized_content_objects, checksum) + || g_hash_table_contains (bsdiff_optimized_content_objects, checksum)) continue; - if (!process_one_object (repo, builder, ¤t_part, - checksum, OSTREE_OBJECT_TYPE_FILE, + if (!process_one_object (repo, builder, ¤t_part, checksum, OSTREE_OBJECT_TYPE_FILE, cancellable, error)) return FALSE; } @@ -1237,8 +1157,7 @@ generate_delta_lowlatency (OstreeRepo *repo, { const char *checksum = key; - if (!process_one_object (repo, builder, ¤t_part, - checksum, OSTREE_OBJECT_TYPE_FILE, + if (!process_one_object (repo, builder, ¤t_part, checksum, OSTREE_OBJECT_TYPE_FILE, cancellable, error)) return FALSE; } @@ -1250,14 +1169,11 @@ generate_delta_lowlatency (OstreeRepo *repo, } static gboolean -get_fallback_headers (OstreeRepo *self, - OstreeStaticDeltaBuilder *builder, - GVariant **out_headers, - GCancellable *cancellable, - GError **error) +get_fallback_headers (OstreeRepo *self, OstreeStaticDeltaBuilder *builder, GVariant **out_headers, + GCancellable *cancellable, GError **error) { - g_autoptr(GVariantBuilder) fallback_builder = - g_variant_builder_new (G_VARIANT_TYPE ("a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT)); + g_autoptr (GVariantBuilder) fallback_builder + = g_variant_builder_new (G_VARIANT_TYPE ("a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT)); for (guint i = 0; i < builder->fallback_objects->len; i++) { @@ -1271,38 +1187,32 @@ get_fallback_headers (OstreeRepo *self, if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { - if (!ostree_repo_load_object_stream (self, objtype, checksum, - NULL, &uncompressed_size, + if (!ostree_repo_load_object_stream (self, objtype, checksum, NULL, &uncompressed_size, cancellable, error)) return FALSE; compressed_size = uncompressed_size; } else { - if (!ostree_repo_query_object_storage_size (self, OSTREE_OBJECT_TYPE_FILE, - checksum, - &compressed_size, - cancellable, error)) + if (!ostree_repo_query_object_storage_size (self, OSTREE_OBJECT_TYPE_FILE, checksum, + &compressed_size, cancellable, error)) return FALSE; - g_autoptr(GFileInfo) file_info = NULL; - if (!ostree_repo_load_file (self, checksum, - NULL, &file_info, NULL, - cancellable, error)) + g_autoptr (GFileInfo) file_info = NULL; + if (!ostree_repo_load_file (self, checksum, NULL, &file_info, NULL, cancellable, error)) return FALSE; uncompressed_size = g_file_info_get_size (file_info); } - g_variant_builder_add_value (fallback_builder, - g_variant_new ("(y@aytt)", - objtype, - ostree_checksum_to_bytes_v (checksum), - maybe_swap_endian_u64 (builder->swap_endian, compressed_size), - maybe_swap_endian_u64 (builder->swap_endian, uncompressed_size))); + g_variant_builder_add_value ( + fallback_builder, + g_variant_new ("(y@aytt)", objtype, ostree_checksum_to_bytes_v (checksum), + maybe_swap_endian_u64 (builder->swap_endian, compressed_size), + maybe_swap_endian_u64 (builder->swap_endian, uncompressed_size))); } - g_autoptr(GVariant) ret_headers = g_variant_ref_sink (g_variant_builder_end (fallback_builder)); + g_autoptr (GVariant) ret_headers = g_variant_ref_sink (g_variant_builder_end (fallback_builder)); ot_transfer_out_value (out_headers, &ret_headers); return TRUE; } @@ -1325,7 +1235,8 @@ get_fallback_headers (OstreeRepo *self, * * The @params argument should be an a{sv}. The following attributes * are known: - * - min-fallback-size: u: Minimum uncompressed size in megabytes to use fallback, 0 to disable fallbacks + * - min-fallback-size: u: Minimum uncompressed size in megabytes to use fallback, 0 to disable + * fallbacks * - max-chunk-size: u: Maximum size in megabytes of a delta part * - max-bsdiff-size: u: Maximum size in megabytes to consider bsdiff compression * for input files @@ -1333,22 +1244,21 @@ get_fallback_headers (OstreeRepo *self, * - bsdiff-enabled: b: Enable bsdiff compression. Default TRUE. * - inline-parts: b: Put part data in header, to get a single file delta. Default FALSE. * - verbose: b: Print diagnostic messages. Default FALSE. - * - endianness: b: Deltas use host byte order by default; this option allows choosing (G_BIG_ENDIAN or G_LITTLE_ENDIAN) - * - filename: ay: Save delta superblock to this filename, and parts in the same directory. Default saves to repository. - * - sign-name: ay: Signature type to use. - * - sign-key-ids: as: Array of keys used to sign delta superblock. + * - endianness: b: Deltas use host byte order by default; this option allows choosing + * (G_BIG_ENDIAN or G_LITTLE_ENDIAN) + * - filename: ^ay: Save delta superblock to this filename (bytestring), and parts in the same + * directory. Default saves to repository. + * - sign-name: ^ay: Signature type to use (bytestring). + * - sign-key-ids: ^as: NULL-terminated array of keys used to sign delta superblock. */ gboolean -ostree_repo_static_delta_generate (OstreeRepo *self, - OstreeStaticDeltaGenerateOpt opt, - const char *from, - const char *to, - GVariant *metadata, - GVariant *params, - GCancellable *cancellable, - GError **error) +ostree_repo_static_delta_generate (OstreeRepo *self, OstreeStaticDeltaGenerateOpt opt, + const char *from, const char *to, GVariant *metadata, + GVariant *params, GCancellable *cancellable, GError **error) { - OstreeStaticDeltaBuilder builder = { 0, }; + OstreeStaticDeltaBuilder builder = { + 0, + }; guint i; guint min_fallback_size; guint max_bsdiff_size; @@ -1356,20 +1266,22 @@ ostree_repo_static_delta_generate (OstreeRepo *self, DeltaOpts delta_opts = DELTAOPT_FLAG_NONE; guint64 total_compressed_size = 0; guint64 total_uncompressed_size = 0; - g_autoptr(GVariantBuilder) part_headers = NULL; - g_autoptr(GPtrArray) part_temp_paths = NULL; - g_autoptr(GVariant) to_commit = NULL; + g_autoptr (GVariantBuilder) part_headers = NULL; + g_autoptr (GVariant) to_commit = NULL; const char *opt_filename; g_autofree char *descriptor_name = NULL; glnx_autofd int descriptor_dfd = -1; - g_autoptr(GVariant) fallback_headers = NULL; - g_autoptr(GVariant) detached = NULL; + g_autoptr (GVariant) fallback_headers = NULL; + g_autoptr (GVariant) detached = NULL; gboolean inline_parts; guint endianness = G_BYTE_ORDER; - g_autoptr(GPtrArray) builder_parts = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_static_delta_part_builder_unref); - g_autoptr(GPtrArray) builder_fallback_objects = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); - g_auto(GLnxTmpfile) descriptor_tmpf = { 0, }; - g_autoptr(OtVariantBuilder) descriptor_builder = NULL; + g_autoptr (GPtrArray) builder_parts + = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_static_delta_part_builder_unref); + g_autoptr (GPtrArray) builder_fallback_objects + = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); + g_auto (GLnxTmpfile) descriptor_tmpf = { + 0, + }; const char *opt_sign_name; const char **opt_key_ids; @@ -1384,21 +1296,24 @@ ostree_repo_static_delta_generate (OstreeRepo *self, max_chunk_size = 32; builder.max_chunk_size_bytes = ((guint64)max_chunk_size) * 1000 * 1000; - (void) g_variant_lookup (params, "endianness", "u", &endianness); - g_return_val_if_fail (endianness == G_BIG_ENDIAN || endianness == G_LITTLE_ENDIAN, FALSE); + (void)g_variant_lookup (params, "endianness", "u", &endianness); + if (!(endianness == G_BIG_ENDIAN || endianness == G_LITTLE_ENDIAN)) + return glnx_throw (error, "Invalid endianness parameter"); builder.swap_endian = endianness != G_BYTE_ORDER; builder.parts = builder_parts; builder.fallback_objects = builder_fallback_objects; - { gboolean use_bsdiff; + { + gboolean use_bsdiff; if (!g_variant_lookup (params, "bsdiff-enabled", "b", &use_bsdiff)) use_bsdiff = TRUE; if (!use_bsdiff) delta_opts |= DELTAOPT_FLAG_DISABLE_BSDIFF; } - { gboolean verbose; + { + gboolean verbose; if (!g_variant_lookup (params, "verbose", "b", &verbose)) verbose = FALSE; if (verbose) @@ -1410,15 +1325,18 @@ ostree_repo_static_delta_generate (OstreeRepo *self, if (!g_variant_lookup (params, "filename", "^&ay", &opt_filename)) opt_filename = NULL; + else if (opt_filename[0] == '\0') + return glnx_throw (error, "Invalid 'filename' parameter"); if (!g_variant_lookup (params, "sign-name", "^&ay", &opt_sign_name)) opt_sign_name = NULL; + else if (opt_sign_name[0] == '\0') + return glnx_throw (error, "Invalid 'sign-name' parameter"); if (!g_variant_lookup (params, "sign-key-ids", "^a&s", &opt_key_ids)) opt_key_ids = NULL; - if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, to, - &to_commit, error)) + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, to, &to_commit, error)) return FALSE; builder.delta_opts = delta_opts; @@ -1434,11 +1352,13 @@ ostree_repo_static_delta_generate (OstreeRepo *self, } else { - g_autofree char *descriptor_relpath = _ostree_get_relative_static_delta_superblock_path (from, to); + g_autofree char *descriptor_relpath + = _ostree_get_relative_static_delta_superblock_path (from, to); g_autofree char *dnbuf = g_strdup (descriptor_relpath); const char *dn = dirname (dnbuf); - if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, dn, DEFAULT_DIRECTORY_MODE, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, dn, DEFAULT_DIRECTORY_MODE, cancellable, + error)) return FALSE; if (!glnx_opendirat (self->repo_dir_fd, dn, TRUE, &descriptor_dfd, error)) return FALSE; @@ -1448,15 +1368,16 @@ ostree_repo_static_delta_generate (OstreeRepo *self, builder.parts_dfd = descriptor_dfd; /* Ignore optimization flags */ - if (!generate_delta_lowlatency (self, from, to, delta_opts, &builder, - cancellable, error)) + if (!generate_delta_lowlatency (self, from, to, delta_opts, &builder, cancellable, error)) return FALSE; - if (!glnx_open_tmpfile_linkable_at (descriptor_dfd, ".", O_RDWR | O_CLOEXEC, - &descriptor_tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (descriptor_dfd, ".", O_RDWR | O_CLOEXEC, &descriptor_tmpf, + error)) return FALSE; - descriptor_builder = ot_variant_builder_new (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), descriptor_tmpf.fd); + g_autoptr (OtVariantBuilder) descriptor_builder = ot_variant_builder_new ( + G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), descriptor_tmpf.fd); + g_assert (descriptor_builder != NULL); /* Open the metadata dict */ if (!ot_variant_builder_open (descriptor_builder, G_VARIANT_TYPE ("a{sv}"), error)) @@ -1480,7 +1401,8 @@ ostree_repo_static_delta_generate (OstreeRepo *self, } } - { guint8 endianness_char; + { + guint8 endianness_char; switch (endianness) { @@ -1493,12 +1415,12 @@ ostree_repo_static_delta_generate (OstreeRepo *self, default: g_assert_not_reached (); } - if (!ot_variant_builder_add (descriptor_builder, error, "{sv}", "ostree.endianness", g_variant_new_byte (endianness_char))) + if (!ot_variant_builder_add (descriptor_builder, error, "{sv}", "ostree.endianness", + g_variant_new_byte (endianness_char))) return FALSE; } part_headers = g_variant_builder_new (G_VARIANT_TYPE ("a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT)); - part_temp_paths = g_ptr_array_new_with_free_func ((GDestroyNotify)glnx_tmpfile_clear); for (i = 0; i < builder.parts->len; i++) { OstreeStaticDeltaPartBuilder *part_builder = builder.parts->pdata[i]; @@ -1509,12 +1431,14 @@ ostree_repo_static_delta_generate (OstreeRepo *self, lseek (part_builder->part_tmpf.fd, 0, SEEK_SET); - if (!ot_variant_builder_open (descriptor_builder, G_VARIANT_TYPE ("{sv}"), error) || - !ot_variant_builder_add (descriptor_builder, error, "s", part_relpath) || - !ot_variant_builder_open (descriptor_builder, G_VARIANT_TYPE ("v"), error) || - !ot_variant_builder_add_from_fd (descriptor_builder, G_VARIANT_TYPE ("(yay)"), part_builder->part_tmpf.fd, part_builder->compressed_size, error) || - !ot_variant_builder_close (descriptor_builder, error) || - !ot_variant_builder_close (descriptor_builder, error)) + if (!ot_variant_builder_open (descriptor_builder, G_VARIANT_TYPE ("{sv}"), error) + || !ot_variant_builder_add (descriptor_builder, error, "s", part_relpath) + || !ot_variant_builder_open (descriptor_builder, G_VARIANT_TYPE ("v"), error) + || !ot_variant_builder_add_from_fd (descriptor_builder, G_VARIANT_TYPE ("(yay)"), + part_builder->part_tmpf.fd, + part_builder->compressed_size, error) + || !ot_variant_builder_close (descriptor_builder, error) + || !ot_variant_builder_close (descriptor_builder, error)) return FALSE; } else @@ -1535,8 +1459,7 @@ ostree_repo_static_delta_generate (OstreeRepo *self, total_uncompressed_size += part_builder->uncompressed_size; } - if (!get_fallback_headers (self, &builder, &fallback_headers, - cancellable, error)) + if (!get_fallback_headers (self, &builder, &fallback_headers, cancellable, error)) return FALSE; if (!ostree_repo_read_commit_detached_metadata (self, to, &detached, cancellable, error)) @@ -1544,7 +1467,8 @@ ostree_repo_static_delta_generate (OstreeRepo *self, if (detached) { - g_autofree char *detached_key = _ostree_get_relative_static_delta_path (from, to, "commitmeta"); + g_autofree char *detached_key + = _ostree_get_relative_static_delta_path (from, to, "commitmeta"); if (!ot_variant_builder_add (descriptor_builder, error, "{sv}", detached_key, detached)) return FALSE; } @@ -1556,26 +1480,20 @@ ostree_repo_static_delta_generate (OstreeRepo *self, /* Generate OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */ { GDateTime *now = g_date_time_new_now_utc (); - /* floating */ GVariant *from_csum_v = - from ? ostree_checksum_to_bytes_v (from) : ot_gvariant_new_bytearray ((guchar *)"", 0); - /* floating */ GVariant *to_csum_v = - ostree_checksum_to_bytes_v (to); - + /* floating */ GVariant *from_csum_v + = from ? ostree_checksum_to_bytes_v (from) : ot_gvariant_new_bytearray ((guchar *)"", 0); + /* floating */ GVariant *to_csum_v = ostree_checksum_to_bytes_v (to); if (!ot_variant_builder_add (descriptor_builder, error, "t", - GUINT64_TO_BE (g_date_time_to_unix (now))) || - !ot_variant_builder_add_value (descriptor_builder, - from_csum_v, error) || - !ot_variant_builder_add_value (descriptor_builder, - to_csum_v, error) || - !ot_variant_builder_add_value (descriptor_builder, - to_commit, error) || - !ot_variant_builder_add_value (descriptor_builder, - ot_gvariant_new_bytearray ((guchar*)"", 0), error) || - !ot_variant_builder_add_value (descriptor_builder, - g_variant_builder_end (part_headers), error) || - !ot_variant_builder_add_value (descriptor_builder, - fallback_headers, error)) + GUINT64_TO_BE (g_date_time_to_unix (now))) + || !ot_variant_builder_add_value (descriptor_builder, from_csum_v, error) + || !ot_variant_builder_add_value (descriptor_builder, to_csum_v, error) + || !ot_variant_builder_add_value (descriptor_builder, to_commit, error) + || !ot_variant_builder_add_value (descriptor_builder, + ot_gvariant_new_bytearray ((guchar *)"", 0), error) + || !ot_variant_builder_add_value (descriptor_builder, g_variant_builder_end (part_headers), + error) + || !ot_variant_builder_add_value (descriptor_builder, fallback_headers, error)) return FALSE; if (!ot_variant_builder_end (descriptor_builder, error)) @@ -1586,24 +1504,23 @@ ostree_repo_static_delta_generate (OstreeRepo *self, if (delta_opts & DELTAOPT_FLAG_VERBOSE) { - g_printerr ("uncompressed=%" G_GUINT64_FORMAT " compressed=%" G_GUINT64_FORMAT " loose=%" G_GUINT64_FORMAT "\n", - total_uncompressed_size, - total_compressed_size, - builder.loose_compressed_size); - g_printerr ("rollsum=%u objects, %" G_GUINT64_FORMAT " bytes\n", - builder.n_rollsum, + g_printerr ("uncompressed=%" G_GUINT64_FORMAT " compressed=%" G_GUINT64_FORMAT + " loose=%" G_GUINT64_FORMAT "\n", + total_uncompressed_size, total_compressed_size, builder.loose_compressed_size); + g_printerr ("rollsum=%u objects, %" G_GUINT64_FORMAT " bytes\n", builder.n_rollsum, builder.rollsum_size); g_printerr ("bsdiff=%u objects\n", builder.n_bsdiff); } if (opt_sign_name != NULL && opt_key_ids != NULL) { - g_autoptr(GBytes) tmpdata = NULL; - g_autoptr(OstreeSign) sign = NULL; + g_autoptr (GBytes) tmpdata = NULL; + g_autoptr (OstreeSign) sign = NULL; const gchar *signature_key = NULL; - g_autoptr(GVariantBuilder) signature_builder = NULL; - g_auto(GLnxTmpfile) descriptor_sign_tmpf = { 0, }; - g_autoptr(OtVariantBuilder) descriptor_sign_builder = NULL; + g_autoptr (GVariantBuilder) signature_builder = NULL; + g_auto (GLnxTmpfile) descriptor_sign_tmpf = { + 0, + }; lseek (descriptor_tmpf.fd, 0, SEEK_SET); tmpdata = glnx_fd_readall_bytes (descriptor_tmpf.fd, cancellable, error); @@ -1622,36 +1539,38 @@ ostree_repo_static_delta_generate (OstreeRepo *self, for (const char **iter = opt_key_ids; iter && *iter; iter++) { const char *keyid = *iter; - g_autoptr(GVariant) secret_key = NULL; - g_autoptr(GBytes) signature_bytes = NULL; + g_autoptr (GVariant) secret_key = NULL; + g_autoptr (GBytes) signature_bytes = NULL; secret_key = g_variant_new_string (keyid); if (!ostree_sign_set_sk (sign, secret_key, error)) - return FALSE; + return FALSE; - if (!ostree_sign_data (sign, tmpdata, &signature_bytes, - NULL, error)) + if (!ostree_sign_data (sign, tmpdata, &signature_bytes, NULL, error)) return FALSE; - g_variant_builder_add (signature_builder, "@ay", ot_gvariant_new_ay_bytes (signature_bytes)); + g_variant_builder_add (signature_builder, "@ay", + ot_gvariant_new_ay_bytes (signature_bytes)); } if (!glnx_open_tmpfile_linkable_at (descriptor_dfd, ".", O_WRONLY | O_CLOEXEC, &descriptor_sign_tmpf, error)) return FALSE; - descriptor_sign_builder = ot_variant_builder_new (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SIGNED_FORMAT), - descriptor_sign_tmpf.fd); + g_autoptr (OtVariantBuilder) descriptor_sign_builder = ot_variant_builder_new ( + G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SIGNED_FORMAT), descriptor_sign_tmpf.fd); + g_assert (descriptor_sign_builder != NULL); if (!ot_variant_builder_add (descriptor_sign_builder, error, "t", GUINT64_TO_BE (OSTREE_STATIC_DELTA_SIGNED_MAGIC))) return FALSE; - if (!ot_variant_builder_add (descriptor_sign_builder, error, "@ay", ot_gvariant_new_ay_bytes (tmpdata))) + if (!ot_variant_builder_add (descriptor_sign_builder, error, "@ay", + ot_gvariant_new_ay_bytes (tmpdata))) return FALSE; if (!ot_variant_builder_open (descriptor_sign_builder, G_VARIANT_TYPE ("a{sv}"), error)) return FALSE; - if (!ot_variant_builder_add (descriptor_sign_builder, error, "{sv}", - signature_key, g_variant_builder_end(signature_builder))) + if (!ot_variant_builder_add (descriptor_sign_builder, error, "{sv}", signature_key, + g_variant_builder_end (signature_builder))) return FALSE; if (!ot_variant_builder_close (descriptor_sign_builder, error)) return FALSE; @@ -1662,8 +1581,8 @@ ostree_repo_static_delta_generate (OstreeRepo *self, if (fchmod (descriptor_sign_tmpf.fd, 0644) < 0) return glnx_throw_errno_prefix (error, "fchmod"); - if (!glnx_link_tmpfile_at (&descriptor_sign_tmpf, GLNX_LINK_TMPFILE_REPLACE, - descriptor_dfd, descriptor_name, error)) + if (!glnx_link_tmpfile_at (&descriptor_sign_tmpf, GLNX_LINK_TMPFILE_REPLACE, descriptor_dfd, + descriptor_name, error)) return FALSE; } else @@ -1671,8 +1590,8 @@ ostree_repo_static_delta_generate (OstreeRepo *self, if (fchmod (descriptor_tmpf.fd, 0644) < 0) return glnx_throw_errno_prefix (error, "fchmod"); - if (!glnx_link_tmpfile_at (&descriptor_tmpf, GLNX_LINK_TMPFILE_REPLACE, - descriptor_dfd, descriptor_name, error)) + if (!glnx_link_tmpfile_at (&descriptor_tmpf, GLNX_LINK_TMPFILE_REPLACE, descriptor_dfd, + descriptor_name, error)) return FALSE; } diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c index 7854211..dc57a2f 100644 --- a/src/libostree/ostree-repo-static-delta-core.c +++ b/src/libostree/ostree-repo-static-delta-core.c @@ -19,31 +19,28 @@ #include "config.h" -#include -#include -#include +#include "ostree-checksum-input-stream.h" +#include "ostree-cmd-private.h" #include "ostree-core-private.h" -#include "ostree-repo-private.h" #include "ostree-lzma-decompressor.h" -#include "ostree-cmd-private.h" -#include "ostree-checksum-input-stream.h" +#include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" #include "otutil.h" +#include +#include +#include gboolean -_ostree_static_delta_parse_checksum_array (GVariant *array, - guint8 **out_checksums_array, - guint *out_n_checksums, - GError **error) +_ostree_static_delta_parse_checksum_array (GVariant *array, guint8 **out_checksums_array, + guint *out_n_checksums, GError **error) { const gsize n = g_variant_n_children (array); const guint n_checksums = n / OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN; - if (G_UNLIKELY(n > (G_MAXUINT32/OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN) || - (n_checksums * OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN) != n)) + if (G_UNLIKELY (n > (G_MAXUINT32 / OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN) + || (n_checksums * OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN) != n)) { - return glnx_throw (error, - "Invalid checksum array length %" G_GSIZE_FORMAT, n); + return glnx_throw (error, "Invalid checksum array length %" G_GSIZE_FORMAT, n); } *out_checksums_array = (gpointer)g_variant_get_data (array); @@ -53,20 +50,18 @@ _ostree_static_delta_parse_checksum_array (GVariant *array, } GVariant * -_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, - const char *from, - const char *to, - GCancellable *cancellable, - GError **error) +_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, const char *from, const char *to, + GCancellable *cancellable, GError **error) { - g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to); + g_autofree char *superblock + = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to); glnx_autofd int superblock_file_fd = -1; guint8 digest[OSTREE_SHA256_DIGEST_LEN]; if (!glnx_openat_rdonly (repo->repo_dir_fd, superblock, TRUE, &superblock_file_fd, error)) return NULL; - g_autoptr(GBytes) superblock_content = ot_fd_readall_or_mmap (superblock_file_fd, 0, error); + g_autoptr (GBytes) superblock_content = ot_fd_readall_or_mmap (superblock_file_fd, 0, error); if (!superblock_content) return NULL; @@ -78,7 +73,8 @@ _ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, /** * ostree_repo_list_static_delta_names: * @self: Repo - * @out_deltas: (out) (element-type utf8) (transfer container): String name of deltas (checksum-checksum.delta) + * @out_deltas: (out) (element-type utf8) (transfer container): String name of deltas + * (checksum-checksum.delta) * @cancellable: Cancellable * @error: Error * @@ -86,17 +82,16 @@ _ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, * repository, returning its result in @out_deltas. */ gboolean -ostree_repo_list_static_delta_names (OstreeRepo *self, - GPtrArray **out_deltas, - GCancellable *cancellable, - GError **error) +ostree_repo_list_static_delta_names (OstreeRepo *self, GPtrArray **out_deltas, + GCancellable *cancellable, GError **error) { - g_autoptr(GPtrArray) ret_deltas = g_ptr_array_new_with_free_func (g_free); + g_autoptr (GPtrArray) ret_deltas = g_ptr_array_new_with_free_func (g_free); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; gboolean exists; - if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, "deltas", &dfd_iter, - &exists, error)) + if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, "deltas", &dfd_iter, &exists, error)) return FALSE; if (!exists) { @@ -107,7 +102,9 @@ ostree_repo_list_static_delta_names (OstreeRepo *self, while (TRUE) { - g_auto(GLnxDirFdIterator) sub_dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) sub_dfd_iter = { + 0, + }; struct dirent *dent; if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) @@ -117,15 +114,14 @@ ostree_repo_list_static_delta_names (OstreeRepo *self, if (dent->d_type != DT_DIR) continue; - if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, - &sub_dfd_iter, error)) + if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, &sub_dfd_iter, error)) return FALSE; while (TRUE) { struct dirent *sub_dent; - if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent, - cancellable, error)) + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent, cancellable, + error)) return FALSE; if (sub_dent == NULL) break; @@ -143,7 +139,7 @@ ostree_repo_list_static_delta_names (OstreeRepo *self, g_autofree char *buf = g_strconcat (name1, name2, NULL); GString *out = g_string_new (""); - char checksum[OSTREE_SHA256_STRING_LEN+1]; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; guchar csum[OSTREE_SHA256_DIGEST_LEN]; const char *dash = strchr (buf, '-'); @@ -153,7 +149,7 @@ ostree_repo_list_static_delta_names (OstreeRepo *self, if (dash) { g_string_append_c (out, '-'); - ostree_checksum_b64_inplace_to_bytes (dash+1, csum); + ostree_checksum_b64_inplace_to_bytes (dash + 1, csum); ostree_checksum_inplace_from_bytes (csum, checksum); g_string_append (out, checksum); } @@ -169,7 +165,8 @@ ostree_repo_list_static_delta_names (OstreeRepo *self, /** * ostree_repo_list_static_delta_indexes: * @self: Repo - * @out_indexes: (out) (element-type utf8) (transfer container): String name of delta indexes (checksum) + * @out_indexes: (out) (element-type utf8) (transfer container): String name of delta indexes + * (checksum) * @cancellable: Cancellable * @error: Error * @@ -179,17 +176,16 @@ ostree_repo_list_static_delta_names (OstreeRepo *self, * Since: 2020.8 */ gboolean -ostree_repo_list_static_delta_indexes (OstreeRepo *self, - GPtrArray **out_indexes, - GCancellable *cancellable, - GError **error) +ostree_repo_list_static_delta_indexes (OstreeRepo *self, GPtrArray **out_indexes, + GCancellable *cancellable, GError **error) { - g_autoptr(GPtrArray) ret_indexes = g_ptr_array_new_with_free_func (g_free); + g_autoptr (GPtrArray) ret_indexes = g_ptr_array_new_with_free_func (g_free); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; gboolean exists; - if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, "delta-indexes", &dfd_iter, - &exists, error)) + if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, "delta-indexes", &dfd_iter, &exists, error)) return FALSE; if (!exists) { @@ -200,7 +196,9 @@ ostree_repo_list_static_delta_indexes (OstreeRepo *self, while (TRUE) { - g_auto(GLnxDirFdIterator) sub_dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) sub_dfd_iter = { + 0, + }; struct dirent *dent; if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) @@ -212,16 +210,15 @@ ostree_repo_list_static_delta_indexes (OstreeRepo *self, if (strlen (dent->d_name) != 2) continue; - if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, - &sub_dfd_iter, error)) + if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, &sub_dfd_iter, error)) return FALSE; while (TRUE) { struct dirent *sub_dent; - if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent, - cancellable, error)) + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent, cancellable, + error)) return FALSE; if (sub_dent == NULL) break; @@ -232,14 +229,13 @@ ostree_repo_list_static_delta_indexes (OstreeRepo *self, const char *name2 = sub_dent->d_name; /* base64 len is 43, but 2 chars are in the parent dir name */ - if (strlen (name2) != 41 + strlen(".index") || - !g_str_has_suffix (name2, ".index")) + if (strlen (name2) != 41 + strlen (".index") || !g_str_has_suffix (name2, ".index")) continue; - g_autoptr(GString) out = g_string_new (name1); + g_autoptr (GString) out = g_string_new (name1); g_string_append_len (out, name2, 41); - char checksum[OSTREE_SHA256_STRING_LEN+1]; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; guchar csum[OSTREE_SHA256_DIGEST_LEN]; ostree_checksum_b64_inplace_to_bytes (out->str, csum); @@ -254,19 +250,15 @@ ostree_repo_list_static_delta_indexes (OstreeRepo *self, } gboolean -_ostree_repo_static_delta_part_have_all_objects (OstreeRepo *repo, - GVariant *checksum_array, - gboolean *out_have_all, - GCancellable *cancellable, - GError **error) +_ostree_repo_static_delta_part_have_all_objects (OstreeRepo *repo, GVariant *checksum_array, + gboolean *out_have_all, GCancellable *cancellable, + GError **error) { guint8 *checksums_data = NULL; guint n_checksums = 0; gboolean have_object = TRUE; - if (!_ostree_static_delta_parse_checksum_array (checksum_array, - &checksums_data, - &n_checksums, + if (!_ostree_static_delta_parse_checksum_array (checksum_array, &checksums_data, &n_checksums, error)) return FALSE; @@ -274,15 +266,15 @@ _ostree_repo_static_delta_part_have_all_objects (OstreeRepo *repo, { guint8 objtype = *checksums_data; const guint8 *csum = checksums_data + 1; - char tmp_checksum[OSTREE_SHA256_STRING_LEN+1]; + char tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; - if (G_UNLIKELY(!ostree_validate_structureof_objtype (objtype, error))) + if (G_UNLIKELY (!ostree_validate_structureof_objtype (objtype, error))) return FALSE; ostree_checksum_inplace_from_bytes (csum, tmp_checksum); - if (!ostree_repo_has_object (repo, (OstreeObjectType) objtype, tmp_checksum, - &have_object, cancellable, error)) + if (!ostree_repo_has_object (repo, (OstreeObjectType)objtype, tmp_checksum, &have_object, + cancellable, error)) return FALSE; if (!have_object) @@ -296,23 +288,22 @@ _ostree_repo_static_delta_part_have_all_objects (OstreeRepo *repo, } static gboolean -_ostree_repo_static_delta_is_signed (OstreeRepo *self, - int fd, - GPtrArray **out_value, - GError **error) +_ostree_repo_static_delta_is_signed (OstreeRepo *self, int fd, GPtrArray **out_value, + GError **error) { - g_autoptr(GVariant) delta = NULL; - g_autoptr(GVariant) delta_sign_magic = NULL; - g_autoptr(GVariant) delta_sign = NULL; + g_autoptr (GVariant) delta = NULL; + g_autoptr (GVariant) delta_sign_magic = NULL; + g_autoptr (GVariant) delta_sign = NULL; GVariantIter iter; GVariant *item; - g_autoptr(GPtrArray) signatures = NULL; + g_autoptr (GPtrArray) signatures = NULL; gboolean ret = FALSE; if (out_value) *out_value = NULL; - if (!ot_variant_read_fd (fd, 0, (GVariantType*)OSTREE_STATIC_DELTA_SIGNED_FORMAT, TRUE, &delta, error)) + if (!ot_variant_read_fd (fd, 0, (GVariantType *)OSTREE_STATIC_DELTA_SIGNED_FORMAT, TRUE, &delta, + error)) return FALSE; delta_sign_magic = g_variant_get_child_value (delta, 0); @@ -333,7 +324,7 @@ _ostree_repo_static_delta_is_signed (OstreeRepo *self, g_variant_iter_init (&iter, delta_sign); while ((item = g_variant_iter_next_value (&iter))) { - g_autoptr(GVariant) key_v = g_variant_get_child_value (item, 0); + g_autoptr (GVariant) key_v = g_variant_get_child_value (item, 0); const char *str = g_variant_get_string (key_v, NULL); if (g_str_has_prefix (str, "ostree.sign.")) { @@ -351,36 +342,31 @@ _ostree_repo_static_delta_is_signed (OstreeRepo *self, } static gboolean -_ostree_repo_static_delta_verify_signature (OstreeRepo *self, - int fd, - OstreeSign *sign, - char **out_success_message, - GError **error) +_ostree_repo_static_delta_verify_signature (OstreeRepo *self, int fd, OstreeSign *sign, + char **out_success_message, GError **error) { - g_autoptr(GVariant) delta = NULL; + g_autoptr (GVariant) delta = NULL; - if (!ot_variant_read_fd (fd, 0, - (GVariantType*)OSTREE_STATIC_DELTA_SIGNED_FORMAT, - TRUE, &delta, error)) + if (!ot_variant_read_fd (fd, 0, (GVariantType *)OSTREE_STATIC_DELTA_SIGNED_FORMAT, TRUE, &delta, + error)) return FALSE; /* Check if there are signatures for signature engine */ - const gchar *signature_key = ostree_sign_metadata_key(sign); - GVariantType *signature_format = (GVariantType *) ostree_sign_metadata_format(sign); - g_autoptr(GVariant) delta_meta = g_variant_get_child_value (delta, 2); + const gchar *signature_key = ostree_sign_metadata_key (sign); + GVariantType *signature_format = (GVariantType *)ostree_sign_metadata_format (sign); + g_autoptr (GVariant) delta_meta = g_variant_get_child_value (delta, 2); if (delta_meta == NULL) return glnx_throw (error, "no metadata in static-delta superblock"); - g_autoptr(GVariant) signatures = g_variant_lookup_value (delta_meta, - signature_key, - signature_format); + g_autoptr (GVariant) signatures + = g_variant_lookup_value (delta_meta, signature_key, signature_format); if (!signatures) return glnx_throw (error, "no signature for '%s' in static-delta superblock", signature_key); /* Get static delta superblock */ - g_autoptr(GVariant) child = g_variant_get_child_value (delta, 1); + g_autoptr (GVariant) child = g_variant_get_child_value (delta, 1); if (child == NULL) return glnx_throw (error, "no metadata in static-delta superblock"); - g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes(child); + g_autoptr (GBytes) signed_data = g_variant_get_data_as_bytes (child); return ostree_sign_data_verify (sign, signed_data, signatures, out_success_message, error); } @@ -406,15 +392,12 @@ _ostree_repo_static_delta_verify_signature (OstreeRepo *self, * Since: 2020.7 */ gboolean -ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, - GFile *dir_or_file, - OstreeSign *sign, - gboolean skip_validation, - GCancellable *cancellable, - GError **error) +ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, GFile *dir_or_file, + OstreeSign *sign, gboolean skip_validation, + GCancellable *cancellable, GError **error) { g_autofree char *basename = NULL; - g_autoptr(GVariant) meta = NULL; + g_autoptr (GVariant) meta = NULL; const char *dir_or_file_path = gs_file_get_path_cached (dir_or_file); @@ -446,8 +429,8 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, gboolean verify_deltas; gboolean verified; - if (!ot_keyfile_get_boolean_with_default (self->config, "core", "sign-verify-deltas", - FALSE, &verify_deltas, error)) + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "sign-verify-deltas", FALSE, + &verify_deltas, error)) return FALSE; if (verify_deltas && !sign) @@ -455,9 +438,10 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, if (sign) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; - verified = _ostree_repo_static_delta_verify_signature (self, meta_fd, sign, NULL, &local_error); + verified = _ostree_repo_static_delta_verify_signature (self, meta_fd, sign, NULL, + &local_error); if (local_error != NULL) { g_propagate_error (error, g_steal_pointer (&local_error)); @@ -468,15 +452,15 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, return glnx_throw (error, "Delta signature verification failed"); } - g_autoptr(GVariant) delta = NULL; - if (!ot_variant_read_fd (meta_fd, 0, (GVariantType*)OSTREE_STATIC_DELTA_SIGNED_FORMAT, - TRUE, &delta, error)) + g_autoptr (GVariant) delta = NULL; + if (!ot_variant_read_fd (meta_fd, 0, (GVariantType *)OSTREE_STATIC_DELTA_SIGNED_FORMAT, TRUE, + &delta, error)) return FALSE; - g_autoptr(GVariant) child = g_variant_get_child_value (delta, 1); - g_autoptr(GBytes) bytes = g_variant_get_data_as_bytes (child); - meta = g_variant_new_from_bytes ((GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, - bytes, FALSE); + g_autoptr (GVariant) child = g_variant_get_child_value (delta, 1); + g_autoptr (GBytes) bytes = g_variant_get_data_as_bytes (child); + meta = g_variant_new_from_bytes ((GVariantType *)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, bytes, + FALSE); } else { @@ -487,15 +471,15 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, /* Parsing OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */ - g_autoptr(GVariant) metadata = g_variant_get_child_value (meta, 0); + g_autoptr (GVariant) metadata = g_variant_get_child_value (meta, 0); g_autofree char *to_checksum = NULL; g_autofree char *from_checksum = NULL; /* Write the to-commit object */ { - g_autoptr(GVariant) to_csum_v = NULL; - g_autoptr(GVariant) from_csum_v = NULL; - g_autoptr(GVariant) to_commit = NULL; + g_autoptr (GVariant) to_csum_v = NULL; + g_autoptr (GVariant) from_csum_v = NULL; + g_autoptr (GVariant) to_commit = NULL; gboolean have_to_commit; gboolean have_from_commit; @@ -516,59 +500,59 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, return FALSE; if (!have_from_commit) - return glnx_throw (error, "Commit %s, which is the delta source, is not in repository", from_checksum); + return glnx_throw (error, "Commit %s, which is the delta source, is not in repository", + from_checksum); } - if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, to_checksum, - &have_to_commit, cancellable, error)) + if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, to_checksum, &have_to_commit, + cancellable, error)) return FALSE; if (!have_to_commit) { - g_autofree char *detached_path = _ostree_get_relative_static_delta_path (from_checksum, to_checksum, "commitmeta"); - g_autoptr(GVariant) detached_data = - g_variant_lookup_value (metadata, detached_path, G_VARIANT_TYPE("a{sv}")); - if (detached_data && !ostree_repo_write_commit_detached_metadata (self, - to_checksum, - detached_data, - cancellable, - error)) + g_autofree char *detached_path + = _ostree_get_relative_static_delta_path (from_checksum, to_checksum, "commitmeta"); + g_autoptr (GVariant) detached_data + = g_variant_lookup_value (metadata, detached_path, G_VARIANT_TYPE ("a{sv}")); + if (detached_data + && !ostree_repo_write_commit_detached_metadata (self, to_checksum, detached_data, + cancellable, error)) return FALSE; to_commit = g_variant_get_child_value (meta, 4); - if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_COMMIT, - to_checksum, to_commit, NULL, - cancellable, error)) + if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_COMMIT, to_checksum, to_commit, + NULL, cancellable, error)) return FALSE; } } - g_autoptr(GVariant) fallback = g_variant_get_child_value (meta, 7); + g_autoptr (GVariant) fallback = g_variant_get_child_value (meta, 7); if (g_variant_n_children (fallback) > 0) - return glnx_throw (error, "Cannot execute delta offline: contains nonempty http fallback entries"); + return glnx_throw (error, + "Cannot execute delta offline: contains nonempty http fallback entries"); - g_autoptr(GVariant) headers = g_variant_get_child_value (meta, 6); + g_autoptr (GVariant) headers = g_variant_get_child_value (meta, 6); const guint n = g_variant_n_children (headers); for (guint i = 0; i < n; i++) { guint32 version; guint64 size; guint64 usize; - char checksum[OSTREE_SHA256_STRING_LEN+1]; - g_autoptr(GVariant) csum_v = NULL; - g_autoptr(GVariant) objects = NULL; - g_autoptr(GVariant) part = NULL; - OstreeStaticDeltaOpenFlags delta_open_flags = - skip_validation ? OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM : 0; - g_autoptr(GVariant) header = g_variant_get_child_value (headers, i); + char checksum[OSTREE_SHA256_STRING_LEN + 1]; + g_autoptr (GVariant) csum_v = NULL; + g_autoptr (GVariant) objects = NULL; + g_autoptr (GVariant) part = NULL; + OstreeStaticDeltaOpenFlags delta_open_flags + = skip_validation ? OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM : 0; + g_autoptr (GVariant) header = g_variant_get_child_value (headers, i); g_variant_get (header, "(u@aytt@ay)", &version, &csum_v, &size, &usize, &objects); if (version > OSTREE_DELTAPART_VERSION) return glnx_throw (error, "Delta part has too new version %u", version); gboolean have_all; - if (!_ostree_repo_static_delta_part_have_all_objects (self, objects, &have_all, - cancellable, error)) + if (!_ostree_repo_static_delta_part_have_all_objects (self, objects, &have_all, cancellable, + error)) return FALSE; /* If we already have these objects, don't bother executing the @@ -582,14 +566,15 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, return FALSE; ostree_checksum_inplace_from_bytes (csum, checksum); - g_autofree char *deltapart_path = - _ostree_get_relative_static_delta_part_path (from_checksum, to_checksum, i); + g_autofree char *deltapart_path + = _ostree_get_relative_static_delta_part_path (from_checksum, to_checksum, i); - g_autoptr(GInputStream) part_in = NULL; - g_autoptr(GVariant) inline_part_data = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE("(yay)")); + g_autoptr (GInputStream) part_in = NULL; + g_autoptr (GVariant) inline_part_data + = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE ("(yay)")); if (inline_part_data) { - g_autoptr(GBytes) inline_part_bytes = g_variant_get_data_as_bytes (inline_part_data); + g_autoptr (GBytes) inline_part_bytes = g_variant_get_data_as_bytes (inline_part_data); part_in = g_memory_input_stream_new_from_bytes (inline_part_bytes); /* For inline parts, we don't checksum, because it's @@ -599,11 +584,8 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, */ delta_open_flags |= OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM; - if (!_ostree_static_delta_part_open (part_in, inline_part_bytes, - delta_open_flags, - NULL, - &part, - cancellable, error)) + if (!_ostree_static_delta_part_open (part_in, inline_part_bytes, delta_open_flags, NULL, + &part, cancellable, error)) return FALSE; } else @@ -615,16 +597,13 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, part_in = g_unix_input_stream_new (part_fd, FALSE); - if (!_ostree_static_delta_part_open (part_in, NULL, - delta_open_flags, - checksum, - &part, + if (!_ostree_static_delta_part_open (part_in, NULL, delta_open_flags, checksum, &part, cancellable, error)) return FALSE; } - if (!_ostree_static_delta_part_execute (self, objects, part, skip_validation, - NULL, cancellable, error)) + if (!_ostree_static_delta_part_execute (self, objects, part, skip_validation, NULL, + cancellable, error)) return glnx_prefix_error (error, "Executing delta part %i", i); } @@ -645,26 +624,18 @@ ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, * must contain a file named "superblock", along with at least one part. */ gboolean -ostree_repo_static_delta_execute_offline (OstreeRepo *self, - GFile *dir_or_file, - gboolean skip_validation, - GCancellable *cancellable, - GError **error) +ostree_repo_static_delta_execute_offline (OstreeRepo *self, GFile *dir_or_file, + gboolean skip_validation, GCancellable *cancellable, + GError **error) { - return ostree_repo_static_delta_execute_offline_with_signature(self, dir_or_file, NULL, - skip_validation, - cancellable, - error); + return ostree_repo_static_delta_execute_offline_with_signature ( + self, dir_or_file, NULL, skip_validation, cancellable, error); } gboolean -_ostree_static_delta_part_open (GInputStream *part_in, - GBytes *inline_part_bytes, - OstreeStaticDeltaOpenFlags flags, - const char *expected_checksum, - GVariant **out_part, - GCancellable *cancellable, - GError **error) +_ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, + OstreeStaticDeltaOpenFlags flags, const char *expected_checksum, + GVariant **out_part, GCancellable *cancellable, GError **error) { const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; @@ -673,13 +644,13 @@ _ostree_static_delta_part_open (GInputStream *part_in, g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); - g_autoptr(GChecksum) checksum = NULL; - g_autoptr(GInputStream) checksum_in = NULL; + g_autoptr (GChecksum) checksum = NULL; + g_autoptr (GInputStream) checksum_in = NULL; GInputStream *source_in; if (!skip_checksum) { checksum = g_checksum_new (G_CHECKSUM_SHA256); - checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); + checksum_in = (GInputStream *)ostree_checksum_input_stream_new (part_in, checksum); source_in = checksum_in; } else @@ -688,52 +659,52 @@ _ostree_static_delta_part_open (GInputStream *part_in, } guint8 comptype; - { guint8 buf[1]; + { + guint8 buf[1]; gsize bytes_read; /* First byte is compression type */ - if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, - cancellable, error)) + if (!g_input_stream_read_all (source_in, buf, sizeof (buf), &bytes_read, cancellable, error)) return glnx_prefix_error (error, "Reading initial compression flag byte"); comptype = buf[0]; } - g_autoptr(GVariant) ret_part = NULL; + g_autoptr (GVariant) ret_part = NULL; switch (comptype) { case 0: if (!inline_part_bytes) { - int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); + int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased *)part_in); /* No compression, no checksums - a fast path */ - if (!ot_variant_read_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), + if (!ot_variant_read_fd (part_fd, 1, + G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) return FALSE; } else { - g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, - g_bytes_get_size (inline_part_bytes) - 1); - ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), - content_bytes, trusted); + g_autoptr (GBytes) content_bytes = g_bytes_new_from_bytes ( + inline_part_bytes, 1, g_bytes_get_size (inline_part_bytes) - 1); + ret_part = g_variant_new_from_bytes ( + G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), content_bytes, trusted); g_variant_ref_sink (ret_part); } if (!skip_checksum) - g_checksum_update (checksum, g_variant_get_data (ret_part), - g_variant_get_size (ret_part)); + g_checksum_update (checksum, g_variant_get_data (ret_part), g_variant_get_size (ret_part)); break; case 'x': { - g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); - g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); - g_autoptr(GBytes) buf = ot_map_anonymous_tmpfile_from_content (convin, cancellable, error); + g_autoptr (GConverter) decomp = (GConverter *)_ostree_lzma_decompressor_new (); + g_autoptr (GInputStream) convin = g_converter_input_stream_new (source_in, decomp); + g_autoptr (GBytes) buf = ot_map_anonymous_tmpfile_from_content (convin, cancellable, error); if (!buf) return FALSE; - ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), - buf, FALSE); + ret_part = g_variant_new_from_bytes ( + G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), buf, FALSE); } break; default: @@ -758,69 +729,57 @@ _ostree_static_delta_part_open (GInputStream *part_in, */ static gboolean -show_one_part (OstreeRepo *self, - gboolean swap_endian, - const char *from, - const char *to, - GVariant *meta_entries, - guint i, - guint64 *total_size_ref, - guint64 *total_usize_ref, - GCancellable *cancellable, - GError **error) +show_one_part (OstreeRepo *self, gboolean swap_endian, const char *from, const char *to, + GVariant *meta_entries, guint i, guint64 *total_size_ref, guint64 *total_usize_ref, + GCancellable *cancellable, GError **error) { g_autofree char *part_path = _ostree_get_relative_static_delta_part_path (from, to, i); guint32 version; guint64 size, usize; - g_autoptr(GVariant) objects = NULL; + g_autoptr (GVariant) objects = NULL; g_variant_get_child (meta_entries, i, "(u@aytt@ay)", &version, NULL, &size, &usize, &objects); size = maybe_swap_endian_u64 (swap_endian, size); usize = maybe_swap_endian_u64 (swap_endian, usize); *total_size_ref += size; *total_usize_ref += usize; - g_print ("PartMeta%u: nobjects=%u size=%" G_GUINT64_FORMAT " usize=%" G_GUINT64_FORMAT "\n", - i, (guint)(g_variant_get_size (objects) / OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN), size, usize); + g_print ("PartMeta%u: nobjects=%u size=%" G_GUINT64_FORMAT " usize=%" G_GUINT64_FORMAT "\n", i, + (guint)(g_variant_get_size (objects) / OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN), size, + usize); glnx_autofd int part_fd = openat (self->repo_dir_fd, part_path, O_RDONLY | O_CLOEXEC); if (part_fd < 0) return glnx_throw_errno_prefix (error, "openat(%s)", part_path); - g_autoptr(GInputStream) part_in = g_unix_input_stream_new (part_fd, FALSE); + g_autoptr (GInputStream) part_in = g_unix_input_stream_new (part_fd, FALSE); - g_autoptr(GVariant) part = NULL; - if (!_ostree_static_delta_part_open (part_in, NULL, - OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM, - NULL, - &part, - cancellable, error)) + g_autoptr (GVariant) part = NULL; + if (!_ostree_static_delta_part_open (part_in, NULL, OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM, + NULL, &part, cancellable, error)) return FALSE; - { g_autoptr(GVariant) modes = NULL; - g_autoptr(GVariant) xattrs = NULL; - g_autoptr(GVariant) blob = NULL; - g_autoptr(GVariant) ops = NULL; - OstreeDeltaExecuteStats stats = { { 0, }, }; - - g_variant_get (part, "(@a(uuu)@aa(ayay)@ay@ay)", - &modes, &xattrs, &blob, &ops); - - g_print ("PartPayload%u: nmodes=%" G_GUINT64_FORMAT - " nxattrs=%" G_GUINT64_FORMAT - " blobsize=%" G_GUINT64_FORMAT - " opsize=%" G_GUINT64_FORMAT - "\n", - i, - (guint64)g_variant_n_children (modes), - (guint64)g_variant_n_children (xattrs), - (guint64)g_variant_n_children (blob), - (guint64)g_variant_n_children (ops)); - - if (!_ostree_static_delta_part_execute (self, objects, - part, TRUE, - &stats, cancellable, error)) + { + g_autoptr (GVariant) modes = NULL; + g_autoptr (GVariant) xattrs = NULL; + g_autoptr (GVariant) blob = NULL; + g_autoptr (GVariant) ops = NULL; + OstreeDeltaExecuteStats stats = { + { + 0, + }, + }; + + g_variant_get (part, "(@a(uuu)@aa(ayay)@ay@ay)", &modes, &xattrs, &blob, &ops); + + g_print ("PartPayload%u: nmodes=%" G_GUINT64_FORMAT " nxattrs=%" G_GUINT64_FORMAT + " blobsize=%" G_GUINT64_FORMAT " opsize=%" G_GUINT64_FORMAT "\n", + i, (guint64)g_variant_n_children (modes), (guint64)g_variant_n_children (xattrs), + (guint64)g_variant_n_children (blob), (guint64)g_variant_n_children (ops)); + + if (!_ostree_static_delta_part_execute (self, objects, part, TRUE, &stats, cancellable, error)) return FALSE; - { const guint *n_ops = stats.n_ops_executed; + { + const guint *n_ops = stats.n_ops_executed; g_print ("PartPayloadOps%u: openspliceclose=%u open=%u write=%u setread=%u " "unsetread=%u close=%u bspatch=%u\n", i, n_ops[0], n_ops[1], n_ops[2], n_ops[3], n_ops[4], n_ops[5], n_ops[6]); @@ -831,11 +790,10 @@ show_one_part (OstreeRepo *self, } OstreeDeltaEndianness -_ostree_delta_get_endianness (GVariant *superblock, - gboolean *out_was_heuristic) +_ostree_delta_get_endianness (GVariant *superblock, gboolean *out_was_heuristic) { - g_autoptr(GVariant) delta_meta = g_variant_get_child_value (superblock, 0); - g_autoptr(GVariantDict) delta_metadict = g_variant_dict_new (delta_meta); + g_autoptr (GVariant) delta_meta = g_variant_get_child_value (superblock, 0); + g_autoptr (GVariantDict) delta_metadict = g_variant_dict_new (delta_meta); if (out_was_heuristic) *out_was_heuristic = FALSE; @@ -860,7 +818,8 @@ _ostree_delta_get_endianness (GVariant *superblock, guint64 total_size = 0; guint64 total_usize = 0; guint total_objects = 0; - { g_autoptr(GVariant) meta_entries = NULL; + { + g_autoptr (GVariant) meta_entries = NULL; gboolean is_byteswapped = FALSE; g_variant_get_child (superblock, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, &meta_entries); @@ -868,7 +827,7 @@ _ostree_delta_get_endianness (GVariant *superblock, for (guint i = 0; i < n_parts; i++) { - g_autoptr(GVariant) objects = NULL; + g_autoptr (GVariant) objects = NULL; guint64 size, usize; guint n_objects; @@ -881,9 +840,10 @@ _ostree_delta_get_endianness (GVariant *superblock, if (size > usize) { - double ratio = ((double)size)/((double)usize); + double ratio = ((double)size) / ((double)usize); - /* This should really never happen where compressing things makes it more than 50% bigger. + /* This should really never happen where compressing things makes it more than 50% + * bigger. */ if (ratio > 1.2) { @@ -939,10 +899,8 @@ _ostree_delta_needs_byteswap (GVariant *superblock) } gboolean -_ostree_repo_static_delta_delete (OstreeRepo *self, - const char *delta_id, - GCancellable *cancellable, - GError **error) +_ostree_repo_static_delta_delete (OstreeRepo *self, const char *delta_id, GCancellable *cancellable, + GError **error) { g_autofree char *from = NULL; g_autofree char *to = NULL; @@ -955,27 +913,23 @@ _ostree_repo_static_delta_delete (OstreeRepo *self, { if (errno == ENOENT) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Can't find delta %s", delta_id); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Can't find delta %s", delta_id); return FALSE; } else return glnx_throw_errno_prefix (error, "fstatat(%s)", deltadir); } - if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir, - cancellable, error)) + if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir, cancellable, error)) return FALSE; return TRUE; } gboolean -_ostree_repo_static_delta_query_exists (OstreeRepo *self, - const char *delta_id, - gboolean *out_exists, - GCancellable *cancellable, - GError **error) +_ostree_repo_static_delta_query_exists (OstreeRepo *self, const char *delta_id, + gboolean *out_exists, GCancellable *cancellable, + GError **error) { g_autofree char *from = NULL; g_autofree char *to = NULL; @@ -991,14 +945,12 @@ _ostree_repo_static_delta_query_exists (OstreeRepo *self, } gboolean -_ostree_repo_static_delta_dump (OstreeRepo *self, - const char *delta_id, - GCancellable *cancellable, - GError **error) +_ostree_repo_static_delta_dump (OstreeRepo *self, const char *delta_id, GCancellable *cancellable, + GError **error) { glnx_autofd int superblock_fd = -1; - g_autoptr(GVariant) delta = NULL; - g_autoptr(GVariant) delta_superblock = NULL; + g_autoptr (GVariant) delta = NULL; + g_autoptr (GVariant) delta_superblock = NULL; if (strchr (delta_id, '/')) { @@ -1012,34 +964,35 @@ _ostree_repo_static_delta_dump (OstreeRepo *self, if (!_ostree_parse_delta_name (delta_id, &from, &to, error)) return FALSE; - g_autofree char *superblock_path = _ostree_get_relative_static_delta_superblock_path (from, to); + g_autofree char *superblock_path + = _ostree_get_relative_static_delta_superblock_path (from, to); if (!glnx_openat_rdonly (self->repo_dir_fd, superblock_path, TRUE, &superblock_fd, error)) return FALSE; } - gboolean is_signed = _ostree_repo_static_delta_is_signed(self, superblock_fd, NULL, NULL); + gboolean is_signed = _ostree_repo_static_delta_is_signed (self, superblock_fd, NULL, NULL); if (is_signed) { - if (!ot_variant_read_fd (superblock_fd, 0, (GVariantType*)OSTREE_STATIC_DELTA_SIGNED_FORMAT, + if (!ot_variant_read_fd (superblock_fd, 0, (GVariantType *)OSTREE_STATIC_DELTA_SIGNED_FORMAT, TRUE, &delta, error)) return FALSE; - g_autoptr(GVariant) child = g_variant_get_child_value (delta, 1); - g_autoptr(GBytes) bytes = g_variant_get_data_as_bytes(child); - delta_superblock = g_variant_new_from_bytes ((GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, - bytes, FALSE); + g_autoptr (GVariant) child = g_variant_get_child_value (delta, 1); + g_autoptr (GBytes) bytes = g_variant_get_data_as_bytes (child); + delta_superblock = g_variant_new_from_bytes ( + (GVariantType *)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, bytes, FALSE); } else { if (!ot_variant_read_fd (superblock_fd, 0, - (GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, - TRUE, &delta_superblock, error)) + (GVariantType *)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, TRUE, + &delta_superblock, error)) return FALSE; } g_print ("Delta: %s\n", delta_id); g_print ("Signed: %s\n", is_signed ? "yes" : "no"); - g_autoptr(GVariant) from_commit_v = NULL; + g_autoptr (GVariant) from_commit_v = NULL; g_variant_get_child (delta_superblock, 2, "@ay", &from_commit_v); g_autofree char *from_commit = NULL; if (g_variant_n_children (from_commit_v) > 0) @@ -1053,7 +1006,7 @@ _ostree_repo_static_delta_dump (OstreeRepo *self, { g_print ("From \n"); } - g_autoptr(GVariant) to_commit_v = NULL; + g_autoptr (GVariant) to_commit_v = NULL; g_variant_get_child (delta_superblock, 3, "@ay", &to_commit_v); if (!ostree_checksum_bytes_peek_validate (to_commit_v, error)) return FALSE; @@ -1062,7 +1015,8 @@ _ostree_repo_static_delta_dump (OstreeRepo *self, gboolean swap_endian = FALSE; OstreeDeltaEndianness endianness; - { const char *endianness_description; + { + const char *endianness_description; gboolean was_heuristic; endianness = _ostree_delta_get_endianness (delta_superblock, &was_heuristic); @@ -1099,11 +1053,12 @@ _ostree_repo_static_delta_dump (OstreeRepo *self, g_variant_get_child (delta_superblock, 1, "t", &ts); g_print ("Timestamp: %" G_GUINT64_FORMAT "\n", GUINT64_FROM_BE (ts)); - g_autoptr(GVariant) recurse = NULL; + g_autoptr (GVariant) recurse = NULL; g_variant_get_child (delta_superblock, 5, "@ay", &recurse); - g_print ("Number of parents: %u\n", (guint)(g_variant_get_size (recurse) / (OSTREE_SHA256_DIGEST_LEN * 2))); + g_print ("Number of parents: %u\n", + (guint)(g_variant_get_size (recurse) / (OSTREE_SHA256_DIGEST_LEN * 2))); - g_autoptr(GVariant) fallback = NULL; + g_autoptr (GVariant) fallback = NULL; g_variant_get_child (delta_superblock, 7, "@a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT, &fallback); const guint n_fallback = g_variant_n_children (fallback); @@ -1114,8 +1069,8 @@ _ostree_repo_static_delta_dump (OstreeRepo *self, for (guint i = 0; i < n_fallback; i++) { guint64 size, usize; - g_autoptr(GVariant) checksum_v = NULL; - char checksum[OSTREE_SHA256_STRING_LEN+1]; + g_autoptr (GVariant) checksum_v = NULL; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; g_variant_get_child (fallback, i, "(y@aytt)", NULL, &checksum_v, &size, &usize); ostree_checksum_inplace_from_bytes (ostree_checksum_bytes_peek (checksum_v), checksum); size = maybe_swap_endian_u64 (swap_endian, size); @@ -1124,34 +1079,38 @@ _ostree_repo_static_delta_dump (OstreeRepo *self, total_fallback_size += size; total_fallback_usize += usize; } - { g_autofree char *sizestr = g_format_size (total_fallback_size); + { + g_autofree char *sizestr = g_format_size (total_fallback_size); g_autofree char *usizestr = g_format_size (total_fallback_usize); g_print ("Total Fallback Size: %" G_GUINT64_FORMAT " (%s)\n", total_fallback_size, sizestr); - g_print ("Total Fallback Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", total_fallback_usize, usizestr); + g_print ("Total Fallback Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", total_fallback_usize, + usizestr); } - g_autoptr(GVariant) meta_entries = NULL; + g_autoptr (GVariant) meta_entries = NULL; guint n_parts; - g_variant_get_child (delta_superblock, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, &meta_entries); + g_variant_get_child (delta_superblock, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, + &meta_entries); n_parts = g_variant_n_children (meta_entries); g_print ("Number of parts: %u\n", n_parts); for (guint i = 0; i < n_parts; i++) { - if (!show_one_part (self, swap_endian, from_commit, to_commit, meta_entries, i, - &total_size, &total_usize, - cancellable, error)) + if (!show_one_part (self, swap_endian, from_commit, to_commit, meta_entries, i, &total_size, + &total_usize, cancellable, error)) return FALSE; } - { g_autofree char *sizestr = g_format_size (total_size); + { + g_autofree char *sizestr = g_format_size (total_size); g_autofree char *usizestr = g_format_size (total_usize); g_print ("Total Part Size: %" G_GUINT64_FORMAT " (%s)\n", total_size, sizestr); g_print ("Total Part Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", total_usize, usizestr); } - { guint64 overall_size = total_size + total_fallback_size; + { + guint64 overall_size = total_size + total_fallback_size; guint64 overall_usize = total_usize + total_fallback_usize; g_autofree char *sizestr = g_format_size (overall_size); g_autofree char *usizestr = g_format_size (overall_usize); @@ -1178,13 +1137,10 @@ _ostree_repo_static_delta_dump (OstreeRepo *self, * Since: 2020.7 */ gboolean -ostree_repo_static_delta_verify_signature (OstreeRepo *self, - const char *delta_id, - OstreeSign *sign, - char **out_success_message, - GError **error) +ostree_repo_static_delta_verify_signature (OstreeRepo *self, const char *delta_id, OstreeSign *sign, + char **out_success_message, GError **error) { - g_autoptr(GVariant) delta_meta = NULL; + g_autoptr (GVariant) delta_meta = NULL; glnx_autofd int delta_fd = -1; if (strchr (delta_id, '/')) @@ -1207,7 +1163,8 @@ ostree_repo_static_delta_verify_signature (OstreeRepo *self, if (!_ostree_repo_static_delta_is_signed (self, delta_fd, NULL, error)) return FALSE; - return _ostree_repo_static_delta_verify_signature (self, delta_fd, sign, out_success_message, error); + return _ostree_repo_static_delta_verify_signature (self, delta_fd, sign, out_success_message, + error); } static void @@ -1218,10 +1175,7 @@ null_or_ptr_array_unref (GPtrArray *array) } static gboolean -file_has_content (OstreeRepo *repo, - const char *subpath, - GBytes *data, - GCancellable *cancellable) +file_has_content (OstreeRepo *repo, const char *subpath, GBytes *data, GCancellable *cancellable) { struct stat stbuf; glnx_autofd int existing_fd = -1; @@ -1235,7 +1189,7 @@ file_has_content (OstreeRepo *repo, if (!glnx_openat_rdonly (repo->repo_dir_fd, subpath, TRUE, &existing_fd, NULL)) return FALSE; - g_autoptr(GBytes) existing_data = glnx_fd_readall_bytes (existing_fd, cancellable, NULL); + g_autoptr (GBytes) existing_data = glnx_fd_readall_bytes (existing_fd, cancellable, NULL); if (existing_data == NULL) return FALSE; @@ -1255,48 +1209,48 @@ file_has_content (OstreeRepo *repo, * a particular commit (if @opt_to_commit is non-%NULL), or for all commits that * are reachable by an existing delta (if @opt_to_commit is %NULL). * - * This is normally called automatically when the summary is updated in ostree_repo_regenerate_summary(). + * This is normally called automatically when the summary is updated in + * ostree_repo_regenerate_summary(). * * Locking: shared * * Since: 2020.8 */ gboolean -ostree_repo_static_delta_reindex (OstreeRepo *repo, - OstreeStaticDeltaIndexFlags flags, - const char *opt_to_commit, - GCancellable *cancellable, - GError **error) +ostree_repo_static_delta_reindex (OstreeRepo *repo, OstreeStaticDeltaIndexFlags flags, + const char *opt_to_commit, GCancellable *cancellable, + GError **error) { - g_autoptr(GPtrArray) all_deltas = NULL; - g_autoptr(GHashTable) deltas_to_commit_ht = NULL; /* map: to checksum -> ptrarray of from checksums (or NULL) */ + g_autoptr (GPtrArray) all_deltas = NULL; + g_autoptr (GHashTable) deltas_to_commit_ht + = NULL; /* map: to checksum -> ptrarray of from checksums (or NULL) */ gboolean opt_indexed_deltas; /* Protect against parallel prune operation */ - g_autoptr(OstreeRepoAutoLock) lock = - ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, cancellable, error); + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, cancellable, error); if (!lock) return FALSE; /* Enusre that the "indexed-deltas" option is set on the config, so we know this when pulling */ - if (!ot_keyfile_get_boolean_with_default (repo->config, "core", - "indexed-deltas", FALSE, + if (!ot_keyfile_get_boolean_with_default (repo->config, "core", "indexed-deltas", FALSE, &opt_indexed_deltas, error)) return FALSE; if (!opt_indexed_deltas) { - g_autoptr(GKeyFile) config = ostree_repo_copy_config (repo); + g_autoptr (GKeyFile) config = ostree_repo_copy_config (repo); g_key_file_set_boolean (config, "core", "indexed-deltas", TRUE); if (!ostree_repo_write_config (repo, config, error)) return FALSE; } - deltas_to_commit_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)null_or_ptr_array_unref); + deltas_to_commit_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify)null_or_ptr_array_unref); if (opt_to_commit == NULL) { - g_autoptr(GPtrArray) old_indexes = NULL; + g_autoptr (GPtrArray) old_indexes = NULL; /* To ensure all old index files either is regenerated, or * removed, we initialize all existing indexes to NULL in the @@ -1345,7 +1299,7 @@ ostree_repo_static_delta_reindex (OstreeRepo *repo, g_ptr_array_add (deltas_to_commit, g_steal_pointer (&from)); } - GLNX_HASH_TABLE_FOREACH_KV (deltas_to_commit_ht, const char*, to, GPtrArray*, froms) + GLNX_HASH_TABLE_FOREACH_KV (deltas_to_commit_ht, const char *, to, GPtrArray *, froms) { g_autofree char *index_path = _ostree_get_relative_static_delta_index_path (to); @@ -1359,10 +1313,10 @@ ostree_repo_static_delta_reindex (OstreeRepo *repo, } else { - g_auto(GVariantDict) index_builder = OT_VARIANT_BUILDER_INITIALIZER; - g_auto(GVariantDict) deltas_builder = OT_VARIANT_BUILDER_INITIALIZER; - g_autoptr(GVariant) index_variant = NULL; - g_autoptr(GBytes) index = NULL; + g_auto (GVariantDict) index_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantDict) deltas_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_autoptr (GVariant) index_variant = NULL; + g_autoptr (GBytes) index = NULL; /* We sort on from here so that the index file is reproducible */ g_ptr_array_sort (froms, (GCompareFunc)g_strcmp0); @@ -1375,7 +1329,8 @@ ostree_repo_static_delta_reindex (OstreeRepo *repo, g_autofree char *delta_name = NULL; GVariant *digest; - digest = _ostree_repo_static_delta_superblock_digest (repo, from, to, cancellable, error); + digest = _ostree_repo_static_delta_superblock_digest (repo, from, to, cancellable, + error); if (digest == NULL) return FALSE; @@ -1387,28 +1342,31 @@ ostree_repo_static_delta_reindex (OstreeRepo *repo, g_variant_dict_insert_value (&deltas_builder, delta_name, digest); } - /* The toplevel of the index is an a{sv} for extensibility, and we use same key name (and format) as when - * storing deltas in the summary. */ + /* The toplevel of the index is an a{sv} for extensibility, and we use same key name (and + * format) as when storing deltas in the summary. */ g_variant_dict_init (&index_builder, NULL); - g_variant_dict_insert_value (&index_builder, OSTREE_SUMMARY_STATIC_DELTAS, g_variant_dict_end (&deltas_builder)); + g_variant_dict_insert_value (&index_builder, OSTREE_SUMMARY_STATIC_DELTAS, + g_variant_dict_end (&deltas_builder)); index_variant = g_variant_ref_sink (g_variant_dict_end (&index_builder)); index = g_variant_get_data_as_bytes (index_variant); g_autofree char *index_dirname = g_path_get_dirname (index_path); - if (!glnx_shutil_mkdir_p_at (repo->repo_dir_fd, index_dirname, DEFAULT_DIRECTORY_MODE, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (repo->repo_dir_fd, index_dirname, DEFAULT_DIRECTORY_MODE, + cancellable, error)) return FALSE; - /* delta indexes are generally small and static, so reading it back and comparing is cheap, and it will - lower the write load (and particular sync-load) on the disk during reindexing (i.e. summary updates), */ + /* delta indexes are generally small and static, so reading it back and comparing is + cheap, and it will lower the write load (and particular sync-load) on the disk during + reindexing (i.e. summary updates), */ if (file_has_content (repo, index_path, index, cancellable)) continue; g_debug ("Updating delta index for %s", to); if (!glnx_file_replace_contents_at (repo->repo_dir_fd, index_path, - g_bytes_get_data (index, NULL), g_bytes_get_size (index), - 0, cancellable, error)) + g_bytes_get_data (index, NULL), + g_bytes_get_size (index), 0, cancellable, error)) return FALSE; } } diff --git a/src/libostree/ostree-repo-static-delta-private.h b/src/libostree/ostree-repo-static-delta-private.h index ccc0ad0..72208c2 100644 --- a/src/libostree/ostree-repo-static-delta-private.h +++ b/src/libostree/ostree-repo-static-delta-private.h @@ -24,7 +24,7 @@ G_BEGIN_DECLS /* Arbitrarily chosen */ -#define OSTREE_STATIC_DELTA_PART_MAX_SIZE_BYTES (16*1024*1024) +#define OSTREE_STATIC_DELTA_PART_MAX_SIZE_BYTES (16 * 1024 * 1024) /* 1 byte for object type, 32 bytes for checksum */ #define OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN 33 @@ -57,7 +57,6 @@ G_BEGIN_DECLS #define OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "(uayttay)" - /** * OSTREE_STATIC_DELTA_FALLBACK_FORMAT: * @@ -88,7 +87,7 @@ G_BEGIN_DECLS * * The metadata would include things like a version number, as well as * extended verification data like a GPG signature. - * + * * The second array is an array of delta objects that should be * fetched and applied before this one. This is a fairly generic * recursion mechanism that would potentially allow saving significant @@ -99,8 +98,10 @@ G_BEGIN_DECLS * Finally, we have the fallback array, which is the set of objects to * fetch individually - the compiler determined it wasn't worth * duplicating the space. - */ -#define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")" + */ +#define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT \ + "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT \ + "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")" /** * OSTREE_STATIC_DELTA_SIGNED_FORMAT @@ -119,15 +120,17 @@ G_BEGIN_DECLS */ #define OSTREE_STATIC_DELTA_SIGNED_FORMAT "(taya{sv})" -#define OSTREE_STATIC_DELTA_SIGNED_MAGIC 0x4F535453474E4454 /* OSTSGNDT */ +#define OSTREE_STATIC_DELTA_SIGNED_MAGIC 0x4F535453474E4454 /* OSTSGNDT */ -typedef enum { +typedef enum +{ OSTREE_STATIC_DELTA_OPEN_FLAGS_NONE = 0, OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM = (1 << 0), OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED = (1 << 1) } OstreeStaticDeltaOpenFlags; -typedef enum { +typedef enum +{ OSTREE_STATIC_DELTA_OP_OPEN_SPLICE_AND_CLOSE = 'S', OSTREE_STATIC_DELTA_OP_OPEN = 'o', OSTREE_STATIC_DELTA_OP_WRITE = 'w', @@ -138,52 +141,39 @@ typedef enum { } OstreeStaticDeltaOpCode; #define OSTREE_STATIC_DELTA_N_OPS 7 -gboolean -_ostree_static_delta_part_open (GInputStream *part_in, - GBytes *inline_part_bytes, - OstreeStaticDeltaOpenFlags flags, - const char *expected_checksum, - GVariant **out_part, - GCancellable *cancellable, - GError **error); +gboolean _ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, + OstreeStaticDeltaOpenFlags flags, + const char *expected_checksum, GVariant **out_part, + GCancellable *cancellable, GError **error); -typedef struct { +typedef struct +{ guint n_ops_executed[OSTREE_STATIC_DELTA_N_OPS]; } OstreeDeltaExecuteStats; -gboolean _ostree_static_delta_part_execute (OstreeRepo *repo, - GVariant *header, - GVariant *part_payload, - gboolean stats_only, +gboolean _ostree_static_delta_part_execute (OstreeRepo *repo, GVariant *header, + GVariant *part_payload, gboolean stats_only, OstreeDeltaExecuteStats *stats, - GCancellable *cancellable, - GError **error); - -void _ostree_static_delta_part_execute_async (OstreeRepo *repo, - GVariant *header, - GVariant *part_payload, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean _ostree_static_delta_part_execute_finish (OstreeRepo *repo, - GAsyncResult *result, - GError **error); - -gboolean -_ostree_static_delta_parse_checksum_array (GVariant *array, - guint8 **out_checksums_array, - guint *out_n_checksums, - GError **error); - -gboolean -_ostree_repo_static_delta_part_have_all_objects (OstreeRepo *repo, - GVariant *checksum_array, - gboolean *out_have_all, - GCancellable *cancellable, - GError **error); - -typedef struct { + GCancellable *cancellable, GError **error); + +void _ostree_static_delta_part_execute_async (OstreeRepo *repo, GVariant *header, + GVariant *part_payload, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); + +gboolean _ostree_static_delta_part_execute_finish (OstreeRepo *repo, GAsyncResult *result, + GError **error); + +gboolean _ostree_static_delta_parse_checksum_array (GVariant *array, guint8 **out_checksums_array, + guint *out_n_checksums, GError **error); + +gboolean _ostree_repo_static_delta_part_have_all_objects (OstreeRepo *repo, + GVariant *checksum_array, + gboolean *out_have_all, + GCancellable *cancellable, + GError **error); + +typedef struct +{ char *checksum; guint64 size; GPtrArray *basenames; @@ -191,45 +181,27 @@ typedef struct { void _ostree_delta_content_sizenames_free (gpointer v); -gboolean -_ostree_delta_compute_similar_objects (OstreeRepo *repo, - GVariant *from_commit, - GVariant *to_commit, - GHashTable *new_reachable_regfile_content, - guint similarity_percent_threshold, - GHashTable **out_modified_regfile_content, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_static_delta_query_exists (OstreeRepo *repo, - const char *delta_id, - gboolean *out_exists, - GCancellable *cancellable, - GError **error); -GVariant * -_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, - const char *from, - const char *to, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_static_delta_dump (OstreeRepo *repo, - const char *delta_id, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_repo_static_delta_delete (OstreeRepo *repo, - const char *delta_id, - GCancellable *cancellable, - GError **error); -gboolean -_ostree_repo_static_delta_reindex (OstreeRepo *repo, - const char *opt_to_commit, - GCancellable *cancellable, - GError **error); +gboolean _ostree_delta_compute_similar_objects (OstreeRepo *repo, GVariant *from_commit, + GVariant *to_commit, + GHashTable *new_reachable_regfile_content, + guint similarity_percent_threshold, + GHashTable **out_modified_regfile_content, + GCancellable *cancellable, GError **error); + +gboolean _ostree_repo_static_delta_query_exists (OstreeRepo *repo, const char *delta_id, + gboolean *out_exists, GCancellable *cancellable, + GError **error); +GVariant *_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, const char *from, + const char *to, GCancellable *cancellable, + GError **error); + +gboolean _ostree_repo_static_delta_dump (OstreeRepo *repo, const char *delta_id, + GCancellable *cancellable, GError **error); + +gboolean _ostree_repo_static_delta_delete (OstreeRepo *repo, const char *delta_id, + GCancellable *cancellable, GError **error); +gboolean _ostree_repo_static_delta_reindex (OstreeRepo *repo, const char *opt_to_commit, + GCancellable *cancellable, GError **error); /* Used for static deltas which due to a historical mistake are * inconsistent endian. @@ -237,8 +209,7 @@ _ostree_repo_static_delta_reindex (OstreeRepo *repo, * https://bugzilla.gnome.org/show_bug.cgi?id=762515 */ static inline guint32 -maybe_swap_endian_u32 (gboolean swap, - guint32 v) +maybe_swap_endian_u32 (gboolean swap, guint32 v) { if (!swap) return v; @@ -246,21 +217,22 @@ maybe_swap_endian_u32 (gboolean swap, } static inline guint64 -maybe_swap_endian_u64 (gboolean swap, - guint64 v) +maybe_swap_endian_u64 (gboolean swap, guint64 v) { if (!swap) return v; return GUINT64_SWAP_LE_BE (v); } -typedef enum { +typedef enum +{ OSTREE_DELTA_ENDIAN_BIG, OSTREE_DELTA_ENDIAN_LITTLE, OSTREE_DELTA_ENDIAN_INVALID } OstreeDeltaEndianness; -OstreeDeltaEndianness _ostree_delta_get_endianness (GVariant *superblock, gboolean *out_was_heuristic); +OstreeDeltaEndianness _ostree_delta_get_endianness (GVariant *superblock, + gboolean *out_was_heuristic); gboolean _ostree_delta_needs_byteswap (GVariant *superblock); diff --git a/src/libostree/ostree-repo-static-delta-processing.c b/src/libostree/ostree-repo-static-delta-processing.c index 47e6c06..94876fa 100644 --- a/src/libostree/ostree-repo-static-delta-processing.c +++ b/src/libostree/ostree-repo-static-delta-processing.c @@ -22,93 +22,89 @@ #include -#include +#include #include #include -#include +#include +#include "bsdiff/bspatch.h" #include "ostree-core-private.h" +#include "ostree-lzma-decompressor.h" #include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" -#include "ostree-lzma-decompressor.h" -#include "otutil.h" #include "ostree-varint.h" -#include "bsdiff/bspatch.h" +#include "otutil.h" /* This should really always be true, but hey, let's just assert it */ G_STATIC_ASSERT (sizeof (guint) >= sizeof (guint32)); -typedef struct { - gboolean stats_only; - OstreeRepo *repo; - guint checksum_index; - const guint8 *checksums; - guint n_checksums; +typedef struct +{ + gboolean stats_only; + OstreeRepo *repo; + guint checksum_index; + const guint8 *checksums; + guint n_checksums; - const guint8 *opdata; - guint oplen; + const guint8 *opdata; + guint oplen; - GVariant *mode_dict; - GVariant *xattr_dict; + GVariant *mode_dict; + GVariant *xattr_dict; - gboolean object_start; - gboolean caught_error; - GError **async_error; + gboolean object_start; + gboolean caught_error; + GError **async_error; OstreeObjectType output_objtype; - guint64 content_size; - char checksum[OSTREE_SHA256_STRING_LEN+1]; + guint64 content_size; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; OstreeRepoBareContent content_out; - char *read_source_object; - int read_source_fd; - gboolean have_obj; - guint32 uid; - guint32 gid; - guint32 mode; - GVariant *xattrs; - - const guint8 *output_target; - const guint8 *input_target_csum; - - const guint8 *payload_data; - guint64 payload_size; + char *read_source_object; + int read_source_fd; + gboolean have_obj; + guint32 uid; + guint32 gid; + guint32 mode; + GVariant *xattrs; + + const guint8 *output_target; + const guint8 *input_target_csum; + + const guint8 *payload_data; + guint64 payload_size; } StaticDeltaExecutionState; -typedef struct { +typedef struct +{ StaticDeltaExecutionState *state; - char checksum[OSTREE_SHA256_STRING_LEN+1]; + char checksum[OSTREE_SHA256_STRING_LEN + 1]; } StaticDeltaContentWrite; -typedef gboolean (*DispatchOpFunc) (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error); +typedef gboolean (*DispatchOpFunc) (OstreeRepo *repo, StaticDeltaExecutionState *state, + GCancellable *cancellable, GError **error); #define OPPROTO(name) \ - static gboolean dispatch_##name (OstreeRepo *repo, \ - StaticDeltaExecutionState *state, \ - GCancellable *cancellable, \ - GError **error); - -OPPROTO(open_splice_and_close) -OPPROTO(open) -OPPROTO(write) -OPPROTO(set_read_source) -OPPROTO(unset_read_source) -OPPROTO(close) -OPPROTO(bspatch) + static gboolean dispatch_##name (OstreeRepo *repo, StaticDeltaExecutionState *state, \ + GCancellable *cancellable, GError **error); + +OPPROTO (open_splice_and_close) +OPPROTO (open) +OPPROTO (write) +OPPROTO (set_read_source) +OPPROTO (unset_read_source) +OPPROTO (close) +OPPROTO (bspatch) #undef OPPROTO static void -static_delta_execution_state_init (StaticDeltaExecutionState *state) +static_delta_execution_state_init (StaticDeltaExecutionState *state) { state->read_source_fd = -1; } static gboolean -read_varuint64 (StaticDeltaExecutionState *state, - guint64 *out_value, - GError **error) +read_varuint64 (StaticDeltaExecutionState *state, guint64 *out_value, GError **error) { gsize bytes_read; if (!_ostree_read_varuint64 (state->opdata, state->oplen, out_value, &bytes_read)) @@ -121,20 +117,19 @@ read_varuint64 (StaticDeltaExecutionState *state, } static gboolean -open_output_target (StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +open_output_target (StaticDeltaExecutionState *state, GCancellable *cancellable, GError **error) { g_assert (state->checksums != NULL); g_assert (state->output_target == NULL); g_assert (state->checksum_index < state->n_checksums); - guint8 *objcsum = (guint8*)state->checksums + (state->checksum_index * OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN); + guint8 *objcsum + = (guint8 *)state->checksums + (state->checksum_index * OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN); - if (G_UNLIKELY(!ostree_validate_structureof_objtype (*objcsum, error))) + if (G_UNLIKELY (!ostree_validate_structureof_objtype (*objcsum, error))) return FALSE; - state->output_objtype = (OstreeObjectType) *objcsum; + state->output_objtype = (OstreeObjectType)*objcsum; state->output_target = objcsum + 1; ostree_checksum_inplace_from_bytes (state->output_target, state->checksum); @@ -167,21 +162,19 @@ delta_opcode_index (OstreeStaticDeltaOpCode op) } gboolean -_ostree_static_delta_part_execute (OstreeRepo *repo, - GVariant *objects, - GVariant *part, - gboolean stats_only, - OstreeDeltaExecuteStats *stats, - GCancellable *cancellable, - GError **error) +_ostree_static_delta_part_execute (OstreeRepo *repo, GVariant *objects, GVariant *part, + gboolean stats_only, OstreeDeltaExecuteStats *stats, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint8 *checksums_data; - g_autoptr(GVariant) mode_dict = NULL; - g_autoptr(GVariant) xattr_dict = NULL; - g_autoptr(GVariant) payload = NULL; - g_autoptr(GVariant) ops = NULL; - StaticDeltaExecutionState statedata = { 0, }; + g_autoptr (GVariant) mode_dict = NULL; + g_autoptr (GVariant) xattr_dict = NULL; + g_autoptr (GVariant) payload = NULL; + g_autoptr (GVariant) ops = NULL; + StaticDeltaExecutionState statedata = { + 0, + }; StaticDeltaExecutionState *state = &statedata; guint n_executed = 0; @@ -191,9 +184,7 @@ _ostree_static_delta_part_execute (OstreeRepo *repo, state->async_error = error; state->stats_only = stats_only; - if (!_ostree_static_delta_parse_checksum_array (objects, - &checksums_data, - &state->n_checksums, + if (!_ostree_static_delta_parse_checksum_array (objects, &checksums_data, &state->n_checksums, error)) goto out; @@ -206,10 +197,7 @@ _ostree_static_delta_part_execute (OstreeRepo *repo, state->checksums = checksums_data; - g_variant_get (part, "(@a(uuu)@aa(ayay)@ay@ay)", - &mode_dict, - &xattr_dict, - &payload, &ops); + g_variant_get (part, "(@a(uuu)@aa(ayay)@ay@ay)", &mode_dict, &xattr_dict, &payload, &ops); state->mode_dict = mode_dict; state->xattr_dict = xattr_dict; @@ -269,19 +257,20 @@ _ostree_static_delta_part_execute (OstreeRepo *repo, n_executed++; if (stats) - stats->n_ops_executed[delta_opcode_index(opcode)]++; + stats->n_ops_executed[delta_opcode_index (opcode)]++; } if (state->caught_error) goto out; ret = TRUE; - out: +out: _ostree_repo_bare_content_cleanup (&state->content_out); return ret; } -typedef struct { +typedef struct +{ OstreeRepo *repo; GVariant *header; GVariant *part; @@ -301,18 +290,13 @@ static_delta_part_execute_async_data_free (gpointer user_data) } static void -static_delta_part_execute_thread (GTask *task, - GObject *object, - gpointer datap, - GCancellable *cancellable) +static_delta_part_execute_thread (GTask *task, GObject *object, gpointer datap, + GCancellable *cancellable) { GError *error = NULL; StaticDeltaPartExecuteAsyncData *data = datap; - if (!_ostree_static_delta_part_execute (data->repo, - data->header, - data->part, - FALSE, NULL, + if (!_ostree_static_delta_part_execute (data->repo, data->header, data->part, FALSE, NULL, cancellable, &error)) g_task_return_error (task, error); else @@ -320,14 +304,11 @@ static_delta_part_execute_thread (GTask *task, } void -_ostree_static_delta_part_execute_async (OstreeRepo *repo, - GVariant *header, - GVariant *part, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_static_delta_part_execute_async (OstreeRepo *repo, GVariant *header, GVariant *part, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { - g_autoptr(GTask) task = NULL; + g_autoptr (GTask) task = NULL; StaticDeltaPartExecuteAsyncData *asyncdata; asyncdata = g_new0 (StaticDeltaPartExecuteAsyncData, 1); @@ -343,41 +324,34 @@ _ostree_static_delta_part_execute_async (OstreeRepo *repo, } gboolean -_ostree_static_delta_part_execute_finish (OstreeRepo *repo, - GAsyncResult *result, - GError **error) +_ostree_static_delta_part_execute_finish (OstreeRepo *repo, GAsyncResult *result, GError **error) { g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE); g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (g_task_is_valid (result, repo), FALSE); - g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_static_delta_part_execute_async), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_static_delta_part_execute_async), + FALSE); return g_task_propagate_boolean (G_TASK (result), error); } static gboolean -validate_ofs (StaticDeltaExecutionState *state, - guint64 offset, - guint64 length, - GError **error) +validate_ofs (StaticDeltaExecutionState *state, guint64 offset, guint64 length, GError **error) { - if (G_UNLIKELY (offset + length < offset || - offset + length > state->payload_size)) + if (G_UNLIKELY (offset + length < offset || offset + length > state->payload_size)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - "Invalid offset/length %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, - offset, length); + "Invalid offset/length %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, offset, + length); return FALSE; } return TRUE; } static gboolean -do_content_open_generic (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +do_content_open_generic (OstreeRepo *repo, StaticDeltaExecutionState *state, + GCancellable *cancellable, GError **error) { guint64 mode_offset; guint64 xattr_offset; @@ -387,7 +361,7 @@ do_content_open_generic (OstreeRepo *repo, if (!read_varuint64 (state, &xattr_offset, error)) return FALSE; - g_autoptr(GVariant) modev = g_variant_get_child_value (state->mode_dict, mode_offset); + g_autoptr (GVariant) modev = g_variant_get_child_value (state->mode_dict, mode_offset); guint32 uid, gid, mode; g_variant_get (modev, "(uuu)", &uid, &gid, &mode); state->uid = GUINT32_FROM_BE (uid); @@ -401,12 +375,12 @@ do_content_open_generic (OstreeRepo *repo, struct bzpatch_opaque_s { - StaticDeltaExecutionState *state; + StaticDeltaExecutionState *state; guint64 offset, length; }; static int -bspatch_read (const struct bspatch_stream* stream, void* buffer, int length) +bspatch_read (const struct bspatch_stream *stream, void *buffer, int length) { struct bzpatch_opaque_s *opaque = stream->opaque; @@ -420,10 +394,8 @@ bspatch_read (const struct bspatch_stream* stream, void* buffer, int length) } static gboolean -dispatch_bspatch (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +dispatch_bspatch (OstreeRepo *repo, StaticDeltaExecutionState *state, GCancellable *cancellable, + GError **error) { guint64 offset, length; @@ -437,7 +409,8 @@ dispatch_bspatch (OstreeRepo *repo, if (!state->have_obj) { - g_autoptr(GMappedFile) input_mfile = g_mapped_file_new_from_fd (state->read_source_fd, FALSE, error); + g_autoptr (GMappedFile) input_mfile + = g_mapped_file_new_from_fd (state->read_source_fd, FALSE, error); if (!input_mfile) return FALSE; @@ -450,15 +423,12 @@ dispatch_bspatch (OstreeRepo *repo, struct bspatch_stream stream; stream.read = bspatch_read; stream.opaque = &opaque; - if (bspatch ((const guint8*)g_mapped_file_get_contents (input_mfile), - g_mapped_file_get_length (input_mfile), - buf, - state->content_size, - &stream) < 0) + if (bspatch ((const guint8 *)g_mapped_file_get_contents (input_mfile), + g_mapped_file_get_length (input_mfile), buf, state->content_size, &stream) + < 0) return glnx_throw (error, "bsdiff patch failed"); - if (!_ostree_repo_bare_content_write (repo, &state->content_out, - buf, state->content_size, + if (!_ostree_repo_bare_content_write (repo, &state->content_out, buf, state->content_size, cancellable, error)) return FALSE; } @@ -467,10 +437,8 @@ dispatch_bspatch (OstreeRepo *repo, } static gboolean -dispatch_open_splice_and_close (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +dispatch_open_splice_and_close (OstreeRepo *repo, StaticDeltaExecutionState *state, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; @@ -479,7 +447,7 @@ dispatch_open_splice_and_close (OstreeRepo *repo, if (OSTREE_OBJECT_TYPE_IS_META (state->output_objtype)) { - g_autoptr(GVariant) metadata = NULL; + g_autoptr (GVariant) metadata = NULL; guint64 offset; guint64 length; @@ -500,18 +468,15 @@ dispatch_open_splice_and_close (OstreeRepo *repo, * and we didn't guarantee that in static deltas. We can do so in the * future. */ - g_autoptr(GBytes) metadata_copy = g_bytes_new (state->payload_data + offset, length); + g_autoptr (GBytes) metadata_copy = g_bytes_new (state->payload_data + offset, length); metadata = g_variant_new_from_bytes (ostree_metadata_variant_type (state->output_objtype), metadata_copy, FALSE); { g_autofree guchar *actual_csum = NULL; - if (!ostree_repo_write_metadata (state->repo, state->output_objtype, - state->checksum, - metadata, &actual_csum, - cancellable, - error)) + if (!ostree_repo_write_metadata (state->repo, state->output_objtype, state->checksum, + metadata, &actual_csum, cancellable, error)) goto out; } } @@ -519,8 +484,8 @@ dispatch_open_splice_and_close (OstreeRepo *repo, { guint64 content_offset; guint64 objlen; - g_autoptr(GInputStream) object_input = NULL; - g_autoptr(GInputStream) memin = NULL; + g_autoptr (GInputStream) object_input = NULL; + g_autoptr (GInputStream) memin = NULL; if (!do_content_open_generic (repo, state, cancellable, error)) goto out; @@ -539,8 +504,7 @@ dispatch_open_splice_and_close (OstreeRepo *repo, } /* Fast path for regular files to bare repositories */ - if (S_ISREG (state->mode) && - _ostree_repo_mode_is_bare (repo->mode)) + if (S_ISREG (state->mode) && _ostree_repo_mode_is_bare (repo->mode)) { if (!ostree_repo_has_object (repo, OSTREE_OBJECT_TYPE_FILE, state->checksum, &state->have_obj, cancellable, error)) @@ -548,54 +512,45 @@ dispatch_open_splice_and_close (OstreeRepo *repo, if (!state->have_obj) { - if (!_ostree_repo_bare_content_open (repo, state->checksum, - state->content_size, - state->uid, state->gid, state->mode, - state->xattrs, - &state->content_out, - cancellable, error)) + if (!_ostree_repo_bare_content_open ( + repo, state->checksum, state->content_size, state->uid, state->gid, + state->mode, state->xattrs, &state->content_out, cancellable, error)) goto out; if (!_ostree_repo_bare_content_write (repo, &state->content_out, state->payload_data + content_offset, - state->content_size, - cancellable, error)) + state->content_size, cancellable, error)) goto out; } } else { /* Slower path, for symlinks and unpacking deltas into archive */ - g_autoptr(GFileInfo) finfo = - _ostree_mode_uidgid_to_gfileinfo (state->mode, state->uid, state->gid); + g_autoptr (GFileInfo) finfo + = _ostree_mode_uidgid_to_gfileinfo (state->mode, state->uid, state->gid); if (S_ISLNK (state->mode)) { - g_autofree char *nulterminated_target = - g_strndup ((char*)state->payload_data + content_offset, state->content_size); + g_autofree char *nulterminated_target + = g_strndup ((char *)state->payload_data + content_offset, state->content_size); g_file_info_set_symlink_target (finfo, nulterminated_target); } else { g_assert (S_ISREG (state->mode)); g_file_info_set_size (finfo, state->content_size); - memin = g_memory_input_stream_new_from_data (state->payload_data + content_offset, state->content_size, NULL); + memin = g_memory_input_stream_new_from_data (state->payload_data + content_offset, + state->content_size, NULL); } - if (!ostree_raw_file_to_content_stream (memin, finfo, state->xattrs, - &object_input, &objlen, - cancellable, error)) + if (!ostree_raw_file_to_content_stream (memin, finfo, state->xattrs, &object_input, + &objlen, cancellable, error)) goto out; { g_autofree guchar *actual_csum = NULL; - if (!ostree_repo_write_content (state->repo, - state->checksum, - object_input, - objlen, - &actual_csum, - cancellable, - error)) + if (!ostree_repo_write_content (state->repo, state->checksum, object_input, objlen, + &actual_csum, cancellable, error)) goto out; } } @@ -605,29 +560,26 @@ dispatch_open_splice_and_close (OstreeRepo *repo, goto out; ret = TRUE; - out: +out: if (state->stats_only) - (void) dispatch_close (repo, state, cancellable, NULL); + (void)dispatch_close (repo, state, cancellable, NULL); if (!ret) g_prefix_error (error, "opcode open-splice-and-close: "); return ret; } static gboolean -dispatch_open (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +dispatch_open (OstreeRepo *repo, StaticDeltaExecutionState *state, GCancellable *cancellable, + GError **error) { - GLNX_AUTO_PREFIX_ERROR("opcode open", error); + GLNX_AUTO_PREFIX_ERROR ("opcode open", error); g_assert (state->output_target == NULL); /* FIXME - lift this restriction */ if (!state->stats_only) { - g_assert (repo->mode == OSTREE_REPO_MODE_BARE || - repo->mode == OSTREE_REPO_MODE_BARE_USER || - repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY); + g_assert (repo->mode == OSTREE_REPO_MODE_BARE || repo->mode == OSTREE_REPO_MODE_BARE_USER + || repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY); } if (!open_output_target (state, cancellable, error)) @@ -642,18 +594,15 @@ dispatch_open (OstreeRepo *repo, if (state->stats_only) return TRUE; /* Early return */ - if (!ostree_repo_has_object (repo, OSTREE_OBJECT_TYPE_FILE, state->checksum, - &state->have_obj, cancellable, error)) + if (!ostree_repo_has_object (repo, OSTREE_OBJECT_TYPE_FILE, state->checksum, &state->have_obj, + cancellable, error)) return FALSE; if (!state->have_obj) { - if (!_ostree_repo_bare_content_open (repo, state->checksum, - state->content_size, - state->uid, state->gid, state->mode, - state->xattrs, - &state->content_out, - cancellable, error)) + if (!_ostree_repo_bare_content_open (repo, state->checksum, state->content_size, state->uid, + state->gid, state->mode, state->xattrs, + &state->content_out, cancellable, error)) return FALSE; } @@ -661,12 +610,10 @@ dispatch_open (OstreeRepo *repo, } static gboolean -dispatch_write (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +dispatch_write (OstreeRepo *repo, StaticDeltaExecutionState *state, GCancellable *cancellable, + GError **error) { - GLNX_AUTO_PREFIX_ERROR("opcode write", error); + GLNX_AUTO_PREFIX_ERROR ("opcode write", error); guint64 content_size; guint64 content_offset; @@ -688,16 +635,17 @@ dispatch_write (OstreeRepo *repo, gssize bytes_read; do - bytes_read = pread (state->read_source_fd, buf, MIN(sizeof(buf), content_size), content_offset); + bytes_read = pread (state->read_source_fd, buf, MIN (sizeof (buf), content_size), + content_offset); while (G_UNLIKELY (bytes_read == -1 && errno == EINTR)); if (bytes_read == -1) return glnx_throw_errno_prefix (error, "read"); if (G_UNLIKELY (bytes_read == 0)) - return glnx_throw (error, "Unexpected EOF reading object %s", state->read_source_object); + return glnx_throw (error, "Unexpected EOF reading object %s", + state->read_source_object); - if (!_ostree_repo_bare_content_write (repo, &state->content_out, - (guint8*)buf, bytes_read, - cancellable, error)) + if (!_ostree_repo_bare_content_write (repo, &state->content_out, (guint8 *)buf, + bytes_read, cancellable, error)) return FALSE; content_size -= bytes_read; @@ -720,12 +668,10 @@ dispatch_write (OstreeRepo *repo, } static gboolean -dispatch_set_read_source (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +dispatch_set_read_source (OstreeRepo *repo, StaticDeltaExecutionState *state, + GCancellable *cancellable, GError **error) { - GLNX_AUTO_PREFIX_ERROR("opcode set-read-source", error); + GLNX_AUTO_PREFIX_ERROR ("opcode set-read-source", error); guint64 source_offset; glnx_close_fd (&state->read_source_fd); @@ -741,22 +687,18 @@ dispatch_set_read_source (OstreeRepo *repo, g_free (state->read_source_object); state->read_source_object = ostree_checksum_from_bytes (state->payload_data + source_offset); - if (!_ostree_repo_load_file_bare (repo, state->read_source_object, - &state->read_source_fd, - NULL, NULL, NULL, - cancellable, error)) + if (!_ostree_repo_load_file_bare (repo, state->read_source_object, &state->read_source_fd, NULL, + NULL, NULL, cancellable, error)) return FALSE; return TRUE; } static gboolean -dispatch_unset_read_source (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +dispatch_unset_read_source (OstreeRepo *repo, StaticDeltaExecutionState *state, + GCancellable *cancellable, GError **error) { - GLNX_AUTO_PREFIX_ERROR("opcode unset-read-source", error); + GLNX_AUTO_PREFIX_ERROR ("opcode unset-read-source", error); if (state->stats_only) return TRUE; /* Early return */ @@ -768,19 +710,16 @@ dispatch_unset_read_source (OstreeRepo *repo, } static gboolean -dispatch_close (OstreeRepo *repo, - StaticDeltaExecutionState *state, - GCancellable *cancellable, - GError **error) +dispatch_close (OstreeRepo *repo, StaticDeltaExecutionState *state, GCancellable *cancellable, + GError **error) { - GLNX_AUTO_PREFIX_ERROR("opcode close", error); + GLNX_AUTO_PREFIX_ERROR ("opcode close", error); if (state->content_out.initialized) { - char actual_checksum[OSTREE_SHA256_STRING_LEN+1]; + char actual_checksum[OSTREE_SHA256_STRING_LEN + 1]; if (!_ostree_repo_bare_content_commit (repo, &state->content_out, actual_checksum, - sizeof (actual_checksum), - cancellable, error)) + sizeof (actual_checksum), cancellable, error)) return FALSE; g_assert_cmpstr (state->checksum, ==, actual_checksum); diff --git a/src/libostree/ostree-repo-traverse.c b/src/libostree/ostree-repo-traverse.c index 5efed10..08172b8 100644 --- a/src/libostree/ostree-repo-traverse.c +++ b/src/libostree/ostree-repo-traverse.c @@ -25,7 +25,8 @@ #include "ostree.h" #include "otutil.h" -struct _OstreeRepoRealCommitTraverseIter { +struct _OstreeRepoRealCommitTraverseIter +{ gboolean initialized; OstreeRepo *repo; GVariant *commit; @@ -33,8 +34,8 @@ struct _OstreeRepoRealCommitTraverseIter { const char *name; OstreeRepoCommitIterResult state; guint idx; - char checksum_content[OSTREE_SHA256_STRING_LEN+1]; - char checksum_meta[OSTREE_SHA256_STRING_LEN+1]; + char checksum_content[OSTREE_SHA256_STRING_LEN + 1]; + char checksum_meta[OSTREE_SHA256_STRING_LEN + 1]; }; /** @@ -48,14 +49,11 @@ struct _OstreeRepoRealCommitTraverseIter { * Initialize (in place) an iterator over the root of a commit object. */ gboolean -ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter *iter, - OstreeRepo *repo, - GVariant *commit, - OstreeRepoCommitTraverseFlags flags, - GError **error) +ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter *iter, OstreeRepo *repo, + GVariant *commit, OstreeRepoCommitTraverseFlags flags, + GError **error) { - struct _OstreeRepoRealCommitTraverseIter *real = - (struct _OstreeRepoRealCommitTraverseIter*)iter; + struct _OstreeRepoRealCommitTraverseIter *real = (struct _OstreeRepoRealCommitTraverseIter *)iter; memset (real, 0, sizeof (*real)); real->initialized = TRUE; @@ -64,14 +62,14 @@ ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter *it real->current_dir = NULL; real->idx = 0; - g_autoptr(GVariant) content_csum_bytes = NULL; + g_autoptr (GVariant) content_csum_bytes = NULL; g_variant_get_child (commit, 6, "@ay", &content_csum_bytes); const guchar *csum = ostree_checksum_bytes_peek_validate (content_csum_bytes, error); if (!csum) return FALSE; ostree_checksum_inplace_from_bytes (csum, real->checksum_content); - g_autoptr(GVariant) meta_csum_bytes = NULL; + g_autoptr (GVariant) meta_csum_bytes = NULL; g_variant_get_child (commit, 7, "@ay", &meta_csum_bytes); csum = ostree_checksum_bytes_peek_validate (meta_csum_bytes, error); if (!csum) @@ -92,14 +90,11 @@ ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter *it * Initialize (in place) an iterator over a directory tree. */ gboolean -ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter *iter, - OstreeRepo *repo, - GVariant *dirtree, - OstreeRepoCommitTraverseFlags flags, - GError **error) +ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter *iter, OstreeRepo *repo, + GVariant *dirtree, + OstreeRepoCommitTraverseFlags flags, GError **error) { - struct _OstreeRepoRealCommitTraverseIter *real = - (struct _OstreeRepoRealCommitTraverseIter*)iter; + struct _OstreeRepoRealCommitTraverseIter *real = (struct _OstreeRepoRealCommitTraverseIter *)iter; memset (real, 0, sizeof (*real)); real->initialized = TRUE; @@ -124,26 +119,22 @@ ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter *i * data for that directory. Similarly, if * %OSTREE_REPO_COMMIT_ITER_RESULT_FILE is returned, call * ostree_repo_commit_traverse_iter_get_file(). - * + * * If %OSTREE_REPO_COMMIT_ITER_RESULT_ERROR is returned, it is a * program error to call any further API on @iter except for * ostree_repo_commit_traverse_iter_clear(). */ OstreeRepoCommitIterResult ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, - GCancellable *cancellable, - GError **error) + GCancellable *cancellable, GError **error) { - struct _OstreeRepoRealCommitTraverseIter *real = - (struct _OstreeRepoRealCommitTraverseIter*)iter; + struct _OstreeRepoRealCommitTraverseIter *real = (struct _OstreeRepoRealCommitTraverseIter *)iter; OstreeRepoCommitIterResult res = OSTREE_REPO_COMMIT_ITER_RESULT_ERROR; if (!real->current_dir) { if (!ostree_repo_load_variant (real->repo, OSTREE_OBJECT_TYPE_DIR_TREE, - real->checksum_content, - &real->current_dir, - error)) + real->checksum_content, &real->current_dir, error)) goto out; res = OSTREE_REPO_COMMIT_ITER_RESULT_DIR; } @@ -153,10 +144,10 @@ ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, guint ndirs; guint idx; const guchar *csum; - g_autoptr(GVariant) content_csum_v = NULL; - g_autoptr(GVariant) meta_csum_v = NULL; - g_autoptr(GVariant) files_variant = NULL; - g_autoptr(GVariant) dirs_variant = NULL; + g_autoptr (GVariant) content_csum_v = NULL; + g_autoptr (GVariant) meta_csum_v = NULL; + g_autoptr (GVariant) files_variant = NULL; + g_autoptr (GVariant) dirs_variant = NULL; files_variant = g_variant_get_child_value (real->current_dir, 0); dirs_variant = g_variant_get_child_value (real->current_dir, 1); @@ -166,9 +157,7 @@ ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, if (real->idx < nfiles) { idx = real->idx; - g_variant_get_child (files_variant, idx, "(&s@ay)", - &real->name, - &content_csum_v); + g_variant_get_child (files_variant, idx, "(&s@ay)", &real->name, &content_csum_v); csum = ostree_checksum_bytes_peek_validate (content_csum_v, error); if (!csum) @@ -183,8 +172,8 @@ ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, { idx = real->idx - nfiles; - g_variant_get_child (dirs_variant, idx, "(&s@ay@ay)", - &real->name, &content_csum_v, &meta_csum_v); + g_variant_get_child (dirs_variant, idx, "(&s@ay@ay)", &real->name, &content_csum_v, + &meta_csum_v); csum = ostree_checksum_bytes_peek_validate (content_csum_v, error); if (!csum) @@ -195,7 +184,7 @@ ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, if (!csum) goto out; ostree_checksum_inplace_from_bytes (csum, real->checksum_meta); - + res = OSTREE_REPO_COMMIT_ITER_RESULT_DIR; real->idx++; @@ -203,9 +192,9 @@ ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, else res = OSTREE_REPO_COMMIT_ITER_RESULT_END; } - + real->state = res; - out: +out: return res; } @@ -220,14 +209,12 @@ ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, * ostree_repo_commit_traverse_iter_next(). */ void -ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter, - char **out_name, - char **out_checksum) +ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter, char **out_name, + char **out_checksum) { - struct _OstreeRepoRealCommitTraverseIter *real = - (struct _OstreeRepoRealCommitTraverseIter*)iter; - *out_name = (char*)real->name; - *out_checksum = (char*)real->checksum_content; + struct _OstreeRepoRealCommitTraverseIter *real = (struct _OstreeRepoRealCommitTraverseIter *)iter; + *out_name = (char *)real->name; + *out_checksum = (char *)real->checksum_content; } /** @@ -242,23 +229,19 @@ ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter, * from ostree_repo_commit_traverse_iter_next(). */ void -ostree_repo_commit_traverse_iter_get_dir (OstreeRepoCommitTraverseIter *iter, - char **out_name, - char **out_content_checksum, - char **out_meta_checksum) +ostree_repo_commit_traverse_iter_get_dir (OstreeRepoCommitTraverseIter *iter, char **out_name, + char **out_content_checksum, char **out_meta_checksum) { - struct _OstreeRepoRealCommitTraverseIter *real = - (struct _OstreeRepoRealCommitTraverseIter*)iter; - *out_name = (char*)real->name; - *out_content_checksum = (char*)real->checksum_content; - *out_meta_checksum = (char*)real->checksum_meta; + struct _OstreeRepoRealCommitTraverseIter *real = (struct _OstreeRepoRealCommitTraverseIter *)iter; + *out_name = (char *)real->name; + *out_content_checksum = (char *)real->checksum_content; + *out_meta_checksum = (char *)real->checksum_meta; } void ostree_repo_commit_traverse_iter_clear (OstreeRepoCommitTraverseIter *iter) { - struct _OstreeRepoRealCommitTraverseIter *real = - (struct _OstreeRepoRealCommitTraverseIter*)iter; + struct _OstreeRepoRealCommitTraverseIter *real = (struct _OstreeRepoRealCommitTraverseIter *)iter; g_clear_object (&real->repo); g_clear_pointer (&real->commit, g_variant_unref); g_clear_pointer (&real->current_dir, g_variant_unref); @@ -268,8 +251,7 @@ void ostree_repo_commit_traverse_iter_cleanup (void *p) { OstreeRepoCommitTraverseIter *iter = p; - struct _OstreeRepoRealCommitTraverseIter *real = - (struct _OstreeRepoRealCommitTraverseIter*)iter; + struct _OstreeRepoRealCommitTraverseIter *real = (struct _OstreeRepoRealCommitTraverseIter *)iter; if (real->initialized) { ostree_repo_commit_traverse_iter_clear (iter); @@ -288,8 +270,8 @@ ostree_repo_commit_traverse_iter_cleanup (void *p) GHashTable * ostree_repo_traverse_new_reachable (void) { - return g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, - NULL, (GDestroyNotify)g_variant_unref); + return g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, NULL, + (GDestroyNotify)g_variant_unref); } /** @@ -334,7 +316,7 @@ parents_get_commits (GHashTable *parents_ht, GVariant *object, GHashTable *res) for (i = 0; i < len; i++) { - g_autoptr(GVariant) parent = g_variant_get_child_value (parents, i); + g_autoptr (GVariant) parent = g_variant_get_child_value (parents, i); parents_get_commits (parents_ht, parent, res); } } @@ -357,27 +339,20 @@ parents_get_commits (GHashTable *parents_ht, GVariant *object, GHashTable *res) char ** ostree_repo_traverse_parents_get_commits (GHashTable *parents, GVariant *object) { - g_autoptr(GHashTable) res = g_hash_table_new (g_str_hash, g_str_equal); + g_autoptr (GHashTable) res = g_hash_table_new (g_str_hash, g_str_equal); parents_get_commits (parents, object, res); return (char **)g_hash_table_get_keys_as_array (res, NULL); } -static gboolean -traverse_dirtree (OstreeRepo *repo, - const char *checksum, - GVariant *parent_key, - GHashTable *inout_reachable, - GHashTable *inout_parents, - gboolean ignore_missing_dirs, - GCancellable *cancellable, - GError **error); +static gboolean traverse_dirtree (OstreeRepo *repo, const char *checksum, GVariant *parent_key, + GHashTable *inout_reachable, GHashTable *inout_parents, + gboolean ignore_missing_dirs, GCancellable *cancellable, + GError **error); static void -add_parent_ref (GHashTable *inout_parents, - GVariant *key, - GVariant *parent_key) +add_parent_ref (GHashTable *inout_parents, GVariant *key, GVariant *parent_key) { GVariant *old_parents; @@ -398,10 +373,10 @@ add_parent_ref (GHashTable *inout_parents, if (g_variant_is_of_type (old_parents, G_VARIANT_TYPE_ARRAY)) { gsize old_parents_len = g_variant_n_children (old_parents); - new_parents = g_new (GVariant *, old_parents_len + 1); - for (i = 0; i < old_parents_len ; i++) + new_parents = g_new (GVariant *, old_parents_len + 1); + for (i = 0; i < old_parents_len; i++) { - g_autoptr(GVariant) old_parent = g_variant_get_child_value (old_parents, i); + g_autoptr (GVariant) old_parent = g_variant_get_child_value (old_parents, i); if (!g_variant_equal (old_parent, parent_key)) new_parents[len++] = g_steal_pointer (&old_parent); } @@ -413,41 +388,36 @@ add_parent_ref (GHashTable *inout_parents, new_parents[len++] = g_variant_ref (old_parents); } new_parents[len++] = g_variant_ref (parent_key); - g_hash_table_insert (inout_parents, g_variant_ref (key), - g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(su)"), new_parents , len))); + g_hash_table_insert ( + inout_parents, g_variant_ref (key), + g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(su)"), new_parents, len))); for (i = 0; i < len; i++) g_variant_unref (new_parents[i]); } } - static gboolean -traverse_iter (OstreeRepo *repo, - OstreeRepoCommitTraverseIter *iter, - GVariant *parent_key, - GHashTable *inout_reachable, - GHashTable *inout_parents, - gboolean ignore_missing_dirs, - GCancellable *cancellable, - GError **error) +traverse_iter (OstreeRepo *repo, OstreeRepoCommitTraverseIter *iter, GVariant *parent_key, + GHashTable *inout_reachable, GHashTable *inout_parents, gboolean ignore_missing_dirs, + GCancellable *cancellable, GError **error) { while (TRUE) { - g_autoptr(GVariant) key = NULL; - g_autoptr(GError) local_error = NULL; - OstreeRepoCommitIterResult iterres = - ostree_repo_commit_traverse_iter_next (iter, cancellable, &local_error); + g_autoptr (GVariant) key = NULL; + g_autoptr (GError) local_error = NULL; + OstreeRepoCommitIterResult iterres + = ostree_repo_commit_traverse_iter_next (iter, cancellable, &local_error); if (iterres == OSTREE_REPO_COMMIT_ITER_RESULT_ERROR) { /* There is only one kind of not-found error, which is failing to load the dirmeta itself, if so, we ignore that (and the whole subtree) if told to. */ - if (ignore_missing_dirs && - g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + if (ignore_missing_dirs + && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_debug ("Ignoring not-found dirmeta"); - return TRUE; /* Note early return */ + return TRUE; /* Note early return */ } g_propagate_error (error, g_steal_pointer (&local_error)); @@ -463,7 +433,8 @@ traverse_iter (OstreeRepo *repo, ostree_repo_commit_traverse_iter_get_file (iter, &name, &checksum); g_debug ("Found file object %s", checksum); - key = g_variant_ref_sink (ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_FILE)); + key = g_variant_ref_sink ( + ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_FILE)); add_parent_ref (inout_parents, key, parent_key); g_hash_table_add (inout_reachable, g_steal_pointer (&key)); } @@ -473,16 +444,17 @@ traverse_iter (OstreeRepo *repo, char *content_checksum; char *meta_checksum; - ostree_repo_commit_traverse_iter_get_dir (iter, &name, &content_checksum, - &meta_checksum); + ostree_repo_commit_traverse_iter_get_dir (iter, &name, &content_checksum, &meta_checksum); g_debug ("Found dirtree object %s", content_checksum); g_debug ("Found dirmeta object %s", meta_checksum); - key = g_variant_ref_sink (ostree_object_name_serialize (meta_checksum, OSTREE_OBJECT_TYPE_DIR_META)); + key = g_variant_ref_sink ( + ostree_object_name_serialize (meta_checksum, OSTREE_OBJECT_TYPE_DIR_META)); add_parent_ref (inout_parents, key, parent_key); g_hash_table_add (inout_reachable, g_steal_pointer (&key)); - key = g_variant_ref_sink (ostree_object_name_serialize (content_checksum, OSTREE_OBJECT_TYPE_DIR_TREE)); + key = g_variant_ref_sink ( + ostree_object_name_serialize (content_checksum, OSTREE_OBJECT_TYPE_DIR_TREE)); add_parent_ref (inout_parents, key, parent_key); if (!g_hash_table_lookup (inout_reachable, key)) { @@ -501,23 +473,17 @@ traverse_iter (OstreeRepo *repo, } static gboolean -traverse_dirtree (OstreeRepo *repo, - const char *checksum, - GVariant *parent_key, - GHashTable *inout_reachable, - GHashTable *inout_parents, - gboolean ignore_missing_dirs, - GCancellable *cancellable, - GError **error) +traverse_dirtree (OstreeRepo *repo, const char *checksum, GVariant *parent_key, + GHashTable *inout_reachable, GHashTable *inout_parents, + gboolean ignore_missing_dirs, GCancellable *cancellable, GError **error) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; - g_autoptr(GVariant) dirtree = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum, - &dirtree, &local_error)) + g_autoptr (GVariant) dirtree = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum, &dirtree, + &local_error)) { - if (ignore_missing_dirs && - g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + if (ignore_missing_dirs && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_debug ("Ignoring not-found dirmeta %s", checksum); return TRUE; /* Early return */ @@ -528,14 +494,15 @@ traverse_dirtree (OstreeRepo *repo, } g_debug ("Traversing dirtree %s", checksum); - ostree_cleanup_repo_commit_traverse_iter - OstreeRepoCommitTraverseIter iter = { 0, }; + ostree_cleanup_repo_commit_traverse_iter OstreeRepoCommitTraverseIter iter = { + 0, + }; if (!ostree_repo_commit_traverse_iter_init_dirtree (&iter, repo, dirtree, - OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, - error)) + OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, error)) return FALSE; - if (!traverse_iter (repo, &iter, parent_key, inout_reachable, inout_parents, ignore_missing_dirs, cancellable, error)) + if (!traverse_iter (repo, &iter, parent_key, inout_reachable, inout_parents, ignore_missing_dirs, + cancellable, error)) return FALSE; return TRUE; @@ -562,30 +529,25 @@ traverse_dirtree (OstreeRepo *repo, * Since: 2018.5 */ gboolean -ostree_repo_traverse_commit_with_flags (OstreeRepo *repo, - OstreeRepoCommitTraverseFlags flags, - const char *commit_checksum, - int maxdepth, - GHashTable *inout_reachable, - GHashTable *inout_parents, - GCancellable *cancellable, - GError **error) +ostree_repo_traverse_commit_with_flags (OstreeRepo *repo, OstreeRepoCommitTraverseFlags flags, + const char *commit_checksum, int maxdepth, + GHashTable *inout_reachable, GHashTable *inout_parents, + GCancellable *cancellable, GError **error) { g_autofree char *tmp_checksum = NULL; gboolean commit_only = flags & OSTREE_REPO_COMMIT_TRAVERSE_FLAG_COMMIT_ONLY; while (TRUE) { - g_autoptr(GVariant) key = - g_variant_ref_sink (ostree_object_name_serialize (commit_checksum, OSTREE_OBJECT_TYPE_COMMIT)); + g_autoptr (GVariant) key = g_variant_ref_sink ( + ostree_object_name_serialize (commit_checksum, OSTREE_OBJECT_TYPE_COMMIT)); if (g_hash_table_contains (inout_reachable, key)) break; - g_autoptr(GVariant) commit = NULL; - if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT, - commit_checksum, &commit, - error)) + g_autoptr (GVariant) commit = NULL; + if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, + &commit, error)) return FALSE; /* Just return if the parent isn't found; we do expect most @@ -596,8 +558,7 @@ ostree_repo_traverse_commit_with_flags (OstreeRepo *repo, /* See if the commit is partial, if so it's not an error to lack objects */ OstreeRepoCommitState commitstate; - if (!ostree_repo_load_commit (repo, commit_checksum, NULL, &commitstate, - error)) + if (!ostree_repo_load_commit (repo, commit_checksum, NULL, &commitstate, error)) return FALSE; gboolean ignore_missing_dirs = FALSE; @@ -607,19 +568,20 @@ ostree_repo_traverse_commit_with_flags (OstreeRepo *repo, g_hash_table_add (inout_reachable, g_variant_ref (key)); /* Save time by skipping traversal of non-commit objects */ - if (!commit_only) + if (!commit_only) { g_debug ("Traversing commit %s", commit_checksum); - ostree_cleanup_repo_commit_traverse_iter - OstreeRepoCommitTraverseIter iter = { 0, }; - if (!ostree_repo_commit_traverse_iter_init_commit (&iter, repo, commit, - OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, - error)) + ostree_cleanup_repo_commit_traverse_iter OstreeRepoCommitTraverseIter iter = { + 0, + }; + if (!ostree_repo_commit_traverse_iter_init_commit ( + &iter, repo, commit, OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, error)) return FALSE; - if (!traverse_iter (repo, &iter, key, inout_reachable, inout_parents, ignore_missing_dirs, cancellable, error)) + if (!traverse_iter (repo, &iter, key, inout_reachable, inout_parents, ignore_missing_dirs, + cancellable, error)) return FALSE; - } + } gboolean recurse = FALSE; if (maxdepth == -1 || maxdepth > 0) @@ -661,17 +623,14 @@ ostree_repo_traverse_commit_with_flags (OstreeRepo *repo, * Since: 2018.5 */ gboolean -ostree_repo_traverse_commit_union_with_parents (OstreeRepo *repo, - const char *commit_checksum, - int maxdepth, - GHashTable *inout_reachable, - GHashTable *inout_parents, - GCancellable *cancellable, - GError **error) +ostree_repo_traverse_commit_union_with_parents (OstreeRepo *repo, const char *commit_checksum, + int maxdepth, GHashTable *inout_reachable, + GHashTable *inout_parents, + GCancellable *cancellable, GError **error) { - return ostree_repo_traverse_commit_with_flags(repo, OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, - commit_checksum, maxdepth, inout_reachable, inout_parents, - cancellable, error); + return ostree_repo_traverse_commit_with_flags (repo, OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE, + commit_checksum, maxdepth, inout_reachable, + inout_parents, cancellable, error); } /** @@ -687,17 +646,12 @@ ostree_repo_traverse_commit_union_with_parents (OstreeRepo *repo, * from @commit_checksum, traversing @maxdepth parent commits. */ gboolean -ostree_repo_traverse_commit_union (OstreeRepo *repo, - const char *commit_checksum, - int maxdepth, - GHashTable *inout_reachable, - GCancellable *cancellable, - GError **error) +ostree_repo_traverse_commit_union (OstreeRepo *repo, const char *commit_checksum, int maxdepth, + GHashTable *inout_reachable, GCancellable *cancellable, + GError **error) { - return - ostree_repo_traverse_commit_union_with_parents (repo, commit_checksum, maxdepth, - inout_reachable, NULL, - cancellable, error); + return ostree_repo_traverse_commit_union_with_parents (repo, commit_checksum, maxdepth, + inout_reachable, NULL, cancellable, error); } /** @@ -705,7 +659,8 @@ ostree_repo_traverse_commit_union (OstreeRepo *repo, * @repo: Repo * @commit_checksum: ASCII SHA256 checksum * @maxdepth: Traverse this many parent commits, -1 for unlimited - * @out_reachable: (out) (transfer container) (element-type GVariant GVariant): Set of reachable objects + * @out_reachable: (out) (transfer container) (element-type GVariant GVariant): Set of reachable + * objects * @cancellable: Cancellable * @error: Error * @@ -713,16 +668,12 @@ ostree_repo_traverse_commit_union (OstreeRepo *repo, * from @commit_checksum, traversing @maxdepth parent commits. */ gboolean -ostree_repo_traverse_commit (OstreeRepo *repo, - const char *commit_checksum, - int maxdepth, - GHashTable **out_reachable, - GCancellable *cancellable, - GError **error) +ostree_repo_traverse_commit (OstreeRepo *repo, const char *commit_checksum, int maxdepth, + GHashTable **out_reachable, GCancellable *cancellable, GError **error) { - g_autoptr(GHashTable) ret_reachable = ostree_repo_traverse_new_reachable (); - if (!ostree_repo_traverse_commit_union (repo, commit_checksum, maxdepth, - ret_reachable, cancellable, error)) + g_autoptr (GHashTable) ret_reachable = ostree_repo_traverse_new_reachable (); + if (!ostree_repo_traverse_commit_union (repo, commit_checksum, maxdepth, ret_reachable, + cancellable, error)) return FALSE; if (out_reachable) diff --git a/src/libostree/ostree-repo-verity.c b/src/libostree/ostree-repo-verity.c index d25d693..6a7130c 100644 --- a/src/libostree/ostree-repo-verity.c +++ b/src/libostree/ostree-repo-verity.c @@ -23,56 +23,92 @@ #include "ostree-core-private.h" #include "ostree-repo-private.h" -#include "otutil.h" #include "ot-fs-utils.h" +#include "otutil.h" #ifdef HAVE_LINUX_FSVERITY_H #include #endif -gboolean +#if defined(HAVE_OPENSSL) +#include +#include +#include +#include +#include + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (X509, X509_free); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (EVP_PKEY, EVP_PKEY_free); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (BIO, BIO_free); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (PKCS7, PKCS7_free); +#endif + +gboolean _ostree_repo_parse_fsverity_config (OstreeRepo *self, GError **error) { /* Currently experimental */ - static const char fsverity_key[] = "ex-fsverity"; - self->fs_verity_wanted = _OSTREE_FEATURE_NO; + OtTristate use_composefs; + OtTristate use_fsverity; + #ifdef HAVE_LINUX_FSVERITY_H self->fs_verity_supported = _OSTREE_FEATURE_MAYBE; #else self->fs_verity_supported = _OSTREE_FEATURE_NO; #endif - gboolean fsverity_required = FALSE; - if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "required", - FALSE, &fsverity_required, error)) + + /* Composefs use implies fsverity default of maybe */ + if (!ot_keyfile_get_tristate_with_default (self->config, _OSTREE_INTEGRITY_SECTION, "composefs", + OT_TRISTATE_NO, &use_composefs, error)) + return FALSE; + + if (!ot_keyfile_get_tristate_with_default (self->config, _OSTREE_INTEGRITY_SECTION, "fsverity", + (use_composefs != OT_TRISTATE_NO) ? OT_TRISTATE_MAYBE + : OT_TRISTATE_NO, + &use_fsverity, error)) return FALSE; - if (fsverity_required) + + if (use_fsverity != OT_TRISTATE_NO) { - self->fs_verity_wanted = _OSTREE_FEATURE_YES; - if (self->fs_verity_supported == _OSTREE_FEATURE_NO) - return glnx_throw (error, "fsverity required, but libostree compiled without support"); + self->fs_verity_wanted = (_OstreeFeatureSupport)use_fsverity; } else - { - gboolean fsverity_opportunistic = FALSE; - if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "opportunistic", - FALSE, &fsverity_opportunistic, error)) + { + /* Fall back to old configuration key */ + static const char fsverity_section[] = "ex-fsverity"; + + self->fs_verity_wanted = _OSTREE_FEATURE_NO; + gboolean fsverity_required = FALSE; + if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_section, "required", FALSE, + &fsverity_required, error)) return FALSE; - if (fsverity_opportunistic) - self->fs_verity_wanted = _OSTREE_FEATURE_MAYBE; + if (fsverity_required) + { + self->fs_verity_wanted = _OSTREE_FEATURE_YES; + } + else + { + gboolean fsverity_opportunistic = FALSE; + if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_section, "opportunistic", + FALSE, &fsverity_opportunistic, error)) + return FALSE; + if (fsverity_opportunistic) + self->fs_verity_wanted = _OSTREE_FEATURE_MAYBE; + } } + if (self->fs_verity_wanted == _OSTREE_FEATURE_YES + && self->fs_verity_supported == _OSTREE_FEATURE_NO) + return glnx_throw (error, "fsverity required, but libostree compiled without support"); + return TRUE; } - /* Wrapper around the fsverity ioctl, compressing the result to * "success, unsupported or error". This is used for /boot where * we enable verity if supported. * */ gboolean -_ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf, - _OstreeFeatureSupport fsverity_requested, - gboolean *supported, - GError **error) +_ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf, _OstreeFeatureSupport fsverity_requested, + GBytes *signature, gboolean *supported, GError **error) { /* Set this by default to simplify the code below */ if (supported) @@ -88,27 +124,29 @@ _ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf, if (!glnx_tmpfile_reopen_rdonly (tmpf, error)) return FALSE; - struct fsverity_enable_arg arg = { 0, }; + struct fsverity_enable_arg arg = { + 0, + }; arg.version = 1; - arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256; /* TODO configurable? */ - arg.block_size = 4096; /* FIXME query */ - arg.salt_size = 0; /* TODO store salt in ostree repo config */ + arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256; /* TODO configurable? */ + arg.block_size = 4096; /* FIXME query */ + arg.salt_size = 0; /* TODO store salt in ostree repo config */ arg.salt_ptr = 0; - arg.sig_size = 0; /* We don't currently expect use of in-kernel signature verification */ - arg.sig_ptr = 0; + arg.sig_size = signature ? g_bytes_get_size (signature) : 0; + arg.sig_ptr = signature ? (guint64)g_bytes_get_data (signature, NULL) : 0; if (ioctl (tmpf->fd, FS_IOC_ENABLE_VERITY, &arg) < 0) { switch (errno) { - case ENOTTY: - case EOPNOTSUPP: - return TRUE; - default: - return glnx_throw_errno_prefix (error, "ioctl(FS_IOC_ENABLE_VERITY)"); + case ENOTTY: + case EOPNOTSUPP: + return TRUE; + default: + return glnx_throw_errno_prefix (error, "ioctl(FS_IOC_ENABLE_VERITY)"); } } - + if (supported) *supported = TRUE; #endif @@ -121,9 +159,7 @@ _ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf, * as well as to support "opportunistic" use (requested and if filesystem supports). * */ gboolean -_ostree_tmpf_fsverity (OstreeRepo *self, - GLnxTmpfile *tmpf, - GError **error) +_ostree_tmpf_fsverity (OstreeRepo *self, GLnxTmpfile *tmpf, GBytes *signature, GError **error) { #ifdef HAVE_LINUX_FSVERITY_H g_mutex_lock (&self->txn_lock); @@ -133,20 +169,20 @@ _ostree_tmpf_fsverity (OstreeRepo *self, switch (fsverity_wanted) { - case _OSTREE_FEATURE_YES: - { - if (fsverity_supported == _OSTREE_FEATURE_NO) - return glnx_throw (error, "fsverity required but filesystem does not support it"); - } - break; - case _OSTREE_FEATURE_MAYBE: - break; - case _OSTREE_FEATURE_NO: - return TRUE; + case _OSTREE_FEATURE_YES: + { + if (fsverity_supported == _OSTREE_FEATURE_NO) + return glnx_throw (error, "fsverity required but filesystem does not support it"); + } + break; + case _OSTREE_FEATURE_MAYBE: + break; + case _OSTREE_FEATURE_NO: + return TRUE; } gboolean supported = FALSE; - if (!_ostree_tmpf_fsverity_core (tmpf, fsverity_wanted, &supported, error)) + if (!_ostree_tmpf_fsverity_core (tmpf, fsverity_wanted, signature, &supported, error)) return FALSE; if (!supported) @@ -161,7 +197,7 @@ _ostree_tmpf_fsverity (OstreeRepo *self, g_mutex_unlock (&self->txn_lock); return TRUE; } - + g_mutex_lock (&self->txn_lock); self->fs_verity_supported = _OSTREE_FEATURE_YES; g_mutex_unlock (&self->txn_lock); diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 994db62..04a5402 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -23,32 +23,33 @@ #include "config.h" -#include -#include -#include -#include #include "libglnx.h" #include "ostree-core.h" #include "otutil.h" +#include +#include +#include +#include #include #include +#include "ostree-autocleanups.h" #include "ostree-core-private.h" -#include "ostree-sysroot-private.h" +#include "ostree-gpg-verifier.h" #include "ostree-remote-private.h" -#include "ostree-repo-private.h" -#include "ostree-repo-file.h" #include "ostree-repo-file-enumerator.h" -#include "ostree-gpg-verifier.h" +#include "ostree-repo-file.h" +#include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" +#include "ostree-sign-private.h" +#include "ostree-sysroot-private.h" #include "ot-fs-utils.h" -#include "ostree-autocleanups.h" -#include #include +#include #include -#include #include +#include #define REPO_LOCK_DISABLED (-2) #define REPO_LOCK_BLOCKING (-1) @@ -61,27 +62,20 @@ * `$ pahole OstreeRepoTransactionStats`. */ #if __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 8 && __SIZEOF_INT__ == 4 -G_STATIC_ASSERT(sizeof(OstreeRepoTransactionStats) == sizeof(int) * 4 + 8 * 5); -G_STATIC_ASSERT(sizeof(OstreeRepoImportArchiveOptions) == sizeof(int) * 9 + 4 + sizeof(void*) * 8); -G_STATIC_ASSERT(sizeof(OstreeRepoExportArchiveOptions) == sizeof(int) * 9 + 4 + 8 + sizeof(void*) * 8); -G_STATIC_ASSERT(sizeof(OstreeRepoCheckoutAtOptions) == - sizeof(OstreeRepoCheckoutMode) + sizeof(OstreeRepoCheckoutOverwriteMode) + - sizeof(int)*6 + - sizeof(int)*5 + - sizeof(int) + - sizeof(void*)*2 + - sizeof(int)*6 + - sizeof(void*)*7); -G_STATIC_ASSERT(sizeof(OstreeRepoCommitTraverseIter) == - sizeof(int) + sizeof(int) + - sizeof(void*) * 10 + - 130 + 6); /* 6 byte hole */ -G_STATIC_ASSERT(sizeof(OstreeRepoPruneOptions) == - sizeof(OstreeRepoPruneFlags) + - 4 + - sizeof(void*) + - sizeof(int) * 12 + - sizeof(void*) * 7); +G_STATIC_ASSERT (sizeof (OstreeRepoTransactionStats) == sizeof (int) * 4 + 8 * 5); +G_STATIC_ASSERT (sizeof (OstreeRepoImportArchiveOptions) + == sizeof (int) * 9 + 4 + sizeof (void *) * 8); +G_STATIC_ASSERT (sizeof (OstreeRepoExportArchiveOptions) + == sizeof (int) * 9 + 4 + 8 + sizeof (void *) * 8); +G_STATIC_ASSERT (sizeof (OstreeRepoCheckoutAtOptions) + == sizeof (OstreeRepoCheckoutMode) + sizeof (OstreeRepoCheckoutOverwriteMode) + + sizeof (int) * 6 + sizeof (int) * 5 + sizeof (int) + sizeof (void *) * 2 + + sizeof (int) * 6 + sizeof (void *) * 7); +G_STATIC_ASSERT (sizeof (OstreeRepoCommitTraverseIter) + == sizeof (int) + sizeof (int) + sizeof (void *) * 10 + 130 + 6); /* 6 byte hole */ +G_STATIC_ASSERT (sizeof (OstreeRepoPruneOptions) + == sizeof (OstreeRepoPruneFlags) + 4 + sizeof (void *) + sizeof (int) * 12 + + sizeof (void *) * 7); #endif /** @@ -138,17 +132,17 @@ G_STATIC_ASSERT(sizeof(OstreeRepoPruneOptions) == * `org.exampleos.Main` and `org.exampleos.Apps`. For the complete format of * collection IDs, see ostree_validate_collection_id(). */ -typedef struct { +typedef struct +{ GObjectClass parent_class; #ifndef OSTREE_DISABLE_GPGME - void (*gpg_verify_result) (OstreeRepo *self, - const char *checksum, - OstreeGpgVerifyResult *result); + void (*gpg_verify_result) (OstreeRepo *self, const char *checksum, OstreeGpgVerifyResult *result); #endif } OstreeRepoClass; -enum { +enum +{ PROP_0, PROP_PATH, @@ -156,7 +150,8 @@ enum { PROP_SYSROOT_PATH }; -enum { +enum +{ GPG_VERIFY_RESULT, LAST_SIGNAL }; @@ -209,7 +204,8 @@ G_DEFINE_TYPE (OstreeRepo, ostree_repo, G_TYPE_OBJECT) * operations performed. */ -typedef struct { +typedef struct +{ guint len; int state; const char *name; @@ -232,8 +228,7 @@ lock_state_name (int state) } static void -repo_lock_info (OstreeRepo *self, GMutexLocker *locker, - OstreeRepoLockInfo *out_info) +repo_lock_info (OstreeRepo *self, GMutexLocker *locker, OstreeRepoLockInfo *out_info) { g_assert (self != NULL); g_assert (locker != NULL); @@ -242,11 +237,11 @@ repo_lock_info (OstreeRepo *self, GMutexLocker *locker, OstreeRepoLockInfo info; info.len = self->lock.shared + self->lock.exclusive; if (info.len == 0) - info.state = LOCK_UN; + info.state = LOCK_UN; else if (self->lock.exclusive > 0) - info.state = LOCK_EX; + info.state = LOCK_EX; else - info.state = LOCK_SH; + info.state = LOCK_SH; info.name = lock_state_name (info.state); *out_info = info; @@ -254,8 +249,7 @@ repo_lock_info (OstreeRepo *self, GMutexLocker *locker, /* Wrapper to handle flock vs OFD locking based on GLnxLockFile */ static gboolean -do_repo_lock (int fd, - int flags) +do_repo_lock (int fd, int flags) { int res; @@ -287,8 +281,7 @@ do_repo_lock (int fd, /* Wrapper to handle flock vs OFD unlocking based on GLnxLockFile */ static gboolean -do_repo_unlock (int fd, - int flags) +do_repo_unlock (int fd, int flags) { int res; @@ -319,27 +312,22 @@ do_repo_unlock (int fd, } static gboolean -push_repo_lock (OstreeRepo *self, - OstreeRepoLockType lock_type, - gboolean blocking, - GError **error) +push_repo_lock (OstreeRepo *self, OstreeRepoLockType lock_type, gboolean blocking, GError **error) { int flags = (lock_type == OSTREE_REPO_LOCK_EXCLUSIVE) ? LOCK_EX : LOCK_SH; int next_state = flags; if (!blocking) flags |= LOCK_NB; - g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->lock.mutex); + g_autoptr (GMutexLocker) locker = g_mutex_locker_new (&self->lock.mutex); if (self->lock.fd == -1) { g_debug ("Opening repo lock file"); - self->lock.fd = TEMP_FAILURE_RETRY (openat (self->repo_dir_fd, ".lock", - O_CREAT | O_RDWR | O_CLOEXEC, - DEFAULT_REGFILE_MODE)); + self->lock.fd = TEMP_FAILURE_RETRY ( + openat (self->repo_dir_fd, ".lock", O_CREAT | O_RDWR | O_CLOEXEC, DEFAULT_REGFILE_MODE)); if (self->lock.fd < 0) - return glnx_throw_errno_prefix (error, - "Opening lock file %s/.lock failed", + return glnx_throw_errno_prefix (error, "Opening lock file %s/.lock failed", gs_file_get_path_cached (self->repodir)); } @@ -349,9 +337,9 @@ push_repo_lock (OstreeRepo *self, guint *counter; if (next_state == LOCK_EX) - counter = &(self->lock.exclusive); + counter = &(self->lock.exclusive); else - counter = &(self->lock.shared); + counter = &(self->lock.shared); /* Check for overflow */ if (*counter == G_MAXUINT) @@ -369,8 +357,7 @@ push_repo_lock (OstreeRepo *self, const char *next_state_name = lock_state_name (next_state); g_debug ("Locking repo %s", next_state_name); if (!do_repo_lock (self->lock.fd, flags)) - return glnx_throw_errno_prefix (error, "Locking repo %s failed", - next_state_name); + return glnx_throw_errno_prefix (error, "Locking repo %s failed", next_state_name); } /* Update state */ @@ -380,14 +367,11 @@ push_repo_lock (OstreeRepo *self, } static gboolean -pop_repo_lock (OstreeRepo *self, - OstreeRepoLockType lock_type, - gboolean blocking, - GError **error) +pop_repo_lock (OstreeRepo *self, OstreeRepoLockType lock_type, gboolean blocking, GError **error) { int flags = blocking ? 0 : LOCK_NB; - g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->lock.mutex); + g_autoptr (GMutexLocker) locker = g_mutex_locker_new (&self->lock.mutex); if (self->lock.fd == -1) g_error ("Cannot pop repo never locked repo lock"); @@ -443,8 +427,7 @@ pop_repo_lock (OstreeRepo *self, g_assert (next_state == LOCK_SH); g_debug ("Returning lock state to shared"); if (!do_repo_lock (self->lock.fd, next_state | flags)) - return glnx_throw_errno_prefix (error, - "Setting repo lock to shared failed"); + return glnx_throw_errno_prefix (error, "Setting repo lock to shared failed"); } /* Update state */ @@ -482,10 +465,8 @@ pop_repo_lock (OstreeRepo *self, * Since: 2021.3 */ gboolean -ostree_repo_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error) +ostree_repo_lock_push (OstreeRepo *self, OstreeRepoLockType lock_type, GCancellable *cancellable, + GError **error) { g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); @@ -509,19 +490,17 @@ ostree_repo_lock_push (OstreeRepo *self, /* Convert to unsigned to guard against negative values */ guint lock_timeout_seconds = self->lock_timeout_seconds; guint waited = 0; - g_debug ("Pushing lock non-blocking with timeout %u", - lock_timeout_seconds); + g_debug ("Pushing lock non-blocking with timeout %u", lock_timeout_seconds); for (;;) { if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; if (push_repo_lock (self, lock_type, FALSE, &local_error)) return TRUE; - if (!g_error_matches (local_error, G_IO_ERROR, - G_IO_ERROR_WOULD_BLOCK)) + if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; @@ -529,8 +508,7 @@ ostree_repo_lock_push (OstreeRepo *self, if (waited >= lock_timeout_seconds) { - g_debug ("Push lock: Could not acquire lock within %u seconds", - lock_timeout_seconds); + g_debug ("Push lock: Could not acquire lock within %u seconds", lock_timeout_seconds); g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; } @@ -539,8 +517,8 @@ ostree_repo_lock_push (OstreeRepo *self, if (waited % 60 == 0) { guint remaining = lock_timeout_seconds - waited; - g_debug ("Push lock: Waiting %u more second%s to acquire lock", - remaining, (remaining == 1) ? "" : "s"); + g_debug ("Push lock: Waiting %u more second%s to acquire lock", remaining, + (remaining == 1) ? "" : "s"); } waited++; sleep (1); @@ -576,10 +554,8 @@ ostree_repo_lock_push (OstreeRepo *self, * Since: 2021.3 */ gboolean -ostree_repo_lock_pop (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error) +ostree_repo_lock_pop (OstreeRepo *self, OstreeRepoLockType lock_type, GCancellable *cancellable, + GError **error) { g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); @@ -603,19 +579,17 @@ ostree_repo_lock_pop (OstreeRepo *self, /* Convert to unsigned to guard against negative values */ guint lock_timeout_seconds = self->lock_timeout_seconds; guint waited = 0; - g_debug ("Popping lock non-blocking with timeout %u", - lock_timeout_seconds); + g_debug ("Popping lock non-blocking with timeout %u", lock_timeout_seconds); for (;;) { if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; if (pop_repo_lock (self, lock_type, FALSE, &local_error)) return TRUE; - if (!g_error_matches (local_error, G_IO_ERROR, - G_IO_ERROR_WOULD_BLOCK)) + if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; @@ -623,8 +597,7 @@ ostree_repo_lock_pop (OstreeRepo *self, if (waited >= lock_timeout_seconds) { - g_debug ("Pop lock: Could not remove lock within %u seconds", - lock_timeout_seconds); + g_debug ("Pop lock: Could not remove lock within %u seconds", lock_timeout_seconds); g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; } @@ -633,8 +606,8 @@ ostree_repo_lock_pop (OstreeRepo *self, if (waited % 60 == 0) { guint remaining = lock_timeout_seconds - waited; - g_debug ("Pop lock: Waiting %u more second%s to remove lock", - remaining, (remaining == 1) ? "" : "s"); + g_debug ("Pop lock: Waiting %u more second%s to remove lock", remaining, + (remaining == 1) ? "" : "s"); } waited++; sleep (1); @@ -642,7 +615,8 @@ ostree_repo_lock_pop (OstreeRepo *self, } } -struct OstreeRepoAutoLock { +struct OstreeRepoAutoLock +{ OstreeRepo *repo; OstreeRepoLockType lock_type; }; @@ -670,10 +644,8 @@ struct OstreeRepoAutoLock { * Since: 2021.3 */ OstreeRepoAutoLock * -ostree_repo_auto_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error) +ostree_repo_auto_lock_push (OstreeRepo *self, OstreeRepoLockType lock_type, + GCancellable *cancellable, GError **error) { if (!ostree_repo_lock_push (self, lock_type, cancellable, error)) return NULL; @@ -699,7 +671,7 @@ ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *auto_lock) { if (auto_lock != NULL) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; int errsv = errno; if (!ostree_repo_lock_pop (auto_lock->repo, auto_lock->lock_type, NULL, &error)) @@ -730,7 +702,7 @@ _ostree_repo_auto_transaction_new (OstreeRepo *repo) { g_assert (repo != NULL); - OstreeRepoAutoTransaction *txn = g_malloc(sizeof(OstreeRepoAutoTransaction)); + OstreeRepoAutoTransaction *txn = g_malloc (sizeof (OstreeRepoAutoTransaction)); txn->atomic_refcount = 1; txn->repo = g_object_ref (repo); @@ -749,9 +721,7 @@ _ostree_repo_auto_transaction_new (OstreeRepo *repo) * %NULL otherwise. */ OstreeRepoAutoTransaction * -_ostree_repo_auto_transaction_start (OstreeRepo *repo, - GCancellable *cancellable, - GError **error) +_ostree_repo_auto_transaction_start (OstreeRepo *repo, GCancellable *cancellable, GError **error) { g_assert (repo != NULL); @@ -772,15 +742,15 @@ _ostree_repo_auto_transaction_start (OstreeRepo *repo, * Returns: %TRUE on successful commit, %FALSE otherwise. */ gboolean -_ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction *txn, - GCancellable *cancellable, - GError **error) +_ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction *txn, GCancellable *cancellable, + GError **error) { g_assert (txn != NULL); - if (txn->repo == NULL) { - return glnx_throw (error, "transaction already completed"); - } + if (txn->repo == NULL) + { + return glnx_throw (error, "transaction already completed"); + } if (!ostree_repo_abort_transaction (txn->repo, cancellable, error)) return FALSE; @@ -802,16 +772,16 @@ _ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction *txn, * Returns: %TRUE on successful aborting, %FALSE otherwise. */ gboolean -_ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction *txn, +_ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction *txn, OstreeRepoTransactionStats *out_stats, - GCancellable *cancellable, - GError **error) + GCancellable *cancellable, GError **error) { g_assert (txn != NULL); - if (txn->repo == NULL) { - return glnx_throw (error, "transaction already completed"); - } + if (txn->repo == NULL) + { + return glnx_throw (error, "transaction already completed"); + } if (!ostree_repo_commit_transaction (txn->repo, out_stats, cancellable, error)) return FALSE; @@ -859,9 +829,9 @@ _ostree_repo_auto_transaction_unref (OstreeRepoAutoTransaction *txn) // Auto-abort only if transaction has not already been aborted/committed. if (txn->repo != NULL) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; if (!ostree_repo_abort_transaction (txn->repo, NULL, &error)) - g_warning("Failed to auto-cleanup OSTree transaction: %s", error->message); + g_warning ("Failed to auto-cleanup OSTree transaction: %s", error->message); g_clear_object (&txn->repo); } @@ -870,18 +840,13 @@ _ostree_repo_auto_transaction_unref (OstreeRepoAutoTransaction *txn) return; } -G_DEFINE_BOXED_TYPE(OstreeRepoAutoTransaction, _ostree_repo_auto_transaction, - _ostree_repo_auto_transaction_ref, - _ostree_repo_auto_transaction_unref); +G_DEFINE_BOXED_TYPE (OstreeRepoAutoTransaction, _ostree_repo_auto_transaction, + _ostree_repo_auto_transaction_ref, _ostree_repo_auto_transaction_unref); -static GFile * -get_remotes_d_dir (OstreeRepo *self, - GFile *sysroot); +static GFile *get_remotes_d_dir (OstreeRepo *self, GFile *sysroot); OstreeRemote * -_ostree_repo_get_remote (OstreeRepo *self, - const char *name, - GError **error) +_ostree_repo_get_remote (OstreeRepo *self, const char *name, GError **error) { OstreeRemote *remote = NULL; @@ -894,8 +859,7 @@ _ostree_repo_get_remote (OstreeRepo *self, if (remote != NULL) ostree_remote_ref (remote); else - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Remote \"%s\" not found", name); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Remote \"%s\" not found", name); g_mutex_unlock (&self->remotes_lock); @@ -903,12 +867,10 @@ _ostree_repo_get_remote (OstreeRepo *self, } OstreeRemote * -_ostree_repo_get_remote_inherited (OstreeRepo *self, - const char *name, - GError **error) +_ostree_repo_get_remote_inherited (OstreeRepo *self, const char *name, GError **error) { - g_autoptr(OstreeRemote) remote = NULL; - g_autoptr(GError) temp_error = NULL; + g_autoptr (OstreeRemote) remote = NULL; + g_autoptr (GError) temp_error = NULL; remote = _ostree_repo_get_remote (self, name, &temp_error); if (remote == NULL) @@ -924,8 +886,7 @@ _ostree_repo_get_remote_inherited (OstreeRepo *self, } gboolean -_ostree_repo_add_remote (OstreeRepo *self, - OstreeRemote *remote) +_ostree_repo_add_remote (OstreeRepo *self, OstreeRemote *remote) { gboolean already_existed; @@ -943,8 +904,7 @@ _ostree_repo_add_remote (OstreeRepo *self, } gboolean -_ostree_repo_remove_remote (OstreeRepo *self, - OstreeRemote *remote) +_ostree_repo_remove_remote (OstreeRepo *self, OstreeRemote *remote) { gboolean removed; @@ -972,8 +932,8 @@ _ostree_repo_remote_name_is_file (const char *remote_name) * @self: A OstreeRepo * @remote_name: Name * @option_name: Option - * @default_value: (allow-none): Value returned if @option_name is not present - * @out_value: (out): Return location for value + * @default_value: (nullable): Value returned if @option_name is not present + * @out_value: (out) (nullable): Return location for value * @error: Error * * OSTree remotes are represented by keyfile groups, formatted like: @@ -986,16 +946,12 @@ _ostree_repo_remote_name_is_file (const char *remote_name) * Since: 2016.5 */ gboolean -ostree_repo_get_remote_option (OstreeRepo *self, - const char *remote_name, - const char *option_name, - const char *default_value, - char **out_value, - GError **error) -{ - g_autoptr(OstreeRemote) remote = NULL; +ostree_repo_get_remote_option (OstreeRepo *self, const char *remote_name, const char *option_name, + const char *default_value, char **out_value, GError **error) +{ + g_autoptr (OstreeRemote) remote = NULL; gboolean ret = FALSE; - g_autoptr(GError) temp_error = NULL; + g_autoptr (GError) temp_error = NULL; g_autofree char *value = NULL; if (_ostree_repo_remote_name_is_file (remote_name)) @@ -1015,12 +971,9 @@ ostree_repo_get_remote_option (OstreeRepo *self, /* Note: We ignore errors on the parent because the parent config may not specify this remote, causing a "remote not found" error, but we found the remote at some point, so we need to instead return the default */ - if (self->parent_repo != NULL && - ostree_repo_get_remote_option (self->parent_repo, - remote_name, option_name, - default_value, - out_value, - NULL)) + if (self->parent_repo != NULL + && ostree_repo_get_remote_option (self->parent_repo, remote_name, option_name, + default_value, out_value, NULL)) return TRUE; value = g_strdup (default_value); @@ -1033,11 +986,8 @@ ostree_repo_get_remote_option (OstreeRepo *self, ret = TRUE; } else if (self->parent_repo != NULL) - return ostree_repo_get_remote_option (self->parent_repo, - remote_name, option_name, - default_value, - out_value, - error); + return ostree_repo_get_remote_option (self->parent_repo, remote_name, option_name, + default_value, out_value, error); else g_propagate_error (error, g_steal_pointer (&temp_error)); @@ -1066,16 +1016,13 @@ ostree_repo_get_remote_option (OstreeRepo *self, * Since: 2016.5 */ gboolean -ostree_repo_get_remote_list_option (OstreeRepo *self, - const char *remote_name, - const char *option_name, - char ***out_value, - GError **error) +ostree_repo_get_remote_list_option (OstreeRepo *self, const char *remote_name, + const char *option_name, char ***out_value, GError **error) { - g_autoptr(OstreeRemote) remote = NULL; + g_autoptr (OstreeRemote) remote = NULL; gboolean ret = FALSE; - g_autoptr(GError) temp_error = NULL; - g_auto(GStrv) value = NULL; + g_autoptr (GError) temp_error = NULL; + g_auto (GStrv) value = NULL; if (_ostree_repo_remote_name_is_file (remote_name)) { @@ -1086,10 +1033,8 @@ ostree_repo_get_remote_list_option (OstreeRepo *self, remote = _ostree_repo_get_remote (self, remote_name, &temp_error); if (remote != NULL) { - value = g_key_file_get_string_list (remote->options, - remote->group, - option_name, - NULL, &temp_error); + value = g_key_file_get_string_list (remote->options, remote->group, option_name, NULL, + &temp_error); /* Default value if key not found is always NULL. */ if (g_error_matches (temp_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) @@ -1097,11 +1042,9 @@ ostree_repo_get_remote_list_option (OstreeRepo *self, /* Note: We ignore errors on the parent because the parent config may not specify this remote, causing a "remote not found" error, but we found the remote at some point, so we need to instead return the default */ - if (self->parent_repo != NULL && - ostree_repo_get_remote_list_option (self->parent_repo, - remote_name, option_name, - out_value, - NULL)) + if (self->parent_repo != NULL + && ostree_repo_get_remote_list_option (self->parent_repo, remote_name, option_name, + out_value, NULL)) return TRUE; ret = TRUE; @@ -1112,10 +1055,8 @@ ostree_repo_get_remote_list_option (OstreeRepo *self, ret = TRUE; } else if (self->parent_repo != NULL) - return ostree_repo_get_remote_list_option (self->parent_repo, - remote_name, option_name, - out_value, - error); + return ostree_repo_get_remote_list_option (self->parent_repo, remote_name, option_name, + out_value, error); else g_propagate_error (error, g_steal_pointer (&temp_error)); @@ -1143,15 +1084,12 @@ ostree_repo_get_remote_list_option (OstreeRepo *self, * Since: 2016.5 */ gboolean -ostree_repo_get_remote_boolean_option (OstreeRepo *self, - const char *remote_name, - const char *option_name, - gboolean default_value, - gboolean *out_value, - GError **error) -{ - g_autoptr(OstreeRemote) remote = NULL; - g_autoptr(GError) temp_error = NULL; +ostree_repo_get_remote_boolean_option (OstreeRepo *self, const char *remote_name, + const char *option_name, gboolean default_value, + gboolean *out_value, GError **error) +{ + g_autoptr (OstreeRemote) remote = NULL; + g_autoptr (GError) temp_error = NULL; gboolean ret = FALSE; gboolean value = FALSE; @@ -1172,12 +1110,9 @@ ostree_repo_get_remote_boolean_option (OstreeRepo *self, /* Note: We ignore errors on the parent because the parent config may not specify this remote, causing a "remote not found" error, but we found the remote at some point, so we need to instead return the default */ - if (self->parent_repo != NULL && - ostree_repo_get_remote_boolean_option (self->parent_repo, - remote_name, option_name, - default_value, - out_value, - NULL)) + if (self->parent_repo != NULL + && ostree_repo_get_remote_boolean_option ( + self->parent_repo, remote_name, option_name, default_value, out_value, NULL)) return TRUE; value = default_value; @@ -1190,11 +1125,8 @@ ostree_repo_get_remote_boolean_option (OstreeRepo *self, ret = TRUE; } else if (self->parent_repo != NULL) - return ostree_repo_get_remote_boolean_option (self->parent_repo, - remote_name, option_name, - default_value, - out_value, - error); + return ostree_repo_get_remote_boolean_option (self->parent_repo, remote_name, option_name, + default_value, out_value, error); else g_propagate_error (error, g_steal_pointer (&temp_error)); @@ -1238,6 +1170,7 @@ ostree_repo_finalize (GObject *object) g_mutex_clear (&self->txn_lock); g_free (self->collection_id); g_strfreev (self->repo_finders); + g_clear_pointer (&self->bls_append_values, g_hash_table_unref); g_clear_pointer (&self->remotes, g_hash_table_destroy); g_mutex_clear (&self->remotes_lock); @@ -1249,10 +1182,7 @@ ostree_repo_finalize (GObject *object) } static void -ostree_repo_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +ostree_repo_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { OstreeRepo *self = OSTREE_REPO (object); @@ -1274,10 +1204,7 @@ ostree_repo_set_property(GObject *object, } static void -ostree_repo_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +ostree_repo_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { OstreeRepo *self = OSTREE_REPO (object); @@ -1317,11 +1244,10 @@ ostree_repo_class_init (OstreeRepoClass *klass) * to the repository's directory fd via `ostree_repo_get_dfd()` and * use file-descriptor relative operations. */ - g_object_class_install_property (object_class, - PROP_PATH, - g_param_spec_object ("path", "Path", "Path", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( + object_class, PROP_PATH, + g_param_spec_object ("path", "Path", "Path", G_TYPE_FILE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * OstreeRepo:sysroot-path: * @@ -1333,13 +1259,10 @@ ostree_repo_class_init (OstreeRepoClass *klass) * on a system repository, use `OstreeSysroot` and access the repository * object via `ostree_sysroot_repo()`. */ - g_object_class_install_property (object_class, - PROP_SYSROOT_PATH, - g_param_spec_object ("sysroot-path", - "", - "", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( + object_class, PROP_SYSROOT_PATH, + g_param_spec_object ("sysroot-path", "", "", G_TYPE_FILE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * OstreeRepo:remotes-config-dir: * @@ -1349,13 +1272,10 @@ ostree_repo_class_init (OstreeRepoClass *klass) * * This value will only be used for system repositories. */ - g_object_class_install_property (object_class, - PROP_REMOTES_CONFIG_DIR, - g_param_spec_string ("remotes-config-dir", - "", - "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( + object_class, PROP_REMOTES_CONFIG_DIR, + g_param_spec_string ("remotes-config-dir", "", "", NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); #ifndef OSTREE_DISABLE_GPGME /** @@ -1372,14 +1292,10 @@ ostree_repo_class_init (OstreeRepoClass *klass) * thread-default at the point when ostree_repo_pull_with_options() * is called. */ - signals[GPG_VERIFY_RESULT] = g_signal_new ("gpg-verify-result", - OSTREE_TYPE_REPO, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (OstreeRepoClass, gpg_verify_result), - NULL, NULL, NULL, - G_TYPE_NONE, 2, - G_TYPE_STRING, - OSTREE_TYPE_GPG_VERIFY_RESULT); + signals[GPG_VERIFY_RESULT] + = g_signal_new ("gpg-verify-result", OSTREE_TYPE_REPO, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (OstreeRepoClass, gpg_verify_result), NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_STRING, OSTREE_TYPE_GPG_VERIFY_RESULT); #endif /* OSTREE_DISABLE_GPGME */ } @@ -1409,9 +1325,10 @@ ostree_repo_init (OstreeRepo *self) g_mutex_init (&self->cache_lock); g_mutex_init (&self->txn_lock); - self->remotes = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) ostree_remote_unref); + self->remotes = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)NULL, + (GDestroyNotify)ostree_remote_unref); + self->bls_append_values = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, + (GDestroyNotify)g_free); g_mutex_init (&self->remotes_lock); self->repo_dir_fd = -1; @@ -1429,19 +1346,17 @@ ostree_repo_init (OstreeRepo *self) * * Returns: (transfer full): An accessor object for an OSTree repository located at @path */ -OstreeRepo* +OstreeRepo * ostree_repo_new (GFile *path) { return g_object_new (OSTREE_TYPE_REPO, "path", path, NULL); } static OstreeRepo * -repo_open_at_take_fd (int *dfd, - GCancellable *cancellable, - GError **error) +repo_open_at_take_fd (int *dfd, GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = g_object_new (OSTREE_TYPE_REPO, NULL); - repo->repo_dir_fd = glnx_steal_fd (dfd); + g_autoptr (OstreeRepo) repo = g_object_new (OSTREE_TYPE_REPO, NULL); + repo->repo_dir_fd = g_steal_fd (dfd); if (!ostree_repo_open (repo, cancellable, error)) return NULL; @@ -1461,11 +1376,8 @@ repo_open_at_take_fd (int *dfd, * * Since: 2017.10 */ -OstreeRepo* -ostree_repo_open_at (int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +OstreeRepo * +ostree_repo_open_at (int dfd, const char *path, GCancellable *cancellable, GError **error) { glnx_autofd int repo_dfd = -1; if (!glnx_opendirat (dfd, path, TRUE, &repo_dfd, error)) @@ -1494,8 +1406,7 @@ get_default_repo_path (GFile *sysroot_path) * Returns: (transfer full): An accessor object for the OSTree repository located at @repo_path. */ OstreeRepo * -ostree_repo_new_for_sysroot_path (GFile *repo_path, - GFile *sysroot_path) +ostree_repo_new_for_sysroot_path (GFile *repo_path, GFile *sysroot_path) { return g_object_new (OSTREE_TYPE_REPO, "path", repo_path, "sysroot-path", sysroot_path, NULL); } @@ -1511,19 +1422,18 @@ ostree_repo_new_for_sysroot_path (GFile *repo_path, * * Returns: (transfer full): An accessor object for an OSTree repository located at /ostree/repo */ -OstreeRepo* +OstreeRepo * ostree_repo_new_default (void) { - if (g_file_test ("objects", G_FILE_TEST_IS_DIR) - && g_file_test ("config", G_FILE_TEST_IS_REGULAR)) + if (g_file_test ("objects", G_FILE_TEST_IS_DIR) && g_file_test ("config", G_FILE_TEST_IS_REGULAR)) { - g_autoptr(GFile) cwd = g_file_new_for_path ("."); + g_autoptr (GFile) cwd = g_file_new_for_path ("."); return ostree_repo_new (cwd); } else { const char *envvar = g_getenv ("OSTREE_REPO"); - g_autoptr(GFile) repo_path = NULL; + g_autoptr (GFile) repo_path = NULL; if (envvar == NULL || *envvar == '\0') repo_path = get_default_repo_path (NULL); @@ -1541,15 +1451,15 @@ ostree_repo_new_default (void) * Returns: %TRUE if this repository is the root-owned system global repository */ gboolean -ostree_repo_is_system (OstreeRepo *repo) +ostree_repo_is_system (OstreeRepo *repo) { g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE); /* If we were created via ostree_sysroot_get_repo(), we know the answer is yes * without having to compare file paths. */ - if (repo->sysroot_kind == OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT || - repo->sysroot_kind == OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE) + if (repo->sysroot_kind == OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT + || repo->sysroot_kind == OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE) return TRUE; /* No sysroot_dir set? Not a system repo then. */ @@ -1561,7 +1471,7 @@ ostree_repo_is_system (OstreeRepo *repo) */ if (repo->repodir) { - g_autoptr(GFile) default_repo_path = get_default_repo_path (repo->sysroot_dir); + g_autoptr (GFile) default_repo_path = get_default_repo_path (repo->sysroot_dir); return g_file_equal (repo->repodir, default_repo_path); } /* Otherwise, not a system repo */ @@ -1579,8 +1489,7 @@ ostree_repo_is_system (OstreeRepo *repo) * Returns: %TRUE if this repository is writable */ gboolean -ostree_repo_is_writable (OstreeRepo *self, - GError **error) +ostree_repo_is_writable (OstreeRepo *self, GError **error) { g_assert (self != NULL); g_assert (self->inited); @@ -1601,8 +1510,7 @@ ostree_repo_is_writable (OstreeRepo *self, * can detect that the refs have updated. */ gboolean -_ostree_repo_update_mtime (OstreeRepo *self, - GError **error) +_ostree_repo_update_mtime (OstreeRepo *self, GError **error) { if (futimens (self->repo_dir_fd, NULL) != 0) { @@ -1660,9 +1568,7 @@ ostree_repo_copy_config (OstreeRepo *self) * Save @new_config in place of this repository's config file. */ gboolean -ostree_repo_write_config (OstreeRepo *self, - GKeyFile *new_config, - GError **error) +ostree_repo_write_config (OstreeRepo *self, GKeyFile *new_config, GError **error) { g_return_val_if_fail (self->inited, FALSE); @@ -1670,20 +1576,19 @@ ostree_repo_write_config (OstreeRepo *self, * separate config file. */ gsize num_groups; - g_auto(GStrv) groups = g_key_file_get_groups (new_config, &num_groups); + g_auto (GStrv) groups = g_key_file_get_groups (new_config, &num_groups); for (gsize i = 0; i < num_groups; i++) { - g_autoptr(OstreeRemote) new_remote = ostree_remote_new_from_keyfile (new_config, groups[i]); + g_autoptr (OstreeRemote) new_remote = ostree_remote_new_from_keyfile (new_config, groups[i]); if (new_remote != NULL) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; - g_autoptr(OstreeRemote) cur_remote = - _ostree_repo_get_remote (self, new_remote->name, &local_error); + g_autoptr (OstreeRemote) cur_remote + = _ostree_repo_get_remote (self, new_remote->name, &local_error); if (cur_remote == NULL) { - if (!g_error_matches (local_error, G_IO_ERROR, - G_IO_ERROR_NOT_FOUND)) + if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; @@ -1692,8 +1597,7 @@ ostree_repo_write_config (OstreeRepo *self, else if (cur_remote->file != NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS, - "Remote \"%s\" already defined in %s", - new_remote->name, + "Remote \"%s\" already defined in %s", new_remote->name, gs_file_get_path_cached (cur_remote->file)); return FALSE; } @@ -1702,9 +1606,8 @@ ostree_repo_write_config (OstreeRepo *self, gsize len; g_autofree char *data = g_key_file_to_data (new_config, &len, error); - if (!glnx_file_replace_contents_at (self->repo_dir_fd, "config", - (guint8*)data, len, 0, - NULL, error)) + if (!glnx_file_replace_contents_at (self->repo_dir_fd, "config", (guint8 *)data, len, 0, NULL, + error)) return FALSE; g_key_file_free (self->config); @@ -1717,9 +1620,7 @@ ostree_repo_write_config (OstreeRepo *self, /* Bind a subset of an a{sv} to options in a given GKeyfile section */ static void -keyfile_set_from_vardict (GKeyFile *keyfile, - const char *section, - GVariant *vardict) +keyfile_set_from_vardict (GKeyFile *keyfile, const char *section, GVariant *vardict) { GVariantIter viter; const char *key; @@ -1728,7 +1629,7 @@ keyfile_set_from_vardict (GKeyFile *keyfile, g_variant_iter_init (&viter, vardict); while (g_variant_iter_loop (&viter, "{&s@v}", &key, &val)) { - g_autoptr(GVariant) child = g_variant_get_variant (val); + g_autoptr (GVariant) child = g_variant_get_variant (val); if (g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) g_key_file_set_string (keyfile, section, key, g_variant_get_string (child, NULL)); else if (g_variant_is_of_type (child, G_VARIANT_TYPE_BOOLEAN)) @@ -1740,28 +1641,22 @@ keyfile_set_from_vardict (GKeyFile *keyfile, g_key_file_set_string_list (keyfile, section, key, strv_child, len); } else - g_critical ("Unhandled type '%s' in %s", - (char*)g_variant_get_type (child), G_STRFUNC); + g_critical ("Unhandled type '%s' in %s", (char *)g_variant_get_type (child), G_STRFUNC); } } static gboolean -impl_repo_remote_add (OstreeRepo *self, - GFile *sysroot, - gboolean if_not_exists, - const char *name, - const char *url, - GVariant *options, - GCancellable *cancellable, - GError **error) +impl_repo_remote_add (OstreeRepo *self, GFile *sysroot, gboolean if_not_exists, const char *name, + const char *url, GVariant *options, GCancellable *cancellable, GError **error) { g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (options == NULL || g_variant_is_of_type (options, G_VARIANT_TYPE ("a{sv}")), FALSE); + g_return_val_if_fail (options == NULL || g_variant_is_of_type (options, G_VARIANT_TYPE ("a{sv}")), + FALSE); if (!ostree_validate_remote_name (name, error)) return FALSE; - g_autoptr(OstreeRemote) remote = _ostree_repo_get_remote (self, name, NULL); + g_autoptr (OstreeRemote) remote = _ostree_repo_get_remote (self, name, NULL); if (remote != NULL && if_not_exists) { /* Note early return */ @@ -1769,9 +1664,8 @@ impl_repo_remote_add (OstreeRepo *self, } else if (remote != NULL) { - return glnx_throw (error, - "Remote configuration for \"%s\" already exists: %s", - name, remote->file ? gs_file_get_path_cached (remote->file) : "(in config)"); + return glnx_throw (error, "Remote configuration for \"%s\" already exists: %s", name, + remote->file ? gs_file_get_path_cached (remote->file) : "(in config)"); } remote = ostree_remote_new (name); @@ -1780,13 +1674,12 @@ impl_repo_remote_add (OstreeRepo *self, * add-remotes-config-dir is true. This is the default for system * repos. */ - g_autoptr(GFile) etc_ostree_remotes_d = get_remotes_d_dir (self, sysroot); + g_autoptr (GFile) etc_ostree_remotes_d = get_remotes_d_dir (self, sysroot); if (etc_ostree_remotes_d && self->add_remotes_config_dir) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; - if (!g_file_make_directory_with_parents (etc_ostree_remotes_d, - cancellable, &local_error)) + if (!g_file_make_directory_with_parents (etc_ostree_remotes_d, cancellable, &local_error)) { if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { @@ -1806,7 +1699,8 @@ impl_repo_remote_add (OstreeRepo *self, if (url) { if (g_str_has_prefix (url, "metalink=")) - g_key_file_set_string (remote->options, remote->group, "metalink", url + strlen ("metalink=")); + g_key_file_set_string (remote->options, remote->group, "metalink", + url + strlen ("metalink=")); else g_key_file_set_string (remote->options, remote->group, "url", url); } @@ -1819,15 +1713,13 @@ impl_repo_remote_add (OstreeRepo *self, gsize length; g_autofree char *data = g_key_file_to_data (remote->options, &length, NULL); - if (!g_file_replace_contents (remote->file, - data, length, - NULL, FALSE, 0, NULL, - cancellable, error)) + if (!g_file_replace_contents (remote->file, data, length, NULL, FALSE, 0, NULL, cancellable, + error)) return FALSE; } else { - g_autoptr(GKeyFile) config = NULL; + g_autoptr (GKeyFile) config = NULL; config = ostree_repo_copy_config (self); ot_keyfile_copy_group (remote->options, config, remote->group); @@ -1860,31 +1752,22 @@ impl_repo_remote_add (OstreeRepo *self, * */ gboolean -ostree_repo_remote_add (OstreeRepo *self, - const char *name, - const char *url, - GVariant *options, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_add (OstreeRepo *self, const char *name, const char *url, GVariant *options, + GCancellable *cancellable, GError **error) { - return impl_repo_remote_add (self, NULL, FALSE, name, url, options, - cancellable, error); + return impl_repo_remote_add (self, NULL, FALSE, name, url, options, cancellable, error); } static gboolean -impl_repo_remote_delete (OstreeRepo *self, - GFile *sysroot, - gboolean if_exists, - const char *name, - GCancellable *cancellable, - GError **error) +impl_repo_remote_delete (OstreeRepo *self, GFile *sysroot, gboolean if_exists, const char *name, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (name != NULL, FALSE); if (!ostree_validate_remote_name (name, error)) return FALSE; - g_autoptr(OstreeRemote) remote = NULL; + g_autoptr (OstreeRemote) remote = NULL; if (if_exists) { remote = _ostree_repo_get_remote (self, name, NULL); @@ -1907,7 +1790,7 @@ impl_repo_remote_delete (OstreeRepo *self, } else { - g_autoptr(GKeyFile) config = ostree_repo_copy_config (self); + g_autoptr (GKeyFile) config = ostree_repo_copy_config (self); /* XXX Not sure it's worth failing if the group to remove * isn't found. It's the end result we want, after all. */ @@ -1939,32 +1822,25 @@ impl_repo_remote_delete (OstreeRepo *self, * */ gboolean -ostree_repo_remote_delete (OstreeRepo *self, - const char *name, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_delete (OstreeRepo *self, const char *name, GCancellable *cancellable, + GError **error) { return impl_repo_remote_delete (self, NULL, FALSE, name, cancellable, error); } - static gboolean -impl_repo_remote_replace (OstreeRepo *self, - GFile *sysroot, - const char *name, - const char *url, - GVariant *options, - GCancellable *cancellable, - GError **error) +impl_repo_remote_replace (OstreeRepo *self, GFile *sysroot, const char *name, const char *url, + GVariant *options, GCancellable *cancellable, GError **error) { g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (options == NULL || g_variant_is_of_type (options, G_VARIANT_TYPE ("a{sv}")), FALSE); + g_return_val_if_fail (options == NULL || g_variant_is_of_type (options, G_VARIANT_TYPE ("a{sv}")), + FALSE); if (!ostree_validate_remote_name (name, error)) return FALSE; - g_autoptr(GError) local_error = NULL; - g_autoptr(OstreeRemote) remote = _ostree_repo_get_remote (self, name, &local_error); + g_autoptr (GError) local_error = NULL; + g_autoptr (OstreeRemote) remote = _ostree_repo_get_remote (self, name, &local_error); if (remote == NULL) { if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) @@ -1973,8 +1849,7 @@ impl_repo_remote_replace (OstreeRepo *self, return FALSE; } g_clear_error (&local_error); - if (!impl_repo_remote_add (self, sysroot, FALSE, name, url, options, - cancellable, error)) + if (!impl_repo_remote_add (self, sysroot, FALSE, name, url, options, cancellable, error)) return FALSE; } else @@ -1999,17 +1874,15 @@ impl_repo_remote_replace (OstreeRepo *self, if (remote->file != NULL) { gsize length; - g_autofree char *data = g_key_file_to_data (remote->options, &length, - NULL); + g_autofree char *data = g_key_file_to_data (remote->options, &length, NULL); - if (!g_file_replace_contents (remote->file, data, length, - NULL, FALSE, 0, NULL, + if (!g_file_replace_contents (remote->file, data, length, NULL, FALSE, 0, NULL, cancellable, error)) return FALSE; } else { - g_autoptr(GKeyFile) config = ostree_repo_copy_config (self); + g_autoptr (GKeyFile) config = ostree_repo_copy_config (self); /* Remove the existing group if it exists */ if (!g_key_file_remove_group (config, remote->group, &local_error)) @@ -2049,39 +1922,28 @@ impl_repo_remote_replace (OstreeRepo *self, * */ gboolean -ostree_repo_remote_change (OstreeRepo *self, - GFile *sysroot, - OstreeRepoRemoteChange changeop, - const char *name, - const char *url, - GVariant *options, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_change (OstreeRepo *self, GFile *sysroot, OstreeRepoRemoteChange changeop, + const char *name, const char *url, GVariant *options, + GCancellable *cancellable, GError **error) { switch (changeop) { case OSTREE_REPO_REMOTE_CHANGE_ADD: - return impl_repo_remote_add (self, sysroot, FALSE, name, url, options, - cancellable, error); + return impl_repo_remote_add (self, sysroot, FALSE, name, url, options, cancellable, error); case OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS: - return impl_repo_remote_add (self, sysroot, TRUE, name, url, options, - cancellable, error); + return impl_repo_remote_add (self, sysroot, TRUE, name, url, options, cancellable, error); case OSTREE_REPO_REMOTE_CHANGE_DELETE: - return impl_repo_remote_delete (self, sysroot, FALSE, name, - cancellable, error); + return impl_repo_remote_delete (self, sysroot, FALSE, name, cancellable, error); case OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS: - return impl_repo_remote_delete (self, sysroot, TRUE, name, - cancellable, error); + return impl_repo_remote_delete (self, sysroot, TRUE, name, cancellable, error); case OSTREE_REPO_REMOTE_CHANGE_REPLACE: - return impl_repo_remote_replace (self, sysroot, name, url, options, - cancellable, error); + return impl_repo_remote_replace (self, sysroot, name, url, options, cancellable, error); } g_assert_not_reached (); } static void -_ostree_repo_remote_list (OstreeRepo *self, - GHashTable *out) +_ostree_repo_remote_list (OstreeRepo *self, GHashTable *out) { GHashTableIter iter; gpointer key, value; @@ -2110,16 +1972,14 @@ _ostree_repo_remote_list (OstreeRepo *self, * array of remote names **/ char ** -ostree_repo_remote_list (OstreeRepo *self, - guint *out_n_remotes) +ostree_repo_remote_list (OstreeRepo *self, guint *out_n_remotes) { char **remotes = NULL; guint n_remotes; - g_autoptr(GHashTable) remotes_ht = NULL; + g_autoptr (GHashTable) remotes_ht = NULL; - remotes_ht = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) NULL); + remotes_ht = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, + (GDestroyNotify)NULL); _ostree_repo_remote_list (self, remotes_ht); @@ -2133,7 +1993,7 @@ ostree_repo_remote_list (OstreeRepo *self, remotes = g_new (char *, n_remotes + 1); list = g_hash_table_get_keys (remotes_ht); - list = g_list_sort (list, (GCompareFunc) strcmp); + list = g_list_sort (list, (GCompareFunc)strcmp); for (link = list; link != NULL; link = link->next) remotes[ii++] = g_strdup (link->data); @@ -2153,7 +2013,7 @@ ostree_repo_remote_list (OstreeRepo *self, * ostree_repo_remote_get_url: * @self: Repo * @name: Name of remote - * @out_url: (out) (allow-none): Remote's URL + * @out_url: (out) (optional): Remote's URL * @error: Error * * Return the URL of the remote named @name through @out_url. It is an @@ -2162,10 +2022,7 @@ ostree_repo_remote_list (OstreeRepo *self, * Returns: %TRUE on success, %FALSE on failure */ gboolean -ostree_repo_remote_get_url (OstreeRepo *self, - const char *name, - char **out_url, - GError **error) +ostree_repo_remote_get_url (OstreeRepo *self, const char *name, char **out_url, GError **error) { g_return_val_if_fail (name != NULL, FALSE); @@ -2196,7 +2053,7 @@ ostree_repo_remote_get_url (OstreeRepo *self, * ostree_repo_remote_get_gpg_verify: * @self: Repo * @name: Name of remote - * @out_gpg_verify: (out) (allow-none): Remote's GPG option + * @out_gpg_verify: (out) (optional): Remote's GPG option * @error: Error * * Return whether GPG verification is enabled for the remote named @name @@ -2206,10 +2063,8 @@ ostree_repo_remote_get_url (OstreeRepo *self, * Returns: %TRUE on success, %FALSE on failure */ gboolean -ostree_repo_remote_get_gpg_verify (OstreeRepo *self, - const char *name, - gboolean *out_gpg_verify, - GError **error) +ostree_repo_remote_get_gpg_verify (OstreeRepo *self, const char *name, gboolean *out_gpg_verify, + GError **error) { g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); g_return_val_if_fail (name != NULL, FALSE); @@ -2222,8 +2077,8 @@ ostree_repo_remote_get_gpg_verify (OstreeRepo *self, return TRUE; } - return ostree_repo_get_remote_boolean_option (self, name, "gpg-verify", - TRUE, out_gpg_verify, error); + return ostree_repo_get_remote_boolean_option (self, name, "gpg-verify", TRUE, out_gpg_verify, + error); } /** @@ -2240,13 +2095,11 @@ ostree_repo_remote_get_gpg_verify (OstreeRepo *self, * Returns: %TRUE on success, %FALSE on failure */ gboolean -ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self, - const char *name, - gboolean *out_gpg_verify_summary, - GError **error) +ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self, const char *name, + gboolean *out_gpg_verify_summary, GError **error) { - return ostree_repo_get_remote_boolean_option (self, name, "gpg-verify-summary", - FALSE, out_gpg_verify_summary, error); + return ostree_repo_get_remote_boolean_option (self, name, "gpg-verify-summary", FALSE, + out_gpg_verify_summary, error); } /** @@ -2254,7 +2107,8 @@ ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self, * @self: Self * @name: name of a remote * @source_stream: (nullable): a #GInputStream, or %NULL - * @key_ids: (array zero-terminated=1) (element-type utf8) (nullable): a %NULL-terminated array of GPG key IDs, or %NULL + * @key_ids: (array zero-terminated=1) (element-type utf8) (nullable): a %NULL-terminated array of + * GPG key IDs, or %NULL * @out_imported: (out) (optional): return location for the number of imported * keys, or %NULL * @cancellable: a #GCancellable @@ -2271,25 +2125,21 @@ ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self, * Returns: %TRUE on success, %FALSE on failure */ gboolean -ostree_repo_remote_gpg_import (OstreeRepo *self, - const char *name, - GInputStream *source_stream, - const char * const *key_ids, - guint *out_imported, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_gpg_import (OstreeRepo *self, const char *name, GInputStream *source_stream, + const char *const *key_ids, guint *out_imported, + GCancellable *cancellable, GError **error) { #ifndef OSTREE_DISABLE_GPGME OstreeRemote *remote; - g_auto(gpgme_ctx_t) source_context = NULL; - g_auto(gpgme_ctx_t) target_context = NULL; - g_auto(gpgme_data_t) data_buffer = NULL; + g_auto (gpgme_ctx_t) source_context = NULL; + g_auto (gpgme_ctx_t) target_context = NULL; + g_auto (gpgme_data_t) data_buffer = NULL; gpgme_import_result_t import_result; gpgme_import_status_t import_status; g_autofree char *source_tmp_dir = NULL; g_autofree char *target_tmp_dir = NULL; glnx_autofd int target_temp_fd = -1; - g_autoptr(GPtrArray) keys = NULL; + g_autoptr (GPtrArray) keys = NULL; struct stat stbuf; gpgme_error_t gpg_error; gboolean ret = FALSE; @@ -2316,8 +2166,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, { data_buffer = ot_gpgme_data_input (source_stream); - if (!ot_gpgme_ctx_tmp_home_dir (source_context, &source_tmp_dir, - NULL, cancellable, error)) + if (!ot_gpgme_ctx_tmp_home_dir (source_context, &source_tmp_dir, NULL, cancellable, error)) { g_prefix_error (error, "Unable to configure context: "); goto out; @@ -2338,7 +2187,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, /* The keys array will contain a NULL terminator, but it turns out, * although not documented, gpgme_key_unref() gracefully handles it. */ - keys = g_ptr_array_new_with_free_func ((GDestroyNotify) gpgme_key_unref); + keys = g_ptr_array_new_with_free_func ((GDestroyNotify)gpgme_key_unref); if (key_ids != NULL) { @@ -2396,8 +2245,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, goto out; /* No need for an output stream since we copy in a pubring.gpg. */ - if (!ot_gpgme_ctx_tmp_home_dir (target_context, &target_tmp_dir, - NULL, cancellable, error)) + if (!ot_gpgme_ctx_tmp_home_dir (target_context, &target_tmp_dir, NULL, cancellable, error)) { g_prefix_error (error, "Unable to configure context: "); goto out; @@ -2411,9 +2259,8 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, if (fstatat (self->repo_dir_fd, remote->keyring, &stbuf, AT_SYMLINK_NOFOLLOW) == 0) { - if (!glnx_file_copy_at (self->repo_dir_fd, remote->keyring, - &stbuf, target_temp_fd, "pubring.gpg", - GLNX_FILE_COPY_NOXATTRS, cancellable, error)) + if (!glnx_file_copy_at (self->repo_dir_fd, remote->keyring, &stbuf, target_temp_fd, + "pubring.gpg", GLNX_FILE_COPY_NOXATTRS, cancellable, error)) { g_prefix_error (error, "Unable to copy remote's keyring: "); goto out; @@ -2430,8 +2277,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, * * [1] https://gnupg.org/faq/whats-new-in-2.1.html#keybox */ - fd = openat (target_temp_fd, "pubring.gpg", - O_WRONLY | O_CREAT | O_CLOEXEC | O_NOCTTY, 0644); + fd = openat (target_temp_fd, "pubring.gpg", O_WRONLY | O_CREAT | O_CLOEXEC | O_NOCTTY, 0644); if (fd == -1) { glnx_set_prefix_error_from_errno (error, "%s", "Unable to create pubring.gpg"); @@ -2454,16 +2300,14 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, goto out; } - gpg_error = gpgme_op_export_keys (source_context, - (gpgme_key_t *) keys->pdata, 0, - data_buffer); + gpg_error = gpgme_op_export_keys (source_context, (gpgme_key_t *)keys->pdata, 0, data_buffer); if (gpg_error != GPG_ERR_NO_ERROR) { ot_gpgme_throw (gpg_error, error, "Unable to export keys"); goto out; } - (void) gpgme_data_seek (data_buffer, 0, SEEK_SET); + (void)gpgme_data_seek (data_buffer, 0, SEEK_SET); gpg_error = gpgme_op_import (target_context, data_buffer); if (gpg_error != GPG_ERR_NO_ERROR) @@ -2477,28 +2321,24 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, /* Check the status of each import and fail on the first error. * All imports must be successful to update the remote's keyring. */ - for (import_status = import_result->imports; - import_status != NULL; + for (import_status = import_result->imports; import_status != NULL; import_status = import_status->next) { if (import_status->result != GPG_ERR_NO_ERROR) { - ot_gpgme_throw (gpg_error, error, "Unable to import key \"%s\"", - import_status->fpr); + ot_gpgme_throw (gpg_error, error, "Unable to import key \"%s\"", import_status->fpr); goto out; } } /* Import successful; replace the remote's old keyring with the * updated keyring in the target context's temporary directory. */ - if (!glnx_file_copy_at (target_temp_fd, "pubring.gpg", NULL, - self->repo_dir_fd, remote->keyring, - GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE, - cancellable, error)) + if (!glnx_file_copy_at (target_temp_fd, "pubring.gpg", NULL, self->repo_dir_fd, remote->keyring, + GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE, cancellable, error)) goto out; if (out_imported != NULL) - *out_imported = (guint) import_result->imported; + *out_imported = (guint)import_result->imported; ret = TRUE; @@ -2506,33 +2346,33 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, if (remote != NULL) ostree_remote_unref (remote); - if (source_tmp_dir != NULL) { - ot_gpgme_kill_agent (source_tmp_dir); - (void) glnx_shutil_rm_rf_at (AT_FDCWD, source_tmp_dir, NULL, NULL); - } + if (source_tmp_dir != NULL) + { + ot_gpgme_kill_agent (source_tmp_dir); + (void)glnx_shutil_rm_rf_at (AT_FDCWD, source_tmp_dir, NULL, NULL); + } - if (target_tmp_dir != NULL) { - ot_gpgme_kill_agent (target_tmp_dir); - (void) glnx_shutil_rm_rf_at (AT_FDCWD, target_tmp_dir, NULL, NULL); - } + if (target_tmp_dir != NULL) + { + ot_gpgme_kill_agent (target_tmp_dir); + (void)glnx_shutil_rm_rf_at (AT_FDCWD, target_tmp_dir, NULL, NULL); + } g_prefix_error (error, "GPG: "); return ret; -#else /* OSTREE_DISABLE_GPGME */ +#else /* OSTREE_DISABLE_GPGME */ return glnx_throw (error, "GPG feature is disabled in a build time"); #endif /* OSTREE_DISABLE_GPGME */ } -static gboolean -_ostree_repo_gpg_prepare_verifier (OstreeRepo *self, - const gchar *remote_name, - GFile *keyringdir, - GFile *extra_keyring, - gboolean add_global_keyrings, - OstreeGpgVerifier **out_verifier, - GCancellable *cancellable, - GError **error); +#ifndef OSTREE_DISABLE_GPGME +static gboolean _ostree_repo_gpg_prepare_verifier (OstreeRepo *self, const gchar *remote_name, + GFile *keyringdir, GFile *extra_keyring, + gboolean add_global_keyrings, + OstreeGpgVerifier **out_verifier, + GCancellable *cancellable, GError **error); +#endif /* OSTREE_DISABLE_GPGME */ /** * ostree_repo_remote_get_gpg_keys: @@ -2558,39 +2398,32 @@ _ostree_repo_gpg_prepare_verifier (OstreeRepo *self, * Since: 2021.4 */ gboolean -ostree_repo_remote_get_gpg_keys (OstreeRepo *self, - const char *name, - const char * const *key_ids, - GPtrArray **out_keys, - GCancellable *cancellable, - GError **error) +ostree_repo_remote_get_gpg_keys (OstreeRepo *self, const char *name, const char *const *key_ids, + GPtrArray **out_keys, GCancellable *cancellable, GError **error) { #ifndef OSTREE_DISABLE_GPGME - g_autoptr(OstreeGpgVerifier) verifier = NULL; + g_autoptr (OstreeGpgVerifier) verifier = NULL; gboolean global_keyrings = (name == NULL); - if (!_ostree_repo_gpg_prepare_verifier (self, name, NULL, NULL, global_keyrings, - &verifier, cancellable, error)) + if (!_ostree_repo_gpg_prepare_verifier (self, name, NULL, NULL, global_keyrings, &verifier, + cancellable, error)) return FALSE; - g_autoptr(GPtrArray) gpg_keys = NULL; - if (!_ostree_gpg_verifier_list_keys (verifier, key_ids, &gpg_keys, - cancellable, error)) + g_autoptr (GPtrArray) gpg_keys = NULL; + if (!_ostree_gpg_verifier_list_keys (verifier, key_ids, &gpg_keys, cancellable, error)) return FALSE; - g_autoptr(GPtrArray) keys = - g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_unref); + g_autoptr (GPtrArray) keys = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); for (guint i = 0; i < gpg_keys->len; i++) { gpgme_key_t key = gpg_keys->pdata[i]; - g_auto(GVariantBuilder) subkeys_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantBuilder) subkeys_builder = OT_VARIANT_BUILDER_INITIALIZER; g_variant_builder_init (&subkeys_builder, G_VARIANT_TYPE ("aa{sv}")); - g_auto(GVariantBuilder) uids_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantBuilder) uids_builder = OT_VARIANT_BUILDER_INITIALIZER; g_variant_builder_init (&uids_builder, G_VARIANT_TYPE ("aa{sv}")); - for (gpgme_subkey_t subkey = key->subkeys; subkey != NULL; - subkey = subkey->next) + for (gpgme_subkey_t subkey = key->subkeys; subkey != NULL; subkey = subkey->next) { - g_auto(GVariantDict) subkey_dict = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantDict) subkey_dict = OT_VARIANT_BUILDER_INITIALIZER; g_variant_dict_init (&subkey_dict, NULL); g_variant_dict_insert_value (&subkey_dict, "fingerprint", g_variant_new_string (subkey->fpr)); @@ -2604,8 +2437,7 @@ ostree_repo_remote_get_gpg_keys (OstreeRepo *self, g_variant_new_boolean (subkey->expired)); g_variant_dict_insert_value (&subkey_dict, "invalid", g_variant_new_boolean (subkey->invalid)); - g_variant_builder_add (&subkeys_builder, "@a{sv}", - g_variant_dict_end (&subkey_dict)); + g_variant_builder_add (&subkeys_builder, "@a{sv}", g_variant_dict_end (&subkey_dict)); } for (gpgme_user_id_t uid = key->uids; uid != NULL; uid = uid->next) @@ -2615,41 +2447,31 @@ ostree_repo_remote_get_gpg_keys (OstreeRepo *self, g_autofree char *direct_url = NULL; if (uid->address != NULL) { - if (!ot_gpg_wkd_urls (uid->address, &advanced_url, &direct_url, - error)) + if (!ot_gpg_wkd_urls (uid->address, &advanced_url, &direct_url, error)) return FALSE; } - g_auto(GVariantDict) uid_dict = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantDict) uid_dict = OT_VARIANT_BUILDER_INITIALIZER; g_variant_dict_init (&uid_dict, NULL); - g_variant_dict_insert_value (&uid_dict, "uid", - g_variant_new_string (uid->uid)); - g_variant_dict_insert_value (&uid_dict, "name", - g_variant_new_string (uid->name)); - g_variant_dict_insert_value (&uid_dict, "comment", - g_variant_new_string (uid->comment)); - g_variant_dict_insert_value (&uid_dict, "email", - g_variant_new_string (uid->email)); - g_variant_dict_insert_value (&uid_dict, "revoked", - g_variant_new_boolean (uid->revoked)); - g_variant_dict_insert_value (&uid_dict, "invalid", - g_variant_new_boolean (uid->invalid)); + g_variant_dict_insert_value (&uid_dict, "uid", g_variant_new_string (uid->uid)); + g_variant_dict_insert_value (&uid_dict, "name", g_variant_new_string (uid->name)); + g_variant_dict_insert_value (&uid_dict, "comment", g_variant_new_string (uid->comment)); + g_variant_dict_insert_value (&uid_dict, "email", g_variant_new_string (uid->email)); + g_variant_dict_insert_value (&uid_dict, "revoked", g_variant_new_boolean (uid->revoked)); + g_variant_dict_insert_value (&uid_dict, "invalid", g_variant_new_boolean (uid->invalid)); g_variant_dict_insert_value (&uid_dict, "advanced_url", g_variant_new ("ms", advanced_url)); - g_variant_dict_insert_value (&uid_dict, "direct_url", - g_variant_new ("ms", direct_url)); - g_variant_builder_add (&uids_builder, "@a{sv}", - g_variant_dict_end (&uid_dict)); + g_variant_dict_insert_value (&uid_dict, "direct_url", g_variant_new ("ms", direct_url)); + g_variant_builder_add (&uids_builder, "@a{sv}", g_variant_dict_end (&uid_dict)); } /* Currently empty */ - g_auto(GVariantDict) metadata_dict = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantDict) metadata_dict = OT_VARIANT_BUILDER_INITIALIZER; g_variant_dict_init (&metadata_dict, NULL); - GVariant *key_variant = g_variant_new ("(@aa{sv}@aa{sv}@a{sv})", - g_variant_builder_end (&subkeys_builder), - g_variant_builder_end (&uids_builder), - g_variant_dict_end (&metadata_dict)); + GVariant *key_variant = g_variant_new ( + "(@aa{sv}@aa{sv}@a{sv})", g_variant_builder_end (&subkeys_builder), + g_variant_builder_end (&uids_builder), g_variant_dict_end (&metadata_dict)); g_ptr_array_add (keys, g_variant_ref_sink (key_variant)); } @@ -2657,7 +2479,7 @@ ostree_repo_remote_get_gpg_keys (OstreeRepo *self, *out_keys = g_steal_pointer (&keys); return TRUE; -#else /* OSTREE_DISABLE_GPGME */ +#else /* OSTREE_DISABLE_GPGME */ return glnx_throw (error, "GPG feature is disabled in a build time"); #endif /* OSTREE_DISABLE_GPGME */ } @@ -2690,26 +2512,16 @@ ostree_repo_remote_get_gpg_keys (OstreeRepo *self, * Returns: %TRUE on success, %FALSE on failure */ gboolean -ostree_repo_remote_fetch_summary (OstreeRepo *self, - const char *name, - GBytes **out_summary, - GBytes **out_signatures, - GCancellable *cancellable, - GError **error) -{ - return ostree_repo_remote_fetch_summary_with_options (self, - name, - NULL, - out_summary, - out_signatures, - cancellable, - error); +ostree_repo_remote_fetch_summary (OstreeRepo *self, const char *name, GBytes **out_summary, + GBytes **out_signatures, GCancellable *cancellable, + GError **error) +{ + return ostree_repo_remote_fetch_summary_with_options (self, name, NULL, out_summary, + out_signatures, cancellable, error); } static gboolean -ostree_repo_mode_to_string (OstreeRepoMode mode, - const char **out_mode, - GError **error) +ostree_repo_mode_to_string (OstreeRepoMode mode, const char **out_mode, GError **error) { const char *ret_mode; @@ -2726,7 +2538,7 @@ ostree_repo_mode_to_string (OstreeRepoMode mode, break; case OSTREE_REPO_MODE_ARCHIVE: /* Legacy alias */ - ret_mode ="archive-z2"; + ret_mode = "archive-z2"; break; case OSTREE_REPO_MODE_BARE_SPLIT_XATTRS: ret_mode = "bare-split-xattrs"; @@ -2746,9 +2558,7 @@ ostree_repo_mode_to_string (OstreeRepoMode mode, * @error: a #GError if the string is not a valid mode */ gboolean -ostree_repo_mode_from_string (const char *mode, - OstreeRepoMode *out_mode, - GError **error) +ostree_repo_mode_from_string (const char *mode, OstreeRepoMode *out_mode, GError **error) { OstreeRepoMode ret_mode; @@ -2758,8 +2568,7 @@ ostree_repo_mode_from_string (const char *mode, ret_mode = OSTREE_REPO_MODE_BARE_USER; else if (strcmp (mode, "bare-user-only") == 0) ret_mode = OSTREE_REPO_MODE_BARE_USER_ONLY; - else if (strcmp (mode, "archive-z2") == 0 || - strcmp (mode, "archive") == 0) + else if (strcmp (mode, "archive-z2") == 0 || strcmp (mode, "archive") == 0) ret_mode = OSTREE_REPO_MODE_ARCHIVE; else if (strcmp (mode, "bare-split-xattrs") == 0) ret_mode = OSTREE_REPO_MODE_BARE_SPLIT_XATTRS; @@ -2770,28 +2579,24 @@ ostree_repo_mode_from_string (const char *mode, return TRUE; } -#define DEFAULT_CONFIG_CONTENTS ("[core]\n" \ - "repo_version=1\n") +#define DEFAULT_CONFIG_CONTENTS \ + ("[core]\n" \ + "repo_version=1\n") /* Just write the dirs to disk, return a dfd */ static gboolean -repo_create_at_internal (int dfd, - const char *path, - OstreeRepoMode mode, - GVariant *options, - int *out_dfd, - GCancellable *cancellable, - GError **error) +repo_create_at_internal (int dfd, const char *path, OstreeRepoMode mode, GVariant *options, + int *out_dfd, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Creating repo", error); - struct stat stbuf; + struct stat stbuf; /* We do objects/ last - if it exists we do nothing and exit successfully */ - const char *state_dirs[] = { "tmp", "extensions", "state", - "refs", "refs/heads", "refs/mirrors", - "refs/remotes", "objects" }; + const char *state_dirs[] = { "tmp", "extensions", "state", "refs", + "refs/heads", "refs/mirrors", "refs/remotes", "objects" }; /* Early return if we have an existing repo */ - { g_autofree char *objects_path = g_build_filename (path, "objects", NULL); + { + g_autofree char *objects_path = g_build_filename (path, "objects", NULL); if (!glnx_fstatat_allow_noent (dfd, objects_path, &stbuf, 0, error)) return FALSE; @@ -2802,7 +2607,7 @@ repo_create_at_internal (int dfd, return FALSE; /* Note early return */ - *out_dfd = glnx_steal_fd (&repo_dfd); + *out_dfd = g_steal_fd (&repo_dfd); return TRUE; } } @@ -2822,7 +2627,7 @@ repo_create_at_internal (int dfd, if (errno == ENOENT) { const char *mode_str = NULL; - g_autoptr(GString) config_data = g_string_new (DEFAULT_CONFIG_CONTENTS); + g_autoptr (GString) config_data = g_string_new (DEFAULT_CONFIG_CONTENTS); if (!ostree_repo_mode_to_string (mode, &mode_str, error)) return FALSE; @@ -2832,13 +2637,12 @@ repo_create_at_internal (int dfd, const char *collection_id = NULL; if (options) - g_variant_lookup (options, "collection-id", "&s", &collection_id); + (void)g_variant_lookup (options, "collection-id", "&s", &collection_id); if (collection_id != NULL) g_string_append_printf (config_data, "collection-id=%s\n", collection_id); - if (!glnx_file_replace_contents_at (repo_dfd, "config", - (guint8*)config_data->str, config_data->len, - 0, cancellable, error)) + if (!glnx_file_replace_contents_at (repo_dfd, "config", (guint8 *)config_data->str, + config_data->len, 0, cancellable, error)) return FALSE; } @@ -2857,15 +2661,17 @@ repo_create_at_internal (int dfd, */ if (mode == OSTREE_REPO_MODE_BARE_USER) { - g_auto(GLnxTmpfile) tmpf = { 0, }; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; - if (!glnx_open_tmpfile_linkable_at (repo_dfd, ".", O_RDWR|O_CLOEXEC, &tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (repo_dfd, ".", O_RDWR | O_CLOEXEC, &tmpf, error)) return FALSE; if (!_ostree_write_bareuser_metadata (tmpf.fd, 0, 0, 644, NULL, error)) return FALSE; - } + } - *out_dfd = glnx_steal_fd (&repo_dfd); + *out_dfd = g_steal_fd (&repo_dfd); return TRUE; } @@ -2892,26 +2698,22 @@ repo_create_at_internal (int dfd, * this function on a repository initialized via ostree_repo_open_at(). */ gboolean -ostree_repo_create (OstreeRepo *self, - OstreeRepoMode mode, - GCancellable *cancellable, - GError **error) +ostree_repo_create (OstreeRepo *self, OstreeRepoMode mode, GCancellable *cancellable, + GError **error) { g_return_val_if_fail (self->repodir, FALSE); const char *repopath = gs_file_get_path_cached (self->repodir); - g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); if (self->collection_id) g_variant_builder_add (builder, "{s@v}", "collection-id", g_variant_new_variant (g_variant_new_string (self->collection_id))); glnx_autofd int repo_dir_fd = -1; - g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_builder_end (builder)); - if (!repo_create_at_internal (AT_FDCWD, repopath, mode, - options, - &repo_dir_fd, - cancellable, error)) + g_autoptr (GVariant) options = g_variant_ref_sink (g_variant_builder_end (builder)); + if (!repo_create_at_internal (AT_FDCWD, repopath, mode, options, &repo_dir_fd, cancellable, + error)) return FALSE; - self->repo_dir_fd = glnx_steal_fd (&repo_dir_fd); + self->repo_dir_fd = g_steal_fd (&repo_dir_fd); if (!ostree_repo_open (self, cancellable, error)) return FALSE; return TRUE; @@ -2944,33 +2746,25 @@ ostree_repo_create (OstreeRepo *self, * Since: 2017.10 */ OstreeRepo * -ostree_repo_create_at (int dfd, - const char *path, - OstreeRepoMode mode, - GVariant *options, - GCancellable *cancellable, - GError **error) +ostree_repo_create_at (int dfd, const char *path, OstreeRepoMode mode, GVariant *options, + GCancellable *cancellable, GError **error) { glnx_autofd int repo_dfd = -1; - if (!repo_create_at_internal (dfd, path, mode, options, &repo_dfd, - cancellable, error)) + if (!repo_create_at_internal (dfd, path, mode, options, &repo_dfd, cancellable, error)) return NULL; return repo_open_at_take_fd (&repo_dfd, cancellable, error); } static gboolean -enumerate_directory_allow_noent (GFile *dirpath, - const char *queryargs, - GFileQueryInfoFlags queryflags, - GFileEnumerator **out_direnum, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GError) temp_error = NULL; - g_autoptr(GFileEnumerator) ret_direnum = NULL; - - ret_direnum = g_file_enumerate_children (dirpath, queryargs, queryflags, - cancellable, &temp_error); +enumerate_directory_allow_noent (GFile *dirpath, const char *queryargs, + GFileQueryInfoFlags queryflags, GFileEnumerator **out_direnum, + GCancellable *cancellable, GError **error) +{ + g_autoptr (GError) temp_error = NULL; + g_autoptr (GFileEnumerator) ret_direnum = NULL; + + ret_direnum + = g_file_enumerate_children (dirpath, queryargs, queryflags, cancellable, &temp_error); if (!ret_direnum) { if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) @@ -2988,13 +2782,10 @@ enumerate_directory_allow_noent (GFile *dirpath, } static gboolean -add_remotes_from_keyfile (OstreeRepo *self, - GKeyFile *keyfile, - GFile *file, - GError **error) +add_remotes_from_keyfile (OstreeRepo *self, GKeyFile *keyfile, GFile *file, GError **error) { GQueue queue = G_QUEUE_INIT; - g_auto(GStrv) groups = NULL; + g_auto (GStrv) groups = NULL; gsize length, ii; gboolean ret = FALSE; @@ -3017,8 +2808,7 @@ add_remotes_from_keyfile (OstreeRepo *self, if (g_hash_table_contains (self->remotes, remote->name)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Multiple specifications found for remote \"%s\"", - remote->name); + "Multiple specifications found for remote \"%s\"", remote->name); goto out; } @@ -3035,7 +2825,7 @@ add_remotes_from_keyfile (OstreeRepo *self, ret = TRUE; - out: +out: while (!g_queue_is_empty (&queue)) ostree_remote_unref (g_queue_pop_head (&queue)); @@ -3045,31 +2835,27 @@ add_remotes_from_keyfile (OstreeRepo *self, } static gboolean -append_one_remote_config (OstreeRepo *self, - GFile *path, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GKeyFile) remotedata = g_key_file_new (); - if (!g_key_file_load_from_file (remotedata, gs_file_get_path_cached (path), - 0, error)) - return FALSE; +append_one_remote_config (OstreeRepo *self, GFile *path, GCancellable *cancellable, GError **error) +{ + g_autoptr (GKeyFile) remotedata = g_key_file_new (); + const char *pathname = gs_file_get_path_cached (path); + if (!g_key_file_load_from_file (remotedata, pathname, 0, error)) + return glnx_prefix_error (error, "Failed to parse %s", pathname); return add_remotes_from_keyfile (self, remotedata, path, error); } static GFile * -get_remotes_d_dir (OstreeRepo *self, - GFile *sysroot) +get_remotes_d_dir (OstreeRepo *self, GFile *sysroot) { - g_autoptr(GFile) sysroot_owned = NULL; + g_autoptr (GFile) sysroot_owned = NULL; /* Very complicated sysroot logic; this bit breaks the otherwise mostly clean * layering between OstreeRepo and OstreeSysroot. First, If a sysroot was * provided, use it. Otherwise, check to see whether we reference * /ostree/repo, or if not that, see if we have a ref to a sysroot (and it's * physical). */ - g_autoptr(OstreeSysroot) sysroot_ref = NULL; + g_autoptr (OstreeSysroot) sysroot_ref = NULL; if (sysroot == NULL) { /* No explicit sysroot? Let's see if we have a kind */ @@ -3084,13 +2870,16 @@ get_remotes_d_dir (OstreeRepo *self, sysroot = sysroot_owned = g_file_new_for_path ("/"); break; case OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT: - sysroot_ref = (OstreeSysroot*)g_weak_ref_get (&self->sysroot); + sysroot_ref = (OstreeSysroot *)g_weak_ref_get (&self->sysroot); /* Only write to /etc/ostree/remotes.d if we are pointed at a deployment */ if (sysroot_ref != NULL && !sysroot_ref->is_physical) sysroot = ostree_sysroot_get_path (sysroot_ref); break; } } + + (void)sysroot_owned; // Conditionally owned + /* For backwards compat, also fall back to the sysroot-path variable, which we * don't set anymore internally, and I hope no one else uses. */ @@ -3126,19 +2915,25 @@ min_free_space_calculate_reserved_bytes (OstreeRepo *self, guint64 *bytes, GErro if (self->min_free_space_mb > 0) { if (self->min_free_space_mb > (G_MAXUINT64 >> 20)) - return glnx_throw (error, "min-free-space value is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes", - (G_MAXUINT64 >> 20)); + return glnx_throw ( + error, + "min-free-space value is greater than the maximum allowed value of %" G_GUINT64_FORMAT + " bytes", + (G_MAXUINT64 >> 20)); reserved_bytes = self->min_free_space_mb << 20; } else if (self->min_free_space_percent > 0) { if (stvfsbuf.f_frsize > (G_MAXUINT64 / stvfsbuf.f_blocks)) - return glnx_throw (error, "Filesystem's size is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes", - (G_MAXUINT64 / stvfsbuf.f_blocks)); + return glnx_throw ( + error, + "Filesystem's size is greater than the maximum allowed value of %" G_GUINT64_FORMAT + " bytes", + (G_MAXUINT64 / stvfsbuf.f_blocks)); guint64 total_bytes = (stvfsbuf.f_frsize * stvfsbuf.f_blocks); - reserved_bytes = ((double)total_bytes) * (self->min_free_space_percent/100.0); + reserved_bytes = ((double)total_bytes) * (self->min_free_space_percent / 100.0); } *bytes = reserved_bytes; @@ -3146,9 +2941,8 @@ min_free_space_calculate_reserved_bytes (OstreeRepo *self, guint64 *bytes, GErro } static gboolean -min_free_space_size_validate_and_convert (OstreeRepo *self, - const char *min_free_space_size_str, - GError **error) +min_free_space_size_validate_and_convert (OstreeRepo *self, const char *min_free_space_size_str, + GError **error) { static GRegex *regex; static gsize regex_initialized; @@ -3159,7 +2953,7 @@ min_free_space_size_validate_and_convert (OstreeRepo *self, g_once_init_leave (®ex_initialized, 1); } - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; if (!g_regex_match (regex, min_free_space_size_str, 0, &match)) return glnx_throw (error, "It should be of the format '123MB', '123GB' or '123TB'"); @@ -3169,17 +2963,17 @@ min_free_space_size_validate_and_convert (OstreeRepo *self, switch (*unit) { - case 'M': - shifts = 0; - break; - case 'G': - shifts = 10; - break; - case 'T': - shifts = 20; - break; - default: - g_assert_not_reached (); + case 'M': + shifts = 0; + break; + case 'G': + shifts = 10; + break; + case 'T': + shifts = 20; + break; + default: + g_assert_not_reached (); } guint64 min_free_space = g_ascii_strtoull (size_str, NULL, 10); @@ -3192,9 +2986,7 @@ min_free_space_size_validate_and_convert (OstreeRepo *self, } static gboolean -reload_core_config (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +reload_core_config (OstreeRepo *self, GCancellable *cancellable, GError **error) { g_autofree char *version = NULL; g_autofree char *mode = NULL; @@ -3206,8 +2998,7 @@ reload_core_config (OstreeRepo *self, g_clear_pointer (&self->config, g_key_file_unref); self->config = g_key_file_new (); - contents = glnx_file_get_contents_utf8_at (self->repo_dir_fd, "config", &len, - NULL, error); + contents = glnx_file_get_contents_utf8_at (self->repo_dir_fd, "config", &len, NULL, error); if (!contents) return FALSE; if (!g_key_file_load_from_data (self->config, contents, len, 0, error)) @@ -3223,18 +3014,18 @@ reload_core_config (OstreeRepo *self, if (strcmp (version, "1") != 0) return glnx_throw (error, "Invalid repository version '%s'", version); - if (!ot_keyfile_get_boolean_with_default (self->config, "core", "archive", - FALSE, &is_archive, error)) + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "archive", FALSE, &is_archive, + error)) return FALSE; if (is_archive) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of OSTree no longer supports \"archive\" repositories; use archive-z2 instead"); + "This version of OSTree no longer supports \"archive\" repositories; use " + "archive-z2 instead"); return FALSE; } - if (!ot_keyfile_get_value_with_default (self->config, "core", "mode", - "bare", &mode, error)) + if (!ot_keyfile_get_value_with_default (self->config, "core", "mode", "bare", &mode, error)) return FALSE; if (!ostree_repo_mode_from_string (mode, &self->mode, error)) return FALSE; @@ -3251,24 +3042,25 @@ reload_core_config (OstreeRepo *self, { gboolean do_fsync; - if (!ot_keyfile_get_boolean_with_default (self->config, "core", "fsync", - TRUE, &do_fsync, error)) + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "fsync", TRUE, &do_fsync, + error)) return FALSE; if (!do_fsync) ostree_repo_set_disable_fsync (self, TRUE); } - if (!ot_keyfile_get_boolean_with_default (self->config, "core", "per-object-fsync", - FALSE, &self->per_object_fsync, error)) + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "per-object-fsync", FALSE, + &self->per_object_fsync, error)) return FALSE; /* See https://github.com/ostreedev/ostree/issues/758 */ - if (!ot_keyfile_get_boolean_with_default (self->config, "core", "disable-xattrs", - FALSE, &self->disable_xattrs, error)) + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "disable-xattrs", FALSE, + &self->disable_xattrs, error)) return FALSE; - { g_autofree char *tmp_expiry_seconds = NULL; + { + g_autofree char *tmp_expiry_seconds = NULL; /* 86400 secs = one day */ if (!ot_keyfile_get_value_with_default (self->config, "core", "tmp-expiry-secs", "86400", @@ -3278,10 +3070,11 @@ reload_core_config (OstreeRepo *self, self->tmp_expiry_seconds = g_ascii_strtoull (tmp_expiry_seconds, NULL, 10); } - { gboolean locking; + { + gboolean locking; /* Enabled by default in 2018.05 */ - if (!ot_keyfile_get_boolean_with_default (self->config, "core", "locking", - TRUE, &locking, error)) + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "locking", TRUE, &locking, + error)) return FALSE; if (!locking) { @@ -3291,7 +3084,7 @@ reload_core_config (OstreeRepo *self, { g_autofree char *lock_timeout_seconds = NULL; - if (!ot_keyfile_get_value_with_default (self->config, "core", "lock-timeout-secs", "30", + if (!ot_keyfile_get_value_with_default (self->config, "core", "lock-timeout-secs", "300", &lock_timeout_seconds, error)) return FALSE; @@ -3299,7 +3092,8 @@ reload_core_config (OstreeRepo *self, } } - { g_autofree char *compression_level_str = NULL; + { + g_autofree char *compression_level_str = NULL; /* gzip defaults to 6 */ (void)ot_keyfile_get_value_with_default (self->config, "archive", "zlib-level", NULL, @@ -3307,26 +3101,29 @@ reload_core_config (OstreeRepo *self, if (compression_level_str) /* Ensure level is in [1,9] */ - self->zlib_compression_level = MAX (1, MIN (9, g_ascii_strtoull (compression_level_str, NULL, 10))); + self->zlib_compression_level + = MAX (1, MIN (9, g_ascii_strtoull (compression_level_str, NULL, 10))); else self->zlib_compression_level = OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL; } { - /* Try to parse both min-free-space-* config options first. If both are absent, fallback on 3% free space. - * If both are present and are non-zero, use min-free-space-size unconditionally and display a warning. + /* Try to parse both min-free-space-* config options first. If both are absent, fallback on 3% + * free space. If both are present and are non-zero, use min-free-space-size unconditionally + * and display a warning. */ if (g_key_file_has_key (self->config, "core", "min-free-space-size", NULL)) { g_autofree char *min_free_space_size_str = NULL; - if (!ot_keyfile_get_value_with_default (self->config, "core", "min-free-space-size", - NULL, &min_free_space_size_str, error)) + if (!ot_keyfile_get_value_with_default (self->config, "core", "min-free-space-size", NULL, + &min_free_space_size_str, error)) return FALSE; /* Validate the string and convert the size to MBs */ if (!min_free_space_size_validate_and_convert (self, min_free_space_size_str, error)) - return glnx_prefix_error (error, "Invalid min-free-space-size '%s'", min_free_space_size_str); + return glnx_prefix_error (error, "Invalid min-free-space-size '%s'", + min_free_space_size_str); } if (g_key_file_has_key (self->config, "core", "min-free-space-percent", NULL)) @@ -3339,11 +3136,13 @@ reload_core_config (OstreeRepo *self, self->min_free_space_percent = g_ascii_strtoull (min_free_space_percent_str, NULL, 10); if (self->min_free_space_percent > 99) - return glnx_throw (error, "Invalid min-free-space-percent '%s'", min_free_space_percent_str); + return glnx_throw (error, "Invalid min-free-space-percent '%s'", + min_free_space_percent_str); } else if (!g_key_file_has_key (self->config, "core", "min-free-space-size", NULL)) { - /* Default fallback of 3% free space. If changing this, be sure to change the man page too */ + /* Default fallback of 3% free space. If changing this, be sure to change the man page too + */ self->min_free_space_percent = 3; self->min_free_space_mb = 0; } @@ -3351,27 +3150,31 @@ reload_core_config (OstreeRepo *self, if (self->min_free_space_percent != 0 && self->min_free_space_mb != 0) { self->min_free_space_percent = 0; - g_debug ("Both min-free-space-percent and -size are mentioned in config. Enforcing min-free-space-size check only."); + g_debug ("Both min-free-space-percent and -size are mentioned in config. Enforcing " + "min-free-space-size check only."); } } if (!_ostree_repo_parse_fsverity_config (self, error)) return FALSE; - + + if (!_ostree_repo_parse_composefs_config (self, error)) + return FALSE; + { g_clear_pointer (&self->collection_id, g_free); - if (!ot_keyfile_get_value_with_default (self->config, "core", "collection-id", - NULL, &self->collection_id, NULL)) + if (!ot_keyfile_get_value_with_default (self->config, "core", "collection-id", NULL, + &self->collection_id, NULL)) return FALSE; } - if (!ot_keyfile_get_value_with_default (self->config, "core", "parent", - NULL, &parent_repo_path, error)) + if (!ot_keyfile_get_value_with_default (self->config, "core", "parent", NULL, &parent_repo_path, + error)) return FALSE; if (parent_repo_path && parent_repo_path[0]) { - g_autoptr(GFile) parent_repo_f = g_file_new_for_path (parent_repo_path); + g_autoptr (GFile) parent_repo_f = g_file_new_for_path (parent_repo_path); g_clear_object (&self->parent_repo); self->parent_repo = ostree_repo_new (parent_repo_f); @@ -3388,14 +3191,16 @@ reload_core_config (OstreeRepo *self, * system repos. This is to preserve legacy behavior for non-system * repos that specify a remotes config dir (flatpak). */ - { gboolean is_system = ostree_repo_is_system (self); + { + gboolean is_system = ostree_repo_is_system (self); if (!ot_keyfile_get_boolean_with_default (self->config, "core", "add-remotes-config-dir", is_system, &self->add_remotes_config_dir, error)) return FALSE; } - { g_autofree char *payload_threshold = NULL; + { + g_autofree char *payload_threshold = NULL; if (!ot_keyfile_get_value_with_default (self->config, "core", "payload-link-threshold", "-1", &payload_threshold, error)) @@ -3404,8 +3209,9 @@ reload_core_config (OstreeRepo *self, self->payload_link_threshold = g_ascii_strtoull (payload_threshold, NULL, 10); } - { g_auto(GStrv) configured_finders = NULL; - g_autoptr(GError) local_error = NULL; + { + g_auto (GStrv) configured_finders = NULL; + g_autoptr (GError) local_error = NULL; configured_finders = g_key_file_get_string_list (self->config, "core", "default-repo-finders", NULL, &local_error); @@ -3424,9 +3230,8 @@ reload_core_config (OstreeRepo *self, { const char *repo_finder = *iter; - if (strcmp (repo_finder, "config") != 0 && - strcmp (repo_finder, "lan") != 0 && - strcmp (repo_finder, "mount") != 0) + if (strcmp (repo_finder, "config") != 0 && strcmp (repo_finder, "lan") != 0 + && strcmp (repo_finder, "mount") != 0) return glnx_throw (error, "Invalid configured repo-finder '%s'", repo_finder); } @@ -3442,10 +3247,9 @@ reload_core_config (OstreeRepo *self, } static gboolean -reload_remote_config (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +reload_remote_config (OstreeRepo *self, GCancellable *cancellable, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Reloading remotes", error); g_mutex_lock (&self->remotes_lock); g_hash_table_remove_all (self->remotes); @@ -3454,13 +3258,12 @@ reload_remote_config (OstreeRepo *self, if (!add_remotes_from_keyfile (self, self->config, NULL, error)) return FALSE; - g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL); + g_autoptr (GFile) remotes_d = get_remotes_d_dir (self, NULL); if (remotes_d == NULL) return TRUE; - g_autoptr(GFileEnumerator) direnum = NULL; - if (!enumerate_directory_allow_noent (remotes_d, OSTREE_GIO_FAST_QUERYINFO, 0, - &direnum, + g_autoptr (GFileEnumerator) direnum = NULL; + if (!enumerate_directory_allow_noent (remotes_d, OSTREE_GIO_FAST_QUERYINFO, 0, &direnum, cancellable, error)) return FALSE; if (direnum) @@ -3472,8 +3275,7 @@ reload_remote_config (OstreeRepo *self, const char *name; guint32 type; - if (!g_file_enumerator_iterate (direnum, &file_info, &path, - NULL, error)) + if (!g_file_enumerator_iterate (direnum, &file_info, &path, NULL, error)) return FALSE; if (file_info == NULL) break; @@ -3481,8 +3283,7 @@ reload_remote_config (OstreeRepo *self, name = g_file_info_get_attribute_byte_string (file_info, "standard::name"); type = g_file_info_get_attribute_uint32 (file_info, "standard::type"); - if (type == G_FILE_TYPE_REGULAR && - g_str_has_suffix (name, ".conf")) + if (type == G_FILE_TYPE_REGULAR && g_str_has_suffix (name, ".conf")) { if (!append_one_remote_config (self, path, cancellable, error)) return FALSE; @@ -3494,14 +3295,12 @@ reload_remote_config (OstreeRepo *self, } static gboolean -reload_sysroot_config (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +reload_sysroot_config (OstreeRepo *self, GCancellable *cancellable, GError **error) { g_autofree char *bootloader = NULL; - if (!ot_keyfile_get_value_with_default_group_optional (self->config, "sysroot", - "bootloader", "auto", + if (!ot_keyfile_get_value_with_default_group_optional (self->config, "sysroot", "bootloader", + CFG_SYSROOT_BOOTLOADER_DEFAULT_STR, &bootloader, error)) return FALSE; @@ -3510,16 +3309,48 @@ reload_sysroot_config (OstreeRepo *self, * https://github.com/ostreedev/ostree/issues/1719 * https://github.com/ostreedev/ostree/issues/1801 */ + gboolean valid_bootloader = FALSE; for (int i = 0; CFG_SYSROOT_BOOTLOADER_OPTS_STR[i]; i++) { if (g_str_equal (bootloader, CFG_SYSROOT_BOOTLOADER_OPTS_STR[i])) { - self->bootloader = (OstreeCfgSysrootBootloaderOpt) i; - return TRUE; + self->bootloader = (OstreeCfgSysrootBootloaderOpt)i; + valid_bootloader = TRUE; } } + if (!valid_bootloader) + { + return glnx_throw (error, "Invalid bootloader configuration: '%s'", bootloader); + } + /* Parse bls-append-except-default string list. */ + g_auto (GStrv) read_values = NULL; + if (!ot_keyfile_get_string_list_with_default ( + self->config, "sysroot", "bls-append-except-default", ';', NULL, &read_values, error)) + return glnx_throw (error, "Unable to parse bls-append-except-default"); + + /* get all key value pairs in bls-append-except-default */ + g_hash_table_remove_all (self->bls_append_values); + for (char **iter = read_values; iter && *iter; iter++) + { + const char *key_value = *iter; + const char *sep = strchr (key_value, '='); + if (sep == NULL) + { + glnx_throw ( + error, + "bls-append-except-default key must be of the form \"key1=value1;key2=value2...\""); + return FALSE; + } + char *key = g_strndup (key_value, sep - key_value); + char *value = g_strdup (sep + 1); + g_hash_table_replace (self->bls_append_values, key, value); + } + + if (!ot_keyfile_get_boolean_with_default (self->config, "sysroot", "bootprefix", FALSE, + &self->enable_bootprefix, error)) + return FALSE; - return glnx_throw (error, "Invalid bootloader configuration: '%s'", bootloader); + return TRUE; } /** @@ -3534,9 +3365,7 @@ reload_sysroot_config (OstreeRepo *self, * Since: 2017.2 */ gboolean -ostree_repo_reload_config (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +ostree_repo_reload_config (OstreeRepo *self, GCancellable *cancellable, GError **error) { if (!reload_core_config (self, cancellable, error)) return FALSE; @@ -3548,9 +3377,7 @@ ostree_repo_reload_config (OstreeRepo *self, } gboolean -ostree_repo_open (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +ostree_repo_open (OstreeRepo *self, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("opening repo", error); @@ -3565,17 +3392,15 @@ ostree_repo_open (OstreeRepo *self, * where if the ${BOOT_ID} doesn't match, we know file contents * possibly haven't been sync'd to disk and need to be discarded. */ - { const char *env_bootid = getenv ("OSTREE_BOOTID"); + { + const char *env_bootid = getenv ("OSTREE_BOOTID"); g_autofree char *boot_id = NULL; if (env_bootid != NULL) boot_id = g_strdup (env_bootid); else { - if (!g_file_get_contents ("/proc/sys/kernel/random/boot_id", - &boot_id, - NULL, - error)) + if (!g_file_get_contents ("/proc/sys/kernel/random/boot_id", &boot_id, NULL, error)) return FALSE; g_strdelimit (boot_id, "\n", '\0'); } @@ -3596,8 +3421,7 @@ ostree_repo_open (OstreeRepo *self, self->device = stbuf.st_dev; self->inode = stbuf.st_ino; - if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE, - &self->objects_dir_fd, error)) + if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE, &self->objects_dir_fd, error)) return FALSE; self->writable = faccessat (self->objects_dir_fd, ".", W_OK, 0) == 0; @@ -3608,6 +3432,17 @@ ostree_repo_open (OstreeRepo *self, /* Note - we don't return this error yet! */ } + { + struct statfs fsstbuf; + if (fstatfs (self->repo_dir_fd, &fsstbuf) < 0) + return glnx_throw_errno_prefix (error, "fstatfs"); +#ifndef FUSE_SUPER_MAGIC +#define FUSE_SUPER_MAGIC 0x65735546 +#endif + self->is_on_fuse = (fsstbuf.f_type == FUSE_SUPER_MAGIC); + g_debug ("using fuse: %d", self->is_on_fuse); + } + if (!glnx_fstat (self->objects_dir_fd, &stbuf, error)) return FALSE; self->owner_uid = stbuf.st_uid; @@ -3631,7 +3466,8 @@ ostree_repo_open (OstreeRepo *self, if (self->writable && getenv ("OSTREE_SKIP_CACHE") == NULL) { - if (!glnx_shutil_mkdir_p_at (self->tmp_dir_fd, _OSTREE_CACHE_DIR, DEFAULT_DIRECTORY_MODE, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (self->tmp_dir_fd, _OSTREE_CACHE_DIR, DEFAULT_DIRECTORY_MODE, + cancellable, error)) return FALSE; if (!glnx_opendirat (self->tmp_dir_fd, _OSTREE_CACHE_DIR, TRUE, &self->cache_dir_fd, error)) @@ -3649,8 +3485,7 @@ ostree_repo_open (OstreeRepo *self, if (fstatat (AT_FDCWD, "/ostree/repo", &system_stbuf, 0) == 0) { /* Are we the same as /ostree/repo? */ - if (self->device == system_stbuf.st_dev && - self->inode == system_stbuf.st_ino) + if (self->device == system_stbuf.st_dev && self->inode == system_stbuf.st_ino) self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE; else self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_NO; @@ -3677,8 +3512,7 @@ ostree_repo_open (OstreeRepo *self, * ensuring data consistency. */ void -ostree_repo_set_disable_fsync (OstreeRepo *self, - gboolean disable_fsync) +ostree_repo_set_disable_fsync (OstreeRepo *self, gboolean disable_fsync) { self->disable_fsync = disable_fsync; } @@ -3699,18 +3533,15 @@ ostree_repo_set_disable_fsync (OstreeRepo *self, * Since: 2016.5 */ gboolean -ostree_repo_set_cache_dir (OstreeRepo *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +ostree_repo_set_cache_dir (OstreeRepo *self, int dfd, const char *path, GCancellable *cancellable, + GError **error) { glnx_autofd int fd = -1; if (!glnx_opendirat (dfd, path, TRUE, &fd, error)) return FALSE; glnx_close_fd (&self->cache_dir_fd); - self->cache_dir_fd = glnx_steal_fd (&fd); + self->cache_dir_fd = g_steal_fd (&fd); return TRUE; } @@ -3724,7 +3555,7 @@ ostree_repo_set_cache_dir (OstreeRepo *self, * Returns: Whether or not fsync() is enabled for this repo. */ gboolean -ostree_repo_get_disable_fsync (OstreeRepo *self) +ostree_repo_get_disable_fsync (OstreeRepo *self) { return self->disable_fsync; } @@ -3733,16 +3564,12 @@ ostree_repo_get_disable_fsync (OstreeRepo *self) * policy. */ gboolean -_ostree_repo_file_replace_contents (OstreeRepo *self, - int dfd, - const char *path, - const guint8 *buf, - gsize len, - GCancellable *cancellable, - GError **error) +_ostree_repo_file_replace_contents (OstreeRepo *self, int dfd, const char *path, const guint8 *buf, + gsize len, GCancellable *cancellable, GError **error) { return glnx_file_replace_contents_at (dfd, path, buf, len, - self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW, + self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC + : GLNX_FILE_REPLACE_DATASYNC_NEW, cancellable, error); } @@ -3757,7 +3584,7 @@ _ostree_repo_file_replace_contents (OstreeRepo *self, * Returns: (transfer none): Path to repo */ GFile * -ostree_repo_get_path (OstreeRepo *self) +ostree_repo_get_path (OstreeRepo *self) { /* Did we have an abspath? Return it */ if (self->repodir) @@ -3781,7 +3608,7 @@ ostree_repo_get_path (OstreeRepo *self) * Since: 2016.4 */ int -ostree_repo_get_dfd (OstreeRepo *self) +ostree_repo_get_dfd (OstreeRepo *self) { g_return_val_if_fail (self->repo_dir_fd != -1, -1); return self->repo_dir_fd; @@ -3830,8 +3657,7 @@ ostree_repo_hash (OstreeRepo *self) * Since: 2017.12 */ gboolean -ostree_repo_equal (OstreeRepo *a, - OstreeRepo *b) +ostree_repo_equal (OstreeRepo *a, OstreeRepo *b) { g_return_val_if_fail (OSTREE_IS_REPO (a), FALSE); g_return_val_if_fail (OSTREE_IS_REPO (b), FALSE); @@ -3843,7 +3669,7 @@ ostree_repo_equal (OstreeRepo *a, } OstreeRepoMode -ostree_repo_get_mode (OstreeRepo *self) +ostree_repo_get_mode (OstreeRepo *self) { g_assert (self != NULL); g_assert (self->inited); @@ -3866,7 +3692,7 @@ ostree_repo_get_mode (OstreeRepo *self) * Since: 2018.9 */ gboolean -ostree_repo_get_min_free_space_bytes (OstreeRepo *self, guint64 *out_reserved_bytes, GError **error) +ostree_repo_get_min_free_space_bytes (OstreeRepo *self, guint64 *out_reserved_bytes, GError **error) { g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); g_return_val_if_fail (out_reserved_bytes != NULL, FALSE); @@ -3885,26 +3711,24 @@ ostree_repo_get_min_free_space_bytes (OstreeRepo *self, guint64 *out_reserved_b * Before this function can be used, ostree_repo_init() must have been * called. * - * Returns: (transfer none): Parent repository, or %NULL if none + * Returns: (transfer none) (nullable): Parent repository, or %NULL if none */ OstreeRepo * -ostree_repo_get_parent (OstreeRepo *self) +ostree_repo_get_parent (OstreeRepo *self) { return self->parent_repo; } static gboolean -list_loose_objects_at (OstreeRepo *self, - GHashTable *inout_objects, - int dfd, - const char *prefix, - const char *commit_starting_with, - GCancellable *cancellable, - GError **error) +list_loose_objects_at (OstreeRepo *self, GVariant *dummy_value, GHashTable *inout_objects, int dfd, + const char *prefix, const char *commit_starting_with, + GCancellable *cancellable, GError **error) { - GVariant *key, *value; + GVariant *key; - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; gboolean exists; if (!ot_dfd_iter_init_allow_noent (dfd, prefix, &dfd_iter, &exists, error)) return FALSE; @@ -3922,8 +3746,7 @@ list_loose_objects_at (OstreeRepo *self, break; const char *name = dent->d_name; - if (strcmp (name, ".") == 0 || - strcmp (name, "..") == 0) + if (strcmp (name, ".") == 0 || strcmp (name, "..") == 0) continue; const char *dot = strrchr (name, '.'); @@ -3931,10 +3754,8 @@ list_loose_objects_at (OstreeRepo *self, continue; OstreeObjectType objtype; - if ((self->mode == OSTREE_REPO_MODE_ARCHIVE - && strcmp (dot, ".filez") == 0) || - ((_ostree_repo_mode_is_bare (self->mode)) - && strcmp (dot, ".file") == 0)) + if ((self->mode == OSTREE_REPO_MODE_ARCHIVE && strcmp (dot, ".filez") == 0) + || ((_ostree_repo_mode_is_bare (self->mode)) && strcmp (dot, ".file") == 0)) objtype = OSTREE_OBJECT_TYPE_FILE; else if (strcmp (dot, ".dirtree") == 0) objtype = OSTREE_OBJECT_TYPE_DIR_TREE; @@ -3950,11 +3771,11 @@ list_loose_objects_at (OstreeRepo *self, if ((dot - name) != 62) continue; - char buf[OSTREE_SHA256_STRING_LEN+1]; + char buf[OSTREE_SHA256_STRING_LEN + 1]; memcpy (buf, prefix, 2); memcpy (buf + 2, name, 62); - buf[sizeof(buf)-1] = '\0'; + buf[sizeof (buf) - 1] = '\0'; /* if we passed in a "starting with" argument, then we only want to return .commit objects with a checksum @@ -3963,7 +3784,7 @@ list_loose_objects_at (OstreeRepo *self, { /* object is not a commit, do not add to array */ if (objtype != OSTREE_OBJECT_TYPE_COMMIT) - continue; + continue; /* commit checksum does not match "starting with", do not add to array */ if (!g_str_has_prefix (buf, commit_starting_with)) @@ -3971,22 +3792,20 @@ list_loose_objects_at (OstreeRepo *self, } key = ostree_object_name_serialize (buf, objtype); - value = g_variant_new ("(b@as)", - TRUE, g_variant_new_strv (NULL, 0)); + /* transfer ownership */ - g_hash_table_replace (inout_objects, g_variant_ref_sink (key), - g_variant_ref_sink (value)); + if (dummy_value) + g_hash_table_replace (inout_objects, g_variant_ref_sink (key), g_variant_ref (dummy_value)); + else + g_hash_table_add (inout_objects, g_variant_ref_sink (key)); } return TRUE; } static gboolean -list_loose_objects (OstreeRepo *self, - GHashTable *inout_objects, - const char *commit_starting_with, - GCancellable *cancellable, - GError **error) +list_loose_objects (OstreeRepo *self, GVariant *dummy_value, GHashTable *inout_objects, + const char *commit_starting_with, GCancellable *cancellable, GError **error) { static const gchar hexchars[] = "0123456789abcdef"; @@ -3996,9 +3815,8 @@ list_loose_objects (OstreeRepo *self, buf[0] = hexchars[c >> 4]; buf[1] = hexchars[c & 0xF]; buf[2] = '\0'; - if (!list_loose_objects_at (self, inout_objects, self->objects_dir_fd, buf, - commit_starting_with, - cancellable, error)) + if (!list_loose_objects_at (self, dummy_value, inout_objects, self->objects_dir_fd, buf, + commit_starting_with, cancellable, error)) return FALSE; } @@ -4006,21 +3824,15 @@ list_loose_objects (OstreeRepo *self, } static gboolean -load_metadata_internal (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - gboolean error_if_not_found, - GVariant **out_variant, - GInputStream **out_stream, - guint64 *out_size, - OstreeRepoCommitState *out_state, - GCancellable *cancellable, - GError **error) +load_metadata_internal (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + gboolean error_if_not_found, GVariant **out_variant, + GInputStream **out_stream, guint64 *out_size, + OstreeRepoCommitState *out_state, GCancellable *cancellable, GError **error) { char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; glnx_autofd int fd = -1; - g_autoptr(GInputStream) ret_stream = NULL; - g_autoptr(GVariant) ret_variant = NULL; + g_autoptr (GInputStream) ret_stream = NULL; + g_autoptr (GVariant) ret_variant = NULL; g_return_val_if_fail (OSTREE_OBJECT_TYPE_IS_META (objtype), FALSE); g_return_val_if_fail (objtype == OSTREE_OBJECT_TYPE_COMMIT || out_state == NULL, FALSE); @@ -4032,8 +3844,8 @@ load_metadata_internal (OstreeRepo *self, /* Special caching for dirmeta objects, since they're commonly referenced many * times. */ - const gboolean is_dirmeta_cachable = - (objtype == OSTREE_OBJECT_TYPE_DIR_META && out_variant && !out_stream); + const gboolean is_dirmeta_cachable + = (objtype == OSTREE_OBJECT_TYPE_DIR_META && out_variant && !out_stream); if (is_dirmeta_cachable) { GMutex *lock = &self->cache_lock; @@ -4051,14 +3863,12 @@ load_metadata_internal (OstreeRepo *self, _ostree_loose_path (loose_path_buf, sha256, objtype, self->mode); - if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd, - error)) + if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd, error)) return FALSE; if (fd < 0 && self->commit_stagedir.initialized) { - if (!ot_openat_ignore_enoent (self->commit_stagedir.fd, loose_path_buf, &fd, - error)) + if (!ot_openat_ignore_enoent (self->commit_stagedir.fd, loose_path_buf, &fd, error)) return FALSE; } @@ -4079,7 +3889,8 @@ load_metadata_internal (OstreeRepo *self, GMutex *lock = &self->cache_lock; g_mutex_lock (lock); if (self->dirmeta_cache) - g_hash_table_replace (self->dirmeta_cache, g_strdup (sha256), g_variant_ref (ret_variant)); + g_hash_table_replace (self->dirmeta_cache, g_strdup (sha256), + g_variant_ref (ret_variant)); g_mutex_unlock (lock); } } @@ -4100,17 +3911,18 @@ load_metadata_internal (OstreeRepo *self, *out_state = 0; glnx_autofd int commitpartial_fd = -1; - if (!ot_openat_ignore_enoent (self->repo_dir_fd, commitpartial_path, &commitpartial_fd, error)) + if (!ot_openat_ignore_enoent (self->repo_dir_fd, commitpartial_path, &commitpartial_fd, + error)) return FALSE; if (commitpartial_fd != -1) { *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL; - char reason; - if (read (commitpartial_fd, &reason, 1) == 1) - { - if (reason == 'f') - *out_state |= OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL; - } + char reason; + if (read (commitpartial_fd, &reason, 1) == 1) + { + if (reason == 'f') + *out_state |= OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL; + } } } } @@ -4118,14 +3930,13 @@ load_metadata_internal (OstreeRepo *self, { /* Directly recurse to simplify out parameters */ return load_metadata_internal (self->parent_repo, objtype, sha256, error_if_not_found, - out_variant, out_stream, out_size, out_state, - cancellable, error); + out_variant, out_stream, out_size, out_state, cancellable, + error); } else if (error_if_not_found) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No such metadata object %s.%s", - sha256, ostree_object_type_to_string (objtype)); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No such metadata object %s.%s", sha256, + ostree_object_type_to_string (objtype)); return FALSE; } @@ -4134,15 +3945,13 @@ load_metadata_internal (OstreeRepo *self, return TRUE; } -static GVariant * -filemeta_to_stat (struct stat *stbuf, - GVariant *metadata) +static GVariant * +filemeta_to_stat (struct stat *stbuf, GVariant *metadata) { guint32 uid, gid, mode; GVariant *xattrs; - g_variant_get (metadata, "(uuu@a(ayay))", - &uid, &gid, &mode, &xattrs); + g_variant_get (metadata, "(uuu@a(ayay))", &uid, &gid, &mode, &xattrs); stbuf->st_uid = GUINT32_FROM_BE (uid); stbuf->st_gid = GUINT32_FROM_BE (gid); stbuf->st_mode = GUINT32_FROM_BE (mode); @@ -4151,27 +3960,21 @@ filemeta_to_stat (struct stat *stbuf, } static gboolean -repo_load_file_archive (OstreeRepo *self, - const char *checksum, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) +repo_load_file_archive (OstreeRepo *self, const char *checksum, GInputStream **out_input, + GFileInfo **out_file_info, GVariant **out_xattrs, GCancellable *cancellable, + GError **error) { struct stat stbuf; char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, self->mode); glnx_autofd int fd = -1; - if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd, - error)) + if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd, error)) return FALSE; if (fd < 0 && self->commit_stagedir.initialized) { - if (!ot_openat_ignore_enoent (self->commit_stagedir.fd, loose_path_buf, &fd, - error)) + if (!ot_openat_ignore_enoent (self->commit_stagedir.fd, loose_path_buf, &fd, error)) return FALSE; } @@ -4180,31 +3983,27 @@ repo_load_file_archive (OstreeRepo *self, if (!glnx_fstat (fd, &stbuf, error)) return FALSE; - g_autoptr(GInputStream) tmp_stream = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE); + g_autoptr (GInputStream) tmp_stream = g_unix_input_stream_new (g_steal_fd (&fd), TRUE); /* Note return here */ - return ostree_content_stream_parse (TRUE, tmp_stream, stbuf.st_size, TRUE, - out_input, out_file_info, out_xattrs, - cancellable, error); + return ostree_content_stream_parse (TRUE, tmp_stream, stbuf.st_size, TRUE, out_input, + out_file_info, out_xattrs, cancellable, error); } else if (self->parent_repo) { - return ostree_repo_load_file (self->parent_repo, checksum, - out_input, out_file_info, out_xattrs, - cancellable, error); + return ostree_repo_load_file (self->parent_repo, checksum, out_input, out_file_info, + out_xattrs, cancellable, error); } else { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Couldn't find file object '%s'", checksum); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Couldn't find file object '%s'", + checksum); return FALSE; } } static GVariant * -_ostree_repo_read_xattrs_file_link (OstreeRepo *self, - const char *checksum, - GCancellable *cancellable, - GError **error) +_ostree_repo_read_xattrs_file_link (OstreeRepo *self, const char *checksum, + GCancellable *cancellable, GError **error) { g_assert (self != NULL); g_assert (checksum != NULL); @@ -4212,14 +4011,13 @@ _ostree_repo_read_xattrs_file_link (OstreeRepo *self, char xattr_path[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (xattr_path, checksum, OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK, self->mode); - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; glnx_autofd int fd = -1; if (!glnx_openat_rdonly (self->objects_dir_fd, xattr_path, FALSE, &fd, error)) return FALSE; g_assert (fd >= 0); - if (!ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a(ayay)"), TRUE, - &xattrs, error)) + if (!ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a(ayay)"), TRUE, &xattrs, error)) return glnx_prefix_error_null (error, "Deserializing xattrs content"); g_assert (xattrs != NULL); @@ -4227,20 +4025,15 @@ _ostree_repo_read_xattrs_file_link (OstreeRepo *self, } gboolean -_ostree_repo_load_file_bare (OstreeRepo *self, - const char *checksum, - int *out_fd, - struct stat *out_stbuf, - char **out_symlink, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) +_ostree_repo_load_file_bare (OstreeRepo *self, const char *checksum, int *out_fd, + struct stat *out_stbuf, char **out_symlink, GVariant **out_xattrs, + GCancellable *cancellable, GError **error) { /* The bottom case recursing on the parent repo */ if (self == NULL) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Couldn't find file object '%s'", checksum); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Couldn't find file object '%s'", + checksum); return FALSE; } @@ -4250,14 +4043,15 @@ _ostree_repo_load_file_bare (OstreeRepo *self, struct stat stbuf; glnx_autofd int fd = -1; g_autofree char *ret_symlink = NULL; - g_autoptr(GVariant) ret_xattrs = NULL; + g_autoptr (GVariant) ret_xattrs = NULL; char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, self->mode); /* Do a fstatat() and find the object directory that contains this object */ int objdir_fd = self->objects_dir_fd; int res; - if ((res = TEMP_FAILURE_RETRY (fstatat (objdir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW))) < 0 + if ((res = TEMP_FAILURE_RETRY (fstatat (objdir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW))) + < 0 && errno == ENOENT && self->commit_stagedir.initialized) { objdir_fd = self->commit_stagedir.fd; @@ -4268,14 +4062,12 @@ _ostree_repo_load_file_bare (OstreeRepo *self, else if (res < 0) { g_assert (errno == ENOENT); - return _ostree_repo_load_file_bare (self->parent_repo, checksum, out_fd, - out_stbuf, out_symlink, out_xattrs, - cancellable, error); + return _ostree_repo_load_file_bare (self->parent_repo, checksum, out_fd, out_stbuf, + out_symlink, out_xattrs, cancellable, error); } - const gboolean need_open = (out_fd || - (out_xattrs && self->mode == OSTREE_REPO_MODE_BARE) || - self->mode == OSTREE_REPO_MODE_BARE_USER); + const gboolean need_open = (out_fd || (out_xattrs && self->mode == OSTREE_REPO_MODE_BARE) + || self->mode == OSTREE_REPO_MODE_BARE_USER); /* If it's a regular file and we're requested to return the fd, do it now. As * a special case in bare-user, we always do an open, since the stat() metadata * lives there. @@ -4291,31 +4083,29 @@ _ostree_repo_load_file_bare (OstreeRepo *self, return glnx_throw (error, "Not a regular file or symlink"); /* In the non-bare-user case, gather symlink info if requested */ - if (self->mode != OSTREE_REPO_MODE_BARE_USER - && S_ISLNK (stbuf.st_mode) && out_symlink) + if (self->mode != OSTREE_REPO_MODE_BARE_USER && S_ISLNK (stbuf.st_mode) && out_symlink) { - ret_symlink = glnx_readlinkat_malloc (objdir_fd, loose_path_buf, - cancellable, error); + ret_symlink = glnx_readlinkat_malloc (objdir_fd, loose_path_buf, cancellable, error); if (!ret_symlink) return FALSE; } if (self->mode == OSTREE_REPO_MODE_BARE_USER) { - g_autoptr(GBytes) bytes = glnx_fgetxattr_bytes (fd, "user.ostreemeta", error); + g_autoptr (GBytes) bytes = glnx_fgetxattr_bytes (fd, "user.ostreemeta", error); if (bytes == NULL) return FALSE; - g_autoptr(GVariant) metadata = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_FILEMETA_GVARIANT_FORMAT, - bytes, FALSE)); + g_autoptr (GVariant) metadata = g_variant_ref_sink ( + g_variant_new_from_bytes (OSTREE_FILEMETA_GVARIANT_FORMAT, bytes, FALSE)); ret_xattrs = filemeta_to_stat (&stbuf, metadata); if (S_ISLNK (stbuf.st_mode)) { if (out_symlink) { - char targetbuf[PATH_MAX+1]; + char targetbuf[PATH_MAX + 1]; gsize target_size; - g_autoptr(GInputStream) target_input = g_unix_input_stream_new (fd, FALSE); + g_autoptr (GInputStream) target_input = g_unix_input_stream_new (fd, FALSE); if (!g_input_stream_read_all (target_input, targetbuf, sizeof (targetbuf), &target_size, cancellable, error)) return FALSE; @@ -4345,8 +4135,9 @@ _ostree_repo_load_file_bare (OstreeRepo *self, if (S_ISREG (stbuf.st_mode) && out_xattrs) { if (self->disable_xattrs) - ret_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); - else + ret_xattrs + = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); + else { ret_xattrs = ostree_fs_get_all_xattrs (fd, cancellable, error); if (!ret_xattrs) @@ -4356,9 +4147,9 @@ _ostree_repo_load_file_bare (OstreeRepo *self, else if (S_ISLNK (stbuf.st_mode) && out_xattrs) { if (self->disable_xattrs) - ret_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); - else if (!glnx_dfd_name_get_all_xattrs (objdir_fd, loose_path_buf, - &ret_xattrs, + ret_xattrs + = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); + else if (!glnx_dfd_name_get_all_xattrs (objdir_fd, loose_path_buf, &ret_xattrs, cancellable, error)) return FALSE; } @@ -4367,7 +4158,7 @@ _ostree_repo_load_file_bare (OstreeRepo *self, { if (out_xattrs) { - ret_xattrs = _ostree_repo_read_xattrs_file_link(self, checksum, cancellable, error); + ret_xattrs = _ostree_repo_read_xattrs_file_link (self, checksum, cancellable, error); if (ret_xattrs == NULL) return FALSE; } @@ -4378,7 +4169,7 @@ _ostree_repo_load_file_bare (OstreeRepo *self, } if (out_fd) - *out_fd = glnx_steal_fd (&fd); + *out_fd = g_steal_fd (&fd); if (out_stbuf) *out_stbuf = stbuf; ot_transfer_out_value (out_symlink, &ret_symlink); @@ -4400,13 +4191,9 @@ _ostree_repo_load_file_bare (OstreeRepo *self, * content (for regular files), the metadata, and extended attributes. */ gboolean -ostree_repo_load_file (OstreeRepo *self, - const char *checksum, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) +ostree_repo_load_file (OstreeRepo *self, const char *checksum, GInputStream **out_input, + GFileInfo **out_file_info, GVariant **out_xattrs, GCancellable *cancellable, + GError **error) { if (self->mode == OSTREE_REPO_MODE_ARCHIVE) return repo_load_file_archive (self, checksum, out_input, out_file_info, out_xattrs, @@ -4416,20 +4203,18 @@ ostree_repo_load_file (OstreeRepo *self, glnx_autofd int fd = -1; struct stat stbuf; g_autofree char *symlink_target = NULL; - g_autoptr(GVariant) ret_xattrs = NULL; - if (!_ostree_repo_load_file_bare (self, checksum, - out_input ? &fd : NULL, + g_autoptr (GVariant) ret_xattrs = NULL; + if (!_ostree_repo_load_file_bare (self, checksum, out_input ? &fd : NULL, out_file_info ? &stbuf : NULL, out_file_info ? &symlink_target : NULL, - out_xattrs ? &ret_xattrs : NULL, - cancellable, error)) + out_xattrs ? &ret_xattrs : NULL, cancellable, error)) return FALSE; /* Convert fd → GInputStream and struct stat → GFileInfo */ if (out_input) { if (fd != -1) - *out_input = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE); + *out_input = g_unix_input_stream_new (g_steal_fd (&fd), TRUE); else *out_input = NULL; } @@ -4461,37 +4246,30 @@ ostree_repo_load_file (OstreeRepo *self, * repositories. */ gboolean -ostree_repo_load_object_stream (OstreeRepo *self, - OstreeObjectType objtype, - const char *checksum, - GInputStream **out_input, - guint64 *out_size, - GCancellable *cancellable, - GError **error) +ostree_repo_load_object_stream (OstreeRepo *self, OstreeObjectType objtype, const char *checksum, + GInputStream **out_input, guint64 *out_size, + GCancellable *cancellable, GError **error) { guint64 size; - g_autoptr(GInputStream) ret_input = NULL; + g_autoptr (GInputStream) ret_input = NULL; if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { - if (!load_metadata_internal (self, objtype, checksum, TRUE, NULL, - &ret_input, &size, NULL, + if (!load_metadata_internal (self, objtype, checksum, TRUE, NULL, &ret_input, &size, NULL, cancellable, error)) return FALSE; } else { - g_autoptr(GInputStream) input = NULL; - g_autoptr(GFileInfo) finfo = NULL; - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GInputStream) input = NULL; + g_autoptr (GFileInfo) finfo = NULL; + g_autoptr (GVariant) xattrs = NULL; - if (!ostree_repo_load_file (self, checksum, &input, &finfo, &xattrs, - cancellable, error)) + if (!ostree_repo_load_file (self, checksum, &input, &finfo, &xattrs, cancellable, error)) return FALSE; - if (!ostree_raw_file_to_content_stream (input, finfo, xattrs, - &ret_input, &size, - cancellable, error)) + if (!ostree_raw_file_to_content_stream (input, finfo, xattrs, &ret_input, &size, cancellable, + error)) return FALSE; } @@ -4508,12 +4286,8 @@ ostree_repo_load_object_stream (OstreeRepo *self, * set to TRUE. @loose_path_buf is always set to the loose path. */ gboolean -_ostree_repo_has_loose_object (OstreeRepo *self, - const char *checksum, - OstreeObjectType objtype, - gboolean *out_is_stored, - GCancellable *cancellable, - GError **error) +_ostree_repo_has_loose_object (OstreeRepo *self, const char *checksum, OstreeObjectType objtype, + gboolean *out_is_stored, GCancellable *cancellable, GError **error) { char loose_path_buf[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (loose_path_buf, checksum, objtype, self->mode); @@ -4562,25 +4336,21 @@ _ostree_repo_has_loose_object (OstreeRepo *self, * Returns: %FALSE if an unexpected error occurred, %TRUE otherwise */ gboolean -ostree_repo_has_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *checksum, - gboolean *out_have_object, - GCancellable *cancellable, - GError **error) +ostree_repo_has_object (OstreeRepo *self, OstreeObjectType objtype, const char *checksum, + gboolean *out_have_object, GCancellable *cancellable, GError **error) { gboolean ret_have_object = FALSE; - if (!_ostree_repo_has_loose_object (self, checksum, objtype, &ret_have_object, - cancellable, error)) + if (!_ostree_repo_has_loose_object (self, checksum, objtype, &ret_have_object, cancellable, + error)) return FALSE; /* In the future, here is where we would also look up in metadata pack files */ if (!ret_have_object && self->parent_repo) { - if (!ostree_repo_has_object (self->parent_repo, objtype, checksum, - &ret_have_object, cancellable, error)) + if (!ostree_repo_has_object (self->parent_repo, objtype, checksum, &ret_have_object, + cancellable, error)) return FALSE; } @@ -4602,11 +4372,8 @@ ostree_repo_has_object (OstreeRepo *self, * is thrown if the object does not exist. */ gboolean -ostree_repo_delete_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GCancellable *cancellable, - GError **error) +ostree_repo_delete_object (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GCancellable *cancellable, GError **error) { char loose_path[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (loose_path, sha256, objtype, self->mode); @@ -4622,9 +4389,11 @@ ostree_repo_delete_object (OstreeRepo *self, } if (!glnx_unlinkat (self->objects_dir_fd, loose_path, 0, error)) - return glnx_prefix_error (error, "Deleting object %s.%s", sha256, ostree_object_type_to_string (objtype)); + return glnx_prefix_error (error, "Deleting object %s.%s", sha256, + ostree_object_type_to_string (objtype)); - /* If the repository is configured to use tombstone commits, create one when deleting a commit. */ + /* If the repository is configured to use tombstone commits, create one when deleting a commit. + */ if (objtype == OSTREE_OBJECT_TYPE_COMMIT) { gboolean tombstone_commits = FALSE; @@ -4635,18 +4404,14 @@ ostree_repo_delete_object (OstreeRepo *self, if (tombstone_commits) { - g_auto(GVariantBuilder) builder = OT_VARIANT_BUILDER_INITIALIZER; - g_autoptr(GVariant) variant = NULL; + g_auto (GVariantBuilder) builder = OT_VARIANT_BUILDER_INITIALIZER; + g_autoptr (GVariant) variant = NULL; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&builder, "{sv}", "commit", g_variant_new_bytestring (sha256)); variant = g_variant_ref_sink (g_variant_builder_end (&builder)); - if (!ostree_repo_write_metadata_trusted (self, - OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, - sha256, - variant, - cancellable, - error)) + if (!ostree_repo_write_metadata_trusted (self, OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT, + sha256, variant, cancellable, error)) return FALSE; } } @@ -4656,17 +4421,13 @@ ostree_repo_delete_object (OstreeRepo *self, /* Thin wrapper for _ostree_verify_metadata_object() */ static gboolean -fsck_metadata_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GCancellable *cancellable, - GError **error) +fsck_metadata_object (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GCancellable *cancellable, GError **error) { const char *errmsg = glnx_strjoina ("fsck ", sha256, ".", ostree_object_type_to_string (objtype)); GLNX_AUTO_PREFIX_ERROR (errmsg, error); - g_autoptr(GVariant) metadata = NULL; - if (!load_metadata_internal (self, objtype, sha256, TRUE, - &metadata, NULL, NULL, NULL, + g_autoptr (GVariant) metadata = NULL; + if (!load_metadata_internal (self, objtype, sha256, TRUE, &metadata, NULL, NULL, NULL, cancellable, error)) return FALSE; @@ -4674,19 +4435,16 @@ fsck_metadata_object (OstreeRepo *self, } static gboolean -fsck_content_object (OstreeRepo *self, - const char *sha256, - GCancellable *cancellable, - GError **error) +fsck_content_object (OstreeRepo *self, const char *sha256, GCancellable *cancellable, + GError **error) { const char *errmsg = glnx_strjoina ("fsck content object ", sha256); GLNX_AUTO_PREFIX_ERROR (errmsg, error); - g_autoptr(GInputStream) input = NULL; - g_autoptr(GFileInfo) file_info = NULL; - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GInputStream) input = NULL; + g_autoptr (GFileInfo) file_info = NULL; + g_autoptr (GVariant) xattrs = NULL; - if (!ostree_repo_load_file (self, sha256, &input, &file_info, &xattrs, - cancellable, error)) + if (!ostree_repo_load_file (self, sha256, &input, &file_info, &xattrs, cancellable, error)) return FALSE; /* TODO more consistency checks here */ @@ -4695,12 +4453,11 @@ fsck_content_object (OstreeRepo *self, return FALSE; g_autofree guchar *computed_csum = NULL; - if (!ostree_checksum_file_from_input (file_info, xattrs, input, - OSTREE_OBJECT_TYPE_FILE, &computed_csum, - cancellable, error)) + if (!ostree_checksum_file_from_input (file_info, xattrs, input, OSTREE_OBJECT_TYPE_FILE, + &computed_csum, cancellable, error)) return FALSE; - char actual_checksum[OSTREE_SHA256_STRING_LEN+1]; + char actual_checksum[OSTREE_SHA256_STRING_LEN + 1]; ostree_checksum_inplace_from_bytes (computed_csum, actual_checksum); return _ostree_compare_object_checksum (OSTREE_OBJECT_TYPE_FILE, sha256, actual_checksum, error); } @@ -4720,11 +4477,8 @@ fsck_content_object (OstreeRepo *self, * Since: 2017.15 */ gboolean -ostree_repo_fsck_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GCancellable *cancellable, - GError **error) +ostree_repo_fsck_object (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GCancellable *cancellable, GError **error) { if (OSTREE_OBJECT_TYPE_IS_META (objtype)) return fsck_metadata_object (self, objtype, sha256, cancellable, error); @@ -4749,16 +4503,11 @@ ostree_repo_fsck_object (OstreeRepo *self, * Otherwise, a copy will be performed. */ gboolean -ostree_repo_import_object_from (OstreeRepo *self, - OstreeRepo *source, - OstreeObjectType objtype, - const char *checksum, - GCancellable *cancellable, - GError **error) +ostree_repo_import_object_from (OstreeRepo *self, OstreeRepo *source, OstreeObjectType objtype, + const char *checksum, GCancellable *cancellable, GError **error) { - return - ostree_repo_import_object_from_with_trust (self, source, objtype, - checksum, TRUE, cancellable, error); + return ostree_repo_import_object_from_with_trust (self, source, objtype, checksum, TRUE, + cancellable, error); } /** @@ -4781,18 +4530,14 @@ ostree_repo_import_object_from (OstreeRepo *self, * Since: 2016.5 */ gboolean -ostree_repo_import_object_from_with_trust (OstreeRepo *self, - OstreeRepo *source, - OstreeObjectType objtype, - const char *checksum, - gboolean trusted, - GCancellable *cancellable, - GError **error) +ostree_repo_import_object_from_with_trust (OstreeRepo *self, OstreeRepo *source, + OstreeObjectType objtype, const char *checksum, + gboolean trusted, GCancellable *cancellable, + GError **error) { /* This just wraps a currently internal API, may make it public later */ OstreeRepoImportFlags flags = trusted ? _OSTREE_REPO_IMPORT_FLAGS_TRUSTED : 0; - return _ostree_repo_import_object (self, source, objtype, checksum, - flags, cancellable, error); + return _ostree_repo_import_object (self, source, objtype, checksum, flags, cancellable, error); } /** @@ -4808,24 +4553,24 @@ ostree_repo_import_object_from_with_trust (OstreeRepo *self, * compression has been applied. */ gboolean -ostree_repo_query_object_storage_size (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - guint64 *out_size, - GCancellable *cancellable, - GError **error) +ostree_repo_query_object_storage_size (OstreeRepo *self, OstreeObjectType objtype, + const char *sha256, guint64 *out_size, + GCancellable *cancellable, GError **error) { char loose_path[_OSTREE_LOOSE_PATH_MAX]; _ostree_loose_path (loose_path, sha256, objtype, self->mode); int res; struct stat stbuf; - res = TEMP_FAILURE_RETRY (fstatat (self->objects_dir_fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW)); + res = TEMP_FAILURE_RETRY ( + fstatat (self->objects_dir_fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW)); if (res < 0 && errno == ENOENT && self->commit_stagedir.initialized) - res = TEMP_FAILURE_RETRY (fstatat (self->commit_stagedir.fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW)); + res = TEMP_FAILURE_RETRY ( + fstatat (self->commit_stagedir.fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW)); if (res < 0) - return glnx_throw_errno_prefix (error, "Querying object %s.%s", sha256, ostree_object_type_to_string (objtype)); + return glnx_throw_errno_prefix (error, "Querying object %s.%s", sha256, + ostree_object_type_to_string (objtype)); *out_size = stbuf.st_size; return TRUE; @@ -4845,14 +4590,11 @@ ostree_repo_query_object_storage_size (OstreeRepo *self, * return TRUE. */ gboolean -ostree_repo_load_variant_if_exists (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GVariant **out_variant, - GError **error) +ostree_repo_load_variant_if_exists (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GVariant **out_variant, GError **error) { - return load_metadata_internal (self, objtype, sha256, FALSE, - out_variant, NULL, NULL, NULL, NULL, error); + return load_metadata_internal (self, objtype, sha256, FALSE, out_variant, NULL, NULL, NULL, NULL, + error); } /** @@ -4867,14 +4609,11 @@ ostree_repo_load_variant_if_exists (OstreeRepo *self, * result in @out_variant. */ gboolean -ostree_repo_load_variant (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GVariant **out_variant, - GError **error) +ostree_repo_load_variant (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GVariant **out_variant, GError **error) { - return load_metadata_internal (self, objtype, sha256, TRUE, - out_variant, NULL, NULL, NULL, NULL, error); + return load_metadata_internal (self, objtype, sha256, TRUE, out_variant, NULL, NULL, NULL, NULL, + error); } /** @@ -4891,57 +4630,35 @@ ostree_repo_load_variant (OstreeRepo *self, * means that only a sub-path of the commit is available. */ gboolean -ostree_repo_load_commit (OstreeRepo *self, - const char *checksum, - GVariant **out_variant, - OstreeRepoCommitState *out_state, - GError **error) +ostree_repo_load_commit (OstreeRepo *self, const char *checksum, GVariant **out_variant, + OstreeRepoCommitState *out_state, GError **error) { - return load_metadata_internal (self, OSTREE_OBJECT_TYPE_COMMIT, checksum, TRUE, - out_variant, NULL, NULL, out_state, NULL, error); + return load_metadata_internal (self, OSTREE_OBJECT_TYPE_COMMIT, checksum, TRUE, out_variant, NULL, + NULL, out_state, NULL, error); } -/** - * ostree_repo_list_objects: - * @self: Repo - * @flags: Flags controlling enumeration - * @out_objects: (out) (transfer container) (element-type GVariant GVariant): - * Map of serialized object name to variant data - * @cancellable: Cancellable - * @error: Error - * - * This function synchronously enumerates all objects in the - * repository, returning data in @out_objects. @out_objects - * maps from keys returned by ostree_object_name_serialize() - * to #GVariant values of type %OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE. - * - * Returns: %TRUE on success, %FALSE on error, and @error will be set - */ -gboolean -ostree_repo_list_objects (OstreeRepo *self, - OstreeRepoListObjectsFlags flags, - GHashTable **out_objects, - GCancellable *cancellable, - GError **error) +static GHashTable * +repo_list_objects_impl (OstreeRepo *self, OstreeRepoListObjectsFlags flags, GVariant *dummy_value, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (self->inited, FALSE); + g_assert (error == NULL || *error == NULL); + g_assert (self->inited); - g_autoptr(GHashTable) ret_objects = - g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, - (GDestroyNotify) g_variant_unref, - (GDestroyNotify) g_variant_unref); + g_autoptr (GHashTable) ret_objects = g_hash_table_new_full ( + ostree_hash_object_name, g_variant_equal, (GDestroyNotify)g_variant_unref, + dummy_value ? (GDestroyNotify)g_variant_unref : NULL); if (flags & OSTREE_REPO_LIST_OBJECTS_ALL) flags |= (OSTREE_REPO_LIST_OBJECTS_LOOSE | OSTREE_REPO_LIST_OBJECTS_PACKED); if (flags & OSTREE_REPO_LIST_OBJECTS_LOOSE) { - if (!list_loose_objects (self, ret_objects, NULL, cancellable, error)) + if (!list_loose_objects (self, dummy_value, ret_objects, NULL, cancellable, error)) return FALSE; if ((flags & OSTREE_REPO_LIST_OBJECTS_NO_PARENTS) == 0 && self->parent_repo) { - if (!list_loose_objects (self->parent_repo, ret_objects, NULL, cancellable, error)) + if (!list_loose_objects (self->parent_repo, dummy_value, ret_objects, NULL, cancellable, + error)) return FALSE; } } @@ -4951,14 +4668,62 @@ ostree_repo_list_objects (OstreeRepo *self, /* Nothing for now... */ } - ot_transfer_out_value (out_objects, &ret_objects); + return g_steal_pointer (&ret_objects); +} + +/* A currently-internal version of ostree_repo_list_objects which returns + * a set, and not a map (with a useless value). + */ +GHashTable * +ostree_repo_list_objects_set (OstreeRepo *self, OstreeRepoListObjectsFlags flags, + GCancellable *cancellable, GError **error) +{ + return repo_list_objects_impl (self, flags, NULL, cancellable, error); +} + +/* For unfortunate historical reasons we emit this dummy value. + * It was intended to provide additional information about the object (e.g. "is in a pack file") + * but we ended up not shipping pack files. + */ +static GVariant * +get_dummy_list_objects_variant (void) +{ + return g_variant_ref_sink (g_variant_new ("(b@as)", TRUE, g_variant_new_strv (NULL, 0))); +} + +/** + * ostree_repo_list_objects: + * @self: Repo + * @flags: Flags controlling enumeration + * @out_objects: (out) (transfer container) (element-type GVariant GVariant): + * Map of serialized object name to variant data + * @cancellable: Cancellable + * @error: Error + * + * This function synchronously enumerates all objects in the + * repository, returning data in @out_objects. @out_objects + * maps from keys returned by ostree_object_name_serialize() + * to #GVariant values of type %OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE. + * + * Returns: %TRUE on success, %FALSE on error, and @error will be set + */ +gboolean +ostree_repo_list_objects (OstreeRepo *self, OstreeRepoListObjectsFlags flags, + GHashTable **out_objects, GCancellable *cancellable, GError **error) +{ + g_autoptr (GVariant) dummy_value = get_dummy_list_objects_variant (); + g_autoptr (GHashTable) ret + = repo_list_objects_impl (self, flags, dummy_value, cancellable, error); + if (!ret) + return FALSE; + ot_transfer_out_value (out_objects, &ret); return TRUE; } /** * ostree_repo_list_commit_objects_starting_with: * @self: Repo - * @start: List commits starting with this checksum + * @start: List commits starting with this checksum (empty string for all) * @out_commits: (out) (transfer container) (element-type GVariant GVariant): * Map of serialized commit name to variant data * @cancellable: Cancellable @@ -4967,29 +4732,30 @@ ostree_repo_list_objects (OstreeRepo *self, * This function synchronously enumerates all commit objects starting * with @start, returning data in @out_commits. * + * To list all commit objects, provide the empty string `""` for @start. + * * Returns: %TRUE on success, %FALSE on error, and @error will be set */ gboolean -ostree_repo_list_commit_objects_starting_with (OstreeRepo *self, - const char *start, - GHashTable **out_commits, - GCancellable *cancellable, - GError **error) +ostree_repo_list_commit_objects_starting_with (OstreeRepo *self, const char *start, + GHashTable **out_commits, GCancellable *cancellable, + GError **error) { g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (self->inited, FALSE); - g_autoptr(GHashTable) ret_commits = - g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, - (GDestroyNotify) g_variant_unref, - (GDestroyNotify) g_variant_unref); + g_autoptr (GHashTable) ret_commits + = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, + (GDestroyNotify)g_variant_unref, (GDestroyNotify)g_variant_unref); + g_autoptr (GVariant) dummy_loose_object_variant = get_dummy_list_objects_variant (); - if (!list_loose_objects (self, ret_commits, start, cancellable, error)) + if (!list_loose_objects (self, dummy_loose_object_variant, ret_commits, start, cancellable, + error)) return FALSE; if (self->parent_repo) { - if (!list_loose_objects (self->parent_repo, ret_commits, start, + if (!list_loose_objects (self->parent_repo, dummy_loose_object_variant, ret_commits, start, cancellable, error)) return FALSE; } @@ -5002,34 +4768,31 @@ ostree_repo_list_commit_objects_starting_with (OstreeRepo *self * ostree_repo_read_commit: * @self: Repo * @ref: Ref or ASCII checksum - * @out_root: (out): An #OstreeRepoFile corresponding to the root - * @out_commit: (out): The resolved commit checksum + * @out_root: (out) (optional): An #OstreeRepoFile corresponding to the root + * @out_commit: (out) (optional): The resolved commit checksum * @cancellable: Cancellable * @error: Error * * Load the content for @rev into @out_root. */ gboolean -ostree_repo_read_commit (OstreeRepo *self, - const char *ref, - GFile **out_root, - char **out_commit, - GCancellable *cancellable, - GError **error) +ostree_repo_read_commit (OstreeRepo *self, const char *ref, GFile **out_root, char **out_commit, + GCancellable *cancellable, GError **error) { g_autofree char *resolved_commit = NULL; if (!ostree_repo_resolve_rev (self, ref, FALSE, &resolved_commit, error)) return FALSE; - g_autoptr(GFile) ret_root = (GFile*) _ostree_repo_file_new_for_commit (self, resolved_commit, error); + g_autoptr (GFile) ret_root + = (GFile *)_ostree_repo_file_new_for_commit (self, resolved_commit, error); if (!ret_root) return FALSE; - if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile*)ret_root, error)) + if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *)ret_root, error)) return FALSE; - ot_transfer_out_value(out_root, &ret_root); - ot_transfer_out_value(out_commit, &resolved_commit); + ot_transfer_out_value (out_root, &ret_root); + ot_transfer_out_value (out_commit, &resolved_commit); return TRUE; } @@ -5037,7 +4800,8 @@ ostree_repo_read_commit (OstreeRepo *self, * ostree_repo_pull: * @self: Repo * @remote_name: Name of remote - * @refs_to_fetch: (array zero-terminated=1) (element-type utf8) (allow-none): Optional list of refs; if %NULL, fetch all configured refs + * @refs_to_fetch: (array zero-terminated=1) (element-type utf8) (allow-none): Optional list of + * refs; if %NULL, fetch all configured refs * @flags: Options controlling fetch behavior * @progress: (allow-none): Progress * @cancellable: Cancellable @@ -5061,15 +4825,12 @@ ostree_repo_read_commit (OstreeRepo *self, * one around this call. */ gboolean -ostree_repo_pull (OstreeRepo *self, - const char *remote_name, - char **refs_to_fetch, - OstreeRepoPullFlags flags, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GError **error) +ostree_repo_pull (OstreeRepo *self, const char *remote_name, char **refs_to_fetch, + OstreeRepoPullFlags flags, OstreeAsyncProgress *progress, + GCancellable *cancellable, GError **error) { - return ostree_repo_pull_one_dir (self, remote_name, NULL, refs_to_fetch, flags, progress, cancellable, error); + return ostree_repo_pull_one_dir (self, remote_name, NULL, refs_to_fetch, flags, progress, + cancellable, error); } /** @@ -5077,7 +4838,8 @@ ostree_repo_pull (OstreeRepo *self, * @self: Repo * @remote_name: Name of remote * @dir_to_pull: Subdirectory path - * @refs_to_fetch: (array zero-terminated=1) (element-type utf8) (allow-none): Optional list of refs; if %NULL, fetch all configured refs + * @refs_to_fetch: (array zero-terminated=1) (element-type utf8) (allow-none): Optional list of + * refs; if %NULL, fetch all configured refs * @flags: Options controlling fetch behavior * @progress: (allow-none): Progress * @cancellable: Cancellable @@ -5087,17 +4849,12 @@ ostree_repo_pull (OstreeRepo *self, * subpath. */ gboolean -ostree_repo_pull_one_dir (OstreeRepo *self, - const char *remote_name, - const char *dir_to_pull, - char **refs_to_fetch, - OstreeRepoPullFlags flags, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GError **error) +ostree_repo_pull_one_dir (OstreeRepo *self, const char *remote_name, const char *dir_to_pull, + char **refs_to_fetch, OstreeRepoPullFlags flags, + OstreeAsyncProgress *progress, GCancellable *cancellable, GError **error) { GVariantBuilder builder; - g_autoptr(GVariant) options = NULL; + g_autoptr (GVariant) options = NULL; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); @@ -5107,12 +4864,12 @@ ostree_repo_pull_one_dir (OstreeRepo *self, g_variant_builder_add (&builder, "{s@v}", "flags", g_variant_new_variant (g_variant_new_int32 (flags))); if (refs_to_fetch) - g_variant_builder_add (&builder, "{s@v}", "refs", - g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch, -1))); + g_variant_builder_add ( + &builder, "{s@v}", "refs", + g_variant_new_variant (g_variant_new_strv ((const char *const *)refs_to_fetch, -1))); options = g_variant_ref_sink (g_variant_builder_end (&builder)); - return ostree_repo_pull_with_options (self, remote_name, options, - progress, cancellable, error); + return ostree_repo_pull_with_options (self, remote_name, options, progress, cancellable, error); } /** @@ -5165,7 +4922,7 @@ _formatted_time_remaining_from_seconds (guint64 seconds_remaining) **/ void ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress, - gpointer user_data) + gpointer user_data) { g_autofree char *status = NULL; gboolean caught_error, scanning; @@ -5178,21 +4935,15 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress guint fetched_delta_part_fallbacks; guint total_delta_part_fallbacks; - g_autoptr(GString) buf = g_string_new (""); - - ostree_async_progress_get (progress, - "outstanding-fetches", "u", &outstanding_fetches, - "outstanding-metadata-fetches", "u", &outstanding_metadata_fetches, - "outstanding-writes", "u", &outstanding_writes, - "caught-error", "b", &caught_error, - "scanning", "u", &scanning, - "scanned-metadata", "u", &n_scanned_metadata, - "fetched-delta-parts", "u", &fetched_delta_parts, - "total-delta-parts", "u", &total_delta_parts, - "fetched-delta-fallbacks", "u", &fetched_delta_part_fallbacks, - "total-delta-fallbacks", "u", &total_delta_part_fallbacks, - "status", "s", &status, - NULL); + g_autoptr (GString) buf = g_string_new (""); + + ostree_async_progress_get ( + progress, "outstanding-fetches", "u", &outstanding_fetches, "outstanding-metadata-fetches", + "u", &outstanding_metadata_fetches, "outstanding-writes", "u", &outstanding_writes, + "caught-error", "b", &caught_error, "scanning", "u", &scanning, "scanned-metadata", "u", + &n_scanned_metadata, "fetched-delta-parts", "u", &fetched_delta_parts, "total-delta-parts", + "u", &total_delta_parts, "fetched-delta-fallbacks", "u", &fetched_delta_part_fallbacks, + "total-delta-fallbacks", "u", &total_delta_part_fallbacks, "status", "s", &status, NULL); if (*status != '\0') { @@ -5212,14 +4963,10 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress guint64 bytes_sec; /* Note: This is not atomic wrt the above getter call. */ - ostree_async_progress_get (progress, - "bytes-transferred", "t", &bytes_transferred, - "fetched", "u", &fetched, - "metadata-fetched", "u", &metadata_fetched, - "requested", "u", &requested, - "start-time", "t", &start_time, - "total-delta-part-size", "t", &total_delta_part_size, - NULL); + ostree_async_progress_get (progress, "bytes-transferred", "t", &bytes_transferred, "fetched", + "u", &fetched, "metadata-fetched", "u", &metadata_fetched, + "requested", "u", &requested, "start-time", "t", &start_time, + "total-delta-part-size", "t", &total_delta_part_size, NULL); formatted_bytes_transferred = g_format_size_full (bytes_transferred, 0); @@ -5240,7 +4987,8 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress /* Are we doing deltas? If so, we can be more accurate */ if (total_delta_parts > 0) { - guint64 fetched_delta_part_size = ostree_async_progress_get_uint64 (progress, "fetched-delta-part-size"); + guint64 fetched_delta_part_size + = ostree_async_progress_get_uint64 (progress, "fetched-delta-part-size"); g_autofree char *formatted_fetched = NULL; g_autofree char *formatted_total = NULL; @@ -5256,31 +5004,33 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress guint64 est_time_remaining = 0; if (total_delta_part_size > fetched_delta_part_size) est_time_remaining = (total_delta_part_size - fetched_delta_part_size) / bytes_sec; - g_autofree char *formatted_est_time_remaining = _formatted_time_remaining_from_seconds (est_time_remaining); - /* No space between %s and remaining, since formatted_est_time_remaining has a trailing space */ + g_autofree char *formatted_est_time_remaining + = _formatted_time_remaining_from_seconds (est_time_remaining); + /* No space between %s and remaining, since formatted_est_time_remaining has a + * trailing space */ g_string_append_printf (buf, "Receiving delta parts: %u/%u %s/%s %s/s %sremaining", - fetched_delta_parts, total_delta_parts, - formatted_fetched, formatted_total, - formatted_bytes_sec, + fetched_delta_parts, total_delta_parts, formatted_fetched, + formatted_total, formatted_bytes_sec, formatted_est_time_remaining); } else { g_string_append_printf (buf, "Receiving delta parts: %u/%u %s/%s", - fetched_delta_parts, total_delta_parts, - formatted_fetched, formatted_total); + fetched_delta_parts, total_delta_parts, formatted_fetched, + formatted_total); } } else if (scanning || outstanding_metadata_fetches) { g_string_append_printf (buf, "Receiving metadata objects: %u/(estimating) %s/s %s", - metadata_fetched, formatted_bytes_sec, formatted_bytes_transferred); + metadata_fetched, formatted_bytes_sec, + formatted_bytes_transferred); } else { g_string_append_printf (buf, "Receiving objects: %u%% (%u/%u) %s/s %s", - (guint)((((double)fetched) / requested) * 100), - fetched, requested, formatted_bytes_sec, formatted_bytes_transferred); + (guint)((((double)fetched) / requested) * 100), fetched, + requested, formatted_bytes_sec, formatted_bytes_transferred); } } else if (outstanding_writes) @@ -5306,28 +5056,20 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress * Append a GPG signature to a commit. */ gboolean -ostree_repo_append_gpg_signature (OstreeRepo *self, - const gchar *commit_checksum, - GBytes *signature_bytes, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GVariant) metadata = NULL; - if (!ostree_repo_read_commit_detached_metadata (self, - commit_checksum, - &metadata, - cancellable, +ostree_repo_append_gpg_signature (OstreeRepo *self, const gchar *commit_checksum, + GBytes *signature_bytes, GCancellable *cancellable, + GError **error) +{ + g_autoptr (GVariant) metadata = NULL; + if (!ostree_repo_read_commit_detached_metadata (self, commit_checksum, &metadata, cancellable, error)) return FALSE; #ifndef OSTREE_DISABLE_GPGME - g_autoptr(GVariant) new_metadata = - _ostree_detached_metadata_append_gpg_sig (metadata, signature_bytes); + g_autoptr (GVariant) new_metadata + = _ostree_detached_metadata_append_gpg_sig (metadata, signature_bytes); - if (!ostree_repo_write_commit_detached_metadata (self, - commit_checksum, - new_metadata, - cancellable, + if (!ostree_repo_write_commit_detached_metadata (self, commit_checksum, new_metadata, cancellable, error)) return FALSE; @@ -5339,34 +5081,32 @@ ostree_repo_append_gpg_signature (OstreeRepo *self, #ifndef OSTREE_DISABLE_GPGME static gboolean -sign_data (OstreeRepo *self, - GBytes *input_data, - const gchar *key_id, - const gchar *homedir, - GBytes **out_signature, - GCancellable *cancellable, - GError **error) -{ - g_auto(GLnxTmpfile) tmpf = { 0, }; - if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_RDWR | O_CLOEXEC, - &tmpf, error)) +sign_data (OstreeRepo *self, GBytes *input_data, const gchar *key_id, const gchar *homedir, + GBytes **out_signature, GCancellable *cancellable, GError **error) +{ + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_RDWR | O_CLOEXEC, &tmpf, error)) return FALSE; - g_autoptr(GOutputStream) tmp_signature_output = g_unix_output_stream_new (tmpf.fd, FALSE); + g_autoptr (GOutputStream) tmp_signature_output = g_unix_output_stream_new (tmpf.fd, FALSE); - g_auto(gpgme_ctx_t) context = ot_gpgme_new_ctx (homedir, error); + g_auto (gpgme_ctx_t) context = ot_gpgme_new_ctx (homedir, error); if (!context) return FALSE; /* Get the secret keys with the given key id */ - g_auto(gpgme_key_t) key = NULL; + g_auto (gpgme_key_t) key = NULL; gpgme_error_t err = gpgme_get_key (context, key_id, &key, 1); if (gpgme_err_code (err) == GPG_ERR_EOF) return glnx_throw (error, "No gpg key found with ID %s (homedir: %s)", key_id, homedir ? homedir : ""); - else if (gpgme_err_code (err) == GPG_ERR_AMBIGUOUS_NAME) { - return glnx_throw (error, "gpg key id %s ambiguous (homedir: %s). Try the fingerprint instead", key_id, - homedir ? homedir : ""); - } + else if (gpgme_err_code (err) == GPG_ERR_AMBIGUOUS_NAME) + { + return glnx_throw (error, + "gpg key id %s ambiguous (homedir: %s). Try the fingerprint instead", + key_id, homedir ? homedir : ""); + } else if (err != GPG_ERR_NO_ERROR) return ot_gpgme_throw (err, error, "Unable to lookup key ID %s", key_id); @@ -5375,14 +5115,14 @@ sign_data (OstreeRepo *self, return ot_gpgme_throw (err, error, "Error signing commit"); /* Get a gpg buffer from the commit */ - g_auto(gpgme_data_t) commit_buffer = NULL; + g_auto (gpgme_data_t) commit_buffer = NULL; gsize len; const char *buf = g_bytes_get_data (input_data, &len); if ((err = gpgme_data_new_from_mem (&commit_buffer, buf, len, FALSE)) != GPG_ERR_NO_ERROR) return ot_gpgme_throw (err, error, "Failed to create buffer from commit file"); /* Sign it */ - g_auto(gpgme_data_t) signature_buffer = ot_gpgme_data_output (tmp_signature_output); + g_auto (gpgme_data_t) signature_buffer = ot_gpgme_data_output (tmp_signature_output); if ((err = gpgme_op_sign (context, commit_buffer, signature_buffer, GPGME_SIG_MODE_DETACH)) != GPG_ERR_NO_ERROR) return ot_gpgme_throw (err, error, "Failure signing commit file"); @@ -5390,7 +5130,7 @@ sign_data (OstreeRepo *self, return FALSE; /* Return a mmap() reference */ - g_autoptr(GMappedFile) signature_file = g_mapped_file_new_from_fd (tmpf.fd, FALSE, error); + g_autoptr (GMappedFile) signature_file = g_mapped_file_new_from_fd (tmpf.fd, FALSE, error); if (!signature_file) return FALSE; @@ -5412,27 +5152,20 @@ sign_data (OstreeRepo *self, * Add a GPG signature to a commit. */ gboolean -ostree_repo_sign_commit (OstreeRepo *self, - const gchar *commit_checksum, - const gchar *key_id, - const gchar *homedir, - GCancellable *cancellable, - GError **error) +ostree_repo_sign_commit (OstreeRepo *self, const gchar *commit_checksum, const gchar *key_id, + const gchar *homedir, GCancellable *cancellable, GError **error) { #ifndef OSTREE_DISABLE_GPGME - g_autoptr(GBytes) commit_data = NULL; - g_autoptr(GBytes) signature = NULL; + g_autoptr (GBytes) commit_data = NULL; + g_autoptr (GBytes) signature = NULL; - g_autoptr(GVariant) commit_variant = NULL; - if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, - commit_checksum, &commit_variant, error)) + g_autoptr (GVariant) commit_variant = NULL; + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit_variant, + error)) return glnx_prefix_error (error, "Failed to read commit"); - g_autoptr(GVariant) old_metadata = NULL; - if (!ostree_repo_read_commit_detached_metadata (self, - commit_checksum, - &old_metadata, - cancellable, + g_autoptr (GVariant) old_metadata = NULL; + if (!ostree_repo_read_commit_detached_metadata (self, commit_checksum, &old_metadata, cancellable, error)) return glnx_prefix_error (error, "Failed to read detached metadata"); @@ -5443,14 +5176,12 @@ ostree_repo_sign_commit (OstreeRepo *self, * We want to avoid storing duplicate signatures in the metadata. We * pass the homedir so that the signing key can be imported, allowing * subkey signatures to be recognised. */ - g_autoptr(GError) local_error = NULL; - g_autoptr(GFile) verify_keydir = NULL; + g_autoptr (GError) local_error = NULL; + g_autoptr (GFile) verify_keydir = NULL; if (homedir != NULL) verify_keydir = g_file_new_for_path (homedir); - g_autoptr(OstreeGpgVerifyResult) result - =_ostree_repo_gpg_verify_with_metadata (self, commit_data, old_metadata, - NULL, verify_keydir, NULL, - cancellable, &local_error); + g_autoptr (OstreeGpgVerifyResult) result = _ostree_repo_gpg_verify_with_metadata ( + self, commit_data, old_metadata, NULL, verify_keydir, NULL, cancellable, &local_error); if (!result) { /* "Not found" just means the commit is not yet signed. That's okay. */ @@ -5463,22 +5194,18 @@ ostree_repo_sign_commit (OstreeRepo *self, } else if (ostree_gpg_verify_result_lookup (result, key_id, NULL)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS, - "Commit is already signed with GPG key %s", key_id); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS, "Commit is already signed with GPG key %s", + key_id); return FALSE; } - if (!sign_data (self, commit_data, key_id, homedir, - &signature, cancellable, error)) + if (!sign_data (self, commit_data, key_id, homedir, &signature, cancellable, error)) return FALSE; - g_autoptr(GVariant) new_metadata = - _ostree_detached_metadata_append_gpg_sig (old_metadata, signature); + g_autoptr (GVariant) new_metadata + = _ostree_detached_metadata_append_gpg_sig (old_metadata, signature); - if (!ostree_repo_write_commit_detached_metadata (self, - commit_checksum, - new_metadata, - cancellable, + if (!ostree_repo_write_commit_detached_metadata (self, commit_checksum, new_metadata, cancellable, error)) return FALSE; @@ -5503,92 +5230,91 @@ ostree_repo_sign_commit (OstreeRepo *self, * Add a GPG signature to a static delta. */ gboolean -ostree_repo_sign_delta (OstreeRepo *self, - const gchar *from_commit, - const gchar *to_commit, - const gchar *key_id, - const gchar *homedir, - GCancellable *cancellable, - GError **error) -{ - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "ostree_repo_sign_delta is deprecated"); +ostree_repo_sign_delta (OstreeRepo *self, const gchar *from_commit, const gchar *to_commit, + const gchar *key_id, const gchar *homedir, GCancellable *cancellable, + GError **error) +{ + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "ostree_repo_sign_delta is deprecated"); return FALSE; } -/** - * ostree_repo_add_gpg_signature_summary: - * @self: Self - * @key_id: (array zero-terminated=1) (element-type utf8): NULL-terminated array of GPG keys. - * @homedir: (allow-none): GPG home directory, or %NULL - * @cancellable: A #GCancellable - * @error: a #GError - * - * Add a GPG signature to a summary file. - */ -gboolean -ostree_repo_add_gpg_signature_summary (OstreeRepo *self, - const gchar **key_id, - const gchar *homedir, - GCancellable *cancellable, - GError **error) +static gboolean +_ostree_repo_add_gpg_signature_summary_at (OstreeRepo *self, int dir_fd, const gchar **key_id, + const gchar *homedir, GCancellable *cancellable, + GError **error) { #ifndef OSTREE_DISABLE_GPGME glnx_autofd int fd = -1; - if (!glnx_openat_rdonly (self->repo_dir_fd, "summary", TRUE, &fd, error)) + if (!glnx_openat_rdonly (dir_fd, "summary", TRUE, &fd, error)) return FALSE; - g_autoptr(GBytes) summary_data = ot_fd_readall_or_mmap (fd, 0, error); + g_autoptr (GBytes) summary_data = ot_fd_readall_or_mmap (fd, 0, error); if (!summary_data) return FALSE; /* Note that fd is reused below */ glnx_close_fd (&fd); - g_autoptr(GVariant) metadata = NULL; - if (!ot_openat_ignore_enoent (self->repo_dir_fd, "summary.sig", &fd, error)) + g_autoptr (GVariant) metadata = NULL; + if (!ot_openat_ignore_enoent (dir_fd, "summary.sig", &fd, error)) return FALSE; if (fd >= 0) { - if (!ot_variant_read_fd (fd, 0, G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING), - FALSE, &metadata, error)) + if (!ot_variant_read_fd (fd, 0, G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING), FALSE, + &metadata, error)) return FALSE; } for (guint i = 0; key_id[i]; i++) { - g_autoptr(GBytes) signature_data = NULL; - if (!sign_data (self, summary_data, key_id[i], homedir, - &signature_data, - cancellable, error)) + g_autoptr (GBytes) signature_data = NULL; + if (!sign_data (self, summary_data, key_id[i], homedir, &signature_data, cancellable, error)) return FALSE; - g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata); + g_autoptr (GVariant) old_metadata = g_steal_pointer (&metadata); metadata = _ostree_detached_metadata_append_gpg_sig (old_metadata, signature_data); } - g_autoptr(GVariant) normalized = g_variant_get_normal_form (metadata); + g_autoptr (GVariant) normalized = g_variant_get_normal_form (metadata); - if (!_ostree_repo_file_replace_contents (self, - self->repo_dir_fd, - "summary.sig", + if (!_ostree_repo_file_replace_contents (self, dir_fd, "summary.sig", g_variant_get_data (normalized), - g_variant_get_size (normalized), - cancellable, error)) + g_variant_get_size (normalized), cancellable, error)) return FALSE; return TRUE; #else - return glnx_throw (error, "GPG feature is disabled in a build time"); + return glnx_throw (error, "GPG feature is disabled at build time"); #endif /* OSTREE_DISABLE_GPGME */ } +/** + * ostree_repo_add_gpg_signature_summary: + * @self: Self + * @key_id: (array zero-terminated=1) (element-type utf8): NULL-terminated array of GPG keys. + * @homedir: (allow-none): GPG home directory, or %NULL + * @cancellable: A #GCancellable + * @error: a #GError + * + * Add a GPG signature to a summary file. + */ +gboolean +ostree_repo_add_gpg_signature_summary (OstreeRepo *self, const gchar **key_id, const gchar *homedir, + GCancellable *cancellable, GError **error) +{ +#ifndef OSTREE_DISABLE_GPGME + return _ostree_repo_add_gpg_signature_summary_at (self, self->repo_dir_fd, key_id, homedir, + cancellable, error); +#else + return glnx_throw (error, "GPG feature is disabled in a build time"); +#endif /* OSTREE_DISABLE_GPGME */ +} /** * ostree_repo_gpg_sign_data: * @self: Self * @data: Data as a #GBytes - * @old_signatures: Existing signatures to append to (or %NULL) + * @old_signatures: (nullable): Existing signatures to append to (or %NULL) * @key_id: (array zero-terminated=1) (element-type utf8): NULL-terminated array of GPG keys. - * @homedir: (allow-none): GPG home directory, or %NULL + * @homedir: (nullable): GPG home directory, or %NULL * @out_signatures: (out): in case of success will contain signature * @cancellable: A #GCancellable * @error: a #GError @@ -5599,37 +5325,31 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self, * * You can use ostree_repo_gpg_verify_data() to verify the signatures. * - * Returns: @TRUE if @data has been signed successfully, - * @FALSE in case of error (@error will contain the reason). + * Returns: %TRUE if @data has been signed successfully, + * %FALSE in case of error (@error will contain the reason). * * Since: 2020.8 */ gboolean -ostree_repo_gpg_sign_data (OstreeRepo *self, - GBytes *data, - GBytes *old_signatures, - const gchar **key_id, - const gchar *homedir, - GBytes **out_signatures, - GCancellable *cancellable, - GError **error) +ostree_repo_gpg_sign_data (OstreeRepo *self, GBytes *data, GBytes *old_signatures, + const gchar **key_id, const gchar *homedir, GBytes **out_signatures, + GCancellable *cancellable, GError **error) { #ifndef OSTREE_DISABLE_GPGME - g_autoptr(GVariant) metadata = NULL; - g_autoptr(GVariant) res = NULL; + g_autoptr (GVariant) metadata = NULL; + g_autoptr (GVariant) res = NULL; if (old_signatures) - metadata = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING), old_signatures, FALSE)); + metadata = g_variant_ref_sink (g_variant_new_from_bytes ( + G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING), old_signatures, FALSE)); for (guint i = 0; key_id[i]; i++) { - g_autoptr(GBytes) signature_data = NULL; - if (!sign_data (self, data, key_id[i], homedir, - &signature_data, - cancellable, error)) + g_autoptr (GBytes) signature_data = NULL; + if (!sign_data (self, data, key_id[i], homedir, &signature_data, cancellable, error)) return FALSE; - g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata); + g_autoptr (GVariant) old_metadata = g_steal_pointer (&metadata); metadata = _ostree_detached_metadata_append_gpg_sig (old_metadata, signature_data); } @@ -5641,7 +5361,6 @@ ostree_repo_gpg_sign_data (OstreeRepo *self, #endif /* OSTREE_DISABLE_GPGME */ } - #ifndef OSTREE_DISABLE_GPGME /* Special remote for _ostree_repo_gpg_verify_with_metadata() */ static const char *OSTREE_ALL_REMOTES = "__OSTREE_ALL_REMOTES__"; @@ -5650,11 +5369,8 @@ static const char *OSTREE_ALL_REMOTES = "__OSTREE_ALL_REMOTES__"; * /etc/ostree/remotes.d. */ static gboolean -find_keyring (OstreeRepo *self, - OstreeRemote *remote, - GBytes **ret_bytes, - GCancellable *cancellable, - GError **error) +find_keyring (OstreeRepo *self, OstreeRemote *remote, GBytes **ret_bytes, GCancellable *cancellable, + GError **error) { glnx_autofd int fd = -1; if (!ot_openat_ignore_enoent (self->repo_dir_fd, remote->keyring, &fd, error)) @@ -5669,10 +5385,10 @@ find_keyring (OstreeRepo *self, return TRUE; } - g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL); + g_autoptr (GFile) remotes_d = get_remotes_d_dir (self, NULL); if (remotes_d) { - g_autoptr(GFile) child = g_file_get_child (remotes_d, remote->keyring); + g_autoptr (GFile) child = g_file_get_child (remotes_d, remote->keyring); if (!ot_openat_ignore_enoent (AT_FDCWD, gs_file_get_path_cached (child), &fd, error)) return FALSE; @@ -5695,36 +5411,32 @@ find_keyring (OstreeRepo *self, } static gboolean -_ostree_repo_gpg_prepare_verifier (OstreeRepo *self, - const gchar *remote_name, - GFile *keyringdir, - GFile *extra_keyring, - gboolean add_global_keyrings, - OstreeGpgVerifier **out_verifier, - GCancellable *cancellable, - GError **error) +_ostree_repo_gpg_prepare_verifier (OstreeRepo *self, const gchar *remote_name, GFile *keyringdir, + GFile *extra_keyring, gboolean add_global_keyrings, + OstreeGpgVerifier **out_verifier, GCancellable *cancellable, + GError **error) { - g_autoptr(OstreeGpgVerifier) verifier = _ostree_gpg_verifier_new (); + g_autoptr (OstreeGpgVerifier) verifier = _ostree_gpg_verifier_new (); if (remote_name == OSTREE_ALL_REMOTES) { /* Add all available remote keyring files. */ - if (!_ostree_gpg_verifier_add_keyring_dir_at (verifier, self->repo_dir_fd, ".", - cancellable, error)) + if (!_ostree_gpg_verifier_add_keyring_dir_at (verifier, self->repo_dir_fd, ".", cancellable, + error)) return FALSE; } else if (remote_name != NULL) { /* Add the remote's keyring file if it exists. */ - g_autoptr(OstreeRemote) remote = NULL; + g_autoptr (OstreeRemote) remote = NULL; remote = _ostree_repo_get_remote_inherited (self, remote_name, error); if (remote == NULL) return FALSE; - g_autoptr(GBytes) keyring_data = NULL; + g_autoptr (GBytes) keyring_data = NULL; if (!find_keyring (self, remote, &keyring_data, cancellable, error)) return FALSE; @@ -5734,21 +5446,16 @@ _ostree_repo_gpg_prepare_verifier (OstreeRepo *self, add_global_keyrings = FALSE; } - g_auto(GStrv) gpgkeypath_list = NULL; + g_auto (GStrv) gpgkeypath_list = NULL; - if (!ot_keyfile_get_string_list_with_separator_choice (remote->options, - remote->group, - "gpgkeypath", - ";,", - &gpgkeypath_list, - error)) + if (!ot_keyfile_get_string_list_with_separator_choice ( + remote->options, remote->group, "gpgkeypath", ";,", &gpgkeypath_list, error)) return FALSE; if (gpgkeypath_list) { for (char **iter = gpgkeypath_list; *iter != NULL; ++iter) - if (!_ostree_gpg_verifier_add_keyfile_path (verifier, *iter, - cancellable, error)) + if (!_ostree_gpg_verifier_add_keyfile_path (verifier, *iter, cancellable, error)) return FALSE; } } @@ -5762,8 +5469,7 @@ _ostree_repo_gpg_prepare_verifier (OstreeRepo *self, if (keyringdir) { - if (!_ostree_gpg_verifier_add_keyring_dir (verifier, keyringdir, - cancellable, error)) + if (!_ostree_gpg_verifier_add_keyring_dir (verifier, keyringdir, cancellable, error)) return FALSE; } if (extra_keyring != NULL) @@ -5778,57 +5484,38 @@ _ostree_repo_gpg_prepare_verifier (OstreeRepo *self, } static OstreeGpgVerifyResult * -_ostree_repo_gpg_verify_data_internal (OstreeRepo *self, - const gchar *remote_name, - GBytes *data, - GBytes *signatures, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(OstreeGpgVerifier) verifier = NULL; - if (!_ostree_repo_gpg_prepare_verifier (self, - remote_name, - keyringdir, - extra_keyring, - TRUE, - &verifier, - cancellable, - error)) +_ostree_repo_gpg_verify_data_internal (OstreeRepo *self, const gchar *remote_name, GBytes *data, + GBytes *signatures, GFile *keyringdir, GFile *extra_keyring, + GCancellable *cancellable, GError **error) +{ + g_autoptr (OstreeGpgVerifier) verifier = NULL; + if (!_ostree_repo_gpg_prepare_verifier (self, remote_name, keyringdir, extra_keyring, TRUE, + &verifier, cancellable, error)) return NULL; - return _ostree_gpg_verifier_check_signature (verifier, - data, - signatures, - cancellable, - error); + return _ostree_gpg_verifier_check_signature (verifier, data, signatures, cancellable, error); } OstreeGpgVerifyResult * -_ostree_repo_gpg_verify_with_metadata (OstreeRepo *self, - GBytes *signed_data, - GVariant *metadata, - const char *remote_name, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GVariant) signaturedata = NULL; +_ostree_repo_gpg_verify_with_metadata (OstreeRepo *self, GBytes *signed_data, GVariant *metadata, + const char *remote_name, GFile *keyringdir, + GFile *extra_keyring, GCancellable *cancellable, + GError **error) +{ + g_autoptr (GVariant) signaturedata = NULL; GByteArray *buffer; GVariantIter iter; GVariant *child; g_autoptr (GBytes) signatures = NULL; if (metadata) - signaturedata = g_variant_lookup_value (metadata, - _OSTREE_METADATA_GPGSIGS_NAME, + signaturedata = g_variant_lookup_value (metadata, _OSTREE_METADATA_GPGSIGS_NAME, _OSTREE_METADATA_GPGSIGS_TYPE); if (!signaturedata) { g_set_error_literal (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, - "GPG verification enabled, but no signatures found (use gpg-verify=false in remote config to disable)"); + "GPG verification enabled, but no signatures found (use " + "gpg-verify=false in remote config to disable)"); return NULL; } @@ -5844,50 +5531,35 @@ _ostree_repo_gpg_verify_with_metadata (OstreeRepo *self, g_variant_iter_init (&iter, signaturedata); while ((child = g_variant_iter_next_value (&iter)) != NULL) { - g_byte_array_append (buffer, - g_variant_get_data (child), - g_variant_get_size (child)); + g_byte_array_append (buffer, g_variant_get_data (child), g_variant_get_size (child)); g_variant_unref (child); } signatures = g_byte_array_free_to_bytes (buffer); - return _ostree_repo_gpg_verify_data_internal (self, - remote_name, - signed_data, - signatures, - keyringdir, - extra_keyring, - cancellable, - error); + return _ostree_repo_gpg_verify_data_internal (self, remote_name, signed_data, signatures, + keyringdir, extra_keyring, cancellable, error); } /* Needed an internal version for the remote_name parameter. */ OstreeGpgVerifyResult * -_ostree_repo_verify_commit_internal (OstreeRepo *self, - const char *commit_checksum, - const char *remote_name, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GVariant) commit_variant = NULL; +_ostree_repo_verify_commit_internal (OstreeRepo *self, const char *commit_checksum, + const char *remote_name, GFile *keyringdir, + GFile *extra_keyring, GCancellable *cancellable, + GError **error) +{ + g_autoptr (GVariant) commit_variant = NULL; /* Load the commit */ - if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, - commit_checksum, &commit_variant, + if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit_variant, error)) return glnx_prefix_error_null (error, "Failed to read commit"); /* Load the metadata */ - g_autoptr(GVariant) metadata = NULL; - if (!ostree_repo_read_commit_detached_metadata (self, - commit_checksum, - &metadata, - cancellable, + g_autoptr (GVariant) metadata = NULL; + if (!ostree_repo_read_commit_detached_metadata (self, commit_checksum, &metadata, cancellable, error)) return glnx_prefix_error_null (error, "Failed to read detached metadata"); - g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit_variant); + g_autoptr (GBytes) signed_data = g_variant_get_data_as_bytes (commit_variant); /* XXX This is a hackish way to indicate to use ALL remote-specific * keyrings in the signature verification. We want this when @@ -5895,10 +5567,8 @@ _ostree_repo_verify_commit_internal (OstreeRepo *self, if (remote_name == NULL) remote_name = OSTREE_ALL_REMOTES; - return _ostree_repo_gpg_verify_with_metadata (self, signed_data, - metadata, remote_name, - keyringdir, extra_keyring, - cancellable, error); + return _ostree_repo_gpg_verify_with_metadata (self, signed_data, metadata, remote_name, + keyringdir, extra_keyring, cancellable, error); } #endif /* OSTREE_DISABLE_GPGME */ @@ -5917,18 +5587,13 @@ _ostree_repo_verify_commit_internal (OstreeRepo *self, * Returns: %TRUE if there was a GPG signature from a trusted keyring, otherwise %FALSE */ gboolean -ostree_repo_verify_commit (OstreeRepo *self, - const gchar *commit_checksum, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error) +ostree_repo_verify_commit (OstreeRepo *self, const gchar *commit_checksum, GFile *keyringdir, + GFile *extra_keyring, GCancellable *cancellable, GError **error) { #ifndef OSTREE_DISABLE_GPGME - g_autoptr(OstreeGpgVerifyResult) result = NULL; + g_autoptr (OstreeGpgVerifyResult) result = NULL; - result = ostree_repo_verify_commit_ext (self, commit_checksum, - keyringdir, extra_keyring, + result = ostree_repo_verify_commit_ext (self, commit_checksum, keyringdir, extra_keyring, cancellable, error); if (!ostree_gpg_verify_result_require_valid_signature (result, error)) @@ -5955,21 +5620,12 @@ ostree_repo_verify_commit (OstreeRepo *self, * Returns: (transfer full): an #OstreeGpgVerifyResult, or %NULL on error */ OstreeGpgVerifyResult * -ostree_repo_verify_commit_ext (OstreeRepo *self, - const gchar *commit_checksum, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error) +ostree_repo_verify_commit_ext (OstreeRepo *self, const gchar *commit_checksum, GFile *keyringdir, + GFile *extra_keyring, GCancellable *cancellable, GError **error) { #ifndef OSTREE_DISABLE_GPGME - return _ostree_repo_verify_commit_internal (self, - commit_checksum, - NULL, - keyringdir, - extra_keyring, - cancellable, - error); + return _ostree_repo_verify_commit_internal (self, commit_checksum, NULL, keyringdir, + extra_keyring, cancellable, error); #else glnx_throw (error, "GPG feature is disabled in a build time"); return NULL; @@ -5993,20 +5649,13 @@ ostree_repo_verify_commit_ext (OstreeRepo *self, * Since: 2016.14 */ OstreeGpgVerifyResult * -ostree_repo_verify_commit_for_remote (OstreeRepo *self, - const gchar *commit_checksum, - const gchar *remote_name, - GCancellable *cancellable, - GError **error) +ostree_repo_verify_commit_for_remote (OstreeRepo *self, const gchar *commit_checksum, + const gchar *remote_name, GCancellable *cancellable, + GError **error) { #ifndef OSTREE_DISABLE_GPGME - return _ostree_repo_verify_commit_internal (self, - commit_checksum, - remote_name, - NULL, - NULL, - cancellable, - error); + return _ostree_repo_verify_commit_internal (self, commit_checksum, remote_name, NULL, NULL, + cancellable, error); #else glnx_throw (error, "GPG feature is disabled in a build time"); return NULL; @@ -6035,28 +5684,18 @@ ostree_repo_verify_commit_for_remote (OstreeRepo *self, * Since: 2016.6 */ OstreeGpgVerifyResult * -ostree_repo_gpg_verify_data (OstreeRepo *self, - const gchar *remote_name, - GBytes *data, - GBytes *signatures, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error) +ostree_repo_gpg_verify_data (OstreeRepo *self, const gchar *remote_name, GBytes *data, + GBytes *signatures, GFile *keyringdir, GFile *extra_keyring, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (signatures != NULL, NULL); #ifndef OSTREE_DISABLE_GPGME - return _ostree_repo_gpg_verify_data_internal (self, - (remote_name != NULL) ? remote_name : OSTREE_ALL_REMOTES, - data, - signatures, - keyringdir, - extra_keyring, - cancellable, - error); + return _ostree_repo_gpg_verify_data_internal ( + self, (remote_name != NULL) ? remote_name : OSTREE_ALL_REMOTES, data, signatures, keyringdir, + extra_keyring, cancellable, error); #else glnx_throw (error, "GPG feature is disabled in a build time"); return NULL; @@ -6078,31 +5717,22 @@ ostree_repo_gpg_verify_data (OstreeRepo *self, * Returns: (transfer full): an #OstreeGpgVerifyResult, or %NULL on error */ OstreeGpgVerifyResult * -ostree_repo_verify_summary (OstreeRepo *self, - const char *remote_name, - GBytes *summary, - GBytes *signatures, - GCancellable *cancellable, - GError **error) +ostree_repo_verify_summary (OstreeRepo *self, const char *remote_name, GBytes *summary, + GBytes *signatures, GCancellable *cancellable, GError **error) { - g_autoptr(GVariant) signatures_variant = NULL; + g_autoptr (GVariant) signatures_variant = NULL; g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); g_return_val_if_fail (remote_name != NULL, NULL); g_return_val_if_fail (summary != NULL, NULL); g_return_val_if_fail (signatures != NULL, NULL); - signatures_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, - signatures, FALSE); + signatures_variant + = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, signatures, FALSE); #ifndef OSTREE_DISABLE_GPGME - return _ostree_repo_gpg_verify_with_metadata (self, - summary, - signatures_variant, - remote_name, - NULL, NULL, - cancellable, - error); + return _ostree_repo_gpg_verify_with_metadata (self, summary, signatures_variant, remote_name, + NULL, NULL, cancellable, error); #else glnx_throw (error, "GPG feature is disabled in a build time"); return NULL; @@ -6113,15 +5743,13 @@ ostree_repo_verify_summary (OstreeRepo *self, * @refs_builder to go into a `summary` file. This includes building the * standard additional metadata keys for the ref. */ static gboolean -summary_add_ref_entry (OstreeRepo *self, - const char *ref, - const char *checksum, - GVariantBuilder *refs_builder, - GError **error) +summary_add_ref_entry (OstreeRepo *self, const char *ref, const char *checksum, + GVariantBuilder *refs_builder, GError **error) { - g_auto(GVariantDict) commit_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantDict) commit_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER; - g_assert (ref); g_assert (checksum); + g_assert (ref); + g_assert (checksum); g_autofree char *remotename = NULL; if (!ostree_parse_refspec (ref, &remotename, NULL, NULL)) @@ -6131,16 +5759,16 @@ summary_add_ref_entry (OstreeRepo *self, if (remotename != NULL) return TRUE; - g_autoptr(GVariant) commit_obj = NULL; + g_autoptr (GVariant) commit_obj = NULL; if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, checksum, &commit_obj, error)) return FALSE; - g_autoptr(GVariant) orig_metadata = g_variant_get_child_value (commit_obj, 0); + g_autoptr (GVariant) orig_metadata = g_variant_get_child_value (commit_obj, 0); g_variant_dict_init (&commit_metadata_builder, NULL); /* Forward the commit’s timestamp and version if they're valid. */ guint64 commit_timestamp = ostree_commit_get_timestamp (commit_obj); - g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc (commit_timestamp); + g_autoptr (GDateTime) dt = g_date_time_new_from_unix_utc (commit_timestamp); if (dt != NULL) g_variant_dict_insert_value (&commit_metadata_builder, OSTREE_COMMIT_TIMESTAMP, @@ -6150,69 +5778,120 @@ summary_add_ref_entry (OstreeRepo *self, if (g_variant_lookup (orig_metadata, OSTREE_COMMIT_META_KEY_VERSION, "&s", &version)) g_variant_dict_insert (&commit_metadata_builder, OSTREE_COMMIT_VERSION, "s", version); - g_variant_builder_add_value (refs_builder, - g_variant_new ("(s(t@ay@a{sv}))", ref, - (guint64) g_variant_get_size (commit_obj), - ostree_checksum_to_bytes_v (checksum), - g_variant_dict_end (&commit_metadata_builder))); + g_variant_builder_add_value ( + refs_builder, g_variant_new ("(s(t@ay@a{sv}))", ref, (guint64)g_variant_get_size (commit_obj), + ostree_checksum_to_bytes_v (checksum), + g_variant_dict_end (&commit_metadata_builder))); return TRUE; } -/** - * ostree_repo_regenerate_summary: - * @self: Repo - * @additional_metadata: (allow-none): A GVariant of type a{sv}, or %NULL - * @cancellable: Cancellable - * @error: Error - * - * An OSTree repository can contain a high level "summary" file that - * describes the available branches and other metadata. - * - * If the timetable for making commits and updating the summary file is fairly - * regular, setting the `ostree.summary.expires` key in @additional_metadata - * will aid clients in working out when to check for updates. - * - * It is regenerated automatically after any ref is - * added, removed, or updated if `core/auto-update-summary` is set. - * - * If the `core/collection-id` key is set in the configuration, it will be - * included as %OSTREE_SUMMARY_COLLECTION_ID in the summary file. Refs that - * have associated collection IDs will be included in the generated summary - * file, listed under the %OSTREE_SUMMARY_COLLECTION_MAP key. Collection IDs - * and refs in %OSTREE_SUMMARY_COLLECTION_MAP are guaranteed to be in - * lexicographic order. - * - * Locking: shared (Prior to 2021.7, this was exclusive) - */ -gboolean -ostree_repo_regenerate_summary (OstreeRepo *self, - GVariant *additional_metadata, - GCancellable *cancellable, - GError **error) +static gboolean +regenerate_metadata (OstreeRepo *self, gboolean do_metadata_commit, GVariant *additional_metadata, + GVariant *options, GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepoAutoLock) lock = NULL; + g_autoptr (OstreeRepoAutoLock) lock = NULL; gboolean no_deltas_in_summary = FALSE; - lock = ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_SHARED, - cancellable, error); + lock = ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_SHARED, cancellable, error); if (!lock) return FALSE; - g_auto(GVariantDict) additional_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER; - g_variant_dict_init (&additional_metadata_builder, additional_metadata); - g_autoptr(GVariantBuilder) refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))")); + /* Parse options vardict. */ + g_autofree char **gpg_key_ids = NULL; + const char *gpg_homedir = NULL; + g_autoptr (GVariant) sign_keys = NULL; + const char *sign_type = NULL; + g_autoptr (OstreeSign) sign = NULL; + + if (options != NULL) + { + if (!g_variant_is_of_type (options, G_VARIANT_TYPE_VARDICT)) + return glnx_throw (error, "Invalid options doesn't match variant type '%s'", + (const char *)G_VARIANT_TYPE_VARDICT); + + (void)g_variant_lookup (options, "gpg-key-ids", "^a&s", &gpg_key_ids); + (void)g_variant_lookup (options, "gpg-homedir", "&s", &gpg_homedir); + sign_keys = g_variant_lookup_value (options, "sign-keys", G_VARIANT_TYPE_ARRAY); + (void)g_variant_lookup (options, "sign-type", "&s", &sign_type); + + if (sign_keys != NULL) + { + if (sign_type == NULL) + sign_type = OSTREE_SIGN_NAME_ED25519; + + sign = ostree_sign_get_by_name (sign_type, error); + if (sign == NULL) + return FALSE; + } + } const gchar *main_collection_id = ostree_repo_get_collection_id (self); + /* Write out a new metadata commit for the repository when it has a collection ID. */ + if (do_metadata_commit && main_collection_id != NULL) + { + g_autoptr (OstreeRepoAutoTransaction) txn + = _ostree_repo_auto_transaction_start (self, cancellable, error); + if (!txn) + return FALSE; + + /* Disable automatic summary updating since we're already doing it */ + self->txn.disable_auto_summary = TRUE; + + g_autofree gchar *new_ostree_metadata_checksum = NULL; + if (!_ostree_repo_transaction_write_repo_metadata ( + self, additional_metadata, &new_ostree_metadata_checksum, cancellable, error)) + return FALSE; + + /* Sign the new commit. */ + if (gpg_key_ids != NULL) + { + for (const char *const *iter = (const char *const *)gpg_key_ids; + iter != NULL && *iter != NULL; iter++) + { + const char *gpg_key_id = *iter; + + if (!ostree_repo_sign_commit (self, new_ostree_metadata_checksum, gpg_key_id, + gpg_homedir, cancellable, error)) + return FALSE; + } + } + + if (sign_keys != NULL) + { + GVariantIter *iter; + GVariant *key; + + g_variant_get (sign_keys, "av", &iter); + while (g_variant_iter_loop (iter, "v", &key)) + { + if (!ostree_sign_set_sk (sign, key, error)) + return FALSE; + + if (!ostree_sign_commit (sign, self, new_ostree_metadata_checksum, cancellable, + error)) + return FALSE; + } + } + + if (!_ostree_repo_auto_transaction_commit (txn, NULL, cancellable, error)) + return FALSE; + } + + g_auto (GVariantDict) additional_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_variant_dict_init (&additional_metadata_builder, additional_metadata); + g_autoptr (GVariantBuilder) refs_builder + = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))")); + { if (main_collection_id == NULL) { - g_autoptr(GHashTable) refs = NULL; + g_autoptr (GHashTable) refs = NULL; if (!ostree_repo_list_refs (self, NULL, &refs, cancellable, error)) return FALSE; - g_autoptr(GList) ordered_keys = g_hash_table_get_keys (refs); + g_autoptr (GList) ordered_keys = g_hash_table_get_keys (refs); ordered_keys = g_list_sort (ordered_keys, (GCompareFunc)strcmp); for (GList *iter = ordered_keys; iter; iter = iter->next) @@ -6226,15 +5905,14 @@ ostree_repo_regenerate_summary (OstreeRepo *self, } } - if (!ot_keyfile_get_boolean_with_default (self->config, "core", - "no-deltas-in-summary", FALSE, + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "no-deltas-in-summary", FALSE, &no_deltas_in_summary, error)) return FALSE; if (!no_deltas_in_summary) { - g_autoptr(GPtrArray) delta_names = NULL; - g_auto(GVariantDict) deltas_builder = OT_VARIANT_BUILDER_INITIALIZER; + g_autoptr (GPtrArray) delta_names = NULL; + g_auto (GVariantDict) deltas_builder = OT_VARIANT_BUILDER_INITIALIZER; if (!ostree_repo_list_static_delta_names (self, &delta_names, cancellable, error)) return FALSE; @@ -6249,9 +5927,8 @@ ostree_repo_regenerate_summary (OstreeRepo *self, if (!_ostree_parse_delta_name (delta_names->pdata[i], &from, &to, error)) return FALSE; - digest = _ostree_repo_static_delta_superblock_digest (self, - (from && from[0]) ? from : NULL, - to, cancellable, error); + digest = _ostree_repo_static_delta_superblock_digest ( + self, (from && from[0]) ? from : NULL, to, cancellable, error); if (digest == NULL) return FALSE; @@ -6259,18 +5936,20 @@ ostree_repo_regenerate_summary (OstreeRepo *self, } if (delta_names->len > 0) - g_variant_dict_insert_value (&additional_metadata_builder, OSTREE_SUMMARY_STATIC_DELTAS, g_variant_dict_end (&deltas_builder)); + g_variant_dict_insert_value (&additional_metadata_builder, OSTREE_SUMMARY_STATIC_DELTAS, + g_variant_dict_end (&deltas_builder)); } { - g_variant_dict_insert_value (&additional_metadata_builder, OSTREE_SUMMARY_LAST_MODIFIED, - g_variant_new_uint64 (GUINT64_TO_BE (g_get_real_time () / G_USEC_PER_SEC))); + g_variant_dict_insert_value ( + &additional_metadata_builder, OSTREE_SUMMARY_LAST_MODIFIED, + g_variant_new_uint64 (GUINT64_TO_BE (g_get_real_time () / G_USEC_PER_SEC))); } { g_autofree char *remote_mode_str = NULL; - if (!ot_keyfile_get_value_with_default (self->config, "core", "mode", "bare", - &remote_mode_str, error)) + if (!ot_keyfile_get_value_with_default (self->config, "core", "mode", "bare", &remote_mode_str, + error)) return FALSE; g_variant_dict_insert_value (&additional_metadata_builder, OSTREE_SUMMARY_MODE, g_variant_new_string (remote_mode_str)); @@ -6291,21 +5970,21 @@ ostree_repo_regenerate_summary (OstreeRepo *self, /* Add refs which have a collection specified, which could be in refs/mirrors, * refs/heads, and/or refs/remotes. */ { - g_autoptr(GHashTable) collection_refs = NULL; + g_autoptr (GHashTable) collection_refs = NULL; if (!ostree_repo_list_collection_refs (self, NULL, &collection_refs, OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error)) return FALSE; gsize collection_map_size = 0; GHashTableIter iter; - g_autoptr(GHashTable) collection_map = NULL; /* (element-type utf8 GHashTable) */ + g_autoptr (GHashTable) collection_map = NULL; /* (element-type utf8 GHashTable) */ g_hash_table_iter_init (&iter, collection_refs); - collection_map = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, - (GDestroyNotify)g_hash_table_unref); + collection_map + = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_hash_table_unref); const OstreeCollectionRef *c_ref; const char *checksum; - while (g_hash_table_iter_next (&iter, (gpointer *) &c_ref, (gpointer *) &checksum)) + while (g_hash_table_iter_next (&iter, (gpointer *)&c_ref, (gpointer *)&checksum)) { GHashTable *ref_map = g_hash_table_lookup (collection_map, c_ref->collection_id); @@ -6315,22 +5994,25 @@ ostree_repo_regenerate_summary (OstreeRepo *self, g_hash_table_insert (collection_map, c_ref->collection_id, ref_map); } - g_hash_table_insert (ref_map, c_ref->ref_name, (gpointer) checksum); + g_hash_table_insert (ref_map, c_ref->ref_name, (gpointer)checksum); } - g_autoptr(GVariantBuilder) collection_refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sa(s(taya{sv}))}")); + g_autoptr (GVariantBuilder) collection_refs_builder + = g_variant_builder_new (G_VARIANT_TYPE ("a{sa(s(taya{sv}))}")); - g_autoptr(GList) ordered_collection_ids = g_hash_table_get_keys (collection_map); - ordered_collection_ids = g_list_sort (ordered_collection_ids, (GCompareFunc) strcmp); + g_autoptr (GList) ordered_collection_ids = g_hash_table_get_keys (collection_map); + ordered_collection_ids = g_list_sort (ordered_collection_ids, (GCompareFunc)strcmp); - for (GList *collection_iter = ordered_collection_ids; collection_iter; collection_iter = collection_iter->next) + for (GList *collection_iter = ordered_collection_ids; collection_iter; + collection_iter = collection_iter->next) { const char *collection_id = collection_iter->data; GHashTable *ref_map = g_hash_table_lookup (collection_map, collection_id); /* We put the local repo's collection ID in the main refs map, rather * than the collection map, for backwards compatibility. */ - gboolean is_main_collection_id = (main_collection_id != NULL && g_str_equal (collection_id, main_collection_id)); + gboolean is_main_collection_id + = (main_collection_id != NULL && g_str_equal (collection_id, main_collection_id)); if (!is_main_collection_id) { @@ -6339,14 +6021,15 @@ ostree_repo_regenerate_summary (OstreeRepo *self, g_variant_builder_open (collection_refs_builder, G_VARIANT_TYPE ("a(s(taya{sv}))")); } - g_autoptr(GList) ordered_refs = g_hash_table_get_keys (ref_map); - ordered_refs = g_list_sort (ordered_refs, (GCompareFunc) strcmp); + g_autoptr (GList) ordered_refs = g_hash_table_get_keys (ref_map); + ordered_refs = g_list_sort (ordered_refs, (GCompareFunc)strcmp); for (GList *ref_iter = ordered_refs; ref_iter != NULL; ref_iter = ref_iter->next) { const char *ref = ref_iter->data; const char *commit = g_hash_table_lookup (ref_map, ref); - GVariantBuilder *builder = is_main_collection_id ? refs_builder : collection_refs_builder; + GVariantBuilder *builder + = is_main_collection_id ? refs_builder : collection_refs_builder; if (!summary_add_ref_entry (self, ref, commit, builder, error)) return FALSE; @@ -6357,8 +6040,8 @@ ostree_repo_regenerate_summary (OstreeRepo *self, if (!is_main_collection_id) { - g_variant_builder_close (collection_refs_builder); /* array */ - g_variant_builder_close (collection_refs_builder); /* dict entry */ + g_variant_builder_close (collection_refs_builder); /* array */ + g_variant_builder_close (collection_refs_builder); /* dict entry */ } } @@ -6370,13 +6053,14 @@ ostree_repo_regenerate_summary (OstreeRepo *self, g_variant_builder_end (collection_refs_builder)); } - g_autoptr(GVariant) summary = NULL; + g_autoptr (GVariant) summary = NULL; { - g_autoptr(GVariantBuilder) summary_builder = - g_variant_builder_new (OSTREE_SUMMARY_GVARIANT_FORMAT); + g_autoptr (GVariantBuilder) summary_builder + = g_variant_builder_new (OSTREE_SUMMARY_GVARIANT_FORMAT); g_variant_builder_add_value (summary_builder, g_variant_builder_end (refs_builder)); - g_variant_builder_add_value (summary_builder, g_variant_dict_end (&additional_metadata_builder)); + g_variant_builder_add_value (summary_builder, + g_variant_dict_end (&additional_metadata_builder)); summary = g_variant_builder_end (summary_builder); g_variant_ref_sink (summary); } @@ -6384,21 +6068,129 @@ ostree_repo_regenerate_summary (OstreeRepo *self, if (!ostree_repo_static_delta_reindex (self, 0, NULL, cancellable, error)) return FALSE; - if (!_ostree_repo_file_replace_contents (self, - self->repo_dir_fd, - "summary", + /* Create the summary and signature in a temporary directory so that + * the summary isn't published without a matching signature. + */ + g_auto (GLnxTmpDir) summary_tmpdir = { + 0, + }; + if (!glnx_mkdtempat (self->tmp_dir_fd, "summary-XXXXXX", 0777, &summary_tmpdir, error)) + return FALSE; + g_debug ("Using summary tmpdir %s", summary_tmpdir.path); + + if (!_ostree_repo_file_replace_contents (self, summary_tmpdir.fd, "summary", g_variant_get_data (summary), - g_variant_get_size (summary), - cancellable, - error)) + g_variant_get_size (summary), cancellable, error)) + return FALSE; + + if (gpg_key_ids != NULL + && !_ostree_repo_add_gpg_signature_summary_at ( + self, summary_tmpdir.fd, (const char **)gpg_key_ids, gpg_homedir, cancellable, error)) return FALSE; - if (!ot_ensure_unlinked_at (self->repo_dir_fd, "summary.sig", error)) + if (sign_keys != NULL + && !_ostree_sign_summary_at (sign, self, summary_tmpdir.fd, sign_keys, cancellable, error)) return FALSE; + /* Rename them into place */ + if (!glnx_renameat (summary_tmpdir.fd, "summary", self->repo_dir_fd, "summary", error)) + return glnx_prefix_error (error, "Unable to rename summary file: "); + + if (gpg_key_ids != NULL || sign_keys != NULL) + { + if (!glnx_renameat (summary_tmpdir.fd, "summary.sig", self->repo_dir_fd, "summary.sig", + error)) + { + /* Delete an existing signature since it no longer corresponds + * to the published summary. + */ + g_debug ("Deleting existing unmatched summary.sig file"); + (void)ot_ensure_unlinked_at (self->repo_dir_fd, "summary.sig", NULL); + + return glnx_prefix_error (error, "Unable to rename summary signature file: "); + } + } + else + { + g_debug ("Deleting existing unmatched summary.sig file"); + if (!ot_ensure_unlinked_at (self->repo_dir_fd, "summary.sig", error)) + return glnx_prefix_error (error, "Unable to delete summary signature file: "); + } + return TRUE; } +/** + * ostree_repo_regenerate_summary: + * @self: Repo + * @additional_metadata: (allow-none): A GVariant of type a{sv}, or %NULL + * @cancellable: Cancellable + * @error: Error + * + * An OSTree repository can contain a high level "summary" file that + * describes the available branches and other metadata. + * + * If the timetable for making commits and updating the summary file is fairly + * regular, setting the `ostree.summary.expires` key in @additional_metadata + * will aid clients in working out when to check for updates. + * + * It is regenerated automatically after any ref is + * added, removed, or updated if `core/auto-update-summary` is set. + * + * If the `core/collection-id` key is set in the configuration, it will be + * included as %OSTREE_SUMMARY_COLLECTION_ID in the summary file. Refs that + * have associated collection IDs will be included in the generated summary + * file, listed under the %OSTREE_SUMMARY_COLLECTION_MAP key. Collection IDs + * and refs in %OSTREE_SUMMARY_COLLECTION_MAP are guaranteed to be in + * lexicographic order. + * + * Locking: shared (Prior to 2021.7, this was exclusive) + */ +gboolean +ostree_repo_regenerate_summary (OstreeRepo *self, GVariant *additional_metadata, + GCancellable *cancellable, GError **error) +{ + return regenerate_metadata (self, FALSE, additional_metadata, NULL, cancellable, error); +} + +/** + * ostree_repo_regenerate_metadata: + * @self: Repo + * @additional_metadata: (nullable): A GVariant `a{sv}`, or %NULL + * @options: (nullable): A GVariant `a{sv}` with an extensible set of flags + * @cancellable: Cancellable + * @error: Error + * + * Regenerate the OSTree repository metadata used by clients to describe + * available branches and other metadata. + * + * The repository metadata currently consists of the `summary` file. See + * ostree_repo_regenerate_summary() and %OSTREE_SUMMARY_GVARIANT_FORMAT for + * additional details on its contents. + * + * Additionally, if the `core/collection-id` key is set in the configuration, a + * %OSTREE_REPO_METADATA_REF commit will be created. + * + * The following @options are currently defined: + * + * * `gpg-key-ids` (`as`): Array of GPG key IDs to sign the metadata with. + * * `gpg-homedir` (`s`): GPG home directory. + * * `sign-keys` (`av`): Array of keys to sign the metadata with. The key + * type is specific to the sign engine used. + * * `sign-type` (`s`): Sign engine type to use. If not specified, + * %OSTREE_SIGN_NAME_ED25519 is used. + * + * Locking: shared + * + * Since: 2023.1 + */ +gboolean +ostree_repo_regenerate_metadata (OstreeRepo *self, GVariant *additional_metadata, GVariant *options, + GCancellable *cancellable, GError **error) +{ + return regenerate_metadata (self, TRUE, additional_metadata, options, cancellable, error); +} + /* Regenerate the summary if `core/auto-update-summary` is set. We default to FALSE for * this setting because OSTree supports multiple processes committing to the same repo (but * different refs) concurrently, and in fact gnome-continuous actually does this. In that @@ -6406,25 +6198,21 @@ ostree_repo_regenerate_summary (OstreeRepo *self, * transactions instead of automatically here. `auto-update-summary` only updates * atomically within a transaction. */ gboolean -_ostree_repo_maybe_regenerate_summary (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +_ostree_repo_maybe_regenerate_summary (OstreeRepo *self, GCancellable *cancellable, GError **error) { gboolean auto_update_summary; - if (!ot_keyfile_get_boolean_with_default (self->config, "core", - "auto-update-summary", FALSE, + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "auto-update-summary", FALSE, &auto_update_summary, error)) return FALSE; /* Deprecated alias for `auto-update-summary`. */ gboolean commit_update_summary; - if (!ot_keyfile_get_boolean_with_default (self->config, "core", - "commit-update-summary", FALSE, + if (!ot_keyfile_get_boolean_with_default (self->config, "core", "commit-update-summary", FALSE, &commit_update_summary, error)) return FALSE; - if ((auto_update_summary || commit_update_summary) && - !ostree_repo_regenerate_summary (self, NULL, cancellable, error)) + if ((auto_update_summary || commit_update_summary) + && !ostree_repo_regenerate_summary (self, NULL, cancellable, error)) return FALSE; return TRUE; @@ -6437,20 +6225,16 @@ _ostree_repo_has_staging_prefix (const char *filename) } gboolean -_ostree_repo_try_lock_tmpdir (int tmpdir_dfd, - const char *tmpdir_name, - GLnxLockFile *file_lock_out, - gboolean *out_did_lock, - GError **error) +_ostree_repo_try_lock_tmpdir (int tmpdir_dfd, const char *tmpdir_name, GLnxLockFile *file_lock_out, + gboolean *out_did_lock, GError **error) { g_autofree char *lock_name = g_strconcat (tmpdir_name, "-lock", NULL); gboolean did_lock = FALSE; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; /* We put the lock outside the dir, so we can hold the lock * until the directory is fully removed */ - if (!glnx_make_lock_file (tmpdir_dfd, lock_name, LOCK_EX | LOCK_NB, - file_lock_out, &local_error)) + if (!glnx_make_lock_file (tmpdir_dfd, lock_name, LOCK_EX | LOCK_NB, file_lock_out, &local_error)) { /* we need to handle EACCES too in the case of POSIX locks; see F_SETLK in fcntl(2) */ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) @@ -6485,28 +6269,28 @@ _ostree_repo_try_lock_tmpdir (int tmpdir_dfd, /* This allocates and locks a subdir of the repo tmp dir, using an existing * one with the same prefix if it is not in use already. */ gboolean -_ostree_repo_allocate_tmpdir (int tmpdir_dfd, - const char *tmpdir_prefix, - GLnxTmpDir *tmpdir_out, - GLnxLockFile *file_lock_out, - gboolean *reusing_dir_out, - GCancellable *cancellable, - GError **error) +_ostree_repo_allocate_tmpdir (int tmpdir_dfd, const char *tmpdir_prefix, GLnxTmpDir *tmpdir_out, + GLnxLockFile *file_lock_out, gboolean *reusing_dir_out, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (_ostree_repo_has_staging_prefix (tmpdir_prefix), FALSE); /* Look for existing tmpdir (with same prefix) to reuse */ - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (tmpdir_dfd, ".", FALSE, &dfd_iter, error)) return FALSE; gboolean reusing_dir = FALSE; gboolean did_lock = FALSE; - g_auto(GLnxTmpDir) ret_tmpdir = { 0, }; + g_auto (GLnxTmpDir) ret_tmpdir = { + 0, + }; while (!ret_tmpdir.initialized) { struct dirent *dent; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error)) return FALSE; @@ -6518,16 +6302,14 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd, continue; /* Quickly skip non-dirs, if unknown we ignore ENOTDIR when opening instead */ - if (dent->d_type != DT_UNKNOWN && - dent->d_type != DT_DIR) + if (dent->d_type != DT_UNKNOWN && dent->d_type != DT_DIR) continue; glnx_autofd int target_dfd = -1; - if (!glnx_opendirat (dfd_iter.fd, dent->d_name, FALSE, - &target_dfd, &local_error)) + if (!glnx_opendirat (dfd_iter.fd, dent->d_name, FALSE, &target_dfd, &local_error)) { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY) || - g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY) + || g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) continue; else { @@ -6538,9 +6320,7 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd, /* We put the lock outside the dir, so we can hold the lock * until the directory is fully removed */ - if (!_ostree_repo_try_lock_tmpdir (tmpdir_dfd, dent->d_name, - file_lock_out, &did_lock, - error)) + if (!_ostree_repo_try_lock_tmpdir (tmpdir_dfd, dent->d_name, file_lock_out, &did_lock, error)) return FALSE; if (!did_lock) continue; @@ -6554,7 +6334,7 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd, g_debug ("Reusing tmpdir %s", dent->d_name); reusing_dir = TRUE; ret_tmpdir.src_dfd = tmpdir_dfd; - ret_tmpdir.fd = glnx_steal_fd (&target_dfd); + ret_tmpdir.fd = g_steal_fd (&target_dfd); ret_tmpdir.path = g_strdup (dent->d_name); ret_tmpdir.initialized = TRUE; } @@ -6562,17 +6342,18 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd, const char *tmpdir_name_template = glnx_strjoina (tmpdir_prefix, "XXXXXX"); while (!ret_tmpdir.initialized) { - g_auto(GLnxTmpDir) new_tmpdir = { 0, }; + g_auto (GLnxTmpDir) new_tmpdir = { + 0, + }; /* No existing tmpdir found, create a new */ - if (!glnx_mkdtempat (tmpdir_dfd, tmpdir_name_template, DEFAULT_DIRECTORY_MODE, - &new_tmpdir, error)) + if (!glnx_mkdtempat (tmpdir_dfd, tmpdir_name_template, DEFAULT_DIRECTORY_MODE, &new_tmpdir, + error)) return FALSE; /* Note, at this point we can race with another process that picks up this * new directory. If that happens we need to retry, making a new directory. */ - if (!_ostree_repo_try_lock_tmpdir (new_tmpdir.src_dfd, new_tmpdir.path, - file_lock_out, &did_lock, - error)) + if (!_ostree_repo_try_lock_tmpdir (new_tmpdir.src_dfd, new_tmpdir.path, file_lock_out, + &did_lock, error)) return FALSE; if (!did_lock) { @@ -6599,17 +6380,16 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd, /* See ostree-repo-private.h for more information about this */ void -_ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state, - OstreeRepo *repo) +_ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state, OstreeRepo *repo) { state->repo = g_object_ref (repo); GMutex *lock = &repo->cache_lock; g_mutex_lock (lock); repo->dirmeta_cache_refcount++; if (repo->dirmeta_cache == NULL) - repo->dirmeta_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); + repo->dirmeta_cache + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); g_mutex_unlock (lock); - } /* See ostree-repo-private.h for more information about this */ @@ -6657,9 +6437,7 @@ ostree_repo_get_collection_id (OstreeRepo *self) * Since: 2018.6 */ gboolean -ostree_repo_set_collection_id (OstreeRepo *self, - const gchar *collection_id, - GError **error) +ostree_repo_set_collection_id (OstreeRepo *self, const gchar *collection_id, GError **error) { if (collection_id != NULL && !ostree_validate_collection_id (collection_id, error)) return FALSE; @@ -6690,12 +6468,12 @@ ostree_repo_set_collection_id (OstreeRepo *self, * %NULL-terminated array of strings. * Since: 2018.9 */ -const gchar * const * +const gchar *const * ostree_repo_get_default_repo_finders (OstreeRepo *self) { g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); - return (const gchar * const *)self->repo_finders; + return (const gchar *const *)self->repo_finders; } /** @@ -6709,14 +6487,13 @@ ostree_repo_get_default_repo_finders (OstreeRepo *self) * Since: 2019.2 */ const gchar * -ostree_repo_get_bootloader (OstreeRepo *self) +ostree_repo_get_bootloader (OstreeRepo *self) { g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); return CFG_SYSROOT_BOOTLOADER_OPTS_STR[self->bootloader]; } - /** * _ostree_repo_verify_bindings: * @collection_id: (nullable): Locally specified collection ID for the remote @@ -6744,17 +6521,12 @@ ostree_repo_get_bootloader (OstreeRepo *self) * Since: 2017.14 */ gboolean -_ostree_repo_verify_bindings (const char *collection_id, - const char *ref_name, - GVariant *commit, - GError **error) +_ostree_repo_verify_bindings (const char *collection_id, const char *ref_name, GVariant *commit, + GError **error) { - g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0); + g_autoptr (GVariant) metadata = g_variant_get_child_value (commit, 0); g_autofree const char **refs = NULL; - if (!g_variant_lookup (metadata, - OSTREE_COMMIT_META_KEY_REF_BINDING, - "^a&s", - &refs)) + if (!g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_REF_BINDING, "^a&s", &refs)) { /* Early return here - if the remote collection ID is NULL, then * we certainly will not verify the collection binding in the @@ -6763,16 +6535,15 @@ _ostree_repo_verify_bindings (const char *collection_id, if (collection_id == NULL) return TRUE; - return glnx_throw (error, - "Expected commit metadata to have ref " - "binding information, found none"); + return glnx_throw (error, "Expected commit metadata to have ref " + "binding information, found none"); } if (ref_name != NULL) { - if (!g_strv_contains ((const char *const *) refs, ref_name)) + if (!g_strv_contains ((const char *const *)refs, ref_name)) { - g_autoptr(GString) refs_dump = g_string_new (NULL); + g_autoptr (GString) refs_dump = g_string_new (NULL); const char *refs_str; if (refs != NULL && (*refs) != NULL) @@ -6793,7 +6564,8 @@ _ostree_repo_verify_bindings (const char *collection_id, refs_str = "no refs"; } - return glnx_throw (error, "Commit has no requested ref ‘%s’ " + return glnx_throw (error, + "Commit has no requested ref ‘%s’ " "in ref binding metadata (%s)", ref_name, refs_str); } @@ -6802,13 +6574,10 @@ _ostree_repo_verify_bindings (const char *collection_id, if (collection_id != NULL) { const char *collection_id_binding; - if (!g_variant_lookup (metadata, - OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, - "&s", + if (!g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "&s", &collection_id_binding)) - return glnx_throw (error, - "Expected commit metadata to have collection ID " - "binding information, found none"); + return glnx_throw (error, "Expected commit metadata to have collection ID " + "binding information, found none"); if (!g_str_equal (collection_id_binding, collection_id)) return glnx_throw (error, "Commit has collection ID ‘%s’ in collection binding " diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 9857117..73e62f5 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -23,143 +23,111 @@ #include -#include "ostree-core.h" -#include "ostree-types.h" #include "ostree-async-progress.h" +#include "ostree-core.h" +#include "ostree-gpg-verify-result.h" #include "ostree-ref.h" #include "ostree-repo-finder.h" #include "ostree-sepolicy.h" -#include "ostree-gpg-verify-result.h" #include "ostree-sign.h" +#include "ostree-types.h" G_BEGIN_DECLS -#define OSTREE_TYPE_REPO ostree_repo_get_type() -#define OSTREE_REPO(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_REPO, OstreeRepo)) -#define OSTREE_IS_REPO(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_REPO)) +#define OSTREE_TYPE_REPO ostree_repo_get_type () +#define OSTREE_REPO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_REPO, OstreeRepo)) +#define OSTREE_IS_REPO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_REPO)) _OSTREE_PUBLIC -gboolean ostree_repo_mode_from_string (const char *mode, - OstreeRepoMode *out_mode, - GError **error); +gboolean ostree_repo_mode_from_string (const char *mode, OstreeRepoMode *out_mode, GError **error); _OSTREE_PUBLIC GType ostree_repo_get_type (void); _OSTREE_PUBLIC -OstreeRepo* ostree_repo_new (GFile *path); +OstreeRepo *ostree_repo_new (GFile *path); _OSTREE_PUBLIC -OstreeRepo* ostree_repo_new_for_sysroot_path (GFile *repo_path, - GFile *sysroot_path); +OstreeRepo *ostree_repo_new_for_sysroot_path (GFile *repo_path, GFile *sysroot_path); _OSTREE_PUBLIC -OstreeRepo* ostree_repo_new_default (void); +OstreeRepo *ostree_repo_new_default (void); _OSTREE_PUBLIC -gboolean ostree_repo_open (OstreeRepo *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_open (OstreeRepo *self, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeRepo* -ostree_repo_open_at (int dfd, - const char *path, - GCancellable *cancellable, - GError **error); +OstreeRepo *ostree_repo_open_at (int dfd, const char *path, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -void ostree_repo_set_disable_fsync (OstreeRepo *self, - gboolean disable_fsync); +void ostree_repo_set_disable_fsync (OstreeRepo *self, gboolean disable_fsync); _OSTREE_PUBLIC -gboolean ostree_repo_set_cache_dir (OstreeRepo *self, - int dfd, - const char *path, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_set_cache_dir (OstreeRepo *self, int dfd, const char *path, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_get_disable_fsync (OstreeRepo *self); +gboolean ostree_repo_get_disable_fsync (OstreeRepo *self); _OSTREE_PUBLIC -gboolean ostree_repo_is_system (OstreeRepo *repo); +gboolean ostree_repo_is_system (OstreeRepo *repo); _OSTREE_PUBLIC -gboolean ostree_repo_is_writable (OstreeRepo *self, - GError **error); +gboolean ostree_repo_is_writable (OstreeRepo *self, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_create (OstreeRepo *self, - OstreeRepoMode mode, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_create (OstreeRepo *self, OstreeRepoMode mode, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -OstreeRepo * ostree_repo_create_at (int dfd, - const char *path, - OstreeRepoMode mode, - GVariant *options, - GCancellable *cancellable, - GError **error); +OstreeRepo *ostree_repo_create_at (int dfd, const char *path, OstreeRepoMode mode, + GVariant *options, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -const gchar * ostree_repo_get_collection_id (OstreeRepo *self); +const gchar *ostree_repo_get_collection_id (OstreeRepo *self); _OSTREE_PUBLIC -gboolean ostree_repo_set_collection_id (OstreeRepo *self, - const gchar *collection_id, - GError **error); +gboolean ostree_repo_set_collection_id (OstreeRepo *self, const gchar *collection_id, + GError **error); _OSTREE_PUBLIC -const gchar * const * ostree_repo_get_default_repo_finders (OstreeRepo *self); +const gchar *const *ostree_repo_get_default_repo_finders (OstreeRepo *self); _OSTREE_PUBLIC -const gchar * ostree_repo_get_bootloader (OstreeRepo *self); +const gchar *ostree_repo_get_bootloader (OstreeRepo *self); _OSTREE_PUBLIC -GFile * ostree_repo_get_path (OstreeRepo *self); +GFile *ostree_repo_get_path (OstreeRepo *self); _OSTREE_PUBLIC -int ostree_repo_get_dfd (OstreeRepo *self); +int ostree_repo_get_dfd (OstreeRepo *self); _OSTREE_PUBLIC -guint ostree_repo_hash (OstreeRepo *self); +guint ostree_repo_hash (OstreeRepo *self); _OSTREE_PUBLIC -gboolean ostree_repo_equal (OstreeRepo *a, - OstreeRepo *b); +gboolean ostree_repo_equal (OstreeRepo *a, OstreeRepo *b); _OSTREE_PUBLIC -OstreeRepoMode ostree_repo_get_mode (OstreeRepo *self); +OstreeRepoMode ostree_repo_get_mode (OstreeRepo *self); _OSTREE_PUBLIC -gboolean ostree_repo_get_min_free_space_bytes (OstreeRepo *self, - guint64 *out_reserved_bytes, - GError **error); +gboolean ostree_repo_get_min_free_space_bytes (OstreeRepo *self, guint64 *out_reserved_bytes, + GError **error); _OSTREE_PUBLIC -GKeyFile * ostree_repo_get_config (OstreeRepo *self); +GKeyFile *ostree_repo_get_config (OstreeRepo *self); _OSTREE_PUBLIC -GKeyFile * ostree_repo_copy_config (OstreeRepo *self); +GKeyFile *ostree_repo_copy_config (OstreeRepo *self); _OSTREE_PUBLIC -gboolean ostree_repo_reload_config (OstreeRepo *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_reload_config (OstreeRepo *self, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_add (OstreeRepo *self, - const char *name, - const char *url, - GVariant *options, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_add (OstreeRepo *self, const char *name, const char *url, + GVariant *options, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_delete (OstreeRepo *self, - const char *name, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_delete (OstreeRepo *self, const char *name, GCancellable *cancellable, + GError **error); /** * OstreeRepoRemoteChange: @@ -167,10 +135,12 @@ gboolean ostree_repo_remote_delete (OstreeRepo *self, * @OSTREE_REPO_REMOTE_CHANGE_ADD: Add a remote * @OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS: Like above, but do nothing if the remote exists * @OSTREE_REPO_REMOTE_CHANGE_DELETE: Delete a remote - * @OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS: Delete a remote, do nothing if the remote does not exist + * @OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS: Delete a remote, do nothing if the remote does not + * exist * @OSTREE_REPO_REMOTE_CHANGE_REPLACE: Add or replace a remote (Since: 2019.2) */ -typedef enum { +typedef enum +{ OSTREE_REPO_REMOTE_CHANGE_ADD, OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS, OSTREE_REPO_REMOTE_CHANGE_DELETE, @@ -179,73 +149,49 @@ typedef enum { } OstreeRepoRemoteChange; _OSTREE_PUBLIC -gboolean ostree_repo_remote_change (OstreeRepo *self, - GFile *sysroot, - OstreeRepoRemoteChange changeop, - const char *name, - const char *url, - GVariant *options, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_change (OstreeRepo *self, GFile *sysroot, + OstreeRepoRemoteChange changeop, const char *name, + const char *url, GVariant *options, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -char ** ostree_repo_remote_list (OstreeRepo *self, - guint *out_n_remotes); +char **ostree_repo_remote_list (OstreeRepo *self, guint *out_n_remotes); _OSTREE_PUBLIC -gboolean ostree_repo_remote_get_url (OstreeRepo *self, - const char *name, - char **out_url, - GError **error); +gboolean ostree_repo_remote_get_url (OstreeRepo *self, const char *name, char **out_url, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_get_remote_option (OstreeRepo *self, - const char *remote_name, - const char *option_name, - const char *default_value, - char **out_value, - GError **error); +gboolean ostree_repo_get_remote_option (OstreeRepo *self, const char *remote_name, + const char *option_name, const char *default_value, + char **out_value, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_get_remote_list_option (OstreeRepo *self, - const char *remote_name, - const char *option_name, - char ***out_value, - GError **error); +gboolean ostree_repo_get_remote_list_option (OstreeRepo *self, const char *remote_name, + const char *option_name, char ***out_value, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_get_remote_boolean_option (OstreeRepo *self, - const char *remote_name, - const char *option_name, - gboolean default_value, - gboolean *out_value, - GError **error); - +gboolean ostree_repo_get_remote_boolean_option (OstreeRepo *self, const char *remote_name, + const char *option_name, gboolean default_value, + gboolean *out_value, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_fetch_summary (OstreeRepo *self, - const char *name, - GBytes **out_summary, - GBytes **out_signatures, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_fetch_summary (OstreeRepo *self, const char *name, GBytes **out_summary, + GBytes **out_signatures, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, - const char *name, - GVariant *options, - GBytes **out_summary, - GBytes **out_signatures, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, const char *name, + GVariant *options, GBytes **out_summary, + GBytes **out_signatures, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeRepo * ostree_repo_get_parent (OstreeRepo *self); +OstreeRepo *ostree_repo_get_parent (OstreeRepo *self); _OSTREE_PUBLIC -gboolean ostree_repo_write_config (OstreeRepo *self, - GKeyFile *new_config, - GError **error); +gboolean ostree_repo_write_config (OstreeRepo *self, GKeyFile *new_config, GError **error); /** * OstreeRepoCommitState: @@ -261,7 +207,8 @@ gboolean ostree_repo_write_config (OstreeRepo *self, * * Since: 2015.7 */ -typedef enum { +typedef enum +{ OSTREE_REPO_COMMIT_STATE_NORMAL = 0, OSTREE_REPO_COMMIT_STATE_PARTIAL = (1 << 0), OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL = (1 << 1), @@ -289,7 +236,8 @@ typedef enum { */ typedef struct _OstreeRepoTransactionStats OstreeRepoTransactionStats; -struct _OstreeRepoTransactionStats { +struct _OstreeRepoTransactionStats +{ guint metadata_objects_total; guint metadata_objects_written; guint content_objects_total; @@ -297,7 +245,7 @@ struct _OstreeRepoTransactionStats { guint64 content_bytes_written; guint devino_cache_hits; - guint padding1; + guint padding1; guint64 padding2; guint64 padding3; guint64 padding4; @@ -307,232 +255,154 @@ _OSTREE_PUBLIC GType ostree_repo_transaction_stats_get_type (void); _OSTREE_PUBLIC -gboolean ostree_repo_scan_hardlinks (OstreeRepo *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_scan_hardlinks (OstreeRepo *self, GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_prepare_transaction (OstreeRepo *self, gboolean *out_transaction_resume, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_commit_transaction (OstreeRepo *self, OstreeRepoTransactionStats *out_stats, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_abort_transaction (OstreeRepo *self, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_prepare_transaction (OstreeRepo *self, - gboolean *out_transaction_resume, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_mark_commit_partial (OstreeRepo *self, const char *checksum, + gboolean is_partial, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_commit_transaction (OstreeRepo *self, - OstreeRepoTransactionStats *out_stats, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_mark_commit_partial_reason (OstreeRepo *self, const char *checksum, + gboolean is_partial, + OstreeRepoCommitState in_state, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_abort_transaction (OstreeRepo *self, - GCancellable *cancellable, - GError **error); +void ostree_repo_transaction_set_refspec (OstreeRepo *self, const char *refspec, + const char *checksum); _OSTREE_PUBLIC -gboolean ostree_repo_mark_commit_partial (OstreeRepo *self, - const char *checksum, - gboolean is_partial, - GError **error); +void ostree_repo_transaction_set_ref (OstreeRepo *self, const char *remote, const char *ref, + const char *checksum); _OSTREE_PUBLIC -gboolean ostree_repo_mark_commit_partial_reason (OstreeRepo *self, - const char *checksum, - gboolean is_partial, - OstreeRepoCommitState in_state, - GError **error); +void ostree_repo_transaction_set_collection_ref (OstreeRepo *self, const OstreeCollectionRef *ref, + const char *checksum); _OSTREE_PUBLIC -void ostree_repo_transaction_set_refspec (OstreeRepo *self, - const char *refspec, - const char *checksum); +gboolean ostree_repo_set_ref_immediate (OstreeRepo *self, const char *remote, const char *ref, + const char *checksum, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -void ostree_repo_transaction_set_ref (OstreeRepo *self, - const char *remote, - const char *ref, - const char *checksum); +gboolean ostree_repo_set_alias_ref_immediate (OstreeRepo *self, const char *remote, const char *ref, + const char *target, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -void ostree_repo_transaction_set_collection_ref (OstreeRepo *self, - const OstreeCollectionRef *ref, - const char *checksum); +gboolean ostree_repo_set_collection_ref_immediate (OstreeRepo *self, const OstreeCollectionRef *ref, + const char *checksum, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_set_ref_immediate (OstreeRepo *self, - const char *remote, - const char *ref, - const char *checksum, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_has_object (OstreeRepo *self, OstreeObjectType objtype, const char *checksum, + gboolean *out_have_object, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_set_alias_ref_immediate (OstreeRepo *self, - const char *remote, - const char *ref, - const char *target, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_metadata (OstreeRepo *self, OstreeObjectType objtype, + const char *expected_checksum, GVariant *object, + guchar **out_csum, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_set_collection_ref_immediate (OstreeRepo *self, - const OstreeCollectionRef *ref, - const char *checksum, - GCancellable *cancellable, - GError **error); +void ostree_repo_write_metadata_async (OstreeRepo *self, OstreeObjectType objtype, + const char *expected_checksum, GVariant *object, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data); _OSTREE_PUBLIC -gboolean ostree_repo_has_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *checksum, - gboolean *out_have_object, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_metadata_finish (OstreeRepo *self, GAsyncResult *result, + guchar **out_csum, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_metadata (OstreeRepo *self, - OstreeObjectType objtype, - const char *expected_checksum, - GVariant *object, - guchar **out_csum, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_content (OstreeRepo *self, const char *expected_checksum, + GInputStream *object_input, guint64 length, guchar **out_csum, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -void ostree_repo_write_metadata_async (OstreeRepo *self, - OstreeObjectType objtype, - const char *expected_checksum, - GVariant *object, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +char *ostree_repo_write_regfile_inline (OstreeRepo *self, const char *expected_checksum, + guint32 uid, guint32 gid, guint32 mode, GVariant *xattrs, + const guint8 *buf, gsize len, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_metadata_finish (OstreeRepo *self, - GAsyncResult *result, - guchar **out_csum, - GError **error); +OstreeContentWriter *ostree_repo_write_regfile (OstreeRepo *self, const char *expected_checksum, + guint32 uid, guint32 gid, guint32 mode, + guint64 content_len, GVariant *xattrs, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_content (OstreeRepo *self, - const char *expected_checksum, - GInputStream *object_input, - guint64 length, - guchar **out_csum, - GCancellable *cancellable, - GError **error); +char *ostree_repo_write_symlink (OstreeRepo *self, const char *expected_checksum, guint32 uid, + guint32 gid, GVariant *xattrs, const char *symlink_target, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -char * ostree_repo_write_regfile_inline (OstreeRepo *self, - const char *expected_checksum, - guint32 uid, - guint32 gid, - guint32 mode, - GVariant *xattrs, - const guint8* buf, - gsize len, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_metadata_trusted (OstreeRepo *self, OstreeObjectType objtype, + const char *checksum, GVariant *variant, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeContentWriter * ostree_repo_write_regfile (OstreeRepo *self, - const char *expected_checksum, - guint32 uid, - guint32 gid, - guint32 mode, - guint64 content_len, - GVariant *xattrs, - GError **error); - -_OSTREE_PUBLIC -char * ostree_repo_write_symlink (OstreeRepo *self, - const char *expected_checksum, - guint32 uid, - guint32 gid, - GVariant *xattrs, - const char *symlink_target, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_repo_write_metadata_trusted (OstreeRepo *self, - OstreeObjectType objtype, - const char *checksum, - GVariant *variant, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_repo_write_metadata_stream_trusted (OstreeRepo *self, - OstreeObjectType objtype, - const char *checksum, - GInputStream *object_input, - guint64 length, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_repo_write_content_trusted (OstreeRepo *self, - const char *checksum, - GInputStream *object_input, - guint64 length, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -void ostree_repo_write_content_async (OstreeRepo *self, - const char *expected_checksum, - GInputStream *object, - guint64 length, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -_OSTREE_PUBLIC -gboolean ostree_repo_write_content_finish (OstreeRepo *self, - GAsyncResult *result, - guchar **out_csum, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_repo_resolve_rev (OstreeRepo *self, - const char *refspec, - gboolean allow_noent, - char **out_rev, - GError **error); +gboolean ostree_repo_write_metadata_stream_trusted (OstreeRepo *self, OstreeObjectType objtype, + const char *checksum, + GInputStream *object_input, guint64 length, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_write_content_trusted (OstreeRepo *self, const char *checksum, + GInputStream *object_input, guint64 length, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +void ostree_repo_write_content_async (OstreeRepo *self, const char *expected_checksum, + GInputStream *object, guint64 length, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +_OSTREE_PUBLIC +gboolean ostree_repo_write_content_finish (OstreeRepo *self, GAsyncResult *result, + guchar **out_csum, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_resolve_rev (OstreeRepo *self, const char *refspec, gboolean allow_noent, + char **out_rev, GError **error); /** * OstreeRepoResolveRevExtFlags: * @OSTREE_REPO_RESOLVE_REV_EXT_NONE: No flags. * @OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY: Exclude remote and mirrored refs. Since: 2019.2 */ -typedef enum { +typedef enum +{ OSTREE_REPO_RESOLVE_REV_EXT_NONE = 0, OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY = (1 << 0), } OstreeRepoResolveRevExtFlags; _OSTREE_PUBLIC -gboolean ostree_repo_resolve_rev_ext (OstreeRepo *self, - const char *refspec, - gboolean allow_noent, - OstreeRepoResolveRevExtFlags flags, - char **out_rev, - GError **error); +gboolean ostree_repo_resolve_rev_ext (OstreeRepo *self, const char *refspec, gboolean allow_noent, + OstreeRepoResolveRevExtFlags flags, char **out_rev, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_resolve_collection_ref (OstreeRepo *self, - const OstreeCollectionRef *ref, - gboolean allow_noent, - OstreeRepoResolveRevExtFlags flags, - char **out_rev, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_resolve_collection_ref (OstreeRepo *self, const OstreeCollectionRef *ref, + gboolean allow_noent, + OstreeRepoResolveRevExtFlags flags, char **out_rev, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_list_refs (OstreeRepo *self, - const char *refspec_prefix, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_list_refs (OstreeRepo *self, const char *refspec_prefix, + GHashTable **out_all_refs, GCancellable *cancellable, + GError **error); /** * OstreeRepoListRefsExtFlags: @@ -541,7 +411,8 @@ gboolean ostree_repo_list_refs (OstreeRepo *self, * @OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES: Exclude remote refs. Since: 2017.11 * @OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS: Exclude mirrored refs. Since: 2019.2 */ -typedef enum { +typedef enum +{ OSTREE_REPO_LIST_REFS_EXT_NONE = 0, OSTREE_REPO_LIST_REFS_EXT_ALIASES = (1 << 0), OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES = (1 << 1), @@ -549,110 +420,74 @@ typedef enum { } OstreeRepoListRefsExtFlags; _OSTREE_PUBLIC -gboolean ostree_repo_list_refs_ext (OstreeRepo *self, - const char *refspec_prefix, - GHashTable **out_all_refs, - OstreeRepoListRefsExtFlags flags, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_list_refs_ext (OstreeRepo *self, const char *refspec_prefix, + GHashTable **out_all_refs, OstreeRepoListRefsExtFlags flags, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_list_refs (OstreeRepo *self, - const char *remote_name, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_list_refs (OstreeRepo *self, const char *remote_name, + GHashTable **out_all_refs, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_list_collection_refs (OstreeRepo *self, - const char *remote_name, - GHashTable **out_all_refs, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_list_collection_refs (OstreeRepo *self, const char *remote_name, + GHashTable **out_all_refs, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_load_variant (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GVariant **out_variant, - GError **error); +gboolean ostree_repo_load_variant (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GVariant **out_variant, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_load_variant_if_exists (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GVariant **out_variant, - GError **error); +gboolean ostree_repo_load_variant_if_exists (OstreeRepo *self, OstreeObjectType objtype, + const char *sha256, GVariant **out_variant, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_load_commit (OstreeRepo *self, - const char *checksum, - GVariant **out_commit, - OstreeRepoCommitState *out_state, - GError **error); +gboolean ostree_repo_load_commit (OstreeRepo *self, const char *checksum, GVariant **out_commit, + OstreeRepoCommitState *out_state, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_load_file (OstreeRepo *self, - const char *checksum, - GInputStream **out_input, - GFileInfo **out_file_info, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_load_file (OstreeRepo *self, const char *checksum, GInputStream **out_input, + GFileInfo **out_file_info, GVariant **out_xattrs, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_load_object_stream (OstreeRepo *self, - OstreeObjectType objtype, - const char *checksum, - GInputStream **out_input, - guint64 *out_size, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_load_object_stream (OstreeRepo *self, OstreeObjectType objtype, + const char *checksum, GInputStream **out_input, + guint64 *out_size, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_query_object_storage_size (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - guint64 *out_size, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_query_object_storage_size (OstreeRepo *self, OstreeObjectType objtype, + const char *sha256, guint64 *out_size, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_import_object_from (OstreeRepo *self, - OstreeRepo *source, - OstreeObjectType objtype, - const char *checksum, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_import_object_from (OstreeRepo *self, OstreeRepo *source, + OstreeObjectType objtype, const char *checksum, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_import_object_from_with_trust (OstreeRepo *self, - OstreeRepo *source, - OstreeObjectType objtype, - const char *checksum, - gboolean trusted, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_import_object_from_with_trust (OstreeRepo *self, OstreeRepo *source, + OstreeObjectType objtype, const char *checksum, + gboolean trusted, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_delete_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_delete_object (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_fsck_object (OstreeRepo *self, - OstreeObjectType objtype, - const char *sha256, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_fsck_object (OstreeRepo *self, OstreeObjectType objtype, const char *sha256, + GCancellable *cancellable, GError **error); -/** +/** * OstreeRepoCommitFilterResult: * @OSTREE_REPO_COMMIT_FILTER_ALLOW: Do commit this object * @OSTREE_REPO_COMMIT_FILTER_SKIP: Ignore this object */ -typedef enum { +typedef enum +{ OSTREE_REPO_COMMIT_FILTER_ALLOW, OSTREE_REPO_COMMIT_FILTER_SKIP } OstreeRepoCommitFilterResult; @@ -666,10 +501,9 @@ typedef enum { * * Returns: #OstreeRepoCommitFilterResult saying whether or not to commit this file */ -typedef OstreeRepoCommitFilterResult (*OstreeRepoCommitFilter) (OstreeRepo *repo, - const char *path, - GFileInfo *file_info, - gpointer user_data); +typedef OstreeRepoCommitFilterResult (*OstreeRepoCommitFilter) (OstreeRepo *repo, const char *path, + GFileInfo *file_info, + gpointer user_data); /** * OstreeRepoCommitModifierFlags: @@ -677,15 +511,22 @@ typedef OstreeRepoCommitFilterResult (*OstreeRepoCommitFilter) (OstreeRepo *r * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS: Do not process extended attributes * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES: Generate size information. * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS: Canonicalize permissions. - * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_ERROR_ON_UNLABELED: Emit an error if configured SELinux policy does not provide a label - * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME: Delete added files/directories after commit; Since: 2017.13 - * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL: If a devino cache hit is found, skip modifier filters (non-directories only); Since: 2017.14 + * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_ERROR_ON_UNLABELED: Emit an error if configured SELinux + * policy does not provide a label + * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME: Delete added files/directories after commit; Since: + * 2017.13 + * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL: If a devino cache hit is found, skip + * modifier filters (non-directories only); Since: 2017.14 + * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SELINUX_LABEL_V1: For SELinux and other systems, label + * /usr/etc as if it was /etc. * - * Flags modifying commit behavior. In bare-user-only mode, @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS - * and @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS are automatically enabled. + * Flags modifying commit behavior. In bare-user-only mode, + * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS and + * @OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS are automatically enabled. * */ -typedef enum { +typedef enum +{ OSTREE_REPO_COMMIT_MODIFIER_FLAGS_NONE = 0, OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS = (1 << 0), OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES = (1 << 1), @@ -693,6 +534,7 @@ typedef enum { OSTREE_REPO_COMMIT_MODIFIER_FLAGS_ERROR_ON_UNLABELED = (1 << 3), OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME = (1 << 4), OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL = (1 << 5), + OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SELINUX_LABEL_V1 = (1 << 6), } OstreeRepoCommitModifierFlags; /** @@ -703,39 +545,36 @@ typedef enum { typedef struct OstreeRepoCommitModifier OstreeRepoCommitModifier; _OSTREE_PUBLIC -OstreeRepoCommitModifier *ostree_repo_commit_modifier_new (OstreeRepoCommitModifierFlags flags, - OstreeRepoCommitFilter commit_filter, - gpointer user_data, - GDestroyNotify destroy_notify); +OstreeRepoCommitModifier *ostree_repo_commit_modifier_new (OstreeRepoCommitModifierFlags flags, + OstreeRepoCommitFilter commit_filter, + gpointer user_data, + GDestroyNotify destroy_notify); _OSTREE_PUBLIC GType ostree_repo_commit_modifier_get_type (void); -typedef GVariant *(*OstreeRepoCommitModifierXattrCallback) (OstreeRepo *repo, - const char *path, - GFileInfo *file_info, - gpointer user_data); +typedef GVariant *(*OstreeRepoCommitModifierXattrCallback) (OstreeRepo *repo, const char *path, + GFileInfo *file_info, + gpointer user_data); _OSTREE_PUBLIC -void ostree_repo_commit_modifier_set_xattr_callback (OstreeRepoCommitModifier *modifier, - OstreeRepoCommitModifierXattrCallback callback, - GDestroyNotify destroy, - gpointer user_data); +void ostree_repo_commit_modifier_set_xattr_callback (OstreeRepoCommitModifier *modifier, + OstreeRepoCommitModifierXattrCallback callback, + GDestroyNotify destroy, gpointer user_data); _OSTREE_PUBLIC -void ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier *modifier, - OstreeSePolicy *sepolicy); +void ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier *modifier, + OstreeSePolicy *sepolicy); _OSTREE_PUBLIC -gboolean ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier *modifier, - OstreeRepo *repo, - const char *rev, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier *modifier, + OstreeRepo *repo, const char *rev, + GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -void ostree_repo_commit_modifier_set_devino_cache (OstreeRepoCommitModifier *modifier, - OstreeRepoDevInoCache *cache); +void ostree_repo_commit_modifier_set_devino_cache (OstreeRepoCommitModifier *modifier, + OstreeRepoDevInoCache *cache); _OSTREE_PUBLIC OstreeRepoCommitModifier *ostree_repo_commit_modifier_ref (OstreeRepoCommitModifier *modifier); @@ -743,41 +582,30 @@ _OSTREE_PUBLIC void ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier); _OSTREE_PUBLIC -gboolean ostree_repo_write_directory_to_mtree (OstreeRepo *self, - GFile *dir, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_directory_to_mtree (OstreeRepo *self, GFile *dir, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_dfd_to_mtree (OstreeRepo *self, - int dfd, - const char *path, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GCancellable *cancellable, - GError **error); - +gboolean ostree_repo_write_dfd_to_mtree (OstreeRepo *self, int dfd, const char *path, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_archive_to_mtree (OstreeRepo *self, - GFile *archive, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - gboolean autocreate_parents, - GCancellable *cancellable, - GError **error); - +gboolean ostree_repo_write_archive_to_mtree (OstreeRepo *self, GFile *archive, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + gboolean autocreate_parents, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo *self, - int fd, - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - gboolean autocreate_parents, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo *self, int fd, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + gboolean autocreate_parents, + GCancellable *cancellable, GError **error); /** * OstreeRepoImportArchiveTranslatePathname: @@ -799,10 +627,10 @@ gboolean ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo * * Since: 2017.11 */ -typedef char *(*OstreeRepoImportArchiveTranslatePathname) (OstreeRepo *repo, +typedef char *(*OstreeRepoImportArchiveTranslatePathname) (OstreeRepo *repo, const struct stat *stbuf, - const char *src_path, - gpointer user_data); + const char *src_path, + gpointer user_data); /** * OstreeRepoImportArchiveOptions: (skip) @@ -811,7 +639,8 @@ typedef char *(*OstreeRepoImportArchiveTranslatePathname) (OstreeRepo *repo, * you have entirely zeroed the structure, then set just the desired * options. This is used by ostree_repo_import_archive_to_mtree(). */ -typedef struct { +typedef struct +{ guint ignore_unsupported_content : 1; guint autocreate_parents : 1; guint use_ostree_convention : 1; @@ -825,13 +654,12 @@ typedef struct { } OstreeRepoImportArchiveOptions; _OSTREE_PUBLIC -gboolean ostree_repo_import_archive_to_mtree (OstreeRepo *self, - OstreeRepoImportArchiveOptions *opts, - void *archive, /* Really struct archive * */ - OstreeMutableTree *mtree, - OstreeRepoCommitModifier *modifier, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_import_archive_to_mtree (OstreeRepo *self, + OstreeRepoImportArchiveOptions *opts, + void *archive, /* Really struct archive * */ + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + GCancellable *cancellable, GError **error); /** * OstreeRepoExportArchiveOptions: (skip) @@ -840,7 +668,8 @@ gboolean ostree_repo_import_archive_to_mtree (OstreeRepo * you have entirely zeroed the structure, then set just the desired * options. This is used by ostree_repo_export_tree_to_archive(). */ -typedef struct { +typedef struct +{ guint disable_xattrs : 1; guint reserved : 31; @@ -855,63 +684,49 @@ typedef struct { } OstreeRepoExportArchiveOptions; _OSTREE_PUBLIC -gboolean ostree_repo_export_tree_to_archive (OstreeRepo *self, - OstreeRepoExportArchiveOptions *opts, - OstreeRepoFile *root, - void *archive, /* Really struct archive * */ - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_export_tree_to_archive (OstreeRepo *self, OstreeRepoExportArchiveOptions *opts, + OstreeRepoFile *root, + void *archive, /* Really struct archive * */ + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_mtree (OstreeRepo *self, - OstreeMutableTree *mtree, - GFile **out_file, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_mtree (OstreeRepo *self, OstreeMutableTree *mtree, GFile **out_file, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_commit (OstreeRepo *self, - const char *parent, - const char *subject, - const char *body, - GVariant *metadata, - OstreeRepoFile *root, - char **out_commit, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_commit_add_composefs_metadata (OstreeRepo *self, guint format_version, + GVariantDict *dict, OstreeRepoFile *repo_root, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_commit_with_time (OstreeRepo *self, - const char *parent, - const char *subject, - const char *body, - GVariant *metadata, - OstreeRepoFile *root, - guint64 time, - char **out_commit, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_commit (OstreeRepo *self, const char *parent, const char *subject, + const char *body, GVariant *metadata, OstreeRepoFile *root, + char **out_commit, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_read_commit_detached_metadata (OstreeRepo *self, - const char *checksum, - GVariant **out_metadata, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_write_commit_with_time (OstreeRepo *self, const char *parent, + const char *subject, const char *body, + GVariant *metadata, OstreeRepoFile *root, guint64 time, + char **out_commit, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_write_commit_detached_metadata (OstreeRepo *self, - const char *checksum, - GVariant *metadata, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_read_commit_detached_metadata (OstreeRepo *self, const char *checksum, + GVariant **out_metadata, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_write_commit_detached_metadata (OstreeRepo *self, const char *checksum, + GVariant *metadata, GCancellable *cancellable, + GError **error); /** * OstreeRepoCheckoutMode: * @OSTREE_REPO_CHECKOUT_MODE_NONE: No special options * @OSTREE_REPO_CHECKOUT_MODE_USER: Ignore uid/gid of files */ -typedef enum { +typedef enum +{ OSTREE_REPO_CHECKOUT_MODE_NONE = 0, OSTREE_REPO_CHECKOUT_MODE_USER = 1 } OstreeRepoCheckoutMode; @@ -919,27 +734,27 @@ typedef enum { /** * OstreeRepoCheckoutOverwriteMode: * @OSTREE_REPO_CHECKOUT_OVERWRITE_NONE: No special options - * @OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES: When layering checkouts, unlink() and replace existing files, but do not modify existing directories (unless whiteouts are enabled, then directories are replaced) + * @OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES: When layering checkouts, unlink() and replace + * existing files, but do not modify existing directories (unless whiteouts are enabled, then + * directories are replaced) * @OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES: Only add new files/directories - * @OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL: Like UNION_FILES, but error if files are not identical (requires hardlink checkouts) + * @OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL: Like UNION_FILES, but error if files are not + * identical (requires hardlink checkouts) */ -typedef enum { +typedef enum +{ OSTREE_REPO_CHECKOUT_OVERWRITE_NONE = 0, OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES = 1, - OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES = 2, /* Since: 2017.3 */ + OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES = 2, /* Since: 2017.3 */ OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL = 3, /* Since: 2017.11 */ } OstreeRepoCheckoutOverwriteMode; _OSTREE_PUBLIC -gboolean -ostree_repo_checkout_tree (OstreeRepo *self, - OstreeRepoCheckoutMode mode, - OstreeRepoCheckoutOverwriteMode overwrite_mode, - GFile *destination, - OstreeRepoFile *source, - GFileInfo *source_info, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_checkout_tree (OstreeRepo *self, OstreeRepoCheckoutMode mode, + OstreeRepoCheckoutOverwriteMode overwrite_mode, + GFile *destination, OstreeRepoFile *source, + GFileInfo *source_info, GCancellable *cancellable, + GError **error); /** * OstreeRepoCheckoutFilterResult: @@ -948,7 +763,8 @@ ostree_repo_checkout_tree (OstreeRepo *self, * * Since: 2018.2 */ -typedef enum { +typedef enum +{ OSTREE_REPO_CHECKOUT_FILTER_ALLOW, OSTREE_REPO_CHECKOUT_FILTER_SKIP } OstreeRepoCheckoutFilterResult; @@ -964,10 +780,10 @@ typedef enum { * * Since: 2018.2 */ -typedef OstreeRepoCheckoutFilterResult (*OstreeRepoCheckoutFilter) (OstreeRepo *repo, - const char *path, - struct stat *stbuf, - gpointer user_data); +typedef OstreeRepoCheckoutFilterResult (*OstreeRepoCheckoutFilter) (OstreeRepo *repo, + const char *path, + struct stat *stbuf, + gpointer user_data); /** * OstreeRepoCheckoutAtOptions: @@ -978,19 +794,21 @@ typedef OstreeRepoCheckoutFilterResult (*OstreeRepoCheckoutFilter) (OstreeRepo * supercedes previous separate enumeration usage in * ostree_repo_checkout_tree() and ostree_repo_checkout_tree_at(). */ -typedef struct { +typedef struct +{ OstreeRepoCheckoutMode mode; OstreeRepoCheckoutOverwriteMode overwrite_mode; - gboolean enable_uncompressed_cache; /* Deprecated */ - gboolean enable_fsync; /* Deprecated */ + gboolean enable_uncompressed_cache; /* Deprecated */ + gboolean enable_fsync; /* Deprecated */ gboolean process_whiteouts; gboolean no_copy_fallback; - gboolean force_copy; /* Since: 2017.6 */ - gboolean bareuseronly_dirs; /* Since: 2017.7 */ + gboolean force_copy; /* Since: 2017.6 */ + gboolean bareuseronly_dirs; /* Since: 2017.7 */ gboolean force_copy_zerosized; /* Since: 2018.9 */ - gboolean unused_bools[4]; - /* 4 byte hole on 64 bit */ + gboolean process_passthrough_whiteouts; + gboolean unused_bools[3]; + /* 3 byte hole on 64 bit */ const char *subpath; @@ -999,8 +817,8 @@ typedef struct { int unused_ints[6]; gpointer unused_ptrs[3]; OstreeRepoCheckoutFilter filter; /* Since: 2018.2 */ - gpointer filter_user_data; /* Since: 2018.2 */ - OstreeSePolicy *sepolicy; /* Since: 2017.6 */ + gpointer filter_user_data; /* Since: 2018.2 */ + OstreeSePolicy *sepolicy; /* Since: 2017.6 */ const char *sepolicy_prefix; } OstreeRepoCheckoutAtOptions; @@ -1009,34 +827,25 @@ GType ostree_repo_devino_cache_get_type (void); _OSTREE_PUBLIC OstreeRepoDevInoCache *ostree_repo_devino_cache_new (void); _OSTREE_PUBLIC -OstreeRepoDevInoCache * ostree_repo_devino_cache_ref (OstreeRepoDevInoCache *cache); +OstreeRepoDevInoCache *ostree_repo_devino_cache_ref (OstreeRepoDevInoCache *cache); _OSTREE_PUBLIC void ostree_repo_devino_cache_unref (OstreeRepoDevInoCache *cache); _OSTREE_PUBLIC -void ostree_repo_checkout_at_options_set_devino (OstreeRepoCheckoutAtOptions *opts, OstreeRepoDevInoCache *cache); +void ostree_repo_checkout_at_options_set_devino (OstreeRepoCheckoutAtOptions *opts, + OstreeRepoDevInoCache *cache); _OSTREE_PUBLIC -gboolean ostree_repo_checkout_at (OstreeRepo *self, - OstreeRepoCheckoutAtOptions *options, - int destination_dfd, - const char *destination_path, - const char *commit, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_checkout_at (OstreeRepo *self, OstreeRepoCheckoutAtOptions *options, + int destination_dfd, const char *destination_path, + const char *commit, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_checkout_gc (OstreeRepo *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_checkout_gc (OstreeRepo *self, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_read_commit (OstreeRepo *self, - const char *ref, - GFile **out_root, - char **out_commit, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_read_commit (OstreeRepo *self, const char *ref, GFile **out_root, + char **out_commit, GCancellable *cancellable, GError **error); /** * OstreeRepoListObjectsFlags: @@ -1045,7 +854,8 @@ gboolean ostree_repo_read_commit (OstreeRepo *self, * @OSTREE_REPO_LIST_OBJECTS_ALL: List all objects * @OSTREE_REPO_LIST_OBJECTS_NO_PARENTS: Only list objects in this repo, not parents */ -typedef enum { +typedef enum +{ OSTREE_REPO_LIST_OBJECTS_LOOSE = (1 << 0), OSTREE_REPO_LIST_OBJECTS_PACKED = (1 << 1), OSTREE_REPO_LIST_OBJECTS_ALL = (1 << 2), @@ -1061,30 +871,22 @@ typedef enum { #define OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE (G_VARIANT_TYPE ("(bas)") _OSTREE_PUBLIC -gboolean ostree_repo_list_objects (OstreeRepo *self, - OstreeRepoListObjectsFlags flags, - GHashTable **out_objects, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_list_objects (OstreeRepo *self, OstreeRepoListObjectsFlags flags, + GHashTable **out_objects, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_list_commit_objects_starting_with ( OstreeRepo *self, - const char *start, - GHashTable **out_commits, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_list_commit_objects_starting_with (OstreeRepo *self, const char *start, + GHashTable **out_commits, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_list_static_delta_names (OstreeRepo *self, - GPtrArray **out_deltas, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_list_static_delta_names (OstreeRepo *self, GPtrArray **out_deltas, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_list_static_delta_indexes (OstreeRepo *self, - GPtrArray **out_indexes, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_list_static_delta_indexes (OstreeRepo *self, GPtrArray **out_indexes, + GCancellable *cancellable, GError **error); /** * OstreeStaticDeltaGenerateOpt: @@ -1093,20 +895,17 @@ gboolean ostree_repo_list_static_delta_indexes (OstreeRepo *sel * * Parameters controlling optimization of static deltas. */ -typedef enum { +typedef enum +{ OSTREE_STATIC_DELTA_GENERATE_OPT_LOWLATENCY, OSTREE_STATIC_DELTA_GENERATE_OPT_MAJOR } OstreeStaticDeltaGenerateOpt; _OSTREE_PUBLIC -gboolean ostree_repo_static_delta_generate (OstreeRepo *self, - OstreeStaticDeltaGenerateOpt opt, - const char *from, - const char *to, - GVariant *metadata, - GVariant *params, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_static_delta_generate (OstreeRepo *self, OstreeStaticDeltaGenerateOpt opt, + const char *from, const char *to, GVariant *metadata, + GVariant *params, GCancellable *cancellable, + GError **error); /** * OstreeStaticDeltaIndexFlags: @@ -1114,48 +913,43 @@ gboolean ostree_repo_static_delta_generate (OstreeRepo *self, * * Flags controlling static delta index generation. */ -typedef enum { +typedef enum +{ OSTREE_STATIC_DELTA_INDEX_FLAGS_NONE = 0, } OstreeStaticDeltaIndexFlags; /** * OstreeRepoCommitTraverseFlags: * @OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE: No special options for traverse - * @OSTREE_REPO_COMMIT_TRAVERSE_FLAG_COMMIT_ONLY: Traverse and retrieve only commit objects. (Since: 2022.2) + * @OSTREE_REPO_COMMIT_TRAVERSE_FLAG_COMMIT_ONLY: Traverse and retrieve only commit objects. + * (Since: 2022.2) */ -typedef enum { +typedef enum +{ OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE = (1 << 0), OSTREE_REPO_COMMIT_TRAVERSE_FLAG_COMMIT_ONLY = (1 << 1), } OstreeRepoCommitTraverseFlags; _OSTREE_PUBLIC -gboolean ostree_repo_static_delta_reindex (OstreeRepo *repo, - OstreeStaticDeltaIndexFlags flags, - const char *opt_to_commit, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_static_delta_reindex (OstreeRepo *repo, OstreeStaticDeltaIndexFlags flags, + const char *opt_to_commit, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, - GFile *dir_or_file, - OstreeSign *sign, - gboolean skip_validation, - GCancellable *cancellable, - GError **error); +gboolean +ostree_repo_static_delta_execute_offline_with_signature (OstreeRepo *self, GFile *dir_or_file, + OstreeSign *sign, gboolean skip_validation, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_static_delta_execute_offline (OstreeRepo *self, - GFile *dir_or_file, - gboolean skip_validation, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_static_delta_execute_offline (OstreeRepo *self, GFile *dir_or_file, + gboolean skip_validation, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_static_delta_verify_signature (OstreeRepo *self, - const char *delta_id, - OstreeSign *sign, - char **out_success_message, - GError **error); +gboolean ostree_repo_static_delta_verify_signature (OstreeRepo *self, const char *delta_id, + OstreeSign *sign, char **out_success_message, + GError **error); _OSTREE_PUBLIC GHashTable *ostree_repo_traverse_new_reachable (void); @@ -1164,69 +958,57 @@ _OSTREE_PUBLIC GHashTable *ostree_repo_traverse_new_parents (void); _OSTREE_PUBLIC -char ** ostree_repo_traverse_parents_get_commits (GHashTable *parents, GVariant *object); +char **ostree_repo_traverse_parents_get_commits (GHashTable *parents, GVariant *object); _OSTREE_PUBLIC -gboolean ostree_repo_traverse_commit (OstreeRepo *repo, - const char *commit_checksum, - int maxdepth, - GHashTable **out_reachable, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_traverse_commit (OstreeRepo *repo, const char *commit_checksum, int maxdepth, + GHashTable **out_reachable, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_traverse_commit_union (OstreeRepo *repo, - const char *commit_checksum, - int maxdepth, - GHashTable *inout_reachable, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_traverse_commit_union (OstreeRepo *repo, const char *commit_checksum, + int maxdepth, GHashTable *inout_reachable, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_traverse_commit_union_with_parents (OstreeRepo *repo, - const char *commit_checksum, - int maxdepth, - GHashTable *inout_reachable, - GHashTable *inout_parents, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_traverse_commit_union_with_parents (OstreeRepo *repo, + const char *commit_checksum, int maxdepth, + GHashTable *inout_reachable, + GHashTable *inout_parents, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_traverse_commit_with_flags (OstreeRepo *repo, - OstreeRepoCommitTraverseFlags flags, - const char *commit_checksum, - int maxdepth, - GHashTable *inout_reachable, - GHashTable *inout_parents, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_traverse_commit_with_flags (OstreeRepo *repo, + OstreeRepoCommitTraverseFlags flags, + const char *commit_checksum, int maxdepth, + GHashTable *inout_reachable, + GHashTable *inout_parents, + GCancellable *cancellable, GError **error); -struct _OstreeRepoCommitTraverseIter { +struct _OstreeRepoCommitTraverseIter +{ gboolean initialized; /* 4 byte hole on 64 bit */ gpointer dummy[10]; - char dummy_checksum_data[(OSTREE_SHA256_STRING_LEN+1)*2]; + char dummy_checksum_data[(OSTREE_SHA256_STRING_LEN + 1) * 2]; }; typedef struct _OstreeRepoCommitTraverseIter OstreeRepoCommitTraverseIter; _OSTREE_PUBLIC -gboolean -ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter *iter, - OstreeRepo *repo, - GVariant *commit, - OstreeRepoCommitTraverseFlags flags, - GError **error); +gboolean ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter *iter, + OstreeRepo *repo, GVariant *commit, + OstreeRepoCommitTraverseFlags flags, + GError **error); _OSTREE_PUBLIC -gboolean -ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter *iter, - OstreeRepo *repo, - GVariant *dirtree, - OstreeRepoCommitTraverseFlags flags, - GError **error); +gboolean ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter *iter, + OstreeRepo *repo, GVariant *dirtree, + OstreeRepoCommitTraverseFlags flags, + GError **error); -typedef enum { +typedef enum +{ OSTREE_REPO_COMMIT_ITER_RESULT_ERROR, OSTREE_REPO_COMMIT_ITER_RESULT_END, OSTREE_REPO_COMMIT_ITER_RESULT_FILE, @@ -1234,20 +1016,18 @@ typedef enum { } OstreeRepoCommitIterResult; _OSTREE_PUBLIC -OstreeRepoCommitIterResult ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, - GCancellable *cancellable, - GError **error); +OstreeRepoCommitIterResult +ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -void ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter, - char **out_name, - char **out_checksum); +void ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter, char **out_name, + char **out_checksum); _OSTREE_PUBLIC -void ostree_repo_commit_traverse_iter_get_dir (OstreeRepoCommitTraverseIter *iter, - char **out_name, - char **out_content_checksum, - char **out_meta_checksum); +void ostree_repo_commit_traverse_iter_get_dir (OstreeRepoCommitTraverseIter *iter, char **out_name, + char **out_content_checksum, + char **out_meta_checksum); _OSTREE_PUBLIC void ostree_repo_commit_traverse_iter_clear (OstreeRepoCommitTraverseIter *iter); @@ -1255,16 +1035,19 @@ void ostree_repo_commit_traverse_iter_clear (OstreeRepoCommitTraverseIter *iter) _OSTREE_PUBLIC void ostree_repo_commit_traverse_iter_cleanup (void *p); -#define ostree_cleanup_repo_commit_traverse_iter __attribute__ ((cleanup(ostree_repo_commit_traverse_iter_cleanup))) +#define ostree_cleanup_repo_commit_traverse_iter \ + __attribute__ ((cleanup (ostree_repo_commit_traverse_iter_cleanup))) /** * OstreeRepoPruneFlags: * @OSTREE_REPO_PRUNE_FLAGS_NONE: No special options for pruning * @OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE: Don't actually delete objects * @OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY: Do not traverse individual commit objects, only follow refs + * for reachability calculations * @OSTREE_REPO_PRUNE_FLAGS_COMMIT_ONLY: Only traverse commit objects. (Since 2022.2) */ -typedef enum { +typedef enum +{ OSTREE_REPO_PRUNE_FLAGS_NONE = 0, OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE = (1 << 0), OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY = (1 << 1), @@ -1272,22 +1055,17 @@ typedef enum { } OstreeRepoPruneFlags; _OSTREE_PUBLIC -gboolean -ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_prune (OstreeRepo *self, - OstreeRepoPruneFlags flags, - gint depth, - gint *out_objects_total, - gint *out_objects_pruned, - guint64 *out_pruned_object_size_total, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_prune (OstreeRepo *self, OstreeRepoPruneFlags flags, gint depth, + gint *out_objects_total, gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, GCancellable *cancellable, + GError **error); -struct _OstreeRepoPruneOptions { +struct _OstreeRepoPruneOptions +{ OstreeRepoPruneFlags flags; /* 4 byte hole on 64 bit */ @@ -1302,32 +1080,30 @@ struct _OstreeRepoPruneOptions { typedef struct _OstreeRepoPruneOptions OstreeRepoPruneOptions; _OSTREE_PUBLIC -gboolean -ostree_repo_traverse_reachable_refs (OstreeRepo *self, - guint depth, - GHashTable *reachable, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_traverse_reachable_refs (OstreeRepo *self, guint depth, GHashTable *reachable, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_prune_from_reachable (OstreeRepo *self, - OstreeRepoPruneOptions *options, - gint *out_objects_total, - gint *out_objects_pruned, - guint64 *out_pruned_object_size_total, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_prune_from_reachable (OstreeRepo *self, OstreeRepoPruneOptions *options, + gint *out_objects_total, gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, + GCancellable *cancellable, GError **error); /** * OstreeRepoPullFlags: * @OSTREE_REPO_PULL_FLAGS_NONE: No special options for pull - * @OSTREE_REPO_PULL_FLAGS_MIRROR: Write out refs suitable for mirrors and fetch all refs if none requested + * @OSTREE_REPO_PULL_FLAGS_MIRROR: Write out refs suitable for mirrors and fetch all refs if none + * requested * @OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY: Fetch only the commit metadata - * @OSTREE_REPO_PULL_FLAGS_UNTRUSTED: Do verify checksums of local (filesystem-accessible) repositories (defaults on for HTTP) - * @OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES: Since 2017.7. Reject writes of content objects with modes outside of 0775. - * @OSTREE_REPO_PULL_FLAGS_TRUSTED_HTTP: Don't verify checksums of objects HTTP repositories (Since: 2017.12) + * @OSTREE_REPO_PULL_FLAGS_UNTRUSTED: Do verify checksums of local (filesystem-accessible) + * repositories (defaults on for HTTP) + * @OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES: Since 2017.7. Reject writes of content objects with + * modes outside of 0775. + * @OSTREE_REPO_PULL_FLAGS_TRUSTED_HTTP: Don't verify checksums of objects HTTP repositories + * (Since: 2017.12) */ -typedef enum { +typedef enum +{ OSTREE_REPO_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_MIRROR = (1 << 0), OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1), @@ -1337,115 +1113,79 @@ typedef enum { } OstreeRepoPullFlags; _OSTREE_PUBLIC -gboolean ostree_repo_pull (OstreeRepo *self, - const char *remote_name, - char **refs_to_fetch, - OstreeRepoPullFlags flags, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_pull (OstreeRepo *self, const char *remote_name, char **refs_to_fetch, + OstreeRepoPullFlags flags, OstreeAsyncProgress *progress, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean -ostree_repo_pull_one_dir (OstreeRepo *self, - const char *remote_name, - const char *dir_to_pull, - char **refs_to_fetch, - OstreeRepoPullFlags flags, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_repo_pull_with_options (OstreeRepo *self, - const char *remote_name_or_baseurl, - GVariant *options, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -void ostree_repo_find_remotes_async (OstreeRepo *self, - const OstreeCollectionRef * const *refs, - GVariant *options, - OstreeRepoFinder **finders, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -_OSTREE_PUBLIC -OstreeRepoFinderResult **ostree_repo_find_remotes_finish (OstreeRepo *self, - GAsyncResult *result, - GError **error); - -_OSTREE_PUBLIC -void ostree_repo_pull_from_remotes_async (OstreeRepo *self, - const OstreeRepoFinderResult * const *results, - GVariant *options, - OstreeAsyncProgress *progress, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -_OSTREE_PUBLIC -gboolean ostree_repo_pull_from_remotes_finish (OstreeRepo *self, - GAsyncResult *result, - GError **error); - -_OSTREE_PUBLIC -OstreeRemote *ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, - const gchar *collection_id, - GCancellable *cancellable, - GError **error); - -_OSTREE_PUBLIC -gboolean ostree_repo_list_collection_refs (OstreeRepo *self, - const char *match_collection_id, - GHashTable **out_all_refs, +gboolean ostree_repo_pull_one_dir (OstreeRepo *self, const char *remote_name, + const char *dir_to_pull, char **refs_to_fetch, + OstreeRepoPullFlags flags, OstreeAsyncProgress *progress, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_pull_with_options (OstreeRepo *self, const char *remote_name_or_baseurl, + GVariant *options, OstreeAsyncProgress *progress, + GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +void ostree_repo_find_remotes_async (OstreeRepo *self, const OstreeCollectionRef *const *refs, + GVariant *options, OstreeRepoFinder **finders, + OstreeAsyncProgress *progress, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); +_OSTREE_PUBLIC +OstreeRepoFinderResult **ostree_repo_find_remotes_finish (OstreeRepo *self, GAsyncResult *result, + GError **error); + +_OSTREE_PUBLIC +void ostree_repo_pull_from_remotes_async (OstreeRepo *self, + const OstreeRepoFinderResult *const *results, + GVariant *options, OstreeAsyncProgress *progress, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data); +_OSTREE_PUBLIC +gboolean ostree_repo_pull_from_remotes_finish (OstreeRepo *self, GAsyncResult *result, + GError **error); + +_OSTREE_PUBLIC +OstreeRemote *ostree_repo_resolve_keyring_for_collection (OstreeRepo *self, + const gchar *collection_id, + GCancellable *cancellable, + GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_list_collection_refs (OstreeRepo *self, const char *match_collection_id, + GHashTable **out_all_refs, OstreeRepoListRefsExtFlags flags, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC void ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress, - gpointer user_data); + gpointer user_data); _OSTREE_PUBLIC -gboolean ostree_repo_sign_commit (OstreeRepo *self, - const gchar *commit_checksum, - const gchar *key_id, - const gchar *homedir, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_sign_commit (OstreeRepo *self, const gchar *commit_checksum, + const gchar *key_id, const gchar *homedir, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_sign_delta (OstreeRepo *self, - const gchar *from_commit, - const gchar *to_commit, - const gchar *key_id, - const gchar *homedir, - GCancellable *cancellable, - GError **error); - +gboolean ostree_repo_sign_delta (OstreeRepo *self, const gchar *from_commit, const gchar *to_commit, + const gchar *key_id, const gchar *homedir, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_verify_commit (OstreeRepo *self, - const gchar *commit_checksum, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_verify_commit (OstreeRepo *self, const gchar *commit_checksum, + GFile *keyringdir, GFile *extra_keyring, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_get_gpg_verify (OstreeRepo *self, - const char *name, - gboolean *out_gpg_verify, - GError **error); +gboolean ostree_repo_remote_get_gpg_verify (OstreeRepo *self, const char *name, + gboolean *out_gpg_verify, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self, - const char *name, - gboolean *out_gpg_verify_summary, - GError **error); +gboolean ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self, const char *name, + gboolean *out_gpg_verify_summary, + GError **error); /** * OSTREE_GPG_KEY_GVARIANT_FORMAT: @@ -1481,109 +1221,85 @@ gboolean ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self, #define OSTREE_GPG_KEY_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_GPG_KEY_GVARIANT_STRING) _OSTREE_PUBLIC -gboolean ostree_repo_remote_get_gpg_keys (OstreeRepo *self, - const char *name, - const char * const *key_ids, - GPtrArray **out_keys, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_get_gpg_keys (OstreeRepo *self, const char *name, + const char *const *key_ids, GPtrArray **out_keys, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_remote_gpg_import (OstreeRepo *self, - const char *name, - GInputStream *source_stream, - const char * const *key_ids, - guint *out_imported, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_remote_gpg_import (OstreeRepo *self, const char *name, + GInputStream *source_stream, const char *const *key_ids, + guint *out_imported, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_add_gpg_signature_summary (OstreeRepo *self, - const gchar **key_id, - const gchar *homedir, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_add_gpg_signature_summary (OstreeRepo *self, const gchar **key_id, + const gchar *homedir, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_append_gpg_signature (OstreeRepo *self, - const gchar *commit_checksum, - GBytes *signature_bytes, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_append_gpg_signature (OstreeRepo *self, const gchar *commit_checksum, + GBytes *signature_bytes, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_gpg_sign_data (OstreeRepo *self, - GBytes *data, - GBytes *old_signatures, - const gchar **key_id, - const gchar *homedir, - GBytes **out_signatures, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_gpg_sign_data (OstreeRepo *self, GBytes *data, GBytes *old_signatures, + const gchar **key_id, const gchar *homedir, + GBytes **out_signatures, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -OstreeGpgVerifyResult * ostree_repo_verify_commit_ext (OstreeRepo *self, - const gchar *commit_checksum, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error); +OstreeGpgVerifyResult *ostree_repo_verify_commit_ext (OstreeRepo *self, + const gchar *commit_checksum, + GFile *keyringdir, GFile *extra_keyring, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeGpgVerifyResult * -ostree_repo_verify_commit_for_remote (OstreeRepo *self, - const gchar *commit_checksum, - const gchar *remote_name, - GCancellable *cancellable, - GError **error); +OstreeGpgVerifyResult *ostree_repo_verify_commit_for_remote (OstreeRepo *self, + const gchar *commit_checksum, + const gchar *remote_name, + GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -OstreeGpgVerifyResult * ostree_repo_gpg_verify_data (OstreeRepo *self, - const gchar *remote_name, - GBytes *data, - GBytes *signatures, - GFile *keyringdir, - GFile *extra_keyring, - GCancellable *cancellable, - GError **error); +OstreeGpgVerifyResult *ostree_repo_gpg_verify_data (OstreeRepo *self, const gchar *remote_name, + GBytes *data, GBytes *signatures, + GFile *keyringdir, GFile *extra_keyring, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeGpgVerifyResult * ostree_repo_verify_summary (OstreeRepo *self, - const char *remote_name, - GBytes *summary, - GBytes *signatures, - GCancellable *cancellable, - GError **error); +OstreeGpgVerifyResult *ostree_repo_verify_summary (OstreeRepo *self, const char *remote_name, + GBytes *summary, GBytes *signatures, + GCancellable *cancellable, GError **error); /** * OstreeRepoVerifyFlags: * @OSTREE_REPO_VERIFY_FLAGS_NONE: No flags * @OSTREE_REPO_VERIFY_FLAGS_NO_GPG: Skip GPG verification * @OSTREE_REPO_VERIFY_FLAGS_NO_SIGNAPI: Skip all other signature verification methods - * + * * Since: 2021.4 */ -typedef enum { +typedef enum +{ OSTREE_REPO_VERIFY_FLAGS_NONE = 0, OSTREE_REPO_VERIFY_FLAGS_NO_GPG = (1 << 0), OSTREE_REPO_VERIFY_FLAGS_NO_SIGNAPI = (1 << 1), } OstreeRepoVerifyFlags; _OSTREE_PUBLIC -gboolean ostree_repo_signature_verify_commit_data (OstreeRepo *self, - const char *remote_name, - GBytes *commit_data, - GBytes *commit_metadata, - OstreeRepoVerifyFlags flags, - char **out_results, - GError **error); +gboolean ostree_repo_signature_verify_commit_data (OstreeRepo *self, const char *remote_name, + GBytes *commit_data, GBytes *commit_metadata, + OstreeRepoVerifyFlags flags, char **out_results, + GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_regenerate_summary (OstreeRepo *self, - GVariant *additional_metadata, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_regenerate_summary (OstreeRepo *self, GVariant *additional_metadata, + GCancellable *cancellable, GError **error); +_OSTREE_PUBLIC +gboolean ostree_repo_regenerate_metadata (OstreeRepo *self, GVariant *additional_metadata, + GVariant *options, GCancellable *cancellable, + GError **error); /** * OstreeRepoLockType: @@ -1594,21 +1310,18 @@ gboolean ostree_repo_regenerate_summary (OstreeRepo *self, * * Since: 2021.3 */ -typedef enum { +typedef enum +{ OSTREE_REPO_LOCK_SHARED, OSTREE_REPO_LOCK_EXCLUSIVE } OstreeRepoLockType; _OSTREE_PUBLIC -gboolean ostree_repo_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_lock_push (OstreeRepo *self, OstreeRepoLockType lock_type, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_repo_lock_pop (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error); +gboolean ostree_repo_lock_pop (OstreeRepo *self, OstreeRepoLockType lock_type, + GCancellable *cancellable, GError **error); /* C convenience API only */ #ifndef __GI_SCANNER__ @@ -1623,10 +1336,8 @@ gboolean ostree_repo_lock_pop (OstreeRepo *self, typedef struct OstreeRepoAutoLock OstreeRepoAutoLock; _OSTREE_PUBLIC -OstreeRepoAutoLock * ostree_repo_auto_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error); +OstreeRepoAutoLock *ostree_repo_auto_lock_push (OstreeRepo *self, OstreeRepoLockType lock_type, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC void ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock); @@ -1634,7 +1345,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, ostree_repo_auto_lock_cleanup #endif - /** * OSTREE_REPO_METADATA_REF: * @@ -1683,7 +1393,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, ostree_repo_auto_lock_cleanup G_END_DECLS - /* Include here as the functions defined before should not depend on anything which is defined in -deprecated.h. */ #include "ostree-repo-deprecated.h" diff --git a/src/libostree/ostree-rollsum.c b/src/libostree/ostree-rollsum.c index 805c156..e09ceb6 100644 --- a/src/libostree/ostree-rollsum.c +++ b/src/libostree/ostree-rollsum.c @@ -22,14 +22,14 @@ #include #include -#include "ostree-rollsum.h" -#include "libglnx.h" #include "bupsplit.h" +#include "libglnx.h" +#include "ostree-rollsum.h" -#define ROLLSUM_BLOB_MAX (8192*4) +#define ROLLSUM_BLOB_MAX (8192 * 4) static GHashTable * -rollsum_chunks_crc32 (GBytes *bytes) +rollsum_chunks_crc32 (GBytes *bytes) { gsize start = 0; gboolean rollsum_end = FALSE; @@ -49,26 +49,27 @@ rollsum_chunks_crc32 (GBytes *bytes) if (!rollsum_end) { - offset = bupsplit_find_ofs (buf + start, MIN(G_MAXINT32, remaining), &bits); + offset = bupsplit_find_ofs (buf + start, MIN (G_MAXINT32, remaining), &bits); if (offset == 0) { rollsum_end = TRUE; - offset = MIN(ROLLSUM_BLOB_MAX, remaining); + offset = MIN (ROLLSUM_BLOB_MAX, remaining); } else if (offset > ROLLSUM_BLOB_MAX) offset = ROLLSUM_BLOB_MAX; } else - offset = MIN(ROLLSUM_BLOB_MAX, remaining); + offset = MIN (ROLLSUM_BLOB_MAX, remaining); /* Use zlib's crc32 */ - { guint32 crc = crc32 (0L, NULL, 0); + { + guint32 crc = crc32 (0L, NULL, 0); GVariant *val; GPtrArray *matches; crc = crc32 (crc, buf, offset); - val = g_variant_ref_sink (g_variant_new ("(utt)", crc, (guint64) start, (guint64)offset)); + val = g_variant_ref_sink (g_variant_new ("(utt)", crc, (guint64)start, (guint64)offset)); matches = g_hash_table_lookup (ret_rollsums, GUINT_TO_POINTER (crc)); if (!matches) { @@ -86,15 +87,14 @@ rollsum_chunks_crc32 (GBytes *bytes) } static gint -compare_matches (const void *app, - const void *bpp) +compare_matches (const void *app, const void *bpp) { - GVariant **avpp = (GVariant**)app; + GVariant **avpp = (GVariant **)app; GVariant *a = *avpp; - GVariant **bvpp = (GVariant**)bpp; + GVariant **bvpp = (GVariant **)bpp; GVariant *b = *bvpp; guint64 a_start, b_start; - + g_variant_get_child (a, 2, "t", &a_start); g_variant_get_child (b, 2, "t", &b_start); @@ -106,13 +106,12 @@ compare_matches (const void *app, } OstreeRollsumMatches * -_ostree_compute_rollsum_matches (GBytes *from, - GBytes *to) +_ostree_compute_rollsum_matches (GBytes *from, GBytes *to) { OstreeRollsumMatches *ret_rollsum = NULL; - g_autoptr(GHashTable) from_rollsum = NULL; - g_autoptr(GHashTable) to_rollsum = NULL; - g_autoptr(GPtrArray) matches = NULL; + g_autoptr (GHashTable) from_rollsum = NULL; + g_autoptr (GHashTable) to_rollsum = NULL; + g_autoptr (GPtrArray) matches = NULL; const guint8 *from_buf; gsize from_len; const guint8 *to_buf; @@ -165,18 +164,19 @@ _ostree_compute_rollsum_matches (GBytes *from, /* Same crc32 but different length, skip it. */ if (to_offset != from_offset) continue; - + /* Rsync uses a cryptographic checksum, but let's be * very conservative here and just memcmp. */ if (memcmp (from_buf + from_start, to_buf + to_start, to_offset) == 0) { - GVariant *match = g_variant_new ("(uttt)", fromcrc, to_offset, to_start, from_start); + GVariant *match + = g_variant_new ("(uttt)", fromcrc, to_offset, to_start, from_start); ret_rollsum->bufmatches++; ret_rollsum->match_size += to_offset; g_ptr_array_add (matches, g_variant_ref_sink (match)); break; /* Don't need any more matches */ - } + } } } } @@ -186,9 +186,12 @@ _ostree_compute_rollsum_matches (GBytes *from, g_ptr_array_sort (matches, compare_matches); - ret_rollsum->from_rollsums = from_rollsum; from_rollsum = NULL; - ret_rollsum->to_rollsums = to_rollsum; to_rollsum = NULL; - ret_rollsum->matches = matches; matches = NULL; + ret_rollsum->from_rollsums = from_rollsum; + from_rollsum = NULL; + ret_rollsum->to_rollsums = to_rollsum; + to_rollsum = NULL; + ret_rollsum->matches = matches; + matches = NULL; return ret_rollsum; } diff --git a/src/libostree/ostree-rollsum.h b/src/libostree/ostree-rollsum.h index 50016b3..ac620f4 100644 --- a/src/libostree/ostree-rollsum.h +++ b/src/libostree/ostree-rollsum.h @@ -19,12 +19,13 @@ #pragma once -#include #include "libglnx.h" +#include G_BEGIN_DECLS -typedef struct { +typedef struct +{ GHashTable *from_rollsums; GHashTable *to_rollsums; guint crcmatches; @@ -34,11 +35,9 @@ typedef struct { GPtrArray *matches; } OstreeRollsumMatches; -OstreeRollsumMatches * -_ostree_compute_rollsum_matches (GBytes *from, - GBytes *to); +OstreeRollsumMatches *_ostree_compute_rollsum_matches (GBytes *from, GBytes *to); void _ostree_rollsum_matches_free (OstreeRollsumMatches *rollsum); -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeRollsumMatches, _ostree_rollsum_matches_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRollsumMatches, _ostree_rollsum_matches_free) G_END_DECLS diff --git a/src/libostree/ostree-sepolicy-private.h b/src/libostree/ostree-sepolicy-private.h index 7bbc1a1..350ef40 100644 --- a/src/libostree/ostree-sepolicy-private.h +++ b/src/libostree/ostree-sepolicy-private.h @@ -23,18 +23,16 @@ G_BEGIN_DECLS -typedef struct { +typedef struct +{ gboolean initialized; } OstreeSepolicyFsCreatecon; void _ostree_sepolicy_fscreatecon_clear (OstreeSepolicyFsCreatecon *con); -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeSepolicyFsCreatecon, _ostree_sepolicy_fscreatecon_clear) +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeSepolicyFsCreatecon, _ostree_sepolicy_fscreatecon_clear) -gboolean _ostree_sepolicy_preparefscreatecon (OstreeSepolicyFsCreatecon *con, - OstreeSePolicy *self, - const char *path, - guint32 mode, - GError **error); +gboolean _ostree_sepolicy_preparefscreatecon (OstreeSepolicyFsCreatecon *con, OstreeSePolicy *self, + const char *path, guint32 mode, GError **error); GVariant *_ostree_filter_selinux_xattr (GVariant *xattrs); diff --git a/src/libostree/ostree-sepolicy.c b/src/libostree/ostree-sepolicy.c index 5fd59a8..d61a9cc 100644 --- a/src/libostree/ostree-sepolicy.c +++ b/src/libostree/ostree-sepolicy.c @@ -20,17 +20,17 @@ #include "config.h" #ifdef HAVE_SELINUX -#include #include +#include #endif #include "otutil.h" -#include "ostree-sepolicy.h" +#include "ostree-bootloader-syslinux.h" +#include "ostree-bootloader-uboot.h" #include "ostree-repo.h" #include "ostree-sepolicy-private.h" -#include "ostree-bootloader-uboot.h" -#include "ostree-bootloader-syslinux.h" +#include "ostree-sepolicy.h" /** * SECTION:ostree-sepolicy @@ -40,7 +40,8 @@ * A #OstreeSePolicy object can load the SELinux policy from a given * root and perform labeling. */ -struct OstreeSePolicy { +struct OstreeSePolicy +{ GObject parent; int rootfs_dfd; @@ -56,13 +57,15 @@ struct OstreeSePolicy { #endif }; -typedef struct { +typedef struct +{ GObjectClass parent_class; } OstreeSePolicyClass; -static void initable_iface_init (GInitableIface *initable_iface); +static void initable_iface_init (GInitableIface *initable_iface); -enum { +enum +{ PROP_0, PROP_PATH, @@ -77,11 +80,11 @@ ostree_sepolicy_finalize (GObject *object) { OstreeSePolicy *self = OSTREE_SEPOLICY (object); - (void) glnx_tmpdir_delete (&self->tmpdir, NULL, NULL); + (void)glnx_tmpdir_delete (&self->tmpdir, NULL, NULL); g_clear_object (&self->path); if (self->rootfs_dfd_owned != -1) - (void) close (self->rootfs_dfd_owned); + (void)close (self->rootfs_dfd_owned); #ifdef HAVE_SELINUX g_clear_object (&self->selinux_policy_root); g_clear_pointer (&self->selinux_policy_name, g_free); @@ -97,10 +100,8 @@ ostree_sepolicy_finalize (GObject *object) } static void -ostree_sepolicy_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +ostree_sepolicy_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeSePolicy *self = OSTREE_SEPOLICY (object); @@ -134,10 +135,7 @@ ostree_sepolicy_set_property(GObject *object, } static void -ostree_sepolicy_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +ostree_sepolicy_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { OstreeSePolicy *self = OSTREE_SEPOLICY (object); @@ -175,35 +173,25 @@ ostree_sepolicy_class_init (OstreeSePolicyClass *klass) object_class->set_property = ostree_sepolicy_set_property; object_class->finalize = ostree_sepolicy_finalize; - g_object_class_install_property (object_class, - PROP_PATH, - g_param_spec_object ("path", - "", - "", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_ROOTFS_DFD, - g_param_spec_int ("rootfs-dfd", - "", "", - -1, G_MAXINT, -1, + g_object_class_install_property ( + object_class, PROP_PATH, + g_param_spec_object ("path", "", "", G_TYPE_FILE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_ROOTFS_DFD, + g_param_spec_int ("rootfs-dfd", "", "", -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - } #ifdef HAVE_SELINUX /* Find the latest policy file in our root and return its checksum. */ static gboolean -get_policy_checksum (char **out_csum, - GCancellable *cancellable, - GError **error) +get_policy_checksum (char **out_csum, GCancellable *cancellable, GError **error) { const char *binary_policy_path = selinux_binary_policy_path (); const char *binfile_prefix = glnx_basename (binary_policy_path); g_autofree char *bindir_path = g_path_get_dirname (binary_policy_path); - g_autofree char *best_policy = NULL; int best_version = 0; @@ -211,7 +199,9 @@ get_policy_checksum (char **out_csum, if (!glnx_opendirat (AT_FDCWD, bindir_path, TRUE, &bindir_dfd, error)) return FALSE; - g_auto(GLnxDirFdIterator) dfd_iter = { 0,}; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (bindir_dfd, ".", FALSE, &dfd_iter, error)) return FALSE; @@ -219,8 +209,7 @@ get_policy_checksum (char **out_csum, { struct dirent *dent = NULL; - if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, - cancellable, error)) + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) return FALSE; if (dent == NULL) break; @@ -233,16 +222,14 @@ get_policy_checksum (char **out_csum, * somehow change; there would be cheers & slow-mo high-fives at the * sight of our code not breaking. Is that hope not worth a fraction * of a millisecond? I believe it is... or maybe I'm just lazy. */ - g_autofree char *regex = g_strdup_printf ("^\\Q%s\\E\\.[0-9]+$", - binfile_prefix); + g_autofree char *regex = g_strdup_printf ("^\\Q%s\\E\\.[0-9]+$", binfile_prefix); /* we could use match groups to extract the version, but mehhh, we * already have the prefix on hand */ if (g_regex_match_simple (regex, dent->d_name, 0, 0)) { int version = /* do +1 for the period */ - (int)g_ascii_strtoll (dent->d_name + strlen (binfile_prefix)+1, - NULL, 10); + (int)g_ascii_strtoll (dent->d_name + strlen (binfile_prefix) + 1, NULL, 10); g_assert (version > 0); if (version > best_version) @@ -258,8 +245,7 @@ get_policy_checksum (char **out_csum, if (!best_policy) return glnx_throw (error, "Could not find binary policy file"); - *out_csum = ot_checksum_file_at (bindir_dfd, best_policy, G_CHECKSUM_SHA256, - cancellable, error); + *out_csum = ot_checksum_file_at (bindir_dfd, best_policy, G_CHECKSUM_SHA256, cancellable, error); if (*out_csum == NULL) return FALSE; @@ -282,21 +268,21 @@ get_policy_checksum (char **out_csum, * * Returns: (transfer full): A new policy */ -OstreeSePolicy* -ostree_sepolicy_new_from_commit (OstreeRepo *repo, - const char *rev, - GCancellable *cancellable, - GError **error) +OstreeSePolicy * +ostree_sepolicy_new_from_commit (OstreeRepo *repo, const char *rev, GCancellable *cancellable, + GError **error) { GLNX_AUTO_PREFIX_ERROR ("setting sepolicy from commit", error); - g_autoptr(GFile) root = NULL; + g_autoptr (GFile) root = NULL; g_autofree char *commit = NULL; if (!ostree_repo_read_commit (repo, rev, &root, &commit, cancellable, error)) return NULL; const char policypath[] = "usr/etc/selinux"; - g_autoptr(GFile) policyroot = g_file_get_child (root, policypath); + g_autoptr (GFile) policyroot = g_file_get_child (root, policypath); - GLnxTmpDir tmpdir = {0,}; + GLnxTmpDir tmpdir = { + 0, + }; if (!glnx_mkdtemp ("ostree-commit-sepolicy-XXXXXX", 0700, &tmpdir, error)) return FALSE; if (!glnx_shutil_mkdir_p_at (tmpdir.fd, "usr/etc", 0755, cancellable, error)) @@ -304,12 +290,15 @@ ostree_sepolicy_new_from_commit (OstreeRepo *repo, if (g_file_query_exists (policyroot, NULL)) { - OstreeRepoCheckoutAtOptions coopts = {0,}; - coopts.mode = OSTREE_REPO_CHECKOUT_MODE_USER; - coopts.subpath = glnx_strjoina ("/", policypath); - - if (!ostree_repo_checkout_at (repo, &coopts, tmpdir.fd, policypath, commit, cancellable, error)) - return glnx_prefix_error_null (error, "policy checkout"); + OstreeRepoCheckoutAtOptions coopts = { + 0, + }; + coopts.mode = OSTREE_REPO_CHECKOUT_MODE_USER; + coopts.subpath = glnx_strjoina ("/", policypath); + + if (!ostree_repo_checkout_at (repo, &coopts, tmpdir.fd, policypath, commit, cancellable, + error)) + return glnx_prefix_error_null (error, "policy checkout"); } OstreeSePolicy *ret = ostree_sepolicy_new_at (tmpdir.fd, cancellable, error); @@ -338,9 +327,7 @@ cached_is_selinux_enabled (void) #endif static gboolean -initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) +initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { #ifdef HAVE_SELINUX OstreeSePolicy *self = OSTREE_SEPOLICY (initable); @@ -352,10 +339,10 @@ initable_init (GInitable *initable, /* First thing here, call is_selinux_enabled() to prime the cache. See the * link above for more information why. */ - (void) cached_is_selinux_enabled (); + (void)cached_is_selinux_enabled (); /* TODO - use this below */ - g_autoptr(GFile) path = NULL; + g_autoptr (GFile) path = NULL; if (self->rootfs_dfd != -1) path = ot_fdrel_to_gfile (self->rootfs_dfd, "."); else if (self->path) @@ -372,30 +359,30 @@ initable_init (GInitable *initable, else g_assert_not_reached (); - g_autoptr(GFile) etc_selinux_dir = g_file_resolve_relative_path (path, "etc/selinux"); + g_autoptr (GFile) etc_selinux_dir = g_file_resolve_relative_path (path, "etc/selinux"); if (!g_file_query_exists (etc_selinux_dir, NULL)) { g_object_unref (etc_selinux_dir); etc_selinux_dir = g_file_resolve_relative_path (path, "usr/etc/selinux"); } - g_autoptr(GFile) policy_config_path = g_file_get_child (etc_selinux_dir, "config"); - g_autoptr(GFile) policy_root = NULL; + g_autoptr (GFile) policy_config_path = g_file_get_child (etc_selinux_dir, "config"); + g_autoptr (GFile) policy_root = NULL; if (g_file_query_exists (policy_config_path, NULL)) { - g_autoptr(GFileInputStream) filein = g_file_read (policy_config_path, cancellable, error); + g_autoptr (GFileInputStream) filein = g_file_read (policy_config_path, cancellable, error); if (!filein) return FALSE; - g_autoptr(GDataInputStream) datain = g_data_input_stream_new ((GInputStream*)filein); + g_autoptr (GDataInputStream) datain = g_data_input_stream_new ((GInputStream *)filein); while (TRUE) { gsize len; - g_autoptr(GError) temp_error = NULL; - g_autofree char *line = g_data_input_stream_read_line_utf8 (datain, &len, - cancellable, &temp_error); + g_autoptr (GError) temp_error = NULL; + g_autofree char *line + = g_data_input_stream_read_line_utf8 (datain, &len, cancellable, &temp_error); if (temp_error) return g_propagate_error (error, g_steal_pointer (&temp_error)), FALSE; @@ -411,8 +398,8 @@ initable_init (GInitable *initable, else if (g_str_has_prefix (line, selinux_prefix)) { const char *enabled_str = line + strlen (selinux_prefix); - if (g_ascii_strncasecmp (enabled_str, "enforcing", strlen ("enforcing")) == 0 || - g_ascii_strncasecmp (enabled_str, "permissive", strlen ("permissive")) == 0) + if (g_ascii_strncasecmp (enabled_str, "enforcing", strlen ("enforcing")) == 0 + || g_ascii_strncasecmp (enabled_str, "permissive", strlen ("permissive")) == 0) enabled = TRUE; } } @@ -427,13 +414,13 @@ initable_init (GInitable *initable, self->selinux_hnd = selabel_open (SELABEL_CTX_FILE, NULL, 0); if (!self->selinux_hnd) - return glnx_throw_errno_prefix (error, "With policy root '%s': selabel_open(SELABEL_CTX_FILE)", - policy_rootpath); + return glnx_throw_errno_prefix ( + error, "With policy root '%s': selabel_open(SELABEL_CTX_FILE)", policy_rootpath); char *con = NULL; if (selabel_lookup_raw (self->selinux_hnd, &con, "/", 0755) != 0) - return glnx_throw_errno_prefix (error, "With policy root '%s': Failed to look up context of /", - policy_rootpath); + return glnx_throw_errno_prefix ( + error, "With policy root '%s': Failed to look up context of /", policy_rootpath); freecon (con); if (!get_policy_checksum (&self->selinux_policy_csum, cancellable, error)) @@ -468,10 +455,8 @@ initable_iface_init (GInitableIface *initable_iface) * * Returns: (transfer full): An accessor object for SELinux policy in root located at @path */ -OstreeSePolicy* -ostree_sepolicy_new (GFile *path, - GCancellable *cancellable, - GError **error) +OstreeSePolicy * +ostree_sepolicy_new (GFile *path, GCancellable *cancellable, GError **error) { return g_initable_new (OSTREE_TYPE_SEPOLICY, cancellable, error, "path", path, NULL); } @@ -486,10 +471,8 @@ ostree_sepolicy_new (GFile *path, * * Since: 2017.4 */ -OstreeSePolicy* -ostree_sepolicy_new_at (int rootfs_dfd, - GCancellable *cancellable, - GError **error) +OstreeSePolicy * +ostree_sepolicy_new_at (int rootfs_dfd, GCancellable *cancellable, GError **error) { return g_initable_new (OSTREE_TYPE_SEPOLICY, cancellable, error, "rootfs-dfd", rootfs_dfd, NULL); } @@ -502,10 +485,10 @@ ostree_sepolicy_new_at (int rootfs_dfd, * policy objects to be created from file-descriptor relative paths, which * may not be globally accessible. * - * Returns: (transfer none): Path to rootfs + * Returns: (transfer none) (nullable): Path to rootfs */ GFile * -ostree_sepolicy_get_path (OstreeSePolicy *self) +ostree_sepolicy_get_path (OstreeSePolicy *self) { return self->path; } @@ -530,7 +513,7 @@ ostree_sepolicy_get_name (OstreeSePolicy *self) * ostree_sepolicy_get_csum: * @self: * - * Returns: (transfer none): Checksum of current policy + * Returns: (transfer none) (nullable): Checksum of current policy * * Since: 2016.5 */ @@ -549,7 +532,7 @@ ostree_sepolicy_get_csum (OstreeSePolicy *self) * @self: Self * @relpath: Path * @unix_mode: Unix mode - * @out_label: (allow-none) (out) (transfer full): Return location for security context + * @out_label: (nullable) (out) (transfer full): Return location for security context * @cancellable: Cancellable * @error: Error * @@ -558,13 +541,10 @@ ostree_sepolicy_get_csum (OstreeSePolicy *self) * will be returned. */ gboolean -ostree_sepolicy_get_label (OstreeSePolicy *self, - const char *relpath, - guint32 unix_mode, - char **out_label, - GCancellable *cancellable, - GError **error) +ostree_sepolicy_get_label (OstreeSePolicy *self, const char *relpath, guint32 unix_mode, + char **out_label, GCancellable *cancellable, GError **error) { + *out_label = NULL; #ifdef HAVE_SELINUX /* Early return if no policy */ if (!self->selinux_hnd) @@ -600,33 +580,27 @@ ostree_sepolicy_get_label (OstreeSePolicy *self, * ostree_sepolicy_restorecon: * @self: Self * @path: Path string to use for policy lookup - * @info: (allow-none): File attributes + * @info: (nullable): File attributes * @target: Physical path to target file * @flags: Flags controlling behavior - * @out_new_label: (allow-none) (out): New label, or %NULL if unchanged + * @out_new_label: (nullable) (optional) (out): New label, or %NULL if unchanged * @cancellable: Cancellable * @error: Error * * Reset the security context of @target based on the SELinux policy. */ gboolean -ostree_sepolicy_restorecon (OstreeSePolicy *self, - const char *path, - GFileInfo *info, - GFile *target, - OstreeSePolicyRestoreconFlags flags, - char **out_new_label, - GCancellable *cancellable, - GError **error) +ostree_sepolicy_restorecon (OstreeSePolicy *self, const char *path, GFileInfo *info, GFile *target, + OstreeSePolicyRestoreconFlags flags, char **out_new_label, + GCancellable *cancellable, GError **error) { #ifdef HAVE_SELINUX - g_autoptr(GFileInfo) src_info = NULL; + g_autoptr (GFileInfo) src_info = NULL; if (info != NULL) src_info = g_object_ref (info); else { - src_info = g_file_query_info (target, "unix::mode", - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + src_info = g_file_query_info (target, "unix::mode", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!src_info) return FALSE; @@ -636,8 +610,7 @@ ostree_sepolicy_restorecon (OstreeSePolicy *self, if (flags & OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING) { char *existing_con = NULL; - if (lgetfilecon_raw (gs_file_get_path_cached (target), &existing_con) > 0 - && existing_con) + if (lgetfilecon_raw (gs_file_get_path_cached (target), &existing_con) > 0 && existing_con) { do_relabel = FALSE; freecon (existing_con); @@ -649,8 +622,7 @@ ostree_sepolicy_restorecon (OstreeSePolicy *self, { if (!ostree_sepolicy_get_label (self, path, g_file_info_get_attribute_uint32 (src_info, "unix::mode"), - &label, - cancellable, error)) + &label, cancellable, error)) return FALSE; if (!label) @@ -680,10 +652,8 @@ ostree_sepolicy_restorecon (OstreeSePolicy *self, * */ gboolean -ostree_sepolicy_setfscreatecon (OstreeSePolicy *self, - const char *path, - guint32 mode, - GError **error) +ostree_sepolicy_setfscreatecon (OstreeSePolicy *self, const char *path, guint32 mode, + GError **error) { #ifdef HAVE_SELINUX g_autofree char *label = NULL; @@ -725,11 +695,8 @@ ostree_sepolicy_fscreatecon_cleanup (void **unused) * g_auto() cleanup. May be made public later. */ gboolean -_ostree_sepolicy_preparefscreatecon (OstreeSepolicyFsCreatecon *con, - OstreeSePolicy *self, - const char *path, - guint32 mode, - GError **error) +_ostree_sepolicy_preparefscreatecon (OstreeSepolicyFsCreatecon *con, OstreeSePolicy *self, + const char *path, guint32 mode, GError **error) { if (!self || ostree_sepolicy_get_name (self) == NULL) return TRUE; @@ -767,10 +734,9 @@ _ostree_filter_selinux_xattr (GVariant *xattrs) for (guint i = 0; i < n; i++) { const char *name = NULL; - g_autoptr(GVariant) value = NULL; + g_autoptr (GVariant) value = NULL; - g_variant_get_child (xattrs, i, "(^&ay@ay)", - &name, &value); + g_variant_get_child (xattrs, i, "(^&ay@ay)", &name, &value); if (strcmp (name, "security.selinux") == 0) continue; @@ -780,9 +746,7 @@ _ostree_filter_selinux_xattr (GVariant *xattrs) have_xattrs = TRUE; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)")); } - g_variant_builder_add (&builder, "(@ay@ay)", - g_variant_new_bytestring (name), - value); + g_variant_builder_add (&builder, "(@ay@ay)", g_variant_new_bytestring (name), value); } /* Canonicalize zero length to NULL for efficiency */ if (!have_xattrs) diff --git a/src/libostree/ostree-sepolicy.h b/src/libostree/ostree-sepolicy.h index 3534a53..2098456 100644 --- a/src/libostree/ostree-sepolicy.h +++ b/src/libostree/ostree-sepolicy.h @@ -23,33 +23,26 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_SEPOLICY ostree_sepolicy_get_type() +#define OSTREE_TYPE_SEPOLICY ostree_sepolicy_get_type () #define OSTREE_SEPOLICY(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_SEPOLICY, OstreeSePolicy)) -#define OSTREE_IS_SEPOLICY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_SEPOLICY)) +#define OSTREE_IS_SEPOLICY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_SEPOLICY)) _OSTREE_PUBLIC GType ostree_sepolicy_get_type (void); _OSTREE_PUBLIC -OstreeSePolicy* ostree_sepolicy_new (GFile *path, - GCancellable *cancellable, - GError **error); +OstreeSePolicy *ostree_sepolicy_new (GFile *path, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeSePolicy* ostree_sepolicy_new_at (int rootfs_dfd, - GCancellable *cancellable, - GError **error); +OstreeSePolicy *ostree_sepolicy_new_at (int rootfs_dfd, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -OstreeSePolicy* ostree_sepolicy_new_from_commit (OstreeRepo *repo, - const char *rev, - GCancellable *cancellable, - GError **error); +OstreeSePolicy *ostree_sepolicy_new_from_commit (OstreeRepo *repo, const char *rev, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -GFile * ostree_sepolicy_get_path (OstreeSePolicy *self); +GFile *ostree_sepolicy_get_path (OstreeSePolicy *self); _OSTREE_PUBLIC const char *ostree_sepolicy_get_name (OstreeSePolicy *self); @@ -58,38 +51,30 @@ _OSTREE_PUBLIC const char *ostree_sepolicy_get_csum (OstreeSePolicy *self); _OSTREE_PUBLIC -gboolean ostree_sepolicy_get_label (OstreeSePolicy *self, - const char *relpath, - guint32 unix_mode, - char **out_label, - GCancellable *cancellable, - GError **error); - -typedef enum { +gboolean ostree_sepolicy_get_label (OstreeSePolicy *self, const char *relpath, guint32 unix_mode, + char **out_label, GCancellable *cancellable, GError **error); + +typedef enum +{ OSTREE_SEPOLICY_RESTORECON_FLAGS_NONE, OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL = (1 << 0), OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING = (1 << 1) } OstreeSePolicyRestoreconFlags; _OSTREE_PUBLIC -gboolean ostree_sepolicy_restorecon (OstreeSePolicy *self, - const char *path, - GFileInfo *info, - GFile *target, - OstreeSePolicyRestoreconFlags flags, - char **out_new_label, - GCancellable *cancellable, - GError **error); +gboolean ostree_sepolicy_restorecon (OstreeSePolicy *self, const char *path, GFileInfo *info, + GFile *target, OstreeSePolicyRestoreconFlags flags, + char **out_new_label, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_sepolicy_setfscreatecon (OstreeSePolicy *self, - const char *path, - guint32 mode, - GError **error); +gboolean ostree_sepolicy_setfscreatecon (OstreeSePolicy *self, const char *path, guint32 mode, + GError **error); _OSTREE_PUBLIC void ostree_sepolicy_fscreatecon_cleanup (void **unused); -#define ostree_cleanup_sepolicy_fscreatecon __attribute__ ((cleanup(ostree_sepolicy_fscreatecon_cleanup))) +#define ostree_cleanup_sepolicy_fscreatecon \ + __attribute__ ((cleanup (ostree_sepolicy_fscreatecon_cleanup))) G_END_DECLS diff --git a/src/libostree/ostree-sign-dummy.c b/src/libostree/ostree-sign-dummy.c index 562413e..fdd6ca5 100644 --- a/src/libostree/ostree-sign-dummy.c +++ b/src/libostree/ostree-sign-dummy.c @@ -22,8 +22,8 @@ #include "config.h" -#include #include "ostree-sign-dummy.h" +#include #include #undef G_LOG_DOMAIN @@ -45,11 +45,10 @@ struct _OstreeSignDummy G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSignDummy, g_object_unref) #endif -static void -ostree_sign_dummy_iface_init (OstreeSignInterface *self); +static void ostree_sign_dummy_iface_init (OstreeSignInterface *self); G_DEFINE_TYPE_WITH_CODE (OstreeSignDummy, _ostree_sign_dummy, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_SIGN, ostree_sign_dummy_iface_init)); + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_SIGN, ostree_sign_dummy_iface_init)); static gboolean check_dummy_sign_enabled (GError **error) @@ -87,73 +86,74 @@ _ostree_sign_dummy_init (OstreeSignDummy *self) self->pk_ascii = NULL; } -gboolean ostree_sign_dummy_set_sk (OstreeSign *self, GVariant *key, GError **error) +gboolean +ostree_sign_dummy_set_sk (OstreeSign *self, GVariant *key, GError **error) { if (!check_dummy_sign_enabled (error)) return FALSE; - OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private(OSTREE_SIGN_DUMMY(self)); + OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private (OSTREE_SIGN_DUMMY (self)); - g_free(sign->sk_ascii); + g_free (sign->sk_ascii); sign->sk_ascii = g_variant_dup_string (key, 0); return TRUE; } -gboolean ostree_sign_dummy_set_pk (OstreeSign *self, GVariant *key, GError **error) +gboolean +ostree_sign_dummy_set_pk (OstreeSign *self, GVariant *key, GError **error) { - OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private(OSTREE_SIGN_DUMMY(self)); + OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private (OSTREE_SIGN_DUMMY (self)); - g_free(sign->pk_ascii); + g_free (sign->pk_ascii); sign->pk_ascii = g_variant_dup_string (key, 0); return TRUE; } -gboolean ostree_sign_dummy_data (OstreeSign *self, - GBytes *data, - GBytes **signature, - GCancellable *cancellable, - GError **error) +gboolean +ostree_sign_dummy_data (OstreeSign *self, GBytes *data, GBytes **signature, + GCancellable *cancellable, GError **error) { if (!check_dummy_sign_enabled (error)) return FALSE; g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); - OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private(OSTREE_SIGN_DUMMY(self)); + OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private (OSTREE_SIGN_DUMMY (self)); - *signature = g_bytes_new (sign->sk_ascii, strlen(sign->sk_ascii)); + *signature = g_bytes_new (sign->sk_ascii, strlen (sign->sk_ascii)); return TRUE; } -const gchar * ostree_sign_dummy_get_name (OstreeSign *self) +const gchar * +ostree_sign_dummy_get_name (OstreeSign *self) { g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); return OSTREE_SIGN_DUMMY_NAME; } -const gchar * ostree_sign_dummy_metadata_key (OstreeSign *self) +const gchar * +ostree_sign_dummy_metadata_key (OstreeSign *self) { return OSTREE_SIGN_METADATA_DUMMY_KEY; } -const gchar * ostree_sign_dummy_metadata_format (OstreeSign *self) +const gchar * +ostree_sign_dummy_metadata_format (OstreeSign *self) { return OSTREE_SIGN_METADATA_DUMMY_TYPE; } -gboolean ostree_sign_dummy_data_verify (OstreeSign *self, - GBytes *data, - GVariant *signatures, - char **out_success_message, - GError **error) +gboolean +ostree_sign_dummy_data_verify (OstreeSign *self, GBytes *data, GVariant *signatures, + char **out_success_message, GError **error) { if (!check_dummy_sign_enabled (error)) return FALSE; @@ -161,27 +161,27 @@ gboolean ostree_sign_dummy_data_verify (OstreeSign *self, g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); g_return_val_if_fail (data != NULL, FALSE); - OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private(OSTREE_SIGN_DUMMY(self)); + OstreeSignDummy *sign = _ostree_sign_dummy_get_instance_private (OSTREE_SIGN_DUMMY (self)); if (signatures == NULL) return glnx_throw (error, "signature: dummy: commit have no signatures of my type"); - if (!g_variant_is_of_type (signatures, (GVariantType *) OSTREE_SIGN_METADATA_DUMMY_TYPE)) + if (!g_variant_is_of_type (signatures, (GVariantType *)OSTREE_SIGN_METADATA_DUMMY_TYPE)) return glnx_throw (error, "signature: dummy: wrong type passed for verification"); - gsize n = g_variant_n_children(signatures); + gsize n = g_variant_n_children (signatures); for (gsize i = 0; i < n; i++) { g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i); - g_autoptr (GBytes) signature = g_variant_get_data_as_bytes(child); + g_autoptr (GBytes) signature = g_variant_get_data_as_bytes (child); gsize sign_size = 0; g_bytes_get_data (signature, &sign_size); - g_autofree gchar *sign_ascii = g_strndup(g_bytes_get_data (signature, NULL), sign_size); - g_debug("Read signature %d: %s", (gint)i, sign_ascii); - g_debug("Stored signature %d: %s", (gint)i, sign->pk_ascii); + g_autofree gchar *sign_ascii = g_strndup (g_bytes_get_data (signature, NULL), sign_size); + g_debug ("Read signature %d: %s", (gint)i, sign_ascii); + g_debug ("Stored signature %d: %s", (gint)i, sign->pk_ascii); - if (!g_strcmp0(sign_ascii, sign->pk_ascii)) + if (!g_strcmp0 (sign_ascii, sign->pk_ascii)) { if (out_success_message) *out_success_message = g_strdup ("dummy: Signature verified"); diff --git a/src/libostree/ostree-sign-dummy.h b/src/libostree/ostree-sign-dummy.h index 3f4d764..b13dbd1 100644 --- a/src/libostree/ostree-sign-dummy.h +++ b/src/libostree/ostree-sign-dummy.h @@ -34,10 +34,21 @@ GType _ostree_sign_dummy_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeSignDummy OstreeSignDummy; -typedef struct { GObjectClass parent_class; } OstreeSignDummyClass; - -static inline OstreeSignDummy *OSTREE_SIGN_DUMMY (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, _ostree_sign_dummy_get_type (), OstreeSignDummy); } -static inline gboolean OSTREE_IS_SIGN_DUMMY (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, _ostree_sign_dummy_get_type ()); } +typedef struct +{ + GObjectClass parent_class; +} OstreeSignDummyClass; + +static inline OstreeSignDummy * +OSTREE_SIGN_DUMMY (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, _ostree_sign_dummy_get_type (), OstreeSignDummy); +} +static inline gboolean +OSTREE_IS_SIGN_DUMMY (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, _ostree_sign_dummy_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS @@ -50,26 +61,19 @@ G_DECLARE_FINAL_TYPE (OstreeSignDummy, GObject) */ -const gchar * ostree_sign_dummy_get_name (OstreeSign *self); +const gchar *ostree_sign_dummy_get_name (OstreeSign *self); -gboolean ostree_sign_dummy_data (OstreeSign *self, - GBytes *data, - GBytes **signature, - GCancellable *cancellable, - GError **error); +gboolean ostree_sign_dummy_data (OstreeSign *self, GBytes *data, GBytes **signature, + GCancellable *cancellable, GError **error); -gboolean ostree_sign_dummy_data_verify (OstreeSign *self, - GBytes *data, - GVariant *signatures, - char **success_message, - GError **error); +gboolean ostree_sign_dummy_data_verify (OstreeSign *self, GBytes *data, GVariant *signatures, + char **success_message, GError **error); -const gchar * ostree_sign_dummy_metadata_key (OstreeSign *self); -const gchar * ostree_sign_dummy_metadata_format (OstreeSign *self); +const gchar *ostree_sign_dummy_metadata_key (OstreeSign *self); +const gchar *ostree_sign_dummy_metadata_format (OstreeSign *self); gboolean ostree_sign_dummy_set_sk (OstreeSign *self, GVariant *key, GError **error); gboolean ostree_sign_dummy_set_pk (OstreeSign *self, GVariant *key, GError **error); gboolean ostree_sign_dummy_add_pk (OstreeSign *self, GVariant *key, GError **error); G_END_DECLS - diff --git a/src/libostree/ostree-sign-ed25519.c b/src/libostree/ostree-sign-ed25519.c index 809ffe8..cfe1f65 100644 --- a/src/libostree/ostree-sign-ed25519.c +++ b/src/libostree/ostree-sign-ed25519.c @@ -23,19 +23,19 @@ #include "config.h" -#include #include "ostree-sign-ed25519.h" -#ifdef HAVE_LIBSODIUM -#include -#endif +#include "otcore.h" +#include +#include #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "OSTreeSign" #define OSTREE_SIGN_ED25519_NAME "ed25519" -#define OSTREE_SIGN_METADATA_ED25519_KEY "ostree.sign.ed25519" -#define OSTREE_SIGN_METADATA_ED25519_TYPE "aay" +#define OSTREE_SIGN_ED25519_SEED_SIZE 32U +#define OSTREE_SIGN_ED25519_SECKEY_SIZE \ + (OSTREE_SIGN_ED25519_SEED_SIZE + OSTREE_SIGN_ED25519_PUBKEY_SIZE) typedef enum { @@ -48,20 +48,19 @@ struct _OstreeSignEd25519 { GObject parent; ed25519_state state; - guchar *secret_key; - GList *public_keys; - GList *revoked_keys; + guchar *secret_key; /* malloc'd buffer of length OSTREE_SIGN_ED25519_SECKEY_SIZE */ + GList *public_keys; /* malloc'd buffer of length OSTREE_SIGN_ED25519_PUBKEY_SIZE */ + GList *revoked_keys; /* malloc'd buffer of length OSTREE_SIGN_ED25519_PUBKEY_SIZE */ }; #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSignEd25519, g_object_unref) #endif -static void -ostree_sign_ed25519_iface_init (OstreeSignInterface *self); +static void ostree_sign_ed25519_iface_init (OstreeSignInterface *self); G_DEFINE_TYPE_WITH_CODE (OstreeSignEd25519, _ostree_sign_ed25519, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (OSTREE_TYPE_SIGN, ostree_sign_ed25519_iface_init)); + G_IMPLEMENT_INTERFACE (OSTREE_TYPE_SIGN, ostree_sign_ed25519_iface_init)); static void ostree_sign_ed25519_iface_init (OstreeSignInterface *self) @@ -93,12 +92,22 @@ _ostree_sign_ed25519_init (OstreeSignEd25519 *self) self->public_keys = NULL; self->revoked_keys = NULL; -#ifdef HAVE_LIBSODIUM - if (sodium_init() < 0) - self->state = ED25519_FAILED_INITIALIZATION; -#else +#if !(defined(USE_OPENSSL) || defined(USE_LIBSODIUM)) self->state = ED25519_NOT_SUPPORTED; -#endif /* HAVE_LIBSODIUM */ +#else + if (!otcore_ed25519_init ()) + self->state = ED25519_FAILED_INITIALIZATION; +#endif +} + +static gboolean +validate_length (gsize found, gsize expected, GError **error) +{ + if (found == expected) + return TRUE; + return glnx_throw ( + error, "Ill-formed input: expected %" G_GSIZE_FORMAT " bytes, got %" G_GSIZE_FORMAT " bytes", + found, expected); } static gboolean @@ -109,71 +118,80 @@ _ostree_sign_ed25519_is_initialized (OstreeSignEd25519 *self, GError **error) case ED25519_OK: break; case ED25519_NOT_SUPPORTED: - return glnx_throw(error, "ed25519: engine is not supported"); + return glnx_throw (error, "ed25519: engine is not supported"); case ED25519_FAILED_INITIALIZATION: - return glnx_throw(error, "ed25519: libsodium library isn't initialized properly"); + return glnx_throw (error, "ed25519: crypto library isn't initialized properly"); } return TRUE; } -gboolean ostree_sign_ed25519_data (OstreeSign *self, - GBytes *data, - GBytes **signature, - GCancellable *cancellable, - GError **error) +gboolean +ostree_sign_ed25519_data (OstreeSign *self, GBytes *data, GBytes **signature, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); - OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self)); - -#ifdef HAVE_LIBSODIUM - guchar *sig = NULL; -#endif + g_assert (OSTREE_IS_SIGN (self)); + OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); if (!_ostree_sign_ed25519_is_initialized (sign, error)) - return FALSE; + return FALSE; if (sign->secret_key == NULL) return glnx_throw (error, "Not able to sign: secret key is not set"); -#ifdef HAVE_LIBSODIUM unsigned long long sig_size = 0; + g_autofree guchar *sig = g_malloc0 (OSTREE_SIGN_ED25519_SIG_SIZE); - sig = g_malloc0(crypto_sign_BYTES); - - if (crypto_sign_detached (sig, - &sig_size, - g_bytes_get_data (data, NULL), - g_bytes_get_size (data), +#if defined(USE_LIBSODIUM) + if (crypto_sign_detached (sig, &sig_size, g_bytes_get_data (data, NULL), g_bytes_get_size (data), sign->secret_key)) + sig_size = 0; +#elif defined(USE_OPENSSL) + EVP_MD_CTX *ctx = EVP_MD_CTX_new (); + if (!ctx) + return glnx_throw (error, "openssl: failed to allocate context"); + EVP_PKEY *pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, sign->secret_key, + OSTREE_SIGN_ED25519_SEED_SIZE); + if (!pkey) { - return glnx_throw (error, "Not able to sign: fail to sign the object"); + EVP_MD_CTX_free (ctx); + return glnx_throw (error, "openssl: Failed to initialize ed5519 key"); } - *signature = g_bytes_new_take (sig, sig_size); + size_t len; + if (EVP_DigestSignInit (ctx, NULL, NULL, NULL, pkey) + && EVP_DigestSign (ctx, sig, &len, g_bytes_get_data (data, NULL), g_bytes_get_size (data))) + sig_size = len; + + EVP_PKEY_free (pkey); + EVP_MD_CTX_free (ctx); + +#endif + + if (sig_size == 0) + return glnx_throw (error, "Failed to sign"); + + *signature = g_bytes_new_take (g_steal_pointer (&sig), sig_size); return TRUE; -#endif /* HAVE_LIBSODIUM */ - return FALSE; } -#ifdef HAVE_LIBSODIUM static gint -_compare_ed25519_keys(gconstpointer a, gconstpointer b) { - return memcmp (a, b, crypto_sign_PUBLICKEYBYTES); +_compare_ed25519_keys (gconstpointer a, gconstpointer b) +{ + return memcmp (a, b, OSTREE_SIGN_ED25519_PUBKEY_SIZE); } -#endif -gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, - GBytes *data, - GVariant *signatures, - char **out_success_message, - GError **error) +gboolean +ostree_sign_ed25519_data_verify (OstreeSign *self, GBytes *data, GVariant *signatures, + char **out_success_message, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); - g_return_val_if_fail (data != NULL, FALSE); + g_assert (OSTREE_IS_SIGN (self)); - OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self)); + if (data == NULL) + return glnx_throw (error, "ed25519: unable to verify NULL data"); + + OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); if (!_ostree_sign_ed25519_is_initialized (sign, error)) return FALSE; @@ -181,10 +199,9 @@ gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, if (signatures == NULL) return glnx_throw (error, "ed25519: commit have no signatures of my type"); - if (!g_variant_is_of_type (signatures, (GVariantType *) OSTREE_SIGN_METADATA_ED25519_TYPE)) + if (!g_variant_is_of_type (signatures, (GVariantType *)OSTREE_SIGN_METADATA_ED25519_TYPE)) return glnx_throw (error, "ed25519: wrong type passed for verification"); -#ifdef HAVE_LIBSODIUM /* If no keys pre-loaded then, * try to load public keys from storage(s) */ if (sign->public_keys == NULL) @@ -199,37 +216,41 @@ gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, return FALSE; } - g_debug ("verify: data hash = 0x%x", g_bytes_hash(data)); + g_debug ("verify: data hash = 0x%x", g_bytes_hash (data)); - g_autoptr(GString) invalid_signatures = NULL; + g_autoptr (GString) invalid_signatures = NULL; guint n_invalid_signatures = 0; - for (gsize i = 0; i < g_variant_n_children(signatures); i++) + for (gsize i = 0; i < g_variant_n_children (signatures); i++) { g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i); - g_autoptr (GBytes) signature = g_variant_get_data_as_bytes(child); + g_autoptr (GBytes) signature = g_variant_get_data_as_bytes (child); - g_autofree char * hex = g_malloc0 (crypto_sign_PUBLICKEYBYTES*2 + 1); + if (!validate_length (g_bytes_get_size (signature), OSTREE_SIGN_ED25519_SIG_SIZE, error)) + return glnx_prefix_error (error, "Invalid signature"); - g_debug("Read signature %d: %s", (gint)i, g_variant_print(child, TRUE)); + g_autofree char *hex = g_malloc0 (OSTREE_SIGN_ED25519_PUBKEY_SIZE * 2 + 1); - for (GList *public_key = sign->public_keys; - public_key != NULL; - public_key = public_key->next) - { + g_debug ("Read signature %d: %s", (gint)i, g_variant_print (child, TRUE)); + for (GList *public_key = sign->public_keys; public_key != NULL; public_key = public_key->next) + { /* TODO: use non-list for tons of revoked keys? */ - if (g_list_find_custom (sign->revoked_keys, public_key->data, _compare_ed25519_keys) != NULL) + if (g_list_find_custom (sign->revoked_keys, public_key->data, _compare_ed25519_keys) + != NULL) { - g_debug("Skip revoked key '%s'", - sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, public_key->data, crypto_sign_PUBLICKEYBYTES)); + ot_bin2hex (hex, public_key->data, OSTREE_SIGN_ED25519_PUBKEY_SIZE); + g_debug ("Skip revoked key '%s'", hex); continue; } - if (crypto_sign_verify_detached ((guchar *) g_variant_get_data (child), - g_bytes_get_data (data, NULL), - g_bytes_get_size (data), - public_key->data) != 0) + bool valid = false; + // Wrap the pubkey in a GBytes as that's what this API wants + g_autoptr (GBytes) public_key_bytes + = g_bytes_new_static (public_key->data, OSTREE_SIGN_ED25519_PUBKEY_SIZE); + if (!otcore_validate_ed25519_signature (data, public_key_bytes, signature, &valid, error)) + return FALSE; + if (!valid) { /* Incorrect signature! */ if (invalid_signatures == NULL) @@ -237,16 +258,16 @@ gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, else g_string_append (invalid_signatures, "; "); n_invalid_signatures++; - g_string_append_printf (invalid_signatures, "key '%s'", - sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, public_key->data, crypto_sign_PUBLICKEYBYTES)); + ot_bin2hex (hex, public_key->data, OSTREE_SIGN_ED25519_PUBKEY_SIZE); + g_string_append_printf (invalid_signatures, "key '%s'", hex); } else { if (out_success_message) { - *out_success_message = - g_strdup_printf ("ed25519: Signature verified successfully with key '%s'", - sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, public_key->data, crypto_sign_PUBLICKEYBYTES)); + ot_bin2hex (hex, public_key->data, OSTREE_SIGN_ED25519_PUBKEY_SIZE); + *out_success_message = g_strdup_printf ( + "ed25519: Signature verified successfully with key '%s'", hex); } return TRUE; } @@ -260,52 +281,53 @@ gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, * cap a reasonable error message at 3. */ if (n_invalid_signatures > 3) - return glnx_throw (error, "ed25519: Signature couldn't be verified; tried %u keys", n_invalid_signatures); - return glnx_throw (error, "ed25519: Signature couldn't be verified with: %s", invalid_signatures->str); + return glnx_throw (error, "ed25519: Signature couldn't be verified; tried %u keys", + n_invalid_signatures); + return glnx_throw (error, "ed25519: Signature couldn't be verified with: %s", + invalid_signatures->str); } return glnx_throw (error, "ed25519: no signatures found"); -#endif /* HAVE_LIBSODIUM */ - - return FALSE; } -const gchar * ostree_sign_ed25519_get_name (OstreeSign *self) +const gchar * +ostree_sign_ed25519_get_name (OstreeSign *self) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); return OSTREE_SIGN_ED25519_NAME; } -const gchar * ostree_sign_ed25519_metadata_key (OstreeSign *self) +const gchar * +ostree_sign_ed25519_metadata_key (OstreeSign *self) { return OSTREE_SIGN_METADATA_ED25519_KEY; } -const gchar * ostree_sign_ed25519_metadata_format (OstreeSign *self) +const gchar * +ostree_sign_ed25519_metadata_format (OstreeSign *self) { return OSTREE_SIGN_METADATA_ED25519_TYPE; } -gboolean ostree_sign_ed25519_clear_keys (OstreeSign *self, - GError **error) +gboolean +ostree_sign_ed25519_clear_keys (OstreeSign *self, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); - OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self)); + OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); if (!_ostree_sign_ed25519_is_initialized (sign, error)) return FALSE; -#ifdef HAVE_LIBSODIUM /* Clear secret key */ if (sign->secret_key != NULL) - { - memset (sign->secret_key, 0, crypto_sign_SECRETKEYBYTES); - g_free (sign->secret_key); - sign->secret_key = NULL; - } + { + memset (sign->secret_key, 0, OSTREE_SIGN_ED25519_SECKEY_SIZE); + g_free (sign->secret_key); + sign->secret_key = NULL; + } /* Clear already loaded trusted keys */ if (sign->public_keys != NULL) @@ -322,62 +344,56 @@ gboolean ostree_sign_ed25519_clear_keys (OstreeSign *self, } return TRUE; -#endif /* HAVE_LIBSODIUM */ - - return FALSE; } /* Support 2 representations: * base64 ascii -- secret key is passed as string * raw key -- key is passed as bytes array * */ -gboolean ostree_sign_ed25519_set_sk (OstreeSign *self, - GVariant *secret_key, - GError **error) +gboolean +ostree_sign_ed25519_set_sk (OstreeSign *self, GVariant *secret_key, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); - + g_assert (OSTREE_IS_SIGN (self)); if (!ostree_sign_ed25519_clear_keys (self, error)) return FALSE; -#ifdef HAVE_LIBSODIUM - OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self)); + OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); gsize n_elements = 0; + g_autofree guchar *secret_key_buf = NULL; if (g_variant_is_of_type (secret_key, G_VARIANT_TYPE_STRING)) { const gchar *sk_ascii = g_variant_get_string (secret_key, NULL); - sign->secret_key = g_base64_decode (sk_ascii, &n_elements); + secret_key_buf = g_base64_decode (sk_ascii, &n_elements); } else if (g_variant_is_of_type (secret_key, G_VARIANT_TYPE_BYTESTRING)) { - sign->secret_key = (guchar *) g_variant_get_fixed_array (secret_key, &n_elements, sizeof(guchar)); + secret_key_buf + = (guchar *)g_variant_get_fixed_array (secret_key, &n_elements, sizeof (guchar)); } else { - return glnx_throw (error, "Unknown ed25519 secret key type"); + return glnx_throw (error, "Unknown ed25519 secret key type"); } - if (n_elements != crypto_sign_SECRETKEYBYTES) - return glnx_throw (error, "Incorrect ed25519 secret key"); + if (!validate_length (n_elements, OSTREE_SIGN_ED25519_SECKEY_SIZE, error)) + return glnx_prefix_error (error, "Invalid ed25519 secret key"); - return TRUE; -#endif /* HAVE_LIBSODIUM */ + sign->secret_key = g_steal_pointer (&secret_key_buf); - return FALSE; + return TRUE; } /* Support 2 representations: * base64 ascii -- public key is passed as string * raw key -- key is passed as bytes array * */ -gboolean ostree_sign_ed25519_set_pk (OstreeSign *self, - GVariant *public_key, - GError **error) +gboolean +ostree_sign_ed25519_set_pk (OstreeSign *self, GVariant *public_key, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); if (!ostree_sign_ed25519_clear_keys (self, error)) return FALSE; @@ -389,96 +405,88 @@ gboolean ostree_sign_ed25519_set_pk (OstreeSign *self, * base64 ascii -- public key is passed as string * raw key -- key is passed as bytes array * */ -gboolean ostree_sign_ed25519_add_pk (OstreeSign *self, - GVariant *public_key, - GError **error) +gboolean +ostree_sign_ed25519_add_pk (OstreeSign *self, GVariant *public_key, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); - OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self)); + OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); if (!_ostree_sign_ed25519_is_initialized (sign, error)) return FALSE; -#ifdef HAVE_LIBSODIUM - gpointer key = NULL; + g_autofree guint8 *key_owned = NULL; + const guint8 *key = NULL; gsize n_elements = 0; if (g_variant_is_of_type (public_key, G_VARIANT_TYPE_STRING)) { const gchar *pk_ascii = g_variant_get_string (public_key, NULL); - key = g_base64_decode (pk_ascii, &n_elements); + key = key_owned = g_base64_decode (pk_ascii, &n_elements); } else if (g_variant_is_of_type (public_key, G_VARIANT_TYPE_BYTESTRING)) { - key = (gpointer) g_variant_get_fixed_array (public_key, &n_elements, sizeof(guchar)); + key = g_variant_get_fixed_array (public_key, &n_elements, sizeof (guchar)); } else { return glnx_throw (error, "Unknown ed25519 public key type"); } - if (n_elements != crypto_sign_PUBLICKEYBYTES) - return glnx_throw (error, "Incorrect ed25519 public key"); + if (!validate_length (n_elements, OSTREE_SIGN_ED25519_PUBKEY_SIZE, error)) + return glnx_prefix_error (error, "Invalid ed25519 public key"); - g_autofree char *hex = g_malloc0 (crypto_sign_PUBLICKEYBYTES*2 + 1); - g_debug ("Read ed25519 public key = %s", sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, key, n_elements)); + g_autofree char *hex = g_malloc0 (OSTREE_SIGN_ED25519_PUBKEY_SIZE * 2 + 1); + ot_bin2hex (hex, key, n_elements); + g_debug ("Read ed25519 public key = %s", hex); if (g_list_find_custom (sign->public_keys, key, _compare_ed25519_keys) == NULL) { - gpointer newkey = g_memdup (key, n_elements); + gpointer newkey = g_memdup2 (key, n_elements); sign->public_keys = g_list_prepend (sign->public_keys, newkey); } -#endif /* HAVE_LIBSODIUM */ return TRUE; } -#ifdef HAVE_LIBSODIUM /* Add revoked public key */ static gboolean -_ed25519_add_revoked (OstreeSign *self, - GVariant *revoked_key, - GError **error) +_ed25519_add_revoked (OstreeSign *self, GVariant *revoked_key, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); if (!g_variant_is_of_type (revoked_key, G_VARIANT_TYPE_STRING)) return glnx_throw (error, "Unknown ed25519 revoked key type"); - OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self)); + OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); const gchar *rk_ascii = g_variant_get_string (revoked_key, NULL); gsize n_elements = 0; - gpointer key = g_base64_decode (rk_ascii, &n_elements); + g_autofree guint8 *key = g_base64_decode (rk_ascii, &n_elements); - if (n_elements != crypto_sign_PUBLICKEYBYTES) - { - return glnx_throw (error, "Incorrect ed25519 revoked key"); - } + if (!validate_length (n_elements, OSTREE_SIGN_ED25519_PUBKEY_SIZE, error)) + return glnx_prefix_error (error, "Incorrect ed25519 revoked key"); - g_autofree char * hex = g_malloc0 (crypto_sign_PUBLICKEYBYTES*2 + 1); - g_debug ("Read ed25519 revoked key = %s", sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, key, n_elements)); + g_autofree char *hex = g_malloc0 (OSTREE_SIGN_ED25519_PUBKEY_SIZE * 2 + 1); + ot_bin2hex (hex, key, n_elements); + g_debug ("Read ed25519 revoked key = %s", hex); if (g_list_find_custom (sign->revoked_keys, key, _compare_ed25519_keys) == NULL) { - gpointer newkey = g_memdup (key, n_elements); + gpointer newkey = g_memdup2 (key, n_elements); sign->revoked_keys = g_list_prepend (sign->revoked_keys, newkey); } return TRUE; } -#endif /* HAVE_LIBSODIUM */ - static gboolean -_load_pk_from_stream (OstreeSign *self, - GDataInputStream *key_data_in, - gboolean trusted, +_load_pk_from_stream (OstreeSign *self, GDataInputStream *key_data_in, gboolean trusted, GError **error) { - g_return_val_if_fail (key_data_in, FALSE); -#ifdef HAVE_LIBSODIUM + if (key_data_in == NULL) + return glnx_throw (error, "ed25519: unable to read from NULL key-data input stream"); + gboolean ret = FALSE; /* Use simple file format with just a list of base64 public keys per line */ @@ -487,7 +495,7 @@ _load_pk_from_stream (OstreeSign *self, gsize len = 0; g_autoptr (GVariant) pk = NULL; gboolean added = FALSE; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; g_autofree char *line = g_data_input_stream_read_line (key_data_in, &len, NULL, &local_error); if (local_error != NULL) @@ -498,7 +506,7 @@ _load_pk_from_stream (OstreeSign *self, if (line == NULL) return ret; - + /* Read the key itself */ /* base64 encoded key */ pk = g_variant_new_string (line); @@ -508,24 +516,18 @@ _load_pk_from_stream (OstreeSign *self, else added = _ed25519_add_revoked (self, pk, error); - g_debug ("%s %s key: %s", - added ? "Added" : "Invalid", - trusted ? "public" : "revoked", - line); + g_debug ("%s %s key: %s", added ? "Added" : "Invalid", trusted ? "public" : "revoked", line); /* Mark what we load at least one key */ if (added) ret = TRUE; } -#endif /* HAVE_LIBSODIUM */ - return FALSE; + + return ret; } static gboolean -_load_pk_from_file (OstreeSign *self, - const gchar *filename, - gboolean trusted, - GError **error) +_load_pk_from_file (OstreeSign *self, const gchar *filename, gboolean trusted, GError **error) { g_debug ("Processing file '%s'", filename); @@ -543,16 +545,14 @@ _load_pk_from_file (OstreeSign *self, key_stream_in = g_file_read (keyfile, NULL, error); if (key_stream_in == NULL) return FALSE; - - key_data_in = g_data_input_stream_new (G_INPUT_STREAM(key_stream_in)); + + key_data_in = g_data_input_stream_new (G_INPUT_STREAM (key_stream_in)); g_assert (key_data_in != NULL); if (!_load_pk_from_stream (self, key_data_in, trusted, error)) { if (error == NULL || *error == NULL) - return glnx_throw (error, - "signature: ed25519: no valid keys in file '%s'", - filename); + return glnx_throw (error, "signature: ed25519: no valid keys in file '%s'", filename); else return FALSE; } @@ -561,10 +561,7 @@ _load_pk_from_file (OstreeSign *self, } static gboolean -_ed25519_load_pk (OstreeSign *self, - GVariant *options, - gboolean trusted, - GError **error) +_ed25519_load_pk (OstreeSign *self, GVariant *options, gboolean trusted, GError **error) { gboolean ret = FALSE; @@ -586,15 +583,14 @@ _ed25519_load_pk (OstreeSign *self, } /* Scan all well-known directories and construct the list with file names to scan keys */ - for (gint i=0; i < base_dirs->len; i++) + for (gint i = 0; i < base_dirs->len; i++) { gchar *base_name = NULL; g_autofree gchar *base_dir = NULL; g_autoptr (GDir) dir = NULL; - base_name = g_build_filename ((gchar *)g_ptr_array_index (base_dirs, i), - trusted ? "trusted.ed25519" : "revoked.ed25519", - NULL); + base_name = g_build_filename ((gchar *)g_ptr_array_index (base_dirs, i), + trusted ? "trusted.ed25519" : "revoked.ed25519", NULL); g_debug ("Check ed25519 keys from file: %s", base_name); g_ptr_array_add (ed25519_files, base_name); @@ -616,14 +612,13 @@ _ed25519_load_pk (OstreeSign *self, } /* Scan all well-known files */ - for (gint i=0; i < ed25519_files->len; i++) + for (gint i = 0; i < ed25519_files->len; i++) { if (!_load_pk_from_file (self, (gchar *)g_ptr_array_index (ed25519_files, i), trusted, error)) { - g_debug ("Problem with loading ed25519 %s keys from `%s`", - trusted ? "public" : "revoked", + g_debug ("Problem with loading ed25519 %s keys from `%s`", trusted ? "public" : "revoked", (gchar *)g_ptr_array_index (ed25519_files, i)); - g_clear_error(error); + g_clear_error (error); } else ret = TRUE; @@ -644,20 +639,18 @@ _ed25519_load_pk (OstreeSign *self, * directories if defaults are not suitable for any reason. */ gboolean -ostree_sign_ed25519_load_pk (OstreeSign *self, - GVariant *options, - GError **error) +ostree_sign_ed25519_load_pk (OstreeSign *self, GVariant *options, GError **error) { const gchar *filename = NULL; - OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self)); + OstreeSignEd25519 *sign = _ostree_sign_ed25519_get_instance_private (OSTREE_SIGN_ED25519 (self)); if (!_ostree_sign_ed25519_is_initialized (sign, error)) return FALSE; /* Read keys only from single file provided */ if (g_variant_lookup (options, "filename", "&s", &filename)) - return _load_pk_from_file (self, filename, TRUE, error); + return _load_pk_from_file (self, filename, TRUE, error); /* Load public keys from well-known directories and files */ if (!_ed25519_load_pk (self, options, TRUE, error)) @@ -668,7 +661,7 @@ ostree_sign_ed25519_load_pk (OstreeSign *self, * empty list of revoked keys. * */ if (!_ed25519_load_pk (self, options, FALSE, error)) - g_clear_error(error); + g_clear_error (error); return TRUE; } diff --git a/src/libostree/ostree-sign-ed25519.h b/src/libostree/ostree-sign-ed25519.h index ec5271d..e8c3df2 100644 --- a/src/libostree/ostree-sign-ed25519.h +++ b/src/libostree/ostree-sign-ed25519.h @@ -34,10 +34,21 @@ GType _ostree_sign_ed25519_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeSignEd25519 OstreeSignEd25519; -typedef struct { GObjectClass parent_class; } OstreeSignEd25519Class; - -static inline OstreeSignEd25519 *OSTREE_SIGN_ED25519 (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, _ostree_sign_ed25519_get_type (), OstreeSignEd25519); } -static inline gboolean OSTREE_IS_SIGN_ED25519 (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, _ostree_sign_ed25519_get_type ()); } +typedef struct +{ + GObjectClass parent_class; +} OstreeSignEd25519Class; + +static inline OstreeSignEd25519 * +OSTREE_SIGN_ED25519 (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, _ostree_sign_ed25519_get_type (), OstreeSignEd25519); +} +static inline gboolean +OSTREE_IS_SIGN_ED25519 (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, _ostree_sign_ed25519_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS @@ -50,40 +61,24 @@ G_DECLARE_FINAL_TYPE (OstreeSignEd25519, GObject) */ -gboolean ostree_sign_ed25519_data (OstreeSign *self, - GBytes *data, - GBytes **signature, - GCancellable *cancellable, - GError **error); +gboolean ostree_sign_ed25519_data (OstreeSign *self, GBytes *data, GBytes **signature, + GCancellable *cancellable, GError **error); -gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, - GBytes *data, - GVariant *signatures, - char **out_success_message, - GError **error); +gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, GBytes *data, GVariant *signatures, + char **out_success_message, GError **error); -const gchar * ostree_sign_ed25519_get_name (OstreeSign *self); -const gchar * ostree_sign_ed25519_metadata_key (OstreeSign *self); -const gchar * ostree_sign_ed25519_metadata_format (OstreeSign *self); +const gchar *ostree_sign_ed25519_get_name (OstreeSign *self); +const gchar *ostree_sign_ed25519_metadata_key (OstreeSign *self); +const gchar *ostree_sign_ed25519_metadata_format (OstreeSign *self); -gboolean ostree_sign_ed25519_clear_keys (OstreeSign *self, - GError **error); +gboolean ostree_sign_ed25519_clear_keys (OstreeSign *self, GError **error); -gboolean ostree_sign_ed25519_set_sk (OstreeSign *self, - GVariant *secret_key, - GError **error); +gboolean ostree_sign_ed25519_set_sk (OstreeSign *self, GVariant *secret_key, GError **error); -gboolean ostree_sign_ed25519_set_pk (OstreeSign *self, - GVariant *public_key, - GError **error); +gboolean ostree_sign_ed25519_set_pk (OstreeSign *self, GVariant *public_key, GError **error); -gboolean ostree_sign_ed25519_add_pk (OstreeSign *self, - GVariant *public_key, - GError **error); +gboolean ostree_sign_ed25519_add_pk (OstreeSign *self, GVariant *public_key, GError **error); -gboolean ostree_sign_ed25519_load_pk (OstreeSign *self, - GVariant *options, - GError **error); +gboolean ostree_sign_ed25519_load_pk (OstreeSign *self, GVariant *options, GError **error); G_END_DECLS - diff --git a/src/libostree/ostree-sign-private.h b/src/libostree/ostree-sign-private.h new file mode 100644 index 0000000..b14dc63 --- /dev/null +++ b/src/libostree/ostree-sign-private.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2023 Endless OS Foundation LLC + * + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * - Dan Nicholson + */ + +#pragma once + +#include + +#include "ostree-sign.h" +#include "ostree-types.h" + +G_BEGIN_DECLS + +gboolean _ostree_sign_summary_at (OstreeSign *self, OstreeRepo *repo, int dir_fd, GVariant *keys, + GCancellable *cancellable, GError **error); + +G_END_DECLS diff --git a/src/libostree/ostree-sign.c b/src/libostree/ostree-sign.c index 16e5d0f..d76271b 100644 --- a/src/libostree/ostree-sign.c +++ b/src/libostree/ostree-sign.c @@ -31,19 +31,18 @@ #include "config.h" -#include -#include -#include #include "libglnx.h" #include "otutil.h" +#include +#include +#include #include "ostree-autocleanups.h" #include "ostree-core.h" -#include "ostree-sign.h" #include "ostree-sign-dummy.h" -#ifdef HAVE_LIBSODIUM #include "ostree-sign-ed25519.h" -#endif +#include "ostree-sign-private.h" +#include "ostree-sign.h" #include "ostree-autocleanups.h" #include "ostree-repo-private.h" @@ -57,20 +56,19 @@ typedef struct GType type; } _sign_type; -_sign_type sign_types[] = -{ -#if defined(HAVE_LIBSODIUM) - {OSTREE_SIGN_NAME_ED25519, 0}, +_sign_type sign_types[] = { +#if defined(HAVE_ED25519) + { OSTREE_SIGN_NAME_ED25519, 0 }, #endif - {"dummy", 0} + { "dummy", 0 } }; enum { -#if defined(HAVE_LIBSODIUM) - SIGN_ED25519, +#if defined(HAVE_ED25519) + SIGN_ED25519, #endif - SIGN_DUMMY + SIGN_DUMMY }; G_DEFINE_INTERFACE (OstreeSign, ostree_sign, G_TYPE_OBJECT) @@ -96,8 +94,11 @@ ostree_sign_default_init (OstreeSignInterface *iface) const gchar * ostree_sign_metadata_key (OstreeSign *self) { + g_assert (OSTREE_IS_SIGN (self)); + + if (OSTREE_SIGN_GET_IFACE (self)->metadata_key == NULL) + return NULL; - g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->metadata_key != NULL, NULL); return OSTREE_SIGN_GET_IFACE (self)->metadata_key (self); } @@ -116,8 +117,11 @@ ostree_sign_metadata_key (OstreeSign *self) const gchar * ostree_sign_metadata_format (OstreeSign *self) { + g_assert (OSTREE_IS_SIGN (self)); + + if (OSTREE_SIGN_GET_IFACE (self)->metadata_format == NULL) + return NULL; - g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->metadata_format != NULL, NULL); return OSTREE_SIGN_GET_IFACE (self)->metadata_format (self); } @@ -133,10 +137,10 @@ ostree_sign_metadata_format (OstreeSign *self) * Since: 2020.2 */ gboolean -ostree_sign_clear_keys (OstreeSign *self, - GError **error) +ostree_sign_clear_keys (OstreeSign *self, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); + if (OSTREE_SIGN_GET_IFACE (self)->clear_keys == NULL) return glnx_throw (error, "not implemented"); @@ -159,11 +163,10 @@ ostree_sign_clear_keys (OstreeSign *self, * Since: 2020.2 */ gboolean -ostree_sign_set_sk (OstreeSign *self, - GVariant *secret_key, - GError **error) +ostree_sign_set_sk (OstreeSign *self, GVariant *secret_key, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); + if (OSTREE_SIGN_GET_IFACE (self)->set_sk == NULL) return glnx_throw (error, "not implemented"); @@ -187,11 +190,10 @@ ostree_sign_set_sk (OstreeSign *self, * Since: 2020.2 */ gboolean -ostree_sign_set_pk (OstreeSign *self, - GVariant *public_key, - GError **error) +ostree_sign_set_pk (OstreeSign *self, GVariant *public_key, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); + if (OSTREE_SIGN_GET_IFACE (self)->set_pk == NULL) return glnx_throw (error, "not implemented"); @@ -215,11 +217,10 @@ ostree_sign_set_pk (OstreeSign *self, * Since: 2020.2 */ gboolean -ostree_sign_add_pk (OstreeSign *self, - GVariant *public_key, - GError **error) +ostree_sign_add_pk (OstreeSign *self, GVariant *public_key, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); + if (OSTREE_SIGN_GET_IFACE (self)->add_pk == NULL) return glnx_throw (error, "not implemented"); @@ -254,11 +255,10 @@ ostree_sign_add_pk (OstreeSign *self, * what the signing software will load the secret key in it's own way. */ gboolean -ostree_sign_load_pk (OstreeSign *self, - GVariant *options, - GError **error) +ostree_sign_load_pk (OstreeSign *self, GVariant *options, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); + if (OSTREE_SIGN_GET_IFACE (self)->load_pk == NULL) return glnx_throw (error, "not implemented"); @@ -284,14 +284,11 @@ ostree_sign_load_pk (OstreeSign *self, * Since: 2020.2 */ gboolean -ostree_sign_data (OstreeSign *self, - GBytes *data, - GBytes **signature, - GCancellable *cancellable, +ostree_sign_data (OstreeSign *self, GBytes *data, GBytes **signature, GCancellable *cancellable, GError **error) { + g_assert (OSTREE_IS_SIGN (self)); - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); if (OSTREE_SIGN_GET_IFACE (self)->data == NULL) return glnx_throw (error, "not implemented"); @@ -303,7 +300,8 @@ ostree_sign_data (OstreeSign *self, * @self: an #OstreeSign object * @data: the raw data to check * @signatures: the signatures to be checked - * @out_success_message: (out) (nullable) (optional): success message returned by the signing engine + * @out_success_message: (out) (nullable) (optional): success message returned by the signing + * engine * @error: a #GError * * Verify given data against signatures with pre-loaded public keys. @@ -318,52 +316,51 @@ ostree_sign_data (OstreeSign *self, * Since: 2020.2 */ gboolean -ostree_sign_data_verify (OstreeSign *self, - GBytes *data, - GVariant *signatures, - char **out_success_message, - GError **error) +ostree_sign_data_verify (OstreeSign *self, GBytes *data, GVariant *signatures, + char **out_success_message, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); + if (OSTREE_SIGN_GET_IFACE (self)->data_verify == NULL) return glnx_throw (error, "not implemented"); - return OSTREE_SIGN_GET_IFACE (self)->data_verify(self, data, signatures, out_success_message, error); + return OSTREE_SIGN_GET_IFACE (self)->data_verify (self, data, signatures, out_success_message, + error); } /* * Adopted version of _ostree_detached_metadata_append_gpg_sig () */ static GVariant * -_sign_detached_metadata_append (OstreeSign *self, - GVariant *existing_metadata, - GBytes *signature_bytes) +_sign_detached_metadata_append (OstreeSign *self, GVariant *existing_metadata, + GBytes *signature_bytes, GError **error) { - g_return_val_if_fail (signature_bytes != NULL, FALSE); + g_assert (OSTREE_IS_SIGN (self)); + + if (signature_bytes == NULL) + return glnx_null_throw (error, "Invalid NULL signature bytes"); GVariantDict metadata_dict; - g_autoptr(GVariant) signature_data = NULL; - g_autoptr(GVariantBuilder) signature_builder = NULL; + g_autoptr (GVariant) signature_data = NULL; + g_autoptr (GVariantBuilder) signature_builder = NULL; g_variant_dict_init (&metadata_dict, existing_metadata); - const gchar *signature_key = ostree_sign_metadata_key(self); - GVariantType *signature_format = (GVariantType *) ostree_sign_metadata_format(self); + const gchar *signature_key = ostree_sign_metadata_key (self); + GVariantType *signature_format = (GVariantType *)ostree_sign_metadata_format (self); - signature_data = g_variant_dict_lookup_value (&metadata_dict, - signature_key, - (GVariantType*)signature_format); + signature_data = g_variant_dict_lookup_value (&metadata_dict, signature_key, + (GVariantType *)signature_format); /* signature_data may be NULL */ signature_builder = ot_util_variant_builder_from_variant (signature_data, signature_format); g_variant_builder_add (signature_builder, "@ay", ot_gvariant_new_ay_bytes (signature_bytes)); - g_variant_dict_insert_value (&metadata_dict, - signature_key, + g_variant_dict_insert_value (&metadata_dict, signature_key, g_variant_builder_end (signature_builder)); - return g_variant_ref_sink (g_variant_dict_end (&metadata_dict)); + return g_variant_ref_sink (g_variant_dict_end (&metadata_dict)); } /** @@ -371,7 +368,8 @@ _sign_detached_metadata_append (OstreeSign *self, * @self: an #OstreeSign object * @repo: an #OsreeRepo object * @commit_checksum: SHA256 of given commit to verify - * @out_success_message: (out) (nullable) (optional): success message returned by the signing engine + * @out_success_message: (out) (nullable) (optional): success message returned by the signing + * engine * @cancellable: A #GCancellable * @error: a #GError * @@ -387,50 +385,35 @@ _sign_detached_metadata_append (OstreeSign *self, * Since: 2020.2 */ gboolean -ostree_sign_commit_verify (OstreeSign *self, - OstreeRepo *repo, - const gchar *commit_checksum, - char **out_success_message, - GCancellable *cancellable, - GError **error) +ostree_sign_commit_verify (OstreeSign *self, OstreeRepo *repo, const gchar *commit_checksum, + char **out_success_message, GCancellable *cancellable, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); + g_assert (OSTREE_IS_SIGN (self)); - g_autoptr(GVariant) commit_variant = NULL; + g_autoptr (GVariant) commit_variant = NULL; /* Load the commit */ - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, - commit_checksum, &commit_variant, + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit_variant, error)) return glnx_prefix_error (error, "Failed to read commit"); /* Load the metadata */ - g_autoptr(GVariant) metadata = NULL; - if (!ostree_repo_read_commit_detached_metadata (repo, - commit_checksum, - &metadata, - cancellable, + g_autoptr (GVariant) metadata = NULL; + if (!ostree_repo_read_commit_detached_metadata (repo, commit_checksum, &metadata, cancellable, error)) return glnx_prefix_error (error, "Failed to read detached metadata"); - g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit_variant); + g_autoptr (GBytes) signed_data = g_variant_get_data_as_bytes (commit_variant); - g_autoptr(GVariant) signatures = NULL; + g_autoptr (GVariant) signatures = NULL; - const gchar *signature_key = ostree_sign_metadata_key(self); - GVariantType *signature_format = (GVariantType *) ostree_sign_metadata_format(self); + const gchar *signature_key = ostree_sign_metadata_key (self); + GVariantType *signature_format = (GVariantType *)ostree_sign_metadata_format (self); if (metadata) - signatures = g_variant_lookup_value (metadata, - signature_key, - signature_format); + signatures = g_variant_lookup_value (metadata, signature_key, signature_format); - - return ostree_sign_data_verify (self, - signed_data, - signatures, - out_success_message, - error); + return ostree_sign_data_verify (self, signed_data, signatures, out_success_message, error); } /** @@ -444,13 +427,15 @@ ostree_sign_commit_verify (OstreeSign *self, * * Since: 2020.2 */ -const gchar * +const gchar * ostree_sign_get_name (OstreeSign *self) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), NULL); - g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->get_name != NULL, NULL); + g_assert (OSTREE_IS_SIGN (self)); - return OSTREE_SIGN_GET_IFACE (self)->get_name (self); + if (OSTREE_SIGN_GET_IFACE (self)->get_name == NULL) + return NULL; + + return OSTREE_SIGN_GET_IFACE (self)->get_name (self); } /** @@ -472,43 +457,34 @@ ostree_sign_get_name (OstreeSign *self) * Since: 2020.2 */ gboolean -ostree_sign_commit (OstreeSign *self, - OstreeRepo *repo, - const gchar *commit_checksum, - GCancellable *cancellable, - GError **error) +ostree_sign_commit (OstreeSign *self, OstreeRepo *repo, const gchar *commit_checksum, + GCancellable *cancellable, GError **error) { - g_autoptr(GBytes) commit_data = NULL; - g_autoptr(GBytes) signature = NULL; - g_autoptr(GVariant) commit_variant = NULL; - g_autoptr(GVariant) old_metadata = NULL; - g_autoptr(GVariant) new_metadata = NULL; + g_autoptr (GBytes) commit_data = NULL; + g_autoptr (GBytes) signature = NULL; + g_autoptr (GVariant) commit_variant = NULL; + g_autoptr (GVariant) old_metadata = NULL; + g_autoptr (GVariant) new_metadata = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, - commit_checksum, &commit_variant, error)) + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit_variant, + error)) return glnx_prefix_error (error, "Failed to read commit"); - if (!ostree_repo_read_commit_detached_metadata (repo, - commit_checksum, - &old_metadata, - cancellable, + if (!ostree_repo_read_commit_detached_metadata (repo, commit_checksum, &old_metadata, cancellable, error)) return glnx_prefix_error (error, "Failed to read detached metadata"); commit_data = g_variant_get_data_as_bytes (commit_variant); - if (!ostree_sign_data (self, commit_data, &signature, - cancellable, error)) + if (!ostree_sign_data (self, commit_data, &signature, cancellable, error)) return glnx_prefix_error (error, "Not able to sign the cobject"); - new_metadata = - _sign_detached_metadata_append (self, old_metadata, signature); + new_metadata = _sign_detached_metadata_append (self, old_metadata, signature, error); + if (new_metadata == NULL) + return FALSE; - if (!ostree_repo_write_commit_detached_metadata (repo, - commit_checksum, - new_metadata, - cancellable, + if (!ostree_repo_write_commit_detached_metadata (repo, commit_checksum, new_metadata, cancellable, error)) return FALSE; @@ -528,8 +504,8 @@ ostree_sign_commit (OstreeSign *self, GPtrArray * ostree_sign_get_all (void) { - g_autoptr(GPtrArray) engines = g_ptr_array_new_with_free_func (g_object_unref); - for (guint i = 0; i < G_N_ELEMENTS(sign_types); i++) + g_autoptr (GPtrArray) engines = g_ptr_array_new_with_free_func (g_object_unref); + for (guint i = 0; i < G_N_ELEMENTS (sign_types); i++) { OstreeSign *engine = ostree_sign_get_by_name (sign_types[i].name, NULL); g_assert (engine); @@ -557,61 +533,43 @@ ostree_sign_get_by_name (const gchar *name, GError **error) OstreeSign *sign = NULL; /* Get types if not initialized yet */ -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) if (sign_types[SIGN_ED25519].type == 0) sign_types[SIGN_ED25519].type = OSTREE_TYPE_SIGN_ED25519; #endif if (sign_types[SIGN_DUMMY].type == 0) sign_types[SIGN_DUMMY].type = OSTREE_TYPE_SIGN_DUMMY; - for (gint i=0; i < G_N_ELEMENTS(sign_types); i++) - { - if (g_strcmp0 (name, sign_types[i].name) == 0) - { - g_debug ("Using '%s' signing engine", sign_types[i].name); - sign = g_object_new (sign_types[i].type, NULL); - break; - } - } + for (gint i = 0; i < G_N_ELEMENTS (sign_types); i++) + { + if (g_strcmp0 (name, sign_types[i].name) == 0) + { + g_debug ("Using '%s' signing engine", sign_types[i].name); + sign = g_object_new (sign_types[i].type, NULL); + break; + } + } if (sign == NULL) - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Requested signature type is not implemented"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Requested signature type is not implemented"); return sign; } -/** - * ostree_sign_summary: - * @self: Self - * @repo: ostree repository - * @keys: keys -- GVariant containing keys as GVarints specific to signature type. - * @cancellable: A #GCancellable - * @error: a #GError - * - * Add a signature to a summary file. - * Based on ostree_repo_add_gpg_signature_summary implementation. - * - * Returns: @TRUE if summary file has been signed with all provided keys - * - * Since: 2020.2 - */ gboolean -ostree_sign_summary (OstreeSign *self, - OstreeRepo *repo, - GVariant *keys, - GCancellable *cancellable, - GError **error) +_ostree_sign_summary_at (OstreeSign *self, OstreeRepo *repo, int dir_fd, GVariant *keys, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE); - g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE); + g_assert (OSTREE_IS_SIGN (self)); + g_assert (OSTREE_IS_REPO (repo)); - g_autoptr(GVariant) normalized = NULL; - g_autoptr(GBytes) summary_data = NULL; - g_autoptr(GVariant) metadata = NULL; + g_autoptr (GVariant) normalized = NULL; + g_autoptr (GBytes) summary_data = NULL; + g_autoptr (GVariant) metadata = NULL; glnx_autofd int fd = -1; - if (!glnx_openat_rdonly (repo->repo_dir_fd, "summary", TRUE, &fd, error)) + if (!glnx_openat_rdonly (dir_fd, "summary", TRUE, &fd, error)) return FALSE; summary_data = ot_fd_readall_or_mmap (fd, 0, error); if (!summary_data) @@ -620,17 +578,16 @@ ostree_sign_summary (OstreeSign *self, /* Note that fd is reused below */ glnx_close_fd (&fd); - if (!ot_openat_ignore_enoent (repo->repo_dir_fd, "summary.sig", &fd, error)) + if (!ot_openat_ignore_enoent (dir_fd, "summary.sig", &fd, error)) return FALSE; if (fd >= 0) { - if (!ot_variant_read_fd (fd, 0, OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, - FALSE, &metadata, error)) + if (!ot_variant_read_fd (fd, 0, OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, FALSE, &metadata, error)) return FALSE; } - if (g_variant_n_children(keys) == 0) + if (g_variant_n_children (keys) == 0) return glnx_throw (error, "No keys passed for signing summary"); GVariantIter *iter; @@ -644,27 +601,43 @@ ostree_sign_summary (OstreeSign *self, if (!ostree_sign_set_sk (self, key, error)) return FALSE; - if (!ostree_sign_data (self, - summary_data, - &signature, - cancellable, - error)) + if (!ostree_sign_data (self, summary_data, &signature, cancellable, error)) return FALSE; - g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata); - metadata = - _sign_detached_metadata_append (self, old_metadata, signature); + g_autoptr (GVariant) old_metadata = g_steal_pointer (&metadata); + metadata = _sign_detached_metadata_append (self, old_metadata, signature, error); + if (metadata == NULL) + return FALSE; } g_variant_iter_free (iter); normalized = g_variant_get_normal_form (metadata); - if (!_ostree_repo_file_replace_contents (repo, - repo->repo_dir_fd, - "summary.sig", + if (!_ostree_repo_file_replace_contents (repo, dir_fd, "summary.sig", g_variant_get_data (normalized), - g_variant_get_size (normalized), - cancellable, error)) + g_variant_get_size (normalized), cancellable, error)) return FALSE; return TRUE; } + +/** + * ostree_sign_summary: + * @self: Self + * @repo: ostree repository + * @keys: keys -- GVariant containing keys as GVarints specific to signature type. + * @cancellable: A #GCancellable + * @error: a #GError + * + * Add a signature to a summary file. + * Based on ostree_repo_add_gpg_signature_summary implementation. + * + * Returns: @TRUE if summary file has been signed with all provided keys + * + * Since: 2020.2 + */ +gboolean +ostree_sign_summary (OstreeSign *self, OstreeRepo *repo, GVariant *keys, GCancellable *cancellable, + GError **error) +{ + return _ostree_sign_summary_at (self, repo, repo->repo_dir_fd, keys, cancellable, error); +} diff --git a/src/libostree/ostree-sign.h b/src/libostree/ostree-sign.h index 3a9bcc6..ba84c56 100644 --- a/src/libostree/ostree-sign.h +++ b/src/libostree/ostree-sign.h @@ -24,8 +24,8 @@ #pragma once -#include #include +#include #include "ostree-ref.h" #include "ostree-remote.h" @@ -42,9 +42,21 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeSign OstreeSign; typedef struct _OstreeSignInterface OstreeSignInterface; -static inline OstreeSign *OSTREE_SIGN (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_sign_get_type (), OstreeSign); } -static inline gboolean OSTREE_IS_SIGN (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_sign_get_type ()); } -static inline OstreeSignInterface *OSTREE_SIGN_GET_IFACE (gpointer ptr) { return G_TYPE_INSTANCE_GET_INTERFACE (ptr, ostree_sign_get_type (), OstreeSignInterface); } +static inline OstreeSign * +OSTREE_SIGN (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_sign_get_type (), OstreeSign); +} +static inline gboolean +OSTREE_IS_SIGN (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_sign_get_type ()); +} +static inline OstreeSignInterface * +OSTREE_SIGN_GET_IFACE (gpointer ptr) +{ + return G_TYPE_INSTANCE_GET_INTERFACE (ptr, ostree_sign_get_type (), OstreeSignInterface); +} G_GNUC_END_IGNORE_DEPRECATIONS /** @@ -63,109 +75,68 @@ G_DECLARE_INTERFACE (OstreeSign, ostree_sign, OSTREE, SIGN, GObject) struct _OstreeSignInterface { GTypeInterface g_iface; - const gchar *(* get_name) (OstreeSign *self); - gboolean (* data) (OstreeSign *self, - GBytes *data, - GBytes **signature, - GCancellable *cancellable, - GError **error); - gboolean (* data_verify) (OstreeSign *self, - GBytes *data, - GVariant *signatures, - char **out_success_message, - GError **error); - const gchar *(* metadata_key) (OstreeSign *self); - const gchar *(* metadata_format) (OstreeSign *self); - gboolean (* clear_keys) (OstreeSign *self, - GError **error); - gboolean (* set_sk) (OstreeSign *self, - GVariant *secret_key, - GError **error); - gboolean (* set_pk) (OstreeSign *self, - GVariant *public_key, - GError **error); - gboolean (* add_pk) (OstreeSign *self, - GVariant *public_key, - GError **error); - gboolean (* load_pk) (OstreeSign *self, - GVariant *options, - GError **error); + const gchar *(*get_name) (OstreeSign *self); + gboolean (*data) (OstreeSign *self, GBytes *data, GBytes **signature, GCancellable *cancellable, + GError **error); + gboolean (*data_verify) (OstreeSign *self, GBytes *data, GVariant *signatures, + char **out_success_message, GError **error); + const gchar *(*metadata_key) (OstreeSign *self); + const gchar *(*metadata_format) (OstreeSign *self); + gboolean (*clear_keys) (OstreeSign *self, GError **error); + gboolean (*set_sk) (OstreeSign *self, GVariant *secret_key, GError **error); + gboolean (*set_pk) (OstreeSign *self, GVariant *public_key, GError **error); + gboolean (*add_pk) (OstreeSign *self, GVariant *public_key, GError **error); + gboolean (*load_pk) (OstreeSign *self, GVariant *options, GError **error); }; _OSTREE_PUBLIC -const gchar * ostree_sign_get_name (OstreeSign *self); +const gchar *ostree_sign_get_name (OstreeSign *self); _OSTREE_PUBLIC -gboolean ostree_sign_data (OstreeSign *self, - GBytes *data, - GBytes **signature, - GCancellable *cancellable, - GError **error); +gboolean ostree_sign_data (OstreeSign *self, GBytes *data, GBytes **signature, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_data_verify (OstreeSign *self, - GBytes *data, - GVariant *signatures, - char **out_success_message, - GError **error); +gboolean ostree_sign_data_verify (OstreeSign *self, GBytes *data, GVariant *signatures, + char **out_success_message, GError **error); _OSTREE_PUBLIC -const gchar * ostree_sign_metadata_key (OstreeSign *self); +const gchar *ostree_sign_metadata_key (OstreeSign *self); _OSTREE_PUBLIC -const gchar * ostree_sign_metadata_format (OstreeSign *self); +const gchar *ostree_sign_metadata_format (OstreeSign *self); _OSTREE_PUBLIC -gboolean ostree_sign_commit (OstreeSign *self, - OstreeRepo *repo, - const gchar *commit_checksum, - GCancellable *cancellable, - GError **error); +gboolean ostree_sign_commit (OstreeSign *self, OstreeRepo *repo, const gchar *commit_checksum, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_commit_verify (OstreeSign *self, - OstreeRepo *repo, - const gchar *commit_checksum, - char **out_success_message, - GCancellable *cancellable, - GError **error); +gboolean ostree_sign_commit_verify (OstreeSign *self, OstreeRepo *repo, + const gchar *commit_checksum, char **out_success_message, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_clear_keys (OstreeSign *self, - GError **error); +gboolean ostree_sign_clear_keys (OstreeSign *self, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_set_sk (OstreeSign *self, - GVariant *secret_key, - GError **error); +gboolean ostree_sign_set_sk (OstreeSign *self, GVariant *secret_key, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_set_pk (OstreeSign *self, - GVariant *public_key, - GError **error); +gboolean ostree_sign_set_pk (OstreeSign *self, GVariant *public_key, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_add_pk (OstreeSign *self, - GVariant *public_key, - GError **error); +gboolean ostree_sign_add_pk (OstreeSign *self, GVariant *public_key, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_load_pk (OstreeSign *self, - GVariant *options, - GError **error); - +gboolean ostree_sign_load_pk (OstreeSign *self, GVariant *options, GError **error); _OSTREE_PUBLIC -GPtrArray * ostree_sign_get_all(void); +GPtrArray *ostree_sign_get_all (void); _OSTREE_PUBLIC -OstreeSign * ostree_sign_get_by_name (const gchar *name, GError **error); +OstreeSign *ostree_sign_get_by_name (const gchar *name, GError **error); _OSTREE_PUBLIC -gboolean ostree_sign_summary (OstreeSign *self, - OstreeRepo *repo, - GVariant *keys, - GCancellable *cancellable, - GError **error); +gboolean ostree_sign_summary (OstreeSign *self, OstreeRepo *repo, GVariant *keys, + GCancellable *cancellable, GError **error); G_END_DECLS - diff --git a/src/libostree/ostree-sysroot-cleanup.c b/src/libostree/ostree-sysroot-cleanup.c index 3471cac..090b004 100644 --- a/src/libostree/ostree-sysroot-cleanup.c +++ b/src/libostree/ostree-sysroot-cleanup.c @@ -19,9 +19,9 @@ #include "config.h" -#include "otutil.h" -#include "ostree-repo-private.h" #include "ostree-linuxfsutil.h" +#include "ostree-repo-private.h" +#include "otutil.h" #include "ostree-sysroot-private.h" @@ -30,13 +30,13 @@ * @inout_deployments: All deployments in this subdir will be appended to this array */ gboolean -_ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd, - const char *osname, - GPtrArray *inout_deployments, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd, const char *osname, + GPtrArray *inout_deployments, + GCancellable *cancellable, GError **error) { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; gboolean exists; const char *osdeploy_path = glnx_strjoina (osname, "/deploy"); if (!ot_dfd_iter_init_allow_noent (deploydir_dfd, osdeploy_path, &dfd_iter, &exists, error)) @@ -61,7 +61,8 @@ _ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd, if (!_ostree_sysroot_parse_deploy_path_name (dent->d_name, &csum, &deployserial, error)) return FALSE; - g_ptr_array_add (inout_deployments, ostree_deployment_new (-1, osname, csum, deployserial, NULL, -1)); + g_ptr_array_add (inout_deployments, + ostree_deployment_new (-1, osname, csum, deployserial, NULL, -1)); } return TRUE; @@ -71,15 +72,14 @@ _ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd, * filesystem state. */ static gboolean -list_all_deployment_directories (OstreeSysroot *self, - GPtrArray **out_deployments, - GCancellable *cancellable, - GError **error) +list_all_deployment_directories (OstreeSysroot *self, GPtrArray **out_deployments, + GCancellable *cancellable, GError **error) { - g_autoptr(GPtrArray) ret_deployments = - g_ptr_array_new_with_free_func (g_object_unref); + g_autoptr (GPtrArray) ret_deployments = g_ptr_array_new_with_free_func (g_object_unref); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; gboolean exists; if (!ot_dfd_iter_init_allow_noent (self->sysroot_fd, "ostree/deploy", &dfd_iter, &exists, error)) return FALSE; @@ -98,8 +98,7 @@ list_all_deployment_directories (OstreeSysroot *self, if (dent->d_type != DT_DIR) continue; - if (!_ostree_sysroot_list_deployment_dirs_for_os (dfd_iter.fd, dent->d_name, - ret_deployments, + if (!_ostree_sysroot_list_deployment_dirs_for_os (dfd_iter.fd, dent->d_name, ret_deployments, cancellable, error)) return FALSE; } @@ -108,10 +107,8 @@ list_all_deployment_directories (OstreeSysroot *self, return TRUE; } -static gboolean -parse_bootdir_name (const char *name, - char **out_osname, - char **out_csum) +gboolean +_ostree_sysroot_parse_bootdir_name (const char *name, char **out_osname, char **out_csum) { const char *lastdash; @@ -136,69 +133,43 @@ parse_bootdir_name (const char *name, return TRUE; } -static gboolean -list_all_boot_directories (OstreeSysroot *self, - GPtrArray **out_bootdirs, - GCancellable *cancellable, - GError **error) +gboolean +_ostree_sysroot_list_all_boot_directories (OstreeSysroot *self, char ***out_bootdirs, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autoptr(GFile) boot_ostree = NULL; - g_autoptr(GPtrArray) ret_bootdirs = NULL; - GError *temp_error = NULL; - - boot_ostree = g_file_resolve_relative_path (self->path, "boot/ostree"); - - ret_bootdirs = g_ptr_array_new_with_free_func (g_object_unref); - - g_autoptr(GFileEnumerator) dir_enum = - g_file_enumerate_children (boot_ostree, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, &temp_error); - if (!dir_enum) - { - if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - { - g_clear_error (&temp_error); - goto done; - } - else - { - g_propagate_error (error, temp_error); - goto out; - } - } + g_autoptr (GPtrArray) ret_bootdirs = g_ptr_array_new_with_free_func (g_free); + + gboolean exists = FALSE; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + if (self->boot_fd >= 0 + && !ot_dfd_iter_init_allow_noent (self->boot_fd, "ostree", &dfd_iter, &exists, error)) + return FALSE; - while (TRUE) + while (exists) { - GFileInfo *file_info = NULL; - GFile *child = NULL; - const char *name; - - if (!g_file_enumerator_iterate (dir_enum, &file_info, &child, - NULL, error)) - goto out; - if (file_info == NULL) + struct dirent *dent; + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) + return FALSE; + if (dent == NULL) break; - if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY) + if (dent->d_type != DT_DIR) continue; /* Only look at directories ending in -CHECKSUM; nothing else * should be in here, but let's be conservative. */ - name = g_file_info_get_name (file_info); - if (!parse_bootdir_name (name, NULL, NULL)) + if (!_ostree_sysroot_parse_bootdir_name (dent->d_name, NULL, NULL)) continue; - - g_ptr_array_add (ret_bootdirs, g_object_ref (child)); + + g_ptr_array_add (ret_bootdirs, g_strdup (dent->d_name)); } - - done: - ret = TRUE; - ot_transfer_out_value (out_bootdirs, &ret_bootdirs); - out: - return ret; + + g_ptr_array_add (ret_bootdirs, NULL); + *out_bootdirs = (char **)g_ptr_array_free (g_steal_pointer (&ret_bootdirs), FALSE); + return TRUE; } /* A sysroot has at most one active "boot version" (pair of version,subversion) @@ -206,31 +177,34 @@ list_all_boot_directories (OstreeSysroot *self, * other versions that aren't active. */ static gboolean -cleanup_other_bootversions (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +cleanup_other_bootversions (OstreeSysroot *self, GCancellable *cancellable, GError **error) { const int cleanup_bootversion = self->bootversion == 0 ? 1 : 0; const int cleanup_subbootversion = self->subbootversion == 0 ? 1 : 0; /* Reusable buffer for path */ - g_autoptr(GString) buf = g_string_new (""); + g_autoptr (GString) buf = g_string_new (""); /* These directories are for the other major version */ - g_string_truncate (buf, 0); g_string_append_printf (buf, "boot/loader.%d", cleanup_bootversion); + g_string_truncate (buf, 0); + g_string_append_printf (buf, "boot/loader.%d", cleanup_bootversion); if (!glnx_shutil_rm_rf_at (self->sysroot_fd, buf->str, cancellable, error)) return FALSE; - g_string_truncate (buf, 0); g_string_append_printf (buf, "ostree/boot.%d", cleanup_bootversion); + g_string_truncate (buf, 0); + g_string_append_printf (buf, "ostree/boot.%d", cleanup_bootversion); if (!glnx_shutil_rm_rf_at (self->sysroot_fd, buf->str, cancellable, error)) return FALSE; - g_string_truncate (buf, 0); g_string_append_printf (buf, "ostree/boot.%d.0", cleanup_bootversion); + g_string_truncate (buf, 0); + g_string_append_printf (buf, "ostree/boot.%d.0", cleanup_bootversion); if (!glnx_shutil_rm_rf_at (self->sysroot_fd, buf->str, cancellable, error)) return FALSE; - g_string_truncate (buf, 0); g_string_append_printf (buf, "ostree/boot.%d.1", cleanup_bootversion); + g_string_truncate (buf, 0); + g_string_append_printf (buf, "ostree/boot.%d.1", cleanup_bootversion); if (!glnx_shutil_rm_rf_at (self->sysroot_fd, buf->str, cancellable, error)) return FALSE; /* And finally the other subbootversion */ - g_string_truncate (buf, 0); g_string_append_printf (buf, "ostree/boot.%d.%d", self->bootversion, cleanup_subbootversion); + g_string_truncate (buf, 0); + g_string_append_printf (buf, "ostree/boot.%d.%d", self->bootversion, cleanup_subbootversion); if (!glnx_shutil_rm_rf_at (self->sysroot_fd, buf->str, cancellable, error)) return FALSE; @@ -239,18 +213,15 @@ cleanup_other_bootversions (OstreeSysroot *self, /* Delete a deployment directory */ gboolean -_ostree_sysroot_rmrf_deployment (OstreeSysroot *self, - OstreeDeployment *deployment, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_rmrf_deployment (OstreeSysroot *self, OstreeDeployment *deployment, + GCancellable *cancellable, GError **error) { g_autofree char *origin_relpath = ostree_deployment_get_origin_relpath (deployment); g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); struct stat stbuf; glnx_autofd int deployment_fd = -1; - if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, - &deployment_fd, error)) + if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_fd, error)) return FALSE; if (!glnx_fstat (deployment_fd, &stbuf, error)) @@ -259,13 +230,11 @@ _ostree_sysroot_rmrf_deployment (OstreeSysroot *self, /* This shouldn't happen, because higher levels should * disallow having the booted deployment not in the active * deployment list, but let's be extra safe. */ - if (stbuf.st_dev == self->root_device && - stbuf.st_ino == self->root_inode) + if (stbuf.st_dev == self->root_device && stbuf.st_ino == self->root_inode) return TRUE; /* This deployment wasn't referenced, so delete it */ - if (!_ostree_linuxfs_fd_alter_immutable_flag (deployment_fd, FALSE, - cancellable, error)) + if (!_ostree_linuxfs_fd_alter_immutable_flag (deployment_fd, FALSE, cancellable, error)) return FALSE; if (!glnx_shutil_rm_rf_at (self->sysroot_fd, origin_relpath, cancellable, error)) return FALSE; @@ -280,43 +249,22 @@ _ostree_sysroot_rmrf_deployment (OstreeSysroot *self, * referenced. */ static gboolean -cleanup_old_deployments (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +cleanup_old_deployments (OstreeSysroot *self, GCancellable *cancellable, GError **error) { - /* Gather the device/inode of the rootfs, so we can double - * check we won't delete it. - */ - struct stat root_stbuf; - if (!glnx_fstatat (AT_FDCWD, "/", &root_stbuf, 0, error)) - return FALSE; - /* Load all active deployments referenced by bootloader configuration. */ - g_autoptr(GHashTable) active_deployment_dirs = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_autoptr(GHashTable) active_boot_checksums = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_autoptr(GHashTable) active_overlay_initrds = - g_hash_table_new (g_str_hash, g_str_equal); /* borrows from deployment's bootconfig */ + g_autoptr (GHashTable) active_deployment_dirs + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (guint i = 0; i < self->deployments->len; i++) { OstreeDeployment *deployment = self->deployments->pdata[i]; char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); - char *bootcsum = g_strdup (ostree_deployment_get_bootcsum (deployment)); /* Transfer ownership */ g_hash_table_replace (active_deployment_dirs, deployment_path, deployment_path); - g_hash_table_replace (active_boot_checksums, bootcsum, bootcsum); - - OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment); - char **initrds = ostree_bootconfig_parser_get_overlay_initrds (bootconfig); - for (char **it = initrds; it && *it; it++) - g_hash_table_add (active_overlay_initrds, (char*)glnx_basename (*it)); } /* Find all deployment directories, both active and inactive */ - g_autoptr(GPtrArray) all_deployment_dirs = NULL; - if (!list_all_deployment_directories (self, &all_deployment_dirs, - cancellable, error)) + g_autoptr (GPtrArray) all_deployment_dirs = NULL; + if (!list_all_deployment_directories (self, &all_deployment_dirs, cancellable, error)) return FALSE; g_assert (all_deployment_dirs); /* Pacify static analysis */ for (guint i = 0; i < all_deployment_dirs->len; i++) @@ -331,32 +279,57 @@ cleanup_old_deployments (OstreeSysroot *self, return FALSE; } + return TRUE; +} + +/* This function deletes any files in the bootfs unreferenced by the active + * bootloader configuration. + */ +gboolean +_ostree_sysroot_cleanup_bootfs (OstreeSysroot *self, GCancellable *cancellable, GError **error) +{ + /* Load all active bootcsums and overlays referenced by bootloader configuration. */ + g_autoptr (GHashTable) active_boot_checksums + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_autoptr (GHashTable) active_overlay_initrds + = g_hash_table_new (g_str_hash, g_str_equal); /* borrows from deployment's bootconfig */ + for (guint i = 0; i < self->deployments->len; i++) + { + OstreeDeployment *deployment = self->deployments->pdata[i]; + char *bootcsum = g_strdup (ostree_deployment_get_bootcsum (deployment)); + /* Transfer ownership */ + g_hash_table_replace (active_boot_checksums, bootcsum, bootcsum); + + OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment); + char **initrds = ostree_bootconfig_parser_get_overlay_initrds (bootconfig); + for (char **it = initrds; it && *it; it++) + g_hash_table_add (active_overlay_initrds, (char *)glnx_basename (*it)); + } + /* Clean up boot directories */ - g_autoptr(GPtrArray) all_boot_dirs = NULL; - if (!list_all_boot_directories (self, &all_boot_dirs, - cancellable, error)) + g_auto (GStrv) all_boot_dirs = NULL; + if (!_ostree_sysroot_list_all_boot_directories (self, &all_boot_dirs, cancellable, error)) return FALSE; - for (guint i = 0; i < all_boot_dirs->len; i++) + for (char **it = all_boot_dirs; it && *it; it++) { - GFile *bootdir = all_boot_dirs->pdata[i]; - g_autofree char *osname = NULL; + char *bootdir = *it; g_autofree char *bootcsum = NULL; - if (!parse_bootdir_name (glnx_basename (gs_file_get_path_cached (bootdir)), - &osname, &bootcsum)) - g_assert_not_reached (); + if (!_ostree_sysroot_parse_bootdir_name (bootdir, NULL, &bootcsum)) + g_assert_not_reached (); /* checked in _ostree_sysroot_list_all_boot_directories() */ if (g_hash_table_lookup (active_boot_checksums, bootcsum)) continue; - if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (bootdir), cancellable, error)) + g_autofree char *subpath = g_build_filename ("ostree", bootdir, NULL); + if (!glnx_shutil_rm_rf_at (self->boot_fd, subpath, cancellable, error)) return FALSE; } /* Clean up overlay initrds */ - glnx_autofd int overlays_dfd = - glnx_opendirat_with_errno (self->sysroot_fd, _OSTREE_SYSROOT_INITRAMFS_OVERLAYS, FALSE); + glnx_autofd int overlays_dfd + = glnx_opendirat_with_errno (self->sysroot_fd, _OSTREE_SYSROOT_INITRAMFS_OVERLAYS, FALSE); if (overlays_dfd < 0) { if (errno != ENOENT) @@ -364,8 +337,10 @@ cleanup_old_deployments (OstreeSysroot *self, } else { - g_autoptr(GPtrArray) initrds_to_delete = g_ptr_array_new_with_free_func (g_free); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_autoptr (GPtrArray) initrds_to_delete = g_ptr_array_new_with_free_func (g_free); + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; if (!glnx_dirfd_iterator_init_at (overlays_dfd, ".", TRUE, &dfd_iter, error)) return FALSE; while (TRUE) @@ -395,15 +370,13 @@ cleanup_old_deployments (OstreeSysroot *self, /* Delete the ref bindings for a non-active boot version */ static gboolean -cleanup_ref_prefix (OstreeRepo *repo, - int bootversion, - int subbootversion, - GCancellable *cancellable, - GError **error) +cleanup_ref_prefix (OstreeRepo *repo, int bootversion, int subbootversion, + GCancellable *cancellable, GError **error) { g_autofree char *prefix = g_strdup_printf ("ostree/%d/%d", bootversion, subbootversion); - g_autoptr(GHashTable) refs = NULL; - if (!ostree_repo_list_refs_ext (repo, prefix, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error)) + g_autoptr (GHashTable) refs = NULL; + if (!ostree_repo_list_refs_ext (repo, prefix, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, + error)) return FALSE; GLNX_HASH_TABLE_FOREACH (refs, const char *, ref) @@ -420,39 +393,31 @@ cleanup_ref_prefix (OstreeRepo *repo, * to match active deployments. */ static gboolean -generate_deployment_refs (OstreeSysroot *self, - OstreeRepo *repo, - int bootversion, - int subbootversion, - GPtrArray *deployments, - GCancellable *cancellable, - GError **error) +generate_deployment_refs (OstreeSysroot *self, OstreeRepo *repo, int bootversion, + int subbootversion, GPtrArray *deployments, GCancellable *cancellable, + GError **error) { int cleanup_bootversion = (bootversion == 0) ? 1 : 0; int cleanup_subbootversion = (subbootversion == 0) ? 1 : 0; - if (!cleanup_ref_prefix (repo, cleanup_bootversion, 0, - cancellable, error)) + if (!cleanup_ref_prefix (repo, cleanup_bootversion, 0, cancellable, error)) return FALSE; - if (!cleanup_ref_prefix (repo, cleanup_bootversion, 1, - cancellable, error)) + if (!cleanup_ref_prefix (repo, cleanup_bootversion, 1, cancellable, error)) return FALSE; - if (!cleanup_ref_prefix (repo, bootversion, cleanup_subbootversion, - cancellable, error)) + if (!cleanup_ref_prefix (repo, bootversion, cleanup_subbootversion, cancellable, error)) return FALSE; - g_autoptr(OstreeRepoAutoTransaction) txn = - _ostree_repo_auto_transaction_start (repo, cancellable, error); + g_autoptr (OstreeRepoAutoTransaction) txn + = _ostree_repo_auto_transaction_start (repo, cancellable, error); if (!txn) return FALSE; for (guint i = 0; i < deployments->len; i++) { OstreeDeployment *deployment = deployments->pdata[i]; - g_autofree char *refname = g_strdup_printf ("ostree/%d/%d/%u", - bootversion, subbootversion, - i); + g_autofree char *refname + = g_strdup_printf ("ostree/%d/%d/%u", bootversion, subbootversion, i); ostree_repo_transaction_set_refspec (repo, refname, ostree_deployment_get_csum (deployment)); } @@ -484,13 +449,10 @@ generate_deployment_refs (OstreeSysroot *self, * Since: 2018.6 */ gboolean -ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, - OstreeRepoPruneOptions *options, - gint *out_objects_total, - gint *out_objects_pruned, - guint64 *out_pruned_object_size_total, - GCancellable *cancellable, - GError **error) +ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, OstreeRepoPruneOptions *options, + gint *out_objects_total, gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, GCancellable *cancellable, + GError **error) { GLNX_AUTO_PREFIX_ERROR ("Pruning system repository", error); OstreeRepo *repo = ostree_sysroot_repo (sysroot); @@ -502,8 +464,8 @@ ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, /* Hold an exclusive lock by default across gathering refs and doing * the prune. */ - g_autoptr(OstreeRepoAutoLock) lock = - ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; @@ -529,10 +491,8 @@ ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, return FALSE; } - if (!ostree_repo_prune_from_reachable (repo, options, - out_objects_total, out_objects_pruned, - out_pruned_object_size_total, - cancellable, error)) + if (!ostree_repo_prune_from_reachable (repo, options, out_objects_total, out_objects_pruned, + out_pruned_object_size_total, cancellable, error)) return FALSE; return TRUE; @@ -548,9 +508,7 @@ ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, * transaction, such as incomplete deployments. */ gboolean -ostree_sysroot_cleanup (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +ostree_sysroot_cleanup (OstreeSysroot *self, GCancellable *cancellable, GError **error) { return _ostree_sysroot_cleanup_internal (self, TRUE, cancellable, error); } @@ -565,21 +523,17 @@ ostree_sysroot_cleanup (OstreeSysroot *self, * and old boot versions, but does NOT prune the repository. */ gboolean -ostree_sysroot_prepare_cleanup (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +ostree_sysroot_prepare_cleanup (OstreeSysroot *self, GCancellable *cancellable, GError **error) { return _ostree_sysroot_cleanup_internal (self, FALSE, cancellable, error); } gboolean -_ostree_sysroot_cleanup_internal (OstreeSysroot *self, - gboolean do_prune_repo, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_cleanup_internal (OstreeSysroot *self, gboolean do_prune_repo, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (OSTREE_IS_SYSROOT (self), FALSE); - g_return_val_if_fail (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED, FALSE); + g_assert (OSTREE_IS_SYSROOT (self)); + g_assert (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED); if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; @@ -590,12 +544,12 @@ _ostree_sysroot_cleanup_internal (OstreeSysroot *self, if (!cleanup_old_deployments (self, cancellable, error)) return glnx_prefix_error (error, "Cleaning deployments"); + if (!_ostree_sysroot_cleanup_bootfs (self, cancellable, error)) + return glnx_prefix_error (error, "Cleaning bootfs"); + OstreeRepo *repo = ostree_sysroot_repo (self); - if (!generate_deployment_refs (self, repo, - self->bootversion, - self->subbootversion, - self->deployments, - cancellable, error)) + if (!generate_deployment_refs (self, repo, self->bootversion, self->subbootversion, + self->deployments, cancellable, error)) return glnx_prefix_error (error, "Generating deployment refs"); if (do_prune_repo) @@ -603,11 +557,10 @@ _ostree_sysroot_cleanup_internal (OstreeSysroot *self, gint n_objects_total; gint n_objects_pruned; guint64 freed_space; - g_autoptr(GHashTable) reachable = ostree_repo_traverse_new_reachable (); + g_autoptr (GHashTable) reachable = ostree_repo_traverse_new_reachable (); OstreeRepoPruneOptions opts = { OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY, reachable }; - if (!ostree_sysroot_cleanup_prune_repo (self, &opts, &n_objects_total, - &n_objects_pruned, &freed_space, - cancellable, error)) + if (!ostree_sysroot_cleanup_prune_repo (self, &opts, &n_objects_total, &n_objects_pruned, + &freed_space, cancellable, error)) return FALSE; /* TODO remove printf in library */ diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 3a4f8d4..116143c 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -19,18 +19,17 @@ #include "config.h" +#include #include #include #include +#include #include -#include -#include -#include #include -#include +#include #include -#include -#include +#include +#include #ifdef HAVE_LIBMOUNT #include @@ -39,21 +38,25 @@ #include #endif -#include "otutil.h" -#include "ostree.h" -#include "ostree-repo-private.h" -#include "ostree-sysroot-private.h" -#include "ostree-sepolicy-private.h" -#include "ostree-deployment-private.h" +#include "libglnx.h" #include "ostree-core-private.h" +#include "ostree-deployment-private.h" #include "ostree-linuxfsutil.h" -#include "libglnx.h" +#include "ostree-repo-private.h" +#include "ostree-sepolicy-private.h" +#include "ostree-sysroot-private.h" +#include "ostree.h" +#include "otcore.h" #ifdef HAVE_LIBSYSTEMD -#define OSTREE_VARRELABEL_ID SD_ID128_MAKE(da,67,9b,08,ac,d3,45,04,b7,89,d9,6f,81,8e,a7,81) -#define OSTREE_CONFIGMERGE_ID SD_ID128_MAKE(d3,86,3b,ae,c1,3e,44,49,ab,03,84,68,4a,8a,f3,a7) -#define OSTREE_DEPLOYMENT_COMPLETE_ID SD_ID128_MAKE(dd,44,0e,3e,54,90,83,b6,3d,0e,fc,7d,c1,52,55,f1) -#define OSTREE_DEPLOYMENT_FINALIZING_ID SD_ID128_MAKE(e8,64,6c,d6,3d,ff,46,25,b7,79,09,a8,e7,a4,09,94) +#define OSTREE_VARRELABEL_ID \ + SD_ID128_MAKE (da, 67, 9b, 08, ac, d3, 45, 04, b7, 89, d9, 6f, 81, 8e, a7, 81) +#define OSTREE_CONFIGMERGE_ID \ + SD_ID128_MAKE (d3, 86, 3b, ae, c1, 3e, 44, 49, ab, 03, 84, 68, 4a, 8a, f3, a7) +#define OSTREE_DEPLOYMENT_COMPLETE_ID \ + SD_ID128_MAKE (dd, 44, 0e, 3e, 54, 90, 83, b6, 3d, 0e, fc, 7d, c1, 52, 55, f1) +#define OSTREE_DEPLOYMENT_FINALIZING_ID \ + SD_ID128_MAKE (e8, 64, 6c, d6, 3d, ff, 46, 25, b7, 79, 09, a8, e7, a4, 09, 94) #endif /* @@ -61,11 +64,8 @@ * symlink. */ static gboolean -symlink_at_replace (const char *oldpath, - int parent_dfd, - const char *newpath, - GCancellable *cancellable, - GError **error) +symlink_at_replace (const char *oldpath, int parent_dfd, const char *newpath, + GCancellable *cancellable, GError **error) { /* Possibly in the future generate a temporary random name here, * would need to move "generate a temporary name" code into @@ -74,7 +74,7 @@ symlink_at_replace (const char *oldpath, g_autofree char *temppath = g_strconcat (newpath, ".tmp", NULL); /* Clean up any stale temporary links */ - (void) unlinkat (parent_dfd, temppath, 0); + (void)unlinkat (parent_dfd, temppath, 0); /* Create the temp link */ if (TEMP_FAILURE_RETRY (symlinkat (oldpath, parent_dfd, temppath)) < 0) @@ -88,8 +88,7 @@ symlink_at_replace (const char *oldpath, } static GLnxFileCopyFlags -sysroot_flags_to_copy_flags (GLnxFileCopyFlags defaults, - OstreeSysrootDebugFlags sysrootflags) +sysroot_flags_to_copy_flags (GLnxFileCopyFlags defaults, OstreeSysrootDebugFlags sysrootflags) { if (sysrootflags & OSTREE_SYSROOT_DEBUG_NO_XATTRS) defaults |= GLNX_FILE_COPY_NOXATTRS; @@ -101,14 +100,9 @@ sysroot_flags_to_copy_flags (GLnxFileCopyFlags defaults, * hardlink if we're on the same partition. */ static gboolean -install_into_boot (OstreeRepo *repo, - OstreeSePolicy *sepolicy, - int src_dfd, - const char *src_subpath, - int dest_dfd, - const char *dest_subpath, - GCancellable *cancellable, - GError **error) +install_into_boot (OstreeRepo *repo, OstreeSePolicy *sepolicy, int src_dfd, const char *src_subpath, + int dest_dfd, const char *dest_subpath, GCancellable *cancellable, + GError **error) { if (linkat (src_dfd, src_subpath, dest_dfd, dest_subpath, 0) == 0) return TRUE; /* Note early return */ @@ -125,27 +119,30 @@ install_into_boot (OstreeRepo *repo, return FALSE; /* Be sure we relabel when copying the kernel, as in current - * e.g. Fedora it might be labeled module_object_t or usr_t, - * but policy may not allow other processes to read from that - * like kdump. - * See also https://github.com/fedora-selinux/selinux-policy/commit/747f4e6775d773ab74efae5aa37f3e5e7f0d4aca - * This means we also drop xattrs but...I doubt anyone uses - * non-SELinux xattrs for the kernel anyways aside from perhaps - * IMA but that's its own story. - */ - g_auto(OstreeSepolicyFsCreatecon) fscreatecon = { 0, }; + * e.g. Fedora it might be labeled module_object_t or usr_t, + * but policy may not allow other processes to read from that + * like kdump. + * See also + * https://github.com/fedora-selinux/selinux-policy/commit/747f4e6775d773ab74efae5aa37f3e5e7f0d4aca + * This means we also drop xattrs but...I doubt anyone uses + * non-SELinux xattrs for the kernel anyways aside from perhaps + * IMA but that's its own story. + */ + g_auto (OstreeSepolicyFsCreatecon) fscreatecon = { + 0, + }; const char *boot_path = glnx_strjoina ("/boot/", glnx_basename (dest_subpath)); - if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, sepolicy, - boot_path, S_IFREG | 0644, + if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, sepolicy, boot_path, S_IFREG | 0644, error)) return FALSE; - g_auto(GLnxTmpfile) tmp_dest = { 0, }; - if (!glnx_open_tmpfile_linkable_at (dest_dfd, ".", O_WRONLY | O_CLOEXEC, - &tmp_dest, error)) + g_auto (GLnxTmpfile) tmp_dest = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (dest_dfd, ".", O_WRONLY | O_CLOEXEC, &tmp_dest, error)) return FALSE; - if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t) -1) < 0) + if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t)-1) < 0) return glnx_throw_errno_prefix (error, "regfile copy"); /* Kernel data should always be root-owned */ @@ -166,7 +163,7 @@ install_into_boot (OstreeRepo *repo, _OstreeFeatureSupport boot_verity = _OSTREE_FEATURE_NO; if (repo->fs_verity_wanted != _OSTREE_FEATURE_NO) boot_verity = _OSTREE_FEATURE_MAYBE; - if (!_ostree_tmpf_fsverity_core (&tmp_dest, boot_verity, NULL, error)) + if (!_ostree_tmpf_fsverity_core (&tmp_dest, boot_verity, NULL, NULL, error)) return FALSE; if (!glnx_link_tmpfile_at (&tmp_dest, GLNX_LINK_TMPFILE_NOREPLACE, dest_dfd, dest_subpath, error)) @@ -177,15 +174,11 @@ install_into_boot (OstreeRepo *repo, /* Copy ownership, mode, and xattrs from source directory to destination */ static gboolean -dirfd_copy_attributes_and_xattrs (int src_parent_dfd, - const char *src_name, - int src_dfd, - int dest_dfd, - OstreeSysrootDebugFlags flags, - GCancellable *cancellable, - GError **error) +dirfd_copy_attributes_and_xattrs (int src_parent_dfd, const char *src_name, int src_dfd, + int dest_dfd, OstreeSysrootDebugFlags flags, + GCancellable *cancellable, GError **error) { - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; /* Clone all xattrs first, so we get the SELinux security context * right. This will allow other users access if they have ACLs, but @@ -193,11 +186,9 @@ dirfd_copy_attributes_and_xattrs (int src_parent_dfd, */ if (!(flags & OSTREE_SYSROOT_DEBUG_NO_XATTRS)) { - if (!glnx_dfd_name_get_all_xattrs (src_parent_dfd, src_name, - &xattrs, cancellable, error)) + if (!glnx_dfd_name_get_all_xattrs (src_parent_dfd, src_name, &xattrs, cancellable, error)) return FALSE; - if (!glnx_fd_set_all_xattrs (dest_dfd, xattrs, - cancellable, error)) + if (!glnx_fd_set_all_xattrs (dest_dfd, xattrs, cancellable, error)) return FALSE; } @@ -215,20 +206,19 @@ dirfd_copy_attributes_and_xattrs (int src_parent_dfd, static gint str_sort_cb (gconstpointer name_ptr_a, gconstpointer name_ptr_b) { - const gchar *name_a = *((const gchar **) name_ptr_a); - const gchar *name_b = *((const gchar **) name_ptr_b); + const gchar *name_a = *((const gchar **)name_ptr_a); + const gchar *name_b = *((const gchar **)name_ptr_b); return g_strcmp0 (name_a, name_b); } static gboolean -checksum_dir_recurse (int dfd, - const char *path, - OtChecksum *checksum, - GCancellable *cancellable, - GError **error) +checksum_dir_recurse (int dfd, const char *path, OtChecksum *checksum, GCancellable *cancellable, + GError **error) { - g_auto(GLnxDirFdIterator) dfditer = { 0, }; + g_auto (GLnxDirFdIterator) dfditer = { + 0, + }; g_autoptr (GPtrArray) d_entries = g_ptr_array_new_with_free_func (g_free); if (!glnx_dirfd_iterator_init_at (dfd, path, TRUE, &dfditer, error)) @@ -250,20 +240,19 @@ checksum_dir_recurse (int dfd, /* File systems do not guarantee dir entry order, make sure this is * reproducable */ - g_ptr_array_sort(d_entries, str_sort_cb); + g_ptr_array_sort (d_entries, str_sort_cb); - for (gint i=0; i < d_entries->len; i++) + for (gint i = 0; i < d_entries->len; i++) { const gchar *d_name = (gchar *)g_ptr_array_index (d_entries, i); struct stat stbuf; - if (!glnx_fstatat (dfditer.fd, d_name, &stbuf, - AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat (dfditer.fd, d_name, &stbuf, AT_SYMLINK_NOFOLLOW, error)) return FALSE; if (S_ISDIR (stbuf.st_mode)) { - if (!checksum_dir_recurse(dfditer.fd, d_name, checksum, cancellable, error)) + if (!checksum_dir_recurse (dfditer.fd, d_name, checksum, cancellable, error)) return FALSE; } else @@ -274,26 +263,23 @@ checksum_dir_recurse (int dfd, return FALSE; if (fd != -1) { - g_autoptr(GInputStream) in = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE); + g_autoptr (GInputStream) in = g_unix_input_stream_new (g_steal_fd (&fd), TRUE); if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error)) return FALSE; } } - } return TRUE; } static gboolean -copy_dir_recurse (int src_parent_dfd, - int dest_parent_dfd, - const char *name, - OstreeSysrootDebugFlags flags, - GCancellable *cancellable, - GError **error) -{ - g_auto(GLnxDirFdIterator) src_dfd_iter = { 0, }; +copy_dir_recurse (int src_parent_dfd, int dest_parent_dfd, const char *name, + OstreeSysrootDebugFlags flags, GCancellable *cancellable, GError **error) +{ + g_auto (GLnxDirFdIterator) src_dfd_iter = { + 0, + }; glnx_autofd int dest_dfd = -1; struct dirent *dent; @@ -307,8 +293,8 @@ copy_dir_recurse (int src_parent_dfd, if (!glnx_opendirat (dest_parent_dfd, name, TRUE, &dest_dfd, error)) return FALSE; - if (!dirfd_copy_attributes_and_xattrs (src_parent_dfd, name, src_dfd_iter.fd, dest_dfd, - flags, cancellable, error)) + if (!dirfd_copy_attributes_and_xattrs (src_parent_dfd, name, src_dfd_iter.fd, dest_dfd, flags, + cancellable, error)) return glnx_prefix_error (error, "Copying attributes of %s", name); while (TRUE) @@ -320,20 +306,19 @@ copy_dir_recurse (int src_parent_dfd, if (dent == NULL) break; - if (!glnx_fstatat (src_dfd_iter.fd, dent->d_name, &child_stbuf, - AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat (src_dfd_iter.fd, dent->d_name, &child_stbuf, AT_SYMLINK_NOFOLLOW, error)) return FALSE; if (S_ISDIR (child_stbuf.st_mode)) { - if (!copy_dir_recurse (src_dfd_iter.fd, dest_dfd, dent->d_name, - flags, cancellable, error)) + if (!copy_dir_recurse (src_dfd_iter.fd, dest_dfd, dent->d_name, flags, cancellable, + error)) return FALSE; } else { - if (!glnx_file_copy_at (src_dfd_iter.fd, dent->d_name, &child_stbuf, - dest_dfd, dent->d_name, + if (!glnx_file_copy_at (src_dfd_iter.fd, dent->d_name, &child_stbuf, dest_dfd, + dent->d_name, sysroot_flags_to_copy_flags (GLNX_FILE_COPY_OVERWRITE, flags), cancellable, error)) return glnx_prefix_error (error, "Copying %s", dent->d_name); @@ -347,14 +332,9 @@ copy_dir_recurse (int src_parent_dfd, * they're created. */ static gboolean -ensure_directory_from_template (int orig_etc_fd, - int modified_etc_fd, - int new_etc_fd, - const char *path, - int *out_dfd, - OstreeSysrootDebugFlags flags, - GCancellable *cancellable, - GError **error) +ensure_directory_from_template (int orig_etc_fd, int modified_etc_fd, int new_etc_fd, + const char *path, int *out_dfd, OstreeSysrootDebugFlags flags, + GCancellable *cancellable, GError **error) { glnx_autofd int src_dfd = -1; glnx_autofd int target_dfd = -1; @@ -366,7 +346,7 @@ ensure_directory_from_template (int orig_etc_fd, return FALSE; /* Create with mode 0700, we'll fchmod/fchown later */ - again: +again: if (mkdirat (new_etc_fd, path, 0700) != 0) { if (errno == EEXIST) @@ -399,12 +379,12 @@ ensure_directory_from_template (int orig_etc_fd, if (!glnx_opendirat (new_etc_fd, path, TRUE, &target_dfd, error)) return FALSE; - if (!dirfd_copy_attributes_and_xattrs (modified_etc_fd, path, src_dfd, target_dfd, - flags, cancellable, error)) + if (!dirfd_copy_attributes_and_xattrs (modified_etc_fd, path, src_dfd, target_dfd, flags, + cancellable, error)) return FALSE; if (out_dfd) - *out_dfd = glnx_steal_fd (&target_dfd); + *out_dfd = g_steal_fd (&target_dfd); return TRUE; } @@ -413,13 +393,8 @@ ensure_directory_from_template (int orig_etc_fd, * or a directory. Directories will be copied recursively. */ static gboolean -copy_modified_config_file (int orig_etc_fd, - int modified_etc_fd, - int new_etc_fd, - const char *path, - OstreeSysrootDebugFlags flags, - GCancellable *cancellable, - GError **error) +copy_modified_config_file (int orig_etc_fd, int modified_etc_fd, int new_etc_fd, const char *path, + OstreeSysrootDebugFlags flags, GCancellable *cancellable, GError **error) { struct stat modified_stbuf; struct stat new_stbuf; @@ -432,8 +407,8 @@ copy_modified_config_file (int orig_etc_fd, { g_autofree char *parent = g_path_get_dirname (path); - if (!ensure_directory_from_template (orig_etc_fd, modified_etc_fd, new_etc_fd, - parent, &dest_parent_dfd, flags, cancellable, error)) + if (!ensure_directory_from_template (orig_etc_fd, modified_etc_fd, new_etc_fd, parent, + &dest_parent_dfd, flags, cancellable, error)) return FALSE; } else @@ -450,13 +425,14 @@ copy_modified_config_file (int orig_etc_fd, if (errno != ENOENT) return glnx_throw_errno_prefix (error, "fstatat"); } - else if (S_ISDIR(new_stbuf.st_mode)) + else if (S_ISDIR (new_stbuf.st_mode)) { - if (!S_ISDIR(modified_stbuf.st_mode)) + if (!S_ISDIR (modified_stbuf.st_mode)) { return g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Modified config file newly defaults to directory '%s', cannot merge", - path), FALSE; + path), + FALSE; } else { @@ -474,21 +450,20 @@ copy_modified_config_file (int orig_etc_fd, if (S_ISDIR (modified_stbuf.st_mode)) { - if (!copy_dir_recurse (modified_etc_fd, new_etc_fd, path, flags, - cancellable, error)) + if (!copy_dir_recurse (modified_etc_fd, new_etc_fd, path, flags, cancellable, error)) return FALSE; } else if (S_ISLNK (modified_stbuf.st_mode) || S_ISREG (modified_stbuf.st_mode)) { - if (!glnx_file_copy_at (modified_etc_fd, path, &modified_stbuf, - new_etc_fd, path, + if (!glnx_file_copy_at (modified_etc_fd, path, &modified_stbuf, new_etc_fd, path, sysroot_flags_to_copy_flags (GLNX_FILE_COPY_OVERWRITE, flags), cancellable, error)) return glnx_prefix_error (error, "Copying %s", path); } else { - ot_journal_print (LOG_INFO, "Ignoring non-regular/non-symlink file found during /etc merge: %s", path); + ot_journal_print (LOG_INFO, + "Ignoring non-regular/non-symlink file found during /etc merge: %s", path); } return TRUE; @@ -512,12 +487,9 @@ copy_modified_config_file (int orig_etc_fd, * changed in @new_etc, the modified version always wins. */ static gboolean -merge_configuration_from (OstreeSysroot *sysroot, - OstreeDeployment *merge_deployment, - OstreeDeployment *new_deployment, - int new_deployment_dfd, - GCancellable *cancellable, - GError **error) +merge_configuration_from (OstreeSysroot *sysroot, OstreeDeployment *merge_deployment, + OstreeDeployment *new_deployment, int new_deployment_dfd, + GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("During /etc merge", error); const OstreeSysrootDebugFlags flags = sysroot->debug_flags; @@ -525,19 +497,21 @@ merge_configuration_from (OstreeSysroot *sysroot, g_assert (merge_deployment != NULL && new_deployment != NULL); g_assert (new_deployment_dfd != -1); - g_autofree char *merge_deployment_path = ostree_sysroot_get_deployment_dirpath (sysroot, merge_deployment); + g_autofree char *merge_deployment_path + = ostree_sysroot_get_deployment_dirpath (sysroot, merge_deployment); glnx_autofd int merge_deployment_dfd = -1; - if (!glnx_opendirat (sysroot->sysroot_fd, merge_deployment_path, FALSE, - &merge_deployment_dfd, error)) + if (!glnx_opendirat (sysroot->sysroot_fd, merge_deployment_path, FALSE, &merge_deployment_dfd, + error)) return FALSE; /* TODO: get rid of GFile usage here */ - g_autoptr(GFile) orig_etc = ot_fdrel_to_gfile (merge_deployment_dfd, "usr/etc"); - g_autoptr(GFile) modified_etc = ot_fdrel_to_gfile (merge_deployment_dfd, "etc"); + g_autoptr (GFile) orig_etc = ot_fdrel_to_gfile (merge_deployment_dfd, "usr/etc"); + g_autoptr (GFile) modified_etc = ot_fdrel_to_gfile (merge_deployment_dfd, "etc"); /* Return values for below */ - g_autoptr(GPtrArray) modified = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_diff_item_unref); - g_autoptr(GPtrArray) removed = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - g_autoptr(GPtrArray) added = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + g_autoptr (GPtrArray) modified + = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref); + g_autoptr (GPtrArray) removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); + g_autoptr (GPtrArray) added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); /* For now, ignore changes to xattrs; the problem is that * security.selinux will be different between the /usr/etc labels * and the ones in the real /etc, so they all show up as different. @@ -546,20 +520,17 @@ merge_configuration_from (OstreeSysroot *sysroot, * file, to have that change persist across upgrades, you must also * modify the content of the file. */ - if (!ostree_diff_dirs (OSTREE_DIFF_FLAGS_IGNORE_XATTRS, - orig_etc, modified_etc, modified, removed, added, - cancellable, error)) + if (!ostree_diff_dirs (OSTREE_DIFF_FLAGS_IGNORE_XATTRS, orig_etc, modified_etc, modified, removed, + added, cancellable, error)) return glnx_prefix_error (error, "While computing configuration diff"); - { g_autofree char *msg = - g_strdup_printf ("Copying /etc changes: %u modified, %u removed, %u added", - modified->len, removed->len, added->len); - ot_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_CONFIGMERGE_ID), - "MESSAGE=%s", msg, - "ETC_N_MODIFIED=%u", modified->len, - "ETC_N_REMOVED=%u", removed->len, - "ETC_N_ADDED=%u", added->len, - NULL); + { + g_autofree char *msg + = g_strdup_printf ("Copying /etc changes: %u modified, %u removed, %u added", modified->len, + removed->len, added->len); + ot_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL (OSTREE_CONFIGMERGE_ID), + "MESSAGE=%s", msg, "ETC_N_MODIFIED=%u", modified->len, "ETC_N_REMOVED=%u", + removed->len, "ETC_N_ADDED=%u", added->len, NULL); _ostree_sysroot_emit_journal_msg (sysroot, msg); } @@ -592,8 +563,8 @@ merge_configuration_from (OstreeSysroot *sysroot, g_assert (path); - if (!copy_modified_config_file (orig_etc_fd, modified_etc_fd, new_etc_fd, path, - flags, cancellable, error)) + if (!copy_modified_config_file (orig_etc_fd, modified_etc_fd, new_etc_fd, path, flags, + cancellable, error)) return FALSE; } for (guint i = 0; i < added->len; i++) @@ -603,30 +574,58 @@ merge_configuration_from (OstreeSysroot *sysroot, g_assert (path); - if (!copy_modified_config_file (orig_etc_fd, modified_etc_fd, new_etc_fd, path, - flags, cancellable, error)) + if (!copy_modified_config_file (orig_etc_fd, modified_etc_fd, new_etc_fd, path, flags, + cancellable, error)) return FALSE; } return TRUE; } +#ifdef HAVE_COMPOSEFS +static gboolean +compare_verity_digests (GVariant *metadata_composefs, const guchar *fsverity_digest, GError **error) +{ + const guchar *expected_digest; + + if (metadata_composefs == NULL) + return TRUE; + + if (g_variant_n_children (metadata_composefs) != OSTREE_SHA256_DIGEST_LEN) + return glnx_throw (error, "Expected composefs fs-verity in metadata has the wrong size"); + + expected_digest = g_variant_get_data (metadata_composefs); + if (memcmp (fsverity_digest, expected_digest, OSTREE_SHA256_DIGEST_LEN) != 0) + { + char actual_checksum[OSTREE_SHA256_STRING_LEN + 1]; + char expected_checksum[OSTREE_SHA256_STRING_LEN + 1]; + + ostree_checksum_inplace_from_bytes (fsverity_digest, actual_checksum); + ostree_checksum_inplace_from_bytes (expected_digest, expected_checksum); + + return glnx_throw (error, + "Generated composefs image digest (%s) doesn't match expected digest (%s)", + actual_checksum, expected_checksum); + } + + return TRUE; +} + +#endif + /* Look up @revision in the repository, and check it out in * /ostree/deploy/OS/deploy/${treecsum}.${deployserial}. * A dfd for the result is returned in @out_deployment_dfd. */ static gboolean -checkout_deployment_tree (OstreeSysroot *sysroot, - OstreeRepo *repo, - OstreeDeployment *deployment, - int *out_deployment_dfd, - GCancellable *cancellable, - GError **error) +checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeployment *deployment, + const char *revision, int *out_deployment_dfd, GCancellable *cancellable, + GError **error) { GLNX_AUTO_PREFIX_ERROR ("Checking out deployment tree", error); /* Find the directory with deployments for this stateroot */ - g_autofree char *osdeploy_path = - g_strconcat ("ostree/deploy/", ostree_deployment_get_osname (deployment), "/deploy", NULL); + g_autofree char *osdeploy_path + = g_strconcat ("ostree/deploy/", ostree_deployment_get_osname (deployment), "/deploy", NULL); if (!glnx_shutil_mkdir_p_at (sysroot->sysroot_fd, osdeploy_path, 0775, cancellable, error)) return FALSE; @@ -636,24 +635,75 @@ checkout_deployment_tree (OstreeSysroot *sysroot, /* Clean up anything that was there before, from e.g. an interrupted checkout */ const char *csum = ostree_deployment_get_csum (deployment); - g_autofree char *checkout_target_name = - g_strdup_printf ("%s.%d", csum, ostree_deployment_get_deployserial (deployment)); + g_autofree char *checkout_target_name + = g_strdup_printf ("%s.%d", csum, ostree_deployment_get_deployserial (deployment)); if (!glnx_shutil_rm_rf_at (osdeploy_dfd, checkout_target_name, cancellable, error)) return FALSE; /* Generate hardlink farm, then opendir it */ - OstreeRepoCheckoutAtOptions checkout_opts = { 0, }; - if (!ostree_repo_checkout_at (repo, &checkout_opts, osdeploy_dfd, - checkout_target_name, csum, + OstreeRepoCheckoutAtOptions checkout_opts = { .process_passthrough_whiteouts = TRUE }; + if (!ostree_repo_checkout_at (repo, &checkout_opts, osdeploy_dfd, checkout_target_name, csum, cancellable, error)) return FALSE; - return glnx_opendirat (osdeploy_dfd, checkout_target_name, TRUE, out_deployment_dfd, - error); +#ifdef HAVE_COMPOSEFS + if (repo->composefs_wanted != OT_TRISTATE_NO) + { + g_autofree guchar *fsverity_digest = NULL; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + g_autoptr (GVariant) commit_variant = NULL; + + if (!ostree_repo_load_commit (repo, revision, &commit_variant, NULL, error)) + return FALSE; + + g_autoptr (GVariant) metadata = g_variant_get_child_value (commit_variant, 0); + g_autoptr (GVariant) metadata_composefs = g_variant_lookup_value ( + metadata, OSTREE_COMPOSEFS_DIGEST_KEY_V0, G_VARIANT_TYPE_BYTESTRING); + + /* Create a composefs image and put in deploy dir */ + g_autoptr (OstreeComposefsTarget) target = ostree_composefs_target_new (); + + g_autoptr (GFile) commit_root = NULL; + if (!ostree_repo_read_commit (repo, csum, &commit_root, NULL, cancellable, error)) + return FALSE; + + if (!ostree_repo_checkout_composefs (repo, target, (OstreeRepoFile *)commit_root, cancellable, + error)) + return FALSE; + + g_autofree char *composefs_cfs_path + = g_strdup_printf ("%s/" OSTREE_COMPOSEFS_NAME, checkout_target_name); + + if (!glnx_open_tmpfile_linkable_at (osdeploy_dfd, checkout_target_name, O_WRONLY | O_CLOEXEC, + &tmpf, error)) + return FALSE; + + if (!ostree_composefs_target_write (target, tmpf.fd, &fsverity_digest, cancellable, error)) + return FALSE; + + /* If the commit specified a composefs digest, verify it */ + if (!compare_verity_digests (metadata_composefs, fsverity_digest, error)) + return FALSE; + + if (!glnx_fchmod (tmpf.fd, 0644, error)) + return FALSE; + + if (!_ostree_tmpf_fsverity (repo, &tmpf, NULL, error)) + return FALSE; + + if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_REPLACE, osdeploy_dfd, composefs_cfs_path, + error)) + return FALSE; + } +#endif + + return glnx_opendirat (osdeploy_dfd, checkout_target_name, TRUE, out_deployment_dfd, error); } static char * -ptrarray_path_join (GPtrArray *path) +ptrarray_path_join (GPtrArray *path) { GString *path_buf; @@ -677,49 +727,36 @@ ptrarray_path_join (GPtrArray *path) } static gboolean -relabel_one_path (OstreeSysroot *sysroot, - OstreeSePolicy *sepolicy, - GFile *path, - GFileInfo *info, - GPtrArray *path_parts, - GCancellable *cancellable, - GError **error) +relabel_one_path (OstreeSysroot *sysroot, OstreeSePolicy *sepolicy, GFile *path, GFileInfo *info, + GPtrArray *path_parts, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *relpath = NULL; relpath = ptrarray_path_join (path_parts); - if (!ostree_sepolicy_restorecon (sepolicy, relpath, - info, path, - OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL, - NULL, + if (!ostree_sepolicy_restorecon (sepolicy, relpath, info, path, + OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL, NULL, cancellable, error)) goto out; ret = TRUE; - out: +out: return ret; } static gboolean -relabel_recursively (OstreeSysroot *sysroot, - OstreeSePolicy *sepolicy, - GFile *dir, - GFileInfo *dir_info, - GPtrArray *path_parts, - GCancellable *cancellable, - GError **error) +relabel_recursively (OstreeSysroot *sysroot, OstreeSePolicy *sepolicy, GFile *dir, + GFileInfo *dir_info, GPtrArray *path_parts, GCancellable *cancellable, + GError **error) { gboolean ret = FALSE; - g_autoptr(GFileEnumerator) direnum = NULL; + g_autoptr (GFileEnumerator) direnum = NULL; - if (!relabel_one_path (sysroot, sepolicy, dir, dir_info, path_parts, - cancellable, error)) + if (!relabel_one_path (sysroot, sepolicy, dir, dir_info, path_parts, cancellable, error)) goto out; direnum = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!direnum) goto out; @@ -729,25 +766,24 @@ relabel_recursively (OstreeSysroot *sysroot, GFile *child; GFileType ftype; - if (!g_file_enumerator_iterate (direnum, &file_info, &child, - cancellable, error)) + if (!g_file_enumerator_iterate (direnum, &file_info, &child, cancellable, error)) goto out; if (file_info == NULL) break; - g_ptr_array_add (path_parts, (char*)g_file_info_get_name (file_info)); + g_ptr_array_add (path_parts, (char *)g_file_info_get_name (file_info)); ftype = g_file_info_get_file_type (file_info); if (ftype == G_FILE_TYPE_DIRECTORY) { - if (!relabel_recursively (sysroot, sepolicy, child, file_info, path_parts, - cancellable, error)) + if (!relabel_recursively (sysroot, sepolicy, child, file_info, path_parts, cancellable, + error)) goto out; } else { - if (!relabel_one_path (sysroot, sepolicy, child, file_info, path_parts, - cancellable, error)) + if (!relabel_one_path (sysroot, sepolicy, child, file_info, path_parts, cancellable, + error)) goto out; } @@ -755,30 +791,23 @@ relabel_recursively (OstreeSysroot *sysroot, } ret = TRUE; - out: +out: return ret; } static gboolean -selinux_relabel_dir (OstreeSysroot *sysroot, - OstreeSePolicy *sepolicy, - GFile *dir, - const char *prefix, - GCancellable *cancellable, - GError **error) -{ - - g_autoptr(GFileInfo) root_info = - g_file_query_info (dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); +selinux_relabel_dir (OstreeSysroot *sysroot, OstreeSePolicy *sepolicy, GFile *dir, + const char *prefix, GCancellable *cancellable, GError **error) +{ + + g_autoptr (GFileInfo) root_info = g_file_query_info ( + dir, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!root_info) return FALSE; - g_autoptr(GPtrArray) path_parts = g_ptr_array_new (); - g_ptr_array_add (path_parts, (char*)prefix); - if (!relabel_recursively (sysroot, sepolicy, dir, root_info, path_parts, - cancellable, error)) + g_autoptr (GPtrArray) path_parts = g_ptr_array_new (); + g_ptr_array_add (path_parts, (char *)prefix); + if (!relabel_recursively (sysroot, sepolicy, dir, root_info, path_parts, cancellable, error)) return glnx_prefix_error (error, "Relabeling /%s", prefix); return TRUE; @@ -788,12 +817,10 @@ selinux_relabel_dir (OstreeSysroot *sysroot, * https://github.com/ostreedev/ostree/pull/872 */ static gboolean -selinux_relabel_var_if_needed (OstreeSysroot *sysroot, - OstreeSePolicy *sepolicy, - int os_deploy_dfd, - GCancellable *cancellable, - GError **error) +selinux_relabel_var_if_needed (OstreeSysroot *sysroot, OstreeSePolicy *sepolicy, int os_deploy_dfd, + GCancellable *cancellable, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Relabeling /var", error); /* This is a bit of a hack; we should change the code at some * point in the distant future to only create (and label) /var * when doing a deployment. @@ -804,34 +831,32 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot, return FALSE; if (errno == ENOENT) { - { g_autofree char *msg = - g_strdup_printf ("Relabeling /var (no stamp file '%s' found)", selabeled); - ot_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_VARRELABEL_ID), - "MESSAGE=%s", msg, - NULL); + { + g_autofree char *msg + = g_strdup_printf ("Relabeling /var (no stamp file '%s' found)", selabeled); + ot_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, + SD_ID128_FORMAT_VAL (OSTREE_VARRELABEL_ID), "MESSAGE=%s", msg, NULL); _ostree_sysroot_emit_journal_msg (sysroot, msg); } - g_autoptr(GFile) deployment_var_path = ot_fdrel_to_gfile (os_deploy_dfd, "var"); - if (!selinux_relabel_dir (sysroot, sepolicy, - deployment_var_path, "var", - cancellable, error)) + g_autoptr (GFile) deployment_var_path = ot_fdrel_to_gfile (os_deploy_dfd, "var"); + if (!selinux_relabel_dir (sysroot, sepolicy, deployment_var_path, "var", cancellable, error)) { g_prefix_error (error, "Relabeling /var: "); return FALSE; } - { g_auto(OstreeSepolicyFsCreatecon) con = { 0, }; + { + g_auto (OstreeSepolicyFsCreatecon) con = { + 0, + }; const char *selabeled_abspath = glnx_strjoina ("/", selabeled); - if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, - selabeled_abspath, - 0644, error)) + if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, selabeled_abspath, 0644, error)) return FALSE; - if (!glnx_file_replace_contents_at (os_deploy_dfd, selabeled, (guint8*)"", 0, - GLNX_FILE_REPLACE_DATASYNC_NEW, - cancellable, error)) + if (!glnx_file_replace_contents_at (os_deploy_dfd, selabeled, (guint8 *)"", 0, + GLNX_FILE_REPLACE_DATASYNC_NEW, cancellable, error)) return FALSE; } } @@ -843,58 +868,105 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot, * merge_configuration_from(). */ static gboolean -prepare_deployment_etc (OstreeSysroot *sysroot, - OstreeRepo *repo, - OstreeDeployment *deployment, - int deployment_dfd, - GCancellable *cancellable, - GError **error) +prepare_deployment_etc (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeployment *deployment, + int deployment_dfd, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Preparing /etc", error); + enum DirectoryState + { + DIRSTATE_NONEXISTENT, + DIRSTATE_EMPTY, + DIRSTATE_POPULATED, + }; + + enum DirectoryState etc_state; + { + gboolean exists = FALSE; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + if (!ot_dfd_iter_init_allow_noent (deployment_dfd, "etc", &dfd_iter, &exists, error)) + return glnx_prefix_error (error, "Failed to stat etc in deployment"); + if (!exists) + { + etc_state = DIRSTATE_NONEXISTENT; + } + else + { + struct dirent *dent; + if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, NULL, error)) + return FALSE; + if (dent) + etc_state = DIRSTATE_POPULATED; + else + etc_state = DIRSTATE_EMPTY; + } + } struct stat stbuf; - if (!glnx_fstatat_allow_noent (deployment_dfd, "etc", &stbuf, AT_SYMLINK_NOFOLLOW, error)) - return FALSE; - gboolean etc_exists = (errno == 0); if (!glnx_fstatat_allow_noent (deployment_dfd, "usr/etc", &stbuf, AT_SYMLINK_NOFOLLOW, error)) return FALSE; gboolean usretc_exists = (errno == 0); - if (etc_exists) - { - if (usretc_exists) - return glnx_throw (error, "Tree contains both /etc and /usr/etc"); - /* Compatibility hack */ - if (!glnx_renameat (deployment_dfd, "etc", deployment_dfd, "usr/etc", error)) - return FALSE; - usretc_exists = TRUE; + switch (etc_state) + { + case DIRSTATE_NONEXISTENT: + break; + case DIRSTATE_EMPTY: + { + if (usretc_exists) + { + /* For now it's actually simpler to just remove the empty directory + * and have a symmetrical code path. + */ + if (unlinkat (deployment_dfd, "etc", AT_REMOVEDIR) < 0) + return glnx_throw_errno_prefix (error, "Failed to remove empty etc"); + etc_state = DIRSTATE_NONEXISTENT; + } + /* Otherwise, there's no /etc or /usr/etc, we'll assume they know what they're doing... */ + } + break; + case DIRSTATE_POPULATED: + { + if (usretc_exists) + { + return glnx_throw (error, "Tree contains both /etc and /usr/etc"); + } + else + { + /* Compatibility hack */ + if (!glnx_renameat (deployment_dfd, "etc", deployment_dfd, "usr/etc", error)) + return FALSE; + etc_state = DIRSTATE_NONEXISTENT; + usretc_exists = TRUE; + } + } + break; } if (usretc_exists) { + g_assert (etc_state == DIRSTATE_NONEXISTENT); /* We need copies of /etc from /usr/etc (so admins can use vi), and if * SELinux is enabled, we need to relabel. */ - OstreeRepoCheckoutAtOptions etc_co_opts = { .force_copy = TRUE, - .subpath = "/usr/etc", - .sepolicy_prefix = "/etc"}; + OstreeRepoCheckoutAtOptions etc_co_opts + = { .force_copy = TRUE, .subpath = "/usr/etc", .sepolicy_prefix = "/etc" }; /* Here, we initialize SELinux policy from the /usr/etc inside * the root - this is before we've finalized the configuration * merge into /etc. */ - g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); + g_autoptr (OstreeSePolicy) sepolicy + = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); if (!sepolicy) return FALSE; if (ostree_sepolicy_get_name (sepolicy) != NULL) etc_co_opts.sepolicy = sepolicy; /* Copy usr/etc → etc */ - if (!ostree_repo_checkout_at (repo, &etc_co_opts, - deployment_dfd, "etc", - ostree_deployment_get_csum (deployment), - cancellable, error)) + if (!ostree_repo_checkout_at (repo, &etc_co_opts, deployment_dfd, "etc", + ostree_deployment_get_csum (deployment), cancellable, error)) return FALSE; - } return TRUE; @@ -904,44 +976,36 @@ prepare_deployment_etc (OstreeSysroot *sysroot, * the assumption the caller may be writing multiple. */ static gboolean -write_origin_file_internal (OstreeSysroot *sysroot, - OstreeSePolicy *sepolicy, - OstreeDeployment *deployment, - GKeyFile *new_origin, - GLnxFileReplaceFlags flags, - GCancellable *cancellable, - GError **error) +write_origin_file_internal (OstreeSysroot *sysroot, OstreeSePolicy *sepolicy, + OstreeDeployment *deployment, GKeyFile *new_origin, + GLnxFileReplaceFlags flags, GCancellable *cancellable, GError **error) { if (!_ostree_sysroot_ensure_writable (sysroot, error)) return FALSE; GLNX_AUTO_PREFIX_ERROR ("Writing out origin file", error); - GKeyFile *origin = - new_origin ? new_origin : ostree_deployment_get_origin (deployment); + GKeyFile *origin = new_origin ? new_origin : ostree_deployment_get_origin (deployment); if (origin) { - g_auto(OstreeSepolicyFsCreatecon) con = { 0, }; - if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, - "/etc/ostree/remotes.d/dummy.conf", + g_auto (OstreeSepolicyFsCreatecon) con = { + 0, + }; + if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, "/etc/ostree/remotes.d/dummy.conf", 0644, error)) return FALSE; - g_autofree char *origin_path = - g_strdup_printf ("ostree/deploy/%s/deploy/%s.%d.origin", - ostree_deployment_get_osname (deployment), - ostree_deployment_get_csum (deployment), - ostree_deployment_get_deployserial (deployment)); + g_autofree char *origin_path = g_strdup_printf ( + "ostree/deploy/%s/deploy/%s.%d.origin", ostree_deployment_get_osname (deployment), + ostree_deployment_get_csum (deployment), ostree_deployment_get_deployserial (deployment)); gsize len; g_autofree char *contents = g_key_file_to_data (origin, &len, error); if (!contents) return FALSE; - if (!glnx_file_replace_contents_at (sysroot->sysroot_fd, - origin_path, (guint8*)contents, len, - flags, - cancellable, error)) + if (!glnx_file_replace_contents_at (sysroot->sysroot_fd, origin_path, (guint8 *)contents, len, + flags, cancellable, error)) return FALSE; } @@ -961,20 +1025,16 @@ write_origin_file_internal (OstreeSysroot *sysroot, * this function will write the current origin of @deployment. */ gboolean -ostree_sysroot_write_origin_file (OstreeSysroot *sysroot, - OstreeDeployment *deployment, - GKeyFile *new_origin, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GFile) rootfs = g_file_new_for_path ("/"); - g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new (rootfs, cancellable, error); +ostree_sysroot_write_origin_file (OstreeSysroot *sysroot, OstreeDeployment *deployment, + GKeyFile *new_origin, GCancellable *cancellable, GError **error) +{ + g_autoptr (GFile) rootfs = g_file_new_for_path ("/"); + g_autoptr (OstreeSePolicy) sepolicy = ostree_sepolicy_new (rootfs, cancellable, error); if (!sepolicy) return FALSE; if (!write_origin_file_internal (sysroot, sepolicy, deployment, new_origin, - GLNX_FILE_REPLACE_DATASYNC_NEW, - cancellable, error)) + GLNX_FILE_REPLACE_DATASYNC_NEW, cancellable, error)) return FALSE; if (!_ostree_sysroot_bump_mtime (sysroot, error)) @@ -983,8 +1043,9 @@ ostree_sysroot_write_origin_file (OstreeSysroot *sysroot, return TRUE; } -typedef struct { - int boot_dfd; +typedef struct +{ + int boot_dfd; char *kernel_srcpath; char *kernel_namever; char *kernel_hmac_srcpath; @@ -993,6 +1054,8 @@ typedef struct { char *initramfs_namever; char *devicetree_srcpath; char *devicetree_namever; + char *aboot_srcpath; + char *aboot_namever; char *bootcsum; } OstreeKernelLayout; static void @@ -1007,12 +1070,14 @@ _ostree_kernel_layout_free (OstreeKernelLayout *layout) g_free (layout->initramfs_namever); g_free (layout->devicetree_srcpath); g_free (layout->devicetree_namever); + g_free (layout->aboot_srcpath); + g_free (layout->aboot_namever); g_free (layout->bootcsum); g_free (layout); } -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeKernelLayout, _ostree_kernel_layout_free); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeKernelLayout, _ostree_kernel_layout_free); -static OstreeKernelLayout* +static OstreeKernelLayout * _ostree_kernel_layout_new (void) { OstreeKernelLayout *ret = g_new0 (OstreeKernelLayout, 1); @@ -1022,18 +1087,18 @@ _ostree_kernel_layout_new (void) /* See get_kernel_from_tree() below */ static gboolean -get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, - int deployment_dfd, - OstreeKernelLayout **out_layout, - GCancellable *cancellable, - GError **error) +get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, int deployment_dfd, + OstreeKernelLayout **out_layout, GCancellable *cancellable, + GError **error) { g_autofree char *kver = NULL; /* Look in usr/lib/modules */ - g_auto(GLnxDirFdIterator) mod_dfditer = { 0, }; + g_auto (GLnxDirFdIterator) mod_dfditer = { + 0, + }; gboolean exists; - if (!ot_dfd_iter_init_allow_noent (deployment_dfd, "usr/lib/modules", &mod_dfditer, - &exists, error)) + if (!ot_dfd_iter_init_allow_noent (deployment_dfd, "usr/lib/modules", &mod_dfditer, &exists, + error)) return FALSE; if (!exists) { @@ -1042,10 +1107,10 @@ get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, return TRUE; } - g_autoptr(OstreeKernelLayout) ret_layout = _ostree_kernel_layout_new (); + g_autoptr (OstreeKernelLayout) ret_layout = _ostree_kernel_layout_new (); /* Reusable buffer for path string */ - g_autoptr(GString) pathbuf = g_string_new (""); + g_autoptr (GString) pathbuf = g_string_new (""); /* Loop until we find something that looks like a valid /usr/lib/modules/$kver */ while (ret_layout->boot_dfd == -1) { @@ -1092,13 +1157,15 @@ get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, } /* We found a module directory, compute the checksum */ - g_auto(OtChecksum) checksum = { 0, }; + g_auto (OtChecksum) checksum = { + 0, + }; ot_checksum_init (&checksum); glnx_autofd int fd = -1; /* Checksum the kernel */ if (!glnx_openat_rdonly (ret_layout->boot_dfd, "vmlinuz", TRUE, &fd, error)) return FALSE; - g_autoptr(GInputStream) in = g_unix_input_stream_new (fd, FALSE); + g_autoptr (GInputStream) in = g_unix_input_stream_new (fd, FALSE); if (!ot_gio_splice_update_checksum (NULL, in, &checksum, cancellable, error)) return FALSE; g_clear_object (&in); @@ -1108,9 +1175,9 @@ get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, * for this, let's be a bit conservative and support both `initramfs.img` and * `initramfs`. */ - const char *initramfs_paths[] = {"initramfs.img", "initramfs"}; + const char *initramfs_paths[] = { "initramfs.img", "initramfs" }; const char *initramfs_path = NULL; - for (guint i = 0; i < G_N_ELEMENTS(initramfs_paths); i++) + for (guint i = 0; i < G_N_ELEMENTS (initramfs_paths); i++) { initramfs_path = initramfs_paths[i]; if (!ot_openat_ignore_enoent (ret_layout->boot_dfd, initramfs_path, &fd, error)) @@ -1132,13 +1199,28 @@ get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, g_clear_object (&in); glnx_close_fd (&fd); + /* look for a aboot.img file. */ + if (!ot_openat_ignore_enoent (ret_layout->boot_dfd, "aboot.img", &fd, error)) + return FALSE; + + if (fd != -1) + { + ret_layout->aboot_srcpath = g_strdup ("aboot.img"); + ret_layout->aboot_namever = g_strdup_printf ("aboot-%s.img", kver); + } + glnx_close_fd (&fd); + + /* look for a aboot.cfg file. */ + if (!ot_openat_ignore_enoent (ret_layout->boot_dfd, "aboot.cfg", &fd, error)) + return FALSE; + /* Testing aid for https://github.com/ostreedev/ostree/issues/2154 */ const gboolean no_dtb = (sysroot->debug_flags & OSTREE_SYSROOT_DEBUG_TEST_NO_DTB) > 0; if (!no_dtb) { /* Check for /usr/lib/modules/$kver/devicetree first, if it does not - * exist check for /usr/lib/modules/$kver/dtb/ directory. - */ + * exist check for /usr/lib/modules/$kver/dtb/ directory. + */ if (!ot_openat_ignore_enoent (ret_layout->boot_dfd, "devicetree", &fd, error)) return FALSE; if (fd != -1) @@ -1162,7 +1244,8 @@ get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, ret_layout->devicetree_srcpath = g_strdup ("dtb"); ret_layout->devicetree_namever = NULL; - if (!checksum_dir_recurse(ret_layout->boot_dfd, "dtb", &checksum, cancellable, error)) + if (!checksum_dir_recurse (ret_layout->boot_dfd, "dtb", &checksum, cancellable, + error)) return FALSE; } } @@ -1176,11 +1259,13 @@ get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, if (errno == 0) { ret_layout->kernel_hmac_srcpath = g_strdup (".vmlinuz.hmac"); - /* Name it as dracut expects it: https://github.com/dracutdevs/dracut/blob/225e4b94cbdb702cf512490dcd2ad9ca5f5b22c1/modules.d/01fips/fips.sh#L129 */ + /* Name it as dracut expects it: + * https://github.com/dracutdevs/dracut/blob/225e4b94cbdb702cf512490dcd2ad9ca5f5b22c1/modules.d/01fips/fips.sh#L129 + */ ret_layout->kernel_hmac_namever = g_strdup_printf (".%s.hmac", ret_layout->kernel_namever); } - char hexdigest[OSTREE_SHA256_STRING_LEN+1]; + char hexdigest[OSTREE_SHA256_STRING_LEN + 1]; ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest)); ret_layout->bootcsum = g_strdup (hexdigest); @@ -1190,16 +1275,14 @@ get_kernel_from_tree_usrlib_modules (OstreeSysroot *sysroot, /* See get_kernel_from_tree() below */ static gboolean -get_kernel_from_tree_legacy_layouts (int deployment_dfd, - OstreeKernelLayout **out_layout, - GCancellable *cancellable, - GError **error) +get_kernel_from_tree_legacy_layouts (int deployment_dfd, OstreeKernelLayout **out_layout, + GCancellable *cancellable, GError **error) { - const char *legacy_paths[] = {"usr/lib/ostree-boot", "boot"}; + const char *legacy_paths[] = { "usr/lib/ostree-boot", "boot" }; g_autofree char *kernel_checksum = NULL; g_autofree char *initramfs_checksum = NULL; g_autofree char *devicetree_checksum = NULL; - g_autoptr(OstreeKernelLayout) ret_layout = _ostree_kernel_layout_new (); + g_autoptr (OstreeKernelLayout) ret_layout = _ostree_kernel_layout_new (); for (guint i = 0; i < G_N_ELEMENTS (legacy_paths); i++) { @@ -1224,7 +1307,9 @@ get_kernel_from_tree_legacy_layouts (int deployment_dfd, /* ret_layout->boot_dfd will point to either /usr/lib/ostree-boot or /boot, let's * inspect it. */ - g_auto(GLnxDirFdIterator) dfditer = { 0, }; + g_auto (GLnxDirFdIterator) dfditer = { + 0, + }; if (!glnx_dirfd_iterator_init_at (ret_layout->boot_dfd, ".", FALSE, &dfditer, error)) return FALSE; @@ -1279,9 +1364,8 @@ get_kernel_from_tree_legacy_layouts (int deployment_dfd, } /* If we found a kernel, an initramfs and a devicetree, break out of the loop */ - if (ret_layout->kernel_srcpath != NULL && - ret_layout->initramfs_srcpath != NULL && - ret_layout->devicetree_srcpath != NULL) + if (ret_layout->kernel_srcpath != NULL && ret_layout->initramfs_srcpath != NULL + && ret_layout->devicetree_srcpath != NULL) break; } @@ -1335,17 +1419,15 @@ get_kernel_from_tree_legacy_layouts (int deployment_dfd, * initramfs there, so we need to look in /usr/lib/ostree-boot first. */ static gboolean -get_kernel_from_tree (OstreeSysroot *sysroot, - int deployment_dfd, - OstreeKernelLayout **out_layout, - GCancellable *cancellable, - GError **error) +get_kernel_from_tree (OstreeSysroot *sysroot, int deployment_dfd, OstreeKernelLayout **out_layout, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeKernelLayout) usrlib_modules_layout = NULL; - g_autoptr(OstreeKernelLayout) legacy_layout = NULL; + g_autoptr (OstreeKernelLayout) usrlib_modules_layout = NULL; + g_autoptr (OstreeKernelLayout) legacy_layout = NULL; /* First, gather from usr/lib/modules/$kver if it exists */ - if (!get_kernel_from_tree_usrlib_modules (sysroot, deployment_dfd, &usrlib_modules_layout, cancellable, error)) + if (!get_kernel_from_tree_usrlib_modules (sysroot, deployment_dfd, &usrlib_modules_layout, + cancellable, error)) return FALSE; /* Gather the legacy layout */ @@ -1375,9 +1457,8 @@ get_kernel_from_tree (OstreeSysroot *sysroot, return TRUE; } } - else if (usrlib_modules_layout != NULL && - usrlib_modules_layout->initramfs_srcpath == NULL && - legacy_layout->initramfs_srcpath != NULL) + else if (usrlib_modules_layout != NULL && usrlib_modules_layout->initramfs_srcpath == NULL + && legacy_layout->initramfs_srcpath != NULL) { /* Does the module path not have an initramfs, but the legacy does? Prefer * the latter then, to make rpm-ostree work as is today. @@ -1410,10 +1491,7 @@ get_kernel_from_tree (OstreeSysroot *sysroot, * https://github.com/ostreedev/ostree/pull/1049 */ static gboolean -fsfreeze_thaw_cycle (OstreeSysroot *self, - int rootfs_dfd, - GCancellable *cancellable, - GError **error) +fsfreeze_thaw_cycle (OstreeSysroot *self, int rootfs_dfd, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("During fsfreeze-thaw", error); @@ -1427,7 +1505,7 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, if (pid < 0) return glnx_throw_errno_prefix (error, "fork"); - const gboolean debug_fifreeze = (self->debug_flags & OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE)>0; + const gboolean debug_fifreeze = (self->debug_flags & OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE) > 0; char c = '!'; if (pid == 0) /* Child watchdog/unfreezer process. */ { @@ -1476,7 +1554,7 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, * EOPNOTSUPP: If the filesystem doesn't support it */ int saved_errno = errno; - (void) TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)); + _ostree_linuxfs_filesystem_thaw (rootfs_dfd); errno = saved_errno; /* But if we got an error from poll, let's log it */ if (r < 0) @@ -1517,7 +1595,7 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, return glnx_throw (error, "aborting due to test-fifreeze"); } /* Do a freeze/thaw cycle; TODO add a FIFREEZETHAW ioctl */ - if (ioctl (rootfs_dfd, FIFREEZE, 0) != 0) + if (_ostree_linuxfs_filesystem_freeze (rootfs_dfd) != 0) { /* Not supported, we're running in the unit tests (as non-root), or * the filesystem is already frozen (EBUSY). @@ -1539,7 +1617,7 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, return glnx_throw_errno_prefix (error, "ioctl(FIFREEZE)"); } /* And finally thaw, then signal our completion to the watchdog */ - if (TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)) != 0) + if (_ostree_linuxfs_filesystem_thaw (rootfs_dfd) != 0) { /* Warn but don't error if the filesystem was already thawed */ if (errno == EINVAL) @@ -1553,118 +1631,45 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, return TRUE; } -typedef struct { +typedef struct +{ guint64 root_syncfs_msec; guint64 boot_syncfs_msec; - guint64 extra_syncfs_msec; } SyncStats; -typedef struct { - int ref_count; /* atomic */ - bool success; - GMutex mutex; - GCond cond; -} SyncData; - -static void -sync_data_unref (SyncData *data) -{ - if (!g_atomic_int_dec_and_test (&data->ref_count)) - return; - g_mutex_clear (&data->mutex); - g_cond_clear (&data->cond); - g_free (data); -} - -// An asynchronous sync() call. See below. -static void * -sync_in_thread (void *ptr) -{ - SyncData *syncdata = ptr; - // Ensure that the caller is blocked waiting - g_mutex_lock (&syncdata->mutex); - sync (); - // Signal success - syncdata->success = true; - g_cond_broadcast (&syncdata->cond); - g_mutex_unlock (&syncdata->mutex); - sync_data_unref (syncdata); - return NULL; -} - /* First, sync the root directory as well as /var and /boot which may * be separate mount points. Then *in addition*, do a global * `sync()`. */ static gboolean -full_system_sync (OstreeSysroot *self, - SyncStats *out_stats, - GCancellable *cancellable, - GError **error) +full_system_sync (OstreeSysroot *self, SyncStats *out_stats, GCancellable *cancellable, + GError **error) { GLNX_AUTO_PREFIX_ERROR ("Full sync", error); + ot_journal_print (LOG_INFO, "Starting syncfs() for system root"); guint64 start_msec = g_get_monotonic_time () / 1000; if (syncfs (self->sysroot_fd) != 0) return glnx_throw_errno_prefix (error, "syncfs(sysroot)"); guint64 end_msec = g_get_monotonic_time () / 1000; + ot_journal_print (LOG_INFO, "Completed syncfs() for system root in %" G_GUINT64_FORMAT " ms", + end_msec - start_msec); out_stats->root_syncfs_msec = (end_msec - start_msec); - if (!_ostree_sysroot_ensure_boot_fd (self, error)) + if (!_ostree_sysroot_ensure_boot_fd (self, error)) return FALSE; + g_assert_cmpint (self->boot_fd, !=, -1); + ot_journal_print (LOG_INFO, "Starting freeze/thaw cycle for system root"); start_msec = g_get_monotonic_time () / 1000; if (!fsfreeze_thaw_cycle (self, self->boot_fd, cancellable, error)) return FALSE; end_msec = g_get_monotonic_time () / 1000; + ot_journal_print (LOG_INFO, + "Completed freeze/thaw cycle for system root in %" G_GUINT64_FORMAT " ms", + end_msec - start_msec); out_stats->boot_syncfs_msec = (end_msec - start_msec); - /* And now out of an excess of conservativism, we still invoke - * sync(). The advantage of still using `syncfs()` above is that we - * actually get error codes out of that API, and we more clearly - * delineate what we actually want to sync in the future when this - * global sync call is removed. - * - * Due to https://bugzilla.redhat.com/show_bug.cgi?id=2003532 which is - * a bug in the interaction between Ceph and systemd, we have a capped - * timeout of 5s on the sync here. In general, we don't actually want - * to "own" flushing data on *all* mounted filesystems as part of - * our process. Again, we're only keeping the `sync` here out of - * conservatisim. We could likely just remove it and e.g. systemd - * would take care of sync as part of unmounting individual filesystems. - */ - start_msec = g_get_monotonic_time () / 1000; - if (!(self->opt_flags & OSTREE_SYSROOT_GLOBAL_OPT_SKIP_SYNC)) - { - SyncData *syncdata = g_new (SyncData, 1); - syncdata->ref_count = 2; // One for us, one for thread - syncdata->success = FALSE; - g_mutex_init (&syncdata->mutex); - g_cond_init (&syncdata->cond); - g_mutex_lock (&syncdata->mutex); - GThread *worker = g_thread_new ("ostree sync", sync_in_thread, syncdata); - // Wait up to 5 seconds for sync() to finish - gint64 end_time = g_get_monotonic_time () + (5 * G_TIME_SPAN_SECOND); - while (!syncdata->success) - { - if (!g_cond_wait_until (&syncdata->cond, &syncdata->mutex, end_time)) - { - ot_journal_print (LOG_INFO, "Timed out waiting for global sync()"); - break; - } - } - g_mutex_unlock (&syncdata->mutex); - sync_data_unref (syncdata); - // We can't join the thread here, for two reasons. First, the whole - // point here is to avoid blocking on `sync`. The other reason is - // today there is no return value on success from `sync`, so there's - // no point to joining the thread even if we had a nonblocking mechanism - // to do so. - g_thread_unref (worker); - } - end_msec = g_get_monotonic_time () / 1000; - out_stats->extra_syncfs_msec = (end_msec - start_msec); - return TRUE; } @@ -1675,11 +1680,8 @@ full_system_sync (OstreeSysroot *self, * These new links are made active by swap_bootlinks(). */ static gboolean -create_new_bootlinks (OstreeSysroot *self, - int bootversion, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error) +create_new_bootlinks (OstreeSysroot *self, int bootversion, GPtrArray *new_deployments, + GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Creating new current bootlinks", error); glnx_autofd int ostree_dfd = -1; @@ -1701,7 +1703,8 @@ create_new_bootlinks (OstreeSysroot *self, /* Create the "subbootdir", which is a directory holding a symlink farm pointing to * deployments per-osname. */ - g_autofree char *ostree_subbootdir_name = g_strdup_printf ("boot.%d.%d", bootversion, new_subbootversion); + g_autofree char *ostree_subbootdir_name + = g_strdup_printf ("boot.%d.%d", bootversion, new_subbootversion); if (!glnx_shutil_rm_rf_at (ostree_dfd, ostree_subbootdir_name, cancellable, error)) return FALSE; if (!glnx_shutil_mkdir_p_at (ostree_dfd, ostree_subbootdir_name, 0755, cancellable, error)) @@ -1714,17 +1717,17 @@ create_new_bootlinks (OstreeSysroot *self, for (guint i = 0; i < new_deployments->len; i++) { OstreeDeployment *deployment = new_deployments->pdata[i]; - g_autofree char *bootlink_parent = g_strconcat (ostree_deployment_get_osname (deployment), - "/", - ostree_deployment_get_bootcsum (deployment), - NULL); - g_autofree char *bootlink_pathname = g_strdup_printf ("%s/%d", bootlink_parent, ostree_deployment_get_bootserial (deployment)); - g_autofree char *bootlink_target = g_strdup_printf ("../../../deploy/%s/deploy/%s.%d", - ostree_deployment_get_osname (deployment), - ostree_deployment_get_csum (deployment), - ostree_deployment_get_deployserial (deployment)); - - if (!glnx_shutil_mkdir_p_at (ostree_subbootdir_dfd, bootlink_parent, 0755, cancellable, error)) + g_autofree char *bootlink_parent + = g_strconcat (ostree_deployment_get_osname (deployment), "/", + ostree_deployment_get_bootcsum (deployment), NULL); + g_autofree char *bootlink_pathname = g_strdup_printf ( + "%s/%d", bootlink_parent, ostree_deployment_get_bootserial (deployment)); + g_autofree char *bootlink_target = g_strdup_printf ( + "../../../deploy/%s/deploy/%s.%d", ostree_deployment_get_osname (deployment), + ostree_deployment_get_csum (deployment), ostree_deployment_get_deployserial (deployment)); + + if (!glnx_shutil_mkdir_p_at (ostree_subbootdir_dfd, bootlink_parent, 0755, cancellable, + error)) return FALSE; if (!symlink_at_replace (bootlink_target, ostree_subbootdir_dfd, bootlink_pathname, @@ -1738,12 +1741,8 @@ create_new_bootlinks (OstreeSysroot *self, /* Rename into place symlinks created via create_new_bootlinks(). */ static gboolean -swap_bootlinks (OstreeSysroot *self, - int bootversion, - GPtrArray *new_deployments, - char **out_subbootdir, - GCancellable *cancellable, - GError **error) +swap_bootlinks (OstreeSysroot *self, int bootversion, GPtrArray *new_deployments, + char **out_subbootdir, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Swapping new version bootlinks", error); glnx_autofd int ostree_dfd = -1; @@ -1762,9 +1761,10 @@ swap_bootlinks (OstreeSysroot *self, int new_subbootversion = old_subbootversion == 0 ? 1 : 0; g_autofree char *ostree_bootdir_name = g_strdup_printf ("boot.%d", bootversion); - g_autofree char *ostree_subbootdir_name = g_strdup_printf ("boot.%d.%d", bootversion, new_subbootversion); - if (!symlink_at_replace (ostree_subbootdir_name, ostree_dfd, ostree_bootdir_name, - cancellable, error)) + g_autofree char *ostree_subbootdir_name + = g_strdup_printf ("boot.%d.%d", bootversion, new_subbootversion); + if (!symlink_at_replace (ostree_subbootdir_name, ostree_dfd, ostree_bootdir_name, cancellable, + error)) return FALSE; if (out_subbootdir) *out_subbootdir = g_steal_pointer (&ostree_subbootdir_name); @@ -1772,8 +1772,7 @@ swap_bootlinks (OstreeSysroot *self, } static GHashTable * -parse_os_release (const char *contents, - const char *split) +parse_os_release (const char *contents, const char *split) { g_autofree char **lines = g_strsplit (contents, split, -1); GHashTable *ret = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -1806,45 +1805,44 @@ parse_os_release (const char *contents, * /boot/loader/entries. */ static gboolean -install_deployment_kernel (OstreeSysroot *sysroot, - OstreeRepo *repo, - int new_bootversion, - OstreeDeployment *deployment, - guint n_deployments, - gboolean show_osname, - GCancellable *cancellable, - GError **error) +install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion, + OstreeDeployment *deployment, guint n_deployments, gboolean show_osname, + GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Installing kernel", error); OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment); g_autofree char *deployment_dirpath = ostree_sysroot_get_deployment_dirpath (sysroot, deployment); glnx_autofd int deployment_dfd = -1; - if (!glnx_opendirat (sysroot->sysroot_fd, deployment_dirpath, FALSE, - &deployment_dfd, error)) + if (!glnx_opendirat (sysroot->sysroot_fd, deployment_dirpath, FALSE, &deployment_dfd, error)) return FALSE; /* We need to label the kernels */ - g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); + g_autoptr (OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); if (!sepolicy) return FALSE; /* Find the kernel/initramfs/devicetree in the tree */ - g_autoptr(OstreeKernelLayout) kernel_layout = NULL; - if (!get_kernel_from_tree (sysroot, deployment_dfd, &kernel_layout, - cancellable, error)) + g_autoptr (OstreeKernelLayout) kernel_layout = NULL; + if (!get_kernel_from_tree (sysroot, deployment_dfd, &kernel_layout, cancellable, error)) return FALSE; - if (!_ostree_sysroot_ensure_boot_fd (sysroot, error)) + if (!_ostree_sysroot_ensure_boot_fd (sysroot, error)) return FALSE; const char *osname = ostree_deployment_get_osname (deployment); const char *bootcsum = ostree_deployment_get_bootcsum (deployment); g_autofree char *bootcsumdir = g_strdup_printf ("ostree/%s-%s", osname, bootcsum); g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion); - g_autofree char *bootconf_name = g_strdup_printf ("ostree-%d-%s.conf", - n_deployments - ostree_deployment_get_index (deployment), - osname); + g_autofree char *bootconf_name = NULL; + guint index = n_deployments - ostree_deployment_get_index (deployment); + // Allow opt-in to dropping the stateroot, because grub2 parses the *filename* and ignores + // the version field. xref https://github.com/ostreedev/ostree/issues/2961 + bool use_new_naming = (sysroot->opt_flags & OSTREE_SYSROOT_GLOBAL_OPT_BOOTLOADER_NAMING_2) > 0; + if (use_new_naming) + bootconf_name = g_strdup_printf ("ostree-%d.conf", index); + else + bootconf_name = g_strdup_printf ("ostree-%d-%s.conf", index, osname); if (!glnx_shutil_mkdir_p_at (sysroot->boot_fd, bootcsumdir, 0775, cancellable, error)) return FALSE; @@ -1855,6 +1853,10 @@ install_deployment_kernel (OstreeSysroot *sysroot, if (!glnx_shutil_mkdir_p_at (sysroot->boot_fd, bootconfdir, 0775, cancellable, error)) return FALSE; + OstreeRepo *repo = ostree_sysroot_repo (sysroot); + + const char *bootprefix = repo->enable_bootprefix ? "/boot/" : "/"; + /* Install (hardlink/copy) the kernel into /boot/ostree/osname-${bootcsum} if * it doesn't exist already. */ @@ -1863,9 +1865,9 @@ install_deployment_kernel (OstreeSysroot *sysroot, return FALSE; if (errno == ENOENT) { - if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_srcpath, - bootcsum_dfd, kernel_layout->kernel_namever, - cancellable, error)) + if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, + kernel_layout->kernel_srcpath, bootcsum_dfd, + kernel_layout->kernel_namever, cancellable, error)) return FALSE; } @@ -1875,13 +1877,14 @@ install_deployment_kernel (OstreeSysroot *sysroot, if (kernel_layout->initramfs_srcpath) { g_assert (kernel_layout->initramfs_namever); - if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->initramfs_namever, &stbuf, 0, error)) + if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->initramfs_namever, &stbuf, 0, + error)) return FALSE; if (errno == ENOENT) { - if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->initramfs_srcpath, - bootcsum_dfd, kernel_layout->initramfs_namever, - cancellable, error)) + if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, + kernel_layout->initramfs_srcpath, bootcsum_dfd, + kernel_layout->initramfs_namever, cancellable, error)) return FALSE; } } @@ -1891,38 +1894,58 @@ install_deployment_kernel (OstreeSysroot *sysroot, /* If devicetree_namever is set a single device tree is deployed */ if (kernel_layout->devicetree_namever) { - if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->devicetree_namever, &stbuf, 0, error)) + if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->devicetree_namever, &stbuf, 0, + error)) return FALSE; if (errno == ENOENT) { - if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->devicetree_srcpath, - bootcsum_dfd, kernel_layout->devicetree_namever, - cancellable, error)) + if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, + kernel_layout->devicetree_srcpath, bootcsum_dfd, + kernel_layout->devicetree_namever, cancellable, error)) return FALSE; } } else { - if (!copy_dir_recurse(kernel_layout->boot_dfd, bootcsum_dfd, kernel_layout->devicetree_srcpath, - sysroot->debug_flags, cancellable, error)) + if (!copy_dir_recurse (kernel_layout->boot_dfd, bootcsum_dfd, + kernel_layout->devicetree_srcpath, sysroot->debug_flags, + cancellable, error)) return FALSE; } } if (kernel_layout->kernel_hmac_srcpath) { - if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->kernel_hmac_namever, &stbuf, 0, error)) + if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->kernel_hmac_namever, &stbuf, 0, + error)) return FALSE; if (errno == ENOENT) { - if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_hmac_srcpath, - bootcsum_dfd, kernel_layout->kernel_hmac_namever, - cancellable, error)) + if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, + kernel_layout->kernel_hmac_srcpath, bootcsum_dfd, + kernel_layout->kernel_hmac_namever, cancellable, error)) + return FALSE; + } + } + + if (kernel_layout->aboot_srcpath) + { + g_assert (kernel_layout->aboot_namever); + if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->aboot_namever, &stbuf, 0, error)) + return FALSE; + + if (errno == ENOENT) + { + if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, + kernel_layout->aboot_srcpath, bootcsum_dfd, + kernel_layout->aboot_namever, cancellable, error)) return FALSE; } } - g_autoptr(GPtrArray) overlay_initrds = NULL; + /* NOTE: if adding more things in bootcsum_dfd, also update get_kernel_layout_size() */ + + g_autoptr (GPtrArray) overlay_initrds = NULL; for (char **it = _ostree_deployment_get_overlay_initrds (deployment); it && *it; it++) { char *checksum = *it; @@ -1934,8 +1957,8 @@ install_deployment_kernel (OstreeSysroot *sysroot, * across different boocsums). Eventually, it'd be nice to have an OSTree repo in * /boot itself and drop the boocsum dir concept entirely. */ - g_autofree char *destpath = - g_strdup_printf ("/" _OSTREE_SYSROOT_BOOT_INITRAMFS_OVERLAYS "/%s.img", checksum); + g_autofree char *destpath = g_strdup_printf ( + "%s%s/%s.img", bootprefix, _OSTREE_SYSROOT_BOOT_INITRAMFS_OVERLAYS, checksum); const char *rel_destpath = destpath + 1; /* lazily allocate array and create dir so we don't pollute /boot if not needed */ @@ -1952,8 +1975,8 @@ install_deployment_kernel (OstreeSysroot *sysroot, return FALSE; if (errno == ENOENT) { - g_autofree char *srcpath = - g_strdup_printf (_OSTREE_SYSROOT_RUNSTATE_STAGED_INITRDS_DIR "/%s", checksum); + g_autofree char *srcpath + = g_strdup_printf (_OSTREE_SYSROOT_RUNSTATE_STAGED_INITRDS_DIR "/%s", checksum); if (!install_into_boot (repo, sepolicy, AT_FDCWD, srcpath, sysroot->boot_fd, rel_destpath, cancellable, error)) return FALSE; @@ -1981,11 +2004,11 @@ install_deployment_kernel (OstreeSysroot *sysroot, return glnx_prefix_error (error, "Reading /usr/lib/os-release"); } - g_autoptr(GHashTable) osrelease_values = parse_os_release (contents, "\n"); + g_autoptr (GHashTable) osrelease_values = parse_os_release (contents, "\n"); /* title */ const char *val = g_hash_table_lookup (osrelease_values, "PRETTY_NAME"); if (val == NULL) - val = g_hash_table_lookup (osrelease_values, "ID"); + val = g_hash_table_lookup (osrelease_values, "ID"); if (val == NULL) return glnx_throw (error, "No PRETTY_NAME or ID in /etc/os-release"); @@ -1994,24 +2017,24 @@ install_deployment_kernel (OstreeSysroot *sysroot, { /* Try extracting a version for this deployment. */ const char *csum = ostree_deployment_get_csum (deployment); - g_autoptr(GVariant) variant = NULL; - g_autoptr(GVariant) metadata = NULL; + g_autoptr (GVariant) variant = NULL; + g_autoptr (GVariant) metadata = NULL; /* XXX Copying ot_admin_checksum_version() + bits from * ot-admin-builtin-status.c. Maybe this should be * public API in libostree? */ - if (ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, csum, - &variant, NULL)) + if (ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, csum, &variant, NULL)) { metadata = g_variant_get_child_value (variant, 0); - g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", &deployment_version); + (void)g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", + &deployment_version); } } /* XXX The SYSLINUX bootloader backend actually parses the title string * (specifically, it looks for the substring "(ostree"), so further * changes to the title format may require updating that backend. */ - g_autoptr(GString) title_key = g_string_new (val); + g_autoptr (GString) title_key = g_string_new (val); if (deployment_version && *deployment_version && !strstr (val, deployment_version)) { g_string_append_c (title_key, ' '); @@ -2029,38 +2052,68 @@ install_deployment_kernel (OstreeSysroot *sysroot, g_string_append_c (title_key, ')'); ostree_bootconfig_parser_set (bootconfig, "title", title_key->str); - g_autofree char *version_key = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment)); + g_autofree char *version_key + = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment)); ostree_bootconfig_parser_set (bootconfig, OSTREE_COMMIT_META_KEY_VERSION, version_key); - g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", kernel_layout->kernel_namever, NULL); + g_autofree char *boot_relpath + = g_strconcat (bootprefix, bootcsumdir, "/", kernel_layout->kernel_namever, NULL); ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath); val = ostree_bootconfig_parser_get (bootconfig, "options"); - g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_from_string (val); + g_autoptr (OstreeKernelArgs) kargs = ostree_kernel_args_from_string (val); if (kernel_layout->initramfs_namever) { - g_autofree char * initrd_boot_relpath = - g_strconcat ("/", bootcsumdir, "/", kernel_layout->initramfs_namever, NULL); + g_autofree char *initrd_boot_relpath + = g_strconcat (bootprefix, bootcsumdir, "/", kernel_layout->initramfs_namever, NULL); ostree_bootconfig_parser_set (bootconfig, "initrd", initrd_boot_relpath); if (overlay_initrds) { g_ptr_array_add (overlay_initrds, NULL); - ostree_bootconfig_parser_set_overlay_initrds (bootconfig, (char**)overlay_initrds->pdata); + ostree_bootconfig_parser_set_overlay_initrds (bootconfig, + (char **)overlay_initrds->pdata); } } else { g_autofree char *prepare_root_arg = NULL; - prepare_root_arg = g_strdup_printf ("init=/ostree/boot.%d/%s/%s/%d/usr/lib/ostree/ostree-prepare-root", - new_bootversion, osname, bootcsum, - ostree_deployment_get_bootserial (deployment)); + prepare_root_arg = g_strdup_printf ( + "init=/ostree/boot.%d/%s/%s/%d/usr/lib/ostree/ostree-prepare-root", new_bootversion, + osname, bootcsum, ostree_deployment_get_bootserial (deployment)); ostree_kernel_args_replace_take (kargs, g_steal_pointer (&prepare_root_arg)); } + const char *aboot_fn = NULL; + if (kernel_layout->aboot_namever) + { + aboot_fn = kernel_layout->aboot_namever; + } + else if (kernel_layout->aboot_srcpath) + { + aboot_fn = kernel_layout->aboot_srcpath; + } + + if (aboot_fn) + { + g_autofree char *aboot_relpath = g_strconcat ("/", bootcsumdir, "/", aboot_fn, NULL); + ostree_bootconfig_parser_set (bootconfig, "aboot", aboot_relpath); + } + else + { + g_autofree char *aboot_relpath + = g_strconcat ("/", deployment_dirpath, "/usr/lib/ostree-boot/aboot.img", NULL); + ostree_bootconfig_parser_set (bootconfig, "aboot", aboot_relpath); + } + + g_autofree char *abootcfg_relpath + = g_strconcat ("/", deployment_dirpath, "/usr/lib/ostree-boot/aboot.cfg", NULL); + ostree_bootconfig_parser_set (bootconfig, "abootcfg", abootcfg_relpath); + if (kernel_layout->devicetree_namever) { - g_autofree char * dt_boot_relpath = g_strconcat ("/", bootcsumdir, "/", kernel_layout->devicetree_namever, NULL); + g_autofree char *dt_boot_relpath + = g_strconcat (bootprefix, bootcsumdir, "/", kernel_layout->devicetree_namever, NULL); ostree_bootconfig_parser_set (bootconfig, "devicetree", dt_boot_relpath); } else if (kernel_layout->devicetree_srcpath) @@ -2069,61 +2122,31 @@ install_deployment_kernel (OstreeSysroot *sysroot, * want to point to a whole directory of device trees. * See: https://github.com/ostreedev/ostree/issues/1900 */ - g_autofree char * dt_boot_relpath = g_strconcat ("/", bootcsumdir, "/", kernel_layout->devicetree_srcpath, NULL); + g_autofree char *dt_boot_relpath + = g_strconcat (bootprefix, bootcsumdir, "/", kernel_layout->devicetree_srcpath, NULL); ostree_bootconfig_parser_set (bootconfig, "fdtdir", dt_boot_relpath); } /* Note this is parsed in ostree-impl-system-generator.c */ - g_autofree char *ostree_kernel_arg = g_strdup_printf ("ostree=/ostree/boot.%d/%s/%s/%d", - new_bootversion, osname, bootcsum, - ostree_deployment_get_bootserial (deployment)); + g_autofree char *ostree_kernel_arg + = g_strdup_printf ("ostree=/ostree/boot.%d/%s/%s/%d", new_bootversion, osname, bootcsum, + ostree_deployment_get_bootserial (deployment)); ostree_kernel_args_replace_take (kargs, g_steal_pointer (&ostree_kernel_arg)); g_autofree char *options_key = ostree_kernel_args_to_string (kargs); ostree_bootconfig_parser_set (bootconfig, "options", options_key); - g_autoptr(GError) local_error = NULL; - GKeyFile *config = ostree_repo_get_config (repo); - gchar **read_values = g_key_file_get_string_list (config, "sysroot", "bls-append-except-default", NULL, &local_error); - /* We can ignore not found errors */ - if (!read_values) - { - gboolean not_found = g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) || \ - g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); - if (not_found) - { - g_clear_error (&local_error); - } - else - { - g_propagate_error (error, g_steal_pointer (&local_error)); - return FALSE; - } - } - /* Only append to this BLS config if: * - this is not the default deployment */ - /* If deployment was prepended, it is the new default */ + /* If deployment was prepended, it is the new default */ gboolean is_new_default = (ostree_deployment_get_index (deployment) == 0); gboolean allow_append = !is_new_default; if (allow_append) { /* get all key value pairs in bls-append */ - for (char **iter = read_values; iter && *iter; iter++) - { - const char *key_value = *iter; - const char *sep = strchr (key_value, '='); - if (sep == NULL) - { - glnx_throw (error, "bls-append-except-default key must be of the form \"key1=value1;key2=value2...\""); - return FALSE; - } - g_autofree char *key = g_strndup (key_value, sep - key_value); - g_autofree char *value = g_strdup (sep + 1); - ostree_bootconfig_parser_set (bootconfig, key, value); - } - + GLNX_HASH_TABLE_FOREACH_KV (repo->bls_append_values, const char *, key, const char *, value) + ostree_bootconfig_parser_set (bootconfig, key, value); } glnx_autofd int bootconf_dfd = -1; @@ -2131,8 +2154,7 @@ install_deployment_kernel (OstreeSysroot *sysroot, return FALSE; if (!ostree_bootconfig_parser_write_at (ostree_deployment_get_bootconfig (deployment), - bootconf_dfd, bootconf_name, - cancellable, error)) + bootconf_dfd, bootconf_name, cancellable, error)) return FALSE; return TRUE; @@ -2143,15 +2165,12 @@ install_deployment_kernel (OstreeSysroot *sysroot, * rename it into place. */ static gboolean -prepare_new_bootloader_link (OstreeSysroot *sysroot, - int current_bootversion, - int new_bootversion, - GCancellable *cancellable, - GError **error) +prepare_new_bootloader_link (OstreeSysroot *sysroot, int current_bootversion, int new_bootversion, + GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Preparing final bootloader swap", error); - g_assert ((current_bootversion == 0 && new_bootversion == 1) || - (current_bootversion == 1 && new_bootversion == 0)); + g_assert ((current_bootversion == 0 && new_bootversion == 1) + || (current_bootversion == 1 && new_bootversion == 0)); /* This allows us to support both /boot on a seperate filesystem to / as well * as on the same filesystem. */ @@ -2163,8 +2182,7 @@ prepare_new_bootloader_link (OstreeSysroot *sysroot, /* We shouldn't actually need to replace but it's easier to reuse that code */ - if (!symlink_at_replace (new_target, sysroot->sysroot_fd, "boot/loader.tmp", - cancellable, error)) + if (!symlink_at_replace (new_target, sysroot->sysroot_fd, "boot/loader.tmp", cancellable, error)) return FALSE; return TRUE; @@ -2172,19 +2190,15 @@ prepare_new_bootloader_link (OstreeSysroot *sysroot, /* Update the /boot/loader symlink to point to /boot/loader.$new_bootversion */ static gboolean -swap_bootloader (OstreeSysroot *sysroot, - OstreeBootloader *bootloader, - int current_bootversion, - int new_bootversion, - GCancellable *cancellable, - GError **error) +swap_bootloader (OstreeSysroot *sysroot, OstreeBootloader *bootloader, int current_bootversion, + int new_bootversion, GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Final bootloader swap", error); - g_assert ((current_bootversion == 0 && new_bootversion == 1) || - (current_bootversion == 1 && new_bootversion == 0)); + g_assert ((current_bootversion == 0 && new_bootversion == 1) + || (current_bootversion == 1 && new_bootversion == 0)); - if (!_ostree_sysroot_ensure_boot_fd (sysroot, error)) + if (!_ostree_sysroot_ensure_boot_fd (sysroot, error)) return FALSE; /* The symlink was already written, and we used syncfs() to ensure @@ -2222,10 +2236,9 @@ swap_bootloader (OstreeSysroot *sysroot, * per-bootchecksum. It's used by the symbolic links after the bootloader. */ static void -assign_bootserials (GPtrArray *deployments) +assign_bootserials (GPtrArray *deployments) { - g_autoptr(GHashTable) serials = - g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + g_autoptr (GHashTable) serials = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); for (guint i = 0; i < deployments->len; i++) { @@ -2233,36 +2246,34 @@ assign_bootserials (GPtrArray *deployments) const char *bootcsum = ostree_deployment_get_bootcsum (deployment); /* Note that not-found maps to NULL which converts to zero */ guint count = GPOINTER_TO_UINT (g_hash_table_lookup (serials, bootcsum)); - g_hash_table_replace (serials, (char*) bootcsum, - GUINT_TO_POINTER (count + 1)); + g_hash_table_replace (serials, (char *)bootcsum, GUINT_TO_POINTER (count + 1)); ostree_deployment_set_bootserial (deployment, count); } } -static char* +static char * get_deployment_nonostree_kargs (OstreeDeployment *deployment) { /* pick up kernel arguments but filter out ostree= */ OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment); const char *boot_options = ostree_bootconfig_parser_get (bootconfig, "options"); - g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_from_string (boot_options); + g_autoptr (OstreeKernelArgs) kargs = ostree_kernel_args_from_string (boot_options); ostree_kernel_args_replace (kargs, "ostree"); return ostree_kernel_args_to_string (kargs); } -static char* -get_deployment_ostree_version (OstreeRepo *repo, - OstreeDeployment *deployment) +static char * +get_deployment_ostree_version (OstreeRepo *repo, OstreeDeployment *deployment) { const char *csum = ostree_deployment_get_csum (deployment); g_autofree char *version = NULL; - g_autoptr(GVariant) variant = NULL; + g_autoptr (GVariant) variant = NULL; if (ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, csum, &variant, NULL)) { - g_autoptr(GVariant) metadata = g_variant_get_child_value (variant, 0); - g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", &version); + g_autoptr (GVariant) metadata = g_variant_get_child_value (variant, 0); + (void)g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", &version); } return g_steal_pointer (&version); @@ -2278,9 +2289,7 @@ get_deployment_ostree_version (OstreeRepo *repo, * bootloader perspective. */ static gboolean -deployment_bootconfigs_equal (OstreeRepo *repo, - OstreeDeployment *a, - OstreeDeployment *b) +deployment_bootconfigs_equal (OstreeRepo *repo, OstreeDeployment *a, OstreeDeployment *b) { /* same kernel & initramfs? */ const char *a_bootcsum = ostree_deployment_get_bootcsum (a); @@ -2313,11 +2322,9 @@ deployment_bootconfigs_equal (OstreeRepo *repo, * the OSTree API to find deployments. */ static gboolean -cleanup_legacy_current_symlinks (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +cleanup_legacy_current_symlinks (OstreeSysroot *self, GCancellable *cancellable, GError **error) { - g_autoptr(GString) buf = g_string_new (""); + g_autoptr (GString) buf = g_string_new (""); for (guint i = 0; i < self->deployments->len; i++) { @@ -2345,14 +2352,12 @@ cleanup_legacy_current_symlinks (OstreeSysroot *self, * version will perform post-deployment cleanup by default. */ gboolean -ostree_sysroot_write_deployments (OstreeSysroot *self, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error) +ostree_sysroot_write_deployments (OstreeSysroot *self, GPtrArray *new_deployments, + GCancellable *cancellable, GError **error) { OstreeSysrootWriteDeploymentsOpts opts = { .do_postclean = TRUE }; - return ostree_sysroot_write_deployments_with_options (self, new_deployments, &opts, - cancellable, error); + return ostree_sysroot_write_deployments_with_options (self, new_deployments, &opts, cancellable, + error); } /* Handle writing out a new bootloader config. One reason this needs to be a @@ -2360,31 +2365,20 @@ ostree_sysroot_write_deployments (OstreeSysroot *self, * rw. */ static gboolean -write_deployments_bootswap (OstreeSysroot *self, - GPtrArray *new_deployments, - OstreeSysrootWriteDeploymentsOpts *opts, - OstreeBootloader *bootloader, - SyncStats *out_syncstats, - char **out_subbootdir, - GCancellable *cancellable, - GError **error) +write_deployments_bootswap (OstreeSysroot *self, GPtrArray *new_deployments, + OstreeSysrootWriteDeploymentsOpts *opts, OstreeBootloader *bootloader, + SyncStats *out_syncstats, char **out_subbootdir, + GCancellable *cancellable, GError **error) { const int new_bootversion = self->bootversion ? 0 : 1; - g_autofree char* new_loader_entries_dir = g_strdup_printf ("boot/loader.%d/entries", new_bootversion); + g_autofree char *new_loader_entries_dir + = g_strdup_printf ("boot/loader.%d/entries", new_bootversion); if (!glnx_shutil_rm_rf_at (self->sysroot_fd, new_loader_entries_dir, cancellable, error)) return FALSE; - if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, new_loader_entries_dir, 0755, - cancellable, error)) + if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, new_loader_entries_dir, 0755, cancellable, error)) return FALSE; - /* Need the repo to try and extract the versions for deployments. - * But this is a "nice-to-have" for the bootloader UI, so failure - * here is not fatal to the whole operation. We just gracefully - * fall back to the deployment index. */ - g_autoptr(OstreeRepo) repo = NULL; - (void) ostree_sysroot_get_repo (self, &repo, cancellable, NULL); - /* Only show the osname in bootloader titles if there are multiple * osname's among the new deployments. Check for that here. */ gboolean show_osname = FALSE; @@ -2402,42 +2396,35 @@ write_deployments_bootswap (OstreeSysroot *self, for (guint i = 0; i < new_deployments->len; i++) { OstreeDeployment *deployment = new_deployments->pdata[i]; - if (!install_deployment_kernel (self, repo, new_bootversion, - deployment, new_deployments->len, + if (!install_deployment_kernel (self, new_bootversion, deployment, new_deployments->len, show_osname, cancellable, error)) return FALSE; } /* Create and swap bootlinks for *new* version */ - if (!create_new_bootlinks (self, new_bootversion, - new_deployments, - cancellable, error)) + if (!create_new_bootlinks (self, new_bootversion, new_deployments, cancellable, error)) return FALSE; g_autofree char *new_subbootdir = NULL; - if (!swap_bootlinks (self, new_bootversion, new_deployments, &new_subbootdir, - cancellable, error)) + if (!swap_bootlinks (self, new_bootversion, new_deployments, &new_subbootdir, cancellable, error)) return FALSE; - g_debug ("Using bootloader: %s", bootloader ? - g_type_name (G_TYPE_FROM_INSTANCE (bootloader)) : "(none)"); + g_debug ("Using bootloader: %s", + bootloader ? g_type_name (G_TYPE_FROM_INSTANCE (bootloader)) : "(none)"); if (bootloader) { - if (!_ostree_bootloader_write_config (bootloader, new_bootversion, - new_deployments, cancellable, - error)) + if (!_ostree_bootloader_write_config (bootloader, new_bootversion, new_deployments, + cancellable, error)) return glnx_prefix_error (error, "Bootloader write config"); } - if (!prepare_new_bootloader_link (self, self->bootversion, new_bootversion, - cancellable, error)) + if (!prepare_new_bootloader_link (self, self->bootversion, new_bootversion, cancellable, error)) return FALSE; if (!full_system_sync (self, out_syncstats, cancellable, error)) return FALSE; - if (!swap_bootloader (self, bootloader, self->bootversion, new_bootversion, - cancellable, error)) + if (!swap_bootloader (self, bootloader, self->bootversion, new_bootversion, cancellable, error)) return FALSE; if (out_subbootdir) @@ -2447,9 +2434,7 @@ write_deployments_bootswap (OstreeSysroot *self, /* Actions taken after writing deployments is complete */ static gboolean -write_deployments_finish (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +write_deployments_finish (OstreeSysroot *self, GCancellable *cancellable, GError **error) { if (!_ostree_sysroot_bump_mtime (self, error)) return FALSE; @@ -2464,6 +2449,295 @@ write_deployments_finish (OstreeSysroot *self, return TRUE; } +static gboolean +add_file_size_if_nonnull (int dfd, const char *path, guint64 *inout_size, GError **error) +{ + if (path == NULL) + return TRUE; + + struct stat stbuf; + if (!glnx_fstatat (dfd, path, &stbuf, 0, error)) + return FALSE; + + *inout_size += stbuf.st_size; + return TRUE; +} + +/* calculates the total size of the bootcsum dir in /boot after we would copy + * it. This reflects the logic in install_deployment_kernel(). */ +static gboolean +get_kernel_layout_size (OstreeSysroot *self, OstreeDeployment *deployment, guint64 *out_size, + GCancellable *cancellable, GError **error) +{ + g_autofree char *deployment_dirpath = ostree_sysroot_get_deployment_dirpath (self, deployment); + glnx_autofd int deployment_dfd = -1; + if (!glnx_opendirat (self->sysroot_fd, deployment_dirpath, FALSE, &deployment_dfd, error)) + return FALSE; + + g_autoptr (OstreeKernelLayout) kernel_layout = NULL; + if (!get_kernel_from_tree (self, deployment_dfd, &kernel_layout, cancellable, error)) + return FALSE; + + guint64 bootdir_size = 0; + if (!add_file_size_if_nonnull (kernel_layout->boot_dfd, kernel_layout->kernel_srcpath, + &bootdir_size, error)) + return FALSE; + if (!add_file_size_if_nonnull (kernel_layout->boot_dfd, kernel_layout->initramfs_srcpath, + &bootdir_size, error)) + return FALSE; + if (kernel_layout->devicetree_srcpath) + { + /* These conditionals mirror the logic in install_deployment_kernel(). */ + if (kernel_layout->devicetree_namever) + { + if (!add_file_size_if_nonnull (kernel_layout->boot_dfd, kernel_layout->devicetree_srcpath, + &bootdir_size, error)) + return FALSE; + } + else + { + guint64 dirsize = 0; + if (!ot_get_dir_size (kernel_layout->boot_dfd, kernel_layout->devicetree_srcpath, + &dirsize, cancellable, error)) + return FALSE; + bootdir_size += dirsize; + } + } + if (!add_file_size_if_nonnull (kernel_layout->boot_dfd, kernel_layout->kernel_hmac_srcpath, + &bootdir_size, error)) + return FALSE; + if (!add_file_size_if_nonnull (kernel_layout->boot_dfd, kernel_layout->aboot_srcpath, + &bootdir_size, error)) + return FALSE; + + *out_size = bootdir_size; + return TRUE; +} + +/* This is a roundabout but more trustworthy way of doing a space check than + * relying on statvfs's f_bfree when you know the size of the objects. */ +static gboolean +dfd_fallocate_check (int dfd, off_t len, gboolean *out_passed, GError **error) +{ + /* If the requested size is 0 then return early. Passing a 0 len to + * fallocate results in EINVAL */ + if (len == 0) + { + *out_passed = TRUE; + return TRUE; + } + + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_WRONLY | O_CLOEXEC, &tmpf, error)) + return FALSE; + + *out_passed = TRUE; + /* There's glnx_try_fallocate, but not with the same error semantics. */ + if (TEMP_FAILURE_RETRY (fallocate (tmpf.fd, 0, 0, len)) < 0) + { + if (G_IN_SET (errno, ENOSYS, EOPNOTSUPP)) + return TRUE; + else if (errno != ENOSPC) + return glnx_throw_errno_prefix (error, "fallocate"); + *out_passed = FALSE; + } + return TRUE; +} + +/* Analyze /boot and figure out if the new deployments won't fit in the + * remaining space. If they won't, check if deleting the deployments that are + * getting rotated out (e.g. the current rollback) would free up sufficient + * space. If so, call ostree_sysroot_write_deployments() to delete them. */ +static gboolean +auto_early_prune_old_deployments (OstreeSysroot *self, GPtrArray *new_deployments, + GCancellable *cancellable, GError **error) +{ + /* If we're not booted into a deployment, then this is some kind of e.g. disk + * creation/provisioning. The situation isn't as dire, so let's not resort to + * auto-pruning and instead let possible ENOSPC errors naturally bubble. */ + if (self->booted_deployment == NULL) + return TRUE; + + { + struct stat stbuf; + if (!glnx_fstatat (self->boot_fd, ".", &stbuf, 0, error)) + return FALSE; + + /* if /boot is on the same filesystem as the sysroot (which must be where + * the sysroot repo is), don't do anything */ + if (stbuf.st_dev == self->repo->device) + return TRUE; + } + + /* pre-emptive cleanup of any cruft in /boot to free up any wasted space */ + if (!_ostree_sysroot_cleanup_bootfs (self, cancellable, error)) + return FALSE; + + /* tracks all the bootcsums currently in /boot */ + g_autoptr (GHashTable) current_bootcsums + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + /* tracks all the bootcsums of new_deployments */ + g_autoptr (GHashTable) new_bootcsums + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + g_auto (GStrv) bootdirs = NULL; + if (!_ostree_sysroot_list_all_boot_directories (self, &bootdirs, cancellable, error)) + return glnx_prefix_error (error, "listing bootcsum directories in bootfs"); + + for (char **it = bootdirs; it && *it; it++) + { + const char *bootdir = *it; + + g_autofree char *bootcsum = NULL; + if (!_ostree_sysroot_parse_bootdir_name (bootdir, NULL, &bootcsum)) + g_assert_not_reached (); /* checked in _ostree_sysroot_list_all_boot_directories() */ + + guint64 bootdir_size; + g_autofree char *ostree_bootdir = g_build_filename ("ostree", bootdir, NULL); + if (!ot_get_dir_size (self->boot_fd, ostree_bootdir, &bootdir_size, cancellable, error)) + return FALSE; + + /* for our purposes of sizing bootcsums, it's highly unlikely we need a + * guint64; cast it down to guint so we can more easily store it */ + if (bootdir_size > G_MAXUINT) + { + /* If it somehow happens, don't make it fatal. this is all an + * optimization anyway, so let the deployment continue. But log it so + * that users report it and we tweak this code to handle this. + * + * An alternative is working with the block size instead, which would + * be easier to handle. But ideally, `ot_get_dir_size` would be block + * size aware too for better accuracy, which is awkward since the + * function itself is generic over directories and doesn't consider + * e.g. mount points from different filesystems. */ + g_printerr ("bootcsum %s size exceeds %u; disabling auto-prune optimization\n", bootdir, + G_MAXUINT); + return TRUE; + } + + g_assert_cmpuint (bootdir_size, >, 0); + g_hash_table_insert (current_bootcsums, g_steal_pointer (&bootcsum), + GUINT_TO_POINTER (bootdir_size)); + } + + /* total size of all bootcsums dirs that aren't already in /boot */ + guint64 net_new_bootcsum_dirs_total_size = 0; + + /* now gather all the bootcsums of the new deployments */ + for (guint i = 0; i < new_deployments->len; i++) + { + OstreeDeployment *deployment = new_deployments->pdata[i]; + + const char *bootcsum = ostree_deployment_get_bootcsum (deployment); + gpointer bootdir_sizep = g_hash_table_lookup (current_bootcsums, bootcsum); + if (bootdir_sizep != 0) + { + g_hash_table_insert (new_bootcsums, g_strdup (bootcsum), bootdir_sizep); + continue; + } + + guint64 bootdir_size = 0; + if (!get_kernel_layout_size (self, deployment, &bootdir_size, cancellable, error)) + return FALSE; + + /* see similar logic in previous loop */ + if (bootdir_size > G_MAXUINT) + { + g_printerr ( + "deployment %s kernel layout size exceeds %u; disabling auto-prune optimization\n", + ostree_deployment_get_csum (deployment), G_MAXUINT); + return TRUE; + } + + g_hash_table_insert (new_bootcsums, g_strdup (bootcsum), GUINT_TO_POINTER (bootdir_size)); + + /* it wasn't in current_bootcsums; add */ + net_new_bootcsum_dirs_total_size += bootdir_size; + } + + { + gboolean bootfs_has_space = FALSE; + if (!dfd_fallocate_check (self->boot_fd, net_new_bootcsum_dirs_total_size, &bootfs_has_space, + error)) + return glnx_prefix_error (error, "Checking if bootfs has sufficient space"); + + /* does the bootfs have enough free space for temporarily holding both the new + * and old bootdirs? */ + if (bootfs_has_space) + return TRUE; /* nothing to do! */ + } + + /* OK, we would fail if we tried to write the new bootdirs. Is it salvageable? + * First, calculate how much space we could save with the bootcsums scheduled + * for removal. */ + guint64 bootcsum_dirs_to_remove_total_size = 0; + GLNX_HASH_TABLE_FOREACH_KV (current_bootcsums, const char *, bootcsum, gpointer, sizep) + { + if (!g_hash_table_contains (new_bootcsums, bootcsum)) + bootcsum_dirs_to_remove_total_size += GPOINTER_TO_UINT (sizep); + } + + if (net_new_bootcsum_dirs_total_size > bootcsum_dirs_to_remove_total_size) + { + /* Check whether if we did early prune, we'd have enough space to write + * the new bootcsum dirs. */ + gboolean bootfs_has_space = FALSE; + if (!dfd_fallocate_check ( + self->boot_fd, net_new_bootcsum_dirs_total_size - bootcsum_dirs_to_remove_total_size, + &bootfs_has_space, error)) + return glnx_prefix_error (error, "Checking if prune would give bootfs sufficient space"); + + if (!bootfs_has_space) + { + /* Even if we auto-pruned, the new bootdirs wouldn't fit. Just let the + * code continue and let it hit ENOSPC. */ + g_printerr ("Disabling auto-prune optimization; insufficient space left in bootfs\n"); + return TRUE; + } + } + + g_printerr ("Insufficient space left in bootfs; updating bootloader in two steps\n"); + + /* Auto-pruning can salvage the situation. Calculate the set of deployments in common. */ + g_autoptr (GPtrArray) common_deployments = g_ptr_array_new (); + for (guint i = 0; i < self->deployments->len; i++) + { + OstreeDeployment *deployment = self->deployments->pdata[i]; + const char *bootcsum = ostree_deployment_get_bootcsum (deployment); + if (g_hash_table_contains (new_bootcsums, bootcsum)) + { + g_ptr_array_add (common_deployments, deployment); + } + else + { + /* we always keep the booted deployment */ + g_assert (deployment != self->booted_deployment); + } + } + + /* if we're here, it means that removing some deployments is possible to gain space */ + g_assert_cmpuint (common_deployments->len, <, self->deployments->len); + + /* Do an initial write out where we do a pure deployment pruning, keeping + * common deployments. To be safe, disable auto-pruning to make recursion + * impossible (though the logic in this function shouldn't kick in anyway in + * that recursive call). Disable cleaning since it's an intermediate stage. */ + OstreeSysrootWriteDeploymentsOpts opts + = { .do_postclean = FALSE, .disable_auto_early_prune = TRUE }; + if (!ostree_sysroot_write_deployments_with_options (self, common_deployments, &opts, cancellable, + error)) + return FALSE; + + /* clean up /boot */ + if (!_ostree_sysroot_cleanup_bootfs (self, cancellable, error)) + return FALSE; + + return TRUE; +} + /** * ostree_sysroot_write_deployments_with_options: * @self: Sysroot @@ -2482,17 +2756,20 @@ write_deployments_finish (OstreeSysroot *self, * Since: 2017.4 */ gboolean -ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, - GPtrArray *new_deployments, +ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, GPtrArray *new_deployments, OstreeSysrootWriteDeploymentsOpts *opts, - GCancellable *cancellable, - GError **error) + GCancellable *cancellable, GError **error) { g_assert (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED); if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; + const bool skip_early_prune = (self->opt_flags & OSTREE_SYSROOT_GLOBAL_OPT_NO_EARLY_PRUNE) > 0; + if (!skip_early_prune && !opts->disable_auto_early_prune + && !auto_early_prune_old_deployments (self, new_deployments, cancellable, error)) + return FALSE; + /* Dealing with the staged deployment is quite tricky here. This function is * primarily concerned with writing out "finalized" deployments which have * bootloader entries. Originally, we simply dropped the staged deployment @@ -2501,7 +2778,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, * silently dropped. */ - g_autoptr(GPtrArray) new_deployments_copy = g_ptr_array_new (); + g_autoptr (GPtrArray) new_deployments_copy = g_ptr_array_new (); gboolean removed_staged = (self->staged_deployment != NULL); if (new_deployments->len > 0) { @@ -2607,10 +2884,11 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, OstreeDeployment *deployment = new_deployments->pdata[i]; g_assert (!ostree_deployment_is_staged (deployment)); - if (deployment == self->booted_deployment) + if (ostree_deployment_equal (deployment, self->booted_deployment)) found_booted_deployment = TRUE; - g_autoptr(GFile) deployment_root = ostree_sysroot_get_deployment_directory (self, deployment); + g_autoptr (GFile) deployment_root + = ostree_sysroot_get_deployment_directory (self, deployment); if (!g_file_query_exists (deployment_root, NULL)) return glnx_throw (error, "Unable to find expected deployment root: %s", gs_file_get_path_cached (deployment_root)); @@ -2622,22 +2900,21 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, return glnx_throw (error, "Attempting to remove booted deployment"); gboolean bootloader_is_atomic = FALSE; - SyncStats syncstats = { 0, }; - g_autoptr(OstreeBootloader) bootloader = NULL; + SyncStats syncstats = { + 0, + }; + g_autoptr (OstreeBootloader) bootloader = NULL; g_autofree char *new_subbootdir = NULL; if (!requires_new_bootversion) { - if (!create_new_bootlinks (self, self->bootversion, - new_deployments, - cancellable, error)) + if (!create_new_bootlinks (self, self->bootversion, new_deployments, cancellable, error)) return FALSE; if (!full_system_sync (self, &syncstats, cancellable, error)) return FALSE; - if (!swap_bootlinks (self, self->bootversion, - new_deployments, &new_subbootdir, - cancellable, error)) + if (!swap_bootlinks (self, self->bootversion, new_deployments, &new_subbootdir, cancellable, + error)) return FALSE; bootloader_is_atomic = TRUE; @@ -2649,29 +2926,27 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, bootloader_is_atomic = bootloader != NULL && _ostree_bootloader_is_atomic (bootloader); - if (!write_deployments_bootswap (self, new_deployments, opts, bootloader, - &syncstats, &new_subbootdir, cancellable, error)) + if (!write_deployments_bootswap (self, new_deployments, opts, bootloader, &syncstats, + &new_subbootdir, cancellable, error)) return FALSE; } - { g_autofree char *msg = - g_strdup_printf ("%s; bootconfig swap: %s; bootversion: %s, deployment count change: %i", - (bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"), - requires_new_bootversion ? "yes" : "no", - new_subbootdir, - new_deployments->len - self->deployments->len); + { + g_autofree char *msg + = g_strdup_printf ("%s; bootconfig swap: %s; bootversion: %s, deployment count change: %i", + (bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"), + requires_new_bootversion ? "yes" : "no", new_subbootdir, + new_deployments->len - self->deployments->len); const gchar *bootloader_config = ostree_repo_get_bootloader (ostree_sysroot_repo (self)); - ot_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_DEPLOYMENT_COMPLETE_ID), - "MESSAGE=%s", msg, - "OSTREE_BOOTLOADER=%s", bootloader ? _ostree_bootloader_get_name (bootloader) : "none", - "OSTREE_BOOTLOADER_CONFIG=%s", bootloader_config, - "OSTREE_BOOTLOADER_ATOMIC=%s", bootloader_is_atomic ? "yes" : "no", - "OSTREE_DID_BOOTSWAP=%s", requires_new_bootversion ? "yes" : "no", - "OSTREE_N_DEPLOYMENTS=%u", new_deployments->len, - "OSTREE_SYNCFS_ROOT_MSEC=%" G_GUINT64_FORMAT, syncstats.root_syncfs_msec, - "OSTREE_SYNCFS_BOOT_MSEC=%" G_GUINT64_FORMAT, syncstats.boot_syncfs_msec, - "OSTREE_SYNCFS_EXTRA_MSEC=%" G_GUINT64_FORMAT, syncstats.extra_syncfs_msec, - NULL); + ot_journal_send ( + "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL (OSTREE_DEPLOYMENT_COMPLETE_ID), + "MESSAGE=%s", msg, "OSTREE_BOOTLOADER=%s", + bootloader ? _ostree_bootloader_get_name (bootloader) : "none", + "OSTREE_BOOTLOADER_CONFIG=%s", bootloader_config, "OSTREE_BOOTLOADER_ATOMIC=%s", + bootloader_is_atomic ? "yes" : "no", "OSTREE_DID_BOOTSWAP=%s", + requires_new_bootversion ? "yes" : "no", "OSTREE_N_DEPLOYMENTS=%u", new_deployments->len, + "OSTREE_SYNCFS_ROOT_MSEC=%" G_GUINT64_FORMAT, syncstats.root_syncfs_msec, + "OSTREE_SYNCFS_BOOT_MSEC=%" G_GUINT64_FORMAT, syncstats.boot_syncfs_msec, NULL); _ostree_sysroot_emit_journal_msg (self, msg); } @@ -2690,23 +2965,17 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, } static gboolean -allocate_deployserial (OstreeSysroot *self, - const char *osname, - const char *revision, - int *out_deployserial, - GCancellable *cancellable, - GError **error) +allocate_deployserial (OstreeSysroot *self, const char *osname, const char *revision, + int *out_deployserial, GCancellable *cancellable, GError **error) { int new_deployserial = 0; - g_autoptr(GPtrArray) tmp_current_deployments = - g_ptr_array_new_with_free_func (g_object_unref); + g_autoptr (GPtrArray) tmp_current_deployments = g_ptr_array_new_with_free_func (g_object_unref); glnx_autofd int deploy_dfd = -1; if (!glnx_opendirat (self->sysroot_fd, "ostree/deploy", TRUE, &deploy_dfd, error)) return FALSE; - if (!_ostree_sysroot_list_deployment_dirs_for_os (deploy_dfd, osname, - tmp_current_deployments, + if (!_ostree_sysroot_list_deployment_dirs_for_os (deploy_dfd, osname, tmp_current_deployments, cancellable, error)) return FALSE; @@ -2717,7 +2986,8 @@ allocate_deployserial (OstreeSysroot *self, if (strcmp (ostree_deployment_get_csum (deployment), revision) != 0) continue; - new_deployserial = MAX(new_deployserial, ostree_deployment_get_deployserial (deployment)+1); + new_deployserial + = MAX (new_deployserial, ostree_deployment_get_deployserial (deployment) + 1); } *out_deployserial = new_deployserial; @@ -2726,12 +2996,12 @@ allocate_deployserial (OstreeSysroot *self, void _ostree_deployment_set_bootconfig_from_kargs (OstreeDeployment *deployment, - char **override_kernel_argv) + char **override_kernel_argv) { /* Create an empty boot configuration; we will merge things into * it as we go. */ - g_autoptr(OstreeBootconfigParser) bootconfig = ostree_bootconfig_parser_new (); + g_autoptr (OstreeBootconfigParser) bootconfig = ostree_bootconfig_parser_new (); ostree_deployment_set_bootconfig (deployment, bootconfig); /* After this, install_deployment_kernel() will set the other boot @@ -2739,7 +3009,7 @@ _ostree_deployment_set_bootconfig_from_kargs (OstreeDeployment *deployment, */ if (override_kernel_argv) { - g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_new (); + g_autoptr (OstreeKernelArgs) kargs = ostree_kernel_args_new (); ostree_kernel_args_append_argv (kargs, override_kernel_argv); g_autofree char *new_options = ostree_kernel_args_to_string (kargs); ostree_bootconfig_parser_set (bootconfig, "options", new_options); @@ -2750,14 +3020,12 @@ _ostree_deployment_set_bootconfig_from_kargs (OstreeDeployment *deployment, // that are likely to fail later. This function only returns // a hard error if something unexpected (e.g. I/O error) occurs. static gboolean -lint_deployment_fs (OstreeSysroot *self, - OstreeDeployment *deployment, - int deployment_dfd, - GCancellable *cancellable, - GError **error) +lint_deployment_fs (OstreeSysroot *self, OstreeDeployment *deployment, int deployment_dfd, + GCancellable *cancellable, GError **error) { - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - glnx_autofd int dest_dfd = -1; + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; gboolean exists; if (!ot_dfd_iter_init_allow_noent (deployment_dfd, "var", &dfd_iter, &exists, error)) @@ -2771,60 +3039,71 @@ lint_deployment_fs (OstreeSysroot *self, if (dent == NULL) break; - fprintf (stderr, "note: Deploying commit %s which contains content in /var/%s that will be ignored.\n", - ostree_deployment_get_csum (deployment), - dent->d_name); + fprintf ( + stderr, + "note: Deploying commit %s which contains content in /var/%s that will be ignored.\n", + ostree_deployment_get_csum (deployment), dent->d_name); } return TRUE; } +static gboolean +require_stateroot (OstreeSysroot *self, const char *stateroot, GError **error) +{ + const char *osdeploypath = glnx_strjoina ("ostree/deploy/", stateroot); + if (!glnx_fstatat_allow_noent (self->sysroot_fd, osdeploypath, NULL, 0, error)) + return FALSE; + if (errno == ENOENT) + return glnx_throw (error, "No such stateroot: %s", stateroot); + return TRUE; +} + /* The first part of writing a deployment. This primarily means doing the * hardlink farm checkout, but we also compute some initial state. */ static gboolean -sysroot_initialize_deployment (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeSysrootDeployTreeOpts *opts, - OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error) +sysroot_initialize_deployment (OstreeSysroot *self, const char *osname, const char *revision, + GKeyFile *origin, OstreeSysrootDeployTreeOpts *opts, + OstreeDeployment **out_new_deployment, GCancellable *cancellable, + GError **error) { - g_return_val_if_fail (osname != NULL || self->booted_deployment != NULL, FALSE); + GLNX_AUTO_PREFIX_ERROR ("Initializing deployment", error); + + g_assert (osname != NULL || self->booted_deployment != NULL); if (osname == NULL) osname = ostree_deployment_get_osname (self->booted_deployment); + if (!require_stateroot (self, osname, error)) + return FALSE; + OstreeRepo *repo = ostree_sysroot_repo (self); gint new_deployserial; - if (!allocate_deployserial (self, osname, revision, &new_deployserial, - cancellable, error)) + if (!allocate_deployserial (self, osname, revision, &new_deployserial, cancellable, error)) return FALSE; - g_autoptr(OstreeDeployment) new_deployment = - ostree_deployment_new (0, osname, revision, new_deployserial, NULL, -1); + g_autoptr (OstreeDeployment) new_deployment + = ostree_deployment_new (0, osname, revision, new_deployserial, NULL, -1); ostree_deployment_set_origin (new_deployment, origin); /* Check out the userspace tree onto the filesystem */ glnx_autofd int deployment_dfd = -1; - if (!checkout_deployment_tree (self, repo, new_deployment, &deployment_dfd, - cancellable, error)) + if (!checkout_deployment_tree (self, repo, new_deployment, revision, &deployment_dfd, cancellable, + error)) return FALSE; - g_autoptr(OstreeKernelLayout) kernel_layout = NULL; - if (!get_kernel_from_tree (self, deployment_dfd, &kernel_layout, - cancellable, error)) + g_autoptr (OstreeKernelLayout) kernel_layout = NULL; + if (!get_kernel_from_tree (self, deployment_dfd, &kernel_layout, cancellable, error)) return FALSE; _ostree_deployment_set_bootcsum (new_deployment, kernel_layout->bootcsum); - _ostree_deployment_set_bootconfig_from_kargs (new_deployment, opts ? opts->override_kernel_argv : NULL); + _ostree_deployment_set_bootconfig_from_kargs (new_deployment, + opts ? opts->override_kernel_argv : NULL); _ostree_deployment_set_overlay_initrds (new_deployment, opts ? opts->overlay_initrds : NULL); - if (!prepare_deployment_etc (self, repo, new_deployment, deployment_dfd, - cancellable, error)) + if (!prepare_deployment_etc (self, repo, new_deployment, deployment_dfd, cancellable, error)) return FALSE; if (!lint_deployment_fs (self, new_deployment, deployment_dfd, cancellable, error)) @@ -2844,14 +3123,11 @@ sysroot_initialize_deployment (OstreeSysroot *self, * nor (relatedly) the case of upgrading a separate stateroot. */ static gboolean -get_var_dfd (OstreeSysroot *self, - int osdeploy_dfd, - OstreeDeployment *deployment, - int *ret_fd, - GError **error) +get_var_dfd (OstreeSysroot *self, int osdeploy_dfd, OstreeDeployment *deployment, int *ret_fd, + GError **error) { - const char *booted_stateroot = - self->booted_deployment ? ostree_deployment_get_osname (self->booted_deployment) : NULL; + const char *booted_stateroot + = self->booted_deployment ? ostree_deployment_get_osname (self->booted_deployment) : NULL; int base_dfd; const char *base_path; @@ -2879,8 +3155,8 @@ get_var_dfd (OstreeSysroot *self, static void child_setup_fchdir (gpointer data) { - int fd = (int) (uintptr_t) data; - int rc __attribute__((unused)); + int fd = (int)(uintptr_t)data; + int rc __attribute__ ((unused)); rc = fchdir (fd); } @@ -2889,35 +3165,65 @@ child_setup_fchdir (gpointer data) * Derived from rpm-ostree's rust/src/bwrap.rs */ static gboolean -run_in_deployment (int deployment_dfd, - const gchar * const *child_argv, - gsize child_argc, - gint *exit_status, - gchar **stdout, - GError **error) +run_in_deployment (int deployment_dfd, const gchar *const *child_argv, gsize child_argc, + gint *exit_status, gchar **stdout, GError **error) { - static const gchar * const COMMON_ARGV[] = { + static const gchar *const COMMON_ARGV[] = { "/usr/bin/bwrap", - "--dev", "/dev", "--proc", "/proc", "--dir", "/run", "--dir", "/tmp", - "--chdir", "/", + "--dev", + "/dev", + "--proc", + "/proc", + "--dir", + "/run", + "--dir", + "/tmp", + "--chdir", + "/", "--die-with-parent", "--unshare-pid", "--unshare-uts", "--unshare-ipc", "--unshare-cgroup-try", - "--ro-bind", "/sys/block", "/sys/block", - "--ro-bind", "/sys/bus", "/sys/bus", - "--ro-bind", "/sys/class", "/sys/class", - "--ro-bind", "/sys/dev", "/sys/dev", - "--ro-bind", "/sys/devices", "/sys/devices", - "--bind", "usr", "/usr", - "--bind", "etc", "/etc", - "--bind", "var", "/var", - "--symlink", "/usr/lib", "/lib", - "--symlink", "/usr/lib32", "/lib32", - "--symlink", "/usr/lib64", "/lib64", - "--symlink", "/usr/bin", "/bin", - "--symlink", "/usr/sbin", "/sbin", + "--ro-bind", + "/sys/block", + "/sys/block", + "--ro-bind", + "/sys/bus", + "/sys/bus", + "--ro-bind", + "/sys/class", + "/sys/class", + "--ro-bind", + "/sys/dev", + "/sys/dev", + "--ro-bind", + "/sys/devices", + "/sys/devices", + "--bind", + "usr", + "/usr", + "--bind", + "etc", + "/etc", + "--bind", + "var", + "/var", + "--symlink", + "/usr/lib", + "/lib", + "--symlink", + "/usr/lib32", + "/lib32", + "--symlink", + "/usr/lib64", + "/lib64", + "--symlink", + "/usr/bin", + "/bin", + "--symlink", + "/usr/sbin", + "/sbin", }; static const gsize COMMON_ARGC = sizeof (COMMON_ARGV) / sizeof (*COMMON_ARGV); @@ -2926,18 +3232,17 @@ run_in_deployment (int deployment_dfd, g_autofree gchar **args_raw = NULL; for (i = 0; i < COMMON_ARGC; i++) - g_ptr_array_add (args, (gchar *) COMMON_ARGV[i]); + g_ptr_array_add (args, (gchar *)COMMON_ARGV[i]); for (i = 0; i < child_argc; i++) - g_ptr_array_add (args, (gchar *) child_argv[i]); + g_ptr_array_add (args, (gchar *)child_argv[i]); g_ptr_array_add (args, NULL); - args_raw = (gchar **) g_ptr_array_free (args, FALSE); + args_raw = (gchar **)g_ptr_array_free (args, FALSE); return g_spawn_sync (NULL, args_raw, NULL, 0, &child_setup_fchdir, - (gpointer) (uintptr_t) deployment_dfd, - stdout, NULL, exit_status, error); + (gpointer)(uintptr_t)deployment_dfd, stdout, NULL, exit_status, error); } /* @@ -2947,12 +3252,13 @@ run_in_deployment (int deployment_dfd, static gboolean sysroot_finalize_selinux_policy (int deployment_dfd, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Finalizing SELinux policy", error); struct stat stbuf; gint exit_status; g_autofree gchar *stdout = NULL; - if (!glnx_fstatat_allow_noent (deployment_dfd, "etc/selinux/config", &stbuf, - AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat_allow_noent (deployment_dfd, "etc/selinux/config", &stbuf, AT_SYMLINK_NOFOLLOW, + error)) return FALSE; /* Skip the SELinux policy refresh if /etc/selinux/config doesn't exist. */ @@ -2960,43 +3266,45 @@ sysroot_finalize_selinux_policy (int deployment_dfd, GError **error) return TRUE; /* - * Skip the SELinux policy refresh if the --rebuild-if-modules-changed + * Skip the SELinux policy refresh if the --refresh * flag is not supported by semodule. */ - static const gchar * const SEMODULE_HELP_ARGV[] = { - "semodule", "--help" - }; - static const gsize SEMODULE_HELP_ARGC = sizeof (SEMODULE_HELP_ARGV) / sizeof (*SEMODULE_HELP_ARGV); - if (!run_in_deployment (deployment_dfd, SEMODULE_HELP_ARGV, - SEMODULE_HELP_ARGC, &exit_status, &stdout, error)) + static const gchar *const SEMODULE_HELP_ARGV[] = { "semodule", "--help" }; + static const gsize SEMODULE_HELP_ARGC + = sizeof (SEMODULE_HELP_ARGV) / sizeof (*SEMODULE_HELP_ARGV); + if (!run_in_deployment (deployment_dfd, SEMODULE_HELP_ARGV, SEMODULE_HELP_ARGC, &exit_status, + &stdout, error)) return FALSE; if (!g_spawn_check_exit_status (exit_status, error)) return glnx_prefix_error (error, "failed to run semodule"); - if (!strstr(stdout, "--rebuild-if-modules-changed")) + if (!strstr (stdout, "--refresh")) { - ot_journal_print (LOG_INFO, "semodule does not have --rebuild-if-modules-changed"); + ot_journal_print (LOG_INFO, "semodule does not have --refresh"); return TRUE; } - static const gchar * const SEMODULE_REBUILD_ARGV[] = { - "semodule", "-N", "--rebuild-if-modules-changed" - }; - static const gsize SEMODULE_REBUILD_ARGC = sizeof (SEMODULE_REBUILD_ARGV) / sizeof (*SEMODULE_REBUILD_ARGV); + static const gchar *const SEMODULE_REBUILD_ARGV[] = { "semodule", "-N", "--refresh" }; + static const gsize SEMODULE_REBUILD_ARGC + = sizeof (SEMODULE_REBUILD_ARGV) / sizeof (*SEMODULE_REBUILD_ARGV); - if (!run_in_deployment (deployment_dfd, SEMODULE_REBUILD_ARGV, - SEMODULE_REBUILD_ARGC, &exit_status, NULL, error)) + ot_journal_print (LOG_INFO, "Refreshing SELinux policy"); + guint64 start_msec = g_get_monotonic_time () / 1000; + if (!run_in_deployment (deployment_dfd, SEMODULE_REBUILD_ARGV, SEMODULE_REBUILD_ARGC, + &exit_status, NULL, error)) return FALSE; + guint64 end_msec = g_get_monotonic_time () / 1000; + ot_journal_print (LOG_INFO, "Refreshed SELinux policy in %" G_GUINT64_FORMAT " ms", + end_msec - start_msec); return g_spawn_check_exit_status (exit_status, error); } #endif /* HAVE_SELINUX */ static gboolean -sysroot_finalize_deployment (OstreeSysroot *self, - OstreeDeployment *deployment, - OstreeDeployment *merge_deployment, - GCancellable *cancellable, - GError **error) +sysroot_finalize_deployment (OstreeSysroot *self, OstreeDeployment *deployment, + OstreeDeployment *merge_deployment, GCancellable *cancellable, + GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Finalizing deployment", error); g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); glnx_autofd int deployment_dfd = -1; if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error)) @@ -3009,13 +3317,13 @@ sysroot_finalize_deployment (OstreeSysroot *self, * finalize-staged path, they're set by OstreeSysroot when reading the staged GVariant. */ if (merge_deployment && ostree_bootconfig_parser_get (bootconfig, "options") == NULL) { - OstreeBootconfigParser *merge_bootconfig = ostree_deployment_get_bootconfig (merge_deployment); + OstreeBootconfigParser *merge_bootconfig + = ostree_deployment_get_bootconfig (merge_deployment); if (merge_bootconfig) { const char *kargs = ostree_bootconfig_parser_get (merge_bootconfig, "options"); ostree_bootconfig_parser_set (bootconfig, "options", kargs); } - } if (merge_deployment) @@ -3024,14 +3332,15 @@ sysroot_finalize_deployment (OstreeSysroot *self, if (!merge_configuration_from (self, merge_deployment, deployment, deployment_dfd, cancellable, error)) return FALSE; - } #ifdef HAVE_SELINUX - if (!sysroot_finalize_selinux_policy(deployment_dfd, error)) - return FALSE; + if (!sysroot_finalize_selinux_policy (deployment_dfd, error)) + return FALSE; #endif /* HAVE_SELINUX */ + } - const char *osdeploypath = glnx_strjoina ("ostree/deploy/", ostree_deployment_get_osname (deployment)); + const char *osdeploypath + = glnx_strjoina ("ostree/deploy/", ostree_deployment_get_osname (deployment)); glnx_autofd int os_deploy_dfd = -1; if (!glnx_opendirat (self->sysroot_fd, osdeploypath, TRUE, &os_deploy_dfd, error)) return FALSE; @@ -3048,7 +3357,7 @@ sysroot_finalize_deployment (OstreeSysroot *self, if (!ot_ensure_unlinked_at (var_dfd, ".updated", error)) return FALSE; - g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); + g_autoptr (OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); if (!sepolicy) return FALSE; @@ -3060,15 +3369,13 @@ sysroot_finalize_deployment (OstreeSysroot *self, */ if (!write_origin_file_internal (self, sepolicy, deployment, ostree_deployment_get_origin (deployment), - GLNX_FILE_REPLACE_NODATASYNC, - cancellable, error)) + GLNX_FILE_REPLACE_NODATASYNC, cancellable, error)) return FALSE; /* Seal it */ if (!(self->debug_flags & OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS)) { - if (!ostree_sysroot_deployment_set_mutable (self, deployment, FALSE, - cancellable, error)) + if (!ostree_sysroot_deployment_set_mutable (self, deployment, FALSE, cancellable, error)) return FALSE; } @@ -3078,12 +3385,12 @@ sysroot_finalize_deployment (OstreeSysroot *self, /** * ostree_sysroot_deploy_tree_with_options: * @self: Sysroot - * @osname: (allow-none): osname to use for merge deployment + * @osname: (nullable): osname to use for merge deployment * @revision: Checksum to add - * @origin: (allow-none): Origin to use for upgrades - * @provided_merge_deployment: (allow-none): Use this deployment for merge path - * @opts: (allow-none): Options - * @out_new_deployment: (out): The new deployment path + * @origin: (nullable): Origin to use for upgrades + * @provided_merge_deployment: (nullable): Use this deployment for merge path + * @opts: (nullable): Options + * @out_new_deployment: (out) (transfer full): The new deployment path * @cancellable: Cancellable * @error: Error * @@ -3096,26 +3403,25 @@ sysroot_finalize_deployment (OstreeSysroot *self, * Since: 2020.7 */ gboolean -ostree_sysroot_deploy_tree_with_options (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *provided_merge_deployment, +ostree_sysroot_deploy_tree_with_options (OstreeSysroot *self, const char *osname, + const char *revision, GKeyFile *origin, + OstreeDeployment *provided_merge_deployment, OstreeSysrootDeployTreeOpts *opts, OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error) + GCancellable *cancellable, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Deploying tree", error); + if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; - g_autoptr(OstreeDeployment) deployment = NULL; - if (!sysroot_initialize_deployment (self, osname, revision, origin, opts, - &deployment, cancellable, error)) + g_autoptr (OstreeDeployment) deployment = NULL; + if (!sysroot_initialize_deployment (self, osname, revision, origin, opts, &deployment, + cancellable, error)) return FALSE; - if (!sysroot_finalize_deployment (self, deployment, provided_merge_deployment, - cancellable, error)) + if (!sysroot_finalize_deployment (self, deployment, provided_merge_deployment, cancellable, + error)) return FALSE; *out_new_deployment = g_steal_pointer (&deployment); @@ -3125,11 +3431,12 @@ ostree_sysroot_deploy_tree_with_options (OstreeSysroot *self, /** * ostree_sysroot_deploy_tree: * @self: Sysroot - * @osname: (allow-none): osname to use for merge deployment + * @osname: (nullable): osname to use for merge deployment * @revision: Checksum to add - * @origin: (allow-none): Origin to use for upgrades - * @provided_merge_deployment: (allow-none): Use this deployment for merge path - * @override_kernel_argv: (allow-none) (array zero-terminated=1) (element-type utf8): Use these as kernel arguments; if %NULL, inherit options from provided_merge_deployment + * @origin: (nullable): Origin to use for upgrades + * @provided_merge_deployment: (nullable): Use this deployment for merge path + * @override_kernel_argv: (nullable) (array zero-terminated=1) (element-type utf8): Use these as + * kernel arguments; if %NULL, inherit options from provided_merge_deployment * @out_new_deployment: (out): The new deployment path * @cancellable: Cancellable * @error: Error @@ -3139,15 +3446,10 @@ ostree_sysroot_deploy_tree_with_options (OstreeSysroot *self, * Since: 2018.5 */ gboolean -ostree_sysroot_deploy_tree (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *provided_merge_deployment, - char **override_kernel_argv, - OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error) +ostree_sysroot_deploy_tree (OstreeSysroot *self, const char *osname, const char *revision, + GKeyFile *origin, OstreeDeployment *provided_merge_deployment, + char **override_kernel_argv, OstreeDeployment **out_new_deployment, + GCancellable *cancellable, GError **error) { OstreeSysrootDeployTreeOpts opts = { .override_kernel_argv = override_kernel_argv }; return ostree_sysroot_deploy_tree_with_options (self, osname, revision, origin, @@ -3161,13 +3463,11 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self, static GVariant * serialize_deployment_to_variant (OstreeDeployment *deployment) { - g_auto(GVariantBuilder) builder = OT_VARIANT_BUILDER_INITIALIZER; - g_variant_builder_init (&builder, (GVariantType*)"a{sv}"); - g_autofree char *name = - g_strdup_printf ("%s.%d", ostree_deployment_get_csum (deployment), - ostree_deployment_get_deployserial (deployment)); - g_variant_builder_add (&builder, "{sv}", "name", - g_variant_new_string (name)); + g_auto (GVariantBuilder) builder = OT_VARIANT_BUILDER_INITIALIZER; + g_variant_builder_init (&builder, (GVariantType *)"a{sv}"); + g_autofree char *name = g_strdup_printf ("%s.%d", ostree_deployment_get_csum (deployment), + ostree_deployment_get_deployserial (deployment)); + g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string (name)); g_variant_builder_add (&builder, "{sv}", "osname", g_variant_new_string (ostree_deployment_get_osname (deployment))); g_variant_builder_add (&builder, "{sv}", "bootcsum", @@ -3177,10 +3477,7 @@ serialize_deployment_to_variant (OstreeDeployment *deployment) } static gboolean -require_str_key (GVariantDict *dict, - const char *name, - const char **ret, - GError **error) +require_str_key (GVariantDict *dict, const char *name, const char **ret, GError **error) { if (!g_variant_dict_lookup (dict, name, "&s", ret)) return glnx_throw (error, "Missing key: %s", name); @@ -3192,10 +3489,9 @@ require_str_key (GVariantDict *dict, * higher level code. */ OstreeDeployment * -_ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, - GError **error) +_ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, GError **error) { - g_autoptr(GVariantDict) dict = g_variant_dict_new (v); + g_autoptr (GVariantDict) dict = g_variant_dict_new (v); const char *name = NULL; if (!require_str_key (dict, "name", &name, error)) return FALSE; @@ -3209,11 +3505,9 @@ _ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, gint deployserial; if (!_ostree_sysroot_parse_deploy_path_name (name, &checksum, &deployserial, error)) return NULL; - return ostree_deployment_new (-1, osname, checksum, deployserial, - bootcsum, -1); + return ostree_deployment_new (-1, osname, checksum, deployserial, bootcsum, -1); } - /** * ostree_sysroot_stage_overlay_initrd: * @self: Sysroot @@ -3229,17 +3523,14 @@ _ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, * Since: 2020.7 */ gboolean -ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self, - int fd, - char **out_checksum, - GCancellable *cancellable, - GError **error) +ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self, int fd, char **out_checksum, + GCancellable *cancellable, GError **error) { - g_return_val_if_fail (fd != -1, FALSE); - g_return_val_if_fail (out_checksum != NULL, FALSE); + g_assert (fd != -1); + g_assert (out_checksum != NULL); - if (!glnx_shutil_mkdir_p_at (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED_INITRDS_DIR, - 0755, cancellable, error)) + if (!glnx_shutil_mkdir_p_at (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED_INITRDS_DIR, 0755, + cancellable, error)) return FALSE; glnx_autofd int staged_initrds_dfd = -1; @@ -3247,30 +3538,31 @@ ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self, &staged_initrds_dfd, error)) return FALSE; - g_auto(GLnxTmpfile) overlay_initrd = { 0, }; + g_auto (GLnxTmpfile) overlay_initrd = { + 0, + }; if (!glnx_open_tmpfile_linkable_at (staged_initrds_dfd, ".", O_WRONLY | O_CLOEXEC, &overlay_initrd, error)) return FALSE; - char checksum[_OSTREE_SHA256_STRING_LEN+1]; + char checksum[_OSTREE_SHA256_STRING_LEN + 1]; { - g_autoptr(GOutputStream) output = g_unix_output_stream_new (overlay_initrd.fd, FALSE); - g_autoptr(GInputStream) input = g_unix_input_stream_new (fd, FALSE); + g_autoptr (GOutputStream) output = g_unix_output_stream_new (overlay_initrd.fd, FALSE); + g_autoptr (GInputStream) input = g_unix_input_stream_new (fd, FALSE); g_autofree guchar *digest = NULL; if (!ot_gio_splice_get_checksum (output, input, &digest, cancellable, error)) return FALSE; - ot_bin2hex (checksum, (guint8*)digest, _OSTREE_SHA256_DIGEST_LEN); + ot_bin2hex (checksum, (guint8 *)digest, _OSTREE_SHA256_DIGEST_LEN); } - if (!glnx_link_tmpfile_at (&overlay_initrd, GLNX_LINK_TMPFILE_REPLACE, - staged_initrds_dfd, checksum, error)) + if (!glnx_link_tmpfile_at (&overlay_initrd, GLNX_LINK_TMPFILE_REPLACE, staged_initrds_dfd, + checksum, error)) return FALSE; *out_checksum = g_strdup (checksum); return TRUE; } - /** * ostree_sysroot_stage_tree: * @self: Sysroot @@ -3278,7 +3570,8 @@ ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self, * @revision: Checksum to add * @origin: (allow-none): Origin to use for upgrades * @merge_deployment: (allow-none): Use this deployment for merge path - * @override_kernel_argv: (allow-none) (array zero-terminated=1) (element-type utf8): Use these as kernel arguments; if %NULL, inherit options from provided_merge_deployment + * @override_kernel_argv: (allow-none) (array zero-terminated=1) (element-type utf8): Use these as + * kernel arguments; if %NULL, inherit options from provided_merge_deployment * @out_new_deployment: (out): The new deployment path * @cancellable: Cancellable * @error: Error @@ -3288,23 +3581,16 @@ ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self, * Since: 2018.5 */ gboolean -ostree_sysroot_stage_tree (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *merge_deployment, - char **override_kernel_argv, - OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error) +ostree_sysroot_stage_tree (OstreeSysroot *self, const char *osname, const char *revision, + GKeyFile *origin, OstreeDeployment *merge_deployment, + char **override_kernel_argv, OstreeDeployment **out_new_deployment, + GCancellable *cancellable, GError **error) { OstreeSysrootDeployTreeOpts opts = { .override_kernel_argv = override_kernel_argv }; - return ostree_sysroot_stage_tree_with_options (self, osname, revision, origin, - merge_deployment, &opts, - out_new_deployment, cancellable, error); + return ostree_sysroot_stage_tree_with_options (self, osname, revision, origin, merge_deployment, + &opts, out_new_deployment, cancellable, error); } - /** * ostree_sysroot_stage_tree_with_options: * @self: Sysroot @@ -3323,16 +3609,15 @@ ostree_sysroot_stage_tree (OstreeSysroot *self, * Since: 2020.7 */ gboolean -ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *merge_deployment, +ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, const char *osname, + const char *revision, GKeyFile *origin, + OstreeDeployment *merge_deployment, OstreeSysrootDeployTreeOpts *opts, OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error) + GCancellable *cancellable, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Staging deployment", error); + if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; @@ -3340,7 +3625,7 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, if (booted_deployment == NULL) return glnx_prefix_error (error, "Cannot stage deployment"); - g_autoptr(OstreeDeployment) deployment = NULL; + g_autoptr (OstreeDeployment) deployment = NULL; if (!sysroot_initialize_deployment (self, osname, revision, origin, opts, &deployment, cancellable, error)) return FALSE; @@ -3349,18 +3634,18 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, * now (i.e. using /usr/etc policy, not /etc); in practice we don't really * expect people to customize the label for it. */ - { g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); + { + g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); glnx_autofd int deployment_dfd = -1; - if (!glnx_opendirat (self->sysroot_fd, deployment_path, FALSE, - &deployment_dfd, error)) + if (!glnx_opendirat (self->sysroot_fd, deployment_path, FALSE, &deployment_dfd, error)) return FALSE; - g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); + g_autoptr (OstreeSePolicy) sepolicy + = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); if (!sepolicy) return FALSE; if (!write_origin_file_internal (self, sepolicy, deployment, ostree_deployment_get_origin (deployment), - GLNX_FILE_REPLACE_NODATASYNC, - cancellable, error)) + GLNX_FILE_REPLACE_NODATASYNC, cancellable, error)) return FALSE; } @@ -3369,30 +3654,29 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, */ /* "target" is the staged deployment */ - g_autoptr(GVariantBuilder) builder = g_variant_builder_new ((GVariantType*)"a{sv}"); - g_variant_builder_add (builder, "{sv}", "target", - serialize_deployment_to_variant (deployment)); + g_autoptr (GVariantBuilder) builder = g_variant_builder_new ((GVariantType *)"a{sv}"); + g_variant_builder_add (builder, "{sv}", "target", serialize_deployment_to_variant (deployment)); if (merge_deployment) g_variant_builder_add (builder, "{sv}", "merge-deployment", serialize_deployment_to_variant (merge_deployment)); if (opts && opts->override_kernel_argv) - g_variant_builder_add (builder, "{sv}", "kargs", - g_variant_new_strv ((const char *const*)opts->override_kernel_argv, -1)); + g_variant_builder_add ( + builder, "{sv}", "kargs", + g_variant_new_strv ((const char *const *)opts->override_kernel_argv, -1)); if (opts && opts->overlay_initrds) g_variant_builder_add (builder, "{sv}", "overlay-initrds", - g_variant_new_strv ((const char *const*)opts->overlay_initrds, -1)); + g_variant_new_strv ((const char *const *)opts->overlay_initrds, -1)); const char *parent = dirname (strdupa (_OSTREE_SYSROOT_RUNSTATE_STAGED)); if (!glnx_shutil_mkdir_p_at (AT_FDCWD, parent, 0755, cancellable, error)) return FALSE; - g_autoptr(GVariant) state = g_variant_ref_sink (g_variant_builder_end (builder)); + g_autoptr (GVariant) state = g_variant_ref_sink (g_variant_builder_end (builder)); if (!glnx_file_replace_contents_at (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED, g_variant_get_data (state), g_variant_get_size (state), - GLNX_FILE_REPLACE_NODATASYNC, - cancellable, error)) + GLNX_FILE_REPLACE_NODATASYNC, cancellable, error)) return FALSE; /* If we have a previous one, clean it up */ @@ -3400,6 +3684,9 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, { if (!_ostree_sysroot_rmrf_deployment (self, self->staged_deployment, cancellable, error)) return FALSE; + // Also remove the lock; xref https://github.com/ostreedev/ostree/issues/3025 + if (!ot_ensure_unlinked_at (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED, error)) + return FALSE; } /* Bump mtime so external processes know something changed, and then reload. */ @@ -3421,9 +3708,8 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, /* Invoked at shutdown time by ostree-finalize-staged.service */ static gboolean -_ostree_sysroot_finalize_staged_inner (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_finalize_staged_inner (OstreeSysroot *self, GCancellable *cancellable, + GError **error) { /* It's totally fine if there's no staged deployment; perhaps down the line * though we could teach the ostree cmdline to tell systemd to activate the @@ -3436,38 +3722,32 @@ _ostree_sysroot_finalize_staged_inner (OstreeSysroot *self, } /* Check if finalization is locked. */ - if (!glnx_fstatat_allow_noent (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED, - NULL, 0, error)) + if (!glnx_fstatat_allow_noent (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED, NULL, 0, error)) return FALSE; if (errno == 0) { - ot_journal_print (LOG_INFO, "Not finalizing; found " - _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED); + ot_journal_print (LOG_INFO, "Not finalizing; found " _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED); return TRUE; } /* Notice we send this *after* the trivial `return TRUE` above; this msg implies we've * committed to finalizing the deployment. */ - ot_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, - SD_ID128_FORMAT_VAL(OSTREE_DEPLOYMENT_FINALIZING_ID), - "MESSAGE=Finalizing staged deployment", - "OSTREE_OSNAME=%s", - ostree_deployment_get_osname (self->staged_deployment), - "OSTREE_CHECKSUM=%s", - ostree_deployment_get_csum (self->staged_deployment), - "OSTREE_DEPLOYSERIAL=%u", - ostree_deployment_get_deployserial (self->staged_deployment), - NULL); + ot_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, + SD_ID128_FORMAT_VAL (OSTREE_DEPLOYMENT_FINALIZING_ID), + "MESSAGE=Finalizing staged deployment", "OSTREE_OSNAME=%s", + ostree_deployment_get_osname (self->staged_deployment), "OSTREE_CHECKSUM=%s", + ostree_deployment_get_csum (self->staged_deployment), "OSTREE_DEPLOYSERIAL=%u", + ostree_deployment_get_deployserial (self->staged_deployment), NULL); g_assert (self->staged_deployment_data); - g_autoptr(OstreeDeployment) merge_deployment = NULL; - g_autoptr(GVariant) merge_deployment_v = NULL; + g_autoptr (OstreeDeployment) merge_deployment = NULL; + g_autoptr (GVariant) merge_deployment_v = NULL; if (g_variant_lookup (self->staged_deployment_data, "merge-deployment", "@a{sv}", &merge_deployment_v)) { - g_autoptr(OstreeDeployment) merge_deployment_stub = - _ostree_sysroot_deserialize_deployment_from_variant (merge_deployment_v, error); + g_autoptr (OstreeDeployment) merge_deployment_stub + = _ostree_sysroot_deserialize_deployment_from_variant (merge_deployment_v, error); if (!merge_deployment_stub) return FALSE; for (guint i = 0; i < self->deployments->len; i++) @@ -3492,14 +3772,15 @@ _ostree_sysroot_finalize_staged_inner (OstreeSysroot *self, if (!glnx_unlinkat (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED, 0, error)) return FALSE; - if (!sysroot_finalize_deployment (self, self->staged_deployment, merge_deployment, - cancellable, error)) + if (!sysroot_finalize_deployment (self, self->staged_deployment, merge_deployment, cancellable, + error)) return FALSE; + ot_journal_print (LOG_INFO, "Finalized deployment"); /* Now, take ownership of the staged state, as normally the API below strips * it out. */ - g_autoptr(OstreeDeployment) staged = g_steal_pointer (&self->staged_deployment); + g_autoptr (OstreeDeployment) staged = g_steal_pointer (&self->staged_deployment); staged->staged = FALSE; g_ptr_array_remove_index (self->deployments, 0); @@ -3509,16 +3790,17 @@ _ostree_sysroot_finalize_staged_inner (OstreeSysroot *self, * shutdown, and also because e.g. rpm-ostree wants to own the cleanup * process. */ - OstreeSysrootSimpleWriteDeploymentFlags flags = - OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN; - if (!ostree_sysroot_simple_write_deployment (self, ostree_deployment_get_osname (staged), - staged, merge_deployment, flags, - cancellable, error)) + OstreeSysrootSimpleWriteDeploymentFlags flags + = OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN; + if (!ostree_sysroot_simple_write_deployment (self, ostree_deployment_get_osname (staged), staged, + merge_deployment, flags, cancellable, error)) return FALSE; + ot_journal_print (LOG_INFO, "Finished writing deployment"); /* Do the basic cleanup that may impact /boot, but not the repo pruning */ if (!ostree_sysroot_prepare_cleanup (self, cancellable, error)) return FALSE; + ot_journal_print (LOG_INFO, "Cleanup complete"); // Cleanup will have closed some FDs, re-ensure writability if (!_ostree_sysroot_ensure_writable (self, error)) @@ -3529,41 +3811,49 @@ _ostree_sysroot_finalize_staged_inner (OstreeSysroot *self, /* Invoked at shutdown time by ostree-finalize-staged.service */ gboolean -_ostree_sysroot_finalize_staged (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_finalize_staged (OstreeSysroot *self, GCancellable *cancellable, GError **error) { - g_autoptr(GError) finalization_error = NULL; + g_autoptr (GError) finalization_error = NULL; if (!_ostree_sysroot_ensure_boot_fd (self, error)) return FALSE; if (!_ostree_sysroot_finalize_staged_inner (self, cancellable, &finalization_error)) { - g_autoptr(GError) writing_error = NULL; + g_autoptr (GError) writing_error = NULL; g_assert_cmpint (self->boot_fd, !=, -1); - if (!glnx_file_replace_contents_at (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, - (guint8*)finalization_error->message, -1, - 0, cancellable, &writing_error)) + if (!glnx_file_replace_contents_at (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, + (guint8 *)finalization_error->message, -1, 0, cancellable, + &writing_error)) { - // We somehow failed to write the failure message...that's not great. Maybe ENOSPC on /boot. - g_printerr ("Failed to write %s: %s\n", _OSTREE_FINALIZE_STAGED_FAILURE_PATH, writing_error->message); + // We somehow failed to write the failure message...that's not great. Maybe ENOSPC on + // /boot. + g_printerr ("Failed to write %s: %s\n", _OSTREE_FINALIZE_STAGED_FAILURE_PATH, + writing_error->message); } g_propagate_error (error, g_steal_pointer (&finalization_error)); return FALSE; } + else + { + /* we may have failed in a previous invocation on this boot, but we were + * rerun again (likely manually) and passed this time; nuke any stamp */ + if (!glnx_shutil_rm_rf_at (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, cancellable, + error)) + return FALSE; + } return TRUE; } /* Invoked at bootup time by ostree-boot-complete.service */ gboolean -_ostree_sysroot_boot_complete (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_boot_complete (OstreeSysroot *self, GCancellable *cancellable, GError **error) { if (!_ostree_sysroot_ensure_boot_fd (self, error)) return FALSE; glnx_autofd int failure_fd = -1; - if (!ot_openat_ignore_enoent (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, &failure_fd, error)) + g_assert_cmpint (self->boot_fd, !=, -1); + if (!ot_openat_ignore_enoent (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, &failure_fd, + error)) return FALSE; // If we didn't find a failure log, then there's nothing to do right now. // (Actually this unit shouldn't even be invoked, but we may do more in the future) @@ -3573,8 +3863,9 @@ _ostree_sysroot_boot_complete (OstreeSysroot *self, if (failure_data == NULL) return glnx_prefix_error (error, "Reading from %s", _OSTREE_FINALIZE_STAGED_FAILURE_PATH); // Remove the file; we don't want to continually error out. - (void) unlinkat (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, 0); - return glnx_throw (error, "ostree-finalize-staged.service failed on previous boot: %s", failure_data); + (void)unlinkat (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, 0); + return glnx_throw (error, "ostree-finalize-staged.service failed on previous boot: %s", + failure_data); } /** @@ -3589,11 +3880,8 @@ _ostree_sysroot_boot_complete (OstreeSysroot *self, * values in @new_kargs. */ gboolean -ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, - OstreeDeployment *deployment, - char **new_kargs, - GCancellable *cancellable, - GError **error) +ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, OstreeDeployment *deployment, + char **new_kargs, GCancellable *cancellable, GError **error) { if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; @@ -3601,15 +3889,15 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, /* For now; instead of this do a redeployment */ g_assert (!ostree_deployment_is_staged (deployment)); - g_autoptr(OstreeDeployment) new_deployment = ostree_deployment_clone (deployment); + g_autoptr (OstreeDeployment) new_deployment = ostree_deployment_clone (deployment); OstreeBootconfigParser *new_bootconfig = ostree_deployment_get_bootconfig (new_deployment); - g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_new (); + g_autoptr (OstreeKernelArgs) kargs = ostree_kernel_args_new (); ostree_kernel_args_append_argv (kargs, new_kargs); g_autofree char *new_options = ostree_kernel_args_to_string (kargs); ostree_bootconfig_parser_set (new_bootconfig, "options", new_options); - g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref); + g_autoptr (GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref); for (guint i = 0; i < self->deployments->len; i++) { OstreeDeployment *cur = self->deployments->pdata[i]; @@ -3619,13 +3907,83 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, g_ptr_array_add (new_deployments, g_object_ref (cur)); } - if (!ostree_sysroot_write_deployments (self, new_deployments, - cancellable, error)) + if (!ostree_sysroot_write_deployments (self, new_deployments, cancellable, error)) return FALSE; return TRUE; } +/** + * ostree_sysroot_deployment_set_kargs_in_place: + * @self: Sysroot + * @deployment: A deployment + * @kargs_str: (allow-none): Replace @deployment's kernel arguments + * @cancellable: Cancellable + * @error: Error + * + * Replace the kernel arguments of @deployment with the values in @kargs_str. + */ +gboolean +ostree_sysroot_deployment_set_kargs_in_place (OstreeSysroot *self, OstreeDeployment *deployment, + char *kargs_str, GCancellable *cancellable, + GError **error) +{ + if (!ostree_sysroot_initialize (self, error)) + return FALSE; + if (!_ostree_sysroot_ensure_boot_fd (self, error)) + return FALSE; + if (!_ostree_sysroot_ensure_writable (self, error)) + return FALSE; + + // handle staged deployment + if (ostree_deployment_is_staged (deployment)) + { + /* Read the staged state from disk */ + glnx_autofd int fd = -1; + if (!glnx_openat_rdonly (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED, TRUE, &fd, error)) + return FALSE; + + g_autoptr (GBytes) contents = ot_fd_readall_or_mmap (fd, 0, error); + if (!contents) + return FALSE; + g_autoptr (GVariant) staged_deployment_data + = g_variant_new_from_bytes ((GVariantType *)"a{sv}", contents, TRUE); + g_autoptr (GVariantDict) staged_deployment_dict = g_variant_dict_new (staged_deployment_data); + + g_autoptr (OstreeKernelArgs) kargs = ostree_kernel_args_from_string (kargs_str); + g_auto (GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs); + + g_variant_dict_insert (staged_deployment_dict, "kargs", "^a&s", kargs_strv); + g_autoptr (GVariant) new_staged_deployment_data = g_variant_dict_end (staged_deployment_dict); + + if (!glnx_file_replace_contents_at (fd, _OSTREE_SYSROOT_RUNSTATE_STAGED, + g_variant_get_data (new_staged_deployment_data), + g_variant_get_size (new_staged_deployment_data), + GLNX_FILE_REPLACE_NODATASYNC, cancellable, error)) + return FALSE; + } + else + { + OstreeBootconfigParser *new_bootconfig = ostree_deployment_get_bootconfig (deployment); + ostree_bootconfig_parser_set (new_bootconfig, "options", kargs_str); + + g_autofree char *bootconf_name = g_strdup_printf ( + "ostree-%d-%s.conf", self->deployments->len - ostree_deployment_get_index (deployment), + ostree_deployment_get_osname (deployment)); + + g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", self->bootversion); + glnx_autofd int bootconf_dfd = -1; + if (!glnx_opendirat (self->boot_fd, bootconfdir, TRUE, &bootconf_dfd, error)) + return FALSE; + + if (!ostree_bootconfig_parser_write_at (new_bootconfig, bootconf_dfd, bootconf_name, + cancellable, error)) + return FALSE; + } + + return TRUE; +} + /** * ostree_sysroot_deployment_set_mutable: * @self: Sysroot @@ -3639,11 +3997,9 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, * layering additional non-OSTree content. */ gboolean -ostree_sysroot_deployment_set_mutable (OstreeSysroot *self, - OstreeDeployment *deployment, - gboolean is_mutable, - GCancellable *cancellable, - GError **error) +ostree_sysroot_deployment_set_mutable (OstreeSysroot *self, OstreeDeployment *deployment, + gboolean is_mutable, GCancellable *cancellable, + GError **error) { if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h index a49a406..8e6945b 100644 --- a/src/libostree/ostree-sysroot-private.h +++ b/src/libostree/ostree-sysroot-private.h @@ -20,12 +20,13 @@ #pragma once #include "libglnx.h" -#include "ostree.h" #include "ostree-bootloader.h" +#include "ostree.h" G_BEGIN_DECLS -typedef enum { +typedef enum +{ /* Don't flag deployments as immutable. */ OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS = 1 << 0, @@ -38,22 +39,28 @@ typedef enum { OSTREE_SYSROOT_DEBUG_TEST_NO_DTB = 1 << 3, /* https://github.com/ostreedev/ostree/issues/2154 */ } OstreeSysrootDebugFlags; -typedef enum { +typedef enum +{ /* Skip invoking `sync()` */ OSTREE_SYSROOT_GLOBAL_OPT_SKIP_SYNC = 1 << 0, + /* See https://github.com/ostreedev/ostree/pull/2847 */ + OSTREE_SYSROOT_GLOBAL_OPT_NO_EARLY_PRUNE = 1 << 1, + OSTREE_SYSROOT_GLOBAL_OPT_BOOTLOADER_NAMING_2 = 1 << 2, } OstreeSysrootGlobalOptFlags; -typedef enum { - OSTREE_SYSROOT_LOAD_STATE_NONE, /* ostree_sysroot_new() was called */ - OSTREE_SYSROOT_LOAD_STATE_INIT, /* We've loaded basic sysroot state and have an fd */ - OSTREE_SYSROOT_LOAD_STATE_LOADED, /* We've loaded all of the deployments */ +typedef enum +{ + OSTREE_SYSROOT_LOAD_STATE_NONE, /* ostree_sysroot_new() was called */ + OSTREE_SYSROOT_LOAD_STATE_INIT, /* We've loaded basic sysroot state and have an fd */ + OSTREE_SYSROOT_LOAD_STATE_LOADED, /* We've loaded all of the deployments */ } OstreeSysrootLoadState; /** * OstreeSysroot: * Internal struct */ -struct OstreeSysroot { +struct OstreeSysroot +{ GObject parent; GFile *path; @@ -63,10 +70,12 @@ struct OstreeSysroot { OstreeSysrootLoadState loadstate; gboolean mount_namespace_in_use; /* TRUE if caller has told us they used CLONE_NEWNS */ - gboolean root_is_ostree_booted; /* TRUE if sysroot is / and we are booted via ostree */ - /* The device/inode for /, used to detect booted deployment */ + gboolean root_is_ostree_booted; /* TRUE if sysroot is / and we are booted via ostree */ + /* The device/inode for / and /etc, used to detect booted deployment */ dev_t root_device; ino_t root_inode; + dev_t etc_device; + ino_t etc_inode; gboolean is_physical; /* TRUE if we're pointed at physical storage root and not a deployment */ GPtrArray *deployments; @@ -99,92 +108,68 @@ struct OstreeSysroot { // Relative to /boot, consumed by ostree-boot-complete.service #define _OSTREE_FINALIZE_STAGED_FAILURE_PATH "ostree/finalize-failure.stamp" -gboolean -_ostree_sysroot_ensure_writable (OstreeSysroot *self, - GError **error); - -void -_ostree_sysroot_emit_journal_msg (OstreeSysroot *self, - const char *msg); - -gboolean -_ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, - int bootversion, - GPtrArray **out_loader_configs, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_sysroot_read_current_subbootversion (OstreeSysroot *self, - int bootversion, - int *out_subbootversion, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_sysroot_parse_deploy_path_name (const char *name, - char **out_csum, - int *out_serial, - GError **error); - -gboolean -_ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd, - const char *osname, - GPtrArray *inout_deployments, - GCancellable *cancellable, - GError **error); - -void -_ostree_deployment_set_bootconfig_from_kargs (OstreeDeployment *deployment, - char **override_kernel_argv); - -gboolean -_ostree_sysroot_reload_staged (OstreeSysroot *self, GError **error); - -gboolean -_ostree_sysroot_finalize_staged (OstreeSysroot *self, - GCancellable *cancellable, - GError **error); -gboolean -_ostree_sysroot_boot_complete (OstreeSysroot *self, - GCancellable *cancellable, - GError **error); - -OstreeDeployment * -_ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, - GError **error); - -char * -_ostree_sysroot_get_origin_relpath (GFile *path, - guint32 *out_device, - guint64 *out_inode, - GCancellable *cancellable, - GError **error); - -gboolean -_ostree_sysroot_rmrf_deployment (OstreeSysroot *sysroot, - OstreeDeployment *deployment, - GCancellable *cancellable, - GError **error); - -char * _ostree_sysroot_get_runstate_path (OstreeDeployment *deployment, const char *key); - -char *_ostree_sysroot_join_lines (GPtrArray *lines); - -gboolean -_ostree_sysroot_ensure_boot_fd (OstreeSysroot *self, GError **error); - -gboolean _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot, +gboolean _ostree_sysroot_ensure_writable (OstreeSysroot *self, GError **error); + +void _ostree_sysroot_emit_journal_msg (OstreeSysroot *self, const char *msg); + +gboolean _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, int bootversion, + GPtrArray **out_loader_configs, + GCancellable *cancellable, GError **error); + +gboolean _ostree_sysroot_read_current_subbootversion (OstreeSysroot *self, int bootversion, + int *out_subbootversion, + GCancellable *cancellable, GError **error); + +gboolean _ostree_sysroot_parse_deploy_path_name (const char *name, char **out_csum, int *out_serial, + GError **error); + +gboolean _ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd, const char *osname, + GPtrArray *inout_deployments, + GCancellable *cancellable, GError **error); + +void _ostree_deployment_set_bootconfig_from_kargs (OstreeDeployment *deployment, + char **override_kernel_argv); + +gboolean _ostree_sysroot_reload_staged (OstreeSysroot *self, GError **error); + +gboolean _ostree_sysroot_finalize_staged (OstreeSysroot *self, GCancellable *cancellable, + GError **error); +gboolean _ostree_sysroot_boot_complete (OstreeSysroot *self, GCancellable *cancellable, + GError **error); + +OstreeDeployment *_ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, GError **error); + +char *_ostree_sysroot_get_origin_relpath (GFile *path, guint32 *out_device, guint64 *out_inode, + GCancellable *cancellable, GError **error); + +gboolean _ostree_sysroot_rmrf_deployment (OstreeSysroot *sysroot, OstreeDeployment *deployment, + GCancellable *cancellable, GError **error); + +char *_ostree_sysroot_get_runstate_path (OstreeDeployment *deployment, const char *key); + +char *_ostree_sysroot_join_lines (GPtrArray *lines); + +gboolean _ostree_sysroot_ensure_boot_fd (OstreeSysroot *self, GError **error); + +gboolean _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot, OstreeBootloader **out_bootloader, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); + +gboolean _ostree_sysroot_bump_mtime (OstreeSysroot *sysroot, GError **error); + +gboolean _ostree_sysroot_cleanup_internal (OstreeSysroot *sysroot, gboolean prune_repo, + GCancellable *cancellable, GError **error); + +gboolean _ostree_sysroot_cleanup_bootfs (OstreeSysroot *self, GCancellable *cancellable, + GError **error); + +gboolean _ostree_sysroot_parse_bootdir_name (const char *name, char **out_osname, char **out_csum); -gboolean _ostree_sysroot_bump_mtime (OstreeSysroot *sysroot, - GError **error); +gboolean _ostree_sysroot_list_all_boot_directories (OstreeSysroot *self, char ***out_bootdirs, + GCancellable *cancellable, GError **error); -gboolean _ostree_sysroot_cleanup_internal (OstreeSysroot *sysroot, - gboolean prune_repo, - GCancellable *cancellable, - GError **error); +gboolean _ostree_sysroot_parse_bootlink (const char *bootlink, int *out_entry_bootversion, + char **out_osname, char **out_bootcsum, + int *out_treebootserial, GError **error); G_END_DECLS diff --git a/src/libostree/ostree-sysroot-upgrader.c b/src/libostree/ostree-sysroot-upgrader.c index 0b2590b..94654c8 100644 --- a/src/libostree/ostree-sysroot-upgrader.c +++ b/src/libostree/ostree-sysroot-upgrader.c @@ -21,9 +21,9 @@ #include "otutil.h" -#include "ostree.h" -#include "ostree-sysroot-upgrader.h" #include "ostree-core-private.h" +#include "ostree-sysroot-upgrader.h" +#include "ostree.h" /** * SECTION:ostree-sysroot-upgrader @@ -33,11 +33,13 @@ * The #OstreeSysrootUpgrader class allows performing simple upgrade * operations. */ -typedef struct { +typedef struct +{ GObjectClass parent_class; } OstreeSysrootUpgraderClass; -struct OstreeSysrootUpgrader { +struct OstreeSysrootUpgrader +{ GObject parent; OstreeSysroot *sysroot; @@ -53,7 +55,8 @@ struct OstreeSysrootUpgrader { char *new_revision; }; -enum { +enum +{ PROP_0, PROP_SYSROOT, @@ -64,12 +67,11 @@ enum { static void ostree_sysroot_upgrader_initable_iface_init (GInitableIface *iface); G_DEFINE_TYPE_WITH_CODE (OstreeSysrootUpgrader, ostree_sysroot_upgrader, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, ostree_sysroot_upgrader_initable_iface_init)) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + ostree_sysroot_upgrader_initable_iface_init)) static gboolean -parse_refspec (OstreeSysrootUpgrader *self, - GCancellable *cancellable, - GError **error) +parse_refspec (OstreeSysrootUpgrader *self, GCancellable *cancellable, GError **error) { g_autofree char *origin_refspec = NULL; g_autofree char *unconfigured_state = NULL; @@ -80,21 +82,20 @@ parse_refspec (OstreeSysrootUpgrader *self, /* If explicit action by the OS creator is requried to upgrade, print their text as an error. * NOTE: If changing this, see the matching implementation in ostree-repo-pull.c. */ - unconfigured_state = g_key_file_get_string (self->origin, "origin", "unconfigured-state", NULL); + unconfigured_state + = g_key_file_get_string (self->origin, "origin", "unconfigured-state", NULL); if (unconfigured_state) return glnx_throw (error, "origin unconfigured-state: %s", unconfigured_state); } origin_refspec = g_key_file_get_string (self->origin, "origin", "refspec", NULL); if (!origin_refspec) - return glnx_throw (error, "No origin/refspec in current deployment origin; cannot upgrade via ostree"); + return glnx_throw (error, + "No origin/refspec in current deployment origin; cannot upgrade via ostree"); g_clear_pointer (&self->origin_remote, g_free); g_clear_pointer (&self->origin_ref, g_free); - if (!ostree_parse_refspec (origin_refspec, - &self->origin_remote, - &self->origin_ref, - error)) + if (!ostree_parse_refspec (origin_refspec, &self->origin_remote, &self->origin_ref, error)) return FALSE; csum = g_key_file_get_string (self->origin, "origin", "override-commit", NULL); @@ -107,13 +108,11 @@ parse_refspec (OstreeSysrootUpgrader *self, } static gboolean -ostree_sysroot_upgrader_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) +ostree_sysroot_upgrader_initable_init (GInitable *initable, GCancellable *cancellable, + GError **error) { - OstreeSysrootUpgrader *self = (OstreeSysrootUpgrader*)initable; - OstreeDeployment *booted_deployment = - ostree_sysroot_get_booted_deployment (self->sysroot); + OstreeSysrootUpgrader *self = (OstreeSysrootUpgrader *)initable; + OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (self->sysroot); if (booted_deployment == NULL && self->osname == NULL) return glnx_throw (error, "Not currently booted into an OSTree system and no OS specified"); @@ -169,10 +168,8 @@ ostree_sysroot_upgrader_finalize (GObject *object) } static void -ostree_sysroot_upgrader_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +ostree_sysroot_upgrader_set_property (GObject *object, guint prop_id, const GValue *value, + GParamSpec *pspec) { OstreeSysrootUpgrader *self = OSTREE_SYSROOT_UPGRADER (object); @@ -194,10 +191,8 @@ ostree_sysroot_upgrader_set_property (GObject *object, } static void -ostree_sysroot_upgrader_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +ostree_sysroot_upgrader_get_property (GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec) { OstreeSysrootUpgrader *self = OSTREE_SYSROOT_UPGRADER (object); @@ -238,22 +233,18 @@ ostree_sysroot_upgrader_class_init (OstreeSysrootUpgraderClass *klass) object_class->set_property = ostree_sysroot_upgrader_set_property; object_class->finalize = ostree_sysroot_upgrader_finalize; - g_object_class_install_property (object_class, - PROP_SYSROOT, - g_param_spec_object ("sysroot", "", "", - OSTREE_TYPE_SYSROOT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( + object_class, PROP_SYSROOT, + g_param_spec_object ("sysroot", "", "", OSTREE_TYPE_SYSROOT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_OSNAME, - g_param_spec_string ("osname", "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( + object_class, PROP_OSNAME, + g_param_spec_string ("osname", "", "", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_FLAGS, + g_object_class_install_property (object_class, PROP_FLAGS, g_param_spec_flags ("flags", "", "", - ostree_sysroot_upgrader_flags_get_type (), - 0, + ostree_sysroot_upgrader_flags_get_type (), 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } @@ -270,13 +261,11 @@ ostree_sysroot_upgrader_init (OstreeSysrootUpgrader *self) * * Returns: (transfer full): An upgrader */ -OstreeSysrootUpgrader* -ostree_sysroot_upgrader_new (OstreeSysroot *sysroot, - GCancellable *cancellable, - GError **error) +OstreeSysrootUpgrader * +ostree_sysroot_upgrader_new (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) { - return g_initable_new (OSTREE_TYPE_SYSROOT_UPGRADER, cancellable, error, - "sysroot", sysroot, NULL); + return g_initable_new (OSTREE_TYPE_SYSROOT_UPGRADER, cancellable, error, "sysroot", sysroot, + NULL); } /** @@ -288,14 +277,12 @@ ostree_sysroot_upgrader_new (OstreeSysroot *sysroot, * * Returns: (transfer full): An upgrader */ -OstreeSysrootUpgrader* -ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroot, - const char *osname, - GCancellable *cancellable, - GError **error) +OstreeSysrootUpgrader * +ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroot, const char *osname, + GCancellable *cancellable, GError **error) { - return g_initable_new (OSTREE_TYPE_SYSROOT_UPGRADER, cancellable, error, - "sysroot", sysroot, "osname", osname, NULL); + return g_initable_new (OSTREE_TYPE_SYSROOT_UPGRADER, cancellable, error, "sysroot", sysroot, + "osname", osname, NULL); } /** @@ -309,21 +296,19 @@ ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroot, * Returns: (transfer full): An upgrader */ OstreeSysrootUpgrader * -ostree_sysroot_upgrader_new_for_os_with_flags (OstreeSysroot *sysroot, - const char *osname, - OstreeSysrootUpgraderFlags flags, - GCancellable *cancellable, - GError **error) +ostree_sysroot_upgrader_new_for_os_with_flags (OstreeSysroot *sysroot, const char *osname, + OstreeSysrootUpgraderFlags flags, + GCancellable *cancellable, GError **error) { - return g_initable_new (OSTREE_TYPE_SYSROOT_UPGRADER, cancellable, error, - "sysroot", sysroot, "osname", osname, "flags", flags, NULL); + return g_initable_new (OSTREE_TYPE_SYSROOT_UPGRADER, cancellable, error, "sysroot", sysroot, + "osname", osname, "flags", flags, NULL); } /** * ostree_sysroot_upgrader_get_origin: * @self: Sysroot * - * Returns: (transfer none): The origin file, or %NULL if unknown + * Returns: (transfer none) (nullable): The origin file, or %NULL if unknown. */ GKeyFile * ostree_sysroot_upgrader_get_origin (OstreeSysrootUpgrader *self) @@ -335,14 +320,14 @@ ostree_sysroot_upgrader_get_origin (OstreeSysrootUpgrader *self) * ostree_sysroot_upgrader_dup_origin: * @self: Sysroot * - * Returns: (transfer full): A copy of the origin file, or %NULL if unknown + * Returns: (transfer full) (nullable): A copy of the origin file, or %NULL if unknown. */ GKeyFile * ostree_sysroot_upgrader_dup_origin (OstreeSysrootUpgrader *self) { - GKeyFile *copy = NULL; + g_assert (OSTREE_IS_SYSROOT_UPGRADER (self)); - g_return_val_if_fail (OSTREE_IS_SYSROOT_UPGRADER (self), NULL); + GKeyFile *copy = NULL; if (self->origin != NULL) { @@ -351,8 +336,7 @@ ostree_sysroot_upgrader_dup_origin (OstreeSysrootUpgrader *self) copy = g_key_file_new (); data = g_key_file_to_data (self->origin, &length, NULL); - g_key_file_load_from_data (copy, data, length, - G_KEY_FILE_KEEP_COMMENTS, NULL); + g_key_file_load_from_data (copy, data, length, G_KEY_FILE_KEEP_COMMENTS, NULL); } return copy; @@ -368,10 +352,8 @@ ostree_sysroot_upgrader_dup_origin (OstreeSysrootUpgrader *self) * Replace the origin with @origin. */ gboolean -ostree_sysroot_upgrader_set_origin (OstreeSysrootUpgrader *self, - GKeyFile *origin, - GCancellable *cancellable, - GError **error) +ostree_sysroot_upgrader_set_origin (OstreeSysrootUpgrader *self, GKeyFile *origin, + GCancellable *cancellable, GError **error) { g_clear_pointer (&self->origin, g_key_file_unref); if (origin) @@ -388,7 +370,8 @@ ostree_sysroot_upgrader_set_origin (OstreeSysrootUpgrader *self, * ostree_sysroot_upgrader_get_origin_description: * @self: Upgrader * - * Returns: A one-line descriptive summary of the origin, or %NULL if unknown + * Returns: (transfer full) (nullable): A one-line descriptive summary of the origin, or %NULL if + * unknown. */ char * ostree_sysroot_upgrader_get_origin_description (OstreeSysrootUpgrader *self) @@ -410,28 +393,19 @@ ostree_sysroot_upgrader_get_origin_description (OstreeSysrootUpgrader *self) * attackers which provide a client with an older commit. */ gboolean -ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo, - const char *from_rev, - const char *to_rev, - GError **error) +ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo, const char *from_rev, + const char *to_rev, GError **error) { - g_autoptr(GVariant) old_commit = NULL; - if (!ostree_repo_load_variant (repo, - OSTREE_OBJECT_TYPE_COMMIT, - from_rev, - &old_commit, - error)) + g_autoptr (GVariant) old_commit = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, from_rev, &old_commit, error)) return FALSE; - g_autoptr(GVariant) new_commit = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, - to_rev, &new_commit, - error)) + g_autoptr (GVariant) new_commit = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, to_rev, &new_commit, error)) return FALSE; - if (!_ostree_compare_timestamps (from_rev, ostree_commit_get_timestamp (old_commit), - to_rev, ostree_commit_get_timestamp (new_commit), - error)) + if (!_ostree_compare_timestamps (from_rev, ostree_commit_get_timestamp (old_commit), to_rev, + ostree_commit_get_timestamp (new_commit), error)) return FALSE; return TRUE; @@ -455,15 +429,13 @@ ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo, * %FALSE. */ gboolean -ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self, - OstreeRepoPullFlags flags, - OstreeSysrootUpgraderPullFlags upgrader_flags, - OstreeAsyncProgress *progress, - gboolean *out_changed, - GCancellable *cancellable, - GError **error) +ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self, OstreeRepoPullFlags flags, + OstreeSysrootUpgraderPullFlags upgrader_flags, + OstreeAsyncProgress *progress, gboolean *out_changed, + GCancellable *cancellable, GError **error) { - return ostree_sysroot_upgrader_pull_one_dir (self, NULL, flags, upgrader_flags, progress, out_changed, cancellable, error); + return ostree_sysroot_upgrader_pull_one_dir (self, NULL, flags, upgrader_flags, progress, + out_changed, cancellable, error); } /** @@ -483,31 +455,26 @@ ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self, * */ gboolean -ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, - const char *dir_to_pull, - OstreeRepoPullFlags flags, - OstreeSysrootUpgraderPullFlags upgrader_flags, - OstreeAsyncProgress *progress, - gboolean *out_changed, - GCancellable *cancellable, - GError **error) +ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, const char *dir_to_pull, + OstreeRepoPullFlags flags, + OstreeSysrootUpgraderPullFlags upgrader_flags, + OstreeAsyncProgress *progress, gboolean *out_changed, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; char *refs_to_fetch[] = { NULL, NULL }; const char *from_revision = NULL; g_autofree char *origin_refspec = NULL; g_autofree char *new_revision = NULL; - g_autoptr(GVariant) new_variant = NULL; - g_autoptr(GVariant) new_metadata = NULL; - g_autoptr(GVariant) rebase = NULL; + g_autoptr (GVariant) new_variant = NULL; + g_autoptr (GVariant) new_metadata = NULL; + g_autoptr (GVariant) rebase = NULL; if (self->override_csum != NULL) refs_to_fetch[0] = self->override_csum; else refs_to_fetch[0] = self->origin_ref; - if (!ostree_sysroot_get_repo (self->sysroot, &repo, cancellable, error)) - return FALSE; + OstreeRepo *repo = ostree_sysroot_repo (self->sysroot); if (self->origin_remote) origin_refspec = g_strconcat (self->origin_remote, ":", self->origin_ref, NULL); @@ -517,10 +484,9 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, g_assert (self->merge_deployment); from_revision = ostree_deployment_get_csum (self->merge_deployment); - if (self->origin_remote && - (upgrader_flags & OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC) == 0) + if (self->origin_remote && (upgrader_flags & OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC) == 0) { - g_autoptr(GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); if (dir_to_pull && *dir_to_pull) g_variant_builder_add (optbuilder, "{s@v}", "subdir", g_variant_new_variant (g_variant_new_string (dir_to_pull))); @@ -531,12 +497,12 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, g_variant_builder_add (optbuilder, "{s@v}", "timestamp-check-from-rev", g_variant_new_variant (g_variant_new_string (from_revision))); - g_variant_builder_add (optbuilder, "{s@v}", "refs", - g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch, -1))); - g_autoptr(GVariant) opts = g_variant_ref_sink (g_variant_builder_end (optbuilder)); - if (!ostree_repo_pull_with_options (repo, self->origin_remote, - opts, progress, - cancellable, error)) + g_variant_builder_add ( + optbuilder, "{s@v}", "refs", + g_variant_new_variant (g_variant_new_strv ((const char *const *)refs_to_fetch, -1))); + g_autoptr (GVariant) opts = g_variant_ref_sink (g_variant_builder_end (optbuilder)); + if (!ostree_repo_pull_with_options (repo, self->origin_remote, opts, progress, cancellable, + error)) return FALSE; if (progress) @@ -545,64 +511,55 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, /* Check to see if the commit marks the ref as EOL, redirecting to * another. */ - if (!ostree_repo_resolve_rev (repo, origin_refspec, FALSE, - &new_revision, error)) + if (!ostree_repo_resolve_rev (repo, origin_refspec, FALSE, &new_revision, error)) return FALSE; - if (!ostree_repo_load_variant (repo, - OSTREE_OBJECT_TYPE_COMMIT, - new_revision, - &new_variant, + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, new_revision, &new_variant, error)) return FALSE; g_variant_get_child (new_variant, 0, "@a{sv}", &new_metadata); - rebase = g_variant_lookup_value (new_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, G_VARIANT_TYPE_STRING); + rebase = g_variant_lookup_value (new_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, + G_VARIANT_TYPE_STRING); if (rebase) { const char *new_ref = g_variant_get_string (rebase, 0); /* Pull the new ref */ - if (self->origin_remote && - (upgrader_flags & OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC) == 0) + if (self->origin_remote + && (upgrader_flags & OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC) == 0) { - refs_to_fetch[0] = (char *) new_ref; + refs_to_fetch[0] = (char *)new_ref; if (!ostree_repo_pull_one_dir (repo, self->origin_remote, dir_to_pull, refs_to_fetch, flags, progress, cancellable, error)) return FALSE; } - /* Use the new ref for the rest of the update process */ - g_free (self->origin_ref); - self->origin_ref = g_strdup(new_ref); - g_free (origin_refspec); + /* Use the new ref for the rest of the update process */ + g_free (self->origin_ref); + self->origin_ref = g_strdup (new_ref); + g_free (origin_refspec); - if (self->origin_remote) - origin_refspec = g_strconcat (self->origin_remote, ":", new_ref, NULL); - else - origin_refspec = g_strdup (new_ref); + if (self->origin_remote) + origin_refspec = g_strconcat (self->origin_remote, ":", new_ref, NULL); + else + origin_refspec = g_strdup (new_ref); - g_key_file_set_string (self->origin, "origin", "refspec", origin_refspec); + g_key_file_set_string (self->origin, "origin", "refspec", origin_refspec); } if (self->override_csum != NULL) { - if (!ostree_repo_set_ref_immediate (repo, - self->origin_remote, - self->origin_ref, - self->override_csum, - cancellable, - error)) + if (!ostree_repo_set_ref_immediate (repo, self->origin_remote, self->origin_ref, + self->override_csum, cancellable, error)) return FALSE; self->new_revision = g_strdup (self->override_csum); } else { - if (!ostree_repo_resolve_rev (repo, origin_refspec, FALSE, - &self->new_revision, error)) + if (!ostree_repo_resolve_rev (repo, origin_refspec, FALSE, &self->new_revision, error)) return FALSE; - } if (g_strcmp0 (from_revision, self->new_revision) == 0) @@ -617,8 +574,7 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, if (from_revision && !allow_older) { - if (!ostree_sysroot_upgrader_check_timestamps (repo, from_revision, - self->new_revision, + if (!ostree_sysroot_upgrader_check_timestamps (repo, from_revision, self->new_revision, error)) return FALSE; } @@ -637,41 +593,30 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, * with /etc, and update the bootloader configuration. */ gboolean -ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self, - GCancellable *cancellable, - GError **error) +ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self, GCancellable *cancellable, + GError **error) { - g_autoptr(OstreeDeployment) new_deployment = NULL; + g_autoptr (OstreeDeployment) new_deployment = NULL; /* Experimental flag to enable staging */ - gboolean stage = (self->flags & OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE) > 0 || getenv ("OSTREE_EX_STAGE_DEPLOYMENTS") != NULL; + gboolean stage = (self->flags & OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE) > 0 + || getenv ("OSTREE_EX_STAGE_DEPLOYMENTS") != NULL; if (stage) { - if (!ostree_sysroot_stage_tree (self->sysroot, self->osname, - self->new_revision, - self->origin, - self->merge_deployment, - NULL, - &new_deployment, - cancellable, error)) + if (!ostree_sysroot_stage_tree (self->sysroot, self->osname, self->new_revision, self->origin, + self->merge_deployment, NULL, &new_deployment, cancellable, + error)) return FALSE; } else { - if (!ostree_sysroot_deploy_tree (self->sysroot, self->osname, - self->new_revision, - self->origin, - self->merge_deployment, - NULL, - &new_deployment, + if (!ostree_sysroot_deploy_tree (self->sysroot, self->osname, self->new_revision, + self->origin, self->merge_deployment, NULL, &new_deployment, cancellable, error)) return FALSE; - if (!ostree_sysroot_simple_write_deployment (self->sysroot, self->osname, - new_deployment, - self->merge_deployment, - 0, - cancellable, error)) + if (!ostree_sysroot_simple_write_deployment (self->sysroot, self->osname, new_deployment, + self->merge_deployment, 0, cancellable, error)) return FALSE; } @@ -685,13 +630,14 @@ ostree_sysroot_upgrader_flags_get_type (void) if (g_once_init_enter (&static_g_define_type_id)) { - static const GFlagsValue values[] = { - { OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED, "OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED", "ignore-unconfigured" }, - { OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE, "OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE", "stage" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_flags_register_static (g_intern_static_string ("OstreeSysrootUpgraderFlags"), values); + static const GFlagsValue values[] + = { { OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED, + "OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED", "ignore-unconfigured" }, + { OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE, "OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE", + "stage" }, + { 0, NULL, NULL } }; + GType g_define_type_id + = g_flags_register_static (g_intern_static_string ("OstreeSysrootUpgraderFlags"), values); g_once_init_leave (&static_g_define_type_id, g_define_type_id); } diff --git a/src/libostree/ostree-sysroot-upgrader.h b/src/libostree/ostree-sysroot-upgrader.h index b214157..5d1e8c2 100644 --- a/src/libostree/ostree-sysroot-upgrader.h +++ b/src/libostree/ostree-sysroot-upgrader.h @@ -23,7 +23,7 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_SYSROOT_UPGRADER ostree_sysroot_upgrader_get_type() +#define OSTREE_TYPE_SYSROOT_UPGRADER ostree_sysroot_upgrader_get_type () #define OSTREE_SYSROOT_UPGRADER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_SYSROOT_UPGRADER, OstreeSysrootUpgrader)) #define OSTREE_IS_SYSROOT_UPGRADER(obj) \ @@ -32,13 +32,15 @@ G_BEGIN_DECLS /** * OstreeSysrootUpgraderFlags: * @OSTREE_SYSROOT_UPGRADER_FLAGS_NONE: No options - * @OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED: Do not error if the origin has an unconfigured-state key + * @OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED: Do not error if the origin has an + * unconfigured-state key * @OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE: Enable "staging" (finalization at shutdown); recommended * (Since: 2021.4) * * Flags controlling operation of an #OstreeSysrootUpgrader. */ -typedef enum { +typedef enum +{ OSTREE_SYSROOT_UPGRADER_FLAGS_NONE = (1 << 0), OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED = (1 << 1), OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE = (1 << 2), @@ -52,21 +54,19 @@ GType ostree_sysroot_upgrader_flags_get_type (void); _OSTREE_PUBLIC OstreeSysrootUpgrader *ostree_sysroot_upgrader_new (OstreeSysroot *sysroot, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC OstreeSysrootUpgrader *ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroot, - const char *osname, - GCancellable *cancellable, - GError **error); + const char *osname, + GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -OstreeSysrootUpgrader *ostree_sysroot_upgrader_new_for_os_with_flags (OstreeSysroot *sysroot, - const char *osname, - OstreeSysrootUpgraderFlags flags, - GCancellable *cancellable, - GError **error); +OstreeSysrootUpgrader * +ostree_sysroot_upgrader_new_for_os_with_flags (OstreeSysroot *sysroot, const char *osname, + OstreeSysrootUpgraderFlags flags, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC GKeyFile *ostree_sysroot_upgrader_get_origin (OstreeSysrootUpgrader *self); @@ -80,39 +80,32 @@ _OSTREE_PUBLIC char *ostree_sysroot_upgrader_get_origin_description (OstreeSysrootUpgrader *self); _OSTREE_PUBLIC -gboolean ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo, - const char *from_rev, - const char *to_rev, - GError **error); +gboolean ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo, const char *from_rev, + const char *to_rev, GError **error); -typedef enum { +typedef enum +{ OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_NONE = 0, OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER = (1 << 0), - OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC = (1 << 1) /* Don't actually do a pull, just check timestamps/changed */ + OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC + = (1 << 1) /* Don't actually do a pull, just check timestamps/changed */ } OstreeSysrootUpgraderPullFlags; _OSTREE_PUBLIC -gboolean ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self, - OstreeRepoPullFlags flags, - OstreeSysrootUpgraderPullFlags upgrader_flags, - OstreeAsyncProgress *progress, - gboolean *out_changed, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self, OstreeRepoPullFlags flags, + OstreeSysrootUpgraderPullFlags upgrader_flags, + OstreeAsyncProgress *progress, gboolean *out_changed, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, - const char *dir_to_pull, - OstreeRepoPullFlags flags, - OstreeSysrootUpgraderPullFlags upgrader_flags, - OstreeAsyncProgress *progress, - gboolean *out_changed, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self, const char *dir_to_pull, + OstreeRepoPullFlags flags, + OstreeSysrootUpgraderPullFlags upgrader_flags, + OstreeAsyncProgress *progress, gboolean *out_changed, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self, GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index bcb55e5..91b63f9 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -21,21 +21,22 @@ #include "config.h" #include "otutil.h" +#include #include #include -#include #include -#include "ostree.h" +#include "ostree-bootloader-aboot.h" +#include "ostree-bootloader-grub2.h" +#include "ostree-bootloader-syslinux.h" +#include "ostree-bootloader-uboot.h" +#include "ostree-bootloader-zipl.h" #include "ostree-core-private.h" +#include "ostree-deployment-private.h" #include "ostree-repo-private.h" #include "ostree-sepolicy-private.h" #include "ostree-sysroot-private.h" -#include "ostree-deployment-private.h" -#include "ostree-bootloader-uboot.h" -#include "ostree-bootloader-syslinux.h" -#include "ostree-bootloader-grub2.h" -#include "ostree-bootloader-zipl.h" +#include "ostree.h" /** * SECTION:ostree-sysroot @@ -51,21 +52,23 @@ * or external processes. You can use ostree_sysroot_lock() to * perform locking externally. */ -typedef struct { +typedef struct +{ GObjectClass parent_class; /* Signals */ - void (*journal_msg) (OstreeSysroot *sysroot, - const char *msg); + void (*journal_msg) (OstreeSysroot *sysroot, const char *msg); } OstreeSysrootClass; -enum { +enum +{ JOURNAL_MSG_SIGNAL, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; -enum { +enum +{ PROP_0, PROP_PATH @@ -93,10 +96,7 @@ ostree_sysroot_finalize (GObject *object) } static void -ostree_sysroot_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +ostree_sysroot_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { OstreeSysroot *self = OSTREE_SYSROOT (object); @@ -112,10 +112,7 @@ ostree_sysroot_set_property(GObject *object, } static void -ostree_sysroot_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +ostree_sysroot_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { OstreeSysroot *self = OSTREE_SYSROOT (object); @@ -152,13 +149,10 @@ ostree_sysroot_class_init (OstreeSysrootClass *klass) object_class->set_property = ostree_sysroot_set_property; object_class->finalize = ostree_sysroot_finalize; - g_object_class_install_property (object_class, - PROP_PATH, - g_param_spec_object ("path", - "", - "", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( + object_class, PROP_PATH, + g_param_spec_object ("path", "", "", G_TYPE_FILE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * OstreeSysroot::journal-msg: @@ -174,12 +168,10 @@ ostree_sysroot_class_init (OstreeSysrootClass *klass) * * Since: 2017.10 */ - signals[JOURNAL_MSG_SIGNAL] = - g_signal_new ("journal-msg", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (OstreeSysrootClass, journal_msg), - NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING); + signals[JOURNAL_MSG_SIGNAL] + = g_signal_new ("journal-msg", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (OstreeSysrootClass, journal_msg), NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_STRING); } static void @@ -187,6 +179,8 @@ ostree_sysroot_init (OstreeSysroot *self) { const GDebugKey globalopt_keys[] = { { "skip-sync", OSTREE_SYSROOT_GLOBAL_OPT_SKIP_SYNC }, + { "no-early-prune", OSTREE_SYSROOT_GLOBAL_OPT_NO_EARLY_PRUNE }, + { "bootloader-naming-2", OSTREE_SYSROOT_GLOBAL_OPT_BOOTLOADER_NAMING_2 }, }; const GDebugKey keys[] = { { "mutable-deployments", OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS }, @@ -195,10 +189,10 @@ ostree_sysroot_init (OstreeSysroot *self) { "no-dtb", OSTREE_SYSROOT_DEBUG_TEST_NO_DTB }, }; - self->opt_flags = g_parse_debug_string (g_getenv ("OSTREE_SYSROOT_OPTS"), - globalopt_keys, G_N_ELEMENTS (globalopt_keys)); - self->debug_flags = g_parse_debug_string (g_getenv ("OSTREE_SYSROOT_DEBUG"), - keys, G_N_ELEMENTS (keys)); + self->opt_flags = g_parse_debug_string (g_getenv ("OSTREE_SYSROOT_OPTS"), globalopt_keys, + G_N_ELEMENTS (globalopt_keys)); + self->debug_flags + = g_parse_debug_string (g_getenv ("OSTREE_SYSROOT_DEBUG"), keys, G_N_ELEMENTS (keys)); self->sysroot_fd = -1; self->boot_fd = -1; @@ -215,7 +209,7 @@ ostree_sysroot_init (OstreeSysroot *self) * * Returns: (transfer full): An accessor object for an system root located at @path */ -OstreeSysroot* +OstreeSysroot * ostree_sysroot_new (GFile *path) { return g_object_new (OSTREE_TYPE_SYSROOT, "path", path, NULL); @@ -226,7 +220,7 @@ ostree_sysroot_new (GFile *path) * * Returns: (transfer full): An accessor for the current visible root / filesystem */ -OstreeSysroot* +OstreeSysroot * ostree_sysroot_new_default (void) { return ostree_sysroot_new (NULL); @@ -251,7 +245,7 @@ ostree_sysroot_new_default (void) * Since: 2020.1 */ void -ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self) +ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self) { /* Must be before we're loaded, as otherwise we'd have to close/reopen all our fds, e.g. the repo */ @@ -259,6 +253,64 @@ ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self) self->mount_namespace_in_use = TRUE; } +/** + * ostree_sysroot_initialize_with_mount_namespace: + * + * Prepare the current process for modifying a booted sysroot, if applicable. + * This function subsumes the functionality of `ostree_sysroot_initialize` + * and may be invoked wherever that function is. + * + * If the sysroot does not appear to be booted, or where the current process is not uid 0, + * this function returns successfully. + * + * Otherwise, if the process is in the same mount namespace as pid 1, create + * a new namespace. + * + * If you invoke this function, it must be before ostree_sysroot_load(); it may + * be invoked before or after ostree_sysroot_initialize(). + * + * Since: 2022.7 + */ +gboolean +ostree_sysroot_initialize_with_mount_namespace (OstreeSysroot *self, GCancellable *cancellable, + GError **error) +{ + GLNX_AUTO_PREFIX_ERROR ("Initializing with mountns", error); + /* Must be before we're loaded, as otherwise we'd have to close/reopen all our + fds, e.g. the repo */ + g_assert (self->loadstate < OSTREE_SYSROOT_LOAD_STATE_LOADED); + + if (!ostree_sysroot_initialize (self, error)) + return FALSE; + + /* Do nothing if we're not privileged */ + if (getuid () != 0) + return TRUE; + + /* We also assume operating on non-booted roots won't have a readonly sysroot */ + if (!self->root_is_ostree_booted) + return TRUE; + + g_autofree char *mntns_pid1 + = glnx_readlinkat_malloc (AT_FDCWD, "/proc/1/ns/mnt", cancellable, error); + if (!mntns_pid1) + return glnx_prefix_error (error, "Reading /proc/1/ns/mnt"); + g_autofree char *mntns_self + = glnx_readlinkat_malloc (AT_FDCWD, "/proc/self/ns/mnt", cancellable, error); + if (!mntns_self) + return glnx_prefix_error (error, "Reading /proc/self/ns/mnt"); + + // If the mount namespaces are the same, we need to unshare(). + if (strcmp (mntns_pid1, mntns_self) == 0) + { + if (unshare (CLONE_NEWNS) < 0) + return glnx_throw_errno_prefix (error, "Failed to invoke unshare(CLONE_NEWNS)"); + } + + ostree_sysroot_set_mount_namespace_in_use (self); + return TRUE; +} + /** * ostree_sysroot_get_path: * @self: Sysroot @@ -266,20 +318,19 @@ ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self) * Returns: (transfer none) (not nullable): Path to rootfs */ GFile * -ostree_sysroot_get_path (OstreeSysroot *self) +ostree_sysroot_get_path (OstreeSysroot *self) { return self->path; } /* Open a directory file descriptor for the sysroot if we haven't yet */ static gboolean -ensure_sysroot_fd (OstreeSysroot *self, - GError **error) +ensure_sysroot_fd (OstreeSysroot *self, GError **error) { if (self->sysroot_fd == -1) { - if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->path), TRUE, - &self->sysroot_fd, error)) + if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->path), TRUE, &self->sysroot_fd, + error)) return FALSE; } @@ -291,8 +342,7 @@ _ostree_sysroot_ensure_boot_fd (OstreeSysroot *self, GError **error) { if (self->boot_fd == -1) { - if (!glnx_opendirat (self->sysroot_fd, "boot", TRUE, - &self->boot_fd, error)) + if (!glnx_opendirat (self->sysroot_fd, "boot", TRUE, &self->boot_fd, error)) return FALSE; } return TRUE; @@ -325,17 +375,15 @@ remount_writable (const char *path, gboolean *did_remount, GError **error) /* Remount /sysroot read-write if necessary */ gboolean -_ostree_sysroot_ensure_writable (OstreeSysroot *self, - GError **error) +_ostree_sysroot_ensure_writable (OstreeSysroot *self, GError **error) { + if (!ostree_sysroot_initialize (self, error)) + return FALSE; + /* Do nothing if no mount namespace is in use */ if (!self->mount_namespace_in_use) return TRUE; - /* If a mount namespace is in use, ensure we're initialized */ - if (!ostree_sysroot_initialize (self, error)) - return FALSE; - /* If we aren't operating on a booted system, then we don't * do anything with mounts. */ @@ -385,7 +433,7 @@ ostree_sysroot_get_fd (OstreeSysroot *self) * @self: Sysroot * * Can only be invoked after `ostree_sysroot_initialize()`. - * + * * Returns: %TRUE iff the sysroot points to a booted deployment * Since: 2020.1 */ @@ -397,8 +445,7 @@ ostree_sysroot_is_booted (OstreeSysroot *self) } gboolean -_ostree_sysroot_bump_mtime (OstreeSysroot *self, - GError **error) +_ostree_sysroot_bump_mtime (OstreeSysroot *self, GError **error) { /* Allow other systems to monitor for changes */ if (utimensat (self->sysroot_fd, "ostree/deploy", NULL, 0) < 0) @@ -421,7 +468,7 @@ _ostree_sysroot_bump_mtime (OstreeSysroot *self, * This undoes the effect of `ostree_sysroot_load()`. */ void -ostree_sysroot_unload (OstreeSysroot *self) +ostree_sysroot_unload (OstreeSysroot *self) { glnx_close_fd (&self->sysroot_fd); glnx_close_fd (&self->boot_fd); @@ -437,42 +484,33 @@ ostree_sysroot_unload (OstreeSysroot *self) * /ostree/repo, among other things. */ gboolean -ostree_sysroot_ensure_initialized (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +ostree_sysroot_ensure_initialized (OstreeSysroot *self, GCancellable *cancellable, GError **error) { if (!ensure_sysroot_fd (self, error)) return FALSE; - if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, "ostree/repo", 0755, - cancellable, error)) + if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, "ostree/repo", 0755, cancellable, error)) return FALSE; - if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, "ostree/deploy", 0755, - cancellable, error)) + if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, "ostree/deploy", 0755, cancellable, error)) return FALSE; - g_autoptr(OstreeRepo) repo = - ostree_repo_create_at (self->sysroot_fd, "ostree/repo", - OSTREE_REPO_MODE_BARE, NULL, - cancellable, error); + g_autoptr (OstreeRepo) repo = ostree_repo_create_at ( + self->sysroot_fd, "ostree/repo", OSTREE_REPO_MODE_BARE, NULL, cancellable, error); if (!repo) return FALSE; return TRUE; } void -_ostree_sysroot_emit_journal_msg (OstreeSysroot *self, - const char *msg) +_ostree_sysroot_emit_journal_msg (OstreeSysroot *self, const char *msg) { g_signal_emit (self, signals[JOURNAL_MSG_SIGNAL], 0, msg); } gboolean -_ostree_sysroot_parse_deploy_path_name (const char *name, - char **out_csum, - int *out_serial, - GError **error) +_ostree_sysroot_parse_deploy_path_name (const char *name, char **out_csum, int *out_serial, + GError **error) { static gsize regex_initialized; @@ -484,7 +522,7 @@ _ostree_sysroot_parse_deploy_path_name (const char *name, g_once_init_leave (®ex_initialized, 1); } - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; if (!g_regex_match (regex, name, 0, &match)) return glnx_throw (error, "Invalid deploy name '%s', expected CHECKSUM.TREESERIAL", name); @@ -496,47 +534,47 @@ _ostree_sysroot_parse_deploy_path_name (const char *name, /* For a given bootversion, get its subbootversion from `/ostree/boot.$bootversion`. */ gboolean -_ostree_sysroot_read_current_subbootversion (OstreeSysroot *self, - int bootversion, - int *out_subbootversion, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_read_current_subbootversion (OstreeSysroot *self, int bootversion, + int *out_subbootversion, GCancellable *cancellable, + GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Reading current subbootversion", error); + if (!ensure_sysroot_fd (self, error)) return FALSE; g_autofree char *ostree_bootdir_name = g_strdup_printf ("ostree/boot.%d", bootversion); struct stat stbuf; - if (!glnx_fstatat_allow_noent (self->sysroot_fd, ostree_bootdir_name, &stbuf, AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat_allow_noent (self->sysroot_fd, ostree_bootdir_name, &stbuf, AT_SYMLINK_NOFOLLOW, + error)) return FALSE; if (errno == ENOENT) { - g_debug ("Didn't find $sysroot/ostree/boot.%d symlink; assuming subbootversion 0", bootversion); + g_debug ("Didn't find $sysroot/ostree/boot.%d symlink; assuming subbootversion 0", + bootversion); *out_subbootversion = 0; } else { - g_autofree char *current_subbootdir_name = - glnx_readlinkat_malloc (self->sysroot_fd, ostree_bootdir_name, - cancellable, error); + g_autofree char *current_subbootdir_name + = glnx_readlinkat_malloc (self->sysroot_fd, ostree_bootdir_name, cancellable, error); if (!current_subbootdir_name) - return FALSE; + return glnx_prefix_error (error, "Reading %s", ostree_bootdir_name); if (g_str_has_suffix (current_subbootdir_name, ".0")) *out_subbootversion = 0; else if (g_str_has_suffix (current_subbootdir_name, ".1")) *out_subbootversion = 1; else - return glnx_throw (error, "Invalid target '%s' in %s", - current_subbootdir_name, ostree_bootdir_name); + return glnx_throw (error, "Invalid target '%s' in %s", current_subbootdir_name, + ostree_bootdir_name); } return TRUE; } static gint -compare_boot_loader_configs (OstreeBootconfigParser *a, - OstreeBootconfigParser *b) +compare_boot_loader_configs (OstreeBootconfigParser *a, OstreeBootconfigParser *b) { const char *a_version = ostree_bootconfig_parser_get (a, "version"); const char *b_version = ostree_bootconfig_parser_get (b, "version"); @@ -554,34 +592,33 @@ compare_boot_loader_configs (OstreeBootconfigParser *a, } static int -compare_loader_configs_for_sorting (gconstpointer a_pp, - gconstpointer b_pp) +compare_loader_configs_for_sorting (gconstpointer a_pp, gconstpointer b_pp) { - OstreeBootconfigParser *a = *((OstreeBootconfigParser**)a_pp); - OstreeBootconfigParser *b = *((OstreeBootconfigParser**)b_pp); + OstreeBootconfigParser *a = *((OstreeBootconfigParser **)a_pp); + OstreeBootconfigParser *b = *((OstreeBootconfigParser **)b_pp); return compare_boot_loader_configs (a, b); } /* Read all the bootconfigs from `/boot/loader/`. */ gboolean -_ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, - int bootversion, - GPtrArray **out_loader_configs, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, int bootversion, + GPtrArray **out_loader_configs, GCancellable *cancellable, + GError **error) { if (!ensure_sysroot_fd (self, error)) return FALSE; - g_autoptr(GPtrArray) ret_loader_configs = - g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); + g_autoptr (GPtrArray) ret_loader_configs + = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); g_autofree char *entries_path = g_strdup_printf ("boot/loader.%d/entries", bootversion); gboolean entries_exists; - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - if (!ot_dfd_iter_init_allow_noent (self->sysroot_fd, entries_path, - &dfd_iter, &entries_exists, error)) + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + if (!ot_dfd_iter_init_allow_noent (self->sysroot_fd, entries_path, &dfd_iter, &entries_exists, + error)) return FALSE; if (!entries_exists) { @@ -603,13 +640,13 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, if (!glnx_fstatat (dfd_iter.fd, dent->d_name, &stbuf, 0, error)) return FALSE; - if (g_str_has_prefix (dent->d_name, "ostree-") && - g_str_has_suffix (dent->d_name, ".conf") && - S_ISREG (stbuf.st_mode)) + if (g_str_has_prefix (dent->d_name, "ostree-") && g_str_has_suffix (dent->d_name, ".conf") + && S_ISREG (stbuf.st_mode)) { - g_autoptr(OstreeBootconfigParser) config = ostree_bootconfig_parser_new (); + g_autoptr (OstreeBootconfigParser) config = ostree_bootconfig_parser_new (); - if (!ostree_bootconfig_parser_parse_at (config, dfd_iter.fd, dent->d_name, cancellable, error)) + if (!ostree_bootconfig_parser_parse_at (config, dfd_iter.fd, dent->d_name, cancellable, + error)) return glnx_prefix_error (error, "Parsing %s", dent->d_name); g_ptr_array_add (ret_loader_configs, g_object_ref (config)); @@ -618,21 +655,20 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, /* Callers expect us to give them a sorted array */ g_ptr_array_sort (ret_loader_configs, compare_loader_configs_for_sorting); - ot_transfer_out_value(out_loader_configs, &ret_loader_configs); + ot_transfer_out_value (out_loader_configs, &ret_loader_configs); return TRUE; } /* Get the bootversion from the `/boot/loader` symlink. */ static gboolean -read_current_bootversion (OstreeSysroot *self, - int *out_bootversion, - GCancellable *cancellable, - GError **error) +read_current_bootversion (OstreeSysroot *self, int *out_bootversion, GCancellable *cancellable, + GError **error) { int ret_bootversion; struct stat stbuf; - if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", &stbuf, AT_SYMLINK_NOFOLLOW, + error)) return FALSE; if (errno == ENOENT) { @@ -644,8 +680,8 @@ read_current_bootversion (OstreeSysroot *self, if (!S_ISLNK (stbuf.st_mode)) return glnx_throw (error, "Not a symbolic link: boot/loader"); - g_autofree char *target = - glnx_readlinkat_malloc (self->sysroot_fd, "boot/loader", cancellable, error); + g_autofree char *target + = glnx_readlinkat_malloc (self->sysroot_fd, "boot/loader", cancellable, error); if (!target) return FALSE; if (g_strcmp0 (target, "loader.0") == 0) @@ -661,10 +697,8 @@ read_current_bootversion (OstreeSysroot *self, } static gboolean -load_origin (OstreeSysroot *self, - OstreeDeployment *deployment, - GCancellable *cancellable, - GError **error) +load_origin (OstreeSysroot *self, OstreeDeployment *deployment, GCancellable *cancellable, + GError **error) { g_autofree char *origin_path = ostree_deployment_get_origin_relpath (deployment); @@ -673,12 +707,11 @@ load_origin (OstreeSysroot *self, return FALSE; if (fd >= 0) { - g_autofree char *origin_contents = - glnx_fd_readall_utf8 (fd, NULL, cancellable, error); + g_autofree char *origin_contents = glnx_fd_readall_utf8 (fd, NULL, cancellable, error); if (!origin_contents) return FALSE; - g_autoptr(GKeyFile) origin = g_key_file_new (); + g_autoptr (GKeyFile) origin = g_key_file_new (); if (!g_key_file_load_from_data (origin, origin_contents, -1, 0, error)) return glnx_prefix_error (error, "Parsing %s", origin_path); @@ -688,13 +721,10 @@ load_origin (OstreeSysroot *self, return TRUE; } -static gboolean -parse_bootlink (const char *bootlink, - int *out_entry_bootversion, - char **out_osname, - char **out_bootcsum, - int *out_treebootserial, - GError **error) +// Parse the kernel argument ostree= +gboolean +_ostree_sysroot_parse_bootlink (const char *bootlink, int *out_entry_bootversion, char **out_osname, + char **out_bootcsum, int *out_treebootserial, GError **error) { static gsize regex_initialized; static GRegex *regex; @@ -705,35 +735,37 @@ parse_bootlink (const char *bootlink, g_once_init_leave (®ex_initialized, 1); } - g_autoptr(GMatchInfo) match = NULL; + g_autoptr (GMatchInfo) match = NULL; if (!g_regex_match (regex, bootlink, 0, &match)) - return glnx_throw (error, "Invalid ostree= argument '%s', expected ostree=/ostree/boot.BOOTVERSION/OSNAME/BOOTCSUM/TREESERIAL", bootlink); + return glnx_throw (error, + "Invalid ostree= argument '%s', expected " + "ostree=/ostree/boot.BOOTVERSION/OSNAME/BOOTCSUM/TREESERIAL", + bootlink); g_autofree char *bootversion_str = g_match_info_fetch (match, 1); g_autofree char *treebootserial_str = g_match_info_fetch (match, 4); - *out_entry_bootversion = (int)g_ascii_strtoll (bootversion_str, NULL, 10); - *out_osname = g_match_info_fetch (match, 2); - *out_bootcsum = g_match_info_fetch (match, 3); - *out_treebootserial = (int)g_ascii_strtoll (treebootserial_str, NULL, 10); + if (out_entry_bootversion) + *out_entry_bootversion = (int)g_ascii_strtoll (bootversion_str, NULL, 10); + if (out_osname) + *out_osname = g_match_info_fetch (match, 2); + if (out_bootcsum) + *out_bootcsum = g_match_info_fetch (match, 3); + if (out_treebootserial) + *out_treebootserial = (int)g_ascii_strtoll (treebootserial_str, NULL, 10); return TRUE; } char * _ostree_sysroot_get_runstate_path (OstreeDeployment *deployment, const char *key) { - return g_strdup_printf ("%s%s.%d/%s", - _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR, + return g_strdup_printf ("%s%s.%d/%s", _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR, ostree_deployment_get_csum (deployment), - ostree_deployment_get_deployserial (deployment), - key); + ostree_deployment_get_deployserial (deployment), key); } static gboolean -parse_deployment (OstreeSysroot *self, - const char *boot_link, - OstreeDeployment **out_deployment, - GCancellable *cancellable, - GError **error) +parse_deployment (OstreeSysroot *self, const char *boot_link, OstreeDeployment **out_deployment, + GCancellable *cancellable, GError **error) { if (!ensure_sysroot_fd (self, error)) return FALSE; @@ -742,65 +774,72 @@ parse_deployment (OstreeSysroot *self, g_autofree char *osname = NULL; g_autofree char *bootcsum = NULL; int treebootserial = -1; - if (!parse_bootlink (boot_link, &entry_boot_version, - &osname, &bootcsum, &treebootserial, - error)) + if (!_ostree_sysroot_parse_bootlink (boot_link, &entry_boot_version, &osname, &bootcsum, + &treebootserial, error)) return FALSE; - g_autofree char *errprefix = - g_strdup_printf ("Parsing deployment %s in stateroot '%s'", boot_link, osname); - GLNX_AUTO_PREFIX_ERROR(errprefix, error); + g_autofree char *errprefix + = g_strdup_printf ("Parsing deployment %s in stateroot '%s'", boot_link, osname); + GLNX_AUTO_PREFIX_ERROR (errprefix, error); const char *relative_boot_link = boot_link; if (*relative_boot_link == '/') relative_boot_link++; - g_autofree char *treebootserial_target = - glnx_readlinkat_malloc (self->sysroot_fd, relative_boot_link, - cancellable, error); + g_autofree char *treebootserial_target + = glnx_readlinkat_malloc (self->sysroot_fd, relative_boot_link, cancellable, error); if (!treebootserial_target) return FALSE; const char *deploy_basename = glnx_basename (treebootserial_target); g_autofree char *treecsum = NULL; int deployserial = -1; - if (!_ostree_sysroot_parse_deploy_path_name (deploy_basename, - &treecsum, &deployserial, error)) + if (!_ostree_sysroot_parse_deploy_path_name (deploy_basename, &treecsum, &deployserial, error)) return FALSE; glnx_autofd int deployment_dfd = -1; - if (!glnx_opendirat (self->sysroot_fd, relative_boot_link, TRUE, - &deployment_dfd, error)) + if (!glnx_opendirat (self->sysroot_fd, relative_boot_link, TRUE, &deployment_dfd, error)) return FALSE; /* See if this is the booted deployment */ - const gboolean looking_for_booted_deployment = - (self->root_is_ostree_booted && !self->booted_deployment); + const gboolean looking_for_booted_deployment + = (self->root_is_ostree_booted && !self->booted_deployment); gboolean is_booted_deployment = FALSE; if (looking_for_booted_deployment) { struct stat stbuf; + struct stat etc_stbuf = {}; if (!glnx_fstat (deployment_dfd, &stbuf, error)) return FALSE; + + /* We look for either the root or the etc subdir of the + * deployment. We need to do this, because when using composefs, + * the root is not a bind mount of the deploy dir, but the etc + * dir is. + */ + + if (!glnx_fstatat_allow_noent (deployment_dfd, "etc", &etc_stbuf, 0, error)) + return FALSE; + /* A bit ugly, we're assigning to a sysroot-owned variable from deep in * this parsing code. But eh, if something fails the sysroot state can't * be relied on anyways. */ - is_booted_deployment = (stbuf.st_dev == self->root_device && - stbuf.st_ino == self->root_inode); + is_booted_deployment + = (stbuf.st_dev == self->root_device && stbuf.st_ino == self->root_inode) + || (etc_stbuf.st_dev == self->etc_device && etc_stbuf.st_ino == self->etc_inode); } - g_autoptr(OstreeDeployment) ret_deployment - = ostree_deployment_new (-1, osname, treecsum, deployserial, - bootcsum, treebootserial); + g_autoptr (OstreeDeployment) ret_deployment + = ostree_deployment_new (-1, osname, treecsum, deployserial, bootcsum, treebootserial); if (!load_origin (self, ret_deployment, cancellable, error)) return FALSE; ret_deployment->unlocked = OSTREE_DEPLOYMENT_UNLOCKED_NONE; - g_autofree char *unlocked_development_path = - _ostree_sysroot_get_runstate_path (ret_deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT); - g_autofree char *unlocked_transient_path = - _ostree_sysroot_get_runstate_path (ret_deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_TRANSIENT); + g_autofree char *unlocked_development_path = _ostree_sysroot_get_runstate_path ( + ret_deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT); + g_autofree char *unlocked_transient_path = _ostree_sysroot_get_runstate_path ( + ret_deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_TRANSIENT); struct stat stbuf; if (lstat (unlocked_development_path, &stbuf) == 0) ret_deployment->unlocked = OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT; @@ -809,8 +848,8 @@ parse_deployment (OstreeSysroot *self, else { GKeyFile *origin = ostree_deployment_get_origin (ret_deployment); - g_autofree char *existing_unlocked_state = origin ? - g_key_file_get_string (origin, "origin", "unlocked", NULL) : NULL; + g_autofree char *existing_unlocked_state + = origin ? g_key_file_get_string (origin, "origin", "unlocked", NULL) : NULL; if (g_strcmp0 (existing_unlocked_state, "hotfix") == 0) { @@ -832,13 +871,13 @@ parse_deployment (OstreeSysroot *self, * argument. */ static char * -get_ostree_kernel_arg_from_config (OstreeBootconfigParser *config) +get_ostree_kernel_arg_from_config (OstreeBootconfigParser *config) { const char *options = ostree_bootconfig_parser_get (config, "options"); if (!options) return NULL; - g_auto(GStrv) opts = g_strsplit (options, " ", -1); + g_auto (GStrv) opts = g_strsplit (options, " ", -1); for (char **iter = opts; *iter; iter++) { const char *opt = *iter; @@ -852,24 +891,21 @@ get_ostree_kernel_arg_from_config (OstreeBootconfigParser *config) /* From a BLS config, use its ostree= karg to find the deployment it points to and add it to * the inout_deployments array. */ static gboolean -list_deployments_process_one_boot_entry (OstreeSysroot *self, - OstreeBootconfigParser *config, - GPtrArray *inout_deployments, - GCancellable *cancellable, - GError **error) +list_deployments_process_one_boot_entry (OstreeSysroot *self, OstreeBootconfigParser *config, + GPtrArray *inout_deployments, GCancellable *cancellable, + GError **error) { g_autofree char *ostree_arg = get_ostree_kernel_arg_from_config (config); if (ostree_arg == NULL) return glnx_throw (error, "No ostree= kernel argument found"); - g_autoptr(OstreeDeployment) deployment = NULL; - if (!parse_deployment (self, ostree_arg, &deployment, - cancellable, error)) + g_autoptr (OstreeDeployment) deployment = NULL; + if (!parse_deployment (self, ostree_arg, &deployment, cancellable, error)) return FALSE; ostree_deployment_set_bootconfig (deployment, config); char **overlay_initrds = ostree_bootconfig_parser_get_overlay_initrds (config); - g_autoptr(GPtrArray) initrds_chksums = NULL; + g_autoptr (GPtrArray) initrds_chksums = NULL; for (char **it = overlay_initrds; it && *it; it++) { const char *basename = glnx_basename (*it); @@ -884,7 +920,7 @@ list_deployments_process_one_boot_entry (OstreeSysroot *self, if (initrds_chksums) { g_ptr_array_add (initrds_chksums, NULL); - _ostree_deployment_set_overlay_initrds (deployment, (char**)initrds_chksums->pdata); + _ostree_deployment_set_overlay_initrds (deployment, (char **)initrds_chksums->pdata); } g_ptr_array_add (inout_deployments, g_object_ref (deployment)); @@ -892,11 +928,10 @@ list_deployments_process_one_boot_entry (OstreeSysroot *self, } static gint -compare_deployments_by_boot_loader_version_reversed (gconstpointer a_pp, - gconstpointer b_pp) +compare_deployments_by_boot_loader_version_reversed (gconstpointer a_pp, gconstpointer b_pp) { - OstreeDeployment *a = *((OstreeDeployment**)a_pp); - OstreeDeployment *b = *((OstreeDeployment**)b_pp); + OstreeDeployment *a = *((OstreeDeployment **)a_pp); + OstreeDeployment *b = *((OstreeDeployment **)b_pp); OstreeBootconfigParser *a_bootconfig = ostree_deployment_get_bootconfig (a); OstreeBootconfigParser *b_bootconfig = ostree_deployment_get_bootconfig (b); @@ -922,17 +957,16 @@ compare_deployments_by_boot_loader_version_reversed (gconstpointer a_pp, * rootfs @self. */ gboolean -ostree_sysroot_load (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +ostree_sysroot_load (OstreeSysroot *self, GCancellable *cancellable, GError **error) { return ostree_sysroot_load_if_changed (self, NULL, cancellable, error); } static gboolean -ensure_repo (OstreeSysroot *self, - GError **error) +ensure_repo (OstreeSysroot *self, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Opening sysroot repo", error); + if (self->repo != NULL) return TRUE; if (!ensure_sysroot_fd (self, error)) @@ -969,9 +1003,10 @@ ensure_repo (OstreeSysroot *self, * Since: 2020.1 */ gboolean -ostree_sysroot_initialize (OstreeSysroot *self, - GError **error) +ostree_sysroot_initialize (OstreeSysroot *self, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Initializing sysroot", error); + if (!ensure_sysroot_fd (self, error)) return FALSE; @@ -985,20 +1020,31 @@ ostree_sysroot_initialize (OstreeSysroot *self, return FALSE; const gboolean ostree_booted = (errno == 0); - { struct stat root_stbuf; + { + struct stat root_stbuf; if (!glnx_fstatat (AT_FDCWD, "/", &root_stbuf, 0, error)) return FALSE; self->root_device = root_stbuf.st_dev; self->root_inode = root_stbuf.st_ino; } + { + struct stat etc_stbuf; + if (!glnx_fstatat_allow_noent (AT_FDCWD, "/etc", &etc_stbuf, 0, error)) + return FALSE; + if (errno != ENOENT) + { + self->etc_device = etc_stbuf.st_dev; + self->etc_inode = etc_stbuf.st_ino; + } + } + struct stat self_stbuf; if (!glnx_fstatat (AT_FDCWD, gs_file_get_path_cached (self->path), &self_stbuf, 0, error)) return FALSE; - const gboolean root_is_sysroot = - (self->root_device == self_stbuf.st_dev && - self->root_inode == self_stbuf.st_ino); + const gboolean root_is_sysroot + = (self->root_device == self_stbuf.st_dev && self->root_inode == self_stbuf.st_ino); self->root_is_ostree_booted = (ostree_booted && root_is_sysroot); self->loadstate = OSTREE_SYSROOT_LOAD_STATE_INIT; @@ -1009,8 +1055,7 @@ ostree_sysroot_initialize (OstreeSysroot *self, /* Reload the staged deployment from the file in /run */ gboolean -_ostree_sysroot_reload_staged (OstreeSysroot *self, - GError **error) +_ostree_sysroot_reload_staged (OstreeSysroot *self, GError **error) { GLNX_AUTO_PREFIX_ERROR ("Loading staged deployment", error); if (!self->root_is_ostree_booted) @@ -1027,16 +1072,15 @@ _ostree_sysroot_reload_staged (OstreeSysroot *self, return FALSE; if (fd != -1) { - g_autoptr(GBytes) contents = ot_fd_readall_or_mmap (fd, 0, error); + g_autoptr (GBytes) contents = ot_fd_readall_or_mmap (fd, 0, error); if (!contents) return FALSE; - g_autoptr(GVariant) staged_deployment_data = - g_variant_new_from_bytes ((GVariantType*)"a{sv}", contents, TRUE); - g_autoptr(GVariantDict) staged_deployment_dict = - g_variant_dict_new (staged_deployment_data); + g_autoptr (GVariant) staged_deployment_data + = g_variant_new_from_bytes ((GVariantType *)"a{sv}", contents, TRUE); + g_autoptr (GVariantDict) staged_deployment_dict = g_variant_dict_new (staged_deployment_data); /* Parse it */ - g_autoptr(GVariant) target = NULL; + g_autoptr (GVariant) target = NULL; g_autofree char **kargs = NULL; g_autofree char **overlay_initrds = NULL; g_variant_dict_lookup (staged_deployment_dict, "target", "@a{sv}", &target); @@ -1044,8 +1088,8 @@ _ostree_sysroot_reload_staged (OstreeSysroot *self, g_variant_dict_lookup (staged_deployment_dict, "overlay-initrds", "^a&s", &overlay_initrds); if (target) { - g_autoptr(OstreeDeployment) staged = - _ostree_sysroot_deserialize_deployment_from_variant (target, error); + g_autoptr (OstreeDeployment) staged + = _ostree_sysroot_deserialize_deployment_from_variant (target, error); if (!staged) return FALSE; @@ -1072,9 +1116,8 @@ _ostree_sysroot_reload_staged (OstreeSysroot *self, * bootloader configs which are the source of truth. */ static gboolean -sysroot_load_from_bootloader_configs (OstreeSysroot *self, - GCancellable *cancellable, - GError **error) +sysroot_load_from_bootloader_configs (OstreeSysroot *self, GCancellable *cancellable, + GError **error) { struct stat stbuf; @@ -1083,16 +1126,17 @@ sysroot_load_from_bootloader_configs (OstreeSysroot *self, return FALSE; int subbootversion = 0; - if (!_ostree_sysroot_read_current_subbootversion (self, bootversion, &subbootversion, - cancellable, error)) + if (!_ostree_sysroot_read_current_subbootversion (self, bootversion, &subbootversion, cancellable, + error)) return FALSE; - g_autoptr(GPtrArray) boot_loader_configs = NULL; + g_autoptr (GPtrArray) boot_loader_configs = NULL; if (!_ostree_sysroot_read_boot_loader_configs (self, bootversion, &boot_loader_configs, cancellable, error)) return FALSE; - g_autoptr(GPtrArray) deployments = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); + g_autoptr (GPtrArray) deployments + = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); g_assert (boot_loader_configs); /* Pacify static analysis */ for (guint i = 0; i < boot_loader_configs->len; i++) @@ -1100,8 +1144,7 @@ sysroot_load_from_bootloader_configs (OstreeSysroot *self, OstreeBootconfigParser *config = boot_loader_configs->pdata[i]; /* Note this also sets self->booted_deployment */ - if (!list_deployments_process_one_boot_entry (self, config, deployments, - cancellable, error)) + if (!list_deployments_process_one_boot_entry (self, config, deployments, cancellable, error)) { g_clear_object (&self->booted_deployment); return FALSE; @@ -1110,17 +1153,21 @@ sysroot_load_from_bootloader_configs (OstreeSysroot *self, if (self->root_is_ostree_booted && !self->booted_deployment) { - if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", NULL, AT_SYMLINK_NOFOLLOW, error)) + if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", NULL, AT_SYMLINK_NOFOLLOW, + error)) return FALSE; if (errno == ENOENT) { - return glnx_throw (error, "Unexpected state: %s found, but no /boot/loader directory", OSTREE_PATH_BOOTED); + return glnx_throw (error, "Unexpected state: %s found, but no /boot/loader directory", + OSTREE_PATH_BOOTED); } else { - return glnx_throw (error, "Unexpected state: %s found and in / sysroot, but bootloader entry not found", OSTREE_PATH_BOOTED); + return glnx_throw ( + error, "Unexpected state: %s found and in / sysroot, but bootloader entry not found", + OSTREE_PATH_BOOTED); } - } + } if (!_ostree_sysroot_reload_staged (self, error)) return FALSE; @@ -1146,7 +1193,7 @@ sysroot_load_from_bootloader_configs (OstreeSysroot *self, * not physical. */ if (self->booted_deployment) - self->is_physical = FALSE; /* (the default, but explicit for clarity) */ + self->is_physical = FALSE; /* (the default, but explicit for clarity) */ /* Otherwise - check for /sysroot which should only exist in a deployment, * not in ${sysroot} (a metavariable for the real physical root). */ @@ -1179,10 +1226,8 @@ sysroot_load_from_bootloader_configs (OstreeSysroot *self, * Since: 2016.4 */ gboolean -ostree_sysroot_load_if_changed (OstreeSysroot *self, - gboolean *out_changed, - GCancellable *cancellable, - GError **error) +ostree_sysroot_load_if_changed (OstreeSysroot *self, gboolean *out_changed, + GCancellable *cancellable, GError **error) { GLNX_AUTO_PREFIX_ERROR ("loading sysroot", error); @@ -1200,8 +1245,8 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self, if (!glnx_fstatat (self->sysroot_fd, "ostree/deploy", &stbuf, 0, error)) return FALSE; - if (self->loaded_ts.tv_sec == stbuf.st_mtim.tv_sec && - self->loaded_ts.tv_nsec == stbuf.st_mtim.tv_nsec) + if (self->loaded_ts.tv_sec == stbuf.st_mtim.tv_sec + && self->loaded_ts.tv_nsec == stbuf.st_mtim.tv_nsec) { if (out_changed) *out_changed = FALSE; @@ -1226,13 +1271,13 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self, } int -ostree_sysroot_get_bootversion (OstreeSysroot *self) +ostree_sysroot_get_bootversion (OstreeSysroot *self) { return self->bootversion; } int -ostree_sysroot_get_subbootversion (OstreeSysroot *self) +ostree_sysroot_get_subbootversion (OstreeSysroot *self) { return self->subbootversion; } @@ -1246,7 +1291,7 @@ ostree_sysroot_get_subbootversion (OstreeSysroot *self) * Returns: (transfer none) (nullable): The currently booted deployment, or %NULL if none */ OstreeDeployment * -ostree_sysroot_get_booted_deployment (OstreeSysroot *self) +ostree_sysroot_get_booted_deployment (OstreeSysroot *self) { g_assert (self); g_assert (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED); @@ -1254,7 +1299,6 @@ ostree_sysroot_get_booted_deployment (OstreeSysroot *self) return self->booted_deployment; } - /** * ostree_sysroot_require_booted_deployment: * @self: Sysroot @@ -1274,7 +1318,6 @@ ostree_sysroot_require_booted_deployment (OstreeSysroot *self, GError **error) return self->booted_deployment; } - /** * ostree_sysroot_get_staged_deployment: * @self: Sysroot @@ -1284,7 +1327,7 @@ ostree_sysroot_require_booted_deployment (OstreeSysroot *self, GError **error) * Since: 2018.5 */ OstreeDeployment * -ostree_sysroot_get_staged_deployment (OstreeSysroot *self) +ostree_sysroot_get_staged_deployment (OstreeSysroot *self) { g_assert (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED); @@ -1298,7 +1341,7 @@ ostree_sysroot_get_staged_deployment (OstreeSysroot *self) * Returns: (element-type OstreeDeployment) (transfer container): Ordered list of deployments */ GPtrArray * -ostree_sysroot_get_deployments (OstreeSysroot *self) +ostree_sysroot_get_deployments (OstreeSysroot *self) { g_assert (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED); @@ -1320,13 +1363,11 @@ ostree_sysroot_get_deployments (OstreeSysroot *self) * Returns: (transfer full) (not nullable): Path to deployment root directory, relative to sysroot */ char * -ostree_sysroot_get_deployment_dirpath (OstreeSysroot *self, - OstreeDeployment *deployment) +ostree_sysroot_get_deployment_dirpath (OstreeSysroot *self, OstreeDeployment *deployment) { - return g_strdup_printf ("ostree/deploy/%s/deploy/%s.%d", - ostree_deployment_get_osname (deployment), - ostree_deployment_get_csum (deployment), - ostree_deployment_get_deployserial (deployment)); + return g_strdup_printf ( + "ostree/deploy/%s/deploy/%s.%d", ostree_deployment_get_osname (deployment), + ostree_deployment_get_csum (deployment), ostree_deployment_get_deployserial (deployment)); } /** @@ -1337,8 +1378,7 @@ ostree_sysroot_get_deployment_dirpath (OstreeSysroot *self, * Returns: (transfer full): Path to deployment root directory */ GFile * -ostree_sysroot_get_deployment_directory (OstreeSysroot *self, - OstreeDeployment *deployment) +ostree_sysroot_get_deployment_directory (OstreeSysroot *self, OstreeDeployment *deployment) { g_autofree char *dirpath = ostree_sysroot_get_deployment_dirpath (self, deployment); return g_file_resolve_relative_path (self->path, dirpath); @@ -1351,11 +1391,10 @@ ostree_sysroot_get_deployment_directory (OstreeSysroot *self, * Returns: (transfer full): Path to deployment origin file */ GFile * -ostree_sysroot_get_deployment_origin_path (GFile *deployment_path) +ostree_sysroot_get_deployment_origin_path (GFile *deployment_path) { - g_autoptr(GFile) deployment_parent = g_file_get_parent (deployment_path); - return ot_gfile_resolve_path_printf (deployment_parent, - "%s.origin", + g_autoptr (GFile) deployment_parent = g_file_get_parent (deployment_path); + return ot_gfile_resolve_path_printf (deployment_parent, "%s.origin", gs_file_get_path_cached (deployment_path)); } @@ -1372,10 +1411,8 @@ ostree_sysroot_get_deployment_origin_path (GFile *deployment_path) * Returns: %TRUE on success, %FALSE otherwise */ gboolean -ostree_sysroot_get_repo (OstreeSysroot *self, - OstreeRepo **out_repo, - GCancellable *cancellable, - GError **error) +ostree_sysroot_get_repo (OstreeSysroot *self, OstreeRepo **out_repo, GCancellable *cancellable, + GError **error) { if (!ensure_repo (self, error)) return FALSE; @@ -1405,10 +1442,9 @@ ostree_sysroot_repo (OstreeSysroot *self) return self->repo; } -static OstreeBootloader* -_ostree_sysroot_new_bootloader_by_type ( - OstreeSysroot *sysroot, - OstreeCfgSysrootBootloaderOpt bl_type) +static OstreeBootloader * +_ostree_sysroot_new_bootloader_by_type (OstreeSysroot *sysroot, + OstreeCfgSysrootBootloaderOpt bl_type) { switch (bl_type) { @@ -1416,15 +1452,17 @@ _ostree_sysroot_new_bootloader_by_type ( /* No bootloader specified; do not query bootloaders to run. */ return NULL; case CFG_SYSROOT_BOOTLOADER_OPT_GRUB2: - return (OstreeBootloader*) _ostree_bootloader_grub2_new (sysroot); + return (OstreeBootloader *)_ostree_bootloader_grub2_new (sysroot); case CFG_SYSROOT_BOOTLOADER_OPT_SYSLINUX: - return (OstreeBootloader*) _ostree_bootloader_syslinux_new (sysroot); + return (OstreeBootloader *)_ostree_bootloader_syslinux_new (sysroot); + case CFG_SYSROOT_BOOTLOADER_OPT_ABOOT: + return (OstreeBootloader *)_ostree_bootloader_aboot_new (sysroot); case CFG_SYSROOT_BOOTLOADER_OPT_UBOOT: - return (OstreeBootloader*) _ostree_bootloader_uboot_new (sysroot); + return (OstreeBootloader *)_ostree_bootloader_uboot_new (sysroot); case CFG_SYSROOT_BOOTLOADER_OPT_ZIPL: /* We never consider zipl as active by default, so it can only be created * if it's explicitly requested in the config */ - return (OstreeBootloader*) _ostree_bootloader_zipl_new (sysroot); + return (OstreeBootloader *)_ostree_bootloader_zipl_new (sysroot); case CFG_SYSROOT_BOOTLOADER_OPT_AUTO: /* "auto" is handled by ostree_sysroot_query_bootloader so we should * never get here: Fallthrough */ @@ -1436,23 +1474,22 @@ _ostree_sysroot_new_bootloader_by_type ( /** * ostree_sysroot_query_bootloader: * @sysroot: Sysroot - * @out_bootloader: (out) (transfer full) (optional) (nullable): Return location for bootloader, may be %NULL + * @out_bootloader: (out) (transfer full) (optional) (nullable): Return location for bootloader, + * may be %NULL * @cancellable: Cancellable * @error: Error */ gboolean -_ostree_sysroot_query_bootloader (OstreeSysroot *sysroot, - OstreeBootloader **out_bootloader, - GCancellable *cancellable, - GError **error) +_ostree_sysroot_query_bootloader (OstreeSysroot *sysroot, OstreeBootloader **out_bootloader, + GCancellable *cancellable, GError **error) { OstreeRepo *repo = ostree_sysroot_repo (sysroot); OstreeCfgSysrootBootloaderOpt bootloader_config = repo->bootloader; g_debug ("Using bootloader configuration: %s", - CFG_SYSROOT_BOOTLOADER_OPTS_STR[bootloader_config]); + CFG_SYSROOT_BOOTLOADER_OPTS_STR[bootloader_config]); - g_autoptr(OstreeBootloader) ret_loader = NULL; + g_autoptr (OstreeBootloader) ret_loader = NULL; if (bootloader_config == CFG_SYSROOT_BOOTLOADER_OPT_AUTO) { OstreeCfgSysrootBootloaderOpt probe[] = { @@ -1462,8 +1499,8 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot, }; for (int i = 0; i < G_N_ELEMENTS (probe); i++) { - g_autoptr(OstreeBootloader) bl = _ostree_sysroot_new_bootloader_by_type ( - sysroot, probe[i]); + g_autoptr (OstreeBootloader) bl + = _ostree_sysroot_new_bootloader_by_type (sysroot, probe[i]); gboolean is_active = FALSE; if (!_ostree_bootloader_query (bl, &is_active, cancellable, error)) return FALSE; @@ -1477,12 +1514,11 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot, else ret_loader = _ostree_sysroot_new_bootloader_by_type (sysroot, bootloader_config); - ot_transfer_out_value (out_bootloader, &ret_loader) - return TRUE; + ot_transfer_out_value (out_bootloader, &ret_loader) return TRUE; } char * -_ostree_sysroot_join_lines (GPtrArray *lines) +_ostree_sysroot_join_lines (GPtrArray *lines) { GString *buf = g_string_new (""); gboolean prev_was_empty = FALSE; @@ -1520,14 +1556,13 @@ _ostree_sysroot_join_lines (GPtrArray *lines) * Since: 2017.7 */ void -ostree_sysroot_query_deployments_for (OstreeSysroot *self, - const char *osname, - OstreeDeployment **out_pending, - OstreeDeployment **out_rollback) +ostree_sysroot_query_deployments_for (OstreeSysroot *self, const char *osname, + OstreeDeployment **out_pending, + OstreeDeployment **out_rollback) { g_assert (osname != NULL || self->booted_deployment != NULL); - g_autoptr(OstreeDeployment) ret_pending = NULL; - g_autoptr(OstreeDeployment) ret_rollback = NULL; + g_autoptr (OstreeDeployment) ret_pending = NULL; + g_autoptr (OstreeDeployment) ret_rollback = NULL; if (osname == NULL) osname = ostree_deployment_get_osname (self->booted_deployment); @@ -1539,11 +1574,11 @@ ostree_sysroot_query_deployments_for (OstreeSysroot *self, /* Ignore deployments not for this osname */ if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0) - continue; + continue; /* Is this deployment booted? If so, note we're past the booted */ - if (self->booted_deployment != NULL && - ostree_deployment_equal (deployment, self->booted_deployment)) + if (self->booted_deployment != NULL + && ostree_deployment_equal (deployment, self->booted_deployment)) { found_booted = TRUE; continue; @@ -1560,7 +1595,6 @@ ostree_sysroot_query_deployments_for (OstreeSysroot *self, *out_rollback = g_steal_pointer (&ret_rollback); } - /** * ostree_sysroot_get_merge_deployment: * @self: Sysroot @@ -1572,8 +1606,7 @@ ostree_sysroot_query_deployments_for (OstreeSysroot *self, * Returns: (transfer full) (nullable): Configuration merge deployment */ OstreeDeployment * -ostree_sysroot_get_merge_deployment (OstreeSysroot *self, - const char *osname) +ostree_sysroot_get_merge_deployment (OstreeSysroot *self, const char *osname) { g_return_val_if_fail (osname != NULL || self->booted_deployment != NULL, NULL); @@ -1584,12 +1617,12 @@ ostree_sysroot_get_merge_deployment (OstreeSysroot *self, * merge the currently *booted* configuration, rather than the most * recently deployed. */ - if (self->booted_deployment && - g_strcmp0 (ostree_deployment_get_osname (self->booted_deployment), osname) == 0) - return g_object_ref (self->booted_deployment); + if (self->booted_deployment + && g_strcmp0 (ostree_deployment_get_osname (self->booted_deployment), osname) == 0) + return g_object_ref (self->booted_deployment); else { - g_autoptr(OstreeDeployment) pending = NULL; + g_autoptr (OstreeDeployment) pending = NULL; ostree_sysroot_query_deployments_for (self, osname, &pending, NULL); return g_steal_pointer (&pending); } @@ -1603,8 +1636,7 @@ ostree_sysroot_get_merge_deployment (OstreeSysroot *self, * Returns: (transfer full) (not nullable): A new config file which sets @refspec as an origin */ GKeyFile * -ostree_sysroot_origin_new_from_refspec (OstreeSysroot *self, - const char *refspec) +ostree_sysroot_origin_new_from_refspec (OstreeSysroot *self, const char *refspec) { GKeyFile *ret = g_key_file_new (); g_key_file_set_string (ret, "origin", "refspec", refspec); @@ -1624,8 +1656,7 @@ ostree_sysroot_origin_new_from_refspec (OstreeSysroot *self, * be released if @self is deallocated. */ gboolean -ostree_sysroot_lock (OstreeSysroot *self, - GError **error) +ostree_sysroot_lock (OstreeSysroot *self, GError **error) { if (!ensure_sysroot_fd (self, error)) return FALSE; @@ -1633,8 +1664,8 @@ ostree_sysroot_lock (OstreeSysroot *self, if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; - return glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE, - LOCK_EX, &self->lock, error); + return glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE, LOCK_EX, &self->lock, + error); } /** @@ -1652,9 +1683,7 @@ ostree_sysroot_lock (OstreeSysroot *self, * be released if @self is deallocated. */ gboolean -ostree_sysroot_try_lock (OstreeSysroot *self, - gboolean *out_acquired, - GError **error) +ostree_sysroot_try_lock (OstreeSysroot *self, gboolean *out_acquired, GError **error) { if (!ensure_sysroot_fd (self, error)) return FALSE; @@ -1663,9 +1692,9 @@ ostree_sysroot_try_lock (OstreeSysroot *self, return FALSE; /* Note use of LOCK_NB */ - g_autoptr(GError) local_error = NULL; - if (!glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE, - LOCK_EX | LOCK_NB, &self->lock, &local_error)) + g_autoptr (GError) local_error = NULL; + if (!glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE, LOCK_EX | LOCK_NB, + &self->lock, &local_error)) { if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { @@ -1694,16 +1723,13 @@ ostree_sysroot_try_lock (OstreeSysroot *self, * acquired. */ void -ostree_sysroot_unlock (OstreeSysroot *self) +ostree_sysroot_unlock (OstreeSysroot *self) { glnx_release_lock_file (&self->lock); } static void -lock_in_thread (GTask *task, - gpointer source, - gpointer task_data, - GCancellable *cancellable) +lock_in_thread (GTask *task, gpointer source, gpointer task_data, GCancellable *cancellable) { GError *local_error = NULL; OstreeSysroot *self = source; @@ -1714,7 +1740,7 @@ lock_in_thread (GTask *task, if (g_cancellable_set_error_if_cancelled (cancellable, &local_error)) ostree_sysroot_unlock (self); - out: +out: if (local_error) g_task_return_error (task, local_error); else @@ -1731,12 +1757,10 @@ lock_in_thread (GTask *task, * An asynchronous version of ostree_sysroot_lock(). */ void -ostree_sysroot_lock_async (OstreeSysroot *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +ostree_sysroot_lock_async (OstreeSysroot *self, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(GTask) task = g_task_new (self, cancellable, callback, user_data); + g_autoptr (GTask) task = g_task_new (self, cancellable, callback, user_data); g_task_run_in_thread (task, lock_in_thread); } @@ -1749,12 +1773,10 @@ ostree_sysroot_lock_async (OstreeSysroot *self, * Call when ostree_sysroot_lock_async() is ready. */ gboolean -ostree_sysroot_lock_finish (OstreeSysroot *self, - GAsyncResult *result, - GError **error) +ostree_sysroot_lock_finish (OstreeSysroot *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), FALSE); - return g_task_propagate_boolean ((GTask*)result, error); + return g_task_propagate_boolean ((GTask *)result, error); } /** @@ -1771,10 +1793,8 @@ ostree_sysroot_lock_finish (OstreeSysroot *self, * Since: 2016.4 */ gboolean -ostree_sysroot_init_osname (OstreeSysroot *self, - const char *osname, - GCancellable *cancellable, - GError **error) +ostree_sysroot_init_osname (OstreeSysroot *self, const char *osname, GCancellable *cancellable, + GError **error) { if (!_ostree_sysroot_ensure_writable (self, error)) return FALSE; @@ -1855,33 +1875,29 @@ ostree_sysroot_init_osname (OstreeSysroot *self, * later, instead. */ gboolean -ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, - const char *osname, - OstreeDeployment *new_deployment, - OstreeDeployment *merge_deployment, +ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, const char *osname, + OstreeDeployment *new_deployment, + OstreeDeployment *merge_deployment, OstreeSysrootSimpleWriteDeploymentFlags flags, - GCancellable *cancellable, - GError **error) -{ - const gboolean postclean = - (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN) == 0; - const gboolean make_default = - !((flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT) > 0); - const gboolean retain_pending = - (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING) > 0; - const gboolean retain_rollback = - (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK) > 0; - gboolean retain = - (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN) > 0; - - g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot); + GCancellable *cancellable, GError **error) +{ + const gboolean postclean = (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN) == 0; + const gboolean make_default + = !((flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT) > 0); + const gboolean retain_pending + = (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING) > 0; + const gboolean retain_rollback + = (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK) > 0; + gboolean retain = (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN) > 0; + + g_autoptr (GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot); OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (sysroot); if (osname == NULL && booted_deployment) osname = ostree_deployment_get_osname (booted_deployment); gboolean added_new = FALSE; - g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref); + g_autoptr (GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref); if (make_default) { g_ptr_array_add (new_deployments, g_object_ref (new_deployment)); @@ -1900,8 +1916,8 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, for (guint i = 0; i < deployments->len; i++) { OstreeDeployment *deployment = deployments->pdata[i]; - const gboolean osname_matches = - (osname == NULL || g_str_equal (ostree_deployment_get_osname (deployment), osname)); + const gboolean osname_matches + = (osname == NULL || g_str_equal (ostree_deployment_get_osname (deployment), osname)); const gboolean is_booted = ostree_deployment_equal (deployment, booted_deployment); const gboolean is_merge = ostree_deployment_equal (deployment, merge_deployment); @@ -1922,11 +1938,8 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, * - this is the merge or boot deployment, or * - we're keeping rollback deployments and this is a rollback deployment */ - if (retain - || ostree_deployment_is_pinned (deployment) - || !osname_matches - || (retain_pending && !passed_crossover) - || (is_booted || is_merge) + if (retain || ostree_deployment_is_pinned (deployment) || !osname_matches + || (retain_pending && !passed_crossover) || (is_booted || is_merge) || (retain_rollback && passed_crossover)) g_ptr_array_add (new_deployments, g_object_ref (deployment)); @@ -1952,11 +1965,8 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, /* Deploy a copy of @target_deployment */ static gboolean -clone_deployment (OstreeSysroot *sysroot, - OstreeDeployment *target_deployment, - OstreeDeployment *merge_deployment, - GCancellable *cancellable, - GError **error) +clone_deployment (OstreeSysroot *sysroot, OstreeDeployment *target_deployment, + OstreeDeployment *merge_deployment, GCancellable *cancellable, GError **error) { /* Ensure we have a clean slate */ if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error)) @@ -1964,28 +1974,28 @@ clone_deployment (OstreeSysroot *sysroot, /* Copy the bootloader config options */ OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment); - g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); - g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_new (); + g_auto (GStrv) previous_args + = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); + g_autoptr (OstreeKernelArgs) kargs = ostree_kernel_args_new (); ostree_kernel_args_append_argv (kargs, previous_args); /* Deploy the copy */ - g_autoptr(OstreeDeployment) new_deployment = NULL; - g_auto(GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs); - if (!ostree_sysroot_deploy_tree (sysroot, - ostree_deployment_get_osname (target_deployment), + g_autoptr (OstreeDeployment) new_deployment = NULL; + g_auto (GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs); + if (!ostree_sysroot_deploy_tree (sysroot, ostree_deployment_get_osname (target_deployment), ostree_deployment_get_csum (target_deployment), ostree_deployment_get_origin (target_deployment), - merge_deployment, kargs_strv, &new_deployment, - cancellable, error)) + merge_deployment, kargs_strv, &new_deployment, cancellable, + error)) return FALSE; /* Hotfixes push the deployment as rollback target, so it shouldn't * be the default. */ - if (!ostree_sysroot_simple_write_deployment (sysroot, ostree_deployment_get_osname (target_deployment), - new_deployment, merge_deployment, - OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT, - cancellable, error)) + if (!ostree_sysroot_simple_write_deployment ( + sysroot, ostree_deployment_get_osname (target_deployment), new_deployment, + merge_deployment, OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT, cancellable, + error)) return FALSE; return TRUE; @@ -1994,11 +2004,8 @@ clone_deployment (OstreeSysroot *sysroot, /* Do `mkdir()` followed by `chmod()` immediately afterwards to ensure `umask()` isn't * masking permissions where we don't want it to. Thus we avoid calling `umask()`, which * would affect the whole process. */ -static gboolean mkdir_unmasked (int dfd, - const char *path, - int mode, - GCancellable *cancellable, - GError **error) +static gboolean +mkdir_unmasked (int dfd, const char *path, int mode, GCancellable *cancellable, GError **error) { if (!glnx_shutil_mkdir_p_at (dfd, path, mode, cancellable, error)) return FALSE; @@ -2025,11 +2032,9 @@ static gboolean mkdir_unmasked (int dfd, * Since: 2016.4 */ gboolean -ostree_sysroot_deployment_unlock (OstreeSysroot *self, - OstreeDeployment *deployment, +ostree_sysroot_deployment_unlock (OstreeSysroot *self, OstreeDeployment *deployment, OstreeDeploymentUnlockedState unlocked_state, - GCancellable *cancellable, - GError **error) + GCancellable *cancellable, GError **error) { /* This function cannot re-lock */ g_return_val_if_fail (unlocked_state != OSTREE_DEPLOYMENT_UNLOCKED_NONE, FALSE); @@ -2039,8 +2044,8 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, return glnx_throw (error, "Deployment is already in unlocked state: %s", ostree_deployment_unlocked_state_to_string (current_unlocked)); - g_autoptr(OstreeDeployment) merge_deployment = - ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment)); + g_autoptr (OstreeDeployment) merge_deployment + = ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment)); if (!merge_deployment) return glnx_throw (error, "No previous deployment to duplicate"); @@ -2052,8 +2057,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, } /* Crack it open */ - if (!ostree_sysroot_deployment_set_mutable (self, deployment, TRUE, - cancellable, error)) + if (!ostree_sysroot_deployment_set_mutable (self, deployment, TRUE, cancellable, error)) return FALSE; g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); @@ -2061,20 +2065,22 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error)) return FALSE; - g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); + g_autoptr (OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); if (!sepolicy) return FALSE; /* we want our /usr overlay to have the same permission bits as the one we'll shadow */ mode_t usr_mode; - { struct stat stbuf; + { + struct stat stbuf; if (!glnx_fstatat (deployment_dfd, "usr", &stbuf, 0, error)) return FALSE; usr_mode = stbuf.st_mode; } const char *ovl_options = NULL; - static const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; + static const char hotfix_ovl_options[] + = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; g_autofree char *unlock_ovldir = NULL; switch (unlocked_state) @@ -2106,10 +2112,12 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, const char *development_ovl_work; /* Ensure that the directory is created with the same label as `/usr` */ - { g_auto(OstreeSepolicyFsCreatecon) con = { 0, }; + { + g_auto (OstreeSepolicyFsCreatecon) con = { + 0, + }; - if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, - "/usr", usr_mode, error)) + if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, "/usr", usr_mode, error)) return FALSE; if (g_mkdtemp_full (unlock_ovldir, 0755) == NULL) @@ -2168,7 +2176,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, } } - g_autoptr(OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment); + g_autoptr (OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment); GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone); /* Now, write out the flag saying what we did */ @@ -2180,18 +2188,18 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX: g_key_file_set_string (origin_clone, "origin", "unlocked", ostree_deployment_unlocked_state_to_string (unlocked_state)); - if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone, - cancellable, error)) + if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone, cancellable, error)) return FALSE; break; case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT: case OSTREE_DEPLOYMENT_UNLOCKED_TRANSIENT: { - g_autofree char *devpath = - unlocked_state == OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT ? - _ostree_sysroot_get_runstate_path (deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT) - : - _ostree_sysroot_get_runstate_path (deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_TRANSIENT); + g_autofree char *devpath + = unlocked_state == OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT + ? _ostree_sysroot_get_runstate_path ( + deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT) + : _ostree_sysroot_get_runstate_path ( + deployment, _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_TRANSIENT); g_autofree char *devpath_parent = dirname (g_strdup (devpath)); if (!glnx_shutil_mkdir_p_at (AT_FDCWD, devpath_parent, 0755, cancellable, error)) @@ -2233,10 +2241,8 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, * Since: 2018.3 */ gboolean -ostree_sysroot_deployment_set_pinned (OstreeSysroot *self, - OstreeDeployment *deployment, - gboolean is_pinned, - GError **error) +ostree_sysroot_deployment_set_pinned (OstreeSysroot *self, OstreeDeployment *deployment, + gboolean is_pinned, GError **error) { const gboolean current_pin = ostree_deployment_is_pinned (deployment); if (is_pinned == current_pin) @@ -2245,7 +2251,7 @@ ostree_sysroot_deployment_set_pinned (OstreeSysroot *self, if (ostree_deployment_is_staged (deployment)) return glnx_throw (error, "Cannot pin staged deployment"); - g_autoptr(OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment); + g_autoptr (OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment); GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone); if (is_pinned) diff --git a/src/libostree/ostree-sysroot.h b/src/libostree/ostree-sysroot.h index c240aaa..e84007a 100644 --- a/src/libostree/ostree-sysroot.h +++ b/src/libostree/ostree-sysroot.h @@ -19,8 +19,8 @@ #pragma once -#include "ostree-repo.h" #include "ostree-deployment.h" +#include "ostree-repo.h" G_BEGIN_DECLS @@ -32,23 +32,25 @@ G_BEGIN_DECLS */ #define OSTREE_PATH_BOOTED "/run/ostree-booted" -#define OSTREE_TYPE_SYSROOT ostree_sysroot_get_type() -#define OSTREE_SYSROOT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_SYSROOT, OstreeSysroot)) -#define OSTREE_IS_SYSROOT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_SYSROOT)) +#define OSTREE_TYPE_SYSROOT ostree_sysroot_get_type () +#define OSTREE_SYSROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_SYSROOT, OstreeSysroot)) +#define OSTREE_IS_SYSROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_SYSROOT)) _OSTREE_PUBLIC GType ostree_sysroot_get_type (void); _OSTREE_PUBLIC -OstreeSysroot* ostree_sysroot_new (GFile *path); +OstreeSysroot *ostree_sysroot_new (GFile *path); + +_OSTREE_PUBLIC +OstreeSysroot *ostree_sysroot_new_default (void); _OSTREE_PUBLIC -OstreeSysroot* ostree_sysroot_new_default (void); +void ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self); _OSTREE_PUBLIC -void ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self); +gboolean ostree_sysroot_initialize_with_mount_namespace (OstreeSysroot *self, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC GFile *ostree_sysroot_get_path (OstreeSysroot *self); @@ -60,149 +62,122 @@ _OSTREE_PUBLIC int ostree_sysroot_get_fd (OstreeSysroot *self); _OSTREE_PUBLIC -gboolean ostree_sysroot_initialize (OstreeSysroot *self, - GError **error); +gboolean ostree_sysroot_initialize (OstreeSysroot *self, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_load (OstreeSysroot *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_load (OstreeSysroot *self, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_load_if_changed (OstreeSysroot *self, - gboolean *out_changed, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_load_if_changed (OstreeSysroot *self, gboolean *out_changed, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -void ostree_sysroot_unload (OstreeSysroot *self); +void ostree_sysroot_unload (OstreeSysroot *self); _OSTREE_PUBLIC -gboolean ostree_sysroot_ensure_initialized (OstreeSysroot *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_ensure_initialized (OstreeSysroot *self, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -int ostree_sysroot_get_bootversion (OstreeSysroot *self); +int ostree_sysroot_get_bootversion (OstreeSysroot *self); _OSTREE_PUBLIC -int ostree_sysroot_get_subbootversion (OstreeSysroot *self); +int ostree_sysroot_get_subbootversion (OstreeSysroot *self); _OSTREE_PUBLIC -GPtrArray *ostree_sysroot_get_deployments (OstreeSysroot *self); +GPtrArray *ostree_sysroot_get_deployments (OstreeSysroot *self); _OSTREE_PUBLIC OstreeDeployment *ostree_sysroot_get_booted_deployment (OstreeSysroot *self); _OSTREE_PUBLIC -OstreeDeployment * -ostree_sysroot_require_booted_deployment (OstreeSysroot *self, GError **error); +OstreeDeployment *ostree_sysroot_require_booted_deployment (OstreeSysroot *self, GError **error); _OSTREE_PUBLIC OstreeDeployment *ostree_sysroot_get_staged_deployment (OstreeSysroot *self); _OSTREE_PUBLIC -GFile *ostree_sysroot_get_deployment_directory (OstreeSysroot *self, - OstreeDeployment *deployment); +GFile *ostree_sysroot_get_deployment_directory (OstreeSysroot *self, OstreeDeployment *deployment); _OSTREE_PUBLIC -char *ostree_sysroot_get_deployment_dirpath (OstreeSysroot *self, - OstreeDeployment *deployment); +char *ostree_sysroot_get_deployment_dirpath (OstreeSysroot *self, OstreeDeployment *deployment); _OSTREE_PUBLIC -GFile * ostree_sysroot_get_deployment_origin_path (GFile *deployment_path); +GFile *ostree_sysroot_get_deployment_origin_path (GFile *deployment_path); _OSTREE_PUBLIC -gboolean ostree_sysroot_lock (OstreeSysroot *self, GError **error); +gboolean ostree_sysroot_lock (OstreeSysroot *self, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_try_lock (OstreeSysroot *self, - gboolean *out_acquired, - GError **error); +gboolean ostree_sysroot_try_lock (OstreeSysroot *self, gboolean *out_acquired, GError **error); _OSTREE_PUBLIC -void ostree_sysroot_lock_async (OstreeSysroot *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +void ostree_sysroot_lock_async (OstreeSysroot *self, GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); _OSTREE_PUBLIC -gboolean ostree_sysroot_lock_finish (OstreeSysroot *self, - GAsyncResult *result, - GError **error); +gboolean ostree_sysroot_lock_finish (OstreeSysroot *self, GAsyncResult *result, GError **error); _OSTREE_PUBLIC -void ostree_sysroot_unlock (OstreeSysroot *self); +void ostree_sysroot_unlock (OstreeSysroot *self); _OSTREE_PUBLIC -gboolean ostree_sysroot_init_osname (OstreeSysroot *self, - const char *osname, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_init_osname (OstreeSysroot *self, const char *osname, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_cleanup (OstreeSysroot *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_cleanup (OstreeSysroot *self, GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_prepare_cleanup (OstreeSysroot *self, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_prepare_cleanup (OstreeSysroot *self, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean -ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, - OstreeRepoPruneOptions *options, - gint *out_objects_total, - gint *out_objects_pruned, - guint64 *out_pruned_object_size_total, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, OstreeRepoPruneOptions *options, + gint *out_objects_total, gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_write_origin_file (OstreeSysroot *sysroot, - OstreeDeployment *deployment, - GKeyFile *new_origin, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_write_origin_file (OstreeSysroot *sysroot, OstreeDeployment *deployment, + GKeyFile *new_origin, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -OstreeRepo * ostree_sysroot_repo (OstreeSysroot *self); +OstreeRepo *ostree_sysroot_repo (OstreeSysroot *self); _OSTREE_PUBLIC -gboolean ostree_sysroot_get_repo (OstreeSysroot *self, - OstreeRepo **out_repo, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_get_repo (OstreeSysroot *self, OstreeRepo **out_repo, + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, - OstreeDeployment *deployment, - char **new_kargs, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, OstreeDeployment *deployment, + char **new_kargs, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_write_deployments (OstreeSysroot *self, - GPtrArray *new_deployments, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_deployment_set_kargs_in_place (OstreeSysroot *self, + OstreeDeployment *deployment, + char *kargs_str, GCancellable *cancellable, + GError **error); -typedef struct { +_OSTREE_PUBLIC +gboolean ostree_sysroot_write_deployments (OstreeSysroot *self, GPtrArray *new_deployments, + GCancellable *cancellable, GError **error); + +typedef struct +{ gboolean do_postclean; + gboolean disable_auto_early_prune; gboolean unused_bools[7]; int unused_ints[7]; gpointer unused_ptrs[7]; } OstreeSysrootWriteDeploymentsOpts; _OSTREE_PUBLIC -gboolean ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, - GPtrArray *new_deployments, +gboolean ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, + GPtrArray *new_deployments, OstreeSysrootWriteDeploymentsOpts *opts, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self, - int fd, - char **out_checksum, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self, int fd, char **out_checksum, + GCancellable *cancellable, GError **error); -typedef struct { +typedef struct +{ gboolean unused_bools[8]; int unused_ints[8]; char **override_kernel_argv; @@ -211,86 +186,62 @@ typedef struct { } OstreeSysrootDeployTreeOpts; _OSTREE_PUBLIC -gboolean ostree_sysroot_deploy_tree (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *provided_merge_deployment, - char **override_kernel_argv, +gboolean ostree_sysroot_deploy_tree (OstreeSysroot *self, const char *osname, const char *revision, + GKeyFile *origin, OstreeDeployment *provided_merge_deployment, + char **override_kernel_argv, OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_deploy_tree_with_options (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *provided_merge_deployment, +gboolean ostree_sysroot_deploy_tree_with_options (OstreeSysroot *self, const char *osname, + const char *revision, GKeyFile *origin, + OstreeDeployment *provided_merge_deployment, OstreeSysrootDeployTreeOpts *opts, OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_stage_tree (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *merge_deployment, - char **override_kernel_argv, +gboolean ostree_sysroot_stage_tree (OstreeSysroot *self, const char *osname, const char *revision, + GKeyFile *origin, OstreeDeployment *merge_deployment, + char **override_kernel_argv, OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, - const char *osname, - const char *revision, - GKeyFile *origin, - OstreeDeployment *merge_deployment, +gboolean ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, const char *osname, + const char *revision, GKeyFile *origin, + OstreeDeployment *merge_deployment, OstreeSysrootDeployTreeOpts *opts, OstreeDeployment **out_new_deployment, - GCancellable *cancellable, - GError **error); - + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_deployment_set_mutable (OstreeSysroot *self, - OstreeDeployment *deployment, - gboolean is_mutable, - GCancellable *cancellable, - GError **error); +gboolean ostree_sysroot_deployment_set_mutable (OstreeSysroot *self, OstreeDeployment *deployment, + gboolean is_mutable, GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_deployment_set_pinned (OstreeSysroot *self, - OstreeDeployment *deployment, - gboolean is_pinned, - GError **error); +gboolean ostree_sysroot_deployment_set_pinned (OstreeSysroot *self, OstreeDeployment *deployment, + gboolean is_pinned, GError **error); _OSTREE_PUBLIC -gboolean ostree_sysroot_deployment_unlock (OstreeSysroot *self, - OstreeDeployment *deployment, +gboolean ostree_sysroot_deployment_unlock (OstreeSysroot *self, OstreeDeployment *deployment, OstreeDeploymentUnlockedState unlocked_state, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); _OSTREE_PUBLIC -void ostree_sysroot_query_deployments_for (OstreeSysroot *self, - const char *osname, - OstreeDeployment **out_pending, - OstreeDeployment **out_rollback); +void ostree_sysroot_query_deployments_for (OstreeSysroot *self, const char *osname, + OstreeDeployment **out_pending, + OstreeDeployment **out_rollback); _OSTREE_PUBLIC -OstreeDeployment *ostree_sysroot_get_merge_deployment (OstreeSysroot *self, - const char *osname); - +OstreeDeployment *ostree_sysroot_get_merge_deployment (OstreeSysroot *self, const char *osname); _OSTREE_PUBLIC -GKeyFile *ostree_sysroot_origin_new_from_refspec (OstreeSysroot *self, - const char *refspec); +GKeyFile *ostree_sysroot_origin_new_from_refspec (OstreeSysroot *self, const char *refspec); -typedef enum { +typedef enum +{ OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NONE = 0, OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN = (1 << 0), OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT = (1 << 1), @@ -300,12 +251,10 @@ typedef enum { } OstreeSysrootSimpleWriteDeploymentFlags; _OSTREE_PUBLIC -gboolean ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, - const char *osname, - OstreeDeployment *new_deployment, - OstreeDeployment *merge_deployment, +gboolean ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, const char *osname, + OstreeDeployment *new_deployment, + OstreeDeployment *merge_deployment, OstreeSysrootSimpleWriteDeploymentFlags flags, - GCancellable *cancellable, - GError **error); + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/src/libostree/ostree-tls-cert-interaction-private.h b/src/libostree/ostree-tls-cert-interaction-private.h index 58db65a..0aca097 100644 --- a/src/libostree/ostree-tls-cert-interaction-private.h +++ b/src/libostree/ostree-tls-cert-interaction-private.h @@ -24,20 +24,25 @@ G_BEGIN_DECLS -#define OSTREE_TYPE_TLS_CERT_INTERACTION (_ostree_tls_cert_interaction_get_type ()) -#define OSTREE_TLS_CERT_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteraction)) -#define OSTREE_TLS_CERT_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteractionClass)) -#define OSTREE_IS_TLS_CERT_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_TLS_CERT_INTERACTION)) -#define OSTREE_IS_TLS_CERT_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_TLS_CERT_INTERACTION)) -#define OSTREE_TLS_CERT_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteractionClass)) - -typedef struct _OstreeTlsCertInteraction OstreeTlsCertInteraction; -typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass; -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeTlsCertInteraction, g_object_unref) - -GType _ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST; - -OstreeTlsCertInteraction * _ostree_tls_cert_interaction_new (const char *cert_path, - const char *key_path); +#define OSTREE_TYPE_TLS_CERT_INTERACTION (_ostree_tls_cert_interaction_get_type ()) +#define OSTREE_TLS_CERT_INTERACTION(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteraction)) +#define OSTREE_TLS_CERT_INTERACTION_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteractionClass)) +#define OSTREE_IS_TLS_CERT_INTERACTION(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_TLS_CERT_INTERACTION)) +#define OSTREE_IS_TLS_CERT_INTERACTION_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_TLS_CERT_INTERACTION)) +#define OSTREE_TLS_CERT_INTERACTION_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteractionClass)) + +typedef struct _OstreeTlsCertInteraction OstreeTlsCertInteraction; +typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass; +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeTlsCertInteraction, g_object_unref) + +GType _ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST; + +OstreeTlsCertInteraction *_ostree_tls_cert_interaction_new (const char *cert_path, + const char *key_path); G_END_DECLS diff --git a/src/libostree/ostree-tls-cert-interaction.c b/src/libostree/ostree-tls-cert-interaction.c index 7614244..25d84ea 100644 --- a/src/libostree/ostree-tls-cert-interaction.c +++ b/src/libostree/ostree-tls-cert-interaction.c @@ -40,13 +40,10 @@ struct _OstreeTlsCertInteractionClass G_DEFINE_TYPE (OstreeTlsCertInteraction, _ostree_tls_cert_interaction, G_TYPE_TLS_INTERACTION); static GTlsInteractionResult -request_certificate (GTlsInteraction *interaction, - GTlsConnection *connection, - GTlsCertificateRequestFlags flags, - GCancellable *cancellable, - GError **error) +request_certificate (GTlsInteraction *interaction, GTlsConnection *connection, + GTlsCertificateRequestFlags flags, GCancellable *cancellable, GError **error) { - OstreeTlsCertInteraction *self = (OstreeTlsCertInteraction*)interaction; + OstreeTlsCertInteraction *self = (OstreeTlsCertInteraction *)interaction; if (!self->cert) { @@ -72,8 +69,7 @@ _ostree_tls_cert_interaction_class_init (OstreeTlsCertInteractionClass *klass) } OstreeTlsCertInteraction * -_ostree_tls_cert_interaction_new (const char *cert_path, - const char *key_path) +_ostree_tls_cert_interaction_new (const char *cert_path, const char *key_path) { OstreeTlsCertInteraction *self = g_object_new (OSTREE_TYPE_TLS_CERT_INTERACTION, NULL); self->cert_path = g_strdup (cert_path); diff --git a/src/libostree/ostree-varint.c b/src/libostree/ostree-varint.c index 26b5d46..fd7c81f 100644 --- a/src/libostree/ostree-varint.c +++ b/src/libostree/ostree-varint.c @@ -49,7 +49,7 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ #include "config.h" @@ -67,15 +67,12 @@ static const int max_varint_bytes = 10; * Returns: %TRUE on success, %FALSE on end of stream */ gboolean -_ostree_read_varuint64 (const guint8 *buf, - gsize buflen, - guint64 *out_value, - gsize *bytes_read) +_ostree_read_varuint64 (const guint8 *buf, gsize buflen, guint64 *out_value, gsize *bytes_read) { guint64 result = 0; int count = 0; guint8 b; - + /* Adapted from CodedInputStream::ReadVarint64Slow */ do @@ -90,7 +87,8 @@ _ostree_read_varuint64 (const guint8 *buf, buf++; buflen--; ++count; - } while (b & 0x80); + } + while (b & 0x80); *bytes_read = count; *out_value = result; @@ -126,58 +124,105 @@ _ostree_write_varuint64 (GString *buf, guint64 n) * we probably don't want to optimize for small numbers anyway. Thus, * we end up with a hardcoded binary search tree... */ - if (part2 == 0) { - if (part1 == 0) { - if (part0 < (1 << 14)) { - if (part0 < (1 << 7)) { - size = 1; goto size1; - } else { - size = 2; goto size2; + if (part2 == 0) + { + if (part1 == 0) + { + if (part0 < (1 << 14)) + { + if (part0 < (1 << 7)) + { + size = 1; + goto size1; + } + else + { + size = 2; + goto size2; + } + } + else + { + if (part0 < (1 << 21)) + { + size = 3; + goto size3; + } + else + { + size = 4; + goto size4; + } + } } - } else { - if (part0 < (1 << 21)) { - size = 3; goto size3; - } else { - size = 4; goto size4; + else + { + if (part1 < (1 << 14)) + { + if (part1 < (1 << 7)) + { + size = 5; + goto size5; + } + else + { + size = 6; + goto size6; + } + } + else + { + if (part1 < (1 << 21)) + { + size = 7; + goto size7; + } + else + { + size = 8; + goto size8; + } + } } - } - } else { - if (part1 < (1 << 14)) { - if (part1 < (1 << 7)) { - size = 5; goto size5; - } else { - size = 6; goto size6; + } + else + { + if (part2 < (1 << 7)) + { + size = 9; + goto size9; } - } else { - if (part1 < (1 << 21)) { - size = 7; goto size7; - } else { - size = 8; goto size8; + else + { + size = 10; + goto size10; } - } - } - } else { - if (part2 < (1 << 7)) { - size = 9; goto size9; - } else { - size = 10; goto size10; } - } g_assert_not_reached (); - size10: target[9] = (guint8)((part2 >> 7) | 0x80); - size9 : target[8] = (guint8)((part2 ) | 0x80); - size8 : target[7] = (guint8)((part1 >> 21) | 0x80); - size7 : target[6] = (guint8)((part1 >> 14) | 0x80); - size6 : target[5] = (guint8)((part1 >> 7) | 0x80); - size5 : target[4] = (guint8)((part1 ) | 0x80); - size4 : target[3] = (guint8)((part0 >> 21) | 0x80); - size3 : target[2] = (guint8)((part0 >> 14) | 0x80); - size2 : target[1] = (guint8)((part0 >> 7) | 0x80); - size1 : target[0] = (guint8)((part0 ) | 0x80); - - target[size-1] &= 0x7F; +size10: + target[9] = (guint8)((part2 >> 7) | 0x80); +size9: + target[8] = (guint8)((part2) | 0x80); +size8: + target[7] = (guint8)((part1 >> 21) | 0x80); +size7: + target[6] = (guint8)((part1 >> 14) | 0x80); +size6: + target[5] = (guint8)((part1 >> 7) | 0x80); +size5: + target[4] = (guint8)((part1) | 0x80); +size4: + target[3] = (guint8)((part0 >> 21) | 0x80); +size3: + target[2] = (guint8)((part0 >> 14) | 0x80); +size2: + target[1] = (guint8)((part0 >> 7) | 0x80); +size1: + target[0] = (guint8)((part0) | 0x80); + + target[size - 1] &= 0x7F; for (i = 0; i < size; i++) g_string_append_c (buf, target[i]); diff --git a/src/libostree/ostree-varint.h b/src/libostree/ostree-varint.h index db23221..4783c78 100644 --- a/src/libostree/ostree-varint.h +++ b/src/libostree/ostree-varint.h @@ -23,10 +23,8 @@ G_BEGIN_DECLS -gboolean _ostree_read_varuint64 (const guint8 *buf, - gsize buflen, - guint64 *out_value, - gsize *bytes_read); +gboolean _ostree_read_varuint64 (const guint8 *buf, gsize buflen, guint64 *out_value, + gsize *bytes_read); void _ostree_write_varuint64 (GString *buf, guint64 n); diff --git a/src/libostree/ostree-version.h b/src/libostree/ostree-version.h index 7368706..7ef08d5 100644 --- a/src/libostree/ostree-version.h +++ b/src/libostree/ostree-version.h @@ -32,7 +32,7 @@ * * Since: 2017.4 */ -#define OSTREE_YEAR_VERSION (2022) +#define OSTREE_YEAR_VERSION (2023) /** * OSTREE_RELEASE_VERSION: @@ -41,7 +41,7 @@ * * Since: 2017.4 */ -#define OSTREE_RELEASE_VERSION (4) +#define OSTREE_RELEASE_VERSION (7) /** * OSTREE_VERSION @@ -50,7 +50,7 @@ * * Since: 2017.4 */ -#define OSTREE_VERSION (2022.4) +#define OSTREE_VERSION (2023.7) /** * OSTREE_VERSION_S: @@ -60,7 +60,7 @@ * * Since: 2017.4 */ -#define OSTREE_VERSION_S "2022.4" +#define OSTREE_VERSION_S "2023.7" #define OSTREE_ENCODE_VERSION(year,release) \ ((year) << 16 | (release)) @@ -99,5 +99,5 @@ * Since: 2019.3 */ #ifndef __GI_SCANNER__ -#define OSTREE_BUILT_FEATURES "libsoup gpgme ex-fsverity libarchive selinux libmount systemd release p2p" +#define OSTREE_BUILT_FEATURES "inode64 libsoup gpgme composefs ex-fsverity libarchive selinux libmount systemd release p2p" #endif diff --git a/src/libostree/ostree.h b/src/libostree/ostree.h index 8422823..6c52ba0 100644 --- a/src/libostree/ostree.h +++ b/src/libostree/ostree.h @@ -20,26 +20,28 @@ #pragma once #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include +#include +#include #include -#include +#include +#include #include #include #include #include -#include +#include +#include +#include #include -#include +#include +#include #include + +// Include after type definitions +#include diff --git a/src/libostree/s390x-se-luks-gencpio b/src/libostree/s390x-se-luks-gencpio deleted file mode 100755 index e821e2f..0000000 --- a/src/libostree/s390x-se-luks-gencpio +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# This script creates new initramdisk with LUKS config within -set -euo pipefail - -old_initrd=$1 -new_initrd=$2 -currdir=$PWD - -# Copying existing initramdisk -cp ${old_initrd} ${new_initrd} - -# Appending LUKS root keys and crypttab config to the end of initrd -workdir=$(mktemp -d -p /tmp se-initramfs-XXXXXX) -cd ${workdir} -mkdir -p etc/luks -cp -f /etc/luks/* etc/luks/ -cp -f /etc/crypttab etc/ -find . -mindepth 1 | cpio --quiet -H newc -o | gzip -9 -n >> ${new_initrd} - -# Cleanup -cd ${currdir} -rm -rf ${workdir} diff --git a/src/libotcore/otcore-ed25519-verify.c b/src/libotcore/otcore-ed25519-verify.c new file mode 100644 index 0000000..1c0ec2b --- /dev/null +++ b/src/libotcore/otcore-ed25519-verify.c @@ -0,0 +1,115 @@ +/* + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "otcore.h" + +/* Initialize global state; may be called multiple times and is idempotent. */ +bool +otcore_ed25519_init (void) +{ +#if defined(HAVE_LIBSODIUM) + static gssize initstate; + if (g_once_init_enter (&initstate)) + { + int val = sodium_init () >= 0 ? 1 : -1; + g_once_init_leave (&initstate, val); + } + switch (initstate) + { + case 1: + return true; + case -1: + return false; + default: + g_assert_not_reached (); + } +#else + return true; +#endif +} + +/* Validate a single ed25519 signature. If there is an unexpected state, such + * as an ill-forumed public key or signature, a hard error will be returned. + * + * If the signature is not correct, this function will return successfully, but + * `out_valid` will be set to `false`. + * + * If the signature is correct, `out_valid` will be `true`. + * */ +gboolean +otcore_validate_ed25519_signature (GBytes *data, GBytes *public_key, GBytes *signature, + bool *out_valid, GError **error) +{ + // Since this is signature verification code, let's verify preconditions. + g_assert (data); + g_assert (public_key); + g_assert (signature); + g_assert (out_valid); + // It is OK for error to be NULL, though according to GError rules. + +#if defined(HAVE_LIBSODIUM) || defined(HAVE_OPENSSL) + // And strictly verify pubkey and signature lengths + if (g_bytes_get_size (public_key) != OSTREE_SIGN_ED25519_PUBKEY_SIZE) + return glnx_throw (error, "Invalid public key of %" G_GSIZE_FORMAT " expected %" G_GSIZE_FORMAT, + (gsize)g_bytes_get_size (public_key), + (gsize)OSTREE_SIGN_ED25519_PUBKEY_SIZE); + const guint8 *public_key_buf = g_bytes_get_data (public_key, NULL); + if (g_bytes_get_size (signature) != OSTREE_SIGN_ED25519_SIG_SIZE) + return glnx_throw ( + error, "Invalid signature length of %" G_GSIZE_FORMAT " bytes, expected %" G_GSIZE_FORMAT, + (gsize)g_bytes_get_size (signature), (gsize)OSTREE_SIGN_ED25519_SIG_SIZE); + const guint8 *signature_buf = g_bytes_get_data (signature, NULL); + +#endif + +#if defined(HAVE_LIBSODIUM) + // Note that libsodium assumes the passed byte arrays for the signature and public key + // have at least the expected length, but we checked that above. + if (crypto_sign_verify_detached (signature_buf, g_bytes_get_data (data, NULL), + g_bytes_get_size (data), public_key_buf) + == 0) + { + *out_valid = true; + } + return TRUE; +#elif defined(HAVE_OPENSSL) + EVP_MD_CTX *ctx = EVP_MD_CTX_new (); + if (!ctx) + return glnx_throw (error, "openssl: failed to allocate context"); + EVP_PKEY *pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, public_key_buf, + OSTREE_SIGN_ED25519_PUBKEY_SIZE); + if (!pkey) + { + EVP_MD_CTX_free (ctx); + return glnx_throw (error, "openssl: Failed to initialize ed5519 key"); + } + if (EVP_DigestVerifyInit (ctx, NULL, NULL, NULL, pkey) != 0 + && EVP_DigestVerify (ctx, signature_buf, OSTREE_SIGN_ED25519_SIG_SIZE, + g_bytes_get_data (data, NULL), g_bytes_get_size (data)) + != 0) + { + *out_valid = true; + } + EVP_PKEY_free (pkey); + EVP_MD_CTX_free (ctx); + return TRUE; +#else + return glnx_throw (error, "ed25519 signature validation requested, but support not compiled in"); +#endif +} diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c new file mode 100644 index 0000000..f7523ef --- /dev/null +++ b/src/libotcore/otcore-prepare-root.c @@ -0,0 +1,139 @@ +/* + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "otcore.h" + +static bool +proc_cmdline_has_key_starting_with (const char *cmdline, const char *key) +{ + for (const char *iter = cmdline; iter;) + { + if (g_str_has_prefix (iter, key)) + return true; + + iter = strchr (iter, ' '); + if (iter == NULL) + return false; + + iter += strspn (iter, " "); + } + + return false; +} + +// Parse a kernel cmdline to find the provided key. +// TODO: Deduplicate this with the kernel argument code from libostree.so +char * +otcore_find_proc_cmdline_key (const char *cmdline, const char *key) +{ + const size_t key_len = strlen (key); + for (const char *iter = cmdline; iter;) + { + const char *next = strchr (iter, ' '); + if (strncmp (iter, key, key_len) == 0 && iter[key_len] == '=') + { + const char *start = iter + key_len + 1; + if (next) + return strndup (start, next - start); + + return strdup (start); + } + + if (next) + next += strspn (next, " "); + + iter = next; + } + + return NULL; +} + +// Find the target OSTree root filesystem from parsing the provided kernel commandline. +// If none is found, @out_target will be set to NULL, and the function will return successfully. +// +// If invalid data is found, @error will be set. +gboolean +otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error) +{ + g_assert (cmdline); + g_assert (out_target && *out_target == NULL); + static const char slot_a[] = "/ostree/root.a"; + static const char slot_b[] = "/ostree/root.b"; + + // First, handle the Android boot case + g_autofree char *slot_suffix = otcore_find_proc_cmdline_key (cmdline, "androidboot.slot_suffix"); + if (slot_suffix) + { + if (strcmp (slot_suffix, "_a") == 0) + { + *out_target = g_strdup (slot_a); + return TRUE; + } + else if (strcmp (slot_suffix, "_b") == 0) + { + *out_target = g_strdup (slot_b); + return TRUE; + } + return glnx_throw (error, "androidboot.slot_suffix invalid: %s", slot_suffix); + } + + /* Non-A/B androidboot: + * https://source.android.com/docs/core/ota/nonab + */ + if (proc_cmdline_has_key_starting_with (cmdline, "androidboot.")) + { + *out_target = g_strdup (slot_a); + return TRUE; + } + + // Otherwise, fall back to the default `ostree=` kernel cmdline + *out_target = otcore_find_proc_cmdline_key (cmdline, "ostree"); + return TRUE; +} + +// Load a config file; if it doesn't exist, we return an empty configuration. +// NULL will be returned if we caught an error. +GKeyFile * +otcore_load_config (int rootfs_fd, const char *filename, GError **error) +{ + // The path to the config file for this binary + static const char *const config_roots[] = { "usr/lib", "etc" }; + g_autoptr (GKeyFile) ret = g_key_file_new (); + + for (guint i = 0; i < G_N_ELEMENTS (config_roots); i++) + { + glnx_autofd int fd = -1; + g_autofree char *path = g_build_filename (config_roots[i], filename, NULL); + if (!ot_openat_ignore_enoent (rootfs_fd, path, &fd, error)) + return NULL; + /* If the config file doesn't exist, that's OK */ + if (fd == -1) + continue; + + g_print ("Loading %s\n", path); + + g_autofree char *buf = glnx_fd_readall_utf8 (fd, NULL, NULL, error); + if (!buf) + return NULL; + if (!g_key_file_load_from_data (ret, buf, -1, 0, error)) + return NULL; + } + + return g_steal_pointer (&ret); +} diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h new file mode 100644 index 0000000..1593e7b --- /dev/null +++ b/src/libotcore/otcore.h @@ -0,0 +1,76 @@ +/* + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#pragma once + +#include "config.h" + +#include "otutil.h" +#include + +#ifdef HAVE_LIBSODIUM +#include +#define USE_LIBSODIUM +#elif defined(HAVE_OPENSSL) +#include +#define USE_OPENSSL +#endif + +// Length of a signature in bytes +#define OSTREE_SIGN_ED25519_SIG_SIZE 64U +// Length of a public key in bytes +#define OSTREE_SIGN_ED25519_PUBKEY_SIZE 32U +// This key is stored inside commit metadata. +#define OSTREE_SIGN_METADATA_ED25519_KEY "ostree.sign.ed25519" +// The variant type +#define OSTREE_SIGN_METADATA_ED25519_TYPE "aay" + +bool otcore_ed25519_init (void); +gboolean otcore_validate_ed25519_signature (GBytes *data, GBytes *pubkey, GBytes *signature, + bool *out_valid, GError **error); + +char *otcore_find_proc_cmdline_key (const char *cmdline, const char *key); +gboolean otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error); + +GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error); + +// Our directory with transient state (eventually /run/ostree-booted should be a link to +// /run/ostree/booted) +#define OTCORE_RUN_OSTREE "/run/ostree" +// This sub-directory is transient state that should not be visible to other processes in general; +// we make it with mode 0 (which requires CAP_DAC_OVERRIDE to pass through). +#define OTCORE_RUN_OSTREE_PRIVATE "/run/ostree/.private" + +// The name of the composefs metadata root +#define OSTREE_COMPOSEFS_NAME ".ostree.cfs" +// The temporary directory used for the EROFS mount; it's in the .private directory +// to help ensure that at least unprivileged code can't transiently see the underlying +// EROFS mount if we somehow leaked it (but it *should* be unmounted always). +#define OSTREE_COMPOSEFS_LOWERMNT OTCORE_RUN_OSTREE_PRIVATE "/cfsroot-lower" + +// The file written in the initramfs which contains an a{sv} of metadata +// from ostree-prepare-root. +#define OTCORE_RUN_BOOTED "/run/ostree-booted" +// This key will be present if composefs was successfully used. +#define OTCORE_RUN_BOOTED_KEY_COMPOSEFS "composefs" +// This key if present contains the public key successfully used +// to verify the signature. +#define OTCORE_RUN_BOOTED_KEY_COMPOSEFS_SIGNATURE "composefs.signed" +// This key will be present if the sysroot-ro flag was found +#define OTCORE_RUN_BOOTED_KEY_SYSROOT_RO "sysroot-ro" + +#define OTCORE_RUN_BOOTED_KEY_TRANSIENT_ETC "transient-etc" diff --git a/src/libotutil/ot-checksum-instream.c b/src/libotutil/ot-checksum-instream.c index e89d68e..31286a5 100644 --- a/src/libotutil/ot-checksum-instream.c +++ b/src/libotutil/ot-checksum-instream.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2017 Colin Walters * Copyright (C) 2022 Igalia S.L. * @@ -23,22 +23,20 @@ #include "ot-checksum-instream.h" #include "ot-checksum-utils.h" -struct _OtChecksumInstreamPrivate { +struct _OtChecksumInstreamPrivate +{ OtChecksum checksum; }; G_DEFINE_TYPE_WITH_PRIVATE (OtChecksumInstream, ot_checksum_instream, G_TYPE_FILTER_INPUT_STREAM) -static gssize ot_checksum_instream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error); +static gssize ot_checksum_instream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error); static void ot_checksum_instream_finalize (GObject *object) { - OtChecksumInstream *self = (OtChecksumInstream*)object; + OtChecksumInstream *self = (OtChecksumInstream *)object; ot_checksum_clear (&self->priv->checksum); @@ -62,26 +60,21 @@ ot_checksum_instream_init (OtChecksumInstream *self) } OtChecksumInstream * -ot_checksum_instream_new (GInputStream *base, - GChecksumType checksum_type) +ot_checksum_instream_new (GInputStream *base, GChecksumType checksum_type) { return ot_checksum_instream_new_with_start (base, checksum_type, NULL, 0); } /* Initialize a checksum stream with starting state from data */ OtChecksumInstream * -ot_checksum_instream_new_with_start (GInputStream *base, - GChecksumType checksum_type, - const guint8 *buf, - size_t len) +ot_checksum_instream_new_with_start (GInputStream *base, GChecksumType checksum_type, + const guint8 *buf, size_t len) { OtChecksumInstream *stream; g_return_val_if_fail (G_IS_INPUT_STREAM (base), NULL); - stream = g_object_new (OT_TYPE_CHECKSUM_INSTREAM, - "base-stream", base, - NULL); + stream = g_object_new (OT_TYPE_CHECKSUM_INSTREAM, "base-stream", base, NULL); /* For now */ g_assert (checksum_type == G_CHECKSUM_SHA256); @@ -89,25 +82,18 @@ ot_checksum_instream_new_with_start (GInputStream *base, if (buf) ot_checksum_update (&stream->priv->checksum, buf, len); - return (OtChecksumInstream*) (stream); + return (OtChecksumInstream *)(stream); } static gssize -ot_checksum_instream_read (GInputStream *stream, - void *buffer, - gsize count, - GCancellable *cancellable, - GError **error) +ot_checksum_instream_read (GInputStream *stream, void *buffer, gsize count, + GCancellable *cancellable, GError **error) { - OtChecksumInstream *self = (OtChecksumInstream*) stream; - GFilterInputStream *fself = (GFilterInputStream*) self; + OtChecksumInstream *self = (OtChecksumInstream *)stream; + GFilterInputStream *fself = (GFilterInputStream *)self; gssize res = -1; - res = g_input_stream_read (fself->base_stream, - buffer, - count, - cancellable, - error); + res = g_input_stream_read (fself->base_stream, buffer, count, cancellable, error); if (res > 0) ot_checksum_update (&self->priv->checksum, buffer, res); @@ -117,7 +103,7 @@ ot_checksum_instream_read (GInputStream *stream, char * ot_checksum_instream_get_string (OtChecksumInstream *stream) { - char buf[_OSTREE_SHA256_STRING_LEN+1]; - ot_checksum_get_hexdigest (&stream->priv->checksum, buf, sizeof(buf)); - return g_strndup (buf, sizeof(buf)); + char buf[_OSTREE_SHA256_STRING_LEN + 1]; + ot_checksum_get_hexdigest (&stream->priv->checksum, buf, sizeof (buf)); + return g_strndup (buf, sizeof (buf)); } diff --git a/src/libotutil/ot-checksum-instream.h b/src/libotutil/ot-checksum-instream.h index 643e496..096d43c 100644 --- a/src/libotutil/ot-checksum-instream.h +++ b/src/libotutil/ot-checksum-instream.h @@ -24,16 +24,20 @@ G_BEGIN_DECLS -#define OT_TYPE_CHECKSUM_INSTREAM (ot_checksum_instream_get_type ()) -#define OT_CHECKSUM_INSTREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OT_TYPE_CHECKSUM_INPUT_STREAM, OtChecksumInstream)) -#define OT_CHECKSUM_INSTREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OT_TYPE_CHECKSUM_INPUT_STREAM, OtChecksumInstreamClass)) -#define OT_IS_CHECKSUM_INSTREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OT_TYPE_CHECKSUM_INPUT_STREAM)) -#define OT_IS_CHECKSUM_INSTREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OT_TYPE_CHECKSUM_INPUT_STREAM)) -#define OT_CHECKSUM_INSTREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OT_TYPE_CHECKSUM_INPUT_STREAM, OtChecksumInstreamClass)) +#define OT_TYPE_CHECKSUM_INSTREAM (ot_checksum_instream_get_type ()) +#define OT_CHECKSUM_INSTREAM(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), OT_TYPE_CHECKSUM_INPUT_STREAM, OtChecksumInstream)) +#define OT_CHECKSUM_INSTREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), OT_TYPE_CHECKSUM_INPUT_STREAM, OtChecksumInstreamClass)) +#define OT_IS_CHECKSUM_INSTREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OT_TYPE_CHECKSUM_INPUT_STREAM)) +#define OT_IS_CHECKSUM_INSTREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), OT_TYPE_CHECKSUM_INPUT_STREAM)) +#define OT_CHECKSUM_INSTREAM_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), OT_TYPE_CHECKSUM_INPUT_STREAM, OtChecksumInstreamClass)) -typedef struct _OtChecksumInstream OtChecksumInstream; -typedef struct _OtChecksumInstreamClass OtChecksumInstreamClass; -typedef struct _OtChecksumInstreamPrivate OtChecksumInstreamPrivate; +typedef struct _OtChecksumInstream OtChecksumInstream; +typedef struct _OtChecksumInstreamClass OtChecksumInstreamClass; +typedef struct _OtChecksumInstreamPrivate OtChecksumInstreamPrivate; struct _OtChecksumInstream { @@ -48,12 +52,13 @@ struct _OtChecksumInstreamClass GFilterInputStreamClass parent_class; }; -GType ot_checksum_instream_get_type (void) G_GNUC_CONST; +GType ot_checksum_instream_get_type (void) G_GNUC_CONST; -OtChecksumInstream * ot_checksum_instream_new (GInputStream *stream, GChecksumType checksum); -OtChecksumInstream * ot_checksum_instream_new_with_start (GInputStream *stream, GChecksumType checksum, - const guint8 *buf, size_t len); +OtChecksumInstream *ot_checksum_instream_new (GInputStream *stream, GChecksumType checksum); +OtChecksumInstream *ot_checksum_instream_new_with_start (GInputStream *stream, + GChecksumType checksum, const guint8 *buf, + size_t len); -char * ot_checksum_instream_get_string (OtChecksumInstream *stream); +char *ot_checksum_instream_get_string (OtChecksumInstream *stream); G_END_DECLS diff --git a/src/libotutil/ot-checksum-utils.c b/src/libotutil/ot-checksum-utils.c index df573f2..2fe7277 100644 --- a/src/libotutil/ot-checksum-utils.c +++ b/src/libotutil/ot-checksum-utils.c @@ -25,8 +25,8 @@ #if defined(HAVE_OPENSSL) #include #elif defined(HAVE_GNUTLS) -#include #include +#include #endif #include @@ -41,16 +41,18 @@ ot_bin2hex (char *out_buf, const guint8 *inbuf, gsize len) { guchar byte = inbuf[i]; out_buf[j] = hexchars[byte >> 4]; - out_buf[j+1] = hexchars[byte & 0xF]; + out_buf[j + 1] = hexchars[byte & 0xF]; } out_buf[j] = '\0'; } /* I like to think of this as AbstractChecksumProxyFactoryBean. In homage to * https://news.ycombinator.com/item?id=4549544 - * aka http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html + * aka + * http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html */ -typedef struct { +typedef struct +{ gboolean initialized; gboolean closed; #if defined(HAVE_OPENSSL) @@ -68,7 +70,7 @@ G_STATIC_ASSERT (sizeof (OtChecksum) >= sizeof (OtRealChecksum)); void ot_checksum_init (OtChecksum *checksum) { - OtRealChecksum *real = (OtRealChecksum*)checksum; + OtRealChecksum *real = (OtRealChecksum *)checksum; g_return_if_fail (!real->initialized); #if defined(HAVE_OPENSSL) real->checksum = EVP_MD_CTX_create (); @@ -88,11 +90,10 @@ ot_checksum_init (OtChecksum *checksum) } void -ot_checksum_update (OtChecksum *checksum, - const guint8 *buf, - size_t len) +ot_checksum_update (OtChecksum *checksum, const guint8 *buf, size_t len) { - OtRealChecksum *real = (OtRealChecksum*)checksum; + OtRealChecksum *real = (OtRealChecksum *)checksum; + g_assert (buf); g_return_if_fail (real->initialized); g_return_if_fail (!real->closed); #if defined(HAVE_OPENSSL) @@ -105,11 +106,10 @@ ot_checksum_update (OtChecksum *checksum, } static void -ot_checksum_get_digest_internal (OtRealChecksum *real, - guint8 *buf, - size_t buflen) +ot_checksum_get_digest_internal (OtRealChecksum *real, guint8 *buf, size_t buflen) { g_return_if_fail (real->initialized); + g_assert (buf); g_assert_cmpint (buflen, ==, _OSTREE_SHA256_DIGEST_LEN); #if defined(HAVE_OPENSSL) guint digest_len = buflen; @@ -125,31 +125,27 @@ ot_checksum_get_digest_internal (OtRealChecksum *real, } void -ot_checksum_get_digest (OtChecksum *checksum, - guint8 *buf, - size_t buflen) +ot_checksum_get_digest (OtChecksum *checksum, guint8 *buf, size_t buflen) { - OtRealChecksum *real = (OtRealChecksum*)checksum; + OtRealChecksum *real = (OtRealChecksum *)checksum; ot_checksum_get_digest_internal (real, buf, buflen); real->closed = TRUE; } void -ot_checksum_get_hexdigest (OtChecksum *checksum, - char *buf, - size_t buflen) +ot_checksum_get_hexdigest (OtChecksum *checksum, char *buf, size_t buflen) { - OtRealChecksum *real = (OtRealChecksum*)checksum; + OtRealChecksum *real = (OtRealChecksum *)checksum; const guint digest_len = real->digest_len; guint8 digest_buf[digest_len]; ot_checksum_get_digest (checksum, digest_buf, digest_len); - ot_bin2hex (buf, (guint8*)digest_buf, digest_len); + ot_bin2hex (buf, (guint8 *)digest_buf, digest_len); } void ot_checksum_clear (OtChecksum *checksum) { - OtRealChecksum *real = (OtRealChecksum*)checksum; + OtRealChecksum *real = (OtRealChecksum *)checksum; if (!real->initialized) return; #if defined(HAVE_OPENSSL) @@ -163,7 +159,7 @@ ot_checksum_clear (OtChecksum *checksum) } guchar * -ot_csum_from_gchecksum (GChecksum *checksum) +ot_csum_from_gchecksum (GChecksum *checksum) { guchar *ret = g_malloc (32); gsize len = 32; @@ -174,18 +170,13 @@ ot_csum_from_gchecksum (GChecksum *checksum) } gboolean -ot_gio_write_update_checksum (GOutputStream *out, - gconstpointer data, - gsize len, - gsize *out_bytes_written, - OtChecksum *checksum, - GCancellable *cancellable, - GError **error) +ot_gio_write_update_checksum (GOutputStream *out, gconstpointer data, gsize len, + gsize *out_bytes_written, OtChecksum *checksum, + GCancellable *cancellable, GError **error) { if (out) { - if (!g_output_stream_write_all (out, data, len, out_bytes_written, - cancellable, error)) + if (!g_output_stream_write_all (out, data, len, out_bytes_written, cancellable, error)) return FALSE; } else if (out_bytes_written) @@ -199,11 +190,8 @@ ot_gio_write_update_checksum (GOutputStream *out, } gboolean -ot_gio_splice_update_checksum (GOutputStream *out, - GInputStream *in, - OtChecksum *checksum, - GCancellable *cancellable, - GError **error) +ot_gio_splice_update_checksum (GOutputStream *out, GInputStream *in, OtChecksum *checksum, + GCancellable *cancellable, GError **error) { g_return_val_if_fail (out != NULL || checksum != NULL, FALSE); @@ -234,13 +222,12 @@ ot_gio_splice_update_checksum (GOutputStream *out, * all data read. */ gboolean -ot_gio_splice_get_checksum (GOutputStream *out, - GInputStream *in, - guchar **out_csum, - GCancellable *cancellable, - GError **error) +ot_gio_splice_get_checksum (GOutputStream *out, GInputStream *in, guchar **out_csum, + GCancellable *cancellable, GError **error) { - g_auto(OtChecksum) checksum = { 0, }; + g_auto (OtChecksum) checksum = { + 0, + }; ot_checksum_init (&checksum); if (!ot_gio_splice_update_checksum (out, in, &checksum, cancellable, error)) @@ -249,36 +236,36 @@ ot_gio_splice_get_checksum (GOutputStream *out, guint8 digest[_OSTREE_SHA256_DIGEST_LEN]; ot_checksum_get_digest (&checksum, digest, sizeof (digest)); if (out_csum) - *out_csum = g_memdup (digest, sizeof (digest)); + *out_csum = g_memdup2 (digest, sizeof (digest)); return TRUE; } char * -ot_checksum_file_at (int dfd, - const char *path, - GChecksumType checksum_type, - GCancellable *cancellable, - GError **error) +ot_checksum_file_at (int dfd, const char *path, GChecksumType checksum_type, + GCancellable *cancellable, GError **error) { - g_autoptr(GInputStream) in = NULL; + g_autoptr (GInputStream) in = NULL; if (!ot_openat_read_stream (dfd, path, TRUE, &in, cancellable, error)) return FALSE; - g_auto(OtChecksum) checksum = { 0, }; + g_auto (OtChecksum) checksum = { + 0, + }; ot_checksum_init (&checksum); if (!ot_gio_splice_update_checksum (NULL, in, &checksum, cancellable, error)) return FALSE; - char hexdigest[_OSTREE_SHA256_STRING_LEN+1]; + char hexdigest[_OSTREE_SHA256_STRING_LEN + 1]; ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest)); return g_strdup (hexdigest); } void -ot_checksum_bytes (GBytes *data, - guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN]) +ot_checksum_bytes (GBytes *data, guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN]) { - g_auto(OtChecksum) hasher = { 0, }; + g_auto (OtChecksum) hasher = { + 0, + }; ot_checksum_init (&hasher); ot_checksum_update_bytes (&hasher, data); ot_checksum_get_digest (&hasher, out_digest, _OSTREE_SHA256_DIGEST_LEN); diff --git a/src/libotutil/ot-checksum-utils.h b/src/libotutil/ot-checksum-utils.h index d1be20b..3ee66ce 100644 --- a/src/libotutil/ot-checksum-utils.h +++ b/src/libotutil/ot-checksum-utils.h @@ -29,7 +29,8 @@ void ot_bin2hex (char *out_buf, const guint8 *inbuf, gsize len); guchar *ot_csum_from_gchecksum (GChecksum *checksum); -struct OtChecksum { +struct OtChecksum +{ gboolean initialized; guint uints[2]; gpointer data[2]; @@ -48,53 +49,32 @@ typedef struct OtChecksum OtChecksum; #endif void ot_checksum_init (OtChecksum *checksum); -void ot_checksum_update (OtChecksum *checksum, - const guint8 *buf, - size_t len); +void ot_checksum_update (OtChecksum *checksum, const guint8 *buf, size_t len); static inline void -ot_checksum_update_bytes (OtChecksum *checksum, - GBytes *buf) +ot_checksum_update_bytes (OtChecksum *checksum, GBytes *buf) { gsize len; const guint8 *bufdata = g_bytes_get_data (buf, &len); ot_checksum_update (checksum, bufdata, len); } -void ot_checksum_get_digest (OtChecksum *checksum, - guint8 *buf, - size_t buflen); -void ot_checksum_get_hexdigest (OtChecksum *checksum, - char *buf, - size_t buflen); +void ot_checksum_get_digest (OtChecksum *checksum, guint8 *buf, size_t buflen); +void ot_checksum_get_hexdigest (OtChecksum *checksum, char *buf, size_t buflen); void ot_checksum_clear (OtChecksum *checksum); -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OtChecksum, ot_checksum_clear) +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OtChecksum, ot_checksum_clear) -gboolean ot_gio_write_update_checksum (GOutputStream *out, - gconstpointer data, - gsize len, - gsize *out_bytes_written, - OtChecksum *checksum, - GCancellable *cancellable, - GError **error); +gboolean ot_gio_write_update_checksum (GOutputStream *out, gconstpointer data, gsize len, + gsize *out_bytes_written, OtChecksum *checksum, + GCancellable *cancellable, GError **error); -gboolean ot_gio_splice_get_checksum (GOutputStream *out, - GInputStream *in, - guchar **out_csum, - GCancellable *cancellable, - GError **error); +gboolean ot_gio_splice_get_checksum (GOutputStream *out, GInputStream *in, guchar **out_csum, + GCancellable *cancellable, GError **error); -gboolean ot_gio_splice_update_checksum (GOutputStream *out, - GInputStream *in, - OtChecksum *checksum, - GCancellable *cancellable, - GError **error); +gboolean ot_gio_splice_update_checksum (GOutputStream *out, GInputStream *in, OtChecksum *checksum, + GCancellable *cancellable, GError **error); -char * ot_checksum_file_at (int dfd, - const char *path, - GChecksumType checksum_type, - GCancellable *cancellable, - GError **error); +char *ot_checksum_file_at (int dfd, const char *path, GChecksumType checksum_type, + GCancellable *cancellable, GError **error); -void ot_checksum_bytes (GBytes *data, - guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN]); +void ot_checksum_bytes (GBytes *data, guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN]); G_END_DECLS diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c index 5439c95..efbb2f2 100644 --- a/src/libotutil/ot-fs-utils.c +++ b/src/libotutil/ot-fs-utils.c @@ -19,12 +19,12 @@ #include "config.h" -#include "ot-fs-utils.h" #include "libglnx.h" -#include -#include +#include "ot-fs-utils.h" #include #include +#include +#include /* Convert a fd-relative path to a GFile* - use * for legacy code. @@ -40,13 +40,10 @@ ot_fdrel_to_gfile (int dfd, const char *path) * of @target_info. */ gboolean -ot_readlinkat_gfile_info (int dfd, - const char *path, - GFileInfo *target_info, - GCancellable *cancellable, - GError **error) +ot_readlinkat_gfile_info (int dfd, const char *path, GFileInfo *target_info, + GCancellable *cancellable, GError **error) { - char targetbuf[PATH_MAX+1]; + char targetbuf[PATH_MAX + 1]; ssize_t len; if (TEMP_FAILURE_RETRY (len = readlinkat (dfd, path, targetbuf, sizeof (targetbuf) - 1)) < 0) @@ -72,25 +69,19 @@ ot_readlinkat_gfile_info (int dfd, * symlink path components are always followed. */ gboolean -ot_openat_read_stream (int dfd, - const char *path, - gboolean follow, - GInputStream **out_istream, - GCancellable *cancellable, - GError **error) +ot_openat_read_stream (int dfd, const char *path, gboolean follow, GInputStream **out_istream, + GCancellable *cancellable, GError **error) { glnx_autofd int fd = -1; if (!glnx_openat_rdonly (dfd, path, follow, &fd, error)) return FALSE; - *out_istream = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE); + *out_istream = g_unix_input_stream_new (g_steal_fd (&fd), TRUE); return TRUE; } /* Like unlinkat() but ignore ENOENT */ gboolean -ot_ensure_unlinked_at (int dfd, - const char *path, - GError **error) +ot_ensure_unlinked_at (int dfd, const char *path, GError **error) { if (unlinkat (dfd, path, 0) != 0) { @@ -101,10 +92,7 @@ ot_ensure_unlinked_at (int dfd, } gboolean -ot_openat_ignore_enoent (int dfd, - const char *path, - int *out_fd, - GError **error) +ot_openat_ignore_enoent (int dfd, const char *path, int *out_fd, GError **error) { int target_fd = openat (dfd, path, O_CLOEXEC | O_RDONLY); if (target_fd < 0) @@ -121,11 +109,8 @@ ot_openat_ignore_enoent (int dfd, * @out_exists to %FALSE, and return successfully. */ gboolean -ot_dfd_iter_init_allow_noent (int dfd, - const char *path, - GLnxDirFdIterator *dfd_iter, - gboolean *out_exists, - GError **error) +ot_dfd_iter_init_allow_noent (int dfd, const char *path, GLnxDirFdIterator *dfd_iter, + gboolean *out_exists, GError **error) { glnx_autofd int fd = glnx_opendirat_with_errno (dfd, path, TRUE); if (fd < 0) @@ -141,7 +126,8 @@ ot_dfd_iter_init_allow_noent (int dfd, return TRUE; } -typedef struct { +typedef struct +{ gpointer addr; gsize len; } MapData; @@ -150,7 +136,7 @@ static void map_data_destroy (gpointer data) { MapData *mdata = data; - (void) munmap (mdata->addr, mdata->len); + (void)munmap (mdata->addr, mdata->len); g_free (mdata); } @@ -158,9 +144,7 @@ map_data_destroy (gpointer data) * starting at offset @start. If the file is large enough, mmap() may be used. */ GBytes * -ot_fd_readall_or_mmap (int fd, - goffset start, - GError **error) +ot_fd_readall_or_mmap (int fd, goffset start, GError **error) { struct stat stbuf; if (!glnx_fstat (fd, &stbuf, error)) @@ -170,14 +154,14 @@ ot_fd_readall_or_mmap (int fd, if (start > stbuf.st_size) return g_bytes_new_static (NULL, 0); const gsize len = stbuf.st_size - start; - if (len > 16*1024) + if (len > 16 * 1024) { /* The reason we don't use g_mapped_file_new_from_fd() here * is it doesn't support passing an offset, which is actually * used by the static delta code. */ gpointer map = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, start); - if (map == (void*)-1) + if (map == (void *)-1) return glnx_null_throw_errno_prefix (error, "mmap"); MapData *mdata = g_new (MapData, 1); @@ -198,41 +182,38 @@ ot_fd_readall_or_mmap (int fd, * Useful for potentially large but transient files. */ GBytes * -ot_map_anonymous_tmpfile_from_content (GInputStream *instream, - GCancellable *cancellable, - GError **error) +ot_map_anonymous_tmpfile_from_content (GInputStream *instream, GCancellable *cancellable, + GError **error) { - g_auto(GLnxTmpfile) tmpf = { 0, }; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &tmpf, error)) return NULL; - g_autoptr(GOutputStream) out = g_unix_output_stream_new (tmpf.fd, FALSE); - gssize n_bytes_written = g_output_stream_splice (out, instream, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - cancellable, error); + g_autoptr (GOutputStream) out = g_unix_output_stream_new (tmpf.fd, FALSE); + gssize n_bytes_written = g_output_stream_splice ( + out, instream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + cancellable, error); if (n_bytes_written < 0) return NULL; - g_autoptr(GMappedFile) mfile = g_mapped_file_new_from_fd (tmpf.fd, FALSE, error); + g_autoptr (GMappedFile) mfile = g_mapped_file_new_from_fd (tmpf.fd, FALSE, error); if (!mfile) return NULL; return g_mapped_file_get_bytes (mfile); } gboolean -ot_parse_file_by_line (const char *path, - gboolean (*cb)(const char*, void*, GError**), - void *cbdata, - GCancellable *cancellable, - GError **error) +ot_parse_file_by_line (const char *path, gboolean (*cb) (const char *, void *, GError **), + void *cbdata, GCancellable *cancellable, GError **error) { - g_autofree char *contents = - glnx_file_get_contents_utf8_at (AT_FDCWD, path, NULL, cancellable, error); + g_autofree char *contents + = glnx_file_get_contents_utf8_at (AT_FDCWD, path, NULL, cancellable, error); if (!contents) return FALSE; - g_auto(GStrv) lines = g_strsplit (contents, "\n", -1); + g_auto (GStrv) lines = g_strsplit (contents, "\n", -1); for (char **iter = lines; iter && *iter; iter++) { /* skip empty lines at least */ @@ -245,3 +226,46 @@ ot_parse_file_by_line (const char *path, return TRUE; } + +/* Calculate the size of the files contained in a directory. Symlinks are not + * followed. */ +gboolean +ot_get_dir_size (int dfd, const char *path, guint64 *out_size, GCancellable *cancellable, + GError **error) +{ + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error)) + return FALSE; + + *out_size = 0; + while (TRUE) + { + struct dirent *dent; + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) + return FALSE; + + if (dent == NULL) + break; + + if (dent->d_type == DT_REG) + { + struct stat stbuf; + if (!glnx_fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return FALSE; + + *out_size += stbuf.st_size; + } + else if (dent->d_type == DT_DIR) + { + guint64 subdir_size; + if (!ot_get_dir_size (dfd_iter.fd, dent->d_name, &subdir_size, cancellable, error)) + return FALSE; + + *out_size += subdir_size; + } + } + + return TRUE; +} diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h index fad4c53..b64adce 100644 --- a/src/libotutil/ot-fs-utils.h +++ b/src/libotutil/ot-fs-utils.h @@ -19,8 +19,8 @@ #pragma once -#include "ot-unix-utils.h" #include "libglnx.h" +#include "ot-unix-utils.h" G_BEGIN_DECLS @@ -28,7 +28,8 @@ G_BEGIN_DECLS * function. Mostly only necessary to handle * deletion of temporary symlinks. */ -typedef struct { +typedef struct +{ int dfd; char *path; } OtCleanupUnlinkat; @@ -44,55 +45,37 @@ ot_cleanup_unlinkat (OtCleanupUnlinkat *cleanup) { if (cleanup->path) { - (void) unlinkat (cleanup->dfd, cleanup->path, 0); + (void)unlinkat (cleanup->dfd, cleanup->path, 0); ot_cleanup_unlinkat_clear (cleanup); } } -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OtCleanupUnlinkat, ot_cleanup_unlinkat) +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OtCleanupUnlinkat, ot_cleanup_unlinkat) -GFile * ot_fdrel_to_gfile (int dfd, const char *path); +GFile *ot_fdrel_to_gfile (int dfd, const char *path); -gboolean ot_readlinkat_gfile_info (int dfd, - const char *path, - GFileInfo *target_info, - GCancellable *cancellable, - GError **error); +gboolean ot_readlinkat_gfile_info (int dfd, const char *path, GFileInfo *target_info, + GCancellable *cancellable, GError **error); -gboolean ot_openat_read_stream (int dfd, - const char *path, - gboolean follow, - GInputStream **out_istream, - GCancellable *cancellable, - GError **error); - -gboolean ot_ensure_unlinked_at (int dfd, - const char *path, +gboolean ot_openat_read_stream (int dfd, const char *path, gboolean follow, + GInputStream **out_istream, GCancellable *cancellable, GError **error); -gboolean ot_openat_ignore_enoent (int dfd, - const char *path, - int *out_fd, - GError **error); - -gboolean ot_dfd_iter_init_allow_noent (int dfd, - const char *path, - GLnxDirFdIterator *dfd_iter, - gboolean *out_exists, - GError **error); - -GBytes * -ot_map_anonymous_tmpfile_from_content (GInputStream *instream, - GCancellable *cancellable, - GError **error); - -GBytes *ot_fd_readall_or_mmap (int fd, goffset offset, - GError **error); - -gboolean -ot_parse_file_by_line (const char *path, - gboolean (*cb)(const char*, void*, GError**), - void *cbdata, - GCancellable *cancellable, - GError **error); +gboolean ot_ensure_unlinked_at (int dfd, const char *path, GError **error); + +gboolean ot_openat_ignore_enoent (int dfd, const char *path, int *out_fd, GError **error); + +gboolean ot_dfd_iter_init_allow_noent (int dfd, const char *path, GLnxDirFdIterator *dfd_iter, + gboolean *out_exists, GError **error); + +GBytes *ot_map_anonymous_tmpfile_from_content (GInputStream *instream, GCancellable *cancellable, + GError **error); + +GBytes *ot_fd_readall_or_mmap (int fd, goffset offset, GError **error); + +gboolean ot_parse_file_by_line (const char *path, gboolean (*cb) (const char *, void *, GError **), + void *cbdata, GCancellable *cancellable, GError **error); + +gboolean ot_get_dir_size (int dfd, const char *path, guint64 *out_size, GCancellable *cancellable, + GError **error); G_END_DECLS diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c index ef22602..d3d9765 100644 --- a/src/libotutil/ot-gio-utils.c +++ b/src/libotutil/ot-gio-utils.c @@ -21,10 +21,10 @@ #include "config.h" +#include #include #include #include -#include #include @@ -35,9 +35,7 @@ #endif GFile * -ot_gfile_resolve_path_printf (GFile *path, - const char *format, - ...) +ot_gfile_resolve_path_printf (GFile *path, const char *format, ...) { va_list args; g_autofree char *relpath = NULL; @@ -51,22 +49,18 @@ ot_gfile_resolve_path_printf (GFile *path, /** * ot_gfile_replace_contents_fsync: - * + * * Like g_file_replace_contents(), except always uses fdatasync(). */ gboolean -ot_gfile_replace_contents_fsync (GFile *path, - GBytes *contents, - GCancellable *cancellable, - GError **error) +ot_gfile_replace_contents_fsync (GFile *path, GBytes *contents, GCancellable *cancellable, + GError **error) { gsize len; - const guint8*buf = g_bytes_get_data (contents, &len); + const guint8 *buf = g_bytes_get_data (contents, &len); - return glnx_file_replace_contents_at (AT_FDCWD, gs_file_get_path_cached (path), - buf, len, - GLNX_FILE_REPLACE_DATASYNC_NEW, - cancellable, error); + return glnx_file_replace_contents_at (AT_FDCWD, gs_file_get_path_cached (path), buf, len, + GLNX_FILE_REPLACE_DATASYNC_NEW, cancellable, error); } /** @@ -76,9 +70,7 @@ ot_gfile_replace_contents_fsync (GFile *path, * exist. */ gboolean -ot_gfile_ensure_unlinked (GFile *path, - GCancellable *cancellable, - GError **error) +ot_gfile_ensure_unlinked (GFile *path, GCancellable *cancellable, GError **error) { g_assert (path); const char *pathc = gs_file_get_path_cached (path); @@ -94,11 +86,8 @@ ot_gfile_ensure_unlinked (GFile *path, #if !GLIB_CHECK_VERSION(2, 44, 0) gboolean -ot_file_enumerator_iterate (GFileEnumerator *direnum, - GFileInfo **out_info, - GFile **out_child, - GCancellable *cancellable, - GError **error) +ot_file_enumerator_iterate (GFileEnumerator *direnum, GFileInfo **out_info, GFile **out_child, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GError *temp_error = NULL; @@ -127,17 +116,19 @@ ot_file_enumerator_iterate (GFileEnumerator *direnum, } else if (*out_info != NULL) { - g_object_set_qdata_full ((GObject*)direnum, cached_info_quark, *out_info, (GDestroyNotify)g_object_unref); + g_object_set_qdata_full ((GObject *)direnum, cached_info_quark, *out_info, + (GDestroyNotify)g_object_unref); if (out_child != NULL) { const char *name = g_file_info_get_name (*out_info); *out_child = g_file_get_child (g_file_enumerator_get_container (direnum), name); - g_object_set_qdata_full ((GObject*)direnum, cached_child_quark, *out_child, (GDestroyNotify)g_object_unref); + g_object_set_qdata_full ((GObject *)direnum, cached_child_quark, *out_child, + (GDestroyNotify)g_object_unref); } } ret = TRUE; - out: +out: return ret; } @@ -162,7 +153,7 @@ ot_file_get_path_cached (GFile *file) G_LOCK (pathname_cache); - path = g_object_get_qdata ((GObject*)file, _file_path_quark); + path = g_object_get_qdata ((GObject *)file, _file_path_quark); if (!path) { path = g_file_get_path (file); @@ -171,7 +162,8 @@ ot_file_get_path_cached (GFile *file) G_UNLOCK (pathname_cache); return NULL; } - g_object_set_qdata_full ((GObject*)file, _file_path_quark, (char*)path, (GDestroyNotify)g_free); + g_object_set_qdata_full ((GObject *)file, _file_path_quark, (char *)path, + (GDestroyNotify)g_free); } G_UNLOCK (pathname_cache); diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h index 27c1d2d..9928713 100644 --- a/src/libotutil/ot-gio-utils.h +++ b/src/libotutil/ot-gio-utils.h @@ -29,49 +29,35 @@ G_BEGIN_DECLS * readlink(). Other things require opening the file, or also * stat()ing the parent directory. */ -#define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \ - "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev") +#define OSTREE_GIO_FAST_QUERYINFO \ + ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \ + "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev") -GFile * ot_gfile_resolve_path_printf (GFile *path, - const char *format, - ...) G_GNUC_PRINTF(2, 3); +GFile *ot_gfile_resolve_path_printf (GFile *path, const char *format, ...) G_GNUC_PRINTF (2, 3); -gboolean ot_gfile_replace_contents_fsync (GFile *path, - GBytes *contents, - GCancellable *cancellable, - GError **error); +gboolean ot_gfile_replace_contents_fsync (GFile *path, GBytes *contents, GCancellable *cancellable, + GError **error); -gboolean ot_gfile_ensure_unlinked (GFile *path, - GCancellable *cancellable, - GError **error); +gboolean ot_gfile_ensure_unlinked (GFile *path, GCancellable *cancellable, GError **error); #if !GLIB_CHECK_VERSION(2, 44, 0) -gboolean -ot_file_enumerator_iterate (GFileEnumerator *direnum, - GFileInfo **out_info, - GFile **out_child, - GCancellable *cancellable, - GError **error); +gboolean ot_file_enumerator_iterate (GFileEnumerator *direnum, GFileInfo **out_info, + GFile **out_child, GCancellable *cancellable, GError **error); #else static inline gboolean -ot_file_enumerator_iterate (GFileEnumerator *direnum, - GFileInfo **out_info, - GFile **out_child, - GCancellable *cancellable, - GError **error) +ot_file_enumerator_iterate (GFileEnumerator *direnum, GFileInfo **out_info, GFile **out_child, + GCancellable *cancellable, GError **error) { G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - return (g_file_enumerator_iterate) (direnum, out_info, out_child, cancellable, error); + return (g_file_enumerator_iterate)(direnum, out_info, out_child, cancellable, error); G_GNUC_END_IGNORE_DEPRECATIONS; } #endif #define g_file_enumerator_iterate ot_file_enumerator_iterate -const char * -ot_file_get_path_cached (GFile *file); +const char *ot_file_get_path_cached (GFile *file); -static inline -const char * +static inline const char * gs_file_get_path_cached (GFile *file) { return ot_file_get_path_cached (file); diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c index fd65e12..bb91a77 100644 --- a/src/libotutil/ot-gpg-utils.c +++ b/src/libotutil/ot-gpg-utils.c @@ -24,14 +24,13 @@ #include -#include #include "libglnx.h" #include "zbase32.h" +#include /* Like glnx_throw_errno_prefix, but takes @gpg_error */ gboolean -ot_gpgme_throw (gpgme_error_t gpg_error, GError **error, - const char *fmt, ...) +ot_gpgme_throw (gpgme_error_t gpg_error, GError **error, const char *fmt, ...) { if (error == NULL) return FALSE; @@ -42,32 +41,28 @@ ot_gpgme_throw (gpgme_error_t gpg_error, GError **error, /* XXX This list is incomplete. Add cases as needed. */ switch (gpgme_err_code (gpg_error)) { - /* special case - shouldn't be here */ - case GPG_ERR_NO_ERROR: - g_assert_not_reached (); - - /* special case - abort on out-of-memory */ - case GPG_ERR_ENOMEM: - (void) gpg_strerror_r (gpg_error, errbuf, sizeof (errbuf)); - errbuf[sizeof(errbuf)-1] = '\0'; - g_error ("%s: %s", - gpgme_strsource (gpg_error), - errbuf); - - case GPG_ERR_INV_VALUE: - errcode = G_IO_ERROR_INVALID_ARGUMENT; - break; - - default: - errcode = G_IO_ERROR_FAILED; - break; + /* special case - shouldn't be here */ + case GPG_ERR_NO_ERROR: + g_assert_not_reached (); + + /* special case - abort on out-of-memory */ + case GPG_ERR_ENOMEM: + (void)gpg_strerror_r (gpg_error, errbuf, sizeof (errbuf)); + errbuf[sizeof (errbuf) - 1] = '\0'; + g_error ("%s: %s", gpgme_strsource (gpg_error), errbuf); + + case GPG_ERR_INV_VALUE: + errcode = G_IO_ERROR_INVALID_ARGUMENT; + break; + + default: + errcode = G_IO_ERROR_FAILED; + break; } - (void) gpg_strerror_r (gpg_error, errbuf, sizeof (errbuf)); - errbuf[sizeof(errbuf)-1] = '\0'; - g_set_error (error, G_IO_ERROR, errcode, "%s: %s", - gpgme_strsource (gpg_error), - errbuf); + (void)gpg_strerror_r (gpg_error, errbuf, sizeof (errbuf)); + errbuf[sizeof (errbuf) - 1] = '\0'; + g_set_error (error, G_IO_ERROR, errcode, "%s: %s", gpgme_strsource (gpg_error), errbuf); va_list args; va_start (args, fmt); glnx_real_set_prefix_error_va (*error, fmt, args); @@ -77,11 +72,9 @@ ot_gpgme_throw (gpgme_error_t gpg_error, GError **error, } gboolean -ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, - char **out_tmp_home_dir, - GOutputStream **out_pubring_stream, - GCancellable *cancellable, - GError **error) +ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, char **out_tmp_home_dir, + GOutputStream **out_pubring_stream, GCancellable *cancellable, + GError **error) { g_autofree char *tmp_home_dir = NULL; gpgme_error_t gpg_error; @@ -105,9 +98,7 @@ ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, /* Not documented, but gpgme_ctx_set_engine_info() accepts NULL for * the executable file name, which leaves the old setting unchanged. */ - gpg_error = gpgme_ctx_set_engine_info (gpgme_ctx, - GPGME_PROTOCOL_OpenPGP, - NULL, tmp_home_dir); + gpg_error = gpgme_ctx_set_engine_info (gpgme_ctx, GPGME_PROTOCOL_OpenPGP, NULL, tmp_home_dir); if (gpg_error != GPG_ERR_NO_ERROR) { ot_gpgme_throw (gpg_error, error, "gpgme_ctx_set_engine_info"); @@ -117,15 +108,13 @@ ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, if (out_pubring_stream != NULL) { GFileOutputStream *pubring_stream; - g_autoptr(GFile) pubring_file = NULL; + g_autoptr (GFile) pubring_file = NULL; g_autofree char *pubring_path = NULL; pubring_path = g_build_filename (tmp_home_dir, "pubring.gpg", NULL); pubring_file = g_file_new_for_path (pubring_path); - pubring_stream = g_file_create (pubring_file, - G_FILE_CREATE_NONE, - cancellable, error); + pubring_stream = g_file_create (pubring_file, G_FILE_CREATE_NONE, cancellable, error); if (pubring_stream == NULL) goto out; @@ -142,7 +131,7 @@ ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, if (!ret) { /* Clean up our mess on error. */ - (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_home_dir, NULL, NULL); + (void)glnx_shutil_rm_rf_at (AT_FDCWD, tmp_home_dir, NULL, NULL); } return ret; @@ -159,98 +148,98 @@ set_errno_from_gio_error (GError *error) switch (error->code) { - case G_IO_ERROR_FAILED: - errno = EIO; - break; - case G_IO_ERROR_NOT_FOUND: - errno = ENOENT; - break; - case G_IO_ERROR_EXISTS: - errno = EEXIST; - break; - case G_IO_ERROR_IS_DIRECTORY: - errno = EISDIR; - break; - case G_IO_ERROR_NOT_DIRECTORY: - errno = ENOTDIR; - break; - case G_IO_ERROR_NOT_EMPTY: - errno = ENOTEMPTY; - break; - case G_IO_ERROR_NOT_REGULAR_FILE: - case G_IO_ERROR_NOT_SYMBOLIC_LINK: - case G_IO_ERROR_NOT_MOUNTABLE_FILE: - errno = EBADF; - break; - case G_IO_ERROR_FILENAME_TOO_LONG: - errno = ENAMETOOLONG; - break; - case G_IO_ERROR_INVALID_FILENAME: - errno = EINVAL; - break; - case G_IO_ERROR_TOO_MANY_LINKS: - errno = EMLINK; - break; - case G_IO_ERROR_NO_SPACE: - errno = ENOSPC; - break; - case G_IO_ERROR_INVALID_ARGUMENT: - errno = EINVAL; - break; - case G_IO_ERROR_PERMISSION_DENIED: - errno = EPERM; - break; - case G_IO_ERROR_NOT_SUPPORTED: - errno = ENOTSUP; - break; - case G_IO_ERROR_NOT_MOUNTED: - errno = ENOENT; - break; - case G_IO_ERROR_ALREADY_MOUNTED: - errno = EALREADY; - break; - case G_IO_ERROR_CLOSED: - errno = EBADF; - break; - case G_IO_ERROR_CANCELLED: - errno = EINTR; - break; - case G_IO_ERROR_PENDING: - errno = EALREADY; - break; - case G_IO_ERROR_READ_ONLY: - errno = EACCES; - break; - case G_IO_ERROR_CANT_CREATE_BACKUP: - errno = EIO; - break; - case G_IO_ERROR_WRONG_ETAG: - errno = EACCES; - break; - case G_IO_ERROR_TIMED_OUT: - errno = EIO; - break; - case G_IO_ERROR_WOULD_RECURSE: - errno = ELOOP; - break; - case G_IO_ERROR_BUSY: - errno = EBUSY; - break; - case G_IO_ERROR_WOULD_BLOCK: - errno = EWOULDBLOCK; - break; - case G_IO_ERROR_HOST_NOT_FOUND: - errno = EHOSTDOWN; - break; - case G_IO_ERROR_WOULD_MERGE: - errno = EIO; - break; - case G_IO_ERROR_FAILED_HANDLED: - errno = 0; - break; - default: - errno = EIO; - break; + case G_IO_ERROR_FAILED: + errno = EIO; + break; + case G_IO_ERROR_NOT_FOUND: + errno = ENOENT; + break; + case G_IO_ERROR_EXISTS: + errno = EEXIST; + break; + case G_IO_ERROR_IS_DIRECTORY: + errno = EISDIR; + break; + case G_IO_ERROR_NOT_DIRECTORY: + errno = ENOTDIR; + break; + case G_IO_ERROR_NOT_EMPTY: + errno = ENOTEMPTY; + break; + case G_IO_ERROR_NOT_REGULAR_FILE: + case G_IO_ERROR_NOT_SYMBOLIC_LINK: + case G_IO_ERROR_NOT_MOUNTABLE_FILE: + errno = EBADF; + break; + case G_IO_ERROR_FILENAME_TOO_LONG: + errno = ENAMETOOLONG; + break; + case G_IO_ERROR_INVALID_FILENAME: + errno = EINVAL; + break; + case G_IO_ERROR_TOO_MANY_LINKS: + errno = EMLINK; + break; + case G_IO_ERROR_NO_SPACE: + errno = ENOSPC; + break; + case G_IO_ERROR_INVALID_ARGUMENT: + errno = EINVAL; + break; + case G_IO_ERROR_PERMISSION_DENIED: + errno = EPERM; + break; + case G_IO_ERROR_NOT_SUPPORTED: + errno = ENOTSUP; + break; + case G_IO_ERROR_NOT_MOUNTED: + errno = ENOENT; + break; + case G_IO_ERROR_ALREADY_MOUNTED: + errno = EALREADY; + break; + case G_IO_ERROR_CLOSED: + errno = EBADF; + break; + case G_IO_ERROR_CANCELLED: + errno = EINTR; + break; + case G_IO_ERROR_PENDING: + errno = EALREADY; + break; + case G_IO_ERROR_READ_ONLY: + errno = EACCES; + break; + case G_IO_ERROR_CANT_CREATE_BACKUP: + errno = EIO; + break; + case G_IO_ERROR_WRONG_ETAG: + errno = EACCES; + break; + case G_IO_ERROR_TIMED_OUT: + errno = EIO; + break; + case G_IO_ERROR_WOULD_RECURSE: + errno = ELOOP; + break; + case G_IO_ERROR_BUSY: + errno = EBUSY; + break; + case G_IO_ERROR_WOULD_BLOCK: + errno = EWOULDBLOCK; + break; + case G_IO_ERROR_HOST_NOT_FOUND: + errno = EHOSTDOWN; + break; + case G_IO_ERROR_WOULD_MERGE: + errno = EIO; + break; + case G_IO_ERROR_FAILED_HANDLED: + errno = 0; + break; + default: + errno = EIO; + break; } } @@ -263,8 +252,7 @@ data_read_cb (void *handle, void *buffer, size_t size) g_return_val_if_fail (G_IS_INPUT_STREAM (input_stream), -1); - if (!g_input_stream_read_all (input_stream, buffer, size, - &bytes_read, NULL, &local_error)) + if (!g_input_stream_read_all (input_stream, buffer, size, &bytes_read, NULL, &local_error)) { set_errno_from_gio_error (local_error); g_clear_error (&local_error); @@ -283,8 +271,7 @@ data_write_cb (void *handle, const void *buffer, size_t size) g_return_val_if_fail (G_IS_OUTPUT_STREAM (output_stream), -1); - if (g_output_stream_write_all (output_stream, buffer, size, - &bytes_written, NULL, &local_error)) + if (g_output_stream_write_all (output_stream, buffer, size, &bytes_written, NULL, &local_error)) { (void)g_output_stream_flush (output_stream, NULL, &local_error); } @@ -308,27 +295,27 @@ data_seek_cb (void *handle, off_t offset, int whence) off_t position = -1; GError *local_error = NULL; - g_return_val_if_fail (G_IS_INPUT_STREAM (stream) || - G_IS_OUTPUT_STREAM (stream), -1); + g_return_val_if_fail (G_IS_INPUT_STREAM (stream) || G_IS_OUTPUT_STREAM (stream), -1); - if (!G_IS_SEEKABLE (stream)) { - errno = EOPNOTSUPP; - goto out; - } + if (!G_IS_SEEKABLE (stream)) + { + errno = EOPNOTSUPP; + goto out; + } switch (whence) { - case SEEK_SET: - seek_type = G_SEEK_SET; - break; - case SEEK_CUR: - seek_type = G_SEEK_CUR; - break; - case SEEK_END: - seek_type = G_SEEK_END; - break; - default: - g_assert_not_reached (); + case SEEK_SET: + seek_type = G_SEEK_SET; + break; + case SEEK_CUR: + seek_type = G_SEEK_CUR; + break; + case SEEK_END: + seek_type = G_SEEK_END; + break; + default: + g_assert_not_reached (); } seekable = G_SEEKABLE (stream); @@ -351,25 +338,15 @@ data_release_cb (void *handle) { GObject *stream = handle; - g_return_if_fail (G_IS_INPUT_STREAM (stream) || - G_IS_OUTPUT_STREAM (stream)); + g_return_if_fail (G_IS_INPUT_STREAM (stream) || G_IS_OUTPUT_STREAM (stream)); g_object_unref (stream); } -static struct gpgme_data_cbs data_input_cbs = { - data_read_cb, - NULL, - data_seek_cb, - data_release_cb -}; +static struct gpgme_data_cbs data_input_cbs = { data_read_cb, NULL, data_seek_cb, data_release_cb }; -static struct gpgme_data_cbs data_output_cbs = { - NULL, - data_write_cb, - data_seek_cb, - data_release_cb -}; +static struct gpgme_data_cbs data_output_cbs + = { NULL, data_write_cb, data_seek_cb, data_release_cb }; gpgme_data_t ot_gpgme_data_input (GInputStream *input_stream) @@ -416,14 +393,13 @@ ot_gpgme_data_output (GOutputStream *output_stream) } gpgme_ctx_t -ot_gpgme_new_ctx (const char *homedir, - GError **error) +ot_gpgme_new_ctx (const char *homedir, GError **error) { gpgme_error_t err; - g_auto(gpgme_ctx_t) context = NULL; + g_auto (gpgme_ctx_t) context = NULL; if ((err = gpgme_new (&context)) != GPG_ERR_NO_ERROR) - return ot_gpgme_throw (err, error, "Unable to create gpg context"), NULL; + return ot_gpgme_throw (err, error, "Unable to create gpg context"), NULL; if (homedir != NULL) { @@ -440,9 +416,7 @@ ot_gpgme_new_ctx (const char *homedir, } static gboolean -get_gnupg_version (guint *major, - guint *minor, - guint *patch) +get_gnupg_version (guint *major, guint *minor, guint *patch) { g_return_val_if_fail (major != NULL, FALSE); g_return_val_if_fail (minor != NULL, FALSE); @@ -452,8 +426,8 @@ get_gnupg_version (guint *major, gpgme_error_t err = gpgme_get_engine_info (&info); if (err != GPG_ERR_NO_ERROR) { - g_debug ("Failed to get GPGME engine info: %s: %s", - gpgme_strsource (err), gpgme_strerror (err)); + g_debug ("Failed to get GPGME engine info: %s: %s", gpgme_strsource (err), + gpgme_strerror (err)); return FALSE; } @@ -473,7 +447,7 @@ get_gnupg_version (guint *major, return FALSE; } - g_auto(GStrv) parts = g_strsplit (gnupg_version, ".", 4); + g_auto (GStrv) parts = g_strsplit (gnupg_version, ".", 4); if (g_strv_length (parts) < 3) { g_debug ("Less than 3 components in GnuPG version \"%s\"", gnupg_version); @@ -498,9 +472,8 @@ ot_gpgme_kill_agent (const char *homedir) guint gnupg_major = 0, gnupg_minor = 0, gnupg_patch = 0; if (get_gnupg_version (&gnupg_major, &gnupg_minor, &gnupg_patch)) { - if ((gnupg_major > 2) || - (gnupg_major == 2 && gnupg_minor > 1) || - (gnupg_major == 2 && gnupg_minor == 1 && gnupg_patch >= 17)) + if ((gnupg_major > 2) || (gnupg_major == 2 && gnupg_minor > 1) + || (gnupg_major == 2 && gnupg_minor == 1 && gnupg_patch >= 17)) { /* Note early return */ g_debug ("GnuPG >= 2.1.17, skipping gpg-agent cleanup in %s", homedir); @@ -509,7 +482,7 @@ ot_gpgme_kill_agent (const char *homedir) } /* Run gpg-connect-agent killagent /bye */ - g_autoptr(GPtrArray) argv = g_ptr_array_new (); + g_autoptr (GPtrArray) argv = g_ptr_array_new (); g_ptr_array_add (argv, "gpg-connect-agent"); g_ptr_array_add (argv, "--homedir"); g_ptr_array_add (argv, (gpointer)homedir); @@ -517,13 +490,13 @@ ot_gpgme_kill_agent (const char *homedir) g_ptr_array_add (argv, "/bye"); g_ptr_array_add (argv, NULL); - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GSpawnFlags flags = G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL; gint proc_status = 0; g_autofree gchar *proc_stderr = NULL; g_debug ("Killing gpg-agent in %s", homedir); - if (!g_spawn_sync (NULL, (char **)argv->pdata, NULL, flags, NULL, NULL, - NULL, &proc_stderr, &proc_status, &local_error)) + if (!g_spawn_sync (NULL, (char **)argv->pdata, NULL, flags, NULL, NULL, NULL, &proc_stderr, + &proc_status, &local_error)) { g_debug ("Spawning gpg-connect-agent failed: %s", local_error->message); return; @@ -533,8 +506,7 @@ ot_gpgme_kill_agent (const char *homedir) /* Dump out stderr on failures */ g_printerr ("%s", proc_stderr); - g_debug ("Killing GPG agent with gpg-connect-agent failed: %s", - local_error->message); + g_debug ("Killing GPG agent with gpg-connect-agent failed: %s", local_error->message); return; } } @@ -549,7 +521,7 @@ encode_wkd_local (const char *local) guint8 digest[20] = { 0 }; gsize len = sizeof (digest); - g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA1); + g_autoptr (GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA1); g_checksum_update (checksum, (const guchar *)local, -1); g_checksum_get_digest (checksum, digest, &len); @@ -568,18 +540,15 @@ encode_wkd_local (const char *local) * https://datatracker.ietf.org/doc/html/draft-koch-openpgp-webkey-service */ gboolean -ot_gpg_wkd_urls (const char *email, - char **out_advanced_url, - char **out_direct_url, - GError **error) +ot_gpg_wkd_urls (const char *email, char **out_advanced_url, char **out_direct_url, GError **error) { g_return_val_if_fail (email != NULL, FALSE); - g_auto(GStrv) email_parts = g_strsplit (email, "@", -1); + g_auto (GStrv) email_parts = g_strsplit (email, "@", -1); if (g_strv_length (email_parts) != 2) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - "Invalid email address \"%s\"", email); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid email address \"%s\"", + email); return FALSE; } @@ -588,21 +557,17 @@ ot_gpg_wkd_urls (const char *email, g_autofree char *local_encoded = encode_wkd_local (local_lowered); g_autofree char *local_escaped = g_uri_escape_string (email_parts[0], NULL, FALSE); - g_autofree char *advanced_url = g_strdup_printf ("https://openpgpkey.%s" - "/.well-known/openpgpkey" - "/%s/hu/%s?l=%s", - email_parts[1], - domain_lowered, - local_encoded, - local_escaped); + g_autofree char *advanced_url + = g_strdup_printf ("https://openpgpkey.%s" + "/.well-known/openpgpkey" + "/%s/hu/%s?l=%s", + email_parts[1], domain_lowered, local_encoded, local_escaped); g_debug ("GPG UID \"%s\" advanced WKD URL: %s", email, advanced_url); g_autofree char *direct_url = g_strdup_printf ("https://%s" "/.well-known/openpgpkey" "/hu/%s?l=%s", - email_parts[1], - local_encoded, - local_escaped); + email_parts[1], local_encoded, local_escaped); g_debug ("GPG UID \"%s\" direct WKD URL: %s", email, direct_url); if (out_advanced_url != NULL) diff --git a/src/libotutil/ot-gpg-utils.h b/src/libotutil/ot-gpg-utils.h index ee1b127..039a2f3 100644 --- a/src/libotutil/ot-gpg-utils.h +++ b/src/libotutil/ot-gpg-utils.h @@ -19,36 +19,31 @@ #pragma once -#include -#include #include "libglnx.h" +#include +#include G_BEGIN_DECLS -G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_data_t, gpgme_data_release, NULL) -G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_ctx_t, gpgme_release, NULL) -G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_key_t, gpgme_key_unref, NULL) +G_DEFINE_AUTO_CLEANUP_FREE_FUNC (gpgme_data_t, gpgme_data_release, NULL) +G_DEFINE_AUTO_CLEANUP_FREE_FUNC (gpgme_ctx_t, gpgme_release, NULL) +G_DEFINE_AUTO_CLEANUP_FREE_FUNC (gpgme_key_t, gpgme_key_unref, NULL) -gboolean ot_gpgme_throw (gpgme_error_t gpg_error, GError **error, - const char *fmt, ...) G_GNUC_PRINTF (3, 4); +gboolean ot_gpgme_throw (gpgme_error_t gpg_error, GError **error, const char *fmt, ...) + G_GNUC_PRINTF (3, 4); -gboolean ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, - char **out_tmp_home_dir, - GOutputStream **out_pubring_stream, - GCancellable *cancellable, - GError **error); +gboolean ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, char **out_tmp_home_dir, + GOutputStream **out_pubring_stream, GCancellable *cancellable, + GError **error); gpgme_data_t ot_gpgme_data_input (GInputStream *input_stream); gpgme_data_t ot_gpgme_data_output (GOutputStream *output_stream); -gpgme_ctx_t ot_gpgme_new_ctx (const char *homedir, - GError **error); +gpgme_ctx_t ot_gpgme_new_ctx (const char *homedir, GError **error); void ot_gpgme_kill_agent (const char *homedir); -gboolean ot_gpg_wkd_urls (const char *email, - char **out_advanced_url, - char **out_direct_url, - GError **error); +gboolean ot_gpg_wkd_urls (const char *email, char **out_advanced_url, char **out_direct_url, + GError **error); G_END_DECLS diff --git a/src/libotutil/ot-keyfile-utils.c b/src/libotutil/ot-keyfile-utils.c index de8abd2..d6cd102 100644 --- a/src/libotutil/ot-keyfile-utils.c +++ b/src/libotutil/ot-keyfile-utils.c @@ -29,16 +29,12 @@ static gboolean is_notfound (GError *error) { return g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) - || g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + || g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); } gboolean -ot_keyfile_get_boolean_with_default (GKeyFile *keyfile, - const char *section, - const char *value, - gboolean default_value, - gboolean *out_bool, - GError **error) +ot_keyfile_get_boolean_with_default (GKeyFile *keyfile, const char *section, const char *value, + gboolean default_value, gboolean *out_bool, GError **error) { g_return_val_if_fail (keyfile != NULL, FALSE); g_return_val_if_fail (section != NULL, FALSE); @@ -65,12 +61,52 @@ ot_keyfile_get_boolean_with_default (GKeyFile *keyfile, } gboolean -ot_keyfile_get_value_with_default (GKeyFile *keyfile, - const char *section, - const char *value, - const char *default_value, - char **out_value, - GError **error) +ot_keyfile_get_tristate_with_default (GKeyFile *keyfile, const char *section, const char *value, + OtTristate default_value, OtTristate *out_tri, GError **error) +{ + g_return_val_if_fail (keyfile != NULL, FALSE); + g_return_val_if_fail (section != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + GError *temp_error = NULL; + g_autofree char *ret_value = g_key_file_get_value (keyfile, section, value, &temp_error); + if (temp_error) + { + if (is_notfound (temp_error)) + { + g_clear_error (&temp_error); + g_assert (ret_value == NULL); + *out_tri = default_value; + return TRUE; + } + + g_propagate_error (error, temp_error); + return FALSE; + } + + ret_value = g_strstrip (ret_value); + + if (strcmp (ret_value, "yes") == 0 || strcmp (ret_value, "true") == 0 + || strcmp (ret_value, "1") == 0) + *out_tri = OT_TRISTATE_YES; + else if (strcmp (ret_value, "no") == 0 || strcmp (ret_value, "false") == 0 + || strcmp (ret_value, "0") == 0) + *out_tri = OT_TRISTATE_NO; + else if (strcmp (ret_value, "maybe") == 0) + *out_tri = OT_TRISTATE_MAYBE; + else + { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, + "Invalid tri-state value: %s", ret_value); + return FALSE; + } + + return TRUE; +} + +gboolean +ot_keyfile_get_value_with_default (GKeyFile *keyfile, const char *section, const char *value, + const char *default_value, char **out_value, GError **error) { g_return_val_if_fail (keyfile != NULL, FALSE); g_return_val_if_fail (section != NULL, FALSE); @@ -93,17 +129,14 @@ ot_keyfile_get_value_with_default (GKeyFile *keyfile, } } - ot_transfer_out_value(out_value, &ret_value); + ot_transfer_out_value (out_value, &ret_value); return TRUE; } gboolean -ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, - const char *section, - const char *value, - const char *default_value, - char **out_value, - GError **error) +ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, const char *section, + const char *value, const char *default_value, + char **out_value, GError **error) { g_return_val_if_fail (keyfile != NULL, FALSE); g_return_val_if_fail (section != NULL, FALSE); @@ -111,7 +144,8 @@ ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, GError *local_error = NULL; g_autofree char *ret_value = NULL; - if (!ot_keyfile_get_value_with_default (keyfile, section, value, default_value, &ret_value, &local_error)) + if (!ot_keyfile_get_value_with_default (keyfile, section, value, default_value, &ret_value, + &local_error)) { if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { @@ -125,7 +159,7 @@ ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, } } - ot_transfer_out_value(out_value, &ret_value); + ot_transfer_out_value (out_value, &ret_value); return TRUE; } @@ -133,27 +167,24 @@ ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, * zero or one of the separators and none of the others, read the * string as a NULL-terminated array out_value. If the value string * contains multiple of the separators, give an error. - * + * * Returns TRUE on success, FALSE on error. */ gboolean -ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile, - const char *section, - const char *key, - const char *separators, - char ***out_value, - GError **error) +ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile, const char *section, + const char *key, const char *separators, + char ***out_value, GError **error) { - g_return_val_if_fail (keyfile != NULL, FALSE); - g_return_val_if_fail (section != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (separators != NULL, FALSE); - - g_autofree char *value_str = NULL; - if (!ot_keyfile_get_value_with_default (keyfile, section, key, NULL, - &value_str, error)) + g_assert (keyfile != NULL); + g_assert (section != NULL); + g_assert (key != NULL); + g_assert (separators != NULL); + g_assert (out_value != NULL); + + g_autofree char *value_str = NULL; + if (!ot_keyfile_get_value_with_default (keyfile, section, key, NULL, &value_str, error)) return FALSE; - g_auto(GStrv) value_list = NULL; + g_auto (GStrv) value_list = NULL; if (value_str) { gchar sep = '\0'; @@ -175,8 +206,8 @@ ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile, } else if (sep_count == 1) { - if (!ot_keyfile_get_string_list_with_default (keyfile, section, key, - sep, NULL, &value_list, error)) + if (!ot_keyfile_get_string_list_with_default (keyfile, section, key, sep, NULL, + &value_list, error)) return FALSE; } else @@ -185,20 +216,16 @@ ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile, } } - ot_transfer_out_value (out_value, &value_list); + *out_value = g_steal_pointer (&value_list); return TRUE; } gboolean -ot_keyfile_get_string_list_with_default (GKeyFile *keyfile, - const char *section, - const char *key, - char separator, - char **default_value, - char ***out_value, - GError **error) +ot_keyfile_get_string_list_with_default (GKeyFile *keyfile, const char *section, const char *key, + char separator, char **default_value, char ***out_value, + GError **error) { - g_autoptr(GError) temp_error = NULL; + g_autoptr (GError) temp_error = NULL; g_return_val_if_fail (keyfile != NULL, FALSE); g_return_val_if_fail (section != NULL, FALSE); @@ -206,8 +233,7 @@ ot_keyfile_get_string_list_with_default (GKeyFile *keyfile, g_key_file_set_list_separator (keyfile, separator); - g_auto(GStrv) ret_value = g_key_file_get_string_list (keyfile, section, - key, NULL, &temp_error); + g_auto (GStrv) ret_value = g_key_file_get_string_list (keyfile, section, key, NULL, &temp_error); if (temp_error) { @@ -228,11 +254,9 @@ ot_keyfile_get_string_list_with_default (GKeyFile *keyfile, } gboolean -ot_keyfile_copy_group (GKeyFile *source_keyfile, - GKeyFile *target_keyfile, - const char *group_name) +ot_keyfile_copy_group (GKeyFile *source_keyfile, GKeyFile *target_keyfile, const char *group_name) { - g_auto(GStrv) keys = NULL; + g_auto (GStrv) keys = NULL; gsize length, ii; gboolean ret = FALSE; @@ -255,6 +279,6 @@ ot_keyfile_copy_group (GKeyFile *source_keyfile, ret = TRUE; - out: +out: return ret; } diff --git a/src/libotutil/ot-keyfile-utils.h b/src/libotutil/ot-keyfile-utils.h index 3b4f656..eb97c8d 100644 --- a/src/libotutil/ot-keyfile-utils.h +++ b/src/libotutil/ot-keyfile-utils.h @@ -23,53 +23,42 @@ #include +typedef enum +{ + OT_TRISTATE_NO, + OT_TRISTATE_MAYBE, + OT_TRISTATE_YES, +} OtTristate; + G_BEGIN_DECLS -gboolean -ot_keyfile_get_boolean_with_default (GKeyFile *keyfile, - const char *section, - const char *value, - gboolean default_value, - gboolean *out_bool, - GError **error); +gboolean ot_keyfile_get_boolean_with_default (GKeyFile *keyfile, const char *section, + const char *value, gboolean default_value, + gboolean *out_bool, GError **error); +gboolean ot_keyfile_get_tristate_with_default (GKeyFile *keyfile, const char *section, + const char *value, OtTristate default_value, + OtTristate *out_tri, GError **error); -gboolean -ot_keyfile_get_value_with_default (GKeyFile *keyfile, - const char *section, - const char *value, - const char *default_value, - char **out_value, - GError **error); +gboolean ot_keyfile_get_value_with_default (GKeyFile *keyfile, const char *section, + const char *value, const char *default_value, + char **out_value, GError **error); -gboolean -ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, - const char *section, - const char *value, - const char *default_value, - char **out_value, - GError **error); +gboolean ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile, const char *section, + const char *value, + const char *default_value, + char **out_value, GError **error); -gboolean -ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile, - const char *section, - const char *key, - const char *separators, - char ***out_value_list, - GError **error); +gboolean ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile, const char *section, + const char *key, const char *separators, + char ***out_value_list, GError **error); -gboolean -ot_keyfile_get_string_list_with_default (GKeyFile *keyfile, - const char *section, - const char *key, - char separator, - char **default_value, - char ***out_value, - GError **error); +gboolean ot_keyfile_get_string_list_with_default (GKeyFile *keyfile, const char *section, + const char *key, char separator, + char **default_value, char ***out_value, + GError **error); -gboolean -ot_keyfile_copy_group (GKeyFile *source_keyfile, - GKeyFile *target_keyfile, - const char *group_name); +gboolean ot_keyfile_copy_group (GKeyFile *source_keyfile, GKeyFile *target_keyfile, + const char *group_name); G_END_DECLS diff --git a/src/libotutil/ot-tool-util.c b/src/libotutil/ot-tool-util.c index 33e8766..0e772c2 100644 --- a/src/libotutil/ot-tool-util.c +++ b/src/libotutil/ot-tool-util.c @@ -19,23 +19,17 @@ #include "config.h" -#include "otutil.h" #include "ot-tool-util.h" +#include "otutil.h" gboolean -ot_parse_boolean (const char *value, - gboolean *out_parsed, - GError **error) +ot_parse_boolean (const char *value, gboolean *out_parsed, GError **error) { -#define ARG_EQ(x, y) (g_ascii_strcasecmp(x, y) == 0) - if (ARG_EQ(value, "1") - || ARG_EQ(value, "true") - || ARG_EQ(value, "yes")) +#define ARG_EQ(x, y) (g_ascii_strcasecmp (x, y) == 0) + if (ARG_EQ (value, "1") || ARG_EQ (value, "true") || ARG_EQ (value, "yes")) *out_parsed = TRUE; - else if (ARG_EQ(value, "0") - || ARG_EQ(value, "false") - || ARG_EQ(value, "no") - || ARG_EQ(value, "none")) + else if (ARG_EQ (value, "0") || ARG_EQ (value, "false") || ARG_EQ (value, "no") + || ARG_EQ (value, "none")) *out_parsed = FALSE; else { @@ -46,10 +40,7 @@ ot_parse_boolean (const char *value, } gboolean -ot_parse_keyvalue (const char *keyvalue, - char **out_key, - char **out_value, - GError **error) +ot_parse_keyvalue (const char *keyvalue, char **out_key, char **out_value, GError **error) { const char *eq = strchr (keyvalue, '='); if (!eq) @@ -62,8 +53,10 @@ ot_parse_keyvalue (const char *keyvalue, } /** - * Note: temporarily copied from GLib: https://github.com/GNOME/glib/blob/a419146578a42c760cff684292465b38df855f75/glib/garray.c#L1664 - * See documentation at: https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-find-with-equal-func + * Note: temporarily copied from GLib: + * https://github.com/GNOME/glib/blob/a419146578a42c760cff684292465b38df855f75/glib/garray.c#L1664 + * See documentation at: + * https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-find-with-equal-func * * ot_ptr_array_find_with_equal_func: (skip) * @haystack: pointer array to be searched @@ -88,10 +81,8 @@ ot_parse_keyvalue (const char *keyvalue, * Since: 2.54 */ gboolean -ot_ptr_array_find_with_equal_func (GPtrArray *haystack, - gconstpointer needle, - GEqualFunc equal_func, - guint *index_) +ot_ptr_array_find_with_equal_func (GPtrArray *haystack, gconstpointer needle, GEqualFunc equal_func, + guint *index_) { guint i; diff --git a/src/libotutil/ot-tool-util.h b/src/libotutil/ot-tool-util.h index be15c01..6d0a152 100644 --- a/src/libotutil/ot-tool-util.h +++ b/src/libotutil/ot-tool-util.h @@ -23,19 +23,9 @@ G_BEGIN_DECLS -gboolean -ot_parse_boolean (const char *value, - gboolean *out_parsed, - GError **error); -gboolean -ot_parse_keyvalue (const char *keyvalue, - char **out_key, - char **out_value, - GError **error); -gboolean -ot_ptr_array_find_with_equal_func (GPtrArray *haystack, - gconstpointer needle, - GEqualFunc equal_func, - guint *index_); +gboolean ot_parse_boolean (const char *value, gboolean *out_parsed, GError **error); +gboolean ot_parse_keyvalue (const char *keyvalue, char **out_key, char **out_value, GError **error); +gboolean ot_ptr_array_find_with_equal_func (GPtrArray *haystack, gconstpointer needle, + GEqualFunc equal_func, guint *index_); G_END_DECLS diff --git a/src/libotutil/ot-unix-utils.c b/src/libotutil/ot-unix-utils.c index 5853986..33cd1c0 100644 --- a/src/libotutil/ot-unix-utils.c +++ b/src/libotutil/ot-unix-utils.c @@ -24,22 +24,21 @@ #include "otutil.h" #include -#include #include +#include +#include +#include +#include #include #include -#include #include -#include -#include /* Ensure that a pathname component @name does not contain the special Unix * entries `.` or `..`, and does not contain `/`. */ gboolean -ot_util_filename_validate (const char *name, - GError **error) +ot_util_filename_validate (const char *name, GError **error) { if (name == NULL) return glnx_throw (error, "Invalid NULL filename"); @@ -55,25 +54,26 @@ ot_util_filename_validate (const char *name, } static GPtrArray * -ot_split_string_ptrarray (const char *str, - char c) +ot_split_string_ptrarray (const char *str, char c) { GPtrArray *ret = g_ptr_array_new_with_free_func (g_free); const char *p; - do { - p = strchr (str, '/'); - if (!p) - { - g_ptr_array_add (ret, g_strdup (str)); - str = NULL; - } - else - { - g_ptr_array_add (ret, g_strndup (str, p - str)); - str = p + 1; - } - } while (str && *str); + do + { + p = strchr (str, '/'); + if (!p) + { + g_ptr_array_add (ret, g_strdup (str)); + str = NULL; + } + else + { + g_ptr_array_add (ret, g_strndup (str, p - str)); + str = p + 1; + } + } + while (str && *str); return ret; } @@ -82,17 +82,15 @@ ot_split_string_ptrarray (const char *str, * validating that it does not have backreferences (`..`) etc. */ gboolean -ot_util_path_split_validate (const char *path, - GPtrArray **out_components, - GError **error) +ot_util_path_split_validate (const char *path, GPtrArray **out_components, GError **error) { if (strlen (path) > PATH_MAX) return glnx_throw (error, "Path '%s' is too long", path); - g_autoptr(GPtrArray) ret_components = ot_split_string_ptrarray (path, '/'); + g_autoptr (GPtrArray) ret_components = ot_split_string_ptrarray (path, '/'); /* Canonicalize by removing '.' and '', throw an error on .. */ - for (int i = ret_components->len-1; i >= 0; i--) + for (int i = ret_components->len - 1; i >= 0; i--) { const char *name = ret_components->pdata[i]; if (strcmp (name, "..") == 0) @@ -101,6 +99,6 @@ ot_util_path_split_validate (const char *path, g_ptr_array_remove_index (ret_components, i); } - ot_transfer_out_value(out_components, &ret_components); + ot_transfer_out_value (out_components, &ret_components); return TRUE; } diff --git a/src/libotutil/ot-unix-utils.h b/src/libotutil/ot-unix-utils.h index 46fb49a..3e4be2f 100644 --- a/src/libotutil/ot-unix-utils.h +++ b/src/libotutil/ot-unix-utils.h @@ -24,14 +24,14 @@ #include /* I just put all this shit here. Sue me. */ -#include -#include -#include -#include #include -#include +#include #include #include +#include +#include +#include +#include G_BEGIN_DECLS diff --git a/src/libotutil/ot-variant-builder.c b/src/libotutil/ot-variant-builder.c index 4d3dcbe..68b3a3b 100644 --- a/src/libotutil/ot-variant-builder.c +++ b/src/libotutil/ot-variant-builder.c @@ -21,8 +21,8 @@ #include "config.h" -#include "ot-variant-builder.h" #include "libglnx/libglnx.h" +#include "ot-variant-builder.h" /***************************************************************************************** * This code is copied from gvariant in glib. With the following copyright: @@ -48,13 +48,12 @@ typedef struct _GVariantTypeInfo GVariantTypeInfo; -#define G_VARIANT_TYPE_INFO_CHAR_MAYBE 'm' -#define G_VARIANT_TYPE_INFO_CHAR_ARRAY 'a' -#define G_VARIANT_TYPE_INFO_CHAR_TUPLE '(' +#define G_VARIANT_TYPE_INFO_CHAR_MAYBE 'm' +#define G_VARIANT_TYPE_INFO_CHAR_ARRAY 'a' +#define G_VARIANT_TYPE_INFO_CHAR_TUPLE '(' #define G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY '{' -#define G_VARIANT_TYPE_INFO_CHAR_VARIANT 'v' -#define g_variant_type_info_get_type_char(info) \ - (g_variant_type_info_get_type_string(info)[0]) +#define G_VARIANT_TYPE_INFO_CHAR_VARIANT 'v' +#define g_variant_type_info_get_type_char(info) (g_variant_type_info_get_type_string (info)[0]) struct _GVariantTypeInfo { @@ -73,9 +72,9 @@ typedef struct guint8 ending_type; } GVariantMemberInfo; -#define G_VARIANT_MEMBER_ENDING_FIXED 0 -#define G_VARIANT_MEMBER_ENDING_LAST 1 -#define G_VARIANT_MEMBER_ENDING_OFFSET 2 +#define G_VARIANT_MEMBER_ENDING_FIXED 0 +#define G_VARIANT_MEMBER_ENDING_LAST 1 +#define G_VARIANT_MEMBER_ENDING_OFFSET 2 typedef struct { @@ -102,34 +101,34 @@ typedef struct /* Hard-code the base types in a constant array */ static const GVariantTypeInfo g_variant_type_info_basic_table[24] = { -#define fixed_aligned(x) x, x - 1 -#define not_a_type 0, -#define unaligned 0, 0 -#define aligned(x) 0, x - 1 - /* 'b' */ { fixed_aligned(1) }, /* boolean */ +#define fixed_aligned(x) x, x - 1 +#define not_a_type 0, +#define unaligned 0, 0 +#define aligned(x) 0, x - 1 + /* 'b' */ { fixed_aligned (1) }, /* boolean */ /* 'c' */ { not_a_type }, - /* 'd' */ { fixed_aligned(8) }, /* double */ + /* 'd' */ { fixed_aligned (8) }, /* double */ /* 'e' */ { not_a_type }, /* 'f' */ { not_a_type }, - /* 'g' */ { unaligned }, /* signature string */ - /* 'h' */ { fixed_aligned(4) }, /* file handle (int32) */ - /* 'i' */ { fixed_aligned(4) }, /* int32 */ + /* 'g' */ { unaligned }, /* signature string */ + /* 'h' */ { fixed_aligned (4) }, /* file handle (int32) */ + /* 'i' */ { fixed_aligned (4) }, /* int32 */ /* 'j' */ { not_a_type }, /* 'k' */ { not_a_type }, /* 'l' */ { not_a_type }, /* 'm' */ { not_a_type }, - /* 'n' */ { fixed_aligned(2) }, /* int16 */ - /* 'o' */ { unaligned }, /* object path string */ + /* 'n' */ { fixed_aligned (2) }, /* int16 */ + /* 'o' */ { unaligned }, /* object path string */ /* 'p' */ { not_a_type }, - /* 'q' */ { fixed_aligned(2) }, /* uint16 */ + /* 'q' */ { fixed_aligned (2) }, /* uint16 */ /* 'r' */ { not_a_type }, - /* 's' */ { unaligned }, /* string */ - /* 't' */ { fixed_aligned(8) }, /* uint64 */ - /* 'u' */ { fixed_aligned(4) }, /* uint32 */ - /* 'v' */ { aligned(8) }, /* variant */ + /* 's' */ { unaligned }, /* string */ + /* 't' */ { fixed_aligned (8) }, /* uint64 */ + /* 'u' */ { fixed_aligned (4) }, /* uint32 */ + /* 'v' */ { aligned (8) }, /* variant */ /* 'w' */ { not_a_type }, - /* 'x' */ { fixed_aligned(8) }, /* int64 */ - /* 'y' */ { fixed_aligned(1) }, /* byte */ + /* 'x' */ { fixed_aligned (8) }, /* int64 */ + /* 'y' */ { fixed_aligned (1) }, /* byte */ #undef fixed_aligned #undef not_a_type #undef unaligned @@ -139,15 +138,15 @@ static const GVariantTypeInfo g_variant_type_info_basic_table[24] = { static GRecMutex g_variant_type_info_lock; static GHashTable *g_variant_type_info_table; -static GVariantTypeInfo * g_variant_type_info_ref (GVariantTypeInfo *info); +static GVariantTypeInfo *g_variant_type_info_ref (GVariantTypeInfo *info); static void g_variant_type_info_unref (GVariantTypeInfo *info); -static GVariantTypeInfo * g_variant_type_info_get (const GVariantType *type); +static GVariantTypeInfo *g_variant_type_info_get (const GVariantType *type); #define GV_ARRAY_INFO_CLASS 'a' static ArrayInfo * GV_ARRAY_INFO (GVariantTypeInfo *info) { - return (ArrayInfo *) info; + return (ArrayInfo *)info; } static void @@ -156,7 +155,7 @@ array_info_free (GVariantTypeInfo *info) ArrayInfo *array_info; g_assert (info->container_class == GV_ARRAY_INFO_CLASS); - array_info = (ArrayInfo *) info; + array_info = (ArrayInfo *)info; g_variant_type_info_unref (array_info->element); g_slice_free (ArrayInfo, array_info); @@ -174,7 +173,7 @@ array_info_new (const GVariantType *type) info->container.info.alignment = info->element->alignment; info->container.info.fixed_size = 0; - return (ContainerInfo *) info; + return (ContainerInfo *)info; } /* == tuple == */ @@ -182,7 +181,7 @@ array_info_new (const GVariantType *type) static TupleInfo * GV_TUPLE_INFO (GVariantTypeInfo *info) { - return (TupleInfo *) info; + return (TupleInfo *)info; } static void @@ -192,20 +191,17 @@ tuple_info_free (GVariantTypeInfo *info) gint i; g_assert (info->container_class == GV_TUPLE_INFO_CLASS); - tuple_info = (TupleInfo *) info; + tuple_info = (TupleInfo *)info; for (i = 0; i < tuple_info->n_members; i++) g_variant_type_info_unref (tuple_info->members[i].type_info); - g_slice_free1 (sizeof (GVariantMemberInfo) * tuple_info->n_members, - tuple_info->members); + g_slice_free1 (sizeof (GVariantMemberInfo) * tuple_info->n_members, tuple_info->members); g_slice_free (TupleInfo, tuple_info); } static void -tuple_allocate_members (const GVariantType *type, - GVariantMemberInfo **members, - gsize *n_members) +tuple_allocate_members (const GVariantType *type, GVariantMemberInfo **members, gsize *n_members) { const GVariantType *item_type; gsize i = 0; @@ -237,10 +233,7 @@ tuple_allocate_members (const GVariantType *type, * range and %FALSE is returned if not. */ static gboolean -tuple_get_item (TupleInfo *info, - GVariantMemberInfo *item, - gsize *d, - gsize *e) +tuple_get_item (TupleInfo *info, GVariantMemberInfo *item, gsize *d, gsize *e) { if (&info->members[info->n_members] == item) return FALSE; @@ -268,11 +261,7 @@ tuple_get_item (TupleInfo *info, * computation and more compact storage. */ static void -tuple_table_append (GVariantMemberInfo **items, - gsize i, - gsize a, - gsize b, - gsize c) +tuple_table_append (GVariantMemberInfo **items, gsize i, gsize a, gsize b, gsize c) { GVariantMemberInfo *item = (*items)++; @@ -303,9 +292,8 @@ tuple_table_append (GVariantMemberInfo **items, * ends up saving us 'two pointer sizes' per item in each tuple when * allocating using GSlice. */ - a += ~b & c; /* take the "aligned" part of 'c' and add to 'a' */ - c &= b; /* chop 'c' to contain only the unaligned part */ - + a += ~b & c; /* take the "aligned" part of 'c' and add to 'a' */ + c &= b; /* chop 'c' to contain only the unaligned part */ /* Finally, we made one last adjustment. Recall: * @@ -362,8 +350,7 @@ tuple_table_append (GVariantMemberInfo **items, } static gsize -tuple_align (gsize offset, - guint alignment) +tuple_align (gsize offset, guint alignment) { return offset + ((-offset) & alignment); } @@ -418,9 +405,9 @@ tuple_generate_table (TupleInfo *info) { /* align to 'd' */ if (d <= b) - c = tuple_align (c, d); /* rule 1 */ + c = tuple_align (c, d); /* rule 1 */ else - a += tuple_align (c, b), b = d, c = 0; /* rule 2 */ + a += tuple_align (c, b), b = d, c = 0; /* rule 2 */ /* the start of the item is at this point (ie: right after we * have aligned for it). store this information in the table. @@ -438,7 +425,7 @@ tuple_generate_table (TupleInfo *info) i++, a = b = c = 0; else /* fixed size */ - c += e; /* rule 3 */ + c += e; /* rule 3 */ } } @@ -476,9 +463,8 @@ tuple_set_base_info (TupleInfo *info) * the alignment requirement (to make packing into arrays * easier) so we round up to that here. */ - base->fixed_size = - tuple_align (((m->a & m->b) | m->c) + m->type_info->fixed_size, - base->alignment); + base->fixed_size + = tuple_align (((m->a & m->b) | m->c) + m->type_info->fixed_size, base->alignment); else /* else, the tuple is not fixed size */ base->fixed_size = 0; @@ -521,12 +507,11 @@ tuple_info_new (const GVariantType *type) tuple_generate_table (info); tuple_set_base_info (info); - return (ContainerInfo *) info; + return (ContainerInfo *)info; } static const GVariantMemberInfo * -g_variant_type_info_member_info (GVariantTypeInfo *info, - gsize index) +g_variant_type_info_member_info (GVariantTypeInfo *info, gsize index) { TupleInfo *tuple_info = GV_TUPLE_INFO (info); @@ -547,7 +532,7 @@ g_variant_type_info_ref (GVariantTypeInfo *info) { if (info->container_class) { - ContainerInfo *container = (ContainerInfo *) info; + ContainerInfo *container = (ContainerInfo *)info; g_assert_cmpint (container->ref_count, >, 0); g_atomic_int_inc (&container->ref_count); @@ -561,13 +546,12 @@ g_variant_type_info_unref (GVariantTypeInfo *info) { if (info->container_class) { - ContainerInfo *container = (ContainerInfo *) info; + ContainerInfo *container = (ContainerInfo *)info; g_rec_mutex_lock (&g_variant_type_info_lock); if (g_atomic_int_dec_and_test (&container->ref_count)) { - g_hash_table_remove (g_variant_type_info_table, - container->type_string); + g_hash_table_remove (g_variant_type_info_table, container->type_string); if (g_hash_table_size (g_variant_type_info_table) == 0) { g_hash_table_unref (g_variant_type_info_table); @@ -598,10 +582,9 @@ g_variant_type_info_get (const GVariantType *type) type_char = g_variant_type_peek_string (type)[0]; - if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE || - type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY || - type_char == G_VARIANT_TYPE_INFO_CHAR_TUPLE || - type_char == G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY) + if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE || type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY + || type_char == G_VARIANT_TYPE_INFO_CHAR_TUPLE + || type_char == G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY) { GVariantTypeInfo *info; gchar *type_string; @@ -611,16 +594,15 @@ g_variant_type_info_get (const GVariantType *type) g_rec_mutex_lock (&g_variant_type_info_lock); if (g_variant_type_info_table == NULL) - g_variant_type_info_table = g_hash_table_new (g_str_hash, - g_str_equal); + g_variant_type_info_table = g_hash_table_new (g_str_hash, g_str_equal); info = g_hash_table_lookup (g_variant_type_info_table, type_string); if (info == NULL) { ContainerInfo *container; - if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE || - type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY) + if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE + || type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY) { container = array_info_new (type); } @@ -629,7 +611,7 @@ g_variant_type_info_get (const GVariantType *type) container = tuple_info_new (type); } - info = (GVariantTypeInfo *) container; + info = (GVariantTypeInfo *)container; container->type_string = type_string; container->ref_count = 1; @@ -656,14 +638,12 @@ g_variant_type_info_get (const GVariantType *type) info = g_variant_type_info_basic_table + index; - return (GVariantTypeInfo *) info; + return (GVariantTypeInfo *)info; } } static inline void -gvs_write_unaligned_le (guchar *bytes, - gsize value, - guint size) +gvs_write_unaligned_le (guchar *bytes, gsize value, guint size) { union { @@ -694,8 +674,7 @@ gvs_get_offset_size (gsize size) } static gsize -gvs_calculate_total_size (gsize body_size, - gsize offsets) +gvs_calculate_total_size (gsize body_size, gsize offsets) { if (body_size + 1 * offsets <= G_MAXUINT8) return body_size + 1 * offsets; @@ -709,14 +688,14 @@ gvs_calculate_total_size (gsize body_size, return body_size + 8 * offsets; } - /***************************************************************************************** * End of glib code *****************************************************************************************/ typedef struct _OtVariantBuilderInfo OtVariantBuilderInfo; -struct _OtVariantBuilderInfo { +struct _OtVariantBuilderInfo +{ OtVariantBuilderInfo *parent; OtVariantBuilder *builder; GVariantType *type; @@ -743,9 +722,10 @@ struct _OtVariantBuilderInfo { * (ie: maybe, array, variant) '0' if not (ie: tuple, dict entry) */ guint uniform_item_types : 1; -} ; +}; -struct _OtVariantBuilder { +struct _OtVariantBuilder +{ gint ref_count; int fd; @@ -758,11 +738,9 @@ struct _OtVariantBuilder { static OtVariantBuilderInfo * ot_variant_builder_info_new (OtVariantBuilder *builder, const GVariantType *type) { - OtVariantBuilderInfo *info; + g_assert (g_variant_type_is_container (type)); - g_return_val_if_fail (g_variant_type_is_container (type), NULL); - - info = (OtVariantBuilderInfo *) g_slice_new0 (OtVariantBuilderInfo); + OtVariantBuilderInfo *info = (OtVariantBuilderInfo *)g_slice_new0 (OtVariantBuilderInfo); info->builder = builder; info->type = g_variant_type_copy (type); @@ -771,7 +749,7 @@ ot_variant_builder_info_new (OtVariantBuilder *builder, const GVariantType *type info->n_children = 0; info->child_ends = g_array_new (FALSE, TRUE, sizeof (guint64)); - switch (*(const gchar *) type) + switch (*(const gchar *)type) { case G_VARIANT_CLASS_VARIANT: info->uniform_item_types = TRUE; @@ -782,24 +760,21 @@ ot_variant_builder_info_new (OtVariantBuilder *builder, const GVariantType *type case G_VARIANT_CLASS_ARRAY: info->uniform_item_types = TRUE; - info->expected_type = - g_variant_type_element (info->type); + info->expected_type = g_variant_type_element (info->type); info->min_items = 0; info->max_items = -1; break; case G_VARIANT_CLASS_MAYBE: info->uniform_item_types = TRUE; - info->expected_type = - g_variant_type_element (info->type); + info->expected_type = g_variant_type_element (info->type); info->min_items = 0; info->max_items = 1; break; case G_VARIANT_CLASS_DICT_ENTRY: info->uniform_item_types = FALSE; - info->expected_type = - g_variant_type_key (info->type); + info->expected_type = g_variant_type_key (info->type); info->min_items = 2; info->max_items = 2; break; @@ -812,8 +787,7 @@ ot_variant_builder_info_new (OtVariantBuilder *builder, const GVariantType *type break; case G_VARIANT_CLASS_TUPLE: /* a definite tuple type was given */ - info->expected_type = - g_variant_type_first (info->type); + info->expected_type = g_variant_type_first (info->type); info->min_items = g_variant_type_n_items (type); info->max_items = info->min_items; info->uniform_item_types = FALSE; @@ -821,7 +795,7 @@ ot_variant_builder_info_new (OtVariantBuilder *builder, const GVariantType *type default: g_assert_not_reached (); - } + } return info; } @@ -840,14 +814,11 @@ ot_variant_builder_info_free (OtVariantBuilderInfo *info) } OtVariantBuilder * -ot_variant_builder_new (const GVariantType *type, - int fd) +ot_variant_builder_new (const GVariantType *type, int fd) { - OtVariantBuilder *builder; - - g_return_val_if_fail (g_variant_type_is_container (type), NULL); + g_assert (g_variant_type_is_container (type)); - builder = (OtVariantBuilder *) g_slice_new0 (OtVariantBuilder); + OtVariantBuilder *builder = (OtVariantBuilder *)g_slice_new0 (OtVariantBuilder); builder->head = ot_variant_builder_info_new (builder, type); builder->ref_count = 1; @@ -877,9 +848,7 @@ ot_variant_builder_ref (OtVariantBuilder *builder) /* This is called before adding a child to the container. It updates the internal state and does the needed alignment */ static gboolean -ot_variant_builder_pre_add (OtVariantBuilderInfo *info, - const GVariantType *type, - GError **error) +ot_variant_builder_pre_add (OtVariantBuilderInfo *info, const GVariantType *type, GError **error) { guint alignment = 0; @@ -887,12 +856,10 @@ ot_variant_builder_pre_add (OtVariantBuilderInfo *info, { /* advance our expected type pointers */ if (info->expected_type) - info->expected_type = - g_variant_type_next (info->expected_type); + info->expected_type = g_variant_type_next (info->expected_type); if (info->prev_item_type) - info->prev_item_type = - g_variant_type_next (info->prev_item_type); + info->prev_item_type = g_variant_type_next (info->prev_item_type); } else { @@ -901,8 +868,7 @@ ot_variant_builder_pre_add (OtVariantBuilderInfo *info, info->prev_item_type = info->prev_item_type_base; } - if (g_variant_type_is_tuple (info->type) || - g_variant_type_is_dict_entry (info->type)) + if (g_variant_type_is_tuple (info->type) || g_variant_type_is_dict_entry (info->type)) { const GVariantMemberInfo *member_info; @@ -945,15 +911,12 @@ ot_variant_builder_add_child_end (OtVariantBuilderInfo *info) table if needed */ static gboolean -ot_variant_builder_post_add (OtVariantBuilderInfo *info, - const GVariantType *type, - guint64 bytes_added, - GError **error) +ot_variant_builder_post_add (OtVariantBuilderInfo *info, const GVariantType *type, + guint64 bytes_added, GError **error) { info->offset += bytes_added; - if (g_variant_type_is_tuple (info->type) || - g_variant_type_is_dict_entry (info->type)) + if (g_variant_type_is_tuple (info->type) || g_variant_type_is_dict_entry (info->type)) { const GVariantMemberInfo *member_info; @@ -989,24 +952,16 @@ ot_variant_builder_post_add (OtVariantBuilderInfo *info, } gboolean -ot_variant_builder_add_from_fd (OtVariantBuilder *builder, - const GVariantType *type, - int fd, - guint64 size, - GError **error) +ot_variant_builder_add_from_fd (OtVariantBuilder *builder, const GVariantType *type, int fd, + guint64 size, GError **error) { OtVariantBuilderInfo *info = builder->head; - g_return_val_if_fail (info->n_children < info->max_items, - FALSE); - g_return_val_if_fail (!info->expected_type || - g_variant_type_is_subtype_of (type, - info->expected_type), - FALSE); - g_return_val_if_fail (!info->prev_item_type || - g_variant_type_is_subtype_of (info->prev_item_type, - type), - FALSE); + g_return_val_if_fail (info->n_children < info->max_items, FALSE); + g_return_val_if_fail ( + !info->expected_type || g_variant_type_is_subtype_of (type, info->expected_type), FALSE); + g_return_val_if_fail ( + !info->prev_item_type || g_variant_type_is_subtype_of (info->prev_item_type, type), FALSE); if (!ot_variant_builder_pre_add (info, type, error)) return FALSE; @@ -1021,25 +976,18 @@ ot_variant_builder_add_from_fd (OtVariantBuilder *builder, } gboolean -ot_variant_builder_add_value (OtVariantBuilder *builder, - GVariant *value, - GError **error) +ot_variant_builder_add_value (OtVariantBuilder *builder, GVariant *value, GError **error) { OtVariantBuilderInfo *info = builder->head; gconstpointer data; gsize data_size; /* We ref-sink value, just like g_variant_builder_add_value does */ - g_autoptr(GVariant) keep_around_until_return G_GNUC_UNUSED = g_variant_ref_sink (value); + g_autoptr (GVariant) keep_around_until_return G_GNUC_UNUSED = g_variant_ref_sink (value); - g_return_val_if_fail (info->n_children < info->max_items, + g_return_val_if_fail (info->n_children < info->max_items, FALSE); + g_return_val_if_fail (!info->expected_type || g_variant_is_of_type (value, info->expected_type), FALSE); - g_return_val_if_fail (!info->expected_type || - g_variant_is_of_type (value, - info->expected_type), - FALSE); - g_return_val_if_fail (!info->prev_item_type || - g_variant_is_of_type (value, - info->prev_item_type), + g_return_val_if_fail (!info->prev_item_type || g_variant_is_of_type (value, info->prev_item_type), FALSE); if (!ot_variant_builder_pre_add (info, g_variant_get_type (value), error)) @@ -1061,10 +1009,7 @@ ot_variant_builder_add_value (OtVariantBuilder *builder, } gboolean -ot_variant_builder_add (OtVariantBuilder *builder, - GError **error, - const gchar *format_string, - ...) +ot_variant_builder_add (OtVariantBuilder *builder, GError **error, const gchar *format_string, ...) { GVariant *variant; va_list ap; @@ -1076,27 +1021,21 @@ ot_variant_builder_add (OtVariantBuilder *builder, return ot_variant_builder_add_value (builder, variant, error); } - gboolean -ot_variant_builder_open (OtVariantBuilder *builder, - const GVariantType *type, - GError **error) +ot_variant_builder_open (OtVariantBuilder *builder, const GVariantType *type, GError **error) { OtVariantBuilderInfo *info = builder->head; - OtVariantBuilderInfo *new_info; g_assert (info->n_children < info->max_items); - g_assert (!info->expected_type || - g_variant_type_is_subtype_of (type, - info->expected_type)); - g_assert (!info->prev_item_type || - g_variant_type_is_subtype_of (info->prev_item_type, - type)); + g_assert (!info->expected_type || g_variant_type_is_subtype_of (type, info->expected_type)); + g_assert (!info->prev_item_type || g_variant_type_is_subtype_of (info->prev_item_type, type)); if (!ot_variant_builder_pre_add (info, type, error)) return FALSE; - new_info = ot_variant_builder_info_new (builder, type); + OtVariantBuilderInfo *new_info = ot_variant_builder_info_new (builder, type); + g_assert (new_info != NULL); + new_info->parent = info; /* push the prev_item_type down into the subcontainer */ @@ -1104,13 +1043,11 @@ ot_variant_builder_open (OtVariantBuilder *builder, { if (!new_info->uniform_item_types) /* tuples and dict entries */ - new_info->prev_item_type = - g_variant_type_first (info->prev_item_type); + new_info->prev_item_type = g_variant_type_first (info->prev_item_type); else if (!g_variant_type_is_variant (new_info->type)) /* maybes and arrays */ - new_info->prev_item_type = - g_variant_type_element (info->prev_item_type); + new_info->prev_item_type = g_variant_type_element (info->prev_item_type); } builder->head = new_info; @@ -1118,8 +1055,7 @@ ot_variant_builder_open (OtVariantBuilder *builder, } gboolean -ot_variant_builder_close (OtVariantBuilder *builder, - GError **error) +ot_variant_builder_close (OtVariantBuilder *builder, GError **error) { OtVariantBuilderInfo *info = builder->head; OtVariantBuilderInfo *parent; @@ -1143,22 +1079,18 @@ ot_variant_builder_close (OtVariantBuilder *builder, } gboolean -ot_variant_builder_end (OtVariantBuilder *builder, - GError **error) +ot_variant_builder_end (OtVariantBuilder *builder, GError **error) { OtVariantBuilderInfo *info = builder->head; gboolean add_offset_table = FALSE; gboolean reverse_offset_table = FALSE; - g_return_val_if_fail (info->n_children >= info->min_items, - FALSE); - g_return_val_if_fail (!info->uniform_item_types || - info->prev_item_type != NULL || - g_variant_type_is_definite (info->type), + g_return_val_if_fail (info->n_children >= info->min_items, FALSE); + g_return_val_if_fail (!info->uniform_item_types || info->prev_item_type != NULL + || g_variant_type_is_definite (info->type), FALSE); - if (g_variant_type_is_tuple (info->type) || - g_variant_type_is_dict_entry (info->type)) + if (g_variant_type_is_tuple (info->type) || g_variant_type_is_dict_entry (info->type)) { add_offset_table = TRUE; reverse_offset_table = TRUE; diff --git a/src/libotutil/ot-variant-builder.h b/src/libotutil/ot-variant-builder.h index ed59eee..4acda3f 100644 --- a/src/libotutil/ot-variant-builder.h +++ b/src/libotutil/ot-variant-builder.h @@ -29,32 +29,19 @@ G_BEGIN_DECLS typedef struct _OtVariantBuilder OtVariantBuilder; -OtVariantBuilder *ot_variant_builder_new (const GVariantType *type, - int fd); -void ot_variant_builder_unref (OtVariantBuilder *builder); -OtVariantBuilder *ot_variant_builder_ref (OtVariantBuilder *builder); -gboolean ot_variant_builder_end (OtVariantBuilder *builder, - GError **error); -gboolean ot_variant_builder_open (OtVariantBuilder *builder, - const GVariantType *type, - GError **error); -gboolean ot_variant_builder_close (OtVariantBuilder *builder, - GError **error); -gboolean ot_variant_builder_add_from_fd (OtVariantBuilder *builder, - const GVariantType *type, - int fd, - guint64 size, - GError **error); -gboolean ot_variant_builder_add_value (OtVariantBuilder *builder, - GVariant *value, - GError **error); -gboolean ot_variant_builder_add (OtVariantBuilder *builder, - GError **error, - const gchar *format_string, - ...); -void ot_variant_builder_add_parsed (OtVariantBuilder *builder, - const gchar *format, - ...); +OtVariantBuilder *ot_variant_builder_new (const GVariantType *type, int fd); +void ot_variant_builder_unref (OtVariantBuilder *builder); +OtVariantBuilder *ot_variant_builder_ref (OtVariantBuilder *builder); +gboolean ot_variant_builder_end (OtVariantBuilder *builder, GError **error); +gboolean ot_variant_builder_open (OtVariantBuilder *builder, const GVariantType *type, + GError **error); +gboolean ot_variant_builder_close (OtVariantBuilder *builder, GError **error); +gboolean ot_variant_builder_add_from_fd (OtVariantBuilder *builder, const GVariantType *type, + int fd, guint64 size, GError **error); +gboolean ot_variant_builder_add_value (OtVariantBuilder *builder, GVariant *value, GError **error); +gboolean ot_variant_builder_add (OtVariantBuilder *builder, GError **error, + const gchar *format_string, ...); +void ot_variant_builder_add_parsed (OtVariantBuilder *builder, const gchar *format, ...); G_DEFINE_AUTOPTR_CLEANUP_FUNC (OtVariantBuilder, ot_variant_builder_unref) diff --git a/src/libotutil/ot-variant-utils.c b/src/libotutil/ot-variant-utils.c index f6a4e43..a660e33 100644 --- a/src/libotutil/ot-variant-utils.c +++ b/src/libotutil/ot-variant-utils.c @@ -21,8 +21,8 @@ #include "config.h" -#include #include +#include #include @@ -32,20 +32,18 @@ GVariant * ot_gvariant_new_empty_string_dict (void) { - g_auto(GVariantBuilder) builder = OT_VARIANT_BUILDER_INITIALIZER; + g_auto (GVariantBuilder) builder = OT_VARIANT_BUILDER_INITIALIZER; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); return g_variant_builder_end (&builder); } - /* Create a new GVariant of type ay from the raw @data pointer */ GVariant * -ot_gvariant_new_bytearray (const guchar *data, - gsize len) +ot_gvariant_new_bytearray (const guchar *data, gsize len) { - gpointer data_copy = g_memdup (data, len); - GVariant *ret = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data_copy, - len, FALSE, g_free, data_copy); + gpointer data_copy = g_memdup2 (data, len); + GVariant *ret + = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data_copy, len, FALSE, g_free, data_copy); return ret; } @@ -56,8 +54,8 @@ ot_gvariant_new_ay_bytes (GBytes *bytes) gsize size; gconstpointer data = g_bytes_get_data (bytes, &size); g_bytes_ref (bytes); - return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size, - TRUE, (GDestroyNotify)g_bytes_unref, bytes); + return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size, TRUE, + (GDestroyNotify)g_bytes_unref, bytes); } /* Create a GVariant in @out_variant that is backed by @@ -66,14 +64,10 @@ ot_gvariant_new_ay_bytes (GBytes *bytes) * by the GVariant core; see g_variant_new_from_data(). */ gboolean -ot_variant_read_fd (int fd, - goffset start, - const GVariantType *type, - gboolean trusted, - GVariant **out_variant, - GError **error) +ot_variant_read_fd (int fd, goffset start, const GVariantType *type, gboolean trusted, + GVariant **out_variant, GError **error) { - g_autoptr(GBytes) bytes = ot_fd_readall_or_mmap (fd, start, error); + g_autoptr (GBytes) bytes = ot_fd_readall_or_mmap (fd, start, error); if (!bytes) return FALSE; @@ -85,8 +79,7 @@ ot_variant_read_fd (int fd, * for a new variant, inherting the data from @variant. */ GVariantBuilder * -ot_util_variant_builder_from_variant (GVariant *variant, - const GVariantType *type) +ot_util_variant_builder_from_variant (GVariant *variant, const GVariantType *type) { GVariantBuilder *builder = g_variant_builder_new (type); @@ -95,7 +88,7 @@ ot_util_variant_builder_from_variant (GVariant *variant, const int n = g_variant_n_children (variant); for (int i = 0; i < n; i++) { - g_autoptr(GVariant) child = g_variant_get_child_value (variant, i); + g_autoptr (GVariant) child = g_variant_get_child_value (variant, i); g_variant_builder_add_value (builder, child); } } @@ -116,9 +109,7 @@ ot_util_variant_builder_from_variant (GVariant *variant, * Returns: %TRUE if found, %FALSE otherwise */ gboolean -ot_variant_bsearch_str (GVariant *array, - const char *str, - int *out_pos) +ot_variant_bsearch_str (GVariant *array, const char *str, int *out_pos) { const gsize n = g_variant_n_children (array); if (n == 0) @@ -133,7 +124,7 @@ ot_variant_bsearch_str (GVariant *array, imid = (imin + imax) / 2; - g_autoptr(GVariant) child = g_variant_get_child_value (array, imid); + g_autoptr (GVariant) child = g_variant_get_child_value (array, imid); g_variant_get_child (child, 0, "&s", &cur, NULL); int cmp = strcmp (cur, str); @@ -155,3 +146,21 @@ ot_variant_bsearch_str (GVariant *array, *out_pos = imid; return FALSE; } + +/** + * ot_variant_get_data: + * @variant: A variant + * @error: An error + * + * `g_variant_get_data` says it can return `NULL`, which many callers are not prepared + * to handle. Return an error in this case. + * + **/ +const guint8 * +ot_variant_get_data (GVariant *variant, GError **error) +{ + const guint8 *data = g_variant_get_data (variant); + if (!data) + return glnx_null_throw (error, "Corrupted serialized variant"); + return data; +} diff --git a/src/libotutil/ot-variant-utils.h b/src/libotutil/ot-variant-utils.h index b12682e..cbbc302 100644 --- a/src/libotutil/ot-variant-utils.h +++ b/src/libotutil/ot-variant-utils.h @@ -25,26 +25,19 @@ G_BEGIN_DECLS -GVariant *ot_gvariant_new_bytearray (const guchar *data, - gsize len); +GVariant *ot_gvariant_new_bytearray (const guchar *data, gsize len); GVariant *ot_gvariant_new_ay_bytes (GBytes *bytes); GVariant *ot_gvariant_new_empty_string_dict (void); -gboolean ot_variant_read_fd (int fd, - goffset offset, - const GVariantType *type, - gboolean trusted, - GVariant **out_variant, - GError **error); +gboolean ot_variant_read_fd (int fd, goffset offset, const GVariantType *type, gboolean trusted, + GVariant **out_variant, GError **error); -GVariantBuilder *ot_util_variant_builder_from_variant (GVariant *variant, - const GVariantType *type); +GVariantBuilder *ot_util_variant_builder_from_variant (GVariant *variant, const GVariantType *type); -gboolean -ot_variant_bsearch_str (GVariant *array, - const char *str, - int *out_pos); +gboolean ot_variant_bsearch_str (GVariant *array, const char *str, int *out_pos); + +const guint8 *ot_variant_get_data (GVariant *variant, GError **error); G_END_DECLS diff --git a/src/libotutil/otutil.h b/src/libotutil/otutil.h index 4279bc1..27f8410 100644 --- a/src/libotutil/otutil.h +++ b/src/libotutil/otutil.h @@ -22,9 +22,9 @@ #pragma once #include +#include #include /* Yeah...let's just do that here. */ #include -#include #ifdef HAVE_LIBSYSTEMD #include @@ -32,9 +32,21 @@ /* https://bugzilla.gnome.org/show_bug.cgi?id=766370 */ #if !GLIB_CHECK_VERSION(2, 49, 3) -#define OT_VARIANT_BUILDER_INITIALIZER {{0,}} +#define OT_VARIANT_BUILDER_INITIALIZER \ + { \ + { \ + 0, \ + } \ + } #else -#define OT_VARIANT_BUILDER_INITIALIZER {{{0,}}} +#define OT_VARIANT_BUILDER_INITIALIZER \ + { \ + { \ + { \ + 0, \ + } \ + } \ + } #endif static inline const char * @@ -45,20 +57,27 @@ ot_booltostr (int b) #define ot_gobject_refz(o) (o ? g_object_ref (o) : o) -#define ot_transfer_out_value(outp, srcp) G_STMT_START { \ - if (outp) \ - { \ - *outp = *srcp; \ - *(srcp) = NULL; \ - } \ - } G_STMT_END; +#define ot_transfer_out_value(outp, srcp) \ + G_STMT_START \ + { \ + if (outp) \ + { \ + *outp = *srcp; \ + *(srcp) = NULL; \ + } \ + } \ + G_STMT_END; #ifdef HAVE_LIBSYSTEMD -#define ot_journal_send(...) sd_journal_send(__VA_ARGS__) -#define ot_journal_print(...) sd_journal_print(__VA_ARGS__) +#define ot_journal_send(...) sd_journal_send (__VA_ARGS__) +#define ot_journal_print(...) sd_journal_print (__VA_ARGS__) #else -#define ot_journal_send(...) {} -#define ot_journal_print(...) {} +#define ot_journal_send(...) \ + { \ + } +#define ot_journal_print(...) \ + { \ + } #endif typedef GMainContext GMainContextPopDefault; @@ -85,17 +104,16 @@ _ostree_main_context_new_default (void) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GMainContextPopDefault, _ostree_main_context_pop_default_destroy) - -#include -#include +#include +#include #include +#include +#include #include +#include #include -#include #include -#include -#include -#include +#include #ifndef OSTREE_DISABLE_GPGME #include diff --git a/src/libotutil/zbase32.c b/src/libotutil/zbase32.c index 39fa97a..acd8a92 100644 --- a/src/libotutil/zbase32.c +++ b/src/libotutil/zbase32.c @@ -7,116 +7,133 @@ #include "zbase32.h" #include -#include -#include #include /* XXX only for debug printfs */ +#include +#include -static const char*const chars="ybndrfg8ejkmcpqxot1uwisza345h769"; +static const char *const chars = "ybndrfg8ejkmcpqxot1uwisza345h769"; /* Types from zstr */ /** * A zstr is simply an unsigned int length and a pointer to a buffer of * unsigned chars. */ -typedef struct { - size_t len; /* the length of the string (not counting the null-terminating character) */ - unsigned char* buf; /* pointer to the first byte */ +typedef struct +{ + size_t len; /* the length of the string (not counting the null-terminating character) */ + unsigned char *buf; /* pointer to the first byte */ } zstr; /** * A zstr is simply an unsigned int length and a pointer to a buffer of * const unsigned chars. */ -typedef struct { - size_t len; /* the length of the string (not counting the null-terminating character) */ - const unsigned char* buf; /* pointer to the first byte */ +typedef struct +{ + size_t len; /* the length of the string (not counting the null-terminating character) */ + const unsigned char *buf; /* pointer to the first byte */ } czstr; /* Functions from zstr */ static zstr -new_z(const size_t len) +new_z (const size_t len) { - zstr result; - result.buf = (unsigned char *)malloc(len+1); - if (result.buf == NULL) { - result.len = 0; - return result; - } - result.len = len; - result.buf[len] = '\0'; - return result; + zstr result; + result.buf = (unsigned char *)malloc (len + 1); + if (result.buf == NULL) + { + result.len = 0; + return result; + } + result.len = len; + result.buf[len] = '\0'; + return result; } /* Functions from zutil */ static size_t -divceil(size_t n, size_t d) +divceil (size_t n, size_t d) { - return n/d+((n%d)!=0); + return n / d + ((n % d) != 0); } -static zstr b2a_l_extra_Duffy(const czstr os, const size_t lengthinbits) +static zstr +b2a_l_extra_Duffy (const czstr os, const size_t lengthinbits) { - zstr result = new_z(divceil(os.len*8, 5)); /* if lengthinbits is not a multiple of 8 then this is allocating space for 0, 1, or 2 extra quintets that will be truncated at the end of this function if they are not needed */ - if (result.buf == NULL) - return result; + zstr result = new_z ( + divceil (os.len * 8, 5)); /* if lengthinbits is not a multiple of 8 then this is allocating + space for 0, 1, or 2 extra quintets that will be truncated at + the end of this function if they are not needed */ + if (result.buf == NULL) + return result; - unsigned char* resp = result.buf + result.len; /* pointer into the result buffer, initially pointing to the "one-past-the-end" quintet */ - const unsigned char* osp = os.buf + os.len; /* pointer into the os buffer, initially pointing to the "one-past-the-end" octet */ + unsigned char *resp = result.buf + result.len; /* pointer into the result buffer, initially + pointing to the "one-past-the-end" quintet */ + const unsigned char *osp = os.buf + os.len; /* pointer into the os buffer, initially pointing to + the "one-past-the-end" octet */ - /* Now this is a real live Duff's device. You gotta love it. */ - unsigned long x=0; /* to hold up to 32 bits worth of the input */ - switch ((osp - os.buf) % 5) { - case 0: - do { - x = *--osp; - *--resp = chars[x % 32]; /* The least sig 5 bits go into the final quintet. */ - x /= 32; /* ... now we have 3 bits worth in x... */ - case 4: - x |= ((unsigned long)(*--osp)) << 3; /* ... now we have 11 bits worth in x... */ - *--resp = chars[x % 32]; - x /= 32; /* ... now we have 6 bits worth in x... */ - *--resp = chars[x % 32]; - x /= 32; /* ... now we have 1 bits worth in x... */ - case 3: - x |= ((unsigned long)(*--osp)) << 1; /* The 8 bits from the 2-indexed octet. So now we have 9 bits worth in x... */ - *--resp = chars[x % 32]; - x /= 32; /* ... now we have 4 bits worth in x... */ - case 2: - x |= ((unsigned long)(*--osp)) << 4; /* The 8 bits from the 1-indexed octet. So now we have 12 bits worth in x... */ - *--resp = chars[x%32]; - x /= 32; /* ... now we have 7 bits worth in x... */ - *--resp = chars[x%32]; - x /= 32; /* ... now we have 2 bits worth in x... */ - case 1: - x |= ((unsigned long)(*--osp)) << 2; /* The 8 bits from the 0-indexed octet. So now we have 10 bits worth in x... */ - *--resp = chars[x%32]; - x /= 32; /* ... now we have 5 bits worth in x... */ - *--resp = chars[x]; - } while (osp > os.buf); - } /* switch ((osp - os.buf) % 5) */ + /* Now this is a real live Duff's device. You gotta love it. */ + unsigned long x = 0; /* to hold up to 32 bits worth of the input */ + switch ((osp - os.buf) % 5) + { + case 0: + do + { + x = *--osp; + *--resp = chars[x % 32]; /* The least sig 5 bits go into the final quintet. */ + x /= 32; /* ... now we have 3 bits worth in x... */ + case 4: + x |= ((unsigned long)(*--osp)) << 3; /* ... now we have 11 bits worth in x... */ + *--resp = chars[x % 32]; + x /= 32; /* ... now we have 6 bits worth in x... */ + *--resp = chars[x % 32]; + x /= 32; /* ... now we have 1 bits worth in x... */ + case 3: + x |= ((unsigned long)(*--osp)) << 1; /* The 8 bits from the 2-indexed octet. So now we + have 9 bits worth in x... */ + *--resp = chars[x % 32]; + x /= 32; /* ... now we have 4 bits worth in x... */ + case 2: + x |= ((unsigned long)(*--osp)) << 4; /* The 8 bits from the 1-indexed octet. So now we + have 12 bits worth in x... */ + *--resp = chars[x % 32]; + x /= 32; /* ... now we have 7 bits worth in x... */ + *--resp = chars[x % 32]; + x /= 32; /* ... now we have 2 bits worth in x... */ + case 1: + x |= ((unsigned long)(*--osp)) << 2; /* The 8 bits from the 0-indexed octet. So now we + have 10 bits worth in x... */ + *--resp = chars[x % 32]; + x /= 32; /* ... now we have 5 bits worth in x... */ + *--resp = chars[x]; + } + while (osp > os.buf); + } /* switch ((osp - os.buf) % 5) */ - /* truncate any unused trailing zero quintets */ - result.len = divceil(lengthinbits, 5); - result.buf[result.len] = '\0'; - return result; + /* truncate any unused trailing zero quintets */ + result.len = divceil (lengthinbits, 5); + result.buf[result.len] = '\0'; + return result; } -static zstr b2a_l(const czstr os, const size_t lengthinbits) +static zstr +b2a_l (const czstr os, const size_t lengthinbits) { - return b2a_l_extra_Duffy(os, lengthinbits); + return b2a_l_extra_Duffy (os, lengthinbits); } -static zstr b2a(const czstr os) +static zstr +b2a (const czstr os) { - return b2a_l(os, os.len*8); + return b2a_l (os, os.len * 8); } char * -zbase32_encode(const unsigned char *data, size_t length) +zbase32_encode (const unsigned char *data, size_t length) { - czstr input = { length, data }; - zstr output = b2a(input); - return (char *)output.buf; + czstr input = { length, data }; + zstr output = b2a (input); + return (char *)output.buf; } /** @@ -127,15 +144,15 @@ zbase32_encode(const unsigned char *data, size_t length) * distribute, sublicense, and/or sell copies of this software, and to permit * persons to whom this software is furnished to do so, subject to the following * conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of this software. - * - * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * + * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN + * OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN * THIS SOFTWARE. */ diff --git a/src/libotutil/zbase32.h b/src/libotutil/zbase32.h index bf9cf68..f5d27b4 100644 --- a/src/libotutil/zbase32.h +++ b/src/libotutil/zbase32.h @@ -7,12 +7,12 @@ #ifndef __INCL_base32_h #define __INCL_base32_h -static char const* const base32_h_cvsid = "$Id: base32.h,v 1.11 2003/12/15 01:16:19 zooko Exp $"; +static char const *const base32_h_cvsid = "$Id: base32.h,v 1.11 2003/12/15 01:16:19 zooko Exp $"; static int const base32_vermaj = 0; static int const base32_vermin = 9; static int const base32_vermicro = 12; -static char const* const base32_vernum = "0.9.12"; +static char const *const base32_vernum = "0.9.12"; #include #include @@ -23,7 +23,7 @@ static char const* const base32_vernum = "0.9.12"; * * @return an allocated string containing the zbase-32 encoded representation */ -char *zbase32_encode(const unsigned char *data, size_t length); +char *zbase32_encode (const unsigned char *data, size_t length); #endif /* #ifndef __INCL_base32_h */ @@ -44,6 +44,6 @@ char *zbase32_encode(const unsigned char *data, size_t length); * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN + * OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN * THIS SOFTWARE. */ diff --git a/src/ostree/main.c b/src/ostree/main.c index 7d17080..246ff73 100644 --- a/src/ostree/main.c +++ b/src/ostree/main.c @@ -27,7 +27,6 @@ #include #include -#include "ot-main.h" #include "ot-builtins.h" static OstreeCommand commands[] = { @@ -36,99 +35,52 @@ static OstreeCommand commands[] = { * admin command may have their own * admin flag */ - { "admin", OSTREE_BUILTIN_FLAG_NO_REPO, - ostree_builtin_admin, + { "admin", OSTREE_BUILTIN_FLAG_NO_REPO, ostree_builtin_admin, "Commands for managing a host system booted with ostree" }, - { "cat", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_cat, - "Concatenate contents of files"}, - { "checkout", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_checkout, + { "cat", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_cat, "Concatenate contents of files" }, + { "checkout", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_checkout, "Check out a commit into a filesystem tree" }, - { "checksum", OSTREE_BUILTIN_FLAG_NO_REPO, - ostree_builtin_checksum, + { "checksum", OSTREE_BUILTIN_FLAG_NO_REPO, ostree_builtin_checksum, "Checksum a file or directory" }, - { "commit", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_commit, - "Commit a new revision" }, - { "config", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_config, + { "commit", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_commit, "Commit a new revision" }, + { "config", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_config, "Change repo configuration settings" }, - { "diff", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_diff, - "Compare directory TARGETDIR against revision REV"}, - { "export", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_export, + { "diff", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_diff, + "Compare directory TARGETDIR against revision REV" }, + { "export", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_export, "Stream COMMIT to stdout in tar format" }, - { "find-remotes", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_find_remotes, + { "find-remotes", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_find_remotes, "Find remotes to serve the given refs" }, - { "create-usb", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_create_usb, + { "create-usb", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_create_usb, "Copy the refs to a USB stick" }, - { "fsck", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_fsck, - "Check the repository for consistency" }, + { "fsck", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_fsck, "Check the repository for consistency" }, #ifndef OSTREE_DISABLE_GPGME - { "gpg-sign", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_gpg_sign, - "Sign a commit" }, + { "gpg-sign", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_gpg_sign, "Sign a commit" }, #endif /* OSTREE_DISABLE_GPGME */ - { "init", OSTREE_BUILTIN_FLAG_NO_CHECK, - ostree_builtin_init, + { "init", OSTREE_BUILTIN_FLAG_NO_CHECK, ostree_builtin_init, "Initialize a new empty repository" }, - { "log", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_log, - "Show log starting at commit or ref" }, - { "ls", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_ls, - "List file paths" }, - { "prune", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_prune, - "Search for unreachable objects" }, - { "pull-local", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_pull_local, - "Copy data from SRC_REPO" }, + { "log", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_log, "Show log starting at commit or ref" }, + { "ls", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_ls, "List file paths" }, + { "prune", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_prune, "Search for unreachable objects" }, + { "pull-local", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_pull_local, "Copy data from SRC_REPO" }, #ifdef HAVE_LIBCURL_OR_LIBSOUP - { "pull", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_pull, - "Download data from remote repository" }, + { "pull", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_pull, "Download data from remote repository" }, #endif - { "refs", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_refs, - "List refs" }, - { "remote", OSTREE_BUILTIN_FLAG_NO_REPO, - ostree_builtin_remote, + { "refs", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_refs, "List refs" }, + { "remote", OSTREE_BUILTIN_FLAG_NO_REPO, ostree_builtin_remote, "Remote commands that may involve internet access" }, - { "reset", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_reset, - "Reset a REF to a previous COMMIT" }, - { "rev-parse", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_rev_parse, - "Output the target of a rev" }, - { "sign", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_sign, - "Sign a commit" }, - { "show", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_show, - "Output a metadata object" }, - { "static-delta", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_static_delta, + { "reset", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_reset, "Reset a REF to a previous COMMIT" }, + { "rev-parse", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_rev_parse, "Output the target of a rev" }, + { "sign", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_sign, "Sign a commit" }, + { "show", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_show, "Output a metadata object" }, + { "static-delta", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_static_delta, "Static delta related commands" }, - { "summary", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_summary, - "Manage summary metadata" }, -#if defined(HAVE_LIBSOUP) && defined(BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE) - { "trivial-httpd", OSTREE_BUILTIN_FLAG_NONE, - ostree_builtin_trivial_httpd, - NULL }, -#endif + { "summary", OSTREE_BUILTIN_FLAG_NONE, ostree_builtin_summary, "Manage summary metadata" }, { NULL } }; int -main (int argc, - char **argv) +main (int argc, char **argv) { g_assert (argc > 0); diff --git a/src/ostree/ostree-trivial-httpd.c b/src/ostree/ostree-trivial-httpd.c index 6f038e9..facc152 100644 --- a/src/ostree/ostree-trivial-httpd.c +++ b/src/ostree/ostree-trivial-httpd.c @@ -23,16 +23,32 @@ #include -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" -#include #include -#include -#include +#include #include +#include +#include + +#if !SOUP_CHECK_VERSION(3, 0, 0) +#define SoupServerMessage SoupMessage +#define soup_server_message_get_method(msg) ((msg)->method) +#define soup_server_message_get_request_headers(msg) ((msg)->request_headers) +#define soup_server_message_get_response_headers(msg) ((msg)->response_headers) +#define soup_server_message_get_response_body(msg) ((msg)->response_body) +#define soup_server_message_set_status(msg, status) soup_message_set_status (msg, status) +#define soup_server_message_set_redirect(msg, status, uri) \ + soup_message_set_redirect (msg, status, uri) +#define soup_server_message_set_response(msg, ct, ru, rb, rl) \ + soup_message_set_response (msg, ct, ru, rb, rl) +#else +#define soup_server_message_set_status(msg, status) \ + soup_server_message_set_status (msg, status, NULL) +#endif static char *opt_port_file = NULL; static char *opt_log = NULL; @@ -53,7 +69,8 @@ static gboolean opt_require_basic_auth; static guint emitted_random_500s_count = 0; static guint emitted_random_408s_count = 0; -typedef struct { +typedef struct +{ int root_dfd; gboolean running; GOutputStream *log; @@ -64,30 +81,41 @@ typedef struct { * man page (man/ostree-trivial-httpd.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "daemonize", 'd', 0, G_OPTION_ARG_NONE, &opt_daemonize, "Fork into background when ready", NULL }, - { "autoexit", 0, 0, G_OPTION_ARG_NONE, &opt_autoexit, "Automatically exit when directory is deleted", NULL }, - { "port", 'P', 0, G_OPTION_ARG_INT, &opt_port, "Use the specified TCP port", "PORT" }, - { "port-file", 'p', 0, G_OPTION_ARG_FILENAME, &opt_port_file, "Write port number to PATH (- for standard output)", "PATH" }, - { "force-range-requests", 0, 0, G_OPTION_ARG_NONE, &opt_force_ranges, "Force range requests by only serving half of files", NULL }, - { "require-basic-auth", 0, 0, G_OPTION_ARG_NONE, &opt_require_basic_auth, "Require username foouser, password barpw", NULL }, - { "random-500s", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_percentage, "Generate random HTTP 500 errors approximately for PERCENTAGE requests", "PERCENTAGE" }, - { "random-500s-max", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_max, "Limit HTTP 500 errors to MAX (default 100)", "MAX" }, - { "random-408s", 0, 0, G_OPTION_ARG_INT, &opt_random_408s_percentage, "Generate random HTTP 408 errors approximately for PERCENTAGE requests", "PERCENTAGE" }, - { "random-408s-max", 0, 0, G_OPTION_ARG_INT, &opt_random_408s_max, "Limit HTTP 408 errors to MAX (default 100)", "MAX" }, - { "log-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_log, "Put logs here (use - for stdout)", "PATH" }, - { "expected-cookies", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_cookies, "Expect given cookies in the http request", "KEY=VALUE" }, - { "expected-header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_headers, "Expect given headers in the http request", "KEY=VALUE" }, - { NULL } -}; - -static void -httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) __attribute__ ((format(printf, 2, 3))); +static GOptionEntry options[] + = { { "daemonize", 'd', 0, G_OPTION_ARG_NONE, &opt_daemonize, "Fork into background when ready", + NULL }, + { "autoexit", 0, 0, G_OPTION_ARG_NONE, &opt_autoexit, + "Automatically exit when directory is deleted", NULL }, + { "port", 'P', 0, G_OPTION_ARG_INT, &opt_port, "Use the specified TCP port", "PORT" }, + { "port-file", 'p', 0, G_OPTION_ARG_FILENAME, &opt_port_file, + "Write port number to PATH (- for standard output)", "PATH" }, + { "force-range-requests", 0, 0, G_OPTION_ARG_NONE, &opt_force_ranges, + "Force range requests by only serving half of files", NULL }, + { "require-basic-auth", 0, 0, G_OPTION_ARG_NONE, &opt_require_basic_auth, + "Require username foouser, password barpw", NULL }, + { "random-500s", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_percentage, + "Generate random HTTP 500 errors approximately for PERCENTAGE requests", "PERCENTAGE" }, + { "random-500s-max", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_max, + "Limit HTTP 500 errors to MAX (default 100)", "MAX" }, + { "random-408s", 0, 0, G_OPTION_ARG_INT, &opt_random_408s_percentage, + "Generate random HTTP 408 errors approximately for PERCENTAGE requests", "PERCENTAGE" }, + { "random-408s-max", 0, 0, G_OPTION_ARG_INT, &opt_random_408s_max, + "Limit HTTP 408 errors to MAX (default 100)", "MAX" }, + { "log-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_log, "Put logs here (use - for stdout)", + "PATH" }, + { "expected-cookies", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_cookies, + "Expect given cookies in the http request", "KEY=VALUE" }, + { "expected-header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_headers, + "Expect given headers in the http request", "KEY=VALUE" }, + { NULL } }; + +static void httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) + __attribute__ ((format (printf, 2, 3))); static void httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) { - g_autoptr(GString) str = NULL; + g_autoptr (GString) str = NULL; va_list args; gsize written; @@ -95,7 +123,7 @@ httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) return; { - g_autoptr(GDateTime) now = g_date_time_new_now_local (); + g_autoptr (GDateTime) now = g_date_time_new_now_local (); g_autofree char *timestamp = g_date_time_format (now, "%F %T"); str = g_string_new (timestamp); g_string_append_printf (str, ".%06d - ", g_date_time_get_microsecond (now)); @@ -118,12 +146,13 @@ compare_strings (gconstpointer a, gconstpointer b) } static GString * -get_directory_listing (int dfd, - const char *path) +get_directory_listing (int dfd, const char *path) { - g_autoptr(GPtrArray) entries = g_ptr_array_new_with_free_func (g_free); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - g_autoptr(GError) local_error = NULL; + g_autoptr (GPtrArray) entries = g_ptr_array_new_with_free_func (g_free); + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; guint i; char *escaped; @@ -156,13 +185,12 @@ get_directory_listing (int dfd, g_free (escaped); for (i = 0; i < entries->len; i++) { - g_string_append_printf (listing, "%s
    \r\n", - (char *)entries->pdata[i], + g_string_append_printf (listing, "%s
    \r\n", (char *)entries->pdata[i], (char *)entries->pdata[i]); g_free (g_steal_pointer (&entries->pdata[i])); } g_string_append (listing, "\r\n\r\n"); - out: +out: if (local_error) g_printerr ("%s\n", local_error->message); return listing; @@ -188,15 +216,12 @@ is_safe_to_access (struct stat *stbuf) } static void -close_socket (SoupMessage *msg, gpointer user_data) +close_socket (SoupServerMessage *msg, gpointer user_data) { - SoupSocket *sock = user_data; + GSocket *sock = user_data; int sockfd; - /* Actually calling soup_socket_disconnect() here would cause - * us to leak memory, so just shutdown the socket instead. - */ - sockfd = soup_socket_get_fd (sock); + sockfd = g_socket_get_fd (sock); #ifdef G_OS_WIN32 shutdown (sockfd, SD_SEND); #else @@ -208,17 +233,54 @@ close_socket (SoupMessage *msg, gpointer user_data) static gchar * calculate_etag (GMappedFile *mapping) { - g_autoptr(GBytes) bytes = g_mapped_file_get_bytes (mapping); + g_autoptr (GBytes) bytes = g_mapped_file_get_bytes (mapping); g_autofree gchar *checksum = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, bytes); return g_strconcat ("\"", checksum, "\"", NULL); } +static GSList * +_server_cookies_from_request (SoupServerMessage *msg) +{ + SoupCookie *cookie; + GSList *cookies = NULL; + GHashTable *params; + GHashTableIter iter; + gpointer name, value; + const char *header; + const char *host; + + header = soup_message_headers_get_one (soup_server_message_get_request_headers (msg), "Cookie"); + if (!header) + return NULL; + +#if !SOUP_CHECK_VERSION(3, 0, 0) + host = soup_uri_get_host (soup_message_get_uri (msg)); +#else + host = g_uri_get_host (soup_server_message_get_uri (msg)); +#endif + params = soup_header_parse_semi_param_list (header); + g_hash_table_iter_init (&iter, params); + + while (g_hash_table_iter_next (&iter, &name, &value)) + { + if (!name || !value) + continue; + cookie = soup_cookie_new (name, value, host, NULL, 0); + cookies = g_slist_prepend (cookies, cookie); + } + + soup_header_free_param_list (params); + + return g_slist_reverse (cookies); +} + static void -do_get (OtTrivialHttpd *self, - SoupServer *server, - SoupMessage *msg, - const char *path, +#if !SOUP_CHECK_VERSION(3, 0, 0) +do_get (OtTrivialHttpd *self, SoupServer *server, SoupServerMessage *msg, const char *path, SoupClientContext *context) +#else +do_get (OtTrivialHttpd *self, SoupServer *server, SoupServerMessage *msg, const char *path) +#endif { char *slash; int ret; @@ -228,22 +290,22 @@ do_get (OtTrivialHttpd *self, if (opt_expected_cookies) { - GSList *cookies = soup_cookies_from_request (msg); + GSList *cookies = _server_cookies_from_request (msg); GSList *l; int i; - for (i = 0 ; opt_expected_cookies[i] != NULL; i++) + for (i = 0; opt_expected_cookies[i] != NULL; i++) { gboolean found = FALSE; gchar *k = opt_expected_cookies[i]; gchar *v = strchr (k, '=') + 1; - for (l = cookies; l != NULL ; l = g_slist_next (l)) + for (l = cookies; l != NULL; l = g_slist_next (l)) { SoupCookie *c = l->data; - if (!strncmp (k, soup_cookie_get_name (c), v - k - 1) && - !strcmp (v, soup_cookie_get_value (c))) + if (!strncmp (k, soup_cookie_get_name (c), v - k - 1) + && !strcmp (v, soup_cookie_get_value (c))) { found = TRUE; break; @@ -253,17 +315,17 @@ do_get (OtTrivialHttpd *self, if (!found) { httpd_log (self, "Expected cookie not found %s\n", k); - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - soup_cookies_free (cookies); + soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + g_slist_free_full (cookies, (GDestroyNotify)soup_cookie_free); goto out; } } - soup_cookies_free (cookies); + g_slist_free_full (cookies, (GDestroyNotify)soup_cookie_free); } if (opt_expected_headers) { - for (int i = 0 ; opt_expected_headers[i] != NULL; i++) + for (int i = 0; opt_expected_headers[i] != NULL; i++) { const gchar *kv = opt_expected_headers[i]; const gchar *eq = strchr (kv, '='); @@ -273,18 +335,19 @@ do_get (OtTrivialHttpd *self, { g_autofree char *k = g_strndup (kv, eq - kv); const gchar *expected_v = eq + 1; - const gchar *found_v = soup_message_headers_get_one (msg->request_headers, k); + const gchar *found_v + = soup_message_headers_get_one (soup_server_message_get_request_headers (msg), k); if (!found_v) { httpd_log (self, "Expected header not found %s\n", k); - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN); goto out; } if (strcmp (found_v, expected_v) != 0) { httpd_log (self, "Expected header %s: %s but found %s\n", k, expected_v, found_v); - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN); goto out; } } @@ -293,24 +356,22 @@ do_get (OtTrivialHttpd *self, if (strstr (path, "../") != NULL) { - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN); goto out; } - if (opt_random_500s_percentage > 0 && - emitted_random_500s_count < opt_random_500s_max && - g_random_int_range (0, 100) < opt_random_500s_percentage) + if (opt_random_500s_percentage > 0 && emitted_random_500s_count < opt_random_500s_max + && g_random_int_range (0, 100) < opt_random_500s_percentage) { emitted_random_500s_count++; - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); goto out; } - else if (opt_random_408s_percentage > 0 && - emitted_random_408s_count < opt_random_408s_max && - g_random_int_range (0, 100) < opt_random_408s_percentage) + else if (opt_random_408s_percentage > 0 && emitted_random_408s_count < opt_random_408s_max + && g_random_int_range (0, 100) < opt_random_408s_percentage) { emitted_random_408s_count++; - soup_message_set_status (msg, SOUP_STATUS_REQUEST_TIMEOUT); + soup_server_message_set_status (msg, SOUP_STATUS_REQUEST_TIMEOUT); goto out; } @@ -323,17 +384,17 @@ do_get (OtTrivialHttpd *self, if (ret == -1) { if (errno == EPERM) - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN); else if (errno == ENOENT) - soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); + soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND); else - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); goto out; } if (!is_safe_to_access (&stbuf)) { - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN); goto out; } @@ -344,9 +405,12 @@ do_get (OtTrivialHttpd *self, { g_autofree char *redir_uri = NULL; - redir_uri = g_strdup_printf ("%s/", soup_message_get_uri (msg)->path); - soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, - redir_uri); +#if !SOUP_CHECK_VERSION(3, 0, 0) + redir_uri = g_strdup_printf ("%s/", soup_uri_get_path (soup_message_get_uri (msg))); +#else + redir_uri = g_strdup_printf ("%s/", g_uri_get_path (soup_server_message_get_uri (msg))); +#endif + soup_server_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, redir_uri); } else { @@ -354,55 +418,61 @@ do_get (OtTrivialHttpd *self, if (fstatat (self->root_dfd, index_realpath, &stbuf, 0) != -1) { g_autofree char *index_path = g_strconcat (path, "/index.html", NULL); +#if !SOUP_CHECK_VERSION(3, 0, 0) do_get (self, server, msg, index_path, context); +#else + do_get (self, server, msg, index_path); +#endif } else { GString *listing = get_directory_listing (self->root_dfd, path); - soup_message_set_response (msg, "text/html", - SOUP_MEMORY_TAKE, - listing->str, listing->len); - soup_message_set_status (msg, SOUP_STATUS_OK); + soup_server_message_set_response (msg, "text/html", SOUP_MEMORY_TAKE, listing->str, + listing->len); + soup_server_message_set_status (msg, SOUP_STATUS_OK); g_string_free (listing, FALSE); } } } - else + else { if (!S_ISREG (stbuf.st_mode)) { - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN); goto out; } glnx_autofd int fd = openat (self->root_dfd, path, O_RDONLY | O_CLOEXEC); if (fd < 0) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); goto out; } - g_autoptr(GMappedFile) mapping = g_mapped_file_new_from_fd (fd, FALSE, NULL); + g_autoptr (GMappedFile) mapping = g_mapped_file_new_from_fd (fd, FALSE, NULL); if (!mapping) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); goto out; } - (void) close (fd); fd = -1; + (void)close (fd); + fd = -1; /* Send caching headers */ - g_autoptr(GDateTime) last_modified = g_date_time_new_from_unix_utc (stbuf.st_mtim.tv_sec); + g_autoptr (GDateTime) last_modified = g_date_time_new_from_unix_utc (stbuf.st_mtim.tv_sec); if (last_modified != NULL) { - g_autofree gchar *formatted = g_date_time_format (last_modified, "%a, %d %b %Y %H:%M:%S GMT"); - soup_message_headers_append (msg->response_headers, "Last-Modified", formatted); + g_autofree gchar *formatted + = g_date_time_format (last_modified, "%a, %d %b %Y %H:%M:%S GMT"); + soup_message_headers_append (soup_server_message_get_response_headers (msg), + "Last-Modified", formatted); } g_autofree gchar *etag = calculate_etag (mapping); if (etag != NULL) - soup_message_headers_append (msg->response_headers, "ETag", etag); - - if (msg->method == SOUP_METHOD_GET) + soup_message_headers_append (soup_server_message_get_response_headers (msg), "ETag", etag); + + if (!strcmp (soup_server_message_get_method (msg), "GET")) { gsize buffer_length, file_size; SoupRange *ranges; @@ -410,13 +480,15 @@ do_get (OtTrivialHttpd *self, gboolean have_ranges; file_size = g_mapped_file_get_length (mapping); - have_ranges = soup_message_headers_get_ranges(msg->request_headers, file_size, &ranges, &ranges_length); + have_ranges = soup_message_headers_get_ranges ( + soup_server_message_get_request_headers (msg), file_size, &ranges, &ranges_length); if (opt_force_ranges && !have_ranges && g_strrstr (path, "/objects") != NULL) { - SoupSocket *sock; - buffer_length = file_size/2; - soup_message_headers_set_content_length (msg->response_headers, file_size); - soup_message_headers_append (msg->response_headers, + GSocket *sock; + buffer_length = file_size / 2; + soup_message_headers_set_content_length ( + soup_server_message_get_response_headers (msg), file_size); + soup_message_headers_append (soup_server_message_get_response_headers (msg), "Connection", "close"); /* soup-message-io will wait for us to add @@ -424,7 +496,11 @@ do_get (OtTrivialHttpd *self, * the declared Content-Length. Instead, we * forcibly close the socket at that point. */ - sock = soup_client_context_get_socket (context); +#if !SOUP_CHECK_VERSION(3, 0, 0) + sock = soup_client_context_get_gsocket (context); +#else + sock = soup_server_message_get_socket (msg); +#endif g_signal_connect (msg, "wrote-chunk", G_CALLBACK (close_socket), sock); } else @@ -434,25 +510,41 @@ do_get (OtTrivialHttpd *self, { if (ranges_length > 0 && ranges[0].start >= file_size) { - soup_message_set_status (msg, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE); - soup_message_headers_free_ranges (msg->request_headers, ranges); + soup_server_message_set_status (msg, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE); + soup_message_headers_free_ranges (soup_server_message_get_request_headers (msg), + ranges); goto out; } - soup_message_headers_free_ranges (msg->request_headers, ranges); + soup_message_headers_free_ranges (soup_server_message_get_request_headers (msg), + ranges); } +#if !SOUP_CHECK_VERSION(3, 0, 0) if (buffer_length > 0) { SoupBuffer *buffer; buffer = soup_buffer_new_with_owner (g_mapped_file_get_contents (mapping), - buffer_length, - g_mapped_file_ref (mapping), + buffer_length, g_mapped_file_ref (mapping), (GDestroyNotify)g_mapped_file_unref); soup_message_body_append_buffer (msg->response_body, buffer); soup_buffer_free (buffer); } +#else + if (buffer_length > 0 && buffer_length == file_size) + { + GBytes *bytes = g_mapped_file_get_bytes (mapping); + soup_message_body_append_bytes (soup_server_message_get_response_body (msg), bytes); + g_bytes_unref (bytes); + } + else if (buffer_length > 0) + { + gchar *contents = g_mapped_file_get_contents (mapping); + soup_message_body_append (soup_server_message_get_response_body (msg), + SOUP_MEMORY_COPY, contents, buffer_length); + } +#endif } - else /* msg->method == SOUP_METHOD_HEAD */ + else /* method == HEAD */ { g_autofree char *length = NULL; @@ -461,93 +553,105 @@ do_get (OtTrivialHttpd *self, * But we'll optimize and avoid the extra I/O. */ length = g_strdup_printf ("%lu", (gulong)stbuf.st_size); - soup_message_headers_append (msg->response_headers, + soup_message_headers_append (soup_server_message_get_response_headers (msg), "Content-Length", length); } /* Check client’s caching headers. */ - const gchar *if_modified_since = soup_message_headers_get_one (msg->request_headers, - "If-Modified-Since"); - const gchar *if_none_match = soup_message_headers_get_one (msg->request_headers, - "If-None-Match"); + const gchar *if_modified_since = soup_message_headers_get_one ( + soup_server_message_get_request_headers (msg), "If-Modified-Since"); + const gchar *if_none_match = soup_message_headers_get_one ( + soup_server_message_get_request_headers (msg), "If-None-Match"); if (if_none_match != NULL && etag != NULL) { if (g_strcmp0 (etag, if_none_match) == 0) { - soup_message_set_status (msg, SOUP_STATUS_NOT_MODIFIED); - soup_message_body_truncate (msg->response_body); + soup_server_message_set_status (msg, SOUP_STATUS_NOT_MODIFIED); + soup_message_body_truncate (soup_server_message_get_response_body (msg)); } else { - soup_message_set_status (msg, SOUP_STATUS_OK); + soup_server_message_set_status (msg, SOUP_STATUS_OK); } } else if (if_modified_since != NULL && last_modified != NULL) { + g_autoptr (GDateTime) if_modified_since_dt = NULL; +#if !SOUP_CHECK_VERSION(3, 0, 0) SoupDate *if_modified_since_sd = soup_date_new_from_string (if_modified_since); - g_autoptr(GDateTime) if_modified_since_dt = NULL; if (if_modified_since_sd != NULL) - if_modified_since_dt = g_date_time_new_from_unix_utc (soup_date_to_time_t (if_modified_since_sd)); + if_modified_since_dt + = g_date_time_new_from_unix_utc (soup_date_to_time_t (if_modified_since_sd)); +#else + if_modified_since_dt = soup_date_time_new_from_http_string (if_modified_since); +#endif - if (if_modified_since_dt != NULL && - g_date_time_compare (last_modified, if_modified_since_dt) <= 0) + if (if_modified_since_dt != NULL + && g_date_time_compare (last_modified, if_modified_since_dt) <= 0) { - soup_message_set_status (msg, SOUP_STATUS_NOT_MODIFIED); - soup_message_body_truncate (msg->response_body); + soup_server_message_set_status (msg, SOUP_STATUS_NOT_MODIFIED); + soup_message_body_truncate (soup_server_message_get_response_body (msg)); } else { - soup_message_set_status (msg, SOUP_STATUS_OK); + soup_server_message_set_status (msg, SOUP_STATUS_OK); } - - g_clear_pointer (&if_modified_since_sd, soup_date_free); } else { - soup_message_set_status (msg, SOUP_STATUS_OK); + soup_server_message_set_status (msg, SOUP_STATUS_OK); } } - out: +out: { +#if !SOUP_CHECK_VERSION(3, 0, 0) guint status = 0; g_autofree gchar *reason = NULL; - g_object_get (msg, - "status-code", &status, - "reason-phrase", &reason, - NULL); + g_object_get (msg, "status-code", &status, "reason-phrase", &reason, NULL); +#else + guint status = soup_server_message_get_status (msg); + const char *reason = soup_server_message_get_reason_phrase (msg); +#endif + httpd_log (self, " status: %s (%u)\n", reason, status); } return; } static void -httpd_callback (SoupServer *server, SoupMessage *msg, - const char *path, GHashTable *query, +#if !SOUP_CHECK_VERSION(3, 0, 0) +httpd_callback (SoupServer *server, SoupServerMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) +#else +httpd_callback (SoupServer *server, SoupServerMessage *msg, const char *path, GHashTable *query, + gpointer data) +#endif { OtTrivialHttpd *self = data; + const char *meth = soup_server_message_get_method (msg); - if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD) + if (!strcmp (meth, "GET") || !strcmp (meth, "HEAD")) +#if !SOUP_CHECK_VERSION(3, 0, 0) do_get (self, server, msg, path, context); +#else + do_get (self, server, msg, path); +#endif else - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); } static gboolean -basic_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg, - const char *username, const char *password, gpointer data) +basic_auth_callback (SoupAuthDomain *auth_domain, SoupServerMessage *msg, const char *username, + const char *password, gpointer data) { - return g_str_equal (username, "foouser") && g_str_equal (password, "barpw"); + return g_str_equal (username, "foouser") && g_str_equal (password, "barpw"); } static void -on_dir_changed (GFileMonitor *mon, - GFile *file, - GFile *other, - GFileMonitorEvent event, +on_dir_changed (GFileMonitor *mon, GFile *file, GFile *other, GFileMonitorEvent event, gpointer user_data) { OtTrivialHttpd *self = user_data; @@ -564,13 +668,15 @@ static gboolean run (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GOptionContext) context = NULL; + g_autoptr (GOptionContext) context = NULL; const char *dirpath; - OtTrivialHttpd appstruct = { 0, }; + OtTrivialHttpd appstruct = { + 0, + }; OtTrivialHttpd *app = &appstruct; int pipefd[2] = { -1, -1 }; glnx_unref_object SoupServer *server = NULL; - g_autoptr(GFileMonitor) dirmon = NULL; + g_autoptr (GFileMonitor) dirmon = NULL; context = g_option_context_new ("[DIR] - Simple webserver"); g_option_context_add_main_entries (context, options, NULL); @@ -590,21 +696,22 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) if (!(opt_random_500s_percentage >= 0 && opt_random_500s_percentage <= 99)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid --random-500s=%u", opt_random_500s_percentage); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid --random-500s=%u", + opt_random_500s_percentage); goto out; } if (!(opt_random_408s_percentage >= 0 && opt_random_408s_percentage <= 99)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid --random-408s=%u", opt_random_408s_percentage); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid --random-408s=%u", + opt_random_408s_percentage); goto out; } if (opt_daemonize && (g_strcmp0 (opt_log, "-") == 0)) { - ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error); + ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", + error); goto out; } @@ -621,7 +728,7 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) goto out; } - pid_t pid = fork(); + pid_t pid = fork (); if (pid == -1) { glnx_set_error_from_errno (error); @@ -686,14 +793,11 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) } else { - g_autoptr(GFile) log_file = NULL; - GFileOutputStream* log_stream; + g_autoptr (GFile) log_file = NULL; + GFileOutputStream *log_stream; log_file = g_file_new_for_path (opt_log); - log_stream = g_file_create (log_file, - G_FILE_CREATE_PRIVATE, - cancellable, - error); + log_stream = g_file_create (log_file, G_FILE_CREATE_PRIVATE, cancellable, error); if (!log_stream) goto out; stream = G_OUTPUT_STREAM (log_stream); @@ -703,21 +807,26 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) } #if SOUP_CHECK_VERSION(2, 48, 0) - server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); + server = soup_server_new ("server-header", "ostree-httpd ", NULL); if (!soup_server_listen_all (server, opt_port, 0, error)) goto out; #else - server = soup_server_new (SOUP_SERVER_PORT, opt_port, - SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", + server = soup_server_new (SOUP_SERVER_PORT, opt_port, SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); #endif + if (opt_require_basic_auth) { - glnx_unref_object SoupAuthDomain *auth_domain = - soup_auth_domain_basic_new (SOUP_AUTH_DOMAIN_REALM, "auth-test", - SOUP_AUTH_DOMAIN_ADD_PATH, "/", - SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, basic_auth_callback, - NULL); +#if !SOUP_CHECK_VERSION(3, 0, 0) + glnx_unref_object SoupAuthDomain *auth_domain = soup_auth_domain_basic_new ( + SOUP_AUTH_DOMAIN_REALM, "auth-test", SOUP_AUTH_DOMAIN_ADD_PATH, "/", + SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, basic_auth_callback, NULL); +#else + glnx_unref_object SoupAuthDomain *auth_domain + = soup_auth_domain_basic_new ("realm", "auth-test", NULL); + soup_auth_domain_add_path (auth_domain, "/"); + soup_auth_domain_basic_set_auth_callback (auth_domain, basic_auth_callback, NULL, NULL); +#endif soup_server_add_auth_domain (server, auth_domain); } @@ -727,9 +836,9 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) g_autofree char *portstr = NULL; #if SOUP_CHECK_VERSION(2, 48, 0) GSList *listeners = soup_server_get_listeners (server); - g_autoptr(GSocket) listener = NULL; - g_autoptr(GSocketAddress) addr = NULL; - + g_autoptr (GSocket) listener = NULL; + g_autoptr (GSocketAddress) addr = NULL; + g_assert (listeners); listener = g_object_ref (listeners->data); g_slist_free (listeners); @@ -739,8 +848,9 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) goto out; g_assert (G_IS_INET_SOCKET_ADDRESS (addr)); - - portstr = g_strdup_printf ("%u\n", g_inet_socket_address_get_port ((GInetSocketAddress*)addr)); + + portstr + = g_strdup_printf ("%u\n", g_inet_socket_address_get_port ((GInetSocketAddress *)addr)); #else portstr = g_strdup_printf ("%u\n", soup_server_get_port (server)); #endif @@ -775,17 +885,17 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) goto out; } /* Daemonising: close stdout/stderr so $() et al work on us */ - if (freopen("/dev/null", "r", stdin) == NULL) + if (freopen ("/dev/null", "r", stdin) == NULL) { glnx_set_prefix_error_from_errno (error, "%s", "freopen: "); goto out; } - if (freopen("/dev/null", "w", stdout) == NULL) + if (freopen ("/dev/null", "w", stdout) == NULL) { glnx_set_prefix_error_from_errno (error, "%s", "freopen: "); goto out; } - if (freopen("/dev/null", "w", stderr) == NULL) + if (freopen ("/dev/null", "w", stderr) == NULL) { glnx_set_prefix_error_from_errno (error, "%s", "freopen: "); goto out; @@ -796,14 +906,12 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) if (opt_autoexit) { gboolean is_symlink = FALSE; - g_autoptr(GFile) root = NULL; - g_autoptr(GFileInfo) info = NULL; + g_autoptr (GFile) root = NULL; + g_autoptr (GFileInfo) info = NULL; root = g_file_new_for_path (dirpath); - info = g_file_query_info (root, - G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + info = g_file_query_info (root, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!info) goto out; @@ -823,7 +931,7 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) g_main_context_iteration (NULL, TRUE); ret = TRUE; - out: +out: if (pipefd[0] >= 0) { /* Read end in the parent. This should only be open on errors. */ @@ -836,21 +944,20 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error) g_assert_false (ret); guint8 buf = 1; g_debug ("Writing %u to parent", buf); - (void) TEMP_FAILURE_RETRY (write (pipefd[1], &buf, 1)); + (void)TEMP_FAILURE_RETRY (write (pipefd[1], &buf, 1)); glnx_close_fd (&pipefd[1]); } if (app->root_dfd != -1) - (void) close (app->root_dfd); + (void)close (app->root_dfd); g_clear_object (&app->log); return ret; } int -main (int argc, - char **argv) +main (int argc, char **argv) { - g_autoptr(GError) error = NULL; - g_autoptr(GCancellable) cancellable = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GCancellable) cancellable = NULL; setlocale (LC_ALL, ""); @@ -858,10 +965,8 @@ main (int argc, if (!run (argc, argv, cancellable, &error)) { - g_printerr ("%s%serror:%s%s %s\n", - ot_get_red_start (), ot_get_bold_start (), - ot_get_bold_end (), ot_get_red_end (), - error->message); + g_printerr ("%s%serror:%s%s %s\n", ot_get_red_start (), ot_get_bold_start (), + ot_get_bold_end (), ot_get_red_end (), error->message); return 1; } diff --git a/src/ostree/ot-admin-builtin-boot-complete.c b/src/ostree/ot-admin-builtin-boot-complete.c index 5d50c02..4599606 100644 --- a/src/ostree/ot-admin-builtin-boot-complete.c +++ b/src/ostree/ot-admin-builtin-boot-complete.c @@ -21,20 +21,19 @@ #include -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" #include "ostree-cmd-private.h" -static GOptionEntry options[] = { - { NULL } -}; +static GOptionEntry options[] = { { NULL } }; gboolean -ot_admin_builtin_boot_complete (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_boot_complete (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { /* Just a sanity check; we shouldn't be called outside of the service though. */ @@ -44,14 +43,14 @@ ot_admin_builtin_boot_complete (int argc, char **argv, OstreeCommandInvocation * // We must have been invoked via systemd which should have set up a mount namespace. g_assert (getenv ("INVOCATION_ID")); - g_autoptr(GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (GOptionContext) context = g_option_context_new (""); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) return FALSE; - if (!ostree_cmd__private__()->ostree_boot_complete (sysroot, cancellable, error)) + if (!ostree_cmd__private__ ()->ostree_boot_complete (sysroot, cancellable, error)) return FALSE; return TRUE; diff --git a/src/ostree/ot-admin-builtin-cleanup.c b/src/ostree/ot-admin-builtin-cleanup.c index 94d3224..b2d3423 100644 --- a/src/ostree/ot-admin-builtin-cleanup.c +++ b/src/ostree/ot-admin-builtin-cleanup.c @@ -21,26 +21,25 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include -static GOptionEntry options[] = { - { NULL } -}; +static GOptionEntry options[] = { { NULL } }; gboolean -ot_admin_builtin_cleanup (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_cleanup (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) return FALSE; if (!ostree_sysroot_cleanup (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-builtin-deploy.c b/src/ostree/ot-admin-builtin-deploy.c index 28a5d9e..c0faaab 100644 --- a/src/ostree/ot-admin-builtin-deploy.c +++ b/src/ostree/ot-admin-builtin-deploy.c @@ -23,10 +23,10 @@ #include "ostree-sysroot-private.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" #include @@ -41,7 +41,7 @@ static gboolean opt_no_prune; static gboolean opt_no_merge; static char **opt_kernel_argv; static char **opt_kernel_argv_append; -static char *opt_kernel_argv_delete; +static char **opt_kernel_argv_delete; static gboolean opt_kernel_proc_cmdline; static char *opt_osname; static char *opt_origin_path; @@ -49,35 +49,53 @@ static gboolean opt_kernel_arg_none; static char **opt_overlay_initrds; static GOptionEntry options[] = { - { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, - { "origin-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_origin_path, "Specify origin file", "FILENAME" }, - { "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Don't prune the repo when done", NULL}, - { "no-merge", 0, 0, G_OPTION_ARG_NONE, &opt_no_merge, "Do not apply configuration (/etc and kernel arguments) from booted deployment", NULL}, + { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, + "Use a different operating system root than the current one", "OSNAME" }, + { "stateroot", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Target the provided stateroot", + "STATEROOT" }, + { "origin-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_origin_path, "Specify origin file", + "FILENAME" }, + { "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Don't prune the repo when done", NULL }, + { "no-merge", 0, 0, G_OPTION_ARG_NONE, &opt_no_merge, + "Do not apply configuration (/etc and kernel arguments) from booted deployment", NULL }, { "retain", 0, 0, G_OPTION_ARG_NONE, &opt_retain, "Do not delete previous deployments", NULL }, { "stage", 0, 0, G_OPTION_ARG_NONE, &opt_stage, "Complete deployment at OS shutdown", NULL }, - { "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, "Prevent automatic deployment finalization on shutdown", NULL }, - { "retain-pending", 0, 0, G_OPTION_ARG_NONE, &opt_retain_pending, "Do not delete pending deployments", NULL }, - { "retain-rollback", 0, 0, G_OPTION_ARG_NONE, &opt_retain_rollback, "Do not delete rollback deployments", NULL }, - { "not-as-default", 0, 0, G_OPTION_ARG_NONE, &opt_not_as_default, "Append rather than prepend new deployment", NULL }, - { "karg-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_kernel_proc_cmdline, "Import current /proc/cmdline", NULL }, - { "karg", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv, "Set kernel argument, like root=/dev/sda1; this overrides any earlier argument with the same name", "NAME=VALUE" }, - { "karg-append", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv_append, "Append kernel argument; useful with e.g. console= that can be used multiple times", "NAME=VALUE" }, - { "karg-none", 0, 0, G_OPTION_ARG_NONE, &opt_kernel_arg_none, "Do not import kernel arguments", NULL }, - { "karg-delete", 0, 0, G_OPTION_ARG_STRING, &opt_kernel_argv_delete, "Delete kernel argument if exists", "NAME=VALUE" }, - { "overlay-initrd", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_overlay_initrds, "Overlay iniramfs file", "FILE" }, + { "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, + "Prevent automatic deployment finalization on shutdown", NULL }, + { "retain-pending", 0, 0, G_OPTION_ARG_NONE, &opt_retain_pending, + "Do not delete pending deployments", NULL }, + { "retain-rollback", 0, 0, G_OPTION_ARG_NONE, &opt_retain_rollback, + "Do not delete rollback deployments", NULL }, + { "not-as-default", 0, 0, G_OPTION_ARG_NONE, &opt_not_as_default, + "Append rather than prepend new deployment", NULL }, + { "karg-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_kernel_proc_cmdline, + "Import current /proc/cmdline", NULL }, + { "karg", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv, + "Set kernel argument, like root=/dev/sda1; this overrides any earlier argument with the same " + "name", + "NAME=VALUE" }, + { "karg-append", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv_append, + "Append kernel argument; useful with e.g. console= that can be used multiple times", + "NAME=VALUE" }, + { "karg-none", 0, 0, G_OPTION_ARG_NONE, &opt_kernel_arg_none, "Do not import kernel arguments", + NULL }, + { "karg-delete", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv_delete, + "Delete kernel argument if exists, can be used multiple times", "NAME=VALUE" }, + { "overlay-initrd", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_overlay_initrds, + "Overlay iniramfs file", "FILE" }, { NULL } }; gboolean -ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = - g_option_context_new ("REFSPEC"); + g_autoptr (GOptionContext) context = g_option_context_new ("REFSPEC"); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) return FALSE; if (argc < 2) @@ -88,7 +106,8 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat if (opt_kernel_proc_cmdline && opt_kernel_arg_none) { - ot_util_usage_error (context, "Can't specify both --karg-proc-cmdline and --karg-none", error); + ot_util_usage_error (context, "Can't specify both --karg-proc-cmdline and --karg-none", + error); return FALSE; } @@ -111,11 +130,10 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat /* Find the currently booted deployment, if any; we will ensure it * is present in the new deployment list. */ - if (!ot_admin_require_booted_deployment_or_osname (sysroot, opt_osname, - cancellable, error)) + if (!ot_admin_require_booted_deployment_or_osname (sysroot, opt_osname, cancellable, error)) return glnx_prefix_error (error, "Looking for booted deployment"); - g_autoptr(GKeyFile) origin = NULL; + g_autoptr (GKeyFile) origin = NULL; if (opt_origin_path) { origin = g_key_file_new (); @@ -132,8 +150,8 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat if (!ostree_repo_resolve_rev (repo, refspec, FALSE, &revision, error)) return FALSE; - g_autoptr(OstreeDeployment) merge_deployment = - opt_no_merge ? NULL : ostree_sysroot_get_merge_deployment (sysroot, opt_osname); + g_autoptr (OstreeDeployment) merge_deployment + = opt_no_merge ? NULL : ostree_sysroot_get_merge_deployment (sysroot, opt_osname); /* Here we perform cleanup of any leftover data from previous * partial failures. This avoids having to call @@ -148,7 +166,7 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat /* Initial set of kernel arguments; the default is to use the merge * deployment, unless --karg-none or --karg-proc-cmdline are specified. */ - g_autoptr(OstreeKernelArgs) kargs = NULL; + g_autoptr (OstreeKernelArgs) kargs = NULL; if (opt_kernel_arg_none) { kargs = ostree_kernel_args_new (); @@ -159,10 +177,12 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat if (!ostree_kernel_args_append_proc_cmdline (kargs, cancellable, error)) return FALSE; } - else if (merge_deployment && (opt_kernel_argv || opt_kernel_argv_append || opt_kernel_argv_delete)) + else if (merge_deployment + && (opt_kernel_argv || opt_kernel_argv_append || opt_kernel_argv_delete)) { OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment); - g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); + g_auto (GStrv) previous_args + = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); kargs = ostree_kernel_args_new (); ostree_kernel_args_append_argv (kargs, previous_args); } @@ -185,13 +205,14 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat ostree_kernel_args_append_argv (kargs, opt_kernel_argv_append); } - if (opt_kernel_argv_delete) + for (char **strviter = opt_kernel_argv_delete; strviter && *strviter; strviter++) { - if (!ostree_kernel_args_delete (kargs, opt_kernel_argv_delete, error)) + const char *arg = *strviter; + if (!ostree_kernel_args_delete_if_present (kargs, arg, error)) return FALSE; } - g_autoptr(GPtrArray) overlay_initrd_chksums = NULL; + g_autoptr (GPtrArray) overlay_initrd_chksums = NULL; for (char **it = opt_overlay_initrds; it && *it; it++) { const char *path = *it; @@ -212,14 +233,14 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat if (overlay_initrd_chksums) g_ptr_array_add (overlay_initrd_chksums, NULL); - g_auto(GStrv) kargs_strv = kargs ? ostree_kernel_args_to_strv (kargs) : NULL; + g_auto (GStrv) kargs_strv = kargs ? ostree_kernel_args_to_strv (kargs) : NULL; OstreeSysrootDeployTreeOpts opts = { .override_kernel_argv = kargs_strv, - .overlay_initrds = overlay_initrd_chksums ? (char**)overlay_initrd_chksums->pdata : NULL, + .overlay_initrds = overlay_initrd_chksums ? (char **)overlay_initrd_chksums->pdata : NULL, }; - g_autoptr(OstreeDeployment) new_deployment = NULL; + g_autoptr (OstreeDeployment) new_deployment = NULL; if (opt_stage) { if (opt_retain_pending || opt_retain_rollback) @@ -243,16 +264,15 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat /* use old API if we can to exercise it in CI */ if (!overlay_initrd_chksums) { - if (!ostree_sysroot_stage_tree (sysroot, opt_osname, revision, origin, - merge_deployment, kargs_strv, &new_deployment, - cancellable, error)) + if (!ostree_sysroot_stage_tree (sysroot, opt_osname, revision, origin, merge_deployment, + kargs_strv, &new_deployment, cancellable, error)) return FALSE; } else { - if (!ostree_sysroot_stage_tree_with_options (sysroot, opt_osname, revision, - origin, merge_deployment, &opts, - &new_deployment, cancellable, error)) + if (!ostree_sysroot_stage_tree_with_options (sysroot, opt_osname, revision, origin, + merge_deployment, &opts, &new_deployment, + cancellable, error)) return FALSE; } g_assert (new_deployment); @@ -262,22 +282,21 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat /* use old API if we can to exercise it in CI */ if (!overlay_initrd_chksums) { - if (!ostree_sysroot_deploy_tree (sysroot, opt_osname, revision, origin, - merge_deployment, kargs_strv, &new_deployment, - cancellable, error)) + if (!ostree_sysroot_deploy_tree (sysroot, opt_osname, revision, origin, merge_deployment, + kargs_strv, &new_deployment, cancellable, error)) return FALSE; } else { - if (!ostree_sysroot_deploy_tree_with_options (sysroot, opt_osname, revision, - origin, merge_deployment, &opts, - &new_deployment, cancellable, - error)) + if (!ostree_sysroot_deploy_tree_with_options (sysroot, opt_osname, revision, origin, + merge_deployment, &opts, &new_deployment, + cancellable, error)) return FALSE; } g_assert (new_deployment); - OstreeSysrootSimpleWriteDeploymentFlags flags = OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN; + OstreeSysrootSimpleWriteDeploymentFlags flags + = OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN; if (opt_retain) flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN; else diff --git a/src/ostree/ot-admin-builtin-diff.c b/src/ostree/ot-admin-builtin-diff.c index 73e49d4..8a123a2 100644 --- a/src/ostree/ot-admin-builtin-diff.c +++ b/src/ostree/ot-admin-builtin-diff.c @@ -21,58 +21,59 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include static char *opt_osname; -static GOptionEntry options[] = { - { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, - { NULL } -}; +static GOptionEntry options[] + = { { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, + "Use a different operating system root than the current one", "OSNAME" }, + { NULL } }; gboolean -ot_admin_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER + | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, invocation, &sysroot, cancellable, error)) return FALSE; - if (!ot_admin_require_booted_deployment_or_osname (sysroot, opt_osname, - cancellable, error)) + if (!ot_admin_require_booted_deployment_or_osname (sysroot, opt_osname, cancellable, error)) return FALSE; - g_autoptr(OstreeDeployment) deployment = NULL; + g_autoptr (OstreeDeployment) deployment = NULL; if (opt_osname != NULL) { deployment = ostree_sysroot_get_merge_deployment (sysroot, opt_osname); if (deployment == NULL) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No deployment for OS '%s'", opt_osname); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No deployment for OS '%s'", + opt_osname); return FALSE; } } else deployment = g_object_ref (ostree_sysroot_get_booted_deployment (sysroot)); - g_autoptr(GFile) deployment_dir = ostree_sysroot_get_deployment_directory (sysroot, deployment); - g_autoptr(GFile) orig_etc_path = g_file_resolve_relative_path (deployment_dir, "usr/etc"); - g_autoptr(GFile) new_etc_path = g_file_resolve_relative_path (deployment_dir, "etc"); - g_autoptr(GPtrArray) modified = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_diff_item_unref); - g_autoptr(GPtrArray) removed = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - g_autoptr(GPtrArray) added = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - if (!ostree_diff_dirs (OSTREE_DIFF_FLAGS_IGNORE_XATTRS, - orig_etc_path, new_etc_path, modified, removed, added, - cancellable, error)) + g_autoptr (GFile) deployment_dir = ostree_sysroot_get_deployment_directory (sysroot, deployment); + g_autoptr (GFile) orig_etc_path = g_file_resolve_relative_path (deployment_dir, "usr/etc"); + g_autoptr (GFile) new_etc_path = g_file_resolve_relative_path (deployment_dir, "etc"); + g_autoptr (GPtrArray) modified + = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref); + g_autoptr (GPtrArray) removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); + g_autoptr (GPtrArray) added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); + if (!ostree_diff_dirs (OSTREE_DIFF_FLAGS_IGNORE_XATTRS, orig_etc_path, new_etc_path, modified, + removed, added, cancellable, error)) return FALSE; ostree_diff_print (orig_etc_path, new_etc_path, modified, removed, added); diff --git a/src/ostree/ot-admin-builtin-finalize-staged.c b/src/ostree/ot-admin-builtin-finalize-staged.c index eedffdd..a60f468 100644 --- a/src/ostree/ot-admin-builtin-finalize-staged.c +++ b/src/ostree/ot-admin-builtin-finalize-staged.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2018 Red Hat, Inc. + * Copyright (C) 2022 Endless OS Foundation LLC * * SPDX-License-Identifier: LGPL-2.0+ * @@ -19,28 +20,32 @@ #include "config.h" -#include "config.h" - +#include +#include +#include #include -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" #include "ostree-cmd-private.h" #include "ostree.h" -static GOptionEntry options[] = { - { NULL } -}; +static gboolean opt_hold; + +static GOptionEntry options[] + = { { "hold", 0, 0, G_OPTION_ARG_NONE, &opt_hold, "Hold /boot open during finalization", NULL }, + { NULL } }; /* Called by ostree-finalize-staged.service, and in turn * invokes a cmdprivate function inside the shared library. */ gboolean -ot_admin_builtin_finalize_staged (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_finalize_staged (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { /* Just a sanity check; we shouldn't be called outside of the service though. */ @@ -48,15 +53,53 @@ ot_admin_builtin_finalize_staged (int argc, char **argv, OstreeCommandInvocation if (fstatat (AT_FDCWD, OSTREE_PATH_BOOTED, &stbuf, 0) < 0) return TRUE; - g_autoptr(GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (GOptionContext) context = g_option_context_new (""); + g_autoptr (OstreeSysroot) sysroot = NULL; + + /* First parse the args without loading the sysroot to see what options are + * set. */ if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_NO_LOAD, invocation, &sysroot, + cancellable, error)) return FALSE; - if (!ostree_cmd__private__()->ostree_finalize_staged (sysroot, cancellable, error)) - return FALSE; + if (opt_hold) + { + /* Load the sysroot unlocked so that a separate namespace isn't + * created. */ + if (!ostree_admin_sysroot_load ( + sysroot, OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, + cancellable, error)) + return FALSE; + + /* In case it's an automount, open /boot so that the automount doesn't + * expire until before this process exits. If it did expire and got + * unmounted, the service would be stopped and the deployment would be + * finalized earlier than expected. + */ + int sysroot_fd = ostree_sysroot_get_fd (sysroot); + glnx_autofd int boot_fd = -1; + g_debug ("Opening /boot directory"); + if (!glnx_opendirat (sysroot_fd, "boot", TRUE, &boot_fd, error)) + return FALSE; + + /* We want to keep /boot open until the deployment is finalized during + * system shutdown, so block until we get SIGTERM which systemd will send + * when the unit is stopped. + */ + pause (); + } + else + { + /* Load the sysroot with the normal flags and actually finalize the + * deployment. */ + if (!ostree_admin_sysroot_load (sysroot, OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, cancellable, + error)) + return FALSE; + + if (!ostree_cmd__private__ ()->ostree_finalize_staged (sysroot, cancellable, error)) + return FALSE; + } return TRUE; } diff --git a/src/ostree/ot-admin-builtin-init-fs.c b/src/ostree/ot-admin-builtin-init-fs.c index 87f46cb..bf00f19 100644 --- a/src/ostree/ot-admin-builtin-init-fs.c +++ b/src/ostree/ot-admin-builtin-init-fs.c @@ -21,29 +21,29 @@ #include "config.h" -#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" +#include "ot-main.h" #include "otutil.h" #include static gboolean opt_modern; -static GOptionEntry options[] = { - { "modern", 0, 0, G_OPTION_ARG_NONE, &opt_modern, "Only create /boot and /ostree", NULL }, - { NULL } -}; +static GOptionEntry options[] + = { { "modern", 0, 0, G_OPTION_ARG_NONE, &opt_modern, "Only create /boot and /ostree", NULL }, + { NULL } }; gboolean -ot_admin_builtin_init_fs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_init_fs (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("PATH"); + g_autoptr (GOptionContext) context = g_option_context_new ("PATH"); if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | - OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED | - OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT, + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER + | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED + | OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT, invocation, NULL, cancellable, error)) return FALSE; @@ -70,20 +70,18 @@ ot_admin_builtin_init_fs (int argc, char **argv, OstreeCommandInvocation *invoca */ if (!opt_modern) { - const char *traditional_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"}; + const char *traditional_toplevels[] = { "boot", "dev", "home", "proc", "run", "sys" }; for (guint i = 0; i < G_N_ELEMENTS (traditional_toplevels); i++) { - if (!glnx_shutil_mkdir_p_at (root_dfd, traditional_toplevels[i], 0755, - cancellable, error)) + if (!glnx_shutil_mkdir_p_at (root_dfd, traditional_toplevels[i], 0755, cancellable, + error)) return FALSE; } - if (!glnx_shutil_mkdir_p_at (root_dfd, "root", 0700, - cancellable, error)) + if (!glnx_shutil_mkdir_p_at (root_dfd, "root", 0700, cancellable, error)) return FALSE; - if (!glnx_shutil_mkdir_p_at (root_dfd, "tmp", 01777, - cancellable, error)) + if (!glnx_shutil_mkdir_p_at (root_dfd, "tmp", 01777, cancellable, error)) return FALSE; if (fchmodat (root_dfd, "tmp", 01777, 0) == -1) { @@ -92,8 +90,8 @@ ot_admin_builtin_init_fs (int argc, char **argv, OstreeCommandInvocation *invoca } } - g_autoptr(GFile) dir = g_file_new_for_path (sysroot_path); - g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (dir); + g_autoptr (GFile) dir = g_file_new_for_path (sysroot_path); + g_autoptr (OstreeSysroot) sysroot = ostree_sysroot_new (dir); if (!ostree_sysroot_ensure_initialized (sysroot, cancellable, error)) return FALSE; diff --git a/src/ostree/ot-admin-builtin-instutil.c b/src/ostree/ot-admin-builtin-instutil.c index b946a96..d697cb0 100644 --- a/src/ostree/ot-admin-builtin-instutil.c +++ b/src/ostree/ot-admin-builtin-instutil.c @@ -19,26 +19,23 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" -#include "ot-admin-instutil-builtins.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-admin-instutil-builtins.h" +#include "ot-builtins.h" +#include "ot-main.h" #include static OstreeCommand admin_instutil_subcommands[] = { #ifdef HAVE_SELINUX { "selinux-ensure-labeled", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_instutil_builtin_selinux_ensure_labeled, - "Relabel all or part of a deployment" }, + ot_admin_instutil_builtin_selinux_ensure_labeled, "Relabel all or part of a deployment" }, #endif - { "set-kargs", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_instutil_builtin_set_kargs, - "Set new kernel command line arguments(Not stable)" }, - { "grub2-generate", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_instutil_builtin_grub2_generate, + { "set-kargs", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_instutil_builtin_set_kargs, + "Set new kernel command line arguments(Not stable)" }, + { "grub2-generate", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_instutil_builtin_grub2_generate, "Generate GRUB2 configuration from given BLS entries" }, { NULL, 0, NULL, NULL } }; @@ -49,7 +46,7 @@ ostree_admin_instutil_option_context_new_with_commands (void) OstreeCommand *command = admin_instutil_subcommands; GOptionContext *context = g_option_context_new ("COMMAND"); - g_autoptr(GString) summary = g_string_new ("Builtin \"admin instutil\" Commands:"); + g_autoptr (GString) summary = g_string_new ("Builtin \"admin instutil\" Commands:"); while (command->name != NULL) { @@ -69,7 +66,8 @@ ostree_admin_instutil_option_context_new_with_commands (void) } gboolean -ot_admin_builtin_instutil (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_instutil (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { const char *subcommand_name = NULL; int in, out; @@ -107,13 +105,13 @@ ot_admin_builtin_instutil (int argc, char **argv, OstreeCommandInvocation *invoc if (!subcommand->name) { - g_autoptr(GOptionContext) context = - ostree_admin_instutil_option_context_new_with_commands (); + g_autoptr (GOptionContext) context + = ostree_admin_instutil_option_context_new_with_commands (); /* This will not return for some options (e.g. --version). */ if (ostree_admin_option_context_parse (context, NULL, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT, - invocation, NULL, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT, invocation, NULL, + cancellable, error)) { if (subcommand_name == NULL) { diff --git a/src/ostree/ot-admin-builtin-kargs.c b/src/ostree/ot-admin-builtin-kargs.c new file mode 100644 index 0000000..c4d440b --- /dev/null +++ b/src/ostree/ot-admin-builtin-kargs.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015 Colin Walters + * Copyright (C) 2022 Huijing Hei + * + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "ot-admin-builtins.h" +#include "ot-admin-functions.h" +#include "ot-admin-kargs-builtins.h" +#include "ot-main.h" +#include "otutil.h" + +#include + +static OstreeCommand admin_kargs_subcommands[] = { + { "edit-in-place", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN, + ot_admin_kargs_builtin_edit_in_place, + "Set new kernel command line arguments in place (applies to all deployments by default)" }, + { NULL, 0, NULL, NULL } +}; + +static GOptionContext * +ostree_admin_kargs_option_context_new_with_commands (void) +{ + OstreeCommand *command = admin_kargs_subcommands; + GOptionContext *context = g_option_context_new ("COMMAND"); + + g_autoptr (GString) summary = g_string_new ("Builtin \"admin kargs\" Commands:"); + + while (command->name != NULL) + { + if ((command->flags & OSTREE_BUILTIN_FLAG_HIDDEN) == 0) + { + g_string_append_printf (summary, "\n %-24s", command->name); + if (command->description != NULL) + g_string_append_printf (summary, "%s", command->description); + } + + command++; + } + + g_option_context_set_summary (context, summary->str); + + return context; +} + +gboolean +ot_admin_builtin_kargs (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) +{ + const char *subcommand_name = NULL; + int in, out; + for (in = 1, out = 1; in < argc; in++, out++) + { + /* The non-option is the command, take it out of the arguments */ + if (argv[in][0] != '-') + { + if (subcommand_name == NULL) + { + subcommand_name = argv[in]; + out--; + continue; + } + } + + else if (g_str_equal (argv[in], "--")) + { + break; + } + + argv[out] = argv[in]; + } + + argc = out; + + OstreeCommand *subcommand = admin_kargs_subcommands; + while (subcommand->name) + { + if (g_strcmp0 (subcommand_name, subcommand->name) == 0) + break; + subcommand++; + } + + if (!subcommand->name) + { + g_autoptr (GOptionContext) context = ostree_admin_kargs_option_context_new_with_commands (); + + /* This will not return for some options (e.g. --version). */ + if (ostree_admin_option_context_parse (context, NULL, &argc, &argv, + OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT, invocation, NULL, + cancellable, error)) + { + if (subcommand_name == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No \"admin kargs\" subcommand specified"); + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Unknown \"admin kargs\" subcommand '%s'", subcommand_name); + } + } + + g_autofree char *help = g_option_context_get_help (context, FALSE, NULL); + g_printerr ("%s", help); + return FALSE; + } + + g_autofree char *prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name); + g_set_prgname (prgname); + + OstreeCommandInvocation sub_invocation = { .command = subcommand }; + if (!subcommand->fn (argc, argv, &sub_invocation, cancellable, error)) + return FALSE; + + return TRUE; +} diff --git a/src/ostree/ot-admin-builtin-os-init.c b/src/ostree/ot-admin-builtin-os-init.c index cb1ec66..561d6cd 100644 --- a/src/ostree/ot-admin-builtin-os-init.c +++ b/src/ostree/ot-admin-builtin-os-init.c @@ -21,49 +21,42 @@ #include "config.h" -#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" +#include "ot-main.h" #include "otutil.h" #include -static GOptionEntry options[] = { - { NULL } -}; +static GOptionEntry options[] = { { NULL } }; gboolean -ot_admin_builtin_os_init (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_os_init (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - gboolean ret = FALSE; - const char *osname = NULL; - - context = g_option_context_new ("OSNAME"); + g_autoptr (GOptionContext) context = g_option_context_new ("STATEROOT"); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, - invocation, &sysroot, cancellable, error)) - goto out; + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) + return FALSE; if (!ostree_sysroot_ensure_initialized (sysroot, cancellable, error)) - goto out; + return FALSE; if (argc < 2) { - ot_util_usage_error (context, "OSNAME must be specified", error); - goto out; + ot_util_usage_error (context, "STATEROOT must be specified", error); + return FALSE; } - osname = argv[1]; + const char *osname = argv[1]; if (!ostree_sysroot_init_osname (sysroot, osname, cancellable, error)) - goto out; + return FALSE; - g_print ("ostree/deploy/%s initialized as OSTree root\n", osname); + g_print ("ostree/deploy/%s initialized as OSTree stateroot\n", osname); - ret = TRUE; - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-admin-builtin-pin.c b/src/ostree/ot-admin-builtin-pin.c index 301e1aa..362df44 100644 --- a/src/ostree/ot-admin-builtin-pin.c +++ b/src/ostree/ot-admin-builtin-pin.c @@ -21,27 +21,26 @@ #include -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_unpin; -static GOptionEntry options[] = { - { "unpin", 'u', 0, G_OPTION_ARG_NONE, &opt_unpin, "Unset pin", NULL }, - { NULL } -}; +static GOptionEntry options[] + = { { "unpin", 'u', 0, G_OPTION_ARG_NONE, &opt_unpin, "Unset pin", NULL }, { NULL } }; gboolean -ot_admin_builtin_pin (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_pin (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("INDEX"); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (GOptionContext) context = g_option_context_new ("INDEX"); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) return FALSE; if (argc < 2) @@ -62,7 +61,8 @@ ot_admin_builtin_pin (int argc, char **argv, OstreeCommandInvocation *invocation if (errno == ERANGE) return glnx_throw (error, "Index too large: %s", deploy_index_str); - g_autoptr(OstreeDeployment) target_deployment = ot_admin_get_indexed_deployment (sysroot, deploy_index, error); + g_autoptr (OstreeDeployment) target_deployment + = ot_admin_get_indexed_deployment (sysroot, deploy_index, error); if (!target_deployment) return FALSE; @@ -70,14 +70,17 @@ ot_admin_builtin_pin (int argc, char **argv, OstreeCommandInvocation *invocation const gboolean desired_pin = !opt_unpin; if (current_pin == desired_pin) { - g_print ("Deployment %s is already %s\n", deploy_index_str, current_pin ? "pinned" : "unpinned"); + g_print ("Deployment %s is already %s\n", deploy_index_str, + current_pin ? "pinned" : "unpinned"); } else - { - if (!ostree_sysroot_deployment_set_pinned (sysroot, target_deployment, desired_pin, error)) - return FALSE; - g_print ("Deployment %s is now %s\n", deploy_index_str, desired_pin ? "pinned" : "unpinned"); - } + { + if (!ostree_sysroot_deployment_set_pinned (sysroot, target_deployment, desired_pin, + error)) + return FALSE; + g_print ("Deployment %s is now %s\n", deploy_index_str, + desired_pin ? "pinned" : "unpinned"); + } } return TRUE; diff --git a/src/ostree/ot-admin-builtin-set-default.c b/src/ostree/ot-admin-builtin-set-default.c new file mode 100644 index 0000000..89e6754 --- /dev/null +++ b/src/ostree/ot-admin-builtin-set-default.c @@ -0,0 +1,68 @@ +/* + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include + +#include "ostree.h" +#include "ot-admin-builtins.h" +#include "ot-admin-functions.h" +#include "ot-main.h" +#include "otutil.h" + +static GOptionEntry options[] = { { NULL } }; + +gboolean +ot_admin_builtin_set_default (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) +{ + g_autoptr (GOptionContext) context = g_option_context_new ("INDEX"); + + g_autoptr (OstreeSysroot) sysroot = NULL; + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) + return FALSE; + + if (argc < 2) + { + ot_util_usage_error (context, "INDEX must be specified", error); + return FALSE; + } + + g_autoptr (GPtrArray) current_deployments = ostree_sysroot_get_deployments (sysroot); + + const char *deploy_index_str = argv[1]; + int deploy_index = atoi (deploy_index_str); + + g_autoptr (OstreeDeployment) target_deployment + = ot_admin_get_indexed_deployment (sysroot, deploy_index, error); + if (!target_deployment) + return FALSE; + + g_ptr_array_remove_index (current_deployments, deploy_index); + g_ptr_array_insert (current_deployments, 0, g_object_ref (target_deployment)); + + if (!ostree_sysroot_write_deployments (sysroot, current_deployments, cancellable, error)) + return FALSE; + + if (!ostree_sysroot_cleanup (sysroot, cancellable, error)) + return glnx_prefix_error (error, "Performing final cleanup"); + + return TRUE; +} diff --git a/src/ostree/ot-admin-builtin-set-origin.c b/src/ostree/ot-admin-builtin-set-origin.c index 1a6bf2e..45b5dbd 100644 --- a/src/ostree/ot-admin-builtin-set-origin.c +++ b/src/ostree/ot-admin-builtin-set-origin.c @@ -19,63 +19,59 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" -#include -#include #include +#include +#include static int opt_index = -1; static char **opt_set; -static GOptionEntry options[] = { - { "set", 's', 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, "Set config option KEY=VALUE for remote", "KEY=VALUE" }, - { "index", 0, 0, G_OPTION_ARG_INT, &opt_index, "Operate on the deployment INDEX, starting from zero", "INDEX" }, - { NULL } -}; +static GOptionEntry options[] + = { { "set", 's', 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, + "Set config option KEY=VALUE for remote", "KEY=VALUE" }, + { "index", 0, 0, G_OPTION_ARG_INT, &opt_index, + "Operate on the deployment INDEX, starting from zero", "INDEX" }, + { NULL } }; gboolean -ot_admin_builtin_set_origin (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_set_origin (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autoptr(GOptionContext) context = NULL; - const char *remotename = NULL; - const char *url = NULL; - const char *branch = NULL; - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - g_autoptr(OstreeDeployment) target_deployment = NULL; - - context = g_option_context_new ("REMOTENAME URL [BRANCH]"); - + g_autoptr (GOptionContext) context = g_option_context_new ("REMOTENAME URL [BRANCH]"); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) - goto out; + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) + return FALSE; if (argc < 3) { ot_util_usage_error (context, "REMOTENAME and URL must be specified", error); - goto out; + return FALSE; } - remotename = argv[1]; - url = argv[2]; + const char *remotename = argv[1]; + const char *url = argv[2]; + const char *branch = NULL; if (argc > 3) branch = argv[3]; + g_autoptr (OstreeRepo) repo = NULL; if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error)) - goto out; + return FALSE; + g_autoptr (OstreeDeployment) target_deployment = NULL; if (opt_index == -1) { target_deployment = ostree_sysroot_require_booted_deployment (sysroot, error); if (target_deployment == NULL) - goto out; + return FALSE; /* To match the below */ target_deployment = g_object_ref (target_deployment); } @@ -83,57 +79,54 @@ ot_admin_builtin_set_origin (int argc, char **argv, OstreeCommandInvocation *inv { target_deployment = ot_admin_get_indexed_deployment (sysroot, opt_index, error); if (!target_deployment) - goto out; + return FALSE; } - { char **iter; - g_autoptr(GVariantBuilder) optbuilder = - g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); - g_autoptr(GVariant) remote_options = NULL; + { + g_autoptr (GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariant) remote_options = NULL; - for (iter = opt_set; iter && *iter; iter++) + for (char **iter = opt_set; iter && *iter; iter++) { const char *keyvalue = *iter; g_autofree char *subkey = NULL; g_autofree char *subvalue = NULL; if (!ot_parse_keyvalue (keyvalue, &subkey, &subvalue, error)) - goto out; + return FALSE; - g_variant_builder_add (optbuilder, "{s@v}", - subkey, g_variant_new_variant (g_variant_new_string (subvalue))); + g_variant_builder_add (optbuilder, "{s@v}", subkey, + g_variant_new_variant (g_variant_new_string (subvalue))); } remote_options = g_variant_ref_sink (g_variant_builder_end (optbuilder)); - if (!ostree_repo_remote_change (repo, NULL, - OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS, - remotename, url, - remote_options, - cancellable, error)) - goto out; + if (!ostree_repo_remote_change (repo, NULL, OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS, + remotename, url, remote_options, cancellable, error)) + return FALSE; } - - { GKeyFile *old_origin = ostree_deployment_get_origin (target_deployment); + + { + GKeyFile *old_origin = ostree_deployment_get_origin (target_deployment); g_autofree char *origin_refspec = g_key_file_get_string (old_origin, "origin", "refspec", NULL); g_autofree char *origin_remote = NULL; g_autofree char *origin_ref = NULL; - + if (!ostree_parse_refspec (origin_refspec, &origin_remote, &origin_ref, error)) - goto out; + return FALSE; + + { + g_autofree char *new_refspec + = g_strconcat (remotename, ":", branch ? branch : origin_ref, NULL); + g_autoptr (GKeyFile) new_origin = NULL; - { g_autofree char *new_refspec = g_strconcat (remotename, ":", branch ? branch : origin_ref, NULL); - g_autoptr(GKeyFile) new_origin = NULL; - new_origin = ostree_sysroot_origin_new_from_refspec (sysroot, new_refspec); - if (!ostree_sysroot_write_origin_file (sysroot, target_deployment, new_origin, - cancellable, error)) - goto out; + if (!ostree_sysroot_write_origin_file (sysroot, target_deployment, new_origin, cancellable, + error)) + return FALSE; } } - ret = TRUE; - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-admin-builtin-status.c b/src/ostree/ot-admin-builtin-status.c index af1a711..3addfd1 100644 --- a/src/ostree/ot-admin-builtin-status.c +++ b/src/ostree/ot-admin-builtin-status.c @@ -21,25 +21,23 @@ #include "config.h" -#include "ot-main.h" +#include "libglnx.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" -#include "libglnx.h" +#include "ot-main.h" #include static gboolean opt_verify; -static GOptionEntry options[] = { - { "verify", 'V', 0, G_OPTION_ARG_NONE, &opt_verify, "Print the commit verification status", NULL }, - { NULL } -}; +static GOptionEntry options[] = { { "verify", 'V', 0, G_OPTION_ARG_NONE, &opt_verify, + "Print the commit verification status", NULL }, + { NULL } }; #ifndef OSTREE_DISABLE_GPGME static gboolean -deployment_get_gpg_verify (OstreeDeployment *deployment, - OstreeRepo *repo) +deployment_get_gpg_verify (OstreeDeployment *deployment, OstreeRepo *repo) { /* XXX Something like this could be added to the OstreeDeployment * API in libostree if the OstreeRepo parameter is acceptable. */ @@ -59,38 +57,32 @@ deployment_get_gpg_verify (OstreeDeployment *deployment, gboolean gpg_verify = FALSE; if (remote) - (void) ostree_repo_remote_get_gpg_verify (repo, remote, &gpg_verify, NULL); + (void)ostree_repo_remote_get_gpg_verify (repo, remote, &gpg_verify, NULL); return gpg_verify; } #endif /* OSTREE_DISABLE_GPGME */ - static gboolean -deployment_print_status (OstreeSysroot *sysroot, - OstreeRepo *repo, - OstreeDeployment *deployment, - gboolean is_booted, - gboolean is_pending, - gboolean is_rollback, - GCancellable *cancellable, - GError **error) +deployment_print_status (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeployment *deployment, + gboolean is_booted, gboolean is_pending, gboolean is_rollback, + GCancellable *cancellable, GError **error) { const char *ref = ostree_deployment_get_csum (deployment); /* Load the backing commit; shouldn't normally fail, but if it does, * we stumble on. */ - g_autoptr(GVariant) commit = NULL; - (void)ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, ref, - &commit, NULL); - g_autoptr(GVariant) commit_metadata = NULL; + g_autoptr (GVariant) commit = NULL; + (void)ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, ref, &commit, NULL); + g_autoptr (GVariant) commit_metadata = NULL; if (commit) commit_metadata = g_variant_get_child_value (commit, 0); - g_autoptr(GVariant) commit_detached_metadata = NULL; + g_autoptr (GVariant) commit_detached_metadata = NULL; if (commit) { - if (!ostree_repo_read_commit_detached_metadata (repo, ref, &commit_detached_metadata, cancellable, error)) + if (!ostree_repo_read_commit_detached_metadata (repo, ref, &commit_detached_metadata, + cancellable, error)) return FALSE; } @@ -98,8 +90,9 @@ deployment_print_status (OstreeSysroot *sysroot, const char *source_title = NULL; if (commit_metadata) { - (void) g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_VERSION, "&s", &version); - (void) g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_SOURCE_TITLE, "&s", &source_title); + (void)g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_VERSION, "&s", &version); + (void)g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_SOURCE_TITLE, "&s", + &source_title); } GKeyFile *origin = ostree_deployment_get_origin (deployment); @@ -111,11 +104,8 @@ deployment_print_status (OstreeSysroot *sysroot, deployment_status = " (pending)"; else if (is_rollback) deployment_status = " (rollback)"; - g_print ("%c %s %s.%d%s\n", - is_booted ? '*' : ' ', - ostree_deployment_get_osname (deployment), - ostree_deployment_get_csum (deployment), - ostree_deployment_get_deployserial (deployment), + g_print ("%c %s %s.%d%s\n", is_booted ? '*' : ' ', ostree_deployment_get_osname (deployment), + ostree_deployment_get_csum (deployment), ostree_deployment_get_deployserial (deployment), deployment_status); if (version) g_print (" Version: %s\n", version); @@ -127,8 +117,8 @@ deployment_print_status (OstreeSysroot *sysroot, break; default: g_print (" %s%sUnlocked: %s%s%s\n", ot_get_red_start (), ot_get_bold_start (), - ostree_deployment_unlocked_state_to_string (unlocked), - ot_get_bold_end (), ot_get_red_end ()); + ostree_deployment_unlocked_state_to_string (unlocked), ot_get_bold_end (), + ot_get_red_end ()); } if (ostree_deployment_is_pinned (deployment)) g_print (" Pinned: yes\n"); @@ -148,14 +138,13 @@ deployment_print_status (OstreeSysroot *sysroot, #ifndef OSTREE_DISABLE_GPGME if (!opt_verify && deployment_get_gpg_verify (deployment, repo)) { - g_autoptr(GString) output_buffer = g_string_sized_new (256); + g_autoptr (GString) output_buffer = g_string_sized_new (256); /* Print any digital signatures on this commit. */ const char *osname = ostree_deployment_get_osname (deployment); - g_autoptr(GError) local_error = NULL; - g_autoptr(OstreeGpgVerifyResult) result = - ostree_repo_verify_commit_for_remote (repo, ref, osname, - cancellable, &local_error); + g_autoptr (GError) local_error = NULL; + g_autoptr (OstreeGpgVerifyResult) result + = ostree_repo_verify_commit_for_remote (repo, ref, osname, cancellable, &local_error); /* G_IO_ERROR_NOT_FOUND just means the commit is not signed. */ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) @@ -172,8 +161,8 @@ deployment_print_status (OstreeSysroot *sysroot, const guint n_signatures = ostree_gpg_verify_result_count_all (result); for (guint jj = 0; jj < n_signatures; jj++) { - ostree_gpg_verify_result_describe (result, jj, output_buffer, " GPG: ", - OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT); + ostree_gpg_verify_result_describe (result, jj, output_buffer, + " GPG: ", OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT); } g_print ("%s", output_buffer->str); @@ -196,11 +185,13 @@ deployment_print_status (OstreeSysroot *sysroot, if (remote == NULL) return glnx_throw (error, "Cannot verify deployment without remote"); - g_autoptr(GBytes) commit_data = g_variant_get_data_as_bytes (commit); - g_autoptr(GBytes) commit_detached_metadata_bytes = - commit_detached_metadata ? g_variant_get_data_as_bytes (commit_detached_metadata) : NULL; + g_autoptr (GBytes) commit_data = g_variant_get_data_as_bytes (commit); + g_autoptr (GBytes) commit_detached_metadata_bytes + = commit_detached_metadata ? g_variant_get_data_as_bytes (commit_detached_metadata) + : NULL; g_autofree char *verify_text = NULL; - if (!ostree_repo_signature_verify_commit_data (repo, remote, commit_data, commit_detached_metadata_bytes, 0, &verify_text, error)) + if (!ostree_repo_signature_verify_commit_data ( + repo, remote, commit_data, commit_detached_metadata_bytes, 0, &verify_text, error)) return FALSE; g_print ("%s\n", verify_text); } @@ -209,28 +200,28 @@ deployment_print_status (OstreeSysroot *sysroot, } gboolean -ot_admin_builtin_status (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_status (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, invocation, &sysroot, + cancellable, error)) return FALSE; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (OstreeRepo) repo = NULL; if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error)) return FALSE; - g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot); + g_autoptr (GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot); OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (sysroot); - g_autoptr(OstreeDeployment) pending_deployment = NULL; - g_autoptr(OstreeDeployment) rollback_deployment = NULL; + g_autoptr (OstreeDeployment) pending_deployment = NULL; + g_autoptr (OstreeDeployment) rollback_deployment = NULL; if (booted_deployment) - ostree_sysroot_query_deployments_for (sysroot, NULL, &pending_deployment, - &rollback_deployment); + ostree_sysroot_query_deployments_for (sysroot, NULL, &pending_deployment, &rollback_deployment); if (deployments->len == 0) { @@ -241,12 +232,9 @@ ot_admin_builtin_status (int argc, char **argv, OstreeCommandInvocation *invocat for (guint i = 0; i < deployments->len; i++) { OstreeDeployment *deployment = deployments->pdata[i]; - if (!deployment_print_status (sysroot, repo, deployment, - deployment == booted_deployment, + if (!deployment_print_status (sysroot, repo, deployment, deployment == booted_deployment, deployment == pending_deployment, - deployment == rollback_deployment, - cancellable, - error)) + deployment == rollback_deployment, cancellable, error)) return FALSE; } } diff --git a/src/ostree/ot-admin-builtin-switch.c b/src/ostree/ot-admin-builtin-switch.c index d29e703..cb41cac 100644 --- a/src/ostree/ot-admin-builtin-switch.c +++ b/src/ostree/ot-admin-builtin-switch.c @@ -19,34 +19,34 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" -#include -#include #include +#include +#include static gboolean opt_reboot; static char *opt_osname; -static GOptionEntry options[] = { - { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after switching trees", NULL }, - { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, - { NULL } -}; +static GOptionEntry options[] + = { { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after switching trees", NULL }, + { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, + "Use a different operating system root than the current one", "OSNAME" }, + { NULL } }; gboolean -ot_admin_builtin_switch (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_switch (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = - g_option_context_new ("REFSPEC"); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (GOptionContext) context = g_option_context_new ("REFSPEC"); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) return FALSE; if (argc < 2) @@ -57,10 +57,8 @@ ot_admin_builtin_switch (int argc, char **argv, OstreeCommandInvocation *invocat const char *new_provided_refspec = argv[1]; - g_autoptr(OstreeSysrootUpgrader) upgrader = - ostree_sysroot_upgrader_new_for_os_with_flags (sysroot, opt_osname, - OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED, - cancellable, error); + g_autoptr (OstreeSysrootUpgrader) upgrader = ostree_sysroot_upgrader_new_for_os_with_flags ( + sysroot, opt_osname, OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED, cancellable, error); if (!upgrader) return FALSE; @@ -77,7 +75,7 @@ ot_admin_builtin_switch (int argc, char **argv, OstreeCommandInvocation *invocat if (g_str_has_suffix (new_provided_refspec, ":")) { new_remote = g_strdup (new_provided_refspec); - new_remote[strlen(new_remote)-1] = '\0'; + new_remote[strlen (new_remote) - 1] = '\0'; new_ref = g_strdup (origin_ref); } else @@ -86,7 +84,7 @@ ot_admin_builtin_switch (int argc, char **argv, OstreeCommandInvocation *invocat return FALSE; } - const char* remote = new_remote ?: origin_remote; + const char *remote = new_remote ?: origin_remote; g_autofree char *new_refspec = NULL; if (remote) new_refspec = g_strconcat (remote, ":", new_ref, NULL); @@ -95,30 +93,32 @@ ot_admin_builtin_switch (int argc, char **argv, OstreeCommandInvocation *invocat if (strcmp (origin_refspec, new_refspec) == 0) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Old and new refs are equal: %s", new_refspec); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Old and new refs are equal: %s", + new_refspec); return FALSE; } - g_autoptr(GKeyFile) new_origin = ostree_sysroot_origin_new_from_refspec (sysroot, new_refspec); + g_autoptr (GKeyFile) new_origin = ostree_sysroot_origin_new_from_refspec (sysroot, new_refspec); if (!ostree_sysroot_upgrader_set_origin (upgrader, new_origin, cancellable, error)) return FALSE; - { g_auto(GLnxConsoleRef) console = { 0, }; + { + g_auto (GLnxConsoleRef) console = { + 0, + }; glnx_console_lock (&console); - g_autoptr(OstreeAsyncProgress) progress = NULL; + g_autoptr (OstreeAsyncProgress) progress = NULL; if (console.is_tty) - progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect ( + ostree_repo_pull_default_console_progress_changed, &console); /* Always allow older...there's not going to be a chronological * relationship necessarily. */ gboolean changed; - if (!ostree_sysroot_upgrader_pull (upgrader, 0, - OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER, - progress, &changed, - cancellable, error)) + if (!ostree_sysroot_upgrader_pull (upgrader, 0, OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER, + progress, &changed, cancellable, error)) return FALSE; if (progress) diff --git a/src/ostree/ot-admin-builtin-undeploy.c b/src/ostree/ot-admin-builtin-undeploy.c index 4115568..ab028d4 100644 --- a/src/ostree/ot-admin-builtin-undeploy.c +++ b/src/ostree/ot-admin-builtin-undeploy.c @@ -21,31 +21,24 @@ #include -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" -static GOptionEntry options[] = { - { NULL } -}; +static GOptionEntry options[] = { { NULL } }; gboolean -ot_admin_builtin_undeploy (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_undeploy (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - const char *deploy_index_str; - int deploy_index; - g_autoptr(GPtrArray) current_deployments = NULL; - g_autoptr(OstreeDeployment) target_deployment = NULL; - - context = g_option_context_new ("INDEX"); + g_autoptr (GOptionContext) context = g_option_context_new ("INDEX"); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) return FALSE; if (argc < 2) @@ -54,12 +47,13 @@ ot_admin_builtin_undeploy (int argc, char **argv, OstreeCommandInvocation *invoc return FALSE; } - current_deployments = ostree_sysroot_get_deployments (sysroot); + g_autoptr (GPtrArray) current_deployments = ostree_sysroot_get_deployments (sysroot); - deploy_index_str = argv[1]; - deploy_index = atoi (deploy_index_str); + const char *deploy_index_str = argv[1]; + int deploy_index = atoi (deploy_index_str); - target_deployment = ot_admin_get_indexed_deployment (sysroot, deploy_index, error); + g_autoptr (OstreeDeployment) target_deployment + = ot_admin_get_indexed_deployment (sysroot, deploy_index, error); if (!target_deployment) return FALSE; @@ -72,8 +66,7 @@ ot_admin_builtin_undeploy (int argc, char **argv, OstreeCommandInvocation *invoc g_ptr_array_remove_index (current_deployments, deploy_index); - if (!ostree_sysroot_write_deployments (sysroot, current_deployments, - cancellable, error)) + if (!ostree_sysroot_write_deployments (sysroot, current_deployments, cancellable, error)) return FALSE; g_print ("Deleted deployment %s.%d\n", ostree_deployment_get_csum (target_deployment), diff --git a/src/ostree/ot-admin-builtin-unlock.c b/src/ostree/ot-admin-builtin-unlock.c index 800c074..d0c4145 100644 --- a/src/ostree/ot-admin-builtin-unlock.c +++ b/src/ostree/ot-admin-builtin-unlock.c @@ -19,54 +19,50 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" -#include #include +#include static gboolean opt_hotfix; static gboolean opt_transient; -static GOptionEntry options[] = { - { "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Retain changes across reboots", NULL }, - { "transient", 0, 0, G_OPTION_ARG_NONE, &opt_transient, "Mount overlayfs read-only by default", NULL }, - { NULL } -}; +static GOptionEntry options[] + = { { "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Retain changes across reboots", NULL }, + { "transient", 0, 0, G_OPTION_ARG_NONE, &opt_transient, + "Mount overlayfs read-only by default", NULL }, + { NULL } }; gboolean -ot_admin_builtin_unlock (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_unlock (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - OstreeDeployment *booted_deployment = NULL; - OstreeDeploymentUnlockedState target_state; - - context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) - goto out; - + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) + return FALSE; + if (argc > 1) { ot_util_usage_error (context, "This command takes no extra arguments", error); - goto out; + return FALSE; } - booted_deployment = ostree_sysroot_require_booted_deployment (sysroot, error); + OstreeDeployment *booted_deployment = ostree_sysroot_require_booted_deployment (sysroot, error); if (!booted_deployment) - goto out; + return FALSE; + OstreeDeploymentUnlockedState target_state; if (opt_hotfix && opt_transient) { - glnx_throw (error, "Cannot specify both --hotfix and --transient"); - goto out; + return glnx_throw (error, "Cannot specify both --hotfix and --transient"); } else if (opt_hotfix) target_state = OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX; @@ -75,10 +71,10 @@ ot_admin_builtin_unlock (int argc, char **argv, OstreeCommandInvocation *invocat else target_state = OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT; - if (!ostree_sysroot_deployment_unlock (sysroot, booted_deployment, - target_state, cancellable, error)) - goto out; - + if (!ostree_sysroot_deployment_unlock (sysroot, booted_deployment, target_state, cancellable, + error)) + return FALSE; + switch (target_state) { case OSTREE_DEPLOYMENT_UNLOCKED_NONE: @@ -99,7 +95,5 @@ ot_admin_builtin_unlock (int argc, char **argv, OstreeCommandInvocation *invocat break; } - ret = TRUE; - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-admin-builtin-upgrade.c b/src/ostree/ot-admin-builtin-upgrade.c index 3ed71ef..1171042 100644 --- a/src/ostree/ot-admin-builtin-upgrade.c +++ b/src/ostree/ot-admin-builtin-upgrade.c @@ -21,15 +21,15 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" -#include -#include #include +#include +#include static gboolean opt_reboot; static gboolean opt_allow_downgrade; @@ -40,25 +40,31 @@ static char *opt_osname; static char *opt_override_commit; static GOptionEntry options[] = { - { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, + { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, + "Use a different operating system root than the current one", "OSNAME" }, { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after a successful upgrade", NULL }, - { "allow-downgrade", 0, 0, G_OPTION_ARG_NONE, &opt_allow_downgrade, "Permit deployment of chronologically older trees", NULL }, - { "override-commit", 0, 0, G_OPTION_ARG_STRING, &opt_override_commit, "Deploy CHECKSUM instead of the latest tree", "CHECKSUM" }, - { "pull-only", 0, 0, G_OPTION_ARG_NONE, &opt_pull_only, "Do not create a deployment, just download", NULL }, + { "allow-downgrade", 0, 0, G_OPTION_ARG_NONE, &opt_allow_downgrade, + "Permit deployment of chronologically older trees", NULL }, + { "override-commit", 0, 0, G_OPTION_ARG_STRING, &opt_override_commit, + "Deploy CHECKSUM instead of the latest tree", "CHECKSUM" }, + { "pull-only", 0, 0, G_OPTION_ARG_NONE, &opt_pull_only, + "Do not create a deployment, just download", NULL }, { "deploy-only", 0, 0, G_OPTION_ARG_NONE, &opt_deploy_only, "Do not pull, only deploy", NULL }, - { "stage", 0, 0, G_OPTION_ARG_NONE, &opt_stage, "Enable staging (finalization at reboot time)", NULL }, + { "stage", 0, 0, G_OPTION_ARG_NONE, &opt_stage, "Enable staging (finalization at reboot time)", + NULL }, { NULL } }; gboolean -ot_admin_builtin_upgrade (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_builtin_upgrade (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, - invocation, &sysroot, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) return FALSE; if (opt_pull_only && opt_deploy_only) @@ -78,13 +84,12 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeCommandInvocation *invoca if (opt_stage) flags |= OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE; - g_autoptr(OstreeSysrootUpgrader) upgrader = - ostree_sysroot_upgrader_new_for_os_with_flags (sysroot, opt_osname, flags, - cancellable, error); + g_autoptr (OstreeSysrootUpgrader) upgrader = ostree_sysroot_upgrader_new_for_os_with_flags ( + sysroot, opt_osname, flags, cancellable, error); if (!upgrader) return FALSE; - g_autoptr(GKeyFile) origin = ostree_sysroot_upgrader_dup_origin (upgrader); + g_autoptr (GKeyFile) origin = ostree_sysroot_upgrader_dup_origin (upgrader); if (origin != NULL) { /* Should we consider requiring --discard-hotfix here? */ @@ -92,9 +97,7 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeCommandInvocation *invoca if (opt_override_commit != NULL) { /* Override the commit to pull and deploy. */ - g_key_file_set_string (origin, "origin", - "override-commit", - opt_override_commit); + g_key_file_set_string (origin, "origin", "override-commit", opt_override_commit); } if (!ostree_sysroot_upgrader_set_origin (upgrader, origin, NULL, error)) @@ -106,18 +109,21 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeCommandInvocation *invoca if (opt_deploy_only) upgraderpullflags |= OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC; - { g_auto(GLnxConsoleRef) console = { 0, }; + { + g_auto (GLnxConsoleRef) console = { + 0, + }; glnx_console_lock (&console); - g_autoptr(OstreeAsyncProgress) progress = NULL; + g_autoptr (OstreeAsyncProgress) progress = NULL; if (console.is_tty) - progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect ( + ostree_repo_pull_default_console_progress_changed, &console); if (opt_allow_downgrade) upgraderpullflags |= OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER; - if (!ostree_sysroot_upgrader_pull (upgrader, 0, upgraderpullflags, - progress, &changed, + if (!ostree_sysroot_upgrader_pull (upgrader, 0, upgraderpullflags, progress, &changed, cancellable, error)) { /* In the pull-only case, we do a cleanup here to ensure that if @@ -129,7 +135,7 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeCommandInvocation *invoca * isn't directly referenced. */ if (opt_pull_only) - (void) ostree_sysroot_cleanup (sysroot, NULL, NULL); + (void)ostree_sysroot_cleanup (sysroot, NULL, NULL); return FALSE; } diff --git a/src/ostree/ot-admin-builtins.h b/src/ostree/ot-admin-builtins.h index 8d9451b..0464a81 100644 --- a/src/ostree/ot-admin-builtins.h +++ b/src/ostree/ot-admin-builtins.h @@ -21,31 +21,33 @@ #pragma once -#include +#include "ot-main.h" G_BEGIN_DECLS -#define BUILTINPROTO(name) gboolean ot_admin_builtin_ ## name (int argc, char **argv, \ - OstreeCommandInvocation *invocation, \ - GCancellable *cancellable, GError **error) +#define BUILTINPROTO(name) \ + gboolean ot_admin_builtin_##name (int argc, char **argv, OstreeCommandInvocation *invocation, \ + GCancellable *cancellable, GError **error) -BUILTINPROTO(selinux_ensure_labeled); -BUILTINPROTO(os_init); -BUILTINPROTO(install); -BUILTINPROTO(instutil); -BUILTINPROTO(init_fs); -BUILTINPROTO(undeploy); -BUILTINPROTO(deploy); -BUILTINPROTO(cleanup); -BUILTINPROTO(pin); -BUILTINPROTO(finalize_staged); -BUILTINPROTO(boot_complete); -BUILTINPROTO(unlock); -BUILTINPROTO(status); -BUILTINPROTO(set_origin); -BUILTINPROTO(diff); -BUILTINPROTO(switch); -BUILTINPROTO(upgrade); +BUILTINPROTO (selinux_ensure_labeled); +BUILTINPROTO (os_init); +BUILTINPROTO (install); +BUILTINPROTO (instutil); +BUILTINPROTO (init_fs); +BUILTINPROTO (undeploy); +BUILTINPROTO (set_default); +BUILTINPROTO (deploy); +BUILTINPROTO (cleanup); +BUILTINPROTO (pin); +BUILTINPROTO (finalize_staged); +BUILTINPROTO (boot_complete); +BUILTINPROTO (unlock); +BUILTINPROTO (status); +BUILTINPROTO (set_origin); +BUILTINPROTO (diff); +BUILTINPROTO (switch); +BUILTINPROTO (upgrade); +BUILTINPROTO (kargs); #undef BUILTINPROTO diff --git a/src/ostree/ot-admin-functions.c b/src/ostree/ot-admin-functions.c index e2309f6..e54fe8d 100644 --- a/src/ostree/ot-admin-functions.c +++ b/src/ostree/ot-admin-functions.c @@ -22,20 +22,18 @@ #include "config.h" #include "libglnx.h" +#include "ostree.h" #include "ot-admin-functions.h" #include "otutil.h" -#include "ostree.h" gboolean -ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot, - const char *osname, - GCancellable *cancellable, - GError **error) +ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot, const char *osname, + GCancellable *cancellable, GError **error) { - OstreeDeployment *booted_deployment = - ostree_sysroot_get_booted_deployment (sysroot); + OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (sysroot); if (booted_deployment == NULL && osname == NULL) - return glnx_throw (error, "Not currently booted into an OSTree system and no --os= argument given"); + return glnx_throw (error, + "Not currently booted into an OSTree system and no --os= argument given"); return TRUE; } @@ -51,7 +49,7 @@ ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot, char * ot_admin_checksum_version (GVariant *checksum) { - g_autoptr(GVariant) metadata = NULL; + g_autoptr (GVariant) metadata = NULL; const char *ret = NULL; metadata = g_variant_get_child_value (checksum, 0); @@ -63,18 +61,14 @@ ot_admin_checksum_version (GVariant *checksum) } OstreeDeployment * -ot_admin_get_indexed_deployment (OstreeSysroot *sysroot, - int index, - GError **error) +ot_admin_get_indexed_deployment (OstreeSysroot *sysroot, int index, GError **error) { - g_autoptr(GPtrArray) current_deployments = - ostree_sysroot_get_deployments (sysroot); + g_autoptr (GPtrArray) current_deployments = ostree_sysroot_get_deployments (sysroot); if (index < 0) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Invalid index %d", index); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Invalid index %d", index); return NULL; } if (index >= current_deployments->len) @@ -84,11 +78,12 @@ ot_admin_get_indexed_deployment (OstreeSysroot *sysroot, current_deployments->len); return NULL; } - + return g_object_ref (current_deployments->pdata[index]); } -struct ContextState { +struct ContextState +{ GMainContext *mainctx; gboolean running; }; @@ -101,17 +96,14 @@ on_sysroot_lock_timeout (gpointer user_data) } static void -on_sysroot_lock_acquired (OstreeSysroot *sysroot, - GAsyncResult *result, - struct ContextState *state) +on_sysroot_lock_acquired (OstreeSysroot *sysroot, GAsyncResult *result, struct ContextState *state) { state->running = FALSE; g_main_context_wakeup (state->mainctx); } gboolean -ot_admin_sysroot_lock (OstreeSysroot *sysroot, - GError **error) +ot_admin_sysroot_lock (OstreeSysroot *sysroot, GError **error) { gboolean ret = FALSE; gboolean acquired; @@ -134,14 +126,15 @@ ot_admin_sysroot_lock (OstreeSysroot *sysroot, on_sysroot_lock_timeout (&state); - ostree_sysroot_lock_async (sysroot, NULL, (GAsyncReadyCallback)on_sysroot_lock_acquired, &state); + ostree_sysroot_lock_async (sysroot, NULL, (GAsyncReadyCallback)on_sysroot_lock_acquired, + &state); while (state.running) g_main_context_iteration (state.mainctx, TRUE); } ret = TRUE; - out: +out: g_main_context_pop_thread_default (state.mainctx); g_main_context_unref (state.mainctx); return ret; diff --git a/src/ostree/ot-admin-functions.h b/src/ostree/ot-admin-functions.h index f2cbc0b..50aef16 100644 --- a/src/ostree/ot-admin-functions.h +++ b/src/ostree/ot-admin-functions.h @@ -26,26 +26,16 @@ G_BEGIN_DECLS -gboolean -ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot, - const char *osname, - GCancellable *cancellable, - GError **error); - -char * -ot_admin_checksum_version (GVariant *checksum); - -OstreeDeployment * -ot_admin_get_indexed_deployment (OstreeSysroot *sysroot, - int index, - GError **error); - -gboolean -ot_admin_sysroot_lock (OstreeSysroot *sysroot, - GError **error); - -gboolean -ot_admin_execve_reboot (OstreeSysroot *sysroot, - GError **error); +gboolean ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot, const char *osname, + GCancellable *cancellable, GError **error); + +char *ot_admin_checksum_version (GVariant *checksum); + +OstreeDeployment *ot_admin_get_indexed_deployment (OstreeSysroot *sysroot, int index, + GError **error); + +gboolean ot_admin_sysroot_lock (OstreeSysroot *sysroot, GError **error); + +gboolean ot_admin_execve_reboot (OstreeSysroot *sysroot, GError **error); G_END_DECLS diff --git a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c index d359846..e73ffa1 100644 --- a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c +++ b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c @@ -17,45 +17,39 @@ #include "config.h" -#include #include +#include -#include "ot-main.h" -#include "ot-admin-instutil-builtins.h" #include "ostree-cmd-private.h" +#include "ot-admin-instutil-builtins.h" +#include "ot-main.h" #include "otutil.h" -static GOptionEntry options[] = { - { NULL } -}; +static GOptionEntry options[] = { { NULL } }; gboolean -ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, + OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - guint bootversion; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - - context = g_option_context_new ("[BOOTVERSION]"); + g_autoptr (GOptionContext) context = g_option_context_new ("[BOOTVERSION]"); + g_autoptr (OstreeSysroot) sysroot = NULL; if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER + | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, invocation, &sysroot, cancellable, error)) - goto out; + return FALSE; + guint bootversion; if (argc >= 2) { - bootversion = (guint) g_ascii_strtoull (argv[1], NULL, 10); + bootversion = (guint)g_ascii_strtoull (argv[1], NULL, 10); if (!(bootversion == 0 || bootversion == 1)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid bootversion: %u", bootversion); - goto out; - } + return glnx_throw (error, "Invalid bootversion: %u", bootversion); } - else + else { const char *bootversion_env = g_getenv ("_OSTREE_GRUB2_BOOTVERSION"); if (bootversion_env) @@ -65,10 +59,6 @@ ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeCommandIn g_assert (bootversion == 0 || bootversion == 1); } - if (!ostree_cmd__private__()->ostree_generate_grub2_config (sysroot, bootversion, 1, cancellable, error)) - goto out; - - ret = TRUE; - out: - return ret; + return ostree_cmd__private__ ()->ostree_generate_grub2_config (sysroot, bootversion, 1, + cancellable, error); } diff --git a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c index 017ae5c..bc226fb 100644 --- a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c +++ b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c @@ -17,16 +17,16 @@ #include "config.h" -#include #include +#include -#include "ot-main.h" #include "ot-admin-instutil-builtins.h" +#include "ot-main.h" #include "otutil.h" static char * -ptrarray_path_join (GPtrArray *path) +ptrarray_path_join (GPtrArray *path) { GString *path_buf; @@ -50,86 +50,69 @@ ptrarray_path_join (GPtrArray *path) } static gboolean -relabel_one_path (OstreeSePolicy *sepolicy, - GFile *path, - GFileInfo *info, - GPtrArray *path_parts, - GCancellable *cancellable, - GError **error) +relabel_one_path (OstreeSePolicy *sepolicy, GFile *path, GFileInfo *info, GPtrArray *path_parts, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *relpath = NULL; g_autofree char *new_label = NULL; relpath = ptrarray_path_join (path_parts); - if (!ostree_sepolicy_restorecon (sepolicy, relpath, - info, path, - OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL | - OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING, - &new_label, - cancellable, error)) + if (!ostree_sepolicy_restorecon (sepolicy, relpath, info, path, + OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL + | OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING, + &new_label, cancellable, error)) { g_prefix_error (error, "Setting context of %s: ", gs_file_get_path_cached (path)); goto out; } if (new_label) - g_print ("Set label of '%s' (as '%s') to '%s'\n", - gs_file_get_path_cached (path), - relpath, + g_print ("Set label of '%s' (as '%s') to '%s'\n", gs_file_get_path_cached (path), relpath, new_label); ret = TRUE; - out: +out: return ret; } static gboolean -relabel_recursively (OstreeSePolicy *sepolicy, - GFile *dir, - GFileInfo *dir_info, - GPtrArray *path_parts, - GCancellable *cancellable, - GError **error) +relabel_recursively (OstreeSePolicy *sepolicy, GFile *dir, GFileInfo *dir_info, + GPtrArray *path_parts, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GFileEnumerator) direnum = NULL; + g_autoptr (GFileEnumerator) direnum = NULL; - if (!relabel_one_path (sepolicy, dir, dir_info, path_parts, - cancellable, error)) + if (!relabel_one_path (sepolicy, dir, dir_info, path_parts, cancellable, error)) goto out; direnum = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!direnum) goto out; - + while (TRUE) { GFileInfo *file_info; GFile *child; GFileType ftype; - if (!g_file_enumerator_iterate (direnum, &file_info, &child, - cancellable, error)) + if (!g_file_enumerator_iterate (direnum, &file_info, &child, cancellable, error)) goto out; if (file_info == NULL) break; - g_ptr_array_add (path_parts, (char*)g_file_info_get_name (file_info)); + g_ptr_array_add (path_parts, (char *)g_file_info_get_name (file_info)); ftype = g_file_info_get_file_type (file_info); if (ftype == G_FILE_TYPE_DIRECTORY) { - if (!relabel_recursively (sepolicy, child, file_info, path_parts, - cancellable, error)) + if (!relabel_recursively (sepolicy, child, file_info, path_parts, cancellable, error)) goto out; } else { - if (!relabel_one_path (sepolicy, child, file_info, path_parts, - cancellable, error)) + if (!relabel_one_path (sepolicy, child, file_info, path_parts, cancellable, error)) goto out; } @@ -137,70 +120,65 @@ relabel_recursively (OstreeSePolicy *sepolicy, } ret = TRUE; - out: +out: return ret; } static gboolean -selinux_relabel_dir (OstreeSePolicy *sepolicy, - GFile *dir, - const char *prefix, - GCancellable *cancellable, - GError **error) +selinux_relabel_dir (OstreeSePolicy *sepolicy, GFile *dir, const char *prefix, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GPtrArray) path_parts = g_ptr_array_new (); - g_autoptr(GFileInfo) root_info = NULL; + g_autoptr (GPtrArray) path_parts = g_ptr_array_new (); + g_autoptr (GFileInfo) root_info = NULL; root_info = g_file_query_info (dir, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!root_info) goto out; - - g_ptr_array_add (path_parts, (char*)prefix); - if (!relabel_recursively (sepolicy, dir, root_info, path_parts, - cancellable, error)) + + g_ptr_array_add (path_parts, (char *)prefix); + if (!relabel_recursively (sepolicy, dir, root_info, path_parts, cancellable, error)) { g_prefix_error (error, "Relabeling /%s: ", prefix); goto out; } ret = TRUE; - out: +out: return ret; } -static GOptionEntry options[] = { - { NULL } -}; +static GOptionEntry options[] = { { NULL } }; gboolean -ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, + OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const char *policy_name; - g_autoptr(GFile) subpath = NULL; + g_autoptr (GFile) subpath = NULL; const char *prefix = NULL; - g_autoptr(OstreeSePolicy) sepolicy = NULL; - g_autoptr(GPtrArray) deployments = NULL; + g_autoptr (OstreeSePolicy) sepolicy = NULL; + g_autoptr (GPtrArray) deployments = NULL; OstreeDeployment *first_deployment; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - g_autoptr(GFile) deployment_path = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; + g_autoptr (GFile) deployment_path = NULL; context = g_option_context_new ("[SUBPATH PREFIX]"); if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER + | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, invocation, &sysroot, cancellable, error)) goto out; deployments = ostree_sysroot_get_deployments (sysroot); if (deployments->len == 0) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unable to find a deployment in sysroot"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unable to find a deployment in sysroot"); goto out; } first_deployment = deployments->pdata[0]; @@ -220,13 +198,12 @@ ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeC sepolicy = ostree_sepolicy_new (deployment_path, cancellable, error); if (!sepolicy) goto out; - + policy_name = ostree_sepolicy_get_name (sepolicy); if (policy_name) { g_print ("Relabeling using policy '%s'\n", policy_name); - if (!selinux_relabel_dir (sepolicy, subpath, prefix, - cancellable, error)) + if (!selinux_relabel_dir (sepolicy, subpath, prefix, cancellable, error)) goto out; } else @@ -234,6 +211,6 @@ ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeC gs_file_get_path_cached (deployment_path)); ret = TRUE; - out: +out: return ret; } diff --git a/src/ostree/ot-admin-instutil-builtin-set-kargs.c b/src/ostree/ot-admin-instutil-builtin-set-kargs.c index ff773c3..90a69b4 100644 --- a/src/ostree/ot-admin-instutil-builtin-set-kargs.c +++ b/src/ostree/ot-admin-instutil-builtin-set-kargs.c @@ -17,51 +17,57 @@ #include "config.h" -#include #include +#include -#include "ot-main.h" #include "ot-admin-instutil-builtins.h" +#include "ot-main.h" -#include "otutil.h" #include "ostree.h" +#include "otutil.h" static gboolean opt_proc_cmdline; static gboolean opt_merge; static char **opt_replace; static char **opt_append; -static GOptionEntry options[] = { - { "import-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_proc_cmdline, "Import current /proc/cmdline", NULL }, - { "merge", 0, 0, G_OPTION_ARG_NONE, &opt_merge, "Merge with previous command line", NULL }, - { "replace", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_replace, "Set kernel argument, like root=/dev/sda1; this overrides any earlier argument with the same name", "NAME=VALUE" }, - { "append", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_append, "Append kernel argument; useful with e.g. console= that can be used multiple times", "NAME=VALUE" }, - { NULL } -}; +static GOptionEntry options[] + = { { "import-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_proc_cmdline, + "Import current /proc/cmdline", NULL }, + { "merge", 0, 0, G_OPTION_ARG_NONE, &opt_merge, "Merge with previous command line", NULL }, + { "replace", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_replace, + "Set kernel argument, like root=/dev/sda1; this overrides any earlier argument with the " + "same name", + "NAME=VALUE" }, + { "append", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_append, + "Append kernel argument; useful with e.g. console= that can be used multiple times", + "NAME=VALUE" }, + { NULL } }; gboolean -ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint i; - g_autoptr(GPtrArray) deployments = NULL; + g_autoptr (GPtrArray) deployments = NULL; OstreeDeployment *first_deployment = NULL; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - g_autoptr(OstreeKernelArgs) kargs = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeKernelArgs) kargs = NULL; context = g_option_context_new ("ARGS"); if (!ostree_admin_option_context_parse (context, options, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER + | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, invocation, &sysroot, cancellable, error)) goto out; deployments = ostree_sysroot_get_deployments (sysroot); if (deployments->len == 0) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unable to find a deployment in sysroot"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unable to find a deployment in sysroot"); goto out; } first_deployment = deployments->pdata[0]; @@ -79,7 +85,8 @@ ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeCommandInvocat else if (opt_merge) { OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (first_deployment); - g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); + g_auto (GStrv) previous_args + = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); ostree_kernel_args_append_argv (kargs, previous_args); } @@ -98,15 +105,14 @@ ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeCommandInvocat ostree_kernel_args_append (kargs, argv[i]); { - g_auto(GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs); + g_auto (GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs); - if (!ostree_sysroot_deployment_set_kargs (sysroot, first_deployment, - kargs_strv, - cancellable, error)) + if (!ostree_sysroot_deployment_set_kargs (sysroot, first_deployment, kargs_strv, cancellable, + error)) goto out; } ret = TRUE; - out: +out: return ret; } diff --git a/src/ostree/ot-admin-instutil-builtins.h b/src/ostree/ot-admin-instutil-builtins.h index 03a0bb6..746809e 100644 --- a/src/ostree/ot-admin-instutil-builtins.h +++ b/src/ostree/ot-admin-instutil-builtins.h @@ -19,12 +19,19 @@ #pragma once -#include +#include "ot-main.h" G_BEGIN_DECLS -gboolean ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error); -gboolean ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error); -gboolean ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error); +gboolean ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, + OstreeCommandInvocation *invocation, + GCancellable *cancellable, + GError **error); +gboolean ot_admin_instutil_builtin_set_kargs (int argc, char **argv, + OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error); +gboolean ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, + OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/src/ostree/ot-admin-kargs-builtin-edit-in-place.c b/src/ostree/ot-admin-kargs-builtin-edit-in-place.c new file mode 100644 index 0000000..cd434a7 --- /dev/null +++ b/src/ostree/ot-admin-kargs-builtin-edit-in-place.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 Colin Walters + * Copyright (C) 2022 Huijing Hei + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the licence or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library. If not, see . + */ + +#include "config.h" + +#include "ot-admin-kargs-builtins.h" +#include "ot-main.h" + +#include "ostree.h" +#include "otutil.h" + +static char **opt_kargs_edit_in_place_append; + +static GOptionEntry options[] + = { { "append-if-missing", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kargs_edit_in_place_append, + "Append kernel arguments if they do not exist", "NAME=VALUE" }, + { NULL } }; + +gboolean +ot_admin_kargs_builtin_edit_in_place (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) +{ + g_autoptr (OstreeSysroot) sysroot = NULL; + + g_autoptr (GOptionContext) context = g_option_context_new ("ARGS"); + + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, + OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot, + cancellable, error)) + return FALSE; + + g_autoptr (GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot); + if (deployments->len == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unable to find a deployment in sysroot"); + return FALSE; + } + + // set kargs for each deployment + for (guint i = 0; i < deployments->len; i++) + { + OstreeDeployment *deployment = deployments->pdata[i]; + OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment); + g_autoptr (OstreeKernelArgs) kargs + = ostree_kernel_args_from_string (ostree_bootconfig_parser_get (bootconfig, "options")); + + if (opt_kargs_edit_in_place_append) + { + for (char **strviter = opt_kargs_edit_in_place_append; strviter && *strviter; strviter++) + { + const char *arg = *strviter; + ostree_kernel_args_append_if_missing (kargs, arg); + } + } + + g_autofree char *new_options = ostree_kernel_args_to_string (kargs); + + if (!ostree_sysroot_deployment_set_kargs_in_place (sysroot, deployment, new_options, + cancellable, error)) + return FALSE; + } + + return TRUE; +} diff --git a/src/ostree/ot-builtin-trivial-httpd.c b/src/ostree/ot-admin-kargs-builtins.h similarity index 52% rename from src/ostree/ot-builtin-trivial-httpd.c rename to src/ostree/ot-admin-kargs-builtins.h index 71c286b..139e81d 100644 --- a/src/ostree/ot-builtin-trivial-httpd.c +++ b/src/ostree/ot-admin-kargs-builtins.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2016 Colin Walters + * Copyright (C) 2014 Colin Walters + * Copyright (C) 2022 Huijing Hei * * SPDX-License-Identifier: LGPL-2.0+ * @@ -17,24 +18,19 @@ * License along with this library. If not, see . */ -#include "config.h" +#pragma once #include "ot-main.h" -#include "ot-builtins.h" -#include "ostree.h" -#include "otutil.h" -gboolean -ostree_builtin_trivial_httpd (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) -{ - g_autoptr(GPtrArray) new_argv = g_ptr_array_new (); +G_BEGIN_DECLS - g_ptr_array_add (new_argv, PKGLIBEXECDIR "/ostree-trivial-httpd"); - for (int i = 1; i < argc; i++) - g_ptr_array_add (new_argv, argv[i]); - g_ptr_array_add (new_argv, NULL); - execvp (new_argv->pdata[0], (char**)new_argv->pdata); - /* Fall through on error */ - glnx_set_error_from_errno (error); - return FALSE; -} +#define BUILTINPROTO(name) \ + gboolean ot_admin_kargs_builtin_##name (int argc, char **argv, \ + OstreeCommandInvocation *invocation, \ + GCancellable *cancellable, GError **error) + +BUILTINPROTO (edit_in_place); + +#undef BUILTINPROTO + +G_END_DECLS diff --git a/src/ostree/ot-builtin-admin.c b/src/ostree/ot-builtin-admin.c index af09a61..e48f91e 100644 --- a/src/ostree/ot-builtin-admin.c +++ b/src/ostree/ot-builtin-admin.c @@ -21,61 +21,49 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" +#include "ostree-repo-file.h" +#include "ostree.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" -#include "ostree.h" -#include "ostree-repo-file.h" +#include "ot-builtins.h" +#include "ot-main.h" #include static OstreeCommand admin_subcommands[] = { - { "cleanup", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_cleanup, + { "cleanup", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_cleanup, "Delete untagged deployments and repository objects" }, - { "config-diff", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_diff, + { "config-diff", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_diff, "Diff current /etc configuration versus default" }, - { "deploy", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_deploy, + { "deploy", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_deploy, "Checkout revision REFSPEC as the new default deployment" }, { "finalize-staged", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN, - ot_admin_builtin_finalize_staged, - "Internal command to run at shutdown time" }, + ot_admin_builtin_finalize_staged, "Internal command to run at shutdown time" }, { "boot-complete", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN, - ot_admin_builtin_boot_complete, - "Internal command to run at boot after an update was applied" }, - { "init-fs", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_init_fs, + ot_admin_builtin_boot_complete, "Internal command to run at boot after an update was applied" }, + { "init-fs", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_init_fs, "Initialize a root filesystem" }, - { "instutil", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN, - ot_admin_builtin_instutil, + { "instutil", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN, ot_admin_builtin_instutil, "Deprecated commands intended for installer programs" }, - { "os-init", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_os_init, + { "os-init", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_os_init, "Initialize empty state for given operating system" }, - { "pin", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_pin, + { "stateroot-init", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_os_init, + "Initialize empty state for given operating system" }, + { "pin", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_pin, "Change the \"pinning\" state of a deployment" }, - { "set-origin", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_set_origin, + { "set-origin", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_set_origin, "Set Origin and create a new origin file" }, - { "status", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_status, - "List deployments" }, - { "switch", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_switch, + { "status", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_status, "List deployments" }, + { "switch", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_switch, "Construct new tree from REFSPEC and deploy it" }, - { "undeploy", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_undeploy, - "Delete deployment INDEX" }, - { "unlock", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_unlock, + { "undeploy", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_undeploy, "Delete deployment INDEX" }, + { "set-default", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_set_default, + "Make deployment INDEX the default" }, + { "unlock", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_unlock, "Make the current deployment mutable (as a hotfix or development)" }, - { "upgrade", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_admin_builtin_upgrade, + { "upgrade", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_upgrade, "Construct new tree from current origin and deploy it, if it changed" }, + { "kargs", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_kargs, "Change kernel arguments" }, { NULL, 0, NULL, NULL } }; @@ -85,7 +73,7 @@ ostree_admin_option_context_new_with_commands (void) OstreeCommand *command = admin_subcommands; GOptionContext *context = g_option_context_new ("--print-current-dir|COMMAND"); - g_autoptr(GString) summary = g_string_new ("Builtin \"admin\" Commands:"); + g_autoptr (GString) summary = g_string_new ("Builtin \"admin\" Commands:"); while (command->name != NULL) { @@ -104,20 +92,16 @@ ostree_admin_option_context_new_with_commands (void) } gboolean -ostree_builtin_admin (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_admin (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - const char *subcommand_name = NULL; - OstreeCommand *subcommand; - g_autofree char *prgname = NULL; - int in, out; - /* * Parse the global options. We rearrange the options as * necessary, in order to pass relevant options through * to the commands, but also have them take effect globally. */ - + int in, out; + const char *subcommand_name = NULL; for (in = 1, out = 1; in < argc; in++, out++) { /* The non-option is the command, take it out of the arguments */ @@ -141,7 +125,7 @@ ostree_builtin_admin (int argc, char **argv, OstreeCommandInvocation *invocation argc = out; - subcommand = admin_subcommands; + OstreeCommand *subcommand = admin_subcommands; while (subcommand->name) { if (g_strcmp0 (subcommand_name, subcommand->name) == 0) @@ -151,15 +135,15 @@ ostree_builtin_admin (int argc, char **argv, OstreeCommandInvocation *invocation if (!subcommand->name) { - g_autoptr(GOptionContext) context = NULL; + g_autoptr (GOptionContext) context = NULL; g_autofree char *help = NULL; context = ostree_admin_option_context_new_with_commands (); /* This will not return for some options (e.g. --version). */ if (ostree_admin_option_context_parse (context, NULL, &argc, &argv, - OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT, - invocation, NULL, cancellable, error)) + OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT, invocation, NULL, + cancellable, error)) { if (subcommand_name == NULL) { @@ -176,17 +160,14 @@ ostree_builtin_admin (int argc, char **argv, OstreeCommandInvocation *invocation help = g_option_context_get_help (context, FALSE, NULL); g_printerr ("%s", help); - goto out; + return FALSE; } - prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name); - g_set_prgname (prgname); + { + g_autofree char *prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name); + g_set_prgname (prgname); + } OstreeCommandInvocation sub_invocation = { .command = subcommand }; - if (!subcommand->fn (argc, argv, &sub_invocation, cancellable, error)) - goto out; - - ret = TRUE; - out: - return ret; + return subcommand->fn (argc, argv, &sub_invocation, cancellable, error); } diff --git a/src/ostree/ot-builtin-cat.c b/src/ostree/ot-builtin-cat.c index 6d9736e..58201b7 100644 --- a/src/ostree/ot-builtin-cat.c +++ b/src/ostree/ot-builtin-cat.c @@ -21,9 +21,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" #include @@ -38,28 +38,28 @@ static GOptionEntry options[] = { }; static gboolean -cat_one_file (GFile *f, - GOutputStream *stdout_stream, - GCancellable *cancellable, - GError **error) +cat_one_file (GFile *f, GOutputStream *stdout_stream, GCancellable *cancellable, GError **error) { - g_autoptr(GInputStream) in = (GInputStream*)g_file_read (f, cancellable, error); + g_autoptr (GInputStream) in = (GInputStream *)g_file_read (f, cancellable, error); if (!in) return FALSE; - if (g_output_stream_splice (stdout_stream, in, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - cancellable, error) < 0) + if (g_output_stream_splice (stdout_stream, in, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, cancellable, + error) + < 0) return FALSE; return TRUE; } gboolean -ostree_builtin_cat (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_cat (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("COMMIT PATH..."); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new ("COMMIT PATH..."); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (argc <= 2) @@ -69,15 +69,15 @@ ostree_builtin_cat (int argc, char **argv, OstreeCommandInvocation *invocation, } const char *rev = argv[1]; - g_autoptr(GFile) root = NULL; + g_autoptr (GFile) root = NULL; if (!ostree_repo_read_commit (repo, rev, &root, NULL, NULL, error)) return FALSE; - g_autoptr(GOutputStream) stdout_stream = g_unix_output_stream_new (1, FALSE); + g_autoptr (GOutputStream) stdout_stream = g_unix_output_stream_new (1, FALSE); for (int i = 2; i < argc; i++) { - g_autoptr(GFile) f = g_file_resolve_relative_path (root, argv[i]); + g_autoptr (GFile) f = g_file_resolve_relative_path (root, argv[i]); if (!cat_one_file (f, stdout_stream, cancellable, error)) return FALSE; diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c index d69c8b0..368c1f6 100644 --- a/src/ostree/ot-builtin-checkout.c +++ b/src/ostree/ot-builtin-checkout.c @@ -21,12 +21,12 @@ #include "config.h" -#include #include +#include -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_user_mode; @@ -37,6 +37,7 @@ static gboolean opt_union; static gboolean opt_union_add; static gboolean opt_union_identical; static gboolean opt_whiteouts; +static gboolean opt_process_passthrough_whiteouts; static gboolean opt_from_stdin; static char *opt_from_file; static gboolean opt_disable_fsync; @@ -49,10 +50,7 @@ static char *opt_selinux_policy; static char *opt_selinux_prefix; static gboolean -parse_fsync_cb (const char *option_name, - const char *value, - gpointer data, - GError **error) +parse_fsync_cb (const char *option_name, const char *value, gpointer data, GError **error) { gboolean val; @@ -70,31 +68,51 @@ parse_fsync_cb (const char *option_name, */ static GOptionEntry options[] = { - { "user-mode", 'U', 0, G_OPTION_ARG_NONE, &opt_user_mode, "Do not change file ownership or initialize extended attributes", NULL }, - { "disable-cache", 0, 0, G_OPTION_ARG_NONE, &opt_disable_cache, "Do not update or use the internal repository uncompressed object cache", NULL }, + { "user-mode", 'U', 0, G_OPTION_ARG_NONE, &opt_user_mode, + "Do not change file ownership or initialize extended attributes", NULL }, + { "disable-cache", 0, 0, G_OPTION_ARG_NONE, &opt_disable_cache, + "Do not update or use the internal repository uncompressed object cache", NULL }, { "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" }, - { "union", 0, 0, G_OPTION_ARG_NONE, &opt_union, "Keep existing directories, overwrite existing files", NULL }, - { "union-add", 0, 0, G_OPTION_ARG_NONE, &opt_union_add, "Keep existing files/directories, only add new", NULL }, - { "union-identical", 0, 0, G_OPTION_ARG_NONE, &opt_union_identical, "When layering checkouts, error out if a file would be replaced with a different version, but add new files and directories", NULL }, - { "whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_whiteouts, "Process 'whiteout' (Docker style) entries", NULL }, - { "allow-noent", 0, 0, G_OPTION_ARG_NONE, &opt_allow_noent, "Do nothing if specified path does not exist", NULL }, - { "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, "Process many checkouts from standard input", NULL }, - { "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" }, - { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" }, - { "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, "Do not fall back to full copies if hardlinking fails", NULL }, - { "force-copy-zerosized", 'z', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_force_copy_zerosized, "Do not hardlink zero-sized files", NULL }, - { "force-copy", 'C', 0, G_OPTION_ARG_NONE, &opt_force_copy, "Never hardlink (but may reflink if available)", NULL }, - { "bareuseronly-dirs", 'M', 0, G_OPTION_ARG_NONE, &opt_bareuseronly_dirs, "Suppress mode bits outside of 0775 for directories (suid, world writable, etc.)", NULL }, - { "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "FILE" }, - { "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /); implies --force-copy", "PATH" }, - { "selinux-prefix", 0, 0, G_OPTION_ARG_STRING, &opt_selinux_prefix, "When setting SELinux labels, prefix all paths by PREFIX", "PREFIX" }, + { "union", 0, 0, G_OPTION_ARG_NONE, &opt_union, + "Keep existing directories, overwrite existing files", NULL }, + { "union-add", 0, 0, G_OPTION_ARG_NONE, &opt_union_add, + "Keep existing files/directories, only add new", NULL }, + { "union-identical", 0, 0, G_OPTION_ARG_NONE, &opt_union_identical, + "When layering checkouts, error out if a file would be replaced with a different version, but " + "add new files and directories", + NULL }, + { "whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_whiteouts, + "Process 'whiteout' (Docker style) entries", NULL }, + { "process-passthrough-whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_process_passthrough_whiteouts, + "Enable overlayfs whiteout extraction into char 0:0 devices", NULL }, + { "allow-noent", 0, 0, G_OPTION_ARG_NONE, &opt_allow_noent, + "Do nothing if specified path does not exist", NULL }, + { "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, + "Process many checkouts from standard input", NULL }, + { "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, + "Process many checkouts from input file", "FILE" }, + { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", + "POLICY" }, + { "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, + "Do not fall back to full copies if hardlinking fails", NULL }, + { "force-copy-zerosized", 'z', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_force_copy_zerosized, + "Do not hardlink zero-sized files", NULL }, + { "force-copy", 'C', 0, G_OPTION_ARG_NONE, &opt_force_copy, + "Never hardlink (but may reflink if available)", NULL }, + { "bareuseronly-dirs", 'M', 0, G_OPTION_ARG_NONE, &opt_bareuseronly_dirs, + "Suppress mode bits outside of 0775 for directories (suid, world writable, etc.)", NULL }, + { "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, + "File containing list of files to skip", "FILE" }, + { "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, + "Set SELinux labels based on policy in root filesystem PATH (may be /); implies --force-copy", + "PATH" }, + { "selinux-prefix", 0, 0, G_OPTION_ARG_STRING, &opt_selinux_prefix, + "When setting SELinux labels, prefix all paths by PREFIX", "PREFIX" }, { NULL } }; static gboolean -handle_skiplist_line (const char *line, - void *data, - GError **error) +handle_skiplist_line (const char *line, void *data, GError **error) { GHashTable *files = data; g_hash_table_add (files, g_strdup (line)); @@ -102,10 +120,7 @@ handle_skiplist_line (const char *line, } static OstreeRepoCheckoutFilterResult -checkout_filter (OstreeRepo *self, - const char *path, - struct stat *st_buf, - gpointer user_data) +checkout_filter (OstreeRepo *self, const char *path, struct stat *st_buf, gpointer user_data) { GHashTable *skiplist = user_data; if (g_hash_table_contains (skiplist, path)) @@ -114,24 +129,22 @@ checkout_filter (OstreeRepo *self, } static gboolean -process_one_checkout (OstreeRepo *repo, - const char *resolved_commit, - const char *subpath, - const char *destination, - GCancellable *cancellable, - GError **error) +process_one_checkout (OstreeRepo *repo, const char *resolved_commit, const char *subpath, + const char *destination, GCancellable *cancellable, GError **error) { /* This strange code structure is to preserve testing * coverage of both `ostree_repo_checkout_tree` and * `ostree_repo_checkout_at` until such time as we have a more * convenient infrastructure for testing C APIs with data. */ - if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || - opt_union_add || opt_force_copy || opt_force_copy_zerosized || - opt_bareuseronly_dirs || opt_union_identical || - opt_skiplist_file || opt_selinux_policy || opt_selinux_prefix) + if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || opt_union_add || opt_force_copy + || opt_force_copy_zerosized || opt_bareuseronly_dirs || opt_union_identical + || opt_skiplist_file || opt_selinux_policy || opt_selinux_prefix + || opt_process_passthrough_whiteouts) { - OstreeRepoCheckoutAtOptions checkout_options = { 0, }; + OstreeRepoCheckoutAtOptions checkout_options = { + 0, + }; /* do this early so option checking also catches force copy conflicts */ if (opt_selinux_policy) @@ -162,10 +175,12 @@ process_one_checkout (OstreeRepo *repo, } if (opt_whiteouts) checkout_options.process_whiteouts = TRUE; + if (opt_process_passthrough_whiteouts) + checkout_options.process_passthrough_whiteouts = TRUE; if (subpath) checkout_options.subpath = subpath; - g_autoptr(OstreeSePolicy) policy = NULL; + g_autoptr (OstreeSePolicy) policy = NULL; if (opt_selinux_policy) { glnx_autofd int rootfs_dfd = -1; @@ -178,8 +193,8 @@ process_one_checkout (OstreeRepo *repo, checkout_options.sepolicy_prefix = opt_selinux_prefix; } - g_autoptr(GHashTable) skip_list = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_autoptr (GHashTable) skip_list + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); if (opt_skiplist_file) { if (!ot_parse_file_by_line (opt_skiplist_file, handle_skiplist_line, skip_list, @@ -194,35 +209,31 @@ process_one_checkout (OstreeRepo *repo, checkout_options.force_copy_zerosized = opt_force_copy_zerosized; checkout_options.bareuseronly_dirs = opt_bareuseronly_dirs; - if (!ostree_repo_checkout_at (repo, &checkout_options, - AT_FDCWD, destination, - resolved_commit, + if (!ostree_repo_checkout_at (repo, &checkout_options, AT_FDCWD, destination, resolved_commit, cancellable, error)) return FALSE; } else { GError *tmp_error = NULL; - g_autoptr(GFile) root = NULL; - g_autoptr(GFile) destination_file = g_file_new_for_path (destination); + g_autoptr (GFile) root = NULL; + g_autoptr (GFile) destination_file = g_file_new_for_path (destination); if (!ostree_repo_read_commit (repo, resolved_commit, &root, NULL, cancellable, error)) return FALSE; - g_autoptr(GFile) subtree = NULL; + g_autoptr (GFile) subtree = NULL; if (subpath) subtree = g_file_resolve_relative_path (root, subpath); else subtree = g_object_ref (root); - g_autoptr(GFileInfo) file_info - = g_file_query_info (subtree, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, &tmp_error); + g_autoptr (GFileInfo) file_info + = g_file_query_info (subtree, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, &tmp_error); if (!file_info) { - if (opt_allow_noent - && g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + if (opt_allow_noent && g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_clear_error (&tmp_error); /* Note early return */ @@ -237,8 +248,7 @@ process_one_checkout (OstreeRepo *repo, if (!ostree_repo_checkout_tree (repo, opt_user_mode ? OSTREE_REPO_CHECKOUT_MODE_USER : 0, opt_union ? OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES : 0, - destination_file, - OSTREE_REPO_FILE (subtree), file_info, + destination_file, OSTREE_REPO_FILE (subtree), file_info, cancellable, error)) return FALSE; } @@ -247,84 +257,76 @@ process_one_checkout (OstreeRepo *repo, } static gboolean -process_many_checkouts (OstreeRepo *repo, - const char *target, - GCancellable *cancellable, - GError **error) +process_many_checkouts (OstreeRepo *repo, const char *target, GCancellable *cancellable, + GError **error) { - gboolean ret = FALSE; - gsize len; GError *temp_error = NULL; - g_autoptr(GInputStream) instream = NULL; - g_autoptr(GDataInputStream) datastream = NULL; - g_autofree char *revision = NULL; - g_autofree char *subpath = NULL; - g_autofree char *resolved_commit = NULL; + g_autoptr (GInputStream) instream = NULL; if (opt_from_stdin) { - instream = (GInputStream*)g_unix_input_stream_new (0, FALSE); + instream = (GInputStream *)g_unix_input_stream_new (0, FALSE); } else { - g_autoptr(GFile) f = g_file_new_for_path (opt_from_file); + g_autoptr (GFile) f = g_file_new_for_path (opt_from_file); - instream = (GInputStream*)g_file_read (f, cancellable, error); + instream = (GInputStream *)g_file_read (f, cancellable, error); if (!instream) - goto out; + return FALSE; } - datastream = g_data_input_stream_new (instream); + g_autoptr (GDataInputStream) datastream = g_data_input_stream_new (instream); - while ((revision = g_data_input_stream_read_upto (datastream, "", 1, &len, - cancellable, &temp_error)) != NULL) + g_autofree char *resolved_commit = NULL; + g_autofree char *revision = NULL; + gsize len; + while ( + (revision = g_data_input_stream_read_upto (datastream, "", 1, &len, cancellable, &temp_error)) + != NULL) { if (revision[0] == '\0') break; /* Read the null byte */ - (void) g_data_input_stream_read_byte (datastream, cancellable, NULL); - g_free (subpath); - subpath = g_data_input_stream_read_upto (datastream, "", 1, &len, - cancellable, &temp_error); + (void)g_data_input_stream_read_byte (datastream, cancellable, NULL); + g_autofree char *subpath + = g_data_input_stream_read_upto (datastream, "", 1, &len, cancellable, &temp_error); if (temp_error) { g_propagate_error (error, temp_error); - goto out; + return FALSE; } /* Read the null byte */ - (void) g_data_input_stream_read_byte (datastream, cancellable, NULL); + (void)g_data_input_stream_read_byte (datastream, cancellable, NULL); if (!ostree_repo_resolve_rev (repo, revision, FALSE, &resolved_commit, error)) - goto out; + return FALSE; - if (!process_one_checkout (repo, resolved_commit, subpath, target, - cancellable, error)) + if (!process_one_checkout (repo, resolved_commit, subpath, target, cancellable, error)) { g_prefix_error (error, "Processing tree %s: ", resolved_commit); - goto out; + return FALSE; } - - g_free (revision); } if (temp_error) { g_propagate_error (error, temp_error); - goto out; + return FALSE; } - ret = TRUE; - out: - return ret; + return TRUE; } gboolean -ostree_builtin_checkout (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_checkout (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("COMMIT [DESTINATION]"); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new ("COMMIT [DESTINATION]"); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (opt_disable_fsync) @@ -357,9 +359,8 @@ ostree_builtin_checkout (int argc, char **argv, OstreeCommandInvocation *invocat if (!ostree_repo_resolve_rev (repo, commit, FALSE, &resolved_commit, error)) return FALSE; - if (!process_one_checkout (repo, resolved_commit, opt_subpath, - destination, - cancellable, error)) + if (!process_one_checkout (repo, resolved_commit, opt_subpath, destination, cancellable, + error)) return FALSE; } diff --git a/src/ostree/ot-builtin-checksum.c b/src/ostree/ot-builtin-checksum.c index 576fbfd..b3b15c2 100644 --- a/src/ostree/ot-builtin-checksum.c +++ b/src/ostree/ot-builtin-checksum.c @@ -21,9 +21,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include @@ -34,30 +34,28 @@ static gboolean opt_ignore_xattrs; -static GOptionEntry options[] = { - { "ignore-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_ignore_xattrs, "Don't include xattrs in checksum", NULL }, - { NULL } -}; +static GOptionEntry options[] = { { "ignore-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_ignore_xattrs, + "Don't include xattrs in checksum", NULL }, + { NULL } }; -typedef struct { +typedef struct +{ GError **error; gboolean success; GMainLoop *loop; } AsyncChecksumData; static void -on_checksum_received (GObject *obj, - GAsyncResult *result, - gpointer user_data) +on_checksum_received (GObject *obj, GAsyncResult *result, gpointer user_data) { AsyncChecksumData *data = user_data; g_autofree guchar *csum_bytes = NULL; - data->success = - ostree_checksum_file_async_finish ((GFile*)obj, result, &csum_bytes, data->error); + data->success + = ostree_checksum_file_async_finish ((GFile *)obj, result, &csum_bytes, data->error); if (data->success) { - char csum[OSTREE_SHA256_STRING_LEN+1]; + char csum[OSTREE_SHA256_STRING_LEN + 1]; ostree_checksum_inplace_from_bytes (csum_bytes, csum); g_print ("%s\n", csum); } @@ -66,12 +64,12 @@ on_checksum_received (GObject *obj, } gboolean -ostree_builtin_checksum (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_checksum (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = - g_option_context_new ("PATH"); - if (!ostree_option_context_parse (context, options, &argc, &argv, - invocation, NULL, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new ("PATH"); + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, NULL, cancellable, + error)) return FALSE; if (argc < 2) @@ -81,23 +79,24 @@ ostree_builtin_checksum (int argc, char **argv, OstreeCommandInvocation *invocat /* for test coverage, use the async API if no flags are needed */ if (!opt_ignore_xattrs) { - g_autoptr(GFile) f = g_file_new_for_path (path); - g_autoptr(GMainLoop) loop = g_main_loop_new (NULL, FALSE); + g_autoptr (GFile) f = g_file_new_for_path (path); + g_autoptr (GMainLoop) loop = g_main_loop_new (NULL, FALSE); - AsyncChecksumData data = { 0, }; + AsyncChecksumData data = { + 0, + }; data.loop = loop; data.error = error; - ostree_checksum_file_async (f, OSTREE_OBJECT_TYPE_FILE, G_PRIORITY_DEFAULT, - cancellable, on_checksum_received, &data); + ostree_checksum_file_async (f, OSTREE_OBJECT_TYPE_FILE, G_PRIORITY_DEFAULT, cancellable, + on_checksum_received, &data); g_main_loop_run (data.loop); return data.success; } g_autofree char *checksum = NULL; if (!ostree_checksum_file_at (AT_FDCWD, path, NULL, OSTREE_OBJECT_TYPE_FILE, - OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS, &checksum, - cancellable, error)) + OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS, &checksum, cancellable, error)) return FALSE; g_print ("%s\n", checksum); diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c index c43f9b3..0309e73 100644 --- a/src/ostree/ot-builtin-commit.c +++ b/src/ostree/ot-builtin-commit.c @@ -21,15 +21,15 @@ #include "config.h" -#include "ot-main.h" +#include "ostree-libarchive-private.h" +#include "ostree-repo-private.h" +#include "ostree-sign.h" +#include "ostree.h" #include "ot-builtins.h" #include "ot-editor.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" #include "parse-datetime.h" -#include "ostree-repo-private.h" -#include "ostree-libarchive-private.h" -#include "ostree-sign.h" static char *opt_subject; static char *opt_body; @@ -54,6 +54,7 @@ static char *opt_tar_pathname_filter; static gboolean opt_no_xattrs; static char *opt_selinux_policy; static gboolean opt_selinux_policy_from_base; +static int opt_selinux_labeling_epoch; static gboolean opt_canonical_permissions; static gboolean opt_ro_executables; static gboolean opt_consume; @@ -68,16 +69,15 @@ static char **opt_gpg_key_ids; static char *opt_gpg_homedir; #endif static char **opt_key_ids; +static char **opt_key_files; static char *opt_sign_name; static gboolean opt_generate_sizes; +static gboolean opt_composefs_metadata; static gboolean opt_disable_fsync; static char *opt_timestamp; static gboolean -parse_fsync_cb (const char *option_name, - const char *value, - gpointer data, - GError **error) +parse_fsync_cb (const char *option_name, const char *value, gpointer data, GError **error) { gboolean val; if (!ot_parse_boolean (value, &val, error)) @@ -93,61 +93,103 @@ parse_fsync_cb (const char *option_name, */ static GOptionEntry options[] = { - { "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent commit checksum, or \"none\"", "COMMIT" }, + { "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent commit checksum, or \"none\"", + "COMMIT" }, { "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, "One line subject", "SUBJECT" }, { "body", 'm', 0, G_OPTION_ARG_STRING, &opt_body, "Full description", "BODY" }, - { "body-file", 'F', 0, G_OPTION_ARG_FILENAME, &opt_body_file, "Commit message from FILE path", "FILE" }, - { "editor", 'e', 0, G_OPTION_ARG_NONE, &opt_editor, "Use an editor to write the commit message", NULL }, + { "body-file", 'F', 0, G_OPTION_ARG_FILENAME, &opt_body_file, "Commit message from FILE path", + "FILE" }, + { "editor", 'e', 0, G_OPTION_ARG_NONE, &opt_editor, "Use an editor to write the commit message", + NULL }, { "branch", 'b', 0, G_OPTION_ARG_STRING, &opt_branch, "Branch", "BRANCH" }, { "orphan", 0, 0, G_OPTION_ARG_NONE, &opt_orphan, "Create a commit without writing a ref", NULL }, - { "no-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_no_bindings, "Do not write any ref bindings", NULL }, - { "bind-ref", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_bind_refs, "Add a ref to ref binding commit metadata", "BRANCH" }, - { "base", 0, 0, G_OPTION_ARG_STRING, &opt_base, "Start from the given commit as a base (no modifiers apply)", "REV" }, - { "tree", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_trees, "Overlay the given argument as a tree", "dir=PATH or tar=TARFILE or ref=COMMIT" }, - { "add-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_strings, "Add a key/value pair to metadata", "KEY=VALUE" }, - { "add-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_variants, "Add a key/value pair to metadata, where the KEY is a string, an VALUE is g_variant_parse() formatted", "KEY=VALUE" }, - { "keep-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_keep, "Keep metadata KEY and its associated VALUE from parent", "KEY" }, - { "add-detached-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_detached_metadata_strings, "Add a key/value pair to detached metadata", "KEY=VALUE" }, + { "no-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_no_bindings, "Do not write any ref bindings", + NULL }, + { "bind-ref", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_bind_refs, + "Add a ref to ref binding commit metadata", "BRANCH" }, + { "base", 0, 0, G_OPTION_ARG_STRING, &opt_base, + "Start from the given commit as a base (no modifiers apply)", "REV" }, + { "tree", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_trees, "Overlay the given argument as a tree", + "dir=PATH or tar=TARFILE or ref=COMMIT" }, + { "add-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_strings, + "Add a key/value pair to metadata", "KEY=VALUE" }, + { "add-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_variants, + "Add a key/value pair to metadata, where the KEY is a string, and VALUE is in GVariant Text " + "Format", + "KEY=VALUE" }, + { "keep-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_keep, + "Keep metadata KEY and its associated VALUE from parent", "KEY" }, + { "add-detached-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_detached_metadata_strings, + "Add a key/value pair to detached metadata", "KEY=VALUE" }, { "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, "Set file ownership user id", "UID" }, { "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Set file ownership group id", "GID" }, - { "canonical-permissions", 0, 0, G_OPTION_ARG_NONE, &opt_canonical_permissions, "Canonicalize permissions in the same way bare-user does for hardlinked files", NULL }, - { "bootable", 0, 0, G_OPTION_ARG_NONE, &opt_bootable, "Flag this commit as a bootable OSTree (e.g. contains a Linux kernel)", NULL }, - { "mode-ro-executables", 0, 0, G_OPTION_ARG_NONE, &opt_ro_executables, "Ensure executable files are not writable", NULL }, - { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Do not import extended attributes", NULL }, - { "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /)", "PATH" }, - { "selinux-policy-from-base", 'P', 0, G_OPTION_ARG_NONE, &opt_selinux_policy_from_base, "Set SELinux labels based on first --tree argument", NULL }, - { "link-checkout-speedup", 0, 0, G_OPTION_ARG_NONE, &opt_link_checkout_speedup, "Optimize for commits of trees composed of hardlinks into the repository", NULL }, - { "devino-canonical", 'I', 0, G_OPTION_ARG_NONE, &opt_devino_canonical, "Assume hardlinked objects are unmodified. Implies --link-checkout-speedup", NULL }, - { "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL }, - { "tar-pathname-filter", 0, 0, G_OPTION_ARG_STRING, &opt_tar_pathname_filter, "When loading tar archives, use REGEX,REPLACEMENT against path names", "REGEX,REPLACEMENT" }, - { "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &opt_skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL }, - { "statoverride", 0, 0, G_OPTION_ARG_FILENAME, &opt_statoverride_file, "File containing list of modifications to make to permissions", "PATH" }, - { "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "PATH" }, - { "consume", 0, 0, G_OPTION_ARG_NONE, &opt_consume, "Consume (delete) content after commit (for local directories)", NULL }, - { "table-output", 0, 0, G_OPTION_ARG_NONE, &opt_table_output, "Output more information in a KEY: VALUE format", NULL }, + { "canonical-permissions", 0, 0, G_OPTION_ARG_NONE, &opt_canonical_permissions, + "Canonicalize permissions in the same way bare-user does for hardlinked files", NULL }, + { "bootable", 0, 0, G_OPTION_ARG_NONE, &opt_bootable, + "Flag this commit as a bootable OSTree (e.g. contains a Linux kernel)", NULL }, + { "mode-ro-executables", 0, 0, G_OPTION_ARG_NONE, &opt_ro_executables, + "Ensure executable files are not writable", NULL }, + { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Do not import extended attributes", + NULL }, + { "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, + "Set SELinux labels based on policy in root filesystem PATH (may be /)", "PATH" }, + { "selinux-policy-from-base", 'P', 0, G_OPTION_ARG_NONE, &opt_selinux_policy_from_base, + "Set SELinux labels based on first --tree argument", NULL }, + { "selinux-labeling-epoch", 0, 0, G_OPTION_ARG_INT, &opt_selinux_labeling_epoch, + "Configure the default SELinux labeling rules; 0 is the default, 1 enables labeling /usr/etc " + "as /etc", + NULL }, + { "link-checkout-speedup", 0, 0, G_OPTION_ARG_NONE, &opt_link_checkout_speedup, + "Optimize for commits of trees composed of hardlinks into the repository", NULL }, + { "devino-canonical", 'I', 0, G_OPTION_ARG_NONE, &opt_devino_canonical, + "Assume hardlinked objects are unmodified. Implies --link-checkout-speedup", NULL }, + { "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, + "When loading tar archives, automatically create parent directories as needed", NULL }, + { "tar-pathname-filter", 0, 0, G_OPTION_ARG_STRING, &opt_tar_pathname_filter, + "When loading tar archives, use REGEX,REPLACEMENT against path names", "REGEX,REPLACEMENT" }, + { "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &opt_skip_if_unchanged, + "If the contents are unchanged from previous commit, do nothing", NULL }, + { "statoverride", 0, 0, G_OPTION_ARG_FILENAME, &opt_statoverride_file, + "File containing list of modifications to make to permissions", "PATH" }, + { "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, + "File containing list of files to skip", "PATH" }, + { "consume", 0, 0, G_OPTION_ARG_NONE, &opt_consume, + "Consume (delete) content after commit (for local directories)", NULL }, + { "table-output", 0, 0, G_OPTION_ARG_NONE, &opt_table_output, + "Output more information in a KEY: VALUE format", NULL }, #ifndef OSTREE_DISABLE_GPGME - { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, "GPG Key ID to sign the commit with", "KEY-ID"}, - { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"}, + { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, + "GPG Key ID to sign the commit with", "KEY-ID" }, + { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, + "GPG Homedir to use when looking for keyrings", "HOMEDIR" }, #endif - { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Sign the commit with", "KEY_ID"}, - { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"}, - { "generate-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_generate_sizes, "Generate size information along with commit metadata", NULL }, - { "disable-fsync", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, - { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" }, - { "timestamp", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp, "Override the timestamp of the commit", "TIMESTAMP" }, + { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Sign the commit with", "KEY_ID" }, + { "sign-from-file", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_files, + "Sign the commit with key from the provided file", "PATH" }, + { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, + "Signature type to use (defaults to 'ed25519')", "NAME" }, + { "generate-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_generate_sizes, + "Generate size information along with commit metadata", NULL }, + { "generate-composefs-metadata", 0, 0, G_OPTION_ARG_NONE, &opt_composefs_metadata, + "Generate composefs commit metadata", NULL }, + { "disable-fsync", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_disable_fsync, + "Do not invoke fsync()", NULL }, + { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", + "POLICY" }, + { "timestamp", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp, "Override the timestamp of the commit", + "TIMESTAMP" }, { NULL } }; -struct CommitFilterData { +struct CommitFilterData +{ GHashTable *mode_adds; GHashTable *mode_overrides; GHashTable *skip_list; }; static gboolean -handle_statoverride_line (const char *line, - void *data, - GError **error) +handle_statoverride_line (const char *line, void *data, GError **error) { struct CommitFilterData *cf = data; const char *spc = strchr (line, ' '); @@ -157,23 +199,20 @@ handle_statoverride_line (const char *line, if (g_str_has_prefix (line, "=")) { - guint mode_override = (guint32)(gint32)g_ascii_strtod (line+1, NULL); + guint mode_override = (guint32)(gint32)g_ascii_strtod (line + 1, NULL); g_hash_table_insert (cf->mode_overrides, g_strdup (fn), - GUINT_TO_POINTER((gint32)mode_override)); + GUINT_TO_POINTER ((gint32)mode_override)); } else { guint mode_add = (guint32)(gint32)g_ascii_strtod (line, NULL); - g_hash_table_insert (cf->mode_adds, g_strdup (fn), - GUINT_TO_POINTER((gint32)mode_add)); + g_hash_table_insert (cf->mode_adds, g_strdup (fn), GUINT_TO_POINTER ((gint32)mode_add)); } return TRUE; } static gboolean -handle_skiplist_line (const char *line, - void *data, - GError **error) +handle_skiplist_line (const char *line, void *data, GError **error) { GHashTable *files = data; g_hash_table_add (files, g_strdup (line)); @@ -181,10 +220,7 @@ handle_skiplist_line (const char *line, } static OstreeRepoCommitFilterResult -commit_filter (OstreeRepo *self, - const char *path, - GFileInfo *file_info, - gpointer user_data) +commit_filter (OstreeRepo *self, const char *path, GFileInfo *file_info, gpointer user_data) { struct CommitFilterData *data = user_data; GHashTable *mode_adds = data->mode_adds; @@ -207,16 +243,14 @@ commit_filter (OstreeRepo *self, if (mode_adds && g_hash_table_lookup_extended (mode_adds, path, NULL, &value)) { guint mode_add = GPOINTER_TO_UINT (value); - g_file_info_set_attribute_uint32 (file_info, "unix::mode", - mode | mode_add); + g_file_info_set_attribute_uint32 (file_info, "unix::mode", mode | mode_add); g_hash_table_remove (mode_adds, path); } else if (mode_overrides && g_hash_table_lookup_extended (mode_overrides, path, NULL, &value)) { guint current_fmt = g_file_info_get_attribute_uint32 (file_info, "unix::mode") & S_IFMT; guint mode_override = GPOINTER_TO_UINT (value); - g_file_info_set_attribute_uint32 (file_info, "unix::mode", - current_fmt | mode_override); + g_file_info_set_attribute_uint32 (file_info, "unix::mode", current_fmt | mode_override); g_hash_table_remove (mode_adds, path); } @@ -230,23 +264,20 @@ commit_filter (OstreeRepo *self, } #ifdef HAVE_LIBARCHIVE -typedef struct { +typedef struct +{ GRegex *regex; const char *replacement; } TranslatePathnameData; /* Implement --tar-pathname-filter */ static char * -handle_translate_pathname (OstreeRepo *repo, - const struct stat *stbuf, - const char *path, +handle_translate_pathname (OstreeRepo *repo, const struct stat *stbuf, const char *path, gpointer user_data) { TranslatePathnameData *tpdata = user_data; - g_autoptr(GError) tmp_error = NULL; - char *ret = - g_regex_replace (tpdata->regex, path, -1, 0, - tpdata->replacement, 0, &tmp_error); + g_autoptr (GError) tmp_error = NULL; + char *ret = g_regex_replace (tpdata->regex, path, -1, 0, tpdata->replacement, 0, &tmp_error); g_assert_no_error (tmp_error); g_assert (ret); return ret; @@ -254,22 +285,17 @@ handle_translate_pathname (OstreeRepo *repo, #endif static gboolean -commit_editor (OstreeRepo *repo, - const char *branch, - char **subject, - char **body, - GCancellable *cancellable, - GError **error) +commit_editor (OstreeRepo *repo, const char *branch, char **subject, char **body, + GCancellable *cancellable, GError **error) { - g_autofree char *input = g_strdup_printf ("\n" + g_autofree char *input = g_strdup_printf ( + "\n" "# Please enter the commit message for your changes. The first line will\n" "# become the subject, and the remainder the body. Lines starting\n" "# with '#' will be ignored, and an empty message aborts the commit." - "%s%s%s%s%s%s\n" - , branch ? "\n#\n# Branch: " : "", branch ? branch : "" - , *subject ? "\n" : "", *subject ? *subject : "" - , *body ? "\n" : "", *body ? *body : "" - ); + "%s%s%s%s%s%s\n", + branch ? "\n#\n# Branch: " : "", branch ? branch : "", *subject ? "\n" : "", + *subject ? *subject : "", *body ? "\n" : "", *body ? *body : ""); *subject = NULL; *body = NULL; @@ -278,8 +304,8 @@ commit_editor (OstreeRepo *repo, if (output == NULL) return FALSE; - g_auto(GStrv) lines = g_strsplit (output, "\n", -1); - g_autoptr(GString) bodybuf = NULL; + g_auto (GStrv) lines = g_strsplit (output, "\n", -1); + g_autoptr (GString) bodybuf = NULL; for (guint i = 0; lines[i] != NULL; i++) { g_strchomp (lines[i]); @@ -323,12 +349,10 @@ commit_editor (OstreeRepo *repo, } static gboolean -parse_keyvalue_strings (GVariantBuilder *builder, - char **strings, - gboolean is_gvariant_print, - GError **error) +parse_keyvalue_strings (GVariantBuilder *builder, char **strings, gboolean is_gvariant_print, + GError **error) { - for (char ** iter = strings; *iter; iter++) + for (char **iter = strings; *iter; iter++) { const char *s = *iter; const char *eq = strchr (s, '='); @@ -338,23 +362,21 @@ parse_keyvalue_strings (GVariantBuilder *builder, const char *value = eq + 1; if (is_gvariant_print) { - g_autoptr(GVariant) variant = g_variant_parse (NULL, value, NULL, NULL, error); + g_autoptr (GVariant) variant = g_variant_parse (NULL, value, NULL, NULL, error); if (!variant) return glnx_prefix_error (error, "Parsing %s", s); g_variant_builder_add (builder, "{sv}", key, variant); } else - g_variant_builder_add (builder, "{sv}", key, - g_variant_new_string (value)); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (value)); } return TRUE; } static void -add_collection_binding (OstreeRepo *repo, - GVariantBuilder *metadata_builder) +add_collection_binding (OstreeRepo *repo, GVariantBuilder *metadata_builder) { const char *collection_id = ostree_repo_get_collection_id (repo); @@ -379,67 +401,68 @@ add_ref_binding (GVariantBuilder *metadata_builder) { g_assert (opt_branch != NULL || opt_orphan); - g_autoptr(GPtrArray) refs = g_ptr_array_new (); + g_autoptr (GPtrArray) refs = g_ptr_array_new (); if (opt_branch != NULL) g_ptr_array_add (refs, opt_branch); for (char **iter = opt_bind_refs; iter != NULL && *iter != NULL; ++iter) g_ptr_array_add (refs, *iter); g_ptr_array_sort (refs, compare_strings); - g_autoptr(GVariant) refs_v = g_variant_new_strv ((const char *const *)refs->pdata, - refs->len); + g_autoptr (GVariant) refs_v = g_variant_new_strv ((const char *const *)refs->pdata, refs->len); g_variant_builder_add (metadata_builder, "{s@v}", OSTREE_COMMIT_META_KEY_REF_BINDING, g_variant_new_variant (g_steal_pointer (&refs_v))); } /* Note if you're using the API, you currently need to do this yourself */ static void -fill_bindings (OstreeRepo *repo, - GVariant *metadata, - GVariant **out_metadata) +fill_bindings (OstreeRepo *repo, GVariant *metadata, GVariant **out_metadata) { - g_autoptr(GVariantBuilder) metadata_builder = - ot_util_variant_builder_from_variant (metadata, G_VARIANT_TYPE_VARDICT); + g_autoptr (GVariantBuilder) metadata_builder + = ot_util_variant_builder_from_variant (metadata, G_VARIANT_TYPE_VARDICT); add_ref_binding (metadata_builder); /* Allow the collection ID to be overridden using * --add-metadata-string=ostree.collection-binding=blah */ - if (metadata == NULL || - !g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "*", NULL)) + if (metadata == NULL + || !g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "*", NULL)) add_collection_binding (repo, metadata_builder); *out_metadata = g_variant_ref_sink (g_variant_builder_end (metadata_builder)); } gboolean -ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; gboolean ret = FALSE; gboolean skip_commit = FALSE; - g_autoptr(GFile) object_to_commit = NULL; + g_autoptr (GFile) object_to_commit = NULL; g_autofree char *parent = NULL; g_autofree char *commit_checksum = NULL; - g_autoptr(GFile) root = NULL; - g_autoptr(GVariant) metadata = NULL; - g_autoptr(GVariant) detached_metadata = NULL; - g_autoptr(OstreeMutableTree) mtree = NULL; + g_autoptr (GFile) root = NULL; + g_autoptr (GVariant) metadata = NULL; + g_autoptr (GVariant) detached_metadata = NULL; + g_autoptr (OstreeMutableTree) mtree = NULL; g_autofree char *tree_type = NULL; - g_autoptr(GHashTable) mode_adds = NULL; - g_autoptr(GHashTable) mode_overrides = NULL; - g_autoptr(GHashTable) skip_list = NULL; + g_autoptr (GHashTable) mode_adds = NULL; + g_autoptr (GHashTable) mode_overrides = NULL; + g_autoptr (GHashTable) skip_list = NULL; OstreeRepoCommitModifierFlags flags = 0; - g_autoptr(OstreeSePolicy) policy = NULL; - g_autoptr(OstreeRepoCommitModifier) modifier = NULL; + g_autoptr (OstreeSePolicy) policy = NULL; + g_autoptr (OstreeRepoCommitModifier) modifier = NULL; OstreeRepoTransactionStats stats; - struct CommitFilterData filter_data = { 0, }; + struct CommitFilterData filter_data = { + 0, + }; g_autofree char *commit_body = NULL; g_autoptr (OstreeSign) sign = NULL; context = g_option_context_new ("[PATH]"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) goto out; if (!ostree_ensure_repo_writable (repo, error)) @@ -447,18 +470,21 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (opt_statoverride_file) { - filter_data.mode_adds = mode_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - filter_data.mode_overrides = mode_overrides = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - if (!ot_parse_file_by_line (opt_statoverride_file, handle_statoverride_line, - &filter_data, cancellable, error)) + filter_data.mode_adds = mode_adds + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + filter_data.mode_overrides = mode_overrides + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + if (!ot_parse_file_by_line (opt_statoverride_file, handle_statoverride_line, &filter_data, + cancellable, error)) goto out; } + (void)mode_overrides; // This takes care of cleanup if (opt_skiplist_file) { skip_list = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - if (!ot_parse_file_by_line (opt_skiplist_file, handle_skiplist_line, - skip_list, cancellable, error)) + if (!ot_parse_file_by_line (opt_skiplist_file, handle_skiplist_line, skip_list, cancellable, + error)) goto out; } @@ -487,10 +513,11 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) { /* A folder exists with the specified ref name, - * which is handled by _ostree_repo_write_ref */ + * which is handled by _ostree_repo_write_ref */ g_clear_error (error); } - else goto out; + else + goto out; } } @@ -504,31 +531,30 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (opt_metadata_strings || opt_metadata_variants || opt_metadata_keep || opt_bootable) { - g_autoptr(GVariantBuilder) builder = - g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); - if (opt_metadata_strings && - !parse_keyvalue_strings (builder, opt_metadata_strings, FALSE, error)) - goto out; + if (opt_metadata_strings + && !parse_keyvalue_strings (builder, opt_metadata_strings, FALSE, error)) + goto out; - if (opt_metadata_variants && - !parse_keyvalue_strings (builder, opt_metadata_variants, TRUE, error)) + if (opt_metadata_variants + && !parse_keyvalue_strings (builder, opt_metadata_variants, TRUE, error)) goto out; if (opt_metadata_keep) { g_assert (parent); - g_autoptr(GVariant) parent_commit = NULL; + g_autoptr (GVariant) parent_commit = NULL; if (!ostree_repo_load_commit (repo, parent, &parent_commit, NULL, error)) goto out; - g_auto(GVariantDict) dict; + g_auto (GVariantDict) dict; g_variant_dict_init (&dict, g_variant_get_child_value (parent_commit, 0)); for (char **keyp = opt_metadata_keep; keyp && *keyp; keyp++) { const char *key = *keyp; - g_autoptr(GVariant) val = g_variant_dict_lookup_value (&dict, key, NULL); + g_autoptr (GVariant) val = g_variant_dict_lookup_value (&dict, key, NULL); if (!val) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -545,8 +571,7 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (opt_detached_metadata_strings) { - g_autoptr(GVariantBuilder) builder = - g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); if (!parse_keyvalue_strings (builder, opt_detached_metadata_strings, FALSE, error)) goto out; @@ -577,6 +602,19 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS; if (opt_consume) flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME; + switch (opt_selinux_labeling_epoch) + { + case 0: + break; + case 1: + flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SELINUX_LABEL_V1; + break; + default: + { + glnx_throw (error, "Unknown SELinux labeling epoch: %d", opt_selinux_labeling_epoch); + goto out; + } + } if (opt_devino_canonical) { opt_link_checkout_speedup = TRUE; /* Imply this */ @@ -587,20 +625,13 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (opt_disable_fsync) ostree_repo_set_disable_fsync (repo, TRUE); - if (flags != 0 - || opt_owner_uid >= 0 - || opt_owner_gid >= 0 - || opt_statoverride_file != NULL - || opt_skiplist_file != NULL - || opt_no_xattrs - || opt_ro_executables - || opt_selinux_policy + if (flags != 0 || opt_owner_uid >= 0 || opt_owner_gid >= 0 || opt_statoverride_file != NULL + || opt_skiplist_file != NULL || opt_no_xattrs || opt_ro_executables || opt_selinux_policy || opt_selinux_policy_from_base) { filter_data.mode_adds = mode_adds; filter_data.skip_list = skip_list; - modifier = ostree_repo_commit_modifier_new (flags, commit_filter, - &filter_data, NULL); + modifier = ostree_repo_commit_modifier_new (flags, commit_filter, &filter_data, NULL); if (opt_selinux_policy) { @@ -621,8 +652,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio } else if (opt_body_file) { - commit_body = glnx_file_get_contents_utf8_at (AT_FDCWD, opt_body_file, NULL, - cancellable, error); + commit_body + = glnx_file_get_contents_utf8_at (AT_FDCWD, opt_body_file, NULL, cancellable, error); if (!commit_body) goto out; } @@ -644,7 +675,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (opt_selinux_policy_from_base) { g_assert (modifier); - if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, opt_base, cancellable, error)) + if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, opt_base, + cancellable, error)) goto out; /* Don't try to handle it twice */ opt_selinux_policy_from_base = FALSE; @@ -655,7 +687,6 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio mtree = ostree_mutable_tree_new (); } - /* Convert implicit . or explicit path via argv into * --tree=dir= so that we only have one primary code path below. */ @@ -670,20 +701,20 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio opt_trees[0] = g_strconcat ("dir=", path, NULL); } - const char *const*tree_iter; + const char *const *tree_iter; const char *tree; const char *eq; g_assert (opt_trees && *opt_trees); - for (tree_iter = (const char *const*)opt_trees; *tree_iter; tree_iter++) + for (tree_iter = (const char *const *)opt_trees; *tree_iter; tree_iter++) { - const gboolean first = (tree_iter == (const char *const*)opt_trees); + const gboolean first = (tree_iter == (const char *const *)opt_trees); tree = *tree_iter; eq = strchr (tree, '='); if (!eq) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Missing type in tree specification '%s'", tree); + "Missing type in tree specification '%s'", tree); goto out; } g_free (tree_type); @@ -703,8 +734,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio goto out; ostree_repo_commit_modifier_set_sepolicy (modifier, policy); } - if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, tree, mtree, modifier, - cancellable, error)) + if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, tree, mtree, modifier, cancellable, + error)) goto out; } else if (strcmp (tree_type, "tar") == 0) @@ -718,9 +749,9 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio { if (strcmp (tree, "-") == 0) { - if (!ostree_repo_write_archive_to_mtree_from_fd (repo, STDIN_FILENO, mtree, modifier, - opt_tar_autocreate_parents, - cancellable, error)) + if (!ostree_repo_write_archive_to_mtree_from_fd ( + repo, STDIN_FILENO, mtree, modifier, opt_tar_autocreate_parents, + cancellable, error)) goto out; } else @@ -728,8 +759,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio object_to_commit = g_file_new_for_path (tree); if (!ostree_repo_write_archive_to_mtree (repo, object_to_commit, mtree, modifier, - opt_tar_autocreate_parents, - cancellable, error)) + opt_tar_autocreate_parents, cancellable, + error)) goto out; } } @@ -740,16 +771,19 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (!comma) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Missing ',' in --tar-pathname-filter"); + "Missing ',' in --tar-pathname-filter"); goto out; } const char *replacement = comma + 1; - g_autofree char *regexp_text = g_strndup (opt_tar_pathname_filter, comma - opt_tar_pathname_filter); + g_autofree char *regexp_text + = g_strndup (opt_tar_pathname_filter, comma - opt_tar_pathname_filter); /* Use new API if we have a pathname filter */ - OstreeRepoImportArchiveOptions opts = { 0, }; + OstreeRepoImportArchiveOptions opts = { + 0, + }; opts.autocreate_parents = opt_tar_autocreate_parents; opts.translate_pathname = handle_translate_pathname; - g_autoptr(GRegex) regexp = g_regex_new (regexp_text, 0, 0, error); + g_autoptr (GRegex) regexp = g_regex_new (regexp_text, 0, 0, error); TranslatePathnameData tpdata = { regexp, replacement }; if (!regexp) { @@ -758,7 +792,7 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio } opts.translate_pathname_user_data = &tpdata; - g_autoptr(OtAutoArchiveRead) archive; + g_autoptr (OtAutoArchiveRead) archive; if (strcmp (tree, "-") == 0) archive = ot_open_archive_read_fd (STDIN_FILENO, error); else @@ -766,12 +800,12 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (!archive) goto out; - if (!ostree_repo_import_archive_to_mtree (repo, &opts, archive, mtree, - modifier, cancellable, error)) + if (!ostree_repo_import_archive_to_mtree (repo, &opts, archive, mtree, modifier, + cancellable, error)) goto out; #else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of ostree is not compiled with libarchive support"); + "This version of ostree is not compiled with libarchive support"); goto out; #endif } @@ -781,20 +815,21 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (first && opt_selinux_policy_from_base) { g_assert (modifier); - if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, tree, cancellable, error)) + if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, tree, + cancellable, error)) goto out; } if (!ostree_repo_read_commit (repo, tree, &object_to_commit, NULL, cancellable, error)) goto out; if (!ostree_repo_write_directory_to_mtree (repo, object_to_commit, mtree, modifier, - cancellable, error)) + cancellable, error)) goto out; } else { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid tree type specification '%s'", tree_type); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid tree type specification '%s'", + tree_type); goto out; } } @@ -808,10 +843,9 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio while (g_hash_table_iter_next (&hash_iter, &key, &value)) { - g_printerr ("Unmatched statoverride path: %s\n", (char*)key); + g_printerr ("Unmatched statoverride path: %s\n", (char *)key); } - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unmatched statoverride paths"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unmatched statoverride paths"); goto out; } @@ -824,10 +858,9 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio while (g_hash_table_iter_next (&hash_iter, &key, NULL)) { - g_printerr ("Unmatched skip-list path: %s\n", (char*)key); + g_printerr ("Unmatched skip-list path: %s\n", (char *)key); } - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unmatched skip-list paths"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unmatched skip-list paths"); goto out; } @@ -836,7 +869,7 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio if (opt_skip_if_unchanged && parent) { - g_autoptr(GFile) parent_root; + g_autoptr (GFile) parent_root; if (!ostree_repo_read_commit (repo, parent, &parent_root, NULL, cancellable, error)) goto out; @@ -849,14 +882,14 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio { if (!opt_no_bindings) { - g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata); + g_autoptr (GVariant) old_metadata = g_steal_pointer (&metadata); fill_bindings (repo, old_metadata, &metadata); } if (opt_bootable) { - g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata); - g_auto(GVariantDict) bootmeta; + g_autoptr (GVariant) old_metadata = g_steal_pointer (&metadata); + g_auto (GVariantDict) bootmeta; g_variant_dict_init (&bootmeta, old_metadata); if (!ostree_commit_metadata_for_bootable (root, &bootmeta, cancellable, error)) goto out; @@ -864,11 +897,23 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio metadata = g_variant_ref_sink (g_variant_dict_end (&bootmeta)); } + if (opt_composefs_metadata) + { + g_autoptr (GVariant) old_metadata = g_steal_pointer (&metadata); + g_auto (GVariantDict) newmeta; + g_variant_dict_init (&newmeta, old_metadata); + if (!ostree_repo_commit_add_composefs_metadata ( + repo, 0, &newmeta, OSTREE_REPO_FILE (root), cancellable, error)) + goto out; + + metadata = g_variant_ref_sink (g_variant_dict_end (&newmeta)); + } + if (!opt_timestamp) { if (!ostree_repo_write_commit (repo, parent, opt_subject, commit_body, metadata, - OSTREE_REPO_FILE (root), - &commit_checksum, cancellable, error)) + OSTREE_REPO_FILE (root), &commit_checksum, cancellable, + error)) goto out; } else @@ -876,56 +921,66 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio struct timespec ts; if (!parse_datetime (&ts, opt_timestamp, NULL)) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Could not parse '%s'", opt_timestamp); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not parse '%s'", + opt_timestamp); goto out; } guint64 timestamp = ts.tv_sec; if (!ostree_repo_write_commit_with_time (repo, parent, opt_subject, commit_body, metadata, - OSTREE_REPO_FILE (root), - timestamp, + OSTREE_REPO_FILE (root), timestamp, &commit_checksum, cancellable, error)) goto out; } if (detached_metadata) { - if (!ostree_repo_write_commit_detached_metadata (repo, commit_checksum, - detached_metadata, + if (!ostree_repo_write_commit_detached_metadata (repo, commit_checksum, detached_metadata, cancellable, error)) goto out; } - if (opt_key_ids) + const char *sign_name = opt_sign_name ?: OSTREE_SIGN_NAME_ED25519; + if (opt_key_files || opt_key_ids) { - /* Initialize crypto system */ - opt_sign_name = opt_sign_name ?: OSTREE_SIGN_NAME_ED25519; - - sign = ostree_sign_get_by_name (opt_sign_name, error); + sign = ostree_sign_get_by_name (sign_name, error); if (sign == NULL) goto out; + } - char **iter; - - for (iter = opt_key_ids; iter && *iter; iter++) - { - const char *keyid = *iter; - g_autoptr (GVariant) secret_key = NULL; + // Loop over the inline private keys on the command line; this should be + // avoided in new code in favor of --sign-from-file. + for (char **iter = opt_key_ids; iter && *iter; iter++) + { + const char *keyid = *iter; + g_autoptr (GVariant) secret_key = g_variant_new_string (keyid); + g_assert (sign); + if (!ostree_sign_set_sk (sign, secret_key, error)) + goto out; - secret_key = g_variant_new_string (keyid); - if (!ostree_sign_set_sk (sign, secret_key, error)) - goto out; + if (!ostree_sign_commit (sign, repo, commit_checksum, cancellable, error)) + goto out; + } - if (!ostree_sign_commit (sign, - repo, - commit_checksum, - cancellable, - error)) - goto out; + // Load each base64 encoded private key in a file and sign with it. + for (char **iter = opt_key_files; iter && *iter; iter++) + { + const char *path = *iter; + g_autofree char *b64key + = glnx_file_get_contents_utf8_at (AT_FDCWD, path, NULL, NULL, error); + if (!b64key) + { + g_prefix_error (error, "Reading %s", path); + goto out; } - } + g_autoptr (GVariant) secret_key = g_variant_new_string (b64key); + g_assert (sign); + if (!ostree_sign_set_sk (sign, secret_key, error)) + goto out; + if (!ostree_sign_commit (sign, repo, commit_checksum, cancellable, error)) + goto out; + } #ifndef OSTREE_DISABLE_GPGME if (opt_gpg_key_ids) { @@ -935,12 +990,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio { const char *keyid = *iter; - if (!ostree_repo_sign_commit (repo, - commit_checksum, - keyid, - opt_gpg_homedir, - cancellable, - error)) + if (!ostree_repo_sign_commit (repo, commit_checksum, keyid, opt_gpg_homedir, + cancellable, error)) goto out; } } @@ -975,7 +1026,7 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio } ret = TRUE; - out: +out: if (repo) ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; diff --git a/src/ostree/ot-builtin-config.c b/src/ostree/ot-builtin-config.c index 3c16049..ad90b4b 100644 --- a/src/ostree/ot-builtin-config.c +++ b/src/ostree/ot-builtin-config.c @@ -21,35 +21,29 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" -static char* opt_group; +static char *opt_group; /* ATTENTION: * Please remember to update the bash-completion script (bash/ostree) and * man page (man/ostree-config.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "group", 0, 0, G_OPTION_ARG_STRING, &opt_group , "Group name", NULL }, - { NULL } -}; +static GOptionEntry options[] + = { { "group", 0, 0, G_OPTION_ARG_STRING, &opt_group, "Group name", NULL }, { NULL } }; static gboolean -split_key_string (const char *k, - char **out_section, - char **out_value, - GError **error) +split_key_string (const char *k, char **out_section, char **out_value, GError **error) { const char *dot = strchr (k, '.'); if (!dot) { - return glnx_throw (error, - "Key must be of the form \"sectionname.keyname\""); + return glnx_throw (error, "Key must be of the form \"sectionname.keyname\""); } *out_section = g_strndup (k, dot - k); @@ -59,21 +53,15 @@ split_key_string (const char *k, } gboolean -ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - const char *op; - const char *section_key; - const char *value; - g_autofree char *section = NULL; - g_autofree char *key = NULL; - g_autoptr(GKeyFile) config = NULL; - int correct_argc; - context = g_option_context_new ("(get KEY|set KEY VALUE|unset KEY)"); + g_autoptr (GOptionContext) context = g_option_context_new ("(get KEY|set KEY VALUE|unset KEY)"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (argc < 2) @@ -82,12 +70,11 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio return FALSE; } - op = argv[1]; + const char *op = argv[1]; + int correct_argc = 3; if (!strcmp (op, "set")) correct_argc = 4; - else - correct_argc = 3; if (argc > correct_argc) { @@ -95,31 +82,35 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio return FALSE; } + g_autofree char *section = NULL; + g_autofree char *key = NULL; + g_autoptr (GKeyFile) config = NULL; + const char *section_key; + const char *value; if (!strcmp (op, "set")) { if (opt_group) { if (argc < 4) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "GROUP name, KEY and VALUE must be specified"); - return FALSE; + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "GROUP name, KEY and VALUE must be specified"); + return FALSE; } - section = g_strdup(opt_group); - key = g_strdup(argv[2]); + section = g_strdup (opt_group); + key = g_strdup (argv[2]); value = argv[3]; } else { if (argc < 4) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "KEY and VALUE must be specified"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "KEY and VALUE must be specified"); return FALSE; } section_key = argv[2]; value = argv[3]; - if(!split_key_string (section_key, §ion, &key, error)) + if (!split_key_string (section_key, §ion, &key, error)) return FALSE; } @@ -141,15 +132,14 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio "Group name and key must be specified"); return FALSE; } - section = g_strdup(opt_group); - key = g_strdup(argv[2]); + section = g_strdup (opt_group); + key = g_strdup (argv[2]); } else { - if(argc < 3) + if (argc < 3) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "KEY must be specified"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "KEY must be specified"); return FALSE; } section_key = argv[2]; @@ -166,7 +156,7 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio } else if (!strcmp (op, "unset")) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; if (opt_group) { if (argc < 3) @@ -175,15 +165,14 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio "Group name and key must be specified"); return FALSE; } - section = g_strdup(opt_group); - key = g_strdup(argv[2]); + section = g_strdup (opt_group); + key = g_strdup (argv[2]); } else { if (argc < 3) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "KEY must be specified"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "KEY must be specified"); return FALSE; } section_key = argv[2]; @@ -194,8 +183,8 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio config = ostree_repo_copy_config (repo); if (!g_key_file_remove_key (config, section, key, &local_error)) { - if (!g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) && - !g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) + if (!g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) + && !g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; @@ -207,8 +196,7 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio } else { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown operation %s", op); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown operation %s", op); return FALSE; } diff --git a/src/ostree/ot-builtin-create-usb.c b/src/ostree/ot-builtin-create-usb.c index 6bd5f2a..0c48295 100644 --- a/src/ostree/ot-builtin-create-usb.c +++ b/src/ostree/ot-builtin-create-usb.c @@ -22,9 +22,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" #include "ostree-remote-private.h" @@ -33,31 +33,32 @@ static gboolean opt_disable_fsync = FALSE; static char *opt_destination_repo = NULL; static char *opt_commit = NULL; -static GOptionEntry options[] = - { - { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, - { "destination-repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_destination_repo, "Use custom repository directory within the mount", "DEST" }, - { "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, "Pull a specific commit (only works when a single ref is specified)", "COMMIT" }, - { NULL } - }; +static GOptionEntry options[] + = { { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", + NULL }, + { "destination-repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_destination_repo, + "Use custom repository directory within the mount", "DEST" }, + { "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, + "Pull a specific commit (only works when a single ref is specified)", "COMMIT" }, + { NULL } }; gboolean -ostree_builtin_create_usb (int argc, - char **argv, - OstreeCommandInvocation *invocation, - GCancellable *cancellable, - GError **error) +ostree_builtin_create_usb (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeAsyncProgress) progress = NULL; - g_auto(GLnxConsoleRef) console = { 0, }; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeAsyncProgress) progress = NULL; + g_auto (GLnxConsoleRef) console = { + 0, + }; context = g_option_context_new ("MOUNT-PATH COLLECTION-ID REF [COLLECTION-ID REF...]"); /* Parse options. */ - g_autoptr(OstreeRepo) src_repo = NULL; + g_autoptr (OstreeRepo) src_repo = NULL; - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &src_repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &src_repo, + cancellable, error)) return FALSE; if (argc < 2) @@ -74,13 +75,17 @@ ostree_builtin_create_usb (int argc, if (argc % 2 == 1) { - ot_util_usage_error (context, "Only complete COLLECTION-ID REF pairs may be specified", error); + ot_util_usage_error (context, "Only complete COLLECTION-ID REF pairs may be specified", + error); return FALSE; } if (opt_commit && argc > 4) { - ot_util_usage_error (context, "The --commit option can only be used when a single COLLECTION-ID REF pair is specified", error); + ot_util_usage_error ( + context, + "The --commit option can only be used when a single COLLECTION-ID REF pair is specified", + error); return FALSE; } @@ -95,12 +100,13 @@ ostree_builtin_create_usb (int argc, return FALSE; /* Read in the refs to add to the USB stick. */ - g_autoptr(GPtrArray) refs = g_ptr_array_new_full (argc, (GDestroyNotify) ostree_collection_ref_free); + g_autoptr (GPtrArray) refs + = g_ptr_array_new_full (argc, (GDestroyNotify)ostree_collection_ref_free); for (gsize i = 2; i < argc; i += 2) { - if (!ostree_validate_collection_id (argv[i], error) || - !ostree_validate_rev (argv[i + 1], error)) + if (!ostree_validate_collection_id (argv[i], error) + || !ostree_validate_rev (argv[i + 1], error)) return FALSE; g_ptr_array_add (refs, ostree_collection_ref_new (argv[i], argv[i + 1])); @@ -109,7 +115,8 @@ ostree_builtin_create_usb (int argc, /* Open the destination repository on the USB stick or create it if it doesn’t exist. * Check it’s below @mount_root_path, and that it’s not the same as the source * repository. */ - const char *dest_repo_path = (opt_destination_repo != NULL) ? opt_destination_repo : ".ostree/repo"; + const char *dest_repo_path + = (opt_destination_repo != NULL) ? opt_destination_repo : ".ostree/repo"; if (!glnx_shutil_mkdir_p_at (mount_root_dfd, dest_repo_path, 0755, cancellable, error)) return FALSE; @@ -122,8 +129,8 @@ ostree_builtin_create_usb (int argc, g_debug ("%s: Creating repository in mode %u", G_STRFUNC, mode); - g_autoptr(OstreeRepo) dest_repo = ostree_repo_create_at (mount_root_dfd, dest_repo_path, - mode, NULL, cancellable, error); + g_autoptr (OstreeRepo) dest_repo + = ostree_repo_create_at (mount_root_dfd, dest_repo_path, mode, NULL, cancellable, error); if (dest_repo == NULL) return FALSE; @@ -159,19 +166,20 @@ ostree_builtin_create_usb (int argc, { const OstreeCollectionRef *ref = g_ptr_array_index (refs, i); - g_variant_builder_add (&refs_builder, "(sss)", - ref->collection_id, ref->ref_name, opt_commit ?: ""); + g_variant_builder_add (&refs_builder, "(sss)", ref->collection_id, ref->ref_name, + opt_commit ?: ""); } { GVariantBuilder builder; - g_autoptr(GVariant) opts = NULL; + g_autoptr (GVariant) opts = NULL; OstreeRepoPullFlags flags = OSTREE_REPO_PULL_FLAGS_MIRROR; glnx_console_lock (&console); if (console.is_tty) - progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect ( + ostree_repo_pull_default_console_progress_changed, &console); g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); @@ -185,10 +193,8 @@ ostree_builtin_create_usb (int argc, g_autofree char *src_repo_uri = g_file_get_uri (ostree_repo_get_path (src_repo)); - if (!ostree_repo_pull_with_options (dest_repo, src_repo_uri, - opts, - progress, - cancellable, error)) + if (!ostree_repo_pull_with_options (dest_repo, src_repo_uri, opts, progress, cancellable, + error)) { ostree_repo_abort_transaction (dest_repo, cancellable, NULL); return FALSE; @@ -208,8 +214,7 @@ ostree_builtin_create_usb (int argc, /* Add the symlinks .ostree/repos.d/@symlink_name → @dest_repo_path, unless * the @dest_repo_path is a well-known one like ostree/repo, in which case no * symlink is necessary; #OstreeRepoFinderMount always looks there. */ - if (!g_str_equal (dest_repo_path, "ostree/repo") && - !g_str_equal (dest_repo_path, ".ostree/repo")) + if (!g_str_equal (dest_repo_path, "ostree/repo") && !g_str_equal (dest_repo_path, ".ostree/repo")) { if (!glnx_shutil_mkdir_p_at (mount_root_dfd, ".ostree/repos.d", 0755, cancellable, error)) return FALSE; @@ -219,7 +224,8 @@ ostree_builtin_create_usb (int argc, GLnxDirFdIterator repos_iter; gboolean need_symlink = TRUE; - if (!glnx_dirfd_iterator_init_at (mount_root_dfd, ".ostree/repos.d", TRUE, &repos_iter, error)) + if (!glnx_dirfd_iterator_init_at (mount_root_dfd, ".ostree/repos.d", TRUE, &repos_iter, + error)) return FALSE; while (TRUE) @@ -246,7 +252,8 @@ ostree_builtin_create_usb (int argc, if (need_symlink) { /* Relative to .ostree/repos.d. */ - g_autofree char *relative_dest_repo_path = g_build_filename ("..", "..", dest_repo_path, NULL); + g_autofree char *relative_dest_repo_path + = g_build_filename ("..", "..", dest_repo_path, NULL); guint i; const guint max_attempts = 100; @@ -254,9 +261,11 @@ ostree_builtin_create_usb (int argc, { g_autofree char *symlink_path = g_strdup_printf (".ostree/repos.d/%02u-generated", i); - int ret = TEMP_FAILURE_RETRY (symlinkat (relative_dest_repo_path, mount_root_dfd, symlink_path)); + int ret = TEMP_FAILURE_RETRY ( + symlinkat (relative_dest_repo_path, mount_root_dfd, symlink_path)); if (ret < 0 && errno != EEXIST) - return glnx_throw_errno_prefix (error, "symlinkat(%s → %s)", symlink_path, relative_dest_repo_path); + return glnx_throw_errno_prefix (error, "symlinkat(%s → %s)", symlink_path, + relative_dest_repo_path); else if (ret >= 0) break; } @@ -269,8 +278,8 @@ ostree_builtin_create_usb (int argc, /* Report success to the user. */ g_autofree char *src_repo_path = g_file_get_path (ostree_repo_get_path (src_repo)); - g_print ("Copied %u/%u refs successfully from ‘%s’ to ‘%s’ repository in ‘%s’.\n", refs->len, refs->len, - src_repo_path, dest_repo_path, mount_root_path); + g_print ("Copied %u/%u refs successfully from ‘%s’ to ‘%s’ repository in ‘%s’.\n", refs->len, + refs->len, src_repo_path, dest_repo_path, mount_root_path); return TRUE; } diff --git a/src/ostree/ot-builtin-diff.c b/src/ostree/ot-builtin-diff.c index eecc471..2060dc7 100644 --- a/src/ostree/ot-builtin-diff.c +++ b/src/ostree/ot-builtin-diff.c @@ -21,9 +21,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_stats; @@ -37,41 +37,35 @@ static gint opt_owner_gid = -1; * man page (man/ostree-diff.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL }, - { "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL }, - { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL }, - { "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, "Use file ownership user id for local files", "UID" }, - { "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Use file ownership group id for local files", "GID" }, - { NULL } -}; +static GOptionEntry options[] + = { { "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL }, + { "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL }, + { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, + "Skip output of extended attributes", NULL }, + { "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, + "Use file ownership user id for local files", "UID" }, + { "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, + "Use file ownership group id for local files", "GID" }, + { NULL } }; static gboolean -parse_file_or_commit (OstreeRepo *repo, - const char *arg, - GFile **out_file, - GCancellable *cancellable, - GError **error) +parse_file_or_commit (OstreeRepo *repo, const char *arg, GFile **out_file, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autoptr(GFile) ret_file = NULL; + g_autoptr (GFile) ret_file = NULL; - if (g_str_has_prefix (arg, "/") - || g_str_has_prefix (arg, "./") - ) + if (g_str_has_prefix (arg, "/") || g_str_has_prefix (arg, "./")) { ret_file = g_file_new_for_path (arg); } else { if (!ostree_repo_read_commit (repo, arg, &ret_file, NULL, cancellable, error)) - goto out; + return FALSE; } - ret = TRUE; ot_transfer_out_value (out_file, &ret_file); - out: - return ret; + return TRUE; } static GHashTable * @@ -93,13 +87,9 @@ reachable_set_intersect (GHashTable *a, GHashTable *b) } static gboolean -object_set_total_size (OstreeRepo *repo, - GHashTable *reachable, - guint64 *out_total, - GCancellable *cancellable, - GError **error) +object_set_total_size (OstreeRepo *repo, GHashTable *reachable, guint64 *out_total, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; GHashTableIter hashiter; gpointer key, value; @@ -114,47 +104,37 @@ object_set_total_size (OstreeRepo *repo, guint64 size; ostree_object_name_deserialize (v, &csum, &objtype); - if (!ostree_repo_query_object_storage_size (repo, objtype, csum, &size, - cancellable, error)) - goto out; + if (!ostree_repo_query_object_storage_size (repo, objtype, csum, &size, cancellable, error)) + return FALSE; *out_total += size; } - ret = TRUE; - out: - return ret; + return TRUE; } gboolean -ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - const char *src; - const char *target; - g_autofree char *src_prev = NULL; - g_autoptr(GFile) srcf = NULL; - g_autoptr(GFile) targetf = NULL; - g_autoptr(GPtrArray) modified = NULL; - g_autoptr(GPtrArray) removed = NULL; - g_autoptr(GPtrArray) added = NULL; - - context = g_option_context_new ("REV_OR_DIR REV_OR_DIR"); + g_autoptr (GOptionContext) context = g_option_context_new ("REV_OR_DIR REV_OR_DIR"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) - goto out; + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) + return FALSE; if (argc < 2) { gchar *help = g_option_context_get_help (context, TRUE, NULL); g_printerr ("%s\n", help); g_free (help); - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "REV must be specified"); - goto out; + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "REV must be specified"); + return FALSE; } + g_autofree char *src_prev = NULL; + const char *src; + const char *target; if (argc == 2) { src_prev = g_strconcat (argv[1], "^", NULL); @@ -170,35 +150,41 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, if (!opt_stats && !opt_fs_diff) opt_fs_diff = TRUE; + g_autoptr (GFile) srcf = NULL; + g_autoptr (GFile) targetf = NULL; + g_autoptr (GPtrArray) modified = NULL; + g_autoptr (GPtrArray) removed = NULL; + g_autoptr (GPtrArray) added = NULL; + if (opt_fs_diff) { - OstreeDiffFlags diff_flags = OSTREE_DIFF_FLAGS_NONE; + OstreeDiffFlags diff_flags = OSTREE_DIFF_FLAGS_NONE; if (opt_no_xattrs) diff_flags |= OSTREE_DIFF_FLAGS_IGNORE_XATTRS; - + if (!parse_file_or_commit (repo, src, &srcf, cancellable, error)) - goto out; + return FALSE; if (!parse_file_or_commit (repo, target, &targetf, cancellable, error)) - goto out; + return FALSE; modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref); removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); OstreeDiffDirsOptions diff_opts = { opt_owner_uid, opt_owner_gid }; - if (!ostree_diff_dirs_with_options (diff_flags, srcf, targetf, modified, removed, - added, &diff_opts, cancellable, error)) - goto out; + if (!ostree_diff_dirs_with_options (diff_flags, srcf, targetf, modified, removed, added, + &diff_opts, cancellable, error)) + return FALSE; ostree_diff_print (srcf, targetf, modified, removed, added); } if (opt_stats) { - g_autoptr(GHashTable) reachable_a = NULL; - g_autoptr(GHashTable) reachable_b = NULL; - g_autoptr(GHashTable) reachable_intersection = NULL; + g_autoptr (GHashTable) reachable_a = NULL; + g_autoptr (GHashTable) reachable_b = NULL; + g_autoptr (GHashTable) reachable_intersection = NULL; g_autofree char *rev_a = NULL; g_autofree char *rev_b = NULL; g_autofree char *size = NULL; @@ -207,14 +193,14 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, guint64 total_common; if (!ostree_repo_resolve_rev (repo, src, FALSE, &rev_a, error)) - goto out; + return FALSE; if (!ostree_repo_resolve_rev (repo, target, FALSE, &rev_b, error)) - goto out; + return FALSE; if (!ostree_repo_traverse_commit (repo, rev_a, 0, &reachable_a, cancellable, error)) - goto out; + return FALSE; if (!ostree_repo_traverse_commit (repo, rev_b, 0, &reachable_b, cancellable, error)) - goto out; + return FALSE; a_size = g_hash_table_size (reachable_a); b_size = g_hash_table_size (reachable_b); @@ -225,14 +211,11 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, g_print ("Common Object Count: %u\n", g_hash_table_size (reachable_intersection)); - if (!object_set_total_size (repo, reachable_intersection, &total_common, - cancellable, error)) - goto out; + if (!object_set_total_size (repo, reachable_intersection, &total_common, cancellable, error)) + return FALSE; size = g_format_size_full (total_common, 0); g_print ("Common Object Size: %s\n", size); } - ret = TRUE; - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-builtin-export.c b/src/ostree/ot-builtin-export.c index bcf7da5..4dda9c2 100644 --- a/src/ostree/ot-builtin-export.c +++ b/src/ostree/ot-builtin-export.c @@ -19,12 +19,12 @@ #include "config.h" -#include "otutil.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree-libarchive-private.h" -#include "ostree.h" #include "ostree-repo-file.h" +#include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" +#include "otutil.h" #ifdef HAVE_LIBARCHIVE #include @@ -41,57 +41,37 @@ static gboolean opt_no_xattrs; * man page (man/ostree-export.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL }, - { "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" }, - { "prefix", 0, 0, G_OPTION_ARG_FILENAME, &opt_prefix, "Add PATH as prefix to archive pathnames", "PATH" }, - { "output", 'o', 0, G_OPTION_ARG_FILENAME, &opt_output_path, "Output to PATH ", "PATH" }, - { NULL } -}; - -#ifdef HAVE_LIBARCHIVE - -static void -propagate_libarchive_error (GError **error, - struct archive *a) -{ - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "%s", archive_error_string (a)); -} - -#endif +static GOptionEntry options[] + = { { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, + "Skip output of extended attributes", NULL }, + { "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", + "PATH" }, + { "prefix", 0, 0, G_OPTION_ARG_FILENAME, &opt_prefix, + "Add PATH as prefix to archive pathnames", "PATH" }, + { "output", 'o', 0, G_OPTION_ARG_FILENAME, &opt_output_path, "Output to PATH ", "PATH" }, + { NULL } }; gboolean -ostree_builtin_export (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_export (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - gboolean ret = FALSE; - g_autoptr(GFile) root = NULL; - g_autoptr(GFile) subtree = NULL; - g_autofree char *commit = NULL; - g_autoptr(GVariant) commit_data = NULL; -#ifdef HAVE_LIBARCHIVE - const char *rev; - g_autoptr(OtAutoArchiveWrite) a = NULL; - OstreeRepoExportArchiveOptions opts = { 0, }; -#endif + g_autoptr (GOptionContext) context = g_option_context_new ("COMMIT"); - context = g_option_context_new ("COMMIT"); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) + return FALSE; - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) - goto out; - -#ifdef HAVE_LIBARCHIVE +#ifdef HAVE_LIBARCHIVE if (argc <= 1) { ot_util_usage_error (context, "A COMMIT argument is required", error); - goto out; + return FALSE; } - rev = argv[1]; + const char *rev = argv[1]; - a = archive_write_new (); + g_autoptr (OtAutoArchiveWrite) a = archive_write_new (); /* Yes, this is hardcoded for now. There is * archive_write_set_format_filter_by_ext() but it's fairly magic. * Many programs have support now for GNU tar, so should be a good @@ -99,43 +79,38 @@ ostree_builtin_export (int argc, char **argv, OstreeCommandInvocation *invocatio * supports. */ if (archive_write_set_format_gnutar (a) != ARCHIVE_OK) - { - propagate_libarchive_error (error, a); - goto out; - } + return glnx_throw (error, "%s", archive_error_string (a)); if (archive_write_add_filter_none (a) != ARCHIVE_OK) - { - propagate_libarchive_error (error, a); - goto out; - } + return glnx_throw (error, "%s", archive_error_string (a)); if (opt_output_path) { if (archive_write_open_filename (a, opt_output_path) != ARCHIVE_OK) - { - propagate_libarchive_error (error, a); - goto out; - } + return glnx_throw (error, "%s", archive_error_string (a)); } else { if (archive_write_open_FILE (a, stdout) != ARCHIVE_OK) - { - propagate_libarchive_error (error, a); - goto out; - } + return glnx_throw (error, "%s", archive_error_string (a)); } + OstreeRepoExportArchiveOptions opts = { + 0, + }; if (opt_no_xattrs) opts.disable_xattrs = TRUE; + g_autofree char *commit = NULL; + g_autoptr (GFile) root = NULL; if (!ostree_repo_read_commit (repo, rev, &root, &commit, cancellable, error)) - goto out; + return FALSE; + g_autoptr (GVariant) commit_data = NULL; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit, &commit_data, error)) - goto out; + return FALSE; opts.timestamp_secs = ostree_commit_get_timestamp (commit_data); + g_autoptr (GFile) subtree = NULL; if (opt_subpath) subtree = g_file_resolve_relative_path (root, opt_subpath); else @@ -143,23 +118,17 @@ ostree_builtin_export (int argc, char **argv, OstreeCommandInvocation *invocatio opts.path_prefix = opt_prefix; - if (!ostree_repo_export_tree_to_archive (repo, &opts, (OstreeRepoFile*)subtree, a, - cancellable, error)) - goto out; + if (!ostree_repo_export_tree_to_archive (repo, &opts, (OstreeRepoFile *)subtree, a, cancellable, + error)) + return FALSE; if (archive_write_close (a) != ARCHIVE_OK) - { - propagate_libarchive_error (error, a); - goto out; - } + return glnx_throw (error, "%s", archive_error_string (a)); + return TRUE; #else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "This version of ostree is not compiled with libarchive support"); - goto out; -#endif - - ret = TRUE; - out: - return ret; + return FALSE; +#endif } diff --git a/src/ostree/ot-builtin-find-remotes.c b/src/ostree/ot-builtin-find-remotes.c index 03ab1be..b13ab4e 100644 --- a/src/ostree/ot-builtin-find-remotes.c +++ b/src/ostree/ot-builtin-find-remotes.c @@ -22,9 +22,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" #include "ostree-remote-private.h" @@ -35,20 +35,21 @@ static gboolean opt_disable_fsync = FALSE; static gboolean opt_pull = FALSE; static gboolean opt_mirror = FALSE; -static GOptionEntry options[] = - { - { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, - { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, - { "finders", 0, 0, G_OPTION_ARG_STRING, &opt_finders, "Use the specified comma separated list of finders (e.g. config,lan,mount)", "FINDERS" }, - { "pull", 0, 0, G_OPTION_ARG_NONE, &opt_pull, "Pull the updates after finding them", NULL }, - { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Do a mirror pull (see ostree pull --mirror)", NULL}, - { NULL } - }; +static GOptionEntry options[] + = { { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, + { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", + NULL }, + { "finders", 0, 0, G_OPTION_ARG_STRING, &opt_finders, + "Use the specified comma separated list of finders (e.g. config,lan,mount)", "FINDERS" }, + { "pull", 0, 0, G_OPTION_ARG_NONE, &opt_pull, "Pull the updates after finding them", NULL }, + { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, + "Do a mirror pull (see ostree pull --mirror)", NULL }, + { NULL } }; static gchar * uint64_secs_to_iso8601 (guint64 secs) { - g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc (secs); + g_autoptr (GDateTime) dt = g_date_time_new_from_unix_utc (secs); if (dt != NULL) return g_date_time_format (dt, "%FT%TZ"); @@ -57,21 +58,20 @@ uint64_secs_to_iso8601 (guint64 secs) } static gchar * -format_ref_to_checksum (GHashTable *ref_to_checksum /* (element-type OstreeCollectionRef utf8) */, +format_ref_to_checksum (GHashTable *ref_to_checksum /* (element-type OstreeCollectionRef utf8) */, const gchar *line_prefix) { GHashTableIter iter; const OstreeCollectionRef *ref; const gchar *checksum; - g_autoptr(GString) out = NULL; + g_autoptr (GString) out = NULL; g_hash_table_iter_init (&iter, ref_to_checksum); out = g_string_new (""); - while (g_hash_table_iter_next (&iter, (gpointer *) &ref, (gpointer *) &checksum)) - g_string_append_printf (out, "%s - (%s, %s) = %s\n", - line_prefix, ref->collection_id, ref->ref_name, - (checksum != NULL) ? checksum : "(not found)"); + while (g_hash_table_iter_next (&iter, (gpointer *)&ref, (gpointer *)&checksum)) + g_string_append_printf (out, "%s - (%s, %s) = %s\n", line_prefix, ref->collection_id, + ref->ref_name, (checksum != NULL) ? checksum : "(not found)"); return g_string_free (g_steal_pointer (&out), FALSE); } @@ -79,7 +79,7 @@ format_ref_to_checksum (GHashTable *ref_to_checksum /* (element-type OstreeCol static gchar * remote_get_uri (OstreeRemote *remote) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; g_autofree gchar *uri = NULL; uri = g_key_file_get_string (remote->options, remote->group, "url", &error); @@ -90,8 +90,7 @@ remote_get_uri (OstreeRemote *remote) /* Add each key from @keys_input to @set iff its value is non-%NULL. */ static void -add_keys_to_set_if_non_null (GHashTable *set, - GHashTable *keys_input) +add_keys_to_set_if_non_null (GHashTable *set, GHashTable *keys_input) { GHashTableIter iter; gpointer key, value; @@ -104,9 +103,7 @@ add_keys_to_set_if_non_null (GHashTable *set, } static void -get_result_cb (GObject *obj, - GAsyncResult *result, - gpointer user_data) +get_result_cb (GObject *obj, GAsyncResult *result, gpointer user_data) { GAsyncResult **result_out = user_data; *result_out = g_object_ref (result); @@ -121,19 +118,16 @@ collection_ref_free0 (OstreeCollectionRef *ref) } static gboolean -validate_finders_list (const char **finders, - GOptionContext *context, - GError **error) +validate_finders_list (const char **finders, GOptionContext *context, GError **error) { - typedef struct { + typedef struct + { gchar *finder_name; gboolean already_used; } Finder; - Finder valid_finders[] = { - {.finder_name = "config", .already_used = FALSE}, - {.finder_name = "lan", .already_used = FALSE}, - {.finder_name = "mount", .already_used = FALSE} - }; + Finder valid_finders[] = { { .finder_name = "config", .already_used = FALSE }, + { .finder_name = "lan", .already_used = FALSE }, + { .finder_name = "mount", .already_used = FALSE } }; if (finders == NULL || *finders == NULL) { @@ -157,7 +151,8 @@ validate_finders_list (const char **finders, if (!is_valid_finder) { g_autofree gchar *error_msg = NULL; - error_msg = g_strdup_printf ("Unknown or duplicate finder type given in --finders option: ‘%s’", *iter); + error_msg = g_strdup_printf ( + "Unknown or duplicate finder type given in --finders option: ‘%s’", *iter); ot_util_usage_error (context, error_msg, error); return FALSE; } @@ -167,33 +162,33 @@ validate_finders_list (const char **finders, } gboolean -ostree_builtin_find_remotes (int argc, - char **argv, - OstreeCommandInvocation *invocation, - GCancellable *cancellable, - GError **error) +ostree_builtin_find_remotes (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */ - g_autoptr(GPtrArray) finders = NULL; /* (element-type OstreeRepoFinder) */ - g_autoptr(OstreeRepoFinder) finder_config = NULL; - g_autoptr(OstreeRepoFinder) finder_mount = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */ + g_autoptr (GPtrArray) finders = NULL; /* (element-type OstreeRepoFinder) */ + g_autoptr (OstreeRepoFinder) finder_config = NULL; + g_autoptr (OstreeRepoFinder) finder_mount = NULL; #ifdef HAVE_AVAHI - g_autoptr(OstreeRepoFinder) finder_avahi = NULL; -#endif /* HAVE_AVAHI */ - g_autoptr(OstreeAsyncProgress) progress = NULL; + g_autoptr (OstreeRepoFinder) finder_avahi = NULL; +#endif /* HAVE_AVAHI */ + g_autoptr (OstreeAsyncProgress) progress = NULL; gsize i; - g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL; - g_auto(OstreeRepoFinderResultv) results = NULL; - g_auto(GLnxConsoleRef) console = { 0, }; - g_autoptr(GHashTable) refs_found = NULL; /* set (element-type OstreeCollectionRef) */ - g_autoptr(GVariant) pull_options = NULL; + g_autoptr (GAsyncResult) find_result = NULL, pull_result = NULL; + g_auto (OstreeRepoFinderResultv) results = NULL; + g_auto (GLnxConsoleRef) console = { + 0, + }; + g_autoptr (GHashTable) refs_found = NULL; /* set (element-type OstreeCollectionRef) */ + g_autoptr (GVariant) pull_options = NULL; context = g_option_context_new ("COLLECTION-ID REF [COLLECTION-ID REF...]"); /* Parse options. */ - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (!ostree_ensure_repo_writable (repo, error)) @@ -207,7 +202,8 @@ ostree_builtin_find_remotes (int argc, if (argc % 2 == 0) { - ot_util_usage_error (context, "Only complete COLLECTION-ID REF pairs may be specified", error); + ot_util_usage_error (context, "Only complete COLLECTION-ID REF pairs may be specified", + error); return FALSE; } @@ -220,17 +216,17 @@ ostree_builtin_find_remotes (int argc, if (opt_disable_fsync) ostree_repo_set_disable_fsync (repo, TRUE); - if (opt_cache_dir && - !ostree_repo_set_cache_dir (repo, AT_FDCWD, opt_cache_dir, cancellable, error)) + if (opt_cache_dir + && !ostree_repo_set_cache_dir (repo, AT_FDCWD, opt_cache_dir, cancellable, error)) return FALSE; /* Read in the refs to search for remotes for. */ - refs = g_ptr_array_new_full (argc, (GDestroyNotify) collection_ref_free0); + refs = g_ptr_array_new_full (argc, (GDestroyNotify)collection_ref_free0); for (i = 1; i < argc; i += 2) { - if (!ostree_validate_collection_id (argv[i], error) || - !ostree_validate_rev (argv[i + 1], error)) + if (!ostree_validate_collection_id (argv[i], error) + || !ostree_validate_rev (argv[i + 1], error)) return FALSE; g_ptr_array_add (refs, ostree_collection_ref_new (argv[i], argv[i + 1])); @@ -241,7 +237,7 @@ ostree_builtin_find_remotes (int argc, /* Build the array of OstreeRepoFinder instances */ if (opt_finders != NULL) { - g_auto(GStrv) finders_strings = NULL; + g_auto (GStrv) finders_strings = NULL; finders_strings = g_strsplit (opt_finders, ",", 0); if (!validate_finders_list ((const char **)finders_strings, context, error)) @@ -264,10 +260,11 @@ ostree_builtin_find_remotes (int argc, { #ifdef HAVE_AVAHI GMainContext *main_context = g_main_context_get_thread_default (); - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (main_context)); - ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), &local_error); + ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), + &local_error); if (local_error != NULL) { @@ -277,9 +274,11 @@ ostree_builtin_find_remotes (int argc, else g_ptr_array_add (finders, finder_avahi); #else - ot_util_usage_error (context, "LAN repo finder requested but ostree was compiled without Avahi support", error); + ot_util_usage_error ( + context, + "LAN repo finder requested but ostree was compiled without Avahi support", error); return FALSE; -#endif /* HAVE_AVAHI */ +#endif /* HAVE_AVAHI */ } else g_assert_not_reached (); @@ -291,14 +290,13 @@ ostree_builtin_find_remotes (int argc, glnx_console_lock (&console); if (console.is_tty) - progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect ( + ostree_repo_pull_default_console_progress_changed, &console); - ostree_repo_find_remotes_async (repo, - (const OstreeCollectionRef * const *) refs->pdata, - NULL /* no options */, - finders != NULL ? (OstreeRepoFinder **) finders->pdata : NULL, - progress, cancellable, - get_result_cb, &find_result); + ostree_repo_find_remotes_async (repo, (const OstreeCollectionRef *const *)refs->pdata, + NULL /* no options */, + finders != NULL ? (OstreeRepoFinder **)finders->pdata : NULL, + progress, cancellable, get_result_cb, &find_result); while (find_result == NULL) g_main_context_iteration (NULL, TRUE); @@ -312,8 +310,8 @@ ostree_builtin_find_remotes (int argc, ostree_async_progress_finish (progress); /* Print results and work out which refs were not found. */ - refs_found = g_hash_table_new_full (ostree_collection_ref_hash, - ostree_collection_ref_equal, NULL, NULL); + refs_found + = g_hash_table_new_full (ostree_collection_ref_hash, ostree_collection_ref_equal, NULL, NULL); for (i = 0; results[i] != NULL; i++) { @@ -350,7 +348,7 @@ ostree_builtin_find_remotes (int argc, g_print ("%u/%u refs were found.\n", g_hash_table_size (refs_found), refs->len - 1); /* Print out the refs which weren’t found. */ - if (g_hash_table_size (refs_found) != refs->len - 1 /* NULL terminator */) + if (g_hash_table_size (refs_found) != refs->len - 1 /* NULL terminator */) { g_print ("Refs not found in any remote:\n"); @@ -371,21 +369,21 @@ ostree_builtin_find_remotes (int argc, g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); if (opt_mirror) - g_variant_builder_add (&builder, "{s@v}", "flags", - g_variant_new_variant (g_variant_new_int32 (OSTREE_REPO_PULL_FLAGS_MIRROR))); + g_variant_builder_add ( + &builder, "{s@v}", "flags", + g_variant_new_variant (g_variant_new_int32 (OSTREE_REPO_PULL_FLAGS_MIRROR))); pull_options = g_variant_ref_sink (g_variant_builder_end (&builder)); } /* Run the pull operation. */ if (console.is_tty) - progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect ( + ostree_repo_pull_default_console_progress_changed, &console); - ostree_repo_pull_from_remotes_async (repo, - (const OstreeRepoFinderResult * const *) results, - pull_options, - progress, cancellable, - get_result_cb, &pull_result); + ostree_repo_pull_from_remotes_async (repo, (const OstreeRepoFinderResult *const *)results, + pull_options, progress, cancellable, get_result_cb, + &pull_result); while (pull_result == NULL) g_main_context_iteration (NULL, TRUE); diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index 9e3f77e..cd3c776 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -22,10 +22,10 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" -#include "ostree.h" #include "ostree-cmd-private.h" +#include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_quiet; @@ -40,31 +40,28 @@ static gboolean opt_verify_back_refs; * man page (man/ostree-fsck.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "add-tombstones", 0, 0, G_OPTION_ARG_NONE, &opt_add_tombstones, "Add tombstones for missing commits", NULL }, - { "quiet", 'q', 0, G_OPTION_ARG_NONE, &opt_quiet, "Only print error messages", NULL }, - { "all", 'a', 0, G_OPTION_ARG_NONE, &opt_all, "Don't stop on first error", NULL }, - { "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Remove corrupted objects", NULL }, - { "verify-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_verify_bindings, "Verify ref bindings", NULL }, - { "verify-back-refs", 0, 0, G_OPTION_ARG_NONE, &opt_verify_back_refs, "Verify back-references (implies --verify-bindings)", NULL }, - { NULL } -}; +static GOptionEntry options[] + = { { "add-tombstones", 0, 0, G_OPTION_ARG_NONE, &opt_add_tombstones, + "Add tombstones for missing commits", NULL }, + { "quiet", 'q', 0, G_OPTION_ARG_NONE, &opt_quiet, "Only print error messages", NULL }, + { "all", 'a', 0, G_OPTION_ARG_NONE, &opt_all, "Don't stop on first error", NULL }, + { "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Remove corrupted objects", NULL }, + { "verify-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_verify_bindings, "Verify ref bindings", + NULL }, + { "verify-back-refs", 0, 0, G_OPTION_ARG_NONE, &opt_verify_back_refs, + "Verify back-references (implies --verify-bindings)", NULL }, + { NULL } }; static gboolean -fsck_one_object (OstreeRepo *repo, - const char *checksum, - OstreeObjectType objtype, - GHashTable *object_parents, - GVariant *key, - gboolean *out_found_corruption, - GCancellable *cancellable, - GError **error) +fsck_one_object (OstreeRepo *repo, const char *checksum, OstreeObjectType objtype, + GHashTable *object_parents, GVariant *key, gboolean *out_found_corruption, + GCancellable *cancellable, GError **error) { - g_autoptr(GError) temp_error = NULL; + g_autoptr (GError) temp_error = NULL; if (!ostree_repo_fsck_object (repo, objtype, checksum, cancellable, &temp_error)) { gboolean object_missing = FALSE; - g_auto(GStrv) parent_commits = NULL; + g_auto (GStrv) parent_commits = NULL; g_autofree char *parent_commits_str = NULL; if (object_parents) @@ -92,7 +89,7 @@ fsck_one_object (OstreeRepo *repo, if (opt_delete) { g_printerr ("%s\n", temp_error->message); - (void) ostree_repo_delete_object (repo, objtype, checksum, cancellable, NULL); + (void)ostree_repo_delete_object (repo, objtype, checksum, cancellable, NULL); object_missing = TRUE; } else if (opt_all) @@ -120,13 +117,14 @@ fsck_one_object (OstreeRepo *repo, { const char *parent_commit = parent_commits[i]; OstreeRepoCommitState state; - if (!ostree_repo_load_commit (repo, parent_commit, NULL, - &state, error)) + if (!ostree_repo_load_commit (repo, parent_commit, NULL, &state, error)) return FALSE; if ((state & OSTREE_REPO_COMMIT_STATE_PARTIAL) == 0) { g_printerr ("Marking commit as partial: %s\n", parent_commit); - if (!ostree_repo_mark_commit_partial_reason (repo, parent_commit, TRUE, OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL, error)) + if (!ostree_repo_mark_commit_partial_reason ( + repo, parent_commit, TRUE, OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL, + error)) return FALSE; } } @@ -138,14 +136,12 @@ fsck_one_object (OstreeRepo *repo, } static gboolean -fsck_reachable_objects_from_commits (OstreeRepo *repo, - GHashTable *commits, - gboolean *out_found_corruption, - GCancellable *cancellable, - GError **error) +fsck_reachable_objects_from_commits (OstreeRepo *repo, GHashTable *commits, + gboolean *out_found_corruption, GCancellable *cancellable, + GError **error) { - g_autoptr(GHashTable) reachable_objects = ostree_repo_traverse_new_reachable (); - g_autoptr(GHashTable) object_parents = ostree_repo_traverse_new_parents (); + g_autoptr (GHashTable) reachable_objects = ostree_repo_traverse_new_reachable (); + g_autoptr (GHashTable) object_parents = ostree_repo_traverse_new_parents (); GHashTableIter hash_iter; gpointer key, value; @@ -160,12 +156,14 @@ fsck_reachable_objects_from_commits (OstreeRepo *repo, g_assert (objtype == OSTREE_OBJECT_TYPE_COMMIT); - if (!ostree_repo_traverse_commit_union_with_parents (repo, checksum, 0, reachable_objects, object_parents, - cancellable, error)) + if (!ostree_repo_traverse_commit_union_with_parents (repo, checksum, 0, reachable_objects, + object_parents, cancellable, error)) return FALSE; } - g_auto(GLnxConsoleRef) console = { 0, }; + g_auto (GLnxConsoleRef) console = { + 0, + }; glnx_console_lock (&console); const guint count = g_hash_table_size (reachable_objects); @@ -179,8 +177,7 @@ fsck_reachable_objects_from_commits (OstreeRepo *repo, ostree_object_name_deserialize (serialized_key, &checksum, &objtype); - if (!fsck_one_object (repo, checksum, objtype, - object_parents, serialized_key, + if (!fsck_one_object (repo, checksum, objtype, object_parents, serialized_key, out_found_corruption, cancellable, error)) return FALSE; @@ -194,27 +191,21 @@ fsck_reachable_objects_from_commits (OstreeRepo *repo, /* Check that a given commit object is valid for the ref it was looked up via. * @collection_id will be %NULL for normal refs, and non-%NULL for collection–refs. */ static gboolean -fsck_commit_for_ref (OstreeRepo *repo, - const char *checksum, - const char *collection_id, - const char *ref_name, - gboolean *found_corruption, - GCancellable *cancellable, - GError **error) +fsck_commit_for_ref (OstreeRepo *repo, const char *checksum, const char *collection_id, + const char *ref_name, gboolean *found_corruption, GCancellable *cancellable, + GError **error) { - if (!fsck_one_object (repo, checksum, OSTREE_OBJECT_TYPE_COMMIT, - NULL, NULL, found_corruption, + if (!fsck_one_object (repo, checksum, OSTREE_OBJECT_TYPE_COMMIT, NULL, NULL, found_corruption, cancellable, error)) return FALSE; /* Check the commit exists. */ - g_autoptr(GVariant) commit = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, - checksum, &commit, error)) + g_autoptr (GVariant) commit = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, &commit, error)) { if (collection_id != NULL) - return glnx_prefix_error (error, "Loading commit for ref (%s, %s)", - collection_id, ref_name); + return glnx_prefix_error (error, "Loading commit for ref (%s, %s)", collection_id, + ref_name); else return glnx_prefix_error (error, "Loading commit for ref %s", ref_name); } @@ -222,30 +213,108 @@ fsck_commit_for_ref (OstreeRepo *repo, /* Check its bindings. */ if (opt_verify_bindings) { - if (!ostree_cmd__private__ ()->ostree_repo_verify_bindings (collection_id, ref_name, commit, error)) + if (!ostree_cmd__private__ ()->ostree_repo_verify_bindings (collection_id, ref_name, commit, + error)) return glnx_prefix_error (error, "Commit %s", checksum); } return TRUE; } +static gboolean +fsck_one_commit (OstreeRepo *repo, const char *checksum, GVariant *commit, GPtrArray *tombstones, + GCancellable *cancellable, GError **error) +{ + /* If requested, check that all the refs listed in the ref-bindings + * for this commit resolve back to this commit. */ + if (opt_verify_back_refs) + { + g_autoptr (GVariant) metadata = g_variant_get_child_value (commit, 0); + const char *collection_id = NULL; + if (!g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "&s", + &collection_id)) + collection_id = NULL; + g_autofree const char **refs = NULL; + if (g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_REF_BINDING, "^a&s", &refs)) + { + for (const char **iter = refs; *iter != NULL; ++iter) + { + g_autofree char *checksum_for_ref = NULL; + if (collection_id != NULL) + { + const OstreeCollectionRef collection_ref + = { (char *)collection_id, (char *)*iter }; + if (!ostree_repo_resolve_collection_ref (repo, &collection_ref, TRUE, + OSTREE_REPO_RESOLVE_REV_EXT_NONE, + &checksum_for_ref, cancellable, error)) + return FALSE; + } + else + { + if (!ostree_repo_resolve_rev (repo, *iter, TRUE, &checksum_for_ref, error)) + return FALSE; + } + if (checksum_for_ref == NULL) + { + if (collection_id != NULL) + return glnx_throw ( + error, "Collection–ref (%s, %s) in bindings for commit %s does not exist", + collection_id, *iter, checksum); + else + return glnx_throw (error, "Ref ‘%s’ in bindings for commit %s does not exist", + *iter, checksum); + } + else if (g_strcmp0 (checksum_for_ref, checksum) != 0) + { + if (collection_id != NULL) + return glnx_throw (error, + "Collection–ref (%s, %s) in bindings for commit %s does " + "not resolve to that commit", + collection_id, *iter, checksum); + else + return glnx_throw ( + error, "Ref ‘%s’ in bindings for commit %s does not resolve to that commit", + *iter, checksum); + } + } + } + } + + if (opt_add_tombstones) + { + g_autofree char *parent = ostree_commit_get_parent (commit); + if (parent) + { + g_autoptr (GVariant) parent_commit = NULL; + if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT, parent, + &parent_commit, error)) + return FALSE; + if (!parent_commit) + g_ptr_array_add (tombstones, g_strdup (checksum)); + } + } + + return TRUE; +} + gboolean -ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (OstreeRepo) repo = NULL; gboolean found_corruption = FALSE; - g_autoptr(GOptionContext) context = g_option_context_new (""); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new (""); + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (!opt_quiet) g_print ("Validating refs...\n"); /* Validate that the commit for each ref is available */ - g_autoptr(GHashTable) all_refs = NULL; - if (!ostree_repo_list_refs (repo, NULL, &all_refs, - cancellable, error)) + g_autoptr (GHashTable) all_refs = NULL; + if (!ostree_repo_list_refs (repo, NULL, &all_refs, cancellable, error)) return FALSE; GHashTableIter hash_iter; @@ -258,42 +327,41 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, g_autofree char *ref_name = NULL; if (!ostree_parse_refspec (refspec, NULL, &ref_name, error)) return FALSE; - if (!fsck_commit_for_ref (repo, checksum, NULL, ref_name, - &found_corruption, cancellable, error)) + if (!fsck_commit_for_ref (repo, checksum, NULL, ref_name, &found_corruption, cancellable, + error)) return FALSE; } if (!opt_quiet) g_print ("Validating refs in collections...\n"); - g_autoptr(GHashTable) all_collection_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) all_collection_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ if (!ostree_repo_list_collection_refs (repo, NULL, &all_collection_refs, - OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, - cancellable, error)) + OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, cancellable, + error)) return FALSE; g_hash_table_iter_init (&hash_iter, all_collection_refs); while (g_hash_table_iter_next (&hash_iter, &key, &value)) { const OstreeCollectionRef *ref = key; - if (!fsck_commit_for_ref (repo, value, ref->collection_id, ref->ref_name, - &found_corruption, cancellable, error)) + if (!fsck_commit_for_ref (repo, value, ref->collection_id, ref->ref_name, &found_corruption, + cancellable, error)) return FALSE; } if (!opt_quiet) - g_print ("Enumerating objects...\n"); + g_print ("Enumerating commits...\n"); - g_autoptr(GHashTable) objects = NULL; - if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL, - &objects, cancellable, error)) + // Find all commit objects, including partial ones + g_autoptr (GHashTable) all_commits = NULL; + if (!ostree_repo_list_commit_objects_starting_with (repo, "", &all_commits, cancellable, error)) return FALSE; + // And gather a set of non-partial commits for further analysis + g_autoptr (GHashTable) commits = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, + (GDestroyNotify)g_variant_unref, NULL); - g_autoptr(GHashTable) commits = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, - (GDestroyNotify)g_variant_unref, NULL); - - - g_autoptr(GPtrArray) tombstones = NULL; + g_autoptr (GPtrArray) tombstones = NULL; if (opt_add_tombstones) tombstones = g_ptr_array_new_with_free_func (g_free); @@ -302,132 +370,42 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, guint n_partial = 0; guint n_fsck_partial = 0; - g_hash_table_iter_init (&hash_iter, objects); - while (g_hash_table_iter_next (&hash_iter, &key, &value)) + g_hash_table_iter_init (&hash_iter, all_commits); + while (g_hash_table_iter_next (&hash_iter, &key, NULL)) { GVariant *serialized_key = key; const char *checksum; OstreeObjectType objtype; OstreeRepoCommitState commitstate = 0; - g_autoptr(GVariant) commit = NULL; + g_autoptr (GVariant) commit = NULL; ostree_object_name_deserialize (serialized_key, &checksum, &objtype); - if (objtype == OSTREE_OBJECT_TYPE_COMMIT) - { - if (!ostree_repo_load_commit (repo, checksum, &commit, &commitstate, error)) - return FALSE; + g_assert (objtype == OSTREE_OBJECT_TYPE_COMMIT); - /* If requested, check that all the refs listed in the ref-bindings - * for this commit resolve back to this commit. */ - if (opt_verify_back_refs) - { - g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0); - - const char *collection_id = NULL; - if (!g_variant_lookup (metadata, - OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, - "&s", - &collection_id)) - collection_id = NULL; - - g_autofree const char **refs = NULL; - if (g_variant_lookup (metadata, - OSTREE_COMMIT_META_KEY_REF_BINDING, - "^a&s", - &refs)) - { - for (const char **iter = refs; *iter != NULL; ++iter) - { - g_autofree char *checksum_for_ref = NULL; - - if (collection_id != NULL) - { - const OstreeCollectionRef collection_ref = { (char *) collection_id, (char *) *iter }; - if (!ostree_repo_resolve_collection_ref (repo, &collection_ref, - TRUE, - OSTREE_REPO_RESOLVE_REV_EXT_NONE, - &checksum_for_ref, - cancellable, - error)) - return FALSE; - } - else - { - if (!ostree_repo_resolve_rev (repo, *iter, TRUE, - &checksum_for_ref, error)) - return FALSE; - } - - if (checksum_for_ref == NULL) - { - if (collection_id != NULL) - return glnx_throw (error, - "Collection–ref (%s, %s) in bindings for commit %s does not exist", - collection_id, *iter, checksum); - else - return glnx_throw (error, - "Ref ‘%s’ in bindings for commit %s does not exist", - *iter, checksum); - } - else if (g_strcmp0 (checksum_for_ref, checksum) != 0) - { - if (collection_id != NULL) - return glnx_throw (error, - "Collection–ref (%s, %s) in bindings for commit %s does not resolve to that commit", - collection_id, *iter, checksum); - else - return glnx_throw (error, - "Ref ‘%s’ in bindings for commit %s does not resolve to that commit", - *iter, checksum); - } - } - } - } + if (!ostree_repo_load_commit (repo, checksum, &commit, &commitstate, error)) + return FALSE; - if (opt_add_tombstones) - { - GError *local_error = NULL; - g_autofree char *parent = ostree_commit_get_parent (commit); - if (parent) - { - g_autoptr(GVariant) parent_commit = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, parent, - &parent_commit, &local_error)) - { - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - { - g_ptr_array_add (tombstones, g_strdup (checksum)); - g_clear_error (&local_error); - } - else - { - g_propagate_error (error, local_error); - return FALSE; - } - } - } - } + if (!fsck_one_commit (repo, checksum, commit, tombstones, cancellable, error)) + return FALSE; - if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) - { - n_partial++; - if (commitstate & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL) - n_fsck_partial++; - } - else - g_hash_table_add (commits, g_variant_ref (serialized_key)); + if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) + { + n_partial++; + if (commitstate & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL) + n_fsck_partial++; } + else + g_hash_table_add (commits, g_variant_ref (serialized_key)); } - g_clear_pointer (&objects, g_hash_table_unref); + g_clear_pointer (&all_commits, g_hash_table_unref); if (!opt_quiet) g_print ("Verifying content integrity of %u commit objects...\n", (guint)g_hash_table_size (commits)); - if (!fsck_reachable_objects_from_commits (repo, commits, &found_corruption, - cancellable, error)) + if (!fsck_reachable_objects_from_commits (repo, commits, &found_corruption, cancellable, error)) return FALSE; if (opt_add_tombstones) @@ -443,7 +421,8 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, { const char *checksum = tombstones->pdata[i]; g_print ("Adding tombstone for commit %s\n", checksum); - if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, cancellable, error)) + if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, cancellable, + error)) return FALSE; } } @@ -458,7 +437,7 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, if (n_fsck_partial > 0) return glnx_throw (error, "%u partial commits from fsck-detected corruption", n_partial); - g_print ("object fsck of %d commits completed successfully - no errors found.\n", + g_print ("object fsck of %d commits completed successfully - no errors found.\n", (guint)g_hash_table_size (commits)); return TRUE; diff --git a/src/ostree/ot-builtin-gpg-sign.c b/src/ostree/ot-builtin-gpg-sign.c index bfb1d90..a0ddf2a 100644 --- a/src/ostree/ot-builtin-gpg-sign.c +++ b/src/ostree/ot-builtin-gpg-sign.c @@ -21,11 +21,11 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" +#include "ostree-core-private.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" -#include "ostree-core-private.h" static gboolean opt_delete; static char *opt_gpg_homedir; @@ -35,11 +35,11 @@ static char *opt_gpg_homedir; * man page (man/ostree-gpg-sign.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, "Delete signatures having any of the GPG KEY-IDs" }, - { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR" }, - { NULL } -}; +static GOptionEntry options[] = { { "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, + "Delete signatures having any of the GPG KEY-IDs" }, + { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, + "GPG Homedir to use when looking for keyrings", "HOMEDIR" }, + { NULL } }; static void usage_error (GOptionContext *context, const char *message, GError **error) @@ -50,19 +50,14 @@ usage_error (GOptionContext *context, const char *message, GError **error) } static gboolean -delete_signatures (OstreeRepo *repo, - const char *commit_checksum, - const char * const *key_ids, - guint n_key_ids, - guint *out_n_deleted, - GCancellable *cancellable, - GError **error) +delete_signatures (OstreeRepo *repo, const char *commit_checksum, const char *const *key_ids, + guint n_key_ids, guint *out_n_deleted, GCancellable *cancellable, GError **error) { GVariantDict metadata_dict; - g_autoptr(OstreeGpgVerifyResult) result = NULL; - g_autoptr(GVariant) old_metadata = NULL; - g_autoptr(GVariant) new_metadata = NULL; - g_autoptr(GVariant) signature_data = NULL; + g_autoptr (OstreeGpgVerifyResult) result = NULL; + g_autoptr (GVariant) old_metadata = NULL; + g_autoptr (GVariant) new_metadata = NULL; + g_autoptr (GVariant) signature_data = NULL; GVariantIter iter; GVariant *child; GQueue signatures = G_QUEUE_INIT; @@ -80,17 +75,13 @@ delete_signatures (OstreeRepo *repo, * OTOH, would this really be a useful addition to libostree? */ - if (!ostree_repo_read_commit_detached_metadata (repo, - commit_checksum, - &old_metadata, - cancellable, + if (!ostree_repo_read_commit_detached_metadata (repo, commit_checksum, &old_metadata, cancellable, error)) goto out; g_variant_dict_init (&metadata_dict, old_metadata); - signature_data = g_variant_dict_lookup_value (&metadata_dict, - _OSTREE_METADATA_GPGSIGS_NAME, + signature_data = g_variant_dict_lookup_value (&metadata_dict, _OSTREE_METADATA_GPGSIGS_NAME, G_VARIANT_TYPE ("aay")); /* Taking the approach of deleting whatever matches we find for the @@ -108,9 +99,8 @@ delete_signatures (OstreeRepo *repo, * XXX Reading detached metadata from disk twice here. Another reason * to move this into libostree? */ - result = ostree_repo_verify_commit_ext (repo, commit_checksum, - NULL, NULL, - cancellable, &local_error); + result = ostree_repo_verify_commit_ext (repo, commit_checksum, NULL, NULL, cancellable, + &local_error); if (result == NULL) { g_variant_dict_clear (&metadata_dict); @@ -169,21 +159,17 @@ delete_signatures (OstreeRepo *repo, while (!g_queue_is_empty (&signatures)) { - g_autoptr(GVariant) sigchild = g_queue_pop_head (&signatures); + g_autoptr (GVariant) sigchild = g_queue_pop_head (&signatures); g_variant_builder_add_value (&signature_builder, sigchild); } - g_variant_dict_insert_value (&metadata_dict, - _OSTREE_METADATA_GPGSIGS_NAME, + g_variant_dict_insert_value (&metadata_dict, _OSTREE_METADATA_GPGSIGS_NAME, g_variant_builder_end (&signature_builder)); } /* Commit the new metadata. */ new_metadata = g_variant_dict_end (&metadata_dict); - if (!ostree_repo_write_commit_detached_metadata (repo, - commit_checksum, - new_metadata, - cancellable, + if (!ostree_repo_write_commit_detached_metadata (repo, commit_checksum, new_metadata, cancellable, error)) goto out; @@ -199,64 +185,55 @@ delete_signatures (OstreeRepo *repo, } gboolean -ostree_builtin_gpg_sign (int argc, char **argv,OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_gpg_sign (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - g_autofree char *resolved_commit = NULL; - const char *commit; - char **key_ids; - int n_key_ids, ii; - gboolean ret = FALSE; - context = g_option_context_new ("COMMIT KEY-ID..."); + g_autoptr (GOptionContext) context = g_option_context_new ("COMMIT KEY-ID..."); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) - goto out; + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) + return FALSE; if (argc < 2) { usage_error (context, "Need a COMMIT to sign", error); - goto out; + return FALSE; } if (argc < 3) { usage_error (context, "Need at least one GPG KEY-ID to sign with", error); - goto out; + return FALSE; } - commit = argv[1]; - key_ids = argv + 2; - n_key_ids = argc - 2; + const char *commit = argv[1]; + char **key_ids = argv + 2; + int n_key_ids = argc - 2; + g_autofree char *resolved_commit = NULL; if (!ostree_repo_resolve_rev (repo, commit, FALSE, &resolved_commit, error)) - goto out; + return FALSE; if (opt_delete) { guint n_deleted = 0; - if (delete_signatures (repo, resolved_commit, - (const char * const *) key_ids, n_key_ids, - &n_deleted, cancellable, error)) - { - g_print ("Signatures deleted: %u\n", n_deleted); - ret = TRUE; - } + if (!delete_signatures (repo, resolved_commit, (const char *const *)key_ids, n_key_ids, + &n_deleted, cancellable, error)) + return FALSE; - goto out; + g_print ("Signatures deleted: %u\n", n_deleted); + return TRUE; } - for (ii = 0; ii < n_key_ids; ii++) + for (int ii = 0; ii < n_key_ids; ii++) { - if (!ostree_repo_sign_commit (repo, resolved_commit, key_ids[ii], - opt_gpg_homedir, cancellable, error)) - goto out; + if (!ostree_repo_sign_commit (repo, resolved_commit, key_ids[ii], opt_gpg_homedir, + cancellable, error)) + return FALSE; } - ret = TRUE; - -out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-builtin-init.c b/src/ostree/ot-builtin-init.c index a699a55..114f9ba 100644 --- a/src/ostree/ot-builtin-init.c +++ b/src/ostree/ot-builtin-init.c @@ -21,9 +21,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" static char *opt_mode = "bare"; static char *opt_collection_id = NULL; @@ -33,35 +33,34 @@ static char *opt_collection_id = NULL; * man page (man/ostree-init.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, bare-user, bare-user-only, archive)", NULL }, - { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, - "Globally unique ID for this repository as an collection of refs for redistribution to other repositories", "COLLECTION-ID" }, - { NULL } -}; +static GOptionEntry options[] + = { { "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, + "Initialize repository in given mode (bare, bare-user, bare-user-only, archive)", NULL }, + { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, + "Globally unique ID for this repository as an collection of refs for redistribution to " + "other repositories", + "COLLECTION-ID" }, + { NULL } }; gboolean -ostree_builtin_init (int argc, char **argv,OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_init (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - gboolean ret = FALSE; - OstreeRepoMode mode; - - context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) - goto out; + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) + return FALSE; + OstreeRepoMode mode; if (!ostree_repo_mode_from_string (opt_mode, &mode, error)) - goto out; + return FALSE; if (!ostree_repo_set_collection_id (repo, opt_collection_id, error)) - goto out; + return FALSE; if (!ostree_repo_create (repo, mode, NULL, error)) - goto out; + return FALSE; - ret = TRUE; - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-builtin-log.c b/src/ostree/ot-builtin-log.c index c75656d..222e67a 100644 --- a/src/ostree/ot-builtin-log.c +++ b/src/ostree/ot-builtin-log.c @@ -21,10 +21,10 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-builtins.h" #include "ot-dump.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_raw; @@ -34,87 +34,69 @@ static gboolean opt_raw; * man page (man/ostree-log.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" }, - { NULL } -}; +static GOptionEntry options[] + = { { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" }, { NULL } }; static gboolean -log_commit (OstreeRepo *repo, - const gchar *checksum, - gboolean is_recurse, - OstreeDumpFlags flags, - GError **error) +log_commit (OstreeRepo *repo, const gchar *checksum, gboolean is_recurse, OstreeDumpFlags flags, + GError **error) { - g_autoptr(GVariant) variant = NULL; - g_autofree char *parent = NULL; - gboolean ret = FALSE; GError *local_error = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, - &variant, &local_error)) + g_autoptr (GVariant) variant = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, &variant, &local_error)) { if (is_recurse && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_print ("<< History beyond this commit not fetched >>\n"); g_clear_error (&local_error); - ret = TRUE; + return TRUE; } else { g_propagate_error (error, local_error); + return FALSE; } - goto out; } ot_dump_object (OSTREE_OBJECT_TYPE_COMMIT, checksum, variant, flags); /* Get the parent of this commit */ - parent = ostree_commit_get_parent (variant); + g_autofree char *parent = ostree_commit_get_parent (variant); if (parent && !log_commit (repo, parent, TRUE, flags, error)) - goto out; + return FALSE; - ret = TRUE; -out: - return ret; + return TRUE; } gboolean -ostree_builtin_log (int argc, - char **argv, - OstreeCommandInvocation *invocation, - GCancellable *cancellable, - GError **error) +ostree_builtin_log (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - gboolean ret = FALSE; - const char *rev; - g_autofree char *checksum = NULL; - OstreeDumpFlags flags = OSTREE_DUMP_NONE; - context = g_option_context_new ("REV"); + g_autoptr (GOptionContext) context = g_option_context_new ("REV"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) - goto out; - - if (opt_raw) - flags |= OSTREE_DUMP_RAW; + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) + return FALSE; if (argc <= 1) { ot_util_usage_error (context, "A rev argument is required", error); - goto out; + return FALSE; } - rev = argv[1]; + const char *rev = argv[1]; + OstreeDumpFlags flags = OSTREE_DUMP_NONE; + if (opt_raw) + flags |= OSTREE_DUMP_RAW; + g_autofree char *checksum = NULL; if (!ostree_repo_resolve_rev (repo, rev, FALSE, &checksum, error)) - goto out; + return FALSE; if (!log_commit (repo, checksum, FALSE, flags, error)) - goto out; + return FALSE; - ret = TRUE; - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-builtin-ls.c b/src/ostree/ot-builtin-ls.c index 5fa080a..780bc01 100644 --- a/src/ostree/ot-builtin-ls.c +++ b/src/ostree/ot-builtin-ls.c @@ -21,10 +21,10 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" -#include "ostree.h" #include "ostree-repo-file.h" +#include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_dironly; @@ -38,27 +38,26 @@ static gboolean opt_nul_filenames_only; * man page (man/ostree-ls.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "dironly", 'd', 0, G_OPTION_ARG_NONE, &opt_dironly, "Do not recurse into directory arguments", NULL }, - { "recursive", 'R', 0, G_OPTION_ARG_NONE, &opt_recursive, "Print directories recursively", NULL }, - { "checksum", 'C', 0, G_OPTION_ARG_NONE, &opt_checksum, "Print checksum", NULL }, - { "xattrs", 'X', 0, G_OPTION_ARG_NONE, &opt_xattrs, "Print extended attributes", NULL }, - { "nul-filenames-only", 0, 0, G_OPTION_ARG_NONE, &opt_nul_filenames_only, "Print only filenames, NUL separated", NULL }, - { NULL } -}; +static GOptionEntry options[] + = { { "dironly", 'd', 0, G_OPTION_ARG_NONE, &opt_dironly, + "Do not recurse into directory arguments", NULL }, + { "recursive", 'R', 0, G_OPTION_ARG_NONE, &opt_recursive, "Print directories recursively", + NULL }, + { "checksum", 'C', 0, G_OPTION_ARG_NONE, &opt_checksum, "Print checksum", NULL }, + { "xattrs", 'X', 0, G_OPTION_ARG_NONE, &opt_xattrs, "Print extended attributes", NULL }, + { "nul-filenames-only", 0, 0, G_OPTION_ARG_NONE, &opt_nul_filenames_only, + "Print only filenames, NUL separated", NULL }, + { NULL } }; static gboolean -print_one_file_text (GFile *f, - GFileInfo *file_info, - GCancellable *cancellable, - GError **error) +print_one_file_text (GFile *f, GFileInfo *file_info, GCancellable *cancellable, GError **error) { - g_autoptr(GString) buf = g_string_new (""); + g_autoptr (GString) buf = g_string_new (""); char type_c; guint32 mode; guint32 type; - if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile*)f, error)) + if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *)f, error)) return FALSE; type_c = '?'; @@ -76,9 +75,9 @@ print_one_file_text (GFile *f, type_c = 'l'; break; case G_FILE_TYPE_SPECIAL: - if (S_ISCHR(mode)) + if (S_ISCHR (mode)) type_c = 'c'; - else if (S_ISBLK(mode)) + else if (S_ISBLK (mode)) type_c = 'b'; break; case G_FILE_TYPE_UNKNOWN: @@ -87,17 +86,17 @@ print_one_file_text (GFile *f, return glnx_throw (error, "Invalid file type"); } g_string_append_c (buf, type_c); - g_string_append_printf (buf, "0%04o %u %u %6" G_GUINT64_FORMAT " ", - mode & ~S_IFMT, + g_string_append_printf (buf, "0%04o %u %u %6" G_GUINT64_FORMAT " ", mode & ~S_IFMT, g_file_info_get_attribute_uint32 (file_info, "unix::uid"), g_file_info_get_attribute_uint32 (file_info, "unix::gid"), g_file_info_get_attribute_uint64 (file_info, "standard::size")); - + if (opt_checksum) { if (type == G_FILE_TYPE_DIRECTORY) - g_string_append_printf (buf, "%s ", ostree_repo_file_tree_get_contents_checksum ((OstreeRepoFile*)f)); - g_string_append_printf (buf, "%s ", ostree_repo_file_get_checksum ((OstreeRepoFile*)f)); + g_string_append_printf (buf, "%s ", + ostree_repo_file_tree_get_contents_checksum ((OstreeRepoFile *)f)); + g_string_append_printf (buf, "%s ", ostree_repo_file_get_checksum ((OstreeRepoFile *)f)); } if (opt_xattrs) @@ -105,9 +104,9 @@ print_one_file_text (GFile *f, GVariant *xattrs; char *formatted; - if (!ostree_repo_file_get_xattrs ((OstreeRepoFile*)f, &xattrs, cancellable, error)) + if (!ostree_repo_file_get_xattrs ((OstreeRepoFile *)f, &xattrs, cancellable, error)) return FALSE; - + formatted = g_variant_print (xattrs, TRUE); g_string_append (buf, "{ "); g_string_append (buf, formatted); @@ -119,22 +118,21 @@ print_one_file_text (GFile *f, g_string_append (buf, gs_file_get_path_cached (f)); if (type == G_FILE_TYPE_SYMBOLIC_LINK) - g_string_append_printf (buf, " -> %s", g_file_info_get_attribute_byte_string (file_info, "standard::symlink-target")); - + g_string_append_printf ( + buf, " -> %s", + g_file_info_get_attribute_byte_string (file_info, "standard::symlink-target")); + g_print ("%s\n", buf->str); return TRUE; } static gboolean -print_one_file_binary (GFile *f, - GFileInfo *file_info, - GCancellable *cancellable, - GError **error) +print_one_file_binary (GFile *f, GFileInfo *file_info, GCancellable *cancellable, GError **error) { const char *path; - if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile*)f, error)) + if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *)f, error)) return FALSE; path = gs_file_get_path_cached (f); @@ -146,10 +144,7 @@ print_one_file_binary (GFile *f, } static gboolean -print_one_file (GFile *f, - GFileInfo *file_info, - GCancellable *cancellable, - GError **error) +print_one_file (GFile *f, GFileInfo *file_info, GCancellable *cancellable, GError **error) { if (opt_nul_filenames_only) return print_one_file_binary (f, file_info, cancellable, error); @@ -158,14 +153,11 @@ print_one_file (GFile *f, } static gboolean -print_directory_recurse (GFile *f, - int depth, - GCancellable *cancellable, - GError **error) +print_directory_recurse (GFile *f, int depth, GCancellable *cancellable, GError **error) { - g_autoptr(GFileEnumerator) dir_enum = NULL; - g_autoptr(GFile) child = NULL; - g_autoptr(GFileInfo) child_info = NULL; + g_autoptr (GFileEnumerator) dir_enum = NULL; + g_autoptr (GFile) child = NULL; + g_autoptr (GFileInfo) child_info = NULL; GError *temp_error = NULL; if (depth > 0) @@ -175,13 +167,11 @@ print_directory_recurse (GFile *f, else g_assert (depth == -1); - dir_enum = g_file_enumerate_children (f, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, - error); + dir_enum = g_file_enumerate_children (f, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, error); if (dir_enum == NULL) return FALSE; - + while ((child_info = g_file_enumerator_next_file (dir_enum, NULL, &temp_error)) != NULL) { g_clear_object (&child); @@ -208,29 +198,25 @@ print_directory_recurse (GFile *f, } static gboolean -print_one_argument (OstreeRepo *repo, - GFile *root, - const char *arg, - GCancellable *cancellable, - GError **error) +print_one_argument (OstreeRepo *repo, GFile *root, const char *arg, GCancellable *cancellable, + GError **error) { g_assert (root != NULL); g_assert (arg != NULL); - g_autoptr(GFile) f = g_file_resolve_relative_path (root, arg); + g_autoptr (GFile) f = g_file_resolve_relative_path (root, arg); if (f == NULL) return glnx_throw (error, "Failed to resolve path '%s'", arg); - g_autoptr(GFileInfo) file_info = NULL; - file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + g_autoptr (GFileInfo) file_info = NULL; + file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (file_info == NULL) return FALSE; - + if (!print_one_file (f, file_info, cancellable, error)) return FALSE; - + if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) { if (opt_recursive) @@ -244,22 +230,24 @@ print_one_argument (OstreeRepo *repo, return FALSE; } } - + return TRUE; } gboolean -ostree_builtin_ls (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_ls (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; const char *rev; int i; - g_autoptr(GFile) root = NULL; + g_autoptr (GFile) root = NULL; context = g_option_context_new ("COMMIT [PATH...]"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (argc <= 1) @@ -285,6 +273,6 @@ ostree_builtin_ls (int argc, char **argv, OstreeCommandInvocation *invocation, G if (!print_one_argument (repo, root, "/", cancellable, error)) return FALSE; } - + return TRUE; } diff --git a/src/ostree/ot-builtin-prune.c b/src/ostree/ot-builtin-prune.c index 73dfe5e..1416ed8 100644 --- a/src/ostree/ot-builtin-prune.c +++ b/src/ostree/ot-builtin-prune.c @@ -22,9 +22,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" #include "parse-datetime.h" @@ -44,29 +44,39 @@ static gboolean opt_commit_only; */ static GOptionEntry options[] = { - { "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Only display unreachable objects; don't delete", NULL }, - { "refs-only", 0, 0, G_OPTION_ARG_NONE, &opt_refs_only, "Only compute reachability via refs", NULL }, - { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Only traverse DEPTH parents for each commit (default: -1=infinite)", "DEPTH" }, - { "delete-commit", 0, 0, G_OPTION_ARG_STRING, &opt_delete_commit, "Specify a commit to delete", "COMMIT" }, - { "keep-younger-than", 0, 0, G_OPTION_ARG_STRING, &opt_keep_younger_than, "Prune all commits older than the specified date", "DATE" }, - { "static-deltas-only", 0, 0, G_OPTION_ARG_NONE, &opt_static_deltas_only, "Change the behavior of delete-commit and keep-younger-than to prune only static deltas" }, - { "retain-branch-depth", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_retain_branch_depth, "Additionally retain BRANCH=DEPTH commits", "BRANCH=DEPTH" }, - { "only-branch", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_only_branches, "Only prune BRANCH (may be specified multiple times)", "BRANCH" }, - { "commit-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Only traverse and delete commit objects.", NULL }, + { "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, + "Only display unreachable objects; don't delete", NULL }, + { "refs-only", 0, 0, G_OPTION_ARG_NONE, &opt_refs_only, "Only compute reachability via refs", + NULL }, + { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, + "Only traverse DEPTH parents for each commit (default: -1=infinite)", "DEPTH" }, + { "delete-commit", 0, 0, G_OPTION_ARG_STRING, &opt_delete_commit, "Specify a commit to delete", + "COMMIT" }, + { "keep-younger-than", 0, 0, G_OPTION_ARG_STRING, &opt_keep_younger_than, + "Prune all commits older than the specified date", "DATE" }, + { "static-deltas-only", 0, 0, G_OPTION_ARG_NONE, &opt_static_deltas_only, + "Change the behavior of delete-commit and keep-younger-than to prune only static deltas" }, + { "retain-branch-depth", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_retain_branch_depth, + "Additionally retain BRANCH=DEPTH commits", "BRANCH=DEPTH" }, + { "only-branch", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_only_branches, + "Only prune BRANCH (may be specified multiple times)", "BRANCH" }, + { "commit-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, + "Only traverse and delete commit objects.", NULL }, { NULL } }; static gboolean -delete_commit (OstreeRepo *repo, const char *commit_to_delete, GCancellable *cancellable, GError **error) +delete_commit (OstreeRepo *repo, const char *commit_to_delete, GCancellable *cancellable, + GError **error) { - g_autoptr(GHashTable) refs = NULL; /* (element-type utf8 utf8) */ - g_autoptr(GHashTable) collection_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) refs = NULL; /* (element-type utf8 utf8) */ + g_autoptr (GHashTable) collection_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ /* Check refs which are not in a collection. */ if (!ostree_repo_list_refs (repo, NULL, &refs, cancellable, error)) return FALSE; - GLNX_HASH_TABLE_FOREACH_KV(refs, const char *, ref, const char *, commit) + GLNX_HASH_TABLE_FOREACH_KV (refs, const char *, ref, const char *, commit) { if (g_strcmp0 (commit_to_delete, commit) == 0) return glnx_throw (error, "Commit '%s' is referenced by '%s'", commit_to_delete, ref); @@ -74,32 +84,31 @@ delete_commit (OstreeRepo *repo, const char *commit_to_delete, GCancellable *can /* And check refs which *are* in a collection. */ if (!ostree_repo_list_collection_refs (repo, NULL, &collection_refs, - OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, - cancellable, error)) + OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES, cancellable, + error)) return FALSE; - GLNX_HASH_TABLE_FOREACH_KV (collection_refs, const OstreeCollectionRef*, ref, - const char *, commit) + GLNX_HASH_TABLE_FOREACH_KV (collection_refs, const OstreeCollectionRef *, ref, const char *, + commit) { if (g_strcmp0 (commit_to_delete, commit) == 0) - return glnx_throw (error, "Commit '%s' is referenced by (%s, %s)", - commit_to_delete, ref->collection_id, ref->ref_name); + return glnx_throw (error, "Commit '%s' is referenced by (%s, %s)", commit_to_delete, + ref->collection_id, ref->ref_name); } if (!ot_enable_tombstone_commits (repo, error)) return FALSE; - if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_to_delete, cancellable, error)) + if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_to_delete, cancellable, + error)) return FALSE; return TRUE; } static gboolean -traverse_keep_younger_than (OstreeRepo *repo, const char *checksum, - struct timespec *ts, - GHashTable *reachable, - GCancellable *cancellable, GError **error) +traverse_keep_younger_than (OstreeRepo *repo, const char *checksum, struct timespec *ts, + GHashTable *reachable, GCancellable *cancellable, GError **error) { g_autofree char *next_checksum = g_strdup (checksum); OstreeRepoCommitTraverseFlags traverse_flags = OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE; @@ -109,13 +118,13 @@ traverse_keep_younger_than (OstreeRepo *repo, const char *checksum, /* This is the first commit in our loop, which has a ref pointing to it. We * don't want to auto-prune it. */ - if (!ostree_repo_traverse_commit_with_flags (repo, traverse_flags, checksum, 0, reachable, - NULL, cancellable, error)) + if (!ostree_repo_traverse_commit_with_flags (repo, traverse_flags, checksum, 0, reachable, NULL, + cancellable, error)) return FALSE; while (TRUE) { - g_autoptr(GVariant) commit = NULL; + g_autoptr (GVariant) commit = NULL; if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT, next_checksum, &commit, error)) return FALSE; @@ -127,8 +136,8 @@ traverse_keep_younger_than (OstreeRepo *repo, const char *checksum, if (commit_timestamp >= ts->tv_sec) { /* It's newer, traverse it */ - if (!ostree_repo_traverse_commit_with_flags (repo, traverse_flags, next_checksum, 0, reachable, - NULL, cancellable, error)) + if (!ostree_repo_traverse_commit_with_flags (repo, traverse_flags, next_checksum, 0, + reachable, NULL, cancellable, error)) return FALSE; g_free (next_checksum); @@ -146,11 +155,13 @@ traverse_keep_younger_than (OstreeRepo *repo, const char *checksum, } gboolean -ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new (""); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (!opt_no_prune && !ostree_ensure_repo_writable (repo, error)) @@ -163,16 +174,17 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation { if (opt_no_prune) { - ot_util_usage_error (context, "Cannot specify both --delete-commit and --no-prune", error); + ot_util_usage_error (context, "Cannot specify both --delete-commit and --no-prune", + error); return FALSE; } - if (opt_static_deltas_only) - { - if(!ostree_repo_prune_static_deltas (repo, opt_delete_commit, cancellable, error)) - return FALSE; - } - else if (!delete_commit (repo, opt_delete_commit, cancellable, error)) - return FALSE; + if (opt_static_deltas_only) + { + if (!ostree_repo_prune_static_deltas (repo, opt_delete_commit, cancellable, error)) + return FALSE; + } + else if (!delete_commit (repo, opt_delete_commit, cancellable, error)) + return FALSE; } else { @@ -181,7 +193,8 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation * https://github.com/ostreedev/ostree/issues/1479 */ if (opt_static_deltas_only) - return glnx_throw (error, "--static-deltas-only requires --delete-commit; see https://github.com/ostreedev/ostree/issues/1479"); + return glnx_throw (error, "--static-deltas-only requires --delete-commit; see " + "https://github.com/ostreedev/ostree/issues/1479"); } OstreeRepoPruneFlags pruneflags = 0; @@ -201,17 +214,28 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation guint64 objsize_total; if (!(opt_retain_branch_depth || opt_keep_younger_than || opt_only_branches)) { - if (!ostree_repo_prune (repo, pruneflags, opt_depth, - &n_objects_total, &n_objects_pruned, &objsize_total, - cancellable, error)) + if (!ostree_repo_prune (repo, pruneflags, opt_depth, &n_objects_total, &n_objects_pruned, + &objsize_total, cancellable, error)) return FALSE; } else { - g_autoptr(GHashTable) all_refs = NULL; - g_autoptr(GHashTable) reachable = ostree_repo_traverse_new_reachable (); - g_autoptr(GHashTable) retain_branch_depth = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - struct timespec keep_younger_than_ts = {0, }; + /* In this branch, we need to compute the reachability set manually. + * While we do this, we can't let new content in since it'll race with + * reachability calculations and we may immediately nuke it. So push an + * exclusive lock now. */ + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + if (!lock) + return FALSE; + + g_autoptr (GHashTable) all_refs = NULL; + g_autoptr (GHashTable) reachable = ostree_repo_traverse_new_reachable (); + g_autoptr (GHashTable) retain_branch_depth + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + struct timespec keep_younger_than_ts = { + 0, + }; GHashTableIter hash_iter; gpointer key, value; @@ -250,8 +274,7 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation /* We start from the refs */ /* FIXME: Do we also want to look at ostree_repo_list_collection_refs()? */ - if (!ostree_repo_list_refs (repo, NULL, &all_refs, - cancellable, error)) + if (!ostree_repo_list_refs (repo, NULL, &all_refs, cancellable, error)) return FALSE; /* Process --only-branch. Note this combines with --retain-branch-depth; one @@ -266,14 +289,14 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation if (opt_only_branches) { /* Turn --only-branch into a set */ - g_autoptr(GHashTable) only_branches_set = g_hash_table_new (g_str_hash, g_str_equal); + g_autoptr (GHashTable) only_branches_set = g_hash_table_new (g_str_hash, g_str_equal); for (char **iter = opt_only_branches; iter && *iter; iter++) { const char *ref = *iter; /* Ensure the specified branch exists */ if (!ostree_repo_resolve_rev (repo, ref, FALSE, NULL, error)) return FALSE; - g_hash_table_add (only_branches_set, (char*)ref); + g_hash_table_add (only_branches_set, (char *)ref); } /* Iterate over all refs, add equivalent of --retain-branch-depth=$ref=-1 @@ -282,10 +305,11 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation */ GLNX_HASH_TABLE_FOREACH (all_refs, const char *, ref) { - if (!g_hash_table_contains (only_branches_set, ref) && - !g_hash_table_contains (retain_branch_depth, ref)) + if (!g_hash_table_contains (only_branches_set, ref) + && !g_hash_table_contains (retain_branch_depth, ref)) { - g_hash_table_insert (retain_branch_depth, g_strdup (ref), GINT_TO_POINTER ((int)-1)); + g_hash_table_insert (retain_branch_depth, g_strdup (ref), + GINT_TO_POINTER ((int)-1)); } } } @@ -309,54 +333,48 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation * --retain-branch-depth=myos/x86_64/dev=5 */ if (depthp) - depth = GPOINTER_TO_INT(depthp); + depth = GPOINTER_TO_INT (depthp); else if (opt_keep_younger_than) { - if (!traverse_keep_younger_than (repo, checksum, - &keep_younger_than_ts, - reachable, + if (!traverse_keep_younger_than (repo, checksum, &keep_younger_than_ts, reachable, cancellable, error)) return FALSE; /* Okay, we handled the younger-than case; the other * two fall through to plain depth-based handling below. */ - continue; /* Note again, we're skipping the below bit */ + continue; /* Note again, we're skipping the below bit */ } else depth = opt_depth; /* No --retain-branch-depth for this branch, use the global default */ g_debug ("Finding objects to keep for commit %s", checksum); - if (!ostree_repo_traverse_commit_with_flags (repo, traverse_flags, checksum, depth, reachable, - NULL, cancellable, error)) + if (!ostree_repo_traverse_commit_with_flags (repo, traverse_flags, checksum, depth, + reachable, NULL, cancellable, error)) return FALSE; } /* We've gathered the reachable set; start the prune ✀ */ - { OstreeRepoPruneOptions opts = { pruneflags, reachable }; - if (!ostree_repo_prune_from_reachable (repo, &opts, - &n_objects_total, - &n_objects_pruned, - &objsize_total, - cancellable, error)) + { + OstreeRepoPruneOptions opts = { pruneflags, reachable }; + if (!ostree_repo_prune_from_reachable (repo, &opts, &n_objects_total, &n_objects_pruned, + &objsize_total, cancellable, error)) return FALSE; } } g_autofree char *formatted_freed_size = g_format_size_full (objsize_total, 0); - if (opt_commit_only) - g_print("Total (commit only) objects: %u\n", n_objects_total); + if (opt_commit_only) + g_print ("Total (commit only) objects: %u\n", n_objects_total); else g_print ("Total objects: %u\n", n_objects_total); if (n_objects_pruned == 0) g_print ("No unreachable objects\n"); else if (pruneflags & OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE) - g_print ("Would delete: %u objects, freeing %s\n", - n_objects_pruned, formatted_freed_size); + g_print ("Would delete: %u objects, freeing %s\n", n_objects_pruned, formatted_freed_size); else - g_print ("Deleted %u objects, %s freed\n", - n_objects_pruned, formatted_freed_size); + g_print ("Deleted %u objects, %s freed\n", n_objects_pruned, formatted_freed_size); return TRUE; } diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c index c39930a..d489c44 100644 --- a/src/ostree/ot-builtin-pull-local.c +++ b/src/ostree/ot-builtin-pull-local.c @@ -21,12 +21,12 @@ #include "config.h" -#include #include +#include -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" static char *opt_remote; @@ -36,6 +36,7 @@ static gboolean opt_per_object_fsync; static gboolean opt_untrusted; static gboolean opt_bareuseronly_files; static gboolean opt_require_static_deltas; +static gboolean opt_disable_static_deltas; static gboolean opt_gpg_verify; static gboolean opt_gpg_verify_summary; static gboolean opt_disable_verify_bindings; @@ -46,45 +47,57 @@ static int opt_depth = 0; * man page (man/ostree-pull-local.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Fetch only the commit metadata", NULL }, - { "remote", 0, 0, G_OPTION_ARG_STRING, &opt_remote, "Add REMOTE to refspec", "REMOTE" }, - { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, - { "per-object-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_per_object_fsync, "Perform writes in such a way that avoids stalling concurrent processes", NULL }, - { "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, "Verify checksums of local sources (always enabled for HTTP pulls)", NULL }, - { "bareuseronly-files", 0, 0, G_OPTION_ARG_NONE, &opt_bareuseronly_files, "Reject regular files with mode outside of 0775 (world writable, suid, etc.)", NULL }, - { "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, "Require static deltas", NULL }, - { "gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify, "GPG verify commits (must specify --remote)", NULL }, - { "gpg-verify-summary", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify_summary, "GPG verify summary (must specify --remote)", NULL }, - { "disable-verify-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_disable_verify_bindings, "Do not verify commit bindings", NULL }, - { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" }, - { NULL } -}; +static GOptionEntry options[] + = { { "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, + "Fetch only the commit metadata", NULL }, + { "remote", 0, 0, G_OPTION_ARG_STRING, &opt_remote, "Add REMOTE to refspec", "REMOTE" }, + { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", + NULL }, + { "per-object-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_per_object_fsync, + "Perform writes in such a way that avoids stalling concurrent processes", NULL }, + { "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, + "Verify checksums of local sources (always enabled for HTTP pulls)", NULL }, + { "bareuseronly-files", 0, 0, G_OPTION_ARG_NONE, &opt_bareuseronly_files, + "Reject regular files with mode outside of 0775 (world writable, suid, etc.)", NULL }, + { "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, + "Require static deltas", NULL }, + { "disable-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_disable_static_deltas, + "Do not use static deltas", NULL }, + { "gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify, + "GPG verify commits (must specify --remote)", NULL }, + { "gpg-verify-summary", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify_summary, + "GPG verify summary (must specify --remote)", NULL }, + { "disable-verify-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_disable_verify_bindings, + "Do not verify commit bindings", NULL }, + { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, + "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" }, + { NULL } }; /* See canonical version of this in ot-builtin-pull.c */ static void -noninteractive_console_progress_changed (OstreeAsyncProgress *progress, - gpointer user_data) +noninteractive_console_progress_changed (OstreeAsyncProgress *progress, gpointer user_data) { /* We do nothing here - we just want the final status */ } gboolean -ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; int i; const char *src_repo_arg; g_autofree char *src_repo_uri = NULL; - g_autoptr(OstreeAsyncProgress) progress = NULL; - g_autoptr(GPtrArray) refs_to_fetch = NULL; + g_autoptr (OstreeAsyncProgress) progress = NULL; + g_autoptr (GPtrArray) refs_to_fetch = NULL; OstreeRepoPullFlags pullflags = 0; context = g_option_context_new ("SRC_REPO [REFS...]"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) goto out; if (!ostree_ensure_repo_writable (repo, error)) @@ -95,8 +108,7 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc gchar *help = g_option_context_get_help (context, TRUE, NULL); g_printerr ("%s\n", help); g_free (help); - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "DESTINATION must be specified"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "DESTINATION must be specified"); goto out; } @@ -105,7 +117,7 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc if (src_repo_arg[0] == '/') src_repo_uri = g_strconcat ("file://", src_repo_arg, NULL); else - { + { g_autofree char *cwd = g_get_current_dir (); src_repo_uri = g_strconcat ("file://", cwd, "/", src_repo_arg, NULL); } @@ -122,9 +134,9 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc if (argc == 2) { - g_autoptr(GFile) src_repo_path = g_file_new_for_path (src_repo_arg); - g_autoptr(OstreeRepo) src_repo = ostree_repo_new (src_repo_path); - g_autoptr(GHashTable) refs_to_clone = NULL; + g_autoptr (GFile) src_repo_path = g_file_new_for_path (src_repo_arg); + g_autoptr (OstreeRepo) src_repo = ostree_repo_new (src_repo_path); + g_autoptr (GHashTable) refs_to_clone = NULL; refs_to_fetch = g_ptr_array_new_with_free_func (g_free); @@ -133,13 +145,13 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc /* FIXME: This should grow support for pulling refs from refs/mirrors on * a local repository, using ostree_repo_list_collection_refs(). */ - if (!ostree_repo_list_refs (src_repo, NULL, &refs_to_clone, - cancellable, error)) + if (!ostree_repo_list_refs (src_repo, NULL, &refs_to_clone, cancellable, error)) goto out; - { GHashTableIter hashiter; + { + GHashTableIter hashiter; gpointer hkey, hvalue; - + g_hash_table_iter_init (&hashiter, refs_to_clone); while (g_hash_table_iter_next (&hashiter, &hkey, &hvalue)) g_ptr_array_add (refs_to_fetch, g_strdup (hkey)); @@ -152,15 +164,18 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc for (i = 2; i < argc; i++) { const char *ref = argv[i]; - - g_ptr_array_add (refs_to_fetch, (char*)ref); + + g_ptr_array_add (refs_to_fetch, (char *)ref); } g_ptr_array_add (refs_to_fetch, NULL); } - { GVariantBuilder builder; - g_autoptr(GVariant) opts = NULL; - g_auto(GLnxConsoleRef) console = { 0, }; + { + GVariantBuilder builder; + g_autoptr (GVariant) opts = NULL; + g_auto (GLnxConsoleRef) console = { + 0, + }; glnx_console_lock (&console); @@ -168,21 +183,27 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc g_variant_builder_add (&builder, "{s@v}", "flags", g_variant_new_variant (g_variant_new_int32 (pullflags))); - g_variant_builder_add (&builder, "{s@v}", "refs", - g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch->pdata, -1))); + g_variant_builder_add ( + &builder, "{s@v}", "refs", + g_variant_new_variant (g_variant_new_strv ((const char *const *)refs_to_fetch->pdata, -1))); if (opt_remote) g_variant_builder_add (&builder, "{s@v}", "override-remote-name", g_variant_new_variant (g_variant_new_string (opt_remote))); - g_variant_builder_add (&builder, "{s@v}", "require-static-deltas", - g_variant_new_variant (g_variant_new_boolean (opt_require_static_deltas))); + g_variant_builder_add ( + &builder, "{s@v}", "disable-static-deltas", + g_variant_new_variant (g_variant_new_boolean (opt_disable_static_deltas))); + g_variant_builder_add ( + &builder, "{s@v}", "require-static-deltas", + g_variant_new_variant (g_variant_new_boolean (opt_require_static_deltas))); if (opt_gpg_verify) g_variant_builder_add (&builder, "{s@v}", "gpg-verify", g_variant_new_variant (g_variant_new_boolean (TRUE))); if (opt_gpg_verify_summary) g_variant_builder_add (&builder, "{s@v}", "gpg-verify-summary", g_variant_new_variant (g_variant_new_boolean (TRUE))); - g_variant_builder_add (&builder, "{s@v}", "disable-verify-bindings", - g_variant_new_variant (g_variant_new_boolean (opt_disable_verify_bindings))); + g_variant_builder_add ( + &builder, "{s@v}", "disable-verify-bindings", + g_variant_new_variant (g_variant_new_boolean (opt_disable_verify_bindings))); g_variant_builder_add (&builder, "{s@v}", "depth", g_variant_new_variant (g_variant_new_int32 (opt_depth))); /* local pulls always disable signapi verification. If you don't want this, use @@ -193,25 +214,24 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc g_variant_builder_add (&builder, "{s@v}", "disable-sign-verify-summary", g_variant_new_variant (g_variant_new_boolean (TRUE))); if (opt_per_object_fsync) - g_variant_builder_add (&builder, "{s@v}", "per-object-fsync", - g_variant_new_variant (g_variant_new_boolean (TRUE))); + g_variant_builder_add (&builder, "{s@v}", "per-object-fsync", + g_variant_new_variant (g_variant_new_boolean (TRUE))); if (console.is_tty) - progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect ( + ostree_repo_pull_default_console_progress_changed, &console); else - progress = ostree_async_progress_new_and_connect (noninteractive_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect (noninteractive_console_progress_changed, + &console); opts = g_variant_ref_sink (g_variant_builder_end (&builder)); - if (!ostree_repo_pull_with_options (repo, src_repo_uri, - opts, - progress, - cancellable, error)) + if (!ostree_repo_pull_with_options (repo, src_repo_uri, opts, progress, cancellable, error)) goto out; if (!console.is_tty) { g_assert (progress); - const char *status = ostree_async_progress_get_status (progress); + g_autofree char *status = ostree_async_progress_get_status (progress); if (status) g_print ("%s\n", status); } @@ -219,7 +239,7 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeCommandInvocation *invoc } ret = TRUE; - out: +out: if (repo) ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 61f408e..c06f4e6 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -21,9 +21,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_disable_fsync; @@ -37,55 +37,92 @@ static gboolean opt_untrusted; static gboolean opt_http_trusted; static gboolean opt_timestamp_check; static gboolean opt_disable_verify_bindings; -static char* opt_timestamp_check_from_rev; +static char *opt_timestamp_check_from_rev; static gboolean opt_bareuseronly_files; -static char** opt_subpaths; -static char** opt_http_headers; -static char* opt_cache_dir; -static char* opt_append_user_agent; +static gboolean opt_retry_all; +static char **opt_subpaths; +static char **opt_http_headers; +static char *opt_cache_dir; +static char *opt_append_user_agent; static int opt_depth = 0; static int opt_frequency = 0; static int opt_network_retries = -1; -static char* opt_url; -static char** opt_localcache_repos; +static int opt_low_speed_limit_bytes = -1; +static int opt_low_speed_time_seconds = -1; +static int opt_max_outstanding_fetcher_requests = -1; +static char *opt_url; +static char **opt_localcache_repos; /* ATTENTION: * Please remember to update the bash-completion script (bash/ostree) and * man page (man/ostree-pull.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Fetch only the commit metadata", NULL }, - { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, - { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, - { "per-object-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_per_object_fsync, "Perform writes in such a way that avoids stalling concurrent processes", NULL }, - { "disable-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_disable_static_deltas, "Do not use static deltas", NULL }, - { "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, "Require static deltas", NULL }, - { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Write refs suitable for a mirror and fetches all refs if none provided", NULL }, - { "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, "Only pull the provided subpath(s)", NULL }, - { "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, "Verify checksums of local sources (always enabled for HTTP pulls)", NULL }, - { "http-trusted", 0, 0, G_OPTION_ARG_NONE, &opt_http_trusted, "Do not verify checksums of HTTP sources (mostly useful when mirroring)", NULL }, - { "bareuseronly-files", 0, 0, G_OPTION_ARG_NONE, &opt_bareuseronly_files, "Reject regular files with mode outside of 0775 (world writable, suid, etc.)", NULL }, - { "dry-run", 0, 0, G_OPTION_ARG_NONE, &opt_dry_run, "Only print information on what will be downloaded (requires static deltas)", NULL }, - { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" }, - { "url", 0, 0, G_OPTION_ARG_STRING, &opt_url, "Pull objects from this URL instead of the one from the remote config", "URL" }, - { "http-header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_http_headers, "Add NAME=VALUE as HTTP header to all requests", "NAME=VALUE" }, - { "update-frequency", 0, 0, G_OPTION_ARG_INT, &opt_frequency, "Sets the update frequency, in milliseconds (0=1000ms) (default: 0)", "FREQUENCY" }, - { "network-retries", 0, 0, G_OPTION_ARG_INT, &opt_network_retries, "Specifies how many times each download should be retried upon error (default: 5)", "N"}, - { "localcache-repo", 'L', 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_localcache_repos, "Add REPO as local cache source for objects during this pull", "REPO" }, - { "timestamp-check", 'T', 0, G_OPTION_ARG_NONE, &opt_timestamp_check, "Require fetched commits to have newer timestamps", NULL }, - { "timestamp-check-from-rev", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp_check_from_rev, "Require fetched commits to have newer timestamps than given rev", NULL }, - { "disable-verify-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_disable_verify_bindings, "Do not verify commit bindings", NULL }, - /* let's leave this hidden for now; we just need it for tests */ - { "append-user-agent", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_append_user_agent, "Append string to user agent", NULL }, - { NULL } - }; +static GOptionEntry options[] + = { { "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, + "Fetch only the commit metadata", NULL }, + { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, + { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", + NULL }, + { "per-object-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_per_object_fsync, + "Perform writes in such a way that avoids stalling concurrent processes", NULL }, + { "disable-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_disable_static_deltas, + "Do not use static deltas", NULL }, + { "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, + "Require static deltas", NULL }, + { "disable-retry-on-network-errors", 0, 0, G_OPTION_ARG_NONE, &opt_retry_all, + "Do not retry when network issues happen, instead fail automatically. (Currently only " + "affects libcurl)", + NULL }, + { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, + "Write refs suitable for a mirror and fetches all refs if none provided", NULL }, + { "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, + "Only pull the provided subpath(s)", NULL }, + { "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, + "Verify checksums of local sources (always enabled for HTTP pulls)", NULL }, + { "http-trusted", 0, 0, G_OPTION_ARG_NONE, &opt_http_trusted, + "Do not verify checksums of HTTP sources (mostly useful when mirroring)", NULL }, + { "bareuseronly-files", 0, 0, G_OPTION_ARG_NONE, &opt_bareuseronly_files, + "Reject regular files with mode outside of 0775 (world writable, suid, etc.)", NULL }, + { "dry-run", 0, 0, G_OPTION_ARG_NONE, &opt_dry_run, + "Only print information on what will be downloaded (requires static deltas)", NULL }, + { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, + "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" }, + { "url", 0, 0, G_OPTION_ARG_STRING, &opt_url, + "Pull objects from this URL instead of the one from the remote config", "URL" }, + { "http-header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_http_headers, + "Add NAME=VALUE as HTTP header to all requests", "NAME=VALUE" }, + { "update-frequency", 0, 0, G_OPTION_ARG_INT, &opt_frequency, + "Sets the update frequency, in milliseconds (0=1000ms) (default: 0)", "FREQUENCY" }, + { "network-retries", 0, 0, G_OPTION_ARG_INT, &opt_network_retries, + "Specifies how many times each download should be retried upon error (default: 5)", "N" }, + { "low-speed-limit-bytes", 0, 0, G_OPTION_ARG_INT, &opt_low_speed_limit_bytes, + "The average transfer speed per second of a transfer during the time set via " + "'low-speed-time-seconds' for libcurl to abort(default: 1000)", + "N" }, + { "low-speed-time-seconds", 0, 0, G_OPTION_ARG_INT, &opt_low_speed_time_seconds, + "The time in number seconds that the transfer speed should be below the " + "'low-speed-limit-bytes' setting for libcurl to abort (default: 30)", + "N" }, + { "max-outstanding-fetcher-requests", 0, 0, G_OPTION_ARG_INT, + &opt_max_outstanding_fetcher_requests, + "The max amount of concurrent connections allowed. (default: 8)", "N" }, + { "localcache-repo", 'L', 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_localcache_repos, + "Add REPO as local cache source for objects during this pull", "REPO" }, + { "timestamp-check", 'T', 0, G_OPTION_ARG_NONE, &opt_timestamp_check, + "Require fetched commits to have newer timestamps", NULL }, + { "timestamp-check-from-rev", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp_check_from_rev, + "Require fetched commits to have newer timestamps than given rev", NULL }, + { "disable-verify-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_disable_verify_bindings, + "Do not verify commit bindings", NULL }, + /* let's leave this hidden for now; we just need it for tests */ + { "append-user-agent", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_append_user_agent, + "Append string to user agent", NULL }, + { NULL } }; #ifndef OSTREE_DISABLE_GPGME static void -gpg_verify_result_cb (OstreeRepo *repo, - const char *checksum, - OstreeGpgVerifyResult *result, +gpg_verify_result_cb (OstreeRepo *repo, const char *checksum, OstreeGpgVerifyResult *result, GLnxConsoleRef *console) { /* Temporarily place the tty back in normal mode before printing GPG @@ -103,8 +140,7 @@ gpg_verify_result_cb (OstreeRepo *repo, static gboolean printed_console_progress; static void -dry_run_console_progress_changed (OstreeAsyncProgress *progress, - gpointer user_data) +dry_run_console_progress_changed (OstreeAsyncProgress *progress, gpointer user_data) { guint fetched_delta_parts, total_delta_parts; guint fetched_delta_part_fallbacks, total_delta_part_fallbacks; @@ -113,17 +149,15 @@ dry_run_console_progress_changed (OstreeAsyncProgress *progress, g_assert (!printed_console_progress); printed_console_progress = TRUE; - ostree_async_progress_get (progress, - /* Number of parts */ - "fetched-delta-parts", "u", &fetched_delta_parts, - "total-delta-parts", "u", &total_delta_parts, - "fetched-delta-fallbacks", "u", &fetched_delta_part_fallbacks, - "total-delta-fallbacks", "u", &total_delta_part_fallbacks, - /* Size variables */ - "fetched-delta-part-size", "t", &fetched_delta_part_size, - "total-delta-part-size", "t", &total_delta_part_size, - "total-delta-part-usize", "t", &total_delta_part_usize, - NULL); + ostree_async_progress_get ( + progress, + /* Number of parts */ + "fetched-delta-parts", "u", &fetched_delta_parts, "total-delta-parts", "u", + &total_delta_parts, "fetched-delta-fallbacks", "u", &fetched_delta_part_fallbacks, + "total-delta-fallbacks", "u", &total_delta_part_fallbacks, + /* Size variables */ + "fetched-delta-part-size", "t", &fetched_delta_part_size, "total-delta-part-size", "t", + &total_delta_part_size, "total-delta-part-usize", "t", &total_delta_part_usize, NULL); /* Fold the count of deltaparts + fallbacks for simplicity; if changing this, * please change ostree_repo_pull_default_console_progress_changed() first. @@ -131,46 +165,44 @@ dry_run_console_progress_changed (OstreeAsyncProgress *progress, fetched_delta_parts += fetched_delta_part_fallbacks; total_delta_parts += total_delta_part_fallbacks; - g_autoptr(GString) buf = g_string_new (""); + g_autoptr (GString) buf = g_string_new (""); - { g_autofree char *formatted_fetched = - g_format_size (fetched_delta_part_size); - g_autofree char *formatted_size = - g_format_size (total_delta_part_size); - g_autofree char *formatted_usize = - g_format_size (total_delta_part_usize); + { + g_autofree char *formatted_fetched = g_format_size (fetched_delta_part_size); + g_autofree char *formatted_size = g_format_size (total_delta_part_size); + g_autofree char *formatted_usize = g_format_size (total_delta_part_usize); g_string_append_printf (buf, "Delta update: %u/%u parts, %s/%s, %s total uncompressed", - fetched_delta_parts, total_delta_parts, - formatted_fetched, formatted_size, - formatted_usize); + fetched_delta_parts, total_delta_parts, formatted_fetched, + formatted_size, formatted_usize); } g_print ("%s\n", buf->str); } static void -noninteractive_console_progress_changed (OstreeAsyncProgress *progress, - gpointer user_data) +noninteractive_console_progress_changed (OstreeAsyncProgress *progress, gpointer user_data) { /* We do nothing here - we just want the final status */ } gboolean -ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; gboolean ret = FALSE; g_autofree char *remote = NULL; OstreeRepoPullFlags pullflags = 0; - g_autoptr(GPtrArray) refs_to_fetch = NULL; - g_autoptr(GPtrArray) override_commit_ids = NULL; - g_autoptr(OstreeAsyncProgress) progress = NULL; + g_autoptr (GPtrArray) refs_to_fetch = NULL; + g_autoptr (GPtrArray) override_commit_ids = NULL; + g_autoptr (OstreeAsyncProgress) progress = NULL; gulong signal_handler_id = 0; context = g_option_context_new ("REMOTE [BRANCH...]"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) goto out; if (!ostree_ensure_repo_writable (repo, error)) @@ -271,8 +303,10 @@ ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, { GVariantBuilder builder; - g_autoptr(GVariant) pull_options = NULL; - g_auto(GLnxConsoleRef) console = { 0, }; + g_autoptr (GVariant) pull_options = NULL; + g_auto (GLnxConsoleRef) console = { + 0, + }; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); glnx_console_lock (&console); @@ -288,29 +322,52 @@ ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, g_variant_builder_add (&builder, "{s@v}", "subdir", g_variant_new_variant (g_variant_new_string (opt_subpaths[0]))); else - g_variant_builder_add (&builder, "{s@v}", "subdirs", - g_variant_new_variant (g_variant_new_strv ((const char *const*) opt_subpaths, -1))); + g_variant_builder_add ( + &builder, "{s@v}", "subdirs", + g_variant_new_variant (g_variant_new_strv ((const char *const *)opt_subpaths, -1))); } g_variant_builder_add (&builder, "{s@v}", "flags", g_variant_new_variant (g_variant_new_int32 (pullflags))); if (refs_to_fetch) g_variant_builder_add (&builder, "{s@v}", "refs", - g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch->pdata, -1))); + g_variant_new_variant (g_variant_new_strv ( + (const char *const *)refs_to_fetch->pdata, -1))); g_variant_builder_add (&builder, "{s@v}", "depth", g_variant_new_variant (g_variant_new_int32 (opt_depth))); - + g_variant_builder_add (&builder, "{s@v}", "update-frequency", g_variant_new_variant (g_variant_new_uint32 (opt_frequency))); - + if (opt_network_retries >= 0) g_variant_builder_add (&builder, "{s@v}", "n-network-retries", g_variant_new_variant (g_variant_new_uint32 (opt_network_retries))); - g_variant_builder_add (&builder, "{s@v}", "disable-static-deltas", - g_variant_new_variant (g_variant_new_boolean (opt_disable_static_deltas))); + if (opt_low_speed_limit_bytes >= 0) + g_variant_builder_add ( + &builder, "{s@v}", "low-speed-limit-bytes", + g_variant_new_variant (g_variant_new_uint32 (opt_low_speed_limit_bytes))); + + if (opt_low_speed_time_seconds >= 0) + g_variant_builder_add ( + &builder, "{s@v}", "low-speed-time-seconds", + g_variant_new_variant (g_variant_new_uint32 (opt_low_speed_time_seconds))); + + if (opt_max_outstanding_fetcher_requests >= 0) + g_variant_builder_add ( + &builder, "{s@v}", "max-outstanding-fetcher-requests", + g_variant_new_variant (g_variant_new_uint32 (opt_max_outstanding_fetcher_requests))); + + if (opt_retry_all) + g_variant_builder_add (&builder, "{s@v}", "retry-all-network-errors", + g_variant_new_variant (g_variant_new_boolean (FALSE))); + + g_variant_builder_add ( + &builder, "{s@v}", "disable-static-deltas", + g_variant_new_variant (g_variant_new_boolean (opt_disable_static_deltas))); - g_variant_builder_add (&builder, "{s@v}", "require-static-deltas", - g_variant_new_variant (g_variant_new_boolean (opt_require_static_deltas))); + g_variant_builder_add ( + &builder, "{s@v}", "require-static-deltas", + g_variant_new_variant (g_variant_new_boolean (opt_require_static_deltas))); g_variant_builder_add (&builder, "{s@v}", "dry-run", g_variant_new_variant (g_variant_new_boolean (opt_dry_run))); @@ -318,20 +375,25 @@ ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, g_variant_builder_add (&builder, "{s@v}", "timestamp-check", g_variant_new_variant (g_variant_new_boolean (opt_timestamp_check))); if (opt_timestamp_check_from_rev) - g_variant_builder_add (&builder, "{s@v}", "timestamp-check-from-rev", - g_variant_new_variant (g_variant_new_string (opt_timestamp_check_from_rev))); + g_variant_builder_add ( + &builder, "{s@v}", "timestamp-check-from-rev", + g_variant_new_variant (g_variant_new_string (opt_timestamp_check_from_rev))); if (override_commit_ids) - g_variant_builder_add (&builder, "{s@v}", "override-commit-ids", - g_variant_new_variant (g_variant_new_strv ((const char*const*)override_commit_ids->pdata, override_commit_ids->len))); + g_variant_builder_add ( + &builder, "{s@v}", "override-commit-ids", + g_variant_new_variant (g_variant_new_strv ( + (const char *const *)override_commit_ids->pdata, override_commit_ids->len))); if (opt_localcache_repos) g_variant_builder_add (&builder, "{s@v}", "localcache-repos", - g_variant_new_variant (g_variant_new_strv ((const char*const*)opt_localcache_repos, -1))); + g_variant_new_variant (g_variant_new_strv ( + (const char *const *)opt_localcache_repos, -1))); if (opt_per_object_fsync) g_variant_builder_add (&builder, "{s@v}", "per-object-fsync", g_variant_new_variant (g_variant_new_boolean (TRUE))); - g_variant_builder_add (&builder, "{s@v}", "disable-verify-bindings", - g_variant_new_variant (g_variant_new_boolean (opt_disable_verify_bindings))); + g_variant_builder_add ( + &builder, "{s@v}", "disable-verify-bindings", + g_variant_new_variant (g_variant_new_boolean (opt_disable_verify_bindings))); if (opt_http_headers) { GVariantBuilder hdr_builder; @@ -344,8 +406,7 @@ ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, g_autofree char *key = NULL; if (!eq) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Missing '=' in --http-header"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Missing '=' in --http-header"); goto out; } key = g_strndup (kv, eq - kv); @@ -362,9 +423,11 @@ ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, if (!opt_dry_run) { if (console.is_tty) - progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect ( + ostree_repo_pull_default_console_progress_changed, &console); else - progress = ostree_async_progress_new_and_connect (noninteractive_console_progress_changed, &console); + progress = ostree_async_progress_new_and_connect (noninteractive_console_progress_changed, + &console); } else { @@ -375,21 +438,19 @@ ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, { #ifndef OSTREE_DISABLE_GPGME signal_handler_id = g_signal_connect (repo, "gpg-verify-result", - G_CALLBACK (gpg_verify_result_cb), - &console); + G_CALLBACK (gpg_verify_result_cb), &console); #endif /* OSTREE_DISABLE_GPGME */ } pull_options = g_variant_ref_sink (g_variant_builder_end (&builder)); - if (!ostree_repo_pull_with_options (repo, remote, pull_options, - progress, cancellable, error)) + if (!ostree_repo_pull_with_options (repo, remote, pull_options, progress, cancellable, error)) goto out; if (!console.is_tty && !opt_dry_run) { g_assert (progress); - const char *status = ostree_async_progress_get_status (progress); + g_autofree char *status = ostree_async_progress_get_status (progress); if (status) g_print ("%s\n", status); } @@ -401,7 +462,7 @@ ostree_builtin_pull (int argc, char **argv, OstreeCommandInvocation *invocation, } ret = TRUE; - out: +out: if (signal_handler_id > 0) g_signal_handler_disconnect (repo, signal_handler_id); return ret; diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index c687a5f..ec345b5 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -21,12 +21,13 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" static gboolean opt_delete; static gboolean opt_list; +static gboolean opt_revision; static gboolean opt_alias; static char *opt_create; static gboolean opt_collections; @@ -38,39 +39,60 @@ static gboolean opt_force; */ static GOptionEntry options[] = { - { "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Delete refs which match PREFIX, rather than listing them", NULL }, + { "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, + "Delete refs which match PREFIX, rather than listing them", NULL }, { "list", 0, 0, G_OPTION_ARG_NONE, &opt_list, "Do not remove the prefix from the refs", NULL }, - { "alias", 'A', 0, G_OPTION_ARG_NONE, &opt_alias, "If used with --create, create an alias, otherwise just list aliases", NULL }, - { "create", 0, 0, G_OPTION_ARG_STRING, &opt_create, "Create a new ref for an existing commit", "NEWREF" }, - { "collections", 'c', 0, G_OPTION_ARG_NONE, &opt_collections, "Enable listing collection IDs for refs", NULL }, + { "revision", 'r', 0, G_OPTION_ARG_NONE, &opt_revision, "Show revisions in listing", NULL }, + { "alias", 'A', 0, G_OPTION_ARG_NONE, &opt_alias, + "If used with --create, create an alias, otherwise just list aliases", NULL }, + { "create", 0, 0, G_OPTION_ARG_STRING, &opt_create, "Create a new ref for an existing commit", + "NEWREF" }, + { "collections", 'c', 0, G_OPTION_ARG_NONE, &opt_collections, + "Enable listing collection IDs for refs", NULL }, { "force", 0, 0, G_OPTION_ARG_NONE, &opt_force, "Overwrite existing refs when creating", NULL }, { NULL } }; +static int +collection_ref_cmp (OstreeCollectionRef *a, OstreeCollectionRef *b) +{ + int ret = g_strcmp0 (a->collection_id, b->collection_id); + if (ret == 0) + ret = g_strcmp0 (a->ref_name, b->ref_name); + return ret; +} + static gboolean -do_ref_with_collections (OstreeRepo *repo, - const char *refspec_prefix, - GCancellable *cancellable, - GError **error) +do_ref_with_collections (OstreeRepo *repo, const char *refspec_prefix, GCancellable *cancellable, + GError **error) { - g_autoptr(GHashTable) refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr (GHashTable) refs = NULL; /* (element-type OstreeCollectionRef utf8) */ GHashTableIter hashiter; gpointer hashkey, hashvalue; gboolean ret = FALSE; - if (!ostree_repo_list_collection_refs (repo, - (!opt_create) ? refspec_prefix : NULL, - &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, - cancellable, error)) + if (!ostree_repo_list_collection_refs (repo, (!opt_create) ? refspec_prefix : NULL, &refs, + OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error)) goto out; if (!opt_delete && !opt_create) { - g_hash_table_iter_init (&hashiter, refs); - while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)) + g_autoptr (GList) ordered_keys = g_hash_table_get_keys (refs); + ordered_keys = g_list_sort (ordered_keys, (GCompareFunc)collection_ref_cmp); + + for (GList *iter = ordered_keys; iter != NULL; iter = iter->next) { - const OstreeCollectionRef *ref = hashkey; - g_print ("(%s, %s)\n", ref->collection_id, ref->ref_name); + OstreeCollectionRef *ref = iter->data; + + if (opt_revision) + { + const char *rev = g_hash_table_lookup (refs, ref); + g_print ("(%s, %s)\t%s\n", ref->collection_id, ref->ref_name, rev); + } + else + { + g_print ("(%s, %s)\n", ref->collection_id, ref->ref_name); + } } } else if (opt_create) @@ -78,7 +100,8 @@ do_ref_with_collections (OstreeRepo *repo, g_autofree char *checksum = NULL; g_autofree char *checksum_existing = NULL; - if (!ostree_repo_resolve_rev_ext (repo, opt_create, TRUE, OSTREE_REPO_RESOLVE_REV_EXT_NONE, &checksum_existing, error)) + if (!ostree_repo_resolve_rev_ext (repo, opt_create, TRUE, OSTREE_REPO_RESOLVE_REV_EXT_NONE, + &checksum_existing, error)) { if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) { @@ -86,7 +109,8 @@ do_ref_with_collections (OstreeRepo *repo, * which is handled by _ostree_repo_write_ref */ g_clear_error (error); } - else goto out; + else + goto out; } if (!opt_force && checksum_existing != NULL) @@ -101,7 +125,7 @@ do_ref_with_collections (OstreeRepo *repo, /* This is technically an abuse of the refspec syntax: collection IDs * should not be treated like remote names. */ - g_auto(GStrv) parts = g_strsplit (opt_create, ":", 2); + g_auto (GStrv) parts = g_strsplit (opt_create, ":", 2); const char *collection_id = parts[0]; const char *ref_name = parts[1]; if (!ostree_validate_collection_id (collection_id, error)) @@ -109,9 +133,8 @@ do_ref_with_collections (OstreeRepo *repo, if (!ostree_validate_rev (ref_name, error)) goto out; - const OstreeCollectionRef ref = { (gchar *) collection_id, (gchar *) ref_name }; - if (!ostree_repo_set_collection_ref_immediate (repo, &ref, checksum, - cancellable, error)) + const OstreeCollectionRef ref = { (gchar *)collection_id, (gchar *)ref_name }; + if (!ostree_repo_set_collection_ref_immediate (repo, &ref, checksum, cancellable, error)) goto out; } else @@ -122,20 +145,20 @@ do_ref_with_collections (OstreeRepo *repo, { const OstreeCollectionRef *ref = hashkey; - if (!ostree_repo_set_collection_ref_immediate (repo, ref, NULL, - cancellable, error)) + if (!ostree_repo_set_collection_ref_immediate (repo, ref, NULL, cancellable, error)) goto out; } } ret = TRUE; - out: +out: return ret; } -static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellable *cancellable, GError **error) +static gboolean +do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellable *cancellable, GError **error) { - g_autoptr(GHashTable) refs = NULL; - g_autoptr(GHashTable) ref_aliases = NULL; + g_autoptr (GHashTable) refs = NULL; + g_autoptr (GHashTable) ref_aliases = NULL; GHashTableIter hashiter; gpointer hashkey, hashvalue; gboolean ret = FALSE; @@ -151,8 +174,7 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab */ if (opt_alias || opt_delete) { - if (!ostree_repo_list_refs_ext (repo, NULL, &ref_aliases, - OSTREE_REPO_LIST_REFS_EXT_ALIASES, + if (!ostree_repo_list_refs_ext (repo, NULL, &ref_aliases, OSTREE_REPO_LIST_REFS_EXT_ALIASES, cancellable, error)) goto out; } @@ -164,8 +186,7 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab OstreeRepoListRefsExtFlags flags = OSTREE_REPO_LIST_REFS_EXT_NONE; if (opt_alias) flags |= OSTREE_REPO_LIST_REFS_EXT_ALIASES; - if (!ostree_repo_list_refs_ext (repo, refspec_prefix, &refs, flags, - cancellable, error)) + if (!ostree_repo_list_refs_ext (repo, refspec_prefix, &refs, flags, cancellable, error)) goto out; } else if (opt_create) @@ -179,12 +200,27 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab if (is_list) { - GLNX_HASH_TABLE_FOREACH_KV (refs, const char *, ref, const char *, value) + g_autoptr (GList) ordered_keys = g_hash_table_get_keys (refs); + ordered_keys = g_list_sort (ordered_keys, (GCompareFunc)g_strcmp0); + + for (GList *iter = ordered_keys; iter != NULL; iter = iter->next) { + const char *ref = iter->data; + if (opt_alias) - g_print ("%s -> %s\n", ref, value); + { + const char *alias = g_hash_table_lookup (refs, ref); + g_print ("%s -> %s\n", ref, alias); + } + else if (opt_revision) + { + const char *rev = g_hash_table_lookup (refs, ref); + g_print ("%s\t%s\n", ref, rev); + } else - g_print ("%s\n", ref); + { + g_print ("%s\n", ref); + } } } else if (opt_create) @@ -194,7 +230,8 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab g_autofree char *remote = NULL; g_autofree char *ref = NULL; - if (!ostree_repo_resolve_rev_ext (repo, opt_create, TRUE, OSTREE_REPO_RESOLVE_REV_EXT_NONE, &checksum_existing, error)) + if (!ostree_repo_resolve_rev_ext (repo, opt_create, TRUE, OSTREE_REPO_RESOLVE_REV_EXT_NONE, + &checksum_existing, error)) { if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) { @@ -202,7 +239,8 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab * which is handled by _ostree_repo_write_ref */ g_clear_error (error); } - else goto out; + else + goto out; } /* We want to allow replacing an existing alias or a normal ref when @@ -226,8 +264,8 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab if (!g_hash_table_contains (refs, refspec_prefix)) return glnx_throw (error, "Cannot create alias to non-existent ref: %s", refspec_prefix); - if (!ostree_repo_set_alias_ref_immediate (repo, remote, ref, refspec_prefix, - cancellable, error)) + if (!ostree_repo_set_alias_ref_immediate (repo, remote, ref, refspec_prefix, cancellable, + error)) goto out; } else @@ -235,8 +273,7 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error)) goto out; - if (!ostree_repo_set_ref_immediate (repo, remote, ref, checksum, - cancellable, error)) + if (!ostree_repo_set_ref_immediate (repo, remote, ref, checksum, cancellable, error)) goto out; } } @@ -254,8 +291,7 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab goto out; /* Look for alias if it exists for a ref we want to delete */ - GLNX_HASH_TABLE_FOREACH_KV (ref_aliases, const char *, - ref_alias, const char *, value) + GLNX_HASH_TABLE_FOREACH_KV (ref_aliases, const char *, ref_alias, const char *, value) { if (!strcmp (ref, value)) { @@ -264,27 +300,28 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab goto out; } } - if (!ostree_repo_set_ref_immediate (repo, remote, ref, NULL, - cancellable, error)) + if (!ostree_repo_set_ref_immediate (repo, remote, ref, NULL, cancellable, error)) goto out; } } ret = TRUE; - out: +out: return ret; } gboolean -ostree_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; int i; context = g_option_context_new ("[PREFIX]"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) goto out; if (argc >= 2) @@ -320,7 +357,7 @@ ostree_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocation, } ret = TRUE; - out: +out: if (repo) ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; diff --git a/src/ostree/ot-builtin-remote.c b/src/ostree/ot-builtin-remote.c index 0e14bb1..f50e09b 100644 --- a/src/ostree/ot-builtin-remote.c +++ b/src/ostree/ot-builtin-remote.c @@ -21,48 +21,31 @@ #include "config.h" -#include "ot-main.h" #include "ot-builtins.h" +#include "ot-main.h" #include "ot-remote-builtins.h" static OstreeCommand remote_subcommands[] = { - { "add", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_remote_builtin_add, - "Add a remote repository" }, - { "delete", OSTREE_BUILTIN_FLAG_NO_REPO, - ot_remote_builtin_delete, - "Delete a remote repository" }, - { "show-url", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_show_url, + { "add", OSTREE_BUILTIN_FLAG_NO_REPO, ot_remote_builtin_add, "Add a remote repository" }, + { "delete", OSTREE_BUILTIN_FLAG_NO_REPO, ot_remote_builtin_delete, "Delete a remote repository" }, + { "show-url", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_show_url, "Show remote repository URL" }, - { "list", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_list, - "List remote repository names" }, + { "list", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_list, "List remote repository names" }, #ifndef OSTREE_DISABLE_GPGME - { "gpg-import", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_gpg_import, - "Import GPG keys" }, - { "gpg-list-keys", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_list_gpg_keys, + { "gpg-import", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_gpg_import, "Import GPG keys" }, + { "gpg-list-keys", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_list_gpg_keys, "Show remote GPG keys" }, #endif /* OSTREE_DISABLE_GPGME */ #ifdef HAVE_LIBCURL_OR_LIBSOUP - { "add-cookie", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_add_cookie, + { "add-cookie", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_add_cookie, "Add a cookie to remote" }, - { "delete-cookie", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_delete_cookie, + { "delete-cookie", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_delete_cookie, "Remove one cookie from remote" }, - { "list-cookies", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_list_cookies, + { "list-cookies", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_list_cookies, "Show remote repository cookies" }, #endif - { "refs", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_refs, - "List remote refs" }, - { "summary", OSTREE_BUILTIN_FLAG_NONE, - ot_remote_builtin_summary, - "Show remote summary" }, + { "refs", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_refs, "List remote refs" }, + { "summary", OSTREE_BUILTIN_FLAG_NONE, ot_remote_builtin_summary, "Show remote summary" }, { NULL, 0, NULL, NULL } }; @@ -72,7 +55,7 @@ remote_option_context_new_with_commands (void) OstreeCommand *subcommand = remote_subcommands; GOptionContext *context = g_option_context_new ("COMMAND"); - g_autoptr(GString) summary = g_string_new ("Builtin \"remote\" Commands:"); + g_autoptr (GString) summary = g_string_new ("Builtin \"remote\" Commands:"); while (subcommand->name != NULL) { @@ -91,10 +74,11 @@ remote_option_context_new_with_commands (void) } gboolean -ostree_builtin_remote (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_remote (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { const char *subcommand_name = NULL; - int in,out; + int in, out; for (in = 1, out = 1; in < argc; in++, out++) { /* The non-option is the command, take it out of the arguments */ @@ -128,14 +112,13 @@ ostree_builtin_remote (int argc, char **argv, OstreeCommandInvocation *invocatio if (!subcommand->name) { - g_autoptr(GOptionContext) context = NULL; + g_autoptr (GOptionContext) context = NULL; g_autofree char *help = NULL; context = remote_option_context_new_with_commands (); /* This will not return for some options (e.g. --version). */ - if (ostree_option_context_parse (context, NULL, &argc, &argv, - invocation, NULL, cancellable, + if (ostree_option_context_parse (context, NULL, &argc, &argv, invocation, NULL, cancellable, error)) { if (subcommand_name == NULL) diff --git a/src/ostree/ot-builtin-reset.c b/src/ostree/ot-builtin-reset.c index 591eed1..86c5d9c 100644 --- a/src/ostree/ot-builtin-reset.c +++ b/src/ostree/ot-builtin-reset.c @@ -21,9 +21,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" /* ATTENTION: @@ -31,20 +31,15 @@ * man page (man/ostree-reset.xml) when changing the option list. */ -static GOptionEntry options[] = { - { NULL } -}; +static GOptionEntry options[] = { { NULL } }; gboolean -ostree_builtin_reset (int argc, - char **argv, - OstreeCommandInvocation *invocation, - GCancellable *cancellable, - GError **error) +ostree_builtin_reset (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GHashTable) known_refs = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GHashTable) known_refs = NULL; gboolean ret = FALSE; const char *ref; const char *target = NULL; @@ -53,7 +48,8 @@ ostree_builtin_reset (int argc, /* FIXME: Add support for collection–refs. */ context = g_option_context_new ("REF COMMIT"); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) goto out; if (!ostree_ensure_repo_writable (repo, error)) @@ -88,7 +84,7 @@ ostree_builtin_reset (int argc, goto out; ret = TRUE; - out: +out: if (repo) ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; diff --git a/src/ostree/ot-builtin-rev-parse.c b/src/ostree/ot-builtin-rev-parse.c index c4a7ec9..e94012d 100644 --- a/src/ostree/ot-builtin-rev-parse.c +++ b/src/ostree/ot-builtin-rev-parse.c @@ -21,51 +21,80 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" #include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" #include "otutil.h" +#include /* ATTENTION: * Please remember to update the bash-completion script (bash/ostree) and * man page (man/ostree-rev-parse.xml) when changing the option list. */ -static GOptionEntry options[] = { - { NULL } -}; +static gboolean opt_single; + +static GOptionEntry options[] = { { "single", 'S', 0, G_OPTION_ARG_NONE, &opt_single, + "If the repository has exactly one commit, then print it; any " + "other case will result in an error", + NULL }, + { NULL } }; gboolean -ostree_builtin_rev_parse (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_rev_parse (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - gboolean ret = FALSE; - const char *rev = "master"; - int i; - g_autofree char *resolved_rev = NULL; + g_autoptr (GOptionContext) context = g_option_context_new ("REV"); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) + return FALSE; + + if (opt_single) + { + if (argc >= 2) + { + ot_util_usage_error (context, "Cannot specify arguments with --single", error); + return FALSE; + } + + g_autoptr (GHashTable) objects = NULL; + if (!ostree_repo_list_commit_objects_starting_with (repo, "", &objects, cancellable, error)) + return FALSE; + + GVariant *found = NULL; + GLNX_HASH_TABLE_FOREACH (objects, GVariant *, key) + { + if (found) + return glnx_throw (error, "Multiple commit objects found"); + found = key; + } + if (!found) + return glnx_throw (error, "No commit objects found"); + const char *checksum; + OstreeObjectType objtype; + ostree_object_name_deserialize (found, &checksum, &objtype); + g_assert (objtype == OSTREE_OBJECT_TYPE_COMMIT); - context = g_option_context_new ("REV"); + g_print ("%s\n", checksum); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) - goto out; + return TRUE; /* Note early return */ + } if (argc < 2) { ot_util_usage_error (context, "REV must be specified", error); - goto out; + return FALSE; } - for (i = 1; i < argc; i++) + + for (gint i = 1; i < argc; i++) { - rev = argv[i]; - g_free (resolved_rev); - resolved_rev = NULL; + const char *rev = argv[i]; + g_autofree char *resolved_rev = NULL; if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) - goto out; + return FALSE; g_print ("%s\n", resolved_rev); } - - ret = TRUE; - out: - return ret; + + return TRUE; } diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c index 55f2b47..c1fc0fe 100644 --- a/src/ostree/ot-builtin-show.c +++ b/src/ostree/ot-builtin-show.c @@ -21,18 +21,21 @@ #include "config.h" -#include "ot-main.h" +#include "ostree.h" #include "ot-builtins.h" #include "ot-dump.h" -#include "ostree.h" +#include "ot-main.h" #include "otutil.h" static gboolean opt_print_related; -static char* opt_print_variant_type; -static char* opt_print_metadata_key; -static char* opt_print_detached_metadata_key; +static char *opt_print_variant_type; +static char *opt_print_metadata_key; +static char *opt_print_detached_metadata_key; +static gboolean opt_list_metadata_keys; +static gboolean opt_list_detached_metadata_keys; static gboolean opt_print_sizes; static gboolean opt_raw; +static gboolean opt_print_hex; static gboolean opt_no_byteswap; static char *opt_gpg_homedir; static char *opt_gpg_verify_remote; @@ -42,25 +45,43 @@ static char *opt_gpg_verify_remote; * man page (man/ostree-show.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "print-related", 0, 0, G_OPTION_ARG_NONE, &opt_print_related, "Show the \"related\" commits", NULL }, - { "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &opt_print_variant_type, "Memory map OBJECT (in this case a filename) to the GVariant type string", "TYPE" }, - { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" }, - { "print-detached-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_detached_metadata_key, "Print string value of detached metadata key", "KEY" }, - { "print-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_print_sizes, "Show the commit size metadata", NULL }, - { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" }, - { "no-byteswap", 'B', 0, G_OPTION_ARG_NONE, &opt_no_byteswap, "Do not automatically convert variant data from big endian" }, - { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"}, - { "gpg-verify-remote", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_verify_remote, "Use REMOTE name for GPG configuration", "REMOTE"}, - { NULL } -}; +static GOptionEntry options[] + = { { "print-related", 0, 0, G_OPTION_ARG_NONE, &opt_print_related, + "Show the \"related\" commits", NULL }, + { "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &opt_print_variant_type, + "Memory map OBJECT (in this case a filename) to the GVariant type string", "TYPE" }, + { "list-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_metadata_keys, + "List the available metadata keys", NULL }, + { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, + "Print string value of metadata key", "KEY" }, + { + "print-hex", + 0, + 0, + G_OPTION_ARG_NONE, + &opt_print_hex, + "For byte array valued keys, output an unquoted hexadecimal string", + NULL, + }, + { "list-detached-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_detached_metadata_keys, + "List the available detached metadata keys", NULL }, + { "print-detached-metadata-key", 0, 0, G_OPTION_ARG_STRING, + &opt_print_detached_metadata_key, "Print string value of detached metadata key", "KEY" }, + { "print-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_print_sizes, "Show the commit size metadata", + NULL }, + { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" }, + { "no-byteswap", 'B', 0, G_OPTION_ARG_NONE, &opt_no_byteswap, + "Do not automatically convert variant data from big endian" }, + { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, + "GPG Homedir to use when looking for keyrings", "HOMEDIR" }, + { "gpg-verify-remote", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_verify_remote, + "Use REMOTE name for GPG configuration", "REMOTE" }, + { NULL } }; static gboolean -do_print_variant_generic (const GVariantType *type, - const char *filename, - GError **error) +do_print_variant_generic (const GVariantType *type, const char *filename, GError **error) { - g_autoptr(GVariant) variant = NULL; + g_autoptr (GVariant) variant = NULL; glnx_autofd int fd = -1; if (!glnx_openat_rdonly (AT_FDCWD, filename, TRUE, &fd, error)) @@ -73,22 +94,18 @@ do_print_variant_generic (const GVariantType *type, } static gboolean -do_print_related (OstreeRepo *repo, - const char *rev, - const char *resolved_rev, - GError **error) +do_print_related (OstreeRepo *repo, const char *rev, const char *resolved_rev, GError **error) { - g_autoptr(GVariant) variant = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, - resolved_rev, &variant, error)) + g_autoptr (GVariant) variant = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, resolved_rev, &variant, error)) return FALSE; /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */ - g_autoptr(GVariant) related = g_variant_get_child_value (variant, 2); - g_autoptr(GVariantIter) viter = g_variant_iter_new (related); + g_autoptr (GVariant) related = g_variant_get_child_value (variant, 2); + g_autoptr (GVariantIter) viter = g_variant_iter_new (related); const char *name; - GVariant* csum_v; + GVariant *csum_v; while (g_variant_iter_loop (viter, "(&s@ay)", &name, &csum_v)) { g_autofree char *checksum = ostree_checksum_from_bytes_v (csum_v); @@ -98,27 +115,24 @@ do_print_related (OstreeRepo *repo, } static gboolean -do_print_metadata_key (OstreeRepo *repo, - const char *resolved_rev, - gboolean detached, - const char *key, - GError **error) +get_metadata (OstreeRepo *repo, const char *resolved_rev, gboolean detached, + GVariant **out_metadata, GError **error) { - g_autoptr(GVariant) commit = NULL; - g_autoptr(GVariant) metadata = NULL; + g_assert (out_metadata != NULL); + + g_autoptr (GVariant) commit = NULL; + g_autoptr (GVariant) metadata = NULL; if (!detached) { - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, - resolved_rev, &commit, error)) + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, resolved_rev, &commit, error)) return FALSE; /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */ metadata = g_variant_get_child_value (commit, 0); } else { - if (!ostree_repo_read_commit_detached_metadata (repo, resolved_rev, &metadata, - NULL, error)) + if (!ostree_repo_read_commit_detached_metadata (repo, resolved_rev, &metadata, NULL, error)) return FALSE; if (metadata == NULL) { @@ -128,14 +142,68 @@ do_print_metadata_key (OstreeRepo *repo, } } - g_autoptr(GVariant) value = g_variant_lookup_value (metadata, key, NULL); + *out_metadata = g_steal_pointer (&metadata); + + return TRUE; +} + +static gint +strptr_cmp (gconstpointer a, gconstpointer b) +{ + const char *a_str = *((const char **)a); + const char *b_str = *((const char **)b); + + return g_strcmp0 (a_str, b_str); +} + +static gboolean +do_list_metadata_keys (OstreeRepo *repo, const char *resolved_rev, gboolean detached, + GError **error) +{ + g_autoptr (GVariant) metadata = NULL; + if (!get_metadata (repo, resolved_rev, detached, &metadata, error)) + return FALSE; + + GVariantIter iter; + const char *key = NULL; + g_autoptr (GPtrArray) keys = g_ptr_array_new (); + g_variant_iter_init (&iter, metadata); + while (g_variant_iter_loop (&iter, "{&s@v}", &key, NULL)) + g_ptr_array_add (keys, (gpointer)key); + + g_ptr_array_sort (keys, strptr_cmp); + for (guint i = 0; i < keys->len; i++) + { + key = keys->pdata[i]; + g_print ("%s\n", key); + } + + return TRUE; +} + +static gboolean +do_print_metadata_key (OstreeRepo *repo, const char *resolved_rev, gboolean detached, + const char *key, GError **error) +{ + g_autoptr (GVariant) metadata = NULL; + if (!get_metadata (repo, resolved_rev, detached, &metadata, error)) + return FALSE; + + g_autoptr (GVariant) value = g_variant_lookup_value (metadata, key, NULL); if (!value) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "No such metadata key '%s'", key); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No such metadata key '%s'", key); return FALSE; } + if (opt_print_hex && g_variant_is_of_type (value, (GVariantType *)"ay")) + { + g_autofree char *buf = g_malloc (g_variant_get_size (value) * 2 + 1); + ot_bin2hex (buf, g_variant_get_data (value), g_variant_get_size (value)); + g_print ("%s\n", buf); + return TRUE; + } + if (opt_no_byteswap) { g_autofree char *formatted = g_variant_print (value, TRUE); @@ -147,19 +215,16 @@ do_print_metadata_key (OstreeRepo *repo, } static gboolean -do_print_sizes (OstreeRepo *repo, - const char *rev, - GError **error) +do_print_sizes (OstreeRepo *repo, const char *rev, GError **error) { - g_autoptr(GVariant) commit = NULL; - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, - &commit, error)) + g_autoptr (GVariant) commit = NULL; + if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &commit, error)) { g_prefix_error (error, "Failed to read commit: "); return FALSE; } - g_autoptr(GPtrArray) sizes = NULL; + g_autoptr (GPtrArray) sizes = NULL; if (!ostree_commit_get_object_sizes (commit, &sizes, error)) return FALSE; @@ -178,8 +243,7 @@ do_print_sizes (OstreeRepo *repo, objects++; gboolean exists; - if (!ostree_repo_has_object (repo, entry->objtype, entry->checksum, - &exists, NULL, error)) + if (!ostree_repo_has_object (repo, entry->objtype, entry->checksum, &exists, NULL, error)) return FALSE; if (!exists) @@ -198,24 +262,18 @@ do_print_sizes (OstreeRepo *repo, g_print ("Compressed size (needed/total): %s/%s\n" "Unpacked size (needed/total): %s/%s\n" "Number of objects (needed/total): %" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT "\n", - new_archived_str, archived_str, - new_unpacked_str, unpacked_str, - new_objects, objects); + new_archived_str, archived_str, new_unpacked_str, unpacked_str, new_objects, objects); return TRUE; } static gboolean -print_object (OstreeRepo *repo, - OstreeObjectType objtype, - const char *checksum, - GError **error) +print_object (OstreeRepo *repo, OstreeObjectType objtype, const char *checksum, GError **error) { OstreeDumpFlags flags = OSTREE_DUMP_NONE; - g_autoptr(GVariant) variant = NULL; - if (!ostree_repo_load_variant (repo, objtype, checksum, - &variant, error)) + g_autoptr (GVariant) variant = NULL; + if (!ostree_repo_load_variant (repo, objtype, checksum, &variant, error)) return FALSE; if (opt_raw) flags |= OSTREE_DUMP_RAW; @@ -226,9 +284,10 @@ print_object (OstreeRepo *repo, #ifndef OSTREE_DISABLE_GPGME if (objtype == OSTREE_OBJECT_TYPE_COMMIT) { - g_autoptr(OstreeGpgVerifyResult) result = NULL; - g_autoptr(GError) local_error = NULL; - g_autoptr(GFile) gpg_homedir = opt_gpg_homedir ? g_file_new_for_path (opt_gpg_homedir) : NULL; + g_autoptr (OstreeGpgVerifyResult) result = NULL; + g_autoptr (GError) local_error = NULL; + g_autoptr (GFile) gpg_homedir + = opt_gpg_homedir ? g_file_new_for_path (opt_gpg_homedir) : NULL; if (opt_gpg_verify_remote) { @@ -237,8 +296,7 @@ print_object (OstreeRepo *repo, } else { - result = ostree_repo_verify_commit_ext (repo, checksum, - gpg_homedir, NULL, NULL, + result = ostree_repo_verify_commit_ext (repo, checksum, gpg_homedir, NULL, NULL, &local_error); } @@ -256,7 +314,7 @@ print_object (OstreeRepo *repo, guint n_sigs = ostree_gpg_verify_result_count_all (result); g_print ("Found %u signature%s:\n", n_sigs, n_sigs == 1 ? "" : "s"); - g_autoptr(GString) buffer = g_string_sized_new (256); + g_autoptr (GString) buffer = g_string_sized_new (256); for (guint ii = 0; ii < n_sigs; ii++) { g_string_append_c (buffer, '\n'); @@ -273,20 +331,15 @@ print_object (OstreeRepo *repo, } static gboolean -print_if_found (OstreeRepo *repo, - OstreeObjectType objtype, - const char *checksum, - gboolean *inout_was_found, - GCancellable *cancellable, - GError **error) +print_if_found (OstreeRepo *repo, OstreeObjectType objtype, const char *checksum, + gboolean *inout_was_found, GCancellable *cancellable, GError **error) { gboolean have_object = FALSE; if (*inout_was_found) return TRUE; - if (!ostree_repo_has_object (repo, objtype, checksum, &have_object, - cancellable, error)) + if (!ostree_repo_has_object (repo, objtype, checksum, &have_object, cancellable, error)) return FALSE; if (have_object) { @@ -299,12 +352,14 @@ print_if_found (OstreeRepo *repo, } gboolean -ostree_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("OBJECT"); + g_autoptr (GOptionContext) context = g_option_context_new ("OBJECT"); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; if (argc <= 1) @@ -321,10 +376,16 @@ ostree_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation, const char *key = detached ? opt_print_detached_metadata_key : opt_print_metadata_key; if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) return FALSE; - if (!do_print_metadata_key (repo, resolved_rev, detached, key, error)) return FALSE; } + else if (opt_list_metadata_keys || opt_list_detached_metadata_keys) + { + if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) + return FALSE; + if (!do_list_metadata_keys (repo, resolved_rev, opt_list_detached_metadata_keys, error)) + return FALSE; + } else if (opt_print_related) { if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) @@ -358,25 +419,22 @@ ostree_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation, } else { - if (!print_if_found (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, - &found, cancellable, error)) + if (!print_if_found (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &found, cancellable, error)) return FALSE; - if (!print_if_found (repo, OSTREE_OBJECT_TYPE_DIR_META, rev, - &found, cancellable, error)) + if (!print_if_found (repo, OSTREE_OBJECT_TYPE_DIR_META, rev, &found, cancellable, error)) return FALSE; - if (!print_if_found (repo, OSTREE_OBJECT_TYPE_DIR_TREE, rev, - &found, cancellable, error)) + if (!print_if_found (repo, OSTREE_OBJECT_TYPE_DIR_TREE, rev, &found, cancellable, error)) return FALSE; if (!found) { - g_autoptr(GFileInfo) finfo = NULL; - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GFileInfo) finfo = NULL; + g_autoptr (GVariant) xattrs = NULL; - if (!ostree_repo_load_file (repo, rev, NULL, &finfo, &xattrs, - cancellable, error)) + if (!ostree_repo_load_file (repo, rev, NULL, &finfo, &xattrs, cancellable, error)) return FALSE; - g_print ("Object: %s\nType: %s\n", rev, ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE)); + g_print ("Object: %s\nType: %s\n", rev, + ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE)); GFileType filetype = g_file_info_get_file_type (finfo); g_print ("File Type: "); switch (filetype) diff --git a/src/ostree/ot-builtin-sign.c b/src/ostree/ot-builtin-sign.c index f4e5c0e..f51fc51 100644 --- a/src/ostree/ot-builtin-sign.c +++ b/src/ostree/ot-builtin-sign.c @@ -24,12 +24,12 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" -#include "ostree.h" -#include "otutil.h" #include "ostree-core-private.h" #include "ostree-sign.h" +#include "ostree.h" +#include "ot-builtins.h" +#include "ot-main.h" +#include "otutil.h" static gboolean opt_delete; static gboolean opt_verify; @@ -42,16 +42,19 @@ static char *opt_keysdir; * man page (man/ostree-sign.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, "Delete signatures having any of the KEY-IDs", NULL}, - { "verify", 0, 0, G_OPTION_ARG_NONE, &opt_verify, "Verify signatures", NULL}, - { "sign-type", 's', 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"}, -#if defined(HAVE_LIBSODIUM) - { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_filename, "Read key(s) from file", "NAME"}, - { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, "Redefine system-wide directories with public and revoked keys for verification", "NAME"}, +static GOptionEntry options[] + = { { "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, + "Delete signatures having any of the KEY-IDs", NULL }, + { "verify", 0, 0, G_OPTION_ARG_NONE, &opt_verify, "Verify signatures", NULL }, + { "sign-type", 's', 0, G_OPTION_ARG_STRING, &opt_sign_name, + "Signature type to use (defaults to 'ed25519')", "NAME" }, +#if defined(HAVE_ED25519) + { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_filename, "Read key(s) from file", "NAME" }, + { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, + "Redefine system-wide directories with public and revoked keys for verification", + "NAME" }, #endif - { NULL } -}; + { NULL } }; static void usage_error (GOptionContext *context, const char *message, GError **error) @@ -62,7 +65,8 @@ usage_error (GOptionContext *context, const char *message, GError **error) } gboolean -ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { g_autoptr (GOptionContext) context = NULL; g_autoptr (OstreeRepo) repo = NULL; @@ -76,8 +80,8 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, context = g_option_context_new ("COMMIT KEY-ID..."); - - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) goto out; if (argc < 2) @@ -89,9 +93,7 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, commit = argv[1]; /* Verification could be done via system files with public keys */ - if (!opt_verify && - !opt_filename && - argc < 3) + if (!opt_verify && !opt_filename && argc < 3) { usage_error (context, "Need at least one KEY-ID to sign with", error); goto out; @@ -119,18 +121,13 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, { g_autoptr (GError) local_error = NULL; - // Pass the key as a string - pk = g_variant_new_string(key_ids[ii]); + pk = g_variant_new_string (key_ids[ii]); if (!ostree_sign_set_pk (sign, pk, &local_error)) continue; - if (ostree_sign_commit_verify (sign, - repo, - resolved_commit, - &success_message, - cancellable, + if (ostree_sign_commit_verify (sign, repo, resolved_commit, &success_message, cancellable, &local_error)) { g_assert (success_message); @@ -142,18 +139,14 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, else { // Pass the key as a string - sk = g_variant_new_string(key_ids[ii]); + sk = g_variant_new_string (key_ids[ii]); if (!ostree_sign_set_sk (sign, sk, error)) { ret = FALSE; goto out; } - ret = ostree_sign_commit (sign, - repo, - resolved_commit, - cancellable, - error); + ret = ostree_sign_commit (sign, repo, resolved_commit, cancellable, error); if (ret != TRUE) goto out; } @@ -168,22 +161,20 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, g_autoptr (GVariant) sign_options = NULL; builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); - /* Use custom directory with public and revoked keys instead of system-wide directories */ + /* Use custom directory with public and revoked keys instead of system-wide directories + */ if (opt_keysdir) g_variant_builder_add (builder, "{sv}", "basedir", g_variant_new_string (opt_keysdir)); /* The last chance for verification source -- system files */ if (opt_filename) - g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (opt_filename)); + g_variant_builder_add (builder, "{sv}", "filename", + g_variant_new_string (opt_filename)); sign_options = g_variant_builder_end (builder); if (!ostree_sign_load_pk (sign, sign_options, error)) goto out; - if (ostree_sign_commit_verify (sign, - repo, - resolved_commit, - &success_message, - cancellable, + if (ostree_sign_commit_verify (sign, repo, resolved_commit, &success_message, cancellable, error)) { g_print ("%s\n", success_message); @@ -213,14 +204,15 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, if (key_stream_in == NULL) goto out; - key_data_in = g_data_input_stream_new (G_INPUT_STREAM(key_stream_in)); + key_data_in = g_data_input_stream_new (G_INPUT_STREAM (key_stream_in)); g_assert (key_data_in != NULL); /* Use simple file format with just a list of base64 public keys per line */ while (TRUE) { gsize len = 0; - g_autofree char *line = g_data_input_stream_read_line (key_data_in, &len, NULL, error); + g_autofree char *line + = g_data_input_stream_read_line (key_data_in, &len, NULL, error); g_autoptr (GVariant) sk = NULL; if (*error != NULL) @@ -229,20 +221,15 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, if (line == NULL) break; - // Pass the key as a string - sk = g_variant_new_string(line); + sk = g_variant_new_string (line); if (!ostree_sign_set_sk (sign, sk, error)) { ret = FALSE; goto out; } - ret = ostree_sign_commit (sign, - repo, - resolved_commit, - cancellable, - error); + ret = ostree_sign_commit (sign, repo, resolved_commit, cancellable, error); if (ret != TRUE) goto out; } @@ -250,9 +237,7 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, } // No valid signature found if (opt_verify && (ret != TRUE) && (*error == NULL)) - g_set_error_literal (error, - G_IO_ERROR, G_IO_ERROR_FAILED, - "No valid signatures found"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No valid signatures found"); out: /* It is possible to have an error due multiple signatures check */ diff --git a/src/ostree/ot-builtin-static-delta.c b/src/ostree/ot-builtin-static-delta.c index a5483c1..ba9a2f2 100644 --- a/src/ostree/ot-builtin-static-delta.c +++ b/src/ostree/ot-builtin-static-delta.c @@ -19,10 +19,9 @@ #include "config.h" -#include "ot-main.h" -#include "ot-builtins.h" -#include "ostree.h" #include "ostree-cmd-private.h" +#include "ostree.h" +#include "ot-builtins.h" #include "ot-main.h" #include "otutil.h" @@ -43,43 +42,35 @@ static char *opt_sign_name; static char *opt_keysfilename; static char *opt_keysdir; -#define BUILTINPROTO(name) static gboolean ot_static_delta_builtin_ ## name (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +#define BUILTINPROTO(name) \ + static gboolean ot_static_delta_builtin_##name (int argc, char **argv, \ + OstreeCommandInvocation *invocation, \ + GCancellable *cancellable, GError **error) -BUILTINPROTO(list); -BUILTINPROTO(show); -BUILTINPROTO(delete); -BUILTINPROTO(generate); -BUILTINPROTO(apply_offline); -BUILTINPROTO(verify); -BUILTINPROTO(indexes); -BUILTINPROTO(reindex); +BUILTINPROTO (list); +BUILTINPROTO (show); +BUILTINPROTO (delete); +BUILTINPROTO (generate); +BUILTINPROTO (apply_offline); +BUILTINPROTO (verify); +BUILTINPROTO (indexes); +BUILTINPROTO (reindex); #undef BUILTINPROTO static OstreeCommand static_delta_subcommands[] = { - { "list", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_list, - "List static delta files" }, - { "show", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_show, - "Dump information on a delta" }, - { "delete", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_delete, - "Remove a delta" }, - { "generate", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_generate, + { "list", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_list, "List static delta files" }, + { "show", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_show, "Dump information on a delta" }, + { "delete", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_delete, "Remove a delta" }, + { "generate", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_generate, "Generate static delta files" }, - { "apply-offline", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_apply_offline, + { "apply-offline", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_apply_offline, "Apply static delta file" }, - { "verify", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_verify, + { "verify", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_verify, "Verify static delta signatures" }, - { "indexes", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_indexes, + { "indexes", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_indexes, "List static delta indexes" }, - { "reindex", OSTREE_BUILTIN_FLAG_NONE, - ot_static_delta_builtin_reindex, + { "reindex", OSTREE_BUILTIN_FLAG_NONE, ot_static_delta_builtin_reindex, "Regenerate static delta indexes" }, { NULL, 0, NULL, NULL } }; @@ -95,55 +86,63 @@ static GOptionEntry generate_options[] = { { "inline", 0, 0, G_OPTION_ARG_NONE, &opt_inline, "Inline delta parts into main delta", NULL }, { "to", 0, 0, G_OPTION_ARG_STRING, &opt_to_rev, "Create delta to revision REV", "REV" }, { "disable-bsdiff", 0, 0, G_OPTION_ARG_NONE, &opt_disable_bsdiff, "Disable use of bsdiff", NULL }, - { "if-not-exists", 'n', 0, G_OPTION_ARG_NONE, &opt_if_not_exists, "Only generate if a delta does not already exist", NULL }, - { "set-endianness", 0, 0, G_OPTION_ARG_STRING, &opt_endianness, "Choose metadata endianness ('l' or 'B')", "ENDIAN" }, - { "swap-endianness", 0, 0, G_OPTION_ARG_NONE, &opt_swap_endianness, "Swap metadata endianness from host order", NULL }, - { "min-fallback-size", 0, 0, G_OPTION_ARG_STRING, &opt_min_fallback_size, "Minimum uncompressed size in megabytes for individual HTTP request", NULL}, - { "max-bsdiff-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_bsdiff_size, "Maximum size in megabytes to consider bsdiff compression for input files", NULL}, - { "max-chunk-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_chunk_size, "Maximum size of delta chunks in megabytes", NULL}, - { "filename", 0, 0, G_OPTION_ARG_FILENAME, &opt_filename, "Write the delta content to PATH (a directory). If not specified, the OSTree repository is used", "PATH"}, - { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Sign the delta with", "KEY_ID"}, - { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"}, -#if defined(HAVE_LIBSODIUM) - { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME"}, + { "if-not-exists", 'n', 0, G_OPTION_ARG_NONE, &opt_if_not_exists, + "Only generate if a delta does not already exist", NULL }, + { "set-endianness", 0, 0, G_OPTION_ARG_STRING, &opt_endianness, + "Choose metadata endianness ('l' or 'B')", "ENDIAN" }, + { "swap-endianness", 0, 0, G_OPTION_ARG_NONE, &opt_swap_endianness, + "Swap metadata endianness from host order", NULL }, + { "min-fallback-size", 0, 0, G_OPTION_ARG_STRING, &opt_min_fallback_size, + "Minimum uncompressed size in megabytes for individual HTTP request", NULL }, + { "max-bsdiff-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_bsdiff_size, + "Maximum size in megabytes to consider bsdiff compression for input files", NULL }, + { "max-chunk-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_chunk_size, + "Maximum size of delta chunks in megabytes", NULL }, + { "filename", 0, 0, G_OPTION_ARG_FILENAME, &opt_filename, + "Write the delta content to PATH (a directory). If not specified, the OSTree repository is " + "used", + "PATH" }, + { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Sign the delta with", "KEY_ID" }, + { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, + "Signature type to use (defaults to 'ed25519')", "NAME" }, +#if defined(HAVE_ED25519) + { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME" }, #endif { NULL } }; static GOptionEntry apply_offline_options[] = { - { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"}, -#if defined(HAVE_LIBSODIUM) - { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME"}, - { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, "Redefine system-wide directories with public and revoked keys for verification", "NAME"}, + { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, + "Signature type to use (defaults to 'ed25519')", "NAME" }, +#if defined(HAVE_ED25519) + { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME" }, + { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, + "Redefine system-wide directories with public and revoked keys for verification", "NAME" }, #endif { NULL } }; -static GOptionEntry list_options[] = { - { NULL } -}; +static GOptionEntry list_options[] = { { NULL } }; static GOptionEntry verify_options[] = { - { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"}, -#if defined(HAVE_LIBSODIUM) - { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME"}, - { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, "Redefine system-wide directories with public and revoked keys for verification", "NAME"}, + { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, + "Signature type to use (defaults to 'ed25519')", "NAME" }, +#if defined(HAVE_ED25519) + { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME" }, + { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, + "Redefine system-wide directories with public and revoked keys for verification", "NAME" }, #endif { NULL } }; -static GOptionEntry indexes_options[] = { - { NULL } -}; +static GOptionEntry indexes_options[] = { { NULL } }; -static GOptionEntry reindex_options[] = { - { "to", 0, 0, G_OPTION_ARG_STRING, &opt_to_rev, "Only update delta index to revision REV", "REV" }, - { NULL } -}; +static GOptionEntry reindex_options[] = { { "to", 0, 0, G_OPTION_ARG_STRING, &opt_to_rev, + "Only update delta index to revision REV", "REV" }, + { NULL } }; static void -static_delta_usage (char **argv, - gboolean is_error) +static_delta_usage (char **argv, gboolean is_error) { OstreeCommand *command = static_delta_subcommands; void (*print_func) (const gchar *format, ...); @@ -168,15 +167,16 @@ static_delta_usage (char **argv, } static gboolean -ot_static_delta_builtin_list (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_list (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GOptionContext) context = g_option_context_new (""); - if (!ostree_option_context_parse (context, list_options, &argc, &argv, - invocation, &repo, cancellable, error)) + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = g_option_context_new (""); + if (!ostree_option_context_parse (context, list_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; - g_autoptr(GPtrArray) delta_names = NULL; + g_autoptr (GPtrArray) delta_names = NULL; if (!ostree_repo_list_static_delta_names (repo, &delta_names, cancellable, error)) return FALSE; @@ -185,22 +185,23 @@ ot_static_delta_builtin_list (int argc, char **argv, OstreeCommandInvocation *in else { for (guint i = 0; i < delta_names->len; i++) - g_print ("%s\n", (char*)delta_names->pdata[i]); + g_print ("%s\n", (char *)delta_names->pdata[i]); } return TRUE; } static gboolean -ot_static_delta_builtin_indexes (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_indexes (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GOptionContext) context = g_option_context_new (""); - if (!ostree_option_context_parse (context, indexes_options, &argc, &argv, - invocation, &repo, cancellable, error)) + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = g_option_context_new (""); + if (!ostree_option_context_parse (context, indexes_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; - g_autoptr(GPtrArray) indexes = NULL; + g_autoptr (GPtrArray) indexes = NULL; if (!ostree_repo_list_static_delta_indexes (repo, &indexes, cancellable, error)) return FALSE; @@ -209,19 +210,21 @@ ot_static_delta_builtin_indexes (int argc, char **argv, OstreeCommandInvocation else { for (guint i = 0; i < indexes->len; i++) - g_print ("%s\n", (char*)indexes->pdata[i]); + g_print ("%s\n", (char *)indexes->pdata[i]); } return TRUE; } static gboolean -ot_static_delta_builtin_reindex (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_reindex (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, reindex_options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, reindex_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (!ostree_repo_static_delta_reindex (repo, 0, opt_to_rev, cancellable, error)) @@ -230,21 +233,21 @@ ot_static_delta_builtin_reindex (int argc, char **argv, OstreeCommandInvocation return TRUE; } - static gboolean -ot_static_delta_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, list_options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, list_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (argc < 3) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "DELTA must be specified"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "DELTA must be specified"); return FALSE; } @@ -257,18 +260,19 @@ ot_static_delta_builtin_show (int argc, char **argv, OstreeCommandInvocation *in } static gboolean -ot_static_delta_builtin_delete (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_delete (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new (""); + g_autoptr (GOptionContext) context = g_option_context_new (""); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, list_options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, list_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (argc < 3) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "DELTA must be specified"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "DELTA must be specified"); return FALSE; } @@ -280,13 +284,14 @@ ot_static_delta_builtin_delete (int argc, char **argv, OstreeCommandInvocation * return TRUE; } - static gboolean -ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("[TO]"); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, generate_options, &argc, &argv, invocation, &repo, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new ("[TO]"); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, generate_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (!ostree_ensure_repo_writable (repo, error)) @@ -297,8 +302,7 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation if (argc < 3 && opt_to_rev == NULL) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "TO revision must be specified"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "TO revision must be specified"); return FALSE; } else @@ -307,7 +311,7 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation g_autofree char *from_resolved = NULL; g_autofree char *to_resolved = NULL; g_autofree char *from_parent_str = NULL; - g_autoptr(GVariantBuilder) parambuilder = NULL; + g_autoptr (GVariantBuilder) parambuilder = NULL; int endianness; g_assert (opt_to_rev); @@ -343,8 +347,11 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation if (opt_if_not_exists) { gboolean does_exist; - g_autofree char *delta_id = from_resolved ? g_strconcat (from_resolved, "-", to_resolved, NULL) : g_strdup (to_resolved); - if (!ostree_cmd__private__ ()->ostree_static_delta_query_exists (repo, delta_id, &does_exist, cancellable, error)) + g_autofree char *delta_id = from_resolved + ? g_strconcat (from_resolved, "-", to_resolved, NULL) + : g_strdup (to_resolved); + if (!ostree_cmd__private__ ()->ostree_static_delta_query_exists ( + repo, delta_id, &does_exist, cancellable, error)) return FALSE; if (does_exist) { @@ -361,8 +368,8 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation endianness = G_BIG_ENDIAN; else { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid endianness '%s'", opt_endianness); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid endianness '%s'", + opt_endianness); return FALSE; } } @@ -386,31 +393,34 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation parambuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); if (opt_min_fallback_size) - g_variant_builder_add (parambuilder, "{sv}", - "min-fallback-size", g_variant_new_uint32 (g_ascii_strtoull (opt_min_fallback_size, NULL, 10))); + g_variant_builder_add ( + parambuilder, "{sv}", "min-fallback-size", + g_variant_new_uint32 (g_ascii_strtoull (opt_min_fallback_size, NULL, 10))); if (opt_max_bsdiff_size) - g_variant_builder_add (parambuilder, "{sv}", - "max-bsdiff-size", g_variant_new_uint32 (g_ascii_strtoull (opt_max_bsdiff_size, NULL, 10))); + g_variant_builder_add ( + parambuilder, "{sv}", "max-bsdiff-size", + g_variant_new_uint32 (g_ascii_strtoull (opt_max_bsdiff_size, NULL, 10))); if (opt_max_chunk_size) - g_variant_builder_add (parambuilder, "{sv}", - "max-chunk-size", g_variant_new_uint32 (g_ascii_strtoull (opt_max_chunk_size, NULL, 10))); + g_variant_builder_add ( + parambuilder, "{sv}", "max-chunk-size", + g_variant_new_uint32 (g_ascii_strtoull (opt_max_chunk_size, NULL, 10))); if (opt_disable_bsdiff) - g_variant_builder_add (parambuilder, "{sv}", - "bsdiff-enabled", g_variant_new_boolean (FALSE)); + g_variant_builder_add (parambuilder, "{sv}", "bsdiff-enabled", + g_variant_new_boolean (FALSE)); if (opt_inline) - g_variant_builder_add (parambuilder, "{sv}", - "inline-parts", g_variant_new_boolean (TRUE)); + g_variant_builder_add (parambuilder, "{sv}", "inline-parts", g_variant_new_boolean (TRUE)); if (opt_filename) - g_variant_builder_add (parambuilder, "{sv}", - "filename", g_variant_new_bytestring (opt_filename)); + g_variant_builder_add (parambuilder, "{sv}", "filename", + g_variant_new_bytestring (opt_filename)); g_variant_builder_add (parambuilder, "{sv}", "verbose", g_variant_new_boolean (TRUE)); if (opt_endianness || opt_swap_endianness) - g_variant_builder_add (parambuilder, "{sv}", "endianness", g_variant_new_uint32 (endianness)); + g_variant_builder_add (parambuilder, "{sv}", "endianness", + g_variant_new_uint32 (endianness)); if (opt_key_ids || opt_keysfilename) { - g_autoptr(GPtrArray) key_ids = g_ptr_array_new (); + g_autoptr (GPtrArray) key_ids = g_ptr_array_new (); for (char **iter = opt_key_ids; iter != NULL && *iter != NULL; ++iter) g_ptr_array_add (key_ids, *iter); @@ -424,7 +434,8 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation if (!g_file_test (opt_keysfilename, G_FILE_TEST_IS_REGULAR)) { g_warning ("Can't open file '%s' with keys", opt_keysfilename); - return glnx_throw (error, "File object '%s' is not a regular file", opt_keysfilename); + return glnx_throw (error, "File object '%s' is not a regular file", + opt_keysfilename); } keyfile = g_file_new_for_path (opt_keysfilename); @@ -432,14 +443,15 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation if (key_stream_in == NULL) return FALSE; - key_data_in = g_data_input_stream_new (G_INPUT_STREAM(key_stream_in)); + key_data_in = g_data_input_stream_new (G_INPUT_STREAM (key_stream_in)); g_assert (key_data_in != NULL); /* Use simple file format with just a list of base64 public keys per line */ while (TRUE) { gsize len = 0; - g_autofree char *line = g_data_input_stream_read_line (key_data_in, &len, NULL, error); + g_autofree char *line + = g_data_input_stream_read_line (key_data_in, &len, NULL, error); g_autoptr (GVariant) sk = NULL; if (*error != NULL) @@ -453,8 +465,8 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation } } - g_autoptr(GVariant) key_ids_v = g_variant_new_strv ((const char *const *)key_ids->pdata, - key_ids->len); + g_autoptr (GVariant) key_ids_v + = g_variant_new_strv ((const char *const *)key_ids->pdata, key_ids->len); g_variant_builder_add (parambuilder, "{s@v}", "sign-key-ids", g_variant_new_variant (g_steal_pointer (&key_ids_v))); } @@ -465,30 +477,31 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation g_print ("Generating static delta:\n"); g_print (" From: %s\n", from_resolved ? from_resolved : "empty"); g_print (" To: %s\n", to_resolved); - { g_autoptr(GVariant) params = g_variant_ref_sink (g_variant_builder_end (parambuilder)); + { + g_autoptr (GVariant) params = g_variant_ref_sink (g_variant_builder_end (parambuilder)); if (!ostree_repo_static_delta_generate (repo, OSTREE_STATIC_DELTA_GENERATE_OPT_MAJOR, - from_resolved, to_resolved, NULL, - params, + from_resolved, to_resolved, NULL, params, cancellable, error)) return FALSE; } - } return TRUE; } static gboolean -ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; g_autoptr (OstreeSign) sign = NULL; char **key_ids; int n_key_ids; context = g_option_context_new (""); - if (!ostree_option_context_parse (context, apply_offline_options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, apply_offline_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (!ostree_ensure_repo_writable (repo, error)) @@ -496,12 +509,11 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc if (argc < 3) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "PATH must be specified"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "PATH must be specified"); return FALSE; } -#if defined(HAVE_LIBSODIUM) +#if defined(HAVE_ED25519) /* Initialize crypto system */ opt_sign_name = opt_sign_name ?: OSTREE_SIGN_NAME_ED25519; #endif @@ -516,8 +528,8 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc n_key_ids = argc - 3; for (int i = 0; i < n_key_ids; i++) { - g_autoptr (GVariant) pk = g_variant_new_string(key_ids[i]); - if (!ostree_sign_add_pk(sign, pk, error)) + g_autoptr (GVariant) pk = g_variant_new_string (key_ids[i]); + if (!ostree_sign_add_pk (sign, pk, error)) return FALSE; } if ((n_key_ids == 0) || opt_keysfilename) @@ -525,21 +537,24 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc g_autoptr (GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); g_autoptr (GVariant) options = NULL; - /* Use custom directory with public and revoked keys instead of system-wide directories */ + /* Use custom directory with public and revoked keys instead of system-wide directories + */ if (opt_keysdir) g_variant_builder_add (builder, "{sv}", "basedir", g_variant_new_string (opt_keysdir)); /* The last chance for verification source -- system files */ if (opt_keysfilename) - g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (opt_keysfilename)); + g_variant_builder_add (builder, "{sv}", "filename", + g_variant_new_string (opt_keysfilename)); options = g_variant_builder_end (builder); if (!ostree_sign_load_pk (sign, options, error)) { - /* If it fails to load system default public keys, consider there no signature engine */ + /* If it fails to load system default public keys, consider there no signature engine + */ if (!opt_keysdir && !opt_keysfilename) { - g_clear_error(error); - g_clear_object(&sign); + g_clear_error (error); + g_clear_object (&sign); } else return FALSE; @@ -548,12 +563,13 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc } const char *patharg = argv[2]; - g_autoptr(GFile) path = g_file_new_for_path (patharg); + g_autoptr (GFile) path = g_file_new_for_path (patharg); if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) return FALSE; - if (!ostree_repo_static_delta_execute_offline_with_signature (repo, path, sign, FALSE, cancellable, error)) + if (!ostree_repo_static_delta_execute_offline_with_signature (repo, path, sign, FALSE, + cancellable, error)) return FALSE; if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error)) @@ -563,7 +579,8 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc } static gboolean -ot_static_delta_builtin_verify (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_static_delta_builtin_verify (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { g_autoptr (GOptionContext) context = g_option_context_new ("STATIC-DELTA-FILE [KEY-ID...]"); g_autoptr (OstreeRepo) repo = NULL; @@ -571,13 +588,13 @@ ot_static_delta_builtin_verify (int argc, char **argv, OstreeCommandInvocation * char **key_ids; int n_key_ids; - if (!ostree_option_context_parse (context, verify_options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, verify_options, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (argc < 3) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "DELTA must be specified"); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "DELTA must be specified"); return FALSE; } @@ -588,7 +605,7 @@ ot_static_delta_builtin_verify (int argc, char **argv, OstreeCommandInvocation * g_autoptr (OstreeSign) sign = ostree_sign_get_by_name (opt_sign_name, error); if (!sign) { - g_print("Sign-type not supported\n"); + g_print ("Sign-type not supported\n"); return FALSE; } @@ -596,8 +613,8 @@ ot_static_delta_builtin_verify (int argc, char **argv, OstreeCommandInvocation * n_key_ids = argc - 3; for (int i = 0; i < n_key_ids; i++) { - g_autoptr (GVariant) pk = g_variant_new_string(key_ids[i]); - if (!ostree_sign_add_pk(sign, pk, error)) + g_autoptr (GVariant) pk = g_variant_new_string (key_ids[i]); + if (!ostree_sign_add_pk (sign, pk, error)) return FALSE; } if ((n_key_ids == 0) || opt_keysfilename) @@ -611,7 +628,8 @@ ot_static_delta_builtin_verify (int argc, char **argv, OstreeCommandInvocation * g_variant_builder_add (builder, "{sv}", "basedir", g_variant_new_string (opt_keysdir)); /* The last chance for verification source -- system files */ if (opt_keysfilename) - g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (opt_keysfilename)); + g_variant_builder_add (builder, "{sv}", "filename", + g_variant_new_string (opt_keysfilename)); options = g_variant_builder_end (builder); if (!ostree_sign_load_pk (sign, options, error)) @@ -625,7 +643,8 @@ ot_static_delta_builtin_verify (int argc, char **argv, OstreeCommandInvocation * } gboolean -ostree_builtin_static_delta (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_static_delta (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { gboolean want_help = FALSE; const char *cmdname = NULL; diff --git a/src/ostree/ot-builtin-summary.c b/src/ostree/ot-builtin-summary.c index 2d6306a..df980df 100644 --- a/src/ostree/ot-builtin-summary.c +++ b/src/ostree/ot-builtin-summary.c @@ -20,14 +20,16 @@ #include "config.h" #include "ostree-repo-private.h" +#include "ostree-sign.h" +#include "ostree.h" +#include "ot-builtins.h" #include "ot-dump.h" #include "ot-main.h" -#include "ot-builtins.h" -#include "ostree.h" #include "otutil.h" -#include "ostree-sign.h" static gboolean opt_update, opt_view, opt_raw; +static gboolean opt_list_metadata_keys; +static char *opt_print_metadata_key; static char **opt_gpg_key_ids; static char *opt_gpg_homedir; static char **opt_key_ids; @@ -39,25 +41,33 @@ static char **opt_metadata; * man page (man/ostree-summary.xml) when changing the option list. */ -static GOptionEntry options[] = { - { "update", 'u', 0, G_OPTION_ARG_NONE, &opt_update, "Update the summary", NULL }, - { "view", 'v', 0, G_OPTION_ARG_NONE, &opt_view, "View the local summary file", NULL }, - { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "View the raw bytes of the summary file", NULL }, - { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, "GPG Key ID to sign the summary with", "KEY-ID"}, - { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"}, - { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Key ID to sign the summary with", "KEY-ID"}, - { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"}, - { "add-metadata", 'm', 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata, "Additional metadata field to add to the summary", "KEY=VALUE" }, - { NULL } -}; +static GOptionEntry options[] + = { { "update", 'u', 0, G_OPTION_ARG_NONE, &opt_update, "Update the summary", NULL }, + { "view", 'v', 0, G_OPTION_ARG_NONE, &opt_view, "View the local summary file", NULL }, + { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "View the raw bytes of the summary file", + NULL }, + { "list-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_metadata_keys, + "List the available metadata keys", NULL }, + { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, + "Print string value of metadata key", "KEY" }, + { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, + "GPG Key ID to sign the summary with", "KEY-ID" }, + { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, + "GPG Homedir to use when looking for keyrings", "HOMEDIR" }, + { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Key ID to sign the summary with", + "KEY-ID" }, + { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, + "Signature type to use (defaults to 'ed25519')", "NAME" }, + { "add-metadata", 'm', 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata, + "Additional metadata field to add to the summary", "KEY=VALUE" }, + { NULL } }; /* Take arguments of the form KEY=VALUE and put them into an a{sv} variant. The * value arguments must be parsable using g_variant_parse(). */ static GVariant * -build_additional_metadata (const char * const *args, - GError **error) +build_additional_metadata (const char *const *args, GError **error) { - g_autoptr(GVariantBuilder) builder = NULL; + g_autoptr (GVariantBuilder) builder = NULL; builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); @@ -66,11 +76,10 @@ build_additional_metadata (const char * const *args, const gchar *equals = strchr (args[i], '='); g_autofree gchar *key = NULL; const gchar *value_str; - g_autoptr(GVariant) value = NULL; + g_autoptr (GVariant) value = NULL; if (equals == NULL) - return glnx_null_throw (error, - "Missing '=' in KEY=VALUE metadata '%s'", args[i]); + return glnx_null_throw (error, "Missing '=' in KEY=VALUE metadata '%s'", args[i]); key = g_strndup (args[i], equals - args[i]); value_str = equals + 1; @@ -85,17 +94,37 @@ build_additional_metadata (const char * const *args, return g_variant_ref_sink (g_variant_builder_end (builder)); } +static gboolean +get_summary_data (OstreeRepo *repo, GBytes **out_summary_data, GError **error) +{ + g_assert (out_summary_data != NULL); + + g_autoptr (GBytes) summary_data = NULL; + glnx_autofd int fd = -1; + if (!glnx_openat_rdonly (repo->repo_dir_fd, "summary", TRUE, &fd, error)) + return FALSE; + summary_data = ot_fd_readall_or_mmap (fd, 0, error); + if (!summary_data) + return FALSE; + + *out_summary_data = g_steal_pointer (&summary_data); + + return TRUE; +} + gboolean -ostree_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ostree_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; g_autoptr (OstreeSign) sign = NULL; OstreeDumpFlags flags = OSTREE_DUMP_NONE; context = g_option_context_new (""); - if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, + error)) return FALSE; /* Initialize crypto system */ @@ -110,180 +139,85 @@ ostree_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocati if (opt_update) { - g_autoptr(GVariant) additional_metadata = NULL; + g_autoptr (GVariant) additional_metadata = NULL; if (!ostree_ensure_repo_writable (repo, error)) return FALSE; if (opt_metadata != NULL) { - additional_metadata = build_additional_metadata ((const char * const *) opt_metadata, error); + additional_metadata + = build_additional_metadata ((const char *const *)opt_metadata, error); if (additional_metadata == NULL) return FALSE; } - const char *collection_id = ostree_repo_get_collection_id (repo); - - /* Write out a new metadata commit for the repository. */ - if (collection_id != NULL) + /* Regenerate and sign the repo metadata. */ + g_auto (GVariantBuilder) metadata_opts_builder + = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); + g_autoptr (GVariant) metadata_opts = NULL; + if (opt_gpg_key_ids != NULL) + g_variant_builder_add (&metadata_opts_builder, "{sv}", "gpg-key-ids", + g_variant_new_strv ((const char *const *)opt_gpg_key_ids, -1)); + if (opt_gpg_homedir != NULL) + g_variant_builder_add (&metadata_opts_builder, "{sv}", "gpg-homedir", + g_variant_new_string (opt_gpg_homedir)); + if (opt_key_ids != NULL) { - OstreeCollectionRef collection_ref = { (gchar *) collection_id, (gchar *) OSTREE_REPO_METADATA_REF }; - g_autofree char *old_ostree_metadata_checksum = NULL; - g_autofree gchar *new_ostree_metadata_checksum = NULL; - g_autoptr(OstreeMutableTree) mtree = NULL; - g_autoptr(OstreeRepoFile) repo_file = NULL; - g_autoptr(GVariantDict) new_summary_commit_dict = NULL; - g_autoptr(GVariant) new_summary_commit = NULL; - - if (!ostree_repo_resolve_rev (repo, OSTREE_REPO_METADATA_REF, - TRUE, &old_ostree_metadata_checksum, error)) - return FALSE; - - /* Add bindings to the metadata. */ - new_summary_commit_dict = g_variant_dict_new (additional_metadata); - g_variant_dict_insert (new_summary_commit_dict, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, - "s", collection_ref.collection_id); - g_variant_dict_insert_value (new_summary_commit_dict, OSTREE_COMMIT_META_KEY_REF_BINDING, - g_variant_new_strv ((const gchar * const *) &collection_ref.ref_name, 1)); - new_summary_commit = g_variant_dict_end (new_summary_commit_dict); - - if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) - return FALSE; - - /* Set up an empty mtree. */ - mtree = ostree_mutable_tree_new (); - - glnx_unref_object GFileInfo *fi = g_file_info_new (); - g_file_info_set_attribute_uint32 (fi, "unix::uid", 0); - g_file_info_set_attribute_uint32 (fi, "unix::gid", 0); - g_file_info_set_attribute_uint32 (fi, "unix::mode", (0755 | S_IFDIR)); - - g_autofree guchar *csum_raw = NULL; - g_autofree char *csum = NULL; - - g_autoptr(GVariant) dirmeta = ostree_create_directory_metadata (fi, NULL /* xattrs */); - - if (!ostree_repo_write_metadata (repo, OSTREE_OBJECT_TYPE_DIR_META, NULL, - dirmeta, &csum_raw, cancellable, error)) - return FALSE; - - csum = ostree_checksum_from_bytes (csum_raw); - ostree_mutable_tree_set_metadata_checksum (mtree, csum); - - if (!ostree_repo_write_mtree (repo, mtree, (GFile **) &repo_file, NULL, error)) - return FALSE; - - if (!ostree_repo_write_commit (repo, old_ostree_metadata_checksum, - NULL /* subject */, NULL /* body */, - new_summary_commit, repo_file, &new_ostree_metadata_checksum, - NULL, error)) - return FALSE; - if (opt_gpg_key_ids != NULL) - { - for (const char * const *iter = (const char * const *) opt_gpg_key_ids; - iter != NULL && *iter != NULL; iter++) - { - const char *key_id = *iter; - - if (!ostree_repo_sign_commit (repo, - new_ostree_metadata_checksum, - key_id, - opt_gpg_homedir, - cancellable, - error)) - return FALSE; - } - } + g_auto (GVariantBuilder) sk_builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_ARRAY); - if (opt_key_ids) + /* Currently only strings are used as keys for supported + * signature types. */ + for (const char *const *iter = (const char *const *)opt_key_ids; + iter != NULL && *iter != NULL; iter++) { - char **iter; - for (iter = opt_key_ids; iter && *iter; iter++) - { - const char *keyid = *iter; - g_autoptr (GVariant) secret_key = NULL; - - secret_key = g_variant_new_string (keyid); - if (!ostree_sign_set_sk (sign, secret_key, error)) - return FALSE; - - if (!ostree_sign_commit (sign, - repo, - new_ostree_metadata_checksum, - cancellable, - error)) - return FALSE; - } + const char *key_id = *iter; + g_variant_builder_add (&sk_builder, "v", g_variant_new_string (key_id)); } - ostree_repo_transaction_set_collection_ref (repo, &collection_ref, - new_ostree_metadata_checksum); - - if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error)) - return FALSE; + g_variant_builder_add (&metadata_opts_builder, "{sv}", "sign-keys", + g_variant_builder_end (&sk_builder)); } + if (opt_sign_name != NULL) + g_variant_builder_add (&metadata_opts_builder, "{sv}", "sign-type", + g_variant_new_string (opt_sign_name)); - /* Regenerate and sign the conventional summary file. */ - if (!ostree_repo_regenerate_summary (repo, additional_metadata, cancellable, error)) + metadata_opts = g_variant_ref_sink (g_variant_builder_end (&metadata_opts_builder)); + if (!ostree_repo_regenerate_metadata (repo, additional_metadata, metadata_opts, cancellable, + error)) return FALSE; - -#ifndef OSTREE_DISABLE_GPGME - if (opt_gpg_key_ids) - { - if (!ostree_repo_add_gpg_signature_summary (repo, - (const gchar **) opt_gpg_key_ids, - opt_gpg_homedir, - cancellable, - error)) - return FALSE; - } -#endif - if (opt_key_ids) - { - g_autoptr (GVariant) secret_keys = NULL; - g_autoptr (GVariantBuilder) sk_builder = NULL; - - sk_builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); - - char **iter; - for (iter = opt_key_ids; iter && *iter; iter++) - { - const char *keyid = *iter; - GVariant *secret_key = NULL; - - /* Currently only strings are used as keys - * for supported signature types */ - secret_key = g_variant_new_string (keyid); - - g_variant_builder_add (sk_builder, "v", secret_key); - } - - secret_keys = g_variant_builder_end (sk_builder); - - if (! ostree_sign_summary (sign, - repo, - secret_keys, - cancellable, - error)) - return FALSE; - } } else if (opt_view || opt_raw) { - g_autoptr(GBytes) summary_data = NULL; + g_autoptr (GBytes) summary_data = NULL; if (opt_raw) flags |= OSTREE_DUMP_RAW; - glnx_autofd int fd = -1; - if (!glnx_openat_rdonly (repo->repo_dir_fd, "summary", TRUE, &fd, error)) - return FALSE; - summary_data = ot_fd_readall_or_mmap (fd, 0, error); - if (!summary_data) + if (!get_summary_data (repo, &summary_data, error)) return FALSE; ot_dump_summary_bytes (summary_data, flags); } + else if (opt_list_metadata_keys) + { + g_autoptr (GBytes) summary_data = NULL; + + if (!get_summary_data (repo, &summary_data, error)) + return FALSE; + + ot_dump_summary_metadata_keys (summary_data); + } + else if (opt_print_metadata_key) + { + g_autoptr (GBytes) summary_data = NULL; + + if (!get_summary_data (repo, &summary_data, error)) + return FALSE; + + if (!ot_dump_summary_metadata_key (summary_data, opt_print_metadata_key, error)) + return FALSE; + } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, diff --git a/src/ostree/ot-builtins.h b/src/ostree/ot-builtins.h index 286c2e9..e14f67f 100644 --- a/src/ostree/ot-builtins.h +++ b/src/ostree/ot-builtins.h @@ -24,41 +24,43 @@ #include "config.h" #include "ostree.h" +#include "ot-main.h" G_BEGIN_DECLS -#define BUILTINPROTO(name) gboolean ostree_builtin_ ## name (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +#define BUILTINPROTO(name) \ + gboolean ostree_builtin_##name (int argc, char **argv, OstreeCommandInvocation *invocation, \ + GCancellable *cancellable, GError **error) -BUILTINPROTO(admin); -BUILTINPROTO(cat); -BUILTINPROTO(config); -BUILTINPROTO(checkout); -BUILTINPROTO(checksum); -BUILTINPROTO(commit); -BUILTINPROTO(diff); -BUILTINPROTO(export); -BUILTINPROTO(find_remotes); -BUILTINPROTO(create_usb); +BUILTINPROTO (admin); +BUILTINPROTO (cat); +BUILTINPROTO (config); +BUILTINPROTO (checkout); +BUILTINPROTO (checksum); +BUILTINPROTO (commit); +BUILTINPROTO (diff); +BUILTINPROTO (export); +BUILTINPROTO (find_remotes); +BUILTINPROTO (create_usb); #ifndef OSTREE_DISABLE_GPGME -BUILTINPROTO(gpg_sign); +BUILTINPROTO (gpg_sign); #endif -BUILTINPROTO(init); -BUILTINPROTO(log); -BUILTINPROTO(pull); -BUILTINPROTO(pull_local); -BUILTINPROTO(ls); -BUILTINPROTO(prune); -BUILTINPROTO(refs); -BUILTINPROTO(reset); -BUILTINPROTO(fsck); -BUILTINPROTO(sign); -BUILTINPROTO(show); -BUILTINPROTO(static_delta); -BUILTINPROTO(summary); -BUILTINPROTO(rev_parse); -BUILTINPROTO(remote); -BUILTINPROTO(write_refs); -BUILTINPROTO(trivial_httpd); +BUILTINPROTO (init); +BUILTINPROTO (log); +BUILTINPROTO (pull); +BUILTINPROTO (pull_local); +BUILTINPROTO (ls); +BUILTINPROTO (prune); +BUILTINPROTO (refs); +BUILTINPROTO (reset); +BUILTINPROTO (fsck); +BUILTINPROTO (sign); +BUILTINPROTO (show); +BUILTINPROTO (static_delta); +BUILTINPROTO (summary); +BUILTINPROTO (rev_parse); +BUILTINPROTO (remote); +BUILTINPROTO (write_refs); #undef BUILTINPROTO diff --git a/src/ostree/ot-dump.c b/src/ostree/ot-dump.c index 509eb79..2ff2fe2 100644 --- a/src/ostree/ot-dump.c +++ b/src/ostree/ot-dump.c @@ -27,15 +27,15 @@ #include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" +#include "ot-admin-functions.h" #include "ot-dump.h" #include "otutil.h" -#include "ot-admin-functions.h" void ot_dump_variant (GVariant *variant) { g_autofree char *formatted_variant = NULL; - g_autoptr(GVariant) byteswapped = NULL; + g_autoptr (GVariant) byteswapped = NULL; if (G_BYTE_ORDER != G_BIG_ENDIAN) { @@ -50,9 +50,7 @@ ot_dump_variant (GVariant *variant) } static gchar * -format_timestamp (guint64 timestamp, - gboolean local_tz, - GError **error) +format_timestamp (guint64 timestamp, gboolean local_tz, GError **error) { GDateTime *dt; gchar *str; @@ -70,7 +68,7 @@ format_timestamp (guint64 timestamp, /* Convert to local time and display in the locale's preferred * representation. */ - g_autoptr(GDateTime) dt_local = g_date_time_to_local (dt); + g_autoptr (GDateTime) dt_local = g_date_time_to_local (dt); str = g_date_time_format (dt_local, "%c"); } else @@ -86,8 +84,8 @@ format_timestamp (guint64 timestamp, static gchar * uint64_secs_to_iso8601 (guint64 secs) { - g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc (secs); - g_autoptr(GDateTime) local = (dt != NULL) ? g_date_time_to_local (dt) : NULL; + g_autoptr (GDateTime) dt = g_date_time_new_from_unix_utc (secs); + g_autoptr (GDateTime) local = (dt != NULL) ? g_date_time_to_local (dt) : NULL; if (local != NULL) return g_date_time_format (local, "%FT%T%:::z"); @@ -98,7 +96,7 @@ uint64_secs_to_iso8601 (guint64 secs) static void dump_indented_lines (const gchar *data) { - const char* indent = " "; + const char *indent = " "; const gchar *pos; for (;;) @@ -119,8 +117,7 @@ dump_indented_lines (const gchar *data) } static void -dump_commit (GVariant *variant, - OstreeDumpFlags flags) +dump_commit (GVariant *variant, OstreeDumpFlags flags) { const gchar *subject; const gchar *body; @@ -128,11 +125,11 @@ dump_commit (GVariant *variant, g_autofree char *parent = NULL; g_autofree char *str = NULL; g_autofree char *version = NULL; - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; /* See OSTREE_COMMIT_GVARIANT_FORMAT */ - g_variant_get (variant, "(a{sv}aya(say)&s&stayay)", NULL, NULL, NULL, - &subject, &body, ×tamp, NULL, NULL); + g_variant_get (variant, "(a{sv}aya(say)&s&stayay)", NULL, NULL, NULL, &subject, &body, ×tamp, + NULL, NULL); timestamp = GUINT64_FROM_BE (timestamp); str = format_timestamp (timestamp, FALSE, &local_error); @@ -142,7 +139,7 @@ dump_commit (GVariant *variant, errx (1, "Failed to read commit: %s", local_error->message); } - if ((parent = ostree_commit_get_parent(variant))) + if ((parent = ostree_commit_get_parent (variant))) { g_print ("Parent: %s\n", parent); } @@ -175,10 +172,8 @@ dump_commit (GVariant *variant, } void -ot_dump_object (OstreeObjectType objtype, - const char *checksum, - GVariant *variant, - OstreeDumpFlags flags) +ot_dump_object (OstreeObjectType objtype, const char *checksum, GVariant *variant, + OstreeDumpFlags flags) { g_print ("%s %s\n", ostree_object_type_to_string (objtype), checksum); @@ -194,22 +189,19 @@ ot_dump_object (OstreeObjectType objtype, } switch (objtype) - { + { case OSTREE_OBJECT_TYPE_COMMIT: dump_commit (variant, flags); break; /* TODO: Others could be implemented here */ default: break; - } + } } static void -dump_summary_ref (const char *collection_id, - const char *ref_name, - guint64 commit_size, - GVariant *csum_v, - GVariantIter *metadata) +dump_summary_ref (const char *collection_id, const char *ref_name, guint64 commit_size, + GVariant *csum_v, GVariantIter *metadata) { const guchar *csum_bytes; GError *csum_error = NULL; @@ -228,7 +220,7 @@ dump_summary_ref (const char *collection_id, csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, &csum_error); if (csum_error == NULL) { - char csum[OSTREE_SHA256_STRING_LEN+1]; + char csum[OSTREE_SHA256_STRING_LEN + 1]; ostree_checksum_inplace_from_bytes (csum_bytes, csum); g_print (" %s\n", csum); @@ -268,8 +260,7 @@ dump_summary_ref (const char *collection_id, } static void -dump_summary_refs (const gchar *collection_id, - GVariant *refs) +dump_summary_refs (const gchar *collection_id, GVariant *refs) { GVariantIter iter; GVariant *value; @@ -284,12 +275,11 @@ dump_summary_refs (const gchar *collection_id, if (ref_name != NULL) { - g_autoptr(GVariant) csum_v = NULL; - g_autoptr(GVariantIter) metadata = NULL; + g_autoptr (GVariant) csum_v = NULL; + g_autoptr (GVariantIter) metadata = NULL; guint64 commit_size; - g_variant_get_child (value, 1, "(t@aya{sv})", - &commit_size, &csum_v, &metadata); + g_variant_get_child (value, 1, "(t@aya{sv})", &commit_size, &csum_v, &metadata); dump_summary_ref (collection_id, ref_name, commit_size, csum_v, metadata); @@ -301,20 +291,18 @@ dump_summary_refs (const gchar *collection_id, } void -ot_dump_summary_bytes (GBytes *summary_bytes, - OstreeDumpFlags flags) +ot_dump_summary_bytes (GBytes *summary_bytes, OstreeDumpFlags flags) { - g_autoptr(GVariant) summary = NULL; - g_autoptr(GVariant) refs = NULL; - g_autoptr(GVariant) exts = NULL; + g_autoptr (GVariant) summary = NULL; + g_autoptr (GVariant) refs = NULL; + g_autoptr (GVariant) exts = NULL; GVariantIter iter; GVariant *value; char *key; g_return_if_fail (summary_bytes != NULL); - summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, - summary_bytes, FALSE); + summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE); if (flags & OSTREE_DUMP_RAW) { @@ -327,7 +315,7 @@ ot_dump_summary_bytes (GBytes *summary_bytes, /* Print the refs, including those with a collection ID specified. */ const gchar *main_collection_id; - g_autoptr(GVariant) collection_map = NULL; + g_autoptr (GVariant) collection_map = NULL; const gchar *collection_id; if (!g_variant_lookup (exts, OSTREE_SUMMARY_COLLECTION_ID, "&s", &main_collection_id)) @@ -335,10 +323,11 @@ ot_dump_summary_bytes (GBytes *summary_bytes, dump_summary_refs (main_collection_id, refs); - collection_map = g_variant_lookup_value (exts, OSTREE_SUMMARY_COLLECTION_MAP, G_VARIANT_TYPE ("a{sa(s(taya{sv}))}")); + collection_map = g_variant_lookup_value (exts, OSTREE_SUMMARY_COLLECTION_MAP, + G_VARIANT_TYPE ("a{sa(s(taya{sv}))}")); if (collection_map != NULL) { - g_autoptr(GVariant) collection_refs = NULL; + g_autoptr (GVariant) collection_refs = NULL; g_variant_iter_init (&iter, collection_map); while (g_variant_iter_loop (&iter, "{&s@a(s(taya{sv}))}", &collection_id, &collection_refs)) @@ -407,10 +396,62 @@ ot_dump_summary_bytes (GBytes *summary_bytes, } } +static gint +strptr_cmp (gconstpointer a, gconstpointer b) +{ + const char *a_str = *((const char **)a); + const char *b_str = *((const char **)b); + + return g_strcmp0 (a_str, b_str); +} + +void +ot_dump_summary_metadata_keys (GBytes *summary_bytes) +{ + g_autoptr (GVariant) summary = NULL; + g_autoptr (GVariant) metadata = NULL; + + summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE); + metadata = g_variant_get_child_value (summary, 1); + + GVariantIter iter; + const char *key = NULL; + g_autoptr (GPtrArray) keys = g_ptr_array_new (); + g_variant_iter_init (&iter, metadata); + while (g_variant_iter_loop (&iter, "{&s@v}", &key, NULL)) + g_ptr_array_add (keys, (gpointer)key); + + g_ptr_array_sort (keys, strptr_cmp); + for (guint i = 0; i < keys->len; i++) + { + key = keys->pdata[i]; + g_print ("%s\n", key); + } +} + +gboolean +ot_dump_summary_metadata_key (GBytes *summary_bytes, const char *key, GError **error) +{ + g_autoptr (GVariant) summary = NULL; + g_autoptr (GVariant) metadata = NULL; + g_autoptr (GVariant) value = NULL; + + summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE); + metadata = g_variant_get_child_value (summary, 1); + value = g_variant_lookup_value (metadata, key, NULL); + if (!value) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No such metadata key '%s'", key); + return FALSE; + } + + ot_dump_variant (value); + + return TRUE; +} + static gboolean -dump_gpg_subkey (GVariant *subkey, - gboolean primary, - GError **error) +dump_gpg_subkey (GVariant *subkey, gboolean primary, GError **error) { const gchar *fingerprint = NULL; gint64 created = 0; @@ -418,64 +459,53 @@ dump_gpg_subkey (GVariant *subkey, gboolean revoked = FALSE; gboolean expired = FALSE; gboolean invalid = FALSE; - (void) g_variant_lookup (subkey, "fingerprint", "&s", &fingerprint); - (void) g_variant_lookup (subkey, "created", "x", &created); - (void) g_variant_lookup (subkey, "expires", "x", &expires); - (void) g_variant_lookup (subkey, "revoked", "b", &revoked); - (void) g_variant_lookup (subkey, "expired", "b", &expired); - (void) g_variant_lookup (subkey, "invalid", "b", &invalid); + (void)g_variant_lookup (subkey, "fingerprint", "&s", &fingerprint); + (void)g_variant_lookup (subkey, "created", "x", &created); + (void)g_variant_lookup (subkey, "expires", "x", &expires); + (void)g_variant_lookup (subkey, "revoked", "b", &revoked); + (void)g_variant_lookup (subkey, "expired", "b", &expired); + (void)g_variant_lookup (subkey, "invalid", "b", &invalid); /* Convert timestamps from big endian if needed */ created = GINT64_FROM_BE (created); expires = GINT64_FROM_BE (expires); - g_print ("%s: %s%s%s\n", - primary ? "Key" : " Subkey", - fingerprint, - revoked ? " (revoked)" : "", + g_print ("%s: %s%s%s\n", primary ? "Key" : " Subkey", fingerprint, revoked ? " (revoked)" : "", invalid ? " (invalid)" : ""); - g_autofree gchar *created_str = format_timestamp (created, TRUE, - error); + g_autofree gchar *created_str = format_timestamp (created, TRUE, error); if (created_str == NULL) return FALSE; - g_print ("%sCreated: %s\n", - primary ? " " : " ", - created_str); + g_print ("%sCreated: %s\n", primary ? " " : " ", created_str); if (expires > 0) { - g_autofree gchar *expires_str = format_timestamp (expires, TRUE, - error); + g_autofree gchar *expires_str = format_timestamp (expires, TRUE, error); if (expires_str == NULL) return FALSE; - g_print ("%s%s: %s\n", - primary ? " " : " ", - expired ? "Expired" : "Expires", - expires_str); + g_print ("%s%s: %s\n", primary ? " " : " ", expired ? "Expired" : "Expires", expires_str); } return TRUE; } gboolean -ot_dump_gpg_key (GVariant *key, - GError **error) +ot_dump_gpg_key (GVariant *key, GError **error) { if (!g_variant_is_of_type (key, OSTREE_GPG_KEY_GVARIANT_FORMAT)) return glnx_throw (error, "GPG key variant type doesn't match '%s'", OSTREE_GPG_KEY_GVARIANT_STRING); - g_autoptr(GVariant) subkeys_v = g_variant_get_child_value (key, 0); + g_autoptr (GVariant) subkeys_v = g_variant_get_child_value (key, 0); GVariantIter subkeys_iter; g_variant_iter_init (&subkeys_iter, subkeys_v); - g_autoptr(GVariant) primary_key = NULL; + g_autoptr (GVariant) primary_key = NULL; g_variant_iter_next (&subkeys_iter, "@a{sv}", &primary_key); if (!dump_gpg_subkey (primary_key, TRUE, error)) return FALSE; - g_autoptr(GVariant) uids_v = g_variant_get_child_value (key, 1); + g_autoptr (GVariant) uids_v = g_variant_get_child_value (key, 1); GVariantIter uids_iter; g_variant_iter_init (&uids_iter, uids_v); GVariant *uid_v = NULL; @@ -484,18 +514,15 @@ ot_dump_gpg_key (GVariant *key, const gchar *uid = NULL; gboolean revoked = FALSE; gboolean invalid = FALSE; - (void) g_variant_lookup (uid_v, "uid", "&s", &uid); - (void) g_variant_lookup (uid_v, "revoked", "b", &revoked); - (void) g_variant_lookup (uid_v, "invalid", "b", &invalid); - g_print (" UID: %s%s%s\n", - uid, - revoked ? " (revoked)" : "", - invalid ? " (invalid)" : ""); + (void)g_variant_lookup (uid_v, "uid", "&s", &uid); + (void)g_variant_lookup (uid_v, "revoked", "b", &revoked); + (void)g_variant_lookup (uid_v, "invalid", "b", &invalid); + g_print (" UID: %s%s%s\n", uid, revoked ? " (revoked)" : "", invalid ? " (invalid)" : ""); const char *advanced_url = NULL; const char *direct_url = NULL; - (void) g_variant_lookup (uid_v, "advanced_url", "m&s", &advanced_url); - (void) g_variant_lookup (uid_v, "direct_url", "m&s", &direct_url); + (void)g_variant_lookup (uid_v, "advanced_url", "m&s", &advanced_url); + (void)g_variant_lookup (uid_v, "direct_url", "m&s", &direct_url); g_print (" Advanced update URL: %s\n", advanced_url ?: ""); g_print (" Direct update URL: %s\n", direct_url ?: ""); } diff --git a/src/ostree/ot-dump.h b/src/ostree/ot-dump.h index 217a396..8022e97 100644 --- a/src/ostree/ot-dump.h +++ b/src/ostree/ot-dump.h @@ -25,21 +25,22 @@ #include "ostree-core.h" -typedef enum { +typedef enum +{ OSTREE_DUMP_NONE = (1 << 0), OSTREE_DUMP_RAW = (1 << 1), OSTREE_DUMP_UNSWAPPED = (1 << 2), } OstreeDumpFlags; -void ot_dump_variant (GVariant *variant); +void ot_dump_variant (GVariant *variant); -void ot_dump_object (OstreeObjectType objtype, - const char *checksum, - GVariant *variant, - OstreeDumpFlags flags); +void ot_dump_object (OstreeObjectType objtype, const char *checksum, GVariant *variant, + OstreeDumpFlags flags); -void ot_dump_summary_bytes (GBytes *summary_bytes, - OstreeDumpFlags flags); +void ot_dump_summary_bytes (GBytes *summary_bytes, OstreeDumpFlags flags); -gboolean ot_dump_gpg_key (GVariant *key, - GError **error); +void ot_dump_summary_metadata_keys (GBytes *summary_bytes); + +gboolean ot_dump_summary_metadata_key (GBytes *summary_bytes, const char *key, GError **error); + +gboolean ot_dump_gpg_key (GVariant *key, GError **error); diff --git a/src/ostree/ot-editor.c b/src/ostree/ot-editor.c index f6e8e6a..7b2e251 100644 --- a/src/ostree/ot-editor.c +++ b/src/ostree/ot-editor.c @@ -22,11 +22,11 @@ #include "config.h" #include "libglnx.h" -#include "otutil.h" #include "ot-editor.h" +#include "otutil.h" -#include #include +#include #ifndef DEFAULT_EDITOR #define DEFAULT_EDITOR "vi" @@ -56,14 +56,11 @@ get_editor (void) } char * -ot_editor_prompt (OstreeRepo *repo, - const char *input, - GCancellable *cancellable, - GError **error) +ot_editor_prompt (OstreeRepo *repo, const char *input, GCancellable *cancellable, GError **error) { glnx_unref_object GSubprocess *proc = NULL; - g_autoptr(GFile) file = NULL; - g_autoptr(GFileIOStream) io = NULL; + g_autoptr (GFile) file = NULL; + g_autoptr (GFileIOStream) io = NULL; GOutputStream *output; const char *editor; char *ret = NULL; @@ -82,8 +79,8 @@ ot_editor_prompt (OstreeRepo *repo, goto out; output = g_io_stream_get_output_stream (G_IO_STREAM (io)); - if (!g_output_stream_write_all (output, input, strlen (input), NULL, cancellable, error) || - !g_io_stream_close (G_IO_STREAM (io), cancellable, error)) + if (!g_output_stream_write_all (output, input, strlen (input), NULL, cancellable, error) + || !g_io_stream_close (G_IO_STREAM (io), cancellable, error)) goto out; { @@ -91,8 +88,7 @@ ot_editor_prompt (OstreeRepo *repo, args = g_strconcat (editor, " ", quoted_file, NULL); } - proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_INHERIT, error, - "/bin/sh", "-c", args, NULL); + proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_INHERIT, error, "/bin/sh", "-c", args, NULL); if (!g_subprocess_wait_check (proc, cancellable, error)) { @@ -100,11 +96,11 @@ ot_editor_prompt (OstreeRepo *repo, goto out; } - ret = glnx_file_get_contents_utf8_at (AT_FDCWD, gs_file_get_path_cached (file), NULL, - cancellable, error); + ret = glnx_file_get_contents_utf8_at (AT_FDCWD, gs_file_get_path_cached (file), NULL, cancellable, + error); out: if (file) - (void )g_file_delete (file, NULL, NULL); + (void)g_file_delete (file, NULL, NULL); return ret; } diff --git a/src/ostree/ot-editor.h b/src/ostree/ot-editor.h index c096bed..eb65dd0 100644 --- a/src/ostree/ot-editor.h +++ b/src/ostree/ot-editor.h @@ -25,5 +25,5 @@ #include "ostree.h" -char * ot_editor_prompt (OstreeRepo *repo, const char *input, - GCancellable *cancellable, GError **error); +char *ot_editor_prompt (OstreeRepo *repo, const char *input, GCancellable *cancellable, + GError **error); diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index b7b50d6..59a3fcb 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -26,13 +26,12 @@ #include #include #include -#include #include -#include +#include -#include "ot-main.h" #include "ostree.h" #include "ot-admin-functions.h" +#include "ot-main.h" #include "otutil.h" static char *opt_repo; @@ -45,21 +44,25 @@ static gboolean opt_print_current_dir; // to find where to put files. Maybe we can make it printed by the CLI? #define _OSTREE_EXT_DIR PKGLIBEXECDIR "/ext" -static GOptionEntry global_entries[] = { - { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, "Print debug information during command processing", NULL }, - { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, "Print version information and exit", NULL }, - { NULL } -}; +static GOptionEntry global_entries[] + = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, + "Print debug information during command processing", NULL }, + { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, "Print version information and exit", + NULL }, + { NULL } }; -static GOptionEntry repo_entry[] = { - { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, "Path to OSTree repository (defaults to current directory or /sysroot/ostree/repo)", "PATH" }, - { NULL } -}; +static GOptionEntry repo_entry[] + = { { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, + "Path to OSTree repository (defaults to current directory or /sysroot/ostree/repo)", + "PATH" }, + { NULL } }; static GOptionEntry global_admin_entries[] = { /* No description since it's hidden from --help output. */ - { "print-current-dir", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_print_current_dir, NULL, NULL }, - { "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, "Create a new OSTree sysroot at PATH", "PATH" }, + { "print-current-dir", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_print_current_dir, NULL, + NULL }, + { "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, "Create a new OSTree sysroot at PATH", + "PATH" }, { NULL } }; @@ -68,7 +71,7 @@ ostree_option_context_new_with_commands (OstreeCommand *commands) { GOptionContext *context = g_option_context_new ("COMMAND"); - g_autoptr(GString) summary = g_string_new ("Builtin Commands:"); + g_autoptr (GString) summary = g_string_new ("Builtin Commands:"); while (commands->name != NULL) { @@ -76,7 +79,7 @@ ostree_option_context_new_with_commands (OstreeCommand *commands) { g_string_append_printf (summary, "\n %-18s", commands->name); - if (commands->description != NULL ) + if (commands->description != NULL) g_string_append_printf (summary, "%s", commands->description); } @@ -89,11 +92,9 @@ ostree_option_context_new_with_commands (OstreeCommand *commands) } int -ostree_usage (OstreeCommand *commands, - gboolean is_error) +ostree_usage (OstreeCommand *commands, gboolean is_error) { - g_autoptr(GOptionContext) context = - ostree_option_context_new_with_commands (commands); + g_autoptr (GOptionContext) context = ostree_option_context_new_with_commands (commands); g_option_context_add_main_entries (context, global_entries, NULL); g_autofree char *help = g_option_context_get_help (context, FALSE, NULL); @@ -110,8 +111,7 @@ ostree_usage (OstreeCommand *commands, * if so, and return *out_ns = TRUE. Otherwise, *out_ns = FALSE. */ static gboolean -maybe_setup_mount_namespace (gboolean *out_ns, - GError **error) +maybe_setup_mount_namespace (gboolean *out_ns, GError **error) { *out_ns = FALSE; @@ -133,9 +133,7 @@ maybe_setup_mount_namespace (gboolean *out_ns, } static void -message_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, +message_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { /* Make this look like normal console output */ @@ -146,11 +144,9 @@ message_handler (const gchar *log_domain, } int -ostree_main (int argc, - char **argv, - OstreeCommand *commands) +ostree_main (int argc, char **argv, OstreeCommand *commands) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; setlocale (LC_ALL, ""); @@ -160,16 +156,13 @@ ostree_main (int argc, if (error != NULL) { - g_printerr ("%s%serror:%s%s %s\n", - ot_get_red_start (), ot_get_bold_start (), - ot_get_bold_end (), ot_get_red_end (), - error->message); + g_printerr ("%s%serror:%s%s %s\n", ot_get_red_start (), ot_get_bold_start (), + ot_get_bold_end (), ot_get_red_end (), error->message); } return ret; } - /** * ostree_command_lookup_external: * @argc: number of entries in @argv @@ -184,9 +177,7 @@ ostree_main (int argc, * external command if found, or %NULL otherwise. */ gchar * -ostree_command_lookup_external (int argc, - char **argv, - OstreeCommand *commands) +ostree_command_lookup_external (int argc, char **argv, OstreeCommand *commands) { g_assert (commands != NULL); @@ -197,10 +188,9 @@ ostree_command_lookup_external (int argc, for (guint arg_index = 1; arg_index < argc; arg_index++) { char *current_arg = argv[arg_index]; - if (current_arg == NULL || - g_str_has_prefix (current_arg, "-") || - g_strcmp0 (current_arg, "") == 0) - continue; + if (current_arg == NULL || g_str_has_prefix (current_arg, "-") + || g_strcmp0 (current_arg, "") == 0) + continue; for (guint cmd_index = 0; commands[cmd_index].name != NULL; cmd_index++) { @@ -208,7 +198,6 @@ ostree_command_lookup_external (int argc, return NULL; } - g_autofree gchar *ext_command = g_strdup_printf ("ostree-%s", current_arg); /* First, search in our libdir /usr/lib/ostree/ostree-$cmd */ @@ -219,7 +208,7 @@ ostree_command_lookup_external (int argc, /* Otherwise, look in $PATH */ if (g_find_program_in_path (ext_command) == NULL) - return NULL; + return NULL; return g_steal_pointer (&ext_command); } @@ -237,23 +226,17 @@ ostree_command_lookup_external (int argc, int ostree_command_exec_external (char **argv) { - int r = execvp(argv[0], argv); + int r = execvp (argv[0], argv); g_assert (r == -1); setlocale (LC_ALL, ""); - g_printerr ("%s%serror:%s%s: Executing %s: %s\n", - ot_get_red_start (), ot_get_bold_start (), - ot_get_bold_end (), ot_get_red_end (), - argv[0], - g_strerror (errno)); + g_printerr ("%s%serror:%s%s: Executing %s: %s\n", ot_get_red_start (), ot_get_bold_start (), + ot_get_bold_end (), ot_get_red_end (), argv[0], g_strerror (errno)); return 1; } int -ostree_run (int argc, - char **argv, - OstreeCommand *commands, - GError **res_error) +ostree_run (int argc, char **argv, OstreeCommand *commands, GError **res_error) { GError *error = NULL; GCancellable *cancellable = NULL; @@ -267,7 +250,7 @@ ostree_run (int argc, /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ if (!g_setenv ("GIO_USE_VFS", "local", TRUE)) { - (void) glnx_throw (res_error, "Failed to set environment variable GIO_USE_FVS"); + (void)glnx_throw (res_error, "Failed to set environment variable GIO_USE_FVS"); return 1; } @@ -307,21 +290,20 @@ ostree_run (int argc, if (!command->fn) { - g_autoptr(GOptionContext) context = - ostree_option_context_new_with_commands (commands); + g_autoptr (GOptionContext) context = ostree_option_context_new_with_commands (commands); /* This will not return for some options (e.g. --version). */ - if (ostree_option_context_parse (context, NULL, &argc, &argv, NULL, NULL, cancellable, &error)) + if (ostree_option_context_parse (context, NULL, &argc, &argv, NULL, NULL, cancellable, + &error)) { if (command_name == NULL) { - g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No command specified"); + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "No command specified"); } else { - g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown command '%s'", command_name); + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown command '%s'", + command_name); } } @@ -338,7 +320,7 @@ ostree_run (int argc, goto out; success = TRUE; - out: +out: g_assert (success || error); if (error) @@ -351,17 +333,14 @@ ostree_run (int argc, /* Process a --repo arg. */ static OstreeRepo * -parse_repo_option (GOptionContext *context, - const char *repo_path, - gboolean skip_repo_open, - GCancellable *cancellable, - GError **error) +parse_repo_option (GOptionContext *context, const char *repo_path, gboolean skip_repo_open, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (OstreeRepo) repo = NULL; if (repo_path == NULL) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; repo = ostree_repo_new_default (); if (!ostree_repo_open (repo, cancellable, &local_error)) @@ -385,7 +364,7 @@ parse_repo_option (GOptionContext *context, } else { - g_autoptr(GFile) repo_file = g_file_new_for_path (repo_path); + g_autoptr (GFile) repo_file = g_file_new_for_path (repo_path); repo = ostree_repo_new (repo_file); if (!skip_repo_open) @@ -398,15 +377,15 @@ parse_repo_option (GOptionContext *context, return g_steal_pointer (&repo); } -/* Process a --repo arg, determining if we should remount /sysroot; used below, and for the remote builtins */ +/* Process a --repo arg, determining if we should remount /sysroot; used below, and for the remote + * builtins */ static OstreeRepo * -parse_repo_option_and_maybe_remount (GOptionContext *context, - const char *repo_path, - gboolean skip_repo_open, - GCancellable *cancellable, - GError **error) +parse_repo_option_and_maybe_remount (GOptionContext *context, const char *repo_path, + gboolean skip_repo_open, GCancellable *cancellable, + GError **error) { - g_autoptr(OstreeRepo) repo = parse_repo_option (context, repo_path, skip_repo_open, cancellable, error); + g_autoptr (OstreeRepo) repo + = parse_repo_option (context, repo_path, skip_repo_open, cancellable, error); if (!repo) return NULL; @@ -437,19 +416,16 @@ parse_repo_option_and_maybe_remount (GOptionContext *context, /* Used by the remote builtins which are special in taking --sysroot or --repo */ gboolean -ostree_parse_sysroot_or_repo_option (GOptionContext *context, - const char *sysroot_path, - const char *repo_path, - OstreeSysroot **out_sysroot, - OstreeRepo **out_repo, - GCancellable *cancellable, +ostree_parse_sysroot_or_repo_option (GOptionContext *context, const char *sysroot_path, + const char *repo_path, OstreeSysroot **out_sysroot, + OstreeRepo **out_repo, GCancellable *cancellable, GError **error) { - g_autoptr(OstreeSysroot) sysroot = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeRepo) repo = NULL; if (sysroot_path) { - g_autoptr(GFile) sysroot_file = g_file_new_for_path (sysroot_path); + g_autoptr (GFile) sysroot_file = g_file_new_for_path (sysroot_path); sysroot = ostree_sysroot_new (sysroot_file); if (!ostree_sysroot_load (sysroot, cancellable, error)) return FALSE; @@ -469,18 +445,14 @@ ostree_parse_sysroot_or_repo_option (GOptionContext *context, } gboolean -ostree_option_context_parse (GOptionContext *context, - const GOptionEntry *main_entries, - int *argc, - char ***argv, - OstreeCommandInvocation *invocation, - OstreeRepo **out_repo, - GCancellable *cancellable, - GError **error) +ostree_option_context_parse (GOptionContext *context, const GOptionEntry *main_entries, int *argc, + char ***argv, OstreeCommandInvocation *invocation, + OstreeRepo **out_repo, GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (OstreeRepo) repo = NULL; /* When invocation is NULL, do not fetch repo */ - const OstreeBuiltinFlags flags = invocation ? invocation->command->flags : OSTREE_BUILTIN_FLAG_NO_REPO; + const OstreeBuiltinFlags flags + = invocation ? invocation->command->flags : OSTREE_BUILTIN_FLAG_NO_REPO; if (invocation && invocation->command->description != NULL) { @@ -496,9 +468,10 @@ ostree_option_context_parse (GOptionContext *context, { /* TODO: remove this part once we deduplicate the ostree_option_context_new_with_commands * function from other root commands( command with subcommands). Because - * we can directly add the summary inside the ostree_option_context_new_with_commands function. + * we can directly add the summary inside the ostree_option_context_new_with_commands + * function. */ - g_autoptr(GString) new_summary_string = g_string_new (context_summary); + g_autoptr (GString) new_summary_string = g_string_new (context_summary); g_string_prepend (new_summary_string, "\n\n"); g_string_prepend (new_summary_string, invocation->command->description); @@ -540,7 +513,7 @@ ostree_option_context_parse (GOptionContext *context, { /* This should now be YAML, like `docker version`, so it's both nice to read * possible to parse */ - g_auto(GStrv) features = g_strsplit (OSTREE_FEATURES, " ", -1); + g_auto (GStrv) features = g_strsplit (OSTREE_FEATURES, " ", -1); g_print ("%s:\n", PACKAGE_NAME); g_print (" Version: '%s'\n", PACKAGE_VERSION); if (strlen (OSTREE_GITREV) > 0) @@ -559,8 +532,8 @@ ostree_option_context_parse (GOptionContext *context, if (!(flags & OSTREE_BUILTIN_FLAG_NO_REPO)) { - repo = parse_repo_option_and_maybe_remount (context, opt_repo, (flags & OSTREE_BUILTIN_FLAG_NO_CHECK) > 0, - cancellable, error); + repo = parse_repo_option_and_maybe_remount ( + context, opt_repo, (flags & OSTREE_BUILTIN_FLAG_NO_CHECK) > 0, cancellable, error); if (!repo) return FALSE; } @@ -572,68 +545,20 @@ ostree_option_context_parse (GOptionContext *context, } static void -on_sysroot_journal_msg (OstreeSysroot *sysroot, - const char *msg, - void *dummy) +on_sysroot_journal_msg (OstreeSysroot *sysroot, const char *msg, void *dummy) { g_print ("%s\n", msg); } gboolean -ostree_admin_option_context_parse (GOptionContext *context, - const GOptionEntry *main_entries, - int *argc, - char ***argv, - OstreeAdminBuiltinFlags flags, - OstreeCommandInvocation *invocation, - OstreeSysroot **out_sysroot, - GCancellable *cancellable, - GError **error) +ostree_admin_sysroot_load (OstreeSysroot *sysroot, OstreeAdminBuiltinFlags flags, + GCancellable *cancellable, GError **error) { - /* Entries are listed in --help output in the order added. We add the - * main entries ourselves so that we can add the --sysroot entry first. */ - - g_option_context_add_main_entries (context, global_admin_entries, NULL); - - if (!ostree_option_context_parse (context, main_entries, argc, argv, - invocation, NULL, cancellable, error)) - return FALSE; - - if (!opt_print_current_dir && (flags & OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT)) - { - g_assert_null (out_sysroot); - /* Early return if no sysroot is requested */ - return TRUE; - } - - g_autoptr(GFile) sysroot_path = NULL; - if (opt_sysroot != NULL) - sysroot_path = g_file_new_for_path (opt_sysroot); - - g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path); - if (!ostree_sysroot_initialize (sysroot, error)) - return FALSE; - g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL); - if ((flags & OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED) == 0) { - /* If we're requested to lock the sysroot, first check if we're operating - * on a booted (not physical) sysroot. Then find out if the /sysroot - * subdir is a read-only mount point, and if so, create a new mount - * namespace and tell the sysroot that we've done so. See the docs for - * ostree_sysroot_set_mount_namespace_in_use(). - * - * This is a conservative approach; we could just always - * unshare() too. - */ - if (ostree_sysroot_is_booted (sysroot)) - { - gboolean setup_ns = FALSE; - if (!maybe_setup_mount_namespace (&setup_ns, error)) - return FALSE; - if (setup_ns) - ostree_sysroot_set_mount_namespace_in_use (sysroot); - } + /* Set up the mount namespace, if applicable */ + if (!ostree_sysroot_initialize_with_mount_namespace (sysroot, cancellable, error)) + return FALSE; /* Released when sysroot is finalized, or on process exit */ if (!ot_admin_sysroot_lock (sysroot, error)) @@ -658,11 +583,51 @@ ostree_admin_option_context_parse (GOptionContext *context, } } + return TRUE; +} + +gboolean +ostree_admin_option_context_parse (GOptionContext *context, const GOptionEntry *main_entries, + int *argc, char ***argv, OstreeAdminBuiltinFlags flags, + OstreeCommandInvocation *invocation, OstreeSysroot **out_sysroot, + GCancellable *cancellable, GError **error) +{ + /* Entries are listed in --help output in the order added. We add the + * main entries ourselves so that we can add the --sysroot entry first. */ + + g_option_context_add_main_entries (context, global_admin_entries, NULL); + + if (!ostree_option_context_parse (context, main_entries, argc, argv, invocation, NULL, + cancellable, error)) + return FALSE; + + if (!opt_print_current_dir && (flags & OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT)) + { + g_assert_null (out_sysroot); + /* Early return if no sysroot is requested */ + return TRUE; + } + + g_autoptr (GFile) sysroot_path = NULL; + if (opt_sysroot != NULL) + sysroot_path = g_file_new_for_path (opt_sysroot); + + g_autoptr (OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path); + if (!ostree_sysroot_initialize (sysroot, error)) + return FALSE; + g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL); + + if (opt_print_current_dir || (flags & OSTREE_ADMIN_BUILTIN_FLAG_NO_LOAD) == 0) + { + if (!ostree_admin_sysroot_load (sysroot, flags, cancellable, error)) + return FALSE; + } + if (opt_print_current_dir) { - g_autoptr(GPtrArray) deployments = NULL; + g_autoptr (GPtrArray) deployments = NULL; OstreeDeployment *first_deployment; - g_autoptr(GFile) deployment_file = NULL; + g_autoptr (GFile) deployment_file = NULL; g_autofree char *deployment_path = NULL; deployments = ostree_sysroot_get_deployments (sysroot); @@ -691,8 +656,7 @@ ostree_admin_option_context_parse (GOptionContext *context, } gboolean -ostree_ensure_repo_writable (OstreeRepo *repo, - GError **error) +ostree_ensure_repo_writable (OstreeRepo *repo, GError **error) { if (!ostree_repo_is_writable (repo, error)) return glnx_prefix_error (error, "Cannot write to repository"); @@ -706,10 +670,9 @@ ostree_print_gpg_verify_result (OstreeGpgVerifyResult *result) guint n_sigs = ostree_gpg_verify_result_count_all (result); /* XXX If we ever add internationalization, use ngettext() here. */ - g_print ("GPG: Verification enabled, found %u signature%s:\n", - n_sigs, n_sigs == 1 ? "" : "s"); + g_print ("GPG: Verification enabled, found %u signature%s:\n", n_sigs, n_sigs == 1 ? "" : "s"); - g_autoptr(GString) buffer = g_string_sized_new (256); + g_autoptr (GString) buffer = g_string_sized_new (256); for (guint ii = 0; ii < n_sigs; ii++) { @@ -729,7 +692,8 @@ ot_enable_tombstone_commits (OstreeRepo *repo, GError **error) GKeyFile *config = ostree_repo_get_config (repo); tombstone_commits = g_key_file_get_boolean (config, "core", "tombstone-commits", NULL); - /* tombstone_commits is FALSE either if it is not found or it is really set to FALSE in the config file. */ + /* tombstone_commits is FALSE either if it is not found or it is really set to FALSE in the + * config file. */ if (!tombstone_commits) { g_key_file_set_boolean (config, "core", "tombstone-commits", TRUE); diff --git a/src/ostree/ot-main.h b/src/ostree/ot-main.h index b369deb..8df1ca8 100644 --- a/src/ostree/ot-main.h +++ b/src/ostree/ot-main.h @@ -24,27 +24,31 @@ #include "libglnx.h" #include "ostree.h" -typedef enum { +typedef enum +{ OSTREE_BUILTIN_FLAG_NONE = 0, OSTREE_BUILTIN_FLAG_NO_REPO = 1 << 0, OSTREE_BUILTIN_FLAG_NO_CHECK = 1 << 1, OSTREE_BUILTIN_FLAG_HIDDEN = 1 << 2, } OstreeBuiltinFlags; -typedef enum { +typedef enum +{ OSTREE_ADMIN_BUILTIN_FLAG_NONE = 0, OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER = (1 << 0), OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED = (1 << 1), OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT = (1 << 2), + OSTREE_ADMIN_BUILTIN_FLAG_NO_LOAD = (1 << 3), } OstreeAdminBuiltinFlags; - typedef struct OstreeCommandInvocation OstreeCommandInvocation; -typedef struct { +typedef struct +{ const char *name; OstreeBuiltinFlags flags; - gboolean (*fn) (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error); + gboolean (*fn) (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error); const char *description; } OstreeCommand; @@ -54,7 +58,8 @@ typedef struct { * In the future if we want to add something new we won't need to * touch every prototype */ -struct OstreeCommandInvocation { +struct OstreeCommandInvocation +{ OstreeCommand *command; }; @@ -64,32 +69,29 @@ int ostree_run (int argc, char **argv, OstreeCommand *commands, GError **error); int ostree_usage (OstreeCommand *commands, gboolean is_error); -char* ostree_command_lookup_external (int argc, char **argv, OstreeCommand *commands); +char *ostree_command_lookup_external (int argc, char **argv, OstreeCommand *commands); int ostree_command_exec_external (char **argv); -gboolean ostree_parse_sysroot_or_repo_option (GOptionContext *context, - const char *sysroot_path, - const char *repo_path, - OstreeSysroot **out_sysroot, - OstreeRepo **out_repo, - GCancellable *cancellable, +gboolean ostree_parse_sysroot_or_repo_option (GOptionContext *context, const char *sysroot_path, + const char *repo_path, OstreeSysroot **out_sysroot, + OstreeRepo **out_repo, GCancellable *cancellable, GError **error); -gboolean ostree_option_context_parse (GOptionContext *context, - const GOptionEntry *main_entries, - int *argc, char ***argv, - OstreeCommandInvocation *invocation, - OstreeRepo **out_repo, - GCancellable *cancellable, GError **error); +gboolean ostree_option_context_parse (GOptionContext *context, const GOptionEntry *main_entries, + int *argc, char ***argv, OstreeCommandInvocation *invocation, + OstreeRepo **out_repo, GCancellable *cancellable, + GError **error); gboolean ostree_admin_option_context_parse (GOptionContext *context, - const GOptionEntry *main_entries, - int *argc, char ***argv, - OstreeAdminBuiltinFlags flags, + const GOptionEntry *main_entries, int *argc, + char ***argv, OstreeAdminBuiltinFlags flags, OstreeCommandInvocation *invocation, - OstreeSysroot **out_sysroot, - GCancellable *cancellable, GError **error); + OstreeSysroot **out_sysroot, GCancellable *cancellable, + GError **error); + +gboolean ostree_admin_sysroot_load (OstreeSysroot *sysroot, OstreeAdminBuiltinFlags flags, + GCancellable *cancellable, GError **error); gboolean ostree_ensure_repo_writable (OstreeRepo *repo, GError **error); @@ -98,16 +100,17 @@ void ostree_print_gpg_verify_result (OstreeGpgVerifyResult *result); gboolean ot_enable_tombstone_commits (OstreeRepo *repo, GError **error); /* Copied from rpm-ostree's rpmostree-libbuiltin.h */ -#define TERM_ESCAPE_SEQUENCE(type,seq) \ - static inline const char* ot_get_##type (void) { \ - if (glnx_stdout_is_tty ()) \ - return seq; \ - return ""; \ +#define TERM_ESCAPE_SEQUENCE(type, seq) \ + static inline const char *ot_get_##type (void) \ + { \ + if (glnx_stdout_is_tty ()) \ + return seq; \ + return ""; \ } -TERM_ESCAPE_SEQUENCE(red_start, "\x1b[31m") -TERM_ESCAPE_SEQUENCE(red_end, "\x1b[22m") -TERM_ESCAPE_SEQUENCE(bold_start, "\x1b[1m") -TERM_ESCAPE_SEQUENCE(bold_end, "\x1b[0m") +TERM_ESCAPE_SEQUENCE (red_start, "\x1b[31m") +TERM_ESCAPE_SEQUENCE (red_end, "\x1b[22m") +TERM_ESCAPE_SEQUENCE (bold_start, "\x1b[1m") +TERM_ESCAPE_SEQUENCE (bold_end, "\x1b[0m") #undef TERM_ESCAPE_SEQUENCE diff --git a/src/ostree/ot-remote-builtin-add-cookie.c b/src/ostree/ot-remote-builtin-add-cookie.c index 30aeacb..900520d 100644 --- a/src/ostree/ot-remote-builtin-add-cookie.c +++ b/src/ostree/ot-remote-builtin-add-cookie.c @@ -22,9 +22,9 @@ #include "otutil.h" +#include "ostree-repo-private.h" #include "ot-main.h" #include "ot-remote-builtins.h" -#include "ostree-repo-private.h" #include "ot-remote-cookie-util.h" /* ATTENTION: @@ -32,22 +32,22 @@ * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { NULL } -}; +static GOptionEntry option_entries[] = { { NULL } }; gboolean -ot_remote_builtin_add_cookie (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_add_cookie (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("NAME DOMAIN PATH COOKIE_NAME VALUE"); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new ("NAME DOMAIN PATH COOKIE_NAME VALUE"); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (argc < 6) { - ot_util_usage_error (context, "NAME, DOMAIN, PATH, COOKIE_NAME and VALUE must be specified", error); + ot_util_usage_error (context, "NAME, DOMAIN, PATH, COOKIE_NAME and VALUE must be specified", + error); return FALSE; } @@ -57,7 +57,8 @@ ot_remote_builtin_add_cookie (int argc, char **argv, OstreeCommandInvocation *in const char *cookie_name = argv[4]; const char *value = argv[5]; g_autofree char *cookie_file = g_strdup_printf ("%s.cookies.txt", remote_name); - if (!ot_add_cookie_at (ostree_repo_get_dfd (repo), cookie_file, domain, path, cookie_name, value, error)) + if (!ot_add_cookie_at (ostree_repo_get_dfd (repo), cookie_file, domain, path, cookie_name, value, + error)) return FALSE; return TRUE; diff --git a/src/ostree/ot-remote-builtin-add.c b/src/ostree/ot-remote-builtin-add.c index f07005f..7fd157b 100644 --- a/src/ostree/ot-remote-builtin-add.c +++ b/src/ostree/ot-remote-builtin-add.c @@ -42,41 +42,52 @@ static char *opt_repo; * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { "set", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, "Set config option KEY=VALUE for remote", "KEY=VALUE" }, - { "no-gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_no_gpg_verify, "Disable GPG verification", NULL }, - { "no-sign-verify", 0, 0, G_OPTION_ARG_NONE, &opt_no_sign_verify, "Disable signature verification", NULL }, - { "sign-verify", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_sign_verify, "Verify signatures using KEYTYPE=inline:PUBKEY or KEYTYPE=file:/path/to/key", "KEYTYPE=[inline|file]:PUBKEY" }, - { "if-not-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_not_exists, "Do nothing if the provided remote exists", NULL }, - { "force", 0, 0, G_OPTION_ARG_NONE, &opt_force, "Replace the provided remote if it exists", NULL }, - { "gpg-import", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_import, "Import GPG key from FILE", "FILE" }, - { "custom-backend", 0, 0, G_OPTION_ARG_STRING, &opt_custom_backend, "This remote has content not fetched via libostree", "NAME" }, - { "contenturl", 0, 0, G_OPTION_ARG_STRING, &opt_contenturl, "Use URL when fetching content", "URL" }, - { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, - "Globally unique ID for this repository as an collection of refs for redistribution to other repositories", "COLLECTION-ID" }, - { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" }, - { "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, "Use sysroot at PATH (overrides --repo)", "PATH" }, - { NULL } -}; +static GOptionEntry option_entries[] + = { { "set", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, + "Set config option KEY=VALUE for remote", "KEY=VALUE" }, + { "no-gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_no_gpg_verify, "Disable GPG verification", + NULL }, + { "no-sign-verify", 0, 0, G_OPTION_ARG_NONE, &opt_no_sign_verify, + "Disable signature verification", NULL }, + { "sign-verify", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_sign_verify, + "Verify signatures using KEYTYPE=inline:PUBKEY or KEYTYPE=file:/path/to/key", + "KEYTYPE=[inline|file]:PUBKEY" }, + { "if-not-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_not_exists, + "Do nothing if the provided remote exists", NULL }, + { "force", 0, 0, G_OPTION_ARG_NONE, &opt_force, "Replace the provided remote if it exists", + NULL }, + { "gpg-import", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_import, "Import GPG key from FILE", + "FILE" }, + { "custom-backend", 0, 0, G_OPTION_ARG_STRING, &opt_custom_backend, + "This remote has content not fetched via libostree", "NAME" }, + { "contenturl", 0, 0, G_OPTION_ARG_STRING, &opt_contenturl, "Use URL when fetching content", + "URL" }, + { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, + "Globally unique ID for this repository as an collection of refs for redistribution to " + "other repositories", + "COLLECTION-ID" }, + { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, + "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" }, + { "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, + "Use sysroot at PATH (overrides --repo)", "PATH" }, + { NULL } }; static char * -add_verify_opt (GVariantBuilder *builder, - const char *keyspec, - GError **error) +add_verify_opt (GVariantBuilder *builder, const char *keyspec, GError **error) { - g_auto(GStrv) parts = g_strsplit (keyspec, "=", 2); + g_auto (GStrv) parts = g_strsplit (keyspec, "=", 2); g_assert (parts && *parts); const char *keytype = parts[0]; if (!parts[1]) return glnx_null_throw (error, "Failed to parse KEYTYPE=[inline|file]:DATA in %s", keyspec); - g_autoptr(OstreeSign) sign = ostree_sign_get_by_name (keytype, error); + g_autoptr (OstreeSign) sign = ostree_sign_get_by_name (keytype, error); if (!sign) return NULL; const char *rest = parts[1]; g_assert (!parts[2]); - g_auto(GStrv) keyparts = g_strsplit (rest, ":", 2); + g_auto (GStrv) keyparts = g_strsplit (rest, ":", 2); g_assert (keyparts && *keyparts); const char *keyref = keyparts[0]; g_assert (keyref); @@ -89,42 +100,34 @@ add_verify_opt (GVariantBuilder *builder, return glnx_null_throw (error, "Invalid key reference %s, expected inline|file", keyref); g_assert (keyparts[1] && !keyparts[2]); - g_variant_builder_add (builder, "{s@v}", - optname, + g_variant_builder_add (builder, "{s@v}", optname, g_variant_new_variant (g_variant_new_string (keyparts[1]))); return g_strdup (ostree_sign_get_name (sign)); } gboolean -ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeSysroot) sysroot = NULL; - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GString) sign_verify = NULL; - const char *remote_name; - const char *remote_url = NULL; - g_autoptr(GVariantBuilder) optbuilder = NULL; - g_autoptr(GVariant) options = NULL; - gboolean ret = FALSE; - - context = g_option_context_new ("NAME [metalink=|mirrorlist=]URL [BRANCH...]"); - - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, NULL, cancellable, error)) - goto out; - - if (!ostree_parse_sysroot_or_repo_option (context, opt_sysroot, opt_repo, - &sysroot, &repo, + g_autoptr (GOptionContext) context + = g_option_context_new ("NAME [metalink=|mirrorlist=]URL [BRANCH...]"); + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, NULL, + cancellable, error)) + return FALSE; + + g_autoptr (OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_parse_sysroot_or_repo_option (context, opt_sysroot, opt_repo, &sysroot, &repo, cancellable, error)) - goto out; + return FALSE; + const char *remote_url = NULL; if (opt_custom_backend) { if (argc < 2) { ot_util_usage_error (context, "NAME must be specified", error); - goto out; + return FALSE; } if (argc >= 3) remote_url = argv[2]; @@ -134,34 +137,30 @@ ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocatio if (argc < 3) { ot_util_usage_error (context, "NAME and URL must be specified", error); - goto out; + return FALSE; } remote_url = argv[2]; } - remote_name = argv[1]; + const char *remote_name = argv[1]; if (opt_if_not_exists && opt_force) { - ot_util_usage_error (context, - "Can only specify one of --if-not-exists and --force", - error); - goto out; + ot_util_usage_error (context, "Can only specify one of --if-not-exists and --force", error); + return FALSE; } - optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); if (argc > 3) { - g_autoptr(GPtrArray) branchesp = g_ptr_array_new (); - int i; - - for (i = 3; i < argc; i++) + g_autoptr (GPtrArray) branchesp = g_ptr_array_new (); + for (int i = 3; i < argc; i++) g_ptr_array_add (branchesp, argv[i]); g_ptr_array_add (branchesp, NULL); - g_variant_builder_add (optbuilder, "{s@v}", - "branches", - g_variant_new_variant (g_variant_new_strv ((const char*const*)branchesp->pdata, -1))); + g_variant_builder_add ( + optbuilder, "{s@v}", "branches", + g_variant_new_variant (g_variant_new_strv ((const char *const *)branchesp->pdata, -1))); } /* We could just make users use --set instead for this since it's a string, @@ -169,11 +168,11 @@ ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocatio * --set=contenturl=mirrorlist=... */ if (opt_contenturl != NULL) - g_variant_builder_add (optbuilder, "{s@v}", - "contenturl", g_variant_new_variant (g_variant_new_string (opt_contenturl))); + g_variant_builder_add (optbuilder, "{s@v}", "contenturl", + g_variant_new_variant (g_variant_new_string (opt_contenturl))); if (opt_custom_backend != NULL) - g_variant_builder_add (optbuilder, "{s@v}", - "custom-backend", g_variant_new_variant (g_variant_new_string (opt_custom_backend))); + g_variant_builder_add (optbuilder, "{s@v}", "custom-backend", + g_variant_new_variant (g_variant_new_string (opt_custom_backend))); for (char **iter = opt_set; iter && *iter; iter++) { @@ -182,17 +181,16 @@ ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocatio g_autofree char *subvalue = NULL; if (!ot_parse_keyvalue (keyvalue, &subkey, &subvalue, error)) - goto out; + return FALSE; - g_variant_builder_add (optbuilder, "{s@v}", - subkey, g_variant_new_variant (g_variant_new_string (subvalue))); + g_variant_builder_add (optbuilder, "{s@v}", subkey, + g_variant_new_variant (g_variant_new_string (subvalue))); } #ifndef OSTREE_DISABLE_GPGME /* No signature verification implies no verification for GPG signature as well */ if (opt_no_gpg_verify || opt_no_sign_verify) - g_variant_builder_add (optbuilder, "{s@v}", - "gpg-verify", + g_variant_builder_add (optbuilder, "{s@v}", "gpg-verify", g_variant_new_variant (g_variant_new_boolean (FALSE))); #endif /* OSTREE_DISABLE_GPGME */ @@ -200,11 +198,11 @@ ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocatio { if (opt_sign_verify) return glnx_throw (error, "Cannot specify both --sign-verify and --no-sign-verify"); - g_variant_builder_add (optbuilder, "{s@v}", - "sign-verify", - g_variant_new_variant (g_variant_new_boolean (FALSE))); + g_variant_builder_add (optbuilder, "{s@v}", "sign-verify", + g_variant_new_variant (g_variant_new_boolean (FALSE))); } + g_autoptr (GString) sign_verify = NULL; for (char **iter = opt_sign_verify; iter && *iter; iter++) { const char *keyspec = *iter; @@ -222,15 +220,15 @@ ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocatio } } if (sign_verify != NULL) - g_variant_builder_add (optbuilder, "{s@v}", - "sign-verify", - g_variant_new_variant (g_variant_new_string (sign_verify->str))); + g_variant_builder_add (optbuilder, "{s@v}", "sign-verify", + g_variant_new_variant (g_variant_new_string (sign_verify->str))); if (opt_collection_id != NULL) - g_variant_builder_add (optbuilder, "{s@v}", "collection-id", - g_variant_new_variant (g_variant_new_take_string (g_steal_pointer (&opt_collection_id)))); + g_variant_builder_add ( + optbuilder, "{s@v}", "collection-id", + g_variant_new_variant (g_variant_new_take_string (g_steal_pointer (&opt_collection_id)))); - options = g_variant_ref_sink (g_variant_builder_end (optbuilder)); + g_autoptr (GVariant) options = g_variant_ref_sink (g_variant_builder_end (optbuilder)); OstreeRepoRemoteChange changeop; if (opt_if_not_exists) @@ -239,11 +237,9 @@ ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocatio changeop = OSTREE_REPO_REMOTE_CHANGE_REPLACE; else changeop = OSTREE_REPO_REMOTE_CHANGE_ADD; - if (!ostree_repo_remote_change (repo, NULL, changeop, - remote_name, remote_url, - options, + if (!ostree_repo_remote_change (repo, NULL, changeop, remote_name, remote_url, options, cancellable, error)) - goto out; + return FALSE; #ifndef OSTREE_DISABLE_GPGME /* This is just a convenience option and is not as flexible as the full @@ -254,27 +250,25 @@ ot_remote_builtin_add (int argc, char **argv, OstreeCommandInvocation *invocatio * know whether the remote already existed. We import regardless. */ if (opt_gpg_import != NULL) { - g_autoptr(GFile) file = NULL; - g_autoptr(GInputStream) input_stream = NULL; + g_autoptr (GFile) file = NULL; + g_autoptr (GInputStream) input_stream = NULL; guint imported = 0; file = g_file_new_for_path (opt_gpg_import); - input_stream = (GInputStream *) g_file_read (file, cancellable, error); + input_stream = (GInputStream *)g_file_read (file, cancellable, error); if (input_stream == NULL) - goto out; + return FALSE; - if (!ostree_repo_remote_gpg_import (repo, remote_name, input_stream, - NULL, &imported, cancellable, error)) - goto out; + if (!ostree_repo_remote_gpg_import (repo, remote_name, input_stream, NULL, &imported, + cancellable, error)) + return FALSE; /* XXX If we ever add internationalization, use ngettext() here. */ - g_print ("Imported %u GPG key%s to remote \"%s\"\n", - imported, (imported == 1) ? "" : "s", remote_name); + g_print ("Imported %u GPG key%s to remote \"%s\"\n", imported, (imported == 1) ? "" : "s", + remote_name); } #endif /* OSTREE_DISABLE_GPGME */ - ret = TRUE; - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-remote-builtin-delete-cookie.c b/src/ostree/ot-remote-builtin-delete-cookie.c index 0c22caa..f79854e 100644 --- a/src/ostree/ot-remote-builtin-delete-cookie.c +++ b/src/ostree/ot-remote-builtin-delete-cookie.c @@ -23,9 +23,9 @@ #include "otutil.h" #include +#include "ostree-repo-private.h" #include "ot-main.h" #include "ot-remote-builtins.h" -#include "ostree-repo-private.h" #include "ot-remote-cookie-util.h" /* ATTENTION: @@ -33,18 +33,17 @@ * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { NULL } -}; +static GOptionEntry option_entries[] = { { NULL } }; gboolean -ot_remote_builtin_delete_cookie (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_delete_cookie (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GOptionContext) context = g_option_context_new ("NAME DOMAIN PATH COOKIE_NAME"); + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = g_option_context_new ("NAME DOMAIN PATH COOKIE_NAME"); - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (argc < 5) @@ -58,7 +57,8 @@ ot_remote_builtin_delete_cookie (int argc, char **argv, OstreeCommandInvocation const char *path = argv[3]; const char *cookie_name = argv[4]; g_autofree char *cookie_file = g_strdup_printf ("%s.cookies.txt", remote_name); - if (!ot_delete_cookie_at (ostree_repo_get_dfd (repo), cookie_file, domain, path, cookie_name, error)) + if (!ot_delete_cookie_at (ostree_repo_get_dfd (repo), cookie_file, domain, path, cookie_name, + error)) return FALSE; return TRUE; diff --git a/src/ostree/ot-remote-builtin-delete.c b/src/ostree/ot-remote-builtin-delete.c index eb60783..e5e310f 100644 --- a/src/ostree/ot-remote-builtin-delete.c +++ b/src/ostree/ot-remote-builtin-delete.c @@ -33,27 +33,29 @@ static char *opt_repo; * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { "if-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_exists, "Do nothing if the provided remote does not exist", NULL }, - { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" }, - { "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, "Use sysroot at PATH (overrides --repo)", "PATH" }, - { NULL } -}; +static GOptionEntry option_entries[] + = { { "if-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_exists, + "Do nothing if the provided remote does not exist", NULL }, + { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, + "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" }, + { "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, + "Use sysroot at PATH (overrides --repo)", "PATH" }, + { NULL } }; gboolean -ot_remote_builtin_delete (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_delete (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("NAME"); + g_autoptr (GOptionContext) context = g_option_context_new ("NAME"); - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, NULL, cancellable, error)) + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, NULL, + cancellable, error)) return FALSE; - g_autoptr(OstreeSysroot) sysroot = NULL; - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_parse_sysroot_or_repo_option (context, opt_sysroot, opt_repo, - &sysroot, &repo, + g_autoptr (OstreeSysroot) sysroot = NULL; + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_parse_sysroot_or_repo_option (context, opt_sysroot, opt_repo, &sysroot, &repo, cancellable, error)) return FALSE; @@ -66,10 +68,9 @@ ot_remote_builtin_delete (int argc, char **argv, OstreeCommandInvocation *invoca const char *remote_name = argv[1]; if (!ostree_repo_remote_change (repo, NULL, - opt_if_exists ? OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS : - OSTREE_REPO_REMOTE_CHANGE_DELETE, - remote_name, NULL, NULL, - cancellable, error)) + opt_if_exists ? OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS + : OSTREE_REPO_REMOTE_CHANGE_DELETE, + remote_name, NULL, NULL, cancellable, error)) return FALSE; return TRUE; diff --git a/src/ostree/ot-remote-builtin-gpg-import.c b/src/ostree/ot-remote-builtin-gpg-import.c index ba4aa3b..0d9744e 100644 --- a/src/ostree/ot-remote-builtin-gpg-import.c +++ b/src/ostree/ot-remote-builtin-gpg-import.c @@ -19,8 +19,8 @@ #include "config.h" -#include #include +#include #include "otutil.h" @@ -38,18 +38,16 @@ static char **opt_keyrings; * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { "keyring", 'k', 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_keyrings, "Import keys from a keyring file (repeatable)", "FILE" }, - { "stdin", 0, 0, G_OPTION_ARG_NONE, &opt_stdin, "Import keys from standard input", NULL }, - { NULL } -}; +static GOptionEntry option_entries[] + = { { "keyring", 'k', 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_keyrings, + "Import keys from a keyring file (repeatable)", "FILE" }, + { "stdin", 0, 0, G_OPTION_ARG_NONE, &opt_stdin, "Import keys from standard input", NULL }, + { NULL } }; static gboolean -open_source_stream (GInputStream **out_source_stream, - GCancellable *cancellable, - GError **error) +open_source_stream (GInputStream **out_source_stream, GCancellable *cancellable, GError **error) { - g_autoptr(GInputStream) source_stream = NULL; + g_autoptr (GInputStream) source_stream = NULL; guint n_keyrings = 0; gboolean ret = FALSE; @@ -62,14 +60,14 @@ open_source_stream (GInputStream **out_source_stream, } else { - g_autoptr(GPtrArray) streams = NULL; + g_autoptr (GPtrArray) streams = NULL; guint ii; streams = g_ptr_array_new_with_free_func (g_object_unref); for (ii = 0; ii < n_keyrings; ii++) { - g_autoptr(GFile) file = NULL; + g_autoptr (GFile) file = NULL; GFileInputStream *input_stream = NULL; file = g_file_new_for_path (opt_keyrings[ii]); @@ -82,8 +80,8 @@ open_source_stream (GInputStream **out_source_stream, g_ptr_array_add (streams, input_stream); } - /* Chain together all the --keyring options as one long stream. */ - source_stream = (GInputStream *) ostree_chain_input_stream_new (streams); + /* Chain together all the --keyring options as one long stream. */ + source_stream = (GInputStream *)ostree_chain_input_stream_new (streams); } *out_source_stream = g_steal_pointer (&source_stream); @@ -95,20 +93,21 @@ open_source_stream (GInputStream **out_source_stream, } gboolean -ot_remote_builtin_gpg_import (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_gpg_import (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GInputStream) source_stream = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GInputStream) source_stream = NULL; const char *remote_name; - const char * const *key_ids; + const char *const *key_ids; guint imported = 0; gboolean ret = FALSE; context = g_option_context_new ("NAME [KEY-ID...]"); - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) goto out; if (argc < 2) @@ -124,21 +123,21 @@ ot_remote_builtin_gpg_import (int argc, char **argv, OstreeCommandInvocation *in } remote_name = argv[1]; - key_ids = (argc > 2) ? (const char * const *) argv + 2 : NULL; + key_ids = (argc > 2) ? (const char *const *)argv + 2 : NULL; if (!open_source_stream (&source_stream, cancellable, error)) goto out; - if (!ostree_repo_remote_gpg_import (repo, remote_name, source_stream, - key_ids, &imported, cancellable, error)) + if (!ostree_repo_remote_gpg_import (repo, remote_name, source_stream, key_ids, &imported, + cancellable, error)) goto out; /* XXX If we ever add internationalization, use ngettext() here. */ - g_print ("Imported %u GPG key%s to remote \"%s\"\n", - imported, (imported == 1) ? "" : "s", remote_name); + g_print ("Imported %u GPG key%s to remote \"%s\"\n", imported, (imported == 1) ? "" : "s", + remote_name); ret = TRUE; - out: +out: return ret; } diff --git a/src/ostree/ot-remote-builtin-gpg-list-keys.c b/src/ostree/ot-remote-builtin-gpg-list-keys.c index d0a388e..8bd4c6b 100644 --- a/src/ostree/ot-remote-builtin-gpg-list-keys.c +++ b/src/ostree/ot-remote-builtin-gpg-list-keys.c @@ -21,8 +21,8 @@ #include "otutil.h" -#include "ot-main.h" #include "ot-dump.h" +#include "ot-main.h" #include "ot-remote-builtins.h" /* ATTENTION: @@ -30,28 +30,22 @@ * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { NULL } -}; +static GOptionEntry option_entries[] = { { NULL } }; gboolean -ot_remote_builtin_list_gpg_keys (int argc, - char **argv, - OstreeCommandInvocation *invocation, - GCancellable *cancellable, - GError **error) +ot_remote_builtin_list_gpg_keys (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = g_option_context_new ("NAME"); - g_autoptr(OstreeRepo) repo = NULL; - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) + g_autoptr (GOptionContext) context = g_option_context_new ("NAME"); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; const char *remote_name = (argc > 1) ? argv[1] : NULL; - g_autoptr(GPtrArray) keys = NULL; - if (!ostree_repo_remote_get_gpg_keys (repo, remote_name, NULL, &keys, - cancellable, error)) + g_autoptr (GPtrArray) keys = NULL; + if (!ostree_repo_remote_get_gpg_keys (repo, remote_name, NULL, &keys, cancellable, error)) return FALSE; for (guint i = 0; i < keys->len; i++) diff --git a/src/ostree/ot-remote-builtin-list-cookies.c b/src/ostree/ot-remote-builtin-list-cookies.c index 04e7573..2e576d5 100644 --- a/src/ostree/ot-remote-builtin-list-cookies.c +++ b/src/ostree/ot-remote-builtin-list-cookies.c @@ -22,9 +22,9 @@ #include "otutil.h" +#include "ostree-repo-private.h" #include "ot-main.h" #include "ot-remote-builtins.h" -#include "ostree-repo-private.h" #include "ot-remote-cookie-util.h" /* ATTENTION: @@ -32,18 +32,17 @@ * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { NULL } -}; +static GOptionEntry option_entries[] = { { NULL } }; gboolean -ot_remote_builtin_list_cookies (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_list_cookies (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GOptionContext) context = g_option_context_new ("NAME"); + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = g_option_context_new ("NAME"); - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) return FALSE; if (argc < 2) diff --git a/src/ostree/ot-remote-builtin-list.c b/src/ostree/ot-remote-builtin-list.c index 552e535..31c60ec 100644 --- a/src/ostree/ot-remote-builtin-list.c +++ b/src/ostree/ot-remote-builtin-list.c @@ -29,53 +29,46 @@ static gboolean opt_show_urls; * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { "show-urls", 'u', 0, G_OPTION_ARG_NONE, &opt_show_urls, "Show remote URLs in list", NULL }, - { NULL } -}; +static GOptionEntry option_entries[] = { { "show-urls", 'u', 0, G_OPTION_ARG_NONE, &opt_show_urls, + "Show remote URLs in list", NULL }, + { NULL } }; gboolean -ot_remote_builtin_list (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_list (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - g_auto(GStrv) remotes = NULL; - guint ii, n_remotes = 0; - gboolean ret = FALSE; + g_autoptr (GOptionContext) context = g_option_context_new (""); - context = g_option_context_new (""); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) + return FALSE; - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) - goto out; - - remotes = ostree_repo_remote_list (repo, &n_remotes); + guint n_remotes = 0; + g_auto (GStrv) remotes = ostree_repo_remote_list (repo, &n_remotes); if (opt_show_urls) { int max_length = 0; - for (ii = 0; ii < n_remotes; ii++) + for (guint ii = 0; ii < n_remotes; ii++) max_length = MAX (max_length, strlen (remotes[ii])); - for (ii = 0; ii < n_remotes; ii++) + for (guint ii = 0; ii < n_remotes; ii++) { g_autofree char *remote_url = NULL; if (!ostree_repo_remote_get_url (repo, remotes[ii], &remote_url, error)) - goto out; + return FALSE; g_print ("%-*s %s\n", max_length, remotes[ii], remote_url); } } else { - for (ii = 0; ii < n_remotes; ii++) + for (guint ii = 0; ii < n_remotes; ii++) g_print ("%s\n", remotes[ii]); } - ret = TRUE; - - out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-remote-builtin-refs.c b/src/ostree/ot-remote-builtin-refs.c index d778fe6..103c913 100644 --- a/src/ostree/ot-remote-builtin-refs.c +++ b/src/ostree/ot-remote-builtin-refs.c @@ -24,64 +24,70 @@ #include "ot-main.h" #include "ot-remote-builtins.h" -static char* opt_cache_dir; +static gboolean opt_revision; +static char *opt_cache_dir; /* ATTENTION: * Please remember to update the bash-completion script (bash/ostree) and * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, - { NULL } -}; +static GOptionEntry option_entries[] + = { { "revision", 'r', 0, G_OPTION_ARG_NONE, &opt_revision, "Show revisions in listing", NULL }, + { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, + { NULL } }; gboolean -ot_remote_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - const char *remote_name; - gboolean ret = FALSE; - g_autoptr(GHashTable) refs = NULL; + g_autoptr (GOptionContext) context = g_option_context_new ("NAME"); - context = g_option_context_new ("NAME"); - - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) - goto out; + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) + return FALSE; if (argc < 2) { ot_util_usage_error (context, "NAME must be specified", error); - goto out; + return FALSE; } if (opt_cache_dir) { if (!ostree_repo_set_cache_dir (repo, AT_FDCWD, opt_cache_dir, cancellable, error)) - goto out; + return FALSE; } - remote_name = argv[1]; + const char *remote_name = argv[1]; + g_autoptr (GHashTable) refs = NULL; if (!ostree_repo_remote_list_refs (repo, remote_name, &refs, cancellable, error)) - goto out; + return FALSE; else { - g_autoptr(GList) ordered_keys = NULL; + g_autoptr (GList) ordered_keys = NULL; GList *iter = NULL; ordered_keys = g_hash_table_get_keys (refs); - ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) strcmp); + ordered_keys = g_list_sort (ordered_keys, (GCompareFunc)strcmp); for (iter = ordered_keys; iter; iter = iter->next) { - g_print ("%s:%s\n", remote_name, (const char *) iter->data); + const char *ref = iter->data; + + if (opt_revision) + { + const char *rev = g_hash_table_lookup (refs, ref); + g_print ("%s:%s\t%s\n", remote_name, ref, rev); + } + else + { + g_print ("%s:%s\n", remote_name, ref); + } } } - ret = TRUE; -out: - return ret; + return TRUE; } diff --git a/src/ostree/ot-remote-builtin-show-url.c b/src/ostree/ot-remote-builtin-show-url.c index f63908a..0ce7ee3 100644 --- a/src/ostree/ot-remote-builtin-show-url.c +++ b/src/ostree/ot-remote-builtin-show-url.c @@ -29,39 +29,30 @@ * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { NULL } -}; +static GOptionEntry option_entries[] = { { NULL } }; gboolean -ot_remote_builtin_show_url (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_show_url (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; - const char *remote_name; - g_autofree char *remote_url = NULL; - gboolean ret = FALSE; - - context = g_option_context_new ("NAME"); - - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) - goto out; + g_autoptr (GOptionContext) context = g_option_context_new ("NAME"); + g_autoptr (OstreeRepo) repo = NULL; + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) + return FALSE; if (argc < 2) { ot_util_usage_error (context, "NAME must be specified", error); - goto out; + return FALSE; } - remote_name = argv[1]; + const char *remote_name = argv[1]; - if (ostree_repo_remote_get_url (repo, remote_name, &remote_url, error)) - { - g_print ("%s\n", remote_url); - ret = TRUE; - } + g_autofree char *remote_url = NULL; + if (!ostree_repo_remote_get_url (repo, remote_name, &remote_url, error)) + return FALSE; - out: - return ret; + g_print ("%s\n", remote_url); + return TRUE; } diff --git a/src/ostree/ot-remote-builtin-summary.c b/src/ostree/ot-remote-builtin-summary.c index fb2c45a..ec508cb 100644 --- a/src/ostree/ot-remote-builtin-summary.c +++ b/src/ostree/ot-remote-builtin-summary.c @@ -21,33 +21,39 @@ #include "otutil.h" -#include "ot-main.h" #include "ot-dump.h" +#include "ot-main.h" #include "ot-remote-builtins.h" +static gboolean opt_list_metadata_keys; static gboolean opt_raw; -static char* opt_cache_dir; +static char *opt_print_metadata_key; +static char *opt_cache_dir; /* ATTENTION: * Please remember to update the bash-completion script (bash/ostree) and * man page (man/ostree-remote.xml) when changing the option list. */ -static GOptionEntry option_entries[] = { - { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, - { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data", NULL }, - { NULL } -}; +static GOptionEntry option_entries[] + = { { "list-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_metadata_keys, + "List the available metadata keys", NULL }, + { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, + "Print string value of metadata key", "KEY" }, + { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, + { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data", NULL }, + { NULL } }; gboolean -ot_remote_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) +ot_remote_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) { - g_autoptr(GOptionContext) context = NULL; - g_autoptr(OstreeRepo) repo = NULL; + g_autoptr (GOptionContext) context = NULL; + g_autoptr (OstreeRepo) repo = NULL; const char *remote_name; - g_autoptr(GBytes) summary_bytes = NULL; - g_autoptr(GBytes) signature_bytes = NULL; + g_autoptr (GBytes) summary_bytes = NULL; + g_autoptr (GBytes) signature_bytes = NULL; OstreeDumpFlags flags = OSTREE_DUMP_NONE; #ifndef OSTREE_DISABLE_GPGME gboolean gpg_verify_summary; @@ -56,8 +62,8 @@ ot_remote_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invoc context = g_option_context_new ("NAME"); - if (!ostree_option_context_parse (context, option_entries, &argc, &argv, - invocation, &repo, cancellable, error)) + if (!ostree_option_context_parse (context, option_entries, &argc, &argv, invocation, &repo, + cancellable, error)) goto out; if (argc < 2) @@ -77,55 +83,59 @@ ot_remote_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invoc if (opt_raw) flags |= OSTREE_DUMP_RAW; - if (!ostree_repo_remote_fetch_summary (repo, remote_name, - &summary_bytes, - &signature_bytes, + if (!ostree_repo_remote_fetch_summary (repo, remote_name, &summary_bytes, &signature_bytes, cancellable, error)) goto out; if (summary_bytes == NULL) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Remote server has no summary file"); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Remote server has no summary file"); goto out; } - ot_dump_summary_bytes (summary_bytes, flags); + if (opt_list_metadata_keys) + { + ot_dump_summary_metadata_keys (summary_bytes); + } + else if (opt_print_metadata_key) + { + if (!ot_dump_summary_metadata_key (summary_bytes, opt_print_metadata_key, error)) + goto out; + } + else + { + ot_dump_summary_bytes (summary_bytes, flags); #ifndef OSTREE_DISABLE_GPGME - if (!ostree_repo_remote_get_gpg_verify_summary (repo, remote_name, - &gpg_verify_summary, - error)) - goto out; - - if (!gpg_verify_summary) - g_clear_pointer (&signature_bytes, g_bytes_unref); - - /* XXX Note we don't show signatures for "--raw". My intuition is - * if someone needs to see or parse raw summary data, including - * signatures in the output would probably just interfere. - * If there's demand for it I suppose we could introduce a new - * option for raw signature data like "--raw-signatures". */ - if (signature_bytes != NULL && !opt_raw) - { - g_autoptr(OstreeGpgVerifyResult) result = NULL; - - /* The actual signed summary verification happens above in - * ostree_repo_remote_fetch_summary(). Here we just parse - * the signatures again for the purpose of printing. */ - result = ostree_repo_verify_summary (repo, - remote_name, - summary_bytes, - signature_bytes, - cancellable, - error); - if (result == NULL) + if (!ostree_repo_remote_get_gpg_verify_summary (repo, remote_name, &gpg_verify_summary, + error)) goto out; - g_print ("\n"); - ostree_print_gpg_verify_result (result); - } + if (!gpg_verify_summary) + g_clear_pointer (&signature_bytes, g_bytes_unref); + + /* XXX Note we don't show signatures for "--raw". My intuition is + * if someone needs to see or parse raw summary data, including + * signatures in the output would probably just interfere. + * If there's demand for it I suppose we could introduce a new + * option for raw signature data like "--raw-signatures". */ + if (signature_bytes != NULL && !opt_raw) + { + g_autoptr (OstreeGpgVerifyResult) result = NULL; + + /* The actual signed summary verification happens above in + * ostree_repo_remote_fetch_summary(). Here we just parse + * the signatures again for the purpose of printing. */ + result = ostree_repo_verify_summary (repo, remote_name, summary_bytes, signature_bytes, + cancellable, error); + if (result == NULL) + goto out; + + g_print ("\n"); + ostree_print_gpg_verify_result (result); + } #endif /* OSTREE_DISABLE_GPGME */ + } ret = TRUE; out: diff --git a/src/ostree/ot-remote-builtins.h b/src/ostree/ot-remote-builtins.h index 4a0482a..0386478 100644 --- a/src/ostree/ot-remote-builtins.h +++ b/src/ostree/ot-remote-builtins.h @@ -23,23 +23,23 @@ G_BEGIN_DECLS -#define BUILTINPROTO(name) gboolean ot_remote_builtin_ ## name (int argc, char **argv, \ - OstreeCommandInvocation *invocation, \ - GCancellable *cancellable, GError **error) +#define BUILTINPROTO(name) \ + gboolean ot_remote_builtin_##name (int argc, char **argv, OstreeCommandInvocation *invocation, \ + GCancellable *cancellable, GError **error) -BUILTINPROTO(add); -BUILTINPROTO(delete); -BUILTINPROTO(gpg_import); -BUILTINPROTO(list_gpg_keys); -BUILTINPROTO(list); +BUILTINPROTO (add); +BUILTINPROTO (delete); +BUILTINPROTO (gpg_import); +BUILTINPROTO (list_gpg_keys); +BUILTINPROTO (list); #ifdef HAVE_LIBCURL_OR_LIBSOUP -BUILTINPROTO(add_cookie); -BUILTINPROTO(list_cookies); -BUILTINPROTO(delete_cookie); +BUILTINPROTO (add_cookie); +BUILTINPROTO (list_cookies); +BUILTINPROTO (delete_cookie); #endif -BUILTINPROTO(show_url); -BUILTINPROTO(refs); -BUILTINPROTO(summary); +BUILTINPROTO (show_url); +BUILTINPROTO (refs); +BUILTINPROTO (summary); #undef BUILTINPROTO diff --git a/src/ostree/ot-remote-cookie-util.c b/src/ostree/ot-remote-cookie-util.c index 8cf1eb0..5b15dd3 100644 --- a/src/ostree/ot-remote-cookie-util.c +++ b/src/ostree/ot-remote-cookie-util.c @@ -22,13 +22,14 @@ #include "ot-remote-cookie-util.h" -#include "otutil.h" +#include "ostree-repo-private.h" #include "ot-main.h" #include "ot-remote-builtins.h" -#include "ostree-repo-private.h" +#include "otutil.h" typedef struct OtCookieParser OtCookieParser; -struct OtCookieParser { +struct OtCookieParser +{ char *buf; char *iter; @@ -42,15 +43,11 @@ struct OtCookieParser { char *value; }; void ot_cookie_parser_free (OtCookieParser *parser); -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtCookieParser, ot_cookie_parser_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OtCookieParser, ot_cookie_parser_free) -gboolean -ot_parse_cookies_at (int dfd, const char *path, - OtCookieParser **out_parser, - GCancellable *cancellable, - GError **error); -gboolean -ot_parse_cookies_next (OtCookieParser *parser); +gboolean ot_parse_cookies_at (int dfd, const char *path, OtCookieParser **out_parser, + GCancellable *cancellable, GError **error); +gboolean ot_parse_cookies_next (OtCookieParser *parser); static void ot_cookie_parser_clear (OtCookieParser *parser) @@ -72,10 +69,8 @@ ot_cookie_parser_free (OtCookieParser *parser) } gboolean -ot_parse_cookies_at (int dfd, const char *path, - OtCookieParser **out_parser, - GCancellable *cancellable, - GError **error) +ot_parse_cookies_at (int dfd, const char *path, OtCookieParser **out_parser, + GCancellable *cancellable, GError **error) { OtCookieParser *parser; g_autofree char *cookies_content = NULL; @@ -120,14 +115,10 @@ ot_parse_cookies_next (OtCookieParser *parser) parser->iter = NULL; ot_cookie_parser_clear (parser); - if (sscanf (iter, "%ms\t%ms\t%ms\t%ms\t%llu\t%ms\t%ms", - &parser->domain, - &parser->flag, - &parser->path, - &parser->secure, - &parser->expiration, - &parser->name, - &parser->value) != 7) + if (sscanf (iter, "%ms\t%ms\t%ms\t%ms\t%llu\t%ms\t%ms", &parser->domain, &parser->flag, + &parser->path, &parser->secure, &parser->expiration, &parser->name, + &parser->value) + != 7) continue; parser->line = iter; @@ -138,69 +129,58 @@ ot_parse_cookies_next (OtCookieParser *parser) } gboolean -ot_add_cookie_at (int dfd, const char *jar_path, - const char *domain, const char *path, - const char *name, const char *value, - GError **error) +ot_add_cookie_at (int dfd, const char *jar_path, const char *domain, const char *path, + const char *name, const char *value, GError **error) { glnx_autofd int fd = openat (dfd, jar_path, O_WRONLY | O_APPEND | O_CREAT, 0644); if (fd < 0) return glnx_throw_errno_prefix (error, "open(%s)", jar_path); - g_autoptr(GDateTime) now = g_date_time_new_now_utc (); - g_autoptr(GDateTime) expires = g_date_time_add_years (now, 25); + g_autoptr (GDateTime) now = g_date_time_new_now_utc (); + g_autoptr (GDateTime) expires = g_date_time_add_years (now, 25); /* Adapted from soup-cookie-jar-text.c:write_cookie() */ - g_autofree char *buf = g_strdup_printf ("%s\t%s\t%s\t%s\t%llu\t%s\t%s\n", - domain, - *domain == '.' ? "TRUE" : "FALSE", - path, - "FALSE", - (long long unsigned)g_date_time_to_unix (expires), - name, - value); + g_autofree char *buf = g_strdup_printf ( + "%s\t%s\t%s\t%s\t%llu\t%s\t%s\n", domain, *domain == '.' ? "TRUE" : "FALSE", path, "FALSE", + (long long unsigned)g_date_time_to_unix (expires), name, value); if (glnx_loop_write (fd, buf, strlen (buf)) < 0) return glnx_throw_errno_prefix (error, "write"); return TRUE; } gboolean -ot_delete_cookie_at (int dfd, const char *jar_path, - const char *domain, const char *path, - const char *name, - GError **error) +ot_delete_cookie_at (int dfd, const char *jar_path, const char *domain, const char *path, + const char *name, GError **error) { gboolean found = FALSE; - g_auto(GLnxTmpfile) tmpf = { 0, }; - g_autoptr(OtCookieParser) parser = NULL; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; + g_autoptr (OtCookieParser) parser = NULL; if (!ot_parse_cookies_at (dfd, jar_path, &parser, NULL, error)) return FALSE; g_assert (!strchr (jar_path, '/')); - if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_WRONLY | O_CLOEXEC, - &tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_WRONLY | O_CLOEXEC, &tmpf, error)) return FALSE; while (ot_parse_cookies_next (parser)) { - if (strcmp (domain, parser->domain) == 0 && - strcmp (path, parser->path) == 0 && - strcmp (name, parser->name) == 0) + if (strcmp (domain, parser->domain) == 0 && strcmp (path, parser->path) == 0 + && strcmp (name, parser->name) == 0) { found = TRUE; /* Match, skip writing this one */ continue; } - if (glnx_loop_write (tmpf.fd, parser->line, strlen (parser->line)) < 0 || - glnx_loop_write (tmpf.fd, "\n", 1) < 0) + if (glnx_loop_write (tmpf.fd, parser->line, strlen (parser->line)) < 0 + || glnx_loop_write (tmpf.fd, "\n", 1) < 0) return glnx_throw_errno_prefix (error, "write"); } - if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_REPLACE, - dfd, jar_path, - error)) + if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_REPLACE, dfd, jar_path, error)) return FALSE; if (!found) @@ -209,18 +189,17 @@ ot_delete_cookie_at (int dfd, const char *jar_path, return TRUE; } - gboolean ot_list_cookies_at (int dfd, const char *jar_path, GError **error) { - g_autoptr(OtCookieParser) parser = NULL; + g_autoptr (OtCookieParser) parser = NULL; if (!ot_parse_cookies_at (AT_FDCWD, jar_path, &parser, NULL, error)) return FALSE; while (ot_parse_cookies_next (parser)) { - g_autoptr(GDateTime) expires = g_date_time_new_from_unix_utc (parser->expiration); + g_autoptr (GDateTime) expires = g_date_time_new_from_unix_utc (parser->expiration); g_autofree char *expires_str = NULL; if (expires != NULL) diff --git a/src/ostree/ot-remote-cookie-util.h b/src/ostree/ot-remote-cookie-util.h index 838714f..e0a84a1 100644 --- a/src/ostree/ot-remote-cookie-util.h +++ b/src/ostree/ot-remote-cookie-util.h @@ -23,19 +23,12 @@ G_BEGIN_DECLS -gboolean -ot_add_cookie_at (int dfd, const char *jar_path, - const char *domain, const char *path, - const char *name, const char *value, - GError **error); +gboolean ot_add_cookie_at (int dfd, const char *jar_path, const char *domain, const char *path, + const char *name, const char *value, GError **error); -gboolean -ot_delete_cookie_at (int dfd, const char *jar_path, - const char *domain, const char *path, - const char *name, - GError **error); +gboolean ot_delete_cookie_at (int dfd, const char *jar_path, const char *domain, const char *path, + const char *name, GError **error); -gboolean -ot_list_cookies_at (int dfd, const char *jar_path, GError **error); +gboolean ot_list_cookies_at (int dfd, const char *jar_path, GError **error); G_END_DECLS diff --git a/src/rofiles-fuse/main.c b/src/rofiles-fuse/main.c index 7f49dd8..937ee4a 100644 --- a/src/rofiles-fuse/main.c +++ b/src/rofiles-fuse/main.c @@ -23,19 +23,19 @@ #error config.h needs to define FUSE_USE_VERSION #endif -#include -#include -#include -#include +#include #include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include #include -#include #include -#include #include @@ -98,11 +98,11 @@ callback_readlink (const char *path, char *buf, size_t size) static int #if FUSE_USE_VERSION >= 31 -callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags) +callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, + struct fuse_file_info *fi, enum fuse_readdir_flags flags) #else -callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) +callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, + struct fuse_file_info *fi) #endif { DIR *dp; @@ -146,7 +146,7 @@ callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler, #endif } - (void) closedir (dp); + (void)closedir (dp); return 0; } @@ -195,8 +195,7 @@ callback_symlink (const char *from, const char *to) if (fstatat (basefd, to, &stbuf, AT_SYMLINK_NOFOLLOW) == -1) { - fprintf (stderr, "Failed to find newly created symlink '%s': %s\n", - to, g_strerror (errno)); + fprintf (stderr, "Failed to find newly created symlink '%s': %s\n", to, g_strerror (errno)); exit (EXIT_FAILURE); } return 0; @@ -277,8 +276,7 @@ gioerror_to_errno (GIOErrorEnum e) } static int -verify_write_or_copyup (const char *path, const struct stat *stbuf, - gboolean *out_did_copyup) +verify_write_or_copyup (const char *path, const struct stat *stbuf, gboolean *out_did_copyup) { struct stat stbuf_local; @@ -303,7 +301,7 @@ verify_write_or_copyup (const char *path, const struct stat *stbuf, { if (opt_copyup) { - g_autoptr(GError) tmp_error = NULL; + g_autoptr (GError) tmp_error = NULL; if (!ostree_break_hardlink (basefd, path, FALSE, NULL, &tmp_error)) return -gioerror_to_errno ((GIOErrorEnum)tmp_error->code); if (out_did_copyup) @@ -320,12 +318,15 @@ verify_write_or_copyup (const char *path, const struct stat *stbuf, * to a relative path (even for the caller) and * perform either write verification or copy-up. */ -#define PATH_WRITE_ENTRYPOINT(path) do { \ - path = ENSURE_RELPATH (path); \ - int r = verify_write_or_copyup (path, NULL, NULL); \ - if (r != 0) \ - return r; \ - } while (0) +#define PATH_WRITE_ENTRYPOINT(path) \ + do \ + { \ + path = ENSURE_RELPATH (path); \ + int r = verify_write_or_copyup (path, NULL, NULL); \ + if (r != 0) \ + return r; \ + } \ + while (0) static int #if FUSE_USE_VERSION >= 31 @@ -368,7 +369,7 @@ callback_truncate (const char *path, off_t size) { PATH_WRITE_ENTRYPOINT (path); - glnx_autofd int fd = openat (basefd, path, O_NOFOLLOW|O_WRONLY); + glnx_autofd int fd = openat (basefd, path, O_NOFOLLOW | O_WRONLY); if (fd == -1) return -errno; @@ -422,7 +423,7 @@ do_open (const char *path, mode_t mode, struct fuse_file_info *finfo) if (fstat (fd, &stbuf) == -1) { - (void) close (fd); + (void)close (fd); return -errno; } @@ -430,20 +431,20 @@ do_open (const char *path, mode_t mode, struct fuse_file_info *finfo) int r = verify_write_or_copyup (path, &stbuf, &did_copyup); if (r != 0) { - (void) close (fd); + (void)close (fd); return r; } /* In the copyup case, we need to re-open */ if (did_copyup) { - (void) close (fd); + (void)close (fd); /* Note that unlike the initial open, we will pass through * O_TRUNC. More ideally in this copyup case we'd avoid copying * the whole file in the first place, but eh. It's not like we're * high performance anyways. */ - fd = openat (basefd, path, finfo->flags & ~(O_EXCL|O_CREAT), mode); + fd = openat (basefd, path, finfo->flags & ~(O_EXCL | O_CREAT), mode); if (fd == -1) return -errno; } @@ -456,7 +457,7 @@ do_open (const char *path, mode_t mode, struct fuse_file_info *finfo) { if (ftruncate (fd, 0) == -1) { - (void) close (fd); + (void)close (fd); return -errno; } } @@ -475,14 +476,14 @@ callback_open (const char *path, struct fuse_file_info *finfo) } static int -callback_create(const char *path, mode_t mode, struct fuse_file_info *finfo) +callback_create (const char *path, mode_t mode, struct fuse_file_info *finfo) { return do_open (path, mode, finfo); } static int -callback_read_buf (const char *path, struct fuse_bufvec **bufp, - size_t size, off_t offset, struct fuse_file_info *finfo) +callback_read_buf (const char *path, struct fuse_bufvec **bufp, size_t size, off_t offset, + struct fuse_file_info *finfo) { struct fuse_bufvec *src; @@ -501,8 +502,7 @@ callback_read_buf (const char *path, struct fuse_bufvec **bufp, } static int -callback_read (const char *path, char *buf, size_t size, off_t offset, - struct fuse_file_info *finfo) +callback_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *finfo) { int r; r = pread (finfo->fh, buf, size, offset); @@ -546,7 +546,7 @@ callback_statfs (const char *path, struct statvfs *st_buf) static int callback_release (const char *path, struct fuse_file_info *finfo) { - (void) close (finfo->fh); + (void)close (finfo->fh); return 0; } @@ -573,8 +573,7 @@ callback_access (const char *path, int mode) } static int -callback_setxattr (const char *path, const char *name, const char *value, - size_t size, int flags) +callback_setxattr (const char *path, const char *name, const char *value, size_t size, int flags) { PATH_WRITE_ENTRYPOINT (path); @@ -587,8 +586,7 @@ callback_setxattr (const char *path, const char *name, const char *value, } static int -callback_getxattr (const char *path, const char *name, char *value, - size_t size) +callback_getxattr (const char *path, const char *name, char *value, size_t size) { path = ENSURE_RELPATH (path); @@ -634,40 +632,39 @@ callback_removexattr (const char *path, const char *name) return 0; } -struct fuse_operations callback_oper = { - .getattr = callback_getattr, - .readlink = callback_readlink, - .readdir = callback_readdir, - .mknod = callback_mknod, - .mkdir = callback_mkdir, - .symlink = callback_symlink, - .unlink = callback_unlink, - .rmdir = callback_rmdir, - .rename = callback_rename, - .link = callback_link, - .chmod = callback_chmod, - .chown = callback_chown, - .truncate = callback_truncate, - .utimens = callback_utimens, - .create = callback_create, - .open = callback_open, - .read_buf = callback_read_buf, - .read = callback_read, - .write_buf = callback_write_buf, - .write = callback_write, - .statfs = callback_statfs, - .release = callback_release, - .fsync = callback_fsync, - .access = callback_access, - - /* Extended attributes support for userland interaction */ - .setxattr = callback_setxattr, - .getxattr = callback_getxattr, - .listxattr = callback_listxattr, - .removexattr = callback_removexattr -}; - -enum { +struct fuse_operations callback_oper = { .getattr = callback_getattr, + .readlink = callback_readlink, + .readdir = callback_readdir, + .mknod = callback_mknod, + .mkdir = callback_mkdir, + .symlink = callback_symlink, + .unlink = callback_unlink, + .rmdir = callback_rmdir, + .rename = callback_rename, + .link = callback_link, + .chmod = callback_chmod, + .chown = callback_chown, + .truncate = callback_truncate, + .utimens = callback_utimens, + .create = callback_create, + .open = callback_open, + .read_buf = callback_read_buf, + .read = callback_read, + .write_buf = callback_write_buf, + .write = callback_write, + .statfs = callback_statfs, + .release = callback_release, + .fsync = callback_fsync, + .access = callback_access, + + /* Extended attributes support for userland interaction */ + .setxattr = callback_setxattr, + .getxattr = callback_getxattr, + .listxattr = callback_listxattr, + .removexattr = callback_removexattr }; + +enum +{ KEY_HELP, KEY_VERSION, KEY_COPYUP, @@ -679,26 +676,28 @@ usage (const char *progname) fprintf (stdout, "usage: %s basepath mountpoint [options]\n" "\n" - " Makes basepath visible at mountpoint such that files are read-only, directories are writable\n" + " Makes basepath visible at mountpoint such that files are read-only, directories " + "are writable\n" "\n" "general options:\n" " -o opt,[opt...] mount options\n" " -h --help print help\n" - "\n", progname); + "\n", + progname); } static int -rofs_parse_opt (void *data, const char *arg, int key, - struct fuse_args *outargs) +rofs_parse_opt (void *data, const char *arg, int key, struct fuse_args *outargs) { - (void) data; + (void)data; switch (key) { case FUSE_OPT_KEY_NONOPT: if (basefd == -1) { - basefd = openat (AT_FDCWD, arg, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); + basefd + = openat (AT_FDCWD, arg, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); if (basefd == -1) err (1, "opening rootfs %s", arg); return 0; @@ -722,14 +721,10 @@ rofs_parse_opt (void *data, const char *arg, int key, return 1; } -static struct fuse_opt rofs_opts[] = { - FUSE_OPT_KEY ("-h", KEY_HELP), - FUSE_OPT_KEY ("--help", KEY_HELP), - FUSE_OPT_KEY ("-V", KEY_VERSION), - FUSE_OPT_KEY ("--version", KEY_VERSION), - FUSE_OPT_KEY ("--copyup", KEY_COPYUP), - FUSE_OPT_END -}; +static struct fuse_opt rofs_opts[] + = { FUSE_OPT_KEY ("-h", KEY_HELP), FUSE_OPT_KEY ("--help", KEY_HELP), + FUSE_OPT_KEY ("-V", KEY_VERSION), FUSE_OPT_KEY ("--version", KEY_VERSION), + FUSE_OPT_KEY ("--copyup", KEY_COPYUP), FUSE_OPT_END }; int main (int argc, char *argv[]) diff --git a/src/switchroot/ostree-mount-util.h b/src/switchroot/ostree-mount-util.h index 92bc802..eb79efd 100644 --- a/src/switchroot/ostree-mount-util.h +++ b/src/switchroot/ostree-mount-util.h @@ -22,16 +22,21 @@ #define __OSTREE_MOUNT_UTIL_H_ #include +#include +#include +#include +#include #include +#include +#include #include -#include #include -#include -#include -#include #define INITRAMFS_MOUNT_VAR "/run/ostree/initramfs-mount-var" #define _OSTREE_SYSROOT_READONLY_STAMP "/run/ostree-sysroot-ro.stamp" +#define _OSTREE_COMPOSEFS_ROOT_STAMP "/run/ostree-composefs-root.stamp" + +#define autofree __attribute__ ((cleanup (cleanup_free))) static inline int path_is_on_readonly_fs (const char *path) @@ -47,7 +52,7 @@ path_is_on_readonly_fs (const char *path) static inline char * read_proc_cmdline (void) { - FILE *f = fopen("/proc/cmdline", "r"); + FILE *f = fopen ("/proc/cmdline", "r"); char *cmdline = NULL; size_t len; @@ -64,46 +69,44 @@ read_proc_cmdline (void) */ len = strlen (cmdline); - if (cmdline[len-1] == '\n') - cmdline[len-1] = '\0'; + if (cmdline[len - 1] == '\n') + cmdline[len - 1] = '\0'; out: if (f) fclose (f); return cmdline; } -static inline char * -read_proc_cmdline_ostree (void) +static inline void +cleanup_free (void *p) { - char *cmdline = NULL; - const char *iter; - char *ret = NULL; - - cmdline = read_proc_cmdline (); - if (!cmdline) - err (EXIT_FAILURE, "failed to read /proc/cmdline"); + void **pp = (void **)p; + free (*pp); +} - iter = cmdline; - while (iter != NULL) +static inline char * +find_proc_cmdline_key (const char *cmdline, const char *key) +{ + const size_t key_len = strlen (key); + for (const char *iter = cmdline; iter;) { const char *next = strchr (iter, ' '); - const char *next_nonspc = next; - while (next_nonspc && *next_nonspc == ' ') - next_nonspc += 1; - if (strncmp (iter, "ostree=", strlen ("ostree=")) == 0) + if (strncmp (iter, key, key_len) == 0 && iter[key_len] == '=') { - const char *start = iter + strlen ("ostree="); + const char *start = iter + key_len + 1; if (next) - ret = strndup (start, next - start); - else - ret = strdup (start); - break; + return strndup (start, next - start); + + return strdup (start); } - iter = next_nonspc; + + if (next) + next += strspn (next, " "); + + iter = next; } - free (cmdline); - return ret; + return NULL; } /* This is an API for other projects to determine whether or not the @@ -118,7 +121,7 @@ touch_run_ostree (void) */ if (fd == -1) return; - (void) close (fd); + (void)close (fd); } #endif /* __OSTREE_MOUNT_UTIL_H_ */ diff --git a/src/switchroot/ostree-prepare-root-static.c b/src/switchroot/ostree-prepare-root-static.c new file mode 100644 index 0000000..4aaa469 --- /dev/null +++ b/src/switchroot/ostree-prepare-root-static.c @@ -0,0 +1,393 @@ +/* -*- c-file-style: "gnu" -*- + * Switch to new root directory and start init. + * + * Copyright 2011,2012,2013 Colin Walters + * + * Based on code from util-linux/sys-utils/switch_root.c, + * Copyright 2002-2009 Red Hat, Inc. All rights reserved. + * Authors: + * Peter Jones + * Jeremy Katz + * + * Relicensed with permission to LGPLv2+. + * + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +/* The high level goal of this code is to run inside + * the initial ram disk (if one is in use) and set up the `/` mountpoint + * to be the deployment root, using the ostree= kernel commandline + * argument to find the target deployment root. + * + * It's really the heart of how ostree works - basically multiple + * hardlinked chroot() targets are maintained, this one does the equivalent + * of chroot(). + * + * This -static.c variant of ostree-prepare-root is designed for + * the case where an initrd isn't used - instead the binary must be statically linked (and the + * kernel must have mounted the rootfs itself) - then we set things up and exec the real init + * directly. This can be popular in embedded systems to increase bootup speed. + * + * Note that as of lately, good tools exist for embedding an initramfs + * inside a kernel binary, and this can help avoid static linking. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// A temporary mount point +#define TMP_SYSROOT "/sysroot.tmp" + +#include "ostree-mount-util.h" + +static inline bool +sysroot_is_configured_ro (const char *sysroot) +{ + char *config_path = NULL; + assert (asprintf (&config_path, "%s/ostree/repo/config", sysroot) != -1); + FILE *f = fopen (config_path, "r"); + if (!f) + { + fprintf (stderr, "Missing expected repo config: %s\n", config_path); + free (config_path); + return false; + } + free (config_path); + + bool ret = false; + char *line = NULL; + size_t len = 0; + /* Note getline() will reuse the previous buffer */ + bool in_sysroot = false; + while (getline (&line, &len, f) != -1) + { + /* This is an awful hack to avoid depending on GLib in the + * initramfs right now. + */ + if (strstr (line, "[sysroot]") == line) + in_sysroot = true; + else if (*line == '[') + in_sysroot = false; + else if (in_sysroot && strstr (line, "readonly=true") == line) + { + ret = true; + break; + } + } + + fclose (f); + free (line); + return ret; +} + +static char * +resolve_deploy_path (const char *root_mountpoint) +{ + char destpath[PATH_MAX]; + struct stat stbuf; + char *deploy_path; + autofree char *kernel_cmdline = read_proc_cmdline (); + if (!kernel_cmdline) + errx (EXIT_FAILURE, "Failed to read kernel cmdline"); + autofree char *ostree_cmdline = find_proc_cmdline_key (kernel_cmdline, "ostree"); + + if (snprintf (destpath, sizeof (destpath), "%s/%s", root_mountpoint, ostree_cmdline) < 0) + err (EXIT_FAILURE, "failed to assemble ostree target path"); + if (lstat (destpath, &stbuf) < 0) + err (EXIT_FAILURE, "Couldn't find specified OSTree root '%s'", destpath); + if (!S_ISLNK (stbuf.st_mode)) + errx (EXIT_FAILURE, "OSTree target is not a symbolic link: %s", destpath); + deploy_path = realpath (destpath, NULL); + if (deploy_path == NULL) + err (EXIT_FAILURE, "realpath(%s) failed", destpath); + if (stat (deploy_path, &stbuf) < 0) + err (EXIT_FAILURE, "stat(%s) failed", deploy_path); + /* Quiet logs if there's no journal */ +#ifdef USE_LIBSYSTEMD + const char *resolved_path = deploy_path + strlen (root_mountpoint); + sd_journal_send ("MESSAGE=Resolved OSTree target to: %s", deploy_path, + "MESSAGE_ID=" SD_ID128_FORMAT_STR, + SD_ID128_FORMAT_VAL (OSTREE_PREPARE_ROOT_DEPLOYMENT_MSG), "DEPLOYMENT_PATH=%s", + resolved_path, "DEPLOYMENT_DEVICE=%" PRIu64, (uint64_t)stbuf.st_dev, + "DEPLOYMENT_INODE=%" PRIu64, (uint64_t)stbuf.st_ino, NULL); +#endif + return deploy_path; +} + +static int +pivot_root (const char *new_root, const char *put_old) +{ + return syscall (__NR_pivot_root, new_root, put_old); +} + +int +main (int argc, char *argv[]) +{ + char srcpath[PATH_MAX]; + + /* If we're pid 1, that means there's no initramfs; in this situation + * various defaults change: + * + * - Assume that the target root is / + * - Quiet logging as there's no journal + * etc. + */ + bool running_as_pid1 = (getpid () == 1); + assert (running_as_pid1); + + const char *root_arg = "/"; + root_arg = "/"; + + struct stat stbuf; + bool we_mounted_proc = false; + if (stat ("/proc/cmdline", &stbuf) < 0) + { + if (errno != ENOENT) + err (EXIT_FAILURE, "stat(\"/proc/cmdline\") failed"); + /* We need /proc mounted for /proc/cmdline and realpath (on musl) to + * work: */ + if (mount ("proc", "/proc", "proc", MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to mount proc on /proc"); + we_mounted_proc = true; + } + + /* This is the final target where we should prepare the rootfs. The usual + * case with systemd in the initramfs is that root_mountpoint = "/sysroot". + * In the fastboot embedded case we're pid1 and will setup / ourself, and + * then root_mountpoint = "/". + * */ + const char *root_mountpoint = realpath (root_arg, NULL); + if (root_mountpoint == NULL) + err (EXIT_FAILURE, "realpath(\"%s\")", root_arg); + char *deploy_path = resolve_deploy_path (root_mountpoint); + + if (we_mounted_proc) + { + /* Leave the filesystem in the state that we found it: */ + if (umount ("/proc")) + err (EXIT_FAILURE, "failed to umount proc from /proc"); + } + + /* Query the repository configuration - this is an operating system builder + * choice. More info: https://github.com/ostreedev/ostree/pull/1767 + */ + const bool sysroot_readonly = sysroot_is_configured_ro (root_arg); + const bool sysroot_currently_writable = !path_is_on_readonly_fs (root_arg); + + /* Work-around for a kernel bug: for some reason the kernel + * refuses switching root if any file systems are mounted + * MS_SHARED. Hence remount them MS_PRIVATE here as a + * work-around. + * + * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */ + if (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to make \"/\" private mount"); + + if (mkdir (TMP_SYSROOT, 0755) < 0) + err (EXIT_FAILURE, "couldn't create temporary sysroot %s", TMP_SYSROOT); + + /* Run in the deploy_path dir so we can use relative paths below */ + if (chdir (deploy_path) < 0) + err (EXIT_FAILURE, "failed to chdir to deploy_path"); + + /* The deploy root starts out bind mounted to sysroot.tmp */ + if (mount (deploy_path, TMP_SYSROOT, NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to make initial bind mount %s", deploy_path); + + /* This will result in a system with /sysroot read-only. Thus, two additional + * writable bind-mounts (for /etc and /var) are required later on. */ + if (sysroot_readonly) + { + if (!sysroot_currently_writable) + errx (EXIT_FAILURE, "sysroot.readonly=true requires %s to be writable at this point", + root_arg); + /* Pass on the fact that we discovered a readonly sysroot to ostree-remount.service */ + int fd = open (_OSTREE_SYSROOT_READONLY_STAMP, O_WRONLY | O_CREAT | O_CLOEXEC, 0644); + if (fd < 0) + err (EXIT_FAILURE, "failed to create %s", _OSTREE_SYSROOT_READONLY_STAMP); + (void)close (fd); + } + + /* Prepare /boot. + * If /boot is on the same partition, use a bind mount to make it visible + * at /boot inside the deployment. */ + if (snprintf (srcpath, sizeof (srcpath), "%s/boot/loader", root_mountpoint) < 0) + err (EXIT_FAILURE, "failed to assemble /boot/loader path"); + if (lstat (srcpath, &stbuf) == 0 && S_ISLNK (stbuf.st_mode)) + { + if (lstat ("boot", &stbuf) == 0 && S_ISDIR (stbuf.st_mode)) + { + if (snprintf (srcpath, sizeof (srcpath), "%s/boot", root_mountpoint) < 0) + err (EXIT_FAILURE, "failed to assemble /boot path"); + if (mount (srcpath, TMP_SYSROOT "/boot", NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to bind mount %s to boot", srcpath); + } + } + + /* Prepare /etc. + * No action required if sysroot is writable. Otherwise, a bind-mount for + * the deployment needs to be created and remounted as read/write. */ + if (sysroot_readonly) + { + /* Bind-mount /etc (at deploy path), and remount as writable. */ + if (mount ("etc", TMP_SYSROOT "/etc", NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to prepare /etc bind-mount at /sysroot.tmp/etc"); + if (mount (TMP_SYSROOT "/etc", TMP_SYSROOT "/etc", NULL, MS_BIND | MS_REMOUNT | MS_SILENT, + NULL) + < 0) + err (EXIT_FAILURE, "failed to make writable /etc bind-mount at /sysroot.tmp/etc"); + } + + /* Prepare /usr. + * It may be either just a read-only bind-mount, or a persistent overlayfs. */ + if (lstat (".usr-ovl-work", &stbuf) == 0) + { + /* Do we have a persistent overlayfs for /usr? If so, mount it now. */ + const char usr_ovl_options[] + = "lowerdir=" TMP_SYSROOT "/usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; + + /* Except overlayfs barfs if we try to mount it on a read-only + * filesystem. For this use case I think admins are going to be + * okay if we remount the rootfs here, rather than waiting until + * later boot and `systemd-remount-fs.service`. + */ + if (path_is_on_readonly_fs (TMP_SYSROOT)) + { + if (mount (TMP_SYSROOT, TMP_SYSROOT, NULL, MS_REMOUNT | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to remount rootfs writable (for overlayfs)"); + } + + if (mount ("overlay", TMP_SYSROOT "/usr", "overlay", MS_SILENT, usr_ovl_options) < 0) + err (EXIT_FAILURE, "failed to mount /usr overlayfs"); + } + else + { + /* Otherwise, a read-only bind mount for /usr. (Not needed for composefs) */ + if (mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr"); + if (mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL, + MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) + < 0) + err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr"); + } + + /* Prepare /var. + * When a read-only sysroot is configured, this adds a dedicated bind-mount (to itself) + * so that the stateroot location stays writable. */ + if (sysroot_readonly) + { + /* Bind-mount /var (at stateroot path), and remount as writable. */ + if (mount ("../../var", "../../var", NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to prepare /var bind-mount at %s", srcpath); + if (mount ("../../var", "../../var", NULL, MS_BIND | MS_REMOUNT | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to make writable /var bind-mount at %s", srcpath); + } + + /* When running under systemd, /var will be handled by a 'var.mount' unit outside + * of initramfs. + * Systemd auto-detection can be overridden by a marker file under /run. */ + bool mount_var = true; + + /* If required, bind-mount `/var` in the deployment to the "stateroot", which is + * the shared persistent directory for a set of deployments. More info: + * https://ostreedev.github.io/ostree/deployment/#stateroot-aka-osname-group-of-deployments-that-share-var + */ + if (mount_var) + { + if (mount ("../../var", TMP_SYSROOT "/var", NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to bind mount ../../var to var"); + } + + if (chdir (TMP_SYSROOT) < 0) + err (EXIT_FAILURE, "failed to chdir to " TMP_SYSROOT); + + if (strcmp (root_mountpoint, "/") == 0) + { + /* pivot_root rotates two mount points around. In this instance . (the + * deploy location) becomes / and the existing / becomes /sysroot. We + * have to use pivot_root rather than mount --move in this instance + * because our deploy location is mounted as a subdirectory of the real + * sysroot, so moving sysroot would also move the deploy location. In + * reality attempting mount --move would fail with EBUSY. */ + if (pivot_root (".", "sysroot") < 0) + err (EXIT_FAILURE, "failed to pivot_root to deployment"); + } + else + { + /* In this instance typically we have our ready made-up up root at + * /sysroot.tmp and the physical root at /sysroot (root_mountpoint). + * We want to end up with our deploy root at /sysroot/ and the physical + * root under /sysroot/sysroot as systemd will be responsible for + * moving /sysroot to /. + */ + if (mount (root_mountpoint, "sysroot", NULL, MS_MOVE | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to MS_MOVE '%s' to 'sysroot'", root_mountpoint); + + if (mount (".", root_mountpoint, NULL, MS_MOVE | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to MS_MOVE %s to %s", ".", root_mountpoint); + + if (chdir (root_mountpoint) < 0) + err (EXIT_FAILURE, "failed to chdir to %s", root_mountpoint); + + if (rmdir (TMP_SYSROOT) < 0) + err (EXIT_FAILURE, "couldn't remove temporary sysroot %s", TMP_SYSROOT); + + if (sysroot_readonly) + { + if (mount ("sysroot", "sysroot", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) + < 0) + err (EXIT_FAILURE, "failed to make /sysroot read-only"); + + /* TODO(lucab): This will make the final '/' read-only. + * Stabilize read-only '/sysroot' first, then enable this additional hardening too. + * + * if (mount (".", ".", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0) + * err (EXIT_FAILURE, "failed to make / read-only"); + */ + } + } + + /* The /sysroot mount needs to be private to avoid having a mount for e.g. /var/cache + * also propagate to /sysroot/ostree/deploy/$stateroot/var/cache + * + * Now in reality, today this is overridden by systemd: the *actual* way we fix this up + * is in ostree-remount.c. But let's do it here to express the semantics we want + * at the very start (perhaps down the line systemd will have compile/runtime option + * to say that the initramfs environment did everything right from the start). + */ + if (mount ("none", "sysroot", NULL, MS_PRIVATE | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "remounting 'sysroot' private"); + + execl ("/sbin/init", "/sbin/init", NULL); + err (EXIT_FAILURE, "failed to exec init inside ostree"); +} diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index a5fbc8a..27d06fa 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -36,101 +36,110 @@ * hardlinked chroot() targets are maintained, this one does the equivalent * of chroot(). * + * # ostree-prepare-root.service + * * If using systemd, an excellent reference is `man bootup`. This * service runs Before=initrd-root-fs.target. At this point it's * assumed that the block storage and root filesystem are mounted at * /sysroot - i.e. /sysroot points to the *physical* root before - * this service runs. After, `/` is the deployment root. + * this service runs. After, `/` is the deployment root, and /sysroot is + * the physical root. + * + * # Running as pid 1 * - * There is also a secondary mode for this service when an initrd isn't - * used - instead the binary must be statically linked (and the kernel - * must have mounted the rootfs itself) - then we set things up and - * exec the real init directly. This can be popular in embedded - * systems to increase bootup speed. + * See ostree-prepare-root-static.c for this. */ #include "config.h" -#include -#include -#include -#include -#include +#include +#include +#include #include -#include -#include +#include #include #include +#include #include -#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -#if defined(HAVE_LIBSYSTEMD) && !defined(OSTREE_PREPARE_ROOT_STATIC) -#define USE_LIBSYSTEMD -#endif +#include +#include + +#include "ot-keyfile-utils.h" +#include "otcore.h" + +#define PREPARE_ROOT_CONFIG_PATH "ostree/prepare-root.conf" + +// This key is used by default if present in the initramfs to verify +// the signature on the target commit object. When composefs is +// in use, the ostree commit metadata will contain the composefs image digest, +// which can be used to fully verify the target filesystem tree. +#define BINDING_KEYPATH "/etc/ostree/initramfs-root-binding.key" + +#define SYSROOT_KEY "sysroot" +#define READONLY_KEY "readonly" + +#define ETC_KEY "etc" +#define TRANSIENT_KEY "transient" -#ifdef USE_LIBSYSTEMD -#include -#define OSTREE_PREPARE_ROOT_DEPLOYMENT_MSG SD_ID128_MAKE(71,70,33,6a,73,ba,46,01,ba,d3,1a,f8,88,aa,0d,f7) +#define COMPOSEFS_KEY "composefs" +#define ENABLED_KEY "enabled" +#define KEYPATH_KEY "keypath" + +#define OSTREE_PREPARE_ROOT_DEPLOYMENT_MSG \ + SD_ID128_MAKE (71, 70, 33, 6a, 73, ba, 46, 01, ba, d3, 1a, f8, 88, aa, 0d, f7) + +// A temporary mount point +#define TMP_SYSROOT "/sysroot.tmp" + +#ifdef HAVE_COMPOSEFS +#include +#include #endif #include "ostree-mount-util.h" -static inline bool +static bool sysroot_is_configured_ro (const char *sysroot) { - char * config_path = NULL; - assert (asprintf (&config_path, "%s/ostree/repo/config", sysroot) != -1); - FILE *f = fopen(config_path, "r"); - if (!f) + g_autoptr (GError) local_error = NULL; + g_autofree char *repo_config_path = g_build_filename (sysroot, "ostree/repo/config", NULL); + g_autoptr (GKeyFile) repo_config = g_key_file_new (); + if (!g_key_file_load_from_file (repo_config, repo_config_path, G_KEY_FILE_NONE, &local_error)) { - fprintf (stderr, "Missing expected repo config: %s\n", config_path); - free (config_path); + g_printerr ("Failed to load %s: %s", repo_config_path, local_error->message); return false; } - free (config_path); - - bool ret = false; - char *line = NULL; - size_t len = 0; - /* Note getline() will reuse the previous buffer */ - bool in_sysroot = false; - while (getline (&line, &len, f) != -1) - { - /* This is an awful hack to avoid depending on GLib in the - * initramfs right now. - */ - if (strstr (line, "[sysroot]") == line) - in_sysroot = true; - else if (*line == '[') - in_sysroot = false; - else if (in_sysroot && strstr (line, "readonly=true") == line) - { - ret = true; - break; - } - } - fclose (f); - free (line); - return ret; + return g_key_file_get_boolean (repo_config, SYSROOT_KEY, READONLY_KEY, NULL); } -static char* -resolve_deploy_path (const char * root_mountpoint) +static char * +resolve_deploy_path (const char *root_mountpoint) { char destpath[PATH_MAX]; struct stat stbuf; - char *ostree_target, *deploy_path; - - ostree_target = read_proc_cmdline_ostree (); + char *deploy_path; + g_autofree char *kernel_cmdline = read_proc_cmdline (); + if (!kernel_cmdline) + errx (EXIT_FAILURE, "Failed to read kernel cmdline"); + + g_autoptr (GError) error = NULL; + g_autofree char *ostree_target = NULL; + if (!otcore_get_ostree_target (kernel_cmdline, &ostree_target, &error)) + errx (EXIT_FAILURE, "Failed to determine ostree target: %s", error->message); if (!ostree_target) - errx (EXIT_FAILURE, "No OSTree target; expected ostree=/ostree/boot.N/..."); + errx (EXIT_FAILURE, "No ostree target found"); - if (snprintf (destpath, sizeof(destpath), "%s/%s", root_mountpoint, ostree_target) < 0) + if (snprintf (destpath, sizeof (destpath), "%s/%s", root_mountpoint, ostree_target) < 0) err (EXIT_FAILURE, "failed to assemble ostree target path"); if (lstat (destpath, &stbuf) < 0) err (EXIT_FAILURE, "Couldn't find specified OSTree root '%s'", destpath); @@ -142,93 +151,253 @@ resolve_deploy_path (const char * root_mountpoint) if (stat (deploy_path, &stbuf) < 0) err (EXIT_FAILURE, "stat(%s) failed", deploy_path); /* Quiet logs if there's no journal */ -#ifdef USE_LIBSYSTEMD const char *resolved_path = deploy_path + strlen (root_mountpoint); - sd_journal_send ("MESSAGE=Resolved OSTree target to: %s", deploy_path, + ot_journal_send ("MESSAGE=Resolved OSTree target to: %s", deploy_path, "MESSAGE_ID=" SD_ID128_FORMAT_STR, - SD_ID128_FORMAT_VAL(OSTREE_PREPARE_ROOT_DEPLOYMENT_MSG), - "DEPLOYMENT_PATH=%s", resolved_path, - "DEPLOYMENT_DEVICE=%" PRIu64, (uint64_t) stbuf.st_dev, - "DEPLOYMENT_INODE=%" PRIu64, (uint64_t) stbuf.st_ino, - NULL); -#endif + SD_ID128_FORMAT_VAL (OSTREE_PREPARE_ROOT_DEPLOYMENT_MSG), "DEPLOYMENT_PATH=%s", + resolved_path, "DEPLOYMENT_DEVICE=%" PRIu64, (uint64_t)stbuf.st_dev, + "DEPLOYMENT_INODE=%" PRIu64, (uint64_t)stbuf.st_ino, NULL); return deploy_path; } -static int -pivot_root(const char * new_root, const char * put_old) +#ifdef HAVE_COMPOSEFS +static GVariant * +load_variant (const char *root_mountpoint, const char *digest, const char *extension, + const GVariantType *type, GError **error) { - return syscall(__NR_pivot_root, new_root, put_old); + g_autofree char *path = g_strdup_printf ("%s/ostree/repo/objects/%.2s/%s.%s", root_mountpoint, + digest, digest + 2, extension); + + char *data = NULL; + gsize data_size; + if (!g_file_get_contents (path, &data, &data_size, error)) + return NULL; + + return g_variant_ref_sink (g_variant_new_from_data (type, data, data_size, FALSE, g_free, data)); } -int -main(int argc, char *argv[]) +static gboolean +load_commit_for_deploy (const char *root_mountpoint, const char *deploy_path, GVariant **commit_out, + GVariant **commitmeta_out, GError **error) { - char srcpath[PATH_MAX]; + g_autoptr (GError) local_error = NULL; + g_autofree char *digest = g_path_get_basename (deploy_path); + char *dot = strchr (digest, '.'); + if (dot != NULL) + *dot = 0; + + g_autoptr (GVariant) commit_v + = load_variant (root_mountpoint, digest, "commit", OSTREE_COMMIT_GVARIANT_FORMAT, error); + if (commit_v == NULL) + return FALSE; + + g_autoptr (GVariant) commitmeta_v = load_variant (root_mountpoint, digest, "commitmeta", + G_VARIANT_TYPE ("a{sv}"), &local_error); + if (commitmeta_v == NULL) + { + if (g_error_matches (local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + glnx_throw (error, "No commitmeta for commit %s", digest); + else + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } - /* If we're pid 1, that means there's no initramfs; in this situation - * various defaults change: - * - * - Assume that the target root is / - * - Quiet logging as there's no journal - * etc. - */ - bool running_as_pid1 = (getpid () == 1); + *commit_out = g_steal_pointer (&commit_v); + *commitmeta_out = g_steal_pointer (&commitmeta_v); - const char *root_arg = NULL; - bool we_mounted_proc = false; - if (running_as_pid1) + return TRUE; +} + +static gboolean +validate_signature (GBytes *data, GVariant *signatures, GPtrArray *pubkeys) +{ + g_assert (data); + g_assert (signatures); + g_assert (pubkeys); + + for (gsize j = 0; j < pubkeys->len; j++) { - root_arg = "/"; + GBytes *pubkey = pubkeys->pdata[j]; + g_assert (pubkey); + + for (gsize i = 0; i < g_variant_n_children (signatures); i++) + { + g_autoptr (GError) local_error = NULL; + g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i); + g_autoptr (GBytes) signature = g_variant_get_data_as_bytes (child); + bool valid = false; + + if (!otcore_validate_ed25519_signature (data, pubkey, signature, &valid, &local_error)) + errx (EXIT_FAILURE, "signature verification failed: %s", local_error->message); + if (valid) + return TRUE; + } } - else + + return FALSE; +} + +// Output a friendly message based on an errno for common cases +static const char * +composefs_error_message (int errsv) +{ + switch (errsv) { - if (argc < 2) - err (EXIT_FAILURE, "usage: ostree-prepare-root SYSROOT"); - root_arg = argv[1]; + case ENOVERITY: + return "fsverity not enabled on composefs image"; + case EWRONGVERITY: + return "Wrong fsverity digest in composefs image"; + case ENOSIGNATURE: + return "Missing signature for fsverity in composefs image"; + default: + return strerror (errsv); } -#ifdef USE_LIBSYSTEMD - sd_journal_send ("MESSAGE=preparing sysroot at %s", root_arg, - NULL); +} + #endif - struct stat stbuf; - if (stat ("/proc/cmdline", &stbuf) < 0) +typedef struct +{ + OtTristate enabled; + gboolean is_signed; + char *signature_pubkey; + GPtrArray *pubkeys; +} ComposefsConfig; + +static void +free_composefs_config (ComposefsConfig *config) +{ + g_ptr_array_unref (config->pubkeys); + g_free (config->signature_pubkey); + g_free (config); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComposefsConfig, free_composefs_config) + +// Parse the [composefs] section of the prepare-root.conf. +static ComposefsConfig * +load_composefs_config (GKeyFile *config, GError **error) +{ + GLNX_AUTO_PREFIX_ERROR ("Loading composefs config", error); + + g_autoptr (ComposefsConfig) ret = g_new0 (ComposefsConfig, 1); + + g_autofree char *enabled = g_key_file_get_value (config, COMPOSEFS_KEY, ENABLED_KEY, NULL); + if (g_strcmp0 (enabled, "signed") == 0) { - if (errno != ENOENT) - err (EXIT_FAILURE, "stat(\"/proc/cmdline\") failed"); - /* We need /proc mounted for /proc/cmdline and realpath (on musl) to - * work: */ - if (mount ("proc", "/proc", "proc", MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to mount proc on /proc"); - we_mounted_proc = 1; + ret->enabled = OT_TRISTATE_YES; + ret->is_signed = true; } + else if (!ot_keyfile_get_tristate_with_default (config, COMPOSEFS_KEY, ENABLED_KEY, + OT_TRISTATE_MAYBE, &ret->enabled, error)) + return NULL; + + // Look for a key - we default to the initramfs binding path. + if (!ot_keyfile_get_value_with_default (config, COMPOSEFS_KEY, KEYPATH_KEY, BINDING_KEYPATH, + &ret->signature_pubkey, error)) + return NULL; + + if (ret->is_signed) + { + ret->pubkeys = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref); + + g_autofree char *pubkeys = NULL; + gsize pubkeys_size; + + /* Load keys */ + if (!g_file_get_contents (ret->signature_pubkey, &pubkeys, &pubkeys_size, error)) + return glnx_prefix_error_null (error, "Reading public key file '%s'", + ret->signature_pubkey); + + g_auto (GStrv) lines = g_strsplit (pubkeys, "\n", -1); + for (char **iter = lines; *iter; iter++) + { + const char *line = *iter; + if (!*line) + continue; + + gsize pubkey_size; + g_autofree guchar *pubkey = g_base64_decode (line, &pubkey_size); + g_ptr_array_add (ret->pubkeys, g_bytes_new_take (g_steal_pointer (&pubkey), pubkey_size)); + } + + if (ret->pubkeys->len == 0) + return glnx_null_throw (error, "public key file specified, but no public keys found"); + } + + return g_steal_pointer (&ret); +} + +int +main (int argc, char *argv[]) +{ + char srcpath[PATH_MAX]; + struct stat stbuf; + g_autoptr (GError) error = NULL; + + if (argc < 2) + err (EXIT_FAILURE, "usage: ostree-prepare-root SYSROOT"); + const char *root_arg = argv[1]; + + // Since several APIs want to operate in terms of file descriptors, let's + // open the initramfs now. Currently this is just used for the config parser. + glnx_autofd int initramfs_rootfs_fd = -1; + if (!glnx_opendirat (AT_FDCWD, "/", FALSE, &initramfs_rootfs_fd, &error)) + errx (EXIT_FAILURE, "Failed to open /: %s", error->message); + + g_autoptr (GKeyFile) config + = otcore_load_config (initramfs_rootfs_fd, PREPARE_ROOT_CONFIG_PATH, &error); + if (!config) + errx (EXIT_FAILURE, "Failed to parse config: %s", error->message); + + gboolean sysroot_readonly = FALSE; + + // We always parse the composefs config, because we want to detect and error + // out if it's enabled, but not supported at compile time. + g_autoptr (ComposefsConfig) composefs_config = load_composefs_config (config, &error); + if (!composefs_config) + errx (EXIT_FAILURE, "%s", error->message); + + // If composefs is enabled, that also implies sysroot.readonly=true because it's + // the new default we want to use (not because it's actually required) + const bool sysroot_readonly_default = composefs_config->enabled == OT_TRISTATE_YES; + if (!ot_keyfile_get_boolean_with_default (config, SYSROOT_KEY, READONLY_KEY, + sysroot_readonly_default, &sysroot_readonly, &error)) + errx (EXIT_FAILURE, "Failed to parse sysroot.readonly value: %s", error->message); + + /* This is the final target where we should prepare the rootfs. The usual + * case with systemd in the initramfs is that root_mountpoint = "/sysroot". + * In the fastboot embedded case we're pid1 and will setup / ourself, and + * then root_mountpoint = "/". + * */ const char *root_mountpoint = realpath (root_arg, NULL); if (root_mountpoint == NULL) err (EXIT_FAILURE, "realpath(\"%s\")", root_arg); char *deploy_path = resolve_deploy_path (root_mountpoint); - if (we_mounted_proc) - { - /* Leave the filesystem in the state that we found it: */ - if (umount ("/proc")) - err (EXIT_FAILURE, "failed to umount proc from /proc"); - } + if (mkdirat (AT_FDCWD, OTCORE_RUN_OSTREE, 0755) < 0) + err (EXIT_FAILURE, "Failed to create %s", OTCORE_RUN_OSTREE); + if (mkdirat (AT_FDCWD, OTCORE_RUN_OSTREE_PRIVATE, 0) < 0) + err (EXIT_FAILURE, "Failed to create %s", OTCORE_RUN_OSTREE_PRIVATE); - /* Query the repository configuration - this is an operating system builder - * choice. More info: https://github.com/ostreedev/ostree/pull/1767 + /* Fall back to querying the repository configuration in the target disk. + * This is an operating system builder choice. More info: + * https://github.com/ostreedev/ostree/pull/1767 + * However, we only do this if composefs is not enabled, because we don't + * want to parse the target root filesystem before verifying its integrity. */ - const bool sysroot_readonly = sysroot_is_configured_ro (root_arg); + if (!sysroot_readonly && composefs_config->enabled != OT_TRISTATE_YES) + { + sysroot_readonly = sysroot_is_configured_ro (root_arg); + // Encourage porting to the new config file + if (sysroot_readonly) + g_print ("Found legacy sysroot.readonly flag, not configured in %s\n", + PREPARE_ROOT_CONFIG_PATH); + } const bool sysroot_currently_writable = !path_is_on_readonly_fs (root_arg); -#ifdef USE_LIBSYSTEMD - sd_journal_send ("MESSAGE=filesystem at %s currently writable: %d", root_arg, - (int)sysroot_currently_writable, - NULL); - sd_journal_send ("MESSAGE=sysroot.readonly configuration value: %d", - (int)sysroot_readonly, - NULL); -#endif + g_print ("sysroot.readonly configuration value: %d (fs writable: %d)\n", (int)sysroot_readonly, + (int)sysroot_currently_writable); /* Work-around for a kernel bug: for some reason the kernel * refuses switching root if any file systems are mounted @@ -239,16 +408,115 @@ main(int argc, char *argv[]) if (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE | MS_SILENT, NULL) < 0) err (EXIT_FAILURE, "failed to make \"/\" private mount"); - /* Make deploy_path a bind mount, so we can move it later */ - if (mount (deploy_path, deploy_path, NULL, MS_BIND | MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to make initial bind mount %s", deploy_path); + if (mkdir (TMP_SYSROOT, 0755) < 0) + err (EXIT_FAILURE, "couldn't create temporary sysroot %s", TMP_SYSROOT); - /* chdir to our new root. We need to do this after bind-mounting it over - * itself otherwise our cwd is still on the non-bind-mounted filesystem - * below. */ + /* Run in the deploy_path dir so we can use relative paths below */ if (chdir (deploy_path) < 0) err (EXIT_FAILURE, "failed to chdir to deploy_path"); + GVariantBuilder metadata_builder; + g_variant_builder_init (&metadata_builder, G_VARIANT_TYPE ("a{sv}")); + + // Tracks if we did successfully enable it at runtime + bool using_composefs = false; + +#ifdef HAVE_COMPOSEFS + /* We construct the new sysroot in /sysroot.tmp, which is either the composfs + mount or a bind mount of the deploy-dir */ + if (composefs_config->enabled != OT_TRISTATE_NO) + { + const char *objdirs[] = { "/sysroot/ostree/repo/objects" }; + g_autofree char *cfs_digest = NULL; + struct lcfs_mount_options_s cfs_options = { + objdirs, + 1, + }; + + cfs_options.flags = LCFS_MOUNT_FLAGS_READONLY; + cfs_options.image_mountdir = OSTREE_COMPOSEFS_LOWERMNT; + if (mkdirat (AT_FDCWD, OSTREE_COMPOSEFS_LOWERMNT, 0700) < 0) + err (EXIT_FAILURE, "Failed to create %s", OSTREE_COMPOSEFS_LOWERMNT); + + g_autofree char *expected_digest = NULL; + + if (composefs_config->is_signed) + { + const char *composefs_pubkey = composefs_config->signature_pubkey; + g_autoptr (GError) local_error = NULL; + g_autoptr (GVariant) commit = NULL; + g_autoptr (GVariant) commitmeta = NULL; + + if (!load_commit_for_deploy (root_mountpoint, deploy_path, &commit, &commitmeta, + &local_error)) + errx (EXIT_FAILURE, "Error loading signatures from repo: %s", local_error->message); + + g_autoptr (GVariant) signatures = g_variant_lookup_value ( + commitmeta, OSTREE_SIGN_METADATA_ED25519_KEY, G_VARIANT_TYPE ("aay")); + if (signatures == NULL) + errx (EXIT_FAILURE, "Signature validation requested, but no signatures in commit"); + + g_autoptr (GBytes) commit_data = g_variant_get_data_as_bytes (commit); + if (!validate_signature (commit_data, signatures, composefs_config->pubkeys)) + errx (EXIT_FAILURE, "No valid signatures found for public key"); + + g_print ("composefs+ostree: Validated commit signature using '%s'\n", composefs_pubkey); + g_variant_builder_add (&metadata_builder, "{sv}", + OTCORE_RUN_BOOTED_KEY_COMPOSEFS_SIGNATURE, + g_variant_new_string (composefs_pubkey)); + + g_autoptr (GVariant) metadata = g_variant_get_child_value (commit, 0); + g_autoptr (GVariant) cfs_digest_v = g_variant_lookup_value ( + metadata, OSTREE_COMPOSEFS_DIGEST_KEY_V0, G_VARIANT_TYPE_BYTESTRING); + if (cfs_digest_v == NULL || g_variant_get_size (cfs_digest_v) != OSTREE_SHA256_DIGEST_LEN) + errx (EXIT_FAILURE, "Signature validation requested, but no valid digest in commit"); + const guint8 *cfs_digest_buf = ot_variant_get_data (cfs_digest_v, &error); + if (!cfs_digest_buf) + errx (EXIT_FAILURE, "Failed to query digest: %s", error->message); + + expected_digest = g_malloc (OSTREE_SHA256_STRING_LEN + 1); + ot_bin2hex (expected_digest, cfs_digest_buf, g_variant_get_size (cfs_digest_v)); + + cfs_options.flags |= LCFS_MOUNT_FLAGS_REQUIRE_VERITY; + g_print ("composefs: Verifying digest: %s\n", expected_digest); + cfs_options.expected_fsverity_digest = expected_digest; + } + + if (lcfs_mount_image (OSTREE_COMPOSEFS_NAME, TMP_SYSROOT, &cfs_options) == 0) + { + using_composefs = true; + g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_COMPOSEFS, + g_variant_new_boolean (true)); + g_print ("composefs: mounted successfully"); + } + else + { + int errsv = errno; + g_assert (composefs_config->enabled != OT_TRISTATE_NO); + if (composefs_config->enabled == OT_TRISTATE_MAYBE && errsv == ENOENT) + { + g_print ("composefs: No image present\n"); + } + else + { + const char *errmsg = composefs_error_message (errsv); + errx (EXIT_FAILURE, "composefs: failed to mount: %s", errmsg); + } + } + } +#else + /* if composefs is configured as "maybe", we should continue */ + if (composefs_config->enabled == OT_TRISTATE_YES) + errx (EXIT_FAILURE, "composefs: enabled at runtime, but support is not compiled in"); +#endif + + if (!using_composefs) + { + /* The deploy root starts out bind mounted to sysroot.tmp */ + if (mount (deploy_path, TMP_SYSROOT, NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to make initial bind mount %s", deploy_path); + } + /* This will result in a system with /sysroot read-only. Thus, two additional * writable bind-mounts (for /etc and /var) are required later on. */ if (sysroot_readonly) @@ -256,25 +524,23 @@ main(int argc, char *argv[]) if (!sysroot_currently_writable) errx (EXIT_FAILURE, "sysroot.readonly=true requires %s to be writable at this point", root_arg); - /* Pass on the fact that we discovered a readonly sysroot to ostree-remount.service */ - int fd = open (_OSTREE_SYSROOT_READONLY_STAMP, O_WRONLY | O_CREAT | O_CLOEXEC, 0644); - if (fd < 0) - err (EXIT_FAILURE, "failed to create %s", _OSTREE_SYSROOT_READONLY_STAMP); - (void) close (fd); } + /* Pass on the state for use by ostree-prepare-root */ + g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_SYSROOT_RO, + g_variant_new_boolean (sysroot_readonly)); /* Prepare /boot. * If /boot is on the same partition, use a bind mount to make it visible * at /boot inside the deployment. */ - if (snprintf (srcpath, sizeof(srcpath), "%s/boot/loader", root_mountpoint) < 0) + if (snprintf (srcpath, sizeof (srcpath), "%s/boot/loader", root_mountpoint) < 0) err (EXIT_FAILURE, "failed to assemble /boot/loader path"); if (lstat (srcpath, &stbuf) == 0 && S_ISLNK (stbuf.st_mode)) { if (lstat ("boot", &stbuf) == 0 && S_ISDIR (stbuf.st_mode)) { - if (snprintf (srcpath, sizeof(srcpath), "%s/boot", root_mountpoint) < 0) + if (snprintf (srcpath, sizeof (srcpath), "%s/boot", root_mountpoint) < 0) err (EXIT_FAILURE, "failed to assemble /boot path"); - if (mount (srcpath, "boot", NULL, MS_BIND | MS_SILENT, NULL) < 0) + if (mount (srcpath, TMP_SYSROOT "/boot", NULL, MS_BIND | MS_SILENT, NULL) < 0) err (EXIT_FAILURE, "failed to bind mount %s to boot", srcpath); } } @@ -282,42 +548,85 @@ main(int argc, char *argv[]) /* Prepare /etc. * No action required if sysroot is writable. Otherwise, a bind-mount for * the deployment needs to be created and remounted as read/write. */ - if (sysroot_readonly) - { - /* Bind-mount /etc (at deploy path), and remount as writable. */ - if (mount ("etc", "etc", NULL, MS_BIND | MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to prepare /etc bind-mount at %s", srcpath); - if (mount ("etc", "etc", NULL, MS_BIND | MS_REMOUNT | MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to make writable /etc bind-mount at %s", srcpath); - } + if (sysroot_readonly || using_composefs) + { + gboolean etc_transient = FALSE; + if (!ot_keyfile_get_boolean_with_default (config, ETC_KEY, TRANSIENT_KEY, FALSE, + &etc_transient, &error)) + errx (EXIT_FAILURE, "Failed to parse etc.transient value: %s", error->message); + + if (etc_transient) + { + char *ovldir = "/run/ostree/transient-etc"; + + g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_TRANSIENT_ETC, + g_variant_new_string (ovldir)); + + char *lowerdir = "usr/etc"; + if (using_composefs) + lowerdir = TMP_SYSROOT "/usr/etc"; + + g_autofree char *upperdir = g_build_filename (ovldir, "upper", NULL); + g_autofree char *workdir = g_build_filename (ovldir, "work", NULL); + + struct + { + const char *path; + int mode; + } subdirs[] = { { ovldir, 0700 }, { upperdir, 0755 }, { workdir, 0755 } }; + for (int i = 0; i < G_N_ELEMENTS (subdirs); i++) + { + if (mkdirat (AT_FDCWD, subdirs[i].path, subdirs[i].mode) < 0) + err (EXIT_FAILURE, "Failed to create dir %s", subdirs[i].path); + } + + g_autofree char *ovl_options + = g_strdup_printf ("lowerdir=%s,upperdir=%s,workdir=%s", lowerdir, upperdir, workdir); + if (mount ("overlay", TMP_SYSROOT "/etc", "overlay", MS_SILENT, ovl_options) < 0) + err (EXIT_FAILURE, "failed to mount transient etc overlayfs"); + } + else + { + /* Bind-mount /etc (at deploy path), and remount as writable. */ + if (mount ("etc", TMP_SYSROOT "/etc", NULL, MS_BIND | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to prepare /etc bind-mount at /sysroot.tmp/etc"); + if (mount (TMP_SYSROOT "/etc", TMP_SYSROOT "/etc", NULL, MS_BIND | MS_REMOUNT | MS_SILENT, + NULL) + < 0) + err (EXIT_FAILURE, "failed to make writable /etc bind-mount at /sysroot.tmp/etc"); + } + } /* Prepare /usr. * It may be either just a read-only bind-mount, or a persistent overlayfs. */ if (lstat (".usr-ovl-work", &stbuf) == 0) { /* Do we have a persistent overlayfs for /usr? If so, mount it now. */ - const char usr_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; + const char usr_ovl_options[] + = "lowerdir=" TMP_SYSROOT "/usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; /* Except overlayfs barfs if we try to mount it on a read-only * filesystem. For this use case I think admins are going to be * okay if we remount the rootfs here, rather than waiting until * later boot and `systemd-remount-fs.service`. */ - if (path_is_on_readonly_fs (".")) + if (path_is_on_readonly_fs (TMP_SYSROOT)) { - if (mount (".", ".", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0) + if (mount (TMP_SYSROOT, TMP_SYSROOT, NULL, MS_REMOUNT | MS_SILENT, NULL) < 0) err (EXIT_FAILURE, "failed to remount rootfs writable (for overlayfs)"); } - if (mount ("overlay", "usr", "overlay", MS_SILENT, usr_ovl_options) < 0) + if (mount ("overlay", TMP_SYSROOT "/usr", "overlay", MS_SILENT, usr_ovl_options) < 0) err (EXIT_FAILURE, "failed to mount /usr overlayfs"); } - else + else if (!using_composefs) { - /* Otherwise, a read-only bind mount for /usr */ - if (mount ("usr", "usr", NULL, MS_BIND | MS_SILENT, NULL) < 0) + /* Otherwise, a read-only bind mount for /usr. (Not needed for composefs) */ + if (mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL, MS_BIND | MS_SILENT, NULL) < 0) err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr"); - if (mount ("usr", "usr", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0) + if (mount (TMP_SYSROOT "/usr", TMP_SYSROOT "/usr", NULL, + MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) + < 0) err (EXIT_FAILURE, "failed to bind mount (class:readonly) /usr"); } @@ -333,9 +642,9 @@ main(int argc, char *argv[]) err (EXIT_FAILURE, "failed to make writable /var bind-mount at %s", srcpath); } - /* When running under systemd, /var will be handled by a 'var.mount' unit outside - * of initramfs. - * Systemd auto-detection can be overridden by a marker file under /run. */ + /* When running under systemd, /var will be handled by a 'var.mount' unit outside + * of initramfs. + * Systemd auto-detection can be overridden by a marker file under /run. */ #ifdef HAVE_SYSTEMD_AND_LIBMOUNT bool mount_var = false; #else @@ -345,76 +654,57 @@ main(int argc, char *argv[]) mount_var = true; /* If required, bind-mount `/var` in the deployment to the "stateroot", which is - * the shared persistent directory for a set of deployments. More info: - * https://ostreedev.github.io/ostree/deployment/#stateroot-aka-osname-group-of-deployments-that-share-var - */ + * the shared persistent directory for a set of deployments. More info: + * https://ostreedev.github.io/ostree/deployment/#stateroot-aka-osname-group-of-deployments-that-share-var + */ if (mount_var) { - if (mount ("../../var", "var", NULL, MS_BIND | MS_SILENT, NULL) < 0) + if (mount ("../../var", TMP_SYSROOT "/var", NULL, MS_BIND | MS_SILENT, NULL) < 0) err (EXIT_FAILURE, "failed to bind mount ../../var to var"); } - /* We only stamp /run now if we're running in an initramfs, i.e. we're - * not pid 1. Otherwise it's handled later via ostree-system-generator. - * https://mail.gnome.org/archives/ostree-list/2018-March/msg00012.html - * https://github.com/ostreedev/ostree/pull/1675 - */ - if (!running_as_pid1) - touch_run_ostree (); + /* This can be used by other things to signal ostree is in use */ + { + g_autoptr (GVariant) metadata = g_variant_ref_sink (g_variant_builder_end (&metadata_builder)); + const guint8 *buf = g_variant_get_data (metadata) ?: (guint8 *)""; + if (!glnx_file_replace_contents_at (AT_FDCWD, OTCORE_RUN_BOOTED, buf, + g_variant_get_size (metadata), 0, NULL, &error)) + errx (EXIT_FAILURE, "Writing %s: %s", OTCORE_RUN_BOOTED, error->message); + } - if (strcmp(root_mountpoint, "/") == 0) - { - /* pivot_root rotates two mount points around. In this instance . (the - * deploy location) becomes / and the existing / becomes /sysroot. We - * have to use pivot_root rather than mount --move in this instance - * because our deploy location is mounted as a subdirectory of the real - * sysroot, so moving sysroot would also move the deploy location. In - * reality attempting mount --move would fail with EBUSY. */ - if (pivot_root (".", "sysroot") < 0) - err (EXIT_FAILURE, "failed to pivot_root to deployment"); - } - else - { - /* In this instance typically we have our ready made-up up root at - * /sysroot/ostree/deploy/.../ (deploy_path) and the real rootfs at - * /sysroot (root_mountpoint). We want to end up with our made-up root at - * /sysroot/ and the real rootfs under /sysroot/sysroot as systemd will be - * responsible for moving /sysroot to /. - * - * We need to do this in 3 moves to avoid trying to move /sysroot under - * itself: - * - * 1. /sysroot/ostree/deploy/... -> /sysroot.tmp - * 2. /sysroot -> /sysroot.tmp/sysroot - * 3. /sysroot.tmp -> /sysroot - */ - if (mkdir ("/sysroot.tmp", 0755) < 0) - err (EXIT_FAILURE, "couldn't create temporary sysroot /sysroot.tmp"); + if (chdir (TMP_SYSROOT) < 0) + err (EXIT_FAILURE, "failed to chdir to " TMP_SYSROOT); - if (mount (deploy_path, "/sysroot.tmp", NULL, MS_MOVE | MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to MS_MOVE '%s' to '/sysroot.tmp'", deploy_path); + /* Now we have our ready made-up up root at + * /sysroot.tmp and the physical root at /sysroot (root_mountpoint). + * We want to end up with our deploy root at /sysroot/ and the physical + * root under /sysroot/sysroot as systemd will be responsible for + * moving /sysroot to /. + */ + if (mount (root_mountpoint, "sysroot", NULL, MS_MOVE | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to MS_MOVE '%s' to 'sysroot'", root_mountpoint); - if (mount (root_mountpoint, "sysroot", NULL, MS_MOVE | MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to MS_MOVE '%s' to 'sysroot'", root_mountpoint); + if (mount (".", root_mountpoint, NULL, MS_MOVE | MS_SILENT, NULL) < 0) + err (EXIT_FAILURE, "failed to MS_MOVE %s to %s", ".", root_mountpoint); - if (mount (".", root_mountpoint, NULL, MS_MOVE | MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to MS_MOVE %s to %s", deploy_path, root_mountpoint); + if (chdir (root_mountpoint) < 0) + err (EXIT_FAILURE, "failed to chdir to %s", root_mountpoint); - if (rmdir ("/sysroot.tmp") < 0) - err (EXIT_FAILURE, "couldn't remove temporary sysroot /sysroot.tmp"); + if (rmdir (TMP_SYSROOT) < 0) + err (EXIT_FAILURE, "couldn't remove temporary sysroot %s", TMP_SYSROOT); - if (sysroot_readonly) - { - if (mount ("sysroot", "sysroot", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0) - err (EXIT_FAILURE, "failed to make /sysroot read-only"); - - /* TODO(lucab): This will make the final '/' read-only. - * Stabilize read-only '/sysroot' first, then enable this additional hardening too. - * - * if (mount (".", ".", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0) - * err (EXIT_FAILURE, "failed to make / read-only"); - */ - } + if (sysroot_readonly) + { + if (mount ("sysroot", "sysroot", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) + < 0) + err (EXIT_FAILURE, "failed to make /sysroot read-only"); + + /* TODO(lucab): This will make the final '/' read-only. + * Stabilize read-only '/sysroot' first, then enable this additional hardening too. + * + * if (mount (".", ".", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0) + * err (EXIT_FAILURE, "failed to make / read-only"); + */ } /* The /sysroot mount needs to be private to avoid having a mount for e.g. /var/cache @@ -428,13 +718,5 @@ main(int argc, char *argv[]) if (mount ("none", "sysroot", NULL, MS_PRIVATE | MS_SILENT, NULL) < 0) err (EXIT_FAILURE, "remounting 'sysroot' private"); - if (running_as_pid1) - { - execl ("/sbin/init", "/sbin/init", NULL); - err (EXIT_FAILURE, "failed to exec init inside ostree"); - } - else - { - exit (EXIT_SUCCESS); - } + exit (EXIT_SUCCESS); } diff --git a/src/switchroot/ostree-remount.c b/src/switchroot/ostree-remount.c index 4044b5a..497603e 100644 --- a/src/switchroot/ostree-remount.c +++ b/src/switchroot/ostree-remount.c @@ -21,29 +21,29 @@ #include "config.h" -#include -#include +#include +#include +#include #include #include #include -#include +#include +#include +#include #include +#include +#include #include -#include -#include #include -#include -#include -#include - -#include +#ifdef HAVE_SELINUX +#include +#endif #include "ostree-mount-util.h" -#include "glnx-backport-autocleanups.h" +#include "otcore.h" static void -do_remount (const char *target, - bool writable) +do_remount (const char *target, bool writable) { struct stat stbuf; if (lstat (target, &stbuf) < 0) @@ -70,7 +70,7 @@ do_remount (const char *target, /* Also ignore EINVAL - if the target isn't a mountpoint * already, then assume things are OK. */ - if (errno != EINVAL) + if (errno != EINVAL) err (EXIT_FAILURE, "failed to remount(%s) %s", writable ? "rw" : "ro", target); else return; @@ -79,13 +79,83 @@ do_remount (const char *target, printf ("Remounted %s: %s\n", writable ? "rw" : "ro", target); } +/* Relabel the directory $real_path, which is going to be an overlayfs mount, + * based on the content of an overlayfs upperdirectory that is in use by the mount. + * The goal is that we relabel in the overlay mount all the files that have been + * modified (directly or via parent copyup operations) since the overlayfs was + * mounted. This will be used for the /etc overlayfs mount where no selinux labels + * are set before selinux policy is loaded. + */ +static void +relabel_dir_for_upper (const char *upper_path, const char *real_path, gboolean is_dir) +{ +#ifdef HAVE_SELINUX + if (selinux_restorecon (real_path, 0)) + err (EXIT_FAILURE, "Failed to relabel %s", real_path); + + if (!is_dir) + return; + + g_auto (GLnxDirFdIterator) dfd_iter = { + 0, + }; + + if (!glnx_dirfd_iterator_init_at (AT_FDCWD, upper_path, FALSE, &dfd_iter, NULL)) + err (EXIT_FAILURE, "Failed to open upper directory %s for relabeling", upper_path); + + while (TRUE) + { + struct dirent *dent; + + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, NULL, NULL)) + { + err (EXIT_FAILURE, "Failed to read upper directory %s for relabelin", upper_path); + break; + } + + if (dent == NULL) + break; + + g_autofree char *upper_child = g_build_filename (upper_path, dent->d_name, NULL); + g_autofree char *real_child = g_build_filename (real_path, dent->d_name, NULL); + relabel_dir_for_upper (upper_child, real_child, dent->d_type == DT_DIR); + } +#endif +} + int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - /* When systemd is in use this is normally created via the generator, but - * we ensure it's created here as well for redundancy. - */ - touch_run_ostree (); + g_autoptr (GError) error = NULL; + g_autoptr (GVariant) ostree_run_metadata_v = NULL; + { + glnx_autofd int fd = open (OTCORE_RUN_BOOTED, O_RDONLY | O_CLOEXEC); + if (fd < 0) + { + /* We really expect that nowadays that everything is done in the initramfs, + * but historically we created this file here, so we'll continue to do be + * sure here it exists. This code should be removed at some point though. + */ + if (errno == ENOENT) + { + int subfd = open (OTCORE_RUN_BOOTED, O_EXCL | O_CREAT | O_WRONLY | O_NOCTTY | O_CLOEXEC, + 0640); + if (subfd != -1) + (void)close (subfd); + } + else + { + err (EXIT_FAILURE, "failed to open %s", OTCORE_RUN_BOOTED); + } + } + else + { + if (!ot_variant_read_fd (fd, 0, G_VARIANT_TYPE_VARDICT, TRUE, &ostree_run_metadata_v, + &error)) + errx (EXIT_FAILURE, "failed to read %s: %s", OTCORE_RUN_BOOTED, error->message); + } + } + g_autoptr (GVariantDict) ostree_run_metadata = g_variant_dict_new (ostree_run_metadata_v); /* The /sysroot mount needs to be private to avoid having a mount for e.g. /var/cache * also propagate to /sysroot/ostree/deploy/$stateroot/var/cache @@ -96,7 +166,57 @@ main(int argc, char *argv[]) if (mount ("none", "/sysroot", NULL, MS_REC | MS_PRIVATE, NULL) < 0) perror ("warning: While remounting /sysroot MS_PRIVATE"); - if (path_is_on_readonly_fs ("/")) + const char *transient_etc = NULL; + g_variant_dict_lookup (ostree_run_metadata, OTCORE_RUN_BOOTED_KEY_TRANSIENT_ETC, "&s", + &transient_etc); + + if (transient_etc) + { + /* If the initramfs created any files in /etc (directly or via overlay copy-up) they + * will be unlabeled, because the selinux policy is not loaded until after the + * pivot-root. So, for all files in the upper dir, relabel the corresponding overlay + * file. + * + * Also, note that during boot systemd will create a /run/machine-id -> + * /etc/machine-id bind mount (as /etc is read-only early on). It will then later + * replace this mount with a real one (in systemd-machine-id-commit.service). + * + * We need to label the actual overlayfs file, not the temporary bind-mount. To do + * this we unmount the covering mount before relabeling, but we do so in a temporary + * private namespace to avoid affecting other parts of the system. + */ + + glnx_autofd int initial_ns_fd = -1; + if (g_file_test ("/run/machine-id", G_FILE_TEST_EXISTS) + && g_file_test ("/etc/machine-id", G_FILE_TEST_EXISTS)) + { + initial_ns_fd = open ("/proc/self/ns/mnt", O_RDONLY | O_NOCTTY | O_CLOEXEC); + if (initial_ns_fd < 0) + err (EXIT_FAILURE, "Failed to open initial namespace"); + + if (unshare (CLONE_NEWNS) < 0) + err (EXIT_FAILURE, "Failed to unshare initial namespace"); + + /* Ensure unmount is not propagated */ + if (mount ("none", "/etc", NULL, MS_REC | MS_PRIVATE, NULL) < 0) + err (EXIT_FAILURE, "warning: While remounting /etc MS_PRIVATE"); + + if (umount2 ("/etc/machine-id", MNT_DETACH) < 0) + err (EXIT_FAILURE, "Failed to unmount machine-id"); + } + + g_autofree char *upper = g_build_filename (transient_etc, "upper", NULL); + relabel_dir_for_upper (upper, "/etc", TRUE); + + if (initial_ns_fd != -1 && setns (initial_ns_fd, CLONE_NEWNS) < 0) + err (EXIT_FAILURE, "Failed to join initial namespace"); + } + + gboolean root_is_composefs = FALSE; + g_variant_dict_lookup (ostree_run_metadata, OTCORE_RUN_BOOTED_KEY_COMPOSEFS, "b", + &root_is_composefs); + + if (path_is_on_readonly_fs ("/") && !root_is_composefs) { /* If / isn't writable, don't do any remounts; we don't want * to clear the readonly flag in that case. @@ -107,24 +227,26 @@ main(int argc, char *argv[]) /* Handle remounting /sysroot; if it's explicitly marked as read-only (opt in) * then ensure it's readonly, otherwise mount writable, the same as / */ - bool sysroot_configured_readonly = unlink (_OSTREE_SYSROOT_READONLY_STAMP) == 0; + gboolean sysroot_configured_readonly = FALSE; + g_variant_dict_lookup (ostree_run_metadata, OTCORE_RUN_BOOTED_KEY_SYSROOT_RO, "b", + &sysroot_configured_readonly); do_remount ("/sysroot", !sysroot_configured_readonly); /* And also make sure to make /etc rw again. We make this conditional on - * sysroot_configured_readonly because only in that case is it a bind-mount. */ - if (sysroot_configured_readonly) + * sysroot_configured_readonly && !transient_etc because only in that case is it a + * bind-mount. */ + if (sysroot_configured_readonly && !transient_etc) do_remount ("/etc", true); - /* If /var was created as as an OSTree default bind mount (instead of being a separate filesystem) - * then remounting the root mount read-only also remounted it. - * So just like /etc, we need to make it read-write by default. - * If it was a separate filesystem, we expect it to be writable anyways, - * so it doesn't hurt to remount it if so. - * - * And if we started out with a writable system root, then we need - * to ensure that the /var bind mount created by the systemd generator - * is writable too. - */ + /* If /var was created as as an OSTree default bind mount (instead of being a separate + * filesystem) then remounting the root mount read-only also remounted it. So just like /etc, we + * need to make it read-write by default. If it was a separate filesystem, we expect it to be + * writable anyways, so it doesn't hurt to remount it if so. + * + * And if we started out with a writable system root, then we need + * to ensure that the /var bind mount created by the systemd generator + * is writable too. + */ do_remount ("/var", true); exit (EXIT_SUCCESS); diff --git a/src/switchroot/ostree-system-generator.c b/src/switchroot/ostree-system-generator.c index bd0901b..4fddc36 100644 --- a/src/switchroot/ostree-system-generator.c +++ b/src/switchroot/ostree-system-generator.c @@ -20,15 +20,14 @@ #include "config.h" #include -#include -#include #include #include +#include +#include #include #include "ostree-cmd-private.h" -#include "ostree-mount-util.h" static const char *arg_dest = "/tmp"; static const char *arg_dest_late = "/tmp"; @@ -37,18 +36,8 @@ static const char *arg_dest_late = "/tmp"; * lives inside libostree. */ int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - /* We conflict with the magic ostree-mount-deployment-var file for ostree-prepare-root */ - { struct stat stbuf; - if (fstatat (AT_FDCWD, INITRAMFS_MOUNT_VAR, &stbuf, 0) == 0) - { - if (unlinkat (AT_FDCWD, INITRAMFS_MOUNT_VAR, 0) < 0) - err (EXIT_FAILURE, "Can't unlink " INITRAMFS_MOUNT_VAR); - exit (EXIT_SUCCESS); - } - } - if (argc > 1 && argc != 4) errx (EXIT_FAILURE, "This program takes three or no arguments"); @@ -57,25 +46,10 @@ main(int argc, char *argv[]) if (argc > 3) arg_dest_late = argv[3]; - /* If we're installed on a system which isn't using OSTree for boot (e.g. - * package installed as a dependency for flatpak or whatever), silently - * exit so that we don't error, but at the same time work where switchroot - * is PID 1 (and so hasn't created /run/ostree-booted). - */ - char *ostree_cmdline = read_proc_cmdline_ostree (); - if (!ostree_cmdline) - exit (EXIT_SUCCESS); - - /* See comments in ostree-prepare-root.c for this. - * - * It's a lot easier for various bits of userspace to check for - * a file versus parsing the kernel cmdline. So let's ensure - * the stamp file is created here too. - */ - touch_run_ostree (); - - { g_autoptr(GError) local_error = NULL; - if (!ostree_cmd__private__()->ostree_system_generator (ostree_cmdline, arg_dest, NULL, arg_dest_late, &local_error)) + { + g_autoptr (GError) local_error = NULL; + if (!ostree_cmd__private__ ()->ostree_system_generator (arg_dest, NULL, arg_dest_late, + &local_error)) errx (EXIT_FAILURE, "%s", local_error->message); } diff --git a/tests/admin-test.sh b/tests/admin-test.sh index 366dece..520a875 100644 --- a/tests/admin-test.sh +++ b/tests/admin-test.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..$((28 + ${extra_admin_tests:-0}))" +echo "1..$((30 + ${extra_admin_tests:-0}))" mkdir sysrootmin ${CMD_PREFIX} ostree admin init-fs --modern sysrootmin @@ -76,6 +76,13 @@ assert_file_has_content curdir ^`pwd`/sysroot/ostree/deploy/testos/deploy/${rev} echo "ok --print-current-dir" +if ${CMD_PREFIX} ostree admin deploy --stateroot=nosuchroot testos:testos/buildmain/x86_64-runtime 2>err.txt; then + fatal "deployed to nonexistent root" +fi +assert_file_has_content err.txt "error:.*No such stateroot: nosuchroot" + +echo "ok nice error for deploy with no stateroot" + # Test layout of bootloader config and refs assert_not_has_dir sysroot/boot/loader.0 assert_has_dir sysroot/boot/loader.1 @@ -97,7 +104,7 @@ assert_file_has_content_literal err.txt "Cannot stage deployment: Not currently echo "ok staging does not work when not booted" orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy) -${CMD_PREFIX} ostree admin deploy --os=testos testos:testos/buildmain/x86_64-runtime +${CMD_PREFIX} ostree admin deploy --stateroot=testos testos:testos/buildmain/x86_64-runtime new_mtime=$(stat -c '%.Y' sysroot/ostree/deploy) assert_not_streq "${orig_mtime}" "${new_mtime}" # Need a new bootversion, sine we now have two deployments @@ -208,6 +215,16 @@ validate_bootloader echo "ok deploy --retain-rollback" + +${CMD_PREFIX} ostree admin status +assert_file_has_content sysroot/boot/loader/entries/ostree-3-otheros.conf "^title.*TestOS 42 1.0.10" +${CMD_PREFIX} ostree admin set-default 1 +assert_file_has_content sysroot/boot/loader/entries/ostree-3-testos.conf "^title.*TestOS 42 1.0.10" +${CMD_PREFIX} ostree admin set-default 1 +assert_file_has_content sysroot/boot/loader/entries/ostree-3-otheros.conf "^title.*TestOS 42 1.0.10" + +echo "ok set-default" + os_repository_new_commit ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime newrev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos:testos/buildmain/x86_64-runtime) diff --git a/tests/archive-test.sh b/tests/archive-test.sh index b6d8497..f6bfd5f 100644 --- a/tests/archive-test.sh +++ b/tests/archive-test.sh @@ -71,6 +71,11 @@ mkdir -p test-overlays date > test-overlays/overlaid-file $OSTREE commit ${COMMIT_ARGS} -b test-base --base test2 --owner-uid 42 --owner-gid 42 test-overlays/ $OSTREE ls -R test-base > ls.txt -assert_streq "$(wc -l < ls.txt)" 14 +if can_create_whiteout_devices; then + assert_streq "$(wc -l < ls.txt)" 22 +else + assert_streq "$(wc -l < ls.txt)" 19 +fi + assert_streq "$(grep '42.*42' ls.txt | wc -l)" 2 echo "ok commit overlay base" diff --git a/tests/basic-test.sh b/tests/basic-test.sh index 04506c3..7905e6e 100644 --- a/tests/basic-test.sh +++ b/tests/basic-test.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..$((87 + ${extra_basic_tests:-0}))" +echo "1..$((90 + ${extra_basic_tests:-0}))" CHECKOUT_U_ARG="" CHECKOUT_H_ARGS="-H" @@ -97,6 +97,22 @@ $OSTREE rev-parse 'test2^' $OSTREE rev-parse 'test2^^' 2>/dev/null && fatal "rev-parse test2^^ unexpectedly succeeded!" echo "ok rev-parse" +if $OSTREE rev-parse -S 2>err.txt; then + fatal "rev parse multiple" +fi +assert_file_has_content_literal err.txt 'Multiple commit objects found' +$CMD_PREFIX ostree --repo=repo-copy init --mode=archive +if $CMD_PREFIX ostree --repo=repo-copy rev-parse -S 2>err.txt; then + fatal "rev parse none" +fi +assert_file_has_content_literal err.txt 'No commit objects found' +rev=$($OSTREE rev-parse test2) +$CMD_PREFIX ostree --repo=repo-copy pull-local repo test2 +rev2=$($CMD_PREFIX ostree --repo=repo-copy rev-parse -S) +assert_streq "${rev}" "${rev2}" +echo "ok rev-parse -S" + + checksum=$($OSTREE rev-parse test2) partial=${checksum:0:6} echo "partial:" $partial @@ -990,6 +1006,13 @@ $OSTREE show -B --print-metadata-key=SOMENUM test2 > test2-meta assert_file_has_content test2-meta "uint64 42" $OSTREE show --print-detached-metadata-key=SIGNATURE test2 > test2-meta assert_file_has_content test2-meta "HANCOCK" + +$OSTREE show --list-metadata-keys test2 > test2-meta +assert_file_has_content test2-meta "FOO" +assert_file_has_content test2-meta "KITTENS" +assert_file_has_content test2-meta "SOMENUM" +$OSTREE show --list-detached-metadata-keys test2 > test2-meta +assert_file_has_content test2-meta "SIGNATURE" echo "ok metadata commit with strings" $OSTREE commit ${COMMIT_ARGS} -b test2 --tree=ref=test2 \ @@ -1103,7 +1126,7 @@ echo "ok test error pre commit/bootid" # Whiteouts cd ${test_tmpdir} -mkdir -p overlay/baz/ +mkdir -p overlay/baz/another/ if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper && touch overlay/baz/another/.wh..wh..opq; then touch overlay/anewfile mkdir overlay/anewdir/ @@ -1187,3 +1210,30 @@ if test "$(id -u)" != "0"; then else echo "ok # SKIP not run when root" fi + +if ! skip_one_without_whiteouts_devices; then + cd ${test_tmpdir} + rm checkout-test2 -rf + $OSTREE checkout test2 checkout-test2 + + assert_not_has_file checkout-test2/whiteouts/whiteout + assert_not_has_file checkout-test2/whiteouts/whiteout2 + assert_has_file checkout-test2/whiteouts/.ostree-wh.whiteout + assert_has_file checkout-test2/whiteouts/.ostree-wh.whiteout2 + + echo "ok checkout: no whiteout passthrough by default" +fi + +if ! skip_one_without_whiteouts_devices; then + cd ${test_tmpdir} + rm checkout-test2 -rf + $OSTREE checkout --process-passthrough-whiteouts test2 checkout-test2 + + assert_not_has_file checkout-test2/whiteouts/.ostree-wh.whiteout + assert_not_has_file checkout-test2/whiteouts/.ostree-wh.whiteout2 + + assert_is_whiteout_device checkout-test2/whiteouts/whiteout + assert_is_whiteout_device checkout-test2/whiteouts/whiteout2 + + echo "ok checkout: whiteout with overlayfs passthrough processing" +fi diff --git a/tests/libostreetest.c b/tests/libostreetest.c index 08abb9f..a195356 100644 --- a/tests/libostreetest.c +++ b/tests/libostreetest.c @@ -34,11 +34,11 @@ ot_test_run_libtest (const char *cmd, GError **error) g_assert (srcdir != NULL); g_assert (cmd != NULL); - g_autoptr(GPtrArray) argv = g_ptr_array_new (); + g_autoptr (GPtrArray) argv = g_ptr_array_new (); g_ptr_array_add (argv, "bash"); g_ptr_array_add (argv, "-c"); - g_autoptr(GString) cmdstr = g_string_new (""); + g_autoptr (GString) cmdstr = g_string_new (""); g_string_append (cmdstr, "set -xeuo pipefail; . "); g_string_append (cmdstr, srcdir); g_string_append (cmdstr, "/tests/libtest.sh; "); @@ -48,8 +48,8 @@ ot_test_run_libtest (const char *cmd, GError **error) g_ptr_array_add (argv, NULL); int estatus; - if (!g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_SEARCH_PATH, - NULL, NULL, NULL, NULL, &estatus, error)) + if (!g_spawn_sync (NULL, (char **)argv->pdata, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, + &estatus, error)) return FALSE; if (!g_spawn_check_exit_status (estatus, error)) return FALSE; @@ -58,14 +58,13 @@ ot_test_run_libtest (const char *cmd, GError **error) } OstreeRepo * -ot_test_setup_repo (GCancellable *cancellable, - GError **error) +ot_test_setup_repo (GCancellable *cancellable, GError **error) { if (!ot_test_run_libtest ("setup_test_repository archive", error)) return NULL; - g_autoptr(GFile) repo_path = g_file_new_for_path ("repo"); - g_autoptr(OstreeRepo) ret_repo = ostree_repo_new (repo_path); + g_autoptr (GFile) repo_path = g_file_new_for_path ("repo"); + g_autoptr (OstreeRepo) ret_repo = ostree_repo_new (repo_path); if (!ostree_repo_open (ret_repo, cancellable, error)) return NULL; @@ -74,15 +73,16 @@ ot_test_setup_repo (GCancellable *cancellable, /* Determine whether we're able to relabel files. Needed for bare tests. */ gboolean -ot_check_relabeling (gboolean *can_relabel, - GError **error) +ot_check_relabeling (gboolean *can_relabel, GError **error) { - g_auto(GLnxTmpfile) tmpf = { 0, }; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_RDWR | O_CLOEXEC, &tmpf, error)) return FALSE; - g_autoptr(GError) local_error = NULL; - g_autoptr(GBytes) bytes = glnx_fgetxattr_bytes (tmpf.fd, "security.selinux", &local_error); + g_autoptr (GError) local_error = NULL; + g_autoptr (GBytes) bytes = glnx_fgetxattr_bytes (tmpf.fd, "security.selinux", &local_error); if (!bytes) { /* libglnx preserves errno. The EOPNOTSUPP case can't be part of a @@ -115,10 +115,11 @@ ot_check_relabeling (gboolean *can_relabel, /* Determine whether the filesystem supports getting/setting user xattrs. */ gboolean -ot_check_user_xattrs (gboolean *has_user_xattrs, - GError **error) +ot_check_user_xattrs (gboolean *has_user_xattrs, GError **error) { - g_auto(GLnxTmpfile) tmpf = { 0, }; + g_auto (GLnxTmpfile) tmpf = { + 0, + }; if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_RDWR | O_CLOEXEC, &tmpf, error)) return FALSE; @@ -137,13 +138,12 @@ ot_check_user_xattrs (gboolean *has_user_xattrs, } OstreeSysroot * -ot_test_setup_sysroot (GCancellable *cancellable, - GError **error) +ot_test_setup_sysroot (GCancellable *cancellable, GError **error) { if (!ot_test_run_libtest ("setup_os_repository \"archive\" \"syslinux\"", error)) return FALSE; - g_autoptr(GString) buf = g_string_new ("mutable-deployments"); + g_autoptr (GString) buf = g_string_new ("mutable-deployments"); gboolean can_relabel = FALSE; if (!ot_check_relabeling (&can_relabel, error)) @@ -158,6 +158,6 @@ ot_test_setup_sysroot (GCancellable *cancellable, if (!g_setenv ("OSTREE_SYSROOT_DEBUG", buf->str, TRUE)) return glnx_null_throw (error, "Failed to set environment variable OSTREE_SYSROOT_DEBUG"); - g_autoptr(GFile) sysroot_path = g_file_new_for_path ("sysroot"); + g_autoptr (GFile) sysroot_path = g_file_new_for_path ("sysroot"); return ostree_sysroot_new (sysroot_path); } diff --git a/tests/libostreetest.h b/tests/libostreetest.h index aacfe5e..e593ac1 100644 --- a/tests/libostreetest.h +++ b/tests/libostreetest.h @@ -28,16 +28,12 @@ G_BEGIN_DECLS gboolean ot_test_run_libtest (const char *cmd, GError **error); -OstreeRepo *ot_test_setup_repo (GCancellable *cancellable, - GError **error); +OstreeRepo *ot_test_setup_repo (GCancellable *cancellable, GError **error); -gboolean ot_check_relabeling (gboolean *can_relabel, - GError **error); +gboolean ot_check_relabeling (gboolean *can_relabel, GError **error); -gboolean ot_check_user_xattrs (gboolean *has_user_xattrs, - GError **error); +gboolean ot_check_user_xattrs (gboolean *has_user_xattrs, GError **error); -OstreeSysroot *ot_test_setup_sysroot (GCancellable *cancellable, - GError **error); +OstreeSysroot *ot_test_setup_sysroot (GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/tests/libtest-core.sh b/tests/libtest-core.sh index d10aac1..3465fb9 100644 --- a/tests/libtest-core.sh +++ b/tests/libtest-core.sh @@ -163,6 +163,13 @@ assert_file_has_mode () { fi } +assert_is_whiteout_device () { + device_details="$(stat -c '%F %t:%T' $1)" + if [ "$device_details" != "character special file 0:0" ]; then + fatal "File '$1' is not a whiteout character device 0:0" + fi +} + assert_symlink_has_content () { if ! test -L "$1"; then fatal "File '$1' is not a symbolic link" diff --git a/tests/libtest.sh b/tests/libtest.sh index 686f08d..d1c99ea 100755 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -25,13 +25,17 @@ else test_srcdir=$(dirname $0) fi -if [ -n "${G_TEST_BUILDDIR:-}" ]; then - test_builddir="${G_TEST_BUILDDIR}/tests" -else - test_builddir=$(dirname $0) +top_builddir="${G_TEST_BUILDDIR:-}" +if test -z "${top_builddir}"; then + top_builddir=$(cd $(dirname $0)/.. && pwd) fi + +test_builddir="${top_builddir}/tests" . ${test_srcdir}/libtest-core.sh +# Make sure /sbin/capsh etc. are in our PATH even if non-root +PATH="$PATH:/usr/sbin:/sbin" + # Array of expressions to execute when exiting. Each expression should # be a single string (quoting if necessary) that will be eval'd. To add # a command to run on exit, append to the libtest_exit_cmds array like @@ -148,6 +152,20 @@ if ! have_selinux_relabel; then fi echo done +# whiteout char 0:0 devices can be created as regular users, but +# cannot be created inside containers mounted via overlayfs +can_create_whiteout_devices() { + mknod -m 000 ${test_tmpdir}/.test-whiteout c 0 0 || return 1 + rm -f ${test_tmpdir}/.test-whiteout + return 0 +} + +echo -n checking for overlayfs whiteouts... +if ! can_create_whiteout_devices; then + export OSTREE_NO_WHITEOUTS=1 +fi +echo done + if test -n "${OT_TESTS_DEBUG:-}"; then set -x fi @@ -158,30 +176,15 @@ if test -n "${ASAN_OPTIONS:-}"; then BUILT_WITH_ASAN=1 fi +CMD_PREFIX="" if test -n "${OT_TESTS_VALGRIND:-}"; then CMD_PREFIX="env G_SLICE=always-malloc OSTREE_SUPPRESS_SYNCFS=1 valgrind -q --error-exitcode=1 --leak-check=full --num-callers=30 --suppressions=${test_srcdir}/glib.supp --suppressions=${test_srcdir}/ostree.supp" -else - # In some cases the LD_PRELOAD may cause obscure problems, - # e.g. right now it breaks for me with -fsanitize=address, so - # let's allow users to skip it. - if test -z "${OT_SKIP_READDIR_RAND:-}" && test -z "${BUILT_WITH_ASAN:-}"; then - CMD_PREFIX="env LD_PRELOAD=${test_builddir}/libreaddir-rand.so" - else - CMD_PREFIX="" - fi fi -if test -n "${OSTREE_UNINSTALLED:-}"; then - OSTREE_HTTPD=${OSTREE_UNINSTALLED}/ostree-trivial-httpd -else - # trivial-httpd is now in $libexecdir by default, which we don't - # know at this point. Fortunately, libtest.sh is also in - # $libexecdir, so make an educated guess. If it's not found, assume - # it's still runnable as "ostree trivial-httpd". - if [ -x "${test_srcdir}/../../libostree/ostree-trivial-httpd" ]; then - OSTREE_HTTPD="${CMD_PREFIX} ${test_srcdir}/../../libostree/ostree-trivial-httpd" - else - OSTREE_HTTPD="${CMD_PREFIX} ostree trivial-httpd" +if test -z "${OSTREE_HTTPD:-}"; then + OSTREE_HTTPD="${top_builddir}/ostree-trivial-httpd" + if ! [ -x "${OSTREE_HTTPD}" ]; then + OSTREE_HTTPD= fi fi @@ -245,6 +248,22 @@ setup_test_repository () { ln -s nonexistent baz/alink mkdir baz/another/ echo x > baz/another/y + + mkdir baz/sub1 + echo SAME_CONTENT > baz/sub1/duplicate_a + echo SAME_CONTENT > baz/sub1/duplicate_b + + mkdir baz/sub2 + echo SAME_CONTENT > baz/sub2/duplicate_c + + # if we are running inside a container we cannot test + # the overlayfs whiteout marker passthrough + if ! test -n "${OSTREE_NO_WHITEOUTS:-}"; then + mkdir whiteouts + touch whiteouts/.ostree-wh.whiteout + touch whiteouts/.ostree-wh.whiteout2 + chmod 755 whiteouts/.ostree-wh.whiteout2 + fi umask "${oldumask}" cd ${test_tmpdir}/files @@ -406,7 +425,7 @@ setup_os_repository () { mkdir osdata cd osdata kver=3.6.0 - mkdir -p usr/bin ${bootdir} usr/lib/modules/${kver} usr/share usr/etc + mkdir -p usr/bin ${bootdir} usr/lib/modules/${kver} usr/share usr/etc usr/container/layers/abcd kernel_path=${bootdir}/vmlinuz initramfs_path=${bootdir}/initramfs.img # the HMAC file is only in /usr/lib/modules @@ -449,6 +468,17 @@ EOF mkdir -p usr/etc/testdirectory echo "a default daemon file" > usr/etc/testdirectory/test + # if we are running inside a container we cannot test + # the overlayfs whiteout marker passthrough + if ! test -n "${OSTREE_NO_WHITEOUTS:-}"; then + # overlayfs whiteout passhthrough marker files + touch usr/container/layers/abcd/.ostree-wh.whiteout + chmod 400 usr/container/layers/abcd/.ostree-wh.whiteout + + touch usr/container/layers/abcd/.ostree-wh.whiteout2 + chmod 777 usr/container/layers/abcd/.ostree-wh.whiteout2 + fi + ${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit ${bootable_flag} --add-metadata-string version=1.0.9 -b testos/buildmain/x86_64-runtime -s "Build" # Ensure these commits have distinct second timestamps @@ -474,7 +504,7 @@ EOF if test -n "${OSTREE_NO_XATTRS:-}"; then echo -e 'disable-xattrs=true\n' >> sysroot/ostree/repo/config fi - ${CMD_PREFIX} ostree admin os-init testos + ${CMD_PREFIX} ostree admin stateroot-init testos case $bootmode in "syslinux") @@ -588,6 +618,28 @@ skip_without_user_xattrs () { fi } +skip_without_sudo () { + if test -z "${OSTREE_TEST_SUDO:-}"; then + skip "this test needs sudo, skipping without OSTREE_TEST_SUDO being set" + fi +} + +# Usage: if ! skip_one_without_whiteouts_devices; then ... more tests ...; fi +skip_one_without_whiteouts_devices() { + if ! can_create_whiteout_devices; then + echo "ok # SKIP - this test requires whiteout device support (test outside containers)" + return 0 + else + return 1 + fi +} + +skip_without_whiteouts_devices () { + if ! can_create_whiteout_devices; then + skip "this test requires whiteout device support (test outside containers)" + fi +} + _have_systemd_and_libmount='' have_systemd_and_libmount() { if test "${_have_systemd_and_libmount}" = ''; then diff --git a/tests/readdir-rand.c b/tests/readdir-rand.c deleted file mode 100644 index f5d31ff..0000000 --- a/tests/readdir-rand.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2015 Colin Walters . - * - * SPDX-License-Identifier: LGPL-2.0+ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Glibc uses readdir64 when _FILE_OFFSET_BITS == 64 as set by - * AC_SYS_LARGEFILE on 32 bit systems. - */ -#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) -# define READDIR "readdir64" -# define READDIR_R "readdir64_r" -#else -# define READDIR "readdir" -# define READDIR_R "readdir_r" -#endif - -static GHashTable *direntcache; -static GMutex direntcache_lock; -static gsize initialized; - -typedef struct { - GPtrArray *entries; - guint offset; -} DirEntries; - -static void -dir_entries_free (gpointer data) -{ - DirEntries *d = data; - g_ptr_array_unref (d->entries); - g_free (d); -} - -static DirEntries * -dir_entries_new (void) -{ - DirEntries *d = g_new0 (DirEntries, 1); - d->entries = g_ptr_array_new_with_free_func (g_free); - return d; -} - -static void -ensure_initialized (void) -{ - if (g_once_init_enter (&initialized)) - { - direntcache = g_hash_table_new_full (NULL, NULL, NULL, dir_entries_free); - g_mutex_init (&direntcache_lock); - g_once_init_leave (&initialized, 1); - } -} - -struct dirent * -readdir (DIR *dirp) -{ - struct dirent *(*real_readdir)(DIR *dirp) = dlsym (RTLD_NEXT, READDIR); - struct dirent *ret; - gboolean cache_another = TRUE; - - ensure_initialized (); - - /* The core idea here is that each time through the loop, we read a - * directory entry. If there is one, we choose whether to cache it - * or to return it. Because multiple entries can be cached, - * ordering is randomized. Statistically, the order will still be - * *weighted* towards the ordering returned from the - * kernel/filesystem, but the goal here is just to provide some - * randomness in order to trigger bugs, not to be perfectly random. - */ - while (cache_another) - { - DirEntries *de; - - errno = 0; - ret = real_readdir (dirp); - if (ret == NULL && errno != 0) - goto out; - - g_mutex_lock (&direntcache_lock); - de = g_hash_table_lookup (direntcache, dirp); - if (ret) - { - if (g_random_boolean ()) - { - struct dirent *copy; - if (!de) - { - de = dir_entries_new (); - g_hash_table_insert (direntcache, dirp, de); - } - copy = g_memdup (ret, sizeof (struct dirent)); - g_ptr_array_add (de->entries, copy); - } - else - { - cache_another = FALSE; - } - } - else - { - if (de && de->offset < de->entries->len) - { - ret = de->entries->pdata[de->offset]; - de->offset++; - } - cache_another = FALSE; - } - g_mutex_unlock (&direntcache_lock); - } - - out: - return ret; -} - -int -closedir (DIR *dirp) -{ - int (*real_closedir)(DIR *dirp) = dlsym (RTLD_NEXT, "closedir"); - - ensure_initialized (); - - g_mutex_lock (&direntcache_lock); - g_hash_table_remove (direntcache, dirp); - g_mutex_unlock (&direntcache_lock); - - return real_closedir (dirp); -} - -static void -assert_no_cached_entries (DIR *dirp) -{ - DirEntries *de; - g_mutex_lock (&direntcache_lock); - de = g_hash_table_lookup (direntcache, dirp); - g_assert (!de || de->entries->len == 0); - g_mutex_unlock (&direntcache_lock); -} - -void -seekdir (DIR *dirp, long loc) -{ - void (*real_seekdir)(DIR *dirp, long loc) = dlsym (RTLD_NEXT, "seekdir"); - - ensure_initialized (); - - /* For now, crash if seekdir is called when we have cached entries. - * If some app wants to use this and seekdir() we can implement it. - */ - assert_no_cached_entries (dirp); - - real_seekdir (dirp, loc); -} - -void -rewinddir (DIR *dirp) -{ - void (*real_rewinddir)(DIR *dirp) = dlsym (RTLD_NEXT, "rewinddir"); - - ensure_initialized (); - - /* Blow away the cache */ - g_mutex_lock (&direntcache_lock); - g_hash_table_remove (direntcache, dirp); - g_mutex_unlock (&direntcache_lock); - - real_rewinddir (dirp); -} - -int -readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result) -{ - int (*real_readdir_r)(DIR *dirp, struct dirent *entry, struct dirent **result) = dlsym (RTLD_NEXT, READDIR_R); - - ensure_initialized (); - - /* For now, assert that no one is mixing readdir_r() with readdir(). - * It'd be broken to do so, and very few programs use readdir_r() - * anyways. */ - assert_no_cached_entries (dirp); - - return real_readdir_r (dirp, entry, result); -} diff --git a/tests/repo-finder-mount.c b/tests/repo-finder-mount.c index 66c4ecd..68a0e3d 100644 --- a/tests/repo-finder-mount.c +++ b/tests/repo-finder-mount.c @@ -24,22 +24,20 @@ #include "config.h" #include -#include #include +#include #include #include #include "ostree-autocleanups.h" #include "ostree-remote-private.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-mount.h" +#include "ostree-repo-finder.h" #include "ostree-types.h" #include "test-mock-gio.h" static void -result_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) +result_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GAsyncResult **result_out = user_data; *result_out = g_object_ref (result); @@ -54,33 +52,35 @@ collection_ref_free0 (OstreeCollectionRef *ref) int main (int argc, char **argv) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; setlocale (LC_ALL, ""); if (argc < 5 || (argc % 2) != 1) { - g_printerr ("Usage: %s REPO MOUNT-ROOT COLLECTION-ID REF-NAME [COLLECTION-ID REF-NAME …]\n", argv[0]); + g_printerr ("Usage: %s REPO MOUNT-ROOT COLLECTION-ID REF-NAME [COLLECTION-ID REF-NAME …]\n", + argv[0]); return 1; } - g_autoptr(GMainContext) context = g_main_context_new (); + g_autoptr (GMainContext) context = g_main_context_new (); g_main_context_push_thread_default (context); - g_autoptr(OstreeRepo) parent_repo = ostree_repo_open_at (AT_FDCWD, argv[1], NULL, &error); + g_autoptr (OstreeRepo) parent_repo = ostree_repo_open_at (AT_FDCWD, argv[1], NULL, &error); g_assert_no_error (error); /* Set up a mock volume. */ - g_autoptr(GFile) mount_root = g_file_new_for_commandline_arg (argv[2]); - g_autoptr(GMount) mount = G_MOUNT (ostree_mock_mount_new ("mount", mount_root)); + g_autoptr (GFile) mount_root = g_file_new_for_commandline_arg (argv[2]); + g_autoptr (GMount) mount = G_MOUNT (ostree_mock_mount_new ("mount", mount_root)); - g_autoptr(GList) mounts = g_list_prepend (NULL, mount); + g_autoptr (GList) mounts = g_list_prepend (NULL, mount); - g_autoptr(GVolumeMonitor) monitor = ostree_mock_volume_monitor_new (mounts, NULL); - g_autoptr(OstreeRepoFinderMount) finder = ostree_repo_finder_mount_new (monitor); + g_autoptr (GVolumeMonitor) monitor = ostree_mock_volume_monitor_new (mounts, NULL); + g_autoptr (OstreeRepoFinderMount) finder = ostree_repo_finder_mount_new (monitor); /* Resolve the refs. */ - g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func ((GDestroyNotify) collection_ref_free0); + g_autoptr (GPtrArray) refs + = g_ptr_array_new_with_free_func ((GDestroyNotify)collection_ref_free0); for (gsize i = 3; i < argc; i += 2) { @@ -90,18 +90,18 @@ main (int argc, char **argv) g_ptr_array_add (refs, ostree_collection_ref_new (collection_id, ref_name)); } - g_ptr_array_add (refs, NULL); /* NULL terminator */ + g_ptr_array_add (refs, NULL); /* NULL terminator */ - g_autoptr(GAsyncResult) async_result = NULL; + g_autoptr (GAsyncResult) async_result = NULL; ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), - (const OstreeCollectionRef * const *) refs->pdata, - parent_repo, NULL, result_cb, &async_result); + (const OstreeCollectionRef *const *)refs->pdata, parent_repo, + NULL, result_cb, &async_result); while (async_result == NULL) g_main_context_iteration (context, TRUE); - g_autoptr(GPtrArray) results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), - async_result, &error); + g_autoptr (GPtrArray) results + = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), async_result, &error); g_assert_no_error (error); /* Check that the results are correct: the invalid refs should have been @@ -115,11 +115,9 @@ main (int argc, char **argv) g_hash_table_iter_init (&iter, result->ref_to_checksum); - while (g_hash_table_iter_next (&iter, (gpointer *) &ref, (gpointer *) &checksum)) - g_print ("%" G_GSIZE_FORMAT " %s %s %s %s\n", - i, ostree_remote_get_name (result->remote), - ref->collection_id, ref->ref_name, - checksum); + while (g_hash_table_iter_next (&iter, (gpointer *)&ref, (gpointer *)&checksum)) + g_print ("%" G_GSIZE_FORMAT " %s %s %s %s\n", i, ostree_remote_get_name (result->remote), + ref->collection_id, ref->ref_name, checksum); } g_main_context_pop_thread_default (context); diff --git a/tests/test-admin-deploy-bootprefix.sh b/tests/test-admin-deploy-bootprefix.sh new file mode 100755 index 0000000..d80c310 --- /dev/null +++ b/tests/test-admin-deploy-bootprefix.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# Copyright (C) 2022 Colin Walters +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +# Exports OSTREE_SYSROOT so --sysroot not needed. +setup_os_repository "archive" "syslinux" + +${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime +${CMD_PREFIX} ostree --repo=sysroot/ostree/repo config set sysroot.bootprefix 'true' +${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=root --os=testos testos:testos/buildmain/x86_64-runtime +assert_file_has_content_literal sysroot/boot/loader/entries/ostree-1-testos.conf 'linux /boot/ostree/testos-' +assert_file_has_content_literal sysroot/boot/loader/entries/ostree-1-testos.conf 'initrd /boot/ostree/testos-' + +tap_ok "bootprefix" + +tap_end diff --git a/tests/test-admin-deploy-emptyetc.sh b/tests/test-admin-deploy-emptyetc.sh new file mode 100755 index 0000000..8c96207 --- /dev/null +++ b/tests/test-admin-deploy-emptyetc.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +setup_os_repository "archive" "syslinux" + +echo "1..1" +cd ${test_tmpdir}/osdata +mkdir etc +${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string "version=42.etc" -b testos/buildmain/x86_64-runtime +cd - +${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime +${CMD_PREFIX} ostree admin deploy --os=testos testos:testos/buildmain/x86_64-runtime +origdeployment=$(${CMD_PREFIX} ostree admin --sysroot=sysroot --print-current-dir) +assert_file_has_content ${origdeployment}/etc/NetworkManager/nm.conf "a default daemon file" +echo "ok empty etc" diff --git a/tests/test-admin-deploy-karg.sh b/tests/test-admin-deploy-karg.sh index 047ca63..39fcdf3 100755 --- a/tests/test-admin-deploy-karg.sh +++ b/tests/test-admin-deploy-karg.sh @@ -71,11 +71,9 @@ assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf 'option echo "ok deploy --karg-append" assert_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf 'options.*quiet .*TESTARG=TESTVALUE .*APPENDARG=VALAPPEND .*APPENDARG=2NDAPPEND' -${CMD_PREFIX} ostree admin deploy --os=testos --karg-delete=TESTARG=TESTVALUE testos:testos/buildmain/x86_64-runtime +${CMD_PREFIX} ostree admin deploy --os=testos --karg-delete=TESTARG=TESTVALUE --karg-delete=quiet --karg-delete=APPENDARG=VALAPPEND testos:testos/buildmain/x86_64-runtime assert_not_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf 'options.*TESTARG=TESTVALUE' -${CMD_PREFIX} ostree admin deploy --os=testos --karg-delete=quiet testos:testos/buildmain/x86_64-runtime assert_not_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf 'options.*quiet' -${CMD_PREFIX} ostree admin deploy --os=testos --karg-delete=APPENDARG=VALAPPEND testos:testos/buildmain/x86_64-runtime assert_not_file_has_content sysroot/boot/loader/entries/ostree-2-testos.conf 'options.*APPENDARG=VALAPPEND' echo "ok deploy --karg-delete" diff --git a/tests/test-admin-deploy-whiteouts.sh b/tests/test-admin-deploy-whiteouts.sh new file mode 100755 index 0000000..6642194 --- /dev/null +++ b/tests/test-admin-deploy-whiteouts.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Copyright (C) 2022 Red Hat, Inc. +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + +set -euox pipefail + +. $(dirname $0)/libtest.sh + +skip_without_whiteouts_devices + +# Exports OSTREE_SYSROOT so --sysroot not needed. +setup_os_repository "archive" "syslinux" +${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime + +echo "1..3" +${CMD_PREFIX} ostree admin deploy --os=testos --karg=root=LABEL=foo --karg=testkarg=1 testos:testos/buildmain/x86_64-runtime +origdeployment=$(${CMD_PREFIX} ostree admin --sysroot=sysroot --print-current-dir) + +assert_is_whiteout_device "${origdeployment}"/usr/container/layers/abcd/whiteout +echo "ok whiteout deployment" + +assert_not_has_file "${origdeployment}"/usr/container/layers/abcd/.ostree-wh.whiteout +echo "ok .ostree-wh.whiteout not created" + +assert_file_has_mode "${origdeployment}"/usr/container/layers/abcd/whiteout 400 +assert_file_has_mode "${origdeployment}"/usr/container/layers/abcd/whiteout2 777 +echo "ok whiteout permissions are preserved" diff --git a/tests/test-admin-gpg.sh b/tests/test-admin-gpg.sh index dcf075c..f71c306 100755 --- a/tests/test-admin-gpg.sh +++ b/tests/test-admin-gpg.sh @@ -21,6 +21,11 @@ set -euo pipefail . $(dirname $0)/libtest.sh +if test -z "${OSTREE_HTTPD}"; then + echo "1..0 #SKIP no ostree-trivial-httpd" + exit 0 +fi + setup_os_repository_signed () { mode=$1 shift diff --git a/tests/test-admin-kargs.sh b/tests/test-admin-kargs.sh new file mode 100755 index 0000000..afcfc05 --- /dev/null +++ b/tests/test-admin-kargs.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Copyright (C) 2011 Colin Walters +# Copyright (C) 2022 Huijing Hei +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +# Exports OSTREE_SYSROOT so --sysroot not needed. +setup_os_repository "archive" "syslinux" + +echo "1..2" + +${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime +${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmain/x86_64-runtime +${CMD_PREFIX} ostree admin kargs edit-in-place --append-if-missing=TESTARG=TESTVALUE --append-if-missing=ARGWITHOUTKEY testos:testos/buildmain/x86_64-runtime + +assert_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'options.*TESTARG=TESTVALUE .*ARGWITHOUTKEY' + +echo "ok kargs edit-in-place (basic)" + +${CMD_PREFIX} ostree admin kargs edit-in-place --append-if-missing=quiet testos:testos/buildmain/x86_64-runtime +assert_not_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'quiet$' + +${CMD_PREFIX} ostree admin kargs edit-in-place --append-if-missing=TESTARG=TESTVALUE testos:testos/buildmain/x86_64-runtime +assert_not_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'TESTARG=TESTVALUE$' + +echo "ok kargs edit-in-place (duplicate)" diff --git a/tests/test-basic-bare-split-xattrs.sh b/tests/test-basic-bare-split-xattrs.sh index bf828eb..b30e9d6 100755 --- a/tests/test-basic-bare-split-xattrs.sh +++ b/tests/test-basic-bare-split-xattrs.sh @@ -9,7 +9,9 @@ set -euo pipefail mode="bare-split-xattrs" OSTREE="${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo" +skip_without_sudo SUDO="sudo --non-interactive" + PRIVILEGED="false" if [ $(id -u) -eq 0 ]; then PRIVILEGED="true" diff --git a/tests/test-basic-c.c b/tests/test-basic-c.c index 1886feb..a01cef6 100644 --- a/tests/test-basic-c.c +++ b/tests/test-basic-c.c @@ -19,11 +19,11 @@ #include "config.h" -#include -#include +#include #include +#include +#include #include -#include #include "libglnx.h" #include "libostreetest.h" @@ -31,25 +31,21 @@ static void test_repo_is_not_system (gconstpointer data) { - OstreeRepo *repo = (void*)data; + OstreeRepo *repo = (void *)data; g_assert (!ostree_repo_is_system (repo)); } static GBytes * input_stream_to_bytes (GInputStream *input) { - g_autoptr(GOutputStream) mem_out_stream = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GOutputStream) mem_out_stream = NULL; + g_autoptr (GError) error = NULL; if (input == NULL) return g_bytes_new (NULL, 0); mem_out_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); - g_output_stream_splice (mem_out_stream, - input, - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - NULL, - &error); + g_output_stream_splice (mem_out_stream, input, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, &error); g_assert_no_error (error); return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem_out_stream)); @@ -60,56 +56,41 @@ test_raw_file_to_archive_stream (gconstpointer data) { OstreeRepo *repo = OSTREE_REPO (data); g_autofree gchar *commit_checksum = NULL; - g_autoptr(GHashTable) reachable = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GHashTable) reachable = NULL; + g_autoptr (GError) error = NULL; /* branch name of the test repository, see setup_test_repository in libtest.sh */ const gchar *rev = "test2"; GHashTableIter iter; GVariant *serialized_object; guint checks = 0; - ostree_repo_resolve_rev (repo, - rev, - FALSE, - &commit_checksum, - &error); + ostree_repo_resolve_rev (repo, rev, FALSE, &commit_checksum, &error); g_assert_no_error (error); - ostree_repo_traverse_commit (repo, - commit_checksum, - -1, - &reachable, - NULL, - &error); + ostree_repo_traverse_commit (repo, commit_checksum, -1, &reachable, NULL, &error); g_assert_no_error (error); g_hash_table_iter_init (&iter, reachable); - while (g_hash_table_iter_next (&iter, (gpointer*)&serialized_object, NULL)) + while (g_hash_table_iter_next (&iter, (gpointer *)&serialized_object, NULL)) { const gchar *object_checksum; OstreeObjectType object_type; - g_autoptr(GInputStream) input = NULL; - g_autoptr(GFileInfo) info = NULL; - g_autoptr(GVariant) xattrs = NULL; - g_autoptr(GBytes) input_bytes = NULL; - g_autoptr(GInputStream) mem_input = NULL; - g_autoptr(GInputStream) zlib_stream = NULL; - g_autoptr(GBytes) zlib_bytes = NULL; - g_autoptr(GInputStream) mem_zlib = NULL; - g_autoptr(GInputStream) input2 = NULL; - g_autoptr(GFileInfo) info2 = NULL; - g_autoptr(GVariant) xattrs2 = NULL; - g_autoptr(GBytes) input2_bytes = NULL; + g_autoptr (GInputStream) input = NULL; + g_autoptr (GFileInfo) info = NULL; + g_autoptr (GVariant) xattrs = NULL; + g_autoptr (GBytes) input_bytes = NULL; + g_autoptr (GInputStream) mem_input = NULL; + g_autoptr (GInputStream) zlib_stream = NULL; + g_autoptr (GBytes) zlib_bytes = NULL; + g_autoptr (GInputStream) mem_zlib = NULL; + g_autoptr (GInputStream) input2 = NULL; + g_autoptr (GFileInfo) info2 = NULL; + g_autoptr (GVariant) xattrs2 = NULL; + g_autoptr (GBytes) input2_bytes = NULL; ostree_object_name_deserialize (serialized_object, &object_checksum, &object_type); if (object_type != OSTREE_OBJECT_TYPE_FILE) continue; - ostree_repo_load_file (repo, - object_checksum, - &input, - &info, - &xattrs, - NULL, - &error); + ostree_repo_load_file (repo, object_checksum, &input, &info, &xattrs, NULL, &error); g_assert_no_error (error); input_bytes = input_stream_to_bytes (input); @@ -121,44 +102,21 @@ test_raw_file_to_archive_stream (gconstpointer data) * GFileDescriptorBased interface. */ if (input != NULL) mem_input = g_memory_input_stream_new_from_bytes (input_bytes); - ostree_raw_file_to_archive_z2_stream (mem_input, - info, - xattrs, - &zlib_stream, - NULL, - &error); + ostree_raw_file_to_archive_z2_stream (mem_input, info, xattrs, &zlib_stream, NULL, &error); g_assert_no_error (error); zlib_bytes = input_stream_to_bytes (zlib_stream); mem_zlib = g_memory_input_stream_new_from_bytes (zlib_bytes); - ostree_content_stream_parse (FALSE, - mem_zlib, - g_bytes_get_size (zlib_bytes), - FALSE, - &input2, - &info2, - &xattrs2, - NULL, - &error); + ostree_content_stream_parse (FALSE, mem_zlib, g_bytes_get_size (zlib_bytes), FALSE, &input2, + &info2, &xattrs2, NULL, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); g_clear_error (&error); - g_seekable_seek (G_SEEKABLE (mem_zlib), - 0, - G_SEEK_SET, - NULL, - &error); + g_seekable_seek (G_SEEKABLE (mem_zlib), 0, G_SEEK_SET, NULL, &error); g_assert_no_error (error); - ostree_content_stream_parse (TRUE, - mem_zlib, - g_bytes_get_size (zlib_bytes), - FALSE, - &input2, - &info2, - &xattrs2, - NULL, - &error); + ostree_content_stream_parse (TRUE, mem_zlib, g_bytes_get_size (zlib_bytes), FALSE, &input2, + &info2, &xattrs2, NULL, &error); g_assert_no_error (error); input2_bytes = input_stream_to_bytes (input2); @@ -171,35 +129,38 @@ test_raw_file_to_archive_stream (gconstpointer data) g_assert_cmpint (checks, >, 0); } -static gboolean hi_content_stream_new (GInputStream **out_stream, - guint64 *out_length, - GError **error) +static gboolean +hi_content_stream_new (GInputStream **out_stream, guint64 *out_length, GError **error) { static const char hi[] = "hi"; - g_autoptr(GMemoryInputStream) hi_memstream = (GMemoryInputStream*)g_memory_input_stream_new_from_data (hi, sizeof(hi)-1, NULL); - g_autoptr(GFileInfo) finfo = g_file_info_new (); + const size_t len = sizeof (hi) - 1; + g_autoptr (GMemoryInputStream) hi_memstream + = (GMemoryInputStream *)g_memory_input_stream_new_from_data (hi, len, NULL); + g_autoptr (GFileInfo) finfo = g_file_info_new (); g_file_info_set_attribute_uint32 (finfo, "standard::type", G_FILE_TYPE_REGULAR); g_file_info_set_attribute_boolean (finfo, "standard::is-symlink", FALSE); + g_file_info_set_size (finfo, len); g_file_info_set_attribute_uint32 (finfo, "unix::uid", 0); g_file_info_set_attribute_uint32 (finfo, "unix::gid", 0); - g_file_info_set_attribute_uint32 (finfo, "unix::mode", S_IFREG|0644); - return ostree_raw_file_to_content_stream ((GInputStream*)hi_memstream, finfo, NULL, out_stream, out_length, NULL, error); + g_file_info_set_attribute_uint32 (finfo, "unix::mode", S_IFREG | 0644); + return ostree_raw_file_to_content_stream ((GInputStream *)hi_memstream, finfo, NULL, out_stream, + out_length, NULL, error); } static void test_validate_remotename (void) { - const char *valid[] = {"foo", "hello-world"}; - const char *invalid[] = {"foo/bar", ""}; - for (guint i = 0; i < G_N_ELEMENTS(valid); i++) + const char *valid[] = { "foo", "hello-world" }; + const char *invalid[] = { "foo/bar", "" }; + for (guint i = 0; i < G_N_ELEMENTS (valid); i++) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; g_assert (ostree_validate_remote_name (valid[i], &error)); g_assert_no_error (error); } - for (guint i = 0; i < G_N_ELEMENTS(invalid); i++) + for (guint i = 0; i < G_N_ELEMENTS (invalid); i++) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; g_assert (!ostree_validate_remote_name (invalid[i], &error)); g_assert (error != NULL); } @@ -209,39 +170,40 @@ static void test_object_writes (gconstpointer data) { OstreeRepo *repo = OSTREE_REPO (data); - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; - static const char hi_sha256[] = "2301b5923720c3edc1f0467addb5c287fd5559e3e0cd1396e7f1edb6b01be9f0"; + static const char hi_sha256[] + = "2301b5923720c3edc1f0467addb5c287fd5559e3e0cd1396e7f1edb6b01be9f0"; /* Successful content write */ - { g_autoptr(GInputStream) hi_memstream = NULL; + { + g_autoptr (GInputStream) hi_memstream = NULL; guint64 len; hi_content_stream_new (&hi_memstream, &len, &error); g_assert_no_error (error); g_autofree guchar *csum = NULL; - (void)ostree_repo_write_content (repo, hi_sha256, hi_memstream, len, &csum, - NULL, &error); + (void)ostree_repo_write_content (repo, hi_sha256, hi_memstream, len, &csum, NULL, &error); g_assert_no_error (error); } /* Invalid content write */ - { g_autoptr(GInputStream) hi_memstream = NULL; + { + g_autoptr (GInputStream) hi_memstream = NULL; guint64 len; hi_content_stream_new (&hi_memstream, &len, &error); g_assert_no_error (error); g_autofree guchar *csum = NULL; - static const char invalid_hi_sha256[] = "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"; - g_assert (!ostree_repo_write_content (repo, invalid_hi_sha256, hi_memstream, len, &csum, - NULL, &error)); + static const char invalid_hi_sha256[] + = "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"; + g_assert (!ostree_repo_write_content (repo, invalid_hi_sha256, hi_memstream, len, &csum, NULL, + &error)); g_assert (error); g_assert (strstr (error->message, "Corrupted file object")); } } static gboolean -impl_test_break_hardlink (int tmp_dfd, - const char *path, - GError **error) +impl_test_break_hardlink (int tmp_dfd, const char *path, GError **error) { const char *linkedpath = glnx_strjoina (path, ".link"); struct stat orig_stbuf; @@ -274,8 +236,8 @@ impl_test_break_hardlink (int tmp_dfd, g_assert_cmpint (orig_stbuf.st_dev, ==, stbuf.st_dev); g_assert_cmpint (orig_stbuf.st_ino, ==, stbuf.st_ino); - (void) unlinkat (tmp_dfd, path, 0); - (void) unlinkat (tmp_dfd, linkedpath, 0); + (void)unlinkat (tmp_dfd, path, 0); + (void)unlinkat (tmp_dfd, linkedpath, 0); return TRUE; } @@ -284,14 +246,12 @@ static void test_break_hardlink (void) { int tmp_dfd = AT_FDCWD; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; /* Regular file */ const char hello_hardlinked_content[] = "hello hardlinked content"; - glnx_file_replace_contents_at (tmp_dfd, "test-hardlink", - (guint8*)hello_hardlinked_content, - strlen (hello_hardlinked_content), - GLNX_FILE_REPLACE_NODATASYNC, + glnx_file_replace_contents_at (tmp_dfd, "test-hardlink", (guint8 *)hello_hardlinked_content, + strlen (hello_hardlinked_content), GLNX_FILE_REPLACE_NODATASYNC, NULL, &error); g_assert_no_error (error); (void)impl_test_break_hardlink (tmp_dfd, "test-hardlink", &error); @@ -304,11 +264,8 @@ test_break_hardlink (void) g_assert_no_error (error); } -static GVariant* -xattr_cb (OstreeRepo *repo, - const char *path, - GFileInfo *file_info, - gpointer user_data) +static GVariant * +xattr_cb (OstreeRepo *repo, const char *path, GFileInfo *file_info, gpointer user_data) { GVariant *xattr = user_data; if (g_str_equal (path, "/baz/cow")) @@ -320,10 +277,10 @@ xattr_cb (OstreeRepo *repo, static void test_devino_cache_xattrs (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; gboolean ret = FALSE; - g_autoptr(GFile) repo_path = g_file_new_for_path ("repo"); + g_autoptr (GFile) repo_path = g_file_new_for_path ("repo"); /* re-initialize as bare */ ret = ot_test_run_libtest ("setup_test_repository bare", &error); @@ -347,7 +304,7 @@ test_devino_cache_xattrs (void) return; } - g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path); + g_autoptr (OstreeRepo) repo = ostree_repo_new (repo_path); ret = ostree_repo_open (repo, NULL, &error); g_assert_no_error (error); g_assert (ret); @@ -357,47 +314,47 @@ test_devino_cache_xattrs (void) g_assert_no_error (error); g_assert (ret); - g_autoptr(OstreeRepoDevInoCache) cache = ostree_repo_devino_cache_new (); + g_autoptr (OstreeRepoDevInoCache) cache = ostree_repo_devino_cache_new (); - OstreeRepoCheckoutAtOptions options = {0,}; + OstreeRepoCheckoutAtOptions options = { + 0, + }; options.no_copy_fallback = TRUE; options.devino_to_csum_cache = cache; ret = ostree_repo_checkout_at (repo, &options, AT_FDCWD, "checkout", csum, NULL, &error); g_assert_no_error (error); g_assert (ret); - g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new (); - g_autoptr(OstreeRepoCommitModifier) modifier = - ostree_repo_commit_modifier_new (0, NULL, NULL, NULL); + g_autoptr (OstreeMutableTree) mtree = ostree_mutable_tree_new (); + g_autoptr (OstreeRepoCommitModifier) modifier + = ostree_repo_commit_modifier_new (0, NULL, NULL, NULL); ostree_repo_commit_modifier_set_devino_cache (modifier, cache); - g_auto(GVariantBuilder) builder; - g_variant_builder_init (&builder, (GVariantType*)"a(ayay)"); - g_variant_builder_add (&builder, "(@ay@ay)", - g_variant_new_bytestring ("user.myattr"), + g_auto (GVariantBuilder) builder; + g_variant_builder_init (&builder, (GVariantType *)"a(ayay)"); + g_variant_builder_add (&builder, "(@ay@ay)", g_variant_new_bytestring ("user.myattr"), g_variant_new_bytestring ("data")); - g_autoptr(GVariant) orig_xattrs = g_variant_ref_sink (g_variant_builder_end (&builder)); + g_autoptr (GVariant) orig_xattrs = g_variant_ref_sink (g_variant_builder_end (&builder)); ret = ostree_repo_prepare_transaction (repo, NULL, NULL, &error); g_assert_no_error (error); g_assert (ret); ostree_repo_commit_modifier_set_xattr_callback (modifier, xattr_cb, NULL, orig_xattrs); - ret = ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, "checkout", - mtree, modifier, NULL, &error); + ret = ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, "checkout", mtree, modifier, NULL, &error); g_assert_no_error (error); g_assert (ret); - g_autoptr(GFile) root = NULL; + g_autoptr (GFile) root = NULL; ret = ostree_repo_write_mtree (repo, mtree, &root, NULL, &error); g_assert_no_error (error); g_assert (ret); /* now check that the final xattr matches */ - g_autoptr(GFile) baz_child = g_file_get_child (root, "baz"); - g_autoptr(GFile) cow_child = g_file_get_child (baz_child, "cow"); + g_autoptr (GFile) baz_child = g_file_get_child (root, "baz"); + g_autoptr (GFile) cow_child = g_file_get_child (baz_child, "cow"); - g_autoptr(GVariant) xattrs = NULL; + g_autoptr (GVariant) xattrs = NULL; ret = ostree_repo_file_get_xattrs (OSTREE_REPO_FILE (cow_child), &xattrs, NULL, &error); g_assert_no_error (error); g_assert (ret); @@ -406,13 +363,13 @@ test_devino_cache_xattrs (void) gsize n = g_variant_n_children (xattrs); for (gsize i = 0; i < n; i++) { - const guint8* name; - const guint8* value; + const guint8 *name; + const guint8 *value; g_variant_get_child (xattrs, i, "(^&ay^&ay)", &name, &value); - if (g_str_equal ((const char*)name, "user.myattr")) + if (g_str_equal ((const char *)name, "user.myattr")) { - g_assert_cmpstr ((const char*)value, ==, "data"); + g_assert_cmpstr ((const char *)value, ==, "data"); found_xattr = TRUE; break; } @@ -435,44 +392,43 @@ test_devino_cache_xattrs (void) static void test_big_metadata (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; gboolean ret = FALSE; - g_autoptr(GFile) repo_path = g_file_new_for_path ("repo"); + g_autoptr (GFile) repo_path = g_file_new_for_path ("repo"); /* init as bare-user-only so we run everywhere */ ret = ot_test_run_libtest ("setup_test_repository bare-user-only", &error); g_assert_no_error (error); g_assert (ret); - g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path); + g_autoptr (OstreeRepo) repo = ostree_repo_new (repo_path); ret = ostree_repo_open (repo, NULL, &error); g_assert_no_error (error); g_assert (ret); - g_autoptr(GFile) object_to_commit = NULL; + g_autoptr (GFile) object_to_commit = NULL; ret = ostree_repo_read_commit (repo, "test2", &object_to_commit, NULL, NULL, &error); g_assert_no_error (error); g_assert (ret); - g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new (); - ret = ostree_repo_write_directory_to_mtree (repo, object_to_commit, mtree, NULL, - NULL, &error); + g_autoptr (OstreeMutableTree) mtree = ostree_mutable_tree_new (); + ret = ostree_repo_write_directory_to_mtree (repo, object_to_commit, mtree, NULL, NULL, &error); g_assert_no_error (error); g_assert (ret); - const size_t len = 20 * 1024 * 1024; + const size_t len = OSTREE_MAX_METADATA_SIZE + 1; g_assert_cmpint (len, >, OSTREE_MAX_METADATA_SIZE); g_autofree char *large_buf = g_malloc (len); memset (large_buf, 0x42, len); - g_autoptr(GVariantBuilder) builder = - g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); g_autofree char *commit_checksum = NULL; - g_variant_builder_add (builder, "{sv}", "large-value", - g_variant_new_fixed_array ((GVariantType*)"y", - large_buf, len, sizeof (char))); + g_variant_builder_add ( + builder, "{sv}", "large-value", + g_variant_new_fixed_array ((GVariantType *)"y", large_buf, len, sizeof (char))); ret = ostree_repo_write_commit (repo, NULL, NULL, NULL, g_variant_builder_end (builder), - OSTREE_REPO_FILE (object_to_commit), &commit_checksum, NULL, &error); + OSTREE_REPO_FILE (object_to_commit), &commit_checksum, NULL, + &error); g_assert_no_error (error); g_assert (ret); } @@ -499,10 +455,12 @@ compare_xattrs (GVariant *orig, GVariant *new) static void test_read_xattrs (void) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; - g_auto(GLnxTmpDir) tmpd = { 0, }; + g_auto (GLnxTmpDir) tmpd = { + 0, + }; // Use /var/tmp to hope we get xattr support glnx_mkdtempat (AT_FDCWD, "/var/tmp/ostree-xattrs-test.XXXXXX", 0700, &tmpd, error); g_assert_no_error (local_error); @@ -510,15 +468,22 @@ test_read_xattrs (void) const char value[] = "foo"; { - g_autoptr(GVariant) current_xattrs = ostree_fs_get_all_xattrs (tmpd.fd, NULL, error); + g_autoptr (GVariant) current_xattrs = ostree_fs_get_all_xattrs (tmpd.fd, NULL, error); g_assert_no_error (local_error); - + int r = fsetxattr (tmpd.fd, "user.ostreetesting", value, sizeof (value), 0); - g_assert_cmpint (r, ==, 0); - - g_autoptr(GVariant) new_xattrs = ostree_fs_get_all_xattrs (tmpd.fd, NULL, error); + + if (r != 0) + { + g_autofree gchar *message = g_strdup_printf ( + "Unable to set extended attributes in /var/tmp: %s", g_strerror (errno)); + g_test_skip (message); + return; + } + + g_autoptr (GVariant) new_xattrs = ostree_fs_get_all_xattrs (tmpd.fd, NULL, error); g_assert_no_error (local_error); - + compare_xattrs (current_xattrs, new_xattrs); } @@ -527,9 +492,10 @@ test_read_xattrs (void) glnx_throw_errno_prefix (error, "symlinkat"); g_assert_no_error (local_error); - g_autoptr(GVariant) current_xattrs = ostree_fs_get_all_xattrs_at (tmpd.fd, "somelink", NULL, error); + g_autoptr (GVariant) current_xattrs + = ostree_fs_get_all_xattrs_at (tmpd.fd, "somelink", NULL, error); g_assert_no_error (local_error); - (void) current_xattrs; + (void)current_xattrs; // OK, can't do user. xattrs on symlinks unfortunately. @@ -539,17 +505,18 @@ test_read_xattrs (void) // if (r < 0) // glnx_throw_errno_prefix (error, "lsetxattr"); // g_assert_no_error (local_error); - - // g_autoptr(GVariant) new_xattrs = ostree_fs_get_all_xattrs_at (tmpd.fd, "somelink", NULL, error); - // g_assert_no_error (local_error); - + + // g_autoptr(GVariant) new_xattrs = ostree_fs_get_all_xattrs_at (tmpd.fd, "somelink", NULL, + // error); g_assert_no_error (local_error); + // compare_xattrs (current_xattrs, new_xattrs); } } -int main (int argc, char **argv) +int +main (int argc, char **argv) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; glnx_unref_object OstreeRepo *repo = NULL; g_test_init (&argc, &argv, NULL); @@ -567,8 +534,8 @@ int main (int argc, char **argv) g_test_add_func ("/big-metadata", test_big_metadata); g_test_add_func ("/read-xattrs", test_read_xattrs); - return g_test_run(); - out: + return g_test_run (); +out: if (error) g_error ("%s", error->message); return 1; diff --git a/tests/test-bloom.c b/tests/test-bloom.c index 970a882..93f46eb 100644 --- a/tests/test-bloom.c +++ b/tests/test-bloom.c @@ -31,8 +31,8 @@ static void test_bloom_init (void) { - g_autoptr(OstreeBloom) bloom = NULL; - g_autoptr(GBytes) bytes = NULL; + g_autoptr (OstreeBloom) bloom = NULL; + g_autoptr (GBytes) bytes = NULL; bloom = ostree_bloom_new (1, 1, ostree_str_bloom_hash); g_assert_cmpuint (ostree_bloom_get_size (bloom), ==, 1); @@ -53,18 +53,12 @@ test_bloom_init (void) static void test_bloom_construction (void) { - g_autoptr(OstreeBloom) bloom = NULL; - g_autoptr(OstreeBloom) immutable_bloom = NULL; - g_autoptr(GBytes) bytes = NULL; + g_autoptr (OstreeBloom) bloom = NULL; + g_autoptr (OstreeBloom) immutable_bloom = NULL; + g_autoptr (GBytes) bytes = NULL; gsize i; - const gchar *members[] = - { - "hello", "there", "these", "are", "test", "strings" - }; - const gchar *non_members[] = - { - "not", "an", "element" - }; + const gchar *members[] = { "hello", "there", "these", "are", "test", "strings" }; + const gchar *non_members[] = { "not", "an", "element" }; const gsize n_bytes = 256; const guint8 k = 8; const OstreeBloomHashFunc hash = ostree_str_bloom_hash; @@ -94,7 +88,7 @@ test_bloom_construction (void) static void test_bloom_empty (void) { - g_autoptr(OstreeBloom) bloom = NULL; + g_autoptr (OstreeBloom) bloom = NULL; const gsize n_bytes = 256; const guint8 k = 8; const OstreeBloomHashFunc hash = ostree_str_bloom_hash; @@ -111,12 +105,9 @@ test_bloom_empty (void) static void test_bloom_membership_during_construction (void) { - g_autoptr(OstreeBloom) bloom = NULL; + g_autoptr (OstreeBloom) bloom = NULL; gsize i, j; - const gchar *members[] = - { - "hello", "there", "these", "are", "test", "strings" - }; + const gchar *members[] = { "hello", "there", "these", "are", "test", "strings" }; const gsize n_bytes = 256; const guint8 k = 8; const OstreeBloomHashFunc hash = ostree_str_bloom_hash; @@ -140,14 +131,16 @@ test_bloom_membership_during_construction (void) } } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/bloom/init", test_bloom_init); g_test_add_func ("/bloom/construction", test_bloom_construction); g_test_add_func ("/bloom/empty", test_bloom_empty); - g_test_add_func ("/bloom/membership-during-construction", test_bloom_membership_during_construction); + g_test_add_func ("/bloom/membership-during-construction", + test_bloom_membership_during_construction); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-bsdiff.c b/tests/test-bsdiff.c index 4a9ac6c..2d6b472 100644 --- a/tests/test-bsdiff.c +++ b/tests/test-bsdiff.c @@ -19,37 +19,29 @@ #include "config.h" -#include "libglnx.h" #include "bsdiff/bsdiff.h" #include "bsdiff/bspatch.h" +#include "libglnx.h" +#include #include #include -#include #include static int -bzpatch_read (const struct bspatch_stream* stream, void* buffer, int length) +bzpatch_read (const struct bspatch_stream *stream, void *buffer, int length) { GInputStream *in = stream->opaque; - if (length && ! g_input_stream_read (in, - buffer, - length, - NULL, - NULL)) + if (length && !g_input_stream_read (in, buffer, length, NULL, NULL)) return -1; return 0; } static int -bzdiff_write (struct bsdiff_stream* stream, const void* buffer, int size) +bzdiff_write (struct bsdiff_stream *stream, const void *buffer, int size) { GOutputStream *out = stream->opaque; - if (! g_output_stream_write (out, - buffer, - size, - NULL, - NULL)) + if (!g_output_stream_write (out, buffer, size, NULL, NULL)) return -1; return 0; @@ -59,7 +51,7 @@ static void test_bsdiff (void) { #define OLD_SIZE 512 -#define NEW_SIZE (512+24) +#define NEW_SIZE (512 + 24) struct bsdiff_stream bsdiff_stream; struct bspatch_stream bspatch_stream; @@ -67,8 +59,8 @@ test_bsdiff (void) g_autofree guint8 *old = g_new (guint8, OLD_SIZE); g_autofree guint8 *new = g_new (guint8, NEW_SIZE); g_autofree guint8 *new_generated = g_new0 (guint8, NEW_SIZE); - g_autoptr(GOutputStream) out = g_memory_output_stream_new_resizable (); - g_autoptr(GInputStream) in = NULL; + g_autoptr (GOutputStream) out = g_memory_output_stream_new_resizable (); + g_autoptr (GInputStream) in = NULL; new[0] = 'A'; for (i = 0; i < OLD_SIZE; i++) @@ -88,7 +80,8 @@ test_bsdiff (void) g_assert (g_output_stream_close (out, NULL, NULL)); /* Now generate NEW_GENERATED from OLD and OUT. */ - { g_autoptr(GBytes) bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out)); + { + g_autoptr (GBytes) bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out)); in = g_memory_input_stream_new_from_bytes (bytes); } bspatch_stream.read = bzpatch_read; @@ -99,9 +92,10 @@ test_bsdiff (void) g_assert_cmpint (memcmp (new, new_generated, NEW_SIZE), ==, 0); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/bsdiff", test_bsdiff); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-checksum.c b/tests/test-checksum.c index 85d1c26..fabd029 100644 --- a/tests/test-checksum.c +++ b/tests/test-checksum.c @@ -20,11 +20,11 @@ #include "config.h" #include "libglnx.h" +#include "ostree-core-private.h" +#include #include #include -#include #include -#include "ostree-core-private.h" static void test_ostree_parse_delta_name (void) @@ -32,7 +32,8 @@ test_ostree_parse_delta_name (void) { g_autofree char *from = NULL; g_autofree char *to = NULL; - g_assert (_ostree_parse_delta_name ("30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d", &from, &to, NULL)); + g_assert (_ostree_parse_delta_name ( + "30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d", &from, &to, NULL)); g_assert_cmpstr (to, ==, "30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d"); g_assert_null (from); } @@ -40,7 +41,10 @@ test_ostree_parse_delta_name (void) { g_autofree char *from = NULL; g_autofree char *to = NULL; - g_assert (_ostree_parse_delta_name ("30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d-5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", &from, &to, NULL)); + g_assert (_ostree_parse_delta_name ( + "30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d-" + "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", + &from, &to, NULL)); g_assert_cmpstr (from, ==, "30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d"); g_assert_cmpstr (to, ==, "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03"); } @@ -64,7 +68,9 @@ test_ostree_parse_delta_name (void) { g_autofree char *from = NULL; g_autofree char *to = NULL; - g_assert (!_ostree_parse_delta_name ("GARBAGE-5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", &from, &to, NULL)); + g_assert (!_ostree_parse_delta_name ( + "GARBAGE-5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", &from, &to, + NULL)); g_assert_null (from); g_assert_null (to); } @@ -72,15 +78,18 @@ test_ostree_parse_delta_name (void) { g_autofree char *from = NULL; g_autofree char *to = NULL; - g_assert (!_ostree_parse_delta_name ("30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d-GARBAGE", &from, &to, NULL)); + g_assert (!_ostree_parse_delta_name ( + "30d13b73cfe1e6988ffc345eac905f82a18def8ef1f0666fc392019e9eac388d-GARBAGE", &from, &to, + NULL)); g_assert_null (from); g_assert_null (to); } } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/ostree_parse_delta_name", test_ostree_parse_delta_name); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-commit-sign-sh-ext.c b/tests/test-commit-sign-sh-ext.c index 6dc287d..3469471 100644 --- a/tests/test-commit-sign-sh-ext.c +++ b/tests/test-commit-sign-sh-ext.c @@ -41,7 +41,7 @@ corrupt (GBytes *input) const guint8 *buf = g_bytes_get_data (input, &len); g_assert_cmpint (len, >, 0); g_assert_cmpint (len, <, G_MAXINT); - g_autofree char *newbuf = g_memdup (buf, len); + g_autofree char *newbuf = g_memdup2 (buf, len); g_assert (newbuf != NULL); int o = g_random_int_range (0, len); newbuf[o] = (newbuf[0] + 1); @@ -52,7 +52,7 @@ corrupt (GBytes *input) static gboolean run (GError **error) { - g_autoptr(OstreeRepo) repo = ostree_repo_open_at (AT_FDCWD, "repo", NULL, error); + g_autoptr (OstreeRepo) repo = ostree_repo_open_at (AT_FDCWD, "repo", NULL, error); if (!repo) return FALSE; @@ -60,45 +60,46 @@ run (GError **error) if (!ostree_repo_resolve_rev (repo, "origin:main", FALSE, &rev, error)) return FALSE; g_assert (rev); - g_autoptr(GVariant) commit = NULL; + g_autoptr (GVariant) commit = NULL; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &commit, error)) return FALSE; g_assert (commit); - g_autoptr(GVariant) detached_meta = NULL; + g_autoptr (GVariant) detached_meta = NULL; if (!ostree_repo_read_commit_detached_metadata (repo, rev, &detached_meta, NULL, error)) return FALSE; g_assert (detached_meta); - g_autoptr(GBytes) commit_bytes = g_variant_get_data_as_bytes (commit); - g_autoptr(GBytes) detached_meta_bytes = g_variant_get_data_as_bytes (detached_meta); + g_autoptr (GBytes) commit_bytes = g_variant_get_data_as_bytes (commit); + g_autoptr (GBytes) detached_meta_bytes = g_variant_get_data_as_bytes (detached_meta); g_autofree char *verify_report = NULL; - if (!ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, detached_meta_bytes, 0, - &verify_report, error)) + if (!ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, detached_meta_bytes, + 0, &verify_report, error)) return FALSE; - if (ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, detached_meta_bytes, - OSTREE_REPO_VERIFY_FLAGS_NO_GPG | OSTREE_REPO_VERIFY_FLAGS_NO_SIGNAPI, + if (ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, detached_meta_bytes, + OSTREE_REPO_VERIFY_FLAGS_NO_GPG + | OSTREE_REPO_VERIFY_FLAGS_NO_SIGNAPI, &verify_report, error)) return glnx_throw (error, "Should not have validated"); assert_error_contains (error, "No commit verification types enabled"); // No signatures - g_autoptr(GBytes) empty = g_bytes_new_static ("", 0); - if (ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, empty, 0, - &verify_report, error)) + g_autoptr (GBytes) empty = g_bytes_new_static ("", 0); + if (ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, empty, 0, + &verify_report, error)) return glnx_throw (error, "Should not have validated"); assert_error_contains (error, "no signatures found"); // No such remote - if (ostree_repo_signature_verify_commit_data (repo, "nosuchremote", commit_bytes, detached_meta_bytes, 0, - &verify_report, error)) + if (ostree_repo_signature_verify_commit_data (repo, "nosuchremote", commit_bytes, + detached_meta_bytes, 0, &verify_report, error)) return glnx_throw (error, "Should not have validated"); assert_error_contains (error, "Remote \"nosuchremote\" not found"); // Corrupted commit - g_autoptr(GBytes) corrupted_commit = corrupt (commit_bytes); - if (ostree_repo_signature_verify_commit_data (repo, "origin", corrupted_commit, detached_meta_bytes, 0, - &verify_report, error)) + g_autoptr (GBytes) corrupted_commit = corrupt (commit_bytes); + if (ostree_repo_signature_verify_commit_data (repo, "origin", corrupted_commit, + detached_meta_bytes, 0, &verify_report, error)) return glnx_throw (error, "Should not have validated"); assert_error_contains (error, "BAD signature"); @@ -108,7 +109,7 @@ run (GError **error) int main (int argc, char **argv) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; if (!run (&error)) { g_printerr ("error: %s\n", error->message); diff --git a/tests/test-commit-sign.sh b/tests/test-commit-sign.sh index 2aad1cf..e0cea0b 100755 --- a/tests/test-commit-sign.sh +++ b/tests/test-commit-sign.sh @@ -26,6 +26,11 @@ if ! has_gpgme; then exit 0 fi +if test -z "${OSTREE_HTTPD}"; then + echo "1..0 #SKIP no ostree-trivial-httpd" + exit 0 +fi + echo "1..7" keyid="472CDAFA" diff --git a/tests/test-commit-timestamp.sh b/tests/test-commit-timestamp.sh index 7dbdbdf..de105b7 100755 --- a/tests/test-commit-timestamp.sh +++ b/tests/test-commit-timestamp.sh @@ -30,16 +30,16 @@ mkdir testrepo-files cd testrepo-files echo first > firstfile cd .. -${CMD_PREFIX} SOURCE_DATE_EPOCH='1234567890' ostree --repo=./testrepo commit -b env -s "env timestamp" -if (${CMD_PREFIX} SOURCE_DATE_EPOCH='invalid' ostree --repo=./testrepo commit -b env -s "invalid timestamp") 2> commit-invalid.txt; then +${CMD_PREFIX} env SOURCE_DATE_EPOCH='1234567890' ostree --repo=./testrepo commit -b env -s "env timestamp" +if (${CMD_PREFIX} env SOURCE_DATE_EPOCH='invalid' ostree --repo=./testrepo commit -b env -s "invalid timestamp") 2> commit-invalid.txt; then assert_not_reached "commit with invalid timestamp succeeded" fi -if (${CMD_PREFIX} SOURCE_DATE_EPOCH='12345678901234567890' ostree --repo=./testrepo commit -b env -s "overflowing timestamp") 2> commit-overflowing.txt; then +if (${CMD_PREFIX} env SOURCE_DATE_EPOCH='12345678901234567890' ostree --repo=./testrepo commit -b env -s "overflowing timestamp") 2> commit-overflowing.txt; then assert_not_reached "commit with overflowing timestamp succeeded" fi ${CMD_PREFIX} ostree --repo=./testrepo show env > show-env.txt rm -rf testrepo testrepo-files assert_file_has_content_literal commit-invalid.txt 'Failed to convert SOURCE_DATE_EPOCH' -assert_file_has_content_literal commit-overflowing.txt 'Parsing SOURCE_DATE_EPOCH: Numerical result out of range' +assert_file_has_content commit-overflowing.txt 'Parsing SOURCE_DATE_EPOCH: \(Numerical result out of range\|Result not representable\)' assert_file_has_content_literal show-env.txt 'Date: 2009-02-13 23:31:30 +0000' echo "ok commit with env timestamp" diff --git a/tests/test-composefs.sh b/tests/test-composefs.sh new file mode 100755 index 0000000..4b91973 --- /dev/null +++ b/tests/test-composefs.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +if ! ${CMD_PREFIX} ostree --version | grep -q -e '- composefs'; then + echo "1..0 #SKIP no composefs support compiled in" + exit 0 +fi + + +setup_test_repository "bare-user" + +cd ${test_tmpdir} +$OSTREE checkout test2 test2-co +rm test2-co/whiteouts -rf # This may or may not exist +COMMIT_ARGS="--owner-uid=0 --owner-gid=0 --no-xattrs --canonical-permissions" +$OSTREE commit ${COMMIT_ARGS} -b test-composefs --generate-composefs-metadata test2-co +# If the test fails we'll dump this out +$OSTREE ls -RCX test-composefs / +orig_composefs_digest=$($OSTREE show --print-hex --print-metadata-key ostree.composefs.digest.v0 test-composefs) +$OSTREE commit ${COMMIT_ARGS} -b test-composefs2 --generate-composefs-metadata test2-co +new_composefs_digest=$($OSTREE show --print-hex --print-metadata-key ostree.composefs.digest.v0 test-composefs2) +assert_streq "${orig_composefs_digest}" "${new_composefs_digest}" +assert_streq "${new_composefs_digest}" "be956966c70970ea23b1a8043bca58cfb0d011d490a35a7817b36d04c0210954" +tap_ok "composefs metadata" + +tap_end diff --git a/tests/test-concurrency.py b/tests/test-concurrency.py index 99b7436..7efb5bd 100755 --- a/tests/test-concurrency.py +++ b/tests/test-concurrency.py @@ -43,10 +43,6 @@ def mktree(dname, serial=0): # it's simpler, and we don't need xattr coverage for this f.write('disable-xattrs=true\n') - # Make any locking errors fail quickly instead of blocking the test - # for 30 seconds. - f.write('lock-timeout-secs=5\n') - def commit(v): tdir='tree{}'.format(v) cmd = ['ostree', '--repo=repo', 'commit', '--fsync=0', '-b', tdir, '--tree=dir='+tdir] diff --git a/tests/test-delta-ed25519.sh b/tests/test-delta-ed25519.sh index 791b316..9e00fdb 100755 --- a/tests/test-delta-ed25519.sh +++ b/tests/test-delta-ed25519.sh @@ -90,7 +90,6 @@ newrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test) # Test ostree sign with 'ed25519' module gen_ed25519_keys PUBLIC=${ED25519PUBLIC} -SEED=${ED25519SEED} SECRET=${ED25519SECRET} WRONG_PUBLIC="$(gen_ed25519_random_public)" @@ -240,7 +239,6 @@ echo 'ok verified with ed25519 (keyfile - file)' # Test ostree sign with multiple 'ed25519' keys gen_ed25519_keys PUBLIC2=${ED25519PUBLIC} -SEED2=${ED25519SEED} SECRET2=${ED25519SECRET} echo ${SECRET2} >> ${SECRETKEYS} diff --git a/tests/test-delta.sh b/tests/test-delta.sh index 2a63026..4c9e2e2 100755 --- a/tests/test-delta.sh +++ b/tests/test-delta.sh @@ -26,7 +26,7 @@ skip_without_user_xattrs bindatafiles="bash true ostree" morebindatafiles="false ls" -echo '1..13' +echo '1..14' mkdir repo ostree_repo_init repo --mode=archive @@ -183,13 +183,27 @@ echo 'ok heuristic endian detection' ${CMD_PREFIX} ostree --repo=repo summary -u mkdir repo2 && ostree_repo_init repo2 --mode=bare-user -${CMD_PREFIX} ostree --repo=repo2 pull-local --require-static-deltas repo ${origrev} +${CMD_PREFIX} ostree --repo=repo2 pull-local --require-static-deltas repo ${origrev} | tee pullstats.txt +# we should've only fetched the superblock, the index, and the delta part +assert_file_has_content pullstats.txt '1 delta parts, 2 loose fetched; .* transferred in .* seconds; 0 bytes content written' ${CMD_PREFIX} ostree --repo=repo2 fsck ${CMD_PREFIX} ostree --repo=repo2 ls ${origrev} >/dev/null echo 'ok pull delta' -rm repo2 -rf +# verify that having the commit partially doesn't degrade static delta fetching +rm repo2 pullstats.txt -rf +mkdir repo2 && ostree_repo_init repo2 --mode=bare-user +${CMD_PREFIX} ostree --repo=repo2 pull-local --disable-static-deltas repo ${origrev} --commit-metadata-only +${CMD_PREFIX} ostree --repo=repo2 pull-local --require-static-deltas repo ${origrev} | tee pullstats.txt +${CMD_PREFIX} ostree --repo=repo2 fsck +# we should've only fetched the superblock, the index, and the delta part +assert_file_has_content pullstats.txt '1 delta parts, 2 loose fetched; .* transferred in .* seconds; 0 bytes content written' +${CMD_PREFIX} ostree --repo=repo2 ls ${origrev} >/dev/null + +echo 'ok pull delta with commitpartial' + +rm repo2 pullstats.txt -rf mkdir repo2 && ostree_repo_init repo2 --mode=bare-user mkdir deltadir diff --git a/tests/test-export.sh b/tests/test-export.sh index e490ae4..6b8de94 100755 --- a/tests/test-export.sh +++ b/tests/test-export.sh @@ -28,7 +28,7 @@ fi setup_test_repository "archive" -echo '1..5' +echo '1..6' $OSTREE checkout test2 test2-co $OSTREE commit --no-xattrs -b test2-noxattrs -s "test2 without xattrs" --tree=dir=test2-co @@ -81,3 +81,11 @@ assert_file_empty diff.txt rm test2.tar diff.txt t -rf echo 'ok export import' + +cd ${test_tmpdir} +${OSTREE} 'export' test2 -o test2.tar +tar tvf test2.tar > test2.manifest +assert_file_has_content test2.manifest 'baz/sub1/duplicate_b link to baz/sub1/duplicate_a' +assert_file_has_content test2.manifest 'baz/sub2/duplicate_c link to baz/sub1/duplicate_a' + +echo 'ok export hard links' diff --git a/tests/test-gpg-verify-result.c b/tests/test-gpg-verify-result.c index 8485b88..e7171a8 100644 --- a/tests/test-gpg-verify-result.c +++ b/tests/test-gpg-verify-result.c @@ -19,51 +19,55 @@ #include "config.h" -#include #include "libglnx.h" +#include #include "ostree-gpg-verify-result-private.h" #define assert_no_gpg_error(err, filename) \ - G_STMT_START { \ - if (err != GPG_ERR_NO_ERROR) { \ - g_autoptr(GString) string = g_string_new ("assertion failed "); \ - g_string_append_printf (string, "%s: %s ", gpgme_strsource (err), gpgme_strerror (err)); \ - g_string_append (string, filename ? filename : ""); \ - g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, string->str); \ - } \ - } G_STMT_END + G_STMT_START \ + { \ + if (err != GPG_ERR_NO_ERROR) \ + { \ + g_autoptr (GString) string = g_string_new ("assertion failed "); \ + g_string_append_printf (string, "%s: %s ", gpgme_strsource (err), gpgme_strerror (err)); \ + g_string_append (string, filename ? filename : ""); \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, string->str); \ + } \ + } \ + G_STMT_END #define assert_str_contains(s1, s2) \ - G_STMT_START { \ + G_STMT_START \ + { \ const char *__s1 = (s1), *__s2 = (s2); \ - if (strstr (__s1, __s2) == NULL) { \ - g_autoptr(GString) string = g_string_new ("assertion failed (" #s1 " contains " #s2 "): "); \ - g_autofree char *__es1 = g_strescape (__s1, NULL); \ - g_autofree char *__es2 = g_strescape (__s2, NULL); \ - g_string_append_printf (string, "(\"%s\", \"%s\")", __es1, __es2); \ - g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, string->str); \ - } \ - } G_STMT_END - -typedef struct { + if (strstr (__s1, __s2) == NULL) \ + { \ + g_autoptr (GString) string \ + = g_string_new ("assertion failed (" #s1 " contains " #s2 "): "); \ + g_autofree char *__es1 = g_strescape (__s1, NULL); \ + g_autofree char *__es2 = g_strescape (__s2, NULL); \ + g_string_append_printf (string, "(\"%s\", \"%s\")", __es1, __es2); \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, string->str); \ + } \ + } \ + G_STMT_END + +typedef struct +{ OstreeGpgVerifyResult *result; } TestFixture; static OstreeGpgSignatureAttr some_attributes[] = { - OSTREE_GPG_SIGNATURE_ATTR_VALID, - OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, - OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, - OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED, - OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, - OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, + OSTREE_GPG_SIGNATURE_ATTR_VALID, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED, + OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED, + OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP, }; static void -test_fixture_setup (TestFixture *fixture, - gconstpointer user_data) +test_fixture_setup (TestFixture *fixture, gconstpointer user_data) { - const char * const *sig_files = user_data; + const char *const *sig_files = user_data; gpgme_error_t gpg_error; gpgme_data_t data_buffer; gpgme_data_t signature_buffer; @@ -81,8 +85,7 @@ test_fixture_setup (TestFixture *fixture, gboolean is_ok = g_setenv ("GNUPGHOME", homedir, TRUE); g_assert (is_ok == TRUE); - result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT, - NULL, &local_error, NULL); + result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT, NULL, &local_error, NULL); g_assert_no_error (local_error); g_autofree char *data_filename = g_build_filename (homedir, "lgpl2", NULL); @@ -102,15 +105,15 @@ test_fixture_setup (TestFixture *fixture, gpg_error = gpgme_data_new (&signature_buffer); assert_no_gpg_error (gpg_error, NULL); - for (const char * const *name = sig_files; *name != NULL; name++) + for (const char *const *name = sig_files; *name != NULL; name++) { g_autofree char *path = g_build_filename (homedir, *name, NULL); - g_autoptr(GFile) sig_file = g_file_new_for_path (path); + g_autoptr (GFile) sig_file = g_file_new_for_path (path); g_autofree char *contents = NULL; gsize len; - g_assert_true (g_file_load_contents (sig_file, NULL, &contents, - &len, NULL, &local_error)); + g_assert_true ( + g_file_load_contents (sig_file, NULL, &contents, &len, NULL, &local_error)); g_assert_no_error (local_error); char *cur = contents; @@ -127,8 +130,7 @@ test_fixture_setup (TestFixture *fixture, gpgme_data_seek (signature_buffer, 0, SEEK_SET); } - gpg_error = gpgme_op_verify (result->context, - signature_buffer, data_buffer, NULL); + gpg_error = gpgme_op_verify (result->context, signature_buffer, data_buffer, NULL); assert_no_gpg_error (gpg_error, NULL); result->details = gpgme_op_verify_result (result->context); @@ -141,15 +143,13 @@ test_fixture_setup (TestFixture *fixture, } static void -test_fixture_teardown (TestFixture *fixture, - gconstpointer user_data) +test_fixture_teardown (TestFixture *fixture, gconstpointer user_data) { g_clear_object (&fixture->result); } static void -test_check_counts (TestFixture *fixture, - gconstpointer user_data) +test_check_counts (TestFixture *fixture, gconstpointer user_data) { guint count_all; guint count_valid; @@ -162,8 +162,7 @@ test_check_counts (TestFixture *fixture, } static void -test_signature_lookup (TestFixture *fixture, - gconstpointer user_data) +test_signature_lookup (TestFixture *fixture, gconstpointer user_data) { /* Checking the signature with the revoked key for this case. */ guint expected_signature_index = 2; @@ -176,33 +175,29 @@ test_signature_lookup (TestFixture *fixture, /* Lookup full fingerprint. */ signature_index = 999999; - signature_found = ostree_gpg_verify_result_lookup (fixture->result, - fingerprint, - &signature_index); + signature_found + = ostree_gpg_verify_result_lookup (fixture->result, fingerprint, &signature_index); g_assert_true (signature_found); g_assert_cmpint (signature_index, ==, expected_signature_index); /* Lookup abbreviated key ID. */ signature_index = 999999; - signature_found = ostree_gpg_verify_result_lookup (fixture->result, - fingerprint + 32, - &signature_index); + signature_found + = ostree_gpg_verify_result_lookup (fixture->result, fingerprint + 32, &signature_index); g_assert_true (signature_found); g_assert_cmpint (signature_index, ==, expected_signature_index); /* Bogus fingerprint, index should remain unchanged. */ signature_index = expected_signature_index = 999999; fingerprint = "CAFEBABECAFEBABECAFEBABECAFEBABECAFEBABE"; - signature_found = ostree_gpg_verify_result_lookup (fixture->result, - fingerprint, - &signature_index); + signature_found + = ostree_gpg_verify_result_lookup (fixture->result, fingerprint, &signature_index); g_assert_false (signature_found); g_assert_cmpint (signature_index, ==, expected_signature_index); } static void -test_attribute_basics (TestFixture *fixture, - gconstpointer user_data) +test_attribute_basics (TestFixture *fixture, gconstpointer user_data) { guint n_signatures, ii; @@ -210,7 +205,7 @@ test_attribute_basics (TestFixture *fixture, for (ii = 0; ii < n_signatures; ii++) { - g_autoptr(GVariant) tuple = NULL; + g_autoptr (GVariant) tuple = NULL; const char *attr_string; const char *type_string; gboolean key_missing; @@ -222,31 +217,21 @@ test_attribute_basics (TestFixture *fixture, /* Check attributes which should be common to all signatures. */ - g_variant_get_child (tuple, - OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME, - "&s", &attr_string); + g_variant_get_child (tuple, OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME, "&s", &attr_string); g_assert_cmpstr (attr_string, ==, "RSA"); - g_variant_get_child (tuple, - OSTREE_GPG_SIGNATURE_ATTR_HASH_ALGO_NAME, - "&s", &attr_string); + g_variant_get_child (tuple, OSTREE_GPG_SIGNATURE_ATTR_HASH_ALGO_NAME, "&s", &attr_string); g_assert_cmpstr (attr_string, ==, "SHA1"); - g_variant_get_child (tuple, - OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, - "b", &key_missing); + g_variant_get_child (tuple, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING, "b", &key_missing); - g_variant_get_child (tuple, - OSTREE_GPG_SIGNATURE_ATTR_USER_NAME, - "&s", &attr_string); + g_variant_get_child (tuple, OSTREE_GPG_SIGNATURE_ATTR_USER_NAME, "&s", &attr_string); if (key_missing) g_assert_cmpstr (attr_string, ==, "[unknown name]"); else g_assert_cmpstr (attr_string, ==, "J. Random User"); - g_variant_get_child (tuple, - OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL, - "&s", &attr_string); + g_variant_get_child (tuple, OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL, "&s", &attr_string); if (key_missing) g_assert_cmpstr (attr_string, ==, "[unknown email]"); else @@ -255,11 +240,10 @@ test_attribute_basics (TestFixture *fixture, } static void -test_valid_signature (TestFixture *fixture, - gconstpointer user_data) +test_valid_signature (TestFixture *fixture, gconstpointer user_data) { guint signature_index = 0; - g_autoptr(GVariant) tuple = NULL; + g_autoptr (GVariant) tuple = NULL; gboolean valid; gboolean sig_expired; gboolean key_expired; @@ -267,17 +251,10 @@ test_valid_signature (TestFixture *fixture, gboolean key_missing; gint64 key_exp_timestamp; - tuple = ostree_gpg_verify_result_get (fixture->result, - signature_index, - some_attributes, + tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbbx)", - &valid, - &sig_expired, - &key_expired, - &key_revoked, - &key_missing, + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, &key_missing, &key_exp_timestamp); g_assert_true (valid); @@ -289,11 +266,10 @@ test_valid_signature (TestFixture *fixture, } static void -test_expired_key (TestFixture *fixture, - gconstpointer user_data) +test_expired_key (TestFixture *fixture, gconstpointer user_data) { guint signature_index = 1; - g_autoptr(GVariant) tuple = NULL; + g_autoptr (GVariant) tuple = NULL; gboolean valid; gboolean sig_expired; gboolean key_expired; @@ -301,17 +277,10 @@ test_expired_key (TestFixture *fixture, gboolean key_missing; gint64 key_exp_timestamp; - tuple = ostree_gpg_verify_result_get (fixture->result, - signature_index, - some_attributes, + tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbbx)", - &valid, - &sig_expired, - &key_expired, - &key_revoked, - &key_missing, + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, &key_missing, &key_exp_timestamp); g_assert_false (valid); @@ -323,11 +292,10 @@ test_expired_key (TestFixture *fixture, } static void -test_revoked_key (TestFixture *fixture, - gconstpointer user_data) +test_revoked_key (TestFixture *fixture, gconstpointer user_data) { guint signature_index = 2; - g_autoptr(GVariant) tuple = NULL; + g_autoptr (GVariant) tuple = NULL; gboolean valid; gboolean sig_expired; gboolean key_expired; @@ -335,17 +303,10 @@ test_revoked_key (TestFixture *fixture, gboolean key_missing; gint64 key_exp_timestamp; - tuple = ostree_gpg_verify_result_get (fixture->result, - signature_index, - some_attributes, + tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbbx)", - &valid, - &sig_expired, - &key_expired, - &key_revoked, - &key_missing, + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, &key_missing, &key_exp_timestamp); g_assert_false (valid); @@ -357,11 +318,10 @@ test_revoked_key (TestFixture *fixture, } static void -test_missing_key (TestFixture *fixture, - gconstpointer user_data) +test_missing_key (TestFixture *fixture, gconstpointer user_data) { guint signature_index = 3; - g_autoptr(GVariant) tuple = NULL; + g_autoptr (GVariant) tuple = NULL; gboolean valid; gboolean sig_expired; gboolean key_expired; @@ -369,17 +329,10 @@ test_missing_key (TestFixture *fixture, gboolean key_missing; gint64 key_exp_timestamp; - tuple = ostree_gpg_verify_result_get (fixture->result, - signature_index, - some_attributes, + tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbbx)", - &valid, - &sig_expired, - &key_expired, - &key_revoked, - &key_missing, + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, &key_missing, &key_exp_timestamp); g_assert_false (valid); @@ -391,11 +344,10 @@ test_missing_key (TestFixture *fixture, } static void -test_expired_signature (TestFixture *fixture, - gconstpointer user_data) +test_expired_signature (TestFixture *fixture, gconstpointer user_data) { guint signature_index = 4; - g_autoptr(GVariant) tuple = NULL; + g_autoptr (GVariant) tuple = NULL; gboolean valid; gboolean sig_expired; gboolean key_expired; @@ -403,17 +355,10 @@ test_expired_signature (TestFixture *fixture, gboolean key_missing; gint64 key_exp_timestamp; - tuple = ostree_gpg_verify_result_get (fixture->result, - signature_index, - some_attributes, + tuple = ostree_gpg_verify_result_get (fixture->result, signature_index, some_attributes, G_N_ELEMENTS (some_attributes)); - g_variant_get (tuple, "(bbbbbx)", - &valid, - &sig_expired, - &key_expired, - &key_revoked, - &key_missing, + g_variant_get (tuple, "(bbbbbx)", &valid, &sig_expired, &key_expired, &key_revoked, &key_missing, &key_exp_timestamp); g_assert_false (valid); @@ -425,71 +370,59 @@ test_expired_signature (TestFixture *fixture, } static void -test_require_valid_signature (TestFixture *fixture, - gconstpointer user_data) +test_require_valid_signature (TestFixture *fixture, gconstpointer user_data) { GError *error = NULL; - gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, - &error); + gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, &error); g_assert_true (res); g_assert_no_error (error); } static void -test_require_valid_signature_expired_key (TestFixture *fixture, - gconstpointer user_data) +test_require_valid_signature_expired_key (TestFixture *fixture, gconstpointer user_data) { GError *error = NULL; - gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, - &error); + gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, &error); g_assert_false (res); g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_EXPIRED_KEY); assert_str_contains (error->message, "Key expired"); } static void -test_require_valid_signature_revoked_key (TestFixture *fixture, - gconstpointer user_data) +test_require_valid_signature_revoked_key (TestFixture *fixture, gconstpointer user_data) { GError *error = NULL; - gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, - &error); + gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, &error); g_assert_false (res); g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_REVOKED_KEY); assert_str_contains (error->message, "Key revoked"); } static void -test_require_valid_signature_missing_key (TestFixture *fixture, - gconstpointer user_data) +test_require_valid_signature_missing_key (TestFixture *fixture, gconstpointer user_data) { GError *error = NULL; - gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, - &error); + gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, &error); g_assert_false (res); g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_MISSING_KEY); assert_str_contains (error->message, "public key not found"); } static void -test_require_valid_signature_expired_signature (TestFixture *fixture, - gconstpointer user_data) +test_require_valid_signature_expired_signature (TestFixture *fixture, gconstpointer user_data) { GError *error = NULL; - gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, - &error); + gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, &error); g_assert_false (res); g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_EXPIRED_SIGNATURE); assert_str_contains (error->message, "Signature expired"); } static void -test_require_valid_signature_expired_missing_key (TestFixture *fixture, - gconstpointer user_data) +test_require_valid_signature_expired_missing_key (TestFixture *fixture, gconstpointer user_data) { GError *error = NULL; - gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, - &error); + gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result, &error); g_assert_false (res); /* @@ -506,110 +439,59 @@ main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); - (void) gpgme_check_version (NULL); + (void)gpgme_check_version (NULL); - g_test_add ("/gpg-verify-result/check-counts", - TestFixture, - NULL, - test_fixture_setup, - test_check_counts, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/check-counts", TestFixture, NULL, test_fixture_setup, + test_check_counts, test_fixture_teardown); - g_test_add ("/gpg-verify-result/signature-lookup", - TestFixture, - NULL, - test_fixture_setup, - test_signature_lookup, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/signature-lookup", TestFixture, NULL, test_fixture_setup, + test_signature_lookup, test_fixture_teardown); - g_test_add ("/gpg-verify-result/attribute-basics", - TestFixture, - NULL, - test_fixture_setup, - test_attribute_basics, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/attribute-basics", TestFixture, NULL, test_fixture_setup, + test_attribute_basics, test_fixture_teardown); - g_test_add ("/gpg-verify-result/valid-signature", - TestFixture, - NULL, - test_fixture_setup, - test_valid_signature, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/valid-signature", TestFixture, NULL, test_fixture_setup, + test_valid_signature, test_fixture_teardown); - g_test_add ("/gpg-verify-result/expired-key", - TestFixture, - NULL, - test_fixture_setup, - test_expired_key, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/expired-key", TestFixture, NULL, test_fixture_setup, + test_expired_key, test_fixture_teardown); - g_test_add ("/gpg-verify-result/revoked-key", - TestFixture, - NULL, - test_fixture_setup, - test_revoked_key, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/revoked-key", TestFixture, NULL, test_fixture_setup, + test_revoked_key, test_fixture_teardown); - g_test_add ("/gpg-verify-result/missing-key", - TestFixture, - NULL, - test_fixture_setup, - test_missing_key, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/missing-key", TestFixture, NULL, test_fixture_setup, + test_missing_key, test_fixture_teardown); - g_test_add ("/gpg-verify-result/expired-signature", - TestFixture, - NULL, - test_fixture_setup, - test_expired_signature, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/expired-signature", TestFixture, NULL, test_fixture_setup, + test_expired_signature, test_fixture_teardown); - g_test_add ("/gpg-verify-result/require-valid-signature", - TestFixture, - NULL, - test_fixture_setup, - test_require_valid_signature, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/require-valid-signature", TestFixture, NULL, test_fixture_setup, + test_require_valid_signature, test_fixture_teardown); const char *expired_key_files[] = { "lgpl2.sig1", NULL }; - g_test_add ("/gpg-verify-result/require-valid-signature-expired-key", - TestFixture, - expired_key_files, - test_fixture_setup, - test_require_valid_signature_expired_key, + g_test_add ("/gpg-verify-result/require-valid-signature-expired-key", TestFixture, + expired_key_files, test_fixture_setup, test_require_valid_signature_expired_key, test_fixture_teardown); const char *revoked_key_files[] = { "lgpl2.sig2", NULL }; - g_test_add ("/gpg-verify-result/require-valid-signature-revoked-key", - TestFixture, - revoked_key_files, - test_fixture_setup, - test_require_valid_signature_revoked_key, + g_test_add ("/gpg-verify-result/require-valid-signature-revoked-key", TestFixture, + revoked_key_files, test_fixture_setup, test_require_valid_signature_revoked_key, test_fixture_teardown); const char *missing_key_files[] = { "lgpl2.sig3", NULL }; - g_test_add ("/gpg-verify-result/require-valid-signature-missing-key", - TestFixture, - missing_key_files, - test_fixture_setup, - test_require_valid_signature_missing_key, + g_test_add ("/gpg-verify-result/require-valid-signature-missing-key", TestFixture, + missing_key_files, test_fixture_setup, test_require_valid_signature_missing_key, test_fixture_teardown); const char *expired_signature_files[] = { "lgpl2.sig4", NULL }; - g_test_add ("/gpg-verify-result/require-valid-signature-expired-signature", - TestFixture, - expired_signature_files, - test_fixture_setup, - test_require_valid_signature_expired_signature, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/require-valid-signature-expired-signature", TestFixture, + expired_signature_files, test_fixture_setup, + test_require_valid_signature_expired_signature, test_fixture_teardown); const char *expired_missing_key_files[] = { "lgpl2.sig1", "lgpl2.sig3", NULL }; - g_test_add ("/gpg-verify-result/require-valid-signature-expired-missing-key", - TestFixture, - expired_missing_key_files, - test_fixture_setup, - test_require_valid_signature_expired_missing_key, - test_fixture_teardown); + g_test_add ("/gpg-verify-result/require-valid-signature-expired-missing-key", TestFixture, + expired_missing_key_files, test_fixture_setup, + test_require_valid_signature_expired_missing_key, test_fixture_teardown); return g_test_run (); } diff --git a/tests/test-include-ostree-h.c b/tests/test-include-ostree-h.c index e23dc18..45b2c05 100644 --- a/tests/test-include-ostree-h.c +++ b/tests/test-include-ostree-h.c @@ -32,12 +32,13 @@ test_include_ostree_h_compiled (void) } /* Just ensure that we can compile with ostree.h included */ -int main (int argc, char **argv) +int +main (int argc, char **argv) { setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); g_test_add_func ("/include-ostree-h/compiled", test_include_ostree_h_compiled); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-kargs.c b/tests/test-kargs.c index 92441fb..bd1735d 100644 --- a/tests/test-kargs.c +++ b/tests/test-kargs.c @@ -18,29 +18,26 @@ */ #include "config.h" -#include "ostree-kernel-args.h" +#include "ostree-kernel-args-private.h" #include "otutil.h" static gboolean -check_string_existance (OstreeKernelArgs *karg, - const char *string_to_find) +check_string_existance (OstreeKernelArgs *karg, const char *string_to_find) { - g_autofree gchar* string_with_spaces = ostree_kernel_args_to_string (karg); - g_auto(GStrv) string_list = g_strsplit (string_with_spaces, " ", -1); - return g_strv_contains ((const char* const*) string_list, string_to_find); + g_autofree gchar *string_with_spaces = ostree_kernel_args_to_string (karg); + g_auto (GStrv) string_list = g_strsplit (string_with_spaces, " ", -1); + return g_strv_contains ((const char *const *)string_list, string_to_find); } static gboolean -kernel_args_entry_value_equal (gconstpointer data, - gconstpointer value) +kernel_args_entry_value_equal (gconstpointer data, gconstpointer value) { const OstreeKernelArgsEntry *e = data; return g_strcmp0 (_ostree_kernel_args_entry_get_value (e), value) == 0; } static gboolean -kernel_args_entry_key_equal (gconstpointer data, - gconstpointer key) +kernel_args_entry_key_equal (gconstpointer data, gconstpointer key) { const OstreeKernelArgsEntry *e = data; return g_strcmp0 (_ostree_kernel_args_entry_get_key (e), key) == 0; @@ -49,9 +46,10 @@ kernel_args_entry_key_equal (gconstpointer data, static void test_kargs_delete (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; gboolean ret; - __attribute__((cleanup(ostree_kernel_args_cleanup))) OstreeKernelArgs *karg = ostree_kernel_args_new (); + __attribute__ ((cleanup (ostree_kernel_args_cleanup))) OstreeKernelArgs *karg + = ostree_kernel_args_new (); ostree_kernel_args_append (karg, "single_key=test"); ostree_kernel_args_append (karg, "test=firstval"); @@ -96,7 +94,8 @@ test_kargs_delete (void) g_assert (ret); /* verify the value array is properly updated */ GPtrArray *kargs_array = _ostree_kernel_arg_get_key_array (karg); - g_assert (!ot_ptr_array_find_with_equal_func (kargs_array, "single_key", kernel_args_entry_value_equal, NULL)); + g_assert (!ot_ptr_array_find_with_equal_func (kargs_array, "single_key", + kernel_args_entry_value_equal, NULL)); g_assert (!check_string_existance (karg, "single_key")); /* Delete specific key/value pair */ @@ -146,9 +145,10 @@ test_kargs_delete (void) static void test_kargs_replace (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; gboolean ret; - __attribute__((cleanup(ostree_kernel_args_cleanup))) OstreeKernelArgs *karg = ostree_kernel_args_new (); + __attribute__ ((cleanup (ostree_kernel_args_cleanup))) OstreeKernelArgs *karg + = ostree_kernel_args_new (); ostree_kernel_args_append (karg, "single_key"); ostree_kernel_args_append (karg, "test=firstval"); @@ -198,7 +198,8 @@ test_kargs_replace (void) static void test_kargs_append (void) { - __attribute__((cleanup(ostree_kernel_args_cleanup))) OstreeKernelArgs *append_arg = ostree_kernel_args_new (); + __attribute__ ((cleanup (ostree_kernel_args_cleanup))) OstreeKernelArgs *append_arg + = ostree_kernel_args_new (); /* Some valid cases (key=value) pair */ ostree_kernel_args_append (append_arg, "test=valid"); ostree_kernel_args_append (append_arg, "test=secondvalid"); @@ -211,43 +212,49 @@ test_kargs_append (void) * we have yet to find the conversion kargs to string fully "functional" */ GHashTable *kargs_table = _ostree_kernel_arg_get_kargs_table (append_arg); - GLNX_HASH_TABLE_FOREACH_KV (kargs_table, const char*, key, GPtrArray*, value_array) + GLNX_HASH_TABLE_FOREACH_KV (kargs_table, const char *, key, GPtrArray *, value_array) { if (g_str_equal (key, "test")) { - g_assert (ot_ptr_array_find_with_equal_func (value_array, "valid", kernel_args_entry_value_equal, NULL)); - g_assert (ot_ptr_array_find_with_equal_func (value_array, "secondvalid", kernel_args_entry_value_equal, NULL)); - g_assert (ot_ptr_array_find_with_equal_func (value_array, "", kernel_args_entry_value_equal, NULL)); - g_assert (ot_ptr_array_find_with_equal_func (value_array, NULL, kernel_args_entry_value_equal, NULL)); + g_assert (ot_ptr_array_find_with_equal_func (value_array, "valid", + kernel_args_entry_value_equal, NULL)); + g_assert (ot_ptr_array_find_with_equal_func (value_array, "secondvalid", + kernel_args_entry_value_equal, NULL)); + g_assert (ot_ptr_array_find_with_equal_func (value_array, "", + kernel_args_entry_value_equal, NULL)); + g_assert (ot_ptr_array_find_with_equal_func (value_array, NULL, + kernel_args_entry_value_equal, NULL)); } else { g_assert_cmpstr (key, ==, "second_test"); - g_assert (ot_ptr_array_find_with_equal_func (value_array, NULL, kernel_args_entry_value_equal, NULL)); + g_assert (ot_ptr_array_find_with_equal_func (value_array, NULL, + kernel_args_entry_value_equal, NULL)); } } /* verify the value array is properly updated */ GPtrArray *kargs_array = _ostree_kernel_arg_get_key_array (append_arg); - g_assert (ot_ptr_array_find_with_equal_func (kargs_array, "test", kernel_args_entry_key_equal, NULL)); - g_assert (ot_ptr_array_find_with_equal_func (kargs_array, "second_test", kernel_args_entry_key_equal, NULL)); + g_assert ( + ot_ptr_array_find_with_equal_func (kargs_array, "test", kernel_args_entry_key_equal, NULL)); + g_assert (ot_ptr_array_find_with_equal_func (kargs_array, "second_test", + kernel_args_entry_key_equal, NULL)); /* Up till this point, we verified that the above was all correct, we then * check ostree_kernel_args_to_string has the right result */ - g_autofree gchar* kargs_str = ostree_kernel_args_to_string (append_arg); - g_auto(GStrv) kargs_list = g_strsplit(kargs_str, " ", -1); - g_assert (g_strv_contains ((const char* const *)kargs_list, "test=valid")); - g_assert (g_strv_contains ((const char* const *)kargs_list, "test=secondvalid")); - g_assert (g_strv_contains ((const char* const *)kargs_list, "test=")); - g_assert (g_strv_contains ((const char* const *)kargs_list, "test")); - g_assert (g_strv_contains ((const char* const *)kargs_list, "second_test")); + g_autofree gchar *kargs_str = ostree_kernel_args_to_string (append_arg); + g_auto (GStrv) kargs_list = g_strsplit (kargs_str, " ", -1); + g_assert (g_strv_contains ((const char *const *)kargs_list, "test=valid")); + g_assert (g_strv_contains ((const char *const *)kargs_list, "test=secondvalid")); + g_assert (g_strv_contains ((const char *const *)kargs_list, "test=")); + g_assert (g_strv_contains ((const char *const *)kargs_list, "test")); + g_assert (g_strv_contains ((const char *const *)kargs_list, "second_test")); g_assert_cmpint (5, ==, g_strv_length (kargs_list)); } int -main (int argc, - char *argv[]) +main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); diff --git a/tests/test-keyfile-utils.c b/tests/test-keyfile-utils.c index 49ac10f..198e71d 100644 --- a/tests/test-keyfile-utils.c +++ b/tests/test-keyfile-utils.c @@ -19,57 +19,41 @@ #include "config.h" #include "libglnx.h" +#include "ot-keyfile-utils.h" +#include #include #include -#include #include -#include "ot-keyfile-utils.h" static GKeyFile *g_keyfile; static void test_get_boolean_with_default (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; gboolean out = FALSE; - g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, - "section", - "a_boolean_true", - FALSE, - &out, - &error)); + g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, "section", "a_boolean_true", FALSE, + &out, &error)); g_assert_true (out); - g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, - "section", - "a_boolean_false", - TRUE, - &out, - &error)); + g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, "section", "a_boolean_false", TRUE, + &out, &error)); g_assert_false (out); - g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, - "section", - "a_not_existing_boolean", - TRUE, - &out, - &error)); + g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, "section", "a_not_existing_boolean", + TRUE, &out, &error)); g_assert_true (out); g_clear_error (&error); - g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, - "a_fake_section", - "a_boolean_true", - FALSE, - &out, - &error)); + g_assert (ot_keyfile_get_boolean_with_default (g_keyfile, "a_fake_section", "a_boolean_true", + FALSE, &out, &error)); } static void test_get_value_with_default (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; g_autofree char *out = NULL; GLogLevelFlags always_fatal_mask; const char *section = "section"; @@ -77,55 +61,31 @@ test_get_value_with_default (void) /* Avoid that g_return_val_if_fail causes the test to fail. */ always_fatal_mask = g_log_set_always_fatal (0); - g_assert_false (ot_keyfile_get_value_with_default (g_keyfile, - NULL, - "value_foo", - "none", - &out, - &error)); + g_assert_false ( + ot_keyfile_get_value_with_default (g_keyfile, NULL, "value_foo", "none", &out, &error)); g_clear_pointer (&out, g_free); - g_assert_false (ot_keyfile_get_value_with_default (g_keyfile, - section, - NULL, - "none", - &out, - &error)); + g_assert_false ( + ot_keyfile_get_value_with_default (g_keyfile, section, NULL, "none", &out, &error)); g_clear_pointer (&out, g_free); - g_assert_false (ot_keyfile_get_value_with_default (g_keyfile, - section, - NULL, - "something", - &out, - &error)); + g_assert_false ( + ot_keyfile_get_value_with_default (g_keyfile, section, NULL, "something", &out, &error)); g_clear_pointer (&out, g_free); /* Restore the old mask. */ g_log_set_always_fatal (always_fatal_mask); - g_assert (ot_keyfile_get_value_with_default (g_keyfile, - section, - "value_foo", - "none", - &out, - &error)); + g_assert ( + ot_keyfile_get_value_with_default (g_keyfile, section, "value_foo", "none", &out, &error)); g_assert_cmpstr (out, ==, "foo"); g_clear_pointer (&out, g_free); - g_assert (ot_keyfile_get_value_with_default (g_keyfile, - section, - "a_not_existing_value", - "correct", - &out, - &error)); + g_assert (ot_keyfile_get_value_with_default (g_keyfile, section, "a_not_existing_value", + "correct", &out, &error)); g_assert_cmpstr (out, ==, "correct"); g_clear_pointer (&out, g_free); - g_assert (ot_keyfile_get_value_with_default (g_keyfile, - "a_fake_section", - "a_value_true", - "no value", - &out, - &error)); + g_assert (ot_keyfile_get_value_with_default (g_keyfile, "a_fake_section", "a_value_true", + "no value", &out, &error)); g_assert_cmpstr (out, ==, "no value"); g_clear_pointer (&out, g_free); } @@ -133,63 +93,39 @@ test_get_value_with_default (void) static void test_get_value_with_default_group_optional (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; g_autofree char *out = NULL; GLogLevelFlags always_fatal_mask; const char *section = "section"; -/* Avoid that g_return_val_if_fail causes the test to fail. */ + /* Avoid that g_return_val_if_fail causes the test to fail. */ always_fatal_mask = g_log_set_always_fatal (0); - g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, - NULL, - "value_foo", - "none", - &out, - &error)); + g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, NULL, "value_foo", + "none", &out, &error)); g_clear_pointer (&out, g_free); - g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, - section, - NULL, - "none", - &out, - &error)); + g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, section, NULL, + "none", &out, &error)); g_clear_pointer (&out, g_free); - g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, - section, - NULL, - "something", - &out, - &error)); + g_assert_false (ot_keyfile_get_value_with_default_group_optional (g_keyfile, section, NULL, + "something", &out, &error)); g_clear_pointer (&out, g_free); /* Restore the old mask. */ g_log_set_always_fatal (always_fatal_mask); - g_assert (ot_keyfile_get_value_with_default_group_optional (g_keyfile, - section, - "value_foo", - "none", - &out, - &error)); + g_assert (ot_keyfile_get_value_with_default_group_optional (g_keyfile, section, "value_foo", + "none", &out, &error)); g_assert_cmpstr (out, ==, "foo"); g_clear_pointer (&out, g_free); - g_assert (ot_keyfile_get_value_with_default_group_optional (g_keyfile, - section, - "a_not_existing_value", - "correct", - &out, - &error)); + g_assert (ot_keyfile_get_value_with_default_group_optional ( + g_keyfile, section, "a_not_existing_value", "correct", &out, &error)); g_assert_cmpstr (out, ==, "correct"); g_clear_pointer (&out, g_free); - g_assert (ot_keyfile_get_value_with_default_group_optional (g_keyfile, - "an_optional_section", - "a_value_true", - "no value", - &out, - &error)); + g_assert (ot_keyfile_get_value_with_default_group_optional ( + g_keyfile, "an_optional_section", "a_value_true", "no value", &out, &error)); g_clear_error (&error); g_clear_pointer (&out, g_free); } @@ -204,7 +140,7 @@ test_copy_group (void) /* Avoid that g_return_val_if_fail causes the test to fail. */ always_fatal_mask = g_log_set_always_fatal (0); - g_autoptr(GKeyFile) tmp = g_key_file_new (); + g_autoptr (GKeyFile) tmp = g_key_file_new (); g_assert_false (ot_keyfile_copy_group (NULL, tmp, section)); g_assert_false (ot_keyfile_copy_group (g_keyfile, NULL, section)); @@ -215,9 +151,9 @@ test_copy_group (void) g_assert_true (ot_keyfile_copy_group (g_keyfile, tmp, section)); - g_auto(GStrv) keys = g_key_file_get_keys (g_keyfile, section, &length, NULL); + g_auto (GStrv) keys = g_key_file_get_keys (g_keyfile, section, &length, NULL); g_strfreev (g_key_file_get_keys (tmp, section, &length2, NULL)); - g_assert_cmpint(length, ==, length2); + g_assert_cmpint (length, ==, length2); for (gsize ii = 0; ii < length; ii++) { @@ -225,7 +161,6 @@ test_copy_group (void) g_autofree char *value2 = g_key_file_get_value (g_keyfile, section, keys[ii], NULL); g_assert_cmpstr (value, ==, value2); } - } static void @@ -238,7 +173,8 @@ fill_keyfile (GKeyFile *file) g_key_file_set_value (file, "section", "value_bar", "bar"); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { int ret; g_test_init (&argc, &argv, NULL); @@ -247,10 +183,11 @@ int main (int argc, char **argv) g_test_add_func ("/keyfile-utils/get-boolean-with-default", test_get_boolean_with_default); g_test_add_func ("/keyfile-utils/get-value-with-default", test_get_value_with_default); - g_test_add_func ("/keyfile-utils/get-value-with-default-group-optional", test_get_value_with_default_group_optional); + g_test_add_func ("/keyfile-utils/get-value-with-default-group-optional", + test_get_value_with_default_group_optional); g_test_add_func ("/keyfile-utils/copy-group", test_copy_group); - ret = g_test_run(); + ret = g_test_run (); g_key_file_free (g_keyfile); diff --git a/tests/test-libarchive-import.c b/tests/test-libarchive-import.c index 716aa30..86536fc 100644 --- a/tests/test-libarchive-import.c +++ b/tests/test-libarchive-import.c @@ -19,17 +19,18 @@ #include "config.h" #include "libglnx.h" +#include #include #include -#include #include -#include #include "ostree-libarchive-private.h" #include #include +#include -typedef struct { +typedef struct +{ OstreeRepo *repo; int fd; int fd_empty; @@ -41,7 +42,7 @@ static void test_data_init (TestData *td) { GError *error = NULL; - g_autoptr(OtAutoArchiveWrite) a = archive_write_new (); + g_autoptr (OtAutoArchiveWrite) a = archive_write_new (); struct archive_entry *ae; uid_t uid = getuid (); gid_t gid = getgid (); @@ -50,11 +51,11 @@ test_data_init (TestData *td) g_assert_cmpint (0, ==, chdir (td->tmpd)); td->fd = openat (AT_FDCWD, "foo.tar.gz", O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0644); - (void) unlink ("foo.tar.gz"); + (void)unlink ("foo.tar.gz"); g_assert_no_error (error); g_assert (td->fd >= 0); - + g_assert_cmpint (0, ==, archive_write_set_format_pax (a)); g_assert_cmpint (0, ==, archive_write_add_filter_gzip (a)); g_assert_cmpint (0, ==, archive_write_open_fd (a, td->fd)); @@ -122,7 +123,7 @@ test_data_init (TestData *td) td->fd_empty = openat (AT_FDCWD, "empty.tar.gz", O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0644); g_assert (td->fd_empty >= 0); - (void) unlink ("empty.tar.gz"); + (void)unlink ("empty.tar.gz"); g_assert_cmpint (ARCHIVE_OK, ==, archive_write_free (a)); a = archive_write_new (); @@ -133,7 +134,8 @@ test_data_init (TestData *td) g_assert_cmpint (0, ==, archive_write_open_fd (a, td->fd_empty)); g_assert_cmpint (ARCHIVE_OK, ==, archive_write_close (a)); - { g_autoptr(GFile) repopath = g_file_new_for_path ("repo"); + { + g_autoptr (GFile) repopath = g_file_new_for_path ("repo"); td->repo = ostree_repo_new (repopath); g_assert_cmpint (0, ==, mkdir ("repo", 0755)); @@ -172,10 +174,12 @@ test_archive_setup (int fd, struct archive *a) static void test_libarchive_noautocreate_empty (gconstpointer data) { - TestData *td = (void*)data; + TestData *td = (void *)data; GError *error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); - OstreeRepoImportArchiveOptions opts = { 0, }; + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); + OstreeRepoImportArchiveOptions opts = { + 0, + }; glnx_unref_object OstreeMutableTree *mtree = ostree_mutable_tree_new (); if (td->skip_all != NULL) @@ -194,10 +198,12 @@ test_libarchive_noautocreate_empty (gconstpointer data) static void test_libarchive_autocreate_empty (gconstpointer data) { - TestData *td = (void*)data; - g_autoptr(GError) error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); - OstreeRepoImportArchiveOptions opts = { 0, }; + TestData *td = (void *)data; + g_autoptr (GError) error = NULL; + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); + OstreeRepoImportArchiveOptions opts = { + 0, + }; glnx_unref_object OstreeMutableTree *mtree = ostree_mutable_tree_new (); if (td->skip_all != NULL) @@ -218,10 +224,12 @@ test_libarchive_autocreate_empty (gconstpointer data) static void test_libarchive_error_device_file (gconstpointer data) { - TestData *td = (void*)data; - g_autoptr(GError) error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); - OstreeRepoImportArchiveOptions opts = { 0, }; + TestData *td = (void *)data; + g_autoptr (GError) error = NULL; + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); + OstreeRepoImportArchiveOptions opts = { + 0, + }; glnx_unref_object OstreeMutableTree *mtree = ostree_mutable_tree_new (); if (td->skip_all != NULL) @@ -244,9 +252,8 @@ skip_if_no_xattr (TestData *td) if (setxattr (td->tmpd, "user.test-xattr-support", "yes", 4, 0) != 0) { int saved_errno = errno; - g_autofree gchar *message - = g_strdup_printf ("unable to setxattr on \"%s\": %s", - td->tmpd, g_strerror (saved_errno)); + g_autofree gchar *message = g_strdup_printf ("unable to setxattr on \"%s\": %s", td->tmpd, + g_strerror (saved_errno)); g_test_skip (message); return TRUE; } @@ -255,29 +262,23 @@ skip_if_no_xattr (TestData *td) } static gboolean -import_write_and_ref (OstreeRepo *repo, - OstreeRepoImportArchiveOptions *opts, - struct archive *a, - const char *ref, - OstreeRepoCommitModifier *modifier, - GError **error) +import_write_and_ref (OstreeRepo *repo, OstreeRepoImportArchiveOptions *opts, struct archive *a, + const char *ref, OstreeRepoCommitModifier *modifier, GError **error) { - g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new (); + g_autoptr (OstreeMutableTree) mtree = ostree_mutable_tree_new (); if (!ostree_repo_prepare_transaction (repo, NULL, NULL, error)) return FALSE; - if (!ostree_repo_import_archive_to_mtree (repo, opts, a, mtree, modifier, - NULL, error)) + if (!ostree_repo_import_archive_to_mtree (repo, opts, a, mtree, modifier, NULL, error)) return FALSE; - g_autoptr(GFile) root = NULL; + g_autoptr (GFile) root = NULL; if (!ostree_repo_write_mtree (repo, mtree, &root, NULL, error)) return FALSE; g_autofree char *commit_checksum = NULL; - if (!ostree_repo_write_commit (repo, NULL, "", "", NULL, - OSTREE_REPO_FILE (root), + if (!ostree_repo_write_commit (repo, NULL, "", "", NULL, OSTREE_REPO_FILE (root), &commit_checksum, NULL, error)) return FALSE; @@ -292,10 +293,12 @@ import_write_and_ref (OstreeRepo *repo, static void test_libarchive_ignore_device_file (gconstpointer data) { - TestData *td = (void*)data; - g_autoptr(GError) error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); - OstreeRepoImportArchiveOptions opts = { 0, }; + TestData *td = (void *)data; + g_autoptr (GError) error = NULL; + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); + OstreeRepoImportArchiveOptions opts = { + 0, + }; if (skip_if_no_xattr (td)) goto out; @@ -328,7 +331,7 @@ test_libarchive_ignore_device_file (gconstpointer data) g_assert (error != NULL); g_clear_error (&error); - out: +out: g_assert_no_error (error); } @@ -360,10 +363,12 @@ check_ostree_convention (GError *error) static void test_libarchive_ostree_convention (gconstpointer data) { - TestData *td = (void*)data; + TestData *td = (void *)data; GError *error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); - OstreeRepoImportArchiveOptions opts = { 0, }; + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); + OstreeRepoImportArchiveOptions opts = { + 0, + }; if (skip_if_no_xattr (td)) goto out; @@ -386,21 +391,17 @@ test_libarchive_ostree_convention (gconstpointer data) if (!check_ostree_convention (error)) goto out; - out: +out: g_assert_no_error (error); } -static GVariant* -xattr_cb (OstreeRepo *repo, - const char *path, - GFileInfo *file_info, - gpointer user_data) +static GVariant * +xattr_cb (OstreeRepo *repo, const char *path, GFileInfo *file_info, gpointer user_data) { - g_auto(GVariantBuilder) builder; - g_variant_builder_init (&builder, (GVariantType*)"a(ayay)"); + g_auto (GVariantBuilder) builder; + g_variant_builder_init (&builder, (GVariantType *)"a(ayay)"); if (strcmp (path, "/anotherfile") == 0) - g_variant_builder_add (&builder, "(@ay@ay)", - g_variant_new_bytestring ("user.data"), + g_variant_builder_add (&builder, "(@ay@ay)", g_variant_new_bytestring ("user.data"), g_variant_new_bytestring ("mydata")); return g_variant_ref_sink (g_variant_builder_end (&builder)); } @@ -408,11 +409,11 @@ xattr_cb (OstreeRepo *repo, static void test_libarchive_xattr_callback (gconstpointer data) { - TestData *td = (void*)data; + TestData *td = (void *)data; GError *error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0 }; - g_autoptr(OstreeRepoCommitModifier) modifier = NULL; + g_autoptr (OstreeRepoCommitModifier) modifier = NULL; char buf[7] = { 0 }; if (skip_if_no_xattr (td)) @@ -425,8 +426,7 @@ test_libarchive_xattr_callback (gconstpointer data) } modifier = ostree_repo_commit_modifier_new (0, NULL, NULL, NULL); - ostree_repo_commit_modifier_set_xattr_callback (modifier, xattr_cb, - NULL, NULL); + ostree_repo_commit_modifier_set_xattr_callback (modifier, xattr_cb, NULL, NULL); test_archive_setup (td->fd, a); @@ -450,16 +450,16 @@ test_libarchive_xattr_callback (gconstpointer data) g_assert_cmpstr (buf, ==, "mydata"); - out: +out: g_assert_no_error (error); } static void test_libarchive_xattr_import (gconstpointer data) { - TestData *td = (void*)data; + TestData *td = (void *)data; GError *error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0 }; char buf[15] = { 0 }; @@ -495,20 +495,20 @@ test_libarchive_xattr_import (gconstpointer data) x = getxattr ("import-checkout/anotherfile", "user.b_key", buf, sizeof buf - 1); g_assert_cmpint (x, ==, 14); - g_assert (memcmp(buf, "contains\0nuls", 14) == 0); + g_assert (memcmp (buf, "contains\0nuls", 14) == 0); - out: +out: g_assert_no_error (error); } static void test_libarchive_xattr_import_skip_xattr (gconstpointer data) { - TestData *td = (void*)data; + TestData *td = (void *)data; GError *error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0 }; - g_autoptr(OstreeRepoCommitModifier) modifier = NULL; + g_autoptr (OstreeRepoCommitModifier) modifier = NULL; if (skip_if_no_xattr (td)) goto out; @@ -523,8 +523,8 @@ test_libarchive_xattr_import_skip_xattr (gconstpointer data) opts.ignore_unsupported_content = TRUE; - modifier = ostree_repo_commit_modifier_new ( - OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS, NULL, NULL, NULL); + modifier = ostree_repo_commit_modifier_new (OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS, NULL, + NULL, NULL); if (!import_write_and_ref (td->repo, &opts, a, "baz", modifier, &error)) goto out; @@ -535,27 +535,27 @@ test_libarchive_xattr_import_skip_xattr (gconstpointer data) ssize_t n_attrs = listxattr ("import-checkout/anotherfile", NULL, 0); g_assert_cmpint (n_attrs, ==, 0); - out: +out: g_assert_no_error (error); } -static GVariant* -path_cb (OstreeRepo *repo, - const char *path, - GFileInfo *file_info, - gpointer user_data) +static GVariant * +path_cb (OstreeRepo *repo, const char *path, GFileInfo *file_info, gpointer user_data) { if (strcmp (path, "/etc/file") == 0) - *(gboolean*)user_data = TRUE; + *(gboolean *)user_data = TRUE; return NULL; } static void entry_pathname_test_helper (gconstpointer data, gboolean on) { - TestData *td = (void*)data; GError *error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); - OstreeRepoImportArchiveOptions opts = { 0, }; + TestData *td = (void *)data; + GError *error = NULL; + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); + OstreeRepoImportArchiveOptions opts = { + 0, + }; OstreeRepoCommitModifier *modifier = NULL; gboolean met_etc_file = FALSE; @@ -569,8 +569,7 @@ entry_pathname_test_helper (gconstpointer data, gboolean on) } modifier = ostree_repo_commit_modifier_new (0, NULL, NULL, NULL); - ostree_repo_commit_modifier_set_xattr_callback (modifier, path_cb, - NULL, &met_etc_file); + ostree_repo_commit_modifier_set_xattr_callback (modifier, path_cb, NULL, &met_etc_file); test_archive_setup (td->fd, a); @@ -601,7 +600,7 @@ entry_pathname_test_helper (gconstpointer data, gboolean on) } ostree_repo_commit_modifier_unref (modifier); - out: +out: g_assert_no_error (error); } @@ -620,12 +619,12 @@ test_libarchive_use_entry_pathname (gconstpointer data) static void test_libarchive_selinux (gconstpointer data) { - TestData *td = (void*)data; + TestData *td = (void *)data; GError *error = NULL; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); + g_autoptr (OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0 }; glnx_unref_object OstreeSePolicy *sepol = NULL; - g_autoptr(OstreeRepoCommitModifier) modifier = NULL; + g_autoptr (OstreeRepoCommitModifier) modifier = NULL; char buf[64] = { 0 }; if (skip_if_no_xattr (td)) @@ -678,13 +677,16 @@ test_libarchive_selinux (gconstpointer data) buf[(sizeof buf) - 1] = '\0'; g_assert_cmpstr (buf, ==, "system_u:object_r:etc_t:s0"); - out: +out: g_assert_no_error (error); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { - TestData td = {NULL,}; + TestData td = { + NULL, + }; int r; test_data_init (&td); @@ -697,17 +699,19 @@ int main (int argc, char **argv) g_test_add_data_func ("/libarchive/ignore-device-file", &td, test_libarchive_ignore_device_file); g_test_add_data_func ("/libarchive/ostree-convention", &td, test_libarchive_ostree_convention); g_test_add_data_func ("/libarchive/xattr-import", &td, test_libarchive_xattr_import); - g_test_add_data_func ("/libarchive/xattr-import-skip-xattr", &td, test_libarchive_xattr_import_skip_xattr); + g_test_add_data_func ("/libarchive/xattr-import-skip-xattr", &td, + test_libarchive_xattr_import_skip_xattr); g_test_add_data_func ("/libarchive/xattr-callback", &td, test_libarchive_xattr_callback); - g_test_add_data_func ("/libarchive/no-use-entry-pathname", &td, test_libarchive_no_use_entry_pathname); + g_test_add_data_func ("/libarchive/no-use-entry-pathname", &td, + test_libarchive_no_use_entry_pathname); g_test_add_data_func ("/libarchive/use-entry-pathname", &td, test_libarchive_use_entry_pathname); g_test_add_data_func ("/libarchive/selinux", &td, test_libarchive_selinux); - r = g_test_run(); + r = g_test_run (); g_clear_object (&td.repo); if (td.tmpd && g_getenv ("TEST_SKIP_CLEANUP") == NULL) - (void) glnx_shutil_rm_rf_at (AT_FDCWD, td.tmpd, NULL, NULL); + (void)glnx_shutil_rm_rf_at (AT_FDCWD, td.tmpd, NULL, NULL); g_free (td.tmpd); return r; } diff --git a/tests/test-lzma.c b/tests/test-lzma.c index c26bc8d..5c1ce9d 100644 --- a/tests/test-lzma.c +++ b/tests/test-lzma.c @@ -19,32 +19,33 @@ #include "config.h" #include "libglnx.h" -#include -#include -#include -#include #include "ostree-lzma-compressor.h" #include "ostree-lzma-decompressor.h" -#include +#include #include +#include +#include +#include +#include static void helper_test_compress_decompress (const guint8 *data, gssize data_size) { - g_autoptr(GError) error = NULL; - g_autoptr(GOutputStream) out_compress = g_memory_output_stream_new_resizable (); - g_autoptr(GOutputStream) out_decompress = NULL; - g_autoptr(GInputStream) in_compress = g_memory_input_stream_new_from_data (data, data_size, NULL); - g_autoptr(GInputStream) in_decompress = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GOutputStream) out_compress = g_memory_output_stream_new_resizable (); + g_autoptr (GOutputStream) out_decompress = NULL; + g_autoptr (GInputStream) in_compress + = g_memory_input_stream_new_from_data (data, data_size, NULL); + g_autoptr (GInputStream) in_decompress = NULL; { gssize n_bytes_written; - g_autoptr(GInputStream) convin = NULL; - g_autoptr(GConverter) compressor = (GConverter*)_ostree_lzma_compressor_new (NULL); - convin = g_converter_input_stream_new ((GInputStream*) in_compress, compressor); - n_bytes_written = g_output_stream_splice (out_compress, convin, - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - NULL, &error); + g_autoptr (GInputStream) convin = NULL; + g_autoptr (GConverter) compressor = (GConverter *)_ostree_lzma_compressor_new (NULL); + convin = g_converter_input_stream_new ((GInputStream *)in_compress, compressor); + n_bytes_written = g_output_stream_splice ( + out_compress, convin, + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, NULL, &error); g_assert_cmpint (n_bytes_written, >, 0); g_assert_no_error (error); } @@ -53,25 +54,26 @@ helper_test_compress_decompress (const guint8 *data, gssize data_size) { gssize n_bytes_written; - g_autoptr(GInputStream) convin = NULL; - g_autoptr(GConverter) decompressor = (GConverter*)_ostree_lzma_decompressor_new (); - g_autoptr(GBytes) bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out_compress)); + g_autoptr (GInputStream) convin = NULL; + g_autoptr (GConverter) decompressor = (GConverter *)_ostree_lzma_decompressor_new (); + g_autoptr (GBytes) bytes + = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out_compress)); in_decompress = g_memory_input_stream_new_from_bytes (bytes); - convin = g_converter_input_stream_new ((GInputStream*) in_decompress, decompressor); - n_bytes_written = g_output_stream_splice (out_decompress, convin, - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - NULL, &error); + convin = g_converter_input_stream_new ((GInputStream *)in_decompress, decompressor); + n_bytes_written = g_output_stream_splice ( + out_decompress, convin, + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, NULL, &error); g_assert_cmpint (n_bytes_written, >, 0); g_assert_no_error (error); } - g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (out_decompress)), ==, data_size); + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (out_decompress)), + ==, data_size); { gpointer new_data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (out_decompress)); g_assert_cmpint (memcmp (new_data, data, data_size), ==, 0); } - } static void @@ -79,11 +81,11 @@ test_lzma_random (void) { gssize i; guint8 buffer[4096]; - g_autoptr(GRand) r = g_rand_new (); - for (i = 0; i < sizeof(buffer); i++) + g_autoptr (GRand) r = g_rand_new (); + for (i = 0; i < sizeof (buffer); i++) buffer[i] = g_rand_int (r); - for (i = 2; i < (sizeof(buffer) - 1); i *= 2) + for (i = 2; i < (sizeof (buffer) - 1); i *= 2) { helper_test_compress_decompress (buffer, i - 1); helper_test_compress_decompress (buffer, i); @@ -97,16 +99,17 @@ test_lzma_big_buffer (void) const guint32 buffer_size = 1 << 21; g_autofree guint8 *buffer = g_new (guint8, buffer_size); - memset (buffer, (int) 'a', buffer_size); + memset (buffer, (int)'a', buffer_size); helper_test_compress_decompress (buffer, buffer_size); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/lzma/random-buffer", test_lzma_random); g_test_add_func ("/lzma/big-buffer", test_lzma_big_buffer); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-mock-gio.c b/tests/test-mock-gio.c index 719dc6c..94682f2 100644 --- a/tests/test-mock-gio.c +++ b/tests/test-mock-gio.c @@ -24,8 +24,8 @@ #include "config.h" #include -#include #include +#include #include #include "test-mock-gio.h" @@ -60,7 +60,7 @@ struct _OstreeMockVolumeMonitor GVolumeMonitor parent_instance; GList *mounts; /* (element-type OstreeMockMount) */ - GList *volumes; /* (element-type OstreeMockVolume) */ + GList *volumes; /* (element-type OstreeMockVolume) */ }; G_DEFINE_TYPE (OstreeMockVolumeMonitor, ostree_mock_volume_monitor, G_TYPE_VOLUME_MONITOR) @@ -69,14 +69,14 @@ static GList * ostree_mock_volume_monitor_get_mounts (GVolumeMonitor *monitor) { OstreeMockVolumeMonitor *self = OSTREE_MOCK_VOLUME_MONITOR (monitor); - return g_list_copy_deep (self->mounts, (GCopyFunc) g_object_ref, NULL); + return g_list_copy_deep (self->mounts, (GCopyFunc)g_object_ref, NULL); } static GList * ostree_mock_volume_monitor_get_volumes (GVolumeMonitor *monitor) { OstreeMockVolumeMonitor *self = OSTREE_MOCK_VOLUME_MONITOR (monitor); - return g_list_copy_deep (self->volumes, (GCopyFunc) g_object_ref, NULL); + return g_list_copy_deep (self->volumes, (GCopyFunc)g_object_ref, NULL); } static void @@ -128,14 +128,13 @@ ostree_mock_volume_monitor_class_init (OstreeMockVolumeMonitorClass *klass) * Since: 2017.8 */ GVolumeMonitor * -ostree_mock_volume_monitor_new (GList *mounts, - GList *volumes) +ostree_mock_volume_monitor_new (GList *mounts, GList *volumes) { - g_autoptr(OstreeMockVolumeMonitor) monitor = NULL; + g_autoptr (OstreeMockVolumeMonitor) monitor = NULL; monitor = g_object_new (OSTREE_TYPE_MOCK_VOLUME_MONITOR, NULL); - monitor->mounts = g_list_copy_deep (mounts, (GCopyFunc) g_object_ref, NULL); - monitor->volumes = g_list_copy_deep (volumes, (GCopyFunc) g_object_ref, NULL); + monitor->mounts = g_list_copy_deep (mounts, (GCopyFunc)g_object_ref, NULL); + monitor->volumes = g_list_copy_deep (volumes, (GCopyFunc)g_object_ref, NULL); return (GVolumeMonitor *)g_steal_pointer (&monitor); } @@ -147,8 +146,8 @@ struct _OstreeMockVolume GObject parent_instance; gchar *name; - GDrive *drive; /* (owned) (nullable) */ - GMount *mount; /* (owned) (nullable) */ + GDrive *drive; /* (owned) (nullable) */ + GMount *mount; /* (owned) (nullable) */ }; static void ostree_mock_volume_iface_init (GVolumeIface *iface); @@ -231,11 +230,9 @@ ostree_mock_volume_iface_init (GVolumeIface *iface) * Since: 2017.8 */ OstreeMockVolume * -ostree_mock_volume_new (const gchar *name, - GDrive *drive, - GMount *mount) +ostree_mock_volume_new (const gchar *name, GDrive *drive, GMount *mount) { - g_autoptr(OstreeMockVolume) volume = NULL; + g_autoptr (OstreeMockVolume) volume = NULL; volume = g_object_new (OSTREE_TYPE_MOCK_VOLUME, NULL); volume->name = g_strdup (name); @@ -302,7 +299,7 @@ ostree_mock_drive_iface_init (GDriveIface *iface) OstreeMockDrive * ostree_mock_drive_new (gboolean is_removable) { - g_autoptr(OstreeMockDrive) drive = NULL; + g_autoptr (OstreeMockDrive) drive = NULL; drive = g_object_new (OSTREE_TYPE_MOCK_DRIVE, NULL); drive->is_removable = is_removable; @@ -316,8 +313,8 @@ struct _OstreeMockMount { GObject parent_instance; - gchar *name; /* (owned) */ - GFile *root; /* (owned) */ + gchar *name; /* (owned) */ + GFile *root; /* (owned) */ }; static void ostree_mock_mount_iface_init (GMountIface *iface); @@ -387,10 +384,9 @@ ostree_mock_mount_iface_init (GMountIface *iface) * Since: 2017.8 */ OstreeMockMount * -ostree_mock_mount_new (const gchar *name, - GFile *root) +ostree_mock_mount_new (const gchar *name, GFile *root) { - g_autoptr(OstreeMockMount) mount = NULL; + g_autoptr (OstreeMockMount) mount = NULL; mount = g_object_new (OSTREE_TYPE_MOCK_MOUNT, NULL); mount->name = g_strdup (name); diff --git a/tests/test-mock-gio.h b/tests/test-mock-gio.h index 2cc38f1..fae260a 100644 --- a/tests/test-mock-gio.h +++ b/tests/test-mock-gio.h @@ -23,8 +23,8 @@ #pragma once #include -#include #include +#include #include #include "ostree-types.h" @@ -35,24 +35,36 @@ G_BEGIN_DECLS /* Manually expanded version of the following, omitting autoptr support (for GLib < 2.44): G_GNUC_INTERNAL -G_DECLARE_FINAL_TYPE (OstreeMockVolumeMonitor, ostree_mock_volume_monitor, OSTREE, MOCK_VOLUME_MONITOR, GVolumeMonitor) */ +G_DECLARE_FINAL_TYPE (OstreeMockVolumeMonitor, ostree_mock_volume_monitor, OSTREE, +MOCK_VOLUME_MONITOR, GVolumeMonitor) */ G_GNUC_INTERNAL GType ostree_mock_volume_monitor_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeMockVolumeMonitor OstreeMockVolumeMonitor; -typedef struct { GVolumeMonitorClass parent_class; } OstreeMockVolumeMonitorClass; - -static inline OstreeMockVolumeMonitor *OSTREE_MOCK_VOLUME_MONITOR (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_volume_monitor_get_type (), OstreeMockVolumeMonitor); } -static inline gboolean OSTREE_IS_MOCK_VOLUME_MONITOR (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_volume_monitor_get_type ()); } +typedef struct +{ + GVolumeMonitorClass parent_class; +} OstreeMockVolumeMonitorClass; + +static inline OstreeMockVolumeMonitor * +OSTREE_MOCK_VOLUME_MONITOR (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_volume_monitor_get_type (), + OstreeMockVolumeMonitor); +} +static inline gboolean +OSTREE_IS_MOCK_VOLUME_MONITOR (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_volume_monitor_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMockVolumeMonitor, g_object_unref) G_GNUC_INTERNAL -GVolumeMonitor *ostree_mock_volume_monitor_new (GList *mounts, - GList *volumes); +GVolumeMonitor *ostree_mock_volume_monitor_new (GList *mounts, GList *volumes); #define OSTREE_TYPE_MOCK_VOLUME (ostree_mock_volume_get_type ()) @@ -65,18 +77,27 @@ GType ostree_mock_volume_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeMockVolume OstreeMockVolume; -typedef struct { GObjectClass parent_class; } OstreeMockVolumeClass; - -static inline OstreeMockVolume *OSTREE_MOCK_VOLUME (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_volume_get_type (), OstreeMockVolume); } -static inline gboolean OSTREE_IS_MOCK_VOLUME (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_volume_get_type ()); } +typedef struct +{ + GObjectClass parent_class; +} OstreeMockVolumeClass; + +static inline OstreeMockVolume * +OSTREE_MOCK_VOLUME (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_volume_get_type (), OstreeMockVolume); +} +static inline gboolean +OSTREE_IS_MOCK_VOLUME (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_volume_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMockVolume, g_object_unref) G_GNUC_INTERNAL -OstreeMockVolume *ostree_mock_volume_new (const gchar *name, - GDrive *drive, - GMount *mount); +OstreeMockVolume *ostree_mock_volume_new (const gchar *name, GDrive *drive, GMount *mount); #define OSTREE_TYPE_MOCK_DRIVE (ostree_mock_drive_get_type ()) @@ -89,10 +110,21 @@ GType ostree_mock_drive_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeMockDrive OstreeMockDrive; -typedef struct { GObjectClass parent_class; } OstreeMockDriveClass; - -static inline OstreeMockDrive *OSTREE_MOCK_DRIVE (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_drive_get_type (), OstreeMockDrive); } -static inline gboolean OSTREE_IS_MOCK_DRIVE (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_drive_get_type ()); } +typedef struct +{ + GObjectClass parent_class; +} OstreeMockDriveClass; + +static inline OstreeMockDrive * +OSTREE_MOCK_DRIVE (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_drive_get_type (), OstreeMockDrive); +} +static inline gboolean +OSTREE_IS_MOCK_DRIVE (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_drive_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMockDrive, g_object_unref) @@ -111,16 +143,26 @@ GType ostree_mock_mount_get_type (void); G_GNUC_BEGIN_IGNORE_DEPRECATIONS typedef struct _OstreeMockMount OstreeMockMount; -typedef struct { GObjectClass parent_class; } OstreeMockMountClass; - -static inline OstreeMockMount *OSTREE_MOCK_MOUNT (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_mount_get_type (), OstreeMockMount); } -static inline gboolean OSTREE_IS_MOCK_MOUNT (gpointer ptr) { return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_mount_get_type ()); } +typedef struct +{ + GObjectClass parent_class; +} OstreeMockMountClass; + +static inline OstreeMockMount * +OSTREE_MOCK_MOUNT (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, ostree_mock_mount_get_type (), OstreeMockMount); +} +static inline gboolean +OSTREE_IS_MOCK_MOUNT (gpointer ptr) +{ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, ostree_mock_mount_get_type ()); +} G_GNUC_END_IGNORE_DEPRECATIONS G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMockMount, g_object_unref) G_GNUC_INTERNAL -OstreeMockMount *ostree_mock_mount_new (const gchar *name, - GFile *root); +OstreeMockMount *ostree_mock_mount_new (const gchar *name, GFile *root); G_END_DECLS diff --git a/tests/test-mutable-tree.c b/tests/test-mutable-tree.c index e5a6b04..4ef3593 100644 --- a/tests/test-mutable-tree.c +++ b/tests/test-mutable-tree.c @@ -20,16 +20,16 @@ #include "config.h" #include "libglnx.h" #include "ostree-mutable-tree.h" +#include "ot-unix-utils.h" +#include #include #include -#include #include -#include "ot-unix-utils.h" static void test_metadata_checksum (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; const char *checksum = "12345678901234567890123456789012"; glnx_unref_object OstreeMutableTree *tree = ostree_mutable_tree_new (); @@ -45,20 +45,16 @@ test_metadata_checksum (void) g_assert (ostree_mutable_tree_ensure_dir (tree, "subdir", &subdir, &error)); g_assert_nonnull (subdir); - ostree_mutable_tree_set_contents_checksum ( - subdir, "11111111111111111111111111111111"); - ostree_mutable_tree_set_metadata_checksum ( - subdir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - ostree_mutable_tree_set_contents_checksum ( - tree, "abcdefabcdefabcdefabcdefabcdefab"); + ostree_mutable_tree_set_contents_checksum (subdir, "11111111111111111111111111111111"); + ostree_mutable_tree_set_metadata_checksum (subdir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + ostree_mutable_tree_set_contents_checksum (tree, "abcdefabcdefabcdefabcdefabcdefab"); g_assert_cmpstr (ostree_mutable_tree_get_contents_checksum (tree), ==, - "abcdefabcdefabcdefabcdefabcdefab"); - ostree_mutable_tree_set_metadata_checksum ( - subdir, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); + "abcdefabcdefabcdefabcdefabcdefab"); + ostree_mutable_tree_set_metadata_checksum (subdir, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); g_assert_null (ostree_mutable_tree_get_contents_checksum (tree)); g_assert_cmpstr (ostree_mutable_tree_get_contents_checksum (subdir), ==, - "11111111111111111111111111111111"); + "11111111111111111111111111111111"); } static void @@ -66,16 +62,14 @@ test_mutable_tree_walk (void) { glnx_unref_object OstreeMutableTree *tree = ostree_mutable_tree_new (); glnx_unref_object OstreeMutableTree *parent = NULL; - g_autoptr(GPtrArray) split_path = NULL; + g_autoptr (GPtrArray) split_path = NULL; GError *error = NULL; const char *pathname = "a/b/c/d/e/f/g/i"; const char *checksum = "01234567890123456789012345678901"; g_assert (ot_util_path_split_validate (pathname, &split_path, &error)); - g_assert (ostree_mutable_tree_ensure_parent_dirs (tree, split_path, - checksum, &parent, - &error)); + g_assert (ostree_mutable_tree_ensure_parent_dirs (tree, split_path, checksum, &parent, &error)); { glnx_unref_object OstreeMutableTree *subdir = NULL; g_assert (ostree_mutable_tree_walk (tree, split_path, 0, &subdir, &error)); @@ -106,8 +100,8 @@ test_ensure_parent_dirs (void) { glnx_unref_object OstreeMutableTree *tree = ostree_mutable_tree_new (); glnx_unref_object OstreeMutableTree *parent = NULL; - g_autoptr(GPtrArray) split_path = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GPtrArray) split_path = NULL; + g_autoptr (GError) error = NULL; const char *pathname = "/foo/bar/baz"; const char *checksum = "01234567890123456789012345678901"; g_autofree char *source_checksum = NULL; @@ -117,15 +111,12 @@ test_ensure_parent_dirs (void) g_assert (ot_util_path_split_validate (pathname, &split_path, &error)); - g_assert (ostree_mutable_tree_ensure_parent_dirs (tree, split_path, - checksum, &parent, - &error)); + g_assert (ostree_mutable_tree_ensure_parent_dirs (tree, split_path, checksum, &parent, &error)); - g_assert (ostree_mutable_tree_lookup (tree, "foo", &source_checksum, - &source_subdir, &error)); + g_assert (ostree_mutable_tree_lookup (tree, "foo", &source_checksum, &source_subdir, &error)); - g_assert_false (ostree_mutable_tree_lookup (tree, "bar", &source_checksum2, - &source_subdir2, &error)); + g_assert_false ( + ostree_mutable_tree_lookup (tree, "bar", &source_checksum2, &source_subdir2, &error)); g_clear_error (&error); } @@ -134,7 +125,7 @@ test_ensure_dir (void) { glnx_unref_object OstreeMutableTree *tree = ostree_mutable_tree_new (); glnx_unref_object OstreeMutableTree *parent = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; const char *dirname = "foo"; const char *filename = "bar"; const char *checksum = "01234567890123456789012345678901"; @@ -153,7 +144,7 @@ static void test_replace_file (void) { glnx_unref_object OstreeMutableTree *tree = ostree_mutable_tree_new (); - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; const char *filename = "bar"; const char *checksum = "01234567890123456789012345678901"; const char *checksum2 = "ABCDEF01234567890123456789012345"; @@ -195,7 +186,8 @@ test_contents_checksum (void) g_assert_null (ostree_mutable_tree_get_contents_checksum (tree)); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/mutable-tree/metadata-checksum", test_metadata_checksum); @@ -204,5 +196,5 @@ int main (int argc, char **argv) g_test_add_func ("/mutable-tree/walk", test_mutable_tree_walk); g_test_add_func ("/mutable-tree/ensure-dir", test_ensure_dir); g_test_add_func ("/mutable-tree/replace-file", test_replace_file); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-ot-opt-utils.c b/tests/test-ot-opt-utils.c index 45de154..3a700f4 100644 --- a/tests/test-ot-opt-utils.c +++ b/tests/test-ot-opt-utils.c @@ -18,13 +18,13 @@ */ #include "config.h" +#include "libglnx.h" #include "ostree-mutable-tree.h" +#include "ot-opt-utils.h" +#include #include #include -#include #include -#include "ot-opt-utils.h" -#include "libglnx.h" static GString *printerr_str = NULL; @@ -39,8 +39,8 @@ util_usage_error_printerr (const gchar *string) static void test_ot_util_usage_error (void) { - g_autoptr(GError) error = NULL; - g_autoptr(GOptionContext) context = g_option_context_new ("[TEST]"); + g_autoptr (GError) error = NULL; + g_autoptr (GOptionContext) context = g_option_context_new ("[TEST]"); GPrintFunc old_printerr = g_set_printerr_handler (util_usage_error_printerr); ot_util_usage_error (context, "find_me", &error); @@ -54,9 +54,10 @@ test_ot_util_usage_error (void) printerr_str = NULL; } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/ot-opt-utils/ot-util-usage-error", test_ot_util_usage_error); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-ot-tool-util.c b/tests/test-ot-tool-util.c index 6eb3520..f189b3c 100644 --- a/tests/test-ot-tool-util.c +++ b/tests/test-ot-tool-util.c @@ -20,11 +20,11 @@ #include "config.h" #include "libglnx.h" #include "ostree-mutable-tree.h" +#include "ot-tool-util.h" +#include #include #include -#include #include -#include "ot-tool-util.h" /* @@ -42,7 +42,7 @@ ot_parse_keyvalue (const char *keyvalue, static void test_ot_parse_boolean (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; gboolean out = FALSE; g_assert_true (ot_parse_boolean ("yes", &out, &error)); g_assert_true (out); @@ -79,20 +79,17 @@ test_ot_parse_boolean (void) static void test_ot_parse_keyvalue (void) { - g_autoptr(GError) error = NULL; - char *keyvalue[] = {"foo=bar", "a=", "b=1231231"}; - char *key[] = {"foo", "a", "b"}; - char *value[] = {"bar", "", "1231231"}; + g_autoptr (GError) error = NULL; + char *keyvalue[] = { "foo=bar", "a=", "b=1231231" }; + char *key[] = { "foo", "a", "b" }; + char *value[] = { "bar", "", "1231231" }; guint i; for (i = 0; i < G_N_ELEMENTS (keyvalue); i++) { g_autofree char *out_key = NULL; g_autofree char *out_value = NULL; - g_assert_true (ot_parse_keyvalue (keyvalue[i], - &out_key, - &out_value, - &error)); + g_assert_true (ot_parse_keyvalue (keyvalue[i], &out_key, &out_value, &error)); g_assert_cmpstr (out_key, ==, key[i]); g_assert_cmpstr (out_value, ==, value[i]); } @@ -100,19 +97,17 @@ test_ot_parse_keyvalue (void) { g_autofree char *out_key = NULL; g_autofree char *out_value = NULL; - g_assert_false (ot_parse_keyvalue ("blabla", - &out_key, - &out_value, - &error)); + g_assert_false (ot_parse_keyvalue ("blabla", &out_key, &out_value, &error)); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); g_clear_error (&error); } } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/ot-tool-util/parse-boolean", test_ot_parse_boolean); g_test_add_func ("/ot-tool-util/parse-keyvalue", test_ot_parse_keyvalue); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-ot-unix-utils.c b/tests/test-ot-unix-utils.c index 3f16b55..853e877 100644 --- a/tests/test-ot-unix-utils.c +++ b/tests/test-ot-unix-utils.c @@ -26,14 +26,14 @@ static void test_ot_util_path_split_validate (void) { - const char *paths[] = {"foo/bar", "test", "foo/bar:", "a/b/c/d/e/f/g/h/i/l/m/n/o/p", NULL}; - int n_components[] = {2, 1, 2, 14, 0}; + const char *paths[] = { "foo/bar", "test", "foo/bar:", "a/b/c/d/e/f/g/h/i/l/m/n/o/p", NULL }; + int n_components[] = { 2, 1, 2, 14, 0 }; int i; for (i = 0; paths[i]; i++) { GError *error = NULL; - g_autoptr(GPtrArray) components = NULL; - if (! ot_util_path_split_validate (paths[i], &components, &error)) + g_autoptr (GPtrArray) components = NULL; + if (!ot_util_path_split_validate (paths[i], &components, &error)) { int j; g_assert_cmpint (components->len, ==, n_components[i]); @@ -49,7 +49,7 @@ test_ot_util_path_split_validate (void) static void test_ot_util_filename_validate (void) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; /* Check for valid inputs. */ g_assert (ot_util_filename_validate ("valid", &error)); @@ -74,10 +74,11 @@ test_ot_util_filename_validate (void) g_clear_error (&error); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/ot_util_path_split_validate", test_ot_util_path_split_validate); g_test_add_func ("/ot_util_filename_validate", test_ot_util_filename_validate); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-otcore.c b/tests/test-otcore.c new file mode 100644 index 0000000..4af575b --- /dev/null +++ b/tests/test-otcore.c @@ -0,0 +1,141 @@ +/* + * SPDX-License-Identifier: LGPL-2.0+ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "otcore.h" + +static void +test_ed25519 (void) +{ + g_autoptr (GBytes) empty = g_bytes_new_static ("", 0); + bool valid = false; + g_autoptr (GError) error = NULL; + if (otcore_validate_ed25519_signature (empty, empty, empty, &valid, &error)) + g_assert_not_reached (); + g_assert (error != NULL); + g_clear_error (&error); +} + +static void +test_prepare_root_cmdline (void) +{ + g_autoptr (GError) error = NULL; + g_autofree char *target = NULL; + + static const char *notfound_cases[] + = { "", "foo", "foo=bar baz sometest", "xostree foo", "xostree=blah bar", NULL }; + for (const char **iter = notfound_cases; iter && *iter; iter++) + { + const char *tcase = *iter; + g_assert (otcore_get_ostree_target (tcase, &target, &error)); + g_assert_no_error (error); + g_assert (target == NULL); + } + + // Test the default ostree= + g_assert (otcore_get_ostree_target ("blah baz=blah ostree=/foo/bar somearg", &target, &error)); + g_assert_no_error (error); + g_assert_cmpstr (target, ==, "/foo/bar"); + free (g_steal_pointer (&target)); + + // Test android boot + g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_b somearg", &target, + &error)); + g_assert_no_error (error); + g_assert_cmpstr (target, ==, "/ostree/root.b"); + free (g_steal_pointer (&target)); + + g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_a somearg", &target, + &error)); + g_assert_no_error (error); + g_assert_cmpstr (target, ==, "/ostree/root.a"); + free (g_steal_pointer (&target)); + + // And an expected failure to parse a "c" suffix + g_assert (!otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_c somearg", &target, + &error)); + g_assert (error); + g_assert (target == NULL); + g_clear_error (&error); + + // And non-A/B androidboot + g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.somethingelse somearg", &target, + &error)); + g_assert_no_error (error); + g_assert_cmpstr (target, ==, "/ostree/root.a"); + free (g_steal_pointer (&target)); +} + +static void +test_prepare_root_config (void) +{ + g_autoptr (GError) error = NULL; + g_auto (GLnxTmpDir) tmpdir = { + 0, + }; + g_assert (glnx_mkdtempat (AT_FDCWD, "/tmp/test-XXXXXX", 0777, &tmpdir, &error)); + g_assert_no_error (error); + + { + g_autoptr (GKeyFile) config = NULL; + g_auto (GStrv) keys = NULL; + config = otcore_load_config (tmpdir.fd, "ostree/someconfig.conf", &error); + g_assert (config); + keys = g_key_file_get_groups (config, NULL); + g_assert (keys && *keys == NULL); + } + + g_assert (glnx_shutil_mkdir_p_at (tmpdir.fd, "usr/lib/ostree", 0755, NULL, NULL)); + g_assert (glnx_file_replace_contents_at (tmpdir.fd, "usr/lib/ostree/someconfig.conf", + (guint8 *)"[foo]\nbar=baz", -1, 0, NULL, NULL)); + + { + g_autoptr (GKeyFile) config = NULL; + g_auto (GStrv) keys = NULL; + config = otcore_load_config (tmpdir.fd, "ostree/someconfig.conf", &error); + g_assert (config); + keys = g_key_file_get_groups (config, NULL); + g_assert (keys); + g_assert_cmpstr (*keys, ==, "foo"); + } + + g_assert (glnx_shutil_mkdir_p_at (tmpdir.fd, "etc/ostree", 0755, NULL, NULL)); + g_assert (glnx_file_replace_contents_at (tmpdir.fd, "usr/lib/ostree/someconfig.conf", + (guint8 *)"[test]\nbar=baz", -1, 0, NULL, NULL)); + + { + g_autoptr (GKeyFile) config = NULL; + g_auto (GStrv) keys = NULL; + config = otcore_load_config (tmpdir.fd, "ostree/someconfig.conf", &error); + g_assert (config); + keys = g_key_file_get_groups (config, NULL); + g_assert (keys); + g_assert_cmpstr (*keys, ==, "test"); + } +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + otcore_ed25519_init (); + g_test_add_func ("/ed25519", test_ed25519); + g_test_add_func ("/prepare-root-cmdline", test_prepare_root_cmdline); + g_test_add_func ("/prepare-root-config", test_prepare_root_config); + return g_test_run (); +} diff --git a/tests/test-prune.sh b/tests/test-prune.sh index bbb77a2..0e62840 100755 --- a/tests/test-prune.sh +++ b/tests/test-prune.sh @@ -363,4 +363,16 @@ ${CMD_PREFIX} ostree --repo=repo prune --commit-only --keep-younger-than="1 week assert_repo_has_n_commits repo 4 assert_repo_has_n_non_commit_objects repo ${orig_obj_count} tap_ok --commit-only and --keep-younger-than + +reinitialize_commit_only_test_repo +for i in {1..10}; do + ${CMD_PREFIX} ostree --repo=repo prune --commit-only --keep-younger-than="1 week ago" & + commit=$(${CMD_PREFIX} ostree --repo=repo commit --branch foobar tree) + wait $! + if ! ostree show --repo=repo ${commit}; then + assert_not_reached "commit ${commit} on branch foobar was pruned?" + fi +done +tap_ok commit and prune together + tap_end diff --git a/tests/test-pull-c.c b/tests/test-pull-c.c index 3957e43..605c636 100644 --- a/tests/test-pull-c.c +++ b/tests/test-pull-c.c @@ -19,14 +19,15 @@ #include "config.h" #include "libglnx.h" +#include #include #include -#include #include #include "libostreetest.h" -typedef struct { +typedef struct +{ OstreeRepo *repo; } TestData; @@ -52,18 +53,20 @@ test_data_init (TestData *td) repo_url = g_strconcat (http_address, "/ostree/gnomerepo", NULL); - { g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); - g_autoptr(GVariant) opts = NULL; + { + g_autoptr (GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr (GVariant) opts = NULL; - g_variant_builder_add (builder, "{s@v}", "gpg-verify", g_variant_new_variant (g_variant_new_boolean (FALSE))); + g_variant_builder_add (builder, "{s@v}", "gpg-verify", + g_variant_new_variant (g_variant_new_boolean (FALSE))); opts = g_variant_ref_sink (g_variant_builder_end (builder)); - if (!ostree_repo_remote_change (td->repo, NULL, OSTREE_REPO_REMOTE_CHANGE_ADD, - "origin", repo_url, opts, NULL, error)) + if (!ostree_repo_remote_change (td->repo, NULL, OSTREE_REPO_REMOTE_CHANGE_ADD, "origin", + repo_url, opts, NULL, error)) goto out; } - out: +out: g_assert_no_error (local_error); } @@ -72,17 +75,17 @@ test_pull_multi_nochange (gconstpointer data) { GError *local_error = NULL; GError **error = &local_error; - TestData *td = (void*)data; + TestData *td = (void *)data; char *refs[] = { "main", NULL }; - if (!ostree_repo_pull (td->repo, "origin", (char**)&refs, 0, NULL, NULL, error)) + if (!ostree_repo_pull (td->repo, "origin", (char **)&refs, 0, NULL, NULL, error)) goto out; - if (!ostree_repo_pull (td->repo, "origin", (char**)&refs, 0, NULL, NULL, error)) + if (!ostree_repo_pull (td->repo, "origin", (char **)&refs, 0, NULL, NULL, error)) goto out; - if (!ostree_repo_pull (td->repo, "origin", (char**)&refs, 0, NULL, NULL, error)) + if (!ostree_repo_pull (td->repo, "origin", (char **)&refs, 0, NULL, NULL, error)) goto out; - - out: + +out: g_assert_no_error (local_error); } @@ -91,33 +94,36 @@ test_pull_multi_error_then_ok (gconstpointer data) { GError *local_error = NULL; GError **error = &local_error; - - TestData *td = (void*)data; + + TestData *td = (void *)data; char *ok_refs[] = { "main", NULL }; char *bad_refs[] = { "nosuchbranch", NULL }; for (guint i = 0; i < 3; i++) { - g_autoptr(GError) tmp_error = NULL; - if (!ostree_repo_pull (td->repo, "origin", (char**)&ok_refs, 0, NULL, NULL, error)) + g_autoptr (GError) tmp_error = NULL; + if (!ostree_repo_pull (td->repo, "origin", (char **)&ok_refs, 0, NULL, NULL, error)) goto out; - if (ostree_repo_pull (td->repo, "origin", (char**)&bad_refs, 0, NULL, NULL, &tmp_error)) + if (ostree_repo_pull (td->repo, "origin", (char **)&bad_refs, 0, NULL, NULL, &tmp_error)) g_assert_not_reached (); g_clear_error (&tmp_error); - if (ostree_repo_pull (td->repo, "origin", (char**)&bad_refs, 0, NULL, NULL, &tmp_error)) + if (ostree_repo_pull (td->repo, "origin", (char **)&bad_refs, 0, NULL, NULL, &tmp_error)) g_assert_not_reached (); g_clear_error (&tmp_error); - if (!ostree_repo_pull (td->repo, "origin", (char**)&ok_refs, 0, NULL, NULL, error)) + if (!ostree_repo_pull (td->repo, "origin", (char **)&ok_refs, 0, NULL, NULL, error)) goto out; } - - out: + +out: g_assert_no_error (local_error); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { - TestData td = {NULL,}; + TestData td = { + NULL, + }; int r; test_data_init (&td); @@ -127,7 +133,7 @@ int main (int argc, char **argv) g_test_add_data_func ("/test-pull-c/multi-nochange", &td, test_pull_multi_nochange); g_test_add_data_func ("/test-pull-c/multi-ok-error-repeat", &td, test_pull_multi_error_then_ok); - r = g_test_run(); + r = g_test_run (); g_clear_object (&td.repo); return r; diff --git a/tests/test-pull-contenturl.sh b/tests/test-pull-contenturl.sh index ba6a2a5..d47fdfe 100755 --- a/tests/test-pull-contenturl.sh +++ b/tests/test-pull-contenturl.sh @@ -21,6 +21,11 @@ set -euo pipefail . $(dirname $0)/libtest.sh +if test -z "${OSTREE_HTTPD}"; then + echo "1..0 #SKIP no ostree-trivial-httpd" + exit 0 +fi + echo "1..2" COMMIT_SIGN="" diff --git a/tests/test-pull-large-metadata.sh b/tests/test-pull-large-metadata.sh index 4394cc5..0768638 100755 --- a/tests/test-pull-large-metadata.sh +++ b/tests/test-pull-large-metadata.sh @@ -25,10 +25,11 @@ setup_fake_remote_repo1 "archive" echo '1..1' -# Overwrite the commit object with 20 M of +# Overwrite the commit object with 121 M of zeroes. This is based on the +# OSTREE_MAX_METADATA_SIZE constant in src/libostree/ostree-core.h cd ${test_tmpdir} rev=$(cd ostree-srv && ${CMD_PREFIX} ostree --repo=gnomerepo rev-parse main) -dd if=/dev/zero bs=1M count=20 of=ostree-srv/gnomerepo/objects/$(echo $rev | cut -b 1-2)/$(echo $rev | cut -b 3-).commit +dd if=/dev/zero bs=1M count=130 of=ostree-srv/gnomerepo/objects/$(echo $rev | cut -b 1-2)/$(echo $rev | cut -b 3-).commit cd ${test_tmpdir} mkdir repo diff --git a/tests/test-pull-localcache.sh b/tests/test-pull-localcache.sh index a10a93e..f4ebdd7 100755 --- a/tests/test-pull-localcache.sh +++ b/tests/test-pull-localcache.sh @@ -48,7 +48,7 @@ commit=$(${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo commit -b main --tree= rm -rf repo init_repo ${CMD_PREFIX} ostree --repo=repo pull --localcache-repo repo-local origin main >out.txt -assert_file_has_content out.txt '3 metadata, 1 content objects fetched (4 meta, 5 content local)' +assert_file_has_content out.txt '2 metadata, 1 content objects fetched (4 meta, 5 content local)' echo "ok pull --localcache-repo" # Check that pulling the same commit works as well diff --git a/tests/test-pull-metalink.sh b/tests/test-pull-metalink.sh index f73992b..22e5d59 100755 --- a/tests/test-pull-metalink.sh +++ b/tests/test-pull-metalink.sh @@ -21,6 +21,11 @@ set -euo pipefail . $(dirname $0)/libtest.sh +if test -z "${OSTREE_HTTPD}"; then + echo "1..0 #SKIP no ostree-trivial-httpd" + exit 0 +fi + setup_fake_remote_repo1 "archive" echo '1..9' diff --git a/tests/test-pull-mirrorlist.sh b/tests/test-pull-mirrorlist.sh index 1d0d2c5..d04d1e4 100755 --- a/tests/test-pull-mirrorlist.sh +++ b/tests/test-pull-mirrorlist.sh @@ -21,6 +21,11 @@ set -euo pipefail . $(dirname $0)/libtest.sh +if test -z "${OSTREE_HTTPD}"; then + echo "1..0 #SKIP no ostree-trivial-httpd" + exit 0 +fi + echo "1..3" setup_fake_remote_repo1 "archive" diff --git a/tests/test-pull-override-url.sh b/tests/test-pull-override-url.sh index 71a3271..4e8ed03 100755 --- a/tests/test-pull-override-url.sh +++ b/tests/test-pull-override-url.sh @@ -21,6 +21,11 @@ set -euo pipefail . $(dirname $0)/libtest.sh +if test -z "${OSTREE_HTTPD}"; then + echo "1..0 #SKIP no ostree-trivial-httpd" + exit 0 +fi + setup_fake_remote_repo1 "archive" echo '1..1' diff --git a/tests/test-pull-repeated.sh b/tests/test-pull-repeated.sh index 4c32161..7f724c9 100755 --- a/tests/test-pull-repeated.sh +++ b/tests/test-pull-repeated.sh @@ -26,18 +26,32 @@ if has_gpgme; then COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}" fi -echo "1..4" +echo "1..6" -# Test pulling from a repo which gives error 500 (internal server error) a lot of the time. +# Sanity check with no network retries and 500s given, pull should fail. +rm ostree-srv httpd repo -rf +setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-500s=99 + +pushd ${test_tmpdir} +ostree_repo_init repo --mode=archive +${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo +assert_fail ${CMD_PREFIX} ostree --repo=repo pull --mirror origin --network-retries=0 main 2>err.txt +assert_file_has_content err.txt "\(500.*Internal Server Error\)\|\(HTTP 500\)" + +popd +echo "ok no retries after a 500" + +# Test pulling a repo which gives error 500 (internal server error) a lot of the time. +rm ostree-srv httpd repo -rf setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-500s=50 pushd ${test_tmpdir} ostree_repo_init repo --mode=archive ${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo -for x in $(seq 200); do - if ${CMD_PREFIX} ostree --repo=repo pull --mirror origin main 2>err.txt; then - echo "Success on iteration ${x}" - break; +for x in $(seq 40); do + if ${CMD_PREFIX} ostree --repo=repo pull --mirror origin --network-retries=2 main 2>err.txt; then + echo "Success on iteration ${x}" + break; fi assert_file_has_content err.txt "\(500.*Internal Server Error\)\|\(HTTP 500\)" done @@ -48,6 +62,24 @@ ${CMD_PREFIX} ostree --repo=repo rev-parse main popd echo "ok repeated pull after 500s" +# Test pulling a repo that gives 408s a lot of the time, with many network retries. +rm ostree-srv httpd repo -rf +setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-500s=50 + +pushd ${test_tmpdir} +ostree_repo_init repo --mode=archive +${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo + +# We limit 500s above to 100, so 100 retries should be enough always. +${CMD_PREFIX} ostree --repo=repo pull --mirror origin --network-retries=100 main +echo "Success with big number of network retries" + +${CMD_PREFIX} ostree --repo=repo fsck +${CMD_PREFIX} ostree --repo=repo rev-parse main + +popd +echo "ok big number of retries with one 500s" + # Sanity check with no network retries and 408s given, pull should fail. rm ostree-srv httpd repo -rf setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-408s=99 diff --git a/tests/test-pull-summary-sigs.sh b/tests/test-pull-summary-sigs.sh index 03a40e4..e1b0412 100755 --- a/tests/test-pull-summary-sigs.sh +++ b/tests/test-pull-summary-sigs.sh @@ -157,6 +157,16 @@ assert_file_has_content summary.txt "Good signature from \"Ostree Tester static-deltas.txt assert_file_has_content static-deltas.txt \ $(${OSTREE} --repo=repo rev-parse origin:main) +${OSTREE} --repo=repo remote summary origin --list-metadata-keys > metadata +assert_file_has_content metadata "^ostree.static-deltas$" +assert_file_has_content metadata "^ostree.summary.indexed-deltas$" +assert_file_has_content metadata "^ostree.summary.last-modified$" +assert_file_has_content metadata "^ostree.summary.mode$" +assert_file_has_content metadata "^ostree.summary.tombstone-commits$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.indexed-deltas > metadata +assert_file_has_content metadata "^true$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.mode > metadata +assert_file_has_content metadata "^'archive-z2'$" ## Tests for handling of cached summaries while racing with remote summary updates diff --git a/tests/test-refs.sh b/tests/test-refs.sh index 3653d03..53b36f6 100755 --- a/tests/test-refs.sh +++ b/tests/test-refs.sh @@ -42,6 +42,10 @@ done ${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount assert_file_has_content refscount "^10$" +${CMD_PREFIX} ostree --repo=repo refs > refs +sort refs > refs-sorted +assert_files_equal refs refs-sorted + ${CMD_PREFIX} ostree --repo=repo refs foo > refs assert_not_file_has_content refs foo @@ -51,6 +55,14 @@ assert_file_has_content refs foo ${CMD_PREFIX} ostree --repo=repo refs foo | wc -l > refscount.foo assert_file_has_content refscount.foo "^5$" +rm -f expected-refs-revs +for ref in foo/test-{1..5}; do + rev=$(${CMD_PREFIX} ostree --repo=repo rev-parse $ref) + echo -e "${ref}\t${rev}" >> expected-refs-revs +done +${CMD_PREFIX} ostree --repo=repo refs --list --revision foo > refs-revs +assert_files_equal refs-revs expected-refs-revs + ${CMD_PREFIX} ostree --repo=repo refs --delete 2>/dev/null || true ${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.delete1 assert_file_has_content refscount.delete1 "^10$" diff --git a/tests/test-remote-refs.sh b/tests/test-remote-refs.sh new file mode 100755 index 0000000..b92fb20 --- /dev/null +++ b/tests/test-remote-refs.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright © 2023 Endless OS Foundation LLC +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . +# +# Authors: +# - Dan Nicholson + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +echo "1..2" + +setup_fake_remote_repo2 "archive" +${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/repo summary -u +${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/repo refs > origin-refs +${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/repo refs --revision > origin-refs-revs + +cd ${test_tmpdir} +rm -rf repo +ostree_repo_init repo --mode=archive +${OSTREE} remote add --no-sign-verify origin $(cat httpd-address)/ostree/repo + +${OSTREE} remote refs origin > refs +sed 's/^/origin:/' origin-refs > expected-refs +assert_files_equal refs expected-refs + +echo "ok remote refs listing" + +${OSTREE} remote refs origin --revision > refs-revs +sed 's/^/origin:/' origin-refs-revs > expected-refs-revs +assert_files_equal refs-revs expected-refs-revs + +echo "ok remote refs revisions" diff --git a/tests/test-repo-finder-avahi.c b/tests/test-repo-finder-avahi.c index 932c80b..a187b2f 100644 --- a/tests/test-repo-finder-avahi.c +++ b/tests/test-repo-finder-avahi.c @@ -23,15 +23,15 @@ #include "config.h" #include -#include #include +#include #include #include #include "ostree-autocleanups.h" -#include "ostree-repo-finder.h" -#include "ostree-repo-finder-avahi.h" #include "ostree-repo-finder-avahi-private.h" +#include "ostree-repo-finder-avahi.h" +#include "ostree-repo-finder.h" /* FIXME: Upstream this */ G_DEFINE_AUTOPTR_CLEANUP_FUNC (AvahiStringList, avahi_string_list_free) @@ -40,8 +40,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (AvahiStringList, avahi_string_list_free) static void test_repo_finder_avahi_init (void) { - g_autoptr(OstreeRepoFinderAvahi) finder = NULL; - g_autoptr(GMainContext) context = NULL; + g_autoptr (OstreeRepoFinderAvahi) finder = NULL; + g_autoptr (GMainContext) context = NULL; /* Default main context. */ finder = ostree_repo_finder_avahi_new (NULL); @@ -58,36 +58,34 @@ static void test_repo_finder_avahi_txt_records_parse (void) { struct - { - const guint8 *txt; - gsize txt_len; - const gchar *expected_key; /* (nullable) to indicate parse failure */ - const guint8 *expected_value; /* (nullable) to allow for valueless keys */ - gsize expected_value_len; - } - vectors[] = - { - { (const guint8 *) "", 0, NULL, NULL, 0 }, - { (const guint8 *) "\x00", 1, NULL, NULL, 0 }, - { (const guint8 *) "\xff", 1, NULL, NULL, 0 }, - { (const guint8 *) "k\x00", 2, NULL, NULL, 0 }, - { (const guint8 *) "k\xff", 2, NULL, NULL, 0 }, - { (const guint8 *) "=", 1, NULL, NULL, 0 }, - { (const guint8 *) "=value", 6, NULL, NULL, 0 }, - { (const guint8 *) "k=v", 3, "k", (const guint8 *) "v", 1 }, - { (const guint8 *) "key=value", 9, "key", (const guint8 *) "value", 5 }, - { (const guint8 *) "k=v=", 4, "k", (const guint8 *) "v=", 2 }, - { (const guint8 *) "k=", 2, "k", (const guint8 *) "", 0 }, - { (const guint8 *) "k", 1, "k", NULL, 0 }, - { (const guint8 *) "k==", 3, "k", (const guint8 *) "=", 1 }, - { (const guint8 *) "k=\x00\x01\x02", 5, "k", (const guint8 *) "\x00\x01\x02", 3 }, - }; + { + const guint8 *txt; + gsize txt_len; + const gchar *expected_key; /* (nullable) to indicate parse failure */ + const guint8 *expected_value; /* (nullable) to allow for valueless keys */ + gsize expected_value_len; + } vectors[] = { + { (const guint8 *)"", 0, NULL, NULL, 0 }, + { (const guint8 *)"\x00", 1, NULL, NULL, 0 }, + { (const guint8 *)"\xff", 1, NULL, NULL, 0 }, + { (const guint8 *)"k\x00", 2, NULL, NULL, 0 }, + { (const guint8 *)"k\xff", 2, NULL, NULL, 0 }, + { (const guint8 *)"=", 1, NULL, NULL, 0 }, + { (const guint8 *)"=value", 6, NULL, NULL, 0 }, + { (const guint8 *)"k=v", 3, "k", (const guint8 *)"v", 1 }, + { (const guint8 *)"key=value", 9, "key", (const guint8 *)"value", 5 }, + { (const guint8 *)"k=v=", 4, "k", (const guint8 *)"v=", 2 }, + { (const guint8 *)"k=", 2, "k", (const guint8 *)"", 0 }, + { (const guint8 *)"k", 1, "k", NULL, 0 }, + { (const guint8 *)"k==", 3, "k", (const guint8 *)"=", 1 }, + { (const guint8 *)"k=\x00\x01\x02", 5, "k", (const guint8 *)"\x00\x01\x02", 3 }, + }; gsize i; for (i = 0; i < G_N_ELEMENTS (vectors); i++) { - g_autoptr(AvahiStringList) string_list = NULL; - g_autoptr(GHashTable) attributes = NULL; + g_autoptr (AvahiStringList) string_list = NULL; + g_autoptr (GHashTable) attributes = NULL; g_test_message ("Vector %" G_GSIZE_FORMAT, i); @@ -98,18 +96,17 @@ test_repo_finder_avahi_txt_records_parse (void) if (vectors[i].expected_key != NULL) { GBytes *value; - g_autoptr(GBytes) expected_value = NULL; + g_autoptr (GBytes) expected_value = NULL; - g_assert_true (g_hash_table_lookup_extended (attributes, - vectors[i].expected_key, - NULL, - (gpointer *) &value)); + g_assert_true (g_hash_table_lookup_extended (attributes, vectors[i].expected_key, NULL, + (gpointer *)&value)); g_assert_cmpuint (g_hash_table_size (attributes), ==, 1); if (vectors[i].expected_value != NULL) { g_assert_nonnull (value); - expected_value = g_bytes_new_static (vectors[i].expected_value, vectors[i].expected_value_len); + expected_value + = g_bytes_new_static (vectors[i].expected_value, vectors[i].expected_value_len); g_assert_true (g_bytes_equal (value, expected_value)); } else @@ -129,10 +126,10 @@ test_repo_finder_avahi_txt_records_parse (void) static void test_repo_finder_avahi_txt_records_duplicates (void) { - g_autoptr(AvahiStringList) string_list = NULL; - g_autoptr(GHashTable) attributes = NULL; + g_autoptr (AvahiStringList) string_list = NULL; + g_autoptr (GHashTable) attributes = NULL; GBytes *value; - g_autoptr(GBytes) expected_value = NULL; + g_autoptr (GBytes) expected_value = NULL; /* Reverse the list before using it, as they are built in reverse order. * (See the #AvahiStringList documentation.) */ @@ -153,17 +150,14 @@ test_repo_finder_avahi_txt_records_duplicates (void) static void test_repo_finder_avahi_txt_records_case_sensitivity (void) { - g_autoptr(AvahiStringList) string_list = NULL; - g_autoptr(GHashTable) attributes = NULL; + g_autoptr (AvahiStringList) string_list = NULL; + g_autoptr (GHashTable) attributes = NULL; GBytes *value1, *value2; - g_autoptr(GBytes) expected_value1 = NULL, expected_value2 = NULL; + g_autoptr (GBytes) expected_value1 = NULL, expected_value2 = NULL; /* Reverse the list before using it, as they are built in reverse order. * (See the #AvahiStringList documentation.) */ - string_list = avahi_string_list_new ("k=value1", - "K=value2", - "KeY2=v", - NULL); + string_list = avahi_string_list_new ("k=value1", "K=value2", "KeY2=v", NULL); string_list = avahi_string_list_reverse (string_list); attributes = _ostree_txt_records_parse (string_list); @@ -189,14 +183,12 @@ test_repo_finder_avahi_txt_records_case_sensitivity (void) static void test_repo_finder_avahi_txt_records_empty_and_missing (void) { - g_autoptr(AvahiStringList) string_list = NULL; - g_autoptr(GHashTable) attributes = NULL; + g_autoptr (AvahiStringList) string_list = NULL; + g_autoptr (GHashTable) attributes = NULL; GBytes *value1, *value2; - g_autoptr(GBytes) expected_value1 = NULL; + g_autoptr (GBytes) expected_value1 = NULL; - string_list = avahi_string_list_new ("empty=", - "missing", - NULL); + string_list = avahi_string_list_new ("empty=", "missing", NULL); attributes = _ostree_txt_records_parse (string_list); g_assert_cmpuint (g_hash_table_size (attributes), ==, 2); @@ -206,22 +198,27 @@ test_repo_finder_avahi_txt_records_empty_and_missing (void) expected_value1 = g_bytes_new_static ("", 0); g_assert_true (g_bytes_equal (value1, expected_value1)); - g_assert_true (g_hash_table_lookup_extended (attributes, "missing", NULL, (gpointer *) &value2)); + g_assert_true (g_hash_table_lookup_extended (attributes, "missing", NULL, (gpointer *)&value2)); g_assert_null (value2); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); g_test_add_func ("/repo-finder-avahi/init", test_repo_finder_avahi_init); - g_test_add_func ("/repo-finder-avahi/txt-records/parse", test_repo_finder_avahi_txt_records_parse); - g_test_add_func ("/repo-finder-avahi/txt-records/duplicates", test_repo_finder_avahi_txt_records_duplicates); - g_test_add_func ("/repo-finder-avahi/txt-records/case-sensitivity", test_repo_finder_avahi_txt_records_case_sensitivity); - g_test_add_func ("/repo-finder-avahi/txt-records/empty-and-missing", test_repo_finder_avahi_txt_records_empty_and_missing); + g_test_add_func ("/repo-finder-avahi/txt-records/parse", + test_repo_finder_avahi_txt_records_parse); + g_test_add_func ("/repo-finder-avahi/txt-records/duplicates", + test_repo_finder_avahi_txt_records_duplicates); + g_test_add_func ("/repo-finder-avahi/txt-records/case-sensitivity", + test_repo_finder_avahi_txt_records_case_sensitivity); + g_test_add_func ("/repo-finder-avahi/txt-records/empty-and-missing", + test_repo_finder_avahi_txt_records_empty_and_missing); /* FIXME: Add tests for service processing, probably by splitting the * code in OstreeRepoFinderAvahi around found_services. */ - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-repo-finder-config.c b/tests/test-repo-finder-config.c index 30f1b20..4b08b2e 100644 --- a/tests/test-repo-finder-config.c +++ b/tests/test-repo-finder-config.c @@ -23,30 +23,29 @@ #include "config.h" #include -#include #include +#include #include #include #include #include "libostreetest.h" #include "ostree-autocleanups.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-config.h" +#include "ostree-repo-finder.h" /* Test fixture. Creates a temporary directory. */ typedef struct { - OstreeRepo *parent_repo; /* owned */ - GLnxTmpDir tmpdir; /* owned */ - GFile *working_dir; /* owned */ + OstreeRepo *parent_repo; /* owned */ + GLnxTmpDir tmpdir; /* owned */ + GFile *working_dir; /* owned */ } Fixture; static void -setup (Fixture *fixture, - gconstpointer test_data) +setup (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; (void)glnx_mkdtemp ("test-repo-finder-config-XXXXXX", 0700, &fixture->tmpdir, &error); g_assert_no_error (error); @@ -63,8 +62,7 @@ setup (Fixture *fixture, } static void -teardown (Fixture *fixture, - gconstpointer test_data) +teardown (Fixture *fixture, gconstpointer test_data) { /* Recursively remove the temporary directory. */ (void)glnx_tmpdir_delete (&fixture->tmpdir, NULL, NULL); @@ -83,16 +81,14 @@ teardown (Fixture *fixture, static void test_repo_finder_config_init (void) { - g_autoptr(OstreeRepoFinderConfig) finder = NULL; + g_autoptr (OstreeRepoFinderConfig) finder = NULL; /* Default everything. */ finder = ostree_repo_finder_config_new (); } static void -result_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) +result_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GAsyncResult **result_out = user_data; *result_out = g_object_ref (result); @@ -101,31 +97,29 @@ result_cb (GObject *source_object, /* Test that no remotes are found if there are no config files in the refs * directory. */ static void -test_repo_finder_config_no_configs (Fixture *fixture, - gconstpointer test_data) +test_repo_finder_config_no_configs (Fixture *fixture, gconstpointer test_data) { - g_autoptr(OstreeRepoFinderConfig) finder = NULL; - g_autoptr(GMainContext) context = NULL; - g_autoptr(GAsyncResult) result = NULL; - g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ - g_autoptr(GError) error = NULL; + g_autoptr (OstreeRepoFinderConfig) finder = NULL; + g_autoptr (GMainContext) context = NULL; + g_autoptr (GAsyncResult) result = NULL; + g_autoptr (GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GError) error = NULL; const OstreeCollectionRef ref1 = { "org.example.Os", "exampleos/x86_64/standard" }; const OstreeCollectionRef ref2 = { "org.example.Os", "exampleos/x86_64/buildmain/standard" }; - const OstreeCollectionRef * const refs[] = { &ref1, &ref2, NULL }; + const OstreeCollectionRef *const refs[] = { &ref1, &ref2, NULL }; context = g_main_context_new (); g_main_context_push_thread_default (context); finder = ostree_repo_finder_config_new (); - ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, - fixture->parent_repo, NULL, result_cb, &result); + ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, fixture->parent_repo, NULL, + result_cb, &result); while (result == NULL) g_main_context_iteration (context, TRUE); - results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), - result, &error); + results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), result, &error); g_assert_no_error (error); g_assert_nonnull (results); g_assert_cmpuint (results->len, ==, 0); @@ -136,36 +130,30 @@ test_repo_finder_config_no_configs (Fixture *fixture, /* Add configuration for a remote named @remote_name, at @remote_uri, with a * remote collection ID of @collection_id, to the given @repo. */ static void -assert_create_remote_config (OstreeRepo *repo, - const gchar *remote_name, - const gchar *remote_uri, +assert_create_remote_config (OstreeRepo *repo, const gchar *remote_name, const gchar *remote_uri, const gchar *collection_id) { - g_autoptr(GError) error = NULL; - g_autoptr(GVariant) options = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GVariant) options = NULL; if (collection_id != NULL) - options = g_variant_new_parsed ("@a{sv} { 'collection-id': <%s> }", - collection_id); + options = g_variant_new_parsed ("@a{sv} { 'collection-id': <%s> }", collection_id); ostree_repo_remote_add (repo, remote_name, remote_uri, options, NULL, &error); g_assert_no_error (error); } -static gchar *assert_create_remote (Fixture *fixture, - const gchar *collection_id, +static gchar *assert_create_remote (Fixture *fixture, const gchar *collection_id, ...) G_GNUC_NULL_TERMINATED; /* Create a new repository in a temporary directory with its collection ID set * to @collection_id, and containing the refs given in @... (which must be * %NULL-terminated). Return the `file://` URI of the new repository. */ static gchar * -assert_create_remote (Fixture *fixture, - const gchar *collection_id, - ...) +assert_create_remote (Fixture *fixture, const gchar *collection_id, ...) { va_list args; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; const gchar *repo_name = (collection_id != NULL) ? collection_id : "no-collection"; glnx_shutil_mkdir_p_at (fixture->tmpdir.fd, repo_name, 0700, NULL, &error); @@ -174,8 +162,8 @@ assert_create_remote (Fixture *fixture, glnx_shutil_mkdir_p_at (fixture->tmpdir.fd, "empty", 0700, NULL, &error); g_assert_no_error (error); - g_autoptr(GFile) repo_path = g_file_get_child (fixture->working_dir, repo_name); - g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path); + g_autoptr (GFile) repo_path = g_file_get_child (fixture->working_dir, repo_name); + g_autoptr (OstreeRepo) repo = ostree_repo_new (repo_path); ostree_repo_set_collection_id (repo, collection_id, &error); g_assert_no_error (error); ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE, NULL, &error); @@ -184,24 +172,22 @@ assert_create_remote (Fixture *fixture, /* Set up the refs from @.... */ va_start (args, collection_id); - for (const gchar *ref_name = va_arg (args, const gchar *); - ref_name != NULL; + for (const gchar *ref_name = va_arg (args, const gchar *); ref_name != NULL; ref_name = va_arg (args, const gchar *)) { - OstreeCollectionRef collection_ref = { (gchar *) collection_id, (gchar *) ref_name }; + OstreeCollectionRef collection_ref = { (gchar *)collection_id, (gchar *)ref_name }; g_autofree gchar *checksum = NULL; - g_autoptr(OstreeMutableTree) mtree = NULL; - g_autoptr(OstreeRepoFile) repo_file = NULL; + g_autoptr (OstreeMutableTree) mtree = NULL; + g_autoptr (OstreeRepoFile) repo_file = NULL; mtree = ostree_mutable_tree_new (); ostree_repo_write_dfd_to_mtree (repo, fixture->tmpdir.fd, "empty", mtree, NULL, NULL, &error); g_assert_no_error (error); - ostree_repo_write_mtree (repo, mtree, (GFile **) &repo_file, NULL, &error); + ostree_repo_write_mtree (repo, mtree, (GFile **)&repo_file, NULL, &error); g_assert_no_error (error); - ostree_repo_write_commit (repo, NULL /* no parent */, ref_name, ref_name, - NULL /* no metadata */, repo_file, &checksum, - NULL, &error); + ostree_repo_write_commit (repo, NULL /* no parent */, ref_name, ref_name, + NULL /* no metadata */, repo_file, &checksum, NULL, &error); g_assert_no_error (error); if (collection_id != NULL) @@ -214,7 +200,7 @@ assert_create_remote (Fixture *fixture, va_end (args); /* Update the summary. */ - ostree_repo_regenerate_summary (repo, NULL /* no metadata */, NULL, &error); + ostree_repo_regenerate_summary (repo, NULL /* no metadata */, NULL, &error); g_assert_no_error (error); return g_file_get_uri (repo_path); @@ -223,54 +209,52 @@ assert_create_remote (Fixture *fixture, /* Test resolving the refs against a collection of config files, which contain * valid, invalid or duplicate repo information. */ static void -test_repo_finder_config_mixed_configs (Fixture *fixture, - gconstpointer test_data) +test_repo_finder_config_mixed_configs (Fixture *fixture, gconstpointer test_data) { - g_autoptr(OstreeRepoFinderConfig) finder = NULL; - g_autoptr(GMainContext) context = NULL; - g_autoptr(GAsyncResult) async_result = NULL; - g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ - g_autoptr(GError) error = NULL; + g_autoptr (OstreeRepoFinderConfig) finder = NULL; + g_autoptr (GMainContext) context = NULL; + g_autoptr (GAsyncResult) async_result = NULL; + g_autoptr (GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GError) error = NULL; gsize i; const OstreeCollectionRef ref0 = { "org.example.Collection0", "exampleos/x86_64/ref0" }; const OstreeCollectionRef ref1 = { "org.example.Collection0", "exampleos/x86_64/ref1" }; const OstreeCollectionRef ref2 = { "org.example.Collection1", "exampleos/x86_64/ref1" }; const OstreeCollectionRef ref3 = { "org.example.Collection1", "exampleos/x86_64/ref2" }; const OstreeCollectionRef ref4 = { "org.example.Collection2", "exampleos/x86_64/ref3" }; - const OstreeCollectionRef * const refs[] = { &ref0, &ref1, &ref2, &ref3, &ref4, NULL }; + const OstreeCollectionRef *const refs[] = { &ref0, &ref1, &ref2, &ref3, &ref4, NULL }; context = g_main_context_new (); g_main_context_push_thread_default (context); /* Put together various ref configuration files. */ - g_autofree gchar *collection0_uri = assert_create_remote (fixture, "org.example.Collection0", - "exampleos/x86_64/ref0", - "exampleos/x86_64/ref1", - NULL); - g_autofree gchar *collection1_uri = assert_create_remote (fixture, "org.example.Collection1", - "exampleos/x86_64/ref2", - NULL); - g_autofree gchar *no_collection_uri = assert_create_remote (fixture, NULL, - "exampleos/x86_64/ref3", - NULL); - - assert_create_remote_config (fixture->parent_repo, "remote0", collection0_uri, "org.example.Collection0"); - assert_create_remote_config (fixture->parent_repo, "remote1", collection1_uri, "org.example.Collection1"); - assert_create_remote_config (fixture->parent_repo, "remote0-copy", collection0_uri, "org.example.Collection0"); - assert_create_remote_config (fixture->parent_repo, "remote1-bad-copy", collection1_uri, "org.example.NotCollection1"); + g_autofree gchar *collection0_uri = assert_create_remote ( + fixture, "org.example.Collection0", "exampleos/x86_64/ref0", "exampleos/x86_64/ref1", NULL); + g_autofree gchar *collection1_uri + = assert_create_remote (fixture, "org.example.Collection1", "exampleos/x86_64/ref2", NULL); + g_autofree gchar *no_collection_uri + = assert_create_remote (fixture, NULL, "exampleos/x86_64/ref3", NULL); + + assert_create_remote_config (fixture->parent_repo, "remote0", collection0_uri, + "org.example.Collection0"); + assert_create_remote_config (fixture->parent_repo, "remote1", collection1_uri, + "org.example.Collection1"); + assert_create_remote_config (fixture->parent_repo, "remote0-copy", collection0_uri, + "org.example.Collection0"); + assert_create_remote_config (fixture->parent_repo, "remote1-bad-copy", collection1_uri, + "org.example.NotCollection1"); assert_create_remote_config (fixture->parent_repo, "remote2", no_collection_uri, NULL); finder = ostree_repo_finder_config_new (); /* Resolve the refs. */ - ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, - fixture->parent_repo, NULL, result_cb, &async_result); + ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, fixture->parent_repo, NULL, + result_cb, &async_result); while (async_result == NULL) g_main_context_iteration (context, TRUE); - results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), - async_result, &error); + results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), async_result, &error); g_assert_no_error (error); g_assert_nonnull (results); g_assert_cmpuint (results->len, ==, 3); @@ -281,8 +265,8 @@ test_repo_finder_config_mixed_configs (Fixture *fixture, { const OstreeRepoFinderResult *result = g_ptr_array_index (results, i); - if (g_strcmp0 (ostree_remote_get_name (result->remote), "remote0") == 0 || - g_strcmp0 (ostree_remote_get_name (result->remote), "remote0-copy") == 0) + if (g_strcmp0 (ostree_remote_get_name (result->remote), "remote0") == 0 + || g_strcmp0 (ostree_remote_get_name (result->remote), "remote0-copy") == 0) { g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 2); g_assert_true (g_hash_table_contains (result->ref_to_checksum, &ref0)); @@ -306,58 +290,57 @@ test_repo_finder_config_mixed_configs (Fixture *fixture, /* Test that using ostree_repo_find_remotes_async() works too.*/ static void -test_repo_finder_config_find_remotes (Fixture *fixture, - gconstpointer test_data) +test_repo_finder_config_find_remotes (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GMainContext) context = NULL; - g_autoptr(GAsyncResult) result = NULL; - g_auto(OstreeRepoFinderResultv) results = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GMainContext) context = NULL; + g_autoptr (GAsyncResult) result = NULL; + g_auto (OstreeRepoFinderResultv) results = NULL; + g_autoptr (GError) error = NULL; gsize i; const OstreeCollectionRef ref0 = { "org.example.Collection0", "exampleos/x86_64/ref0" }; const OstreeCollectionRef ref1 = { "org.example.Collection0", "exampleos/x86_64/ref1" }; const OstreeCollectionRef ref2 = { "org.example.Collection1", "exampleos/x86_64/ref1" }; const OstreeCollectionRef ref3 = { "org.example.Collection1", "exampleos/x86_64/ref2" }; const OstreeCollectionRef ref4 = { "org.example.Collection2", "exampleos/x86_64/ref3" }; - const OstreeCollectionRef * const refs[] = { &ref0, &ref1, &ref2, &ref3, &ref4, NULL }; - OstreeRepoFinder *finders[2] = {NULL, }; + const OstreeCollectionRef *const refs[] = { &ref0, &ref1, &ref2, &ref3, &ref4, NULL }; + OstreeRepoFinder *finders[2] = { + NULL, + }; context = g_main_context_new (); g_main_context_push_thread_default (context); /* Put together various ref configuration files. */ - g_autofree gchar *collection0_uri = assert_create_remote (fixture, "org.example.Collection0", - "exampleos/x86_64/ref0", - "exampleos/x86_64/ref1", - NULL); - g_autofree gchar *collection1_uri = assert_create_remote (fixture, "org.example.Collection1", - "exampleos/x86_64/ref2", - NULL); - g_autofree gchar *no_collection_uri = assert_create_remote (fixture, NULL, - "exampleos/x86_64/ref3", - NULL); - - assert_create_remote_config (fixture->parent_repo, "remote0", collection0_uri, "org.example.Collection0"); - assert_create_remote_config (fixture->parent_repo, "remote1", collection1_uri, "org.example.Collection1"); - assert_create_remote_config (fixture->parent_repo, "remote0-copy", collection0_uri, "org.example.Collection0"); - assert_create_remote_config (fixture->parent_repo, "remote1-bad-copy", collection1_uri, "org.example.NotCollection1"); + g_autofree gchar *collection0_uri = assert_create_remote ( + fixture, "org.example.Collection0", "exampleos/x86_64/ref0", "exampleos/x86_64/ref1", NULL); + g_autofree gchar *collection1_uri + = assert_create_remote (fixture, "org.example.Collection1", "exampleos/x86_64/ref2", NULL); + g_autofree gchar *no_collection_uri + = assert_create_remote (fixture, NULL, "exampleos/x86_64/ref3", NULL); + + assert_create_remote_config (fixture->parent_repo, "remote0", collection0_uri, + "org.example.Collection0"); + assert_create_remote_config (fixture->parent_repo, "remote1", collection1_uri, + "org.example.Collection1"); + assert_create_remote_config (fixture->parent_repo, "remote0-copy", collection0_uri, + "org.example.Collection0"); + assert_create_remote_config (fixture->parent_repo, "remote1-bad-copy", collection1_uri, + "org.example.NotCollection1"); assert_create_remote_config (fixture->parent_repo, "remote2", no_collection_uri, NULL); finders[0] = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ()); /* Resolve the refs. */ - ostree_repo_find_remotes_async (fixture->parent_repo, refs, - NULL, finders, - NULL, NULL, result_cb, &result); + ostree_repo_find_remotes_async (fixture->parent_repo, refs, NULL, finders, NULL, NULL, result_cb, + &result); while (result == NULL) g_main_context_iteration (context, TRUE); - results = ostree_repo_find_remotes_finish (fixture->parent_repo, - result, &error); + results = ostree_repo_find_remotes_finish (fixture->parent_repo, result, &error); g_assert_no_error (error); g_assert_nonnull (results); - g_assert_cmpuint (g_strv_length ((char **) results), ==, 3); + g_assert_cmpuint (g_strv_length ((char **)results), ==, 3); /* Check that the results are correct: the invalid refs should have been * ignored, and the valid results canonicalised and deduplicated. */ @@ -366,8 +349,8 @@ test_repo_finder_config_find_remotes (Fixture *fixture, const char *ref0_checksum, *ref1_checksum, *ref2_checksum, *ref3_checksum; guint64 *ref0_timestamp, *ref1_timestamp, *ref2_timestamp, *ref3_timestamp; - if (g_strcmp0 (ostree_remote_get_name (results[i]->remote), "remote0") == 0 || - g_strcmp0 (ostree_remote_get_name (results[i]->remote), "remote0-copy") == 0) + if (g_strcmp0 (ostree_remote_get_name (results[i]->remote), "remote0") == 0 + || g_strcmp0 (ostree_remote_get_name (results[i]->remote), "remote0-copy") == 0) { g_assert_cmpuint (g_hash_table_size (results[i]->ref_to_checksum), ==, 5); @@ -427,7 +410,8 @@ test_repo_finder_config_find_remotes (Fixture *fixture, g_main_context_pop_thread_default (context); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); @@ -440,5 +424,5 @@ int main (int argc, char **argv) g_test_add ("/repo-finder-config/find-remotes", Fixture, NULL, setup, test_repo_finder_config_find_remotes, teardown); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-repo-finder-mount-integration.sh b/tests/test-repo-finder-mount-integration.sh index e7a0f86..b1a8d42 100755 --- a/tests/test-repo-finder-mount-integration.sh +++ b/tests/test-repo-finder-mount-integration.sh @@ -24,6 +24,7 @@ set -euo pipefail . $(dirname $0)/libtest.sh +skip_without_sudo SUDO="sudo --non-interactive" # Skip the test if a well-known USB stick is not available. diff --git a/tests/test-repo-finder-mount.c b/tests/test-repo-finder-mount.c index 3d36018..0bbcd84 100644 --- a/tests/test-repo-finder-mount.c +++ b/tests/test-repo-finder-mount.c @@ -23,16 +23,16 @@ #include "config.h" #include -#include #include +#include #include #include #include "libostreetest.h" #include "ostree-autocleanups.h" #include "ostree-remote-private.h" -#include "ostree-repo-finder.h" #include "ostree-repo-finder-mount.h" +#include "ostree-repo-finder.h" #include "ostree-types.h" #include "test-mock-gio.h" @@ -40,15 +40,14 @@ typedef struct { OstreeRepo *parent_repo; - GLnxTmpDir tmpdir; /* owned */ + GLnxTmpDir tmpdir; /* owned */ GFile *working_dir; /* Points at tmpdir */ } Fixture; static void -setup (Fixture *fixture, - gconstpointer test_data) +setup (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; (void)glnx_mkdtemp ("test-repo-finder-mount-XXXXXX", 0700, &fixture->tmpdir, &error); g_assert_no_error (error); @@ -69,8 +68,7 @@ setup (Fixture *fixture, } static void -teardown (Fixture *fixture, - gconstpointer test_data) +teardown (Fixture *fixture, gconstpointer test_data) { /* Recursively remove the temporary directory. */ (void)glnx_tmpdir_delete (&fixture->tmpdir, NULL, NULL); @@ -89,8 +87,8 @@ teardown (Fixture *fixture, static void test_repo_finder_mount_init (void) { - g_autoptr(OstreeRepoFinderMount) finder = NULL; - g_autoptr(GVolumeMonitor) monitor = NULL; + g_autoptr (OstreeRepoFinderMount) finder = NULL; + g_autoptr (GVolumeMonitor) monitor = NULL; /* Default #GVolumeMonitor. */ finder = ostree_repo_finder_mount_new (NULL); @@ -103,9 +101,7 @@ test_repo_finder_mount_init (void) } static void -result_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) +result_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GAsyncResult **result_out = user_data; *result_out = g_object_ref (result); @@ -113,20 +109,20 @@ result_cb (GObject *source_object, /* Test that no remotes are found if the #GVolumeMonitor returns no mounts. */ static void -test_repo_finder_mount_no_mounts (Fixture *fixture, - gconstpointer test_data) +test_repo_finder_mount_no_mounts (Fixture *fixture, gconstpointer test_data) { - g_autoptr(OstreeRepoFinderMount) finder = NULL; - g_autoptr(GVolumeMonitor) monitor = NULL; - g_autoptr(GMainContext) context = NULL; - g_autoptr(GAsyncResult) result = NULL; - g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ - g_autoptr(GError) error = NULL; + g_autoptr (OstreeRepoFinderMount) finder = NULL; + g_autoptr (GVolumeMonitor) monitor = NULL; + g_autoptr (GMainContext) context = NULL; + g_autoptr (GAsyncResult) result = NULL; + g_autoptr (GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GError) error = NULL; const OstreeCollectionRef ref1 = { "org.example.Collection1", "exampleos/x86_64/standard" }; - const OstreeCollectionRef ref2 = { "org.example.Collection1", "exampleos/x86_64/buildmain/standard" }; + const OstreeCollectionRef ref2 + = { "org.example.Collection1", "exampleos/x86_64/buildmain/standard" }; const OstreeCollectionRef ref3 = { "org.example.Collection2", "exampleos/x86_64/standard" }; const OstreeCollectionRef ref4 = { "org.example.Collection2", "exampleos/arm64/standard" }; - const OstreeCollectionRef * const refs[] = { &ref1, &ref2, &ref3, &ref4, NULL }; + const OstreeCollectionRef *const refs[] = { &ref1, &ref2, &ref3, &ref4, NULL }; context = g_main_context_new (); g_main_context_push_thread_default (context); @@ -134,15 +130,13 @@ test_repo_finder_mount_no_mounts (Fixture *fixture, monitor = ostree_mock_volume_monitor_new (NULL, NULL); finder = ostree_repo_finder_mount_new (monitor); - ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, - fixture->parent_repo, - NULL, result_cb, &result); + ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, fixture->parent_repo, NULL, + result_cb, &result); while (result == NULL) g_main_context_iteration (context, TRUE); - results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), - result, &error); + results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), result, &error); g_assert_no_error (error); g_assert_nonnull (results); g_assert_cmpuint (results->len, ==, 0); @@ -152,13 +146,11 @@ test_repo_finder_mount_no_mounts (Fixture *fixture, /* Create a .ostree/repos.d directory under the given @mount_root, or abort. */ static gboolean -assert_create_repos_dir (Fixture *fixture, - const gchar *mount_root_name, - int *out_repos_dfd, - GMount **out_mount) +assert_create_repos_dir (Fixture *fixture, const gchar *mount_root_name, int *out_repos_dfd, + GMount **out_mount) { glnx_autofd int repos_dfd = -1; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; g_autofree gchar *path = g_build_filename (mount_root_name, ".ostree", "repos.d", NULL); glnx_shutil_mkdir_p_at_open (fixture->tmpdir.fd, path, 0700, &repos_dfd, NULL, &error); @@ -166,8 +158,8 @@ assert_create_repos_dir (Fixture *fixture, g_clear_error (&error); g_assert_no_error (error); - *out_repos_dfd = glnx_steal_fd (&repos_dfd); - g_autoptr(GFile) mount_root = g_file_get_child (fixture->working_dir, mount_root_name); + *out_repos_dfd = g_steal_fd (&repos_dfd); + g_autoptr (GFile) mount_root = g_file_get_child (fixture->working_dir, mount_root_name); *out_mount = G_MOUNT (ostree_mock_mount_new (mount_root_name, mount_root)); return TRUE; @@ -178,13 +170,11 @@ assert_create_repos_dir (Fixture *fixture, * #OstreeCollectionRef in @... is followed by a gchar** return address for the * checksum committed for that ref. Return the new repository. */ static OstreeRepo * -assert_create_remote_va (Fixture *fixture, - GFile *repo_dir, - va_list args) +assert_create_remote_va (Fixture *fixture, GFile *repo_dir, va_list args) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_dir); + g_autoptr (OstreeRepo) repo = ostree_repo_new (repo_dir); ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE, NULL, &error); g_assert_no_error (error); @@ -192,24 +182,22 @@ assert_create_remote_va (Fixture *fixture, g_assert_no_error (error); /* Set up the refs from @.... */ - for (const OstreeCollectionRef *ref = va_arg (args, const OstreeCollectionRef *); - ref != NULL; + for (const OstreeCollectionRef *ref = va_arg (args, const OstreeCollectionRef *); ref != NULL; ref = va_arg (args, const OstreeCollectionRef *)) { g_autofree gchar *checksum = NULL; - g_autoptr(OstreeMutableTree) mtree = NULL; - g_autoptr(OstreeRepoFile) repo_file = NULL; + g_autoptr (OstreeMutableTree) mtree = NULL; + g_autoptr (OstreeRepoFile) repo_file = NULL; gchar **out_checksum = va_arg (args, gchar **); mtree = ostree_mutable_tree_new (); ostree_repo_write_dfd_to_mtree (repo, fixture->tmpdir.fd, "empty", mtree, NULL, NULL, &error); g_assert_no_error (error); - ostree_repo_write_mtree (repo, mtree, (GFile **) &repo_file, NULL, &error); + ostree_repo_write_mtree (repo, mtree, (GFile **)&repo_file, NULL, &error); g_assert_no_error (error); - ostree_repo_write_commit (repo, NULL /* no parent */, ref->ref_name, ref->ref_name, - NULL /* no metadata */, repo_file, &checksum, - NULL, &error); + ostree_repo_write_commit (repo, NULL /* no parent */, ref->ref_name, ref->ref_name, + NULL /* no metadata */, repo_file, &checksum, NULL, &error); g_assert_no_error (error); if (ref->collection_id != NULL) @@ -223,34 +211,26 @@ assert_create_remote_va (Fixture *fixture, } /* Update the summary. */ - ostree_repo_regenerate_summary (repo, NULL /* no metadata */, NULL, &error); + ostree_repo_regenerate_summary (repo, NULL /* no metadata */, NULL, &error); g_assert_no_error (error); return g_steal_pointer (&repo); } -static OstreeRepo * -assert_create_repo_dir (Fixture *fixture, - int repos_dfd, - GMount *repos_mount, - const char *repo_name, - gchar **out_uri, - ...) G_GNUC_NULL_TERMINATED; +static OstreeRepo *assert_create_repo_dir (Fixture *fixture, int repos_dfd, GMount *repos_mount, + const char *repo_name, gchar **out_uri, + ...) G_GNUC_NULL_TERMINATED; /* Create a @repo_name directory under the given @repos_dfd, or abort. Create a * new repository in it with the refs given in @..., as per * assert_create_remote_va(). Return the URI of the repository. */ static OstreeRepo * -assert_create_repo_dir (Fixture *fixture, - int repos_dfd, - GMount *repos_mount, - const char *repo_name, - gchar **out_uri, - ...) +assert_create_repo_dir (Fixture *fixture, int repos_dfd, GMount *repos_mount, const char *repo_name, + gchar **out_uri, ...) { glnx_autofd int ref_dfd = -1; - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (OstreeRepo) repo = NULL; + g_autoptr (GError) error = NULL; va_list args; glnx_shutil_mkdir_p_at_open (repos_dfd, repo_name, 0700, &ref_dfd, NULL, &error); @@ -258,9 +238,9 @@ assert_create_repo_dir (Fixture *fixture, g_clear_error (&error); g_assert_no_error (error); - g_autoptr(GFile) mount_root = g_mount_get_root (repos_mount); - g_autoptr(GFile) repos_dir = g_file_get_child (mount_root, ".ostree/repos.d"); - g_autoptr(GFile) repo_dir = g_file_get_child (repos_dir, repo_name); + g_autoptr (GFile) mount_root = g_mount_get_root (repos_mount); + g_autoptr (GFile) repos_dir = g_file_get_child (mount_root, ".ostree/repos.d"); + g_autoptr (GFile) repo_dir = g_file_get_child (repos_dir, repo_name); va_start (args, out_uri); repo = assert_create_remote_va (fixture, repo_dir, args); @@ -274,13 +254,11 @@ assert_create_repo_dir (Fixture *fixture, /* Create a @repo_name symlink under the given @repos_dfd, pointing to * @symlink_target_path, or abort. */ static void -assert_create_repo_symlink (int repos_dfd, - const char *repo_name, - const char *symlink_target_path) +assert_create_repo_symlink (int repos_dfd, const char *repo_name, const char *symlink_target_path) { if (TEMP_FAILURE_RETRY (symlinkat (symlink_target_path, repos_dfd, repo_name)) != 0) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; glnx_throw_errno_prefix (&error, "symlinkat"); g_assert_no_error (error); } @@ -289,17 +267,14 @@ assert_create_repo_symlink (int repos_dfd, /* Add configuration for a remote named @remote_name, at @remote_uri, with a * remote collection ID of @collection_id, to the given @repo. */ static void -assert_create_remote_config (OstreeRepo *repo, - const gchar *remote_name, - const gchar *remote_uri, +assert_create_remote_config (OstreeRepo *repo, const gchar *remote_name, const gchar *remote_uri, const gchar *collection_id) { - g_autoptr(GError) error = NULL; - g_autoptr(GVariant) options = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GVariant) options = NULL; if (collection_id != NULL) - options = g_variant_new_parsed ("@a{sv} { 'collection-id': <%s> }", - collection_id); + options = g_variant_new_parsed ("@a{sv} { 'collection-id': <%s> }", collection_id); ostree_repo_remote_add (repo, remote_name, remote_uri, options, NULL, &error); g_assert_no_error (error); @@ -309,39 +284,41 @@ assert_create_remote_config (OstreeRepo *repo, * are mounted, some of which are removable, some of which contain valid or * invalid repo information on the file system, etc. */ static void -test_repo_finder_mount_mixed_mounts (Fixture *fixture, - gconstpointer test_data) +test_repo_finder_mount_mixed_mounts (Fixture *fixture, gconstpointer test_data) { - g_autoptr(OstreeRepoFinderMount) finder = NULL; - g_autoptr(GVolumeMonitor) monitor = NULL; - g_autoptr(GMainContext) context = NULL; - g_autoptr(GAsyncResult) async_result = NULL; - g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ - g_autoptr(GError) error = NULL; - g_autoptr(GList) mounts = NULL; /* (element-type OstreeMockMount) */ - g_autoptr(GMount) non_removable_mount = NULL; - g_autoptr(GMount) no_repos_mount = NULL; - g_autoptr(GMount) repo1_mount = NULL; - g_autoptr(GMount) repo2_mount = NULL; - g_autoptr(GFile) non_removable_root = NULL; + g_autoptr (OstreeRepoFinderMount) finder = NULL; + g_autoptr (GVolumeMonitor) monitor = NULL; + g_autoptr (GMainContext) context = NULL; + g_autoptr (GAsyncResult) async_result = NULL; + g_autoptr (GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GError) error = NULL; + g_autoptr (GList) mounts = NULL; /* (element-type OstreeMockMount) */ + g_autoptr (GMount) non_removable_mount = NULL; + g_autoptr (GMount) no_repos_mount = NULL; + g_autoptr (GMount) repo1_mount = NULL; + g_autoptr (GMount) repo2_mount = NULL; + g_autoptr (GFile) non_removable_root = NULL; glnx_autofd int no_repos_repos = -1; glnx_autofd int repo1_repos = -1; glnx_autofd int repo2_repos = -1; - g_autoptr(OstreeRepo) repo1_repo_a = NULL, repo1_repo_b = NULL; - g_autoptr(OstreeRepo) repo2_repo_a = NULL; + g_autoptr (OstreeRepo) repo1_repo_a = NULL, repo1_repo_b = NULL; + g_autoptr (OstreeRepo) repo2_repo_a = NULL; g_autofree gchar *repo1_repo_a_uri = NULL, *repo1_repo_b_uri = NULL; g_autofree gchar *repo2_repo_a_uri = NULL; - g_autofree gchar *repo1_ref0_checksum = NULL, *repo1_ref1_checksum = NULL, *repo1_ref2_checksum = NULL; - g_autofree gchar *repo2_ref0_checksum = NULL, *repo2_ref1_checksum = NULL, *repo2_ref2_checksum = NULL; + g_autofree gchar *repo1_ref0_checksum = NULL, *repo1_ref1_checksum = NULL, + *repo1_ref2_checksum = NULL; + g_autofree gchar *repo2_ref0_checksum = NULL, *repo2_ref1_checksum = NULL, + *repo2_ref2_checksum = NULL; g_autofree gchar *repo1_ref5_checksum = NULL, *repo2_ref3_checksum = NULL; gsize i; const OstreeCollectionRef ref0 = { "org.example.Collection1", "exampleos/x86_64/ref0" }; const OstreeCollectionRef ref1 = { "org.example.Collection1", "exampleos/x86_64/ref1" }; const OstreeCollectionRef ref2 = { "org.example.Collection1", "exampleos/x86_64/ref2" }; const OstreeCollectionRef ref3 = { "org.example.Collection1", "exampleos/x86_64/ref3" }; - const OstreeCollectionRef ref4 = { "org.example.UnconfiguredCollection", "exampleos/x86_64/ref4" }; + const OstreeCollectionRef ref4 + = { "org.example.UnconfiguredCollection", "exampleos/x86_64/ref4" }; const OstreeCollectionRef ref5 = { "org.example.Collection3", "exampleos/x86_64/ref0" }; - const OstreeCollectionRef * const refs[] = { &ref0, &ref1, &ref2, &ref3, &ref4, &ref5, NULL }; + const OstreeCollectionRef *const refs[] = { &ref0, &ref1, &ref2, &ref3, &ref4, &ref5, NULL }; context = g_main_context_new (); g_main_context_push_thread_default (context); @@ -356,23 +333,18 @@ test_repo_finder_mount_mixed_mounts (Fixture *fixture, assert_create_repos_dir (fixture, "no-repos-mount", &no_repos_repos, &no_repos_mount); assert_create_repos_dir (fixture, "repo1-mount", &repo1_repos, &repo1_mount); - repo1_repo_a = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, "repo1-repo-a", &repo1_repo_a_uri, - refs[0], &repo1_ref0_checksum, - refs[2], &repo1_ref2_checksum, - refs[5], &repo1_ref5_checksum, - NULL); - repo1_repo_b = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, "repo1-repo-b", &repo1_repo_b_uri, - refs[1], &repo1_ref1_checksum, - NULL); + repo1_repo_a = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, "repo1-repo-a", + &repo1_repo_a_uri, refs[0], &repo1_ref0_checksum, refs[2], + &repo1_ref2_checksum, refs[5], &repo1_ref5_checksum, NULL); + repo1_repo_b = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, "repo1-repo-b", + &repo1_repo_b_uri, refs[1], &repo1_ref1_checksum, NULL); assert_create_repo_symlink (repo1_repos, "repo1-repo-a-alias", "repo1-repo-a"); assert_create_repos_dir (fixture, "repo2-mount", &repo2_repos, &repo2_mount); - repo2_repo_a = assert_create_repo_dir (fixture, repo2_repos, repo2_mount, "repo2-repo-a", &repo2_repo_a_uri, - refs[0], &repo2_ref0_checksum, - refs[1], &repo2_ref1_checksum, - refs[2], &repo2_ref2_checksum, - refs[3], &repo2_ref3_checksum, - NULL); + repo2_repo_a = assert_create_repo_dir (fixture, repo2_repos, repo2_mount, "repo2-repo-a", + &repo2_repo_a_uri, refs[0], &repo2_ref0_checksum, refs[1], + &repo2_ref1_checksum, refs[2], &repo2_ref2_checksum, + refs[3], &repo2_ref3_checksum, NULL); assert_create_repo_symlink (repo2_repos, "repo2-repo-a-alias", "repo2-repo-a"); assert_create_repo_symlink (repo2_repos, "dangling-symlink", "repo2-repo-b"); assert_create_repo_symlink (repo2_repos, "root", "/"); @@ -385,21 +357,22 @@ test_repo_finder_mount_mixed_mounts (Fixture *fixture, monitor = ostree_mock_volume_monitor_new (mounts, NULL); finder = ostree_repo_finder_mount_new (monitor); - assert_create_remote_config (fixture->parent_repo, "remote1", "https://nope1", "org.example.Collection1"); - assert_create_remote_config (fixture->parent_repo, "remote2", "https://nope2", "org.example.Collection2"); + assert_create_remote_config (fixture->parent_repo, "remote1", "https://nope1", + "org.example.Collection1"); + assert_create_remote_config (fixture->parent_repo, "remote2", "https://nope2", + "org.example.Collection2"); /* don’t configure org.example.UnconfiguredCollection */ - assert_create_remote_config (fixture->parent_repo, "remote3", "https://nope3", "org.example.Collection3"); + assert_create_remote_config (fixture->parent_repo, "remote3", "https://nope3", + "org.example.Collection3"); /* Resolve the refs. */ - ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, - fixture->parent_repo, - NULL, result_cb, &async_result); + ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, fixture->parent_repo, NULL, + result_cb, &async_result); while (async_result == NULL) g_main_context_iteration (context, TRUE); - results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), - async_result, &error); + results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), async_result, &error); g_assert_no_error (error); g_assert_nonnull (results); g_assert_cmpuint (results->len, ==, 4); @@ -416,38 +389,46 @@ test_repo_finder_mount_mixed_mounts (Fixture *fixture, g_assert_no_error (error); keyring = result->remote->keyring; - if (g_strcmp0 (uri, repo1_repo_a_uri) == 0 && - g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) + if (g_strcmp0 (uri, repo1_repo_a_uri) == 0 + && g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) { g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 2); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[0]), ==, repo1_ref0_checksum); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[2]), ==, repo1_ref2_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[0]), ==, + repo1_ref0_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[2]), ==, + repo1_ref2_checksum); } - else if (g_strcmp0 (uri, repo1_repo_a_uri) == 0 && - g_strcmp0 (keyring, "remote3.trustedkeys.gpg") == 0) + else if (g_strcmp0 (uri, repo1_repo_a_uri) == 0 + && g_strcmp0 (keyring, "remote3.trustedkeys.gpg") == 0) { g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 1); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[5]), ==, repo1_ref5_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[5]), ==, + repo1_ref5_checksum); } - else if (g_strcmp0 (uri, repo1_repo_b_uri) == 0 && - g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) + else if (g_strcmp0 (uri, repo1_repo_b_uri) == 0 + && g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) { g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 1); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[1]), ==, repo1_ref1_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[1]), ==, + repo1_ref1_checksum); } - else if (g_strcmp0 (uri, repo2_repo_a_uri) == 0 && - g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) + else if (g_strcmp0 (uri, repo2_repo_a_uri) == 0 + && g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) { g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 4); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[0]), ==, repo2_ref0_checksum); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[1]), ==, repo2_ref1_checksum); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[2]), ==, repo2_ref2_checksum); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[3]), ==, repo2_ref3_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[0]), ==, + repo2_ref0_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[1]), ==, + repo2_ref1_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[2]), ==, + repo2_ref2_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[3]), ==, + repo2_ref3_checksum); } else { - g_error ("Unknown result ‘%s’ with keyring ‘%s’", - result->remote->name, result->remote->keyring); + g_error ("Unknown result ‘%s’ with keyring ‘%s’", result->remote->name, + result->remote->keyring); } } @@ -458,25 +439,24 @@ test_repo_finder_mount_mixed_mounts (Fixture *fixture, * in the default repository paths ostree/repo and .ostree/repo, to check that * those paths are read */ static void -test_repo_finder_mount_well_known (Fixture *fixture, - gconstpointer test_data) +test_repo_finder_mount_well_known (Fixture *fixture, gconstpointer test_data) { - g_autoptr(OstreeRepoFinderMount) finder = NULL; - g_autoptr(GVolumeMonitor) monitor = NULL; - g_autoptr(GMainContext) context = NULL; - g_autoptr(GAsyncResult) async_result = NULL; - g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ - g_autoptr(GError) error = NULL; - g_autoptr(GList) mounts = NULL; /* (element-type OstreeMockMount) */ - g_autoptr(GMount) mount = NULL; + g_autoptr (OstreeRepoFinderMount) finder = NULL; + g_autoptr (GVolumeMonitor) monitor = NULL; + g_autoptr (GMainContext) context = NULL; + g_autoptr (GAsyncResult) async_result = NULL; + g_autoptr (GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */ + g_autoptr (GError) error = NULL; + g_autoptr (GList) mounts = NULL; /* (element-type OstreeMockMount) */ + g_autoptr (GMount) mount = NULL; glnx_autofd int repos = -1; - g_autoptr(OstreeRepo) repo_a = NULL, repo_b = NULL; + g_autoptr (OstreeRepo) repo_a = NULL, repo_b = NULL; g_autofree gchar *repo_a_uri = NULL, *repo_b_uri = NULL; g_autofree gchar *ref_a_checksum = NULL, *ref_b_checksum = NULL; gsize i; const OstreeCollectionRef ref_a = { "org.example.Collection1", "refA" }; const OstreeCollectionRef ref_b = { "org.example.Collection2", "refB" }; - const OstreeCollectionRef * const refs[] = { &ref_a, &ref_b, NULL }; + const OstreeCollectionRef *const refs[] = { &ref_a, &ref_b, NULL }; context = g_main_context_new (); g_main_context_push_thread_default (context); @@ -486,12 +466,10 @@ test_repo_finder_mount_well_known (Fixture *fixture, * file system from /tmp, so it’s an example of a symlink pointing outside * its mount point. */ assert_create_repos_dir (fixture, "mount", &repos, &mount); - repo_a = assert_create_repo_dir (fixture, repos, mount, "../../ostree/repo", &repo_a_uri, - &ref_a, &ref_a_checksum, - NULL); - repo_b = assert_create_repo_dir (fixture, repos, mount, "../../.ostree/repo", &repo_b_uri, - &ref_b, &ref_b_checksum, - NULL); + repo_a = assert_create_repo_dir (fixture, repos, mount, "../../ostree/repo", &repo_a_uri, &ref_a, + &ref_a_checksum, NULL); + repo_b = assert_create_repo_dir (fixture, repos, mount, "../../.ostree/repo", &repo_b_uri, &ref_b, + &ref_b_checksum, NULL); assert_create_repo_symlink (repos, "repo-a-alias", "../../ostree/repo"); mounts = g_list_prepend (mounts, mount); @@ -499,19 +477,19 @@ test_repo_finder_mount_well_known (Fixture *fixture, monitor = ostree_mock_volume_monitor_new (mounts, NULL); finder = ostree_repo_finder_mount_new (monitor); - assert_create_remote_config (fixture->parent_repo, "remote1", "https://nope1", "org.example.Collection1"); - assert_create_remote_config (fixture->parent_repo, "remote2", "https://nope2", "org.example.Collection2"); + assert_create_remote_config (fixture->parent_repo, "remote1", "https://nope1", + "org.example.Collection1"); + assert_create_remote_config (fixture->parent_repo, "remote2", "https://nope2", + "org.example.Collection2"); /* Resolve the refs. */ - ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, - fixture->parent_repo, - NULL, result_cb, &async_result); + ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs, fixture->parent_repo, NULL, + result_cb, &async_result); while (async_result == NULL) g_main_context_iteration (context, TRUE); - results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), - async_result, &error); + results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder), async_result, &error); g_assert_no_error (error); g_assert_nonnull (results); g_assert_cmpuint (results->len, ==, 2); @@ -528,22 +506,23 @@ test_repo_finder_mount_well_known (Fixture *fixture, g_assert_no_error (error); keyring = result->remote->keyring; - if (g_strcmp0 (uri, repo_a_uri) == 0 && - g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) + if (g_strcmp0 (uri, repo_a_uri) == 0 && g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0) { g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 1); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, &ref_a), ==, ref_a_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, &ref_a), ==, + ref_a_checksum); } - else if (g_strcmp0 (uri, repo_b_uri) == 0 && - g_strcmp0 (keyring, "remote2.trustedkeys.gpg") == 0) + else if (g_strcmp0 (uri, repo_b_uri) == 0 + && g_strcmp0 (keyring, "remote2.trustedkeys.gpg") == 0) { g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 1); - g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, &ref_b), ==, ref_b_checksum); + g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, &ref_b), ==, + ref_b_checksum); } else { - g_test_message ("Unknown result ‘%s’ with keyring ‘%s’.", - result->remote->name, result->remote->keyring); + g_test_message ("Unknown result ‘%s’ with keyring ‘%s’.", result->remote->name, + result->remote->keyring); g_assert_not_reached (); } } @@ -551,7 +530,8 @@ test_repo_finder_mount_well_known (Fixture *fixture, g_main_context_pop_thread_default (context); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); @@ -560,12 +540,13 @@ int main (int argc, char **argv) g_test_add ("/repo-finder-mount/no-mounts", Fixture, NULL, setup, test_repo_finder_mount_no_mounts, teardown); #ifndef OSTREE_DISABLE_GPGME - /*`ostree_repo_resolve_keyring_for_collection()` fail the tests if no GPG support is compiled in. */ + /*`ostree_repo_resolve_keyring_for_collection()` fail the tests if no GPG support is compiled in. + */ g_test_add ("/repo-finder-mount/mixed-mounts", Fixture, NULL, setup, test_repo_finder_mount_mixed_mounts, teardown); g_test_add ("/repo-finder-mount/well-known", Fixture, NULL, setup, test_repo_finder_mount_well_known, teardown); #endif /* OSTREE_DISABLE_GPGME */ - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-repo.c b/tests/test-repo.c index 4a7a44a..1bc4cb8 100644 --- a/tests/test-repo.c +++ b/tests/test-repo.c @@ -23,8 +23,8 @@ #include "config.h" #include -#include #include +#include #include #include @@ -34,16 +34,15 @@ /* Test fixture. Creates a temporary directory. */ typedef struct { - GLnxTmpDir tmpdir; /* (owned) */ + GLnxTmpDir tmpdir; /* (owned) */ } Fixture; static void -setup (Fixture *fixture, - gconstpointer test_data) +setup (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; - (void) glnx_mkdtemp ("test-repo-XXXXXX", 0700, &fixture->tmpdir, &error); + (void)glnx_mkdtemp ("test-repo-XXXXXX", 0700, &fixture->tmpdir, &error); g_assert_no_error (error); g_test_message ("Using temporary directory: %s", fixture->tmpdir.path); @@ -53,49 +52,41 @@ setup (Fixture *fixture, * set the locking timeout to 0 so lock failures don't block. */ static void -lock_setup (Fixture *fixture, - gconstpointer test_data) +lock_setup (Fixture *fixture, gconstpointer test_data) { setup (fixture, test_data); - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_create_at (fixture->tmpdir.fd, ".", - OSTREE_REPO_MODE_ARCHIVE, - NULL, - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo = ostree_repo_create_at ( + fixture->tmpdir.fd, ".", OSTREE_REPO_MODE_ARCHIVE, NULL, NULL, &error); g_assert_no_error (error); /* Set the lock timeout to 0 so failures don't block the test */ - g_autoptr(GKeyFile) config = ostree_repo_copy_config (repo); + g_autoptr (GKeyFile) config = ostree_repo_copy_config (repo); g_key_file_set_integer (config, "core", "lock-timeout-secs", 0); ostree_repo_write_config (repo, config, &error); g_assert_no_error (error); } static void -teardown (Fixture *fixture, - gconstpointer test_data) +teardown (Fixture *fixture, gconstpointer test_data) { /* Recursively remove the temporary directory. */ - (void) glnx_tmpdir_delete (&fixture->tmpdir, NULL, NULL); + (void)glnx_tmpdir_delete (&fixture->tmpdir, NULL, NULL); } /* Test that the hash values for two #OstreeRepo instances pointing at the same * repository are equal. We can’t test anything else, since hash collisions are * always a possibility. */ static void -test_repo_hash (Fixture *fixture, - gconstpointer test_data) +test_repo_hash (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo1 = ostree_repo_create_at (fixture->tmpdir.fd, ".", - OSTREE_REPO_MODE_ARCHIVE, - NULL, - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo1 = ostree_repo_create_at ( + fixture->tmpdir.fd, ".", OSTREE_REPO_MODE_ARCHIVE, NULL, NULL, &error); g_assert_no_error (error); - g_autoptr(OstreeRepo) repo2 = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (OstreeRepo) repo2 = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); g_assert_cmpuint (ostree_repo_hash (repo1), ==, ostree_repo_hash (repo2)); @@ -103,13 +94,12 @@ test_repo_hash (Fixture *fixture, /* Test that trying to hash a closed repo results in an assertion failure. */ static void -test_repo_hash_closed (Fixture *fixture, - gconstpointer test_data) +test_repo_hash_closed (Fixture *fixture, gconstpointer test_data) { if (g_test_subprocess ()) { - g_autoptr(GFile) repo_path = g_file_new_for_path (fixture->tmpdir.path); - g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path); + g_autoptr (GFile) repo_path = g_file_new_for_path (fixture->tmpdir.path); + g_autoptr (OstreeRepo) repo = ostree_repo_new (repo_path); ostree_repo_hash (repo); @@ -123,10 +113,9 @@ test_repo_hash_closed (Fixture *fixture, /* Test that various repositories test equal (or not) with each other. */ static void -test_repo_equal (Fixture *fixture, - gconstpointer test_data) +test_repo_equal (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; /* Create a few separate repos and some #OstreeRepo objects for them. */ glnx_ensure_dir (fixture->tmpdir.fd, "repo1", 0755, &error); @@ -134,24 +123,20 @@ test_repo_equal (Fixture *fixture, glnx_ensure_dir (fixture->tmpdir.fd, "repo2", 0755, &error); g_assert_no_error (error); - g_autoptr(OstreeRepo) repo1 = ostree_repo_create_at (fixture->tmpdir.fd, "repo1", - OSTREE_REPO_MODE_ARCHIVE, - NULL, - NULL, &error); + g_autoptr (OstreeRepo) repo1 = ostree_repo_create_at ( + fixture->tmpdir.fd, "repo1", OSTREE_REPO_MODE_ARCHIVE, NULL, NULL, &error); g_assert_no_error (error); - g_autoptr(OstreeRepo) repo1_alias = ostree_repo_open_at (fixture->tmpdir.fd, "repo1", - NULL, &error); + g_autoptr (OstreeRepo) repo1_alias + = ostree_repo_open_at (fixture->tmpdir.fd, "repo1", NULL, &error); g_assert_no_error (error); - g_autoptr(OstreeRepo) repo2 = ostree_repo_create_at (fixture->tmpdir.fd, "repo2", - OSTREE_REPO_MODE_ARCHIVE, - NULL, - NULL, &error); + g_autoptr (OstreeRepo) repo2 = ostree_repo_create_at ( + fixture->tmpdir.fd, "repo2", OSTREE_REPO_MODE_ARCHIVE, NULL, NULL, &error); g_assert_no_error (error); - g_autoptr(GFile) closed_repo_path = g_file_new_for_path (fixture->tmpdir.path); - g_autoptr(OstreeRepo) closed_repo = ostree_repo_new (closed_repo_path); + g_autoptr (GFile) closed_repo_path = g_file_new_for_path (fixture->tmpdir.path); + g_autoptr (OstreeRepo) closed_repo = ostree_repo_new (closed_repo_path); /* Test various equalities. */ g_assert_true (ostree_repo_equal (repo1, repo1)); @@ -173,30 +158,26 @@ test_repo_equal (Fixture *fixture, } static void -test_repo_get_min_free_space (Fixture *fixture, - gconstpointer test_data) +test_repo_get_min_free_space (Fixture *fixture, gconstpointer test_data) { g_autoptr (GKeyFile) config = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; guint64 bytes = 0; typedef struct - { - const char *val; - gboolean should_succeed; - } min_free_space_value; + { + const char *val; + gboolean should_succeed; + } min_free_space_value; - g_autoptr(OstreeRepo) repo = ostree_repo_create_at (fixture->tmpdir.fd, ".", - OSTREE_REPO_MODE_ARCHIVE, - NULL, - NULL, &error); + g_autoptr (OstreeRepo) repo = ostree_repo_create_at ( + fixture->tmpdir.fd, ".", OSTREE_REPO_MODE_ARCHIVE, NULL, NULL, &error); g_assert_no_error (error); - min_free_space_value values_to_test[] = { - {"500MB", TRUE }, - { "0MB", TRUE }, - { "17179869185GB", FALSE }, /* Overflow parameter: bytes > G_MAXUINT64 */ - { NULL, FALSE } - }; + min_free_space_value values_to_test[] + = { { "500MB", TRUE }, + { "0MB", TRUE }, + { "17179869185GB", FALSE }, /* Overflow parameter: bytes > G_MAXUINT64 */ + { NULL, FALSE } }; config = ostree_repo_copy_config (repo); @@ -219,89 +200,94 @@ test_repo_get_min_free_space (Fixture *fixture, } static void -test_write_regfile_api (Fixture *fixture, - gconstpointer test_data) +test_write_regfile_api (Fixture *fixture, gconstpointer test_data) { g_autoptr (GKeyFile) config = NULL; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_create_at (fixture->tmpdir.fd, ".", - OSTREE_REPO_MODE_ARCHIVE, - NULL, - NULL, &error); + g_autoptr (OstreeRepo) repo = ostree_repo_create_at ( + fixture->tmpdir.fd, ".", OSTREE_REPO_MODE_ARCHIVE, NULL, NULL, &error); g_assert_no_error (error); - g_auto(GVariantBuilder) xattrs_builder; - g_variant_builder_init (&xattrs_builder, (GVariantType*)"a(ayay)"); - g_variant_builder_add (&xattrs_builder, "(^ay^ay)", "security.selinux", "system_u:object_r:etc_t:s0"); - g_autoptr(GVariant) xattrs = g_variant_ref_sink (g_variant_builder_end (&xattrs_builder)); + g_auto (GVariantBuilder) xattrs_builder; + g_variant_builder_init (&xattrs_builder, (GVariantType *)"a(ayay)"); + g_variant_builder_add (&xattrs_builder, "(^ay^ay)", "security.selinux", + "system_u:object_r:etc_t:s0"); + g_autoptr (GVariant) xattrs = g_variant_ref_sink (g_variant_builder_end (&xattrs_builder)); // Current contents of /etc/networks in Fedora static const char contents[] = "default 0.0.0.0\nloopback 127.0.0.0\nlink-local 169.254.0.0\n"; // First with no xattrs - g_autofree char *checksum = ostree_repo_write_regfile_inline (repo, NULL, 0, 0, S_IFREG | 0644, NULL, (const guint8*)contents, sizeof (contents)-1, NULL, &error); + g_autofree char *checksum = ostree_repo_write_regfile_inline ( + repo, NULL, 0, 0, S_IFREG | 0644, NULL, (const guint8 *)contents, sizeof (contents) - 1, NULL, + &error); g_assert_no_error (error); - g_assert_cmpstr (checksum, ==, "8aaa9dc13a0c5839fe4a277756798c609c53fac6fa2290314ecfef9041065873"); + g_assert_cmpstr (checksum, ==, + "8aaa9dc13a0c5839fe4a277756798c609c53fac6fa2290314ecfef9041065873"); g_clear_pointer (&checksum, g_free); // Invalid checksum - checksum = ostree_repo_write_regfile_inline (repo, "3272139f889f6a7007b3d64adc74be9e2979bf6bbe663d1512e5bd43f4de24a1", - 0, 0, S_IFREG | 0644, NULL, (const guint8*)contents, sizeof (contents)-1, NULL, &error); + checksum = ostree_repo_write_regfile_inline ( + repo, "3272139f889f6a7007b3d64adc74be9e2979bf6bbe663d1512e5bd43f4de24a1", 0, 0, + S_IFREG | 0644, NULL, (const guint8 *)contents, sizeof (contents) - 1, NULL, &error); g_assert (checksum == NULL); g_assert (error != NULL); g_clear_error (&error); - - // Now with xattrs + + // Now with xattrs g_clear_pointer (&checksum, g_free); - checksum = ostree_repo_write_regfile_inline (repo, NULL, 0, 0, S_IFREG | 0644, xattrs, (const guint8*)contents, sizeof (contents)-1, NULL, &error); + checksum = ostree_repo_write_regfile_inline (repo, NULL, 0, 0, S_IFREG | 0644, xattrs, + (const guint8 *)contents, sizeof (contents) - 1, + NULL, &error); g_assert_no_error (error); - g_assert_cmpstr (checksum, ==, "4f600d252338f93279c51c964915cb2c26f0d09082164c54890d1a3c78cdeb1e"); + g_assert_cmpstr (checksum, ==, + "4f600d252338f93279c51c964915cb2c26f0d09082164c54890d1a3c78cdeb1e"); g_clear_pointer (&checksum, g_free); // Test symlinks g_clear_pointer (&xattrs, g_variant_unref); - g_variant_builder_init (&xattrs_builder, (GVariantType*)"a(ayay)"); - g_variant_builder_add (&xattrs_builder, "(^ay^ay)", "security.selinux", "system_u:object_r:bin_t:s0"); + g_variant_builder_init (&xattrs_builder, (GVariantType *)"a(ayay)"); + g_variant_builder_add (&xattrs_builder, "(^ay^ay)", "security.selinux", + "system_u:object_r:bin_t:s0"); xattrs = g_variant_ref_sink (g_variant_builder_end (&xattrs_builder)); g_clear_pointer (&checksum, g_free); checksum = ostree_repo_write_symlink (repo, NULL, 0, 0, xattrs, "bash", NULL, &error); g_assert_no_error (error); - g_assert_cmpstr (checksum, ==, "23a2e97d21d960ac7a4e39a8721b1baff7b213e00e5e5641334f50506012fcff"); + g_assert_cmpstr (checksum, ==, + "23a2e97d21d960ac7a4e39a8721b1baff7b213e00e5e5641334f50506012fcff"); } /* Just a sanity check of the C autolocking API */ static void -test_repo_autolock (Fixture *fixture, - gconstpointer test_data) +test_repo_autolock (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_create_at (fixture->tmpdir.fd, ".", - OSTREE_REPO_MODE_ARCHIVE, - NULL, - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo = ostree_repo_create_at ( + fixture->tmpdir.fd, ".", OSTREE_REPO_MODE_ARCHIVE, NULL, NULL, &error); g_assert_no_error (error); { - g_autoptr(OstreeRepoAutoLock) lock = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, NULL, &error); + g_autoptr (OstreeRepoAutoLock) lock + = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, NULL, &error); g_assert_no_error (error); } - g_autoptr(OstreeRepoAutoLock) lock1 = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); + g_autoptr (OstreeRepoAutoLock) lock1 + = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); g_assert_no_error (error); - g_autoptr(OstreeRepoAutoLock) lock2 = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); + g_autoptr (OstreeRepoAutoLock) lock2 + = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); g_assert_no_error (error); } /* Locking from single thread with a single OstreeRepo */ static void -test_repo_lock_single (Fixture *fixture, - gconstpointer test_data) +test_repo_lock_single (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); /* Single thread on a single repo can freely recurse in any state */ @@ -321,14 +307,12 @@ test_repo_lock_single (Fixture *fixture, /* Unlocking without having ever locked */ static void -test_repo_lock_unlock_never_locked (Fixture *fixture, - gconstpointer test_data) +test_repo_lock_unlock_never_locked (Fixture *fixture, gconstpointer test_data) { if (g_test_subprocess ()) { - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); ostree_repo_lock_pop (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); @@ -343,14 +327,12 @@ test_repo_lock_unlock_never_locked (Fixture *fixture, /* Unlocking after already unlocked */ static void -test_repo_lock_double_unlock (Fixture *fixture, - gconstpointer test_data) +test_repo_lock_double_unlock (Fixture *fixture, gconstpointer test_data) { if (g_test_subprocess ()) { - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); ostree_repo_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); @@ -369,14 +351,12 @@ test_repo_lock_double_unlock (Fixture *fixture, /* Unlocking the wrong type */ static void -test_repo_lock_unlock_wrong_type (Fixture *fixture, - gconstpointer test_data) +test_repo_lock_unlock_wrong_type (Fixture *fixture, gconstpointer test_data) { if (g_test_subprocess ()) { - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); ostree_repo_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); @@ -388,22 +368,20 @@ test_repo_lock_unlock_wrong_type (Fixture *fixture, g_test_trap_subprocess (NULL, 0, 0); g_test_trap_assert_failed (); - g_test_trap_assert_stderr ("*ERROR*Repo exclusive lock pop requested, but none have been taken\n"); + g_test_trap_assert_stderr ( + "*ERROR*Repo exclusive lock pop requested, but none have been taken\n"); } /* Locking with single thread and multiple OstreeRepos */ static void -test_repo_lock_multi_repo (Fixture *fixture, - gconstpointer test_data) +test_repo_lock_multi_repo (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; /* Open two OstreeRepo instances */ - g_autoptr(OstreeRepo) repo1 = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (OstreeRepo) repo1 = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); - g_autoptr(OstreeRepo) repo2 = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (OstreeRepo) repo2 = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); /* Single thread with multiple OstreeRepo's conflict */ @@ -437,7 +415,8 @@ test_repo_lock_multi_repo (Fixture *fixture, } /* Locking from multiple threads with a single OstreeRepo */ -typedef struct { +typedef struct +{ OstreeRepo *repo; guint step; } LockThreadData; @@ -446,7 +425,7 @@ static gpointer lock_thread1 (gpointer thread_data) { LockThreadData *data = thread_data; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; /* Step 0: Take an exclusive lock */ g_assert_cmpuint (data->step, ==, 0); @@ -481,7 +460,7 @@ static gpointer lock_thread2 (gpointer thread_data) { LockThreadData *data = thread_data; - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; /* Step 1: Wait for the other thread to acquire a lock and then take a * shared lock. @@ -505,18 +484,15 @@ lock_thread2 (gpointer thread_data) } static void -test_repo_lock_multi_thread (Fixture *fixture, - gconstpointer test_data) +test_repo_lock_multi_thread (Fixture *fixture, gconstpointer test_data) { - g_autoptr(GError) error = NULL; - g_autoptr(OstreeRepo) repo1 = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (GError) error = NULL; + g_autoptr (OstreeRepo) repo1 = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); - g_autoptr(OstreeRepo) repo2 = ostree_repo_open_at (fixture->tmpdir.fd, ".", - NULL, &error); + g_autoptr (OstreeRepo) repo2 = ostree_repo_open_at (fixture->tmpdir.fd, ".", NULL, &error); g_assert_no_error (error); - LockThreadData thread_data = {repo1, 0}; + LockThreadData thread_data = { repo1, 0 }; GThread *thread1 = g_thread_new ("lock-thread-1", lock_thread1, &thread_data); GThread *thread2 = g_thread_new ("lock-thread-2", lock_thread2, &thread_data); @@ -566,36 +542,29 @@ test_repo_lock_multi_thread (Fixture *fixture, } int -main (int argc, - char **argv) +main (int argc, char **argv) { setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); - g_test_add ("/repo/hash", Fixture, NULL, setup, - test_repo_hash, teardown); - g_test_add ("/repo/hash/closed", Fixture, NULL, setup, - test_repo_hash_closed, teardown); - g_test_add ("/repo/equal", Fixture, NULL, setup, - test_repo_equal, teardown); - g_test_add ("/repo/get_min_free_space", Fixture, NULL, setup, - test_repo_get_min_free_space, teardown); - g_test_add ("/repo/write_regfile_api", Fixture, NULL, setup, - test_write_regfile_api, teardown); - g_test_add ("/repo/autolock", Fixture, NULL, setup, - test_repo_autolock, teardown); - g_test_add ("/repo/lock/single", Fixture, NULL, lock_setup, - test_repo_lock_single, teardown); + g_test_add ("/repo/hash", Fixture, NULL, setup, test_repo_hash, teardown); + g_test_add ("/repo/hash/closed", Fixture, NULL, setup, test_repo_hash_closed, teardown); + g_test_add ("/repo/equal", Fixture, NULL, setup, test_repo_equal, teardown); + g_test_add ("/repo/get_min_free_space", Fixture, NULL, setup, test_repo_get_min_free_space, + teardown); + g_test_add ("/repo/write_regfile_api", Fixture, NULL, setup, test_write_regfile_api, teardown); + g_test_add ("/repo/autolock", Fixture, NULL, setup, test_repo_autolock, teardown); + g_test_add ("/repo/lock/single", Fixture, NULL, lock_setup, test_repo_lock_single, teardown); g_test_add ("/repo/lock/unlock-never-locked", Fixture, NULL, lock_setup, test_repo_lock_unlock_never_locked, teardown); - g_test_add ("/repo/lock/double-unlock", Fixture, NULL, lock_setup, - test_repo_lock_double_unlock, teardown); + g_test_add ("/repo/lock/double-unlock", Fixture, NULL, lock_setup, test_repo_lock_double_unlock, + teardown); g_test_add ("/repo/lock/unlock-wrong-type", Fixture, NULL, lock_setup, test_repo_lock_unlock_wrong_type, teardown); - g_test_add ("/repo/lock/multi-repo", Fixture, NULL, lock_setup, - test_repo_lock_multi_repo, teardown); - g_test_add ("/repo/lock/multi-thread", Fixture, NULL, lock_setup, - test_repo_lock_multi_thread, teardown); + g_test_add ("/repo/lock/multi-repo", Fixture, NULL, lock_setup, test_repo_lock_multi_repo, + teardown); + g_test_add ("/repo/lock/multi-thread", Fixture, NULL, lock_setup, test_repo_lock_multi_thread, + teardown); return g_test_run (); } diff --git a/tests/test-rfc2616-dates.c b/tests/test-rfc2616-dates.c index 55807f1..a47bca8 100644 --- a/tests/test-rfc2616-dates.c +++ b/tests/test-rfc2616-dates.c @@ -30,58 +30,57 @@ static void test_ostree_parse_rfc2616_date_time (void) { #if GLIB_CHECK_VERSION(2, 62, 0) -G_GNUC_BEGIN_IGNORE_DEPRECATIONS + G_GNUC_BEGIN_IGNORE_DEPRECATIONS const struct - { - const char *rfc2616; - const char *expected_iso8601; /* (nullable) if parsing is expected to fail */ - } - tests[] = - { - { "Wed, 21 Oct 2015 07:28:00 GMT", "2015-10-21T07:28:00Z" }, - { "Wed, 21 Oct 2015 07:28:00", NULL }, /* too short */ - { "Wed, 21 Oct 2015 07:28:00 CEST", NULL }, /* too long; not GMT */ - { "Cat, 21 Oct 2015 07:28:00 GMT", NULL }, /* invalid day */ - { "Wed 21 Oct 2015 07:28:00 GMT", NULL }, /* no comma */ - { "Wed,21 Oct 2015 07:28:00 GMT ", NULL }, /* missing space */ - { "Wed, xx Oct 2015 07:28:00 GMT", NULL }, /* no day-of-month */ - { "Wed, 011Oct 2015 07:28:00 GMT", NULL }, /* overlong day-of-month */ - { "Wed, 00 Oct 2015 07:28:00 GMT", NULL }, /* day-of-month underflow */ - { "Wed, 32 Oct 2015 07:28:00 GMT", NULL }, /* day-of-month overflow */ - { "Wed, 21,Oct 2015 07:28:00 GMT", NULL }, /* missing space */ - { "Wed, 21 Cat 2015 07:28:00 GMT", NULL }, /* invalid month */ - { "Wed, 21 Oct,2015 07:28:00 GMT", NULL }, /* missing space */ - { "Wed, 21 Oct xxxx 07:28:00 GMT", NULL }, /* no year */ - { "Wed, 21 Oct 0201507:28:00 GMT", NULL }, /* overlong year */ - { "Wed, 21 Oct 0000 07:28:00 GMT", NULL }, /* year underflow */ - { "Wed, 21 Oct 10000 07:28:00 GM", NULL }, /* year overflow */ - { "Wed, 21 Oct 2015,07:28:00 GMT", NULL }, /* missing space */ - { "Wed, 21 Oct 2015 07 28:00 GMT", NULL }, /* missing colon */ - { "Wed, 21 Oct 2015 007:28:00 GM", NULL }, /* overlong hour */ - { "Wed, 21 Oct 2015 xx:28:00 GMT", NULL }, /* missing hour */ - { "Wed, 21 Oct 2015 -1:28:00 GMT", NULL }, /* hour underflow */ - { "Wed, 21 Oct 2015 24:28:00 GMT", NULL }, /* hour overflow */ - { "Wed, 21 Oct 2015 07:28 00 GMT", NULL }, /* missing colon */ - { "Wed, 21 Oct 2015 07:028:00 GM", NULL }, /* overlong minute */ - { "Wed, 21 Oct 2015 07:xx:00 GMT", NULL }, /* missing minute */ - { "Wed, 21 Oct 2015 07:-1:00 GMT", NULL }, /* minute underflow */ - { "Wed, 21 Oct 2015 07:60:00 GMT", NULL }, /* minute overflow */ - { "Wed, 21 Oct 2015 07:28:00CEST", NULL }, /* missing space */ - { "Wed, 21 Oct 2015 07:28:000 GM", NULL }, /* overlong second */ - { "Wed, 21 Oct 2015 07:28:xx GMT", NULL }, /* missing second */ - { "Wed, 21 Oct 2015 07:28:-1 GMT", NULL }, /* seconds underflow */ - { "Wed, 21 Oct 2015 07:28:61 GMT", NULL }, /* seconds overflow */ - { "Wed, 21 Oct 2015 07:28:00 UTC", NULL }, /* invalid timezone (only GMT is allowed) */ - { "Thu, 01 Jan 1970 00:00:00 GMT", "1970-01-01T00:00:00Z" }, /* extreme but valid date */ - { "Mon, 31 Dec 9999 23:59:59 GMT", "9999-12-31T23:59:59Z" }, /* extreme but valid date */ - }; + { + const char *rfc2616; + const char *expected_iso8601; /* (nullable) if parsing is expected to fail */ + } tests[] = { + { "Wed, 21 Oct 2015 07:28:00 GMT", "2015-10-21T07:28:00Z" }, + { "Wed, 21 Oct 2015 07:28:00", NULL }, /* too short */ + { "Wed, 21 Oct 2015 07:28:00 CEST", NULL }, /* too long; not GMT */ + { "Cat, 21 Oct 2015 07:28:00 GMT", NULL }, /* invalid day */ + { "Wed 21 Oct 2015 07:28:00 GMT", NULL }, /* no comma */ + { "Wed,21 Oct 2015 07:28:00 GMT ", NULL }, /* missing space */ + { "Wed, xx Oct 2015 07:28:00 GMT", NULL }, /* no day-of-month */ + { "Wed, 011Oct 2015 07:28:00 GMT", NULL }, /* overlong day-of-month */ + { "Wed, 00 Oct 2015 07:28:00 GMT", NULL }, /* day-of-month underflow */ + { "Wed, 32 Oct 2015 07:28:00 GMT", NULL }, /* day-of-month overflow */ + { "Wed, 21,Oct 2015 07:28:00 GMT", NULL }, /* missing space */ + { "Wed, 21 Cat 2015 07:28:00 GMT", NULL }, /* invalid month */ + { "Wed, 21 Oct,2015 07:28:00 GMT", NULL }, /* missing space */ + { "Wed, 21 Oct xxxx 07:28:00 GMT", NULL }, /* no year */ + { "Wed, 21 Oct 0201507:28:00 GMT", NULL }, /* overlong year */ + { "Wed, 21 Oct 0000 07:28:00 GMT", NULL }, /* year underflow */ + { "Wed, 21 Oct 10000 07:28:00 GM", NULL }, /* year overflow */ + { "Wed, 21 Oct 2015,07:28:00 GMT", NULL }, /* missing space */ + { "Wed, 21 Oct 2015 07 28:00 GMT", NULL }, /* missing colon */ + { "Wed, 21 Oct 2015 007:28:00 GM", NULL }, /* overlong hour */ + { "Wed, 21 Oct 2015 xx:28:00 GMT", NULL }, /* missing hour */ + { "Wed, 21 Oct 2015 -1:28:00 GMT", NULL }, /* hour underflow */ + { "Wed, 21 Oct 2015 24:28:00 GMT", NULL }, /* hour overflow */ + { "Wed, 21 Oct 2015 07:28 00 GMT", NULL }, /* missing colon */ + { "Wed, 21 Oct 2015 07:028:00 GM", NULL }, /* overlong minute */ + { "Wed, 21 Oct 2015 07:xx:00 GMT", NULL }, /* missing minute */ + { "Wed, 21 Oct 2015 07:-1:00 GMT", NULL }, /* minute underflow */ + { "Wed, 21 Oct 2015 07:60:00 GMT", NULL }, /* minute overflow */ + { "Wed, 21 Oct 2015 07:28:00CEST", NULL }, /* missing space */ + { "Wed, 21 Oct 2015 07:28:000 GM", NULL }, /* overlong second */ + { "Wed, 21 Oct 2015 07:28:xx GMT", NULL }, /* missing second */ + { "Wed, 21 Oct 2015 07:28:-1 GMT", NULL }, /* seconds underflow */ + { "Wed, 21 Oct 2015 07:28:61 GMT", NULL }, /* seconds overflow */ + { "Wed, 21 Oct 2015 07:28:00 UTC", NULL }, /* invalid timezone (only GMT is allowed) */ + { "Thu, 01 Jan 1970 00:00:00 GMT", "1970-01-01T00:00:00Z" }, /* extreme but valid date */ + { "Mon, 31 Dec 9999 23:59:59 GMT", "9999-12-31T23:59:59Z" }, /* extreme but valid date */ + }; for (gsize i = 0; i < G_N_ELEMENTS (tests); i++) { g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, tests[i].rfc2616); /* Parse once with a trailing nul */ - g_autoptr(GDateTime) dt1 = _ostree_parse_rfc2616_date_time (tests[i].rfc2616, strlen (tests[i].rfc2616)); + g_autoptr (GDateTime) dt1 + = _ostree_parse_rfc2616_date_time (tests[i].rfc2616, strlen (tests[i].rfc2616)); if (tests[i].expected_iso8601 == NULL) g_assert_null (dt1); else @@ -94,7 +93,8 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS /* And parse again with no trailing nul */ g_autofree char *rfc2616_no_nul = g_malloc (strlen (tests[i].rfc2616)); memcpy (rfc2616_no_nul, tests[i].rfc2616, strlen (tests[i].rfc2616)); - g_autoptr(GDateTime) dt2 = _ostree_parse_rfc2616_date_time (rfc2616_no_nul, strlen (tests[i].rfc2616)); + g_autoptr (GDateTime) dt2 + = _ostree_parse_rfc2616_date_time (rfc2616_no_nul, strlen (tests[i].rfc2616)); if (tests[i].expected_iso8601 == NULL) g_assert_null (dt2); else @@ -104,7 +104,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS g_assert_cmpstr (iso8601, ==, tests[i].expected_iso8601); } } -G_GNUC_END_IGNORE_DEPRECATIONS + G_GNUC_END_IGNORE_DEPRECATIONS #else /* GLib 2.62 is needed for g_date_time_format_iso8601(). */ g_test_skip ("RFC 2616 date parsing test needs GLib ≥ 2.62.0"); @@ -112,8 +112,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS } int -main (int argc, - char **argv) +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/ostree_parse_rfc2616_date_time", test_ostree_parse_rfc2616_date_time); diff --git a/tests/test-rollsum-cli.c b/tests/test-rollsum-cli.c index 2cf730d..f906e99 100644 --- a/tests/test-rollsum-cli.c +++ b/tests/test-rollsum-cli.c @@ -26,7 +26,7 @@ int main (int argc, char **argv) { - g_autoptr(GError) local_error = NULL; + g_autoptr (GError) local_error = NULL; GError **error = &local_error; GBytes *from_bytes = NULL; GBytes *to_bytes = NULL; @@ -57,12 +57,10 @@ main (int argc, char **argv) matches = _ostree_compute_rollsum_matches (from_bytes, to_bytes); - g_printerr ("rollsum crcs=%u bufs=%u total=%u matchsize=%llu\n", - matches->crcmatches, - matches->bufmatches, - matches->total, (unsigned long long)matches->match_size); + g_printerr ("rollsum crcs=%u bufs=%u total=%u matchsize=%llu\n", matches->crcmatches, + matches->bufmatches, matches->total, (unsigned long long)matches->match_size); - out: +out: if (local_error) { g_printerr ("%s\n", local_error->message); diff --git a/tests/test-rollsum.c b/tests/test-rollsum.c index 57f7aa0..a454e62 100644 --- a/tests/test-rollsum.c +++ b/tests/test-rollsum.c @@ -19,22 +19,23 @@ #include "config.h" -#include "libglnx.h" #include "bsdiff/bsdiff.h" #include "bsdiff/bspatch.h" +#include "bupsplit.h" +#include "libglnx.h" +#include "ostree-rollsum.h" +#include #include #include -#include #include -#include "ostree-rollsum.h" -#include "bupsplit.h" static void -test_rollsum_helper (const unsigned char *a, gsize size_a, const unsigned char *b, gsize size_b, gboolean expected_match) +test_rollsum_helper (const unsigned char *a, gsize size_a, const unsigned char *b, gsize size_b, + gboolean expected_match) { gsize i; - g_autoptr(GBytes) bytes_a = g_bytes_new_static (a, size_a); - g_autoptr(GBytes) bytes_b = g_bytes_new_static (b, size_b); + g_autoptr (GBytes) bytes_a = g_bytes_new_static (a, size_a); + g_autoptr (GBytes) bytes_b = g_bytes_new_static (b, size_b); OstreeRollsumMatches *matches; GPtrArray *matchlist; guint64 sum_matched = 0; @@ -75,16 +76,34 @@ test_rollsum (void) int len; g_autofree unsigned char *a = g_malloc (MAX_BUFFER_SIZE); g_autofree unsigned char *b = g_malloc (MAX_BUFFER_SIZE); - g_autoptr(GRand) rand = g_rand_new (); + g_autoptr (GRand) rand = g_rand_new (); /* These two buffers produce the same crc32. */ - const unsigned char conflicting_a[] = {0x35, 0x9b, 0x94, 0x5a, 0xa0, 0x5a, 0x34, 0xdc, 0x5c, 0x3, 0x46, 0xe, 0x34, 0x53, 0x85, 0x73, 0x64, 0xcc, 0x47, 0x10, 0x23, 0x8e, 0x7e, 0x6a, 0xca, 0xda, 0x7c, 0x12, 0x8a, 0x59, 0x7f, 0x7f, 0x4d, 0x1, 0xd8, 0xcc, 0x81, 0xcf, 0x2c, 0x7f, 0x10, 0xc2, 0xb4, 0x40, 0x1f, 0x2a, 0x0, 0x37, 0x85, 0xde, 0xfe, 0xa5, 0xc, 0x7c, 0xa1, 0x8, 0xd6, 0x75, 0xfd, 0x2, 0xcf, 0x2d, 0x53, 0x1b, 0x8a, 0x6b, 0x35, 0xad, 0xa, 0x8f, 0xad, 0x2d, 0x91, 0x87, 0x2b, 0x97, 0xcf, 0x1d, 0x7c, 0x61, 0xc4, 0xb2, 0x5e, 0xc3, 0xba, 0x5d, 0x2f, 0x3a, 0xeb, 0x41, 0x61, 0x4c, 0xa2, 0x34, 0xd, 0x43, 0xce, 0x10, 0xa3, 0x47, 0x4, 0xa0, 0x39, 0x77, 0xc2, 0xe8, 0x36, 0x1d, 0x87, 0xd1, 0x8f, 0x4d, 0x13, 0xa1, 0x34, 0xc3, 0x2c, 0xee, 0x1a, 0x10, 0x79, 0xb7, 0x97, 0x29, 0xe8, 0xf0, 0x5, 0xfc, 0xe6, 0x14, 0x87, 0x9c, 0x8f, 0x97, 0x23, 0xac, 0x1, 0xf2, 0xee, 0x69, 0xb2, 0xe5}; - - const unsigned char conflicting_b[] = {0xb2, 0x54, 0x81, 0x7d, 0x31, 0x83, 0xc7, 0xc, 0xcf, 0x7d, 0x90, 0x1c, 0x6b, 0xf6, 0x4e, 0xff, 0x49, 0xd1, 0xb6, 0xc, 0x9e, 0x85, 0xe3, 0x2d, 0xdb, 0x94, 0x8e, 0x1a, 0x17, 0x3f, 0x63, 0x59, 0xf9, 0x4b, 0x5f, 0x47, 0x97, 0x9c, 0x1c, 0xd7, 0x24, 0xd9, 0x42, 0x6, 0x1e, 0xf, 0x98, 0x10, 0xb4, 0xc, 0x50, 0xcb, 0xc5, 0x62, 0x53, 0x1, 0xd1, 0x5f, 0x16, 0x97, 0xaa, 0xd7, 0x57, 0x5e, 0xf2, 0xde, 0xae, 0x53, 0x58, 0x6, 0xb7, 0x9b, 0x8d, 0x2b, 0xd6, 0xb4, 0x55, 0x29, 0x3b, 0x27, 0x70, 0xd5, 0xf3, 0x8d, 0xdc, 0xad, 0x68, 0x63, 0xa5, 0x72, 0xce, 0x6b, 0x9, 0x2b, 0x60, 0x1b, 0x99, 0xd7, 0x86}; + const unsigned char conflicting_a[] + = { 0x35, 0x9b, 0x94, 0x5a, 0xa0, 0x5a, 0x34, 0xdc, 0x5c, 0x3, 0x46, 0xe, 0x34, 0x53, 0x85, + 0x73, 0x64, 0xcc, 0x47, 0x10, 0x23, 0x8e, 0x7e, 0x6a, 0xca, 0xda, 0x7c, 0x12, 0x8a, 0x59, + 0x7f, 0x7f, 0x4d, 0x1, 0xd8, 0xcc, 0x81, 0xcf, 0x2c, 0x7f, 0x10, 0xc2, 0xb4, 0x40, 0x1f, + 0x2a, 0x0, 0x37, 0x85, 0xde, 0xfe, 0xa5, 0xc, 0x7c, 0xa1, 0x8, 0xd6, 0x75, 0xfd, 0x2, + 0xcf, 0x2d, 0x53, 0x1b, 0x8a, 0x6b, 0x35, 0xad, 0xa, 0x8f, 0xad, 0x2d, 0x91, 0x87, 0x2b, + 0x97, 0xcf, 0x1d, 0x7c, 0x61, 0xc4, 0xb2, 0x5e, 0xc3, 0xba, 0x5d, 0x2f, 0x3a, 0xeb, 0x41, + 0x61, 0x4c, 0xa2, 0x34, 0xd, 0x43, 0xce, 0x10, 0xa3, 0x47, 0x4, 0xa0, 0x39, 0x77, 0xc2, + 0xe8, 0x36, 0x1d, 0x87, 0xd1, 0x8f, 0x4d, 0x13, 0xa1, 0x34, 0xc3, 0x2c, 0xee, 0x1a, 0x10, + 0x79, 0xb7, 0x97, 0x29, 0xe8, 0xf0, 0x5, 0xfc, 0xe6, 0x14, 0x87, 0x9c, 0x8f, 0x97, 0x23, + 0xac, 0x1, 0xf2, 0xee, 0x69, 0xb2, 0xe5 }; + + const unsigned char conflicting_b[] + = { 0xb2, 0x54, 0x81, 0x7d, 0x31, 0x83, 0xc7, 0xc, 0xcf, 0x7d, 0x90, 0x1c, 0x6b, 0xf6, 0x4e, + 0xff, 0x49, 0xd1, 0xb6, 0xc, 0x9e, 0x85, 0xe3, 0x2d, 0xdb, 0x94, 0x8e, 0x1a, 0x17, 0x3f, + 0x63, 0x59, 0xf9, 0x4b, 0x5f, 0x47, 0x97, 0x9c, 0x1c, 0xd7, 0x24, 0xd9, 0x42, 0x6, 0x1e, + 0xf, 0x98, 0x10, 0xb4, 0xc, 0x50, 0xcb, 0xc5, 0x62, 0x53, 0x1, 0xd1, 0x5f, 0x16, 0x97, + 0xaa, 0xd7, 0x57, 0x5e, 0xf2, 0xde, 0xae, 0x53, 0x58, 0x6, 0xb7, 0x9b, 0x8d, 0x2b, 0xd6, + 0xb4, 0x55, 0x29, 0x3b, 0x27, 0x70, 0xd5, 0xf3, 0x8d, 0xdc, 0xad, 0x68, 0x63, 0xa5, 0x72, + 0xce, 0x6b, 0x9, 0x2b, 0x60, 0x1b, 0x99, 0xd7, 0x86 }; + + test_rollsum_helper (conflicting_a, sizeof conflicting_a, conflicting_b, sizeof conflicting_b, + FALSE); - test_rollsum_helper (conflicting_a, sizeof conflicting_a, conflicting_b, sizeof conflicting_b, FALSE); - - for (i = 0; i < MAX_BUFFER_SIZE; i++) + for (i = 0; i < MAX_BUFFER_SIZE; i++) { a[i] = g_rand_int (rand); b[i] = a[i]; @@ -139,32 +158,33 @@ test_rollsum (void) #define BUP_SELFTEST_SIZE 100000 static void -test_bupsplit_sum(void) +test_bupsplit_sum (void) { - g_autofree uint8_t *buf = g_malloc (BUP_SELFTEST_SIZE); - uint32_t sum1a, sum1b, sum2a, sum2b, sum3a, sum3b; - unsigned count; - - for (count = 0; count < BUP_SELFTEST_SIZE; count++) - buf[count] = g_random_int_range (0, 256); - - sum1a = bupsplit_sum(buf, 0, BUP_SELFTEST_SIZE); - sum1b = bupsplit_sum(buf, 1, BUP_SELFTEST_SIZE); - sum2a = bupsplit_sum(buf, BUP_SELFTEST_SIZE - BUP_WINDOWSIZE*5/2, - BUP_SELFTEST_SIZE - BUP_WINDOWSIZE); - sum2b = bupsplit_sum(buf, 0, BUP_SELFTEST_SIZE - BUP_WINDOWSIZE); - sum3a = bupsplit_sum(buf, 0, BUP_WINDOWSIZE+3); - sum3b = bupsplit_sum(buf, 3, BUP_WINDOWSIZE+3); - - g_assert_cmpint (sum1a, ==, sum1b); - g_assert_cmpint (sum2a, ==, sum2b); - g_assert_cmpint (sum3a, ==, sum3b); + g_autofree uint8_t *buf = g_malloc (BUP_SELFTEST_SIZE); + uint32_t sum1a, sum1b, sum2a, sum2b, sum3a, sum3b; + unsigned count; + + for (count = 0; count < BUP_SELFTEST_SIZE; count++) + buf[count] = g_random_int_range (0, 256); + + sum1a = bupsplit_sum (buf, 0, BUP_SELFTEST_SIZE); + sum1b = bupsplit_sum (buf, 1, BUP_SELFTEST_SIZE); + sum2a = bupsplit_sum (buf, BUP_SELFTEST_SIZE - BUP_WINDOWSIZE * 5 / 2, + BUP_SELFTEST_SIZE - BUP_WINDOWSIZE); + sum2b = bupsplit_sum (buf, 0, BUP_SELFTEST_SIZE - BUP_WINDOWSIZE); + sum3a = bupsplit_sum (buf, 0, BUP_WINDOWSIZE + 3); + sum3b = bupsplit_sum (buf, 3, BUP_WINDOWSIZE + 3); + + g_assert_cmpint (sum1a, ==, sum1b); + g_assert_cmpint (sum2a, ==, sum2b); + g_assert_cmpint (sum3a, ==, sum3b); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/rollsum", test_rollsum); g_test_add_func ("/bupsum", test_bupsplit_sum); - return g_test_run(); + return g_test_run (); } diff --git a/tests/test-signed-commit.sh b/tests/test-signed-commit.sh index 47aba39..432687d 100755 --- a/tests/test-signed-commit.sh +++ b/tests/test-signed-commit.sh @@ -75,12 +75,10 @@ fi # Test ostree sign with 'ed25519' module gen_ed25519_keys PUBLIC=${ED25519PUBLIC} -SEED=${ED25519SEED} SECRET=${ED25519SECRET} WRONG_PUBLIC="$(gen_ed25519_random_public)" -echo "SEED = $SEED" echo "PUBLIC = $PUBLIC" echo "Signed commit with ed25519: ${SECRET}" >> file.txt diff --git a/tests/test-signed-pull-summary.sh b/tests/test-signed-pull-summary.sh index 2d6b255..d287389 100755 --- a/tests/test-signed-pull-summary.sh +++ b/tests/test-signed-pull-summary.sh @@ -194,6 +194,16 @@ assert_file_has_content summary.txt "* yet-another" grep static-deltas summary.txt > static-deltas.txt assert_file_has_content static-deltas.txt \ $(${OSTREE} --repo=repo rev-parse origin:main) +${OSTREE} --repo=repo remote summary origin --list-metadata-keys > metadata +assert_file_has_content metadata "^ostree.static-deltas$" +assert_file_has_content metadata "^ostree.summary.indexed-deltas$" +assert_file_has_content metadata "^ostree.summary.last-modified$" +assert_file_has_content metadata "^ostree.summary.mode$" +assert_file_has_content metadata "^ostree.summary.tombstone-commits$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.indexed-deltas > metadata +assert_file_has_content metadata "^true$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.mode > metadata +assert_file_has_content metadata "^'archive-z2'$" ## Tests for handling of cached summaries while racing with remote summary updates diff --git a/tests/test-signed-pull.sh b/tests/test-signed-pull.sh index 372287f..5754914 100755 --- a/tests/test-signed-pull.sh +++ b/tests/test-signed-pull.sh @@ -155,10 +155,10 @@ fi # Test ostree sign with 'ed25519' module gen_ed25519_keys PUBLIC=${ED25519PUBLIC} -SEED=${ED25519SEED} SECRET=${ED25519SECRET} - -COMMIT_ARGS="--sign=${SECRET} --sign-type=ed25519" +# Other tests verify --sign, we will verify --sign-from-file here +echo ${ED25519SECRET} > key +COMMIT_ARGS="--sign-from-file=key --sign-type=ed25519" repo_init --set=sign-verify=true ${CMD_PREFIX} ostree --repo=repo config set 'remote "origin"'.verification-ed25519-key "${PUBLIC}" diff --git a/tests/test-summary-update.sh b/tests/test-summary-update.sh index 74c42d1..d85e9c4 100755 --- a/tests/test-summary-update.sh +++ b/tests/test-summary-update.sh @@ -59,6 +59,10 @@ ${CMD_PREFIX} ostree --repo=repo summary --update --add-metadata=map='@a{sv} {}' # Check the additional metadata turns up in the output. ${CMD_PREFIX} ostree --repo=repo summary --view > summary assert_file_has_content summary "^map: {}$" +${CMD_PREFIX} ostree --repo=repo summary --list-metadata-keys > metadata +assert_file_has_content metadata "^map$" +${CMD_PREFIX} ostree --repo=repo summary --print-metadata-key=map > metadata +assert_file_has_content metadata "^@a{sv} {}$" echo "ok 1 update summary" diff --git a/tests/test-symbols.sh b/tests/test-symbols.sh index a888ef3..f9b8f81 100755 --- a/tests/test-symbols.sh +++ b/tests/test-symbols.sh @@ -54,7 +54,7 @@ echo 'ok documented symbols' # ONLY update this checksum in release commits! cat > released-sha256.txt < #include +#include #include #include "libglnx.h" @@ -40,8 +40,8 @@ run_sync (const char *cmdline, GError **error) static void test_sysroot_reload (gconstpointer data) { - OstreeSysroot *sysroot = (void*)data; - g_autoptr(GError) error = NULL; + OstreeSysroot *sysroot = (void *)data; + g_autoptr (GError) error = NULL; gboolean changed; if (!ostree_sysroot_load (sysroot, NULL, &error)) @@ -51,10 +51,14 @@ test_sysroot_reload (gconstpointer data) goto out; g_assert (!changed); - if (!run_sync ("ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime", &error)) + if (!run_sync ("ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo " + "testos/buildmain/x86_64-runtime", + &error)) goto out; - if (!run_sync ("ostree admin --sysroot=sysroot deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmain/x86_64-runtime", &error)) + if (!run_sync ("ostree admin --sysroot=sysroot deploy --karg=root=LABEL=MOO --karg=quiet " + "--os=testos testos:testos/buildmain/x86_64-runtime", + &error)) goto out; if (!ostree_sysroot_load_if_changed (sysroot, &changed, NULL, &error)) @@ -65,26 +69,27 @@ test_sysroot_reload (gconstpointer data) goto out; g_assert (!changed); - out: +out: if (error) g_error ("%s", error->message); } -int main (int argc, char **argv) +int +main (int argc, char **argv) { - g_autoptr(GError) error = NULL; + g_autoptr (GError) error = NULL; glnx_unref_object OstreeSysroot *sysroot = NULL; g_test_init (&argc, &argv, NULL); - sysroot = ot_test_setup_sysroot (NULL, &error); + sysroot = ot_test_setup_sysroot (NULL, &error); if (!sysroot) goto out; - + g_test_add_data_func ("/sysroot-reload", sysroot, test_sysroot_reload); - return g_test_run(); - out: + return g_test_run (); +out: if (error) g_error ("%s", error->message); return 1; diff --git a/tests/test-varint.c b/tests/test-varint.c index 3fea805..9c42f64 100644 --- a/tests/test-varint.c +++ b/tests/test-varint.c @@ -24,20 +24,21 @@ #include "ostree-varint.h" static void -check_one_roundtrip (guint64 val) +check_one_roundtrip (guint64 val) { - g_autoptr(GString) buf = g_string_new (NULL); + g_autoptr (GString) buf = g_string_new (NULL); guint64 newval; gsize bytes_read; _ostree_write_varuint64 (buf, val); if (g_test_verbose ()) { - g_autoptr(GVariant) v = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), buf->str, buf->len, TRUE, NULL, NULL); + g_autoptr (GVariant) v + = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), buf->str, buf->len, TRUE, NULL, NULL); g_autofree char *data = g_variant_print (v, FALSE); g_test_message ("%" G_GUINT64_FORMAT " -> %s", val, data); } - g_assert (_ostree_read_varuint64 ((guint8*)buf->str, buf->len, &newval, &bytes_read)); + g_assert (_ostree_read_varuint64 ((guint8 *)buf->str, buf->len, &newval, &bytes_read)); g_assert_cmpint (bytes_read, <=, 10); g_assert_cmpint (val, ==, newval); } @@ -45,9 +46,17 @@ check_one_roundtrip (guint64 val) static void test_roundtrips (void) { - const guint64 test_inputs[] = { 0, 1, 0x6F, 0xA0, 0xFF, 0xF0F0, 0xCAFE, - 0xCAFEBABE, G_MAXUINT64, G_MAXUINT64-1, - G_MAXUINT64 / 2}; + const guint64 test_inputs[] = { 0, + 1, + 0x6F, + 0xA0, + 0xFF, + 0xF0F0, + 0xCAFE, + 0xCAFEBABE, + G_MAXUINT64, + G_MAXUINT64 - 1, + G_MAXUINT64 / 2 }; guint i; for (i = 0; i < G_N_ELEMENTS (test_inputs); i++)