Exemple #1
0
def infocalypse_setupwot(ui_, **opts):
    if not opts['truster']:
        raise util.Abort("Specify default truster with --truster")

    import wot
    from wot_id import Local_WoT_ID
    fcpopts = wot.get_fcpopts(fcphost=opts["fcphost"], fcpport=opts["fcpport"])
    wot.execute_setup_wot(ui_, Local_WoT_ID(opts['truster'], fcpopts=fcpopts))
Exemple #2
0
def infocalypse_setupwot(ui_, **opts):
    if not opts['truster']:
        raise util.Abort("Specify default truster with --truster")

    import wot
    from wot_id import Local_WoT_ID
    fcpopts = wot.get_fcpopts(fcphost=opts["fcphost"], fcpport=opts["fcpport"])
    wot.execute_setup_wot(ui_, Local_WoT_ID(opts['truster'], fcpopts=fcpopts))
Exemple #3
0
def infocalypse_check_notifications(ui, repo, **opts):
    import wot
    from wot_id import Local_WoT_ID
    if not opts['wot']:
        raise util.Abort("What ID do you want to check for notifications? Set"
                         " --wot.\n")

    fcpopts = wot.get_fcpopts(fcpport=opts["fcpport"], fcphost=opts["fcphost"])
    wot.check_notifications(ui, Local_WoT_ID(opts['wot'], fcpopts=fcpopts))
Exemple #4
0
def infocalypse_check_notifications(ui, repo, **opts):
    import wot
    from wot_id import Local_WoT_ID
    if not opts['wot']:
        raise util.Abort("What ID do you want to check for notifications? Set"
                         " --wot.\n")

    fcpopts = wot.get_fcpopts(fcpport=opts["fcpport"], fcphost=opts["fcphost"])
    wot.check_notifications(ui, Local_WoT_ID(opts['wot'], fcpopts=fcpopts))
Exemple #5
0
def infocalypse_update_repo_list(ui, **opts):
    if not opts['wot']:
        raise util.Abort("Update which repository list? Use --wot")

    import wot
    from wot_id import Local_WoT_ID
    wot.update_repo_listing(ui, Local_WoT_ID(opts['wot'], fcpopts=wot.get_fcpopts(
        fcphost=opts["fcphost"],
        fcpport=opts["fcpport"])), 
                            fcphost=opts["fcphost"],
                            fcpport=opts["fcpport"])
Exemple #6
0
def get_truster(ui,
                repo=None,
                truster_identifier=None,
                fcpport=None,
                fcphost=None):
    """
    Return a local WoT ID.

    Search for a local identity from most to least specific:
    1. truster_identifier (if given)
    2. identity that published this respository (if repo is given and an
                                                 identity is set)
    3. default truster

    TODO: Accept fcp port and fcp host parameters.

    :rtype : Local_WoT_ID
    """
    import wot
    import wot_id
    fcpopts = wot.get_fcpopts(fcphost=fcphost, fcpport=fcpport)
    if truster_identifier:
        return wot_id.Local_WoT_ID(truster_identifier, fcpopts=fcpopts)
    else:
        cfg = Config.from_ui(ui)

        # Value is identity ID, so '@' prefix makes it an identifier with an
        # empty nickname.
        identity = None
        default = False
        if repo:
            identity = cfg.get_wot_identity(cfg.get_request_uri(repo.root))

        # Either repo is not given or there is no associated identity.
        if not identity:
            identity = cfg.defaults['DEFAULT_TRUSTER']
            default = True

        try:
            return wot_id.Local_WoT_ID('@' + identity)
        except util.Abort:
            if default:
                raise util.Abort("Cannot resolve the default truster with "
                                 "public key hash '{0}'. Set it with hg"
                                 " fn-setupwot --truster".format(identity))
            else:
                # TODO: Is this suggestion appropriate?
                # TODO: Ensure that fn-create on an existing repo does not
                # leave isolated insert_usks or wot_identities entries in the
                # config file.
                raise util.Abort("Cannot resolve the identity with public key "
                                 "hash '{0}' that published this repository. "
                                 "To create this repository under a different "
                                 "identity run hg fn-create".format(identity))
