[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Code to parse tor version numbers so we can do an is-newer-...



Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv10447/src/or

Modified Files:
	or.h routerparse.c test.c 
Log Message:
Code to parse tor version numbers so we can do an is-newer-than check.

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.378
retrieving revision 1.379
diff -u -d -r1.378 -r1.379
--- or.h	13 Jul 2004 07:42:20 -0000	1.378
+++ or.h	13 Jul 2004 19:16:49 -0000	1.379
@@ -1383,6 +1383,15 @@
 
 /********************************* routerparse.c ************************/
 
+typedef struct tor_version_t {
+  int major;
+  int minor;
+  int micro;
+  enum { VER_PRE=0, VER_RC=1, VER_RELEASE=2 } status;
+  int patchlevel;
+  enum { IS_CVS=0, IS_NOT_CVS=1} cvs;
+} tor_version_t;
+
 int router_get_router_hash(const char *s, char *digest);
 int router_get_dir_hash(const char *s, char *digest);
 int router_get_runningrouters_hash(const char *s, char *digest);
@@ -1399,7 +1408,9 @@
 struct exit_policy_t *router_parse_exit_policy_from_string(const char *s);
 int check_software_version_against_directory(const char *directory,
                                              int ignoreversion);
-
+int tor_version_parse(const char *s, tor_version_t *out);
+int tor_version_compare(tor_version_t *a, tor_version_t *b);
+int tor_version_compare_to_mine(const char *s);
 
 #endif
 

Index: routerparse.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerparse.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- routerparse.c	12 Jul 2004 18:02:54 -0000	1.10
+++ routerparse.c	13 Jul 2004 19:16:49 -0000	1.11
@@ -1297,6 +1297,113 @@
   return 0;
 }
 
