[or-cvs] r20611: {} Add old, first go at an auto naming directory for Tor from 2 (in projects/tor-naming/trunk: . tor-naming-web)

weasel at seul.org weasel at seul.org
Sat Sep 19 10:04:53 UTC 2009


Author: weasel
Date: 2009-09-19 06:04:53 -0400 (Sat, 19 Sep 2009)
New Revision: 20611

Added:
   projects/tor-naming/trunk/10-create.sql
   projects/tor-naming/trunk/12-modify.sql
   projects/tor-naming/trunk/README
   projects/tor-naming/trunk/controller-password
   projects/tor-naming/trunk/db-config.rb
   projects/tor-naming/trunk/db.rb
   projects/tor-naming/trunk/feed-into-pg
   projects/tor-naming/trunk/import-old-directory
   projects/tor-naming/trunk/old-contact-from-sd-table-to-their-own-v2
   projects/tor-naming/trunk/old-server-descriptors-parse-version-and-contact
   projects/tor-naming/trunk/old-versionandcontact-from-sd-table-to-their-own
   projects/tor-naming/trunk/parse-capacities
   projects/tor-naming/trunk/parse-missing-version-into-sd-table
   projects/tor-naming/trunk/process-approved-routers-v2
   projects/tor-naming/trunk/test-if-all-sds-have-a-descriptor
   projects/tor-naming/trunk/tor-naming-web/
   projects/tor-naming/trunk/tor-naming-web/List-all-sds-by-fpr.rb
   projects/tor-naming/trunk/tor-naming-web/List-nodes-died.rb
   projects/tor-naming/trunk/tor-naming-web/List-nodes-rejected.rb
   projects/tor-naming/trunk/tor-naming-web/List.rb
   projects/tor-naming/trunk/tor-naming-web/Makefile
   projects/tor-naming/trunk/tor-naming-web/Set_annotation.rb
   projects/tor-naming/trunk/tor-naming-web/Show-fpr.rb
   projects/tor-naming/trunk/tor-naming-web/Show-nick.rb
   projects/tor-naming/trunk/tor-naming-web/Show-sd.rb
   projects/tor-naming/trunk/tor-naming-web/common.rb
   projects/tor-naming/trunk/tor-naming-web/db-config.rb
   projects/tor-naming/trunk/tor-naming-web/db.rb
   projects/tor-naming/trunk/tor-naming-web/format.css
   projects/tor-naming/trunk/tor-naming-web/index.html
   projects/tor-naming/trunk/tor-naming-web/list-all-sds-by-fpr.rb
   projects/tor-naming/trunk/tor-naming-web/list-nodes-died.rb
   projects/tor-naming/trunk/tor-naming-web/list-nodes-rejected.rb
   projects/tor-naming/trunk/tor-naming-web/list.html
   projects/tor-naming/trunk/tor-naming-web/list.plogic
   projects/tor-naming/trunk/tor-naming-web/list.rb
   projects/tor-naming/trunk/tor-naming-web/list.rb-bak2
   projects/tor-naming/trunk/tor-naming-web/set_annotation.rb
   projects/tor-naming/trunk/tor-naming-web/show-fpr.html
   projects/tor-naming/trunk/tor-naming-web/show-fpr.plogic
   projects/tor-naming/trunk/tor-naming-web/show-fpr.rb
   projects/tor-naming/trunk/tor-naming-web/show-nick.html
   projects/tor-naming/trunk/tor-naming-web/show-nick.plogic
   projects/tor-naming/trunk/tor-naming-web/show-nick.rb
   projects/tor-naming/trunk/tor-naming-web/show-sd.html
   projects/tor-naming/trunk/tor-naming-web/show-sd.plogic
   projects/tor-naming/trunk/tor-naming-web/show-sd.rb
Log:
Add old, first go at an auto naming directory for Tor from 2005; requested by arma

Added: projects/tor-naming/trunk/10-create.sql
===================================================================
--- projects/tor-naming/trunk/10-create.sql	                        (rev 0)
+++ projects/tor-naming/trunk/10-create.sql	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,77 @@
+DROP TABLE named;
+DROP TABLE node;
+DROP TABLE action;
+DROP TABLE sd;
+
+CREATE TABLE named (
+	ref		INTEGER		PRIMARY KEY,
+	fingerprint	CHAR(40)	NOT NULL UNIQUE,
+	name		VARCHAR(30),
+	named_since	TIMESTAMP WITH TIME ZONE	DEFAULT CURRENT_TIMESTAMP
+);
+
+CREATE TABLE node (
+	ref		INTEGER		PRIMARY KEY,
+	fingerprint	CHAR(40)	NOT NULL UNIQUE,
+	max_capacity	INTEGER,
+	contact		BOOLEAN,
+	no_contact_until	DATE,
+	last_contacted	DATE,
+	comment		TEXT
+);
+
+CREATE TABLE action (
+	ref		INTEGER		PRIMARY KEY,
+	action		VARCHAR(20)	NOT NULL UNIQUE
+);
+
+
+CREATE TABLE sd (
+	ref		INTEGER		PRIMARY KEY,
+	node_ref	INTEGER		REFERENCES node(ref) NOT NULL,
+	action_ref	INTEGER		REFERENCES action(ref) NOT NULL,
+	msg		VARCHAR(160),
+	nickname	VARCHAR(40),
+	posted		TIMESTAMP WITH TIME ZONE	DEFAULT CURRENT_TIMESTAMP,
+	version		VARCHAR(25)
+);
+
+CREATE TABLE descriptor (
+	ref		INTEGER		PRIMARY KEY REFERENCES sd(ref) ON DELETE CASCADE,
+	capacity	INTEGER,
+	descriptor	TEXT
+);
+
+INSERT INTO action (ref, action) VALUES (1, 'ACCEPTED');
+INSERT INTO action (ref, action) VALUES (2, 'DROPPED');
+INSERT INTO action (ref, action) VALUES (3, 'REJECTED');
+
+
+CREATE INDEX sd_node_ref ON sd (node_ref);
+CREATE INDEX sd_posted ON sd (posted);
+CREATE INDEX sd_nickname ON sd (UPPER(nickname));
+
+
+CREATE SEQUENCE sd_seq;
+
+
+CREATE TABLE contact (
+	ref		INTEGER		PRIMARY KEY,
+	node_ref	INTEGER		REFERENCES node(ref) NOT NULL,
+	lastseen_sd_ref	INTEGER		REFERENCES sd(ref),
+	contact		VARCHAR(120),
+	UNIQUE (ref, contact)
+);
+CREATE INDEX contact_node_ref ON contact (node_ref);
+CREATE INDEX contact_lastseen_sd_ref ON contact (lastseen_sd_ref);
+
+
+CREATE TABLE version (
+	ref		INTEGER		PRIMARY KEY,
+	node_ref	INTEGER		REFERENCES node(ref) NOT NULL,
+	lastseen_sd_ref	INTEGER		REFERENCES sd(ref),
+	version		VARCHAR(120),
+	UNIQUE (ref, version)
+);
+CREATE INDEX version_node_ref ON version (node_ref);
+CREATE INDEX version_lastseen_sd_ref ON version (lastseen_sd_ref);

Added: projects/tor-naming/trunk/12-modify.sql
===================================================================
--- projects/tor-naming/trunk/12-modify.sql	                        (rev 0)
+++ projects/tor-naming/trunk/12-modify.sql	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,33 @@
+ALTER TABLE version drop CONSTRAINT version_ref_key;
+ALTER TABLE contact drop CONSTRAINT contact_ref_key;
+
+ALTER TABLE version ADD CONSTRAINT version_noderef_key UNIQUE (node_ref, version);
+ALTER TABLE contact ADD CONSTRAINT contact_noderef_key UNIQUE (node_ref, contact);
+
+
+
+CREATE SEQUENCE networkstatus_sequence;
+CREATE TABLE networkstatus (
+	ref		INTEGER	PRIMARY KEY DEFAULT nextval('networkstatus_sequence'),
+	publisher	INTEGER REFERENCES node(ref) NOT NULL,
+	published	TIMESTAMP WITH TIME ZONE
+);
+
+CREATE TABLE listed_in_status (
+	node_ref	INTEGER REFERENCES node(ref) NOT NULL,
+	status_ref	INTEGER REFERENCES networkstatus(ref) NOT NULL,
+
+	isAuthority	BOOLEAN,
+	isExit		BOOLEAN,
+	isFast		BOOLEAN,
+	isGuard		BOOLEAN,
+	isStable	BOOLEAN,
+	isRunning	BOOLEAN,
+	isValid		BOOLEAN,
+	isV2Dir		BOOLEAN,
+
+	PRIMARY KEY (node_ref, status_ref)
+);
+
+ALTER TABLE sd ADD COLUMN digest CHAR(40) UNIQUE;
+

Added: projects/tor-naming/trunk/README
===================================================================
--- projects/tor-naming/trunk/README	                        (rev 0)
+++ projects/tor-naming/trunk/README	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,45 @@
+Hi,
+
+this is the old, first go at an auto naming directory for Tor from 2005.
+
+From a quick look it appears that such a setup would consist of
+ * a postgresql database, to be created by the *.sql scripts in this
+   directory.
+ * import-old-directory was used to import version 1 directory
+   dumps into the database.
+ * A couple of scripts to convert data as the database schema changed.
+ * feed-into-pg would connect to the authority's controlport and listen
+   for new SD events, inserting them into the database.
+ * and a tor-naming-web/ directory with some web service stuff to query
+   it all.  Note that this was never open to the public, so who knows
+   how secure it is.
+
+Also, all of this code is from 2005, so it probably has bitrotted away
+since then.
+
+Cheers,
+weasel
+Sat, 19 Sep 2009 12:01:05 +0200
+
+
+All of this is:
+Copyright (c) 2005 Peter Palfrader
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the 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 the Software.
+
+THE 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 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+

Added: projects/tor-naming/trunk/controller-password
===================================================================
--- projects/tor-naming/trunk/controller-password	                        (rev 0)
+++ projects/tor-naming/trunk/controller-password	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1 @@
+geheim

Added: projects/tor-naming/trunk/db-config.rb
===================================================================
--- projects/tor-naming/trunk/db-config.rb	                        (rev 0)
+++ projects/tor-naming/trunk/db-config.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,12 @@
+$CONFIG             = {} unless $CONFIG
+$CONFIG['database'] = {} unless $CONFIG['database']
+
+if true
+	$CONFIG['database']['dbname'] = 'weasel_tor';
+	$CONFIG['database']['user'] = 'weasel_tor';
+	$CONFIG['database']['password'] = 'swordfish';
+else
+	$CONFIG['database']['dbname'] = 'weasel_test';
+	$CONFIG['database']['user'] = 'weasel';
+	$CONFIG['database']['password'] = 'secret';
+end