Exemple #7
0
def infocalypse_update_repo_list(ui, **opts):
    if not opts['wot']:
        raise util.Abort("Update which repository list? Use --wot")

    import wot
    from wot_id import Local_WoT_ID
    wot.update_repo_listing(ui,
                            Local_WoT_ID(opts['wot'],
                                         fcpopts=wot.get_fcpopts(
                                             fcphost=opts["fcphost"],
                                             fcpport=opts["fcpport"])),
                            fcphost=opts["fcphost"],
                            fcpport=opts["fcpport"])
Exemple #8
0
def get_truster(ui, repo=None, truster_identifier=None, fcpport=None, fcphost=None):
    """
    Return a local WoT ID.

    Search for a local identity from most to least specific:
    1. truster_identifier (if given)
    2. identity that published this respository (if repo is given and an
                                                 identity is set)
    3. default truster

    TODO: Accept fcp port and fcp host parameters.

    :rtype : Local_WoT_ID
    """
    import wot
    import wot_id
    fcpopts = wot.get_fcpopts(fcphost=fcphost, fcpport=fcpport)
    if truster_identifier:
        return wot_id.Local_WoT_ID(truster_identifier, fcpopts=fcpopts)
    else:
        cfg = Config.from_ui(ui)

        # Value is identity ID, so '@' prefix makes it an identifier with an
        # empty nickname.
        identity = None
        default = False
        if repo:
            identity = cfg.get_wot_identity(cfg.get_request_uri(repo.root))

        # Either repo is not given or there is no associated identity.
        if not identity:
            identity = cfg.defaults['DEFAULT_TRUSTER']
            default = True

        try:
            return wot_id.Local_WoT_ID('@' + identity)
        except util.Abort:
            if default:
                raise util.Abort("Cannot resolve the default truster with "
                                 "public key hash '{0}'. Set it with hg"
                                 " fn-setupwot --truster".format(identity))
            else:
                # TODO: Is this suggestion appropriate?
                # TODO: Ensure that fn-create on an existing repo does not
                # leave isolated insert_usks or wot_identities entries in the
                # config file.
                raise util.Abort("Cannot resolve the identity with public key "
                                 "hash '{0}' that published this repository. "
                                 "To create this repository under a different "
                                 "identity run hg fn-create".format(identity))
