Imported Upstream version 0.7.27
[platform/upstream/libsolv.git] / examples / solv / repoinfo_config_yum.c
1 #if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <dirent.h>
7 #include <sys/utsname.h>
8
9 #include "pool.h"
10 #include "repo.h"
11 #include "repo_rpmdb.h"
12
13 #include "repoinfo.h"
14 #include "repoinfo_config_yum.h"
15
16
17 #if defined(FEDORA) || defined(MAGEIA)
18 # define REPOINFO_PATH "/etc/yum.repos.d"
19 #endif
20 #ifdef SUSE
21 # define REPOINFO_PATH "/etc/zypp/repos.d"
22 #endif
23
24 static char *
25 find_releaseevr(Pool *pool)
26 {
27 #ifdef SUSE
28   extern char *suse_find_baseproduct_evr(Pool *);
29 #endif
30   void *rpmstate;
31   char *releaseevr = 0;
32   Queue q;
33
34 #ifdef SUSE
35   if ((releaseevr = suse_find_baseproduct_evr(pool)) != 0)
36     return releaseevr;
37 #endif
38   queue_init(&q);
39   rpmstate = rpm_state_create(pool, pool_get_rootdir(pool));
40   rpm_installedrpmdbids(rpmstate, "Providename", "system-release", &q);
41   if (q.count)
42     {
43       void *handle;
44       char *p;
45       handle = rpm_byrpmdbid(rpmstate, q.elements[0]);
46       releaseevr = handle ? rpm_query(handle, SOLVABLE_EVR) : 0;
47       if (releaseevr && (p = strchr(releaseevr, '-')) != 0)
48         *p = 0;
49     }
50   rpm_state_free(rpmstate);
51   queue_free(&q);
52   return releaseevr;
53 }
54
55 char *
56 yum_substitute(Pool *pool, char *line)
57 {
58   char *p, *p2;
59   static char *releaseevr;
60   static char *basearch;
61
62   if (!line)
63     {
64       solv_free(releaseevr);
65       releaseevr = 0;
66       solv_free(basearch);
67       basearch = 0;
68       return 0;
69     }
70   p = line;
71   while ((p2 = strchr(p, '$')) != 0)
72     {
73       if (!strncmp(p2, "$releasever", 11))
74         {
75           if (!releaseevr)
76             {
77               releaseevr = find_releaseevr(pool);
78               if (!releaseevr)
79                 {
80                   fprintf(stderr, "Cannot determine $releasever\n");
81                   exit(1);
82                 }
83               /* we only need the version */
84               if ((p = strchr(releaseevr, '-')) != 0)
85                 *p = 0;
86             }
87           *p2 = 0;
88           p = pool_tmpjoin(pool, line, releaseevr, p2 + 11);
89           p2 = p + (p2 - line);
90           line = p;
91           p = p2 + strlen(releaseevr);
92           continue;
93         }
94       if (!strncmp(p2, "$basearch", 9))
95         {
96           if (!basearch)
97             {
98               struct utsname un;
99               if (uname(&un))
100                 {
101                   perror("uname");
102                   exit(1);
103                 }
104               basearch = strdup(un.machine);
105               if (basearch[0] == 'i' && basearch[1] && !strcmp(basearch + 2, "86"))
106                 basearch[1] = '3';
107             }
108           *p2 = 0;
109           p = pool_tmpjoin(pool, line, basearch, p2 + 9);
110           p2 = p + (p2 - line);
111           line = p;
112           p = p2 + strlen(basearch);
113           continue;
114         }
115       p = p2 + 1;
116     }
117   return line;
118 }
119
120 struct repoinfo *
121 read_repoinfos_yum(Pool *pool, int *nrepoinfosp)
122 {
123   const char *reposdir = REPOINFO_PATH;
124   char buf[4096];
125   char buf2[4096], *kp, *vp, *kpe;
126   DIR *dir;
127   FILE *fp;
128   struct dirent *ent;
129   int l, rdlen;
130   struct repoinfo *repoinfos = 0, *cinfo;
131   int nrepoinfos = 0;
132
133   rdlen = strlen(reposdir);
134   dir = opendir(reposdir);
135   if (!dir)
136     {
137       *nrepoinfosp = 0;
138       return 0;
139     }
140   while ((ent = readdir(dir)) != 0)
141     {
142       if (ent->d_name[0] == '.')
143         continue;
144       l = strlen(ent->d_name);
145       if (l < 6 || rdlen + 2 + l >= sizeof(buf) || strcmp(ent->d_name + l - 5, ".repo") != 0)
146         continue;
147       snprintf(buf, sizeof(buf), "%s/%s", reposdir, ent->d_name);
148       if ((fp = fopen(buf, "r")) == 0)
149         {
150           perror(buf);
151           continue;
152         }
153       cinfo = 0;
154       while(fgets(buf2, sizeof(buf2), fp))
155         {
156           l = strlen(buf2);
157           if (l == 0)
158             continue;
159           while (l && (buf2[l - 1] == '\n' || buf2[l - 1] == ' ' || buf2[l - 1] == '\t'))
160             buf2[--l] = 0;
161           kp = buf2;
162           while (*kp == ' ' || *kp == '\t')
163             kp++;
164           if (!*kp || *kp == '#')
165             continue;
166           if (strchr(kp, '$'))
167             kp = yum_substitute(pool, kp);
168           if (*kp == '[')
169             {
170               vp = strrchr(kp, ']');
171               if (!vp)
172                 continue;
173               *vp = 0;
174               repoinfos = solv_extend(repoinfos, nrepoinfos, 1, sizeof(*repoinfos), 15);
175               cinfo = repoinfos + nrepoinfos++;
176               memset(cinfo, 0, sizeof(*cinfo));
177               cinfo->alias = strdup(kp + 1);
178               cinfo->type = TYPE_RPMMD;
179               cinfo->autorefresh = 1;
180               cinfo->priority = 99;
181 #if !defined(FEDORA) && !defined(MAGEIA)
182               cinfo->repo_gpgcheck = 1;
183 #endif
184               cinfo->metadata_expire = METADATA_EXPIRE;
185               continue;
186             }
187           if (!cinfo)
188             continue;
189           vp = strchr(kp, '=');
190           if (!vp)
191             continue;
192           for (kpe = vp - 1; kpe >= kp; kpe--)
193             if (*kpe != ' ' && *kpe != '\t')
194               break;
195           if (kpe == kp)
196             continue;
197           vp++;
198           while (*vp == ' ' || *vp == '\t')
199             vp++;
200           kpe[1] = 0;
201           if (!strcmp(kp, "name"))
202             cinfo->name = strdup(vp);
203           else if (!strcmp(kp, "enabled"))
204             cinfo->enabled = *vp == '0' ? 0 : 1;
205           else if (!strcmp(kp, "autorefresh"))
206             cinfo->autorefresh = *vp == '0' ? 0 : 1;
207           else if (!strcmp(kp, "gpgcheck"))
208             cinfo->pkgs_gpgcheck = *vp == '0' ? 0 : 1;
209           else if (!strcmp(kp, "repo_gpgcheck"))
210             cinfo->repo_gpgcheck = *vp == '0' ? 0 : 1;
211           else if (!strcmp(kp, "baseurl"))
212             cinfo->baseurl = strdup(vp);
213           else if (!strcmp(kp, "mirrorlist"))
214             {
215               if (strstr(vp, "metalink"))
216                 cinfo->metalink = strdup(vp);
217               else
218                 cinfo->mirrorlist = strdup(vp);
219             }
220           else if (!strcmp(kp, "path"))
221             {
222               if (vp && strcmp(vp, "/") != 0)
223                 cinfo->path = strdup(vp);
224             }
225           else if (!strcmp(kp, "type"))
226             {
227               if (!strcmp(vp, "yast2"))
228                 cinfo->type = TYPE_SUSETAGS;
229               else if (!strcmp(vp, "rpm-md"))
230                 cinfo->type = TYPE_RPMMD;
231               else if (!strcmp(vp, "plaindir"))
232                 cinfo->type = TYPE_PLAINDIR;
233               else if (!strcmp(vp, "mdk"))
234                 cinfo->type = TYPE_MDK;
235               else
236                 cinfo->type = TYPE_UNKNOWN;
237             }
238           else if (!strcmp(kp, "priority"))
239             cinfo->priority = atoi(vp);
240           else if (!strcmp(kp, "keeppackages"))
241             cinfo->keeppackages = *vp == '0' ? 0 : 1;
242         }
243       fclose(fp);
244       cinfo = 0;
245     }
246   closedir(dir);
247   *nrepoinfosp = nrepoinfos;
248   return repoinfos;
249 }
250
251 #endif