~ubuntu-branches/ubuntu/quantal/apt-cacher-ng/quantal-backports

« back to all changes in this revision

Viewing changes to source/acfg.cc

  • Committer: Bazaar Package Importer
  • Author(s): Eduard Bloch
  • Date: 2011-08-01 23:40:11 UTC
  • mfrom: (1.1.29 upstream) (29.1.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110801234011-2ouft5pay71773vs
Tags: 0.6.4-1
* New upstream version
  + fixes potential pipeline freeze (closes: #628995)
  + supports "soft" blacklisting of bad hosts when important files are
    missing (see keyfile in documentation, closes: #616091)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
 
3
 
#define LOCAL_DEBUG
 
3
//#define LOCAL_DEBUG
4
4
#include "debug.h"
5
5
 
6
6
#include "acfg.h"
7
7
#include "meta.h"
8
8
#include "filereader.h"
9
9
#include "fileio.h"
 
10
#include "lockable.h"
 
11
#include "cleaner.h"
10
12
 
11
13
#include <regex.h>
12
14
 
19
21
 
20
22
using namespace MYSTD;
21
23
 
 
24
 
 
25
#define _iterPos(it, start) (it-start.begin())/sizeof(it)
 
26
#define sProblemLoc szPath<< ':'<< _iterPos(it, lines)
 
27
 
 
28
string sFilterSet(SPACECHARS "#");
 
29
#define IsValidButIrrelevantLine(x) (x.empty() || stmiss != sFilterSet.find(x[0]))
 
30
#define BARF(x) { cerr << x << endl; exit(EXIT_FAILURE); }
 
31
 
22
32
namespace rechecks
23
33
{
24
34
bool CompileExpressions();
28
38
 
29
39
namespace acfg {
30
40
 
 
41
 
31
42
// internal stuff:
32
43
char alphabet[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
33
44
string sPopularPath("/debian/");
37
48
tStrMap localdirs;
38
49
NoCaseStringMap mimemap;
39
50
 
 
51
#ifndef MINIBUILD
 
52
 
40
53
MapNameToString n2sTbl[] = {
41
54
                {  "Port",                      &port , 0}
42
55
                ,{ "CacheDir",  &cachedir, 0 }
54
67
                ,{ "DontCache", &dontcache, 0}
55
68
                ,{ "DontCacheRequested",        &dontcachetgt, 0}
56
69
                ,{ "DontCacheResolved", &dontcacherq, 0}
 
70
                ,{ "PrecacheFor", &mirrorsrcs, 0}
 
71
                ,{ "RequestAppendix", &requestapx, 0}
57
72
};
58
73
 
59
74
MapNameToInt n2iTbl[] = {
83
98
                ,{ "FilePerms", &fileperms, 0, 8}
84
99
};
85
100
 
86
 
#define _iterPos(it, start) (it-start.begin())/sizeof(it)
87
 
#define sProblemLoc szPath<< ':'<< _iterPos(it, lines)
88
 
 
89
 
string sFilterSet(SPACECHARS "#");
90
 
#define IsValidButIrrelevantLine(x) (x.empty() || stmiss != sFilterSet.find(x[0]))
91
 
#define BARF(x) { cerr << x << endl; exit(EXIT_FAILURE); }
92
 
 
93
101
void _ReadRewriteFiles(const string & sFile, const string & sRepName);
94
102
void _ReadBackendsFiles(const string & sFile, const string &sRepName);
95
103
 
105
113
typedef tMapUrl2StringPtr::iterator tUrl2RepIter;
106
114
tMapUrl2StringPtr mapUrl2pVname;
107
115
 
108
 
typedef map<const string, tHostiVec> tMapString2Hostivec;
109
 
tMapString2Hostivec mapRepName2Backends;
 
116
typedef map<const string, tRepoData> tRepMap;
 
117
tRepMap repoparms;
110
118
 
111
 
string * _GetStringPtr(const string &key)  {
112
 
        for(unsigned int i=0; i<_countof(n2sTbl); i++) {
 
119
string * _GetStringPtr(const string &key) {
 
120
        for(unsigned int i=0; i<_countof(n2sTbl); i++)
 
121
        {
113
122
                if(0==strcasecmp(key.c_str(), n2sTbl[i].name))
114
123
                {
115
124
                        if(n2sTbl[i].warn)
121
130
        return NULL;
122
131
}
123
132
 
124
 
int * _GetIntPtr(const string &key, int &base)  {
125
 
        for(unsigned int i=0; i<_countof(n2iTbl); i++) {
 
133
int * _GetIntPtr(const string &key, int &base) {
 
134
        for(unsigned int i=0; i<_countof(n2iTbl); i++)
 
135
        {
126
136
                if(0==strcasecmp(key.c_str(), n2iTbl[i].name))
127
137
                {
128
138
                        if(n2iTbl[i].warn)
149
159
        filereader reader;
150
160
        reader.OpenFile(szFilename);
151
161
        reader.CheckGoodState(true);
152
 
        string sLine, key, val;
 
162
        string sLine;
153
163
        for (bool bNotEof=true; bNotEof;)
154
164
        {
155
165
                bNotEof=reader.GetOneLine(sLine);
158
168
#ifdef DEBUG
159
169
                cerr << sLine <<endl;
160
170
#endif
 
171
                tStrPos pos=sLine.find('#');
 
172
                if(stmiss != pos)
 
173
                        sLine.erase(pos);
 
174
 
161
175
                if(! SetOption(sLine))
162
176
                        BARF("Error reading main options, terminating.");
163
 
                // XXX: move that to SetOption... if (debug>4)
164
 
                //      cout << key << " -> "<< val <<endl;
165
 
        }
166
 
        return true;
167
 
}
168
 
 
169
 
const string * _CheckBEentryGetNamePtr(const string & sRepName)
170
 
{
171
 
        // needs a reliably stored string for the pointer. Backend description may not exist,
172
 
        // then create a dummy one with no contents and point at this string. Iterators on map are
173
 
        // guaranteed to be stable so point at its key variable.
174
 
        tMapString2Hostivec::iterator
175
 
                        itHostiVec = mapRepName2Backends.find(sRepName);
176
 
        if (itHostiVec == mapRepName2Backends.end())
177
 
        {
178
 
                mapRepName2Backends[sRepName]=tHostiVec(0);
179
 
                itHostiVec=mapRepName2Backends.find(sRepName); // must refer to that string on the heap
180
 
                if (debug>4)
181
 
                        cout << "created empty backend entry for "<< sRepName <<endl;
182
 
        }
183
 
        return & itHostiVec->first;
184
 
}
185
 
 
186
 
inline void _AddRemapInfo(bool bAsBackend, const string & token,
 
177
        }
 
178
        return true;
 
179
}
 
180
 
 
181
inline const string * GetRepoEntryNamePtr(const string & sRepName)
 
182
{
 
183
        // save some memory by storing only pointer to its entry in the map since the life time is guaranteed
 
184
 
 
185
        tRepMap::iterator it = repoparms.find(sRepName);
 
186
        if(repoparms.end() == it)
 
187
        {
 
188
                repoparms[sRepName] = tRepoData();
 
189
                it = repoparms.find(sRepName);
 
190
        }
 
191
        return & it->first;
 
192
}
 
193
 
 
194
inline bool ParseOptionLine(const string &sLine, string &key, string &val, bool bQuiet)
 
195
{
 
196
        string::size_type posCol = sLine.find(":");
 
197
        string::size_type posEq = sLine.find("=");
 
198
        if (posEq==stmiss && posCol==stmiss)
 
199
        {
 
200
                if(!bQuiet)
 
201
                        cerr << "Not a valid configuration directive: " << sLine <<endl;
 
202
                return false;
 
203
        }
 
204
        string::size_type pos;
 
205
        if (posEq!=stmiss && posCol!=stmiss)
 
206
                pos=min(posEq,posCol);
 
207
        else if (posEq!=stmiss)
 
208
                pos=posEq;
 
209
        else
 
210
                pos=posCol;
 
211
 
 
212
        key=sLine.substr(0, pos);
 
213
        val=sLine.substr(pos+1);
 
214
        trimString(key);
 
215
        trimString(val);
 
216
        if(key.empty())
 
217
                return false; // weird
 
218
 
 
219
        return true;
 
220
}
 
221
 
 
222
 
 
223
inline void AddRemapFlag(const string & token, const string &repname)
 
224
{
 
225
        mstring key, value;
 
226
        if(!ParseOptionLine(token, key, value, true))
 
227
                return;
 
228
 
 
229
        if(key=="keyfile" && !value.empty())
 
230
        {
 
231
                //if(!startsWithSz(value, "/"))
 
232
                //      value.insert(0, "/");
 
233
                if (acfg::debug>3)
 
234
                        cerr << "Fatal keyfile for " <<repname<<": "<<value <<endl;
 
235
 
 
236
                tRepoData &where = repoparms[repname];
 
237
                where.m_keyfiles.push_back(value);
 
238
        }
 
239
}
 
240
 
 
241
inline void AddRemapInfo(bool bAsBackend, const string & token,
187
242
                const string &repname)
188
243
{
189
244
        if (0!=token.compare(0, 5, "file:"))
193
248
                        BARF(token + " <-- bad URL detected");
194
249
                _FixPostPreSlashes(url.sPath);
195
250
                
 
251
                if(url.sPort.empty())
 
252
                        url.sPort = remoteport;
 
253
 
196
254
                if (bAsBackend)
197
 
                        mapRepName2Backends[repname].push_back(url);
 
255
                        repoparms[repname].m_backends.push_back(url);
198
256
                else
199
257
                        mapUrl2pVname.insert(pair<tHttpUrl,const string*>(
200
 
                                        url, _CheckBEentryGetNamePtr(repname)));
 
258
                                        url, GetRepoEntryNamePtr(repname)));
201
259
        }
202
260
        else
203
261
        {
218
276
        }
219
277
}
220
278
 
221
 
inline string _GetBase64Auth(const string & sUserColonPass)
222
 
{
223
 
        int cols, bits, c, char_count;
224
 
 
225
 
        char_count = 0;
226
 
        bits = 0;
227
 
        cols = 0;
228
 
        tStrPos pos(0);
 
279
struct tHookHandler: public tRepoData::IHookHandler, public lockable
 
280
{
 
281
        string cmdRel, cmdCon;
 
282
        time_t downDuration, downTimeNext;
 
283
 
 
284
        int m_nRefCnt;
 
285
 
 
286
        tHookHandler(cmstring&) :
 
287
                downDuration(30), downTimeNext(0), m_nRefCnt(0)
 
288
        {
 
289
//              cmdRel = "logger JobRelease/" + name;
 
290
//              cmdCon = "logger JobConnect/" + name;
 
291
        }
 
292
        virtual void JobRelease()
 
293
        {
 
294
                setLockGuard;
 
295
                if (0 >= --m_nRefCnt)
 
296
                {
 
297
                        //system(cmdRel.c_str());
 
298
                        downTimeNext= time(0) + downDuration;
 
299
                }
 
300
        }
 
301
        virtual void JobConnect()
 
302
        {
 
303
                setLockGuard;
 
304
                if (0 == m_nRefCnt++)
 
305
                {
 
306
                        if(downTimeNext) // huh, already ticking? reset
 
307
                                downTimeNext=0;
 
308
                        else
 
309
                                system(cmdCon.c_str());
 
310
                }
 
311
        }
 
312
};
 
313
 
 
314
void _AddHooksFile(cmstring& vname)
 
315
{
 
316
        filereader reader;
 
317
        if(!reader.OpenFile(acfg::confdir+"/"+vname+".hooks"))
 
318
                return;
 
319
 
 
320
        string sLine, key, val;
 
321
        struct tHookHandler &hs = *(new tHookHandler(vname));
 
322
 
 
323
        for (bool bNotEof=true; bNotEof;)
 
324
        {
 
325
                bNotEof=reader.GetOneLine(sLine);
 
326
                if (IsValidButIrrelevantLine(sLine))
 
327
                        continue;
 
328
 
 
329
                if(!ParseOptionLine(sLine, key, val, false))
 
330
                        continue;
 
331
                const char *p=key.c_str();
 
332
                if(strcasecmp("PreUp", p) == 0)
 
333
                {
 
334
                        hs.cmdCon = val;
 
335
                }
 
336
                else if(strcasecmp("Down", p) == 0)
 
337
                {
 
338
                        hs.cmdRel = val;
 
339
                }
 
340
                else if(strcasecmp("DownTimeout", p) == 0)
 
341
                {
 
342
                        errno=0;
 
343
                        uint n = strtoul(val.c_str(), NULL, 10);
 
344
                        if(!errno)
 
345
                                hs.downDuration = n;
 
346
                }
 
347
        }
 
348
        repoparms[vname].m_pHooks = &hs;
 
349
 
 
350
}
 
351
 
 
352
string _GetBase64Auth(const string & s)
 
353
{
 
354
        int cols=0, bits=0, c=0, char_count=0;
 
355
        tStrPos pos=0;
229
356
        string out;
230
 
        while ( pos<sUserColonPass.size())
 
357
        while ( pos<s.size() )
231
358
        {
232
 
                c=sUserColonPass[pos++];
 
359
                c=s[pos++];
 
360
                if('%' == c && pos<s.length()-1
 
361
                                && hexmap[(unsigned)s[pos]]<=15
 
362
                                && hexmap[(unsigned)s[pos+1]]<=15)
 
363
                {
 
364
                        c=char(16*hexmap[(unsigned)s[pos]]+hexmap[(unsigned)s[pos+1]]);
 
365
                        pos+=2;
 
366
                }
233
367
                bits += c;
234
368
                char_count++;
235
369
                if (char_count == 3)
266
400
        return out;
267
401
}
268
402
 
 
403
inline void _ParseLocalDirs(cmstring &value)
 
404
{
 
405
        tStrVec tokens;
 
406
        Tokenize(value, ";", tokens);
 
407
        for(tStrVecIter it=tokens.begin(); it!=tokens.end(); it++)
 
408
        {
 
409
                trimString(*it);
 
410
                tStrPos pos = it->find_first_of(SPACECHARS);
 
411
                if(stmiss == pos)
 
412
                {
 
413
                        cerr << "Cannot map " << *it << ", needed format: virtualdir realdir, ignoring it";
 
414
                        continue;
 
415
                }
 
416
                string from=it->substr(0, pos);
 
417
                trimString(from, "/");
 
418
                string what=it->substr(pos);
 
419
                trimString(what, SPACECHARS "'\"");
 
420
                if(what.empty())
 
421
                {
 
422
                        cerr << "Unsupported target of " << from << ": " << what << ", ignoring it" << endl;
 
423
                        continue;
 
424
                }
 
425
                localdirs[from]=what;
 
426
        }
 
427
}
 
428
 
 
429
inline void _FetchMimeTypes()
 
430
{
 
431
        filereader mreader;
 
432
        tStrVec toks;
 
433
        string line;
 
434
        for(mreader.OpenFile("/etc/mime.types"); mreader.CheckGoodState(false); )
 
435
        {
 
436
                if(!mreader.GetOneLine(line))
 
437
                        break;
 
438
                if(IsValidButIrrelevantLine(line))
 
439
                        continue;
 
440
 
 
441
                if(Tokenize(line, SPACECHARS, toks, false)>1)
 
442
                {
 
443
                        for(UINT i=1; i<toks.size();i++)
 
444
                                mimemap[toks[i]]=toks[0];
 
445
                }
 
446
        }
 
447
}
 
448
 
269
449
bool SetOption(const string &sLine, bool bQuiet)
270
450
{
271
 
        string::size_type posCol = sLine.find(":");
272
 
        string::size_type posEq = sLine.find("=");
273
 
        if (posEq==stmiss && posCol==stmiss)
274
 
        {
275
 
                if(!bQuiet)
276
 
                        cerr << "Not a valid configuration directive: " << sLine <<endl;
 
451
 
 
452
        string key, value;
 
453
 
 
454
        if(!ParseOptionLine(sLine, key, value, bQuiet))
277
455
                return false;
278
 
        }
279
 
        string::size_type pos;
280
 
        if (posEq!=stmiss && posCol!=stmiss)
281
 
                pos=min(posEq,posCol);
282
 
        else if (posEq!=stmiss)
283
 
                pos=posEq;
284
 
        else
285
 
                pos=posCol;
286
456
 
287
 
        string key=sLine.substr(0, pos);
288
 
        string value=sLine.substr(pos+1);
289
 
        trimString(key);
290
 
        trimString(value);
291
 
        if(key.empty())
292
 
                return false; // weird
293
 
        
294
457
        string * psTarget;
295
458
        int * pnTarget;
296
459
        int nNumBase(10);
338
501
                        cerr << "Invalid proxy specification, aborting..." << endl;
339
502
                        exit(EXIT_FAILURE);
340
503
                }
341
 
                tStrPos pos = proxy_info.sHost.find('@');
 
504
                tStrPos pos = proxy_info.sHost.rfind('@');
342
505
                if (stmiss != pos)
343
506
                {
 
507
                        tStrPos pwStart= startsWithSz(value, "http://") ? 7 : 0;
344
508
                        proxy_info.sPath = string("Proxy-Authorization: Basic ")
345
 
                                        + _GetBase64Auth(value.substr(0, pos)) + "\r\n";
 
509
                                        + _GetBase64Auth(value.substr(pwStart, pos)) + "\r\n";
346
510
                        proxy_info.sHost.erase(0, pos + 1);
347
511
                }
348
512
                else
369
533
        }
370
534
        else if(0==strcasecmp(key.c_str(), "LocalDirs"))
371
535
        {
372
 
                tStrVec tokens;
373
 
                Tokenize(value, ";", tokens);
374
 
                for(tStrVecIter it=tokens.begin(); it!=tokens.end(); it++)
375
 
                {
376
 
                        trimString(*it);
377
 
                        tStrPos pos = it->find_first_of(SPACECHARS);
378
 
                        if(stmiss == pos)
379
 
                        {
380
 
                                cerr << "Cannot map " << *it << ", needed format: virtualdir realdir, ignoring it";
381
 
                                continue;
382
 
                        }
383
 
                        string from=it->substr(0, pos);
384
 
                        trimString(from, "/");
385
 
                        string what=it->substr(pos);
386
 
                        trimString(what, SPACECHARS "'\"");
387
 
                        if(what.empty())
388
 
                        {
389
 
                                cerr << "Unsupported target of " << from << ": " << what << ", ignoring it" << endl;
390
 
                                continue;
391
 
                        }
392
 
                        localdirs[from]=what;
393
 
                }
394
 
 
395
 
                filereader mreader;
396
 
                tStrVec toks;
397
 
                string line;
398
 
                for(mreader.OpenFile("/etc/mime.types"); mreader.CheckGoodState(false); )
399
 
                {
400
 
                        if(!mreader.GetOneLine(line))
401
 
                                break;
402
 
                        if(IsValidButIrrelevantLine(line))
403
 
                                continue;
404
 
 
405
 
                        if(Tokenize(line, SPACECHARS, toks, false)>1)
406
 
                        {
407
 
                                for(UINT i=1; i<toks.size();i++)
408
 
                                        mimemap[toks[i]]=toks[0];
409
 
                        }
410
 
                }
411
 
 
 
536
                _ParseLocalDirs(value);
 
537
                _FetchMimeTypes();
412
538
                return !localdirs.empty();
413
539
        }
414
540
        else if(0==strncasecmp(key.c_str(), "Remap-", 6))
423
549
                                cerr << "Found invalid entry, ignoring " << key << ": " << value <<endl;
424
550
                        return false;
425
551
                }
426
 
                bool bIsBackend=false;
427
 
                for(UINT i=0; i<tokens.size(); i++)
 
552
                int type(0); // prefixes ; backends ; flags
 
553
                for(tStrVecIterConst it=tokens.begin(); it!=tokens.end(); ++it)
428
554
                {
429
 
                        if(tokens[i]==";")
430
 
                        {
431
 
                                bIsBackend=true;
 
555
                        if(it->empty())
432
556
                                continue;
433
 
                        }
434
 
                        if(startsWithSz(tokens[i], "#"))
 
557
                        if(it->at(0)=='#')
435
558
                                break;
436
 
                        _AddRemapInfo(bIsBackend, tokens[i], vname);
 
559
 
 
560
                        if(it->at(0)==';')
 
561
                                ++type;
 
562
                        else if(0 == type)
 
563
                                AddRemapInfo(false, *it, vname);
 
564
                        else if(1 == type)
 
565
                                AddRemapInfo(true, *it, vname);
 
566
                        else if(2 == type)
 
567
                                AddRemapFlag(*it, vname);
437
568
                }
438
 
                
 
569
                _AddHooksFile(vname);
439
570
        }
440
571
        else
441
572
        {
452
583
{
453
584
        sRetPathResidual.clear();
454
585
        
 
586
        // get all the URLs matching THE HOSTNAME
455
587
        pair<tUrl2RepIter,tUrl2RepIter> range=mapUrl2pVname.equal_range(in);
456
588
        if(range.first==range.second)
457
589
                return NULL;
459
591
        tStrPos bestMatchLen(0);
460
592
        string const * psBestHit(NULL);
461
593
                
 
594
        // now find the longest directory part which is the suffix of requested URL's path
462
595
        for (tUrl2RepIter & it=range.first; it!=range.second; it++)
463
596
        {
464
597
                // rewrite rule path must be a real prefix
480
613
        
481
614
}
482
615
 
483
 
tHostiVec * GetBackendVec(const string * vname)
 
616
const tRepoData * GetBackendVec(const string * vname)
484
617
{
485
618
        if(!vname)
486
619
                return NULL;
487
 
        tMapString2Hostivec::iterator it=mapRepName2Backends.find(*vname);
488
 
        if(it==mapRepName2Backends.end() || it->second.empty())
 
620
        tRepMap::iterator it=repoparms.find(*vname);
 
621
        if(it==repoparms.end() || it->second.m_backends.empty())
489
622
                return NULL;
490
623
        return & it->second;
491
624
}
531
664
                        cerr << "Backend: " << sRepName << " <-- " << entry.ToURI() <<endl;
532
665
#endif          
533
666
 
534
 
                        mapRepName2Backends[sRepName].push_back(entry);
 
667
                        if(entry.sPort.empty())
 
668
                                entry.sPort = remoteport;
 
669
 
 
670
                        repoparms[sRepName].m_backends.push_back(entry);
535
671
                        nAddCount++;
536
672
                        entry.clear();
537
673
                }
578
714
void ShutDown()
579
715
{
580
716
        mapUrl2pVname.clear();
581
 
        mapRepName2Backends.clear();
 
717
        repoparms.clear();
582
718
}
583
719
 
584
720
void _ReadRewriteFiles(const string & sFile, const string & sRepName)
605
741
                        {
606
742
                                _FixPostPreSlashes(url.sPath);
607
743
                                pair<tHttpUrl, const string*> info(url,
608
 
                                                _CheckBEentryGetNamePtr(sRepName));
 
744
                                                GetRepoEntryNamePtr(sRepName));
609
745
                                mapUrl2pVname.insert(info);
610
746
                        }
611
747
                        else
643
779
                                        tHttpUrl url;
644
780
                                        url.sHost=*itHost;
645
781
                                        url.sPath=*itPath;
646
 
                                        pair<tHttpUrl,const string*> info(url, _CheckBEentryGetNamePtr(sRepName));
 
782
                                        pair<tHttpUrl,const string*> info(url, GetRepoEntryNamePtr(sRepName));
647
783
                                        mapUrl2pVname.insert(info);
648
784
 
649
785
#ifdef DEBUG
682
818
}
683
819
 
684
820
 
 
821
tRepoData::~tRepoData()
 
822
{
 
823
        if(m_pHooks)
 
824
        {
 
825
                delete m_pHooks;
 
826
                m_pHooks=NULL;
 
827
        }
 
828
}
685
829
 
686
830
void ReadConfigDirectory(const char *szPath)
687
831
{
762
906
        for(tStrPos pos; stmiss != (pos = cachedir.find(SZPATHSEP SZPATHSEP )); )
763
907
                cachedir.erase(pos, 1);
764
908
 
 
909
        cacheDirSlash=cachedir+CPATHSEP;
 
910
 
765
911
   if(!pidfile.empty() && pidfile.at(0) != CPATHSEP)
766
912
   {
767
913
           cerr << "Pid file path must be absolute, terminating..."  <<endl;
842
988
                   const_cast<string&>(suc->first.sPath)=it->first.sPath;
843
989
   }
844
990
   */
845
 
}
846
 
}
 
991
 
 
992
#if 0 //def DEBUG
 
993
#warning adding hook control pins
 
994
   for(tMapString2Hostivec::iterator it = repoparms.begin();
 
995
                   it!=repoparms.end() ; ++it)
 
996
   {
 
997
           tHookHandler *p = new tHookHandler(it->first);
 
998
           p->downDuration=10;
 
999
           p->cmdCon = "logger wanna/connect";
 
1000
           p->cmdRel = "logger wanna/disconnect";
 
1001
           it->second.m_pHooks = p;
 
1002
   }
 
1003
#endif
 
1004
 
 
1005
   if(debug == -42)
 
1006
   {
 
1007
           /*
 
1008
           for(tMapString2Hostivec::const_iterator it=mapRepName2Backends.begin();
 
1009
                           it!=mapRepName2Backends.end(); it++)
 
1010
           {
 
1011
                   for(tRepoData::const_iterator jit=it->second.begin();
 
1012
                                   jit != it->second.end(); jit++)
 
1013
                   {
 
1014
                           cout << jit->ToURI() <<endl;
 
1015
                   }
 
1016
           }
 
1017
           */
 
1018
           for(tUrl2RepIter it=mapUrl2pVname.begin(); it!=mapUrl2pVname.end(); it++)
 
1019
           {
 
1020
                   cout << it->first.ToURI() << " ___" << *(it->second) << endl;
 
1021
           }
 
1022
 
 
1023
           exit(1);
 
1024
   }
 
1025
} // PostProcConfig
 
1026
 
 
1027
time_t ExecutePostponed()
 
1028
{
 
1029
        time_t ret(cleaner::never), now(time(0));
 
1030
        for (tRepMap::iterator it = repoparms.begin(); it != repoparms.end(); ++it)
 
1031
        {
 
1032
                if (!it->second.m_pHooks)
 
1033
                        continue;
 
1034
                tHookHandler & hooks = *(static_cast<tHookHandler*> (it->second.m_pHooks));
 
1035
                lockguard g(hooks);
 
1036
                if (hooks.downTimeNext)
 
1037
                {
 
1038
                        if (hooks.downTimeNext <= now) // time to execute
 
1039
                        {
 
1040
                                if(acfg::debug>1)
 
1041
                                        aclog::misc(hooks.cmdRel, 'X');
 
1042
                                if(acfg::debug>3)
 
1043
                                        aclog::flush();
 
1044
 
 
1045
                                system(hooks.cmdRel.c_str());
 
1046
                                hooks.downTimeNext = 0;
 
1047
                        }
 
1048
                        else // in future, use the soonest time
 
1049
                                ret = min(ret, hooks.downTimeNext);
 
1050
                }
 
1051
        }
 
1052
        return ret;
 
1053
}
 
1054
 
 
1055
#endif // MINIBUILD
 
1056
 
 
1057
} // namespace acfg
847
1058
 
848
1059
namespace rechecks
849
1060
{
850
 
regex_t reIfiles, rePfiles, reWfiles;
851
 
deque<regex_t> vecReqPatters, vecTgtPatterns;
 
1061
        const UINT rexCount = 3;
 
1062
        regex_t rex[rexCount];
852
1063
 
853
1064
bool CompileExpressions()
854
1065
{
855
 
        //printf("%s\\n%s\\n", a, b);
856
 
 
857
 
    if(regcomp(&rePfiles, acfg::pfilepat.c_str(), REG_EXTENDED))
858
 
        return false;
859
 
    if(regcomp(&reIfiles, acfg::vfilepat.c_str(), REG_EXTENDED))
860
 
        return false;
861
 
    if(regcomp(&reWfiles, acfg::wfilepat.c_str(), REG_EXTENDED))
862
 
        return false;
863
 
 
864
 
    return true;
 
1066
        cmstring *psRex[rexCount] = {&acfg::vfilepat, &acfg::pfilepat, &acfg::wfilepat};
 
1067
        for(UINT i=0; i<rexCount; i++)
 
1068
        {
 
1069
                int nErr=regcomp(&rex[i], psRex[i]->c_str(), REG_EXTENDED);
 
1070
                if(nErr)
 
1071
                {
 
1072
                        char buf[1024];
 
1073
                        regerror(nErr,  &rex[i], buf, sizeof(buf));
 
1074
                        buf[_countof(buf)-1]=0; // better be safe...
 
1075
                        std::cerr << buf << ": " << *(psRex[i]) << std::endl;
 
1076
                        return false;
 
1077
                }
 
1078
        }
 
1079
        return true;
865
1080
}
866
1081
 
867
1082
eFileKind GetFiletype(const string & in) {
868
1083
        //LOGSTART("rechecks::getFiletype");
869
1084
    //dbgline;
870
 
    if(!regexec(&reIfiles, in.c_str(), 0, NULL, 0))
 
1085
    if(!regexec(&rex[0], in.c_str(), 0, NULL, 0))
871
1086
        return FILE_INDEX;
872
1087
    //dbgline;
873
 
    if(!regexec(&rePfiles, in.c_str(), 0, NULL, 0))
 
1088
    if(!regexec(&rex[1], in.c_str(), 0, NULL, 0))
874
1089
        return FILE_PKG;
875
1090
    //dbgline;
876
1091
    return FILE_INVALID;
879
1094
bool MatchWhitelist(const string & in)
880
1095
{
881
1096
        LOGSTART("MatchWhiteList");
882
 
        bool bPersistent=!regexec(&reWfiles, in.c_str(), 0, NULL, 0);
 
1097
        bool bPersistent=!regexec(&rex[2], in.c_str(), 0, NULL, 0);
883
1098
        LOG(in <<" is " << (bPersistent ? "persistent" : "mortal") <<  " file");
884
1099
        return bPersistent;
885
1100
}
886
1101
 
 
1102
deque<regex_t> vecReqPatters, vecTgtPatterns;
 
1103
 
 
1104
#ifndef MINIBUILD
887
1105
inline bool CompileUncachedRex(const string & token, bool bIsTgtPattern, bool bRecursiveCall)
888
1106
{
889
1107
        deque<regex_t> & patvec = bIsTgtPattern ? vecTgtPatterns : vecReqPatters;
970
1188
        return false;
971
1189
}
972
1190
 
 
1191
#endif //MINIBUILD
 
1192
 
 
1193
 
 
1194
} // namespace rechecks
 
1195
 
 
1196
mstring GetDirPart(const string &in)
 
1197
{
 
1198
        if(in.empty())
 
1199
                return "";
 
1200
 
 
1201
        tStrPos end = in.find_last_of(CPATHSEP);
 
1202
        if(end == stmiss) // none? don't care then
 
1203
                return "";
 
1204
 
 
1205
        return in.substr(0, end+1);
973
1206
}
974
1207
 
975
1208
void mkbasedir(const string & path)
976
1209
{
977
 
    for(UINT pos=0; pos<path.size(); pos=path.find("/", pos+1))
 
1210
        if(0==mkdir(GetDirPart(path).c_str(), acfg::dirperms) || EEXIST == errno)
 
1211
                return; // should succeed in most cases
 
1212
 
 
1213
        UINT pos=0; // but skip the cache dir components, if possible
 
1214
        if(startsWith(path, acfg::cacheDirSlash))
 
1215
        {
 
1216
                // pos=acfg::cachedir.size();
 
1217
                pos=path.find("/", acfg::cachedir.size()+1);
 
1218
        }
 
1219
    for(; pos<path.size(); pos=path.find(SZPATHSEP, pos+1))
978
1220
    {
979
1221
        if(pos>0)
980
1222
            mkdir(path.substr(0,pos).c_str(), acfg::dirperms);
981
1223
    }
982
1224
}
 
1225
 
 
1226
 
983
1227
/*
984
1228
int main(int argc, char **argv)
985
1229
{