Beispiel #1
0
/**
 * Parse a version string coming from a database file.
 *
 * It parses a version string, and prints a warning or an error depending
 * on the parse options.
 *
 * @param ps The parsedb state.
 * @param version The version to parse into.
 * @param value The version string to parse from.
 *
 * @retval  0 On success, and err is reset.
 * @retval -1 On failure, and err is set accordingly.
 */
int
parse_db_version(struct parsedb_state *ps, struct dpkg_version *version,
                 const char *value)
{
  dpkg_error_destroy(&ps->err);

  if (parseversion(version, value, &ps->err) == 0)
    return 0;

  /* If not in lax mode, turn everything into an error. */
  if (!(ps->flags & pdb_lax_version_parser))
    ps->err.type = DPKG_MSG_ERROR;

  return -1;
}
Beispiel #2
0
int main(int argc, char *argv[]) 
{
  const char *err;
  struct versionrevision ver, ref;

  if (argc < 4) {
    fprintf(stderr, "usage: %s: version op refversion\n", argv[0]);
    return 2;
  }

  err = parseversion(&ver, argv[1]);
  if (err) {
    fprintf(stderr, "Invalid version `%s': %s\n", argv[1], err);
    return 2;
  }
    
  err = parseversion(&ref, argv[3]);
  if (err) {
    fprintf(stderr, "Invalid version `%s': %s\n", argv[3], err);
    return 2;
  }

  return ! versionsatisfied3(&ver, &ref, argv[2]);
}
Beispiel #3
0
int main(int argc, char *argv[]) 
{
  const char *err;
  struct versionrevision ver, ref;

  if (argc < 4) {
    fprintf(stderr, "usage: %s version1 lt|gt|le|ge|eq version2\n       return value 0 if true, else 1\n", argv[0]);
    return 2;
  }

  err = parseversion(&ver, argv[1]);
  if (err) {
    fprintf(stderr, "Invalid version `%s': %s\n", argv[1], err);
    return 2;
  }
    
  err = parseversion(&ref, argv[3]);
  if (err) {
    fprintf(stderr, "Invalid version `%s': %s\n", argv[3], err);
    return 2;
  }

  return ! versionsatisfied3(&ver, &ref, argv[2]);
}
Beispiel #4
0
void add_dependencies(struct pkginfo *dpkg, psys_pkg_t pkg)
{
	struct dependency *dep;
	struct deppossi *depp;

	dep = nfmalloc(sizeof(*dep));
	dep->up = dpkg;
	dep->next = NULL;
	dep->type = dep_depends;

	depp = nfmalloc(sizeof(*depp));
	depp->up = dep;
	depp->next = NULL;
	depp->nextrev = NULL;
	depp->backrev = NULL;
	depp->ed = findpackage("lsb");
	depp->verrel = dvr_laterequal;
	parseversion(&depp->version, psys_pkg_lsbversion(pkg));

	dep->list = depp;
	dpkg->installed.depends = dep;
}
/**
 * Parse a version string coming from a database file.
 *
 * It parses a version string, and prints a warning or an error depending
 * on the parse options.
 *
 * @param ps The parsedb state.
 * @param version The version to parse into.
 * @param value The version string to parse from.
 * @param fmt The error format string.
 */
