]> cygwin.com Git - cygwin-apps/setup.git/blob - package_db.cc
2001-11-29 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / package_db.cc
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
37 #include "package_version.h"
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 {
60 db = 0;
61 curr_package = 0;
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;
71
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;
81 db = 0;
82 /* Later versions may not use installed.db other than to record the version. */
83 if (dbver == 1 || dbver == 2)
84 {
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))
90 {
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 {
104 pkg = new packagemeta (pkgname, inst);
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);
118 pkg->desired = pkg->installed;
119 addpackage (*pkg);
120
121 }
122 delete db;
123 db = 0;
124 }
125 else
126 // unknown dbversion
127 exit (1);
128 }
129 installeddbread = 1;
130 }
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 {
159 packagemeta **newpackages = (packagemeta **) realloc (packages,
160 sizeof
161 (packagemeta *) *
162 (packagespace +
163 100));
164 if (!newpackages)
165 {
166 //die
167 exit (100);
168 }
169 packages = newpackages;
170 packagespace += 100;
171 }
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;
180 packagecount++;
181 return 0;
182 }
183
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
209 * no longer exists, and it does not correlate to used disk space
210 */
211 sprintf (line, "%s %s %d\n", pkgm->name, pkgm->installed_from,
212 0);
213 ndb->write (line, strlen (line));
214 }
215 pkgm = getnextpackage ();
216 }
217 }
218
219 delete ndb;
220
221 io_stream::remove (odbn);
222
223 if (io_stream::move (ndbn, odbn))
224 return errno ? errno : 1;
225 return 0;
226 }
227
228 packagemeta & packagedb::registerpackage (char const *pkgname)
229 {
230 packagemeta *
231 tmp =
232 getpackagebyname (pkgname);
233 if (tmp)
234 return *tmp;
235 tmp = new packagemeta (pkgname);
236 addpackage (*tmp);
237 return *tmp;
238 }
239
240
241 packagemeta **
242 packagedb::packages =
243 0;
244 size_t packagedb::packagecount = 0;
245 size_t packagedb::packagespace = 0;
246 int
247 packagedb::installeddbread =
248 0;
249 CategoryList packagedb::categories = CategoryList ();
This page took 0.047218 seconds and 5 git commands to generate.