54
67
,{ "DontCache", &dontcache, 0}
55
68
,{ "DontCacheRequested", &dontcachetgt, 0}
56
69
,{ "DontCacheResolved", &dontcacherq, 0}
70
,{ "PrecacheFor", &mirrorsrcs, 0}
71
,{ "RequestAppendix", &requestapx, 0}
59
74
MapNameToInt n2iTbl[] = {
83
98
,{ "FilePerms", &fileperms, 0, 8}
86
#define _iterPos(it, start) (it-start.begin())/sizeof(it)
87
#define sProblemLoc szPath<< ':'<< _iterPos(it, lines)
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); }
93
101
void _ReadRewriteFiles(const string & sFile, const string & sRepName);
94
102
void _ReadBackendsFiles(const string & sFile, const string &sRepName);
105
113
typedef tMapUrl2StringPtr::iterator tUrl2RepIter;
106
114
tMapUrl2StringPtr mapUrl2pVname;
108
typedef map<const string, tHostiVec> tMapString2Hostivec;
109
tMapString2Hostivec mapRepName2Backends;
116
typedef map<const string, tRepoData> tRepMap;
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++)
113
122
if(0==strcasecmp(key.c_str(), n2sTbl[i].name))
115
124
if(n2sTbl[i].warn)
159
169
cerr << sLine <<endl;
171
tStrPos pos=sLine.find('#');
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;
169
const string * _CheckBEentryGetNamePtr(const string & sRepName)
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())
178
mapRepName2Backends[sRepName]=tHostiVec(0);
179
itHostiVec=mapRepName2Backends.find(sRepName); // must refer to that string on the heap
181
cout << "created empty backend entry for "<< sRepName <<endl;
183
return & itHostiVec->first;
186
inline void _AddRemapInfo(bool bAsBackend, const string & token,
181
inline const string * GetRepoEntryNamePtr(const string & sRepName)
183
// save some memory by storing only pointer to its entry in the map since the life time is guaranteed
185
tRepMap::iterator it = repoparms.find(sRepName);
186
if(repoparms.end() == it)
188
repoparms[sRepName] = tRepoData();
189
it = repoparms.find(sRepName);
194
inline bool ParseOptionLine(const string &sLine, string &key, string &val, bool bQuiet)
196
string::size_type posCol = sLine.find(":");
197
string::size_type posEq = sLine.find("=");
198
if (posEq==stmiss && posCol==stmiss)
201
cerr << "Not a valid configuration directive: " << sLine <<endl;
204
string::size_type pos;
205
if (posEq!=stmiss && posCol!=stmiss)
206
pos=min(posEq,posCol);
207
else if (posEq!=stmiss)
212
key=sLine.substr(0, pos);
213
val=sLine.substr(pos+1);
217
return false; // weird
223
inline void AddRemapFlag(const string & token, const string &repname)
226
if(!ParseOptionLine(token, key, value, true))
229
if(key=="keyfile" && !value.empty())
231
//if(!startsWithSz(value, "/"))
232
// value.insert(0, "/");
234
cerr << "Fatal keyfile for " <<repname<<": "<<value <<endl;
236
tRepoData &where = repoparms[repname];
237
where.m_keyfiles.push_back(value);
241
inline void AddRemapInfo(bool bAsBackend, const string & token,
187
242
const string &repname)
189
244
if (0!=token.compare(0, 5, "file:"))
221
inline string _GetBase64Auth(const string & sUserColonPass)
223
int cols, bits, c, char_count;
279
struct tHookHandler: public tRepoData::IHookHandler, public lockable
281
string cmdRel, cmdCon;
282
time_t downDuration, downTimeNext;
286
tHookHandler(cmstring&) :
287
downDuration(30), downTimeNext(0), m_nRefCnt(0)
289
// cmdRel = "logger JobRelease/" + name;
290
// cmdCon = "logger JobConnect/" + name;
292
virtual void JobRelease()
295
if (0 >= --m_nRefCnt)
297
//system(cmdRel.c_str());
298
downTimeNext= time(0) + downDuration;
301
virtual void JobConnect()
304
if (0 == m_nRefCnt++)
306
if(downTimeNext) // huh, already ticking? reset
309
system(cmdCon.c_str());
314
void _AddHooksFile(cmstring& vname)
317
if(!reader.OpenFile(acfg::confdir+"/"+vname+".hooks"))
320
string sLine, key, val;
321
struct tHookHandler &hs = *(new tHookHandler(vname));
323
for (bool bNotEof=true; bNotEof;)
325
bNotEof=reader.GetOneLine(sLine);
326
if (IsValidButIrrelevantLine(sLine))
329
if(!ParseOptionLine(sLine, key, val, false))
331
const char *p=key.c_str();
332
if(strcasecmp("PreUp", p) == 0)
336
else if(strcasecmp("Down", p) == 0)
340
else if(strcasecmp("DownTimeout", p) == 0)
343
uint n = strtoul(val.c_str(), NULL, 10);
348
repoparms[vname].m_pHooks = &hs;
352
string _GetBase64Auth(const string & s)
354
int cols=0, bits=0, c=0, char_count=0;
230
while ( pos<sUserColonPass.size())
357
while ( pos<s.size() )
232
c=sUserColonPass[pos++];
360
if('%' == c && pos<s.length()-1
361
&& hexmap[(unsigned)s[pos]]<=15
362
&& hexmap[(unsigned)s[pos+1]]<=15)
364
c=char(16*hexmap[(unsigned)s[pos]]+hexmap[(unsigned)s[pos+1]]);
235
369
if (char_count == 3)
403
inline void _ParseLocalDirs(cmstring &value)
406
Tokenize(value, ";", tokens);
407
for(tStrVecIter it=tokens.begin(); it!=tokens.end(); it++)
410
tStrPos pos = it->find_first_of(SPACECHARS);
413
cerr << "Cannot map " << *it << ", needed format: virtualdir realdir, ignoring it";
416
string from=it->substr(0, pos);
417
trimString(from, "/");
418
string what=it->substr(pos);
419
trimString(what, SPACECHARS "'\"");
422
cerr << "Unsupported target of " << from << ": " << what << ", ignoring it" << endl;
425
localdirs[from]=what;
429
inline void _FetchMimeTypes()
434
for(mreader.OpenFile("/etc/mime.types"); mreader.CheckGoodState(false); )
436
if(!mreader.GetOneLine(line))
438
if(IsValidButIrrelevantLine(line))
441
if(Tokenize(line, SPACECHARS, toks, false)>1)
443
for(UINT i=1; i<toks.size();i++)
444
mimemap[toks[i]]=toks[0];
269
449
bool SetOption(const string &sLine, bool bQuiet)
271
string::size_type posCol = sLine.find(":");
272
string::size_type posEq = sLine.find("=");
273
if (posEq==stmiss && posCol==stmiss)
276
cerr << "Not a valid configuration directive: " << sLine <<endl;
454
if(!ParseOptionLine(sLine, key, value, bQuiet))
279
string::size_type pos;
280
if (posEq!=stmiss && posCol!=stmiss)
281
pos=min(posEq,posCol);
282
else if (posEq!=stmiss)
287
string key=sLine.substr(0, pos);
288
string value=sLine.substr(pos+1);
292
return false; // weird
294
457
string * psTarget;
296
459
int nNumBase(10);
338
501
cerr << "Invalid proxy specification, aborting..." << endl;
339
502
exit(EXIT_FAILURE);
341
tStrPos pos = proxy_info.sHost.find('@');
504
tStrPos pos = proxy_info.sHost.rfind('@');
342
505
if (stmiss != pos)
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);
370
534
else if(0==strcasecmp(key.c_str(), "LocalDirs"))
373
Tokenize(value, ";", tokens);
374
for(tStrVecIter it=tokens.begin(); it!=tokens.end(); it++)
377
tStrPos pos = it->find_first_of(SPACECHARS);
380
cerr << "Cannot map " << *it << ", needed format: virtualdir realdir, ignoring it";
383
string from=it->substr(0, pos);
384
trimString(from, "/");
385
string what=it->substr(pos);
386
trimString(what, SPACECHARS "'\"");
389
cerr << "Unsupported target of " << from << ": " << what << ", ignoring it" << endl;
392
localdirs[from]=what;
398
for(mreader.OpenFile("/etc/mime.types"); mreader.CheckGoodState(false); )
400
if(!mreader.GetOneLine(line))
402
if(IsValidButIrrelevantLine(line))
405
if(Tokenize(line, SPACECHARS, toks, false)>1)
407
for(UINT i=1; i<toks.size();i++)
408
mimemap[toks[i]]=toks[0];
536
_ParseLocalDirs(value);
412
538
return !localdirs.empty();
414
540
else if(0==strncasecmp(key.c_str(), "Remap-", 6))
423
549
cerr << "Found invalid entry, ignoring " << key << ": " << value <<endl;
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)
434
if(startsWithSz(tokens[i], "#"))
436
_AddRemapInfo(bIsBackend, tokens[i], vname);
563
AddRemapInfo(false, *it, vname);
565
AddRemapInfo(true, *it, vname);
567
AddRemapFlag(*it, vname);
569
_AddHooksFile(vname);
842
988
const_cast<string&>(suc->first.sPath)=it->first.sPath;
993
#warning adding hook control pins
994
for(tMapString2Hostivec::iterator it = repoparms.begin();
995
it!=repoparms.end() ; ++it)
997
tHookHandler *p = new tHookHandler(it->first);
999
p->cmdCon = "logger wanna/connect";
1000
p->cmdRel = "logger wanna/disconnect";
1001
it->second.m_pHooks = p;
1008
for(tMapString2Hostivec::const_iterator it=mapRepName2Backends.begin();
1009
it!=mapRepName2Backends.end(); it++)
1011
for(tRepoData::const_iterator jit=it->second.begin();
1012
jit != it->second.end(); jit++)
1014
cout << jit->ToURI() <<endl;
1018
for(tUrl2RepIter it=mapUrl2pVname.begin(); it!=mapUrl2pVname.end(); it++)
1020
cout << it->first.ToURI() << " ___" << *(it->second) << endl;
1027
time_t ExecutePostponed()
1029
time_t ret(cleaner::never), now(time(0));
1030
for (tRepMap::iterator it = repoparms.begin(); it != repoparms.end(); ++it)
1032
if (!it->second.m_pHooks)
1034
tHookHandler & hooks = *(static_cast<tHookHandler*> (it->second.m_pHooks));
1036
if (hooks.downTimeNext)
1038
if (hooks.downTimeNext <= now) // time to execute
1041
aclog::misc(hooks.cmdRel, 'X');
1045
system(hooks.cmdRel.c_str());
1046
hooks.downTimeNext = 0;
1048
else // in future, use the soonest time
1049
ret = min(ret, hooks.downTimeNext);
848
1059
namespace rechecks
850
regex_t reIfiles, rePfiles, reWfiles;
851
deque<regex_t> vecReqPatters, vecTgtPatterns;
1061
const UINT rexCount = 3;
1062
regex_t rex[rexCount];
853
1064
bool CompileExpressions()
855
//printf("%s\\n%s\\n", a, b);
857
if(regcomp(&rePfiles, acfg::pfilepat.c_str(), REG_EXTENDED))
859
if(regcomp(&reIfiles, acfg::vfilepat.c_str(), REG_EXTENDED))
861
if(regcomp(&reWfiles, acfg::wfilepat.c_str(), REG_EXTENDED))
1066
cmstring *psRex[rexCount] = {&acfg::vfilepat, &acfg::pfilepat, &acfg::wfilepat};
1067
for(UINT i=0; i<rexCount; i++)
1069
int nErr=regcomp(&rex[i], psRex[i]->c_str(), REG_EXTENDED);
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;
867
1082
eFileKind GetFiletype(const string & in) {
868
1083
//LOGSTART("rechecks::getFiletype");
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;
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;
876
1091
return FILE_INVALID;
879
1094
bool MatchWhitelist(const string & in)
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;
1102
deque<regex_t> vecReqPatters, vecTgtPatterns;
887
1105
inline bool CompileUncachedRex(const string & token, bool bIsTgtPattern, bool bRecursiveCall)
889
1107
deque<regex_t> & patvec = bIsTgtPattern ? vecTgtPatterns : vecReqPatters;
1194
} // namespace rechecks
1196
mstring GetDirPart(const string &in)
1201
tStrPos end = in.find_last_of(CPATHSEP);
1202
if(end == stmiss) // none? don't care then
1205
return in.substr(0, end+1);
975
1208
void mkbasedir(const string & path)
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
1213
UINT pos=0; // but skip the cache dir components, if possible
1214
if(startsWith(path, acfg::cacheDirSlash))
1216
// pos=acfg::cachedir.size();
1217
pos=path.find("/", acfg::cachedir.size()+1);
1219
for(; pos<path.size(); pos=path.find(SZPATHSEP, pos+1))
980
1222
mkdir(path.substr(0,pos).c_str(), acfg::dirperms);
984
1228
int main(int argc, char **argv)