Added: projects/tor-naming/trunk/db.rb
===================================================================
--- projects/tor-naming/trunk/db.rb	                        (rev 0)
+++ projects/tor-naming/trunk/db.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,123 @@
+#!/usr/bin/ruby
+
+require "dbi"
+
+class WeaselDbQueryHandle
+	def initialize(sth)
+		@sth = sth
+	end
+
+	def next()
+		row = @sth.fetch_hash
+		if row
+			return row
+		else
+			@sth.finish
+			return nil
+		end
+	end
+end
+
+class Db
+	def initialize(database, user, password)
+		@dbh = DBI.connect("dbi:Pg:#{database}:localhost", user, password);
+		@dbh['AutoCommit'] = false
+		@transaction = false
+		@pre_initial_transaction=true
+	end
+
+	def do(query,*args)
+		@dbh.do(query,*args)
+	end
+	def transaction_begin()
+		@dbh.do("BEGIN") unless @pre_initial_transaction
+		@transaction = true
+		@pre_initial_transaction=false
+	end
+	def transaction_commit()
+		@dbh.do("COMMIT")
+		@transaction = false
+	end
+	def transaction_rollback()
+		@dbh.do("ROLLBACK")
+	end
+
+	def update_row(table, values)
+		throw "Ref not defined" unless values['ref']
+		cols = []
+		vals = []
+		values.each_pair{ |k,v|
+			next if k == "ref"
+			cols << "#{k}=?"
+			vals << v
+		}
+		vals << values['ref']
+		if cols.size > 0
+			query = "UPDATE #{table} SET #{cols.join(',')} WHERE ref=?"
+			transaction_begin unless transaction_before=@transaction
+			@dbh.do(query, *vals)
+			transaction_commit unless transaction_before
+		end
+	end
+	def insert_row(table, values)
+		if values['ref']
+			cols = values.keys
+			vals = values.values
+			qmarks = values.values.collect{ '?' }
+
+			query = "INSERT INTO #{table} (#{cols.join(',')}) VALUES (#{qmarks.join(',')})"
+			transaction_begin unless transaction_before=@transaction
+			@dbh.do(query, *vals)
+			transaction_commit unless transaction_before
+		else
+			transaction_begin unless transaction_before=@transaction
+			row = query_row("SELECT COALESCE(max(ref)+1,1) AS newref FROM #{table}");
+			throw "No newref?" unless row['newref']
+			values['ref'] = row['newref']
+			insert_row(table, values);
+			transaction_commit unless transaction_before
+		end
+	end
+	def delete_row(table, ref)
+		query = "DELETE FROM #{table} WHERE ref=?"
+		transaction_begin unless transaction_before=@transaction
+		@dbh.do(query, ref)
+		transaction_commit unless transaction_before
+	end
+	def query(query, *params)
+		sth = @dbh.execute(query, *params)
+		while row = sth.fetch_hash
+			yield row
+		end
+		sth.finish
+	end
+	# nil if no results
+	# hash if one match
+	# throw otherwise
+	def query_row(query, *params)
+		sth = @dbh.execute(query, *params)
+
+		row = sth.fetch_hash
+		if row == nil
+			sth.finish
+			return nil
+		elsif sth.fetch_hash != nil
+			sth.finish
+			throw "More than one result when querying for #{query}"
+		else
+			sth.finish
+			return row
+		end
+	end
+	def query_all(query, *params)
+		sth = @dbh.execute(query, *params)
+
+		rows = sth.fetch_all
+		return nil if rows.size == 0
+		return rows
+	end
+	def query2(query, *params)
+		sth = @dbh.execute(query, *params)
+		return WeaselDbQueryHandle.new(sth)
+	end
+end

Added: projects/tor-naming/trunk/feed-into-pg
===================================================================
--- projects/tor-naming/trunk/feed-into-pg	                        (rev 0)
+++ projects/tor-naming/trunk/feed-into-pg	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,163 @@
+#!/usr/bin/ruby
+
+# connect to the tor control port, subscribe to new server descriptors being posted,
+# and feed them all into the database
+#
+# ignored DROPPED descriptors
+
+require 'db'
+require 'socket'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+PASSWORD = File.new("controller-password").read.chop
+
+tor = TCPSocket.new('localhost', 9051)
+
+
+def ctrl_read(fd)
+	line = fd.readline.chop
+	throw "short reply" if line.length <= 3
+
+	code = line[0..2]
+	spec = line[3..3]
+	rest = line[4..line.length-1]
+
+	if spec == " "
+		msg = rest
+		return { 'code' => code, 'msg' => msg };
+	elsif spec == "-"
+		(key,value) = rest.split('=', 2)
+		return { 'code' => code, 'key' => key, 'value' => value };
+	elsif spec == "+"
+		throw "In line #{line} I epexcted the last char to be a =" unless rest[rest.length-1..rest.length-1] == '='
+		key = rest[0..rest.length-2]
+		value = []
+		while line = fd.readline.chop
+			break if line == "."
+			line = [1..line.length-1] if line[0..0] == "."
+			value << line
+		end
+		return { 'code' => code, 'key' => key, 'value' => value };
+	end
+end
+
+def get_server_ref(db, fpr)
+	row = db.query_row("SELECT * FROM node WHERE fingerprint=?", fpr);
+	if !row
+		db.insert_row('node', { 'fingerprint' => fpr } );
+		row = db.query_row("SELECT * FROM node WHERE fingerprint=?", fpr);
+		throw "No node with fingerprint '#{fpr}' after inserting it" unless row
+	end
+	return row['ref']
+end
+
+actions = {}
+db.query('SELECT * FROM action') { |row|
+        actions[ row["action"] ] = row['ref']
+}
+db.transaction_rollback
+
+
+tor.print "AUTHENTICATE \"#{PASSWORD}\"\r\n"
+reply = ctrl_read(tor)
+throw "Unexpected reply #{reply.to_yaml}" unless reply['code'] == '250'
+
+tor.print "SETEVENTS AUTHDIR_NEWDESCS\r\n"
+reply = ctrl_read(tor)
+throw "Unexpected reply #{reply.to_yaml}" unless reply['code'] == '250'
+
+
+while true do
+	r = ctrl_read(tor)
+	if r['code'] == '650' and r['key'] == 'AUTHDIR_NEWDESC'
+		action = r['value'].shift
+		msg = r['value'].shift
+		sd = r['value']
+
+		throw "Uknown action #{action}" unless actions.has_key?(action)
+		nickname = nil
+		fingerprint = nil
+		version = nil
+		contact = nil
+		capacity = nil
+		sd.each{ |line|
+			args = line.split(/\s+/)
+			s = 0
+			s = s+1 if args[0] == "opt"
+
+			nickname = args[s+1] if args[s] == "router"
+			fingerprint = args[s+1..s+10].join('') if args[s] == "fingerprint"
+			version = args[s+2] if args[s] == "platform"
+			contact = /^(?:opt )?contact (.*)/.match(line).to_a[1] if args[s] == "contact"
+			capacity = args[s+3] if args[s] == "bandwidth" and args.length >= s+3+1
+		}
+		throw "Got no nickname" unless nickname
+		throw "Got no fingerprint" unless fingerprint
+		throw "Got no version" unless version
+		throw "Got no capacity" unless capacity
+
+		node_ref = get_server_ref(db, fingerprint);
+		unless action == "DROPPED"
+			db.transaction_begin
+			new_sd_ref = db.query_row("SELECT nextval('sd_seq') as ref");
+			db.insert_row('sd', {
+				'ref'		=> new_sd_ref['ref'],
+				'node_ref'	=> node_ref,
+				'action_ref'	=> actions[action],
+				'msg'		=> msg,
+				'nickname'	=> nickname,
+				'version'	=> version[0..24]
+				})
+
+			db.insert_row('descriptor', {
+				'ref'		=> new_sd_ref['ref'],
+				'descriptor'	=> sd.join("\n"),
+				'capacity'	=> capacity
+				})
+
+
+			{ 'version' => version,
+			  'contact' => contact }.each_pair{ |k,v|
+				next unless v
+				v = v[0..119] # max column length
+				row = db.query_row("SELECT ref FROM #{k} WHERE node_ref=? AND #{k}=?", node_ref, v)
+				if row
+					db.update_row(k, { 'ref' => row['ref'], 'lastseen_sd_ref' => new_sd_ref['ref'] })
+				else
+					db.insert_row(k, {
+						'ref'		=> new_sd_ref['ref'], # pick something unique
+						'node_ref'	=> node_ref,
+						'lastseen_sd_ref' => new_sd_ref['ref'],
+						k		=> v
+						})
+				end
+			}
+
+			node = db.query_row("SELECT max_capacity FROM node WHERE ref=?", node_ref)
+			if !node['max_capacity'] or node['max_capacity'] < capacity.to_i
+				db.update_row('node', {
+					'ref'		=> node_ref,
+					'max_capacity'	=> capacity
+					})
+			end
+
+			db.transaction_commit
+			puts "Server #{fingerprint} (node_ref=#{node_ref}) running #{version} has nick #{nickname} and was #{action} with #{msg} got ref #{new_sd_ref['ref']}"
+		else
+			puts "Server #{fingerprint} (node_ref=#{node_ref}) running #{version} has nick #{nickname} and was #{action} with #{msg}  (IGNORED)"
+		end
+	elsif r['code'] == '650' and r['msg'] == 'OK'
+		# null
+	else
+		STDERR.puts("Cannot handle " + r.to_yaml);
+	end
+end
+
+
+tor.print "QUIT\r\n"
+reply = ctrl_read(tor)
+throw "Unexpected reply #{reply.to_yaml}" unless reply['code'] == '250'
+


Property changes on: projects/tor-naming/trunk/feed-into-pg
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/import-old-directory
===================================================================
--- projects/tor-naming/trunk/import-old-directory	                        (rev 0)
+++ projects/tor-naming/trunk/import-old-directory	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,131 @@
+#!/usr/bin/ruby
+
+# Imports old directories from dumps into the databse
+# does not set contact or version
+#
+# As arguments pass folder named that have the tor-directories in one
+# tor-directory per file.  the filenames need to start with 'directory-'.
+#
+
+require 'db'
+require 'socket'
+require 'yaml'
+require 'digest/sha1'
+
+require 'db-config'
+#db = Db.new('weasel_test', 'weasel', File.new("postgres-password-weasel").read.chop)
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+def get_server_ref(db, fpr)
+	row = db.query_row("SELECT * FROM node WHERE fingerprint=?", fpr);
+	if !row
+		db.insert_row('node', { 'fingerprint' => fpr } );
+		row = db.query_row("SELECT * FROM node WHERE fingerprint=?", fpr);
+		throw "No node with fingerprint '#{fpr}' after inserting it" unless row
+	end
+	return row['ref']
+end
+
+actions = {}
+db.query('SELECT * FROM action') { |row|
+        actions[ row["action"] ] = row['ref']
+}
+
+
+ARGV.each{ |arg|
+	Dir.entries(arg).each{ |entry|
+		next unless entry =~ /^directory-.*/;
+		filename = arg+'/'+entry;
+		puts "Doing file #{filename}";
+		directory = File.new(filename)
+
+		sds = []
+		signer = nil
+
+		lines = directory.readlines.collect{ |l| l.chop }
+
+		throw "Directory does not start with 'signed-directory'" if lines.shift != "signed-directory"
+		throw "second line is not published" unless lines[0] =~ /^published /
+		dirpublished = lines.shift.split(" ",2)[1] + ' UTC';
+		while lines[0] =~ /^router / and lines[0] != ""
+			lines.shift
+		end
+
+		while true
+			line = lines.shift
+			if line =~ /^router /
+				nickname = line.split(" ")[1]
+				published = nil
+				digest = nil
+				sd = []
+
+				sd.push line
+				while true
+					break if lines[0] =~ /^router / or lines[0] == ""
+					if lines[0] =~ /^published /
+						published = lines[0].split(" ",2)[1] + ' UTC';
+					end
+					if lines[0] == "signing-key" then
+						key = ""
+						sd.push lines.shift
+						while true
+							break if lines[0] == "-----END RSA PUBLIC KEY-----"
+							if lines[0] != "-----BEGIN RSA PUBLIC KEY-----"
+								key = key + lines[0]
+							end
+							sd.push lines.shift
+						end
+
+						#de-base64
+						binkey = key.unpack("m")[0]
+						digest = Digest::SHA1.hexdigest(binkey).upcase
+					end
+					sd.push lines.shift
+				end
+				throw "No 'published' for #{nickname}" unless published
+				throw "No 'digest' for #{nickname}" unless digest
+				sds.push({ 'descriptor' => sd.join("\n"),
+				           'nickname'   => nickname,
+				           'posted'     => published,
+				           'fingerprint'=> digest })
+			elsif line =~ /directory-signature /
+				signer = line.split(" ", 2)[1]
+				break
+			elsif line = ""
+			else
+				throw "Uknown line #{line}"
+			end
+		end
+		throw "Didn't find a signer" unless signer
+		throw "Didn't find any SDs" unless sds.length > 0
+
+		db.transaction_begin
+		sds.each{ |sd|
+			fingerprint = sd['fingerprint']
+			node_ref = get_server_ref(db, fingerprint);
+
+			# avoid dups
+			if db.query_row("SELECT ref FROM sd WHERE node_ref=? AND posted=?", node_ref, sd['posted']);
+				dup="DUPDUPDUP "
+			else
+				newref = db.query_row("SELECT nextval('sd_seq') as ref");
+
+				db.insert_row('sd', {
+					'ref'		=> newref['ref'],
+					'node_ref'	=> node_ref,
+					'action_ref'	=> actions[ 'ACCEPTED' ],
+					'msg'		=> "Imported from directory published by #{signer} on #{dirpublished}",
+					'posted'	=> sd['posted'],
+					'nickname'	=> sd['nickname'],
+					})
+				db.insert_row('descriptor',{
+					'ref'		=> newref['ref'],
+					'descriptor'	=> sd['descriptor']
+					})
+				dup=""
+			end
+			puts "#{dup}Server #{fingerprint} (node_ref=#{node_ref}) has nick #{sd['nickname']} and was published at #{sd['posted']} in #{signer}'s directory published at #{dirpublished}"
+		};
+		db.transaction_commit
+	}
+}