Exemple #9
0
def infocalypse_create(ui_, repo, local_identity=None, **opts):
    """ Create a new Infocalypse repository in Freenet.
    :type local_identity: Local_WoT_ID
    :param local_identity: If specified the new repository is associated with
                           that identity.
    """
    params, stored_cfg = get_config_info(ui_, opts)

    if opts['uri'] and opts['wot']:
        ui_.warn("Please specify only one of --uri or --wot.\n")
        return
    elif opts['uri']:
        insert_uri = parse_repo_path(opts['uri'])
    elif opts['wot']:
        opts['wot'] = parse_repo_path(opts['wot'])
        nick_prefix, repo_name, repo_edition = opts['wot'].split('/', 2)

        if not repo_name.endswith('.R1') and not repo_name.endswith('.R0'):
            ui_.warn("Warning: Creating repository without redundancy. (R0 or"
                     " R1)\n")

        from wot_id import Local_WoT_ID

        local_identity = Local_WoT_ID(nick_prefix)

        insert_uri = local_identity.insert_uri.clone()

        insert_uri.name = repo_name
        insert_uri.edition = repo_edition
        # Before passing along into execute_create().
        insert_uri = str(insert_uri)
    else:
        ui_.warn("Please set the insert key with either --uri or --wot.\n")
        return

    # This is a WoT repository.
    if local_identity:
        # Prompt whether to replace in the case of conflicting names.
        from wot import build_repo_list

        request_usks = build_repo_list(ui_, local_identity)
        names = map(lambda x: USK(x).get_repo_name(), request_usks)
        new_name = USK(insert_uri).get_repo_name()

        if new_name in names:
            replace = ui_.prompt("A repository with the name '{0}' is already"
                                 " published by {1}. Replace it? [y/N]"
                                 .format(new_name, local_identity),
                                 default='n')

            if replace.lower() != 'y':
                raise util.Abort("A repository with this name already exists.")

            # Remove the existing repository from each configuration section.
            existing_usk = request_usks[names.index(new_name)]

            existing_dir = None
            for directory, request_usk in stored_cfg.request_usks.iteritems():
                if request_usk == existing_usk:
                    if existing_dir:
                        raise util.Abort("Configuration lists the same "
                                         "request USK multiple times.")
                    existing_dir = directory

            assert existing_dir

            existing_hash = normalize(existing_usk)

            # Config file changes will not be written until a successful insert
            # below.
            del stored_cfg.version_table[existing_hash]
            del stored_cfg.request_usks[existing_dir]
            del stored_cfg.insert_usks[existing_hash]
            del stored_cfg.wot_identities[existing_hash]

        # Add "vcs" context. No-op if the identity already has it.
        msg_params = {'Message': 'AddContext',
                      'Identity': local_identity.identity_id,
                      'Context': 'vcs'}

        import fcp
        import wot
        node = fcp.FCPNode(**wot.get_fcpopts(fcphost=opts["fcphost"],
                                             fcpport=opts["fcpport"]))
        atexit.register(node.shutdown)
        vcs_response =\
            node.fcpPluginMessage(plugin_name="plugins.WebOfTrust.WebOfTrust",
                                  plugin_params=msg_params)[0]

        if vcs_response['header'] != 'FCPPluginReply' or\
                'Replies.Message' not in vcs_response or\
                vcs_response['Replies.Message'] != 'ContextAdded':
            raise util.Abort("Failed to add context. Got {0}\n.".format(
                             vcs_response))

    set_target_version(ui_, repo, opts, params,
                       "Only inserting to version(s): %s\n")
    params['INSERT_URI'] = insert_uri
    inserted_to = execute_create(ui_, repo, params, stored_cfg)

    if inserted_to and local_identity:
        # creation returns a list of request URIs; use the first.
        stored_cfg.set_wot_identity(inserted_to[0], local_identity)
        Config.to_file(stored_cfg)

        import wot
        wot.update_repo_listing(ui_, local_identity, 
                                fcphost=opts["fcphost"],
                                fcpport=opts["fcpport"])
