diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-06-01 18:19:01 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-06-01 18:19:01 +0000 |
commit | 94782444f80f483bafebf537b059f2d8a8e0cdd2 (patch) | |
tree | d7e0c5af0a66f2b9176b2366d18eec2deeb26f5d /src/or/routerparse.c | |
parent | 74f611581ef992e8657c989883956d5a352b8965 (diff) | |
download | tor-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.c | 83 |
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. |