source: projects/synaptic/trunk/common/raptoptions.cc @ 280

Revision 280, 7.7 KB checked in by yasumichi, 15 years ago (diff)

first import

Line 
1/* raptoptions.cc - configuration handling
2 *
3 * Copyright (c) 2000, 2001 Conectiva S/A
4 *
5 * Author: Alfredo K. Kojima <kojima@conectiva.com.br>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 */
22
23
24
25#include "config.h"
26#include <fstream>
27#include <sstream>
28#include <dirent.h>
29
30#include <apt-pkg/error.h>
31#include <apt-pkg/configuration.h>
32#include <apt-pkg/tagfile.h>
33#include <apt-pkg/policy.h>
34#include <apt-pkg/sptr.h>
35#include <apt-pkg/strutl.h>
36
37#include "rconfiguration.h"
38#include "raptoptions.h"
39
40#include "i18n.h"
41
42
43RAPTOptions *_roptions = new RAPTOptions;
44
45using namespace std;
46
47ostream &operator<<(ostream &os, const RAPTOptions::packageOptions &o)
48{
49   os << o.isNew;
50   return os;
51}
52
53istream &operator>>(istream &is, RAPTOptions::packageOptions &o)
54{
55   is >> o.isNew;
56   return is;
57}
58
59
60bool RAPTOptions::store()
61{
62   ofstream out;
63   if (!RPackageOptionsFile(out))
64      return false;
65
66   for (packageOptionsIter it = _roptions->_packageOptions.begin();
67        it != _roptions->_packageOptions.end(); it++) {
68      // we only write out if it's new and the pkgname is not empty
69      if ((*it).second.isNew && !(*it).first.empty())
70         out << (*it).first << " " << (*it).second << endl;
71   }
72   return true;
73}
74
75
76bool RAPTOptions::restore()
77{
78   string pkg, line;
79   packageOptions o;
80
81   //cout << "bool RAPTOptions::restore()" << endl;
82
83   ifstream in;
84   if (!RPackageOptionsFile(in))
85      return false;
86
87   // new stuff
88   while (!in.eof()) {
89      getline(in, line);
90      istringstream strstr(line.c_str());
91      strstr >> pkg >> o >> ws;
92      _packageOptions[pkg] = o;
93   }
94
95   // upgrade code for older synaptic versions, can go away in the future
96   if(FileExists(RConfDir()+"/preferences"))
97      rename(string(RConfDir()+"/preferences").c_str(),
98             string(RStateDir()+"/preferences").c_str());
99
100
101   // pining stuff
102   string File = RStateDir() + "/preferences";
103
104   if (!FileExists(File))
105      return true;
106
107   FileFd Fd(File, FileFd::ReadOnly);
108   pkgTagFile TF(&Fd);
109   if (_error->PendingError() == true) {
110      return false;
111   }
112   pkgTagSection Tags;
113   while (TF.Step(Tags) == true) {
114      string Name = Tags.FindS("Package");
115      if (Name.empty() == true)
116         return _error->
117            Error(_
118                  ("Invalid record in the preferences file, no Package header"));
119      if (Name == "*")
120         Name = string();
121
122      const char *Start;
123      const char *End;
124      if (Tags.Find("Pin", Start, End) == false)
125         continue;
126
127      const char *Word = Start;
128      for (; Word != End && isspace(*Word) == 0; Word++);
129
130      // Parse the type, we are only interesseted in "version" for now
131      pkgVersionMatch::MatchType Type;
132      if (stringcasecmp(Start, Word, "version") == 0 && Name.empty() == false)
133         Type = pkgVersionMatch::Version;
134      else
135         continue;
136      for (; Word != End && isspace(*Word) != 0; Word++);
137
138      setPackageLock(Name.c_str(), true);
139   }
140
141   // deborphan stuff
142   rereadOrphaned();
143
144   // debconf stuff
145   rereadDebconf();
146
147   return true;
148}
149
150bool RAPTOptions::getPackageDebconf(const char *package)
151{
152   string tmp = string(package);
153
154   if (_packageOptions.find(tmp) == _packageOptions.end())
155      return false;
156
157   //cout << "getPackageOrphaned("<<package<<") called"<<endl;
158   return _packageOptions[tmp].isDebconf;
159}
160
161
162void RAPTOptions::setPackageDebconf(const char *package, bool flag)
163{
164   //cout << "debconf called pkg: " << package << endl;
165   _packageOptions[string(package)].isDebconf = flag;
166}
167
168void RAPTOptions::rereadDebconf()
169{
170   //cout << "void RAPTOptions::rereadDebconf()" << endl;
171
172   // forget about any previously debconf packages
173   for (packageOptionsIter it = _roptions->_packageOptions.begin();
174        it != _roptions->_packageOptions.end(); it++) {
175      (*it).second.isDebconf = false;
176   }
177
178   // read dir
179   const char infodir[] = "/var/lib/dpkg/info";
180   const char configext[] = ".config";
181
182   DIR *dir;
183   struct dirent *dent;
184   char *point;
185
186   if ((dir = opendir(infodir)) == NULL) {
187      //cerr << "Error opening " << infodir << endl;
188      return;
189   }
190   for (int i = 3; (dent = readdir(dir)); i++) {
191      if ((point = strrchr(dent->d_name, '.')) == NULL)
192         continue;
193      if (strcmp(point, configext) == 0) {
194         bzero(point, strlen(point));
195         //cout << (dent->d_name) << endl;
196         setPackageDebconf(dent->d_name, true);
197      }
198   }
199   closedir(dir);
200}
201
202void RAPTOptions::rereadOrphaned()
203{
204   // forget about any previously orphaned packages
205   for (packageOptionsIter it = _roptions->_packageOptions.begin();
206        it != _roptions->_packageOptions.end(); it++) {
207      (*it).second.isOrphaned = false;
208   }
209
210   //mvo: call deborphan and read package list from it
211   //     TODO: make deborphan a library to make this cleaner
212   FILE *fp;
213   char buf[255];
214   char cmd[] = "/usr/bin/deborphan";
215   //FIXME: fail silently if deborphan is not installed - change this?
216   if (!FileExists(cmd))
217      return;
218   fp = popen(cmd, "r");
219   if (fp == NULL) {
220      //cerr << "deborphan failed" << endl;
221      return;
222   }
223   while (fgets(buf, 254, fp) != NULL) {
224      //mvo: FIXME this sucks (remove newline at end)
225      buf[strlen(buf) - 1] = 0;
226      //cout << "buf: " << buf << endl;
227      setPackageOrphaned(buf, true);
228   }
229   pclose(fp);
230}
231
232
233bool RAPTOptions::getPackageOrphaned(const char *package)
234{
235   string tmp = string(package);
236
237   if (_packageOptions.find(tmp) == _packageOptions.end())
238      return false;
239
240   //cout << "getPackageOrphaned("<<package<<") called"<<endl;
241   return _packageOptions[tmp].isOrphaned;
242}
243
244
245void RAPTOptions::setPackageOrphaned(const char *package, bool flag)
246{
247   //cout << "orphaned called pkg: " << package << endl;
248   _packageOptions[string(package)].isOrphaned = flag;
249}
250
251
252bool RAPTOptions::getPackageLock(const char *package)
253{
254   string tmp = string(package);
255
256   if (_packageOptions.find(tmp) == _packageOptions.end())
257      return false;
258
259   return _packageOptions[tmp].isLocked;
260}
261
262
263void RAPTOptions::setPackageLock(const char *package, bool lock)
264{
265   _packageOptions[string(package)].isLocked = lock;
266}
267
268bool RAPTOptions::getPackageNew(const char *package)
269{
270   string tmp = string(package);
271
272   if (_packageOptions.find(tmp) == _packageOptions.end())
273      return false;
274
275   return _packageOptions[tmp].isNew;
276}
277
278void RAPTOptions::setPackageNew(const char *package, bool lock)
279{
280   _packageOptions[string(package)].isNew = lock;
281}
282
283void RAPTOptions::forgetNewPackages()
284{
285   for (packageOptionsIter it = _roptions->_packageOptions.begin();
286        it != _roptions->_packageOptions.end(); it++) {
287      (*it).second.isNew = false;
288   }
289}
290
291bool RAPTOptions::getFlag(const char *key)
292{
293   if (_options.find(key) != _options.end())
294      return _options[string(key)] == "true";
295   else
296      return false;
297}
298
299
300string RAPTOptions::getString(const char *key)
301{
302   if (_options.find(key) != _options.end())
303      return _options[string(key)];
304   else
305      return "";
306}
307
308
309void RAPTOptions::setFlag(const char *key, bool value)
310{
311   _options[string(key)] = string(value ? "true" : "false");
312}
313
314
315void RAPTOptions::setString(const char *key, string value)
316{
317   _options[string(key)] = value;
318}
Note: See TracBrowser for help on using the repository browser.