source: lliurex-apt/trunk/fuentes/src/Sources.cpp @ 923

Last change on this file since 923 was 923, checked in by mabarracus, 3 years ago

Imported trusty code

File size: 6.9 KB
Line 
1
2#include "Sources.hpp"
3
4#include <iostream>
5#include <fstream>
6#include <string>
7#include <stdexcept>
8#include <sstream>
9
10#include <regex.h>
11#include <glibmm/regex.h>
12#include <giomm.h>
13#include <glibmm.h>
14
15using namespace std;
16using namespace net::lliurex::apt;
17
18
19
20string SourceLine::ToString()
21{
22        stringstream ss;
23       
24        ss.str("");
25        ss<< ((source_type==SourceType::Deb) ? "deb" : "deb-src");
26        ss<<" ";
27       
28        switch(uri_type)
29        {
30                case UriType::Http:
31                        ss<<"http://";
32                break;
33               
34                case UriType::Https:
35                        ss<<"https://";
36                break;
37               
38                case UriType::Ftp:
39                        ss<<"ftp://";
40                break;
41               
42                case UriType::File:
43                        ss<<"file://";
44                break;
45               
46                case UriType::Cdrom:
47                        ss<<"cdrom:";
48                break;
49        }
50       
51        ss<<uri<<" "<<dist;
52       
53        for(string c : components)
54        {
55                ss<<" "<<c;
56        }
57       
58        return ss.str();
59}
60
61bool SourceLine::IsEqual(SourceLine & line)
62{
63        bool found=false;
64       
65        if(source_type==line.source_type && uri_type==line.uri_type
66        && uri==line.uri && dist==line.dist)
67        {
68                found=true;
69               
70                for(string c : components)
71                {
72                        bool cfound = false;
73
74                        for(string cc : line.components)
75                        {
76                                if(cc==c)cfound=true;
77                        }
78
79                        if(!cfound)found=false;
80                }
81        }
82       
83        return found;
84}
85
86
87string Sources::str_line="^(?<deb_type>deb|deb\\-src)\\s+(?<uri_type>http://|https://|file://|ftp://|cdrom:)(?<uri>\\[.+\\]/|\\S+)\\s+(?<dist>\\S+)(?<components>(\\s+\\S+)+)";
88       
89string Sources::str_option="^#(?<key>\\w+)(\\[(?<locale>\\S+)\\])?\\s*=\\s*(?<value>.*)";
90
91const string Sources::SourcesList = "/etc/apt/sources.list";
92
93
94Sources::Sources()
95{
96
97}
98
99
100Sources::Sources(string filename)
101{
102       
103               
104        Glib::RefPtr<Glib::Regex> regex_line = Glib::Regex::create(Sources::str_line);
105        Glib::RefPtr<Glib::Regex> regex_option = Glib::Regex::create(Sources::str_option);
106       
107        ifstream file(filename);
108       
109       
110        optional=false;
111        name["C"]="noname";
112               
113        while(!file.eof())
114        {
115                string line;
116                getline(file,line);//read a single line from the file
117               
118                Glib::MatchInfo info;
119               
120                //have we got a match?
121                if(regex_line->match(line,info))
122                {
123                       
124                        string type;
125                        string uri_type;
126                        string uri;
127                        string dist;
128                        string components;
129                        vector<string> vcmp;
130                       
131                        //fetch matching groups
132                        type = info.fetch_named("deb_type");
133                        uri_type=info.fetch_named("uri_type");
134                        uri=info.fetch_named("uri");
135                        dist = info.fetch_named("dist");
136                                               
137                       
138                        components=info.fetch_named("components");
139                       
140                        //split components
141                        string buf;
142                        stringstream ss(components.substr(1));
143                                                                       
144                        while(ss >> buf)
145                                vcmp.push_back(buf);
146                               
147                       
148                        //fill SourceLine object
149                        SourceLine sl;
150                       
151                        if(type=="deb")sl.source_type=SourceType::Deb;
152                        if(type=="deb-src")sl.source_type=SourceType::Source;
153                       
154                        if(uri_type=="http://")sl.uri_type=UriType::Http;
155                        if(uri_type=="https://")sl.uri_type=UriType::Https;
156                        if(uri_type=="file://")sl.uri_type=UriType::File;
157                        if(uri_type=="ftp://")sl.uri_type=UriType::Ftp;
158                        if(uri_type=="cdrom:")sl.uri_type=UriType::Cdrom;
159                       
160                       
161                        //remove all ending slashs
162                        while(uri[uri.length()-1]=='/')
163                        {
164                                uri=uri.substr(0,uri.length()-1);
165                        }
166                       
167                        sl.uri=uri;
168                        sl.dist=dist;
169                       
170                        sl.components = vcmp;
171                                               
172                       
173                        //and Push it up
174                        Push(sl);
175                }
176                else
177                {
178                        if(regex_option->match(line,info))
179                        {
180                               
181                                string key=info.fetch_named("key");
182                                string value=info.fetch_named("value");
183                                string locale=info.fetch_named("locale");
184                               
185                                if(key=="optional")
186                                {
187                                        optional=(value=="true");
188                                }
189                               
190                                if(key=="name")
191                                {
192                                        locale=(locale=="") ? "C" : locale;
193                                        name[locale]=value;
194                                }
195                               
196                               
197                        }
198                }
199        }
200       
201        file.close();
202}
203
204
205void Sources::Add(string line)
206{
207        Glib::RefPtr<Glib::Regex> regex_line = Glib::Regex::create(Sources::str_line);
208       
209        Glib::MatchInfo info;
210               
211
212        if(regex_line->match(line,info))
213        {
214                string type;
215                string uri_type;
216                string uri;
217                string dist;
218                string components;
219                vector<string> vcmp;
220               
221                //fetch matching groups
222                type = info.fetch_named("deb_type");
223                uri_type=info.fetch_named("uri_type");
224                uri=info.fetch_named("uri");
225                dist = info.fetch_named("dist");
226               
227                components=info.fetch_named("components");
228               
229                //split components
230                string buf;
231                stringstream ss(components.substr(1));
232                                                               
233                while(ss >> buf)
234                        vcmp.push_back(buf);
235                       
236               
237                //fill SourceLine object
238                SourceLine sl;
239               
240                if(type=="deb")sl.source_type=SourceType::Deb;
241                if(type=="deb-src")sl.source_type=SourceType::Source;
242               
243                if(uri_type=="http://")sl.uri_type=UriType::Http;
244                if(uri_type=="https://")sl.uri_type=UriType::Https;
245                if(uri_type=="file://")sl.uri_type=UriType::File;
246                if(uri_type=="ftp://")sl.uri_type=UriType::Ftp;
247                if(uri_type=="cdrom:")sl.uri_type=UriType::Cdrom;
248                                       
249                sl.uri=uri;
250                sl.dist=dist;
251               
252                sl.components = vcmp;
253                                       
254               
255                //and Push it up
256                Push(sl);
257        }
258        else
259        {
260                throw runtime_error("Failed to parse source line");
261        }
262       
263}
264
265
266void Sources::Push(SourceLine line)
267{
268
269        bool found = false;
270       
271        for(int n = 0;n<lines.size();n++)
272        {
273                SourceLine & q = lines[n];
274               
275                if(q.source_type==line.source_type && q.uri_type==line.uri_type
276                 && q.uri==line.uri && q.dist==line.dist)
277                 {
278                        found = true;
279                       
280                        for(string component : line.components)
281                        {
282                                bool cfound = false;
283                               
284                                for(string c : q.components)
285                                {
286                                        if(c==component)cfound=true;
287                                }
288                               
289                                if(!cfound)
290                                {
291                                        q.components.push_back(component);
292                                }
293                        }
294                 }
295        }
296       
297        if(!found)
298        {
299                lines.push_back(line);
300        }
301}
302
303
304FindLineStatus Sources::Find(SourceLine line)
305{
306       
307        int f=0;
308        int p=0;
309        int nf=0;
310       
311        for(int n=0;n<lines.size();n++)
312        {
313                SourceLine & q = lines[n];
314               
315                bool found=false;
316                bool partial=false;
317               
318               
319                if(q.source_type==line.source_type && q.uri_type==line.uri_type
320                && q.uri==line.uri && q.dist==line.dist)
321                {
322                        found=true;
323                        partial=true;
324                       
325                        for(string c : q.components)
326                        {
327                                bool cfound=false;
328                               
329                                for(string cc : line.components)
330                                {
331                                        if(cc==c)cfound=true;
332                                }
333                               
334                                if(!cfound)found=false;
335                        }
336                }
337               
338                if(found)
339                {
340                        f++;
341                }
342                else
343                {
344                        if(partial)
345                        {
346                                p++;
347                        }
348                        else
349                        {
350                                nf++;
351                        }
352                }
353        }
354       
355       
356        FindLineStatus ret;
357       
358        if(f>0)
359        {
360                ret=FindLineStatus::Found;
361        }
362        else
363        {
364                if(p>0)
365                {
366                        ret=FindLineStatus::Partial;
367                }
368                else
369                {
370                        ret=FindLineStatus::NotFound;
371                }
372        }
373       
374        return ret;
375}
376
377Sources net::lliurex::apt::operator+(Sources & A,Sources & B)
378{
379        Sources R;
380       
381       
382        R.lines = A.lines;
383       
384        for(SourceLine line : B.lines)
385        {
386                R.Push(line);
387        }
388       
389        return R;
390}
391
392
393void Sources::Print()
394{
395
396       
397        for(int n=0;n<lines.size();n++)
398        {
399                SourceLine & q = lines[n];
400
401                cout<<q.ToString()<<endl;
402
403        }
404}
405
406
407void Sources::Write(string filename)
408{
409
410        ofstream file;
411        string out;
412        string err;
413        int ret;
414       
415        file.open("/tmp/llx-apt-sources.list");
416
417        for(int n=0;n<lines.size();n++)
418        {
419                SourceLine & q = lines[n];
420
421                file<<q.ToString()<<endl;
422
423        }
424
425        file.close();
426       
427        Glib::spawn_command_line_sync("llx-apt-backend /tmp/llx-apt-sources.list "+filename,&out,&err,&ret);
428
429               
430       
431        if(ret!=0)
432        {
433                cout<<"output:"<<endl;
434                cout<<out<<endl;
435       
436                cout<<"err:"<<endl;
437                cout<<err<<endl;
438                throw std::runtime_error("Failed to write "+filename);
439        }
440}
Note: See TracBrowser for help on using the repository browser.