Baseline synchonization or audit.

        Both functions implemented in this routine because audit is a prerequisite
        for a baseline sync. In the case of baseline sync the last timestamp seen
        is recorded as client state.

def baseline_or_audit(self, allow_deletion=False, audit_only=False):
        """Baseline synchonization or audit.

        Both functions implemented in this routine because audit is a prerequisite
        for a baseline sync. In the case of baseline sync the last timestamp seen
        is recorded as client state.
        """
        action = ('audit' if (audit_only) else 'baseline sync')
        self.logger.debug("Starting " + action)
        # 0. Sanity checks
        if (len(self.mapper) < 1):
            raise ClientFatalError(
                "No source to destination mapping specified")
        if (not audit_only and self.mapper.unsafe()):
            raise ClientFatalError(
                "Source to destination mappings unsafe: %s" %
                str(self.mapper))
        # 1. Get inventories from both src and dst
        # 1.a source resource list
        src_resource_list = self.find_resource_list()
        self.logger.info(
            "Read source resource list, %d resources listed" %
            (len(src_resource_list)))
        if (len(src_resource_list) == 0):
            raise ClientFatalError(
                "Aborting as there are no resources to sync")
        if (len(self.hashes) > 0):
            self.prune_hashes(src_resource_list.hashes(), 'resource')
        # 1.b destination resource list mapped back to source URIs
        rlb = ResourceListBuilder(set_hashes=self.hashes, mapper=self.mapper)
        dst_resource_list = rlb.from_disk()
        # 2. Compare these resource lists respecting any comparison options
        (same, updated, deleted, created) = dst_resource_list.compare(src_resource_list)
        # 3. Report status and planned actions
        self.log_status(in_sync=(len(updated) + len(deleted) + len(created) == 0),
                        audit=True, same=len(same), created=len(created),
                        updated=len(updated), deleted=len(deleted))
        if (audit_only or len(created) + len(updated) + len(deleted) == 0):
            self.logger.debug("Completed " + action)
            return
        # 4. Check that sitemap has authority over URIs listed
        if (not self.noauth):
            uauth = UrlAuthority(self.sitemap, strict=self.strictauth)
            for resource in src_resource_list:
                if (not uauth.has_authority_over(resource.uri)):
                    raise ClientFatalError(
                        "Aborting as sitemap (%s) mentions resource at a location it does not have authority over (%s), override with --noauth" %
                        (self.sitemap, resource.uri))
        # 5. Grab files to do sync
        delete_msg = (
            ", and delete %d resources" %
            len(deleted)) if (allow_deletion) else ''
        self.logger.warning(
            "Will GET %d resources%s" %
            (len(created) + len(updated), delete_msg))
        self.last_timestamp = 0
        num_created = 0
        num_updated = 0
        num_deleted = 0
        for resource in created:
            uri = resource.uri
            filename = self.mapper.src_to_dst(uri)
            self.logger.info("created: %s -> %s" % (uri, filename))
            num_created += self.update_resource(resource, filename, 'created')
        for resource in updated:
            uri = resource.uri
            filename = self.mapper.src_to_dst(uri)
            self.logger.info("updated: %s -> %s" % (uri, filename))
            num_updated += self.update_resource(resource, filename, 'updated')
        for resource in deleted:
            uri = resource.uri
            filename = self.mapper.src_to_dst(uri)
            num_deleted += self.delete_resource(resource,
                                                filename, allow_deletion)
        # 6. Store last timestamp to allow incremental sync
        if (not audit_only and self.last_timestamp > 0):
            ClientState().set_state(self.sitemap, self.last_timestamp)
            self.logger.info(
                "Written last timestamp %s for incremental sync" %
                (datetime_to_str(
                    self.last_timestamp)))
        # 7. Done
        self.log_status(in_sync=(len(updated) + len(deleted) + len(created) == 0),
                        same=len(same), created=num_created,
                        updated=num_updated, deleted=num_deleted, to_delete=len(deleted))
        self.logger.debug("Completed %s" % (action))