+int tor_version_parse(const char *s, tor_version_t *out)
+{
+  char *eos=NULL, *cp=NULL;
+  /* Format is:
+   *   NUM dot NUM dot NUM [ ( pre | rc | dot ) NUM [ -cvs ] ]
+   */
+  tor_assert(s && out);
+  memset(out, 0, sizeof(tor_version_t));
+
+  /* Get major. */
+  out->major = strtol(s,&eos,10);
+  if (!eos || eos==s || *eos != '.') return -1;
+  cp = eos+1;
+
+  /* Get minor */
+  out->minor = strtol(cp,&eos,10);
+  if (!eos || eos==cp || *eos != '.') return -1;
+  cp = eos+1;
+
+  /* Get micro */
+  out->micro = strtol(cp,&eos,10);
+  if (!eos || eos==cp) return -1;
+  if (!*eos) {
+    out->status = VER_RELEASE;
+    out->patchlevel = 0;
+    out->cvs = IS_NOT_CVS;
+    return 0;
+  }
+  cp = eos;
+
+  /* Get status */
+  if (*cp == '.') {
+    out->status = VER_RELEASE;
+    ++cp;
+  } else if (0==strncmp(cp, "pre", 3)) {
+    out->status = VER_PRE;
+    cp += 3;
+  } else if (0==strncmp(cp, "rc", 2)) {
+    out->status = VER_RC;
+    cp += 2;
+  } else {
+    return -1;
+  }
+
+  /* Get patchlevel */
+  out->patchlevel = strtol(cp,&eos,10);
+  if (!eos || eos==cp) return -1;
+  cp = eos;
+
+  /* Get cvs status. */
+  if (!*eos) {
+    out->cvs = IS_NOT_CVS;
+  } else if (0==strcmp(cp, "-cvs")) {
+    out->cvs = IS_CVS;
+  } else {
+    return -1;
+  }
+
+  return 0;
+}
+
+/** Compare two tor versions; Return <0 if a < b; 0 if a ==b, >0 if a >
+ * b. */
+int tor_version_compare(tor_version_t *a, tor_version_t *b)
+{
+  int i;
+  tor_assert(a && b);
+  if ((i = a->major - b->major))
+    return i;
+  else if ((i = a->minor - b->minor))
+    return i;
+  else if ((i = a->micro - b->micro))
+    return i;
+  else if ((i = a->status - b->status))
+    return i;
+  else if ((i = a->patchlevel - b->patchlevel))
+    return i;
+  else if ((i = a->cvs - b->cvs))
+    return i;
+  else
+    return 0;
+}
+
+static tor_version_t *my_tor_version=NULL;
+
+/** 1 for unequal, newer or can't tell; 0 for equal, -1 for older. */
+int tor_version_compare_to_mine(const char *s)
+{
+  tor_version_t v;
+
+  if (!my_tor_version) {
+    my_tor_version = tor_malloc(sizeof(tor_version_t));
+    if (tor_version_parse(VERSION, my_tor_version)) {
+      log_fn(LOG_ERR, "I couldn't parse my own version ("VERSION")");
+      exit(1);
+    }
+  }
+
+  if (tor_version_parse(s,&v)) {
+    log_fn(LOG_WARN, "Unparseable tor version %s", s);
+    return 1;
+  }
+
+  return tor_version_compare(my_tor_version, &v);
+}
+
+
 /*
   Local Variables:
   mode:c

Index: test.c
===================================================================
RCS file: /home/or/cvsroot/src/or/test.c,v
retrieving revision 1.98
retrieving revision 1.99
diff -u -d -r1.98 -r1.99
--- test.c	12 Jul 2004 20:18:05 -0000	1.98
+++ test.c	13 Jul 2004 19:16:49 -0000	1.99
@@ -661,6 +661,7 @@
   routerinfo_t *rp1 = NULL, *rp2 = NULL;
   struct exit_policy_t ex1, ex2;
   routerlist_t *dir1 = NULL, *dir2 = NULL;
+  tor_version_t ver1, ver2;
 
   test_assert( (pk1 = crypto_new_pk_env()) );
   test_assert( (pk2 = crypto_new_pk_env()) );
@@ -824,6 +825,36 @@
   test_eq(0, is_recommended_version("a", "ab,abd,abde,abc,abcde"));
   test_eq(0, is_recommended_version("abb", "ab,abd,abde,abc,abcde"));
   test_eq(0, is_recommended_version("a", ""));
+
+  /* Try out version parsing functionality */
+  test_eq(0, tor_version_parse("0.3.4pre2-cvs", &ver1));
+  test_eq(0, ver1.major);
+  test_eq(3, ver1.minor);
+  test_eq(4, ver1.micro);
+  test_eq(VER_PRE, ver1.status);
+  test_eq(2, ver1.patchlevel);
+  test_eq(IS_CVS, ver1.cvs);
+  test_eq(0, tor_version_parse("0.3.4rc1", &ver1));
+  test_eq(0, ver1.major);
+  test_eq(3, ver1.minor);
+  test_eq(4, ver1.micro);
+  test_eq(VER_RC, ver1.status);
+  test_eq(1, ver1.patchlevel);
+  test_eq(IS_NOT_CVS, ver1.cvs);
+  test_eq(0, tor_version_parse("1.3.4", &ver1));
+  test_eq(1, ver1.major);
+  test_eq(3, ver1.minor);
+  test_eq(4, ver1.micro);
+  test_eq(VER_RELEASE, ver1.status);
+  test_eq(0, ver1.patchlevel);
+  test_eq(IS_NOT_CVS, ver1.cvs);
+  test_eq(0, tor_version_parse("1.3.4.999", &ver1));
+  test_eq(1, ver1.major);
+  test_eq(3, ver1.minor);
+  test_eq(4, ver1.micro);
+  test_eq(VER_RELEASE, ver1.status);
+  test_eq(999, ver1.patchlevel);
+  test_eq(IS_NOT_CVS, ver1.cvs);
 }
 
 void test_rend_fns()