Imported Upstream version 0.6.23
[platform/upstream/libsolv.git] / examples / solv / repoinfo_system_rpm.c
1 #if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA) || defined(MANDRIVA) || defined(MAGEIA))
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <sys/types.h>
8 #include <sys/wait.h>
9 #include <sys/stat.h>
10
11 #include "pool.h"
12 #include "repo.h"
13 #include "repo_rpmdb.h"
14 #if defined(ENABLE_SUSEREPO) && defined(SUSE)
15 #include "repo_products.h"
16 #endif
17 #if defined(ENABLE_APPDATA)
18 #include "repo_appdata.h"
19 #endif
20 #include "transaction.h"
21
22 #include "repoinfo.h"
23 #include "repoinfo_cache.h"
24 #include "repoinfo_system_rpm.h"
25
26 #ifdef SUSE
27 # define PRODUCTS_PATH "/etc/products.d"
28 #endif
29 #ifdef ENABLE_APPDATA
30 # define APPDATA_PATH "/usr/share/metainfo"
31 # define APPDATA_LEGACY_PATH "/usr/share/appdata"
32 #endif
33
34 static void
35 runrpm(const char *arg, const char *name, int dupfd3, const char *rootdir)
36 {
37   pid_t pid;
38   int status;
39
40   if ((pid = fork()) == (pid_t)-1)
41     {
42       perror("fork");
43       exit(1);
44     }
45   if (pid == 0)
46     {
47       if (!rootdir)
48         rootdir = "/";
49       if (dupfd3 != -1 && dupfd3 != 3)
50         {
51           dup2(dupfd3, 3);
52           close(dupfd3);
53         }
54       if (dupfd3 != -1)
55         fcntl(3, F_SETFD, 0);   /* clear CLOEXEC */
56       if (strcmp(arg, "-e") == 0)
57         execlp("rpm", "rpm", arg, "--nodeps", "--nodigest", "--nosignature", "--root", rootdir, name, (char *)0);
58       else
59         execlp("rpm", "rpm", arg, "--force", "--nodeps", "--nodigest", "--nosignature", "--root", rootdir, name, (char *)0);
60       perror("rpm");
61       _exit(0);
62     }
63   while (waitpid(pid, &status, 0) != pid)
64     ;
65   if (status)
66     {
67       printf("rpm failed\n");
68       exit(1);
69     }
70 }
71
72 int
73 read_installed_rpm(struct repoinfo *cinfo)
74 {
75   Repo *repo = cinfo->repo;
76   Pool *pool = repo->pool;
77   FILE *ofp = 0;
78   struct stat stb;
79
80   memset(&stb, 0, sizeof(stb));
81   printf("rpm database:");
82   if (stat(pool_prepend_rootdir_tmp(pool, "/var/lib/rpm/Packages"), &stb))
83     memset(&stb, 0, sizeof(stb));
84   calc_cookie_stat(&stb, REPOKEY_TYPE_SHA256, 0, cinfo->cookie);
85   cinfo->cookieset = 1;
86   if (usecachedrepo(cinfo, 0, 0))
87     {
88       printf(" cached\n");
89       return 1;
90     }
91   printf(" reading\n");
92 #if defined(ENABLE_SUSEREPO) && defined(PRODUCTS_PATH)
93   if (repo_add_products(repo, PRODUCTS_PATH, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR))
94     {
95       fprintf(stderr, "product reading failed: %s\n", pool_errstr(pool));
96       return 0;
97     }
98 #endif
99 #if defined(ENABLE_APPDATA) && defined(APPDATA_PATH)
100   if (repo_add_appdata_dir(repo, APPDATA_PATH, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR))
101     {
102       fprintf(stderr, "appdata reading failed: %s\n", pool_errstr(pool));
103       return 0;
104     }
105 #elif defined(ENABLE_APPDATA) && defined(APPDATA_LEGACY_PATH)
106   if (repo_add_appdata_dir(repo, APPDATA_LEGACY_PATH, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR))
107     {
108       fprintf(stderr, "appdata reading from legacy dir failed: %s\n", pool_errstr(pool));
109       return 0;
110     }
111 #endif
112   ofp = fopen(calc_cachepath(repo, 0, 0), "r");
113   if (repo_add_rpmdb_reffp(repo, ofp, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR))
114     {
115       fprintf(stderr, "installed db: %s\n", pool_errstr(pool));
116       return 0;
117     }
118   if (ofp)
119     fclose(ofp);
120   repo_internalize(repo);
121   writecachedrepo(cinfo, 0, 0);
122   return 1;
123 }
124
125 void
126 commit_transactionelement_rpm(Pool *pool, Id type, Id p, FILE *fp)
127 {
128   Solvable *s = pool_id2solvable(pool, p);
129   const char *rootdir = pool_get_rootdir(pool);
130   const char *evr, *evrp, *nvra;
131
132   switch(type)
133     {
134     case SOLVER_TRANSACTION_ERASE:
135       if (!s->repo->rpmdbid || !s->repo->rpmdbid[p - s->repo->start])
136         break;
137       /* strip epoch from evr */
138       evr = evrp = pool_id2str(pool, s->evr);
139       while (*evrp >= '0' && *evrp <= '9')
140         evrp++;
141       if (evrp > evr && evrp[0] == ':' && evrp[1])
142         evr = evrp + 1;
143       nvra = pool_tmpjoin(pool, pool_id2str(pool, s->name), "-", evr);
144       nvra = pool_tmpappend(pool, nvra, ".", pool_id2str(pool, s->arch));
145       runrpm("-e", nvra, -1, rootdir);      /* too bad that --querybynumber doesn't work */
146       break;
147     case SOLVER_TRANSACTION_INSTALL:
148     case SOLVER_TRANSACTION_MULTIINSTALL:
149       rewind(fp);
150       lseek(fileno(fp), 0, SEEK_SET);
151       runrpm(type == SOLVER_TRANSACTION_MULTIINSTALL ? "-i" : "-U", "/dev/fd/3", fileno(fp), rootdir);
152       break;
153     default:
154       break;
155     }
156 }
157
158 #endif