2 * Copyright (c) 2013, SUSE Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
20 #include "linkedpkg.h"
22 #ifdef ENABLE_LINKED_PKGS
25 find_application_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Queue *qp)
31 /* find appdata requires */
34 Id *reqp = s->repo->idarraydata + s->requires;
35 while ((req = *reqp++) != 0) /* go through all requires */
39 if (!strncmp("appdata(", pool_id2str(pool, req), 8))
45 /* find application-appdata provides */
48 Id *prvp = s->repo->idarraydata + s->provides;
49 while ((prv = *prvp++) != 0) /* go through all provides */
53 if (strncmp("application-appdata(", pool_id2str(pool, prv), 20))
55 if (!strcmp(pool_id2str(pool, prv) + 12, pool_id2str(pool, req)))
62 FOR_PROVIDES(p, pp, req)
63 if (pool->solvables[p].repo == s->repo)
69 FOR_PROVIDES(p, pp, prv)
70 if (pool->solvables[p].repo == s->repo)
78 find_product_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Queue *qp)
80 Id n = s - pool->solvables;
86 Id buddy = pool->nscallback(pool, pool->nscallbackdata, NAMESPACE_PRODUCTBUDDY, n);
87 if (buddy > 0 && buddy != SYSTEMSOLVABLE && buddy != n && buddy < pool->nsolvables)
90 *reqidp = solvable_selfprovidedep(pool->solvables + buddy);
91 queue_push(qr, buddy);
93 *prvidp = solvable_selfprovidedep(s);
99 /* search for project requires */
103 Id req, *reqp = s->repo->idarraydata + s->requires;
104 const char *nn = pool_id2str(pool, s->name);
105 int nnl = strlen(nn);
106 while ((req = *reqp++) != 0) /* go through all requires */
110 Reldep *rd = GETRELDEP(pool, req);
111 if (rd->flags != REL_EQ || rd->evr != s->evr)
113 rn = pool_id2str(pool, rd->name);
114 if (!strncmp(rn, "product(", 8) && !strncmp(rn + 8, nn + 8, nnl - 8) && !strcmp( rn + nnl, ")"))
123 /* too bad. construct from scratch */
124 str = pool_tmpjoin(pool, pool_id2str(pool, s->name), ")", 0);
126 namerelid = pool_rel2id(pool, pool_str2id(pool, str, 1), s->evr, REL_EQ, 1);
128 FOR_PROVIDES(p, pp, namerelid)
130 Solvable *ps = pool->solvables + p;
131 if (ps->repo != s->repo || ps->arch != s->arch)
135 if (!qr->count && s->repo == pool->installed)
137 /* oh no! Look up reference file */
139 const char *refbasename = solvable_lookup_str(s, PRODUCT_REFERENCEFILE);
140 dataiterator_init(&di, pool, s->repo, 0, SOLVABLE_FILELIST, refbasename, SEARCH_STRING);
141 while (dataiterator_step(&di))
142 queue_push(qr, di.solvid);
143 dataiterator_free(&di);
146 dataiterator_init(&di, pool, s->repo, 0, PRODUCT_REFERENCEFILE, refbasename, SEARCH_STRING);
147 while (dataiterator_step(&di))
148 queue_push(qp, di.solvid);
149 dataiterator_free(&di);
155 FOR_PROVIDES(p, pp, s->name)
157 Solvable *ps = pool->solvables + p;
158 if (s->name != ps->name || ps->repo != s->repo || ps->arch != s->arch || s->evr != ps->evr)
166 *prvidp = solvable_selfprovidedep(s);
170 find_pattern_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Queue *qp)
172 Id p, pp, *pr, apevr = 0, aprel = 0;
174 /* check if autopattern */
177 for (pr = s->repo->idarraydata + s->provides; (p = *pr++) != 0; )
180 Reldep *rd = GETRELDEP(pool, p);
181 if (rd->flags == REL_EQ && !strcmp(pool_id2str(pool, rd->name), "autopattern()"))
190 FOR_PROVIDES(p, pp, apevr)
192 Solvable *s2 = pool->solvables + p;
193 if (s2->repo == s->repo && s2->name == apevr && s2->evr == s->evr && s2->vendor == s->vendor)
198 FOR_PROVIDES(p, pp, aprel)
200 Solvable *s2 = pool->solvables + p;
201 if (s2->repo == s->repo && s2->evr == s->evr && s2->vendor == s->vendor)
212 find_autopattern_name(Pool *pool, Solvable *s)
217 for (prvp = s->repo->idarraydata + s->provides; (prv = *prvp++) != 0; )
220 Reldep *rd = GETRELDEP(pool, prv);
221 if (rd->flags == REL_EQ && !strcmp(pool_id2str(pool, rd->name), "autopattern()"))
222 return strncmp(pool_id2str(pool, rd->evr), "pattern:", 8) != 0 ? rd->evr : 0;
228 find_package_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Queue *qp)
230 const char *name = pool_id2str(pool, s->name);
231 if (name[0] == 'a' && !strncmp("application:", name, 12))
232 find_application_link(pool, s, reqidp, qr, prvidp, qp);
233 else if (name[0] == 'p' && !strncmp("pattern:", name, 7))
234 find_pattern_link(pool, s, reqidp, qr, prvidp, qp);
235 else if (name[0] == 'p' && !strncmp("product:", name, 8))
236 find_product_link(pool, s, reqidp, qr, prvidp, qp);