def enter(self, dummy): """ Implementation of State virtual. """ #require_state(from_state, QUIESCENT) #print "REQUEST_URI:" #print self.parent.ctx['REQUEST_URI'] request_uri = self.parent.ctx['REQUEST_URI'] if (is_usk(request_uri) and self.parent.params.get('AGGRESSIVE_SEARCH', False)): request_uri = get_negative_usk(request_uri) if (is_usk(request_uri) and self.parent.params['NO_SEARCH']): request_uris = make_frozen_uris(request_uri, False) self.parent.ctx.ui_.status("Request URI index searching " + "disabled.\n") else: request_uris = make_search_uris(request_uri) for uri in request_uris: #[uri, tries, is_insert, raw_data, mime_type, last_msg] if self.parent.params.get('DUMP_URIS', False): self.parent.ctx.ui_.status("REQUEST URI: %s\n" % uri) self.queue([uri, 0, False, None, None, None]) self.required_successes = 1 #len(self.results) # Hmmm fix, but how # So we don't implictly favor one by requesting it first. random.shuffle(self.current_candidates)
def do_key_setup(ui_, update_sm, params, stored_cfg): """ INTERNAL: Handle inverting/updating keys before running a command.""" insert_uri = params.get('INSERT_URI') if not insert_uri is None and insert_uri.startswith('USK@/'): insert_uri = ('USK' + stored_cfg.defaults['DEFAULT_PRIVATE_KEY'][3:] + insert_uri[5:]) ui_.status("Filled in the insert URI using the default private key.\n") if insert_uri is None or not (is_usk(insert_uri) or is_ssk(insert_uri)): return (params.get('REQUEST_URI'), False) update_sm.start_inverting(insert_uri) run_until_quiescent(update_sm, params['POLL_SECS'], False) if update_sm.get_state(QUIESCENT).prev_state != INVERTING_URI: raise util.Abort("Couldn't invert private key:\n%s" % insert_uri) inverted_uri = update_sm.get_state(INVERTING_URI).get_request_uri() params['INVERTED_INSERT_URI'] = inverted_uri if is_usk(insert_uri): # Determine the highest known index for the insert uri. max_index = max(stored_cfg.get_index(inverted_uri), get_version(insert_uri)) # Update the insert uri to the latest known version. params['INSERT_URI'] = get_usk_for_usk_version(insert_uri, max_index) # Update the inverted insert URI to the latest known version. params['INVERTED_INSERT_URI'] = get_usk_for_usk_version( inverted_uri, max_index) # Update the index of the request uri using the stored config. request_uri = params.get('REQUEST_URI') if not request_uri is None and is_usk(request_uri): assert not params['NO_SEARCH'] or not request_uri is None if not params['NO_SEARCH']: max_index = max(stored_cfg.get_index(request_uri), get_version(request_uri)) request_uri = get_usk_for_usk_version(request_uri, max_index) if (params['NO_SEARCH'] and # Force the insert URI down to the version in the request URI. usks_equal(request_uri, params['INVERTED_INSERT_URI'])): params['INVERTED_INSERT_URI'] = request_uri params['INSERT_URI'] = get_usk_for_usk_version( insert_uri, get_version(request_uri)) # Skip key inversion if we already inverted the insert_uri. is_keypair = False if (request_uri is None and not params.get('INVERTED_INSERT_URI') is None): request_uri = params['INVERTED_INSERT_URI'] is_keypair = True return (request_uri, is_keypair)
def next_runnable(self): """ Implementation of RequestQueueState virtual. """ if self.queued: return None self.queued = True uri = self.insert_uri if is_usk(uri): # Hack to keep freenet from doing a USK search. uri = get_ssk_for_usk_version(uri, 0) request = StatefulRequest(self.parent) request.in_params.definition = GET_REQUEST_URI_DEF request.in_params.fcp_params = { 'URI': uri, 'MaxRetries': 1, 'PriorityClass': 1, 'UploadFrom': 'direct', 'GetCHKOnly': True } request.in_params.send_data = '@' * 9 request.in_params.fcp_params['DataLength'] = (len( request.in_params.send_data)) request.tag = 'only_invert' # Hmmmm... self.parent.ctx.set_cancel_time(request) return request
def start_inverting(self, insert_uri): """ Start inverting a Freenet URI into it's analogous request URI. """ assert is_usk(insert_uri) or is_ssk(insert_uri) self.require_state(QUIESCENT) self.reset() self.get_state(INVERTING_URI).insert_uri = insert_uri self.transition(INVERTING_URI)
def execute_reinsert(ui_, repo, params, stored_cfg): """ Run the reinsert command. """ update_sm = None try: update_sm = setup(ui_, repo, params, stored_cfg) request_uri, is_keypair = do_key_setup(ui_, update_sm, params, stored_cfg) params['REQUEST_URI'] = request_uri if not params['INSERT_URI'] is None: if (is_usk(params['INSERT_URI']) and (not is_usk(params['REQUEST_URI'])) or (not usks_equal(params['REQUEST_URI'], params['INVERTED_INSERT_URI']))): raise util.Abort("Request URI doesn't match insert URI.") ui_.debug("%sInsert URI:\n%s\n" % (is_redundant(params[ 'INSERT_URI']), params['INSERT_URI'])) ui_.status("%sRequest URI:\n%s\n" % (is_redundant(params[ 'REQUEST_URI']), params['REQUEST_URI'])) ui_.status(LEVEL_MSGS[params['REINSERT_LEVEL']] + '\n') update_sm.start_reinserting(params['REQUEST_URI'], params['INSERT_URI'], is_keypair, params['REINSERT_LEVEL']) run_until_quiescent(update_sm, params['POLL_SECS']) if update_sm.get_state(QUIESCENT).arrived_from(((FINISHING,))): ui_.status("Reinsert finished.\n") else: ui_.status("Reinsert failed.\n") # Don't need to update the config. finally: cleanup(update_sm)
def leave(self, to_state): """ Override to update REQUEST_URI in the parent's context. """ InsertingUri.leave(self, to_state) if to_state.name != self.success_state: return if self.parent.ctx['INSERT_URI'] is None: # Assert reinserting??? return # i.e. for reinserting. if not (is_usk(self.parent.ctx['INSERT_URI']) and is_usk(self.parent.ctx['REQUEST_URI'])): return if (get_version(self.parent.ctx['INSERT_URI']) > get_version(self.parent.ctx['REQUEST_URI'])): version = get_version(self.parent.ctx['INSERT_URI']) self.parent.ctx['REQUEST_URI'] = ( get_usk_for_usk_version(self.parent.ctx['REQUEST_URI'], version))
def leave(self, to_state): """ Implementation of State virtual. """ if to_state.name == self.success_state: # Hmmm... what about chks? # Update the index in the insert_uri on success if (should_increment(self) and is_usk(self.parent.ctx['INSERT_URI'])): version = get_version(self.parent.ctx['INSERT_URI']) + 1 self.parent.ctx['INSERT_URI'] = (get_usk_for_usk_version( self.parent.ctx['INSERT_URI'], version)) if self.parent.params.get('DUMP_URIS', False): self.parent.ctx.ui_.status( ("INSERT UPDATED INSERT " + "URI:\n%s\n") % self.parent.ctx['INSERT_URI'])
def execute_reinsert(ui_, repo, params, stored_cfg): """ Run the reinsert command. """ update_sm = None try: update_sm = setup(ui_, repo, params, stored_cfg) request_uri, is_keypair = do_key_setup(ui_, update_sm, params, stored_cfg) params['REQUEST_URI'] = request_uri if not params['INSERT_URI'] is None: if (is_usk(params['INSERT_URI']) and (not is_usk(params['REQUEST_URI'])) or (not usks_equal( params['REQUEST_URI'], params['INVERTED_INSERT_URI']))): raise util.Abort("Request URI doesn't match insert URI.") ui_.status( "%sInsert URI:\n%s\n" % (is_redundant(params['INSERT_URI']), params['INSERT_URI'])) ui_.status( "%sRequest URI:\n%s\n" % (is_redundant(params['REQUEST_URI']), params['REQUEST_URI'])) ui_.status(LEVEL_MSGS[params['REINSERT_LEVEL']] + '\n') update_sm.start_reinserting(params['REQUEST_URI'], params['INSERT_URI'], is_keypair, params['REINSERT_LEVEL']) run_until_quiescent(update_sm, params['POLL_SECS']) if update_sm.get_state(QUIESCENT).arrived_from(((FINISHING, ))): ui_.status("Reinsert finished.\n") else: ui_.status("Reinsert failed.\n") # Don't need to update the config. finally: cleanup(update_sm)
def leave(self, to_state): """ Implementation of State virtual. """ if to_state.name == self.success_state: # Hmmm... what about chks? # Update the index in the insert_uri on success if (should_increment(self) and is_usk(self.parent.ctx['INSERT_URI'])): version = get_version(self.parent.ctx['INSERT_URI']) + 1 self.parent.ctx['INSERT_URI'] = ( get_usk_for_usk_version(self.parent.ctx['INSERT_URI'], version)) if self.parent.params.get('DUMP_URIS', False): self.parent.ctx.ui_.status(("INSERT UPDATED INSERT " + "URI:\n%s\n") % self.parent.ctx['INSERT_URI'])
def leave(self, to_state): """ Implementation of State virtual. """ if to_state.name == self.success_state: self.parent.ctx['REQUEST_URI'] = self.get_latest_uri() if is_usk(self.parent.ctx['REQUEST_URI']): self.parent.ctx.ui_.status( "Current USK version: %i\n" % get_version(self.parent.ctx['REQUEST_URI'])) if (self.parent.ctx['IS_KEYPAIR'] and is_usk(self.parent.ctx['REQUEST_URI']) and # lose usk checks? is_usk(self.parent.ctx['INSERT_URI'])): version = get_version(self.parent.ctx['REQUEST_URI']) self.parent.ctx['INSERT_URI'] = (get_usk_for_usk_version( self.parent.ctx['INSERT_URI'], version)) #print "SEARCH UPDATED INSERT URI: ", \ # self.parent.ctx['INSERT_URI'] # Allow pending requests to run to completion. self.parent.ctx.orphan_requests(self) if self.parent.params.get('DUMP_TOP_KEY', False): self.topkey_funcs.dump_top_key_tuple( self.get_top_key_tuple(), self.parent.ctx.ui_.status)
def leave(self, to_state): """ Implementation of State virtual. """ if to_state.name == self.success_state: self.parent.ctx['REQUEST_URI'] = self.get_latest_uri() if is_usk(self.parent.ctx['REQUEST_URI']): self.parent.ctx.ui_.status("Current USK version: %i\n" % get_version(self.parent .ctx['REQUEST_URI'])) if (self.parent.ctx['IS_KEYPAIR'] and is_usk(self.parent.ctx['REQUEST_URI']) and # lose usk checks? is_usk(self.parent.ctx['INSERT_URI'])): version = get_version(self.parent.ctx['REQUEST_URI']) self.parent.ctx['INSERT_URI'] = ( get_usk_for_usk_version(self.parent.ctx['INSERT_URI'], version)) #print "SEARCH UPDATED INSERT URI: ", \ # self.parent.ctx['INSERT_URI'] # Allow pending requests to run to completion. self.parent.ctx.orphan_requests(self) if self.parent.params.get('DUMP_TOP_KEY', False): self.topkey_funcs.dump_top_key_tuple(self.get_top_key_tuple(), self.parent.ctx.ui_.status)
def arc_handle_updating_config(update_sm, params, stored_cfg, is_pulling=False): """ INTERNAL: Write updates into the config file IFF the previous command succeeded. """ base_dir = params['ARCHIVE_CACHE_DIR'] if not is_pulling: if not update_sm.get_state(QUIESCENT).arrived_from(((FINISHING, ))): return if (params['INSERT_URI'] is None or # <- re-insert w/o insert uri not is_usk_file(params['INSERT_URI'])): return inverted_uri = params['INVERTED_INSERT_URI'] # Cache the request_uri - insert_uri mapping. stored_cfg.set_insert_uri(inverted_uri, update_sm.ctx['INSERT_URI']) # Cache the updated index for the insert. version = get_version(update_sm.ctx['INSERT_URI']) stored_cfg.update_index(inverted_uri, version) stored_cfg.update_dir(base_dir, inverted_uri) # Hmmm... if we wanted to be clever we could update the request # uri too when it doesn't match the insert uri. Ok for now. # Only for usks and only on success. #print "UPDATED STORED CONFIG(0)" Config.to_file(stored_cfg) else: # Only finishing required. same. REDFLAG: look at this again if not update_sm.get_state(QUIESCENT).arrived_from((FINISHING, )): return if not is_usk(params['REQUEST_URI']): return state = update_sm.get_state(ARC_REQUESTING_URI) updated_uri = state.get_latest_uri() version = get_version(updated_uri) stored_cfg.update_index(updated_uri, version) stored_cfg.update_dir(base_dir, updated_uri) #print "UPDATED STORED CONFIG(1)" Config.to_file(stored_cfg)
def check_uri(ui_, uri): """ INTERNAL: Abort if uri is not supported. """ if uri is None: return if is_usk(uri): if not is_usk_file(uri): ui_.status("Only file USKs are allowed." + "\nMake sure the URI ends with '/<number>' " + "with no trailing '/'.\n") raise util.Abort("Non-file USK %s\n" % uri) # Just fix it instead of doing B&H? if is_negative_usk(uri): ui_.status("Negative USK index values are not allowed." + "\nUse --aggressive instead. \n") raise util.Abort("Negative USK %s\n" % uri)
def arc_handle_updating_config(update_sm, params, stored_cfg, is_pulling=False): """ INTERNAL: Write updates into the config file IFF the previous command succeeded. """ base_dir = params['ARCHIVE_CACHE_DIR'] if not is_pulling: if not update_sm.get_state(QUIESCENT).arrived_from(((FINISHING,))): return if (params['INSERT_URI'] is None or # <- re-insert w/o insert uri not is_usk_file(params['INSERT_URI'])): return inverted_uri = params['INVERTED_INSERT_URI'] # Cache the request_uri - insert_uri mapping. stored_cfg.set_insert_uri(inverted_uri, update_sm.ctx['INSERT_URI']) # Cache the updated index for the insert. version = get_version(update_sm.ctx['INSERT_URI']) stored_cfg.update_index(inverted_uri, version) stored_cfg.update_dir(base_dir, inverted_uri) # Hmmm... if we wanted to be clever we could update the request # uri too when it doesn't match the insert uri. Ok for now. # Only for usks and only on success. #print "UPDATED STORED CONFIG(0)" Config.to_file(stored_cfg) else: # Only finishing required. same. REDFLAG: look at this again if not update_sm.get_state(QUIESCENT).arrived_from((FINISHING,)): return if not is_usk(params['REQUEST_URI']): return state = update_sm.get_state(ARC_REQUESTING_URI) updated_uri = state.get_latest_uri() version = get_version(updated_uri) stored_cfg.update_index(updated_uri, version) stored_cfg.update_dir(base_dir, updated_uri) #print "UPDATED STORED CONFIG(1)" Config.to_file(stored_cfg)
def get_latest_uri(self): """ Returns the URI with the version part update if the URI is a USK.""" if (is_usk(self.parent.ctx['REQUEST_URI']) and self.parent.params['NO_SEARCH']): return self.parent.ctx['REQUEST_URI'] max_version = None for candidate in self.ordered: result = candidate[5] if result is None or result[0] != 'AllData': continue uri = result[1]['URI'] if not is_usk_file(uri): return uri max_version = max(max_version, abs(get_version(uri))) break assert not max_version is None # The .R1 URI is queued first. assert (len(self.ordered) < 2 or self.ordered[0][0].find('.R1') != -1) return get_usk_for_usk_version(self.ordered[0][0], max_version)
def monitor_callback(self, update_sm, client, msg): """ FCP message status callback which writes to a ui. """ if self.verbosity < 2: return #prefix = update_sm.current_state.name prefix = '' if self.verbosity > 2: prefix = client.request_id()[:10] + ':' if hasattr(update_sm.current_state, 'pending') and self.verbosity > 1: prefix = ("{%i}:" % len(update_sm.runner.running)) + prefix if msg[0] == 'SimpleProgress': text = str(parse_progress(msg)) elif msg[0] == 'URIGenerated': return # shows up twice #elif msg[0] == 'PutSuccessful': # text = 'PutSuccessful:' + msg[1]['URI'] elif msg[0] == 'ProtocolError': text = 'ProtocolError:' + str(msg) elif msg[0] == 'AllData': # Don't try to print raw data. text = 'AllData: length=%s' % msg[1].get('DataLength', '???') elif msg[0].find('Failed') != -1: code = get_code(msg) or -1 redirect = '' if (code == 27 and 'RedirectURI' in msg[1] and is_usk(msg[1]['RedirectURI'])): redirect = ", redirected to version: %i" % \ get_version(msg[1]['RedirectURI']) text = "%s: code=%i%s" % (msg[0], code, redirect) else: text = msg[0] self.ui_.status("%s%s:%s\n" % (prefix, str(client.tag), text))
def next_runnable(self): """ Implementation of RequestQueueState virtual. """ if self.queued: return None self.queued = True uri = self.insert_uri if is_usk(uri): # Hack to keep freenet from doing a USK search. uri = get_ssk_for_usk_version(uri, 0) request = StatefulRequest(self.parent) request.in_params.definition = GET_REQUEST_URI_DEF request.in_params.fcp_params = {'URI': uri, 'MaxRetries': 1, 'PriorityClass':1, 'UploadFrom':'direct', 'GetCHKOnly':True} request.in_params.send_data = '@' * 9 request.in_params.fcp_params['DataLength'] = ( len(request.in_params.send_data)) request.tag = 'only_invert' # Hmmmm... self.parent.ctx.set_cancel_time(request) return request