Property changes on: projects/tor-naming/trunk/import-old-directory
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/old-contact-from-sd-table-to-their-own-v2
===================================================================
--- projects/tor-naming/trunk/old-contact-from-sd-table-to-their-own-v2	                        (rev 0)
+++ projects/tor-naming/trunk/old-contact-from-sd-table-to-their-own-v2	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,50 @@
+#!/usr/bin/ruby
+
+# copy version and contact info into their own tables from sd
+
+require 'db'
+require 'socket'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+db.transaction_begin
+
+fetchedrow = 0
+inserts = 0
+db.query('SELECT sd.ref, sd.node_ref, sd.version, sd.contact FROM sd ORDER BY posted DESC') { |row|
+	{ 'version' => row['version'],
+	  'contact' => row['contact'] }.each_pair{ |k,v|
+		next unless v
+		v = v[0..119] # max column length
+		if db.query_row("SELECT ref FROM #{k} WHERE node_ref=? AND #{k}=?", row['node_ref'], v)
+			# we already have something and it's newer because we sorted by posted
+		else
+			db.insert_row(k, {
+				'ref'		=> row['ref'], # pick something unique
+				'node_ref'	=> row['node_ref'],
+				'lastseen_sd_ref' => row['ref'],
+				k		=> v
+				})
+
+			inserts = inserts + 1
+			if inserts == 5000
+				puts "\ncommitting\n";
+				db.transaction_commit
+				db.transaction_begin
+				inserts = 0
+			else
+				STDOUT.print "."
+				STDOUT.flush
+			end
+		end
+	}
+	fetchedrow = fetchedrow + 1
+	if fetchedrow == 500
+		STDOUT.print ","
+		STDOUT.flush
+		fetchedrow = 0
+	end
+}
+
+db.transaction_commit


Property changes on: projects/tor-naming/trunk/old-contact-from-sd-table-to-their-own-v2
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/old-server-descriptors-parse-version-and-contact
===================================================================
--- projects/tor-naming/trunk/old-server-descriptors-parse-version-and-contact	                        (rev 0)
+++ projects/tor-naming/trunk/old-server-descriptors-parse-version-and-contact	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,54 @@
+#!/usr/bin/ruby
+
+# parse version and contact info into the new columns in the sd table
+
+require 'db'
+require 'socket'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+db.transaction_begin
+
+done = 0
+db.query('SELECT sd.ref, sd.nickname FROM sd') { |row|
+	descriptor = db.query_row("SELECT descriptor.descriptor FROM descriptor WHERE ref=?", row['ref']);
+	sd = descriptor['descriptor'].split("\n")
+
+	nickname = nil
+	version = nil
+	contact = nil
+	sd.each{ |line|
+		args = line.split(/\s+/)
+		s = 0
+		s = s+1 if args[0] == "opt"
+
+		nickname = args[s+1] if args[s] == "router"
+		version = args[s+2] if args[s] == "platform"
+		contact = /^(?:opt )?contact (.*)/.match(line).to_a[1] if args[s] == "contact"
+	}
+	throw "Got no nickname" unless nickname
+	throw "Got no version" unless version
+	throw "Nickname #{nickname} does not match nickname #{row['nickname']} from the database at ref #{row['ref']}" unless nickname == row['nickname']
+
+	# sanity check
+	newref = db.query_row("SELECT nextval('sd_seq') as ref");
+	db.update_row('sd', {
+		'ref'		=> row['ref'],
+		'version'	=> version[0..24],
+		'contact'	=> contact ? contact[0..69] : nil
+		})
+	#puts "ref #{row['ref']}/nick #{nickname} has #{version} operated by #{contact}"
+	done = done + 1
+	if done == 5000
+		puts "\ncommitting\n";
+		db.transaction_commit
+		db.transaction_begin
+		done = 0
+	else
+		STDOUT.print "."
+		STDOUT.flush if (done % 20 == 0)
+	end
+}
+
+db.transaction_commit


Property changes on: projects/tor-naming/trunk/old-server-descriptors-parse-version-and-contact
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/old-versionandcontact-from-sd-table-to-their-own
===================================================================
--- projects/tor-naming/trunk/old-versionandcontact-from-sd-table-to-their-own	                        (rev 0)
+++ projects/tor-naming/trunk/old-versionandcontact-from-sd-table-to-their-own	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,50 @@
+#!/usr/bin/ruby
+
+# copy version and contact info into their own tables from sd
+
+require 'db'
+require 'socket'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+db.transaction_begin
+
+fetchedrow = 0
+inserts = 0
+db.query('SELECT sd.ref, sd.node_ref, sd.version, sd.contact FROM sd ORDER BY posted DESC') { |row|
+	{ 'version' => row['version'],
+	  'contact' => row['contact'] }.each_pair{ |k,v|
+		next unless v
+		v = v[0..119] # max column length
+		if db.query_row("SELECT ref FROM #{k} WHERE node_ref=? AND #{k}=?", row['node_ref'], v)
+			# we already have something and it's newer because we sorted by posted
+		else
+			db.insert_row(k, {
+				'ref'		=> row['ref'], # pick something unique
+				'node_ref'	=> row['node_ref'],
+				'lastseen_sd_ref' => row['ref'],
+				k		=> v
+				})
+
+			inserts = inserts + 1
+			if inserts == 5000
+				puts "\ncommitting\n";
+				db.transaction_commit
+				db.transaction_begin
+				inserts = 0
+			else
+				STDOUT.print "."
+				STDOUT.flush
+			end
+		end
+	}
+	fetchedrow = fetchedrow + 1
+	if fetchedrow == 500
+		STDOUT.print ","
+		STDOUT.flush
+		fetchedrow = 0
+	end
+}
+
+db.transaction_commit


Property changes on: projects/tor-naming/trunk/old-versionandcontact-from-sd-table-to-their-own
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/parse-capacities
===================================================================
--- projects/tor-naming/trunk/parse-capacities	                        (rev 0)
+++ projects/tor-naming/trunk/parse-capacities	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,74 @@
+#!/usr/bin/ruby
+
+# parse version and contact info into the new columns in the sd table
+
+require 'db'
+require 'socket'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+db.transaction_begin
+
+done = 0
+changes = 0
+db.query('SELECT sd.ref, sd.nickname, sd.node_ref FROM sd') { |row|
+	done = done + 1
+
+	descriptor = db.query_row("SELECT descriptor.capacity, descriptor.descriptor FROM descriptor WHERE ref=?", row['ref'])
+	next if descriptor['capacity']
+	sd = descriptor['descriptor'].split("\n")
+
+	nickname = nil
+	capacity = nil
+	sd.each{ |line|
+		args = line.split(/\s+/)
+		s = 0
+		s = s+1 if args[0] == "opt"
+
+		nickname = args[s+1] if args[s] == "router"
+		capacity = args[s+3] if args[s] == "bandwidth" and args.length >= s+3+1
+	}
+	throw "Got no nickname" unless nickname
+	throw "Nickname #{nickname} does not match nickname #{row['nickname']} from the database at ref #{row['ref']}" unless nickname == row['nickname']
+
+	unless capacity
+		STDOUT.print "-"
+		STDOUT.flush if (done % 200 == 0)
+		next
+	end
+
+	db.update_row('descriptor', {
+		'ref'		=> row['ref'],
+		'capacity'	=> capacity
+		})
+
+	node = db.query_row("SELECT max_capacity FROM node WHERE ref=?", row['node_ref'])
+
+
+	if node['max_capacity'] and node['max_capacity'] > capacity.to_i
+		STDOUT.print "*"
+		STDOUT.flush if (done % 200 == 0)
+		next
+	end
+
+	db.update_row('node', {
+		'ref'		=> row['node_ref'],
+		'max_capacity'	=> capacity
+		})
+
+
+
+	changes = changes + 1
+	if changes >= 50
+		puts "\ncommitting\n"
+		db.transaction_commit
+		db.transaction_begin
+		changes = 0
+	else
+		STDOUT.print "."
+		STDOUT.flush if (done % 200 == 0)
+	end
+}
+
+db.transaction_commit


Property changes on: projects/tor-naming/trunk/parse-capacities
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/parse-missing-version-into-sd-table
===================================================================
--- projects/tor-naming/trunk/parse-missing-version-into-sd-table	                        (rev 0)
+++ projects/tor-naming/trunk/parse-missing-version-into-sd-table	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,55 @@
+#!/usr/bin/ruby
+
+# connect to the tor control port, subscribe to new server descriptors being posted
+# and feed them all into the database
+#
+# ignored DROPPED descriptors
+
+require 'db'
+require 'socket'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+db.transaction_begin
+
+done = 0
+db.query('SELECT sd.ref, sd.nickname FROM sd WHERE version IS NULL') { |row|
+	puts row['ref']
+	descriptor = db.query_row("SELECT descriptor.descriptor FROM descriptor WHERE ref=?", row['ref']);
+	sd = descriptor['descriptor'].split("\n")
+
+	nickname = nil
+	version = nil
+	sd.each{ |line|
+		args = line.split(/\s+/)
+		s = 0
+		s = s+1 if args[0] == "opt"
+
+		nickname = args[s+1] if args[s] == "router"
+		version = args[s+2] if args[s] == "platform"
+	}
+	throw "Got no nickname" unless nickname
+	throw "Got no version" unless version
+	throw "Nickname #{nickname} does not match nickname #{row['nickname']} from the database at ref #{row['ref']}" unless nickname == row['nickname']
+
+	# sanity check
+	newref = db.query_row("SELECT nextval('sd_seq') as ref");
+	db.update_row('sd', {
+		'ref'		=> row['ref'],
+		'version'	=> version[0..24]
+		})
+	#puts "ref #{row['ref']}/nick #{nickname} has #{version} operated by #{contact}"
+	done = done + 1
+	if done == 5000
+		puts "\ncommitting\n";
+		db.transaction_commit
+		db.transaction_begin
+		done = 0
+	else
+		STDOUT.print "."
+		STDOUT.flush if (done % 20 == 0)
+	end
+}
+
+db.transaction_commit


