tor-commits
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2012
- 16 participants
- 941 discussions

27 Apr '12
commit 19fa71d13e9e0b7c62fe1296ada7e35b8089005a
Author: David Fifield <david(a)bamsoftware.com>
Date: Fri Apr 27 00:20:05 2012 -0700
Write a space at the end of visible_sleep.
This overwrites the last digit when the number of digits decreases.
Otherwise you get output like this:
sleep 14
sleep 13
sleep 12
sleep 11
sleep 10
sleep 90
sleep 80
sleep 70
...
---
experiments/common.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/experiments/common.sh b/experiments/common.sh
index 87f7d79..258f9bd 100644
--- a/experiments/common.sh
+++ b/experiments/common.sh
@@ -15,7 +15,7 @@ visible_sleep() {
while [ "$N" -gt 0 ]; do
sleep 1
N=$((N-1))
- echo -ne "\rsleep $N"
+ echo -ne "\rsleep $N "
done
echo -ne "\n"
}
1
0

27 Apr '12
commit 0dddee5316aebf046db58858af81220bdf3fcb6a
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Fri Apr 27 08:50:31 2012 +0200
Update analysis code for #3261.
---
task-3261/.gitignore | 2 +
task-3261/AggregateStats.java | 122 +++++++++
task-3261/AnalyzeDescriptorParts.java | 315 ++++++++++++++++++++++
task-3261/AnalyzeStatsCoverage.java | 478 ---------------------------------
task-3261/ExtractDescriptorParts.java | 172 ++++++++++++
task-3261/README | 38 +++-
task-3261/plot.R | 65 +++++
task-3261/stats-coverage.R | 25 --
8 files changed, 711 insertions(+), 506 deletions(-)
diff --git a/task-3261/.gitignore b/task-3261/.gitignore
index 2bfd23b..5f2b4dc 100644
--- a/task-3261/.gitignore
+++ b/task-3261/.gitignore
@@ -2,6 +2,8 @@
*.png
*.pdf
*.csv
+bridge-network-statuses
+parse-history
in/
temp/
*.jar
diff --git a/task-3261/AggregateStats.java b/task-3261/AggregateStats.java
new file mode 100755
index 0000000..73f7279
--- /dev/null
+++ b/task-3261/AggregateStats.java
@@ -0,0 +1,122 @@
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/* Aggregate half-hourly per-bridge data to daily statistics. */
+public class AggregateStats {
+ public static void main(String[] args) throws Exception {
+
+ /* Read file containing publication times of bridge statuses and count
+ * statuses per day. */
+ SortedMap<String, Long> publishedStatuses =
+ new TreeMap<String, Long>();
+ File statusFile = new File("bridge-network-statuses");
+ if (!statusFile.exists()) {
+ System.err.println(statusFile.getAbsolutePath() + " does not "
+ + "exist. Exiting.");
+ System.exit(1);
+ } else {
+ BufferedReader br = new BufferedReader(new FileReader(statusFile));
+ String line;
+ while ((line = br.readLine()) != null) {
+ String date = line.split(" ")[0];
+ if (publishedStatuses.containsKey(date)) {
+ publishedStatuses.put(date, publishedStatuses.get(date) + 1L);
+ } else {
+ publishedStatuses.put(date, 1L);
+ }
+ }
+ }
+
+ /* Aggregate single observations in memory. */
+ SortedMap<String, Map<String, Long>> aggregatedStats =
+ new TreeMap<String, Map<String, Long>>();
+ SortedSet<String> allKeys = new TreeSet<String>();
+ File evalOutFile = new File("eval-out.csv");
+ if (!evalOutFile.exists()) {
+ System.err.println(evalOutFile.getAbsolutePath() + " does not "
+ + "exist. Exiting.");
+ System.exit(1);
+ } else {
+ BufferedReader ebr = new BufferedReader(new FileReader(evalOutFile));
+ String line;
+ while ((line = ebr.readLine()) != null) {
+ String[] parts = line.split(",");
+ String date = parts[0].split(" ")[0];
+ String key = parts[2] + "," + parts[3] + "," + parts[4];
+ allKeys.add(key);
+ Map<String, Long> stats = null;
+ if (aggregatedStats.containsKey(date)) {
+ stats = aggregatedStats.get(date);
+ } else {
+ stats = new HashMap<String, Long>();
+ aggregatedStats.put(date, stats);
+ }
+ if (stats.containsKey(key)) {
+ stats.put(key, stats.get(key) + 1L);
+ } else {
+ stats.put(key, 1L);
+ }
+ }
+ ebr.close();
+ }
+
+ /* Write aggregated statistics to aggregated.csv. */
+ File aggregatedFile = new File("aggregated.csv");
+ BufferedWriter abw = new BufferedWriter(new FileWriter(
+ aggregatedFile));
+ abw.write("date,reported,discarded,reason,bridges,statuses\n");
+ long previousDateMillis = -1L;
+ final long DAY = 24L * 60L * 60L * 1000L;
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ for (Map.Entry<String, Map<String, Long>> e :
+ aggregatedStats.entrySet()) {
+ String date = e.getKey();
+ long currentDateMillis = dateFormat.parse(date).getTime();
+ while (previousDateMillis > -1L &&
+ currentDateMillis - previousDateMillis > DAY) {
+ previousDateMillis += DAY;
+ String tempDate = dateFormat.format(previousDateMillis);
+ for (String key : allKeys) {
+ abw.write(tempDate + "," + key + ",NA,0\n");
+ }
+ }
+ previousDateMillis = currentDateMillis;
+ String nextDate = dateFormat.format(currentDateMillis + DAY);
+ String nextPlusOneDate = dateFormat.format(currentDateMillis
+ + 2 * DAY);
+ long statuses = publishedStatuses.containsKey(date) ?
+ publishedStatuses.get(date) : 0L;
+ Map<String, Long> stats = e.getValue();
+ if (!aggregatedStats.containsKey(nextDate) ||
+ !aggregatedStats.containsKey(nextPlusOneDate) ||
+ statuses < 40) {
+ for (String key : allKeys) {
+ abw.write(date + "," + key + ",NA," + statuses + "\n");
+ }
+ } else {
+ for (String key : allKeys) {
+ if (stats.containsKey(key)) {
+ abw.write(date + "," + key + "," + (stats.get(key) / statuses)
+ + "," + statuses + "\n");
+ } else {
+ abw.write(date + "," + key + ",0," + statuses + "\n");
+ }
+ }
+ }
+ }
+ abw.close();
+ }
+}
+
diff --git a/task-3261/AnalyzeDescriptorParts.java b/task-3261/AnalyzeDescriptorParts.java
new file mode 100755
index 0000000..7f4bbc4
--- /dev/null
+++ b/task-3261/AnalyzeDescriptorParts.java
@@ -0,0 +1,315 @@
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/* Analyze descriptors parts bridge by bridge and determine whether a
+ * bridge reported usage statistics at a given time, and if not, find out
+ * why not. */
+public class AnalyzeDescriptorParts {
+ public static void main(String[] args) throws Exception {
+
+ /* Define paths: we read descriptor part files from temp/ and append
+ * statistics on half hour detail to eval-out.csv. */
+ File tempDirectory = new File("temp");
+ File evalOutFile = new File("eval-out.csv");
+
+ /* Parse descriptor part files bridge by bridge. */
+ SimpleDateFormat dateTimeFormat =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ final long HALF_HOUR = 30L * 60L * 1000L;
+ BufferedWriter ebw = new BufferedWriter(new FileWriter(evalOutFile));
+ for (File tempFile : tempDirectory.listFiles()) {
+ String fingerprint = tempFile.getName();
+ BufferedReader br = new BufferedReader(new FileReader(tempFile));
+ String line;
+
+ /* For each bridge, determine when it was first seen as relay. All
+ * timestamps are in half hours since 1970-01-01 00:00:00 UTC. */
+ long firstRunningRelay = Long.MAX_VALUE;
+
+ /* For each time the bridge was listed in a bridge network status as
+ * Running, remember the status publication time and referenced
+ * descriptor digest. */
+ SortedMap<Long, String> runningBridgeHalfHours =
+ new TreeMap<Long, String>();
+
+ /* For each descriptor published by the bridge, remember seven
+ * timestamps in an array:
+ * 0: when the bridge was started due to the descriptor publication
+ * time and reported uptime,
+ * 1: when the descriptor was published,
+ * 2: when the descriptor was first referenced in a status,
+ * 3: when the descriptor was last referenced in status,
+ * 4: when the first descriptor in the same uptime session was first
+ * referenced in a status,
+ * 5: when the last descriptor in the same uptime session was last
+ * referenced in a status, and
+ * 6: when the last descriptor in the same uptime session was
+ * published. */
+ Map<String, long[]> descriptorSessions =
+ new HashMap<String, long[]>();
+
+ /* For each descriptor, remember the platform string. */
+ Map<String, String> descriptorPlatforms =
+ new HashMap<String, String>();
+
+ /* For each bridge-stats or geoip-stats line, remember a long[] with
+ * two timestamps and a boolean:
+ * 0: when the statistics interval started,
+ * 1: when the statistics interval ended,
+ * 2: whether the bridge reported its geoip file digest (only
+ * 0.2.3.x or higher). */
+ SortedMap<Long, long[]> bridgeStats = new TreeMap<Long, long[]>(),
+ geoipStats = new TreeMap<Long, long[]>();
+
+ /* Parse the file in temp/ line by line. */
+ while ((line = br.readLine()) != null) {
+
+ /* Remember when a descriptor was published and which platform
+ * string it contained. */
+ if (line.startsWith("server-descriptor ")) {
+ String[] parts = line.split(" ");
+ long publishedMillis = dateTimeFormat.parse(parts[1] + " "
+ + parts[2]).getTime();
+ long publishedHalfHour = publishedMillis / HALF_HOUR + 1L;
+ String descriptor = parts[3];
+ long startedHalfHour = (publishedMillis
+ - Long.parseLong(parts[4]) * 1000L) / HALF_HOUR + 1L;
+ long[] descriptorSession;
+ if (descriptorSessions.containsKey(descriptor)) {
+ descriptorSession = descriptorSessions.get(descriptor);
+ } else {
+ descriptorSession = new long[7];
+ descriptorSessions.put(descriptor, descriptorSession);
+ }
+ if (descriptorSession[0] == 0) {
+ descriptorSession[0] = startedHalfHour;
+ descriptorSession[1] = publishedHalfHour;
+ }
+ String platform = line.substring(line.indexOf("Tor "));
+ descriptorPlatforms.put(descriptor, platform);
+
+ /* Remember when a descriptor was first and last referenced from a
+ * bridge network status. */
+ } else if (line.startsWith("running-bridge ")) {
+ String[] parts = line.split(" ");
+ long publishedMillis = dateTimeFormat.parse(parts[1] + " "
+ + parts[2]).getTime();
+ long publishedHalfHour = publishedMillis / HALF_HOUR;
+ String descriptor = parts[3];
+ long[] descriptorSession;
+ if (descriptorSessions.containsKey(descriptor)) {
+ descriptorSession = descriptorSessions.get(descriptor);
+ if (descriptorSession[2] == 0 ||
+ publishedHalfHour < descriptorSession[2]) {
+ descriptorSession[2] = publishedHalfHour;
+ }
+ if (publishedHalfHour > descriptorSession[3]) {
+ descriptorSession[3] = publishedHalfHour;
+ }
+ } else {
+ descriptorSession = new long[7];
+ descriptorSession[2] = publishedHalfHour;
+ descriptorSession[3] = publishedHalfHour;
+ descriptorSessions.put(descriptor, descriptorSession);
+ }
+ runningBridgeHalfHours.put(publishedHalfHour, descriptor);
+
+ /* Remember the start and end of a bridge-stats or geoip-stats
+ * interval, and remember whether the extra-info descriptor
+ * contained a geoip-db-digest line. */
+ } else if (line.startsWith("bridge-stats ") ||
+ line.startsWith("geoip-stats ")) {
+ String parts[] = line.split(" ");
+ long statsEndMillis = dateTimeFormat.parse(parts[1] + " "
+ + parts[2]).getTime();
+ long statsEnd = statsEndMillis / HALF_HOUR;
+ long statsStart = (statsEndMillis - Long.parseLong(parts[3])
+ * 1000L) / HALF_HOUR;
+ boolean hasGeoipFile = !parts[4].equals("NA");
+ long[] stats = new long[3];
+ stats[0] = statsStart;
+ stats[1] = statsEnd;
+ stats[2] = hasGeoipFile ? 1L : 0L;
+ if (line.startsWith("bridge-stats ")) {
+ bridgeStats.put(statsStart, stats);
+ } else {
+ geoipStats.put(statsStart, stats);
+ }
+
+ /* Remember when this bridge was first seen as a relay in the
+ * consensus. */
+ } else if (line.startsWith("running-relay ")) {
+ long runningRelayMillis = dateTimeFormat.parse(line.substring(
+ "running-relay ".length())).getTime() / HALF_HOUR;
+ firstRunningRelay = Math.min(firstRunningRelay,
+ runningRelayMillis);
+ }
+ }
+ br.close();
+
+ /* Sort descriptors by their first reference in a bridge network
+ * status. */
+ SortedMap<Long, String> descriptorsByFirstReferenced =
+ new TreeMap<Long, String>();
+ for (Map.Entry<String, long[]> e : descriptorSessions.entrySet()) {
+ if (e.getValue()[2] == 0) {
+ continue;
+ }
+ descriptorsByFirstReferenced.put(e.getValue()[2], e.getKey());
+ }
+ if (descriptorsByFirstReferenced.isEmpty()) {
+ continue;
+ }
+
+ /* Go through list of descriptors and see if two or more of them
+ * belong to the same bridge uptime session. Two descriptors are
+ * considered as part of the same uptime session if a) they are
+ * referenced from two subsequent statuses and b) the start time in
+ * the second descriptor lies before the publication time of the
+ * first descriptor. First make a list of all descriptors of a
+ * session and then update their long[] values to contain session
+ * information. */
+ long[] previousDescriptorTimestamps = null;
+ long firstStatusInSession = Long.MAX_VALUE,
+ lastStatusInSession = -1L, lastDescriptorPublished = -1L;
+ Set<String> descriptorsInSession = new HashSet<String>();
+ for (String descriptor : descriptorsByFirstReferenced.values()) {
+ long[] currentDescriptorTimestamps =
+ descriptorSessions.get(descriptor);
+ String currentDescriptor = descriptor;
+ if (previousDescriptorTimestamps != null) {
+ boolean sameSession =
+ previousDescriptorTimestamps[3] + 1L ==
+ currentDescriptorTimestamps[2] &&
+ currentDescriptorTimestamps[0] <=
+ previousDescriptorTimestamps[1];
+ if (!sameSession) {
+ for (String descriptorInSession : descriptorsInSession) {
+ long[] descriptorTimestamps = descriptorSessions.get(
+ descriptorInSession);
+ descriptorTimestamps[4] = firstStatusInSession;
+ descriptorTimestamps[5] = lastStatusInSession;
+ descriptorTimestamps[6] = lastDescriptorPublished;
+ }
+ firstStatusInSession = Long.MAX_VALUE;
+ lastStatusInSession = lastDescriptorPublished = -1L;
+ descriptorsInSession.clear();
+ }
+ }
+ firstStatusInSession = Math.min(firstStatusInSession,
+ currentDescriptorTimestamps[2]);
+ lastStatusInSession = Math.max(lastStatusInSession,
+ currentDescriptorTimestamps[3]);
+ lastDescriptorPublished = Math.max(lastDescriptorPublished,
+ currentDescriptorTimestamps[1]);
+ descriptorsInSession.add(currentDescriptor);
+ previousDescriptorTimestamps = currentDescriptorTimestamps;
+ }
+ for (String descriptorInSession : descriptorsInSession) {
+ long[] descriptorTimestamps = descriptorSessions.get(
+ descriptorInSession);
+ descriptorTimestamps[4] = firstStatusInSession;
+ descriptorTimestamps[5] = lastStatusInSession;
+ descriptorTimestamps[6] = lastDescriptorPublished;
+ }
+
+ /* Go through all statuses listing this bridge as Running, determine
+ * if it reported usage statistics and if they were considered for
+ * aggregation, and find out possible reasons for the bridge not
+ * reporting usage statistics. */
+ for (Map.Entry<Long, String> e :
+ runningBridgeHalfHours.entrySet()) {
+ long statusPublished = e.getKey();
+ String descriptor = e.getValue();
+ String platform = descriptorPlatforms.get(descriptor);
+ boolean reported = false, discarded = false;
+ String reason = "none";
+ if (firstRunningRelay <= statusPublished) {
+ /* The bridge was running as a relay before. */
+ discarded = true;
+ reason = "runasrelay";
+ }
+ if (!geoipStats.headMap(statusPublished + 1).isEmpty()) {
+ long[] stats = geoipStats.get(geoipStats.headMap(statusPublished
+ + 1).lastKey());
+ if (stats[0] <= statusPublished && stats[1] > statusPublished) {
+ /* Status publication time falls into stats interval. */
+ reported = true;
+ if (platform != null && platform.compareTo("Tor 0.2.2") > 0) {
+ /* geoip stats published by versions 0.2.2.x or higher are
+ * buggy and therefore discarded. */
+ discarded = true;
+ reason = "geoip022";
+ }
+ }
+ }
+ if (!bridgeStats.headMap(statusPublished + 1).isEmpty()) {
+ long[] stats = bridgeStats.get(bridgeStats.headMap(
+ statusPublished + 1).lastKey());
+ if (stats[0] <= statusPublished && stats[1] > statusPublished) {
+ /* Status publication time falls into stats interval. */
+ reported = true;
+ if (platform != null && platform.compareTo("Tor 0.2.3") > 0 &&
+ stats[2] == 0) {
+ /* The bridge running version 0.2.3.x did not have a geoip
+ * file and therefore published bad bridge statistics. */
+ discarded = true;
+ reason = "nogeoipfile";
+ }
+ }
+ }
+ if (!reported) {
+ /* The bridge didn't report statistics, so it doesn't matter
+ * whether we'd have discarded them. */
+ discarded = false;
+ if (!descriptorSessions.containsKey(descriptor)) {
+ /* The descriptor referenced in the bridge network status is
+ * unavailable, which means we cannot make any statement why the
+ * bridge did not report usage statistics. */
+ reason = "noserverdesc";
+ } else {
+ long[] descriptorTimestamps = descriptorSessions.get(descriptor);
+ long sessionStart = descriptorTimestamps[4],
+ sessionEnd = descriptorTimestamps[5],
+ lastDescPubl = descriptorTimestamps[6];
+ long currentStatsEnd = sessionStart
+ + 48 * ((statusPublished - sessionStart) / 48 + 1);
+ if (sessionEnd <= currentStatsEnd) {
+ /* The current uptime session ends before the 24-hour statistics
+ * interval. */
+ reason = "lessthan24h";
+ } else if (currentStatsEnd > lastDescPubl) {
+ /* The current uptime session ended after the 24-hour statistics
+ * interval, but the bridge didn't publish a descriptor
+ * containing the statistics. */
+ reason = "publdelay";
+ } else {
+ /* There is some other reason why the bridge did not report
+ * statistics. */
+ reason = "other";
+ }
+ }
+ }
+ ebw.write(dateTimeFormat.format(statusPublished * HALF_HOUR) + ","
+ + fingerprint + "," + reported + "," + discarded + ","
+ + reason + "\n");
+ }
+ }
+ ebw.close();
+ }
+}
+
diff --git a/task-3261/AnalyzeStatsCoverage.java b/task-3261/AnalyzeStatsCoverage.java
deleted file mode 100644
index 4688bde..0000000
--- a/task-3261/AnalyzeStatsCoverage.java
+++ /dev/null
@@ -1,478 +0,0 @@
-import java.io.*;
-import java.text.*;
-import java.util.*;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.binary.Hex;
-public class AnalyzeStatsCoverage {
- public static void main(String[] args) throws Exception {
- File inDirectory = new File("in");
- File tempDirectory = new File("temp");
- File outFile = new File("stats-coverage.csv");
-
- /* Extract relevant lines from extra-info descriptors in inDirectory
- * and write them to files tempDirectory/$date/$fingerprint-$date for
- * later processing by fingerprint and date. */
- SimpleDateFormat dateTimeFormat =
- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- if (inDirectory.exists() && inDirectory.isDirectory()) {
- System.out.println("Parsing descriptors in '"
- + inDirectory.getAbsolutePath() + "'.");
- long started = System.currentTimeMillis();
- tempDirectory.mkdirs();
- Stack<File> dirs = new Stack<File>();
- SortedSet<File> files = new TreeSet<File>();
- dirs.add(inDirectory);
- while (!dirs.isEmpty()) {
- File file = dirs.pop();
- if (file.isDirectory()) {
- if (file.getName().equals("statuses")) {
- continue;
- }
- for (File f : file.listFiles()) {
- dirs.add(f);
- }
- } else {
- files.add(file);
- }
- }
- int totalFiles = files.size(), fileNumber = 0;
- for (File file : files) {
- if (++fileNumber % (totalFiles / 1000) == 0) {
- int numberLength = String.valueOf(totalFiles).length();
- long minutesLeft = (((System.currentTimeMillis() - started)
- * (totalFiles - fileNumber)) / fileNumber) / (60L * 1000L);
- System.out.printf("Parsed %" + numberLength + "d of %"
- + numberLength + "d descriptors (%3d %%) %d minutes left%n",
- fileNumber, totalFiles, (fileNumber * 100) / totalFiles,
- minutesLeft);
- }
- BufferedReader br = new BufferedReader(new FileReader(file));
- String line, fingerprint = null, publishedLine = null;
- SortedMap<String, SortedSet<String>> linesByDate =
- new TreeMap<String, SortedSet<String>>();
- while ((line = br.readLine()) != null) {
- if (line.startsWith("extra-info ")) {
- fingerprint = line.split(" ")[2];
- } else if (line.startsWith("write-history ") ||
- line.startsWith("read-history ")) {
- String[] parts = line.split(" ");
- if (parts.length < 6) {
- continue;
- }
- String historyEndDate = parts[1];
- long historyEndMillis = dateTimeFormat.parse(parts[1] + " "
- + parts[2]).getTime();
- long intervalLength = Long.parseLong(parts[3].substring(1));
- if (intervalLength != 900L) {
- System.out.println("Non-standard interval length in "
- + "line '" + line + "' in file "
- + file.getAbsolutePath() + ". Skipping this line.");
- continue;
- }
- int intervals = parts[5].split(",").length;
- long historyStartMillis = historyEndMillis
- - (intervals * intervalLength * 1000L);
- long currentMillis = historyStartMillis;
- String currentDate;
- while ((currentDate = dateFormat.format(currentMillis)).
- compareTo(historyEndDate) <= 0) {
- if (!linesByDate.containsKey(currentDate)) {
- linesByDate.put(currentDate, new TreeSet<String>());
- }
- linesByDate.get(currentDate).add(line);
- currentMillis += 24L * 60L * 60L * 1000L;
- }
- } else if (line.startsWith("dirreq-stats-end ") ||
- line.startsWith("entry-stats-end ") ||
- line.startsWith("exit-stats-end ") ||
- line.startsWith("cell-stats-end ") ||
- line.startsWith("conn-bi-direct ") ||
- line.startsWith("bridge-stats-end ")) {
- String[] parts = line.split(" ");
- if (parts.length < 5) {
- System.out.println("Malformed line '" + line + "' in "
- + "file " + file.getAbsolutePath() + ". Skipping "
- + "this line.");
- continue;
- }
- String statsEndDate = parts[1];
- long statsEndMillis = dateTimeFormat.parse(parts[1] + " "
- + parts[2]).getTime();
- long intervalLength = Long.parseLong(parts[3].substring(1));
- long statsStartMillis = statsEndMillis
- - intervalLength * 1000L;
- long currentMillis = statsStartMillis;
- String currentDate;
- while ((currentDate = dateFormat.format(currentMillis)).
- compareTo(statsEndDate) <= 0) {
- if (!linesByDate.containsKey(currentDate)) {
- linesByDate.put(currentDate, new TreeSet<String>());
- }
- linesByDate.get(currentDate).add(line);
- currentMillis += 24L * 60L * 60L * 1000L;
- }
- } else if (line.startsWith("published ")) {
- publishedLine = line;
- } else if (line.startsWith("geoip-start-time ")) {
- if (publishedLine == null) {
- System.out.println("Missing published line in file "
- + file.getAbsolutePath() + ". Skipping "
- + "geoip-start-time line.");
- continue;
- }
- String[] publishedParts = publishedLine.split(" ");
- if (publishedParts.length < 3) {
- System.out.println("Malformed line '" + publishedLine
- + "' in file " + file.getAbsolutePath() + ". "
- + "Skipping geoip-start-time line.");
- continue;
- }
- String[] parts = line.split(" ");
- if (parts.length < 3) {
- System.out.println("Malformed line '" + line + "' in "
- + "file " + file.getAbsolutePath() + ". Skipping "
- + "this line.");
- continue;
- }
- String statsEndDate = parts[1];
- long statsEndMillis = dateTimeFormat.parse(
- publishedParts[1] + " " + publishedParts[2]).getTime();
- long statsStartMillis = dateTimeFormat.parse(parts[1] + " "
- + parts[2]).getTime();
- long intervalLength = (statsEndMillis - statsStartMillis)
- / 1000L;
- String rewrittenLine = "geoip-stats-end "
- + publishedParts[1] + " " + publishedParts[2] + " ("
- + intervalLength + " s)";
- long currentMillis = statsStartMillis;
- String currentDate;
- while ((currentDate = dateFormat.format(currentMillis)).
- compareTo(statsEndDate) <= 0) {
- if (!linesByDate.containsKey(currentDate)) {
- linesByDate.put(currentDate, new TreeSet<String>());
- }
- linesByDate.get(currentDate).add(rewrittenLine);
- currentMillis += 24L * 60L * 60L * 1000L;
- }
- }
- }
- br.close();
- for (Map.Entry<String, SortedSet<String>> e :
- linesByDate.entrySet()) {
- String date = e.getKey();
- SortedSet<String> lines = e.getValue();
- File outputFile = new File(tempDirectory, date + "/"
- + fingerprint + "-" + date);
- if (outputFile.exists()) {
- br = new BufferedReader(new FileReader(outputFile));
- while ((line = br.readLine()) != null) {
- lines.add(line);
- }
- br.close();
- }
- outputFile.getParentFile().mkdirs();
- BufferedWriter bw = new BufferedWriter(new FileWriter(
- outputFile));
- for (String l : lines) {
- bw.write(l + "\n");
- }
- bw.close();
- }
- }
- }
-
- /* Parse bridge network statuses and append "running " lines to
- * files tempDirectory/$date/$fingerprint-$date for later processing
- * by fingerprint and date. */
- SimpleDateFormat statusFormat =
- new SimpleDateFormat("yyyyMMdd-HHmmss");
- statusFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- if (inDirectory.exists() && inDirectory.isDirectory()) {
- System.out.println("Parsing statuses in '"
- + inDirectory.getAbsolutePath() + "'.");
- long started = System.currentTimeMillis();
- tempDirectory.mkdirs();
- Stack<File> dirs = new Stack<File>();
- SortedSet<File> files = new TreeSet<File>();
- dirs.add(inDirectory);
- while (!dirs.isEmpty()) {
- File file = dirs.pop();
- if (file.isDirectory()) {
- if (file.getName().equals("extra-infos")) {
- continue;
- }
- for (File f : file.listFiles()) {
- dirs.add(f);
- }
- } else {
- files.add(file);
- }
- }
- int totalFiles = files.size(), fileNumber = 0;
- for (File file : files) {
- if (++fileNumber % (totalFiles / 1000) == 0) {
- int numberLength = String.valueOf(totalFiles).length();
- long minutesLeft = (((System.currentTimeMillis() - started)
- * (totalFiles - fileNumber)) / fileNumber) / (60L * 1000L);
- System.out.printf("Parsed %" + numberLength + "d of %"
- + numberLength + "d statuses (%3d %%) %d minutes left%n",
- fileNumber, totalFiles, (fileNumber * 100) / totalFiles,
- minutesLeft);
- }
- long statusPublishedMillis = statusFormat.parse(
- file.getName().substring(0, "YYYYMMdd-HHmmss".length())).
- getTime();
- SortedSet<String> statusPublishedDates = new TreeSet<String>();
- String statusPublishedString = dateTimeFormat.format(
- statusPublishedMillis);
- statusPublishedDates.add(dateFormat.format(
- statusPublishedMillis));
- statusPublishedDates.add(dateFormat.format(
- statusPublishedMillis + 15L * 60L * 1000L));
- BufferedReader br = new BufferedReader(new FileReader(file));
- String line, rLine = null;
- while ((line = br.readLine()) != null) {
- if (line.startsWith("r ")) {
- rLine = line;
- } else if (line.startsWith("s ") && line.contains(" Running") &&
- rLine != null) {
- String[] parts = rLine.split(" ");
- if (parts.length != 9) {
- System.out.println("Illegal line '" + rLine + "' in "
- + file.getAbsolutePath() + ". Skipping this line.");
- continue;
- }
- String fingerprint = Hex.encodeHexString(Base64.decodeBase64(
- parts[2] + "=="));
- for (String date : statusPublishedDates) {
- File outputFile = new File(tempDirectory, date + "/"
- + fingerprint.toUpperCase() + "-" + date);
- outputFile.getParentFile().mkdirs();
- BufferedWriter bw = new BufferedWriter(new FileWriter(
- outputFile, true));
- bw.write("running " + statusPublishedString + "\n");
- bw.close();
- }
- }
- }
- }
- }
-
- /* Parse relevant lines by fingerprint and date. The result will be
- * how many bytes that relay or bridge read/wrote in total, and how
- * many bytes were included in the different reported statistics.
- * Other results are the number of seconds for which this relay or
- * bridge reported byte histories and other statistics, either based
- * on self-reported bandwidth histories or based on the Running flag
- * in bridge network statuses. */
- if (tempDirectory.exists() && tempDirectory.isDirectory()) {
- System.out.println("Evaluating previously parsed descriptors in '"
- + tempDirectory.getAbsolutePath() + "'.");
- BufferedWriter bw = new BufferedWriter(new FileWriter(outFile));
- bw.write("fingerprint,date,totalwritten,totalread,totalseconds,"
- + "totalrunning,dirreqwritten,dirreqread,dirreqseconds,"
- + "dirreqrunning,entrywritten,entryread,entryseconds,"
- + "entryrunning,exitwritten,exitread,exitseconds,exitrunning,"
- + "cellwritten,cellread,cellseconds,cellrunning,"
- + "connbidirectwritten,connbidirectread,connbidirectseconds,"
- + "connbidirectrunning,bridgewritten,bridgeread,bridgeseconds,"
- + "bridgerunning,geoipwritten,geoipread,geoipseconds,"
- + "geoiprunning\n");
- Stack<File> dirs = new Stack<File>();
- SortedSet<File> files = new TreeSet<File>();
- dirs.add(tempDirectory);
- while (!dirs.isEmpty()) {
- File file = dirs.pop();
- if (file.isDirectory()) {
- for (File f : file.listFiles()) {
- dirs.add(f);
- }
- } else {
- files.add(file);
- }
- }
- int totalFiles = files.size(), fileNumber = 0;
- for (File file : files) {
- if (++fileNumber % (totalFiles / 1000) == 0) {
- int numberLength = String.valueOf(totalFiles).length();
- System.out.printf("Evaluated %" + numberLength + "d of %"
- + numberLength + "d descriptors/days (%3d %%)%n",
- fileNumber, totalFiles, (fileNumber * 100) / totalFiles);
- }
- String fingerprint = file.getName().substring(0, 40);
- String date = file.getName().substring(41);
- long dateStartMillis = dateFormat.parse(date).getTime();
- long dateEndMillis = dateStartMillis + 24L * 60L * 60L * 1000L;
- long[] writeHistory = new long[96], readHistory = new long[96];
- boolean[] upBridge = new boolean[96],
- upStatus = new boolean[96],
- dirreqStats = new boolean[96],
- entryStats = new boolean[96],
- exitStats = new boolean[96],
- cellStats = new boolean[96],
- connBiDirectStats = new boolean[96],
- bridgeStats = new boolean[96],
- geoipStats = new boolean[96];
- BufferedReader br = new BufferedReader(new FileReader(file));
- String line;
- while ((line = br.readLine()) != null) {
- if (line.startsWith("running ")) {
- long statusPublishedMillis = dateTimeFormat.parse(
- line.substring("running ".length())).getTime();
- int j = (int) ((statusPublishedMillis - dateStartMillis)
- / (900L * 1000L));
- for (int i = 0; i < 2; i++) {
- if (j + i >= 0 && j + i < 96) {
- upStatus[j + i] = true;
- }
- }
- } else if (line.startsWith("write-history ") ||
- line.startsWith("read-history ")) {
- long[] history = line.startsWith("write-history ")
- ? writeHistory : readHistory;
- String[] parts = line.split(" ");
- long historyEndMillis = dateTimeFormat.parse(parts[1] + " "
- + parts[2]).getTime();
- String[] historyValues = parts[5].split(",");
- long historyStartMillis = historyEndMillis
- - (historyValues.length * 900L * 1000L);
- long currentMillis = historyStartMillis;
- for (int i = 0; i < historyValues.length; i++) {
- if (currentMillis >= dateStartMillis &&
- currentMillis < dateEndMillis) {
- int j = (int) ((currentMillis - dateStartMillis)
- / (900L * 1000L));
- if (j < 0 || j >= 96) {
- System.out.println("Internal error when processing "
- + "line '" + line + "'. Index = " + j
- + ". Exiting.");
- System.exit(1);
- }
- history[j] = Long.parseLong(historyValues[i]);
- upBridge[j] = true;
- }
- currentMillis += 15L * 60L * 1000L;
- }
- } else if (line.startsWith("dirreq-stats-end ") ||
- line.startsWith("entry-stats-end ") ||
- line.startsWith("exit-stats-end ") ||
- line.startsWith("cell-stats-end ") ||
- line.startsWith("conn-bi-direct ") ||
- line.startsWith("bridge-stats-end ") ||
- line.startsWith("geoip-stats-end ")) {
- boolean[] stats = null;
- if (line.startsWith("dirreq-stats-end ")) {
- stats = dirreqStats;
- } else if (line.startsWith("entry-stats-end ")) {
- stats = entryStats;
- } else if (line.startsWith("exit-stats-end ")) {
- stats = exitStats;
- } else if (line.startsWith("cell-stats-end ")) {
- stats = cellStats;
- } else if (line.startsWith("conn-bi-direct ")) {
- stats = connBiDirectStats;
- } else if (line.startsWith("bridge-stats-end ")) {
- stats = bridgeStats;
- } else if (line.startsWith("geoip-stats-end ")) {
- stats = geoipStats;
- } else {
- System.out.println("Internal error when processing line '"
- + line + "'. Exiting.");
- System.exit(1);
- }
- String[] parts = line.split(" ");
- long statsEndMillis = dateTimeFormat.parse(parts[1] + " "
- + parts[2]).getTime();
- long intervalLength = Long.parseLong(parts[3].substring(1));
- long statsStartMillis = statsEndMillis
- - intervalLength * 1000L;
- long currentMillis = statsStartMillis;
- while (currentMillis < dateEndMillis) {
- if (currentMillis >= dateStartMillis) {
- int j = (int) ((currentMillis - dateStartMillis)
- / (900L * 1000L));
- if (j < 0 || j >= 96) {
- System.out.println("Internal error when processing "
- + "line '" + line + "'. Index = " + j
- + ". Exiting.");
- System.exit(1);
- }
- stats[j] = true;
- }
- currentMillis += 15L * 60L * 1000L;
- }
- }
- }
- br.close();
- bw.write(fingerprint + "," + date + ",");
- long totalWritten = 0L, totalRead = 0L, totalSeconds = 0L,
- totalRunning = 0L, dirreqWritten = 0L, dirreqRead = 0L,
- dirreqSeconds = 0L, dirreqRunning = 0L, entryWritten = 0L,
- entryRead = 0L, entrySeconds = 0L, entryRunning = 0L,
- exitWritten = 0L, exitRead = 0L, exitSeconds = 0L,
- exitRunning = 0L, cellWritten = 0L, cellRead = 0L,
- cellSeconds = 0L, cellRunning = 0L, connBiDirectWritten = 0L,
- connBiDirectRead = 0L, connBiDirectSeconds = 0L,
- connBiDirectRunning = 0L, bridgeWritten = 0L, bridgeRead = 0L,
- bridgeSeconds = 0L, bridgeRunning = 0L, geoipWritten = 0L,
- geoipRead = 0L, geoipSeconds = 0L, geoipRunning = 0L;
- for (int i = 0; i < 96; i++) {
- totalWritten += writeHistory[i];
- totalRead += readHistory[i];
- totalSeconds += upBridge[i] ? 900L : 0L;
- totalRunning += upStatus[i] ? 900L : 0L;
- dirreqWritten += dirreqStats[i] ? writeHistory[i] : 0L;
- dirreqRead += dirreqStats[i] ? readHistory[i] : 0L;
- dirreqSeconds += dirreqStats[i] && upBridge[i] ? 900L : 0L;
- dirreqRunning += dirreqStats[i] && upStatus[i] ? 900L : 0L;
- entryWritten += entryStats[i] ? writeHistory[i] : 0L;
- entryRead += entryStats[i] ? readHistory[i] : 0L;
- entrySeconds += entryStats[i] && upBridge[i] ? 900L : 0L;
- entryRunning += entryStats[i] && upStatus[i] ? 900L : 0L;
- exitWritten += exitStats[i] ? writeHistory[i] : 0L;
- exitRead += exitStats[i] ? readHistory[i] : 0L;
- exitSeconds += exitStats[i] && upBridge[i] ? 900L : 0L;
- exitRunning += exitStats[i] && upStatus[i] ? 900L : 0L;
- cellWritten += cellStats[i] ? writeHistory[i] : 0L;
- cellRead += cellStats[i] ? readHistory[i] : 0L;
- cellSeconds += cellStats[i] && upBridge[i] ? 900L : 0L;
- cellRunning += cellStats[i] && upStatus[i] ? 900L : 0L;
- connBiDirectWritten += connBiDirectStats[i] ? writeHistory[i]
- : 0L;
- connBiDirectRead += connBiDirectStats[i] ? readHistory[i]
- : 0L;
- connBiDirectSeconds += connBiDirectStats[i] && upBridge[i]
- ? 900L : 0L;
- connBiDirectRunning += connBiDirectStats[i] && upStatus[i]
- ? 900L : 0L;
- bridgeWritten += bridgeStats[i] ? writeHistory[i] : 0L;
- bridgeRead += bridgeStats[i] ? readHistory[i] : 0L;
- bridgeSeconds += bridgeStats[i] && upBridge[i] ? 900L : 0L;
- bridgeRunning += bridgeStats[i] && upStatus[i] ? 900L : 0L;
- geoipWritten += geoipStats[i] ? writeHistory[i] : 0L;
- geoipRead += geoipStats[i] ? readHistory[i] : 0L;
- geoipSeconds += geoipStats[i] && upBridge[i] ? 900L : 0L;
- geoipRunning += geoipStats[i] && upStatus[i] ? 900L : 0L;
- }
- bw.write(totalWritten + "," + totalRead + "," + totalSeconds + ","
- + totalRunning + "," + dirreqWritten + "," + dirreqRead + ","
- + dirreqSeconds + "," + dirreqRunning + "," + entryWritten
- + "," + entryRead + "," + entrySeconds + "," + entryRunning
- + "," + exitWritten + "," + exitRead + "," + exitSeconds + ","
- + exitRunning + "," + cellWritten + "," + cellRead + ","
- + cellSeconds + "," + cellRunning + "," + connBiDirectWritten
- + "," + connBiDirectRead + "," + connBiDirectSeconds + ","
- + connBiDirectRunning + "," + bridgeWritten + "," + bridgeRead
- + "," + bridgeSeconds + "," + bridgeRunning + ","
- + geoipWritten + "," + geoipRead + "," + geoipSeconds + ","
- + geoipRunning + "\n");
- }
- bw.close();
- }
- }
-}
-
diff --git a/task-3261/ExtractDescriptorParts.java b/task-3261/ExtractDescriptorParts.java
new file mode 100755
index 0000000..544022d
--- /dev/null
+++ b/task-3261/ExtractDescriptorParts.java
@@ -0,0 +1,172 @@
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.text.SimpleDateFormat;
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.TimeZone;
+import java.util.TreeSet;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.torproject.descriptor.BridgeNetworkStatus;
+import org.torproject.descriptor.Descriptor;
+import org.torproject.descriptor.DescriptorFile;
+import org.torproject.descriptor.DescriptorReader;
+import org.torproject.descriptor.DescriptorSourceFactory;
+import org.torproject.descriptor.ExtraInfoDescriptor;
+import org.torproject.descriptor.NetworkStatusEntry;
+import org.torproject.descriptor.RelayNetworkStatusConsensus;
+import org.torproject.descriptor.ServerDescriptor;
+
+/* Extract the relevant parts from bridge descriptors and consensuses that
+ * are required to answer what fraction of bridges are not reporting
+ * bridge usage statistics. */
+public class ExtractDescriptorParts {
+ public static void main(String[] args) throws Exception {
+
+ /* Define paths: we parse descriptor (tarballs) from in/, store the
+ * parse history to parse-history, write relevant parts per bridge to
+ * temp/, and write publication times of bridge network statuses to
+ * bridge-network-statuses. */
+ File inDirectory = new File("in");
+ File parseHistoryFile = new File("parse-history");
+ File tempDirectory = new File("temp");
+ File statusFile = new File("bridge-network-statuses");
+
+ /* Read descriptors. */
+ SimpleDateFormat dateTimeFormat =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ DescriptorReader reader =
+ DescriptorSourceFactory.createDescriptorReader();
+ reader.addDirectory(inDirectory);
+ reader.setExcludeFiles(parseHistoryFile);
+ Iterator<DescriptorFile> descriptorFiles = reader.readDescriptors();
+ while (descriptorFiles.hasNext()) {
+ DescriptorFile descriptorFile = descriptorFiles.next();
+ if (descriptorFile.getDescriptors() != null) {
+ for (Descriptor descriptor : descriptorFile.getDescriptors()) {
+
+ /* Extract bridge-stats and geoip-stats from bridge extra-info
+ * descriptors. */
+ if (descriptor instanceof ExtraInfoDescriptor) {
+ System.out.print("e");
+ SortedSet<String> lines = new TreeSet<String>();
+ ExtraInfoDescriptor extraInfoDescriptor =
+ (ExtraInfoDescriptor) descriptor;
+ if (extraInfoDescriptor.getBridgeStatsEndMillis() > 0) {
+ lines.add("bridge-stats " + dateTimeFormat.format(
+ extraInfoDescriptor.getBridgeStatsEndMillis()) + " "
+ + extraInfoDescriptor.getBridgeStatsIntervalLength()
+ + " " + (extraInfoDescriptor.getGeoipDbDigest() == null
+ ? "NA" : extraInfoDescriptor.getGeoipDbDigest()));
+ }
+ if (extraInfoDescriptor.getGeoipStartTimeMillis() > 0) {
+ long intervalLength =
+ (extraInfoDescriptor.getPublishedMillis()
+ - extraInfoDescriptor.getGeoipStartTimeMillis())
+ / 1000L;
+ String geoipStatsEnd = dateTimeFormat.format(
+ extraInfoDescriptor.getPublishedMillis());
+ lines.add("geoip-stats " + geoipStatsEnd + " "
+ + intervalLength + " "
+ + (extraInfoDescriptor.getGeoipDbDigest() == null
+ ? "NA" : extraInfoDescriptor.getGeoipDbDigest()));
+ }
+ if (!lines.isEmpty()) {
+ File outputFile = new File(tempDirectory,
+ extraInfoDescriptor.getFingerprint().toUpperCase());
+ outputFile.getParentFile().mkdirs();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(
+ outputFile, true));
+ for (String l : lines) {
+ bw.write(l + "\n");
+ }
+ bw.close();
+ }
+
+ /* Extract all bridges with the Running flag from bridge network
+ * statuses. Also extract the status publication time. */
+ } else if (descriptor instanceof BridgeNetworkStatus) {
+ System.out.print("n");
+ BridgeNetworkStatus status = (BridgeNetworkStatus) descriptor;
+ String published = dateTimeFormat.format(
+ status.getPublishedMillis());
+ if (status.getStatusEntries() != null) {
+ for (NetworkStatusEntry entry :
+ status.getStatusEntries().values()) {
+ if (entry.getFlags().contains("Running")) {
+ File outputFile = new File(tempDirectory,
+ entry.getFingerprint().toUpperCase());
+ outputFile.getParentFile().mkdirs();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(
+ outputFile, true));
+ String digest = entry.getDescriptor().toUpperCase();
+ bw.write("running-bridge " + published + " " + digest
+ + "\n");
+ bw.close();
+ }
+ }
+ BufferedWriter bw = new BufferedWriter(new FileWriter(
+ statusFile, true));
+ bw.write(published + "\n");
+ bw.close();
+ }
+
+ /* Extract publication time, digest, uptime, and platform string
+ * from bridge server descriptors. */
+ } else if (descriptor instanceof ServerDescriptor) {
+ System.out.print("s");
+ ServerDescriptor serverDescriptor =
+ (ServerDescriptor) descriptor;
+ String published = dateTimeFormat.format(
+ serverDescriptor.getPublishedMillis());
+ String digest = descriptorFile.getFileName().substring(
+ descriptorFile.getFileName().lastIndexOf("/") + 1).
+ toUpperCase();
+ String uptime = serverDescriptor.getUptime() == null ? "-1"
+ : String.valueOf(serverDescriptor.getUptime());
+ String platform = serverDescriptor.getPlatform() == null
+ ? "NA" : serverDescriptor.getPlatform();
+ File outputFile = new File(tempDirectory,
+ serverDescriptor.getFingerprint().toUpperCase());
+ outputFile.getParentFile().mkdirs();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(
+ outputFile, true));
+ bw.write("server-descriptor " + published + " "
+ + digest + " " + uptime + " " + platform + "\n");
+ bw.close();
+
+ /* Extract hashed fingerprints of all relays with the Running
+ * flag from relay network status consensuses. */
+ } else if (descriptor instanceof RelayNetworkStatusConsensus) {
+ System.out.print("r");
+ RelayNetworkStatusConsensus status =
+ (RelayNetworkStatusConsensus) descriptor;
+ if (status.getStatusEntries() != null) {
+ for (NetworkStatusEntry entry :
+ status.getStatusEntries().values()) {
+ if (entry.getFlags().contains("Running")) {
+ String hashedFingerprint = Hex.encodeHexString(
+ DigestUtils.sha(Hex.decodeHex(
+ entry.getFingerprint().toCharArray()))).
+ toUpperCase();
+ File outputFile = new File(tempDirectory,
+ hashedFingerprint);
+ outputFile.getParentFile().mkdirs();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(
+ outputFile, true));
+ bw.write("running-relay " + dateTimeFormat.format(
+ status.getValidAfterMillis()) + "\n");
+ bw.close();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/task-3261/README b/task-3261/README
old mode 100644
new mode 100755
index cb430ac..43ef208
--- a/task-3261/README
+++ b/task-3261/README
@@ -1,4 +1,36 @@
-$ javac -cp commons-codec-1.4.jar AnalyzeStatsCoverage.java
-$ java -cp commons-codec-1.4.jar.: -Xmx4g AnalyzeStatsCoverage
-$ R --slave -f stats-coverage.R
+What fraction of our bridges are not reporting usage statistics?
+================================================================
+
+Usage:
+
+1. Put metrics tarballs into a directory called in/. The best parsing
+ performance can be achieved by decompressing tarballs without
+ extracting them. The bridge-descriptors-* and consensuses-* tarballs
+ are required for this analysis.
+
+2. Clone metrics-lib.git, build descriptor.jar, and put it in this
+ directory.
+
+3. Download Apache Commons Codec and Compress and put the .jar files in
+ this directory.
+
+4. Parse descriptors and write all relevant parts to one file per bridge:
+ $ javac
+ -cp commons-codec-1.4.jar:commons-compress-1.3.jar:descriptor.jar
+ ExtractDescriptorParts.java
+ $ java
+ -cp commons-codec-1.4.jar:commons-compress-1.3.jar:descriptor.jar:.
+ ExtractDescriptorParts
+
+5. Analyze descriptors parts bridge by bridge and determine whether it
+ reported bridge stats at a given time, and if not, find out why not:
+ $ javac AnalyzeDescriptorParts.java
+ $ java AnalyzeDescriptorParts
+
+6. Aggregate daily statistics that can be plotted:
+ $ javac AggregateStats.java
+ $ java AggregateStats
+
+7. Plot results:
+ $ R --slave -f plot.R
diff --git a/task-3261/plot.R b/task-3261/plot.R
new file mode 100644
index 0000000..8a3808c
--- /dev/null
+++ b/task-3261/plot.R
@@ -0,0 +1,65 @@
+library(ggplot2)
+library(scales)
+library(reshape)
+a <- read.csv("aggregated.csv", stringsAsFactors = FALSE)
+
+e <- a
+e <- data.frame(date = as.Date(e$date), case = ifelse(
+ e$reported == "true", ifelse(e$discarded == "false", "case1", "case2"),
+ "case3"), bridges = e$bridges)
+e <- aggregate(list(bridges = e$bridges),
+ by = list(date = e$date, case = e$case), FUN = sum)
+e <- cast(e, date ~ case)
+sums <- e$case1 + e$case2 + e$case3
+e <- data.frame(date = e$date, case1 = e$case1 / sums,
+ case2 = e$case2 / sums, case3 = e$case3 / sums, stringsAsFactors = FALSE)
+e <- melt(e, "date")
+e <- data.frame(date = e$date, variable = ifelse(e$variable == "case1",
+ "reported and used", ifelse(e$variable == "case2",
+ "reported and discarded", "not reported")), value = e$value)
+ggplot(e, aes(x = as.Date(date), y = value)) +
+geom_line() +
+facet_grid(variable ~ .) +
+scale_x_date(name = "") +
+scale_y_continuous(name = "", labels = percent) +
+opts(title = "Fraction of bridge usage statistics that were...\n")
+ggsave("reported-bridge-statistics.png", width = 8, height = 6, dpi = 120)
+
+d <- a
+d <- d[d$reported == "false", ]
+d <- data.frame(date = d$date, reason = d$reason, value = d$bridges)
+d <- cast(d, date ~ reason)
+d <- data.frame(date = d$date, case1 = d$lessthan24h / sums,
+ case2 = d$publdelay / sums, case3 = d$other / sums)
+d <- melt(d, "date")
+d <- data.frame(date = d$date, variable = ifelse(d$variable == "case1",
+ "Less than 24h uptime", ifelse(d$variable == "case2",
+ "Publication delay", "Other reason")), value = d$value)
+ggplot(d, aes(x = as.Date(date), y = value)) +
+geom_line() +
+facet_grid(variable ~ .) +
+scale_x_date(name = "") +
+scale_y_continuous(name = "", labels = percent) +
+opts(title = "Reasons for bridges not reporting usage statistics\n")
+ggsave("bridge-statistics-nonreported.png", width = 8, height = 6,
+ dpi = 120)
+
+b <- a
+b <- b[b$discarded == "true", ]
+b <- data.frame(date = b$date, reason = b$reason, value = b$bridges)
+b <- cast(b, date ~ reason)
+b <- data.frame(date = b$date, case1 = b$geoip022 / sums,
+ case2 = b$nogeoipfile / sums, case3 = b$runasrelay / sums)
+b <- melt(b, "date")
+b <- data.frame(date = b$date, variable = ifelse(b$variable == "case1",
+ "0.2.2.x geoip-stats bug", ifelse(b$variable == "case2",
+ "missing geoip file", "Run as non-bridge relay")), value = b$value)
+ggplot(b, aes(x = as.Date(date), y = value)) +
+geom_line() +
+facet_grid(variable ~ .) +
+scale_x_date(name = "") +
+scale_y_continuous(name = "", labels = percent) +
+opts(title = "Reasons for discarding reported usage statistics\n")
+ggsave("bridge-statistics-discarded.png", width = 8, height = 6,
+ dpi = 120)
+
diff --git a/task-3261/stats-coverage.R b/task-3261/stats-coverage.R
deleted file mode 100644
index aef63f2..0000000
--- a/task-3261/stats-coverage.R
+++ /dev/null
@@ -1,25 +0,0 @@
-library(ggplot2)
-library(scales)
-b <- read.csv("stats-coverage.csv")
-b <- aggregate(list(
- totalwritten = b$totalwritten, totalseconds = b$totalseconds,
- totalrunning = b$totalrunning, bridgewritten = b$bridgewritten,
- bridgeseconds = b$bridgeseconds, bridgerunning = b$bridgerunning,
- geoipwritten = b$geoipwritten, geoipseconds = b$geoipseconds,
- geoiprunning = b$geoiprunning), by = list(date = as.Date(b$date)), sum)
-b <- rbind(data.frame(date = b$date, variable = "by written bytes",
- value = (b$bridgewritten + b$geoipwritten) / b$totalwritten),
- data.frame(date = b$date, variable = "by uptime (bandwidth history)",
- value = (b$bridgeseconds + b$geoipseconds) / b$totalseconds),
- data.frame(date = b$date, variable = "by uptime (Running flag)",
- value = (b$bridgerunning + b$geoiprunning) / b$totalrunning))
-b <- b[b$date >= as.Date("2010-10-01") & b$date < as.Date("2012-04-01"), ]
-ggplot(b, aes(x = date, y = value)) +
-geom_line() +
-facet_grid(variable ~ .) +
-scale_x_date(name = "") +
-scale_y_continuous(name = "", limits = c(0, 1), labels = percent) +
-scale_colour_hue(name = "") +
-opts(title = "Fraction of bridges reporting statistics\n")
-ggsave("stats-coverage-bridges.png", width = 8, height = 7, dpi = 72)
-
1
0

[metrics-lib/master] Remove two suggested data sources from the TODO list.
by karsten@torproject.org 27 Apr '12
by karsten@torproject.org 27 Apr '12
27 Apr '12
commit 6eb12377add8d24e9500bb49d9b9e19c3c382e03
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Fri Apr 27 08:07:25 2012 +0200
Remove two suggested data sources from the TODO list.
Using Tor's control port as a data source could be useful in some cases,
but Damian and I decided it's not worth the effort. We wouldn't learn
much new stuff compared to running a Tor client/relay and reading the
cached-* files. Damian says that a good workaround for file permission
issues with cached-* files is to run the Tor process and Java process as
the same user.
Having a database as a data source was a nice idea, too, but we don't have
such a database. Once we have a good database we can still write a
metrics-lib wrapper for it.
---
TODO | 14 --------------
1 files changed, 0 insertions(+), 14 deletions(-)
diff --git a/TODO b/TODO
deleted file mode 100644
index f468893..0000000
--- a/TODO
+++ /dev/null
@@ -1,14 +0,0 @@
-- New data sources
- - Add Tor's control port as another data source for relay descriptors.
- In theory, the descriptors that can be parsed from a local Tor data
- directory should be similar to what we can learn via Tor's control
- port, though maybe not as up-to-date. In order to fit the data store
- model, we should query the list of all available descriptors and make
- them available to the application.
- - Add a Tor descriptor database as another data source for relay and
- maybe bridge descriptors. There is no good database schema around for
- descriptors, so that should come first. In order to fit the data
- store model, the descriptor source should allow the program to define
- which descriptors to include, and it may be useful to exclude
- descriptors by publication date.
-
1
0
commit 1f7e23a01d08e6534ba04b1d81101fc4a70fe49f
Author: Damian Johnson <atagar(a)torproject.org>
Date: Thu Apr 26 19:18:18 2012 -0700
Lowering unrecognized auth type to INFO
Now that we have SafeCookie this is gonna be a common warning until we add
handling for it. This isn't a notice that should be user facing - it indicates
something useful to me, but not users.
---
src/util/torTools.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/util/torTools.py b/src/util/torTools.py
index 7676a97..5b70c6a 100644
--- a/src/util/torTools.py
+++ b/src/util/torTools.py
@@ -430,7 +430,7 @@ class FixedConnection(TorCtl.Connection):
# not of a recognized authentication type (new addition to the
# control-spec?)
- log.log(log.WARN, "Unrecognized authentication type: %s" % authEntry)
+ log.log(log.INFO, "Unrecognized authentication type: %s" % authEntry)
elif entry.startswith("COOKIEFILE=\"") and entry.endswith("\""):
# Quoted path of the authentication cookie. This only exists if we're
# using cookie auth and, of course, doesn't account for chroot.
1
0

[arm/master] Circuits wouldn't be updated when connection resolution failed
by atagar@torproject.org 27 Apr '12
by atagar@torproject.org 27 Apr '12
27 Apr '12
commit 5e2bc2229eafc81cc26c46529ed812add14a66f2
Author: Damian Johnson <atagar(a)torproject.org>
Date: Thu Apr 26 19:31:24 2012 -0700
Circuits wouldn't be updated when connection resolution failed
The connecion panel provides information from two sources: connections from
system utilities and circuits from tor. We had a check that prevented the
connection panel from being updated when the former didn't have any new
information, which in turn broke the panel entirely when connection resolvers
either failed or were disabled.
The 'is new connecion results available' check was actually pretty pointless.
The update method gets called every five seconds and the connection resolvers
operate at a similar rate (maybe every ten seconds? it depends on resolver
performance) so it didn't actually buy us much.
Removed the check.
---
src/cli/connections/connPanel.py | 193 +++++++++++++++++++-------------------
1 files changed, 96 insertions(+), 97 deletions(-)
diff --git a/src/cli/connections/connPanel.py b/src/cli/connections/connPanel.py
index d108252..cf7823a 100644
--- a/src/cli/connections/connPanel.py
+++ b/src/cli/connections/connPanel.py
@@ -419,105 +419,104 @@ class ConnectionPanel(panel.Panel, threading.Thread):
connResolver = connections.getResolver("tor")
currentResolutionCount = connResolver.getResolutionCount()
- if self._lastResourceFetch != currentResolutionCount:
- self.valsLock.acquire()
-
- newEntries = [] # the new results we'll display
-
- # Fetches new connections and client circuits...
- # newConnections [(local ip, local port, foreign ip, foreign port)...]
- # newCircuits {circuitID => (status, purpose, path)...}
-
- newConnections = connResolver.getConnections()
- newCircuits = {}
-
- for circuitID, status, purpose, path in torTools.getConn().getCircuits():
- # Skips established single-hop circuits (these are for directory
- # fetches, not client circuits)
- if not (status == "BUILT" and len(path) == 1):
- newCircuits[circuitID] = (status, purpose, path)
-
- # Populates newEntries with any of our old entries that still exist.
- # This is both for performance and to keep from resetting the uptime
- # attributes. Note that CircEntries are a ConnectionEntry subclass so
- # we need to check for them first.
-
- for oldEntry in self._entries:
- if isinstance(oldEntry, circEntry.CircEntry):
- newEntry = newCircuits.get(oldEntry.circuitID)
-
- if newEntry:
- oldEntry.update(newEntry[0], newEntry[2])
- newEntries.append(oldEntry)
- del newCircuits[oldEntry.circuitID]
- elif isinstance(oldEntry, connEntry.ConnectionEntry):
- connLine = oldEntry.getLines()[0]
- connAttr = (connLine.local.getIpAddr(), connLine.local.getPort(),
- connLine.foreign.getIpAddr(), connLine.foreign.getPort())
-
- if connAttr in newConnections:
- newEntries.append(oldEntry)
- newConnections.remove(connAttr)
-
- # Reset any display attributes for the entries we're keeping
- for entry in newEntries: entry.resetDisplay()
-
- # Adds any new connection and circuit entries.
- for lIp, lPort, fIp, fPort in newConnections:
- newConnEntry = connEntry.ConnectionEntry(lIp, lPort, fIp, fPort)
- newConnLine = newConnEntry.getLines()[0]
+ self.valsLock.acquire()
+
+ newEntries = [] # the new results we'll display
+
+ # Fetches new connections and client circuits...
+ # newConnections [(local ip, local port, foreign ip, foreign port)...]
+ # newCircuits {circuitID => (status, purpose, path)...}
+
+ newConnections = connResolver.getConnections()
+ newCircuits = {}
+
+ for circuitID, status, purpose, path in torTools.getConn().getCircuits():
+ # Skips established single-hop circuits (these are for directory
+ # fetches, not client circuits)
+ if not (status == "BUILT" and len(path) == 1):
+ newCircuits[circuitID] = (status, purpose, path)
+
+ # Populates newEntries with any of our old entries that still exist.
+ # This is both for performance and to keep from resetting the uptime
+ # attributes. Note that CircEntries are a ConnectionEntry subclass so
+ # we need to check for them first.
+
+ for oldEntry in self._entries:
+ if isinstance(oldEntry, circEntry.CircEntry):
+ newEntry = newCircuits.get(oldEntry.circuitID)
- if newConnLine.getType() != connEntry.Category.CIRCUIT:
- newEntries.append(newConnEntry)
-
- # updates exit port and client locale usage information
- if newConnLine.isPrivate():
- if newConnLine.getType() == connEntry.Category.INBOUND:
- # client connection, update locale information
- clientLocale = newConnLine.foreign.getLocale()
-
- if clientLocale:
- self._clientLocaleUsage[clientLocale] = self._clientLocaleUsage.get(clientLocale, 0) + 1
- elif newConnLine.getType() == connEntry.Category.EXIT:
- exitPort = newConnLine.foreign.getPort()
- self._exitPortUsage[exitPort] = self._exitPortUsage.get(exitPort, 0) + 1
-
- for circuitID in newCircuits:
- status, purpose, path = newCircuits[circuitID]
- newEntries.append(circEntry.CircEntry(circuitID, status, purpose, path))
-
- # Counts the relays in each of the categories. This also flushes the
- # type cache for all of the connections (in case its changed since last
- # fetched).
-
- categoryTypes = connEntry.Category.values()
- typeCounts = dict((type, 0) for type in categoryTypes)
- for entry in newEntries:
- if isinstance(entry, connEntry.ConnectionEntry):
- typeCounts[entry.getLines()[0].getType()] += 1
- elif isinstance(entry, circEntry.CircEntry):
- typeCounts[connEntry.Category.CIRCUIT] += 1
-
- # makes labels for all the categories with connections (ie,
- # "21 outbound", "1 control", etc)
- countLabels = []
-
- for category in categoryTypes:
- if typeCounts[category] > 0:
- countLabels.append("%i %s" % (typeCounts[category], category.lower()))
-
- if countLabels: self._title = "Connections (%s):" % ", ".join(countLabels)
- else: self._title = "Connections:"
-
- self._entries = newEntries
-
- self._entryLines = []
- for entry in self._entries:
- self._entryLines += entry.getLines()
+ if newEntry:
+ oldEntry.update(newEntry[0], newEntry[2])
+ newEntries.append(oldEntry)
+ del newCircuits[oldEntry.circuitID]
+ elif isinstance(oldEntry, connEntry.ConnectionEntry):
+ connLine = oldEntry.getLines()[0]
+ connAttr = (connLine.local.getIpAddr(), connLine.local.getPort(),
+ connLine.foreign.getIpAddr(), connLine.foreign.getPort())
+
+ if connAttr in newConnections:
+ newEntries.append(oldEntry)
+ newConnections.remove(connAttr)
+
+ # Reset any display attributes for the entries we're keeping
+ for entry in newEntries: entry.resetDisplay()
+
+ # Adds any new connection and circuit entries.
+ for lIp, lPort, fIp, fPort in newConnections:
+ newConnEntry = connEntry.ConnectionEntry(lIp, lPort, fIp, fPort)
+ newConnLine = newConnEntry.getLines()[0]
- self.setSortOrder()
- self._lastResourceFetch = currentResolutionCount
- self.valsLock.release()
+ if newConnLine.getType() != connEntry.Category.CIRCUIT:
+ newEntries.append(newConnEntry)
+
+ # updates exit port and client locale usage information
+ if newConnLine.isPrivate():
+ if newConnLine.getType() == connEntry.Category.INBOUND:
+ # client connection, update locale information
+ clientLocale = newConnLine.foreign.getLocale()
+
+ if clientLocale:
+ self._clientLocaleUsage[clientLocale] = self._clientLocaleUsage.get(clientLocale, 0) + 1
+ elif newConnLine.getType() == connEntry.Category.EXIT:
+ exitPort = newConnLine.foreign.getPort()
+ self._exitPortUsage[exitPort] = self._exitPortUsage.get(exitPort, 0) + 1
+
+ for circuitID in newCircuits:
+ status, purpose, path = newCircuits[circuitID]
+ newEntries.append(circEntry.CircEntry(circuitID, status, purpose, path))
+
+ # Counts the relays in each of the categories. This also flushes the
+ # type cache for all of the connections (in case its changed since last
+ # fetched).
+
+ categoryTypes = connEntry.Category.values()
+ typeCounts = dict((type, 0) for type in categoryTypes)
+ for entry in newEntries:
+ if isinstance(entry, connEntry.ConnectionEntry):
+ typeCounts[entry.getLines()[0].getType()] += 1
+ elif isinstance(entry, circEntry.CircEntry):
+ typeCounts[connEntry.Category.CIRCUIT] += 1
+
+ # makes labels for all the categories with connections (ie,
+ # "21 outbound", "1 control", etc)
+ countLabels = []
+
+ for category in categoryTypes:
+ if typeCounts[category] > 0:
+ countLabels.append("%i %s" % (typeCounts[category], category.lower()))
+
+ if countLabels: self._title = "Connections (%s):" % ", ".join(countLabels)
+ else: self._title = "Connections:"
+
+ self._entries = newEntries
+
+ self._entryLines = []
+ for entry in self._entries:
+ self._entryLines += entry.getLines()
+
+ self.setSortOrder()
+ self._lastResourceFetch = currentResolutionCount
+ self.valsLock.release()
def _resolveApps(self, flagQuery = True):
"""
1
0

27 Apr '12
commit 62515adee0b40a062b33355ba7a385fb6c260fc9
Author: David Fifield <david(a)bamsoftware.com>
Date: Thu Apr 26 19:31:52 2012 -0700
Document IDLE_READ_TIMEOUT adjustment.
---
experiments/README | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/experiments/README b/experiments/README
index 0599fcd..57f8af7 100644
--- a/experiments/README
+++ b/experiments/README
@@ -16,6 +16,10 @@ http://acme.com/software/thttpd/. websockify is from
https://github.com/kanaka/websockify/. The old Firefox is from
http://download.mozilla.org/?product=firefox-8.0.1&os=linux&lang=en-US.
+Before compiling thttpd, increade IDLE_READ_TIMEOUT in config.h to a
+high value (several thousand). This is because some tests wait a long
+time between making a connection and sending an HTTP request.
+
Firefox versions 9 and 10 will not work; these versions have a change to
the -no-remote option that prevents the tests from running. This is
supposed to be fixed with a -new-instance option in version 12.
1
0

[arm/master] Better validation for path component of circuit-staus output
by atagar@torproject.org 27 Apr '12
by atagar@torproject.org 27 Apr '12
27 Apr '12
commit 67b8532f1135b80756339b41e77a06ac33d81aec
Author: Damian Johnson <atagar(a)torproject.org>
Date: Thu Apr 26 19:10:38 2012 -0700
Better validation for path component of circuit-staus output
The 'GETINFO circuit-status' output has an *optional* third arguement that is a
path. This is a pita because it's essentially an optional positional arguement
that can have '=', so we need to differentiate it from the key=value entities
that follow.
This resulted in confusing 'Unable to determine fingerprint' warnings, and
seemed to cause a screwed up circuit listing. Ticket tracking this is...
https://trac.torproject.org/projects/tor/ticket/5267
---
src/util/torTools.py | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/util/torTools.py b/src/util/torTools.py
index d132e28..7676a97 100644
--- a/src/util/torTools.py
+++ b/src/util/torTools.py
@@ -2422,10 +2422,17 @@ class Controller(TorCtl.PostEventListener):
for line in circStatusResults.split("\n"):
# appends a tuple with the (status, purpose, path)
lineComp = line.split(" ")
+ if len(lineComp) < 3: continue
- # skips blank lines and circuits without a path, for instance:
- # 5 LAUNCHED PURPOSE=TESTING
- if len(lineComp) < 4: continue
+ # The third parameter is *optionally* the path. This is a pita to
+ # parse out because we need to identify it verses the key=value
+ # entries that might follow. To do this checking if...
+ # - it lacks a '=' then it can't be a key=value entry
+ # - if it has a '=' but starts with a '$' then this should be a
+ # $fingerprint=nickname entity
+
+ if lineComp[2].count("=") == 1 and lineComp[2][0] != "$":
+ continue
path = []
for hopEntry in lineComp[2].split(","):
1
0

27 Apr '12
commit 10962515848e77192eaa7409363e2596e11a52b9
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Thu Apr 26 12:07:47 2012 -0700
Fix mac build issue w/ dnd patch.
---
...ven-Michaud-s-Mac-crashfix-patch-for-FF12.patch | 19 ++++++++++++-------
1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch b/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch
index 16de3d9..5a08ed4 100644
--- a/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch
+++ b/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch
@@ -1,14 +1,15 @@
-From d56b1a845aa9a9528eb1f9db8ce8a67d85683b28 Mon Sep 17 00:00:00 2001
+From 262403fb627ca452bfbcaf06fd6ad965f156ed18 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu, 26 Apr 2012 10:54:24 -0700
Subject: [PATCH 16/16] Adapt Steven Michaud's Mac crashfix patch for FF12.
Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
-Some minor tweaks were needed to get it to apply to FF12.
+Some minor tweaks were needed to get it to apply to FF12 and to compile on
+MacOS.
---
widget/Makefile.in | 1 +
- widget/cocoa/nsChildView.mm | 31 +++++++++++--------
+ widget/cocoa/nsChildView.mm | 35 +++++++++++++--------
widget/gtk2/nsDragService.cpp | 2 +-
widget/gtk2/nsWindow.cpp | 2 +-
widget/nsIDragService.idl | 4 +--
@@ -22,7 +23,7 @@ Some minor tweaks were needed to get it to apply to FF12.
widget/windows/nsPIDragServiceWindows.idl | 46 +++++++++++++++++++++++++++
widget/xpwidgets/nsBaseDragService.cpp | 16 +++++++++-
widget/xpwidgets/nsBaseDragService.h | 9 ++---
- 15 files changed, 176 insertions(+), 49 deletions(-)
+ 15 files changed, 180 insertions(+), 49 deletions(-)
create mode 100644 widget/nsPIDragService.idl
create mode 100644 widget/windows/nsPIDragServiceWindows.idl
@@ -39,7 +40,7 @@ index 4a3405b..4c105a4 100644
nsIFormatConverter.idl \
nsIClipboard.idl \
diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
-index 7f738a1..189b9ef 100644
+index 7f738a1..0149ab1 100644
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -4566,11 +4566,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
@@ -75,7 +76,7 @@ index 7f738a1..189b9ef 100644
// XXX: dropEffect should be updated per |operation|.
// As things stand though, |operation| isn't well handled within "our"
-@@ -4606,13 +4609,15 @@ NSEvent* gLastDragMouseDownEvent = nil;
+@@ -4606,13 +4609,19 @@ NSEvent* gLastDragMouseDownEvent = nil;
// value for NSDragOperationGeneric that is passed by other applications.
// All that said, NSDragOperationNone is still reliable.
if (operation == NSDragOperationNone) {
@@ -92,7 +93,11 @@ index 7f738a1..189b9ef 100644
+ nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
+ dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
+ if (dataTransfer) {
-+ dataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
++ do_QueryInterface(dataTransfer);
++ if (dataTransferNS) {
++ dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ }
+ }
+ }
}
1
0

[torbrowser/maint-2.3] Add in Steven Michaud's Mac crash fix patch.
by erinn@torproject.org 27 Apr '12
by erinn@torproject.org 27 Apr '12
27 Apr '12
commit 14b892d5ef89eabf4d94c15da0a1d10677ebccc6
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Thu Apr 26 11:03:48 2012 -0700
Add in Steven Michaud's Mac crash fix patch.
Also remove a patch that it includes.
---
.../0015-Add-DDG-and-StartPage-to-Omnibox.patch | 84 +++
.../0015-Undo-some-Mozilla-braindamage.patch | 28 -
...ven-Michaud-s-Mac-crashfix-patch-for-FF12.patch | 539 ++++++++++++++++++++
.../0016-Add-DDG-and-StartPage-to-Omnibox.patch | 84 ---
4 files changed, 623 insertions(+), 112 deletions(-)
diff --git a/src/current-patches/firefox/0015-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/0015-Add-DDG-and-StartPage-to-Omnibox.patch
new file mode 100644
index 0000000..e0740ae
--- /dev/null
+++ b/src/current-patches/firefox/0015-Add-DDG-and-StartPage-to-Omnibox.patch
@@ -0,0 +1,84 @@
+From db055738d6431057670e8f219616170ed3644a9e Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 25 Apr 2012 15:03:46 -0700
+Subject: [PATCH 15/16] Add DDG and StartPage to Omnibox.
+
+You mean there are search engines that don't require captchas if you don't
+have a cookie? Holy crap. Get those in there now.
+---
+ browser/locales/en-US/searchplugins/duckduckgo.xml | 29 ++++++++++++++++++++
+ browser/locales/en-US/searchplugins/list.txt | 2 +
+ browser/locales/en-US/searchplugins/startpage.xml | 11 +++++++
+ 3 files changed, 42 insertions(+), 0 deletions(-)
+ create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml
+ create mode 100644 browser/locales/en-US/searchplugins/startpage.xml
+
+diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml
+new file mode 100644
+index 0000000..4f00b4d
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/duckduckgo.xml
+@@ -0,0 +1,29 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>DuckDuckGo</ShortName>
++<Description>Duck Duck Go</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n
++IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB
++Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n/////
++/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v//
++//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h
++XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg
++7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs
++5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/
++JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1
++/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/
++fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y
++1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs
++AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA
++AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA
++AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD
++AADwDwAA+B8AAA==</Image>
++<Url type="text/html" method="POST" template="https://duckduckgo.com/html/">
++ <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://duckduckgo.com/html/</SearchForm>
++</SearchPlugin>
+diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt
+index 2a1141a..0466f4e 100644
+--- a/browser/locales/en-US/searchplugins/list.txt
++++ b/browser/locales/en-US/searchplugins/list.txt
+@@ -1,7 +1,9 @@
+ amazondotcom
+ bing
++duckduckgo
+ eBay
+ google
++startpage
+ twitter
+ wikipedia
+ yahoo
+diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml
+new file mode 100644
+index 0000000..1a310b1
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/startpage.xml
+@@ -0,0 +1,11 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>Startpage</ShortName>
++<Description>Start Page</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH+
+LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
++
++<Url type="text/html" method="POST" template="https://startpage.com/do/search">
++ <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://startpage.com/do/search/</SearchForm>
++</SearchPlugin>
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0015-Undo-some-Mozilla-braindamage.patch b/src/current-patches/firefox/0015-Undo-some-Mozilla-braindamage.patch
deleted file mode 100644
index 88e204f..0000000
--- a/src/current-patches/firefox/0015-Undo-some-Mozilla-braindamage.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 74be7d742204d48fbb51a90275781378948ba749 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 25 Apr 2012 13:42:52 -0700
-Subject: [PATCH 15/16] Undo some Mozilla braindamage.
-
-https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c33
-
-Seriously guys?
----
- widget/nsIDragService.idl | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
-index e42c578..6863a88 100644
---- a/widget/nsIDragService.idl
-+++ b/widget/nsIDragService.idl
-@@ -48,7 +48,7 @@ interface nsIDOMDragEvent;
- interface nsIDOMDataTransfer;
- interface nsISelection;
-
--[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass]
-+[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
- interface nsIDragService : nsISupports
- {
- const long DRAGDROP_ACTION_NONE = 0;
---
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch b/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch
new file mode 100644
index 0000000..16de3d9
--- /dev/null
+++ b/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch
@@ -0,0 +1,539 @@
+From d56b1a845aa9a9528eb1f9db8ce8a67d85683b28 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Thu, 26 Apr 2012 10:54:24 -0700
+Subject: [PATCH 16/16] Adapt Steven Michaud's Mac crashfix patch for FF12.
+
+Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
+
+Some minor tweaks were needed to get it to apply to FF12.
+---
+ widget/Makefile.in | 1 +
+ widget/cocoa/nsChildView.mm | 31 +++++++++++--------
+ widget/gtk2/nsDragService.cpp | 2 +-
+ widget/gtk2/nsWindow.cpp | 2 +-
+ widget/nsIDragService.idl | 4 +--
+ widget/nsPIDragService.idl | 48 +++++++++++++++++++++++++++++
+ widget/qt/nsDragService.h | 2 +
+ widget/windows/Makefile.in | 4 ++
+ widget/windows/nsDragService.cpp | 13 +++++---
+ widget/windows/nsDragService.h | 12 +++---
+ widget/windows/nsNativeDragSource.cpp | 7 ++--
+ widget/windows/nsNativeDragTarget.cpp | 28 ++++++++++------
+ widget/windows/nsPIDragServiceWindows.idl | 46 +++++++++++++++++++++++++++
+ widget/xpwidgets/nsBaseDragService.cpp | 16 +++++++++-
+ widget/xpwidgets/nsBaseDragService.h | 9 ++---
+ 15 files changed, 176 insertions(+), 49 deletions(-)
+ create mode 100644 widget/nsPIDragService.idl
+ create mode 100644 widget/windows/nsPIDragServiceWindows.idl
+
+diff --git a/widget/Makefile.in b/widget/Makefile.in
+index 4a3405b..4c105a4 100644
+--- a/widget/Makefile.in
++++ b/widget/Makefile.in
+@@ -138,6 +138,7 @@ XPIDLSRCS = \
+ nsIClipboardDragDropHooks.idl \
+ nsIClipboardDragDropHookList.idl \
+ nsIDragSession.idl \
++ nsPIDragService.idl \
+ nsIDragService.idl \
+ nsIFormatConverter.idl \
+ nsIClipboard.idl \
+diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
+index 7f738a1..189b9ef 100644
+--- a/widget/cocoa/nsChildView.mm
++++ b/widget/cocoa/nsChildView.mm
+@@ -4566,11 +4566,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ if (!dragService) {
+ dragService = do_GetService(kDragServiceContractID);
+ }
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
+
+ if (dragService) {
+ NSPoint pnt = [NSEvent mouseLocation];
+ FlipCocoaScreenCoordinate(pnt);
+- dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
+ }
+ }
+
+@@ -4591,11 +4592,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ }
+
+ if (mDragService) {
+- // set the dragend point from the current mouse location
+- nsDragService* dragService = static_cast<nsDragService *>(mDragService);
+- NSPoint pnt = [NSEvent mouseLocation];
+- FlipCocoaScreenCoordinate(pnt);
+- dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ // set the dragend point from the current mouse location
++ NSPoint pnt = [NSEvent mouseLocation];
++ FlipCocoaScreenCoordinate(pnt);
++ dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ }
+
+ // XXX: dropEffect should be updated per |operation|.
+ // As things stand though, |operation| isn't well handled within "our"
+@@ -4606,13 +4609,15 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ // value for NSDragOperationGeneric that is passed by other applications.
+ // All that said, NSDragOperationNone is still reliable.
+ if (operation == NSDragOperationNone) {
+- nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
+- dragService->GetDataTransfer(getter_AddRefs(dataTransfer));
+- nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
+- do_QueryInterface(dataTransfer);
+-
+- if (dataTransferNS)
+- dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ nsCOMPtr<nsIDragSession> dragSession;
++ mDragService->GetCurrentSession(getter_AddRefs(dragSession));
++ if (dragSession) {
++ nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
++ dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
++ if (dataTransfer) {
++ dataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ }
++ }
+ }
+
+ mDragService->EndDragSession(true);
+diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp
+index ca5a42c..876fd55 100644
+--- a/widget/gtk2/nsDragService.cpp
++++ b/widget/gtk2/nsDragService.cpp
+@@ -1334,7 +1334,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
+ GdkDisplay* display = gdk_display_get_default();
+ if (display) {
+ gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+- SetDragEndPoint(nsIntPoint(x, y));
++ SetDragEndPoint(x, y);
+ }
+
+ // Either the drag was aborted or the drop occurred outside the app.
+diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp
+index 5e4afee..25c394b 100644
+--- a/widget/gtk2/nsWindow.cpp
++++ b/widget/gtk2/nsWindow.cpp
+@@ -3698,7 +3698,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
+ if (display) {
+ // get the current cursor position
+ gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+- ((nsDragService *)dragService.get())->SetDragEndPoint(nsIntPoint(x, y));
++ ((nsDragService *)dragService.get())->SetDragEndPoint(x, y);
+ }
+ dragService->EndDragSession(true);
+
+diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
+index e42c578..ef8c46f 100644
+--- a/widget/nsIDragService.idl
++++ b/widget/nsIDragService.idl
+@@ -48,7 +48,7 @@ interface nsIDOMDragEvent;
+ interface nsIDOMDataTransfer;
+ interface nsISelection;
+
+-[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass]
++[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
+ interface nsIDragService : nsISupports
+ {
+ const long DRAGDROP_ACTION_NONE = 0;
+@@ -145,8 +145,6 @@ interface nsIDragService : nsISupports
+ */
+ void suppress();
+ void unsuppress();
+-
+- [noscript] void dragMoved(in long aX, in long aY);
+ };
+
+
+diff --git a/widget/nsPIDragService.idl b/widget/nsPIDragService.idl
+new file mode 100644
+index 0000000..93a144d
+--- /dev/null
++++ b/widget/nsPIDragService.idl
+@@ -0,0 +1,48 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)]
++interface nsPIDragService : nsISupports
++{
++ void dragMoved(in long aX, in long aY);
++
++ PRUint16 getInputSource();
++
++ void setDragEndPoint(in long aX, in long aY);
++};
+diff --git a/widget/qt/nsDragService.h b/widget/qt/nsDragService.h
+index 5a3e5bb..50dcfac 100644
+--- a/widget/qt/nsDragService.h
++++ b/widget/qt/nsDragService.h
+@@ -50,6 +50,8 @@ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDRAGSERVICE
+
++ NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY);
++
+ nsDragService();
+
+ private:
+diff --git a/widget/windows/Makefile.in b/widget/windows/Makefile.in
+index c9327f8..3298997 100644
+--- a/widget/windows/Makefile.in
++++ b/widget/windows/Makefile.in
+@@ -119,6 +119,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER
+ DEFINES += -DMOZ_ENABLE_D3D10_LAYER
+ endif
+
++XPIDLSRCS += \
++ nsPIDragServiceWindows.idl \
++ $(NULL)
++
+ SHARED_LIBRARY_LIBS = \
+ ../xpwidgets/$(LIB_PREFIX)xpwidgets_s.$(LIB_SUFFIX) \
+ $(NULL)
+diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp
+index 8c5df7e..1cf9995 100644
+--- a/widget/windows/nsDragService.cpp
++++ b/widget/windows/nsDragService.cpp
+@@ -97,6 +97,8 @@ nsDragService::~nsDragService()
+ NS_IF_RELEASE(mDataObject);
+ }
+
++NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows)
++
+ bool
+ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
+ nsIScriptableRegion *aRegion,
+@@ -350,7 +352,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
+ POINT cpos;
+ cpos.x = GET_X_LPARAM(pos);
+ cpos.y = GET_Y_LPARAM(pos);
+- SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ SetDragEndPoint(cpos.x, cpos.y);
+ EndDragSession(true);
+
+ mDoingDrag = false;
+@@ -468,25 +470,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+-nsDragService::SetIDataObject(IDataObject * aDataObj)
++nsDragService::SetIDataObject(nsISupports * aDataObj)
+ {
++ IDataObject *dataObj = (IDataObject*) aDataObj;
+ // When the native drag starts the DragService gets
+ // the IDataObject that is being dragged
+ NS_IF_RELEASE(mDataObject);
+- mDataObject = aDataObj;
++ mDataObject = dataObj;
+ NS_IF_ADDREF(mDataObject);
+
+ return NS_OK;
+ }
+
+ //---------------------------------------------------------
+-void
++NS_IMETHODIMP
+ nsDragService::SetDroppedLocal()
+ {
+ // Sent from the native drag handler, letting us know
+ // a drop occurred within the application vs. outside of it.
+ mSentLocalDropEvent = true;
+- return;
++ return NS_OK;
+ }
+
+ //-------------------------------------------------------------------------
+diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h
+index 87d6cc9..04c8746 100644
+--- a/widget/windows/nsDragService.h
++++ b/widget/windows/nsDragService.h
+@@ -39,6 +39,7 @@
+ #define nsDragService_h__
+
+ #include "nsBaseDragService.h"
++#include "nsPIDragServiceWindows.h"
+ #include <windows.h>
+ #include <shlobj.h>
+
+@@ -52,12 +53,15 @@ class nsString;
+ * Native Win32 DragService wrapper
+ */
+
+-class nsDragService : public nsBaseDragService
++class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows
+ {
+ public:
+ nsDragService();
+ virtual ~nsDragService();
+-
++
++ NS_DECL_ISUPPORTS_INHERITED
++ NS_DECL_NSPIDRAGSERVICEWINDOWS
++
+ // nsIDragService
+ NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
+ nsISupportsArray *anArrayTransferables,
+@@ -71,13 +75,9 @@ public:
+ NS_IMETHOD EndDragSession(bool aDoneDrag);
+
+ // native impl.
+- NS_IMETHOD SetIDataObject(IDataObject * aDataObj);
+ NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
+ PRUint32 aActionType);
+
+- // A drop occurred within the application vs. outside of it.
+- void SetDroppedLocal();
+-
+ protected:
+ nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
+
+diff --git a/widget/windows/nsNativeDragSource.cpp b/widget/windows/nsNativeDragSource.cpp
+index e51101e..0fe6ffe 100644
+--- a/widget/windows/nsNativeDragSource.cpp
++++ b/widget/windows/nsNativeDragSource.cpp
+@@ -42,7 +42,7 @@
+ #include "nsIServiceManager.h"
+ #include "nsToolkit.h"
+ #include "nsWidgetsCID.h"
+-#include "nsIDragService.h"
++#include "nsDragService.h"
+
+ static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
+
+@@ -101,9 +101,10 @@ STDMETHODIMP
+ nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
+ {
+ nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
+- if (dragService) {
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
++ if (dragServicePriv) {
+ DWORD pos = ::GetMessagePos();
+- dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
++ dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
+ }
+
+ if (fEsc) {
+diff --git a/widget/windows/nsNativeDragTarget.cpp b/widget/windows/nsNativeDragTarget.cpp
+index cf6196b..82ad3c6 100644
+--- a/widget/windows/nsNativeDragTarget.cpp
++++ b/widget/windows/nsNativeDragTarget.cpp
+@@ -209,7 +209,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
+ event.isControl = IsKeyDown(NS_VK_CONTROL);
+ event.isMeta = false;
+ event.isAlt = IsKeyDown(NS_VK_ALT);
+- event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
++ event.inputSource = 0;
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ dragServicePriv->GetInputSource(&event.inputSource);
++ }
+
+ mWindow->DispatchEvent(&event, status);
+ }
+@@ -296,9 +300,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService. It should be a private interface, though.
+- nsDragService * winDragService =
+- static_cast<nsDragService *>(mDragService);
+- winDragService->SetIDataObject(pIDataSource);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pIDataSource);
+
+ // Now process the native drag state and then dispatch the event
+ ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
+@@ -436,8 +439,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService (but it should still be a private interface)
+- nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
+- winDragService->SetIDataObject(pData);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pData);
+
+ // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects.
+ // We use strong refs to prevent it from destroying these:
+@@ -461,11 +464,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // tell the drag service we're done with the session
+ // Use GetMessagePos to get the position of the mouse at the last message
+ // seen by the event loop. (Bug 489729)
+- DWORD pos = ::GetMessagePos();
+- POINT cpos;
+- cpos.x = GET_X_LPARAM(pos);
+- cpos.y = GET_Y_LPARAM(pos);
+- winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ DWORD pos = ::GetMessagePos();
++ POINT cpos;
++ cpos.x = GET_X_LPARAM(pos);
++ cpos.y = GET_Y_LPARAM(pos);
++ dragServicePriv->SetDragEndPoint(cpos.x, cpos.y);
++ }
+ serv->EndDragSession(true);
+
+ // release the ref that was taken in DragEnter
+diff --git a/widget/windows/nsPIDragServiceWindows.idl b/widget/windows/nsPIDragServiceWindows.idl
+new file mode 100644
+index 0000000..c8a46dd
+--- /dev/null
++++ b/widget/windows/nsPIDragServiceWindows.idl
+@@ -0,0 +1,46 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)]
++interface nsPIDragServiceWindows : nsISupports
++{
++ void setIDataObject(in nsISupports aDataObj);
++
++ void setDroppedLocal();
++};
+diff --git a/widget/xpwidgets/nsBaseDragService.cpp b/widget/xpwidgets/nsBaseDragService.cpp
+index 342a036..87e28f7 100644
+--- a/widget/xpwidgets/nsBaseDragService.cpp
++++ b/widget/xpwidgets/nsBaseDragService.cpp
+@@ -88,7 +88,7 @@ nsBaseDragService::~nsBaseDragService()
+ {
+ }
+
+-NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession)
++NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+@@ -436,6 +436,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
+ return NS_OK;
+ }
+
++NS_IMETHODIMP
++nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY)
++{
++ mEndDragPoint = nsIntPoint(aX, aY);
++ return NS_OK;
++}
++
++NS_IMETHODIMP
++nsBaseDragService::GetInputSource(PRUint16* aInputSource)
++{
++ *aInputSource = mInputSource;
++ return NS_OK;
++}
++
+ static nsIPresShell*
+ GetPresShellForContent(nsIDOMNode* aDOMNode)
+ {
+diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h
+index 290c0cb..2ceac2b 100644
+--- a/widget/xpwidgets/nsBaseDragService.h
++++ b/widget/xpwidgets/nsBaseDragService.h
+@@ -39,6 +39,7 @@
+ #define nsBaseDragService_h__
+
+ #include "nsIDragService.h"
++#include "nsPIDragService.h"
+ #include "nsIDragSession.h"
+ #include "nsITransferable.h"
+ #include "nsISupportsArray.h"
+@@ -64,6 +65,7 @@ class nsICanvasElementExternal;
+ */
+
+ class nsBaseDragService : public nsIDragService,
++ public nsPIDragService,
+ public nsIDragSession
+ {
+
+@@ -74,14 +76,11 @@ public:
+ //nsISupports
+ NS_DECL_ISUPPORTS
+
+- //nsIDragSession and nsIDragService
++ //nsIDragSession, nsIDragService and nsPIDragService
+ NS_DECL_NSIDRAGSERVICE
++ NS_DECL_NSPIDRAGSERVICE
+ NS_DECL_NSIDRAGSESSION
+
+- void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
+-
+- PRUint16 GetInputSource() { return mInputSource; }
+-
+ protected:
+
+ /**
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0016-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/0016-Add-DDG-and-StartPage-to-Omnibox.patch
deleted file mode 100644
index 2206d96..0000000
--- a/src/current-patches/firefox/0016-Add-DDG-and-StartPage-to-Omnibox.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 67552486c7e0a1b8797e0cb562bddf771aa2015b Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 25 Apr 2012 15:03:46 -0700
-Subject: [PATCH 16/16] Add DDG and StartPage to Omnibox.
-
-You mean there are search engines that don't require captchas if you don't
-have a cookie? Holy crap. Get those in there now.
----
- browser/locales/en-US/searchplugins/duckduckgo.xml | 29 ++++++++++++++++++++
- browser/locales/en-US/searchplugins/list.txt | 2 +
- browser/locales/en-US/searchplugins/startpage.xml | 11 +++++++
- 3 files changed, 42 insertions(+), 0 deletions(-)
- create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml
- create mode 100644 browser/locales/en-US/searchplugins/startpage.xml
-
-diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml
-new file mode 100644
-index 0000000..4f00b4d
---- /dev/null
-+++ b/browser/locales/en-US/searchplugins/duckduckgo.xml
-@@ -0,0 +1,29 @@
-+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-+<ShortName>DuckDuckGo</ShortName>
-+<Description>Duck Duck Go</Description>
-+<InputEncoding>UTF-8</InputEncoding>
-+<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA
-+AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA
-+AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n
-+IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB
-+Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n/////
-+/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v//
-+//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h
-+XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg
-+7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs
-+5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/
-+JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg
-+7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1
-+/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/
-+fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y
-+1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg
-+7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs
-+AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA
-+AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA
-+AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD
-+AADwDwAA+B8AAA==</Image>
-+<Url type="text/html" method="POST" template="https://duckduckgo.com/html/">
-+ <Param name="q" value="{searchTerms}"/>
-+</Url>
-+<SearchForm>https://duckduckgo.com/html/</SearchForm>
-+</SearchPlugin>
-diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt
-index 2a1141a..0466f4e 100644
---- a/browser/locales/en-US/searchplugins/list.txt
-+++ b/browser/locales/en-US/searchplugins/list.txt
-@@ -1,7 +1,9 @@
- amazondotcom
- bing
-+duckduckgo
- eBay
- google
-+startpage
- twitter
- wikipedia
- yahoo
-diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml
-new file mode 100644
-index 0000000..1a310b1
---- /dev/null
-+++ b/browser/locales/en-US/searchplugins/startpage.xml
-@@ -0,0 +1,11 @@
-+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-+<ShortName>Startpage</ShortName>
-+<Description>Start Page</Description>
-+<InputEncoding>UTF-8</InputEncoding>
-+<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH+
+LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
-+
-+<Url type="text/html" method="POST" template="https://startpage.com/do/search">
-+ <Param name="q" value="{searchTerms}"/>
-+</Url>
-+<SearchForm>https://startpage.com/do/search/</SearchForm>
-+</SearchPlugin>
---
-1.7.5.4
-
1
0

[torbrowser/maint-2.2] Add in Steven Michaud's Mac crash fix patch.
by erinn@torproject.org 27 Apr '12
by erinn@torproject.org 27 Apr '12
27 Apr '12
commit 14b892d5ef89eabf4d94c15da0a1d10677ebccc6
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Thu Apr 26 11:03:48 2012 -0700
Add in Steven Michaud's Mac crash fix patch.
Also remove a patch that it includes.
---
.../0015-Add-DDG-and-StartPage-to-Omnibox.patch | 84 +++
.../0015-Undo-some-Mozilla-braindamage.patch | 28 -
...ven-Michaud-s-Mac-crashfix-patch-for-FF12.patch | 539 ++++++++++++++++++++
.../0016-Add-DDG-and-StartPage-to-Omnibox.patch | 84 ---
4 files changed, 623 insertions(+), 112 deletions(-)
diff --git a/src/current-patches/firefox/0015-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/0015-Add-DDG-and-StartPage-to-Omnibox.patch
new file mode 100644
index 0000000..e0740ae
--- /dev/null
+++ b/src/current-patches/firefox/0015-Add-DDG-and-StartPage-to-Omnibox.patch
@@ -0,0 +1,84 @@
+From db055738d6431057670e8f219616170ed3644a9e Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 25 Apr 2012 15:03:46 -0700
+Subject: [PATCH 15/16] Add DDG and StartPage to Omnibox.
+
+You mean there are search engines that don't require captchas if you don't
+have a cookie? Holy crap. Get those in there now.
+---
+ browser/locales/en-US/searchplugins/duckduckgo.xml | 29 ++++++++++++++++++++
+ browser/locales/en-US/searchplugins/list.txt | 2 +
+ browser/locales/en-US/searchplugins/startpage.xml | 11 +++++++
+ 3 files changed, 42 insertions(+), 0 deletions(-)
+ create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml
+ create mode 100644 browser/locales/en-US/searchplugins/startpage.xml
+
+diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml
+new file mode 100644
+index 0000000..4f00b4d
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/duckduckgo.xml
+@@ -0,0 +1,29 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>DuckDuckGo</ShortName>
++<Description>Duck Duck Go</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n
++IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB
++Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n/////
++/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v//
++//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h
++XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg
++7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs
++5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/
++JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1
++/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/
++fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y
++1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs
++AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA
++AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA
++AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD
++AADwDwAA+B8AAA==</Image>
++<Url type="text/html" method="POST" template="https://duckduckgo.com/html/">
++ <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://duckduckgo.com/html/</SearchForm>
++</SearchPlugin>
+diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt
+index 2a1141a..0466f4e 100644
+--- a/browser/locales/en-US/searchplugins/list.txt
++++ b/browser/locales/en-US/searchplugins/list.txt
+@@ -1,7 +1,9 @@
+ amazondotcom
+ bing
++duckduckgo
+ eBay
+ google
++startpage
+ twitter
+ wikipedia
+ yahoo
+diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml
+new file mode 100644
+index 0000000..1a310b1
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/startpage.xml
+@@ -0,0 +1,11 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>Startpage</ShortName>
++<Description>Start Page</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH+
+LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
++
++<Url type="text/html" method="POST" template="https://startpage.com/do/search">
++ <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://startpage.com/do/search/</SearchForm>
++</SearchPlugin>
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0015-Undo-some-Mozilla-braindamage.patch b/src/current-patches/firefox/0015-Undo-some-Mozilla-braindamage.patch
deleted file mode 100644
index 88e204f..0000000
--- a/src/current-patches/firefox/0015-Undo-some-Mozilla-braindamage.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 74be7d742204d48fbb51a90275781378948ba749 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 25 Apr 2012 13:42:52 -0700
-Subject: [PATCH 15/16] Undo some Mozilla braindamage.
-
-https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c33
-
-Seriously guys?
----
- widget/nsIDragService.idl | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
-index e42c578..6863a88 100644
---- a/widget/nsIDragService.idl
-+++ b/widget/nsIDragService.idl
-@@ -48,7 +48,7 @@ interface nsIDOMDragEvent;
- interface nsIDOMDataTransfer;
- interface nsISelection;
-
--[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass]
-+[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
- interface nsIDragService : nsISupports
- {
- const long DRAGDROP_ACTION_NONE = 0;
---
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch b/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch
new file mode 100644
index 0000000..16de3d9
--- /dev/null
+++ b/src/current-patches/firefox/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch
@@ -0,0 +1,539 @@
+From d56b1a845aa9a9528eb1f9db8ce8a67d85683b28 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Thu, 26 Apr 2012 10:54:24 -0700
+Subject: [PATCH 16/16] Adapt Steven Michaud's Mac crashfix patch for FF12.
+
+Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
+
+Some minor tweaks were needed to get it to apply to FF12.
+---
+ widget/Makefile.in | 1 +
+ widget/cocoa/nsChildView.mm | 31 +++++++++++--------
+ widget/gtk2/nsDragService.cpp | 2 +-
+ widget/gtk2/nsWindow.cpp | 2 +-
+ widget/nsIDragService.idl | 4 +--
+ widget/nsPIDragService.idl | 48 +++++++++++++++++++++++++++++
+ widget/qt/nsDragService.h | 2 +
+ widget/windows/Makefile.in | 4 ++
+ widget/windows/nsDragService.cpp | 13 +++++---
+ widget/windows/nsDragService.h | 12 +++---
+ widget/windows/nsNativeDragSource.cpp | 7 ++--
+ widget/windows/nsNativeDragTarget.cpp | 28 ++++++++++------
+ widget/windows/nsPIDragServiceWindows.idl | 46 +++++++++++++++++++++++++++
+ widget/xpwidgets/nsBaseDragService.cpp | 16 +++++++++-
+ widget/xpwidgets/nsBaseDragService.h | 9 ++---
+ 15 files changed, 176 insertions(+), 49 deletions(-)
+ create mode 100644 widget/nsPIDragService.idl
+ create mode 100644 widget/windows/nsPIDragServiceWindows.idl
+
+diff --git a/widget/Makefile.in b/widget/Makefile.in
+index 4a3405b..4c105a4 100644
+--- a/widget/Makefile.in
++++ b/widget/Makefile.in
+@@ -138,6 +138,7 @@ XPIDLSRCS = \
+ nsIClipboardDragDropHooks.idl \
+ nsIClipboardDragDropHookList.idl \
+ nsIDragSession.idl \
++ nsPIDragService.idl \
+ nsIDragService.idl \
+ nsIFormatConverter.idl \
+ nsIClipboard.idl \
+diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
+index 7f738a1..189b9ef 100644
+--- a/widget/cocoa/nsChildView.mm
++++ b/widget/cocoa/nsChildView.mm
+@@ -4566,11 +4566,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ if (!dragService) {
+ dragService = do_GetService(kDragServiceContractID);
+ }
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
+
+ if (dragService) {
+ NSPoint pnt = [NSEvent mouseLocation];
+ FlipCocoaScreenCoordinate(pnt);
+- dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
+ }
+ }
+
+@@ -4591,11 +4592,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ }
+
+ if (mDragService) {
+- // set the dragend point from the current mouse location
+- nsDragService* dragService = static_cast<nsDragService *>(mDragService);
+- NSPoint pnt = [NSEvent mouseLocation];
+- FlipCocoaScreenCoordinate(pnt);
+- dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ // set the dragend point from the current mouse location
++ NSPoint pnt = [NSEvent mouseLocation];
++ FlipCocoaScreenCoordinate(pnt);
++ dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ }
+
+ // XXX: dropEffect should be updated per |operation|.
+ // As things stand though, |operation| isn't well handled within "our"
+@@ -4606,13 +4609,15 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ // value for NSDragOperationGeneric that is passed by other applications.
+ // All that said, NSDragOperationNone is still reliable.
+ if (operation == NSDragOperationNone) {
+- nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
+- dragService->GetDataTransfer(getter_AddRefs(dataTransfer));
+- nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
+- do_QueryInterface(dataTransfer);
+-
+- if (dataTransferNS)
+- dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ nsCOMPtr<nsIDragSession> dragSession;
++ mDragService->GetCurrentSession(getter_AddRefs(dragSession));
++ if (dragSession) {
++ nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
++ dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
++ if (dataTransfer) {
++ dataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ }
++ }
+ }
+
+ mDragService->EndDragSession(true);
+diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp
+index ca5a42c..876fd55 100644
+--- a/widget/gtk2/nsDragService.cpp
++++ b/widget/gtk2/nsDragService.cpp
+@@ -1334,7 +1334,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
+ GdkDisplay* display = gdk_display_get_default();
+ if (display) {
+ gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+- SetDragEndPoint(nsIntPoint(x, y));
++ SetDragEndPoint(x, y);
+ }
+
+ // Either the drag was aborted or the drop occurred outside the app.
+diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp
+index 5e4afee..25c394b 100644
+--- a/widget/gtk2/nsWindow.cpp
++++ b/widget/gtk2/nsWindow.cpp
+@@ -3698,7 +3698,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
+ if (display) {
+ // get the current cursor position
+ gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+- ((nsDragService *)dragService.get())->SetDragEndPoint(nsIntPoint(x, y));
++ ((nsDragService *)dragService.get())->SetDragEndPoint(x, y);
+ }
+ dragService->EndDragSession(true);
+
+diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
+index e42c578..ef8c46f 100644
+--- a/widget/nsIDragService.idl
++++ b/widget/nsIDragService.idl
+@@ -48,7 +48,7 @@ interface nsIDOMDragEvent;
+ interface nsIDOMDataTransfer;
+ interface nsISelection;
+
+-[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass]
++[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
+ interface nsIDragService : nsISupports
+ {
+ const long DRAGDROP_ACTION_NONE = 0;
+@@ -145,8 +145,6 @@ interface nsIDragService : nsISupports
+ */
+ void suppress();
+ void unsuppress();
+-
+- [noscript] void dragMoved(in long aX, in long aY);
+ };
+
+
+diff --git a/widget/nsPIDragService.idl b/widget/nsPIDragService.idl
+new file mode 100644
+index 0000000..93a144d
+--- /dev/null
++++ b/widget/nsPIDragService.idl
+@@ -0,0 +1,48 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)]
++interface nsPIDragService : nsISupports
++{
++ void dragMoved(in long aX, in long aY);
++
++ PRUint16 getInputSource();
++
++ void setDragEndPoint(in long aX, in long aY);
++};
+diff --git a/widget/qt/nsDragService.h b/widget/qt/nsDragService.h
+index 5a3e5bb..50dcfac 100644
+--- a/widget/qt/nsDragService.h
++++ b/widget/qt/nsDragService.h
+@@ -50,6 +50,8 @@ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDRAGSERVICE
+
++ NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY);
++
+ nsDragService();
+
+ private:
+diff --git a/widget/windows/Makefile.in b/widget/windows/Makefile.in
+index c9327f8..3298997 100644
+--- a/widget/windows/Makefile.in
++++ b/widget/windows/Makefile.in
+@@ -119,6 +119,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER
+ DEFINES += -DMOZ_ENABLE_D3D10_LAYER
+ endif
+
++XPIDLSRCS += \
++ nsPIDragServiceWindows.idl \
++ $(NULL)
++
+ SHARED_LIBRARY_LIBS = \
+ ../xpwidgets/$(LIB_PREFIX)xpwidgets_s.$(LIB_SUFFIX) \
+ $(NULL)
+diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp
+index 8c5df7e..1cf9995 100644
+--- a/widget/windows/nsDragService.cpp
++++ b/widget/windows/nsDragService.cpp
+@@ -97,6 +97,8 @@ nsDragService::~nsDragService()
+ NS_IF_RELEASE(mDataObject);
+ }
+
++NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows)
++
+ bool
+ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
+ nsIScriptableRegion *aRegion,
+@@ -350,7 +352,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
+ POINT cpos;
+ cpos.x = GET_X_LPARAM(pos);
+ cpos.y = GET_Y_LPARAM(pos);
+- SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ SetDragEndPoint(cpos.x, cpos.y);
+ EndDragSession(true);
+
+ mDoingDrag = false;
+@@ -468,25 +470,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+-nsDragService::SetIDataObject(IDataObject * aDataObj)
++nsDragService::SetIDataObject(nsISupports * aDataObj)
+ {
++ IDataObject *dataObj = (IDataObject*) aDataObj;
+ // When the native drag starts the DragService gets
+ // the IDataObject that is being dragged
+ NS_IF_RELEASE(mDataObject);
+- mDataObject = aDataObj;
++ mDataObject = dataObj;
+ NS_IF_ADDREF(mDataObject);
+
+ return NS_OK;
+ }
+
+ //---------------------------------------------------------
+-void
++NS_IMETHODIMP
+ nsDragService::SetDroppedLocal()
+ {
+ // Sent from the native drag handler, letting us know
+ // a drop occurred within the application vs. outside of it.
+ mSentLocalDropEvent = true;
+- return;
++ return NS_OK;
+ }
+
+ //-------------------------------------------------------------------------
+diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h
+index 87d6cc9..04c8746 100644
+--- a/widget/windows/nsDragService.h
++++ b/widget/windows/nsDragService.h
+@@ -39,6 +39,7 @@
+ #define nsDragService_h__
+
+ #include "nsBaseDragService.h"
++#include "nsPIDragServiceWindows.h"
+ #include <windows.h>
+ #include <shlobj.h>
+
+@@ -52,12 +53,15 @@ class nsString;
+ * Native Win32 DragService wrapper
+ */
+
+-class nsDragService : public nsBaseDragService
++class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows
+ {
+ public:
+ nsDragService();
+ virtual ~nsDragService();
+-
++
++ NS_DECL_ISUPPORTS_INHERITED
++ NS_DECL_NSPIDRAGSERVICEWINDOWS
++
+ // nsIDragService
+ NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
+ nsISupportsArray *anArrayTransferables,
+@@ -71,13 +75,9 @@ public:
+ NS_IMETHOD EndDragSession(bool aDoneDrag);
+
+ // native impl.
+- NS_IMETHOD SetIDataObject(IDataObject * aDataObj);
+ NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
+ PRUint32 aActionType);
+
+- // A drop occurred within the application vs. outside of it.
+- void SetDroppedLocal();
+-
+ protected:
+ nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
+
+diff --git a/widget/windows/nsNativeDragSource.cpp b/widget/windows/nsNativeDragSource.cpp
+index e51101e..0fe6ffe 100644
+--- a/widget/windows/nsNativeDragSource.cpp
++++ b/widget/windows/nsNativeDragSource.cpp
+@@ -42,7 +42,7 @@
+ #include "nsIServiceManager.h"
+ #include "nsToolkit.h"
+ #include "nsWidgetsCID.h"
+-#include "nsIDragService.h"
++#include "nsDragService.h"
+
+ static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
+
+@@ -101,9 +101,10 @@ STDMETHODIMP
+ nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
+ {
+ nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
+- if (dragService) {
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
++ if (dragServicePriv) {
+ DWORD pos = ::GetMessagePos();
+- dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
++ dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
+ }
+
+ if (fEsc) {
+diff --git a/widget/windows/nsNativeDragTarget.cpp b/widget/windows/nsNativeDragTarget.cpp
+index cf6196b..82ad3c6 100644
+--- a/widget/windows/nsNativeDragTarget.cpp
++++ b/widget/windows/nsNativeDragTarget.cpp
+@@ -209,7 +209,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
+ event.isControl = IsKeyDown(NS_VK_CONTROL);
+ event.isMeta = false;
+ event.isAlt = IsKeyDown(NS_VK_ALT);
+- event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
++ event.inputSource = 0;
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ dragServicePriv->GetInputSource(&event.inputSource);
++ }
+
+ mWindow->DispatchEvent(&event, status);
+ }
+@@ -296,9 +300,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService. It should be a private interface, though.
+- nsDragService * winDragService =
+- static_cast<nsDragService *>(mDragService);
+- winDragService->SetIDataObject(pIDataSource);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pIDataSource);
+
+ // Now process the native drag state and then dispatch the event
+ ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
+@@ -436,8 +439,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService (but it should still be a private interface)
+- nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
+- winDragService->SetIDataObject(pData);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pData);
+
+ // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects.
+ // We use strong refs to prevent it from destroying these:
+@@ -461,11 +464,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // tell the drag service we're done with the session
+ // Use GetMessagePos to get the position of the mouse at the last message
+ // seen by the event loop. (Bug 489729)
+- DWORD pos = ::GetMessagePos();
+- POINT cpos;
+- cpos.x = GET_X_LPARAM(pos);
+- cpos.y = GET_Y_LPARAM(pos);
+- winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ DWORD pos = ::GetMessagePos();
++ POINT cpos;
++ cpos.x = GET_X_LPARAM(pos);
++ cpos.y = GET_Y_LPARAM(pos);
++ dragServicePriv->SetDragEndPoint(cpos.x, cpos.y);
++ }
+ serv->EndDragSession(true);
+
+ // release the ref that was taken in DragEnter
+diff --git a/widget/windows/nsPIDragServiceWindows.idl b/widget/windows/nsPIDragServiceWindows.idl
+new file mode 100644
+index 0000000..c8a46dd
+--- /dev/null
++++ b/widget/windows/nsPIDragServiceWindows.idl
+@@ -0,0 +1,46 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)]
++interface nsPIDragServiceWindows : nsISupports
++{
++ void setIDataObject(in nsISupports aDataObj);
++
++ void setDroppedLocal();
++};
+diff --git a/widget/xpwidgets/nsBaseDragService.cpp b/widget/xpwidgets/nsBaseDragService.cpp
+index 342a036..87e28f7 100644
+--- a/widget/xpwidgets/nsBaseDragService.cpp
++++ b/widget/xpwidgets/nsBaseDragService.cpp
+@@ -88,7 +88,7 @@ nsBaseDragService::~nsBaseDragService()
+ {
+ }
+
+-NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession)
++NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+@@ -436,6 +436,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
+ return NS_OK;
+ }
+
++NS_IMETHODIMP
++nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY)
++{
++ mEndDragPoint = nsIntPoint(aX, aY);
++ return NS_OK;
++}
++
++NS_IMETHODIMP
++nsBaseDragService::GetInputSource(PRUint16* aInputSource)
++{
++ *aInputSource = mInputSource;
++ return NS_OK;
++}
++
+ static nsIPresShell*
+ GetPresShellForContent(nsIDOMNode* aDOMNode)
+ {
+diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h
+index 290c0cb..2ceac2b 100644
+--- a/widget/xpwidgets/nsBaseDragService.h
++++ b/widget/xpwidgets/nsBaseDragService.h
+@@ -39,6 +39,7 @@
+ #define nsBaseDragService_h__
+
+ #include "nsIDragService.h"
++#include "nsPIDragService.h"
+ #include "nsIDragSession.h"
+ #include "nsITransferable.h"
+ #include "nsISupportsArray.h"
+@@ -64,6 +65,7 @@ class nsICanvasElementExternal;
+ */
+
+ class nsBaseDragService : public nsIDragService,
++ public nsPIDragService,
+ public nsIDragSession
+ {
+
+@@ -74,14 +76,11 @@ public:
+ //nsISupports
+ NS_DECL_ISUPPORTS
+
+- //nsIDragSession and nsIDragService
++ //nsIDragSession, nsIDragService and nsPIDragService
+ NS_DECL_NSIDRAGSERVICE
++ NS_DECL_NSPIDRAGSERVICE
+ NS_DECL_NSIDRAGSESSION
+
+- void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
+-
+- PRUint16 GetInputSource() { return mInputSource; }
+-
+ protected:
+
+ /**
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0016-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/0016-Add-DDG-and-StartPage-to-Omnibox.patch
deleted file mode 100644
index 2206d96..0000000
--- a/src/current-patches/firefox/0016-Add-DDG-and-StartPage-to-Omnibox.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 67552486c7e0a1b8797e0cb562bddf771aa2015b Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 25 Apr 2012 15:03:46 -0700
-Subject: [PATCH 16/16] Add DDG and StartPage to Omnibox.
-
-You mean there are search engines that don't require captchas if you don't
-have a cookie? Holy crap. Get those in there now.
----
- browser/locales/en-US/searchplugins/duckduckgo.xml | 29 ++++++++++++++++++++
- browser/locales/en-US/searchplugins/list.txt | 2 +
- browser/locales/en-US/searchplugins/startpage.xml | 11 +++++++
- 3 files changed, 42 insertions(+), 0 deletions(-)
- create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml
- create mode 100644 browser/locales/en-US/searchplugins/startpage.xml
-
-diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml
-new file mode 100644
-index 0000000..4f00b4d
---- /dev/null
-+++ b/browser/locales/en-US/searchplugins/duckduckgo.xml
-@@ -0,0 +1,29 @@
-+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-+<ShortName>DuckDuckGo</ShortName>
-+<Description>Duck Duck Go</Description>
-+<InputEncoding>UTF-8</InputEncoding>
-+<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA
-+AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA
-+AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n
-+IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB
-+Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n/////
-+/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v//
-+//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h
-+XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg
-+7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs
-+5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/
-+JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg
-+7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1
-+/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/
-+fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y
-+1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg
-+7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs
-+AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA
-+AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA
-+AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD
-+AADwDwAA+B8AAA==</Image>
-+<Url type="text/html" method="POST" template="https://duckduckgo.com/html/">
-+ <Param name="q" value="{searchTerms}"/>
-+</Url>
-+<SearchForm>https://duckduckgo.com/html/</SearchForm>
-+</SearchPlugin>
-diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt
-index 2a1141a..0466f4e 100644
---- a/browser/locales/en-US/searchplugins/list.txt
-+++ b/browser/locales/en-US/searchplugins/list.txt
-@@ -1,7 +1,9 @@
- amazondotcom
- bing
-+duckduckgo
- eBay
- google
-+startpage
- twitter
- wikipedia
- yahoo
-diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml
-new file mode 100644
-index 0000000..1a310b1
---- /dev/null
-+++ b/browser/locales/en-US/searchplugins/startpage.xml
-@@ -0,0 +1,11 @@
-+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-+<ShortName>Startpage</ShortName>
-+<Description>Start Page</Description>
-+<InputEncoding>UTF-8</InputEncoding>
-+<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH+
+LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
-+
-+<Url type="text/html" method="POST" template="https://startpage.com/do/search">
-+ <Param name="q" value="{searchTerms}"/>
-+</Url>
-+<SearchForm>https://startpage.com/do/search/</SearchForm>
-+</SearchPlugin>
---
-1.7.5.4
-
1
0