summaryrefslogtreecommitdiff
path: root/src/or/routerparse.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-06-01 18:19:01 +0000
committerNick Mathewson <nickm@torproject.org>2004-06-01 18:19:01 +0000
commit94782444f80f483bafebf537b059f2d8a8e0cdd2 (patch)
treed7e0c5af0a66f2b9176b2366d18eec2deeb26f5d /src/or/routerparse.c
parent74f611581ef992e8657c989883956d5a352b8965 (diff)
downloadtor-94782444f80f483bafebf537b059f2d8a8e0cdd2.tar.gz
tor-94782444f80f483bafebf537b059f2d8a8e0cdd2.zip
Check recommended-software string *early*, before actually parsing the directory.
svn:r1930
Diffstat (limited to 'src/or/routerparse.c')
-rw-r--r--src/or/routerparse.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 6b227fcddf..c239a613e2 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -176,6 +176,89 @@ static int parse_time(const char *cp, time_t *t)
return 0;
}
+/**
+ * Find the first instance of "recommended-software ...\n" at the start of
+ * a line; return a newly allocated string containing the "..." portion.
+ * Return NULL if no such instance was found.
+ */
+static char *
+get_recommended_software_from_directory(const char *str)
+{
+#define REC "recommended-software "
+ const char *cp = str, *eol;
+ int len = strlen(REC);
+ cp = str;
+ if (strncmp(str, REC, len)==0) {
+ cp += len;
+ } else {
+ cp = strstr(str, "\n"REC);
+ if (!cp)
+ return NULL;
+ cp += len+1;
+ }
+ eol = strchr(cp, '\n');
+ if (!eol)
+ return NULL;
+ return tor_strndup(cp, eol-cp);
+#undef REC
+}
+
+/** Return 1 if myversion is in versionlist. Else return 0.
+ * (versionlist is a comma-separated list of versions.) */
+/* static */ int is_recommended_version(const char *myversion,
+ const char *versionlist) {
+ int len_myversion = strlen(myversion);
+ char *comma;
+ const char *end = versionlist + strlen(versionlist);
+
+ log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, versionlist);
+
+ for(;;) {
+ comma = strchr(versionlist, ',');
+ if( ((comma ? comma : end) - versionlist == len_myversion) &&
+ !strncmp(versionlist, myversion, len_myversion))
+ /* only do strncmp if the length matches */
+ return 1; /* success, it's there */
+ if(!comma)
+ return 0; /* nope */
+ versionlist = comma+1;
+ }
+}
+
+/* Return 0 if myversion is supported; else log a message and return
+ * -1 (or exit if ignoreversions is false) */
+int check_software_version_against_directory(const char *directory,
+ int ignoreversion)
+{
+ char *v;
+ v = get_recommended_software_from_directory(directory);
+ if (!v) {
+ log_fn(LOG_WARN, "No recommended-versions string found in directory");
+ return -1;
+ }
+ /* Look for versions of the form "0.1.0" and of the form "Tor 0.1.0".
+ * Eventually, we should deprecate the first form.
+ */
+ if (is_recommended_version(VERSION, v) ||
+ is_recommended_version("Tor "VERSION, v)) {
+ tor_free(v);
+ return 0;
+ }
+ log(ignoreversion ? LOG_WARN : LOG_ERR,
+ "You are running Tor version %s, which will not work with this network.\n"
+ "Please use %s%s.",
+ VERSION, strchr(v,',') ? "one of " : "", v);
+ tor_free(v);
+
+ if(ignoreversion) {
+ log(LOG_WARN, "IgnoreVersion is set. If it breaks, we told you so.");
+ return -1;
+ } else {
+ fflush(0);
+ exit(0);
+ return -1; /* never reached */
+ }
+}
/** Parse a directory from <b>s</b> and, when done, store the
* resulting routerlist in *<b>dest</b>, freeing the old value if necessary.