Duh, sqlite backend completely forgotten from srcrecord handling..
[apt.git] / apt-pkg / rpm / rpmsrcrecords.cc
1 // -*- mode: c++; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: rpmsrcrecords.cc,v 1.9 2003/01/29 15:19:02 niemeyer Exp $
4 /* ######################################################################
5    
6    SRPM Records - Parser implementation for RPM style source indexes
7       
8    ##################################################################### 
9  */
10                                                                         /*}}}*/
11 // Include Files                                                        /*{{{*/
12 #ifdef __GNUG__
13 #pragma implementation "apt-pkg/rpmsrcrecords.h"
14 #endif 
15
16 #include <config.h>
17
18 #ifdef HAVE_RPM
19
20 #include <assert.h>
21
22 #include <apt-pkg/rpmsrcrecords.h>
23 #include <apt-pkg/error.h>
24 #include <apt-pkg/strutl.h>
25 #include <apt-pkg/rpmhandler.h>
26 #include <apt-pkg/pkgcache.h>
27
28 #include <apti18n.h>
29
30 using namespace std;
31
32 // SrcRecordParser::rpmSrcRecordParser - Constructor                    /*{{{*/
33 // ---------------------------------------------------------------------
34 /* */
35 rpmSrcRecordParser::rpmSrcRecordParser(string File,pkgIndexFile const *Index)
36     : Parser(Index), Buffer(0), BufSize(0), BufUsed(0)
37 {
38    struct stat Buf;
39    if (stat(File.c_str(),&Buf) == 0 && S_ISDIR(Buf.st_mode))
40       Handler = new RPMDirHandler(File);
41    else if (flExtension(File) == "rpm")
42       Handler = new RPMSingleFileHandler(File);
43 #ifdef APT_WITH_REPOMD
44 #ifdef WITH_SQLITE3
45    else if (flExtension(File) == "sqlite")
46       Handler = new RPMSqliteHandler(File);
47 #endif
48    else if (flExtension(File) == "xml")
49       Handler = new RPMRepomdHandler(File);
50 #endif
51    else
52       Handler = new RPMFileHandler(File);
53 }
54                                                                         /*}}}*/
55 // SrcRecordParser::~rpmSrcRecordParser - Destructor                    /*{{{*/
56 // ---------------------------------------------------------------------
57 /* */
58 rpmSrcRecordParser::~rpmSrcRecordParser()
59 {
60    delete Handler;
61    free(Buffer);
62 }
63                                                                         /*}}}*/
64 // SrcRecordParser::Binaries - Return the binaries field                /*{{{*/
65 // ---------------------------------------------------------------------
66 /* This member parses the binaries field into a pair of class arrays and
67    returns a list of strings representing all of the components of the
68    binaries field. The returned array need not be freed and will be
69    reused by the next Binaries function call. */
70 const char **rpmSrcRecordParser::Binaries()
71 {
72    return NULL;
73
74 // WTF is this ?!? If we're looking for sources why would be interested
75 // in binaries? Maybe there's an inner Zen to this all but
76 // apt-cache showsrc seems to work without just fine so disabled for now...
77 #if 0
78    int i = 0;
79    char **bins;
80    int type, count;
81    assert(HeaderP != NULL);
82    int rc = headerGetEntry(HeaderP, CRPMTAG_BINARY,
83                            &type, (void**)&bins, &count);
84    if (rc != 1)
85        return NULL;
86    for (i = 0; (unsigned)i < sizeof(StaticBinList)/sizeof(char*) && i < count;
87         i++)
88       StaticBinList[i] = bins[i];
89    StaticBinList[i] = 0;
90    return StaticBinList;
91 #endif
92 }
93                                                                         /*}}}*/
94 // SrcRecordParser::Files - Return a list of files for this source      /*{{{*/
95 // ---------------------------------------------------------------------
96 /* This parses the list of files and returns it, each file is required to have
97    a complete source package */
98 bool rpmSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
99 {
100    List.clear();
101    
102    pkgSrcRecords::File F;
103
104    // XXX FIXME: Ignoring the md5sum for source packages for now 
105    //F.MD5Hash = Handler->MD5Sum();
106    F.MD5Hash = "";
107    F.Size = Handler->FileSize();
108    F.Path = flCombine(Handler->Directory(), Handler->FileName());
109    F.Type = "srpm";
110
111    List.push_back(F);
112    
113    return true;
114 }
115                                                                         /*}}}*/
116
117 bool rpmSrcRecordParser::Restart()
118 {
119    Handler->Rewind();
120    return true;
121 }
122
123 bool rpmSrcRecordParser::Step() 
124 {
125    bool ret = Handler->Skip();
126    // Repomd can have both binaries and sources, step over any binaries
127    while (ret && ! Handler->IsSourceRpm()) {
128       ret = Handler->Skip();
129    }
130    return ret;
131 }
132
133 bool rpmSrcRecordParser::Jump(off_t Off)
134 {
135    return Handler->Jump(Off);
136 }
137
138 string rpmSrcRecordParser::Package() const
139 {
140    return Handler->Name();
141 }
142
143 string rpmSrcRecordParser::Version() const
144 {
145    return Handler->EVR();
146 }
147     
148
149 // RecordParser::Maintainer - Return the maintainer email               /*{{{*/
150 // ---------------------------------------------------------------------
151 /* */
152 string rpmSrcRecordParser::Maintainer() const
153 {
154    return Handler->Packager();
155 }
156
157 string rpmSrcRecordParser::Section() const
158 {
159    return Handler->Group();
160 }
161
162 off_t rpmSrcRecordParser::Offset() 
163 {
164     return Handler->Offset();
165 }
166
167 void rpmSrcRecordParser::BufCat(const char *text)
168 {
169    if (text != NULL)
170       BufCat(text, text+strlen(text));
171 }
172
173 void rpmSrcRecordParser::BufCat(const char *begin, const char *end)
174 {
175    unsigned len = end - begin;
176     
177    if (BufUsed+len+1 >= BufSize)
178    {
179       BufSize += 512;
180       char *tmp = (char*)realloc(Buffer, BufSize);
181       if (tmp == NULL)
182       {
183          _error->Errno("realloc", _("Could not allocate buffer for record text"));
184          return;
185       }
186       Buffer = tmp;
187    }
188
189    strncpy(Buffer+BufUsed, begin, len);
190    BufUsed += len;
191 }
192
193 void rpmSrcRecordParser::BufCatTag(const char *tag, const char *value)
194 {
195    BufCat(tag);
196    BufCat(value);
197 }
198
199 void rpmSrcRecordParser::BufCatDep(Dependency *Dep)
200 {
201    string buf;
202
203    BufCat(Dep->Name.c_str());
204    if (Dep->Version.empty() == false) 
205    {
206       BufCat(" ");
207       switch (Dep->Op) {
208          case pkgCache::Dep::Less:
209             buf += "<";
210             break;
211          case pkgCache::Dep::LessEq:
212             buf += "<=";
213             break;
214          case pkgCache::Dep::Equals: 
215             buf += "=";
216             break;
217          case pkgCache::Dep::Greater:
218             buf += ">";
219             break;
220          case pkgCache::Dep::GreaterEq:
221             buf += ">=";
222             break;
223       }
224
225       BufCat(buf.c_str());
226       BufCat(" ");
227       BufCat(Dep->Version.c_str());
228    }
229 }
230
231 void rpmSrcRecordParser::BufCatDescr(const char *descr)
232 {
233    const char *begin = descr;
234
235    while (*descr) 
236    {
237       if (*descr=='\n') 
238       {
239          BufCat(" ");
240          BufCat(begin, descr+1);
241          begin = descr+1;
242       }
243       descr++;
244    }
245    BufCat(" ");
246    BufCat(begin, descr);
247    BufCat("\n");
248 }
249
250 // SrcRecordParser::AsStr - The record in raw text
251 // -----------------------------------------------
252 string rpmSrcRecordParser::AsStr() 
253 {
254    char buf[32];
255
256    BufUsed = 0;
257
258    BufCatTag("Package: ", Handler->Name().c_str());
259
260    BufCatTag("\nSection: ", Handler->Group().c_str());
261
262    snprintf(buf, sizeof(buf), "%lu", Handler->InstalledSize());
263    BufCatTag("\nInstalled Size: ", buf);
264
265    BufCatTag("\nPackager: ", Handler->Packager().c_str());
266    //BufCatTag("\nVendor: ", Handler->Vendor().c_str());
267
268    BufCat("\nVersion: ");
269    BufCat(Handler->EVR().c_str());
270
271    vector<Dependency*> Deps, Conflicts;
272    vector<Dependency*>::iterator I;
273    bool start = true;
274
275    Handler->PRCO(pkgCache::Dep::Depends, Deps);
276    for (I = Deps.begin(); I != Deps.end(); I++) {
277       if ((*I)->Type != pkgCache::Dep::Depends)
278          continue;
279       if (start) {
280          BufCat("\nBuild-Depends: ");
281          start = false;
282       } else {
283          BufCat(", ");
284       }
285       BufCatDep(*I);
286    }
287
288    // Doesn't do anything yet, build conflicts aren't recorded yet...
289    Handler->PRCO(pkgCache::Dep::Conflicts, Conflicts);
290    start = true;
291    for (I = Conflicts.begin(); I != Conflicts.end(); I++) {
292       if (start) {
293          BufCat("\nBuild-Conflicts: ");
294          start = false;
295       } else {
296          BufCat(", ");
297       }
298       BufCatDep(*I);
299    }
300
301    BufCatTag("\nArchitecture: ", Handler->Arch().c_str());
302
303    snprintf(buf, sizeof(buf), "%lu", Handler->FileSize());
304    BufCatTag("\nSize: ", buf);
305
306    BufCatTag("\nMD5Sum: ", Handler->MD5Sum().c_str());
307
308    BufCatTag("\nFilename: ", Handler->FileName().c_str());
309
310    BufCatTag("\nSummary: ", Handler->Summary().c_str());
311    BufCat("\nDescription: ");
312    BufCat("\n");
313    BufCatDescr(Handler->Description().c_str());
314    BufCat("\n");
315
316    return string(Buffer, BufUsed);
317 }
318
319
320 // SrcRecordParser::BuildDepends - Return the Build-Depends information /*{{{*/
321 // ---------------------------------------------------------------------
322 bool rpmSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps,
323                                       bool ArchOnly)
324 {
325    BuildDepRec rec;
326    BuildDeps.clear();
327
328    vector<Dependency*> Deps, Conflicts;
329    Handler->PRCO(pkgCache::Dep::Depends, Deps);
330
331    for (vector<Dependency*>::iterator I = Deps.begin(); I != Deps.end(); I++) {
332       rec.Package = (*I)->Name;
333       rec.Version = (*I)->Version;
334       rec.Op = (*I)->Op;
335       rec.Type = pkgSrcRecords::Parser::BuildDepend;
336       BuildDeps.push_back(rec);
337    }
338       
339    Handler->PRCO(pkgCache::Dep::Conflicts, Conflicts);
340
341    for (vector<Dependency*>::iterator I = Conflicts.begin(); I != Conflicts.end(); I++) {
342       rec.Package = (*I)->Name;
343       rec.Version = (*I)->Version;
344       rec.Op = (*I)->Op;
345       rec.Type = pkgSrcRecords::Parser::BuildConflict;
346       BuildDeps.push_back(rec);
347    }
348    return true;
349 }
350                                                                         /*}}}*/
351 #endif /* HAVE_RPM */
352
353 // vim:sts=3:sw=3