Property changes on: projects/tor-naming/trunk/parse-missing-version-into-sd-table
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/process-approved-routers-v2
===================================================================
--- projects/tor-naming/trunk/process-approved-routers-v2	                        (rev 0)
+++ projects/tor-naming/trunk/process-approved-routers-v2	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,101 @@
+#!/usr/bin/ruby
+
+# read /etc/tor/approved-routers and its RCS versioning history file
+# and set the named table in the database accordingly
+
+require 'db'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+routers_in_db = {}
+db.query('SELECT * FROM named') { |row|
+	routers_in_db[ row["fingerprint"] ] = { "ref"         => row["ref"],
+	                                        "name"        => row["name"],
+	                                        "named_since" => row["named_since"] };
+}
+
+rlog = IO.popen("rlog -z+00:00 /etc/tor/approved-routers")
+revision = nil
+$revs = []
+rlog.each_line{ |line|
+	line.chop!
+	if line =~ /^revision /
+		revision = line.split(" ",2)[1]
+	elsif line =~ /^date: /
+		date = /date: ([0-9 :+-]+);/.match(line)[1]
+
+		$revs.push({ 'r' => revision, 'date' => date });
+		revision = nil
+		date = nil
+	end
+}
+rlog.close
+
+def getfile(r)
+	puts "Reading #{r['r']}"
+	co = IO.popen("co -p#{r['r']} /etc/tor/approved-routers 2>&1")
+	found = 0
+	r['file'] = co.readlines.collect{ |l| l.chop! }
+	co.close
+end
+
+def getdateforline(line)
+	foundinrev = nil
+	$revs.each{ |r|
+		getfile(r) unless r['file']
+		if r['file'].include?(line)
+			foundinrev = r
+		else
+			break
+		end
+	}
+	throw "Did not find #{line} in any revision" unless foundinrev;
+	return foundinrev['date']
+end
+
+routers_in_binding = {}
+bindinglist = File.new("/etc/tor/approved-routers", "r")
+bindinglist.each_line{ |line|
+	line.chomp!
+	next if line =~ /^\s*#/ or line =~ /^s*$/
+
+
+	(name, fpr) = line.split(/\s+/, 2)
+	fpr.delete! ' '
+	throw "Invalid fingerpint in '#{line}'" unless fpr.length == 40
+	throw "Duplicate fingerprint #{fpr}" if routers_in_binding[ fpr ]
+	if name[0..0] == "!"
+		puts "Ignoring #{name} for #{fpr}"
+	else
+		routers_in_binding[ fpr ] = { "name"        => name, 'line' => line };
+	end
+}
+
+routers_in_binding.each_pair{ |fpr, node|
+	if routers_in_db.has_key?(fpr)
+		if routers_in_db[fpr]["name"] != node["name"]
+			db.update_row('named', { 'ref' => routers_in_db[fpr]["ref"], 'name' => node["name"], 'named_since' => getdateforline(node["line"]) } );
+			puts "Node #{fpr} changed name from #{routers_in_db[fpr]["name"]} to #{node["name"]}"
+		end
+	else
+		db.insert_row('named',  { 'fingerprint' => fpr, 'name' => node["name"], 'named_since' => getdateforline(node["line"]) });
+
+		row = db.query_row('SELECT * FROM node WHERE fingerprint=?', fpr);
+		if row
+			throw "No row['ref'] for node with fingerprint #{fpr}" unless row['ref']
+			db.update_row('node',  { 'ref' => row['ref'], 'contact' => 'T' });
+		else
+			puts "Warning: have no dataset in node for named server #{node["name"]}, #{fpr}"
+		end
+
+		puts "Node #{fpr} (#{node["name"]}) added"
+	end
+}
+routers_in_db.each_pair{ |fpr, node|
+	if ! routers_in_binding.has_key?( fpr )
+		db.delete_row('named', routers_in_db[fpr]["ref"])
+		puts "Node #{fpr} (#{node["name"]}) removed"
+	end
+}


Property changes on: projects/tor-naming/trunk/process-approved-routers-v2
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/test-if-all-sds-have-a-descriptor
===================================================================
--- projects/tor-naming/trunk/test-if-all-sds-have-a-descriptor	                        (rev 0)
+++ projects/tor-naming/trunk/test-if-all-sds-have-a-descriptor	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,29 @@
+#!/usr/bin/ruby
+
+# connect to the tor control port, subscribe to new server descriptors being posted
+# and feed them all into the database
+#
+# ignored DROPPED descriptors
+
+require 'db'
+require 'socket'
+require 'yaml'
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+db.transaction_begin
+
+done = 0
+db.query('SELECT sd.ref FROM sd') { |row|
+	descriptor = db.query_row("SELECT descriptor.descriptor FROM descriptor WHERE ref=?", row['ref']);
+	puts row['ref'] unless descriptor
+
+	done = done + 1
+	if done == 500
+		STDERR.print "."
+		STDERR.flush
+		done = 0
+	end
+}
+
+db.transaction_commit


Property changes on: projects/tor-naming/trunk/test-if-all-sds-have-a-descriptor
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/List-all-sds-by-fpr.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/List-all-sds-by-fpr.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/List-all-sds-by-fpr.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'list-all-sds-by-fpr.rb'


Property changes on: projects/tor-naming/trunk/tor-naming-web/List-all-sds-by-fpr.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/List-nodes-died.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/List-nodes-died.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/List-nodes-died.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'list-nodes-died.rb'


Property changes on: projects/tor-naming/trunk/tor-naming-web/List-nodes-died.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/List-nodes-rejected.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/List-nodes-rejected.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/List-nodes-rejected.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'list-nodes-rejected.rb'


Property changes on: projects/tor-naming/trunk/tor-naming-web/List-nodes-rejected.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/List.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/List.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/List.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'list'


Property changes on: projects/tor-naming/trunk/tor-naming-web/List.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/Makefile
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/Makefile	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/Makefile	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,10 @@
+all: show-sd.rhtml list.rhtml show-fpr.rhtml show-nick.rhtml
+
+show-sd.rhtml: show-sd.html show-sd.plogic
+	kwartz -e -l eruby  -p show-sd.plogic show-sd.html > $@
+show-fpr.rhtml: show-fpr.html show-fpr.plogic
+	kwartz -e -l eruby  -p show-fpr.plogic show-fpr.html > $@
+show-nick.rhtml: show-nick.html show-nick.plogic
+	kwartz -e -l eruby  -p show-nick.plogic show-nick.html > $@
+list.rhtml: list.html list.plogic
+	kwartz -e -l eruby  -p list.plogic list.html > $@

Added: projects/tor-naming/trunk/tor-naming-web/Set_annotation.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/Set_annotation.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/Set_annotation.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'set_annotation'


Property changes on: projects/tor-naming/trunk/tor-naming-web/Set_annotation.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/Show-fpr.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/Show-fpr.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/Show-fpr.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'show-fpr'


Property changes on: projects/tor-naming/trunk/tor-naming-web/Show-fpr.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/Show-nick.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/Show-nick.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/Show-nick.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'show-nick'


Property changes on: projects/tor-naming/trunk/tor-naming-web/Show-nick.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/Show-sd.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/Show-sd.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/Show-sd.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+
+require 'show-sd'


Property changes on: projects/tor-naming/trunk/tor-naming-web/Show-sd.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/common.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/common.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/common.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,58 @@
+def error(msg)
+	print $cgi.header
+	puts msg
+	exit 0
+end
+
+def pretty_fpr(fpr)
+	res = ""
+	fpr.length.times{ |i|
+		res += fpr[i..i]
+		res += " " if (((i-3) % 4) == 0)
+	}
+	return res
+end
+
+def remove_at_signs(text)
+	return "(WTF!? nil?)" unless text
+	text.gsub('@', '.')
+end
+
+
+def has_bw_graph(fpr)
+	key = fpr[0..1]
+	return FileTest.exist?( "../tor-running-routers/#{key}/node-traf-#{fpr}.png" )
+end
+
+def bw_graph_url(fpr)
+	key = fpr[0..1]
+	return "../tor-running-routers/#{key}/node-traf-#{fpr}.png"
+end
+
+def genparams(params)
+	outparms = []
+	params.each_pair{ |k,v|
+		outparms << { 'key' => k, 'value' => v}
+	}
+	outparms
+end
+
+def do_contact(contact)
+	if contact == nil
+		return "unknown"
+	elsif contact == true
+		return "yes"
+	else
+		return "no"
+	end
+end
+
+def do_contact_short(contact)
+	if contact == nil
+		return "."
+	elsif contact == true
+		return "y"
+	else
+		return "n"
+	end
+end

Added: projects/tor-naming/trunk/tor-naming-web/db-config.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/db-config.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/db-config.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1 @@
+link ../db-config.rb
\ No newline at end of file


Property changes on: projects/tor-naming/trunk/tor-naming-web/db-config.rb
___________________________________________________________________
Added: svn:special
   + *

Added: projects/tor-naming/trunk/tor-naming-web/db.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/db.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/db.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1 @@
+link ../db.rb
\ No newline at end of file


Property changes on: projects/tor-naming/trunk/tor-naming-web/db.rb
___________________________________________________________________
Added: svn:special
   + *

Added: projects/tor-naming/trunk/tor-naming-web/format.css
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/format.css	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/format.css	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,59 @@
+body {
+	background-color:#ddddff;
+	font-color:#000000;
+}
+
+table {
+	background-color:#FFFFFF;
+	caption-side:left;
+	text-align:left;
+}
+
+table.frame { 
+	font-family:Arial,Helvetica;
+	background-color:#7777FF;
+}
+
+tr.titel_navigation { 
+	font-family:Arial,Helvetica;
+	background-color:#DDDDFF;
+}
+
+tr.login_navigation { 
+	font-family:Arial,Helvetica;
+	background-color:#7777FF;
+}
+
+table.frame a {
+	color:#101010;
+}
+
+input {
+	border-width:1
+}
+
+p.ind {
+  margin-left: 50px;
+}
+
+th {
+	vertical-align: top
+}
+
+h1 {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 21px;
+	font-style: normal;
+	line-height: normal;
+	font-weight: normal;
+	font-variant: normal;
+	text-transform: none }
+h2 {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 18px;
+	font-style: normal;
+	line-height: normal;
+	font-weight: normal;
+	font-variant: normal;
+	text-transform: none }
+

Added: projects/tor-naming/trunk/tor-naming-web/index.html
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/index.html	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/index.html	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,31 @@
+<html>
+<head>
+<title>Tor Name Binding at Tor26</title>
+<link rel="stylesheet" type="text/css" href="format.css">
+</head>
+<body>
+
+<table class="frame" width="100%">
+	<tr class="titel_navigation"><td>
+		<a href="/">www.noreply.org</a> ::
+		<a href="./">overview</a> ::
+		<span id="value:sd['nickname']">nickname</span> server descriptor
+	</td></tr>
+</table>
+
+<p>
+<table style="width:100%;"><tr><td>
+<ul>
+<li><a href="List.rb">Last few uploaded descriptors</a>
+<li><a href="List-nodes-rejected.rb">Nodes with rejected descriptors</a>
+<li><a href="List-nodes-died.rb">Nodes that stopped publishing recently</a>
+</ul>
+</td></tr></table>
+
+<p>
+<table class="frame" width="100%">
+	<tr><td class="header_navigation"><address><a href="mailto:web at palfrader.org">Peter Palfrader &lt;web at palfrader.org&gt;</a></td></tr>
+</table>
+
+</body>
+</html>

