예제 #1
0
파일: chksum.c 프로젝트: openSUSE/libsolv
const unsigned char *
solv_chksum_get(Chksum *chk, int *lenp)
{
  if (chk->done)
    {
      if (lenp)
        *lenp = solv_chksum_len(chk->type);
      return chk->result;
    }
  switch(chk->type)
    {
    case REPOKEY_TYPE_MD5:
      solv_MD5_Final(chk->result, &chk->c.md5);
      chk->done = 1;
      if (lenp)
	*lenp = 16;
      return chk->result;
    case REPOKEY_TYPE_SHA1:
      solv_SHA1_Final(&chk->c.sha1, chk->result);
      chk->done = 1;
      if (lenp)
	*lenp = 20;
      return chk->result;
    case REPOKEY_TYPE_SHA224:
      solv_SHA224_Final(chk->result, &chk->c.sha224);
      chk->done = 1;
      if (lenp)
	*lenp = 28;
      return chk->result;
    case REPOKEY_TYPE_SHA256:
      solv_SHA256_Final(chk->result, &chk->c.sha256);
      chk->done = 1;
      if (lenp)
	*lenp = 32;
      return chk->result;
    case REPOKEY_TYPE_SHA384:
      solv_SHA384_Final(chk->result, &chk->c.sha384);
      chk->done = 1;
      if (lenp)
	*lenp = 48;
      return chk->result;
    case REPOKEY_TYPE_SHA512:
      solv_SHA512_Final(chk->result, &chk->c.sha512);
      chk->done = 1;
      if (lenp)
	*lenp = 64;
      return chk->result;
    default:
      if (lenp)
	*lenp = 0;
      return 0;
    }
}
예제 #2
0
파일: chksum.c 프로젝트: dmacvicar/libsolv
void *
solv_chksum_create_from_bin(Id type, const unsigned char *buf)
{
    struct ctxhandle *h;
    int l = solv_chksum_len(type);
    if (buf == 0 || l == 0)
        return 0;
    h = solv_calloc(1, sizeof(*h));
    h->type = type;
    h->done = 1;
    memcpy(h->result, buf, l);
    return h;
}
예제 #3
0
파일: chksum.c 프로젝트: openSUSE/libsolv
Chksum *
solv_chksum_create_from_bin(Id type, const unsigned char *buf)
{
  Chksum *chk;
  int l = solv_chksum_len(type);
  if (buf == 0 || l == 0)
    return 0;
  chk = solv_calloc(1, sizeof(*chk));
  chk->type = type;
  chk->done = 1;
  memcpy(chk->result, buf, l);
  return chk;
}
static void
set_checksum(struct parsedata *pd, Repodata *data, Id handle, Id keyname, char *line)
{
  char *sp[3];
  Id type;
  if (split(line, sp, 3) != 2)
    {
      pd->ret = pool_error(pd->pool, -1, "susetags: line %d: bad checksum line '%s'\n", pd->lineno, line);
      return;
    }
  type = solv_chksum_str2type(sp[0]);
  if (!type)
    {
      pd->ret = pool_error(pd->pool, -1, "susetags: line %d: unknown checksum type: '%s'\n", pd->lineno, sp[0]);
      return;
    }
  if (strlen(sp[1]) != 2 * solv_chksum_len(type))
    {
      pd->ret = pool_error(pd->pool, -1, "susetags: line %d: bad checksum length for type %s: '%s'\n", pd->lineno, sp[0], sp[1]);
      return;
    }
  repodata_set_checksum(data, handle, keyname, type, sp[1]);
}
예제 #5
0
파일: chksum.c 프로젝트: dmacvicar/libsolv
const unsigned char *
solv_chksum_get(void *handle, int *lenp)
{
    struct ctxhandle *h = handle;
    if (h->done)
    {
        if (lenp)
            *lenp = solv_chksum_len(h->type);
        return h->result;
    }
    switch(h->type)
    {
    case REPOKEY_TYPE_MD5:
        solv_MD5_Final(h->result, &h->c.md5);
        h->done = 1;
        if (lenp)
            *lenp = 16;
        return h->result;
    case REPOKEY_TYPE_SHA1:
        solv_SHA1_Final(&h->c.sha1, h->result);
        h->done = 1;
        if (lenp)
            *lenp = 20;
        return h->result;
    case REPOKEY_TYPE_SHA256:
        solv_SHA256_Final(h->result, &h->c.sha256);
        h->done = 1;
        if (lenp)
            *lenp = 32;
        return h->result;
    default:
        if (lenp)
            *lenp = 0;
        return 0;
    }
}
예제 #6
0
int
repo_add_content(Repo *repo, FILE *fp, int flags)
{
  Pool *pool = repo->pool;
  char *line, *linep;
  int aline;
  Solvable *s;
  struct parsedata pd;
  Repodata *data;
  Id handle = 0;
  int contentstyle = 0;
  char *descrdir = 0;
  char *datadir = 0;
  char *defvendor = 0;

  int i = 0;
  int res = 0;

  /* architectures
     we use the first architecture in BASEARCHS or noarch
     for the product. At the end we create (clone) the product
     for each one of the remaining architectures
     we allow max 4 archs
  */
  unsigned int numotherarchs = 0;
  Id *otherarchs = 0;

  memset(&pd, 0, sizeof(pd));
  line = solv_malloc(1024);
  aline = 1024;

  pd.repo = repo;
  linep = line;
  s = 0;

  data = repo_add_repodata(repo, flags);

  for (;;)
    {
      char *key, *value;

      /* read line into big-enough buffer */
      if (linep - line + 16 > aline)
	{
	  aline = linep - line;
	  line = solv_realloc(line, aline + 512);
	  linep = line + aline;
	  aline += 512;
	}
      if (!fgets(linep, aline - (linep - line), fp))
	break;
      linep += strlen(linep);
      if (linep == line || linep[-1] != '\n')
        continue;
      while ( --linep > line && ( linep[-1] == ' ' ||  linep[-1] == '\t' ) )
        ; /* skip trailing ws */
      *linep = 0;
      linep = line;

      /* expect "key value" lines */
      value = line;
      key = splitword(&value);

      if (key)
        {
#if 0
	  fprintf (stderr, "key %s, value %s\n", key, value);
#endif

#define istag(x) (!strcmp (key, x))
#define code10 (contentstyle == 10)
#define code11 (contentstyle == 11)


	  if (istag ("CONTENTSTYLE"))
	    {
	      if (contentstyle)
	        pool_debug(pool, SOLV_ERROR, "repo_content: 'CONTENTSTYLE' must be first line of 'content'\n");
	      contentstyle = atoi(value);
	      continue;
	    }
	  if (!contentstyle)
	    contentstyle = 10;

	  /* repository tags */
          /* we also replicate some of them into the product solvables
           * to be backward compatible */

	  if (istag ("REPOID"))
	    {
	      repodata_add_poolstr_array(data, SOLVID_META, REPOSITORY_REPOID, value);
	      continue;
	    }
	  if (istag ("REPOKEYWORDS"))
	    {
	      add_multiple_strings(data, SOLVID_META, REPOSITORY_KEYWORDS, value);
	      continue;
	    }
	  if (istag ("DISTRO"))
	    {
	      Id dh = repodata_new_handle(data);
	      char *p;
	      /* like with createrepo --distro */
	      if ((p = strchr(value, ',')) != 0)
		{
		  *p++ = 0;
		  if (*value)
		    repodata_set_poolstr(data, dh, REPOSITORY_PRODUCT_CPEID, value);
		}
	      else
	        p = value;
	      if (*p)
		repodata_set_str(data, dh, REPOSITORY_PRODUCT_LABEL, p);
	      repodata_add_flexarray(data, SOLVID_META, REPOSITORY_DISTROS, dh);
	      continue;
	    }

	  if (istag ("DESCRDIR"))
	    {
	      if (descrdir)
		free(descrdir);
	      else
	        repodata_set_str(data, SOLVID_META, SUSETAGS_DESCRDIR, value);
	      if (s)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, value);
	      descrdir = solv_strdup(value);
	      continue;
	    }
	  if (istag ("DATADIR"))
	    {
	      if (datadir)
		free(datadir);
	      else
	        repodata_set_str(data, SOLVID_META, SUSETAGS_DATADIR, value);
	      if (s)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, value);
	      datadir = solv_strdup(value);
	      continue;
	    }
	  if (istag ("VENDOR"))
	    {
	      if (defvendor)
		free(defvendor);
	      else
	        repodata_set_poolstr(data, SOLVID_META, SUSETAGS_DEFAULTVENDOR, value);
	      if (s)
		s->vendor = pool_str2id(pool, value, 1);
	      defvendor = solv_strdup(value);
	      continue;
	    }

	  if (istag ("META") || istag ("HASH") || istag ("KEY"))
	    {
	      char *checksumtype, *checksum;
	      Id fh, type;
	      int l;

	      if ((checksumtype = splitword(&value)) == 0)
		continue;
	      if ((checksum = splitword(&value)) == 0)
		continue;
	      if (!*value)
		continue;
	      type = solv_chksum_str2type(checksumtype);
	      if (!type)
		{
		  pool_error(pool, -1, "%s: unknown checksum type '%s'", value, checksumtype);
		  res = 1;
		  continue;
		}
              l = solv_chksum_len(type);
	      if (strlen(checksum) != 2 * l)
	        {
		  pool_error(pool, -1, "%s: invalid checksum length for %s", value, checksumtype);
		  res = 1;
		  continue;
	        }
	      fh = repodata_new_handle(data);
	      repodata_set_poolstr(data, fh, SUSETAGS_FILE_TYPE, key);
	      repodata_set_str(data, fh, SUSETAGS_FILE_NAME, value);
	      repodata_set_checksum(data, fh, SUSETAGS_FILE_CHECKSUM, type, checksum);
	      repodata_add_flexarray(data, SOLVID_META, SUSETAGS_FILE, fh);
	      continue;
	    }

	  /* product tags */

	  if ((code10 && istag ("PRODUCT"))
	      || (code11 && istag ("NAME")))
	    {
	      if (s && !s->name)
		{
		  /* this solvable was created without seeing a
		     PRODUCT entry, just set the name and continue */
		  s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1);
		  continue;
		}
	      if (s)
		{
		  /* finish old solvable */
		  if (!s->arch)
		    s->arch = ARCH_NOARCH;
		  if (!s->evr)
		    s->evr = ID_EMPTY;
		  if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
		    s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
		  if (code10)
		    s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
		}
	      /* create new solvable */
	      s = pool_id2solvable(pool, repo_add_solvable(repo));
	      handle = s - pool->solvables;
	      s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1);
	      if (datadir)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, datadir);
	      if (descrdir)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, descrdir);
	      if (defvendor)
		s->vendor = pool_str2id(pool, defvendor, 1);
	      continue;
	    }

	  /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable
	     from here on.  */
	  if (!s)
	    {
	      s = pool_id2solvable(pool, repo_add_solvable(repo));
	      handle = s - pool->solvables;
	    }

	  if (istag ("VERSION"))
            pd.tmpvers = solv_strdup(value);
          else if (istag ("RELEASE"))
            pd.tmprel = solv_strdup(value);
	  else if (code11 && istag ("DISTRIBUTION"))
	    repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
	  else if (istag ("UPDATEURLS"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "update", 1));
	  else if (istag ("EXTRAURLS"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "extra", 1));
	  else if (istag ("OPTIONALURLS"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "optional", 1));
	  else if (istag ("RELNOTESURL"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "releasenotes", 1));
	  else if (istag ("SHORTLABEL"))
	    repodata_set_str(data, s - pool->solvables, PRODUCT_SHORTLABEL, value);
	  else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
	    repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, value);
	  else if (!strncmp (key, "LABEL.", 6))
	    repodata_set_str(data, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
	  else if (istag ("FLAGS"))
	    add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
	  else if (istag ("VENDOR"))	/* actually already handled above */
	    s->vendor = pool_str2id(pool, value, 1);
          else if (istag ("BASEARCHS"))
            {
              char *arch;

	      if ((arch = splitword(&value)) != 0)
		{
		  s->arch = pool_str2id(pool, arch, 1);
		  while ((arch = splitword(&value)) != 0)
		    {
		       otherarchs = solv_extend(otherarchs, numotherarchs, 1, sizeof(Id), 7);
		       otherarchs[numotherarchs++] = pool_str2id(pool, arch, 1);
		    }
		}
            }
	  if (!code10)
	    continue;

	  /*
	   * Every tag below is Code10 only
	   *
	   */

	  if (istag ("ARCH"))
	    /* Theoretically we want to have the best arch of the given
	       modifiers which still is compatible with the system
	       arch.  We don't know the latter here, though.  */
	    s->arch = ARCH_NOARCH;
	  else if (istag ("PREREQUIRES"))
	    s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
	  else if (istag ("REQUIRES"))
	    s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
	  else if (istag ("PROVIDES"))
	    s->provides = adddep(pool, &pd, s->provides, value, 0);
	  else if (istag ("CONFLICTS"))
	    s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
	  else if (istag ("OBSOLETES"))
	    s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
	  else if (istag ("RECOMMENDS"))
	    s->recommends = adddep(pool, &pd, s->recommends, value, 0);
	  else if (istag ("SUGGESTS"))
	    s->suggests = adddep(pool, &pd, s->suggests, value, 0);
	  else if (istag ("SUPPLEMENTS"))
	    s->supplements = adddep(pool, &pd, s->supplements, value, 0);
	  else if (istag ("ENHANCES"))
	    s->enhances = adddep(pool, &pd, s->enhances, value, 0);
	  /* FRESHENS doesn't seem to exist.  */
	  else if (istag ("TYPE"))
	    repodata_set_str(data, s - pool->solvables, PRODUCT_TYPE, value);

	  /* XXX do something about LINGUAS and ARCH?
          * <ma>: Don't think so. zypp does not use or propagate them.
          */
#undef istag
	}
      else
	pool_debug(pool, SOLV_ERROR, "repo_content: malformed line: %s\n", line);
    }

  if (datadir)
    free(datadir);
  if (descrdir)
    free(descrdir);
  if (defvendor)
    free(defvendor);

  if (s && !s->name)
    {
      pool_debug(pool, SOLV_ERROR, "repo_content: 'content' incomplete, no product solvable created!\n");
      repo_free_solvable(repo, s - pool->solvables, 1);
      s = 0;
    }
  if (s)
    {
      if (pd.tmprel)
	s->evr = makeevr(pool, join(&pd, pd.tmpvers, "-", pd.tmprel));
      else
	s->evr = makeevr(pool, pd.tmpvers);
      pd.tmpvers = solv_free((void *)pd.tmpvers);
      pd.tmprel = solv_free((void *)pd.tmprel);

      if (!s->arch)
	s->arch = ARCH_NOARCH;
      if (!s->evr)
	s->evr = ID_EMPTY;
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
        s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      if (code10)
	s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);

      /* now for every other arch, clone the product except the architecture */
      for (i = 0; i < numotherarchs; ++i)
	{
	  Solvable *p = pool_id2solvable(pool, repo_add_solvable(repo));
	  p->name = s->name;
	  p->evr = s->evr;
	  p->vendor = s->vendor;
	  p->arch = otherarchs[i];

	  /* self provides */
	  if (s->name && p->arch != ARCH_SRC && p->arch != ARCH_NOSRC)
	      p->provides = repo_addid_dep(repo, p->provides, pool_rel2id(pool, p->name, p->evr, REL_EQ, 1), 0);

	  /* now merge the attributes */
	  repodata_merge_attrs(data, p - pool->solvables, s - pool->solvables);
	}
    }

  if (pd.tmp)
    solv_free(pd.tmp);
  solv_free(line);
  solv_free(otherarchs);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return res;
}
예제 #7
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  //fprintf(stderr,"-tag: %s\n", name);
  struct parsedata *pd = userData;
  Pool *pool = pd->common.pool;
  Solvable *s = pd->solvable;
  Repo *repo = pd->common.repo;
  Id handle = pd->handle;
  Id id;
  char *p;

  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
      // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
      return;
    }

  /* ignore patterns & metadata */
  if (pd->state == STATE_START && !strcmp(name, "patterns"))
    return;
  if (pd->state == STATE_START && !strcmp(name, "products"))
    return;
  //if (pd->state == STATE_START && !strcmp(name, "metadata"))
  //  return;
  if (pd->state == STATE_SOLVABLE && !strcmp(name, "format"))
    return;

  pd->depth--;
  pd->statedepth--;
  switch (pd->state)
    {
    case STATE_SOLVABLE:
      if (pd->kind && !s->name) /* add namespace in case of NULL name */
        s->name = pool_str2id(pool, join2(pd->kind, ":", ""), 1);
      if (!s->arch)
        s->arch = ARCH_NOARCH;
      if (!s->evr)
        s->evr = ID_EMPTY;	/* some patterns have this */
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
        s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, pd->freshens);
      s->conflicts = repo_fix_conflicts(repo, s->conflicts);
      pd->freshens = 0;
      pd->kind = 0;
      break;
    case STATE_NAME:
      if (pd->kind)
        s->name = pool_str2id(pool, join2(pd->kind, ":", pd->content), 1);
      else
        s->name = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_ARCH:
      s->arch = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_RPM_GROUP:
      repodata_set_poolstr(pd->data, handle, SOLVABLE_GROUP, pd->content);
      break;
    case STATE_RPM_LICENSE:
      repodata_set_poolstr(pd->data, handle, SOLVABLE_LICENSE, pd->content);
      break;
    case STATE_CHECKSUM:
      {
        Id type, index;
	type = solv_chksum_str2type(pd->tmpattr);
	if (!type)
	  {
            fprintf(stderr, "Unknown checksum type: %d: %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
            exit(1);
	  }
        if (strlen(pd->content) != 2 * solv_chksum_len(type))
          {
            fprintf(stderr, "Invalid checksum length: %d: for %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
            exit(1);
          }
        repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, type, pd->content);
        /* we save the checksum to solvable id relationship for extended
           metadata */
        index = stringpool_str2id(&pd->cspool, pd->content, 1 /* create it */);
        if (index >= pd->ncscache)
          {
            pd->cscache = solv_zextend(pd->cscache, pd->ncscache, index + 1 - pd->ncscache, sizeof(Id), 255);
            pd->ncscache = index + 1;
          }
        /* add the checksum to the cache */
        pd->cscache[index] = s - pool->solvables;
        break;
      }
    case STATE_FILE:
#if 0
      id = pool_str2id(pool, pd->content, 1);
      s->provides = repo_addid_dep(repo, s->provides, id, SOLVABLE_FILEMARKER);
#endif
      if ((p = strrchr(pd->content, '/')) != 0)
	{
	  *p++ = 0;
	  if (pd->lastdir && !strcmp(pd->lastdirstr, pd->content))
	    {
	      id = pd->lastdir;
	    }
	  else
	    {
	      int l;
	      id = repodata_str2dir(pd->data, pd->content, 1);
	      l = strlen(pd->content) + 1;
	      if (l > pd->lastdirstrl)
		{
		  pd->lastdirstrl = l + 128;
		  pd->lastdirstr = solv_realloc(pd->lastdirstr, pd->lastdirstrl);
		}
	      strcpy(pd->lastdirstr, pd->content);
	      pd->lastdir = id;
	    }
	}
      else
	{
	  p = pd->content;
	  id = 0;
	}
      if (!id)
	id = repodata_str2dir(pd->data, "/", 1);
      repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, id, p);
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content);
      break;
    case STATE_DESCRIPTION:
      set_description_author(pd->data, handle, pd->content, pd);
      break;
    case STATE_CATEGORY:
      repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_CATEGORY, pd->tmplang), pd->content);
      break;
    case STATE_DISTRIBUTION:
        repodata_set_poolstr(pd->data, handle, SOLVABLE_DISTRIBUTION, pd->content);
        break;
    case STATE_URL:
      if (pd->content[0])
	repodata_set_str(pd->data, handle, SOLVABLE_URL, pd->content);
      break;
    case STATE_PACKAGER:
      if (pd->content[0])
	repodata_set_poolstr(pd->data, handle, SOLVABLE_PACKAGER, pd->content);
      break;
    case STATE_SOURCERPM:
      set_sourcerpm(pd->data, s, handle, pd->content);
      break;
    case STATE_RELNOTESURL:
      if (pd->content[0])
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pool_str2id(pool, "releasenotes", 1));
        }
      break;
    case STATE_UPDATEURL:
      if (pd->content[0])
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pool_str2id(pool, "update", 1));
        }
      break;
    case STATE_OPTIONALURL:
      if (pd->content[0])
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pool_str2id(pool, "optional", 1));
        }
      break;
    case STATE_FLAG:
      if (pd->content[0])
          repodata_set_poolstr(pd->data, handle, PRODUCT_FLAGS, pd->content);
      break;
    case STATE_EULA:
      if (pd->content[0])
	repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_EULA, pd->tmplang), pd->content);
      break;
    case STATE_KEYWORD:
      if (pd->content[0])
        repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_KEYWORDS, pd->content);
      break;
    case STATE_DISKUSAGE:
      if (pd->ndirs)
        commit_diskusage(pd, pd->handle);
      break;
    case STATE_ORDER:
      if (pd->content[0])
        repodata_set_str(pd->data, pd->handle, SOLVABLE_ORDER, pd->content);
    default:
      break;
    }
  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;
  // fprintf(stderr, "back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth);
}
예제 #8
0
int
repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags)
{
  Pool *pool = repo->pool;
  struct parsedata pd;
  char buf[BUFF_SIZE];
  int i, l;
  struct stateswitch *sw;
  Repodata *data;
  unsigned int now;
  XML_Parser parser;

  now = solv_timems(0);
  data = repo_add_repodata(repo, flags);

  memset(&pd, 0, sizeof(pd));
  for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
    {
      if (!pd.swtab[sw->from])
        pd.swtab[sw->from] = sw;
      pd.sbtab[sw->to] = sw->from;
    }
  pd.common.pool = pool;
  pd.common.repo = repo;

  pd.data = data;

  pd.content = solv_malloc(256);
  pd.acontent = 256;
  pd.lcontent = 0;
  pd.common.tmp = 0;
  pd.common.tmpl = 0;
  pd.kind = 0;
  pd.language = language;

  /* initialize the string pool where we will store
     the package checksums we know about, to get an Id
     we can use in a cache */
  stringpool_init_empty(&pd.cspool);
  if ((flags & REPO_EXTEND_SOLVABLES) != 0)
    {
      /* setup join data */
      Dataiterator di;
      dataiterator_init(&di, pool, repo, 0, SOLVABLE_CHECKSUM, 0, 0);
      while (dataiterator_step(&di))
	{
	  const char *str;
	  int index;

	  if (!solv_chksum_len(di.key->type))
	    continue;
	  str = repodata_chk2str(di.data, di.key->type, (const unsigned char *)di.kv.str);
          index = stringpool_str2id(&pd.cspool, str, 1);
	  if (index >= pd.ncscache)
	    {
	      pd.cscache = solv_zextend(pd.cscache, pd.ncscache, index + 1 - pd.ncscache, sizeof(Id), 255);
	      pd.ncscache = index + 1;
	    }
          pd.cscache[index] = di.solvid;
	}
      dataiterator_free(&di);
    }

  parser = XML_ParserCreate(NULL);
  XML_SetUserData(parser, &pd);
  pd.parser = &parser;
  XML_SetElementHandler(parser, startElement, endElement);
  XML_SetCharacterDataHandler(parser, characterData);
  for (;;)
    {
      l = fread(buf, 1, sizeof(buf), fp);
      if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
	{
	  pool_debug(pool, SOLV_FATAL, "repo_rpmmd: %s at line %u:%u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
	  exit(1);
	}
      if (l == 0)
	break;
    }
  XML_ParserFree(parser);
  solv_free(pd.content);
  solv_free(pd.lastdirstr);
  join_freemem();
  stringpool_free(&pd.cspool);
  solv_free(pd.cscache);

  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  POOL_DEBUG(SOLV_DEBUG_STATS, "repo_add_rpmmd took %d ms\n", solv_timems(now));
  POOL_DEBUG(SOLV_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
  POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
  return 0;
}
예제 #9
0
/* warning: does inplace changes */
static void
control2solvable(Solvable *s, Repodata *data, char *control)
{
  Repo *repo = s->repo;
  Pool *pool = repo->pool;
  char *p, *q, *end, *tag;
  int x, l;
  int havesource = 0;
  char checksum[32 * 2 + 1];
  Id checksumtype = 0;
  Id newtype;

  p = control;
  while (*p)
    {
      p = strchr(p, '\n');
      if (!p)
	break;
      if (p[1] == ' ' || p[1] == '\t')
	{
	  char *q;
	  /* continuation line */
	  q = p - 1;
	  while (q >= control && *q == ' ' && *q == '\t')
	    q--;
	  l = q + 1 - control;
	  if (l)
	    memmove(p + 1 - l, control, l);
	  control = p + 1 - l;
	  p[1] = '\n';
	  p += 2;
	  continue;
	}
      end = p - 1;
      if (*p)
        *p++ = 0;
      /* strip trailing space */
      while (end >= control && (*end == ' ' || *end == '\t'))
	*end-- = 0;
      tag = control;
      control = p;
      q = strchr(tag, ':');
      if (!q || q - tag < 4)
	continue;
      *q++ = 0;
      while (*q == ' ' || *q == '\t')
	q++;
      x = '@' + (tag[0] & 0x1f);
      x = (x << 8) + '@' + (tag[1] & 0x1f);
      switch(x)
	{
	case 'A' << 8 | 'R':
	  if (!strcasecmp(tag, "architecture"))
	    s->arch = pool_str2id(pool, q, 1);
	  break;
	case 'B' << 8 | 'R':
	  if (!strcasecmp(tag, "breaks"))
	    s->conflicts = makedeps(repo, q, s->conflicts, 0);
	  break;
	case 'C' << 8 | 'O':
	  if (!strcasecmp(tag, "conflicts"))
	    s->conflicts = makedeps(repo, q, s->conflicts, 0);
	  break;
	case 'D' << 8 | 'E':
	  if (!strcasecmp(tag, "depends"))
	    s->requires = makedeps(repo, q, s->requires, -SOLVABLE_PREREQMARKER);
	  else if (!strcasecmp(tag, "description"))
	    {
	      char *ld = strchr(q, '\n');
	      if (ld)
		{
		  *ld++ = 0;
	          repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, ld);
		}
	      else
	        repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, q);
	      repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, q);
	    }
	  break;
	case 'E' << 8 | 'N':
	  if (!strcasecmp(tag, "enhances"))
	    s->enhances = makedeps(repo, q, s->enhances, 0);
	  break;
	case 'F' << 8 | 'I':
	  if (!strcasecmp(tag, "filename"))
	    repodata_set_location(data, s - pool->solvables, 0, 0, q);
	  break;
	case 'H' << 8 | 'O':
	  if (!strcasecmp(tag, "homepage"))
	    repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, q);
	  break;
	case 'I' << 8 | 'N':
	  if (!strcasecmp(tag, "installed-size"))
	    repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(q, 0, 10) << 10);
	  break;
	case 'M' << 8 | 'D':
	  if (!strcasecmp(tag, "md5sum") && !checksumtype && strlen(q) == 16 * 2)
	    {
	      strcpy(checksum, q);
	      checksumtype = REPOKEY_TYPE_MD5;
	    }
	  break;
	case 'P' << 8 | 'A':
	  if (!strcasecmp(tag, "package"))
	    s->name = pool_str2id(pool, q, 1);
	  break;
	case 'P' << 8 | 'R':
	  if (!strcasecmp(tag, "pre-depends"))
	    s->requires = makedeps(repo, q, s->requires, SOLVABLE_PREREQMARKER);
	  else if (!strcasecmp(tag, "provides"))
	    s->provides = makedeps(repo, q, s->provides, 0);
	  break;
	case 'R' << 8 | 'E':
	  if (!strcasecmp(tag, "replaces"))
	    s->obsoletes = makedeps(repo, q, s->obsoletes, 0);
	  else if (!strcasecmp(tag, "recommends"))
	    s->recommends = makedeps(repo, q, s->recommends, 0);
	  break;
	case 'S' << 8 | 'H':
	  newtype = solv_chksum_str2type(tag);
	  if (!newtype || solv_chksum_len(newtype) * 2 != strlen(q))
	    break;
	  if (!checksumtype || (newtype == REPOKEY_TYPE_SHA1 && checksumtype != REPOKEY_TYPE_SHA256) || newtype == REPOKEY_TYPE_SHA256)
	    {
	      strcpy(checksum, q);
	      checksumtype = newtype;
	    }
	  break;
	case 'S' << 8 | 'O':
	  if (!strcasecmp(tag, "source"))
	    {
	      char *q2;
	      /* ignore version for now */
	      for (q2 = q; *q2; q2++)
		if (*q2 == ' ' || *q2 == '\t')
		  {
		    *q2 = 0;
		    break;
		  }
	      if (s->name && !strcmp(q, pool_id2str(pool, s->name)))
		repodata_set_void(data, s - pool->solvables, SOLVABLE_SOURCENAME);
	      else
		repodata_set_id(data, s - pool->solvables, SOLVABLE_SOURCENAME, pool_str2id(pool, q, 1));
	      havesource = 1;
	    }
	  break;
	case 'S' << 8 | 'T':
	  if (!strcasecmp(tag, "status"))
	    repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_INSTALLSTATUS, q);
	  break;
	case 'S' << 8 | 'U':
	  if (!strcasecmp(tag, "suggests"))
	    s->suggests = makedeps(repo, q, s->suggests, 0);
	  break;
	case 'V' << 8 | 'E':
	  if (!strcasecmp(tag, "version"))
	    s->evr = pool_str2id(pool, q, 1);
	  break;
	}
    }
  if (checksumtype)
    repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, checksumtype, checksum);
  if (!s->arch)
    s->arch = ARCH_ALL;
  if (!s->evr)
    s->evr = ID_EMPTY;
  if (s->name)
    s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
  if (s->name && !havesource)
    repodata_set_void(data, s - pool->solvables, SOLVABLE_SOURCENAME);
  if (s->obsoletes)
    {
      /* obsoletes only count when the packages also conflict */
      /* XXX: should not transcode here */
      int i, j, k;
      Id d, cid;
      for (i = j = s->obsoletes; (d = repo->idarraydata[i]) != 0; i++)
	{
	  if (!s->conflicts)
	    continue;
	  for (k = s->conflicts; (cid = repo->idarraydata[k]) != 0; k++)
	    {
	      if (repo->idarraydata[k] == cid)
		break;
	      if (ISRELDEP(cid))
		{
		  Reldep *rd = GETRELDEP(pool, cid);
		  if (rd->flags < 8 && rd->name == d)
		    break;	/* specialize obsoletes */
		}
	    }
	  if (cid)
	    repo->idarraydata[j++] = cid;
	}
      repo->idarraydata[j] = 0;
      if (j == s->obsoletes)
	s->obsoletes = 0;
    }
}
예제 #10
0
const char *
repo_lookup_checksum(Repo *repo, Id entry, Id keyname, Id *typep)
{
  const unsigned char *chk = repo_lookup_bin_checksum(repo, entry, keyname, typep);
  return chk ? pool_bin2hex(repo->pool, chk, solv_chksum_len(*typep)) : 0;
}
예제 #11
0
파일: dumpsolv.c 프로젝트: openSUSE/libsolv
static int
dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
{
  const char *keyname;
  KeyValue *kvp;
  int indent = 0;

  keyname = pool_id2str(repo->pool, key->name);
  for (kvp = kv; (kvp = kvp->parent) != 0; indent += 2)
    printf("  ");
  switch(key->type)
    {
    case REPOKEY_TYPE_ID:
      if (data && data->localpool)
	kv->str = stringpool_id2str(&data->spool, kv->id);
      else
	kv->str = pool_dep2str(repo->pool, kv->id);
      printf("%s: %s\n", keyname, kv->str);
      break;
    case REPOKEY_TYPE_CONSTANTID:
      printf("%s: %s\n", keyname, pool_dep2str(repo->pool, kv->id));
      break;
    case REPOKEY_TYPE_IDARRAY:
      if (!kv->entry)
        printf("%s:\n%*s", keyname, indent, "");
      if (data && data->localpool)
        printf("  %s\n", stringpool_id2str(&data->spool, kv->id));
      else
        printf("  %s\n", pool_dep2str(repo->pool, kv->id));
      break;
    case REPOKEY_TYPE_STR:
      printf("%s: %s\n", keyname, kv->str);
      break;
    case REPOKEY_TYPE_VOID:
      printf("%s: (void)\n", keyname);
      break;
    case REPOKEY_TYPE_CONSTANT:
      printf("%s: %u\n", keyname, kv->num);
      break;
    case REPOKEY_TYPE_NUM:
      printf("%s: %llu\n", keyname, SOLV_KV_NUM64(kv));
      break;
    case REPOKEY_TYPE_BINARY:
      if (kv->num)
        printf("%s: %02x..%02x len %u\n", keyname, (unsigned char)kv->str[0], (unsigned char)kv->str[kv->num - 1], kv->num);
      else
        printf("%s: len 0\n", keyname);
      break;
    case REPOKEY_TYPE_DIRNUMNUMARRAY:
      if (!kv->entry)
        printf("%s:\n%*s", keyname, indent, "");
      printf("  %s %u %u\n", repodata_dir2str(data, kv->id, 0), kv->num, kv->num2);
      break;
    case REPOKEY_TYPE_DIRSTRARRAY:
      if (!kv->entry)
        printf("%s:\n%*s", keyname, indent, "");
      printf("  %s\n", repodata_dir2str(data, kv->id, kv->str));
      break;
    case REPOKEY_TYPE_FIXARRAY:
    case REPOKEY_TYPE_FLEXARRAY:
      if (!kv->entry)
        printf("%s:\n", keyname);
      else
        printf("\n");
      break;
    default:
      if (solv_chksum_len(key->type))
	{
	  printf("%s: %s (%s)\n", keyname, repodata_chk2str(data, key->type, (unsigned char *)kv->str), solv_chksum_type2str(key->type));
	  break;
	}
      printf("%s: ?\n", keyname);
      break;
    }
  return 0;
}
예제 #12
0
파일: dumpsolv.c 프로젝트: openSUSE/libsolv
static int
dump_attr_json(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv, struct cbdata *cbdata)
{
  Pool *pool = repo->pool;
  const char *keyname;
  KeyValue *kvp;
  int indent = cbdata->baseindent;
  int isarray = 0;
  const char *str;
  int depth = 0;

  keyname = pool_id2str(repo->pool, key->name);
  for (kvp = kv; (kvp = kvp->parent) != 0; indent += 4)
    depth++;
  if (cbdata->nfirst < depth + 1)
    {
      cbdata->first = solv_realloc(cbdata->first, depth + 16);
      memset(cbdata->first + cbdata->nfirst, 0, depth + 16 - cbdata->nfirst);
      cbdata->nfirst = depth + 16;
    }
  switch(key->type)
    {
    case REPOKEY_TYPE_IDARRAY:
    case REPOKEY_TYPE_DIRNUMNUMARRAY:
    case REPOKEY_TYPE_DIRSTRARRAY:
      isarray = 1;
      break;
    case REPOKEY_TYPE_FIXARRAY:
    case REPOKEY_TYPE_FLEXARRAY:
      isarray = 2;
      break;
    default:
      break;
    }
  if (!isarray || !kv->entry)
    {
      if (cbdata->first[depth])
	printf(",\n");
      printf("%*s%s: ", indent, "", jsonstring(pool, keyname));
      cbdata->first[depth] = 1;
    }
  if (isarray == 1 && !kv->entry)
    printf("[\n%*s", indent + 2, "");
  else if (isarray == 1 && kv->entry)
    printf("%*s", indent + 2, "");
  switch(key->type)
    {
    case REPOKEY_TYPE_ID:
      if (data && data->localpool)
	str = stringpool_id2str(&data->spool, kv->id);
      else
	str = pool_dep2str(repo->pool, kv->id);
      printf("%s", jsonstring(pool, str));
      break;
    case REPOKEY_TYPE_CONSTANTID:
      str = pool_dep2str(repo->pool, kv->id);
      printf("%s", jsonstring(pool, str));
      break;
    case REPOKEY_TYPE_IDARRAY:
      if (data && data->localpool)
        str = stringpool_id2str(&data->spool, kv->id);
      else
        str = pool_dep2str(repo->pool, kv->id);
      printf("%s", jsonstring(pool, str));
      break;
    case REPOKEY_TYPE_STR:
      str = kv->str;
      printf("%s", jsonstring(pool, str));
      break;
    case REPOKEY_TYPE_VOID:
      printf("null");
      break;
    case REPOKEY_TYPE_CONSTANT:
      printf("%u", kv->num);
      break;
    case REPOKEY_TYPE_NUM:
      printf("%llu", SOLV_KV_NUM64(kv));
      break;
    case REPOKEY_TYPE_BINARY:
      printf("\"<binary>\"");
      break;
    case REPOKEY_TYPE_DIRNUMNUMARRAY:
      printf("{\n");
      printf("%*s    \"dir\": %s,\n", indent, "", jsonstring(pool, repodata_dir2str(data, kv->id, 0)));
      printf("%*s    \"num1\": %u,\n", indent, "", kv->num);
      printf("%*s    \"num2\": %u\n", indent, "", kv->num2);
      printf("%*s  }", indent, "");
      break;
    case REPOKEY_TYPE_DIRSTRARRAY:
      printf("%s", jsonstring(pool, repodata_dir2str(data, kv->id, kv->str)));
      break;
    case REPOKEY_TYPE_FIXARRAY:
    case REPOKEY_TYPE_FLEXARRAY:
      cbdata->first[depth + 1] = 0;
      if (!kv->entry)
	printf("[\n");
      else
	{
	  if (kv->eof != 2)
            printf("\n%*s  },\n", indent, "");
	  else
            printf("\n%*s  }\n", indent, "");
	}
      if (kv->eof != 2)
        printf("%*s  {\n", indent, "");
      else
        printf("%*s]", indent, "");
      break;
    default:
      if (solv_chksum_len(key->type))
	{
	  printf("{\n");
	  printf("%*s  \"value\": %s,\n", indent, "", jsonstring(pool, repodata_chk2str(data, key->type, (unsigned char *)kv->str)));
	  printf("%*s  \"type\": %s\n", indent, "", jsonstring(pool, solv_chksum_type2str(key->type)));
	  printf("%*s}", indent, "");
	  break;
	}
      printf("\"?\"");
      break;
    }
  if (isarray == 1)
    {
      if (!kv->eof)
        printf(",\n");
      else
        printf("\n%*s]", indent, "");
    }
  return 0;
}