Exemple #10
0
def infocalypse_create(ui_, repo, local_identity=None, **opts):
    """ Create a new Infocalypse repository in Freenet.
    :type local_identity: Local_WoT_ID
    :param local_identity: If specified the new repository is associated with
                           that identity.
    """
    params, stored_cfg = get_config_info(ui_, opts)

    if opts['uri'] and opts['wot']:
        ui_.warn("Please specify only one of --uri or --wot.\n")
        return
    elif opts['uri']:
        insert_uri = parse_repo_path(opts['uri'])
    elif opts['wot']:
        opts['wot'] = parse_repo_path(opts['wot'])
        nick_prefix, repo_name, repo_edition = opts['wot'].split('/', 2)

        if not repo_name.endswith('.R1') and not repo_name.endswith('.R0'):
            ui_.warn("Warning: Creating repository without redundancy. (R0 or"
                     " R1)\n")

        from wot_id import Local_WoT_ID

        local_identity = Local_WoT_ID(nick_prefix)

        insert_uri = local_identity.insert_uri.clone()

        insert_uri.name = repo_name
        insert_uri.edition = repo_edition
        # Before passing along into execute_create().
        insert_uri = str(insert_uri)
    else:
        ui_.warn("Please set the insert key with either --uri or --wot.\n")
        return

    # This is a WoT repository.
    if local_identity:
        # Prompt whether to replace in the case of conflicting names.
        from wot import build_repo_list

        request_usks = build_repo_list(ui_, local_identity)
        names = map(lambda x: USK(x).get_repo_name(), request_usks)
        new_name = USK(insert_uri).get_repo_name()

        if new_name in names:
            replace = ui_.prompt("A repository with the name '{0}' is already"
                                 " published by {1}. Replace it? [y/N]".format(
                                     new_name, local_identity),
                                 default='n')

            if replace.lower() != 'y':
                raise util.Abort("A repository with this name already exists.")

            # Remove the existing repository from each configuration section.
            existing_usk = request_usks[names.index(new_name)]

            existing_dir = None
            for directory, request_usk in stored_cfg.request_usks.iteritems():
                if request_usk == existing_usk:
                    if existing_dir:
                        raise util.Abort("Configuration lists the same "
                                         "request USK multiple times.")
                    existing_dir = directory

            assert existing_dir

            existing_hash = normalize(existing_usk)

            # Config file changes will not be written until a successful insert
            # below.
            del stored_cfg.version_table[existing_hash]
            del stored_cfg.request_usks[existing_dir]
            del stored_cfg.insert_usks[existing_hash]
            del stored_cfg.wot_identities[existing_hash]

        # Add "vcs" context. No-op if the identity already has it.
        msg_params = {
            'Message': 'AddContext',
            'Identity': local_identity.identity_id,
            'Context': 'vcs'
        }

        import fcp
        import wot
        node = fcp.FCPNode(**wot.get_fcpopts(fcphost=opts["fcphost"],
                                             fcpport=opts["fcpport"]))
        atexit.register(node.shutdown)
        vcs_response =\
            node.fcpPluginMessage(plugin_name="plugins.WebOfTrust.WebOfTrust",
                                  plugin_params=msg_params)[0]

        if vcs_response['header'] != 'FCPPluginReply' or\
                'Replies.Message' not in vcs_response or\
                vcs_response['Replies.Message'] != 'ContextAdded':
            raise util.Abort(
                "Failed to add context. Got {0}\n.".format(vcs_response))

    set_target_version(ui_, repo, opts, params,
                       "Only inserting to version(s): %s\n")
    params['INSERT_URI'] = insert_uri
    inserted_to = execute_create(ui_, repo, params, stored_cfg)

    if inserted_to and local_identity:
        # creation returns a list of request URIs; use the first.
        stored_cfg.set_wot_identity(inserted_to[0], local_identity)
        Config.to_file(stored_cfg)

        import wot
        wot.update_repo_listing(ui_,
                                local_identity,
                                fcphost=opts["fcphost"],
                                fcpport=opts["fcpport"])
