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