]> cygwin.com Git - cygwin-apps/setup.git/blob - package_db.cc
2002-07-05 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 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <strings.h>
29 #if HAVE_ERRNO_H
30 #include <errno.h>
31 #endif
32
33 #include "io_stream.h"
34 #include "compress.h"
35
36 #include "filemanip.h"
37
38 #include "package_version.h"
39 #include "cygpackage.h"
40 #include "package_db.h"
41 #include "package_meta.h"
42
43 /* static members */
44
45 packagedb::packagedb ()
46 {
47 io_stream *db = 0;
48 if (!installeddbread)
49 {
50 /* no parameters. Read in the local installation database. */
51 db = io_stream::open ("cygfile:///etc/setup/installed.db", "rt");
52 if (!db)
53 return;
54 /* flush_local_db_package_data */
55 char line[1000], pkgname[1000], inst[1000], src[1000];
56 int instsz, srcsz;
57
58 if (db->gets (line, 1000))
59 {
60 int dbver;
61 sscanf (line, "%s %d", pkgname, &instsz);
62 if (!strcasecmp (pkgname, "INSTALLED.DB") && instsz == 2)
63 dbver = 2;
64 else
65 dbver = 1;
66 delete db;
67 db = 0;
68 /* Later versions may not use installed.db other than to record the version. */
69 if (dbver == 1 || dbver == 2)
70 {
71 db =
72 io_stream::open ("cygfile:///etc/setup/installed.db", "rt");
73 if (dbver == 2)
74 db->gets (line, 1000);
75 while (db->gets (line, 1000))
76 {
77 int parseable;
78 src[0] = '\0';
79 pkgname[0] = '\0';
80 inst[0] = '\0';
81 srcsz = 0;
82 instsz = 0;
83
84 sscanf (line, "%s %s %d %s %d", pkgname, inst, &instsz, src,
85 &srcsz);
86
87 if (pkgname[0] == '\0' || inst[0] == '\0')
88 continue;
89
90 fileparse f;
91 parseable = parse_filename (inst, f);
92 if (!parseable)
93 continue;
94
95 packagemeta *pkg = packages.getbykey (pkgname);
96 if (!pkg)
97 {
98 pkg = new packagemeta (pkgname, inst);
99 /* we should install a new handler then not check this...
100 */
101 //if (!pkg)
102 //die badly
103 }
104
105 packageversion binary =
106 cygpackage::createInstance (pkgname, inst, instsz, f.ver,
107 package_installed,
108 package_binary);
109
110 pkg->add_version (binary);
111 pkg->set_installed (binary);
112 pkg->desired = pkg->installed;
113 packages.registerbyobject (*pkg);
114
115 }
116 delete db;
117 db = 0;
118 }
119 else
120 // unknown dbversion
121 exit (1);
122 }
123 installeddbread = 1;
124 }
125 }
126
127 int
128 packagedb::flush ()
129 {
130 /* naive approach - just dump the lot */
131 char const *odbn = "cygfile:///etc/setup/installed.db";
132 char const *ndbn = "cygfile:///etc/setup/installed.db.new";
133
134 io_stream::mkpath_p (PATH_TO_FILE, ndbn);
135
136 io_stream *ndb = io_stream::open (ndbn, "wb");
137
138 // XXX if this failed, try removing any existing .new database?
139 if (!ndb)
140 return errno ? errno : 1;
141
142 ndb->write ("INSTALLED.DB 2\n", strlen ("INSTALLED.DB 2\n"));
143 for (size_t n = 1; n <= packages.number (); n++)
144 {
145 packagemeta & pkgm = *packages[n];
146 if (pkgm.installed)
147 {
148 /* size here is irrelevant - as we can assume that this install source
149 * no longer exists, and it does not correlate to used disk space
150 * also note that we are writing a fictional install source
151 * to keep cygcheck happy.
152 */
153 String line;
154 line = pkgm.name + " " + pkgm.name + "-" +
155 pkgm.installed.Canonical_version () + ".tar.bz2 0\n";
156 ndb->write (line.cstr_oneuse(), line.size());
157 }
158 }
159
160 delete ndb;
161
162 io_stream::remove (odbn);
163
164 if (io_stream::move (ndbn, odbn))
165 return errno ? errno : 1;
166 return 0;
167 }
168
169 packagemeta *
170 packagedb::findBinary (PackageSpecification const &spec) const
171 {
172 for (size_t n = 1; n <= packages.number (); ++n)
173 {
174 packagemeta & pkgm = *packages[n];
175 for (set<packageversion>::iterator i=pkgm.versions.begin();
176 i != pkgm.versions.end(); ++i)
177 if (spec.satisfies (*i))
178 return &pkgm;
179 }
180 return NULL;
181 }
182
183 packagemeta *
184 packagedb::findSource (PackageSpecification const &spec) const
185 {
186 for (vector <packagemeta *>::iterator n=sourcePackages.begin();
187 n != sourcePackages.end(); ++n)
188 {
189 for (set<packageversion>::iterator i = (*n)->versions.begin();
190 i != (*n)->versions.end(); ++i)
191 if (spec.satisfies (*i))
192 return *n;
193 }
194 return NULL;
195 }
196
197 int
198 packagedb::installeddbread =
199 0;
200 list < packagemeta, String,
201 String::casecompare >
202 packagedb::packages;
203 list < Category, String,
204 String::casecompare >
205 packagedb::categories;
206 vector <packagemeta *> packagedb::sourcePackages;
207 PackageDBActions
208 packagedb::task =
209 PackageDB_Install;
This page took 0.041944 seconds and 5 git commands to generate.