Added: projects/tor-naming/trunk/tor-naming-web/list-all-sds-by-fpr.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/list-all-sds-by-fpr.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/list-all-sds-by-fpr.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,53 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+fpr = $cgi.params['fpr'].first
+error "Evil person" unless fpr =~ /^[0-9A-F]{40}$/
+
+limit = $cgi.params['limit'].first
+limit = '500' unless limit
+error "Evil person" unless limit =~ /^[0-9]+$/
+limit = 500 if limit.to_i > 10000;
+
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+rows = db.query2("
+	SELECT
+		to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') as posted,
+		sd.ref,
+		sd.msg,
+		sd.nickname,
+		sd.version,
+		node.fingerprint,
+		action.action,
+		to_char( (SELECT named.named_since FROM named WHERE named.fingerprint = node.fingerprint AND UPPER(sd.nickname) = UPPER(named.name) ) AT TIME ZONE 'UTC', 'YYYY-MM-DD') as named_since
+	FROM
+		sd,
+		node,
+		action
+	WHERE   sd.node_ref = node.ref
+	    AND sd.action_ref = action.ref
+	    AND node.fingerprint = ?
+	ORDER BY
+		sd.posted DESC
+	LIMIT ?
+	", fpr, limit);
+
+legend="Show last #{limit} server descriptors by #{pretty_fpr(fpr)}"
+have_version=true
+have_comment=false
+show_params=true
+params = genparams({
+	'fpr' => fpr,
+	'limit' => limit })
+print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ERuby::import('list.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/list-all-sds-by-fpr.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/list-nodes-died.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/list-nodes-died.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/list-nodes-died.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,126 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+from = $cgi.params['from'].first
+from = '3' unless from
+error "Evil person 1" unless from =~ /^[0-9]+$/
+
+to = $cgi.params['to'].first
+to = '21' unless to
+error "Evil person 2" unless to =~ /^[0-9]+$/
+
+if to.to_i - from.to_i > 1000 then
+	from = 3
+	to = 21
+end
+
+minlivetime = $cgi.params['minlivetime'].first
+minlivetime = '1d' unless minlivetime
+minlivetime.delete!(" ")
+error "Evil person 3" unless minlivetime =~ /^(?:([0-9]+)y)?(?:([0-9]+)m)?(?:([0-9]+)d)?(?:([0-9]+)h)?$/
+
+ymdh = /^(?:([0-9]+)y)?(?:([0-9]+)m)?(?:([0-9]+)d)?(?:([0-9]+)h)?$/.match(minlivetime).to_a[1..4].collect{|l| l ? l.to_i : 0}
+minlive = "%d years %d months %d days %d hours"%ymdh
+
+
+minbw = $cgi.params['minbw'].first
+minbw = '0' unless minbw
+error "Evil person 4" unless minbw =~ /^[0-9]+$/
+
+filter = $cgi.params['filter'].first
+filter = '0' unless filter
+error "Evil person 5" unless filter =~ /^[01]$/
+filter = (filter == '1')
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+rows = db.query2("
+	SELECT
+		to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') as posted,
+		sd.ref,
+		sd.msg,
+		sd.nickname,
+		node.fingerprint,
+		node.max_capacity/1000 as max_capacity,
+		node.contact,
+		(NOT node.comment IS NULL) AS has_comment,
+		action.action,
+		to_char( (SELECT named.named_since FROM named WHERE named.fingerprint = node.fingerprint AND UPPER(sd.nickname) = UPPER(named.name) ) AT TIME ZONE 'UTC', 'YYYY-MM-DD') as named_since,
+		sd.version,
+		CASE WHEN latest.posted = latest.first_posted THEN 'only descriptor ever published' ELSE
+			EXTRACT(year   FROM latest.age) || 'y ' ||
+			EXTRACT(month  FROM latest.age) || 'm ' ||
+			EXTRACT(day    FROM latest.age) || 'd ' ||
+			EXTRACT(hour   FROM latest.age) || 'h ' ||
+			EXTRACT(minute FROM latest.age) || 'm'
+		END AS comment,
+		(SELECT count(*) FROM contact WHERE contact.node_ref = node.ref) AS contact_count
+	FROM
+		sd,
+		(
+			SELECT
+				node_ref,
+				max(posted) AS posted,
+				min(posted) AS first_posted,
+				age( max(posted), min(posted)) AS age
+			FROM
+				sd AS s
+			WHERE
+				action_ref != (SELECT ref FROM action WHERE action.action = 'DROPPED')
+			GROUP BY
+				node_ref
+		) AS latest,
+		node,
+		action
+	WHERE
+		sd.node_ref=latest.node_ref
+	    AND sd.posted=latest.posted
+	    AND sd.node_ref = node.ref
+	    AND (CURRENT_TIMESTAMP - sd.posted) > ? * INTERVAL '1 day'
+	    AND (CURRENT_TIMESTAMP - sd.posted) < ? * INTERVAL '1 day'
+	    AND sd.action_ref = action.ref
+	    AND age > ?
+	    AND node.max_capacity > ?*1024
+	" + (filter ?
+	"
+	    AND (node.contact OR node.contact IS NULL)
+	    AND (node.no_contact_until <= 'now' OR node.no_contact_until IS NULL)
+	" : "")+
+	"
+	ORDER BY
+		posted DESC;
+	", from, to, minlive, minbw);
+
+
+legend="Nodes that stopped publishing between #{from} and #{to} days ago, and have been alive for at least #{minlive} and had a capacity of at least #{minbw} kB/s at one time"
+if filter
+	legend = legend + " and filtered on ((contact==True or contact is null) and (no_contact_until <= now or no_contact_until is null))"
+end
+have_version = true
+have_comment = true
+have_comment2 = true
+have_comment3 = true
+have_comment4 = true
+have_comment5 = true
+comment_label = 'lived for'
+comment2_label = 'has contact?'
+comment3_label = 'max capacity [kB/s]'
+comment4_label = 'may contact'
+comment5_label = 'has comment'
+show_params=true
+params = genparams({
+	'from' => from,
+	'to' => to,
+	'minlivetime' => minlivetime,
+	'minbw' => minbw,
+	'filter' => filter ? 1 : 0})
+print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ERuby::import('list.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/list-nodes-died.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/list-nodes-rejected.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/list-nodes-rejected.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/list-nodes-rejected.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,60 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+days = $cgi.params['days'].first
+days = '7' unless days
+error "Evil person" unless days =~ /^[0-9]+$/
+days = 7 if days.to_i > 150;
+
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+rows = db.query2("
+	SELECT
+		to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') as posted,
+		sd.ref,
+		sd.msg,
+		sd.nickname,
+		node.fingerprint,
+		action.action,
+		to_char( (SELECT named.named_since FROM named WHERE named.fingerprint = node.fingerprint AND UPPER(sd.nickname) = UPPER(named.name) ) AT TIME ZONE 'UTC', 'YYYY-MM-DD') as named_since
+	FROM
+		sd,
+		(
+			SELECT
+				node_ref,
+				max(posted) as posted
+			FROM
+				sd AS s
+			WHERE
+				(CURRENT_TIMESTAMP - s.posted) < ? * INTERVAL '1 day'
+			GROUP BY
+				node_ref
+		) AS latest,
+		node,
+		action
+	WHERE
+		action.action = 'REJECTED'
+	    AND sd.action_ref = action.ref
+	    AND sd.node_ref = node.ref
+	    AND sd.node_ref=latest.node_ref
+	    AND sd.posted=latest.posted
+	ORDER BY
+		posted DESC;
+	", days);
+
+legend="Nodes with rejected descriptors in the last few days"
+have_version=false
+have_comment=false
+show_params=true
+params = genparams({
+	'days' => days })
+print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ERuby::import('list.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/list-nodes-rejected.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/list.html
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/list.html	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/list.html	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,74 @@
+<html>
+<head>
+<title id="value:legend">Uploaded descriptors</title>
+<link rel="stylesheet" type="text/css" href="format.css">
+</head>
+<body>
+
+<table class="frame" width="100%">
+	<tr class="titel_navigation"><td>
+		<a href="/">www.noreply.org</a> ::
+		<a href="./">overview</a> ::
+		<span id="value:legend">nickname</span>
+	</td></tr>
+</table>
+<p>
+[Page is cached client-side for a while, force reload if you think it's stale]
+<p>
+<span id="value:legend">Last few accepted and rejected descriptors at the tor26 directory server</span>
+<p>
+<table style="width:100%;"><tr><td>
+	<fieldset>
+	<!--<legend id="value:legend">Last few accepted and rejected descriptors at the tor26 directory server</legend>-->
+	<table>
+	<tr>
+		<th>SD Posted</th>
+		<th>Fingerprint</th>
+		<th>Named</th>
+		<th>Nickname</th>
+		<th>Action</th>
+		<th>[sd]</th>
+		<span id="has_version_column1"><th>Version</th></span>
+		<span id="has_comment_column1"><th id="value:comment_label"></th></span>
+		<span id="has_comment2_column1"><th id="value:comment2_label" align="center"></th></span>
+		<span id="has_comment3_column1"><th id="value:comment3_label" align="right"></th></span>
+		<span id="has_comment4_column1"><th id="value:comment4_label" align="center"></th></span>
+		<span id="has_comment5_column1"><th id="value:comment5_label" align="center"></th></span>
+	</tr>
+	<tr id="descriptors">
+		<td id="value:row['posted']">Posted</td>
+		<td><a href="Show-fpr.rb?fpr=<span id="value:row['fingerprint']"></span>"><code id="value:pretty_fpr(row['fingerprint'])">fpr</code></a></td>
+		<td align="center" id="named">yes/no</td>
+		<td><a href="Show-nick.rb?nick=<span id="value:row['nickname']"></span>"><span id="value:row['nickname']">nick</span></a></td>
+		<td id="actionmsg">action</td>
+		<td><a id="linksd" href="Show-sd.rb?sd_ref=1">desc</a></td>
+		<span id="has_version_column2"><td id="value:row['version']">version</td></span>
+		<span id="has_comment_column2"><td id="value:row['comment']">comment</td></span>
+		<span id="has_comment2_column2"><td id="has_contacts" align="center">ja/nein</td></span>
+		<span id="has_comment3_column2"><td id="value:row['max_capacity']" align="right">102356</td></span>
+		<span id="has_comment4_column2"><td id="node_contact" align="center">y/n/?</td></span>
+		<span id="has_comment5_column2"><td id="node_has_comment" align="center">y/_</td></span>
+	</tr>
+	</table>
+	</fieldset>
+</td></tr></table>
+
+<span id="show_params">
+	<p>
+	<form method="GET">
+	<table>
+		<tr id="params">
+			<th id="value:param['key']">Key</th><td><input type="text" name="<span id="value:param['key']"></span>" value="<span id="value:param['value']"></span>"></td>
+		</tr>
+	</table>
+	<input type="submit">
+	</form>
+</span>
+<p>
+<table class="frame" width="100%">
+	<tr><td class="header_navigation"><address><a href="mailto:web at palfrader.org">Peter Palfrader &lt;web at palfrader.org&gt;</a></td>
+	    <td class="header_navigation" align="right">Built at <span id="value:utc_timestamp">jetzt ungefaehr</span>.  It's probably cached on your end for a while.</td></tr>
+</table>
+
+</body>
+</html>

Added: projects/tor-naming/trunk/tor-naming-web/list.plogic
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/list.plogic	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/list.plogic	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,53 @@
+// vim:syn=off
+
+#actionmsg {
+	remove: "id";
+	attr: "bgcolor" ( row['action'] == "REJECTED" ? "red" : "lightgreen" );
+	value: row['action'] + ": " + row['msg'];
+}
+
+#named {
+	remove: "id";
+	value: row['named_since'] ? row['named_since'] : "no";
+}
+
+#linksd {
+	remove: "id";
+	attr: "href" ("Show-sd.rb?sd_ref=" + String(row['ref']));
+}
+
+#descriptors {
+	attr:  "bgcolor" color;
+	remove: "id";
+	plogic: {
+		i = 0;
+		while (row = rows.next) {
+			i += 1;
+			color = i % 3 == 2 ? '#EEEEEE' : '#FFFFFF';
+			@stag;
+			@cont;
+			@etag;
+		}
+	}
+}
+#has_version_column1 { remove: "id"; plogic: { if (have_version) { @stag; @cont; @etag; } } }
+#has_version_column2 { remove: "id"; plogic: { if (have_version) { @stag; @cont; @etag; } } }
+#has_comment_column1 { remove: "id"; plogic: { if (have_comment) { @stag; @cont; @etag; } } }
+#has_comment_column2 { remove: "id"; plogic: { if (have_comment) { @stag; @cont; @etag; } } }
+#has_comment2_column1 { remove: "id"; plogic: { if (have_comment && have_comment2) { @stag; @cont; @etag; } } }
+#has_comment2_column2 { remove: "id"; plogic: { if (have_comment && have_comment2) { @stag; @cont; @etag; } } }
+#has_comment3_column1 { remove: "id"; plogic: { if (have_comment && have_comment2 && have_comment3) { @stag; @cont; @etag; } } }
+#has_comment3_column2 { remove: "id"; plogic: { if (have_comment && have_comment2 && have_comment3) { @stag; @cont; @etag; } } }
+#has_comment4_column1 { remove: "id"; plogic: { if (have_comment && have_comment2 && have_comment3 && have_comment4) { @stag; @cont; @etag; } } }
+#has_comment4_column2 { remove: "id"; plogic: { if (have_comment && have_comment2 && have_comment3 && have_comment4) { @stag; @cont; @etag; } } }
+#has_comment5_column1 { remove: "id"; plogic: { if (have_comment && have_comment2 && have_comment3 && have_comment4 && have_comment5) { @stag; @cont; @etag; } } }
+#has_comment5_column2 { remove: "id"; plogic: { if (have_comment && have_comment2 && have_comment3 && have_comment4 && have_comment5) { @stag; @cont; @etag; } } }
+
+#show_params { remove: "id"; plogic: { if (show_params) { @stag; @cont; @etag; } } }
+#params { remove: "id"; plogic: { foreach (param in params) { @stag; @cont; @etag; } } }
+
+#has_contacts   { remove: "id"; value: row['contact_count'] > 0 ? "Yes" : "No"; }
+
+
+#node_contact           { remove: "id"; value: do_contact_short(row['contact']); }
+#node_has_comment       { remove: "id"; value: row['has_comment'] ? "y" : "-"; }

Added: projects/tor-naming/trunk/tor-naming-web/list.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/list.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/list.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,51 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+limit = $cgi.params['limit'].first
+limit = '200' unless limit
+error "Evil person" unless limit =~ /^[0-9]+$/
+limit = 200 if limit.to_i > 1000;
+
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+rows = db.query2("
+	SELECT
+		to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') as posted,
+		sd.ref,
+		sd.msg,
+		sd.nickname,
+		node.fingerprint,
+		action.action,
+		to_char( (SELECT named.named_since FROM named WHERE named.fingerprint = node.fingerprint AND UPPER(sd.nickname) = UPPER(named.name) ) AT TIME ZONE 'UTC', 'YYYY-MM-DD') as named_since
+	FROM
+		(SELECT sd.ref, sd.msg, sd.nickname, sd.action_ref, sd.posted, sd.node_ref
+		 FROM sd
+		 ORDER BY posted DESC
+		 LIMIT ?
+		) AS sd,
+		node,
+		action
+	WHERE   sd.node_ref = node.ref
+	    AND sd.action_ref = action.ref
+	    AND NOT action.action='DROPPED'
+	ORDER BY
+		sd.posted
+	", limit);
+
+legend="Last few accepted and rejected descriptors at the tor26 directory server"
+have_version=false
+have_comment=false
+show_params=true
+params = genparams({
+	'limit' => limit })
+print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ERuby::import('list.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/list.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/list.rb-bak2
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/list.rb-bak2	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/list.rb-bak2	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,42 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+limit = $cgi.params['limit'].first
+limit = '200' unless limit
+error "Evil person" unless limit =~ /^[0-9]+$/
+limit = 200 if limit.to_i > 1000;
+
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+rows = db.query_all("
+	SELECT
+		to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') as posted,
+		sd.ref,
+		sd.msg,
+		sd.nickname,
+		node.fingerprint,
+		action.action,
+		to_char(named.named_since AT TIME ZONE 'UTC', 'YYYY-MM-DD') as named_since
+	FROM
+			sd
+		JOIN	node
+		ON	sd.node_ref = node.ref
+		JOIN	action
+		ON	sd.action_ref = action.ref
+		LEFT JOIN named
+		ON	named.fingerprint = node.fingerprint AND UPPER(sd.nickname) = UPPER(named.name)
+	WHERE	NOT action.action='DROPPED'
+	ORDER BY posted DESC
+	LIMIT	?", limit);
+
+legend="Last few accepted and rejected descriptors at the tor26 directory server"
+print $cgi.header
+ERuby::import('list.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/list.rb-bak2
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/set_annotation.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/set_annotation.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/set_annotation.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,67 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+fpr = $cgi.params['fpr'].first
+error "Evil person" unless fpr =~ /^[0-9A-F]{40}$/
+
+contact = $cgi.params['contact'].first
+error "Evil person" unless contact == nil or contact =~ /^[FTN]$/
+
+no_contact_until = $cgi.params['no_contact_until'].first
+error "Evil person" unless no_contact_until == nil or no_contact_until == "" or no_contact_until =~ /^\d\d\d\d-\d\d-\d\d$/ or no_contact_until == "now"
+
+last_contacted = $cgi.params['last_contacted'].first
+error "Evil person" unless last_contacted == nil or last_contacted == "" or last_contacted =~ /^\d\d\d\d-\d\d-\d\d$/ or last_contacted == "now"
+
+comment = $cgi.params['comment'].first
+# no check.
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+db.transaction_begin
+node = db.query_row("SELECT ref FROM node WHERE fingerprint=?", fpr);
+error "No host with fpr #{fpr} found" unless node['ref']
+
+update = {}
+if contact == "T" or contact == 'F'
+	update['contact'] = contact
+elsif contact == "N"
+	update['contact'] = nil
+end
+
+if no_contact_until =~ /^\d\d\d\d-\d\d-\d\d$/ or no_contact_until == "now"
+	update['no_contact_until'] = no_contact_until
+elsif no_contact_until == ""
+	update['no_contact_until'] = nil
+end
+
+if last_contacted =~ /^\d\d\d\d-\d\d-\d\d$/ or last_contacted == "now"
+	update['last_contacted'] = last_contacted
+elsif last_contacted == ""
+	update['last_contacted'] = nil
+end
+
+if comment == ""
+	update['comment'] = nil
+elsif comment
+	update['comment'] = comment
+end
+
+update['ref'] = node['ref']
+db.update_row('node', update);
+db.transaction_commit
+
+##print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+#print $cgi.header( 'Expires' => Time.now + (1 * 15) )
+#utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+#ERuby::import('show-fpr.rhtml')
+
+print $cgi.header( { 'Status' => '302 Moved', 'location' => "Show-fpr.rb?fpr=#{fpr}" } )
+puts "Redirecting you to Show-fpr.rb?fpr=#{fpr}"


Property changes on: projects/tor-naming/trunk/tor-naming-web/set_annotation.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/show-fpr.html
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-fpr.html	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-fpr.html	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,99 @@
+<html>
+<head>
+<title>Serverinformation for <span id="value:pretty_fpr(node['fingerprint'])">nickname</span></title>
+<link rel="stylesheet" type="text/css" href="format.css">
+</head>
+<body>
+
+<table class="frame" width="100%">
+	<tr class="titel_navigation"><td>
+		<a href="/">www.noreply.org</a> ::
+		<a href="./">overview</a> ::
+		Node with fingerprint <code id="value:pretty_fpr(node['fingerprint'])">nickname</code>
+	</td></tr>
+</table>
+
+<p>
+<table style="width:100%;"><tr><td>
+	<fieldset>
+	<legend>Node with fingerprint <code id="value:pretty_fpr(node['fingerprint'])">nickname</code></legend>
+	<table>
+		<tr><th>Fingerprint:</th> <td><code id="value:pretty_fpr(node['fingerprint'])">nickname</code></td></tr>
+		<tr><th colspan=2">&nbsp;</td></tr>
+		<tr><th>Does a nickname bind to this fingerprint?:</th> <td id="is_named">yes/no</td></tr>
+		<span id="if_is_named">
+			<tr><th>Binding nick:</th> <td id="value:named['name']">foobar</td><tr>
+			<tr><th>Bound since:</th>  <td id="value:named['named_since']">2005-01-01</td><tr>
+		</span>
+		<tr><th>Max capacity ever reported:</th>
+		    <td><span id="value:node['max_capacity']">12345678</span> kB/s</td></tr>
+
+		<form action="Set_annotation.rb" method="post">
+			<input type="hidden" name="fpr" value="<span id="value:node['fingerprint']">nickname</span>">
+			<!--<tr><th>Contact:</th><td><span id="node_contact">Y/N/?</span></td></tr>-->
+			<tr><th>Ok to contact:</th><td><input type="radio" name="contact" value="T" id="append:node['contact']==true?' checked':''"> yes<br>
+			                               <input type="radio" name="contact" value="F" id="append:node['contact']==false?' checked':''"> no<br>
+			                               <input type="radio" name="contact" value="N" id="append:node['contact']==nil?' checked':''"> not set
+			</td></tr>
+			<!--<tr><th>Do not contact until:</th><td><span id="node_no_contact_until">-</span></td></tr>-->
+			<tr><th>Do not contact until:</th><td><input type="text" name="no_contact_until" value="<span id="value:node['no_contact_until']"></span>" size="10"> ("yyyy-mm-dd" or "now")</td></tr>
+			<!--<tr><th>Last contacted:</th><td><span id="node_last_contacted">-</span></td></tr>-->
+			<tr><th>Last contacted:</th><td><input type="text" name="last_contacted" value="<span id="value:node['last_contacted']"></span>" size="10"> ("yyyy-mm-dd" or "now")</td></tr>
+			<tr><th>Comment:</th><td><textarea name="comment" cols="50" rows="12" wrap="hard"><span id="value:node['comment']">-</span></textarea><br>
+			        <small>(Please sign your additions with <code>--&lt;name&gt;</code> or similar)</small>
+			        <p>
+			        <input type="submit"> <input type="reset"></td></tr>
+		</form>
+
+
+		<span id="nicknames">
+			<tr><th colspan=2">&nbsp;</td></tr>
+			<tr><th>Nickname:</th>
+			    <td><a href="Show-nick.rb?nick=<span id="value:nick['nickname']">nickname</span>"><span id="value:nick['nickname']">nickname</span><span id="number_of_fingerprints_with_this_nick"> (3!)</span></a></td></tr>
+			<tr><th>Latest descriptor posted:</th>
+			    <td id="lastpost_color"
+			       ><a href="Show-sd.rb?sd_ref=<span id="value:nick['lastpost_ref']"></span>"
+			       ><span id="value:nick['lastpost_action']">NOBODYCARED</span>:
+			        <span id="value:nick['lastpost_date']">2005-01-01 23:21:13</span>;
+				<span id="value:nick['lastpost_version']">0815</span></a></td></tr>
+			<tr><th>First descriptor posted:</th>
+			    <td id="firstpost_color"
+			       ><a href="Show-sd.rb?sd_ref=<span id="value:nick['firstpost_ref']"></span>"
+			       ><span id="value:nick['firstpost_action']">NOBODYCARED</span>:
+			        <span id="value:nick['firstpost_date']">2005-01-01 23:21:13</span>;
+				<span id="value:nick['firstpost_version']">0815</span></a></td></tr>
+		</span>
+
+		<span id="has_contacts">
+			<tr><th>Contacts:</th>
+			    <td>
+			    <span id="contacts"><span id="value:remove_at_signs(contact['contact'])">foo at bar</span> -
+			      last seen in <a href="Show-sd.rb?sd_ref=<span id="value:contact['lastseen_sd_ref']"></span>">SD from
+			      <span id="value:contact['lastseen']">gestern</span></a><br></span></td></tr>
+		</span>
+
+		<tr><th>Versions:</th>
+		    <td>
+		    <span id="versions"><span id="value:version['version']">foo at bar</span> -
+		      last seen in <a href="Show-sd.rb?sd_ref=<span id="value:version['lastseen_sd_ref']"></span>">SD from
+		      <span id="value:version['lastseen']">gestern</span></a><br></span></td></tr>
+
+		<tr><th>Server Descriptors:</td>
+		    <td><a href="List-all-sds-by-fpr.rb?fpr=<span id="value:node['fingerprint']"></span>">List them</a></td></tr>
+
+		<span id="has_bw_graph">
+			<tr><td colspan="2"><strong>Bandwidth history:</strong><br>
+			    <img id="bw_graph" align="right"></td></tr>
+		</span>
+	</table>
+	</fieldset>
+</td></tr></table>
+
+<p>
+<table class="frame" width="100%">
+	<tr><td class="header_navigation"><address><a href="mailto:web at palfrader.org">Peter Palfrader &lt;web at palfrader.org&gt;</a></td>
+	    <td class="header_navigation" align="right">Built at <span id="value:utc_timestamp">jetzt ungefaehr</span>.  It's probably cached on your end for a while.</td></tr>
+</table>
+
+</body>
+</html>

Added: projects/tor-naming/trunk/tor-naming-web/show-fpr.plogic
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-fpr.plogic	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-fpr.plogic	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,44 @@
+// vim:syn=off
+
+#is_named       { remove: "id"; value: named ? "Yes" : "No"; }
+
+#if_is_named {
+	remove: "id";
+	plogic: {
+		if (named) {
+			@stag;
+			@cont;
+			@etag;
+		}
+	}
+}
+
+#nicknames {
+	remove: "id";
+	plogic: {
+		while (nick = nicknames.next) {
+			@stag;    // start tag
+			@cont;    // content
+			@etag;    // end tag
+		}
+	}
+}
+
+#number_of_fingerprints_with_this_nick  { remove: "id"; value: nick['number_of_fingerprints_with_this_nick'] == 1 ? "" : (" (%d!)"%nick['number_of_fingerprints_with_this_nick'] ); }
+
+#firstpost_color { remove: "id"; attr: "bgcolor" ( nick['firstpost_action'] == "REJECTED" ? "red" : "lightgreen" ); }
+#lastpost_color  { remove: "id"; attr: "bgcolor" ( nick['lastpost_action'] == "REJECTED" ? "red" : "lightgreen" ); }
+
+#has_bw_graph    { remove: "id"; plogic: { if (has_bw_graph( node['fingerprint'] )) { @stag; @cont; @etag; } } }
+#bw_graph        { remove: "id"; attr: "src" ( bw_graph_url( node['fingerprint'] ) ), "alt" ( "Bandwidth graph for ".+node['fingerprint'] ); }
+
+
+
+#has_contacts { remove: "id"; plogic: { if (contacts.size > 0) { @stag; @cont; @etag; } } }
+#contacts { remove: "id"; plogic: { foreach (contact in contacts) { @stag; @cont; @etag; } } }
+#versions { remove: "id"; plogic: { foreach (version in versions) { @stag; @cont; @etag; } } }
+
+#node_contact           { remove: "id"; value: do_contact(node['contact']); }
+#node_no_contact_until  { remove: "id"; value: node['no_contact_until'] || "-"; }
+#node_last_contacted    { remove: "id"; value: node['last_contacted'  ] || "-"; }
+#node_comment           { remove: "id"; value: node['comment'         ] || "-"; }

Added: projects/tor-naming/trunk/tor-naming-web/show-fpr.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-fpr.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-fpr.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,73 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+fpr = $cgi.params['fpr'].first
+error "Evil person" unless fpr =~ /^[0-9A-F]{40}$/
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+node = db.query_row("SELECT *, max_capacity/1024 AS max_capacity FROM node WHERE fingerprint=?", fpr);
+error "not found" unless node
+named = db.query_row("SELECT * FROM named WHERE fingerprint=?", fpr);
+contacts = db.query_all("SELECT contact.contact, contact.lastseen_sd_ref,
+	to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS lastseen
+	FROM contact, sd WHERE contact.node_ref=? AND contact.lastseen_sd_ref=sd.ref ORDER BY sd.posted DESC", node['ref']);
+versions = db.query_all("SELECT version.version, version.lastseen_sd_ref,
+	to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS lastseen
+	FROM version, sd WHERE version.node_ref=? AND version.lastseen_sd_ref=sd.ref ORDER BY sd.posted DESC", node['ref']);
+nicknames = db.query2("
+	SELECT
+		subquery.nickname,
+		subquery.firstpost_ref AS firstpost_ref,
+		subquery.lastpost_ref AS lastpost_ref,
+
+		to_char(firstpost.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS firstpost_date,
+		to_char(lastpost.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS lastpost_date,
+
+		firstpostaction.action AS firstpost_action,
+		lastpostaction.action AS lastpost_action,
+
+		firstpost.version AS firstpost_version,
+		lastpost.version AS lastpost_version,
+
+		(SELECT count(DISTINCT node_ref) FROM sd WHERE UPPER(nickname) = UPPER(subquery.nickname)) AS number_of_fingerprints_with_this_nick
+	FROM
+		(SELECT
+			sd.nickname,
+			(SELECT ref FROM sd AS s WHERE s.node_ref = ? AND UPPER(s.nickname)=UPPER(sd.nickname) ORDER BY posted DESC LIMIT 1) AS lastpost_ref,
+			(SELECT ref FROM sd AS s WHERE s.node_ref = ? AND UPPER(s.nickname)=UPPER(sd.nickname) ORDER BY posted ASC  LIMIT 1) AS firstpost_ref
+		FROM
+			(SELECT DISTINCT
+				sd.nickname
+			FROM
+				sd
+			WHERE
+				sd.node_ref = ?) AS sd
+		) AS subquery,
+		sd AS firstpost,
+		sd AS lastpost,
+		action AS firstpostaction,
+		action AS lastpostaction
+	WHERE
+		firstpost.ref = subquery.firstpost_ref
+	    AND lastpost.ref = subquery.lastpost_ref
+	    AND firstpost.action_ref = firstpostaction.ref
+	    AND lastpost.action_ref = lastpostaction.ref
+	ORDER BY
+		lastpost.posted DESC
+	;
+", node['ref'], node['ref'], node['ref'])
+
+#print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+#print $cgi.header( 'Expires' => Time.now + (1 * 15) )
+#print $cgi.header( 'Expires' => Time.now )
+print $cgi.header()
+utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ERuby::import('show-fpr.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/show-fpr.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/show-nick.html
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-nick.html	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-nick.html	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,87 @@
+<html>
+<head>
+<title>Serverinformation for <span id="value:nick">nickname</span></title>
+<link rel="stylesheet" type="text/css" href="format.css">
+</head>
+<body>
+
+<table class="frame" width="100%">
+	<tr class="titel_navigation"><td>
+		<a href="/">www.noreply.org</a> ::
+		<a href="./">overview</a> ::
+		Nodes with nickname <span id="value:nick">nickname</span>
+	</td></tr>
+</table>
+
+<p>
+<table style="width:100%;"><tr><td>
+	<fieldset>
+	<legend>Nodes with nickname <span id="value:nick">nickname</span></legend>
+	<table>
+		<tr><th>Nickname:</th> <td><span id="value:nick">nickname</span></td></tr>
+		<tr><th colspan=2">&nbsp;</td></tr>
+		<tr><th>Does this nickname bind to a fingerprint?:</th> <td id="is_named">yes/no</td></tr>
+		<span id="if_is_named">
+			<tr><th>Bound to:</th>     <td><code id="value:pretty_fpr(named['fingerprint'])">nickname</code></td>
+			<tr><th>Bound since:</th>  <td id="value:named['named_since']">2005-01-01</td><tr>
+		</span>
+
+		<span id="nodes">
+			<tr><th colspan=2">&nbsp;</td></tr>
+			<tr><th>Fingerprint:</th>
+			    <td><a href="Show-fpr.rb?fpr=<span id="value:node['fingerprint']">nickname</span>"><code id="value:pretty_fpr(node['fingerprint'])">nickname</code><span id="number_of_nicks_with_this_fingerprint"> (3!)</span></a></td></tr>
+			<tr><th>Latest descriptor posted:</th>
+			    <td id="lastpost_color"
+			       ><a href="Show-sd.rb?sd_ref=<span id="value:node['lastpost_ref']"></span>"
+			       ><span id="value:node['lastpost_action']">NOBODYCARED</span>: 
+			        <span id="value:node['lastpost_date']">2005-01-01 23:21:13</span>;
+				<span id="value:node['lastpost_version']">0815</span></a></td></tr>
+
+			<tr><th>First descriptor posted:</th>
+			    <td id="firstpost_color"
+			       ><a href="Show-sd.rb?sd_ref=<span id="value:node['firstpost_ref']"></span>"
+			       ><span id="value:node['firstpost_action']">NOBODYCARED</span>: 
+			        <span id="value:node['firstpost_date']">2005-01-01 23:21:13</span>;
+				<span id="value:node['firstpost_version']">0815</span></a></td></tr>
+
+			<tr><th>Max capacity ever reported:</th>
+			    <td><span id="value:node['max_capacity']">12345678</span> kB/s</td></tr>
+			<tr><th>Ok to contact:</th><td><span id="node_contact">Y/N/?</span></td></tr>
+			<tr><th>Do not contact until:</th><td><span id="node_no_contact_until">-</span></td></tr>
+			<tr><th>Last contacted:</th><td><span id="node_last_contacted">-</span></td></tr>
+			<tr><th>Comment:</th><td><pre><span id="node_comment">-</span></pre></td></tr>
+
+			<span id="has_contacts">
+				<tr><th>Contacts:</th>
+				    <td>
+				    <span id="contacts"><span id="value:remove_at_signs(contact['contact'])">foo at bar</span> -
+				      last seen in <a href="Show-sd.rb?sd_ref=<span id="value:contact['lastseen_sd_ref']"></span>">SD from
+				      <span id="value:contact['lastseen']">gestern</span></a><br></span></td></tr>
+			</span>
+			
+			<tr><th>Versions:</th>
+			    <td>
+			    <span id="versions"><span id="value:version['version']">foo at bar</span> -
+			      last seen in <a href="Show-sd.rb?sd_ref=<span id="value:version['lastseen_sd_ref']"></span>">SD from
+			      <span id="value:version['lastseen']">gestern</span></a><br></span></td></tr>
+
+			<tr><th>Server Descriptors:</td>
+			    <td><a href="List-all-sds-by-fpr.rb?fpr=<span id="value:node['fingerprint']"></span>">List them</a></td></tr>
+
+			<span id="has_bw_graph">
+				<tr><td colspan="2"><strong>Bandwidth history:</strong><br>
+				    <img id="bw_graph" align="right"></td></tr>
+			</span>
+		</span>
+	</table>
+	</fieldset>
+</td></tr></table>
+
+<p>
+<table class="frame" width="100%">
+	<tr><td class="header_navigation"><address><a href="mailto:web at palfrader.org">Peter Palfrader &lt;web at palfrader.org&gt;</a></td>
+	    <td class="header_navigation" align="right">Built at <span id="value:utc_timestamp">jetzt ungefaehr</span>.  It's probably cached on your end for a while.</td></tr>
+</table>
+
+</body>
+</html>

Added: projects/tor-naming/trunk/tor-naming-web/show-nick.plogic
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-nick.plogic	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-nick.plogic	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,44 @@
+// vim:syn=off
+
+#is_named       { remove: "id"; value: named ? "Yes" : "No"; }
+
+#if_is_named {
+	remove: "id";
+	plogic: {
+		if (named) {
+			@stag;
+			@cont;
+			@etag;
+		}
+	}
+}
+
+
+#nodes {
+	remove: "id";
+	plogic: {
+		foreach (node in nodes) {
+			@stag;    // start tag
+			@cont;    // content
+			@etag;    // end tag
+		}
+	}
+}
+
+#number_of_nicks_with_this_fingerprint  { remove: "id"; value: node['number_of_nicks_with_this_fingerprint'] == 1 ? "" : " (%d!)"%node['number_of_nicks_with_this_fingerprint']; }
+#firstpost_color { remove: "id"; attr: "bgcolor" ( node['firstpost_action'] == "REJECTED" ? "red" : "lightgreen" ); }
+#lastpost_color { remove: "id"; attr: "bgcolor" ( node['lastpost_action'] == "REJECTED" ? "red" : "lightgreen" ); }
+
+#has_bw_graph    { remove: "id"; plogic: { if (has_bw_graph( node['fingerprint'] )) { @stag; @cont; @etag; } } }
+#bw_graph        { remove: "id"; attr: "src" ( bw_graph_url( node['fingerprint'] ) ), "alt" ( "Bandwidth graph for ".+node['fingerprint'] ); }
+
+
+
+#has_contacts { remove: "id"; plogic: { if (node['contacts']) { @stag; @cont; @etag; } } }
+#contacts { remove: "id"; plogic: { foreach (contact in node['contacts']) { @stag; @cont; @etag; } } }
+#versions { remove: "id"; plogic: { foreach (version in node['versions']) { @stag; @cont; @etag; } } }
+
+#node_contact           { remove: "id"; value: do_contact(node['contact']); }
+#node_no_contact_until  { remove: "id"; value: node['no_contact_until'] || "-"; }
+#node_last_contacted    { remove: "id"; value: node['last_contacted'  ] || "-"; }
+#node_comment           { remove: "id"; value: node['comment'         ] || "-"; }

Added: projects/tor-naming/trunk/tor-naming-web/show-nick.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-nick.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-nick.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,83 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+require 'yaml'
+
+$cgi = CGI.new
+
+nick = $cgi.params['nick'].first
+error "Evil person" unless nick =~ /^[0-9A-Za-z]{1,40}$/
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+named = db.query_row("SELECT * FROM named WHERE UPPER(name)=UPPER(?)", nick);
+nodes = []
+db.query("
+	SELECT
+		node.fingerprint,
+		node.max_capacity/1024 AS max_capacity,
+		node.ref,
+		node.contact,
+		node.no_contact_until,
+		node.last_contacted,
+		node.comment,
+		subquery.firstpost_ref AS firstpost_ref,
+		subquery.lastpost_ref AS lastpost_ref,
+
+		to_char(firstpost.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS firstpost_date,
+		to_char(lastpost.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS lastpost_date,
+
+		firstpostaction.action AS firstpost_action,
+		lastpostaction.action AS lastpost_action,
+
+		firstpost.version AS firstpost_version,
+		lastpost.version AS lastpost_version,
+
+		(SELECT count(DISTINCT UPPER(nickname)) FROM sd WHERE node_ref = subquery.node_ref) AS number_of_nicks_with_this_fingerprint
+	FROM
+		(SELECT
+			sd.node_ref,
+			(SELECT ref FROM sd AS s WHERE s.node_ref = sd.node_ref AND UPPER(s.nickname)=UPPER(?) ORDER BY posted DESC LIMIT 1) AS lastpost_ref,
+			(SELECT ref FROM sd AS s WHERE s.node_ref = sd.node_ref AND UPPER(s.nickname)=UPPER(?) ORDER BY posted ASC  LIMIT 1) AS firstpost_ref
+		FROM
+			(SELECT DISTINCT
+				sd.node_ref
+			FROM
+				sd
+			WHERE
+				UPPER(sd.nickname) = UPPER(?)) AS sd
+		) AS subquery,
+		sd AS firstpost,
+		sd AS lastpost,
+		action AS firstpostaction,
+		action AS lastpostaction,
+		node
+	WHERE
+		firstpost.ref = subquery.firstpost_ref
+	    AND lastpost.ref = subquery.lastpost_ref
+	    AND firstpost.action_ref = firstpostaction.ref
+	    AND lastpost.action_ref = lastpostaction.ref
+	    AND node.ref = subquery.node_ref
+	ORDER BY
+		lastpost.posted DESC
+	;
+", nick, nick, nick) { |row|
+	row['contacts'] = db.query_all("SELECT contact.contact, contact.lastseen_sd_ref,
+		to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS lastseen
+		FROM contact, sd WHERE contact.node_ref=? AND contact.lastseen_sd_ref=sd.ref ORDER BY sd.posted DESC", row['ref']);
+	row['versions'] = db.query_all("SELECT version.version, version.lastseen_sd_ref,
+		to_char(sd.posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS lastseen
+		FROM version, sd WHERE version.node_ref=? AND version.lastseen_sd_ref=sd.ref ORDER BY sd.posted DESC", row['ref']);
+	nodes << row
+}
+
+#print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+#print $cgi.header( 'Expires' => Time.now + (1 * 15) )
+#print $cgi.header( 'Expires' => Time.now )
+print $cgi.header()
+utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ERuby::import('show-nick.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/show-nick.rb
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/tor-naming/trunk/tor-naming-web/show-sd.html
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-sd.html	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-sd.html	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,47 @@
+<html>
+<head>
+<title>Serverdescriptor</title>
+<link rel="stylesheet" type="text/css" href="format.css">
+</head>
+<body>
+
+<table class="frame" width="100%">
+	<tr class="titel_navigation"><td>
+		<a href="/">www.noreply.org</a> ::
+		<a href="./">overview</a> ::
+		<span id="value:sd['nickname']">nickname</span> server descriptor
+	</td></tr>
+</table>
+
+<p>
+<table style="width:100%;"><tr><td>
+	<fieldset>
+	<legend>Server descriptor for router claiming to be <span id="value:sd['nickname']">nickname</span></legend>
+	<table>
+	<tr><th>Fingerprint:</th><td><a href="Show-fpr.rb?fpr=<span id="value:node['fingerprint']"></span>"><span id="value:pretty_fpr(node['fingerprint'])">fingerprint</span></a></td></tr>
+	<tr><th>Nickname:</th>   <td><a href="Show-nick.rb?nick=<span id="value:sd['nickname']"></span>"><span id="value:sd['nickname']">nickname</span></a></td></tr>
+	<tr><th>Named:</th>      <td id="named">yes/no</td></tr>
+	<span id="have_named_since">
+		<tr><th>Named since:</th>      <td id="value:named['named_since']">1.4.2005</td></tr>
+	</span>
+	<tr><th>Posted:</th>     <td id="value:sd['posted']">posted</td></tr>
+	<tr><th>Action:</th>     <td id="value:action['action']">action</td></tr>
+	<tr><th>&nbsp;</th>      <td id="value:sd['msg']">msg</td></tr>
+	<tr><th>Descriptor:</th> <td><pre id="value:remove_at_signs(sd['descriptor'])">router foo
+	bla
+	flub
+	opt foobar
+	sadfsadfdsaf
+	sadfasdfasdf</pre></td></tr>
+	</table>
+	</fieldset>
+</td></tr></table>
+
+<p>
+<table class="frame" width="100%">
+	<tr><td class="header_navigation"><address><a href="mailto:web at palfrader.org">Peter Palfrader &lt;web at palfrader.org&gt;</a></td>
+	    <td class="header_navigation" align="right">Built at <span id="value:utc_timestamp">jetzt ungefaehr</span>.  It's probably cached on your end for a while.</td></tr>
+</table>
+
+</body>
+</html>

Added: projects/tor-naming/trunk/tor-naming-web/show-sd.plogic
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-sd.plogic	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-sd.plogic	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,14 @@
+// vim:syn=off
+
+#named       { remove: "id"; value: named ? "Yes" : "No"; }
+
+#have_named_since {
+	remove: "id";
+	plogic: {
+		if (named) {
+			@stag;
+			@cont;
+			@etag;
+		}
+	}
+}

Added: projects/tor-naming/trunk/tor-naming-web/show-sd.rb
===================================================================
--- projects/tor-naming/trunk/tor-naming-web/show-sd.rb	                        (rev 0)
+++ projects/tor-naming/trunk/tor-naming-web/show-sd.rb	2009-09-19 10:04:53 UTC (rev 20611)
@@ -0,0 +1,23 @@
+#!/usr/bin/ruby
+
+require 'eruby'
+require 'cgi'
+require 'db'
+require 'common'
+
+$cgi = CGI.new
+
+sd_ref = $cgi.params['sd_ref'].first
+error "Evil person" unless sd_ref =~ /^[0-9]+$/
+
+require 'db-config'
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+sd = db.query_row("SELECT sd.*, to_char(posted AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') as posted, descriptor.descriptor FROM sd, descriptor WHERE sd.ref=descriptor.ref and sd.ref=?", sd_ref);
+node = db.query_row("SELECT * FROM node WHERE ref=?", sd['node_ref']);
+named = db.query_row("SELECT *, to_char(named_since AT TIME ZONE 'UTC', 'YYYY-MM-DD') as named_since FROM named WHERE fingerprint=? AND upper(name)=upper(?)", node['fingerprint'], sd['nickname']);
+action = db.query_row("SELECT * FROM action WHERE ref=?", sd['action_ref']);
+
+print $cgi.header( 'Expires' => Time.now + (1 * 60 * 60) )
+utc_timestamp = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ERuby::import('show-sd.rhtml')


Property changes on: projects/tor-naming/trunk/tor-naming-web/show-sd.rb
___________________________________________________________________
Added: svn:executable
   + *



More information about the tor-commits mailing list