]>
Commit | Line | Data |
---|---|---|
7939f6d1 RC |
1 | /* |
2 | * Copyright (c) 2001, Robert Collins. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by Robert Collins <rbtcollins@hotmail.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* this is the package database class. | |
17 | * It lists all known packages, including custom ones, ones from a mirror and | |
18 | * installed ones. | |
19 | */ | |
20 | ||
21 | #if 0 | |
22 | static const char *cvsid = | |
23 | "\n%%% $Id$\n"; | |
24 | #endif | |
25 | ||
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | #include <unistd.h> | |
29 | #include <strings.h> | |
30 | #include "concat.h" | |
31 | ||
32 | #include "io_stream.h" | |
33 | #include "compress.h" | |
34 | ||
35 | #include "filemanip.h" | |
36 | ||
fa0c0d10 | 37 | #include "package_version.h" |
7939f6d1 RC |
38 | #include "cygpackage.h" |
39 | #include "package_db.h" | |
40 | #include "package_meta.h" | |
41 | ||
42 | /* static members */ | |
43 | ||
44 | packagemeta * | |
45 | packagedb::getpackagebyname (const char *search) | |
46 | { | |
47 | /* dumb search, we can add a index and do a btree later */ | |
48 | size_t index = 0; | |
49 | while (index < packagecount) | |
50 | { | |
51 | if (!strcasecmp ((*packages[index]).name, search)) | |
52 | return packages[index]; | |
53 | index++; | |
54 | } | |
55 | return 0; | |
56 | } | |
57 | ||
58 | packagedb::packagedb () | |
59 | { | |
fa0c0d10 RC |
60 | db = 0; |
61 | curr_package = 0; | |
7939f6d1 RC |
62 | if (!installeddbread) |
63 | { | |
64 | /* no parameters. Read in the local installation database. */ | |
65 | db = io_stream::open ("cygfile:///etc/setup/installed.db", "rt"); | |
66 | if (!db) | |
67 | return; | |
68 | /* flush_local_db_package_data */ | |
69 | char line[1000], pkgname[1000], inst[1000], src[1000]; | |
70 | int instsz, srcsz; | |
7939f6d1 | 71 | |
24cbae7f RC |
72 | if (db->gets (line, 1000)) |
73 | { | |
74 | int dbver; | |
75 | sscanf (line, "%s %d", pkgname, &instsz); | |
76 | if (!strcasecmp (pkgname, "INSTALLED.DB") && instsz == 2) | |
77 | dbver = 2; | |
78 | else | |
79 | dbver = 1; | |
80 | delete db; | |
fa0c0d10 | 81 | db = 0; |
24cbae7f RC |
82 | /* Later versions may not use installed.db other than to record the version. */ |
83 | if (dbver == 1 || dbver == 2) | |
7939f6d1 | 84 | { |
24cbae7f RC |
85 | db = |
86 | io_stream::open ("cygfile:///etc/setup/installed.db", "rt"); | |
87 | if (dbver == 2) | |
88 | db->gets (line, 1000); | |
89 | while (db->gets (line, 1000)) | |
7939f6d1 | 90 | { |
24cbae7f RC |
91 | int parseable; |
92 | src[0] = 0; | |
93 | srcsz = 0; | |
94 | sscanf (line, "%s %s %d %s %d", pkgname, inst, &instsz, src, | |
95 | &srcsz); | |
96 | fileparse f; | |
97 | parseable = parse_filename (inst, f); | |
98 | if (!parseable) | |
99 | continue; | |
100 | ||
101 | packagemeta *pkg = getpackagebyname (pkgname); | |
102 | if (!pkg) | |
103 | { | |
fa0c0d10 | 104 | pkg = new packagemeta (pkgname, inst); |
24cbae7f RC |
105 | /* we should install a new handler then not check this... |
106 | */ | |
107 | //if (!pkg) | |
108 | //die badly | |
109 | } | |
110 | ||
111 | cygpackage *binary = | |
112 | new cygpackage (pkgname, inst, instsz, f.ver, | |
113 | package_installed, | |
114 | package_binary); | |
115 | ||
116 | pkg->add_version (*binary); | |
117 | pkg->set_installed (*binary); | |
bb849dbd | 118 | pkg->desired = pkg->installed; |
24cbae7f | 119 | addpackage (*pkg); |
7939f6d1 | 120 | |
7939f6d1 | 121 | } |
24cbae7f | 122 | delete db; |
fa0c0d10 | 123 | db = 0; |
24cbae7f RC |
124 | } |
125 | else | |
126 | // unknown dbversion | |
127 | exit (1); | |
7939f6d1 | 128 | } |
7b606ae5 | 129 | installeddbread = 1; |
7939f6d1 | 130 | } |
7939f6d1 RC |
131 | } |
132 | ||
133 | packagemeta * | |
134 | packagedb::getfirstpackage () | |
135 | { | |
136 | curr_package = 0; | |
137 | if (packages) | |
138 | return packages[0]; | |
139 | return 0; | |
140 | } | |
141 | ||
142 | packagemeta * | |
143 | packagedb::getnextpackage () | |
144 | { | |
145 | curr_package++; | |
146 | if (packagecount >= curr_package) | |
147 | return packages[curr_package]; | |
148 | return 0; | |
149 | } | |
150 | ||
151 | int | |
152 | packagedb::addpackage (packagemeta & newpackage) | |
153 | { | |
154 | if (getpackagebyname (newpackage.name)) | |
155 | return 1; | |
156 | /* lock the mutex */ | |
157 | if (packagecount == packagespace) | |
158 | { | |
24cbae7f RC |
159 | packagemeta **newpackages = (packagemeta **) realloc (packages, |
160 | sizeof | |
161 | (packagemeta *) * | |
162 | (packagespace + | |
163 | 100)); | |
7939f6d1 RC |
164 | if (!newpackages) |
165 | { | |
166 | //die | |
167 | exit (100); | |
168 | } | |
169 | packages = newpackages; | |
170 | packagespace += 100; | |
171 | } | |
fa0c0d10 RC |
172 | size_t n; |
173 | for (n = 0; | |
174 | n < packagecount | |
175 | && strcasecmp (packages[n]->name, newpackage.name) < 0; n++); | |
176 | /* insert at n */ | |
177 | memmove (&packages[n + 1], &packages[n], | |
178 | (packagecount - n) * sizeof (packagemeta *)); | |
179 | packages[n] = &newpackage; | |
7939f6d1 RC |
180 | packagecount++; |
181 | return 0; | |
182 | } | |
183 | ||
7c7034e8 RC |
184 | int |
185 | packagedb::flush () | |
186 | { | |
187 | /* naive approach - just dump the lot */ | |
188 | char const *odbn = "cygfile:///etc/setup/installed.db"; | |
189 | char const *ndbn = "cygfile:///etc/setup/installed.db.new"; | |
190 | ||
191 | io_stream::mkpath_p (PATH_TO_FILE, ndbn); | |
192 | ||
193 | io_stream *ndb = io_stream::open (ndbn, "wb"); | |
194 | ||
195 | if (!ndb) | |
196 | return errno ? errno : 1; | |
197 | ||
198 | ndb->write ("INSTALLED.DB 2\n", strlen ("INSTALLED.DB 2\n")); | |
199 | if (getfirstpackage ()) | |
200 | { | |
201 | packagemeta *pkgm = getfirstpackage (); | |
202 | while (pkgm) | |
203 | { | |
204 | if (pkgm->installed) | |
205 | { | |
206 | char line[2048]; | |
207 | ||
208 | /* size here is irrelevant - as we can assume that this install source | |
7d66d192 RC |
209 | * no longer exists, and it does not correlate to used disk space |
210 | * also note that we are writing a fictional install source | |
211 | * to keep cygcheck happy. | |
7c7034e8 | 212 | */ |
7d66d192 RC |
213 | sprintf (line, "%s %s %d\n", pkgm->name, |
214 | concat (pkgm->name, "-", | |
215 | pkgm->installed->Canonical_version (), | |
216 | ".tar.bz2", 0), 0); | |
7c7034e8 RC |
217 | ndb->write (line, strlen (line)); |
218 | } | |
219 | pkgm = getnextpackage (); | |
220 | } | |
221 | } | |
222 | ||
223 | delete ndb; | |
224 | ||
225 | io_stream::remove (odbn); | |
226 | ||
227 | if (io_stream::move (ndbn, odbn)) | |
228 | return errno ? errno : 1; | |
229 | return 0; | |
230 | } | |
231 | ||
bb849dbd RC |
232 | packagemeta & packagedb::registerpackage (char const *pkgname) |
233 | { | |
234 | packagemeta * | |
235 | tmp = | |
236 | getpackagebyname (pkgname); | |
237 | if (tmp) | |
238 | return *tmp; | |
239 | tmp = new packagemeta (pkgname); | |
240 | addpackage (*tmp); | |
241 | return *tmp; | |
242 | } | |
243 | ||
244 | ||
7939f6d1 RC |
245 | packagemeta ** |
246 | packagedb::packages = | |
247 | 0; | |
4fe323f9 RC |
248 | size_t packagedb::packagecount = 0; |
249 | size_t packagedb::packagespace = 0; | |
7939f6d1 RC |
250 | int |
251 | packagedb::installeddbread = | |
252 | 0; | |
4fe323f9 RC |
253 | list < Category, char const *, |
254 | strcasecmp > | |
255 | packagedb::categories; |