Exemple #11
0
def freenetclone(orig, *args, **opts):
    def parsepushargs(ui, repo, path=None):
        return ui, repo, path

    def isfreenetpath(path):
        try:
            if path.startswith("freenet:") or path.startswith("USK@"):
                return True
        except AttributeError:
            return False
        return False
    ui, source, dest = parsepushargs(*args)
    # only act differently, if dest or source is an infocalypse repo.
    if not isfreenetpath(source) and not isfreenetpath(dest):
        return orig(*args, **opts)

    if not dest:
        if not isfreenetpath(source):
            dest = hg.defaultdest(source)
        else: # this is a freenet key.  It has a /# at the end and
              # could contain .R1 or .R0 as pure technical identifiers
              # which we do not need in the local name.
            segments = source.split("/")
            pathindex = -2
            try:
                int(segments[-1])
            except ValueError: # no number revision
                pathindex = -1
            dest = segments[pathindex]
            if dest.endswith(".R1") or dest.endswith(".R0"):
                dest = dest[:-3]

    # TODO: source holds the "repo" argument, but the naming is confusing in
    # the context of freenetpathtouri().
    # check whether to create, pull or copy
    pulluri, pushuri = None, None
    if isfreenetpath(source):
        pulluri = parse_repo_path(
            freenetpathtouri(ui, source, "pull", None, opts.get('truster')))

    if isfreenetpath(dest):
        pushuri = parse_repo_path(freenetpathtouri(ui, dest, "clone-push", fcphost = opts['fcphost'], fcpport = opts['fcpport']),
                                  assume_redundancy=True)

    # decide which infocalypse command to use.
    if pulluri and pushuri:
        action = "copy"
    elif pulluri:
        action = "pull"
    elif pushuri:
        action = "create"
    else: 
        raise util.Abort("""Can't clone without source and target. This message should not be reached. If you see it, this is a bug.""")

    if action == "copy":
        raise util.Abort("""Cloning without intermediate local repo not yet supported in the simplified commands. Use fn-copy directly.""")
    
    if action == "create":
        # if the pushuri is the short form (USK@/name/#), generate the key.
        if pushuri.startswith("USK@/"):
            ui.status("creating a new key for the repo. To use your default key, call fn-create.\n")
            from sitecmds import genkeypair
            fcphost, fcpport = opts["fcphost"], opts["fcpport"]
            if not fcphost:
                fcphost = DEFAULT_FCP_HOST
            if not fcpport:
                fcpport = DEFAULT_FCP_PORT
            
            # use redundant keys by default, except if explicitely requested otherwise.
            namepart = pushuri[5:]
            namepart = fixnamepart(namepart)
            insert, request = genkeypair(fcphost, fcpport)
            pushuri = "USK"+insert[3:]+namepart
        elif pushuri.endswith("/0"): # initial create, catch the no-.R1 error
            pass
            # this rewriting is dangerous here since it could make it
            # impossible to update old repos when they drop
            # out. Leaving it commented out for now. TODO: Always
            # treat a name without .R0 as requesting redundancy *in.
            # the backend*. Keep it as /name/#, but add /name.Rn/0
            # backup repos. Needs going into the backend.

            #namepart = pushuri.split("/")[-2] + "/0"
            #namepartpos = -len(namepart)
            #namepart2 = fixnamepart(namepart)
            # if namepart2 != namepart:
            # ui.status("changed the repo name to " + namepart2 + " to have more redundancy and longer lifetime. This is a small tweak on infocalypse to avoid the frequent error of forgetting to add .R1 to the name. If you really want no additional redundancy for your repo, use NAME.R0 or call hg fn-create directly.\n")
            #pushuri = pushuri[:namepartpos] + namepart
        opts["uri"] = pushuri
        repo = hg.repository(ui, ui.expandpath(source))
        # TODO: A local identity is looked up for the push URI,
        # but not returned, yet it is required to update configuration.
        # Expecting dest to be something like freenet://name@key/reponame
        local_identifier = strip_protocol(dest).split('/')[0]

        from wot_id import Local_WoT_ID
        from wot import get_fcpopts
        local_identity = Local_WoT_ID(local_identifier,
                                      get_fcpopts(fcphost=opts["fcphost"],
                                                  fcpport=opts["fcpport"]))

        infocalypse_create(ui, repo, local_identity, **opts)

        # TODO: Function for adding paths? It's currently here, for pull,
        # and in WoT pull URI resolution.
        with repo.opener("hgrc", "a", text=True) as f:
            f.write("""[paths]
default-push = freenet:{0}
""".format(pushuri))

    if action == "pull":
        if os.path.exists(dest):
            raise util.Abort(_("destination " + dest + " already exists."))
        # create the repo
        req = dispatch.request(["init", dest], ui=ui)
        dispatch.dispatch(req)
        # pull the data from freenet
        origdest = ui.expandpath(dest)
        dest, branch = hg.parseurl(origdest)
        destrepo = hg.repository(ui, dest)
        infocalypse_pull(ui, destrepo, aggressive=True, hash=None, uri=pulluri, **opts)
        # store the request uri for future updates
        _hgrc_template = """[paths]
default = freenet://{pulluri}

[ui]
username = anonymous

[alias]
clt = commit
ci = !$HG clt --date "$(date -u "+%Y-%m-%d %H:%M:%S +0000")" "$@"
commit = !$HG clt --date "$(date -u "+%Y-%m-%d %H:%M:%S +0000")" "$@"
"""
        # alternative: every commit is done at 09:42:30 (might be
        # confusing but should be safest): date -u "+%Y-%m-%d 09:42:30 +0000
        
        # second alternative: commit done at local time but with
        # timezone +0000 (could be correlated against forum entries
        # and such to find the real timezone): Leave out the -u
        with destrepo.opener("hgrc", "a", text=True) as f:
            f.write(_hgrc_template.format(pulluri=pulluri))
        
        ui.warn("As basic protection, infocalypse automatically \n"
                "  set the username 'anonymous' for commits in this repo, \n"
                "  changed the commands `commit` and `ci` to fake UTC time \n"
                "  and added `clt` which commits in the local timezone. \n"
                "  To change this, edit " 
                + str(os.path.join(destrepo.root, ".hg", "hgrc"))
                + "\n")
        # and update the repo
        return hg.update(destrepo, None)
