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