void
parse_db_version(struct parsedb_state *ps, struct versionrevision *version,
                 const char *value, const char *fmt, ...)
{
  struct dpkg_error err;
  va_list args;
  char buf[1000];

  if (parseversion(version, value, &err) == 0)
    return;

  va_start(args, fmt);
  vsnprintf(buf, sizeof(buf), fmt, args);
  va_end(args);

  if (err.type == DPKG_MSG_WARN && (ps->flags & pdb_lax_parser))
    parse_warn(ps, "%s: %.250s", buf, err.str);
  else
    parse_error(ps, "%s: %.250s", buf, err.str);

  dpkg_error_destroy(&err);
}
Beispiel #6
0
static int do_register(psys_pkg_t pkg, psys_err_t *err, jmp_buf *buf)
{
	int ret;
	char *dpkgname = NULL;
	const char *dpkgarch;
	struct pkginfo *dpkg;
	psys_flist_t flist = NULL;
	char *filelist_path = NULL;
	char *md5list_path = NULL;

	set_error_handler(err, *buf, out);

	dpkgname = dpkg_name(psys_pkg_vendor(pkg), psys_pkg_name(pkg));
	dpkg = findpackage(dpkgname);
	if (ensure_not_installed(dpkg, err)) {
		ret = -1;
		goto out;
	}

	if (ensure_dependencies_met(pkg, err)) {
		ret = -1;
		goto out;
	}

	blankpackage(dpkg);
	blankpackageperfile(&dpkg->installed);

	/* Name, Version */
	dpkg->name = dpkgname;
	parseversion(&dpkg->installed.version, psys_pkg_version(pkg));

	/* Architecture */
	dpkgarch = dpkg_arch(psys_pkg_arch(pkg), err);
	if (!dpkgarch) {
		ret = -1;
		goto out;
	}
	dpkg->installed.architecture = dpkgarch;

	/* Description */
	set_description(dpkg, pkg);

	/* 
	 * Maintainer
	 *
	 * FIXME: Our Maintainer value does not conform to the format
	 * mandated by the Debian Policy Manual (which is "Name <E-Mail>"),
	 * but this is better than not specifying a Maintainer at all
	 * (which is a mandatory field)
	 */
	dpkg->installed.maintainer = nfstrsave(psys_pkg_vendor(pkg));

	/* Priority */
	dpkg->priority = pri_optional;

	/* Dependencies */
	add_dependencies(dpkg, pkg);

	flist = psys_pkg_flist(pkg, err);
	if (!flist) {
		ret = -1;
		goto out;
	}

	/* Installed Size */
	set_installed_size(dpkg, flist);

	/* File List */
	filelist_path = create_file_list(dpkg, flist, err);
	if (!filelist_path) {
		ret = -1;
		goto out;
	}

	/* MD5SUMS List */
	md5list_path = create_md5sums_list(dpkg, flist, err);
	if (!md5list_path) {
		ret = -1;
		goto out;
	}

	dpkg->want = want_install;
	dpkg->status = stat_installed;
	modstatdb_note(dpkg);

	ret = 0;
out:
	if (md5list_path) {
		if (ret == -1)
			remove(md5list_path);
		free(md5list_path);
	}
	if (filelist_path) {
		if (ret == -1)
			remove(filelist_path);
		free(filelist_path);
	}
	if (flist)
		psys_flist_free(flist);
	return ret;
}
Beispiel #7
0
void cmpversions(const char *const *argv) {
  struct relationinfo {
    const char *string;
    /* These values are exit status codes, so 0 = true, 1 = false. */
    int if_lesser, if_equal, if_greater;
    int if_none_a, if_none_both, if_none_b;
  };

  static const struct relationinfo relationinfos[]= {
    /*             < = > !a!2!b  */
    { "le",        0,0,1, 0,0,1  },
    { "lt",        0,1,1, 0,1,1  },
    { "eq",        1,0,1, 1,0,1  },
    { "ne",        0,1,0, 0,1,0  },
    { "ge",        1,0,0, 1,0,0  },
    { "gt",        1,1,0, 1,1,0  },

    /* These treat an empty version as later than any version. */
    { "le-nl",     0,0,1, 1,0,0  },
    { "lt-nl",     0,1,1, 1,1,0  },
    { "ge-nl",     1,0,0, 0,0,1  },
    { "gt-nl",     1,1,0, 0,1,1  },

    /* For compatibility with dpkg control file syntax. */
    { "<",         0,0,1, 0,0,1  },
    { "<=",        0,0,1, 0,0,1  },
    { "<<",        0,1,1, 0,1,1  },
    { "=",         1,0,1, 1,0,1  },
    { ">",         1,0,0, 1,0,0  },
    { ">=",        1,0,0, 1,0,0  },
    { ">>",        1,1,0, 1,1,0  },
    { NULL                       }
  };

  const struct relationinfo *rip;
  const char *emsg;
  struct versionrevision a, b;
  int r;

  if (!argv[0] || !argv[1] || !argv[2] || argv[3])
    badusage(_("--compare-versions takes three arguments:"
             " <version> <relation> <version>"));

  for (rip=relationinfos; rip->string && strcmp(rip->string,argv[1]); rip++);

  if (!rip->string) badusage(_("--compare-versions bad relation"));

  if (*argv[0] && strcmp(argv[0],"<unknown>")) {
    emsg= parseversion(&a,argv[0]);
    if (emsg)
      ohshit(_("version '%s' has bad syntax: %s"), argv[0], emsg);
  } else {
    blankversion(&a);
  }
  if (*argv[2] && strcmp(argv[2],"<unknown>")) {
    emsg= parseversion(&b,argv[2]);
    if (emsg)
      ohshit(_("version '%s' has bad syntax: %s"), argv[2], emsg);
  } else {
    blankversion(&b);
  }
  if (!informativeversion(&a)) {
    exit(informativeversion(&b) ? rip->if_none_a : rip->if_none_both);
  } else if (!informativeversion(&b)) {
    exit(rip->if_none_b);
  }
  r= versioncompare(&a,&b);
  debug(dbg_general,"cmpversions a=`%s' b=`%s' r=%d",
        versiondescribe(&a,vdew_always),
        versiondescribe(&b,vdew_always),
        r);
  if (r>0) exit(rip->if_greater);
  else if (r<0) exit(rip->if_lesser);
  else exit(rip->if_equal);
}
static void
test_version_parse(void)
{
	struct versionrevision a, b;

	/* Test 0 versions. */
	blankversion(&a);
	b = version(0, "0", "");

	test_pass(parseversion(&a, "0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	test_pass(parseversion(&a, "0:0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	test_pass(parseversion(&a, "0:0-") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	b = version(0, "0", "0");
	test_pass(parseversion(&a, "0:0-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	b = version(0, "0.0", "0.0");
	test_pass(parseversion(&a, "0:0.0-0.0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	/* Test epoched versions. */
	b = version(1, "0", "");
	test_pass(parseversion(&a, "1:0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	b = version(5, "1", "");
	test_pass(parseversion(&a, "5:1") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	/* Test multiple dashes. */
	b = version(0, "0-0", "0");
	test_pass(parseversion(&a, "0:0-0-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	b = version(0, "0-0-0", "0");
	test_pass(parseversion(&a, "0:0-0-0-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	/* Test multiple colons. */
	b = version(0, "0:0", "0");
	test_pass(parseversion(&a, "0:0:0-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	b = version(0, "0:0:0", "0");
	test_pass(parseversion(&a, "0:0:0:0-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	/* Test multiple dashes and colons. */
	b = version(0, "0:0-0", "0");
	test_pass(parseversion(&a, "0:0:0-0-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	b = version(0, "0-0:0", "0");
	test_pass(parseversion(&a, "0:0-0:0-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	/* Test valid characters in upstream version. */
	b = version(0, "azAZ09.-+~:", "0");
	test_pass(parseversion(&a, "0:azAZ09.-+~:-0") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	/* Test valid characters in revision. */
	b = version(0, "0", "azAZ09.+~");
	test_pass(parseversion(&a, "0:0-azAZ09.+~") == NULL);
	test_pass(versioncompare(&a, &b) == 0);

	/* Test invalid characters in epoch. */
	test_fail(parseversion(&a, "a:0-0") == NULL);
	test_fail(parseversion(&a, "A:0-0") == NULL);

	/* FIXME: parseversion() should validate input! */
#if 0
	/* Test invalid characters in upstream version. */
	test_fail(parseversion(&a, "0:!#@$%&/|\\<>()[]{};,=*^'-0") == NULL);

	/* Test invalid characters in revision. */
	test_fail(parseversion(&a, "0:0-!#@$%&/|\\<>()[]{};,=*^'") == NULL);
#endif

	/* FIXME: Complete. */
}
Beispiel #9
0
int
cmpversions(const char *const *argv)
{
  struct relationinfo {
    const char *string;
    /* These values are exit status codes, so 0 = true, 1 = false. */
    int if_lesser, if_equal, if_greater;
    int if_none_a, if_none_both, if_none_b;
  };

  static const struct relationinfo relationinfos[]= {
    /*             < = > !a!2!b  */
    { "le",        0,0,1, 0,0,1  },
    { "lt",        0,1,1, 0,1,1  },
    { "eq",        1,0,1, 1,0,1  },
    { "ne",        0,1,0, 0,1,0  },
    { "ge",        1,0,0, 1,0,0  },
    { "gt",        1,1,0, 1,1,0  },

    /* These treat an empty version as later than any version. */
    { "le-nl",     0,0,1, 1,0,0  },
    { "lt-nl",     0,1,1, 1,1,0  },
    { "ge-nl",     1,0,0, 0,0,1  },
    { "gt-nl",     1,1,0, 0,1,1  },

    /* For compatibility with dpkg control file syntax. */
    { "<",         0,0,1, 0,0,1  },
    { "<=",        0,0,1, 0,0,1  },
    { "<<",        0,1,1, 0,1,1  },
    { "=",         1,0,1, 1,0,1  },
    { ">",         1,0,0, 1,0,0  },
    { ">=",        1,0,0, 1,0,0  },
    { ">>",        1,1,0, 1,1,0  },
    { NULL                       }
  };

  const struct relationinfo *rip;
  struct dpkg_version a, b;
  struct dpkg_error err;
  int r;

  if (!argv[0] || !argv[1] || !argv[2] || argv[3])
    badusage(_("--compare-versions takes three arguments:"
             " <version> <relation> <version>"));

  for (rip=relationinfos; rip->string && strcmp(rip->string,argv[1]); rip++);

  if (!rip->string) badusage(_("--compare-versions bad relation"));

  if (*argv[0] && strcmp(argv[0],"<unknown>")) {
    if (parseversion(&a, argv[0], &err) < 0) {
      if (err.type == DPKG_MSG_WARN)
        warning(_("version '%s' has bad syntax: %s"), argv[0], err.str);
      else
        ohshit(_("version '%s' has bad syntax: %s"), argv[0], err.str);
      dpkg_error_destroy(&err);
    }
  } else {
    dpkg_version_blank(&a);
  }
  if (*argv[2] && strcmp(argv[2],"<unknown>")) {
    if (parseversion(&b, argv[2], &err) < 0) {
      if (err.type == DPKG_MSG_WARN)
        warning(_("version '%s' has bad syntax: %s"), argv[2], err.str);
      else
        ohshit(_("version '%s' has bad syntax: %s"), argv[2], err.str);
      dpkg_error_destroy(&err);
    }
  } else {
    dpkg_version_blank(&b);
  }
  if (!dpkg_version_is_informative(&a)) {
    if (dpkg_version_is_informative(&b))
      return rip->if_none_a;
    else
      return rip->if_none_both;
  } else if (!dpkg_version_is_informative(&b)) {
    return rip->if_none_b;
  }
  r = dpkg_version_compare(&a, &b);
  debug(dbg_general,"cmpversions a=`%s' b=`%s' r=%d",
        versiondescribe(&a,vdew_always),
        versiondescribe(&b,vdew_always),
        r);
  if (r > 0)
    return rip->if_greater;
  else if (r < 0)
    return rip->if_lesser;
  else
    return rip->if_equal;
}