Exemple #12
0
def freenetclone(orig, *args, **opts):
    def parsepushargs(ui, repo, path=None):
        return ui, repo, path

    def isfreenetpath(path):
        try:
            if path.startswith("freenet:") or path.startswith("USK@"):
                return True
        except AttributeError:
            return False
        return False

    ui, source, dest = parsepushargs(*args)
    # only act differently, if dest or source is an infocalypse repo.
    if not isfreenetpath(source) and not isfreenetpath(dest):
        return orig(*args, **opts)

    if not dest:
        if not isfreenetpath(source):
            dest = hg.defaultdest(source)
        else:  # this is a freenet key.  It has a /# at the end and
            # could contain .R1 or .R0 as pure technical identifiers
            # which we do not need in the local name.
            segments = source.split("/")
            pathindex = -2
            try:
                int(segments[-1])
            except ValueError:  # no number revision
                pathindex = -1
            dest = segments[pathindex]
            if dest.endswith(".R1") or dest.endswith(".R0"):
                dest = dest[:-3]

    # TODO: source holds the "repo" argument, but the naming is confusing in
    # the context of freenetpathtouri().
    # check whether to create, pull or copy
    pulluri, pushuri = None, None
    if isfreenetpath(source):
        pulluri = parse_repo_path(
            freenetpathtouri(ui, source, "pull", None, opts.get('truster')))

    if isfreenetpath(dest):
        pushuri = parse_repo_path(freenetpathtouri(ui,
                                                   dest,
                                                   "clone-push",
                                                   fcphost=opts['fcphost'],
                                                   fcpport=opts['fcpport']),
                                  assume_redundancy=True)

    # decide which infocalypse command to use.
    if pulluri and pushuri:
        action = "copy"
    elif pulluri:
        action = "pull"
    elif pushuri:
        action = "create"
    else:
        raise util.Abort(
            """Can't clone without source and target. This message should not be reached. If you see it, this is a bug."""
        )

    if action == "copy":
        raise util.Abort(
            """Cloning without intermediate local repo not yet supported in the simplified commands. Use fn-copy directly."""
        )

    if action == "create":
        # if the pushuri is the short form (USK@/name/#), generate the key.
        if pushuri.startswith("USK@/"):
            ui.status(
                "creating a new key for the repo. To use your default key, call fn-create.\n"
            )
            from sitecmds import genkeypair
            fcphost, fcpport = opts["fcphost"], opts["fcpport"]
            if not fcphost:
                fcphost = DEFAULT_FCP_HOST
            if not fcpport:
                fcpport = DEFAULT_FCP_PORT

            # use redundant keys by default, except if explicitely requested otherwise.
            namepart = pushuri[5:]
            namepart = fixnamepart(namepart)
            insert, request = genkeypair(fcphost, fcpport)
            pushuri = "USK" + insert[3:] + namepart
        elif pushuri.endswith("/0"):  # initial create, catch the no-.R1 error
            pass
            # this rewriting is dangerous here since it could make it
            # impossible to update old repos when they drop
            # out. Leaving it commented out for now. TODO: Always
            # treat a name without .R0 as requesting redundancy *in.
            # the backend*. Keep it as /name/#, but add /name.Rn/0
            # backup repos. Needs going into the backend.

            #namepart = pushuri.split("/")[-2] + "/0"
            #namepartpos = -len(namepart)
            #namepart2 = fixnamepart(namepart)
            # if namepart2 != namepart:
            # ui.status("changed the repo name to " + namepart2 + " to have more redundancy and longer lifetime. This is a small tweak on infocalypse to avoid the frequent error of forgetting to add .R1 to the name. If you really want no additional redundancy for your repo, use NAME.R0 or call hg fn-create directly.\n")
            #pushuri = pushuri[:namepartpos] + namepart
        opts["uri"] = pushuri
        repo = hg.repository(ui, ui.expandpath(source))
        # TODO: A local identity is looked up for the push URI,
        # but not returned, yet it is required to update configuration.
        # Expecting dest to be something like freenet://name@key/reponame
        local_identifier = strip_protocol(dest).split('/')[0]

        from wot_id import Local_WoT_ID
        from wot import get_fcpopts
        local_identity = Local_WoT_ID(
            local_identifier,
            get_fcpopts(fcphost=opts["fcphost"], fcpport=opts["fcpport"]))

        infocalypse_create(ui, repo, local_identity, **opts)

        # TODO: Function for adding paths? It's currently here, for pull,
        # and in WoT pull URI resolution.
        with repo.opener("hgrc", "a", text=True) as f:
            f.write("""[paths]
default-push = freenet:{0}
""".format(pushuri))

    if action == "pull":
        if os.path.exists(dest):
            raise util.Abort(_("destination " + dest + " already exists."))
        # create the repo
        req = dispatch.request(["init", dest], ui=ui)
        dispatch.dispatch(req)
        # pull the data from freenet
        origdest = ui.expandpath(dest)
        dest, branch = hg.parseurl(origdest)
        destrepo = hg.repository(ui, dest)
        infocalypse_pull(ui,
                         destrepo,
                         aggressive=True,
                         hash=None,
                         uri=pulluri,
                         **opts)
        # store the request uri for future updates
        _hgrc_template = """[paths]
default = freenet://{pulluri}

[ui]
username = anonymous

[alias]
clt = commit
ci = !$HG clt --date "$(date -u "+%Y-%m-%d %H:%M:%S +0000")" "$@"
commit = !$HG clt --date "$(date -u "+%Y-%m-%d %H:%M:%S +0000")" "$@"
"""
        # alternative: every commit is done at 09:42:30 (might be
        # confusing but should be safest): date -u "+%Y-%m-%d 09:42:30 +0000

        # second alternative: commit done at local time but with
        # timezone +0000 (could be correlated against forum entries
        # and such to find the real timezone): Leave out the -u
        with destrepo.opener("hgrc", "a", text=True) as f:
            f.write(_hgrc_template.format(pulluri=pulluri))

        ui.warn("As basic protection, infocalypse automatically \n"
                "  set the username 'anonymous' for commits in this repo, \n"
                "  changed the commands `commit` and `ci` to fake UTC time \n"
                "  and added `clt` which commits in the local timezone. \n"
                "  To change this, edit " +
                str(os.path.join(destrepo.root, ".hg", "hgrc")) + "\n")
        # and update the repo
        return hg.update(destrepo, None)