Imported Upstream version 0.6.9
[platform/upstream/libsolv.git] / ext / repo_deb.c
index 2e1977b..05d731b 100644 (file)
@@ -17,6 +17,7 @@
 #include "pool.h"
 #include "repo.h"
 #include "util.h"
+#include "solver.h"    /* for GET_USERINSTALLED_ flags */
 #include "chksum.h"
 #include "repo_deb.h"
 
@@ -122,7 +123,14 @@ parseonedep(Pool *pool, char *p)
       while (*p == ' ' || *p == '\t' || *p == '\n')
        p++;
     }
-  name = pool_strn2id(pool, n, ne - n, 1);
+  if (ne - n > 4 && ne[-4] == ':' && !strncmp(ne - 4, ":any", 4))
+    {
+      /* multiarch annotation */
+      name = pool_strn2id(pool, n, ne - n - 4, 1);
+      name = pool_rel2id(pool, name, ARCH_ANY, REL_MULTIARCH, 1);
+    }
+  else
+    name = pool_strn2id(pool, n, ne - n, 1);
   if (e)
     {
       evr = pool_strn2id(pool, e, ee - e, 1);
@@ -197,7 +205,7 @@ control2solvable(Solvable *s, Repodata *data, char *control)
       if (*p)
         *p++ = 0;
       /* strip trailing space */
-      while (end >= control && *end == ' ' && *end == '\t')
+      while (end >= control && (*end == ' ' || *end == '\t'))
        *end-- = 0;
       tag = control;
       control = p;
@@ -274,7 +282,7 @@ control2solvable(Solvable *s, Repodata *data, char *control)
          break;
        case 'R' << 8 | 'E':
          if (!strcasecmp(tag, "replaces"))
-           s->obsoletes = makedeps(repo, q, s->conflicts, 0);
+           s->obsoletes = makedeps(repo, q, s->obsoletes, 0);
          else if (!strcasecmp(tag, "recommends"))
            s->recommends = makedeps(repo, q, s->recommends, 0);
          break;
@@ -306,6 +314,10 @@ control2solvable(Solvable *s, Repodata *data, char *control)
              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);
@@ -329,22 +341,30 @@ control2solvable(Solvable *s, Repodata *data, char *control)
   if (s->obsoletes)
     {
       /* obsoletes only count when the packages also conflict */
+      /* XXX: should not transcode here */
       int i, j, k;
-      Id d;
+      Id d, cid;
       for (i = j = s->obsoletes; (d = repo->idarraydata[i]) != 0; i++)
        {
-         if (s->conflicts)
+         if (!s->conflicts)
+           continue;
+         for (k = s->conflicts; (cid = repo->idarraydata[k]) != 0; k++)
            {
-             for (k = s->conflicts; repo->idarraydata[k] != 0; k++)
-               if (repo->idarraydata[k] == d)
-                 break;
-             if (repo->idarraydata[k])
+             if (repo->idarraydata[k] == cid)
+               break;
+             if (ISRELDEP(cid))
                {
-                 repo->idarraydata[j++] = d;
+                 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;
     }
 }
 
@@ -509,9 +529,9 @@ repo_add_deb(Repo *repo, const char *deb, int flags)
   gotpkgid = 0;
   if (flags & DEBS_ADD_WITH_PKGID)
     {
-      void *handle = solv_chksum_create(REPOKEY_TYPE_MD5);
-      solv_chksum_add(handle, ctgz, clen);
-      solv_chksum_free(handle, pkgid);
+      Chksum *chk = solv_chksum_create(REPOKEY_TYPE_MD5);
+      solv_chksum_add(chk, ctgz, clen);
+      solv_chksum_free(chk, pkgid);
       gotpkgid = 1;
     }
   if (ctgz[0] != 0x1f || ctgz[1] != 0x8b)
@@ -587,7 +607,8 @@ repo_add_deb(Repo *repo, const char *deb, int flags)
   ctar[l2] = 0;
   s = pool_id2solvable(pool, repo_add_solvable(repo));
   control2solvable(s, data, (char *)ctar);
-  repodata_set_location(data, s - pool->solvables, 0, 0, deb);
+  if (!(flags & REPO_NO_LOCATION))
+    repodata_set_location(data, s - pool->solvables, 0, 0, deb);
   if (S_ISREG(stb.st_mode))
     repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned long long)stb.st_size);
   if (gotpkgid)
@@ -597,3 +618,92 @@ repo_add_deb(Repo *repo, const char *deb, int flags)
     repodata_internalize(data);
   return s - pool->solvables;
 }
+
+void
+pool_deb_get_autoinstalled(Pool *pool, FILE *fp, Queue *q, int flags)
+{
+  Id name = 0, arch = 0;
+  int autoinstalled = -1;
+  char *buf, *bp;
+  int x, l, bufl, eof = 0;
+  Id p, pp;
+
+  queue_empty(q);
+  buf = solv_malloc(4096);
+  bufl = 4096;
+  l = 0;
+  while (!eof)
+    {
+      while (bufl - l < 1024)
+       {
+         bufl += 4096;
+         if (bufl > 1024 * 64)
+           break;      /* hmm? */
+         buf = solv_realloc(buf, bufl);
+       }
+      if (!fgets(buf + l, bufl - l, fp))
+       {
+         eof = 1;
+         buf[l] = '\n';
+         buf[l + 1] = 0;
+       }
+      l = strlen(buf);
+      if (l && buf[l - 1] == '\n')
+       buf[--l] = 0;
+      if (!*buf || eof)
+       {
+         l = 0;
+         if (name && autoinstalled > 0)
+           {
+             if ((flags & GET_USERINSTALLED_NAMES) != 0)
+               queue_push(q, name);
+             else
+               {
+                 FOR_PROVIDES(p, pp, name)
+                   {
+                     Solvable *s = pool->solvables + p;
+                     if (s->name != name)
+                       continue;
+                     if (arch && s->arch != arch)
+                       continue;
+                     queue_push(q, p);
+                   }
+               }
+           }
+         name = arch = 0;
+         autoinstalled = -1;
+         continue;
+       }
+      /* strip trailing space */
+      while (l && (buf[l - 1] == ' ' || buf[l - 1] == '\t'))
+       buf[--l] = 0;
+      l = 0;
+
+      bp = strchr(buf, ':');
+      if (!bp || bp - buf < 4)
+       continue;
+      *bp++ = 0;
+      while (*bp == ' ' || *bp == '\t')
+       bp++;
+      x = '@' + (buf[0] & 0x1f);
+      x = (x << 8) + '@' + (buf[1] & 0x1f);
+      switch(x)
+       {
+       case 'P' << 8 | 'A':
+         if (!strcasecmp(buf, "package"))
+           name = pool_str2id(pool, bp, 1);
+         break;
+       case 'A' << 8 | 'R':
+         if (!strcasecmp(buf, "architecture"))
+           arch = pool_str2id(pool, bp, 1);
+         break;
+       case 'A' << 8 | 'U':
+         if (!strcasecmp(buf, "auto-installed"))
+           autoinstalled = atoi(bp);
+         break;
+       default:
+         break;
+       }
+    }
+}
+