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